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