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