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