summaryrefslogtreecommitdiff
path: root/framework/source/fwe/classes/addonsoptions.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'framework/source/fwe/classes/addonsoptions.cxx')
-rw-r--r--framework/source/fwe/classes/addonsoptions.cxx1861
1 files changed, 1861 insertions, 0 deletions
diff --git a/framework/source/fwe/classes/addonsoptions.cxx b/framework/source/fwe/classes/addonsoptions.cxx
new file mode 100644
index 000000000000..730bf0baa32f
--- /dev/null
+++ b/framework/source/fwe/classes/addonsoptions.cxx
@@ -0,0 +1,1861 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: addonsoptions.cxx,v $
+ * $Revision: 1.17 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+//_________________________________________________________________________________________________________________
+// includes
+//_________________________________________________________________________________________________________________
+#include <classes/addonsoptions.hxx>
+#include <unotools/configmgr.hxx>
+#include <unotools/configitem.hxx>
+#include <unotools/ucbstreamhelper.hxx>
+#include <tools/debug.hxx>
+#include <tools/stream.hxx>
+#include <tools/color.hxx>
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/uno/Sequence.hxx>
+#include "com/sun/star/util/XMacroExpander.hpp"
+#include "com/sun/star/uno/XComponentContext.hpp"
+#include "com/sun/star/beans/XPropertySet.hpp"
+#include <rtl/ustrbuf.hxx>
+#include <rtl/uri.hxx>
+#include <comphelper/processfactory.hxx>
+#include <vcl/graph.hxx>
+#include <svtools/filter.hxx>
+
+#include <hash_map>
+#include <algorithm>
+#include <vector>
+
+//_________________________________________________________________________________________________________________
+// namespaces
+//_________________________________________________________________________________________________________________
+
+using namespace ::std ;
+using namespace ::utl ;
+using namespace ::osl ;
+using namespace ::com::sun::star::uno ;
+using namespace ::com::sun::star::beans ;
+using namespace ::com::sun::star::lang ;
+
+//_________________________________________________________________________________________________________________
+// const
+//_________________________________________________________________________________________________________________
+
+#define ROOTNODE_ADDONMENU ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Office.Addons" ))
+#define PATHDELIMITER ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/" ))
+#define TOOLBARITEMS ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ToolBarItems" ))
+#define SEPARATOR_URL_STR "private:separator"
+#define SEPARATOR_URL_LEN 17
+#define SEPARATOR_URL ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( SEPARATOR_URL_STR ))
+
+#define PROPERTYNAME_URL ADDONSMENUITEM_PROPERTYNAME_URL
+#define PROPERTYNAME_TITLE ADDONSMENUITEM_PROPERTYNAME_TITLE
+#define PROPERTYNAME_TARGET ADDONSMENUITEM_PROPERTYNAME_TARGET
+#define PROPERTYNAME_IMAGEIDENTIFIER ADDONSMENUITEM_PROPERTYNAME_IMAGEIDENTIFIER
+#define PROPERTYNAME_CONTEXT ADDONSMENUITEM_PROPERTYNAME_CONTEXT
+#define PROPERTYNAME_SUBMENU ADDONSMENUITEM_PROPERTYNAME_SUBMENU
+#define PROPERTYNAME_CONTROLTYPE ADDONSMENUITEM_PROPERTYNAME_CONTROLTYPE
+#define PROPERTYNAME_WIDTH ADDONSMENUITEM_PROPERTYNAME_WIDTH
+
+#define PROPERTYNAME_IMAGESMALL ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ImageSmall" ))
+#define PROPERTYNAME_IMAGEBIG ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ImageBig" ))
+#define PROPERTYNAME_IMAGESMALLHC ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ImageSmallHC" ))
+#define PROPERTYNAME_IMAGEBIGHC ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ImageBigHC" ))
+#define PROPERTYNAME_IMAGESMALL_URL ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ImageSmallURL" ))
+#define PROPERTYNAME_IMAGEBIG_URL ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ImageBigURL" ))
+#define PROPERTYNAME_IMAGESMALLHC_URL ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ImageSmallHCURL" ))
+#define PROPERTYNAME_IMAGEBIGHC_URL ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ImageBigHCURL" ))
+
+#define IMAGES_NODENAME ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("UserDefinedImages" ))
+#define PRIVATE_IMAGE_URL ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("private:image/" ))
+
+#define PROPERTYNAME_MERGEMENU_MERGEPOINT ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("MergePoint" ))
+#define PROPERTYNAME_MERGEMENU_MERGECOMMAND ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("MergeCommand" ))
+#define PROPERTYNAME_MERGEMENU_MERGECOMMANDPARAMETER ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("MergeCommandParameter" ))
+#define PROPERTYNAME_MERGEMENU_MERGEFALLBACK ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("MergeFallback" ))
+#define PROPERTYNAME_MERGEMENU_MERGECONTEXT ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("MergeContext" ))
+#define PROPERTYNAME_MERGEMENU_MENUITEMS ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("MenuItems" ))
+#define MERGEMENU_MERGEPOINT_SEPARATOR '\\'
+
+#define PROPERTYNAME_MERGETOOLBAR_TOOLBAR ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("MergeToolBar" ))
+#define PROPERTYNAME_MERGETOOLBAR_MERGEPOINT ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("MergePoint" ))
+#define PROPERTYNAME_MERGETOOLBAR_MERGECOMMAND ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("MergeCommand" ))
+#define PROPERTYNAME_MERGETOOLBAR_MERGECOMMANDPARAMETER ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("MergeCommandParameter" ))
+#define PROPERTYNAME_MERGETOOLBAR_MERGEFALLBACK ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("MergeFallback" ))
+#define PROPERTYNAME_MERGETOOLBAR_MERGECONTEXT ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("MergeContext" ))
+#define PROPERTYNAME_MERGETOOLBAR_TOOLBARITEMS ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ToolBarItems" ))
+
+// The following order is mandatory. Please add properties at the end!
+#define INDEX_URL 0
+#define INDEX_TITLE 1
+#define INDEX_IMAGEIDENTIFIER 2
+#define INDEX_TARGET 3
+#define INDEX_CONTEXT 4
+#define INDEX_SUBMENU 5
+#define INDEX_CONTROLTYPE 6
+#define INDEX_WIDTH 7
+#define PROPERTYCOUNT_INDEX 8
+
+// The following order is mandatory. Please add properties at the end!
+#define PROPERTYCOUNT_MENUITEM 6
+#define OFFSET_MENUITEM_URL 0
+#define OFFSET_MENUITEM_TITLE 1
+#define OFFSET_MENUITEM_IMAGEIDENTIFIER 2
+#define OFFSET_MENUITEM_TARGET 3
+#define OFFSET_MENUITEM_CONTEXT 4
+#define OFFSET_MENUITEM_SUBMENU 5
+
+// The following order is mandatory. Please add properties at the end!
+#define PROPERTYCOUNT_POPUPMENU 4
+#define OFFSET_POPUPMENU_TITLE 0
+#define OFFSET_POPUPMENU_CONTEXT 1
+#define OFFSET_POPUPMENU_SUBMENU 2
+#define OFFSET_POPUPMENU_URL 3 // Used for property set
+
+// The following order is mandatory. Please add properties at the end!
+#define PROPERTYCOUNT_TOOLBARITEM 7
+#define OFFSET_TOOLBARITEM_URL 0
+#define OFFSET_TOOLBARITEM_TITLE 1
+#define OFFSET_TOOLBARITEM_IMAGEIDENTIFIER 2
+#define OFFSET_TOOLBARITEM_TARGET 3
+#define OFFSET_TOOLBARITEM_CONTEXT 4
+#define OFFSET_TOOLBARITEM_CONTROLTYPE 5
+#define OFFSET_TOOLBARITEM_WIDTH 6
+
+// The following order is mandatory. Please add properties at the end!
+#define PROPERTYCOUNT_IMAGES 8
+#define PROPERTYCOUNT_EMBEDDED_IMAGES 4
+#define OFFSET_IMAGES_SMALL 0
+#define OFFSET_IMAGES_BIG 1
+#define OFFSET_IMAGES_SMALLHC 2
+#define OFFSET_IMAGES_BIGHC 3
+#define OFFSET_IMAGES_SMALL_URL 4
+#define OFFSET_IMAGES_BIG_URL 5
+#define OFFSET_IMAGES_SMALLHC_URL 6
+#define OFFSET_IMAGES_BIGHC_URL 7
+
+#define PROPERTYCOUNT_MERGE_MENUBAR 6
+#define OFFSET_MERGEMENU_MERGEPOINT 0
+#define OFFSET_MERGEMENU_MERGECOMMAND 1
+#define OFFSET_MERGEMENU_MERGECOMMANDPARAMETER 2
+#define OFFSET_MERGEMENU_MERGEFALLBACK 3
+#define OFFSET_MERGEMENU_MERGECONTEXT 4
+#define OFFSET_MERGEMENU_MENUITEMS 5
+
+#define PROPERTYCOUNT_MERGE_TOOLBAR 7
+#define OFFSET_MERGETOOLBAR_TOOLBAR 0
+#define OFFSET_MERGETOOLBAR_MERGEPOINT 1
+#define OFFSET_MERGETOOLBAR_MERGECOMMAND 2
+#define OFFSET_MERGETOOLBAR_MERGECOMMANDPARAMETER 3
+#define OFFSET_MERGETOOLBAR_MERGEFALLBACK 4
+#define OFFSET_MERGETOOLBAR_MERGECONTEXT 5
+#define OFFSET_MERGETOOLBAR_TOOLBARITEMS 6
+
+#define EXPAND_PROTOCOL "vnd.sun.star.expand:"
+
+const Size aImageSizeSmall( 16, 16 );
+const Size aImageSizeBig( 26, 26 );
+
+//_________________________________________________________________________________________________________________
+// private declarations!
+//_________________________________________________________________________________________________________________
+
+/*-****************************************************************************************************************
+ @descr struct to hold information about one menu entry.
+****************************************************************************************************************-*/
+
+namespace framework
+{
+
+class AddonsOptions_Impl : public ConfigItem
+{
+ //-------------------------------------------------------------------------------------------------------------
+ // public methods
+ //-------------------------------------------------------------------------------------------------------------
+
+ public:
+ //---------------------------------------------------------------------------------------------------------
+ // constructor / destructor
+ //---------------------------------------------------------------------------------------------------------
+
+ AddonsOptions_Impl();
+ ~AddonsOptions_Impl();
+
+ //---------------------------------------------------------------------------------------------------------
+ // overloaded methods of baseclass
+ //---------------------------------------------------------------------------------------------------------
+
+ /*-****************************************************************************************************//**
+ @short called for notify of configmanager
+ @descr These method is called from the ConfigManager before application ends or from the
+ PropertyChangeListener if the sub tree broadcasts changes. You must update your
+ internal values.
+
+ @seealso baseclass ConfigItem
+
+ @param "lPropertyNames" is the list of properties which should be updated.
+ @return -
+
+ @onerror -
+ *//*-*****************************************************************************************************/
+
+ virtual void Notify( const Sequence< ::rtl::OUString >& lPropertyNames );
+
+ /*-****************************************************************************************************//**
+ @short write changes to configuration
+ @descr These method writes the changed values into the sub tree
+ and should always called in our destructor to guarantee consistency of config data.
+
+ @seealso baseclass ConfigItem
+
+ @param -
+ @return -
+
+ @onerror -
+ *//*-*****************************************************************************************************/
+
+ virtual void Commit();
+
+ //---------------------------------------------------------------------------------------------------------
+ // public interface
+ //---------------------------------------------------------------------------------------------------------
+
+ /*-****************************************************************************************************//**
+ @short base implementation of public interface for "SvtDynamicMenuOptions"!
+ @descr These class is used as static member of "SvtDynamicMenuOptions" ...
+ => The code exist only for one time and isn't duplicated for every instance!
+
+ @seealso -
+
+ @param -
+ @return -
+
+ @onerror -
+ *//*-*****************************************************************************************************/
+
+ sal_Bool HasAddonsMenu () const ;
+ sal_Bool HasAddonsHelpMenu () const ;
+ sal_Int32 GetAddonsToolBarCount() const ;
+ const Sequence< Sequence< PropertyValue > >& GetAddonsMenu () const ;
+ const Sequence< Sequence< PropertyValue > >& GetAddonsMenuBarPart () const ;
+ const Sequence< Sequence< PropertyValue > >& GetAddonsToolBarPart ( sal_uInt32 nIndex ) const ;
+ const ::rtl::OUString GetAddonsToolbarResourceName( sal_uInt32 nIndex ) const;
+ const Sequence< Sequence< PropertyValue > >& GetAddonsHelpMenu () const ;
+ Image GetImageFromURL( const rtl::OUString& aURL, sal_Bool bBig, sal_Bool bHiContrast, sal_Bool bNoScale ) const;
+ const MergeMenuInstructionContainer& GetMergeMenuInstructions() const;
+ bool GetMergeToolbarInstructions( const ::rtl::OUString& rToolbarName, MergeToolbarInstructionContainer& rToolbarInstructions ) const;
+
+ void ReadConfigurationData();
+
+ //-------------------------------------------------------------------------------------------------------------
+ // private methods
+ //-------------------------------------------------------------------------------------------------------------
+
+ private:
+ struct OUStringHashCode
+ {
+ size_t operator()( const ::rtl::OUString& sString ) const
+ {
+ return sString.hashCode();
+ }
+ };
+
+ struct ImageEntry
+ {
+ Image aImageSmall;
+ Image aImageBig;
+ Image aImageSmallHC;
+ Image aImageBigHC;
+
+ Image aImageSmallNoScale;
+ Image aImageBigNoScale;
+ Image aImageSmallHCNoScale;
+ Image aImageBigHCNoScale;
+ };
+
+ typedef std::hash_map< ::rtl::OUString, ImageEntry, OUStringHashCode, ::std::equal_to< ::rtl::OUString > > ImageManager;
+ typedef std::hash_map< ::rtl::OUString, sal_uInt32, OUStringHashCode, ::std::equal_to< ::rtl::OUString > > StringToIndexMap;
+ typedef std::vector< Sequence< Sequence< PropertyValue > > > AddonToolBars;
+ typedef ::std::hash_map< ::rtl::OUString, MergeToolbarInstructionContainer, OUStringHashCode, ::std::equal_to< ::rtl::OUString > > ToolbarMergingInstructions;
+
+ enum ImageSize
+ {
+ IMGSIZE_SMALL,
+ IMGSIZE_BIG
+ };
+
+ /*-****************************************************************************************************//**
+ @short return list of key names of our configuration management which represent oue module tree
+ @descr These methods return the current list of key names! We need it to get needed values from our
+ configuration management!
+
+ @seealso -
+
+ @param "nCount" , returns count of menu entries for "new"
+ @return A list of configuration key names is returned.
+
+ @onerror -
+ *//*-*****************************************************************************************************/
+
+ sal_Bool ReadAddonMenuSet( Sequence< Sequence< PropertyValue > >& aAddonMenuSeq );
+ sal_Bool ReadOfficeMenuBarSet( Sequence< Sequence< PropertyValue > >& aAddonOfficeMenuBarSeq );
+ sal_Bool ReadOfficeToolBarSet( AddonToolBars& rAddonOfficeToolBars, std::vector< rtl::OUString >& rAddonOfficeToolBarResNames );
+ sal_Bool ReadToolBarItemSet( const rtl::OUString rToolBarItemSetNodeName, Sequence< Sequence< PropertyValue > >& aAddonOfficeToolBarSeq );
+ sal_Bool ReadOfficeHelpSet( Sequence< Sequence< PropertyValue > >& aAddonOfficeHelpMenuSeq );
+ sal_Bool ReadImages( ImageManager& aImageManager );
+ sal_Bool ReadMenuMergeInstructions( MergeMenuInstructionContainer& rContainer );
+ sal_Bool ReadToolbarMergeInstructions( ToolbarMergingInstructions& rToolbarMergeMap );
+
+ sal_Bool ReadMergeMenuData( const ::rtl::OUString& aMergeAddonInstructionBase, Sequence< Sequence< PropertyValue > >& rMergeMenu );
+ sal_Bool ReadMergeToolbarData( const ::rtl::OUString& aMergeAddonInstructionBase, Sequence< Sequence< PropertyValue > >& rMergeToolbarItems );
+ sal_Bool ReadMenuItem( const ::rtl::OUString& aMenuItemNodeName, Sequence< PropertyValue >& aMenuItem, sal_Bool bIgnoreSubMenu = sal_False );
+ sal_Bool ReadPopupMenu( const ::rtl::OUString& aPopupMenuNodeName, Sequence< PropertyValue >& aPopupMenu );
+ sal_Bool AppendPopupMenu( Sequence< PropertyValue >& aTargetPopupMenu, const Sequence< PropertyValue >& rSourcePopupMenu );
+ sal_Bool ReadToolBarItem( const ::rtl::OUString& aToolBarItemNodeName, Sequence< PropertyValue >& aToolBarItem );
+ sal_Bool ReadImagesItem( const ::rtl::OUString& aImagesItemNodeName, Sequence< PropertyValue >& aImagesItem );
+ ImageEntry* ReadImageData( const ::rtl::OUString& aImagesNodeName );
+ void ReadAndAssociateImages( const ::rtl::OUString& aURL, const ::rtl::OUString& aImageId );
+ void ReadImageFromURL( ImageSize nImageSize, const ::rtl::OUString& aURL, Image& aImage, Image& aNoScaleImage );
+ sal_Bool HasAssociatedImages( const ::rtl::OUString& aURL );
+ void SubstituteVariables( ::rtl::OUString& aURL );
+
+ sal_Bool ReadSubMenuEntries( const Sequence< ::rtl::OUString >& aSubMenuNodeNames, Sequence< Sequence< PropertyValue > >& rSubMenu );
+ void InsertToolBarSeparator( Sequence< Sequence< PropertyValue > >& rAddonOfficeToolBarSeq );
+ ::rtl::OUString GeneratePrefixURL();
+
+ Sequence< ::rtl::OUString > GetPropertyNamesMergeMenuInstruction( const ::rtl::OUString& aPropertyRootName ) const;
+ Sequence< ::rtl::OUString > GetPropertyNamesMenuItem( const ::rtl::OUString& aPropertyRootNode ) const;
+ Sequence< ::rtl::OUString > GetPropertyNamesPopupMenu( const ::rtl::OUString& aPropertyRootNode ) const;
+ Sequence< ::rtl::OUString > GetPropertyNamesToolBarItem( const ::rtl::OUString& aPropertyRootNode ) const;
+ Sequence< ::rtl::OUString > GetPropertyNamesImages( const ::rtl::OUString& aPropertyRootNode ) const;
+ sal_Bool CreateImageFromSequence( Image& rImage, sal_Bool bBig, Sequence< sal_Int8 >& rBitmapDataSeq ) const;
+
+ //-------------------------------------------------------------------------------------------------------------
+ // private member
+ //-------------------------------------------------------------------------------------------------------------
+
+ private:
+ ImageEntry* ReadOptionalImageData( const ::rtl::OUString& aMenuNodeName );
+
+ sal_Int32 m_nRootAddonPopupMenuId;
+ ::rtl::OUString m_aPropNames[PROPERTYCOUNT_INDEX];
+ ::rtl::OUString m_aPropImagesNames[PROPERTYCOUNT_IMAGES];
+ ::rtl::OUString m_aPropMergeMenuNames[PROPERTYCOUNT_MERGE_MENUBAR];
+ ::rtl::OUString m_aPropMergeToolbarNames[PROPERTYCOUNT_MERGE_TOOLBAR];
+ ::rtl::OUString m_aEmpty;
+ ::rtl::OUString m_aPathDelimiter;
+ ::rtl::OUString m_aSeparator;
+ ::rtl::OUString m_aRootAddonPopupMenuURLPrexfix;
+ ::rtl::OUString m_aPrivateImageURL;
+ Sequence< Sequence< PropertyValue > > m_aCachedMenuProperties;
+ Sequence< Sequence< PropertyValue > > m_aCachedMenuBarPartProperties;
+ AddonToolBars m_aCachedToolBarPartProperties;
+ std::vector< rtl::OUString > m_aCachedToolBarPartResourceNames;
+ Sequence< Sequence< PropertyValue > > m_aCachedHelpMenuProperties;
+ Reference< com::sun::star::util::XMacroExpander > m_xMacroExpander;
+ ImageManager m_aImageManager;
+ Sequence< Sequence< PropertyValue > > m_aEmptyAddonToolBar;
+ MergeMenuInstructionContainer m_aCachedMergeMenuInsContainer;
+ ToolbarMergingInstructions m_aCachedToolbarMergingInstructions;
+};
+
+//_________________________________________________________________________________________________________________
+// definitions
+//_________________________________________________________________________________________________________________
+
+//*****************************************************************************************************************
+// constructor
+//*****************************************************************************************************************
+AddonsOptions_Impl::AddonsOptions_Impl()
+ // Init baseclasses first
+ : ConfigItem( ROOTNODE_ADDONMENU ),
+ m_nRootAddonPopupMenuId( 0 ),
+ m_aPathDelimiter( PATHDELIMITER ),
+ m_aSeparator( SEPARATOR_URL ),
+ m_aRootAddonPopupMenuURLPrexfix( ADDONSPOPUPMENU_URL_PREFIX ),
+ m_aPrivateImageURL( PRIVATE_IMAGE_URL )
+{
+ // initialize array with fixed property names
+ m_aPropNames[ INDEX_URL ] = PROPERTYNAME_URL;
+ m_aPropNames[ INDEX_TITLE ] = PROPERTYNAME_TITLE;
+ m_aPropNames[ INDEX_TARGET ] = PROPERTYNAME_TARGET;
+ m_aPropNames[ INDEX_IMAGEIDENTIFIER ] = PROPERTYNAME_IMAGEIDENTIFIER;
+ m_aPropNames[ INDEX_CONTEXT ] = PROPERTYNAME_CONTEXT;
+ m_aPropNames[ INDEX_SUBMENU ] = PROPERTYNAME_SUBMENU; // Submenu set!
+ m_aPropNames[ INDEX_CONTROLTYPE ] = PROPERTYNAME_CONTROLTYPE;
+ m_aPropNames[ INDEX_WIDTH ] = PROPERTYNAME_WIDTH;
+
+ // initialize array with fixed images property names
+ m_aPropImagesNames[ OFFSET_IMAGES_SMALL ] = PROPERTYNAME_IMAGESMALL;
+ m_aPropImagesNames[ OFFSET_IMAGES_BIG ] = PROPERTYNAME_IMAGEBIG;
+ m_aPropImagesNames[ OFFSET_IMAGES_SMALLHC ] = PROPERTYNAME_IMAGESMALLHC;
+ m_aPropImagesNames[ OFFSET_IMAGES_BIGHC ] = PROPERTYNAME_IMAGEBIGHC;
+ m_aPropImagesNames[ OFFSET_IMAGES_SMALL_URL ] = PROPERTYNAME_IMAGESMALL_URL;
+ m_aPropImagesNames[ OFFSET_IMAGES_BIG_URL ] = PROPERTYNAME_IMAGEBIG_URL;
+ m_aPropImagesNames[ OFFSET_IMAGES_SMALLHC_URL ] = PROPERTYNAME_IMAGESMALLHC_URL;
+ m_aPropImagesNames[ OFFSET_IMAGES_BIGHC_URL ] = PROPERTYNAME_IMAGEBIGHC_URL;
+
+ // initialize array with fixed merge menu property names
+ m_aPropMergeMenuNames[ OFFSET_MERGEMENU_MERGEPOINT ] = PROPERTYNAME_MERGEMENU_MERGEPOINT;
+ m_aPropMergeMenuNames[ OFFSET_MERGEMENU_MERGECOMMAND ] = PROPERTYNAME_MERGEMENU_MERGECOMMAND;
+ m_aPropMergeMenuNames[ OFFSET_MERGEMENU_MERGECOMMANDPARAMETER ] = PROPERTYNAME_MERGEMENU_MERGECOMMANDPARAMETER;
+ m_aPropMergeMenuNames[ OFFSET_MERGEMENU_MERGEFALLBACK ] = PROPERTYNAME_MERGEMENU_MERGEFALLBACK;
+ m_aPropMergeMenuNames[ OFFSET_MERGEMENU_MERGECONTEXT ] = PROPERTYNAME_MERGEMENU_MERGECONTEXT;
+ m_aPropMergeMenuNames[ OFFSET_MERGEMENU_MENUITEMS ] = PROPERTYNAME_MERGEMENU_MENUITEMS;
+
+ m_aPropMergeToolbarNames[ OFFSET_MERGETOOLBAR_TOOLBAR ] = PROPERTYNAME_MERGETOOLBAR_TOOLBAR;
+ m_aPropMergeToolbarNames[ OFFSET_MERGETOOLBAR_MERGEPOINT ] = PROPERTYNAME_MERGETOOLBAR_MERGEPOINT;
+ m_aPropMergeToolbarNames[ OFFSET_MERGETOOLBAR_MERGECOMMAND ] = PROPERTYNAME_MERGETOOLBAR_MERGECOMMAND;
+ m_aPropMergeToolbarNames[ OFFSET_MERGETOOLBAR_MERGECOMMANDPARAMETER ] = PROPERTYNAME_MERGETOOLBAR_MERGECOMMANDPARAMETER;
+ m_aPropMergeToolbarNames[ OFFSET_MERGETOOLBAR_MERGEFALLBACK ] = PROPERTYNAME_MERGETOOLBAR_MERGEFALLBACK;
+ m_aPropMergeToolbarNames[ OFFSET_MERGETOOLBAR_MERGECONTEXT ] = PROPERTYNAME_MERGETOOLBAR_MERGECONTEXT;
+ m_aPropMergeToolbarNames[ OFFSET_MERGETOOLBAR_TOOLBARITEMS ] = PROPERTYNAME_MERGETOOLBAR_TOOLBARITEMS;
+
+ Reference< XComponentContext > xContext;
+ Reference< com::sun::star::beans::XPropertySet > xProps( ::comphelper::getProcessServiceFactory(), UNO_QUERY );
+ xProps->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" ))) >>= xContext;
+ if ( xContext.is() )
+ {
+ m_xMacroExpander = Reference< com::sun::star::util::XMacroExpander >( xContext->getValueByName(
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/singletons/com.sun.star.util.theMacroExpander"))),
+ UNO_QUERY );
+ }
+
+ ReadConfigurationData();
+
+ // Enable notification mechanism of ouer baseclass.
+ // We need it to get information about changes outside these class on ouer used configuration keys!
+ Sequence< rtl::OUString > aNotifySeq( 1 );
+ aNotifySeq[0] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "AddonUI" ));
+ EnableNotification( aNotifySeq );
+}
+
+//*****************************************************************************************************************
+// destructor
+//*****************************************************************************************************************
+AddonsOptions_Impl::~AddonsOptions_Impl()
+{
+ // We must save our current values .. if user forget it!
+ if( IsModified() == sal_True )
+ {
+ Commit();
+ }
+}
+
+void AddonsOptions_Impl::ReadConfigurationData()
+{
+ // reset members to be read again from configuration
+ m_aCachedMenuProperties = Sequence< Sequence< PropertyValue > >();
+ m_aCachedMenuBarPartProperties = Sequence< Sequence< PropertyValue > >();
+ m_aCachedToolBarPartProperties = AddonToolBars();
+ m_aCachedHelpMenuProperties = Sequence< Sequence< PropertyValue > >();
+ m_aCachedToolBarPartResourceNames.clear();
+ m_aImageManager = ImageManager();
+
+ ReadAddonMenuSet( m_aCachedMenuProperties );
+ ReadOfficeMenuBarSet( m_aCachedMenuBarPartProperties );
+ ReadOfficeToolBarSet( m_aCachedToolBarPartProperties, m_aCachedToolBarPartResourceNames );
+ ReadOfficeHelpSet( m_aCachedHelpMenuProperties );
+ ReadImages( m_aImageManager );
+
+ m_aCachedMergeMenuInsContainer.clear();
+ m_aCachedToolbarMergingInstructions.clear();
+
+ ReadMenuMergeInstructions( m_aCachedMergeMenuInsContainer );
+ ReadToolbarMergeInstructions( m_aCachedToolbarMergingInstructions );
+}
+
+//*****************************************************************************************************************
+// public method
+//*****************************************************************************************************************
+void AddonsOptions_Impl::Notify( const Sequence< ::rtl::OUString >& /*lPropertyNames*/ )
+{
+ Application::PostUserEvent( STATIC_LINK( 0, AddonsOptions, Notify ) );
+}
+
+//*****************************************************************************************************************
+// public method
+//*****************************************************************************************************************
+void AddonsOptions_Impl::Commit()
+{
+ DBG_ERROR( "AddonsOptions_Impl::Commit()\nNot implemented yet!\n" );
+}
+
+//*****************************************************************************************************************
+// public method
+//*****************************************************************************************************************
+sal_Bool AddonsOptions_Impl::HasAddonsMenu() const
+{
+ return ( m_aCachedMenuProperties.getLength() > 0 );
+}
+
+//*****************************************************************************************************************
+// public method
+//*****************************************************************************************************************
+sal_Bool AddonsOptions_Impl::HasAddonsHelpMenu () const
+{
+ return ( m_aCachedHelpMenuProperties.getLength() > 0 );
+}
+
+//*****************************************************************************************************************
+// public method
+//*****************************************************************************************************************
+sal_Int32 AddonsOptions_Impl::GetAddonsToolBarCount() const
+{
+ return m_aCachedToolBarPartProperties.size();
+}
+
+//*****************************************************************************************************************
+// public method
+//*****************************************************************************************************************
+const Sequence< Sequence< PropertyValue > >& AddonsOptions_Impl::GetAddonsMenu() const
+{
+ return m_aCachedMenuProperties;
+}
+
+//*****************************************************************************************************************
+// public method
+//*****************************************************************************************************************
+const Sequence< Sequence< PropertyValue > >& AddonsOptions_Impl::GetAddonsMenuBarPart() const
+{
+ return m_aCachedMenuBarPartProperties;
+}
+
+//*****************************************************************************************************************
+// public method
+//*****************************************************************************************************************
+const Sequence< Sequence< PropertyValue > >& AddonsOptions_Impl::GetAddonsToolBarPart( sal_uInt32 nIndex ) const
+{
+ if ( /*nIndex >= 0 &&*/ nIndex < m_aCachedToolBarPartProperties.size() )
+ return m_aCachedToolBarPartProperties[nIndex];
+ else
+ return m_aEmptyAddonToolBar;
+}
+
+//*****************************************************************************************************************
+// public method
+//*****************************************************************************************************************
+const ::rtl::OUString AddonsOptions_Impl::GetAddonsToolbarResourceName( sal_uInt32 nIndex ) const
+{
+ if ( nIndex < m_aCachedToolBarPartResourceNames.size() )
+ return m_aCachedToolBarPartResourceNames[nIndex];
+ else
+ return rtl::OUString();
+}
+
+//*****************************************************************************************************************
+// public method
+//*****************************************************************************************************************
+const Sequence< Sequence< PropertyValue > >& AddonsOptions_Impl::GetAddonsHelpMenu () const
+{
+ return m_aCachedHelpMenuProperties;
+}
+
+//*****************************************************************************************************************
+// public method
+//*****************************************************************************************************************
+const MergeMenuInstructionContainer& AddonsOptions_Impl::GetMergeMenuInstructions() const
+{
+ return m_aCachedMergeMenuInsContainer;
+}
+
+//*****************************************************************************************************************
+// public method
+//*****************************************************************************************************************
+bool AddonsOptions_Impl::GetMergeToolbarInstructions(
+ const ::rtl::OUString& rToolbarName,
+ MergeToolbarInstructionContainer& rToolbarInstructions ) const
+{
+ ToolbarMergingInstructions::const_iterator pIter = m_aCachedToolbarMergingInstructions.find( rToolbarName );
+ if ( pIter != m_aCachedToolbarMergingInstructions.end() )
+ {
+ rToolbarInstructions = pIter->second;
+ return true;
+ }
+ else
+ return false;
+}
+
+//*****************************************************************************************************************
+// public method
+//*****************************************************************************************************************
+Image AddonsOptions_Impl::GetImageFromURL( const rtl::OUString& aURL, sal_Bool bBig, sal_Bool bHiContrast, sal_Bool bNoScale ) const
+{
+ Image aImage;
+
+ ImageManager::const_iterator pIter = m_aImageManager.find( aURL );
+ if ( pIter != m_aImageManager.end() )
+ {
+ if ( !bHiContrast )
+ {
+ if ( bNoScale )
+ aImage = ( bBig ? pIter->second.aImageBigNoScale : pIter->second.aImageSmallNoScale );
+ if ( !aImage )
+ aImage = ( bBig ? pIter->second.aImageBig : pIter->second.aImageSmall );
+ }
+ else
+ {
+ if ( bNoScale )
+ aImage = ( bBig ? pIter->second.aImageBigHCNoScale : pIter->second.aImageSmallHCNoScale );
+ if ( !aImage )
+ aImage = ( bBig ? pIter->second.aImageBigHC : pIter->second.aImageSmallHC );
+ }
+ }
+
+ return aImage;
+}
+
+//*****************************************************************************************************************
+// private method
+//*****************************************************************************************************************
+sal_Bool AddonsOptions_Impl::ReadAddonMenuSet( Sequence< Sequence< PropertyValue > >& rAddonMenuSeq )
+{
+ // Read the AddonMenu set and fill property sequences
+ ::rtl::OUString aAddonMenuNodeName( RTL_CONSTASCII_USTRINGPARAM( "AddonUI/AddonMenu" ));
+ Sequence< ::rtl::OUString > aAddonMenuNodeSeq = GetNodeNames( aAddonMenuNodeName );
+ ::rtl::OUString aAddonMenuItemNode( aAddonMenuNodeName + m_aPathDelimiter );
+
+ sal_uInt32 nCount = aAddonMenuNodeSeq.getLength();
+ sal_uInt32 nIndex = 0;
+ Sequence< PropertyValue > aMenuItem( PROPERTYCOUNT_MENUITEM );
+
+ // Init the property value sequence
+ aMenuItem[ OFFSET_MENUITEM_URL ].Name = m_aPropNames[ INDEX_URL ];
+ aMenuItem[ OFFSET_MENUITEM_TITLE ].Name = m_aPropNames[ INDEX_TITLE ];
+ aMenuItem[ OFFSET_MENUITEM_TARGET ].Name = m_aPropNames[ INDEX_TARGET ];
+ aMenuItem[ OFFSET_MENUITEM_IMAGEIDENTIFIER ].Name = m_aPropNames[ INDEX_IMAGEIDENTIFIER];
+ aMenuItem[ OFFSET_MENUITEM_CONTEXT ].Name = m_aPropNames[ INDEX_CONTEXT ];
+ aMenuItem[ OFFSET_MENUITEM_SUBMENU ].Name = m_aPropNames[ INDEX_SUBMENU ]; // Submenu set!
+
+ for ( sal_uInt32 n = 0; n < nCount; n++ )
+ {
+ ::rtl::OUString aRootMenuItemNode( aAddonMenuItemNode + aAddonMenuNodeSeq[n] );
+
+ // Read the MenuItem
+ if ( ReadMenuItem( aRootMenuItemNode, aMenuItem ) )
+ {
+ // Successfully read a menu item, append to our list
+ sal_uInt32 nMenuItemCount = rAddonMenuSeq.getLength() + 1;
+ rAddonMenuSeq.realloc( nMenuItemCount );
+ rAddonMenuSeq[nIndex++] = aMenuItem;
+ }
+ }
+
+ return ( rAddonMenuSeq.getLength() > 0 );
+}
+
+//*****************************************************************************************************************
+// private method
+//*****************************************************************************************************************
+sal_Bool AddonsOptions_Impl::ReadOfficeHelpSet( Sequence< Sequence< PropertyValue > >& rAddonOfficeHelpMenuSeq )
+{
+ // Read the AddonMenu set and fill property sequences
+ ::rtl::OUString aAddonHelpMenuNodeName( RTL_CONSTASCII_USTRINGPARAM( "AddonUI/OfficeHelp" ));
+ Sequence< ::rtl::OUString > aAddonHelpMenuNodeSeq = GetNodeNames( aAddonHelpMenuNodeName );
+ ::rtl::OUString aAddonHelpMenuItemNode( aAddonHelpMenuNodeName + m_aPathDelimiter );
+
+ sal_uInt32 nCount = aAddonHelpMenuNodeSeq.getLength();
+ sal_uInt32 nIndex = 0;
+ Sequence< PropertyValue > aMenuItem( PROPERTYCOUNT_MENUITEM );
+
+ // Init the property value sequence
+ aMenuItem[ OFFSET_MENUITEM_URL ].Name = m_aPropNames[ INDEX_URL ];
+ aMenuItem[ OFFSET_MENUITEM_TITLE ].Name = m_aPropNames[ INDEX_TITLE ];
+ aMenuItem[ OFFSET_MENUITEM_TARGET ].Name = m_aPropNames[ INDEX_TARGET ];
+ aMenuItem[ OFFSET_MENUITEM_IMAGEIDENTIFIER ].Name = m_aPropNames[ INDEX_IMAGEIDENTIFIER];
+ aMenuItem[ OFFSET_MENUITEM_CONTEXT ].Name = m_aPropNames[ INDEX_CONTEXT ];
+ aMenuItem[ OFFSET_MENUITEM_SUBMENU ].Name = m_aPropNames[ INDEX_SUBMENU ]; // Submenu set!
+
+ for ( sal_uInt32 n = 0; n < nCount; n++ )
+ {
+ ::rtl::OUString aRootMenuItemNode( aAddonHelpMenuItemNode + aAddonHelpMenuNodeSeq[n] );
+
+ // Read the MenuItem
+ if ( ReadMenuItem( aRootMenuItemNode, aMenuItem, sal_True ) )
+ {
+ // Successfully read a menu item, append to our list
+ sal_uInt32 nMenuItemCount = rAddonOfficeHelpMenuSeq.getLength() + 1;
+ rAddonOfficeHelpMenuSeq.realloc( nMenuItemCount );
+ rAddonOfficeHelpMenuSeq[nIndex++] = aMenuItem;
+ }
+ }
+
+ return ( rAddonOfficeHelpMenuSeq.getLength() > 0 );
+}
+
+//*****************************************************************************************************************
+// private method
+//*****************************************************************************************************************
+sal_Bool AddonsOptions_Impl::ReadOfficeMenuBarSet( Sequence< Sequence< PropertyValue > >& rAddonOfficeMenuBarSeq )
+{
+ // Read the OfficeMenuBar set and fill property sequences
+ ::rtl::OUString aAddonMenuBarNodeName( RTL_CONSTASCII_USTRINGPARAM( "AddonUI/OfficeMenuBar" ));
+ Sequence< ::rtl::OUString > aAddonMenuBarNodeSeq = GetNodeNames( aAddonMenuBarNodeName );
+ ::rtl::OUString aAddonMenuBarNode( aAddonMenuBarNodeName + m_aPathDelimiter );
+
+ sal_uInt32 nCount = aAddonMenuBarNodeSeq.getLength();
+ sal_uInt32 nIndex = 0;
+ Sequence< PropertyValue > aPopupMenu( PROPERTYCOUNT_POPUPMENU );
+
+ // Init the property value sequence
+ aPopupMenu[ OFFSET_POPUPMENU_TITLE ].Name = m_aPropNames[ INDEX_TITLE ];
+ aPopupMenu[ OFFSET_POPUPMENU_CONTEXT ].Name = m_aPropNames[ INDEX_CONTEXT];
+ aPopupMenu[ OFFSET_POPUPMENU_SUBMENU ].Name = m_aPropNames[ INDEX_SUBMENU];
+ aPopupMenu[ OFFSET_POPUPMENU_URL ].Name = m_aPropNames[ INDEX_URL ];
+
+ StringToIndexMap aTitleToIndexMap;
+
+ for ( sal_uInt32 n = 0; n < nCount; n++ )
+ {
+ ::rtl::OUString aPopupMenuNode( aAddonMenuBarNode + aAddonMenuBarNodeSeq[n] );
+
+ // Read the MenuItem
+ if ( ReadPopupMenu( aPopupMenuNode, aPopupMenu ) )
+ {
+ // Successfully read a popup menu, append to our list
+ ::rtl::OUString aPopupTitle;
+ if ( aPopupMenu[OFFSET_POPUPMENU_TITLE].Value >>= aPopupTitle )
+ {
+ StringToIndexMap::const_iterator pIter = aTitleToIndexMap.find( aPopupTitle );
+ if ( pIter != aTitleToIndexMap.end() )
+ {
+ // title already there => concat both popup menus
+ Sequence< PropertyValue >& rOldPopupMenu = rAddonOfficeMenuBarSeq[pIter->second];
+ AppendPopupMenu( rOldPopupMenu, aPopupMenu );
+ }
+ else
+ {
+ // not found
+ sal_uInt32 nMenuItemCount = rAddonOfficeMenuBarSeq.getLength() + 1;
+ rAddonOfficeMenuBarSeq.realloc( nMenuItemCount );
+ rAddonOfficeMenuBarSeq[nIndex] = aPopupMenu;
+ aTitleToIndexMap.insert( StringToIndexMap::value_type( aPopupTitle, nIndex ));
+ ++nIndex;
+ }
+ }
+ }
+ }
+
+ return ( rAddonOfficeMenuBarSeq.getLength() > 0 );
+}
+
+//*****************************************************************************************************************
+// private method
+//*****************************************************************************************************************
+sal_Bool AddonsOptions_Impl::ReadOfficeToolBarSet( AddonToolBars& rAddonOfficeToolBars, std::vector< rtl::OUString >& rAddonOfficeToolBarResNames )
+{
+ // Read the OfficeToolBar set and fill property sequences
+ ::rtl::OUString aAddonToolBarNodeName( RTL_CONSTASCII_USTRINGPARAM( "AddonUI/OfficeToolBar" ));
+ Sequence< ::rtl::OUString > aAddonToolBarNodeSeq = GetNodeNames( aAddonToolBarNodeName );
+ ::rtl::OUString aAddonToolBarNode( aAddonToolBarNodeName + m_aPathDelimiter );
+
+ sal_uInt32 nCount = aAddonToolBarNodeSeq.getLength();
+
+ for ( sal_uInt32 n = 0; n < nCount; n++ )
+ {
+ ::rtl::OUString aToolBarItemNode( aAddonToolBarNode + aAddonToolBarNodeSeq[n] );
+ rAddonOfficeToolBarResNames.push_back( aAddonToolBarNodeSeq[n] );
+ rAddonOfficeToolBars.push_back( m_aEmptyAddonToolBar );
+ ReadToolBarItemSet( aToolBarItemNode, rAddonOfficeToolBars[n] );
+ }
+
+ return ( !rAddonOfficeToolBars.empty() );
+}
+
+
+//*****************************************************************************************************************
+// private method
+//*****************************************************************************************************************
+sal_Bool AddonsOptions_Impl::ReadToolBarItemSet( const rtl::OUString rToolBarItemSetNodeName, Sequence< Sequence< PropertyValue > >& rAddonOfficeToolBarSeq )
+{
+ sal_Bool bInsertSeparator = sal_False;
+ sal_uInt32 nToolBarItemCount = rAddonOfficeToolBarSeq.getLength();
+ ::rtl::OUString aAddonToolBarItemSetNode( rToolBarItemSetNodeName + m_aPathDelimiter );
+ Sequence< ::rtl::OUString > aAddonToolBarItemSetNodeSeq = GetNodeNames( rToolBarItemSetNodeName );
+ Sequence< PropertyValue > aToolBarItem( PROPERTYCOUNT_TOOLBARITEM );
+
+ // Init the property value sequence
+ aToolBarItem[ OFFSET_TOOLBARITEM_URL ].Name = m_aPropNames[ INDEX_URL ];
+ aToolBarItem[ OFFSET_TOOLBARITEM_TITLE ].Name = m_aPropNames[ INDEX_TITLE ];
+ aToolBarItem[ OFFSET_TOOLBARITEM_IMAGEIDENTIFIER ].Name = m_aPropNames[ INDEX_IMAGEIDENTIFIER];
+ aToolBarItem[ OFFSET_TOOLBARITEM_TARGET ].Name = m_aPropNames[ INDEX_TARGET ];
+ aToolBarItem[ OFFSET_TOOLBARITEM_CONTEXT ].Name = m_aPropNames[ INDEX_CONTEXT ];
+ aToolBarItem[ OFFSET_TOOLBARITEM_CONTROLTYPE ].Name = m_aPropNames[ INDEX_CONTROLTYPE ];
+ aToolBarItem[ OFFSET_TOOLBARITEM_WIDTH ].Name = m_aPropNames[ INDEX_WIDTH ];
+
+ sal_uInt32 nCount = aAddonToolBarItemSetNodeSeq.getLength();
+ for ( sal_uInt32 n = 0; n < nCount; n++ )
+ {
+ ::rtl::OUString aToolBarItemNode( aAddonToolBarItemSetNode + aAddonToolBarItemSetNodeSeq[n] );
+
+ // Read the ToolBarItem
+ if ( ReadToolBarItem( aToolBarItemNode, aToolBarItem ) )
+ {
+ if ( bInsertSeparator )
+ {
+ bInsertSeparator = sal_False;
+ InsertToolBarSeparator( rAddonOfficeToolBarSeq );
+ }
+
+ // Successfully read a toolbar item, append to our list
+ sal_uInt32 nAddonCount = rAddonOfficeToolBarSeq.getLength();
+ rAddonOfficeToolBarSeq.realloc( nAddonCount+1 );
+ rAddonOfficeToolBarSeq[nAddonCount] = aToolBarItem;
+ }
+ }
+
+ return ( (sal_uInt32)rAddonOfficeToolBarSeq.getLength() > nToolBarItemCount );
+}
+
+//*****************************************************************************************************************
+// private method
+//*****************************************************************************************************************
+void AddonsOptions_Impl::InsertToolBarSeparator( Sequence< Sequence< PropertyValue > >& rAddonOfficeToolBarSeq )
+{
+ Sequence< PropertyValue > aToolBarItem( PROPERTYCOUNT_TOOLBARITEM );
+
+ aToolBarItem[ OFFSET_TOOLBARITEM_URL ].Name = m_aPropNames[ INDEX_URL ];
+ aToolBarItem[ OFFSET_TOOLBARITEM_TITLE ].Name = m_aPropNames[ INDEX_TITLE ];
+ aToolBarItem[ OFFSET_TOOLBARITEM_IMAGEIDENTIFIER ].Name = m_aPropNames[ INDEX_IMAGEIDENTIFIER];
+ aToolBarItem[ OFFSET_TOOLBARITEM_TARGET ].Name = m_aPropNames[ INDEX_TARGET ];
+ aToolBarItem[ OFFSET_TOOLBARITEM_CONTEXT ].Name = m_aPropNames[ INDEX_CONTEXT ];
+
+ aToolBarItem[ OFFSET_TOOLBARITEM_URL ].Value <<= SEPARATOR_URL;
+ aToolBarItem[ OFFSET_TOOLBARITEM_TITLE ].Value <<= m_aEmpty;
+ aToolBarItem[ OFFSET_TOOLBARITEM_TARGET ].Value <<= m_aEmpty;
+ aToolBarItem[ OFFSET_TOOLBARITEM_IMAGEIDENTIFIER ].Value <<= m_aEmpty;
+ aToolBarItem[ OFFSET_TOOLBARITEM_CONTEXT ].Value <<= m_aEmpty;
+
+ sal_uInt32 nToolBarItemCount = rAddonOfficeToolBarSeq.getLength();
+ rAddonOfficeToolBarSeq.realloc( nToolBarItemCount+1 );
+ rAddonOfficeToolBarSeq[nToolBarItemCount] = aToolBarItem;
+}
+
+//*****************************************************************************************************************
+// private method
+//*****************************************************************************************************************
+sal_Bool AddonsOptions_Impl::ReadImages( ImageManager& aImageManager )
+{
+ // Read the user-defined Images set and fill image manager
+ ::rtl::OUString aAddonImagesNodeName( RTL_CONSTASCII_USTRINGPARAM( "AddonUI/Images" ));
+ Sequence< ::rtl::OUString > aAddonImagesNodeSeq = GetNodeNames( aAddonImagesNodeName );
+ ::rtl::OUString aAddonImagesNode( aAddonImagesNodeName + m_aPathDelimiter );
+
+ sal_uInt32 nCount = aAddonImagesNodeSeq.getLength();
+
+ // Init the property value sequence
+ Sequence< ::rtl::OUString > aAddonImageItemNodePropNames( 1 );
+ ::rtl::OUString aURL;
+
+ for ( sal_uInt32 n = 0; n < nCount; n++ )
+ {
+ ::rtl::OUString aImagesItemNode( aAddonImagesNode + aAddonImagesNodeSeq[n] );
+
+ // Create sequence for data access
+ ::rtl::OUStringBuffer aBuffer( aImagesItemNode );
+ aBuffer.append( m_aPathDelimiter );
+ aBuffer.append( m_aPropNames[ OFFSET_MENUITEM_URL ] );
+ aAddonImageItemNodePropNames[0] = aBuffer.makeStringAndClear();
+
+ Sequence< Any > aAddonImageItemNodeValues = GetProperties( aAddonImageItemNodePropNames );
+
+ // An user-defined image entry must have an URL. As "ImageIdentifier" has a higher priority
+ // we also check if we already have an images association.
+ if (( aAddonImageItemNodeValues[0] >>= aURL ) &&
+ aURL.getLength() > 0 &&
+ !HasAssociatedImages( aURL ))
+ {
+ ::rtl::OUStringBuffer aBuf( aImagesItemNode );
+ aBuf.append( m_aPathDelimiter );
+ aBuf.append( IMAGES_NODENAME );
+ aBuf.append( m_aPathDelimiter );
+ ::rtl::OUString aImagesUserDefinedItemNode = aBuf.makeStringAndClear();
+
+ // Read a user-defined images data
+ ImageEntry* pImageEntry = ReadImageData( aImagesUserDefinedItemNode );
+ if ( pImageEntry )
+ {
+ // Successfully read a user-defined images item, put it into our image manager
+ aImageManager.insert( ImageManager::value_type( aURL, *pImageEntry ));
+ delete pImageEntry; // We have the ownership of the pointer
+ }
+ }
+ }
+
+ return sal_True;
+}
+
+//*****************************************************************************************************************
+// private method
+//*****************************************************************************************************************
+
+::rtl::OUString AddonsOptions_Impl::GeneratePrefixURL()
+{
+ // Create an unique prefixed Add-On popup menu URL so it can be identified later as a runtime popup menu.
+ // They use a different image manager, so they must be identified by the sfx2/framework code.
+ ::rtl::OUString aPopupMenuURL;
+ ::rtl::OUStringBuffer aBuf( m_aRootAddonPopupMenuURLPrexfix.getLength() + 3 );
+ aBuf.append( m_aRootAddonPopupMenuURLPrexfix );
+ aBuf.append( ::rtl::OUString::valueOf( ++m_nRootAddonPopupMenuId ));
+ aPopupMenuURL = aBuf.makeStringAndClear();
+ return aPopupMenuURL;
+}
+
+//*****************************************************************************************************************
+// private method
+//*****************************************************************************************************************
+
+sal_Bool AddonsOptions_Impl::ReadMenuMergeInstructions( MergeMenuInstructionContainer& aContainer )
+{
+ const ::rtl::OUString aMenuMergeRootName( RTL_CONSTASCII_USTRINGPARAM( "AddonUI/OfficeMenuBarMerging/" ));
+
+ Sequence< ::rtl::OUString > aAddonMergeNodesSeq = GetNodeNames( aMenuMergeRootName );
+ ::rtl::OUString aAddonMergeNode( aMenuMergeRootName );
+
+ sal_uInt32 nCount = aAddonMergeNodesSeq.getLength();
+
+ // Init the property value sequence
+ Sequence< ::rtl::OUString > aNodePropNames( 5 );
+ ::rtl::OUString aURL;
+
+ for ( sal_uInt32 i = 0; i < nCount; i++ )
+ {
+ ::rtl::OUString aMergeAddonInstructions( aAddonMergeNode + aAddonMergeNodesSeq[i] );
+
+ Sequence< ::rtl::OUString > aAddonInstMergeNodesSeq = GetNodeNames( aMergeAddonInstructions );
+ sal_uInt32 nCountAddons = aAddonInstMergeNodesSeq.getLength();
+
+ for ( sal_uInt32 j = 0; j < nCountAddons; j++ )
+ {
+ ::rtl::OUStringBuffer aMergeAddonInstructionBase( aMergeAddonInstructions );
+ aMergeAddonInstructionBase.append( m_aPathDelimiter );
+ aMergeAddonInstructionBase.append( aAddonInstMergeNodesSeq[j] );
+ aMergeAddonInstructionBase.append( m_aPathDelimiter );
+
+ // Create sequence for data access
+ ::rtl::OUStringBuffer aBuffer( aMergeAddonInstructionBase );
+ aBuffer.append( m_aPropMergeMenuNames[ OFFSET_MERGEMENU_MERGEPOINT ] );
+ aNodePropNames[0] = aBuffer.makeStringAndClear();
+
+ aBuffer = aMergeAddonInstructionBase;
+ aBuffer.append( m_aPropMergeMenuNames[ OFFSET_MERGEMENU_MERGECOMMAND ] );
+ aNodePropNames[1] = aBuffer.makeStringAndClear();
+
+ aBuffer = aMergeAddonInstructionBase;
+ aBuffer.append( m_aPropMergeMenuNames[ OFFSET_MERGEMENU_MERGECOMMANDPARAMETER ] );
+ aNodePropNames[2] = aBuffer.makeStringAndClear();
+
+ aBuffer = aMergeAddonInstructionBase;
+ aBuffer.append( m_aPropMergeMenuNames[ OFFSET_MERGEMENU_MERGEFALLBACK ] );
+ aNodePropNames[3] = aBuffer.makeStringAndClear();
+
+ aBuffer = aMergeAddonInstructionBase;
+ aBuffer.append( m_aPropMergeMenuNames[ OFFSET_MERGEMENU_MERGECONTEXT ] );
+ aNodePropNames[4] = aBuffer.makeStringAndClear();
+
+ Sequence< Any > aNodePropValues = GetProperties( aNodePropNames );
+
+ MergeMenuInstruction aMergeMenuInstruction;
+ aNodePropValues[0] >>= aMergeMenuInstruction.aMergePoint;
+ aNodePropValues[1] >>= aMergeMenuInstruction.aMergeCommand;
+ aNodePropValues[2] >>= aMergeMenuInstruction.aMergeCommandParameter;
+ aNodePropValues[3] >>= aMergeMenuInstruction.aMergeFallback;
+ aNodePropValues[4] >>= aMergeMenuInstruction.aMergeContext;
+
+ ::rtl::OUString aMergeMenuBase = aMergeAddonInstructionBase.makeStringAndClear();
+ ReadMergeMenuData( aMergeMenuBase, aMergeMenuInstruction.aMergeMenu );
+
+ aContainer.push_back( aMergeMenuInstruction );
+ }
+ }
+
+ return sal_True;
+}
+
+//*****************************************************************************************************************
+// private method
+//*****************************************************************************************************************
+sal_Bool AddonsOptions_Impl::ReadMergeMenuData( const ::rtl::OUString& aMergeAddonInstructionBase, Sequence< Sequence< PropertyValue > >& rMergeMenu )
+{
+ ::rtl::OUString aMergeMenuBaseNode( aMergeAddonInstructionBase+m_aPropMergeMenuNames[ OFFSET_MERGEMENU_MENUITEMS ] );
+
+ Sequence< ::rtl::OUString > aSubMenuNodeNames = GetNodeNames( aMergeMenuBaseNode );
+ aMergeMenuBaseNode += m_aPathDelimiter;
+
+ // extend the node names to have full path strings
+ for ( sal_uInt32 i = 0; i < (sal_uInt32)aSubMenuNodeNames.getLength(); i++ )
+ aSubMenuNodeNames[i] = ::rtl::OUString( aMergeMenuBaseNode + aSubMenuNodeNames[i] );
+
+ return ReadSubMenuEntries( aSubMenuNodeNames, rMergeMenu );
+}
+
+//*****************************************************************************************************************
+// private method
+//*****************************************************************************************************************
+sal_Bool AddonsOptions_Impl::ReadToolbarMergeInstructions( ToolbarMergingInstructions& rCachedToolbarMergingInstructions )
+{
+ const ::rtl::OUString aToolbarMergeRootName( RTL_CONSTASCII_USTRINGPARAM( "AddonUI/OfficeToolbarMerging/" ));
+
+ Sequence< ::rtl::OUString > aAddonMergeNodesSeq = GetNodeNames( aToolbarMergeRootName );
+ ::rtl::OUString aAddonMergeNode( aToolbarMergeRootName );
+
+ sal_uInt32 nCount = aAddonMergeNodesSeq.getLength();
+
+ // Init the property value sequence
+ Sequence< ::rtl::OUString > aNodePropNames( 6 );
+ ::rtl::OUString aURL;
+
+ for ( sal_uInt32 i = 0; i < nCount; i++ )
+ {
+ ::rtl::OUString aMergeAddonInstructions( aAddonMergeNode + aAddonMergeNodesSeq[i] );
+
+ Sequence< ::rtl::OUString > aAddonInstMergeNodesSeq = GetNodeNames( aMergeAddonInstructions );
+ sal_uInt32 nCountAddons = aAddonInstMergeNodesSeq.getLength();
+
+ for ( sal_uInt32 j = 0; j < nCountAddons; j++ )
+ {
+ ::rtl::OUStringBuffer aMergeAddonInstructionBase( aMergeAddonInstructions );
+ aMergeAddonInstructionBase.append( m_aPathDelimiter );
+ aMergeAddonInstructionBase.append( aAddonInstMergeNodesSeq[j] );
+ aMergeAddonInstructionBase.append( m_aPathDelimiter );
+
+ // Create sequence for data access
+ ::rtl::OUStringBuffer aBuffer( aMergeAddonInstructionBase );
+ aBuffer.append( m_aPropMergeToolbarNames[ OFFSET_MERGETOOLBAR_TOOLBAR ] );
+ aNodePropNames[0] = aBuffer.makeStringAndClear();
+
+ aBuffer = aMergeAddonInstructionBase;
+ aBuffer.append( m_aPropMergeToolbarNames[ OFFSET_MERGETOOLBAR_MERGEPOINT ] );
+ aNodePropNames[1] = aBuffer.makeStringAndClear();
+
+ aBuffer = aMergeAddonInstructionBase;
+ aBuffer.append( m_aPropMergeToolbarNames[ OFFSET_MERGETOOLBAR_MERGECOMMAND ] );
+ aNodePropNames[2] = aBuffer.makeStringAndClear();
+
+ aBuffer = aMergeAddonInstructionBase;
+ aBuffer.append( m_aPropMergeToolbarNames[ OFFSET_MERGETOOLBAR_MERGECOMMANDPARAMETER ] );
+ aNodePropNames[3] = aBuffer.makeStringAndClear();
+
+ aBuffer = aMergeAddonInstructionBase;
+ aBuffer.append( m_aPropMergeToolbarNames[ OFFSET_MERGETOOLBAR_MERGEFALLBACK ] );
+ aNodePropNames[4] = aBuffer.makeStringAndClear();
+
+ aBuffer = aMergeAddonInstructionBase;
+ aBuffer.append( m_aPropMergeToolbarNames[ OFFSET_MERGETOOLBAR_MERGECONTEXT ] );
+ aNodePropNames[5] = aBuffer.makeStringAndClear();
+
+ Sequence< Any > aNodePropValues = GetProperties( aNodePropNames );
+
+ MergeToolbarInstruction aMergeToolbarInstruction;
+ aNodePropValues[0] >>= aMergeToolbarInstruction.aMergeToolbar;
+ aNodePropValues[1] >>= aMergeToolbarInstruction.aMergePoint;
+ aNodePropValues[2] >>= aMergeToolbarInstruction.aMergeCommand;
+ aNodePropValues[3] >>= aMergeToolbarInstruction.aMergeCommandParameter;
+ aNodePropValues[4] >>= aMergeToolbarInstruction.aMergeFallback;
+ aNodePropValues[5] >>= aMergeToolbarInstruction.aMergeContext;
+
+ ReadMergeToolbarData( aMergeAddonInstructionBase.makeStringAndClear(),
+ aMergeToolbarInstruction.aMergeToolbarItems );
+
+ MergeToolbarInstructionContainer& rVector = rCachedToolbarMergingInstructions[ aMergeToolbarInstruction.aMergeToolbar ];
+ rVector.push_back( aMergeToolbarInstruction );
+ }
+ }
+
+ return sal_True;
+}
+
+//*****************************************************************************************************************
+// private method
+//*****************************************************************************************************************
+sal_Bool AddonsOptions_Impl::ReadMergeToolbarData( const ::rtl::OUString& aMergeAddonInstructionBase, Sequence< Sequence< PropertyValue > >& rMergeToolbarItems )
+{
+ ::rtl::OUStringBuffer aBuffer( aMergeAddonInstructionBase );
+ aBuffer.append( m_aPropMergeToolbarNames[ OFFSET_MERGETOOLBAR_TOOLBARITEMS ] );
+
+ ::rtl::OUString aMergeToolbarBaseNode = aBuffer.makeStringAndClear();
+
+ return ReadToolBarItemSet( aMergeToolbarBaseNode, rMergeToolbarItems );
+}
+
+//*****************************************************************************************************************
+// private method
+//*****************************************************************************************************************
+sal_Bool AddonsOptions_Impl::ReadMenuItem( const ::rtl::OUString& aMenuNodeName, Sequence< PropertyValue >& aMenuItem, sal_Bool bIgnoreSubMenu )
+{
+ sal_Bool bResult = sal_False;
+ ::rtl::OUString aStrValue;
+ ::rtl::OUString aAddonMenuItemTreeNode( aMenuNodeName + m_aPathDelimiter );
+ Sequence< Any > aMenuItemNodePropValues;
+
+ aMenuItemNodePropValues = GetProperties( GetPropertyNamesMenuItem( aAddonMenuItemTreeNode ) );
+ if (( aMenuItemNodePropValues[ OFFSET_MENUITEM_TITLE ] >>= aStrValue ) && aStrValue.getLength() > 0 )
+ {
+ aMenuItem[ OFFSET_MENUITEM_TITLE ].Value <<= aStrValue;
+
+ ::rtl::OUString aRootSubMenuName( aAddonMenuItemTreeNode + m_aPropNames[ INDEX_SUBMENU ] );
+ Sequence< ::rtl::OUString > aRootSubMenuNodeNames = GetNodeNames( aRootSubMenuName );
+ if ( aRootSubMenuNodeNames.getLength() > 0 && !bIgnoreSubMenu )
+ {
+ // Set a unique prefixed Add-On popup menu URL so it can be identified later
+ ::rtl::OUString aPopupMenuURL = GeneratePrefixURL();
+ ::rtl::OUString aPopupMenuImageId;
+
+ aMenuItemNodePropValues[ OFFSET_MENUITEM_IMAGEIDENTIFIER ] >>= aPopupMenuImageId;
+ ReadAndAssociateImages( aPopupMenuURL, aPopupMenuImageId );
+
+ // A popup menu must have a title and can have a URL and ImageIdentifier
+ // Set the other property values to empty
+ aMenuItem[ OFFSET_MENUITEM_URL ].Value <<= aPopupMenuURL;
+ aMenuItem[ OFFSET_MENUITEM_TARGET ].Value <<= m_aEmpty;
+ aMenuItem[ OFFSET_MENUITEM_IMAGEIDENTIFIER ].Value <<= aPopupMenuImageId;
+ aMenuItem[ OFFSET_MENUITEM_CONTEXT ].Value <<= aMenuItemNodePropValues[ OFFSET_MENUITEM_CONTEXT ];
+
+ // Continue to read the sub menu nodes
+ Sequence< Sequence< PropertyValue > > aSubMenuSeq;
+ ::rtl::OUString aSubMenuRootNodeName( aRootSubMenuName + m_aPathDelimiter );
+ for ( sal_uInt32 n = 0; n < (sal_uInt32)aRootSubMenuNodeNames.getLength(); n++ )
+ aRootSubMenuNodeNames[n] = ::rtl::OUString( aSubMenuRootNodeName + aRootSubMenuNodeNames[n] );
+ ReadSubMenuEntries( aRootSubMenuNodeNames, aSubMenuSeq );
+ aMenuItem[ OFFSET_MENUITEM_SUBMENU ].Value <<= aSubMenuSeq;
+ bResult = sal_True;
+ }
+ else if (( aMenuItemNodePropValues[ OFFSET_MENUITEM_URL ] >>= aStrValue ) && aStrValue.getLength() > 0 )
+ {
+ // A simple menu item => read the other properties;
+ ::rtl::OUString aMenuImageId;
+
+ aMenuItemNodePropValues[ OFFSET_MENUITEM_IMAGEIDENTIFIER ] >>= aMenuImageId;
+ ReadAndAssociateImages( aStrValue, aMenuImageId );
+
+ aMenuItem[ OFFSET_MENUITEM_URL ].Value <<= aStrValue;
+ aMenuItem[ OFFSET_MENUITEM_TARGET ].Value <<= aMenuItemNodePropValues[ OFFSET_MENUITEM_TARGET ];
+ aMenuItem[ OFFSET_MENUITEM_IMAGEIDENTIFIER ].Value <<= aMenuImageId;
+ aMenuItem[ OFFSET_MENUITEM_CONTEXT ].Value <<= aMenuItemNodePropValues[ OFFSET_MENUITEM_CONTEXT ];
+ aMenuItem[ OFFSET_MENUITEM_SUBMENU ].Value <<= Sequence< Sequence< PropertyValue > >(); // Submenu set!
+
+ bResult = sal_True;
+ }
+ }
+ else if (( aMenuItemNodePropValues[ OFFSET_MENUITEM_URL ] >>= aStrValue ) &&
+ aStrValue.equalsAsciiL( SEPARATOR_URL_STR, SEPARATOR_URL_LEN ))
+ {
+ // Separator
+ aMenuItem[ OFFSET_MENUITEM_URL ].Value <<= aStrValue;
+ aMenuItem[ OFFSET_MENUITEM_TARGET ].Value <<= m_aEmpty;
+ aMenuItem[ OFFSET_MENUITEM_IMAGEIDENTIFIER ].Value <<= m_aEmpty;
+ aMenuItem[ OFFSET_MENUITEM_CONTEXT ].Value <<= m_aEmpty;
+ aMenuItem[ OFFSET_MENUITEM_SUBMENU ].Value <<= Sequence< Sequence< PropertyValue > >(); // Submenu set!
+ bResult = sal_True;
+ }
+
+ return bResult;
+}
+
+//*****************************************************************************************************************
+// private method
+//*****************************************************************************************************************
+sal_Bool AddonsOptions_Impl::ReadPopupMenu( const ::rtl::OUString& aPopupMenuNodeName, Sequence< PropertyValue >& aPopupMenu )
+{
+ sal_Bool bResult = sal_False;
+ ::rtl::OUString aStrValue;
+ ::rtl::OUString aAddonPopupMenuTreeNode( aPopupMenuNodeName + m_aPathDelimiter );
+ Sequence< Any > aPopupMenuNodePropValues;
+
+ aPopupMenuNodePropValues = GetProperties( GetPropertyNamesPopupMenu( aAddonPopupMenuTreeNode ) );
+ if (( aPopupMenuNodePropValues[ OFFSET_POPUPMENU_TITLE ] >>= aStrValue ) &&
+ aStrValue.getLength() > 0 )
+ {
+ aPopupMenu[ OFFSET_POPUPMENU_TITLE ].Value <<= aStrValue;
+
+ ::rtl::OUString aRootSubMenuName( aAddonPopupMenuTreeNode + m_aPropNames[ INDEX_SUBMENU ] );
+ Sequence< ::rtl::OUString > aRootSubMenuNodeNames = GetNodeNames( aRootSubMenuName );
+ if ( aRootSubMenuNodeNames.getLength() > 0 )
+ {
+ // A top-level popup menu needs a title
+ // Set a unique prefixed Add-On popup menu URL so it can be identified later
+ ::rtl::OUString aPopupMenuURL = GeneratePrefixURL();
+
+ aPopupMenu[ OFFSET_POPUPMENU_URL ].Value <<= aPopupMenuURL;
+ aPopupMenu[ OFFSET_POPUPMENU_CONTEXT ].Value <<= aPopupMenuNodePropValues[ OFFSET_POPUPMENU_CONTEXT ];
+
+ // Continue to read the sub menu nodes
+ Sequence< Sequence< PropertyValue > > aSubMenuSeq;
+ ::rtl::OUString aSubMenuRootNodeName( aRootSubMenuName + m_aPathDelimiter );
+ for ( sal_uInt32 n = 0; n < (sal_uInt32)aRootSubMenuNodeNames.getLength(); n++ )
+ aRootSubMenuNodeNames[n] = ::rtl::OUString( aSubMenuRootNodeName + aRootSubMenuNodeNames[n] );
+ ReadSubMenuEntries( aRootSubMenuNodeNames, aSubMenuSeq );
+ aPopupMenu[ OFFSET_POPUPMENU_SUBMENU ].Value <<= aSubMenuSeq;
+ bResult = sal_True;
+ }
+ }
+
+ return bResult;
+}
+
+//*****************************************************************************************************************
+// private method
+//*****************************************************************************************************************
+sal_Bool AddonsOptions_Impl::AppendPopupMenu( Sequence< PropertyValue >& rTargetPopupMenu, const Sequence< PropertyValue >& rSourcePopupMenu )
+{
+ Sequence< Sequence< PropertyValue > > aTargetSubMenuSeq;
+ Sequence< Sequence< PropertyValue > > aSourceSubMenuSeq;
+
+ if (( rTargetPopupMenu[ OFFSET_POPUPMENU_SUBMENU ].Value >>= aTargetSubMenuSeq ) &&
+ ( rSourcePopupMenu[ OFFSET_POPUPMENU_SUBMENU ].Value >>= aSourceSubMenuSeq ))
+ {
+ sal_uInt32 nIndex = aTargetSubMenuSeq.getLength();
+ aTargetSubMenuSeq.realloc( nIndex + aSourceSubMenuSeq.getLength() );
+ for ( sal_uInt32 i = 0; i < sal_uInt32( aSourceSubMenuSeq.getLength() ); i++ )
+ aTargetSubMenuSeq[nIndex++] = aSourceSubMenuSeq[i];
+ rTargetPopupMenu[ OFFSET_POPUPMENU_SUBMENU ].Value <<= aTargetSubMenuSeq;
+ }
+
+ return sal_True;
+}
+
+//*****************************************************************************************************************
+// private method
+//*****************************************************************************************************************
+sal_Bool AddonsOptions_Impl::ReadToolBarItem( const ::rtl::OUString& aToolBarItemNodeName, Sequence< PropertyValue >& aToolBarItem )
+{
+ sal_Bool bResult = sal_False;
+ ::rtl::OUString aTitle;
+ ::rtl::OUString aURL;
+ ::rtl::OUString aAddonToolBarItemTreeNode( aToolBarItemNodeName + m_aPathDelimiter );
+ Sequence< Any > aToolBarItemNodePropValues;
+
+ aToolBarItemNodePropValues = GetProperties( GetPropertyNamesToolBarItem( aAddonToolBarItemTreeNode ) );
+
+ // A toolbar item must have a command URL
+ if (( aToolBarItemNodePropValues[ OFFSET_TOOLBARITEM_URL ] >>= aURL ) && aURL.getLength() > 0 )
+ {
+ if ( aURL.equals( SEPARATOR_URL ))
+ {
+ // A speparator toolbar item only needs a URL
+ aToolBarItem[ OFFSET_TOOLBARITEM_URL ].Value <<= aURL;
+ aToolBarItem[ OFFSET_TOOLBARITEM_TITLE ].Value <<= m_aEmpty;
+ aToolBarItem[ OFFSET_TOOLBARITEM_TARGET ].Value <<= m_aEmpty;
+ aToolBarItem[ OFFSET_TOOLBARITEM_IMAGEIDENTIFIER ].Value <<= m_aEmpty;
+ aToolBarItem[ OFFSET_TOOLBARITEM_CONTEXT ].Value <<= m_aEmpty;
+ aToolBarItem[ OFFSET_TOOLBARITEM_CONTROLTYPE ].Value <<= m_aEmpty;
+ aToolBarItem[ OFFSET_TOOLBARITEM_WIDTH ].Value <<= sal_Int32( 0 );
+
+ bResult = sal_True;
+ }
+ else if (( aToolBarItemNodePropValues[ OFFSET_TOOLBARITEM_TITLE ] >>= aTitle ) && aTitle.getLength() > 0 )
+ {
+ // A normal toolbar item must also have title => read the other properties;
+ ::rtl::OUString aImageId;
+
+ // Try to map a user-defined image URL to our internal private image URL
+ aToolBarItemNodePropValues[ OFFSET_TOOLBARITEM_IMAGEIDENTIFIER ] >>= aImageId;
+ ReadAndAssociateImages( aURL, aImageId );
+
+ aToolBarItem[ OFFSET_TOOLBARITEM_URL ].Value <<= aURL;
+ aToolBarItem[ OFFSET_TOOLBARITEM_TITLE ].Value <<= aTitle;
+ aToolBarItem[ OFFSET_TOOLBARITEM_TARGET ].Value <<= aToolBarItemNodePropValues[ OFFSET_TOOLBARITEM_TARGET ];
+ aToolBarItem[ OFFSET_TOOLBARITEM_IMAGEIDENTIFIER ].Value <<= aImageId;
+ aToolBarItem[ OFFSET_TOOLBARITEM_CONTEXT ].Value <<= aToolBarItemNodePropValues[ OFFSET_TOOLBARITEM_CONTEXT ];
+ aToolBarItem[ OFFSET_TOOLBARITEM_CONTROLTYPE ].Value <<= aToolBarItemNodePropValues[ OFFSET_TOOLBARITEM_CONTROLTYPE ];
+
+ // Configuration uses hyper for long. Therefore transform into sal_Int32
+ sal_Int64 nValue( 0 );
+ aToolBarItemNodePropValues[ OFFSET_TOOLBARITEM_WIDTH ] >>= nValue;
+ aToolBarItem[ OFFSET_TOOLBARITEM_WIDTH ].Value <<= sal_Int32( nValue );
+
+ bResult = sal_True;
+ }
+ }
+
+ return bResult;
+}
+
+//*****************************************************************************************************************
+// private method
+//*****************************************************************************************************************
+sal_Bool AddonsOptions_Impl::ReadSubMenuEntries( const Sequence< ::rtl::OUString >& aSubMenuNodeNames, Sequence< Sequence< PropertyValue > >& rSubMenuSeq )
+{
+ Sequence< PropertyValue > aMenuItem( PROPERTYCOUNT_MENUITEM );
+
+ // Init the property value sequence
+ aMenuItem[ OFFSET_MENUITEM_URL ].Name = PROPERTYNAME_URL;
+ aMenuItem[ OFFSET_MENUITEM_TITLE ].Name = PROPERTYNAME_TITLE;
+ aMenuItem[ OFFSET_MENUITEM_TARGET ].Name = PROPERTYNAME_TARGET;
+ aMenuItem[ OFFSET_MENUITEM_IMAGEIDENTIFIER ].Name = PROPERTYNAME_IMAGEIDENTIFIER;
+ aMenuItem[ OFFSET_MENUITEM_CONTEXT ].Name = PROPERTYNAME_CONTEXT;
+ aMenuItem[ OFFSET_MENUITEM_SUBMENU ].Name = PROPERTYNAME_SUBMENU; // Submenu set!
+
+ sal_uInt32 nIndex = 0;
+ sal_uInt32 nCount = aSubMenuNodeNames.getLength();
+ for ( sal_uInt32 n = 0; n < nCount; n++ )
+ {
+ if ( ReadMenuItem( aSubMenuNodeNames[n], aMenuItem ))
+ {
+ sal_uInt32 nSubMenuCount = rSubMenuSeq.getLength() + 1;
+ rSubMenuSeq.realloc( nSubMenuCount );
+ rSubMenuSeq[nIndex++] = aMenuItem;
+ }
+ }
+
+ return sal_True;
+}
+
+//*****************************************************************************************************************
+// private method
+//*****************************************************************************************************************
+sal_Bool AddonsOptions_Impl::HasAssociatedImages( const ::rtl::OUString& aURL )
+{
+ ImageManager::const_iterator pIter = m_aImageManager.find( aURL );
+ return ( pIter != m_aImageManager.end() );
+}
+
+//*****************************************************************************************************************
+// private method
+//*****************************************************************************************************************
+void AddonsOptions_Impl::SubstituteVariables( ::rtl::OUString& aURL )
+{
+ if (( aURL.compareToAscii( RTL_CONSTASCII_STRINGPARAM( EXPAND_PROTOCOL )) == 0 ) &&
+ m_xMacroExpander.is() )
+ {
+ // cut protocol
+ ::rtl::OUString macro( aURL.copy( sizeof ( EXPAND_PROTOCOL ) -1 ) );
+ // decode uric class chars
+ macro = ::rtl::Uri::decode(
+ macro, rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8 );
+ // expand macro string
+ aURL = m_xMacroExpander->expandMacros( macro );
+ }
+}
+
+//*****************************************************************************************************************
+// private method
+//*****************************************************************************************************************
+void AddonsOptions_Impl::ReadImageFromURL( ImageSize nImageSize, const ::rtl::OUString& aImageURL, Image& aImage, Image& aImageNoScale )
+{
+ SvStream* pStream = UcbStreamHelper::CreateStream( aImageURL, STREAM_STD_READ );
+ if ( pStream && ( pStream->GetErrorCode() == 0 ))
+ {
+ // Use graphic class to also support more graphic formats (bmp,png,...)
+ Graphic aGraphic;
+
+ GraphicFilter* pGF = GraphicFilter::GetGraphicFilter();
+ pGF->ImportGraphic( aGraphic, String(), *pStream, GRFILTER_FORMAT_DONTKNOW );
+
+ BitmapEx aBitmapEx = aGraphic.GetBitmapEx();
+
+ const Size aSize = ( nImageSize == IMGSIZE_SMALL ) ? aImageSizeSmall : aImageSizeBig; // Sizes used for menu/toolbox images
+
+ Size aBmpSize = aBitmapEx.GetSizePixel();
+ if ( aBmpSize.Width() > 0 && aBmpSize.Height() > 0 )
+ {
+ // Support non-transparent bitmaps to be downward compatible with OOo 1.1.x addons
+ if( !aBitmapEx.IsTransparent() )
+ aBitmapEx = BitmapEx( aBitmapEx.GetBitmap(), COL_LIGHTMAGENTA );
+
+ // A non-scaled bitmap can have a flexible width, but must have a defined height!
+ Size aNoScaleSize( aBmpSize.Width(), aSize.Height() );
+ if ( aBmpSize != aNoScaleSize )
+ {
+ BitmapEx aNoScaleBmp( aBitmapEx );
+ aNoScaleBmp.Scale( aNoScaleSize, BMP_SCALE_INTERPOLATE );
+ }
+ else
+ aImageNoScale = Image( aBitmapEx );
+
+ if ( aBmpSize != aSize )
+ aBitmapEx.Scale( aSize, BMP_SCALE_INTERPOLATE );
+
+ aImage = Image( aBitmapEx );
+ }
+ }
+
+ delete pStream;
+}
+
+//*****************************************************************************************************************
+// private method
+//*****************************************************************************************************************
+void AddonsOptions_Impl::ReadAndAssociateImages( const ::rtl::OUString& aURL, const ::rtl::OUString& aImageId )
+{
+ const int MAX_NUM_IMAGES = 4;
+ const char* aExtArray[MAX_NUM_IMAGES] = { "_16", "_26", "_16h", "_26h" };
+ const char* pBmpExt = ".bmp";
+
+ if ( aImageId.getLength() == 0 )
+ return;
+
+ bool bImageFound = true;
+ ImageEntry aImageEntry;
+ ::rtl::OUString aImageURL( aImageId );
+
+ SubstituteVariables( aImageURL );
+
+ // Loop to create the four possible image names and try to read the bitmap files
+ for ( int i = 0; i < MAX_NUM_IMAGES; i++ )
+ {
+ ::rtl::OUStringBuffer aFileURL( aImageURL );
+ aFileURL.appendAscii( aExtArray[i] );
+ aFileURL.appendAscii( pBmpExt );
+
+ Image aImage;
+ Image aImageNoScale;
+ ReadImageFromURL( ((i==0)||(i==2)) ? IMGSIZE_SMALL : IMGSIZE_BIG, aFileURL.makeStringAndClear(), aImage, aImageNoScale );
+ if ( !!aImage )
+ {
+ bImageFound = true;
+ switch ( i )
+ {
+ case 0:
+ aImageEntry.aImageSmall = aImage;
+ aImageEntry.aImageSmallNoScale = aImageNoScale;
+ break;
+ case 1:
+ aImageEntry.aImageBig = aImage;
+ aImageEntry.aImageBigNoScale = aImageNoScale;
+ break;
+ case 2:
+ aImageEntry.aImageSmallHC = aImage;
+ aImageEntry.aImageSmallHCNoScale = aImageNoScale;
+ break;
+ case 3:
+ aImageEntry.aImageBigHC = aImage;
+ aImageEntry.aImageBigHCNoScale = aImageNoScale;
+ break;
+ }
+ }
+ }
+
+ if ( bImageFound )
+ m_aImageManager.insert( ImageManager::value_type( aURL, aImageEntry ));
+}
+
+//*****************************************************************************************************************
+// private method
+//*****************************************************************************************************************
+AddonsOptions_Impl::ImageEntry* AddonsOptions_Impl::ReadImageData( const ::rtl::OUString& aImagesNodeName )
+{
+ Sequence< ::rtl::OUString > aImageDataNodeNames = GetPropertyNamesImages( aImagesNodeName );
+ Sequence< Any > aPropertyData;
+ Sequence< sal_Int8 > aImageDataSeq;
+ ::rtl::OUString aImageURL;
+
+ ImageEntry* pEntry = NULL;
+
+ // It is possible to use both forms (embedded image data and URLs to external bitmap files) at the
+ // same time. Embedded image data has a higher priority.
+ aPropertyData = GetProperties( aImageDataNodeNames );
+ for ( int i = 0; i < PROPERTYCOUNT_IMAGES; i++ )
+ {
+ if ( i < PROPERTYCOUNT_EMBEDDED_IMAGES )
+ {
+ // Extract image data from the embedded hex binary sequence
+ Image aImage;
+ if (( aPropertyData[i] >>= aImageDataSeq ) &&
+ aImageDataSeq.getLength() > 0 &&
+ ( CreateImageFromSequence( aImage,
+ (( i == OFFSET_IMAGES_BIG ) ||
+ ( i == OFFSET_IMAGES_BIGHC )),
+ aImageDataSeq )) )
+ {
+ if ( !pEntry )
+ pEntry = new ImageEntry;
+
+ if ( i == OFFSET_IMAGES_SMALL )
+ pEntry->aImageSmall = aImage;
+ else if ( i == OFFSET_IMAGES_BIG )
+ pEntry->aImageBig = aImage;
+ else if ( i == OFFSET_IMAGES_SMALLHC )
+ pEntry->aImageSmallHC = aImage;
+ else
+ pEntry->aImageBigHC = aImage;
+ }
+ }
+ else
+ {
+ // Retrieve image data from a external bitmap file. Make sure that embedded image data
+ // has a higher priority.
+ aPropertyData[i] >>= aImageURL;
+
+ if ( aImageURL.getLength() > 0 )
+ {
+ Image aImage;
+ Image aImageNoScale;
+
+ SubstituteVariables( aImageURL );
+ ReadImageFromURL( ((i==OFFSET_IMAGES_SMALL_URL)||(i==OFFSET_IMAGES_SMALLHC_URL)) ? IMGSIZE_SMALL : IMGSIZE_BIG,
+ aImageURL, aImage, aImageNoScale );
+ if ( !!aImage )
+ {
+ if ( !pEntry )
+ pEntry = new ImageEntry;
+
+ if ( i == OFFSET_IMAGES_SMALL_URL && !pEntry->aImageSmall )
+ {
+ pEntry->aImageSmall = aImage;
+ pEntry->aImageSmallNoScale = aImageNoScale;
+ }
+ else if ( i == OFFSET_IMAGES_BIG_URL && !pEntry->aImageBig )
+ {
+ pEntry->aImageBig = aImage;
+ pEntry->aImageBigNoScale = aImageNoScale;
+ }
+ else if ( i == OFFSET_IMAGES_SMALLHC_URL && !pEntry->aImageSmallHC )
+ {
+ pEntry->aImageSmallHC = aImage;
+ pEntry->aImageSmallHCNoScale = aImageNoScale;
+ }
+ else if ( !pEntry->aImageBigHC )
+ {
+ pEntry->aImageBigHC = aImage;
+ pEntry->aImageBigHCNoScale = aImageNoScale;
+ }
+ }
+ }
+ }
+ }
+
+ return pEntry;
+}
+
+//*****************************************************************************************************************
+// private method
+//*****************************************************************************************************************
+sal_Bool AddonsOptions_Impl::CreateImageFromSequence( Image& rImage, sal_Bool bBig, Sequence< sal_Int8 >& rBitmapDataSeq ) const
+{
+ sal_Bool bResult = sal_False;
+ Size aSize = bBig ? aImageSizeBig : aImageSizeSmall; // Sizes used for menu/toolbox images
+
+ if ( rBitmapDataSeq.getLength() > 0 )
+ {
+ SvMemoryStream aMemStream( rBitmapDataSeq.getArray(), rBitmapDataSeq.getLength(), STREAM_STD_READ );
+ BitmapEx aBitmapEx;
+
+ aMemStream >> aBitmapEx;
+
+ // Scale bitmap to fit the correct size for the menu/toolbar. Use best quality
+ if ( aBitmapEx.GetSizePixel() != aSize )
+ aBitmapEx.Scale( aSize, BMP_SCALE_INTERPOLATE );
+
+ if( !aBitmapEx.IsTransparent() )
+ {
+ // Support non-transparent bitmaps to be downward compatible with OOo 1.1.x addons
+ aBitmapEx = BitmapEx( aBitmapEx.GetBitmap(), COL_LIGHTMAGENTA );
+ }
+
+ rImage = Image( aBitmapEx );
+ bResult = sal_True;
+ }
+
+ return bResult;
+}
+
+//*****************************************************************************************************************
+// private methods
+//*****************************************************************************************************************
+Sequence< ::rtl::OUString > AddonsOptions_Impl::GetPropertyNamesMergeMenuInstruction( const ::rtl::OUString& aPropertyRootNode ) const
+{
+ Sequence< ::rtl::OUString > lResult( PROPERTYCOUNT_MERGE_MENUBAR );
+
+ // Create property names dependent from the root node name
+ lResult[ OFFSET_MERGEMENU_MERGEPOINT ] = ::rtl::OUString( aPropertyRootNode + m_aPropMergeMenuNames[ OFFSET_MERGEMENU_MERGEPOINT ] );
+ lResult[ OFFSET_MERGEMENU_MERGECOMMAND ] = ::rtl::OUString( aPropertyRootNode + m_aPropMergeMenuNames[ OFFSET_MERGEMENU_MERGECOMMAND ] );
+ lResult[ OFFSET_MERGEMENU_MERGECOMMANDPARAMETER ] = ::rtl::OUString( aPropertyRootNode + m_aPropMergeMenuNames[ OFFSET_MERGEMENU_MERGECOMMANDPARAMETER ] );
+ lResult[ OFFSET_MERGEMENU_MERGEFALLBACK ] = ::rtl::OUString( aPropertyRootNode + m_aPropMergeMenuNames[ OFFSET_MERGEMENU_MERGEFALLBACK ] );
+ lResult[ OFFSET_MERGEMENU_MERGECONTEXT ] = ::rtl::OUString( aPropertyRootNode + m_aPropMergeMenuNames[ OFFSET_MERGEMENU_MERGECONTEXT ] );
+ lResult[ OFFSET_MERGEMENU_MENUITEMS ] = ::rtl::OUString( aPropertyRootNode + m_aPropMergeMenuNames[ OFFSET_MERGEMENU_MENUITEMS ] );
+
+ return lResult;
+}
+
+Sequence< ::rtl::OUString > AddonsOptions_Impl::GetPropertyNamesMenuItem( const ::rtl::OUString& aPropertyRootNode ) const
+{
+ Sequence< ::rtl::OUString > lResult( PROPERTYCOUNT_MENUITEM );
+
+ // Create property names dependent from the root node name
+ lResult[OFFSET_MENUITEM_URL] = ::rtl::OUString( aPropertyRootNode + m_aPropNames[ INDEX_URL ] );
+ lResult[OFFSET_MENUITEM_TITLE] = ::rtl::OUString( aPropertyRootNode + m_aPropNames[ INDEX_TITLE ] );
+ lResult[OFFSET_MENUITEM_IMAGEIDENTIFIER] = ::rtl::OUString( aPropertyRootNode + m_aPropNames[ INDEX_IMAGEIDENTIFIER ] );
+ lResult[OFFSET_MENUITEM_TARGET] = ::rtl::OUString( aPropertyRootNode + m_aPropNames[ INDEX_TARGET ] );
+ lResult[OFFSET_MENUITEM_CONTEXT] = ::rtl::OUString( aPropertyRootNode + m_aPropNames[ INDEX_CONTEXT ] );
+ lResult[OFFSET_MENUITEM_SUBMENU] = ::rtl::OUString( aPropertyRootNode + m_aPropNames[ INDEX_SUBMENU ] );
+
+ return lResult;
+}
+
+//*****************************************************************************************************************
+// private method
+//*****************************************************************************************************************
+Sequence< ::rtl::OUString > AddonsOptions_Impl::GetPropertyNamesPopupMenu( const ::rtl::OUString& aPropertyRootNode ) const
+{
+ // The URL is automatically set and not read from the configuration.
+ Sequence< ::rtl::OUString > lResult( PROPERTYCOUNT_POPUPMENU-1 );
+
+ // Create property names dependent from the root node name
+ lResult[OFFSET_POPUPMENU_TITLE] = ::rtl::OUString( aPropertyRootNode + m_aPropNames[ INDEX_TITLE ] );
+ lResult[OFFSET_POPUPMENU_CONTEXT] = ::rtl::OUString( aPropertyRootNode + m_aPropNames[ INDEX_CONTEXT ] );
+ lResult[OFFSET_POPUPMENU_SUBMENU] = ::rtl::OUString( aPropertyRootNode + m_aPropNames[ INDEX_SUBMENU ] );
+
+ return lResult;
+}
+
+//*****************************************************************************************************************
+// private method
+//*****************************************************************************************************************
+Sequence< ::rtl::OUString > AddonsOptions_Impl::GetPropertyNamesToolBarItem( const ::rtl::OUString& aPropertyRootNode ) const
+{
+ Sequence< ::rtl::OUString > lResult( PROPERTYCOUNT_TOOLBARITEM );
+
+ // Create property names dependent from the root node name
+ lResult[0] = ::rtl::OUString( aPropertyRootNode + m_aPropNames[ INDEX_URL ] );
+ lResult[1] = ::rtl::OUString( aPropertyRootNode + m_aPropNames[ INDEX_TITLE ] );
+ lResult[2] = ::rtl::OUString( aPropertyRootNode + m_aPropNames[ INDEX_IMAGEIDENTIFIER] );
+ lResult[3] = ::rtl::OUString( aPropertyRootNode + m_aPropNames[ INDEX_TARGET ] );
+ lResult[4] = ::rtl::OUString( aPropertyRootNode + m_aPropNames[ INDEX_CONTEXT ] );
+ lResult[5] = ::rtl::OUString( aPropertyRootNode + m_aPropNames[ INDEX_CONTROLTYPE ] );
+ lResult[6] = ::rtl::OUString( aPropertyRootNode + m_aPropNames[ INDEX_WIDTH ] );
+
+ return lResult;
+}
+
+//*****************************************************************************************************************
+// private method
+//*****************************************************************************************************************
+Sequence< ::rtl::OUString > AddonsOptions_Impl::GetPropertyNamesImages( const ::rtl::OUString& aPropertyRootNode ) const
+{
+ Sequence< ::rtl::OUString > lResult( PROPERTYCOUNT_IMAGES );
+
+ // Create property names dependent from the root node name
+ lResult[0] = ::rtl::OUString( aPropertyRootNode + m_aPropImagesNames[ OFFSET_IMAGES_SMALL ] );
+ lResult[1] = ::rtl::OUString( aPropertyRootNode + m_aPropImagesNames[ OFFSET_IMAGES_BIG ] );
+ lResult[2] = ::rtl::OUString( aPropertyRootNode + m_aPropImagesNames[ OFFSET_IMAGES_SMALLHC ] );
+ lResult[3] = ::rtl::OUString( aPropertyRootNode + m_aPropImagesNames[ OFFSET_IMAGES_BIGHC ] );
+ lResult[4] = ::rtl::OUString( aPropertyRootNode + m_aPropImagesNames[ OFFSET_IMAGES_SMALL_URL ] );
+ lResult[5] = ::rtl::OUString( aPropertyRootNode + m_aPropImagesNames[ OFFSET_IMAGES_BIG_URL ] );
+ lResult[6] = ::rtl::OUString( aPropertyRootNode + m_aPropImagesNames[ OFFSET_IMAGES_SMALLHC_URL] );
+ lResult[7] = ::rtl::OUString( aPropertyRootNode + m_aPropImagesNames[ OFFSET_IMAGES_BIGHC_URL ] );
+
+ return lResult;
+}
+
+//*****************************************************************************************************************
+// initialize static member
+// DON'T DO IT IN YOUR HEADER!
+// see definition for further informations
+//*****************************************************************************************************************
+AddonsOptions_Impl* AddonsOptions::m_pDataContainer = NULL ;
+sal_Int32 AddonsOptions::m_nRefCount = 0 ;
+
+//*****************************************************************************************************************
+// constructor
+//*****************************************************************************************************************
+AddonsOptions::AddonsOptions()
+{
+ // Global access, must be guarded (multithreading!).
+ MutexGuard aGuard( GetOwnStaticMutex() );
+ // Increase ouer refcount ...
+ ++m_nRefCount;
+ // ... and initialize ouer data container only if it not already exist!
+ if( m_pDataContainer == NULL )
+ {
+ m_pDataContainer = new AddonsOptions_Impl;
+ }
+}
+
+//*****************************************************************************************************************
+// destructor
+//*****************************************************************************************************************
+AddonsOptions::~AddonsOptions()
+{
+ // Global access, must be guarded (multithreading!)
+ MutexGuard aGuard( GetOwnStaticMutex() );
+ // Decrease ouer refcount.
+ --m_nRefCount;
+ // If last instance was deleted ...
+ // we must destroy ouer static data container!
+ if( m_nRefCount <= 0 )
+ {
+ delete m_pDataContainer;
+ m_pDataContainer = NULL;
+ }
+}
+
+//*****************************************************************************************************************
+// public method
+//*****************************************************************************************************************
+sal_Bool AddonsOptions::HasAddonsMenu() const
+{
+ MutexGuard aGuard( GetOwnStaticMutex() );
+ return m_pDataContainer->HasAddonsMenu();
+}
+
+//*****************************************************************************************************************
+// public method
+//*****************************************************************************************************************
+
+sal_Bool AddonsOptions::HasAddonsHelpMenu() const
+{
+ MutexGuard aGuard( GetOwnStaticMutex() );
+ return m_pDataContainer->HasAddonsHelpMenu();
+}
+
+//*****************************************************************************************************************
+// public method
+//*****************************************************************************************************************
+
+sal_Int32 AddonsOptions::GetAddonsToolBarCount() const
+{
+ MutexGuard aGuard( GetOwnStaticMutex() );
+ return m_pDataContainer->GetAddonsToolBarCount();
+}
+
+//*****************************************************************************************************************
+// public method
+//*****************************************************************************************************************
+const Sequence< Sequence< PropertyValue > >& AddonsOptions::GetAddonsMenu() const
+{
+ MutexGuard aGuard( GetOwnStaticMutex() );
+ return m_pDataContainer->GetAddonsMenu();
+}
+
+//*****************************************************************************************************************
+// public method
+//*****************************************************************************************************************
+const Sequence< Sequence< PropertyValue > >& AddonsOptions::GetAddonsMenuBarPart() const
+{
+ MutexGuard aGuard( GetOwnStaticMutex() );
+ return m_pDataContainer->GetAddonsMenuBarPart();
+}
+
+//*****************************************************************************************************************
+// public method
+//*****************************************************************************************************************
+const Sequence< Sequence< PropertyValue > >& AddonsOptions::GetAddonsToolBarPart( sal_uInt32 nIndex ) const
+{
+ MutexGuard aGuard( GetOwnStaticMutex() );
+ return m_pDataContainer->GetAddonsToolBarPart( nIndex );
+}
+
+//*****************************************************************************************************************
+// public method
+//*****************************************************************************************************************
+const ::rtl::OUString AddonsOptions::GetAddonsToolbarResourceName( sal_uInt32 nIndex ) const
+{
+ MutexGuard aGuard( GetOwnStaticMutex() );
+ return m_pDataContainer->GetAddonsToolbarResourceName( nIndex );
+}
+
+//*****************************************************************************************************************
+// public method
+//*****************************************************************************************************************
+const Sequence< Sequence< PropertyValue > >& AddonsOptions::GetAddonsHelpMenu() const
+{
+ MutexGuard aGuard( GetOwnStaticMutex() );
+ return m_pDataContainer->GetAddonsHelpMenu();
+}
+
+//*****************************************************************************************************************
+// public method
+//*****************************************************************************************************************
+const MergeMenuInstructionContainer& AddonsOptions::GetMergeMenuInstructions() const
+{
+ MutexGuard aGuard( GetOwnStaticMutex() );
+ return m_pDataContainer->GetMergeMenuInstructions();
+}
+
+//*****************************************************************************************************************
+// public method
+//*****************************************************************************************************************
+bool AddonsOptions::GetMergeToolbarInstructions(
+ const ::rtl::OUString& rToolbarName,
+ MergeToolbarInstructionContainer& rToolbarInstructions ) const
+{
+ MutexGuard aGuard( GetOwnStaticMutex() );
+ return m_pDataContainer->GetMergeToolbarInstructions(
+ rToolbarName, rToolbarInstructions );
+}
+
+//*****************************************************************************************************************
+// public method
+//*****************************************************************************************************************
+Image AddonsOptions::GetImageFromURL( const rtl::OUString& aURL, sal_Bool bBig, sal_Bool bHiContrast, sal_Bool bNoScale ) const
+{
+ MutexGuard aGuard( GetOwnStaticMutex() );
+ return m_pDataContainer->GetImageFromURL( aURL, bBig, bHiContrast, bNoScale );
+}
+
+//*****************************************************************************************************************
+// public method
+//*****************************************************************************************************************
+Image AddonsOptions::GetImageFromURL( const rtl::OUString& aURL, sal_Bool bBig, sal_Bool bHiContrast ) const
+{
+ return GetImageFromURL( aURL, bBig, bHiContrast, sal_False );
+}
+
+//*****************************************************************************************************************
+// private method
+//*****************************************************************************************************************
+Mutex& AddonsOptions::GetOwnStaticMutex()
+{
+ // Initialize static mutex only for one time!
+ static Mutex* pMutex = NULL;
+ // If these method first called (Mutex not already exist!) ...
+ if( pMutex == NULL )
+ {
+ // ... we must create a new one. Protect follow code with the global mutex -
+ // It must be - we create a static variable!
+ MutexGuard aGuard( Mutex::getGlobalMutex() );
+ // We must check our pointer again - because it can be that another instance of ouer class will be fastr then these!
+ if( pMutex == NULL )
+ {
+ // Create the new mutex and set it for return on static variable.
+ static Mutex aMutex;
+ pMutex = &aMutex;
+ }
+ }
+ // Return new created or already existing mutex object.
+ return *pMutex;
+}
+
+//*****************************************************************************************************************
+// private method
+//*****************************************************************************************************************
+IMPL_STATIC_LINK_NOINSTANCE( AddonsOptions, Notify, void*, EMPTYARG )
+{
+ MutexGuard aGuard( GetOwnStaticMutex() );
+ m_pDataContainer->ReadConfigurationData();
+ return 0;
+}
+
+}
+