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