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