summaryrefslogtreecommitdiff
path: root/framework/source/classes
diff options
context:
space:
mode:
Diffstat (limited to 'framework/source/classes')
-rw-r--r--framework/source/classes/actiontriggercontainer.cxx203
-rw-r--r--framework/source/classes/actiontriggerpropertyset.cxx478
-rw-r--r--framework/source/classes/actiontriggerseparatorpropertyset.cxx349
-rw-r--r--framework/source/classes/addonmenu.cxx456
-rw-r--r--framework/source/classes/addonsoptions.cxx1858
-rw-r--r--framework/source/classes/bmkmenu.cxx254
-rw-r--r--framework/source/classes/converter.cxx316
-rw-r--r--framework/source/classes/droptargetlistener.cxx254
-rw-r--r--framework/source/classes/framecontainer.cxx418
-rw-r--r--framework/source/classes/framelistanalyzer.cxx302
-rw-r--r--framework/source/classes/fwkresid.cxx65
-rw-r--r--framework/source/classes/fwktabwindow.cxx412
-rwxr-xr-xframework/source/classes/fwlresid.cxx65
-rw-r--r--framework/source/classes/imagewrapper.cxx120
-rw-r--r--framework/source/classes/makefile.mk69
-rw-r--r--framework/source/classes/menuextensionsupplier.cxx64
-rw-r--r--framework/source/classes/menumanager.cxx1179
-rw-r--r--framework/source/classes/propertysethelper.cxx450
-rw-r--r--framework/source/classes/protocolhandlercache.cxx361
-rw-r--r--framework/source/classes/resource.src349
-rw-r--r--framework/source/classes/rootactiontriggercontainer.cxx379
-rw-r--r--framework/source/classes/sfxhelperfunctions.cxx158
-rw-r--r--framework/source/classes/taskcreator.cxx171
23 files changed, 8730 insertions, 0 deletions
diff --git a/framework/source/classes/actiontriggercontainer.cxx b/framework/source/classes/actiontriggercontainer.cxx
new file mode 100644
index 000000000000..ea549fd3fda8
--- /dev/null
+++ b/framework/source/classes/actiontriggercontainer.cxx
@@ -0,0 +1,203 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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"
+#include <classes/actiontriggercontainer.hxx>
+#include <cppuhelper/typeprovider.hxx>
+
+#include <classes/actiontriggerpropertyset.hxx>
+#include <classes/actiontriggerseparatorpropertyset.hxx>
+
+using namespace cppu;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::container;
+
+namespace framework
+{
+
+ActionTriggerContainer::ActionTriggerContainer( const Reference< XMultiServiceFactory >& rServiceManager ) :
+ PropertySetContainer( rServiceManager )
+{
+}
+
+
+ActionTriggerContainer::~ActionTriggerContainer()
+{
+}
+
+// XInterface
+Any SAL_CALL ActionTriggerContainer::queryInterface( const Type& aType )
+throw ( RuntimeException )
+{
+ Any a = ::cppu::queryInterface(
+ aType ,
+ SAL_STATIC_CAST( XMultiServiceFactory*, this ),
+ SAL_STATIC_CAST( XServiceInfo* , this ));
+
+ if( a.hasValue() )
+ {
+ return a;
+ }
+
+ return PropertySetContainer::queryInterface( aType );
+}
+
+void ActionTriggerContainer::acquire() throw()
+{
+ PropertySetContainer::acquire();
+}
+
+void ActionTriggerContainer::release() throw()
+{
+ PropertySetContainer::release();
+}
+
+
+// XMultiServiceFactory
+Reference< XInterface > SAL_CALL ActionTriggerContainer::createInstance( const ::rtl::OUString& aServiceSpecifier )
+throw ( ::com::sun::star::uno::Exception, RuntimeException)
+{
+ if ( aServiceSpecifier.equalsAscii( SERVICENAME_ACTIONTRIGGER ))
+ return (OWeakObject *)( new ActionTriggerPropertySet( m_xServiceManager ));
+ else if ( aServiceSpecifier.equalsAscii( SERVICENAME_ACTIONTRIGGERCONTAINER ))
+ return (OWeakObject *)( new ActionTriggerContainer( m_xServiceManager ));
+ else if ( aServiceSpecifier.equalsAscii( SERVICENAME_ACTIONTRIGGERSEPARATOR ))
+ return (OWeakObject *)( new ActionTriggerSeparatorPropertySet( m_xServiceManager ));
+ else
+ throw com::sun::star::uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Unknown service specifier!" )), (OWeakObject *)this );
+}
+
+
+Reference< XInterface > SAL_CALL ActionTriggerContainer::createInstanceWithArguments( const ::rtl::OUString& ServiceSpecifier, const Sequence< Any >& /*Arguments*/ )
+throw ( Exception, RuntimeException)
+{
+ return createInstance( ServiceSpecifier );
+}
+
+
+Sequence< ::rtl::OUString > SAL_CALL ActionTriggerContainer::getAvailableServiceNames()
+throw ( RuntimeException )
+{
+ Sequence< ::rtl::OUString > aSeq( 3 );
+
+ aSeq[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SERVICENAME_ACTIONTRIGGER ));
+ aSeq[1] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SERVICENAME_ACTIONTRIGGERCONTAINER ));
+ aSeq[2] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SERVICENAME_ACTIONTRIGGERSEPARATOR ));
+
+ return aSeq;
+}
+
+// XServiceInfo
+::rtl::OUString SAL_CALL ActionTriggerContainer::getImplementationName()
+throw ( RuntimeException )
+{
+ return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( IMPLEMENTATIONNAME_ACTIONTRIGGERCONTAINER ));
+}
+
+sal_Bool SAL_CALL ActionTriggerContainer::supportsService( const ::rtl::OUString& ServiceName )
+throw ( RuntimeException )
+{
+ if ( ServiceName.equalsAscii( SERVICENAME_ACTIONTRIGGERCONTAINER ))
+ return sal_True;
+
+ return sal_False;
+}
+
+Sequence< ::rtl::OUString > SAL_CALL ActionTriggerContainer::getSupportedServiceNames()
+throw ( RuntimeException )
+{
+ Sequence< ::rtl::OUString > seqServiceNames( 1 );
+
+ seqServiceNames[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SERVICENAME_ACTIONTRIGGERCONTAINER ));
+ return seqServiceNames;
+}
+
+// XTypeProvider
+Sequence< Type > SAL_CALL ActionTriggerContainer::getTypes() throw ( RuntimeException )
+{
+ // Optimize this method !
+ // We initialize a static variable only one time. And we don't must use a mutex at every call!
+ // For the first call; pTypeCollection is NULL - for the second call pTypeCollection is different from NULL!
+ static ::cppu::OTypeCollection* pTypeCollection = NULL ;
+
+ if ( pTypeCollection == NULL )
+ {
+ // Ready for multithreading; get global mutex for first call of this method only! see before
+ osl::MutexGuard aGuard( osl::Mutex::getGlobalMutex() ) ;
+
+ // Control these pointer again ... it can be, that another instance will be faster then these!
+ if ( pTypeCollection == NULL )
+ {
+ // Create a static typecollection ...
+ static ::cppu::OTypeCollection aTypeCollection(
+ ::getCppuType(( const Reference< XMultiServiceFactory >*)NULL ) ,
+ ::getCppuType(( const Reference< XIndexContainer >*)NULL ) ,
+ ::getCppuType(( const Reference< XIndexAccess >*)NULL ) ,
+ ::getCppuType(( const Reference< XIndexReplace >*)NULL ) ,
+ ::getCppuType(( const Reference< XServiceInfo >*)NULL ) ,
+ ::getCppuType(( const Reference< XTypeProvider >*)NULL ) ) ;
+
+ // ... and set his address to static pointer!
+ pTypeCollection = &aTypeCollection ;
+ }
+ }
+
+ return pTypeCollection->getTypes() ;
+}
+
+Sequence< sal_Int8 > SAL_CALL ActionTriggerContainer::getImplementationId() throw ( RuntimeException )
+{
+ // Create one Id for all instances of this class.
+ // Use ethernet address to do this! (sal_True)
+
+ // Optimize this method
+ // We initialize a static variable only one time. And we don't must use a mutex at every call!
+ // For the first call; pID is NULL - for the second call pID is different from NULL!
+ static ::cppu::OImplementationId* pID = NULL ;
+
+ if ( pID == NULL )
+ {
+ // Ready for multithreading; get global mutex for first call of this method only! see before
+ osl::MutexGuard aGuard( osl::Mutex::getGlobalMutex() ) ;
+
+ // Control these pointer again ... it can be, that another instance will be faster then these!
+ if ( pID == NULL )
+ {
+ // Create a new static ID ...
+ static ::cppu::OImplementationId aID( sal_False ) ;
+ // ... and set his address to static pointer!
+ pID = &aID ;
+ }
+ }
+
+ return pID->getImplementationId() ;
+}
+
+}
+
diff --git a/framework/source/classes/actiontriggerpropertyset.cxx b/framework/source/classes/actiontriggerpropertyset.cxx
new file mode 100644
index 000000000000..e72efe6e7cba
--- /dev/null
+++ b/framework/source/classes/actiontriggerpropertyset.cxx
@@ -0,0 +1,478 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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"
+
+#include <classes/actiontriggerpropertyset.hxx>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <cppuhelper/proptypehlp.hxx>
+#include <cppuhelper/typeprovider.hxx>
+#include <vcl/svapp.hxx>
+
+
+using namespace cppu;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::beans;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::awt;
+
+// Handles for properties
+// (PLEASE SORT THIS FIELD, IF YOU ADD NEW PROPERTIES!)
+// We use an enum to define these handles, to use all numbers from 0 to nn and
+// if you add someone, you don't must control this!
+// But don't forget to change values of follow defines, if you do something with this enum!
+enum EPROPERTIES
+{
+ HANDLE_COMMANDURL,
+ HANDLE_HELPURL,
+ HANDLE_IMAGE,
+ HANDLE_SUBCONTAINER,
+ HANDLE_TEXT,
+ PROPERTYCOUNT
+};
+
+namespace framework
+{
+
+ActionTriggerPropertySet::ActionTriggerPropertySet( const Reference< XMultiServiceFactory >& /*xServiceManager*/ )
+ : ThreadHelpBase ( &Application::GetSolarMutex() )
+ , OBroadcastHelper ( m_aLock.getShareableOslMutex() )
+ , OPropertySetHelper ( *SAL_STATIC_CAST( OBroadcastHelper *, this ))
+ , OWeakObject ()
+ , m_xBitmap ( 0 )
+ , m_xActionTriggerContainer( 0 )
+{
+}
+
+ActionTriggerPropertySet::~ActionTriggerPropertySet()
+{
+}
+
+// XInterface
+Any SAL_CALL ActionTriggerPropertySet::queryInterface( const Type& aType )
+throw ( RuntimeException )
+{
+ Any a = ::cppu::queryInterface(
+ aType ,
+ SAL_STATIC_CAST( XServiceInfo*, this ));
+
+ if( a.hasValue() )
+ return a;
+ else
+ {
+ a = OPropertySetHelper::queryInterface( aType );
+
+ if( a.hasValue() )
+ return a;
+ }
+
+ return OWeakObject::queryInterface( aType );
+}
+
+void SAL_CALL ActionTriggerPropertySet::acquire() throw ()
+{
+ OWeakObject::acquire();
+}
+
+void SAL_CALL ActionTriggerPropertySet::release() throw ()
+{
+ OWeakObject::release();
+}
+
+
+// XServiceInfo
+::rtl::OUString SAL_CALL ActionTriggerPropertySet::getImplementationName()
+throw ( RuntimeException )
+{
+ return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( IMPLEMENTATIONNAME_ACTIONTRIGGER ));
+}
+
+sal_Bool SAL_CALL ActionTriggerPropertySet::supportsService( const ::rtl::OUString& ServiceName )
+throw ( RuntimeException )
+{
+ if ( ServiceName.equalsAscii( SERVICENAME_ACTIONTRIGGER ))
+ return sal_True;
+
+ return sal_False;
+}
+
+Sequence< ::rtl::OUString > SAL_CALL ActionTriggerPropertySet::getSupportedServiceNames()
+throw ( RuntimeException )
+{
+ Sequence< ::rtl::OUString > seqServiceNames( 1 );
+ seqServiceNames[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SERVICENAME_ACTIONTRIGGER ));
+ return seqServiceNames;
+}
+
+// XTypeProvider
+Sequence< Type > SAL_CALL ActionTriggerPropertySet::getTypes() throw ( RuntimeException )
+{
+ // Optimize this method !
+ // We initialize a static variable only one time. And we don't must use a mutex at every call!
+ // For the first call; pTypeCollection is NULL - for the second call pTypeCollection is different from NULL!
+ static ::cppu::OTypeCollection* pTypeCollection = NULL ;
+
+ if ( pTypeCollection == NULL )
+ {
+ // Ready for multithreading; get global mutex for first call of this method only! see before
+ osl::MutexGuard aGuard( osl::Mutex::getGlobalMutex() ) ;
+
+ // Control these pointer again ... it can be, that another instance will be faster then these!
+ if ( pTypeCollection == NULL )
+ {
+ // Create a static typecollection ...
+ static ::cppu::OTypeCollection aTypeCollection(
+ ::getCppuType(( const Reference< XPropertySet >*)NULL ) ,
+ ::getCppuType(( const Reference< XFastPropertySet >*)NULL ) ,
+ ::getCppuType(( const Reference< XMultiPropertySet >*)NULL ) ,
+ ::getCppuType(( const Reference< XServiceInfo >*)NULL ) ,
+ ::getCppuType(( const Reference< XTypeProvider >*)NULL ) ) ;
+
+ // ... and set his address to static pointer!
+ pTypeCollection = &aTypeCollection ;
+ }
+ }
+
+ return pTypeCollection->getTypes() ;
+}
+
+Sequence< sal_Int8 > SAL_CALL ActionTriggerPropertySet::getImplementationId() throw ( RuntimeException )
+{
+ // Create one Id for all instances of this class.
+ // Use ethernet address to do this! (sal_True)
+
+ // Optimize this method
+ // We initialize a static variable only one time. And we don't must use a mutex at every call!
+ // For the first call; pID is NULL - for the second call pID is different from NULL!
+ static ::cppu::OImplementationId* pID = NULL ;
+
+ if ( pID == NULL )
+ {
+ // Ready for multithreading; get global mutex for first call of this method only! see before
+ osl::MutexGuard aGuard( osl::Mutex::getGlobalMutex() ) ;
+
+ // Control these pointer again ... it can be, that another instance will be faster then these!
+ if ( pID == NULL )
+ {
+ // Create a new static ID ...
+ static ::cppu::OImplementationId aID( sal_False ) ;
+ // ... and set his address to static pointer!
+ pID = &aID ;
+ }
+ }
+
+ return pID->getImplementationId() ;
+}
+
+//---------------------------------------------------------------------------------------------------------
+// OPropertySetHelper implementation
+//---------------------------------------------------------------------------------------------------------
+
+sal_Bool SAL_CALL ActionTriggerPropertySet::convertFastPropertyValue(
+ Any& aConvertedValue,
+ Any& aOldValue,
+ sal_Int32 nHandle,
+ const Any& aValue )
+throw( IllegalArgumentException )
+{
+ // Check, if value of property will changed in method "setFastPropertyValue_NoBroadcast()".
+ // Return TRUE, if changed - else return FALSE.
+ // Attention: Method "impl_tryToChangeProperty()" can throw the IllegalArgumentException !!!
+ // Initialize return value with FALSE !!!
+ // (Handle can be invalid)
+ sal_Bool bReturn = sal_False;
+
+ switch( nHandle )
+ {
+ case HANDLE_COMMANDURL:
+ bReturn = impl_tryToChangeProperty( m_aCommandURL, aValue, aOldValue, aConvertedValue );
+ break;
+
+ case HANDLE_HELPURL:
+ bReturn = impl_tryToChangeProperty( m_aHelpURL, aValue, aOldValue, aConvertedValue ) ;
+ break;
+
+ case HANDLE_IMAGE:
+ bReturn = impl_tryToChangeProperty( m_xBitmap, aValue, aOldValue, aConvertedValue ) ;
+ break;
+
+ case HANDLE_SUBCONTAINER:
+ bReturn = impl_tryToChangeProperty( m_xActionTriggerContainer, aValue, aOldValue, aConvertedValue );
+ break;
+
+ case HANDLE_TEXT:
+ bReturn = impl_tryToChangeProperty( m_aText, aValue, aOldValue, aConvertedValue ) ;
+ break;
+ }
+
+ // Return state of operation.
+ return bReturn;
+}
+
+
+void SAL_CALL ActionTriggerPropertySet::setFastPropertyValue_NoBroadcast(
+ sal_Int32 nHandle, const Any& aValue )
+throw( Exception )
+{
+ ::osl::MutexGuard aGuard( LockHelper::getGlobalLock().getShareableOslMutex() );
+
+ // Search for right handle ... and try to set property value.
+ switch( nHandle )
+ {
+ case HANDLE_COMMANDURL:
+ aValue >>= m_aCommandURL;
+ break;
+
+ case HANDLE_HELPURL:
+ aValue >>= m_aHelpURL;
+ break;
+
+ case HANDLE_IMAGE:
+ aValue >>= m_xBitmap;
+ break;
+
+ case HANDLE_SUBCONTAINER:
+ aValue >>= m_xActionTriggerContainer;
+ break;
+
+ case HANDLE_TEXT:
+ aValue >>= m_aText;
+ break;
+ }
+}
+
+void SAL_CALL ActionTriggerPropertySet::getFastPropertyValue(
+ Any& aValue, sal_Int32 nHandle ) const
+{
+ ::osl::MutexGuard aGuard( LockHelper::getGlobalLock().getShareableOslMutex() );
+
+ // Search for right handle ... and try to get property value.
+ switch( nHandle )
+ {
+ case HANDLE_COMMANDURL:
+ aValue <<= m_aCommandURL;
+ break;
+
+ case HANDLE_HELPURL:
+ aValue <<= m_aHelpURL;
+ break;
+
+ case HANDLE_IMAGE:
+ aValue <<= m_xBitmap;
+ break;
+
+ case HANDLE_SUBCONTAINER:
+ aValue <<= m_xActionTriggerContainer;
+ break;
+
+ case HANDLE_TEXT:
+ aValue <<= m_aText;
+ break;
+ }
+}
+
+::cppu::IPropertyArrayHelper& SAL_CALL ActionTriggerPropertySet::getInfoHelper()
+{
+ // Optimize this method !
+ // We initialize a static variable only one time. And we don't must use a mutex at every call!
+ // For the first call; pInfoHelper is NULL - for the second call pInfoHelper is different from NULL!
+ static OPropertyArrayHelper* pInfoHelper = NULL;
+
+ if( pInfoHelper == NULL )
+ {
+ // Ready for multithreading
+ ::osl::MutexGuard aGuard( LockHelper::getGlobalLock().getShareableOslMutex() );
+ // Control this pointer again, another instance can be faster then these!
+ if( pInfoHelper == NULL )
+ {
+ // Define static member to give structure of properties to baseclass "OPropertySetHelper".
+ // "impl_getStaticPropertyDescriptor" is a non exported and static funtion, who will define a static propertytable.
+ // "sal_True" say: Table is sorted by name.
+ static OPropertyArrayHelper aInfoHelper( impl_getStaticPropertyDescriptor(), sal_True );
+ pInfoHelper = &aInfoHelper;
+ }
+ }
+
+ return (*pInfoHelper);
+}
+
+Reference< XPropertySetInfo > SAL_CALL ActionTriggerPropertySet::getPropertySetInfo()
+throw ( RuntimeException )
+{
+ // Optimize this method !
+ // We initialize a static variable only one time. And we don't must use a mutex at every call!
+ // For the first call; pInfo is NULL - for the second call pInfo is different from NULL!
+ static Reference< XPropertySetInfo >* pInfo = NULL ;
+
+ if( pInfo == NULL )
+ {
+ // Ready for multithreading
+ ::osl::MutexGuard aGuard( LockHelper::getGlobalLock().getShareableOslMutex() );
+ // Control this pointer again, another instance can be faster then these!
+ if( pInfo == NULL )
+ {
+ // Create structure of propertysetinfo for baseclass "OPropertySetHelper".
+ // (Use method "getInfoHelper()".)
+ static Reference< XPropertySetInfo > xInfo( createPropertySetInfo( getInfoHelper() ) );
+ pInfo = &xInfo;
+ }
+ }
+
+ return (*pInfo);
+}
+
+const Sequence< Property > ActionTriggerPropertySet::impl_getStaticPropertyDescriptor()
+{
+ static const Property pActionTriggerPropertys[] =
+ {
+ Property( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CommandURL" )), HANDLE_COMMANDURL , ::getCppuType((::rtl::OUString*)0) , PropertyAttribute::TRANSIENT ),
+ Property( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "HelpURL" )), HANDLE_HELPURL , ::getCppuType((::rtl::OUString*)0) , PropertyAttribute::TRANSIENT ),
+ Property( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Image" )), HANDLE_IMAGE , ::getCppuType((Reference<XBitmap>*)0) , PropertyAttribute::TRANSIENT ),
+ Property( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "SubContainer" )), HANDLE_SUBCONTAINER , ::getCppuType((::rtl::OUString*)0) , PropertyAttribute::TRANSIENT ),
+ Property( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Text" )), HANDLE_TEXT , ::getCppuType((Reference<XInterface>*)0) , PropertyAttribute::TRANSIENT )
+ };
+
+ // Use it to initialize sequence!
+ static const Sequence< Property > seqActionTriggerPropertyDescriptor( pActionTriggerPropertys, PROPERTYCOUNT );
+
+ // Return static "PropertyDescriptor"
+ return seqActionTriggerPropertyDescriptor ;
+}
+
+
+//******************************************************************************************************************************
+// private method
+//******************************************************************************************************************************
+sal_Bool ActionTriggerPropertySet::impl_tryToChangeProperty(
+ const ::rtl::OUString& sCurrentValue ,
+ const Any& aNewValue ,
+ Any& aOldValue ,
+ Any& aConvertedValue )
+throw( IllegalArgumentException )
+{
+ // Set default return value if method failed.
+ sal_Bool bReturn = sal_False;
+ // Get new value from any.
+ // IllegalArgumentException() can be thrown!
+ ::rtl::OUString sValue ;
+ convertPropertyValue( sValue, aNewValue );
+
+ // If value change ...
+ if( sValue != sCurrentValue )
+ {
+ // ... set information of change.
+ aOldValue <<= sCurrentValue ;
+ aConvertedValue <<= sValue ;
+ // Return OK - "value will be change ..."
+ bReturn = sal_True;
+ }
+ else
+ {
+ // ... clear information of return parameter!
+ aOldValue.clear () ;
+ aConvertedValue.clear () ;
+ // Return NOTHING - "value will not be change ..."
+ bReturn = sal_False;
+ }
+
+ return bReturn;
+}
+
+
+sal_Bool ActionTriggerPropertySet::impl_tryToChangeProperty(
+ const Reference< XBitmap > aCurrentValue ,
+ const Any& aNewValue ,
+ Any& aOldValue ,
+ Any& aConvertedValue )
+throw( IllegalArgumentException )
+{
+ // Set default return value if method failed.
+ sal_Bool bReturn = sal_False;
+ // Get new value from any.
+ // IllegalArgumentException() can be thrown!
+ Reference< XBitmap > aValue ;
+ convertPropertyValue( aValue, aNewValue );
+
+ // If value change ...
+ if( aValue != aCurrentValue )
+ {
+ // ... set information of change.
+ aOldValue <<= aCurrentValue ;
+ aConvertedValue <<= aValue ;
+ // Return OK - "value will be change ..."
+ bReturn = sal_True;
+ }
+ else
+ {
+ // ... clear information of return parameter!
+ aOldValue.clear () ;
+ aConvertedValue.clear () ;
+ // Return NOTHING - "value will not be change ..."
+ bReturn = sal_False;
+ }
+
+ return bReturn;
+}
+
+sal_Bool ActionTriggerPropertySet::impl_tryToChangeProperty(
+ const Reference< XInterface > aCurrentValue ,
+ const Any& aNewValue ,
+ Any& aOldValue ,
+ Any& aConvertedValue )
+throw( IllegalArgumentException )
+{
+ // Set default return value if method failed.
+ sal_Bool bReturn = sal_False;
+ // Get new value from any.
+ // IllegalArgumentException() can be thrown!
+ Reference< XInterface > aValue ;
+ convertPropertyValue( aValue, aNewValue );
+
+ // If value change ...
+ if( aValue != aCurrentValue )
+ {
+ // ... set information of change.
+ aOldValue <<= aCurrentValue ;
+ aConvertedValue <<= aValue ;
+ // Return OK - "value will be change ..."
+ bReturn = sal_True;
+ }
+ else
+ {
+ // ... clear information of return parameter!
+ aOldValue.clear () ;
+ aConvertedValue.clear () ;
+ // Return NOTHING - "value will not be change ..."
+ bReturn = sal_False;
+ }
+
+ return bReturn;
+}
+
+}
+
diff --git a/framework/source/classes/actiontriggerseparatorpropertyset.cxx b/framework/source/classes/actiontriggerseparatorpropertyset.cxx
new file mode 100644
index 000000000000..f68c293fcef4
--- /dev/null
+++ b/framework/source/classes/actiontriggerseparatorpropertyset.cxx
@@ -0,0 +1,349 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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"
+
+#include <classes/actiontriggerseparatorpropertyset.hxx>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <cppuhelper/proptypehlp.hxx>
+#include <cppuhelper/typeprovider.hxx>
+#include <vcl/svapp.hxx>
+
+
+using namespace cppu;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::beans;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::awt;
+
+// Handles for properties
+// (PLEASE SORT THIS FIELD, IF YOU ADD NEW PROPERTIES!)
+// We use an enum to define these handles, to use all numbers from 0 to nn and
+// if you add someone, you don't must control this!
+// But don't forget to change values of follow defines, if you do something with this enum!
+enum EPROPERTIES
+{
+ HANDLE_TYPE,
+ PROPERTYCOUNT
+};
+
+namespace framework
+{
+
+ActionTriggerSeparatorPropertySet::ActionTriggerSeparatorPropertySet( const Reference< XMultiServiceFactory >& /*ServiceManager*/ )
+ : ThreadHelpBase ( &Application::GetSolarMutex() )
+ , OBroadcastHelper ( m_aLock.getShareableOslMutex() )
+ , OPropertySetHelper ( *SAL_STATIC_CAST( OBroadcastHelper *, this ) )
+ , OWeakObject ( )
+ , m_nSeparatorType( 0 )
+{
+}
+
+ActionTriggerSeparatorPropertySet::~ActionTriggerSeparatorPropertySet()
+{
+}
+
+// XInterface
+Any SAL_CALL ActionTriggerSeparatorPropertySet::queryInterface( const Type& aType )
+throw ( RuntimeException )
+{
+ Any a = ::cppu::queryInterface(
+ aType ,
+ SAL_STATIC_CAST( XServiceInfo*, this ));
+
+ if( a.hasValue() )
+ return a;
+ else
+ {
+ a = OPropertySetHelper::queryInterface( aType );
+
+ if( a.hasValue() )
+ return a;
+ }
+
+ return OWeakObject::queryInterface( aType );
+}
+
+void ActionTriggerSeparatorPropertySet::acquire() throw()
+{
+ OWeakObject::acquire();
+}
+
+void ActionTriggerSeparatorPropertySet::release() throw()
+{
+ OWeakObject::release();
+}
+
+// XServiceInfo
+::rtl::OUString SAL_CALL ActionTriggerSeparatorPropertySet::getImplementationName()
+throw ( RuntimeException )
+{
+ return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( IMPLEMENTATIONNAME_ACTIONTRIGGERSEPARATOR ));
+}
+
+sal_Bool SAL_CALL ActionTriggerSeparatorPropertySet::supportsService( const ::rtl::OUString& ServiceName )
+throw ( RuntimeException )
+{
+ if ( ServiceName.equalsAscii( SERVICENAME_ACTIONTRIGGERSEPARATOR ))
+ return sal_True;
+
+ return sal_False;
+}
+
+Sequence< ::rtl::OUString > SAL_CALL ActionTriggerSeparatorPropertySet::getSupportedServiceNames()
+throw ( RuntimeException )
+{
+ Sequence< ::rtl::OUString > seqServiceNames( 1 );
+ seqServiceNames[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SERVICENAME_ACTIONTRIGGERSEPARATOR ));
+ return seqServiceNames;
+}
+
+// XTypeProvider
+Sequence< Type > SAL_CALL ActionTriggerSeparatorPropertySet::getTypes() throw ( RuntimeException )
+{
+ // Optimize this method !
+ // We initialize a static variable only one time. And we don't must use a mutex at every call!
+ // For the first call; pTypeCollection is NULL - for the second call pTypeCollection is different from NULL!
+ static ::cppu::OTypeCollection* pTypeCollection = NULL ;
+
+ if ( pTypeCollection == NULL )
+ {
+ // Ready for multithreading; get global mutex for first call of this method only! see before
+ osl::MutexGuard aGuard( osl::Mutex::getGlobalMutex() ) ;
+
+ // Control these pointer again ... it can be, that another instance will be faster then these!
+ if ( pTypeCollection == NULL )
+ {
+ // Create a static typecollection ...
+ static ::cppu::OTypeCollection aTypeCollection(
+ ::getCppuType(( const Reference< XPropertySet >*)NULL ) ,
+ ::getCppuType(( const Reference< XFastPropertySet >*)NULL ) ,
+ ::getCppuType(( const Reference< XMultiPropertySet >*)NULL ) ,
+ ::getCppuType(( const Reference< XServiceInfo >*)NULL ) ,
+ ::getCppuType(( const Reference< XTypeProvider >*)NULL ) ) ;
+
+ // ... and set his address to static pointer!
+ pTypeCollection = &aTypeCollection ;
+ }
+ }
+
+ return pTypeCollection->getTypes() ;
+}
+
+Sequence< sal_Int8 > SAL_CALL ActionTriggerSeparatorPropertySet::getImplementationId() throw ( RuntimeException )
+{
+ // Create one Id for all instances of this class.
+ // Use ethernet address to do this! (sal_True)
+
+ // Optimize this method
+ // We initialize a static variable only one time. And we don't must use a mutex at every call!
+ // For the first call; pID is NULL - for the second call pID is different from NULL!
+ static ::cppu::OImplementationId* pID = NULL ;
+
+ if ( pID == NULL )
+ {
+ // Ready for multithreading; get global mutex for first call of this method only! see before
+ osl::MutexGuard aGuard( osl::Mutex::getGlobalMutex() ) ;
+
+ // Control these pointer again ... it can be, that another instance will be faster then these!
+ if ( pID == NULL )
+ {
+ // Create a new static ID ...
+ static ::cppu::OImplementationId aID( sal_False ) ;
+ // ... and set his address to static pointer!
+ pID = &aID ;
+ }
+ }
+
+ return pID->getImplementationId() ;
+}
+
+//---------------------------------------------------------------------------------------------------------
+// OPropertySetHelper implementation
+//---------------------------------------------------------------------------------------------------------
+
+sal_Bool SAL_CALL ActionTriggerSeparatorPropertySet::convertFastPropertyValue(
+ Any& aConvertedValue,
+ Any& aOldValue,
+ sal_Int32 nHandle,
+ const Any& aValue )
+throw( IllegalArgumentException )
+{
+ // Check, if value of property will changed in method "setFastPropertyValue_NoBroadcast()".
+ // Return TRUE, if changed - else return FALSE.
+ // Attention: Method "impl_tryToChangeProperty()" can throw the IllegalArgumentException !!!
+ // Initialize return value with FALSE !!!
+ // (Handle can be invalid)
+ sal_Bool bReturn = sal_False;
+
+ switch( nHandle )
+ {
+ case HANDLE_TYPE:
+ bReturn = impl_tryToChangeProperty( m_nSeparatorType, aValue, aOldValue, aConvertedValue );
+ break;
+ }
+
+ // Return state of operation.
+ return bReturn;
+}
+
+
+void SAL_CALL ActionTriggerSeparatorPropertySet::setFastPropertyValue_NoBroadcast(
+ sal_Int32 nHandle, const Any& aValue )
+throw( Exception )
+{
+ ::osl::MutexGuard aGuard( LockHelper::getGlobalLock().getShareableOslMutex() );
+
+ // Search for right handle ... and try to set property value.
+ switch( nHandle )
+ {
+ case HANDLE_TYPE:
+ aValue >>= m_nSeparatorType;
+ break;
+ }
+}
+
+void SAL_CALL ActionTriggerSeparatorPropertySet::getFastPropertyValue(
+ Any& aValue, sal_Int32 nHandle ) const
+{
+ ::osl::MutexGuard aGuard( LockHelper::getGlobalLock().getShareableOslMutex() );
+
+ // Search for right handle ... and try to get property value.
+ switch( nHandle )
+ {
+ case HANDLE_TYPE:
+ aValue <<= m_nSeparatorType;
+ break;
+ }
+}
+
+::cppu::IPropertyArrayHelper& SAL_CALL ActionTriggerSeparatorPropertySet::getInfoHelper()
+{
+ // Optimize this method !
+ // We initialize a static variable only one time. And we don't must use a mutex at every call!
+ // For the first call; pInfoHelper is NULL - for the second call pInfoHelper is different from NULL!
+ static OPropertyArrayHelper* pInfoHelper = NULL;
+
+ if( pInfoHelper == NULL )
+ {
+ // Ready for multithreading
+ ::osl::MutexGuard aGuard( LockHelper::getGlobalLock().getShareableOslMutex() );
+ // Control this pointer again, another instance can be faster then these!
+ if( pInfoHelper == NULL )
+ {
+ // Define static member to give structure of properties to baseclass "OPropertySetHelper".
+ // "impl_getStaticPropertyDescriptor" is a non exported and static funtion, who will define a static propertytable.
+ // "sal_True" say: Table is sorted by name.
+ static OPropertyArrayHelper aInfoHelper( impl_getStaticPropertyDescriptor(), sal_True );
+ pInfoHelper = &aInfoHelper;
+ }
+ }
+
+ return (*pInfoHelper);
+}
+
+Reference< XPropertySetInfo > SAL_CALL ActionTriggerSeparatorPropertySet::getPropertySetInfo()
+throw ( RuntimeException )
+{
+ // Optimize this method !
+ // We initialize a static variable only one time. And we don't must use a mutex at every call!
+ // For the first call; pInfo is NULL - for the second call pInfo is different from NULL!
+ static Reference< XPropertySetInfo >* pInfo = NULL ;
+
+ if( pInfo == NULL )
+ {
+ // Ready for multithreading
+ ::osl::MutexGuard aGuard( LockHelper::getGlobalLock().getShareableOslMutex() );
+ // Control this pointer again, another instance can be faster then these!
+ if( pInfo == NULL )
+ {
+ // Create structure of propertysetinfo for baseclass "OPropertySetHelper".
+ // (Use method "getInfoHelper()".)
+ static Reference< XPropertySetInfo > xInfo( createPropertySetInfo( getInfoHelper() ) );
+ pInfo = &xInfo;
+ }
+ }
+
+ return (*pInfo);
+}
+
+const Sequence< Property > ActionTriggerSeparatorPropertySet::impl_getStaticPropertyDescriptor()
+{
+ static const Property pActionTriggerPropertys[] =
+ {
+ Property( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "SeparatorType" )), HANDLE_TYPE, ::getCppuType((sal_Int16*)0), PropertyAttribute::TRANSIENT )
+ };
+
+ // Use it to initialize sequence!
+ static const Sequence< Property > seqActionTriggerPropertyDescriptor( pActionTriggerPropertys, PROPERTYCOUNT );
+
+ // Return static "PropertyDescriptor"
+ return seqActionTriggerPropertyDescriptor ;
+}
+
+
+//******************************************************************************************************************************
+// private method
+//******************************************************************************************************************************
+sal_Bool ActionTriggerSeparatorPropertySet::impl_tryToChangeProperty(
+ sal_Int16 aCurrentValue ,
+ const Any& aNewValue ,
+ Any& aOldValue ,
+ Any& aConvertedValue )
+throw( IllegalArgumentException )
+{
+ // Set default return value if method failed.
+ sal_Bool bReturn = sal_False;
+ // Get new value from any.
+ // IllegalArgumentException() can be thrown!
+ sal_Int16 aValue = 0;
+ convertPropertyValue( aValue, aNewValue );
+
+ // If value change ...
+ if( aValue != aCurrentValue )
+ {
+ // ... set information of change.
+ aOldValue <<= aCurrentValue ;
+ aConvertedValue <<= aValue ;
+ // Return OK - "value will be change ..."
+ bReturn = sal_True;
+ }
+ else
+ {
+ // ... clear information of return parameter!
+ aOldValue.clear () ;
+ aConvertedValue.clear () ;
+ // Return NOTHING - "value will not be change ..."
+ bReturn = sal_False;
+ }
+
+ return bReturn;
+}
+
+}
+
diff --git a/framework/source/classes/addonmenu.cxx b/framework/source/classes/addonmenu.cxx
new file mode 100644
index 000000000000..4961a8f7c1f2
--- /dev/null
+++ b/framework/source/classes/addonmenu.cxx
@@ -0,0 +1,456 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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"
+
+//_________________________________________________________________________________________________________________
+// my own includes
+//_________________________________________________________________________________________________________________
+#include "classes/addonmenu.hxx"
+#include "classes/addonsoptions.hxx"
+#include <general.h>
+#include <macros/debug/assertion.hxx>
+#include <helper/imageproducer.hxx>
+#include <xml/menuconfiguration.hxx>
+
+//_________________________________________________________________________________________________________________
+// interface includes
+//_________________________________________________________________________________________________________________
+#include <com/sun/star/uno/Reference.hxx>
+#include <com/sun/star/util/URL.hpp>
+#include <com/sun/star/util/XURLTransformer.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+
+//_________________________________________________________________________________________________________________
+// includes of other projects
+//_________________________________________________________________________________________________________________
+#include <tools/config.hxx>
+#include <vcl/svapp.hxx>
+#include <svtools/menuoptions.hxx>
+#include <svl/solar.hrc>
+//_________________________________________________________________________________________________________________
+// namespace
+//_________________________________________________________________________________________________________________
+
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::frame;
+using namespace ::com::sun::star::beans;
+
+// Please look at sfx2/inc/sfxsids.hrc the values are defined there. Due to build dependencies
+// we cannot include the header file.
+const USHORT SID_HELPMENU = (SID_SFX_START + 410);
+const USHORT SID_ONLINE_REGISTRATION = (SID_SFX_START + 1537);
+
+namespace framework
+{
+
+AddonMenu::AddonMenu( const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame >& rFrame ) :
+ m_xFrame( rFrame )
+{
+}
+
+AddonMenu::~AddonMenu()
+{
+ for ( USHORT i = 0; i < GetItemCount(); i++ )
+ {
+ if ( GetItemType( i ) != MENUITEM_SEPARATOR )
+ {
+ // delete user attributes created with new!
+ USHORT nId = GetItemId( i );
+ MenuConfiguration::Attributes* pUserAttributes = (MenuConfiguration::Attributes*)GetUserValue( nId );
+ delete pUserAttributes;
+ delete GetPopupMenu( nId );
+ }
+ }
+}
+
+// ------------------------------------------------------------------------
+
+// ------------------------------------------------------------------------
+// Check if command URL string has the unique prefix to identify addon popup menus
+sal_Bool AddonPopupMenu::IsCommandURLPrefix( const ::rtl::OUString& aCmdURL )
+{
+ const char aPrefixCharBuf[] = ADDONSPOPUPMENU_URL_PREFIX_STR;
+
+ return aCmdURL.matchAsciiL( aPrefixCharBuf, sizeof( aPrefixCharBuf )-1, 0 );
+}
+
+AddonPopupMenu::AddonPopupMenu( const com::sun::star::uno::Reference< com::sun::star::frame::XFrame >& rFrame ) :
+ AddonMenu( rFrame )
+{
+}
+
+AddonPopupMenu::~AddonPopupMenu()
+{
+}
+
+// ------------------------------------------------------------------------
+
+static Reference< XModel > GetModelFromFrame( const Reference< XFrame >& rFrame )
+{
+ // Query for the model to get check the context information
+ Reference< XModel > xModel;
+ if ( rFrame.is() )
+ {
+ Reference< XController > xController( rFrame->getController(), UNO_QUERY );
+ if ( xController.is() )
+ xModel = xController->getModel();
+ }
+
+ return xModel;
+}
+
+// ------------------------------------------------------------------------
+
+sal_Bool AddonMenuManager::HasAddonMenuElements()
+{
+ return AddonsOptions().HasAddonsMenu();
+}
+
+sal_Bool AddonMenuManager::HasAddonHelpMenuElements()
+{
+ return AddonsOptions().HasAddonsHelpMenu();
+}
+
+// Factory method to create different Add-On menu types
+PopupMenu* AddonMenuManager::CreatePopupMenuType( MenuType eMenuType, const Reference< XFrame >& rFrame )
+{
+ if ( eMenuType == ADDON_MENU )
+ return new AddonMenu( rFrame );
+ else if ( eMenuType == ADDON_POPUPMENU )
+ return new AddonPopupMenu( rFrame );
+ else
+ return NULL;
+}
+
+// Create the Add-Ons menu
+AddonMenu* AddonMenuManager::CreateAddonMenu( const Reference< XFrame >& rFrame )
+{
+ AddonsOptions aOptions;
+ AddonMenu* pAddonMenu = NULL;
+ USHORT nUniqueMenuId = ADDONMENU_ITEMID_START;
+
+ const Sequence< Sequence< PropertyValue > >& rAddonMenuEntries = aOptions.GetAddonsMenu();
+ if ( rAddonMenuEntries.getLength() > 0 )
+ {
+ pAddonMenu = (AddonMenu *)AddonMenuManager::CreatePopupMenuType( ADDON_MENU, rFrame );
+ Reference< XModel > xModel = GetModelFromFrame( rFrame );
+ AddonMenuManager::BuildMenu( pAddonMenu, ADDON_MENU, MENU_APPEND, nUniqueMenuId, rAddonMenuEntries, rFrame, xModel );
+
+ // Don't return an empty Add-On menu
+ if ( pAddonMenu->GetItemCount() == 0 )
+ {
+ delete pAddonMenu;
+ pAddonMenu = NULL;
+ }
+ }
+
+ return pAddonMenu;
+}
+
+// Returns the next insert position from nPos.
+USHORT AddonMenuManager::GetNextPos( USHORT nPos )
+{
+ return ( nPos == MENU_APPEND ) ? MENU_APPEND : ( nPos+1 );
+}
+
+
+static USHORT FindMenuId( Menu* pMenu, const String aCommand )
+{
+ USHORT nPos = 0;
+ String aCmd;
+ for ( nPos = 0; nPos < pMenu->GetItemCount(); nPos++ )
+ {
+ USHORT nId = pMenu->GetItemId( nPos );
+ aCmd = pMenu->GetItemCommand( nId );
+ if ( aCmd == aCommand )
+ return nId;
+ }
+
+ return USHRT_MAX;
+}
+
+
+// Merge the Add-Ons help menu items into the given menu bar at a defined pos
+void AddonMenuManager::MergeAddonHelpMenu( const Reference< XFrame >& rFrame, MenuBar* pMergeMenuBar )
+{
+ if ( pMergeMenuBar )
+ {
+ PopupMenu* pHelpMenu = pMergeMenuBar->GetPopupMenu( SID_HELPMENU );
+ if ( !pHelpMenu )
+ {
+ USHORT nId = FindMenuId( pMergeMenuBar, String::CreateFromAscii( ".uno:HelpMenu" ));
+ if ( nId != USHRT_MAX )
+ pHelpMenu = pMergeMenuBar->GetPopupMenu( nId );
+ }
+
+ if ( pHelpMenu )
+ {
+ static const char REFERENCECOMMAND_AFTER[] = ".uno:OnlineRegistrationDlg";
+ static const char REFERENCECOMMAND_BEFORE[] = ".uno:About";
+
+ // Add-Ons help menu items should be inserted after the "registration" menu item
+ bool bAddAfter = true;
+ USHORT nItemCount = pHelpMenu->GetItemCount();
+ USHORT nRegPos = pHelpMenu->GetItemPos( SID_ONLINE_REGISTRATION );
+ USHORT nInsPos = nRegPos;
+ USHORT nInsSepAfterPos = MENU_APPEND;
+ USHORT nUniqueMenuId = ADDONMENU_ITEMID_START;
+ AddonsOptions aOptions;
+
+ if ( nRegPos == USHRT_MAX )
+ {
+ // try to detect the online registration dialog menu item with the command URL
+ USHORT nId = FindMenuId( pHelpMenu, String::CreateFromAscii( REFERENCECOMMAND_AFTER ));
+ nRegPos = pHelpMenu->GetItemPos( nId );
+ nInsPos = nRegPos;
+ }
+
+ if ( nRegPos == USHRT_MAX )
+ {
+ // second try:
+ // try to detect the about menu item with the command URL
+ USHORT nId = FindMenuId( pHelpMenu, String::CreateFromAscii( REFERENCECOMMAND_BEFORE ));
+ nRegPos = pHelpMenu->GetItemPos( nId );
+ nInsPos = nRegPos;
+ bAddAfter = false;
+ }
+
+ Sequence< Sequence< PropertyValue > > aAddonSubMenu;
+ const Sequence< Sequence< PropertyValue > >& rAddonHelpMenuEntries = aOptions.GetAddonsHelpMenu();
+
+ nInsPos = bAddAfter ? AddonMenuManager::GetNextPos( nInsPos ) : nInsPos;
+ if ( nInsPos < nItemCount && pHelpMenu->GetItemType( nInsPos ) != MENUITEM_SEPARATOR )
+ nInsSepAfterPos = nInsPos;
+
+ Reference< XModel > xModel = GetModelFromFrame( rFrame );
+ AddonMenuManager::BuildMenu( pHelpMenu, ADDON_MENU, nInsPos, nUniqueMenuId, rAddonHelpMenuEntries, rFrame, xModel );
+
+ if ( pHelpMenu->GetItemCount() > nItemCount )
+ {
+ if ( nInsSepAfterPos < MENU_APPEND )
+ {
+ nInsSepAfterPos += ( pHelpMenu->GetItemCount() - nItemCount );
+ if ( pHelpMenu->GetItemType( nInsSepAfterPos ) != MENUITEM_SEPARATOR )
+ pHelpMenu->InsertSeparator( nInsSepAfterPos );
+ }
+ if ( nRegPos < MENU_APPEND )
+ pHelpMenu->InsertSeparator( nRegPos+1 );
+ else
+ pHelpMenu->InsertSeparator( nItemCount );
+ }
+ }
+ }
+}
+
+// Merge the addon popup menus into the given menu bar at the provided pos.
+void AddonMenuManager::MergeAddonPopupMenus( const Reference< XFrame >& rFrame,
+ const Reference< XModel >& rModel,
+ USHORT nMergeAtPos,
+ MenuBar* pMergeMenuBar )
+{
+ if ( pMergeMenuBar )
+ {
+ AddonsOptions aAddonsOptions;
+ USHORT nInsertPos = nMergeAtPos;
+
+ ::rtl::OUString aTitle;
+ ::rtl::OUString aURL;
+ ::rtl::OUString aTarget;
+ ::rtl::OUString aImageId;
+ ::rtl::OUString aContext;
+ Sequence< Sequence< PropertyValue > > aAddonSubMenu;
+ USHORT nUniqueMenuId = ADDONMENU_ITEMID_START;
+
+ const Sequence< Sequence< PropertyValue > >& rAddonMenuEntries = aAddonsOptions.GetAddonsMenuBarPart();
+ for ( sal_Int32 i = 0; i < rAddonMenuEntries.getLength(); i++ )
+ {
+ AddonMenuManager::GetMenuEntry( rAddonMenuEntries[i],
+ aTitle,
+ aURL,
+ aTarget,
+ aImageId,
+ aContext,
+ aAddonSubMenu );
+ if ( aTitle.getLength() > 0 &&
+ aURL.getLength() > 0 &&
+ aAddonSubMenu.getLength() > 0 &&
+ AddonMenuManager::IsCorrectContext( rModel, aContext ))
+ {
+ USHORT nId = nUniqueMenuId++;
+ AddonPopupMenu* pAddonPopupMenu = (AddonPopupMenu *)AddonMenuManager::CreatePopupMenuType( ADDON_POPUPMENU, rFrame );
+
+ AddonMenuManager::BuildMenu( pAddonPopupMenu, ADDON_MENU, MENU_APPEND, nUniqueMenuId, aAddonSubMenu, rFrame, rModel );
+
+ if ( pAddonPopupMenu->GetItemCount() > 0 )
+ {
+ pAddonPopupMenu->SetCommandURL( aURL );
+ pMergeMenuBar->InsertItem( nId, aTitle, 0, nInsertPos++ );
+ pMergeMenuBar->SetPopupMenu( nId, pAddonPopupMenu );
+
+ // Store the command URL into the VCL menu bar for later identification
+ pMergeMenuBar->SetItemCommand( nId, aURL );
+ }
+ else
+ delete pAddonPopupMenu;
+ }
+ }
+ }
+}
+
+// Insert the menu and sub menu entries into pCurrentMenu with the aAddonMenuDefinition provided
+void AddonMenuManager::BuildMenu( PopupMenu* pCurrentMenu,
+ MenuType nSubMenuType,
+ USHORT nInsPos,
+ USHORT& nUniqueMenuId,
+ Sequence< Sequence< PropertyValue > > aAddonMenuDefinition,
+ const Reference< XFrame >& rFrame,
+ const Reference< XModel >& rModel )
+{
+ Sequence< Sequence< PropertyValue > > aAddonSubMenu;
+ BOOL bInsertSeparator = FALSE;
+ UINT32 i = 0;
+ UINT32 nElements = 0;
+ UINT32 nCount = aAddonMenuDefinition.getLength();
+ AddonsOptions aAddonsOptions;
+
+ ::rtl::OUString aTitle;
+ ::rtl::OUString aURL;
+ ::rtl::OUString aTarget;
+ ::rtl::OUString aImageId;
+ ::rtl::OUString aContext;
+
+ for ( i = 0; i < nCount; ++i )
+ {
+ GetMenuEntry( aAddonMenuDefinition[i], aTitle, aURL, aTarget, aImageId, aContext, aAddonSubMenu );
+
+ if ( !IsCorrectContext( rModel, aContext ) || ( !aTitle.getLength() && !aURL.getLength() ))
+ continue;
+
+ if ( aURL == ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "private:separator" )))
+ bInsertSeparator = TRUE;
+ else
+ {
+ PopupMenu* pSubMenu = NULL;
+ if ( aAddonSubMenu.getLength() > 0 )
+ {
+ pSubMenu = AddonMenuManager::CreatePopupMenuType( nSubMenuType, rFrame );
+ AddonMenuManager::BuildMenu( pSubMenu, nSubMenuType, MENU_APPEND, nUniqueMenuId, aAddonSubMenu, rFrame, rModel );
+
+ // Don't create a menu item for an empty sub menu
+ if ( pSubMenu->GetItemCount() == 0 )
+ {
+ delete pSubMenu;
+ pSubMenu = NULL;
+ continue;
+ }
+ }
+
+ if ( bInsertSeparator && nElements > 0 )
+ {
+ // Insert a separator only when we insert a new element afterwards and we
+ // have already one before us
+ nElements = 0;
+ bInsertSeparator = FALSE;
+ pCurrentMenu->InsertSeparator( nInsPos );
+ nInsPos = AddonMenuManager::GetNextPos( nInsPos );
+ }
+
+ USHORT nId = nUniqueMenuId++;
+ pCurrentMenu->InsertItem( nId, aTitle, 0, nInsPos );
+ nInsPos = AddonMenuManager::GetNextPos( nInsPos );
+
+ ++nElements;
+
+ // Store values from configuration to the New and Wizard menu entries to enable
+ // sfx2 based code to support high contrast mode correctly!
+ pCurrentMenu->SetUserValue( nId, ULONG( new MenuConfiguration::Attributes( aTarget, aImageId )) );
+ pCurrentMenu->SetItemCommand( nId, aURL );
+
+ if ( pSubMenu )
+ pCurrentMenu->SetPopupMenu( nId, pSubMenu );
+ }
+ }
+}
+
+// Retrieve the menu entry property values from a sequence
+void AddonMenuManager::GetMenuEntry( const Sequence< PropertyValue >& rAddonMenuEntry,
+ ::rtl::OUString& rTitle,
+ ::rtl::OUString& rURL,
+ ::rtl::OUString& rTarget,
+ ::rtl::OUString& rImageId,
+ ::rtl::OUString& rContext,
+ Sequence< Sequence< PropertyValue > >& rAddonSubMenu )
+{
+ // Reset submenu parameter
+ rAddonSubMenu = Sequence< Sequence< PropertyValue > >();
+
+ for ( int i = 0; i < rAddonMenuEntry.getLength(); i++ )
+ {
+ ::rtl::OUString aMenuEntryPropName = rAddonMenuEntry[i].Name;
+ if ( aMenuEntryPropName == ADDONSMENUITEM_PROPERTYNAME_URL )
+ rAddonMenuEntry[i].Value >>= rURL;
+ else if ( aMenuEntryPropName == ADDONSMENUITEM_PROPERTYNAME_TITLE )
+ rAddonMenuEntry[i].Value >>= rTitle;
+ else if ( aMenuEntryPropName == ADDONSMENUITEM_PROPERTYNAME_TARGET )
+ rAddonMenuEntry[i].Value >>= rTarget;
+ else if ( aMenuEntryPropName == ADDONSMENUITEM_PROPERTYNAME_IMAGEIDENTIFIER )
+ rAddonMenuEntry[i].Value >>= rImageId;
+ else if ( aMenuEntryPropName == ADDONSMENUITEM_PROPERTYNAME_SUBMENU )
+ rAddonMenuEntry[i].Value >>= rAddonSubMenu;
+ else if ( aMenuEntryPropName == ADDONSMENUITEM_PROPERTYNAME_CONTEXT )
+ rAddonMenuEntry[i].Value >>= rContext;
+ }
+}
+
+// Check if the context string matches the provided xModel context
+sal_Bool AddonMenuManager::IsCorrectContext( const Reference< XModel >& rModel, const ::rtl::OUString& aContext )
+{
+ if ( rModel.is() )
+ {
+ Reference< com::sun::star::lang::XServiceInfo > xServiceInfo( rModel, UNO_QUERY );
+ if ( xServiceInfo.is() )
+ {
+ sal_Int32 nIndex = 0;
+ do
+ {
+ ::rtl::OUString aToken = aContext.getToken( 0, ',', nIndex );
+
+ if ( xServiceInfo->supportsService( aToken ))
+ return sal_True;
+ }
+ while ( nIndex >= 0 );
+ }
+ }
+
+ return ( aContext.getLength() == 0 );
+}
+
+}
+
diff --git a/framework/source/classes/addonsoptions.cxx b/framework/source/classes/addonsoptions.cxx
new file mode 100644
index 000000000000..9bdaeb7dfda3
--- /dev/null
+++ b/framework/source/classes/addonsoptions.cxx
@@ -0,0 +1,1858 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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;
+}
+
+}
+
diff --git a/framework/source/classes/bmkmenu.cxx b/framework/source/classes/bmkmenu.cxx
new file mode 100644
index 000000000000..aa2aef3b9d2b
--- /dev/null
+++ b/framework/source/classes/bmkmenu.cxx
@@ -0,0 +1,254 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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"
+
+//_________________________________________________________________________________________________________________
+// my own includes
+//_________________________________________________________________________________________________________________
+
+#include <limits.h>
+
+#include "classes/bmkmenu.hxx"
+#include <general.h>
+#include <macros/debug/assertion.hxx>
+#include <helper/imageproducer.hxx>
+#include <xml/menuconfiguration.hxx>
+
+//_________________________________________________________________________________________________________________
+// interface includes
+//_________________________________________________________________________________________________________________
+#include <com/sun/star/uno/Reference.h>
+#include <com/sun/star/util/URL.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#ifndef _UNOTOOLS_PROCESSFACTORY_HXX
+#include <comphelper/processfactory.hxx>
+#endif
+#include <com/sun/star/util/XURLTransformer.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/util/DateTime.hpp>
+
+//_________________________________________________________________________________________________________________
+// includes of other projects
+//_________________________________________________________________________________________________________________
+#include <tools/config.hxx>
+#include <vcl/svapp.hxx>
+#include <unotools/dynamicmenuoptions.hxx>
+#include <svtools/menuoptions.hxx>
+#include <rtl/logfile.hxx>
+
+//_________________________________________________________________________________________________________________
+// namespace
+//_________________________________________________________________________________________________________________
+
+using namespace ::comphelper;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::util;
+using namespace ::com::sun::star::frame;
+using namespace ::com::sun::star::beans;
+
+namespace framework
+{
+
+void GetMenuEntry(
+ Sequence< PropertyValue >& aDynamicMenuEntry,
+ ::rtl::OUString& rTitle,
+ ::rtl::OUString& rURL,
+ ::rtl::OUString& rFrame,
+ ::rtl::OUString& rImageId );
+
+class BmkMenu_Impl
+{
+ private:
+ static USHORT m_nMID;
+
+ public:
+ BmkMenu* m_pRoot;
+ BOOL m_bInitialized;
+
+ BmkMenu_Impl( BmkMenu* pRoot );
+ BmkMenu_Impl();
+ ~BmkMenu_Impl();
+
+ static USHORT GetMID();
+};
+
+USHORT BmkMenu_Impl::m_nMID = BMKMENU_ITEMID_START;
+
+BmkMenu_Impl::BmkMenu_Impl( BmkMenu* pRoot ) :
+ m_pRoot(pRoot),
+ m_bInitialized(FALSE)
+{
+}
+
+BmkMenu_Impl::BmkMenu_Impl() :
+ m_pRoot(0),
+ m_bInitialized(FALSE)
+{
+}
+
+BmkMenu_Impl::~BmkMenu_Impl()
+{
+}
+
+USHORT BmkMenu_Impl::GetMID()
+{
+ m_nMID++;
+ if( !m_nMID )
+ m_nMID = BMKMENU_ITEMID_START;
+ return m_nMID;
+}
+
+// ------------------------------------------------------------------------
+
+BmkMenu::BmkMenu( com::sun::star::uno::Reference< XFrame >& xFrame, BmkMenu::BmkMenuType nType, BmkMenu* pRoot )
+ :AddonMenu(xFrame)
+ ,m_nType( nType )
+{
+ _pImp = new BmkMenu_Impl( pRoot );
+ Initialize();
+}
+
+BmkMenu::BmkMenu( Reference< XFrame >& xFrame, BmkMenu::BmkMenuType nType )
+ :AddonMenu(xFrame)
+ ,m_nType( nType )
+{
+ _pImp = new BmkMenu_Impl();
+ Initialize();
+}
+
+BmkMenu::~BmkMenu()
+{
+ delete _pImp;
+}
+
+void BmkMenu::Initialize()
+{
+ RTL_LOGFILE_CONTEXT( aLog, "framework (cd100003) ::BmkMenu::Initialize" );
+
+ if( _pImp->m_bInitialized )
+ return;
+
+ _pImp->m_bInitialized = TRUE;
+
+ Sequence< Sequence< PropertyValue > > aDynamicMenuEntries;
+
+ if ( m_nType == BmkMenu::BMK_NEWMENU )
+ aDynamicMenuEntries = SvtDynamicMenuOptions().GetMenu( E_NEWMENU );
+ else if ( m_nType == BmkMenu::BMK_WIZARDMENU )
+ aDynamicMenuEntries = SvtDynamicMenuOptions().GetMenu( E_WIZARDMENU );
+
+ const StyleSettings& rSettings = Application::GetSettings().GetStyleSettings();
+ BOOL bShowMenuImages = rSettings.GetUseImagesInMenus();
+
+ ::rtl::OUString aTitle;
+ ::rtl::OUString aURL;
+ ::rtl::OUString aTargetFrame;
+ ::rtl::OUString aImageId;
+
+ BOOL bIsHiContrastMode = rSettings.GetHighContrastMode();
+
+ UINT32 i, nCount = aDynamicMenuEntries.getLength();
+ for ( i = 0; i < nCount; ++i )
+ {
+ GetMenuEntry( aDynamicMenuEntries[i], aTitle, aURL, aTargetFrame, aImageId );
+
+ if ( !aTitle.getLength() && !aURL.getLength() )
+ continue;
+
+ if ( aURL == ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "private:separator" )))
+ InsertSeparator();
+ else
+ {
+ sal_Bool bImageSet = sal_False;
+ USHORT nId = CreateMenuId();
+
+ if ( bShowMenuImages )
+ {
+ if ( aImageId.getLength() > 0 )
+ {
+ Image aImage = GetImageFromURL( m_xFrame, aImageId, FALSE, bIsHiContrastMode );
+ if ( !!aImage )
+ {
+ bImageSet = sal_True;
+ InsertItem( nId, aTitle, aImage );
+ }
+ }
+
+ if ( !bImageSet )
+ {
+ Image aImage = GetImageFromURL( m_xFrame, aURL, FALSE, bIsHiContrastMode );
+ if ( !aImage )
+ InsertItem( nId, aTitle );
+ else
+ InsertItem( nId, aTitle, aImage );
+ }
+ }
+ else
+ InsertItem( nId, aTitle );
+
+ // Store values from configuration to the New and Wizard menu entries to enable
+ // sfx2 based code to support high contrast mode correctly!
+ MenuConfiguration::Attributes* pUserAttributes = new MenuConfiguration::Attributes( aTargetFrame, aImageId );
+ SetUserValue( nId, (ULONG)pUserAttributes );
+
+ SetItemCommand( nId, aURL );
+ }
+ }
+}
+
+USHORT BmkMenu::CreateMenuId()
+{
+ return BmkMenu_Impl::GetMID();
+}
+
+void GetMenuEntry
+(
+ Sequence< PropertyValue >& aDynamicMenuEntry,
+ ::rtl::OUString& rTitle,
+ ::rtl::OUString& rURL,
+ ::rtl::OUString& rFrame,
+ ::rtl::OUString& rImageId
+)
+{
+ for ( int i = 0; i < aDynamicMenuEntry.getLength(); i++ )
+ {
+ if ( aDynamicMenuEntry[i].Name == DYNAMICMENU_PROPERTYNAME_URL )
+ aDynamicMenuEntry[i].Value >>= rURL;
+ else if ( aDynamicMenuEntry[i].Name == DYNAMICMENU_PROPERTYNAME_TITLE )
+ aDynamicMenuEntry[i].Value >>= rTitle;
+ else if ( aDynamicMenuEntry[i].Name == DYNAMICMENU_PROPERTYNAME_IMAGEIDENTIFIER )
+ aDynamicMenuEntry[i].Value >>= rImageId;
+ else if ( aDynamicMenuEntry[i].Name == DYNAMICMENU_PROPERTYNAME_TARGETNAME )
+ aDynamicMenuEntry[i].Value >>= rFrame;
+ }
+}
+
+}
+
diff --git a/framework/source/classes/converter.cxx b/framework/source/classes/converter.cxx
new file mode 100644
index 000000000000..d70b099c9e03
--- /dev/null
+++ b/framework/source/classes/converter.cxx
@@ -0,0 +1,316 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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"
+#include <classes/converter.hxx>
+#include <rtl/ustrbuf.hxx>
+
+namespace framework{
+
+//-----------------------------------------------------------------------------
+/**
+ * pack every property item of source list into an any entry of destination list
+ * Resulting list will have follow format then: "sequence< Any(PropertyValue) >".
+ * If one item couldn't be converted it will be ignored - means target list can
+ * be smaller then source list. Source list isn't changed anytime.
+ *
+ * algorithm:
+ * (a) reserve enough space on destination list for all possible entries of
+ * source list
+ * (b) try to pack every property of source into an any of destination list
+ * (b1) count successfully packed entries only
+ * (c) use this count of packed entries to resize destination list
+ * Because we getted enough space before - that will remove unused items
+ * of destination list at the end of it only.
+ */
+css::uno::Sequence< css::uno::Any > Converter::convert_seqProp2seqAny( const css::uno::Sequence< css::beans::PropertyValue >& lSource )
+{
+ sal_Int32 nCount = lSource.getLength();
+ css::uno::Sequence< css::uno::Any > lDestination(nCount);
+
+ for (sal_Int32 nItem=0; nItem<nCount; ++nItem)
+ lDestination[nItem]<<=lSource[nItem];
+
+ return lDestination;
+}
+
+//-----------------------------------------------------------------------------
+/**
+ * do the same like convert_seqProp2seqAny() before - but reverse.
+ * It try to unpack PropertyValue items from given Any's.
+ */
+css::uno::Sequence< css::beans::PropertyValue > Converter::convert_seqAny2seqProp( const css::uno::Sequence< css::uno::Any >& lSource )
+{
+ sal_Int32 nCount = lSource.getLength();
+ sal_Int32 nRealCount = 0;
+ css::uno::Sequence< css::beans::PropertyValue > lDestination(nCount);
+
+ for (sal_Int32 nItem=0; nItem<nCount; ++nItem)
+ {
+ if (lSource[nItem]>>=lDestination[nItem])
+ ++nRealCount;
+ }
+
+ if (nRealCount!=nCount)
+ lDestination.realloc(nRealCount);
+
+ return lDestination;
+}
+
+//-----------------------------------------------------------------------------
+/**
+ * converts a sequence of NamedValue to a sequence of PropertyValue.
+ */
+css::uno::Sequence< css::beans::PropertyValue > Converter::convert_seqNamedVal2seqPropVal( const css::uno::Sequence< css::beans::NamedValue >& lSource )
+{
+ sal_Int32 nCount = lSource.getLength();
+ css::uno::Sequence< css::beans::PropertyValue > lDestination(nCount);
+ for (sal_Int32 nItem=0; nItem<nCount; ++nItem)
+ {
+ lDestination[nItem].Name = lSource[nItem].Name ;
+ lDestination[nItem].Value = lSource[nItem].Value;
+ }
+ return lDestination;
+}
+
+//-----------------------------------------------------------------------------
+/**
+ * converts a sequence of PropertyValue to a sequence of NamedValue.
+ */
+css::uno::Sequence< css::beans::NamedValue > Converter::convert_seqPropVal2seqNamedVal( const css::uno::Sequence< css::beans::PropertyValue >& lSource )
+{
+ sal_Int32 nCount = lSource.getLength();
+ css::uno::Sequence< css::beans::NamedValue > lDestination(nCount);
+ for (sal_Int32 nItem=0; nItem<nCount; ++nItem)
+ {
+ lDestination[nItem].Name = lSource[nItem].Name ;
+ lDestination[nItem].Value = lSource[nItem].Value;
+ }
+ return lDestination;
+}
+
+//-----------------------------------------------------------------------------
+/**
+ * converts a sequence of unicode strings into a vector of such items
+ */
+OUStringList Converter::convert_seqOUString2OUStringList( const css::uno::Sequence< ::rtl::OUString >& lSource )
+{
+ OUStringList lDestination;
+ sal_Int32 nCount = lSource.getLength();
+
+ for (sal_Int32 nItem=0; nItem<nCount; ++nItem )
+ {
+ lDestination.push_back(lSource[nItem]);
+ }
+
+ return lDestination;
+}
+
+//-----------------------------------------------------------------------------
+/**
+ * converts a vector of unicode strings into a sequence of such items
+ */
+css::uno::Sequence< ::rtl::OUString > Converter::convert_OUStringList2seqOUString( const OUStringList& lSource )
+{
+ css::uno::Sequence< ::rtl::OUString > lDestination(lSource.size());
+ sal_uInt32 nItem = 0;
+ for (OUStringList::const_iterator pIterator=lSource.begin(); pIterator!=lSource.end(); ++pIterator)
+ {
+ lDestination[nItem] = *pIterator;
+ ++nItem;
+ }
+ return lDestination;
+}
+
+//-----------------------------------------------------------------------------
+/**
+ * converts an unicode string hash to a sequence<PropertyValue>, where names and values match to key and values.
+ */
+css::uno::Sequence< css::beans::PropertyValue > Converter::convert_OUStringHash2seqProp( const OUStringHash& lSource )
+{
+ css::uno::Sequence< css::beans::PropertyValue > lDestination (lSource.size());
+ css::beans::PropertyValue* pDestination = lDestination.getArray();
+ sal_Int32 nItem = 0;
+ for (OUStringHash::const_iterator pItem=lSource.begin(); pItem!=lSource.end(); ++pItem)
+ {
+ pDestination[nItem].Name = pItem->first ;
+ pDestination[nItem].Value <<= pItem->second;
+ ++nItem;
+ }
+ return lDestination;
+}
+
+//-----------------------------------------------------------------------------
+/**
+ * converts a sequence<PropertyValue> to an unicode string hash, where keys and values match to names and values.
+ */
+OUStringHash Converter::convert_seqProp2OUStringHash( const css::uno::Sequence< css::beans::PropertyValue >& lSource )
+{
+ OUStringHash lDestination;
+ sal_Int32 nCount = lSource.getLength();
+ const css::beans::PropertyValue* pSource = lSource.getConstArray();
+ for (sal_Int32 nItem=0; nItem<nCount; ++nItem)
+ {
+ pSource[nItem].Value >>= lDestination[pSource[nItem].Name];
+ }
+ return lDestination;
+}
+
+//-----------------------------------------------------------------------------
+/**
+ @short convert timestamp from String to tools::DateTime notation
+ @descr Format: "<day>.<month>.<year>/<hour>:<min>:<sec>"
+ e.g. : "1.11.2001/13:45:16"
+
+ @param sString
+ timestamp in string notation
+
+ @return timestamp in DateTime notation
+ */
+DateTime Converter::convert_String2DateTime( /*IN*/ const ::rtl::OUString& sSource )
+{
+ DateTime aStamp ;
+ sal_Int32 nIndex = 0;
+
+ sal_uInt16 nDay = (sal_uInt16)(sSource.getToken( 0, (sal_Unicode)'.', nIndex ).toInt32());
+ if( nIndex>0 )
+ {
+ sal_uInt16 nMonth = (sal_uInt16)(sSource.getToken( 0, (sal_Unicode)'.', nIndex ).toInt32());
+ if( nIndex>0 )
+ {
+ sal_uInt16 nYear = (sal_uInt16)(sSource.getToken( 0, (sal_Unicode)'/', nIndex ).toInt32());
+ if( nIndex>0 )
+ {
+ sal_uInt32 nHour = sSource.getToken( 0, (sal_Unicode)':', nIndex ).toInt32();
+ if( nIndex>0 )
+ {
+ sal_uInt32 nMin = sSource.getToken( 0, (sal_Unicode)':', nIndex ).toInt32();
+ if( nIndex>0 && nIndex<sSource.getLength() )
+ {
+ sal_uInt32 nSec = sSource.copy( nIndex, sSource.getLength()-nIndex ).toInt32();
+
+ Date aDate( nDay , nMonth, nYear );
+ Time aTime( nHour, nMin , nSec );
+ aStamp = DateTime( aDate, aTime );
+ }
+ }
+ }
+ }
+ }
+ return aStamp;
+}
+
+//-----------------------------------------------------------------------------
+/**
+ @short convert timestamp from DateTime to String notation
+ @descr Format: "<day>.<month>.<year>/<hour>:<min>:<sec>"
+ e.g. : "1.11.2001/13:45:16"
+
+ @param aStamp
+ timestamp in DateTime notation
+
+ @return timestamp in String notation
+ */
+::rtl::OUString Converter::convert_DateTime2String( /*IN*/ const DateTime& aSource )
+{
+ ::rtl::OUStringBuffer sBuffer(25);
+
+ sBuffer.append( (sal_Int32)aSource.GetDay() );
+ sBuffer.append( (sal_Unicode)'.' );
+ sBuffer.append( (sal_Int32)aSource.GetMonth() );
+ sBuffer.append( (sal_Unicode)'.' );
+ sBuffer.append( (sal_Int32)aSource.GetYear() );
+ sBuffer.append( (sal_Unicode)'/' );
+ sBuffer.append( (sal_Int32)aSource.GetHour() );
+ sBuffer.append( (sal_Unicode)':' );
+ sBuffer.append( (sal_Int32)aSource.GetMin() );
+ sBuffer.append( (sal_Unicode)':' );
+ sBuffer.append( (sal_Int32)aSource.GetSec() );
+
+ return sBuffer.makeStringAndClear();
+}
+
+::rtl::OUString Converter::convert_DateTime2ISO8601( const DateTime& aSource )
+{
+ ::rtl::OUStringBuffer sBuffer(25);
+
+ sal_Int32 nYear = aSource.GetYear();
+ sal_Int32 nMonth = aSource.GetMonth();
+ sal_Int32 nDay = aSource.GetDay();
+
+ sal_Int32 nHour = aSource.GetHour();
+ sal_Int32 nMin = aSource.GetMin();
+ sal_Int32 nSec = aSource.GetSec();
+
+ // write year formated as "YYYY"
+ if (nYear<10)
+ sBuffer.appendAscii("000");
+ else
+ if (nYear<100)
+ sBuffer.appendAscii("00");
+ else
+ if (nYear<1000)
+ sBuffer.appendAscii("0");
+ sBuffer.append( (sal_Int32)nYear );
+
+ sBuffer.appendAscii("-");
+ // write month formated as "MM"
+ if (nMonth<10)
+ sBuffer.appendAscii("0");
+ sBuffer.append( (sal_Int32)nMonth );
+
+ sBuffer.appendAscii("-");
+ // write day formated as "DD"
+ if (nDay<10)
+ sBuffer.appendAscii("0");
+ sBuffer.append( (sal_Int32)nDay );
+
+ sBuffer.appendAscii("T");
+ // write hours formated as "hh"
+ if (nHour<10)
+ sBuffer.appendAscii("0");
+ sBuffer.append( (sal_Int32)nHour );
+
+ sBuffer.appendAscii(":");
+ // write min formated as "mm"
+ if (nMin<10)
+ sBuffer.appendAscii("0");
+ sBuffer.append( (sal_Int32)nMin );
+
+ sBuffer.appendAscii(":");
+ // write sec formated as "ss"
+ if (nSec<10)
+ sBuffer.appendAscii("0");
+ sBuffer.append( (sal_Int32)nSec );
+
+ sBuffer.appendAscii("Z");
+
+ return sBuffer.makeStringAndClear();
+}
+
+} // namespace framework
diff --git a/framework/source/classes/droptargetlistener.cxx b/framework/source/classes/droptargetlistener.cxx
new file mode 100644
index 000000000000..69226cba3162
--- /dev/null
+++ b/framework/source/classes/droptargetlistener.cxx
@@ -0,0 +1,254 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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"
+
+//_________________________________________________________________________________________________________________
+// my own includes
+//_________________________________________________________________________________________________________________
+#include <classes/droptargetlistener.hxx>
+#include <threadhelp/readguard.hxx>
+#include <threadhelp/writeguard.hxx>
+#include <targets.h>
+#include <services.h>
+
+//_________________________________________________________________________________________________________________
+// interface includes
+//_________________________________________________________________________________________________________________
+#include <com/sun/star/datatransfer/dnd/DNDConstants.hpp>
+#include <com/sun/star/frame/XDispatch.hpp>
+#include <com/sun/star/frame/XDispatchProvider.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/util/XURLTransformer.hpp>
+
+//_________________________________________________________________________________________________________________
+// includes of other projects
+//_________________________________________________________________________________________________________________
+#include <svtools/transfer.hxx>
+#include <unotools/localfilehelper.hxx>
+#include <sot/filelist.hxx>
+
+#include <osl/file.hxx>
+#include <vcl/svapp.hxx>
+
+//_________________________________________________________________________________________________________________
+// namespace
+//_________________________________________________________________________________________________________________
+
+namespace framework
+{
+
+DropTargetListener::DropTargetListener( const css::uno::Reference< css::lang::XMultiServiceFactory >& xFactory,
+ const css::uno::Reference< css::frame::XFrame >& xFrame )
+ : ThreadHelpBase ( &Application::GetSolarMutex() )
+ , m_xFactory ( xFactory )
+ , m_xTargetFrame ( xFrame )
+ , m_pFormats ( new DataFlavorExVector )
+{
+}
+
+// -----------------------------------------------------------------------------
+
+DropTargetListener::~DropTargetListener()
+{
+ m_xTargetFrame = css::uno::WeakReference< css::frame::XFrame >();
+ m_xFactory = css::uno::Reference< css::lang::XMultiServiceFactory >();
+ delete m_pFormats;
+ m_pFormats = NULL;
+}
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL DropTargetListener::disposing( const css::lang::EventObject& ) throw( css::uno::RuntimeException )
+{
+ m_xTargetFrame = css::uno::WeakReference< css::frame::XFrame >();
+ m_xFactory = css::uno::Reference< css::lang::XMultiServiceFactory >();
+}
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL DropTargetListener::drop( const css::datatransfer::dnd::DropTargetDropEvent& dtde ) throw( css::uno::RuntimeException )
+{
+ const sal_Int8 nAction = dtde.DropAction;
+
+ try
+ {
+ if ( css::datatransfer::dnd::DNDConstants::ACTION_NONE != nAction )
+ {
+ TransferableDataHelper aHelper( dtde.Transferable );
+ sal_Bool bFormatFound = sal_False;
+ FileList aFileList;
+
+ // at first check filelist format
+ if ( aHelper.GetFileList( SOT_FORMAT_FILE_LIST, aFileList ) )
+ {
+ ULONG i, nCount = aFileList.Count();
+ for ( i = 0; i < nCount; ++i )
+ implts_OpenFile( aFileList.GetFile(i) );
+ bFormatFound = sal_True;
+ }
+
+ // then, if necessary, the file format
+ String aFilePath;
+ if ( !bFormatFound && aHelper.GetString( SOT_FORMAT_FILE, aFilePath ) )
+ implts_OpenFile( aFilePath );
+ }
+ dtde.Context->dropComplete( css::datatransfer::dnd::DNDConstants::ACTION_NONE != nAction );
+ }
+ catch( const ::com::sun::star::uno::Exception& )
+ {
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL DropTargetListener::dragEnter( const css::datatransfer::dnd::DropTargetDragEnterEvent& dtdee ) throw( css::uno::RuntimeException )
+{
+ try
+ {
+ implts_BeginDrag( dtdee.SupportedDataFlavors );
+ }
+ catch( const ::com::sun::star::uno::Exception& )
+ {
+ }
+
+ dragOver( dtdee );
+}
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL DropTargetListener::dragExit( const css::datatransfer::dnd::DropTargetEvent& ) throw( css::uno::RuntimeException )
+{
+ try
+ {
+ implts_EndDrag();
+ }
+ catch( const ::com::sun::star::uno::Exception& )
+ {
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL DropTargetListener::dragOver( const css::datatransfer::dnd::DropTargetDragEvent& dtde ) throw( css::uno::RuntimeException )
+{
+ try
+ {
+ sal_Bool bAccept = ( implts_IsDropFormatSupported( SOT_FORMAT_FILE ) ||
+ implts_IsDropFormatSupported( SOT_FORMAT_FILE_LIST ) );
+
+ if ( !bAccept )
+ dtde.Context->rejectDrag();
+ else
+ dtde.Context->acceptDrag( css::datatransfer::dnd::DNDConstants::ACTION_COPY );
+ }
+ catch( const ::com::sun::star::uno::Exception& )
+ {
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL DropTargetListener::dropActionChanged( const css::datatransfer::dnd::DropTargetDragEvent& ) throw( css::uno::RuntimeException )
+{
+}
+
+void DropTargetListener::implts_BeginDrag( const css::uno::Sequence< css::datatransfer::DataFlavor >& rSupportedDataFlavors )
+{
+ /* SAFE { */
+ WriteGuard aWriteLock(m_aLock);
+ m_pFormats->clear();
+ TransferableDataHelper::FillDataFlavorExVector(rSupportedDataFlavors,*m_pFormats);
+ aWriteLock.unlock();
+ /* } SAFE */
+}
+
+void DropTargetListener::implts_EndDrag()
+{
+ /* SAFE { */
+ WriteGuard aWriteLock(m_aLock);
+ m_pFormats->clear();
+ aWriteLock.unlock();
+ /* } SAFE */
+}
+
+sal_Bool DropTargetListener::implts_IsDropFormatSupported( SotFormatStringId nFormat )
+{
+ /* SAFE { */
+ ReadGuard aReadLock(m_aLock);
+ DataFlavorExVector::iterator aIter( m_pFormats->begin() ), aEnd( m_pFormats->end() );
+ sal_Bool bRet = sal_False;
+
+ while ( aIter != aEnd )
+ {
+ if ( nFormat == (*aIter++).mnSotId )
+ {
+ bRet = sal_True;
+ aIter = aEnd;
+ }
+ }
+ aReadLock.unlock();
+ /* } SAFE */
+
+ return bRet;
+}
+
+void DropTargetListener::implts_OpenFile( const String& rFilePath )
+{
+ String aFileURL;
+ if ( !::utl::LocalFileHelper::ConvertPhysicalNameToURL( rFilePath, aFileURL ) )
+ aFileURL = rFilePath;
+
+ ::osl::FileStatus aStatus( FileStatusMask_FileURL );
+ ::osl::DirectoryItem aItem;
+ if( ::osl::FileBase::E_None == ::osl::DirectoryItem::get( aFileURL, aItem ) &&
+ ::osl::FileBase::E_None == aItem.getFileStatus( aStatus ) )
+ aFileURL = aStatus.getFileURL();
+
+ // open file
+ /* SAFE { */
+ ReadGuard aReadLock(m_aLock);
+ css::uno::Reference< css::frame::XFrame > xTargetFrame( m_xTargetFrame.get() , css::uno::UNO_QUERY );
+ css::uno::Reference< css::util::XURLTransformer > xParser ( m_xFactory->createInstance(SERVICENAME_URLTRANSFORMER), css::uno::UNO_QUERY );
+ aReadLock.unlock();
+ /* } SAFE */
+ if (xTargetFrame.is() && xParser.is())
+ {
+ css::util::URL aURL;
+ aURL.Complete = aFileURL;
+ xParser->parseStrict(aURL);
+
+ css::uno::Reference < css::frame::XDispatchProvider > xProvider( xTargetFrame, css::uno::UNO_QUERY );
+ css::uno::Reference< css::frame::XDispatch > xDispatcher = xProvider->queryDispatch( aURL, SPECIALTARGET_DEFAULT, 0 );
+ if ( xDispatcher.is() )
+ xDispatcher->dispatch( aURL, css::uno::Sequence < css::beans::PropertyValue >() );
+ }
+}
+
+}
+
diff --git a/framework/source/classes/framecontainer.cxx b/framework/source/classes/framecontainer.cxx
new file mode 100644
index 000000000000..af25e786dbf1
--- /dev/null
+++ b/framework/source/classes/framecontainer.cxx
@@ -0,0 +1,418 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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"
+
+//_________________________________________________________________________________________________________________
+// my own includes
+//_________________________________________________________________________________________________________________
+
+#ifndef __FRAMEWORK_FRAMECONTAINER_HXX_
+#include <classes/framecontainer.hxx>
+#endif
+#include <threadhelp/writeguard.hxx>
+#include <threadhelp/readguard.hxx>
+
+#ifndef __FRAMEWORK_COMMANDS_HXX_
+#include <commands.h>
+#endif
+
+//_________________________________________________________________________________________________________________
+// interface includes
+//_________________________________________________________________________________________________________________
+
+#ifndef _COM_SUN_STAR_FRAME_FRAMESEARCH_FLAG_HPP_
+#include <com/sun/star/frame/FrameSearchFlag.hpp>
+#endif
+
+//_________________________________________________________________________________________________________________
+// includes of other projects
+//_________________________________________________________________________________________________________________
+#include <vcl/svapp.hxx>
+
+//_________________________________________________________________________________________________________________
+// namespace
+//_________________________________________________________________________________________________________________
+
+namespace framework{
+
+//_________________________________________________________________________________________________________________
+// non exported const
+//_________________________________________________________________________________________________________________
+
+//_________________________________________________________________________________________________________________
+// non exported definitions
+//_________________________________________________________________________________________________________________
+
+//_________________________________________________________________________________________________________________
+// declarations
+//_________________________________________________________________________________________________________________
+
+/**-***************************************************************************************************************
+ @short initialize an empty container
+ @descr The container will be empty then - special features (e.g. the async quit mechanism) are disabled.
+
+ @threadsafe not neccessary - its not a singleton
+ @modified 01.07.2002 14:42,as96863
+ *****************************************************************************************************************/
+FrameContainer::FrameContainer()
+ // initialize base classes first.
+ // Order is neccessary for right initilization of his and OUR member ... m_aLock
+ : ThreadHelpBase ( &Application::GetSolarMutex() )
+/*DEPRECATEME
+ , m_bAsyncQuit ( sal_False ) // default must be "disabled"!
+ , m_aAsyncCall ( LINK( this, FrameContainer, implts_asyncQuit ) )
+*/
+{
+}
+
+/**-***************************************************************************************************************
+ @short deinitialize may a filled container
+ @descr Special features (if the currently are running) will be dsiabled and we free all used other ressources.
+
+ @threadsafe not neccessary - its not a singleton
+ @modified 01.07.2002 14:43,as96863
+ *****************************************************************************************************************/
+FrameContainer::~FrameContainer()
+{
+ // Don't forget to free memory!
+ m_aContainer.clear();
+ m_xActiveFrame.clear();
+}
+
+/**-***************************************************************************************************************
+ @short append a new frame to the container
+ @descr We accept the incoming frame only, if it is a valid reference and dosnt exist already.
+
+ @param xFrame
+ frame, which should be added to this container
+ Must be a valid reference.
+
+ @threadsafe yes
+ @modified 01.07.2002 14:44,as96863
+ *****************************************************************************************************************/
+void FrameContainer::append( const css::uno::Reference< css::frame::XFrame >& xFrame )
+{
+ if (xFrame.is() && ! exist(xFrame))
+ {
+ /* SAFE { */
+ WriteGuard aWriteLock( m_aLock );
+ m_aContainer.push_back( xFrame );
+ aWriteLock.unlock();
+ /* } SAFE */
+ }
+}
+
+/**-***************************************************************************************************************
+ @short remove a frame from the container
+ @descr In case we remove the last frame and our internal special feature (the async quit mechanism)
+ was enabled by the desktop instance, we start it.
+
+ @param xFrame
+ frame, which should be deleted from this container
+ Must be a valid reference.
+
+ @threadsafe yes
+ @modified 01.07.2002 14:52,as96863
+ *****************************************************************************************************************/
+void FrameContainer::remove( const css::uno::Reference< css::frame::XFrame >& xFrame )
+{
+ /* SAFE { */
+ // write lock neccessary for follwing erase()!
+ WriteGuard aWriteLock( m_aLock );
+
+ TFrameIterator aSearchedItem = ::std::find( m_aContainer.begin(), m_aContainer.end(), xFrame );
+ if (aSearchedItem!=m_aContainer.end())
+ {
+ m_aContainer.erase( aSearchedItem );
+
+ // If removed frame was the current active frame - reset state variable.
+ if (m_xActiveFrame==xFrame)
+ m_xActiveFrame = css::uno::Reference< css::frame::XFrame >();
+
+ // We don't need the write lock any longer ...
+ // downgrade to read access.
+ aWriteLock.downgrade();
+/*DEPRECATEME
+ // If last frame was removed and special quit mode is enabled by the desktop
+ // we must terminate the application by using this asynchronous callback!
+ if (m_aContainer.size()<1 && m_bAsyncQuit)
+ m_aAsyncCall.Post(0);
+*/
+ }
+
+ aWriteLock.unlock();
+ // } SAFE
+}
+
+/**-***************************************************************************************************************
+ @short check if the given frame currently exist inside the container
+ @descr -
+
+ @param xFrame
+ reference to the queried frame
+
+ @return <TRUE/> if frame is oart of this container
+ <FALSE/> otherwhise
+
+ @threadsafe yes
+ @modified 01.07.2002 14:55,as96863
+ *****************************************************************************************************************/
+sal_Bool FrameContainer::exist( const css::uno::Reference< css::frame::XFrame >& xFrame ) const
+{
+ /* SAFE { */
+ ReadGuard aReadLock( m_aLock );
+ return( ::std::find( m_aContainer.begin(), m_aContainer.end(), xFrame ) != m_aContainer.end() );
+ /* } SAFE */
+}
+
+/**-***************************************************************************************************************
+ @short delete all existing items of the container
+ @descr -
+
+ @threadsafe yes
+ @modified 01.07.2002 15:00,as96863
+ *****************************************************************************************************************/
+void FrameContainer::clear()
+{
+ // SAFE {
+ WriteGuard aWriteLock( m_aLock );
+
+ // Clear the container ...
+ m_aContainer.clear();
+ // ... and don't forget to reset the active frame.
+ // Its an reference to a valid container-item.
+ // But no container item => no active frame!
+ m_xActiveFrame = css::uno::Reference< css::frame::XFrame >();
+/*DEPRECATEME
+ // If special quit mode is used - we must terminate the desktop.
+ // He is the owner of this container and can't work without any visible tasks/frames!
+ if (m_bAsyncQuit)
+ m_aAsyncCall.Post(0);
+*/
+
+ aWriteLock.unlock();
+ // } SAFE
+}
+
+/**-***************************************************************************************************************
+ @short returns count of all current existing frames
+ @descr -
+
+ @deprecated This value can't be guaranteed for multithreading environments.
+ So it will be marked as deprecated and should be replaced by "getAllElements()".
+
+ @return the count of existing container items
+
+ @threadsafe yes
+ @modified 01.07.2002 15:00,as96863
+ *****************************************************************************************************************/
+sal_uInt32 FrameContainer::getCount() const
+{
+ /* SAFE { */
+ ReadGuard aReadLock( m_aLock );
+ return( (sal_uInt32)m_aContainer.size() );
+ /* } SAFE */
+}
+
+/**-***************************************************************************************************************
+ @short returns one item of this container
+ @descr -
+
+ @deprecated This value can't be guaranteed for multithreading environments.
+ So it will be marked as deprecated and should be replaced by "getAllElements()".
+
+ @param nIndex
+ a valud between 0 and (getCount()-1) to adress one container item
+
+ @return a reference to a frame inside the container, which match with given index
+
+ @threadsafe yes
+ @modified 01.07.2002 15:03,as96863
+ *****************************************************************************************************************/
+css::uno::Reference< css::frame::XFrame > FrameContainer::operator[]( sal_uInt32 nIndex ) const
+{
+
+ css::uno::Reference< css::frame::XFrame > xFrame;
+ try
+ {
+ // Get element form container WITH automatic test of ranges!
+ // If index not valid, a out_of_range exception is thrown.
+ /* SAFE { */
+ ReadGuard aReadLock( m_aLock );
+ xFrame = m_aContainer.at( nIndex );
+ aReadLock.unlock();
+ /* } SAFE */
+ }
+ catch( std::out_of_range& )
+ {
+ // The index is not valid for current container-content - we must handle this case!
+ // We can return the default value ...
+ LOG_EXCEPTION( "FrameContainer::operator[]", "Exception catched ...", DECLARE_ASCII("::std::out_of_range") )
+ }
+ return xFrame;
+}
+
+/**-***************************************************************************************************************
+ @short returns a snapshot of all currently existing frames inside this container
+ @descr Should be used to replace the deprecated functions getCount()/operator[]!
+
+ @return a list of all frame refrences inside this container
+
+ @threadsafe yes
+ @modified 01.07.2002 15:09,as96863
+ *****************************************************************************************************************/
+css::uno::Sequence< css::uno::Reference< css::frame::XFrame > > FrameContainer::getAllElements() const
+{
+ /* SAFE { */
+ ReadGuard aReadLock( m_aLock );
+
+ sal_Int32 nPosition = 0;
+ css::uno::Sequence< css::uno::Reference< css::frame::XFrame > > lElements ( (sal_uInt32)m_aContainer.size() );
+ for (TConstFrameIterator pItem=m_aContainer.begin(); pItem!=m_aContainer.end(); ++pItem)
+ lElements[nPosition++] = *pItem;
+
+ aReadLock.unlock();
+ /* } SAFE */
+
+ return lElements;
+}
+
+/**-***************************************************************************************************************
+ @short set the given frame as the new active one inside this container
+ @descr We accept this frame only, if it's already a part of this container.
+
+ @param xFrame
+ reference to the new active frame
+ Must be a valid reference and already part of this container.
+
+ @threadsafe yes
+ @modified 01.07.2002 15:11,as96863
+ *****************************************************************************************************************/
+void FrameContainer::setActive( const css::uno::Reference< css::frame::XFrame >& xFrame )
+{
+ if ( !xFrame.is() || exist(xFrame) )
+ {
+ /* SAFE { */
+ WriteGuard aWriteLock( m_aLock );
+ m_xActiveFrame = xFrame;
+ aWriteLock.unlock();
+ /* } SAFE */
+ }
+}
+
+/**-***************************************************************************************************************
+ @short return sthe current active frame of this container
+ @descr Value can be null in case the frame was removed from the container and nobody
+ from outside decide which of all others should be the new one ...
+
+ @return a reference to the current active frame
+ Value can be NULL!
+
+ @threadsafe yes
+ @modified 01.07.2002 15:11,as96863
+ *****************************************************************************************************************/
+css::uno::Reference< css::frame::XFrame > FrameContainer::getActive() const
+{
+ /* SAFE { */
+ ReadGuard aReadLock( m_aLock );
+ return m_xActiveFrame;
+ /* } SAFE */
+}
+
+/**-***************************************************************************************************************
+ @short implements a simple search based on current container items
+ @descr It can be used for findFrame() and implements a deep down search.
+
+ @param sName
+ target name, which is searched
+
+ @return reference to the found frame or NULL if not.
+
+ @threadsafe yes
+ @modified 01.07.2002 15:22,as96863
+ *****************************************************************************************************************/
+css::uno::Reference< css::frame::XFrame > FrameContainer::searchOnAllChildrens( const ::rtl::OUString& sName ) const
+{
+ /* SAFE { */
+ ReadGuard aReadLock( m_aLock );
+
+ // Step over all child frames. But if direct child isn't the right one search on his children first - before
+ // you go to next direct child of this container!
+ css::uno::Reference< css::frame::XFrame > xSearchedFrame;
+ for( TConstFrameIterator pIterator=m_aContainer.begin(); pIterator!=m_aContainer.end(); ++pIterator )
+ {
+ if ((*pIterator)->getName()==sName)
+ {
+ xSearchedFrame = *pIterator;
+ break;
+ }
+ else
+ {
+ xSearchedFrame = (*pIterator)->findFrame( sName, css::frame::FrameSearchFlag::CHILDREN );
+ if (xSearchedFrame.is())
+ break;
+ }
+ }
+ aReadLock.unlock();
+ /* } SAFE */
+ return xSearchedFrame;
+}
+
+/**-***************************************************************************************************************
+ @short implements a simple search based on current container items
+ @descr It can be used for findFrame() and search on members of this container only!
+
+ @param sName
+ target name, which is searched
+
+ @return reference to the found frame or NULL if not.
+
+ @threadsafe yes
+ @modified 01.07.2002 15:22,as96863
+ *****************************************************************************************************************/
+css::uno::Reference< css::frame::XFrame > FrameContainer::searchOnDirectChildrens( const ::rtl::OUString& sName ) const
+{
+ /* SAFE { */
+ ReadGuard aReadLock( m_aLock );
+
+ css::uno::Reference< css::frame::XFrame > xSearchedFrame;
+ for( TConstFrameIterator pIterator=m_aContainer.begin(); pIterator!=m_aContainer.end(); ++pIterator )
+ {
+ if ((*pIterator)->getName()==sName)
+ {
+ xSearchedFrame = *pIterator;
+ break;
+ }
+ }
+ aReadLock.unlock();
+ /* } SAFE */
+ return xSearchedFrame;
+}
+
+} // namespace framework
diff --git a/framework/source/classes/framelistanalyzer.cxx b/framework/source/classes/framelistanalyzer.cxx
new file mode 100644
index 000000000000..22f019e78df5
--- /dev/null
+++ b/framework/source/classes/framelistanalyzer.cxx
@@ -0,0 +1,302 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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"
+
+#include "classes/framelistanalyzer.hxx"
+
+//_______________________________________________
+// my own includes
+#include <threadhelp/writeguard.hxx>
+#include <threadhelp/readguard.hxx>
+#include <targets.h>
+#include <properties.h>
+#include <services.h>
+
+//_______________________________________________
+// interface includes
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/frame/XModuleManager.hpp>
+
+//_______________________________________________
+// includes of other projects
+#include <unotools/processfactory.hxx>
+#include <vcl/svapp.hxx>
+
+//_______________________________________________
+// namespace
+
+namespace framework{
+
+//_______________________________________________
+// non exported const
+
+//_______________________________________________
+// non exported definitions
+
+//_______________________________________________
+// declarations
+
+//_______________________________________________
+
+/**
+ */
+
+FrameListAnalyzer::FrameListAnalyzer( const css::uno::Reference< css::frame::XFramesSupplier >& xSupplier ,
+ const css::uno::Reference< css::frame::XFrame >& xReferenceFrame ,
+ sal_uInt32 eDetectMode )
+ : m_xSupplier (xSupplier )
+ , m_xReferenceFrame(xReferenceFrame)
+ , m_eDetectMode (eDetectMode )
+{
+ impl_analyze();
+}
+
+//_______________________________________________
+
+/**
+ */
+
+FrameListAnalyzer::~FrameListAnalyzer()
+{
+}
+
+//_______________________________________________
+
+/** returns an analyzed list of all currently opened (top!) frames inside the desktop tree.
+
+ We try to get a snapshot of all opened frames, which are part of the desktop frame container.
+ Of course we can't access frames, which stands outside of this tree.
+ But it's neccessary to collect top frames here only. Otherwhise we interpret closing of last
+ frame wrong. Further we analyze this list and split into different parts.
+ E.g. for "CloseDoc" we must know, which frames of the given list referr to the same model.
+ These frames must be closed then. But all other frames must be untouched.
+ In case the request was "CloseWin" these splitted lists can be used too, to decide if the last window
+ or document was closed. Then we have to initialize the backing window ...
+ Last but not least we must know something about our special help frame. It must be handled
+ seperatly. And last but not least - the backing component frame must be detected too.
+*/
+
+void FrameListAnalyzer::impl_analyze()
+{
+ // reset all members to get a consistent state
+ m_bReferenceIsHidden = sal_False;
+ m_bReferenceIsHelp = sal_False;
+ m_bReferenceIsBacking = sal_False;
+ m_xHelp = css::uno::Reference< css::frame::XFrame >();
+ m_xBackingComponent = css::uno::Reference< css::frame::XFrame >();
+
+ // try to get the task container by using the given supplier
+ css::uno::Reference< css::container::XIndexAccess > xFrameContainer(m_xSupplier->getFrames(), css::uno::UNO_QUERY);
+
+ // All return list get an initial size to include all possible frames.
+ // They will be packed at the end of this method ... using the actual step positions then.
+ sal_Int32 nVisibleStep = 0;
+ sal_Int32 nHiddenStep = 0;
+ sal_Int32 nModelStep = 0;
+ sal_Int32 nCount = xFrameContainer->getCount();
+
+ m_lOtherVisibleFrames.realloc(nCount);
+ m_lOtherHiddenFrames.realloc(nCount);
+ m_lModelFrames.realloc(nCount);
+
+ // ask for the model of the given reference frame.
+ // It must be compared with the model of every frame of the container
+ // to sort it into the list of frames with the same model.
+ // Supress this step, if right detect mode isn't set.
+ css::uno::Reference< css::frame::XModel > xReferenceModel;
+ if ((m_eDetectMode & E_MODEL) == E_MODEL )
+ {
+ css::uno::Reference< css::frame::XController > xReferenceController;
+ if (m_xReferenceFrame.is())
+ xReferenceController = m_xReferenceFrame->getController();
+ if (xReferenceController.is())
+ xReferenceModel = xReferenceController->getModel();
+ }
+
+ // check, if the reference frame is in hidden mode.
+ // But look, if this analyze step is realy needed.
+ css::uno::Reference< css::beans::XPropertySet > xSet(m_xReferenceFrame, css::uno::UNO_QUERY);
+ if (
+ ((m_eDetectMode & E_HIDDEN) == E_HIDDEN) &&
+ (xSet.is() )
+ )
+ {
+ xSet->getPropertyValue(FRAME_PROPNAME_ISHIDDEN) >>= m_bReferenceIsHidden;
+ }
+
+ // check, if the reference frame includes the backing component.
+ // But look, if this analyze step is realy needed.
+ if ((m_eDetectMode & E_BACKINGCOMPONENT) == E_BACKINGCOMPONENT)
+ {
+ try
+ {
+ css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = ::utl::getProcessServiceFactory();
+ css::uno::Reference< css::frame::XModuleManager > xModuleMgr(xSMGR->createInstance(SERVICENAME_MODULEMANAGER), css::uno::UNO_QUERY_THROW);
+ ::rtl::OUString sModule = xModuleMgr->identify(m_xReferenceFrame);
+ m_bReferenceIsBacking = (sModule.equals(SERVICENAME_STARTMODULE));
+ }
+ catch(const css::uno::Exception&)
+ {}
+ }
+
+ // check, if the reference frame includes the help module.
+ // But look, if this analyze step is realy needed.
+ if (
+ ((m_eDetectMode & E_HELP) == E_HELP ) &&
+ (m_xReferenceFrame.is() ) &&
+ (m_xReferenceFrame->getName() == SPECIALTARGET_HELPTASK)
+ )
+ {
+ m_bReferenceIsHelp = sal_True;
+ }
+
+ try
+ {
+ // Step over all frames of the desktop frame container and analyze it.
+ for (sal_Int32 i=0; i<nCount; ++i)
+ {
+ // Ignore invalid items ... and of course the reference frame.
+ // It will be a member of the given frame list too - but it was already
+ // analyzed before!
+ css::uno::Reference< css::frame::XFrame > xFrame;
+ if (
+ !(xFrameContainer->getByIndex(i) >>= xFrame) ||
+ !(xFrame.is() ) ||
+ (xFrame==m_xReferenceFrame )
+ )
+ continue;
+
+ #ifdef ENABLE_WARNINGS
+ if (
+ ((m_eDetectMode & E_ZOMBIE) == E_ZOMBIE) &&
+ (
+ (!xFrame->getContainerWindow().is()) ||
+ (!xFrame->getComponentWindow().is())
+ )
+ )
+ {
+ LOG_WARNING("FrameListAnalyzer::impl_analyze()", "ZOMBIE!")
+ }
+ #endif
+
+ // -------------------------------------------------
+ // a) Is it the special help task?
+ // Return it seperated from any return list.
+ if (
+ ((m_eDetectMode & E_HELP) == E_HELP ) &&
+ (xFrame->getName()==SPECIALTARGET_HELPTASK)
+ )
+ {
+ m_xHelp = xFrame;
+ continue;
+ }
+
+ // -------------------------------------------------
+ // b) Or is includes this task the special backing component?
+ // Return it seperated from any return list.
+ // But check if the reference task itself is the backing frame.
+ // Our user mst know it to decide right.
+ if ((m_eDetectMode & E_BACKINGCOMPONENT) == E_BACKINGCOMPONENT)
+ {
+ try
+ {
+ css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = ::utl::getProcessServiceFactory();
+ css::uno::Reference< css::frame::XModuleManager > xModuleMgr(xSMGR->createInstance(SERVICENAME_MODULEMANAGER), css::uno::UNO_QUERY);
+ ::rtl::OUString sModule = xModuleMgr->identify(xFrame);
+ if (sModule.equals(SERVICENAME_STARTMODULE))
+ {
+ m_xBackingComponent = xFrame;
+ continue;
+ }
+ }
+ catch(const css::uno::Exception&)
+ {}
+ }
+
+ // -------------------------------------------------
+ // c) Or is it the a task, which uses the specified model?
+ // Add it to the list of "model frames".
+ if ((m_eDetectMode & E_MODEL) == E_MODEL)
+ {
+ css::uno::Reference< css::frame::XController > xController = xFrame->getController();
+ css::uno::Reference< css::frame::XModel > xModel ;
+ if (xController.is())
+ xModel = xController->getModel();
+ if (xModel==xReferenceModel)
+ {
+ m_lModelFrames[nModelStep] = xFrame;
+ ++nModelStep;
+ continue;
+ }
+ }
+
+ // -------------------------------------------------
+ // d) Or is it the a task, which use another or no model at all?
+ // Add it to the list of "other frames". But look for it's
+ // visible state ... if it's allowed to do so.
+ // -------------------------------------------------
+ sal_Bool bHidden = sal_False;
+ if ((m_eDetectMode & E_HIDDEN) == E_HIDDEN )
+ {
+ xSet = css::uno::Reference< css::beans::XPropertySet >(xFrame, css::uno::UNO_QUERY);
+ if (xSet.is())
+ {
+ xSet->getPropertyValue(FRAME_PROPNAME_ISHIDDEN) >>= bHidden;
+ }
+ }
+
+ if (bHidden)
+ {
+ m_lOtherHiddenFrames[nHiddenStep] = xFrame;
+ ++nHiddenStep;
+ }
+ else
+ {
+ m_lOtherVisibleFrames[nVisibleStep] = xFrame;
+ ++nVisibleStep;
+ }
+ }
+ }
+ catch(css::lang::IndexOutOfBoundsException)
+ {
+ // stop copying if index seams to be wrong.
+ // This interface can't realy guarantee its count for multithreaded
+ // environments. So it can occure!
+ }
+
+ // Pack both lists by using the actual step positions.
+ // All empty or ignorable items should exist at the end of these lists
+ // behind the position pointers. So they will be removed by a reallocation.
+ m_lOtherVisibleFrames.realloc(nVisibleStep);
+ m_lOtherHiddenFrames.realloc(nHiddenStep);
+ m_lModelFrames.realloc(nModelStep);
+}
+
+} // namespace framework
diff --git a/framework/source/classes/fwkresid.cxx b/framework/source/classes/fwkresid.cxx
new file mode 100644
index 000000000000..54b37da6dbf7
--- /dev/null
+++ b/framework/source/classes/fwkresid.cxx
@@ -0,0 +1,65 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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"
+
+#include "classes/fwkresid.hxx"
+#include <tools/string.hxx>
+#include <vos/mutex.hxx>
+#include <vcl/svapp.hxx>
+
+#include <rtl/strbuf.hxx>
+
+namespace framework
+{
+
+ResMgr* FwkResId::GetResManager()
+{
+ static ResMgr* pResMgr = NULL;
+
+ if ( !pResMgr )
+ {
+ rtl::OStringBuffer aBuf( 32 );
+ aBuf.append( "fwe" );
+
+ vos::OGuard aSolarGuard( Application::GetSolarMutex() );
+ pResMgr = ResMgr::CreateResMgr( aBuf.getStr() );
+ }
+
+ return pResMgr;
+}
+
+// -----------------------------------------------------------------------
+
+FwkResId::FwkResId( USHORT nId ) :
+ ResId( nId, *FwkResId::GetResManager() )
+{
+}
+
+}
+
diff --git a/framework/source/classes/fwktabwindow.cxx b/framework/source/classes/fwktabwindow.cxx
new file mode 100644
index 000000000000..aa550807460c
--- /dev/null
+++ b/framework/source/classes/fwktabwindow.cxx
@@ -0,0 +1,412 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+
+#include <classes/fwktabwindow.hxx>
+#include "framework.hrc"
+#include <classes/fwlresid.hxx>
+
+#include <com/sun/star/awt/PosSize.hpp>
+#include <com/sun/star/awt/XContainerWindowEventHandler.hpp>
+#include <com/sun/star/awt/XContainerWindowProvider.hpp>
+#include <com/sun/star/awt/XWindow.hpp>
+#include <com/sun/star/awt/XWindowPeer.hpp>
+#include <com/sun/star/awt/XControl.hpp>
+#include <com/sun/star/beans/NamedValue.hpp>
+#include <com/sun/star/graphic/XGraphic.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+
+#include <comphelper/processfactory.hxx>
+#include <toolkit/helper/vclunohelper.hxx>
+#include <tools/stream.hxx>
+#include <vcl/bitmap.hxx>
+#include <vcl/image.hxx>
+#include <vcl/msgbox.hxx>
+
+const ::rtl::OUString SERVICENAME_WINPROVIDER
+ = ::rtl::OUString::createFromAscii("com.sun.star.awt.ContainerWindowProvider");
+const ::rtl::OUString EXTERNAL_EVENT = ::rtl::OUString::createFromAscii("external_event");
+const ::rtl::OUString BACK_METHOD = ::rtl::OUString::createFromAscii("back");
+const ::rtl::OUString INITIALIZE_METHOD = ::rtl::OUString::createFromAscii("initialize");
+const ::rtl::OUString OK_METHOD = ::rtl::OUString::createFromAscii("ok");
+
+using namespace ::com::sun::star;
+
+namespace framework
+{
+
+// class FwkTabControl ---------------------------------------------------
+FwkTabControl::FwkTabControl( Window* pParent, const ResId& rResId ) :
+
+ TabControl( pParent, rResId )
+{
+}
+
+// -----------------------------------------------------------------------
+
+void FwkTabControl::BroadcastEvent( ULONG nEvent )
+{
+ if ( VCLEVENT_TABPAGE_ACTIVATE == nEvent || VCLEVENT_TABPAGE_DEACTIVATE == nEvent )
+ ImplCallEventListeners( nEvent, (void*)(ULONG)GetCurPageId() );
+ else
+ {
+ DBG_ERRORFILE( "FwkTabControl::BroadcastEvent(): illegal event" );
+ }
+}
+
+// class FwkTabPage ------------------------------------------------
+
+FwkTabPage::FwkTabPage(
+ Window* pParent, const rtl::OUString& rPageURL,
+ const css::uno::Reference< css::awt::XContainerWindowEventHandler >& rEventHdl,
+ const css::uno::Reference< css::awt::XContainerWindowProvider >& rProvider ) :
+
+ TabPage( pParent, WB_DIALOGCONTROL | WB_TABSTOP | WB_CHILDDLGCTRL ),
+
+ m_sPageURL ( rPageURL ),
+ m_xEventHdl ( rEventHdl ),
+ m_xWinProvider ( rProvider )
+
+{
+}
+
+// -----------------------------------------------------------------------
+
+FwkTabPage::~FwkTabPage()
+{
+ Hide();
+ DeactivatePage();
+}
+
+// -----------------------------------------------------------------------
+
+void FwkTabPage::CreateDialog()
+{
+ try
+ {
+ uno::Reference< uno::XInterface > xHandler;
+ if ( m_xEventHdl.is() )
+ xHandler = m_xEventHdl;
+
+ uno::Reference< awt::XWindowPeer > xParent( VCLUnoHelper::GetInterface( this ), uno::UNO_QUERY );
+ m_xPage = uno::Reference < awt::XWindow >(
+ m_xWinProvider->createContainerWindow(
+ m_sPageURL, rtl::OUString(), xParent, xHandler ), uno::UNO_QUERY );
+
+ uno::Reference< awt::XControl > xPageControl( m_xPage, uno::UNO_QUERY );
+ if ( xPageControl.is() )
+ {
+ uno::Reference< awt::XWindowPeer > xWinPeer( xPageControl->getPeer() );
+ if ( xWinPeer.is() )
+ {
+ Window* pWindow = VCLUnoHelper::GetWindow( xWinPeer );
+ if ( pWindow )
+ pWindow->SetStyle( pWindow->GetStyle() | WB_DIALOGCONTROL | WB_CHILDDLGCTRL );
+ }
+ }
+
+ CallMethod( INITIALIZE_METHOD );
+ }
+ catch ( lang::IllegalArgumentException& )
+ {
+ DBG_ERRORFILE( "FwkTabPage::CreateDialog(): illegal argument" );
+ }
+ catch ( uno::Exception& )
+ {
+ DBG_ERRORFILE( "FwkTabPage::CreateDialog(): exception of XDialogProvider2::createContainerWindow()" );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+sal_Bool FwkTabPage::CallMethod( const rtl::OUString& rMethod )
+{
+ sal_Bool bRet = sal_False;
+ if ( m_xEventHdl.is() )
+ {
+ try
+ {
+ bRet = m_xEventHdl->callHandlerMethod( m_xPage, uno::makeAny( rMethod ), EXTERNAL_EVENT );
+ }
+ catch ( uno::Exception& )
+ {
+ DBG_ERRORFILE( "FwkTabPage::CallMethod(): exception of XDialogEventHandler::callHandlerMethod()" );
+ }
+ }
+ return bRet;
+}
+
+// -----------------------------------------------------------------------
+
+void FwkTabPage::ActivatePage()
+{
+ TabPage::ActivatePage();
+
+ if ( !m_xPage.is() )
+ CreateDialog();
+
+ if ( m_xPage.is() )
+ {
+ Resize ();
+ m_xPage->setVisible( sal_True );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void FwkTabPage::DeactivatePage()
+{
+ TabPage::DeactivatePage();
+
+ if ( m_xPage.is() )
+ m_xPage->setVisible( sal_False );
+}
+
+// -----------------------------------------------------------------------
+
+void FwkTabPage::Resize()
+{
+ if ( m_xPage.is () )
+ {
+ Size aSize = GetSizePixel ();
+ Point aPos = GetPosPixel ();
+
+ m_xPage->setPosSize( 0, 0, aSize.Width()-1 , aSize.Height()-1, awt::PosSize::POSSIZE );
+ }
+}
+
+// class FwkTabWindow ---------------------------------------------
+
+FwkTabWindow::FwkTabWindow( Window* pParent ) :
+
+ Window( pParent, FwlResId( WIN_TABWINDOW ) ),
+
+ m_aTabCtrl ( this, FwlResId( TC_TABCONTROL ) )
+{
+ uno::Reference < lang::XMultiServiceFactory > xFactory( ::comphelper::getProcessServiceFactory() );
+ m_xWinProvider = uno::Reference < awt::XContainerWindowProvider >(
+ xFactory->createInstance( SERVICENAME_WINPROVIDER ), uno::UNO_QUERY );
+
+ SetPaintTransparent(true);
+
+ m_aTabCtrl.SetActivatePageHdl( LINK( this, FwkTabWindow, ActivatePageHdl ) );
+ m_aTabCtrl.SetDeactivatePageHdl( LINK( this, FwkTabWindow, DeactivatePageHdl ) );
+ m_aTabCtrl.Show();
+}
+
+// -----------------------------------------------------------------------
+
+FwkTabWindow::~FwkTabWindow()
+{
+ ClearEntryList();
+}
+
+// -----------------------------------------------------------------------
+
+void FwkTabWindow::ClearEntryList()
+{
+ TabEntryList::const_iterator pIt;
+ for ( pIt = m_TabList.begin();
+ pIt != m_TabList.end();
+ ++pIt )
+ {
+ delete *pIt;
+ }
+
+ m_TabList.clear();
+}
+
+// -----------------------------------------------------------------------
+
+bool FwkTabWindow::RemoveEntry( sal_Int32 nIndex )
+{
+ TabEntryList::iterator pIt;
+ for ( pIt = m_TabList.begin();
+ pIt != m_TabList.end();
+ ++pIt )
+ {
+ if ( (*pIt)->m_nIndex == nIndex )
+ break;
+ }
+
+ // remove entry from vector
+ if ( pIt != m_TabList.end())
+ {
+ m_TabList.erase(pIt);
+ return true;
+ }
+ else
+ return false;
+}
+
+// -----------------------------------------------------------------------
+TabEntry* FwkTabWindow::FindEntry( sal_Int32 nIndex ) const
+{
+ TabEntry* pEntry = NULL;
+
+ TabEntryList::const_iterator pIt;
+ for ( pIt = m_TabList.begin();
+ pIt != m_TabList.end();
+ ++pIt )
+ {
+ if ( (*pIt)->m_nIndex == nIndex )
+ {
+ pEntry = *pIt;
+ break;
+ }
+ }
+
+ return pEntry;
+}
+
+// -----------------------------------------------------------------------
+
+IMPL_LINK( FwkTabWindow, ActivatePageHdl, TabControl *, EMPTYARG )
+{
+ const USHORT nId = m_aTabCtrl.GetCurPageId();
+ FwkTabPage* pTabPage = static_cast< FwkTabPage* >( m_aTabCtrl.GetTabPage( nId ) );
+ if ( !pTabPage )
+ {
+ TabEntry* pEntry = FindEntry( nId );
+ if ( pEntry )
+ {
+ pTabPage = new FwkTabPage( &m_aTabCtrl, pEntry->m_sPageURL, pEntry->m_xEventHdl, m_xWinProvider );
+ pEntry->m_pPage = pTabPage;
+ m_aTabCtrl.SetTabPage( nId, pTabPage );
+ pTabPage->Show();
+ pTabPage->ActivatePage();
+ }
+ } else {
+ pTabPage->ActivatePage();
+ }
+ m_aTabCtrl.BroadcastEvent( VCLEVENT_TABPAGE_ACTIVATE );
+ return 1;
+}
+
+// -----------------------------------------------------------------------
+
+IMPL_LINK( FwkTabWindow, DeactivatePageHdl, TabControl *, EMPTYARG )
+{
+ m_aTabCtrl.BroadcastEvent( VCLEVENT_TABPAGE_DEACTIVATE );
+ return 1;
+}
+
+// -----------------------------------------------------------------------
+
+IMPL_LINK( FwkTabWindow, CloseHdl, PushButton *, EMPTYARG )
+{
+// Close();
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+void FwkTabWindow::AddEventListener( const Link& rEventListener )
+{
+ m_aTabCtrl.AddEventListener( rEventListener );
+}
+
+void FwkTabWindow::RemoveEventListener( const Link& rEventListener )
+{
+ m_aTabCtrl.RemoveEventListener( rEventListener );
+}
+
+// -----------------------------------------------------------------------
+
+FwkTabPage* FwkTabWindow::AddTabPage( sal_Int32 nIndex, const uno::Sequence< beans::NamedValue >& rProperties )
+{
+ ::rtl::OUString sTitle, sToolTip, sPageURL;
+ uno::Reference< css::awt::XContainerWindowEventHandler > xEventHdl;
+ uno::Reference< graphic::XGraphic > xImage;
+ bool bDisabled = false;
+
+ sal_Int32 i = 0, nLen = rProperties.getLength();
+ for ( i = 0; i < nLen; ++i )
+ {
+ beans::NamedValue aValue = rProperties[i];
+ ::rtl::OUString sName = aValue.Name;
+
+ if ( sName.equalsAscii("Title") )
+ aValue.Value >>= sTitle;
+ else if ( sName.equalsAscii("ToolTip") )
+ aValue.Value >>= sToolTip;
+ else if ( sName.equalsAscii("PageURL") )
+ aValue.Value >>= sPageURL;
+ else if ( sName.equalsAscii("EventHdl") )
+ aValue.Value >>= xEventHdl;
+ else if ( sName.equalsAscii("Image") )
+ aValue.Value >>= xImage;
+ else if ( sName.equalsAscii("Disabled") )
+ aValue.Value >>= bDisabled;
+ }
+
+ TabEntry* pEntry = new TabEntry( nIndex, sPageURL, xEventHdl );
+ m_TabList.push_back( pEntry );
+ USHORT nIdx = static_cast< USHORT >( nIndex );
+ m_aTabCtrl.InsertPage( nIdx, sTitle );
+ if ( sToolTip.getLength() > 0 )
+ m_aTabCtrl.SetHelpText( nIdx, sToolTip );
+ if ( xImage.is() )
+ m_aTabCtrl.SetPageImage( nIdx, Image( xImage ) );
+ if ( bDisabled )
+ m_aTabCtrl.EnablePage( nIdx, false );
+
+ return pEntry->m_pPage;
+}
+
+// -----------------------------------------------------------------------
+
+void FwkTabWindow::ActivatePage( sal_Int32 nIndex )
+{
+ m_aTabCtrl.SetCurPageId( static_cast< USHORT >( nIndex ) );
+ ActivatePageHdl( &m_aTabCtrl );
+}
+
+// -----------------------------------------------------------------------
+
+void FwkTabWindow::RemovePage( sal_Int32 nIndex )
+{
+ TabEntry* pEntry = FindEntry(nIndex);
+ if ( pEntry )
+ {
+ m_aTabCtrl.RemovePage( static_cast< USHORT >( nIndex ) );
+ if (RemoveEntry(nIndex))
+ delete pEntry;
+ }
+}
+
+// -----------------------------------------------------------------------
+void FwkTabWindow::Resize()
+{
+ Size aPageSize = GetSizePixel();
+ m_aTabCtrl.SetTabPageSizePixel( aPageSize );
+}
+
+} // namespace framework
+
diff --git a/framework/source/classes/fwlresid.cxx b/framework/source/classes/fwlresid.cxx
new file mode 100755
index 000000000000..e3f3e26ce995
--- /dev/null
+++ b/framework/source/classes/fwlresid.cxx
@@ -0,0 +1,65 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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"
+
+#include "classes/fwlresid.hxx"
+#include <tools/string.hxx>
+#include <vos/mutex.hxx>
+#include <vcl/svapp.hxx>
+
+#include <rtl/strbuf.hxx>
+
+namespace framework
+{
+
+ResMgr* FwlResId::GetResManager()
+{
+ static ResMgr* pResMgr = NULL;
+
+ if ( !pResMgr )
+ {
+ rtl::OStringBuffer aBuf( 32 );
+ aBuf.append( "fwe" );
+
+ vos::OGuard aSolarGuard( Application::GetSolarMutex() );
+ pResMgr = ResMgr::CreateResMgr( aBuf.getStr() );
+ }
+
+ return pResMgr;
+}
+
+// -----------------------------------------------------------------------
+
+FwlResId::FwlResId( USHORT nId ) :
+ ResId( nId, *FwlResId::GetResManager() )
+{
+}
+
+}
+
diff --git a/framework/source/classes/imagewrapper.cxx b/framework/source/classes/imagewrapper.cxx
new file mode 100644
index 000000000000..82a7f684413c
--- /dev/null
+++ b/framework/source/classes/imagewrapper.cxx
@@ -0,0 +1,120 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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"
+
+#include <classes/imagewrapper.hxx>
+#include <osl/mutex.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/bitmap.hxx>
+#include <vcl/bitmapex.hxx>
+#include <tools/stream.hxx>
+#include <cppuhelper/typeprovider.hxx>
+
+using namespace com::sun::star::lang;
+using namespace com::sun::star::uno;
+
+namespace framework
+{
+
+static Sequence< sal_Int8 > impl_getStaticIdentifier()
+{
+ static sal_uInt8 pGUID[16] = { 0x46, 0xAD, 0x69, 0xFB, 0xA7, 0xBE, 0x44, 0x83, 0xB2, 0xA7, 0xB3, 0xEC, 0x59, 0x4A, 0xB7, 0x00 };
+ static ::com::sun::star::uno::Sequence< sal_Int8 > seqID((sal_Int8*)pGUID,16) ;
+ return seqID ;
+}
+
+
+ImageWrapper::ImageWrapper( const Image& aImage ) : ThreadHelpBase( &Application::GetSolarMutex() )
+ , m_aImage( aImage )
+{
+}
+
+
+ImageWrapper::~ImageWrapper()
+{
+}
+
+
+Sequence< sal_Int8 > ImageWrapper::GetUnoTunnelId()
+{
+ return impl_getStaticIdentifier();
+}
+
+// XBitmap
+com::sun::star::awt::Size SAL_CALL ImageWrapper::getSize() throw ( RuntimeException )
+{
+ vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ BitmapEx aBitmapEx( m_aImage.GetBitmapEx() );
+ Size aBitmapSize( aBitmapEx.GetSizePixel() );
+
+ return com::sun::star::awt::Size( aBitmapSize.Width(), aBitmapSize.Height() );
+}
+
+Sequence< sal_Int8 > SAL_CALL ImageWrapper::getDIB() throw ( RuntimeException )
+{
+ vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ SvMemoryStream aMem;
+ aMem << m_aImage.GetBitmapEx().GetBitmap();
+ return Sequence< sal_Int8 >( (sal_Int8*) aMem.GetData(), aMem.Tell() );
+}
+
+Sequence< sal_Int8 > SAL_CALL ImageWrapper::getMaskDIB() throw ( RuntimeException )
+{
+ vos::OGuard aGuard( Application::GetSolarMutex() );
+ BitmapEx aBmpEx( m_aImage.GetBitmapEx() );
+
+ if ( aBmpEx.IsAlpha() )
+ {
+ SvMemoryStream aMem;
+ aMem << aBmpEx.GetAlpha().GetBitmap();
+ return Sequence< sal_Int8 >( (sal_Int8*) aMem.GetData(), aMem.Tell() );
+ }
+ else if ( aBmpEx.IsTransparent() )
+ {
+ SvMemoryStream aMem;
+ aMem << aBmpEx.GetMask();
+ return Sequence< sal_Int8 >( (sal_Int8*) aMem.GetData(), aMem.Tell() );
+ }
+
+ return Sequence< sal_Int8 >();
+}
+
+// XUnoTunnel
+sal_Int64 SAL_CALL ImageWrapper::getSomething( const Sequence< sal_Int8 >& aIdentifier ) throw ( RuntimeException )
+{
+ if ( aIdentifier == impl_getStaticIdentifier() )
+ return reinterpret_cast< sal_Int64 >( this );
+ else
+ return 0;
+}
+
+}
+
diff --git a/framework/source/classes/makefile.mk b/framework/source/classes/makefile.mk
new file mode 100644
index 000000000000..22e8a6d540f0
--- /dev/null
+++ b/framework/source/classes/makefile.mk
@@ -0,0 +1,69 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# 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.
+#
+#*************************************************************************
+PRJ=..$/..
+
+PRJNAME= framework
+TARGET= fwk_classes
+ENABLE_EXCEPTIONS= TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# --- Generate -----------------------------------------------------
+
+SLOFILES= \
+ $(SLO)$/propertysethelper.obj \
+ $(SLO)$/framecontainer.obj \
+ $(SLO)$/taskcreator.obj \
+ $(SLO)$/menumanager.obj \
+ $(SLO)$/bmkmenu.obj \
+ $(SLO)$/droptargetlistener.obj \
+ $(SLO)$/converter.obj \
+ $(SLO)$/actiontriggerpropertyset.obj \
+ $(SLO)$/actiontriggerseparatorpropertyset.obj \
+ $(SLO)$/actiontriggercontainer.obj \
+ $(SLO)$/imagewrapper.obj \
+ $(SLO)$/rootactiontriggercontainer.obj \
+ $(SLO)$/protocolhandlercache.obj \
+ $(SLO)$/addonmenu.obj \
+ $(SLO)$/addonsoptions.obj \
+ $(SLO)$/fwkresid.obj \
+ $(SLO)$/fwlresid.obj \
+ $(SLO)$/framelistanalyzer.obj \
+ $(SLO)$/sfxhelperfunctions.obj \
+ $(SLO)$/menuextensionsupplier.obj \
+ $(SLO)$/fwktabwindow.obj
+
+SRS1NAME=$(TARGET)
+SRC1FILES =\
+ resource.src
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
+
diff --git a/framework/source/classes/menuextensionsupplier.cxx b/framework/source/classes/menuextensionsupplier.cxx
new file mode 100644
index 000000000000..07991c61f90f
--- /dev/null
+++ b/framework/source/classes/menuextensionsupplier.cxx
@@ -0,0 +1,64 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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"
+#include <classes/menuextensionsupplier.hxx>
+#include <osl/mutex.hxx>
+
+static pfunc_setMenuExtensionSupplier pMenuExtensionSupplierFunc = NULL;
+
+namespace framework
+{
+
+pfunc_setMenuExtensionSupplier SAL_CALL SetMenuExtensionSupplier( pfunc_setMenuExtensionSupplier pMenuExtensionSupplierFuncArg )
+{
+ ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
+
+ pfunc_setMenuExtensionSupplier pOldMenuExtensionSupplierFunc = pMenuExtensionSupplierFunc;
+ pMenuExtensionSupplierFunc = pMenuExtensionSupplierFuncArg;
+ return pOldMenuExtensionSupplierFunc;
+}
+
+MenuExtensionItem SAL_CALL GetMenuExtension()
+{
+ MenuExtensionItem aItem;
+
+ pfunc_setMenuExtensionSupplier pLocalMenuExtensionSupplierFunc( 0 );
+
+ {
+ ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
+ pLocalMenuExtensionSupplierFunc = pMenuExtensionSupplierFunc;
+ }
+
+ if ( pLocalMenuExtensionSupplierFunc )
+ return (*pLocalMenuExtensionSupplierFunc)();
+ else
+ return aItem;
+}
+
+}
diff --git a/framework/source/classes/menumanager.cxx b/framework/source/classes/menumanager.cxx
new file mode 100644
index 000000000000..0b2f30093ca8
--- /dev/null
+++ b/framework/source/classes/menumanager.cxx
@@ -0,0 +1,1179 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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"
+
+
+//_________________________________________________________________________________________________________________
+// my own includes
+//_________________________________________________________________________________________________________________
+#include <classes/menumanager.hxx>
+#include <xml/menuconfiguration.hxx>
+#include <classes/bmkmenu.hxx>
+#include <classes/addonmenu.hxx>
+#include <helper/imageproducer.hxx>
+#include <threadhelp/resetableguard.hxx>
+#include "classes/addonsoptions.hxx"
+#include <classes/fwkresid.hxx>
+#include <services.h>
+#include "classes/resource.hrc"
+
+//_________________________________________________________________________________________________________________
+// interface includes
+//_________________________________________________________________________________________________________________
+#include <com/sun/star/frame/XDispatchProvider.hpp>
+#include <com/sun/star/frame/XDispatch.hpp>
+#include <com/sun/star/util/XURLTransformer.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/frame/XFramesSupplier.hpp>
+#include <com/sun/star/frame/XDesktop.hpp>
+#include <com/sun/star/container/XEnumeration.hpp>
+#include <com/sun/star/util/XStringWidth.hpp>
+
+//_________________________________________________________________________________________________________________
+// includes of other projects
+//_________________________________________________________________________________________________________________
+#include <comphelper/processfactory.hxx>
+
+#include <comphelper/extract.hxx>
+#include <svtools/menuoptions.hxx>
+#include <unotools/historyoptions.hxx>
+#include <unotools/pathoptions.hxx>
+#include <unotools/localfilehelper.hxx>
+
+#ifndef _TOOLKIT_HELPER_VCLUNOHELPER_HXX_
+#include <toolkit/unohlp.hxx>
+#endif
+#include <tools/urlobj.hxx>
+
+#include <vcl/svapp.hxx>
+#include <vcl/window.hxx>
+#include <vos/mutex.hxx>
+#include <vcl/svapp.hxx>
+#include <osl/file.hxx>
+#include <cppuhelper/implbase1.hxx>
+
+//_________________________________________________________________________________________________________________
+// namespace
+//_________________________________________________________________________________________________________________
+
+using namespace ::cppu;
+using namespace ::vos;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::util;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::frame;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::container;
+
+
+class StringLength : public ::cppu::WeakImplHelper1< ::com::sun::star::util::XStringWidth >
+{
+ public:
+ StringLength() {}
+ virtual ~StringLength() {}
+
+ // XStringWidth
+ sal_Int32 SAL_CALL queryStringWidth( const ::rtl::OUString& aString )
+ throw (::com::sun::star::uno::RuntimeException)
+ {
+ return aString.getLength();
+ }
+};
+
+namespace framework
+{
+
+// special menu ids/command ids for dynamic popup menus
+#define SID_SFX_START 5000
+#define SID_NEWDOCDIRECT (SID_SFX_START + 537)
+#define SID_AUTOPILOTMENU (SID_SFX_START + 1381)
+#define SID_PICKLIST (SID_SFX_START + 510)
+#define SID_MDIWINDOWLIST (SID_SFX_START + 610)
+#define SID_ADDONLIST (SID_SFX_START + 1677)
+#define SID_HELPMENU (SID_SFX_START + 410)
+
+#define SFX_REFERER_USER "private:user"
+
+const ::rtl::OUString aSlotNewDocDirect( RTL_CONSTASCII_USTRINGPARAM( "slot:5537" ));
+const ::rtl::OUString aSlotAutoPilot( RTL_CONSTASCII_USTRINGPARAM( "slot:6381" ));
+
+const ::rtl::OUString aSpecialFileMenu( RTL_CONSTASCII_USTRINGPARAM( "file" ));
+const ::rtl::OUString aSpecialWindowMenu( RTL_CONSTASCII_USTRINGPARAM( "window" ));
+const ::rtl::OUString aSlotSpecialFileMenu( RTL_CONSTASCII_USTRINGPARAM( "slot:5510" ));
+const ::rtl::OUString aSlotSpecialWindowMenu( RTL_CONSTASCII_USTRINGPARAM( "slot:5610" ));
+const ::rtl::OUString aSlotSpecialToolsMenu( RTL_CONSTASCII_USTRINGPARAM( "slot:6677" ));
+
+// special uno commands for picklist and window list
+const ::rtl::OUString aSpecialFileCommand( RTL_CONSTASCII_USTRINGPARAM( "PickList" ));
+const ::rtl::OUString aSpecialWindowCommand( RTL_CONSTASCII_USTRINGPARAM( "WindowList" ));
+
+const ::rtl::OUString UNO_COMMAND( RTL_CONSTASCII_USTRINGPARAM( ".uno:" ));
+
+// #110897#
+MenuManager::MenuManager(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xServiceFactory,
+ REFERENCE< XFRAME >& rFrame, Menu* pMenu, sal_Bool bDelete, sal_Bool bDeleteChildren )
+: // #110897#
+ ThreadHelpBase( &Application::GetSolarMutex() ),
+ mxServiceFactory(xServiceFactory)
+{
+ m_bActive = sal_False;
+ m_bDeleteMenu = bDelete;
+ m_bDeleteChildren = bDeleteChildren;
+ m_pVCLMenu = pMenu;
+ m_xFrame = rFrame;
+ m_bInitialized = sal_False;
+ m_bIsBookmarkMenu = sal_False;
+ SAL_STATIC_CAST( ::com::sun::star::uno::XInterface*, (OWeakObject*)this )->acquire();
+
+ const StyleSettings& rSettings = Application::GetSettings().GetStyleSettings();
+ m_bWasHiContrast = rSettings.GetHighContrastMode();
+ m_bShowMenuImages = rSettings.GetUseImagesInMenus();
+
+ sal_Int32 nAddonsURLPrefixLength = ADDONSPOPUPMENU_URL_PREFIX.getLength();
+#if 0
+ ::std::vector< USHORT > aQueryLabelItemIdVector;
+#endif
+
+ USHORT nItemCount = pMenu->GetItemCount();
+ m_aMenuItemHandlerVector.reserve(nItemCount);
+ ::rtl::OUString aItemCommand;
+ for ( USHORT i = 0; i < nItemCount; i++ )
+ {
+ USHORT nItemId = FillItemCommand(aItemCommand,pMenu, i );
+ bool bShowMenuImages( m_bShowMenuImages );
+ MenuItemBits nBits = pMenu->GetItemBits( nItemId );
+ // overwrite the default?
+ if ( nBits )
+ bShowMenuImages = ( ( nBits & MIB_ICON ) == MIB_ICON );
+
+
+ PopupMenu* pPopupMenu = pMenu->GetPopupMenu( nItemId );
+ if ( pPopupMenu )
+ {
+ AddMenu(pPopupMenu,aItemCommand,nItemId,bDeleteChildren,bDeleteChildren);
+ if (! (( aItemCommand.getLength() > nAddonsURLPrefixLength ) &&
+ ( aItemCommand.indexOf( ADDONSPOPUPMENU_URL_PREFIX ) == 0 )) )
+ {
+ // #110897#
+ // MenuManager* pSubMenuManager = new MenuManager( rFrame, pPopupMenu, bDeleteChildren, bDeleteChildren );
+#if 0
+ if ( pMenu->GetItemText( nItemId ).Len() == 0 )
+ aQueryLabelItemIdVector.push_back( nItemId );
+#endif
+
+ // Create addon popup menu if there exist elements and this is the tools popup menu
+ if (( nItemId == SID_ADDONLIST ||
+ aItemCommand == aSlotSpecialToolsMenu ) &&
+ AddonMenuManager::HasAddonMenuElements() )
+ {
+ USHORT nCount = 0;
+ AddonMenu* pSubMenu = AddonMenuManager::CreateAddonMenu( rFrame );
+ if ( pSubMenu && ( pSubMenu->GetItemCount() > 0 ))
+ {
+ if ( pPopupMenu->GetItemType( nCount-1 ) != MENUITEM_SEPARATOR )
+ pPopupMenu->InsertSeparator();
+
+ // Use resource to load popup menu title
+ String aAddonsStrRes = String( FwkResId( STR_MENU_ADDONS ));
+ pPopupMenu->InsertItem( ITEMID_ADDONLIST, aAddonsStrRes );
+ pPopupMenu->SetPopupMenu( ITEMID_ADDONLIST, pSubMenu );
+
+ // Set item command for popup menu to enable it for GetImageFromURL
+ const static ::rtl::OUString aSlotString( RTL_CONSTASCII_USTRINGPARAM( "slot:" ));
+ aItemCommand = aSlotString;
+ aItemCommand += ::rtl::OUString::valueOf( (sal_Int32)ITEMID_ADDONLIST );
+ pPopupMenu->SetItemCommand( ITEMID_ADDONLIST, aItemCommand );
+
+ // #110897#
+ // MenuManager* pSubMenuManager = new MenuManager( rFrame, pSubMenu, sal_True, sal_False );
+ AddMenu(pSubMenu,::rtl::OUString(),nItemId,sal_True,sal_False);
+#if 0
+ if ( pMenu->GetItemText( nItemId ).Len() == 0 )
+ aQueryLabelItemIdVector.push_back( nItemId );
+#endif
+ // Set image for the addon popup menu item
+ if ( bShowMenuImages && !pPopupMenu->GetItemImage( ITEMID_ADDONLIST ))
+ {
+ Image aImage = GetImageFromURL( rFrame, aItemCommand, FALSE, m_bWasHiContrast );
+ if ( !!aImage )
+ pPopupMenu->SetItemImage( ITEMID_ADDONLIST, aImage );
+ }
+ }
+ else
+ delete pSubMenu;
+ }
+ }
+ }
+ else
+ {
+ if ( nItemId == SID_NEWDOCDIRECT ||
+ aItemCommand == aSlotNewDocDirect )
+ {
+ // #110897#
+ // Reference< ::com::sun::star::lang::XMultiServiceFactory > aMultiServiceFactory(::comphelper::getProcessServiceFactory());
+ // MenuConfiguration aMenuCfg( aMultiServiceFactory );
+ MenuConfiguration aMenuCfg( getServiceFactory() );
+ BmkMenu* pSubMenu = (BmkMenu*)aMenuCfg.CreateBookmarkMenu( rFrame, BOOKMARK_NEWMENU );
+ pMenu->SetPopupMenu( nItemId, pSubMenu );
+
+ // #110897#
+ // MenuManager* pSubMenuManager = new MenuManager( rFrame, pSubMenu, sal_True, sal_False );
+ AddMenu(pSubMenu,::rtl::OUString(),nItemId,sal_True,sal_False);
+#if 0
+ if ( pMenu->GetItemText( nItemId ).Len() == 0 )
+ aQueryLabelItemIdVector.push_back( nItemId );
+#endif
+
+ if ( bShowMenuImages && !pMenu->GetItemImage( nItemId ))
+ {
+ Image aImage = GetImageFromURL( rFrame, aItemCommand, FALSE, m_bWasHiContrast );
+ if ( !!aImage )
+ pMenu->SetItemImage( nItemId, aImage );
+ }
+ }
+ else if ( nItemId == SID_AUTOPILOTMENU ||
+ aItemCommand == aSlotAutoPilot )
+ {
+ // #110897#
+ // Reference< ::com::sun::star::lang::XMultiServiceFactory > aMultiServiceFactory(::comphelper::getProcessServiceFactory());
+ // MenuConfiguration aMenuCfg( aMultiServiceFactory );
+ MenuConfiguration aMenuCfg( getServiceFactory() );
+ BmkMenu* pSubMenu = (BmkMenu*)aMenuCfg.CreateBookmarkMenu( rFrame, BOOKMARK_WIZARDMENU );
+ pMenu->SetPopupMenu( nItemId, pSubMenu );
+
+ // #110897#
+ // MenuManager* pSubMenuManager = new MenuManager( rFrame, pSubMenu, sal_True, sal_False );
+ AddMenu(pSubMenu,::rtl::OUString(),nItemId,sal_True,sal_False);
+#if 0
+ if ( pMenu->GetItemText( nItemId ).Len() == 0 )
+ aQueryLabelItemIdVector.push_back( nItemId );
+#endif
+
+ if ( bShowMenuImages && !pMenu->GetItemImage( nItemId ))
+ {
+ Image aImage = GetImageFromURL( rFrame, aItemCommand, FALSE, m_bWasHiContrast );
+ if ( !!aImage )
+ pMenu->SetItemImage( nItemId, aImage );
+ }
+ }
+ else if ( pMenu->GetItemType( i ) != MENUITEM_SEPARATOR )
+ {
+ if ( bShowMenuImages )
+ {
+ if ( AddonMenuManager::IsAddonMenuId( nItemId ))
+ {
+ // Add-Ons uses a images from different places
+ Image aImage;
+ rtl::OUString aImageId;
+
+ MenuConfiguration::Attributes* pMenuAttributes =
+ (MenuConfiguration::Attributes*)pMenu->GetUserValue( nItemId );
+
+ if ( pMenuAttributes && pMenuAttributes->aImageId.getLength() > 0 )
+ {
+ // Retrieve image id from menu attributes
+ aImage = GetImageFromURL( rFrame, aImageId, FALSE, m_bWasHiContrast );
+ }
+
+ if ( !aImage )
+ {
+ aImage = GetImageFromURL( rFrame, aItemCommand, FALSE, m_bWasHiContrast );
+ if ( !aImage )
+ aImage = AddonsOptions().GetImageFromURL( aItemCommand, FALSE, m_bWasHiContrast );
+ }
+
+ if ( !!aImage )
+ pMenu->SetItemImage( nItemId, aImage );
+ }
+ else if ( !pMenu->GetItemImage( nItemId ))
+ {
+ Image aImage = GetImageFromURL( rFrame, aItemCommand, FALSE, m_bWasHiContrast );
+ if ( !!aImage )
+ pMenu->SetItemImage( nItemId, aImage );
+ }
+ }
+
+ REFERENCE< XDISPATCH > aXDispatchRef;
+ m_aMenuItemHandlerVector.push_back( new MenuItemHandler( nItemId, NULL, aXDispatchRef ));
+#if 0
+ if ( pMenu->GetItemText( nItemId ).Len() == 0 )
+ aQueryLabelItemIdVector.push_back( nItemId );
+#endif
+ }
+ }
+ }
+
+
+ // retrieve label information for all menu items without item text
+#if 0
+ if ( aQueryLabelItemIdVector.size() > 0 )
+ {
+ Sequence< ::rtl::OUString > aURLSequence( aQueryLabelItemIdVector.size() );
+ Sequence< ::rtl::OUString > aLabelSequence( aQueryLabelItemIdVector.size() );
+
+ sal_uInt32 nPos = 0;
+ ::std::vector< USHORT >::iterator p;
+ for ( p = aQueryLabelItemIdVector.begin(); p != aQueryLabelItemIdVector.end(); p++ )
+ aURLSequence[nPos++] = pMenu->GetItemCommand( *p );
+
+ Reference< XDispatchInformationProvider > xDIP( xFrame, UNO_QUERY );
+ if ( xDIP.is() )
+ {
+ nPos = 0;
+ xDIP->queryDispatchInformations( aURLSequence, aLabelSequence );
+ for ( p = aQueryLabelItemIdVector.begin(); p != aQueryLabelItemIdVector.end(); p++ )
+ pMenu->SetItemText( *p, aLabelSequence( nPos++ ));
+ }
+ }
+#endif
+ SetHdl();
+}
+
+// #110897#
+MenuManager::MenuManager(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xServiceFactory,
+ REFERENCE< XFRAME >& rFrame, AddonMenu* pAddonMenu, sal_Bool bDelete, sal_Bool bDeleteChildren )
+: // #110897#
+ ThreadHelpBase( &Application::GetSolarMutex() ),
+ mxServiceFactory(xServiceFactory)
+{
+ m_bActive = sal_False;
+ m_bDeleteMenu = bDelete;
+ m_bDeleteChildren = bDeleteChildren;
+ m_pVCLMenu = pAddonMenu;
+ m_xFrame = rFrame;
+ m_bInitialized = sal_False;
+ m_bIsBookmarkMenu = sal_True;
+
+ const StyleSettings& rSettings = Application::GetSettings().GetStyleSettings();
+ m_bWasHiContrast = rSettings.GetHighContrastMode();
+
+ SAL_STATIC_CAST( ::com::sun::star::uno::XInterface*, (OWeakObject*)this )->acquire();
+
+ USHORT nItemCount = pAddonMenu->GetItemCount();
+ m_aMenuItemHandlerVector.reserve(nItemCount);
+ ::rtl::OUString aItemCommand;
+ for ( USHORT i = 0; i < nItemCount; i++ )
+ {
+ USHORT nItemId = FillItemCommand(aItemCommand,pAddonMenu, i );
+
+ PopupMenu* pPopupMenu = pAddonMenu->GetPopupMenu( nItemId );
+ if ( pPopupMenu )
+ {
+ // #110897#
+ // MenuManager* pSubMenuManager = new MenuManager( rFrame, pPopupMenu, bDeleteChildren, bDeleteChildren );
+ AddMenu(pPopupMenu,aItemCommand,nItemId,bDeleteChildren,bDeleteChildren);
+ }
+ else
+ {
+ if ( pAddonMenu->GetItemType( i ) != MENUITEM_SEPARATOR )
+ {
+ MenuConfiguration::Attributes* pAddonAttributes = (MenuConfiguration::Attributes *)(pAddonMenu->GetUserValue( nItemId ));
+ REFERENCE< XDISPATCH > aXDispatchRef;
+ MenuItemHandler* pMenuItemHandler = new MenuItemHandler( nItemId, NULL, aXDispatchRef );
+
+ if ( pAddonAttributes )
+ {
+ // read additional attributes from attributes struct and AddonMenu implementation will delete all attributes itself!!
+ pMenuItemHandler->aTargetFrame = pAddonAttributes->aTargetFrame;
+ }
+
+ m_aMenuItemHandlerVector.push_back( pMenuItemHandler );
+ }
+ }
+ }
+
+ SetHdl();
+}
+
+void MenuManager::SetHdl()
+{
+ m_pVCLMenu->SetHighlightHdl( LINK( this, MenuManager, Highlight ));
+ m_pVCLMenu->SetActivateHdl( LINK( this, MenuManager, Activate ));
+ m_pVCLMenu->SetDeactivateHdl( LINK( this, MenuManager, Deactivate ));
+ m_pVCLMenu->SetSelectHdl( LINK( this, MenuManager, Select ));
+
+ if ( mxServiceFactory.is() )
+ m_xURLTransformer.set( mxServiceFactory->createInstance(SERVICENAME_URLTRANSFORMER),UNO_QUERY );
+}
+
+MenuManager::~MenuManager()
+{
+ std::vector< MenuItemHandler* >::iterator p;
+ for ( p = m_aMenuItemHandlerVector.begin(); p != m_aMenuItemHandlerVector.end(); p++ )
+ {
+ MenuItemHandler* pItemHandler = *p;
+ pItemHandler->xMenuItemDispatch.clear();
+ if ( pItemHandler->pSubMenuManager )
+ SAL_STATIC_CAST( ::com::sun::star::uno::XInterface*, (OWeakObject*)pItemHandler->pSubMenuManager )->release();
+ delete pItemHandler;
+ }
+
+ if ( m_bDeleteMenu )
+ delete m_pVCLMenu;
+}
+
+
+MenuManager::MenuItemHandler* MenuManager::GetMenuItemHandler( USHORT nItemId )
+{
+ ResetableGuard aGuard( m_aLock );
+
+ std::vector< MenuItemHandler* >::iterator p;
+ for ( p = m_aMenuItemHandlerVector.begin(); p != m_aMenuItemHandlerVector.end(); p++ )
+ {
+ MenuItemHandler* pItemHandler = *p;
+ if ( pItemHandler->nItemId == nItemId )
+ return pItemHandler;
+ }
+
+ return 0;
+}
+
+
+void SAL_CALL MenuManager::statusChanged( const FEATURSTATEEVENT& Event )
+throw ( RuntimeException )
+{
+ ::rtl::OUString aFeatureURL = Event.FeatureURL.Complete;
+ MenuItemHandler* pStatusChangedMenu = NULL;
+
+ {
+ ResetableGuard aGuard( m_aLock );
+
+ std::vector< MenuItemHandler* >::iterator p;
+ for ( p = m_aMenuItemHandlerVector.begin(); p != m_aMenuItemHandlerVector.end(); p++ )
+ {
+ MenuItemHandler* pMenuItemHandler = *p;
+ if ( pMenuItemHandler->aMenuItemURL == aFeatureURL )
+ {
+ pStatusChangedMenu = pMenuItemHandler;
+ break;
+ }
+ }
+ }
+
+ if ( pStatusChangedMenu )
+ {
+ OGuard aSolarGuard( Application::GetSolarMutex() );
+ {
+ ResetableGuard aGuard( m_aLock );
+
+ sal_Bool bSetCheckmark = sal_False;
+ sal_Bool bCheckmark = sal_False;
+ sal_Bool bMenuItemEnabled = m_pVCLMenu->IsItemEnabled( pStatusChangedMenu->nItemId );
+
+ if ( Event.IsEnabled != bMenuItemEnabled )
+ m_pVCLMenu->EnableItem( pStatusChangedMenu->nItemId, Event.IsEnabled );
+
+ if ( Event.State >>= bCheckmark )
+ bSetCheckmark = sal_True;
+
+ if ( bSetCheckmark )
+ m_pVCLMenu->CheckItem( pStatusChangedMenu->nItemId, bCheckmark );
+ }
+
+ if ( Event.Requery )
+ {
+ URL aTargetURL;
+ aTargetURL.Complete = pStatusChangedMenu->aMenuItemURL;
+
+ // #110897#
+ m_xURLTransformer->parseStrict( aTargetURL );
+
+ REFERENCE< XDISPATCHPROVIDER > xDispatchProvider( m_xFrame, UNO_QUERY );
+ REFERENCE< XDISPATCH > xMenuItemDispatch = xDispatchProvider->queryDispatch(
+ aTargetURL, ::rtl::OUString(), 0 );
+
+ if ( xMenuItemDispatch.is() )
+ {
+ pStatusChangedMenu->xMenuItemDispatch = xMenuItemDispatch;
+ pStatusChangedMenu->aMenuItemURL = aTargetURL.Complete;
+ xMenuItemDispatch->addStatusListener( SAL_STATIC_CAST( XSTATUSLISTENER*, this ), aTargetURL );
+ }
+ }
+ }
+}
+
+
+void MenuManager::RemoveListener()
+{
+ ResetableGuard aGuard( m_aLock );
+ ClearMenuDispatch();
+}
+
+void MenuManager::ClearMenuDispatch(const EVENTOBJECT& Source,bool _bRemoveOnly)
+{
+ // disposing called from parent dispatcher
+ // remove all listener to prepare shutdown
+
+ // #110897#
+ std::vector< MenuItemHandler* >::iterator p;
+ for ( p = m_aMenuItemHandlerVector.begin(); p != m_aMenuItemHandlerVector.end(); p++ )
+ {
+ MenuItemHandler* pItemHandler = *p;
+ if ( pItemHandler->xMenuItemDispatch.is() )
+ {
+ URL aTargetURL;
+ aTargetURL.Complete = pItemHandler->aMenuItemURL;
+ m_xURLTransformer->parseStrict( aTargetURL );
+
+ pItemHandler->xMenuItemDispatch->removeStatusListener(
+ SAL_STATIC_CAST( XSTATUSLISTENER*, this ), aTargetURL );
+ }
+
+ pItemHandler->xMenuItemDispatch.clear();
+ if ( pItemHandler->pSubMenuManager )
+ {
+ if ( _bRemoveOnly )
+ pItemHandler->pSubMenuManager->RemoveListener();
+ else
+ pItemHandler->pSubMenuManager->disposing( Source );
+ }
+ }
+}
+
+
+void SAL_CALL MenuManager::disposing( const EVENTOBJECT& Source ) throw ( RUNTIMEEXCEPTION )
+{
+ if ( Source.Source == m_xFrame )
+ {
+ ResetableGuard aGuard( m_aLock );
+ ClearMenuDispatch(Source,false);
+ }
+ else
+ {
+ // disposing called from menu item dispatcher, remove listener
+ MenuItemHandler* pMenuItemDisposing = NULL;
+
+ {
+ ResetableGuard aGuard( m_aLock );
+
+ std::vector< MenuItemHandler* >::iterator p;
+ for ( p = m_aMenuItemHandlerVector.begin(); p != m_aMenuItemHandlerVector.end(); p++ )
+ {
+ MenuItemHandler* pMenuItemHandler = *p;
+ if ( pMenuItemHandler->xMenuItemDispatch == Source.Source )
+ {
+ pMenuItemDisposing = pMenuItemHandler;
+ break;
+ }
+ }
+
+ if ( pMenuItemDisposing )
+ {
+ URL aTargetURL;
+ aTargetURL.Complete = pMenuItemDisposing->aMenuItemURL;
+
+ // #110897#
+ m_xURLTransformer->parseStrict( aTargetURL );
+
+ pMenuItemDisposing->xMenuItemDispatch->removeStatusListener(SAL_STATIC_CAST( XSTATUSLISTENER*, this ), aTargetURL );
+ pMenuItemDisposing->xMenuItemDispatch.clear();
+ }
+ }
+ }
+}
+
+
+void MenuManager::UpdateSpecialFileMenu( Menu* pMenu )
+{
+ // update picklist
+ Sequence< Sequence< PropertyValue > > aHistoryList = SvtHistoryOptions().GetList( ePICKLIST );
+ ::std::vector< MenuItemHandler* > aNewPickVector;
+ Reference< XStringWidth > xStringLength( new StringLength );
+
+ USHORT nPickItemId = START_ITEMID_PICKLIST;
+ int nPickListMenuItems = ( aHistoryList.getLength() > 99 ) ? 99 : aHistoryList.getLength();
+
+ aNewPickVector.reserve(nPickListMenuItems);
+ for ( int i = 0; i < nPickListMenuItems; i++ )
+ {
+ Sequence< PropertyValue > aPickListEntry = aHistoryList[i];
+
+ REFERENCE< XDISPATCH > aXDispatchRef;
+ MenuItemHandler* pNewMenuItemHandler = new MenuItemHandler(
+ nPickItemId++,
+ NULL,
+ aXDispatchRef );
+
+ for ( int j = 0; j < aPickListEntry.getLength(); j++ )
+ {
+ Any a = aPickListEntry[j].Value;
+
+ if ( aPickListEntry[j].Name == HISTORY_PROPERTYNAME_URL )
+ a >>= pNewMenuItemHandler->aMenuItemURL;
+ else if ( aPickListEntry[j].Name == HISTORY_PROPERTYNAME_FILTER )
+ a >>= pNewMenuItemHandler->aFilter;
+ else if ( aPickListEntry[j].Name == HISTORY_PROPERTYNAME_TITLE )
+ a >>= pNewMenuItemHandler->aTitle;
+ else if ( aPickListEntry[j].Name == HISTORY_PROPERTYNAME_PASSWORD )
+ a >>= pNewMenuItemHandler->aPassword;
+ }
+
+ aNewPickVector.push_back( pNewMenuItemHandler );
+ }
+
+ if ( !aNewPickVector.empty() )
+ {
+ URL aTargetURL;
+ REFERENCE< XDISPATCHPROVIDER > xDispatchProvider( m_xFrame, UNO_QUERY );
+
+ // #110897#
+ REFERENCE< XDISPATCH > xMenuItemDispatch;
+
+ static const ::rtl::OUString s_sDefault(RTL_CONSTASCII_USTRINGPARAM("_default"));
+ // query for dispatcher
+ std::vector< MenuItemHandler* >::iterator p;
+ for ( p = aNewPickVector.begin(); p != aNewPickVector.end(); p++ )
+ {
+ MenuItemHandler* pMenuItemHandler = *p;
+
+ aTargetURL.Complete = pMenuItemHandler->aMenuItemURL;
+ m_xURLTransformer->parseStrict( aTargetURL );
+
+ if ( !xMenuItemDispatch.is() )
+ {
+ // attention: this code assume that "_blank" can only be consumed by desktop service
+ xMenuItemDispatch = xDispatchProvider->queryDispatch( aTargetURL, s_sDefault, 0 );
+ }
+
+ if ( xMenuItemDispatch.is() )
+ {
+ pMenuItemHandler->xMenuItemDispatch = xMenuItemDispatch;
+ pMenuItemHandler->aMenuItemURL = aTargetURL.Complete;
+ }
+ }
+
+ {
+ ResetableGuard aGuard( m_aLock );
+
+ int nRemoveItemCount = 0;
+ int nItemCount = pMenu->GetItemCount();
+
+ if ( nItemCount > 0 )
+ {
+ // remove all old picklist entries from menu
+ sal_uInt16 nPos = pMenu->GetItemPos( START_ITEMID_PICKLIST );
+ for ( sal_uInt16 n = nPos; n < pMenu->GetItemCount(); )
+ {
+ pMenu->RemoveItem( n );
+ ++nRemoveItemCount;
+ }
+
+ if ( pMenu->GetItemType( pMenu->GetItemCount()-1 ) == MENUITEM_SEPARATOR )
+ pMenu->RemoveItem( pMenu->GetItemCount()-1 );
+
+ // remove all old picklist entries from menu handler
+ if ( nRemoveItemCount > 0 )
+ {
+ for( sal_uInt32 nIndex = m_aMenuItemHandlerVector.size() - nRemoveItemCount;
+ nIndex < m_aMenuItemHandlerVector.size(); )
+ {
+ delete m_aMenuItemHandlerVector.at( nIndex );
+ m_aMenuItemHandlerVector.erase( m_aMenuItemHandlerVector.begin() + nIndex );
+ }
+ }
+ }
+
+ // append new picklist menu entries
+ aNewPickVector.reserve(aNewPickVector.size());
+ pMenu->InsertSeparator();
+ const sal_uInt32 nCount = aNewPickVector.size();
+ for ( sal_uInt32 i = 0; i < nCount; i++ )
+ {
+ char menuShortCut[5] = "~n: ";
+
+ ::rtl::OUString aMenuShortCut;
+ if ( i <= 9 )
+ {
+ if ( i == 9 )
+ aMenuShortCut = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "1~0: " ));
+ else
+ {
+ menuShortCut[1] = (char)( '1' + i );
+ aMenuShortCut = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( menuShortCut ));
+ }
+ }
+ else
+ {
+ aMenuShortCut = rtl::OUString::valueOf((sal_Int32)( i + 1 ));
+ aMenuShortCut += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ": " ));
+ }
+
+ // Abbreviate URL
+ rtl::OUString aURLString( aNewPickVector.at( i )->aMenuItemURL );
+ rtl::OUString aTipHelpText;
+ rtl::OUString aMenuTitle;
+ INetURLObject aURL( aURLString );
+
+ if ( aURL.GetProtocol() == INET_PROT_FILE )
+ {
+ // Do handle file URL differently => convert it to a system
+ // path and abbreviate it with a special function:
+ String aFileSystemPath( aURL.getFSysPath( INetURLObject::FSYS_DETECT ) );
+
+ ::rtl::OUString aSystemPath( aFileSystemPath );
+ ::rtl::OUString aCompactedSystemPath;
+
+ aTipHelpText = aSystemPath;
+ oslFileError nError = osl_abbreviateSystemPath( aSystemPath.pData, &aCompactedSystemPath.pData, 46, NULL );
+ if ( !nError )
+ aMenuTitle = String( aCompactedSystemPath );
+ else
+ aMenuTitle = aSystemPath;
+ }
+ else
+ {
+ // Use INetURLObject to abbreviate all other URLs
+ String aShortURL;
+ aShortURL = aURL.getAbbreviated( xStringLength, 46, INetURLObject::DECODE_UNAMBIGUOUS );
+ aMenuTitle += aShortURL;
+ aTipHelpText = aURLString;
+ }
+
+ ::rtl::OUString aTitle( aMenuShortCut + aMenuTitle );
+
+ MenuItemHandler* pMenuItemHandler = aNewPickVector.at( i );
+ pMenu->InsertItem( pMenuItemHandler->nItemId, aTitle );
+ pMenu->SetTipHelpText( pMenuItemHandler->nItemId, aTipHelpText );
+ m_aMenuItemHandlerVector.push_back( pMenuItemHandler );
+ }
+ }
+ }
+}
+
+void MenuManager::UpdateSpecialWindowMenu( Menu* pMenu,const Reference< XMultiServiceFactory >& xServiceFactory,framework::IMutex& _rMutex )
+{
+ // update window list
+ ::std::vector< ::rtl::OUString > aNewWindowListVector;
+
+ // #110897#
+ Reference< XDesktop > xDesktop( xServiceFactory->createInstance( SERVICENAME_DESKTOP ), UNO_QUERY );
+
+ USHORT nActiveItemId = 0;
+ USHORT nItemId = START_ITEMID_WINDOWLIST;
+
+ if ( xDesktop.is() )
+ {
+ Reference< XFramesSupplier > xTasksSupplier( xDesktop, UNO_QUERY );
+ Reference< XFrame > xCurrentFrame = xDesktop->getCurrentFrame();
+ Reference< XIndexAccess > xList( xTasksSupplier->getFrames(), UNO_QUERY );
+ sal_Int32 nCount = xList->getCount();
+ aNewWindowListVector.reserve(nCount);
+ for (sal_Int32 i=0; i<nCount; ++i )
+ {
+ Reference< XFrame > xFrame;
+ xList->getByIndex(i) >>= xFrame;
+
+ if (xFrame.is())
+ {
+ if ( xFrame == xCurrentFrame )
+ nActiveItemId = nItemId;
+
+ Window* pWin = VCLUnoHelper::GetWindow( xFrame->getContainerWindow() );
+ if ( pWin && pWin->IsVisible() )
+ {
+ aNewWindowListVector.push_back( pWin->GetText() );
+ ++nItemId;
+ }
+ }
+ }
+ }
+
+ {
+ ResetableGuard aGuard( _rMutex );
+
+ int nItemCount = pMenu->GetItemCount();
+
+ if ( nItemCount > 0 )
+ {
+ // remove all old window list entries from menu
+ sal_uInt16 nPos = pMenu->GetItemPos( START_ITEMID_WINDOWLIST );
+ for ( sal_uInt16 n = nPos; n < pMenu->GetItemCount(); )
+ pMenu->RemoveItem( n );
+
+ if ( pMenu->GetItemType( pMenu->GetItemCount()-1 ) == MENUITEM_SEPARATOR )
+ pMenu->RemoveItem( pMenu->GetItemCount()-1 );
+ }
+
+ if ( !aNewWindowListVector.empty() )
+ {
+ // append new window list entries to menu
+ pMenu->InsertSeparator();
+ nItemId = START_ITEMID_WINDOWLIST;
+ const sal_uInt32 nCount = aNewWindowListVector.size();
+ for ( sal_uInt32 i = 0; i < nCount; i++ )
+ {
+ pMenu->InsertItem( nItemId, aNewWindowListVector.at( i ), MIB_RADIOCHECK );
+ if ( nItemId == nActiveItemId )
+ pMenu->CheckItem( nItemId );
+ ++nItemId;
+ }
+ }
+ }
+}
+
+
+void MenuManager::CreatePicklistArguments( Sequence< PropertyValue >& aArgsList, const MenuItemHandler* pMenuItemHandler )
+{
+ int NUM_OF_PICKLIST_ARGS = 3;
+
+ Any a;
+ aArgsList.realloc( NUM_OF_PICKLIST_ARGS );
+
+ aArgsList[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "FileName" ));
+ a <<= pMenuItemHandler->aMenuItemURL;
+ aArgsList[0].Value = a;
+
+ aArgsList[1].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Referer" ));
+ a <<= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SFX_REFERER_USER ));
+ aArgsList[1].Value = a;
+
+ ::rtl::OUString aFilter( pMenuItemHandler->aFilter );
+
+ sal_Int32 nPos = aFilter.indexOf( '|' );
+ if ( nPos >= 0 )
+ {
+ ::rtl::OUString aFilterOptions;
+
+ if ( nPos < ( aFilter.getLength() - 1 ) )
+ aFilterOptions = aFilter.copy( nPos+1 );
+
+ aArgsList[2].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "FilterOptions" ));
+ a <<= aFilterOptions;
+ aArgsList[2].Value = a;
+
+ aFilter = aFilter.copy( 0, nPos-1 );
+ aArgsList.realloc( ++NUM_OF_PICKLIST_ARGS );
+ }
+
+ aArgsList[NUM_OF_PICKLIST_ARGS-1].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "FilterName" ));
+ a <<= aFilter;
+ aArgsList[NUM_OF_PICKLIST_ARGS-1].Value = a;
+}
+
+
+//_________________________________________________________________________________________________________________
+// vcl handler
+//_________________________________________________________________________________________________________________
+
+IMPL_LINK( MenuManager, Activate, Menu *, pMenu )
+{
+ if ( pMenu == m_pVCLMenu )
+ {
+ // set/unset hiding disabled menu entries
+ sal_Bool bDontHide = SvtMenuOptions().IsEntryHidingEnabled();
+ const StyleSettings& rSettings = Application::GetSettings().GetStyleSettings();
+ sal_Bool bShowMenuImages = rSettings.GetUseImagesInMenus();
+
+ sal_uInt16 nFlag = pMenu->GetMenuFlags();
+ if ( bDontHide )
+ nFlag &= ~MENU_FLAG_HIDEDISABLEDENTRIES;
+ else
+ nFlag |= MENU_FLAG_HIDEDISABLEDENTRIES;
+ pMenu->SetMenuFlags( nFlag );
+
+ if ( m_bActive )
+ return 0;
+
+ m_bActive = TRUE;
+
+ ::rtl::OUString aCommand( m_aMenuItemCommand );
+ if ( m_aMenuItemCommand.matchIgnoreAsciiCase( UNO_COMMAND, 0 ))
+ {
+ // Remove protocol part from command so we can use an easier comparision method
+ aCommand = aCommand.copy( UNO_COMMAND.getLength() );
+ }
+
+ if ( m_aMenuItemCommand == aSpecialFileMenu ||
+ m_aMenuItemCommand == aSlotSpecialFileMenu ||
+ aCommand == aSpecialFileCommand )
+ UpdateSpecialFileMenu( pMenu );
+ else if ( m_aMenuItemCommand == aSpecialWindowMenu ||
+ m_aMenuItemCommand == aSlotSpecialWindowMenu ||
+ aCommand == aSpecialWindowCommand )
+ UpdateSpecialWindowMenu( pMenu,getServiceFactory(),m_aLock );
+
+ // Check if some modes have changed so we have to update our menu images
+ sal_Bool bIsHiContrast = rSettings.GetHighContrastMode();
+
+ if ( m_bWasHiContrast != bIsHiContrast || bShowMenuImages != m_bShowMenuImages )
+ {
+ // The mode changed so we have to replace all images
+ m_bWasHiContrast = bIsHiContrast;
+ m_bShowMenuImages = bShowMenuImages;
+ FillMenuImages(m_xFrame,pMenu,bIsHiContrast,bShowMenuImages);
+ }
+
+ if ( m_bInitialized )
+ return 0;
+ else
+ {
+ URL aTargetURL;
+
+ // #110897#
+ ResetableGuard aGuard( m_aLock );
+
+ REFERENCE< XDISPATCHPROVIDER > xDispatchProvider( m_xFrame, UNO_QUERY );
+ if ( xDispatchProvider.is() )
+ {
+ std::vector< MenuItemHandler* >::iterator p;
+ for ( p = m_aMenuItemHandlerVector.begin(); p != m_aMenuItemHandlerVector.end(); p++ )
+ {
+ MenuItemHandler* pMenuItemHandler = *p;
+ if ( pMenuItemHandler &&
+ pMenuItemHandler->pSubMenuManager == 0 &&
+ !pMenuItemHandler->xMenuItemDispatch.is() )
+ {
+ // There is no dispatch mechanism for the special window list menu items,
+ // because they are handled directly through XFrame->activate!!!
+ if ( pMenuItemHandler->nItemId < START_ITEMID_WINDOWLIST ||
+ pMenuItemHandler->nItemId > END_ITEMID_WINDOWLIST )
+ {
+ ::rtl::OUString aItemCommand = pMenu->GetItemCommand( pMenuItemHandler->nItemId );
+ if ( !aItemCommand.getLength() )
+ {
+ const static ::rtl::OUString aSlotString( RTL_CONSTASCII_USTRINGPARAM( "slot:" ));
+ aItemCommand = aSlotString;
+ aItemCommand += ::rtl::OUString::valueOf( (sal_Int32)pMenuItemHandler->nItemId );
+ pMenu->SetItemCommand( pMenuItemHandler->nItemId, aItemCommand );
+ }
+
+ aTargetURL.Complete = aItemCommand;
+
+ m_xURLTransformer->parseStrict( aTargetURL );
+
+ REFERENCE< XDISPATCH > xMenuItemDispatch;
+ if ( m_bIsBookmarkMenu )
+ xMenuItemDispatch = xDispatchProvider->queryDispatch( aTargetURL, pMenuItemHandler->aTargetFrame, 0 );
+ else
+ xMenuItemDispatch = xDispatchProvider->queryDispatch( aTargetURL, ::rtl::OUString(), 0 );
+
+ if ( xMenuItemDispatch.is() )
+ {
+ pMenuItemHandler->xMenuItemDispatch = xMenuItemDispatch;
+ pMenuItemHandler->aMenuItemURL = aTargetURL.Complete;
+ xMenuItemDispatch->addStatusListener( SAL_STATIC_CAST( XSTATUSLISTENER*, this ), aTargetURL );
+ }
+ else
+ pMenu->EnableItem( pMenuItemHandler->nItemId, sal_False );
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return 1;
+}
+
+
+IMPL_LINK( MenuManager, Deactivate, Menu *, pMenu )
+{
+ if ( pMenu == m_pVCLMenu )
+ m_bActive = sal_False;
+
+ return 1;
+}
+
+
+IMPL_LINK( MenuManager, Select, Menu *, pMenu )
+{
+ URL aTargetURL;
+ Sequence<PropertyValue> aArgs;
+ REFERENCE< XDISPATCH > xDispatch;
+
+ {
+ ResetableGuard aGuard( m_aLock );
+
+ USHORT nCurItemId = pMenu->GetCurItemId();
+ if ( pMenu == m_pVCLMenu &&
+ pMenu->GetItemType( nCurItemId ) != MENUITEM_SEPARATOR )
+ {
+ if ( nCurItemId >= START_ITEMID_WINDOWLIST &&
+ nCurItemId <= END_ITEMID_WINDOWLIST )
+ {
+ // window list menu item selected
+
+ // #110897#
+ // Reference< XFramesSupplier > xDesktop( ::comphelper::getProcessServiceFactory()->createInstance(
+ // DESKTOP_SERVICE ), UNO_QUERY );
+ Reference< XFramesSupplier > xDesktop( getServiceFactory()->createInstance( SERVICENAME_DESKTOP ), UNO_QUERY );
+
+ if ( xDesktop.is() )
+ {
+ USHORT nTaskId = START_ITEMID_WINDOWLIST;
+ Reference< XIndexAccess > xList( xDesktop->getFrames(), UNO_QUERY );
+ sal_Int32 nCount = xList->getCount();
+ for ( sal_Int32 i=0; i<nCount; ++i )
+ {
+ Reference< XFrame > xFrame;
+ xList->getByIndex(i) >>= xFrame;
+
+ if ( xFrame.is() && nTaskId == nCurItemId )
+ {
+ Window* pWin = VCLUnoHelper::GetWindow( xFrame->getContainerWindow() );
+ pWin->GrabFocus();
+ pWin->ToTop( TOTOP_RESTOREWHENMIN );
+ break;
+ }
+
+ nTaskId++;
+ }
+ }
+ }
+ else
+ {
+ MenuItemHandler* pMenuItemHandler = GetMenuItemHandler( nCurItemId );
+ if ( pMenuItemHandler && pMenuItemHandler->xMenuItemDispatch.is() )
+ {
+ aTargetURL.Complete = pMenuItemHandler->aMenuItemURL;
+ m_xURLTransformer->parseStrict( aTargetURL );
+
+ if ( nCurItemId >= START_ITEMID_PICKLIST &&
+ nCurItemId < START_ITEMID_WINDOWLIST )
+ {
+ // picklist menu item selected
+ CreatePicklistArguments( aArgs, pMenuItemHandler );
+ }
+ else if ( m_bIsBookmarkMenu )
+ {
+ // bookmark menu item selected
+ aArgs.realloc( 1 );
+ aArgs[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Referer" ));
+ aArgs[0].Value <<= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SFX_REFERER_USER ));
+ }
+
+ xDispatch = pMenuItemHandler->xMenuItemDispatch;
+ }
+ }
+ }
+ }
+
+ if ( xDispatch.is() )
+ xDispatch->dispatch( aTargetURL, aArgs );
+
+ return 1;
+}
+
+
+IMPL_LINK( MenuManager, Highlight, Menu *, EMPTYARG )
+{
+ return 0;
+}
+
+// #110897#
+const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& MenuManager::getServiceFactory()
+{
+ // #110897#
+ return mxServiceFactory;
+}
+
+void MenuManager::AddMenu(PopupMenu* _pPopupMenu,const ::rtl::OUString& _sItemCommand,USHORT _nItemId,sal_Bool _bDelete,sal_Bool _bDeleteChildren)
+{
+ MenuManager* pSubMenuManager = new MenuManager( getServiceFactory(), m_xFrame, _pPopupMenu, _bDelete, _bDeleteChildren );
+
+ // store menu item command as we later have to know which menu is active (see Activate handler)
+ pSubMenuManager->m_aMenuItemCommand = _sItemCommand;
+
+ REFERENCE< XDISPATCH > aXDispatchRef;
+ MenuItemHandler* pMenuItemHandler = new MenuItemHandler(
+ _nItemId,
+ pSubMenuManager,
+ aXDispatchRef );
+ m_aMenuItemHandlerVector.push_back( pMenuItemHandler );
+}
+
+USHORT MenuManager::FillItemCommand(::rtl::OUString& _rItemCommand,Menu* _pMenu,USHORT _nIndex) const
+{
+ USHORT nItemId = _pMenu->GetItemId( _nIndex );
+
+ _rItemCommand = _pMenu->GetItemCommand( nItemId );
+ if ( !_rItemCommand.getLength() )
+ {
+ const static ::rtl::OUString aSlotString( RTL_CONSTASCII_USTRINGPARAM( "slot:" ));
+ _rItemCommand = aSlotString;
+ _rItemCommand += ::rtl::OUString::valueOf( (sal_Int32)nItemId );
+ _pMenu->SetItemCommand( nItemId, _rItemCommand );
+ }
+ return nItemId;
+}
+void MenuManager::FillMenuImages(Reference< XFrame >& _xFrame,Menu* _pMenu,sal_Bool bIsHiContrast,sal_Bool bShowMenuImages)
+{
+ AddonsOptions aAddonOptions;
+
+ for ( USHORT nPos = 0; nPos < _pMenu->GetItemCount(); nPos++ )
+ {
+ USHORT nId = _pMenu->GetItemId( nPos );
+ if ( _pMenu->GetItemType( nPos ) != MENUITEM_SEPARATOR )
+ {
+ bool bTmpShowMenuImages( bShowMenuImages );
+ MenuItemBits nBits = _pMenu->GetItemBits( nId );
+ // overwrite the default?
+ if ( nBits )
+ bTmpShowMenuImages = ( ( nBits & MIB_ICON ) == MIB_ICON );
+
+ if ( bTmpShowMenuImages )
+ {
+ sal_Bool bImageSet = sal_False;
+ ::rtl::OUString aImageId;
+
+ ::framework::MenuConfiguration::Attributes* pMenuAttributes =
+ (::framework::MenuConfiguration::Attributes*)_pMenu->GetUserValue( nId );
+
+ if ( pMenuAttributes )
+ aImageId = pMenuAttributes->aImageId; // Retrieve image id from menu attributes
+
+ if ( aImageId.getLength() > 0 )
+ {
+ Image aImage = GetImageFromURL( _xFrame, aImageId, FALSE, bIsHiContrast );
+ if ( !!aImage )
+ {
+ bImageSet = sal_True;
+ _pMenu->SetItemImage( nId, aImage );
+ }
+ }
+
+ if ( !bImageSet )
+ {
+ rtl::OUString aMenuItemCommand = _pMenu->GetItemCommand( nId );
+ Image aImage = GetImageFromURL( _xFrame, aMenuItemCommand, FALSE, bIsHiContrast );
+ if ( !aImage )
+ aImage = aAddonOptions.GetImageFromURL( aMenuItemCommand, FALSE, bIsHiContrast );
+
+ _pMenu->SetItemImage( nId, aImage );
+ }
+ }
+ else
+ _pMenu->SetItemImage( nId, Image() );
+ }
+ }
+}
+}
diff --git a/framework/source/classes/propertysethelper.cxx b/framework/source/classes/propertysethelper.cxx
new file mode 100644
index 000000000000..2e41106a9ceb
--- /dev/null
+++ b/framework/source/classes/propertysethelper.cxx
@@ -0,0 +1,450 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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"
+
+//_________________________________________________________________________________________________________________
+// my own includes
+
+#include <classes/propertysethelper.hxx>
+#include <threadhelp/transactionguard.hxx>
+#include <threadhelp/readguard.hxx>
+#include <threadhelp/writeguard.hxx>
+
+//_________________________________________________________________________________________________________________
+// interface includes
+
+//_________________________________________________________________________________________________________________
+// other includes
+
+//_________________________________________________________________________________________________________________
+// namespace
+
+namespace framework{
+
+//_________________________________________________________________________________________________________________
+// non exported definitions
+
+//-----------------------------------------------------------------------------
+PropertySetHelper::PropertySetHelper(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR ,
+ LockHelper* pExternalLock ,
+ TransactionManager* pExternalTransactionManager ,
+ sal_Bool bReleaseLockOnCall )
+ : m_xSMGR (xSMGR )
+ , m_lSimpleChangeListener(pExternalLock->getShareableOslMutex())
+ , m_lVetoChangeListener (pExternalLock->getShareableOslMutex())
+ , m_bReleaseLockOnCall (bReleaseLockOnCall )
+ , m_rLock (*pExternalLock )
+ , m_rTransactionManager (*pExternalTransactionManager )
+{
+}
+
+//-----------------------------------------------------------------------------
+PropertySetHelper::~PropertySetHelper()
+{
+}
+
+//-----------------------------------------------------------------------------
+void PropertySetHelper::impl_setPropertyChangeBroadcaster(const css::uno::Reference< css::uno::XInterface >& xBroadcaster)
+{
+ TransactionGuard aTransaction(m_rTransactionManager, E_SOFTEXCEPTIONS);
+
+ // SAFE ->
+ WriteGuard aWriteLock(m_rLock);
+ m_xBroadcaster = xBroadcaster;
+ aWriteLock.unlock();
+ // <- SAFE
+}
+
+//-----------------------------------------------------------------------------
+void SAL_CALL PropertySetHelper::impl_addPropertyInfo(const css::beans::Property& aProperty)
+ throw(css::beans::PropertyExistException,
+ css::uno::Exception )
+{
+ TransactionGuard aTransaction(m_rTransactionManager, E_SOFTEXCEPTIONS);
+
+ // SAFE ->
+ WriteGuard aWriteLock(m_rLock);
+
+ PropertySetHelper::TPropInfoHash::const_iterator pIt = m_lProps.find(aProperty.Name);
+ if (pIt != m_lProps.end())
+ throw css::beans::PropertyExistException();
+
+ m_lProps[aProperty.Name] = aProperty;
+ // <- SAFE
+}
+
+//-----------------------------------------------------------------------------
+void SAL_CALL PropertySetHelper::impl_removePropertyInfo(const ::rtl::OUString& sProperty)
+ throw(css::beans::UnknownPropertyException,
+ css::uno::Exception )
+{
+ TransactionGuard aTransaction(m_rTransactionManager, E_SOFTEXCEPTIONS);
+
+ // SAFE ->
+ WriteGuard aWriteLock(m_rLock);
+
+ PropertySetHelper::TPropInfoHash::iterator pIt = m_lProps.find(sProperty);
+ if (pIt == m_lProps.end())
+ throw css::beans::UnknownPropertyException();
+
+ m_lProps.erase(pIt);
+ // <- SAFE
+}
+
+//-----------------------------------------------------------------------------
+void SAL_CALL PropertySetHelper::impl_enablePropertySet()
+{
+}
+
+//-----------------------------------------------------------------------------
+void SAL_CALL PropertySetHelper::impl_disablePropertySet()
+{
+ TransactionGuard aTransaction(m_rTransactionManager, E_SOFTEXCEPTIONS);
+
+ // SAFE ->
+ WriteGuard aWriteLock(m_rLock);
+
+ css::uno::Reference< css::uno::XInterface > xThis(static_cast< css::beans::XPropertySet* >(this), css::uno::UNO_QUERY);
+ css::lang::EventObject aEvent(xThis);
+
+ m_lSimpleChangeListener.disposeAndClear(aEvent);
+ m_lVetoChangeListener.disposeAndClear(aEvent);
+ m_lProps.free();
+
+ aWriteLock.unlock();
+ // <- SAFE
+}
+
+//-----------------------------------------------------------------------------
+sal_Bool PropertySetHelper::impl_existsVeto(const css::beans::PropertyChangeEvent& aEvent)
+{
+ /* Dont use the lock here!
+ The used helper is threadsafe and it lives for the whole lifetime of
+ our own object.
+ */
+ ::cppu::OInterfaceContainerHelper* pVetoListener = m_lVetoChangeListener.getContainer(aEvent.PropertyName);
+ if (! pVetoListener)
+ return sal_False;
+
+ ::cppu::OInterfaceIteratorHelper pListener(*pVetoListener);
+ while (pListener.hasMoreElements())
+ {
+ try
+ {
+ css::uno::Reference< css::beans::XVetoableChangeListener > xListener(
+ ((css::beans::XVetoableChangeListener*)pListener.next()),
+ css::uno::UNO_QUERY_THROW);
+ xListener->vetoableChange(aEvent);
+ }
+ catch(const css::uno::RuntimeException&)
+ { pListener.remove(); }
+ catch(const css::beans::PropertyVetoException&)
+ { return sal_True; }
+ }
+
+ return sal_False;
+}
+
+//-----------------------------------------------------------------------------
+void PropertySetHelper::impl_notifyChangeListener(const css::beans::PropertyChangeEvent& aEvent)
+{
+ /* Dont use the lock here!
+ The used helper is threadsafe and it lives for the whole lifetime of
+ our own object.
+ */
+ ::cppu::OInterfaceContainerHelper* pSimpleListener = m_lSimpleChangeListener.getContainer(aEvent.PropertyName);
+ if (! pSimpleListener)
+ return;
+
+ ::cppu::OInterfaceIteratorHelper pListener(*pSimpleListener);
+ while (pListener.hasMoreElements())
+ {
+ try
+ {
+ css::uno::Reference< css::beans::XPropertyChangeListener > xListener(
+ ((css::beans::XVetoableChangeListener*)pListener.next()),
+ css::uno::UNO_QUERY_THROW);
+ xListener->propertyChange(aEvent);
+ }
+ catch(const css::uno::RuntimeException&)
+ { pListener.remove(); }
+ }
+}
+
+//-----------------------------------------------------------------------------
+css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL PropertySetHelper::getPropertySetInfo()
+ throw(css::uno::RuntimeException)
+{
+ TransactionGuard aTransaction(m_rTransactionManager, E_HARDEXCEPTIONS);
+
+ css::uno::Reference< css::beans::XPropertySetInfo > xInfo(static_cast< css::beans::XPropertySetInfo* >(this), css::uno::UNO_QUERY_THROW);
+ return xInfo;
+}
+
+//-----------------------------------------------------------------------------
+void SAL_CALL PropertySetHelper::setPropertyValue(const ::rtl::OUString& sProperty,
+ const css::uno::Any& aValue )
+ throw(css::beans::UnknownPropertyException,
+ css::beans::PropertyVetoException ,
+ css::lang::IllegalArgumentException ,
+ css::lang::WrappedTargetException ,
+ css::uno::RuntimeException )
+{
+ // TODO look for e.g. readonly props and reject setProp() call!
+
+ TransactionGuard aTransaction(m_rTransactionManager, E_HARDEXCEPTIONS);
+
+ // SAFE ->
+ WriteGuard aWriteLock(m_rLock);
+
+ PropertySetHelper::TPropInfoHash::const_iterator pIt = m_lProps.find(sProperty);
+ if (pIt == m_lProps.end())
+ throw css::beans::UnknownPropertyException();
+
+ css::beans::Property aPropInfo = pIt->second;
+
+ sal_Bool bLocked = sal_True;
+ if (m_bReleaseLockOnCall)
+ {
+ aWriteLock.unlock();
+ bLocked = sal_False;
+ // <- SAFE
+ }
+
+ css::uno::Any aCurrentValue = impl_getPropertyValue(aPropInfo.Name, aPropInfo.Handle);
+
+ if (! bLocked)
+ {
+ // SAFE ->
+ aWriteLock.lock();
+ bLocked = sal_True;
+ }
+
+ sal_Bool bWillBeChanged = (aCurrentValue != aValue);
+ if (! bWillBeChanged)
+ return;
+
+ css::beans::PropertyChangeEvent aEvent;
+ aEvent.PropertyName = aPropInfo.Name;
+ aEvent.Further = sal_False;
+ aEvent.PropertyHandle = aPropInfo.Handle;
+ aEvent.OldValue = aCurrentValue;
+ aEvent.NewValue = aValue;
+ aEvent.Source = css::uno::Reference< css::uno::XInterface >(m_xBroadcaster.get(), css::uno::UNO_QUERY);
+
+ if (m_bReleaseLockOnCall)
+ {
+ aWriteLock.unlock();
+ bLocked = sal_False;
+ // <- SAFE
+ }
+
+ if (impl_existsVeto(aEvent))
+ throw css::beans::PropertyVetoException();
+
+ impl_setPropertyValue(aPropInfo.Name, aPropInfo.Handle, aValue);
+
+ impl_notifyChangeListener(aEvent);
+}
+
+//-----------------------------------------------------------------------------
+css::uno::Any SAL_CALL PropertySetHelper::getPropertyValue(const ::rtl::OUString& sProperty)
+ throw(css::beans::UnknownPropertyException,
+ css::lang::WrappedTargetException ,
+ css::uno::RuntimeException )
+{
+ TransactionGuard aTransaction(m_rTransactionManager, E_HARDEXCEPTIONS);
+
+ // SAFE ->
+ ReadGuard aReadLock(m_rLock);
+
+ PropertySetHelper::TPropInfoHash::const_iterator pIt = m_lProps.find(sProperty);
+ if (pIt == m_lProps.end())
+ throw css::beans::UnknownPropertyException();
+
+ css::beans::Property aPropInfo = pIt->second;
+
+ sal_Bool bLocked = sal_True;
+ if (m_bReleaseLockOnCall)
+ {
+ aReadLock.unlock();
+ bLocked = sal_False;
+ // <- SAFE
+ }
+
+ return impl_getPropertyValue(aPropInfo.Name, aPropInfo.Handle);
+}
+
+//-----------------------------------------------------------------------------
+void SAL_CALL PropertySetHelper::addPropertyChangeListener(const ::rtl::OUString& sProperty,
+ const css::uno::Reference< css::beans::XPropertyChangeListener >& xListener)
+ throw(css::beans::UnknownPropertyException,
+ css::lang::WrappedTargetException ,
+ css::uno::RuntimeException )
+{
+ TransactionGuard aTransaction(m_rTransactionManager, E_HARDEXCEPTIONS);
+
+ // SAFE ->
+ ReadGuard aReadLock(m_rLock);
+
+ PropertySetHelper::TPropInfoHash::const_iterator pIt = m_lProps.find(sProperty);
+ if (pIt == m_lProps.end())
+ throw css::beans::UnknownPropertyException();
+
+ aReadLock.unlock();
+ // <- SAFE
+
+ m_lSimpleChangeListener.addInterface(sProperty, xListener);
+}
+
+//-----------------------------------------------------------------------------
+void SAL_CALL PropertySetHelper::removePropertyChangeListener(const ::rtl::OUString& sProperty,
+ const css::uno::Reference< css::beans::XPropertyChangeListener >& xListener)
+ throw(css::beans::UnknownPropertyException,
+ css::lang::WrappedTargetException ,
+ css::uno::RuntimeException )
+{
+ TransactionGuard aTransaction(m_rTransactionManager, E_SOFTEXCEPTIONS);
+
+ // SAFE ->
+ ReadGuard aReadLock(m_rLock);
+
+ PropertySetHelper::TPropInfoHash::const_iterator pIt = m_lProps.find(sProperty);
+ if (pIt == m_lProps.end())
+ throw css::beans::UnknownPropertyException();
+
+ aReadLock.unlock();
+ // <- SAFE
+
+ m_lSimpleChangeListener.removeInterface(sProperty, xListener);
+}
+
+//-----------------------------------------------------------------------------
+void SAL_CALL PropertySetHelper::addVetoableChangeListener(const ::rtl::OUString& sProperty,
+ const css::uno::Reference< css::beans::XVetoableChangeListener >& xListener)
+ throw(css::beans::UnknownPropertyException,
+ css::lang::WrappedTargetException ,
+ css::uno::RuntimeException )
+{
+ TransactionGuard aTransaction(m_rTransactionManager, E_HARDEXCEPTIONS);
+
+ // SAFE ->
+ ReadGuard aReadLock(m_rLock);
+
+ PropertySetHelper::TPropInfoHash::const_iterator pIt = m_lProps.find(sProperty);
+ if (pIt == m_lProps.end())
+ throw css::beans::UnknownPropertyException();
+
+ aReadLock.unlock();
+ // <- SAFE
+
+ m_lVetoChangeListener.addInterface(sProperty, xListener);
+}
+
+//-----------------------------------------------------------------------------
+void SAL_CALL PropertySetHelper::removeVetoableChangeListener(const ::rtl::OUString& sProperty,
+ const css::uno::Reference< css::beans::XVetoableChangeListener >& xListener)
+ throw(css::beans::UnknownPropertyException,
+ css::lang::WrappedTargetException ,
+ css::uno::RuntimeException )
+{
+ TransactionGuard aTransaction(m_rTransactionManager, E_SOFTEXCEPTIONS);
+
+ // SAFE ->
+ ReadGuard aReadLock(m_rLock);
+
+ PropertySetHelper::TPropInfoHash::const_iterator pIt = m_lProps.find(sProperty);
+ if (pIt == m_lProps.end())
+ throw css::beans::UnknownPropertyException();
+
+ aReadLock.unlock();
+ // <- SAFE
+
+ m_lVetoChangeListener.removeInterface(sProperty, xListener);
+}
+
+//-----------------------------------------------------------------------------
+css::uno::Sequence< css::beans::Property > SAL_CALL PropertySetHelper::getProperties()
+ throw(css::uno::RuntimeException)
+{
+ TransactionGuard aTransaction(m_rTransactionManager, E_HARDEXCEPTIONS);
+
+ // SAFE ->
+ ReadGuard aReadLock(m_rLock);
+
+ sal_Int32 c = (sal_Int32)m_lProps.size();
+ css::uno::Sequence< css::beans::Property > lProps(c);
+ PropertySetHelper::TPropInfoHash::const_iterator pIt ;
+
+ for ( pIt = m_lProps.begin();
+ pIt != m_lProps.end() ;
+ ++pIt )
+ {
+ lProps[--c] = pIt->second;
+ }
+
+ return lProps;
+ // <- SAFE
+}
+
+//-----------------------------------------------------------------------------
+css::beans::Property SAL_CALL PropertySetHelper::getPropertyByName(const ::rtl::OUString& sName)
+ throw(css::beans::UnknownPropertyException,
+ css::uno::RuntimeException )
+{
+ TransactionGuard aTransaction(m_rTransactionManager, E_HARDEXCEPTIONS);
+
+ // SAFE ->
+ ReadGuard aReadLock(m_rLock);
+
+ PropertySetHelper::TPropInfoHash::const_iterator pIt = m_lProps.find(sName);
+ if (pIt == m_lProps.end())
+ throw css::beans::UnknownPropertyException();
+
+ return pIt->second;
+ // <- SAFE
+}
+
+//-----------------------------------------------------------------------------
+sal_Bool SAL_CALL PropertySetHelper::hasPropertyByName(const ::rtl::OUString& sName)
+ throw(css::uno::RuntimeException)
+{
+ TransactionGuard aTransaction(m_rTransactionManager, E_HARDEXCEPTIONS);
+
+ // SAFE ->
+ ReadGuard aReadLock(m_rLock);
+
+ PropertySetHelper::TPropInfoHash::iterator pIt = m_lProps.find(sName);
+ sal_Bool bExist = (pIt != m_lProps.end());
+
+ return bExist;
+ // <- SAFE
+}
+
+} // namespace framework
diff --git a/framework/source/classes/protocolhandlercache.cxx b/framework/source/classes/protocolhandlercache.cxx
new file mode 100644
index 000000000000..266100ce4f43
--- /dev/null
+++ b/framework/source/classes/protocolhandlercache.cxx
@@ -0,0 +1,361 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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"
+
+/*TODO
+ - change "singleton" behaviour by using new helper ::comhelper::SingletonRef
+ - rename method exist() to existHandlerForURL() or similar one
+ - may its a good idea to replace struct ProtocolHandler by css::beans::NamedValue type?!
+*/
+
+//_________________________________________________________________________________________________________________
+// my own includes
+//_________________________________________________________________________________________________________________
+
+#include <classes/protocolhandlercache.hxx>
+#include <classes/converter.hxx>
+#include <threadhelp/readguard.hxx>
+#include <threadhelp/writeguard.hxx>
+#include <threadhelp/lockhelper.hxx>
+
+//_________________________________________________________________________________________________________________
+// interface includes
+//_________________________________________________________________________________________________________________
+
+//_________________________________________________________________________________________________________________
+// other includes
+//_________________________________________________________________________________________________________________
+#include <tools/wldcrd.hxx>
+#include <unotools/configpathes.hxx>
+#include <rtl/ustrbuf.hxx>
+
+//_________________________________________________________________________________________________________________
+// namespace
+//_________________________________________________________________________________________________________________
+
+namespace framework{
+
+//_________________________________________________________________________________________________________________
+// non exported const
+//_________________________________________________________________________________________________________________
+
+//_________________________________________________________________________________________________________________
+// non exported definitions
+//_________________________________________________________________________________________________________________
+
+/**
+ @short overloaded index operator of hash map to support pattern key search
+ @descr All keys inside this hash map are URL pattern which points to an uno
+ implementation name of a protocol handler service which is registered
+ for this pattern. This operator makes it easy to find such registered
+ handler by using a full qualified URL and compare it with all pattern
+ keys.
+
+ @param sURL
+ the full qualified URL which should match to a registered pattern
+
+ @return An iterator which points to the found item inside the hash or PatternHash::end()
+ if no pattern match this given <var>sURL</var>.
+
+ @modified 30.04.2002 09:52, as96863
+ */
+PatternHash::iterator PatternHash::findPatternKey( const ::rtl::OUString& sURL )
+{
+ PatternHash::iterator pItem = this->begin();
+ while( pItem!=this->end() )
+ {
+ WildCard aPattern(pItem->first);
+ if (aPattern.Matches(sURL))
+ break;
+ ++pItem;
+ }
+ return pItem;
+}
+
+//_________________________________________________________________________________________________________________
+
+/**
+ @short initialize static member of class HandlerCache
+ @descr We use a singleton pattern to implement this handler cache.
+ That means it use two static member list to hold all neccessary informations
+ and a ref count mechanism to create/destroy it on demand.
+
+ @modified 30.04.2002 11:13, as96863
+ */
+HandlerHash* HandlerCache::m_pHandler = NULL;
+PatternHash* HandlerCache::m_pPattern = NULL;
+sal_Int32 HandlerCache::m_nRefCount = 0 ;
+HandlerCFGAccess* HandlerCache::m_pConfig = NULL;
+
+//_________________________________________________________________________________________________________________
+
+/**
+ @short ctor of the cache of all registered protoco handler
+ @descr It tries to open the right configuration package automaticly
+ and fill the internal structures. After that the cache can be
+ used for read access on this data and perform some search
+ operations on it.
+
+ @modified 30.04.2002 10:02, as96863
+ */
+HandlerCache::HandlerCache()
+{
+ /* SAFE */{
+ WriteGuard aGlobalLock( LockHelper::getGlobalLock() );
+
+ if (m_nRefCount==0)
+ {
+ m_pHandler = new HandlerHash();
+ m_pPattern = new PatternHash();
+ m_pConfig = new HandlerCFGAccess(PACKAGENAME_PROTOCOLHANDLER);
+ m_pConfig->read(&m_pHandler,&m_pPattern);
+ m_pConfig->setCache(this);
+ }
+
+ ++m_nRefCount;
+ /* SAFE */}
+}
+
+//_________________________________________________________________________________________________________________
+
+/**
+ @short dtor of the cache
+ @descr It frees all used memory. In further implementations (may if we support write access too)
+ it's a good place to flush changes back to the configuration - but not needed yet.
+
+ @modified 30.04.2002 09:54, as96863
+ */
+HandlerCache::~HandlerCache()
+{
+ /* SAFE */{
+ WriteGuard aGlobalLock( LockHelper::getGlobalLock() );
+
+ if( m_nRefCount==1)
+ {
+ m_pConfig->setCache(NULL);
+ m_pHandler->free();
+ m_pPattern->free();
+
+ delete m_pConfig;
+ delete m_pHandler;
+ delete m_pPattern;
+ m_pConfig = NULL;
+ m_pHandler= NULL;
+ m_pPattern= NULL;
+ }
+
+ --m_nRefCount;
+ /* SAFE */}
+}
+
+//_________________________________________________________________________________________________________________
+
+/**
+ @short dtor of the cache
+ @descr It frees all used memory. In further implementations (may if we support write access too)
+ it's a good place to flush changes back to the configuration - but not needed yet.
+
+ @modified 30.04.2002 09:54, as96863
+ */
+sal_Bool HandlerCache::search( const ::rtl::OUString& sURL, ProtocolHandler* pReturn ) const
+{
+ sal_Bool bFound = sal_False;
+ /* SAFE */{
+ ReadGuard aReadLock( LockHelper::getGlobalLock() );
+ PatternHash::const_iterator pItem = m_pPattern->findPatternKey(sURL);
+ if (pItem!=m_pPattern->end())
+ {
+ *pReturn = (*m_pHandler)[pItem->second];
+ bFound = sal_True;
+ }
+ /* SAFE */}
+ return bFound;
+}
+
+//_________________________________________________________________________________________________________________
+
+/**
+ @short search for a registered handler by using an URL struct
+ @descr We combine neccessary parts of this struct to a valid URL string
+ and call our other search method ...
+ It's a helper for outside code.
+
+ @modified 30.04.2002 09:54, as96863
+ */
+sal_Bool HandlerCache::search( const css::util::URL& aURL, ProtocolHandler* pReturn ) const
+{
+ return search( aURL.Complete, pReturn );
+}
+
+//_________________________________________________________________________________________________________________
+
+sal_Bool HandlerCache::exists( const ::rtl::OUString& sURL ) const
+{
+ sal_Bool bFound = sal_False;
+ /* SAFE */{
+ ReadGuard aReadLock( LockHelper::getGlobalLock() );
+ PatternHash::const_iterator pItem = m_pPattern->findPatternKey(sURL);
+ bFound = pItem!=m_pPattern->end();
+ /* SAFE */}
+ return bFound;
+}
+
+//_________________________________________________________________________________________________________________
+void HandlerCache::takeOver(HandlerHash* pHandler, PatternHash* pPattern)
+{
+ // SAFE ->
+ WriteGuard aWriteLock( LockHelper::getGlobalLock() );
+
+ HandlerHash* pOldHandler = m_pHandler;
+ PatternHash* pOldPattern = m_pPattern;
+
+ m_pHandler = pHandler;
+ m_pPattern = pPattern;
+
+ pOldHandler->free();
+ pOldPattern->free();
+ delete pOldHandler;
+ delete pOldPattern;
+
+ aWriteLock.unlock();
+ // <- SAFE
+}
+
+//_________________________________________________________________________________________________________________
+
+/**
+ @short dtor of the config access class
+ @descr It opens the configuration package automaticly by using base class mechanism.
+ After that "read()" method of this class should be called to use it.
+
+ @param sPackage
+ specifies the package name of the configuration data which should be used
+
+ @modified 30.04.2002 10:06, as96863
+ */
+HandlerCFGAccess::HandlerCFGAccess( const ::rtl::OUString& sPackage )
+ : ConfigItem( sPackage )
+{
+ css::uno::Sequence< ::rtl::OUString > lListenPathes(1);
+ lListenPathes[0] = SETNAME_HANDLER;
+ EnableNotification(lListenPathes);
+}
+
+//_________________________________________________________________________________________________________________
+
+/**
+ @short use base class mechanism to fill given structures
+ @descr User use us as a wrapper between configuration api and his internal structures.
+ He give us some pointer to his member and we fill it.
+
+ @param pHandler
+ pointer to a list of protocol handler infos
+
+ @param pPattern
+ reverse map of handler pattern to her uno names
+
+ @modified 30.04.2002 09:54, as96863
+ */
+void HandlerCFGAccess::read( HandlerHash** ppHandler ,
+ PatternHash** ppPattern )
+{
+ // list of all uno implementation names without encoding
+ css::uno::Sequence< ::rtl::OUString > lNames = GetNodeNames( SETNAME_HANDLER, ::utl::CONFIG_NAME_LOCAL_PATH );
+ sal_Int32 nSourceCount = lNames.getLength();
+ sal_Int32 nTargetCount = nSourceCount;
+ // list of all full qualified path names of configuration entries
+ css::uno::Sequence< ::rtl::OUString > lFullNames ( nTargetCount );
+
+ // expand names to full path names
+ sal_Int32 nSource=0;
+ sal_Int32 nTarget=0;
+ for( nSource=0; nSource<nSourceCount; ++nSource )
+ {
+ ::rtl::OUStringBuffer sPath( SETNAME_HANDLER );
+ sPath.append(CFG_PATH_SEPERATOR);
+ sPath.append(lNames[nSource]);
+ sPath.append(CFG_PATH_SEPERATOR);
+ sPath.append(PROPERTY_PROTOCOLS);
+
+ lFullNames[nTarget] = sPath.makeStringAndClear();
+ ++nTarget;
+ }
+
+ // get values at all
+ css::uno::Sequence< css::uno::Any > lValues = GetProperties( lFullNames );
+ LOG_ASSERT2( lFullNames.getLength()!=lValues.getLength(), "HandlerCFGAccess::read()", "Miss some configuration values of handler set!" )
+
+ // fill structures
+ nSource = 0;
+ for( nTarget=0; nTarget<nTargetCount; ++nTarget )
+ {
+ // create it new for every loop to guarantee a real empty object!
+ ProtocolHandler aHandler;
+ aHandler.m_sUNOName = ::utl::extractFirstFromConfigurationPath(lNames[nSource]);
+
+ // unpack all values of this handler
+ css::uno::Sequence< ::rtl::OUString > lTemp;
+ lValues[nTarget] >>= lTemp;
+ aHandler.m_lProtocols = Converter::convert_seqOUString2OUStringList(lTemp);
+
+ // register his pattern into the performance search hash
+ for (OUStringList::iterator pItem =aHandler.m_lProtocols.begin();
+ pItem!=aHandler.m_lProtocols.end() ;
+ ++pItem )
+ {
+ (**ppPattern)[*pItem] = lNames[nSource];
+ }
+
+ // �nsert the handler info into the normal handler cache
+ (**ppHandler)[lNames[nSource]] = aHandler;
+ ++nSource;
+ }
+}
+
+//_________________________________________________________________________________________________________________
+void HandlerCFGAccess::Notify(const css::uno::Sequence< rtl::OUString >& /*lPropertyNames*/)
+{
+ HandlerHash* pHandler = new HandlerHash;
+ PatternHash* pPattern = new PatternHash;
+
+ read(&pHandler, &pPattern);
+ if (m_pCache)
+ m_pCache->takeOver(pHandler, pPattern);
+ else
+ {
+ delete pHandler;
+ delete pPattern;
+ }
+}
+
+void HandlerCFGAccess::Commit()
+{
+}
+
+} // namespace framework
diff --git a/framework/source/classes/resource.src b/framework/source/classes/resource.src
new file mode 100644
index 000000000000..d95e0d7213f0
--- /dev/null
+++ b/framework/source/classes/resource.src
@@ -0,0 +1,349 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#include "helpid.hrc"
+
+#ifndef __FRAMEWORK_CLASSES_RESOURCE_HRC_
+#include <classes/resource.hrc>
+#endif
+
+String STR_MENU_ADDONS
+{
+ Text [ en-US ] = "Add-Ons" ;
+};
+
+String STR_MENU_ADDONHELP
+{
+ Text [ en-US ] = "Add-~On Help" ;
+};
+
+String STR_MENU_HEADFOOTALL
+{
+ Text [ en-US ] = "All" ;
+};
+
+String STR_UPDATEDOC
+{
+ Text [ en-US ] = "~Update" ;
+};
+
+String STR_CLOSEDOC_ANDRETURN
+{
+ /* ### ACHTUNG: Neuer Text in Resource? S~chlieen & zur ck zu : S~chlieen & zurck zu */
+ /* ### ACHTUNG: Neuer Text in Resource? S~chlie en & zur ck zu : S~chlieen & zurck zu */
+ Text [ en-US ] = "~Close & Return to " ;
+};
+
+Menu POPUPMENU_TOOLBAR_QUICKCUSTOMIZATION
+{
+ ItemList =
+ {
+ MenuItem
+ {
+ Identifier = MENUITEM_TOOLBAR_VISIBLEBUTTON;
+ SubMenu = Menu
+ {
+ };
+ Text[ en-US ] = "Visible ~Buttons";
+ };
+ MenuItem
+ {
+ Identifier = MENUITEM_TOOLBAR_CUSTOMIZETOOLBAR;
+ Command = ".uno:ConfigureToolboxVisible" ;
+ Text[ en-US ] = "~Customize Toolbar...";
+ };
+ MenuItem
+ {
+ Separator = TRUE ;
+ };
+ MenuItem
+ {
+ Identifier = MENUITEM_TOOLBAR_DOCKTOOLBAR;
+ Text[ en-US ] = "~Dock Toolbar" ;
+ };
+ MenuItem
+ {
+ Identifier = MENUITEM_TOOLBAR_DOCKALLTOOLBAR;
+ Text[ en-US ] = "Dock ~All Toolbars" ;
+ };
+ MenuItem
+ {
+ Separator = TRUE ;
+ };
+ MenuItem
+ {
+ Identifier = MENUITEM_TOOLBAR_LOCKTOOLBARPOSITION;
+ Text[ en-US ] = "~Lock Toolbar Position" ;
+ };
+ MenuItem
+ {
+ Identifier = MENUITEM_TOOLBAR_CLOSE;
+ Text[ en-US ] = "Close ~Toolbar" ;
+ };
+ };
+};
+
+String STR_SAVECOPYDOC
+{
+ Text [ en-US ] = "Save Copy ~as..." ;
+};
+
+String STR_NODOCUMENT
+{
+ Text [ en-US ] = "No Documents";
+};
+
+String STR_TOOLBAR_TITLE_ADDON
+{
+ Text [ en-US ] = "Add-On %num%";
+};
+
+String STR_STATUSBAR_LOGOTEXT
+{
+ Text [ en-US ] = "A %PRODUCTNAME product by Oracle";
+};
+
+// ***********************************************************************
+// License Dialog
+// ***********************************************************************
+#define LICENSE_DIALOG_WIDTH 260
+//#define LICENSE_DIALOG_HEIGTH 185
+//#define LICENSE_DIALOG_HEIGTH 190
+#define LICENSE_RIGHT_BORDER 7
+#define LICENSE_BOTTOM_BORDER 0
+#define LICENSE_ROW_1 (7)
+#define LICENSE_COL_1 (7)
+
+#define OFFSET 2
+#define COL2_WIDTH 10
+#define OFFSET_IMG 10
+#define FT_HEIGHT 8
+#define PB_HEIGHT 14
+#define PD_WIDTH 40
+
+#define LICENSE_HEIGHT 102
+#define LICENSE_ROW_2 (LICENSE_ROW_1 + OFFSET + LICENSE_HEIGHT)
+#define LICENSE_ROW_3 (LICENSE_ROW_2 + OFFSET + FT_HEIGHT)
+#define LICENSE_ROW_4 (LICENSE_ROW_3 + OFFSET + 3*FT_HEIGHT )
+#define LICENSE_ROW_5 (LICENSE_ROW_4 + FT_HEIGHT+ OFFSET )
+#define LICENSE_ROW_6 (LICENSE_ROW_5 + 2*OFFSET )
+
+#define LICENSE_DIALOG_HEIGTH (LICENSE_ROW_6 + + PB_HEIGHT + 7)
+
+#define LICENSE_COL_2 (LICENSE_COL_1 + OFFSET_IMG)
+#define LICENSE_COL_3 (LICENSE_COL_2 + COL2_WIDTH +1)
+#define LICENSE_COL_4 (LICENSE_DIALOG_WIDTH - LICENSE_RIGHT_BORDER - PD_WIDTH)
+
+#define LICENSE_WIDTH (LICENSE_DIALOG_WIDTH - LICENSE_RIGHT_BORDER - LICENSE_ROW_1)
+#define COL3_WIDTH (LICENSE_COL_4 - LICENSE_COL_3)
+
+
+ModalDialog DLG_LICENSE
+{
+ HelpId = HID_LICENSEDIALOG;
+ Moveable = TRUE ;
+ Closeable = TRUE ;
+ OutputSize = TRUE ;
+ SVLook = TRUE ;
+ Hide = TRUE ;
+ Size = MAP_APPFONT ( LICENSE_DIALOG_WIDTH , LICENSE_DIALOG_HEIGTH ) ;
+ Text [ en-US ] = "License Agreement";
+
+ MultiLineEdit ML_LICENSE
+ {
+ PosSize = MAP_APPFONT ( LICENSE_COL_1 , LICENSE_ROW_1 , LICENSE_WIDTH , LICENSE_HEIGHT ) ;
+ Border = TRUE ;
+ VScroll = TRUE ;
+ ReadOnly = TRUE ;
+ };
+
+ FixedText FT_INFO1
+ {
+ WordBreak = TRUE ;
+ Pos = MAP_APPFONT ( LICENSE_COL_1 , LICENSE_ROW_2 ) ;
+ Size = MAP_APPFONT ( LICENSE_WIDTH , FT_HEIGHT ) ;
+ Text [ en-US ] = "Please follow these steps to proceed with the installation:" ;
+ };
+
+ FixedImage IMG_ARROW
+ {
+ Pos = MAP_APPFONT ( LICENSE_COL_1 , LICENSE_ROW_3 ) ;
+ Size = MAP_PIXEL ( 16 , 16 ) ;
+ Fixed = Image
+ {
+ ImageBitmap = Bitmap
+ {
+ File = "arrow.bmp" ;
+ };
+ MaskColor = Color { Red = 0xFFFF ; Green = 0x0000 ; Blue = 0xFFFF ; };
+ };
+ };
+
+ FixedText FT_INFO2_1
+ {
+ WordBreak = TRUE ;
+ Pos = MAP_APPFONT ( LICENSE_COL_2 , LICENSE_ROW_3 ) ;
+ Size = MAP_APPFONT ( COL2_WIDTH , FT_HEIGHT ) ;
+ Text [ en-US ] = "1." ;
+ };
+
+ FixedText FT_INFO2
+ {
+ WordBreak = TRUE ;
+ Pos = MAP_APPFONT ( LICENSE_COL_3 , LICENSE_ROW_3 ) ;
+ Size = MAP_APPFONT ( COL3_WIDTH, 3*FT_HEIGHT ) ;
+ Text [ en-US ] = "View the complete License Agreement. Please use the scroll bar or the '%PAGEDOWN' button in this dialog to view the entire license text." ;
+ };
+
+ PushButton PB_PAGEDOWN
+ {
+ TabStop = TRUE ;
+ Pos = MAP_APPFONT ( LICENSE_COL_4 , LICENSE_ROW_3 ) ;
+ Size = MAP_APPFONT ( PD_WIDTH , PB_HEIGHT ) ;
+ Text [ en-US ] = "Scroll Down" ;
+ };
+
+ FixedText FT_INFO3_1
+ {
+ WordBreak = TRUE ;
+ Pos = MAP_APPFONT ( LICENSE_COL_2 , LICENSE_ROW_4 ) ;
+ Size = MAP_APPFONT ( COL2_WIDTH, FT_HEIGHT ) ;
+ Text [ en-US ] = "2." ;
+ };
+
+ FixedText FT_INFO3
+ {
+ WordBreak = TRUE ;
+ Pos = MAP_APPFONT ( LICENSE_COL_3, LICENSE_ROW_4 ) ;
+ Size = MAP_APPFONT ( COL3_WIDTH, FT_HEIGHT ) ;
+ Text [ en-US ] = "Accept the License Agreement." ;
+ };
+
+ String LICENSE_ACCEPT
+ {
+ Text [ en-US ] = "~Accept" ;
+ };
+
+ String LICENSE_NOTACCEPT
+ {
+ Text [ en-US ] = "Decline" ;
+ };
+
+ FixedLine FL_DIVIDE
+ {
+ Pos = MAP_APPFONT ( LICENSE_COL_1, LICENSE_ROW_5 ) ;
+ Size = MAP_APPFONT ( LICENSE_WIDTH, 1 ) ;
+ };
+
+ PushButton PB_ACCEPT
+ {
+ TabStop = TRUE ;
+ Pos = MAP_APPFONT ( LICENSE_COL_4 - PD_WIDTH - OFFSET_IMG , LICENSE_ROW_6 ) ;
+ Size = MAP_APPFONT ( PD_WIDTH , PB_HEIGHT ) ;
+ };
+
+ PushButton PB_DECLINE
+ {
+ TabStop = TRUE ;
+ Pos = MAP_APPFONT ( LICENSE_COL_4 , LICENSE_ROW_6 ) ;
+ Size = MAP_APPFONT ( PD_WIDTH , PB_HEIGHT ) ;
+ };
+
+};
+
+Image RID_IMAGE_STATUSBAR_LOGO
+{
+ ImageBitmap = Bitmap { File = "logo.png" ; };
+ MaskColor = Color { Red = 0xFFFF; Green = 0x0000; Blue = 0xFFFF; };
+};
+
+String STR_FULL_DISC_RETRY_BUTTON
+{
+ Text [ en-US ] = "Retry" ;
+};
+
+String STR_FULL_DISC_MSG
+{
+ Text [ en-US ] = "%PRODUCTNAME could not save important internal information due to insufficient free disk space at the following location:\n%PATH\n\nYou will not be able to continue working with %PRODUCTNAME without allocating more free disk space at that location.\n\nPress the 'Retry' button after you have allocated more free disk space to retry saving the data.\n\n" ;
+};
+
+String STR_RESTORE_TOOLBARS
+{
+ Text [ en-US ] = "~Reset" ;
+};
+
+String STR_CORRUPT_UICFG_SHARE
+{
+ Text [ en-US ] = "An error occurred while loading the user interface configuration data. The application will be terminated now.\nPlease try to reinstall the application." ;
+};
+
+String STR_CORRUPT_UICFG_USER
+{
+ Text [ en-US ] = "An error occurred while loading the user interface configuration data. The application will be terminated now.\nPlease try to remove your user profile for the application." ;
+};
+
+String STR_CORRUPT_UICFG_GENERAL
+{
+ Text [ en-US ] = "An error occurred while loading the user interface configuration data. The application will be terminated now.\nPlease try to remove your user profile for the application first or try to reinstall the application." ;
+};
+
+String STR_UNTITLED_DOCUMENT
+{
+ Text [ en-US ] = "Untitled" ;
+};
+
+// for displaying 'Multiple Languages' in the language statusbar control
+String STR_LANGSTATUS_MULTIPLE_LANGUAGES
+{
+ Text [ en-US ] = "Multiple Languages" ;
+ Text [ x-comment ] = " ";
+};
+String STR_LANGSTATUS_NONE
+{
+ Text [ en-US ] = "None (Do not check spelling)" ;
+ Text [ x-comment ] = " ";
+};
+String STR_LANGSTATUS_MORE
+{
+ Text [ en-US ] = "More..." ;
+ Text [ x-comment ] = " ";
+};
+String STR_SET_LANGUAGE_FOR_SELECTION
+{
+ Text [ en-US ] = "Set Language for Selection" ;
+ Text [ x-comment ] = " ";
+};
+String STR_SET_LANGUAGE_FOR_PARAGRAPH
+{
+ Text [ en-US ] = "Set Language for Paragraph" ;
+ Text [ x-comment ] = " ";
+};
+String STR_SET_LANGUAGE_FOR_ALL_TEXT
+{
+ Text [ en-US ] = "Set Language for all Text" ;
+ Text [ x-comment ] = " ";
+};
diff --git a/framework/source/classes/rootactiontriggercontainer.cxx b/framework/source/classes/rootactiontriggercontainer.cxx
new file mode 100644
index 000000000000..c78d398b39a7
--- /dev/null
+++ b/framework/source/classes/rootactiontriggercontainer.cxx
@@ -0,0 +1,379 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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"
+
+#include <classes/rootactiontriggercontainer.hxx>
+#include <classes/actiontriggercontainer.hxx>
+#include <classes/actiontriggerpropertyset.hxx>
+#include <classes/actiontriggerseparatorpropertyset.hxx>
+#include <helper/actiontriggerhelper.hxx>
+#include <threadhelp/resetableguard.hxx>
+#include <osl/mutex.hxx>
+#include <vcl/svapp.hxx>
+#include <cppuhelper/typeprovider.hxx>
+
+
+using namespace cppu;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::container;
+using namespace com::sun::star::beans;
+
+
+namespace framework
+{
+
+static Sequence< sal_Int8 > impl_getStaticIdentifier()
+{
+ static sal_uInt8 pGUID[16] = { 0x17, 0x0F, 0xA2, 0xC9, 0xCA, 0x50, 0x4A, 0xD3, 0xA6, 0x3B, 0x39, 0x99, 0xC5, 0x96, 0x43, 0x27 };
+ static ::com::sun::star::uno::Sequence< sal_Int8 > seqID((sal_Int8*)pGUID,16) ;
+ return seqID ;
+}
+
+
+RootActionTriggerContainer::RootActionTriggerContainer( const Menu* pMenu, const ::rtl::OUString* pMenuIdentifier, const Reference< XMultiServiceFactory >& rServiceManager ) :
+ PropertySetContainer( rServiceManager )
+ , m_bContainerCreated( sal_False )
+ , m_bContainerChanged( sal_False )
+ , m_bInContainerCreation( sal_False )
+ , m_pMenu( pMenu )
+ , m_pMenuIdentifier( pMenuIdentifier )
+{
+}
+
+RootActionTriggerContainer::~RootActionTriggerContainer()
+{
+}
+
+Sequence< sal_Int8 > RootActionTriggerContainer::GetUnoTunnelId() const
+{
+ return impl_getStaticIdentifier();
+}
+
+const Menu* RootActionTriggerContainer::GetMenu()
+{
+ if ( !m_bContainerChanged )
+ return m_pMenu;
+ else
+ {
+ ResetableGuard aGuard( m_aLock );
+
+ Menu* pNewMenu = new PopupMenu;
+
+ ActionTriggerHelper::CreateMenuFromActionTriggerContainer( pNewMenu, this );
+ m_pMenu = pNewMenu;
+ m_bContainerChanged = sal_False;
+
+ return m_pMenu;
+ }
+}
+
+
+// XInterface
+Any SAL_CALL RootActionTriggerContainer::queryInterface( const Type& aType )
+throw ( RuntimeException )
+{
+ Any a = ::cppu::queryInterface(
+ aType ,
+ SAL_STATIC_CAST( XMultiServiceFactory* , this ),
+ SAL_STATIC_CAST( XServiceInfo* , this ),
+ SAL_STATIC_CAST( XUnoTunnel* , this ),
+ SAL_STATIC_CAST( XTypeProvider* , this ),
+ SAL_STATIC_CAST( XNamed* , this ));
+
+ if( a.hasValue() )
+ {
+ return a;
+ }
+
+ return PropertySetContainer::queryInterface( aType );
+}
+
+void SAL_CALL RootActionTriggerContainer::acquire() throw ()
+{
+ PropertySetContainer::acquire();
+}
+
+void SAL_CALL RootActionTriggerContainer::release() throw ()
+{
+ PropertySetContainer::release();
+}
+
+// XMultiServiceFactory
+Reference< XInterface > SAL_CALL RootActionTriggerContainer::createInstance( const ::rtl::OUString& aServiceSpecifier )
+throw ( Exception, RuntimeException )
+{
+ if ( aServiceSpecifier.equalsAscii( SERVICENAME_ACTIONTRIGGER ))
+ return (OWeakObject *)( new ActionTriggerPropertySet( m_xServiceManager ));
+ else if ( aServiceSpecifier.equalsAscii( SERVICENAME_ACTIONTRIGGERCONTAINER ))
+ return (OWeakObject *)( new ActionTriggerContainer( m_xServiceManager ));
+ else if ( aServiceSpecifier.equalsAscii( SERVICENAME_ACTIONTRIGGERSEPARATOR ))
+ return (OWeakObject *)( new ActionTriggerSeparatorPropertySet( m_xServiceManager ));
+ else
+ throw com::sun::star::uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Unknown service specifier!" )), (OWeakObject *)this );
+}
+
+Reference< XInterface > SAL_CALL RootActionTriggerContainer::createInstanceWithArguments( const ::rtl::OUString& ServiceSpecifier, const Sequence< Any >& /*Arguments*/ )
+throw ( Exception, RuntimeException )
+{
+ return createInstance( ServiceSpecifier );
+}
+
+Sequence< ::rtl::OUString > SAL_CALL RootActionTriggerContainer::getAvailableServiceNames()
+throw ( RuntimeException )
+{
+ Sequence< ::rtl::OUString > aSeq( 3 );
+
+ aSeq[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SERVICENAME_ACTIONTRIGGER ));
+ aSeq[1] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SERVICENAME_ACTIONTRIGGERCONTAINER ));
+ aSeq[2] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SERVICENAME_ACTIONTRIGGERSEPARATOR ));
+
+ return aSeq;
+}
+
+
+// XIndexContainer
+void SAL_CALL RootActionTriggerContainer::insertByIndex( sal_Int32 Index, const Any& Element )
+throw ( IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException )
+{
+ ResetableGuard aGuard( m_aLock );
+
+ if ( !m_bContainerCreated )
+ FillContainer();
+
+ if ( !m_bInContainerCreation )
+ m_bContainerChanged = sal_True;
+ PropertySetContainer::insertByIndex( Index, Element );
+}
+
+void SAL_CALL RootActionTriggerContainer::removeByIndex( sal_Int32 Index )
+throw ( IndexOutOfBoundsException, WrappedTargetException, RuntimeException )
+{
+ ResetableGuard aGuard( m_aLock );
+
+ if ( !m_bContainerCreated )
+ FillContainer();
+
+ if ( !m_bInContainerCreation )
+ m_bContainerChanged = sal_True;
+ PropertySetContainer::removeByIndex( Index );
+}
+
+
+// XIndexReplace
+void SAL_CALL RootActionTriggerContainer::replaceByIndex( sal_Int32 Index, const Any& Element )
+throw ( IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException )
+{
+ ResetableGuard aGuard( m_aLock );
+
+ if ( !m_bContainerCreated )
+ FillContainer();
+
+ if ( !m_bInContainerCreation )
+ m_bContainerChanged = sal_True;
+ PropertySetContainer::replaceByIndex( Index, Element );
+}
+
+
+// XIndexAccess
+sal_Int32 SAL_CALL RootActionTriggerContainer::getCount()
+throw ( RuntimeException )
+{
+ ResetableGuard aGuard( m_aLock );
+
+ if ( !m_bContainerCreated )
+ {
+ if ( m_pMenu )
+ {
+ vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
+ return m_pMenu->GetItemCount();
+ }
+ else
+ return 0;
+ }
+ else
+ {
+ return PropertySetContainer::getCount();
+ }
+}
+
+Any SAL_CALL RootActionTriggerContainer::getByIndex( sal_Int32 Index )
+throw ( IndexOutOfBoundsException, WrappedTargetException, RuntimeException )
+{
+ ResetableGuard aGuard( m_aLock );
+
+ if ( !m_bContainerCreated )
+ FillContainer();
+
+ return PropertySetContainer::getByIndex( Index );
+}
+
+
+// XElementAccess
+Type SAL_CALL RootActionTriggerContainer::getElementType()
+ throw (::com::sun::star::uno::RuntimeException)
+{
+ return ::getCppuType(( Reference< XPropertySet >*)0);
+}
+
+sal_Bool SAL_CALL RootActionTriggerContainer::hasElements()
+throw (::com::sun::star::uno::RuntimeException)
+{
+ if ( m_pMenu )
+ {
+ vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
+ return ( m_pMenu->GetItemCount() > 0 );
+ }
+
+ return sal_False;
+}
+
+
+// XServiceInfo
+::rtl::OUString SAL_CALL RootActionTriggerContainer::getImplementationName()
+throw ( RuntimeException )
+{
+ return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( IMPLEMENTATIONNAME_ROOTACTIONTRIGGERCONTAINER ));
+}
+
+sal_Bool SAL_CALL RootActionTriggerContainer::supportsService( const ::rtl::OUString& ServiceName )
+throw ( RuntimeException )
+{
+ if ( ServiceName.equalsAscii( SERVICENAME_ACTIONTRIGGERCONTAINER ))
+ return sal_True;
+
+ return sal_False;
+}
+
+Sequence< ::rtl::OUString > SAL_CALL RootActionTriggerContainer::getSupportedServiceNames()
+throw ( RuntimeException )
+{
+ Sequence< ::rtl::OUString > seqServiceNames( 1 );
+
+ seqServiceNames[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SERVICENAME_ACTIONTRIGGERCONTAINER ));
+ return seqServiceNames;
+}
+
+// XUnoTunnel
+sal_Int64 SAL_CALL RootActionTriggerContainer::getSomething( const Sequence< sal_Int8 >& aIdentifier ) throw ( RuntimeException )
+{
+ if ( aIdentifier == impl_getStaticIdentifier() )
+ return reinterpret_cast< sal_Int64 >( this );
+ else
+ return 0;
+}
+
+// XTypeProvider
+Sequence< Type > SAL_CALL RootActionTriggerContainer::getTypes() throw ( RuntimeException )
+{
+ // Optimize this method !
+ // We initialize a static variable only one time. And we don't must use a mutex at every call!
+ // For the first call; pTypeCollection is NULL - for the second call pTypeCollection is different from NULL!
+ static ::cppu::OTypeCollection* pTypeCollection = NULL ;
+
+ if ( pTypeCollection == NULL )
+ {
+ // Ready for multithreading; get global mutex for first call of this method only! see before
+ osl::MutexGuard aGuard( osl::Mutex::getGlobalMutex() ) ;
+
+ // Control these pointer again ... it can be, that another instance will be faster then these!
+ if ( pTypeCollection == NULL )
+ {
+ // Create a static typecollection ...
+ static ::cppu::OTypeCollection aTypeCollection(
+ ::getCppuType(( const Reference< XMultiServiceFactory >*)NULL ) ,
+ ::getCppuType(( const Reference< XIndexContainer >*)NULL ) ,
+ ::getCppuType(( const Reference< XIndexAccess >*)NULL ) ,
+ ::getCppuType(( const Reference< XIndexReplace >*)NULL ) ,
+ ::getCppuType(( const Reference< XServiceInfo >*)NULL ) ,
+ ::getCppuType(( const Reference< XTypeProvider >*)NULL ) ,
+ ::getCppuType(( const Reference< XUnoTunnel >*)NULL ) ,
+ ::getCppuType(( const Reference< XNamed >*)NULL )) ;
+
+ // ... and set his address to static pointer!
+ pTypeCollection = &aTypeCollection ;
+ }
+ }
+
+ return pTypeCollection->getTypes() ;
+}
+
+Sequence< sal_Int8 > SAL_CALL RootActionTriggerContainer::getImplementationId() throw ( RuntimeException )
+{
+ // Create one Id for all instances of this class.
+ // Use ethernet address to do this! (sal_True)
+
+ // Optimize this method
+ // We initialize a static variable only one time. And we don't must use a mutex at every call!
+ // For the first call; pID is NULL - for the second call pID is different from NULL!
+ static ::cppu::OImplementationId* pID = NULL ;
+
+ if ( pID == NULL )
+ {
+ // Ready for multithreading; get global mutex for first call of this method only! see before
+ osl::MutexGuard aGuard( osl::Mutex::getGlobalMutex() ) ;
+
+ // Control these pointer again ... it can be, that another instance will be faster then these!
+ if ( pID == NULL )
+ {
+ // Create a new static ID ...
+ static ::cppu::OImplementationId aID( sal_False ) ;
+ // ... and set his address to static pointer!
+ pID = &aID ;
+ }
+ }
+
+ return pID->getImplementationId() ;
+}
+
+// private implementation helper
+void RootActionTriggerContainer::FillContainer()
+{
+ m_bContainerCreated = sal_True;
+ m_bInContainerCreation = sal_True;
+ Reference<XIndexContainer> xXIndexContainer( (OWeakObject *)this, UNO_QUERY );
+ ActionTriggerHelper::FillActionTriggerContainerFromMenu(
+ xXIndexContainer,
+ m_pMenu );
+ m_bInContainerCreation = sal_False;
+}
+::rtl::OUString RootActionTriggerContainer::getName() throw ( RuntimeException )
+{
+ ::rtl::OUString sRet;
+ if( m_pMenuIdentifier )
+ sRet = *m_pMenuIdentifier;
+ return sRet;
+}
+
+void RootActionTriggerContainer::setName( const ::rtl::OUString& ) throw ( RuntimeException)
+{
+ throw RuntimeException();
+}
+}
+
diff --git a/framework/source/classes/sfxhelperfunctions.cxx b/framework/source/classes/sfxhelperfunctions.cxx
new file mode 100644
index 000000000000..655d96cdb681
--- /dev/null
+++ b/framework/source/classes/sfxhelperfunctions.cxx
@@ -0,0 +1,158 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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"
+
+#ifndef __FRAMEWORK_CLASSES_SFXHELPERFUNCTIONS_CXX_
+#include <classes/sfxhelperfunctions.hxx>
+#endif
+
+static pfunc_setToolBoxControllerCreator pToolBoxControllerCreator = NULL;
+static pfunc_setStatusBarControllerCreator pStatusBarControllerCreator = NULL;
+static pfunc_getRefreshToolbars pRefreshToolbars = NULL;
+static pfunc_createDockingWindow pCreateDockingWindow = NULL;
+static pfunc_isDockingWindowVisible pIsDockingWindowVisible = NULL;
+
+
+
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::frame;
+
+namespace framework
+{
+
+pfunc_setToolBoxControllerCreator SAL_CALL SetToolBoxControllerCreator( pfunc_setToolBoxControllerCreator pSetToolBoxControllerCreator )
+{
+ ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
+ pfunc_setToolBoxControllerCreator pOldSetToolBoxControllerCreator = pToolBoxControllerCreator;
+ pToolBoxControllerCreator = pSetToolBoxControllerCreator;
+ return pOldSetToolBoxControllerCreator;
+}
+
+svt::ToolboxController* SAL_CALL CreateToolBoxController( const Reference< XFrame >& rFrame, ToolBox* pToolbox, unsigned short nID, const ::rtl::OUString& aCommandURL )
+{
+ pfunc_setToolBoxControllerCreator pFactory = NULL;
+ {
+ ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
+ pFactory = pToolBoxControllerCreator;
+ }
+
+ if ( pFactory )
+ return (*pFactory)( rFrame, pToolbox, nID, aCommandURL );
+ else
+ return NULL;
+}
+
+pfunc_setStatusBarControllerCreator SAL_CALL SetStatusBarControllerCreator( pfunc_setStatusBarControllerCreator pSetStatusBarControllerCreator )
+{
+ ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
+ pfunc_setStatusBarControllerCreator pOldSetStatusBarControllerCreator = pSetStatusBarControllerCreator;
+ pStatusBarControllerCreator = pSetStatusBarControllerCreator;
+ return pOldSetStatusBarControllerCreator;
+}
+
+svt::StatusbarController* SAL_CALL CreateStatusBarController( const Reference< XFrame >& rFrame, StatusBar* pStatusBar, unsigned short nID, const ::rtl::OUString& aCommandURL )
+{
+ pfunc_setStatusBarControllerCreator pFactory = NULL;
+ {
+ ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
+ pFactory = pStatusBarControllerCreator;
+ }
+
+ if ( pFactory )
+ return (*pFactory)( rFrame, pStatusBar, nID, aCommandURL );
+ else
+ return NULL;
+}
+
+pfunc_getRefreshToolbars SAL_CALL SetRefreshToolbars( pfunc_getRefreshToolbars pNewRefreshToolbarsFunc )
+{
+ ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
+ pfunc_getRefreshToolbars pOldFunc = pRefreshToolbars;
+ pRefreshToolbars = pNewRefreshToolbarsFunc;
+
+ return pOldFunc;
+}
+
+void SAL_CALL RefreshToolbars( ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame >& rFrame )
+{
+ pfunc_getRefreshToolbars pCallback = NULL;
+ {
+ ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
+ pCallback = pRefreshToolbars;
+ }
+
+ if ( pCallback )
+ (*pCallback)( rFrame );
+}
+
+pfunc_createDockingWindow SAL_CALL SetDockingWindowCreator( pfunc_createDockingWindow pNewCreateDockingWindow )
+{
+ ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
+ pfunc_createDockingWindow pOldFunc = pCreateDockingWindow;
+ pCreateDockingWindow = pNewCreateDockingWindow;
+
+ return pOldFunc;
+}
+
+void SAL_CALL CreateDockingWindow( const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame >& rFrame, const ::rtl::OUString& rResourceURL )
+{
+ pfunc_createDockingWindow pFactory = NULL;
+ {
+ ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
+ pFactory = pCreateDockingWindow;
+ }
+
+ if ( pFactory )
+ (*pFactory)( rFrame, rResourceURL );
+}
+
+pfunc_isDockingWindowVisible SAL_CALL SetIsDockingWindowVisible( pfunc_isDockingWindowVisible pNewIsDockingWindowVisible)
+{
+ ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
+ pfunc_isDockingWindowVisible pOldFunc = pIsDockingWindowVisible;
+ pIsDockingWindowVisible = pNewIsDockingWindowVisible;
+
+ return pOldFunc;
+}
+
+bool SAL_CALL IsDockingWindowVisible( const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame >& rFrame, const ::rtl::OUString& rResourceURL )
+{
+ pfunc_isDockingWindowVisible pCall = NULL;
+ {
+ ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
+ pCall = pIsDockingWindowVisible;
+ }
+
+ if ( pIsDockingWindowVisible )
+ return (*pIsDockingWindowVisible)( rFrame, rResourceURL );
+ else
+ return false;
+}
+
+}
diff --git a/framework/source/classes/taskcreator.cxx b/framework/source/classes/taskcreator.cxx
new file mode 100644
index 000000000000..162c10e5cfa0
--- /dev/null
+++ b/framework/source/classes/taskcreator.cxx
@@ -0,0 +1,171 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * 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"
+
+//_________________________________________________________________________________________________________________
+// my own includes
+//_________________________________________________________________________________________________________________
+#include <classes/taskcreator.hxx>
+#include "services/taskcreatorsrv.hxx"
+#include <threadhelp/readguard.hxx>
+#include <loadenv/targethelper.hxx>
+#include <services.h>
+
+//_________________________________________________________________________________________________________________
+// interface includes
+//_________________________________________________________________________________________________________________
+#include <com/sun/star/lang/XSingleServiceFactory.hpp>
+#include <com/sun/star/beans/NamedValue.hpp>
+
+//_________________________________________________________________________________________________________________
+// includes of other projects
+//_________________________________________________________________________________________________________________
+#include <comphelper/configurationhelper.hxx>
+#include <vcl/svapp.hxx>
+
+//_________________________________________________________________________________________________________________
+// includes of my own project
+//_________________________________________________________________________________________________________________
+
+//_________________________________________________________________________________________________________________
+// namespace
+//_________________________________________________________________________________________________________________
+
+namespace framework{
+
+//_________________________________________________________________________________________________________________
+// non exported const
+//_________________________________________________________________________________________________________________
+
+//_________________________________________________________________________________________________________________
+// non exported definitions
+//_________________________________________________________________________________________________________________
+
+//_________________________________________________________________________________________________________________
+// declarations
+//_________________________________________________________________________________________________________________
+
+/*-****************************************************************************************************//**
+ @short initialize instance with neccessary informations
+ @descr We need a valid uno service manager to create or instanciate new services.
+ All other informations to create frames or tasks come in on right interface methods.
+
+ @param xSMGR
+ points to the valid uno service manager
+
+ @modified 16.05.2002 09:25, as96863
+*//*-*****************************************************************************************************/
+TaskCreator::TaskCreator( const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR )
+ : ThreadHelpBase( )
+ , m_xSMGR ( xSMGR )
+{
+}
+
+/*-****************************************************************************************************//**
+ @short deinitialize instance
+ @descr We should release all used ressource which are not needed any longer.
+
+ @modified 16.05.2002 09:33, as96863
+*//*-*****************************************************************************************************/
+TaskCreator::~TaskCreator()
+{
+ m_xSMGR.clear();
+}
+
+/*-****************************************************************************************************//**
+ TODO document me
+*//*-*****************************************************************************************************/
+css::uno::Reference< css::frame::XFrame > TaskCreator::createTask( const ::rtl::OUString& sName ,
+ sal_Bool bVisible )
+{
+ static ::rtl::OUString PACKAGE = ::rtl::OUString::createFromAscii("org.openoffice.Office.TabBrowse");
+ static ::rtl::OUString RELPATH = ::rtl::OUString::createFromAscii("TaskCreatorService" );
+ static ::rtl::OUString KEY = ::rtl::OUString::createFromAscii("ImplementationName" );
+
+ /* SAFE { */
+ ReadGuard aReadLock( m_aLock );
+ css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
+ aReadLock.unlock();
+ /* } SAFE */
+
+ css::uno::Reference< css::lang::XSingleServiceFactory > xCreator;
+ ::rtl::OUString sCreator = IMPLEMENTATIONNAME_FWK_TASKCREATOR;
+
+ try
+ {
+ if (
+ ( TargetHelper::matchSpecialTarget(sName, TargetHelper::E_BLANK ) ) ||
+ ( TargetHelper::matchSpecialTarget(sName, TargetHelper::E_DEFAULT) )
+ )
+ {
+ ::comphelper::ConfigurationHelper::readDirectKey(xSMGR, PACKAGE, RELPATH, KEY, ::comphelper::ConfigurationHelper::E_READONLY) >>= sCreator;
+ }
+
+ xCreator = css::uno::Reference< css::lang::XSingleServiceFactory >(
+ xSMGR->createInstance(sCreator), css::uno::UNO_QUERY_THROW);
+ }
+ catch(const css::uno::Exception&)
+ {}
+
+ // no catch here ... without an task creator service we cant open ANY document window within the office.
+ // Thats IMHO not a good idea. Then we should accept the stacktrace showing us the real problem.
+ // BTW: The used fallback creator service (IMPLEMENTATIONNAME_FWK_TASKCREATOR) is implemented in the same
+ // library then these class here ... Why we should not be able to create it ?
+ if ( ! xCreator.is())
+ xCreator = css::uno::Reference< css::lang::XSingleServiceFactory >(
+ xSMGR->createInstance(IMPLEMENTATIONNAME_FWK_TASKCREATOR), css::uno::UNO_QUERY_THROW);
+
+ css::uno::Sequence< css::uno::Any > lArgs(5);
+ css::beans::NamedValue aArg ;
+
+ aArg.Name = TaskCreatorService::ARGUMENT_PARENTFRAME;
+ aArg.Value <<= css::uno::Reference< css::frame::XFrame >(xSMGR->createInstance(SERVICENAME_DESKTOP), css::uno::UNO_QUERY_THROW);
+ lArgs[0] <<= aArg;
+
+ aArg.Name = TaskCreatorService::ARGUMENT_CREATETOPWINDOW;
+ aArg.Value <<= sal_True;
+ lArgs[1] <<= aArg;
+
+ aArg.Name = TaskCreatorService::ARGUMENT_MAKEVISIBLE;
+ aArg.Value <<= bVisible;
+ lArgs[2] <<= aArg;
+
+ aArg.Name = TaskCreatorService::ARGUMENT_SUPPORTPERSISTENTWINDOWSTATE;
+ aArg.Value <<= sal_True;
+ lArgs[3] <<= aArg;
+
+ aArg.Name = TaskCreatorService::ARGUMENT_FRAMENAME;
+ aArg.Value <<= sName;
+ lArgs[4] <<= aArg;
+
+ css::uno::Reference< css::frame::XFrame > xTask(xCreator->createInstanceWithArguments(lArgs), css::uno::UNO_QUERY_THROW);
+ return xTask;
+}
+
+} // namespace framework