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