Version 6.4.0.0.beta1, tag libreoffice-6.4.0.0.beta1
[LibreOffice.git] / cui / source / options / optcolor.cxx
blob56e75fecd969bf1de9b76f30de72b2e14891426b
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <sal/config.h>
22 #include <bitset>
24 #include <osl/diagnose.h>
25 #include <tools/debug.hxx>
26 #include <editeng/editids.hrc>
27 #include <svtools/colorcfg.hxx>
28 #include <svtools/extcolorcfg.hxx>
29 #include <svx/colorbox.hxx>
30 #include <unotools/moduleoptions.hxx>
31 #include <vcl/settings.hxx>
32 #include <vcl/svapp.hxx>
33 #include <vcl/weld.hxx>
34 #include <svx/svxdlg.hxx>
35 #include <helpids.h>
36 #include <dialmgr.hxx>
37 #include "optcolor.hxx"
38 #include <strings.hrc>
40 using namespace ::com::sun::star;
41 using namespace ::svtools;
43 namespace
46 // list of default groups
47 enum Group
49 Group_General,
50 Group_Writer,
51 Group_Html,
52 Group_Calc,
53 Group_Draw,
54 Group_Basic,
55 Group_Sql,
57 nGroupCount
60 // group data
61 struct
63 // group
64 Group eGroup;
65 // .ui group name
66 const char *pGroup;
68 const vGroupInfo[] =
70 // the groups are in the same order as in enum Group above
71 { Group_General, "general" },
72 { Group_Writer, "writer" },
73 { Group_Html, "html" },
74 { Group_Calc, "calc" },
75 { Group_Draw, "draw" },
76 { Group_Basic, "basic" },
77 { Group_Sql, "sql" }
80 // color config entry data (see ColorConfigWindow_Impl::Entry below)
81 struct
83 // group
84 Group eGroup;
85 //checkbox (or simple text)
86 const char *pText;
87 //color listbox
88 const char *pColor;
89 // has checkbox?
90 bool bCheckBox;
92 const vEntryInfo[] =
94 #define IDS(Name) \
95 SAL_STRINGIFY(Name), SAL_STRINGIFY(Name##_lb), false
97 #define IDS_CB(Name) \
98 SAL_STRINGIFY(Name), SAL_STRINGIFY(Name##_lb), true
100 // The list of these entries (enum ColorConfigEntry) are in colorcfg.hxx.
102 { Group_General, IDS(doccolor) },
103 { Group_General, IDS_CB(docboundaries) },
104 { Group_General, IDS(appback) },
105 { Group_General, IDS_CB(objboundaries) },
106 { Group_General, IDS_CB(tblboundaries) },
107 { Group_General, IDS(font) },
108 { Group_General, IDS_CB(unvisitedlinks) },
109 { Group_General, IDS_CB(visitedlinks) },
110 { Group_General, IDS(autospellcheck) },
111 { Group_General, IDS(smarttags) },
112 { Group_General, IDS_CB(shadows) },
114 { Group_Writer, IDS(writergrid) },
115 { Group_Writer, IDS_CB(field) },
116 { Group_Writer, IDS_CB(index) },
117 { Group_Writer, IDS(direct) },
118 { Group_Writer, IDS(script) },
119 { Group_Writer, IDS_CB(section) },
120 { Group_Writer, IDS(hdft) },
121 { Group_Writer, IDS(pagebreak) },
123 { Group_Html, IDS(sgml) },
124 { Group_Html, IDS(htmlcomment) },
125 { Group_Html, IDS(htmlkeyword) },
126 { Group_Html, IDS(unknown) },
128 { Group_Calc, IDS(calcgrid) },
129 { Group_Calc, IDS(brk) },
130 { Group_Calc, IDS(brkmanual) },
131 { Group_Calc, IDS(brkauto) },
132 { Group_Calc, IDS(det) },
133 { Group_Calc, IDS(deterror) },
134 { Group_Calc, IDS(ref) },
135 { Group_Calc, IDS(notes) },
136 { Group_Calc, IDS(values) },
137 { Group_Calc, IDS(formulas) },
138 { Group_Calc, IDS(text) },
139 { Group_Calc, IDS(protectedcells) },
141 { Group_Draw, IDS(drawgrid) },
143 { Group_Basic, IDS(basicid) },
144 { Group_Basic, IDS(basiccomment) },
145 { Group_Basic, IDS(basicnumber) },
146 { Group_Basic, IDS(basicstring) },
147 { Group_Basic, IDS(basicop) },
148 { Group_Basic, IDS(basickeyword) },
149 { Group_Basic, IDS(error) },
151 { Group_Sql, IDS(sqlid) },
152 { Group_Sql, IDS(sqlnumber) },
153 { Group_Sql, IDS(sqlstring) },
154 { Group_Sql, IDS(sqlop) },
155 { Group_Sql, IDS(sqlkeyword) },
156 { Group_Sql, IDS(sqlparam) },
157 { Group_Sql, IDS(sqlcomment) }
159 #undef IDS
162 } // namespace
164 // ColorConfigWindow_Impl
166 class ColorConfigWindow_Impl
168 public:
169 explicit ColorConfigWindow_Impl(weld::Window* pTopLevel, weld::Container* pParent);
171 public:
172 void SetLinks(Link<weld::ToggleButton&,void> const&,
173 Link<ColorListBox&,void> const&,
174 Link<weld::Widget&,void> const&);
175 void Update(EditableColorConfig const*, EditableExtendedColorConfig const*);
176 void ClickHdl(EditableColorConfig*, weld::ToggleButton&);
177 void ColorHdl(EditableColorConfig*, EditableExtendedColorConfig*, const ColorListBox*);
179 weld::Widget& GetWidget1()
181 return *m_xWidget1;
184 weld::Widget& GetWidget2()
186 return *m_xWidget2;
189 weld::Widget& GetBody()
191 return *m_xGrid;
194 void AdjustExtraWidths(int nTextWidth);
196 private:
197 // Chapter -- horizontal group separator stripe with text
198 class Chapter
200 // text
201 std::unique_ptr<weld::Label> m_xText;
202 public:
203 Chapter(weld::Builder& rBuilder, const char* pLabelWidget, bool bShow);
204 void SetText(const OUString& rLabel) { m_xText->set_label(rLabel); }
207 // Entry -- a color config entry:
208 // text (checkbox) + color list box
209 class Entry
211 public:
212 Entry(weld::Window* pTopLevel, weld::Builder& rBuilder, const char* pTextWidget, const char* pColorWidget,
213 const Color& rColor, long nCheckBoxLabelOffset, bool bCheckBox, bool bShow);
214 public:
215 void SetText(const OUString& rLabel) { dynamic_cast<weld::Label&>(*m_xText).set_label(rLabel); }
216 void set_width_request(int nTextWidth) { m_xText->set_size_request(nTextWidth, -1); }
217 void Hide ();
218 public:
219 void SetLinks(Link<weld::ToggleButton&,void> const&,
220 Link<ColorListBox&,void> const&,
221 Link<weld::Widget&,void> const&);
222 void Update (ColorConfigValue const&);
223 void Update (ExtendedColorConfigValue const&);
224 void ColorChanged (ColorConfigValue&);
225 void ColorChanged (ExtendedColorConfigValue&);
226 public:
227 bool Is(const weld::ToggleButton* pBox) const { return m_xText.get() == pBox; }
228 bool Is(const ColorListBox* pBox) const { return m_xColorList.get() == pBox; }
229 private:
230 // checkbox (CheckBox) or simple text (FixedText)
231 std::unique_ptr<weld::Widget> m_xText;
232 // color list box
233 std::unique_ptr<ColorListBox> m_xColorList;
234 // default color
235 Color m_aDefaultColor;
238 private:
239 weld::Window* m_pTopLevel;
240 std::unique_ptr<weld::Builder> m_xBuilder;
241 std::unique_ptr<weld::Container> m_xGrid;
242 std::unique_ptr<weld::Widget> m_xWidget1;
243 std::unique_ptr<weld::Widget> m_xWidget2;
245 std::vector<std::unique_ptr<weld::Builder>> vExtBuilders;
246 std::vector<std::unique_ptr<weld::Container>> vExtContainers;
247 // vChapters -- groups (group headers)
248 std::vector<std::shared_ptr<Chapter> > vChapters;
249 // vEntries -- color options
250 std::vector<std::shared_ptr<Entry> > vEntries;
252 // module options
253 SvtModuleOptions aModuleOptions;
255 // initialization
256 void CreateEntries();
258 private:
260 bool IsGroupVisible (Group) const;
263 // ColorConfigWindow_Impl::Chapter
265 // ctor for default groups
266 // rParent: parent window (ColorConfigWindow_Impl)
267 // eGroup: which group is this?
268 ColorConfigWindow_Impl::Chapter::Chapter(weld::Builder& rBuilder, const char* pLabelWidget, bool bShow)
269 : m_xText(rBuilder.weld_label(pLabelWidget))
271 if (!bShow)
272 m_xText->hide();
275 // ColorConfigWindow_Impl::Entry
276 ColorConfigWindow_Impl::Entry::Entry(weld::Window* pTopLevel, weld::Builder& rBuilder,
277 const char* pTextWidget, const char* pColorWidget,
278 const Color& rColor,
279 long nCheckBoxLabelOffset, bool bCheckBox, bool bShow)
280 : m_xColorList(new ColorListBox(rBuilder.weld_menu_button(pColorWidget), pTopLevel))
281 , m_aDefaultColor(rColor)
283 if (bCheckBox)
284 m_xText = rBuilder.weld_check_button(pTextWidget);
285 else
286 m_xText = rBuilder.weld_label(pTextWidget);
288 // color list
289 m_xColorList->SetSlotId(SID_ATTR_CHAR_COLOR);
290 m_xColorList->SetAutoDisplayColor(m_aDefaultColor);
292 if (!bCheckBox)
294 m_xText->set_margin_left(m_xText->get_margin_left() +
295 nCheckBoxLabelOffset);
298 if (!bShow)
299 Hide();
302 void ColorConfigWindow_Impl::Entry::Hide()
304 m_xText->hide();
305 m_xColorList->hide();
308 // SetLinks()
309 void ColorConfigWindow_Impl::Entry::SetLinks(Link<weld::ToggleButton&,void> const& rCheckLink,
310 Link<ColorListBox&,void> const& rColorLink,
311 Link<weld::Widget&,void> const& rGetFocusLink)
313 m_xColorList->SetSelectHdl(rColorLink);
314 m_xColorList->connect_focus_in(rGetFocusLink);
315 if (weld::ToggleButton* pCheckBox = dynamic_cast<weld::ToggleButton*>(m_xText.get()))
317 pCheckBox->connect_toggled(rCheckLink);
318 pCheckBox->connect_focus_in(rGetFocusLink);
322 // updates a default color config entry
323 void ColorConfigWindow_Impl::Entry::Update(ColorConfigValue const& rValue)
325 Color aColor(rValue.nColor);
326 m_xColorList->SelectEntry(aColor);
327 if (weld::ToggleButton* pCheckBox = dynamic_cast<weld::ToggleButton*>(m_xText.get()))
328 pCheckBox->set_active(rValue.bIsVisible);
331 // updates an extended color config entry
332 void ColorConfigWindow_Impl::Entry::Update(ExtendedColorConfigValue const& rValue)
334 Color aColor(rValue.getColor());
335 if (rValue.getColor() == rValue.getDefaultColor())
336 m_xColorList->SelectEntry(COL_AUTO);
337 else
338 m_xColorList->SelectEntry(aColor);
341 // color of a default entry has changed
342 void ColorConfigWindow_Impl::Entry::ColorChanged(ColorConfigValue& rValue)
344 Color aColor = m_xColorList->GetSelectEntryColor();
345 rValue.nColor = aColor;
348 // color of an extended entry has changed
349 void ColorConfigWindow_Impl::Entry::ColorChanged(ExtendedColorConfigValue& rValue)
351 Color aColor = m_xColorList->GetSelectEntryColor();
352 rValue.setColor(aColor);
353 if (aColor == COL_AUTO)
355 rValue.setColor(rValue.getDefaultColor());
359 // ColorConfigWindow_Impl
360 ColorConfigWindow_Impl::ColorConfigWindow_Impl(weld::Window* pTopLevel, weld::Container* pParent)
361 : m_pTopLevel(pTopLevel)
362 , m_xBuilder(Application::CreateBuilder(pParent, "cui/ui/colorconfigwin.ui"))
363 , m_xGrid(m_xBuilder->weld_container("ColorConfigWindow"))
364 , m_xWidget1(m_xBuilder->weld_widget("doccolor"))
365 , m_xWidget2(m_xBuilder->weld_widget("doccolor_lb"))
367 CreateEntries();
370 void ColorConfigWindow_Impl::CreateEntries()
372 std::bitset<nGroupCount> aModulesInstalled;
373 // creating group headers
374 vChapters.reserve(nGroupCount);
375 for (unsigned i = 0; i != nGroupCount; ++i)
377 aModulesInstalled[i] = IsGroupVisible(vGroupInfo[i].eGroup);
378 vChapters.push_back(std::make_shared<Chapter>(*m_xBuilder, vGroupInfo[i].pGroup, aModulesInstalled[i]));
381 // Here we want to get the amount to add to the position of a FixedText to
382 // get it to align its contents with that of a CheckBox
383 long nCheckBoxLabelOffset = 0;
385 OUString sSampleText("X");
386 std::unique_ptr<weld::CheckButton> xCheckBox(m_xBuilder->weld_check_button("docboundaries"));
387 std::unique_ptr<weld::Label> xFixedText(m_xBuilder->weld_label("doccolor"));
388 OUString sOrigCheck(xCheckBox->get_label());
389 OUString sOrigFixed(xFixedText->get_label());
390 xCheckBox->set_label(sSampleText);
391 xFixedText->set_label(sSampleText);
392 Size aCheckSize(xCheckBox->get_preferred_size());
393 Size aFixedSize(xFixedText->get_preferred_size());
394 xCheckBox->set_label(sOrigCheck);
395 xFixedText->set_label(sOrigFixed);
396 nCheckBoxLabelOffset = aCheckSize.Width() - aFixedSize.Width();
399 // creating entries
400 vEntries.reserve(ColorConfigEntryCount);
401 for (size_t i = 0; i < SAL_N_ELEMENTS(vEntryInfo); ++i)
403 vEntries.push_back(std::make_shared<Entry>(m_pTopLevel, *m_xBuilder,
404 vEntryInfo[i].pText, vEntryInfo[i].pColor,
405 ColorConfig::GetDefaultColor(static_cast<ColorConfigEntry>(i)),
406 nCheckBoxLabelOffset,
407 vEntryInfo[i].bCheckBox,
408 aModulesInstalled[vEntryInfo[i].eGroup]));
411 // extended entries
412 ExtendedColorConfig aExtConfig;
413 if (unsigned const nExtGroupCount = aExtConfig.GetComponentCount())
415 size_t nLineNum = vChapters.size() + vEntries.size() + 1;
416 for (unsigned j = 0; j != nExtGroupCount; ++j)
418 vExtBuilders.emplace_back(Application::CreateBuilder(m_xGrid.get(), "cui/ui/chapterfragment.ui"));
419 vExtContainers.emplace_back(vExtBuilders.back()->weld_container("ChapterFragment"));
421 vExtContainers.back()->set_grid_width(3);
422 vExtContainers.back()->set_grid_left_attach(0);
423 vExtContainers.back()->set_grid_top_attach(nLineNum);
425 OUString const sComponentName = aExtConfig.GetComponentName(j);
426 vChapters.push_back(std::make_shared<Chapter>(
427 *vExtBuilders.back(), "chapter", true));
428 vChapters.back()->SetText(aExtConfig.GetComponentDisplayName(sComponentName));
429 ++nLineNum;
430 unsigned nColorCount = aExtConfig.GetComponentColorCount(sComponentName);
431 for (unsigned i = 0; i != nColorCount; ++i)
433 vExtBuilders.emplace_back(Application::CreateBuilder(m_xGrid.get(), "cui/ui/colorfragment.ui"));
434 vExtContainers.emplace_back(vExtBuilders.back()->weld_container("ColorFragment"));
436 vExtContainers.back()->set_grid_width(3);
437 vExtContainers.back()->set_grid_left_attach(0);
438 vExtContainers.back()->set_grid_top_attach(nLineNum);
440 ExtendedColorConfigValue const aColorEntry =
441 aExtConfig.GetComponentColorConfigValue(sComponentName, i);
442 vEntries.push_back(std::make_shared<Entry>(m_pTopLevel, *vExtBuilders.back(),
443 "label", "button", aColorEntry.getDefaultColor(),
444 nCheckBoxLabelOffset, false, true));
445 vEntries.back()->SetText(aColorEntry.getDisplayName());
446 ++nLineNum;
452 void ColorConfigWindow_Impl::AdjustExtraWidths(int nTextWidth)
454 for (size_t i = SAL_N_ELEMENTS(vEntryInfo); i < vEntries.size(); ++i)
455 vEntries[i]->set_width_request(nTextWidth);
458 // SetLinks()
459 void ColorConfigWindow_Impl::SetLinks(Link<weld::ToggleButton&,void> const& aCheckLink,
460 Link<ColorListBox&,void> const& aColorLink,
461 Link<weld::Widget&,void> const& rGetFocusLink)
463 for (auto const & i: vEntries)
464 i->SetLinks(aCheckLink, aColorLink, rGetFocusLink);
467 // Update()
468 void ColorConfigWindow_Impl::Update (
469 EditableColorConfig const* pConfig,
470 EditableExtendedColorConfig const* pExtConfig)
472 // updating default entries
473 for (unsigned i = 0; i != ColorConfigEntryCount; ++i)
475 ColorConfigEntry const aColorEntry = static_cast<ColorConfigEntry>(i);
476 vEntries[i]->Update(
477 pConfig->GetColorValue(aColorEntry)
481 // updating extended entries
482 decltype(vEntries)::size_type i = ColorConfigEntryCount;
483 unsigned const nExtCount = pExtConfig->GetComponentCount();
484 for (unsigned j = 0; j != nExtCount; ++j)
486 OUString sComponentName = pExtConfig->GetComponentName(j);
487 unsigned const nColorCount = pExtConfig->GetComponentColorCount(sComponentName);
488 for (unsigned k = 0; i != vEntries.size() && k != nColorCount; ++i, ++k)
489 vEntries[i]->Update(
490 pExtConfig->GetComponentColorConfigValue(sComponentName, k)
495 // ClickHdl()
496 void ColorConfigWindow_Impl::ClickHdl(EditableColorConfig* pConfig, weld::ToggleButton& rBox)
498 for (unsigned i = 0; i != ColorConfigEntryCount; ++i)
500 if (vEntries[i]->Is(&rBox))
502 ColorConfigEntry const aEntry = static_cast<ColorConfigEntry>(i);
503 ColorConfigValue aValue = pConfig->GetColorValue(aEntry);
504 aValue.bIsVisible = rBox.get_active();
505 pConfig->SetColorValue(aEntry, aValue);
506 break;
511 // ColorHdl()
512 void ColorConfigWindow_Impl::ColorHdl(
513 EditableColorConfig* pConfig, EditableExtendedColorConfig* pExtConfig,
514 const ColorListBox* pBox)
516 unsigned i = 0;
518 // default entries
519 for ( ; i != ColorConfigEntryCount; ++i)
521 if (pBox && vEntries[i]->Is(pBox))
523 ColorConfigEntry const aColorEntry = static_cast<ColorConfigEntry>(i);
524 ColorConfigValue aValue = pConfig->GetColorValue(aColorEntry);
525 vEntries[i]->ColorChanged(aValue);
526 pConfig->SetColorValue(aColorEntry, aValue);
527 break;
531 // extended entries
532 unsigned const nExtCount = pExtConfig->GetComponentCount();
533 i = ColorConfigEntryCount;
534 for (unsigned j = 0; j != nExtCount; ++j)
536 OUString sComponentName = pExtConfig->GetComponentName(j);
537 unsigned const nColorCount = pExtConfig->GetComponentColorCount(sComponentName);
538 unsigned const nCount = vEntries.size();
539 for (unsigned k = 0; i != nCount && k != nColorCount; ++i, ++k)
541 if (pBox && vEntries[i]->Is(pBox))
543 ExtendedColorConfigValue aValue =
544 pExtConfig->GetComponentColorConfigValue(sComponentName, k);
545 vEntries[i]->ColorChanged(aValue);
546 pExtConfig->SetColorValue(sComponentName, aValue);
547 break;
554 // IsGroupVisible()
555 bool ColorConfigWindow_Impl::IsGroupVisible (Group eGroup) const
557 switch (eGroup)
559 case Group_Writer:
560 case Group_Html:
561 return aModuleOptions.IsModuleInstalled(SvtModuleOptions::EModule::WRITER);
562 case Group_Calc:
563 return aModuleOptions.IsModuleInstalled(SvtModuleOptions::EModule::CALC);
564 case Group_Draw:
565 return
566 aModuleOptions.IsModuleInstalled(SvtModuleOptions::EModule::DRAW) ||
567 aModuleOptions.IsModuleInstalled(SvtModuleOptions::EModule::IMPRESS);
568 case Group_Sql:
569 return aModuleOptions.IsModuleInstalled(SvtModuleOptions::EModule::DATABASE);
570 default:
571 return true;
575 class ColorConfigCtrl_Impl
577 std::unique_ptr<weld::ScrolledWindow> m_xVScroll;
578 std::unique_ptr<weld::Container> m_xBody;
579 std::unique_ptr<ColorConfigWindow_Impl> m_xScrollWindow;
581 EditableColorConfig* pColorConfig;
582 EditableExtendedColorConfig* pExtColorConfig;
584 DECL_LINK(ClickHdl, weld::ToggleButton&, void);
585 DECL_LINK(ColorHdl, ColorListBox&, void);
586 DECL_LINK(ControlFocusHdl, weld::Widget&, void);
588 public:
589 explicit ColorConfigCtrl_Impl(weld::Window* pTopLevel, weld::Builder& rbuilder);
591 void AdjustExtraWidths(int nTextWidth) { m_xScrollWindow->AdjustExtraWidths(nTextWidth); }
592 void SetConfig (EditableColorConfig& rConfig) { pColorConfig = &rConfig; }
593 void SetExtendedConfig (EditableExtendedColorConfig& rConfig) { pExtColorConfig = &rConfig; }
594 void Update();
595 long GetScrollPosition() const
597 return m_xVScroll->vadjustment_get_value();
599 void SetScrollPosition(long nSet)
601 m_xVScroll->vadjustment_set_value(nSet);
603 weld::Widget& GetWidget1()
605 return m_xScrollWindow->GetWidget1();
607 weld::Widget& GetWidget2()
609 return m_xScrollWindow->GetWidget2();
613 ColorConfigCtrl_Impl::ColorConfigCtrl_Impl(weld::Window* pTopLevel, weld::Builder& rBuilder)
614 : m_xVScroll(rBuilder.weld_scrolled_window("scroll"))
615 , m_xBody(rBuilder.weld_container("colorconfig"))
616 , m_xScrollWindow(std::make_unique<ColorConfigWindow_Impl>(pTopLevel, m_xBody.get()))
617 , pColorConfig(nullptr)
618 , pExtColorConfig(nullptr)
620 m_xBody->set_stack_background();
622 Link<weld::ToggleButton&,void> aCheckLink = LINK(this, ColorConfigCtrl_Impl, ClickHdl);
623 Link<ColorListBox&,void> aColorLink = LINK(this, ColorConfigCtrl_Impl, ColorHdl);
624 Link<weld::Widget&,void> const& aGetFocusLink = LINK(this, ColorConfigCtrl_Impl, ControlFocusHdl);
625 m_xScrollWindow->SetLinks(aCheckLink, aColorLink, aGetFocusLink);
628 void ColorConfigCtrl_Impl::Update ()
630 DBG_ASSERT(pColorConfig, "Configuration not set");
631 m_xScrollWindow->Update(pColorConfig, pExtColorConfig);
634 IMPL_LINK(ColorConfigCtrl_Impl, ClickHdl, weld::ToggleButton&, rBox, void)
636 DBG_ASSERT(pColorConfig, "Configuration not set");
637 m_xScrollWindow->ClickHdl(pColorConfig, rBox);
640 // a color list has changed
641 IMPL_LINK(ColorConfigCtrl_Impl, ColorHdl, ColorListBox&, rBox, void)
643 DBG_ASSERT(pColorConfig, "Configuration not set" );
644 m_xScrollWindow->ColorHdl(pColorConfig, pExtColorConfig, &rBox);
647 IMPL_LINK(ColorConfigCtrl_Impl, ControlFocusHdl, weld::Widget&, rCtrl, void)
649 // determine whether a control is completely visible
650 // and make it visible
651 unsigned const nWinHeight = m_xVScroll->vadjustment_get_page_size();
653 // calc visible area
654 auto nThumbPos = m_xVScroll->vadjustment_get_value();
655 int const nWinTop = nThumbPos;
656 int const nWinBottom = nWinTop + nWinHeight;
658 int x, nCtrlPosY, width, nHeight;
659 rCtrl.get_extents_relative_to(m_xScrollWindow->GetBody(), x, nCtrlPosY, width, nHeight);
661 int const nSelectedItemTop = nCtrlPosY;
662 int const nSelectedItemBottom = nCtrlPosY + nHeight;
663 bool const shouldScrollDown = nSelectedItemBottom >= nWinBottom;
664 bool const shouldScrollUp = nSelectedItemTop <= nWinTop;
665 bool const isNeedToScroll = shouldScrollDown || shouldScrollUp || nCtrlPosY < 0;
667 if (isNeedToScroll)
669 if (shouldScrollDown)
671 int nOffset = nSelectedItemBottom - nWinBottom;
672 nThumbPos += nOffset + 2;
674 else
676 int nOffset = nWinTop - nSelectedItemTop;
677 nThumbPos -= nOffset + 2;
678 if(nThumbPos < 0)
679 nThumbPos = 0;
681 m_xVScroll->vadjustment_set_value(nThumbPos);
685 // SvxColorOptionsTabPage
686 SvxColorOptionsTabPage::SvxColorOptionsTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rCoreSet)
687 : SfxTabPage(pPage, pController, "cui/ui/optappearancepage.ui", "OptAppearancePage", &rCoreSet)
688 , bFillItemSetCalled(false)
689 , m_xColorSchemeLB(m_xBuilder->weld_combo_box("colorschemelb"))
690 , m_xSaveSchemePB(m_xBuilder->weld_button("save"))
691 , m_xDeleteSchemePB(m_xBuilder->weld_button("delete"))
692 , m_xColorConfigCT(new ColorConfigCtrl_Impl(pController->getDialog(), *m_xBuilder))
693 , m_xTable(m_xBuilder->weld_widget("table"))
694 , m_xOnFT(m_xBuilder->weld_label("on"))
695 , m_xElementFT(m_xBuilder->weld_label("uielements"))
696 , m_xColorFT(m_xBuilder->weld_label("colorsetting"))
697 , m_rWidget1(m_xColorConfigCT->GetWidget1())
698 , m_rWidget2(m_xColorConfigCT->GetWidget2())
700 m_xColorSchemeLB->make_sorted();
701 m_xColorSchemeLB->connect_changed(LINK(this, SvxColorOptionsTabPage, SchemeChangedHdl_Impl));
702 Link<weld::Button&,void> aLk = LINK(this, SvxColorOptionsTabPage, SaveDeleteHdl_Impl );
703 m_xSaveSchemePB->connect_clicked(aLk);
704 m_xDeleteSchemePB->connect_clicked(aLk);
706 m_rWidget1.connect_size_allocate(LINK(this, SvxColorOptionsTabPage, AdjustHeaderBar));
707 m_rWidget2.connect_size_allocate(LINK(this, SvxColorOptionsTabPage, AdjustHeaderBar));
710 SvxColorOptionsTabPage::~SvxColorOptionsTabPage()
712 if (pColorConfig)
714 //when the dialog is cancelled but the color scheme ListBox has been changed these
715 //changes need to be undone
716 if (!bFillItemSetCalled && m_xColorSchemeLB->get_value_changed_from_saved())
718 OUString sOldScheme = m_xColorSchemeLB->get_saved_value();
719 if(!sOldScheme.isEmpty())
721 pColorConfig->SetCurrentSchemeName(sOldScheme);
722 pExtColorConfig->SetCurrentSchemeName(sOldScheme);
725 pColorConfig->ClearModified();
726 pColorConfig->EnableBroadcast();
727 pColorConfig.reset();
729 pExtColorConfig->ClearModified();
730 pExtColorConfig->EnableBroadcast();
731 pExtColorConfig.reset();
733 m_xColorConfigCT.reset();
736 std::unique_ptr<SfxTabPage> SvxColorOptionsTabPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet)
738 return std::make_unique<SvxColorOptionsTabPage>(pPage, pController, *rAttrSet);
741 bool SvxColorOptionsTabPage::FillItemSet( SfxItemSet* )
743 bFillItemSetCalled = true;
744 if (m_xColorSchemeLB->get_value_changed_from_saved())
746 pColorConfig->SetModified();
747 pExtColorConfig->SetModified();
749 if (pColorConfig->IsModified())
750 pColorConfig->Commit();
751 if (pExtColorConfig->IsModified())
752 pExtColorConfig->Commit();
753 return true;
756 void SvxColorOptionsTabPage::Reset( const SfxItemSet* )
758 if(pColorConfig)
760 pColorConfig->ClearModified();
761 pColorConfig->DisableBroadcast();
763 pColorConfig.reset(new EditableColorConfig);
764 m_xColorConfigCT->SetConfig(*pColorConfig);
766 if(pExtColorConfig)
768 pExtColorConfig->ClearModified();
769 pExtColorConfig->DisableBroadcast();
771 pExtColorConfig.reset(new EditableExtendedColorConfig);
772 m_xColorConfigCT->SetExtendedConfig(*pExtColorConfig);
774 OUString sUser = GetUserData();
775 //has to be called always to speed up accessibility tools
776 m_xColorConfigCT->SetScrollPosition(sUser.toInt32());
777 m_xColorSchemeLB->clear();
778 uno::Sequence< OUString > aSchemes = pColorConfig->GetSchemeNames();
779 const OUString* pSchemes = aSchemes.getConstArray();
780 for(sal_Int32 i = 0; i < aSchemes.getLength(); i++)
781 m_xColorSchemeLB->append_text(pSchemes[i]);
782 m_xColorSchemeLB->set_active_text(pColorConfig->GetCurrentSchemeName());
783 m_xColorSchemeLB->save_value();
784 m_xDeleteSchemePB->set_sensitive( aSchemes.getLength() > 1 );
785 UpdateColorConfig();
788 DeactivateRC SvxColorOptionsTabPage::DeactivatePage( SfxItemSet* pSet_ )
790 if ( pSet_ )
791 FillItemSet( pSet_ );
792 return DeactivateRC::LeavePage;
795 void SvxColorOptionsTabPage::UpdateColorConfig()
797 //update the color config control
798 m_xColorConfigCT->Update();
801 IMPL_LINK(SvxColorOptionsTabPage, SchemeChangedHdl_Impl, weld::ComboBox&, rBox, void)
803 pColorConfig->LoadScheme(rBox.get_active_text());
804 pExtColorConfig->LoadScheme(rBox.get_active_text());
805 UpdateColorConfig();
808 IMPL_LINK(SvxColorOptionsTabPage, SaveDeleteHdl_Impl, weld::Button&, rButton, void)
810 if (m_xSaveSchemePB.get() == &rButton)
812 OUString sName;
814 SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
815 ScopedVclPtr<AbstractSvxNameDialog> aNameDlg(pFact->CreateSvxNameDialog(GetFrameWeld(),
816 sName, CuiResId(RID_SVXSTR_COLOR_CONFIG_SAVE2) ));
817 aNameDlg->SetCheckNameHdl( LINK(this, SvxColorOptionsTabPage, CheckNameHdl_Impl));
818 aNameDlg->SetText(CuiResId(RID_SVXSTR_COLOR_CONFIG_SAVE1));
819 aNameDlg->SetHelpId(HID_OPTIONS_COLORCONFIG_SAVE_SCHEME);
820 aNameDlg->SetCheckNameHdl( LINK(this, SvxColorOptionsTabPage, CheckNameHdl_Impl));
821 if(RET_OK == aNameDlg->Execute())
823 aNameDlg->GetName(sName);
824 pColorConfig->AddScheme(sName);
825 pExtColorConfig->AddScheme(sName);
826 m_xColorSchemeLB->append_text(sName);
827 m_xColorSchemeLB->set_active_text(sName);
828 SchemeChangedHdl_Impl(*m_xColorSchemeLB);
831 else
833 DBG_ASSERT(m_xColorSchemeLB->get_count() > 1, "don't delete the last scheme");
834 std::unique_ptr<weld::MessageDialog> xQuery(Application::CreateMessageDialog(GetFrameWeld(),
835 VclMessageType::Question, VclButtonsType::YesNo,
836 CuiResId(RID_SVXSTR_COLOR_CONFIG_DELETE)));
837 xQuery->set_title(CuiResId(RID_SVXSTR_COLOR_CONFIG_DELETE_TITLE));
838 if (RET_YES == xQuery->run())
840 OUString sDeleteScheme(m_xColorSchemeLB->get_active_text());
841 m_xColorSchemeLB->remove(m_xColorSchemeLB->get_active());
842 m_xColorSchemeLB->set_active(0);
843 SchemeChangedHdl_Impl(*m_xColorSchemeLB);
844 //first select the new scheme and then delete the old one
845 pColorConfig->DeleteScheme(sDeleteScheme);
846 pExtColorConfig->DeleteScheme(sDeleteScheme);
849 m_xDeleteSchemePB->set_sensitive(m_xColorSchemeLB->get_count() > 1);
852 IMPL_LINK(SvxColorOptionsTabPage, CheckNameHdl_Impl, AbstractSvxNameDialog&, rDialog, bool )
854 OUString sName;
855 rDialog.GetName(sName);
856 return !sName.isEmpty() && m_xColorSchemeLB->find_text(sName) == -1;
859 void SvxColorOptionsTabPage::FillUserData()
861 SetUserData(OUString::number(m_xColorConfigCT->GetScrollPosition()));
864 IMPL_LINK_NOARG(SvxColorOptionsTabPage, AdjustHeaderBar, const Size&, void)
866 // horizontal positions
867 int nX0 = 0, nX1, nX2, y, width, height;
868 m_rWidget1.get_extents_relative_to(*m_xTable, nX1, y, width, height);
869 m_rWidget2.get_extents_relative_to(*m_xTable, nX2, y, width, height);
870 auto nTextWidth1 = nX1 - nX0;
871 auto nTextWidth2 = nX2 - nX1;
872 m_xOnFT->set_size_request(nTextWidth1, -1);
873 m_xElementFT->set_size_request(nTextWidth2, -1);
874 m_xColorConfigCT->AdjustExtraWidths(nTextWidth2 - 12);
877 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */