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>
27 #include <svtools/extcolorcfg.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 
38 using namespace ::com::sun::star;
39 using namespace ::svtools;
40 
41 namespace
42 {
43 
44 // list of default groups
45 enum 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
59 struct
60 {
61  // group
62  Group eGroup;
63  // .ui group name
64  const char *pGroup;
65 }
66 const 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)
79 struct
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 }
90 const 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(det) },
131  { Group_Calc, IDS(deterror) },
132  { Group_Calc, IDS(ref) },
133  { Group_Calc, IDS(notes) },
134  { Group_Calc, IDS(values) },
135  { Group_Calc, IDS(formulas) },
136  { Group_Calc, IDS(text) },
137  { Group_Calc, IDS(protectedcells) },
138 
139  { Group_Draw, IDS(drawgrid) },
140 
141  { Group_Basic, IDS(basicid) },
142  { Group_Basic, IDS(basiccomment) },
143  { Group_Basic, IDS(basicnumber) },
144  { Group_Basic, IDS(basicstring) },
145  { Group_Basic, IDS(basicop) },
146  { Group_Basic, IDS(basickeyword) },
147  { Group_Basic, IDS(error) },
148 
149  { Group_Sql, IDS(sqlid) },
150  { Group_Sql, IDS(sqlnumber) },
151  { Group_Sql, IDS(sqlstring) },
152  { Group_Sql, IDS(sqlop) },
153  { Group_Sql, IDS(sqlkeyword) },
154  { Group_Sql, IDS(sqlparam) },
155  { Group_Sql, IDS(sqlcomment) }
156 
157  #undef IDS
158 };
159 
160 // ColorConfigWindow_Impl
161 
162 class ColorConfigWindow_Impl
163 {
164 public:
165  explicit ColorConfigWindow_Impl(weld::Window* pTopLevel, weld::Container* pParent);
166 
167 public:
168  void SetLinks(Link<weld::Toggleable&,void> const&,
171  weld::ScrolledWindow& rScroll);
172  void Update(EditableColorConfig const*, EditableExtendedColorConfig const*);
173  void ClickHdl(EditableColorConfig*, weld::Toggleable&);
174  void ColorHdl(EditableColorConfig*, EditableExtendedColorConfig*, const ColorListBox*);
175 
176  weld::Widget& GetWidget1()
177  {
178  return *m_xWidget1;
179  }
180 
181  weld::Widget& GetWidget2()
182  {
183  return *m_xWidget2;
184  }
185 
186  weld::Widget& GetBody()
187  {
188  return *m_xBox;
189  }
190 
191  void AdjustExtraWidths(int nTextWidth);
192 
193 private:
194  // Chapter -- horizontal group separator stripe with text
195  class Chapter
196  {
197  // text
198  std::unique_ptr<weld::Label> m_xText;
199  public:
200  Chapter(weld::Builder& rBuilder, const char* pLabelWidget, bool bShow);
201  void SetText(const OUString& rLabel) { m_xText->set_label(rLabel); }
202  };
203 
204  // Entry -- a color config entry:
205  // text (checkbox) + color list box
206  class Entry
207  {
208  public:
209  Entry(weld::Window* pTopLevel, weld::Builder& rBuilder, const char* pTextWidget, const char* pColorWidget,
210  const Color& rColor, tools::Long nCheckBoxLabelOffset, bool bCheckBox, bool bShow);
211  public:
212  void SetText(const OUString& rLabel) { dynamic_cast<weld::Label&>(*m_xText).set_label(rLabel); }
213  void set_width_request(int nTextWidth) { m_xText->set_size_request(nTextWidth, -1); }
214  int get_height_request() const
215  {
216  return std::max(m_xText->get_preferred_size().Height(),
217  m_xColorList->get_widget().get_preferred_size().Height());
218  }
219  void Hide ();
220  public:
221  void SetLinks(Link<weld::Toggleable&,void> const&,
223  Link<weld::Widget&,void> const&);
224  void Update (ColorConfigValue const&);
225  void Update (ExtendedColorConfigValue const&);
226  void ColorChanged (ColorConfigValue&);
227  void ColorChanged (ExtendedColorConfigValue&);
228  public:
229  bool Is(const weld::Toggleable* pBox) const { return m_xText.get() == pBox; }
230  bool Is(const ColorListBox* pBox) const { return m_xColorList.get() == pBox; }
231  private:
232  // checkbox (CheckBox) or simple text (FixedText)
233  std::unique_ptr<weld::Widget> m_xText;
234  // color list box
235  std::unique_ptr<ColorListBox> m_xColorList;
236  // default color
237  Color m_aDefaultColor;
238  };
239 
240 private:
241  weld::Window* m_pTopLevel;
242  std::unique_ptr<weld::Builder> m_xBuilder;
243  std::unique_ptr<weld::Box> m_xBox;
244  std::unique_ptr<weld::Widget> m_xWidget1;
245  std::unique_ptr<weld::Widget> m_xWidget2;
246 
247  std::vector<std::unique_ptr<weld::Builder>> vExtBuilders;
248  std::vector<std::unique_ptr<weld::Container>> vExtContainers;
249  // vChapters -- groups (group headers)
250  std::vector<std::shared_ptr<Chapter> > vChapters;
251  // vEntries -- color options
252  std::vector<std::shared_ptr<Entry> > vEntries;
253 
254  // module options
255  SvtModuleOptions aModuleOptions;
256 
257  // initialization
258  void CreateEntries();
259 
260 private:
261 
262  bool IsGroupVisible (Group) const;
263 };
264 
265 } // namespace
266 
267 // ColorConfigWindow_Impl::Chapter
268 
269 // ctor for default groups
270 // rParent: parent window (ColorConfigWindow_Impl)
271 // eGroup: which group is this?
272 ColorConfigWindow_Impl::Chapter::Chapter(weld::Builder& rBuilder, const char* pLabelWidget, bool bShow)
273  : m_xText(rBuilder.weld_label(pLabelWidget))
274 {
275  if (!bShow)
276  m_xText->hide();
277 }
278 
279 // ColorConfigWindow_Impl::Entry
280 ColorConfigWindow_Impl::Entry::Entry(weld::Window* pTopLevel, weld::Builder& rBuilder,
281  const char* pTextWidget, const char* pColorWidget,
282  const Color& rColor,
283  tools::Long nCheckBoxLabelOffset, bool bCheckBox, bool bShow)
284  : m_xColorList(new ColorListBox(rBuilder.weld_menu_button(pColorWidget), [pTopLevel]{ return pTopLevel; }))
285  , m_aDefaultColor(rColor)
286 {
287  if (bCheckBox)
288  m_xText = rBuilder.weld_check_button(pTextWidget);
289  else
290  m_xText = rBuilder.weld_label(pTextWidget);
291 
292  // color list
293  m_xColorList->SetSlotId(SID_ATTR_CHAR_COLOR);
294  m_xColorList->SetAutoDisplayColor(m_aDefaultColor);
295 
296  if (!bCheckBox)
297  {
298  m_xText->set_margin_start(m_xText->get_margin_start() +
299  nCheckBoxLabelOffset);
300  }
301 
302  if (!bShow)
303  Hide();
304 }
305 
306 void ColorConfigWindow_Impl::Entry::Hide()
307 {
308  m_xText->hide();
309  m_xColorList->hide();
310 }
311 
312 // SetLinks()
313 void ColorConfigWindow_Impl::Entry::SetLinks(Link<weld::Toggleable&,void> const& rCheckLink,
314  Link<ColorListBox&,void> const& rColorLink,
315  Link<weld::Widget&,void> const& rGetFocusLink)
316 {
317  m_xColorList->SetSelectHdl(rColorLink);
318  m_xColorList->connect_focus_in(rGetFocusLink);
319  if (weld::Toggleable* pCheckBox = dynamic_cast<weld::Toggleable*>(m_xText.get()))
320  {
321  pCheckBox->connect_toggled(rCheckLink);
322  pCheckBox->connect_focus_in(rGetFocusLink);
323  }
324 }
325 
326 // updates a default color config entry
327 void ColorConfigWindow_Impl::Entry::Update(ColorConfigValue const& rValue)
328 {
329  Color aColor(rValue.nColor);
330  m_xColorList->SelectEntry(aColor);
331  if (weld::Toggleable* pCheckBox = dynamic_cast<weld::Toggleable*>(m_xText.get()))
332  pCheckBox->set_active(rValue.bIsVisible);
333 }
334 
335 // updates an extended color config entry
336 void ColorConfigWindow_Impl::Entry::Update(ExtendedColorConfigValue const& rValue)
337 {
338  Color aColor(rValue.getColor());
339  if (rValue.getColor() == rValue.getDefaultColor())
340  m_xColorList->SelectEntry(COL_AUTO);
341  else
342  m_xColorList->SelectEntry(aColor);
343 }
344 
345 // color of a default entry has changed
346 void ColorConfigWindow_Impl::Entry::ColorChanged(ColorConfigValue& rValue)
347 {
348  Color aColor = m_xColorList->GetSelectEntryColor();
349  rValue.nColor = aColor;
350 }
351 
352 // color of an extended entry has changed
353 void ColorConfigWindow_Impl::Entry::ColorChanged(ExtendedColorConfigValue& rValue)
354 {
355  Color aColor = m_xColorList->GetSelectEntryColor();
356  rValue.setColor(aColor);
357  if (aColor == COL_AUTO)
358  {
359  rValue.setColor(rValue.getDefaultColor());
360  }
361 }
362 
363 // ColorConfigWindow_Impl
364 ColorConfigWindow_Impl::ColorConfigWindow_Impl(weld::Window* pTopLevel, weld::Container* pParent)
365  : m_pTopLevel(pTopLevel)
366  , m_xBuilder(Application::CreateBuilder(pParent, "cui/ui/colorconfigwin.ui"))
367  , m_xBox(m_xBuilder->weld_box("ColorConfigWindow"))
368  , m_xWidget1(m_xBuilder->weld_widget("doccolor"))
369  , m_xWidget2(m_xBuilder->weld_widget("doccolor_lb"))
370 {
371  CreateEntries();
372 }
373 
374 void ColorConfigWindow_Impl::CreateEntries()
375 {
376  std::bitset<nGroupCount> aModulesInstalled;
377  // creating group headers
378  vChapters.reserve(nGroupCount);
379  for (unsigned i = 0; i != nGroupCount; ++i)
380  {
381  aModulesInstalled[i] = IsGroupVisible(vGroupInfo[i].eGroup);
382  vChapters.push_back(std::make_shared<Chapter>(*m_xBuilder, vGroupInfo[i].pGroup, aModulesInstalled[i]));
383  }
384 
385  // Here we want to get the amount to add to the position of a FixedText to
386  // get it to align its contents with that of a CheckBox
387  tools::Long nCheckBoxLabelOffset = 0;
388  {
389  OUString sSampleText("X");
390  std::unique_ptr<weld::CheckButton> xCheckBox(m_xBuilder->weld_check_button("docboundaries"));
391  std::unique_ptr<weld::Label> xFixedText(m_xBuilder->weld_label("doccolor"));
392  OUString sOrigCheck(xCheckBox->get_label());
393  OUString sOrigFixed(xFixedText->get_label());
394  xCheckBox->set_label(sSampleText);
395  xFixedText->set_label(sSampleText);
396  Size aCheckSize(xCheckBox->get_preferred_size());
397  Size aFixedSize(xFixedText->get_preferred_size());
398  xCheckBox->set_label(sOrigCheck);
399  xFixedText->set_label(sOrigFixed);
400  nCheckBoxLabelOffset = aCheckSize.Width() - aFixedSize.Width();
401  }
402 
403  // creating entries
404  vEntries.reserve(ColorConfigEntryCount);
405  for (size_t i = 0; i < SAL_N_ELEMENTS(vEntryInfo); ++i)
406  {
407  vEntries.push_back(std::make_shared<Entry>(m_pTopLevel, *m_xBuilder,
408  vEntryInfo[i].pText, vEntryInfo[i].pColor,
409  ColorConfig::GetDefaultColor(static_cast<ColorConfigEntry>(i)),
410  nCheckBoxLabelOffset,
411  vEntryInfo[i].bCheckBox,
412  aModulesInstalled[vEntryInfo[i].eGroup]));
413  }
414 
415  // extended entries
416  ExtendedColorConfig aExtConfig;
417  unsigned const nExtGroupCount = aExtConfig.GetComponentCount();
418  if (!nExtGroupCount)
419  return;
420 
421  for (unsigned j = 0; j != nExtGroupCount; ++j)
422  {
423  vExtBuilders.emplace_back(Application::CreateBuilder(m_xBox.get(), "cui/ui/chapterfragment.ui"));
424  vExtContainers.emplace_back(vExtBuilders.back()->weld_frame("ChapterFragment"));
425 
426  OUString const sComponentName = aExtConfig.GetComponentName(j);
427  vChapters.push_back(std::make_shared<Chapter>(
428  *vExtBuilders.back(), "chapter", true));
429  vChapters.back()->SetText(aExtConfig.GetComponentDisplayName(sComponentName));
430 
431  vExtContainers.emplace_back(vExtBuilders.back()->weld_box("contents"));
432  weld::Container* pChapterBox = vExtContainers.back().get();
433 
434  unsigned nColorCount = aExtConfig.GetComponentColorCount(sComponentName);
435  for (unsigned i = 0; i != nColorCount; ++i)
436  {
437  vExtBuilders.emplace_back(Application::CreateBuilder(pChapterBox, "cui/ui/colorfragment.ui"));
438  vExtContainers.emplace_back(vExtBuilders.back()->weld_container("ColorFragment"));
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  }
447  }
448 }
449 
450 void ColorConfigWindow_Impl::AdjustExtraWidths(int nTextWidth)
451 {
452  for (size_t i = SAL_N_ELEMENTS(vEntryInfo); i < vEntries.size(); ++i)
453  vEntries[i]->set_width_request(nTextWidth);
454 }
455 
456 // SetLinks()
457 void ColorConfigWindow_Impl::SetLinks(Link<weld::Toggleable&,void> const& aCheckLink,
458  Link<ColorListBox&,void> const& aColorLink,
459  Link<weld::Widget&,void> const& rGetFocusLink,
460  weld::ScrolledWindow& rScroll)
461 {
462  if (vEntries.empty())
463  return;
464  for (auto const & i: vEntries)
465  i->SetLinks(aCheckLink, aColorLink, rGetFocusLink);
466  // 6 is the spacing set on ColorConfigWindow
467  rScroll.vadjustment_set_step_increment(vEntries[0]->get_height_request() + 6);
468 }
469 
470 // Update()
471 void ColorConfigWindow_Impl::Update (
472  EditableColorConfig const* pConfig,
473  EditableExtendedColorConfig const* pExtConfig)
474 {
475  // updating default entries
476  for (unsigned i = 0; i != ColorConfigEntryCount; ++i)
477  {
478  ColorConfigEntry const aColorEntry = static_cast<ColorConfigEntry>(i);
479  vEntries[i]->Update(
480  pConfig->GetColorValue(aColorEntry)
481  );
482  }
483 
484  // updating extended entries
485  decltype(vEntries)::size_type i = ColorConfigEntryCount;
486  unsigned const nExtCount = pExtConfig->GetComponentCount();
487  for (unsigned j = 0; j != nExtCount; ++j)
488  {
489  OUString sComponentName = pExtConfig->GetComponentName(j);
490  unsigned const nColorCount = pExtConfig->GetComponentColorCount(sComponentName);
491  for (unsigned k = 0; i != vEntries.size() && k != nColorCount; ++i, ++k)
492  vEntries[i]->Update(
493  pExtConfig->GetComponentColorConfigValue(sComponentName, k)
494  );
495  }
496 }
497 
498 // ClickHdl()
499 void ColorConfigWindow_Impl::ClickHdl(EditableColorConfig* pConfig, weld::Toggleable& rBox)
500 {
501  for (unsigned i = 0; i != ColorConfigEntryCount; ++i)
502  {
503  if (vEntries[i]->Is(&rBox))
504  {
505  ColorConfigEntry const aEntry = static_cast<ColorConfigEntry>(i);
506  ColorConfigValue aValue = pConfig->GetColorValue(aEntry);
507  aValue.bIsVisible = rBox.get_active();
508  pConfig->SetColorValue(aEntry, aValue);
509  break;
510  }
511  }
512 }
513 
514 // ColorHdl()
515 void ColorConfigWindow_Impl::ColorHdl(
516  EditableColorConfig* pConfig, EditableExtendedColorConfig* pExtConfig,
517  const ColorListBox* pBox)
518 {
519  unsigned i = 0;
520 
521  // default entries
522  for ( ; i != ColorConfigEntryCount; ++i)
523  {
524  if (pBox && vEntries[i]->Is(pBox))
525  {
526  ColorConfigEntry const aColorEntry = static_cast<ColorConfigEntry>(i);
527  ColorConfigValue aValue = pConfig->GetColorValue(aColorEntry);
528  vEntries[i]->ColorChanged(aValue);
529  pConfig->SetColorValue(aColorEntry, aValue);
530  break;
531  }
532  }
533 
534  // extended entries
535  unsigned const nExtCount = pExtConfig->GetComponentCount();
537  for (unsigned j = 0; j != nExtCount; ++j)
538  {
539  OUString sComponentName = pExtConfig->GetComponentName(j);
540  unsigned const nColorCount = pExtConfig->GetComponentColorCount(sComponentName);
541  unsigned const nCount = vEntries.size();
542  for (unsigned k = 0; i != nCount && k != nColorCount; ++i, ++k)
543  {
544  if (pBox && vEntries[i]->Is(pBox))
545  {
546  ExtendedColorConfigValue aValue =
547  pExtConfig->GetComponentColorConfigValue(sComponentName, k);
548  vEntries[i]->ColorChanged(aValue);
549  pExtConfig->SetColorValue(sComponentName, aValue);
550  break;
551  }
552  }
553  }
554 }
555 
556 
557 // IsGroupVisible()
558 bool ColorConfigWindow_Impl::IsGroupVisible (Group eGroup) const
559 {
560  switch (eGroup)
561  {
562  case Group_Writer:
563  case Group_Html:
564  return aModuleOptions.IsModuleInstalled(SvtModuleOptions::EModule::WRITER);
565  case Group_Calc:
566  return aModuleOptions.IsModuleInstalled(SvtModuleOptions::EModule::CALC);
567  case Group_Draw:
568  return
569  aModuleOptions.IsModuleInstalled(SvtModuleOptions::EModule::DRAW) ||
570  aModuleOptions.IsModuleInstalled(SvtModuleOptions::EModule::IMPRESS);
571  case Group_Sql:
572  return aModuleOptions.IsModuleInstalled(SvtModuleOptions::EModule::DATABASE);
573  default:
574  return true;
575  }
576 }
577 
579 {
580  std::unique_ptr<weld::ScrolledWindow> m_xVScroll;
581  std::unique_ptr<weld::Container> m_xBody;
582  std::unique_ptr<ColorConfigWindow_Impl> m_xScrollWindow;
583 
584  EditableColorConfig* pColorConfig;
585  EditableExtendedColorConfig* pExtColorConfig;
586 
587  DECL_LINK(ClickHdl, weld::Toggleable&, void);
588  DECL_LINK(ColorHdl, ColorListBox&, void);
589  DECL_LINK(ControlFocusHdl, weld::Widget&, void);
590 
591 public:
592  explicit ColorConfigCtrl_Impl(weld::Window* pTopLevel, weld::Builder& rbuilder);
593 
594  void AdjustExtraWidths(int nTextWidth) { m_xScrollWindow->AdjustExtraWidths(nTextWidth); }
595  void SetConfig (EditableColorConfig& rConfig) { pColorConfig = &rConfig; }
596  void SetExtendedConfig (EditableExtendedColorConfig& rConfig) { pExtColorConfig = &rConfig; }
597  void Update();
599  {
600  return m_xVScroll->vadjustment_get_value();
601  }
603  {
604  m_xVScroll->vadjustment_set_value(nSet);
605  }
607  {
608  return m_xScrollWindow->GetWidget1();
609  }
611  {
612  return m_xScrollWindow->GetWidget2();
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 
650 IMPL_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_xColorSchemeLB(m_xBuilder->weld_combo_box("colorschemelb"))
693  , m_xSaveSchemePB(m_xBuilder->weld_button("save"))
694  , m_xDeleteSchemePB(m_xBuilder->weld_button("delete"))
695  , m_xColorConfigCT(new ColorConfigCtrl_Impl(pController->getDialog(), *m_xBuilder))
696  , m_xTable(m_xBuilder->weld_widget("table"))
697  , m_xOnFT(m_xBuilder->weld_label("on"))
698  , m_xElementFT(m_xBuilder->weld_label("uielements"))
699  , m_xColorFT(m_xBuilder->weld_label("colorsetting"))
700  , m_rWidget1(m_xColorConfigCT->GetWidget1())
701  , m_rWidget2(m_xColorConfigCT->GetWidget2())
702 {
703  m_xColorSchemeLB->make_sorted();
704  m_xColorSchemeLB->connect_changed(LINK(this, SvxColorOptionsTabPage, SchemeChangedHdl_Impl));
705  Link<weld::Button&,void> aLk = LINK(this, SvxColorOptionsTabPage, SaveDeleteHdl_Impl );
706  m_xSaveSchemePB->connect_clicked(aLk);
707  m_xDeleteSchemePB->connect_clicked(aLk);
708 
711 }
712 
714 {
715  if (pColorConfig)
716  {
717  //when the dialog is cancelled but the color scheme ListBox has been changed these
718  //changes need to be undone
719  if (!bFillItemSetCalled && m_xColorSchemeLB->get_value_changed_from_saved())
720  {
721  OUString sOldScheme = m_xColorSchemeLB->get_saved_value();
722  if(!sOldScheme.isEmpty())
723  {
724  pColorConfig->SetCurrentSchemeName(sOldScheme);
725  pExtColorConfig->SetCurrentSchemeName(sOldScheme);
726  }
727  }
728  pColorConfig->ClearModified();
729  pColorConfig->EnableBroadcast();
730  pColorConfig.reset();
731 
732  pExtColorConfig->ClearModified();
733  pExtColorConfig->EnableBroadcast();
734  pExtColorConfig.reset();
735  }
736  m_xColorConfigCT.reset();
737 }
738 
739 std::unique_ptr<SfxTabPage> SvxColorOptionsTabPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet)
740 {
741  return std::make_unique<SvxColorOptionsTabPage>(pPage, pController, *rAttrSet);
742 }
743 
745 {
746  bFillItemSetCalled = true;
747  if (m_xColorSchemeLB->get_value_changed_from_saved())
748  {
749  pColorConfig->SetModified();
750  pExtColorConfig->SetModified();
751  }
752  if (pColorConfig->IsModified())
753  pColorConfig->Commit();
754  if (pExtColorConfig->IsModified())
755  pExtColorConfig->Commit();
756  return true;
757 }
758 
760 {
761  if(pColorConfig)
762  {
763  pColorConfig->ClearModified();
764  pColorConfig->DisableBroadcast();
765  }
766  pColorConfig.reset(new EditableColorConfig);
767  m_xColorConfigCT->SetConfig(*pColorConfig);
768 
769  if(pExtColorConfig)
770  {
771  pExtColorConfig->ClearModified();
772  pExtColorConfig->DisableBroadcast();
773  }
774  pExtColorConfig.reset(new EditableExtendedColorConfig);
775  m_xColorConfigCT->SetExtendedConfig(*pExtColorConfig);
776 
777  OUString sUser = GetUserData();
778  //has to be called always to speed up accessibility tools
779  m_xColorConfigCT->SetScrollPosition(sUser.toInt32());
780  m_xColorSchemeLB->clear();
781  const uno::Sequence< OUString > aSchemes = pColorConfig->GetSchemeNames();
782  for(const OUString& s : aSchemes)
783  m_xColorSchemeLB->append_text(s);
784  m_xColorSchemeLB->set_active_text(pColorConfig->GetCurrentSchemeName());
785  m_xColorSchemeLB->save_value();
786  m_xDeleteSchemePB->set_sensitive( aSchemes.getLength() > 1 );
788 }
789 
791 {
792  if ( pSet_ )
793  FillItemSet( pSet_ );
794  return DeactivateRC::LeavePage;
795 }
796 
798 {
799  //update the color config control
800  m_xColorConfigCT->Update();
801 }
802 
803 IMPL_LINK(SvxColorOptionsTabPage, SchemeChangedHdl_Impl, weld::ComboBox&, rBox, void)
804 {
805  pColorConfig->LoadScheme(rBox.get_active_text());
806  pExtColorConfig->LoadScheme(rBox.get_active_text());
807  UpdateColorConfig();
808 }
809 
810 IMPL_LINK(SvxColorOptionsTabPage, SaveDeleteHdl_Impl, weld::Button&, rButton, void)
811 {
812  if (m_xSaveSchemePB.get() == &rButton)
813  {
814  OUString sName;
815 
818  sName, CuiResId(RID_SVXSTR_COLOR_CONFIG_SAVE2) ));
819  aNameDlg->SetCheckNameHdl( LINK(this, SvxColorOptionsTabPage, CheckNameHdl_Impl));
820  aNameDlg->SetText(CuiResId(RID_SVXSTR_COLOR_CONFIG_SAVE1));
821  aNameDlg->SetHelpId(HID_OPTIONS_COLORCONFIG_SAVE_SCHEME);
822  aNameDlg->SetCheckNameHdl( LINK(this, SvxColorOptionsTabPage, CheckNameHdl_Impl));
823  if(RET_OK == aNameDlg->Execute())
824  {
825  aNameDlg->GetName(sName);
826  pColorConfig->AddScheme(sName);
827  pExtColorConfig->AddScheme(sName);
828  m_xColorSchemeLB->append_text(sName);
829  m_xColorSchemeLB->set_active_text(sName);
830  SchemeChangedHdl_Impl(*m_xColorSchemeLB);
831  }
832  }
833  else
834  {
835  DBG_ASSERT(m_xColorSchemeLB->get_count() > 1, "don't delete the last scheme");
836  std::unique_ptr<weld::MessageDialog> xQuery(Application::CreateMessageDialog(GetFrameWeld(),
837  VclMessageType::Question, VclButtonsType::YesNo,
838  CuiResId(RID_SVXSTR_COLOR_CONFIG_DELETE)));
839  xQuery->set_title(CuiResId(RID_SVXSTR_COLOR_CONFIG_DELETE_TITLE));
840  if (RET_YES == xQuery->run())
841  {
842  OUString sDeleteScheme(m_xColorSchemeLB->get_active_text());
843  m_xColorSchemeLB->remove(m_xColorSchemeLB->get_active());
844  m_xColorSchemeLB->set_active(0);
845  SchemeChangedHdl_Impl(*m_xColorSchemeLB);
846  //first select the new scheme and then delete the old one
847  pColorConfig->DeleteScheme(sDeleteScheme);
848  pExtColorConfig->DeleteScheme(sDeleteScheme);
849  }
850  }
851  m_xDeleteSchemePB->set_sensitive(m_xColorSchemeLB->get_count() > 1);
852 }
853 
854 IMPL_LINK(SvxColorOptionsTabPage, CheckNameHdl_Impl, AbstractSvxNameDialog&, rDialog, bool )
855 {
856  OUString sName;
857  rDialog.GetName(sName);
858  return !sName.isEmpty() && m_xColorSchemeLB->find_text(sName) == -1;
859 }
860 
862 {
863  SetUserData(OUString::number(m_xColorConfigCT->GetScrollPosition()));
864 }
865 
866 IMPL_LINK_NOARG(SvxColorOptionsTabPage, AdjustHeaderBar, const Size&, void)
867 {
868  // horizontal positions
869  int nX0 = 0, nX1, nX2, y, width, height;
870  if (!m_rWidget1.get_extents_relative_to(*m_xTable, nX1, y, width, height))
871  return;
872  if (!m_rWidget2.get_extents_relative_to(*m_xTable, nX2, y, width, height))
873  return;
874  auto nTextWidth1 = nX1 - nX0;
875  auto nTextWidth2 = nX2 - nX1;
876  m_xOnFT->set_size_request(nTextWidth1, -1);
877  m_xElementFT->set_size_request(nTextWidth2, -1);
878  m_xColorConfigCT->AdjustExtraWidths(nTextWidth2 - 12);
879 }
880 
881 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
css::uno::Reference< css::linguistic2::XProofreadingIterator > get(css::uno::Reference< css::uno::XComponentContext > const &context)
Group
Definition: optcolor.cxx:45
static weld::Builder * CreateBuilder(weld::Widget *pParent, const OUString &rUIFile, bool bMobile=false, sal_uInt64 nLOKWindowId=0)
void SetUserData(const OUString &rString)
SvxColorOptionsTabPage(weld::Container *pPage, weld::DialogController *pController, const SfxItemSet &rSet)
Definition: optcolor.cxx:689
EditableExtendedColorConfig * pExtColorConfig
Definition: optcolor.cxx:585
static SvxAbstractDialogFactory * Create()
long Long
std::unique_ptr< weld::Button > m_xSaveSchemePB
Definition: optcolor.hxx:31
virtual void FillUserData() override
Definition: optcolor.cxx:861
std::unique_ptr< svtools::EditableExtendedColorConfig > pExtColorConfig
Definition: optcolor.hxx:42
std::unique_ptr< svtools::EditableColorConfig > pColorConfig
Definition: optcolor.hxx:41
float x
constexpr tools::Long Width() const
#define IDS_CB(Name)
virtual VclPtr< AbstractSvxNameDialog > CreateSvxNameDialog(weld::Window *pParent, const OUString &rName, const OUString &rDesc)=0
std::unique_ptr< ColorConfigWindow_Impl > m_xScrollWindow
Definition: optcolor.cxx:582
RET_YES
#define HID_OPTIONS_COLORCONFIG_SAVE_SCHEME
Definition: helpids.h:21
int nCount
const OUString & GetUserData() const
weld::Widget & GetWidget1()
Definition: optcolor.cxx:606
weld::Widget & GetWidget2()
Definition: optcolor.cxx:610
DECL_LINK(ClickHdl, weld::Toggleable &, void)
const char * sName
float y
#define SAL_N_ELEMENTS(arr)
virtual ~SvxColorOptionsTabPage() override
Definition: optcolor.cxx:713
void SetConfig(EditableColorConfig &rConfig)
Definition: optcolor.cxx:595
OUString CuiResId(TranslateId aKey)
Definition: cuiresmgr.cxx:23
virtual DeactivateRC DeactivatePage(SfxItemSet *pSet) override
Definition: optcolor.cxx:790
#define DBG_ASSERT(sCon, aError)
int i
std::unique_ptr< weld::ScrolledWindow > m_xVScroll
Definition: optcolor.cxx:580
weld::Widget & m_rWidget2
Definition: optcolor.hxx:39
std::unique_ptr< weld::Button > m_xDeleteSchemePB
Definition: optcolor.hxx:32
std::unique_ptr< weld::Container > m_xBody
Definition: optcolor.cxx:581
std::unique_ptr< weld::ComboBox > m_xColorSchemeLB
Definition: optcolor.hxx:30
static std::unique_ptr< SfxTabPage > Create(weld::Container *pPage, weld::DialogController *pController, const SfxItemSet *rAttrSet)
Definition: optcolor.cxx:739
void SetExtendedConfig(EditableExtendedColorConfig &rConfig)
Definition: optcolor.cxx:596
ColorConfigEntryCount
weld::Widget & m_rWidget1
Definition: optcolor.hxx:38
virtual void set_label(const OUString &rText)=0
virtual bool FillItemSet(SfxItemSet *rSet) override
Definition: optcolor.cxx:744
EditableColorConfig * pColorConfig
Definition: optcolor.cxx:584
IMPL_LINK_NOARG(SvxColorOptionsTabPage, AdjustHeaderBar, const Size &, void)
Definition: optcolor.cxx:866
virtual std::unique_ptr< CheckButton > weld_check_button(const OString &id)=0
virtual void connect_size_allocate(const Link< const Size &, void > &rLink)
ColorConfigCtrl_Impl(weld::Window *pTopLevel, weld::Builder &rbuilder)
Definition: optcolor.cxx:616
RET_OK
void SetScrollPosition(tools::Long nSet)
Definition: optcolor.cxx:602
#define IDS(Name)
void AdjustExtraWidths(int nTextWidth)
Definition: optcolor.cxx:594
DeactivateRC
virtual std::unique_ptr< Label > weld_label(const OString &id)=0
virtual void vadjustment_set_step_increment(int size)=0
weld::Window * GetFrameWeld(const SfxFrame *pFrame)
virtual bool get_active() const =0
tools::Long GetScrollPosition() const
Definition: optcolor.cxx:598
static weld::MessageDialog * CreateMessageDialog(weld::Widget *pParent, VclMessageType eMessageType, VclButtonsType eButtonType, const OUString &rPrimaryMessage, bool bMobile=false)
ColorConfigEntry
IMPL_LINK(ColorConfigCtrl_Impl, ClickHdl, weld::Toggleable &, rBox, void)
Definition: optcolor.cxx:637
std::unique_ptr< ColorConfigCtrl_Impl > m_xColorConfigCT
Definition: optcolor.hxx:33
virtual void Reset(const SfxItemSet *rSet) override
Definition: optcolor.cxx:759