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
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
31static sal_Int16 theImageType = css::ui::ImageType::COLOR_NORMAL | css::ui::ImageType::SIZE_DEFAULT;
32
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
48OUString 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
56OUString SvxConfigPageHelper::stripHotKey(const OUString& str) { return str.replaceFirst("~", ""); }
57
58OUString 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
79css::uno::Reference<css::graphic::XGraphic>
80SvxConfigPageHelper::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
110OUString 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
148OUString 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
205OUString 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
362css::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
383css::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 sal_Int16 theImageType
constexpr OUStringLiteral ITEM_DESCRIPTOR_ISVISIBLE
Definition: cfg.hxx:50
constexpr OUStringLiteral CUSTOM_TOOLBAR_STR
Definition: cfg.hxx:57
constexpr OUStringLiteral ITEM_TOOLBAR_URL
Definition: cfg.hxx:55
constexpr OUStringLiteral ITEM_DESCRIPTOR_STYLE
Definition: cfg.hxx:49
constexpr OUStringLiteral ITEM_DESCRIPTOR_COMMANDURL
Definition: cfg.hxx:45
constexpr OUStringLiteral ITEM_DESCRIPTOR_TYPE
Definition: cfg.hxx:48
std::vector< SvxConfigEntry * > SvxEntries
Definition: cfg.hxx:62
constexpr OUStringLiteral ITEM_DESCRIPTOR_LABEL
Definition: cfg.hxx:47
constexpr OUStringLiteral ITEM_DESCRIPTOR_CONTAINER
Definition: cfg.hxx:46
sal_Int32 GetStyle() const
Definition: cfg.hxx:315
const OUString & GetCommand() const
Definition: cfg.hxx:276
SvxEntries * GetEntries() const
Definition: cfg.hxx:290
bool IsVisible() const
Definition: cfg.hxx:307
const OUString & GetName() const
Definition: cfg.hxx:278
bool HasChangedName() const
Definition: cfg.hxx:280
static sal_uInt32 generateRandomValue()
static sal_Int16 GetImageType()
static OUString GetModuleName(std::u16string_view aModuleId)
static OUString generateCustomURL(SvxEntries *entries)
Generates a custom resource URL for a new toolbar.
static OUString generateCustomMenuURL(SvxEntries *entries, sal_Int32 suffix=1)
static OUString replaceSaveInName(const OUString &rMessage, std::u16string_view rSaveInName)
static OUString GetUIModuleName(const OUString &aModuleId, const css::uno::Reference< css::frame::XModuleManager2 > &rModuleManager)
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 css::uno::Sequence< css::beans::PropertyValue > ConvertSvxConfigEntry(const SvxConfigEntry *pEntry)
static OUString stripHotKey(const OUString &str)
static OUString generateCustomName(const OUString &prefix, SvxEntries *entries, sal_Int32 suffix=1)
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)
static void RemoveEntry(SvxEntries *pEntries, SvxConfigEntry const *pChildEntry)
static bool SvxConfigEntryModified(SvxConfigEntry const *pEntry)
static css::uno::Reference< css::graphic::XGraphic > GetGraphic(const css::uno::Reference< css::ui::XImageManager > &xImageManager, const OUString &rCommandURL)
static OUString replaceSixteen(const OUString &str, sal_Int32 nReplacement)
static css::uno::Sequence< css::beans::PropertyValue > ConvertToolbarEntry(const SvxConfigEntry *pEntry)
static bool EntrySort(SvxConfigEntry const *a, SvxConfigEntry const *b)
float u
const char * name
SFX_SYMBOLS_SIZE_32
SFX_SYMBOLS_SIZE_LARGE
sal_Int32 nIndex
uno_Any a
Sequence< sal_Int8 > aSeq
unsigned int uniform_uint_distribution(unsigned int a, unsigned int b)
css::beans::PropertyValue makePropertyValue(const OUString &rName, T &&rValue)
Any result
size_t pos