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