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