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