1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 // MARKER(update_precomp.py): autogen include statement, do not remove
23 #include "precompiled_framework.hxx"
24 
25 //_________________________________________________________________________________________________________________
26 //	includes
27 //_________________________________________________________________________________________________________________
28 #include <framework/addonsoptions.hxx>
29 #include <unotools/configmgr.hxx>
30 #include <unotools/configitem.hxx>
31 #include <unotools/ucbstreamhelper.hxx>
32 #include <tools/debug.hxx>
33 #include <tools/stream.hxx>
34 #include <tools/color.hxx>
35 #include <com/sun/star/uno/Any.hxx>
36 #include <com/sun/star/uno/Sequence.hxx>
37 #include "com/sun/star/util/XMacroExpander.hpp"
38 #include "com/sun/star/uno/XComponentContext.hpp"
39 #include "com/sun/star/beans/XPropertySet.hpp"
40 #include <rtl/ustrbuf.hxx>
41 #include <rtl/uri.hxx>
42 #include <comphelper/processfactory.hxx>
43 #include <vcl/graph.hxx>
44 #include <svtools/filter.hxx>
45 #include <vcl/dibtools.hxx>
46 #include <hash_map>
47 #include <algorithm>
48 #include <vector>
49 
50 //_________________________________________________________________________________________________________________
51 //	namespaces
52 //_________________________________________________________________________________________________________________
53 
54 using namespace ::std					;
55 using namespace ::utl					;
56 using namespace ::osl					;
57 using namespace ::com::sun::star::uno	;
58 using namespace ::com::sun::star::beans	;
59 using namespace ::com::sun::star::lang	;
60 
61 //_________________________________________________________________________________________________________________
62 //	const
63 //_________________________________________________________________________________________________________________
64 
65 #define STR_TOOLBARITEMS    "ToolBarItems"
66 
67 #define ROOTNODE_ADDONMENU                              ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Office.Addons"	))
68 #define PATHDELIMITER                                   ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/"				))
69 #define TOOLBARITEMS									::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(STR_TOOLBARITEMS))
70 #define SEPARATOR_URL_STR								"private:separator"
71 #define SEPARATOR_URL_LEN								17
72 #define SEPARATOR_URL									::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( SEPARATOR_URL_STR ))
73 
74 #define PROPERTYNAME_URL                                ADDONSMENUITEM_PROPERTYNAME_URL
75 #define PROPERTYNAME_TITLE                              ADDONSMENUITEM_PROPERTYNAME_TITLE
76 #define PROPERTYNAME_TARGET                             ADDONSMENUITEM_PROPERTYNAME_TARGET
77 #define PROPERTYNAME_IMAGEIDENTIFIER                    ADDONSMENUITEM_PROPERTYNAME_IMAGEIDENTIFIER
78 #define PROPERTYNAME_CONTEXT							ADDONSMENUITEM_PROPERTYNAME_CONTEXT
79 #define PROPERTYNAME_SUBMENU							ADDONSMENUITEM_PROPERTYNAME_SUBMENU
80 #define PROPERTYNAME_CONTROLTYPE                        ADDONSMENUITEM_PROPERTYNAME_CONTROLTYPE
81 #define PROPERTYNAME_WIDTH                              ADDONSMENUITEM_PROPERTYNAME_WIDTH
82 #define PROPERTYNAME_TOOLBARITEMS                       TOOLBARITEMS
83 
84 #define PROPERTYNAME_ALIGN                              STATUSBARITEM_PROPERTYNAME_ALIGN
85 #define PROPERTYNAME_AUTOSIZE                           STATUSBARITEM_PROPERTYNAME_AUTOSIZE
86 #define PROPERTYNAME_OWNERDRAW                          STATUSBARITEM_PROPERTYNAME_OWNERDRAW
87 
88 #define PROPERTYNAME_IMAGESMALL							::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ImageSmall" ))
89 #define PROPERTYNAME_IMAGEBIG							::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ImageBig" ))
90 #define PROPERTYNAME_IMAGESMALLHC						::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ImageSmallHC" ))
91 #define PROPERTYNAME_IMAGEBIGHC							::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ImageBigHC" ))
92 #define PROPERTYNAME_IMAGESMALL_URL						::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ImageSmallURL" ))
93 #define PROPERTYNAME_IMAGEBIG_URL						::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ImageBigURL" ))
94 #define PROPERTYNAME_IMAGESMALLHC_URL					::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ImageSmallHCURL" ))
95 #define PROPERTYNAME_IMAGEBIGHC_URL						::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ImageBigHCURL" ))
96 
97 #define IMAGES_NODENAME									::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("UserDefinedImages" ))
98 #define PRIVATE_IMAGE_URL                               ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("private:image/" ))
99 
100 #define PROPERTYNAME_MERGEMENU_MERGEPOINT               ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("MergePoint" ))
101 #define PROPERTYNAME_MERGEMENU_MERGECOMMAND             ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("MergeCommand" ))
102 #define PROPERTYNAME_MERGEMENU_MERGECOMMANDPARAMETER    ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("MergeCommandParameter" ))
103 #define PROPERTYNAME_MERGEMENU_MERGEFALLBACK            ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("MergeFallback" ))
104 #define PROPERTYNAME_MERGEMENU_MERGECONTEXT             ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("MergeContext" ))
105 #define PROPERTYNAME_MERGEMENU_MENUITEMS                ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("MenuItems" ))
106 #define MERGEMENU_MERGEPOINT_SEPARATOR                  '\\'
107 
108 #define PROPERTYNAME_MERGETOOLBAR_TOOLBAR               ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("MergeToolBar" ))
109 #define PROPERTYNAME_MERGETOOLBAR_MERGEPOINT            ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("MergePoint" ))
110 #define PROPERTYNAME_MERGETOOLBAR_MERGECOMMAND          ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("MergeCommand" ))
111 #define PROPERTYNAME_MERGETOOLBAR_MERGECOMMANDPARAMETER ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("MergeCommandParameter" ))
112 #define PROPERTYNAME_MERGETOOLBAR_MERGEFALLBACK         ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("MergeFallback" ))
113 #define PROPERTYNAME_MERGETOOLBAR_MERGECONTEXT          ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("MergeContext" ))
114 #define PROPERTYNAME_MERGETOOLBAR_TOOLBARITEMS          ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(STR_TOOLBARITEMS ))
115 
116 #define PROPERTYNAME_MERGESTATUSBAR_MERGEPOINT               ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("MergePoint" ))
117 #define PROPERTYNAME_MERGESTATUSBAR_MERGECOMMAND             ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("MergeCommand" ))
118 #define PROPERTYNAME_MERGESTATUSBAR_MERGECOMMANDPARAMETER    ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("MergeCommandParameter" ))
119 #define PROPERTYNAME_MERGESTATUSBAR_MERGEFALLBACK            ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("MergeFallback" ))
120 #define PROPERTYNAME_MERGESTATUSBAR_MERGECONTEXT             ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("MergeContext" ))
121 #define PROPERTYNAME_MERGESTATUSBAR_STATUSBARITEMS           ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("StatusBarItems" ))
122 
123 // The following order is mandatory. Please add properties at the end!
124 #define INDEX_URL               0
125 #define INDEX_TITLE             1
126 #define INDEX_IMAGEIDENTIFIER   2
127 #define INDEX_TARGET            3
128 #define INDEX_CONTEXT           4
129 #define INDEX_SUBMENU           5
130 #define INDEX_CONTROLTYPE       6
131 #define INDEX_WIDTH             7
132 #define INDEX_ALIGN             8
133 #define INDEX_AUTOSIZE          9
134 #define INDEX_OWNERDRAW         10
135 #define INDEX_TOOLBARITEMS      11
136 #define PROPERTYCOUNT_INDEX     12
137 
138 // The following order is mandatory. Please add properties at the end!
139 #define PROPERTYCOUNT_MENUITEM							6
140 #define OFFSET_MENUITEM_URL                             0
141 #define OFFSET_MENUITEM_TITLE                           1
142 #define OFFSET_MENUITEM_IMAGEIDENTIFIER					2
143 #define OFFSET_MENUITEM_TARGET							3
144 #define OFFSET_MENUITEM_CONTEXT							4
145 #define OFFSET_MENUITEM_SUBMENU							5
146 
147 // The following order is mandatory. Please add properties at the end!
148 #define PROPERTYCOUNT_POPUPMENU							4
149 #define OFFSET_POPUPMENU_TITLE							0
150 #define OFFSET_POPUPMENU_CONTEXT						1
151 #define OFFSET_POPUPMENU_SUBMENU						2
152 #define OFFSET_POPUPMENU_URL							3	// Used for property set
153 
154 // The following order is mandatory. Please add properties at the end!
155 #define PROPERTYCOUNT_TOOLBAR                           2
156 #define OFFSET_TOOLBAR_TITLE                            0
157 #define OFFSET_TOOLBAR_TOOLBARITEMS                     1
158 
159 // The following order is mandatory. Please add properties at the end!
160 #define PROPERTYCOUNT_TOOLBARITEM						7
161 #define OFFSET_TOOLBARITEM_URL							0
162 #define OFFSET_TOOLBARITEM_TITLE						1
163 #define OFFSET_TOOLBARITEM_IMAGEIDENTIFIER				2
164 #define OFFSET_TOOLBARITEM_TARGET						3
165 #define OFFSET_TOOLBARITEM_CONTEXT						4
166 #define OFFSET_TOOLBARITEM_CONTROLTYPE                  5
167 #define OFFSET_TOOLBARITEM_WIDTH                        6
168 
169 // The following order is mandatory. Please add properties at the end!
170 #define PROPERTYCOUNT_STATUSBARITEM                     7
171 #define OFFSET_STATUSBARITEM_URL                        0
172 #define OFFSET_STATUSBARITEM_TITLE                      1
173 #define OFFSET_STATUSBARITEM_CONTEXT                    2
174 #define OFFSET_STATUSBARITEM_ALIGN                      3
175 #define OFFSET_STATUSBARITEM_AUTOSIZE                   4
176 #define OFFSET_STATUSBARITEM_OWNERDRAW                  5
177 #define OFFSET_STATUSBARITEM_WIDTH                      6
178 
179 
180 // The following order is mandatory. Please add properties at the end!
181 #define PROPERTYCOUNT_IMAGES							8
182 #define PROPERTYCOUNT_EMBEDDED_IMAGES                   4
183 #define OFFSET_IMAGES_SMALL								0
184 #define OFFSET_IMAGES_BIG								1
185 #define OFFSET_IMAGES_SMALLHC							2
186 #define OFFSET_IMAGES_BIGHC								3
187 #define OFFSET_IMAGES_SMALL_URL							4
188 #define OFFSET_IMAGES_BIG_URL							5
189 #define OFFSET_IMAGES_SMALLHC_URL						6
190 #define OFFSET_IMAGES_BIGHC_URL							7
191 
192 #define PROPERTYCOUNT_MERGE_MENUBAR                     6
193 #define OFFSET_MERGEMENU_MERGEPOINT                     0
194 #define OFFSET_MERGEMENU_MERGECOMMAND                   1
195 #define OFFSET_MERGEMENU_MERGECOMMANDPARAMETER          2
196 #define OFFSET_MERGEMENU_MERGEFALLBACK                  3
197 #define OFFSET_MERGEMENU_MERGECONTEXT                   4
198 #define OFFSET_MERGEMENU_MENUITEMS                      5
199 
200 #define PROPERTYCOUNT_MERGE_TOOLBAR                     7
201 #define OFFSET_MERGETOOLBAR_TOOLBAR                     0
202 #define OFFSET_MERGETOOLBAR_MERGEPOINT                  1
203 #define OFFSET_MERGETOOLBAR_MERGECOMMAND                2
204 #define OFFSET_MERGETOOLBAR_MERGECOMMANDPARAMETER       3
205 #define OFFSET_MERGETOOLBAR_MERGEFALLBACK               4
206 #define OFFSET_MERGETOOLBAR_MERGECONTEXT                5
207 #define OFFSET_MERGETOOLBAR_TOOLBARITEMS                6
208 
209 #define PROPERTYCOUNT_MERGE_STATUSBAR                   6
210 #define OFFSET_MERGESTATUSBAR_MERGEPOINT                0
211 #define OFFSET_MERGESTATUSBAR_MERGECOMMAND              1
212 #define OFFSET_MERGESTATUSBAR_MERGECOMMANDPARAMETER     2
213 #define OFFSET_MERGESTATUSBAR_MERGEFALLBACK             3
214 #define OFFSET_MERGESTATUSBAR_MERGECONTEXT              4
215 #define OFFSET_MERGESTATUSBAR_STATUSBARITEMS            5
216 
217 #define EXPAND_PROTOCOL                                 "vnd.sun.star.expand:"
218 
219 const Size  aImageSizeSmall( 16, 16 );
220 const Size  aImageSizeBig( 26, 26 );
221 
222 //_________________________________________________________________________________________________________________
223 //	private declarations!
224 //_________________________________________________________________________________________________________________
225 
226 /*-****************************************************************************************************************
227     @descr  struct to hold information about one menu entry.
228 ****************************************************************************************************************-*/
229 
230 namespace framework
231 {
232 
233 class AddonsOptions_Impl : public ConfigItem
234 {
235 	//-------------------------------------------------------------------------------------------------------------
236 	//	public methods
237 	//-------------------------------------------------------------------------------------------------------------
238 
239 	public:
240 		//---------------------------------------------------------------------------------------------------------
241 		//	constructor / destructor
242 		//---------------------------------------------------------------------------------------------------------
243 
244          AddonsOptions_Impl();
245         ~AddonsOptions_Impl();
246 
247 		//---------------------------------------------------------------------------------------------------------
248 		//	overloaded methods of baseclass
249 		//---------------------------------------------------------------------------------------------------------
250 
251 		/*-****************************************************************************************************//**
252 			@short		called for notify of configmanager
253 			@descr		These method is called from the ConfigManager before application ends or from the
254 			 			PropertyChangeListener if the sub tree broadcasts changes. You must update your
255 						internal values.
256 
257 			@seealso	baseclass ConfigItem
258 
259             @param      "lPropertyNames" is the list of properties which should be updated.
260 			@return		-
261 
262 			@onerror	-
263 		*//*-*****************************************************************************************************/
264 
265         virtual void Notify( const Sequence< ::rtl::OUString >& lPropertyNames );
266 
267 		/*-****************************************************************************************************//**
268 			@short		write changes to configuration
269 			@descr		These method writes the changed values into the sub tree
270 						and should always called in our destructor to guarantee consistency of config data.
271 
272 			@seealso	baseclass ConfigItem
273 
274 			@param		-
275 			@return		-
276 
277 			@onerror	-
278 		*//*-*****************************************************************************************************/
279 
280     	virtual void Commit();
281 
282 		//---------------------------------------------------------------------------------------------------------
283 		//	public interface
284 		//---------------------------------------------------------------------------------------------------------
285 
286 		/*-****************************************************************************************************//**
287             @short      base implementation of public interface for "SvtDynamicMenuOptions"!
288             @descr      These class is used as static member of "SvtDynamicMenuOptions" ...
289 						=> The code exist only for one time and isn't duplicated for every instance!
290 
291 			@seealso	-
292 
293 			@param		-
294 			@return		-
295 
296 			@onerror	-
297 		*//*-*****************************************************************************************************/
298 
299 		sal_Bool										HasAddonsMenu		 () const ;
300 		sal_Bool										HasAddonsHelpMenu	 () const ;
301         sal_Int32                                       GetAddonsToolBarCount() const ;
302         const Sequence< Sequence< PropertyValue > >&	GetAddonsMenu		 () const ;
303 		const Sequence< Sequence< PropertyValue > >&	GetAddonsMenuBarPart () const ;
304         const Sequence< Sequence< PropertyValue > >&	GetAddonsToolBarPart ( sal_uInt32 nIndex ) const ;
305         const ::rtl::OUString                           GetAddonsToolbarResourceName( sal_uInt32 nIndex ) const;
306         const ::rtl::OUString                           GetAddonsToolbarUIName( sal_uInt32 nIndex ) const;
307 		const Sequence< Sequence< PropertyValue > >&	GetAddonsHelpMenu	 () const ;
308 		Image											GetImageFromURL( const rtl::OUString& aURL, sal_Bool bBig, sal_Bool bHiContrast, sal_Bool bNoScale ) const;
309         const MergeMenuInstructionContainer&            GetMergeMenuInstructions() const;
310         bool                                            GetMergeToolbarInstructions( const ::rtl::OUString& rToolbarName, MergeToolbarInstructionContainer& rToolbarInstructions ) const;
311         const MergeStatusbarInstructionContainer&       GetMergeStatusbarInstructions() const;
312         void                                            ReadConfigurationData();
313 
314 	//-------------------------------------------------------------------------------------------------------------
315 	//	private methods
316 	//-------------------------------------------------------------------------------------------------------------
317 
318 	private:
319 
320 		struct ImageEntry
321 		{
322 			Image	aImageSmall;
323 			Image	aImageBig;
324 			Image	aImageSmallHC;
325 			Image	aImageBigHC;
326 
327             Image   aImageSmallNoScale;
328             Image   aImageBigNoScale;
329             Image   aImageSmallHCNoScale;
330             Image   aImageBigHCNoScale;
331 		};
332 
333 		typedef std::hash_map< ::rtl::OUString, ImageEntry, rtl::OUStringHash, ::std::equal_to< ::rtl::OUString > > ImageManager;
334         typedef std::hash_map< ::rtl::OUString, sal_uInt32, rtl::OUStringHash, ::std::equal_to< ::rtl::OUString > > StringToIndexMap;
335         typedef std::vector< Sequence< Sequence< PropertyValue > > > AddonToolBars;
336         typedef ::std::hash_map< ::rtl::OUString, MergeToolbarInstructionContainer, rtl::OUStringHash, ::std::equal_to< ::rtl::OUString > > ToolbarMergingInstructions;
337 
338         enum ImageSize
339         {
340             IMGSIZE_SMALL,
341             IMGSIZE_BIG
342         };
343 
344 		/*-****************************************************************************************************//**
345             @short      return list of key names of our configuration management which represent our module tree
346 			@descr		These methods return the current list of key names! We need it to get needed values from our
347                         configuration management!
348 
349 			@seealso	-
350 
351             @param      "nCount"     ,   returns count of menu entries for "new"
352 			@return		A list of configuration key names is returned.
353 
354 			@onerror	-
355 		*//*-*****************************************************************************************************/
356 
357 		sal_Bool			 ReadAddonMenuSet( Sequence< Sequence< PropertyValue > >& aAddonMenuSeq );
358 		sal_Bool			 ReadOfficeMenuBarSet( Sequence< Sequence< PropertyValue > >& aAddonOfficeMenuBarSeq );
359         sal_Bool			 ReadOfficeToolBarSet( AddonToolBars& rAddonOfficeToolBars,
360                                                    std::vector< rtl::OUString >& rAddonOfficeToolBarResNames,
361                                                    std::vector< rtl::OUString >& rAddonOfficeToolBarUINames );
362         sal_Bool			 ReadToolBarItemSet( const rtl::OUString rToolBarItemSetNodeName, Sequence< Sequence< PropertyValue > >& aAddonOfficeToolBarSeq );
363 		sal_Bool			 ReadOfficeHelpSet( Sequence< Sequence< PropertyValue > >& aAddonOfficeHelpMenuSeq );
364 		sal_Bool			 ReadImages( ImageManager& aImageManager );
365         sal_Bool             ReadMenuMergeInstructions( MergeMenuInstructionContainer& rContainer );
366         sal_Bool             ReadToolbarMergeInstructions( ToolbarMergingInstructions& rToolbarMergeMap );
367         sal_Bool             ReadStatusbarMergeInstructions( MergeStatusbarInstructionContainer& rContainer );
368 
369         sal_Bool             ReadMergeMenuData( const ::rtl::OUString& aMergeAddonInstructionBase, Sequence< Sequence< PropertyValue > >& rMergeMenu );
370         sal_Bool             ReadMergeToolbarData( const ::rtl::OUString& aMergeAddonInstructionBase, Sequence< Sequence< PropertyValue > >& rMergeToolbarItems );
371         sal_Bool             ReadMergeStatusbarData( const ::rtl::OUString& aMergeAddonInstructionBase, Sequence< Sequence< PropertyValue > >& rMergeStatusbar );
372 		sal_Bool			 ReadMenuItem( const ::rtl::OUString& aMenuItemNodeName, Sequence< PropertyValue >& aMenuItem, sal_Bool bIgnoreSubMenu = sal_False );
373 		sal_Bool			 ReadPopupMenu( const ::rtl::OUString& aPopupMenuNodeName, Sequence< PropertyValue >& aPopupMenu );
374         sal_Bool             AppendPopupMenu( Sequence< PropertyValue >& aTargetPopupMenu, const Sequence< PropertyValue >& rSourcePopupMenu );
375 		sal_Bool			 ReadToolBarItem( const ::rtl::OUString& aToolBarItemNodeName, Sequence< PropertyValue >& aToolBarItem );
376         sal_Bool             ReadStatusBarItem( const ::rtl::OUString& aStatusbarItemNodeName, Sequence< PropertyValue >& aStatusbarItem );
377 		sal_Bool			 ReadImagesItem( const ::rtl::OUString& aImagesItemNodeName, Sequence< PropertyValue >& aImagesItem );
378 		ImageEntry*			 ReadImageData( const ::rtl::OUString& aImagesNodeName );
379 		void                 ReadAndAssociateImages( const ::rtl::OUString& aURL, const ::rtl::OUString& aImageId );
380 		void                 ReadImageFromURL( ImageSize nImageSize, const ::rtl::OUString& aURL, Image& aImage, Image& aNoScaleImage );
381 		sal_Bool             HasAssociatedImages( const ::rtl::OUString& aURL );
382 		void                 SubstituteVariables( ::rtl::OUString& aURL );
383 
384 		sal_Bool			 ReadSubMenuEntries( const Sequence< ::rtl::OUString >& aSubMenuNodeNames, Sequence< Sequence< PropertyValue > >& rSubMenu );
385 		void				 InsertToolBarSeparator( Sequence< Sequence< PropertyValue > >& rAddonOfficeToolBarSeq );
386 		::rtl::OUString			 GeneratePrefixURL();
387 
388 		Sequence< ::rtl::OUString > GetPropertyNamesMergeMenuInstruction( const ::rtl::OUString& aPropertyRootName ) const;
389         Sequence< ::rtl::OUString > GetPropertyNamesMenuItem( const ::rtl::OUString& aPropertyRootNode ) const;
390 		Sequence< ::rtl::OUString > GetPropertyNamesPopupMenu( const ::rtl::OUString& aPropertyRootNode ) const;
391         Sequence< ::rtl::OUString > GetPropertyNamesToolBar( const ::rtl::OUString& aPropertyRootNode ) const;
392 		Sequence< ::rtl::OUString > GetPropertyNamesToolBarItem( const ::rtl::OUString& aPropertyRootNode ) const;
393         Sequence< ::rtl::OUString > GetPropertyNamesStatusbarItem( const ::rtl::OUString& aPropertyRootNode ) const;
394 		Sequence< ::rtl::OUString > GetPropertyNamesImages( const ::rtl::OUString& aPropertyRootNode ) const;
395 		sal_Bool			 CreateImageFromSequence( Image& rImage, sal_Bool bBig, Sequence< sal_Int8 >& rBitmapDataSeq ) const;
396 
397 	//-------------------------------------------------------------------------------------------------------------
398 	//	private member
399 	//-------------------------------------------------------------------------------------------------------------
400 
401 	private:
402 		ImageEntry*	ReadOptionalImageData( const ::rtl::OUString& aMenuNodeName );
403 
404 		sal_Int32                                         m_nRootAddonPopupMenuId;
405 		::rtl::OUString                                          m_aPropNames[PROPERTYCOUNT_INDEX];
406 		::rtl::OUString                                          m_aPropImagesNames[PROPERTYCOUNT_IMAGES];
407         ::rtl::OUString                                          m_aPropMergeMenuNames[PROPERTYCOUNT_MERGE_MENUBAR];
408         ::rtl::OUString                                          m_aPropMergeToolbarNames[PROPERTYCOUNT_MERGE_TOOLBAR];
409         ::rtl::OUString                                          m_aPropMergeStatusbarNames[PROPERTYCOUNT_MERGE_STATUSBAR];
410 		::rtl::OUString                                          m_aEmpty;
411 		::rtl::OUString                                          m_aPathDelimiter;
412 		::rtl::OUString                                          m_aSeparator;
413 		::rtl::OUString                                          m_aRootAddonPopupMenuURLPrexfix;
414 		::rtl::OUString                                          m_aPrivateImageURL;
415 		Sequence< Sequence< PropertyValue > >             m_aCachedMenuProperties;
416 		Sequence< Sequence< PropertyValue > >             m_aCachedMenuBarPartProperties;
417         AddonToolBars                                     m_aCachedToolBarPartProperties;
418         std::vector< rtl::OUString >                      m_aCachedToolBarPartResourceNames;
419         std::vector< rtl::OUString >                      m_aCachedToolBarPartUINames;
420 		Sequence< Sequence< PropertyValue > >             m_aCachedHelpMenuProperties;
421 		Reference< com::sun::star::util::XMacroExpander > m_xMacroExpander;
422 		ImageManager                                      m_aImageManager;
423         Sequence< Sequence< PropertyValue > >             m_aEmptyAddonToolBar;
424         MergeMenuInstructionContainer                     m_aCachedMergeMenuInsContainer;
425         ToolbarMergingInstructions                        m_aCachedToolbarMergingInstructions;
426         MergeStatusbarInstructionContainer                m_aCachedStatusbarMergingInstructions;
427 };
428 
429 //_________________________________________________________________________________________________________________
430 //	definitions
431 //_________________________________________________________________________________________________________________
432 
433 //*****************************************************************************************************************
434 //	constructor
435 //*****************************************************************************************************************
AddonsOptions_Impl()436 AddonsOptions_Impl::AddonsOptions_Impl()
437     // Init baseclasses first
438     : ConfigItem( ROOTNODE_ADDONMENU ),
439 	m_nRootAddonPopupMenuId( 0 ),
440 	m_aPathDelimiter( PATHDELIMITER ),
441 	m_aSeparator( SEPARATOR_URL ),
442 	m_aRootAddonPopupMenuURLPrexfix( ADDONSPOPUPMENU_URL_PREFIX ),
443 	m_aPrivateImageURL( PRIVATE_IMAGE_URL )
444 {
445 	// initialize array with fixed property names
446 	m_aPropNames[ INDEX_URL				] = PROPERTYNAME_URL;
447 	m_aPropNames[ INDEX_TITLE			] = PROPERTYNAME_TITLE;
448 	m_aPropNames[ INDEX_TARGET			] = PROPERTYNAME_TARGET;
449 	m_aPropNames[ INDEX_IMAGEIDENTIFIER	] = PROPERTYNAME_IMAGEIDENTIFIER;
450 	m_aPropNames[ INDEX_CONTEXT			] = PROPERTYNAME_CONTEXT;
451 	m_aPropNames[ INDEX_SUBMENU			] = PROPERTYNAME_SUBMENU; // Submenu set!
452     m_aPropNames[ INDEX_CONTROLTYPE     ] = PROPERTYNAME_CONTROLTYPE;
453     m_aPropNames[ INDEX_WIDTH           ] = PROPERTYNAME_WIDTH;
454     m_aPropNames[ INDEX_ALIGN           ] = PROPERTYNAME_ALIGN;
455     m_aPropNames[ INDEX_AUTOSIZE        ] = PROPERTYNAME_AUTOSIZE;
456     m_aPropNames[ INDEX_OWNERDRAW       ] = PROPERTYNAME_OWNERDRAW;
457     m_aPropNames[ INDEX_TOOLBARITEMS    ] = PROPERTYNAME_TOOLBARITEMS;
458 
459 	// initialize array with fixed images property names
460 	m_aPropImagesNames[ OFFSET_IMAGES_SMALL			] = PROPERTYNAME_IMAGESMALL;
461 	m_aPropImagesNames[ OFFSET_IMAGES_BIG			] = PROPERTYNAME_IMAGEBIG;
462 	m_aPropImagesNames[ OFFSET_IMAGES_SMALLHC		] = PROPERTYNAME_IMAGESMALLHC;
463 	m_aPropImagesNames[ OFFSET_IMAGES_BIGHC			] = PROPERTYNAME_IMAGEBIGHC;
464 	m_aPropImagesNames[ OFFSET_IMAGES_SMALL_URL		] = PROPERTYNAME_IMAGESMALL_URL;
465 	m_aPropImagesNames[ OFFSET_IMAGES_BIG_URL	    ] = PROPERTYNAME_IMAGEBIG_URL;
466 	m_aPropImagesNames[ OFFSET_IMAGES_SMALLHC_URL	] = PROPERTYNAME_IMAGESMALLHC_URL;
467 	m_aPropImagesNames[ OFFSET_IMAGES_BIGHC_URL		] = PROPERTYNAME_IMAGEBIGHC_URL;
468 
469     // initialize array with fixed merge menu property names
470     m_aPropMergeMenuNames[ OFFSET_MERGEMENU_MERGEPOINT    ] = PROPERTYNAME_MERGEMENU_MERGEPOINT;
471     m_aPropMergeMenuNames[ OFFSET_MERGEMENU_MERGECOMMAND  ] = PROPERTYNAME_MERGEMENU_MERGECOMMAND;
472     m_aPropMergeMenuNames[ OFFSET_MERGEMENU_MERGECOMMANDPARAMETER ] = PROPERTYNAME_MERGEMENU_MERGECOMMANDPARAMETER;
473     m_aPropMergeMenuNames[ OFFSET_MERGEMENU_MERGEFALLBACK ] = PROPERTYNAME_MERGEMENU_MERGEFALLBACK;
474     m_aPropMergeMenuNames[ OFFSET_MERGEMENU_MERGECONTEXT  ] = PROPERTYNAME_MERGEMENU_MERGECONTEXT;
475     m_aPropMergeMenuNames[ OFFSET_MERGEMENU_MENUITEMS     ] = PROPERTYNAME_MERGEMENU_MENUITEMS;
476 
477     m_aPropMergeToolbarNames[ OFFSET_MERGETOOLBAR_TOOLBAR               ] = PROPERTYNAME_MERGETOOLBAR_TOOLBAR;
478     m_aPropMergeToolbarNames[ OFFSET_MERGETOOLBAR_MERGEPOINT            ] = PROPERTYNAME_MERGETOOLBAR_MERGEPOINT;
479     m_aPropMergeToolbarNames[ OFFSET_MERGETOOLBAR_MERGECOMMAND          ] = PROPERTYNAME_MERGETOOLBAR_MERGECOMMAND;
480     m_aPropMergeToolbarNames[ OFFSET_MERGETOOLBAR_MERGECOMMANDPARAMETER ] = PROPERTYNAME_MERGETOOLBAR_MERGECOMMANDPARAMETER;
481     m_aPropMergeToolbarNames[ OFFSET_MERGETOOLBAR_MERGEFALLBACK         ] = PROPERTYNAME_MERGETOOLBAR_MERGEFALLBACK;
482     m_aPropMergeToolbarNames[ OFFSET_MERGETOOLBAR_MERGECONTEXT          ] = PROPERTYNAME_MERGETOOLBAR_MERGECONTEXT;
483     m_aPropMergeToolbarNames[ OFFSET_MERGETOOLBAR_TOOLBARITEMS          ] = PROPERTYNAME_MERGETOOLBAR_TOOLBARITEMS;
484 
485     m_aPropMergeStatusbarNames[ OFFSET_MERGESTATUSBAR_MERGEPOINT            ] = PROPERTYNAME_MERGESTATUSBAR_MERGEPOINT;
486     m_aPropMergeStatusbarNames[ OFFSET_MERGESTATUSBAR_MERGECOMMAND          ] = PROPERTYNAME_MERGESTATUSBAR_MERGECOMMAND;
487     m_aPropMergeStatusbarNames[ OFFSET_MERGESTATUSBAR_MERGECOMMANDPARAMETER ] = PROPERTYNAME_MERGESTATUSBAR_MERGECOMMANDPARAMETER;
488     m_aPropMergeStatusbarNames[ OFFSET_MERGESTATUSBAR_MERGEFALLBACK         ] = PROPERTYNAME_MERGESTATUSBAR_MERGEFALLBACK;
489     m_aPropMergeStatusbarNames[ OFFSET_MERGESTATUSBAR_MERGECONTEXT          ] = PROPERTYNAME_MERGESTATUSBAR_MERGECONTEXT;
490     m_aPropMergeStatusbarNames[ OFFSET_MERGESTATUSBAR_STATUSBARITEMS        ] = PROPERTYNAME_MERGESTATUSBAR_STATUSBARITEMS;
491 
492     Reference< XComponentContext > xContext;
493     Reference< com::sun::star::beans::XPropertySet > xProps( ::comphelper::getProcessServiceFactory(), UNO_QUERY );
494     xProps->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" ))) >>= xContext;
495     if ( xContext.is() )
496     {
497         m_xMacroExpander =  Reference< com::sun::star::util::XMacroExpander >( xContext->getValueByName(
498                                 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/singletons/com.sun.star.util.theMacroExpander"))),
499                                 UNO_QUERY );
500     }
501 
502     ReadConfigurationData();
503 
504     // Enable notification mechanism of our baseclass.
505 	// We need it to get information about changes outside these class on our used configuration keys!
506     Sequence< rtl::OUString > aNotifySeq( 1 );
507     aNotifySeq[0] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "AddonUI" ));
508     EnableNotification( aNotifySeq );
509 }
510 
511 //*****************************************************************************************************************
512 //	destructor
513 //*****************************************************************************************************************
~AddonsOptions_Impl()514 AddonsOptions_Impl::~AddonsOptions_Impl()
515 {
516 	// We must save our current values .. if user forget it!
517 	if( IsModified() == sal_True )
518 	{
519 		Commit();
520 	}
521 }
522 
ReadConfigurationData()523 void AddonsOptions_Impl::ReadConfigurationData()
524 {
525     // reset members to be read again from configuration
526     m_aCachedMenuProperties = Sequence< Sequence< PropertyValue > >();
527     m_aCachedMenuBarPartProperties = Sequence< Sequence< PropertyValue > >();
528     m_aCachedToolBarPartProperties = AddonToolBars();
529     m_aCachedHelpMenuProperties = Sequence< Sequence< PropertyValue > >();
530     m_aCachedToolBarPartResourceNames.clear();
531     m_aCachedToolBarPartUINames.clear();
532     m_aImageManager = ImageManager();
533 
534     ReadAddonMenuSet( m_aCachedMenuProperties );
535 	ReadOfficeMenuBarSet( m_aCachedMenuBarPartProperties );
536 	ReadOfficeToolBarSet( m_aCachedToolBarPartProperties,
537                           m_aCachedToolBarPartResourceNames,
538                           m_aCachedToolBarPartUINames );
539 
540 	ReadOfficeHelpSet( m_aCachedHelpMenuProperties );
541 	ReadImages( m_aImageManager );
542 
543     m_aCachedMergeMenuInsContainer.clear();
544     m_aCachedToolbarMergingInstructions.clear();
545     m_aCachedStatusbarMergingInstructions.clear();
546 
547     ReadMenuMergeInstructions( m_aCachedMergeMenuInsContainer );
548     ReadToolbarMergeInstructions( m_aCachedToolbarMergingInstructions );
549     ReadStatusbarMergeInstructions( m_aCachedStatusbarMergingInstructions );
550 }
551 
552 //*****************************************************************************************************************
553 //	public method
554 //*****************************************************************************************************************
Notify(const Sequence<::rtl::OUString> &)555 void AddonsOptions_Impl::Notify( const Sequence< ::rtl::OUString >& /*lPropertyNames*/ )
556 {
557     Application::PostUserEvent( STATIC_LINK( 0, AddonsOptions, Notify ) );
558 }
559 
560 //*****************************************************************************************************************
561 //	public method
562 //*****************************************************************************************************************
Commit()563 void AddonsOptions_Impl::Commit()
564 {
565     DBG_ERROR( "AddonsOptions_Impl::Commit()\nNot implemented yet!\n" );
566 }
567 
568 //*****************************************************************************************************************
569 //	public method
570 //*****************************************************************************************************************
HasAddonsMenu() const571 sal_Bool AddonsOptions_Impl::HasAddonsMenu() const
572 {
573 	return ( m_aCachedMenuProperties.getLength() > 0 );
574 }
575 
576 //*****************************************************************************************************************
577 //	public method
578 //*****************************************************************************************************************
HasAddonsHelpMenu() const579 sal_Bool AddonsOptions_Impl::HasAddonsHelpMenu	() const
580 {
581 	return ( m_aCachedHelpMenuProperties.getLength() > 0 );
582 }
583 
584 //*****************************************************************************************************************
585 //	public method
586 //*****************************************************************************************************************
GetAddonsToolBarCount() const587 sal_Int32 AddonsOptions_Impl::GetAddonsToolBarCount() const
588 {
589     return m_aCachedToolBarPartProperties.size();
590 }
591 
592 //*****************************************************************************************************************
593 //	public method
594 //*****************************************************************************************************************
GetAddonsMenu() const595 const Sequence< Sequence< PropertyValue > >& AddonsOptions_Impl::GetAddonsMenu() const
596 {
597 	return m_aCachedMenuProperties;
598 }
599 
600 //*****************************************************************************************************************
601 //	public method
602 //*****************************************************************************************************************
GetAddonsMenuBarPart() const603 const Sequence< Sequence< PropertyValue > >& AddonsOptions_Impl::GetAddonsMenuBarPart() const
604 {
605 	return m_aCachedMenuBarPartProperties;
606 }
607 
608 //*****************************************************************************************************************
609 //	public method
610 //*****************************************************************************************************************
GetAddonsToolBarPart(sal_uInt32 nIndex) const611 const Sequence< Sequence< PropertyValue > >& AddonsOptions_Impl::GetAddonsToolBarPart( sal_uInt32 nIndex ) const
612 {
613     if ( /*nIndex >= 0 &&*/ nIndex < m_aCachedToolBarPartProperties.size() )
614         return m_aCachedToolBarPartProperties[nIndex];
615     else
616         return m_aEmptyAddonToolBar;
617 }
618 
619 //*****************************************************************************************************************
620 //	public method
621 //*****************************************************************************************************************
GetAddonsToolbarResourceName(sal_uInt32 nIndex) const622 const ::rtl::OUString AddonsOptions_Impl::GetAddonsToolbarResourceName( sal_uInt32 nIndex ) const
623 {
624     if ( nIndex < m_aCachedToolBarPartResourceNames.size() )
625         return m_aCachedToolBarPartResourceNames[nIndex];
626     else
627         return rtl::OUString();
628 }
629 
630 
GetAddonsToolbarUIName(sal_uInt32 nIndex) const631 const ::rtl::OUString AddonsOptions_Impl::GetAddonsToolbarUIName( sal_uInt32 nIndex ) const
632 {
633     if ( nIndex < m_aCachedToolBarPartUINames.size() )
634         return m_aCachedToolBarPartUINames[nIndex];
635     else
636         return rtl::OUString();
637 }
638 
639 //*****************************************************************************************************************
640 //	public method
641 //*****************************************************************************************************************
GetAddonsHelpMenu() const642 const Sequence< Sequence< PropertyValue > >& AddonsOptions_Impl::GetAddonsHelpMenu	() const
643 {
644 	return m_aCachedHelpMenuProperties;
645 }
646 
647 //*****************************************************************************************************************
648 //	public method
649 //*****************************************************************************************************************
GetMergeMenuInstructions() const650 const MergeMenuInstructionContainer& AddonsOptions_Impl::GetMergeMenuInstructions() const
651 {
652     return m_aCachedMergeMenuInsContainer;
653 }
654 
655 //*****************************************************************************************************************
656 //	public method
657 //*****************************************************************************************************************
GetMergeToolbarInstructions(const::rtl::OUString & rToolbarName,MergeToolbarInstructionContainer & rToolbarInstructions) const658 bool AddonsOptions_Impl::GetMergeToolbarInstructions(
659     const ::rtl::OUString& rToolbarName,
660     MergeToolbarInstructionContainer& rToolbarInstructions ) const
661 {
662     ToolbarMergingInstructions::const_iterator pIter = m_aCachedToolbarMergingInstructions.find( rToolbarName );
663     if ( pIter != m_aCachedToolbarMergingInstructions.end() )
664     {
665         rToolbarInstructions = pIter->second;
666         return true;
667     }
668     else
669         return false;
670 }
671 
GetMergeStatusbarInstructions() const672 const MergeStatusbarInstructionContainer& AddonsOptions_Impl::GetMergeStatusbarInstructions() const
673 {
674     return m_aCachedStatusbarMergingInstructions;
675 }
676 
677 //*****************************************************************************************************************
678 //	public method
679 //*****************************************************************************************************************
GetImageFromURL(const rtl::OUString & aURL,sal_Bool bBig,sal_Bool bHiContrast,sal_Bool bNoScale) const680 Image AddonsOptions_Impl::GetImageFromURL( const rtl::OUString& aURL, sal_Bool bBig, sal_Bool bHiContrast, sal_Bool bNoScale ) const
681 {
682 	Image aImage;
683 
684 	ImageManager::const_iterator pIter = m_aImageManager.find( aURL );
685 	if ( pIter != m_aImageManager.end() )
686 	{
687 		if ( !bHiContrast  )
688         {
689 			if ( bNoScale )
690                 aImage = ( bBig ? pIter->second.aImageBigNoScale : pIter->second.aImageSmallNoScale );
691             if ( !aImage )
692                 aImage = ( bBig ? pIter->second.aImageBig : pIter->second.aImageSmall );
693         }
694 		else
695         {
696 			if ( bNoScale )
697                 aImage = ( bBig ? pIter->second.aImageBigHCNoScale : pIter->second.aImageSmallHCNoScale );
698             if ( !aImage )
699 			    aImage = ( bBig ? pIter->second.aImageBigHC : pIter->second.aImageSmallHC );
700         }
701 	}
702 
703 	return aImage;
704 }
705 
706 //*****************************************************************************************************************
707 //	private method
708 //*****************************************************************************************************************
ReadAddonMenuSet(Sequence<Sequence<PropertyValue>> & rAddonMenuSeq)709 sal_Bool AddonsOptions_Impl::ReadAddonMenuSet( Sequence< Sequence< PropertyValue > >& rAddonMenuSeq )
710 {
711 	// Read the AddonMenu set and fill property sequences
712 	::rtl::OUString				aAddonMenuNodeName( RTL_CONSTASCII_USTRINGPARAM( "AddonUI/AddonMenu" ));
713 	Sequence< ::rtl::OUString >	aAddonMenuNodeSeq = GetNodeNames( aAddonMenuNodeName );
714 	::rtl::OUString				aAddonMenuItemNode( aAddonMenuNodeName + m_aPathDelimiter );
715 
716 	sal_uInt32				nCount = aAddonMenuNodeSeq.getLength();
717 	sal_uInt32				nIndex = 0;
718 	Sequence< PropertyValue > aMenuItem( PROPERTYCOUNT_MENUITEM );
719 
720 	// Init the property value sequence
721 	aMenuItem[ OFFSET_MENUITEM_URL				].Name = m_aPropNames[ INDEX_URL			];
722 	aMenuItem[ OFFSET_MENUITEM_TITLE			].Name = m_aPropNames[ INDEX_TITLE			];
723 	aMenuItem[ OFFSET_MENUITEM_TARGET			].Name = m_aPropNames[ INDEX_TARGET			];
724 	aMenuItem[ OFFSET_MENUITEM_IMAGEIDENTIFIER	].Name = m_aPropNames[ INDEX_IMAGEIDENTIFIER];
725 	aMenuItem[ OFFSET_MENUITEM_CONTEXT			].Name = m_aPropNames[ INDEX_CONTEXT		];
726 	aMenuItem[ OFFSET_MENUITEM_SUBMENU			].Name = m_aPropNames[ INDEX_SUBMENU		];	// Submenu set!
727 
728 	for ( sal_uInt32 n = 0; n < nCount; n++ )
729 	{
730 		::rtl::OUString aRootMenuItemNode( aAddonMenuItemNode + aAddonMenuNodeSeq[n] );
731 
732 		// Read the MenuItem
733 		if ( ReadMenuItem( aRootMenuItemNode, aMenuItem ) )
734 		{
735 			// Successfully read a menu item, append to our list
736 			sal_uInt32 nMenuItemCount = rAddonMenuSeq.getLength() + 1;
737 			rAddonMenuSeq.realloc( nMenuItemCount );
738 			rAddonMenuSeq[nIndex++] = aMenuItem;
739 		}
740 	}
741 
742 	return ( rAddonMenuSeq.getLength() > 0 );
743 }
744 
745 //*****************************************************************************************************************
746 //	private method
747 //*****************************************************************************************************************
ReadOfficeHelpSet(Sequence<Sequence<PropertyValue>> & rAddonOfficeHelpMenuSeq)748 sal_Bool AddonsOptions_Impl::ReadOfficeHelpSet( Sequence< Sequence< PropertyValue > >& rAddonOfficeHelpMenuSeq )
749 {
750 	// Read the AddonMenu set and fill property sequences
751 	::rtl::OUString				aAddonHelpMenuNodeName( RTL_CONSTASCII_USTRINGPARAM( "AddonUI/OfficeHelp" ));
752 	Sequence< ::rtl::OUString >	aAddonHelpMenuNodeSeq = GetNodeNames( aAddonHelpMenuNodeName );
753 	::rtl::OUString				aAddonHelpMenuItemNode( aAddonHelpMenuNodeName + m_aPathDelimiter );
754 
755 	sal_uInt32				nCount = aAddonHelpMenuNodeSeq.getLength();
756 	sal_uInt32				nIndex = 0;
757 	Sequence< PropertyValue > aMenuItem( PROPERTYCOUNT_MENUITEM );
758 
759 	// Init the property value sequence
760 	aMenuItem[ OFFSET_MENUITEM_URL				].Name = m_aPropNames[ INDEX_URL			];
761 	aMenuItem[ OFFSET_MENUITEM_TITLE			].Name = m_aPropNames[ INDEX_TITLE			];
762 	aMenuItem[ OFFSET_MENUITEM_TARGET			].Name = m_aPropNames[ INDEX_TARGET			];
763 	aMenuItem[ OFFSET_MENUITEM_IMAGEIDENTIFIER	].Name = m_aPropNames[ INDEX_IMAGEIDENTIFIER];
764 	aMenuItem[ OFFSET_MENUITEM_CONTEXT			].Name = m_aPropNames[ INDEX_CONTEXT		];
765 	aMenuItem[ OFFSET_MENUITEM_SUBMENU			].Name = m_aPropNames[ INDEX_SUBMENU		];	// Submenu set!
766 
767 	for ( sal_uInt32 n = 0; n < nCount; n++ )
768 	{
769 		::rtl::OUString aRootMenuItemNode( aAddonHelpMenuItemNode + aAddonHelpMenuNodeSeq[n] );
770 
771 		// Read the MenuItem
772 		if ( ReadMenuItem( aRootMenuItemNode, aMenuItem, sal_True ) )
773 		{
774 			// Successfully read a menu item, append to our list
775 			sal_uInt32 nMenuItemCount = rAddonOfficeHelpMenuSeq.getLength() + 1;
776 			rAddonOfficeHelpMenuSeq.realloc( nMenuItemCount );
777 			rAddonOfficeHelpMenuSeq[nIndex++] = aMenuItem;
778 		}
779 	}
780 
781 	return ( rAddonOfficeHelpMenuSeq.getLength() > 0 );
782 }
783 
784 //*****************************************************************************************************************
785 //	private method
786 //*****************************************************************************************************************
ReadOfficeMenuBarSet(Sequence<Sequence<PropertyValue>> & rAddonOfficeMenuBarSeq)787 sal_Bool AddonsOptions_Impl::ReadOfficeMenuBarSet( Sequence< Sequence< PropertyValue > >& rAddonOfficeMenuBarSeq )
788 {
789 	// Read the OfficeMenuBar set and fill property sequences
790 	::rtl::OUString				aAddonMenuBarNodeName( RTL_CONSTASCII_USTRINGPARAM( "AddonUI/OfficeMenuBar" ));
791 	Sequence< ::rtl::OUString >	aAddonMenuBarNodeSeq = GetNodeNames( aAddonMenuBarNodeName );
792 	::rtl::OUString				aAddonMenuBarNode( aAddonMenuBarNodeName + m_aPathDelimiter );
793 
794 	sal_uInt32				nCount = aAddonMenuBarNodeSeq.getLength();
795 	sal_uInt32				nIndex = 0;
796 	Sequence< PropertyValue > aPopupMenu( PROPERTYCOUNT_POPUPMENU );
797 
798 	// Init the property value sequence
799 	aPopupMenu[ OFFSET_POPUPMENU_TITLE		].Name = m_aPropNames[ INDEX_TITLE	];
800 	aPopupMenu[ OFFSET_POPUPMENU_CONTEXT	].Name = m_aPropNames[ INDEX_CONTEXT];
801 	aPopupMenu[ OFFSET_POPUPMENU_SUBMENU	].Name = m_aPropNames[ INDEX_SUBMENU];
802 	aPopupMenu[ OFFSET_POPUPMENU_URL		].Name = m_aPropNames[ INDEX_URL	];
803 
804     StringToIndexMap aTitleToIndexMap;
805 
806     for ( sal_uInt32 n = 0; n < nCount; n++ )
807 	{
808 		::rtl::OUString aPopupMenuNode( aAddonMenuBarNode + aAddonMenuBarNodeSeq[n] );
809 
810 		// Read the MenuItem
811 		if ( ReadPopupMenu( aPopupMenuNode, aPopupMenu ) )
812 		{
813 			// Successfully read a popup menu, append to our list
814             ::rtl::OUString aPopupTitle;
815             if ( aPopupMenu[OFFSET_POPUPMENU_TITLE].Value >>= aPopupTitle )
816             {
817                 StringToIndexMap::const_iterator pIter = aTitleToIndexMap.find( aPopupTitle );
818                 if ( pIter != aTitleToIndexMap.end() )
819                 {
820                     // title already there => concat both popup menus
821                     Sequence< PropertyValue >& rOldPopupMenu = rAddonOfficeMenuBarSeq[pIter->second];
822                     AppendPopupMenu( rOldPopupMenu, aPopupMenu );
823                 }
824                 else
825                 {
826                     // not found
827 			        sal_uInt32 nMenuItemCount = rAddonOfficeMenuBarSeq.getLength() + 1;
828 			        rAddonOfficeMenuBarSeq.realloc( nMenuItemCount );
829 			        rAddonOfficeMenuBarSeq[nIndex] = aPopupMenu;
830                     aTitleToIndexMap.insert( StringToIndexMap::value_type( aPopupTitle, nIndex ));
831                     ++nIndex;
832                 }
833             }
834 		}
835 	}
836 
837 	return ( rAddonOfficeMenuBarSeq.getLength() > 0 );
838 }
839 
840 //*****************************************************************************************************************
841 //	private method
842 //*****************************************************************************************************************
ReadOfficeToolBarSet(AddonToolBars & rAddonOfficeToolBars,std::vector<rtl::OUString> & rAddonOfficeToolBarResNames,std::vector<rtl::OUString> & rAddonOfficeToolBarUINames)843 sal_Bool AddonsOptions_Impl::ReadOfficeToolBarSet(
844     AddonToolBars& rAddonOfficeToolBars,
845     std::vector< rtl::OUString >& rAddonOfficeToolBarResNames,
846     std::vector< rtl::OUString >& rAddonOfficeToolBarUINames )
847 {
848 	// Read the OfficeToolBar set and fill property sequences
849 	::rtl::OUString             aAddonToolBarNodeName( RTL_CONSTASCII_USTRINGPARAM( "AddonUI/OfficeToolBar" ));
850 	Sequence< ::rtl::OUString > aAddonToolBarNodeSeq = GetNodeNames( aAddonToolBarNodeName );
851 	::rtl::OUString             aAddonToolBarNode( aAddonToolBarNodeName + m_aPathDelimiter );
852 
853 	sal_uInt32           nCount = aAddonToolBarNodeSeq.getLength();
854 
855 	for ( sal_uInt32 n = 0; n < nCount; n++ )
856 	{
857         ::rtl::OUString aToolBarNode( aAddonToolBarNode + aAddonToolBarNodeSeq[n] + m_aPathDelimiter );
858         rAddonOfficeToolBarResNames.push_back( aAddonToolBarNodeSeq[n] );
859         rAddonOfficeToolBars.push_back( m_aEmptyAddonToolBar );
860 
861         Sequence< Any > aToolBarNodeValues = GetProperties( GetPropertyNamesToolBar( aToolBarNode ) );
862 
863         rtl::OUString aUIName;
864         aToolBarNodeValues[OFFSET_TOOLBAR_TITLE] >>= aUIName;
865         rAddonOfficeToolBarUINames.push_back( aUIName );
866 
867         Reference < XInterface > xToolbarItems;
868         if ( ( aToolBarNodeValues[OFFSET_TOOLBAR_TOOLBARITEMS] >>= xToolbarItems ) && xToolbarItems.is() )
869         {
870             ::rtl::OUStringBuffer aBuffer;
871             aBuffer.append( aToolBarNode );
872             aBuffer.appendAscii( RTL_CONSTASCII_STRINGPARAM( STR_TOOLBARITEMS ) );
873             ReadToolBarItemSet( aBuffer.makeStringAndClear(), rAddonOfficeToolBars[n] );
874         }
875 	}
876 
877 	return ( !rAddonOfficeToolBars.empty() );
878 }
879 
880 
881 //*****************************************************************************************************************
882 //	private method
883 //*****************************************************************************************************************
ReadToolBarItemSet(const rtl::OUString rToolBarItemSetNodeName,Sequence<Sequence<PropertyValue>> & rAddonOfficeToolBarSeq)884 sal_Bool AddonsOptions_Impl::ReadToolBarItemSet( const rtl::OUString rToolBarItemSetNodeName, Sequence< Sequence< PropertyValue > >& rAddonOfficeToolBarSeq )
885 {
886 	sal_Bool					bInsertSeparator		= sal_False;
887 	sal_uInt32					nToolBarItemCount		= rAddonOfficeToolBarSeq.getLength();
888 	::rtl::OUString					aAddonToolBarItemSetNode( rToolBarItemSetNodeName + m_aPathDelimiter );
889 	Sequence< ::rtl::OUString >		aAddonToolBarItemSetNodeSeq = GetNodeNames( rToolBarItemSetNodeName );
890 	Sequence< PropertyValue >	aToolBarItem( PROPERTYCOUNT_TOOLBARITEM );
891 
892 	// Init the property value sequence
893 	aToolBarItem[ OFFSET_TOOLBARITEM_URL				].Name = m_aPropNames[ INDEX_URL			];
894 	aToolBarItem[ OFFSET_TOOLBARITEM_TITLE				].Name = m_aPropNames[ INDEX_TITLE			];
895 	aToolBarItem[ OFFSET_TOOLBARITEM_IMAGEIDENTIFIER	].Name = m_aPropNames[ INDEX_IMAGEIDENTIFIER];
896 	aToolBarItem[ OFFSET_TOOLBARITEM_TARGET				].Name = m_aPropNames[ INDEX_TARGET			];
897 	aToolBarItem[ OFFSET_TOOLBARITEM_CONTEXT			].Name = m_aPropNames[ INDEX_CONTEXT		];
898 	aToolBarItem[ OFFSET_TOOLBARITEM_CONTROLTYPE		].Name = m_aPropNames[ INDEX_CONTROLTYPE	];
899 	aToolBarItem[ OFFSET_TOOLBARITEM_WIDTH			    ].Name = m_aPropNames[ INDEX_WIDTH		    ];
900 
901 	sal_uInt32 nCount = aAddonToolBarItemSetNodeSeq.getLength();
902 	for ( sal_uInt32 n = 0; n < nCount; n++ )
903 	{
904 		::rtl::OUString aToolBarItemNode( aAddonToolBarItemSetNode + aAddonToolBarItemSetNodeSeq[n] );
905 
906 		// Read the ToolBarItem
907 		if ( ReadToolBarItem( aToolBarItemNode, aToolBarItem ) )
908 		{
909 			if ( bInsertSeparator )
910 			{
911 				bInsertSeparator = sal_False;
912 				InsertToolBarSeparator( rAddonOfficeToolBarSeq );
913 			}
914 
915 			// Successfully read a toolbar item, append to our list
916 			sal_uInt32 nAddonCount = rAddonOfficeToolBarSeq.getLength();
917 			rAddonOfficeToolBarSeq.realloc( nAddonCount+1 );
918 			rAddonOfficeToolBarSeq[nAddonCount] = aToolBarItem;
919 		}
920 	}
921 
922 	return ( (sal_uInt32)rAddonOfficeToolBarSeq.getLength() > nToolBarItemCount );
923 }
924 
925 //*****************************************************************************************************************
926 //	private method
927 //*****************************************************************************************************************
InsertToolBarSeparator(Sequence<Sequence<PropertyValue>> & rAddonOfficeToolBarSeq)928 void AddonsOptions_Impl::InsertToolBarSeparator( Sequence< Sequence< PropertyValue > >& rAddonOfficeToolBarSeq )
929 {
930 	Sequence< PropertyValue >	aToolBarItem( PROPERTYCOUNT_TOOLBARITEM );
931 
932 	aToolBarItem[ OFFSET_TOOLBARITEM_URL				].Name = m_aPropNames[ INDEX_URL			];
933 	aToolBarItem[ OFFSET_TOOLBARITEM_TITLE				].Name = m_aPropNames[ INDEX_TITLE			];
934 	aToolBarItem[ OFFSET_TOOLBARITEM_IMAGEIDENTIFIER	].Name = m_aPropNames[ INDEX_IMAGEIDENTIFIER];
935 	aToolBarItem[ OFFSET_TOOLBARITEM_TARGET				].Name = m_aPropNames[ INDEX_TARGET			];
936 	aToolBarItem[ OFFSET_TOOLBARITEM_CONTEXT			].Name = m_aPropNames[ INDEX_CONTEXT		];
937 
938 	aToolBarItem[ OFFSET_TOOLBARITEM_URL				].Value <<= SEPARATOR_URL;
939 	aToolBarItem[ OFFSET_TOOLBARITEM_TITLE				].Value <<= m_aEmpty;
940 	aToolBarItem[ OFFSET_TOOLBARITEM_TARGET				].Value <<= m_aEmpty;
941 	aToolBarItem[ OFFSET_TOOLBARITEM_IMAGEIDENTIFIER	].Value <<= m_aEmpty;
942 	aToolBarItem[ OFFSET_TOOLBARITEM_CONTEXT			].Value <<= m_aEmpty;
943 
944 	sal_uInt32 nToolBarItemCount = rAddonOfficeToolBarSeq.getLength();
945 	rAddonOfficeToolBarSeq.realloc( nToolBarItemCount+1 );
946 	rAddonOfficeToolBarSeq[nToolBarItemCount] = aToolBarItem;
947 }
948 
949 
950 //*****************************************************************************************************************
951 //	private method
952 //*****************************************************************************************************************
ReadImages(ImageManager & aImageManager)953 sal_Bool AddonsOptions_Impl::ReadImages( ImageManager& aImageManager )
954 {
955 	// Read the user-defined Images set and fill image manager
956 	::rtl::OUString                aAddonImagesNodeName( RTL_CONSTASCII_USTRINGPARAM( "AddonUI/Images" ));
957 	Sequence< ::rtl::OUString >	aAddonImagesNodeSeq = GetNodeNames( aAddonImagesNodeName );
958 	::rtl::OUString                aAddonImagesNode( aAddonImagesNodeName + m_aPathDelimiter );
959 
960 	sal_uInt32              nCount = aAddonImagesNodeSeq.getLength();
961 
962 	// Init the property value sequence
963 	Sequence< ::rtl::OUString >	aAddonImageItemNodePropNames( 1 );
964 	::rtl::OUString                aURL;
965 
966 	for ( sal_uInt32 n = 0; n < nCount; n++ )
967 	{
968 		::rtl::OUString aImagesItemNode( aAddonImagesNode + aAddonImagesNodeSeq[n] );
969 
970 		// Create sequence for data access
971 		::rtl::OUStringBuffer aBuffer( aImagesItemNode );
972 		aBuffer.append( m_aPathDelimiter );
973 		aBuffer.append( m_aPropNames[ OFFSET_MENUITEM_URL ] );
974 		aAddonImageItemNodePropNames[0] = aBuffer.makeStringAndClear();
975 
976 		Sequence< Any > aAddonImageItemNodeValues = GetProperties( aAddonImageItemNodePropNames );
977 
978 		// An user-defined image entry must have an URL. As "ImageIdentifier" has a higher priority
979 		// we also check if we already have an images association.
980 		if (( aAddonImageItemNodeValues[0] >>= aURL ) &&
981 		    aURL.getLength() > 0 &&
982 		    !HasAssociatedImages( aURL ))
983 		{
984 			::rtl::OUStringBuffer aBuf( aImagesItemNode );
985 			aBuf.append( m_aPathDelimiter );
986 			aBuf.append( IMAGES_NODENAME );
987 			aBuf.append( m_aPathDelimiter );
988 			::rtl::OUString aImagesUserDefinedItemNode = aBuf.makeStringAndClear();
989 
990 			// Read a user-defined images data
991 			ImageEntry* pImageEntry = ReadImageData( aImagesUserDefinedItemNode );
992 			if ( pImageEntry )
993 			{
994 				// Successfully read a user-defined images item, put it into our image manager
995 				aImageManager.insert( ImageManager::value_type( aURL, *pImageEntry ));
996 				delete pImageEntry; // We have the ownership of the pointer
997 			}
998 		}
999 	}
1000 
1001 	return sal_True;
1002 }
1003 
1004 //*****************************************************************************************************************
1005 //	private method
1006 //*****************************************************************************************************************
1007 
GeneratePrefixURL()1008 ::rtl::OUString AddonsOptions_Impl::GeneratePrefixURL()
1009 {
1010 	// Create an unique prefixed Add-On popup menu URL so it can be identified later as a runtime popup menu.
1011 	// They use a different image manager, so they must be identified by the sfx2/framework code.
1012 	::rtl::OUString aPopupMenuURL;
1013 	::rtl::OUStringBuffer aBuf( m_aRootAddonPopupMenuURLPrexfix.getLength() + 3 );
1014 	aBuf.append( m_aRootAddonPopupMenuURLPrexfix );
1015 	aBuf.append( ::rtl::OUString::valueOf( ++m_nRootAddonPopupMenuId ));
1016 	aPopupMenuURL = aBuf.makeStringAndClear();
1017 	return aPopupMenuURL;
1018 }
1019 
1020 //*****************************************************************************************************************
1021 //	private method
1022 //*****************************************************************************************************************
1023 
ReadMenuMergeInstructions(MergeMenuInstructionContainer & aContainer)1024 sal_Bool AddonsOptions_Impl::ReadMenuMergeInstructions( MergeMenuInstructionContainer& aContainer )
1025 {
1026     const ::rtl::OUString aMenuMergeRootName( RTL_CONSTASCII_USTRINGPARAM( "AddonUI/OfficeMenuBarMerging/" ));
1027 
1028 	Sequence< ::rtl::OUString >	aAddonMergeNodesSeq = GetNodeNames( aMenuMergeRootName );
1029 	::rtl::OUString                aAddonMergeNode( aMenuMergeRootName );
1030 
1031 	sal_uInt32              nCount = aAddonMergeNodesSeq.getLength();
1032 
1033 	// Init the property value sequence
1034 	Sequence< ::rtl::OUString >	aNodePropNames( 5 );
1035 	::rtl::OUString                aURL;
1036 
1037 	for ( sal_uInt32 i = 0; i < nCount; i++ )
1038     {
1039 		::rtl::OUString aMergeAddonInstructions( aAddonMergeNode + aAddonMergeNodesSeq[i] );
1040 
1041         Sequence< ::rtl::OUString > aAddonInstMergeNodesSeq = GetNodeNames( aMergeAddonInstructions );
1042         sal_uInt32           nCountAddons = aAddonInstMergeNodesSeq.getLength();
1043 
1044         for ( sal_uInt32 j = 0; j < nCountAddons; j++ )
1045 	    {
1046 		    ::rtl::OUStringBuffer aMergeAddonInstructionBase( aMergeAddonInstructions );
1047             aMergeAddonInstructionBase.append( m_aPathDelimiter );
1048             aMergeAddonInstructionBase.append( aAddonInstMergeNodesSeq[j] );
1049             aMergeAddonInstructionBase.append( m_aPathDelimiter );
1050 
1051             // Create sequence for data access
1052             ::rtl::OUStringBuffer aBuffer( aMergeAddonInstructionBase );
1053 		    aBuffer.append( m_aPropMergeMenuNames[ OFFSET_MERGEMENU_MERGEPOINT ] );
1054 		    aNodePropNames[0] = aBuffer.makeStringAndClear();
1055 
1056             aBuffer = aMergeAddonInstructionBase;
1057             aBuffer.append( m_aPropMergeMenuNames[ OFFSET_MERGEMENU_MERGECOMMAND ] );
1058             aNodePropNames[1] = aBuffer.makeStringAndClear();
1059 
1060             aBuffer = aMergeAddonInstructionBase;
1061             aBuffer.append( m_aPropMergeMenuNames[ OFFSET_MERGEMENU_MERGECOMMANDPARAMETER ] );
1062             aNodePropNames[2] = aBuffer.makeStringAndClear();
1063 
1064             aBuffer = aMergeAddonInstructionBase;
1065             aBuffer.append( m_aPropMergeMenuNames[ OFFSET_MERGEMENU_MERGEFALLBACK ] );
1066             aNodePropNames[3] = aBuffer.makeStringAndClear();
1067 
1068             aBuffer = aMergeAddonInstructionBase;
1069             aBuffer.append( m_aPropMergeMenuNames[ OFFSET_MERGEMENU_MERGECONTEXT ] );
1070             aNodePropNames[4] = aBuffer.makeStringAndClear();
1071 
1072             Sequence< Any > aNodePropValues = GetProperties( aNodePropNames );
1073 
1074             MergeMenuInstruction aMergeMenuInstruction;
1075             aNodePropValues[0] >>= aMergeMenuInstruction.aMergePoint;
1076             aNodePropValues[1] >>= aMergeMenuInstruction.aMergeCommand;
1077             aNodePropValues[2] >>= aMergeMenuInstruction.aMergeCommandParameter;
1078             aNodePropValues[3] >>= aMergeMenuInstruction.aMergeFallback;
1079             aNodePropValues[4] >>= aMergeMenuInstruction.aMergeContext;
1080 
1081             ::rtl::OUString aMergeMenuBase = aMergeAddonInstructionBase.makeStringAndClear();
1082             ReadMergeMenuData( aMergeMenuBase, aMergeMenuInstruction.aMergeMenu );
1083 
1084             aContainer.push_back( aMergeMenuInstruction );
1085         }
1086     }
1087 
1088     return sal_True;
1089 }
1090 
1091 //*****************************************************************************************************************
1092 //	private method
1093 //*****************************************************************************************************************
ReadMergeMenuData(const::rtl::OUString & aMergeAddonInstructionBase,Sequence<Sequence<PropertyValue>> & rMergeMenu)1094 sal_Bool AddonsOptions_Impl::ReadMergeMenuData( const ::rtl::OUString& aMergeAddonInstructionBase, Sequence< Sequence< PropertyValue > >& rMergeMenu )
1095 {
1096     ::rtl::OUString aMergeMenuBaseNode( aMergeAddonInstructionBase+m_aPropMergeMenuNames[ OFFSET_MERGEMENU_MENUITEMS ] );
1097 
1098     Sequence< ::rtl::OUString > aSubMenuNodeNames = GetNodeNames( aMergeMenuBaseNode );
1099     aMergeMenuBaseNode += m_aPathDelimiter;
1100 
1101     // extend the node names to have full path strings
1102     for ( sal_uInt32 i = 0; i < (sal_uInt32)aSubMenuNodeNames.getLength(); i++ )
1103 		aSubMenuNodeNames[i] = ::rtl::OUString( aMergeMenuBaseNode + aSubMenuNodeNames[i] );
1104 
1105     return ReadSubMenuEntries( aSubMenuNodeNames, rMergeMenu );
1106 }
1107 
1108 //*****************************************************************************************************************
1109 //	private method
1110 //*****************************************************************************************************************
ReadToolbarMergeInstructions(ToolbarMergingInstructions & rCachedToolbarMergingInstructions)1111 sal_Bool AddonsOptions_Impl::ReadToolbarMergeInstructions( ToolbarMergingInstructions& rCachedToolbarMergingInstructions )
1112 {
1113     const ::rtl::OUString aToolbarMergeRootName( RTL_CONSTASCII_USTRINGPARAM( "AddonUI/OfficeToolbarMerging/" ));
1114 
1115 	Sequence< ::rtl::OUString >	aAddonMergeNodesSeq = GetNodeNames( aToolbarMergeRootName );
1116 	::rtl::OUString                aAddonMergeNode( aToolbarMergeRootName );
1117 
1118 	sal_uInt32              nCount = aAddonMergeNodesSeq.getLength();
1119 
1120 	// Init the property value sequence
1121 	Sequence< ::rtl::OUString >	aNodePropNames( 6 );
1122 	::rtl::OUString                aURL;
1123 
1124 	for ( sal_uInt32 i = 0; i < nCount; i++ )
1125     {
1126 		::rtl::OUString aMergeAddonInstructions( aAddonMergeNode + aAddonMergeNodesSeq[i] );
1127 
1128         Sequence< ::rtl::OUString > aAddonInstMergeNodesSeq = GetNodeNames( aMergeAddonInstructions );
1129         sal_uInt32           nCountAddons = aAddonInstMergeNodesSeq.getLength();
1130 
1131         for ( sal_uInt32 j = 0; j < nCountAddons; j++ )
1132 	    {
1133 		    ::rtl::OUStringBuffer aMergeAddonInstructionBase( aMergeAddonInstructions );
1134             aMergeAddonInstructionBase.append( m_aPathDelimiter );
1135             aMergeAddonInstructionBase.append( aAddonInstMergeNodesSeq[j] );
1136             aMergeAddonInstructionBase.append( m_aPathDelimiter );
1137 
1138             // Create sequence for data access
1139             ::rtl::OUStringBuffer aBuffer( aMergeAddonInstructionBase );
1140 		    aBuffer.append( m_aPropMergeToolbarNames[ OFFSET_MERGETOOLBAR_TOOLBAR ] );
1141 		    aNodePropNames[0] = aBuffer.makeStringAndClear();
1142 
1143             aBuffer = aMergeAddonInstructionBase;
1144 		    aBuffer.append( m_aPropMergeToolbarNames[ OFFSET_MERGETOOLBAR_MERGEPOINT ] );
1145 		    aNodePropNames[1] = aBuffer.makeStringAndClear();
1146 
1147             aBuffer = aMergeAddonInstructionBase;
1148             aBuffer.append( m_aPropMergeToolbarNames[ OFFSET_MERGETOOLBAR_MERGECOMMAND ] );
1149             aNodePropNames[2] = aBuffer.makeStringAndClear();
1150 
1151             aBuffer = aMergeAddonInstructionBase;
1152             aBuffer.append( m_aPropMergeToolbarNames[ OFFSET_MERGETOOLBAR_MERGECOMMANDPARAMETER ] );
1153             aNodePropNames[3] = aBuffer.makeStringAndClear();
1154 
1155             aBuffer = aMergeAddonInstructionBase;
1156             aBuffer.append( m_aPropMergeToolbarNames[ OFFSET_MERGETOOLBAR_MERGEFALLBACK ] );
1157             aNodePropNames[4] = aBuffer.makeStringAndClear();
1158 
1159             aBuffer = aMergeAddonInstructionBase;
1160             aBuffer.append( m_aPropMergeToolbarNames[ OFFSET_MERGETOOLBAR_MERGECONTEXT ] );
1161             aNodePropNames[5] = aBuffer.makeStringAndClear();
1162 
1163             Sequence< Any > aNodePropValues = GetProperties( aNodePropNames );
1164 
1165             MergeToolbarInstruction aMergeToolbarInstruction;
1166             aNodePropValues[0] >>= aMergeToolbarInstruction.aMergeToolbar;
1167             aNodePropValues[1] >>= aMergeToolbarInstruction.aMergePoint;
1168             aNodePropValues[2] >>= aMergeToolbarInstruction.aMergeCommand;
1169             aNodePropValues[3] >>= aMergeToolbarInstruction.aMergeCommandParameter;
1170             aNodePropValues[4] >>= aMergeToolbarInstruction.aMergeFallback;
1171             aNodePropValues[5] >>= aMergeToolbarInstruction.aMergeContext;
1172 
1173             ReadMergeToolbarData( aMergeAddonInstructionBase.makeStringAndClear(),
1174                                   aMergeToolbarInstruction.aMergeToolbarItems );
1175 
1176             MergeToolbarInstructionContainer& rVector = rCachedToolbarMergingInstructions[ aMergeToolbarInstruction.aMergeToolbar ];
1177             rVector.push_back( aMergeToolbarInstruction );
1178         }
1179     }
1180 
1181     return sal_True;
1182 }
1183 
1184 //*****************************************************************************************************************
1185 //	private method
1186 //*****************************************************************************************************************
ReadMergeToolbarData(const::rtl::OUString & aMergeAddonInstructionBase,Sequence<Sequence<PropertyValue>> & rMergeToolbarItems)1187 sal_Bool AddonsOptions_Impl::ReadMergeToolbarData( const ::rtl::OUString& aMergeAddonInstructionBase, Sequence< Sequence< PropertyValue > >& rMergeToolbarItems )
1188 {
1189     ::rtl::OUStringBuffer aBuffer( aMergeAddonInstructionBase );
1190     aBuffer.append( m_aPropMergeToolbarNames[ OFFSET_MERGETOOLBAR_TOOLBARITEMS ] );
1191 
1192     ::rtl::OUString aMergeToolbarBaseNode = aBuffer.makeStringAndClear();
1193 
1194     return ReadToolBarItemSet( aMergeToolbarBaseNode, rMergeToolbarItems );
1195 }
1196 
1197 
ReadStatusbarMergeInstructions(MergeStatusbarInstructionContainer & aContainer)1198 sal_Bool AddonsOptions_Impl::ReadStatusbarMergeInstructions( MergeStatusbarInstructionContainer& aContainer )
1199 {
1200     const ::rtl::OUString aStatusbarMergeRootName( RTL_CONSTASCII_USTRINGPARAM( "AddonUI/OfficeStatusbarMerging/" ));
1201 
1202     Sequence< ::rtl::OUString > aAddonMergeNodesSeq = GetNodeNames( aStatusbarMergeRootName );
1203     ::rtl::OUString aAddonMergeNode( aStatusbarMergeRootName );
1204     sal_uInt32  nCount = aAddonMergeNodesSeq.getLength();
1205 
1206     Sequence< ::rtl::OUString > aNodePropNames( 5 );
1207     ::rtl::OUString aURL;
1208 
1209     for ( sal_uInt32 i = 0; i < nCount; i++ )
1210     {
1211         ::rtl::OUString aMergeAddonInstructions( aAddonMergeNode + aAddonMergeNodesSeq[i] );
1212 
1213         Sequence< ::rtl::OUString > aAddonInstMergeNodesSeq = GetNodeNames( aMergeAddonInstructions );
1214         sal_uInt32 nCountAddons = aAddonInstMergeNodesSeq.getLength();
1215 
1216         for ( sal_uInt32 j = 0; j < nCountAddons; j++ )
1217         {
1218             ::rtl::OUStringBuffer aMergeAddonInstructionBase( aMergeAddonInstructions );
1219             aMergeAddonInstructionBase.append( m_aPathDelimiter );
1220             aMergeAddonInstructionBase.append( aAddonInstMergeNodesSeq[j] );
1221             aMergeAddonInstructionBase.append( m_aPathDelimiter );
1222 
1223             // Create sequence for data access
1224             ::rtl::OUStringBuffer aBuffer( aMergeAddonInstructionBase );
1225             aBuffer.append( m_aPropMergeMenuNames[ OFFSET_MERGESTATUSBAR_MERGEPOINT ] );
1226             aNodePropNames[0] = aBuffer.makeStringAndClear();
1227 
1228             aBuffer = aMergeAddonInstructionBase;
1229             aBuffer.append( m_aPropMergeMenuNames[ OFFSET_MERGESTATUSBAR_MERGECOMMAND ] );
1230             aNodePropNames[1] = aBuffer.makeStringAndClear();
1231 
1232             aBuffer = aMergeAddonInstructionBase;
1233             aBuffer.append( m_aPropMergeMenuNames[ OFFSET_MERGESTATUSBAR_MERGECOMMANDPARAMETER ] );
1234             aNodePropNames[2] = aBuffer.makeStringAndClear();
1235 
1236             aBuffer = aMergeAddonInstructionBase;
1237             aBuffer.append( m_aPropMergeMenuNames[ OFFSET_MERGESTATUSBAR_MERGEFALLBACK ] );
1238             aNodePropNames[3] = aBuffer.makeStringAndClear();
1239 
1240             aBuffer = aMergeAddonInstructionBase;
1241             aBuffer.append( m_aPropMergeMenuNames[ OFFSET_MERGESTATUSBAR_MERGECONTEXT ] );
1242             aNodePropNames[4] = aBuffer.makeStringAndClear();
1243 
1244             Sequence< Any > aNodePropValues = GetProperties( aNodePropNames );
1245 
1246             MergeStatusbarInstruction aMergeStatusbarInstruction;
1247             aNodePropValues[0] >>= aMergeStatusbarInstruction.aMergePoint;
1248             aNodePropValues[1] >>= aMergeStatusbarInstruction.aMergeCommand;
1249             aNodePropValues[2] >>= aMergeStatusbarInstruction.aMergeCommandParameter;
1250             aNodePropValues[3] >>= aMergeStatusbarInstruction.aMergeFallback;
1251             aNodePropValues[4] >>= aMergeStatusbarInstruction.aMergeContext;
1252 
1253             ReadMergeStatusbarData( aMergeAddonInstructionBase.makeStringAndClear(),
1254                                     aMergeStatusbarInstruction.aMergeStatusbarItems );
1255 
1256             aContainer.push_back( aMergeStatusbarInstruction );
1257         }
1258     }
1259 
1260     return sal_True;
1261 }
1262 
ReadMergeStatusbarData(const::rtl::OUString & aMergeAddonInstructionBase,Sequence<Sequence<PropertyValue>> & rMergeStatusbarItems)1263 sal_Bool AddonsOptions_Impl::ReadMergeStatusbarData(
1264     const ::rtl::OUString& aMergeAddonInstructionBase,
1265     Sequence< Sequence< PropertyValue > >& rMergeStatusbarItems )
1266 {
1267     sal_uInt32 nStatusbarItemCount = rMergeStatusbarItems.getLength();
1268 
1269     ::rtl::OUStringBuffer aBuffer( aMergeAddonInstructionBase );
1270     aBuffer.append( m_aPropMergeStatusbarNames[ OFFSET_MERGESTATUSBAR_STATUSBARITEMS ] );
1271     ::rtl::OUString aMergeStatusbarBaseNode = aBuffer.makeStringAndClear();
1272 
1273     ::rtl::OUString aAddonStatusbarItemSetNode( aMergeStatusbarBaseNode + m_aPathDelimiter );
1274     Sequence< ::rtl::OUString > aAddonStatusbarItemSetNodeSeq = GetNodeNames( aMergeStatusbarBaseNode );
1275 
1276     Sequence< PropertyValue > aStatusbarItem( PROPERTYCOUNT_STATUSBARITEM );
1277     aStatusbarItem[ OFFSET_STATUSBARITEM_URL       ].Name = m_aPropNames[ INDEX_URL       ];
1278     aStatusbarItem[ OFFSET_STATUSBARITEM_TITLE     ].Name = m_aPropNames[ INDEX_TITLE     ];
1279     aStatusbarItem[ OFFSET_STATUSBARITEM_CONTEXT   ].Name = m_aPropNames[ INDEX_CONTEXT   ];
1280     aStatusbarItem[ OFFSET_STATUSBARITEM_ALIGN     ].Name = m_aPropNames[ INDEX_ALIGN     ];
1281     aStatusbarItem[ OFFSET_STATUSBARITEM_AUTOSIZE  ].Name = m_aPropNames[ INDEX_AUTOSIZE  ];
1282     aStatusbarItem[ OFFSET_STATUSBARITEM_OWNERDRAW ].Name = m_aPropNames[ INDEX_OWNERDRAW ];
1283     aStatusbarItem[ OFFSET_STATUSBARITEM_WIDTH     ].Name = m_aPropNames[ INDEX_WIDTH     ];
1284 
1285     sal_uInt32 nCount = aAddonStatusbarItemSetNodeSeq.getLength();
1286     for ( sal_uInt32 n = 0; n < nCount; n++ )
1287     {
1288         ::rtl::OUString aStatusbarItemNode( aAddonStatusbarItemSetNode + aAddonStatusbarItemSetNodeSeq[n] );
1289 
1290         if ( ReadStatusBarItem( aStatusbarItemNode, aStatusbarItem ) )
1291         {
1292             sal_uInt32 nAddonCount = rMergeStatusbarItems.getLength();
1293             rMergeStatusbarItems.realloc( nAddonCount+1 );
1294             rMergeStatusbarItems[nAddonCount] = aStatusbarItem;
1295         }
1296     }
1297 
1298     return ( (sal_uInt32)rMergeStatusbarItems.getLength() > nStatusbarItemCount );
1299 }
1300 
ReadStatusBarItem(const::rtl::OUString & aStatusarItemNodeName,Sequence<PropertyValue> & aStatusbarItem)1301 sal_Bool AddonsOptions_Impl::ReadStatusBarItem(
1302     const ::rtl::OUString& aStatusarItemNodeName,
1303     Sequence< PropertyValue >& aStatusbarItem )
1304 {
1305     sal_Bool bResult( sal_False );
1306     ::rtl::OUString aURL;
1307     ::rtl::OUString aAddonStatusbarItemTreeNode( aStatusarItemNodeName + m_aPathDelimiter );
1308     Sequence< Any > aStatusbarItemNodePropValues;
1309 
1310     aStatusbarItemNodePropValues = GetProperties( GetPropertyNamesStatusbarItem( aAddonStatusbarItemTreeNode ) );
1311 
1312     // Command URL is required
1313     if (( aStatusbarItemNodePropValues[ OFFSET_STATUSBARITEM_URL ] >>= aURL ) && aURL.getLength() > 0 )
1314     {
1315         aStatusbarItem[ OFFSET_STATUSBARITEM_URL        ].Value <<= aURL;
1316         aStatusbarItem[ OFFSET_STATUSBARITEM_TITLE      ].Value <<= aStatusbarItemNodePropValues[ OFFSET_STATUSBARITEM_TITLE     ];
1317         aStatusbarItem[ OFFSET_STATUSBARITEM_CONTEXT    ].Value <<= aStatusbarItemNodePropValues[ OFFSET_STATUSBARITEM_CONTEXT   ];
1318         aStatusbarItem[ OFFSET_STATUSBARITEM_ALIGN      ].Value <<= aStatusbarItemNodePropValues[ OFFSET_STATUSBARITEM_ALIGN     ];
1319         aStatusbarItem[ OFFSET_STATUSBARITEM_AUTOSIZE   ].Value <<= aStatusbarItemNodePropValues[ OFFSET_STATUSBARITEM_AUTOSIZE  ];;
1320         aStatusbarItem[ OFFSET_STATUSBARITEM_OWNERDRAW  ].Value <<= aStatusbarItemNodePropValues[ OFFSET_STATUSBARITEM_OWNERDRAW ];
1321 
1322         // Configuration uses hyper for long. Therefore transform into sal_Int32
1323         sal_Int64 nValue( 0 );
1324         aStatusbarItemNodePropValues[ OFFSET_STATUSBARITEM_WIDTH ] >>= nValue;
1325         aStatusbarItem[ OFFSET_STATUSBARITEM_WIDTH ].Value <<= sal_Int32( nValue );
1326 
1327         bResult = sal_True;
1328     }
1329 
1330     return bResult;
1331 }
1332 
1333 //*****************************************************************************************************************
1334 //	private method
1335 //*****************************************************************************************************************
ReadMenuItem(const::rtl::OUString & aMenuNodeName,Sequence<PropertyValue> & aMenuItem,sal_Bool bIgnoreSubMenu)1336 sal_Bool AddonsOptions_Impl::ReadMenuItem( const ::rtl::OUString& aMenuNodeName, Sequence< PropertyValue >& aMenuItem, sal_Bool bIgnoreSubMenu )
1337 {
1338 	sal_Bool			bResult = sal_False;
1339 	::rtl::OUString			aStrValue;
1340 	::rtl::OUString			aAddonMenuItemTreeNode( aMenuNodeName + m_aPathDelimiter );
1341 	Sequence< Any >		aMenuItemNodePropValues;
1342 
1343 	aMenuItemNodePropValues = GetProperties( GetPropertyNamesMenuItem( aAddonMenuItemTreeNode ) );
1344 	if (( aMenuItemNodePropValues[ OFFSET_MENUITEM_TITLE ] >>= aStrValue ) && aStrValue.getLength() > 0 )
1345 	{
1346 		aMenuItem[ OFFSET_MENUITEM_TITLE ].Value <<= aStrValue;
1347 
1348 		::rtl::OUString aRootSubMenuName( aAddonMenuItemTreeNode + m_aPropNames[ INDEX_SUBMENU ] );
1349 		Sequence< ::rtl::OUString > aRootSubMenuNodeNames = GetNodeNames( aRootSubMenuName );
1350 		if ( aRootSubMenuNodeNames.getLength() > 0 && !bIgnoreSubMenu )
1351 		{
1352 			// Set a unique prefixed Add-On popup menu URL so it can be identified later
1353 			::rtl::OUString aPopupMenuURL     = GeneratePrefixURL();
1354             ::rtl::OUString aPopupMenuImageId;
1355 
1356             aMenuItemNodePropValues[ OFFSET_MENUITEM_IMAGEIDENTIFIER ] >>= aPopupMenuImageId;
1357             ReadAndAssociateImages( aPopupMenuURL, aPopupMenuImageId );
1358 
1359 			// A popup menu must have a title and can have a URL and ImageIdentifier
1360 			// Set the other property values to empty
1361 			aMenuItem[ OFFSET_MENUITEM_URL				].Value <<= aPopupMenuURL;
1362 			aMenuItem[ OFFSET_MENUITEM_TARGET			].Value <<= m_aEmpty;
1363 			aMenuItem[ OFFSET_MENUITEM_IMAGEIDENTIFIER	].Value <<= aPopupMenuImageId;
1364 			aMenuItem[ OFFSET_MENUITEM_CONTEXT			].Value <<= aMenuItemNodePropValues[ OFFSET_MENUITEM_CONTEXT ];
1365 
1366 			// Continue to read the sub menu nodes
1367 			Sequence< Sequence< PropertyValue > > aSubMenuSeq;
1368 			::rtl::OUString aSubMenuRootNodeName( aRootSubMenuName + m_aPathDelimiter );
1369 			for ( sal_uInt32 n = 0; n < (sal_uInt32)aRootSubMenuNodeNames.getLength(); n++ )
1370 				aRootSubMenuNodeNames[n] = ::rtl::OUString( aSubMenuRootNodeName + aRootSubMenuNodeNames[n] );
1371 			ReadSubMenuEntries( aRootSubMenuNodeNames, aSubMenuSeq );
1372 			aMenuItem[ OFFSET_MENUITEM_SUBMENU ].Value <<= aSubMenuSeq;
1373 			bResult = sal_True;
1374 		}
1375 		else if (( aMenuItemNodePropValues[ OFFSET_MENUITEM_URL ] >>= aStrValue ) && aStrValue.getLength() > 0 )
1376 		{
1377 			// A simple menu item => read the other properties;
1378 			::rtl::OUString aMenuImageId;
1379 
1380 			aMenuItemNodePropValues[ OFFSET_MENUITEM_IMAGEIDENTIFIER ] >>= aMenuImageId;
1381  			ReadAndAssociateImages( aStrValue, aMenuImageId );
1382 
1383 			aMenuItem[ OFFSET_MENUITEM_URL				].Value <<= aStrValue;
1384 			aMenuItem[ OFFSET_MENUITEM_TARGET			].Value <<= aMenuItemNodePropValues[ OFFSET_MENUITEM_TARGET			];
1385 			aMenuItem[ OFFSET_MENUITEM_IMAGEIDENTIFIER	].Value <<= aMenuImageId;
1386 		    aMenuItem[ OFFSET_MENUITEM_CONTEXT			].Value <<= aMenuItemNodePropValues[ OFFSET_MENUITEM_CONTEXT        ];
1387 			aMenuItem[ OFFSET_MENUITEM_SUBMENU			].Value <<= Sequence< Sequence< PropertyValue > >(); // Submenu set!
1388 
1389 			bResult = sal_True;
1390 		}
1391 	}
1392 	else if (( aMenuItemNodePropValues[ OFFSET_MENUITEM_URL ] >>= aStrValue ) &&
1393 			  aStrValue.equalsAsciiL( SEPARATOR_URL_STR, SEPARATOR_URL_LEN ))
1394 	{
1395 		// Separator
1396 		aMenuItem[ OFFSET_MENUITEM_URL				].Value <<= aStrValue;
1397 		aMenuItem[ OFFSET_MENUITEM_TARGET			].Value <<= m_aEmpty;
1398 		aMenuItem[ OFFSET_MENUITEM_IMAGEIDENTIFIER	].Value <<= m_aEmpty;
1399 		aMenuItem[ OFFSET_MENUITEM_CONTEXT			].Value <<= m_aEmpty;
1400 		aMenuItem[ OFFSET_MENUITEM_SUBMENU			].Value <<= Sequence< Sequence< PropertyValue > >(); // Submenu set!
1401 		bResult = sal_True;
1402 	}
1403 
1404 	return bResult;
1405 }
1406 
1407 //*****************************************************************************************************************
1408 //	private method
1409 //*****************************************************************************************************************
ReadPopupMenu(const::rtl::OUString & aPopupMenuNodeName,Sequence<PropertyValue> & aPopupMenu)1410 sal_Bool AddonsOptions_Impl::ReadPopupMenu( const ::rtl::OUString& aPopupMenuNodeName, Sequence< PropertyValue >& aPopupMenu )
1411 {
1412 	sal_Bool			bResult = sal_False;
1413 	::rtl::OUString			aStrValue;
1414 	::rtl::OUString			aAddonPopupMenuTreeNode( aPopupMenuNodeName + m_aPathDelimiter );
1415 	Sequence< Any >		aPopupMenuNodePropValues;
1416 
1417 	aPopupMenuNodePropValues = GetProperties( GetPropertyNamesPopupMenu( aAddonPopupMenuTreeNode ) );
1418 	if (( aPopupMenuNodePropValues[ OFFSET_POPUPMENU_TITLE ] >>= aStrValue ) &&
1419 		 aStrValue.getLength() > 0 )
1420 	{
1421 		aPopupMenu[ OFFSET_POPUPMENU_TITLE ].Value <<= aStrValue;
1422 
1423 		::rtl::OUString aRootSubMenuName( aAddonPopupMenuTreeNode + m_aPropNames[ INDEX_SUBMENU ] );
1424 		Sequence< ::rtl::OUString > aRootSubMenuNodeNames = GetNodeNames( aRootSubMenuName );
1425 		if ( aRootSubMenuNodeNames.getLength() > 0 )
1426 		{
1427 			// A top-level popup menu needs a title
1428 			// Set a unique prefixed Add-On popup menu URL so it can be identified later
1429 			::rtl::OUString aPopupMenuURL = GeneratePrefixURL();
1430 
1431             aPopupMenu[ OFFSET_POPUPMENU_URL		].Value <<= aPopupMenuURL;
1432 			aPopupMenu[ OFFSET_POPUPMENU_CONTEXT	].Value <<= aPopupMenuNodePropValues[ OFFSET_POPUPMENU_CONTEXT ];
1433 
1434 			// Continue to read the sub menu nodes
1435 			Sequence< Sequence< PropertyValue > > aSubMenuSeq;
1436 			::rtl::OUString aSubMenuRootNodeName( aRootSubMenuName + m_aPathDelimiter );
1437 			for ( sal_uInt32 n = 0; n < (sal_uInt32)aRootSubMenuNodeNames.getLength(); n++ )
1438 				aRootSubMenuNodeNames[n] = ::rtl::OUString( aSubMenuRootNodeName + aRootSubMenuNodeNames[n] );
1439 			ReadSubMenuEntries( aRootSubMenuNodeNames, aSubMenuSeq );
1440 			aPopupMenu[ OFFSET_POPUPMENU_SUBMENU ].Value <<= aSubMenuSeq;
1441 			bResult = sal_True;
1442 		}
1443 	}
1444 
1445 	return bResult;
1446 }
1447 
1448 //*****************************************************************************************************************
1449 //	private method
1450 //*****************************************************************************************************************
AppendPopupMenu(Sequence<PropertyValue> & rTargetPopupMenu,const Sequence<PropertyValue> & rSourcePopupMenu)1451 sal_Bool AddonsOptions_Impl::AppendPopupMenu( Sequence< PropertyValue >& rTargetPopupMenu, const Sequence< PropertyValue >& rSourcePopupMenu )
1452 {
1453     Sequence< Sequence< PropertyValue > > aTargetSubMenuSeq;
1454     Sequence< Sequence< PropertyValue > > aSourceSubMenuSeq;
1455 
1456     if (( rTargetPopupMenu[ OFFSET_POPUPMENU_SUBMENU ].Value >>= aTargetSubMenuSeq ) &&
1457         ( rSourcePopupMenu[ OFFSET_POPUPMENU_SUBMENU ].Value >>= aSourceSubMenuSeq ))
1458     {
1459         sal_uInt32 nIndex = aTargetSubMenuSeq.getLength();
1460         aTargetSubMenuSeq.realloc( nIndex + aSourceSubMenuSeq.getLength() );
1461         for ( sal_uInt32 i = 0; i < sal_uInt32( aSourceSubMenuSeq.getLength() ); i++ )
1462             aTargetSubMenuSeq[nIndex++] = aSourceSubMenuSeq[i];
1463         rTargetPopupMenu[ OFFSET_POPUPMENU_SUBMENU ].Value <<= aTargetSubMenuSeq;
1464     }
1465 
1466     return sal_True;
1467 }
1468 
1469 //*****************************************************************************************************************
1470 //	private method
1471 //*****************************************************************************************************************
ReadToolBarItem(const::rtl::OUString & aToolBarItemNodeName,Sequence<PropertyValue> & aToolBarItem)1472 sal_Bool AddonsOptions_Impl::ReadToolBarItem( const ::rtl::OUString& aToolBarItemNodeName, Sequence< PropertyValue >& aToolBarItem )
1473 {
1474 	sal_Bool			bResult = sal_False;
1475 	::rtl::OUString			aTitle;
1476 	::rtl::OUString			aURL;
1477 	::rtl::OUString			aAddonToolBarItemTreeNode( aToolBarItemNodeName + m_aPathDelimiter );
1478 	Sequence< Any >		aToolBarItemNodePropValues;
1479 
1480 	aToolBarItemNodePropValues = GetProperties( GetPropertyNamesToolBarItem( aAddonToolBarItemTreeNode ) );
1481 
1482 	// A toolbar item must have a command URL
1483 	if (( aToolBarItemNodePropValues[ OFFSET_TOOLBARITEM_URL ] >>= aURL ) && aURL.getLength() > 0 )
1484 	{
1485 		if ( aURL.equals( SEPARATOR_URL ))
1486 		{
1487 			// A speparator toolbar item only needs a URL
1488 			aToolBarItem[ OFFSET_TOOLBARITEM_URL				].Value <<= aURL;
1489 			aToolBarItem[ OFFSET_TOOLBARITEM_TITLE				].Value <<= m_aEmpty;
1490 			aToolBarItem[ OFFSET_TOOLBARITEM_TARGET				].Value <<= m_aEmpty;
1491 			aToolBarItem[ OFFSET_TOOLBARITEM_IMAGEIDENTIFIER	].Value <<= m_aEmpty;
1492 			aToolBarItem[ OFFSET_TOOLBARITEM_CONTEXT			].Value <<= m_aEmpty;
1493 			aToolBarItem[ OFFSET_TOOLBARITEM_CONTROLTYPE		].Value <<= m_aEmpty;
1494 			aToolBarItem[ OFFSET_TOOLBARITEM_WIDTH		        ].Value <<= sal_Int32( 0 );
1495 
1496 			bResult = sal_True;
1497 		}
1498 		else if (( aToolBarItemNodePropValues[ OFFSET_TOOLBARITEM_TITLE	] >>= aTitle ) && aTitle.getLength() > 0 )
1499 		{
1500 			// A normal toolbar item must also have title => read the other properties;
1501 			::rtl::OUString aImageId;
1502 
1503             // Try to map a user-defined image URL to our internal private image URL
1504 			aToolBarItemNodePropValues[ OFFSET_TOOLBARITEM_IMAGEIDENTIFIER ] >>= aImageId;
1505  			ReadAndAssociateImages( aURL, aImageId );
1506 
1507 			aToolBarItem[ OFFSET_TOOLBARITEM_URL				].Value <<= aURL;
1508 			aToolBarItem[ OFFSET_TOOLBARITEM_TITLE				].Value <<= aTitle;
1509 			aToolBarItem[ OFFSET_TOOLBARITEM_TARGET				].Value <<= aToolBarItemNodePropValues[ OFFSET_TOOLBARITEM_TARGET	   ];
1510 			aToolBarItem[ OFFSET_TOOLBARITEM_IMAGEIDENTIFIER	].Value <<= aImageId;
1511 			aToolBarItem[ OFFSET_TOOLBARITEM_CONTEXT			].Value <<= aToolBarItemNodePropValues[ OFFSET_TOOLBARITEM_CONTEXT	   ];
1512 			aToolBarItem[ OFFSET_TOOLBARITEM_CONTROLTYPE		].Value <<= aToolBarItemNodePropValues[ OFFSET_TOOLBARITEM_CONTROLTYPE ];
1513 
1514             // Configuration uses hyper for long. Therefore transform into sal_Int32
1515             sal_Int64 nValue( 0 );
1516             aToolBarItemNodePropValues[ OFFSET_TOOLBARITEM_WIDTH ] >>= nValue;
1517             aToolBarItem[ OFFSET_TOOLBARITEM_WIDTH		        ].Value <<= sal_Int32( nValue );
1518 
1519 			bResult = sal_True;
1520 		}
1521 	}
1522 
1523 	return bResult;
1524 }
1525 
1526 //*****************************************************************************************************************
1527 //	private method
1528 //*****************************************************************************************************************
ReadSubMenuEntries(const Sequence<::rtl::OUString> & aSubMenuNodeNames,Sequence<Sequence<PropertyValue>> & rSubMenuSeq)1529 sal_Bool AddonsOptions_Impl::ReadSubMenuEntries( const Sequence< ::rtl::OUString >& aSubMenuNodeNames, Sequence< Sequence< PropertyValue > >& rSubMenuSeq )
1530 {
1531 	Sequence< PropertyValue > aMenuItem( PROPERTYCOUNT_MENUITEM );
1532 
1533 	// Init the property value sequence
1534 	aMenuItem[ OFFSET_MENUITEM_URL				].Name = PROPERTYNAME_URL;
1535 	aMenuItem[ OFFSET_MENUITEM_TITLE			].Name = PROPERTYNAME_TITLE;
1536 	aMenuItem[ OFFSET_MENUITEM_TARGET			].Name = PROPERTYNAME_TARGET;
1537 	aMenuItem[ OFFSET_MENUITEM_IMAGEIDENTIFIER	].Name = PROPERTYNAME_IMAGEIDENTIFIER;
1538 	aMenuItem[ OFFSET_MENUITEM_CONTEXT			].Name = PROPERTYNAME_CONTEXT;
1539 	aMenuItem[ OFFSET_MENUITEM_SUBMENU			].Name = PROPERTYNAME_SUBMENU;	// Submenu set!
1540 
1541 	sal_uInt32 nIndex = 0;
1542 	sal_uInt32 nCount = aSubMenuNodeNames.getLength();
1543 	for ( sal_uInt32 n = 0; n < nCount; n++ )
1544 	{
1545 		if ( ReadMenuItem( aSubMenuNodeNames[n], aMenuItem ))
1546 		{
1547 			sal_uInt32 nSubMenuCount = rSubMenuSeq.getLength() + 1;
1548 			rSubMenuSeq.realloc( nSubMenuCount );
1549 			rSubMenuSeq[nIndex++] = aMenuItem;
1550 		}
1551 	}
1552 
1553 	return sal_True;
1554 }
1555 
1556 //*****************************************************************************************************************
1557 //	private method
1558 //*****************************************************************************************************************
HasAssociatedImages(const::rtl::OUString & aURL)1559 sal_Bool AddonsOptions_Impl::HasAssociatedImages( const ::rtl::OUString& aURL )
1560 {
1561 	ImageManager::const_iterator pIter = m_aImageManager.find( aURL );
1562 	return ( pIter != m_aImageManager.end() );
1563 }
1564 
1565 //*****************************************************************************************************************
1566 //	private method
1567 //*****************************************************************************************************************
SubstituteVariables(::rtl::OUString & aURL)1568 void AddonsOptions_Impl::SubstituteVariables( ::rtl::OUString& aURL )
1569 {
1570     if (( aURL.compareToAscii( RTL_CONSTASCII_STRINGPARAM( EXPAND_PROTOCOL )) == 0 ) &&
1571         m_xMacroExpander.is() )
1572     {
1573         // cut protocol
1574         ::rtl::OUString macro( aURL.copy( sizeof ( EXPAND_PROTOCOL ) -1 ) );
1575         // decode uric class chars
1576         macro = ::rtl::Uri::decode(
1577             macro, rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8 );
1578         // expand macro string
1579         aURL = m_xMacroExpander->expandMacros( macro );
1580     }
1581 }
1582 
1583 //*****************************************************************************************************************
1584 //	private method
1585 //*****************************************************************************************************************
ReadImageFromURL(ImageSize nImageSize,const::rtl::OUString & aImageURL,Image & aImage,Image & aImageNoScale)1586 void AddonsOptions_Impl::ReadImageFromURL( ImageSize nImageSize, const ::rtl::OUString& aImageURL, Image& aImage, Image& aImageNoScale )
1587 {
1588     SvStream* pStream = UcbStreamHelper::CreateStream( aImageURL, STREAM_STD_READ );
1589     if ( pStream && ( pStream->GetErrorCode() == 0 ))
1590     {
1591         // Use graphic class to also support more graphic formats (bmp,png,...)
1592         Graphic aGraphic;
1593 
1594         GraphicFilter* pGF = GraphicFilter::GetGraphicFilter();
1595         pGF->ImportGraphic( aGraphic, String(), *pStream, GRFILTER_FORMAT_DONTKNOW );
1596 
1597         BitmapEx aBitmapEx = aGraphic.GetBitmapEx();
1598 
1599 	    const Size aSize = ( nImageSize == IMGSIZE_SMALL ) ? aImageSizeSmall : aImageSizeBig; // Sizes used for menu/toolbox images
1600 
1601         Size aBmpSize = aBitmapEx.GetSizePixel();
1602 	    if ( aBmpSize.Width() > 0 && aBmpSize.Height() > 0 )
1603         {
1604             // Support non-transparent bitmaps to be downward compatible with OOo 1.1.x addons
1605             if( !aBitmapEx.IsTransparent() )
1606                 aBitmapEx = BitmapEx( aBitmapEx.GetBitmap(), COL_LIGHTMAGENTA );
1607 
1608             // A non-scaled bitmap can have a flexible width, but must have a defined height!
1609             Size aNoScaleSize( aBmpSize.Width(), aSize.Height() );
1610             if ( aBmpSize != aNoScaleSize )
1611             {
1612                 BitmapEx aNoScaleBmp( aBitmapEx );
1613                 aNoScaleBmp.Scale( aNoScaleSize, BMP_SCALE_INTERPOLATE );
1614             }
1615             else
1616                 aImageNoScale = Image( aBitmapEx );
1617 
1618             if ( aBmpSize != aSize )
1619                 aBitmapEx.Scale( aSize, BMP_SCALE_INTERPOLATE );
1620 
1621             aImage = Image( aBitmapEx );
1622         }
1623     }
1624 
1625     delete pStream;
1626 }
1627 
1628 //*****************************************************************************************************************
1629 //	private method
1630 //*****************************************************************************************************************
ReadAndAssociateImages(const::rtl::OUString & aURL,const::rtl::OUString & aImageId)1631 void AddonsOptions_Impl::ReadAndAssociateImages( const ::rtl::OUString& aURL, const ::rtl::OUString& aImageId )
1632 {
1633     const int   MAX_NUM_IMAGES = 4;
1634     const char* aExtArray[MAX_NUM_IMAGES] = { "_16", "_26", "_16h", "_26h" };
1635     const char* pBmpExt = ".bmp";
1636 
1637     if ( aImageId.getLength() == 0 )
1638         return;
1639 
1640     bool        bImageFound = true;
1641     ImageEntry  aImageEntry;
1642     ::rtl::OUString    aImageURL( aImageId );
1643 
1644     SubstituteVariables( aImageURL );
1645 
1646     // Loop to create the four possible image names and try to read the bitmap files
1647     for ( int i = 0; i < MAX_NUM_IMAGES; i++ )
1648     {
1649         ::rtl::OUStringBuffer aFileURL( aImageURL );
1650         aFileURL.appendAscii( aExtArray[i] );
1651         aFileURL.appendAscii( pBmpExt );
1652 
1653         Image aImage;
1654         Image aImageNoScale;
1655         ReadImageFromURL( ((i==0)||(i==2)) ? IMGSIZE_SMALL : IMGSIZE_BIG, aFileURL.makeStringAndClear(), aImage, aImageNoScale );
1656         if ( !!aImage )
1657         {
1658             bImageFound = true;
1659             switch ( i )
1660             {
1661                 case 0:
1662                     aImageEntry.aImageSmall          = aImage;
1663                     aImageEntry.aImageSmallNoScale   = aImageNoScale;
1664                     break;
1665                 case 1:
1666                     aImageEntry.aImageBig            = aImage;
1667                     aImageEntry.aImageBigNoScale     = aImageNoScale;
1668                     break;
1669                 case 2:
1670                     aImageEntry.aImageSmallHC        = aImage;
1671                     aImageEntry.aImageSmallHCNoScale = aImageNoScale;
1672                     break;
1673                 case 3:
1674                     aImageEntry.aImageBigHC          = aImage;
1675                     aImageEntry.aImageBigHCNoScale   = aImageNoScale;
1676                     break;
1677             }
1678         }
1679     }
1680 
1681     if ( bImageFound )
1682         m_aImageManager.insert( ImageManager::value_type( aURL, aImageEntry ));
1683 }
1684 
1685 //*****************************************************************************************************************
1686 //	private method
1687 //*****************************************************************************************************************
ReadImageData(const::rtl::OUString & aImagesNodeName)1688 AddonsOptions_Impl::ImageEntry* AddonsOptions_Impl::ReadImageData( const ::rtl::OUString& aImagesNodeName )
1689 {
1690 	Sequence< ::rtl::OUString > aImageDataNodeNames = GetPropertyNamesImages( aImagesNodeName );
1691 	Sequence< Any >		 aPropertyData;
1692 	Sequence< sal_Int8 > aImageDataSeq;
1693 	::rtl::OUString             aImageURL;
1694 
1695 	ImageEntry* pEntry = NULL;
1696 
1697     // It is possible to use both forms (embedded image data and URLs to external bitmap files) at the
1698     // same time. Embedded image data has a higher priority.
1699 	aPropertyData = GetProperties( aImageDataNodeNames );
1700 	for ( int i = 0; i < PROPERTYCOUNT_IMAGES; i++ )
1701 	{
1702         if ( i < PROPERTYCOUNT_EMBEDDED_IMAGES )
1703         {
1704             // Extract image data from the embedded hex binary sequence
1705             Image aImage;
1706 		    if (( aPropertyData[i] >>= aImageDataSeq ) &&
1707 		        aImageDataSeq.getLength() > 0 &&
1708 			    ( CreateImageFromSequence( aImage,
1709 									    (( i == OFFSET_IMAGES_BIG ) ||
1710 									    ( i == OFFSET_IMAGES_BIGHC )),
1711 									    aImageDataSeq )) )
1712 		    {
1713 			    if ( !pEntry )
1714 				    pEntry = new ImageEntry;
1715 
1716 			    if ( i == OFFSET_IMAGES_SMALL )
1717 				    pEntry->aImageSmall = aImage;
1718 			    else if ( i == OFFSET_IMAGES_BIG )
1719 				    pEntry->aImageBig = aImage;
1720 			    else if ( i == OFFSET_IMAGES_SMALLHC )
1721 				    pEntry->aImageSmallHC = aImage;
1722 			    else
1723 				    pEntry->aImageBigHC = aImage;
1724 		    }
1725         }
1726         else
1727         {
1728             // Retrieve image data from a external bitmap file. Make sure that embedded image data
1729             // has a higher priority.
1730             aPropertyData[i] >>= aImageURL;
1731 
1732             if ( aImageURL.getLength() > 0 )
1733             {
1734                 Image aImage;
1735                 Image aImageNoScale;
1736 
1737                 SubstituteVariables( aImageURL );
1738                 ReadImageFromURL( ((i==OFFSET_IMAGES_SMALL_URL)||(i==OFFSET_IMAGES_SMALLHC_URL)) ? IMGSIZE_SMALL : IMGSIZE_BIG,
1739                                   aImageURL, aImage, aImageNoScale );
1740                 if ( !!aImage )
1741                 {
1742                     if ( !pEntry )
1743                         pEntry = new ImageEntry;
1744 
1745                     if ( i == OFFSET_IMAGES_SMALL_URL && !pEntry->aImageSmall )
1746                     {
1747                         pEntry->aImageSmall = aImage;
1748                         pEntry->aImageSmallNoScale = aImageNoScale;
1749                     }
1750                     else if ( i == OFFSET_IMAGES_BIG_URL && !pEntry->aImageBig )
1751                     {
1752                         pEntry->aImageBig = aImage;
1753                         pEntry->aImageBigNoScale = aImageNoScale;
1754                     }
1755 			        else if ( i == OFFSET_IMAGES_SMALLHC_URL && !pEntry->aImageSmallHC )
1756                     {
1757 				        pEntry->aImageSmallHC = aImage;
1758 				        pEntry->aImageSmallHCNoScale = aImageNoScale;
1759                     }
1760 			        else if ( !pEntry->aImageBigHC )
1761                     {
1762 				        pEntry->aImageBigHC = aImage;
1763 				        pEntry->aImageBigHCNoScale = aImageNoScale;
1764                     }
1765                 }
1766             }
1767         }
1768 	}
1769 
1770 	return pEntry;
1771 }
1772 
1773 //*****************************************************************************************************************
1774 //	private method
1775 //*****************************************************************************************************************
CreateImageFromSequence(Image & rImage,sal_Bool bBig,Sequence<sal_Int8> & rBitmapDataSeq) const1776 sal_Bool AddonsOptions_Impl::CreateImageFromSequence( Image& rImage, sal_Bool bBig, Sequence< sal_Int8 >& rBitmapDataSeq ) const
1777 {
1778 	sal_Bool	bResult = sal_False;
1779 	Size		aSize = bBig ? aImageSizeBig : aImageSizeSmall; // Sizes used for menu/toolbox images
1780 
1781 	if ( rBitmapDataSeq.getLength() > 0 )
1782 	{
1783 		SvMemoryStream	aMemStream( rBitmapDataSeq.getArray(), rBitmapDataSeq.getLength(), STREAM_STD_READ );
1784 		BitmapEx 		aBitmapEx;
1785 
1786         ReadDIBBitmapEx(aBitmapEx, aMemStream);
1787 
1788 		// Scale bitmap to fit the correct size for the menu/toolbar. Use best quality
1789 		if ( aBitmapEx.GetSizePixel() != aSize )
1790 			aBitmapEx.Scale( aSize, BMP_SCALE_INTERPOLATE );
1791 
1792         if( !aBitmapEx.IsTransparent() )
1793         {
1794             // Support non-transparent bitmaps to be downward compatible with OOo 1.1.x addons
1795             aBitmapEx = BitmapEx( aBitmapEx.GetBitmap(), COL_LIGHTMAGENTA );
1796         }
1797 
1798 		rImage = Image( aBitmapEx );
1799 		bResult = sal_True;
1800 	}
1801 
1802 	return bResult;
1803 }
1804 
1805 //*****************************************************************************************************************
1806 //	private methods
1807 //*****************************************************************************************************************
GetPropertyNamesMergeMenuInstruction(const::rtl::OUString & aPropertyRootNode) const1808 Sequence< ::rtl::OUString > AddonsOptions_Impl::GetPropertyNamesMergeMenuInstruction( const ::rtl::OUString& aPropertyRootNode ) const
1809 {
1810 	Sequence< ::rtl::OUString > lResult( PROPERTYCOUNT_MERGE_MENUBAR );
1811 
1812     // Create property names dependent from the root node name
1813     lResult[ OFFSET_MERGEMENU_MERGEPOINT            ] = ::rtl::OUString( aPropertyRootNode + m_aPropMergeMenuNames[ OFFSET_MERGEMENU_MERGEPOINT    ] );
1814     lResult[ OFFSET_MERGEMENU_MERGECOMMAND          ] = ::rtl::OUString( aPropertyRootNode + m_aPropMergeMenuNames[ OFFSET_MERGEMENU_MERGECOMMAND  ] );
1815     lResult[ OFFSET_MERGEMENU_MERGECOMMANDPARAMETER ] = ::rtl::OUString( aPropertyRootNode + m_aPropMergeMenuNames[ OFFSET_MERGEMENU_MERGECOMMANDPARAMETER ] );
1816     lResult[ OFFSET_MERGEMENU_MERGEFALLBACK         ] = ::rtl::OUString( aPropertyRootNode + m_aPropMergeMenuNames[ OFFSET_MERGEMENU_MERGEFALLBACK ] );
1817     lResult[ OFFSET_MERGEMENU_MERGECONTEXT          ] = ::rtl::OUString( aPropertyRootNode + m_aPropMergeMenuNames[ OFFSET_MERGEMENU_MERGECONTEXT  ] );
1818     lResult[ OFFSET_MERGEMENU_MENUITEMS             ] = ::rtl::OUString( aPropertyRootNode + m_aPropMergeMenuNames[ OFFSET_MERGEMENU_MENUITEMS     ] );
1819 
1820 	return lResult;
1821 }
1822 
GetPropertyNamesMenuItem(const::rtl::OUString & aPropertyRootNode) const1823 Sequence< ::rtl::OUString > AddonsOptions_Impl::GetPropertyNamesMenuItem( const ::rtl::OUString& aPropertyRootNode ) const
1824 {
1825 	Sequence< ::rtl::OUString > lResult( PROPERTYCOUNT_MENUITEM );
1826 
1827     // Create property names dependent from the root node name
1828 	lResult[OFFSET_MENUITEM_URL]             = ::rtl::OUString( aPropertyRootNode + m_aPropNames[ INDEX_URL			 ] );
1829 	lResult[OFFSET_MENUITEM_TITLE]           = ::rtl::OUString( aPropertyRootNode + m_aPropNames[ INDEX_TITLE			 ] );
1830 	lResult[OFFSET_MENUITEM_IMAGEIDENTIFIER] = ::rtl::OUString( aPropertyRootNode + m_aPropNames[ INDEX_IMAGEIDENTIFIER ] );
1831 	lResult[OFFSET_MENUITEM_TARGET]          = ::rtl::OUString( aPropertyRootNode + m_aPropNames[ INDEX_TARGET			 ] );
1832 	lResult[OFFSET_MENUITEM_CONTEXT]         = ::rtl::OUString( aPropertyRootNode + m_aPropNames[ INDEX_CONTEXT	     ] );
1833 	lResult[OFFSET_MENUITEM_SUBMENU]         = ::rtl::OUString( aPropertyRootNode + m_aPropNames[ INDEX_SUBMENU	     ] );
1834 
1835 	return lResult;
1836 }
1837 
1838 //*****************************************************************************************************************
1839 //	private method
1840 //*****************************************************************************************************************
GetPropertyNamesPopupMenu(const::rtl::OUString & aPropertyRootNode) const1841 Sequence< ::rtl::OUString > AddonsOptions_Impl::GetPropertyNamesPopupMenu( const ::rtl::OUString& aPropertyRootNode ) const
1842 {
1843 	// The URL is automatically set and not read from the configuration.
1844 	Sequence< ::rtl::OUString > lResult( PROPERTYCOUNT_POPUPMENU-1 );
1845 
1846 	// Create property names dependent from the root node name
1847 	lResult[OFFSET_POPUPMENU_TITLE]   = ::rtl::OUString( aPropertyRootNode + m_aPropNames[ INDEX_TITLE	] );
1848 	lResult[OFFSET_POPUPMENU_CONTEXT] = ::rtl::OUString( aPropertyRootNode + m_aPropNames[ INDEX_CONTEXT	] );
1849 	lResult[OFFSET_POPUPMENU_SUBMENU] = ::rtl::OUString( aPropertyRootNode + m_aPropNames[ INDEX_SUBMENU	] );
1850 
1851 	return lResult;
1852 }
1853 
1854 //*****************************************************************************************************************
1855 //	private method
1856 //*****************************************************************************************************************
GetPropertyNamesToolBar(const::rtl::OUString & aPropertyRootNode) const1857 Sequence< ::rtl::OUString > AddonsOptions_Impl::GetPropertyNamesToolBar( const ::rtl::OUString& aPropertyRootNode ) const
1858 {
1859     Sequence< ::rtl::OUString > lResult( PROPERTYCOUNT_TOOLBAR );
1860 
1861     // Create property names dependent from the root node name
1862     lResult[OFFSET_TOOLBAR_TITLE]        = ::rtl::OUString( aPropertyRootNode + m_aPropNames[ INDEX_TITLE ] );
1863     lResult[OFFSET_TOOLBAR_TOOLBARITEMS] = ::rtl::OUString( aPropertyRootNode + m_aPropNames[ INDEX_TOOLBARITEMS ] );
1864 
1865     return lResult;
1866 }
1867 
GetPropertyNamesToolBarItem(const::rtl::OUString & aPropertyRootNode) const1868 Sequence< ::rtl::OUString > AddonsOptions_Impl::GetPropertyNamesToolBarItem( const ::rtl::OUString& aPropertyRootNode ) const
1869 {
1870 	Sequence< ::rtl::OUString > lResult( PROPERTYCOUNT_TOOLBARITEM );
1871 
1872 	// Create property names dependent from the root node name
1873 	lResult[0] = ::rtl::OUString( aPropertyRootNode + m_aPropNames[ INDEX_URL			  ] );
1874 	lResult[1] = ::rtl::OUString( aPropertyRootNode + m_aPropNames[ INDEX_TITLE		  ] );
1875 	lResult[2] = ::rtl::OUString( aPropertyRootNode + m_aPropNames[ INDEX_IMAGEIDENTIFIER] );
1876 	lResult[3] = ::rtl::OUString( aPropertyRootNode + m_aPropNames[ INDEX_TARGET		  ] );
1877 	lResult[4] = ::rtl::OUString( aPropertyRootNode + m_aPropNames[ INDEX_CONTEXT		  ] );
1878 	lResult[5] = ::rtl::OUString( aPropertyRootNode + m_aPropNames[ INDEX_CONTROLTYPE	  ] );
1879 	lResult[6] = ::rtl::OUString( aPropertyRootNode + m_aPropNames[ INDEX_WIDTH		  ] );
1880 
1881 	return lResult;
1882 }
1883 
GetPropertyNamesStatusbarItem(const::rtl::OUString & aPropertyRootNode) const1884 Sequence< ::rtl::OUString > AddonsOptions_Impl::GetPropertyNamesStatusbarItem(
1885     const ::rtl::OUString& aPropertyRootNode ) const
1886 {
1887     Sequence< ::rtl::OUString > lResult( PROPERTYCOUNT_STATUSBARITEM );
1888 
1889     lResult[0] = ::rtl::OUString( aPropertyRootNode + m_aPropNames[ INDEX_URL       ] );
1890     lResult[1] = ::rtl::OUString( aPropertyRootNode + m_aPropNames[ INDEX_TITLE     ] );
1891     lResult[2] = ::rtl::OUString( aPropertyRootNode + m_aPropNames[ INDEX_CONTEXT   ] );
1892     lResult[3] = ::rtl::OUString( aPropertyRootNode + m_aPropNames[ INDEX_ALIGN     ] );
1893     lResult[4] = ::rtl::OUString( aPropertyRootNode + m_aPropNames[ INDEX_AUTOSIZE  ] );
1894     lResult[5] = ::rtl::OUString( aPropertyRootNode + m_aPropNames[ INDEX_OWNERDRAW ] );
1895     lResult[6] = ::rtl::OUString( aPropertyRootNode + m_aPropNames[ INDEX_WIDTH     ] );
1896 
1897     return lResult;
1898 }
1899 
1900 //*****************************************************************************************************************
1901 //	private method
1902 //*****************************************************************************************************************
GetPropertyNamesImages(const::rtl::OUString & aPropertyRootNode) const1903 Sequence< ::rtl::OUString > AddonsOptions_Impl::GetPropertyNamesImages( const ::rtl::OUString& aPropertyRootNode ) const
1904 {
1905 	Sequence< ::rtl::OUString > lResult( PROPERTYCOUNT_IMAGES );
1906 
1907 	// Create property names dependent from the root node name
1908 	lResult[0] = ::rtl::OUString( aPropertyRootNode + m_aPropImagesNames[ OFFSET_IMAGES_SMALL		] );
1909 	lResult[1] = ::rtl::OUString( aPropertyRootNode + m_aPropImagesNames[ OFFSET_IMAGES_BIG		] );
1910 	lResult[2] = ::rtl::OUString( aPropertyRootNode + m_aPropImagesNames[ OFFSET_IMAGES_SMALLHC	] );
1911 	lResult[3] = ::rtl::OUString( aPropertyRootNode + m_aPropImagesNames[ OFFSET_IMAGES_BIGHC		] );
1912 	lResult[4] = ::rtl::OUString( aPropertyRootNode + m_aPropImagesNames[ OFFSET_IMAGES_SMALL_URL  ] );
1913 	lResult[5] = ::rtl::OUString( aPropertyRootNode + m_aPropImagesNames[ OFFSET_IMAGES_BIG_URL	] );
1914 	lResult[6] = ::rtl::OUString( aPropertyRootNode + m_aPropImagesNames[ OFFSET_IMAGES_SMALLHC_URL] );
1915 	lResult[7] = ::rtl::OUString( aPropertyRootNode + m_aPropImagesNames[ OFFSET_IMAGES_BIGHC_URL	] );
1916 
1917 	return lResult;
1918 }
1919 
1920 //*****************************************************************************************************************
1921 //	initialize static member
1922 //	DON'T DO IT IN YOUR HEADER!
1923 //	see definition for further informations
1924 //*****************************************************************************************************************
1925 AddonsOptions_Impl*		AddonsOptions::m_pDataContainer = NULL  ;
1926 sal_Int32				AddonsOptions::m_nRefCount      = 0     ;
1927 
1928 //*****************************************************************************************************************
1929 //	constructor
1930 //*****************************************************************************************************************
AddonsOptions()1931 AddonsOptions::AddonsOptions()
1932 {
1933     // Global access, must be guarded (multithreading!).
1934     MutexGuard aGuard( GetOwnStaticMutex() );
1935 	// Increase our refcount ...
1936 	++m_nRefCount;
1937 	// ... and initialize our data container only if it not already exist!
1938     if( m_pDataContainer == NULL )
1939 	{
1940         m_pDataContainer = new AddonsOptions_Impl;
1941 	}
1942 }
1943 
1944 //*****************************************************************************************************************
1945 //	destructor
1946 //*****************************************************************************************************************
~AddonsOptions()1947 AddonsOptions::~AddonsOptions()
1948 {
1949     // Global access, must be guarded (multithreading!)
1950     MutexGuard aGuard( GetOwnStaticMutex() );
1951 	// Decrease our refcount.
1952 	--m_nRefCount;
1953 	// If last instance was deleted ...
1954 	// we must destroy our static data container!
1955     if( m_nRefCount <= 0 )
1956 	{
1957 		delete m_pDataContainer;
1958 		m_pDataContainer = NULL;
1959 	}
1960 }
1961 
1962 //*****************************************************************************************************************
1963 //	public method
1964 //*****************************************************************************************************************
HasAddonsMenu() const1965 sal_Bool AddonsOptions::HasAddonsMenu() const
1966 {
1967     MutexGuard aGuard( GetOwnStaticMutex() );
1968     return m_pDataContainer->HasAddonsMenu();
1969 }
1970 
1971 //*****************************************************************************************************************
1972 //	public method
1973 //*****************************************************************************************************************
1974 
HasAddonsHelpMenu() const1975 sal_Bool AddonsOptions::HasAddonsHelpMenu() const
1976 {
1977     MutexGuard aGuard( GetOwnStaticMutex() );
1978     return m_pDataContainer->HasAddonsHelpMenu();
1979 }
1980 
1981 //*****************************************************************************************************************
1982 //	public method
1983 //*****************************************************************************************************************
1984 
GetAddonsToolBarCount() const1985 sal_Int32 AddonsOptions::GetAddonsToolBarCount() const
1986 {
1987     MutexGuard aGuard( GetOwnStaticMutex() );
1988     return m_pDataContainer->GetAddonsToolBarCount();
1989 }
1990 
1991 //*****************************************************************************************************************
1992 //	public method
1993 //*****************************************************************************************************************
GetAddonsMenu() const1994 const Sequence< Sequence< PropertyValue > >& AddonsOptions::GetAddonsMenu() const
1995 {
1996     MutexGuard aGuard( GetOwnStaticMutex() );
1997     return m_pDataContainer->GetAddonsMenu();
1998 }
1999 
2000 //*****************************************************************************************************************
2001 //	public method
2002 //*****************************************************************************************************************
GetAddonsMenuBarPart() const2003 const Sequence< Sequence< PropertyValue > >& AddonsOptions::GetAddonsMenuBarPart() const
2004 {
2005     MutexGuard aGuard( GetOwnStaticMutex() );
2006     return m_pDataContainer->GetAddonsMenuBarPart();
2007 }
2008 
2009 //*****************************************************************************************************************
2010 //	public method
2011 //*****************************************************************************************************************
GetAddonsToolBarPart(sal_uInt32 nIndex) const2012 const Sequence< Sequence< PropertyValue > >& AddonsOptions::GetAddonsToolBarPart( sal_uInt32 nIndex ) const
2013 {
2014     MutexGuard aGuard( GetOwnStaticMutex() );
2015     return m_pDataContainer->GetAddonsToolBarPart( nIndex );
2016 }
2017 
2018 //*****************************************************************************************************************
2019 //	public method
2020 //*****************************************************************************************************************
GetAddonsToolbarResourceName(sal_uInt32 nIndex) const2021 const ::rtl::OUString AddonsOptions::GetAddonsToolbarResourceName( sal_uInt32 nIndex ) const
2022 {
2023     MutexGuard aGuard( GetOwnStaticMutex() );
2024     return m_pDataContainer->GetAddonsToolbarResourceName( nIndex );
2025 }
2026 
GetAddonsToolbarUIName(sal_uInt32 nIndex) const2027 const ::rtl::OUString AddonsOptions::GetAddonsToolbarUIName( sal_uInt32 nIndex ) const
2028 {
2029     MutexGuard aGuard( GetOwnStaticMutex() );
2030     return m_pDataContainer->GetAddonsToolbarUIName( nIndex );
2031 }
2032 
2033 //*****************************************************************************************************************
2034 //	public method
2035 //*****************************************************************************************************************
GetAddonsHelpMenu() const2036 const Sequence< Sequence< PropertyValue > >& AddonsOptions::GetAddonsHelpMenu() const
2037 {
2038     MutexGuard aGuard( GetOwnStaticMutex() );
2039     return m_pDataContainer->GetAddonsHelpMenu();
2040 }
2041 
2042 //*****************************************************************************************************************
2043 //	public method
2044 //*****************************************************************************************************************
GetMergeMenuInstructions() const2045 const MergeMenuInstructionContainer& AddonsOptions::GetMergeMenuInstructions() const
2046 {
2047     MutexGuard aGuard( GetOwnStaticMutex() );
2048     return m_pDataContainer->GetMergeMenuInstructions();
2049 }
2050 
2051 //*****************************************************************************************************************
2052 //	public method
2053 //*****************************************************************************************************************
GetMergeToolbarInstructions(const::rtl::OUString & rToolbarName,MergeToolbarInstructionContainer & rToolbarInstructions) const2054 bool AddonsOptions::GetMergeToolbarInstructions(
2055     const ::rtl::OUString& rToolbarName,
2056     MergeToolbarInstructionContainer& rToolbarInstructions ) const
2057 {
2058     MutexGuard aGuard( GetOwnStaticMutex() );
2059     return m_pDataContainer->GetMergeToolbarInstructions(
2060         rToolbarName, rToolbarInstructions );
2061 }
2062 
GetMergeStatusbarInstructions() const2063 const MergeStatusbarInstructionContainer& AddonsOptions::GetMergeStatusbarInstructions() const
2064 {
2065     MutexGuard aGuard( GetOwnStaticMutex() );
2066     return m_pDataContainer->GetMergeStatusbarInstructions();
2067 }
2068 
2069 //*****************************************************************************************************************
2070 //	public method
2071 //*****************************************************************************************************************
GetImageFromURL(const rtl::OUString & aURL,sal_Bool bBig,sal_Bool bHiContrast,sal_Bool bNoScale) const2072 Image AddonsOptions::GetImageFromURL( const rtl::OUString& aURL, sal_Bool bBig, sal_Bool bHiContrast, sal_Bool bNoScale ) const
2073 {
2074     MutexGuard aGuard( GetOwnStaticMutex() );
2075     return m_pDataContainer->GetImageFromURL( aURL, bBig, bHiContrast, bNoScale );
2076 }
2077 
2078 //*****************************************************************************************************************
2079 //	public method
2080 //*****************************************************************************************************************
GetImageFromURL(const rtl::OUString & aURL,sal_Bool bBig,sal_Bool bHiContrast) const2081 Image AddonsOptions::GetImageFromURL( const rtl::OUString& aURL, sal_Bool bBig, sal_Bool bHiContrast ) const
2082 {
2083     return GetImageFromURL( aURL, bBig, bHiContrast, sal_False );
2084 }
2085 
2086 //*****************************************************************************************************************
2087 //	private method
2088 //*****************************************************************************************************************
GetOwnStaticMutex()2089 Mutex& AddonsOptions::GetOwnStaticMutex()
2090 {
2091 	// Initialize static mutex only for one time!
2092     static Mutex* pMutex = NULL;
2093 	// If these method first called (Mutex not already exist!) ...
2094     if( pMutex == NULL )
2095     {
2096 		// ... we must create a new one. Protect follow code with the global mutex -
2097 		// It must be - we create a static variable!
2098         MutexGuard aGuard( Mutex::getGlobalMutex() );
2099 		// We must check our pointer again - because it can be that another instance of our class will be faster than these!
2100         if( pMutex == NULL )
2101         {
2102 			// Create the new mutex and set it for return on static variable.
2103             static Mutex aMutex;
2104             pMutex = &aMutex;
2105         }
2106     }
2107 	// Return new created or already existing mutex object.
2108     return *pMutex;
2109 }
2110 
2111 //*****************************************************************************************************************
2112 //	private method
2113 //*****************************************************************************************************************
IMPL_STATIC_LINK_NOINSTANCE(AddonsOptions,Notify,void *,EMPTYARG)2114 IMPL_STATIC_LINK_NOINSTANCE( AddonsOptions, Notify, void*, EMPTYARG )
2115 {
2116     MutexGuard aGuard( GetOwnStaticMutex() );
2117     m_pDataContainer->ReadConfigurationData();
2118 	return 0;
2119 }
2120 
2121 }
2122 
2123