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