bump product version to 4.1.6.2
[LibreOffice.git] / framework / source / fwe / classes / addonsoptions.cxx
blob49b0bb82806f5e748ea60284533dd1a1f4a43c43
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <framework/addonsoptions.hxx>
21 #include <unotools/configmgr.hxx>
22 #include <unotools/configitem.hxx>
23 #include <unotools/ucbstreamhelper.hxx>
24 #include <tools/stream.hxx>
25 #include <com/sun/star/uno/Any.hxx>
26 #include <com/sun/star/uno/Sequence.hxx>
27 #include "com/sun/star/util/theMacroExpander.hpp"
28 #include "com/sun/star/uno/XComponentContext.hpp"
29 #include <rtl/ustrbuf.hxx>
30 #include <rtl/uri.hxx>
31 #include <comphelper/processfactory.hxx>
32 #include <vcl/graph.hxx>
33 #include <vcl/graphicfilter.hxx>
34 #include <vcl/toolbox.hxx>
36 #include <boost/unordered_map.hpp>
37 #include <algorithm>
38 #include <vector>
40 //_________________________________________________________________________________________________________________
41 // namespaces
42 //_________________________________________________________________________________________________________________
44 using namespace ::std ;
45 using namespace ::utl ;
46 using namespace ::osl ;
47 using namespace ::com::sun::star::uno ;
48 using namespace ::com::sun::star::beans ;
49 using namespace ::com::sun::star::lang ;
50 using namespace ::com::sun::star;
52 #define ROOTNODE_ADDONMENU OUString("Office.Addons" )
53 #define PATHDELIMITER OUString("/" )
54 #define SEPARATOR_URL_STR "private:separator"
55 #define SEPARATOR_URL OUString( SEPARATOR_URL_STR )
57 #define PROPERTYNAME_URL ADDONSMENUITEM_PROPERTYNAME_URL
58 #define PROPERTYNAME_TITLE ADDONSMENUITEM_PROPERTYNAME_TITLE
59 #define PROPERTYNAME_TARGET ADDONSMENUITEM_PROPERTYNAME_TARGET
60 #define PROPERTYNAME_IMAGEIDENTIFIER ADDONSMENUITEM_PROPERTYNAME_IMAGEIDENTIFIER
61 #define PROPERTYNAME_CONTEXT ADDONSMENUITEM_PROPERTYNAME_CONTEXT
62 #define PROPERTYNAME_SUBMENU ADDONSMENUITEM_PROPERTYNAME_SUBMENU
63 #define PROPERTYNAME_CONTROLTYPE ADDONSMENUITEM_PROPERTYNAME_CONTROLTYPE
64 #define PROPERTYNAME_WIDTH ADDONSMENUITEM_PROPERTYNAME_WIDTH
66 #define PROPERTYNAME_ALIGN STATUSBARITEM_PROPERTYNAME_ALIGN
67 #define PROPERTYNAME_AUTOSIZE STATUSBARITEM_PROPERTYNAME_AUTOSIZE
68 #define PROPERTYNAME_OWNERDRAW STATUSBARITEM_PROPERTYNAME_OWNERDRAW
70 #define PROPERTYNAME_IMAGESMALL OUString("ImageSmall" )
71 #define PROPERTYNAME_IMAGEBIG OUString("ImageBig" )
72 #define PROPERTYNAME_IMAGESMALLHC OUString("ImageSmallHC" )
73 #define PROPERTYNAME_IMAGEBIGHC OUString("ImageBigHC" )
74 #define PROPERTYNAME_IMAGESMALL_URL OUString("ImageSmallURL" )
75 #define PROPERTYNAME_IMAGEBIG_URL OUString("ImageBigURL" )
76 #define PROPERTYNAME_IMAGESMALLHC_URL OUString("ImageSmallHCURL" )
77 #define PROPERTYNAME_IMAGEBIGHC_URL OUString("ImageBigHCURL" )
79 #define IMAGES_NODENAME OUString("UserDefinedImages" )
80 #define PRIVATE_IMAGE_URL OUString("private:image/" )
82 #define PROPERTYNAME_MERGEMENU_MERGEPOINT OUString("MergePoint" )
83 #define PROPERTYNAME_MERGEMENU_MERGECOMMAND OUString("MergeCommand" )
84 #define PROPERTYNAME_MERGEMENU_MERGECOMMANDPARAMETER OUString("MergeCommandParameter" )
85 #define PROPERTYNAME_MERGEMENU_MERGEFALLBACK OUString("MergeFallback" )
86 #define PROPERTYNAME_MERGEMENU_MERGECONTEXT OUString("MergeContext" )
87 #define PROPERTYNAME_MERGEMENU_MENUITEMS OUString("MenuItems" )
89 #define PROPERTYNAME_MERGETOOLBAR_TOOLBAR OUString("MergeToolBar" )
90 #define PROPERTYNAME_MERGETOOLBAR_MERGEPOINT OUString("MergePoint" )
91 #define PROPERTYNAME_MERGETOOLBAR_MERGECOMMAND OUString("MergeCommand" )
92 #define PROPERTYNAME_MERGETOOLBAR_MERGECOMMANDPARAMETER OUString("MergeCommandParameter" )
93 #define PROPERTYNAME_MERGETOOLBAR_MERGEFALLBACK OUString("MergeFallback" )
94 #define PROPERTYNAME_MERGETOOLBAR_MERGECONTEXT OUString("MergeContext" )
95 #define PROPERTYNAME_MERGETOOLBAR_TOOLBARITEMS OUString("ToolBarItems" )
97 #define PROPERTYNAME_MERGESTATUSBAR_MERGEPOINT ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("MergePoint" ))
98 #define PROPERTYNAME_MERGESTATUSBAR_MERGECOMMAND ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("MergeCommand" ))
99 #define PROPERTYNAME_MERGESTATUSBAR_MERGECOMMANDPARAMETER ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("MergeCommandParameter" ))
100 #define PROPERTYNAME_MERGESTATUSBAR_MERGEFALLBACK ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("MergeFallback" ))
101 #define PROPERTYNAME_MERGESTATUSBAR_MERGECONTEXT ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("MergeContext" ))
102 #define PROPERTYNAME_MERGESTATUSBAR_STATUSBARITEMS ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("StatusBarItems" ))
104 // The following order is mandatory. Please add properties at the end!
105 #define INDEX_URL 0
106 #define INDEX_TITLE 1
107 #define INDEX_IMAGEIDENTIFIER 2
108 #define INDEX_TARGET 3
109 #define INDEX_CONTEXT 4
110 #define INDEX_SUBMENU 5
111 #define INDEX_CONTROLTYPE 6
112 #define INDEX_WIDTH 7
113 #define INDEX_ALIGN 8
114 #define INDEX_AUTOSIZE 9
115 #define INDEX_OWNERDRAW 10
116 #define PROPERTYCOUNT_INDEX 11
118 // The following order is mandatory. Please add properties at the end!
119 #define PROPERTYCOUNT_MENUITEM 6
120 #define OFFSET_MENUITEM_URL 0
121 #define OFFSET_MENUITEM_TITLE 1
122 #define OFFSET_MENUITEM_IMAGEIDENTIFIER 2
123 #define OFFSET_MENUITEM_TARGET 3
124 #define OFFSET_MENUITEM_CONTEXT 4
125 #define OFFSET_MENUITEM_SUBMENU 5
127 // The following order is mandatory. Please add properties at the end!
128 #define PROPERTYCOUNT_POPUPMENU 4
129 #define OFFSET_POPUPMENU_TITLE 0
130 #define OFFSET_POPUPMENU_CONTEXT 1
131 #define OFFSET_POPUPMENU_SUBMENU 2
132 #define OFFSET_POPUPMENU_URL 3 // Used for property set
134 // The following order is mandatory. Please add properties at the end!
135 #define PROPERTYCOUNT_TOOLBARITEM 7
136 #define OFFSET_TOOLBARITEM_URL 0
137 #define OFFSET_TOOLBARITEM_TITLE 1
138 #define OFFSET_TOOLBARITEM_IMAGEIDENTIFIER 2
139 #define OFFSET_TOOLBARITEM_TARGET 3
140 #define OFFSET_TOOLBARITEM_CONTEXT 4
141 #define OFFSET_TOOLBARITEM_CONTROLTYPE 5
142 #define OFFSET_TOOLBARITEM_WIDTH 6
144 // The following order is mandatory. Please add properties at the end!
145 #define PROPERTYCOUNT_STATUSBARITEM 7
146 #define OFFSET_STATUSBARITEM_URL 0
147 #define OFFSET_STATUSBARITEM_TITLE 1
148 #define OFFSET_STATUSBARITEM_CONTEXT 2
149 #define OFFSET_STATUSBARITEM_ALIGN 3
150 #define OFFSET_STATUSBARITEM_AUTOSIZE 4
151 #define OFFSET_STATUSBARITEM_OWNERDRAW 5
152 #define OFFSET_STATUSBARITEM_WIDTH 6
155 // The following order is mandatory. Please add properties at the end!
156 #define PROPERTYCOUNT_IMAGES 8
157 #define PROPERTYCOUNT_EMBEDDED_IMAGES 4
158 #define OFFSET_IMAGES_SMALL 0
159 #define OFFSET_IMAGES_BIG 1
160 #define OFFSET_IMAGES_SMALLHC 2
161 #define OFFSET_IMAGES_BIGHC 3
162 #define OFFSET_IMAGES_SMALL_URL 4
163 #define OFFSET_IMAGES_BIG_URL 5
164 #define OFFSET_IMAGES_SMALLHC_URL 6
165 #define OFFSET_IMAGES_BIGHC_URL 7
167 #define PROPERTYCOUNT_MERGE_MENUBAR 6
168 #define OFFSET_MERGEMENU_MERGEPOINT 0
169 #define OFFSET_MERGEMENU_MERGECOMMAND 1
170 #define OFFSET_MERGEMENU_MERGECOMMANDPARAMETER 2
171 #define OFFSET_MERGEMENU_MERGEFALLBACK 3
172 #define OFFSET_MERGEMENU_MERGECONTEXT 4
173 #define OFFSET_MERGEMENU_MENUITEMS 5
175 #define PROPERTYCOUNT_MERGE_TOOLBAR 7
176 #define OFFSET_MERGETOOLBAR_TOOLBAR 0
177 #define OFFSET_MERGETOOLBAR_MERGEPOINT 1
178 #define OFFSET_MERGETOOLBAR_MERGECOMMAND 2
179 #define OFFSET_MERGETOOLBAR_MERGECOMMANDPARAMETER 3
180 #define OFFSET_MERGETOOLBAR_MERGEFALLBACK 4
181 #define OFFSET_MERGETOOLBAR_MERGECONTEXT 5
182 #define OFFSET_MERGETOOLBAR_TOOLBARITEMS 6
184 #define PROPERTYCOUNT_MERGE_STATUSBAR 6
185 #define OFFSET_MERGESTATUSBAR_MERGEPOINT 0
186 #define OFFSET_MERGESTATUSBAR_MERGECOMMAND 1
187 #define OFFSET_MERGESTATUSBAR_MERGECOMMANDPARAMETER 2
188 #define OFFSET_MERGESTATUSBAR_MERGEFALLBACK 3
189 #define OFFSET_MERGESTATUSBAR_MERGECONTEXT 4
190 #define OFFSET_MERGESTATUSBAR_STATUSBARITEMS 5
192 #define EXPAND_PROTOCOL "vnd.sun.star.expand:"
194 //_________________________________________________________________________________________________________________
195 // private declarations!
196 //_________________________________________________________________________________________________________________
198 /*-****************************************************************************************************************
199 @descr struct to hold information about one menu entry.
200 ****************************************************************************************************************-*/
202 namespace framework
205 class AddonsOptions_Impl : public ConfigItem
207 //-------------------------------------------------------------------------------------------------------------
208 // public methods
209 //-------------------------------------------------------------------------------------------------------------
211 public:
212 //---------------------------------------------------------------------------------------------------------
213 // constructor / destructor
214 //---------------------------------------------------------------------------------------------------------
216 AddonsOptions_Impl();
217 ~AddonsOptions_Impl();
219 //---------------------------------------------------------------------------------------------------------
220 // overloaded methods of baseclass
221 //---------------------------------------------------------------------------------------------------------
223 /*-****************************************************************************************************//**
224 @short called for notify of configmanager
225 @descr These method is called from the ConfigManager before application ends or from the
226 PropertyChangeListener if the sub tree broadcasts changes. You must update your
227 internal values.
229 @seealso baseclass ConfigItem
231 @param "lPropertyNames" is the list of properties which should be updated.
232 @return -
234 @onerror -
235 *//*-*****************************************************************************************************/
237 virtual void Notify( const Sequence< OUString >& lPropertyNames );
239 /*-****************************************************************************************************//**
240 @short write changes to configuration
241 @descr These method writes the changed values into the sub tree
242 and should always called in our destructor to guarantee consistency of config data.
244 @seealso baseclass ConfigItem
246 @param -
247 @return -
249 @onerror -
250 *//*-*****************************************************************************************************/
252 virtual void Commit();
254 //---------------------------------------------------------------------------------------------------------
255 // public interface
256 //---------------------------------------------------------------------------------------------------------
258 /*-****************************************************************************************************//**
259 @short base implementation of public interface for "SvtDynamicMenuOptions"!
260 @descr These class is used as static member of "SvtDynamicMenuOptions" ...
261 => The code exist only for one time and isn't duplicated for every instance!
263 @seealso -
265 @param -
266 @return -
268 @onerror -
269 *//*-*****************************************************************************************************/
271 sal_Bool HasAddonsMenu () const ;
272 sal_Int32 GetAddonsToolBarCount() const ;
273 const Sequence< Sequence< PropertyValue > >& GetAddonsMenu () const ;
274 const Sequence< Sequence< PropertyValue > >& GetAddonsMenuBarPart () const ;
275 const Sequence< Sequence< PropertyValue > >& GetAddonsToolBarPart ( sal_uInt32 nIndex ) const ;
276 const OUString GetAddonsToolbarResourceName( sal_uInt32 nIndex ) const;
277 const Sequence< Sequence< PropertyValue > >& GetAddonsHelpMenu () const ;
278 Image GetImageFromURL( const OUString& aURL, sal_Bool bBig, sal_Bool bNoScale );
279 const MergeMenuInstructionContainer& GetMergeMenuInstructions() const;
280 bool GetMergeToolbarInstructions( const OUString& rToolbarName, MergeToolbarInstructionContainer& rToolbarInstructions ) const;
281 const MergeStatusbarInstructionContainer& GetMergeStatusbarInstructions() const;
282 void ReadConfigurationData();
284 //-------------------------------------------------------------------------------------------------------------
285 // private methods
286 //-------------------------------------------------------------------------------------------------------------
288 private:
289 enum ImageSize
291 IMGSIZE_SMALL,
292 IMGSIZE_BIG
295 struct ImageEntry
297 // if the image is set, it was embedded in some way,
298 // otherwise we use the associated URL to load on demand
300 // accessed in this order
301 Image aScaled[2]; // cached scaled images
302 Image aImage[2]; // original un-scaled images
303 OUString aURL[2]; // URLs in case they are not loaded yet
304 ImageEntry() {}
305 void addImage(ImageSize eSize, const Image &rImage, const OUString &rURL);
308 typedef boost::unordered_map< OUString, ImageEntry, OUStringHash, ::std::equal_to< OUString > > ImageManager;
309 typedef boost::unordered_map< OUString, sal_uInt32, OUStringHash, ::std::equal_to< OUString > > StringToIndexMap;
310 typedef std::vector< Sequence< Sequence< PropertyValue > > > AddonToolBars;
311 typedef ::boost::unordered_map< OUString, MergeToolbarInstructionContainer, OUStringHash, ::std::equal_to< OUString > > ToolbarMergingInstructions;
314 /*-****************************************************************************************************//**
315 @short return list of key names of our configuration management which represent oue module tree
316 @descr These methods return the current list of key names! We need it to get needed values from our
317 configuration management!
319 @seealso -
321 @param "nCount" , returns count of menu entries for "new"
322 @return A list of configuration key names is returned.
324 @onerror -
325 *//*-*****************************************************************************************************/
327 sal_Bool ReadAddonMenuSet( Sequence< Sequence< PropertyValue > >& aAddonMenuSeq );
328 sal_Bool ReadOfficeMenuBarSet( Sequence< Sequence< PropertyValue > >& aAddonOfficeMenuBarSeq );
329 sal_Bool ReadOfficeToolBarSet( AddonToolBars& rAddonOfficeToolBars, std::vector< OUString >& rAddonOfficeToolBarResNames );
330 sal_Bool ReadToolBarItemSet( const OUString rToolBarItemSetNodeName, Sequence< Sequence< PropertyValue > >& aAddonOfficeToolBarSeq );
331 sal_Bool ReadOfficeHelpSet( Sequence< Sequence< PropertyValue > >& aAddonOfficeHelpMenuSeq );
332 void ReadImages( ImageManager& aImageManager );
333 sal_Bool ReadMenuMergeInstructions( MergeMenuInstructionContainer& rContainer );
334 sal_Bool ReadToolbarMergeInstructions( ToolbarMergingInstructions& rToolbarMergeMap );
335 sal_Bool ReadStatusbarMergeInstructions( MergeStatusbarInstructionContainer& rContainer );
337 sal_Bool ReadMergeMenuData( const OUString& aMergeAddonInstructionBase, Sequence< Sequence< PropertyValue > >& rMergeMenu );
338 sal_Bool ReadMergeToolbarData( const OUString& aMergeAddonInstructionBase, Sequence< Sequence< PropertyValue > >& rMergeToolbarItems );
339 sal_Bool ReadMergeStatusbarData( const OUString& aMergeAddonInstructionBase, Sequence< Sequence< PropertyValue > >& rMergeStatusbar );
340 sal_Bool ReadMenuItem( const OUString& aMenuItemNodeName, Sequence< PropertyValue >& aMenuItem, sal_Bool bIgnoreSubMenu = sal_False );
341 sal_Bool ReadPopupMenu( const OUString& aPopupMenuNodeName, Sequence< PropertyValue >& aPopupMenu );
342 sal_Bool AppendPopupMenu( Sequence< PropertyValue >& aTargetPopupMenu, const Sequence< PropertyValue >& rSourcePopupMenu );
343 sal_Bool ReadToolBarItem( const OUString& aToolBarItemNodeName, Sequence< PropertyValue >& aToolBarItem );
344 sal_Bool ReadStatusBarItem( const OUString& aStatusbarItemNodeName, Sequence< PropertyValue >& aStatusbarItem );
345 sal_Bool ReadImagesItem( const OUString& aImagesItemNodeName, Sequence< PropertyValue >& aImagesItem );
346 ImageEntry* ReadImageData( const OUString& aImagesNodeName );
347 void ReadAndAssociateImages( const OUString& aURL, const OUString& aImageId );
348 Image ReadImageFromURL( const OUString& aURL );
349 sal_Bool HasAssociatedImages( const OUString& aURL );
350 void SubstituteVariables( OUString& aURL );
352 sal_Bool ReadSubMenuEntries( const Sequence< OUString >& aSubMenuNodeNames, Sequence< Sequence< PropertyValue > >& rSubMenu );
353 void InsertToolBarSeparator( Sequence< Sequence< PropertyValue > >& rAddonOfficeToolBarSeq );
354 OUString GeneratePrefixURL();
356 Sequence< OUString > GetPropertyNamesMenuItem( const OUString& aPropertyRootNode ) const;
357 Sequence< OUString > GetPropertyNamesPopupMenu( const OUString& aPropertyRootNode ) const;
358 Sequence< OUString > GetPropertyNamesToolBarItem( const OUString& aPropertyRootNode ) const;
359 Sequence< OUString > GetPropertyNamesStatusbarItem( const ::rtl::OUString& aPropertyRootNode ) const;
360 Sequence< OUString > GetPropertyNamesImages( const OUString& aPropertyRootNode ) const;
361 sal_Bool CreateImageFromSequence( Image& rImage, Sequence< sal_Int8 >& rBitmapDataSeq ) const;
363 //-------------------------------------------------------------------------------------------------------------
364 // private member
365 //-------------------------------------------------------------------------------------------------------------
367 private:
368 ImageEntry* ReadOptionalImageData( const OUString& aMenuNodeName );
370 sal_Int32 m_nRootAddonPopupMenuId;
371 OUString m_aPropNames[PROPERTYCOUNT_INDEX];
372 OUString m_aPropImagesNames[PROPERTYCOUNT_IMAGES];
373 OUString m_aPropMergeMenuNames[PROPERTYCOUNT_MERGE_MENUBAR];
374 OUString m_aPropMergeToolbarNames[PROPERTYCOUNT_MERGE_TOOLBAR];
375 OUString m_aPropMergeStatusbarNames[PROPERTYCOUNT_MERGE_STATUSBAR];
376 OUString m_aEmpty;
377 OUString m_aPathDelimiter;
378 OUString m_aSeparator;
379 OUString m_aRootAddonPopupMenuURLPrexfix;
380 OUString m_aPrivateImageURL;
381 Sequence< Sequence< PropertyValue > > m_aCachedMenuProperties;
382 Sequence< Sequence< PropertyValue > > m_aCachedMenuBarPartProperties;
383 AddonToolBars m_aCachedToolBarPartProperties;
384 std::vector< OUString > m_aCachedToolBarPartResourceNames;
385 Sequence< Sequence< PropertyValue > > m_aCachedHelpMenuProperties;
386 Reference< util::XMacroExpander > m_xMacroExpander;
387 ImageManager m_aImageManager;
388 Sequence< Sequence< PropertyValue > > m_aEmptyAddonToolBar;
389 MergeMenuInstructionContainer m_aCachedMergeMenuInsContainer;
390 ToolbarMergingInstructions m_aCachedToolbarMergingInstructions;
391 MergeStatusbarInstructionContainer m_aCachedStatusbarMergingInstructions;
394 void AddonsOptions_Impl::ImageEntry::addImage(ImageSize eSize,
395 const Image &rImage,
396 const OUString &rURL)
398 aImage[(int)eSize] = rImage;
399 aURL[(int)eSize] = rURL;
402 //*****************************************************************************************************************
403 // constructor
404 //*****************************************************************************************************************
405 AddonsOptions_Impl::AddonsOptions_Impl()
406 // Init baseclasses first
407 : ConfigItem( ROOTNODE_ADDONMENU ),
408 m_nRootAddonPopupMenuId( 0 ),
409 m_aPathDelimiter( PATHDELIMITER ),
410 m_aSeparator( SEPARATOR_URL ),
411 m_aRootAddonPopupMenuURLPrexfix( ADDONSPOPUPMENU_URL_PREFIX ),
412 m_aPrivateImageURL( PRIVATE_IMAGE_URL )
414 // initialize array with fixed property names
415 m_aPropNames[ INDEX_URL ] = PROPERTYNAME_URL;
416 m_aPropNames[ INDEX_TITLE ] = PROPERTYNAME_TITLE;
417 m_aPropNames[ INDEX_TARGET ] = PROPERTYNAME_TARGET;
418 m_aPropNames[ INDEX_IMAGEIDENTIFIER ] = PROPERTYNAME_IMAGEIDENTIFIER;
419 m_aPropNames[ INDEX_CONTEXT ] = PROPERTYNAME_CONTEXT;
420 m_aPropNames[ INDEX_SUBMENU ] = PROPERTYNAME_SUBMENU; // Submenu set!
421 m_aPropNames[ INDEX_CONTROLTYPE ] = PROPERTYNAME_CONTROLTYPE;
422 m_aPropNames[ INDEX_WIDTH ] = PROPERTYNAME_WIDTH;
423 m_aPropNames[ INDEX_ALIGN ] = PROPERTYNAME_ALIGN;
424 m_aPropNames[ INDEX_AUTOSIZE ] = PROPERTYNAME_AUTOSIZE;
425 m_aPropNames[ INDEX_OWNERDRAW ] = PROPERTYNAME_OWNERDRAW;
427 // initialize array with fixed images property names
428 m_aPropImagesNames[ OFFSET_IMAGES_SMALL ] = PROPERTYNAME_IMAGESMALL;
429 m_aPropImagesNames[ OFFSET_IMAGES_BIG ] = PROPERTYNAME_IMAGEBIG;
430 m_aPropImagesNames[ OFFSET_IMAGES_SMALLHC ] = PROPERTYNAME_IMAGESMALLHC;
431 m_aPropImagesNames[ OFFSET_IMAGES_BIGHC ] = PROPERTYNAME_IMAGEBIGHC;
432 m_aPropImagesNames[ OFFSET_IMAGES_SMALL_URL ] = PROPERTYNAME_IMAGESMALL_URL;
433 m_aPropImagesNames[ OFFSET_IMAGES_BIG_URL ] = PROPERTYNAME_IMAGEBIG_URL;
434 m_aPropImagesNames[ OFFSET_IMAGES_SMALLHC_URL ] = PROPERTYNAME_IMAGESMALLHC_URL;
435 m_aPropImagesNames[ OFFSET_IMAGES_BIGHC_URL ] = PROPERTYNAME_IMAGEBIGHC_URL;
437 // initialize array with fixed merge menu property names
438 m_aPropMergeMenuNames[ OFFSET_MERGEMENU_MERGEPOINT ] = PROPERTYNAME_MERGEMENU_MERGEPOINT;
439 m_aPropMergeMenuNames[ OFFSET_MERGEMENU_MERGECOMMAND ] = PROPERTYNAME_MERGEMENU_MERGECOMMAND;
440 m_aPropMergeMenuNames[ OFFSET_MERGEMENU_MERGECOMMANDPARAMETER ] = PROPERTYNAME_MERGEMENU_MERGECOMMANDPARAMETER;
441 m_aPropMergeMenuNames[ OFFSET_MERGEMENU_MERGEFALLBACK ] = PROPERTYNAME_MERGEMENU_MERGEFALLBACK;
442 m_aPropMergeMenuNames[ OFFSET_MERGEMENU_MERGECONTEXT ] = PROPERTYNAME_MERGEMENU_MERGECONTEXT;
443 m_aPropMergeMenuNames[ OFFSET_MERGEMENU_MENUITEMS ] = PROPERTYNAME_MERGEMENU_MENUITEMS;
445 m_aPropMergeToolbarNames[ OFFSET_MERGETOOLBAR_TOOLBAR ] = PROPERTYNAME_MERGETOOLBAR_TOOLBAR;
446 m_aPropMergeToolbarNames[ OFFSET_MERGETOOLBAR_MERGEPOINT ] = PROPERTYNAME_MERGETOOLBAR_MERGEPOINT;
447 m_aPropMergeToolbarNames[ OFFSET_MERGETOOLBAR_MERGECOMMAND ] = PROPERTYNAME_MERGETOOLBAR_MERGECOMMAND;
448 m_aPropMergeToolbarNames[ OFFSET_MERGETOOLBAR_MERGECOMMANDPARAMETER ] = PROPERTYNAME_MERGETOOLBAR_MERGECOMMANDPARAMETER;
449 m_aPropMergeToolbarNames[ OFFSET_MERGETOOLBAR_MERGEFALLBACK ] = PROPERTYNAME_MERGETOOLBAR_MERGEFALLBACK;
450 m_aPropMergeToolbarNames[ OFFSET_MERGETOOLBAR_MERGECONTEXT ] = PROPERTYNAME_MERGETOOLBAR_MERGECONTEXT;
451 m_aPropMergeToolbarNames[ OFFSET_MERGETOOLBAR_TOOLBARITEMS ] = PROPERTYNAME_MERGETOOLBAR_TOOLBARITEMS;
453 m_aPropMergeStatusbarNames[ OFFSET_MERGESTATUSBAR_MERGEPOINT ] = PROPERTYNAME_MERGESTATUSBAR_MERGEPOINT;
454 m_aPropMergeStatusbarNames[ OFFSET_MERGESTATUSBAR_MERGECOMMAND ] = PROPERTYNAME_MERGESTATUSBAR_MERGECOMMAND;
455 m_aPropMergeStatusbarNames[ OFFSET_MERGESTATUSBAR_MERGECOMMANDPARAMETER ] = PROPERTYNAME_MERGESTATUSBAR_MERGECOMMANDPARAMETER;
456 m_aPropMergeStatusbarNames[ OFFSET_MERGESTATUSBAR_MERGEFALLBACK ] = PROPERTYNAME_MERGESTATUSBAR_MERGEFALLBACK;
457 m_aPropMergeStatusbarNames[ OFFSET_MERGESTATUSBAR_MERGECONTEXT ] = PROPERTYNAME_MERGESTATUSBAR_MERGECONTEXT;
458 m_aPropMergeStatusbarNames[ OFFSET_MERGESTATUSBAR_STATUSBARITEMS ] = PROPERTYNAME_MERGESTATUSBAR_STATUSBARITEMS;
460 Reference< XComponentContext > xContext(
461 comphelper::getProcessComponentContext() );
462 m_xMacroExpander = util::theMacroExpander::get(xContext);
464 ReadConfigurationData();
466 // Enable notification mechanism of ouer baseclass.
467 // We need it to get information about changes outside these class on ouer used configuration keys!
468 Sequence< OUString > aNotifySeq( 1 );
469 aNotifySeq[0] = OUString( "AddonUI" );
470 EnableNotification( aNotifySeq );
473 //*****************************************************************************************************************
474 // destructor
475 //*****************************************************************************************************************
476 AddonsOptions_Impl::~AddonsOptions_Impl()
478 // We must save our current values .. if user forget it!
479 if( IsModified() == sal_True )
481 Commit();
485 void AddonsOptions_Impl::ReadConfigurationData()
487 // reset members to be read again from configuration
488 m_aCachedMenuProperties = Sequence< Sequence< PropertyValue > >();
489 m_aCachedMenuBarPartProperties = Sequence< Sequence< PropertyValue > >();
490 m_aCachedToolBarPartProperties = AddonToolBars();
491 m_aCachedHelpMenuProperties = Sequence< Sequence< PropertyValue > >();
492 m_aCachedToolBarPartResourceNames.clear();
493 m_aImageManager = ImageManager();
495 ReadAddonMenuSet( m_aCachedMenuProperties );
496 ReadOfficeMenuBarSet( m_aCachedMenuBarPartProperties );
497 ReadOfficeToolBarSet( m_aCachedToolBarPartProperties, m_aCachedToolBarPartResourceNames );
499 ReadOfficeHelpSet( m_aCachedHelpMenuProperties );
500 ReadImages( m_aImageManager );
502 m_aCachedMergeMenuInsContainer.clear();
503 m_aCachedToolbarMergingInstructions.clear();
504 m_aCachedStatusbarMergingInstructions.clear();
506 ReadMenuMergeInstructions( m_aCachedMergeMenuInsContainer );
507 ReadToolbarMergeInstructions( m_aCachedToolbarMergingInstructions );
508 ReadStatusbarMergeInstructions( m_aCachedStatusbarMergingInstructions );
511 //*****************************************************************************************************************
512 // public method
513 //*****************************************************************************************************************
514 void AddonsOptions_Impl::Notify( const Sequence< OUString >& /*lPropertyNames*/ )
516 Application::PostUserEvent( STATIC_LINK( 0, AddonsOptions, Notify ) );
519 //*****************************************************************************************************************
520 // public method
521 //*****************************************************************************************************************
522 void AddonsOptions_Impl::Commit()
524 OSL_FAIL( "AddonsOptions_Impl::Commit()\nNot implemented yet!\n" );
527 //*****************************************************************************************************************
528 // public method
529 //*****************************************************************************************************************
530 sal_Bool AddonsOptions_Impl::HasAddonsMenu() const
532 return ( m_aCachedMenuProperties.getLength() > 0 );
535 //*****************************************************************************************************************
536 // public method
537 //*****************************************************************************************************************
538 sal_Int32 AddonsOptions_Impl::GetAddonsToolBarCount() const
540 return m_aCachedToolBarPartProperties.size();
543 //*****************************************************************************************************************
544 // public method
545 //*****************************************************************************************************************
546 const Sequence< Sequence< PropertyValue > >& AddonsOptions_Impl::GetAddonsMenu() const
548 return m_aCachedMenuProperties;
551 //*****************************************************************************************************************
552 // public method
553 //*****************************************************************************************************************
554 const Sequence< Sequence< PropertyValue > >& AddonsOptions_Impl::GetAddonsMenuBarPart() const
556 return m_aCachedMenuBarPartProperties;
559 //*****************************************************************************************************************
560 // public method
561 //*****************************************************************************************************************
562 const Sequence< Sequence< PropertyValue > >& AddonsOptions_Impl::GetAddonsToolBarPart( sal_uInt32 nIndex ) const
564 if ( /*nIndex >= 0 &&*/ nIndex < m_aCachedToolBarPartProperties.size() )
565 return m_aCachedToolBarPartProperties[nIndex];
566 else
567 return m_aEmptyAddonToolBar;
570 //*****************************************************************************************************************
571 // public method
572 //*****************************************************************************************************************
573 const OUString AddonsOptions_Impl::GetAddonsToolbarResourceName( sal_uInt32 nIndex ) const
575 if ( nIndex < m_aCachedToolBarPartResourceNames.size() )
576 return m_aCachedToolBarPartResourceNames[nIndex];
577 else
578 return OUString();
581 //*****************************************************************************************************************
582 // public method
583 //*****************************************************************************************************************
584 const Sequence< Sequence< PropertyValue > >& AddonsOptions_Impl::GetAddonsHelpMenu () const
586 return m_aCachedHelpMenuProperties;
589 //*****************************************************************************************************************
590 // public method
591 //*****************************************************************************************************************
592 const MergeMenuInstructionContainer& AddonsOptions_Impl::GetMergeMenuInstructions() const
594 return m_aCachedMergeMenuInsContainer;
597 //*****************************************************************************************************************
598 // public method
599 //*****************************************************************************************************************
600 bool AddonsOptions_Impl::GetMergeToolbarInstructions(
601 const OUString& rToolbarName,
602 MergeToolbarInstructionContainer& rToolbarInstructions ) const
604 ToolbarMergingInstructions::const_iterator pIter = m_aCachedToolbarMergingInstructions.find( rToolbarName );
605 if ( pIter != m_aCachedToolbarMergingInstructions.end() )
607 rToolbarInstructions = pIter->second;
608 return true;
610 else
611 return false;
614 const MergeStatusbarInstructionContainer& AddonsOptions_Impl::GetMergeStatusbarInstructions() const
616 return m_aCachedStatusbarMergingInstructions;
619 //*****************************************************************************************************************
620 // public method
621 //*****************************************************************************************************************
622 static Image ScaleImage( const Image &rImage, bool bBig )
624 Size aSize = ToolBox::GetDefaultImageSize(bBig);
625 BitmapEx aScaleBmp(rImage.GetBitmapEx());
626 SAL_INFO("framework", "Addons: expensive scale image from "
627 << aScaleBmp.GetSizePixel() << " to " << aSize);
628 aScaleBmp.Scale(aSize, BMP_SCALE_BESTQUALITY);
629 return Image(aScaleBmp);
632 Image AddonsOptions_Impl::GetImageFromURL( const OUString& aURL, sal_Bool bBig, sal_Bool bNoScale )
634 Image aImage;
635 ImageSize eSize = bBig ? IMGSIZE_BIG : IMGSIZE_SMALL;
636 int nIdx = (int)eSize;
637 int nOtherIdx = nIdx ? 0 : 1;
639 SAL_INFO("framework", "Expensive: Addons GetImageFromURL " << aURL <<
640 " big " << (bBig?"big":"litte") <<
641 " scale " << (bNoScale ? "noscale" : "scale"));
643 ImageManager::iterator pIter = m_aImageManager.find(aURL);
644 if ( pIter != m_aImageManager.end() )
646 ImageEntry &rEntry = pIter->second;
647 // actually read the image ...
648 if (!rEntry.aImage[nIdx])
649 rEntry.aImage[nIdx] = ReadImageFromURL(rEntry.aURL[nIdx]);
651 if (!rEntry.aImage[nIdx])
652 { // try the other size and scale it
653 aImage = ScaleImage(ReadImageFromURL(rEntry.aURL[nOtherIdx]), bBig);
654 rEntry.aImage[nIdx] = aImage;
655 if (!rEntry.aImage[nIdx])
656 SAL_WARN("framework", "failed to load addons image " << aURL);
659 // FIXME: bNoScale is not terribly meaningful or useful
661 if (!aImage && bNoScale)
662 aImage = rEntry.aImage[nIdx];
664 if (!aImage && !!rEntry.aScaled[nIdx])
665 aImage = rEntry.aScaled[nIdx];
667 else // scale to the correct size for the theme / toolbox
669 aImage = rEntry.aImage[nIdx];
670 if (!aImage) // use and scale the other if one size is missing
671 aImage = rEntry.aImage[nOtherIdx];
673 aImage = ScaleImage(aImage, bBig);
674 rEntry.aScaled[nIdx] = aImage; // cache for next time
678 return aImage;
681 //*****************************************************************************************************************
682 // private method
683 //*****************************************************************************************************************
684 sal_Bool AddonsOptions_Impl::ReadAddonMenuSet( Sequence< Sequence< PropertyValue > >& rAddonMenuSeq )
686 // Read the AddonMenu set and fill property sequences
687 OUString aAddonMenuNodeName( "AddonUI/AddonMenu" );
688 Sequence< OUString > aAddonMenuNodeSeq = GetNodeNames( aAddonMenuNodeName );
689 OUString aAddonMenuItemNode( aAddonMenuNodeName + m_aPathDelimiter );
691 sal_uInt32 nCount = aAddonMenuNodeSeq.getLength();
692 sal_uInt32 nIndex = 0;
693 Sequence< PropertyValue > aMenuItem( PROPERTYCOUNT_MENUITEM );
695 // Init the property value sequence
696 aMenuItem[ OFFSET_MENUITEM_URL ].Name = m_aPropNames[ INDEX_URL ];
697 aMenuItem[ OFFSET_MENUITEM_TITLE ].Name = m_aPropNames[ INDEX_TITLE ];
698 aMenuItem[ OFFSET_MENUITEM_TARGET ].Name = m_aPropNames[ INDEX_TARGET ];
699 aMenuItem[ OFFSET_MENUITEM_IMAGEIDENTIFIER ].Name = m_aPropNames[ INDEX_IMAGEIDENTIFIER];
700 aMenuItem[ OFFSET_MENUITEM_CONTEXT ].Name = m_aPropNames[ INDEX_CONTEXT ];
701 aMenuItem[ OFFSET_MENUITEM_SUBMENU ].Name = m_aPropNames[ INDEX_SUBMENU ]; // Submenu set!
703 for ( sal_uInt32 n = 0; n < nCount; n++ )
705 OUString aRootMenuItemNode( aAddonMenuItemNode + aAddonMenuNodeSeq[n] );
707 // Read the MenuItem
708 if ( ReadMenuItem( aRootMenuItemNode, aMenuItem ) )
710 // Successfully read a menu item, append to our list
711 sal_uInt32 nMenuItemCount = rAddonMenuSeq.getLength() + 1;
712 rAddonMenuSeq.realloc( nMenuItemCount );
713 rAddonMenuSeq[nIndex++] = aMenuItem;
717 return ( rAddonMenuSeq.getLength() > 0 );
720 //*****************************************************************************************************************
721 // private method
722 //*****************************************************************************************************************
723 sal_Bool AddonsOptions_Impl::ReadOfficeHelpSet( Sequence< Sequence< PropertyValue > >& rAddonOfficeHelpMenuSeq )
725 // Read the AddonMenu set and fill property sequences
726 OUString aAddonHelpMenuNodeName( "AddonUI/OfficeHelp" );
727 Sequence< OUString > aAddonHelpMenuNodeSeq = GetNodeNames( aAddonHelpMenuNodeName );
728 OUString aAddonHelpMenuItemNode( aAddonHelpMenuNodeName + m_aPathDelimiter );
730 sal_uInt32 nCount = aAddonHelpMenuNodeSeq.getLength();
731 sal_uInt32 nIndex = 0;
732 Sequence< PropertyValue > aMenuItem( PROPERTYCOUNT_MENUITEM );
734 // Init the property value sequence
735 aMenuItem[ OFFSET_MENUITEM_URL ].Name = m_aPropNames[ INDEX_URL ];
736 aMenuItem[ OFFSET_MENUITEM_TITLE ].Name = m_aPropNames[ INDEX_TITLE ];
737 aMenuItem[ OFFSET_MENUITEM_TARGET ].Name = m_aPropNames[ INDEX_TARGET ];
738 aMenuItem[ OFFSET_MENUITEM_IMAGEIDENTIFIER ].Name = m_aPropNames[ INDEX_IMAGEIDENTIFIER];
739 aMenuItem[ OFFSET_MENUITEM_CONTEXT ].Name = m_aPropNames[ INDEX_CONTEXT ];
740 aMenuItem[ OFFSET_MENUITEM_SUBMENU ].Name = m_aPropNames[ INDEX_SUBMENU ]; // Submenu set!
742 for ( sal_uInt32 n = 0; n < nCount; n++ )
744 OUString aRootMenuItemNode( aAddonHelpMenuItemNode + aAddonHelpMenuNodeSeq[n] );
746 // Read the MenuItem
747 if ( ReadMenuItem( aRootMenuItemNode, aMenuItem, sal_True ) )
749 // Successfully read a menu item, append to our list
750 sal_uInt32 nMenuItemCount = rAddonOfficeHelpMenuSeq.getLength() + 1;
751 rAddonOfficeHelpMenuSeq.realloc( nMenuItemCount );
752 rAddonOfficeHelpMenuSeq[nIndex++] = aMenuItem;
756 return ( rAddonOfficeHelpMenuSeq.getLength() > 0 );
759 //*****************************************************************************************************************
760 // private method
761 //*****************************************************************************************************************
762 sal_Bool AddonsOptions_Impl::ReadOfficeMenuBarSet( Sequence< Sequence< PropertyValue > >& rAddonOfficeMenuBarSeq )
764 // Read the OfficeMenuBar set and fill property sequences
765 OUString aAddonMenuBarNodeName( "AddonUI/OfficeMenuBar" );
766 Sequence< OUString > aAddonMenuBarNodeSeq = GetNodeNames( aAddonMenuBarNodeName );
767 OUString aAddonMenuBarNode( aAddonMenuBarNodeName + m_aPathDelimiter );
769 sal_uInt32 nCount = aAddonMenuBarNodeSeq.getLength();
770 sal_uInt32 nIndex = 0;
771 Sequence< PropertyValue > aPopupMenu( PROPERTYCOUNT_POPUPMENU );
773 // Init the property value sequence
774 aPopupMenu[ OFFSET_POPUPMENU_TITLE ].Name = m_aPropNames[ INDEX_TITLE ];
775 aPopupMenu[ OFFSET_POPUPMENU_CONTEXT ].Name = m_aPropNames[ INDEX_CONTEXT];
776 aPopupMenu[ OFFSET_POPUPMENU_SUBMENU ].Name = m_aPropNames[ INDEX_SUBMENU];
777 aPopupMenu[ OFFSET_POPUPMENU_URL ].Name = m_aPropNames[ INDEX_URL ];
779 StringToIndexMap aTitleToIndexMap;
781 for ( sal_uInt32 n = 0; n < nCount; n++ )
783 OUString aPopupMenuNode( aAddonMenuBarNode + aAddonMenuBarNodeSeq[n] );
785 // Read the MenuItem
786 if ( ReadPopupMenu( aPopupMenuNode, aPopupMenu ) )
788 // Successfully read a popup menu, append to our list
789 OUString aPopupTitle;
790 if ( aPopupMenu[OFFSET_POPUPMENU_TITLE].Value >>= aPopupTitle )
792 StringToIndexMap::const_iterator pIter = aTitleToIndexMap.find( aPopupTitle );
793 if ( pIter != aTitleToIndexMap.end() )
795 // title already there => concat both popup menus
796 Sequence< PropertyValue >& rOldPopupMenu = rAddonOfficeMenuBarSeq[pIter->second];
797 AppendPopupMenu( rOldPopupMenu, aPopupMenu );
799 else
801 // not found
802 sal_uInt32 nMenuItemCount = rAddonOfficeMenuBarSeq.getLength() + 1;
803 rAddonOfficeMenuBarSeq.realloc( nMenuItemCount );
804 rAddonOfficeMenuBarSeq[nIndex] = aPopupMenu;
805 aTitleToIndexMap.insert( StringToIndexMap::value_type( aPopupTitle, nIndex ));
806 ++nIndex;
812 return ( rAddonOfficeMenuBarSeq.getLength() > 0 );
815 //*****************************************************************************************************************
816 // private method
817 //*****************************************************************************************************************
818 sal_Bool AddonsOptions_Impl::ReadOfficeToolBarSet( AddonToolBars& rAddonOfficeToolBars, std::vector< OUString >& rAddonOfficeToolBarResNames )
820 // Read the OfficeToolBar set and fill property sequences
821 OUString aAddonToolBarNodeName( "AddonUI/OfficeToolBar" );
822 Sequence< OUString > aAddonToolBarNodeSeq = GetNodeNames( aAddonToolBarNodeName );
823 OUString aAddonToolBarNode( aAddonToolBarNodeName + m_aPathDelimiter );
825 sal_uInt32 nCount = aAddonToolBarNodeSeq.getLength();
827 for ( sal_uInt32 n = 0; n < nCount; n++ )
829 OUString aToolBarItemNode( aAddonToolBarNode + aAddonToolBarNodeSeq[n] );
830 rAddonOfficeToolBarResNames.push_back( aAddonToolBarNodeSeq[n] );
831 rAddonOfficeToolBars.push_back( m_aEmptyAddonToolBar );
832 ReadToolBarItemSet( aToolBarItemNode, rAddonOfficeToolBars[n] );
835 return ( !rAddonOfficeToolBars.empty() );
839 //*****************************************************************************************************************
840 // private method
841 //*****************************************************************************************************************
842 sal_Bool AddonsOptions_Impl::ReadToolBarItemSet( const OUString rToolBarItemSetNodeName, Sequence< Sequence< PropertyValue > >& rAddonOfficeToolBarSeq )
844 sal_Bool bInsertSeparator = sal_False;
845 sal_uInt32 nToolBarItemCount = rAddonOfficeToolBarSeq.getLength();
846 OUString aAddonToolBarItemSetNode( rToolBarItemSetNodeName + m_aPathDelimiter );
847 Sequence< OUString > aAddonToolBarItemSetNodeSeq = GetNodeNames( rToolBarItemSetNodeName );
848 Sequence< PropertyValue > aToolBarItem( PROPERTYCOUNT_TOOLBARITEM );
850 // Init the property value sequence
851 aToolBarItem[ OFFSET_TOOLBARITEM_URL ].Name = m_aPropNames[ INDEX_URL ];
852 aToolBarItem[ OFFSET_TOOLBARITEM_TITLE ].Name = m_aPropNames[ INDEX_TITLE ];
853 aToolBarItem[ OFFSET_TOOLBARITEM_IMAGEIDENTIFIER ].Name = m_aPropNames[ INDEX_IMAGEIDENTIFIER];
854 aToolBarItem[ OFFSET_TOOLBARITEM_TARGET ].Name = m_aPropNames[ INDEX_TARGET ];
855 aToolBarItem[ OFFSET_TOOLBARITEM_CONTEXT ].Name = m_aPropNames[ INDEX_CONTEXT ];
856 aToolBarItem[ OFFSET_TOOLBARITEM_CONTROLTYPE ].Name = m_aPropNames[ INDEX_CONTROLTYPE ];
857 aToolBarItem[ OFFSET_TOOLBARITEM_WIDTH ].Name = m_aPropNames[ INDEX_WIDTH ];
859 sal_uInt32 nCount = aAddonToolBarItemSetNodeSeq.getLength();
860 for ( sal_uInt32 n = 0; n < nCount; n++ )
862 OUString aToolBarItemNode( aAddonToolBarItemSetNode + aAddonToolBarItemSetNodeSeq[n] );
864 // Read the ToolBarItem
865 if ( ReadToolBarItem( aToolBarItemNode, aToolBarItem ) )
867 if ( bInsertSeparator )
869 bInsertSeparator = sal_False;
870 InsertToolBarSeparator( rAddonOfficeToolBarSeq );
873 // Successfully read a toolbar item, append to our list
874 sal_uInt32 nAddonCount = rAddonOfficeToolBarSeq.getLength();
875 rAddonOfficeToolBarSeq.realloc( nAddonCount+1 );
876 rAddonOfficeToolBarSeq[nAddonCount] = aToolBarItem;
880 return ( (sal_uInt32)rAddonOfficeToolBarSeq.getLength() > nToolBarItemCount );
883 //*****************************************************************************************************************
884 // private method
885 //*****************************************************************************************************************
886 void AddonsOptions_Impl::InsertToolBarSeparator( Sequence< Sequence< PropertyValue > >& rAddonOfficeToolBarSeq )
888 Sequence< PropertyValue > aToolBarItem( PROPERTYCOUNT_TOOLBARITEM );
890 aToolBarItem[ OFFSET_TOOLBARITEM_URL ].Name = m_aPropNames[ INDEX_URL ];
891 aToolBarItem[ OFFSET_TOOLBARITEM_TITLE ].Name = m_aPropNames[ INDEX_TITLE ];
892 aToolBarItem[ OFFSET_TOOLBARITEM_IMAGEIDENTIFIER ].Name = m_aPropNames[ INDEX_IMAGEIDENTIFIER];
893 aToolBarItem[ OFFSET_TOOLBARITEM_TARGET ].Name = m_aPropNames[ INDEX_TARGET ];
894 aToolBarItem[ OFFSET_TOOLBARITEM_CONTEXT ].Name = m_aPropNames[ INDEX_CONTEXT ];
896 aToolBarItem[ OFFSET_TOOLBARITEM_URL ].Value <<= SEPARATOR_URL;
897 aToolBarItem[ OFFSET_TOOLBARITEM_TITLE ].Value <<= m_aEmpty;
898 aToolBarItem[ OFFSET_TOOLBARITEM_TARGET ].Value <<= m_aEmpty;
899 aToolBarItem[ OFFSET_TOOLBARITEM_IMAGEIDENTIFIER ].Value <<= m_aEmpty;
900 aToolBarItem[ OFFSET_TOOLBARITEM_CONTEXT ].Value <<= m_aEmpty;
902 sal_uInt32 nToolBarItemCount = rAddonOfficeToolBarSeq.getLength();
903 rAddonOfficeToolBarSeq.realloc( nToolBarItemCount+1 );
904 rAddonOfficeToolBarSeq[nToolBarItemCount] = aToolBarItem;
908 //*****************************************************************************************************************
909 // private method
910 //*****************************************************************************************************************
911 void AddonsOptions_Impl::ReadImages( ImageManager& aImageManager )
913 // Read the user-defined Images set and fill image manager
914 OUString aAddonImagesNodeName( "AddonUI/Images" );
915 Sequence< OUString > aAddonImagesNodeSeq = GetNodeNames( aAddonImagesNodeName );
916 OUString aAddonImagesNode( aAddonImagesNodeName + m_aPathDelimiter );
918 sal_uInt32 nCount = aAddonImagesNodeSeq.getLength();
920 // Init the property value sequence
921 Sequence< OUString > aAddonImageItemNodePropNames( 1 );
922 OUString aURL;
924 for ( sal_uInt32 n = 0; n < nCount; n++ )
926 OUString aImagesItemNode( aAddonImagesNode + aAddonImagesNodeSeq[n] );
928 // Create sequence for data access
929 OUStringBuffer aBuffer( aImagesItemNode );
930 aBuffer.append( m_aPathDelimiter );
931 aBuffer.append( m_aPropNames[ OFFSET_MENUITEM_URL ] );
932 aAddonImageItemNodePropNames[0] = aBuffer.makeStringAndClear();
934 Sequence< Any > aAddonImageItemNodeValues = GetProperties( aAddonImageItemNodePropNames );
936 // An user-defined image entry must have an URL. As "ImageIdentifier" has a higher priority
937 // we also check if we already have an images association.
938 if (( aAddonImageItemNodeValues[0] >>= aURL ) &&
939 !aURL.isEmpty() &&
940 !HasAssociatedImages( aURL ))
942 OUStringBuffer aBuf( aImagesItemNode );
943 aBuf.append( m_aPathDelimiter );
944 aBuf.append( IMAGES_NODENAME );
945 aBuf.append( m_aPathDelimiter );
946 OUString aImagesUserDefinedItemNode = aBuf.makeStringAndClear();
948 // Read a user-defined images data
949 ImageEntry* pImageEntry = ReadImageData( aImagesUserDefinedItemNode );
950 if ( pImageEntry )
952 // Successfully read a user-defined images item, put it into our image manager
953 aImageManager.insert( ImageManager::value_type( aURL, *pImageEntry ));
954 delete pImageEntry; // We have the ownership of the pointer
960 //*****************************************************************************************************************
961 // private method
962 //*****************************************************************************************************************
964 OUString AddonsOptions_Impl::GeneratePrefixURL()
966 // Create an unique prefixed Add-On popup menu URL so it can be identified later as a runtime popup menu.
967 // They use a different image manager, so they must be identified by the sfx2/framework code.
968 OUString aPopupMenuURL;
969 OUStringBuffer aBuf( m_aRootAddonPopupMenuURLPrexfix.getLength() + 3 );
970 aBuf.append( m_aRootAddonPopupMenuURLPrexfix );
971 aBuf.append( OUString::valueOf( ++m_nRootAddonPopupMenuId ));
972 aPopupMenuURL = aBuf.makeStringAndClear();
973 return aPopupMenuURL;
976 //*****************************************************************************************************************
977 // private method
978 //*****************************************************************************************************************
980 sal_Bool AddonsOptions_Impl::ReadMenuMergeInstructions( MergeMenuInstructionContainer& aContainer )
982 const OUString aMenuMergeRootName( "AddonUI/OfficeMenuBarMerging/" );
984 Sequence< OUString > aAddonMergeNodesSeq = GetNodeNames( aMenuMergeRootName );
985 OUString aAddonMergeNode( aMenuMergeRootName );
987 sal_uInt32 nCount = aAddonMergeNodesSeq.getLength();
989 // Init the property value sequence
990 Sequence< OUString > aNodePropNames( 5 );
992 for ( sal_uInt32 i = 0; i < nCount; i++ )
994 OUString aMergeAddonInstructions( aAddonMergeNode + aAddonMergeNodesSeq[i] );
996 Sequence< OUString > aAddonInstMergeNodesSeq = GetNodeNames( aMergeAddonInstructions );
997 sal_uInt32 nCountAddons = aAddonInstMergeNodesSeq.getLength();
999 for ( sal_uInt32 j = 0; j < nCountAddons; j++ )
1001 OUStringBuffer aMergeAddonInstructionBase( aMergeAddonInstructions );
1002 aMergeAddonInstructionBase.append( m_aPathDelimiter );
1003 aMergeAddonInstructionBase.append( aAddonInstMergeNodesSeq[j] );
1004 aMergeAddonInstructionBase.append( m_aPathDelimiter );
1006 // Create sequence for data access
1007 OUStringBuffer aBuffer( aMergeAddonInstructionBase );
1008 aBuffer.append( m_aPropMergeMenuNames[ OFFSET_MERGEMENU_MERGEPOINT ] );
1009 aNodePropNames[0] = aBuffer.makeStringAndClear();
1011 aBuffer = aMergeAddonInstructionBase;
1012 aBuffer.append( m_aPropMergeMenuNames[ OFFSET_MERGEMENU_MERGECOMMAND ] );
1013 aNodePropNames[1] = aBuffer.makeStringAndClear();
1015 aBuffer = aMergeAddonInstructionBase;
1016 aBuffer.append( m_aPropMergeMenuNames[ OFFSET_MERGEMENU_MERGECOMMANDPARAMETER ] );
1017 aNodePropNames[2] = aBuffer.makeStringAndClear();
1019 aBuffer = aMergeAddonInstructionBase;
1020 aBuffer.append( m_aPropMergeMenuNames[ OFFSET_MERGEMENU_MERGEFALLBACK ] );
1021 aNodePropNames[3] = aBuffer.makeStringAndClear();
1023 aBuffer = aMergeAddonInstructionBase;
1024 aBuffer.append( m_aPropMergeMenuNames[ OFFSET_MERGEMENU_MERGECONTEXT ] );
1025 aNodePropNames[4] = aBuffer.makeStringAndClear();
1027 Sequence< Any > aNodePropValues = GetProperties( aNodePropNames );
1029 MergeMenuInstruction aMergeMenuInstruction;
1030 aNodePropValues[0] >>= aMergeMenuInstruction.aMergePoint;
1031 aNodePropValues[1] >>= aMergeMenuInstruction.aMergeCommand;
1032 aNodePropValues[2] >>= aMergeMenuInstruction.aMergeCommandParameter;
1033 aNodePropValues[3] >>= aMergeMenuInstruction.aMergeFallback;
1034 aNodePropValues[4] >>= aMergeMenuInstruction.aMergeContext;
1036 OUString aMergeMenuBase = aMergeAddonInstructionBase.makeStringAndClear();
1037 ReadMergeMenuData( aMergeMenuBase, aMergeMenuInstruction.aMergeMenu );
1039 aContainer.push_back( aMergeMenuInstruction );
1043 return sal_True;
1046 //*****************************************************************************************************************
1047 // private method
1048 //*****************************************************************************************************************
1049 sal_Bool AddonsOptions_Impl::ReadMergeMenuData( const OUString& aMergeAddonInstructionBase, Sequence< Sequence< PropertyValue > >& rMergeMenu )
1051 OUString aMergeMenuBaseNode( aMergeAddonInstructionBase+m_aPropMergeMenuNames[ OFFSET_MERGEMENU_MENUITEMS ] );
1053 Sequence< OUString > aSubMenuNodeNames = GetNodeNames( aMergeMenuBaseNode );
1054 aMergeMenuBaseNode += m_aPathDelimiter;
1056 // extend the node names to have full path strings
1057 for ( sal_uInt32 i = 0; i < (sal_uInt32)aSubMenuNodeNames.getLength(); i++ )
1058 aSubMenuNodeNames[i] = OUString( aMergeMenuBaseNode + aSubMenuNodeNames[i] );
1060 return ReadSubMenuEntries( aSubMenuNodeNames, rMergeMenu );
1063 //*****************************************************************************************************************
1064 // private method
1065 //*****************************************************************************************************************
1066 sal_Bool AddonsOptions_Impl::ReadToolbarMergeInstructions( ToolbarMergingInstructions& rCachedToolbarMergingInstructions )
1068 const OUString aToolbarMergeRootName( "AddonUI/OfficeToolbarMerging/" );
1070 Sequence< OUString > aAddonMergeNodesSeq = GetNodeNames( aToolbarMergeRootName );
1071 OUString aAddonMergeNode( aToolbarMergeRootName );
1073 sal_uInt32 nCount = aAddonMergeNodesSeq.getLength();
1075 // Init the property value sequence
1076 Sequence< OUString > aNodePropNames( 6 );
1078 for ( sal_uInt32 i = 0; i < nCount; i++ )
1080 OUString aMergeAddonInstructions( aAddonMergeNode + aAddonMergeNodesSeq[i] );
1082 Sequence< OUString > aAddonInstMergeNodesSeq = GetNodeNames( aMergeAddonInstructions );
1083 sal_uInt32 nCountAddons = aAddonInstMergeNodesSeq.getLength();
1085 for ( sal_uInt32 j = 0; j < nCountAddons; j++ )
1087 OUStringBuffer aMergeAddonInstructionBase( aMergeAddonInstructions );
1088 aMergeAddonInstructionBase.append( m_aPathDelimiter );
1089 aMergeAddonInstructionBase.append( aAddonInstMergeNodesSeq[j] );
1090 aMergeAddonInstructionBase.append( m_aPathDelimiter );
1092 // Create sequence for data access
1093 OUStringBuffer aBuffer( aMergeAddonInstructionBase );
1094 aBuffer.append( m_aPropMergeToolbarNames[ OFFSET_MERGETOOLBAR_TOOLBAR ] );
1095 aNodePropNames[0] = aBuffer.makeStringAndClear();
1097 aBuffer = aMergeAddonInstructionBase;
1098 aBuffer.append( m_aPropMergeToolbarNames[ OFFSET_MERGETOOLBAR_MERGEPOINT ] );
1099 aNodePropNames[1] = aBuffer.makeStringAndClear();
1101 aBuffer = aMergeAddonInstructionBase;
1102 aBuffer.append( m_aPropMergeToolbarNames[ OFFSET_MERGETOOLBAR_MERGECOMMAND ] );
1103 aNodePropNames[2] = aBuffer.makeStringAndClear();
1105 aBuffer = aMergeAddonInstructionBase;
1106 aBuffer.append( m_aPropMergeToolbarNames[ OFFSET_MERGETOOLBAR_MERGECOMMANDPARAMETER ] );
1107 aNodePropNames[3] = aBuffer.makeStringAndClear();
1109 aBuffer = aMergeAddonInstructionBase;
1110 aBuffer.append( m_aPropMergeToolbarNames[ OFFSET_MERGETOOLBAR_MERGEFALLBACK ] );
1111 aNodePropNames[4] = aBuffer.makeStringAndClear();
1113 aBuffer = aMergeAddonInstructionBase;
1114 aBuffer.append( m_aPropMergeToolbarNames[ OFFSET_MERGETOOLBAR_MERGECONTEXT ] );
1115 aNodePropNames[5] = aBuffer.makeStringAndClear();
1117 Sequence< Any > aNodePropValues = GetProperties( aNodePropNames );
1119 MergeToolbarInstruction aMergeToolbarInstruction;
1120 aNodePropValues[0] >>= aMergeToolbarInstruction.aMergeToolbar;
1121 aNodePropValues[1] >>= aMergeToolbarInstruction.aMergePoint;
1122 aNodePropValues[2] >>= aMergeToolbarInstruction.aMergeCommand;
1123 aNodePropValues[3] >>= aMergeToolbarInstruction.aMergeCommandParameter;
1124 aNodePropValues[4] >>= aMergeToolbarInstruction.aMergeFallback;
1125 aNodePropValues[5] >>= aMergeToolbarInstruction.aMergeContext;
1127 ReadMergeToolbarData( aMergeAddonInstructionBase.makeStringAndClear(),
1128 aMergeToolbarInstruction.aMergeToolbarItems );
1130 MergeToolbarInstructionContainer& rVector = rCachedToolbarMergingInstructions[ aMergeToolbarInstruction.aMergeToolbar ];
1131 rVector.push_back( aMergeToolbarInstruction );
1135 return sal_True;
1138 //*****************************************************************************************************************
1139 // private method
1140 //*****************************************************************************************************************
1141 sal_Bool AddonsOptions_Impl::ReadMergeToolbarData( const OUString& aMergeAddonInstructionBase, Sequence< Sequence< PropertyValue > >& rMergeToolbarItems )
1143 OUStringBuffer aBuffer( aMergeAddonInstructionBase );
1144 aBuffer.append( m_aPropMergeToolbarNames[ OFFSET_MERGETOOLBAR_TOOLBARITEMS ] );
1146 OUString aMergeToolbarBaseNode = aBuffer.makeStringAndClear();
1148 return ReadToolBarItemSet( aMergeToolbarBaseNode, rMergeToolbarItems );
1152 sal_Bool AddonsOptions_Impl::ReadStatusbarMergeInstructions( MergeStatusbarInstructionContainer& aContainer )
1154 const ::rtl::OUString aStatusbarMergeRootName( RTL_CONSTASCII_USTRINGPARAM( "AddonUI/OfficeStatusbarMerging/" ));
1156 Sequence< ::rtl::OUString > aAddonMergeNodesSeq = GetNodeNames( aStatusbarMergeRootName );
1157 ::rtl::OUString aAddonMergeNode( aStatusbarMergeRootName );
1158 sal_uInt32 nCount = aAddonMergeNodesSeq.getLength();
1160 Sequence< ::rtl::OUString > aNodePropNames( 5 );
1161 ::rtl::OUString aURL;
1163 for ( sal_uInt32 i = 0; i < nCount; i++ )
1165 ::rtl::OUString aMergeAddonInstructions( aAddonMergeNode + aAddonMergeNodesSeq[i] );
1167 Sequence< ::rtl::OUString > aAddonInstMergeNodesSeq = GetNodeNames( aMergeAddonInstructions );
1168 sal_uInt32 nCountAddons = aAddonInstMergeNodesSeq.getLength();
1170 for ( sal_uInt32 j = 0; j < nCountAddons; j++ )
1172 ::rtl::OUStringBuffer aMergeAddonInstructionBase( aMergeAddonInstructions );
1173 aMergeAddonInstructionBase.append( m_aPathDelimiter );
1174 aMergeAddonInstructionBase.append( aAddonInstMergeNodesSeq[j] );
1175 aMergeAddonInstructionBase.append( m_aPathDelimiter );
1177 // Create sequence for data access
1178 ::rtl::OUStringBuffer aBuffer( aMergeAddonInstructionBase );
1179 aBuffer.append( m_aPropMergeMenuNames[ OFFSET_MERGESTATUSBAR_MERGEPOINT ] );
1180 aNodePropNames[0] = aBuffer.makeStringAndClear();
1182 aBuffer = aMergeAddonInstructionBase;
1183 aBuffer.append( m_aPropMergeMenuNames[ OFFSET_MERGESTATUSBAR_MERGECOMMAND ] );
1184 aNodePropNames[1] = aBuffer.makeStringAndClear();
1186 aBuffer = aMergeAddonInstructionBase;
1187 aBuffer.append( m_aPropMergeMenuNames[ OFFSET_MERGESTATUSBAR_MERGECOMMANDPARAMETER ] );
1188 aNodePropNames[2] = aBuffer.makeStringAndClear();
1190 aBuffer = aMergeAddonInstructionBase;
1191 aBuffer.append( m_aPropMergeMenuNames[ OFFSET_MERGESTATUSBAR_MERGEFALLBACK ] );
1192 aNodePropNames[3] = aBuffer.makeStringAndClear();
1194 aBuffer = aMergeAddonInstructionBase;
1195 aBuffer.append( m_aPropMergeMenuNames[ OFFSET_MERGESTATUSBAR_MERGECONTEXT ] );
1196 aNodePropNames[4] = aBuffer.makeStringAndClear();
1198 Sequence< Any > aNodePropValues = GetProperties( aNodePropNames );
1200 MergeStatusbarInstruction aMergeStatusbarInstruction;
1201 aNodePropValues[0] >>= aMergeStatusbarInstruction.aMergePoint;
1202 aNodePropValues[1] >>= aMergeStatusbarInstruction.aMergeCommand;
1203 aNodePropValues[2] >>= aMergeStatusbarInstruction.aMergeCommandParameter;
1204 aNodePropValues[3] >>= aMergeStatusbarInstruction.aMergeFallback;
1205 aNodePropValues[4] >>= aMergeStatusbarInstruction.aMergeContext;
1207 ReadMergeStatusbarData( aMergeAddonInstructionBase.makeStringAndClear(),
1208 aMergeStatusbarInstruction.aMergeStatusbarItems );
1210 aContainer.push_back( aMergeStatusbarInstruction );
1214 return sal_True;
1217 sal_Bool AddonsOptions_Impl::ReadMergeStatusbarData(
1218 const ::rtl::OUString& aMergeAddonInstructionBase,
1219 Sequence< Sequence< PropertyValue > >& rMergeStatusbarItems )
1221 sal_uInt32 nStatusbarItemCount = rMergeStatusbarItems.getLength();
1223 ::rtl::OUStringBuffer aBuffer( aMergeAddonInstructionBase );
1224 aBuffer.append( m_aPropMergeStatusbarNames[ OFFSET_MERGESTATUSBAR_STATUSBARITEMS ] );
1225 ::rtl::OUString aMergeStatusbarBaseNode = aBuffer.makeStringAndClear();
1227 ::rtl::OUString aAddonStatusbarItemSetNode( aMergeStatusbarBaseNode + m_aPathDelimiter );
1228 Sequence< ::rtl::OUString > aAddonStatusbarItemSetNodeSeq = GetNodeNames( aMergeStatusbarBaseNode );
1230 Sequence< PropertyValue > aStatusbarItem( PROPERTYCOUNT_STATUSBARITEM );
1231 aStatusbarItem[ OFFSET_STATUSBARITEM_URL ].Name = m_aPropNames[ INDEX_URL ];
1232 aStatusbarItem[ OFFSET_STATUSBARITEM_TITLE ].Name = m_aPropNames[ INDEX_TITLE ];
1233 aStatusbarItem[ OFFSET_STATUSBARITEM_CONTEXT ].Name = m_aPropNames[ INDEX_CONTEXT ];
1234 aStatusbarItem[ OFFSET_STATUSBARITEM_ALIGN ].Name = m_aPropNames[ INDEX_ALIGN ];
1235 aStatusbarItem[ OFFSET_STATUSBARITEM_AUTOSIZE ].Name = m_aPropNames[ INDEX_AUTOSIZE ];
1236 aStatusbarItem[ OFFSET_STATUSBARITEM_OWNERDRAW ].Name = m_aPropNames[ INDEX_OWNERDRAW ];
1237 aStatusbarItem[ OFFSET_STATUSBARITEM_WIDTH ].Name = m_aPropNames[ INDEX_WIDTH ];
1239 sal_uInt32 nCount = aAddonStatusbarItemSetNodeSeq.getLength();
1240 for ( sal_uInt32 n = 0; n < nCount; n++ )
1242 ::rtl::OUString aStatusbarItemNode( aAddonStatusbarItemSetNode + aAddonStatusbarItemSetNodeSeq[n] );
1244 if ( ReadStatusBarItem( aStatusbarItemNode, aStatusbarItem ) )
1246 sal_uInt32 nAddonCount = rMergeStatusbarItems.getLength();
1247 rMergeStatusbarItems.realloc( nAddonCount+1 );
1248 rMergeStatusbarItems[nAddonCount] = aStatusbarItem;
1252 return ( (sal_uInt32)rMergeStatusbarItems.getLength() > nStatusbarItemCount );
1255 sal_Bool AddonsOptions_Impl::ReadStatusBarItem(
1256 const ::rtl::OUString& aStatusarItemNodeName,
1257 Sequence< PropertyValue >& aStatusbarItem )
1259 sal_Bool bResult( sal_False );
1260 ::rtl::OUString aURL;
1261 ::rtl::OUString aAddonStatusbarItemTreeNode( aStatusarItemNodeName + m_aPathDelimiter );
1262 Sequence< Any > aStatusbarItemNodePropValues;
1264 aStatusbarItemNodePropValues = GetProperties( GetPropertyNamesStatusbarItem( aAddonStatusbarItemTreeNode ) );
1266 // Command URL is required
1267 if (( aStatusbarItemNodePropValues[ OFFSET_STATUSBARITEM_URL ] >>= aURL ) && aURL.getLength() > 0 )
1269 aStatusbarItem[ OFFSET_STATUSBARITEM_URL ].Value <<= aURL;
1270 aStatusbarItem[ OFFSET_STATUSBARITEM_TITLE ].Value <<= aStatusbarItemNodePropValues[ OFFSET_STATUSBARITEM_TITLE ];
1271 aStatusbarItem[ OFFSET_STATUSBARITEM_CONTEXT ].Value <<= aStatusbarItemNodePropValues[ OFFSET_STATUSBARITEM_CONTEXT ];
1272 aStatusbarItem[ OFFSET_STATUSBARITEM_ALIGN ].Value <<= aStatusbarItemNodePropValues[ OFFSET_STATUSBARITEM_ALIGN ];
1273 aStatusbarItem[ OFFSET_STATUSBARITEM_AUTOSIZE ].Value <<= aStatusbarItemNodePropValues[ OFFSET_STATUSBARITEM_AUTOSIZE ];;
1274 aStatusbarItem[ OFFSET_STATUSBARITEM_OWNERDRAW ].Value <<= aStatusbarItemNodePropValues[ OFFSET_STATUSBARITEM_OWNERDRAW ];
1276 // Configuration uses hyper for long. Therefore transform into sal_Int32
1277 sal_Int64 nValue( 0 );
1278 aStatusbarItemNodePropValues[ OFFSET_STATUSBARITEM_WIDTH ] >>= nValue;
1279 aStatusbarItem[ OFFSET_STATUSBARITEM_WIDTH ].Value <<= sal_Int32( nValue );
1281 bResult = sal_True;
1284 return bResult;
1287 //*****************************************************************************************************************
1288 // private method
1289 //*****************************************************************************************************************
1290 sal_Bool AddonsOptions_Impl::ReadMenuItem( const OUString& aMenuNodeName, Sequence< PropertyValue >& aMenuItem, sal_Bool bIgnoreSubMenu )
1292 sal_Bool bResult = sal_False;
1293 OUString aStrValue;
1294 OUString aAddonMenuItemTreeNode( aMenuNodeName + m_aPathDelimiter );
1295 Sequence< Any > aMenuItemNodePropValues;
1297 aMenuItemNodePropValues = GetProperties( GetPropertyNamesMenuItem( aAddonMenuItemTreeNode ) );
1298 if (( aMenuItemNodePropValues[ OFFSET_MENUITEM_TITLE ] >>= aStrValue ) && !aStrValue.isEmpty() )
1300 aMenuItem[ OFFSET_MENUITEM_TITLE ].Value <<= aStrValue;
1302 OUString aRootSubMenuName( aAddonMenuItemTreeNode + m_aPropNames[ INDEX_SUBMENU ] );
1303 Sequence< OUString > aRootSubMenuNodeNames = GetNodeNames( aRootSubMenuName );
1304 if ( aRootSubMenuNodeNames.getLength() > 0 && !bIgnoreSubMenu )
1306 // Set a unique prefixed Add-On popup menu URL so it can be identified later
1307 OUString aPopupMenuURL = GeneratePrefixURL();
1308 OUString aPopupMenuImageId;
1310 aMenuItemNodePropValues[ OFFSET_MENUITEM_IMAGEIDENTIFIER ] >>= aPopupMenuImageId;
1311 ReadAndAssociateImages( aPopupMenuURL, aPopupMenuImageId );
1313 // A popup menu must have a title and can have a URL and ImageIdentifier
1314 // Set the other property values to empty
1315 aMenuItem[ OFFSET_MENUITEM_URL ].Value <<= aPopupMenuURL;
1316 aMenuItem[ OFFSET_MENUITEM_TARGET ].Value <<= m_aEmpty;
1317 aMenuItem[ OFFSET_MENUITEM_IMAGEIDENTIFIER ].Value <<= aPopupMenuImageId;
1318 aMenuItem[ OFFSET_MENUITEM_CONTEXT ].Value <<= aMenuItemNodePropValues[ OFFSET_MENUITEM_CONTEXT ];
1320 // Continue to read the sub menu nodes
1321 Sequence< Sequence< PropertyValue > > aSubMenuSeq;
1322 OUString aSubMenuRootNodeName( aRootSubMenuName + m_aPathDelimiter );
1323 for ( sal_uInt32 n = 0; n < (sal_uInt32)aRootSubMenuNodeNames.getLength(); n++ )
1324 aRootSubMenuNodeNames[n] = OUString( aSubMenuRootNodeName + aRootSubMenuNodeNames[n] );
1325 ReadSubMenuEntries( aRootSubMenuNodeNames, aSubMenuSeq );
1326 aMenuItem[ OFFSET_MENUITEM_SUBMENU ].Value <<= aSubMenuSeq;
1327 bResult = sal_True;
1329 else if (( aMenuItemNodePropValues[ OFFSET_MENUITEM_URL ] >>= aStrValue ) && !aStrValue.isEmpty() )
1331 // A simple menu item => read the other properties;
1332 OUString aMenuImageId;
1334 aMenuItemNodePropValues[ OFFSET_MENUITEM_IMAGEIDENTIFIER ] >>= aMenuImageId;
1335 ReadAndAssociateImages( aStrValue, aMenuImageId );
1337 aMenuItem[ OFFSET_MENUITEM_URL ].Value <<= aStrValue;
1338 aMenuItem[ OFFSET_MENUITEM_TARGET ].Value <<= aMenuItemNodePropValues[ OFFSET_MENUITEM_TARGET ];
1339 aMenuItem[ OFFSET_MENUITEM_IMAGEIDENTIFIER ].Value <<= aMenuImageId;
1340 aMenuItem[ OFFSET_MENUITEM_CONTEXT ].Value <<= aMenuItemNodePropValues[ OFFSET_MENUITEM_CONTEXT ];
1341 aMenuItem[ OFFSET_MENUITEM_SUBMENU ].Value <<= Sequence< Sequence< PropertyValue > >(); // Submenu set!
1343 bResult = sal_True;
1346 else if (( aMenuItemNodePropValues[ OFFSET_MENUITEM_URL ] >>= aStrValue ) &&
1347 aStrValue == SEPARATOR_URL_STR )
1349 // Separator
1350 aMenuItem[ OFFSET_MENUITEM_URL ].Value <<= aStrValue;
1351 aMenuItem[ OFFSET_MENUITEM_TARGET ].Value <<= m_aEmpty;
1352 aMenuItem[ OFFSET_MENUITEM_IMAGEIDENTIFIER ].Value <<= m_aEmpty;
1353 aMenuItem[ OFFSET_MENUITEM_CONTEXT ].Value <<= m_aEmpty;
1354 aMenuItem[ OFFSET_MENUITEM_SUBMENU ].Value <<= Sequence< Sequence< PropertyValue > >(); // Submenu set!
1355 bResult = sal_True;
1358 return bResult;
1361 //*****************************************************************************************************************
1362 // private method
1363 //*****************************************************************************************************************
1364 sal_Bool AddonsOptions_Impl::ReadPopupMenu( const OUString& aPopupMenuNodeName, Sequence< PropertyValue >& aPopupMenu )
1366 sal_Bool bResult = sal_False;
1367 OUString aStrValue;
1368 OUString aAddonPopupMenuTreeNode( aPopupMenuNodeName + m_aPathDelimiter );
1369 Sequence< Any > aPopupMenuNodePropValues;
1371 aPopupMenuNodePropValues = GetProperties( GetPropertyNamesPopupMenu( aAddonPopupMenuTreeNode ) );
1372 if (( aPopupMenuNodePropValues[ OFFSET_POPUPMENU_TITLE ] >>= aStrValue ) &&
1373 !aStrValue.isEmpty() )
1375 aPopupMenu[ OFFSET_POPUPMENU_TITLE ].Value <<= aStrValue;
1377 OUString aRootSubMenuName( aAddonPopupMenuTreeNode + m_aPropNames[ INDEX_SUBMENU ] );
1378 Sequence< OUString > aRootSubMenuNodeNames = GetNodeNames( aRootSubMenuName );
1379 if ( aRootSubMenuNodeNames.getLength() > 0 )
1381 // A top-level popup menu needs a title
1382 // Set a unique prefixed Add-On popup menu URL so it can be identified later
1383 OUString aPopupMenuURL = GeneratePrefixURL();
1385 aPopupMenu[ OFFSET_POPUPMENU_URL ].Value <<= aPopupMenuURL;
1386 aPopupMenu[ OFFSET_POPUPMENU_CONTEXT ].Value <<= aPopupMenuNodePropValues[ OFFSET_POPUPMENU_CONTEXT ];
1388 // Continue to read the sub menu nodes
1389 Sequence< Sequence< PropertyValue > > aSubMenuSeq;
1390 OUString aSubMenuRootNodeName( aRootSubMenuName + m_aPathDelimiter );
1391 for ( sal_uInt32 n = 0; n < (sal_uInt32)aRootSubMenuNodeNames.getLength(); n++ )
1392 aRootSubMenuNodeNames[n] = OUString( aSubMenuRootNodeName + aRootSubMenuNodeNames[n] );
1393 ReadSubMenuEntries( aRootSubMenuNodeNames, aSubMenuSeq );
1394 aPopupMenu[ OFFSET_POPUPMENU_SUBMENU ].Value <<= aSubMenuSeq;
1395 bResult = sal_True;
1399 return bResult;
1402 //*****************************************************************************************************************
1403 // private method
1404 //*****************************************************************************************************************
1405 sal_Bool AddonsOptions_Impl::AppendPopupMenu( Sequence< PropertyValue >& rTargetPopupMenu, const Sequence< PropertyValue >& rSourcePopupMenu )
1407 Sequence< Sequence< PropertyValue > > aTargetSubMenuSeq;
1408 Sequence< Sequence< PropertyValue > > aSourceSubMenuSeq;
1410 if (( rTargetPopupMenu[ OFFSET_POPUPMENU_SUBMENU ].Value >>= aTargetSubMenuSeq ) &&
1411 ( rSourcePopupMenu[ OFFSET_POPUPMENU_SUBMENU ].Value >>= aSourceSubMenuSeq ))
1413 sal_uInt32 nIndex = aTargetSubMenuSeq.getLength();
1414 aTargetSubMenuSeq.realloc( nIndex + aSourceSubMenuSeq.getLength() );
1415 for ( sal_uInt32 i = 0; i < sal_uInt32( aSourceSubMenuSeq.getLength() ); i++ )
1416 aTargetSubMenuSeq[nIndex++] = aSourceSubMenuSeq[i];
1417 rTargetPopupMenu[ OFFSET_POPUPMENU_SUBMENU ].Value <<= aTargetSubMenuSeq;
1420 return sal_True;
1423 //*****************************************************************************************************************
1424 // private method
1425 //*****************************************************************************************************************
1426 sal_Bool AddonsOptions_Impl::ReadToolBarItem( const OUString& aToolBarItemNodeName, Sequence< PropertyValue >& aToolBarItem )
1428 sal_Bool bResult = sal_False;
1429 OUString aTitle;
1430 OUString aURL;
1431 OUString aAddonToolBarItemTreeNode( aToolBarItemNodeName + m_aPathDelimiter );
1432 Sequence< Any > aToolBarItemNodePropValues;
1434 aToolBarItemNodePropValues = GetProperties( GetPropertyNamesToolBarItem( aAddonToolBarItemTreeNode ) );
1436 // A toolbar item must have a command URL
1437 if (( aToolBarItemNodePropValues[ OFFSET_TOOLBARITEM_URL ] >>= aURL ) && !aURL.isEmpty() )
1439 if ( aURL.equals( SEPARATOR_URL ))
1441 // A speparator toolbar item only needs a URL
1442 aToolBarItem[ OFFSET_TOOLBARITEM_URL ].Value <<= aURL;
1443 aToolBarItem[ OFFSET_TOOLBARITEM_TITLE ].Value <<= m_aEmpty;
1444 aToolBarItem[ OFFSET_TOOLBARITEM_TARGET ].Value <<= m_aEmpty;
1445 aToolBarItem[ OFFSET_TOOLBARITEM_IMAGEIDENTIFIER ].Value <<= m_aEmpty;
1446 aToolBarItem[ OFFSET_TOOLBARITEM_CONTEXT ].Value <<= m_aEmpty;
1447 aToolBarItem[ OFFSET_TOOLBARITEM_CONTROLTYPE ].Value <<= m_aEmpty;
1448 aToolBarItem[ OFFSET_TOOLBARITEM_WIDTH ].Value <<= sal_Int32( 0 );
1450 bResult = sal_True;
1452 else if (( aToolBarItemNodePropValues[ OFFSET_TOOLBARITEM_TITLE ] >>= aTitle ) && !aTitle.isEmpty() )
1454 // A normal toolbar item must also have title => read the other properties;
1455 OUString aImageId;
1457 // Try to map a user-defined image URL to our internal private image URL
1458 aToolBarItemNodePropValues[ OFFSET_TOOLBARITEM_IMAGEIDENTIFIER ] >>= aImageId;
1459 ReadAndAssociateImages( aURL, aImageId );
1461 aToolBarItem[ OFFSET_TOOLBARITEM_URL ].Value <<= aURL;
1462 aToolBarItem[ OFFSET_TOOLBARITEM_TITLE ].Value <<= aTitle;
1463 aToolBarItem[ OFFSET_TOOLBARITEM_TARGET ].Value <<= aToolBarItemNodePropValues[ OFFSET_TOOLBARITEM_TARGET ];
1464 aToolBarItem[ OFFSET_TOOLBARITEM_IMAGEIDENTIFIER ].Value <<= aImageId;
1465 aToolBarItem[ OFFSET_TOOLBARITEM_CONTEXT ].Value <<= aToolBarItemNodePropValues[ OFFSET_TOOLBARITEM_CONTEXT ];
1466 aToolBarItem[ OFFSET_TOOLBARITEM_CONTROLTYPE ].Value <<= aToolBarItemNodePropValues[ OFFSET_TOOLBARITEM_CONTROLTYPE ];
1468 // Configuration uses hyper for long. Therefore transform into sal_Int32
1469 sal_Int64 nValue( 0 );
1470 aToolBarItemNodePropValues[ OFFSET_TOOLBARITEM_WIDTH ] >>= nValue;
1471 aToolBarItem[ OFFSET_TOOLBARITEM_WIDTH ].Value <<= sal_Int32( nValue );
1473 bResult = sal_True;
1477 return bResult;
1480 //*****************************************************************************************************************
1481 // private method
1482 //*****************************************************************************************************************
1483 sal_Bool AddonsOptions_Impl::ReadSubMenuEntries( const Sequence< OUString >& aSubMenuNodeNames, Sequence< Sequence< PropertyValue > >& rSubMenuSeq )
1485 Sequence< PropertyValue > aMenuItem( PROPERTYCOUNT_MENUITEM );
1487 // Init the property value sequence
1488 aMenuItem[ OFFSET_MENUITEM_URL ].Name = PROPERTYNAME_URL;
1489 aMenuItem[ OFFSET_MENUITEM_TITLE ].Name = PROPERTYNAME_TITLE;
1490 aMenuItem[ OFFSET_MENUITEM_TARGET ].Name = PROPERTYNAME_TARGET;
1491 aMenuItem[ OFFSET_MENUITEM_IMAGEIDENTIFIER ].Name = PROPERTYNAME_IMAGEIDENTIFIER;
1492 aMenuItem[ OFFSET_MENUITEM_CONTEXT ].Name = PROPERTYNAME_CONTEXT;
1493 aMenuItem[ OFFSET_MENUITEM_SUBMENU ].Name = PROPERTYNAME_SUBMENU; // Submenu set!
1495 sal_uInt32 nIndex = 0;
1496 sal_uInt32 nCount = aSubMenuNodeNames.getLength();
1497 for ( sal_uInt32 n = 0; n < nCount; n++ )
1499 if ( ReadMenuItem( aSubMenuNodeNames[n], aMenuItem ))
1501 sal_uInt32 nSubMenuCount = rSubMenuSeq.getLength() + 1;
1502 rSubMenuSeq.realloc( nSubMenuCount );
1503 rSubMenuSeq[nIndex++] = aMenuItem;
1507 return sal_True;
1510 //*****************************************************************************************************************
1511 // private method
1512 //*****************************************************************************************************************
1513 sal_Bool AddonsOptions_Impl::HasAssociatedImages( const OUString& aURL )
1515 // FIXME: potentially this is not so useful in a world of delayed image loading
1516 ImageManager::const_iterator pIter = m_aImageManager.find( aURL );
1517 return ( pIter != m_aImageManager.end() );
1520 //*****************************************************************************************************************
1521 // private method
1522 //*****************************************************************************************************************
1523 void AddonsOptions_Impl::SubstituteVariables( OUString& aURL )
1525 if ( aURL.startsWith( EXPAND_PROTOCOL ) )
1527 // cut protocol
1528 OUString macro( aURL.copy( sizeof ( EXPAND_PROTOCOL ) -1 ) );
1529 // decode uric class chars
1530 macro = ::rtl::Uri::decode(
1531 macro, rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8 );
1532 // expand macro string
1533 aURL = m_xMacroExpander->expandMacros( macro );
1537 //*****************************************************************************************************************
1538 // private method
1539 //*****************************************************************************************************************
1540 Image AddonsOptions_Impl::ReadImageFromURL(const OUString& aImageURL)
1542 Image aImage;
1544 SvStream* pStream = UcbStreamHelper::CreateStream( aImageURL, STREAM_STD_READ );
1545 if ( pStream && ( pStream->GetErrorCode() == 0 ))
1547 // Use graphic class to also support more graphic formats (bmp,png,...)
1548 Graphic aGraphic;
1550 GraphicFilter& rGF = GraphicFilter::GetGraphicFilter();
1551 rGF.ImportGraphic( aGraphic, String(), *pStream, GRFILTER_FORMAT_DONTKNOW );
1553 BitmapEx aBitmapEx = aGraphic.GetBitmapEx();
1555 Size aBmpSize = aBitmapEx.GetSizePixel();
1556 if ( aBmpSize.Width() > 0 && aBmpSize.Height() > 0 )
1558 // Support non-transparent bitmaps to be downward compatible with OOo 1.1.x addons
1559 if( !aBitmapEx.IsTransparent() )
1560 aBitmapEx = BitmapEx( aBitmapEx.GetBitmap(), COL_LIGHTMAGENTA );
1562 aImage = Image(aBitmapEx);
1566 delete pStream;
1568 return aImage;
1571 //*****************************************************************************************************************
1572 // private method
1573 //*****************************************************************************************************************
1574 void AddonsOptions_Impl::ReadAndAssociateImages( const OUString& aURL, const OUString& aImageId )
1576 if ( aImageId.isEmpty() )
1577 return;
1579 ImageEntry aImageEntry;
1580 OUString aImageURL( aImageId );
1582 SubstituteVariables( aImageURL );
1584 // Loop to create the two possible image names and try to read the bitmap files
1585 static const char* aExtArray[] = { "_16", "_26" };
1586 for ( size_t i = 0; i < SAL_N_ELEMENTS(aExtArray); i++ )
1588 OUStringBuffer aFileURL( aImageURL );
1589 aFileURL.appendAscii( aExtArray[i] );
1590 aFileURL.appendAscii( ".bmp" );
1592 aImageEntry.addImage( !i ? IMGSIZE_SMALL : IMGSIZE_BIG,
1593 Image(), aFileURL.makeStringAndClear() );
1596 m_aImageManager.insert( ImageManager::value_type( aURL, aImageEntry ));
1599 //*****************************************************************************************************************
1600 // private method
1601 //*****************************************************************************************************************
1602 AddonsOptions_Impl::ImageEntry* AddonsOptions_Impl::ReadImageData( const OUString& aImagesNodeName )
1604 Sequence< OUString > aImageDataNodeNames = GetPropertyNamesImages( aImagesNodeName );
1605 Sequence< Any > aPropertyData;
1606 Sequence< sal_Int8 > aImageDataSeq;
1607 OUString aImageURL;
1609 ImageEntry* pEntry = NULL;
1611 // It is possible to use both forms (embedded image data and URLs to external bitmap files) at the
1612 // same time. Embedded image data has a higher priority.
1613 aPropertyData = GetProperties( aImageDataNodeNames );
1614 for ( int i = 0; i < PROPERTYCOUNT_IMAGES; i++ )
1616 if ( i < PROPERTYCOUNT_EMBEDDED_IMAGES )
1618 // Extract image data from the embedded hex binary sequence
1619 Image aImage;
1620 if (( aPropertyData[i] >>= aImageDataSeq ) &&
1621 aImageDataSeq.getLength() > 0 &&
1622 ( CreateImageFromSequence( aImage, aImageDataSeq ) ) )
1624 if ( !pEntry )
1625 pEntry = new ImageEntry;
1626 pEntry->addImage(i == OFFSET_IMAGES_SMALL ? IMGSIZE_SMALL : IMGSIZE_BIG, aImage, "");
1629 else
1631 if(!pEntry)
1632 pEntry = new ImageEntry();
1634 // Retrieve image data from a external bitmap file. Make sure that embedded image data
1635 // has a higher priority.
1636 aPropertyData[i] >>= aImageURL;
1638 SubstituteVariables( aImageURL );
1640 pEntry->addImage(i == OFFSET_IMAGES_SMALL ? IMGSIZE_SMALL : IMGSIZE_BIG,
1641 Image(), aImageURL);
1645 return pEntry;
1648 //*****************************************************************************************************************
1649 // private method
1650 //*****************************************************************************************************************
1651 sal_Bool AddonsOptions_Impl::CreateImageFromSequence( Image& rImage, Sequence< sal_Int8 >& rBitmapDataSeq ) const
1653 sal_Bool bResult = sal_False;
1655 if ( rBitmapDataSeq.getLength() > 0 )
1657 SvMemoryStream aMemStream( rBitmapDataSeq.getArray(), rBitmapDataSeq.getLength(), STREAM_STD_READ );
1658 BitmapEx aBitmapEx;
1660 aMemStream >> aBitmapEx;
1662 if( !aBitmapEx.IsTransparent() )
1664 // Support non-transparent bitmaps to be downward compatible with OOo 1.1.x addons
1665 aBitmapEx = BitmapEx( aBitmapEx.GetBitmap(), COL_LIGHTMAGENTA );
1668 rImage = Image( aBitmapEx );
1669 bResult = sal_True;
1672 return bResult;
1675 Sequence< OUString > AddonsOptions_Impl::GetPropertyNamesMenuItem( const OUString& aPropertyRootNode ) const
1677 Sequence< OUString > lResult( PROPERTYCOUNT_MENUITEM );
1679 // Create property names dependent from the root node name
1680 lResult[OFFSET_MENUITEM_URL] = OUString( aPropertyRootNode + m_aPropNames[ INDEX_URL ] );
1681 lResult[OFFSET_MENUITEM_TITLE] = OUString( aPropertyRootNode + m_aPropNames[ INDEX_TITLE ] );
1682 lResult[OFFSET_MENUITEM_IMAGEIDENTIFIER] = OUString( aPropertyRootNode + m_aPropNames[ INDEX_IMAGEIDENTIFIER ] );
1683 lResult[OFFSET_MENUITEM_TARGET] = OUString( aPropertyRootNode + m_aPropNames[ INDEX_TARGET ] );
1684 lResult[OFFSET_MENUITEM_CONTEXT] = OUString( aPropertyRootNode + m_aPropNames[ INDEX_CONTEXT ] );
1685 lResult[OFFSET_MENUITEM_SUBMENU] = OUString( aPropertyRootNode + m_aPropNames[ INDEX_SUBMENU ] );
1687 return lResult;
1690 //*****************************************************************************************************************
1691 // private method
1692 //*****************************************************************************************************************
1693 Sequence< OUString > AddonsOptions_Impl::GetPropertyNamesPopupMenu( const OUString& aPropertyRootNode ) const
1695 // The URL is automatically set and not read from the configuration.
1696 Sequence< OUString > lResult( PROPERTYCOUNT_POPUPMENU-1 );
1698 // Create property names dependent from the root node name
1699 lResult[OFFSET_POPUPMENU_TITLE] = OUString( aPropertyRootNode + m_aPropNames[ INDEX_TITLE ] );
1700 lResult[OFFSET_POPUPMENU_CONTEXT] = OUString( aPropertyRootNode + m_aPropNames[ INDEX_CONTEXT ] );
1701 lResult[OFFSET_POPUPMENU_SUBMENU] = OUString( aPropertyRootNode + m_aPropNames[ INDEX_SUBMENU ] );
1703 return lResult;
1706 //*****************************************************************************************************************
1707 // private method
1708 //*****************************************************************************************************************
1709 Sequence< OUString > AddonsOptions_Impl::GetPropertyNamesToolBarItem( const OUString& aPropertyRootNode ) const
1711 Sequence< OUString > lResult( PROPERTYCOUNT_TOOLBARITEM );
1713 // Create property names dependent from the root node name
1714 lResult[0] = OUString( aPropertyRootNode + m_aPropNames[ INDEX_URL ] );
1715 lResult[1] = OUString( aPropertyRootNode + m_aPropNames[ INDEX_TITLE ] );
1716 lResult[2] = OUString( aPropertyRootNode + m_aPropNames[ INDEX_IMAGEIDENTIFIER] );
1717 lResult[3] = OUString( aPropertyRootNode + m_aPropNames[ INDEX_TARGET ] );
1718 lResult[4] = OUString( aPropertyRootNode + m_aPropNames[ INDEX_CONTEXT ] );
1719 lResult[5] = OUString( aPropertyRootNode + m_aPropNames[ INDEX_CONTROLTYPE ] );
1720 lResult[6] = OUString( aPropertyRootNode + m_aPropNames[ INDEX_WIDTH ] );
1722 return lResult;
1725 Sequence< ::rtl::OUString > AddonsOptions_Impl::GetPropertyNamesStatusbarItem(
1726 const ::rtl::OUString& aPropertyRootNode ) const
1728 Sequence< ::rtl::OUString > lResult( PROPERTYCOUNT_STATUSBARITEM );
1730 lResult[0] = ::rtl::OUString( aPropertyRootNode + m_aPropNames[ INDEX_URL ] );
1731 lResult[1] = ::rtl::OUString( aPropertyRootNode + m_aPropNames[ INDEX_TITLE ] );
1732 lResult[2] = ::rtl::OUString( aPropertyRootNode + m_aPropNames[ INDEX_CONTEXT ] );
1733 lResult[3] = ::rtl::OUString( aPropertyRootNode + m_aPropNames[ INDEX_ALIGN ] );
1734 lResult[4] = ::rtl::OUString( aPropertyRootNode + m_aPropNames[ INDEX_AUTOSIZE ] );
1735 lResult[5] = ::rtl::OUString( aPropertyRootNode + m_aPropNames[ INDEX_OWNERDRAW ] );
1736 lResult[6] = ::rtl::OUString( aPropertyRootNode + m_aPropNames[ INDEX_WIDTH ] );
1738 return lResult;
1741 //*****************************************************************************************************************
1742 // private method
1743 //*****************************************************************************************************************
1744 Sequence< OUString > AddonsOptions_Impl::GetPropertyNamesImages( const OUString& aPropertyRootNode ) const
1746 Sequence< OUString > lResult( PROPERTYCOUNT_IMAGES );
1748 // Create property names dependent from the root node name
1749 lResult[0] = OUString( aPropertyRootNode + m_aPropImagesNames[ OFFSET_IMAGES_SMALL ] );
1750 lResult[1] = OUString( aPropertyRootNode + m_aPropImagesNames[ OFFSET_IMAGES_BIG ] );
1751 lResult[2] = OUString( aPropertyRootNode + m_aPropImagesNames[ OFFSET_IMAGES_SMALLHC ] );
1752 lResult[3] = OUString( aPropertyRootNode + m_aPropImagesNames[ OFFSET_IMAGES_BIGHC ] );
1753 lResult[4] = OUString( aPropertyRootNode + m_aPropImagesNames[ OFFSET_IMAGES_SMALL_URL ] );
1754 lResult[5] = OUString( aPropertyRootNode + m_aPropImagesNames[ OFFSET_IMAGES_BIG_URL ] );
1755 lResult[6] = OUString( aPropertyRootNode + m_aPropImagesNames[ OFFSET_IMAGES_SMALLHC_URL] );
1756 lResult[7] = OUString( aPropertyRootNode + m_aPropImagesNames[ OFFSET_IMAGES_BIGHC_URL ] );
1758 return lResult;
1761 //*****************************************************************************************************************
1762 // initialize static member
1763 // DON'T DO IT IN YOUR HEADER!
1764 // see definition for further information
1765 //*****************************************************************************************************************
1766 AddonsOptions_Impl* AddonsOptions::m_pDataContainer = NULL ;
1767 sal_Int32 AddonsOptions::m_nRefCount = 0 ;
1769 //*****************************************************************************************************************
1770 // constructor
1771 //*****************************************************************************************************************
1772 AddonsOptions::AddonsOptions()
1774 // Global access, must be guarded (multithreading!).
1775 MutexGuard aGuard( GetOwnStaticMutex() );
1776 // Increase ouer refcount ...
1777 ++m_nRefCount;
1778 // ... and initialize ouer data container only if it not already exist!
1779 if( m_pDataContainer == NULL )
1781 m_pDataContainer = new AddonsOptions_Impl;
1785 //*****************************************************************************************************************
1786 // destructor
1787 //*****************************************************************************************************************
1788 AddonsOptions::~AddonsOptions()
1790 // Global access, must be guarded (multithreading!)
1791 MutexGuard aGuard( GetOwnStaticMutex() );
1792 // Decrease ouer refcount.
1793 --m_nRefCount;
1794 // If last instance was deleted ...
1795 // we must destroy ouer static data container!
1796 if( m_nRefCount <= 0 )
1798 delete m_pDataContainer;
1799 m_pDataContainer = NULL;
1803 //*****************************************************************************************************************
1804 // public method
1805 //*****************************************************************************************************************
1806 sal_Bool AddonsOptions::HasAddonsMenu() const
1808 MutexGuard aGuard( GetOwnStaticMutex() );
1809 return m_pDataContainer->HasAddonsMenu();
1812 //*****************************************************************************************************************
1813 // public method
1814 //*****************************************************************************************************************
1816 sal_Int32 AddonsOptions::GetAddonsToolBarCount() const
1818 MutexGuard aGuard( GetOwnStaticMutex() );
1819 return m_pDataContainer->GetAddonsToolBarCount();
1822 //*****************************************************************************************************************
1823 // public method
1824 //*****************************************************************************************************************
1825 const Sequence< Sequence< PropertyValue > >& AddonsOptions::GetAddonsMenu() const
1827 MutexGuard aGuard( GetOwnStaticMutex() );
1828 return m_pDataContainer->GetAddonsMenu();
1831 //*****************************************************************************************************************
1832 // public method
1833 //*****************************************************************************************************************
1834 const Sequence< Sequence< PropertyValue > >& AddonsOptions::GetAddonsMenuBarPart() const
1836 MutexGuard aGuard( GetOwnStaticMutex() );
1837 return m_pDataContainer->GetAddonsMenuBarPart();
1840 //*****************************************************************************************************************
1841 // public method
1842 //*****************************************************************************************************************
1843 const Sequence< Sequence< PropertyValue > >& AddonsOptions::GetAddonsToolBarPart( sal_uInt32 nIndex ) const
1845 MutexGuard aGuard( GetOwnStaticMutex() );
1846 return m_pDataContainer->GetAddonsToolBarPart( nIndex );
1849 //*****************************************************************************************************************
1850 // public method
1851 //*****************************************************************************************************************
1852 const OUString AddonsOptions::GetAddonsToolbarResourceName( sal_uInt32 nIndex ) const
1854 MutexGuard aGuard( GetOwnStaticMutex() );
1855 return m_pDataContainer->GetAddonsToolbarResourceName( nIndex );
1858 //*****************************************************************************************************************
1859 // public method
1860 //*****************************************************************************************************************
1861 const Sequence< Sequence< PropertyValue > >& AddonsOptions::GetAddonsHelpMenu() const
1863 MutexGuard aGuard( GetOwnStaticMutex() );
1864 return m_pDataContainer->GetAddonsHelpMenu();
1867 //*****************************************************************************************************************
1868 // public method
1869 //*****************************************************************************************************************
1870 const MergeMenuInstructionContainer& AddonsOptions::GetMergeMenuInstructions() const
1872 MutexGuard aGuard( GetOwnStaticMutex() );
1873 return m_pDataContainer->GetMergeMenuInstructions();
1876 //*****************************************************************************************************************
1877 // public method
1878 //*****************************************************************************************************************
1879 bool AddonsOptions::GetMergeToolbarInstructions(
1880 const OUString& rToolbarName,
1881 MergeToolbarInstructionContainer& rToolbarInstructions ) const
1883 MutexGuard aGuard( GetOwnStaticMutex() );
1884 return m_pDataContainer->GetMergeToolbarInstructions(
1885 rToolbarName, rToolbarInstructions );
1888 const MergeStatusbarInstructionContainer& AddonsOptions::GetMergeStatusbarInstructions() const
1890 MutexGuard aGuard( GetOwnStaticMutex() );
1891 return m_pDataContainer->GetMergeStatusbarInstructions();
1894 //*****************************************************************************************************************
1895 // public method
1896 //*****************************************************************************************************************
1897 Image AddonsOptions::GetImageFromURL( const OUString& aURL, sal_Bool bBig, sal_Bool bNoScale ) const
1899 MutexGuard aGuard( GetOwnStaticMutex() );
1900 return m_pDataContainer->GetImageFromURL( aURL, bBig, bNoScale );
1903 //*****************************************************************************************************************
1904 // public method
1905 //*****************************************************************************************************************
1906 Image AddonsOptions::GetImageFromURL( const OUString& aURL, sal_Bool bBig ) const
1908 return GetImageFromURL( aURL, bBig, sal_False );
1911 //*****************************************************************************************************************
1912 // private method
1913 //*****************************************************************************************************************
1914 Mutex& AddonsOptions::GetOwnStaticMutex()
1916 // Initialize static mutex only for one time!
1917 static Mutex* pMutex = NULL;
1918 // If these method first called (Mutex not already exist!) ...
1919 if( pMutex == NULL )
1921 // ... we must create a new one. Protect follow code with the global mutex -
1922 // It must be - we create a static variable!
1923 MutexGuard aGuard( Mutex::getGlobalMutex() );
1924 // We must check our pointer again - because it can be that another instance of ouer class will be fastr then these!
1925 if( pMutex == NULL )
1927 // Create the new mutex and set it for return on static variable.
1928 static Mutex aMutex;
1929 pMutex = &aMutex;
1932 // Return new created or already existing mutex object.
1933 return *pMutex;
1936 //*****************************************************************************************************************
1937 // private method
1938 //*****************************************************************************************************************
1939 IMPL_STATIC_LINK_NOINSTANCE( AddonsOptions, Notify, void*, EMPTYARG )
1941 MutexGuard aGuard( GetOwnStaticMutex() );
1942 m_pDataContainer->ReadConfigurationData();
1943 return 0;
1948 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */