1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <framework/addonsoptions.hxx>
21 #include <unotools/configmgr.hxx>
22 #include <unotools/configitem.hxx>
23 #include <unotools/ucbstreamhelper.hxx>
24 #include <tools/stream.hxx>
25 #include <com/sun/star/uno/Any.hxx>
26 #include <com/sun/star/uno/Sequence.hxx>
27 #include <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>
36 #include <unordered_map>
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
;
49 #define ROOTNODE_ADDONMENU OUString("Office.Addons" )
50 #define PATHDELIMITER OUString("/" )
51 #define SEPARATOR_URL "private:separator"
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
60 #define IMAGES_NODENAME OUString("UserDefinedImages" )
62 // The following order is mandatory. Please add properties at the end!
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
72 #define INDEX_AUTOSIZE 9
73 #define INDEX_OWNERDRAW 10
74 #define PROPERTYCOUNT_INDEX 11
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
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
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
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
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
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
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
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
149 // private declarations!
151 /*-****************************************************************************************************************
152 @descr struct to hold information about one menu entry.
153 ****************************************************************************************************************-*/
158 class AddonsOptions_Impl
: public ConfigItem
165 // constructor / destructor
167 AddonsOptions_Impl();
168 virtual ~AddonsOptions_Impl();
170 // overridden methods of baseclass
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
178 @seealso baseclass ConfigItem
180 @param "lPropertyNames" is the list of properties which should be updated.
181 *//*-*****************************************************************************************************/
183 virtual void Notify( const Sequence
< OUString
>& lPropertyNames
) SAL_OVERRIDE
;
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 *//*-*****************************************************************************************************/
193 bool HasAddonsMenu () const;
194 sal_Int32
GetAddonsToolBarCount() const;
195 const Sequence
< Sequence
< PropertyValue
> >& GetAddonsMenu () const { return m_aCachedMenuProperties
;}
196 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 const Sequence
< Sequence
< PropertyValue
> >& GetAddonsHelpMenu () const { return m_aCachedHelpMenuProperties
;}
200 Image
GetImageFromURL( const OUString
& aURL
, bool bBig
, bool bNoScale
);
201 const MergeMenuInstructionContainer
& GetMergeMenuInstructions() const { return m_aCachedMergeMenuInsContainer
;}
202 bool GetMergeToolbarInstructions( const OUString
& rToolbarName
, MergeToolbarInstructionContainer
& rToolbarInstructions
) const;
203 const MergeStatusbarInstructionContainer
& GetMergeStatusbarInstructions() const { return m_aCachedStatusbarMergingInstructions
;}
204 void ReadConfigurationData();
216 Image aScaled
; ///< cached scaled image
217 Image aImage
; ///< original un-scaled image
218 OUString aURL
; ///< URL in case it is not loaded yet
223 // if the image is set, it was embedded in some way,
224 // otherwise we use the associated URL to load on demand
226 // accessed in this order
227 OneImageEntry aSizeEntry
[2];
229 void addImage(ImageSize eSize
, const Image
&rImage
, const OUString
&rURL
);
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
;
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 *//*-*****************************************************************************************************/
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
);
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
);
269 bool ReadSubMenuEntries( const Sequence
< OUString
>& aSubMenuNodeNames
, Sequence
< Sequence
< PropertyValue
> >& rSubMenu
);
270 OUString
GeneratePrefixURL();
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;
279 virtual void ImplCommit() SAL_OVERRIDE
;
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
];
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
;
305 void AddonsOptions_Impl::ImageEntry::addImage(ImageSize eSize
,
307 const OUString
&rURL
)
309 aSizeEntry
[(int)eSize
].aImage
= rImage
;
310 aSizeEntry
[(int)eSize
].aURL
= rURL
;
315 AddonsOptions_Impl::AddonsOptions_Impl()
316 // Init baseclasses first
317 : ConfigItem( ROOTNODE_ADDONMENU
),
318 m_nRootAddonPopupMenuId( 0 ),
319 m_aPathDelimiter( PATHDELIMITER
),
320 m_aRootAddonPopupMenuURLPrexfix( ADDONSPOPUPMENU_URL_PREFIX_STR
)
322 // initialize array with fixed property names
323 m_aPropNames
[ INDEX_URL
] = PROPERTYNAME_URL
;
324 m_aPropNames
[ INDEX_TITLE
] = PROPERTYNAME_TITLE
;
325 m_aPropNames
[ INDEX_TARGET
] = PROPERTYNAME_TARGET
;
326 m_aPropNames
[ INDEX_IMAGEIDENTIFIER
] = PROPERTYNAME_IMAGEIDENTIFIER
;
327 m_aPropNames
[ INDEX_CONTEXT
] = PROPERTYNAME_CONTEXT
;
328 m_aPropNames
[ INDEX_SUBMENU
] = PROPERTYNAME_SUBMENU
; // Submenu set!
329 m_aPropNames
[ INDEX_CONTROLTYPE
] = "ControlType";
330 m_aPropNames
[ INDEX_WIDTH
] = "Width";
331 m_aPropNames
[ INDEX_ALIGN
] = "Alignment";
332 m_aPropNames
[ INDEX_AUTOSIZE
] = "AutoSize";
333 m_aPropNames
[ INDEX_OWNERDRAW
] = "OwnerDraw";
335 // initialize array with fixed images property names
336 m_aPropImagesNames
[ OFFSET_IMAGES_SMALL
] = "ImageSmall";
337 m_aPropImagesNames
[ OFFSET_IMAGES_BIG
] = "ImageBig";
338 m_aPropImagesNames
[ OFFSET_IMAGES_SMALLHC
] = "ImageSmallHC";
339 m_aPropImagesNames
[ OFFSET_IMAGES_BIGHC
] = "ImageBigHC";
340 m_aPropImagesNames
[ OFFSET_IMAGES_SMALL_URL
] = "ImageSmallURL";
341 m_aPropImagesNames
[ OFFSET_IMAGES_BIG_URL
] = "ImageBigURL";
342 m_aPropImagesNames
[ OFFSET_IMAGES_SMALLHC_URL
] = "ImageSmallHCURL";
343 m_aPropImagesNames
[ OFFSET_IMAGES_BIGHC_URL
] = "ImageBigHCURL";
345 // initialize array with fixed merge menu property names
346 m_aPropMergeMenuNames
[ OFFSET_MERGEMENU_MERGEPOINT
] = "MergePoint";
347 m_aPropMergeMenuNames
[ OFFSET_MERGEMENU_MERGECOMMAND
] = "MergeCommand";
348 m_aPropMergeMenuNames
[ OFFSET_MERGEMENU_MERGECOMMANDPARAMETER
] = "MergeCommandParameter";
349 m_aPropMergeMenuNames
[ OFFSET_MERGEMENU_MERGEFALLBACK
] = "MergeFallback";
350 m_aPropMergeMenuNames
[ OFFSET_MERGEMENU_MERGECONTEXT
] = "MergeContext";
351 m_aPropMergeMenuNames
[ OFFSET_MERGEMENU_MENUITEMS
] = "MenuItems";
353 m_aPropMergeToolbarNames
[ OFFSET_MERGETOOLBAR_TOOLBAR
] = "MergeToolBar";
354 m_aPropMergeToolbarNames
[ OFFSET_MERGETOOLBAR_MERGEPOINT
] = "MergePoint";
355 m_aPropMergeToolbarNames
[ OFFSET_MERGETOOLBAR_MERGECOMMAND
] = "MergeCommand";
356 m_aPropMergeToolbarNames
[ OFFSET_MERGETOOLBAR_MERGECOMMANDPARAMETER
] = "MergeCommandParameter";
357 m_aPropMergeToolbarNames
[ OFFSET_MERGETOOLBAR_MERGEFALLBACK
] = "MergeFallback";
358 m_aPropMergeToolbarNames
[ OFFSET_MERGETOOLBAR_MERGECONTEXT
] = "MergeContext";
359 m_aPropMergeToolbarNames
[ OFFSET_MERGETOOLBAR_TOOLBARITEMS
] = "ToolBarItems";
361 m_aPropMergeStatusbarNames
[ OFFSET_MERGESTATUSBAR_MERGEPOINT
] = "MergePoint";
362 m_aPropMergeStatusbarNames
[ OFFSET_MERGESTATUSBAR_MERGECOMMAND
] = "MergeCommand";
363 m_aPropMergeStatusbarNames
[ OFFSET_MERGESTATUSBAR_MERGECOMMANDPARAMETER
] = "MergeCommandParameter";
364 m_aPropMergeStatusbarNames
[ OFFSET_MERGESTATUSBAR_MERGEFALLBACK
] = "MergeFallback";
365 m_aPropMergeStatusbarNames
[ OFFSET_MERGESTATUSBAR_MERGECONTEXT
] = "MergeContext";
366 m_aPropMergeStatusbarNames
[ OFFSET_MERGESTATUSBAR_STATUSBARITEMS
] = "StatusBarItems";
368 ReadConfigurationData();
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 Sequence
< OUString
> aNotifySeq( 1 );
373 aNotifySeq
[0] = "AddonUI";
374 EnableNotification( aNotifySeq
);
379 AddonsOptions_Impl::~AddonsOptions_Impl()
381 assert(!IsModified()); // should have been committed
384 void AddonsOptions_Impl::ReadConfigurationData()
386 // reset members to be read again from configuration
387 m_aCachedMenuProperties
= Sequence
< Sequence
< PropertyValue
> >();
388 m_aCachedMenuBarPartProperties
= Sequence
< Sequence
< PropertyValue
> >();
389 m_aCachedToolBarPartProperties
= AddonToolBars();
390 m_aCachedHelpMenuProperties
= Sequence
< Sequence
< PropertyValue
> >();
391 m_aCachedToolBarPartResourceNames
.clear();
392 m_aImageManager
= ImageManager();
394 ReadAddonMenuSet( m_aCachedMenuProperties
);
395 ReadOfficeMenuBarSet( m_aCachedMenuBarPartProperties
);
396 ReadOfficeToolBarSet( m_aCachedToolBarPartProperties
, m_aCachedToolBarPartResourceNames
);
398 ReadOfficeHelpSet( m_aCachedHelpMenuProperties
);
399 ReadImages( m_aImageManager
);
401 m_aCachedMergeMenuInsContainer
.clear();
402 m_aCachedToolbarMergingInstructions
.clear();
403 m_aCachedStatusbarMergingInstructions
.clear();
405 ReadMenuMergeInstructions( m_aCachedMergeMenuInsContainer
);
406 ReadToolbarMergeInstructions( m_aCachedToolbarMergingInstructions
);
407 ReadStatusbarMergeInstructions( m_aCachedStatusbarMergingInstructions
);
412 void AddonsOptions_Impl::Notify( const Sequence
< OUString
>& /*lPropertyNames*/ )
414 Application::PostUserEvent( LINK( 0, AddonsOptions
, Notify
) );
419 void AddonsOptions_Impl::ImplCommit()
421 SAL_WARN("framework", "AddonsOptions_Impl::ImplCommit(): Not implemented yet!");
426 bool AddonsOptions_Impl::HasAddonsMenu() const
428 return ( m_aCachedMenuProperties
.getLength() > 0 );
433 sal_Int32
AddonsOptions_Impl::GetAddonsToolBarCount() const
435 return m_aCachedToolBarPartProperties
.size();
440 const Sequence
< Sequence
< PropertyValue
> >& AddonsOptions_Impl::GetAddonsToolBarPart( sal_uInt32 nIndex
) const
442 if ( /*nIndex >= 0 &&*/ nIndex
< m_aCachedToolBarPartProperties
.size() )
443 return m_aCachedToolBarPartProperties
[nIndex
];
445 return m_aEmptyAddonToolBar
;
450 const OUString
AddonsOptions_Impl::GetAddonsToolbarResourceName( sal_uInt32 nIndex
) const
452 if ( nIndex
< m_aCachedToolBarPartResourceNames
.size() )
453 return m_aCachedToolBarPartResourceNames
[nIndex
];
460 bool AddonsOptions_Impl::GetMergeToolbarInstructions(
461 const OUString
& rToolbarName
,
462 MergeToolbarInstructionContainer
& rToolbarInstructions
) const
464 ToolbarMergingInstructions::const_iterator pIter
= m_aCachedToolbarMergingInstructions
.find( rToolbarName
);
465 if ( pIter
!= m_aCachedToolbarMergingInstructions
.end() )
467 rToolbarInstructions
= pIter
->second
;
477 static Image
ScaleImage( const Image
&rImage
, bool bBig
)
479 Size aSize
= ToolBox::GetDefaultImageSize(bBig
);
480 BitmapEx
aScaleBmp(rImage
.GetBitmapEx());
481 SAL_INFO("fwk", "Addons: expensive scale image from "
482 << aScaleBmp
.GetSizePixel() << " to " << aSize
);
483 aScaleBmp
.Scale(aSize
, BmpScaleFlag::BestQuality
);
484 return Image(aScaleBmp
);
487 Image
AddonsOptions_Impl::GetImageFromURL( const OUString
& aURL
, bool bBig
, bool bNoScale
)
491 SAL_INFO("fwk", "Expensive: Addons GetImageFromURL " << aURL
<<
492 " big " << (bBig
?"big":"litte") <<
493 " scale " << (bNoScale
? "noscale" : "scale"));
495 ImageManager::iterator pIter
= m_aImageManager
.find(aURL
);
496 if ( pIter
!= m_aImageManager
.end() )
498 ImageSize eSize
= bBig
? IMGSIZE_BIG
: IMGSIZE_SMALL
;
499 int nIdx
= (int)eSize
;
500 int nOtherIdx
= nIdx
? 0 : 1;
502 OneImageEntry
& rSizeEntry
= pIter
->second
.aSizeEntry
[nIdx
];
503 OneImageEntry
& rOtherEntry
= pIter
->second
.aSizeEntry
[nOtherIdx
];
504 // actually read the image ...
505 if (!rSizeEntry
.aImage
)
506 rSizeEntry
.aImage
= ReadImageFromURL(rSizeEntry
.aURL
);
508 if (!rSizeEntry
.aImage
)
509 { // try the other size and scale it
510 aImage
= ScaleImage(ReadImageFromURL(rOtherEntry
.aURL
), bBig
);
511 rSizeEntry
.aImage
= aImage
;
512 if (!rSizeEntry
.aImage
)
513 SAL_WARN("fwk", "failed to load addons image " << aURL
);
516 // FIXME: bNoScale is not terribly meaningful or useful
518 if (!aImage
&& bNoScale
)
519 aImage
= rSizeEntry
.aImage
;
521 if (!aImage
&& !!rSizeEntry
.aScaled
)
522 aImage
= rSizeEntry
.aScaled
;
524 else // scale to the correct size for the theme / toolbox
526 aImage
= rSizeEntry
.aImage
;
527 if (!aImage
) // use and scale the other if one size is missing
528 aImage
= rOtherEntry
.aImage
;
530 aImage
= ScaleImage(aImage
, bBig
);
531 rSizeEntry
.aScaled
= aImage
; // cache for next time
538 bool AddonsOptions_Impl::ReadAddonMenuSet( Sequence
< Sequence
< PropertyValue
> >& rAddonMenuSeq
)
540 // Read the AddonMenu set and fill property sequences
541 OUString
aAddonMenuNodeName( "AddonUI/AddonMenu" );
542 Sequence
< OUString
> aAddonMenuNodeSeq
= GetNodeNames( aAddonMenuNodeName
);
543 OUString
aAddonMenuItemNode( aAddonMenuNodeName
+ m_aPathDelimiter
);
545 sal_uInt32 nCount
= aAddonMenuNodeSeq
.getLength();
546 sal_uInt32 nIndex
= 0;
547 Sequence
< PropertyValue
> aMenuItem( PROPERTYCOUNT_MENUITEM
);
549 // Init the property value sequence
550 aMenuItem
[ OFFSET_MENUITEM_URL
].Name
= m_aPropNames
[ INDEX_URL
];
551 aMenuItem
[ OFFSET_MENUITEM_TITLE
].Name
= m_aPropNames
[ INDEX_TITLE
];
552 aMenuItem
[ OFFSET_MENUITEM_TARGET
].Name
= m_aPropNames
[ INDEX_TARGET
];
553 aMenuItem
[ OFFSET_MENUITEM_IMAGEIDENTIFIER
].Name
= m_aPropNames
[ INDEX_IMAGEIDENTIFIER
];
554 aMenuItem
[ OFFSET_MENUITEM_CONTEXT
].Name
= m_aPropNames
[ INDEX_CONTEXT
];
555 aMenuItem
[ OFFSET_MENUITEM_SUBMENU
].Name
= m_aPropNames
[ INDEX_SUBMENU
]; // Submenu set!
557 for ( sal_uInt32 n
= 0; n
< nCount
; n
++ )
559 OUString
aRootMenuItemNode( aAddonMenuItemNode
+ aAddonMenuNodeSeq
[n
] );
562 if ( ReadMenuItem( aRootMenuItemNode
, aMenuItem
) )
564 // Successfully read a menu item, append to our list
565 sal_uInt32 nMenuItemCount
= rAddonMenuSeq
.getLength() + 1;
566 rAddonMenuSeq
.realloc( nMenuItemCount
);
567 rAddonMenuSeq
[nIndex
++] = aMenuItem
;
571 return ( rAddonMenuSeq
.getLength() > 0 );
574 bool AddonsOptions_Impl::ReadOfficeHelpSet( Sequence
< Sequence
< PropertyValue
> >& rAddonOfficeHelpMenuSeq
)
576 // Read the AddonMenu set and fill property sequences
577 OUString
aAddonHelpMenuNodeName( "AddonUI/OfficeHelp" );
578 Sequence
< OUString
> aAddonHelpMenuNodeSeq
= GetNodeNames( aAddonHelpMenuNodeName
);
579 OUString
aAddonHelpMenuItemNode( aAddonHelpMenuNodeName
+ m_aPathDelimiter
);
581 sal_uInt32 nCount
= aAddonHelpMenuNodeSeq
.getLength();
582 sal_uInt32 nIndex
= 0;
583 Sequence
< PropertyValue
> aMenuItem( PROPERTYCOUNT_MENUITEM
);
585 // Init the property value sequence
586 aMenuItem
[ OFFSET_MENUITEM_URL
].Name
= m_aPropNames
[ INDEX_URL
];
587 aMenuItem
[ OFFSET_MENUITEM_TITLE
].Name
= m_aPropNames
[ INDEX_TITLE
];
588 aMenuItem
[ OFFSET_MENUITEM_TARGET
].Name
= m_aPropNames
[ INDEX_TARGET
];
589 aMenuItem
[ OFFSET_MENUITEM_IMAGEIDENTIFIER
].Name
= m_aPropNames
[ INDEX_IMAGEIDENTIFIER
];
590 aMenuItem
[ OFFSET_MENUITEM_CONTEXT
].Name
= m_aPropNames
[ INDEX_CONTEXT
];
591 aMenuItem
[ OFFSET_MENUITEM_SUBMENU
].Name
= m_aPropNames
[ INDEX_SUBMENU
]; // Submenu set!
593 for ( sal_uInt32 n
= 0; n
< nCount
; n
++ )
595 OUString
aRootMenuItemNode( aAddonHelpMenuItemNode
+ aAddonHelpMenuNodeSeq
[n
] );
598 if ( ReadMenuItem( aRootMenuItemNode
, aMenuItem
, true ) )
600 // Successfully read a menu item, append to our list
601 sal_uInt32 nMenuItemCount
= rAddonOfficeHelpMenuSeq
.getLength() + 1;
602 rAddonOfficeHelpMenuSeq
.realloc( nMenuItemCount
);
603 rAddonOfficeHelpMenuSeq
[nIndex
++] = aMenuItem
;
607 return ( rAddonOfficeHelpMenuSeq
.getLength() > 0 );
610 bool AddonsOptions_Impl::ReadOfficeMenuBarSet( Sequence
< Sequence
< PropertyValue
> >& rAddonOfficeMenuBarSeq
)
612 // Read the OfficeMenuBar set and fill property sequences
613 OUString
aAddonMenuBarNodeName( "AddonUI/OfficeMenuBar" );
614 Sequence
< OUString
> aAddonMenuBarNodeSeq
= GetNodeNames( aAddonMenuBarNodeName
);
615 OUString
aAddonMenuBarNode( aAddonMenuBarNodeName
+ m_aPathDelimiter
);
617 sal_uInt32 nCount
= aAddonMenuBarNodeSeq
.getLength();
618 sal_uInt32 nIndex
= 0;
619 Sequence
< PropertyValue
> aPopupMenu( PROPERTYCOUNT_POPUPMENU
);
621 // Init the property value sequence
622 aPopupMenu
[ OFFSET_POPUPMENU_TITLE
].Name
= m_aPropNames
[ INDEX_TITLE
];
623 aPopupMenu
[ OFFSET_POPUPMENU_CONTEXT
].Name
= m_aPropNames
[ INDEX_CONTEXT
];
624 aPopupMenu
[ OFFSET_POPUPMENU_SUBMENU
].Name
= m_aPropNames
[ INDEX_SUBMENU
];
625 aPopupMenu
[ OFFSET_POPUPMENU_URL
].Name
= m_aPropNames
[ INDEX_URL
];
627 StringToIndexMap aTitleToIndexMap
;
629 for ( sal_uInt32 n
= 0; n
< nCount
; n
++ )
631 OUString
aPopupMenuNode( aAddonMenuBarNode
+ aAddonMenuBarNodeSeq
[n
] );
634 if ( ReadPopupMenu( aPopupMenuNode
, aPopupMenu
) )
636 // Successfully read a popup menu, append to our list
637 OUString aPopupTitle
;
638 if ( aPopupMenu
[OFFSET_POPUPMENU_TITLE
].Value
>>= aPopupTitle
)
640 StringToIndexMap::const_iterator pIter
= aTitleToIndexMap
.find( aPopupTitle
);
641 if ( pIter
!= aTitleToIndexMap
.end() )
643 // title already there => concat both popup menus
644 Sequence
< PropertyValue
>& rOldPopupMenu
= rAddonOfficeMenuBarSeq
[pIter
->second
];
645 AppendPopupMenu( rOldPopupMenu
, aPopupMenu
);
650 sal_uInt32 nMenuItemCount
= rAddonOfficeMenuBarSeq
.getLength() + 1;
651 rAddonOfficeMenuBarSeq
.realloc( nMenuItemCount
);
652 rAddonOfficeMenuBarSeq
[nIndex
] = aPopupMenu
;
653 aTitleToIndexMap
.insert( StringToIndexMap::value_type( aPopupTitle
, nIndex
));
660 return ( rAddonOfficeMenuBarSeq
.getLength() > 0 );
663 bool AddonsOptions_Impl::ReadOfficeToolBarSet( AddonToolBars
& rAddonOfficeToolBars
, std::vector
< OUString
>& rAddonOfficeToolBarResNames
)
665 // Read the OfficeToolBar set and fill property sequences
666 OUString
aAddonToolBarNodeName( "AddonUI/OfficeToolBar" );
667 Sequence
< OUString
> aAddonToolBarNodeSeq
= GetNodeNames( aAddonToolBarNodeName
);
668 OUString
aAddonToolBarNode( aAddonToolBarNodeName
+ m_aPathDelimiter
);
670 sal_uInt32 nCount
= aAddonToolBarNodeSeq
.getLength();
672 for ( sal_uInt32 n
= 0; n
< nCount
; n
++ )
674 OUString
aToolBarItemNode( aAddonToolBarNode
+ aAddonToolBarNodeSeq
[n
] );
675 rAddonOfficeToolBarResNames
.push_back( aAddonToolBarNodeSeq
[n
] );
676 rAddonOfficeToolBars
.push_back( m_aEmptyAddonToolBar
);
677 ReadToolBarItemSet( aToolBarItemNode
, rAddonOfficeToolBars
[n
] );
680 return ( !rAddonOfficeToolBars
.empty() );
683 bool AddonsOptions_Impl::ReadToolBarItemSet( const OUString
& rToolBarItemSetNodeName
, Sequence
< Sequence
< PropertyValue
> >& rAddonOfficeToolBarSeq
)
685 sal_uInt32 nToolBarItemCount
= rAddonOfficeToolBarSeq
.getLength();
686 OUString
aAddonToolBarItemSetNode( rToolBarItemSetNodeName
+ m_aPathDelimiter
);
687 Sequence
< OUString
> aAddonToolBarItemSetNodeSeq
= GetNodeNames( rToolBarItemSetNodeName
);
688 Sequence
< PropertyValue
> aToolBarItem( PROPERTYCOUNT_TOOLBARITEM
);
690 // Init the property value sequence
691 aToolBarItem
[ OFFSET_TOOLBARITEM_URL
].Name
= m_aPropNames
[ INDEX_URL
];
692 aToolBarItem
[ OFFSET_TOOLBARITEM_TITLE
].Name
= m_aPropNames
[ INDEX_TITLE
];
693 aToolBarItem
[ OFFSET_TOOLBARITEM_IMAGEIDENTIFIER
].Name
= m_aPropNames
[ INDEX_IMAGEIDENTIFIER
];
694 aToolBarItem
[ OFFSET_TOOLBARITEM_TARGET
].Name
= m_aPropNames
[ INDEX_TARGET
];
695 aToolBarItem
[ OFFSET_TOOLBARITEM_CONTEXT
].Name
= m_aPropNames
[ INDEX_CONTEXT
];
696 aToolBarItem
[ OFFSET_TOOLBARITEM_CONTROLTYPE
].Name
= m_aPropNames
[ INDEX_CONTROLTYPE
];
697 aToolBarItem
[ OFFSET_TOOLBARITEM_WIDTH
].Name
= m_aPropNames
[ INDEX_WIDTH
];
699 sal_uInt32 nCount
= aAddonToolBarItemSetNodeSeq
.getLength();
700 for ( sal_uInt32 n
= 0; n
< nCount
; n
++ )
702 OUString
aToolBarItemNode( aAddonToolBarItemSetNode
+ aAddonToolBarItemSetNodeSeq
[n
] );
704 // Read the ToolBarItem
705 if ( ReadToolBarItem( aToolBarItemNode
, aToolBarItem
) )
707 // Successfully read a toolbar item, append to our list
708 sal_uInt32 nAddonCount
= rAddonOfficeToolBarSeq
.getLength();
709 rAddonOfficeToolBarSeq
.realloc( nAddonCount
+1 );
710 rAddonOfficeToolBarSeq
[nAddonCount
] = aToolBarItem
;
714 return ( (sal_uInt32
)rAddonOfficeToolBarSeq
.getLength() > nToolBarItemCount
);
717 void AddonsOptions_Impl::ReadImages( ImageManager
& aImageManager
)
719 // Read the user-defined Images set and fill image manager
720 OUString
aAddonImagesNodeName( "AddonUI/Images" );
721 Sequence
< OUString
> aAddonImagesNodeSeq
= GetNodeNames( aAddonImagesNodeName
);
722 OUString
aAddonImagesNode( aAddonImagesNodeName
+ m_aPathDelimiter
);
724 sal_uInt32 nCount
= aAddonImagesNodeSeq
.getLength();
726 // Init the property value sequence
727 Sequence
< OUString
> aAddonImageItemNodePropNames( 1 );
730 for ( sal_uInt32 n
= 0; n
< nCount
; n
++ )
732 OUString
aImagesItemNode( aAddonImagesNode
+ aAddonImagesNodeSeq
[n
] );
734 // Create sequence for data access
735 OUStringBuffer
aBuffer( aImagesItemNode
);
736 aBuffer
.append( m_aPathDelimiter
);
737 aBuffer
.append( m_aPropNames
[ OFFSET_MENUITEM_URL
] );
738 aAddonImageItemNodePropNames
[0] = aBuffer
.makeStringAndClear();
740 Sequence
< Any
> aAddonImageItemNodeValues
= GetProperties( aAddonImageItemNodePropNames
);
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 if (( aAddonImageItemNodeValues
[0] >>= aURL
) &&
746 !HasAssociatedImages( aURL
))
748 OUStringBuffer
aBuf( aImagesItemNode
);
749 aBuf
.append( m_aPathDelimiter
);
750 aBuf
.append( IMAGES_NODENAME
);
751 aBuf
.append( m_aPathDelimiter
);
752 OUString aImagesUserDefinedItemNode
= aBuf
.makeStringAndClear();
754 // Read a user-defined images data
755 ImageEntry
* pImageEntry
= ReadImageData( aImagesUserDefinedItemNode
);
758 // Successfully read a user-defined images item, put it into our image manager
759 aImageManager
.insert( ImageManager::value_type( aURL
, *pImageEntry
));
760 delete pImageEntry
; // We have the ownership of the pointer
766 OUString
AddonsOptions_Impl::GeneratePrefixURL()
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 OUString aPopupMenuURL
;
771 OUStringBuffer
aBuf( m_aRootAddonPopupMenuURLPrexfix
.getLength() + 3 );
772 aBuf
.append( m_aRootAddonPopupMenuURLPrexfix
);
773 aBuf
.append( OUString::number( ++m_nRootAddonPopupMenuId
));
774 aPopupMenuURL
= aBuf
.makeStringAndClear();
775 return aPopupMenuURL
;
778 bool AddonsOptions_Impl::ReadMenuMergeInstructions( MergeMenuInstructionContainer
& aContainer
)
780 const OUString
aMenuMergeRootName( "AddonUI/OfficeMenuBarMerging/" );
782 Sequence
< OUString
> aAddonMergeNodesSeq
= GetNodeNames( aMenuMergeRootName
);
783 OUString
aAddonMergeNode( aMenuMergeRootName
);
785 sal_uInt32 nCount
= aAddonMergeNodesSeq
.getLength();
787 // Init the property value sequence
788 Sequence
< OUString
> aNodePropNames( 5 );
790 for ( sal_uInt32 i
= 0; i
< nCount
; i
++ )
792 OUString
aMergeAddonInstructions( aAddonMergeNode
+ aAddonMergeNodesSeq
[i
] );
794 Sequence
< OUString
> aAddonInstMergeNodesSeq
= GetNodeNames( aMergeAddonInstructions
);
795 sal_uInt32 nCountAddons
= aAddonInstMergeNodesSeq
.getLength();
797 for ( sal_uInt32 j
= 0; j
< nCountAddons
; j
++ )
799 OUStringBuffer
aMergeAddonInstructionBase( aMergeAddonInstructions
);
800 aMergeAddonInstructionBase
.append( m_aPathDelimiter
);
801 aMergeAddonInstructionBase
.append( aAddonInstMergeNodesSeq
[j
] );
802 aMergeAddonInstructionBase
.append( m_aPathDelimiter
);
804 // Create sequence for data access
805 OUStringBuffer
aBuffer( aMergeAddonInstructionBase
);
806 aBuffer
.append( m_aPropMergeMenuNames
[ OFFSET_MERGEMENU_MERGEPOINT
] );
807 aNodePropNames
[0] = aBuffer
.makeStringAndClear();
809 aBuffer
= aMergeAddonInstructionBase
;
810 aBuffer
.append( m_aPropMergeMenuNames
[ OFFSET_MERGEMENU_MERGECOMMAND
] );
811 aNodePropNames
[1] = aBuffer
.makeStringAndClear();
813 aBuffer
= aMergeAddonInstructionBase
;
814 aBuffer
.append( m_aPropMergeMenuNames
[ OFFSET_MERGEMENU_MERGECOMMANDPARAMETER
] );
815 aNodePropNames
[2] = aBuffer
.makeStringAndClear();
817 aBuffer
= aMergeAddonInstructionBase
;
818 aBuffer
.append( m_aPropMergeMenuNames
[ OFFSET_MERGEMENU_MERGEFALLBACK
] );
819 aNodePropNames
[3] = aBuffer
.makeStringAndClear();
821 aBuffer
= aMergeAddonInstructionBase
;
822 aBuffer
.append( m_aPropMergeMenuNames
[ OFFSET_MERGEMENU_MERGECONTEXT
] );
823 aNodePropNames
[4] = aBuffer
.makeStringAndClear();
825 Sequence
< Any
> aNodePropValues
= GetProperties( aNodePropNames
);
827 MergeMenuInstruction aMergeMenuInstruction
;
828 aNodePropValues
[0] >>= aMergeMenuInstruction
.aMergePoint
;
829 aNodePropValues
[1] >>= aMergeMenuInstruction
.aMergeCommand
;
830 aNodePropValues
[2] >>= aMergeMenuInstruction
.aMergeCommandParameter
;
831 aNodePropValues
[3] >>= aMergeMenuInstruction
.aMergeFallback
;
832 aNodePropValues
[4] >>= aMergeMenuInstruction
.aMergeContext
;
834 OUString aMergeMenuBase
= aMergeAddonInstructionBase
.makeStringAndClear();
835 ReadMergeMenuData( aMergeMenuBase
, aMergeMenuInstruction
.aMergeMenu
);
837 aContainer
.push_back( aMergeMenuInstruction
);
844 bool AddonsOptions_Impl::ReadMergeMenuData( const OUString
& aMergeAddonInstructionBase
, Sequence
< Sequence
< PropertyValue
> >& rMergeMenu
)
846 OUString
aMergeMenuBaseNode( aMergeAddonInstructionBase
+m_aPropMergeMenuNames
[ OFFSET_MERGEMENU_MENUITEMS
] );
848 Sequence
< OUString
> aSubMenuNodeNames
= GetNodeNames( aMergeMenuBaseNode
);
849 aMergeMenuBaseNode
+= m_aPathDelimiter
;
851 // extend the node names to have full path strings
852 for ( sal_uInt32 i
= 0; i
< (sal_uInt32
)aSubMenuNodeNames
.getLength(); i
++ )
853 aSubMenuNodeNames
[i
] = aMergeMenuBaseNode
+ aSubMenuNodeNames
[i
];
855 return ReadSubMenuEntries( aSubMenuNodeNames
, rMergeMenu
);
858 bool AddonsOptions_Impl::ReadToolbarMergeInstructions( ToolbarMergingInstructions
& rCachedToolbarMergingInstructions
)
860 const OUString
aToolbarMergeRootName( "AddonUI/OfficeToolbarMerging/" );
862 Sequence
< OUString
> aAddonMergeNodesSeq
= GetNodeNames( aToolbarMergeRootName
);
863 OUString
aAddonMergeNode( aToolbarMergeRootName
);
865 sal_uInt32 nCount
= aAddonMergeNodesSeq
.getLength();
867 // Init the property value sequence
868 Sequence
< OUString
> aNodePropNames( 6 );
870 for ( sal_uInt32 i
= 0; i
< nCount
; i
++ )
872 OUString
aMergeAddonInstructions( aAddonMergeNode
+ aAddonMergeNodesSeq
[i
] );
874 Sequence
< OUString
> aAddonInstMergeNodesSeq
= GetNodeNames( aMergeAddonInstructions
);
875 sal_uInt32 nCountAddons
= aAddonInstMergeNodesSeq
.getLength();
877 for ( sal_uInt32 j
= 0; j
< nCountAddons
; j
++ )
879 OUStringBuffer
aMergeAddonInstructionBase( aMergeAddonInstructions
);
880 aMergeAddonInstructionBase
.append( m_aPathDelimiter
);
881 aMergeAddonInstructionBase
.append( aAddonInstMergeNodesSeq
[j
] );
882 aMergeAddonInstructionBase
.append( m_aPathDelimiter
);
884 // Create sequence for data access
885 OUStringBuffer
aBuffer( aMergeAddonInstructionBase
);
886 aBuffer
.append( m_aPropMergeToolbarNames
[ OFFSET_MERGETOOLBAR_TOOLBAR
] );
887 aNodePropNames
[0] = aBuffer
.makeStringAndClear();
889 aBuffer
= aMergeAddonInstructionBase
;
890 aBuffer
.append( m_aPropMergeToolbarNames
[ OFFSET_MERGETOOLBAR_MERGEPOINT
] );
891 aNodePropNames
[1] = aBuffer
.makeStringAndClear();
893 aBuffer
= aMergeAddonInstructionBase
;
894 aBuffer
.append( m_aPropMergeToolbarNames
[ OFFSET_MERGETOOLBAR_MERGECOMMAND
] );
895 aNodePropNames
[2] = aBuffer
.makeStringAndClear();
897 aBuffer
= aMergeAddonInstructionBase
;
898 aBuffer
.append( m_aPropMergeToolbarNames
[ OFFSET_MERGETOOLBAR_MERGECOMMANDPARAMETER
] );
899 aNodePropNames
[3] = aBuffer
.makeStringAndClear();
901 aBuffer
= aMergeAddonInstructionBase
;
902 aBuffer
.append( m_aPropMergeToolbarNames
[ OFFSET_MERGETOOLBAR_MERGEFALLBACK
] );
903 aNodePropNames
[4] = aBuffer
.makeStringAndClear();
905 aBuffer
= aMergeAddonInstructionBase
;
906 aBuffer
.append( m_aPropMergeToolbarNames
[ OFFSET_MERGETOOLBAR_MERGECONTEXT
] );
907 aNodePropNames
[5] = aBuffer
.makeStringAndClear();
909 Sequence
< Any
> aNodePropValues
= GetProperties( aNodePropNames
);
911 MergeToolbarInstruction aMergeToolbarInstruction
;
912 aNodePropValues
[0] >>= aMergeToolbarInstruction
.aMergeToolbar
;
913 aNodePropValues
[1] >>= aMergeToolbarInstruction
.aMergePoint
;
914 aNodePropValues
[2] >>= aMergeToolbarInstruction
.aMergeCommand
;
915 aNodePropValues
[3] >>= aMergeToolbarInstruction
.aMergeCommandParameter
;
916 aNodePropValues
[4] >>= aMergeToolbarInstruction
.aMergeFallback
;
917 aNodePropValues
[5] >>= aMergeToolbarInstruction
.aMergeContext
;
919 ReadMergeToolbarData( aMergeAddonInstructionBase
.makeStringAndClear(),
920 aMergeToolbarInstruction
.aMergeToolbarItems
);
922 MergeToolbarInstructionContainer
& rVector
= rCachedToolbarMergingInstructions
[ aMergeToolbarInstruction
.aMergeToolbar
];
923 rVector
.push_back( aMergeToolbarInstruction
);
930 bool AddonsOptions_Impl::ReadMergeToolbarData( const OUString
& aMergeAddonInstructionBase
, Sequence
< Sequence
< PropertyValue
> >& rMergeToolbarItems
)
932 OUStringBuffer
aBuffer( aMergeAddonInstructionBase
);
933 aBuffer
.append( m_aPropMergeToolbarNames
[ OFFSET_MERGETOOLBAR_TOOLBARITEMS
] );
935 OUString aMergeToolbarBaseNode
= aBuffer
.makeStringAndClear();
937 return ReadToolBarItemSet( aMergeToolbarBaseNode
, rMergeToolbarItems
);
940 bool AddonsOptions_Impl::ReadStatusbarMergeInstructions( MergeStatusbarInstructionContainer
& aContainer
)
942 const ::rtl::OUString
aStatusbarMergeRootName( "AddonUI/OfficeStatusbarMerging/" );
944 Sequence
< ::rtl::OUString
> aAddonMergeNodesSeq
= GetNodeNames( aStatusbarMergeRootName
);
945 ::rtl::OUString
aAddonMergeNode( aStatusbarMergeRootName
);
946 sal_uInt32 nCount
= aAddonMergeNodesSeq
.getLength();
948 Sequence
< ::rtl::OUString
> aNodePropNames( 5 );
950 for ( sal_uInt32 i
= 0; i
< nCount
; i
++ )
952 ::rtl::OUString
aMergeAddonInstructions( aAddonMergeNode
+ aAddonMergeNodesSeq
[i
] );
954 Sequence
< ::rtl::OUString
> aAddonInstMergeNodesSeq
= GetNodeNames( aMergeAddonInstructions
);
955 sal_uInt32 nCountAddons
= aAddonInstMergeNodesSeq
.getLength();
957 for ( sal_uInt32 j
= 0; j
< nCountAddons
; j
++ )
959 ::rtl::OUStringBuffer
aMergeAddonInstructionBase( aMergeAddonInstructions
);
960 aMergeAddonInstructionBase
.append( m_aPathDelimiter
);
961 aMergeAddonInstructionBase
.append( aAddonInstMergeNodesSeq
[j
] );
962 aMergeAddonInstructionBase
.append( m_aPathDelimiter
);
964 // Create sequence for data access
965 ::rtl::OUStringBuffer
aBuffer( aMergeAddonInstructionBase
);
966 aBuffer
.append( m_aPropMergeMenuNames
[ OFFSET_MERGESTATUSBAR_MERGEPOINT
] );
967 aNodePropNames
[0] = aBuffer
.makeStringAndClear();
969 aBuffer
= aMergeAddonInstructionBase
;
970 aBuffer
.append( m_aPropMergeMenuNames
[ OFFSET_MERGESTATUSBAR_MERGECOMMAND
] );
971 aNodePropNames
[1] = aBuffer
.makeStringAndClear();
973 aBuffer
= aMergeAddonInstructionBase
;
974 aBuffer
.append( m_aPropMergeMenuNames
[ OFFSET_MERGESTATUSBAR_MERGECOMMANDPARAMETER
] );
975 aNodePropNames
[2] = aBuffer
.makeStringAndClear();
977 aBuffer
= aMergeAddonInstructionBase
;
978 aBuffer
.append( m_aPropMergeMenuNames
[ OFFSET_MERGESTATUSBAR_MERGEFALLBACK
] );
979 aNodePropNames
[3] = aBuffer
.makeStringAndClear();
981 aBuffer
= aMergeAddonInstructionBase
;
982 aBuffer
.append( m_aPropMergeMenuNames
[ OFFSET_MERGESTATUSBAR_MERGECONTEXT
] );
983 aNodePropNames
[4] = aBuffer
.makeStringAndClear();
985 Sequence
< Any
> aNodePropValues
= GetProperties( aNodePropNames
);
987 MergeStatusbarInstruction aMergeStatusbarInstruction
;
988 aNodePropValues
[0] >>= aMergeStatusbarInstruction
.aMergePoint
;
989 aNodePropValues
[1] >>= aMergeStatusbarInstruction
.aMergeCommand
;
990 aNodePropValues
[2] >>= aMergeStatusbarInstruction
.aMergeCommandParameter
;
991 aNodePropValues
[3] >>= aMergeStatusbarInstruction
.aMergeFallback
;
992 aNodePropValues
[4] >>= aMergeStatusbarInstruction
.aMergeContext
;
994 ReadMergeStatusbarData( aMergeAddonInstructionBase
.makeStringAndClear(),
995 aMergeStatusbarInstruction
.aMergeStatusbarItems
);
997 aContainer
.push_back( aMergeStatusbarInstruction
);
1004 bool AddonsOptions_Impl::ReadMergeStatusbarData(
1005 const ::rtl::OUString
& aMergeAddonInstructionBase
,
1006 Sequence
< Sequence
< PropertyValue
> >& rMergeStatusbarItems
)
1008 sal_uInt32 nStatusbarItemCount
= rMergeStatusbarItems
.getLength();
1010 ::rtl::OUStringBuffer
aBuffer( aMergeAddonInstructionBase
);
1011 aBuffer
.append( m_aPropMergeStatusbarNames
[ OFFSET_MERGESTATUSBAR_STATUSBARITEMS
] );
1012 ::rtl::OUString aMergeStatusbarBaseNode
= aBuffer
.makeStringAndClear();
1014 ::rtl::OUString
aAddonStatusbarItemSetNode( aMergeStatusbarBaseNode
+ m_aPathDelimiter
);
1015 Sequence
< ::rtl::OUString
> aAddonStatusbarItemSetNodeSeq
= GetNodeNames( aMergeStatusbarBaseNode
);
1017 Sequence
< PropertyValue
> aStatusbarItem( PROPERTYCOUNT_STATUSBARITEM
);
1018 aStatusbarItem
[ OFFSET_STATUSBARITEM_URL
].Name
= m_aPropNames
[ INDEX_URL
];
1019 aStatusbarItem
[ OFFSET_STATUSBARITEM_TITLE
].Name
= m_aPropNames
[ INDEX_TITLE
];
1020 aStatusbarItem
[ OFFSET_STATUSBARITEM_CONTEXT
].Name
= m_aPropNames
[ INDEX_CONTEXT
];
1021 aStatusbarItem
[ OFFSET_STATUSBARITEM_ALIGN
].Name
= m_aPropNames
[ INDEX_ALIGN
];
1022 aStatusbarItem
[ OFFSET_STATUSBARITEM_AUTOSIZE
].Name
= m_aPropNames
[ INDEX_AUTOSIZE
];
1023 aStatusbarItem
[ OFFSET_STATUSBARITEM_OWNERDRAW
].Name
= m_aPropNames
[ INDEX_OWNERDRAW
];
1024 aStatusbarItem
[ OFFSET_STATUSBARITEM_WIDTH
].Name
= m_aPropNames
[ INDEX_WIDTH
];
1026 sal_uInt32 nCount
= aAddonStatusbarItemSetNodeSeq
.getLength();
1027 for ( sal_uInt32 n
= 0; n
< nCount
; n
++ )
1029 ::rtl::OUString
aStatusbarItemNode( aAddonStatusbarItemSetNode
+ aAddonStatusbarItemSetNodeSeq
[n
] );
1031 if ( ReadStatusBarItem( aStatusbarItemNode
, aStatusbarItem
) )
1033 sal_uInt32 nAddonCount
= rMergeStatusbarItems
.getLength();
1034 rMergeStatusbarItems
.realloc( nAddonCount
+1 );
1035 rMergeStatusbarItems
[nAddonCount
] = aStatusbarItem
;
1039 return ( (sal_uInt32
)rMergeStatusbarItems
.getLength() > nStatusbarItemCount
);
1042 bool AddonsOptions_Impl::ReadStatusBarItem(
1043 const ::rtl::OUString
& aStatusarItemNodeName
,
1044 Sequence
< PropertyValue
>& aStatusbarItem
)
1046 bool bResult( false );
1047 ::rtl::OUString aURL
;
1048 ::rtl::OUString
aAddonStatusbarItemTreeNode( aStatusarItemNodeName
+ m_aPathDelimiter
);
1049 Sequence
< Any
> aStatusbarItemNodePropValues
;
1051 aStatusbarItemNodePropValues
= GetProperties( GetPropertyNamesStatusbarItem( aAddonStatusbarItemTreeNode
) );
1053 // Command URL is required
1054 if (( aStatusbarItemNodePropValues
[ OFFSET_STATUSBARITEM_URL
] >>= aURL
) && aURL
.getLength() > 0 )
1056 aStatusbarItem
[ OFFSET_STATUSBARITEM_URL
].Value
<<= aURL
;
1057 aStatusbarItem
[ OFFSET_STATUSBARITEM_TITLE
].Value
<<= aStatusbarItemNodePropValues
[ OFFSET_STATUSBARITEM_TITLE
];
1058 aStatusbarItem
[ OFFSET_STATUSBARITEM_CONTEXT
].Value
<<= aStatusbarItemNodePropValues
[ OFFSET_STATUSBARITEM_CONTEXT
];
1059 aStatusbarItem
[ OFFSET_STATUSBARITEM_ALIGN
].Value
<<= aStatusbarItemNodePropValues
[ OFFSET_STATUSBARITEM_ALIGN
];
1060 aStatusbarItem
[ OFFSET_STATUSBARITEM_AUTOSIZE
].Value
<<= aStatusbarItemNodePropValues
[ OFFSET_STATUSBARITEM_AUTOSIZE
];;
1061 aStatusbarItem
[ OFFSET_STATUSBARITEM_OWNERDRAW
].Value
<<= aStatusbarItemNodePropValues
[ OFFSET_STATUSBARITEM_OWNERDRAW
];
1063 // Configuration uses hyper for long. Therefore transform into sal_Int32
1064 sal_Int64
nValue( 0 );
1065 aStatusbarItemNodePropValues
[ OFFSET_STATUSBARITEM_WIDTH
] >>= nValue
;
1066 aStatusbarItem
[ OFFSET_STATUSBARITEM_WIDTH
].Value
<<= sal_Int32( nValue
);
1074 bool AddonsOptions_Impl::ReadMenuItem( const OUString
& aMenuNodeName
, Sequence
< PropertyValue
>& aMenuItem
, bool bIgnoreSubMenu
)
1076 bool bResult
= false;
1078 OUString
aAddonMenuItemTreeNode( aMenuNodeName
+ m_aPathDelimiter
);
1079 Sequence
< Any
> aMenuItemNodePropValues
;
1081 aMenuItemNodePropValues
= GetProperties( GetPropertyNamesMenuItem( aAddonMenuItemTreeNode
) );
1082 if (( aMenuItemNodePropValues
[ OFFSET_MENUITEM_TITLE
] >>= aStrValue
) && !aStrValue
.isEmpty() )
1084 aMenuItem
[ OFFSET_MENUITEM_TITLE
].Value
<<= aStrValue
;
1086 OUString
aRootSubMenuName( aAddonMenuItemTreeNode
+ m_aPropNames
[ INDEX_SUBMENU
] );
1087 Sequence
< OUString
> aRootSubMenuNodeNames
= GetNodeNames( aRootSubMenuName
);
1088 if ( aRootSubMenuNodeNames
.getLength() > 0 && !bIgnoreSubMenu
)
1090 // Set a unique prefixed Add-On popup menu URL so it can be identified later
1091 OUString aPopupMenuURL
= GeneratePrefixURL();
1092 OUString aPopupMenuImageId
;
1094 aMenuItemNodePropValues
[ OFFSET_MENUITEM_IMAGEIDENTIFIER
] >>= aPopupMenuImageId
;
1095 ReadAndAssociateImages( aPopupMenuURL
, aPopupMenuImageId
);
1097 // A popup menu must have a title and can have a URL and ImageIdentifier
1098 // Set the other property values to empty
1099 aMenuItem
[ OFFSET_MENUITEM_URL
].Value
<<= aPopupMenuURL
;
1100 aMenuItem
[ OFFSET_MENUITEM_TARGET
].Value
<<= m_aEmpty
;
1101 aMenuItem
[ OFFSET_MENUITEM_IMAGEIDENTIFIER
].Value
<<= aPopupMenuImageId
;
1102 aMenuItem
[ OFFSET_MENUITEM_CONTEXT
].Value
<<= aMenuItemNodePropValues
[ OFFSET_MENUITEM_CONTEXT
];
1104 // Continue to read the sub menu nodes
1105 Sequence
< Sequence
< PropertyValue
> > aSubMenuSeq
;
1106 OUString
aSubMenuRootNodeName( aRootSubMenuName
+ m_aPathDelimiter
);
1107 for ( sal_uInt32 n
= 0; n
< (sal_uInt32
)aRootSubMenuNodeNames
.getLength(); n
++ )
1108 aRootSubMenuNodeNames
[n
] = aSubMenuRootNodeName
+ aRootSubMenuNodeNames
[n
];
1109 ReadSubMenuEntries( aRootSubMenuNodeNames
, aSubMenuSeq
);
1110 aMenuItem
[ OFFSET_MENUITEM_SUBMENU
].Value
<<= aSubMenuSeq
;
1113 else if (( aMenuItemNodePropValues
[ OFFSET_MENUITEM_URL
] >>= aStrValue
) && !aStrValue
.isEmpty() )
1115 // A simple menu item => read the other properties;
1116 OUString aMenuImageId
;
1118 aMenuItemNodePropValues
[ OFFSET_MENUITEM_IMAGEIDENTIFIER
] >>= aMenuImageId
;
1119 ReadAndAssociateImages( aStrValue
, aMenuImageId
);
1121 aMenuItem
[ OFFSET_MENUITEM_URL
].Value
<<= aStrValue
;
1122 aMenuItem
[ OFFSET_MENUITEM_TARGET
].Value
<<= aMenuItemNodePropValues
[ OFFSET_MENUITEM_TARGET
];
1123 aMenuItem
[ OFFSET_MENUITEM_IMAGEIDENTIFIER
].Value
<<= aMenuImageId
;
1124 aMenuItem
[ OFFSET_MENUITEM_CONTEXT
].Value
<<= aMenuItemNodePropValues
[ OFFSET_MENUITEM_CONTEXT
];
1125 aMenuItem
[ OFFSET_MENUITEM_SUBMENU
].Value
<<= Sequence
< Sequence
< PropertyValue
> >(); // Submenu set!
1130 else if (( aMenuItemNodePropValues
[ OFFSET_MENUITEM_URL
] >>= aStrValue
) &&
1131 aStrValue
== SEPARATOR_URL
)
1134 aMenuItem
[ OFFSET_MENUITEM_URL
].Value
<<= aStrValue
;
1135 aMenuItem
[ OFFSET_MENUITEM_TARGET
].Value
<<= m_aEmpty
;
1136 aMenuItem
[ OFFSET_MENUITEM_IMAGEIDENTIFIER
].Value
<<= m_aEmpty
;
1137 aMenuItem
[ OFFSET_MENUITEM_CONTEXT
].Value
<<= m_aEmpty
;
1138 aMenuItem
[ OFFSET_MENUITEM_SUBMENU
].Value
<<= Sequence
< Sequence
< PropertyValue
> >(); // Submenu set!
1145 bool AddonsOptions_Impl::ReadPopupMenu( const OUString
& aPopupMenuNodeName
, Sequence
< PropertyValue
>& aPopupMenu
)
1147 bool bResult
= false;
1149 OUString
aAddonPopupMenuTreeNode( aPopupMenuNodeName
+ m_aPathDelimiter
);
1150 Sequence
< Any
> aPopupMenuNodePropValues
;
1152 aPopupMenuNodePropValues
= GetProperties( GetPropertyNamesPopupMenu( aAddonPopupMenuTreeNode
) );
1153 if (( aPopupMenuNodePropValues
[ OFFSET_POPUPMENU_TITLE
] >>= aStrValue
) &&
1154 !aStrValue
.isEmpty() )
1156 aPopupMenu
[ OFFSET_POPUPMENU_TITLE
].Value
<<= aStrValue
;
1158 OUString
aRootSubMenuName( aAddonPopupMenuTreeNode
+ m_aPropNames
[ INDEX_SUBMENU
] );
1159 Sequence
< OUString
> aRootSubMenuNodeNames
= GetNodeNames( aRootSubMenuName
);
1160 if ( aRootSubMenuNodeNames
.getLength() > 0 )
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 OUString aPopupMenuURL
= GeneratePrefixURL();
1166 aPopupMenu
[ OFFSET_POPUPMENU_URL
].Value
<<= aPopupMenuURL
;
1167 aPopupMenu
[ OFFSET_POPUPMENU_CONTEXT
].Value
<<= aPopupMenuNodePropValues
[ OFFSET_POPUPMENU_CONTEXT
];
1169 // Continue to read the sub menu nodes
1170 Sequence
< Sequence
< PropertyValue
> > aSubMenuSeq
;
1171 OUString
aSubMenuRootNodeName( aRootSubMenuName
+ m_aPathDelimiter
);
1172 for ( sal_uInt32 n
= 0; n
< (sal_uInt32
)aRootSubMenuNodeNames
.getLength(); n
++ )
1173 aRootSubMenuNodeNames
[n
] = aSubMenuRootNodeName
+ aRootSubMenuNodeNames
[n
];
1174 ReadSubMenuEntries( aRootSubMenuNodeNames
, aSubMenuSeq
);
1175 aPopupMenu
[ OFFSET_POPUPMENU_SUBMENU
].Value
<<= aSubMenuSeq
;
1183 bool AddonsOptions_Impl::AppendPopupMenu( Sequence
< PropertyValue
>& rTargetPopupMenu
, const Sequence
< PropertyValue
>& rSourcePopupMenu
)
1185 Sequence
< Sequence
< PropertyValue
> > aTargetSubMenuSeq
;
1186 Sequence
< Sequence
< PropertyValue
> > aSourceSubMenuSeq
;
1188 if (( rTargetPopupMenu
[ OFFSET_POPUPMENU_SUBMENU
].Value
>>= aTargetSubMenuSeq
) &&
1189 ( rSourcePopupMenu
[ OFFSET_POPUPMENU_SUBMENU
].Value
>>= aSourceSubMenuSeq
))
1191 sal_uInt32 nIndex
= aTargetSubMenuSeq
.getLength();
1192 aTargetSubMenuSeq
.realloc( nIndex
+ aSourceSubMenuSeq
.getLength() );
1193 for ( sal_uInt32 i
= 0; i
< sal_uInt32( aSourceSubMenuSeq
.getLength() ); i
++ )
1194 aTargetSubMenuSeq
[nIndex
++] = aSourceSubMenuSeq
[i
];
1195 rTargetPopupMenu
[ OFFSET_POPUPMENU_SUBMENU
].Value
<<= aTargetSubMenuSeq
;
1201 bool AddonsOptions_Impl::ReadToolBarItem( const OUString
& aToolBarItemNodeName
, Sequence
< PropertyValue
>& aToolBarItem
)
1203 bool bResult
= false;
1206 OUString
aAddonToolBarItemTreeNode( aToolBarItemNodeName
+ m_aPathDelimiter
);
1207 Sequence
< Any
> aToolBarItemNodePropValues
;
1209 aToolBarItemNodePropValues
= GetProperties( GetPropertyNamesToolBarItem( aAddonToolBarItemTreeNode
) );
1211 // A toolbar item must have a command URL
1212 if (( aToolBarItemNodePropValues
[ OFFSET_TOOLBARITEM_URL
] >>= aURL
) && !aURL
.isEmpty() )
1214 if ( aURL
== SEPARATOR_URL
)
1216 // A speparator toolbar item only needs a URL
1217 aToolBarItem
[ OFFSET_TOOLBARITEM_URL
].Value
<<= aURL
;
1218 aToolBarItem
[ OFFSET_TOOLBARITEM_TITLE
].Value
<<= m_aEmpty
;
1219 aToolBarItem
[ OFFSET_TOOLBARITEM_TARGET
].Value
<<= m_aEmpty
;
1220 aToolBarItem
[ OFFSET_TOOLBARITEM_IMAGEIDENTIFIER
].Value
<<= m_aEmpty
;
1221 aToolBarItem
[ OFFSET_TOOLBARITEM_CONTEXT
].Value
<<= m_aEmpty
;
1222 aToolBarItem
[ OFFSET_TOOLBARITEM_CONTROLTYPE
].Value
<<= m_aEmpty
;
1223 aToolBarItem
[ OFFSET_TOOLBARITEM_WIDTH
].Value
<<= sal_Int32( 0 );
1227 else if (( aToolBarItemNodePropValues
[ OFFSET_TOOLBARITEM_TITLE
] >>= aTitle
) && !aTitle
.isEmpty() )
1229 // A normal toolbar item must also have title => read the other properties;
1232 // Try to map a user-defined image URL to our internal private image URL
1233 aToolBarItemNodePropValues
[ OFFSET_TOOLBARITEM_IMAGEIDENTIFIER
] >>= aImageId
;
1234 ReadAndAssociateImages( aURL
, aImageId
);
1236 aToolBarItem
[ OFFSET_TOOLBARITEM_URL
].Value
<<= aURL
;
1237 aToolBarItem
[ OFFSET_TOOLBARITEM_TITLE
].Value
<<= aTitle
;
1238 aToolBarItem
[ OFFSET_TOOLBARITEM_TARGET
].Value
<<= aToolBarItemNodePropValues
[ OFFSET_TOOLBARITEM_TARGET
];
1239 aToolBarItem
[ OFFSET_TOOLBARITEM_IMAGEIDENTIFIER
].Value
<<= aImageId
;
1240 aToolBarItem
[ OFFSET_TOOLBARITEM_CONTEXT
].Value
<<= aToolBarItemNodePropValues
[ OFFSET_TOOLBARITEM_CONTEXT
];
1241 aToolBarItem
[ OFFSET_TOOLBARITEM_CONTROLTYPE
].Value
<<= aToolBarItemNodePropValues
[ OFFSET_TOOLBARITEM_CONTROLTYPE
];
1243 // Configuration uses hyper for long. Therefore transform into sal_Int32
1244 sal_Int64
nValue( 0 );
1245 aToolBarItemNodePropValues
[ OFFSET_TOOLBARITEM_WIDTH
] >>= nValue
;
1246 aToolBarItem
[ OFFSET_TOOLBARITEM_WIDTH
].Value
<<= sal_Int32( nValue
);
1255 bool AddonsOptions_Impl::ReadSubMenuEntries( const Sequence
< OUString
>& aSubMenuNodeNames
, Sequence
< Sequence
< PropertyValue
> >& rSubMenuSeq
)
1257 Sequence
< PropertyValue
> aMenuItem( PROPERTYCOUNT_MENUITEM
);
1259 // Init the property value sequence
1260 aMenuItem
[ OFFSET_MENUITEM_URL
].Name
= PROPERTYNAME_URL
;
1261 aMenuItem
[ OFFSET_MENUITEM_TITLE
].Name
= PROPERTYNAME_TITLE
;
1262 aMenuItem
[ OFFSET_MENUITEM_TARGET
].Name
= PROPERTYNAME_TARGET
;
1263 aMenuItem
[ OFFSET_MENUITEM_IMAGEIDENTIFIER
].Name
= PROPERTYNAME_IMAGEIDENTIFIER
;
1264 aMenuItem
[ OFFSET_MENUITEM_CONTEXT
].Name
= PROPERTYNAME_CONTEXT
;
1265 aMenuItem
[ OFFSET_MENUITEM_SUBMENU
].Name
= PROPERTYNAME_SUBMENU
; // Submenu set!
1267 sal_uInt32 nIndex
= 0;
1268 sal_uInt32 nCount
= aSubMenuNodeNames
.getLength();
1269 for ( sal_uInt32 n
= 0; n
< nCount
; n
++ )
1271 if ( ReadMenuItem( aSubMenuNodeNames
[n
], aMenuItem
))
1273 sal_uInt32 nSubMenuCount
= rSubMenuSeq
.getLength() + 1;
1274 rSubMenuSeq
.realloc( nSubMenuCount
);
1275 rSubMenuSeq
[nIndex
++] = aMenuItem
;
1282 bool AddonsOptions_Impl::HasAssociatedImages( const OUString
& aURL
)
1284 // FIXME: potentially this is not so useful in a world of delayed image loading
1285 ImageManager::const_iterator pIter
= m_aImageManager
.find( aURL
);
1286 return ( pIter
!= m_aImageManager
.end() );
1289 void AddonsOptions_Impl::SubstituteVariables( OUString
& aURL
)
1291 aURL
= comphelper::getExpandedUri(
1292 comphelper::getProcessComponentContext(), aURL
);
1295 Image
AddonsOptions_Impl::ReadImageFromURL(const OUString
& aImageURL
)
1299 SvStream
* pStream
= UcbStreamHelper::CreateStream( aImageURL
, STREAM_STD_READ
);
1300 if ( pStream
&& ( pStream
->GetErrorCode() == 0 ))
1302 // Use graphic class to also support more graphic formats (bmp,png,...)
1305 GraphicFilter
& rGF
= GraphicFilter::GetGraphicFilter();
1306 rGF
.ImportGraphic( aGraphic
, OUString(), *pStream
, GRFILTER_FORMAT_DONTKNOW
);
1308 BitmapEx aBitmapEx
= aGraphic
.GetBitmapEx();
1310 Size aBmpSize
= aBitmapEx
.GetSizePixel();
1311 if ( aBmpSize
.Width() > 0 && aBmpSize
.Height() > 0 )
1313 // Support non-transparent bitmaps to be downward compatible with OOo 1.1.x addons
1314 if( !aBitmapEx
.IsTransparent() )
1315 aBitmapEx
= BitmapEx( aBitmapEx
.GetBitmap(), COL_LIGHTMAGENTA
);
1317 aImage
= Image(aBitmapEx
);
1326 void AddonsOptions_Impl::ReadAndAssociateImages( const OUString
& aURL
, const OUString
& aImageId
)
1328 if ( aImageId
.isEmpty() )
1331 ImageEntry aImageEntry
;
1332 OUString
aImageURL( aImageId
);
1334 SubstituteVariables( aImageURL
);
1336 // Loop to create the two possible image names and try to read the bitmap files
1337 static const char* aExtArray
[] = { "_16", "_26" };
1338 for ( size_t i
= 0; i
< SAL_N_ELEMENTS(aExtArray
); i
++ )
1340 OUStringBuffer
aFileURL( aImageURL
);
1341 aFileURL
.appendAscii( aExtArray
[i
] );
1342 aFileURL
.appendAscii( ".bmp" );
1344 aImageEntry
.addImage( !i
? IMGSIZE_SMALL
: IMGSIZE_BIG
,
1345 Image(), aFileURL
.makeStringAndClear() );
1348 m_aImageManager
.insert( ImageManager::value_type( aURL
, aImageEntry
));
1351 AddonsOptions_Impl::ImageEntry
* AddonsOptions_Impl::ReadImageData( const OUString
& aImagesNodeName
)
1353 Sequence
< OUString
> aImageDataNodeNames
= GetPropertyNamesImages( aImagesNodeName
);
1354 Sequence
< Any
> aPropertyData
;
1355 Sequence
< sal_Int8
> aImageDataSeq
;
1358 ImageEntry
* pEntry
= NULL
;
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 aPropertyData
= GetProperties( aImageDataNodeNames
);
1363 for ( int i
= 0; i
< PROPERTYCOUNT_IMAGES
; i
++ )
1365 if ( i
< PROPERTYCOUNT_EMBEDDED_IMAGES
)
1367 // Extract image data from the embedded hex binary sequence
1369 if (( aPropertyData
[i
] >>= aImageDataSeq
) &&
1370 aImageDataSeq
.getLength() > 0 &&
1371 ( CreateImageFromSequence( aImage
, aImageDataSeq
) ) )
1374 pEntry
= new ImageEntry
;
1375 pEntry
->addImage(i
== OFFSET_IMAGES_SMALL
? IMGSIZE_SMALL
: IMGSIZE_BIG
, aImage
, "");
1381 pEntry
= new ImageEntry();
1383 // Retrieve image data from a external bitmap file. Make sure that embedded image data
1384 // has a higher priority.
1385 aPropertyData
[i
] >>= aImageURL
;
1387 SubstituteVariables( aImageURL
);
1389 pEntry
->addImage(IMGSIZE_BIG
, Image(), aImageURL
);
1396 bool AddonsOptions_Impl::CreateImageFromSequence( Image
& rImage
, Sequence
< sal_Int8
>& rBitmapDataSeq
) const
1398 bool bResult
= false;
1400 if ( rBitmapDataSeq
.getLength() > 0 )
1402 SvMemoryStream
aMemStream( rBitmapDataSeq
.getArray(), rBitmapDataSeq
.getLength(), STREAM_STD_READ
);
1405 ReadDIBBitmapEx(aBitmapEx
, aMemStream
);
1407 if( !aBitmapEx
.IsTransparent() )
1409 // Support non-transparent bitmaps to be downward compatible with OOo 1.1.x addons
1410 aBitmapEx
= BitmapEx( aBitmapEx
.GetBitmap(), COL_LIGHTMAGENTA
);
1413 rImage
= Image( aBitmapEx
);
1420 Sequence
< OUString
> AddonsOptions_Impl::GetPropertyNamesMenuItem( const OUString
& aPropertyRootNode
) const
1422 Sequence
< OUString
> lResult( PROPERTYCOUNT_MENUITEM
);
1424 // Create property names dependent from the root node name
1425 lResult
[OFFSET_MENUITEM_URL
] = aPropertyRootNode
+ m_aPropNames
[ INDEX_URL
];
1426 lResult
[OFFSET_MENUITEM_TITLE
] = aPropertyRootNode
+ m_aPropNames
[ INDEX_TITLE
];
1427 lResult
[OFFSET_MENUITEM_IMAGEIDENTIFIER
] = aPropertyRootNode
+ m_aPropNames
[ INDEX_IMAGEIDENTIFIER
];
1428 lResult
[OFFSET_MENUITEM_TARGET
] = aPropertyRootNode
+ m_aPropNames
[ INDEX_TARGET
];
1429 lResult
[OFFSET_MENUITEM_CONTEXT
] = aPropertyRootNode
+ m_aPropNames
[ INDEX_CONTEXT
];
1430 lResult
[OFFSET_MENUITEM_SUBMENU
] = aPropertyRootNode
+ m_aPropNames
[ INDEX_SUBMENU
];
1435 Sequence
< OUString
> AddonsOptions_Impl::GetPropertyNamesPopupMenu( const OUString
& aPropertyRootNode
) const
1437 // The URL is automatically set and not read from the configuration.
1438 Sequence
< OUString
> lResult( PROPERTYCOUNT_POPUPMENU
-1 );
1440 // Create property names dependent from the root node name
1441 lResult
[OFFSET_POPUPMENU_TITLE
] = aPropertyRootNode
+ m_aPropNames
[ INDEX_TITLE
];
1442 lResult
[OFFSET_POPUPMENU_CONTEXT
] = aPropertyRootNode
+ m_aPropNames
[ INDEX_CONTEXT
];
1443 lResult
[OFFSET_POPUPMENU_SUBMENU
] = aPropertyRootNode
+ m_aPropNames
[ INDEX_SUBMENU
];
1448 Sequence
< OUString
> AddonsOptions_Impl::GetPropertyNamesToolBarItem( const OUString
& aPropertyRootNode
) const
1450 Sequence
< OUString
> lResult( PROPERTYCOUNT_TOOLBARITEM
);
1452 // Create property names dependent from the root node name
1453 lResult
[0] = aPropertyRootNode
+ m_aPropNames
[ INDEX_URL
];
1454 lResult
[1] = aPropertyRootNode
+ m_aPropNames
[ INDEX_TITLE
];
1455 lResult
[2] = aPropertyRootNode
+ m_aPropNames
[ INDEX_IMAGEIDENTIFIER
];
1456 lResult
[3] = aPropertyRootNode
+ m_aPropNames
[ INDEX_TARGET
];
1457 lResult
[4] = aPropertyRootNode
+ m_aPropNames
[ INDEX_CONTEXT
];
1458 lResult
[5] = aPropertyRootNode
+ m_aPropNames
[ INDEX_CONTROLTYPE
];
1459 lResult
[6] = aPropertyRootNode
+ m_aPropNames
[ INDEX_WIDTH
];
1464 Sequence
< ::rtl::OUString
> AddonsOptions_Impl::GetPropertyNamesStatusbarItem(
1465 const ::rtl::OUString
& aPropertyRootNode
) const
1467 Sequence
< ::rtl::OUString
> lResult( PROPERTYCOUNT_STATUSBARITEM
);
1469 lResult
[0] = ::rtl::OUString( aPropertyRootNode
+ m_aPropNames
[ INDEX_URL
] );
1470 lResult
[1] = ::rtl::OUString( aPropertyRootNode
+ m_aPropNames
[ INDEX_TITLE
] );
1471 lResult
[2] = ::rtl::OUString( aPropertyRootNode
+ m_aPropNames
[ INDEX_CONTEXT
] );
1472 lResult
[3] = ::rtl::OUString( aPropertyRootNode
+ m_aPropNames
[ INDEX_ALIGN
] );
1473 lResult
[4] = ::rtl::OUString( aPropertyRootNode
+ m_aPropNames
[ INDEX_AUTOSIZE
] );
1474 lResult
[5] = ::rtl::OUString( aPropertyRootNode
+ m_aPropNames
[ INDEX_OWNERDRAW
] );
1475 lResult
[6] = ::rtl::OUString( aPropertyRootNode
+ m_aPropNames
[ INDEX_WIDTH
] );
1480 Sequence
< OUString
> AddonsOptions_Impl::GetPropertyNamesImages( const OUString
& aPropertyRootNode
) const
1482 Sequence
< OUString
> lResult( PROPERTYCOUNT_IMAGES
);
1484 // Create property names dependent from the root node name
1485 lResult
[0] = aPropertyRootNode
+ m_aPropImagesNames
[ OFFSET_IMAGES_SMALL
];
1486 lResult
[1] = aPropertyRootNode
+ m_aPropImagesNames
[ OFFSET_IMAGES_BIG
];
1487 lResult
[2] = aPropertyRootNode
+ m_aPropImagesNames
[ OFFSET_IMAGES_SMALLHC
];
1488 lResult
[3] = aPropertyRootNode
+ m_aPropImagesNames
[ OFFSET_IMAGES_BIGHC
];
1489 lResult
[4] = aPropertyRootNode
+ m_aPropImagesNames
[ OFFSET_IMAGES_SMALL_URL
];
1490 lResult
[5] = aPropertyRootNode
+ m_aPropImagesNames
[ OFFSET_IMAGES_BIG_URL
];
1491 lResult
[6] = aPropertyRootNode
+ m_aPropImagesNames
[ OFFSET_IMAGES_SMALLHC_URL
];
1492 lResult
[7] = aPropertyRootNode
+ m_aPropImagesNames
[ OFFSET_IMAGES_BIGHC_URL
];
1497 // initialize static member
1498 // DON'T DO IT IN YOUR HEADER!
1499 // see definition for further information
1501 AddonsOptions_Impl
* AddonsOptions::m_pDataContainer
= NULL
;
1502 sal_Int32
AddonsOptions::m_nRefCount
= 0;
1506 AddonsOptions::AddonsOptions()
1508 // Global access, must be guarded (multithreading!).
1509 MutexGuard
aGuard( GetOwnStaticMutex() );
1510 // Increase our refcount ...
1512 // ... and initialize our data container only if it not already exist!
1513 if( m_pDataContainer
== NULL
)
1515 m_pDataContainer
= new AddonsOptions_Impl
;
1521 AddonsOptions::~AddonsOptions()
1523 // Global access, must be guarded (multithreading!)
1524 MutexGuard
aGuard( GetOwnStaticMutex() );
1525 // Decrease our refcount.
1527 // If last instance was deleted ...
1528 // we must destroy our static data container!
1529 if( m_nRefCount
<= 0 )
1531 delete m_pDataContainer
;
1532 m_pDataContainer
= NULL
;
1538 bool AddonsOptions::HasAddonsMenu() const
1540 MutexGuard
aGuard( GetOwnStaticMutex() );
1541 return m_pDataContainer
->HasAddonsMenu();
1546 sal_Int32
AddonsOptions::GetAddonsToolBarCount() const
1548 MutexGuard
aGuard( GetOwnStaticMutex() );
1549 return m_pDataContainer
->GetAddonsToolBarCount();
1554 const Sequence
< Sequence
< PropertyValue
> >& AddonsOptions::GetAddonsMenu() const
1556 MutexGuard
aGuard( GetOwnStaticMutex() );
1557 return m_pDataContainer
->GetAddonsMenu();
1562 const Sequence
< Sequence
< PropertyValue
> >& AddonsOptions::GetAddonsMenuBarPart() const
1564 MutexGuard
aGuard( GetOwnStaticMutex() );
1565 return m_pDataContainer
->GetAddonsMenuBarPart();
1570 const Sequence
< Sequence
< PropertyValue
> >& AddonsOptions::GetAddonsToolBarPart( sal_uInt32 nIndex
) const
1572 MutexGuard
aGuard( GetOwnStaticMutex() );
1573 return m_pDataContainer
->GetAddonsToolBarPart( nIndex
);
1578 const OUString
AddonsOptions::GetAddonsToolbarResourceName( sal_uInt32 nIndex
) const
1580 MutexGuard
aGuard( GetOwnStaticMutex() );
1581 return m_pDataContainer
->GetAddonsToolbarResourceName( nIndex
);
1586 const Sequence
< Sequence
< PropertyValue
> >& AddonsOptions::GetAddonsHelpMenu() const
1588 MutexGuard
aGuard( GetOwnStaticMutex() );
1589 return m_pDataContainer
->GetAddonsHelpMenu();
1594 const MergeMenuInstructionContainer
& AddonsOptions::GetMergeMenuInstructions() const
1596 MutexGuard
aGuard( GetOwnStaticMutex() );
1597 return m_pDataContainer
->GetMergeMenuInstructions();
1602 bool AddonsOptions::GetMergeToolbarInstructions(
1603 const OUString
& rToolbarName
,
1604 MergeToolbarInstructionContainer
& rToolbarInstructions
) const
1606 MutexGuard
aGuard( GetOwnStaticMutex() );
1607 return m_pDataContainer
->GetMergeToolbarInstructions(
1608 rToolbarName
, rToolbarInstructions
);
1611 const MergeStatusbarInstructionContainer
& AddonsOptions::GetMergeStatusbarInstructions() const
1613 MutexGuard
aGuard( GetOwnStaticMutex() );
1614 return m_pDataContainer
->GetMergeStatusbarInstructions();
1619 Image
AddonsOptions::GetImageFromURL( const OUString
& aURL
, bool bBig
, bool bNoScale
) const
1621 MutexGuard
aGuard( GetOwnStaticMutex() );
1622 return m_pDataContainer
->GetImageFromURL( aURL
, bBig
, bNoScale
);
1627 Image
AddonsOptions::GetImageFromURL( const OUString
& aURL
, bool bBig
) const
1629 return GetImageFromURL( aURL
, bBig
, false );
1632 Mutex
& AddonsOptions::GetOwnStaticMutex()
1634 // Initialize static mutex only for one time!
1635 static Mutex
* pMutex
= NULL
;
1636 // If these method first called (Mutex not already exist!) ...
1637 if( pMutex
== NULL
)
1639 // ... we must create a new one. Protect follow code with the global mutex -
1640 // It must be - we create a static variable!
1641 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 if( pMutex
== NULL
)
1645 // Create the new mutex and set it for return on static variable.
1646 static Mutex aMutex
;
1650 // Return new created or already existing mutex object.
1654 IMPL_STATIC_LINK_NOARG( AddonsOptions
, Notify
)
1656 MutexGuard
aGuard( GetOwnStaticMutex() );
1657 m_pDataContainer
->ReadConfigurationData();
1663 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */