Files
libreoffice/framework/source/classes/addonsoptions.cxx
2003-03-25 17:22:13 +00:00

1234 lines
58 KiB
C++

/*************************************************************************
*
* $RCSfile: addonsoptions.cxx,v $
*
* $Revision: 1.2 $
* last change: $Author: hr $ $Date: 2003-03-25 18:21:26 $
*
* The Contents of this file are made available subject to the terms of
* either of the following licenses
*
* - GNU Lesser General Public License Version 2.1
* - Sun Industry Standards Source License Version 1.1
*
* Sun Microsystems Inc., October, 2000
*
* GNU Lesser General Public License Version 2.1
* =============================================
* Copyright 2000 by Sun Microsystems, Inc.
* 901 San Antonio Road, Palo Alto, CA 94303, USA
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License version 2.1, as published by the Free Software Foundation.
*
* This library 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 for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*
*
* Sun Industry Standards Source License Version 1.1
* =================================================
* The contents of this file are subject to the Sun Industry Standards
* Source License Version 1.1 (the "License"); You may not use this file
* except in compliance with the License. You may obtain a copy of the
* License at http://www.openoffice.org/license.html.
*
* Software provided under this License is provided on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
* WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
* MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
* See the License for the specific provisions governing your rights and
* obligations concerning the Software.
*
* The Initial Developer of the Original Code is: Sun Microsystems, Inc.
*
* Copyright: 2000 by Sun Microsystems, Inc.
*
* All Rights Reserved.
*
* Contributor(s): _______________________________________
*
*
************************************************************************/
#pragma hdrstop
//_________________________________________________________________________________________________________________
// includes
//_________________________________________________________________________________________________________________
#ifndef __FRAMEWORK_CLASSES_ADDONSOPTIONS_HXX_
#include <classes/addonsoptions.hxx>
#endif
#ifndef _UTL_CONFIGMGR_HXX_
#include <unotools/configmgr.hxx>
#endif
#ifndef _UTL_CONFIGITEM_HXX_
#include <unotools/configitem.hxx>
#endif
#ifndef _TOOLS_DEBUG_HXX
#include <tools/debug.hxx>
#endif
#ifndef _STREAM_HXX
#include <tools/stream.hxx>
#endif
#ifndef _TOOLS_COLOR_HXX
#include <tools/color.hxx>
#endif
#ifndef _COM_SUN_STAR_UNO_ANY_HXX_
#include <com/sun/star/uno/Any.hxx>
#endif
#ifndef _COM_SUN_STAR_UNO_SEQUENCE_HXX_
#include <com/sun/star/uno/Sequence.hxx>
#endif
#ifndef _RTL_USTRBUF_HXX_
#include <rtl/ustrbuf.hxx>
#endif
#include <hash_map>
#include <algorithm>
//_________________________________________________________________________________________________________________
// namespaces
//_________________________________________________________________________________________________________________
using namespace ::std ;
using namespace ::utl ;
using namespace ::rtl ;
using namespace ::osl ;
using namespace ::com::sun::star::uno ;
using namespace ::com::sun::star::beans ;
//_________________________________________________________________________________________________________________
// const
//_________________________________________________________________________________________________________________
#define ROOTNODE_ADDONMENU OUString(RTL_CONSTASCII_USTRINGPARAM("Office.Addons" ))
#define PATHDELIMITER OUString(RTL_CONSTASCII_USTRINGPARAM("/" ))
#define SEPARATOR_URL OUString(RTL_CONSTASCII_USTRINGPARAM("private:separator"))
#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_SUBMENU ADDONSMENUITEM_PROPERTYNAME_SUBMENU
#define PROPERTYNAME_COMPONENTID ADDONSMENUITEM_PROPERTYNAME_COMPONENTID
#define PROPERTYNAME_CONTEXT ADDONSMENUITEM_PROPERTYNAME_CONTEXT
#define PROPERTYNAME_IMAGESMALL OUString(RTL_CONSTASCII_USTRINGPARAM("ImageSmall" ))
#define PROPERTYNAME_IMAGEBIG OUString(RTL_CONSTASCII_USTRINGPARAM("ImageBig" ))
#define PROPERTYNAME_IMAGESMALLHC OUString(RTL_CONSTASCII_USTRINGPARAM("ImageSmallHC" ))
#define PROPERTYNAME_IMAGEBIGHC OUString(RTL_CONSTASCII_USTRINGPARAM("ImageBigHC" ))
#define IMAGES_NODENAME OUString(RTL_CONSTASCII_USTRINGPARAM("Images" ))
#define PROPERTYCOUNT_ROOT 6 // Used for C++ interface
#define PROPERTYCOUNT_UI_ROOT 7
#define PROPERTYCOUNT 5
#define CFG_PROPERTYCOUNT 4
#define PROPERTYIMAGES_COUNT 4
#define OFFSET_URL 0
#define OFFSET_TITLE 1
#define OFFSET_TARGET 2
#define OFFSET_IMAGEIDENTIFIER 3
#define OFFSET_SUBMENU 4
#define OFFSET_COMPONENTID 5
#define CFG_UITYPE_PROPERTYCOUNT 5
#define OFFSET_UITYPE_TITLE 0
#define OFFSET_UITYPE_TARGET 1
#define OFFSET_UITYPE_IMAGEIDENTIFIER 2
#define OFFSET_UITYPE_CONTEXT 3
#define OFFSET_UITYPE_SUBMENU 4
#define OFFSET_UITYPE_COMPONENTID 5
#define OFFSET_UITYPE_URL 6
#define OFFSET_IMAGESMALL 0
#define OFFSET_IMAGEBIG 1
#define OFFSET_IMAGESMALLHC 2
#define OFFSET_IMAGEBIGHC 3
#define MENUNODENAME_PREFIX OUString(RTL_CONSTASCII_USTRINGPARAM( "m" ))
//_________________________________________________________________________________________________________________
// private declarations!
//_________________________________________________________________________________________________________________
/*-****************************************************************************************************************
@descr struct to hold information about one menu entry.
****************************************************************************************************************-*/
namespace framework
{
struct AddonMenuEntry;
typedef vector< AddonMenuEntry > AddonSubMenu;
struct AddonMenuEntry
{
public:
AddonMenuEntry() {};
AddonMenuEntry( const OUString& sNewURL ,
const OUString& sNewTitle ,
const OUString& sNewImageIdentifier ,
const OUString& sNewTarget ,
const AddonSubMenu& aNewSubMenu ) :
sURL( sNewURL ),
sTitle( sNewTitle ),
sImageIdentifier( sNewImageIdentifier ),
sTarget( sNewTarget ),
aSubMenu( aNewSubMenu )
{
}
void AppendMenuEntry( const AddonMenuEntry& rEntry )
{
aSubMenu.push_back( rEntry );
}
public:
OUString sName ;
OUString sURL ;
OUString sTitle ;
OUString sTarget ;
OUString sImageIdentifier ;
AddonSubMenu aSubMenu ;
};
struct AddonMenuRootEntry
{
public:
AddonMenuRootEntry() {};
AddonMenuRootEntry( const OUString& sNewComponentID ,
const OUString& sNewURL ,
const OUString& sNewTitle ,
const OUString& sNewTarget ,
const OUString& sNewImageIdentifier ,
const OUString& sNewContext ,
const AddonSubMenu& aNewSubMenu ) :
sName( sNewComponentID ),
sURL( sNewURL ),
sTitle( sNewTitle ),
sImageIdentifier( sNewImageIdentifier ),
sTarget( sNewTarget ),
sContext( sNewContext ),
aSubMenu( aNewSubMenu )
{
}
public:
OUString sName ;
OUString sURL ;
OUString sTitle ;
OUString sTarget ;
OUString sImageIdentifier ;
OUString sContext ;
AddonSubMenu aSubMenu ;
};
/*-****************************************************************************************************************
@descr support simple menu structures and operations on it
****************************************************************************************************************-*/
class SvAddonMenu
{
public:
SvAddonMenu() {}
sal_Int32 Size() const { return aAddonsMenuList.size(); }
//---------------------------------------------------------------------------------------------------------
// append sub menu entry
// Assign a unique node name to fulfill to the configuration requirements.
sal_Bool AppendMenuEntry( const rtl::OUString& aComponentID, const AddonMenuEntry& rEntry )
{
for ( sal_uInt32 nIndex = 0; nIndex < aAddonsMenuList.size(); nIndex++ )
{
AddonMenuRootEntry& rAddonMenuRootEntry = aAddonsMenuList[nIndex];
if ( rAddonMenuRootEntry.sName.equals( aComponentID ))
{
rAddonMenuRootEntry.aSubMenu.push_back( rEntry );
return sal_True;
}
}
return sal_False;
}
//---------------------------------------------------------------------------------------------------------
// append root menu entry
void AppendRootMenuEntry( const AddonMenuRootEntry& rEntry )
{
aAddonsMenuList.push_back( rEntry );
}
//---------------------------------------------------------------------------------------------------------
// retrieve a root menu entry from an index
const AddonMenuRootEntry* GetRootMenuEntry( sal_uInt32 nIndex ) const
{
if ( nIndex < aAddonsMenuList.size() )
return &(aAddonsMenuList[nIndex]);
else
return NULL;
}
//---------------------------------------------------------------------------------------------------------
// the only way to free memory!
void Clear()
{
aAddonsMenuList.clear();
}
//---------------------------------------------------------------------------------------------------------
// convert internal list to external format
// for using it on right menus realy
// Notice: We build a property list with 4 entries and set it on result list then.
// The while-loop starts with pointer on internal member list lSetupEntries, change to
// lUserEntries then and stop after that with NULL!
// Separator entries will be packed in another way then normal entries! We define
// special strings "sEmpty" and "sSeperator" to perform too ...
Sequence< Sequence< PropertyValue > > GetList() const;
//---------------------------------------------------------------------------------------------------------
// convert internal submenu to external format
// for using it on right menus realy
// Notice: We build a property list with 4 entries and set it on result list then.
// The while-loop starts with pointer on internal member list lSetupEntries, change to
// lUserEntries then and stop after that with NULL!
// Separator entries will be packed in another way then normal entries! We define
// special strings "sEmpty" and "sSeperator" to perform too ...
Sequence< Sequence< PropertyValue > > GetSubMenuList( const AddonSubMenu& rSubMenu ) const;
//---------------------------------------------------------------------------------------------------------
// convert internal menu bar list to external format
// for using it on right menus realy
// Notice: We build a property list with 4 entries and set it on result list then.
// The while-loop starts with pointer on internal member list lSetupEntries, change to
// lUserEntries then and stop after that with NULL!
// Separator entries will be packed in another way then normal entries! We define
// special strings "sEmpty" and "sSeperator" to perform too ...
Sequence< Sequence< PropertyValue > > SvAddonMenu::GetMenuBarList() const;
private:
//---------------------------------------------------------------------------------------------------------
// search for an entry named "ux" with x=[0..i] inside our menu
// which has set highest number x. So we can add another user entry.
sal_Int32 impl_getNextSubMenuEntryNr( const AddonSubMenu& rSubMenu ) const
{
sal_Int32 nNr = 0;
for( vector< AddonMenuEntry >::const_iterator pItem = rSubMenu.begin() ;
pItem!=rSubMenu.end() ;
++pItem )
{
sal_Int32 nCurrNr = pItem->sName.copy( 1 ).toInt32();
if ( nCurrNr > nNr )
nNr = nCurrNr;
}
return nNr;
}
private:
const OUString sEmpty ;
vector< AddonMenuRootEntry > aAddonsMenuList ;
};
Sequence< Sequence< PropertyValue > > SvAddonMenu::GetList() const
{
sal_Int32 nCount = (sal_Int32)aAddonsMenuList.size();
sal_Int32 nStep = 0;
Sequence< PropertyValue > lRootProperties ( PROPERTYCOUNT_ROOT );
Sequence< Sequence< PropertyValue > > lResult ( nCount );
const vector< AddonMenuRootEntry >* pList = &aAddonsMenuList;
// Root menu item properites
lRootProperties[OFFSET_URL ].Name = PROPERTYNAME_URL ;
lRootProperties[OFFSET_TITLE ].Name = PROPERTYNAME_TITLE ;
lRootProperties[OFFSET_IMAGEIDENTIFIER ].Name = PROPERTYNAME_IMAGEIDENTIFIER ;
lRootProperties[OFFSET_TARGET ].Name = PROPERTYNAME_TARGET ;
lRootProperties[OFFSET_SUBMENU ].Name = PROPERTYNAME_SUBMENU ;
lRootProperties[OFFSET_COMPONENTID ].Name = PROPERTYNAME_COMPONENTID ;
for( vector< AddonMenuRootEntry >::const_iterator pItem =pList->begin();
pItem!=pList->end() ;
++pItem )
{
lRootProperties[OFFSET_URL ].Value <<= pItem->sURL ;
lRootProperties[OFFSET_TITLE ].Value <<= pItem->sTitle ;
lRootProperties[OFFSET_TARGET ].Value <<= pItem->sTarget ;
lRootProperties[OFFSET_IMAGEIDENTIFIER ].Value <<= pItem->sImageIdentifier ;
sal_Int32 nSubMenuCount = pItem->aSubMenu.size();
if ( nSubMenuCount > 0 )
lRootProperties[OFFSET_SUBMENU].Value <<= GetSubMenuList( pItem->aSubMenu );
else
lRootProperties[OFFSET_SUBMENU].Value <<= Sequence< Sequence< PropertyValue > >();
lRootProperties[OFFSET_COMPONENTID ].Value <<= pItem->sName ;
lResult[nStep++] = lRootProperties;
}
return lResult;
}
Sequence< Sequence< PropertyValue > > SvAddonMenu::GetMenuBarList() const
{
sal_Int32 nCount = (sal_Int32)aAddonsMenuList.size();
sal_Int32 nStep = 0;
Sequence< PropertyValue > lRootProperties ( PROPERTYCOUNT_UI_ROOT );
Sequence< Sequence< PropertyValue > > lResult ( nCount );
const vector< AddonMenuRootEntry >* pList = &aAddonsMenuList;
// Root menu bar item properites
lRootProperties[OFFSET_UITYPE_URL ].Name = PROPERTYNAME_URL ;
lRootProperties[OFFSET_UITYPE_TITLE ].Name = PROPERTYNAME_TITLE ;
lRootProperties[OFFSET_UITYPE_IMAGEIDENTIFIER ].Name = PROPERTYNAME_IMAGEIDENTIFIER ;
lRootProperties[OFFSET_UITYPE_IMAGEIDENTIFIER ].Name = PROPERTYNAME_TARGET ;
lRootProperties[OFFSET_UITYPE_SUBMENU ].Name = PROPERTYNAME_SUBMENU ;
lRootProperties[OFFSET_UITYPE_COMPONENTID ].Name = PROPERTYNAME_COMPONENTID ;
lRootProperties[OFFSET_UITYPE_CONTEXT ].Name = PROPERTYNAME_CONTEXT ;
for( vector< AddonMenuRootEntry >::const_iterator pItem =pList->begin();
pItem!=pList->end() ;
++pItem )
{
lRootProperties[OFFSET_UITYPE_URL ].Value <<= pItem->sURL ;
lRootProperties[OFFSET_UITYPE_TITLE ].Value <<= pItem->sTitle ;
lRootProperties[OFFSET_UITYPE_TARGET ].Value <<= pItem->sTarget ;
lRootProperties[OFFSET_UITYPE_IMAGEIDENTIFIER ].Value <<= pItem->sImageIdentifier ;
lRootProperties[OFFSET_UITYPE_CONTEXT ].Value <<= pItem->sContext ;
sal_Int32 nSubMenuCount = pItem->aSubMenu.size();
if ( nSubMenuCount > 0 )
lRootProperties[OFFSET_UITYPE_SUBMENU].Value <<= GetSubMenuList( pItem->aSubMenu );
else
lRootProperties[OFFSET_SUBMENU].Value <<= Sequence< Sequence< PropertyValue > >();
lRootProperties[OFFSET_UITYPE_COMPONENTID ].Value <<= pItem->sName ;
lResult[nStep++] = lRootProperties;
}
return lResult;
}
Sequence< Sequence< PropertyValue > > SvAddonMenu::GetSubMenuList( const AddonSubMenu& rSubMenu ) const
{
const OUString sSeparator( RTL_CONSTASCII_USTRINGPARAM("private:separator") );
// Sub menu item properites
sal_Int32 nStep = 0;
Sequence< PropertyValue > lProperties ( PROPERTYCOUNT );
Sequence< Sequence< PropertyValue > > lResult ( rSubMenu.size() );
lProperties[OFFSET_URL ].Name = PROPERTYNAME_URL ;
lProperties[OFFSET_TITLE ].Name = PROPERTYNAME_TITLE ;
lProperties[OFFSET_TARGET ].Name = PROPERTYNAME_TARGET ;
lProperties[OFFSET_IMAGEIDENTIFIER ].Name = PROPERTYNAME_IMAGEIDENTIFIER ;
lProperties[OFFSET_SUBMENU ].Name = PROPERTYNAME_SUBMENU ;
for( vector< AddonMenuEntry >::const_iterator pItem = rSubMenu.begin() ;
pItem!=rSubMenu.end() ;
++pItem )
{
if ( pItem->sURL == sSeparator )
{
lProperties[OFFSET_URL ].Value <<= sSeparator ;
lProperties[OFFSET_TITLE ].Value <<= sEmpty ;
lProperties[OFFSET_TARGET ].Value <<= sEmpty ;
lProperties[OFFSET_IMAGEIDENTIFIER ].Value <<= sEmpty ;
lProperties[OFFSET_SUBMENU ].Value <<= Sequence< Sequence< PropertyValue > >() ;
}
else
{
lProperties[OFFSET_URL ].Value <<= pItem->sURL ;
lProperties[OFFSET_TITLE ].Value <<= pItem->sTitle ;
lProperties[OFFSET_TARGET ].Value <<= pItem->sTarget ;
lProperties[OFFSET_IMAGEIDENTIFIER ].Value <<= pItem->sImageIdentifier ;
sal_Int32 nSubMenuCount = pItem->aSubMenu.size();
if ( nSubMenuCount > 0 )
lProperties[OFFSET_SUBMENU].Value <<= GetSubMenuList( pItem->aSubMenu );
else
lProperties[OFFSET_SUBMENU].Value <<= Sequence< Sequence< PropertyValue > >();
}
lResult[nStep++] = lProperties;
}
return lResult;
}
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< 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 ;
const Sequence< Sequence< PropertyValue > >& GetAddonsMenu () const ;
const Sequence< Sequence< PropertyValue > >& GetAddonsMenuBarPart() const;
const Sequence< Sequence< PropertyValue > >& GetAddonsToolBarPart() const;
Sequence< PropertyValue > GetAddonsComponentMenu( const ::rtl::OUString aComponentID ) const;
Image GetImageFromURL( const rtl::OUString& aURL, sal_Bool bBig, sal_Bool bHiContrast ) const;
//-------------------------------------------------------------------------------------------------------------
// private methods
//-------------------------------------------------------------------------------------------------------------
private:
/*-****************************************************************************************************//**
@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 ReadRootMenuEntry( const OUString& aRootMenuNodeName, AddonMenuRootEntry& rRootMenuEntry );
sal_Bool ReadRootMenuBarEntry( const OUString& aRootMenuBarNodeName, AddonMenuRootEntry& rRootMenuBarEntry );
sal_Bool ReadSubMenuEntries( const Sequence< OUString >& aSubMenuNodeNames, AddonSubMenu& rSubMenuContainer );
sal_Bool ReadSubMenuEntry( const OUString& aMenuEntryNodeName, AddonSubMenu& rSubMenuContainer );
Sequence< OUString > GetPropertyNames( const OUString& aPropertyRootNode ) const;
Sequence< OUString > GetUITypePropertyNames( const OUString& aPropertyRootNode ) const;
Sequence< OUString > GetImagesPropertyNames( const OUString& aPropertyRootNode ) const;
sal_Bool CreateImageFromSequence( Image& rImage, sal_Bool bBig, Sequence< sal_Int8 >& rBitmapDataSeq ) const;
//-------------------------------------------------------------------------------------------------------------
// private member
//-------------------------------------------------------------------------------------------------------------
private:
struct OUStringHashCode
{
size_t operator()( const ::rtl::OUString& sString ) const
{
return sString.hashCode();
}
};
struct ImageEntry
{
Image aImageSmall;
Image aImageBig;
Image aImageSmallHC;
Image aImageBigHC;
};
ImageEntry* ReadOptionalImageData( const OUString& aMenuNodeName );
void AddImageEntryToImageManager( const OUString& aURL, ImageEntry* pImageEntry );
typedef std::hash_map< OUString, ImageEntry, OUStringHashCode, ::std::equal_to< OUString > > ImageManager;
sal_Int32 m_nRootAddonPopupMenuId;
OUString m_aPropNames[PROPERTYCOUNT_ROOT];
OUString m_aPropUINames[PROPERTYCOUNT_UI_ROOT];
OUString m_aPropImagesNames[PROPERTYIMAGES_COUNT];
OUString m_aEmpty;
OUString m_aPathDelimiter;
OUString m_aSeparator;
OUString m_aRootAddonPopupMenuURLPrexfix;
SvAddonMenu m_aAddonMenu;
SvAddonMenu m_aAddonMenuBarPart;
SvAddonMenu m_aAddonToolBarPart;
Sequence< Sequence< PropertyValue > > m_aCachedMenuProperties;
Sequence< Sequence< PropertyValue > > m_aCachedMenuBarPartProperties;
Sequence< Sequence< PropertyValue > > m_aCachedToolBarPartProperties;
ImageManager m_aImageManager;
};
//_________________________________________________________________________________________________________________
// definitions
//_________________________________________________________________________________________________________________
//*****************************************************************************************************************
// constructor
//*****************************************************************************************************************
AddonsOptions_Impl::AddonsOptions_Impl()
// Init baseclasses first
: ConfigItem( ROOTNODE_ADDONMENU ),
m_aPathDelimiter( PATHDELIMITER ),
m_aSeparator( SEPARATOR_URL ),
m_nRootAddonPopupMenuId( 0 ),
m_aRootAddonPopupMenuURLPrexfix( ADDONSPOPUPMENU_URL_PREFIX )
{
// initialize array with fixed property names
m_aPropNames[ OFFSET_URL ] = PROPERTYNAME_URL;
m_aPropNames[ OFFSET_TITLE ] = PROPERTYNAME_TITLE;
m_aPropNames[ OFFSET_TARGET ] = PROPERTYNAME_TARGET;
m_aPropNames[ OFFSET_IMAGEIDENTIFIER ] = PROPERTYNAME_IMAGEIDENTIFIER;
m_aPropNames[ OFFSET_SUBMENU ] = PROPERTYNAME_SUBMENU; // Submenu set!
m_aPropNames[ OFFSET_COMPONENTID ] = PROPERTYNAME_COMPONENTID; // External property
// initialize array with fixed property names
m_aPropUINames[ OFFSET_UITYPE_URL ] = PROPERTYNAME_URL;
m_aPropUINames[ OFFSET_UITYPE_TITLE ] = PROPERTYNAME_TITLE;
m_aPropUINames[ OFFSET_UITYPE_TARGET ] = PROPERTYNAME_TARGET;
m_aPropUINames[ OFFSET_UITYPE_IMAGEIDENTIFIER ] = PROPERTYNAME_IMAGEIDENTIFIER;
m_aPropUINames[ OFFSET_UITYPE_CONTEXT ] = PROPERTYNAME_CONTEXT; // Context
m_aPropUINames[ OFFSET_UITYPE_SUBMENU ] = PROPERTYNAME_SUBMENU; // Submenu set!
m_aPropUINames[ OFFSET_UITYPE_COMPONENTID ] = PROPERTYNAME_COMPONENTID; // External property
// initialize array with fixed images property names
m_aPropImagesNames[ OFFSET_IMAGESMALL ] = PROPERTYNAME_IMAGESMALL;
m_aPropImagesNames[ OFFSET_IMAGEBIG ] = PROPERTYNAME_IMAGEBIG;
m_aPropImagesNames[ OFFSET_IMAGESMALLHC ] = PROPERTYNAME_IMAGESMALLHC;
m_aPropImagesNames[ OFFSET_IMAGEBIGHC ] = PROPERTYNAME_IMAGEBIGHC;
// Get names and values of all accessable menu entries and fill internal structures.
// See impl_GetPropertyNames() for further informations.
OUString aAddonMenuNodeName( RTL_CONSTASCII_USTRINGPARAM( "AddonUI/AddonMenu" ));
Sequence< OUString > aAddonRootMenuNodeSeq = GetNodeNames( aAddonMenuNodeName );
OUString aAddonMenuTreeNode( aAddonMenuNodeName + m_aPathDelimiter );
sal_uInt32 nCount = aAddonRootMenuNodeSeq.getLength();
for ( sal_uInt32 n = 0; n < nCount; n++ )
{
AddonMenuRootEntry aItem;
OUString aRootMenuNode( aAddonMenuTreeNode + aAddonRootMenuNodeSeq[n] );
if ( ReadRootMenuEntry( aRootMenuNode, aItem ) )
m_aAddonMenu.AppendRootMenuEntry( aItem );
}
// Save values to the external representation structure to save memory and time.
// Currently this is possible as there is no way to register components during Office runtime!
m_aCachedMenuProperties = m_aAddonMenu.GetList();
// Read the extended OfficeMenuBar definition that allows external component to integrate their
// popup-menu into the Office menu bar!
OUString aAddonMenuBarNodeName( RTL_CONSTASCII_USTRINGPARAM( "AddonUI/OfficeMenuBar" ));
Sequence< OUString > aAddonRootMenuBarNodeSeq = GetNodeNames( aAddonMenuBarNodeName );
OUString aAddonMenuBarTreeNode( aAddonMenuBarNodeName + m_aPathDelimiter );
nCount = aAddonRootMenuBarNodeSeq.getLength();
for ( n = 0; n < nCount; n++ )
{
AddonMenuRootEntry aItem;
OUString aRootMenuNode( aAddonMenuBarTreeNode + aAddonRootMenuBarNodeSeq[n] );
if ( ReadRootMenuBarEntry( aRootMenuNode, aItem ) )
m_aAddonMenuBarPart.AppendRootMenuEntry( aItem );
}
// Save values to the external representation structure to save memory and time.
// Currently this is possible as there is no way to register components during Office runtime!
m_aCachedMenuBarPartProperties = m_aAddonMenuBarPart.GetMenuBarList();
/*TODO: Not used in the moment! see Notify() ...
// Enable notification mechanism of ouer baseclass.
// We need it to get information about changes outside these class on ouer used configuration keys!
EnableNotification( lNames );
*/
}
//*****************************************************************************************************************
// destructor
//*****************************************************************************************************************
AddonsOptions_Impl::~AddonsOptions_Impl()
{
// We must save our current values .. if user forget it!
if( IsModified() == sal_True )
{
Commit();
}
}
//*****************************************************************************************************************
// public method
//*****************************************************************************************************************
void AddonsOptions_Impl::Notify( const Sequence< OUString >& lPropertyNames )
{
DBG_ASSERT( sal_False, "AddonsOptions_Impl::Notify()\nNot implemented yet! I don't know how I can handle a dynamical list of unknown properties ...\n" );
}
//*****************************************************************************************************************
// 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_aAddonMenu.Size() > 0 );
}
//*****************************************************************************************************************
// public method
//*****************************************************************************************************************
const Sequence< Sequence< PropertyValue > >& AddonsOptions_Impl::GetAddonsMenu() const
{
return m_aCachedMenuProperties;
}
//*****************************************************************************************************************
// public method
//*****************************************************************************************************************
Sequence< PropertyValue > AddonsOptions_Impl::GetAddonsComponentMenu( const ::rtl::OUString aComponentID ) const
{
Sequence< PropertyValue > lResult( PROPERTYCOUNT_ROOT );
for ( sal_uInt32 nIndex = 0; nIndex < (sal_uInt32)m_aAddonMenu.Size(); nIndex++ )
{
const AddonMenuRootEntry* pRootMenuEntry = m_aAddonMenu.GetRootMenuEntry( nIndex );
if ( pRootMenuEntry && pRootMenuEntry->sName.equals( aComponentID ))
{
lResult[ OFFSET_URL ].Name = m_aPropNames[ OFFSET_URL ];
lResult[ OFFSET_URL ].Value <<= pRootMenuEntry->sURL;
lResult[ OFFSET_TITLE ].Name = m_aPropNames[ OFFSET_TITLE ];
lResult[ OFFSET_TITLE ].Value <<= pRootMenuEntry->sTitle;
lResult[ OFFSET_TARGET ].Name = m_aPropNames[ OFFSET_TARGET ];
lResult[ OFFSET_TARGET ].Value <<= pRootMenuEntry->sTarget;
lResult[ OFFSET_IMAGEIDENTIFIER ].Name = m_aPropNames[ OFFSET_TITLE ];
lResult[ OFFSET_IMAGEIDENTIFIER ].Value <<= pRootMenuEntry->sImageIdentifier;
lResult[ OFFSET_COMPONENTID ].Name = m_aPropNames[ OFFSET_COMPONENTID ];
lResult[ OFFSET_COMPONENTID ].Value <<= pRootMenuEntry->sName;
lResult[ OFFSET_SUBMENU ].Name = m_aPropNames[ OFFSET_SUBMENU ];
if ( pRootMenuEntry->aSubMenu.size() > 0 )
lResult[ OFFSET_SUBMENU ].Value <<= m_aAddonMenu.GetSubMenuList( pRootMenuEntry->aSubMenu );
else
lResult[ OFFSET_SUBMENU ].Value <<= Sequence< Sequence< PropertyValue > >();
return lResult;
}
}
return lResult;
}
//*****************************************************************************************************************
// public method
//*****************************************************************************************************************
const Sequence< Sequence< PropertyValue > >& AddonsOptions_Impl::GetAddonsMenuBarPart() const
{
return m_aCachedMenuBarPartProperties;
}
//*****************************************************************************************************************
// public method
//*****************************************************************************************************************
const Sequence< Sequence< PropertyValue > >& AddonsOptions_Impl::GetAddonsToolBarPart() const
{
return m_aCachedToolBarPartProperties;
}
//*****************************************************************************************************************
// public method
//*****************************************************************************************************************
Image AddonsOptions_Impl::GetImageFromURL( const rtl::OUString& aURL, sal_Bool bBig, sal_Bool bHiContrast ) const
{
Image aImage;
ImageManager::const_iterator pIter = m_aImageManager.find( aURL );
if ( pIter != m_aImageManager.end() )
{
if ( !bHiContrast )
aImage = ( bBig ? pIter->second.aImageBig : pIter->second.aImageSmall );
else
aImage = ( bBig ? pIter->second.aImageBigHC : pIter->second.aImageSmallHC );
}
return aImage;
}
//*****************************************************************************************************************
// private method
//*****************************************************************************************************************
sal_Bool AddonsOptions_Impl::ReadRootMenuEntry( const OUString& aRootMenuNodeName, AddonMenuRootEntry& rRootMenuEntry )
{
sal_Bool bResult = sal_False;
OUString aAddonRootMenuTreeNode( aRootMenuNodeName + m_aPathDelimiter );
Sequence< Any > aRootMenuNodePropValues;
aRootMenuNodePropValues = GetProperties( GetPropertyNames( aAddonRootMenuTreeNode ) );
if ( aRootMenuNodePropValues[ OFFSET_TITLE ] >>= rRootMenuEntry.sTitle )
{
OUString aRootSubMenuName( aAddonRootMenuTreeNode + m_aPropNames[ OFFSET_SUBMENU ] );
Sequence< OUString > aRootSubMenuNodeNames = GetNodeNames( aRootSubMenuName );
if ( aRootSubMenuNodeNames.getLength() > 0 )
{
// A popup menu only needs a title, ignore other properties and continue to read sub menu nodes
OUString aSubMenuRootNodeName( aRootSubMenuName + m_aPathDelimiter );
for ( sal_uInt32 n = 0; n < (sal_uInt32)aRootSubMenuNodeNames.getLength(); n++ )
aRootSubMenuNodeNames[n] = OUString( aSubMenuRootNodeName + aRootSubMenuNodeNames[n] );
ReadSubMenuEntries( aRootSubMenuNodeNames, rRootMenuEntry.aSubMenu );
rRootMenuEntry.sName = aRootMenuNodeName.copy( aRootMenuNodeName.lastIndexOf( '/' )+1);
bResult = sal_True;
}
else
{
// A simple menu item => read the other properties;
if ( aRootMenuNodePropValues[ OFFSET_URL ] >>= rRootMenuEntry.sURL ) // Menu item must have a command URL
{
aRootMenuNodePropValues[ OFFSET_TARGET ] >>= rRootMenuEntry.sTarget;
aRootMenuNodePropValues[ OFFSET_IMAGEIDENTIFIER ] >>= rRootMenuEntry.sImageIdentifier;
// Set the name/component id of the root menu
rRootMenuEntry.sName = aRootMenuNodeName.copy( aRootMenuNodeName.lastIndexOf( '/' )+1);
// Store bitmap data defined for this menu item into the internal image manager
ImageEntry* pImageEntry = ReadOptionalImageData( aRootMenuNodeName );
if ( pImageEntry )
AddImageEntryToImageManager( rRootMenuEntry.sURL, pImageEntry );
bResult = sal_True;
}
}
}
return bResult;
}
//*****************************************************************************************************************
// private method
//*****************************************************************************************************************
sal_Bool AddonsOptions_Impl::ReadRootMenuBarEntry( const OUString& aRootMenuBarNodeName, AddonMenuRootEntry& rRootMenuBarEntry )
{
sal_Bool bResult = sal_False;
OUString aAddonRootMenuBarTreeNode( aRootMenuBarNodeName + m_aPathDelimiter );
Sequence< Any > aRootMenuBarNodePropValues;
aRootMenuBarNodePropValues = GetProperties( GetUITypePropertyNames( aAddonRootMenuBarTreeNode ) );
if ( aRootMenuBarNodePropValues[ OFFSET_UITYPE_TITLE ] >>= rRootMenuBarEntry.sTitle )
{
// A top-level popup menu needs a title and prefixed url
OUStringBuffer aBuf( m_aRootAddonPopupMenuURLPrexfix.getLength() + 3 );
aBuf.append( m_aRootAddonPopupMenuURLPrexfix );
aBuf.append( OUString::valueOf( ++m_nRootAddonPopupMenuId ));
rRootMenuBarEntry.sURL = aBuf.makeStringAndClear();
OUString aRootSubMenuName( aAddonRootMenuBarTreeNode + m_aPropUINames[ OFFSET_UITYPE_SUBMENU ] );
Sequence< OUString > aRootSubMenuNodeNames = GetNodeNames( aRootSubMenuName );
if ( aRootSubMenuNodeNames.getLength() > 0 )
{
// Read optional context information and continue to read sub menu nodes
aRootMenuBarNodePropValues[ OFFSET_UITYPE_CONTEXT ] >>= rRootMenuBarEntry.sContext;
OUString aSubMenuRootNodeName( aRootSubMenuName + m_aPathDelimiter );
for ( sal_uInt32 n = 0; n < (sal_uInt32)aRootSubMenuNodeNames.getLength(); n++ )
aRootSubMenuNodeNames[n] = OUString( aSubMenuRootNodeName + aRootSubMenuNodeNames[n] );
ReadSubMenuEntries( aRootSubMenuNodeNames, rRootMenuBarEntry.aSubMenu );
rRootMenuBarEntry.sName = aRootMenuBarNodeName.copy( aRootMenuBarNodeName.lastIndexOf( '/' )+1);
bResult = sal_True;
}
else
{
// Not allowed to have a single menu item on a top-level menu bar!
return sal_False;
}
}
return bResult;
}
//*****************************************************************************************************************
// private method
//*****************************************************************************************************************
sal_Bool AddonsOptions_Impl::ReadSubMenuEntries( const Sequence< OUString >& aSubMenuNodeNames, AddonSubMenu& rSubMenuContainer )
{
sal_uInt32 nCount = aSubMenuNodeNames.getLength();
for ( sal_uInt32 n = 0; n < nCount; n++ )
ReadSubMenuEntry( aSubMenuNodeNames[n], rSubMenuContainer );
return sal_True;
}
//*****************************************************************************************************************
// private method
//*****************************************************************************************************************
sal_Bool AddonsOptions_Impl::ReadSubMenuEntry( const OUString& aMenuEntryNodeName, AddonSubMenu& rSubMenuContainer )
{
sal_Bool bResult = sal_False;
OUString aAddonMenuTreeNode( aMenuEntryNodeName + m_aPathDelimiter );
Sequence< Any > aMenuNodePropValues;
AddonMenuEntry aMenuEntry;
aMenuNodePropValues = GetProperties( GetPropertyNames( aAddonMenuTreeNode ) );
if ( aMenuNodePropValues[ OFFSET_TITLE ] >>= aMenuEntry.sTitle )
{
OUString aSubMenuNodeName( aAddonMenuTreeNode + m_aPropNames[ OFFSET_SUBMENU ] );
Sequence< OUString > aSubMenuNodeNames = GetNodeNames( aSubMenuNodeName );
if ( aSubMenuNodeNames.getLength() > 0 )
{
// A popup menu only needs a title, ignore other properties and continue to read sub menu nodes
OUString aSubMenuRootNodeName( aSubMenuNodeName + m_aPathDelimiter );
for ( sal_uInt32 n = 0; n < (sal_uInt32)aSubMenuNodeNames.getLength(); n++ )
aSubMenuNodeNames[n] = OUString( aSubMenuRootNodeName + aSubMenuNodeNames[n] );
ReadSubMenuEntries( aSubMenuNodeNames, aMenuEntry.aSubMenu );
rSubMenuContainer.push_back( aMenuEntry );
}
else
{
// A simple menu item => read the other properties;
if ( aMenuNodePropValues[ OFFSET_URL ] >>= aMenuEntry.sURL ) // Menu item must have a command URL
{
if ( aMenuEntry.sURL.equals( m_aSeparator ))
rSubMenuContainer.push_back( aMenuEntry ); // Separator
else
{
aMenuNodePropValues[ OFFSET_TARGET ] >>= aMenuEntry.sTarget;
aMenuNodePropValues[ OFFSET_IMAGEIDENTIFIER ] >>= aMenuEntry.sImageIdentifier;
rSubMenuContainer.push_back( aMenuEntry );
// Store bitmap data defined for this menu item into the internal image manager
ImageEntry* pImageEntry = ReadOptionalImageData( aMenuEntryNodeName );
if ( pImageEntry )
AddImageEntryToImageManager( aMenuEntry.sURL, pImageEntry );
}
bResult = sal_True;
}
}
}
else if ( aMenuNodePropValues[ OFFSET_URL ] >>= aMenuEntry.sURL )
{
aMenuEntry.sURL = m_aSeparator;
rSubMenuContainer.push_back( aMenuEntry );
bResult = sal_True;
}
return bResult;
}
//*****************************************************************************************************************
// private method
//*****************************************************************************************************************
AddonsOptions_Impl::ImageEntry* AddonsOptions_Impl::ReadOptionalImageData( const OUString& aMenuNodeName )
{
OUStringBuffer aBuffer( aMenuNodeName );
aBuffer.append( m_aPathDelimiter );
aBuffer.append( IMAGES_NODENAME );
aBuffer.append( m_aPathDelimiter );
OUString aImageNodeName = aBuffer.makeStringAndClear();
Sequence< OUString > aImageDataNodeNames = GetImagesPropertyNames( aImageNodeName );
Sequence< Any > aPropertyData;
Sequence< sal_Int8 > aImageDataSeq;
Image aImage;
ImageEntry* pEntry = NULL;
aPropertyData = GetProperties( aImageDataNodeNames );
for ( int i = 0; i < PROPERTYIMAGES_COUNT; i++ )
{
if (( aPropertyData[i] >>= aImageDataSeq ) &&
( CreateImageFromSequence( aImage, (( i == OFFSET_IMAGEBIG ) || ( i == OFFSET_IMAGEBIGHC )), aImageDataSeq )) )
{
if ( !pEntry )
pEntry = new ImageEntry;
if ( i == OFFSET_IMAGESMALL )
pEntry->aImageSmall = aImage;
else if ( i == OFFSET_IMAGEBIG )
pEntry->aImageBig = aImage;
else if ( i == OFFSET_IMAGESMALLHC )
pEntry->aImageSmallHC = aImage;
else
pEntry->aImageBigHC = aImage;
}
}
return pEntry;
}
//*****************************************************************************************************************
// private method
//*****************************************************************************************************************
sal_Bool AddonsOptions_Impl::CreateImageFromSequence( Image& rImage, sal_Bool bBig, Sequence< sal_Int8 >& rBitmapDataSeq ) const
{
sal_Bool bResult = sal_False;
Color aTransparentColor( COL_LIGHTMAGENTA );
Size aSize = bBig ? Size( 26, 26 ) : Size( 16, 16 ); // Sizes used for menu/toolbox images
if ( rBitmapDataSeq.getLength() > 0 )
{
SvMemoryStream aMemStream( rBitmapDataSeq.getArray(), rBitmapDataSeq.getLength(), STREAM_STD_READ );
Bitmap aBitmap;
aBitmap.Read( aMemStream );
// Scale bitmap to fit the correct size for the menu/toolbar. Use best quality
if ( aBitmap.GetSizePixel() != aSize )
aBitmap.Scale( aSize, BMP_SCALE_INTERPOLATE );
rImage = Image( aBitmap, aTransparentColor );
bResult = sal_True;
}
return bResult;
}
//*****************************************************************************************************************
// private method
//*****************************************************************************************************************
void AddonsOptions_Impl::AddImageEntryToImageManager( const OUString& aURL, ImageEntry* pImageEntry )
{
// Attention: ImageEntry pointer belongs now to the implementation!
m_aImageManager.insert( ImageManager::value_type( aURL, *pImageEntry ));
delete pImageEntry;
}
//*****************************************************************************************************************
// private method
//*****************************************************************************************************************
Sequence< OUString > AddonsOptions_Impl::GetPropertyNames( const OUString& aPropertyRootNode ) const
{
Sequence< OUString > lResult( CFG_PROPERTYCOUNT );
// Create property names dependent from the root node name
lResult[0] = OUString( aPropertyRootNode + m_aPropNames[ OFFSET_URL ] );
lResult[1] = OUString( aPropertyRootNode + m_aPropNames[ OFFSET_TITLE ] );
lResult[2] = OUString( aPropertyRootNode + m_aPropNames[ OFFSET_TARGET ] );
lResult[3] = OUString( aPropertyRootNode + m_aPropNames[ OFFSET_IMAGEIDENTIFIER ] );
return lResult;
}
//*****************************************************************************************************************
// private method
//*****************************************************************************************************************
Sequence< OUString > AddonsOptions_Impl::GetUITypePropertyNames( const OUString& aPropertyRootNode ) const
{
Sequence< OUString > lResult( CFG_UITYPE_PROPERTYCOUNT );
// Create property names dependent from the root node name
lResult[0] = OUString( aPropertyRootNode + m_aPropUINames[ OFFSET_UITYPE_TITLE ] );
lResult[1] = OUString( aPropertyRootNode + m_aPropUINames[ OFFSET_UITYPE_TARGET ] );
lResult[2] = OUString( aPropertyRootNode + m_aPropUINames[ OFFSET_UITYPE_IMAGEIDENTIFIER ] );
lResult[3] = OUString( aPropertyRootNode + m_aPropUINames[ OFFSET_UITYPE_CONTEXT ] );
lResult[4] = OUString( aPropertyRootNode + m_aPropUINames[ OFFSET_UITYPE_SUBMENU ] );
return lResult;
}
//*****************************************************************************************************************
// private method
//*****************************************************************************************************************
Sequence< OUString > AddonsOptions_Impl::GetImagesPropertyNames( const OUString& aPropertyRootNode ) const
{
Sequence< OUString > lResult( PROPERTYIMAGES_COUNT );
// Create property names dependent from the root node name
lResult[0] = OUString( aPropertyRootNode + m_aPropImagesNames[ OFFSET_IMAGESMALL ] );
lResult[1] = OUString( aPropertyRootNode + m_aPropImagesNames[ OFFSET_IMAGEBIG ] );
lResult[2] = OUString( aPropertyRootNode + m_aPropImagesNames[ OFFSET_IMAGESMALLHC ] );
lResult[3] = OUString( aPropertyRootNode + m_aPropImagesNames[ OFFSET_IMAGEBIGHC ] );
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
//*****************************************************************************************************************
const Sequence< Sequence< PropertyValue > >& AddonsOptions::GetAddonsMenu() const
{
MutexGuard aGuard( GetOwnStaticMutex() );
return m_pDataContainer->GetAddonsMenu();
}
//*****************************************************************************************************************
// public method
//*****************************************************************************************************************
Sequence< PropertyValue > AddonsOptions::GetAddonsComponentMenu( const ::rtl::OUString aComponentID ) const
{
MutexGuard aGuard( GetOwnStaticMutex() );
return m_pDataContainer->GetAddonsComponentMenu( aComponentID );
}
//*****************************************************************************************************************
// public method
//*****************************************************************************************************************
const Sequence< Sequence< PropertyValue > >& AddonsOptions::GetAddonsMenuBarPart() const
{
MutexGuard aGuard( GetOwnStaticMutex() );
return m_pDataContainer->GetAddonsMenuBarPart();
}
//*****************************************************************************************************************
// public method
//*****************************************************************************************************************
const Sequence< Sequence< PropertyValue > >& AddonsOptions::GetAddonsToolBarPart() const
{
MutexGuard aGuard( GetOwnStaticMutex() );
return m_pDataContainer->GetAddonsToolBarPart();
}
//*****************************************************************************************************************
// public method
//*****************************************************************************************************************
Image AddonsOptions::GetImageFromURL( const rtl::OUString& aURL, sal_Bool bBig, sal_Bool bHiContrast ) const
{
MutexGuard aGuard( GetOwnStaticMutex() );
return m_pDataContainer->GetImageFromURL( aURL, bBig, bHiContrast );
}
//*****************************************************************************************************************
// 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;
}
}