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