xref: /trunk/main/framework/source/fwe/classes/addonsoptions.cxx (revision ff3f4ebcaa9d89f80fc1bbfab0aded7b897d9f72)
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