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