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