LibreOffice Module cui (master)  1
SvxConfigPageHelper.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 <SvxConfigPageHelper.hxx>
21 
22 #include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
23 #include <com/sun/star/ui/ImageType.hpp>
24 #include <com/sun/star/ui/ItemType.hpp>
25 
26 #include <comphelper/random.hxx>
27 #include <svtools/imgdef.hxx>
28 #include <svtools/miscopt.hxx>
29 
30 static sal_Int16 theImageType = css::ui::ImageType::COLOR_NORMAL | css::ui::ImageType::SIZE_DEFAULT;
31 
32 void SvxConfigPageHelper::RemoveEntry(SvxEntries* pEntries, SvxConfigEntry const* pChildEntry)
33 {
34  SvxEntries::iterator iter = pEntries->begin();
35 
36  while (iter != pEntries->end())
37  {
38  if (pChildEntry == *iter)
39  {
40  pEntries->erase(iter);
41  break;
42  }
43  ++iter;
44  }
45 }
46 
47 OUString SvxConfigPageHelper::replaceSaveInName(const OUString& rMessage,
48  std::u16string_view rSaveInName)
49 {
50  OUString name = rMessage.replaceFirst("%SAVE IN SELECTION%", rSaveInName);
51 
52  return name;
53 }
54 
55 OUString SvxConfigPageHelper::stripHotKey(const OUString& str) { return str.replaceFirst("~", ""); }
56 
57 OUString SvxConfigPageHelper::replaceSixteen(const OUString& str, sal_Int32 nReplacement)
58 {
59  return str.replaceAll(OUString::number(16), OUString::number(nReplacement));
60 }
61 
63 
65 {
66  theImageType = css::ui::ImageType::COLOR_NORMAL | css::ui::ImageType::SIZE_DEFAULT;
67 
68  if (SvtMiscOptions().GetCurrentSymbolsSize() == SFX_SYMBOLS_SIZE_LARGE)
69  {
70  theImageType |= css::ui::ImageType::SIZE_LARGE;
71  }
72  else if (SvtMiscOptions().GetCurrentSymbolsSize() == SFX_SYMBOLS_SIZE_32)
73  {
74  theImageType |= css::ui::ImageType::SIZE_32;
75  }
76 }
77 
78 css::uno::Reference<css::graphic::XGraphic>
79 SvxConfigPageHelper::GetGraphic(const css::uno::Reference<css::ui::XImageManager>& xImageManager,
80  const OUString& rCommandURL)
81 {
82  css::uno::Reference<css::graphic::XGraphic> result;
83 
84  if (xImageManager.is())
85  {
86  // TODO handle large graphics
87  css::uno::Sequence<css::uno::Reference<css::graphic::XGraphic>> aGraphicSeq;
88 
89  css::uno::Sequence<OUString> aImageCmdSeq{ rCommandURL };
90 
91  try
92  {
93  aGraphicSeq = xImageManager->getImages(GetImageType(), aImageCmdSeq);
94 
95  if (aGraphicSeq.hasElements())
96  {
97  result = aGraphicSeq[0];
98  }
99  }
100  catch (css::uno::Exception&)
101  {
102  // will return empty XGraphic
103  }
104  }
105 
106  return result;
107 }
108 
109 OUString SvxConfigPageHelper::generateCustomName(const OUString& prefix, SvxEntries* entries,
110  sal_Int32 suffix /*= 1*/)
111 {
112  OUString name;
113  sal_Int32 pos = 0;
114 
115  // find and replace the %n placeholder in the prefix string
116  name = prefix.replaceFirst("%n", OUString::number(suffix), &pos);
117 
118  if (pos == -1)
119  {
120  // no placeholder found so just append the suffix
121  name += OUString::number(suffix);
122  }
123 
124  if (!entries)
125  return name;
126 
127  // now check if there is an already existing entry with this name
128  bool bFoundEntry = false;
129  for (auto const& entry : *entries)
130  {
131  if (name.equals(entry->GetName()))
132  {
133  bFoundEntry = true;
134  break;
135  }
136  }
137 
138  if (bFoundEntry)
139  {
140  // name already exists so try the next number up
141  return generateCustomName(prefix, entries, ++suffix);
142  }
143 
144  return name;
145 }
146 
147 OUString SvxConfigPageHelper::generateCustomMenuURL(SvxEntries* entries, sal_Int32 suffix /*= 1*/)
148 {
149  OUString url = "vnd.openoffice.org:CustomMenu" + OUString::number(suffix);
150  if (!entries)
151  return url;
152 
153  // now check is there is an already existing entry with this url
154  bool bFoundEntry = false;
155  for (auto const& entry : *entries)
156  {
157  if (url.equals(entry->GetCommand()))
158  {
159  bFoundEntry = true;
160  break;
161  }
162  }
163 
164  if (bFoundEntry)
165  {
166  // url already exists so try the next number up
167  return generateCustomMenuURL(entries, ++suffix);
168  }
169 
170  return url;
171 }
172 
174 {
175  return comphelper::rng::uniform_uint_distribution(0, std::numeric_limits<unsigned int>::max());
176 }
177 
179 {
180  OUString url = OUStringLiteral(ITEM_TOOLBAR_URL) + CUSTOM_TOOLBAR_STR +
181  // use a random number to minimize possible clash with existing custom toolbars
182  OUString::number(generateRandomValue(), 16);
183 
184  // now check is there is an already existing entry with this url
185  bool bFoundEntry = false;
186  for (auto const& entry : *entries)
187  {
188  if (url.equals(entry->GetCommand()))
189  {
190  bFoundEntry = true;
191  break;
192  }
193  }
194 
195  if (bFoundEntry)
196  {
197  // url already exists so try the next number up
198  return generateCustomURL(entries);
199  }
200 
201  return url;
202 }
203 
204 OUString SvxConfigPageHelper::GetModuleName(std::u16string_view aModuleId)
205 {
206  if (aModuleId == u"com.sun.star.text.TextDocument"
207  || aModuleId == u"com.sun.star.text.GlobalDocument")
208  return "Writer";
209  else if (aModuleId == u"com.sun.star.text.WebDocument")
210  return "Writer/Web";
211  else if (aModuleId == u"com.sun.star.drawing.DrawingDocument")
212  return "Draw";
213  else if (aModuleId == u"com.sun.star.presentation.PresentationDocument")
214  return "Impress";
215  else if (aModuleId == u"com.sun.star.sheet.SpreadsheetDocument")
216  return "Calc";
217  else if (aModuleId == u"com.sun.star.script.BasicIDE")
218  return "Basic";
219  else if (aModuleId == u"com.sun.star.formula.FormulaProperties")
220  return "Math";
221  else if (aModuleId == u"com.sun.star.sdb.RelationDesign")
222  return "Relation Design";
223  else if (aModuleId == u"com.sun.star.sdb.QueryDesign")
224  return "Query Design";
225  else if (aModuleId == u"com.sun.star.sdb.TableDesign")
226  return "Table Design";
227  else if (aModuleId == u"com.sun.star.sdb.DataSourceBrowser")
228  return "Data Source Browser";
229  else if (aModuleId == u"com.sun.star.sdb.DatabaseDocument")
230  return "Database";
231 
232  return OUString();
233 }
234 
236  const OUString& aModuleId,
237  const css::uno::Reference<css::frame::XModuleManager2>& rModuleManager)
238 {
239  assert(rModuleManager.is());
240 
241  OUString aModuleUIName;
242 
243  try
244  {
245  css::uno::Any a = rModuleManager->getByName(aModuleId);
246  css::uno::Sequence<css::beans::PropertyValue> aSeq;
247 
248  if (a >>= aSeq)
249  {
250  for (css::beans::PropertyValue const& rProp : std::as_const(aSeq))
251  {
252  if (rProp.Name == "ooSetupFactoryUIName")
253  {
254  rProp.Value >>= aModuleUIName;
255  break;
256  }
257  }
258  }
259  }
260  catch (css::uno::RuntimeException&)
261  {
262  throw;
263  }
264  catch (css::uno::Exception&)
265  {
266  }
267 
268  if (aModuleUIName.isEmpty())
269  aModuleUIName = GetModuleName(aModuleId);
270 
271  return aModuleUIName;
272 }
273 
275  const css::uno::Reference<css::container::XIndexAccess>& rItemContainer, sal_Int32 nIndex,
276  OUString& rCommandURL, OUString& rLabel, sal_uInt16& rType, sal_Int32& rStyle,
277  css::uno::Reference<css::container::XIndexAccess>& rSubMenu)
278 {
279  try
280  {
281  css::uno::Sequence<css::beans::PropertyValue> aProps;
282  if (rItemContainer->getByIndex(nIndex) >>= aProps)
283  {
284  for (css::beans::PropertyValue const& rProp : std::as_const(aProps))
285  {
286  if (rProp.Name == ITEM_DESCRIPTOR_COMMANDURL)
287  {
288  rProp.Value >>= rCommandURL;
289  }
290  else if (rProp.Name == ITEM_DESCRIPTOR_CONTAINER)
291  {
292  rProp.Value >>= rSubMenu;
293  }
294  else if (rProp.Name == ITEM_DESCRIPTOR_STYLE)
295  {
296  rProp.Value >>= rStyle;
297  }
298  else if (rProp.Name == ITEM_DESCRIPTOR_LABEL)
299  {
300  rProp.Value >>= rLabel;
301  }
302  else if (rProp.Name == ITEM_DESCRIPTOR_TYPE)
303  {
304  rProp.Value >>= rType;
305  }
306  }
307 
308  return true;
309  }
310  }
311  catch (css::lang::IndexOutOfBoundsException&)
312  {
313  }
314 
315  return false;
316 }
317 
319  const css::uno::Reference<css::container::XIndexAccess>& rItemContainer, sal_Int32 nIndex,
320  OUString& rCommandURL, OUString& rLabel, sal_uInt16& rType, bool& rIsVisible, sal_Int32& rStyle)
321 {
322  try
323  {
324  css::uno::Sequence<css::beans::PropertyValue> aProps;
325  if (rItemContainer->getByIndex(nIndex) >>= aProps)
326  {
327  for (css::beans::PropertyValue const& rProp : std::as_const(aProps))
328  {
329  if (rProp.Name == ITEM_DESCRIPTOR_COMMANDURL)
330  {
331  rProp.Value >>= rCommandURL;
332  }
333  else if (rProp.Name == ITEM_DESCRIPTOR_STYLE)
334  {
335  rProp.Value >>= rStyle;
336  }
337  else if (rProp.Name == ITEM_DESCRIPTOR_LABEL)
338  {
339  rProp.Value >>= rLabel;
340  }
341  else if (rProp.Name == ITEM_DESCRIPTOR_TYPE)
342  {
343  rProp.Value >>= rType;
344  }
345  else if (rProp.Name == ITEM_DESCRIPTOR_ISVISIBLE)
346  {
347  rProp.Value >>= rIsVisible;
348  }
349  }
350 
351  return true;
352  }
353  }
354  catch (css::lang::IndexOutOfBoundsException&)
355  {
356  }
357 
358  return false;
359 }
360 
361 css::uno::Sequence<css::beans::PropertyValue>
363 {
364  css::uno::Sequence<css::beans::PropertyValue> aPropSeq(4);
365 
366  aPropSeq[0].Name = ITEM_DESCRIPTOR_COMMANDURL;
367  aPropSeq[0].Value <<= pEntry->GetCommand();
368 
369  aPropSeq[1].Name = ITEM_DESCRIPTOR_TYPE;
370  aPropSeq[1].Value <<= css::ui::ItemType::DEFAULT;
371 
372  // If the name has not been changed, then the label can be stored
373  // as an empty string.
374  // It will be initialised again later using the command to label map.
375  aPropSeq[2].Name = ITEM_DESCRIPTOR_LABEL;
376  if (!pEntry->HasChangedName() && !pEntry->GetCommand().isEmpty())
377  {
378  aPropSeq[2].Value <<= OUString();
379  }
380  else
381  {
382  aPropSeq[2].Value <<= pEntry->GetName();
383  }
384 
385  aPropSeq[3].Name = ITEM_DESCRIPTOR_STYLE;
386  aPropSeq[3].Value <<= static_cast<sal_Int16>(pEntry->GetStyle());
387 
388  return aPropSeq;
389 }
390 
391 css::uno::Sequence<css::beans::PropertyValue>
393 {
394  css::uno::Sequence<css::beans::PropertyValue> aPropSeq(5);
395 
396  aPropSeq[0].Name = ITEM_DESCRIPTOR_COMMANDURL;
397  aPropSeq[0].Value <<= pEntry->GetCommand();
398 
399  aPropSeq[1].Name = ITEM_DESCRIPTOR_TYPE;
400  aPropSeq[1].Value <<= css::ui::ItemType::DEFAULT;
401 
402  // If the name has not been changed, then the label can be stored
403  // as an empty string.
404  // It will be initialised again later using the command to label map.
405  aPropSeq[2].Name = ITEM_DESCRIPTOR_LABEL;
406  if (!pEntry->HasChangedName() && !pEntry->GetCommand().isEmpty())
407  {
408  aPropSeq[2].Value <<= OUString();
409  }
410  else
411  {
412  aPropSeq[2].Value <<= pEntry->GetName();
413  }
414 
415  aPropSeq[3].Name = ITEM_DESCRIPTOR_ISVISIBLE;
416  aPropSeq[3].Value <<= pEntry->IsVisible();
417 
418  aPropSeq[4].Name = ITEM_DESCRIPTOR_STYLE;
419  aPropSeq[4].Value <<= static_cast<sal_Int16>(pEntry->GetStyle());
420 
421  return aPropSeq;
422 }
423 
425 {
426  return a->GetName().compareTo(b->GetName()) < 0;
427 }
428 
430 {
431  SvxEntries* pEntries = pEntry->GetEntries();
432  if (!pEntries)
433  return false;
434 
435  for (const auto& entry : *pEntries)
436  {
437  if (entry->IsModified() || SvxConfigEntryModified(entry))
438  return true;
439  }
440  return false;
441 }
442 
443 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
static OUString replaceSixteen(const OUString &str, sal_Int32 nReplacement)
SvxEntries * GetEntries() const
Definition: cfg.hxx:289
const char ITEM_DESCRIPTOR_TYPE[]
Definition: cfg.hxx:47
const OUString & GetName() const
Definition: cfg.hxx:277
static OUString generateCustomURL(SvxEntries *entries)
Generates a custom resource URL for a new toolbar.
bool IsVisible() const
Definition: cfg.hxx:306
static OUString stripHotKey(const OUString &str)
static sal_Int16 GetImageType()
static OUString GetUIModuleName(const OUString &aModuleId, const css::uno::Reference< css::frame::XModuleManager2 > &rModuleManager)
const char ITEM_DESCRIPTOR_ISVISIBLE[]
Definition: cfg.hxx:49
const char CUSTOM_TOOLBAR_STR[]
Definition: cfg.hxx:56
static css::uno::Reference< css::graphic::XGraphic > GetGraphic(const css::uno::Reference< css::ui::XImageManager > &xImageManager, const OUString &rCommandURL)
unsigned int uniform_uint_distribution(unsigned int a, unsigned int b)
std::vector< SvxConfigEntry * > SvxEntries
Definition: cfg.hxx:61
const OUString & GetCommand() const
Definition: cfg.hxx:275
static bool SvxConfigEntryModified(SvxConfigEntry const *pEntry)
const BorderLinePrimitive2D *pCandidateB assert(pCandidateA)
size_t pos
static void RemoveEntry(SvxEntries *pEntries, SvxConfigEntry const *pChildEntry)
static OUString generateCustomMenuURL(SvxEntries *entries, sal_Int32 suffix=1)
static OUString replaceSaveInName(const OUString &rMessage, std::u16string_view rSaveInName)
static OUString generateCustomName(const OUString &prefix, SvxEntries *entries, sal_Int32 suffix=1)
static bool EntrySort(SvxConfigEntry const *a, SvxConfigEntry const *b)
uno_Any a
const char ITEM_DESCRIPTOR_STYLE[]
Definition: cfg.hxx:48
const char ITEM_DESCRIPTOR_LABEL[]
Definition: cfg.hxx:46
static css::uno::Sequence< css::beans::PropertyValue > ConvertToolbarEntry(const SvxConfigEntry *pEntry)
static css::uno::Sequence< css::beans::PropertyValue > ConvertSvxConfigEntry(const SvxConfigEntry *pEntry)
float u
static sal_uInt32 generateRandomValue()
sal_Int32 GetStyle() const
Definition: cfg.hxx:314
const char ITEM_DESCRIPTOR_CONTAINER[]
Definition: cfg.hxx:45
static OUString GetModuleName(std::u16string_view aModuleId)
SFX_SYMBOLS_SIZE_32
constexpr char16_t ITEM_TOOLBAR_URL[]
Definition: cfg.hxx:54
const char * name
Sequence< sal_Int8 > aSeq
const char ITEM_DESCRIPTOR_COMMANDURL[]
Definition: cfg.hxx:44
SFX_SYMBOLS_SIZE_LARGE
static bool GetToolbarItemData(const css::uno::Reference< css::container::XIndexAccess > &rItemContainer, sal_Int32 nIndex, OUString &rCommandURL, OUString &rLabel, sal_uInt16 &rType, bool &rIsVisible, sal_Int32 &rStyle)
Any result
static bool GetMenuItemData(const css::uno::Reference< css::container::XIndexAccess > &rItemContainer, sal_Int32 nIndex, OUString &rCommandURL, OUString &rLabel, sal_uInt16 &rType, sal_Int32 &rStyle, css::uno::Reference< css::container::XIndexAccess > &rSubMenu)
static sal_Int16 theImageType
bool HasChangedName() const
Definition: cfg.hxx:279