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