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::ToggleButton&,void> const&,
171  weld::ScrolledWindow& rScroll);
172  void Update(EditableColorConfig const*, EditableExtendedColorConfig const*);
173  void ClickHdl(EditableColorConfig*, weld::ToggleButton&);
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_xGrid;
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, 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::ToggleButton&,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::ToggleButton* 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::Container> m_xGrid;
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  long nCheckBoxLabelOffset, bool bCheckBox, bool bShow)
284  : m_xColorList(new ColorListBox(rBuilder.weld_menu_button(pColorWidget), 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_left(m_xText->get_margin_left() +
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::ToggleButton&,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::ToggleButton* pCheckBox = dynamic_cast<weld::ToggleButton*>(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::ToggleButton* pCheckBox = dynamic_cast<weld::ToggleButton*>(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_xGrid(m_xBuilder->weld_container("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  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  size_t nLineNum = vChapters.size() + vEntries.size() + 1;
422  for (unsigned j = 0; j != nExtGroupCount; ++j)
423  {
424  vExtBuilders.emplace_back(Application::CreateBuilder(m_xGrid.get(), "cui/ui/chapterfragment.ui"));
425  vExtContainers.emplace_back(vExtBuilders.back()->weld_container("ChapterFragment"));
426 
427  vExtContainers.back()->set_grid_width(3);
428  vExtContainers.back()->set_grid_left_attach(0);
429  vExtContainers.back()->set_grid_top_attach(nLineNum);
430 
431  OUString const sComponentName = aExtConfig.GetComponentName(j);
432  vChapters.push_back(std::make_shared<Chapter>(
433  *vExtBuilders.back(), "chapter", true));
434  vChapters.back()->SetText(aExtConfig.GetComponentDisplayName(sComponentName));
435  ++nLineNum;
436  unsigned nColorCount = aExtConfig.GetComponentColorCount(sComponentName);
437  for (unsigned i = 0; i != nColorCount; ++i)
438  {
439  vExtBuilders.emplace_back(Application::CreateBuilder(m_xGrid.get(), "cui/ui/colorfragment.ui"));
440  vExtContainers.emplace_back(vExtBuilders.back()->weld_container("ColorFragment"));
441 
442  vExtContainers.back()->set_grid_width(3);
443  vExtContainers.back()->set_grid_left_attach(0);
444  vExtContainers.back()->set_grid_top_attach(nLineNum);
445 
446  ExtendedColorConfigValue const aColorEntry =
447  aExtConfig.GetComponentColorConfigValue(sComponentName, i);
448  vEntries.push_back(std::make_shared<Entry>(m_pTopLevel, *vExtBuilders.back(),
449  "label", "button", aColorEntry.getDefaultColor(),
450  nCheckBoxLabelOffset, false, true));
451  vEntries.back()->SetText(aColorEntry.getDisplayName());
452  ++nLineNum;
453  }
454  }
455 }
456 
457 void ColorConfigWindow_Impl::AdjustExtraWidths(int nTextWidth)
458 {
459  for (size_t i = SAL_N_ELEMENTS(vEntryInfo); i < vEntries.size(); ++i)
460  vEntries[i]->set_width_request(nTextWidth);
461 }
462 
463 // SetLinks()
464 void ColorConfigWindow_Impl::SetLinks(Link<weld::ToggleButton&,void> const& aCheckLink,
465  Link<ColorListBox&,void> const& aColorLink,
466  Link<weld::Widget&,void> const& rGetFocusLink,
467  weld::ScrolledWindow& rScroll)
468 {
469  if (vEntries.empty())
470  return;
471  for (auto const & i: vEntries)
472  i->SetLinks(aCheckLink, aColorLink, rGetFocusLink);
473  // 6 is the spacing set on ColorConfigWindow
474  rScroll.vadjustment_set_step_increment(vEntries[0]->get_height_request() + 6);
475 }
476 
477 // Update()
478 void ColorConfigWindow_Impl::Update (
479  EditableColorConfig const* pConfig,
480  EditableExtendedColorConfig const* pExtConfig)
481 {
482  // updating default entries
483  for (unsigned i = 0; i != ColorConfigEntryCount; ++i)
484  {
485  ColorConfigEntry const aColorEntry = static_cast<ColorConfigEntry>(i);
486  vEntries[i]->Update(
487  pConfig->GetColorValue(aColorEntry)
488  );
489  }
490 
491  // updating extended entries
492  decltype(vEntries)::size_type i = ColorConfigEntryCount;
493  unsigned const nExtCount = pExtConfig->GetComponentCount();
494  for (unsigned j = 0; j != nExtCount; ++j)
495  {
496  OUString sComponentName = pExtConfig->GetComponentName(j);
497  unsigned const nColorCount = pExtConfig->GetComponentColorCount(sComponentName);
498  for (unsigned k = 0; i != vEntries.size() && k != nColorCount; ++i, ++k)
499  vEntries[i]->Update(
500  pExtConfig->GetComponentColorConfigValue(sComponentName, k)
501  );
502  }
503 }
504 
505 // ClickHdl()
506 void ColorConfigWindow_Impl::ClickHdl(EditableColorConfig* pConfig, weld::ToggleButton& rBox)
507 {
508  for (unsigned i = 0; i != ColorConfigEntryCount; ++i)
509  {
510  if (vEntries[i]->Is(&rBox))
511  {
512  ColorConfigEntry const aEntry = static_cast<ColorConfigEntry>(i);
513  ColorConfigValue aValue = pConfig->GetColorValue(aEntry);
514  aValue.bIsVisible = rBox.get_active();
515  pConfig->SetColorValue(aEntry, aValue);
516  break;
517  }
518  }
519 }
520 
521 // ColorHdl()
522 void ColorConfigWindow_Impl::ColorHdl(
523  EditableColorConfig* pConfig, EditableExtendedColorConfig* pExtConfig,
524  const ColorListBox* pBox)
525 {
526  unsigned i = 0;
527 
528  // default entries
529  for ( ; i != ColorConfigEntryCount; ++i)
530  {
531  if (pBox && vEntries[i]->Is(pBox))
532  {
533  ColorConfigEntry const aColorEntry = static_cast<ColorConfigEntry>(i);
534  ColorConfigValue aValue = pConfig->GetColorValue(aColorEntry);
535  vEntries[i]->ColorChanged(aValue);
536  pConfig->SetColorValue(aColorEntry, aValue);
537  break;
538  }
539  }
540 
541  // extended entries
542  unsigned const nExtCount = pExtConfig->GetComponentCount();
544  for (unsigned j = 0; j != nExtCount; ++j)
545  {
546  OUString sComponentName = pExtConfig->GetComponentName(j);
547  unsigned const nColorCount = pExtConfig->GetComponentColorCount(sComponentName);
548  unsigned const nCount = vEntries.size();
549  for (unsigned k = 0; i != nCount && k != nColorCount; ++i, ++k)
550  {
551  if (pBox && vEntries[i]->Is(pBox))
552  {
553  ExtendedColorConfigValue aValue =
554  pExtConfig->GetComponentColorConfigValue(sComponentName, k);
555  vEntries[i]->ColorChanged(aValue);
556  pExtConfig->SetColorValue(sComponentName, aValue);
557  break;
558  }
559  }
560  }
561 }
562 
563 
564 // IsGroupVisible()
565 bool ColorConfigWindow_Impl::IsGroupVisible (Group eGroup) const
566 {
567  switch (eGroup)
568  {
569  case Group_Writer:
570  case Group_Html:
571  return aModuleOptions.IsModuleInstalled(SvtModuleOptions::EModule::WRITER);
572  case Group_Calc:
573  return aModuleOptions.IsModuleInstalled(SvtModuleOptions::EModule::CALC);
574  case Group_Draw:
575  return
576  aModuleOptions.IsModuleInstalled(SvtModuleOptions::EModule::DRAW) ||
577  aModuleOptions.IsModuleInstalled(SvtModuleOptions::EModule::IMPRESS);
578  case Group_Sql:
579  return aModuleOptions.IsModuleInstalled(SvtModuleOptions::EModule::DATABASE);
580  default:
581  return true;
582  }
583 }
584 
586 {
587  std::unique_ptr<weld::ScrolledWindow> m_xVScroll;
588  std::unique_ptr<weld::Container> m_xBody;
589  std::unique_ptr<ColorConfigWindow_Impl> m_xScrollWindow;
590 
591  EditableColorConfig* pColorConfig;
592  EditableExtendedColorConfig* pExtColorConfig;
593 
594  DECL_LINK(ClickHdl, weld::ToggleButton&, void);
595  DECL_LINK(ColorHdl, ColorListBox&, void);
596  DECL_LINK(ControlFocusHdl, weld::Widget&, void);
597 
598 public:
599  explicit ColorConfigCtrl_Impl(weld::Window* pTopLevel, weld::Builder& rbuilder);
600 
601  void AdjustExtraWidths(int nTextWidth) { m_xScrollWindow->AdjustExtraWidths(nTextWidth); }
602  void SetConfig (EditableColorConfig& rConfig) { pColorConfig = &rConfig; }
603  void SetExtendedConfig (EditableExtendedColorConfig& rConfig) { pExtColorConfig = &rConfig; }
604  void Update();
605  long GetScrollPosition() const
606  {
607  return m_xVScroll->vadjustment_get_value();
608  }
609  void SetScrollPosition(long nSet)
610  {
611  m_xVScroll->vadjustment_set_value(nSet);
612  }
614  {
615  return m_xScrollWindow->GetWidget1();
616  }
618  {
619  return m_xScrollWindow->GetWidget2();
620  }
621 };
622 
624  : m_xVScroll(rBuilder.weld_scrolled_window("scroll"))
625  , m_xBody(rBuilder.weld_container("colorconfig"))
626  , m_xScrollWindow(std::make_unique<ColorConfigWindow_Impl>(pTopLevel, m_xBody.get()))
627  , pColorConfig(nullptr)
628  , pExtColorConfig(nullptr)
629 {
630  m_xBody->set_stack_background();
631 
632  Link<weld::ToggleButton&,void> aCheckLink = LINK(this, ColorConfigCtrl_Impl, ClickHdl);
633  Link<ColorListBox&,void> aColorLink = LINK(this, ColorConfigCtrl_Impl, ColorHdl);
634  Link<weld::Widget&,void> const& aGetFocusLink = LINK(this, ColorConfigCtrl_Impl, ControlFocusHdl);
635  m_xScrollWindow->SetLinks(aCheckLink, aColorLink, aGetFocusLink, *m_xVScroll);
636 }
637 
639 {
640  DBG_ASSERT(pColorConfig, "Configuration not set");
642 }
643 
645 {
646  DBG_ASSERT(pColorConfig, "Configuration not set");
647  m_xScrollWindow->ClickHdl(pColorConfig, rBox);
648 }
649 
650 // a color list has changed
652 {
653  DBG_ASSERT(pColorConfig, "Configuration not set" );
654  m_xScrollWindow->ColorHdl(pColorConfig, pExtColorConfig, &rBox);
655 }
656 
657 IMPL_LINK(ColorConfigCtrl_Impl, ControlFocusHdl, weld::Widget&, rCtrl, void)
658 {
659  // determine whether a control is completely visible
660  // and make it visible
661  unsigned const nWinHeight = m_xVScroll->vadjustment_get_page_size();
662 
663  // calc visible area
664  auto nThumbPos = m_xVScroll->vadjustment_get_value();
665  int const nWinTop = nThumbPos;
666  int const nWinBottom = nWinTop + nWinHeight;
667 
668  int x, nCtrlPosY, width, nHeight;
669  rCtrl.get_extents_relative_to(m_xScrollWindow->GetBody(), x, nCtrlPosY, width, nHeight);
670 
671  int const nSelectedItemTop = nCtrlPosY;
672  int const nSelectedItemBottom = nCtrlPosY + nHeight;
673  bool const shouldScrollDown = nSelectedItemBottom >= nWinBottom;
674  bool const shouldScrollUp = nSelectedItemTop <= nWinTop;
675  bool const isNeedToScroll = shouldScrollDown || shouldScrollUp || nCtrlPosY < 0;
676 
677  if (!isNeedToScroll)
678  return;
679 
680  if (shouldScrollDown)
681  {
682  int nOffset = nSelectedItemBottom - nWinBottom;
683  nThumbPos += nOffset + 2;
684  }
685  else
686  {
687  int nOffset = nWinTop - nSelectedItemTop;
688  nThumbPos -= nOffset + 2;
689  if(nThumbPos < 0)
690  nThumbPos = 0;
691  }
692  m_xVScroll->vadjustment_set_value(nThumbPos);
693 }
694 
695 // SvxColorOptionsTabPage
697  : SfxTabPage(pPage, pController, "cui/ui/optappearancepage.ui", "OptAppearancePage", &rCoreSet)
698  , bFillItemSetCalled(false)
699  , m_xColorSchemeLB(m_xBuilder->weld_combo_box("colorschemelb"))
700  , m_xSaveSchemePB(m_xBuilder->weld_button("save"))
701  , m_xDeleteSchemePB(m_xBuilder->weld_button("delete"))
702  , m_xColorConfigCT(new ColorConfigCtrl_Impl(pController->getDialog(), *m_xBuilder))
703  , m_xTable(m_xBuilder->weld_widget("table"))
704  , m_xOnFT(m_xBuilder->weld_label("on"))
705  , m_xElementFT(m_xBuilder->weld_label("uielements"))
706  , m_xColorFT(m_xBuilder->weld_label("colorsetting"))
707  , m_rWidget1(m_xColorConfigCT->GetWidget1())
708  , m_rWidget2(m_xColorConfigCT->GetWidget2())
709 {
710  m_xColorSchemeLB->make_sorted();
711  m_xColorSchemeLB->connect_changed(LINK(this, SvxColorOptionsTabPage, SchemeChangedHdl_Impl));
712  Link<weld::Button&,void> aLk = LINK(this, SvxColorOptionsTabPage, SaveDeleteHdl_Impl );
713  m_xSaveSchemePB->connect_clicked(aLk);
714  m_xDeleteSchemePB->connect_clicked(aLk);
715 
718 }
719 
721 {
722  if (pColorConfig)
723  {
724  //when the dialog is cancelled but the color scheme ListBox has been changed these
725  //changes need to be undone
726  if (!bFillItemSetCalled && m_xColorSchemeLB->get_value_changed_from_saved())
727  {
728  OUString sOldScheme = m_xColorSchemeLB->get_saved_value();
729  if(!sOldScheme.isEmpty())
730  {
731  pColorConfig->SetCurrentSchemeName(sOldScheme);
732  pExtColorConfig->SetCurrentSchemeName(sOldScheme);
733  }
734  }
735  pColorConfig->ClearModified();
736  pColorConfig->EnableBroadcast();
737  pColorConfig.reset();
738 
739  pExtColorConfig->ClearModified();
740  pExtColorConfig->EnableBroadcast();
741  pExtColorConfig.reset();
742  }
743  m_xColorConfigCT.reset();
744 }
745 
746 std::unique_ptr<SfxTabPage> SvxColorOptionsTabPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet)
747 {
748  return std::make_unique<SvxColorOptionsTabPage>(pPage, pController, *rAttrSet);
749 }
750 
752 {
753  bFillItemSetCalled = true;
754  if (m_xColorSchemeLB->get_value_changed_from_saved())
755  {
756  pColorConfig->SetModified();
757  pExtColorConfig->SetModified();
758  }
759  if (pColorConfig->IsModified())
760  pColorConfig->Commit();
761  if (pExtColorConfig->IsModified())
762  pExtColorConfig->Commit();
763  return true;
764 }
765 
767 {
768  if(pColorConfig)
769  {
770  pColorConfig->ClearModified();
771  pColorConfig->DisableBroadcast();
772  }
773  pColorConfig.reset(new EditableColorConfig);
774  m_xColorConfigCT->SetConfig(*pColorConfig);
775 
776  if(pExtColorConfig)
777  {
778  pExtColorConfig->ClearModified();
779  pExtColorConfig->DisableBroadcast();
780  }
781  pExtColorConfig.reset(new EditableExtendedColorConfig);
782  m_xColorConfigCT->SetExtendedConfig(*pExtColorConfig);
783 
784  OUString sUser = GetUserData();
785  //has to be called always to speed up accessibility tools
786  m_xColorConfigCT->SetScrollPosition(sUser.toInt32());
787  m_xColorSchemeLB->clear();
788  uno::Sequence< OUString > aSchemes = pColorConfig->GetSchemeNames();
789  const OUString* pSchemes = aSchemes.getConstArray();
790  for(sal_Int32 i = 0; i < aSchemes.getLength(); i++)
791  m_xColorSchemeLB->append_text(pSchemes[i]);
792  m_xColorSchemeLB->set_active_text(pColorConfig->GetCurrentSchemeName());
793  m_xColorSchemeLB->save_value();
794  m_xDeleteSchemePB->set_sensitive( aSchemes.getLength() > 1 );
796 }
797 
799 {
800  if ( pSet_ )
801  FillItemSet( pSet_ );
802  return DeactivateRC::LeavePage;
803 }
804 
806 {
807  //update the color config control
808  m_xColorConfigCT->Update();
809 }
810 
811 IMPL_LINK(SvxColorOptionsTabPage, SchemeChangedHdl_Impl, weld::ComboBox&, rBox, void)
812 {
813  pColorConfig->LoadScheme(rBox.get_active_text());
814  pExtColorConfig->LoadScheme(rBox.get_active_text());
815  UpdateColorConfig();
816 }
817 
818 IMPL_LINK(SvxColorOptionsTabPage, SaveDeleteHdl_Impl, weld::Button&, rButton, void)
819 {
820  if (m_xSaveSchemePB.get() == &rButton)
821  {
822  OUString sName;
823 
826  sName, CuiResId(RID_SVXSTR_COLOR_CONFIG_SAVE2) ));
827  aNameDlg->SetCheckNameHdl( LINK(this, SvxColorOptionsTabPage, CheckNameHdl_Impl));
828  aNameDlg->SetText(CuiResId(RID_SVXSTR_COLOR_CONFIG_SAVE1));
829  aNameDlg->SetHelpId(HID_OPTIONS_COLORCONFIG_SAVE_SCHEME);
830  aNameDlg->SetCheckNameHdl( LINK(this, SvxColorOptionsTabPage, CheckNameHdl_Impl));
831  if(RET_OK == aNameDlg->Execute())
832  {
833  aNameDlg->GetName(sName);
834  pColorConfig->AddScheme(sName);
835  pExtColorConfig->AddScheme(sName);
836  m_xColorSchemeLB->append_text(sName);
837  m_xColorSchemeLB->set_active_text(sName);
838  SchemeChangedHdl_Impl(*m_xColorSchemeLB);
839  }
840  }
841  else
842  {
843  DBG_ASSERT(m_xColorSchemeLB->get_count() > 1, "don't delete the last scheme");
844  std::unique_ptr<weld::MessageDialog> xQuery(Application::CreateMessageDialog(GetFrameWeld(),
845  VclMessageType::Question, VclButtonsType::YesNo,
846  CuiResId(RID_SVXSTR_COLOR_CONFIG_DELETE)));
847  xQuery->set_title(CuiResId(RID_SVXSTR_COLOR_CONFIG_DELETE_TITLE));
848  if (RET_YES == xQuery->run())
849  {
850  OUString sDeleteScheme(m_xColorSchemeLB->get_active_text());
851  m_xColorSchemeLB->remove(m_xColorSchemeLB->get_active());
852  m_xColorSchemeLB->set_active(0);
853  SchemeChangedHdl_Impl(*m_xColorSchemeLB);
854  //first select the new scheme and then delete the old one
855  pColorConfig->DeleteScheme(sDeleteScheme);
856  pExtColorConfig->DeleteScheme(sDeleteScheme);
857  }
858  }
859  m_xDeleteSchemePB->set_sensitive(m_xColorSchemeLB->get_count() > 1);
860 }
861 
862 IMPL_LINK(SvxColorOptionsTabPage, CheckNameHdl_Impl, AbstractSvxNameDialog&, rDialog, bool )
863 {
864  OUString sName;
865  rDialog.GetName(sName);
866  return !sName.isEmpty() && m_xColorSchemeLB->find_text(sName) == -1;
867 }
868 
870 {
871  SetUserData(OUString::number(m_xColorConfigCT->GetScrollPosition()));
872 }
873 
874 IMPL_LINK_NOARG(SvxColorOptionsTabPage, AdjustHeaderBar, const Size&, void)
875 {
876  // horizontal positions
877  int nX0 = 0, nX1, nX2, y, width, height;
878  if (!m_rWidget1.get_extents_relative_to(*m_xTable, nX1, y, width, height))
879  return;
880  if (!m_rWidget2.get_extents_relative_to(*m_xTable, nX2, y, width, height))
881  return;
882  auto nTextWidth1 = nX1 - nX0;
883  auto nTextWidth2 = nX2 - nX1;
884  m_xOnFT->set_size_request(nTextWidth1, -1);
885  m_xElementFT->set_size_request(nTextWidth2, -1);
886  m_xColorConfigCT->AdjustExtraWidths(nTextWidth2 - 12);
887 }
888 
889 /* 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
Group
Definition: optcolor.cxx:45
void SetUserData(const OUString &rString)
SvxColorOptionsTabPage(weld::Container *pPage, weld::DialogController *pController, const SfxItemSet &rSet)
Definition: optcolor.cxx:696
EditableExtendedColorConfig * pExtColorConfig
Definition: optcolor.cxx:592
static SvxAbstractDialogFactory * Create()
std::unique_ptr< weld::Button > m_xSaveSchemePB
Definition: optcolor.hxx:31
virtual void FillUserData() override
Definition: optcolor.cxx:869
std::unique_ptr< svtools::EditableExtendedColorConfig > pExtColorConfig
Definition: optcolor.hxx:42
std::unique_ptr< svtools::EditableColorConfig > pColorConfig
Definition: optcolor.hxx:41
float x
virtual bool get_active() const =0
#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:589
RET_YES
IMPL_LINK(ColorConfigCtrl_Impl, ClickHdl, weld::ToggleButton &, rBox, void)
Definition: optcolor.cxx:644
#define HID_OPTIONS_COLORCONFIG_SAVE_SCHEME
Definition: helpids.h:22
int nCount
const OUString & GetUserData() const
Is
weld::Widget & GetWidget1()
Definition: optcolor.cxx:613
weld::Widget & GetWidget2()
Definition: optcolor.cxx:617
DECL_LINK(ClickHdl, weld::ToggleButton &, void)
const char * sName
float y
#define SAL_N_ELEMENTS(arr)
virtual ~SvxColorOptionsTabPage() override
Definition: optcolor.cxx:720
void SetConfig(EditableColorConfig &rConfig)
Definition: optcolor.cxx:602
virtual DeactivateRC DeactivatePage(SfxItemSet *pSet) override
Definition: optcolor.cxx:798
virtual std::unique_ptr< Label > weld_label(const OString &id, bool bTakeOwnership=false)=0
#define DBG_ASSERT(sCon, aError)
int i
std::unique_ptr< weld::ScrolledWindow > m_xVScroll
Definition: optcolor.cxx:587
long GetScrollPosition() const
Definition: optcolor.cxx:605
virtual std::unique_ptr< CheckButton > weld_check_button(const OString &id, bool bTakeOwnership=false)=0
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:588
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:746
void SetExtendedConfig(EditableExtendedColorConfig &rConfig)
Definition: optcolor.cxx:603
ColorConfigEntryCount
weld::Widget & m_rWidget1
Definition: optcolor.hxx:38
OUString CuiResId(const char *pKey)
Definition: cuiresmgr.cxx:23
virtual void set_label(const OUString &rText)=0
virtual bool FillItemSet(SfxItemSet *rSet) override
Definition: optcolor.cxx:751
void SetScrollPosition(long nSet)
Definition: optcolor.cxx:609
EditableColorConfig * pColorConfig
Definition: optcolor.cxx:591
IMPL_LINK_NOARG(SvxColorOptionsTabPage, AdjustHeaderBar, const Size &, void)
Definition: optcolor.cxx:874
virtual void connect_size_allocate(const Link< const Size &, void > &rLink)
ColorConfigCtrl_Impl(weld::Window *pTopLevel, weld::Builder &rbuilder)
Definition: optcolor.cxx:623
RET_OK
#define IDS(Name)
void AdjustExtraWidths(int nTextWidth)
Definition: optcolor.cxx:601
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)
virtual void vadjustment_set_step_increment(int size)=0
weld::Window * GetFrameWeld(const SfxFrame *pFrame)
ColorConfigEntry
std::unique_ptr< ColorConfigCtrl_Impl > m_xColorConfigCT
Definition: optcolor.hxx:33
virtual void Reset(const SfxItemSet *rSet) override
Definition: optcolor.cxx:766