1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <com/sun/star/beans/PropertyValue.hpp>
21 #include <framework/addonsoptions.hxx>
22 #include <o3tl/safeint.hxx>
23 #include <unotools/configmgr.hxx>
24 #include <unotools/configitem.hxx>
25 #include <unotools/ucbstreamhelper.hxx>
26 #include <tools/stream.hxx>
27 #include <com/sun/star/uno/Any.hxx>
28 #include <com/sun/star/uno/Sequence.hxx>
29 #include <rtl/ustrbuf.hxx>
30 #include <sal/log.hxx>
31 #include <comphelper/getexpandeduri.hxx>
32 #include <comphelper/processfactory.hxx>
33 #include <vcl/dibtools.hxx>
34 #include <vcl/graph.hxx>
35 #include <vcl/graphicfilter.hxx>
36 #include <vcl/toolbox.hxx>
37 #include <vcl/svapp.hxx>
40 #include <string_view>
41 #include <unordered_map>
46 using namespace ::utl
;
47 using namespace ::osl
;
48 using namespace ::com::sun::star::uno
;
49 using namespace ::com::sun::star::beans
;
50 using namespace ::com::sun::star::lang
;
51 using namespace ::com::sun::star
;
53 constexpr OUStringLiteral ROOTNODE_ADDONMENU
= u
"Office.Addons";
54 constexpr OUStringLiteral PATHDELIMITER
= u
"/";
55 constexpr OUString SEPARATOR_URL
= u
"private:separator"_ustr
;
57 #define PROPERTYNAME_URL ADDONSMENUITEM_STRING_URL
58 #define PROPERTYNAME_TITLE ADDONSMENUITEM_STRING_TITLE
59 #define PROPERTYNAME_TARGET ADDONSMENUITEM_STRING_TARGET
60 #define PROPERTYNAME_IMAGEIDENTIFIER ADDONSMENUITEM_STRING_IMAGEIDENTIFIER
61 #define PROPERTYNAME_CONTEXT ADDONSMENUITEM_STRING_CONTEXT
62 #define PROPERTYNAME_SUBMENU ADDONSMENUITEM_STRING_SUBMENU
64 constexpr OUStringLiteral IMAGES_NODENAME
= u
"UserDefinedImages";
66 // The following order is mandatory. Please add properties at the end!
69 #define INDEX_IMAGEIDENTIFIER 2
70 #define INDEX_TARGET 3
71 #define INDEX_CONTEXT 4
72 #define INDEX_SUBMENU 5
73 #define INDEX_CONTROLTYPE 6
76 #define INDEX_AUTOSIZE 9
77 #define INDEX_OWNERDRAW 10
78 #define INDEX_MANDATORY 11
79 #define INDEX_STYLE 12
80 #define PROPERTYCOUNT_INDEX 13
82 // The following order is mandatory. Please add properties at the end!
83 #define PROPERTYCOUNT_MENUITEM 6
84 #define OFFSET_MENUITEM_URL 0
85 #define OFFSET_MENUITEM_TITLE 1
86 #define OFFSET_MENUITEM_IMAGEIDENTIFIER 2
87 #define OFFSET_MENUITEM_TARGET 3
88 #define OFFSET_MENUITEM_CONTEXT 4
89 #define OFFSET_MENUITEM_SUBMENU 5
91 // The following order is mandatory. Please add properties at the end!
92 #define PROPERTYCOUNT_POPUPMENU 4
93 #define OFFSET_POPUPMENU_TITLE 0
94 #define OFFSET_POPUPMENU_CONTEXT 1
95 #define OFFSET_POPUPMENU_SUBMENU 2
96 #define OFFSET_POPUPMENU_URL 3 // Used for property set
98 // The following order is mandatory. Please add properties at the end!
99 #define PROPERTYCOUNT_TOOLBARITEM 7
100 #define OFFSET_TOOLBARITEM_URL 0
101 #define OFFSET_TOOLBARITEM_TITLE 1
102 #define OFFSET_TOOLBARITEM_IMAGEIDENTIFIER 2
103 #define OFFSET_TOOLBARITEM_TARGET 3
104 #define OFFSET_TOOLBARITEM_CONTEXT 4
105 #define OFFSET_TOOLBARITEM_CONTROLTYPE 5
106 #define OFFSET_TOOLBARITEM_WIDTH 6
108 // The following order is mandatory. Please add properties at the end!
109 #define PROPERTYCOUNT_NOTEBOOKBARITEM 8
110 #define OFFSET_NOTEBOOKBARITEM_URL 0
111 #define OFFSET_NOTEBOOKBARITEM_TITLE 1
112 #define OFFSET_NOTEBOOKBARITEM_IMAGEIDENTIFIER 2
113 #define OFFSET_NOTEBOOKBARITEM_TARGET 3
114 #define OFFSET_NOTEBOOKBARITEM_CONTEXT 4
115 #define OFFSET_NOTEBOOKBARITEM_CONTROLTYPE 5
116 #define OFFSET_NOTEBOOKBARITEM_WIDTH 6
117 #define OFFSET_NOTEBOOKBARITEM_STYLE 7
119 // The following order is mandatory. Please add properties at the end!
120 #define PROPERTYCOUNT_STATUSBARITEM 8
121 #define OFFSET_STATUSBARITEM_URL 0
122 #define OFFSET_STATUSBARITEM_TITLE 1
123 #define OFFSET_STATUSBARITEM_CONTEXT 2
124 #define OFFSET_STATUSBARITEM_ALIGN 3
125 #define OFFSET_STATUSBARITEM_AUTOSIZE 4
126 #define OFFSET_STATUSBARITEM_OWNERDRAW 5
127 #define OFFSET_STATUSBARITEM_MANDATORY 6
128 #define OFFSET_STATUSBARITEM_WIDTH 7
130 // The following order is mandatory. Please add properties at the end!
131 #define PROPERTYCOUNT_IMAGES 8
132 #define PROPERTYCOUNT_EMBEDDED_IMAGES 2
133 #define OFFSET_IMAGES_SMALL 0
134 #define OFFSET_IMAGES_BIG 1
135 #define OFFSET_IMAGES_SMALLHC 2
136 #define OFFSET_IMAGES_BIGHC 3
137 #define OFFSET_IMAGES_SMALL_URL 4
138 #define OFFSET_IMAGES_BIG_URL 5
139 #define OFFSET_IMAGES_SMALLHC_URL 6
140 #define OFFSET_IMAGES_BIGHC_URL 7
142 #define PROPERTYCOUNT_MERGE_MENUBAR 6
143 #define OFFSET_MERGEMENU_MERGEPOINT 0
144 #define OFFSET_MERGEMENU_MERGECOMMAND 1
145 #define OFFSET_MERGEMENU_MERGECOMMANDPARAMETER 2
146 #define OFFSET_MERGEMENU_MERGEFALLBACK 3
147 #define OFFSET_MERGEMENU_MERGECONTEXT 4
148 #define OFFSET_MERGEMENU_MENUITEMS 5
150 #define PROPERTYCOUNT_MERGE_TOOLBAR 7
151 #define OFFSET_MERGETOOLBAR_TOOLBAR 0
152 #define OFFSET_MERGETOOLBAR_MERGEPOINT 1
153 #define OFFSET_MERGETOOLBAR_MERGECOMMAND 2
154 #define OFFSET_MERGETOOLBAR_MERGECOMMANDPARAMETER 3
155 #define OFFSET_MERGETOOLBAR_MERGEFALLBACK 4
156 #define OFFSET_MERGETOOLBAR_MERGECONTEXT 5
157 #define OFFSET_MERGETOOLBAR_TOOLBARITEMS 6
159 #define PROPERTYCOUNT_MERGE_NOTEBOOKBAR 7
160 #define OFFSET_MERGENOTEBOOKBAR_NOTEBOOKBAR 0
161 #define OFFSET_MERGENOTEBOOKBAR_MERGEPOINT 1
162 #define OFFSET_MERGENOTEBOOKBAR_MERGECOMMAND 2
163 #define OFFSET_MERGENOTEBOOKBAR_MERGECOMMANDPARAMETER 3
164 #define OFFSET_MERGENOTEBOOKBAR_MERGEFALLBACK 4
165 #define OFFSET_MERGENOTEBOOKBAR_MERGECONTEXT 5
166 #define OFFSET_MERGENOTEBOOKBAR_NOTEBOOKBARITEMS 6
168 #define PROPERTYCOUNT_MERGE_STATUSBAR 6
169 #define OFFSET_MERGESTATUSBAR_MERGEPOINT 0
170 #define OFFSET_MERGESTATUSBAR_MERGECOMMAND 1
171 #define OFFSET_MERGESTATUSBAR_MERGECOMMANDPARAMETER 2
172 #define OFFSET_MERGESTATUSBAR_MERGEFALLBACK 3
173 #define OFFSET_MERGESTATUSBAR_MERGECONTEXT 4
174 #define OFFSET_MERGESTATUSBAR_STATUSBARITEMS 5
176 // private declarations!
178 /*-****************************************************************************************************************
179 @descr struct to hold information about one menu entry.
180 ****************************************************************************************************************-*/
185 class AddonsOptions_Impl
: public ConfigItem
192 // constructor / destructor
194 AddonsOptions_Impl();
195 virtual ~AddonsOptions_Impl() override
;
197 // overridden methods of baseclass
199 /*-****************************************************************************************************
200 @short called for notify of configmanager
201 @descr This method is called from the ConfigManager before application ends or from the
202 PropertyChangeListener if the sub tree broadcasts changes. You must update your
205 @seealso baseclass ConfigItem
207 @param "lPropertyNames" is the list of properties which should be updated.
208 *//*-*****************************************************************************************************/
210 virtual void Notify( const Sequence
< OUString
>& lPropertyNames
) override
;
214 /*-****************************************************************************************************
215 @short base implementation of public interface for "SvtDynamicMenuOptions"!
216 @descr These class is used as static member of "SvtDynamicMenuOptions" ...
217 => The code exist only for one time and isn't duplicated for every instance!
218 *//*-*****************************************************************************************************/
220 bool HasAddonsMenu () const;
221 sal_Int32
GetAddonsToolBarCount() const;
222 sal_Int32
GetAddonsNotebookBarCount() const;
223 const Sequence
< Sequence
< PropertyValue
> >& GetAddonsMenu () const { return m_aCachedMenuProperties
;}
224 const Sequence
< Sequence
< PropertyValue
> >& GetAddonsMenuBarPart () const { return m_aCachedMenuBarPartProperties
;}
225 const Sequence
< Sequence
< PropertyValue
> >& GetAddonsToolBarPart ( sal_uInt32 nIndex
) const;
226 const Sequence
< Sequence
< PropertyValue
> >& GetAddonsNotebookBarPart ( sal_uInt32 nIndex
) const;
227 OUString
GetAddonsToolbarResourceName( sal_uInt32 nIndex
) const;
228 OUString
GetAddonsNotebookBarResourceName( sal_uInt32 nIndex
) const;
229 const Sequence
< Sequence
< PropertyValue
> >& GetAddonsHelpMenu () const { return m_aCachedHelpMenuProperties
;}
230 BitmapEx
GetImageFromURL( const OUString
& aURL
, bool bBig
, bool bNoScale
);
231 const MergeMenuInstructionContainer
& GetMergeMenuInstructions() const { return m_aCachedMergeMenuInsContainer
;}
232 bool GetMergeToolbarInstructions( const OUString
& rToolbarName
, MergeToolbarInstructionContainer
& rToolbarInstructions
) const;
233 bool GetMergeNotebookBarInstructions( const OUString
& rNotebookBarName
, MergeNotebookBarInstructionContainer
& rNotebookBarInstructions
) const;
234 const MergeStatusbarInstructionContainer
& GetMergeStatusbarInstructions() const { return m_aCachedStatusbarMergingInstructions
;}
235 void ReadConfigurationData();
246 BitmapEx aScaled
; ///< cached scaled image
247 BitmapEx aImage
; ///< original un-scaled image
248 OUString aURL
; ///< URL in case it is not loaded yet
253 // if the image is set, it was embedded in some way,
254 // otherwise we use the associated URL to load on demand
256 // accessed in this order
257 OneImageEntry aSizeEntry
[2];
259 void addImage(ImageSize eSize
, const BitmapEx
&rImage
);
260 void addImage(ImageSize eSize
, const OUString
&rURL
);
263 typedef std::unordered_map
< OUString
, ImageEntry
> ImageManager
;
264 typedef std::unordered_map
< OUString
, sal_uInt32
> StringToIndexMap
;
265 typedef std::vector
< Sequence
< Sequence
< PropertyValue
> > > AddonToolBars
;
266 typedef std::vector
< Sequence
< Sequence
< PropertyValue
> > > AddonNotebookBars
;
267 typedef std::unordered_map
< OUString
, MergeToolbarInstructionContainer
> ToolbarMergingInstructions
;
268 typedef std::unordered_map
< OUString
, MergeNotebookBarInstructionContainer
> NotebookBarMergingInstructions
;
270 /*-****************************************************************************************************
271 @short return list of key names of our configuration management which represent our module tree
272 @descr These methods return the current list of key names! We need it to get needed values from our
273 configuration management!
274 @param "nCount" , returns count of menu entries for "new"
275 @return A list of configuration key names is returned.
276 *//*-*****************************************************************************************************/
278 void ReadAddonMenuSet( Sequence
< Sequence
< PropertyValue
> >& aAddonMenuSeq
);
279 void ReadOfficeMenuBarSet( Sequence
< Sequence
< PropertyValue
> >& aAddonOfficeMenuBarSeq
);
280 void ReadOfficeToolBarSet( AddonToolBars
& rAddonOfficeToolBars
, std::vector
< OUString
>& rAddonOfficeToolBarResNames
);
281 bool ReadToolBarItemSet( const OUString
& rToolBarItemSetNodeName
, Sequence
< Sequence
< PropertyValue
> >& aAddonOfficeToolBarSeq
);
282 void ReadOfficeNotebookBarSet( AddonNotebookBars
& rAddonOfficeNotebookBars
, std::vector
< OUString
>& rAddonOfficeNotebookBarResNames
);
283 bool ReadNotebookBarItemSet( const OUString
& rNotebookBarItemSetNodeName
, Sequence
< Sequence
< PropertyValue
> >& aAddonOfficeNotebookBarSeq
);
285 void ReadOfficeHelpSet( Sequence
< Sequence
< PropertyValue
> >& aAddonOfficeHelpMenuSeq
);
286 void ReadImages( ImageManager
& aImageManager
);
287 void ReadMenuMergeInstructions( MergeMenuInstructionContainer
& rContainer
);
288 void ReadToolbarMergeInstructions( ToolbarMergingInstructions
& rToolbarMergeMap
);
289 void ReadNotebookBarMergeInstructions( NotebookBarMergingInstructions
& rNotebookBarMergeMap
);
290 void ReadStatusbarMergeInstructions( MergeStatusbarInstructionContainer
& rContainer
);
292 void ReadMergeMenuData( std::u16string_view aMergeAddonInstructionBase
, Sequence
< Sequence
< PropertyValue
> >& rMergeMenu
);
293 void ReadMergeToolbarData( std::u16string_view aMergeAddonInstructionBase
, Sequence
< Sequence
< PropertyValue
> >& rMergeToolbarItems
);
294 void ReadMergeNotebookBarData( std::u16string_view aMergeAddonInstructionBase
, Sequence
< Sequence
< PropertyValue
> >& rMergeNotebookBarItems
);
295 void ReadMergeStatusbarData( std::u16string_view aMergeAddonInstructionBase
, Sequence
< Sequence
< PropertyValue
> >& rMergeStatusbar
);
296 bool ReadMenuItem( std::u16string_view aMenuItemNodeName
, Sequence
< PropertyValue
>& aMenuItem
, bool bIgnoreSubMenu
= false );
297 bool ReadPopupMenu( std::u16string_view aPopupMenuNodeName
, Sequence
< PropertyValue
>& aPopupMenu
);
298 void AppendPopupMenu( Sequence
< PropertyValue
>& aTargetPopupMenu
, const Sequence
< PropertyValue
>& rSourcePopupMenu
);
299 bool ReadToolBarItem( std::u16string_view aToolBarItemNodeName
, Sequence
< PropertyValue
>& aToolBarItem
);
300 bool ReadNotebookBarItem( std::u16string_view aNotebookBarItemNodeName
, Sequence
< PropertyValue
>& aNotebookBarItem
);
302 bool ReadStatusBarItem( std::u16string_view aStatusbarItemNodeName
, Sequence
< PropertyValue
>& aStatusbarItem
);
303 std::unique_ptr
<ImageEntry
> ReadImageData( std::u16string_view aImagesNodeName
);
304 void ReadAndAssociateImages( const OUString
& aURL
, const OUString
& aImageId
);
305 BitmapEx
ReadImageFromURL( const OUString
& aURL
);
306 bool HasAssociatedImages( const OUString
& aURL
);
307 void SubstituteVariables( OUString
& aURL
);
309 void ReadSubMenuEntries( const Sequence
< OUString
>& aSubMenuNodeNames
, Sequence
< Sequence
< PropertyValue
> >& rSubMenu
);
310 OUString
GeneratePrefixURL();
312 Sequence
< OUString
> GetPropertyNamesMenuItem( std::u16string_view aPropertyRootNode
)
314 Sequence
< OUString
> GetPropertyNamesPopupMenu( std::u16string_view aPropertyRootNode
)
316 Sequence
< OUString
> GetPropertyNamesToolBarItem( std::u16string_view aPropertyRootNode
)
318 Sequence
< OUString
> GetPropertyNamesNotebookBarItem( std::u16string_view aPropertyRootNode
) const;
320 Sequence
< OUString
> GetPropertyNamesStatusbarItem( std::u16string_view aPropertyRootNode
) const;
321 Sequence
< OUString
> GetPropertyNamesImages( std::u16string_view aPropertyRootNode
) const;
322 bool CreateImageFromSequence( BitmapEx
& rImage
, Sequence
< sal_Int8
>& rBitmapDataSeq
) const;
324 DECL_LINK(NotifyEvent
, void*, void);
326 virtual void ImplCommit() override
;
331 sal_Int32 m_nRootAddonPopupMenuId
;
332 OUString m_aPropNames
[PROPERTYCOUNT_INDEX
];
333 OUString m_aPropImagesNames
[PROPERTYCOUNT_IMAGES
];
334 OUString m_aPropMergeMenuNames
[PROPERTYCOUNT_MERGE_MENUBAR
];
335 OUString m_aPropMergeToolbarNames
[PROPERTYCOUNT_MERGE_TOOLBAR
];
336 OUString m_aPropMergeNotebookBarNames
[PROPERTYCOUNT_MERGE_NOTEBOOKBAR
];
337 OUString m_aPropMergeStatusbarNames
[PROPERTYCOUNT_MERGE_STATUSBAR
];
338 OUString m_aPathDelimiter
;
339 OUString m_aRootAddonPopupMenuURLPrexfix
;
340 Sequence
< Sequence
< PropertyValue
> > m_aCachedMenuProperties
;
341 Sequence
< Sequence
< PropertyValue
> > m_aCachedMenuBarPartProperties
;
342 AddonToolBars m_aCachedToolBarPartProperties
;
343 AddonNotebookBars m_aCachedNotebookBarPartProperties
;
344 std::vector
< OUString
> m_aCachedToolBarPartResourceNames
;
345 std::vector
< OUString
> m_aCachedNotebookBarPartResourceNames
;
346 Sequence
< Sequence
< PropertyValue
> > m_aCachedHelpMenuProperties
;
347 ImageManager m_aImageManager
;
348 Sequence
< Sequence
< PropertyValue
> > m_aEmptyAddonToolBar
;
349 Sequence
< Sequence
< PropertyValue
> > m_aEmptyAddonNotebookBar
;
350 MergeMenuInstructionContainer m_aCachedMergeMenuInsContainer
;
351 ToolbarMergingInstructions m_aCachedToolbarMergingInstructions
;
352 NotebookBarMergingInstructions m_aCachedNotebookBarMergingInstructions
;
353 MergeStatusbarInstructionContainer m_aCachedStatusbarMergingInstructions
;
356 void AddonsOptions_Impl::ImageEntry::addImage(ImageSize eSize
, const BitmapEx
& rImage
)
358 aSizeEntry
[static_cast<int>(eSize
)].aImage
= rImage
;
361 void AddonsOptions_Impl::ImageEntry::addImage(ImageSize eSize
, const OUString
&rURL
)
363 aSizeEntry
[static_cast<int>(eSize
)].aURL
= rURL
;
368 AddonsOptions_Impl::AddonsOptions_Impl()
369 // Init baseclasses first
370 : ConfigItem( ROOTNODE_ADDONMENU
),
371 m_nRootAddonPopupMenuId( 0 ),
372 m_aPathDelimiter( PATHDELIMITER
),
373 m_aRootAddonPopupMenuURLPrexfix( ADDONSPOPUPMENU_URL_PREFIX_STR
)
375 // initialize array with fixed property names
376 m_aPropNames
[ INDEX_URL
] = PROPERTYNAME_URL
;
377 m_aPropNames
[ INDEX_TITLE
] = PROPERTYNAME_TITLE
;
378 m_aPropNames
[ INDEX_TARGET
] = PROPERTYNAME_TARGET
;
379 m_aPropNames
[ INDEX_IMAGEIDENTIFIER
] = PROPERTYNAME_IMAGEIDENTIFIER
;
380 m_aPropNames
[ INDEX_CONTEXT
] = PROPERTYNAME_CONTEXT
;
381 m_aPropNames
[ INDEX_SUBMENU
] = PROPERTYNAME_SUBMENU
; // Submenu set!
382 m_aPropNames
[ INDEX_CONTROLTYPE
] = "ControlType";
383 m_aPropNames
[ INDEX_WIDTH
] = "Width";
384 m_aPropNames
[ INDEX_ALIGN
] = "Alignment";
385 m_aPropNames
[ INDEX_AUTOSIZE
] = "AutoSize";
386 m_aPropNames
[ INDEX_OWNERDRAW
] = "OwnerDraw";
387 m_aPropNames
[ INDEX_MANDATORY
] = "Mandatory";
388 m_aPropNames
[ INDEX_STYLE
] = "Style";
390 // initialize array with fixed images property names
391 m_aPropImagesNames
[ OFFSET_IMAGES_SMALL
] = "ImageSmall";
392 m_aPropImagesNames
[ OFFSET_IMAGES_BIG
] = "ImageBig";
393 m_aPropImagesNames
[ OFFSET_IMAGES_SMALLHC
] = "ImageSmallHC";
394 m_aPropImagesNames
[ OFFSET_IMAGES_BIGHC
] = "ImageBigHC";
395 m_aPropImagesNames
[ OFFSET_IMAGES_SMALL_URL
] = "ImageSmallURL";
396 m_aPropImagesNames
[ OFFSET_IMAGES_BIG_URL
] = "ImageBigURL";
397 m_aPropImagesNames
[ OFFSET_IMAGES_SMALLHC_URL
] = "ImageSmallHCURL";
398 m_aPropImagesNames
[ OFFSET_IMAGES_BIGHC_URL
] = "ImageBigHCURL";
400 // initialize array with fixed merge menu property names
401 m_aPropMergeMenuNames
[ OFFSET_MERGEMENU_MERGEPOINT
] = "MergePoint";
402 m_aPropMergeMenuNames
[ OFFSET_MERGEMENU_MERGECOMMAND
] = "MergeCommand";
403 m_aPropMergeMenuNames
[ OFFSET_MERGEMENU_MERGECOMMANDPARAMETER
] = "MergeCommandParameter";
404 m_aPropMergeMenuNames
[ OFFSET_MERGEMENU_MERGEFALLBACK
] = "MergeFallback";
405 m_aPropMergeMenuNames
[ OFFSET_MERGEMENU_MERGECONTEXT
] = "MergeContext";
406 m_aPropMergeMenuNames
[ OFFSET_MERGEMENU_MENUITEMS
] = "MenuItems";
408 m_aPropMergeToolbarNames
[ OFFSET_MERGETOOLBAR_TOOLBAR
] = "MergeToolBar";
409 m_aPropMergeToolbarNames
[ OFFSET_MERGETOOLBAR_MERGEPOINT
] = "MergePoint";
410 m_aPropMergeToolbarNames
[ OFFSET_MERGETOOLBAR_MERGECOMMAND
] = "MergeCommand";
411 m_aPropMergeToolbarNames
[ OFFSET_MERGETOOLBAR_MERGECOMMANDPARAMETER
] = "MergeCommandParameter";
412 m_aPropMergeToolbarNames
[ OFFSET_MERGETOOLBAR_MERGEFALLBACK
] = "MergeFallback";
413 m_aPropMergeToolbarNames
[ OFFSET_MERGETOOLBAR_MERGECONTEXT
] = "MergeContext";
414 m_aPropMergeToolbarNames
[ OFFSET_MERGETOOLBAR_TOOLBARITEMS
] = "ToolBarItems";
416 m_aPropMergeNotebookBarNames
[ OFFSET_MERGENOTEBOOKBAR_NOTEBOOKBAR
] = "MergeNotebookBar";
417 m_aPropMergeNotebookBarNames
[ OFFSET_MERGENOTEBOOKBAR_MERGEPOINT
] = "MergePoint";
418 m_aPropMergeNotebookBarNames
[ OFFSET_MERGENOTEBOOKBAR_MERGECOMMAND
] = "MergeCommand";
419 m_aPropMergeNotebookBarNames
[ OFFSET_MERGENOTEBOOKBAR_MERGECOMMANDPARAMETER
] = "MergeCommandParameter";
420 m_aPropMergeNotebookBarNames
[ OFFSET_MERGENOTEBOOKBAR_MERGEFALLBACK
] = "MergeFallback";
421 m_aPropMergeNotebookBarNames
[ OFFSET_MERGENOTEBOOKBAR_MERGECONTEXT
] = "MergeContext";
422 m_aPropMergeNotebookBarNames
[ OFFSET_MERGENOTEBOOKBAR_NOTEBOOKBARITEMS
] = "NotebookBarItems";
424 m_aPropMergeStatusbarNames
[ OFFSET_MERGESTATUSBAR_MERGEPOINT
] = "MergePoint";
425 m_aPropMergeStatusbarNames
[ OFFSET_MERGESTATUSBAR_MERGECOMMAND
] = "MergeCommand";
426 m_aPropMergeStatusbarNames
[ OFFSET_MERGESTATUSBAR_MERGECOMMANDPARAMETER
] = "MergeCommandParameter";
427 m_aPropMergeStatusbarNames
[ OFFSET_MERGESTATUSBAR_MERGEFALLBACK
] = "MergeFallback";
428 m_aPropMergeStatusbarNames
[ OFFSET_MERGESTATUSBAR_MERGECONTEXT
] = "MergeContext";
429 m_aPropMergeStatusbarNames
[ OFFSET_MERGESTATUSBAR_STATUSBARITEMS
] = "StatusBarItems";
431 ReadConfigurationData();
433 // Enable notification mechanism of our baseclass.
434 // We need it to get information about changes outside these class on our used configuration keys!
435 Sequence
<OUString
> aNotifySeq
{ "AddonUI" };
436 EnableNotification( aNotifySeq
);
441 AddonsOptions_Impl::~AddonsOptions_Impl()
443 assert(!IsModified()); // should have been committed
446 void AddonsOptions_Impl::ReadConfigurationData()
448 // reset members to be read again from configuration
449 m_aCachedMenuProperties
= Sequence
< Sequence
< PropertyValue
> >();
450 m_aCachedMenuBarPartProperties
= Sequence
< Sequence
< PropertyValue
> >();
451 m_aCachedToolBarPartProperties
= AddonToolBars();
452 m_aCachedNotebookBarPartProperties
= AddonNotebookBars();
453 m_aCachedHelpMenuProperties
= Sequence
< Sequence
< PropertyValue
> >();
454 m_aCachedToolBarPartResourceNames
.clear();
455 m_aCachedNotebookBarPartResourceNames
.clear();
456 m_aImageManager
= ImageManager();
458 ReadAddonMenuSet( m_aCachedMenuProperties
);
459 ReadOfficeMenuBarSet( m_aCachedMenuBarPartProperties
);
460 ReadOfficeToolBarSet( m_aCachedToolBarPartProperties
, m_aCachedToolBarPartResourceNames
);
461 ReadOfficeNotebookBarSet( m_aCachedNotebookBarPartProperties
, m_aCachedNotebookBarPartResourceNames
);
463 ReadOfficeHelpSet( m_aCachedHelpMenuProperties
);
464 ReadImages( m_aImageManager
);
466 m_aCachedMergeMenuInsContainer
.clear();
467 m_aCachedToolbarMergingInstructions
.clear();
468 m_aCachedNotebookBarMergingInstructions
.clear();
469 m_aCachedStatusbarMergingInstructions
.clear();
471 ReadMenuMergeInstructions( m_aCachedMergeMenuInsContainer
);
472 ReadToolbarMergeInstructions( m_aCachedToolbarMergingInstructions
);
473 ReadNotebookBarMergeInstructions( m_aCachedNotebookBarMergingInstructions
);
474 ReadStatusbarMergeInstructions( m_aCachedStatusbarMergingInstructions
);
479 void AddonsOptions_Impl::Notify( const Sequence
< OUString
>& /*lPropertyNames*/ )
481 Application::PostUserEvent(LINK(this, AddonsOptions_Impl
, NotifyEvent
));
486 void AddonsOptions_Impl::ImplCommit()
488 SAL_WARN("fwk", "AddonsOptions_Impl::ImplCommit(): Not implemented yet!");
493 bool AddonsOptions_Impl::HasAddonsMenu() const
495 return m_aCachedMenuProperties
.hasElements();
500 sal_Int32
AddonsOptions_Impl::GetAddonsToolBarCount() const
502 return m_aCachedToolBarPartProperties
.size();
507 sal_Int32
AddonsOptions_Impl::GetAddonsNotebookBarCount() const
509 return m_aCachedNotebookBarPartProperties
.size();
514 const Sequence
< Sequence
< PropertyValue
> >& AddonsOptions_Impl::GetAddonsToolBarPart( sal_uInt32 nIndex
) const
516 if ( /*nIndex >= 0 &&*/ nIndex
< m_aCachedToolBarPartProperties
.size() )
517 return m_aCachedToolBarPartProperties
[nIndex
];
519 return m_aEmptyAddonToolBar
;
524 const Sequence
< Sequence
< PropertyValue
> >& AddonsOptions_Impl::GetAddonsNotebookBarPart( sal_uInt32 nIndex
) const
526 if ( /*nIndex >= 0 &&*/ nIndex
< m_aCachedNotebookBarPartProperties
.size() )
527 return m_aCachedNotebookBarPartProperties
[nIndex
];
529 return m_aEmptyAddonNotebookBar
;
534 OUString
AddonsOptions_Impl::GetAddonsToolbarResourceName( sal_uInt32 nIndex
) const
536 if ( nIndex
< m_aCachedToolBarPartResourceNames
.size() )
537 return m_aCachedToolBarPartResourceNames
[nIndex
];
544 OUString
AddonsOptions_Impl::GetAddonsNotebookBarResourceName( sal_uInt32 nIndex
) const
546 if ( nIndex
< m_aCachedNotebookBarPartResourceNames
.size() )
547 return m_aCachedNotebookBarPartResourceNames
[nIndex
];
554 bool AddonsOptions_Impl::GetMergeToolbarInstructions(
555 const OUString
& rToolbarName
,
556 MergeToolbarInstructionContainer
& rToolbarInstructions
) const
558 ToolbarMergingInstructions::const_iterator pIter
= m_aCachedToolbarMergingInstructions
.find( rToolbarName
);
559 if ( pIter
!= m_aCachedToolbarMergingInstructions
.end() )
561 rToolbarInstructions
= pIter
->second
;
570 bool AddonsOptions_Impl::GetMergeNotebookBarInstructions(
571 const OUString
& rNotebookBarName
,
572 MergeNotebookBarInstructionContainer
& rNotebookBarInstructions
) const
574 NotebookBarMergingInstructions::const_iterator pIter
= m_aCachedNotebookBarMergingInstructions
.find( rNotebookBarName
);
575 if ( pIter
!= m_aCachedNotebookBarMergingInstructions
.end() )
577 rNotebookBarInstructions
= pIter
->second
;
586 static BitmapEx
ScaleImage( const BitmapEx
&rImage
, bool bBig
)
588 Size aSize
= ToolBox::GetDefaultImageSize(bBig
? ToolBoxButtonSize::Large
: ToolBoxButtonSize::Small
);
589 BitmapEx
aScaleBmp(rImage
);
590 SAL_INFO("fwk", "Addons: expensive scale image from "
591 << aScaleBmp
.GetSizePixel() << " to " << aSize
);
592 aScaleBmp
.Scale(aSize
, BmpScaleFlag::BestQuality
);
596 BitmapEx
AddonsOptions_Impl::GetImageFromURL( const OUString
& aURL
, bool bBig
, bool bNoScale
)
600 SAL_INFO("fwk", "Expensive: Addons GetImageFromURL " << aURL
<<
601 " big " << (bBig
?"big":"little") <<
602 " scale " << (bNoScale
? "noscale" : "scale"));
604 ImageManager::iterator pIter
= m_aImageManager
.find(aURL
);
605 if ( pIter
!= m_aImageManager
.end() )
607 ImageSize eSize
= bBig
? IMGSIZE_BIG
: IMGSIZE_SMALL
;
608 int nIdx
= static_cast<int>(eSize
);
609 int nOtherIdx
= nIdx
? 0 : 1;
611 OneImageEntry
& rSizeEntry
= pIter
->second
.aSizeEntry
[nIdx
];
612 OneImageEntry
& rOtherEntry
= pIter
->second
.aSizeEntry
[nOtherIdx
];
613 // actually read the image ...
614 if (rSizeEntry
.aImage
.IsEmpty())
615 rSizeEntry
.aImage
= ReadImageFromURL(rSizeEntry
.aURL
);
617 if (rSizeEntry
.aImage
.IsEmpty())
618 { // try the other size and scale it
619 aImage
= ScaleImage(ReadImageFromURL(rOtherEntry
.aURL
), bBig
);
620 rSizeEntry
.aImage
= aImage
;
621 if (rSizeEntry
.aImage
.IsEmpty())
622 SAL_WARN("fwk", "failed to load addons image " << aURL
);
625 // FIXME: bNoScale is not terribly meaningful or useful
627 if (aImage
.IsEmpty() && bNoScale
)
628 aImage
= rSizeEntry
.aImage
;
630 if (aImage
.IsEmpty() && !rSizeEntry
.aScaled
.IsEmpty())
631 aImage
= rSizeEntry
.aScaled
;
633 else // scale to the correct size for the theme / toolbox
635 aImage
= rSizeEntry
.aImage
;
636 if (aImage
.IsEmpty()) // use and scale the other if one size is missing
637 aImage
= rOtherEntry
.aImage
;
639 aImage
= ScaleImage(aImage
, bBig
);
640 rSizeEntry
.aScaled
= aImage
; // cache for next time
647 void AddonsOptions_Impl::ReadAddonMenuSet( Sequence
< Sequence
< PropertyValue
> >& rAddonMenuSeq
)
649 // Read the AddonMenu set and fill property sequences
650 OUString
aAddonMenuNodeName( "AddonUI/AddonMenu" );
651 Sequence
< OUString
> aAddonMenuNodeSeq
= GetNodeNames( aAddonMenuNodeName
);
652 OUString
aAddonMenuItemNode( aAddonMenuNodeName
+ m_aPathDelimiter
);
654 sal_uInt32 nCount
= aAddonMenuNodeSeq
.getLength();
655 sal_uInt32 nIndex
= 0;
656 Sequence
< PropertyValue
> aMenuItem( PROPERTYCOUNT_MENUITEM
);
657 auto pMenuItem
= aMenuItem
.getArray();
658 // Init the property value sequence
659 pMenuItem
[ OFFSET_MENUITEM_URL
].Name
= m_aPropNames
[ INDEX_URL
];
660 pMenuItem
[ OFFSET_MENUITEM_TITLE
].Name
= m_aPropNames
[ INDEX_TITLE
];
661 pMenuItem
[ OFFSET_MENUITEM_TARGET
].Name
= m_aPropNames
[ INDEX_TARGET
];
662 pMenuItem
[ OFFSET_MENUITEM_IMAGEIDENTIFIER
].Name
= m_aPropNames
[ INDEX_IMAGEIDENTIFIER
];
663 pMenuItem
[ OFFSET_MENUITEM_CONTEXT
].Name
= m_aPropNames
[ INDEX_CONTEXT
];
664 pMenuItem
[ OFFSET_MENUITEM_SUBMENU
].Name
= m_aPropNames
[ INDEX_SUBMENU
]; // Submenu set!
666 for ( sal_uInt32 n
= 0; n
< nCount
; n
++ )
668 OUString
aRootMenuItemNode( aAddonMenuItemNode
+ aAddonMenuNodeSeq
[n
] );
671 if ( ReadMenuItem( aRootMenuItemNode
, aMenuItem
) )
673 // Successfully read a menu item, append to our list
674 sal_uInt32 nMenuItemCount
= rAddonMenuSeq
.getLength() + 1;
675 rAddonMenuSeq
.realloc( nMenuItemCount
);
676 rAddonMenuSeq
.getArray()[nIndex
++] = aMenuItem
;
681 void AddonsOptions_Impl::ReadOfficeHelpSet( Sequence
< Sequence
< PropertyValue
> >& rAddonOfficeHelpMenuSeq
)
683 // Read the AddonMenu set and fill property sequences
684 OUString
aAddonHelpMenuNodeName( "AddonUI/OfficeHelp" );
685 Sequence
< OUString
> aAddonHelpMenuNodeSeq
= GetNodeNames( aAddonHelpMenuNodeName
);
686 OUString
aAddonHelpMenuItemNode( aAddonHelpMenuNodeName
+ m_aPathDelimiter
);
688 sal_uInt32 nCount
= aAddonHelpMenuNodeSeq
.getLength();
689 sal_uInt32 nIndex
= 0;
690 Sequence
< PropertyValue
> aMenuItem( PROPERTYCOUNT_MENUITEM
);
691 auto pMenuItem
= aMenuItem
.getArray();
692 // Init the property value sequence
693 pMenuItem
[ OFFSET_MENUITEM_URL
].Name
= m_aPropNames
[ INDEX_URL
];
694 pMenuItem
[ OFFSET_MENUITEM_TITLE
].Name
= m_aPropNames
[ INDEX_TITLE
];
695 pMenuItem
[ OFFSET_MENUITEM_TARGET
].Name
= m_aPropNames
[ INDEX_TARGET
];
696 pMenuItem
[ OFFSET_MENUITEM_IMAGEIDENTIFIER
].Name
= m_aPropNames
[ INDEX_IMAGEIDENTIFIER
];
697 pMenuItem
[ OFFSET_MENUITEM_CONTEXT
].Name
= m_aPropNames
[ INDEX_CONTEXT
];
698 pMenuItem
[ OFFSET_MENUITEM_SUBMENU
].Name
= m_aPropNames
[ INDEX_SUBMENU
]; // Submenu set!
700 for ( sal_uInt32 n
= 0; n
< nCount
; n
++ )
702 OUString
aRootMenuItemNode( aAddonHelpMenuItemNode
+ aAddonHelpMenuNodeSeq
[n
] );
705 if ( ReadMenuItem( aRootMenuItemNode
, aMenuItem
, true ) )
707 // Successfully read a menu item, append to our list
708 sal_uInt32 nMenuItemCount
= rAddonOfficeHelpMenuSeq
.getLength() + 1;
709 rAddonOfficeHelpMenuSeq
.realloc( nMenuItemCount
);
710 rAddonOfficeHelpMenuSeq
.getArray()[nIndex
++] = aMenuItem
;
715 void AddonsOptions_Impl::ReadOfficeMenuBarSet( Sequence
< Sequence
< PropertyValue
> >& rAddonOfficeMenuBarSeq
)
717 // Read the OfficeMenuBar set and fill property sequences
718 OUString
aAddonMenuBarNodeName( "AddonUI/OfficeMenuBar" );
719 Sequence
< OUString
> aAddonMenuBarNodeSeq
= GetNodeNames( aAddonMenuBarNodeName
);
720 OUString
aAddonMenuBarNode( aAddonMenuBarNodeName
+ m_aPathDelimiter
);
722 sal_uInt32 nCount
= aAddonMenuBarNodeSeq
.getLength();
723 sal_uInt32 nIndex
= 0;
724 Sequence
< PropertyValue
> aPopupMenu( PROPERTYCOUNT_POPUPMENU
);
725 auto pPopupMenu
= aPopupMenu
.getArray();
726 // Init the property value sequence
727 pPopupMenu
[ OFFSET_POPUPMENU_TITLE
].Name
= m_aPropNames
[ INDEX_TITLE
];
728 pPopupMenu
[ OFFSET_POPUPMENU_CONTEXT
].Name
= m_aPropNames
[ INDEX_CONTEXT
];
729 pPopupMenu
[ OFFSET_POPUPMENU_SUBMENU
].Name
= m_aPropNames
[ INDEX_SUBMENU
];
730 pPopupMenu
[ OFFSET_POPUPMENU_URL
].Name
= m_aPropNames
[ INDEX_URL
];
732 StringToIndexMap aTitleToIndexMap
;
733 auto pAddonOfficeMenuBarSeq
= rAddonOfficeMenuBarSeq
.getArray();
734 for ( sal_uInt32 n
= 0; n
< nCount
; n
++ )
736 OUString
aPopupMenuNode( aAddonMenuBarNode
+ aAddonMenuBarNodeSeq
[n
] );
739 if ( ReadPopupMenu( aPopupMenuNode
, aPopupMenu
) )
741 // Successfully read a popup menu, append to our list
742 OUString aPopupTitle
;
743 if ( aPopupMenu
[OFFSET_POPUPMENU_TITLE
].Value
>>= aPopupTitle
)
745 StringToIndexMap::const_iterator pIter
= aTitleToIndexMap
.find( aPopupTitle
);
746 if ( pIter
!= aTitleToIndexMap
.end() )
748 // title already there => concat both popup menus
749 Sequence
< PropertyValue
>& rOldPopupMenu
= pAddonOfficeMenuBarSeq
[pIter
->second
];
750 AppendPopupMenu( rOldPopupMenu
, aPopupMenu
);
755 sal_uInt32 nMenuItemCount
= rAddonOfficeMenuBarSeq
.getLength() + 1;
756 rAddonOfficeMenuBarSeq
.realloc( nMenuItemCount
);
757 pAddonOfficeMenuBarSeq
= rAddonOfficeMenuBarSeq
.getArray();
758 pAddonOfficeMenuBarSeq
[nIndex
] = aPopupMenu
;
759 aTitleToIndexMap
.emplace( aPopupTitle
, nIndex
);
767 void AddonsOptions_Impl::ReadOfficeToolBarSet( AddonToolBars
& rAddonOfficeToolBars
, std::vector
< OUString
>& rAddonOfficeToolBarResNames
)
769 // Read the OfficeToolBar set and fill property sequences
770 OUString
aAddonToolBarNodeName( "AddonUI/OfficeToolBar" );
771 Sequence
< OUString
> aAddonToolBarNodeSeq
= GetNodeNames( aAddonToolBarNodeName
);
772 OUString
aAddonToolBarNode( aAddonToolBarNodeName
+ m_aPathDelimiter
);
774 sal_uInt32 nCount
= aAddonToolBarNodeSeq
.getLength();
776 for ( sal_uInt32 n
= 0; n
< nCount
; n
++ )
778 OUString
aToolBarItemNode( aAddonToolBarNode
+ aAddonToolBarNodeSeq
[n
] );
779 rAddonOfficeToolBarResNames
.push_back( aAddonToolBarNodeSeq
[n
] );
780 rAddonOfficeToolBars
.push_back( m_aEmptyAddonToolBar
);
781 ReadToolBarItemSet( aToolBarItemNode
, rAddonOfficeToolBars
[n
] );
785 bool AddonsOptions_Impl::ReadToolBarItemSet( const OUString
& rToolBarItemSetNodeName
, Sequence
< Sequence
< PropertyValue
> >& rAddonOfficeToolBarSeq
)
787 sal_uInt32 nToolBarItemCount
= rAddonOfficeToolBarSeq
.getLength();
788 OUString
aAddonToolBarItemSetNode( rToolBarItemSetNodeName
+ m_aPathDelimiter
);
789 Sequence
< OUString
> aAddonToolBarItemSetNodeSeq
= GetNodeNames( rToolBarItemSetNodeName
);
790 Sequence
< PropertyValue
> aToolBarItem( PROPERTYCOUNT_TOOLBARITEM
);
791 auto pToolBarItem
= aToolBarItem
.getArray();
792 // Init the property value sequence
793 pToolBarItem
[ OFFSET_TOOLBARITEM_URL
].Name
= m_aPropNames
[ INDEX_URL
];
794 pToolBarItem
[ OFFSET_TOOLBARITEM_TITLE
].Name
= m_aPropNames
[ INDEX_TITLE
];
795 pToolBarItem
[ OFFSET_TOOLBARITEM_IMAGEIDENTIFIER
].Name
= m_aPropNames
[ INDEX_IMAGEIDENTIFIER
];
796 pToolBarItem
[ OFFSET_TOOLBARITEM_TARGET
].Name
= m_aPropNames
[ INDEX_TARGET
];
797 pToolBarItem
[ OFFSET_TOOLBARITEM_CONTEXT
].Name
= m_aPropNames
[ INDEX_CONTEXT
];
798 pToolBarItem
[ OFFSET_TOOLBARITEM_CONTROLTYPE
].Name
= m_aPropNames
[ INDEX_CONTROLTYPE
];
799 pToolBarItem
[ OFFSET_TOOLBARITEM_WIDTH
].Name
= m_aPropNames
[ INDEX_WIDTH
];
801 sal_uInt32 nCount
= aAddonToolBarItemSetNodeSeq
.getLength();
802 for ( sal_uInt32 n
= 0; n
< nCount
; n
++ )
804 OUString
aToolBarItemNode( aAddonToolBarItemSetNode
+ aAddonToolBarItemSetNodeSeq
[n
] );
806 // Read the ToolBarItem
807 if ( ReadToolBarItem( aToolBarItemNode
, aToolBarItem
) )
809 // Successfully read a toolbar item, append to our list
810 sal_uInt32 nAddonCount
= rAddonOfficeToolBarSeq
.getLength();
811 rAddonOfficeToolBarSeq
.realloc( nAddonCount
+1 );
812 rAddonOfficeToolBarSeq
.getArray()[nAddonCount
] = aToolBarItem
;
816 return ( o3tl::make_unsigned(rAddonOfficeToolBarSeq
.getLength()) > nToolBarItemCount
);
819 void AddonsOptions_Impl::ReadOfficeNotebookBarSet(
820 AddonNotebookBars
& rAddonOfficeNotebookBars
,
821 std::vector
<OUString
>& rAddonOfficeNotebookBarResNames
)
823 // Read the OfficeToolBar set and fill property sequences
824 OUString
aAddonNotebookBarNodeName("AddonUI/OfficeNotebookBar");
825 Sequence
<OUString
> aAddonNotebookBarNodeSeq
= GetNodeNames(aAddonNotebookBarNodeName
);
826 OUString
aAddonNotebookBarNode(aAddonNotebookBarNodeName
+ m_aPathDelimiter
);
828 sal_uInt32 nCount
= aAddonNotebookBarNodeSeq
.getLength();
830 for (sal_uInt32 n
= 0; n
< nCount
; n
++)
832 OUString
aNotebookBarItemNode(aAddonNotebookBarNode
+ aAddonNotebookBarNodeSeq
[n
]);
833 rAddonOfficeNotebookBarResNames
.push_back(aAddonNotebookBarNodeSeq
[n
]);
834 rAddonOfficeNotebookBars
.push_back(m_aEmptyAddonNotebookBar
);
835 ReadNotebookBarItemSet(aNotebookBarItemNode
, rAddonOfficeNotebookBars
[n
]);
839 bool AddonsOptions_Impl::ReadNotebookBarItemSet(
840 const OUString
& rNotebookBarItemSetNodeName
,
841 Sequence
<Sequence
<PropertyValue
>>& rAddonOfficeNotebookBarSeq
)
843 sal_uInt32 nNotebookBarItemCount
= rAddonOfficeNotebookBarSeq
.getLength();
844 OUString
aAddonNotebookBarItemSetNode(rNotebookBarItemSetNodeName
+ m_aPathDelimiter
);
845 Sequence
<OUString
> aAddonNotebookBarItemSetNodeSeq
= GetNodeNames(rNotebookBarItemSetNodeName
);
846 Sequence
<PropertyValue
> aNotebookBarItem(PROPERTYCOUNT_NOTEBOOKBARITEM
);
847 auto pNotebookBarItem
= aNotebookBarItem
.getArray();
848 // Init the property value sequence
849 pNotebookBarItem
[OFFSET_NOTEBOOKBARITEM_URL
].Name
= m_aPropNames
[INDEX_URL
];
850 pNotebookBarItem
[OFFSET_NOTEBOOKBARITEM_TITLE
].Name
= m_aPropNames
[INDEX_TITLE
];
851 pNotebookBarItem
[OFFSET_NOTEBOOKBARITEM_IMAGEIDENTIFIER
].Name
852 = m_aPropNames
[INDEX_IMAGEIDENTIFIER
];
853 pNotebookBarItem
[OFFSET_NOTEBOOKBARITEM_TARGET
].Name
= m_aPropNames
[INDEX_TARGET
];
854 pNotebookBarItem
[OFFSET_NOTEBOOKBARITEM_CONTEXT
].Name
= m_aPropNames
[INDEX_CONTEXT
];
855 pNotebookBarItem
[OFFSET_NOTEBOOKBARITEM_CONTROLTYPE
].Name
= m_aPropNames
[INDEX_CONTROLTYPE
];
856 pNotebookBarItem
[OFFSET_NOTEBOOKBARITEM_WIDTH
].Name
= m_aPropNames
[INDEX_WIDTH
];
857 pNotebookBarItem
[OFFSET_NOTEBOOKBARITEM_STYLE
].Name
= m_aPropNames
[INDEX_STYLE
];
859 sal_uInt32 nCount
= aAddonNotebookBarItemSetNodeSeq
.getLength();
860 for (sal_uInt32 n
= 0; n
< nCount
; n
++)
862 OUString
aNotebookBarItemNode(aAddonNotebookBarItemSetNode
863 + aAddonNotebookBarItemSetNodeSeq
[n
]);
864 // Read the NotebookBarItem
865 if (ReadNotebookBarItem(aNotebookBarItemNode
, aNotebookBarItem
))
867 // Successfully read a toolbar item, append to our list
868 sal_uInt32 nAddonCount
= rAddonOfficeNotebookBarSeq
.getLength();
869 rAddonOfficeNotebookBarSeq
.realloc(nAddonCount
+ 1);
870 rAddonOfficeNotebookBarSeq
.getArray()[nAddonCount
] = aNotebookBarItem
;
874 return (o3tl::make_unsigned(rAddonOfficeNotebookBarSeq
.getLength())
875 > nNotebookBarItemCount
);
878 void AddonsOptions_Impl::ReadImages( ImageManager
& aImageManager
)
880 // Read the user-defined Images set and fill image manager
881 OUString
aAddonImagesNodeName( "AddonUI/Images" );
882 Sequence
< OUString
> aAddonImagesNodeSeq
= GetNodeNames( aAddonImagesNodeName
);
883 OUString
aAddonImagesNode( aAddonImagesNodeName
+ m_aPathDelimiter
);
885 sal_uInt32 nCount
= aAddonImagesNodeSeq
.getLength();
887 // Init the property value sequence
890 for ( sal_uInt32 n
= 0; n
< nCount
; n
++ )
892 OUString
aImagesItemNode( aAddonImagesNode
+ aAddonImagesNodeSeq
[n
] );
894 // Create sequence for data access
895 Sequence
< OUString
> aAddonImageItemNodePropNames
= { aImagesItemNode
+
897 m_aPropNames
[ OFFSET_MENUITEM_URL
] };
899 Sequence
< Any
> aAddonImageItemNodeValues
= GetProperties( aAddonImageItemNodePropNames
);
901 // An user-defined image entry must have a URL. As "ImageIdentifier" has a higher priority
902 // we also check if we already have an images association.
903 if (( aAddonImageItemNodeValues
[0] >>= aURL
) &&
905 !HasAssociatedImages( aURL
))
907 OUString aImagesUserDefinedItemNode
= aImagesItemNode
+
912 // Read a user-defined images data
913 std::unique_ptr
<ImageEntry
> pImageEntry
= ReadImageData( aImagesUserDefinedItemNode
);
916 // Successfully read a user-defined images item, put it into our image manager
917 aImageManager
.emplace( aURL
, std::move(*pImageEntry
) );
923 OUString
AddonsOptions_Impl::GeneratePrefixURL()
925 // Create a unique prefixed Add-On popup menu URL so it can be identified later as a runtime popup menu.
926 return m_aRootAddonPopupMenuURLPrexfix
+ OUString::number( ++m_nRootAddonPopupMenuId
);
929 void AddonsOptions_Impl::ReadMenuMergeInstructions( MergeMenuInstructionContainer
& aContainer
)
931 static constexpr OUString
aMenuMergeRootName( u
"AddonUI/OfficeMenuBarMerging/"_ustr
);
933 Sequence
< OUString
> aAddonMergeNodesSeq
= GetNodeNames( aMenuMergeRootName
);
935 sal_uInt32 nCount
= aAddonMergeNodesSeq
.getLength();
937 // Init the property value sequence
938 Sequence
< OUString
> aNodePropNames( 5 );
939 auto pNodePropNames
= aNodePropNames
.getArray();
941 for ( sal_uInt32 i
= 0; i
< nCount
; i
++ )
943 OUString
aMergeAddonInstructions( aMenuMergeRootName
+ aAddonMergeNodesSeq
[i
] );
945 Sequence
< OUString
> aAddonInstMergeNodesSeq
= GetNodeNames( aMergeAddonInstructions
);
946 sal_uInt32 nCountAddons
= aAddonInstMergeNodesSeq
.getLength();
948 for ( sal_uInt32 j
= 0; j
< nCountAddons
; j
++ )
950 OUString aMergeAddonInstructionBase
= aMergeAddonInstructions
+
952 aAddonInstMergeNodesSeq
[j
] +
955 // Create sequence for data access
956 pNodePropNames
[0] = aMergeAddonInstructionBase
+
957 m_aPropMergeMenuNames
[ OFFSET_MERGEMENU_MERGEPOINT
];
959 pNodePropNames
[1] = aMergeAddonInstructionBase
+
960 m_aPropMergeMenuNames
[ OFFSET_MERGEMENU_MERGECOMMAND
];
962 pNodePropNames
[2] = aMergeAddonInstructionBase
+
963 m_aPropMergeMenuNames
[ OFFSET_MERGEMENU_MERGECOMMANDPARAMETER
];
965 pNodePropNames
[3] = aMergeAddonInstructionBase
+
966 m_aPropMergeMenuNames
[ OFFSET_MERGEMENU_MERGEFALLBACK
];
968 pNodePropNames
[4] = aMergeAddonInstructionBase
+
969 m_aPropMergeMenuNames
[ OFFSET_MERGEMENU_MERGECONTEXT
];
971 Sequence
< Any
> aNodePropValues
= GetProperties( aNodePropNames
);
973 MergeMenuInstruction aMergeMenuInstruction
;
974 aNodePropValues
[0] >>= aMergeMenuInstruction
.aMergePoint
;
975 aNodePropValues
[1] >>= aMergeMenuInstruction
.aMergeCommand
;
976 aNodePropValues
[2] >>= aMergeMenuInstruction
.aMergeCommandParameter
;
977 aNodePropValues
[3] >>= aMergeMenuInstruction
.aMergeFallback
;
978 aNodePropValues
[4] >>= aMergeMenuInstruction
.aMergeContext
;
980 ReadMergeMenuData( aMergeAddonInstructionBase
, aMergeMenuInstruction
.aMergeMenu
);
982 aContainer
.push_back( aMergeMenuInstruction
);
987 void AddonsOptions_Impl::ReadMergeMenuData( std::u16string_view aMergeAddonInstructionBase
, Sequence
< Sequence
< PropertyValue
> >& rMergeMenu
)
989 OUString
aMergeMenuBaseNode( aMergeAddonInstructionBase
+m_aPropMergeMenuNames
[ OFFSET_MERGEMENU_MENUITEMS
] );
991 Sequence
< OUString
> aSubMenuNodeNames
= GetNodeNames( aMergeMenuBaseNode
);
992 aMergeMenuBaseNode
+= m_aPathDelimiter
;
994 // extend the node names to have full path strings
995 for ( OUString
& rName
: asNonConstRange(aSubMenuNodeNames
) )
996 rName
= aMergeMenuBaseNode
+ rName
;
998 ReadSubMenuEntries( aSubMenuNodeNames
, rMergeMenu
);
1001 void AddonsOptions_Impl::ReadToolbarMergeInstructions( ToolbarMergingInstructions
& rCachedToolbarMergingInstructions
)
1003 static constexpr OUString
aToolbarMergeRootName( u
"AddonUI/OfficeToolbarMerging/"_ustr
);
1005 Sequence
< OUString
> aAddonMergeNodesSeq
= GetNodeNames( aToolbarMergeRootName
);
1006 sal_uInt32 nCount
= aAddonMergeNodesSeq
.getLength();
1008 // Init the property value sequence
1009 Sequence
< OUString
> aNodePropNames( 6 );
1010 auto pNodePropNames
= aNodePropNames
.getArray();
1012 for ( sal_uInt32 i
= 0; i
< nCount
; i
++ )
1014 OUString
aMergeAddonInstructions( aToolbarMergeRootName
+ aAddonMergeNodesSeq
[i
] );
1016 Sequence
< OUString
> aAddonInstMergeNodesSeq
= GetNodeNames( aMergeAddonInstructions
);
1017 sal_uInt32 nCountAddons
= aAddonInstMergeNodesSeq
.getLength();
1019 for ( sal_uInt32 j
= 0; j
< nCountAddons
; j
++ )
1021 OUString aMergeAddonInstructionBase
= aMergeAddonInstructions
+
1023 aAddonInstMergeNodesSeq
[j
] +
1026 // Create sequence for data access
1027 pNodePropNames
[0] = aMergeAddonInstructionBase
+
1028 m_aPropMergeToolbarNames
[ OFFSET_MERGETOOLBAR_TOOLBAR
];
1030 pNodePropNames
[1] = aMergeAddonInstructionBase
+
1031 m_aPropMergeToolbarNames
[ OFFSET_MERGETOOLBAR_MERGEPOINT
];
1033 pNodePropNames
[2] = aMergeAddonInstructionBase
+
1034 m_aPropMergeToolbarNames
[ OFFSET_MERGETOOLBAR_MERGECOMMAND
];
1036 pNodePropNames
[3] = aMergeAddonInstructionBase
+
1037 m_aPropMergeToolbarNames
[ OFFSET_MERGETOOLBAR_MERGECOMMANDPARAMETER
];
1039 pNodePropNames
[4] = aMergeAddonInstructionBase
+
1040 m_aPropMergeToolbarNames
[ OFFSET_MERGETOOLBAR_MERGEFALLBACK
];
1042 pNodePropNames
[5] = aMergeAddonInstructionBase
+
1043 m_aPropMergeToolbarNames
[ OFFSET_MERGETOOLBAR_MERGECONTEXT
];
1045 Sequence
< Any
> aNodePropValues
= GetProperties( aNodePropNames
);
1047 MergeToolbarInstruction aMergeToolbarInstruction
;
1048 aNodePropValues
[0] >>= aMergeToolbarInstruction
.aMergeToolbar
;
1049 aNodePropValues
[1] >>= aMergeToolbarInstruction
.aMergePoint
;
1050 aNodePropValues
[2] >>= aMergeToolbarInstruction
.aMergeCommand
;
1051 aNodePropValues
[3] >>= aMergeToolbarInstruction
.aMergeCommandParameter
;
1052 aNodePropValues
[4] >>= aMergeToolbarInstruction
.aMergeFallback
;
1053 aNodePropValues
[5] >>= aMergeToolbarInstruction
.aMergeContext
;
1055 ReadMergeToolbarData( aMergeAddonInstructionBase
,
1056 aMergeToolbarInstruction
.aMergeToolbarItems
);
1058 MergeToolbarInstructionContainer
& rVector
= rCachedToolbarMergingInstructions
[ aMergeToolbarInstruction
.aMergeToolbar
];
1059 rVector
.push_back( aMergeToolbarInstruction
);
1064 void AddonsOptions_Impl::ReadMergeToolbarData( std::u16string_view aMergeAddonInstructionBase
, Sequence
< Sequence
< PropertyValue
> >& rMergeToolbarItems
)
1066 OUString aMergeToolbarBaseNode
= aMergeAddonInstructionBase
+
1067 m_aPropMergeToolbarNames
[ OFFSET_MERGETOOLBAR_TOOLBARITEMS
];
1069 ReadToolBarItemSet( aMergeToolbarBaseNode
, rMergeToolbarItems
);
1072 void AddonsOptions_Impl::ReadNotebookBarMergeInstructions(
1073 NotebookBarMergingInstructions
& rCachedNotebookBarMergingInstructions
)
1075 static constexpr OUString
aNotebookBarMergeRootName(u
"AddonUI/OfficeNotebookBarMerging/"_ustr
);
1077 Sequence
<OUString
> aAddonMergeNodesSeq
= GetNodeNames(aNotebookBarMergeRootName
);
1078 sal_uInt32 nCount
= aAddonMergeNodesSeq
.getLength();
1080 // Init the property value sequence
1081 Sequence
<OUString
> aNodePropNames(6);
1082 auto pNodePropNames
= aNodePropNames
.getArray();
1084 for (sal_uInt32 i
= 0; i
< nCount
; i
++)
1086 OUString
aMergeAddonInstructions(aNotebookBarMergeRootName
+ aAddonMergeNodesSeq
[i
]);
1088 Sequence
<OUString
> aAddonInstMergeNodesSeq
= GetNodeNames(aMergeAddonInstructions
);
1089 sal_uInt32 nCountAddons
= aAddonInstMergeNodesSeq
.getLength();
1091 for (sal_uInt32 j
= 0; j
< nCountAddons
; j
++)
1093 OUString aMergeAddonInstructionBase
= aMergeAddonInstructions
+
1095 aAddonInstMergeNodesSeq
[j
] +
1098 // Create sequence for data access
1099 pNodePropNames
[0] = aMergeAddonInstructionBase
+
1100 m_aPropMergeNotebookBarNames
[OFFSET_MERGENOTEBOOKBAR_NOTEBOOKBAR
];
1102 pNodePropNames
[1] = aMergeAddonInstructionBase
+
1103 m_aPropMergeNotebookBarNames
[OFFSET_MERGENOTEBOOKBAR_MERGEPOINT
];
1105 pNodePropNames
[2] = aMergeAddonInstructionBase
+
1106 m_aPropMergeNotebookBarNames
[OFFSET_MERGENOTEBOOKBAR_MERGECOMMAND
];
1108 pNodePropNames
[3] = aMergeAddonInstructionBase
+
1109 m_aPropMergeNotebookBarNames
[OFFSET_MERGENOTEBOOKBAR_MERGECOMMANDPARAMETER
];
1111 pNodePropNames
[4] = aMergeAddonInstructionBase
+
1112 m_aPropMergeNotebookBarNames
[OFFSET_MERGENOTEBOOKBAR_MERGEFALLBACK
];
1114 pNodePropNames
[5] = aMergeAddonInstructionBase
+
1115 m_aPropMergeNotebookBarNames
[OFFSET_MERGENOTEBOOKBAR_MERGECONTEXT
];
1117 Sequence
<Any
> aNodePropValues
= GetProperties(aNodePropNames
);
1119 MergeNotebookBarInstruction aMergeNotebookBarInstruction
;
1120 aNodePropValues
[0] >>= aMergeNotebookBarInstruction
.aMergeNotebookBar
;
1121 aNodePropValues
[1] >>= aMergeNotebookBarInstruction
.aMergePoint
;
1122 aNodePropValues
[2] >>= aMergeNotebookBarInstruction
.aMergeCommand
;
1123 aNodePropValues
[3] >>= aMergeNotebookBarInstruction
.aMergeCommandParameter
;
1124 aNodePropValues
[4] >>= aMergeNotebookBarInstruction
.aMergeFallback
;
1125 aNodePropValues
[5] >>= aMergeNotebookBarInstruction
.aMergeContext
;
1127 ReadMergeNotebookBarData(aMergeAddonInstructionBase
,
1128 aMergeNotebookBarInstruction
.aMergeNotebookBarItems
);
1130 MergeNotebookBarInstructionContainer
& rVector
1131 = rCachedNotebookBarMergingInstructions
[aMergeNotebookBarInstruction
1132 .aMergeNotebookBar
];
1133 rVector
.push_back(aMergeNotebookBarInstruction
);
1138 void AddonsOptions_Impl::ReadMergeNotebookBarData(
1139 std::u16string_view aMergeAddonInstructionBase
,
1140 Sequence
<Sequence
<PropertyValue
>>& rMergeNotebookBarItems
)
1142 OUString aMergeNotebookBarBaseNode
= aMergeAddonInstructionBase
+
1143 m_aPropMergeNotebookBarNames
[OFFSET_MERGENOTEBOOKBAR_NOTEBOOKBARITEMS
];
1145 ReadNotebookBarItemSet(aMergeNotebookBarBaseNode
, rMergeNotebookBarItems
);
1148 void AddonsOptions_Impl::ReadStatusbarMergeInstructions( MergeStatusbarInstructionContainer
& aContainer
)
1150 static constexpr OUString
aStatusbarMergeRootName( u
"AddonUI/OfficeStatusbarMerging/"_ustr
);
1152 Sequence
< OUString
> aAddonMergeNodesSeq
= GetNodeNames( aStatusbarMergeRootName
);
1153 sal_uInt32 nCount
= aAddonMergeNodesSeq
.getLength();
1155 Sequence
< OUString
> aNodePropNames( 5 );
1156 auto pNodePropNames
= aNodePropNames
.getArray();
1158 for ( sal_uInt32 i
= 0; i
< nCount
; i
++ )
1160 OUString
aMergeAddonInstructions( aStatusbarMergeRootName
+ aAddonMergeNodesSeq
[i
] );
1162 Sequence
< OUString
> aAddonInstMergeNodesSeq
= GetNodeNames( aMergeAddonInstructions
);
1163 sal_uInt32 nCountAddons
= aAddonInstMergeNodesSeq
.getLength();
1165 for ( sal_uInt32 j
= 0; j
< nCountAddons
; j
++ )
1167 OUString aMergeAddonInstructionBase
= aMergeAddonInstructions
+
1169 aAddonInstMergeNodesSeq
[j
] +
1172 // Create sequence for data access
1173 pNodePropNames
[0] = aMergeAddonInstructionBase
+
1174 m_aPropMergeMenuNames
[ OFFSET_MERGESTATUSBAR_MERGEPOINT
];
1176 pNodePropNames
[1] = aMergeAddonInstructionBase
+
1177 m_aPropMergeMenuNames
[ OFFSET_MERGESTATUSBAR_MERGECOMMAND
];
1179 pNodePropNames
[2] = aMergeAddonInstructionBase
+
1180 m_aPropMergeMenuNames
[ OFFSET_MERGESTATUSBAR_MERGECOMMANDPARAMETER
];
1182 pNodePropNames
[3] = aMergeAddonInstructionBase
+
1183 m_aPropMergeMenuNames
[ OFFSET_MERGESTATUSBAR_MERGEFALLBACK
];
1185 pNodePropNames
[4] = aMergeAddonInstructionBase
+
1186 m_aPropMergeMenuNames
[ OFFSET_MERGESTATUSBAR_MERGECONTEXT
];
1188 Sequence
< Any
> aNodePropValues
= GetProperties( aNodePropNames
);
1190 MergeStatusbarInstruction aMergeStatusbarInstruction
;
1191 aNodePropValues
[0] >>= aMergeStatusbarInstruction
.aMergePoint
;
1192 aNodePropValues
[1] >>= aMergeStatusbarInstruction
.aMergeCommand
;
1193 aNodePropValues
[2] >>= aMergeStatusbarInstruction
.aMergeCommandParameter
;
1194 // aNodePropValues[3] >>= aMergeStatusbarInstruction.aMergeFallback;
1195 aNodePropValues
[4] >>= aMergeStatusbarInstruction
.aMergeContext
;
1197 ReadMergeStatusbarData( aMergeAddonInstructionBase
,
1198 aMergeStatusbarInstruction
.aMergeStatusbarItems
);
1200 aContainer
.push_back( aMergeStatusbarInstruction
);
1205 void AddonsOptions_Impl::ReadMergeStatusbarData(
1206 std::u16string_view aMergeAddonInstructionBase
,
1207 Sequence
< Sequence
< PropertyValue
> >& rMergeStatusbarItems
)
1209 OUString aMergeStatusbarBaseNode
= aMergeAddonInstructionBase
+
1210 m_aPropMergeStatusbarNames
[ OFFSET_MERGESTATUSBAR_STATUSBARITEMS
];
1212 OUString
aAddonStatusbarItemSetNode( aMergeStatusbarBaseNode
+ m_aPathDelimiter
);
1213 Sequence
< OUString
> aAddonStatusbarItemSetNodeSeq
= GetNodeNames( aMergeStatusbarBaseNode
);
1215 Sequence
< PropertyValue
> aStatusbarItem( PROPERTYCOUNT_STATUSBARITEM
);
1216 auto pStatusbarItem
= aStatusbarItem
.getArray();
1217 pStatusbarItem
[ OFFSET_STATUSBARITEM_URL
].Name
= m_aPropNames
[ INDEX_URL
];
1218 pStatusbarItem
[ OFFSET_STATUSBARITEM_TITLE
].Name
= m_aPropNames
[ INDEX_TITLE
];
1219 pStatusbarItem
[ OFFSET_STATUSBARITEM_CONTEXT
].Name
= m_aPropNames
[ INDEX_CONTEXT
];
1220 pStatusbarItem
[ OFFSET_STATUSBARITEM_ALIGN
].Name
= m_aPropNames
[ INDEX_ALIGN
];
1221 pStatusbarItem
[ OFFSET_STATUSBARITEM_AUTOSIZE
].Name
= m_aPropNames
[ INDEX_AUTOSIZE
];
1222 pStatusbarItem
[ OFFSET_STATUSBARITEM_OWNERDRAW
].Name
= m_aPropNames
[ INDEX_OWNERDRAW
];
1223 pStatusbarItem
[ OFFSET_STATUSBARITEM_MANDATORY
].Name
= m_aPropNames
[ INDEX_MANDATORY
];
1224 pStatusbarItem
[ OFFSET_STATUSBARITEM_WIDTH
].Name
= m_aPropNames
[ INDEX_WIDTH
];
1226 sal_uInt32 nCount
= aAddonStatusbarItemSetNodeSeq
.getLength();
1227 for ( sal_uInt32 n
= 0; n
< nCount
; n
++ )
1229 OUString
aStatusbarItemNode( aAddonStatusbarItemSetNode
+ aAddonStatusbarItemSetNodeSeq
[n
] );
1231 if ( ReadStatusBarItem( aStatusbarItemNode
, aStatusbarItem
) )
1233 sal_uInt32 nAddonCount
= rMergeStatusbarItems
.getLength();
1234 rMergeStatusbarItems
.realloc( nAddonCount
+1 );
1235 rMergeStatusbarItems
.getArray()[nAddonCount
] = aStatusbarItem
;
1240 bool AddonsOptions_Impl::ReadStatusBarItem(
1241 std::u16string_view aStatusarItemNodeName
,
1242 Sequence
< PropertyValue
>& aStatusbarItem
)
1244 bool bResult( false );
1246 OUString
aAddonStatusbarItemTreeNode( aStatusarItemNodeName
+ m_aPathDelimiter
);
1248 Sequence
< Any
> aStatusbarItemNodePropValues
= GetProperties( GetPropertyNamesStatusbarItem( aAddonStatusbarItemTreeNode
) );
1250 // Command URL is required
1251 if (( aStatusbarItemNodePropValues
[ OFFSET_STATUSBARITEM_URL
] >>= aURL
) && aURL
.getLength() > 0 )
1253 auto pStatusbarItem
= aStatusbarItem
.getArray();
1254 pStatusbarItem
[ OFFSET_STATUSBARITEM_URL
].Value
<<= aURL
;
1255 pStatusbarItem
[ OFFSET_STATUSBARITEM_TITLE
].Value
= aStatusbarItemNodePropValues
[ OFFSET_STATUSBARITEM_TITLE
];
1256 pStatusbarItem
[ OFFSET_STATUSBARITEM_CONTEXT
].Value
= aStatusbarItemNodePropValues
[ OFFSET_STATUSBARITEM_CONTEXT
];
1257 pStatusbarItem
[ OFFSET_STATUSBARITEM_ALIGN
].Value
= aStatusbarItemNodePropValues
[ OFFSET_STATUSBARITEM_ALIGN
];
1258 pStatusbarItem
[ OFFSET_STATUSBARITEM_AUTOSIZE
].Value
= aStatusbarItemNodePropValues
[ OFFSET_STATUSBARITEM_AUTOSIZE
];
1259 pStatusbarItem
[ OFFSET_STATUSBARITEM_OWNERDRAW
].Value
= aStatusbarItemNodePropValues
[ OFFSET_STATUSBARITEM_OWNERDRAW
];
1260 pStatusbarItem
[ OFFSET_STATUSBARITEM_MANDATORY
].Value
= aStatusbarItemNodePropValues
[ OFFSET_STATUSBARITEM_MANDATORY
];
1262 // Configuration uses hyper for long. Therefore transform into sal_Int32
1263 sal_Int64
nValue( 0 );
1264 aStatusbarItemNodePropValues
[ OFFSET_STATUSBARITEM_WIDTH
] >>= nValue
;
1265 pStatusbarItem
[ OFFSET_STATUSBARITEM_WIDTH
].Value
<<= sal_Int32( nValue
);
1273 bool AddonsOptions_Impl::ReadMenuItem( std::u16string_view aMenuNodeName
, Sequence
< PropertyValue
>& aMenuItem
, bool bIgnoreSubMenu
)
1275 bool bResult
= false;
1277 OUString
aAddonMenuItemTreeNode( aMenuNodeName
+ m_aPathDelimiter
);
1279 Sequence
< Any
> aMenuItemNodePropValues
= GetProperties( GetPropertyNamesMenuItem( aAddonMenuItemTreeNode
) );
1280 if (( aMenuItemNodePropValues
[ OFFSET_MENUITEM_TITLE
] >>= aStrValue
) && !aStrValue
.isEmpty() )
1282 auto pMenuItem
= aMenuItem
.getArray();
1283 pMenuItem
[ OFFSET_MENUITEM_TITLE
].Value
<<= aStrValue
;
1285 OUString
aRootSubMenuName( aAddonMenuItemTreeNode
+ m_aPropNames
[ INDEX_SUBMENU
] );
1286 Sequence
< OUString
> aRootSubMenuNodeNames
= GetNodeNames( aRootSubMenuName
);
1287 if ( aRootSubMenuNodeNames
.hasElements() && !bIgnoreSubMenu
)
1289 // Set a unique prefixed Add-On popup menu URL so it can be identified later
1290 OUString aPopupMenuURL
= GeneratePrefixURL();
1291 OUString aPopupMenuImageId
;
1293 aMenuItemNodePropValues
[ OFFSET_MENUITEM_IMAGEIDENTIFIER
] >>= aPopupMenuImageId
;
1294 ReadAndAssociateImages( aPopupMenuURL
, aPopupMenuImageId
);
1296 // A popup menu must have a title and can have a URL and ImageIdentifier
1297 // Set the other property values to empty
1298 pMenuItem
[ OFFSET_MENUITEM_URL
].Value
<<= aPopupMenuURL
;
1299 pMenuItem
[ OFFSET_MENUITEM_TARGET
].Value
<<= OUString();
1300 pMenuItem
[ OFFSET_MENUITEM_IMAGEIDENTIFIER
].Value
<<= aPopupMenuImageId
;
1301 pMenuItem
[ OFFSET_MENUITEM_CONTEXT
].Value
= aMenuItemNodePropValues
[ OFFSET_MENUITEM_CONTEXT
];
1303 // Continue to read the sub menu nodes
1304 Sequence
< Sequence
< PropertyValue
> > aSubMenuSeq
;
1305 OUString
aSubMenuRootNodeName( aRootSubMenuName
+ m_aPathDelimiter
);
1306 for ( OUString
& rName
: asNonConstRange(aRootSubMenuNodeNames
) )
1307 rName
= aSubMenuRootNodeName
+ rName
;
1308 ReadSubMenuEntries( aRootSubMenuNodeNames
, aSubMenuSeq
);
1309 pMenuItem
[ OFFSET_MENUITEM_SUBMENU
].Value
<<= aSubMenuSeq
;
1312 else if (( aMenuItemNodePropValues
[ OFFSET_MENUITEM_URL
] >>= aStrValue
) && !aStrValue
.isEmpty() )
1314 // A simple menu item => read the other properties;
1315 OUString aMenuImageId
;
1317 aMenuItemNodePropValues
[ OFFSET_MENUITEM_IMAGEIDENTIFIER
] >>= aMenuImageId
;
1318 ReadAndAssociateImages( aStrValue
, aMenuImageId
);
1320 pMenuItem
[ OFFSET_MENUITEM_URL
].Value
<<= aStrValue
;
1321 pMenuItem
[ OFFSET_MENUITEM_TARGET
].Value
= aMenuItemNodePropValues
[ OFFSET_MENUITEM_TARGET
];
1322 pMenuItem
[ OFFSET_MENUITEM_IMAGEIDENTIFIER
].Value
<<= aMenuImageId
;
1323 pMenuItem
[ OFFSET_MENUITEM_CONTEXT
].Value
= aMenuItemNodePropValues
[ OFFSET_MENUITEM_CONTEXT
];
1324 pMenuItem
[ OFFSET_MENUITEM_SUBMENU
].Value
<<= Sequence
< Sequence
< PropertyValue
> >(); // Submenu set!
1329 else if (( aMenuItemNodePropValues
[ OFFSET_MENUITEM_URL
] >>= aStrValue
) &&
1330 aStrValue
== SEPARATOR_URL
)
1332 auto pMenuItem
= aMenuItem
.getArray();
1335 pMenuItem
[ OFFSET_MENUITEM_URL
].Value
<<= aStrValue
;
1336 pMenuItem
[ OFFSET_MENUITEM_TARGET
].Value
<<= OUString();
1337 pMenuItem
[ OFFSET_MENUITEM_IMAGEIDENTIFIER
].Value
<<= OUString();
1338 pMenuItem
[ OFFSET_MENUITEM_CONTEXT
].Value
<<= OUString();
1339 pMenuItem
[ OFFSET_MENUITEM_SUBMENU
].Value
<<= Sequence
< Sequence
< PropertyValue
> >(); // Submenu set!
1346 bool AddonsOptions_Impl::ReadPopupMenu( std::u16string_view aPopupMenuNodeName
, Sequence
< PropertyValue
>& aPopupMenu
)
1348 bool bResult
= false;
1350 OUString
aAddonPopupMenuTreeNode( aPopupMenuNodeName
+ m_aPathDelimiter
);
1352 Sequence
< Any
> aPopupMenuNodePropValues
= GetProperties( GetPropertyNamesPopupMenu( aAddonPopupMenuTreeNode
) );
1353 if (( aPopupMenuNodePropValues
[ OFFSET_POPUPMENU_TITLE
] >>= aStrValue
) &&
1354 !aStrValue
.isEmpty() )
1356 auto pPopupMenu
= aPopupMenu
.getArray();
1357 pPopupMenu
[ OFFSET_POPUPMENU_TITLE
].Value
<<= aStrValue
;
1359 OUString
aRootSubMenuName( aAddonPopupMenuTreeNode
+ m_aPropNames
[ INDEX_SUBMENU
] );
1360 Sequence
< OUString
> aRootSubMenuNodeNames
= GetNodeNames( aRootSubMenuName
);
1361 if ( aRootSubMenuNodeNames
.hasElements() )
1363 // A top-level popup menu needs a title
1364 // Set a unique prefixed Add-On popup menu URL so it can be identified later
1365 OUString aPopupMenuURL
= GeneratePrefixURL();
1367 pPopupMenu
[ OFFSET_POPUPMENU_URL
].Value
<<= aPopupMenuURL
;
1368 pPopupMenu
[ OFFSET_POPUPMENU_CONTEXT
].Value
= aPopupMenuNodePropValues
[ OFFSET_POPUPMENU_CONTEXT
];
1370 // Continue to read the sub menu nodes
1371 Sequence
< Sequence
< PropertyValue
> > aSubMenuSeq
;
1372 OUString
aSubMenuRootNodeName( aRootSubMenuName
+ m_aPathDelimiter
);
1373 for ( OUString
& rName
: asNonConstRange(aRootSubMenuNodeNames
) )
1374 rName
= aSubMenuRootNodeName
+ rName
;
1375 ReadSubMenuEntries( aRootSubMenuNodeNames
, aSubMenuSeq
);
1376 pPopupMenu
[ OFFSET_POPUPMENU_SUBMENU
].Value
<<= aSubMenuSeq
;
1384 void AddonsOptions_Impl::AppendPopupMenu( Sequence
< PropertyValue
>& rTargetPopupMenu
, const Sequence
< PropertyValue
>& rSourcePopupMenu
)
1386 Sequence
< Sequence
< PropertyValue
> > aTargetSubMenuSeq
;
1387 Sequence
< Sequence
< PropertyValue
> > aSourceSubMenuSeq
;
1389 if (( rTargetPopupMenu
[ OFFSET_POPUPMENU_SUBMENU
].Value
>>= aTargetSubMenuSeq
) &&
1390 ( rSourcePopupMenu
[ OFFSET_POPUPMENU_SUBMENU
].Value
>>= aSourceSubMenuSeq
))
1392 sal_uInt32 nIndex
= aTargetSubMenuSeq
.getLength();
1393 aTargetSubMenuSeq
.realloc( nIndex
+ aSourceSubMenuSeq
.getLength() );
1394 auto pTargetSubMenuSeq
= aTargetSubMenuSeq
.getArray();
1395 for ( Sequence
<PropertyValue
> const & rSeq
: std::as_const(aSourceSubMenuSeq
) )
1396 pTargetSubMenuSeq
[nIndex
++] = rSeq
;
1397 rTargetPopupMenu
.getArray()[ OFFSET_POPUPMENU_SUBMENU
].Value
<<= aTargetSubMenuSeq
;
1401 bool AddonsOptions_Impl::ReadToolBarItem( std::u16string_view aToolBarItemNodeName
, Sequence
< PropertyValue
>& aToolBarItem
)
1403 bool bResult
= false;
1405 OUString
aAddonToolBarItemTreeNode( aToolBarItemNodeName
+ m_aPathDelimiter
);
1407 Sequence
< Any
> aToolBarItemNodePropValues
= GetProperties( GetPropertyNamesToolBarItem( aAddonToolBarItemTreeNode
) );
1409 // A toolbar item must have a command URL
1410 if (( aToolBarItemNodePropValues
[ OFFSET_TOOLBARITEM_URL
] >>= aURL
) && !aURL
.isEmpty() )
1413 if ( aURL
== SEPARATOR_URL
)
1415 auto pToolBarItem
= aToolBarItem
.getArray();
1417 // A separator toolbar item only needs a URL
1418 pToolBarItem
[ OFFSET_TOOLBARITEM_URL
].Value
<<= aURL
;
1419 pToolBarItem
[ OFFSET_TOOLBARITEM_TITLE
].Value
<<= OUString();
1420 pToolBarItem
[ OFFSET_TOOLBARITEM_TARGET
].Value
<<= OUString();
1421 pToolBarItem
[ OFFSET_TOOLBARITEM_IMAGEIDENTIFIER
].Value
<<= OUString();
1422 pToolBarItem
[ OFFSET_TOOLBARITEM_CONTEXT
].Value
<<= OUString();
1423 pToolBarItem
[ OFFSET_TOOLBARITEM_CONTROLTYPE
].Value
<<= OUString();
1424 pToolBarItem
[ OFFSET_TOOLBARITEM_WIDTH
].Value
<<= sal_Int32( 0 );
1428 else if (( aToolBarItemNodePropValues
[ OFFSET_TOOLBARITEM_TITLE
] >>= aTitle
) && !aTitle
.isEmpty() )
1430 auto pToolBarItem
= aToolBarItem
.getArray();
1432 // A normal toolbar item must also have title => read the other properties;
1435 // Try to map a user-defined image URL to our internal private image URL
1436 aToolBarItemNodePropValues
[ OFFSET_TOOLBARITEM_IMAGEIDENTIFIER
] >>= aImageId
;
1437 ReadAndAssociateImages( aURL
, aImageId
);
1439 pToolBarItem
[ OFFSET_TOOLBARITEM_URL
].Value
<<= aURL
;
1440 pToolBarItem
[ OFFSET_TOOLBARITEM_TITLE
].Value
<<= aTitle
;
1441 pToolBarItem
[ OFFSET_TOOLBARITEM_TARGET
].Value
= aToolBarItemNodePropValues
[ OFFSET_TOOLBARITEM_TARGET
];
1442 pToolBarItem
[ OFFSET_TOOLBARITEM_IMAGEIDENTIFIER
].Value
<<= aImageId
;
1443 pToolBarItem
[ OFFSET_TOOLBARITEM_CONTEXT
].Value
= aToolBarItemNodePropValues
[ OFFSET_TOOLBARITEM_CONTEXT
];
1444 pToolBarItem
[ OFFSET_TOOLBARITEM_CONTROLTYPE
].Value
= aToolBarItemNodePropValues
[ OFFSET_TOOLBARITEM_CONTROLTYPE
];
1446 // Configuration uses hyper for long. Therefore transform into sal_Int32
1447 sal_Int64
nValue( 0 );
1448 aToolBarItemNodePropValues
[ OFFSET_TOOLBARITEM_WIDTH
] >>= nValue
;
1449 pToolBarItem
[ OFFSET_TOOLBARITEM_WIDTH
].Value
<<= sal_Int32( nValue
);
1458 bool AddonsOptions_Impl::ReadNotebookBarItem( std::u16string_view aNotebookBarItemNodeName
, Sequence
< PropertyValue
>& aNotebookBarItem
)
1460 bool bResult
= false;
1462 OUString
aAddonNotebookBarItemTreeNode( aNotebookBarItemNodeName
+ m_aPathDelimiter
);
1464 Sequence
< Any
> aNotebookBarItemNodePropValues
= GetProperties( GetPropertyNamesNotebookBarItem( aAddonNotebookBarItemTreeNode
) );
1466 // A toolbar item must have a command URL
1467 if (( aNotebookBarItemNodePropValues
[ OFFSET_NOTEBOOKBARITEM_URL
] >>= aURL
) && !aURL
.isEmpty() )
1470 if ( aURL
== SEPARATOR_URL
)
1472 auto pNotebookBarItem
= aNotebookBarItem
.getArray();
1474 // A separator toolbar item only needs a URL
1475 pNotebookBarItem
[ OFFSET_NOTEBOOKBARITEM_URL
].Value
<<= aURL
;
1476 pNotebookBarItem
[ OFFSET_NOTEBOOKBARITEM_TITLE
].Value
<<= OUString();
1477 pNotebookBarItem
[ OFFSET_NOTEBOOKBARITEM_TARGET
].Value
<<= OUString();
1478 pNotebookBarItem
[ OFFSET_NOTEBOOKBARITEM_IMAGEIDENTIFIER
].Value
<<= OUString();
1479 pNotebookBarItem
[ OFFSET_NOTEBOOKBARITEM_CONTEXT
].Value
<<= OUString();
1480 pNotebookBarItem
[ OFFSET_NOTEBOOKBARITEM_CONTROLTYPE
].Value
<<= OUString();
1481 pNotebookBarItem
[ OFFSET_NOTEBOOKBARITEM_WIDTH
].Value
<<= sal_Int32( 0 );
1482 pNotebookBarItem
[ OFFSET_NOTEBOOKBARITEM_STYLE
].Value
<<= OUString();
1486 else if (( aNotebookBarItemNodePropValues
[ OFFSET_NOTEBOOKBARITEM_TITLE
] >>= aTitle
) && !aTitle
.isEmpty() )
1488 auto pNotebookBarItem
= aNotebookBarItem
.getArray();
1490 // A normal toolbar item must also have title => read the other properties;
1493 // Try to map a user-defined image URL to our internal private image URL
1494 aNotebookBarItemNodePropValues
[ OFFSET_NOTEBOOKBARITEM_IMAGEIDENTIFIER
] >>= aImageId
;
1495 ReadAndAssociateImages( aURL
, aImageId
);
1497 pNotebookBarItem
[ OFFSET_NOTEBOOKBARITEM_URL
].Value
<<= aURL
;
1498 pNotebookBarItem
[ OFFSET_NOTEBOOKBARITEM_TITLE
].Value
<<= aTitle
;
1499 pNotebookBarItem
[ OFFSET_NOTEBOOKBARITEM_TARGET
].Value
= aNotebookBarItemNodePropValues
[ OFFSET_NOTEBOOKBARITEM_TARGET
];
1500 pNotebookBarItem
[ OFFSET_NOTEBOOKBARITEM_IMAGEIDENTIFIER
].Value
<<= aImageId
;
1501 pNotebookBarItem
[ OFFSET_NOTEBOOKBARITEM_CONTEXT
].Value
= aNotebookBarItemNodePropValues
[ OFFSET_NOTEBOOKBARITEM_CONTEXT
];
1502 pNotebookBarItem
[ OFFSET_NOTEBOOKBARITEM_CONTROLTYPE
].Value
= aNotebookBarItemNodePropValues
[ OFFSET_NOTEBOOKBARITEM_CONTROLTYPE
];
1504 // Configuration uses hyper for long. Therefore transform into sal_Int32
1505 sal_Int64
nValue( 0 );
1506 aNotebookBarItemNodePropValues
[ OFFSET_NOTEBOOKBARITEM_WIDTH
] >>= nValue
;
1507 pNotebookBarItem
[ OFFSET_NOTEBOOKBARITEM_WIDTH
].Value
<<= sal_Int32( nValue
);
1508 pNotebookBarItem
[ OFFSET_NOTEBOOKBARITEM_STYLE
].Value
= aNotebookBarItemNodePropValues
[ OFFSET_NOTEBOOKBARITEM_STYLE
];
1517 void AddonsOptions_Impl::ReadSubMenuEntries( const Sequence
< OUString
>& aSubMenuNodeNames
, Sequence
< Sequence
< PropertyValue
> >& rSubMenuSeq
)
1519 Sequence
< PropertyValue
> aMenuItem( PROPERTYCOUNT_MENUITEM
);
1520 auto pMenuItem
= aMenuItem
.getArray();
1522 // Init the property value sequence
1523 pMenuItem
[ OFFSET_MENUITEM_URL
].Name
= PROPERTYNAME_URL
;
1524 pMenuItem
[ OFFSET_MENUITEM_TITLE
].Name
= PROPERTYNAME_TITLE
;
1525 pMenuItem
[ OFFSET_MENUITEM_TARGET
].Name
= PROPERTYNAME_TARGET
;
1526 pMenuItem
[ OFFSET_MENUITEM_IMAGEIDENTIFIER
].Name
= PROPERTYNAME_IMAGEIDENTIFIER
;
1527 pMenuItem
[ OFFSET_MENUITEM_CONTEXT
].Name
= PROPERTYNAME_CONTEXT
;
1528 pMenuItem
[ OFFSET_MENUITEM_SUBMENU
].Name
= PROPERTYNAME_SUBMENU
; // Submenu set!
1530 sal_uInt32 nIndex
= 0;
1531 sal_uInt32 nCount
= aSubMenuNodeNames
.getLength();
1532 for ( sal_uInt32 n
= 0; n
< nCount
; n
++ )
1534 if ( ReadMenuItem( aSubMenuNodeNames
[n
], aMenuItem
))
1536 sal_uInt32 nSubMenuCount
= rSubMenuSeq
.getLength() + 1;
1537 rSubMenuSeq
.realloc( nSubMenuCount
);
1538 rSubMenuSeq
.getArray()[nIndex
++] = aMenuItem
;
1543 bool AddonsOptions_Impl::HasAssociatedImages( const OUString
& aURL
)
1545 // FIXME: potentially this is not so useful in a world of delayed image loading
1546 ImageManager::const_iterator pIter
= m_aImageManager
.find( aURL
);
1547 return ( pIter
!= m_aImageManager
.end() );
1550 void AddonsOptions_Impl::SubstituteVariables( OUString
& aURL
)
1552 aURL
= comphelper::getExpandedUri(
1553 comphelper::getProcessComponentContext(), aURL
);
1556 BitmapEx
AddonsOptions_Impl::ReadImageFromURL(const OUString
& aImageURL
)
1560 std::unique_ptr
<SvStream
> pStream
= UcbStreamHelper::CreateStream( aImageURL
, StreamMode::STD_READ
);
1561 if ( pStream
&& ( pStream
->GetErrorCode() == ERRCODE_NONE
))
1563 // Use graphic class to also support more graphic formats (bmp,png,...)
1566 GraphicFilter
& rGF
= GraphicFilter::GetGraphicFilter();
1567 rGF
.ImportGraphic( aGraphic
, u
"", *pStream
);
1569 BitmapEx aBitmapEx
= aGraphic
.GetBitmapEx();
1571 Size aBmpSize
= aBitmapEx
.GetSizePixel();
1572 if ( !aBmpSize
.IsEmpty() )
1574 // Support non-transparent bitmaps to be downward compatible with OOo 1.1.x addons
1575 if( !aBitmapEx
.IsAlpha() )
1576 aBitmapEx
= BitmapEx( aBitmapEx
.GetBitmap(), COL_LIGHTMAGENTA
);
1585 void AddonsOptions_Impl::ReadAndAssociateImages( const OUString
& aURL
, const OUString
& aImageId
)
1587 if ( aImageId
.isEmpty() )
1590 ImageEntry aImageEntry
;
1591 OUString
aImageURL( aImageId
);
1593 SubstituteVariables( aImageURL
);
1595 // Loop to create the two possible image names and try to read the bitmap files
1596 static const char* aExtArray
[] = { "_16", "_26" };
1597 for ( size_t i
= 0; i
< std::size(aExtArray
); i
++ )
1599 OUStringBuffer
aFileURL( aImageURL
);
1600 aFileURL
.appendAscii( aExtArray
[i
] );
1601 aFileURL
.append( ".bmp" );
1603 aImageEntry
.addImage( !i
? IMGSIZE_SMALL
: IMGSIZE_BIG
, aFileURL
.makeStringAndClear() );
1606 m_aImageManager
.emplace( aURL
, aImageEntry
);
1609 std::unique_ptr
<AddonsOptions_Impl::ImageEntry
> AddonsOptions_Impl::ReadImageData( std::u16string_view aImagesNodeName
)
1611 Sequence
< OUString
> aImageDataNodeNames
= GetPropertyNamesImages( aImagesNodeName
);
1612 Sequence
< Any
> aPropertyData
;
1613 Sequence
< sal_Int8
> aImageDataSeq
;
1616 std::unique_ptr
<ImageEntry
> pEntry
;
1618 // It is possible to use both forms (embedded image data and URLs to external bitmap files) at the
1619 // same time. Embedded image data has a higher priority.
1620 aPropertyData
= GetProperties( aImageDataNodeNames
);
1621 for ( int i
= 0; i
< PROPERTYCOUNT_IMAGES
; i
++ )
1623 if ( i
< PROPERTYCOUNT_EMBEDDED_IMAGES
)
1625 // Extract image data from the embedded hex binary sequence
1627 if (( aPropertyData
[i
] >>= aImageDataSeq
) &&
1628 aImageDataSeq
.hasElements() &&
1629 ( CreateImageFromSequence( aImage
, aImageDataSeq
) ) )
1632 pEntry
.reset(new ImageEntry
);
1633 pEntry
->addImage(i
== OFFSET_IMAGES_SMALL
? IMGSIZE_SMALL
: IMGSIZE_BIG
, aImage
);
1636 else if ( i
== OFFSET_IMAGES_SMALL_URL
|| i
== OFFSET_IMAGES_BIG_URL
)
1639 pEntry
.reset(new ImageEntry());
1641 // Retrieve image data from an external bitmap file. Make sure that embedded image data
1642 // has a higher priority.
1643 if (aPropertyData
[i
] >>= aImageURL
)
1645 SubstituteVariables(aImageURL
);
1646 pEntry
->addImage(i
== OFFSET_IMAGES_SMALL_URL
? IMGSIZE_SMALL
: IMGSIZE_BIG
, aImageURL
);
1654 bool AddonsOptions_Impl::CreateImageFromSequence( BitmapEx
& rImage
, Sequence
< sal_Int8
>& rBitmapDataSeq
) const
1656 bool bResult
= false;
1658 if ( rBitmapDataSeq
.hasElements() )
1660 SvMemoryStream
aMemStream( rBitmapDataSeq
.getArray(), rBitmapDataSeq
.getLength(), StreamMode::STD_READ
);
1662 ReadDIBBitmapEx(rImage
, aMemStream
);
1664 if( !rImage
.IsAlpha() )
1666 // Support non-transparent bitmaps to be downward compatible with OOo 1.1.x addons
1667 rImage
= BitmapEx( rImage
.GetBitmap(), COL_LIGHTMAGENTA
);
1676 Sequence
< OUString
> AddonsOptions_Impl::GetPropertyNamesMenuItem( std::u16string_view aPropertyRootNode
) const
1678 Sequence
< OUString
> lResult( PROPERTYCOUNT_MENUITEM
);
1679 auto plResult
= lResult
.getArray();
1681 // Create property names dependent from the root node name
1682 plResult
[OFFSET_MENUITEM_URL
] = aPropertyRootNode
+ m_aPropNames
[ INDEX_URL
];
1683 plResult
[OFFSET_MENUITEM_TITLE
] = aPropertyRootNode
+ m_aPropNames
[ INDEX_TITLE
];
1684 plResult
[OFFSET_MENUITEM_IMAGEIDENTIFIER
] = aPropertyRootNode
+ m_aPropNames
[ INDEX_IMAGEIDENTIFIER
];
1685 plResult
[OFFSET_MENUITEM_TARGET
] = aPropertyRootNode
+ m_aPropNames
[ INDEX_TARGET
];
1686 plResult
[OFFSET_MENUITEM_CONTEXT
] = aPropertyRootNode
+ m_aPropNames
[ INDEX_CONTEXT
];
1687 plResult
[OFFSET_MENUITEM_SUBMENU
] = aPropertyRootNode
+ m_aPropNames
[ INDEX_SUBMENU
];
1692 Sequence
< OUString
> AddonsOptions_Impl::GetPropertyNamesPopupMenu( std::u16string_view aPropertyRootNode
) const
1694 // The URL is automatically set and not read from the configuration.
1695 Sequence
< OUString
> lResult( PROPERTYCOUNT_POPUPMENU
-1 );
1696 auto plResult
= lResult
.getArray();
1698 // Create property names dependent from the root node name
1699 plResult
[OFFSET_POPUPMENU_TITLE
] = aPropertyRootNode
+ m_aPropNames
[ INDEX_TITLE
];
1700 plResult
[OFFSET_POPUPMENU_CONTEXT
] = aPropertyRootNode
+ m_aPropNames
[ INDEX_CONTEXT
];
1701 plResult
[OFFSET_POPUPMENU_SUBMENU
] = aPropertyRootNode
+ m_aPropNames
[ INDEX_SUBMENU
];
1706 Sequence
< OUString
> AddonsOptions_Impl::GetPropertyNamesToolBarItem( std::u16string_view aPropertyRootNode
) const
1708 Sequence
< OUString
> lResult( PROPERTYCOUNT_TOOLBARITEM
);
1709 auto plResult
= lResult
.getArray();
1711 // Create property names dependent from the root node name
1712 plResult
[0] = aPropertyRootNode
+ m_aPropNames
[ INDEX_URL
];
1713 plResult
[1] = aPropertyRootNode
+ m_aPropNames
[ INDEX_TITLE
];
1714 plResult
[2] = aPropertyRootNode
+ m_aPropNames
[ INDEX_IMAGEIDENTIFIER
];
1715 plResult
[3] = aPropertyRootNode
+ m_aPropNames
[ INDEX_TARGET
];
1716 plResult
[4] = aPropertyRootNode
+ m_aPropNames
[ INDEX_CONTEXT
];
1717 plResult
[5] = aPropertyRootNode
+ m_aPropNames
[ INDEX_CONTROLTYPE
];
1718 plResult
[6] = aPropertyRootNode
+ m_aPropNames
[ INDEX_WIDTH
];
1723 Sequence
< OUString
> AddonsOptions_Impl::GetPropertyNamesNotebookBarItem( std::u16string_view aPropertyRootNode
) const
1725 Sequence
< OUString
> lResult( PROPERTYCOUNT_NOTEBOOKBARITEM
);
1726 auto plResult
= lResult
.getArray();
1728 // Create property names dependent from the root node name
1729 plResult
[0] = aPropertyRootNode
+ m_aPropNames
[ INDEX_URL
];
1730 plResult
[1] = aPropertyRootNode
+ m_aPropNames
[ INDEX_TITLE
];
1731 plResult
[2] = aPropertyRootNode
+ m_aPropNames
[ INDEX_IMAGEIDENTIFIER
];
1732 plResult
[3] = aPropertyRootNode
+ m_aPropNames
[ INDEX_TARGET
];
1733 plResult
[4] = aPropertyRootNode
+ m_aPropNames
[ INDEX_CONTEXT
];
1734 plResult
[5] = aPropertyRootNode
+ m_aPropNames
[ INDEX_CONTROLTYPE
];
1735 plResult
[6] = aPropertyRootNode
+ m_aPropNames
[ INDEX_WIDTH
];
1736 plResult
[7] = aPropertyRootNode
+ m_aPropNames
[ INDEX_STYLE
];
1741 Sequence
< OUString
> AddonsOptions_Impl::GetPropertyNamesStatusbarItem(
1742 std::u16string_view aPropertyRootNode
) const
1744 Sequence
< OUString
> lResult( PROPERTYCOUNT_STATUSBARITEM
);
1745 auto plResult
= lResult
.getArray();
1747 plResult
[0] = OUString( aPropertyRootNode
+ m_aPropNames
[ INDEX_URL
] );
1748 plResult
[1] = OUString( aPropertyRootNode
+ m_aPropNames
[ INDEX_TITLE
] );
1749 plResult
[2] = OUString( aPropertyRootNode
+ m_aPropNames
[ INDEX_CONTEXT
] );
1750 plResult
[3] = OUString( aPropertyRootNode
+ m_aPropNames
[ INDEX_ALIGN
] );
1751 plResult
[4] = OUString( aPropertyRootNode
+ m_aPropNames
[ INDEX_AUTOSIZE
] );
1752 plResult
[5] = OUString( aPropertyRootNode
+ m_aPropNames
[ INDEX_OWNERDRAW
] );
1753 plResult
[6] = OUString( aPropertyRootNode
+ m_aPropNames
[ INDEX_MANDATORY
] );
1754 plResult
[7] = OUString( aPropertyRootNode
+ m_aPropNames
[ INDEX_WIDTH
] );
1759 Sequence
< OUString
> AddonsOptions_Impl::GetPropertyNamesImages( std::u16string_view aPropertyRootNode
) const
1761 Sequence
< OUString
> lResult( PROPERTYCOUNT_IMAGES
);
1762 auto plResult
= lResult
.getArray();
1764 // Create property names dependent from the root node name
1765 plResult
[0] = aPropertyRootNode
+ m_aPropImagesNames
[ OFFSET_IMAGES_SMALL
];
1766 plResult
[1] = aPropertyRootNode
+ m_aPropImagesNames
[ OFFSET_IMAGES_BIG
];
1767 plResult
[2] = aPropertyRootNode
+ m_aPropImagesNames
[ OFFSET_IMAGES_SMALLHC
];
1768 plResult
[3] = aPropertyRootNode
+ m_aPropImagesNames
[ OFFSET_IMAGES_BIGHC
];
1769 plResult
[4] = aPropertyRootNode
+ m_aPropImagesNames
[ OFFSET_IMAGES_SMALL_URL
];
1770 plResult
[5] = aPropertyRootNode
+ m_aPropImagesNames
[ OFFSET_IMAGES_BIG_URL
];
1771 plResult
[6] = aPropertyRootNode
+ m_aPropImagesNames
[ OFFSET_IMAGES_SMALLHC_URL
];
1772 plResult
[7] = aPropertyRootNode
+ m_aPropImagesNames
[ OFFSET_IMAGES_BIGHC_URL
];
1779 std::weak_ptr
<AddonsOptions_Impl
> g_pAddonsOptions
;
1782 AddonsOptions::AddonsOptions()
1784 // Global access, must be guarded (multithreading!).
1785 MutexGuard
aGuard( GetOwnStaticMutex() );
1787 m_pImpl
= g_pAddonsOptions
.lock();
1790 m_pImpl
= std::make_shared
<AddonsOptions_Impl
>();
1791 g_pAddonsOptions
= m_pImpl
;
1795 AddonsOptions::~AddonsOptions()
1797 // Global access, must be guarded (multithreading!)
1798 MutexGuard
aGuard( GetOwnStaticMutex() );
1805 bool AddonsOptions::HasAddonsMenu() const
1807 MutexGuard
aGuard( GetOwnStaticMutex() );
1808 return m_pImpl
->HasAddonsMenu();
1813 sal_Int32
AddonsOptions::GetAddonsToolBarCount() const
1815 MutexGuard
aGuard( GetOwnStaticMutex() );
1816 return m_pImpl
->GetAddonsToolBarCount();
1821 sal_Int32
AddonsOptions::GetAddonsNotebookBarCount() const
1823 MutexGuard
aGuard( GetOwnStaticMutex() );
1824 return m_pImpl
->GetAddonsNotebookBarCount();
1829 const Sequence
< Sequence
< PropertyValue
> >& AddonsOptions::GetAddonsMenu() const
1831 MutexGuard
aGuard( GetOwnStaticMutex() );
1832 return m_pImpl
->GetAddonsMenu();
1837 const Sequence
< Sequence
< PropertyValue
> >& AddonsOptions::GetAddonsMenuBarPart() const
1839 MutexGuard
aGuard( GetOwnStaticMutex() );
1840 return m_pImpl
->GetAddonsMenuBarPart();
1845 const Sequence
< Sequence
< PropertyValue
> >& AddonsOptions::GetAddonsToolBarPart( sal_uInt32 nIndex
) const
1847 MutexGuard
aGuard( GetOwnStaticMutex() );
1848 return m_pImpl
->GetAddonsToolBarPart( nIndex
);
1853 const Sequence
< Sequence
< PropertyValue
> >& AddonsOptions::GetAddonsNotebookBarPart( sal_uInt32 nIndex
) const
1855 MutexGuard
aGuard( GetOwnStaticMutex() );
1856 return m_pImpl
->GetAddonsNotebookBarPart( nIndex
);
1861 OUString
AddonsOptions::GetAddonsToolbarResourceName( sal_uInt32 nIndex
) const
1863 MutexGuard
aGuard( GetOwnStaticMutex() );
1864 return m_pImpl
->GetAddonsToolbarResourceName( nIndex
);
1869 OUString
AddonsOptions::GetAddonsNotebookBarResourceName( sal_uInt32 nIndex
) const
1871 MutexGuard
aGuard( GetOwnStaticMutex() );
1872 return m_pImpl
->GetAddonsNotebookBarResourceName( nIndex
);
1877 const Sequence
< Sequence
< PropertyValue
> >& AddonsOptions::GetAddonsHelpMenu() const
1879 MutexGuard
aGuard( GetOwnStaticMutex() );
1880 return m_pImpl
->GetAddonsHelpMenu();
1885 const MergeMenuInstructionContainer
& AddonsOptions::GetMergeMenuInstructions() const
1887 MutexGuard
aGuard( GetOwnStaticMutex() );
1888 return m_pImpl
->GetMergeMenuInstructions();
1893 bool AddonsOptions::GetMergeToolbarInstructions(
1894 const OUString
& rToolbarName
,
1895 MergeToolbarInstructionContainer
& rToolbarInstructions
) const
1897 MutexGuard
aGuard( GetOwnStaticMutex() );
1898 return m_pImpl
->GetMergeToolbarInstructions(
1899 rToolbarName
, rToolbarInstructions
);
1904 bool AddonsOptions::GetMergeNotebookBarInstructions(
1905 const OUString
& rNotebookBarName
,
1906 MergeNotebookBarInstructionContainer
& rNotebookBarInstructions
) const
1908 MutexGuard
aGuard( GetOwnStaticMutex() );
1909 return m_pImpl
->GetMergeNotebookBarInstructions(
1910 rNotebookBarName
, rNotebookBarInstructions
);
1915 const MergeStatusbarInstructionContainer
& AddonsOptions::GetMergeStatusbarInstructions() const
1917 MutexGuard
aGuard( GetOwnStaticMutex() );
1918 return m_pImpl
->GetMergeStatusbarInstructions();
1923 BitmapEx
AddonsOptions::GetImageFromURL( const OUString
& aURL
, bool bBig
, bool bNoScale
) const
1925 MutexGuard
aGuard( GetOwnStaticMutex() );
1926 return m_pImpl
->GetImageFromURL( aURL
, bBig
, bNoScale
);
1931 BitmapEx
AddonsOptions::GetImageFromURL( const OUString
& aURL
, bool bBig
) const
1933 return GetImageFromURL( aURL
, bBig
, false );
1936 Mutex
& AddonsOptions::GetOwnStaticMutex()
1938 // Create static mutex variable.
1939 static Mutex ourMutex
;
1944 IMPL_LINK_NOARG(AddonsOptions_Impl
, NotifyEvent
, void*, void)
1946 MutexGuard
aGuard(AddonsOptions::GetOwnStaticMutex());
1947 ReadConfigurationData();
1952 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */