LibreOffice Module cui (master) 1
optcolor.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
20#include <sal/config.h>
21
22#include <bitset>
23
24#include <tools/debug.hxx>
25#include <editeng/editids.hrc>
26#include <svtools/colorcfg.hxx>
28#include <svx/colorbox.hxx>
30#include <vcl/svapp.hxx>
31#include <vcl/weld.hxx>
32#include <svx/svxdlg.hxx>
33#include <helpids.h>
34#include <dialmgr.hxx>
35#include "optcolor.hxx"
36#include <strings.hrc>
37#include <svtools/miscopt.hxx>
38#include <officecfg/Office/Common.hxx>
39using namespace ::com::sun::star;
40using namespace ::svtools;
41
42namespace
43{
44
45// list of default groups
46enum Group
47{
48 Group_General,
49 Group_Writer,
50 Group_Html,
51 Group_Calc,
52 Group_Draw,
53 Group_Basic,
54 Group_Sql,
55
56 nGroupCount
57};
58
59// group data
60struct
61{
62 // group
63 Group eGroup;
64 // .ui group name
65 OUString pGroup;
66}
67const vGroupInfo[] =
68{
69 // the groups are in the same order as in enum Group above
70 { Group_General, "general" },
71 { Group_Writer, "writer" },
72 { Group_Html, "html" },
73 { Group_Calc, "calc" },
74 { Group_Draw, "draw" },
75 { Group_Basic, "basic" },
76 { Group_Sql, "sql" }
77};
78
79// color config entry data (see ColorConfigWindow_Impl::Entry below)
80struct
81{
82 // group
83 Group eGroup;
84 //checkbox (or simple text)
85 OUString pText;
86 //color listbox
87 OUString pColor;
88 // has checkbox?
89 bool bCheckBox;
90}
91const vEntryInfo[] =
92{
93 #define IDS(Name) \
94 SAL_STRINGIFY(Name), SAL_STRINGIFY(Name##_lb), false
95
96 #define IDS_CB(Name) \
97 SAL_STRINGIFY(Name), SAL_STRINGIFY(Name##_lb), true
98
99 // The list of these entries (enum ColorConfigEntry) are in colorcfg.hxx.
100
101 { Group_General, IDS(doccolor) },
102 { Group_General, IDS_CB(docboundaries) },
103 { Group_General, IDS(appback) },
104 { Group_General, IDS_CB(objboundaries) },
105 { Group_General, IDS_CB(tblboundaries) },
106 { Group_General, IDS(font) },
107 { Group_General, IDS_CB(unvisitedlinks) },
108 { Group_General, IDS_CB(visitedlinks) },
109 { Group_General, IDS(autospellcheck) },
110 { Group_General, IDS(grammarcheck) },
111 { Group_General, IDS(smarttags) },
112 { Group_General, IDS_CB(shadows) },
113
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) },
122
123 { Group_Html, IDS(sgml) },
124 { Group_Html, IDS(htmlcomment) },
125 { Group_Html, IDS(htmlkeyword) },
126 { Group_Html, IDS(unknown) },
127
128 { Group_Calc, IDS(calcgrid) },
129 { Group_Calc, IDS(brk) },
130 { Group_Calc, IDS(brkmanual) },
131 { Group_Calc, IDS(brkauto) },
132 { Group_Calc, IDS_CB(hiddencolrow) },
133 { Group_Calc, IDS_CB(textoverflow) },
134 { Group_Calc, IDS(comments) },
135 { Group_Calc, IDS(det) },
136 { Group_Calc, IDS(deterror) },
137 { Group_Calc, IDS(ref) },
138 { Group_Calc, IDS(notes) },
139 { Group_Calc, IDS(values) },
140 { Group_Calc, IDS(formulas) },
141 { Group_Calc, IDS(text) },
142 { Group_Calc, IDS(protectedcells) },
143
144 { Group_Draw, IDS(drawgrid) },
145
146 { Group_Basic, IDS(basiceditor) },
147 { Group_Basic, IDS(basicid) },
148 { Group_Basic, IDS(basiccomment) },
149 { Group_Basic, IDS(basicnumber) },
150 { Group_Basic, IDS(basicstring) },
151 { Group_Basic, IDS(basicop) },
152 { Group_Basic, IDS(basickeyword) },
153 { Group_Basic, IDS(error) },
154
155 { Group_Sql, IDS(sqlid) },
156 { Group_Sql, IDS(sqlnumber) },
157 { Group_Sql, IDS(sqlstring) },
158 { Group_Sql, IDS(sqlop) },
159 { Group_Sql, IDS(sqlkeyword) },
160 { Group_Sql, IDS(sqlparam) },
161 { Group_Sql, IDS(sqlcomment) }
162
163 #undef IDS
164};
165
166// Maps the names of default color schemes to the corresponding TranslateId
167const std::map<OUString, OUString> &getColorSchemes()
168{
169 static std::map<OUString, OUString> const vColorSchemes = {
170 {"COLOR_SCHEME_LIBREOFFICE_AUTOMATIC", CuiResId(RID_COLOR_SCHEME_LIBREOFFICE_AUTOMATIC)},
171 };
172 return vColorSchemes;
173};
174
175// If the color scheme name has a translated string, then return the translation
176// Or else simply return the input string
177// For non-translatable color schemes, the ID and the name are the same
178OUString lcl_SchemeIdToTranslatedName(const OUString& sSchemeId)
179{
180 auto it = getColorSchemes().find(sSchemeId);
181 if (it != getColorSchemes().end())
182 return it->second;
183 return sSchemeId;
184}
185
186// Given a translated color scheme name, return the scheme ID used in the UI.xcu file
187// For non-translatable color schemes, the ID and the name are the same
188OUString lcl_TranslatedNameToSchemeId(const OUString& sName)
189{
190 for (auto it = getColorSchemes().begin(); it != getColorSchemes().end(); ++it)
191 if (it->second == sName)
192 return it->first;
193 return sName;
194}
195
196// ColorConfigWindow_Impl
197
198class ColorConfigWindow_Impl
199{
200public:
201 explicit ColorConfigWindow_Impl(weld::Window* pTopLevel, weld::Container* pParent);
202
203public:
204 void SetLinks(Link<weld::Toggleable&,void> const&,
207 weld::ScrolledWindow& rScroll);
208 void Update(EditableColorConfig const*, EditableExtendedColorConfig const*);
209 void UpdateEntries();
210 void ClickHdl(EditableColorConfig*, const weld::Toggleable&);
211 void ColorHdl(EditableColorConfig*, EditableExtendedColorConfig*, const ColorListBox*);
212
213 weld::Widget& GetWidget1()
214 {
215 return *m_xWidget1;
216 }
217
218 weld::Widget& GetWidget2()
219 {
220 return *m_xWidget2;
221 }
222
223 weld::Widget& GetBody()
224 {
225 return *m_xBox;
226 }
227
228 int GetLabelIndent() const
229 {
230 return m_nCheckBoxLabelOffset;
231 }
232
233private:
234 // Chapter -- horizontal group separator stripe with text
235 class Chapter
236 {
237 // text
238 std::unique_ptr<weld::Label> m_xText;
239 public:
240 Chapter(weld::Builder& rBuilder, const OUString& pLabelWidget, bool bShow);
241 void SetText(const OUString& rLabel) { m_xText->set_label(rLabel); }
242 };
243
244 // Entry -- a color config entry:
245 // text (checkbox) + color list box
246 struct Entry
247 {
248 Entry(weld::Window* pTopLevel, weld::Builder& rBuilder, const OUString& pTextWidget, const OUString& pColorWidget,
249 const Color& rColor, int nCheckBoxLabelOffset, const ColorListBox* pCache, bool bCheckBox, bool bShow);
250 void SetText(const OUString& rLabel) { dynamic_cast<weld::Label&>(*m_xText).set_label(rLabel); }
251 int get_height_request() const
252 {
253 return std::max(m_xText->get_preferred_size().Height(),
254 m_xColorList->get_widget().get_preferred_size().Height());
255 }
256 void Hide();
257
258 void SetLinks(Link<weld::Toggleable&,void> const&,
261 void Update (ColorConfigValue const&);
262 void Update (ExtendedColorConfigValue const&);
263 void ColorChanged (ColorConfigValue&);
264 void ColorChanged (ExtendedColorConfigValue&);
265
266 bool Is(const weld::Toggleable* pBox) const { return m_xText.get() == pBox; }
267 bool Is(const ColorListBox* pBox) const { return m_xColorList.get() == pBox; }
268
269 // checkbox (CheckBox) or simple text (FixedText)
270 std::unique_ptr<weld::Widget> m_xText;
271 // color list box
272 std::unique_ptr<ColorListBox> m_xColorList;
273 // default color
274 Color m_aDefaultColor;
275 };
276
277private:
278 weld::Window* m_pTopLevel;
279 int m_nCheckBoxLabelOffset;
280 std::unique_ptr<weld::Builder> m_xBuilder;
281 std::unique_ptr<weld::Box> m_xBox;
282 std::unique_ptr<weld::Widget> m_xWidget1;
283 std::unique_ptr<weld::Widget> m_xWidget2;
284
285 std::vector<std::unique_ptr<weld::Builder>> vExtBuilders;
286 std::vector<std::unique_ptr<weld::Container>> vExtContainers;
287 // vChapters -- groups (group headers)
288 std::vector<std::shared_ptr<Chapter> > vChapters;
289 // vEntries -- color options
290 std::vector<std::shared_ptr<Entry> > vEntries;
291
292 // module options
293 SvtModuleOptions aModuleOptions;
294
295 // initialization
296 void CreateEntries();
297
298private:
299
300 bool IsGroupVisible (Group) const;
301};
302
303} // namespace
304
305// ColorConfigWindow_Impl::Chapter
306
307// ctor for default groups
308// rParent: parent window (ColorConfigWindow_Impl)
309// eGroup: which group is this?
310ColorConfigWindow_Impl::Chapter::Chapter(weld::Builder& rBuilder, const OUString& pLabelWidget, bool bShow)
311 : m_xText(rBuilder.weld_label(pLabelWidget))
312{
313 if (!bShow)
314 m_xText->hide();
315}
316
317// ColorConfigWindow_Impl::Entry
318ColorConfigWindow_Impl::Entry::Entry(weld::Window* pTopLevel, weld::Builder& rBuilder,
319 const OUString& pTextWidget, const OUString& pColorWidget,
320 const Color& rColor, int nCheckBoxLabelOffset,
321 const ColorListBox* pCache, bool bCheckBox, bool bShow)
322 : m_xColorList(new ColorListBox(rBuilder.weld_menu_button(pColorWidget),
323 [pTopLevel]{ return pTopLevel; }, pCache))
324 , m_aDefaultColor(rColor)
325{
326 if (bCheckBox)
327 m_xText = rBuilder.weld_check_button(pTextWidget);
328 else
329 m_xText = rBuilder.weld_label(pTextWidget);
330
331 // color list
332 m_xColorList->SetSlotId(SID_ATTR_CHAR_COLOR);
333 m_xColorList->SetAutoDisplayColor(m_aDefaultColor);
334
335 if (!bCheckBox)
336 {
337 m_xText->set_margin_start(m_xText->get_margin_start() +
338 nCheckBoxLabelOffset);
339 }
340
341 if (!bShow)
342 Hide();
343}
344
345void ColorConfigWindow_Impl::Entry::Hide()
346{
347 m_xText->hide();
348 m_xColorList->hide();
349}
350
351// SetLinks()
352void ColorConfigWindow_Impl::Entry::SetLinks(Link<weld::Toggleable&,void> const& rCheckLink,
353 Link<ColorListBox&,void> const& rColorLink,
354 Link<weld::Widget&,void> const& rGetFocusLink)
355{
356 m_xColorList->SetSelectHdl(rColorLink);
357 m_xColorList->connect_focus_in(rGetFocusLink);
358 if (weld::Toggleable* pCheckBox = dynamic_cast<weld::Toggleable*>(m_xText.get()))
359 {
360 pCheckBox->connect_toggled(rCheckLink);
361 pCheckBox->connect_focus_in(rGetFocusLink);
362 }
363}
364
365// updates a default color config entry
366void ColorConfigWindow_Impl::Entry::Update(ColorConfigValue const& rValue)
367{
368 Color aColor(rValue.nColor);
369 m_xColorList->SelectEntry(aColor);
370 if (weld::Toggleable* pCheckBox = dynamic_cast<weld::Toggleable*>(m_xText.get()))
371 pCheckBox->set_active(rValue.bIsVisible);
372}
373
374// updates an extended color config entry
375void ColorConfigWindow_Impl::Entry::Update(ExtendedColorConfigValue const& rValue)
376{
377 Color aColor(rValue.getColor());
378 if (rValue.getColor() == rValue.getDefaultColor())
379 m_xColorList->SelectEntry(COL_AUTO);
380 else
381 m_xColorList->SelectEntry(aColor);
382}
383
384// color of a default entry has changed
385void ColorConfigWindow_Impl::Entry::ColorChanged(ColorConfigValue& rValue)
386{
387 Color aColor = m_xColorList->GetSelectEntryColor();
388 rValue.nColor = aColor;
389}
390
391// color of an extended entry has changed
392void ColorConfigWindow_Impl::Entry::ColorChanged(ExtendedColorConfigValue& rValue)
393{
394 Color aColor = m_xColorList->GetSelectEntryColor();
395 rValue.setColor(aColor);
396 if (aColor == COL_AUTO)
397 {
398 rValue.setColor(rValue.getDefaultColor());
399 }
400}
401
402// ColorConfigWindow_Impl
403ColorConfigWindow_Impl::ColorConfigWindow_Impl(weld::Window* pTopLevel, weld::Container* pParent)
404 : m_pTopLevel(pTopLevel)
405 , m_xBuilder(Application::CreateBuilder(pParent, "cui/ui/colorconfigwin.ui"))
406 , m_xBox(m_xBuilder->weld_box("ColorConfigWindow"))
407 , m_xWidget1(m_xBuilder->weld_widget("docboundaries"))
408 , m_xWidget2(m_xBuilder->weld_widget("docboundaries_lb"))
409{
410 CreateEntries();
411}
412
413void ColorConfigWindow_Impl::CreateEntries()
414{
415 std::bitset<nGroupCount> aModulesInstalled;
416 // creating group headers
417 vChapters.reserve(nGroupCount);
418 for (unsigned i = 0; i != nGroupCount; ++i)
419 {
420 aModulesInstalled[i] = IsGroupVisible(vGroupInfo[i].eGroup);
421 vChapters.push_back(std::make_shared<Chapter>(*m_xBuilder, vGroupInfo[i].pGroup, aModulesInstalled[i]));
422 }
423
424 // Here we want to get the amount to add to the position of a FixedText to
425 // get it to align its contents with that of a CheckBox
426 {
427 OUString sSampleText("XXXXXX");
428 std::unique_ptr<weld::CheckButton> xCheckBox(m_xBuilder->weld_check_button("docboundaries"));
429 std::unique_ptr<weld::Label> xFixedText(m_xBuilder->weld_label("doccolor"));
430 OUString sOrigCheck(xCheckBox->get_label());
431 OUString sOrigFixed(xFixedText->get_label());
432 xCheckBox->set_label(sSampleText);
433 xFixedText->set_label(sSampleText);
434 Size aCheckSize(xCheckBox->get_preferred_size());
435 Size aFixedSize(xFixedText->get_preferred_size());
436 xCheckBox->set_label(sOrigCheck);
437 xFixedText->set_label(sOrigFixed);
438 m_nCheckBoxLabelOffset = aCheckSize.Width() - aFixedSize.Width();
439 }
440
441 const ColorListBox* pCache = nullptr;
442
443 // creating entries
444 vEntries.reserve(ColorConfigEntryCount);
445 for (size_t i = 0; i < std::size(vEntryInfo); ++i)
446 {
447 vEntries.push_back(std::make_shared<Entry>(m_pTopLevel, *m_xBuilder,
448 vEntryInfo[i].pText, vEntryInfo[i].pColor,
449 ColorConfig::GetDefaultColor(static_cast<ColorConfigEntry>(i)),
450 m_nCheckBoxLabelOffset, pCache,
451 vEntryInfo[i].bCheckBox,
452 aModulesInstalled[vEntryInfo[i].eGroup]));
453 if (!pCache)
454 pCache = vEntries.back()->m_xColorList.get();
455 }
456
457 // extended entries
458 ExtendedColorConfig aExtConfig;
459 unsigned const nExtGroupCount = aExtConfig.GetComponentCount();
460 if (!nExtGroupCount)
461 return;
462
463 for (unsigned j = 0; j != nExtGroupCount; ++j)
464 {
465 vExtBuilders.emplace_back(Application::CreateBuilder(m_xBox.get(), "cui/ui/chapterfragment.ui"));
466 vExtContainers.emplace_back(vExtBuilders.back()->weld_frame("ChapterFragment"));
467
468 OUString const sComponentName = aExtConfig.GetComponentName(j);
469 vChapters.push_back(std::make_shared<Chapter>(
470 *vExtBuilders.back(), "chapter", true));
471 vChapters.back()->SetText(aExtConfig.GetComponentDisplayName(sComponentName));
472
473 vExtContainers.emplace_back(vExtBuilders.back()->weld_box("contents"));
474 weld::Container* pChapterBox = vExtContainers.back().get();
475
476 unsigned nColorCount = aExtConfig.GetComponentColorCount(sComponentName);
477 for (unsigned i = 0; i != nColorCount; ++i)
478 {
479 vExtBuilders.emplace_back(Application::CreateBuilder(pChapterBox, "cui/ui/colorfragment.ui"));
480 vExtContainers.emplace_back(vExtBuilders.back()->weld_container("ColorFragment"));
481
482 ExtendedColorConfigValue const aColorEntry =
483 aExtConfig.GetComponentColorConfigValue(sComponentName, i);
484 vEntries.push_back(std::make_shared<Entry>(m_pTopLevel, *vExtBuilders.back(),
485 "label", "button", aColorEntry.getDefaultColor(),
486 m_nCheckBoxLabelOffset, pCache, false, true));
487 vEntries.back()->SetText(aColorEntry.getDisplayName());
488 }
489 }
490}
491
492// SetLinks()
493void ColorConfigWindow_Impl::SetLinks(Link<weld::Toggleable&,void> const& aCheckLink,
494 Link<ColorListBox&,void> const& aColorLink,
495 Link<weld::Widget&,void> const& rGetFocusLink,
496 weld::ScrolledWindow& rScroll)
497{
498 if (vEntries.empty())
499 return;
500 for (auto const & i: vEntries)
501 i->SetLinks(aCheckLink, aColorLink, rGetFocusLink);
502 // 6 is the spacing set on ColorConfigWindow
503 rScroll.vadjustment_set_step_increment(vEntries[0]->get_height_request() + 6);
504}
505
506// Update()
507void ColorConfigWindow_Impl::Update (
508 EditableColorConfig const* pConfig,
509 EditableExtendedColorConfig const* pExtConfig)
510{
511 // updating default entries
512 for (unsigned i = 0; i != ColorConfigEntryCount; ++i)
513 {
514 ColorConfigEntry const aColorEntry = static_cast<ColorConfigEntry>(i);
515 vEntries[i]->Update(
516 pConfig->GetColorValue(aColorEntry)
517 );
518 }
519
520 // updating extended entries
521 decltype(vEntries)::size_type i = ColorConfigEntryCount;
522 unsigned const nExtCount = pExtConfig->GetComponentCount();
523 for (unsigned j = 0; j != nExtCount; ++j)
524 {
525 OUString sComponentName = pExtConfig->GetComponentName(j);
526 unsigned const nColorCount = pExtConfig->GetComponentColorCount(sComponentName);
527 for (unsigned k = 0; i != vEntries.size() && k != nColorCount; ++i, ++k)
528 vEntries[i]->Update(
529 pExtConfig->GetComponentColorConfigValue(sComponentName, k)
530 );
531 }
532}
533
534void ColorConfigWindow_Impl::UpdateEntries()
535{
536 for (unsigned i = 0; i != ColorConfigEntryCount; ++i)
537 {
538 ColorConfigEntry const aEntry = static_cast<ColorConfigEntry>(i);
539 Color aColor = ColorConfig::GetDefaultColor(aEntry);
540 vEntries[i]->m_xColorList->SetAutoDisplayColor(aColor);
541 }
542}
543
544// ClickHdl()
545void ColorConfigWindow_Impl::ClickHdl(EditableColorConfig* pConfig, const weld::Toggleable& rBox)
546{
547 for (unsigned i = 0; i != ColorConfigEntryCount; ++i)
548 {
549 if (vEntries[i]->Is(&rBox))
550 {
551 ColorConfigEntry const aEntry = static_cast<ColorConfigEntry>(i);
552 ColorConfigValue aValue = pConfig->GetColorValue(aEntry);
553 aValue.bIsVisible = rBox.get_active();
554 pConfig->SetColorValue(aEntry, aValue);
555 break;
556 }
557 }
558}
559
560// ColorHdl()
561void ColorConfigWindow_Impl::ColorHdl(
562 EditableColorConfig* pConfig, EditableExtendedColorConfig* pExtConfig,
563 const ColorListBox* pBox)
564{
565 unsigned i = 0;
566
567 // default entries
568 for ( ; i != ColorConfigEntryCount; ++i)
569 {
570 if (pBox && vEntries[i]->Is(pBox))
571 {
572 ColorConfigEntry const aColorEntry = static_cast<ColorConfigEntry>(i);
573 ColorConfigValue aValue = pConfig->GetColorValue(aColorEntry);
574 vEntries[i]->ColorChanged(aValue);
575 pConfig->SetColorValue(aColorEntry, aValue);
576 break;
577 }
578 }
579
580 // extended entries
581 unsigned const nExtCount = pExtConfig->GetComponentCount();
583 for (unsigned j = 0; j != nExtCount; ++j)
584 {
585 OUString sComponentName = pExtConfig->GetComponentName(j);
586 unsigned const nColorCount = pExtConfig->GetComponentColorCount(sComponentName);
587 unsigned const nCount = vEntries.size();
588 for (unsigned k = 0; i != nCount && k != nColorCount; ++i, ++k)
589 {
590 if (pBox && vEntries[i]->Is(pBox))
591 {
592 ExtendedColorConfigValue aValue =
593 pExtConfig->GetComponentColorConfigValue(sComponentName, k);
594 vEntries[i]->ColorChanged(aValue);
595 pExtConfig->SetColorValue(sComponentName, aValue);
596 break;
597 }
598 }
599 }
600}
601
602
603// IsGroupVisible()
604bool ColorConfigWindow_Impl::IsGroupVisible (Group eGroup) const
605{
606 switch (eGroup)
607 {
608 case Group_Writer:
609 case Group_Html:
610 return aModuleOptions.IsModuleInstalled(SvtModuleOptions::EModule::WRITER);
611 case Group_Calc:
612 return aModuleOptions.IsModuleInstalled(SvtModuleOptions::EModule::CALC);
613 case Group_Draw:
614 return
615 aModuleOptions.IsModuleInstalled(SvtModuleOptions::EModule::DRAW) ||
616 aModuleOptions.IsModuleInstalled(SvtModuleOptions::EModule::IMPRESS);
617 case Group_Sql:
618 return aModuleOptions.IsModuleInstalled(SvtModuleOptions::EModule::DATABASE);
619 default:
620 return true;
621 }
622}
623
625{
626 std::unique_ptr<weld::ScrolledWindow> m_xVScroll;
627 std::unique_ptr<weld::Container> m_xBody;
628 std::unique_ptr<ColorConfigWindow_Impl> m_xScrollWindow;
629
630 EditableColorConfig* pColorConfig;
631 EditableExtendedColorConfig* pExtColorConfig;
632
633 DECL_LINK(ClickHdl, weld::Toggleable&, void);
634 DECL_LINK(ColorHdl, ColorListBox&, void);
635 DECL_LINK(ControlFocusHdl, weld::Widget&, void);
636
637public:
638 explicit ColorConfigCtrl_Impl(weld::Window* pTopLevel, weld::Builder& rbuilder);
639
640 void SetConfig (EditableColorConfig& rConfig) { pColorConfig = &rConfig; }
641 void SetExtendedConfig (EditableExtendedColorConfig& rConfig) { pExtColorConfig = &rConfig; }
642 void Update();
643 void UpdateEntries();
645 {
646 return m_xVScroll->vadjustment_get_value();
647 }
649 {
650 m_xVScroll->vadjustment_set_value(nSet);
651 }
653 {
654 return m_xScrollWindow->GetWidget1();
655 }
657 {
658 return m_xScrollWindow->GetWidget2();
659 }
660 int GetLabelIndent() const
661 {
662 return m_xScrollWindow->GetLabelIndent();
663 }
664};
665
667 : m_xVScroll(rBuilder.weld_scrolled_window("scroll"))
668 , m_xBody(rBuilder.weld_container("colorconfig"))
669 , m_xScrollWindow(std::make_unique<ColorConfigWindow_Impl>(pTopLevel, m_xBody.get()))
670 , pColorConfig(nullptr)
671 , pExtColorConfig(nullptr)
672{
673 m_xBody->set_stack_background();
674
675 Link<weld::Toggleable&,void> aCheckLink = LINK(this, ColorConfigCtrl_Impl, ClickHdl);
676 Link<ColorListBox&,void> aColorLink = LINK(this, ColorConfigCtrl_Impl, ColorHdl);
677 Link<weld::Widget&,void> const& aGetFocusLink = LINK(this, ColorConfigCtrl_Impl, ControlFocusHdl);
678 m_xScrollWindow->SetLinks(aCheckLink, aColorLink, aGetFocusLink, *m_xVScroll);
679}
680
682{
683 DBG_ASSERT(pColorConfig, "Configuration not set");
685}
686
688{
689 m_xScrollWindow->UpdateEntries();
690}
691
693{
694 DBG_ASSERT(pColorConfig, "Configuration not set");
695 m_xScrollWindow->ClickHdl(pColorConfig, rBox);
696}
697
698// a color list has changed
700{
701 DBG_ASSERT(pColorConfig, "Configuration not set" );
702 m_xScrollWindow->ColorHdl(pColorConfig, pExtColorConfig, &rBox);
703}
704
705IMPL_LINK(ColorConfigCtrl_Impl, ControlFocusHdl, weld::Widget&, rCtrl, void)
706{
707 // determine whether a control is completely visible
708 // and make it visible
709 unsigned const nWinHeight = m_xVScroll->vadjustment_get_page_size();
710
711 // calc visible area
712 auto nThumbPos = m_xVScroll->vadjustment_get_value();
713 int const nWinTop = nThumbPos;
714 int const nWinBottom = nWinTop + nWinHeight;
715
716 int x, nCtrlPosY, width, nHeight;
717 rCtrl.get_extents_relative_to(m_xScrollWindow->GetBody(), x, nCtrlPosY, width, nHeight);
718
719 int const nSelectedItemTop = nCtrlPosY;
720 int const nSelectedItemBottom = nCtrlPosY + nHeight;
721 bool const shouldScrollDown = nSelectedItemBottom >= nWinBottom;
722 bool const shouldScrollUp = nSelectedItemTop <= nWinTop;
723 bool const isNeedToScroll = shouldScrollDown || shouldScrollUp || nCtrlPosY < 0;
724
725 if (!isNeedToScroll)
726 return;
727
728 if (shouldScrollDown)
729 {
730 int nOffset = nSelectedItemBottom - nWinBottom;
731 nThumbPos += nOffset + 2;
732 }
733 else
734 {
735 int nOffset = nWinTop - nSelectedItemTop;
736 nThumbPos -= nOffset + 2;
737 if(nThumbPos < 0)
738 nThumbPos = 0;
739 }
740 m_xVScroll->vadjustment_set_value(nThumbPos);
741}
742
743// SvxColorOptionsTabPage
745 : SfxTabPage(pPage, pController, "cui/ui/optappearancepage.ui", "OptAppearancePage", &rCoreSet)
746 , bFillItemSetCalled(false)
747 , m_nSizeAllocEventId(nullptr)
748 , m_xAutoColorLB(m_xBuilder->weld_combo_box("autocolorlb"))
749 , m_xColorSchemeLB(m_xBuilder->weld_combo_box("colorschemelb"))
750 , m_xSaveSchemePB(m_xBuilder->weld_button("save"))
751 , m_xDeleteSchemePB(m_xBuilder->weld_button("delete"))
752 , m_xColorConfigCT(new ColorConfigCtrl_Impl(pController->getDialog(), *m_xBuilder))
753 , m_xTable(m_xBuilder->weld_widget("table"))
754 , m_xOnFT(m_xBuilder->weld_label("on"))
755 , m_xColorFT(m_xBuilder->weld_label("colorsetting"))
756 , m_rWidget1(m_xColorConfigCT->GetWidget1())
757 , m_rWidget2(m_xColorConfigCT->GetWidget2())
758{
759 m_xColorSchemeLB->make_sorted();
760 m_xColorSchemeLB->connect_changed(LINK(this, SvxColorOptionsTabPage, SchemeChangedHdl_Impl));
761 m_xAutoColorLB->connect_changed(LINK(this, SvxColorOptionsTabPage, onAutoColorChanged));
762 Link<weld::Button&,void> aLk = LINK(this, SvxColorOptionsTabPage, SaveDeleteHdl_Impl );
763 m_xSaveSchemePB->connect_clicked(aLk);
764 m_xDeleteSchemePB->connect_clicked(aLk);
765
768}
769
771{
772 if (pColorConfig)
773 {
774 //when the dialog is cancelled but the color scheme ListBox has been changed these
775 //changes need to be undone
776 if (!bFillItemSetCalled && m_xColorSchemeLB->get_value_changed_from_saved())
777 {
778 OUString sOldScheme = m_xColorSchemeLB->get_saved_value();
779 if(!sOldScheme.isEmpty())
780 {
781 pColorConfig->SetCurrentSchemeName(sOldScheme);
782 pExtColorConfig->SetCurrentSchemeName(sOldScheme);
783 }
784 }
785 pColorConfig->ClearModified();
786 pColorConfig->EnableBroadcast();
787 pColorConfig.reset();
788
789 pExtColorConfig->ClearModified();
790 pExtColorConfig->EnableBroadcast();
791 pExtColorConfig.reset();
792 }
793 m_xColorConfigCT.reset();
796}
797
798std::unique_ptr<SfxTabPage> SvxColorOptionsTabPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet)
799{
800 return std::make_unique<SvxColorOptionsTabPage>(pPage, pController, *rAttrSet);
801}
802
804{
805 bFillItemSetCalled = true;
806 if (m_xColorSchemeLB->get_value_changed_from_saved())
807 {
808 pColorConfig->SetModified();
809 pExtColorConfig->SetModified();
810 }
811 if (pColorConfig->IsModified())
812 pColorConfig->Commit();
813 if (pExtColorConfig->IsModified())
814 pExtColorConfig->Commit();
815 return true;
816}
817
819{
820 if(pColorConfig)
821 {
822 pColorConfig->ClearModified();
823 pColorConfig->DisableBroadcast();
824 }
825 pColorConfig.reset(new EditableColorConfig);
826 m_xColorConfigCT->SetConfig(*pColorConfig);
827
829 {
830 pExtColorConfig->ClearModified();
831 pExtColorConfig->DisableBroadcast();
832 }
833 pExtColorConfig.reset(new EditableExtendedColorConfig);
834 m_xColorConfigCT->SetExtendedConfig(*pExtColorConfig);
835
837
838 OUString sUser = GetUserData();
839 //has to be called always to speed up accessibility tools
840 m_xColorConfigCT->SetScrollPosition(sUser.toInt32());
841 m_xColorSchemeLB->clear();
842 const uno::Sequence< OUString > aSchemes = pColorConfig->GetSchemeNames();
843 for(const OUString& s : aSchemes)
844 m_xColorSchemeLB->append_text(lcl_SchemeIdToTranslatedName(s));
845 m_xColorSchemeLB->set_active_text(lcl_SchemeIdToTranslatedName(pColorConfig->GetCurrentSchemeName()));
846 m_xColorSchemeLB->save_value();
847 m_xDeleteSchemePB->set_sensitive( aSchemes.getLength() > 1 );
849}
850
852{
853 if ( pSet_ )
854 FillItemSet( pSet_ );
855 return DeactivateRC::LeavePage;
856}
857
859{
860 //update the color config control
861 m_xColorConfigCT->Update();
862}
863
865{
866 MiscSettings::SetAppColorMode( m_xAutoColorLB->get_active() );
867
868 m_xColorConfigCT->UpdateEntries();
869
870 pColorConfig->LoadScheme(lcl_TranslatedNameToSchemeId(m_xColorSchemeLB->get_active_text()));
871 pExtColorConfig->LoadScheme(lcl_TranslatedNameToSchemeId(m_xColorSchemeLB->get_active_text()));
872 UpdateColorConfig();
873}
874
875IMPL_LINK(SvxColorOptionsTabPage, SchemeChangedHdl_Impl, weld::ComboBox&, rBox, void)
876{
877 pColorConfig->LoadScheme(lcl_TranslatedNameToSchemeId(rBox.get_active_text()));
878 pExtColorConfig->LoadScheme(lcl_TranslatedNameToSchemeId(rBox.get_active_text()));
879 UpdateColorConfig();
880}
881
882IMPL_LINK(SvxColorOptionsTabPage, SaveDeleteHdl_Impl, weld::Button&, rButton, void)
883{
884 if (m_xSaveSchemePB.get() == &rButton)
885 {
886 OUString sName;
887
890 sName, CuiResId(RID_CUISTR_COLOR_CONFIG_SAVE2) ));
891 aNameDlg->SetCheckNameHdl( LINK(this, SvxColorOptionsTabPage, CheckNameHdl_Impl));
892 aNameDlg->SetText(CuiResId(RID_CUISTR_COLOR_CONFIG_SAVE1));
893 aNameDlg->SetHelpId(HID_OPTIONS_COLORCONFIG_SAVE_SCHEME);
894 aNameDlg->SetCheckNameHdl( LINK(this, SvxColorOptionsTabPage, CheckNameHdl_Impl));
895 if(RET_OK == aNameDlg->Execute())
896 {
897 aNameDlg->GetName(sName);
898 pColorConfig->AddScheme(sName);
899 pExtColorConfig->AddScheme(sName);
900 m_xColorSchemeLB->append_text(sName);
901 m_xColorSchemeLB->set_active_text(sName);
902 SchemeChangedHdl_Impl(*m_xColorSchemeLB);
903 }
904 }
905 else
906 {
907 DBG_ASSERT(m_xColorSchemeLB->get_count() > 1, "don't delete the last scheme");
908 std::unique_ptr<weld::MessageDialog> xQuery(Application::CreateMessageDialog(GetFrameWeld(),
909 VclMessageType::Question, VclButtonsType::YesNo,
910 CuiResId(RID_CUISTR_COLOR_CONFIG_DELETE)));
911 xQuery->set_title(CuiResId(RID_CUISTR_COLOR_CONFIG_DELETE_TITLE));
912 if (RET_YES == xQuery->run())
913 {
914 OUString sDeleteScheme(m_xColorSchemeLB->get_active_text());
915 m_xColorSchemeLB->remove(m_xColorSchemeLB->get_active());
916 m_xColorSchemeLB->set_active(0);
917 SchemeChangedHdl_Impl(*m_xColorSchemeLB);
918 //first select the new scheme and then delete the old one
919 pColorConfig->DeleteScheme(sDeleteScheme);
920 pExtColorConfig->DeleteScheme(sDeleteScheme);
921 }
922 }
923 m_xDeleteSchemePB->set_sensitive(m_xColorSchemeLB->get_count() > 1);
924}
925
926IMPL_LINK(SvxColorOptionsTabPage, CheckNameHdl_Impl, AbstractSvxNameDialog&, rDialog, bool )
927{
928 OUString sName;
929 rDialog.GetName(sName);
930 return !sName.isEmpty() && m_xColorSchemeLB->find_text(sName) == -1;
931}
932
934{
935 SetUserData(OUString::number(m_xColorConfigCT->GetScrollPosition()));
936}
937
938IMPL_LINK_NOARG(SvxColorOptionsTabPage, AdjustHeaderBar, const Size&, void)
939{
940 if (m_nSizeAllocEventId)
941 return;
942 m_nSizeAllocEventId = Application::PostUserEvent(LINK(this, SvxColorOptionsTabPage, PostAdjustHeaderBar));
943}
944
945IMPL_LINK_NOARG(SvxColorOptionsTabPage, PostAdjustHeaderBar, void*, void)
946{
947 m_nSizeAllocEventId = nullptr;
948
949 // horizontal positions
950 int nX1, nX2, nX3, y, width, height;
951 if (!m_rWidget1.get_extents_relative_to(*m_xTable, nX1, y, width, height))
952 return;
953 if (!m_rWidget2.get_extents_relative_to(*m_xTable, nX2, y, width, height))
954 return;
955 if (!m_xTable->get_extents_relative_to(*m_xTable, nX3, y, width, height))
956 return;
957
958 // 6 is the column-spacing of the parent grid of these labels
959 auto nTextWidth1 = nX1 + m_xColorConfigCT->GetLabelIndent() - 6;
960 m_xOnFT->set_size_request(nTextWidth1, -1);
961 auto nTextWidth3 = width - nX2;
962 m_xColorFT->set_size_request(nTextWidth3, -1);
963}
964
965/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
struct _ADOGroup Group
static ImplSVEvent * PostUserEvent(const Link< void *, void > &rLink, void *pCaller=nullptr, bool bReferenceLink=false)
static std::unique_ptr< weld::Builder > CreateBuilder(weld::Widget *pParent, const OUString &rUIFile, bool bMobile=false, sal_uInt64 nLOKWindowId=0)
static void RemoveUserEvent(ImplSVEvent *nUserEvent)
static weld::MessageDialog * CreateMessageDialog(weld::Widget *pParent, VclMessageType eMessageType, VclButtonsType eButtonType, const OUString &rPrimaryMessage, const ILibreOfficeKitNotifier *pNotifier=nullptr)
int GetLabelIndent() const
Definition: optcolor.cxx:660
std::unique_ptr< weld::ScrolledWindow > m_xVScroll
Definition: optcolor.cxx:626
tools::Long GetScrollPosition() const
Definition: optcolor.cxx:644
EditableExtendedColorConfig * pExtColorConfig
Definition: optcolor.cxx:631
ColorConfigCtrl_Impl(weld::Window *pTopLevel, weld::Builder &rbuilder)
Definition: optcolor.cxx:666
weld::Widget & GetWidget1()
Definition: optcolor.cxx:652
std::unique_ptr< ColorConfigWindow_Impl > m_xScrollWindow
Definition: optcolor.cxx:628
void SetConfig(EditableColorConfig &rConfig)
Definition: optcolor.cxx:640
void SetExtendedConfig(EditableExtendedColorConfig &rConfig)
Definition: optcolor.cxx:641
EditableColorConfig * pColorConfig
Definition: optcolor.cxx:630
std::unique_ptr< weld::Container > m_xBody
Definition: optcolor.cxx:627
weld::Widget & GetWidget2()
Definition: optcolor.cxx:656
void SetScrollPosition(tools::Long nSet)
Definition: optcolor.cxx:648
DECL_LINK(ClickHdl, weld::Toggleable &, void)
DECL_LINK(ControlFocusHdl, weld::Widget &, void)
DECL_LINK(ColorHdl, ColorListBox &, void)
static int GetAppColorMode()
static void SetAppColorMode(int nMode)
void SetUserData(const OUString &rString)
const OUString & GetUserData() const
virtual VclPtr< AbstractSvxNameDialog > CreateSvxNameDialog(weld::Window *pParent, const OUString &rName, const OUString &rDesc)=0
static SvxAbstractDialogFactory * Create()
virtual void Reset(const SfxItemSet *rSet) override
Definition: optcolor.cxx:818
std::unique_ptr< weld::Button > m_xDeleteSchemePB
Definition: optcolor.hxx:37
std::unique_ptr< weld::ComboBox > m_xAutoColorLB
Definition: optcolor.hxx:34
virtual DeactivateRC DeactivatePage(SfxItemSet *pSet) override
Definition: optcolor.cxx:851
std::unique_ptr< weld::Button > m_xSaveSchemePB
Definition: optcolor.hxx:36
ImplSVEvent * m_nSizeAllocEventId
Definition: optcolor.hxx:32
virtual void FillUserData() override
Definition: optcolor.cxx:933
weld::Widget & m_rWidget1
Definition: optcolor.hxx:43
SvxColorOptionsTabPage(weld::Container *pPage, weld::DialogController *pController, const SfxItemSet &rSet)
Definition: optcolor.cxx:744
std::unique_ptr< weld::ComboBox > m_xColorSchemeLB
Definition: optcolor.hxx:35
std::unique_ptr< ColorConfigCtrl_Impl > m_xColorConfigCT
Definition: optcolor.hxx:38
virtual bool FillItemSet(SfxItemSet *rSet) override
Definition: optcolor.cxx:803
std::unique_ptr< svtools::EditableExtendedColorConfig > pExtColorConfig
Definition: optcolor.hxx:47
virtual ~SvxColorOptionsTabPage() override
Definition: optcolor.cxx:770
static std::unique_ptr< SfxTabPage > Create(weld::Container *pPage, weld::DialogController *pController, const SfxItemSet *rAttrSet)
Definition: optcolor.cxx:798
std::unique_ptr< svtools::EditableColorConfig > pColorConfig
Definition: optcolor.hxx:46
weld::Widget & m_rWidget2
Definition: optcolor.hxx:44
virtual std::unique_ptr< Label > weld_label(const OUString &id)=0
virtual std::unique_ptr< CheckButton > weld_check_button(const OUString &id)=0
virtual void set_label(const OUString &rText)=0
virtual void vadjustment_set_step_increment(int size)=0
virtual bool get_active() const=0
virtual void connect_size_allocate(const Link< const Size &, void > &rLink)
OUString CuiResId(TranslateId aKey)
Definition: cuiresmgr.cxx:23
int nCount
#define DBG_ASSERT(sCon, aError)
weld::Window * GetFrameWeld(const SfxFrame *pFrame)
virtual void SetText(const OUString &rStr) override
float y
float x
OUString sName
constexpr OUStringLiteral HID_OPTIONS_COLORCONFIG_SAVE_SCHEME
Definition: helpids.h:24
int i
enumrange< T >::Iterator begin(enumrange< T >)
end
ColorConfigEntry
ColorConfigEntryCount
css::uno::Reference< css::linguistic2::XProofreadingIterator > get(css::uno::Reference< css::uno::XComponentContext > const &context)
long Long
#define IDS(Name)
#define IDS_CB(Name)
IMPL_LINK_NOARG(SvxColorOptionsTabPage, onAutoColorChanged, weld::ComboBox &, void)
Definition: optcolor.cxx:864
IMPL_LINK(ColorConfigCtrl_Impl, ClickHdl, weld::Toggleable &, rBox, void)
Definition: optcolor.cxx:692
DeactivateRC
RET_OK
RET_YES