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