office-gobmx/cui/source/options/optcolor.cxx
Heiko Tietze ba0100be03 Resolves tdf#128258 - Draw a dotted line before hidden columns/rows
Color and on/off configurable via Tools > Options > Application Colors

Change-Id: Ia4b1e1c86f36d1b0f508a5b3e866a79418f16c5a
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/128553
Tested-by: Jenkins
Reviewed-by: Heiko Tietze <heiko.tietze@documentfoundation.org>
2022-01-27 10:31:52 +01:00

896 lines
30 KiB
C++

/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* This file incorporates work covered by the following license notice:
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed
* with this work for additional information regarding copyright
* ownership. The ASF licenses this file to you under the Apache
* License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
#include <sal/config.h>
#include <bitset>
#include <tools/debug.hxx>
#include <editeng/editids.hrc>
#include <svtools/colorcfg.hxx>
#include <svtools/extcolorcfg.hxx>
#include <svx/colorbox.hxx>
#include <unotools/moduleoptions.hxx>
#include <vcl/svapp.hxx>
#include <vcl/weld.hxx>
#include <svx/svxdlg.hxx>
#include <helpids.h>
#include <dialmgr.hxx>
#include "optcolor.hxx"
#include <strings.hrc>
using namespace ::com::sun::star;
using namespace ::svtools;
namespace
{
// list of default groups
enum Group
{
Group_General,
Group_Writer,
Group_Html,
Group_Calc,
Group_Draw,
Group_Basic,
Group_Sql,
nGroupCount
};
// group data
struct
{
// group
Group eGroup;
// .ui group name
const char *pGroup;
}
const vGroupInfo[] =
{
// the groups are in the same order as in enum Group above
{ Group_General, "general" },
{ Group_Writer, "writer" },
{ Group_Html, "html" },
{ Group_Calc, "calc" },
{ Group_Draw, "draw" },
{ Group_Basic, "basic" },
{ Group_Sql, "sql" }
};
// color config entry data (see ColorConfigWindow_Impl::Entry below)
struct
{
// group
Group eGroup;
//checkbox (or simple text)
const char *pText;
//color listbox
const char *pColor;
// has checkbox?
bool bCheckBox;
}
const vEntryInfo[] =
{
#define IDS(Name) \
SAL_STRINGIFY(Name), SAL_STRINGIFY(Name##_lb), false
#define IDS_CB(Name) \
SAL_STRINGIFY(Name), SAL_STRINGIFY(Name##_lb), true
// The list of these entries (enum ColorConfigEntry) are in colorcfg.hxx.
{ Group_General, IDS(doccolor) },
{ Group_General, IDS_CB(docboundaries) },
{ Group_General, IDS(appback) },
{ Group_General, IDS_CB(objboundaries) },
{ Group_General, IDS_CB(tblboundaries) },
{ Group_General, IDS(font) },
{ Group_General, IDS_CB(unvisitedlinks) },
{ Group_General, IDS_CB(visitedlinks) },
{ Group_General, IDS(autospellcheck) },
{ Group_General, IDS(smarttags) },
{ Group_General, IDS_CB(shadows) },
{ Group_Writer, IDS(writergrid) },
{ Group_Writer, IDS_CB(field) },
{ Group_Writer, IDS_CB(index) },
{ Group_Writer, IDS(direct) },
{ Group_Writer, IDS(script) },
{ Group_Writer, IDS_CB(section) },
{ Group_Writer, IDS(hdft) },
{ Group_Writer, IDS(pagebreak) },
{ Group_Html, IDS(sgml) },
{ Group_Html, IDS(htmlcomment) },
{ Group_Html, IDS(htmlkeyword) },
{ Group_Html, IDS(unknown) },
{ Group_Calc, IDS(calcgrid) },
{ Group_Calc, IDS(brk) },
{ Group_Calc, IDS(brkmanual) },
{ Group_Calc, IDS(brkauto) },
{ Group_Calc, IDS_CB(hiddencolrow) },
{ Group_Calc, IDS(det) },
{ Group_Calc, IDS(deterror) },
{ Group_Calc, IDS(ref) },
{ Group_Calc, IDS(notes) },
{ Group_Calc, IDS(values) },
{ Group_Calc, IDS(formulas) },
{ Group_Calc, IDS(text) },
{ Group_Calc, IDS(protectedcells) },
{ Group_Draw, IDS(drawgrid) },
{ Group_Basic, IDS(basicid) },
{ Group_Basic, IDS(basiccomment) },
{ Group_Basic, IDS(basicnumber) },
{ Group_Basic, IDS(basicstring) },
{ Group_Basic, IDS(basicop) },
{ Group_Basic, IDS(basickeyword) },
{ Group_Basic, IDS(error) },
{ Group_Sql, IDS(sqlid) },
{ Group_Sql, IDS(sqlnumber) },
{ Group_Sql, IDS(sqlstring) },
{ Group_Sql, IDS(sqlop) },
{ Group_Sql, IDS(sqlkeyword) },
{ Group_Sql, IDS(sqlparam) },
{ Group_Sql, IDS(sqlcomment) }
#undef IDS
};
// ColorConfigWindow_Impl
class ColorConfigWindow_Impl
{
public:
explicit ColorConfigWindow_Impl(weld::Window* pTopLevel, weld::Container* pParent);
public:
void SetLinks(Link<weld::Toggleable&,void> const&,
Link<ColorListBox&,void> const&,
Link<weld::Widget&,void> const&,
weld::ScrolledWindow& rScroll);
void Update(EditableColorConfig const*, EditableExtendedColorConfig const*);
void ClickHdl(EditableColorConfig*, const weld::Toggleable&);
void ColorHdl(EditableColorConfig*, EditableExtendedColorConfig*, const ColorListBox*);
weld::Widget& GetWidget1()
{
return *m_xWidget1;
}
weld::Widget& GetWidget2()
{
return *m_xWidget2;
}
weld::Widget& GetBody()
{
return *m_xBox;
}
int GetLabelIndent() const
{
return m_nCheckBoxLabelOffset;
}
private:
// Chapter -- horizontal group separator stripe with text
class Chapter
{
// text
std::unique_ptr<weld::Label> m_xText;
public:
Chapter(weld::Builder& rBuilder, const char* pLabelWidget, bool bShow);
void SetText(const OUString& rLabel) { m_xText->set_label(rLabel); }
};
// Entry -- a color config entry:
// text (checkbox) + color list box
class Entry
{
public:
Entry(weld::Window* pTopLevel, weld::Builder& rBuilder, const char* pTextWidget, const char* pColorWidget,
const Color& rColor, int nCheckBoxLabelOffset, bool bCheckBox, bool bShow);
public:
void SetText(const OUString& rLabel) { dynamic_cast<weld::Label&>(*m_xText).set_label(rLabel); }
int get_height_request() const
{
return std::max(m_xText->get_preferred_size().Height(),
m_xColorList->get_widget().get_preferred_size().Height());
}
void Hide ();
public:
void SetLinks(Link<weld::Toggleable&,void> const&,
Link<ColorListBox&,void> const&,
Link<weld::Widget&,void> const&);
void Update (ColorConfigValue const&);
void Update (ExtendedColorConfigValue const&);
void ColorChanged (ColorConfigValue&);
void ColorChanged (ExtendedColorConfigValue&);
public:
bool Is(const weld::Toggleable* pBox) const { return m_xText.get() == pBox; }
bool Is(const ColorListBox* pBox) const { return m_xColorList.get() == pBox; }
private:
// checkbox (CheckBox) or simple text (FixedText)
std::unique_ptr<weld::Widget> m_xText;
// color list box
std::unique_ptr<ColorListBox> m_xColorList;
// default color
Color m_aDefaultColor;
};
private:
weld::Window* m_pTopLevel;
int m_nCheckBoxLabelOffset;
std::unique_ptr<weld::Builder> m_xBuilder;
std::unique_ptr<weld::Box> m_xBox;
std::unique_ptr<weld::Widget> m_xWidget1;
std::unique_ptr<weld::Widget> m_xWidget2;
std::vector<std::unique_ptr<weld::Builder>> vExtBuilders;
std::vector<std::unique_ptr<weld::Container>> vExtContainers;
// vChapters -- groups (group headers)
std::vector<std::shared_ptr<Chapter> > vChapters;
// vEntries -- color options
std::vector<std::shared_ptr<Entry> > vEntries;
// module options
SvtModuleOptions aModuleOptions;
// initialization
void CreateEntries();
private:
bool IsGroupVisible (Group) const;
};
} // namespace
// ColorConfigWindow_Impl::Chapter
// ctor for default groups
// rParent: parent window (ColorConfigWindow_Impl)
// eGroup: which group is this?
ColorConfigWindow_Impl::Chapter::Chapter(weld::Builder& rBuilder, const char* pLabelWidget, bool bShow)
: m_xText(rBuilder.weld_label(pLabelWidget))
{
if (!bShow)
m_xText->hide();
}
// ColorConfigWindow_Impl::Entry
ColorConfigWindow_Impl::Entry::Entry(weld::Window* pTopLevel, weld::Builder& rBuilder,
const char* pTextWidget, const char* pColorWidget,
const Color& rColor,
int nCheckBoxLabelOffset, bool bCheckBox, bool bShow)
: m_xColorList(new ColorListBox(rBuilder.weld_menu_button(pColorWidget), [pTopLevel]{ return pTopLevel; }))
, m_aDefaultColor(rColor)
{
if (bCheckBox)
m_xText = rBuilder.weld_check_button(pTextWidget);
else
m_xText = rBuilder.weld_label(pTextWidget);
// color list
m_xColorList->SetSlotId(SID_ATTR_CHAR_COLOR);
m_xColorList->SetAutoDisplayColor(m_aDefaultColor);
if (!bCheckBox)
{
m_xText->set_margin_start(m_xText->get_margin_start() +
nCheckBoxLabelOffset);
}
if (!bShow)
Hide();
}
void ColorConfigWindow_Impl::Entry::Hide()
{
m_xText->hide();
m_xColorList->hide();
}
// SetLinks()
void ColorConfigWindow_Impl::Entry::SetLinks(Link<weld::Toggleable&,void> const& rCheckLink,
Link<ColorListBox&,void> const& rColorLink,
Link<weld::Widget&,void> const& rGetFocusLink)
{
m_xColorList->SetSelectHdl(rColorLink);
m_xColorList->connect_focus_in(rGetFocusLink);
if (weld::Toggleable* pCheckBox = dynamic_cast<weld::Toggleable*>(m_xText.get()))
{
pCheckBox->connect_toggled(rCheckLink);
pCheckBox->connect_focus_in(rGetFocusLink);
}
}
// updates a default color config entry
void ColorConfigWindow_Impl::Entry::Update(ColorConfigValue const& rValue)
{
Color aColor(rValue.nColor);
m_xColorList->SelectEntry(aColor);
if (weld::Toggleable* pCheckBox = dynamic_cast<weld::Toggleable*>(m_xText.get()))
pCheckBox->set_active(rValue.bIsVisible);
}
// updates an extended color config entry
void ColorConfigWindow_Impl::Entry::Update(ExtendedColorConfigValue const& rValue)
{
Color aColor(rValue.getColor());
if (rValue.getColor() == rValue.getDefaultColor())
m_xColorList->SelectEntry(COL_AUTO);
else
m_xColorList->SelectEntry(aColor);
}
// color of a default entry has changed
void ColorConfigWindow_Impl::Entry::ColorChanged(ColorConfigValue& rValue)
{
Color aColor = m_xColorList->GetSelectEntryColor();
rValue.nColor = aColor;
}
// color of an extended entry has changed
void ColorConfigWindow_Impl::Entry::ColorChanged(ExtendedColorConfigValue& rValue)
{
Color aColor = m_xColorList->GetSelectEntryColor();
rValue.setColor(aColor);
if (aColor == COL_AUTO)
{
rValue.setColor(rValue.getDefaultColor());
}
}
// ColorConfigWindow_Impl
ColorConfigWindow_Impl::ColorConfigWindow_Impl(weld::Window* pTopLevel, weld::Container* pParent)
: m_pTopLevel(pTopLevel)
, m_xBuilder(Application::CreateBuilder(pParent, "cui/ui/colorconfigwin.ui"))
, m_xBox(m_xBuilder->weld_box("ColorConfigWindow"))
, m_xWidget1(m_xBuilder->weld_widget("docboundaries"))
, m_xWidget2(m_xBuilder->weld_widget("docboundaries_lb"))
{
CreateEntries();
}
void ColorConfigWindow_Impl::CreateEntries()
{
std::bitset<nGroupCount> aModulesInstalled;
// creating group headers
vChapters.reserve(nGroupCount);
for (unsigned i = 0; i != nGroupCount; ++i)
{
aModulesInstalled[i] = IsGroupVisible(vGroupInfo[i].eGroup);
vChapters.push_back(std::make_shared<Chapter>(*m_xBuilder, vGroupInfo[i].pGroup, aModulesInstalled[i]));
}
// Here we want to get the amount to add to the position of a FixedText to
// get it to align its contents with that of a CheckBox
{
OUString sSampleText("XXXXXX");
std::unique_ptr<weld::CheckButton> xCheckBox(m_xBuilder->weld_check_button("docboundaries"));
std::unique_ptr<weld::Label> xFixedText(m_xBuilder->weld_label("doccolor"));
OUString sOrigCheck(xCheckBox->get_label());
OUString sOrigFixed(xFixedText->get_label());
xCheckBox->set_label(sSampleText);
xFixedText->set_label(sSampleText);
Size aCheckSize(xCheckBox->get_preferred_size());
Size aFixedSize(xFixedText->get_preferred_size());
xCheckBox->set_label(sOrigCheck);
xFixedText->set_label(sOrigFixed);
m_nCheckBoxLabelOffset = aCheckSize.Width() - aFixedSize.Width();
}
// creating entries
vEntries.reserve(ColorConfigEntryCount);
for (size_t i = 0; i < SAL_N_ELEMENTS(vEntryInfo); ++i)
{
vEntries.push_back(std::make_shared<Entry>(m_pTopLevel, *m_xBuilder,
vEntryInfo[i].pText, vEntryInfo[i].pColor,
ColorConfig::GetDefaultColor(static_cast<ColorConfigEntry>(i)),
m_nCheckBoxLabelOffset,
vEntryInfo[i].bCheckBox,
aModulesInstalled[vEntryInfo[i].eGroup]));
}
// extended entries
ExtendedColorConfig aExtConfig;
unsigned const nExtGroupCount = aExtConfig.GetComponentCount();
if (!nExtGroupCount)
return;
for (unsigned j = 0; j != nExtGroupCount; ++j)
{
vExtBuilders.emplace_back(Application::CreateBuilder(m_xBox.get(), "cui/ui/chapterfragment.ui"));
vExtContainers.emplace_back(vExtBuilders.back()->weld_frame("ChapterFragment"));
OUString const sComponentName = aExtConfig.GetComponentName(j);
vChapters.push_back(std::make_shared<Chapter>(
*vExtBuilders.back(), "chapter", true));
vChapters.back()->SetText(aExtConfig.GetComponentDisplayName(sComponentName));
vExtContainers.emplace_back(vExtBuilders.back()->weld_box("contents"));
weld::Container* pChapterBox = vExtContainers.back().get();
unsigned nColorCount = aExtConfig.GetComponentColorCount(sComponentName);
for (unsigned i = 0; i != nColorCount; ++i)
{
vExtBuilders.emplace_back(Application::CreateBuilder(pChapterBox, "cui/ui/colorfragment.ui"));
vExtContainers.emplace_back(vExtBuilders.back()->weld_container("ColorFragment"));
ExtendedColorConfigValue const aColorEntry =
aExtConfig.GetComponentColorConfigValue(sComponentName, i);
vEntries.push_back(std::make_shared<Entry>(m_pTopLevel, *vExtBuilders.back(),
"label", "button", aColorEntry.getDefaultColor(),
m_nCheckBoxLabelOffset, false, true));
vEntries.back()->SetText(aColorEntry.getDisplayName());
}
}
}
// SetLinks()
void ColorConfigWindow_Impl::SetLinks(Link<weld::Toggleable&,void> const& aCheckLink,
Link<ColorListBox&,void> const& aColorLink,
Link<weld::Widget&,void> const& rGetFocusLink,
weld::ScrolledWindow& rScroll)
{
if (vEntries.empty())
return;
for (auto const & i: vEntries)
i->SetLinks(aCheckLink, aColorLink, rGetFocusLink);
// 6 is the spacing set on ColorConfigWindow
rScroll.vadjustment_set_step_increment(vEntries[0]->get_height_request() + 6);
}
// Update()
void ColorConfigWindow_Impl::Update (
EditableColorConfig const* pConfig,
EditableExtendedColorConfig const* pExtConfig)
{
// updating default entries
for (unsigned i = 0; i != ColorConfigEntryCount; ++i)
{
ColorConfigEntry const aColorEntry = static_cast<ColorConfigEntry>(i);
vEntries[i]->Update(
pConfig->GetColorValue(aColorEntry)
);
}
// updating extended entries
decltype(vEntries)::size_type i = ColorConfigEntryCount;
unsigned const nExtCount = pExtConfig->GetComponentCount();
for (unsigned j = 0; j != nExtCount; ++j)
{
OUString sComponentName = pExtConfig->GetComponentName(j);
unsigned const nColorCount = pExtConfig->GetComponentColorCount(sComponentName);
for (unsigned k = 0; i != vEntries.size() && k != nColorCount; ++i, ++k)
vEntries[i]->Update(
pExtConfig->GetComponentColorConfigValue(sComponentName, k)
);
}
}
// ClickHdl()
void ColorConfigWindow_Impl::ClickHdl(EditableColorConfig* pConfig, const weld::Toggleable& rBox)
{
for (unsigned i = 0; i != ColorConfigEntryCount; ++i)
{
if (vEntries[i]->Is(&rBox))
{
ColorConfigEntry const aEntry = static_cast<ColorConfigEntry>(i);
ColorConfigValue aValue = pConfig->GetColorValue(aEntry);
aValue.bIsVisible = rBox.get_active();
pConfig->SetColorValue(aEntry, aValue);
break;
}
}
}
// ColorHdl()
void ColorConfigWindow_Impl::ColorHdl(
EditableColorConfig* pConfig, EditableExtendedColorConfig* pExtConfig,
const ColorListBox* pBox)
{
unsigned i = 0;
// default entries
for ( ; i != ColorConfigEntryCount; ++i)
{
if (pBox && vEntries[i]->Is(pBox))
{
ColorConfigEntry const aColorEntry = static_cast<ColorConfigEntry>(i);
ColorConfigValue aValue = pConfig->GetColorValue(aColorEntry);
vEntries[i]->ColorChanged(aValue);
pConfig->SetColorValue(aColorEntry, aValue);
break;
}
}
// extended entries
unsigned const nExtCount = pExtConfig->GetComponentCount();
i = ColorConfigEntryCount;
for (unsigned j = 0; j != nExtCount; ++j)
{
OUString sComponentName = pExtConfig->GetComponentName(j);
unsigned const nColorCount = pExtConfig->GetComponentColorCount(sComponentName);
unsigned const nCount = vEntries.size();
for (unsigned k = 0; i != nCount && k != nColorCount; ++i, ++k)
{
if (pBox && vEntries[i]->Is(pBox))
{
ExtendedColorConfigValue aValue =
pExtConfig->GetComponentColorConfigValue(sComponentName, k);
vEntries[i]->ColorChanged(aValue);
pExtConfig->SetColorValue(sComponentName, aValue);
break;
}
}
}
}
// IsGroupVisible()
bool ColorConfigWindow_Impl::IsGroupVisible (Group eGroup) const
{
switch (eGroup)
{
case Group_Writer:
case Group_Html:
return aModuleOptions.IsModuleInstalled(SvtModuleOptions::EModule::WRITER);
case Group_Calc:
return aModuleOptions.IsModuleInstalled(SvtModuleOptions::EModule::CALC);
case Group_Draw:
return
aModuleOptions.IsModuleInstalled(SvtModuleOptions::EModule::DRAW) ||
aModuleOptions.IsModuleInstalled(SvtModuleOptions::EModule::IMPRESS);
case Group_Sql:
return aModuleOptions.IsModuleInstalled(SvtModuleOptions::EModule::DATABASE);
default:
return true;
}
}
class ColorConfigCtrl_Impl
{
std::unique_ptr<weld::ScrolledWindow> m_xVScroll;
std::unique_ptr<weld::Container> m_xBody;
std::unique_ptr<ColorConfigWindow_Impl> m_xScrollWindow;
EditableColorConfig* pColorConfig;
EditableExtendedColorConfig* pExtColorConfig;
DECL_LINK(ClickHdl, weld::Toggleable&, void);
DECL_LINK(ColorHdl, ColorListBox&, void);
DECL_LINK(ControlFocusHdl, weld::Widget&, void);
public:
explicit ColorConfigCtrl_Impl(weld::Window* pTopLevel, weld::Builder& rbuilder);
void SetConfig (EditableColorConfig& rConfig) { pColorConfig = &rConfig; }
void SetExtendedConfig (EditableExtendedColorConfig& rConfig) { pExtColorConfig = &rConfig; }
void Update();
tools::Long GetScrollPosition() const
{
return m_xVScroll->vadjustment_get_value();
}
void SetScrollPosition(tools::Long nSet)
{
m_xVScroll->vadjustment_set_value(nSet);
}
weld::Widget& GetWidget1()
{
return m_xScrollWindow->GetWidget1();
}
weld::Widget& GetWidget2()
{
return m_xScrollWindow->GetWidget2();
}
int GetLabelIndent() const
{
return m_xScrollWindow->GetLabelIndent();
}
};
ColorConfigCtrl_Impl::ColorConfigCtrl_Impl(weld::Window* pTopLevel, weld::Builder& rBuilder)
: m_xVScroll(rBuilder.weld_scrolled_window("scroll"))
, m_xBody(rBuilder.weld_container("colorconfig"))
, m_xScrollWindow(std::make_unique<ColorConfigWindow_Impl>(pTopLevel, m_xBody.get()))
, pColorConfig(nullptr)
, pExtColorConfig(nullptr)
{
m_xBody->set_stack_background();
Link<weld::Toggleable&,void> aCheckLink = LINK(this, ColorConfigCtrl_Impl, ClickHdl);
Link<ColorListBox&,void> aColorLink = LINK(this, ColorConfigCtrl_Impl, ColorHdl);
Link<weld::Widget&,void> const& aGetFocusLink = LINK(this, ColorConfigCtrl_Impl, ControlFocusHdl);
m_xScrollWindow->SetLinks(aCheckLink, aColorLink, aGetFocusLink, *m_xVScroll);
}
void ColorConfigCtrl_Impl::Update ()
{
DBG_ASSERT(pColorConfig, "Configuration not set");
m_xScrollWindow->Update(pColorConfig, pExtColorConfig);
}
IMPL_LINK(ColorConfigCtrl_Impl, ClickHdl, weld::Toggleable&, rBox, void)
{
DBG_ASSERT(pColorConfig, "Configuration not set");
m_xScrollWindow->ClickHdl(pColorConfig, rBox);
}
// a color list has changed
IMPL_LINK(ColorConfigCtrl_Impl, ColorHdl, ColorListBox&, rBox, void)
{
DBG_ASSERT(pColorConfig, "Configuration not set" );
m_xScrollWindow->ColorHdl(pColorConfig, pExtColorConfig, &rBox);
}
IMPL_LINK(ColorConfigCtrl_Impl, ControlFocusHdl, weld::Widget&, rCtrl, void)
{
// determine whether a control is completely visible
// and make it visible
unsigned const nWinHeight = m_xVScroll->vadjustment_get_page_size();
// calc visible area
auto nThumbPos = m_xVScroll->vadjustment_get_value();
int const nWinTop = nThumbPos;
int const nWinBottom = nWinTop + nWinHeight;
int x, nCtrlPosY, width, nHeight;
rCtrl.get_extents_relative_to(m_xScrollWindow->GetBody(), x, nCtrlPosY, width, nHeight);
int const nSelectedItemTop = nCtrlPosY;
int const nSelectedItemBottom = nCtrlPosY + nHeight;
bool const shouldScrollDown = nSelectedItemBottom >= nWinBottom;
bool const shouldScrollUp = nSelectedItemTop <= nWinTop;
bool const isNeedToScroll = shouldScrollDown || shouldScrollUp || nCtrlPosY < 0;
if (!isNeedToScroll)
return;
if (shouldScrollDown)
{
int nOffset = nSelectedItemBottom - nWinBottom;
nThumbPos += nOffset + 2;
}
else
{
int nOffset = nWinTop - nSelectedItemTop;
nThumbPos -= nOffset + 2;
if(nThumbPos < 0)
nThumbPos = 0;
}
m_xVScroll->vadjustment_set_value(nThumbPos);
}
// SvxColorOptionsTabPage
SvxColorOptionsTabPage::SvxColorOptionsTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rCoreSet)
: SfxTabPage(pPage, pController, "cui/ui/optappearancepage.ui", "OptAppearancePage", &rCoreSet)
, bFillItemSetCalled(false)
, m_nSizeAllocEventId(nullptr)
, m_xColorSchemeLB(m_xBuilder->weld_combo_box("colorschemelb"))
, m_xSaveSchemePB(m_xBuilder->weld_button("save"))
, m_xDeleteSchemePB(m_xBuilder->weld_button("delete"))
, m_xColorConfigCT(new ColorConfigCtrl_Impl(pController->getDialog(), *m_xBuilder))
, m_xTable(m_xBuilder->weld_widget("table"))
, m_xOnFT(m_xBuilder->weld_label("on"))
, m_xElementFT(m_xBuilder->weld_label("uielements"))
, m_xColorFT(m_xBuilder->weld_label("colorsetting"))
, m_rWidget1(m_xColorConfigCT->GetWidget1())
, m_rWidget2(m_xColorConfigCT->GetWidget2())
{
m_xColorSchemeLB->make_sorted();
m_xColorSchemeLB->connect_changed(LINK(this, SvxColorOptionsTabPage, SchemeChangedHdl_Impl));
Link<weld::Button&,void> aLk = LINK(this, SvxColorOptionsTabPage, SaveDeleteHdl_Impl );
m_xSaveSchemePB->connect_clicked(aLk);
m_xDeleteSchemePB->connect_clicked(aLk);
m_rWidget1.connect_size_allocate(LINK(this, SvxColorOptionsTabPage, AdjustHeaderBar));
m_rWidget2.connect_size_allocate(LINK(this, SvxColorOptionsTabPage, AdjustHeaderBar));
}
SvxColorOptionsTabPage::~SvxColorOptionsTabPage()
{
if (pColorConfig)
{
//when the dialog is cancelled but the color scheme ListBox has been changed these
//changes need to be undone
if (!bFillItemSetCalled && m_xColorSchemeLB->get_value_changed_from_saved())
{
OUString sOldScheme = m_xColorSchemeLB->get_saved_value();
if(!sOldScheme.isEmpty())
{
pColorConfig->SetCurrentSchemeName(sOldScheme);
pExtColorConfig->SetCurrentSchemeName(sOldScheme);
}
}
pColorConfig->ClearModified();
pColorConfig->EnableBroadcast();
pColorConfig.reset();
pExtColorConfig->ClearModified();
pExtColorConfig->EnableBroadcast();
pExtColorConfig.reset();
}
m_xColorConfigCT.reset();
if (m_nSizeAllocEventId)
Application::RemoveUserEvent(m_nSizeAllocEventId);
}
std::unique_ptr<SfxTabPage> SvxColorOptionsTabPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet)
{
return std::make_unique<SvxColorOptionsTabPage>(pPage, pController, *rAttrSet);
}
bool SvxColorOptionsTabPage::FillItemSet( SfxItemSet* )
{
bFillItemSetCalled = true;
if (m_xColorSchemeLB->get_value_changed_from_saved())
{
pColorConfig->SetModified();
pExtColorConfig->SetModified();
}
if (pColorConfig->IsModified())
pColorConfig->Commit();
if (pExtColorConfig->IsModified())
pExtColorConfig->Commit();
return true;
}
void SvxColorOptionsTabPage::Reset( const SfxItemSet* )
{
if(pColorConfig)
{
pColorConfig->ClearModified();
pColorConfig->DisableBroadcast();
}
pColorConfig.reset(new EditableColorConfig);
m_xColorConfigCT->SetConfig(*pColorConfig);
if(pExtColorConfig)
{
pExtColorConfig->ClearModified();
pExtColorConfig->DisableBroadcast();
}
pExtColorConfig.reset(new EditableExtendedColorConfig);
m_xColorConfigCT->SetExtendedConfig(*pExtColorConfig);
OUString sUser = GetUserData();
//has to be called always to speed up accessibility tools
m_xColorConfigCT->SetScrollPosition(sUser.toInt32());
m_xColorSchemeLB->clear();
const uno::Sequence< OUString > aSchemes = pColorConfig->GetSchemeNames();
for(const OUString& s : aSchemes)
m_xColorSchemeLB->append_text(s);
m_xColorSchemeLB->set_active_text(pColorConfig->GetCurrentSchemeName());
m_xColorSchemeLB->save_value();
m_xDeleteSchemePB->set_sensitive( aSchemes.getLength() > 1 );
UpdateColorConfig();
}
DeactivateRC SvxColorOptionsTabPage::DeactivatePage( SfxItemSet* pSet_ )
{
if ( pSet_ )
FillItemSet( pSet_ );
return DeactivateRC::LeavePage;
}
void SvxColorOptionsTabPage::UpdateColorConfig()
{
//update the color config control
m_xColorConfigCT->Update();
}
IMPL_LINK(SvxColorOptionsTabPage, SchemeChangedHdl_Impl, weld::ComboBox&, rBox, void)
{
pColorConfig->LoadScheme(rBox.get_active_text());
pExtColorConfig->LoadScheme(rBox.get_active_text());
UpdateColorConfig();
}
IMPL_LINK(SvxColorOptionsTabPage, SaveDeleteHdl_Impl, weld::Button&, rButton, void)
{
if (m_xSaveSchemePB.get() == &rButton)
{
OUString sName;
SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
ScopedVclPtr<AbstractSvxNameDialog> aNameDlg(pFact->CreateSvxNameDialog(GetFrameWeld(),
sName, CuiResId(RID_CUISTR_COLOR_CONFIG_SAVE2) ));
aNameDlg->SetCheckNameHdl( LINK(this, SvxColorOptionsTabPage, CheckNameHdl_Impl));
aNameDlg->SetText(CuiResId(RID_CUISTR_COLOR_CONFIG_SAVE1));
aNameDlg->SetHelpId(HID_OPTIONS_COLORCONFIG_SAVE_SCHEME);
aNameDlg->SetCheckNameHdl( LINK(this, SvxColorOptionsTabPage, CheckNameHdl_Impl));
if(RET_OK == aNameDlg->Execute())
{
aNameDlg->GetName(sName);
pColorConfig->AddScheme(sName);
pExtColorConfig->AddScheme(sName);
m_xColorSchemeLB->append_text(sName);
m_xColorSchemeLB->set_active_text(sName);
SchemeChangedHdl_Impl(*m_xColorSchemeLB);
}
}
else
{
DBG_ASSERT(m_xColorSchemeLB->get_count() > 1, "don't delete the last scheme");
std::unique_ptr<weld::MessageDialog> xQuery(Application::CreateMessageDialog(GetFrameWeld(),
VclMessageType::Question, VclButtonsType::YesNo,
CuiResId(RID_CUISTR_COLOR_CONFIG_DELETE)));
xQuery->set_title(CuiResId(RID_CUISTR_COLOR_CONFIG_DELETE_TITLE));
if (RET_YES == xQuery->run())
{
OUString sDeleteScheme(m_xColorSchemeLB->get_active_text());
m_xColorSchemeLB->remove(m_xColorSchemeLB->get_active());
m_xColorSchemeLB->set_active(0);
SchemeChangedHdl_Impl(*m_xColorSchemeLB);
//first select the new scheme and then delete the old one
pColorConfig->DeleteScheme(sDeleteScheme);
pExtColorConfig->DeleteScheme(sDeleteScheme);
}
}
m_xDeleteSchemePB->set_sensitive(m_xColorSchemeLB->get_count() > 1);
}
IMPL_LINK(SvxColorOptionsTabPage, CheckNameHdl_Impl, AbstractSvxNameDialog&, rDialog, bool )
{
OUString sName;
rDialog.GetName(sName);
return !sName.isEmpty() && m_xColorSchemeLB->find_text(sName) == -1;
}
void SvxColorOptionsTabPage::FillUserData()
{
SetUserData(OUString::number(m_xColorConfigCT->GetScrollPosition()));
}
IMPL_LINK_NOARG(SvxColorOptionsTabPage, AdjustHeaderBar, const Size&, void)
{
if (m_nSizeAllocEventId)
return;
m_nSizeAllocEventId = Application::PostUserEvent(LINK(this, SvxColorOptionsTabPage, PostAdjustHeaderBar));
}
IMPL_LINK_NOARG(SvxColorOptionsTabPage, PostAdjustHeaderBar, void*, void)
{
m_nSizeAllocEventId = nullptr;
// horizontal positions
int nX1, nX2, nX3, y, width, height;
if (!m_rWidget1.get_extents_relative_to(*m_xTable, nX1, y, width, height))
return;
if (!m_rWidget2.get_extents_relative_to(*m_xTable, nX2, y, width, height))
return;
if (!m_xTable->get_extents_relative_to(*m_xTable, nX3, y, width, height))
return;
// 6 is the column-spacing of the parent grid of these labels
auto nTextWidth1 = nX1 + m_xColorConfigCT->GetLabelIndent() - 6;
m_xOnFT->set_size_request(nTextWidth1, -1);
auto nTextWidth3 = width - nX2;
m_xColorFT->set_size_request(nTextWidth3, -1);
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */