bump product version to 5.0.4.1
[LibreOffice.git] / cui / source / options / optcolor.cxx
blobfd4bcab3471ce0aedddc13b02fc6be42aa8c6312
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <sal/config.h>
22 #include <bitset>
24 #include <svtools/colorcfg.hxx>
25 #include <svtools/extcolorcfg.hxx>
26 #include <svtools/headbar.hxx>
27 #include <svtools/ctrlbox.hxx>
28 #include <vcl/scrbar.hxx>
29 #include <svx/xtable.hxx>
30 #include <unotools/moduleoptions.hxx>
31 #include <unotools/pathoptions.hxx>
32 #include <vcl/msgbox.hxx>
33 #include <vcl/settings.hxx>
34 #include <vcl/builderfactory.hxx>
35 #include <boost/scoped_ptr.hpp>
36 #include <boost/shared_ptr.hpp>
37 #include <svx/svxdlg.hxx>
38 #include <helpid.hrc>
39 #include <dialmgr.hxx>
40 #include "optcolor.hxx"
41 #include <cuires.hrc>
42 #include <svx/dlgutil.hxx>
44 using namespace ::com::sun::star;
45 using namespace ::svtools;
47 namespace
50 // list of default groups
51 enum Group
53 Group_Unknown = -1,
55 Group_General,
56 Group_Writer,
57 Group_Html,
58 Group_Calc,
59 Group_Draw,
60 Group_Basic,
61 Group_Sql,
63 nGroupCount
66 // group data
67 struct
69 // group
70 Group eGroup;
71 // .ui group name
72 const char *pGroup;
74 const vGroupInfo[] =
76 // the groups are in the same order as in enum Group above
77 { Group_General, "general" },
78 { Group_Writer, "writer" },
79 { Group_Html, "html" },
80 { Group_Calc, "calc" },
81 { Group_Draw, "draw" },
82 { Group_Basic, "basic" },
83 { Group_Sql, "sql" }
86 // color config entry data (see ColorConfigWindow_Impl::Entry below)
87 struct
89 // group
90 Group eGroup;
91 //checkbox (or simple text)
92 const char *pText;
93 //color listbox
94 const char *pColor;
95 //preview box
96 const char *pPreview;
97 // has checkbox?
98 bool bCheckBox;
100 const vEntryInfo[] =
102 #define IDS(Name) \
103 SAL_STRINGIFY(Name), SAL_STRINGIFY(Name##_lb), SAL_STRINGIFY(Name##_wn), false
105 #define IDS_CB(Name) \
106 SAL_STRINGIFY(Name), SAL_STRINGIFY(Name##_lb), SAL_STRINGIFY(Name##_wn), true
108 // The list of these entries (enum ColorConfigEntry) are in colorcfg.hxx.
110 { Group_General, IDS(doccolor) },
111 { Group_General, IDS_CB(docboundaries) },
112 { Group_General, IDS(appback) },
113 { Group_General, IDS_CB(objboundaries) },
114 { Group_General, IDS_CB(tblboundaries) },
115 { Group_General, IDS(font) },
116 { Group_General, IDS_CB(unvisitedlinks) },
117 { Group_General, IDS_CB(visitedlinks) },
118 { Group_General, IDS(autospellcheck) },
119 { Group_General, IDS(smarttags) },
120 { Group_General, IDS_CB(shadows) },
122 { Group_Writer, IDS(writergrid) },
123 { Group_Writer, IDS_CB(field) },
124 { Group_Writer, IDS_CB(index) },
125 { Group_Writer, IDS(direct) },
126 { Group_Writer, IDS(script) },
127 { Group_Writer, IDS_CB(section) },
128 { Group_Writer, IDS(hdft) },
129 { Group_Writer, IDS(pagebreak) },
131 { Group_Html, IDS(sgml) },
132 { Group_Html, IDS(htmlcomment) },
133 { Group_Html, IDS(htmlkeyword) },
134 { Group_Html, IDS(unknown) },
136 { Group_Calc, IDS(calcgrid) },
137 { Group_Calc, IDS(brk) },
138 { Group_Calc, IDS(brkmanual) },
139 { Group_Calc, IDS(brkauto) },
140 { Group_Calc, IDS(det) },
141 { Group_Calc, IDS(deterror) },
142 { Group_Calc, IDS(ref) },
143 { Group_Calc, IDS(notes) },
145 { Group_Draw, IDS(drawgrid) },
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) }
163 #undef IDS
166 } // namespace
169 // ColorConfigWindow_Impl
172 class ColorConfigWindow_Impl
173 : public VclContainer
174 , public VclBuilderContainer
176 public:
177 ColorConfigWindow_Impl(vcl::Window* pParent);
178 virtual ~ColorConfigWindow_Impl() { disposeOnce(); }
179 virtual void dispose() SAL_OVERRIDE;
181 public:
182 void SetLinks (Link<> const&, Link<> const&, Link<> const&);
183 unsigned GetEntryHeight () const { return vEntries[0]->GetHeight(); }
184 void Update (EditableColorConfig const*, EditableExtendedColorConfig const*);
185 void ScrollHdl(const ScrollBar&);
186 void ClickHdl (EditableColorConfig*, CheckBox*);
187 void ColorHdl (EditableColorConfig*, EditableExtendedColorConfig*, ColorListBox*);
188 void Init(ScrollBar *pVScroll, HeaderBar *m_pHeaderHB);
189 void AdjustScrollBar();
190 void AdjustHeaderBar();
192 private:
193 // Chapter -- horizontal group separator stripe with text
194 class Chapter
196 // text
197 VclPtr<FixedText> m_pText;
198 public:
199 Chapter(FixedText *pText, bool bShow);
200 Chapter(vcl::Window *pGrid, unsigned nYPos, const OUString& sDisplayName);
201 ~Chapter();
202 void dispose() { m_pText.disposeAndClear(); }
203 public:
204 void SetBackground(const Wallpaper& W) { m_pText->SetBackground(W); }
205 void Show(const Wallpaper& rBackWall);
206 void Hide();
209 // Entry -- a color config entry:
210 // text (checkbox) + color list box + preview box
211 class Entry
213 public:
214 Entry(ColorConfigWindow_Impl& rParent, unsigned iEntry, long nCheckBoxLabelOffset, bool bShow);
215 Entry(vcl::Window* pGrid, unsigned nYPos, const ExtendedColorConfigValue& aColorEntry,
216 long nCheckBoxLabelOffset);
217 ~Entry();
218 public:
219 void Show ();
220 void Hide ();
221 void SetAppearance(Wallpaper const& aTextWall, ColorListBox const& aSampleList);
222 void SetTextColor (Color C) { m_pText->SetTextColor(C); }
223 public:
224 void SetLinks (Link<> const&, Link<> const&, Link<> const&);
225 void Update (ColorConfigEntry, ColorConfigValue const&);
226 void Update (ExtendedColorConfigValue const&);
227 void ColorChanged (ColorConfigEntry, ColorConfigValue&);
228 void ColorChanged (ExtendedColorConfigValue&);
229 public:
230 long GetTop () const { return m_pPreview->GetPosPixel().Y(); }
231 unsigned GetHeight () const { return m_pColorList->GetSizePixel().Height(); }
232 public:
233 bool Is (CheckBox* pBox) const { return m_pText == pBox; }
234 bool Is (ColorListBox* pBox) const { return m_pColorList == pBox; }
235 void dispose()
237 m_pText.disposeAndClear();
238 m_pColorList.disposeAndClear();
239 m_pPreview.disposeAndClear();
241 private:
242 bool m_bOwnsWidgets;
243 // checkbox (CheckBox) or simple text (FixedText)
244 VclPtr<Control> m_pText;
245 // color list box
246 VclPtr<ColorListBox> m_pColorList;
247 // color preview box
248 VclPtr<vcl::Window> m_pPreview;
249 // default color
250 Color m_aDefaultColor;
251 private:
252 void SetColor (Color);
255 // vChapters -- groups (group headers)
256 std::vector<boost::shared_ptr<Chapter> > vChapters;
257 // vEntries -- color options
258 std::vector<boost::shared_ptr<Entry> > vEntries;
260 // module options
261 SvtModuleOptions aModuleOptions;
264 private:
265 VclPtr<VclGrid> m_pGrid;
266 VclPtr<ScrollBar> m_pVScroll;
267 VclPtr<HeaderBar> m_pHeaderHB;
269 // initialization
270 void CreateEntries();
271 void SetAppearance();
273 private:
274 virtual void Command (CommandEvent const& rCEvt) SAL_OVERRIDE;
275 virtual void DataChanged (DataChangedEvent const& rDCEvt) SAL_OVERRIDE;
277 virtual Size calculateRequisition() const SAL_OVERRIDE;
278 virtual void setAllocation(const Size &rAllocation) SAL_OVERRIDE;
280 bool IsGroupVisible (Group) const;
284 // ColorConfigWindow_Impl::Chapter
287 // ctor for default groups
288 // rParent: parent window (ColorConfigWindow_Impl)
289 // eGroup: which group is this?
290 // rResMgr: resource manager
291 ColorConfigWindow_Impl::Chapter::Chapter(FixedText* pText, bool bShow)
292 : m_pText(pText)
294 if (!bShow)
295 Hide();
298 // ctor for extended groups
299 ColorConfigWindow_Impl::Chapter::Chapter(vcl::Window *pGrid,
300 unsigned nYPos, const OUString& rDisplayName)
302 m_pText = VclPtr<FixedText>::Create(pGrid, WB_LEFT|WB_VCENTER|WB_3DLOOK);
303 m_pText->set_font_attribute("weight", "bold");
304 m_pText->set_grid_width(3);
305 m_pText->set_grid_left_attach(0);
306 m_pText->set_grid_top_attach(nYPos);
307 m_pText->SetText(rDisplayName);
310 ColorConfigWindow_Impl::Chapter::~Chapter()
312 // FIXME: we had an horrible m_bOwnsWidget const
313 m_pText.disposeAndClear();
316 void ColorConfigWindow_Impl::Chapter::Show(Wallpaper const& rBackWall)
318 // background
319 m_pText->SetBackground(rBackWall);
320 m_pText->Show();
323 void ColorConfigWindow_Impl::Chapter::Hide ()
325 m_pText->Hide();
329 // ColorConfigWindow_Impl::Entry
332 ColorConfigWindow_Impl::Entry::Entry(ColorConfigWindow_Impl& rParent, unsigned iEntry,
333 long nCheckBoxLabelOffset, bool bShow)
334 : m_bOwnsWidgets(false)
335 , m_aDefaultColor(ColorConfig::GetDefaultColor(static_cast<ColorConfigEntry>(iEntry)))
337 rParent.get(m_pText, vEntryInfo[iEntry].pText);
338 if (!vEntryInfo[iEntry].bCheckBox)
340 m_pText->set_margin_left(m_pText->get_margin_left() +
341 nCheckBoxLabelOffset);
343 rParent.get(m_pColorList, vEntryInfo[iEntry].pColor);
344 rParent.get(m_pPreview, vEntryInfo[iEntry].pPreview);
346 if (!bShow)
347 Hide();
350 // ctor for extended entries
351 ColorConfigWindow_Impl::Entry::Entry( vcl::Window *pGrid, unsigned nYPos,
352 ExtendedColorConfigValue const& rColorEntry, long nCheckBoxLabelOffset)
353 : m_bOwnsWidgets(true)
354 , m_aDefaultColor(rColorEntry.getDefaultColor())
356 m_pText = VclPtr<FixedText>::Create(pGrid, WB_LEFT|WB_VCENTER|WB_3DLOOK);
357 m_pText->set_grid_left_attach(0);
358 m_pText->set_grid_top_attach(nYPos);
359 m_pText->set_margin_left(6 + nCheckBoxLabelOffset);
360 m_pText->SetText(rColorEntry.getDisplayName());
362 WinBits nWinBits = WB_LEFT|WB_VCENTER|WB_3DLOOK|WB_TABSTOP|WB_DROPDOWN;
363 m_pColorList = VclPtr<ColorListBox>::Create(pGrid, nWinBits);
364 m_pColorList->EnableAutoSize(true);
365 m_pColorList->set_grid_left_attach(1);
366 m_pColorList->set_grid_top_attach(nYPos);
368 m_pPreview = VclPtr<vcl::Window>::Create(pGrid, WB_BORDER);
369 m_pPreview->set_grid_left_attach(2);
370 m_pPreview->set_grid_top_attach(nYPos);
371 m_pPreview->set_margin_right(6);
373 Show();
376 ColorConfigWindow_Impl::Entry::~Entry()
378 if (m_bOwnsWidgets)
380 m_pText.disposeAndClear();
381 m_pColorList.disposeAndClear();
382 m_pPreview.disposeAndClear();
386 void ColorConfigWindow_Impl::Entry::Show()
388 m_pText->Show();
389 m_pColorList->Show();
390 m_pPreview->Show();
393 void ColorConfigWindow_Impl::Entry::Hide()
395 m_pText->Hide();
396 m_pColorList->Hide();
397 m_pPreview->Hide();
400 // SetAppearance()
401 // iEntry: which entry is this?
402 // aTextWall: background of the text (transparent)
403 // aSampleList: sample color listbox (to copy from)
404 void ColorConfigWindow_Impl::Entry::SetAppearance(
405 Wallpaper const& aTextWall,
406 ColorListBox const& aSampleList)
408 // text (and optionally checkbox)
409 m_pText->SetBackground(aTextWall);
410 // preview
411 m_pPreview->SetBorderStyle(WindowBorderStyle::MONO);
412 // color list
413 m_pColorList->CopyEntries(aSampleList);
414 m_pColorList->InsertAutomaticEntryColor(m_aDefaultColor);
417 // SetLinks()
418 void ColorConfigWindow_Impl::Entry::SetLinks(
419 Link<> const& aCheckLink, Link<> const& aColorLink,
420 Link<> const& aGetFocusLink)
422 m_pColorList->SetSelectHdl(aColorLink);
423 m_pColorList->SetGetFocusHdl(aGetFocusLink);
424 if (CheckBox* pCheckBox = dynamic_cast<CheckBox*>(m_pText.get()))
426 pCheckBox->SetClickHdl(aCheckLink);
427 pCheckBox->SetGetFocusHdl(aGetFocusLink);
431 // updates a default color config entry
432 void ColorConfigWindow_Impl::Entry::Update (
433 ColorConfigEntry aColorEntry, ColorConfigValue const& rValue
435 Color aColor;
436 if ((unsigned)rValue.nColor == COL_AUTO)
438 aColor = ColorConfig::GetDefaultColor(aColorEntry);
439 m_pColorList->SelectEntryPos(0);
441 else
443 aColor = Color(rValue.nColor);
444 m_pColorList->SelectEntry(aColor);
446 m_pPreview->SetBackground(Wallpaper(aColor));
447 if (CheckBox* pCheckBox = dynamic_cast<CheckBox*>(m_pText.get()))
448 pCheckBox->Check(rValue.bIsVisible);
451 // updates an extended color config entry
452 void ColorConfigWindow_Impl::Entry::Update (
453 ExtendedColorConfigValue const& rValue
455 Color aColor(rValue.getColor());
456 if (rValue.getColor() == rValue.getDefaultColor())
457 m_pColorList->SelectEntryPos(0);
458 else
459 m_pColorList->SelectEntry(aColor);
460 SetColor(aColor);
463 // color of a default entry has changed
464 void ColorConfigWindow_Impl::Entry::ColorChanged (
465 ColorConfigEntry aColorEntry,
466 ColorConfigValue& rValue
468 Color aColor;
469 if (m_pColorList->IsAutomaticSelected())
471 aColor = ColorConfig::GetDefaultColor(aColorEntry);
472 rValue.nColor = COL_AUTO;
474 else
476 aColor = m_pColorList->GetSelectEntryColor();
477 rValue.nColor = aColor.GetColor();
479 SetColor(aColor);
482 // color of an extended entry has changed
483 void ColorConfigWindow_Impl::Entry::ColorChanged (
484 ExtendedColorConfigValue& rValue
486 Color aColor = m_pColorList->GetSelectEntryColor();
487 rValue.setColor(aColor.GetColor());
488 // automatic?
489 if (m_pColorList->GetSelectEntryPos() == 0)
491 rValue.setColor(rValue.getDefaultColor());
492 aColor.SetColor(rValue.getColor());
494 SetColor(aColor);
497 void ColorConfigWindow_Impl::Entry::SetColor (Color aColor)
499 m_pPreview->SetBackground(Wallpaper(aColor));
500 m_pPreview->Invalidate();
505 // ColorConfigWindow_Impl
508 ColorConfigWindow_Impl::ColorConfigWindow_Impl(vcl::Window* pParent)
509 : VclContainer(pParent)
511 m_pUIBuilder = new VclBuilder(this, getUIRootDir(), "cui/ui/colorconfigwin.ui");
512 get(m_pGrid, "ColorConfigWindow");
513 CreateEntries();
514 SetAppearance();
517 void ColorConfigWindow_Impl::dispose()
519 m_pGrid.clear();
520 m_pVScroll.clear();
521 m_pHeaderHB.clear();
522 for (auto i = vChapters.begin(); i != vChapters.end(); ++i)
523 (*i)->dispose();
524 for (auto i = vEntries.begin(); i != vEntries.end(); ++i)
525 (*i)->dispose();
526 disposeBuilder();
527 VclContainer::dispose();
530 Size ColorConfigWindow_Impl::calculateRequisition() const
532 return getLayoutRequisition(*m_pGrid);
535 void ColorConfigWindow_Impl::setAllocation(const Size &rAllocation)
537 Point aChildPos(0, 0);
538 Size aChildSize(getLayoutRequisition(*m_pGrid));
539 aChildSize.Width() = rAllocation.Width();
540 setLayoutPosSize(*m_pGrid, aChildPos, aChildSize);
541 AdjustScrollBar();
542 AdjustHeaderBar();
543 ScrollHdl(*m_pVScroll);
546 void ColorConfigWindow_Impl::CreateEntries()
548 std::bitset<nGroupCount> aModulesInstalled;
549 // creating group headers
550 vChapters.reserve(nGroupCount);
551 for (unsigned i = 0; i != nGroupCount; ++i)
553 aModulesInstalled[i] = IsGroupVisible(vGroupInfo[i].eGroup);
554 vChapters.push_back(boost::shared_ptr<Chapter>(
555 new Chapter(get<FixedText>(vGroupInfo[i].pGroup), aModulesInstalled[i])));
558 //Here we want to get the amount to add to the position
559 //of a FixedText to get it to align its contents
560 //with that of a CheckBox
561 //We should have something like a Control::getTextOrigin
562 //Ideally we could use something like GetCharacterBounds,
563 //but I think that only works on truly visible controls
564 long nCheckBoxLabelOffset = 0;
566 OUString sSampleText("X");
567 ScopedVclPtrInstance< CheckBox > aCheckBox(this);
568 ScopedVclPtrInstance< FixedText > aFixedText(this);
569 aCheckBox->SetText(sSampleText);
570 aFixedText->SetText(sSampleText);
571 Size aCheckSize(aCheckBox->CalcMinimumSize(0x7fffffff));
572 Size aFixedSize(aFixedText->CalcMinimumSize(0x7fffffff));
573 nCheckBoxLabelOffset = aCheckSize.Width() - aFixedSize.Width();
576 // creating entries
577 vEntries.reserve(ColorConfigEntryCount);
578 for (unsigned i = 0; i < SAL_N_ELEMENTS(vEntryInfo); ++i)
580 vEntries.push_back(boost::shared_ptr<Entry>(new Entry(*this, i, nCheckBoxLabelOffset,
581 aModulesInstalled[vEntryInfo[i].eGroup])));
584 // extended entries
585 ExtendedColorConfig aExtConfig;
586 if (unsigned const nExtGroupCount = aExtConfig.GetComponentCount())
588 size_t nLineNum = vChapters.size() + vEntries.size() + 1;
589 for (unsigned j = 0; j != nExtGroupCount; ++j)
591 OUString const sComponentName = aExtConfig.GetComponentName(j);
592 vChapters.push_back(boost::shared_ptr<Chapter>(new Chapter(
593 m_pGrid, nLineNum,
594 aExtConfig.GetComponentDisplayName(sComponentName)
595 )));
596 ++nLineNum;
597 unsigned nColorCount = aExtConfig.GetComponentColorCount(sComponentName);
598 for (unsigned i = 0; i != nColorCount; ++i)
600 ExtendedColorConfigValue const aColorEntry =
601 aExtConfig.GetComponentColorConfigValue(sComponentName, i);
602 vEntries.push_back(boost::shared_ptr<Entry>( new Entry (
603 m_pGrid, nLineNum, aColorEntry, nCheckBoxLabelOffset
604 )));
605 ++nLineNum;
611 void ColorConfigWindow_Impl::SetAppearance ()
613 Color TempColor(COL_TRANSPARENT);
614 Wallpaper const aTransparentWall(TempColor);
615 StyleSettings const& rStyleSettings = GetSettings().GetStyleSettings();
616 Color const aBackColor = rStyleSettings.GetHighContrastMode() ?
617 rStyleSettings.GetShadowColor() : Color(COL_LIGHTGRAY);
618 Wallpaper const aBackWall(aBackColor);
619 for (size_t i = 0; i != vChapters.size(); ++i)
620 vChapters[i]->Show(aBackWall);
621 Wallpaper aBack(rStyleSettings.GetFieldColor());
622 SetBackground(aBack);
623 m_pGrid->SetBackground(aBack);
625 // #104195# when the window color is the same as the text color it has to be changed
626 Color aWinCol = rStyleSettings.GetWindowColor();
627 Color aRCheckCol = rStyleSettings.GetRadioCheckTextColor();
628 if (aWinCol == aRCheckCol)
630 aRCheckCol.Invert();
631 // if inversion didn't work (gray) then it's set to black
632 if (aRCheckCol == aWinCol)
633 aRCheckCol = Color(COL_BLACK);
634 // setting new text color for each entry
635 for (size_t i = 0; i != vEntries.size(); ++i)
636 vEntries[i]->SetTextColor(aRCheckCol);
639 OSL_ENSURE( vEntries.size() >= sizeof vEntryInfo / sizeof vEntryInfo[0], "wrong number of helpIDs for color listboxes" );
641 // creating a sample color listbox with the color entries
642 ScopedVclPtrInstance< ColorListBox > aSampleColorList(this);
644 XColorListRef const xColorTable = XColorList::CreateStdColorList();
645 for (sal_Int32 i = 0; i != xColorTable->Count(); ++i)
647 XColorEntry& rEntry = *xColorTable->GetColor(i);
648 aSampleColorList->InsertEntry(rEntry.GetColor(), rEntry.GetName());
652 // appearance
653 for (size_t i = 0; i != vEntries.size(); ++i)
655 // appearance
656 vEntries[i]->SetAppearance(aTransparentWall, *aSampleColorList.get());
660 void ColorConfigWindow_Impl::AdjustHeaderBar()
662 // horizontal positions
663 unsigned const nX0 = 0;
664 unsigned const nX1 = get<vcl::Window>("doccolor")->GetPosPixel().X();
665 unsigned const nX2 = get<vcl::Window>("doccolor_lb")->GetPosPixel().X();
666 unsigned const nX3 = get<vcl::Window>("doccolor_wn")->GetPosPixel().X();
667 unsigned const nX4 = m_pHeaderHB->GetSizePixel().Width();
668 m_pHeaderHB->SetItemSize(1, nX1 - nX0);
669 m_pHeaderHB->SetItemSize(2, nX2 - nX1);
670 m_pHeaderHB->SetItemSize(3, nX3 - nX2);
671 m_pHeaderHB->SetItemSize(4, nX4 - nX3);
674 void ColorConfigWindow_Impl::AdjustScrollBar()
676 unsigned const nScrollOffset =
677 vEntries[1]->GetTop() - vEntries[0]->GetTop();
678 unsigned const nVisibleEntries = GetSizePixel().Height() / nScrollOffset;
679 m_pVScroll->SetPageSize(nVisibleEntries - 1);
680 m_pVScroll->SetVisibleSize(nVisibleEntries);
683 void ColorConfigWindow_Impl::Init(ScrollBar *pVScroll, HeaderBar *pHeaderHB)
685 m_pHeaderHB = pHeaderHB;
686 m_pVScroll = pVScroll;
687 m_pVScroll->EnableDrag();
688 m_pVScroll->SetRangeMin(0);
689 m_pVScroll->SetRangeMax(vEntries.size() + vChapters.size());
692 // SetLinks()
693 void ColorConfigWindow_Impl::SetLinks (
694 Link<> const& aCheckLink, Link<> const& aColorLink, Link<> const& aGetFocusLink
696 for (unsigned i = 0; i != vEntries.size(); ++i)
697 vEntries[i]->SetLinks(aCheckLink, aColorLink, aGetFocusLink);
700 // Update()
701 void ColorConfigWindow_Impl::Update (
702 EditableColorConfig const* pConfig,
703 EditableExtendedColorConfig const* pExtConfig)
705 // updating default entries
706 for (unsigned i = 0; i != ColorConfigEntryCount; ++i)
708 ColorConfigEntry const aColorEntry = static_cast<ColorConfigEntry>(i);
709 vEntries[i]->Update(
710 aColorEntry, pConfig->GetColorValue(aColorEntry)
714 // updating extended entries
715 unsigned i = ColorConfigEntryCount;
716 unsigned const nExtCount = pExtConfig->GetComponentCount();
717 for (unsigned j = 0; j != nExtCount; ++j)
719 OUString sComponentName = pExtConfig->GetComponentName(j);
720 unsigned const nColorCount = pExtConfig->GetComponentColorCount(sComponentName);
721 for (unsigned k = 0; i != vEntries.size() && k != nColorCount; ++i, ++k)
722 vEntries[i]->Update(
723 pExtConfig->GetComponentColorConfigValue(sComponentName, k)
728 // ScrollHdl()
729 void ColorConfigWindow_Impl::ScrollHdl(const ScrollBar& rVScroll)
731 SetUpdateMode(true);
732 const long nRowHeight = (vEntries[1]->GetTop() - vEntries[0]->GetTop());
733 Point aPos(0, 0 - rVScroll.GetThumbPos() * nRowHeight);
734 m_pGrid->SetPosPixel(aPos);
735 SetUpdateMode(true);
738 // ClickHdl()
739 void ColorConfigWindow_Impl::ClickHdl (EditableColorConfig* pConfig, CheckBox* pBox)
741 for (unsigned i = 0; i != ColorConfigEntryCount; ++i)
743 if (vEntries[i]->Is(pBox))
745 ColorConfigEntry const aEntry = static_cast<ColorConfigEntry>(i);
746 ColorConfigValue aValue = pConfig->GetColorValue(aEntry);
747 aValue.bIsVisible = pBox->IsChecked();
748 pConfig->SetColorValue(aEntry, aValue);
749 break;
754 // ColorHdl()
755 void ColorConfigWindow_Impl::ColorHdl (
756 EditableColorConfig* pConfig, EditableExtendedColorConfig* pExtConfig,
757 ColorListBox* pBox
759 unsigned i = 0;
761 // default entries
762 for ( ; i != ColorConfigEntryCount; ++i)
764 if (pBox && vEntries[i]->Is(pBox))
766 ColorConfigEntry const aColorEntry = static_cast<ColorConfigEntry>(i);
767 ColorConfigValue aValue = pConfig->GetColorValue(aColorEntry);
768 vEntries[i]->ColorChanged(aColorEntry, aValue);
769 pConfig->SetColorValue(aColorEntry, aValue);
770 break;
774 // extended entries
775 unsigned const nExtCount = pExtConfig->GetComponentCount();
776 i = ColorConfigEntryCount;
777 for (unsigned j = 0; j != nExtCount; ++j)
779 OUString sComponentName = pExtConfig->GetComponentName(j);
780 unsigned const nColorCount = pExtConfig->GetComponentColorCount(sComponentName);
781 unsigned const nCount = vEntries.size();
782 for (unsigned k = 0; i != nCount && k != nColorCount; ++i, ++k)
784 if (pBox && vEntries[i]->Is(pBox))
786 ExtendedColorConfigValue aValue =
787 pExtConfig->GetComponentColorConfigValue(sComponentName, k);
788 vEntries[i]->ColorChanged(aValue);
789 pExtConfig->SetColorValue(sComponentName, aValue);
790 break;
797 // IsGroupVisible()
798 bool ColorConfigWindow_Impl::IsGroupVisible (Group eGroup) const
800 switch (eGroup)
802 case Group_Writer:
803 case Group_Html:
804 return aModuleOptions.IsModuleInstalled(SvtModuleOptions::EModule::WRITER);
805 case Group_Calc:
806 return aModuleOptions.IsModuleInstalled(SvtModuleOptions::EModule::CALC);
807 case Group_Draw:
808 return
809 aModuleOptions.IsModuleInstalled(SvtModuleOptions::EModule::DRAW) ||
810 aModuleOptions.IsModuleInstalled(SvtModuleOptions::EModule::IMPRESS);
811 case Group_Sql:
812 return aModuleOptions.IsModuleInstalled(SvtModuleOptions::EModule::DATABASE);
813 default:
814 return true;
818 void ColorConfigWindow_Impl::DataChanged (DataChangedEvent const& rDCEvt)
820 Window::DataChanged( rDCEvt );
821 if ( (rDCEvt.GetType() == DataChangedEventType::SETTINGS) &&
822 (rDCEvt.GetFlags() & AllSettingsFlags::STYLE) )
824 StyleSettings const& rStyleSettings = GetSettings().GetStyleSettings();
825 bool const bHighContrast = rStyleSettings.GetHighContrastMode();
826 Wallpaper const aBackWall(Color(bHighContrast ? COL_TRANSPARENT : COL_LIGHTGRAY));
827 for (unsigned i = 0; i != vChapters.size(); ++i)
828 vChapters[i]->SetBackground(aBackWall);
829 SetBackground(Wallpaper(rStyleSettings.GetWindowColor()));
834 void ColorConfigWindow_Impl::Command( const CommandEvent& rCEvt )
836 GetParent()->Command(rCEvt);
839 class ColorConfigCtrl_Impl : public VclVBox
841 VclPtr<HeaderBar> m_pHeaderHB;
842 VclPtr<VclHBox> m_pBody;
843 VclPtr<ColorConfigWindow_Impl> m_pScrollWindow;
844 VclPtr<ScrollBar> m_pVScroll;
846 EditableColorConfig* pColorConfig;
847 EditableExtendedColorConfig* pExtColorConfig;
849 DECL_LINK(ScrollHdl, ScrollBar*);
850 DECL_LINK(ClickHdl, CheckBox*);
851 DECL_LINK(ColorHdl, ColorListBox*);
852 DECL_LINK(ControlFocusHdl, Control*);
854 virtual bool PreNotify (NotifyEvent& rNEvt) SAL_OVERRIDE;
855 virtual void Command (CommandEvent const& rCEvt) SAL_OVERRIDE;
856 virtual void DataChanged (DataChangedEvent const& rDCEvt) SAL_OVERRIDE;
857 public:
858 ColorConfigCtrl_Impl(vcl::Window* pParent);
859 virtual ~ColorConfigCtrl_Impl();
860 virtual void dispose() SAL_OVERRIDE;
862 void InitHeaderBar(const OUString &rOn, const OUString &rUIElems,
863 const OUString &rColorSetting, const OUString &rPreview);
864 void SetConfig (EditableColorConfig& rConfig) { pColorConfig = &rConfig; }
865 void SetExtendedConfig (EditableExtendedColorConfig& rConfig) { pExtColorConfig = &rConfig; }
866 void Update ();
867 long GetScrollPosition ()
869 return m_pVScroll->GetThumbPos();
871 void SetScrollPosition (long nSet)
873 m_pVScroll->SetThumbPos(nSet);
874 ScrollHdl(m_pVScroll);
878 ColorConfigCtrl_Impl::ColorConfigCtrl_Impl(vcl::Window* pParent)
879 : VclVBox(pParent)
880 , pColorConfig(0)
881 , pExtColorConfig(0)
883 m_pHeaderHB = VclPtr<HeaderBar>::Create(this, WB_BUTTONSTYLE | WB_BOTTOMBORDER);
885 m_pBody = VclPtr<VclHBox>::Create(this);
886 m_pScrollWindow = VclPtr<ColorConfigWindow_Impl>::Create(m_pBody);
887 m_pVScroll = VclPtr<ScrollBar>::Create(m_pBody, WB_VERT);
888 m_pScrollWindow->Init(m_pVScroll, m_pHeaderHB);
890 m_pBody->set_hexpand(true);
891 m_pBody->set_vexpand(true);
892 m_pBody->set_expand(true);
893 m_pBody->set_fill(true);
895 m_pScrollWindow->set_hexpand(true);
896 m_pScrollWindow->set_vexpand(true);
897 m_pScrollWindow->set_expand(true);
898 m_pScrollWindow->set_fill(true);
900 Link<> aScrollLink = LINK(this, ColorConfigCtrl_Impl, ScrollHdl);
901 m_pVScroll->SetScrollHdl(aScrollLink);
902 m_pVScroll->SetEndScrollHdl(aScrollLink);
904 Link<> aCheckLink = LINK(this, ColorConfigCtrl_Impl, ClickHdl);
905 Link<> aColorLink = LINK(this, ColorConfigCtrl_Impl, ColorHdl);
906 Link<> aGetFocusLink = LINK(this, ColorConfigCtrl_Impl, ControlFocusHdl);
907 m_pScrollWindow->SetLinks(aCheckLink, aColorLink, aGetFocusLink);
909 m_pHeaderHB->Show();
910 m_pVScroll->Show();
911 m_pBody->Show();
912 m_pScrollWindow->Show();
915 void ColorConfigCtrl_Impl::InitHeaderBar(const OUString &rOn, const OUString &rUIElems,
916 const OUString &rColorSetting, const OUString &rPreview)
918 // filling
919 const HeaderBarItemBits nHeadBits = HeaderBarItemBits::VCENTER | HeaderBarItemBits::FIXED | HeaderBarItemBits::FIXEDPOS;
920 m_pHeaderHB->InsertItem(1, rOn, 0, nHeadBits | HeaderBarItemBits::CENTER);
921 m_pHeaderHB->InsertItem(2, rUIElems, 0, nHeadBits | HeaderBarItemBits::LEFT);
922 m_pHeaderHB->InsertItem(3, rColorSetting, 0, nHeadBits | HeaderBarItemBits::LEFT);
923 m_pHeaderHB->InsertItem(4, rPreview, 0, nHeadBits | HeaderBarItemBits::LEFT);
924 m_pHeaderHB->set_height_request(GetTextHeight() + 6);
927 ColorConfigCtrl_Impl::~ColorConfigCtrl_Impl()
929 disposeOnce();
932 void ColorConfigCtrl_Impl::dispose()
934 m_pVScroll.disposeAndClear();
935 m_pScrollWindow.disposeAndClear();
936 m_pBody.disposeAndClear();
937 m_pHeaderHB.disposeAndClear();
938 VclVBox::dispose();
941 VCL_BUILDER_DECL_FACTORY(ColorConfigCtrl)
943 (void)rMap;
944 rRet = VclPtr<ColorConfigCtrl_Impl>::Create(pParent);
947 void ColorConfigCtrl_Impl::Update ()
949 DBG_ASSERT(pColorConfig, "Configuration not set");
950 m_pScrollWindow->Update(pColorConfig, pExtColorConfig);
953 IMPL_LINK(ColorConfigCtrl_Impl, ScrollHdl, ScrollBar*, pScrollBar)
955 m_pScrollWindow->ScrollHdl(*pScrollBar);
956 return 0;
959 bool ColorConfigCtrl_Impl::PreNotify( NotifyEvent& rNEvt )
961 if(rNEvt.GetType() == MouseNotifyEvent::COMMAND)
963 const CommandEvent* pCEvt = rNEvt.GetCommandEvent();
964 if( pCEvt->GetCommand() == CommandEventId::Wheel )
966 Command(*pCEvt);
967 return true;
970 return VclVBox::PreNotify(rNEvt);
973 void ColorConfigCtrl_Impl::Command( const CommandEvent& rCEvt )
975 switch ( rCEvt.GetCommand() )
978 case CommandEventId::Wheel:
979 case CommandEventId::StartAutoScroll:
980 case CommandEventId::AutoScroll:
982 const CommandWheelData* pWheelData = rCEvt.GetWheelData();
983 if(pWheelData && !pWheelData->IsHorz() && CommandWheelMode::ZOOM != pWheelData->GetMode())
985 HandleScrollCommand(rCEvt, 0, m_pVScroll);
988 break;
989 default:
990 VclVBox::Command(rCEvt);
994 void ColorConfigCtrl_Impl::DataChanged( const DataChangedEvent& rDCEvt )
996 Window::DataChanged( rDCEvt );
997 if ( (rDCEvt.GetType() == DataChangedEventType::SETTINGS) &&
998 (rDCEvt.GetFlags() & AllSettingsFlags::STYLE) )
1000 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
1001 SetBackground(Wallpaper(rStyleSettings.GetFieldColor()));
1005 IMPL_LINK(ColorConfigCtrl_Impl, ClickHdl, CheckBox*, pBox)
1007 DBG_ASSERT(pColorConfig, "Configuration not set");
1008 m_pScrollWindow->ClickHdl(pColorConfig, pBox);
1009 return 0;
1012 // a color list has changed
1013 IMPL_LINK(ColorConfigCtrl_Impl, ColorHdl, ColorListBox*, pBox)
1015 DBG_ASSERT(pColorConfig, "Configuration not set" );
1016 if (pBox)
1017 m_pScrollWindow->ColorHdl(pColorConfig, pExtColorConfig, pBox);
1018 return 0;
1020 IMPL_LINK(ColorConfigCtrl_Impl, ControlFocusHdl, Control*, pCtrl)
1022 // determine whether a control is completely visible
1023 // and make it visible
1024 long aCtrlPosY = pCtrl->GetPosPixel().Y();
1025 unsigned const nWinHeight = m_pScrollWindow->GetSizePixel().Height();
1026 unsigned const nEntryHeight = m_pScrollWindow->GetEntryHeight();
1027 if (0 != (GETFOCUS_TAB & pCtrl->GetGetFocusFlags()) &&
1028 (aCtrlPosY < 0 || nWinHeight < aCtrlPosY + nEntryHeight)
1030 long nThumbPos = m_pVScroll->GetThumbPos();
1031 if (nWinHeight < aCtrlPosY + nEntryHeight)
1033 //scroll down
1034 nThumbPos += 2;
1036 else
1038 //scroll up
1039 nThumbPos -= 2;
1040 if(nThumbPos < 0)
1041 nThumbPos = 0;
1043 m_pVScroll->SetThumbPos(nThumbPos);
1044 ScrollHdl(m_pVScroll);
1046 return 0;
1051 // SvxColorOptionsTabPage
1054 SvxColorOptionsTabPage::SvxColorOptionsTabPage(
1055 vcl::Window* pParent, const SfxItemSet& rCoreSet)
1056 : SfxTabPage(pParent, "OptAppearancePage", "cui/ui/optappearancepage.ui", &rCoreSet)
1057 , bFillItemSetCalled(false)
1058 , pColorConfig(0)
1059 , pExtColorConfig(0)
1061 get(m_pColorSchemeLB, "colorschemelb");
1062 m_pColorSchemeLB->SetStyle(m_pColorSchemeLB->GetStyle() | WB_SORT);
1063 get(m_pSaveSchemePB, "save");
1064 get(m_pDeleteSchemePB, "delete");
1065 get(m_pColorConfigCT, "colorconfig");
1067 m_pColorConfigCT->InitHeaderBar(
1068 get<vcl::Window>("on")->GetText(),
1069 get<vcl::Window>("uielements")->GetText(),
1070 get<vcl::Window>("colorsetting")->GetText(),
1071 get<vcl::Window>("preview")->GetText());
1073 m_pColorSchemeLB->SetSelectHdl(LINK(this, SvxColorOptionsTabPage, SchemeChangedHdl_Impl));
1074 Link<> aLk = LINK(this, SvxColorOptionsTabPage, SaveDeleteHdl_Impl );
1075 m_pSaveSchemePB->SetClickHdl(aLk);
1076 m_pDeleteSchemePB->SetClickHdl(aLk);
1079 SvxColorOptionsTabPage::~SvxColorOptionsTabPage()
1081 disposeOnce();
1084 void SvxColorOptionsTabPage::dispose()
1086 if (pColorConfig)
1088 //when the dialog is cancelled but the color scheme ListBox has been changed these
1089 //changes need to be undone
1090 if(!bFillItemSetCalled && m_pColorSchemeLB->IsValueChangedFromSaved())
1092 OUString sOldScheme = m_pColorSchemeLB->GetEntry(m_pColorSchemeLB->GetSavedValue());
1093 if(!sOldScheme.isEmpty())
1095 pColorConfig->SetCurrentSchemeName(sOldScheme);
1096 pExtColorConfig->SetCurrentSchemeName(sOldScheme);
1099 pColorConfig->ClearModified();
1100 pColorConfig->EnableBroadcast();
1101 delete pColorConfig;
1102 pColorConfig = NULL;
1104 pExtColorConfig->ClearModified();
1105 pExtColorConfig->EnableBroadcast();
1106 delete pExtColorConfig;
1107 pExtColorConfig = NULL;
1109 m_pColorSchemeLB.clear();
1110 m_pSaveSchemePB.clear();
1111 m_pDeleteSchemePB.clear();
1112 m_pColorConfigCT.clear();
1113 SfxTabPage::dispose();
1116 VclPtr<SfxTabPage> SvxColorOptionsTabPage::Create( vcl::Window* pParent, const SfxItemSet* rAttrSet )
1118 return VclPtr<SvxColorOptionsTabPage>::Create( pParent, *rAttrSet );
1121 bool SvxColorOptionsTabPage::FillItemSet( SfxItemSet* )
1123 bFillItemSetCalled = true;
1124 if(m_pColorSchemeLB->IsValueChangedFromSaved())
1126 pColorConfig->SetModified();
1127 pExtColorConfig->SetModified();
1129 if(pColorConfig->IsModified())
1130 pColorConfig->Commit();
1131 if(pExtColorConfig->IsModified())
1132 pExtColorConfig->Commit();
1133 return true;
1136 void SvxColorOptionsTabPage::Reset( const SfxItemSet* )
1138 if(pColorConfig)
1140 pColorConfig->ClearModified();
1141 pColorConfig->DisableBroadcast();
1142 delete pColorConfig;
1144 pColorConfig = new EditableColorConfig;
1145 m_pColorConfigCT->SetConfig(*pColorConfig);
1147 if(pExtColorConfig)
1149 pExtColorConfig->ClearModified();
1150 pExtColorConfig->DisableBroadcast();
1151 delete pExtColorConfig;
1153 pExtColorConfig = new EditableExtendedColorConfig;
1154 m_pColorConfigCT->SetExtendedConfig(*pExtColorConfig);
1156 OUString sUser = GetUserData();
1157 //has to be called always to speed up accessibility tools
1158 m_pColorConfigCT->SetScrollPosition(sUser.toInt32());
1159 m_pColorSchemeLB->Clear();
1160 uno::Sequence< OUString > aSchemes = pColorConfig->GetSchemeNames();
1161 const OUString* pSchemes = aSchemes.getConstArray();
1162 for(sal_Int32 i = 0; i < aSchemes.getLength(); i++)
1163 m_pColorSchemeLB->InsertEntry(pSchemes[i]);
1164 m_pColorSchemeLB->SelectEntry(pColorConfig->GetCurrentSchemeName());
1165 m_pColorSchemeLB->SaveValue();
1166 m_pDeleteSchemePB->Enable( aSchemes.getLength() > 1 );
1167 UpdateColorConfig();
1170 SfxTabPage::sfxpg SvxColorOptionsTabPage::DeactivatePage( SfxItemSet* pSet_ )
1172 if ( pSet_ )
1173 FillItemSet( pSet_ );
1174 return LEAVE_PAGE;
1177 void SvxColorOptionsTabPage::UpdateColorConfig()
1179 //update the color config control
1180 m_pColorConfigCT->Update();
1183 IMPL_LINK(SvxColorOptionsTabPage, SchemeChangedHdl_Impl, ListBox*, pBox)
1185 pColorConfig->LoadScheme(pBox->GetSelectEntry());
1186 pExtColorConfig->LoadScheme(pBox->GetSelectEntry());
1187 UpdateColorConfig();
1188 return 0;
1191 IMPL_LINK(SvxColorOptionsTabPage, SaveDeleteHdl_Impl, PushButton*, pButton )
1193 if (m_pSaveSchemePB == pButton)
1195 OUString sName;
1197 SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
1198 DBG_ASSERT(pFact, "Dialog creation failed!");
1199 boost::scoped_ptr<AbstractSvxNameDialog> aNameDlg(pFact->CreateSvxNameDialog( pButton,
1200 sName, CUI_RES(RID_SVXSTR_COLOR_CONFIG_SAVE2) ));
1201 DBG_ASSERT(aNameDlg, "Dialog creation failed!");
1202 aNameDlg->SetCheckNameHdl( LINK(this, SvxColorOptionsTabPage, CheckNameHdl_Impl));
1203 aNameDlg->SetText(CUI_RES(RID_SVXSTR_COLOR_CONFIG_SAVE1));
1204 aNameDlg->SetHelpId(HID_OPTIONS_COLORCONFIG_SAVE_SCHEME);
1205 aNameDlg->SetCheckNameHdl( LINK(this, SvxColorOptionsTabPage, CheckNameHdl_Impl));
1206 if(RET_OK == aNameDlg->Execute())
1208 aNameDlg->GetName(sName);
1209 pColorConfig->AddScheme(sName);
1210 pExtColorConfig->AddScheme(sName);
1211 m_pColorSchemeLB->InsertEntry(sName);
1212 m_pColorSchemeLB->SelectEntry(sName);
1213 m_pColorSchemeLB->GetSelectHdl().Call(m_pColorSchemeLB);
1216 else
1218 DBG_ASSERT(m_pColorSchemeLB->GetEntryCount() > 1, "don't delete the last scheme");
1219 ScopedVclPtrInstance< MessageDialog > aQuery(pButton, CUI_RES(RID_SVXSTR_COLOR_CONFIG_DELETE), VCL_MESSAGE_QUESTION, VCL_BUTTONS_YES_NO);
1220 aQuery->SetText(CUI_RES(RID_SVXSTR_COLOR_CONFIG_DELETE_TITLE));
1221 if(RET_YES == aQuery->Execute())
1223 OUString sDeleteScheme(m_pColorSchemeLB->GetSelectEntry());
1224 m_pColorSchemeLB->RemoveEntry(m_pColorSchemeLB->GetSelectEntryPos());
1225 m_pColorSchemeLB->SelectEntryPos(0);
1226 m_pColorSchemeLB->GetSelectHdl().Call(m_pColorSchemeLB);
1227 //first select the new scheme and then delete the old one
1228 pColorConfig->DeleteScheme(sDeleteScheme);
1229 pExtColorConfig->DeleteScheme(sDeleteScheme);
1232 m_pDeleteSchemePB->Enable( m_pColorSchemeLB->GetEntryCount() > 1 );
1233 return 0;
1236 IMPL_LINK(SvxColorOptionsTabPage, CheckNameHdl_Impl, AbstractSvxNameDialog*, pDialog )
1238 OUString sName;
1239 pDialog->GetName(sName);
1240 return long(!sName.isEmpty() && LISTBOX_ENTRY_NOTFOUND == m_pColorSchemeLB->GetEntryPos( sName ));
1243 void SvxColorOptionsTabPage::FillUserData()
1245 SetUserData(OUString::number(m_pColorConfigCT->GetScrollPosition()));
1248 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */