1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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>
24 #include <tools/debug.hxx>
25 #include <editeng/editids.hrc>
26 #include <svtools/colorcfg.hxx>
27 #include <svtools/extcolorcfg.hxx>
28 #include <svx/colorbox.hxx>
29 #include <unotools/moduleoptions.hxx>
30 #include <vcl/svapp.hxx>
31 #include <vcl/weld.hxx>
32 #include <svx/svxdlg.hxx>
34 #include <dialmgr.hxx>
35 #include "optcolor.hxx"
36 #include <strings.hrc>
37 #include <svtools/miscopt.hxx>
38 #include <officecfg/Office/Common.hxx>
39 using namespace ::com::sun::star
;
40 using namespace ::svtools
;
45 // list of default groups
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" },
79 // color config entry data (see ColorConfigWindow_Impl::Entry below)
84 //checkbox (or simple text)
94 SAL_STRINGIFY(Name), SAL_STRINGIFY(Name##_lb), false
96 #define IDS_CB(Name) \
97 SAL_STRINGIFY(Name), SAL_STRINGIFY(Name##_lb), true
99 // The list of these entries (enum ColorConfigEntry) are in colorcfg.hxx.
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
) },
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_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
) },
144 { Group_Draw
, IDS(drawgrid
) },
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
) },
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
) }
166 // Maps the names of default color schemes to the corresponding TranslateId
167 const std::map
<OUString
, OUString
> &getColorSchemes()
169 static std::map
<OUString
, OUString
> const vColorSchemes
= {
170 {"COLOR_SCHEME_LIBREOFFICE_AUTOMATIC", CuiResId(RID_COLOR_SCHEME_LIBREOFFICE_AUTOMATIC
)},
172 return vColorSchemes
;
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
178 OUString
lcl_SchemeIdToTranslatedName(const OUString
& sSchemeId
)
180 auto it
= getColorSchemes().find(sSchemeId
);
181 if (it
!= getColorSchemes().end())
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
188 OUString
lcl_TranslatedNameToSchemeId(const OUString
& sName
)
190 for (auto it
= getColorSchemes().begin(); it
!= getColorSchemes().end(); ++it
)
191 if (it
->second
== sName
)
196 // ColorConfigWindow_Impl
198 class ColorConfigWindow_Impl
201 explicit ColorConfigWindow_Impl(weld::Window
* pTopLevel
, weld::Container
* pParent
);
204 void SetLinks(Link
<weld::Toggleable
&,void> const&,
205 Link
<ColorListBox
&,void> const&,
206 Link
<weld::Widget
&,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
*);
213 weld::Widget
& GetWidget1()
218 weld::Widget
& GetWidget2()
223 weld::Widget
& GetBody()
228 int GetLabelIndent() const
230 return m_nCheckBoxLabelOffset
;
234 // Chapter -- horizontal group separator stripe with text
238 std::unique_ptr
<weld::Label
> m_xText
;
240 Chapter(weld::Builder
& rBuilder
, const OUString
& pLabelWidget
, bool bShow
);
241 void SetText(const OUString
& rLabel
) { m_xText
->set_label(rLabel
); }
244 // Entry -- a color config entry:
245 // text (checkbox) + color list box
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
253 return std::max(m_xText
->get_preferred_size().Height(),
254 m_xColorList
->get_widget().get_preferred_size().Height());
258 void SetLinks(Link
<weld::Toggleable
&,void> const&,
259 Link
<ColorListBox
&,void> const&,
260 Link
<weld::Widget
&,void> const&);
261 void Update (ColorConfigValue
const&);
262 void Update (ExtendedColorConfigValue
const&);
263 void ColorChanged (ColorConfigValue
&);
264 void ColorChanged (ExtendedColorConfigValue
&);
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
; }
269 // checkbox (CheckBox) or simple text (FixedText)
270 std::unique_ptr
<weld::Widget
> m_xText
;
272 std::unique_ptr
<ColorListBox
> m_xColorList
;
274 Color m_aDefaultColor
;
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
;
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
;
293 SvtModuleOptions aModuleOptions
;
296 void CreateEntries();
300 bool IsGroupVisible (Group
) const;
305 // ColorConfigWindow_Impl::Chapter
307 // ctor for default groups
308 // rParent: parent window (ColorConfigWindow_Impl)
309 // eGroup: which group is this?
310 ColorConfigWindow_Impl::Chapter::Chapter(weld::Builder
& rBuilder
, const OUString
& pLabelWidget
, bool bShow
)
311 : m_xText(rBuilder
.weld_label(pLabelWidget
))
317 // ColorConfigWindow_Impl::Entry
318 ColorConfigWindow_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
)
327 m_xText
= rBuilder
.weld_check_button(pTextWidget
);
329 m_xText
= rBuilder
.weld_label(pTextWidget
);
332 m_xColorList
->SetSlotId(SID_ATTR_CHAR_COLOR
);
333 m_xColorList
->SetAutoDisplayColor(m_aDefaultColor
);
337 m_xText
->set_margin_start(m_xText
->get_margin_start() +
338 nCheckBoxLabelOffset
);
345 void ColorConfigWindow_Impl::Entry::Hide()
348 m_xColorList
->hide();
352 void ColorConfigWindow_Impl::Entry::SetLinks(Link
<weld::Toggleable
&,void> const& rCheckLink
,
353 Link
<ColorListBox
&,void> const& rColorLink
,
354 Link
<weld::Widget
&,void> const& rGetFocusLink
)
356 m_xColorList
->SetSelectHdl(rColorLink
);
357 m_xColorList
->connect_focus_in(rGetFocusLink
);
358 if (weld::Toggleable
* pCheckBox
= dynamic_cast<weld::Toggleable
*>(m_xText
.get()))
360 pCheckBox
->connect_toggled(rCheckLink
);
361 pCheckBox
->connect_focus_in(rGetFocusLink
);
365 // updates a default color config entry
366 void ColorConfigWindow_Impl::Entry::Update(ColorConfigValue
const& rValue
)
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
);
374 // updates an extended color config entry
375 void ColorConfigWindow_Impl::Entry::Update(ExtendedColorConfigValue
const& rValue
)
377 Color
aColor(rValue
.getColor());
378 if (rValue
.getColor() == rValue
.getDefaultColor())
379 m_xColorList
->SelectEntry(COL_AUTO
);
381 m_xColorList
->SelectEntry(aColor
);
384 // color of a default entry has changed
385 void ColorConfigWindow_Impl::Entry::ColorChanged(ColorConfigValue
& rValue
)
387 Color aColor
= m_xColorList
->GetSelectEntryColor();
388 rValue
.nColor
= aColor
;
391 // color of an extended entry has changed
392 void ColorConfigWindow_Impl::Entry::ColorChanged(ExtendedColorConfigValue
& rValue
)
394 Color aColor
= m_xColorList
->GetSelectEntryColor();
395 rValue
.setColor(aColor
);
396 if (aColor
== COL_AUTO
)
398 rValue
.setColor(rValue
.getDefaultColor());
402 // ColorConfigWindow_Impl
403 ColorConfigWindow_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"))
413 void ColorConfigWindow_Impl::CreateEntries()
415 std::bitset
<nGroupCount
> aModulesInstalled
;
416 // creating group headers
417 vChapters
.reserve(nGroupCount
);
418 for (unsigned i
= 0; i
!= nGroupCount
; ++i
)
420 aModulesInstalled
[i
] = IsGroupVisible(vGroupInfo
[i
].eGroup
);
421 vChapters
.push_back(std::make_shared
<Chapter
>(*m_xBuilder
, vGroupInfo
[i
].pGroup
, aModulesInstalled
[i
]));
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
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();
441 const ColorListBox
* pCache
= nullptr;
444 vEntries
.reserve(ColorConfigEntryCount
);
445 for (size_t i
= 0; i
< std::size(vEntryInfo
); ++i
)
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
]));
454 pCache
= vEntries
.back()->m_xColorList
.get();
458 ExtendedColorConfig aExtConfig
;
459 unsigned const nExtGroupCount
= aExtConfig
.GetComponentCount();
463 for (unsigned j
= 0; j
!= nExtGroupCount
; ++j
)
465 vExtBuilders
.emplace_back(Application::CreateBuilder(m_xBox
.get(), "cui/ui/chapterfragment.ui"));
466 vExtContainers
.emplace_back(vExtBuilders
.back()->weld_frame("ChapterFragment"));
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
));
473 vExtContainers
.emplace_back(vExtBuilders
.back()->weld_box("contents"));
474 weld::Container
* pChapterBox
= vExtContainers
.back().get();
476 unsigned nColorCount
= aExtConfig
.GetComponentColorCount(sComponentName
);
477 for (unsigned i
= 0; i
!= nColorCount
; ++i
)
479 vExtBuilders
.emplace_back(Application::CreateBuilder(pChapterBox
, "cui/ui/colorfragment.ui"));
480 vExtContainers
.emplace_back(vExtBuilders
.back()->weld_container("ColorFragment"));
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());
493 void 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
)
498 if (vEntries
.empty())
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);
507 void ColorConfigWindow_Impl::Update (
508 EditableColorConfig
const* pConfig
,
509 EditableExtendedColorConfig
const* pExtConfig
)
511 // updating default entries
512 for (unsigned i
= 0; i
!= ColorConfigEntryCount
; ++i
)
514 ColorConfigEntry
const aColorEntry
= static_cast<ColorConfigEntry
>(i
);
516 pConfig
->GetColorValue(aColorEntry
)
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
)
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
)
529 pExtConfig
->GetComponentColorConfigValue(sComponentName
, k
)
534 void ColorConfigWindow_Impl::UpdateEntries()
536 for (unsigned i
= 0; i
!= ColorConfigEntryCount
; ++i
)
538 ColorConfigEntry
const aEntry
= static_cast<ColorConfigEntry
>(i
);
539 Color aColor
= ColorConfig::GetDefaultColor(aEntry
);
540 vEntries
[i
]->m_xColorList
->SetAutoDisplayColor(aColor
);
545 void ColorConfigWindow_Impl::ClickHdl(EditableColorConfig
* pConfig
, const weld::Toggleable
& rBox
)
547 for (unsigned i
= 0; i
!= ColorConfigEntryCount
; ++i
)
549 if (vEntries
[i
]->Is(&rBox
))
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
);
561 void ColorConfigWindow_Impl::ColorHdl(
562 EditableColorConfig
* pConfig
, EditableExtendedColorConfig
* pExtConfig
,
563 const ColorListBox
* pBox
)
568 for ( ; i
!= ColorConfigEntryCount
; ++i
)
570 if (pBox
&& vEntries
[i
]->Is(pBox
))
572 ColorConfigEntry
const aColorEntry
= static_cast<ColorConfigEntry
>(i
);
573 ColorConfigValue aValue
= pConfig
->GetColorValue(aColorEntry
);
574 vEntries
[i
]->ColorChanged(aValue
);
575 pConfig
->SetColorValue(aColorEntry
, aValue
);
581 unsigned const nExtCount
= pExtConfig
->GetComponentCount();
582 i
= ColorConfigEntryCount
;
583 for (unsigned j
= 0; j
!= nExtCount
; ++j
)
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
)
590 if (pBox
&& vEntries
[i
]->Is(pBox
))
592 ExtendedColorConfigValue aValue
=
593 pExtConfig
->GetComponentColorConfigValue(sComponentName
, k
);
594 vEntries
[i
]->ColorChanged(aValue
);
595 pExtConfig
->SetColorValue(sComponentName
, aValue
);
604 bool ColorConfigWindow_Impl::IsGroupVisible (Group eGroup
) const
610 return aModuleOptions
.IsModuleInstalled(SvtModuleOptions::EModule::WRITER
);
612 return aModuleOptions
.IsModuleInstalled(SvtModuleOptions::EModule::CALC
);
615 aModuleOptions
.IsModuleInstalled(SvtModuleOptions::EModule::DRAW
) ||
616 aModuleOptions
.IsModuleInstalled(SvtModuleOptions::EModule::IMPRESS
);
618 return aModuleOptions
.IsModuleInstalled(SvtModuleOptions::EModule::DATABASE
);
624 class ColorConfigCtrl_Impl
626 std::unique_ptr
<weld::ScrolledWindow
> m_xVScroll
;
627 std::unique_ptr
<weld::Container
> m_xBody
;
628 std::unique_ptr
<ColorConfigWindow_Impl
> m_xScrollWindow
;
630 EditableColorConfig
* pColorConfig
;
631 EditableExtendedColorConfig
* pExtColorConfig
;
633 DECL_LINK(ClickHdl
, weld::Toggleable
&, void);
634 DECL_LINK(ColorHdl
, ColorListBox
&, void);
635 DECL_LINK(ControlFocusHdl
, weld::Widget
&, void);
638 explicit ColorConfigCtrl_Impl(weld::Window
* pTopLevel
, weld::Builder
& rbuilder
);
640 void SetConfig (EditableColorConfig
& rConfig
) { pColorConfig
= &rConfig
; }
641 void SetExtendedConfig (EditableExtendedColorConfig
& rConfig
) { pExtColorConfig
= &rConfig
; }
643 void UpdateEntries();
644 tools::Long
GetScrollPosition() const
646 return m_xVScroll
->vadjustment_get_value();
648 void SetScrollPosition(tools::Long nSet
)
650 m_xVScroll
->vadjustment_set_value(nSet
);
652 weld::Widget
& GetWidget1()
654 return m_xScrollWindow
->GetWidget1();
656 weld::Widget
& GetWidget2()
658 return m_xScrollWindow
->GetWidget2();
660 int GetLabelIndent() const
662 return m_xScrollWindow
->GetLabelIndent();
666 ColorConfigCtrl_Impl::ColorConfigCtrl_Impl(weld::Window
* pTopLevel
, weld::Builder
& rBuilder
)
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)
673 m_xBody
->set_stack_background();
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
);
681 void ColorConfigCtrl_Impl::Update ()
683 DBG_ASSERT(pColorConfig
, "Configuration not set");
684 m_xScrollWindow
->Update(pColorConfig
, pExtColorConfig
);
687 void ColorConfigCtrl_Impl::UpdateEntries()
689 m_xScrollWindow
->UpdateEntries();
692 IMPL_LINK(ColorConfigCtrl_Impl
, ClickHdl
, weld::Toggleable
&, rBox
, void)
694 DBG_ASSERT(pColorConfig
, "Configuration not set");
695 m_xScrollWindow
->ClickHdl(pColorConfig
, rBox
);
698 // a color list has changed
699 IMPL_LINK(ColorConfigCtrl_Impl
, ColorHdl
, ColorListBox
&, rBox
, void)
701 DBG_ASSERT(pColorConfig
, "Configuration not set" );
702 m_xScrollWindow
->ColorHdl(pColorConfig
, pExtColorConfig
, &rBox
);
705 IMPL_LINK(ColorConfigCtrl_Impl
, ControlFocusHdl
, weld::Widget
&, rCtrl
, void)
707 // determine whether a control is completely visible
708 // and make it visible
709 unsigned const nWinHeight
= m_xVScroll
->vadjustment_get_page_size();
712 auto nThumbPos
= m_xVScroll
->vadjustment_get_value();
713 int const nWinTop
= nThumbPos
;
714 int const nWinBottom
= nWinTop
+ nWinHeight
;
716 int x
, nCtrlPosY
, width
, nHeight
;
717 rCtrl
.get_extents_relative_to(m_xScrollWindow
->GetBody(), x
, nCtrlPosY
, width
, nHeight
);
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;
728 if (shouldScrollDown
)
730 int nOffset
= nSelectedItemBottom
- nWinBottom
;
731 nThumbPos
+= nOffset
+ 2;
735 int nOffset
= nWinTop
- nSelectedItemTop
;
736 nThumbPos
-= nOffset
+ 2;
740 m_xVScroll
->vadjustment_set_value(nThumbPos
);
743 // SvxColorOptionsTabPage
744 SvxColorOptionsTabPage::SvxColorOptionsTabPage(weld::Container
* pPage
, weld::DialogController
* pController
, const SfxItemSet
& rCoreSet
)
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())
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
);
766 m_rWidget1
.connect_size_allocate(LINK(this, SvxColorOptionsTabPage
, AdjustHeaderBar
));
767 m_rWidget2
.connect_size_allocate(LINK(this, SvxColorOptionsTabPage
, AdjustHeaderBar
));
770 SvxColorOptionsTabPage::~SvxColorOptionsTabPage()
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())
778 OUString sOldScheme
= m_xColorSchemeLB
->get_saved_value();
779 if(!sOldScheme
.isEmpty())
781 pColorConfig
->SetCurrentSchemeName(sOldScheme
);
782 pExtColorConfig
->SetCurrentSchemeName(sOldScheme
);
785 pColorConfig
->ClearModified();
786 pColorConfig
->EnableBroadcast();
787 pColorConfig
.reset();
789 pExtColorConfig
->ClearModified();
790 pExtColorConfig
->EnableBroadcast();
791 pExtColorConfig
.reset();
793 m_xColorConfigCT
.reset();
794 if (m_nSizeAllocEventId
)
795 Application::RemoveUserEvent(m_nSizeAllocEventId
);
798 std::unique_ptr
<SfxTabPage
> SvxColorOptionsTabPage::Create(weld::Container
* pPage
, weld::DialogController
* pController
, const SfxItemSet
* rAttrSet
)
800 return std::make_unique
<SvxColorOptionsTabPage
>(pPage
, pController
, *rAttrSet
);
803 bool SvxColorOptionsTabPage::FillItemSet( SfxItemSet
* )
805 bFillItemSetCalled
= true;
806 if (m_xColorSchemeLB
->get_value_changed_from_saved())
808 pColorConfig
->SetModified();
809 pExtColorConfig
->SetModified();
811 if (pColorConfig
->IsModified())
812 pColorConfig
->Commit();
813 if (pExtColorConfig
->IsModified())
814 pExtColorConfig
->Commit();
818 void SvxColorOptionsTabPage::Reset( const SfxItemSet
* )
822 pColorConfig
->ClearModified();
823 pColorConfig
->DisableBroadcast();
825 pColorConfig
.reset(new EditableColorConfig
);
826 m_xColorConfigCT
->SetConfig(*pColorConfig
);
830 pExtColorConfig
->ClearModified();
831 pExtColorConfig
->DisableBroadcast();
833 pExtColorConfig
.reset(new EditableExtendedColorConfig
);
834 m_xColorConfigCT
->SetExtendedConfig(*pExtColorConfig
);
836 m_xAutoColorLB
->set_active( MiscSettings::GetAppColorMode() );
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 );
851 DeactivateRC
SvxColorOptionsTabPage::DeactivatePage( SfxItemSet
* pSet_
)
854 FillItemSet( pSet_
);
855 return DeactivateRC::LeavePage
;
858 void SvxColorOptionsTabPage::UpdateColorConfig()
860 //update the color config control
861 m_xColorConfigCT
->Update();
864 IMPL_LINK_NOARG(SvxColorOptionsTabPage
, onAutoColorChanged
, weld::ComboBox
&, void)
866 MiscSettings::SetAppColorMode( m_xAutoColorLB
->get_active() );
868 m_xColorConfigCT
->UpdateEntries();
870 pColorConfig
->LoadScheme(lcl_TranslatedNameToSchemeId(m_xColorSchemeLB
->get_active_text()));
871 pExtColorConfig
->LoadScheme(lcl_TranslatedNameToSchemeId(m_xColorSchemeLB
->get_active_text()));
875 IMPL_LINK(SvxColorOptionsTabPage
, SchemeChangedHdl_Impl
, weld::ComboBox
&, rBox
, void)
877 pColorConfig
->LoadScheme(lcl_TranslatedNameToSchemeId(rBox
.get_active_text()));
878 pExtColorConfig
->LoadScheme(lcl_TranslatedNameToSchemeId(rBox
.get_active_text()));
882 IMPL_LINK(SvxColorOptionsTabPage
, SaveDeleteHdl_Impl
, weld::Button
&, rButton
, void)
884 if (m_xSaveSchemePB
.get() == &rButton
)
888 SvxAbstractDialogFactory
* pFact
= SvxAbstractDialogFactory::Create();
889 ScopedVclPtr
<AbstractSvxNameDialog
> aNameDlg(pFact
->CreateSvxNameDialog(GetFrameWeld(),
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())
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
);
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())
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
);
923 m_xDeleteSchemePB
->set_sensitive(m_xColorSchemeLB
->get_count() > 1);
926 IMPL_LINK(SvxColorOptionsTabPage
, CheckNameHdl_Impl
, AbstractSvxNameDialog
&, rDialog
, bool )
929 rDialog
.GetName(sName
);
930 return !sName
.isEmpty() && m_xColorSchemeLB
->find_text(sName
) == -1;
933 void SvxColorOptionsTabPage::FillUserData()
935 SetUserData(OUString::number(m_xColorConfigCT
->GetScrollPosition()));
938 IMPL_LINK_NOARG(SvxColorOptionsTabPage
, AdjustHeaderBar
, const Size
&, void)
940 if (m_nSizeAllocEventId
)
942 m_nSizeAllocEventId
= Application::PostUserEvent(LINK(this, SvxColorOptionsTabPage
, PostAdjustHeaderBar
));
945 IMPL_LINK_NOARG(SvxColorOptionsTabPage
, PostAdjustHeaderBar
, void*, void)
947 m_nSizeAllocEventId
= nullptr;
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
))
953 if (!m_rWidget2
.get_extents_relative_to(*m_xTable
, nX2
, y
, width
, height
))
955 if (!m_xTable
->get_extents_relative_to(*m_xTable
, nX3
, y
, width
, height
))
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);
965 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */