diff options
Diffstat (limited to 'svtools/source/uno')
27 files changed, 13290 insertions, 0 deletions
diff --git a/svtools/source/uno/addrtempuno.cxx b/svtools/source/uno/addrtempuno.cxx new file mode 100644 index 000000000000..2f25a8f2f9b2 --- /dev/null +++ b/svtools/source/uno/addrtempuno.cxx @@ -0,0 +1,245 @@ +/************************************************************************* + * + * 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_svtools.hxx" +#include "svtools/genericunodialog.hxx" +#ifndef _SVT_DOC_ADDRESSTEMPLATE_HXX_ +#include "addresstemplate.hxx" +#endif +#ifndef _CPPUHELPER_EXTRACT_HXX_ +#include <cppuhelper/extract.hxx> +#endif +#include <cppuhelper/typeprovider.hxx> +#include <comphelper/property.hxx> +#include <com/sun/star/sdbc/XDataSource.hpp> + +class SfxItemSet; +class SfxItemPool; +class SfxPoolItem; + +// ....................................................................... +namespace svt +{ +// ....................................................................... + +#define UNODIALOG_PROPERTY_ID_ALIASES 100 +#define UNODIALOG_PROPERTY_ALIASES "FieldMapping" + + using namespace com::sun::star::uno; + using namespace com::sun::star::lang; + using namespace com::sun::star::util; + using namespace com::sun::star::beans; + using namespace com::sun::star::sdbc; + + //========================================================================= + //= OAddressBookSourceDialogUno + //========================================================================= + typedef OGenericUnoDialog OAddressBookSourceDialogUnoBase; + class OAddressBookSourceDialogUno + :public OAddressBookSourceDialogUnoBase + ,public ::comphelper::OPropertyArrayUsageHelper< OAddressBookSourceDialogUno > + { + protected: + Sequence< AliasProgrammaticPair > m_aAliases; + Reference< XDataSource > m_xDataSource; + ::rtl::OUString m_sDataSourceName; + ::rtl::OUString m_sTable; + + protected: + OAddressBookSourceDialogUno(const Reference< XMultiServiceFactory >& _rxORB); + + public: + // XTypeProvider + virtual Sequence<sal_Int8> SAL_CALL getImplementationId( ) throw(RuntimeException); + + // XServiceInfo + virtual ::rtl::OUString SAL_CALL getImplementationName() throw(RuntimeException); + virtual ::comphelper::StringSequence SAL_CALL getSupportedServiceNames() throw(RuntimeException); + + // XServiceInfo - static methods + static Sequence< ::rtl::OUString > getSupportedServiceNames_Static(void) throw( RuntimeException ); + static ::rtl::OUString getImplementationName_Static(void) throw( RuntimeException ); + static Reference< XInterface > + SAL_CALL Create(const Reference< com::sun::star::lang::XMultiServiceFactory >&); + + // XPropertySet + virtual Reference< XPropertySetInfo> SAL_CALL getPropertySetInfo() throw(RuntimeException); + virtual ::cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper(); + + // OPropertyArrayUsageHelper + virtual ::cppu::IPropertyArrayHelper* createArrayHelper( ) const; + + protected: + // OGenericUnoDialog overridables + virtual Dialog* createDialog(Window* _pParent); + + virtual void implInitialize(const com::sun::star::uno::Any& _rValue); + + virtual void executedDialog(sal_Int16 _nExecutionResult); + }; + + + //========================================================================= + //= OAddressBookSourceDialogUno + //========================================================================= + Reference< XInterface > SAL_CALL OAddressBookSourceDialogUno_CreateInstance( const Reference< XMultiServiceFactory >& _rxFactory) + { + return OAddressBookSourceDialogUno::Create(_rxFactory); + } + + //------------------------------------------------------------------------- + OAddressBookSourceDialogUno::OAddressBookSourceDialogUno(const Reference< XMultiServiceFactory >& _rxORB) + :OGenericUnoDialog(_rxORB) + { + registerProperty(::rtl::OUString::createFromAscii(UNODIALOG_PROPERTY_ALIASES), UNODIALOG_PROPERTY_ID_ALIASES, PropertyAttribute::READONLY, + &m_aAliases, getCppuType(&m_aAliases)); + } + + //------------------------------------------------------------------------- + Sequence<sal_Int8> SAL_CALL OAddressBookSourceDialogUno::getImplementationId( ) throw(RuntimeException) + { + static ::cppu::OImplementationId aId; + return aId.getImplementationId(); + } + + //------------------------------------------------------------------------- + Reference< XInterface > SAL_CALL OAddressBookSourceDialogUno::Create(const Reference< XMultiServiceFactory >& _rxFactory) + { + return *(new OAddressBookSourceDialogUno(_rxFactory)); + } + + //------------------------------------------------------------------------- + ::rtl::OUString SAL_CALL OAddressBookSourceDialogUno::getImplementationName() throw(RuntimeException) + { + return getImplementationName_Static(); + } + + //------------------------------------------------------------------------- + ::rtl::OUString OAddressBookSourceDialogUno::getImplementationName_Static() throw(RuntimeException) + { + return ::rtl::OUString::createFromAscii("com.sun.star.comp.svtools.OAddressBookSourceDialogUno"); + } + + //------------------------------------------------------------------------- + ::comphelper::StringSequence SAL_CALL OAddressBookSourceDialogUno::getSupportedServiceNames() throw(RuntimeException) + { + return getSupportedServiceNames_Static(); + } + + //------------------------------------------------------------------------- + ::comphelper::StringSequence OAddressBookSourceDialogUno::getSupportedServiceNames_Static() throw(RuntimeException) + { + ::comphelper::StringSequence aSupported(1); + aSupported.getArray()[0] = ::rtl::OUString::createFromAscii("com.sun.star.ui.AddressBookSourceDialog"); + return aSupported; + } + + //------------------------------------------------------------------------- + Reference<XPropertySetInfo> SAL_CALL OAddressBookSourceDialogUno::getPropertySetInfo() throw(RuntimeException) + { + Reference<XPropertySetInfo> xInfo( createPropertySetInfo( getInfoHelper() ) ); + return xInfo; + } + + //------------------------------------------------------------------------- + ::cppu::IPropertyArrayHelper& OAddressBookSourceDialogUno::getInfoHelper() + { + return *const_cast<OAddressBookSourceDialogUno*>(this)->getArrayHelper(); + } + + //------------------------------------------------------------------------------ + ::cppu::IPropertyArrayHelper* OAddressBookSourceDialogUno::createArrayHelper( ) const + { + Sequence< Property > aProps; + describeProperties(aProps); + return new ::cppu::OPropertyArrayHelper(aProps); + } + + //------------------------------------------------------------------------------ + void OAddressBookSourceDialogUno::executedDialog(sal_Int16 _nExecutionResult) + { + OAddressBookSourceDialogUnoBase::executedDialog(_nExecutionResult); + + if ( _nExecutionResult ) + if ( m_pDialog ) + static_cast< AddressBookSourceDialog* >( m_pDialog )->getFieldMapping( m_aAliases ); + } + + //------------------------------------------------------------------------------ + void OAddressBookSourceDialogUno::implInitialize(const com::sun::star::uno::Any& _rValue) + { + PropertyValue aVal; + if (_rValue >>= aVal) + { + if (0 == aVal.Name.compareToAscii("DataSource")) + { +#if OSL_DEBUG_LEVEL > 0 + sal_Bool bSuccess = +#endif + aVal.Value >>= m_xDataSource; + OSL_ENSURE( bSuccess, "OAddressBookSourceDialogUno::implInitialize: invalid type for DataSource!" ); + return; + } + + if (0 == aVal.Name.compareToAscii("DataSourceName")) + { +#if OSL_DEBUG_LEVEL > 0 + sal_Bool bSuccess = +#endif + aVal.Value >>= m_sDataSourceName; + OSL_ENSURE( bSuccess, "OAddressBookSourceDialogUno::implInitialize: invalid type for DataSourceName!" ); + return; + } + + if (0 == aVal.Name.compareToAscii("Command")) + { +#if OSL_DEBUG_LEVEL > 0 + sal_Bool bSuccess = +#endif + aVal.Value >>= m_sTable; + OSL_ENSURE( bSuccess, "OAddressBookSourceDialogUno::implInitialize: invalid type for Command!" ); + return; + } + } + + OAddressBookSourceDialogUnoBase::implInitialize( _rValue ); + } + + //------------------------------------------------------------------------------ + Dialog* OAddressBookSourceDialogUno::createDialog(Window* _pParent) + { + if ( m_xDataSource.is() && m_sTable.getLength() ) + return new AddressBookSourceDialog(_pParent, m_aContext.getLegacyServiceFactory(), m_xDataSource, m_sDataSourceName, m_sTable, m_aAliases ); + else + return new AddressBookSourceDialog( _pParent, m_aContext.getLegacyServiceFactory() ); + } + +// ....................................................................... +} // namespace svt +// ....................................................................... + diff --git a/svtools/source/uno/contextmenuhelper.cxx b/svtools/source/uno/contextmenuhelper.cxx new file mode 100644 index 000000000000..9eb36cf18a45 --- /dev/null +++ b/svtools/source/uno/contextmenuhelper.cxx @@ -0,0 +1,687 @@ +/************************************************************************* + * + * 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_svtools.hxx" + +#include "contextmenuhelper.hxx" +#include <svtools/menuoptions.hxx> +#include <svtools/miscopt.hxx> + +#include <com/sun/star/frame/XDispatch.hpp> +#include <com/sun/star/frame/XDispatchProvider.hpp> +#include <com/sun/star/frame/XModuleManager.hpp> +#include <com/sun/star/frame/XStatusListener.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/ui/XUIConfigurationManagerSupplier.hpp> +#include <com/sun/star/ui/XUIConfigurationManager.hpp> +#include <com/sun/star/ui/XModuleUIConfigurationManagerSupplier.hpp> +#include <com/sun/star/ui/ImageType.hpp> +#include <com/sun/star/beans/PropertyValue.hpp> + +#include <osl/conditn.hxx> +#include <cppuhelper/weak.hxx> +#include <comphelper/processfactory.hxx> +#include <vos/mutex.hxx> +#include <vcl/svapp.hxx> +#include <vcl/image.hxx> +#include <toolkit/unohlp.hxx> +#include <toolkit/awt/vclxwindow.hxx> +#include <toolkit/awt/vclxmenu.hxx> + +using namespace ::com::sun::star; + +namespace svt +{ + +// internal helper class to retrieve status updates +class StateEventHelper : public ::com::sun::star::frame::XStatusListener, + public ::cppu::OWeakObject +{ + public: + StateEventHelper( const uno::Reference< frame::XDispatchProvider >& xDispatchProvider, + const uno::Reference< util::XURLTransformer >& xURLTransformer, + const rtl::OUString& aCommandURL ); + virtual ~StateEventHelper(); + + bool isCommandEnabled(); + + // XInterface + virtual uno::Any SAL_CALL queryInterface( const uno::Type& aType ) throw ( uno::RuntimeException); + virtual void SAL_CALL acquire() throw (); + virtual void SAL_CALL release() throw (); + + // XEventListener + virtual void SAL_CALL disposing(const lang::EventObject& Source) throw( uno::RuntimeException ); + + // XStatusListener + virtual void SAL_CALL statusChanged(const frame::FeatureStateEvent& Event) throw( uno::RuntimeException ); + + private: + StateEventHelper(); + StateEventHelper( const StateEventHelper& ); + StateEventHelper& operator=( const StateEventHelper& ); + + bool m_bCurrentCommandEnabled; + ::rtl::OUString m_aCommandURL; + uno::Reference< frame::XDispatchProvider > m_xDispatchProvider; + uno::Reference< util::XURLTransformer > m_xURLTransformer; + osl::Condition m_aCondition; +}; + +StateEventHelper::StateEventHelper( + const uno::Reference< frame::XDispatchProvider >& xDispatchProvider, + const uno::Reference< util::XURLTransformer >& xURLTransformer, + const rtl::OUString& rCommandURL ) : + m_bCurrentCommandEnabled( true ), + m_aCommandURL( rCommandURL ), + m_xDispatchProvider( xDispatchProvider ), + m_xURLTransformer( xURLTransformer ) +{ + m_aCondition.reset(); +} + +StateEventHelper::~StateEventHelper() +{} + +uno::Any SAL_CALL StateEventHelper::queryInterface( + const uno::Type& aType ) +throw ( uno::RuntimeException ) +{ + uno::Any a = ::cppu::queryInterface( + aType, + SAL_STATIC_CAST( XStatusListener*, this )); + + if( a.hasValue() ) + return a; + + return ::cppu::OWeakObject::queryInterface( aType ); +} + +void SAL_CALL StateEventHelper::acquire() +throw () +{ + ::cppu::OWeakObject::acquire(); +} + +void SAL_CALL StateEventHelper::release() +throw () +{ + ::cppu::OWeakObject::release(); +} + +void SAL_CALL StateEventHelper::disposing( + const lang::EventObject& ) +throw ( uno::RuntimeException ) +{ + vos::OGuard aSolarGuard( Application::GetSolarMutex() ); + m_xDispatchProvider.clear(); + m_xURLTransformer.clear(); + m_aCondition.set(); +} + +void SAL_CALL StateEventHelper::statusChanged( + const frame::FeatureStateEvent& Event ) +throw ( uno::RuntimeException ) +{ + vos::OGuard aSolarGuard( Application::GetSolarMutex() ); + m_bCurrentCommandEnabled = Event.IsEnabled; + m_aCondition.set(); +} + +bool StateEventHelper::isCommandEnabled() +{ + // Be sure that we cannot die during condition wait + uno::Reference< frame::XStatusListener > xSelf( + SAL_STATIC_CAST( frame::XStatusListener*, this )); + + uno::Reference< frame::XDispatch > xDispatch; + util::URL aTargetURL; + { + vos::OGuard aSolarGuard( Application::GetSolarMutex() ); + if ( m_xDispatchProvider.is() && m_xURLTransformer.is() ) + { + ::rtl::OUString aSelf( RTL_CONSTASCII_USTRINGPARAM( "_self" )); + + aTargetURL.Complete = m_aCommandURL; + m_xURLTransformer->parseStrict( aTargetURL ); + + try + { + xDispatch = m_xDispatchProvider->queryDispatch( aTargetURL, aSelf, 0 ); + } + catch ( uno::RuntimeException& ) + { + throw; + } + catch ( uno::Exception& ) + { + } + } + } + + bool bResult( false ); + if ( xDispatch.is() ) + { + try + { + // add/remove ourself to retrieve status by callback + xDispatch->addStatusListener( xSelf, aTargetURL ); + xDispatch->removeStatusListener( xSelf, aTargetURL ); + + // wait for anwser + m_aCondition.wait(); + } + catch ( uno::RuntimeException& ) + { + throw; + } + catch ( uno::Exception& ) + { + } + + vos::OGuard aSolarGuard( Application::GetSolarMutex() ); + bResult = m_bCurrentCommandEnabled; + } + + return bResult; +} + +/*************************************************************************/ + +struct ExecuteInfo +{ + uno::Reference< frame::XDispatch > xDispatch; + util::URL aTargetURL; + uno::Sequence< beans::PropertyValue > aArgs; +}; + +static const PopupMenu* lcl_FindPopupFromItemId( const PopupMenu* pPopupMenu, sal_uInt16 nItemId ) +{ + if ( pPopupMenu ) + { + sal_uInt16 nCount = pPopupMenu->GetItemCount(); + for ( sal_uInt16 i = 0; i < nCount; i++ ) + { + sal_uInt16 nId = pPopupMenu->GetItemId( i ); + if ( nId == nItemId ) + return pPopupMenu; + else + { + const PopupMenu* pResult( 0 ); + + const PopupMenu* pSubPopup = pPopupMenu->GetPopupMenu( i ); + if ( pPopupMenu ) + pResult = lcl_FindPopupFromItemId( pSubPopup, nItemId ); + if ( pResult != 0 ) + return pResult; + } + } + } + + return NULL; +} + +static ::rtl::OUString lcl_GetItemCommandRecursive( const PopupMenu* pPopupMenu, sal_uInt16 nItemId ) +{ + const PopupMenu* pPopup = lcl_FindPopupFromItemId( pPopupMenu, nItemId ); + if ( pPopup ) + return pPopup->GetItemCommand( nItemId ); + else + return ::rtl::OUString(); +} + +/*************************************************************************/ + +ContextMenuHelper::ContextMenuHelper( + const uno::Reference< frame::XFrame >& xFrame, + bool bAutoRefresh ) : + m_xWeakFrame( xFrame ), + m_aSelf( RTL_CONSTASCII_USTRINGPARAM( "_self" )), + m_bAutoRefresh( bAutoRefresh ), + m_bUICfgMgrAssociated( false ) +{ +} + +ContextMenuHelper::~ContextMenuHelper() +{ +} + +void +ContextMenuHelper::completeAndExecute( + const Point& aPos, + PopupMenu& rPopupMenu ) +{ + vos::OGuard aSolarGuard( Application::GetSolarMutex() ); + + associateUIConfigurationManagers(); + completeMenuProperties( &rPopupMenu ); + executePopupMenu( aPos, &rPopupMenu ); + resetAssociations(); +} + +void +ContextMenuHelper::completeAndExecute( + const Point& aPos, + const uno::Reference< awt::XPopupMenu >& xPopupMenu ) +{ + vos::OGuard aSolarGuard( Application::GetSolarMutex() ); + + VCLXMenu* pXMenu = VCLXMenu::GetImplementation( xPopupMenu ); + if ( pXMenu ) + { + PopupMenu* pPopupMenu = dynamic_cast< PopupMenu* >( pXMenu->GetMenu() ); + // as dynamic_cast can return zero check pointer + if ( pPopupMenu ) + { + associateUIConfigurationManagers(); + completeMenuProperties( pPopupMenu ); + executePopupMenu( aPos, pPopupMenu ); + resetAssociations(); + } + } +} + +uno::Reference< awt::XPopupMenu > +ContextMenuHelper::create( + const ::rtl::OUString& /*aPopupMenuResourceId*/ ) +{ + // NOT IMPLEMENTED YET! + return uno::Reference< awt::XPopupMenu >(); +} + +bool +ContextMenuHelper::createAndExecute( + const Point& /*aPos*/, + const ::rtl::OUString& /*aPopupMenuResourceId*/ ) +{ + // NOT IMPLEMENTED YET! + return false; +} + +// private member + +void +ContextMenuHelper::executePopupMenu( + const Point& rPos, + PopupMenu* pMenu ) +{ + if ( pMenu ) + { + uno::Reference< frame::XFrame > xFrame( m_xWeakFrame ); + if ( xFrame.is() ) + { + uno::Reference< awt::XWindow > xWindow( xFrame->getContainerWindow() ); + if ( xWindow.is() ) + { + Window* pParent = VCLUnoHelper::GetWindow( xWindow ); + sal_uInt16 nResult = pMenu->Execute( pParent, rPos ); + + if ( nResult > 0 ) + { + ::rtl::OUString aCommand = lcl_GetItemCommandRecursive( pMenu, nResult ); + if ( aCommand.getLength() > 0 ) + dispatchCommand( xFrame, aCommand ); + } + } + } + } +} + +bool +ContextMenuHelper::dispatchCommand( + const uno::Reference< ::frame::XFrame >& rFrame, + const ::rtl::OUString& aCommandURL ) +{ + if ( !m_xURLTransformer.is() ) + { + m_xURLTransformer = uno::Reference< util::XURLTransformer >( + ::comphelper::getProcessServiceFactory()->createInstance( + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( + "com.sun.star.util.URLTransformer" ))), + uno::UNO_QUERY ); + } + + util::URL aTargetURL; + uno::Reference< frame::XDispatch > xDispatch; + if ( m_xURLTransformer.is() ) + { + aTargetURL.Complete = aCommandURL; + m_xURLTransformer->parseStrict( aTargetURL ); + + uno::Reference< frame::XDispatchProvider > xDispatchProvider( + rFrame, uno::UNO_QUERY ); + if ( xDispatchProvider.is() ) + { + try + { + xDispatch = xDispatchProvider->queryDispatch( aTargetURL, m_aSelf, 0 ); + } + catch ( uno::RuntimeException& ) + { + throw; + } + catch ( uno::Exception& ) + { + } + } + } + + if ( xDispatch.is() ) + { + ExecuteInfo* pExecuteInfo = new ExecuteInfo; + pExecuteInfo->xDispatch = xDispatch; + pExecuteInfo->aTargetURL = aTargetURL; + pExecuteInfo->aArgs = m_aDefaultArgs; + + Application::PostUserEvent( STATIC_LINK(0, ContextMenuHelper , ExecuteHdl_Impl), pExecuteInfo ); + return true; + } + + return false; +} + +// retrieves and stores references to our user-interface +// configuration managers, like image manager, ui command +// description manager. +bool +ContextMenuHelper::associateUIConfigurationManagers() +{ + uno::Reference< frame::XFrame > xFrame( m_xWeakFrame ); + if ( !m_bUICfgMgrAssociated && xFrame.is() ) + { + // clear current state + m_xDocImageMgr.clear(); + m_xModuleImageMgr.clear(); + m_xUICommandLabels.clear(); + + try + { + uno::Reference < frame::XController > xController; + uno::Reference < frame::XModel > xModel; + xController = xFrame->getController(); + if ( xController.is() ) + xModel = xController->getModel(); + + if ( xModel.is() ) + { + // retrieve document image manager form model + uno::Reference< ui::XUIConfigurationManagerSupplier > xSupplier( xModel, uno::UNO_QUERY ); + if ( xSupplier.is() ) + { + uno::Reference< ui::XUIConfigurationManager > xDocUICfgMgr( + xSupplier->getUIConfigurationManager(), uno::UNO_QUERY ); + m_xDocImageMgr = uno::Reference< ui::XImageManager >( + xDocUICfgMgr->getImageManager(), uno::UNO_QUERY ); + } + } + + uno::Reference< frame::XModuleManager > xModuleManager( + ::comphelper::getProcessServiceFactory()->createInstance( + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( + "com.sun.star.frame.ModuleManager" ))), + uno::UNO_QUERY ); + + uno::Reference< ui::XImageManager > xModuleImageManager; + rtl::OUString aModuleId; + if ( xModuleManager.is() ) + { + // retrieve module image manager + aModuleId = xModuleManager->identify( xFrame ); + + uno::Reference< ui::XModuleUIConfigurationManagerSupplier > xModuleCfgMgrSupplier( + ::comphelper::getProcessServiceFactory()->createInstance( + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( + "com.sun.star.ui.ModuleUIConfigurationManagerSupplier" ))), + uno::UNO_QUERY ); + if ( xModuleCfgMgrSupplier.is() ) + { + uno::Reference< ui::XUIConfigurationManager > xUICfgMgr( + xModuleCfgMgrSupplier->getUIConfigurationManager( aModuleId )); + if ( xUICfgMgr.is() ) + { + m_xModuleImageMgr = uno::Reference< ui::XImageManager >( + xUICfgMgr->getImageManager(), uno::UNO_QUERY ); + } + } + } + + uno::Reference< container::XNameAccess > xNameAccess( + ::comphelper::getProcessServiceFactory()->createInstance( + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( + "com.sun.star.frame.UICommandDescription" ))), + uno::UNO_QUERY ); + if ( xNameAccess.is() ) + { + try + { + uno::Any a = xNameAccess->getByName( aModuleId ); + a >>= m_xUICommandLabels; + } + catch ( container::NoSuchElementException& ) + { + } + } + } + catch ( uno::RuntimeException& ) + { + throw; + } + catch ( uno::Exception& ) + { + m_bUICfgMgrAssociated = true; + return false; + } + m_bUICfgMgrAssociated = true; + } + + return true; +} + +Image +ContextMenuHelper::getImageFromCommandURL( + const ::rtl::OUString& aCmdURL, + bool bHiContrast ) const +{ + Image aImage; + sal_Int16 nImageType( ui::ImageType::COLOR_NORMAL| + ui::ImageType::SIZE_DEFAULT ); + if ( bHiContrast ) + nImageType |= ui::ImageType::COLOR_HIGHCONTRAST; + + uno::Sequence< uno::Reference< graphic::XGraphic > > aGraphicSeq; + uno::Sequence< ::rtl::OUString > aImageCmdSeq( 1 ); + aImageCmdSeq[0] = aCmdURL; + + if ( m_xDocImageMgr.is() ) + { + try + { + aGraphicSeq = m_xDocImageMgr->getImages( nImageType, aImageCmdSeq ); + uno::Reference< graphic::XGraphic > xGraphic = aGraphicSeq[0]; + aImage = Image( xGraphic ); + + if ( !!aImage ) + return aImage; + } + catch ( uno::RuntimeException& ) + { + throw; + } + catch ( uno::Exception& ) + { + } + } + + if ( m_xModuleImageMgr.is() ) + { + try + { + aGraphicSeq = m_xModuleImageMgr->getImages( nImageType, aImageCmdSeq ); + uno::Reference< ::com::sun::star::graphic::XGraphic > xGraphic = aGraphicSeq[0]; + aImage = Image( xGraphic ); + + if ( !!aImage ) + return aImage; + } + catch ( uno::RuntimeException& ) + { + throw; + } + catch ( uno::Exception& ) + { + } + } + + return aImage; +} + +rtl::OUString +ContextMenuHelper::getLabelFromCommandURL( + const ::rtl::OUString& aCmdURL ) const +{ + ::rtl::OUString aLabel; + + if ( m_xUICommandLabels.is() ) + { + try + { + if ( aCmdURL.getLength() > 0 ) + { + rtl::OUString aStr; + uno::Sequence< beans::PropertyValue > aPropSeq; + uno::Any a( m_xUICommandLabels->getByName( aCmdURL )); + if ( a >>= aPropSeq ) + { + for ( sal_Int32 i = 0; i < aPropSeq.getLength(); i++ ) + { + if ( aPropSeq[i].Name.equalsAscii( "Label" )) + { + aPropSeq[i].Value >>= aStr; + break; + } + } + } + aLabel = aStr; + } + } + catch ( uno::RuntimeException& ) + { + } + catch ( uno::Exception& ) + { + } + } + + return aLabel; +} + +void +ContextMenuHelper::completeMenuProperties( + Menu* pMenu ) +{ + // Retrieve some settings necessary to display complete context + // menu correctly. + const StyleSettings& rSettings = Application::GetSettings().GetStyleSettings(); + bool bShowMenuImages( rSettings.GetUseImagesInMenus() ); + bool bIsHiContrast( rSettings.GetHighContrastMode() ); + + if ( pMenu ) + { + uno::Reference< frame::XFrame > xFrame( m_xWeakFrame ); + uno::Reference< frame::XDispatchProvider > xDispatchProvider( xFrame, uno::UNO_QUERY ); + + if ( !m_xURLTransformer.is() ) + { + m_xURLTransformer = uno::Reference< util::XURLTransformer >( + ::comphelper::getProcessServiceFactory()->createInstance( + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( + "com.sun.star.util.URLTransformer" ))), + uno::UNO_QUERY ); + } + + for ( sal_uInt16 nPos = 0; nPos < pMenu->GetItemCount(); nPos++ ) + { + sal_uInt16 nId = pMenu->GetItemId( nPos ); + PopupMenu* pPopupMenu = pMenu->GetPopupMenu( nId ); + if ( pPopupMenu ) + completeMenuProperties( pPopupMenu ); + if ( pMenu->GetItemType( nPos ) != MENUITEM_SEPARATOR ) + { + ::rtl::OUString aCmdURL( pMenu->GetItemCommand( nId )); + + if ( bShowMenuImages ) + { + Image aImage; + if ( aCmdURL.getLength() > 0 ) + aImage = getImageFromCommandURL( aCmdURL, bIsHiContrast ); + pMenu->SetItemImage( nId, aImage ); + } + else + pMenu->SetItemImage( nId, Image() ); + + if ( pMenu->GetItemText( nId ).Len() == 0 ) + { + ::rtl::OUString aLabel( getLabelFromCommandURL( aCmdURL )); + pMenu->SetItemText( nId, aLabel ); + } + + // Use helper to retrieve state of the command URL + StateEventHelper* pHelper = new StateEventHelper( + xDispatchProvider, + m_xURLTransformer, + aCmdURL ); + + uno::Reference< frame::XStatusListener > xHelper( pHelper ); + pMenu->EnableItem( nId, pHelper->isCommandEnabled() ); + } + } + } +} + + +IMPL_STATIC_LINK_NOINSTANCE( ContextMenuHelper, ExecuteHdl_Impl, ExecuteInfo*, pExecuteInfo ) +{ + // Release solar mutex to prevent deadlocks with clipboard thread + const sal_uInt32 nRef = Application::ReleaseSolarMutex(); + try + { + // Asynchronous execution as this can lead to our own destruction while we are + // on the stack. Stack unwinding would access the destroyed context menu. + pExecuteInfo->xDispatch->dispatch( pExecuteInfo->aTargetURL, pExecuteInfo->aArgs ); + } + catch ( uno::Exception& ) + { + } + + // Acquire solar mutex again + Application::AcquireSolarMutex( nRef ); + delete pExecuteInfo; + return 0; +} + +} // namespace svt diff --git a/svtools/source/uno/framestatuslistener.cxx b/svtools/source/uno/framestatuslistener.cxx new file mode 100644 index 000000000000..20176160b396 --- /dev/null +++ b/svtools/source/uno/framestatuslistener.cxx @@ -0,0 +1,444 @@ +/************************************************************************* + * + * 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_svtools.hxx" +#include <framestatuslistener.hxx> +#include <com/sun/star/frame/XDispatchProvider.hpp> +#include <com/sun/star/lang/DisposedException.hpp> +#include <vos/mutex.hxx> +#include <vcl/svapp.hxx> + +using namespace ::cppu; +using namespace ::com::sun::star::awt; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::util; +using namespace ::com::sun::star::beans; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::frame; + +namespace svt +{ + +FrameStatusListener::FrameStatusListener( + const Reference< XMultiServiceFactory >& rServiceManager, + const Reference< XFrame >& xFrame ) : + OWeakObject() + , m_bInitialized( sal_True ) + , m_bDisposed( sal_False ) + , m_xFrame( xFrame ) + , m_xServiceManager( rServiceManager ) +{ +} + +FrameStatusListener::~FrameStatusListener() +{ +} + +Reference< XFrame > FrameStatusListener::getFrameInterface() const +{ + vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() ); + return m_xFrame; +} + +Reference< XMultiServiceFactory > FrameStatusListener::getServiceManager() const +{ + vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() ); + return m_xServiceManager; +} + +// XInterface +Any SAL_CALL FrameStatusListener::queryInterface( const Type& rType ) +throw ( RuntimeException ) +{ + Any a = ::cppu::queryInterface( + rType , + static_cast< XComponent* >( this ), + static_cast< XFrameActionListener* >( this ), + static_cast< XStatusListener* >( this ), + static_cast< XEventListener* >( static_cast< XStatusListener* >( this )), + static_cast< XEventListener* >( static_cast< XFrameActionListener* >( this ))); + + if ( a.hasValue() ) + return a; + + return OWeakObject::queryInterface( rType ); +} + +void SAL_CALL FrameStatusListener::acquire() throw () +{ + OWeakObject::acquire(); +} + +void SAL_CALL FrameStatusListener::release() throw () +{ + OWeakObject::release(); +} + +// XComponent +void SAL_CALL FrameStatusListener::dispose() +throw (::com::sun::star::uno::RuntimeException) +{ + Reference< XComponent > xThis( static_cast< OWeakObject* >(this), UNO_QUERY ); + + vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() ); + if ( m_bDisposed ) + throw DisposedException(); + + Reference< XStatusListener > xStatusListener( static_cast< OWeakObject* >( this ), UNO_QUERY ); + URLToDispatchMap::iterator pIter = m_aListenerMap.begin(); + while ( pIter != m_aListenerMap.end() ) + { + try + { + Reference< XDispatch > xDispatch( pIter->second ); + Reference< XURLTransformer > xURLTransformer( m_xServiceManager->createInstance( + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( + "com.sun.star.util.URLTransformer" ))), + UNO_QUERY ); + com::sun::star::util::URL aTargetURL; + aTargetURL.Complete = pIter->first; + xURLTransformer->parseStrict( aTargetURL ); + + if ( xDispatch.is() && xStatusListener.is() ) + xDispatch->removeStatusListener( xStatusListener, aTargetURL ); + } + catch ( Exception& ) + { + } + + ++pIter; + } + + m_bDisposed = sal_True; +} + +void SAL_CALL FrameStatusListener::addEventListener( const Reference< XEventListener >& ) +throw ( RuntimeException ) +{ + // helper class for status updates - no need to support listener +} + +void SAL_CALL FrameStatusListener::removeEventListener( const Reference< XEventListener >& ) +throw ( RuntimeException ) +{ + // helper class for status updates - no need to support listener +} + +// XEventListener +void SAL_CALL FrameStatusListener::disposing( const EventObject& Source ) +throw ( RuntimeException ) +{ + Reference< XInterface > xSource( Source.Source ); + + vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() ); + + URLToDispatchMap::iterator pIter = m_aListenerMap.begin(); + while ( pIter != m_aListenerMap.end() ) + { + // Compare references and release dispatch references if they are equal. + Reference< XInterface > xIfac( pIter->second, UNO_QUERY ); + if ( xSource == xIfac ) + pIter->second.clear(); + } + + Reference< XInterface > xIfac( m_xFrame, UNO_QUERY ); + if ( xIfac == xSource ) + m_xFrame.clear(); +} + +// XStatusListener +void SAL_CALL FrameStatusListener::statusChanged( const FeatureStateEvent& ) +throw ( RuntimeException ) +{ + // must be implemented by sub class +} + +void FrameStatusListener::frameAction( const FrameActionEvent& Action ) +throw ( RuntimeException ) +{ + if ( Action.Action == FrameAction_CONTEXT_CHANGED ) + bindListener(); +} + +void FrameStatusListener::addStatusListener( const rtl::OUString& aCommandURL ) +{ + Reference< XDispatch > xDispatch; + Reference< XStatusListener > xStatusListener; + com::sun::star::util::URL aTargetURL; + + { + vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() ); + URLToDispatchMap::iterator pIter = m_aListenerMap.find( aCommandURL ); + + // Already in the list of status listener. Do nothing. + if ( pIter != m_aListenerMap.end() ) + return; + + // Check if we are already initialized. Implementation starts adding itself as status listener when + // intialize is called. + if ( !m_bInitialized ) + { + // Put into the hash_map of status listener. Will be activated when initialized is called + m_aListenerMap.insert( URLToDispatchMap::value_type( aCommandURL, Reference< XDispatch >() )); + return; + } + else + { + // Add status listener directly as intialize has already been called. + Reference< XDispatchProvider > xDispatchProvider( m_xFrame, UNO_QUERY ); + if ( m_xServiceManager.is() && xDispatchProvider.is() ) + { + Reference< XURLTransformer > xURLTransformer( m_xServiceManager->createInstance( + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.util.URLTransformer" ))), + UNO_QUERY ); + aTargetURL.Complete = aCommandURL; + xURLTransformer->parseStrict( aTargetURL ); + xDispatch = xDispatchProvider->queryDispatch( aTargetURL, ::rtl::OUString(), 0 ); + + xStatusListener = Reference< XStatusListener >( static_cast< OWeakObject* >( this ), UNO_QUERY ); + URLToDispatchMap::iterator aIter = m_aListenerMap.find( aCommandURL ); + if ( aIter != m_aListenerMap.end() ) + { + Reference< XDispatch > xOldDispatch( aIter->second ); + aIter->second = xDispatch; + + try + { + if ( xOldDispatch.is() ) + xOldDispatch->removeStatusListener( xStatusListener, aTargetURL ); + } + catch ( Exception& ) + { + } + } + else + m_aListenerMap.insert( URLToDispatchMap::value_type( aCommandURL, xDispatch )); + } + } + } + + // Call without locked mutex as we are called back from dispatch implementation + try + { + if ( xDispatch.is() ) + xDispatch->addStatusListener( xStatusListener, aTargetURL ); + } + catch ( Exception& ) + { + } +} + +void FrameStatusListener::removeStatusListener( const rtl::OUString& aCommandURL ) +{ + vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() ); + + URLToDispatchMap::iterator pIter = m_aListenerMap.find( aCommandURL ); + if ( pIter != m_aListenerMap.end() ) + { + Reference< XDispatch > xDispatch( pIter->second ); + Reference< XStatusListener > xStatusListener( static_cast< OWeakObject* >( this ), UNO_QUERY ); + m_aListenerMap.erase( pIter ); + + try + { + Reference< XURLTransformer > xURLTransformer( m_xServiceManager->createInstance( + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.util.URLTransformer" ))), + UNO_QUERY ); + com::sun::star::util::URL aTargetURL; + aTargetURL.Complete = aCommandURL; + xURLTransformer->parseStrict( aTargetURL ); + + if ( xDispatch.is() && xStatusListener.is() ) + xDispatch->removeStatusListener( xStatusListener, aTargetURL ); + } + catch ( Exception& ) + { + } + } +} + +void FrameStatusListener::bindListener() +{ + std::vector< Listener > aDispatchVector; + Reference< XStatusListener > xStatusListener; + + { + vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() ); + + if ( !m_bInitialized ) + return; + + // Collect all registered command URL's and store them temporary + Reference< XDispatchProvider > xDispatchProvider( m_xFrame, UNO_QUERY ); + if ( m_xServiceManager.is() && xDispatchProvider.is() ) + { + xStatusListener = Reference< XStatusListener >( static_cast< OWeakObject* >( this ), UNO_QUERY ); + URLToDispatchMap::iterator pIter = m_aListenerMap.begin(); + while ( pIter != m_aListenerMap.end() ) + { + Reference< XURLTransformer > xURLTransformer( m_xServiceManager->createInstance( + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.util.URLTransformer" ))), + UNO_QUERY ); + com::sun::star::util::URL aTargetURL; + aTargetURL.Complete = pIter->first; + xURLTransformer->parseStrict( aTargetURL ); + + Reference< XDispatch > xDispatch( pIter->second ); + if ( xDispatch.is() ) + { + // We already have a dispatch object => we have to requery. + // Release old dispatch object and remove it as listener + try + { + xDispatch->removeStatusListener( xStatusListener, aTargetURL ); + } + catch ( Exception& ) + { + } + } + + // Query for dispatch object. Old dispatch will be released with this, too. + try + { + xDispatch = xDispatchProvider->queryDispatch( aTargetURL, ::rtl::OUString(), 0 ); + } + catch ( Exception& ) + { + } + pIter->second = xDispatch; + + Listener aListener( aTargetURL, xDispatch ); + aDispatchVector.push_back( aListener ); + ++pIter; + } + } + } + + // Call without locked mutex as we are called back from dispatch implementation + if ( xStatusListener.is() ) + { + try + { + for ( sal_uInt32 i = 0; i < aDispatchVector.size(); i++ ) + { + Listener& rListener = aDispatchVector[i]; + if ( rListener.xDispatch.is() ) + rListener.xDispatch->addStatusListener( xStatusListener, rListener.aURL ); + } + } + catch ( Exception& ) + { + } + } +} + +void FrameStatusListener::unbindListener() +{ + vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() ); + + if ( !m_bInitialized ) + return; + + // Collect all registered command URL's and store them temporary + Reference< XDispatchProvider > xDispatchProvider( m_xFrame, UNO_QUERY ); + if ( m_xServiceManager.is() && xDispatchProvider.is() ) + { + Reference< XStatusListener > xStatusListener( static_cast< OWeakObject* >( this ), UNO_QUERY ); + URLToDispatchMap::iterator pIter = m_aListenerMap.begin(); + while ( pIter != m_aListenerMap.end() ) + { + Reference< XURLTransformer > xURLTransformer( m_xServiceManager->createInstance( + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.util.URLTransformer" ))), + UNO_QUERY ); + com::sun::star::util::URL aTargetURL; + aTargetURL.Complete = pIter->first; + xURLTransformer->parseStrict( aTargetURL ); + + Reference< XDispatch > xDispatch( pIter->second ); + if ( xDispatch.is() ) + { + // We already have a dispatch object => we have to requery. + // Release old dispatch object and remove it as listener + try + { + xDispatch->removeStatusListener( xStatusListener, aTargetURL ); + } + catch ( Exception& ) + { + } + } + pIter->second.clear(); + ++pIter; + } + } +} + +void FrameStatusListener::updateStatus( const rtl::OUString aCommandURL ) +{ + Reference< XDispatch > xDispatch; + Reference< XStatusListener > xStatusListener; + com::sun::star::util::URL aTargetURL; + + { + vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() ); + + if ( !m_bInitialized ) + return; + + // Try to find a dispatch object for the requested command URL + Reference< XDispatchProvider > xDispatchProvider( m_xFrame, UNO_QUERY ); + xStatusListener = Reference< XStatusListener >( static_cast< OWeakObject* >( this ), UNO_QUERY ); + if ( m_xServiceManager.is() && xDispatchProvider.is() ) + { + Reference< XURLTransformer > xURLTransformer( m_xServiceManager->createInstance( + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.util.URLTransformer" ))), + UNO_QUERY ); + aTargetURL.Complete = aCommandURL; + xURLTransformer->parseStrict( aTargetURL ); + xDispatch = xDispatchProvider->queryDispatch( aTargetURL, rtl::OUString(), 0 ); + } + } + + if ( xDispatch.is() && xStatusListener.is() ) + { + // Catch exception as we release our mutex, it is possible that someone else + // has already disposed this instance! + // Add/remove status listener to get a update status information from the + // requested command. + try + { + xDispatch->addStatusListener( xStatusListener, aTargetURL ); + xDispatch->removeStatusListener( xStatusListener, aTargetURL ); + } + catch ( Exception& ) + { + } + } +} + +} // svt diff --git a/svtools/source/uno/generictoolboxcontroller.cxx b/svtools/source/uno/generictoolboxcontroller.cxx new file mode 100644 index 000000000000..a58d9b784cca --- /dev/null +++ b/svtools/source/uno/generictoolboxcontroller.cxx @@ -0,0 +1,208 @@ +/************************************************************************* + * + * 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_svtools.hxx" +#include <svtools/generictoolboxcontroller.hxx> + +//_________________________________________________________________________________________________________________ +// my own includes +//_________________________________________________________________________________________________________________ + +//_________________________________________________________________________________________________________________ +// interface includes +//_________________________________________________________________________________________________________________ +#include <com/sun/star/util/XURLTransformer.hpp> +#include <com/sun/star/frame/XDispatchProvider.hpp> +#include <com/sun/star/beans/PropertyValue.hpp> +#include <com/sun/star/lang/DisposedException.hpp> +#include <com/sun/star/frame/status/ItemStatus.hpp> +#include <com/sun/star/frame/status/ItemState.hpp> + +//_________________________________________________________________________________________________________________ +// other includes +//_________________________________________________________________________________________________________________ +#include <vos/mutex.hxx> +#include <vcl/svapp.hxx> + +using namespace ::com::sun::star::awt; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::beans; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::frame; +using namespace ::com::sun::star::frame::status; +using namespace ::com::sun::star::util; + +namespace svt +{ + +struct ExecuteInfo +{ + ::com::sun::star::uno::Reference< ::com::sun::star::frame::XDispatch > xDispatch; + ::com::sun::star::util::URL aTargetURL; + ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > aArgs; +}; + +GenericToolboxController::GenericToolboxController( const Reference< XMultiServiceFactory >& rServiceManager, + const Reference< XFrame >& rFrame, + ToolBox* pToolbox, + USHORT nID, + const ::rtl::OUString& aCommand ) : + svt::ToolboxController( rServiceManager, rFrame, aCommand ) + , m_pToolbox( pToolbox ) + , m_nID( nID ) +{ + // Initialization is done through ctor + m_bInitialized = sal_True; + + // insert main command to our listener map + if ( m_aCommandURL.getLength() ) + m_aListenerMap.insert( URLToDispatchMap::value_type( aCommand, Reference< XDispatch >() )); +} + +GenericToolboxController::~GenericToolboxController() +{ +} + +void SAL_CALL GenericToolboxController::dispose() +throw ( RuntimeException ) +{ + vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() ); + + svt::ToolboxController::dispose(); + + m_pToolbox = 0; + m_nID = 0; +} + +void SAL_CALL GenericToolboxController::execute( sal_Int16 /*KeyModifier*/ ) +throw ( RuntimeException ) +{ + Reference< XDispatch > xDispatch; + Reference< XURLTransformer > xURLTransformer; + ::rtl::OUString aCommandURL; + + { + vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() ); + + if ( m_bDisposed ) + throw DisposedException(); + + if ( m_bInitialized && + m_xFrame.is() && + m_xServiceManager.is() && + m_aCommandURL.getLength() ) + { + xURLTransformer = Reference< XURLTransformer >( m_xServiceManager->createInstance( + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.util.URLTransformer" ))), + UNO_QUERY ); + + aCommandURL = m_aCommandURL; + URLToDispatchMap::iterator pIter = m_aListenerMap.find( m_aCommandURL ); + if ( pIter != m_aListenerMap.end() ) + xDispatch = pIter->second; + } + } + + if ( xDispatch.is() && xURLTransformer.is() ) + { + com::sun::star::util::URL aTargetURL; + Sequence<PropertyValue> aArgs; + + aTargetURL.Complete = aCommandURL; + xURLTransformer->parseStrict( aTargetURL ); + + // Execute dispatch asynchronously + ExecuteInfo* pExecuteInfo = new ExecuteInfo; + pExecuteInfo->xDispatch = xDispatch; + pExecuteInfo->aTargetURL = aTargetURL; + pExecuteInfo->aArgs = aArgs; + Application::PostUserEvent( STATIC_LINK(0, GenericToolboxController , ExecuteHdl_Impl), pExecuteInfo ); + } +} + +void GenericToolboxController::statusChanged( const FeatureStateEvent& Event ) +throw ( RuntimeException ) +{ + vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() ); + + if ( m_bDisposed ) + return; + + if ( m_pToolbox ) + { + m_pToolbox->EnableItem( m_nID, Event.IsEnabled ); + + USHORT nItemBits = m_pToolbox->GetItemBits( m_nID ); + nItemBits &= ~TIB_CHECKABLE; + TriState eTri = STATE_NOCHECK; + + sal_Bool bValue = sal_Bool(); + rtl::OUString aStrValue; + ItemStatus aItemState; + + if ( Event.State >>= bValue ) + { + // Boolean, treat it as checked/unchecked + m_pToolbox->SetItemBits( m_nID, nItemBits ); + m_pToolbox->CheckItem( m_nID, bValue ); + if ( bValue ) + eTri = STATE_CHECK; + nItemBits |= TIB_CHECKABLE; + } + else if ( Event.State >>= aStrValue ) + { + m_pToolbox->SetItemText( m_nID, aStrValue ); + } + else if ( Event.State >>= aItemState ) + { + eTri = STATE_DONTKNOW; + nItemBits |= TIB_CHECKABLE; + } + + m_pToolbox->SetItemState( m_nID, eTri ); + m_pToolbox->SetItemBits( m_nID, nItemBits ); + } +} + +IMPL_STATIC_LINK_NOINSTANCE( GenericToolboxController, ExecuteHdl_Impl, ExecuteInfo*, pExecuteInfo ) +{ + try + { + // Asynchronous execution as this can lead to our own destruction! + // Framework can recycle our current frame and the layout manager disposes all user interface + // elements if a component gets detached from its frame! + pExecuteInfo->xDispatch->dispatch( pExecuteInfo->aTargetURL, pExecuteInfo->aArgs ); + } + catch ( Exception& ) + { + } + delete pExecuteInfo; + return 0; +} + +} // namespace diff --git a/svtools/source/uno/genericunodialog.cxx b/svtools/source/uno/genericunodialog.cxx new file mode 100644 index 000000000000..a7ece1acc369 --- /dev/null +++ b/svtools/source/uno/genericunodialog.cxx @@ -0,0 +1,373 @@ +/************************************************************************* + * + * 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_svtools.hxx" + +#include "svtools/genericunodialog.hxx" + +#include <com/sun/star/beans/NamedValue.hpp> +#include <com/sun/star/ucb/AlreadyInitializedException.hpp> + +#include <toolkit/awt/vclxwindow.hxx> +#include <cppuhelper/extract.hxx> +#include <cppuhelper/typeprovider.hxx> +#include <comphelper/property.hxx> +#include <osl/diagnose.h> +#include <tools/diagnose_ex.h> +#include <vcl/msgbox.hxx> +#include <vos/mutex.hxx> +#include <vcl/svapp.hxx> + +using namespace ::comphelper; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::beans; +using namespace ::com::sun::star::ucb; + +//......................................................................... +namespace svt +{ +//......................................................................... + +//========================================================================= +//------------------------------------------------------------------------- +OGenericUnoDialog::OGenericUnoDialog(const Reference< XMultiServiceFactory >& _rxORB) + :OPropertyContainer(GetBroadcastHelper()) + ,m_pDialog(NULL) + ,m_bExecuting(sal_False) + ,m_bCanceled(sal_False) + ,m_bTitleAmbiguous(sal_True) + ,m_bInitialized( false ) + ,m_bNeedInitialization( false ) + ,m_aContext( _rxORB ) +{ + registerProperty(::rtl::OUString::createFromAscii(UNODIALOG_PROPERTY_TITLE), UNODIALOG_PROPERTY_ID_TITLE, PropertyAttribute::TRANSIENT, + &m_sTitle, getCppuType(&m_sTitle)); + registerProperty(::rtl::OUString::createFromAscii(UNODIALOG_PROPERTY_PARENT), UNODIALOG_PROPERTY_ID_PARENT, PropertyAttribute::TRANSIENT, + &m_xParent, getCppuType(&m_xParent)); +} + +//------------------------------------------------------------------------- +OGenericUnoDialog::OGenericUnoDialog(const Reference< XComponentContext >& _rxContext) + :OPropertyContainer(GetBroadcastHelper()) + ,m_pDialog(NULL) + ,m_bExecuting(sal_False) + ,m_bCanceled(sal_False) + ,m_bTitleAmbiguous(sal_True) + ,m_bInitialized( false ) + ,m_bNeedInitialization( false ) + ,m_aContext(_rxContext) +{ + registerProperty(::rtl::OUString::createFromAscii(UNODIALOG_PROPERTY_TITLE), UNODIALOG_PROPERTY_ID_TITLE, PropertyAttribute::TRANSIENT, + &m_sTitle, getCppuType(&m_sTitle)); + registerProperty(::rtl::OUString::createFromAscii(UNODIALOG_PROPERTY_PARENT), UNODIALOG_PROPERTY_ID_PARENT, PropertyAttribute::TRANSIENT, + &m_xParent, getCppuType(&m_xParent)); +} + +//------------------------------------------------------------------------- +OGenericUnoDialog::~OGenericUnoDialog() +{ + if ( m_pDialog ) + { + ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); + ::osl::MutexGuard aGuard( m_aMutex ); + if ( m_pDialog ) + destroyDialog(); + } +} + +//------------------------------------------------------------------------- +Any SAL_CALL OGenericUnoDialog::queryInterface(const Type& _rType) throw (RuntimeException) +{ + Any aReturn = OGenericUnoDialogBase::queryInterface(_rType); + + if (!aReturn.hasValue()) + aReturn = ::cppu::queryInterface(_rType + ,static_cast<XPropertySet*>(this) + ,static_cast<XMultiPropertySet*>(this) + ,static_cast<XFastPropertySet*>(this) + ); + + return aReturn; +} + +//------------------------------------------------------------------------- +Sequence<Type> SAL_CALL OGenericUnoDialog::getTypes( ) throw(RuntimeException) +{ + return ::comphelper::concatSequences( + OGenericUnoDialogBase::getTypes(), + ::comphelper::OPropertyContainer::getTypes() + ); +} + +//------------------------------------------------------------------------- +Sequence<sal_Int8> SAL_CALL OGenericUnoDialog::getImplementationId( ) throw(RuntimeException) +{ + static ::cppu::OImplementationId aId; + return aId.getImplementationId(); +} + +//------------------------------------------------------------------------- +sal_Bool SAL_CALL OGenericUnoDialog::supportsService(const ::rtl::OUString& ServiceName) throw(RuntimeException) +{ + Sequence< ::rtl::OUString > aSupported(getSupportedServiceNames()); + const ::rtl::OUString* pArray = aSupported.getConstArray(); + for (sal_Int32 i = 0; i < aSupported.getLength(); ++i, ++pArray) + if (pArray->equals(ServiceName)) + return sal_True; + return sal_False; +} + +//------------------------------------------------------------------------- +void OGenericUnoDialog::setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const Any& rValue ) throw(Exception) +{ + // TODO : need some handling if we're currently executing ... + + OPropertyContainer::setFastPropertyValue_NoBroadcast(nHandle, rValue); + + if (UNODIALOG_PROPERTY_ID_TITLE == nHandle) + { + // from now on m_sTitle is valid + m_bTitleAmbiguous = sal_False; + + if (m_pDialog) + m_pDialog->SetText(String(m_sTitle)); + } +} + +//------------------------------------------------------------------------- +sal_Bool OGenericUnoDialog::convertFastPropertyValue( Any& rConvertedValue, Any& rOldValue, sal_Int32 nHandle, const Any& rValue) throw(IllegalArgumentException) +{ + switch (nHandle) + { + case UNODIALOG_PROPERTY_ID_PARENT: + { + Reference<starawt::XWindow> xNew; + ::cppu::extractInterface(xNew, rValue); + if (xNew != m_xParent) + { + rConvertedValue <<= xNew; + rOldValue <<= m_xParent; + return sal_True; + } + return sal_False; + } + } + return OPropertyContainer::convertFastPropertyValue(rConvertedValue, rOldValue, nHandle, rValue); +} + +//------------------------------------------------------------------------- +void SAL_CALL OGenericUnoDialog::setTitle( const ::rtl::OUString& _rTitle ) throw(RuntimeException) +{ + UnoDialogEntryGuard aGuard( *this ); + + try + { + setPropertyValue(::rtl::OUString::createFromAscii(UNODIALOG_PROPERTY_TITLE), makeAny(_rTitle)); + } + catch(RuntimeException&) + { + // allowed to pass + throw; + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + // not allowed to pass + } +} + +//------------------------------------------------------------------------- +bool OGenericUnoDialog::impl_ensureDialog_lck() +{ + if ( m_pDialog ) + return true; + + // get the parameters for the dialog from the current settings + + // the parent window + Window* pParent = NULL; + VCLXWindow* pImplementation = VCLXWindow::GetImplementation(m_xParent); + if (pImplementation) + pParent = pImplementation->GetWindow(); + + // the title + String sTitle = m_sTitle; + + Dialog* pDialog = createDialog( pParent ); + OSL_ENSURE( pDialog, "OGenericUnoDialog::impl_ensureDialog_lck: createDialog returned nonsense!" ); + if ( !pDialog ) + return false; + + // do some initialisations + if ( !m_bTitleAmbiguous ) + pDialog->SetText( sTitle ); + + // be notified when the dialog is killed by somebody else + // #i65958# / 2006-07-07 / frank.schoenheit@sun.com + pDialog->AddEventListener( LINK( this, OGenericUnoDialog, OnDialogDying ) ); + + m_pDialog = pDialog; + + return true; +} + +//------------------------------------------------------------------------- +sal_Int16 SAL_CALL OGenericUnoDialog::execute( ) throw(RuntimeException) +{ + // both creation and execution of the dialog must be guarded with the SolarMutex, so be generous here + ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); + + Dialog* pDialogToExecute = NULL; + // create the dialog, if neccessary + { + UnoDialogEntryGuard aGuard( *this ); + + if (m_bExecuting) + throw RuntimeException( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "already executing the dialog (recursive call)" ) ), + *this + ); + + m_bCanceled = sal_False; + m_bExecuting = sal_True; + + if ( !impl_ensureDialog_lck() ) + return 0; + + pDialogToExecute = m_pDialog; + } + + // start execution + sal_Int16 nReturn(0); + if ( pDialogToExecute ) + nReturn = pDialogToExecute->Execute(); + + { + ::osl::MutexGuard aExecutionGuard(m_aExecutionMutex); + if (m_bCanceled) + nReturn = RET_CANCEL; + } + + { + ::osl::MutexGuard aGuard(m_aMutex); + + // get the settings of the dialog + executedDialog( nReturn ); + + m_bExecuting = sal_False; + } + + // outta here + return nReturn; +} + +#ifdef AWT_DIALOG +//------------------------------------------------------------------------- +void SAL_CALL OGenericUnoDialog::endExecute( ) throw(RuntimeException) +{ + UnoDialogEntryGuard aGuard( *this ); + if (!m_bExecuting) + throw RuntimeException(); + + { + ::osl::MutexGuard aExecutionGuard(m_aExecutionMutex); + OSL_ENSURE(m_pDialog, "OGenericUnoDialog::endExecute : executing which dialog ?"); + // m_bExecuting is true but we have no dialog ? + if (!m_pDialog) + throw RuntimeException(); + + if (!m_pDialog->IsInExecute()) + // we tighly missed it ... another thread finished the execution of the dialog, + // but did not manage it to reset m_bExecuting, it currently tries to acquire + // m_aMutex or m_aExecutionMutex + // => nothing to do + return; + + m_pDialog->EndDialog(RET_CANCEL); + m_bCanceled = sal_True; + } +} +#endif + +//------------------------------------------------------------------------- +void OGenericUnoDialog::implInitialize(const Any& _rValue) +{ + try + { + PropertyValue aProperty; + NamedValue aValue; + if ( _rValue >>= aProperty ) + { + setPropertyValue( aProperty.Name, aProperty.Value ); + } + else if ( _rValue >>= aValue ) + { + setPropertyValue( aValue.Name, aValue.Value ); + } + } + catch(const Exception&) + { + DBG_UNHANDLED_EXCEPTION(); + } +} + +//------------------------------------------------------------------------- +void SAL_CALL OGenericUnoDialog::initialize( const Sequence< Any >& aArguments ) throw(Exception, RuntimeException) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + if ( m_bInitialized ) + throw AlreadyInitializedException( ::rtl::OUString(), *this ); + + const Any* pArguments = aArguments.getConstArray(); + for (sal_Int32 i=0; i<aArguments.getLength(); ++i, ++pArguments) + implInitialize(*pArguments); + + m_bInitialized = true; +} + +//------------------------------------------------------------------------- +void OGenericUnoDialog::destroyDialog() +{ + delete m_pDialog; + m_pDialog = NULL; +} + +//------------------------------------------------------------------------- +IMPL_LINK( OGenericUnoDialog, OnDialogDying, VclWindowEvent*, _pEvent ) +{ + OSL_ENSURE( _pEvent->GetWindow() == m_pDialog, "OGenericUnoDialog::OnDialogDying: where does this come from?" ); + if ( _pEvent->GetId() == VCLEVENT_OBJECT_DYING ) + m_pDialog = NULL; + return 0L; +} + +//......................................................................... +} // namespace svt +//......................................................................... + diff --git a/svtools/source/uno/makefile.mk b/svtools/source/uno/makefile.mk new file mode 100644 index 000000000000..7c1c44006047 --- /dev/null +++ b/svtools/source/uno/makefile.mk @@ -0,0 +1,61 @@ +#************************************************************************* +# +# 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=svtools +TARGET=unoiface +ENABLE_EXCEPTIONS=TRUE + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk +.INCLUDE : $(PRJ)$/util$/svt.pmk + +# --- Files -------------------------------------------------------- + +SLOFILES= \ + $(SLO)$/addrtempuno.obj \ + $(SLO)$/contextmenuhelper.obj \ + $(SLO)$/framestatuslistener.obj \ + $(SLO)$/generictoolboxcontroller.obj \ + $(SLO)$/genericunodialog.obj \ + $(SLO)$/miscservices.obj\ + $(SLO)$/statusbarcontroller.obj \ + $(SLO)$/toolboxcontroller.obj \ + $(SLO)$/treecontrolpeer.obj \ + $(SLO)$/unocontroltablemodel.obj \ + $(SLO)$/unoevent.obj \ + $(SLO)$/unoiface.obj \ + $(SLO)$/unoimap.obj \ + $(SLO)$/svtxgridcontrol.obj \ + $(SLO)$/popupwindowcontroller.obj \ + $(SLO)$/popupmenucontrollerbase.obj + +# --- Targets ------------------------------------------------------ + +.INCLUDE : target.mk diff --git a/svtools/source/uno/miscservices.cxx b/svtools/source/uno/miscservices.cxx new file mode 100644 index 000000000000..34984976bf07 --- /dev/null +++ b/svtools/source/uno/miscservices.cxx @@ -0,0 +1,170 @@ +/************************************************************************* + * + * 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_svtools.hxx" +#include "sal/types.h" +#include "rtl/ustring.hxx" +#include <cppuhelper/factory.hxx> +#include <cppuhelper/weak.hxx> +#include <com/sun/star/lang/XSingleServiceFactory.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/registry/XRegistryKey.hpp> +#include <osl/diagnose.h> +#include <uno/mapping.hxx> +#include "provider.hxx" +#include "renderer.hxx" +#include "unowizard.hxx" + +#include <com/sun/star/registry/XRegistryKey.hpp> +#include "comphelper/servicedecl.hxx" + +#include "cppuhelper/implementationentry.hxx" + +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::registry; +using namespace ::com::sun::star::lang; +using namespace unographic; + +using rtl::OUString; + +namespace sdecl = comphelper::service_decl; + +namespace unographic { +extern sdecl::ServiceDecl const serviceDecl; +} + +// ------------------------------------------------------------------------------------- + +// for CreateInstance functions implemented elsewhere +#define DECLARE_CREATEINSTANCE( ImplName ) \ + Reference< XInterface > SAL_CALL ImplName##_CreateInstance( const Reference< XMultiServiceFactory >& ); + +// for CreateInstance functions implemented elsewhere, while the function is within a namespace +#define DECLARE_CREATEINSTANCE_NAMESPACE( nmspe, ImplName ) \ + namespace nmspe { \ + Reference< XInterface > SAL_CALL ImplName##_CreateInstance( const Reference< XMultiServiceFactory >& ); \ + } + +namespace +{ + static struct ::cppu::ImplementationEntry s_aServiceEntries[] = + { + { + ::svt::uno::Wizard::Create, + ::svt::uno::Wizard::getImplementationName_static, + ::svt::uno::Wizard::getSupportedServiceNames_static, + ::cppu::createSingleComponentFactory, NULL, 0 + }, + { 0, 0, 0, 0, 0, 0 } + }; +} + +// ------------------------------------------------------------------------------------- + +DECLARE_CREATEINSTANCE_NAMESPACE( svt, OAddressBookSourceDialogUno ) +DECLARE_CREATEINSTANCE( SvFilterOptionsDialog ) +DECLARE_CREATEINSTANCE_NAMESPACE( unographic, GraphicProvider ) +DECLARE_CREATEINSTANCE_NAMESPACE( unographic, GraphicRendererVCL ) + +// ------------------------------------------------------------------------------------- +extern "C" +{ + +SAL_DLLPUBLIC_EXPORT void SAL_CALL component_getImplementationEnvironment ( + const sal_Char ** ppEnvTypeName, uno_Environment ** /* ppEnv */) +{ + *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME; +} + +SAL_DLLPUBLIC_EXPORT void * SAL_CALL component_getFactory ( + const sal_Char * pImplementationName, void * _pServiceManager, void * pRegistryKey) +{ + void * pResult = 0; + if ( _pServiceManager ) + { + Reference< XSingleServiceFactory > xFactory; + if (rtl_str_compare ( + pImplementationName, "com.sun.star.comp.svtools.OAddressBookSourceDialogUno") == 0) + { + Sequence< OUString > aServiceNames(1); + aServiceNames.getArray()[0] = + OUString::createFromAscii( "com.sun.star.ui.AddressBookSourceDialog" ); + + xFactory = ::cppu::createSingleFactory ( + reinterpret_cast< XMultiServiceFactory* >( _pServiceManager ), + OUString::createFromAscii( pImplementationName ), + svt::OAddressBookSourceDialogUno_CreateInstance, + aServiceNames); + } + else if (rtl_str_compare ( + pImplementationName, "com.sun.star.svtools.SvFilterOptionsDialog") == 0) + { + Sequence< OUString > aServiceNames(1); + aServiceNames.getArray()[0] = + OUString::createFromAscii( "com.sun.star.ui.dialogs.FilterOptionsDialog" ); + + xFactory = ::cppu::createSingleFactory ( + reinterpret_cast< XMultiServiceFactory* >( _pServiceManager ), + OUString::createFromAscii( pImplementationName ), + SvFilterOptionsDialog_CreateInstance, + aServiceNames); + } + else if( 0 == GraphicProvider::getImplementationName_Static().compareToAscii( pImplementationName ) ) + { + xFactory = ::cppu::createOneInstanceFactory( + reinterpret_cast< lang::XMultiServiceFactory * >( _pServiceManager ), + GraphicProvider::getImplementationName_Static(), + GraphicProvider_CreateInstance, + GraphicProvider::getSupportedServiceNames_Static() ); + } + else if( 0 == GraphicRendererVCL::getImplementationName_Static().compareToAscii( pImplementationName ) ) + { + xFactory = ::cppu::createOneInstanceFactory( + reinterpret_cast< lang::XMultiServiceFactory * >( _pServiceManager ), + GraphicRendererVCL::getImplementationName_Static(), + GraphicRendererVCL_CreateInstance, + GraphicRendererVCL::getSupportedServiceNames_Static() ); + } + else + { + pResult = component_getFactoryHelper( pImplementationName, reinterpret_cast< lang::XMultiServiceFactory * >( _pServiceManager ),reinterpret_cast< registry::XRegistryKey* >( pRegistryKey ), serviceDecl ); + if ( !pResult ) + pResult = ::cppu::component_getFactoryHelper( pImplementationName, _pServiceManager, pRegistryKey, s_aServiceEntries ); + } + + if ( xFactory.is() ) + { + xFactory->acquire(); + pResult = xFactory.get(); + } + } + return pResult; +} + +} // "C" + diff --git a/svtools/source/uno/popupmenucontrollerbase.cxx b/svtools/source/uno/popupmenucontrollerbase.cxx new file mode 100644 index 000000000000..ac75a1b9a24b --- /dev/null +++ b/svtools/source/uno/popupmenucontrollerbase.cxx @@ -0,0 +1,420 @@ +/************************************************************************* + * + * 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_svtools.hxx" + +//_________________________________________________________________________________________________________________ +// my own includes +//_________________________________________________________________________________________________________________ +#include "svtools/popupmenucontrollerbase.hxx" + + +//_________________________________________________________________________________________________________________ +// interface includes +//_________________________________________________________________________________________________________________ +#include <com/sun/star/awt/XDevice.hpp> +#include <com/sun/star/beans/PropertyValue.hpp> +#include <com/sun/star/awt/MenuItemStyle.hpp> +#include <com/sun/star/frame/XDispatchProvider.hpp> +#include <com/sun/star/lang/DisposedException.hpp> +#include <com/sun/star/awt/XMenuExtended.hpp> + +//_________________________________________________________________________________________________________________ +// includes of other projects +//_________________________________________________________________________________________________________________ + +#ifndef _VCL_MENU_HXX_ +#include <vcl/menu.hxx> +#endif +#include <vcl/svapp.hxx> +#include <rtl/ustrbuf.hxx> +#include <rtl/logfile.hxx> +#include <vos/mutex.hxx> + +//_________________________________________________________________________________________________________________ +// Defines +//_________________________________________________________________________________________________________________ +// + +using ::rtl::OUString; + +using namespace com::sun::star; +using namespace com::sun::star::uno; +using namespace com::sun::star::lang; +using namespace com::sun::star::frame; +using namespace com::sun::star::beans; +using namespace com::sun::star::util; + +namespace svt +{ + +struct PopupMenuControllerBaseDispatchInfo +{ + Reference< XDispatch > mxDispatch; + const URL maURL; + const Sequence< PropertyValue > maArgs; + + PopupMenuControllerBaseDispatchInfo( const Reference< XDispatch >& xDispatch, const URL& rURL, const Sequence< PropertyValue >& rArgs ) + : mxDispatch( xDispatch ), maURL( rURL ), maArgs( rArgs ) {} +}; + +PopupMenuControllerBase::PopupMenuControllerBase( const Reference< XMultiServiceFactory >& xServiceManager ) : + ::comphelper::OBaseMutex(), + PopupMenuControllerBaseType(m_aMutex), + m_bInitialized( false ), + m_xServiceManager( xServiceManager ) +{ + if ( m_xServiceManager.is() ) + m_xURLTransformer.set( m_xServiceManager->createInstance(OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.util.URLTransformer"))),UNO_QUERY ); +} + +PopupMenuControllerBase::~PopupMenuControllerBase() +{ +} + +// protected function +void PopupMenuControllerBase::throwIfDisposed() throw ( RuntimeException ) +{ + if (rBHelper.bDisposed || rBHelper.bInDispose) + throw com::sun::star::lang::DisposedException(); +} + +// protected function +void PopupMenuControllerBase::resetPopupMenu( com::sun::star::uno::Reference< com::sun::star::awt::XPopupMenu >& rPopupMenu ) +{ + VCLXPopupMenu* pPopupMenu = 0; + if ( rPopupMenu.is() && rPopupMenu->getItemCount() > 0 ) + { + pPopupMenu = (VCLXPopupMenu *)VCLXMenu::GetImplementation( rPopupMenu ); + if ( pPopupMenu ) + { + vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() ); + + PopupMenu* pVCLPopupMenu = (PopupMenu *)pPopupMenu->GetMenu(); + pVCLPopupMenu->Clear(); + } + } +} + +void SAL_CALL PopupMenuControllerBase::disposing() +{ + // Reset our members and set disposed flag + osl::MutexGuard aLock( m_aMutex ); + m_xFrame.clear(); + m_xDispatch.clear(); + m_xPopupMenu.clear(); + m_xServiceManager.clear(); +} + +// XServiceInfo + +sal_Bool SAL_CALL PopupMenuControllerBase::supportsService( const ::rtl::OUString& ServiceName ) throw (RuntimeException) +{ + const Sequence< rtl::OUString > aSNL( getSupportedServiceNames() ); + const rtl::OUString * pArray = aSNL.getConstArray(); + + for( sal_Int32 i = 0; i < aSNL.getLength(); i++ ) + if( pArray[i] == ServiceName ) + return true; + + return false; +} + +// XEventListener +void SAL_CALL PopupMenuControllerBase::disposing( const EventObject& ) throw ( RuntimeException ) +{ + osl::MutexGuard aLock( m_aMutex ); + m_xFrame.clear(); + m_xDispatch.clear(); + m_xPopupMenu.clear(); +} + +// XMenuListener +void SAL_CALL PopupMenuControllerBase::highlight( const awt::MenuEvent& ) throw (RuntimeException) +{ +} + +void PopupMenuControllerBase::impl_select(const Reference< XDispatch >& _xDispatch,const URL& aURL) +{ + Sequence<PropertyValue> aArgs; + OSL_ENSURE(_xDispatch.is(),"PopupMenuControllerBase::impl_select: No dispatch"); + if ( _xDispatch.is() ) + _xDispatch->dispatch( aURL, aArgs ); +} + +void SAL_CALL PopupMenuControllerBase::select( const awt::MenuEvent& rEvent ) throw (RuntimeException) +{ + throwIfDisposed(); + + osl::MutexGuard aLock( m_aMutex ); + + Reference< awt::XMenuExtended > xExtMenu( m_xPopupMenu, UNO_QUERY ); + if( xExtMenu.is() ) + { + Sequence<PropertyValue> aArgs; + dispatchCommand( xExtMenu->getCommand( rEvent.MenuId ), aArgs ); + } +} + +void PopupMenuControllerBase::dispatchCommand( const ::rtl::OUString& sCommandURL, const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& rArgs ) +{ + osl::MutexGuard aLock( m_aMutex ); + + throwIfDisposed(); + + try + { + Reference< XDispatchProvider > xDispatchProvider( m_xFrame, UNO_QUERY_THROW ); + URL aURL; + aURL.Complete = sCommandURL; + m_xURLTransformer->parseStrict( aURL ); + + Reference< XDispatch > xDispatch( xDispatchProvider->queryDispatch( aURL, OUString(), 0 ), UNO_QUERY_THROW ); + + Application::PostUserEvent( STATIC_LINK(0, PopupMenuControllerBase, ExecuteHdl_Impl), new PopupMenuControllerBaseDispatchInfo( xDispatch, aURL, rArgs ) ); + + } + catch( Exception& ) + { + } + +} + +IMPL_STATIC_LINK_NOINSTANCE( PopupMenuControllerBase, ExecuteHdl_Impl, PopupMenuControllerBaseDispatchInfo*, pDispatchInfo ) +{ + pDispatchInfo->mxDispatch->dispatch( pDispatchInfo->maURL, pDispatchInfo->maArgs ); + delete pDispatchInfo; + return 0; +} + +void SAL_CALL PopupMenuControllerBase::activate( const awt::MenuEvent& ) throw (RuntimeException) +{ +} + +void SAL_CALL PopupMenuControllerBase::deactivate( const awt::MenuEvent& ) throw (RuntimeException) +{ +} + +void SAL_CALL PopupMenuControllerBase::updatePopupMenu() throw ( ::com::sun::star::uno::RuntimeException ) +{ + osl::ClearableMutexGuard aLock( m_aMutex ); + throwIfDisposed(); + aLock.clear(); + + updateCommand( m_aCommandURL ); +} + +void SAL_CALL PopupMenuControllerBase::updateCommand( const rtl::OUString& rCommandURL ) +{ + osl::ClearableMutexGuard aLock( m_aMutex ); + Reference< XStatusListener > xStatusListener( static_cast< OWeakObject* >( this ), UNO_QUERY ); + Reference< XDispatch > xDispatch( m_xDispatch ); + URL aTargetURL; + aTargetURL.Complete = rCommandURL; + m_xURLTransformer->parseStrict( aTargetURL ); + aLock.clear(); + + // Add/remove status listener to get a status update once + if ( xDispatch.is() ) + { + xDispatch->addStatusListener( xStatusListener, aTargetURL ); + xDispatch->removeStatusListener( xStatusListener, aTargetURL ); + } +} + + +// XDispatchProvider +Reference< XDispatch > SAL_CALL +PopupMenuControllerBase::queryDispatch( + const URL& /*aURL*/, + const rtl::OUString& /*sTarget*/, + sal_Int32 /*nFlags*/ ) +throw( RuntimeException ) +{ + // must be implemented by subclass + osl::MutexGuard aLock( m_aMutex ); + throwIfDisposed(); + + return Reference< XDispatch >(); +} + +Sequence< Reference< XDispatch > > SAL_CALL PopupMenuControllerBase::queryDispatches( const Sequence< DispatchDescriptor >& lDescriptor ) throw( RuntimeException ) +{ + // Create return list - which must have same size then the given descriptor + // It's not allowed to pack it! + osl::ClearableMutexGuard aLock( m_aMutex ); + throwIfDisposed(); + aLock.clear(); + + sal_Int32 nCount = lDescriptor.getLength(); + uno::Sequence< uno::Reference< frame::XDispatch > > lDispatcher( nCount ); + + // Step over all descriptors and try to get any dispatcher for it. + for( sal_Int32 i=0; i<nCount; ++i ) + { + lDispatcher[i] = queryDispatch( lDescriptor[i].FeatureURL , + lDescriptor[i].FrameName , + lDescriptor[i].SearchFlags ); + } + + return lDispatcher; +} + +// XDispatch +void SAL_CALL +PopupMenuControllerBase::dispatch( + const URL& /*aURL*/, + const Sequence< PropertyValue >& /*seqProperties*/ ) +throw( ::com::sun::star::uno::RuntimeException ) +{ + // must be implemented by subclass + osl::MutexGuard aLock( m_aMutex ); + throwIfDisposed(); +} + +void SAL_CALL +PopupMenuControllerBase::addStatusListener( + const Reference< XStatusListener >& xControl, + const URL& aURL ) +throw( ::com::sun::star::uno::RuntimeException ) +{ + osl::ResettableMutexGuard aLock( m_aMutex ); + throwIfDisposed(); + aLock.clear(); + + bool bStatusUpdate( false ); + rBHelper.addListener( ::getCppuType( &xControl ), xControl ); + + aLock.reset(); + if ( aURL.Complete.indexOf( m_aBaseURL ) == 0 ) + bStatusUpdate = true; + aLock.clear(); + + if ( bStatusUpdate ) + { + // Dummy update for popup menu controllers + FeatureStateEvent aEvent; + aEvent.FeatureURL = aURL; + aEvent.IsEnabled = sal_True; + aEvent.Requery = sal_False; + aEvent.State = Any(); + xControl->statusChanged( aEvent ); + } +} + +void SAL_CALL PopupMenuControllerBase::removeStatusListener( + const Reference< XStatusListener >& xControl, + const URL& /*aURL*/ ) +throw( ::com::sun::star::uno::RuntimeException ) +{ + rBHelper.removeListener( ::getCppuType( &xControl ), xControl ); +} + +::rtl::OUString PopupMenuControllerBase::determineBaseURL( const ::rtl::OUString& aURL ) +{ + // Just use the main part of the URL for popup menu controllers + sal_Int32 nQueryPart( 0 ); + sal_Int32 nSchemePart( 0 ); + rtl::OUString aMainURL( RTL_CONSTASCII_USTRINGPARAM( "vnd.sun.star.popup:" )); + + nSchemePart = aURL.indexOf( ':' ); + if (( nSchemePart > 0 ) && + ( aURL.getLength() > ( nSchemePart+1 ))) + { + nQueryPart = aURL.indexOf( '?', nSchemePart ); + if ( nQueryPart > 0 ) + aMainURL += aURL.copy( nSchemePart, nQueryPart-nSchemePart ); + else if ( nQueryPart == -1 ) + aMainURL += aURL.copy( nSchemePart+1 ); + } + + return aMainURL; +} + +// XInitialization +void SAL_CALL PopupMenuControllerBase::initialize( const Sequence< Any >& aArguments ) throw ( Exception, RuntimeException ) +{ + osl::MutexGuard aLock( m_aMutex ); + + sal_Bool bInitalized( m_bInitialized ); + if ( !bInitalized ) + { + PropertyValue aPropValue; + rtl::OUString aCommandURL; + Reference< XFrame > xFrame; + + for ( int i = 0; i < aArguments.getLength(); i++ ) + { + if ( aArguments[i] >>= aPropValue ) + { + if ( aPropValue.Name.equalsAscii( "Frame" )) + aPropValue.Value >>= xFrame; + else if ( aPropValue.Name.equalsAscii( "CommandURL" )) + aPropValue.Value >>= aCommandURL; + } + } + + if ( xFrame.is() && aCommandURL.getLength() ) + { + m_xFrame = xFrame; + m_aCommandURL = aCommandURL; + m_aBaseURL = determineBaseURL( aCommandURL ); + m_bInitialized = true; + } + } +} +// XPopupMenuController +void SAL_CALL PopupMenuControllerBase::setPopupMenu( const Reference< awt::XPopupMenu >& xPopupMenu ) throw ( RuntimeException ) +{ + osl::MutexGuard aLock( m_aMutex ); + throwIfDisposed(); + + if ( m_xFrame.is() && !m_xPopupMenu.is() ) + { + // Create popup menu on demand + vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() ); + + m_xPopupMenu = xPopupMenu; + m_xPopupMenu->addMenuListener( Reference< awt::XMenuListener >( (OWeakObject*)this, UNO_QUERY )); + + Reference< XDispatchProvider > xDispatchProvider( m_xFrame, UNO_QUERY ); + + URL aTargetURL; + aTargetURL.Complete = m_aCommandURL; + m_xURLTransformer->parseStrict( aTargetURL ); + m_xDispatch = xDispatchProvider->queryDispatch( aTargetURL, ::rtl::OUString(), 0 ); + + impl_setPopupMenu(); + + updatePopupMenu(); + } +} +void PopupMenuControllerBase::impl_setPopupMenu() +{ +} +} diff --git a/svtools/source/uno/popupwindowcontroller.cxx b/svtools/source/uno/popupwindowcontroller.cxx new file mode 100644 index 000000000000..4fbaff23714d --- /dev/null +++ b/svtools/source/uno/popupwindowcontroller.cxx @@ -0,0 +1,258 @@ +/************************************************************************* + * + * 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_svtools.hxx" + +#include <toolkit/helper/vclunohelper.hxx> + +#include <vcl/toolbox.hxx> +#include <vcl/svapp.hxx> + +#include "svtools/popupwindowcontroller.hxx" +#include "svtools/toolbarmenu.hxx" + +using rtl::OUString; +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::lang; + + +namespace svt +{ + +class PopupWindowControllerImpl +{ +public: + PopupWindowControllerImpl(); + ~PopupWindowControllerImpl(); + + void SetPopupWindow( ::Window* pPopupWindow, ToolBox* pToolBox ); + + DECL_LINK( WindowEventListener, VclSimpleEvent* ); + DECL_STATIC_LINK( PopupWindowControllerImpl, AsyncDeleteWindowHdl, Window* ); + +private: + ::Window* mpPopupWindow; + ToolBox* mpToolBox; +}; + +PopupWindowControllerImpl::PopupWindowControllerImpl() +: mpPopupWindow( 0 ) +, mpToolBox( 0 ) +{ +} + +PopupWindowControllerImpl::~PopupWindowControllerImpl() +{ + if( mpPopupWindow ) + SetPopupWindow(0,0); +} + +void PopupWindowControllerImpl::SetPopupWindow( ::Window* pPopupWindow, ToolBox* pToolBox ) +{ + if( mpPopupWindow ) + { + mpPopupWindow->RemoveEventListener( LINK( this, PopupWindowControllerImpl, WindowEventListener ) ); + Application::PostUserEvent( STATIC_LINK( this, PopupWindowControllerImpl, AsyncDeleteWindowHdl ), mpPopupWindow ); + } + mpPopupWindow = pPopupWindow; + mpToolBox = pToolBox; + + if( mpPopupWindow ) + { + mpPopupWindow->AddEventListener( LINK( this, PopupWindowControllerImpl, WindowEventListener )); + } +} + +IMPL_LINK( PopupWindowControllerImpl, WindowEventListener, VclSimpleEvent*, pEvent ) +{ + VclWindowEvent* pWindowEvent = dynamic_cast< VclWindowEvent* >( pEvent ); + if( pWindowEvent ) + { + switch( pWindowEvent->GetId() ) + { + case VCLEVENT_WINDOW_CLOSE: + case VCLEVENT_WINDOW_ENDPOPUPMODE: + SetPopupWindow(0,0); + break; + + case VCLEVENT_WINDOW_SHOW: + { + if( mpPopupWindow ) + { + if( mpToolBox ) + mpToolBox->CallEventListeners( VCLEVENT_DROPDOWN_OPEN, (void*)mpPopupWindow ); + mpPopupWindow->CallEventListeners( VCLEVENT_WINDOW_GETFOCUS, 0 ); + + svtools::ToolbarMenu* pToolbarMenu = dynamic_cast< svtools::ToolbarMenu* >( mpPopupWindow ); + if( pToolbarMenu ) + pToolbarMenu->highlightFirstEntry(); + break; + } + break; + } + case VCLEVENT_WINDOW_HIDE: + { + if( mpPopupWindow ) + { + mpPopupWindow->CallEventListeners( VCLEVENT_WINDOW_LOSEFOCUS, 0 ); + if( mpToolBox ) + mpToolBox->CallEventListeners( VCLEVENT_DROPDOWN_CLOSE, (void*)mpPopupWindow ); + } + break; + } + } + } + return 1; +} + +//-------------------------------------------------------------------- + +IMPL_STATIC_LINK( PopupWindowControllerImpl, AsyncDeleteWindowHdl, Window*, pWindow ) +{ + (void)*pThis; + delete pWindow; + return 0; +} + +//======================================================================== +// class PopupWindowController +//======================================================================== + +PopupWindowController::PopupWindowController( const Reference< lang::XMultiServiceFactory >& rServiceManager, + const Reference< frame::XFrame >& xFrame, + const OUString& aCommandURL ) +: svt::ToolboxController( rServiceManager, xFrame, aCommandURL ) +, mpImpl( new PopupWindowControllerImpl() ) +{ +} + +PopupWindowController::~PopupWindowController() +{ +} + +// XInterface +Any SAL_CALL PopupWindowController::queryInterface( const Type& aType ) +throw (RuntimeException) +{ + Any a( ToolboxController::queryInterface( aType ) ); + if ( a.hasValue() ) + return a; + + return ::cppu::queryInterface( aType, static_cast< lang::XServiceInfo* >( this )); +} + +void SAL_CALL PopupWindowController::acquire() throw () +{ + ToolboxController::acquire(); +} + +void SAL_CALL PopupWindowController::release() throw () +{ + ToolboxController::release(); +} + +// XServiceInfo +sal_Bool SAL_CALL PopupWindowController::supportsService( const OUString& ServiceName ) throw(RuntimeException) +{ + const Sequence< OUString > aSNL( getSupportedServiceNames() ); + const OUString * pArray = aSNL.getConstArray(); + + for( sal_Int32 i = 0; i < aSNL.getLength(); i++ ) + if( pArray[i] == ServiceName ) + return true; + + return false; +} + +// XInitialization +void SAL_CALL PopupWindowController::initialize( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aArguments ) throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException) +{ + svt::ToolboxController::initialize( aArguments ); + if( m_aCommandURL.getLength() ) + addStatusListener( m_aCommandURL ); +} + +// XComponent +void SAL_CALL PopupWindowController::dispose() throw (RuntimeException) +{ + if( m_aCommandURL.getLength() ) + removeStatusListener( m_aCommandURL ); + + svt::ToolboxController::dispose(); +} + + +// XStatusListener +void SAL_CALL PopupWindowController::statusChanged( const frame::FeatureStateEvent& rEvent ) throw ( RuntimeException ) +{ + svt::ToolboxController::statusChanged(rEvent); + enable( rEvent.IsEnabled ); +} + +// XToolbarController +void SAL_CALL PopupWindowController::execute( sal_Int16 KeyModifier ) throw (RuntimeException) +{ + svt::ToolboxController::execute( KeyModifier ); +} + +void SAL_CALL PopupWindowController::click() throw (RuntimeException) +{ + svt::ToolboxController::click(); +} + +void SAL_CALL PopupWindowController::doubleClick() throw (RuntimeException) +{ + svt::ToolboxController::doubleClick(); +} + +Reference< awt::XWindow > SAL_CALL PopupWindowController::createPopupWindow() throw (RuntimeException) +{ + ToolBox* pToolBox = dynamic_cast< ToolBox* >( VCLUnoHelper::GetWindow( getParent() ) ); + if( pToolBox ) + { + ::Window* pItemWindow = pToolBox->GetItemWindow( pToolBox->GetDownItemId() ); + ::Window* pWin = createPopupWindow( pItemWindow ? pItemWindow : pToolBox ); + if( pWin ) + { + pWin->EnableDocking(true); + mpImpl->SetPopupWindow(pWin,pToolBox); + ::Window::GetDockingManager()->StartPopupMode( pToolBox, pWin, FLOATWIN_POPUPMODE_NOFOCUSCLOSE|FLOATWIN_POPUPMODE_ALLMOUSEBUTTONCLOSE |FLOATWIN_POPUPMODE_NOMOUSEUPCLOSE ); + } + } + return Reference< awt::XWindow >(); +} + +Reference< awt::XWindow > SAL_CALL PopupWindowController::createItemWindow( const Reference< awt::XWindow >& /*Parent*/ ) + throw (RuntimeException) +{ + return Reference< awt::XWindow >(); +} + +} + diff --git a/svtools/source/uno/statusbarcontroller.cxx b/svtools/source/uno/statusbarcontroller.cxx new file mode 100644 index 000000000000..14b802a1bf90 --- /dev/null +++ b/svtools/source/uno/statusbarcontroller.cxx @@ -0,0 +1,784 @@ +/************************************************************************* + * + * 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_svtools.hxx" +#include <statusbarcontroller.hxx> +#include <com/sun/star/beans/PropertyValue.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/frame/XDispatchProvider.hpp> +#include <com/sun/star/lang/DisposedException.hpp> +#include <com/sun/star/frame/XLayoutManager.hpp> +#include <vos/mutex.hxx> +#include <vcl/svapp.hxx> +#include <vcl/window.hxx> +#include <vcl/status.hxx> +#include <imgdef.hxx> +#include <svtools/miscopt.hxx> +#ifndef _TOOLKIT_HELPER_VCLUNOHELPER_HXX_ +#include <toolkit/unohlp.hxx> +#endif + +using namespace ::cppu; +using namespace ::com::sun::star::awt; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::util; +using namespace ::com::sun::star::beans; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::frame; +using namespace ::com::sun::star::frame; + +namespace svt +{ + +StatusbarController::StatusbarController( + const Reference< XMultiServiceFactory >& rServiceManager, + const Reference< XFrame >& xFrame, + const ::rtl::OUString& aCommandURL, + unsigned short nID ) : + OWeakObject() + , m_bInitialized( sal_False ) + , m_bDisposed( sal_False ) + , m_nID( nID ) + , m_xFrame( xFrame ) + , m_xServiceManager( rServiceManager ) + , m_aCommandURL( aCommandURL ) + , m_aListenerContainer( m_aMutex ) +{ +} + +StatusbarController::StatusbarController() : + OWeakObject() + , m_bInitialized( sal_False ) + , m_bDisposed( sal_False ) + , m_nID( 0 ) + , m_aListenerContainer( m_aMutex ) +{ +} + +StatusbarController::~StatusbarController() +{ +} + +Reference< XFrame > StatusbarController::getFrameInterface() const +{ + vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() ); + return m_xFrame; +} + +Reference< XMultiServiceFactory > StatusbarController::getServiceManager() const +{ + vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() ); + return m_xServiceManager; +} + +Reference< XLayoutManager > StatusbarController::getLayoutManager() const +{ + vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() ); + Reference< XLayoutManager > xLayoutManager; + Reference< XPropertySet > xPropSet( m_xFrame, UNO_QUERY ); + if ( xPropSet.is() ) + { + try + { + Any a; + a = xPropSet->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "LayoutManager" ))); + a >>= xLayoutManager; + } + catch ( Exception& ) + { + } + } + + return xLayoutManager; +} + +Reference< XURLTransformer > StatusbarController::getURLTransformer() const +{ + vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() ); + if ( !m_xURLTransformer.is() && m_xServiceManager.is() ) + { + m_xURLTransformer = Reference< XURLTransformer >( + m_xServiceManager->createInstance( + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.util.URLTransformer" ))), + UNO_QUERY ); + } + + return m_xURLTransformer; +} + +// XInterface +Any SAL_CALL StatusbarController::queryInterface( const Type& rType ) +throw ( RuntimeException ) +{ + Any a = ::cppu::queryInterface( + rType , + static_cast< XStatusbarController* >( this ), + static_cast< XStatusListener* >( this ), + static_cast< XEventListener* >( this ), + static_cast< XInitialization* >( this ), + static_cast< XComponent* >( this ), + static_cast< XUpdatable* >( this )); + + if ( a.hasValue() ) + return a; + + return OWeakObject::queryInterface( rType ); +} + +void SAL_CALL StatusbarController::acquire() throw () +{ + OWeakObject::acquire(); +} + +void SAL_CALL StatusbarController::release() throw () +{ + OWeakObject::release(); +} + +void SAL_CALL StatusbarController::initialize( const Sequence< Any >& aArguments ) +throw ( Exception, RuntimeException ) +{ + const rtl::OUString aFrameName( RTL_CONSTASCII_USTRINGPARAM( "Frame" )); + const rtl::OUString aCommandURLName( RTL_CONSTASCII_USTRINGPARAM( "CommandURL" )); + const rtl::OUString aServiceManagerName( RTL_CONSTASCII_USTRINGPARAM( "ServiceManager" )); + const rtl::OUString aParentWindow( RTL_CONSTASCII_USTRINGPARAM( "ParentWindow" )); + const rtl::OUString aIdentifier( RTL_CONSTASCII_USTRINGPARAM( "Identifier" )); + + bool bInitialized( true ); + + { + vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() ); + + if ( m_bDisposed ) + throw DisposedException(); + + bInitialized = m_bInitialized; + } + + if ( !bInitialized ) + { + vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() ); + m_bInitialized = sal_True; + + PropertyValue aPropValue; + for ( int i = 0; i < aArguments.getLength(); i++ ) + { + if ( aArguments[i] >>= aPropValue ) + { + if ( aPropValue.Name.equalsAscii( "Frame" )) + aPropValue.Value >>= m_xFrame; + else if ( aPropValue.Name.equalsAscii( "CommandURL" )) + aPropValue.Value >>= m_aCommandURL; + else if ( aPropValue.Name.equalsAscii( "ServiceManager" )) + aPropValue.Value >>= m_xServiceManager; + else if ( aPropValue.Name.equalsAscii( "ParentWindow" )) + aPropValue.Value >>= m_xParentWindow; + else if ( aPropValue.Name.equalsAscii( "Identifier" )) + aPropValue.Value >>= m_nID; + } + } + + if ( m_aCommandURL.getLength() ) + m_aListenerMap.insert( URLToDispatchMap::value_type( m_aCommandURL, Reference< XDispatch >() )); + } +} + +void SAL_CALL StatusbarController::update() +throw ( RuntimeException ) +{ + { + vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() ); + if ( m_bDisposed ) + throw DisposedException(); + } + + // Bind all registered listeners to their dispatch objects + bindListener(); +} + +// XComponent +void SAL_CALL StatusbarController::dispose() +throw (::com::sun::star::uno::RuntimeException) +{ + Reference< XComponent > xThis( static_cast< OWeakObject* >(this), UNO_QUERY ); + + { + vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() ); + if ( m_bDisposed ) + throw DisposedException(); + } + + com::sun::star::lang::EventObject aEvent( xThis ); + m_aListenerContainer.disposeAndClear( aEvent ); + + vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() ); + Reference< XStatusListener > xStatusListener( static_cast< OWeakObject* >( this ), UNO_QUERY ); + Reference< XURLTransformer > xURLTransformer = getURLTransformer(); + URLToDispatchMap::iterator pIter = m_aListenerMap.begin(); + com::sun::star::util::URL aTargetURL; + while ( pIter != m_aListenerMap.end() ) + { + try + { + Reference< XDispatch > xDispatch( pIter->second ); + aTargetURL.Complete = pIter->first; + xURLTransformer->parseStrict( aTargetURL ); + + if ( xDispatch.is() && xStatusListener.is() ) + xDispatch->removeStatusListener( xStatusListener, aTargetURL ); + } + catch ( Exception& ) + { + } + + ++pIter; + } + + // clear hash map + m_aListenerMap.clear(); + + // release references + m_xURLTransformer.clear(); + m_xServiceManager.clear(); + m_xFrame.clear(); + m_xParentWindow.clear(); + + m_bDisposed = sal_True; +} + +void SAL_CALL StatusbarController::addEventListener( const Reference< XEventListener >& xListener ) +throw ( RuntimeException ) +{ + m_aListenerContainer.addInterface( ::getCppuType( ( const Reference< XEventListener >* ) NULL ), xListener ); +} + +void SAL_CALL StatusbarController::removeEventListener( const Reference< XEventListener >& aListener ) +throw ( RuntimeException ) +{ + m_aListenerContainer.removeInterface( ::getCppuType( ( const Reference< XEventListener >* ) NULL ), aListener ); +} + +// XEventListener +void SAL_CALL StatusbarController::disposing( const EventObject& Source ) +throw ( RuntimeException ) +{ + Reference< XInterface > xSource( Source.Source ); + + vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() ); + + if ( m_bDisposed ) + return; + + URLToDispatchMap::iterator pIter = m_aListenerMap.begin(); + while ( pIter != m_aListenerMap.end() ) + { + // Compare references and release dispatch references if they are equal. + Reference< XInterface > xIfac( pIter->second, UNO_QUERY ); + if ( xSource == xIfac ) + pIter->second.clear(); + pIter++; + } + + Reference< XInterface > xIfac( m_xFrame, UNO_QUERY ); + if ( xIfac == xSource ) + m_xFrame.clear(); +} + +// XStatusListener +void SAL_CALL StatusbarController::statusChanged( const FeatureStateEvent& Event ) +throw ( RuntimeException ) +{ + vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() ); + + if ( m_bDisposed ) + return; + + Window* pWindow = VCLUnoHelper::GetWindow( m_xParentWindow ); + if ( pWindow && pWindow->GetType() == WINDOW_STATUSBAR && m_nID != 0 ) + { + rtl::OUString aStrValue; + StatusBar* pStatusBar = (StatusBar *)pWindow; + + if ( Event.State >>= aStrValue ) + pStatusBar->SetItemText( m_nID, aStrValue ); + else if ( !Event.State.hasValue() ) + pStatusBar->SetItemText( m_nID, String() ); + } +} + +// XStatusbarController +::sal_Bool SAL_CALL StatusbarController::mouseButtonDown( + const ::com::sun::star::awt::MouseEvent& ) +throw (::com::sun::star::uno::RuntimeException) +{ + return sal_False; +} + +::sal_Bool SAL_CALL StatusbarController::mouseMove( + const ::com::sun::star::awt::MouseEvent& ) +throw (::com::sun::star::uno::RuntimeException) +{ + return sal_False; +} + +::sal_Bool SAL_CALL StatusbarController::mouseButtonUp( + const ::com::sun::star::awt::MouseEvent& ) +throw (::com::sun::star::uno::RuntimeException) +{ + return sal_False; +} + +void SAL_CALL StatusbarController::command( + const ::com::sun::star::awt::Point&, + ::sal_Int32, + ::sal_Bool, + const ::com::sun::star::uno::Any& ) +throw (::com::sun::star::uno::RuntimeException) +{ +} + +void SAL_CALL StatusbarController::paint( + const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XGraphics >&, + const ::com::sun::star::awt::Rectangle&, + ::sal_Int32, + ::sal_Int32 ) +throw (::com::sun::star::uno::RuntimeException) +{ +} + +void SAL_CALL StatusbarController::click() +throw (::com::sun::star::uno::RuntimeException) +{ +} + +void SAL_CALL StatusbarController::doubleClick() throw (::com::sun::star::uno::RuntimeException) +{ + vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() ); + + if ( m_bDisposed ) + return; + + Sequence< PropertyValue > aArgs; + execute( aArgs ); +} + +void StatusbarController::addStatusListener( const rtl::OUString& aCommandURL ) +{ + Reference< XDispatch > xDispatch; + Reference< XStatusListener > xStatusListener; + com::sun::star::util::URL aTargetURL; + + { + vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() ); + URLToDispatchMap::iterator pIter = m_aListenerMap.find( aCommandURL ); + + // Already in the list of status listener. Do nothing. + if ( pIter != m_aListenerMap.end() ) + return; + + // Check if we are already initialized. Implementation starts adding itself as status listener when + // intialize is called. + if ( !m_bInitialized ) + { + // Put into the hash_map of status listener. Will be activated when initialized is called + m_aListenerMap.insert( URLToDispatchMap::value_type( aCommandURL, Reference< XDispatch >() )); + return; + } + else + { + // Add status listener directly as intialize has already been called. + Reference< XDispatchProvider > xDispatchProvider( m_xFrame, UNO_QUERY ); + if ( m_xServiceManager.is() && xDispatchProvider.is() ) + { + Reference< XURLTransformer > xURLTransformer = getURLTransformer(); + aTargetURL.Complete = aCommandURL; + xURLTransformer->parseStrict( aTargetURL ); + xDispatch = xDispatchProvider->queryDispatch( aTargetURL, ::rtl::OUString(), 0 ); + + xStatusListener = Reference< XStatusListener >( static_cast< OWeakObject* >( this ), UNO_QUERY ); + URLToDispatchMap::iterator aIter = m_aListenerMap.find( aCommandURL ); + if ( aIter != m_aListenerMap.end() ) + { + Reference< XDispatch > xOldDispatch( aIter->second ); + aIter->second = xDispatch; + + try + { + if ( xOldDispatch.is() ) + xOldDispatch->removeStatusListener( xStatusListener, aTargetURL ); + } + catch ( Exception& ) + { + } + } + else + m_aListenerMap.insert( URLToDispatchMap::value_type( aCommandURL, xDispatch )); + } + } + } + + // Call without locked mutex as we are called back from dispatch implementation + try + { + if ( xDispatch.is() ) + xDispatch->addStatusListener( xStatusListener, aTargetURL ); + } + catch ( Exception& ) + { + } +} + +void StatusbarController::removeStatusListener( const rtl::OUString& aCommandURL ) +{ + vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() ); + + URLToDispatchMap::iterator pIter = m_aListenerMap.find( aCommandURL ); + if ( pIter != m_aListenerMap.end() ) + { + Reference< XDispatch > xDispatch( pIter->second ); + Reference< XStatusListener > xStatusListener( static_cast< OWeakObject* >( this ), UNO_QUERY ); + m_aListenerMap.erase( pIter ); + + try + { + Reference< XURLTransformer > xURLTransformer = getURLTransformer(); + com::sun::star::util::URL aTargetURL; + aTargetURL.Complete = aCommandURL; + xURLTransformer->parseStrict( aTargetURL ); + + if ( xDispatch.is() && xStatusListener.is() ) + xDispatch->removeStatusListener( xStatusListener, aTargetURL ); + } + catch ( Exception& ) + { + } + } +} + +void StatusbarController::bindListener() +{ + std::vector< Listener > aDispatchVector; + Reference< XStatusListener > xStatusListener; + + { + vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() ); + + if ( !m_bInitialized ) + return; + + // Collect all registered command URL's and store them temporary + Reference< XDispatchProvider > xDispatchProvider( m_xFrame, UNO_QUERY ); + if ( m_xServiceManager.is() && xDispatchProvider.is() ) + { + xStatusListener = Reference< XStatusListener >( static_cast< OWeakObject* >( this ), UNO_QUERY ); + URLToDispatchMap::iterator pIter = m_aListenerMap.begin(); + while ( pIter != m_aListenerMap.end() ) + { + Reference< XURLTransformer > xURLTransformer = getURLTransformer(); + com::sun::star::util::URL aTargetURL; + aTargetURL.Complete = pIter->first; + xURLTransformer->parseStrict( aTargetURL ); + + Reference< XDispatch > xDispatch( pIter->second ); + if ( xDispatch.is() ) + { + // We already have a dispatch object => we have to requery. + // Release old dispatch object and remove it as listener + try + { + xDispatch->removeStatusListener( xStatusListener, aTargetURL ); + } + catch ( Exception& ) + { + } + } + + pIter->second.clear(); + xDispatch.clear(); + + // Query for dispatch object. Old dispatch will be released with this, too. + try + { + xDispatch = xDispatchProvider->queryDispatch( aTargetURL, ::rtl::OUString(), 0 ); + } + catch ( Exception& ) + { + } + pIter->second = xDispatch; + + Listener aListener( aTargetURL, xDispatch ); + aDispatchVector.push_back( aListener ); + ++pIter; + } + } + } + + // Call without locked mutex as we are called back from dispatch implementation + if ( xStatusListener.is() ) + { + try + { + for ( sal_uInt32 i = 0; i < aDispatchVector.size(); i++ ) + { + Listener& rListener = aDispatchVector[i]; + if ( rListener.xDispatch.is() ) + rListener.xDispatch->addStatusListener( xStatusListener, rListener.aURL ); + else if ( rListener.aURL.Complete == m_aCommandURL ) + { + try + { + // Send status changed for the main URL, if we cannot get a valid dispatch object. + // UI disables the button. Catch exception as we release our mutex, it is possible + // that someone else already disposed this instance! + FeatureStateEvent aFeatureStateEvent; + aFeatureStateEvent.IsEnabled = sal_False; + aFeatureStateEvent.FeatureURL = rListener.aURL; + aFeatureStateEvent.State = Any(); + xStatusListener->statusChanged( aFeatureStateEvent ); + } + catch ( Exception& ) + { + } + } + } + } + catch ( Exception& ) + { + } + } +} + +void StatusbarController::unbindListener() +{ + vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() ); + + if ( !m_bInitialized ) + return; + + // Collect all registered command URL's and store them temporary + Reference< XDispatchProvider > xDispatchProvider( m_xFrame, UNO_QUERY ); + if ( m_xServiceManager.is() && xDispatchProvider.is() ) + { + Reference< XStatusListener > xStatusListener( static_cast< OWeakObject* >( this ), UNO_QUERY ); + URLToDispatchMap::iterator pIter = m_aListenerMap.begin(); + while ( pIter != m_aListenerMap.end() ) + { + Reference< XURLTransformer > xURLTransformer = getURLTransformer(); + com::sun::star::util::URL aTargetURL; + aTargetURL.Complete = pIter->first; + xURLTransformer->parseStrict( aTargetURL ); + + Reference< XDispatch > xDispatch( pIter->second ); + if ( xDispatch.is() ) + { + // We already have a dispatch object => we have to requery. + // Release old dispatch object and remove it as listener + try + { + xDispatch->removeStatusListener( xStatusListener, aTargetURL ); + } + catch ( Exception& ) + { + } + } + pIter->second.clear(); + ++pIter; + } + } +} + +sal_Bool StatusbarController::isBound() const +{ + vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() ); + + if ( !m_bInitialized ) + return sal_False; + + URLToDispatchMap::const_iterator pIter = m_aListenerMap.find( m_aCommandURL ); + if ( pIter != m_aListenerMap.end() ) + return ( pIter->second.is() ); + + return sal_False; +} + +void StatusbarController::updateStatus() +{ + bindListener(); +} + +void StatusbarController::updateStatus( const rtl::OUString aCommandURL ) +{ + Reference< XDispatch > xDispatch; + Reference< XStatusListener > xStatusListener; + com::sun::star::util::URL aTargetURL; + + { + vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() ); + + if ( !m_bInitialized ) + return; + + // Try to find a dispatch object for the requested command URL + Reference< XDispatchProvider > xDispatchProvider( m_xFrame, UNO_QUERY ); + xStatusListener = Reference< XStatusListener >( static_cast< OWeakObject* >( this ), UNO_QUERY ); + if ( m_xServiceManager.is() && xDispatchProvider.is() ) + { + Reference< XURLTransformer > xURLTransformer = getURLTransformer(); + aTargetURL.Complete = aCommandURL; + xURLTransformer->parseStrict( aTargetURL ); + xDispatch = xDispatchProvider->queryDispatch( aTargetURL, rtl::OUString(), 0 ); + } + } + + if ( xDispatch.is() && xStatusListener.is() ) + { + // Catch exception as we release our mutex, it is possible that someone else + // has already disposed this instance! + // Add/remove status listener to get a update status information from the + // requested command. + try + { + xDispatch->addStatusListener( xStatusListener, aTargetURL ); + xDispatch->removeStatusListener( xStatusListener, aTargetURL ); + } + catch ( Exception& ) + { + } + } +} + +::Rectangle StatusbarController::getControlRect() const +{ + ::Rectangle aRect; + + { + vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() ); + + if ( m_bDisposed ) + throw DisposedException(); + + if ( m_xParentWindow.is() ) + { + StatusBar* pStatusBar = dynamic_cast< StatusBar* >( VCLUnoHelper::GetWindow( m_xParentWindow )); + if ( pStatusBar && pStatusBar->GetType() == WINDOW_STATUSBAR ) + aRect = pStatusBar->GetItemRect( m_nID ); + } + } + + return aRect; +} + +void StatusbarController::execute( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& aArgs ) +{ + Reference< XDispatch > xDispatch; + Reference< XURLTransformer > xURLTransformer; + rtl::OUString aCommandURL; + + { + vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() ); + + if ( m_bDisposed ) + throw DisposedException(); + + if ( m_bInitialized && + m_xFrame.is() && + m_xServiceManager.is() && + m_aCommandURL.getLength() ) + { + xURLTransformer = getURLTransformer(); + aCommandURL = m_aCommandURL; + URLToDispatchMap::iterator pIter = m_aListenerMap.find( m_aCommandURL ); + if ( pIter != m_aListenerMap.end() ) + xDispatch = pIter->second; + } + } + + if ( xDispatch.is() && xURLTransformer.is() ) + { + try + { + com::sun::star::util::URL aTargetURL; + + aTargetURL.Complete = aCommandURL; + xURLTransformer->parseStrict( aTargetURL ); + xDispatch->dispatch( aTargetURL, aArgs ); + } + catch ( DisposedException& ) + { + } + } +} + +void StatusbarController::execute( + const rtl::OUString& aCommandURL, + const Sequence< ::com::sun::star::beans::PropertyValue >& aArgs ) +{ + Reference< XDispatch > xDispatch; + com::sun::star::util::URL aTargetURL; + + { + vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() ); + + if ( m_bDisposed ) + throw DisposedException(); + + if ( m_bInitialized && + m_xFrame.is() && + m_xServiceManager.is() && + m_aCommandURL.getLength() ) + { + Reference< XURLTransformer > xURLTransformer( getURLTransformer() ); + aTargetURL.Complete = aCommandURL; + xURLTransformer->parseStrict( aTargetURL ); + + URLToDispatchMap::iterator pIter = m_aListenerMap.find( aCommandURL ); + if ( pIter != m_aListenerMap.end() ) + xDispatch = pIter->second; + else + { + Reference< ::com::sun::star::frame::XDispatchProvider > xDispatchProvider( + m_xFrame->getController(), UNO_QUERY ); + if ( xDispatchProvider.is() ) + xDispatch = xDispatchProvider->queryDispatch( aTargetURL, ::rtl::OUString(), 0 ); + } + } + } + + if ( xDispatch.is() ) + { + try + { + xDispatch->dispatch( aTargetURL, aArgs ); + } + catch ( DisposedException& ) + { + } + } +} + +} // svt diff --git a/svtools/source/uno/svtxgridcontrol.cxx b/svtools/source/uno/svtxgridcontrol.cxx new file mode 100755 index 000000000000..f5bc837f60b0 --- /dev/null +++ b/svtools/source/uno/svtxgridcontrol.cxx @@ -0,0 +1,899 @@ +/************************************************************************* + * + * 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_svtools.hxx" + +#include "svtxgridcontrol.hxx" +#include "accessibletableimp.hxx" +#include <com/sun/star/view/SelectionType.hpp> +#include "svtools/table/gridtablerenderer.hxx" +#include "svtools/table/defaultinputhandler.hxx" +#include "svtools/table/tablecontrol.hxx" +#include "unocontroltablemodel.hxx" +#include <comphelper/sequence.hxx> +#include <rtl/ref.hxx> +#include <tools/debug.hxx> +#include <toolkit/helper/property.hxx> +#include <toolkit/helper/vclunohelper.hxx> +#include <comphelper/processfactory.hxx> +#include <com/sun/star/awt/grid/XGridColumn.hpp> +#include <com/sun/star/accessibility/AccessibleTableModelChange.hpp> +#include <com/sun/star/accessibility/AccessibleTableModelChangeType.hpp> +#include <com/sun/star/accessibility/AccessibleEventId.hpp> +#include <com/sun/star/awt/XControl.hpp> +#include <com/sun/star/awt/grid/GridInvalidDataException.hpp> +#include <com/sun/star/awt/grid/GridInvalidModelException.hpp> +#include <com/sun/star/util/Color.hpp> +#include <com/sun/star/awt/FontDescriptor.hpp> + +using ::rtl::OUString; +using namespace ::svt::table; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::awt::grid; +using namespace ::com::sun::star::view; +using namespace ::toolkit; +using namespace ::com::sun::star::accessibility; +using namespace ::com::sun::star::accessibility::AccessibleEventId; +using namespace ::com::sun::star::accessibility::AccessibleTableModelChangeType; +using ::com::sun::star::accessibility::AccessibleTableModelChange; + + +SVTXGridControl::SVTXGridControl() + :m_pTableModel (new UnoControlTableModel()), + m_xDataModel(0), + m_xColumnModel(0), + m_bHasColumnHeaders(false), + m_bHasRowHeaders(false), + m_bVScroll(false), + m_bHScroll(false), + m_bUpdate(false), + m_nSelectedRowCount(0), + m_aSelectionListeners( *this ) +{ +} + +//-------------------------------------------------------------------- +SVTXGridControl::~SVTXGridControl() +{ +} + +::com::sun::star::uno::Any SVTXGridControl::queryInterface( const ::com::sun::star::uno::Type & rType ) throw(::com::sun::star::uno::RuntimeException) +{ + ::com::sun::star::uno::Any aRet = ::cppu::queryInterface( rType, + SAL_STATIC_CAST( ::com::sun::star::awt::grid::XGridControl*, this ), + SAL_STATIC_CAST( ::com::sun::star::awt::grid::XGridDataListener*, this ), + SAL_STATIC_CAST( ::com::sun::star::awt::grid::XGridColumnListener*, this ), + SAL_STATIC_CAST( ::com::sun::star::lang::XTypeProvider*, this ) ); + return (aRet.hasValue() ? aRet : VCLXWindow::queryInterface( rType )); +} + +// ::com::sun::star::lang::XTypeProvider +IMPL_XTYPEPROVIDER_START( SVTXGridControl ) + getCppuType( ( ::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridControl>* ) NULL ), + getCppuType( ( ::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridDataModel>* ) NULL ), + getCppuType( ( ::com::sun::star::uno::Reference< ::com::sun::star::awt::XMouseListener>* ) NULL ), + VCLXWindow::getTypes() +IMPL_XTYPEPROVIDER_END + +sal_Int32 SAL_CALL SVTXGridControl::getItemIndexAtPoint(::sal_Int32 x, ::sal_Int32 y) throw (::com::sun::star::uno::RuntimeException) +{ + TableControl* pTable = (TableControl*)GetWindow(); + return pTable->GetCurrentRow( Point(x,y) ); +} + +void SAL_CALL SVTXGridControl::setToolTip(const ::com::sun::star::uno::Sequence< ::rtl::OUString >& text, const com::sun::star::uno::Sequence< sal_Int32 >& columns) throw (::com::sun::star::uno::RuntimeException) +{ + TableControl* pTable = (TableControl*)GetWindow(); + pTable->setTooltip(text, columns); +} + +void SAL_CALL SVTXGridControl::addSelectionListener(const ::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridSelectionListener > & listener) throw (::com::sun::star::uno::RuntimeException) +{ + m_aSelectionListeners.addInterface(listener); +} + +void SAL_CALL SVTXGridControl::removeSelectionListener(const ::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridSelectionListener > & listener) throw (::com::sun::star::uno::RuntimeException) +{ + m_aSelectionListeners.removeInterface(listener); +} + +void SVTXGridControl::setProperty( const ::rtl::OUString& PropertyName, const Any& aValue) throw(RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + TableControl* pTable = (TableControl*)GetWindow(); + switch( GetPropertyId( PropertyName ) ) + { + case BASEPROPERTY_BACKGROUNDCOLOR: + { + // let the base class handle this for the TableControl + VCLXWindow::setProperty( PropertyName, aValue ); + // and forward to the grid control's data window + if ( pTable->IsBackground() ) + pTable->getDataWindow()->SetBackground( pTable->GetBackground() ); + else + pTable->getDataWindow()->SetBackground(); + } + break; + + case BASEPROPERTY_GRID_SELECTIONMODE: + { + SelectionType eSelectionType; + if( aValue >>= eSelectionType ) + { + SelectionMode eSelMode; + switch( eSelectionType ) + { + case SelectionType_SINGLE: eSelMode = SINGLE_SELECTION; break; + case SelectionType_RANGE: eSelMode = RANGE_SELECTION; break; + case SelectionType_MULTI: eSelMode = MULTIPLE_SELECTION; break; + // case SelectionType_NONE: + default: eSelMode = NO_SELECTION; break; + } + if( pTable->getSelEngine()->GetSelectionMode() != eSelMode ) + pTable->getSelEngine()->SetSelectionMode( eSelMode ); + } + break; + } + case BASEPROPERTY_HSCROLL: + { + sal_Bool bHScroll = true; + if( aValue >>= bHScroll ) + { + m_bHScroll = bHScroll; + m_pTableModel->setHorizontalScrollbarVisibility(bHScroll); + } + break; + } + case BASEPROPERTY_VSCROLL: + { + sal_Bool bVScroll = true; + if( aValue >>= bVScroll ) + { + m_bVScroll = bVScroll; + m_pTableModel->setVerticalScrollbarVisibility(bVScroll); + } + break; + } + + case BASEPROPERTY_GRID_SHOWROWHEADER: + { + sal_Bool rowHeader = true; + if( aValue >>= rowHeader ) + { + m_pTableModel->setRowHeaders(rowHeader); + } + break; + } + case BASEPROPERTY_GRID_HEADER_BACKGROUND: + { + sal_Int32 colorHeader = 0xFFFFFF; + if( aValue >>= colorHeader ) + { + m_pTableModel->setHeaderBackgroundColor(colorHeader); + } + break; + } + case BASEPROPERTY_GRID_LINE_COLOR: + { + sal_Int32 colorLine = 0xFFFFFF; + if( aValue >>= colorLine ) + { + m_pTableModel->setLineColor(colorLine); + } + break; + } + case BASEPROPERTY_GRID_EVEN_ROW_BACKGROUND: + { + sal_Int32 colorEvenRow = 0xFFFFFF; + if( aValue >>= colorEvenRow ) + { + m_pTableModel->setEvenRowBackgroundColor(colorEvenRow); + } + break; + } + case BASEPROPERTY_GRID_ROW_BACKGROUND: + { + sal_Int32 colorBackground = 0xFFFFFF; + if( aValue >>= colorBackground ) + { + m_pTableModel->setOddRowBackgroundColor(colorBackground); + } + break; + } + case BASEPROPERTY_TEXTCOLOR: + { + sal_Int32 colorText = 0x000000; + if( aValue >>= colorText ) + { + m_pTableModel->setTextColor(colorText); + } + break; + } + case BASEPROPERTY_VERTICALALIGN: + { + com::sun::star::style::VerticalAlignment vAlign(com::sun::star::style::VerticalAlignment(0)); + if( aValue >>= vAlign ) + { + switch( vAlign ) + { + case com::sun::star::style::VerticalAlignment_TOP: m_pTableModel->setVerticalAlign(com::sun::star::style::VerticalAlignment(0)); break; + case com::sun::star::style::VerticalAlignment_MIDDLE: m_pTableModel->setVerticalAlign(com::sun::star::style::VerticalAlignment(1)); break; + case com::sun::star::style::VerticalAlignment_BOTTOM: m_pTableModel->setVerticalAlign(com::sun::star::style::VerticalAlignment(2)); break; + default: m_pTableModel->setVerticalAlign(com::sun::star::style::VerticalAlignment(0)); break; + } + } + break; + } + + case BASEPROPERTY_GRID_SHOWCOLUMNHEADER: + { + sal_Bool colHeader = true; + if( aValue >>= colHeader ) + { + m_pTableModel->setColumnHeaders(colHeader); + } + break; + } + case BASEPROPERTY_GRID_DATAMODEL: + { + { + m_xDataModel = Reference< XGridDataModel >( aValue, UNO_QUERY ); + if(m_xDataModel != NULL) + { + Sequence<Sequence< Any > > cellData = m_xDataModel->getData(); + if(cellData.getLength()!= 0) + { + for (int i = 0; i < cellData.getLength(); i++) + { + std::vector< Any > newRow; + Sequence< Any > rawRowData = cellData[i]; + //check whether the data row vector length matches with the column count + if(m_xColumnModel->getColumnCount() == 0) + { + for ( ::svt::table::ColPos col = 0; col < rawRowData.getLength(); ++col ) + { + UnoControlTableColumn* tableColumn = new UnoControlTableColumn(); + m_pTableModel->getColumnModel().push_back((PColumnModel)tableColumn); + } + m_xColumnModel->setDefaultColumns(rawRowData.getLength()); + } + else + if((unsigned int)rawRowData.getLength()!=(unsigned)m_pTableModel->getColumnCount()) + throw GridInvalidDataException(rtl::OUString::createFromAscii("The column count doesn't match with the length of row data"), m_xDataModel); + + for ( int k = 0; k < rawRowData.getLength(); k++) + { + newRow.push_back(rawRowData[k]); + } + m_pTableModel->getCellContent().push_back(newRow); + } + + Sequence< ::rtl::OUString > rowHeaders = m_xDataModel->getRowHeaders(); + std::vector< rtl::OUString > newRow( + comphelper::sequenceToContainer< std::vector<rtl::OUString > >(rowHeaders)); + m_pTableModel->setRowCount(m_xDataModel->getRowCount()); + m_pTableModel->setRowHeaderName(newRow); + } + } + else + throw GridInvalidDataException(rtl::OUString::createFromAscii("The data model isn't set!"), m_xDataModel); + sal_Int32 fontHeight = pTable->PixelToLogic( Size( 0, pTable->GetTextHeight()+3 ), MAP_APPFONT ).Height(); + if(m_xDataModel->getRowHeight() == 0) + { + m_pTableModel->setRowHeight(fontHeight); + m_xDataModel->setRowHeight(fontHeight); + } + else + m_pTableModel->setRowHeight(m_xDataModel->getRowHeight()); + m_pTableModel->setRowHeaderWidth(m_xDataModel->getRowHeaderWidth()); + } + break; + } + case BASEPROPERTY_GRID_COLUMNMODEL: + { + m_xColumnModel = Reference< XGridColumnModel >( aValue, UNO_QUERY ); + if(m_xColumnModel != NULL) + { + if(m_xColumnModel->getColumnCount() != 0) + { + Sequence<Reference< XGridColumn > > columns = m_xColumnModel->getColumns(); + std::vector<Reference< XGridColumn > > aNewColumns( + comphelper::sequenceToContainer<std::vector<Reference< XGridColumn > > >(columns)); + sal_Int32 fontHeight = pTable->PixelToLogic( Size( 0, pTable->GetTextHeight()+3 ), MAP_APPFONT ).Height(); + if(m_xColumnModel->getColumnHeaderHeight() == 0) + { + m_pTableModel->setColumnHeaderHeight(fontHeight); + m_xColumnModel->setColumnHeaderHeight(fontHeight); + } + else + m_pTableModel->setColumnHeaderHeight(m_xColumnModel->getColumnHeaderHeight()); + for ( ::svt::table::ColPos col = 0; col < m_xColumnModel->getColumnCount(); ++col ) + { + UnoControlTableColumn* tableColumn = new UnoControlTableColumn(aNewColumns[col]); + Reference< XGridColumn > xGridColumn = m_xColumnModel->getColumn(col); + m_pTableModel->getColumnModel().push_back((PColumnModel)tableColumn); + tableColumn->setHorizontalAlign(xGridColumn->getHorizontalAlign()); + tableColumn->setWidth(xGridColumn->getColumnWidth()); + if(xGridColumn->getPreferredWidth() != 0) + tableColumn->setPreferredWidth(xGridColumn->getPreferredWidth()); + if(xGridColumn->getMaxWidth() != 0) + tableColumn->setMaxWidth(xGridColumn->getMaxWidth()); + if(xGridColumn->getMinWidth() != 0) + tableColumn->setMinWidth(xGridColumn->getMinWidth()); + tableColumn->setResizable(xGridColumn->getResizeable()); + } + } + } + else + throw GridInvalidModelException(rtl::OUString::createFromAscii("The column model isn't set!"), m_xColumnModel); + + break; + } + default: + VCLXWindow::setProperty( PropertyName, aValue ); + break; + } +} + +Any SVTXGridControl::getProperty( const ::rtl::OUString& PropertyName ) throw(RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + const sal_uInt16 nPropId = GetPropertyId( PropertyName ); + TableControl* pTable = (TableControl*)GetWindow(); + if(pTable) + { + switch(nPropId) + { + case BASEPROPERTY_GRID_SELECTIONMODE: + { + SelectionType eSelectionType; + + SelectionMode eSelMode = pTable->getSelEngine()->GetSelectionMode(); + switch( eSelMode ) + { + case SINGLE_SELECTION: eSelectionType = SelectionType_SINGLE; break; + case RANGE_SELECTION: eSelectionType = SelectionType_RANGE; break; + case MULTIPLE_SELECTION:eSelectionType = SelectionType_MULTI; break; +// case NO_SELECTION: + default: eSelectionType = SelectionType_NONE; break; + } + return Any( eSelectionType ); + } + case BASEPROPERTY_GRID_SHOWROWHEADER: + { + return Any ((sal_Bool) m_pTableModel->hasRowHeaders()); + } + case BASEPROPERTY_GRID_SHOWCOLUMNHEADER: + return Any ((sal_Bool) m_pTableModel->hasColumnHeaders()); + case BASEPROPERTY_GRID_DATAMODEL: + return Any ( m_xDataModel ); + case BASEPROPERTY_GRID_COLUMNMODEL: + return Any ( m_xColumnModel); + case BASEPROPERTY_HSCROLL: + return Any ( m_bHScroll); + case BASEPROPERTY_VSCROLL: + return Any ( m_bVScroll); + } + } + return VCLXWindow::getProperty( PropertyName ); +} + +void SVTXGridControl::ImplGetPropertyIds( std::list< sal_uInt16 > &rIds ) +{ + PushPropertyIds( rIds, + BASEPROPERTY_GRID_SHOWROWHEADER, + BASEPROPERTY_GRID_SHOWCOLUMNHEADER, + BASEPROPERTY_GRID_DATAMODEL, + BASEPROPERTY_GRID_COLUMNMODEL, + BASEPROPERTY_GRID_SELECTIONMODE, + BASEPROPERTY_GRID_EVEN_ROW_BACKGROUND, + BASEPROPERTY_GRID_HEADER_BACKGROUND, + BASEPROPERTY_GRID_LINE_COLOR, + BASEPROPERTY_GRID_ROW_BACKGROUND, + 0); + VCLXWindow::ImplGetPropertyIds( rIds, true ); +} +void SAL_CALL SVTXGridControl::setVisible( sal_Bool bVisible ) throw(::com::sun::star::uno::RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + TableControl* pTable = (TableControl*)GetWindow(); + if ( pTable ) + { + pTable->SetModel(PTableModel(m_pTableModel)); + pTable->Show( bVisible ); + } +} +void SAL_CALL SVTXGridControl::setFocus() throw(::com::sun::star::uno::RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + if ( GetWindow()) + GetWindow()->GrabFocus(); +} +void SAL_CALL SVTXGridControl::rowAdded(const ::com::sun::star::awt::grid::GridDataEvent& Event ) throw (::com::sun::star::uno::RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + std::vector< Any > newRow; + Sequence< Any > rawRowData = Event.rowData; + int colCount = m_xColumnModel->getColumnCount(); + if(colCount == 0) + { + Reference<XGridColumnListener> listener(*this,UNO_QUERY_THROW); + m_xColumnModel->setDefaultColumns(rawRowData.getLength()); + for ( ::svt::table::ColPos col = 0; col < rawRowData.getLength(); ++col ) + { + UnoControlTableColumn* tableColumn = new UnoControlTableColumn(); + m_pTableModel->getColumnModel().push_back((PColumnModel)tableColumn); + m_xColumnModel->getColumn(col)->addColumnListener(listener); + } + + } + else if((unsigned int)rawRowData.getLength()!=(unsigned)colCount) + throw GridInvalidDataException(rtl::OUString::createFromAscii("The column count doesn't match with the length of row data"), m_xDataModel); + + for ( int k = 0; k < rawRowData.getLength(); k++) + newRow.push_back(rawRowData[k]); + m_pTableModel->getCellContent().push_back(newRow); + if(m_pTableModel->hasRowHeaders()) + m_pTableModel->getRowHeaderName().push_back(Event.headerName); + m_pTableModel->setRowCount(m_pTableModel->getCellContent().size()); + TableControl* pTable = (TableControl*)GetWindow(); + pTable->InvalidateDataWindow(m_pTableModel->getCellContent().size()-1, 0, false); + if(pTable->isAccessibleAlive()) + { + pTable->commitGridControlEvent(TABLE_MODEL_CHANGED, + makeAny( AccessibleTableModelChange(INSERT, m_pTableModel->getRowCount()-1, m_pTableModel->getRowCount(), 0, m_pTableModel->getColumnCount())), + Any()); + pTable->commitGridControlEvent(CHILD, + makeAny( pTable->m_pAccessTable->m_pAccessible->getTableHeader(TCTYPE_ROWHEADERBAR)), + Any()); + for (sal_Int32 i = 0 ; i <= m_pTableModel->getColumnCount() ; ++i) + { + pTable->commitGridControlEvent( + CHILD, + makeAny( pTable->m_pAccessTable->m_pAccessible->getTable() ), + Any()); + } + } +} + +void SAL_CALL SVTXGridControl::rowRemoved(const ::com::sun::star::awt::grid::GridDataEvent& Event ) throw (::com::sun::star::uno::RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + TableControl* pTable = (TableControl*)GetWindow(); + if(Event.index == -1) + { + if(!isSelectionEmpty()) + deselectAllRows(); + if(m_pTableModel->hasRowHeaders()) + m_pTableModel->getRowHeaderName().clear(); + pTable->clearSelection(); + m_pTableModel->getCellContent().clear(); + if(pTable->isAccessibleAlive()) + { + pTable->commitGridControlEvent(TABLE_MODEL_CHANGED, + makeAny( AccessibleTableModelChange(DELETE, 0, m_pTableModel->getColumnCount(), 0, m_pTableModel->getColumnCount())), + Any()); + } + } + else if(Event.index >= 0 && Event.index < m_pTableModel->getRowCount()) + { + if(isSelectedIndex(Event.index)) + { + Sequence<sal_Int32> selected(1); + selected[0]=Event.index; + deselectRows(selected); + } + if(m_pTableModel->hasRowHeaders()) + m_pTableModel->getRowHeaderName().erase(m_pTableModel->getRowHeaderName().begin()+Event.index); + std::vector<std::vector<Any> >::iterator rowPos =m_pTableModel->getCellContent().begin() + Event.index; + m_pTableModel->getCellContent().erase( rowPos ); + } + m_pTableModel->setRowCount(m_pTableModel->getCellContent().size()); + pTable->InvalidateDataWindow(Event.index, Event.index, true); + if(pTable->isAccessibleAlive()) + { + pTable->commitGridControlEvent(TABLE_MODEL_CHANGED, + makeAny( AccessibleTableModelChange(DELETE, Event.index, Event.index+1, 0, m_pTableModel->getColumnCount())), + Any()); + } +} + +void SAL_CALL SVTXGridControl::columnChanged(const ::com::sun::star::awt::grid::GridColumnEvent& Event ) throw (::com::sun::star::uno::RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + TableControl* pTable = (TableControl*)GetWindow(); + if(Event.valueName == rtl::OUString::createFromAscii("ColumnResize")) + { + bool resizable = m_pTableModel->getColumnModel()[Event.index]->isResizable(); + Event.newValue>>=resizable; + m_pTableModel->getColumnModel()[Event.index]->setResizable(resizable); + } + else if(Event.valueName == rtl::OUString::createFromAscii("ColWidth")) + { + sal_Int32 colWidth = m_pTableModel->getColumnModel()[Event.index]->getWidth(); + Event.newValue>>=colWidth; + m_pTableModel->getColumnModel()[Event.index]->setWidth(colWidth); + } + else if(Event.valueName == rtl::OUString::createFromAscii("MaxWidth")) + { + sal_Int32 maxWidth = m_pTableModel->getColumnModel()[Event.index]->getMaxWidth(); + Event.newValue>>=maxWidth; + m_pTableModel->getColumnModel()[Event.index]->setMaxWidth(maxWidth); + } + else if(Event.valueName == rtl::OUString::createFromAscii("MinWidth")) + { + sal_Int32 minWidth = m_pTableModel->getColumnModel()[Event.index]->getMinWidth(); + Event.newValue>>=minWidth; + m_pTableModel->getColumnModel()[Event.index]->setMinWidth(minWidth); + } + else if(Event.valueName == rtl::OUString::createFromAscii("PrefWidth")) + { + sal_Int32 prefWidth = m_pTableModel->getColumnModel()[Event.index]->getPreferredWidth(); + Event.newValue>>=prefWidth; + m_pTableModel->getColumnModel()[Event.index]->setPreferredWidth(prefWidth); + } + else if(Event.valueName == rtl::OUString::createFromAscii("HAlign")) + { + ::com::sun::star::style::HorizontalAlignment hAlign = m_pTableModel->getColumnModel()[Event.index]->getHorizontalAlign(); + Event.newValue>>=hAlign; + m_pTableModel->getColumnModel()[Event.index]->setHorizontalAlign(hAlign); + } + else if(Event.valueName == rtl::OUString::createFromAscii("UpdateWidth")) + { + if(m_pTableModel->getColumnModel()[Event.index]->getPreferredWidth() != 0) + m_xColumnModel->getColumn(Event.index)->updateColumn(rtl::OUString::createFromAscii("PrefWidth"), m_pTableModel->getColumnModel()[Event.index]->getPreferredWidth()); + m_xColumnModel->getColumn(Event.index)->updateColumn(rtl::OUString::createFromAscii("ColWidth"), m_pTableModel->getColumnModel()[Event.index]->getWidth()); + } + pTable->Invalidate(); +} +void SAL_CALL SVTXGridControl::dataChanged(const ::com::sun::star::awt::grid::GridDataEvent& Event ) throw (::com::sun::star::uno::RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + TableControl* pTable = (TableControl*)GetWindow(); + if(Event.valueName == rtl::OUString::createFromAscii("RowHeight")) + { + sal_Int32 rowHeight = m_pTableModel->getRowHeight(); + Event.newValue>>=rowHeight; + m_pTableModel->setRowHeight(rowHeight); + pTable->Invalidate(); + } + else if(Event.valueName == rtl::OUString::createFromAscii("RowHeaderWidth")) + { + sal_Int32 rowHeaderWidth = m_pTableModel->getRowHeaderWidth(); + Event.newValue>>=rowHeaderWidth; + m_pTableModel->setRowHeaderWidth(rowHeaderWidth); + pTable->Invalidate(); + } + else if(Event.valueName == rtl::OUString::createFromAscii("RowHeaders")) + { + Sequence< rtl::OUString > headers(0); + Event.newValue>>=headers; + std::vector< rtl::OUString > headerNames( comphelper::sequenceToContainer <std::vector< rtl::OUString > >(headers) ); + m_pTableModel->setRowHeaderName(headerNames); + pTable->Invalidate(); + } + else if(Event.valueName == rtl::OUString::createFromAscii("CellUpdated")) + { + std::vector< std::vector< Any > >& rowContent = m_pTableModel->getCellContent(); + sal_Int32 col = -1; + Event.oldValue>>=col; + rowContent[Event.index][col] = Event.newValue; + pTable->InvalidateDataWindow(Event.index, Event.index, false); + } + else if(Event.valueName == rtl::OUString::createFromAscii("RowUpdated")) + { + std::vector<std::vector< Any > >& rowContent = m_pTableModel->getCellContent(); + Sequence< sal_Int32 > cols(0); + Sequence< Any > values(0); + Event.oldValue>>=cols; + Event.newValue>>=values; + for(int i = 0; i< cols.getLength(); i++) + { + if(cols[i]>=0 && cols[i]<m_pTableModel->getColumnCount()) + rowContent[Event.index][cols[i]]=values[i]; + else + break; + } + pTable->InvalidateDataWindow(Event.index, Event.index, false); + } +} + +void SAL_CALL SVTXGridControl::disposing( const ::com::sun::star::lang::EventObject& Source ) throw(::com::sun::star::uno::RuntimeException) +{ + VCLXWindow::disposing( Source ); +} + +::sal_Int32 SAL_CALL SVTXGridControl::getMinSelectionIndex() throw (::com::sun::star::uno::RuntimeException) +{ + TableControl* pTable = (TableControl*)GetWindow(); + std::vector<RowPos>& selectedRows = pTable->GetSelectedRows(); + if(selectedRows.empty()) + return -1; + else + { + std::vector<RowPos>::iterator itStart = selectedRows.begin(); + std::vector<RowPos>::iterator itEnd = selectedRows.end(); + return *(std::min_element(itStart, itEnd)); + } +} + +::sal_Int32 SAL_CALL SVTXGridControl::getMaxSelectionIndex() throw (::com::sun::star::uno::RuntimeException) +{ + TableControl* pTable = (TableControl*)GetWindow(); + std::vector<RowPos>& selectedRows = pTable->GetSelectedRows(); + if(selectedRows.empty()) + return -1; + else + { + std::vector<RowPos>::iterator itStart = selectedRows.begin(); + std::vector<RowPos>::iterator itEnd = selectedRows.end(); + return *(std::max_element(itStart, itEnd)); + } +} + +void SAL_CALL SVTXGridControl::selectRows(const ::com::sun::star::uno::Sequence< ::sal_Int32 >& rangeOfRows) throw (::com::sun::star::uno::RuntimeException) +{ + TableControl* pTable = (TableControl*)GetWindow(); + SelectionMode eSelMode = pTable->getSelEngine()->GetSelectionMode(); + if(eSelMode != NO_SELECTION) + { + sal_Int32 start = rangeOfRows[0]; + int seqSize = rangeOfRows.getLength(); + sal_Int32 end = rangeOfRows[seqSize-1]; + if((start >= 0 && start < m_pTableModel->getRowCount()) && (end >= 0 && end < m_pTableModel->getRowCount())) + { + std::vector<RowPos>& selectedRows = pTable->GetSelectedRows(); + if(eSelMode == SINGLE_SELECTION) + { + if(!selectedRows.empty()) + selectedRows.clear(); + if(rangeOfRows.getLength() == 1) + selectedRows.push_back(start); + else + return; + } + else + { + for(int i=0;i<seqSize;i++) + { + if(!isSelectedIndex(rangeOfRows[i])) + selectedRows.push_back(rangeOfRows[i]); + } + } + pTable->selectionChanged(true); + pTable->InvalidateDataWindow(start, end, false); + SetSynthesizingVCLEvent( sal_True ); + pTable->Select(); + SetSynthesizingVCLEvent( sal_False ); + } + } +} + +void SAL_CALL SVTXGridControl::selectAllRows() throw (::com::sun::star::uno::RuntimeException) +{ + TableControl* pTable = (TableControl*)GetWindow(); + SelectionMode eSelMode = pTable->getSelEngine()->GetSelectionMode(); + if(eSelMode != NO_SELECTION) + { + std::vector<RowPos>& selectedRows = pTable->GetSelectedRows(); + if(!selectedRows.empty()) + selectedRows.clear(); + for(int i=0;i<m_pTableModel->getRowCount();i++) + selectedRows.push_back(i); + pTable->Invalidate(); + SetSynthesizingVCLEvent( sal_True ); + pTable->Select(); + SetSynthesizingVCLEvent( sal_False ); + } +} + +void SAL_CALL SVTXGridControl::deselectRows(const ::com::sun::star::uno::Sequence< ::sal_Int32 >& rangeOfRows) throw (::com::sun::star::uno::RuntimeException) +{ + TableControl* pTable = (TableControl*)GetWindow(); + std::vector<RowPos>& selectedRows = pTable->GetSelectedRows(); + std::vector<RowPos>::iterator itStart = selectedRows.begin(); + std::vector<RowPos>::iterator itEnd = selectedRows.end(); + for(int i = 0; i < rangeOfRows.getLength(); i++ ) + { + std::vector<RowPos>::iterator iter = std::find(itStart, itEnd, rangeOfRows[i]); + selectedRows.erase(iter); + } + pTable->selectionChanged(true); + pTable->Invalidate(); + SetSynthesizingVCLEvent( sal_True ); + pTable->Select(); + SetSynthesizingVCLEvent( sal_False ); +} + +void SAL_CALL SVTXGridControl::deselectAllRows() throw (::com::sun::star::uno::RuntimeException) +{ + TableControl* pTable = (TableControl*)GetWindow(); + std::vector<RowPos>& selectedRows = pTable->GetSelectedRows(); + if(!selectedRows.empty()) + selectedRows.clear(); + pTable->Invalidate(); + SetSynthesizingVCLEvent( sal_True ); + pTable->Select(); + SetSynthesizingVCLEvent( sal_False ); +} + +::com::sun::star::uno::Sequence< ::sal_Int32 > SAL_CALL SVTXGridControl::getSelection() throw (::com::sun::star::uno::RuntimeException) +{ + TableControl* pTable = (TableControl*)GetWindow(); + std::vector<RowPos>& selectedRows = pTable->GetSelectedRows(); + Sequence<sal_Int32> selectedRowsToSequence(comphelper::containerToSequence(selectedRows)); + return selectedRowsToSequence; +} + +::sal_Bool SAL_CALL SVTXGridControl::isCellEditable() throw (::com::sun::star::uno::RuntimeException) +{ + return sal_False; +} + +::sal_Bool SAL_CALL SVTXGridControl::isSelectionEmpty() throw (::com::sun::star::uno::RuntimeException) +{ + TableControl* pTable = (TableControl*)GetWindow(); + std::vector<RowPos>& selectedRows = pTable->GetSelectedRows(); + if(selectedRows.empty()) + return sal_True; + else + return sal_False; +} + +::sal_Bool SAL_CALL SVTXGridControl::isSelectedIndex(::sal_Int32 index) throw (::com::sun::star::uno::RuntimeException) +{ + TableControl* pTable = (TableControl*)GetWindow(); + std::vector<RowPos>& selectedRows = pTable->GetSelectedRows(); + return std::find(selectedRows.begin(),selectedRows.end(), index) != selectedRows.end(); +} + +void SAL_CALL SVTXGridControl::selectRow(::sal_Int32 index) throw (::com::sun::star::uno::RuntimeException) +{ + if(index<0 || index>=m_pTableModel->getRowCount()) + return; + TableControl* pTable = (TableControl*)GetWindow(); + SelectionMode eSelMode = pTable->getSelEngine()->GetSelectionMode(); + if(eSelMode != NO_SELECTION) + { + std::vector<RowPos>& selectedRows = pTable->GetSelectedRows(); + if(eSelMode == MULTIPLE_SELECTION) + { + if(!isSelectedIndex(index)) + selectedRows.push_back(index); + else + return; + } + else if(eSelMode == SINGLE_SELECTION) + { + if(!selectedRows.empty()) + { + if(!isSelectedIndex(index)) + deselectRows(getSelection()); + else + return; + } + selectedRows.push_back(index); + } + pTable->selectionChanged(true); + pTable->InvalidateDataWindow(index, index, false); + SetSynthesizingVCLEvent( sal_True ); + pTable->Select(); + SetSynthesizingVCLEvent( sal_False ); + } +} + +void SAL_CALL SVTXGridControl::selectColumn(::sal_Int32 x) throw (::com::sun::star::uno::RuntimeException) +{ + (void)x; +} +void SVTXGridControl::dispose() throw(::com::sun::star::uno::RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + ::com::sun::star::lang::EventObject aObj; + aObj.Source = (::cppu::OWeakObject*)this; + m_aSelectionListeners.disposeAndClear( aObj ); + VCLXWindow::dispose(); +} + +void SVTXGridControl::ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent ) +{ + ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindow > xKeepAlive( this ); + + switch ( rVclWindowEvent.GetId() ) + { + case VCLEVENT_TABLEROW_SELECT: + { + TableControl* pTable = (TableControl*)GetWindow(); + + if( pTable ) + { + if ( m_aSelectionListeners.getLength() ) + { + ImplCallItemListeners(); + } + } + } + break; + + default: + VCLXWindow::ProcessWindowEvent( rVclWindowEvent ); + break; + } +} + +void SVTXGridControl::ImplCallItemListeners() +{ + TableControl* pTable = (TableControl*) GetWindow(); + if ( pTable && m_aSelectionListeners.getLength() ) + { + ::std::vector<sal_Int32> selRows = pTable->GetSelectedRows(); + ::com::sun::star::awt::grid::GridSelectionEvent aEvent; + aEvent.Source = (::cppu::OWeakObject*)this; + aEvent.Column = 0; + sal_Int32 actSelRowCount = selRows.size(); + sal_Int32 diff = actSelRowCount - m_nSelectedRowCount; + //row added to selection + if(diff >= 1) + { + aEvent.Action = com::sun::star::awt::grid::SelectionEventType(0); + aEvent.Row = selRows[actSelRowCount-1]; + aEvent.Range = diff; + } + //selected row changed + else if(diff == 0 && actSelRowCount != 0) + { + aEvent.Row = selRows[actSelRowCount-1]; + aEvent.Action = com::sun::star::awt::grid::SelectionEventType(2); + aEvent.Range = 0; + } + else + { + //selection changed: multiple row deselected, only 1 row is selected + if(actSelRowCount == 1) + { + aEvent.Row = selRows[actSelRowCount-1]; + aEvent.Action = com::sun::star::awt::grid::SelectionEventType(2); + } + //row is deselected + else + { + aEvent.Row = pTable->GetCurrentRow(); + aEvent.Action = com::sun::star::awt::grid::SelectionEventType(1); + } + aEvent.Range = 0; + } + m_nSelectedRowCount=actSelRowCount; + m_aSelectionListeners.selectionChanged( aEvent ); + } +} diff --git a/svtools/source/uno/svtxgridcontrol.hxx b/svtools/source/uno/svtxgridcontrol.hxx new file mode 100755 index 000000000000..b15507e4614f --- /dev/null +++ b/svtools/source/uno/svtxgridcontrol.hxx @@ -0,0 +1,117 @@ +/************************************************************************* + * + * 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. + * + ************************************************************************/ + +#ifndef _SVT_GRIDCONTROL_HXX_ +#define _SVT_GRIDCONTROL_HXX_ + +#include <unocontroltablemodel.hxx> +#include <svtools/table/tablecontrol.hxx> +#include <com/sun/star/awt/grid/XGridControl.hpp> +#include <com/sun/star/awt/grid/XGridDataListener.hpp> +#include <com/sun/star/awt/grid/XGridColumnListener.hpp> +#include <com/sun/star/awt/grid/GridDataEvent.hpp> +#include <com/sun/star/awt/grid/GridColumnEvent.hpp> +#include <com/sun/star/awt/grid/XGridColumnModel.hpp> +#include <com/sun/star/awt/grid/XGridDataModel.hpp> +#include <com/sun/star/awt/grid/XGridSelectionListener.hpp> +#include <toolkit/awt/vclxwindow.hxx> +#include <toolkit/awt/vclxwindows.hxx> +#include <cppuhelper/typeprovider.hxx> +#include <cppuhelper/implbase3.hxx> +#include <toolkit/helper/listenermultiplexer.hxx> + + +using namespace ::svt::table; + +class SVTXGridControl : public ::cppu::ImplInheritanceHelper3< VCLXWindow, ::com::sun::star::awt::grid::XGridControl, + ::com::sun::star::awt::grid::XGridDataListener, ::com::sun::star::awt::grid::XGridColumnListener> +{ +private: + ::boost::shared_ptr< UnoControlTableModel > m_pTableModel; + ::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridDataModel >m_xDataModel; + ::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridColumnModel >m_xColumnModel; + bool m_bHasColumnHeaders; + bool m_bHasRowHeaders; + bool m_bVScroll; + bool m_bHScroll; + bool m_bUpdate; + sal_Int32 m_nSelectedRowCount; + SelectionListenerMultiplexer m_aSelectionListeners; + +protected: + virtual void ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent ); + void ImplCallItemListeners(); + +public: + SVTXGridControl(); + ~SVTXGridControl(); + //XGridDataListener overridables + virtual void SAL_CALL rowAdded(const ::com::sun::star::awt::grid::GridDataEvent& Event) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL rowRemoved(const ::com::sun::star::awt::grid::GridDataEvent & Event) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL dataChanged(const ::com::sun::star::awt::grid::GridDataEvent & Event) throw (::com::sun::star::uno::RuntimeException); + + //XGridColumnListener overridables + virtual void SAL_CALL columnChanged(const ::com::sun::star::awt::grid::GridColumnEvent & Event) throw (::com::sun::star::uno::RuntimeException); + + virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source ) throw(::com::sun::star::uno::RuntimeException); + + ::com::sun::star::uno::Any SAL_CALL queryInterface( const ::com::sun::star::uno::Type & rType ) throw(::com::sun::star::uno::RuntimeException); + void SAL_CALL acquire() throw() { VCLXWindow::acquire(); } + void SAL_CALL release() throw() { VCLXWindow::release(); } + + // ::com::sun::star::lang::XTypeProvider + ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type > SAL_CALL getTypes() throw(::com::sun::star::uno::RuntimeException); + ::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL getImplementationId() throw(::com::sun::star::uno::RuntimeException); + + //::com::sun::star::awt::grid::XGridControl + virtual ::sal_Int32 SAL_CALL getMinSelectionIndex() throw (::com::sun::star::uno::RuntimeException); + virtual ::sal_Int32 SAL_CALL getMaxSelectionIndex() throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL selectRows(const ::com::sun::star::uno::Sequence< ::sal_Int32 >& rangeOfRows) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL selectAllRows() throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL deselectRows(const ::com::sun::star::uno::Sequence< ::sal_Int32 >& rangeOfRows) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL deselectAllRows() throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Sequence< ::sal_Int32 > SAL_CALL getSelection() throw (::com::sun::star::uno::RuntimeException); + virtual ::sal_Bool SAL_CALL isCellEditable() throw (::com::sun::star::uno::RuntimeException); + virtual ::sal_Bool SAL_CALL isSelectionEmpty() throw (::com::sun::star::uno::RuntimeException); + virtual ::sal_Bool SAL_CALL isSelectedIndex(::sal_Int32 index) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL selectRow(::sal_Int32 y) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL selectColumn(::sal_Int32 x) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL addSelectionListener(const ::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridSelectionListener > & listener) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL removeSelectionListener(const ::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridSelectionListener > & listener) throw (::com::sun::star::uno::RuntimeException); + virtual ::sal_Int32 SAL_CALL getItemIndexAtPoint(::sal_Int32 x, ::sal_Int32 y) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setToolTip(const ::com::sun::star::uno::Sequence< ::rtl::OUString >& text, const ::com::sun::star::uno::Sequence< sal_Int32 >& columns) throw (::com::sun::star::uno::RuntimeException); + + void SAL_CALL setProperty( const ::rtl::OUString& PropertyName, const ::com::sun::star::uno::Any& Value ) throw(::com::sun::star::uno::RuntimeException); + ::com::sun::star::uno::Any SAL_CALL getProperty( const ::rtl::OUString& PropertyName ) throw(::com::sun::star::uno::RuntimeException); + static void ImplGetPropertyIds( std::list< sal_uInt16 > &aIds ); + void SAL_CALL setVisible(sal_Bool bVisible) throw(::com::sun::star::uno::RuntimeException); + void SAL_CALL setFocus() throw(::com::sun::star::uno::RuntimeException); + + // ::com::sun::star::lang::XComponent + void SAL_CALL dispose( ) throw(::com::sun::star::uno::RuntimeException); + }; + #endif // _SVT_GRIDCONTROL_HXX_ diff --git a/svtools/source/uno/toolboxcontroller.cxx b/svtools/source/uno/toolboxcontroller.cxx new file mode 100644 index 000000000000..bdb2256a07e8 --- /dev/null +++ b/svtools/source/uno/toolboxcontroller.cxx @@ -0,0 +1,886 @@ +/************************************************************************* + * + * 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_svtools.hxx" +#include <svtools/toolboxcontroller.hxx> +#include <com/sun/star/beans/PropertyValue.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/frame/XDispatchProvider.hpp> +#include <com/sun/star/lang/DisposedException.hpp> +#include <com/sun/star/frame/XLayoutManager.hpp> +#include <vos/mutex.hxx> +#include <vcl/svapp.hxx> +#include <imgdef.hxx> +#include <svtools/miscopt.hxx> + +#ifndef _TOOLKIT_HELPER_VCLUNOHELPER_HXX_ +#include <toolkit/unohlp.hxx> +#endif +#include <vcl/toolbox.hxx> +//shizhobo +#include <com/sun/star/beans/PropertyAttribute.hpp> +const int TOOLBARCONTROLLER_PROPHANDLE_SUPPORTSVISIABLE = 1; +const int TOOLBARCONTROLLER_PROPCOUNT = 1; +const rtl::OUString TOOLBARCONTROLLER_PROPNAME_SUPPORTSVISIABLE( RTL_CONSTASCII_USTRINGPARAM( "SupportsVisiable" )); +//end + +using ::rtl::OUString; + +using namespace ::cppu; +using namespace ::com::sun::star::awt; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::util; +using namespace ::com::sun::star::beans; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::frame; +using namespace ::com::sun::star::frame; + +namespace svt +{ + +struct DispatchInfo +{ + Reference< XDispatch > mxDispatch; + const URL maURL; + const Sequence< PropertyValue > maArgs; + + DispatchInfo( const Reference< XDispatch >& xDispatch, const URL& rURL, const Sequence< PropertyValue >& rArgs ) + : mxDispatch( xDispatch ), maURL( rURL ), maArgs( rArgs ) {} +}; + +struct ToolboxController_Impl +{ + ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindow > m_xParentWindow; + ::com::sun::star::uno::Reference< ::com::sun::star::util::XURLTransformer > m_xUrlTransformer; + rtl::OUString m_sModuleName; + sal_uInt16 m_nToolBoxId; + + DECL_STATIC_LINK( ToolboxController_Impl, ExecuteHdl_Impl, DispatchInfo* ); + + ToolboxController_Impl() + : m_nToolBoxId( SAL_MAX_UINT16 ) + {} +}; + +ToolboxController::ToolboxController( + + const Reference< XMultiServiceFactory >& rServiceManager, + const Reference< XFrame >& xFrame, + const ::rtl::OUString& aCommandURL ) : + OPropertyContainer(GetBroadcastHelper()) + , OWeakObject() + , m_bInitialized( sal_False ) + , m_bDisposed( sal_False ) + , m_xFrame(xFrame) + , m_xServiceManager( rServiceManager ) + , m_aCommandURL( aCommandURL ) + , m_aListenerContainer( m_aMutex ) +{ + //registger Propertyh by shizhoubo + registerProperty(TOOLBARCONTROLLER_PROPNAME_SUPPORTSVISIABLE, TOOLBARCONTROLLER_PROPHANDLE_SUPPORTSVISIABLE, com::sun::star::beans::PropertyAttribute::TRANSIENT | com::sun::star::beans::PropertyAttribute::READONLY, + &m_bSupportVisiable, getCppuType(&m_bSupportVisiable)); + + m_pImpl = new ToolboxController_Impl; + + try + { + m_pImpl->m_xUrlTransformer.set( m_xServiceManager->createInstance( + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.util.URLTransformer" ))), + UNO_QUERY ); + } + catch(const Exception&) + { + } +} + +ToolboxController::ToolboxController() : + OPropertyContainer(GetBroadcastHelper()) + , OWeakObject() + , m_bInitialized( sal_False ) + , m_bDisposed( sal_False ) + , m_aListenerContainer( m_aMutex ) +{ + //registger Propertyh by shizhoubo + registerProperty(TOOLBARCONTROLLER_PROPNAME_SUPPORTSVISIABLE, TOOLBARCONTROLLER_PROPHANDLE_SUPPORTSVISIABLE, com::sun::star::beans::PropertyAttribute::TRANSIENT | com::sun::star::beans::PropertyAttribute::READONLY, + &m_bSupportVisiable, getCppuType(&m_bSupportVisiable)); + + m_pImpl = new ToolboxController_Impl; +} + +ToolboxController::~ToolboxController() +{ + delete m_pImpl; +} + +Reference< XFrame > ToolboxController::getFrameInterface() const +{ + vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() ); + return m_xFrame; +} + +Reference< XMultiServiceFactory > ToolboxController::getServiceManager() const +{ + vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() ); + return m_xServiceManager; +} + +Reference< XLayoutManager > ToolboxController::getLayoutManager() const +{ + Reference< XLayoutManager > xLayoutManager; + Reference< XPropertySet > xPropSet; + { + vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() ); + xPropSet = Reference< XPropertySet >( m_xFrame, UNO_QUERY ); + } + + if ( xPropSet.is() ) + { + try + { + xLayoutManager.set(xPropSet->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "LayoutManager" ))),UNO_QUERY); + } + catch ( Exception& ) + { + } + } + + return xLayoutManager; +} + +// XInterface +Any SAL_CALL ToolboxController::queryInterface( const Type& rType ) +throw ( RuntimeException ) +{ + Any a = ::cppu::queryInterface( + rType , + static_cast< XToolbarController* >( this ), + static_cast< XStatusListener* >( this ), + static_cast< XEventListener* >( this ), + static_cast< XInitialization* >( this ), + static_cast< XComponent* >( this ), + static_cast< XUpdatable* >( this )); + if ( !a.hasValue()) + { + a = ::cppu::queryInterface(rType + ,static_cast<XPropertySet*>(this) + ,static_cast<XMultiPropertySet*>(this) + ,static_cast<XFastPropertySet*>(this)); + if (!a.hasValue()) + return OWeakObject::queryInterface( rType ); + } + return a; +} + +void SAL_CALL ToolboxController::acquire() throw () +{ + OWeakObject::acquire(); +} + +void SAL_CALL ToolboxController::release() throw () +{ + OWeakObject::release(); +} + +void SAL_CALL ToolboxController::initialize( const Sequence< Any >& aArguments ) +throw ( Exception, RuntimeException ) +{ + bool bInitialized( true ); + + { + vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() ); + + if ( m_bDisposed ) + throw DisposedException(); + + bInitialized = m_bInitialized; + } + + if ( !bInitialized ) + { + vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() ); + m_bInitialized = sal_True; + //shizhoubo add + m_bSupportVisiable = sal_False; + PropertyValue aPropValue; + for ( int i = 0; i < aArguments.getLength(); i++ ) + { + if ( aArguments[i] >>= aPropValue ) + { + if ( aPropValue.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("Frame") )) + m_xFrame.set(aPropValue.Value,UNO_QUERY); + else if ( aPropValue.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("CommandURL") )) + aPropValue.Value >>= m_aCommandURL; + else if ( aPropValue.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("ServiceManager") )) + m_xServiceManager.set(aPropValue.Value,UNO_QUERY); + else if ( aPropValue.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("ParentWindow") )) + m_pImpl->m_xParentWindow.set(aPropValue.Value,UNO_QUERY); + else if ( aPropValue.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("ModuleName" ) ) ) + aPropValue.Value >>= m_pImpl->m_sModuleName; + } + } + + try + { + if ( !m_pImpl->m_xUrlTransformer.is() && m_xServiceManager.is() ) + m_pImpl->m_xUrlTransformer.set( m_xServiceManager->createInstance( + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.util.URLTransformer" ))), + UNO_QUERY ); + } + catch(const Exception&) + { + } + + if ( m_aCommandURL.getLength() ) + m_aListenerMap.insert( URLToDispatchMap::value_type( m_aCommandURL, Reference< XDispatch >() )); + } +} + +void SAL_CALL ToolboxController::update() +throw ( RuntimeException ) +{ + { + vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() ); + if ( m_bDisposed ) + throw DisposedException(); + } + + // Bind all registered listeners to their dispatch objects + bindListener(); +} + +// XComponent +void SAL_CALL ToolboxController::dispose() +throw (::com::sun::star::uno::RuntimeException) +{ + Reference< XComponent > xThis( static_cast< OWeakObject* >(this), UNO_QUERY ); + + { + vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() ); + if ( m_bDisposed ) + throw DisposedException(); + } + + com::sun::star::lang::EventObject aEvent( xThis ); + m_aListenerContainer.disposeAndClear( aEvent ); + + vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() ); + Reference< XStatusListener > xStatusListener( static_cast< OWeakObject* >( this ), UNO_QUERY ); + URLToDispatchMap::iterator pIter = m_aListenerMap.begin(); + while ( pIter != m_aListenerMap.end() ) + { + try + { + Reference< XDispatch > xDispatch( pIter->second ); + + com::sun::star::util::URL aTargetURL; + aTargetURL.Complete = pIter->first; + if ( m_pImpl->m_xUrlTransformer.is() ) + m_pImpl->m_xUrlTransformer->parseStrict( aTargetURL ); + + if ( xDispatch.is() && xStatusListener.is() ) + xDispatch->removeStatusListener( xStatusListener, aTargetURL ); + } + catch ( Exception& ) + { + } + + ++pIter; + } + + m_bDisposed = sal_True; +} + +void SAL_CALL ToolboxController::addEventListener( const Reference< XEventListener >& xListener ) +throw ( RuntimeException ) +{ + m_aListenerContainer.addInterface( ::getCppuType( ( const Reference< XEventListener >* ) NULL ), xListener ); +} + +void SAL_CALL ToolboxController::removeEventListener( const Reference< XEventListener >& aListener ) +throw ( RuntimeException ) +{ + m_aListenerContainer.removeInterface( ::getCppuType( ( const Reference< XEventListener >* ) NULL ), aListener ); +} + +// XEventListener +void SAL_CALL ToolboxController::disposing( const EventObject& Source ) +throw ( RuntimeException ) +{ + Reference< XInterface > xSource( Source.Source ); + + vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() ); + + if ( m_bDisposed ) + return; + + URLToDispatchMap::iterator pIter = m_aListenerMap.begin(); + while ( pIter != m_aListenerMap.end() ) + { + // Compare references and release dispatch references if they are equal. + Reference< XInterface > xIfac( pIter->second, UNO_QUERY ); + if ( xSource == xIfac ) + pIter->second.clear(); + ++pIter; + } + + Reference< XInterface > xIfac( m_xFrame, UNO_QUERY ); + if ( xIfac == xSource ) + m_xFrame.clear(); +} + +// XStatusListener +void SAL_CALL ToolboxController::statusChanged( const FeatureStateEvent& ) +throw ( RuntimeException ) +{ + // must be implemented by sub class +} + +// XToolbarController +void SAL_CALL ToolboxController::execute( sal_Int16 KeyModifier ) +throw (::com::sun::star::uno::RuntimeException) +{ + Reference< XDispatch > xDispatch; + ::rtl::OUString aCommandURL; + + { + vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() ); + + if ( m_bDisposed ) + throw DisposedException(); + + if ( m_bInitialized && + m_xFrame.is() && + m_xServiceManager.is() && + m_aCommandURL.getLength() ) + { + + aCommandURL = m_aCommandURL; + URLToDispatchMap::iterator pIter = m_aListenerMap.find( m_aCommandURL ); + if ( pIter != m_aListenerMap.end() ) + xDispatch = pIter->second; + } + } + + if ( xDispatch.is() ) + { + try + { + com::sun::star::util::URL aTargetURL; + Sequence<PropertyValue> aArgs( 1 ); + + // Provide key modifier information to dispatch function + aArgs[0].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "KeyModifier" )); + aArgs[0].Value = makeAny( KeyModifier ); + + aTargetURL.Complete = aCommandURL; + if ( m_pImpl->m_xUrlTransformer.is() ) + m_pImpl->m_xUrlTransformer->parseStrict( aTargetURL ); + xDispatch->dispatch( aTargetURL, aArgs ); + } + catch ( DisposedException& ) + { + } + } +} + +void SAL_CALL ToolboxController::click() +throw (::com::sun::star::uno::RuntimeException) +{ +} + +void SAL_CALL ToolboxController::doubleClick() +throw (::com::sun::star::uno::RuntimeException) +{ +} + +Reference< XWindow > SAL_CALL ToolboxController::createPopupWindow() +throw (::com::sun::star::uno::RuntimeException) +{ + return Reference< XWindow >(); +} + +Reference< XWindow > SAL_CALL ToolboxController::createItemWindow( const Reference< XWindow >& ) +throw (::com::sun::star::uno::RuntimeException) +{ + return Reference< XWindow >(); +} + +void ToolboxController::addStatusListener( const rtl::OUString& aCommandURL ) +{ + Reference< XDispatch > xDispatch; + Reference< XStatusListener > xStatusListener; + com::sun::star::util::URL aTargetURL; + + { + vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() ); + URLToDispatchMap::iterator pIter = m_aListenerMap.find( aCommandURL ); + + // Already in the list of status listener. Do nothing. + if ( pIter != m_aListenerMap.end() ) + return; + + // Check if we are already initialized. Implementation starts adding itself as status listener when + // intialize is called. + if ( !m_bInitialized ) + { + // Put into the hash_map of status listener. Will be activated when initialized is called + m_aListenerMap.insert( URLToDispatchMap::value_type( aCommandURL, Reference< XDispatch >() )); + return; + } + else + { + // Add status listener directly as intialize has already been called. + Reference< XDispatchProvider > xDispatchProvider( m_xFrame, UNO_QUERY ); + if ( m_xServiceManager.is() && xDispatchProvider.is() ) + { + aTargetURL.Complete = aCommandURL; + if ( m_pImpl->m_xUrlTransformer.is() ) + m_pImpl->m_xUrlTransformer->parseStrict( aTargetURL ); + xDispatch = xDispatchProvider->queryDispatch( aTargetURL, ::rtl::OUString(), 0 ); + + xStatusListener = Reference< XStatusListener >( static_cast< OWeakObject* >( this ), UNO_QUERY ); + URLToDispatchMap::iterator aIter = m_aListenerMap.find( aCommandURL ); + if ( aIter != m_aListenerMap.end() ) + { + Reference< XDispatch > xOldDispatch( aIter->second ); + aIter->second = xDispatch; + + try + { + if ( xOldDispatch.is() ) + xOldDispatch->removeStatusListener( xStatusListener, aTargetURL ); + } + catch ( Exception& ) + { + } + } + else + m_aListenerMap.insert( URLToDispatchMap::value_type( aCommandURL, xDispatch )); + } + } + } + + // Call without locked mutex as we are called back from dispatch implementation + try + { + if ( xDispatch.is() ) + xDispatch->addStatusListener( xStatusListener, aTargetURL ); + } + catch ( Exception& ) + { + } +} + +void ToolboxController::removeStatusListener( const rtl::OUString& aCommandURL ) +{ + vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() ); + + URLToDispatchMap::iterator pIter = m_aListenerMap.find( aCommandURL ); + if ( pIter != m_aListenerMap.end() ) + { + Reference< XDispatch > xDispatch( pIter->second ); + Reference< XStatusListener > xStatusListener( static_cast< OWeakObject* >( this ), UNO_QUERY ); + m_aListenerMap.erase( pIter ); + + try + { + com::sun::star::util::URL aTargetURL; + aTargetURL.Complete = aCommandURL; + if ( m_pImpl->m_xUrlTransformer.is() ) + m_pImpl->m_xUrlTransformer->parseStrict( aTargetURL ); + + if ( xDispatch.is() && xStatusListener.is() ) + xDispatch->removeStatusListener( xStatusListener, aTargetURL ); + } + catch ( Exception& ) + { + } + } +} + +void ToolboxController::bindListener() +{ + std::vector< Listener > aDispatchVector; + Reference< XStatusListener > xStatusListener; + + { + vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() ); + + if ( !m_bInitialized ) + return; + + // Collect all registered command URL's and store them temporary + Reference< XDispatchProvider > xDispatchProvider( m_xFrame, UNO_QUERY ); + if ( m_xServiceManager.is() && xDispatchProvider.is() ) + { + xStatusListener = Reference< XStatusListener >( static_cast< OWeakObject* >( this ), UNO_QUERY ); + URLToDispatchMap::iterator pIter = m_aListenerMap.begin(); + while ( pIter != m_aListenerMap.end() ) + { + com::sun::star::util::URL aTargetURL; + aTargetURL.Complete = pIter->first; + if ( m_pImpl->m_xUrlTransformer.is() ) + m_pImpl->m_xUrlTransformer->parseStrict( aTargetURL ); + + Reference< XDispatch > xDispatch( pIter->second ); + if ( xDispatch.is() ) + { + // We already have a dispatch object => we have to requery. + // Release old dispatch object and remove it as listener + try + { + xDispatch->removeStatusListener( xStatusListener, aTargetURL ); + } + catch ( Exception& ) + { + } + } + + pIter->second.clear(); + xDispatch.clear(); + + // Query for dispatch object. Old dispatch will be released with this, too. + try + { + xDispatch = xDispatchProvider->queryDispatch( aTargetURL, ::rtl::OUString(), 0 ); + } + catch ( Exception& ) + { + } + pIter->second = xDispatch; + + Listener aListener( aTargetURL, xDispatch ); + aDispatchVector.push_back( aListener ); + ++pIter; + } + } + } + + // Call without locked mutex as we are called back from dispatch implementation + if ( xStatusListener.is() ) + { + try + { + for ( sal_uInt32 i = 0; i < aDispatchVector.size(); i++ ) + { + Listener& rListener = aDispatchVector[i]; + if ( rListener.xDispatch.is() ) + rListener.xDispatch->addStatusListener( xStatusListener, rListener.aURL ); + else if ( rListener.aURL.Complete == m_aCommandURL ) + { + try + { + // Send status changed for the main URL, if we cannot get a valid dispatch object. + // UI disables the button. Catch exception as we release our mutex, it is possible + // that someone else already disposed this instance! + FeatureStateEvent aFeatureStateEvent; + aFeatureStateEvent.IsEnabled = sal_False; + aFeatureStateEvent.FeatureURL = rListener.aURL; + aFeatureStateEvent.State = Any(); + xStatusListener->statusChanged( aFeatureStateEvent ); + } + catch ( Exception& ) + { + } + } + } + } + catch ( Exception& ) + { + } + } +} + +void ToolboxController::unbindListener() +{ + vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() ); + + if ( !m_bInitialized ) + return; + + // Collect all registered command URL's and store them temporary + Reference< XDispatchProvider > xDispatchProvider( m_xFrame, UNO_QUERY ); + if ( m_xServiceManager.is() && xDispatchProvider.is() ) + { + Reference< XStatusListener > xStatusListener( static_cast< OWeakObject* >( this ), UNO_QUERY ); + URLToDispatchMap::iterator pIter = m_aListenerMap.begin(); + while ( pIter != m_aListenerMap.end() ) + { + com::sun::star::util::URL aTargetURL; + aTargetURL.Complete = pIter->first; + if ( m_pImpl->m_xUrlTransformer.is() ) + m_pImpl->m_xUrlTransformer->parseStrict( aTargetURL ); + + Reference< XDispatch > xDispatch( pIter->second ); + if ( xDispatch.is() ) + { + // We already have a dispatch object => we have to requery. + // Release old dispatch object and remove it as listener + try + { + xDispatch->removeStatusListener( xStatusListener, aTargetURL ); + } + catch ( Exception& ) + { + } + } + pIter->second.clear(); + ++pIter; + } + } +} + +sal_Bool ToolboxController::isBound() const +{ + vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() ); + + if ( !m_bInitialized ) + return sal_False; + + URLToDispatchMap::const_iterator pIter = m_aListenerMap.find( m_aCommandURL ); + if ( pIter != m_aListenerMap.end() ) + return ( pIter->second.is() ); + + return sal_False; +} + +sal_Bool ToolboxController::hasBigImages() const +{ + return SvtMiscOptions().AreCurrentSymbolsLarge(); +} + +sal_Bool ToolboxController::isHighContrast() const +{ + sal_Bool bHighContrast( sal_False ); + + Reference< XWindow > xWindow = m_pImpl->m_xParentWindow; + if ( xWindow.is() ) + { + vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() ); + Window* pWindow = VCLUnoHelper::GetWindow( xWindow ); + if ( pWindow ) + bHighContrast = ( ((ToolBox *)pWindow)->GetSettings().GetStyleSettings().GetHighContrastMode() ); + } + + return bHighContrast; +} + +void ToolboxController::updateStatus() +{ + bindListener(); +} + +void ToolboxController::updateStatus( const rtl::OUString aCommandURL ) +{ + Reference< XDispatch > xDispatch; + Reference< XStatusListener > xStatusListener; + com::sun::star::util::URL aTargetURL; + + { + vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() ); + + if ( !m_bInitialized ) + return; + + // Try to find a dispatch object for the requested command URL + Reference< XDispatchProvider > xDispatchProvider( m_xFrame, UNO_QUERY ); + xStatusListener = Reference< XStatusListener >( static_cast< OWeakObject* >( this ), UNO_QUERY ); + if ( m_xServiceManager.is() && xDispatchProvider.is() ) + { + aTargetURL.Complete = aCommandURL; + if ( m_pImpl->m_xUrlTransformer.is() ) + m_pImpl->m_xUrlTransformer->parseStrict( aTargetURL ); + xDispatch = xDispatchProvider->queryDispatch( aTargetURL, rtl::OUString(), 0 ); + } + } + + if ( xDispatch.is() && xStatusListener.is() ) + { + // Catch exception as we release our mutex, it is possible that someone else + // has already disposed this instance! + // Add/remove status listener to get a update status information from the + // requested command. + try + { + xDispatch->addStatusListener( xStatusListener, aTargetURL ); + xDispatch->removeStatusListener( xStatusListener, aTargetURL ); + } + catch ( Exception& ) + { + } + } +} + +Reference< XURLTransformer > ToolboxController::getURLTransformer() const +{ + return m_pImpl->m_xUrlTransformer; +} + +Reference< ::com::sun::star::awt::XWindow > ToolboxController::getParent() const +{ + return m_pImpl->m_xParentWindow; +} + +const rtl::OUString& ToolboxController::getModuleName() const +{ + return m_pImpl->m_sModuleName; +} + +void ToolboxController::dispatchCommand( const OUString& sCommandURL, const Sequence< PropertyValue >& rArgs ) +{ + try + { + Reference< XDispatchProvider > xDispatchProvider( m_xFrame, UNO_QUERY_THROW ); + URL aURL; + aURL.Complete = sCommandURL; + getURLTransformer()->parseStrict( aURL ); + + Reference< XDispatch > xDispatch( xDispatchProvider->queryDispatch( aURL, OUString(), 0 ), UNO_QUERY_THROW ); + + Application::PostUserEvent( STATIC_LINK(0, ToolboxController_Impl, ExecuteHdl_Impl), new DispatchInfo( xDispatch, aURL, rArgs ) ); + + } + catch( Exception& ) + { + } +} + +// +//------------------------------------------------------------------------- +// XPropertySet by shizhoubo +com::sun::star::uno::Reference< com::sun::star::beans::XPropertySetInfo > SAL_CALL ToolboxController::getPropertySetInfo() throw(::com::sun::star::uno::RuntimeException) +{ + Reference<XPropertySetInfo> xInfo( createPropertySetInfo( getInfoHelper() ) ); + return xInfo; +} +//------------------------------------------------------------------------- +::cppu::IPropertyArrayHelper& ToolboxController::getInfoHelper() +{ + return *const_cast<ToolboxController*>(this)->getArrayHelper(); +} +//OPropertyArrayUsageHelper by shizhoubo +//------------------------------------------------------------------------------ +::cppu::IPropertyArrayHelper* ToolboxController::createArrayHelper( ) const +{ + com::sun::star::uno::Sequence< Property > aProps; + describeProperties(aProps); + return new ::cppu::OPropertyArrayHelper(aProps); +} +//shizhoubo for supportsvisiable +void ToolboxController::setSupportVisiableProperty(sal_Bool bValue) +{ + m_bSupportVisiable = bValue; +} +//OPropertySetHelper by shizhoubo +sal_Bool SAL_CALL ToolboxController::convertFastPropertyValue( com::sun::star::uno::Any& aConvertedValue , + com::sun::star::uno::Any& aOldValue , + sal_Int32 nHandle , + const com::sun::star::uno::Any& aValue ) throw( com::sun::star::lang::IllegalArgumentException ) +{ + switch (nHandle) + { + case TOOLBARCONTROLLER_PROPHANDLE_SUPPORTSVISIABLE: + { + sal_Bool aNewValue(sal_False); + aValue >>= aNewValue; + if (aNewValue != m_bSupportVisiable) + { + aConvertedValue <<= aNewValue; + aOldValue <<= m_bSupportVisiable; + return sal_True; + } + return sal_False; + } + } + return OPropertyContainer::convertFastPropertyValue(aConvertedValue, aOldValue, nHandle, aValue); +} + +void SAL_CALL ToolboxController::setFastPropertyValue_NoBroadcast( + sal_Int32 nHandle, + const com::sun::star::uno::Any& aValue ) +throw( com::sun::star::uno::Exception) +{ + OPropertyContainer::setFastPropertyValue_NoBroadcast(nHandle, aValue); + if (TOOLBARCONTROLLER_PROPHANDLE_SUPPORTSVISIABLE == nHandle) + { + sal_Bool rValue(sal_False); + if (( aValue >>= rValue ) && m_bInitialized) + this->setSupportVisiableProperty( rValue ); + } +} + +//-------------------------------------------------------------------- + +IMPL_STATIC_LINK_NOINSTANCE( ToolboxController_Impl, ExecuteHdl_Impl, DispatchInfo*, pDispatchInfo ) +{ + pDispatchInfo->mxDispatch->dispatch( pDispatchInfo->maURL, pDispatchInfo->maArgs ); + delete pDispatchInfo; + return 0; +} + +void ToolboxController::enable( bool bEnable ) +{ + ToolBox* pToolBox = 0; + sal_uInt16 nItemId = 0; + if( getToolboxId( nItemId, &pToolBox ) ) + { + pToolBox->EnableItem( nItemId, bEnable ? TRUE : FALSE ); + } +} + +bool ToolboxController::getToolboxId( sal_uInt16& rItemId, ToolBox** ppToolBox ) +{ + if( (m_pImpl->m_nToolBoxId != SAL_MAX_UINT16) && (ppToolBox == 0) ) + return m_pImpl->m_nToolBoxId; + + ToolBox* pToolBox = static_cast< ToolBox* >( VCLUnoHelper::GetWindow( getParent() ) ); + + if( (m_pImpl->m_nToolBoxId == SAL_MAX_UINT16) && pToolBox ) + { + const sal_uInt16 nCount = pToolBox->GetItemCount(); + for ( sal_uInt16 nPos = 0; nPos < nCount; ++nPos ) + { + const sal_uInt16 nItemId = pToolBox->GetItemId( nPos ); + if ( pToolBox->GetItemCommand( nItemId ) == String( m_aCommandURL ) ) + { + m_pImpl->m_nToolBoxId = nItemId; + break; + } + } + } + + if( ppToolBox ) + *ppToolBox = pToolBox; + + rItemId = m_pImpl->m_nToolBoxId; + + return (rItemId != SAL_MAX_UINT16) && (( ppToolBox == 0) || (*ppToolBox != 0) ); +} +//end + +} // svt diff --git a/svtools/source/uno/treecontrolpeer.cxx b/svtools/source/uno/treecontrolpeer.cxx new file mode 100644 index 000000000000..d1ea854cce61 --- /dev/null +++ b/svtools/source/uno/treecontrolpeer.cxx @@ -0,0 +1,1765 @@ +/************************************************************************* + * + * 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_svtools.hxx" + +#define _SVTREEBX_CXX +#include <tools/debug.hxx> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/lang/DisposedException.hpp> +#include <com/sun/star/view/SelectionType.hpp> +#include <toolkit/helper/property.hxx> +#include <toolkit/helper/vclunohelper.hxx> + +#include <com/sun/star/awt/tree/XMutableTreeNode.hpp> +#include <treecontrolpeer.hxx> +#include <comphelper/processfactory.hxx> + +#include <rtl/ref.hxx> +#include <vcl/graph.hxx> +#include <svtools/svtreebx.hxx> + +#include <map> + +using ::rtl::OUString; +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::awt::tree; +using namespace ::com::sun::star::beans; +using namespace ::com::sun::star::view; +using namespace ::com::sun::star::container; +using namespace ::com::sun::star::util; +using namespace ::com::sun::star::graphic; + +#define O(x) OUString( RTL_CONSTASCII_USTRINGPARAM(x) ) + +struct LockGuard +{ +public: + LockGuard( sal_Int32& rLock ) + : mrLock( rLock ) + { + rLock++; + } + + ~LockGuard() + { + mrLock--; + } + + sal_Int32& mrLock; +}; + +// -------------------------------------------------------------------- + +class ImplGraphicItem : public SvLBoxBmp +{ +public: + ImplGraphicItem( SvLBoxEntry* pEntry, USHORT nFlags, Image& aImage ) : SvLBoxBmp( pEntry, nFlags, aImage ) {} + + OUString msGraphicURL; +}; + +// -------------------------------------------------------------------- + +class ImplContextGraphicItem : public SvLBoxContextBmp +{ +public: + ImplContextGraphicItem( SvLBoxEntry* pEntry,USHORT nFlags,Image& rI1,Image& rI2, USHORT nEntryFlagsBmp1) + : SvLBoxContextBmp( pEntry, nFlags, rI1, rI2, nEntryFlagsBmp1 ) {} + + OUString msExpandedGraphicURL; + OUString msCollapsedGraphicURL; +}; + +// -------------------------------------------------------------------- + +class UnoTreeListBoxImpl : public SvTreeListBox +{ +public: + UnoTreeListBoxImpl( TreeControlPeer* pPeer, Window* pParent, WinBits nWinStyle ); + ~UnoTreeListBoxImpl(); + + sal_uInt32 insert( SvLBoxEntry* pEntry,SvLBoxEntry* pParent,ULONG nPos=LIST_APPEND ); + + virtual void RequestingChilds( SvLBoxEntry* pParent ); + + virtual BOOL EditingEntry( SvLBoxEntry* pEntry, Selection& ); + virtual BOOL EditedEntry( SvLBoxEntry* pEntry, const XubString& rNewText ); + + DECL_LINK( OnSelectionChangeHdl, UnoTreeListBoxImpl* ); + DECL_LINK( OnExpandingHdl, UnoTreeListBoxImpl* ); + DECL_LINK( OnExpandedHdl, UnoTreeListBoxImpl* ); + +private: + rtl::Reference< TreeControlPeer > mxPeer; +}; + +// -------------------------------------------------------------------- + +class SVT_DLLPUBLIC UnoTreeListItem : public SvLBoxItem +{ +public: + UnoTreeListItem( SvLBoxEntry* ); + UnoTreeListItem(); + virtual ~UnoTreeListItem(); + virtual USHORT IsA(); + void InitViewData( SvLBox*,SvLBoxEntry*,SvViewDataItem* ); + OUString GetText() const; + void SetText( const OUString& rText ); + Image GetImage() const; + void SetImage( const Image& rImage ); + OUString GetGraphicURL() const; + void SetGraphicURL( const OUString& rGraphicURL ); + void Paint( const Point&, SvLBox& rDev, USHORT nFlags,SvLBoxEntry* ); + SvLBoxItem* Create() const; + void Clone( SvLBoxItem* pSource ); + +private: + OUString maText; + OUString maGraphicURL; + Image maImage; +}; + +// -------------------------------------------------------------------- + +class UnoTreeListEntry : public SvLBoxEntry +{ +public: + UnoTreeListEntry( const Reference< XTreeNode >& xNode, TreeControlPeer* pPeer ); + virtual ~UnoTreeListEntry(); + + Reference< XTreeNode > mxNode; + TreeControlPeer* mpPeer; +}; + +// -------------------------------------------------------------------- + +class TreeNodeMap : public std::map< Reference< XTreeNode >, UnoTreeListEntry* > +{ +}; + +// -------------------------------------------------------------------- + +TreeControlPeer::TreeControlPeer() +: maSelectionListeners( *this ) +, maTreeExpansionListeners( *this ) +, maTreeEditListeners( *this ) +, mpTreeImpl( 0 ) +, mnEditLock( 0 ) +, mpTreeNodeMap( 0 ) +{ +} + +// -------------------------------------------------------------------- + +TreeControlPeer::~TreeControlPeer() +{ + if( mpTreeImpl ) + mpTreeImpl->Clear(); + delete mpTreeNodeMap; +} + +// -------------------------------------------------------------------- + +void TreeControlPeer::addEntry( UnoTreeListEntry* pEntry ) +{ + if( pEntry && pEntry->mxNode.is() ) + { + if( !mpTreeNodeMap ) + { + mpTreeNodeMap = new TreeNodeMap(); + } + + (*mpTreeNodeMap)[ pEntry->mxNode ] = pEntry; + } +} + +// -------------------------------------------------------------------- + +void TreeControlPeer::removeEntry( UnoTreeListEntry* pEntry ) +{ + if( mpTreeNodeMap && pEntry && pEntry->mxNode.is() ) + { + TreeNodeMap::iterator aIter( mpTreeNodeMap->find( pEntry->mxNode ) ); + if( aIter != mpTreeNodeMap->end() ) + { + mpTreeNodeMap->erase( aIter ); + } + } +} + +// -------------------------------------------------------------------- + +UnoTreeListEntry* TreeControlPeer::getEntry( const Reference< XTreeNode >& xNode, bool bThrow /* = true */ ) throw( IllegalArgumentException ) +{ + if( mpTreeNodeMap ) + { + TreeNodeMap::iterator aIter( mpTreeNodeMap->find( xNode ) ); + if( aIter != mpTreeNodeMap->end() ) + return (*aIter).second; + } + + if( bThrow ) + throw IllegalArgumentException(); + + return 0; +} + +// -------------------------------------------------------------------- + +Window* TreeControlPeer::createVclControl( Window* pParent, sal_Int64 nWinStyle ) +{ + mpTreeImpl = new UnoTreeListBoxImpl( this, pParent, nWinStyle ); + return mpTreeImpl; +} + +// -------------------------------------------------------------------- + +/** called from the UnoTreeListBoxImpl when it gets deleted */ +void TreeControlPeer::disposeControl() +{ + delete mpTreeNodeMap; + mpTreeNodeMap = 0; + mpTreeImpl = 0; +} + +// -------------------------------------------------------------------- + +void TreeControlPeer::SetWindow( Window* pWindow ) +{ + VCLXWindow::SetWindow( pWindow ); +} + +// -------------------------------------------------------------------- + +UnoTreeListEntry* TreeControlPeer::createEntry( const Reference< XTreeNode >& xNode, UnoTreeListEntry* pParent, ULONG nPos /* = LIST_APPEND */ ) +{ + UnoTreeListEntry* pEntry = 0; + if( mpTreeImpl ) + { + Image aImage; + pEntry = new UnoTreeListEntry( xNode, this ); + ImplContextGraphicItem* pContextBmp= new ImplContextGraphicItem( pEntry,0, aImage, aImage, SVLISTENTRYFLAG_EXPANDED ); + + pEntry->AddItem( pContextBmp ); + + UnoTreeListItem * pUnoItem = new UnoTreeListItem( pEntry ); + + if( xNode->getNodeGraphicURL().getLength() ) + { + pUnoItem->SetGraphicURL( xNode->getNodeGraphicURL() ); + Image aNodeImage; + loadImage( xNode->getNodeGraphicURL(), aNodeImage ); + pUnoItem->SetImage( aNodeImage ); + mpTreeImpl->AdjustEntryHeight( aNodeImage ); + } + + pEntry->AddItem( pUnoItem ); + + mpTreeImpl->insert( pEntry, pParent, nPos ); + + if( msDefaultExpandedGraphicURL.getLength() ) + mpTreeImpl->SetExpandedEntryBmp( pEntry, maDefaultExpandedImage ); + + if( msDefaultCollapsedGraphicURL.getLength() ) + mpTreeImpl->SetCollapsedEntryBmp( pEntry, maDefaultCollapsedImage ); + + updateEntry( pEntry ); + } + return pEntry; +} + +// -------------------------------------------------------------------- + +bool TreeControlPeer::updateEntry( UnoTreeListEntry* pEntry ) +{ + bool bChanged = false; + if( pEntry && pEntry->mxNode.is() && mpTreeImpl ) + { + const OUString aValue( getEntryString( pEntry->mxNode->getDisplayValue() ) ); + UnoTreeListItem* pUnoItem = dynamic_cast< UnoTreeListItem* >( pEntry->GetItem( 1 ) ); + if( pUnoItem ) + { + if( aValue != pUnoItem->GetText() ) + { + pUnoItem->SetText( aValue ); + bChanged = true; + } + + if( pUnoItem->GetGraphicURL() != pEntry->mxNode->getNodeGraphicURL() ) + { + Image aImage; + if( loadImage( pEntry->mxNode->getNodeGraphicURL(), aImage ) ) + { + pUnoItem->SetGraphicURL( pEntry->mxNode->getNodeGraphicURL() ); + pUnoItem->SetImage( aImage ); + mpTreeImpl->AdjustEntryHeight( aImage ); + bChanged = true; + } + } + } + + if( (pEntry->mxNode->hasChildrenOnDemand() == sal_True) != (pEntry->HasChildsOnDemand() == TRUE) ) + { + pEntry->EnableChildsOnDemand( pEntry->mxNode->hasChildrenOnDemand() ? TRUE : FALSE ); + bChanged = true; + } + + ImplContextGraphicItem* pContextGraphicItem = dynamic_cast< ImplContextGraphicItem* >( pEntry->GetItem( 0 ) ); + if( pContextGraphicItem ) + { + if( pContextGraphicItem->msExpandedGraphicURL != pEntry->mxNode->getExpandedGraphicURL() ) + { + Image aImage; + if( loadImage( pEntry->mxNode->getExpandedGraphicURL(), aImage ) ) + { + pContextGraphicItem->msExpandedGraphicURL = pEntry->mxNode->getExpandedGraphicURL(); + mpTreeImpl->SetExpandedEntryBmp( pEntry, aImage ); + bChanged = true; + } + } + if( pContextGraphicItem->msCollapsedGraphicURL != pEntry->mxNode->getCollapsedGraphicURL() ) + { + Image aImage; + if( loadImage( pEntry->mxNode->getCollapsedGraphicURL(), aImage ) ) + { + pContextGraphicItem->msCollapsedGraphicURL = pEntry->mxNode->getCollapsedGraphicURL(); + mpTreeImpl->SetCollapsedEntryBmp( pEntry, aImage ); + bChanged = true; + } + } + } + + if( bChanged ) + mpTreeImpl->GetModel()->InvalidateEntry( pEntry ); + } + + return bChanged; +} + +// -------------------------------------------------------------------- + +void TreeControlPeer::onSelectionChanged() +{ + Reference< XInterface > xSource( static_cast< ::cppu::OWeakObject* >( this ) ); + EventObject aEvent( xSource ); + maSelectionListeners.selectionChanged( aEvent ); +} + +// -------------------------------------------------------------------- + +void TreeControlPeer::onRequestChildNodes( const Reference< XTreeNode >& xNode ) +{ + try + { + Reference< XInterface > xSource( static_cast< ::cppu::OWeakObject* >( this ) ); + TreeExpansionEvent aEvent( xSource, xNode ); + maTreeExpansionListeners.requestChildNodes( aEvent ); + } + catch( Exception& ) + { + } +} + +// -------------------------------------------------------------------- + +bool TreeControlPeer::onExpanding( const Reference< XTreeNode >& xNode, bool bExpanding ) +{ + try + { + Reference< XInterface > xSource( static_cast< ::cppu::OWeakObject* >( this ) ); + TreeExpansionEvent aEvent( xSource, xNode ); + if( bExpanding ) + { + maTreeExpansionListeners.treeExpanding( aEvent ); + } + else + { + maTreeExpansionListeners.treeCollapsing( aEvent ); + } + } + catch( Exception& ) + { + return false; + } + return true; +} + +// -------------------------------------------------------------------- + +void TreeControlPeer::onExpanded( const Reference< XTreeNode >& xNode, bool bExpanding ) +{ + try + { + Reference< XInterface > xSource( static_cast< ::cppu::OWeakObject* >( this ) ); + TreeExpansionEvent aEvent( xSource, xNode ); + + if( bExpanding ) + { + maTreeExpansionListeners.treeExpanded( aEvent ); + } + else + { + maTreeExpansionListeners.treeCollapsed( aEvent ); + } + } + catch( Exception& ) + { + } +} + +// -------------------------------------------------------------------- + +void TreeControlPeer::fillTree( UnoTreeListBoxImpl& rTree, const Reference< XTreeDataModel >& xDataModel ) +{ + rTree.Clear(); + + if( xDataModel.is() ) + { + Reference< XTreeNode > xRootNode( xDataModel->getRoot() ); + if( xRootNode.is() ) + { + if( mbIsRootDisplayed ) + { + addNode( rTree, xRootNode, 0 ); + } + else + { + const sal_Int32 nChildCount = xRootNode->getChildCount(); + for( sal_Int32 nChild = 0; nChild < nChildCount; nChild++ ) + addNode( rTree, xRootNode->getChildAt( nChild ), 0 ); + } + } + } +} + +// -------------------------------------------------------------------- + +void TreeControlPeer::addNode( UnoTreeListBoxImpl& rTree, const Reference< XTreeNode >& xNode, UnoTreeListEntry* pParentEntry ) +{ + if( xNode.is() ) + { + UnoTreeListEntry* pEntry = createEntry( xNode, pParentEntry, LIST_APPEND ); + const sal_Int32 nChildCount = xNode->getChildCount(); + for( sal_Int32 nChild = 0; nChild < nChildCount; nChild++ ) + addNode( rTree, xNode->getChildAt( nChild ), pEntry ); + } +} + +// -------------------------------------------------------------------- + +UnoTreeListBoxImpl& TreeControlPeer::getTreeListBoxOrThrow() const throw (RuntimeException ) +{ + if( !mpTreeImpl ) + throw DisposedException(); + return *mpTreeImpl; +} + +// -------------------------------------------------------------------- + +void TreeControlPeer::ChangeNodesSelection( const Any& rSelection, bool bSelect, bool bSetSelection ) throw( RuntimeException, IllegalArgumentException ) +{ + ::vos::OGuard aGuard( GetMutex() ); + + UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow(); + + Reference< XTreeNode > xTempNode; + Sequence< XTreeNode > aTempSeq; + + const Reference< XTreeNode > *pNodes = 0; + sal_Int32 nCount = 0; + + if( rSelection.hasValue() ) + { + switch( rSelection.getValueTypeClass() ) + { + case TypeClass_INTERFACE: + { + rSelection >>= xTempNode; + if( xTempNode.is() ) + { + nCount = 1; + pNodes = &xTempNode; + } + break; + } + case TypeClass_SEQUENCE: + { + if( rSelection.getValueType() == ::getCppuType( (const Sequence< Reference< XTreeNode > > *) 0 ) ) + { + const Sequence< Reference< XTreeNode > >& rSeq( *(const Sequence< Reference< XTreeNode > > *)rSelection.getValue() ); + nCount = rSeq.getLength(); + if( nCount ) + pNodes = rSeq.getConstArray(); + } + break; + } + default: + break; + } + + if( nCount == 0 ) + throw IllegalArgumentException(); + } + + if( bSetSelection ) + rTree.SelectAll( FALSE ); + + if( pNodes && nCount ) + { + while( nCount-- ) + { + UnoTreeListEntry* pEntry = getEntry( *pNodes++ ); + rTree.Select( pEntry, bSelect ? TRUE : FALSE ); + } + } +} + +// ------------------------------------------------------------------- +// ::com::sun::star::view::XSelectionSupplier +// ------------------------------------------------------------------- + +sal_Bool SAL_CALL TreeControlPeer::select( const Any& rSelection ) throw (IllegalArgumentException, RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + ChangeNodesSelection( rSelection, true, true ); + return sal_True; +} + +// ------------------------------------------------------------------- + +Any SAL_CALL TreeControlPeer::getSelection() throw (RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow(); + + Any aRet; + + ULONG nSelectionCount = rTree.GetSelectionCount(); + if( nSelectionCount == 1 ) + { + UnoTreeListEntry* pEntry = dynamic_cast< UnoTreeListEntry* >( rTree.FirstSelected() ); + if( pEntry && pEntry->mxNode.is() ) + aRet <<= pEntry->mxNode; + } + else if( nSelectionCount > 1 ) + { + Sequence< Reference< XTreeNode > > aSelection( nSelectionCount ); + Reference< XTreeNode >* pNodes = aSelection.getArray(); + UnoTreeListEntry* pEntry = dynamic_cast< UnoTreeListEntry* >( rTree.FirstSelected() ); + while( pEntry && nSelectionCount ) + { + *pNodes++ = pEntry->mxNode; + pEntry = dynamic_cast< UnoTreeListEntry* >( rTree.NextSelected( pEntry ) ); + --nSelectionCount; + } + + OSL_ASSERT( (pEntry == 0) && (nSelectionCount == 0) ); + aRet <<= aSelection; + } + + return aRet; +} + +// ------------------------------------------------------------------- + +void SAL_CALL TreeControlPeer::addSelectionChangeListener( const Reference< XSelectionChangeListener >& xListener ) throw (RuntimeException) +{ + maSelectionListeners.addInterface( xListener ); +} + +// ------------------------------------------------------------------- + +void SAL_CALL TreeControlPeer::removeSelectionChangeListener( const Reference< XSelectionChangeListener >& xListener ) throw (RuntimeException) +{ + maSelectionListeners.addInterface( xListener ); +} + +// ------------------------------------------------------------------- +// ::com::sun::star::view::XMultiSelectionSupplier +// ------------------------------------------------------------------- + +sal_Bool SAL_CALL TreeControlPeer::addSelection( const Any& rSelection ) throw (IllegalArgumentException, RuntimeException) +{ + ChangeNodesSelection( rSelection, true, false ); + return sal_True; +} + +// ------------------------------------------------------------------- + +void SAL_CALL TreeControlPeer::removeSelection( const Any& rSelection ) throw (IllegalArgumentException, RuntimeException) +{ + ChangeNodesSelection( rSelection, false, false ); +} + +// ------------------------------------------------------------------- + +void SAL_CALL TreeControlPeer::clearSelection() throw (RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + getTreeListBoxOrThrow().SelectAll( FALSE ); +} + +// ------------------------------------------------------------------- + +sal_Int32 SAL_CALL TreeControlPeer::getSelectionCount() throw (RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + return getTreeListBoxOrThrow().GetSelectionCount(); +} + +// ------------------------------------------------------------------- + +class TreeSelectionEnumeration : public ::cppu::WeakImplHelper1< XEnumeration > +{ +public: + TreeSelectionEnumeration( std::list< Any >& rSelection ); + virtual ::sal_Bool SAL_CALL hasMoreElements() throw (RuntimeException); + virtual Any SAL_CALL nextElement() throw (NoSuchElementException, WrappedTargetException, RuntimeException); + + std::list< Any > maSelection; + std::list< Any >::iterator maIter; +}; + +// ------------------------------------------------------------------- + +TreeSelectionEnumeration::TreeSelectionEnumeration( std::list< Any >& rSelection ) +{ + maSelection.swap( rSelection ); + maIter = maSelection.begin(); +} + +// ------------------------------------------------------------------- + +::sal_Bool SAL_CALL TreeSelectionEnumeration::hasMoreElements() throw (RuntimeException) +{ + return maIter != maSelection.end(); +} + +// ------------------------------------------------------------------- + +Any SAL_CALL TreeSelectionEnumeration::nextElement() throw (NoSuchElementException, WrappedTargetException, RuntimeException) +{ + if( maIter == maSelection.end() ) + throw NoSuchElementException(); + + return (*maIter++); +} + +// ------------------------------------------------------------------- + +Reference< XEnumeration > SAL_CALL TreeControlPeer::createSelectionEnumeration() throw (RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow(); + + sal_uInt32 nSelectionCount = rTree.GetSelectionCount(); + std::list< Any > aSelection( nSelectionCount ); + + UnoTreeListEntry* pEntry = dynamic_cast< UnoTreeListEntry* >( rTree.FirstSelected() ); + while( pEntry && nSelectionCount ) + { + aSelection.push_back( Any( pEntry->mxNode ) ); + pEntry = dynamic_cast< UnoTreeListEntry* >( rTree.NextSelected( pEntry ) ); + --nSelectionCount; + } + + OSL_ASSERT( (pEntry == 0) && (nSelectionCount == 0) ); + + return Reference< XEnumeration >( new TreeSelectionEnumeration( aSelection ) ); +} + +// ------------------------------------------------------------------- + +Reference< XEnumeration > SAL_CALL TreeControlPeer::createReverseSelectionEnumeration() throw (RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow(); + + sal_uInt32 nSelectionCount = rTree.GetSelectionCount(); + std::list< Any > aSelection; + + UnoTreeListEntry* pEntry = dynamic_cast< UnoTreeListEntry* >( rTree.FirstSelected() ); + while( pEntry && nSelectionCount ) + { + aSelection.push_front( Any( pEntry->mxNode ) ); + pEntry = dynamic_cast< UnoTreeListEntry* >( rTree.NextSelected( pEntry ) ); + --nSelectionCount; + } + + OSL_ASSERT( (pEntry == 0) && (nSelectionCount == 0) ); + + return Reference< XEnumeration >( new TreeSelectionEnumeration( aSelection ) ); +} + +// -------------------------------------------------------------------- +// ::com::sun::star::awt::XTreeControl +// -------------------------------------------------------------------- + +OUString SAL_CALL TreeControlPeer::getDefaultExpandedGraphicURL() throw (::com::sun::star::uno::RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + return msDefaultExpandedGraphicURL; +} + +// -------------------------------------------------------------------- + +void SAL_CALL TreeControlPeer::setDefaultExpandedGraphicURL( const ::rtl::OUString& sDefaultExpandedGraphicURL ) throw (::com::sun::star::uno::RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + if( msDefaultExpandedGraphicURL != sDefaultExpandedGraphicURL ) + { + if( sDefaultExpandedGraphicURL.getLength() ) + loadImage( sDefaultExpandedGraphicURL, maDefaultExpandedImage ); + else + maDefaultExpandedImage = Image(); + + UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow(); + + SvLBoxEntry* pEntry = rTree.First(); + while( pEntry ) + { + ImplContextGraphicItem* pContextGraphicItem = dynamic_cast< ImplContextGraphicItem* >( pEntry->GetItem( 0 ) ); + if( pContextGraphicItem ) + { + if( pContextGraphicItem->msExpandedGraphicURL.getLength() == 0 ) + rTree.SetExpandedEntryBmp( pEntry, maDefaultExpandedImage ); + } + pEntry = rTree.Next( pEntry ); + } + + msDefaultExpandedGraphicURL = sDefaultExpandedGraphicURL; + } +} + +// -------------------------------------------------------------------- + +OUString SAL_CALL TreeControlPeer::getDefaultCollapsedGraphicURL() throw (::com::sun::star::uno::RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + return msDefaultCollapsedGraphicURL; +} + +// -------------------------------------------------------------------- + +void SAL_CALL TreeControlPeer::setDefaultCollapsedGraphicURL( const ::rtl::OUString& sDefaultCollapsedGraphicURL ) throw (::com::sun::star::uno::RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + if( msDefaultCollapsedGraphicURL != sDefaultCollapsedGraphicURL ) + { + if( sDefaultCollapsedGraphicURL.getLength() ) + loadImage( sDefaultCollapsedGraphicURL, maDefaultCollapsedImage ); + else + maDefaultCollapsedImage = Image(); + + UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow(); + + SvLBoxEntry* pEntry = rTree.First(); + while( pEntry ) + { + ImplContextGraphicItem* pContextGraphicItem = dynamic_cast< ImplContextGraphicItem* >( pEntry->GetItem( 0 ) ); + if( pContextGraphicItem ) + { + if( pContextGraphicItem->msCollapsedGraphicURL.getLength() == 0 ) + rTree.SetCollapsedEntryBmp( pEntry, maDefaultCollapsedImage ); + } + pEntry = rTree.Next( pEntry ); + } + + msDefaultCollapsedGraphicURL = sDefaultCollapsedGraphicURL; + } +} + +// -------------------------------------------------------------------- + +sal_Bool SAL_CALL TreeControlPeer::isNodeExpanded( const Reference< XTreeNode >& xNode ) throw (RuntimeException, IllegalArgumentException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow(); + UnoTreeListEntry* pEntry = getEntry( xNode ); + return ( pEntry && rTree.IsExpanded( pEntry ) ) ? sal_True : sal_False; +} + +// ------------------------------------------------------------------- + +sal_Bool SAL_CALL TreeControlPeer::isNodeCollapsed( const Reference< XTreeNode >& xNode ) throw (RuntimeException, IllegalArgumentException) +{ + ::vos::OGuard aGuard( GetMutex() ); + return !isNodeExpanded( xNode ); +} + +// ------------------------------------------------------------------- + +void SAL_CALL TreeControlPeer::makeNodeVisible( const Reference< XTreeNode >& xNode ) throw (RuntimeException, ExpandVetoException, IllegalArgumentException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow(); + UnoTreeListEntry* pEntry = getEntry( xNode ); + if( pEntry ) + rTree.MakeVisible( pEntry ); +} + +// ------------------------------------------------------------------- + +sal_Bool SAL_CALL TreeControlPeer::isNodeVisible( const Reference< XTreeNode >& xNode ) throw (RuntimeException, IllegalArgumentException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow(); + UnoTreeListEntry* pEntry = getEntry( xNode ); + return ( pEntry && rTree.IsEntryVisible( pEntry ) ) ? sal_True : sal_False; +} + +// ------------------------------------------------------------------- + +void SAL_CALL TreeControlPeer::expandNode( const Reference< XTreeNode >& xNode ) throw (RuntimeException, ExpandVetoException, IllegalArgumentException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow(); + UnoTreeListEntry* pEntry = getEntry( xNode ); + if( pEntry ) + rTree.Expand( pEntry ); +} + +// ------------------------------------------------------------------- + +void SAL_CALL TreeControlPeer::collapseNode( const Reference< XTreeNode >& xNode ) throw (RuntimeException, ExpandVetoException, IllegalArgumentException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow(); + UnoTreeListEntry* pEntry = getEntry( xNode ); + if( pEntry ) + rTree.Collapse( pEntry ); +} + +// ------------------------------------------------------------------- + +void SAL_CALL TreeControlPeer::addTreeExpansionListener( const Reference< XTreeExpansionListener >& xListener ) throw (RuntimeException) +{ + maTreeExpansionListeners.addInterface( xListener ); +} + +// ------------------------------------------------------------------- + +void SAL_CALL TreeControlPeer::removeTreeExpansionListener( const Reference< XTreeExpansionListener >& xListener ) throw (RuntimeException) +{ + maTreeExpansionListeners.removeInterface( xListener ); +} + +// ------------------------------------------------------------------- + +Reference< XTreeNode > SAL_CALL TreeControlPeer::getNodeForLocation( sal_Int32 x, sal_Int32 y ) throw (RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow(); + + Reference< XTreeNode > xNode; + + const Point aPos( x, y ); + UnoTreeListEntry* pEntry = dynamic_cast< UnoTreeListEntry* >( rTree.GetEntry( aPos, TRUE ) ); + if( pEntry ) + xNode = pEntry->mxNode; + + return xNode; +} + +// ------------------------------------------------------------------- + +Reference< XTreeNode > SAL_CALL TreeControlPeer::getClosestNodeForLocation( sal_Int32 x, sal_Int32 y ) throw (RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow(); + + Reference< XTreeNode > xNode; + + const Point aPos( x, y ); + UnoTreeListEntry* pEntry = dynamic_cast< UnoTreeListEntry* >( rTree.GetEntry( aPos, TRUE ) ); + if( pEntry ) + xNode = pEntry->mxNode; + + return xNode; +} + +// ------------------------------------------------------------------- + +awt::Rectangle SAL_CALL TreeControlPeer::getNodeRect( const Reference< XTreeNode >& i_Node ) throw (IllegalArgumentException, RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow(); + UnoTreeListEntry* pEntry = getEntry( i_Node, true ); + + ::Rectangle aEntryRect( rTree.GetFocusRect( pEntry, rTree.GetEntryPosition( pEntry ).Y() ) ); + return VCLUnoHelper::ConvertToAWTRect( aEntryRect ); +} + +// ------------------------------------------------------------------- + +sal_Bool SAL_CALL TreeControlPeer::isEditing( ) throw (RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow(); + return rTree.IsEditingActive() ? sal_True : sal_False; +} + +// ------------------------------------------------------------------- + +sal_Bool SAL_CALL TreeControlPeer::stopEditing() throw (RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow(); + if( rTree.IsEditingActive() ) + { + rTree.EndEditing(FALSE); + return sal_True; + } + else + { + return sal_False; + } +} + +// ------------------------------------------------------------------- + +void SAL_CALL TreeControlPeer::cancelEditing( ) throw (RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow(); + rTree.EndEditing(FALSE); +} + +// ------------------------------------------------------------------- + +void SAL_CALL TreeControlPeer::startEditingAtNode( const Reference< XTreeNode >& xNode ) throw (IllegalArgumentException, RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow(); + UnoTreeListEntry* pEntry = getEntry( xNode ); + rTree.EditEntry( pEntry ); +} + +void SAL_CALL TreeControlPeer::addTreeEditListener( const Reference< XTreeEditListener >& xListener ) throw (RuntimeException) +{ + maTreeEditListeners.addInterface( xListener ); +} + +void SAL_CALL TreeControlPeer::removeTreeEditListener( const Reference< XTreeEditListener >& xListener ) throw (RuntimeException) +{ + maTreeEditListeners.removeInterface( xListener ); +} + +bool TreeControlPeer::onEditingEntry( UnoTreeListEntry* pEntry ) +{ + if( mpTreeImpl && pEntry && pEntry->mxNode.is() && (maTreeEditListeners.getLength() > 0) ) + { + try + { + maTreeEditListeners.nodeEditing( pEntry->mxNode ); + } + catch( VetoException& ) + { + return false; + } + catch( Exception& ) + { + } + } + return true; +} + +bool TreeControlPeer::onEditedEntry( UnoTreeListEntry* pEntry, const XubString& rNewText ) +{ + if( mpTreeImpl && pEntry && pEntry->mxNode.is() ) try + { + LockGuard aLockGuard( mnEditLock ); + const OUString aNewText( rNewText ); + if( maTreeEditListeners.getLength() > 0 ) + { + maTreeEditListeners.nodeEdited( pEntry->mxNode, aNewText ); + return false; + } + else + { + Reference< XMutableTreeNode > xMutableNode( pEntry->mxNode, UNO_QUERY ); + if( xMutableNode.is() ) + xMutableNode->setDisplayValue( Any( aNewText ) ); + else + return false; + } + + } + catch( Exception& ) + { + } + + return true; +} + +// -------------------------------------------------------------------- +// ::com::sun::star::awt::tree::TreeDataModelListener +// -------------------------------------------------------------------- + +void SAL_CALL TreeControlPeer::treeNodesChanged( const ::com::sun::star::awt::tree::TreeDataModelEvent& rEvent ) throw (RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + if( mnEditLock != 0 ) + return; + + updateTree( rEvent, true ); +} + +void SAL_CALL TreeControlPeer::treeNodesInserted( const ::com::sun::star::awt::tree::TreeDataModelEvent& rEvent ) throw (RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + if( mnEditLock != 0 ) + return; + + updateTree( rEvent, true ); +} + +void SAL_CALL TreeControlPeer::treeNodesRemoved( const ::com::sun::star::awt::tree::TreeDataModelEvent& rEvent ) throw (RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + if( mnEditLock != 0 ) + return; + + updateTree( rEvent, true ); +} + +void SAL_CALL TreeControlPeer::treeStructureChanged( const ::com::sun::star::awt::tree::TreeDataModelEvent& rEvent ) throw (RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + if( mnEditLock != 0 ) + return; + + updateTree( rEvent, true ); +} + +void TreeControlPeer::updateTree( const ::com::sun::star::awt::tree::TreeDataModelEvent& rEvent, bool bRecursive ) +{ + UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow(); + + Sequence< Reference< XTreeNode > > Nodes; + Reference< XTreeNode > xNode( rEvent.ParentNode ); + if( !xNode.is() && Nodes.getLength() ) + { + xNode = Nodes[0]; + } + + if( xNode.is() ) + updateNode( rTree, xNode, bRecursive ); +} + +void TreeControlPeer::updateNode( UnoTreeListBoxImpl& rTree, const Reference< XTreeNode >& xNode, bool bRecursive ) +{ + if( xNode.is() ) + { + UnoTreeListEntry* pNodeEntry = getEntry( xNode, false ); + + if( !pNodeEntry ) + { + Reference< XTreeNode > xParentNode( xNode->getParent() ); + UnoTreeListEntry* pParentEntry = 0; + ULONG nChild = LIST_APPEND; + + if( xParentNode.is() ) + { + pParentEntry = getEntry( xParentNode ); + nChild = xParentNode->getIndex( xNode ); + } + + pNodeEntry = createEntry( xNode, pParentEntry, nChild ); + } + + if( bRecursive ) + updateChildNodes( rTree, xNode, pNodeEntry ); + } +} + +void TreeControlPeer::updateChildNodes( UnoTreeListBoxImpl& rTree, const Reference< XTreeNode >& xParentNode, UnoTreeListEntry* pParentEntry ) +{ + if( xParentNode.is() && pParentEntry ) + { + UnoTreeListEntry* pCurrentChild = dynamic_cast< UnoTreeListEntry* >( rTree.FirstChild( pParentEntry ) ); + + const sal_Int32 nChildCount = xParentNode->getChildCount(); + for( sal_Int32 nChild = 0; nChild < nChildCount; nChild++ ) + { + Reference< XTreeNode > xNode( xParentNode->getChildAt( nChild ) ); + if( !pCurrentChild || ( pCurrentChild->mxNode != xNode ) ) + { + UnoTreeListEntry* pNodeEntry = getEntry( xNode, false ); + if( pNodeEntry == 0 ) + { + // child node is not yet part of the tree, add it + pCurrentChild = createEntry( xNode, pParentEntry, nChild ); + } + else if( pNodeEntry != pCurrentChild ) + { + // node is already part of the tree, but not on the correct position + rTree.GetModel()->Move( pNodeEntry, pParentEntry, nChild ); + pCurrentChild = pNodeEntry; + updateEntry( pCurrentChild ); + } + } + else + { + // child node has entry and entry is equal to current entry, + // so no structural changes happened + updateEntry( pCurrentChild ); + } + + pCurrentChild = dynamic_cast< UnoTreeListEntry* >( rTree.NextSibling( pCurrentChild ) ); + } + + // check if we have entries without nodes left, we need to remove them + while( pCurrentChild ) + { + UnoTreeListEntry* pNextChild = dynamic_cast< UnoTreeListEntry* >( rTree.NextSibling( pCurrentChild ) ); + rTree.GetModel()->Remove( pCurrentChild ); + pCurrentChild = pNextChild; + } + } +} + +OUString TreeControlPeer::getEntryString( const Any& rValue ) +{ + OUString sValue; + if( rValue.hasValue() ) + { + switch( rValue.getValueTypeClass() ) + { + case TypeClass_SHORT: + case TypeClass_LONG: + { + sal_Int32 nValue = 0; + if( rValue >>= nValue ) + sValue = OUString::valueOf( nValue ); + break; + } + case TypeClass_BYTE: + case TypeClass_UNSIGNED_SHORT: + case TypeClass_UNSIGNED_LONG: + { + sal_uInt32 nValue = 0; + if( rValue >>= nValue ) + sValue = OUString::valueOf( (sal_Int64)nValue ); + break; + } + case TypeClass_HYPER: + { + sal_Int64 nValue = 0; + if( rValue >>= nValue ) + sValue = OUString::valueOf( nValue ); + break; + } + case TypeClass_UNSIGNED_HYPER: + { + sal_uInt64 nValue = 0; + if( rValue >>= nValue ) + sValue = OUString::valueOf( (sal_Int64)nValue ); + break; + } + case TypeClass_FLOAT: + case TypeClass_DOUBLE: + { + double fValue = 0.0; + if( rValue >>= fValue ) + sValue = OUString::valueOf( fValue ); + break; + } + case TypeClass_STRING: + rValue >>= sValue; + break; + /* + case TypeClass_INTERFACE: + // @todo + break; + case TypeClass_SEQUENCE: + { + Sequence< Any > aValues; + if( aValue >>= aValues ) + { + updateEntry( SvLBoxEntry& rEntry, aValues ); + return; + } + } + break; + */ + default: + break; + } + } + return sValue; +} + +// XEventListener +void SAL_CALL TreeControlPeer::disposing( const ::com::sun::star::lang::EventObject& ) throw(::com::sun::star::uno::RuntimeException) +{ + // model is disposed, so we clear our tree + ::vos::OGuard aGuard( GetMutex() ); + UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow(); + rTree.Clear(); + mxDataModel.clear(); +} + +void TreeControlPeer::onChangeDataModel( UnoTreeListBoxImpl& rTree, const Reference< XTreeDataModel >& xDataModel ) +{ + if( xDataModel.is() && (mxDataModel == xDataModel) ) + return; // do nothing + + Reference< XTreeDataModelListener > xListener( this ); + + if( mxDataModel.is() ) + mxDataModel->removeTreeDataModelListener( xListener ); + + if( !xDataModel.is() ) + { + static const OUString aSN( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.awt.tree.DefaultTreeDataModel" ) ); + Reference< XMultiServiceFactory > xORB( ::comphelper::getProcessServiceFactory() ); + if( xORB.is() ) + { + mxDataModel.query( xORB->createInstance( aSN ) ); + } + } + + mxDataModel = xDataModel; + + fillTree( rTree, mxDataModel ); + + if( mxDataModel.is() ) + mxDataModel->addTreeDataModelListener( xListener ); +} + +// -------------------------------------------------------------------- +// ::com::sun::star::awt::XLayoutConstrains +// -------------------------------------------------------------------- + +::com::sun::star::awt::Size TreeControlPeer::getMinimumSize() throw(RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + ::com::sun::star::awt::Size aSz; +/* todo + MultiLineEdit* pEdit = (MultiLineEdit*) GetWindow(); + if ( pEdit ) + aSz = AWTSize(pEdit->CalcMinimumSize()); +*/ + return aSz; +} + +::com::sun::star::awt::Size TreeControlPeer::getPreferredSize() throw(RuntimeException) +{ + return getMinimumSize(); +} + +::com::sun::star::awt::Size TreeControlPeer::calcAdjustedSize( const ::com::sun::star::awt::Size& rNewSize ) throw(RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + ::com::sun::star::awt::Size aSz = rNewSize; +/* todo + MultiLineEdit* pEdit = (MultiLineEdit*) GetWindow(); + if ( pEdit ) + aSz = AWTSize(pEdit->CalcAdjustedSize( VCLSize(rNewSize ))); +*/ + return aSz; +} + +// -------------------------------------------------------------------- +// ::com::sun::star::awt::XVclWindowPeer +// -------------------------------------------------------------------- + +void TreeControlPeer::setProperty( const ::rtl::OUString& PropertyName, const Any& aValue) throw(RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow(); + + switch( GetPropertyId( PropertyName ) ) + { + case BASEPROPERTY_HIDEINACTIVESELECTION: + { + sal_Bool bEnabled = sal_False; + if ( aValue >>= bEnabled ) + { + WinBits nStyle = rTree.GetWindowBits(); + if ( bEnabled ) + nStyle |= WB_HIDESELECTION; + else + nStyle &= ~WB_HIDESELECTION; + rTree.SetWindowBits( nStyle ); + } + } + break; + + case BASEPROPERTY_TREE_SELECTIONTYPE: + { + SelectionType eSelectionType; + if( aValue >>= eSelectionType ) + { + SelectionMode eSelMode; + switch( eSelectionType ) + { + case SelectionType_SINGLE: eSelMode = SINGLE_SELECTION; break; + case SelectionType_RANGE: eSelMode = RANGE_SELECTION; break; + case SelectionType_MULTI: eSelMode = MULTIPLE_SELECTION; break; + // case SelectionType_NONE: + default: eSelMode = NO_SELECTION; break; + } + if( rTree.GetSelectionMode() != eSelMode ) + rTree.SetSelectionMode( eSelMode ); + } + break; + } + + case BASEPROPERTY_TREE_DATAMODEL: + onChangeDataModel( rTree, Reference< XTreeDataModel >( aValue, UNO_QUERY ) ); + break; + case BASEPROPERTY_TREE_ROWHEIGHT: + { + sal_Int32 nHeight = 0; + if( aValue >>= nHeight ) + rTree.SetEntryHeight( (short)nHeight ); + break; + } + case BASEPROPERTY_TREE_EDITABLE: + { + sal_Bool bEnabled = false; + if( aValue >>= bEnabled ) + rTree.EnableInplaceEditing( bEnabled ? TRUE : FALSE ); + break; + } + case BASEPROPERTY_TREE_INVOKESSTOPNODEEDITING: + break; // @todo + case BASEPROPERTY_TREE_ROOTDISPLAYED: + { + sal_Bool bDisplayed = false; + if( (aValue >>= bDisplayed) && ( bDisplayed != mbIsRootDisplayed) ) + { + onChangeRootDisplayed(bDisplayed); + } + break; + } + case BASEPROPERTY_TREE_SHOWSHANDLES: + { + sal_Bool bEnabled = false; + if( aValue >>= bEnabled ) + { + WinBits nBits = rTree.GetWindowBits() & (~WB_HASLINES); + if( bEnabled ) + nBits |= WB_HASLINES; + if( nBits != rTree.GetWindowBits() ) + rTree.SetWindowBits( nBits ); + } + break; + } + case BASEPROPERTY_TREE_SHOWSROOTHANDLES: + { + sal_Bool bEnabled = false; + if( aValue >>= bEnabled ) + { + WinBits nBits = rTree.GetWindowBits() & (~WB_HASLINESATROOT); + if( bEnabled ) + nBits |= WB_HASLINESATROOT; + if( nBits != rTree.GetWindowBits() ) + rTree.SetWindowBits( nBits ); + } + break; + } + default: + VCLXWindow::setProperty( PropertyName, aValue ); + break; + } +} + +Any TreeControlPeer::getProperty( const ::rtl::OUString& PropertyName ) throw(RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + const sal_uInt16 nPropId = GetPropertyId( PropertyName ); + if( (nPropId >= BASEPROPERTY_TREE_START) && (nPropId <= BASEPROPERTY_TREE_END) ) + { + UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow(); + switch(nPropId) + { + case BASEPROPERTY_HIDEINACTIVESELECTION: + return Any( ( rTree.GetWindowBits() & WB_HIDESELECTION ) != 0 ? sal_True : sal_False ); + + case BASEPROPERTY_TREE_SELECTIONTYPE: + { + SelectionType eSelectionType; + + SelectionMode eSelMode = rTree.GetSelectionMode(); + switch( eSelMode ) + { + case SINGLE_SELECTION: eSelectionType = SelectionType_SINGLE; break; + case RANGE_SELECTION: eSelectionType = SelectionType_RANGE; break; + case MULTIPLE_SELECTION:eSelectionType = SelectionType_MULTI; break; +// case NO_SELECTION: + default: eSelectionType = SelectionType_NONE; break; + } + return Any( eSelectionType ); + } + case BASEPROPERTY_TREE_ROWHEIGHT: + return Any( (sal_Int32)rTree.GetEntryHeight() ); + case BASEPROPERTY_TREE_DATAMODEL: + return Any( mxDataModel ); + case BASEPROPERTY_TREE_EDITABLE: + return Any( rTree.IsInplaceEditingEnabled() ? sal_True : sal_False ); + case BASEPROPERTY_TREE_INVOKESSTOPNODEEDITING: + return Any( sal_True ); // @todo + case BASEPROPERTY_TREE_ROOTDISPLAYED: + return Any( mbIsRootDisplayed ); + case BASEPROPERTY_TREE_SHOWSHANDLES: + return Any( (rTree.GetWindowBits() & WB_HASLINES) != 0 ? sal_True : sal_False ); + case BASEPROPERTY_TREE_SHOWSROOTHANDLES: + return Any( (rTree.GetWindowBits() & WB_HASLINESATROOT) != 0 ? sal_True : sal_False ); + } + } + return VCLXWindow::getProperty( PropertyName ); +} + +void TreeControlPeer::onChangeRootDisplayed( sal_Bool bIsRootDisplayed ) +{ + if( mbIsRootDisplayed == bIsRootDisplayed ) + return; + + mbIsRootDisplayed = bIsRootDisplayed; + + UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow(); + + if( rTree.GetEntryCount() == 0 ) + return; + + // todo + fillTree( rTree, mxDataModel ); + if( mbIsRootDisplayed ) + { + } + else + { + } +} + +bool TreeControlPeer::loadImage( const ::rtl::OUString& rURL, Image& rImage ) +{ + if( !mxGraphicProvider.is() ) + { + static const OUString aSN( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.graphic.GraphicProvider" ) ); + Reference< XMultiServiceFactory > xORB( ::comphelper::getProcessServiceFactory() ); + if( xORB.is() ) + { + Reference< XInterface > x( xORB->createInstance( aSN ) ); + mxGraphicProvider.query( x ); + mxGraphicProvider = Reference< XGraphicProvider >( x, UNO_QUERY ); + } + } + + if( mxGraphicProvider.is() ) try + { + ::com::sun::star::beans::PropertyValues aProps( 1 ); + aProps[0].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "URL" ) ); + aProps[0].Value <<= rURL; + + Reference< XGraphic > xGraphic( mxGraphicProvider->queryGraphic( aProps ) ); + + Graphic aGraphic( xGraphic ); + rImage = aGraphic.GetBitmapEx(); + return true; + } + catch( Exception& ) + { + } + + return false; +} + +// ==================================================================== +// class UnoTreeListBoxImpl +// ==================================================================== + +UnoTreeListBoxImpl::UnoTreeListBoxImpl( TreeControlPeer* pPeer, Window* pParent, WinBits nWinStyle ) +: SvTreeListBox( pParent, nWinStyle ) +, mxPeer( pPeer ) +{ + SetWindowBits( WB_BORDER | WB_HASLINES |WB_HASBUTTONS | WB_HASLINESATROOT | WB_HASBUTTONSATROOT | WB_HSCROLL ); + SetNodeDefaultImages(); + SetSelectHdl( LINK(this, UnoTreeListBoxImpl, OnSelectionChangeHdl) ); + SetDeselectHdl( LINK(this, UnoTreeListBoxImpl, OnSelectionChangeHdl) ); + + SetExpandingHdl( LINK(this, UnoTreeListBoxImpl, OnExpandingHdl) ); + SetExpandedHdl( LINK(this, UnoTreeListBoxImpl, OnExpandedHdl) ); + +} + +// -------------------------------------------------------------------- + +UnoTreeListBoxImpl::~UnoTreeListBoxImpl() +{ + if( mxPeer.is() ) + mxPeer->disposeControl(); +} + +// -------------------------------------------------------------------- + +IMPL_LINK( UnoTreeListBoxImpl, OnSelectionChangeHdl, UnoTreeListBoxImpl*, EMPTYARG ) +{ + if( mxPeer.is() ) + mxPeer->onSelectionChanged(); + return 0; +} + +// -------------------------------------------------------------------- + +IMPL_LINK(UnoTreeListBoxImpl, OnExpandingHdl, UnoTreeListBoxImpl*, EMPTYARG ) +{ + UnoTreeListEntry* pEntry = dynamic_cast< UnoTreeListEntry* >( GetHdlEntry() ); + + if( pEntry && mxPeer.is() ) + { + return mxPeer->onExpanding( pEntry->mxNode, !IsExpanded( pEntry ) ) ? 1 : 0; + } + return 0; +} + +// -------------------------------------------------------------------- + +IMPL_LINK(UnoTreeListBoxImpl, OnExpandedHdl, UnoTreeListBoxImpl*, EMPTYARG ) +{ + UnoTreeListEntry* pEntry = dynamic_cast< UnoTreeListEntry* >( GetHdlEntry() ); + if( pEntry && mxPeer.is() ) + { + mxPeer->onExpanded( pEntry->mxNode, IsExpanded( pEntry ) ); + } + return 0; +} + +// -------------------------------------------------------------------- + +sal_uInt32 UnoTreeListBoxImpl::insert( SvLBoxEntry* pEntry,SvLBoxEntry* pParent,ULONG nPos ) +{ + if( pParent ) + return SvTreeListBox::Insert( pEntry, pParent, nPos ); + else + return SvTreeListBox::Insert( pEntry, nPos ); +} + +// -------------------------------------------------------------------- + +void UnoTreeListBoxImpl::RequestingChilds( SvLBoxEntry* pParent ) +{ + UnoTreeListEntry* pEntry = dynamic_cast< UnoTreeListEntry* >( pParent ); + if( pEntry && pEntry->mxNode.is() && mxPeer.is() ) + mxPeer->onRequestChildNodes( pEntry->mxNode ); +} + +// -------------------------------------------------------------------- + +BOOL UnoTreeListBoxImpl::EditingEntry( SvLBoxEntry* pEntry, Selection& ) +{ + return mxPeer.is() ? mxPeer->onEditingEntry( dynamic_cast< UnoTreeListEntry* >( pEntry ) ) : false; +} + +// -------------------------------------------------------------------- + +BOOL UnoTreeListBoxImpl::EditedEntry( SvLBoxEntry* pEntry, const XubString& rNewText ) +{ + return mxPeer.is() ? mxPeer->onEditedEntry( dynamic_cast< UnoTreeListEntry* >( pEntry ), rNewText ) : false; +} + +// ==================================================================== +// class UnoTreeListItem +// ==================================================================== + +UnoTreeListItem::UnoTreeListItem( SvLBoxEntry* pEntry ) +: SvLBoxItem( pEntry, 0 ) +{ +} + +// -------------------------------------------------------------------- + +UnoTreeListItem::UnoTreeListItem() +: SvLBoxItem() +{ +} + +// -------------------------------------------------------------------- + +UnoTreeListItem::~UnoTreeListItem() +{ +} + +// -------------------------------------------------------------------- + +USHORT UnoTreeListItem::IsA() +{ + return 0; +} + +// -------------------------------------------------------------------- + +void UnoTreeListItem::Paint( const Point& rPos, SvLBox& rDev, USHORT /* nFlags */, SvLBoxEntry* _pEntry) +{ + Point aPos( rPos ); + if( _pEntry ) + { + Size aSize( GetSize(&rDev,_pEntry) ); + if( !!maImage ) + { + rDev.DrawImage( aPos, maImage, rDev.IsEnabled() ? 0 : IMAGE_DRAW_DISABLE ); + int nWidth = maImage.GetSizePixel().Width() + 6; + aPos.X() += nWidth; + aSize.Width() -= nWidth; + } + rDev.DrawText( Rectangle(aPos,aSize),maText, rDev.IsEnabled() ? 0 : TEXT_DRAW_DISABLE ); + } + else + { + if( !!maImage ) + { + rDev.DrawImage( aPos, maImage, rDev.IsEnabled() ? 0 : IMAGE_DRAW_DISABLE); + aPos.X() += maImage.GetSizePixel().Width() + 6; + } + rDev.DrawText( aPos, maText); + } +} + +// -------------------------------------------------------------------- + +SvLBoxItem* UnoTreeListItem::Create() const +{ + return new UnoTreeListItem; +} + +// -------------------------------------------------------------------- + +void UnoTreeListItem::Clone( SvLBoxItem* pSource ) +{ + UnoTreeListItem* pSourceItem = dynamic_cast< UnoTreeListItem* >( pSource ); + if( pSourceItem ) + { + maText = pSourceItem->maText; + maImage = pSourceItem->maImage; + } +} + +// -------------------------------------------------------------------- + +OUString UnoTreeListItem::GetText() const +{ + return maText; +} + +// -------------------------------------------------------------------- + +void UnoTreeListItem::SetText( const OUString& rText ) +{ + maText = rText; +} + +// -------------------------------------------------------------------- + +void UnoTreeListItem::SetImage( const Image& rImage ) +{ + maImage = rImage; +} + +// -------------------------------------------------------------------- + +OUString UnoTreeListItem::GetGraphicURL() const +{ + return maGraphicURL; +} + +// -------------------------------------------------------------------- + +void UnoTreeListItem::SetGraphicURL( const OUString& rGraphicURL ) +{ + maGraphicURL = rGraphicURL; +} + +// -------------------------------------------------------------------- + +void UnoTreeListItem::InitViewData( SvLBox* pView,SvLBoxEntry* pEntry, SvViewDataItem* pViewData) +{ + if( !pViewData ) + pViewData = pView->GetViewDataItem( pEntry, this ); + + pViewData->aSize = maImage.GetSizePixel(); + + const Size aTextSize(pView->GetTextWidth( maText ), pView->GetTextHeight()); + if( pViewData->aSize.Width() ) + { + pViewData->aSize.Width() += 6 + aTextSize.Width(); + if( pViewData->aSize.Height() < aTextSize.Height() ) + pViewData->aSize.Height() = aTextSize.Height(); + } + else + { + pViewData->aSize = aTextSize; + } +} + +// -------------------------------------------------------------------- + +UnoTreeListEntry::UnoTreeListEntry( const Reference< XTreeNode >& xNode, TreeControlPeer* pPeer ) +: SvLBoxEntry() +, mxNode( xNode ) +, mpPeer( pPeer ) +{ + if( mpPeer ) + mpPeer->addEntry( this ); +} + +// -------------------------------------------------------------------- + +UnoTreeListEntry::~UnoTreeListEntry() +{ + if( mpPeer ) + mpPeer->removeEntry( this ); +} diff --git a/svtools/source/uno/treecontrolpeer.hxx b/svtools/source/uno/treecontrolpeer.hxx new file mode 100644 index 000000000000..336830804a6f --- /dev/null +++ b/svtools/source/uno/treecontrolpeer.hxx @@ -0,0 +1,174 @@ +/************************************************************************* + * + * 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. + * + ************************************************************************/ + +#ifndef _TREE_CONTROL_PEER_HXX_ +#define _TREE_CONTROL_PEER_HXX_ + +#include <com/sun/star/awt/tree/XTreeControl.hpp> +#include <com/sun/star/awt/tree/XTreeDataModel.hpp> +#include <com/sun/star/graphic/XGraphicProvider.hpp> + +#include <toolkit/awt/vclxwindow.hxx> +#include <toolkit/awt/vclxwindows.hxx> + +#include <vcl/image.hxx> + +//#include <comphelper/uno3.hxx> +#include <cppuhelper/implbase2.hxx> + + +class UnoTreeListEntry; +class TreeControlPeer; +class UnoTreeListBoxImpl; +class TreeNodeMap; + +// ---------------------------------------------------- +// class TreeControlPeer +// ---------------------------------------------------- +class TreeControlPeer : public ::cppu::ImplInheritanceHelper2< VCLXWindow, ::com::sun::star::awt::tree::XTreeControl, ::com::sun::star::awt::tree::XTreeDataModelListener > +{ + friend class UnoTreeListBoxImpl; + friend class UnoTreeListEntry; +public: + TreeControlPeer(); + virtual ~TreeControlPeer(); + + Window* createVclControl( Window* pParent, sal_Int64 nWinStyle ); + + // VCLXWindow + virtual void SetWindow( Window* pWindow ); + + // ::com::sun::star::view::XSelectionSupplier + virtual ::sal_Bool SAL_CALL select( const ::com::sun::star::uno::Any& xSelection ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Any SAL_CALL getSelection( ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL addSelectionChangeListener( const ::com::sun::star::uno::Reference< ::com::sun::star::view::XSelectionChangeListener >& xListener ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL removeSelectionChangeListener( const ::com::sun::star::uno::Reference< ::com::sun::star::view::XSelectionChangeListener >& xListener ) throw (::com::sun::star::uno::RuntimeException); + + // ::com::sun::star::view::XMultiSelectionSupplier + virtual ::sal_Bool SAL_CALL addSelection( const ::com::sun::star::uno::Any& Selection ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL removeSelection( const ::com::sun::star::uno::Any& Selection ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL clearSelection( ) throw (::com::sun::star::uno::RuntimeException); + virtual ::sal_Int32 SAL_CALL getSelectionCount( ) throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Reference< ::com::sun::star::container::XEnumeration > SAL_CALL createSelectionEnumeration( ) throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Reference< ::com::sun::star::container::XEnumeration > SAL_CALL createReverseSelectionEnumeration( ) throw (::com::sun::star::uno::RuntimeException); + + // ::com::sun::star::awt::XTreeControl + virtual ::rtl::OUString SAL_CALL getDefaultExpandedGraphicURL() throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setDefaultExpandedGraphicURL( const ::rtl::OUString& _defaultexpandedgraphicurl ) throw (::com::sun::star::uno::RuntimeException); + virtual ::rtl::OUString SAL_CALL getDefaultCollapsedGraphicURL() throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setDefaultCollapsedGraphicURL( const ::rtl::OUString& _defaultcollapsedgraphicurl ) throw (::com::sun::star::uno::RuntimeException); + virtual ::sal_Bool SAL_CALL isNodeExpanded( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::tree::XTreeNode >& Node ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException); + virtual ::sal_Bool SAL_CALL isNodeCollapsed( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::tree::XTreeNode >& Node ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL makeNodeVisible( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::tree::XTreeNode >& Node ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::awt::tree::ExpandVetoException, ::com::sun::star::uno::RuntimeException); + virtual ::sal_Bool SAL_CALL isNodeVisible( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::tree::XTreeNode >& Node ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL expandNode( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::tree::XTreeNode >& Node ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::awt::tree::ExpandVetoException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL collapseNode( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::tree::XTreeNode >& Node ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::awt::tree::ExpandVetoException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL addTreeExpansionListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::tree::XTreeExpansionListener >& Listener ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL removeTreeExpansionListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::tree::XTreeExpansionListener >& Listener ) throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Reference< ::com::sun::star::awt::tree::XTreeNode > SAL_CALL getNodeForLocation( ::sal_Int32 x, ::sal_Int32 y ) throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Reference< ::com::sun::star::awt::tree::XTreeNode > SAL_CALL getClosestNodeForLocation( ::sal_Int32 x, ::sal_Int32 y ) throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::awt::Rectangle SAL_CALL getNodeRect( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::tree::XTreeNode >& Node ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException); + virtual ::sal_Bool SAL_CALL isEditing( ) throw (::com::sun::star::uno::RuntimeException); + virtual ::sal_Bool SAL_CALL stopEditing( ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL cancelEditing( ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL startEditingAtNode( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::tree::XTreeNode >& Node ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL addTreeEditListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::tree::XTreeEditListener >& Listener ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL removeTreeEditListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::tree::XTreeEditListener >& Listener ) throw (::com::sun::star::uno::RuntimeException); + + // ::com::sun::star::awt::tree::TreeDataModelListener + virtual void SAL_CALL treeNodesChanged( const ::com::sun::star::awt::tree::TreeDataModelEvent& aEvent ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL treeNodesInserted( const ::com::sun::star::awt::tree::TreeDataModelEvent& aEvent ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL treeNodesRemoved( const ::com::sun::star::awt::tree::TreeDataModelEvent& aEvent ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL treeStructureChanged( const ::com::sun::star::awt::tree::TreeDataModelEvent& aEvent ) throw (::com::sun::star::uno::RuntimeException); + + // XEventListener + void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source ) throw(::com::sun::star::uno::RuntimeException); + + // ::com::sun::star::awt::XLayoutConstrains + ::com::sun::star::awt::Size SAL_CALL getMinimumSize() throw(::com::sun::star::uno::RuntimeException); + ::com::sun::star::awt::Size SAL_CALL getPreferredSize() throw(::com::sun::star::uno::RuntimeException); + ::com::sun::star::awt::Size SAL_CALL calcAdjustedSize( const ::com::sun::star::awt::Size& aNewSize ) throw(::com::sun::star::uno::RuntimeException); + + // ::com::sun::star::awt::XVclWindowPeer + void SAL_CALL setProperty( const ::rtl::OUString& PropertyName, const ::com::sun::star::uno::Any& Value ) throw(::com::sun::star::uno::RuntimeException); + ::com::sun::star::uno::Any SAL_CALL getProperty( const ::rtl::OUString& PropertyName ) throw(::com::sun::star::uno::RuntimeException); + +private: + UnoTreeListEntry* getEntry( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::tree::XTreeNode >& xNode, bool bThrow = true ) throw (::com::sun::star::lang::IllegalArgumentException ); + + void disposeControl(); + + bool onEditingEntry( UnoTreeListEntry* pEntry ); + bool onEditedEntry( UnoTreeListEntry* pEntry, const XubString& rNewText ); + + void eraseTree( UnoTreeListBoxImpl& rTree ); + void fillTree( UnoTreeListBoxImpl& rTree, const ::com::sun::star::uno::Reference< ::com::sun::star::awt::tree::XTreeDataModel >& xDataModel ); + void addNode( UnoTreeListBoxImpl& rTree, const ::com::sun::star::uno::Reference< ::com::sun::star::awt::tree::XTreeNode >& xNode, UnoTreeListEntry* pParentEntry ); + + UnoTreeListEntry* createEntry( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::tree::XTreeNode >& xNode, UnoTreeListEntry* pParent, ULONG nPos = LIST_APPEND ); + bool updateEntry( UnoTreeListEntry* pEntry ); + + void updateTree( const ::com::sun::star::awt::tree::TreeDataModelEvent& rEvent, bool bRecursive ); + void updateNode( UnoTreeListBoxImpl& rTree, const ::com::sun::star::uno::Reference< ::com::sun::star::awt::tree::XTreeNode >& xNode, bool bRecursive ); + void updateChildNodes( UnoTreeListBoxImpl& rTree, const ::com::sun::star::uno::Reference< ::com::sun::star::awt::tree::XTreeNode >& xParentNode, UnoTreeListEntry* pParentEntry ); + + ::rtl::OUString getEntryString( const ::com::sun::star::uno::Any& rValue ); + + UnoTreeListBoxImpl& getTreeListBoxOrThrow() const throw (::com::sun::star::uno::RuntimeException ); + void ChangeNodesSelection( const ::com::sun::star::uno::Any& rSelection, bool bSelect, bool bSetSelection ) throw( ::com::sun::star::uno::RuntimeException, ::com::sun::star::lang::IllegalArgumentException ); + + void onChangeDataModel( UnoTreeListBoxImpl& rTree, const ::com::sun::star::uno::Reference< ::com::sun::star::awt::tree::XTreeDataModel >& xDataModel ); + + void onSelectionChanged(); + void onRequestChildNodes( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::tree::XTreeNode >& xNode ); + bool onExpanding( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::tree::XTreeNode >& xNode, bool bExpanding ); + void onExpanded( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::tree::XTreeNode >& xNode, bool bExpanding ); + + void onChangeRootDisplayed( sal_Bool bIsRootDisplayed ); + + void addEntry( UnoTreeListEntry* pEntry ); + void removeEntry( UnoTreeListEntry* pEntry ); + + bool loadImage( const ::rtl::OUString& rURL, Image& rImage ); + +private: + ::com::sun::star::uno::Reference< ::com::sun::star::awt::tree::XTreeDataModel >mxDataModel; + TreeSelectionListenerMultiplexer maSelectionListeners; + TreeExpansionListenerMultiplexer maTreeExpansionListeners; + TreeEditListenerMultiplexer maTreeEditListeners; + sal_Bool mbIsRootDisplayed; + UnoTreeListBoxImpl* mpTreeImpl; + sal_Int32 mnEditLock; + ::rtl::OUString msDefaultCollapsedGraphicURL; + ::rtl::OUString msDefaultExpandedGraphicURL; + Image maDefaultExpandedImage; + Image maDefaultCollapsedImage; + TreeNodeMap* mpTreeNodeMap; + ::com::sun::star::uno::Reference< ::com::sun::star::graphic::XGraphicProvider > mxGraphicProvider; +}; + +#endif // _TREE_CONTROL_PEER_HXX_ diff --git a/svtools/source/uno/unocontroltablemodel.cxx b/svtools/source/uno/unocontroltablemodel.cxx new file mode 100644 index 000000000000..d239ee3c740d --- /dev/null +++ b/svtools/source/uno/unocontroltablemodel.cxx @@ -0,0 +1,513 @@ +/************************************************************************* + * + * 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_svtools.hxx" + +#include "unocontroltablemodel.hxx" +#include <com/sun/star/view/SelectionType.hpp> +#include "svtools/table/gridtablerenderer.hxx" +#include "svtools/table/defaultinputhandler.hxx" +#include "svtools/table/tablecontrol.hxx" +#include <comphelper/sequence.hxx> +#include <rtl/ref.hxx> +#include <tools/debug.hxx> +#include <toolkit/helper/property.hxx> +#include <comphelper/processfactory.hxx> +#include <com/sun/star/awt/grid/XGridColumn.hpp> + +using ::rtl::OUString; +using namespace ::svt::table; +using namespace ::com::sun::star::uno; + + + //-------------------------------------------------------------------- + UnoControlTableColumn::UnoControlTableColumn(Reference<XGridColumn> m_xGridColumn) + :m_nID( 0 ) + ,m_sName() + ,m_bIsResizable( true ) + ,m_nWidth( 4 ) + ,m_nMinWidth( 0 ) + ,m_nMaxWidth( 0 ) + ,m_nPrefWidth ( 0 ) + ,m_xHorizontalAlign(com::sun::star::style::HorizontalAlignment(0)) + { + m_sName = m_xGridColumn->getTitle(); + } + //-------------------------------------------------------------------- + UnoControlTableColumn::UnoControlTableColumn() + :m_nID( 0 ) + ,m_sName() + ,m_bIsResizable( true ) + ,m_nWidth( 4 ) + ,m_nMinWidth( 0 ) + ,m_nMaxWidth( 0 ) + ,m_nPrefWidth ( 0 ) + ,m_xHorizontalAlign(com::sun::star::style::HorizontalAlignment(0)) + { + } + + //-------------------------------------------------------------------- + ColumnID UnoControlTableColumn::getID() const + { + return m_nID; + } + + //-------------------------------------------------------------------- + bool UnoControlTableColumn::setID( const ColumnID _nID ) + { + m_nID = _nID; + return true; + } + + //-------------------------------------------------------------------- + String UnoControlTableColumn::getName() const + { + return m_sName; + } + + //-------------------------------------------------------------------- + void UnoControlTableColumn::setName( const String& _rName ) + { + m_sName = _rName; + } + //-------------------------------------------------------------------- + bool UnoControlTableColumn::isResizable() const + { + return m_bIsResizable; + } + + //-------------------------------------------------------------------- + void UnoControlTableColumn::setResizable( bool _bResizable ) + { + m_bIsResizable = _bResizable; + } + + //-------------------------------------------------------------------- + TableMetrics UnoControlTableColumn::getWidth() const + { + return m_nWidth; + } + + //-------------------------------------------------------------------- + void UnoControlTableColumn::setWidth( TableMetrics _nWidth ) + { + m_nWidth = _nWidth; + } + + //-------------------------------------------------------------------- + TableMetrics UnoControlTableColumn::getMinWidth() const + { + return m_nMinWidth; + } + + //-------------------------------------------------------------------- + void UnoControlTableColumn::setMinWidth( TableMetrics _nMinWidth ) + { + m_nMinWidth = _nMinWidth; + } + + //-------------------------------------------------------------------- + TableMetrics UnoControlTableColumn::getMaxWidth() const + { + return m_nMaxWidth; + } + + //-------------------------------------------------------------------- + void UnoControlTableColumn::setMaxWidth( TableMetrics _nMaxWidth ) + { + m_nMaxWidth = _nMaxWidth; + } + //-------------------------------------------------------------------- + TableMetrics UnoControlTableColumn::getPreferredWidth() const + { + return m_nPrefWidth; + } + + //-------------------------------------------------------------------- + void UnoControlTableColumn::setPreferredWidth( TableMetrics _nPrefWidth ) + { + m_nPrefWidth = _nPrefWidth; + } + //-------------------------------------------------------------------- + ::com::sun::star::style::HorizontalAlignment UnoControlTableColumn::getHorizontalAlign() + { + return m_xHorizontalAlign; + } + + //-------------------------------------------------------------------- + void UnoControlTableColumn::setHorizontalAlign( com::sun::star::style::HorizontalAlignment _align ) + { + m_xHorizontalAlign = _align; + } + + //==================================================================== + //= DefaultTableModel_Impl + //==================================================================== + struct UnoControlTableModel_Impl + { + ::std::vector< PColumnModel > aColumns; + TableSize nRowCount; + bool bHasColumnHeaders; + bool bHasRowHeaders; + bool bVScroll; + bool bHScroll; + PTableRenderer pRenderer; + PTableInputHandler pInputHandler; + TableMetrics nRowHeight; + TableMetrics nColumnHeaderHeight; + TableMetrics nRowHeaderWidth; + std::vector<rtl::OUString> aRowHeadersTitle; + std::vector<std::vector< Any > > aCellContent; + ::com::sun::star::util::Color m_xLineColor; + ::com::sun::star::util::Color m_xHeaderColor; + ::com::sun::star::util::Color m_xTextColor; + ::com::sun::star::util::Color m_xRowColor1; + ::com::sun::star::util::Color m_xRowColor2; + ::com::sun::star::style::VerticalAlignment m_xVerticalAlign; + + UnoControlTableModel_Impl() + :aColumns ( ) + ,nRowCount ( 0 ) + ,bHasColumnHeaders ( false ) + ,bHasRowHeaders ( false ) + ,bVScroll ( false ) + ,bHScroll ( false ) + ,pRenderer ( ) + ,pInputHandler ( ) + ,nRowHeight ( 0 ) + ,nColumnHeaderHeight( 0 ) + ,nRowHeaderWidth ( 10 ) + ,aRowHeadersTitle ( ) + ,aCellContent ( ) + ,m_xLineColor ( 0xFFFFFF ) + ,m_xHeaderColor ( 0xFFFFFF ) + ,m_xTextColor ( 0 )//black as default + ,m_xRowColor1 ( 0xFFFFFF ) + ,m_xRowColor2 ( 0xFFFFFF ) + ,m_xVerticalAlign (com::sun::star::style::VerticalAlignment(0)) + { + } + }; + + //==================================================================== + //= UnoControlTableModel + //==================================================================== + //-------------------------------------------------------------------- + UnoControlTableModel::UnoControlTableModel() + :m_pImpl( new UnoControlTableModel_Impl ) + { + m_pImpl->bHasColumnHeaders = false; + m_pImpl->bHasRowHeaders = false; + m_pImpl->pRenderer.reset( new GridTableRenderer( *this ) ); + m_pImpl->pInputHandler.reset( new DefaultInputHandler ); + } + + //-------------------------------------------------------------------- + UnoControlTableModel::~UnoControlTableModel() + { + DELETEZ( m_pImpl ); + } + + //-------------------------------------------------------------------- + TableSize UnoControlTableModel::getColumnCount() const + { + return (TableSize)m_pImpl->aColumns.size(); + } + + //-------------------------------------------------------------------- + TableSize UnoControlTableModel::getRowCount() const + { + return m_pImpl->nRowCount; + } + + //-------------------------------------------------------------------- + bool UnoControlTableModel::hasColumnHeaders() const + { + return m_pImpl->bHasColumnHeaders; + } + + //-------------------------------------------------------------------- + bool UnoControlTableModel::hasRowHeaders() const + { + return m_pImpl->bHasRowHeaders; + } + + //-------------------------------------------------------------------- + void UnoControlTableModel::setRowHeaders(bool _bRowHeaders) + { + m_pImpl->bHasRowHeaders = _bRowHeaders; + } + //-------------------------------------------------------------------- + void UnoControlTableModel::setColumnHeaders(bool _bColumnHeaders) + { + m_pImpl->bHasColumnHeaders = _bColumnHeaders; + } + + void UnoControlTableModel::setColumnCount(TableSize _nColCount) + { + m_pImpl->aColumns.resize( _nColCount); + } + //-------------------------------------------------------------------- + void UnoControlTableModel::setRowCount(TableSize _nRowCount) + { + m_pImpl->nRowCount = _nRowCount; + } + //-------------------------------------------------------------------- + bool UnoControlTableModel::isCellEditable( ColPos col, RowPos row ) const + { + (void)col; + (void)row; + return false; + } + + //-------------------------------------------------------------------- + void UnoControlTableModel::addTableModelListener( const PTableModelListener& listener ) + { + (void) listener; + // TODO + DBG_ERROR( "DefaultTableModel::addTableModelListener: not yet implemented!" ); + } + + //-------------------------------------------------------------------- + void UnoControlTableModel::removeTableModelListener( const PTableModelListener& listener ) + { + (void)listener; + // TODO + DBG_ERROR( "DefaultTableModel::removeTableModelListener: not yet implemented!" ); + } + + //-------------------------------------------------------------------- + PColumnModel UnoControlTableModel::getColumnModel( ColPos column ) + { + DBG_ASSERT( ( column >= 0 ) && ( column < getColumnCount() ), + "DefaultTableModel::getColumnModel: invalid index!" ); + return m_pImpl->aColumns[ column ]; + } + + //-------------------------------------------------------------------- + std::vector<PColumnModel>& UnoControlTableModel::getColumnModel() + { + return m_pImpl->aColumns; + } + //-------------------------------------------------------------------- + PColumnModel UnoControlTableModel::getColumnModelByID( ColumnID id ) + { + (void)id; + // TODO + DBG_ERROR( "DefaultTableModel::getColumnModelByID: not yet implemented!" ); + return PColumnModel(); + } + + //-------------------------------------------------------------------- + PTableRenderer UnoControlTableModel::getRenderer() const + { + return m_pImpl->pRenderer; + } + + //-------------------------------------------------------------------- + PTableInputHandler UnoControlTableModel::getInputHandler() const + { + return m_pImpl->pInputHandler; + } + + //-------------------------------------------------------------------- + TableMetrics UnoControlTableModel::getRowHeight() const + { + return m_pImpl->nRowHeight; + } + //-------------------------------------------------------------------- + void UnoControlTableModel::setRowHeight(TableMetrics _nRowHeight) + { + m_pImpl->nRowHeight = _nRowHeight; + } + + //-------------------------------------------------------------------- + TableMetrics UnoControlTableModel::getColumnHeaderHeight() const + { + DBG_ASSERT( hasColumnHeaders(), "DefaultTableModel::getColumnHeaderHeight: invalid call!" ); + return m_pImpl->nColumnHeaderHeight; + } + + //-------------------------------------------------------------------- + TableMetrics UnoControlTableModel::getRowHeaderWidth() const + { + DBG_ASSERT( hasRowHeaders(), "DefaultTableModel::getRowHeaderWidth: invalid call!" ); + return m_pImpl->nRowHeaderWidth; + } + //-------------------------------------------------------------------- + void UnoControlTableModel::setColumnHeaderHeight(TableMetrics _nHeight) + { + m_pImpl->nColumnHeaderHeight = _nHeight; + } + + //-------------------------------------------------------------------- + void UnoControlTableModel::setRowHeaderWidth(TableMetrics _nWidth) + { + m_pImpl->nRowHeaderWidth = _nWidth; + } + + //-------------------------------------------------------------------- + void UnoControlTableModel::SetTitleHeight( TableMetrics _nHeight ) + { + DBG_ASSERT( _nHeight > 0, "DefaultTableModel::SetTitleHeight: invalid height value!" ); + m_pImpl->nColumnHeaderHeight = _nHeight; + // TODO: notification + } + + //-------------------------------------------------------------------- + void UnoControlTableModel::SetHandleWidth( TableMetrics _nWidth ) + { + DBG_ASSERT( _nWidth > 0, "DefaultTableModel::SetHandleWidth: invalid width value!" ); + m_pImpl->nRowHeaderWidth = _nWidth; + // TODO: notification + } + + //-------------------------------------------------------------------- + ScrollbarVisibility UnoControlTableModel::getVerticalScrollbarVisibility(int overAllHeight, int actHeight) const + { + if(overAllHeight>=actHeight && !m_pImpl->bVScroll) + return ScrollbarShowNever; + else + return ScrollbarShowAlways; + } + + //-------------------------------------------------------------------- + ScrollbarVisibility UnoControlTableModel::getHorizontalScrollbarVisibility(int overAllWidth, int actWidth) const + { + if(overAllWidth>=actWidth && !m_pImpl->bHScroll) + return ScrollbarShowNever; + else + return ScrollbarShowAlways; + } + //-------------------------------------------------------------------- + void UnoControlTableModel::setVerticalScrollbarVisibility(bool _bVScroll) const + { + m_pImpl->bVScroll = _bVScroll; + } + + //-------------------------------------------------------------------- + void UnoControlTableModel::setHorizontalScrollbarVisibility(bool _bHScroll) const + { + m_pImpl->bHScroll = _bHScroll; + } + //-------------------------------------------------------------------- + bool UnoControlTableModel::hasVerticalScrollbar() + { + return m_pImpl->bVScroll; + } + //-------------------------------------------------------------------- + bool UnoControlTableModel::hasHorizontalScrollbar() + { + return m_pImpl->bHScroll; + } + //-------------------------------------------------------------------- + void UnoControlTableModel::setCellContent(const std::vector<std::vector< Any > >& cellContent) + { + m_pImpl->aCellContent = cellContent; + } + + std::vector<std::vector< Any > >& UnoControlTableModel::getCellContent() + { + return m_pImpl->aCellContent; + } + //-------------------------------------------------------------------- + void UnoControlTableModel::setRowHeaderName(const std::vector<rtl::OUString>& cellColumnContent) + { + m_pImpl->aRowHeadersTitle = cellColumnContent; + } + + std::vector<rtl::OUString>& UnoControlTableModel::getRowHeaderName() + { + return m_pImpl->aRowHeadersTitle; + } + //-------------------------------------------------------------------- + ::com::sun::star::util::Color UnoControlTableModel::getLineColor() + { + return m_pImpl->m_xLineColor; + } + + //-------------------------------------------------------------------- + void UnoControlTableModel::setLineColor( ::com::sun::star::util::Color _rColor ) + { + m_pImpl->m_xLineColor = _rColor; + } + //-------------------------------------------------------------------- + ::com::sun::star::util::Color UnoControlTableModel::getHeaderBackgroundColor() + { + return m_pImpl->m_xHeaderColor; + } + + //-------------------------------------------------------------------- + void UnoControlTableModel::setHeaderBackgroundColor( ::com::sun::star::util::Color _rColor ) + { + m_pImpl->m_xHeaderColor = _rColor; + } + //-------------------------------------------------------------------- + ::com::sun::star::util::Color UnoControlTableModel::getTextColor() + { + return m_pImpl->m_xTextColor; + } + + //-------------------------------------------------------------------- + void UnoControlTableModel::setTextColor( ::com::sun::star::util::Color _rColor ) + { + m_pImpl->m_xTextColor = _rColor; + } + //-------------------------------------------------------------------- + ::com::sun::star::util::Color UnoControlTableModel::getOddRowBackgroundColor() + { + return m_pImpl->m_xRowColor1; + } + + //-------------------------------------------------------------------- + void UnoControlTableModel::setOddRowBackgroundColor( ::com::sun::star::util::Color _rColor ) + { + m_pImpl->m_xRowColor1 = _rColor; + } + //-------------------------------------------------------------------- + ::com::sun::star::util::Color UnoControlTableModel::getEvenRowBackgroundColor() + { + return m_pImpl->m_xRowColor2; + } + + //-------------------------------------------------------------------- + void UnoControlTableModel::setEvenRowBackgroundColor( ::com::sun::star::util::Color _rColor ) + { + m_pImpl->m_xRowColor2 = _rColor; + } + //-------------------------------------------------------------------- + ::com::sun::star::style::VerticalAlignment UnoControlTableModel::getVerticalAlign() + { + return m_pImpl->m_xVerticalAlign; + } + + //-------------------------------------------------------------------- + void UnoControlTableModel::setVerticalAlign( com::sun::star::style::VerticalAlignment _xAlign ) + { + m_pImpl->m_xVerticalAlign = _xAlign; + } + diff --git a/svtools/source/uno/unocontroltablemodel.hxx b/svtools/source/uno/unocontroltablemodel.hxx new file mode 100644 index 000000000000..c00642448f79 --- /dev/null +++ b/svtools/source/uno/unocontroltablemodel.hxx @@ -0,0 +1,177 @@ +/************************************************************************* + * + * 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. + * + ************************************************************************/ + +#ifndef _UNOCONTROL_TABLEMODEL_HXX_ +#define _UNOCONTROL_TABLEMODEL_HXX_ + +#include <svtools/table/tablemodel.hxx> +#include <svtools/table/tablecontrol.hxx> +#include <com/sun/star/awt/grid/XGridControl.hpp> +#include <com/sun/star/awt/grid/XGridDataListener.hpp> +#include <com/sun/star/awt/grid/GridDataEvent.hpp> +#include <com/sun/star/awt/grid/XGridColumnModel.hpp> +#include <com/sun/star/awt/grid/XGridDataModel.hpp> +#include <com/sun/star/awt/grid/XGridSelectionListener.hpp> +#include <toolkit/awt/vclxwindow.hxx> +#include <toolkit/awt/vclxwindows.hxx> +#include <cppuhelper/typeprovider.hxx> +#include <cppuhelper/implbase2.hxx> +#include <com/sun/star/awt/grid/XGridColumn.hpp> +#include <com/sun/star/util/Color.hpp> +#include <com/sun/star/style/VerticalAlignment.hpp> +#include <com/sun/star/style/HorizontalAlignment.hpp> + + +using namespace ::svt::table; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::awt::grid; + +class UnoControlTableColumn : public IColumnModel +{ + private: + ColumnID m_nID; + String m_sName; + bool m_bIsResizable; + TableMetrics m_nWidth; + TableMetrics m_nMinWidth; + TableMetrics m_nMaxWidth; + TableMetrics m_nPrefWidth; + ::com::sun::star::style::HorizontalAlignment m_xHorizontalAlign; + + public: + UnoControlTableColumn(Reference<XGridColumn>); + UnoControlTableColumn(); + + // IColumnModel overridables + virtual ColumnID getID() const; + virtual bool setID( const ColumnID _nID ); + virtual String getName() const; + virtual void setName( const String& _rName ); + virtual bool isResizable() const; + virtual void setResizable( bool _bResizable ); + virtual TableMetrics getWidth() const; + virtual void setWidth( TableMetrics _nWidth ); + virtual TableMetrics getMinWidth() const; + virtual void setMinWidth( TableMetrics _nMinWidth ); + virtual TableMetrics getMaxWidth() const; + virtual void setMaxWidth( TableMetrics _nMaxWidth ); + virtual TableMetrics getPreferredWidth() const; + virtual void setPreferredWidth( TableMetrics _nPrefWidth ); + virtual ::com::sun::star::style::HorizontalAlignment getHorizontalAlign(); + virtual void setHorizontalAlign(::com::sun::star::style::HorizontalAlignment _xAlign); +}; + +struct UnoControlTableModel_Impl; + +class UnoControlTableModel : public ITableModel +{ + private: + UnoControlTableModel_Impl* m_pImpl; + + public: + UnoControlTableModel(); + ~UnoControlTableModel(); + + /// returns the current row height, in 1/100 millimeters + inline TableMetrics GetRowHeight() const { return getRowHeight(); } + /// sets a new row height. + void setRowHeight( TableMetrics _nHeight ); + /// sets a new row header width. + void setRowHeaderWidth( TableMetrics _nWidth ); + /// sets a new column header height. + void setColumnHeaderHeight( TableMetrics _nHeight ); + + /// returns the height of the title row (containing the column headers) + inline TableMetrics GetTitleHeight() const { return getColumnHeaderHeight(); } + /// sets a new height for the title row (containing the column headers) + void SetTitleHeight( TableMetrics _nHeight ); + + /// returns the width of the handle column (containing the row headers) + inline TableMetrics GetHandleWidth() const { return getRowHeaderWidth(); } + /// sets a new width for the handle column (containing the row headers) + void SetHandleWidth( TableMetrics _nWidth ); + + /// sets the width of a column + inline void SetColumnWidth( ColPos _nColumn, TableMetrics _nWidth100thMM ); + /// retrieves the width of a column, in 1/100th millimeters + inline TableMetrics GetColumnWidth( ColPos _nColumn ); + + public: + // ITableModel overridables + virtual TableSize getColumnCount() const; + virtual TableSize getRowCount() const; + virtual void setColumnCount(TableSize _nColCount); + virtual void setRowCount(TableSize _nRowCount); + virtual bool hasColumnHeaders() const; + virtual bool hasRowHeaders() const; + virtual void setRowHeaders(bool _bRowHeaders); + virtual void setColumnHeaders(bool _bColumnHeaders); + virtual bool isCellEditable( ColPos col, RowPos row ) const; + virtual void addTableModelListener( const PTableModelListener& listener ); + virtual void removeTableModelListener( const PTableModelListener& listener ); + virtual PColumnModel getColumnModel( ColPos column ); + virtual std::vector<PColumnModel>& getColumnModel(); + virtual PColumnModel getColumnModelByID( ColumnID id ); + virtual PTableRenderer getRenderer() const; + virtual PTableInputHandler getInputHandler() const; + virtual TableMetrics getRowHeight() const; + virtual TableMetrics getColumnHeaderHeight() const; + virtual TableMetrics getRowHeaderWidth() const; + virtual ScrollbarVisibility getVerticalScrollbarVisibility(int overAllHeight, int actHeight) const; + virtual ScrollbarVisibility getHorizontalScrollbarVisibility(int overAllWidth, int actWidth) const; + virtual void setVerticalScrollbarVisibility(bool _bVScroll) const; + virtual void setHorizontalScrollbarVisibility(bool _bHScroll) const; + virtual void setCellContent(const std::vector<std::vector< Any > >& cellContent); + virtual std::vector<std::vector< Any > >& getCellContent(); + virtual void setRowHeaderName(const std::vector<rtl::OUString>& cellColumnContent); + virtual std::vector<rtl::OUString>& getRowHeaderName(); + virtual ::com::sun::star::util::Color getLineColor(); + virtual void setLineColor(::com::sun::star::util::Color _rColor); + virtual ::com::sun::star::util::Color getHeaderBackgroundColor(); + virtual void setHeaderBackgroundColor(::com::sun::star::util::Color _rColor); + virtual ::com::sun::star::util::Color getTextColor(); + virtual void setTextColor(::com::sun::star::util::Color _rColor); + virtual ::com::sun::star::util::Color getOddRowBackgroundColor(); + virtual void setOddRowBackgroundColor(::com::sun::star::util::Color _rColor); + virtual ::com::sun::star::util::Color getEvenRowBackgroundColor(); + virtual void setEvenRowBackgroundColor(::com::sun::star::util::Color _rColor); + virtual ::com::sun::star::style::VerticalAlignment getVerticalAlign(); + virtual void setVerticalAlign(::com::sun::star::style::VerticalAlignment _rAlign); + virtual bool hasVerticalScrollbar(); + virtual bool hasHorizontalScrollbar(); +}; + +inline void UnoControlTableModel::SetColumnWidth( ColPos _nColumn, TableMetrics _nWidth100thMM ) +{ + getColumnModel( _nColumn )->setWidth( _nWidth100thMM ); +} + +inline TableMetrics UnoControlTableModel::GetColumnWidth( ColPos _nColumn ) +{ + return getColumnModel( _nColumn )->getWidth(); +} + #endif // _UNOCONTROL_TABLEMODEL_HXX_ diff --git a/svtools/source/uno/unoevent.cxx b/svtools/source/uno/unoevent.cxx new file mode 100644 index 000000000000..526cdbb5d03a --- /dev/null +++ b/svtools/source/uno/unoevent.cxx @@ -0,0 +1,610 @@ +/************************************************************************* + * + * 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_svtools.hxx" + +#ifndef _COM_SUN_STAR_BEANS_PROPERTYVALUE_HPP +#include <com/sun/star/beans/PropertyValue.hpp> +#endif +#include <rtl/ustrbuf.hxx> + + +#include <tools/rtti.hxx> +#include <tools/solar.h> +#include "unoevent.hxx" +#include <svl/macitem.hxx> + +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; + +using ::com::sun::star::container::NoSuchElementException; +using ::com::sun::star::container::XNameReplace; +using ::com::sun::star::lang::IllegalArgumentException; +using ::com::sun::star::lang::WrappedTargetException; +using ::com::sun::star::lang::XServiceInfo; +using ::com::sun::star::beans::PropertyValue; +using ::cppu::WeakImplHelper2; +using ::rtl::OUString; +using ::rtl::OUStringBuffer; + + +const sal_Char sAPI_ServiceName[] = "com.sun.star.container.XNameReplace"; +const sal_Char sAPI_SvDetachedEventDescriptor[] = "SvDetachedEventDescriptor"; + +// +// SvBaseEventDescriptor +// + +SvBaseEventDescriptor::SvBaseEventDescriptor( const SvEventDescription* pSupportedMacroItems ) : + sEventType(RTL_CONSTASCII_USTRINGPARAM("EventType")), + sMacroName(RTL_CONSTASCII_USTRINGPARAM("MacroName")), + sLibrary(RTL_CONSTASCII_USTRINGPARAM("Library")), + sStarBasic(RTL_CONSTASCII_USTRINGPARAM("StarBasic")), + sJavaScript(RTL_CONSTASCII_USTRINGPARAM("JavaScript")), + sScript(RTL_CONSTASCII_USTRINGPARAM("Script")), + sNone(RTL_CONSTASCII_USTRINGPARAM("None")), + sServiceName(RTL_CONSTASCII_USTRINGPARAM(sAPI_ServiceName)), + sEmpty(), + mpSupportedMacroItems(pSupportedMacroItems), + mnMacroItems(0) +{ + DBG_ASSERT(pSupportedMacroItems != NULL, "Need a list of supported events!"); + + for( ; mpSupportedMacroItems[mnMacroItems].mnEvent != 0; mnMacroItems++) ; +} + + +SvBaseEventDescriptor::~SvBaseEventDescriptor() +{ +} + +void SvBaseEventDescriptor::replaceByName( + const OUString& rName, + const Any& rElement ) + throw( + IllegalArgumentException, + NoSuchElementException, + WrappedTargetException, + RuntimeException) +{ + sal_uInt16 nMacroID = getMacroID(rName); + + // error checking + if (0 == nMacroID) + throw NoSuchElementException(); + if (rElement.getValueType() != getElementType()) + throw IllegalArgumentException(); + + // get sequence + Sequence<PropertyValue> aSequence; + rElement >>= aSequence; + + // perform replace (in subclass) + SvxMacro aMacro(sEmpty,sEmpty); + getMacroFromAny(aMacro, rElement); + replaceByName(nMacroID, aMacro); +} + +Any SvBaseEventDescriptor::getByName( + const OUString& rName ) + throw( + NoSuchElementException, + WrappedTargetException, + RuntimeException) +{ + sal_uInt16 nMacroID = getMacroID(rName); + + // error checking + if (0 == nMacroID) + throw NoSuchElementException(); + + // perform get (in subclass) + Any aAny; + SvxMacro aMacro( sEmpty, sEmpty ); + getByName(aMacro, nMacroID); + getAnyFromMacro(aAny, aMacro); + return aAny; +} + +Sequence<OUString> SvBaseEventDescriptor::getElementNames() + throw(RuntimeException) +{ + // create and fill sequence + Sequence<OUString> aSequence(mnMacroItems); + for( sal_Int16 i = 0; i < mnMacroItems; i++) + { + aSequence[i] = OUString::createFromAscii( mpSupportedMacroItems[i].mpEventName ); + } + + return aSequence; +} + +sal_Bool SvBaseEventDescriptor::hasByName( + const OUString& rName ) + throw(RuntimeException) +{ + sal_uInt16 nMacroID = getMacroID(rName); + return (nMacroID != 0); +} + +Type SvBaseEventDescriptor::getElementType() + throw(RuntimeException) +{ + return ::getCppuType((Sequence<PropertyValue> *)0); +} + +sal_Bool SvBaseEventDescriptor::hasElements() + throw(RuntimeException) +{ + return mnMacroItems != 0; +} + +sal_Bool SvBaseEventDescriptor::supportsService(const OUString& rServiceName) + throw(RuntimeException) +{ + return sServiceName.equals(rServiceName); +} + +Sequence<OUString> SvBaseEventDescriptor::getSupportedServiceNames(void) + throw(RuntimeException) +{ + Sequence<OUString> aSequence(1); + aSequence[0] = sServiceName; + + return aSequence; +} + +sal_uInt16 SvBaseEventDescriptor::mapNameToEventID(const OUString& rName) const +{ + // iterate over known event names + for(sal_Int16 i = 0; i < mnMacroItems; i++) + { + if (0 == rName.compareToAscii(mpSupportedMacroItems[i].mpEventName)) + { + return mpSupportedMacroItems[i].mnEvent; + } + } + + // not found -> return zero + return 0; +} + +OUString SvBaseEventDescriptor::mapEventIDToName(sal_uInt16 nPoolID) const +{ + // iterate over known event IDs + for(sal_Int16 i = 0; i < mnMacroItems; i++) + { + if (nPoolID == mpSupportedMacroItems[i].mnEvent) + { + return OUString::createFromAscii(mpSupportedMacroItems[i].mpEventName); + } + } + + // not found -> return empty string + return OUString(); +} + +sal_uInt16 SvBaseEventDescriptor::getMacroID(const OUString& rName) const +{ + return mapNameToEventID(rName); +} + +void SvBaseEventDescriptor::getAnyFromMacro(Any& rAny, + const SvxMacro& rMacro) +{ + sal_Bool bRetValueOK = sal_False; // do we have a ret value? + + if (rMacro.HasMacro()) + { + switch (rMacro.GetScriptType()) + { + case STARBASIC: + { + // create sequence + Sequence<PropertyValue> aSequence(3); + Any aTmp; + + // create type + PropertyValue aTypeValue; + aTypeValue.Name = sEventType; + aTmp <<= sStarBasic; + aTypeValue.Value = aTmp; + aSequence[0] = aTypeValue; + + // macro name + PropertyValue aNameValue; + aNameValue.Name = sMacroName; + OUString sNameTmp(rMacro.GetMacName()); + aTmp <<= sNameTmp; + aNameValue.Value = aTmp; + aSequence[1] = aNameValue; + + // library name + PropertyValue aLibValue; + aLibValue.Name = sLibrary; + OUString sLibTmp(rMacro.GetLibName()); + aTmp <<= sLibTmp; + aLibValue.Value = aTmp; + aSequence[2] = aLibValue; + + rAny <<= aSequence; + bRetValueOK = sal_True; + break; + } + case EXTENDED_STYPE: + { + // create sequence + Sequence<PropertyValue> aSequence(2); + Any aTmp; + + // create type + PropertyValue aTypeValue; + aTypeValue.Name = sEventType; + aTmp <<= sScript; + aTypeValue.Value = aTmp; + aSequence[0] = aTypeValue; + + // macro name + PropertyValue aNameValue; + aNameValue.Name = sScript; + OUString sNameTmp(rMacro.GetMacName()); + aTmp <<= sNameTmp; + aNameValue.Value = aTmp; + aSequence[1] = aNameValue; + + rAny <<= aSequence; + bRetValueOK = sal_True; + break; + } + case JAVASCRIPT: + default: + DBG_ERROR("not implemented"); + } + } + // else: bRetValueOK not set + + // if we don't have a return value, make an empty one + if (! bRetValueOK) + { + // create "None" macro + Sequence<PropertyValue> aSequence(1); + + PropertyValue aKindValue; + aKindValue.Name = sEventType; + Any aTmp; + aTmp <<= sNone; + aKindValue.Value = aTmp; + aSequence[0] = aKindValue; + + rAny <<= aSequence; + bRetValueOK = sal_True; + } +} + + +void SvBaseEventDescriptor::getMacroFromAny( + SvxMacro& rMacro, + const Any& rAny) + throw ( IllegalArgumentException ) +{ + // get sequence + Sequence<PropertyValue> aSequence; + rAny >>= aSequence; + + // process ... + sal_Bool bTypeOK = sal_False; + sal_Bool bNone = sal_False; // true if EventType=="None" + enum ScriptType eType = EXTENDED_STYPE; + OUString sScriptVal; + OUString sMacroVal; + OUString sLibVal; + sal_Int32 nCount = aSequence.getLength(); + for (sal_Int32 i = 0; i < nCount; i++) + { + PropertyValue& aValue = aSequence[i]; + if (aValue.Name.equals(sEventType)) + { + OUString sTmp; + aValue.Value >>= sTmp; + if (sTmp.equals(sStarBasic)) + { + eType = STARBASIC; + bTypeOK = sal_True; + } + else if (sTmp.equals(sJavaScript)) + { + eType = JAVASCRIPT; + bTypeOK = sal_True; + } + else if (sTmp.equals(sScript)) + { + eType = EXTENDED_STYPE; + bTypeOK = sal_True; + } + else if (sTmp.equals(sNone)) + { + bNone = sal_True; + bTypeOK = sal_True; + } + // else: unknown script type + } + else if (aValue.Name.equals(sMacroName)) + { + aValue.Value >>= sMacroVal; + } + else if (aValue.Name.equals(sLibrary)) + { + aValue.Value >>= sLibVal; + } + else if (aValue.Name.equals(sScript)) + { + aValue.Value >>= sScriptVal; + } + // else: unknown PropertyValue -> ignore + } + + if (bTypeOK) + { + if (bNone) + { + // return empty macro + rMacro = SvxMacro( sEmpty, sEmpty ); + } + else + { + if (eType == STARBASIC) + { + // create macro and return + SvxMacro aMacro(sMacroVal, sLibVal, eType); + rMacro = aMacro; + } + else if (eType == EXTENDED_STYPE) + { + SvxMacro aMacro(sScriptVal, sScript); + rMacro = aMacro; + } + else + { + // we can't process type: abort + // TODO: JavaScript macros + throw IllegalArgumentException(); + } + } + } + else + { + // no valid type: abort + throw IllegalArgumentException(); + } +} + + + + +// +// SvEventDescriptor +// + + +SvEventDescriptor::SvEventDescriptor( + XInterface& rParent, + const SvEventDescription* pSupportedMacroItems) : + SvBaseEventDescriptor(pSupportedMacroItems), + xParentRef(&rParent) +{ +} + + +SvEventDescriptor::~SvEventDescriptor() +{ + // automatically release xParentRef ! +} + +void SvEventDescriptor::replaceByName( + const sal_uInt16 nEvent, + const SvxMacro& rMacro) + throw( + IllegalArgumentException, + NoSuchElementException, + WrappedTargetException, + RuntimeException) +{ + SvxMacroItem aItem(getMacroItemWhich()); + aItem.SetMacroTable(getMacroItem().GetMacroTable()); + aItem.SetMacro(nEvent, rMacro); + setMacroItem(aItem); +} + +void SvEventDescriptor::getByName( + SvxMacro& rMacro, + const sal_uInt16 nEvent ) + throw( + NoSuchElementException, + WrappedTargetException, + RuntimeException) +{ + const SvxMacroItem& rItem = getMacroItem(); + if( rItem.HasMacro( nEvent ) ) + rMacro = rItem.GetMacro(nEvent); + else + { + SvxMacro aEmptyMacro(sEmpty, sEmpty); + rMacro = aEmptyMacro; + } +} + + + + +// +// SvDetachedEventDescriptor +// + +SvDetachedEventDescriptor::SvDetachedEventDescriptor( + const SvEventDescription* pSupportedMacroItems) : + SvBaseEventDescriptor(pSupportedMacroItems), + sImplName(RTL_CONSTASCII_USTRINGPARAM(sAPI_SvDetachedEventDescriptor)) +{ + // allocate aMacros + aMacros = new SvxMacro*[mnMacroItems]; + + // ... and initialize + for(sal_Int16 i = 0; i < mnMacroItems; i++) + { + aMacros[i] = NULL; + } +} + +SvDetachedEventDescriptor::~SvDetachedEventDescriptor() +{ + // delete contents of aMacros + for(sal_Int16 i = 0; i < mnMacroItems; i++) + { + if (NULL != aMacros[i]) + delete aMacros[i]; + } + + delete [] aMacros; +} + +sal_Int16 SvDetachedEventDescriptor::getIndex(const sal_uInt16 nID) const +{ + // iterate over supported events + sal_Int16 nIndex = 0; + while ( (mpSupportedMacroItems[nIndex].mnEvent != nID) && + (mpSupportedMacroItems[nIndex].mnEvent != 0) ) + { + nIndex++; + } + return (mpSupportedMacroItems[nIndex].mnEvent == nID) ? nIndex : -1; +} + +OUString SvDetachedEventDescriptor::getImplementationName() + throw( ::com::sun::star::uno::RuntimeException ) +{ + return sImplName; +} + + +void SvDetachedEventDescriptor::replaceByName( + const sal_uInt16 nEvent, + const SvxMacro& rMacro) + throw( + IllegalArgumentException, + NoSuchElementException, + WrappedTargetException, + RuntimeException) +{ + sal_Int16 nIndex = getIndex(nEvent); + if (-1 == nIndex) + throw IllegalArgumentException(); + + aMacros[nIndex] = new SvxMacro(rMacro.GetMacName(), rMacro.GetLibName(), + rMacro.GetScriptType() ); +} + + +void SvDetachedEventDescriptor::getByName( + SvxMacro& rMacro, + const sal_uInt16 nEvent ) + throw( + NoSuchElementException, + WrappedTargetException, + RuntimeException) +{ + sal_Int16 nIndex = getIndex(nEvent); + if (-1 == nIndex ) + throw NoSuchElementException(); + + if( aMacros[nIndex] ) + rMacro = (*aMacros[nIndex]); +} + +sal_Bool SvDetachedEventDescriptor::hasByName( + const sal_uInt16 nEvent ) const /// item ID of event + throw(IllegalArgumentException) +{ + sal_Int16 nIndex = getIndex(nEvent); + if (-1 == nIndex) + throw IllegalArgumentException(); + + return (NULL == aMacros[nIndex]) ? sal_False : aMacros[nIndex]->HasMacro(); +} + + +// +// SvMacroTableEventDescriptor +// + +SvMacroTableEventDescriptor::SvMacroTableEventDescriptor(const SvEventDescription* pSupportedMacroItems) : + SvDetachedEventDescriptor(pSupportedMacroItems) +{ +} + +SvMacroTableEventDescriptor::SvMacroTableEventDescriptor( + const SvxMacroTableDtor& rMacroTable, + const SvEventDescription* pSupportedMacroItems) : + SvDetachedEventDescriptor(pSupportedMacroItems) +{ + copyMacrosFromTable(rMacroTable); +} + +SvMacroTableEventDescriptor::~SvMacroTableEventDescriptor() +{ +} + +void SvMacroTableEventDescriptor::copyMacrosFromTable( + const SvxMacroTableDtor& rMacroTable) +{ + for(sal_Int16 i = 0; mpSupportedMacroItems[i].mnEvent != 0; i++) + { + const sal_uInt16 nEvent = mpSupportedMacroItems[i].mnEvent; + const SvxMacro* pMacro = rMacroTable.Get(nEvent); + if (NULL != pMacro) + replaceByName(nEvent, *pMacro); + } + +} + +void SvMacroTableEventDescriptor::copyMacrosIntoTable( + SvxMacroTableDtor& rMacroTable) +{ + for(sal_Int16 i = 0; mpSupportedMacroItems[i].mnEvent != 0; i++) + { + const sal_uInt16 nEvent = mpSupportedMacroItems[i].mnEvent; + if (hasByName(nEvent)) + { + SvxMacro* pMacro = new SvxMacro(sEmpty, sEmpty); + getByName(*pMacro, nEvent); + rMacroTable.Insert(nEvent, pMacro); + } + } +} + + + diff --git a/svtools/source/uno/unoiface.cxx b/svtools/source/uno/unoiface.cxx new file mode 100644 index 000000000000..2d22d9cedb33 --- /dev/null +++ b/svtools/source/uno/unoiface.cxx @@ -0,0 +1,2367 @@ +/************************************************************************* + * + * 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_svtools.hxx" + +#define _SVT_UNOIFACE_CXX +#include <tools/debug.hxx> +#include <vcl/svapp.hxx> + +#include <svtools/svmedit.hxx> +#include <unoiface.hxx> +#include "filedlg.hxx" +#include "filectrl.hxx" +#include "roadmap.hxx" +#include <svtools/fixedhyper.hxx> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/lang/XSingleServiceFactory.hpp> +#include <com/sun/star/awt/LineEndFormat.hpp> +#include <comphelper/processfactory.hxx> +#include <toolkit/helper/convert.hxx> +#include <toolkit/helper/property.hxx> +#include <svtools/fmtfield.hxx> +#include <svl/numuno.hxx> +#include <calendar.hxx> +#include <prgsbar.hxx> + +#include <svtools/svtreebx.hxx> +#include "treecontrolpeer.hxx" +#include "svtxgridcontrol.hxx" +#include <svtools/table/tablecontrol.hxx> + +namespace +{ + static void lcl_setWinBits( Window* _pWindow, WinBits _nBits, sal_Bool _bSet ) + { + WinBits nStyle = _pWindow->GetStyle(); + if ( _bSet ) + nStyle |= _nBits; + else + nStyle &= ~_nBits; + _pWindow->SetStyle( nStyle ); + } +} + +// ---------------------------------------------------- +// help function for the toolkit... +// ---------------------------------------------------- + +extern "C" { + +SAL_DLLPUBLIC_EXPORT Window* CreateWindow( VCLXWindow** ppNewComp, const ::com::sun::star::awt::WindowDescriptor* pDescriptor, Window* pParent, WinBits nWinBits ) +{ + Window* pWindow = NULL; + String aServiceName( pDescriptor->WindowServiceName ); + if ( aServiceName.EqualsIgnoreCaseAscii( "MultiLineEdit" ) ) + { + if ( pParent ) + { + pWindow = new MultiLineEdit( pParent, nWinBits|WB_IGNORETAB); + *ppNewComp = new VCLXMultiLineEdit; + } + else + { + *ppNewComp = NULL; + return NULL; + } + } + else if ( aServiceName.EqualsIgnoreCaseAscii( "FileControl" ) ) + { + if ( pParent ) + { + pWindow = new FileControl( pParent, nWinBits ); + *ppNewComp = new VCLXFileControl; + } + else + { + *ppNewComp = NULL; + return NULL; + } + } + else if (aServiceName.EqualsIgnoreCaseAscii("FormattedField") ) + { + pWindow = new FormattedField( pParent, nWinBits ); + *ppNewComp = new SVTXFormattedField; + } + else if (aServiceName.EqualsIgnoreCaseAscii("NumericField") ) + { + pWindow = new DoubleNumericField( pParent, nWinBits ); + *ppNewComp = new SVTXNumericField; + } + else if (aServiceName.EqualsIgnoreCaseAscii("LongCurrencyField") ) + { + pWindow = new DoubleCurrencyField( pParent, nWinBits ); + *ppNewComp = new SVTXCurrencyField; + } + else if (aServiceName.EqualsIgnoreCaseAscii("datefield") ) + { + pWindow = new CalendarField( pParent, nWinBits); + static_cast<CalendarField*>(pWindow)->EnableToday(); + static_cast<CalendarField*>(pWindow)->EnableNone(); + static_cast<CalendarField*>(pWindow)->EnableEmptyFieldValue( TRUE ); + *ppNewComp = new SVTXDateField; + ((VCLXFormattedSpinField*)*ppNewComp)->SetFormatter( (FormatterBase*)(DateField*)pWindow ); + } + else if (aServiceName.EqualsIgnoreCaseAscii("roadmap") ) + { + pWindow = new ::svt::ORoadmap( pParent, WB_TABSTOP ); + *ppNewComp = new SVTXRoadmap; + } + else if ( aServiceName.EqualsIgnoreCaseAscii( "ProgressBar" ) ) + { + if ( pParent ) + { + pWindow = new ProgressBar( pParent, nWinBits ); + *ppNewComp = new VCLXProgressBar; + } + else + { + *ppNewComp = NULL; + return NULL; + } + } + else if ( aServiceName.EqualsIgnoreCaseAscii( "Tree" ) ) + { + TreeControlPeer* pPeer = new TreeControlPeer; + *ppNewComp = pPeer; + pWindow = pPeer->createVclControl( pParent, nWinBits ); + } + else if ( aServiceName.EqualsIgnoreCaseAscii( "FixedHyperlink" ) ) + { + if ( pParent ) + { + pWindow = new ::svt::FixedHyperlink( pParent, nWinBits ); + *ppNewComp = new VCLXFixedHyperlink; + } + else + { + *ppNewComp = NULL; + return NULL; + } + } + else if ( aServiceName.EqualsIgnoreCaseAscii( "Grid" ) ) + { + if ( pParent ) + { + pWindow = new ::svt::table::TableControl(pParent, nWinBits); + *ppNewComp = new SVTXGridControl; + } + else + { + *ppNewComp = NULL; + return NULL; + } + } + return pWindow; +} + +} // extern "C" + +// ---------------------------------------------------- +// class VCLXMultiLineEdit +// ---------------------------------------------------- +VCLXMultiLineEdit::VCLXMultiLineEdit() + :maTextListeners( *this ) + ,meLineEndType( LINEEND_LF ) // default behavior before introducing this property: LF (unix-like) +{ +} + +VCLXMultiLineEdit::~VCLXMultiLineEdit() +{ +} + +::com::sun::star::uno::Any VCLXMultiLineEdit::queryInterface( const ::com::sun::star::uno::Type & rType ) throw(::com::sun::star::uno::RuntimeException) +{ + ::com::sun::star::uno::Any aRet = ::cppu::queryInterface( rType, + SAL_STATIC_CAST( ::com::sun::star::awt::XTextComponent*, this ), + SAL_STATIC_CAST( ::com::sun::star::awt::XTextArea*, this ), + SAL_STATIC_CAST( ::com::sun::star::awt::XTextLayoutConstrains*, this ), + SAL_STATIC_CAST( ::com::sun::star::lang::XTypeProvider*, this ) ); + return (aRet.hasValue() ? aRet : VCLXWindow::queryInterface( rType )); +} + +// ::com::sun::star::lang::XTypeProvider +IMPL_XTYPEPROVIDER_START( VCLXMultiLineEdit ) + getCppuType( ( ::com::sun::star::uno::Reference< ::com::sun::star::awt::XTextComponent>* ) NULL ), + getCppuType( ( ::com::sun::star::uno::Reference< ::com::sun::star::awt::XTextArea>* ) NULL ), + getCppuType( ( ::com::sun::star::uno::Reference< ::com::sun::star::awt::XTextLayoutConstrains>* ) NULL ), + VCLXWindow::getTypes() +IMPL_XTYPEPROVIDER_END + +void VCLXMultiLineEdit::addTextListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XTextListener > & l ) throw(::com::sun::star::uno::RuntimeException) +{ + maTextListeners.addInterface( l ); +} + +void VCLXMultiLineEdit::removeTextListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XTextListener > & l ) throw(::com::sun::star::uno::RuntimeException) +{ + maTextListeners.removeInterface( l ); +} + +void VCLXMultiLineEdit::setText( const ::rtl::OUString& aText ) throw(::com::sun::star::uno::RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + MultiLineEdit* pEdit = (MultiLineEdit*)GetWindow(); + if ( pEdit ) + { + pEdit->SetText( aText ); + + // #107218# Call same listeners like VCL would do after user interaction + SetSynthesizingVCLEvent( sal_True ); + pEdit->SetModifyFlag(); + pEdit->Modify(); + SetSynthesizingVCLEvent( sal_False ); + } +} + +void VCLXMultiLineEdit::insertText( const ::com::sun::star::awt::Selection& rSel, const ::rtl::OUString& aText ) throw(::com::sun::star::uno::RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + MultiLineEdit* pEdit = (MultiLineEdit*)GetWindow(); + if ( pEdit ) + { + setSelection( rSel ); + pEdit->ReplaceSelected( aText ); + } +} + +::rtl::OUString VCLXMultiLineEdit::getText() throw(::com::sun::star::uno::RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + ::rtl::OUString aText; + MultiLineEdit* pEdit = (MultiLineEdit*)GetWindow(); + if ( pEdit ) + aText = pEdit->GetText( meLineEndType ); + return aText; +} + +::rtl::OUString VCLXMultiLineEdit::getSelectedText() throw(::com::sun::star::uno::RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + ::rtl::OUString aText; + MultiLineEdit* pMultiLineEdit = (MultiLineEdit*) GetWindow(); + if ( pMultiLineEdit) + aText = pMultiLineEdit->GetSelected( meLineEndType ); + return aText; + +} + +void VCLXMultiLineEdit::setSelection( const ::com::sun::star::awt::Selection& aSelection ) throw(::com::sun::star::uno::RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + MultiLineEdit* pMultiLineEdit = (MultiLineEdit*) GetWindow(); + if ( pMultiLineEdit ) + { + pMultiLineEdit->SetSelection( Selection( aSelection.Min, aSelection.Max ) ); + } +} + +::com::sun::star::awt::Selection VCLXMultiLineEdit::getSelection() throw(::com::sun::star::uno::RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + ::com::sun::star::awt::Selection aSel; + MultiLineEdit* pMultiLineEdit = (MultiLineEdit*) GetWindow(); + if ( pMultiLineEdit ) + { + aSel.Min = pMultiLineEdit->GetSelection().Min(); + aSel.Max = pMultiLineEdit->GetSelection().Max(); + } + return aSel; +} + +sal_Bool VCLXMultiLineEdit::isEditable() throw(::com::sun::star::uno::RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + MultiLineEdit* pMultiLineEdit = (MultiLineEdit*) GetWindow(); + return ( pMultiLineEdit && !pMultiLineEdit->IsReadOnly() && pMultiLineEdit->IsEnabled() ) ? sal_True : sal_False; +} + +void VCLXMultiLineEdit::setEditable( sal_Bool bEditable ) throw(::com::sun::star::uno::RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + MultiLineEdit* pMultiLineEdit = (MultiLineEdit*) GetWindow(); + if ( pMultiLineEdit ) + pMultiLineEdit->SetReadOnly( !bEditable ); +} + +void VCLXMultiLineEdit::setMaxTextLen( sal_Int16 nLen ) throw(::com::sun::star::uno::RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + MultiLineEdit* pMultiLineEdit = (MultiLineEdit*) GetWindow(); + if ( pMultiLineEdit ) + pMultiLineEdit->SetMaxTextLen( nLen ); +} + +sal_Int16 VCLXMultiLineEdit::getMaxTextLen() throw(::com::sun::star::uno::RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + MultiLineEdit* pMultiLineEdit = (MultiLineEdit*) GetWindow(); + return pMultiLineEdit ? (sal_Int16)pMultiLineEdit->GetMaxTextLen() : (sal_Int16)0; +} + +::rtl::OUString VCLXMultiLineEdit::getTextLines() throw(::com::sun::star::uno::RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + ::rtl::OUString aText; + MultiLineEdit* pEdit = (MultiLineEdit*)GetWindow(); + if ( pEdit ) + aText = pEdit->GetTextLines( meLineEndType ); + return aText; +} + +::com::sun::star::awt::Size VCLXMultiLineEdit::getMinimumSize() throw(::com::sun::star::uno::RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + ::com::sun::star::awt::Size aSz; + MultiLineEdit* pEdit = (MultiLineEdit*) GetWindow(); + if ( pEdit ) + aSz = AWTSize(pEdit->CalcMinimumSize()); + return aSz; +} + +::com::sun::star::awt::Size VCLXMultiLineEdit::getPreferredSize() throw(::com::sun::star::uno::RuntimeException) +{ + return getMinimumSize(); +} + +::com::sun::star::awt::Size VCLXMultiLineEdit::calcAdjustedSize( const ::com::sun::star::awt::Size& rNewSize ) throw(::com::sun::star::uno::RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + ::com::sun::star::awt::Size aSz = rNewSize; + MultiLineEdit* pEdit = (MultiLineEdit*) GetWindow(); + if ( pEdit ) + aSz = AWTSize(pEdit->CalcAdjustedSize( VCLSize(rNewSize ))); + return aSz; +} + +::com::sun::star::awt::Size VCLXMultiLineEdit::getMinimumSize( sal_Int16 nCols, sal_Int16 nLines ) throw(::com::sun::star::uno::RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + ::com::sun::star::awt::Size aSz; + MultiLineEdit* pEdit = (MultiLineEdit*) GetWindow(); + if ( pEdit ) + aSz = AWTSize(pEdit->CalcSize( nCols, nLines )); + return aSz; +} + +void VCLXMultiLineEdit::getColumnsAndLines( sal_Int16& nCols, sal_Int16& nLines ) throw(::com::sun::star::uno::RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + nCols = nLines = 0; + MultiLineEdit* pEdit = (MultiLineEdit*) GetWindow(); + if ( pEdit ) + { + sal_uInt16 nC, nL; + pEdit->GetMaxVisColumnsAndLines( nC, nL ); + nCols = nC; + nLines = nL; + } +} + +void VCLXMultiLineEdit::ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent ) +{ + switch ( rVclWindowEvent.GetId() ) + { + case VCLEVENT_EDIT_MODIFY: + { + if ( maTextListeners.getLength() ) + { + ::com::sun::star::awt::TextEvent aEvent; + aEvent.Source = (::cppu::OWeakObject*)this; + maTextListeners.textChanged( aEvent ); + } + } + break; + default: + { + VCLXWindow::ProcessWindowEvent( rVclWindowEvent ); + } + break; + } +} + +void VCLXMultiLineEdit::setProperty( const ::rtl::OUString& PropertyName, const ::com::sun::star::uno::Any& Value) throw(::com::sun::star::uno::RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + MultiLineEdit* pMultiLineEdit = (MultiLineEdit*)GetWindow(); + if ( pMultiLineEdit ) + { + sal_uInt16 nPropType = GetPropertyId( PropertyName ); + switch ( nPropType ) + { + case BASEPROPERTY_LINE_END_FORMAT: + { + sal_Int16 nLineEndType = ::com::sun::star::awt::LineEndFormat::LINE_FEED; + OSL_VERIFY( Value >>= nLineEndType ); + switch ( nLineEndType ) + { + case ::com::sun::star::awt::LineEndFormat::CARRIAGE_RETURN: meLineEndType = LINEEND_CR; break; + case ::com::sun::star::awt::LineEndFormat::LINE_FEED: meLineEndType = LINEEND_LF; break; + case ::com::sun::star::awt::LineEndFormat::CARRIAGE_RETURN_LINE_FEED: meLineEndType = LINEEND_CRLF; break; + default: DBG_ERROR( "VCLXMultiLineEdit::setProperty: invalid line end value!" ); break; + } + } + break; + + case BASEPROPERTY_READONLY: + { + sal_Bool b = sal_Bool(); + if ( Value >>= b ) + pMultiLineEdit->SetReadOnly( b ); + } + break; + case BASEPROPERTY_MAXTEXTLEN: + { + sal_Int16 n = sal_Int16(); + if ( Value >>= n ) + pMultiLineEdit->SetMaxTextLen( n ); + } + break; + case BASEPROPERTY_HIDEINACTIVESELECTION: + { + sal_Bool b = sal_Bool(); + if ( Value >>= b ) + { + pMultiLineEdit->EnableFocusSelectionHide( b ); + lcl_setWinBits( pMultiLineEdit, WB_NOHIDESELECTION, !b ); + } + } + break; + default: + { + VCLXWindow::setProperty( PropertyName, Value ); + } + } + } +} + +::com::sun::star::uno::Any VCLXMultiLineEdit::getProperty( const ::rtl::OUString& PropertyName ) throw(::com::sun::star::uno::RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + ::com::sun::star::uno::Any aProp; + MultiLineEdit* pMultiLineEdit = (MultiLineEdit*)GetWindow(); + if ( pMultiLineEdit ) + { + sal_uInt16 nPropType = GetPropertyId( PropertyName ); + switch ( nPropType ) + { + case BASEPROPERTY_LINE_END_FORMAT: + { + sal_Int16 nLineEndType = ::com::sun::star::awt::LineEndFormat::LINE_FEED; + switch ( meLineEndType ) + { + case LINEEND_CR: nLineEndType = ::com::sun::star::awt::LineEndFormat::CARRIAGE_RETURN; break; + case LINEEND_LF: nLineEndType = ::com::sun::star::awt::LineEndFormat::LINE_FEED; break; + case LINEEND_CRLF: nLineEndType = ::com::sun::star::awt::LineEndFormat::CARRIAGE_RETURN_LINE_FEED; break; + default: DBG_ERROR( "VCLXMultiLineEdit::getProperty: invalid line end value!" ); break; + } + aProp <<= nLineEndType; + } + break; + + case BASEPROPERTY_READONLY: + { + aProp <<= pMultiLineEdit->IsReadOnly(); + } + break; + case BASEPROPERTY_MAXTEXTLEN: + { + aProp <<= (sal_Int16) pMultiLineEdit->GetMaxTextLen(); + } + break; + default: + { + aProp <<= VCLXWindow::getProperty( PropertyName ); + } + } + } + return aProp; +} + +void SAL_CALL VCLXMultiLineEdit::setFocus( ) throw(::com::sun::star::uno::RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + // don't grab the focus if we already have it. Reason is that the only thing which the edit + // does is forwarding the focus to it's text window. This text window then does a "select all". + // So if the text window already has the focus, and we give the focus to the multi line + // edit, then all which happens is that everything is selected. + // #i27072# - 2004-04-25 - fs@openoffice.org + if ( GetWindow() && !GetWindow()->HasChildPathFocus() ) + GetWindow()->GrabFocus(); +} + +void VCLXMultiLineEdit::ImplGetPropertyIds( std::list< sal_uInt16 > &rIds ) +{ + PushPropertyIds( rIds, + // FIXME: elide duplication ? + BASEPROPERTY_LINE_END_FORMAT, + BASEPROPERTY_READONLY, + BASEPROPERTY_MAXTEXTLEN, + BASEPROPERTY_HIDEINACTIVESELECTION, + 0); + VCLXWindow::ImplGetPropertyIds( rIds, true ); + +} +// ---------------------------------------------------- +// class VCLXFileControl +// ---------------------------------------------------- +VCLXFileControl::VCLXFileControl() : maTextListeners( *this ) +{ +} + +VCLXFileControl::~VCLXFileControl() +{ + FileControl* pControl = (FileControl*) GetWindow(); + if ( pControl ) + pControl->GetEdit().SetModifyHdl( Link() ); +} + +::com::sun::star::uno::Any VCLXFileControl::queryInterface( const ::com::sun::star::uno::Type & rType ) throw(::com::sun::star::uno::RuntimeException) +{ + ::com::sun::star::uno::Any aRet = ::cppu::queryInterface( rType, + SAL_STATIC_CAST( ::com::sun::star::awt::XTextComponent*, this ), + SAL_STATIC_CAST( ::com::sun::star::awt::XTextLayoutConstrains*, this ), + SAL_STATIC_CAST( ::com::sun::star::lang::XTypeProvider*, this ) ); + return (aRet.hasValue() ? aRet : VCLXWindow::queryInterface( rType )); +} + +// ::com::sun::star::lang::XTypeProvider +IMPL_XTYPEPROVIDER_START( VCLXFileControl ) + getCppuType( ( ::com::sun::star::uno::Reference< ::com::sun::star::awt::XTextComponent>* ) NULL ), + getCppuType( ( ::com::sun::star::uno::Reference< ::com::sun::star::awt::XTextLayoutConstrains>* ) NULL ), + VCLXWindow::getTypes() +IMPL_XTYPEPROVIDER_END + +void SAL_CALL VCLXFileControl::setProperty( const ::rtl::OUString& PropertyName, const ::com::sun::star::uno::Any& Value) throw(::com::sun::star::uno::RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + FileControl* pControl = (FileControl*)GetWindow(); + if ( pControl ) + { + sal_uInt16 nPropType = GetPropertyId( PropertyName ); + switch ( nPropType ) + { + case BASEPROPERTY_HIDEINACTIVESELECTION: + { + sal_Bool bValue( sal_False ); + OSL_VERIFY( Value >>= bValue ); + + lcl_setWinBits( pControl, WB_NOHIDESELECTION, !bValue ); + lcl_setWinBits( &pControl->GetEdit(), WB_NOHIDESELECTION, !bValue ); + } + break; + + default: + VCLXWindow::setProperty( PropertyName, Value ); + break; + } + } +} + +void VCLXFileControl::SetWindow( Window* pWindow ) +{ + FileControl* pPrevFileControl = dynamic_cast<FileControl*>( GetWindow() ); + if ( pPrevFileControl ) + pPrevFileControl->GetEdit().SetModifyHdl( Link() ); + + FileControl* pNewFileControl = dynamic_cast<FileControl*>( pWindow ); + if ( pNewFileControl ) + pNewFileControl->GetEdit().SetModifyHdl( LINK( this, VCLXFileControl, ModifyHdl ) ); + + VCLXWindow::SetWindow( pWindow ); +} + +void VCLXFileControl::addTextListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XTextListener > & l ) throw(::com::sun::star::uno::RuntimeException) +{ + maTextListeners.addInterface( l ); +} + +void VCLXFileControl::removeTextListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XTextListener > & l ) throw(::com::sun::star::uno::RuntimeException) +{ + maTextListeners.removeInterface( l ); +} + +void VCLXFileControl::setText( const ::rtl::OUString& aText ) throw(::com::sun::star::uno::RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + Window* pWindow = GetWindow(); + if ( pWindow ) + { + pWindow->SetText( aText ); + + // In JAVA wird auch ein textChanged ausgeloest, in VCL nicht. + // ::com::sun::star::awt::Toolkit soll JAVA-komform sein... + ModifyHdl( NULL ); + } +} + +void VCLXFileControl::insertText( const ::com::sun::star::awt::Selection& rSel, const ::rtl::OUString& aText ) throw(::com::sun::star::uno::RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + FileControl* pFileControl = (FileControl*) GetWindow(); + if ( pFileControl ) + { + pFileControl->GetEdit().SetSelection( Selection( rSel.Min, rSel.Max ) ); + pFileControl->GetEdit().ReplaceSelected( aText ); + } +} + +::rtl::OUString VCLXFileControl::getText() throw(::com::sun::star::uno::RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + ::rtl::OUString aText; + Window* pWindow = GetWindow(); + if ( pWindow ) + aText = pWindow->GetText(); + return aText; +} + +::rtl::OUString VCLXFileControl::getSelectedText() throw(::com::sun::star::uno::RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + ::rtl::OUString aText; + FileControl* pFileControl = (FileControl*) GetWindow(); + if ( pFileControl) + aText = pFileControl->GetEdit().GetSelected(); + return aText; + +} + +void VCLXFileControl::setSelection( const ::com::sun::star::awt::Selection& aSelection ) throw(::com::sun::star::uno::RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + FileControl* pFileControl = (FileControl*) GetWindow(); + if ( pFileControl ) + pFileControl->GetEdit().SetSelection( Selection( aSelection.Min, aSelection.Max ) ); +} + +::com::sun::star::awt::Selection VCLXFileControl::getSelection() throw(::com::sun::star::uno::RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + ::com::sun::star::awt::Selection aSel; + FileControl* pFileControl = (FileControl*) GetWindow(); + if ( pFileControl ) + { + aSel.Min = pFileControl->GetEdit().GetSelection().Min(); + aSel.Max = pFileControl->GetEdit().GetSelection().Max(); + } + return aSel; +} + +sal_Bool VCLXFileControl::isEditable() throw(::com::sun::star::uno::RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + FileControl* pFileControl = (FileControl*) GetWindow(); + return ( pFileControl && !pFileControl->GetEdit().IsReadOnly() && pFileControl->GetEdit().IsEnabled() ) ? sal_True : sal_False; +} + +void VCLXFileControl::setEditable( sal_Bool bEditable ) throw(::com::sun::star::uno::RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + FileControl* pFileControl = (FileControl*) GetWindow(); + if ( pFileControl ) + pFileControl->GetEdit().SetReadOnly( !bEditable ); +} + +void VCLXFileControl::setMaxTextLen( sal_Int16 nLen ) throw(::com::sun::star::uno::RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + FileControl* pFileControl = (FileControl*) GetWindow(); + if ( pFileControl ) + pFileControl->GetEdit().SetMaxTextLen( nLen ); +} + +sal_Int16 VCLXFileControl::getMaxTextLen() throw(::com::sun::star::uno::RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + FileControl* pFileControl = (FileControl*) GetWindow(); + return pFileControl ? pFileControl->GetEdit().GetMaxTextLen() : 0; +} + + +IMPL_LINK( VCLXFileControl, ModifyHdl, Edit*, EMPTYARG ) +{ + ::com::sun::star::awt::TextEvent aEvent; + aEvent.Source = (::cppu::OWeakObject*)this; + maTextListeners.textChanged( aEvent ); + + return 1; +} + +::com::sun::star::awt::Size VCLXFileControl::getMinimumSize() throw(::com::sun::star::uno::RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + ::com::sun::star::awt::Size aSz; + FileControl* pControl = (FileControl*) GetWindow(); + if ( pControl ) + { + Size aTmpSize = pControl->GetEdit().CalcMinimumSize(); + aTmpSize.Width() += pControl->GetButton().CalcMinimumSize().Width(); + aSz = AWTSize(pControl->CalcWindowSize( aTmpSize )); + } + return aSz; +} + +::com::sun::star::awt::Size VCLXFileControl::getPreferredSize() throw(::com::sun::star::uno::RuntimeException) +{ + ::com::sun::star::awt::Size aSz = getMinimumSize(); + aSz.Height += 4; + return aSz; +} + +::com::sun::star::awt::Size VCLXFileControl::calcAdjustedSize( const ::com::sun::star::awt::Size& rNewSize ) throw(::com::sun::star::uno::RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + ::com::sun::star::awt::Size aSz =rNewSize; + FileControl* pControl = (FileControl*) GetWindow(); + if ( pControl ) + { + ::com::sun::star::awt::Size aMinSz = getMinimumSize(); + if ( aSz.Height != aMinSz.Height ) + aSz.Height = aMinSz.Height; + } + return aSz; +} + +::com::sun::star::awt::Size VCLXFileControl::getMinimumSize( sal_Int16 nCols, sal_Int16 ) throw(::com::sun::star::uno::RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + ::com::sun::star::awt::Size aSz; + FileControl* pControl = (FileControl*) GetWindow(); + if ( pControl ) + { + aSz = AWTSize(pControl->GetEdit().CalcSize( nCols )); + aSz.Width += pControl->GetButton().CalcMinimumSize().Width(); + } + return aSz; +} + +void VCLXFileControl::getColumnsAndLines( sal_Int16& nCols, sal_Int16& nLines ) throw(::com::sun::star::uno::RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + nCols = 0; + nLines = 1; + FileControl* pControl = (FileControl*) GetWindow(); + if ( pControl ) + nCols = (sal_Int16) pControl->GetEdit().GetMaxVisChars(); +} + +void VCLXFileControl::ImplGetPropertyIds( std::list< sal_uInt16 > &rIds ) +{ + PushPropertyIds( rIds, + // FIXME: elide duplication ? + BASEPROPERTY_HIDEINACTIVESELECTION, + 0); + VCLXWindow::ImplGetPropertyIds( rIds, true ); +} + + +// ---------------------------------------------------- +// class SVTXFormattedField +// ---------------------------------------------------- +// -------------------------------------------------------------------------------------- +SVTXFormattedField::SVTXFormattedField() + :m_pCurrentSupplier(NULL) + ,bIsStandardSupplier(sal_True) + ,nKeyToSetDelayed(-1) +{ +} + +// -------------------------------------------------------------------------------------- +SVTXFormattedField::~SVTXFormattedField() +{ + if (m_pCurrentSupplier) + { + m_pCurrentSupplier->release(); + m_pCurrentSupplier = NULL; + } +} + +// -------------------------------------------------------------------------------------- +void SVTXFormattedField::SetWindow( Window* _pWindow ) +{ + VCLXSpinField::SetWindow(_pWindow); + if (GetFormattedField()) + GetFormattedField()->SetAutoColor(TRUE); +} + +// -------------------------------------------------------------------------------------- +void SVTXFormattedField::setProperty( const ::rtl::OUString& PropertyName, const ::com::sun::star::uno::Any& Value) throw(::com::sun::star::uno::RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + FormattedField* pField = GetFormattedField(); + if ( pField ) + { + sal_uInt16 nPropType = GetPropertyId( PropertyName ); + switch (nPropType) + { + case BASEPROPERTY_ENFORCE_FORMAT: + { + sal_Bool bEnable( sal_True ); + if ( Value >>= bEnable ) + pField->EnableNotANumber( !bEnable ); + } + break; + + case BASEPROPERTY_EFFECTIVE_MIN: + case BASEPROPERTY_VALUEMIN_DOUBLE: + SetMinValue(Value); + break; + + case BASEPROPERTY_EFFECTIVE_MAX: + case BASEPROPERTY_VALUEMAX_DOUBLE: + SetMaxValue(Value); + break; + + case BASEPROPERTY_EFFECTIVE_DEFAULT: + SetDefaultValue(Value); + break; + + case BASEPROPERTY_TREATASNUMBER: + { + sal_Bool b = sal_Bool(); + if ( Value >>= b ) + SetTreatAsNumber(b); + } + break; + + case BASEPROPERTY_FORMATSSUPPLIER: + if (!Value.hasValue()) + setFormatsSupplier(::com::sun::star::uno::Reference< ::com::sun::star::util::XNumberFormatsSupplier > (NULL)); + else + { + ::com::sun::star::uno::Reference< ::com::sun::star::util::XNumberFormatsSupplier > xNFS; + if ( Value >>= xNFS ) + setFormatsSupplier(xNFS); + } + break; + case BASEPROPERTY_FORMATKEY: + if (!Value.hasValue()) + setFormatKey(0); + else + { + sal_Int32 n = 0; + if ( Value >>= n ) + setFormatKey(n); + } + break; + + case BASEPROPERTY_EFFECTIVE_VALUE: + case BASEPROPERTY_VALUE_DOUBLE: + { + const ::com::sun::star::uno::TypeClass rTC = Value.getValueType().getTypeClass(); + if (rTC != ::com::sun::star::uno::TypeClass_STRING) + // no string + if (rTC != ::com::sun::star::uno::TypeClass_DOUBLE) + // no double + if (Value.hasValue()) + { // but a value + // try if it is something converitble + sal_Int32 nValue = 0; + if (!(Value >>= nValue)) + throw ::com::sun::star::lang::IllegalArgumentException(); + SetValue(::com::sun::star::uno::makeAny((double)nValue)); + break; + } + + SetValue(Value); + } + break; + case BASEPROPERTY_VALUESTEP_DOUBLE: + { + double d = 0.0; + if ( Value >>= d ) + pField->SetSpinSize( d ); + else + { + sal_Int32 n = 0; + if ( Value >>= n ) + pField->SetSpinSize( n ); + } + } + break; + case BASEPROPERTY_DECIMALACCURACY: + { + sal_Int32 n = 0; + if ( Value >>= n ) + pField->SetDecimalDigits( (sal_uInt16)n ); + } + break; + case BASEPROPERTY_NUMSHOWTHOUSANDSEP: + { + sal_Bool b = sal_Bool(); + if ( Value >>= b ) + pField->SetThousandsSep( b ); + } + break; + + default: + VCLXSpinField::setProperty( PropertyName, Value ); + } + + if (BASEPROPERTY_TEXTCOLOR == nPropType) + { // after setting a new text color, think again about the AutoColor flag of the control + // 17.05.2001 - 86859 - frank.schoenheit@germany.sun.com + pField->SetAutoColor(!Value.hasValue()); + } + } + else + VCLXSpinField::setProperty( PropertyName, Value ); +} + +// -------------------------------------------------------------------------------------- +::com::sun::star::uno::Any SVTXFormattedField::getProperty( const ::rtl::OUString& PropertyName ) throw(::com::sun::star::uno::RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + ::com::sun::star::uno::Any aReturn; + + FormattedField* pField = GetFormattedField(); + if ( pField ) + { + sal_uInt16 nPropType = GetPropertyId( PropertyName ); + switch (nPropType) + { + case BASEPROPERTY_EFFECTIVE_MIN: + case BASEPROPERTY_VALUEMIN_DOUBLE: + aReturn <<= GetMinValue(); + break; + + case BASEPROPERTY_EFFECTIVE_MAX: + case BASEPROPERTY_VALUEMAX_DOUBLE: + aReturn <<= GetMaxValue(); + break; + + case BASEPROPERTY_EFFECTIVE_DEFAULT: + aReturn <<= GetDefaultValue(); + break; + + case BASEPROPERTY_TREATASNUMBER: + aReturn <<= GetTreatAsNumber(); + break; + + case BASEPROPERTY_EFFECTIVE_VALUE: + case BASEPROPERTY_VALUE_DOUBLE: + aReturn <<= GetValue(); + break; + + case BASEPROPERTY_VALUESTEP_DOUBLE: + aReturn <<= pField->GetSpinSize(); + break; + + case BASEPROPERTY_DECIMALACCURACY: + aReturn <<= pField->GetDecimalDigits(); + break; + + case BASEPROPERTY_FORMATSSUPPLIER: + { + if (!bIsStandardSupplier) + { // ansonsten void + ::com::sun::star::uno::Reference< ::com::sun::star::util::XNumberFormatsSupplier > xSupplier = getFormatsSupplier(); + aReturn <<= xSupplier; + } + } + break; + + case BASEPROPERTY_FORMATKEY: + { + if (!bIsStandardSupplier) + aReturn <<= getFormatKey(); + } + break; + + default: + aReturn <<= VCLXSpinField::getProperty(PropertyName); + } + } + return aReturn; +} + +// -------------------------------------------------------------------------------------- +::com::sun::star::uno::Any SVTXFormattedField::convertEffectiveValue(const ::com::sun::star::uno::Any& rValue) +{ + ::com::sun::star::uno::Any aReturn; + + FormattedField* pField = GetFormattedField(); + if (!pField) + return aReturn; + + switch (rValue.getValueType().getTypeClass()) + { + case ::com::sun::star::uno::TypeClass_DOUBLE: + if (pField->TreatingAsNumber()) + { + double d = 0.0; + rValue >>= d; + aReturn <<= d; + } + else + { + SvNumberFormatter* pFormatter = pField->GetFormatter(); + if (!pFormatter) + pFormatter = pField->StandardFormatter(); + // should never fail + + Color* pDum; + double d = 0.0; + rValue >>= d; + String sConverted; + pFormatter->GetOutputString(d, 0, sConverted, &pDum); + aReturn <<= ::rtl::OUString( sConverted ); + } + break; + case ::com::sun::star::uno::TypeClass_STRING: + { + ::rtl::OUString aStr; + rValue >>= aStr; + String sValue = aStr; + if (pField->TreatingAsNumber()) + { + SvNumberFormatter* pFormatter = pField->GetFormatter(); + if (!pFormatter) + pFormatter = pField->StandardFormatter(); + + double dVal; + sal_uInt32 nTestFormat(0); + if (!pFormatter->IsNumberFormat(sValue, nTestFormat, dVal)) + aReturn.clear(); + aReturn <<=dVal; + } + else + aReturn <<= aStr; + } + break; + default: + aReturn.clear(); + break; + } + return aReturn; +} + +// -------------------------------------------------------------------------------------- +void SVTXFormattedField::SetMinValue(const ::com::sun::star::uno::Any& rValue) +{ + FormattedField* pField = GetFormattedField(); + if (!pField) + return; + + switch (rValue.getValueType().getTypeClass()) + + { + case ::com::sun::star::uno::TypeClass_DOUBLE: + { + double d = 0.0; + rValue >>= d; + pField->SetMinValue(d); + } + break; + default: + DBG_ASSERT(rValue.getValueType().getTypeClass() == ::com::sun::star::uno::TypeClass_VOID, "SVTXFormattedField::SetMinValue : invalid argument (an exception will be thrown) !"); + if ( rValue.getValueType().getTypeClass() != ::com::sun::star::uno::TypeClass_VOID ) + + { + throw ::com::sun::star::lang::IllegalArgumentException(); + } + pField->ClearMinValue(); + break; + } +} + +// -------------------------------------------------------------------------------------- +::com::sun::star::uno::Any SVTXFormattedField::GetMinValue() +{ + FormattedField* pField = GetFormattedField(); + if (!pField || !pField->HasMinValue()) + return ::com::sun::star::uno::Any(); + + ::com::sun::star::uno::Any aReturn; + aReturn <<= pField->GetMinValue(); + return aReturn; +} + +// -------------------------------------------------------------------------------------- +void SVTXFormattedField::SetMaxValue(const ::com::sun::star::uno::Any& rValue) +{ + FormattedField* pField = GetFormattedField(); + if (!pField) + return; + + switch (rValue.getValueType().getTypeClass()) + + { + case ::com::sun::star::uno::TypeClass_DOUBLE: + { + double d = 0.0; + rValue >>= d; + pField->SetMaxValue(d); + } + break; + default: + if (rValue.getValueType().getTypeClass() != ::com::sun::star::uno::TypeClass_VOID) + + { + throw ::com::sun::star::lang::IllegalArgumentException(); + } + pField->ClearMaxValue(); + break; + } +} + +// -------------------------------------------------------------------------------------- +::com::sun::star::uno::Any SVTXFormattedField::GetMaxValue() +{ + FormattedField* pField = GetFormattedField(); + if (!pField || !pField->HasMaxValue()) + return ::com::sun::star::uno::Any(); + + ::com::sun::star::uno::Any aReturn; + aReturn <<= pField->GetMaxValue(); + return aReturn; +} + +// -------------------------------------------------------------------------------------- +void SVTXFormattedField::SetDefaultValue(const ::com::sun::star::uno::Any& rValue) +{ + FormattedField* pField = GetFormattedField(); + if (!pField) + return; + + ::com::sun::star::uno::Any aConverted = convertEffectiveValue(rValue); + + switch (aConverted.getValueType().getTypeClass()) + + { + case ::com::sun::star::uno::TypeClass_DOUBLE: + { + double d = 0.0; + aConverted >>= d; + pField->SetDefaultValue(d); + } + break; + case ::com::sun::star::uno::TypeClass_STRING: + { + ::rtl::OUString aStr; + aConverted >>= aStr; + pField->SetDefaultText( aStr ); + } + break; + default: + pField->EnableEmptyField(sal_True); + // nur noch void erlaubt + break; + } +} + +// -------------------------------------------------------------------------------------- +::com::sun::star::uno::Any SVTXFormattedField::GetDefaultValue() +{ + FormattedField* pField = GetFormattedField(); + if (!pField || pField->IsEmptyFieldEnabled()) + return ::com::sun::star::uno::Any(); + + ::com::sun::star::uno::Any aReturn; + if (pField->TreatingAsNumber()) + aReturn <<= pField->GetDefaultValue(); + else + aReturn <<= ::rtl::OUString( pField->GetDefaultText() ); + return aReturn; +} + +// -------------------------------------------------------------------------------------- +sal_Bool SVTXFormattedField::GetTreatAsNumber() +{ + FormattedField* pField = GetFormattedField(); + if (pField) + return pField->TreatingAsNumber(); + + return sal_True; +} + +// -------------------------------------------------------------------------------------- +void SVTXFormattedField::SetTreatAsNumber(sal_Bool bSet) +{ + FormattedField* pField = GetFormattedField(); + if (pField) + pField->TreatAsNumber(bSet); +} + +// -------------------------------------------------------------------------------------- +::com::sun::star::uno::Any SVTXFormattedField::GetValue() +{ + FormattedField* pField = GetFormattedField(); + if (!pField) + return ::com::sun::star::uno::Any(); + + ::com::sun::star::uno::Any aReturn; + if (!pField->TreatingAsNumber()) + { + ::rtl::OUString sText = pField->GetTextValue(); + aReturn <<= sText; + } + else + { + if (pField->GetText().Len()) // empty wird erst mal standardmaessig als void nach draussen gereicht + aReturn <<= pField->GetValue(); + } + + return aReturn; +} + +// -------------------------------------------------------------------------------------- +void SVTXFormattedField::SetValue(const ::com::sun::star::uno::Any& rValue) +{ + FormattedField* pField = GetFormattedField(); + if (!pField) + return; + + if (!rValue.hasValue()) + { + pField->SetText(String()); + } + else + { + if (rValue.getValueType().getTypeClass() == ::com::sun::star::uno::TypeClass_DOUBLE ) + { + double d = 0.0; + rValue >>= d; + pField->SetValue(d); + } + else + { + DBG_ASSERT(rValue.getValueType().getTypeClass() == ::com::sun::star::uno::TypeClass_STRING, "SVTXFormattedField::SetValue : invalid argument !"); + + ::rtl::OUString sText; + rValue >>= sText; + String aStr( sText ); + if (!pField->TreatingAsNumber()) + pField->SetTextFormatted(aStr); + else + pField->SetTextValue(aStr); + } + } +// NotifyTextListeners(); +} + +// -------------------------------------------------------------------------------------- +::com::sun::star::uno::Reference< ::com::sun::star::util::XNumberFormatsSupplier > SVTXFormattedField::getFormatsSupplier(void) const +{ + return ::com::sun::star::uno::Reference< ::com::sun::star::util::XNumberFormatsSupplier > ((::com::sun::star::util::XNumberFormatsSupplier*)m_pCurrentSupplier); +} + +// -------------------------------------------------------------------------------------- +void SVTXFormattedField::setFormatsSupplier(const ::com::sun::star::uno::Reference< ::com::sun::star::util::XNumberFormatsSupplier > & xSupplier) +{ + FormattedField* pField = GetFormattedField(); + + SvNumberFormatsSupplierObj* pNew = NULL; + if (!xSupplier.is()) + { + if (pField) + { + pNew = new SvNumberFormatsSupplierObj(pField->StandardFormatter()); + bIsStandardSupplier = sal_True; + } + } + else + { + pNew = SvNumberFormatsSupplierObj::getImplementation(xSupplier); + bIsStandardSupplier = sal_False; + } + + if (!pNew) + return; // TODO : wie das behandeln ? + + if (m_pCurrentSupplier) + m_pCurrentSupplier->release(); + m_pCurrentSupplier = pNew; + m_pCurrentSupplier->acquire(); + if (pField) + { + // den aktuellen Value mit hinueberretten + ::com::sun::star::uno::Any aCurrent = GetValue(); + pField->SetFormatter(m_pCurrentSupplier->GetNumberFormatter(), sal_False); + if (nKeyToSetDelayed != -1) + { + pField->SetFormatKey(nKeyToSetDelayed); + nKeyToSetDelayed = -1; + } + SetValue(aCurrent); + NotifyTextListeners(); + } +} + +// -------------------------------------------------------------------------------------- +sal_Int32 SVTXFormattedField::getFormatKey(void) const +{ + FormattedField* pField = GetFormattedField(); + return pField ? pField->GetFormatKey() : 0; +} + +// -------------------------------------------------------------------------------------- +void SVTXFormattedField::setFormatKey(sal_Int32 nKey) +{ + FormattedField* pField = GetFormattedField(); + if (pField) + { + if (pField->GetFormatter()) + pField->SetFormatKey(nKey); + else + { // Wahrscheinlich bin ich gerade in einem Block, in dem erst der Key und dann der Formatter gesetzt + // wird, das passiert initial mit ziemlicher Sicherheit, da die Properties in alphabetischer Reihenfolge + // gesetzt werden, und der FormatsSupplier nun mal vor dem FormatKey kommt + nKeyToSetDelayed = nKey; + } + NotifyTextListeners(); + } +} + +// -------------------------------------------------------------------------------------- +void SVTXFormattedField::NotifyTextListeners() +{ + if ( GetTextListeners().getLength() ) + { + ::com::sun::star::awt::TextEvent aEvent; + aEvent.Source = (::cppu::OWeakObject*)this; + GetTextListeners().textChanged( aEvent ); + } +} + +void SVTXFormattedField::ImplGetPropertyIds( std::list< sal_uInt16 > &rIds ) +{ + PushPropertyIds( rIds, + // FIXME: elide duplication ? + BASEPROPERTY_EFFECTIVE_MIN, + BASEPROPERTY_VALUEMIN_DOUBLE, + BASEPROPERTY_EFFECTIVE_MAX, + BASEPROPERTY_VALUEMAX_DOUBLE, + BASEPROPERTY_EFFECTIVE_DEFAULT, + BASEPROPERTY_TREATASNUMBER, + BASEPROPERTY_EFFECTIVE_VALUE, + BASEPROPERTY_VALUE_DOUBLE, + BASEPROPERTY_VALUESTEP_DOUBLE, + BASEPROPERTY_DECIMALACCURACY, + BASEPROPERTY_FORMATSSUPPLIER, + BASEPROPERTY_NUMSHOWTHOUSANDSEP, + BASEPROPERTY_FORMATKEY, + BASEPROPERTY_TREATASNUMBER, + BASEPROPERTY_ENFORCE_FORMAT, + 0); + VCLXWindow::ImplGetPropertyIds( rIds, true ); + VCLXSpinField::ImplGetPropertyIds( rIds ); +} + + +// ---------------------------------------------------- +// class SVTXRoadmap +// ---------------------------------------------------- + +using namespace svt; + +// -------------------------------------------------------------------------------------- +SVTXRoadmap::SVTXRoadmap() : maItemListeners( *this ) +{ +} + +// -------------------------------------------------------------------------------------- +SVTXRoadmap::~SVTXRoadmap() +{ +} + +void SVTXRoadmap::ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent ) +{ + switch ( rVclWindowEvent.GetId() ) + { + case VCLEVENT_ROADMAP_ITEMSELECTED: + { + ::vos::OGuard aGuard( GetMutex() ); + ::svt::ORoadmap* pField = GetRoadmap(); + if ( pField ) + { + sal_Int16 CurItemID = pField->GetCurrentRoadmapItemID(); + ::com::sun::star::awt::ItemEvent aEvent; + aEvent.Selected = CurItemID; + aEvent.Highlighted = CurItemID; + aEvent.ItemId = CurItemID; + maItemListeners.itemStateChanged( aEvent ); + } + } + break; + default: + SVTXRoadmap_Base::ProcessWindowEvent( rVclWindowEvent ); + break; + } +} + + +void SVTXRoadmap::propertyChange( const ::com::sun::star::beans::PropertyChangeEvent& evt ) throw (::com::sun::star::uno::RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + ::svt::ORoadmap* pField = GetRoadmap(); + if ( pField ) + { + ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > xRoadmapItem; + xRoadmapItem = evt.Source; + sal_Int32 nID = 0; + ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > xPropertySet( xRoadmapItem, ::com::sun::star::uno::UNO_QUERY ); + ::com::sun::star::uno::Any aValue = xPropertySet->getPropertyValue(::rtl::OUString::createFromAscii( "ID" )); + aValue >>= nID; + + ::com::sun::star::uno::Any rVal = evt.NewValue; + evt.NewValue >>= rVal; + ::rtl::OUString sPropertyName = evt.PropertyName; + if ( sPropertyName.equals(::rtl::OUString::createFromAscii( "Enabled" ) ) ) + { + sal_Bool bEnable = false; + evt.NewValue >>= bEnable; + pField->EnableRoadmapItem( (RoadmapTypes::ItemId)nID , bEnable ); + } + else if ( sPropertyName.equals(::rtl::OUString::createFromAscii( "Label" ) ) ) + { + ::rtl::OUString sLabel; + evt.NewValue >>= sLabel; + pField->ChangeRoadmapItemLabel( (RoadmapTypes::ItemId)nID , sLabel ); + } + else if ( sPropertyName.equals(::rtl::OUString::createFromAscii( "ID" ) ) ) + { + sal_Int32 nNewID = 0; + evt.NewValue >>= nNewID; + evt.OldValue >>= nID; + pField->ChangeRoadmapItemID( (RoadmapTypes::ItemId)nID, (RoadmapTypes::ItemId)nNewID ); + } + // else + // Todo: handle Interactive appropriately + } +} + + +void SVTXRoadmap::addItemListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XItemListener >& l ) throw (::com::sun::star::uno::RuntimeException) +{ + maItemListeners.addInterface( l ); +} + +void SVTXRoadmap::removeItemListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XItemListener >& l ) throw (::com::sun::star::uno::RuntimeException) +{ + maItemListeners.removeInterface( l ); +} + +RMItemData SVTXRoadmap::GetRMItemData( const ::com::sun::star::container::ContainerEvent& _rEvent ) +{ + RMItemData aCurRMItemData; + ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > xRoadmapItem; + _rEvent.Element >>= xRoadmapItem; + ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > xPropertySet( xRoadmapItem, ::com::sun::star::uno::UNO_QUERY ); + if ( xPropertySet.is() ) + { + ::com::sun::star::uno::Any aValue = xPropertySet->getPropertyValue(::rtl::OUString::createFromAscii( "Label" )); + aValue >>= aCurRMItemData.Label; + aValue = xPropertySet->getPropertyValue(::rtl::OUString::createFromAscii( "ID" )); + aValue >>= aCurRMItemData.n_ID; + aValue = xPropertySet->getPropertyValue(::rtl::OUString::createFromAscii( "Enabled" )); + aValue >>= aCurRMItemData.b_Enabled; + } + return aCurRMItemData;; +} + +void SVTXRoadmap::elementInserted( const ::com::sun::star::container::ContainerEvent& _rEvent )throw(::com::sun::star::uno::RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + ::svt::ORoadmap* pField = GetRoadmap(); + if ( pField ) + { + RMItemData CurItemData = GetRMItemData( _rEvent ); + sal_Int32 InsertIndex = 0; + _rEvent.Accessor >>= InsertIndex; + pField->InsertRoadmapItem( InsertIndex, CurItemData.Label, (RoadmapTypes::ItemId)CurItemData.n_ID, CurItemData.b_Enabled ); + } +} + +void SVTXRoadmap::elementRemoved( const ::com::sun::star::container::ContainerEvent& _rEvent )throw(::com::sun::star::uno::RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + ::svt::ORoadmap* pField = GetRoadmap(); + if ( pField ) + { + sal_Int32 DelIndex = 0; + _rEvent.Accessor >>= DelIndex; + pField->DeleteRoadmapItem(DelIndex); +// pField->GetCurrentRoadmapItem() +// setProperty(::rtl::OUString.createFromAscii( "CurrentItem" )aAny, + } +} + +void SVTXRoadmap::elementReplaced( const ::com::sun::star::container::ContainerEvent& _rEvent )throw(::com::sun::star::uno::RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + ::svt::ORoadmap* pField = GetRoadmap(); + if ( pField ) + { + RMItemData CurItemData = GetRMItemData( _rEvent ); + sal_Int32 ReplaceIndex = 0; + _rEvent.Accessor >>= ReplaceIndex; + pField->ReplaceRoadmapItem( ReplaceIndex, CurItemData.Label, (RoadmapTypes::ItemId)CurItemData.n_ID, CurItemData.b_Enabled ); + } +} + + + +// -------------------------------------------------------------------------------------- +void SVTXRoadmap::setProperty( const ::rtl::OUString& PropertyName, const ::com::sun::star::uno::Any& Value) throw(::com::sun::star::uno::RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + ::svt::ORoadmap* pField = GetRoadmap(); + if ( pField ) + { + sal_uInt16 nPropType = GetPropertyId( PropertyName ); + switch (nPropType) + { + case BASEPROPERTY_COMPLETE: + { + sal_Bool b = false; + Value >>= b; + pField->SetRoadmapComplete( b); + } + break; + + case BASEPROPERTY_ACTIVATED: + { + sal_Bool b = false; + Value >>= b; + pField->SetRoadmapInteractive( b); + } + break; + + case BASEPROPERTY_CURRENTITEMID: + { + sal_Int32 nId = 0; + Value >>= nId; + pField->SelectRoadmapItemByID( (RoadmapTypes::ItemId)nId ); + } + break; + + case BASEPROPERTY_TEXT: + { + ::rtl::OUString aStr; + Value >>= aStr; + pField->SetText( aStr ); + pField->Invalidate(); + } + break; + + default: + SVTXRoadmap_Base::setProperty( PropertyName, Value ); + break; + } + + } + else + SVTXRoadmap_Base::setProperty( PropertyName, Value ); +} + + +// -------------------------------------------------------------------------------------- +::com::sun::star::uno::Any SVTXRoadmap::getProperty( const ::rtl::OUString& PropertyName ) throw(::com::sun::star::uno::RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + ::com::sun::star::uno::Any aReturn; + + ::svt::ORoadmap* pField = GetRoadmap(); + if ( pField ) + { + sal_uInt16 nPropType = GetPropertyId( PropertyName ); + switch (nPropType) + { + case BASEPROPERTY_COMPLETE: + aReturn <<= pField->IsRoadmapComplete(); + break; + case BASEPROPERTY_ACTIVATED: + aReturn <<= pField->IsRoadmapInteractive(); + break; + case BASEPROPERTY_CURRENTITEMID: + aReturn <<= pField->GetCurrentRoadmapItemID(); + break; + default: + aReturn = SVTXRoadmap_Base::getProperty(PropertyName); + break; + } + } + return aReturn; +} + +void SVTXRoadmap::ImplSetNewImage() +{ + OSL_PRECOND( GetWindow(), "SVTXRoadmap::ImplSetNewImage: window is required to be not-NULL!" ); + ::svt::ORoadmap* pButton = static_cast< ::svt::ORoadmap* >( GetWindow() ); + pButton->SetRoadmapBitmap( GetBitmap() ); +} + +void SVTXRoadmap::ImplGetPropertyIds( std::list< sal_uInt16 > &rIds ) +{ + PushPropertyIds( rIds, + BASEPROPERTY_COMPLETE, + BASEPROPERTY_ACTIVATED, + BASEPROPERTY_CURRENTITEMID, + BASEPROPERTY_TEXT, + 0); + VCLXWindow::ImplGetPropertyIds( rIds, true ); + VCLXGraphicControl::ImplGetPropertyIds( rIds ); +} + +// ---------------------------------------------------- +// class SVTXNumericField +// ---------------------------------------------------- +SVTXNumericField::SVTXNumericField() +{ +} + +SVTXNumericField::~SVTXNumericField() +{ +} + +::com::sun::star::uno::Any SVTXNumericField::queryInterface( const ::com::sun::star::uno::Type & rType ) throw(::com::sun::star::uno::RuntimeException) +{ + ::com::sun::star::uno::Any aRet = ::cppu::queryInterface( rType, + SAL_STATIC_CAST( ::com::sun::star::awt::XNumericField*, this ), + SAL_STATIC_CAST( ::com::sun::star::lang::XTypeProvider*, this ) ); + return (aRet.hasValue() ? aRet : SVTXFormattedField::queryInterface( rType )); +} + +// ::com::sun::star::lang::XTypeProvider +IMPL_XTYPEPROVIDER_START( SVTXNumericField ) + getCppuType( ( ::com::sun::star::uno::Reference< ::com::sun::star::awt::XNumericField>* ) NULL ), + SVTXFormattedField::getTypes() +IMPL_XTYPEPROVIDER_END + + +void SVTXNumericField::setValue( double Value ) throw(::com::sun::star::uno::RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + FormattedField* pField = GetFormattedField(); + if ( pField ) + pField->SetValue( Value ); +} + +double SVTXNumericField::getValue() throw(::com::sun::star::uno::RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + FormattedField* pField = GetFormattedField(); + return pField ? pField->GetValue() : 0; +} + +void SVTXNumericField::setMin( double Value ) throw(::com::sun::star::uno::RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + FormattedField* pField = GetFormattedField(); + if ( pField ) + pField->SetMinValue( Value ); +} + +double SVTXNumericField::getMin() throw(::com::sun::star::uno::RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + FormattedField* pField = GetFormattedField(); + return pField ? pField->GetMinValue() : 0; +} + +void SVTXNumericField::setMax( double Value ) throw(::com::sun::star::uno::RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + FormattedField* pField = GetFormattedField(); + if ( pField ) + pField->SetMaxValue( Value ); +} + +double SVTXNumericField::getMax() throw(::com::sun::star::uno::RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + FormattedField* pField = GetFormattedField(); + return pField ? pField->GetMaxValue() : 0; +} + +void SVTXNumericField::setFirst( double Value ) throw(::com::sun::star::uno::RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + FormattedField* pField = GetFormattedField(); + if ( pField ) + pField->SetSpinFirst( Value ); +} + +double SVTXNumericField::getFirst() throw(::com::sun::star::uno::RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + FormattedField* pField = GetFormattedField(); + return pField ? pField->GetSpinFirst() : 0; +} + +void SVTXNumericField::setLast( double Value ) throw(::com::sun::star::uno::RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + FormattedField* pField = GetFormattedField(); + if ( pField ) + pField->SetSpinLast( Value ); +} + +double SVTXNumericField::getLast() throw(::com::sun::star::uno::RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + FormattedField* pField = GetFormattedField(); + return pField ? pField->GetSpinLast() : 0; +} + +void SVTXNumericField::setSpinSize( double Value ) throw(::com::sun::star::uno::RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + FormattedField* pField = GetFormattedField(); + if ( pField ) + pField->SetSpinSize( Value ); +} + +double SVTXNumericField::getSpinSize() throw(::com::sun::star::uno::RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + FormattedField* pField = GetFormattedField(); + return pField ? pField->GetSpinSize() : 0; +} + +void SVTXNumericField::setDecimalDigits( sal_Int16 Value ) throw(::com::sun::star::uno::RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + FormattedField* pField = GetFormattedField(); + if ( pField ) + pField->SetDecimalDigits( Value ); +} + +sal_Int16 SVTXNumericField::getDecimalDigits() throw(::com::sun::star::uno::RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + FormattedField* pField = GetFormattedField(); + return pField ? pField->GetDecimalDigits() : 0; +} + +void SVTXNumericField::setStrictFormat( sal_Bool bStrict ) throw(::com::sun::star::uno::RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + FormattedField* pField = GetFormattedField(); + if ( pField ) + pField->SetStrictFormat( bStrict ); +} + +sal_Bool SVTXNumericField::isStrictFormat() throw(::com::sun::star::uno::RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + FormattedField* pField = GetFormattedField(); + return pField ? pField->IsStrictFormat() : sal_False; +} + +void SVTXNumericField::ImplGetPropertyIds( std::list< sal_uInt16 > &rIds ) +{ + SVTXFormattedField::ImplGetPropertyIds( rIds ); +} + +// ---------------------------------------------------- +// class SVTXCurrencyField +// ---------------------------------------------------- +SVTXCurrencyField::SVTXCurrencyField() +{ +} + +SVTXCurrencyField::~SVTXCurrencyField() +{ +} + +::com::sun::star::uno::Any SVTXCurrencyField::queryInterface( const ::com::sun::star::uno::Type & rType ) throw(::com::sun::star::uno::RuntimeException) +{ + ::com::sun::star::uno::Any aRet = ::cppu::queryInterface( rType, + SAL_STATIC_CAST( ::com::sun::star::awt::XCurrencyField*, this ), + SAL_STATIC_CAST( ::com::sun::star::lang::XTypeProvider*, this ) ); + return (aRet.hasValue() ? aRet : SVTXFormattedField::queryInterface( rType )); +} + +// ::com::sun::star::lang::XTypeProvider +IMPL_XTYPEPROVIDER_START( SVTXCurrencyField ) + getCppuType( ( ::com::sun::star::uno::Reference< ::com::sun::star::awt::XCurrencyField>* ) NULL ), + SVTXFormattedField::getTypes() +IMPL_XTYPEPROVIDER_END + +void SVTXCurrencyField::setValue( double Value ) throw(::com::sun::star::uno::RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + FormattedField* pField = GetFormattedField(); + if ( pField ) + pField->SetValue( Value ); +} + +double SVTXCurrencyField::getValue() throw(::com::sun::star::uno::RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + FormattedField* pField = GetFormattedField(); + return pField ? pField->GetValue() : 0; +} + +void SVTXCurrencyField::setMin( double Value ) throw(::com::sun::star::uno::RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + FormattedField* pField = GetFormattedField(); + if ( pField ) + pField->SetMinValue( Value ); +} + +double SVTXCurrencyField::getMin() throw(::com::sun::star::uno::RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + FormattedField* pField = GetFormattedField(); + return pField ? pField->GetMinValue() : 0; +} + +void SVTXCurrencyField::setMax( double Value ) throw(::com::sun::star::uno::RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + FormattedField* pField = GetFormattedField(); + if ( pField ) + pField->SetMaxValue( Value ); +} + +double SVTXCurrencyField::getMax() throw(::com::sun::star::uno::RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + FormattedField* pField = GetFormattedField(); + return pField ? pField->GetMaxValue() : 0; +} + +void SVTXCurrencyField::setFirst( double Value ) throw(::com::sun::star::uno::RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + FormattedField* pField = GetFormattedField(); + if ( pField ) + pField->SetSpinFirst( Value ); +} + +double SVTXCurrencyField::getFirst() throw(::com::sun::star::uno::RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + FormattedField* pField = GetFormattedField(); + return pField ? pField->GetSpinFirst() : 0; +} + +void SVTXCurrencyField::setLast( double Value ) throw(::com::sun::star::uno::RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + FormattedField* pField = GetFormattedField(); + if ( pField ) + pField->SetSpinLast( Value ); +} + +double SVTXCurrencyField::getLast() throw(::com::sun::star::uno::RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + FormattedField* pField = GetFormattedField(); + return pField ? pField->GetSpinLast() : 0; +} + +void SVTXCurrencyField::setSpinSize( double Value ) throw(::com::sun::star::uno::RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + FormattedField* pField = GetFormattedField(); + if ( pField ) + pField->SetSpinSize( Value ); +} + +double SVTXCurrencyField::getSpinSize() throw(::com::sun::star::uno::RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + FormattedField* pField = GetFormattedField(); + return pField ? pField->GetSpinSize() : 0; +} + +void SVTXCurrencyField::setDecimalDigits( sal_Int16 Value ) throw(::com::sun::star::uno::RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + FormattedField* pField = GetFormattedField(); + if ( pField ) + pField->SetDecimalDigits( Value ); +} + +sal_Int16 SVTXCurrencyField::getDecimalDigits() throw(::com::sun::star::uno::RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + FormattedField* pField = GetFormattedField(); + return pField ? pField->GetDecimalDigits() : 0; +} + +void SVTXCurrencyField::setStrictFormat( sal_Bool bStrict ) throw(::com::sun::star::uno::RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + FormattedField* pField = GetFormattedField(); + if ( pField ) + pField->SetStrictFormat( bStrict ); +} + +sal_Bool SVTXCurrencyField::isStrictFormat() throw(::com::sun::star::uno::RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + FormattedField* pField = GetFormattedField(); + return pField ? pField->IsStrictFormat() : sal_False; +} + +void SVTXCurrencyField::setProperty( const ::rtl::OUString& PropertyName, const ::com::sun::star::uno::Any& Value) throw(::com::sun::star::uno::RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + ::com::sun::star::uno::Any aReturn; + + DoubleCurrencyField* pField = (DoubleCurrencyField*)GetFormattedField(); + if ( pField ) + { +#ifdef DBG_UTIL + String sAssertion( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "SVTXCurrencyField::setProperty(" ) ) ); + sAssertion += String( PropertyName ); + sAssertion.AppendAscii( RTL_CONSTASCII_STRINGPARAM( ") : invalid value !" ) ); +#endif + sal_uInt16 nPropType = GetPropertyId( PropertyName ); + switch (nPropType) + { + case BASEPROPERTY_CURRENCYSYMBOL: + { + ::rtl::OUString aStr; + Value >>= aStr; + pField->setCurrencySymbol( aStr ); + } + break; + case BASEPROPERTY_CURSYM_POSITION: + { + sal_Bool b = false; + Value >>= b; + pField->setPrependCurrSym(b); + } + break; + + default: + SVTXFormattedField::setProperty(PropertyName, Value); + } + } + else + SVTXFormattedField::setProperty(PropertyName, Value); +} + +::com::sun::star::uno::Any SVTXCurrencyField::getProperty( const ::rtl::OUString& PropertyName ) throw(::com::sun::star::uno::RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + ::com::sun::star::uno::Any aReturn; + + DoubleCurrencyField* pField = (DoubleCurrencyField*)GetFormattedField(); + if ( pField ) + { + sal_uInt16 nPropType = GetPropertyId( PropertyName ); + switch (nPropType) + { + case BASEPROPERTY_CURRENCYSYMBOL: + { + aReturn <<= ::rtl::OUString( pField->getCurrencySymbol() ); + } + break; + case BASEPROPERTY_CURSYM_POSITION: + { + aReturn <<= pField->getPrependCurrSym(); + } + break; + default: + return SVTXFormattedField::getProperty(PropertyName); + } + } + return SVTXFormattedField::getProperty(PropertyName); +} + +void SVTXCurrencyField::ImplGetPropertyIds( std::list< sal_uInt16 > &rIds ) +{ + PushPropertyIds( rIds, + BASEPROPERTY_CURRENCYSYMBOL, + BASEPROPERTY_CURSYM_POSITION, + 0); + SVTXFormattedField::ImplGetPropertyIds( rIds ); +} + + +// ---------------------------------------------------- +// class VCLXProgressBar +// ---------------------------------------------------- + +VCLXProgressBar::VCLXProgressBar() + :m_nValue(0) + ,m_nValueMin(0) + ,m_nValueMax(100) +{ +} + +VCLXProgressBar::~VCLXProgressBar() +{ +} + +void VCLXProgressBar::ImplUpdateValue() +{ + ProgressBar* pProgressBar = (ProgressBar*) GetWindow(); + if ( pProgressBar ) + { + sal_Int32 nVal; + sal_Int32 nValMin; + sal_Int32 nValMax; + + // check min and max + if (m_nValueMin < m_nValueMax) + { + nValMin = m_nValueMin; + nValMax = m_nValueMax; + } + else + { + nValMin = m_nValueMax; + nValMax = m_nValueMin; + } + + // check value + if (m_nValue < nValMin) + { + nVal = nValMin; + } + else if (m_nValue > nValMax) + { + nVal = nValMax; + } + else + { + nVal = m_nValue; + } + + // calculate percent + sal_Int32 nPercent; + if (nValMin != nValMax) + { + nPercent = 100 * (nVal - nValMin) / (nValMax - nValMin); + } + else + { + nPercent = 0; + } + + // set progressbar value + pProgressBar->SetValue( (USHORT) nPercent ); + } +} + +// ::com::sun::star::uno::XInterface +::com::sun::star::uno::Any VCLXProgressBar::queryInterface( const ::com::sun::star::uno::Type & rType ) throw(::com::sun::star::uno::RuntimeException) +{ + ::com::sun::star::uno::Any aRet = ::cppu::queryInterface( rType, + SAL_STATIC_CAST( ::com::sun::star::awt::XProgressBar*, this ), + SAL_STATIC_CAST( ::com::sun::star::lang::XTypeProvider*, this ) ); + return (aRet.hasValue() ? aRet : VCLXWindow::queryInterface( rType )); +} + +// ::com::sun::star::lang::XTypeProvider +IMPL_XTYPEPROVIDER_START( VCLXProgressBar ) + getCppuType( ( ::com::sun::star::uno::Reference< ::com::sun::star::awt::XProgressBar>* ) NULL ), + VCLXWindow::getTypes() +IMPL_XTYPEPROVIDER_END + +// ::com::sun::star::awt::XProgressBar +void VCLXProgressBar::setForegroundColor( sal_Int32 nColor ) throw(::com::sun::star::uno::RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + Window* pWindow = GetWindow(); + if ( pWindow ) + { + Color aColor( nColor ); + pWindow->SetControlForeground( aColor ); + } +} + +void VCLXProgressBar::setBackgroundColor( sal_Int32 nColor ) throw(::com::sun::star::uno::RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + Window* pWindow = GetWindow(); + if ( pWindow ) + { + Color aColor( nColor ); + pWindow->SetBackground( aColor ); + pWindow->SetControlBackground( aColor ); + pWindow->Invalidate(); + } +} + +void VCLXProgressBar::setValue( sal_Int32 nValue ) throw(::com::sun::star::uno::RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + m_nValue = nValue; + ImplUpdateValue(); +} + +void VCLXProgressBar::setRange( sal_Int32 nMin, sal_Int32 nMax ) throw(::com::sun::star::uno::RuntimeException ) +{ + ::vos::OGuard aGuard( GetMutex() ); + + if ( nMin < nMax ) + { + // take correct min and max + m_nValueMin = nMin; + m_nValueMax = nMax; + } + else + { + // change min and max + m_nValueMin = nMax; + m_nValueMax = nMin; + } + + ImplUpdateValue(); +} + +sal_Int32 VCLXProgressBar::getValue() throw(::com::sun::star::uno::RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + return m_nValue; +} + +// ::com::sun::star::awt::VclWindowPeer +void VCLXProgressBar::setProperty( const ::rtl::OUString& PropertyName, const ::com::sun::star::uno::Any& Value) throw(::com::sun::star::uno::RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + ProgressBar* pProgressBar = (ProgressBar*)GetWindow(); + if ( pProgressBar ) + { + sal_uInt16 nPropType = GetPropertyId( PropertyName ); + switch ( nPropType ) + { + case BASEPROPERTY_PROGRESSVALUE: + { + if ( Value >>= m_nValue ) + ImplUpdateValue(); + } + break; + case BASEPROPERTY_PROGRESSVALUE_MIN: + { + if ( Value >>= m_nValueMin ) + ImplUpdateValue(); + } + break; + case BASEPROPERTY_PROGRESSVALUE_MAX: + { + if ( Value >>= m_nValueMax ) + ImplUpdateValue(); + } + break; + case BASEPROPERTY_FILLCOLOR: + { + Window* pWindow = GetWindow(); + if ( pWindow ) + { + sal_Bool bVoid = Value.getValueType().getTypeClass() == ::com::sun::star::uno::TypeClass_VOID; + + if ( bVoid ) + { + pWindow->SetControlForeground(); + } + else + { + sal_Int32 nColor = 0; + if ( Value >>= nColor ) + { + Color aColor( nColor ); + pWindow->SetControlForeground( aColor ); + } + } + } + } + break; + default: + VCLXWindow::setProperty( PropertyName, Value ); + break; + } + } +} + +::com::sun::star::uno::Any VCLXProgressBar::getProperty( const ::rtl::OUString& PropertyName ) throw(::com::sun::star::uno::RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + ::com::sun::star::uno::Any aProp; + ProgressBar* pProgressBar = (ProgressBar*)GetWindow(); + if ( pProgressBar ) + { + sal_uInt16 nPropType = GetPropertyId( PropertyName ); + switch ( nPropType ) + { + case BASEPROPERTY_PROGRESSVALUE: + { + aProp <<= m_nValue; + } + break; + case BASEPROPERTY_PROGRESSVALUE_MIN: + { + aProp <<= m_nValueMin; + } + break; + case BASEPROPERTY_PROGRESSVALUE_MAX: + { + aProp <<= m_nValueMax; + } + break; + default: + aProp <<= VCLXWindow::getProperty( PropertyName ); + break; + } + } + return aProp; +} + +void VCLXProgressBar::ImplGetPropertyIds( std::list< sal_uInt16 > &rIds ) +{ + PushPropertyIds( rIds, + BASEPROPERTY_PROGRESSVALUE, + BASEPROPERTY_PROGRESSVALUE_MIN, + BASEPROPERTY_PROGRESSVALUE_MAX, + BASEPROPERTY_FILLCOLOR, + 0); + VCLXWindow::ImplGetPropertyIds( rIds, true ); +} + + +// ---------------------------------------------------- +// class SVTXDateField +// ---------------------------------------------------- +SVTXDateField::SVTXDateField() + :VCLXDateField() +{ +} + +SVTXDateField::~SVTXDateField() +{ +} + +void SAL_CALL SVTXDateField::setProperty( const ::rtl::OUString& PropertyName, const ::com::sun::star::uno::Any& Value ) throw(::com::sun::star::uno::RuntimeException) +{ + VCLXDateField::setProperty( PropertyName, Value ); + + // some properties need to be forwarded to the sub edit, too + Edit* pSubEdit = GetWindow() ? static_cast< Edit* >( GetWindow() )->GetSubEdit() : NULL; + if ( !pSubEdit ) + return; + + switch ( GetPropertyId( PropertyName ) ) + { + case BASEPROPERTY_TEXTLINECOLOR: + if ( !Value.hasValue() ) + pSubEdit->SetTextLineColor(); + else + { + sal_Int32 nColor = 0; + if ( Value >>= nColor ) + pSubEdit->SetTextLineColor( Color( nColor ) ); + } + break; + } +} + +void SVTXDateField::ImplGetPropertyIds( std::list< sal_uInt16 > &rIds ) +{ + PushPropertyIds( rIds, + BASEPROPERTY_TEXTLINECOLOR, + 0); + VCLXDateField::ImplGetPropertyIds( rIds ); +} diff --git a/svtools/source/uno/unoimap.cxx b/svtools/source/uno/unoimap.cxx new file mode 100644 index 000000000000..88f22f0c8402 --- /dev/null +++ b/svtools/source/uno/unoimap.cxx @@ -0,0 +1,824 @@ +/************************************************************************* + * + * 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_svtools.hxx" +#include <com/sun/star/container/XNameContainer.hpp> +#include <com/sun/star/container/XIndexContainer.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/document/XEventsSupplier.hpp> +#include <com/sun/star/lang/XUnoTunnel.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/awt/Rectangle.hpp> +#include <com/sun/star/awt/Point.hpp> +#include <com/sun/star/drawing/PointSequence.hpp> + +#ifndef _COMPHELPER_SERVICEHELPER_HXX_ +#include <comphelper/servicehelper.hxx> +#endif +#include <comphelper/propertysethelper.hxx> +#include <comphelper/propertysetinfo.hxx> +#include <cppuhelper/weakagg.hxx> + +#include <cppuhelper/implbase3.hxx> + +#include <list> +#include <rtl/uuid.h> +#include <vos/mutex.hxx> +#include <vcl/svapp.hxx> + +#include "unoevent.hxx" +#include "unoimap.hxx" +#include <svtools/imap.hxx> +#include <svtools/imapcirc.hxx> +#include <svtools/imaprect.hxx> +#include <svtools/imappoly.hxx> + +#ifndef SEQTYPE + #if defined(__SUNPRO_CC) && (__SUNPRO_CC == 0x500) + #define SEQTYPE(x) (new ::com::sun::star::uno::Type( x )) + #else + #define SEQTYPE(x) &(x) + #endif +#endif + +#define MAP_LEN(x) x, sizeof(x)-1 + + +using namespace comphelper; +using namespace cppu; +using namespace com::sun::star; +using namespace com::sun::star::uno; +using namespace com::sun::star::lang; +using namespace com::sun::star::container; +using namespace com::sun::star::beans; +using namespace com::sun::star::document; +using namespace com::sun::star::drawing; + +const sal_Int32 HANDLE_URL = 1; +const sal_Int32 HANDLE_DESCRIPTION = 2; +const sal_Int32 HANDLE_TARGET = 3; +const sal_Int32 HANDLE_NAME = 4; +const sal_Int32 HANDLE_ISACTIVE = 5; +const sal_Int32 HANDLE_POLYGON = 6; +const sal_Int32 HANDLE_CENTER = 7; +const sal_Int32 HANDLE_RADIUS = 8; +const sal_Int32 HANDLE_BOUNDARY = 9; +const sal_Int32 HANDLE_TITLE = 10; + +class SvUnoImageMapObject : public OWeakAggObject, + public XEventsSupplier, + public XServiceInfo, + public PropertySetHelper, + public XTypeProvider, + public XUnoTunnel +{ +public: + SvUnoImageMapObject( UINT16 nType, const SvEventDescription* pSupportedMacroItems ); + SvUnoImageMapObject( const IMapObject& rMapObject, const SvEventDescription* pSupportedMacroItems ); + virtual ~SvUnoImageMapObject() throw(); + + UNO3_GETIMPLEMENTATION_DECL( SvUnoImageMapObject ) + + IMapObject* createIMapObject() const; + + SvMacroTableEventDescriptor* mpEvents; + + // overiden helpers from PropertySetHelper + virtual void _setPropertyValues( const PropertyMapEntry** ppEntries, const Any* pValues ) throw(UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException ); + virtual void _getPropertyValues( const PropertyMapEntry** ppEntries, Any* pValue ) throw(UnknownPropertyException, WrappedTargetException ); + + // XInterface + virtual Any SAL_CALL queryAggregation( const Type & rType ) throw(RuntimeException); + virtual Any SAL_CALL queryInterface( const Type & rType ) throw(RuntimeException); + virtual void SAL_CALL acquire() throw(); + virtual void SAL_CALL release() throw(); + + // XTypeProvider + virtual Sequence< Type > SAL_CALL getTypes( ) throw(RuntimeException); + virtual Sequence< sal_Int8 > SAL_CALL getImplementationId( ) throw(RuntimeException); + + // XEventsSupplier + virtual Reference< ::com::sun::star::container::XNameReplace > SAL_CALL getEvents( ) throw(RuntimeException); + + // XServiceInfo + virtual ::rtl::OUString SAL_CALL getImplementationName( ) throw( RuntimeException ); + virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName ) throw( RuntimeException ); + virtual Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames( ) throw( RuntimeException ); + +private: + static PropertySetInfo* createPropertySetInfo( UINT16 nType ); + + + UINT16 mnType; + + ::rtl::OUString maURL; + ::rtl::OUString maAltText; + ::rtl::OUString maDesc; + ::rtl::OUString maTarget; + ::rtl::OUString maName; + sal_Bool mbIsActive; + awt::Rectangle maBoundary; + awt::Point maCenter; + sal_Int32 mnRadius; + PointSequence maPolygon; +}; + +UNO3_GETIMPLEMENTATION_IMPL( SvUnoImageMapObject ); + +PropertySetInfo* SvUnoImageMapObject::createPropertySetInfo( UINT16 nType ) +{ + switch( nType ) + { + case IMAP_OBJ_POLYGON: + { + static PropertyMapEntry aPolygonObj_Impl[] = + { + { MAP_LEN( "URL" ), HANDLE_URL, &::getCppuType((const ::rtl::OUString*)0), 0, 0 }, + { MAP_LEN( "Title" ), HANDLE_TITLE, &::getCppuType((const ::rtl::OUString*)0), 0, 0 }, + { MAP_LEN( "Description" ), HANDLE_DESCRIPTION, &::getCppuType((const ::rtl::OUString*)0), 0, 0 }, + { MAP_LEN( "Target" ), HANDLE_TARGET, &::getCppuType((const ::rtl::OUString*)0), 0, 0 }, + { MAP_LEN( "Name" ), HANDLE_NAME, &::getCppuType((const ::rtl::OUString*)0), 0, 0 }, + { MAP_LEN( "IsActive" ), HANDLE_ISACTIVE, &::getBooleanCppuType(), 0, 0 }, + { MAP_LEN( "Polygon" ), HANDLE_POLYGON, SEQTYPE(::getCppuType((const PointSequence*)0)), 0, 0 }, + {0,0,0,0,0,0} + }; + + return new PropertySetInfo( aPolygonObj_Impl ); + } + case IMAP_OBJ_CIRCLE: + { + static PropertyMapEntry aCircleObj_Impl[] = + { + { MAP_LEN( "URL" ), HANDLE_URL, &::getCppuType((const ::rtl::OUString*)0), 0, 0 }, + { MAP_LEN( "Title" ), HANDLE_TITLE, &::getCppuType((const ::rtl::OUString*)0), 0, 0 }, + { MAP_LEN( "Description" ), HANDLE_DESCRIPTION, &::getCppuType((const ::rtl::OUString*)0), 0, 0 }, + { MAP_LEN( "Target" ), HANDLE_TARGET, &::getCppuType((const ::rtl::OUString*)0), 0, 0 }, + { MAP_LEN( "Name" ), HANDLE_NAME, &::getCppuType((const ::rtl::OUString*)0), 0, 0 }, + { MAP_LEN( "IsActive" ), HANDLE_ISACTIVE, &::getBooleanCppuType(), 0, 0 }, + { MAP_LEN( "Center" ), HANDLE_CENTER, &::getCppuType((const awt::Point*)0), 0, 0 }, + { MAP_LEN( "Radius" ), HANDLE_RADIUS, &::getCppuType((const sal_Int32*)0), 0, 0 }, + {0,0,0,0,0,0} + }; + + return new PropertySetInfo( aCircleObj_Impl ); + } + case IMAP_OBJ_RECTANGLE: + default: + { + static PropertyMapEntry aRectangleObj_Impl[] = + { + { MAP_LEN( "URL" ), HANDLE_URL, &::getCppuType((const ::rtl::OUString*)0), 0, 0 }, + { MAP_LEN( "Title" ), HANDLE_TITLE, &::getCppuType((const ::rtl::OUString*)0), 0, 0 }, + { MAP_LEN( "Description" ), HANDLE_DESCRIPTION, &::getCppuType((const ::rtl::OUString*)0), 0, 0 }, + { MAP_LEN( "Target" ), HANDLE_TARGET, &::getCppuType((const ::rtl::OUString*)0), 0, 0 }, + { MAP_LEN( "Name" ), HANDLE_NAME, &::getCppuType((const ::rtl::OUString*)0), 0, 0 }, + { MAP_LEN( "IsActive" ), HANDLE_ISACTIVE, &::getBooleanCppuType(), 0, 0 }, + { MAP_LEN( "Boundary" ), HANDLE_BOUNDARY, &::getCppuType((const awt::Rectangle*)0), 0, 0 }, + {0,0,0,0,0,0} + }; + + return new PropertySetInfo( aRectangleObj_Impl ); + } + } +} + +SvUnoImageMapObject::SvUnoImageMapObject( UINT16 nType, const SvEventDescription* pSupportedMacroItems ) +: PropertySetHelper( createPropertySetInfo( nType ) ), + mnType( nType ) +, mbIsActive( true ) +, mnRadius( 0 ) +{ + mpEvents = new SvMacroTableEventDescriptor( pSupportedMacroItems ); + mpEvents->acquire(); +} + +SvUnoImageMapObject::SvUnoImageMapObject( const IMapObject& rMapObject, const SvEventDescription* pSupportedMacroItems ) +: PropertySetHelper( createPropertySetInfo( rMapObject.GetType() ) ), + mnType( rMapObject.GetType() ) +, mbIsActive( true ) +, mnRadius( 0 ) +{ + maURL = rMapObject.GetURL(); + maAltText = rMapObject.GetAltText(); + maDesc = rMapObject.GetDesc(); + maTarget = rMapObject.GetTarget(); + maName = rMapObject.GetName(); + mbIsActive = rMapObject.IsActive(); + + switch( mnType ) + { + case IMAP_OBJ_RECTANGLE: + { + const Rectangle aRect( ((IMapRectangleObject*)&rMapObject)->GetRectangle(sal_False) ); + maBoundary.X = aRect.Left(); + maBoundary.Y = aRect.Top(); + maBoundary.Width = aRect.GetWidth(); + maBoundary.Height = aRect.GetHeight(); + } + break; + case IMAP_OBJ_CIRCLE: + { + mnRadius = (sal_Int32)((IMapCircleObject*)&rMapObject)->GetRadius(sal_False); + const Point aPoint( ((IMapCircleObject*)&rMapObject)->GetCenter(sal_False) ); + + maCenter.X = aPoint.X(); + maCenter.Y = aPoint.Y(); + } + break; + case IMAP_OBJ_POLYGON: + default: + { + const Polygon aPoly( ((IMapPolygonObject*)&rMapObject)->GetPolygon(sal_False) ); + + const USHORT nCount = aPoly.GetSize(); + maPolygon.realloc( nCount ); + awt::Point* pPoints = maPolygon.getArray(); + + for( USHORT nPoint = 0; nPoint < nCount; nPoint++ ) + { + const Point& rPoint = aPoly.GetPoint( nPoint ); + pPoints->X = rPoint.X(); + pPoints->Y = rPoint.Y(); + + pPoints++; + } + } + } + + mpEvents = new SvMacroTableEventDescriptor( rMapObject.GetMacroTable(), pSupportedMacroItems ); + mpEvents->acquire(); +} + +SvUnoImageMapObject::~SvUnoImageMapObject() throw() +{ + mpEvents->release(); +} + +IMapObject* SvUnoImageMapObject::createIMapObject() const +{ + const String aURL( maURL ); + const String aAltText( maAltText ); + const String aDesc( maDesc ); + const String aTarget( maTarget ); + const String aName( maName ); + + IMapObject* pNewIMapObject; + + switch( mnType ) + { + case IMAP_OBJ_RECTANGLE: + { + const Rectangle aRect( maBoundary.X, maBoundary.Y, maBoundary.X + maBoundary.Width - 1, maBoundary.Y + maBoundary.Height - 1 ); + pNewIMapObject = new IMapRectangleObject( aRect, aURL, aAltText, aDesc, aTarget, aName, mbIsActive, sal_False ); + } + break; + + case IMAP_OBJ_CIRCLE: + { + const Point aCenter( maCenter.X, maCenter.Y ); + pNewIMapObject = new IMapCircleObject( aCenter, mnRadius, aURL, aAltText, aDesc, aTarget, aName, mbIsActive, sal_False ); + } + break; + + case IMAP_OBJ_POLYGON: + default: + { + const sal_uInt16 nCount = (sal_uInt16)maPolygon.getLength(); + + Polygon aPoly( nCount ); + for( sal_uInt16 nPoint = 0; nPoint < nCount; nPoint++ ) + { + Point aPoint( maPolygon[nPoint].X, maPolygon[nPoint].Y ); + aPoly.SetPoint( aPoint, nPoint ); + } + + aPoly.Optimize( POLY_OPTIMIZE_CLOSE ); + pNewIMapObject = new IMapPolygonObject( aPoly, aURL, aAltText, aDesc, aTarget, aName, mbIsActive, sal_False ); + } + break; + } + + SvxMacroTableDtor aMacroTable; + mpEvents->copyMacrosIntoTable(aMacroTable); + pNewIMapObject->SetMacroTable( aMacroTable ); + + return pNewIMapObject; +} + +// XInterface + +Any SAL_CALL SvUnoImageMapObject::queryInterface( const Type & rType ) + throw( RuntimeException ) +{ + return OWeakAggObject::queryInterface( rType ); +} + +Any SAL_CALL SvUnoImageMapObject::queryAggregation( const Type & rType ) + throw(RuntimeException) +{ + Any aAny; + + if( rType == ::getCppuType((const Reference< XServiceInfo >*)0) ) + aAny <<= Reference< XServiceInfo >(this); + else if( rType == ::getCppuType((const Reference< XTypeProvider >*)0) ) + aAny <<= Reference< XTypeProvider >(this); + else if( rType == ::getCppuType((const Reference< XPropertySet >*)0) ) + aAny <<= Reference< XPropertySet >(this); + else if( rType == ::getCppuType((const Reference< XEventsSupplier >*)0) ) + aAny <<= Reference< XEventsSupplier >(this); + else if( rType == ::getCppuType((const Reference< XMultiPropertySet >*)0) ) + aAny <<= Reference< XMultiPropertySet >(this); + else if( rType == ::getCppuType((const Reference< XUnoTunnel >*)0) ) + aAny <<= Reference< XUnoTunnel >(this); + else + aAny <<= OWeakAggObject::queryAggregation( rType ); + + return aAny; +} + +void SAL_CALL SvUnoImageMapObject::acquire() throw() +{ + OWeakAggObject::acquire(); +} + +void SAL_CALL SvUnoImageMapObject::release() throw() +{ + OWeakAggObject::release(); +} + +uno::Sequence< uno::Type > SAL_CALL SvUnoImageMapObject::getTypes() + throw (uno::RuntimeException) +{ + uno::Sequence< uno::Type > aTypes( 7 ); + uno::Type* pTypes = aTypes.getArray(); + + *pTypes++ = ::getCppuType((const uno::Reference< XAggregation>*)0); + *pTypes++ = ::getCppuType((const uno::Reference< XEventsSupplier>*)0); + *pTypes++ = ::getCppuType((const uno::Reference< XServiceInfo>*)0); + *pTypes++ = ::getCppuType((const uno::Reference< XPropertySet>*)0); + *pTypes++ = ::getCppuType((const uno::Reference< XMultiPropertySet>*)0); + *pTypes++ = ::getCppuType((const uno::Reference< XTypeProvider>*)0); + *pTypes++ = ::getCppuType((const uno::Reference< XUnoTunnel>*)0); + + return aTypes; +} + +uno::Sequence< sal_Int8 > SAL_CALL SvUnoImageMapObject::getImplementationId() + throw (uno::RuntimeException) +{ + vos::OGuard aGuard( Application::GetSolarMutex() ); + + static uno::Sequence< sal_Int8 > aId; + if( aId.getLength() == 0 ) + { + aId.realloc( 16 ); + rtl_createUuid( (sal_uInt8 *)aId.getArray(), 0, sal_True ); + } + return aId; +} + +// XServiceInfo + +sal_Bool SAL_CALL SvUnoImageMapObject::supportsService( const ::rtl::OUString& ServiceName ) throw(RuntimeException) +{ + const Sequence< ::rtl::OUString > aSNL( getSupportedServiceNames() ); + const ::rtl::OUString * pArray = aSNL.getConstArray(); + + const sal_Int32 nCount = aSNL.getLength(); + for( sal_Int32 i = 0; i < nCount; i++ ) + if( pArray[i] == ServiceName ) + return sal_True; + + return sal_False; +} + +Sequence< ::rtl::OUString > SAL_CALL SvUnoImageMapObject::getSupportedServiceNames() + throw(RuntimeException) +{ + Sequence< ::rtl::OUString > aSNS( 2 ); + aSNS.getArray()[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.image.ImageMapObject" )); + switch( mnType ) + { + case IMAP_OBJ_POLYGON: + default: + aSNS.getArray()[1] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.image.ImageMapPolygonObject" )); + break; + case IMAP_OBJ_RECTANGLE: + aSNS.getArray()[1] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.image.ImageMapRectangleObject" )); + break; + case IMAP_OBJ_CIRCLE: + aSNS.getArray()[1] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.image.ImageMapCircleObject" )); + break; + } + return aSNS; +} + +::rtl::OUString SAL_CALL SvUnoImageMapObject::getImplementationName() throw(RuntimeException) +{ + switch( mnType ) + { + case IMAP_OBJ_POLYGON: + default: + return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("org.openoffice.comp.svt.ImageMapPolygonObject") ); + case IMAP_OBJ_CIRCLE: + return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("org.openoffice.comp.svt.ImageMapCircleObject") ); + case IMAP_OBJ_RECTANGLE: + return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("org.openoffice.comp.svt.ImageMapRectangleObject") ); + } +} + +// overiden helpers from PropertySetHelper +void SvUnoImageMapObject::_setPropertyValues( const PropertyMapEntry** ppEntries, const Any* pValues ) + throw(UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException ) +{ + sal_Bool bOk = sal_False; + + while( *ppEntries ) + { + switch( (*ppEntries)->mnHandle ) + { + case HANDLE_URL: + bOk = *pValues >>= maURL; + break; + case HANDLE_TITLE: + bOk = *pValues >>= maAltText; + break; + case HANDLE_DESCRIPTION: + bOk = *pValues >>= maDesc; + break; + case HANDLE_TARGET: + bOk = *pValues >>= maTarget; + break; + case HANDLE_NAME: + bOk = *pValues >>= maName; + break; + case HANDLE_ISACTIVE: + bOk = *pValues >>= mbIsActive; + break; + case HANDLE_BOUNDARY: + bOk = *pValues >>= maBoundary; + break; + case HANDLE_CENTER: + bOk = *pValues >>= maCenter; + break; + case HANDLE_RADIUS: + bOk = *pValues >>= mnRadius; + break; + case HANDLE_POLYGON: + bOk = *pValues >>= maPolygon; + break; + default: + DBG_ERROR( "SvUnoImageMapObject::_setPropertyValues: unexpected property handle" ); + break; + } + + if( !bOk ) + throw IllegalArgumentException(); + + ppEntries++; + pValues++; + } +} + +void SvUnoImageMapObject::_getPropertyValues( const PropertyMapEntry** ppEntries, Any* pValues ) + throw(UnknownPropertyException, WrappedTargetException ) +{ + while( *ppEntries ) + { + switch( (*ppEntries)->mnHandle ) + { + case HANDLE_URL: + *pValues <<= maURL; + break; + case HANDLE_TITLE: + *pValues <<= maAltText; + break; + case HANDLE_DESCRIPTION: + *pValues <<= maDesc; + break; + case HANDLE_TARGET: + *pValues <<= maTarget; + break; + case HANDLE_NAME: + *pValues <<= maName; + break; + case HANDLE_ISACTIVE: + *pValues <<= mbIsActive; + break; + case HANDLE_BOUNDARY: + *pValues <<= maBoundary; + break; + case HANDLE_CENTER: + *pValues <<= maCenter; + break; + case HANDLE_RADIUS: + *pValues <<= mnRadius; + break; + case HANDLE_POLYGON: + *pValues <<= maPolygon; + break; + default: + DBG_ERROR( "SvUnoImageMapObject::_getPropertyValues: unexpected property handle" ); + break; + } + + ppEntries++; + pValues++; + } +} + + +Reference< XNameReplace > SAL_CALL SvUnoImageMapObject::getEvents() + throw( RuntimeException ) +{ + // try weak reference first + Reference< XNameReplace > xEvents( mpEvents ); + return xEvents; +} + +/////////////////////////////////////////////////////////////////////// + +class SvUnoImageMap : public WeakImplHelper3< XIndexContainer, XServiceInfo, XUnoTunnel > +{ +public: + SvUnoImageMap( const SvEventDescription* pSupportedMacroItems ); + SvUnoImageMap( const ImageMap& rMap, const SvEventDescription* pSupportedMacroItems ); + virtual ~SvUnoImageMap(); + + sal_Bool fillImageMap( ImageMap& rMap ) const; + SvUnoImageMapObject* getObject( const Any& aElement ) const throw( IllegalArgumentException ); + + UNO3_GETIMPLEMENTATION_DECL( SvUnoImageMap ) + + // XIndexContainer + virtual void SAL_CALL insertByIndex( sal_Int32 Index, const Any& Element ) throw( IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException ); + virtual void SAL_CALL removeByIndex( sal_Int32 Index ) throw( IndexOutOfBoundsException, WrappedTargetException, RuntimeException ); + + // XIndexReplace + virtual void SAL_CALL replaceByIndex( sal_Int32 Index, const Any& Element ) throw( IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException ); + + // XIndexAccess + virtual sal_Int32 SAL_CALL getCount( ) throw( RuntimeException ); + virtual Any SAL_CALL getByIndex( sal_Int32 Index ) throw( IndexOutOfBoundsException, WrappedTargetException, RuntimeException ); + + // XElementAccess + virtual Type SAL_CALL getElementType( ) throw( RuntimeException ); + virtual sal_Bool SAL_CALL hasElements( ) throw( RuntimeException ); + + // XSerivceInfo + virtual ::rtl::OUString SAL_CALL getImplementationName( ) throw( RuntimeException ); + virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName ) throw( RuntimeException ); + virtual Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames( ) throw( RuntimeException ); + +private: + ::rtl::OUString maName; + + std::list< SvUnoImageMapObject* > maObjectList; +}; + +UNO3_GETIMPLEMENTATION_IMPL( SvUnoImageMap ); + +SvUnoImageMap::SvUnoImageMap( const SvEventDescription* ) +{ +} + +SvUnoImageMap::SvUnoImageMap( const ImageMap& rMap, const SvEventDescription* pSupportedMacroItems ) +{ + maName = rMap.GetName(); + + const UINT16 nCount = rMap.GetIMapObjectCount(); + for( UINT16 nPos = 0; nPos < nCount; nPos++ ) + { + IMapObject* pMapObject = rMap.GetIMapObject( nPos ); + SvUnoImageMapObject* pUnoObj = new SvUnoImageMapObject( *pMapObject, pSupportedMacroItems ); + pUnoObj->acquire(); + maObjectList.push_back( pUnoObj ); + } +} + +SvUnoImageMap::~SvUnoImageMap() +{ + std::list< SvUnoImageMapObject* >::iterator aIter = maObjectList.begin(); + const std::list< SvUnoImageMapObject* >::iterator aEnd = maObjectList.end(); + while( aIter != aEnd ) + { + (*aIter++)->release(); + } +} + +SvUnoImageMapObject* SvUnoImageMap::getObject( const Any& aElement ) const + throw( IllegalArgumentException ) +{ + Reference< XInterface > xObject; + aElement >>= xObject; + + SvUnoImageMapObject* pObject = SvUnoImageMapObject::getImplementation( xObject ); + if( NULL == pObject ) + throw IllegalArgumentException(); + + return pObject; +} + +// XIndexContainer +void SAL_CALL SvUnoImageMap::insertByIndex( sal_Int32 Index, const Any& Element ) + throw( IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException ) +{ + SvUnoImageMapObject* pObject = getObject( Element ); + const sal_Int32 nCount = maObjectList.size(); + if( NULL == pObject || Index > nCount ) + throw IndexOutOfBoundsException(); + + pObject->acquire(); + + if( Index == nCount ) + maObjectList.push_back( pObject ); + else + { + std::list< SvUnoImageMapObject* >::iterator aIter = maObjectList.begin(); + for( sal_Int32 n = 0; n < Index; n++ ) + aIter++; + + maObjectList.insert( aIter, pObject ); + } +} + +void SAL_CALL SvUnoImageMap::removeByIndex( sal_Int32 Index ) throw(IndexOutOfBoundsException, WrappedTargetException, RuntimeException) +{ + const sal_Int32 nCount = maObjectList.size(); + if( Index >= nCount ) + throw IndexOutOfBoundsException(); + + if( nCount - 1 == Index ) + { + maObjectList.back()->release(); + maObjectList.pop_back(); + } + else + { + std::list< SvUnoImageMapObject* >::iterator aIter = maObjectList.begin(); + for( sal_Int32 n = 0; n < Index; n++ ) + aIter++; + + (*aIter)->release(); + maObjectList.erase( aIter ); + } +} + +// XIndexReplace +void SAL_CALL SvUnoImageMap::replaceByIndex( sal_Int32 Index, const Any& Element ) throw(IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException) +{ + SvUnoImageMapObject* pObject = getObject( Element ); + const sal_Int32 nCount = maObjectList.size(); + if( NULL == pObject || Index >= nCount ) + throw IndexOutOfBoundsException(); + + std::list< SvUnoImageMapObject* >::iterator aIter = maObjectList.begin(); + for( sal_Int32 n = 0; n < Index; n++ ) + aIter++; + + (*aIter)->release(); + *aIter = pObject; + pObject->acquire(); +} + +// XIndexAccess +sal_Int32 SAL_CALL SvUnoImageMap::getCount( ) throw(RuntimeException) +{ + return maObjectList.size(); +} + +Any SAL_CALL SvUnoImageMap::getByIndex( sal_Int32 Index ) throw(IndexOutOfBoundsException, WrappedTargetException, RuntimeException) +{ + const sal_Int32 nCount = maObjectList.size(); + if( Index >= nCount ) + throw IndexOutOfBoundsException(); + + std::list< SvUnoImageMapObject* >::iterator aIter = maObjectList.begin(); + for( sal_Int32 n = 0; n < Index; n++ ) + aIter++; + + Reference< XPropertySet > xObj( *aIter ); + return makeAny( xObj ); +} + +// XElementAccess +Type SAL_CALL SvUnoImageMap::getElementType( ) throw(RuntimeException) +{ + return ::getCppuType((const Reference< XPropertySet >*)0); +} + +sal_Bool SAL_CALL SvUnoImageMap::hasElements( ) throw(RuntimeException) +{ + return maObjectList.size() != 0; +} + +// XSerivceInfo +::rtl::OUString SAL_CALL SvUnoImageMap::getImplementationName( ) + throw(RuntimeException) +{ + return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "org.openoffice.comp.svt.SvUnoImageMap" ) ); +} + +sal_Bool SAL_CALL SvUnoImageMap::supportsService( const ::rtl::OUString& ServiceName ) + throw(RuntimeException) +{ + const Sequence< ::rtl::OUString > aSNL( getSupportedServiceNames() ); + const ::rtl::OUString * pArray = aSNL.getConstArray(); + + const sal_Int32 nCount = aSNL.getLength(); + for( sal_Int32 i = 0; i < nCount; i++ ) + if( pArray[i] == ServiceName ) + return sal_True; + + return sal_False; +} + +Sequence< ::rtl::OUString > SAL_CALL SvUnoImageMap::getSupportedServiceNames( ) + throw(RuntimeException) +{ + const ::rtl::OUString aSN( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.image.ImageMap" ) ); + return Sequence< ::rtl::OUString >( &aSN, 1 ); +} + +sal_Bool SvUnoImageMap::fillImageMap( ImageMap& rMap ) const +{ + rMap.ClearImageMap(); + + rMap.SetName( maName ); + + std::list< SvUnoImageMapObject* >::const_iterator aIter = maObjectList.begin(); + const std::list< SvUnoImageMapObject* >::const_iterator aEnd = maObjectList.end(); + while( aIter != aEnd ) + { + IMapObject* pNewMapObject = (*aIter)->createIMapObject(); + rMap.InsertIMapObject( *pNewMapObject ); + delete pNewMapObject; + + aIter++; + } + + return sal_True; +} + +// ------------------------------------------------------------------- +// factory helper methods +// ------------------------------------------------------------------- + +Reference< XInterface > SvUnoImageMapRectangleObject_createInstance( const SvEventDescription* pSupportedMacroItems ) +{ + return (XWeak*)new SvUnoImageMapObject( IMAP_OBJ_RECTANGLE, pSupportedMacroItems ); +} + +Reference< XInterface > SvUnoImageMapCircleObject_createInstance( const SvEventDescription* pSupportedMacroItems ) +{ + return (XWeak*)new SvUnoImageMapObject( IMAP_OBJ_CIRCLE, pSupportedMacroItems ); +} + +Reference< XInterface > SvUnoImageMapPolygonObject_createInstance( const SvEventDescription* pSupportedMacroItems ) +{ + return (XWeak*)new SvUnoImageMapObject( IMAP_OBJ_POLYGON, pSupportedMacroItems ); +} + +Reference< XInterface > SvUnoImageMap_createInstance( const SvEventDescription* pSupportedMacroItems ) +{ + return (XWeak*)new SvUnoImageMap( pSupportedMacroItems ); +} + +Reference< XInterface > SvUnoImageMap_createInstance( const ImageMap& rMap, const SvEventDescription* pSupportedMacroItems ) +{ + return (XWeak*)new SvUnoImageMap( rMap, pSupportedMacroItems ); +} + +sal_Bool SvUnoImageMap_fillImageMap( Reference< XInterface > xImageMap, ImageMap& rMap ) +{ + SvUnoImageMap* pUnoImageMap = SvUnoImageMap::getImplementation( xImageMap ); + if( NULL == pUnoImageMap ) + return sal_False; + + return pUnoImageMap->fillImageMap( rMap ); +} diff --git a/svtools/source/uno/unowizard.hxx b/svtools/source/uno/unowizard.hxx new file mode 100644 index 000000000000..ceb8fac14eb6 --- /dev/null +++ b/svtools/source/uno/unowizard.hxx @@ -0,0 +1,117 @@ +/************************************************************************* + * 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. + * + ************************************************************************/ + +#ifndef SVT_UNO_WIZARD_HXX +#define SVT_UNO_WIZARD_HXX + +#include "svtools/genericunodialog.hxx" + +/** === begin UNO includes === **/ +#include <com/sun/star/ui/dialogs/XWizard.hpp> +#include <com/sun/star/uno/XComponentContext.hpp> +#include <com/sun/star/ui/dialogs/XWizardController.hpp> +/** === end UNO includes === **/ + +#include <cppuhelper/implbase1.hxx> +#include <comphelper/componentcontext.hxx> + +//...................................................................................................................... +namespace svt { namespace uno +{ +//...................................................................................................................... + + //================================================================================================================== + //= Wizard - declaration + //================================================================================================================== + typedef ::cppu::ImplInheritanceHelper1 < ::svt::OGenericUnoDialog + , ::com::sun::star::ui::dialogs::XWizard + > Wizard_Base; + class Wizard; + typedef ::comphelper::OPropertyArrayUsageHelper< Wizard > Wizard_PBase; + class Wizard : public Wizard_Base + , public Wizard_PBase + { + public: + Wizard( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& i_rContext ); + + // ::com::sun::star::lang::XServiceInfo - static version + static ::rtl::OUString SAL_CALL getImplementationName_static() throw(::com::sun::star::uno::RuntimeException); + static ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames_static() throw(::com::sun::star::uno::RuntimeException); + static ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL Create( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& i_rContext ); + + protected: + // ::com::sun::star::lang::XServiceInfo + virtual ::rtl::OUString SAL_CALL getImplementationName() throw(::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames() throw(::com::sun::star::uno::RuntimeException); + + // ::com::sun::star::beans::XPropertySet + virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo() throw(::com::sun::star::uno::RuntimeException); + virtual ::cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper(); + + // OPropertyArrayUsageHelper + virtual ::cppu::IPropertyArrayHelper* createArrayHelper( ) const; + + // ::com::sun::star::ui::dialogs::XWizard + virtual ::rtl::OUString SAL_CALL getHelpURL() throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setHelpURL( const ::rtl::OUString& _helpurl ) throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindow > SAL_CALL getDialogWindow() throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Reference< ::com::sun::star::ui::dialogs::XWizardPage > SAL_CALL getCurrentPage( ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL enableButton( ::sal_Int16 WizardButton, ::sal_Bool Enable ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setDefaultButton( ::sal_Int16 WizardButton ) throw (::com::sun::star::uno::RuntimeException); + virtual ::sal_Bool SAL_CALL travelNext( ) throw (::com::sun::star::uno::RuntimeException); + virtual ::sal_Bool SAL_CALL travelPrevious( ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL enablePage( ::sal_Int16 PageID, ::sal_Bool Enable ) throw (::com::sun::star::container::NoSuchElementException, ::com::sun::star::util::InvalidStateException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL updateTravelUI( ) throw (::com::sun::star::uno::RuntimeException); + virtual ::sal_Bool SAL_CALL advanceTo( ::sal_Int16 PageId ) throw (::com::sun::star::uno::RuntimeException); + virtual ::sal_Bool SAL_CALL goBackTo( ::sal_Int16 PageId ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL activatePath( ::sal_Int16 PathIndex, ::sal_Bool Final ) throw (::com::sun::star::container::NoSuchElementException, ::com::sun::star::util::InvalidStateException, ::com::sun::star::uno::RuntimeException); + + // ::com::sun::star::ui::dialogs::XExecutableDialog + virtual void SAL_CALL setTitle( const ::rtl::OUString& aTitle ) throw (::com::sun::star::uno::RuntimeException); + virtual ::sal_Int16 SAL_CALL execute( ) throw (::com::sun::star::uno::RuntimeException); + + // ::com::sun::star::lang::XInitialization + virtual void SAL_CALL initialize( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aArguments ) throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException); + + protected: + ~Wizard(); + + protected: + virtual Dialog* createDialog( Window* _pParent ); + virtual void destroyDialog(); + + private: + ::comphelper::ComponentContext m_aContext; + ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< sal_Int16 > > m_aWizardSteps; + ::com::sun::star::uno::Reference< ::com::sun::star::ui::dialogs::XWizardController > m_xController; + ::rtl::OUString m_sHelpURL; + }; + +//...................................................................................................................... +} } // namespace svt::uno +//...................................................................................................................... + +#endif // SVT_UNO_WIZARD_HXX diff --git a/svtools/source/uno/wizard/makefile.mk b/svtools/source/uno/wizard/makefile.mk new file mode 100644 index 000000000000..521496fc5d48 --- /dev/null +++ b/svtools/source/uno/wizard/makefile.mk @@ -0,0 +1,48 @@ +#************************************************************************* +# +# 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=svtools +TARGET=unowiz +ENABLE_EXCEPTIONS=TRUE + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk +.INCLUDE : $(PRJ)$/util$/svt.pmk + +# --- Files -------------------------------------------------------- + +SLOFILES= \ + $(SLO)$/unowizard.obj \ + $(SLO)$/wizardshell.obj \ + $(SLO)$/wizardpagecontroller.obj + +# --- Targets ------------------------------------------------------ + +.INCLUDE : target.mk diff --git a/svtools/source/uno/wizard/unowizard.cxx b/svtools/source/uno/wizard/unowizard.cxx new file mode 100644 index 000000000000..147b11aceb11 --- /dev/null +++ b/svtools/source/uno/wizard/unowizard.cxx @@ -0,0 +1,452 @@ +/************************************************************************* + * 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 "precompiled_svtools.hxx" + +#include "../unowizard.hxx" +#include "wizardshell.hxx" + +/** === begin UNO includes === **/ +#include <com/sun/star/lang/XInitialization.hpp> +#include <com/sun/star/beans/XPropertySetInfo.hpp> +#include <com/sun/star/uno/XComponentContext.hpp> +#include <com/sun/star/ucb/AlreadyInitializedException.hpp> +#include <com/sun/star/ui/dialogs/XWizardController.hpp> +#include <com/sun/star/ui/dialogs/WizardButton.hpp> +/** === end UNO includes === **/ + +#include <tools/diagnose_ex.h> +#include <rtl/strbuf.hxx> +#include <vos/mutex.hxx> +#include <vcl/svapp.hxx> + +//...................................................................................................................... +namespace svt { namespace uno +{ +//...................................................................................................................... + + /** === begin UNO using === **/ + using ::com::sun::star::uno::Reference; + using ::com::sun::star::uno::XInterface; + using ::com::sun::star::uno::UNO_QUERY; + using ::com::sun::star::uno::UNO_QUERY_THROW; + using ::com::sun::star::uno::UNO_SET_THROW; + using ::com::sun::star::uno::Exception; + using ::com::sun::star::uno::RuntimeException; + using ::com::sun::star::uno::Any; + using ::com::sun::star::uno::makeAny; + using ::com::sun::star::uno::Sequence; + using ::com::sun::star::uno::Type; + using ::com::sun::star::lang::XServiceInfo; + using ::com::sun::star::ui::dialogs::XWizard; + using ::com::sun::star::lang::XInitialization; + using ::com::sun::star::beans::XPropertySetInfo; + using ::com::sun::star::uno::XComponentContext; + using ::com::sun::star::beans::Property; + using ::com::sun::star::lang::IllegalArgumentException; + using ::com::sun::star::ucb::AlreadyInitializedException; + using ::com::sun::star::ui::dialogs::XWizardController; + using ::com::sun::star::ui::dialogs::XWizardPage; + using ::com::sun::star::container::NoSuchElementException; + using ::com::sun::star::util::InvalidStateException; + using ::com::sun::star::awt::XWindow; + /** === end UNO using === **/ + namespace WizardButton = ::com::sun::star::ui::dialogs::WizardButton; + + //------------------------------------------------------------------------------------------------------------------ + namespace + { + sal_uInt32 lcl_convertWizardButtonToWZB( const sal_Int16 i_nWizardButton ) + { + switch ( i_nWizardButton ) + { + case WizardButton::NONE: return WZB_NONE; + case WizardButton::NEXT: return WZB_NEXT; + case WizardButton::PREVIOUS: return WZB_PREVIOUS; + case WizardButton::FINISH: return WZB_FINISH; + case WizardButton::CANCEL: return WZB_CANCEL; + case WizardButton::HELP: return WZB_HELP; + } + OSL_ENSURE( false, "lcl_convertWizardButtonToWZB: invalid WizardButton constant!" ); + return WZB_NONE; + } + } + + //================================================================================================================== + //= Wizard - implementation + //================================================================================================================== + //------------------------------------------------------------------------------------------------------------------ + Wizard::Wizard( const Reference< XComponentContext >& _rxContext ) + :Wizard_Base( _rxContext ) + ,m_aContext( _rxContext ) + { + } + + //-------------------------------------------------------------------- + Wizard::~Wizard() + { + // we do this here cause the base class' call to destroyDialog won't reach us anymore : we're within an dtor, + // so this virtual-method-call the base class does does not work, we're already dead then ... + if ( m_pDialog ) + { + ::osl::MutexGuard aGuard( m_aMutex ); + if ( m_pDialog ) + destroyDialog(); + } + } + + //-------------------------------------------------------------------- + Reference< XInterface > SAL_CALL Wizard::Create( const Reference< XComponentContext >& _rxContext ) + { + return *(new Wizard( _rxContext ) ); + } + + //-------------------------------------------------------------------- + namespace + { + static void lcl_checkPaths( const Sequence< Sequence< sal_Int16 > >& i_rPaths, const Reference< XInterface >& i_rContext ) + { + // need at least one path + if ( i_rPaths.getLength() == 0 ) + throw IllegalArgumentException( ::rtl::OUString(), i_rContext, 2 ); + + // each path must be of length 1, at least + for ( sal_Int32 i = 0; i < i_rPaths.getLength(); ++i ) + { + if ( i_rPaths[i].getLength() == 0 ) + throw IllegalArgumentException( ::rtl::OUString(), i_rContext, 2 ); + + // page IDs must be in ascending order + sal_Int16 nPreviousPageID = i_rPaths[i][0]; + for ( sal_Int32 j=1; j<i_rPaths[i].getLength(); ++j ) + { + if ( i_rPaths[i][j] <= nPreviousPageID ) + { + ::rtl::OStringBuffer message; + message.append( "Path " ); + message.append( i ); + message.append( ": invalid page ID sequence - each page ID must be greater than the previous one." ); + throw IllegalArgumentException( + ::rtl::OStringToOUString( message.makeStringAndClear(), RTL_TEXTENCODING_ASCII_US ), + i_rContext, 2 ); + } + nPreviousPageID = i_rPaths[i][j]; + } + } + + // if we have one path, that's okay + if ( i_rPaths.getLength() == 1 ) + return; + + // if we have multiple paths, they must start with the same page id + const sal_Int16 nFirstPageId = i_rPaths[0][0]; + for ( sal_Int32 i = 0; i < i_rPaths.getLength(); ++i ) + { + if ( i_rPaths[i][0] != nFirstPageId ) + throw IllegalArgumentException( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "All paths must start with the same page id." ) ), + i_rContext, 2 ); + } + } + } + + //-------------------------------------------------------------------- + void SAL_CALL Wizard::initialize( const Sequence< Any >& i_Arguments ) throw (Exception, RuntimeException) + { + ::osl::MutexGuard aGuard( m_aMutex ); + if ( m_bInitialized ) + throw AlreadyInitializedException( ::rtl::OUString(), *this ); + + if ( i_Arguments.getLength() != 2 ) + throw IllegalArgumentException( ::rtl::OUString(), *this, -1 ); + + // the second argument must be a XWizardController, for each constructor + m_xController.set( i_Arguments[1], UNO_QUERY ); + if ( !m_xController.is() ) + throw IllegalArgumentException( ::rtl::OUString(), *this, 2 ); + + // the first arg is either a single path (short[]), or multiple paths (short[][]) + Sequence< sal_Int16 > aSinglePath; + i_Arguments[0] >>= aSinglePath; + Sequence< Sequence< sal_Int16 > > aMultiplePaths; + i_Arguments[0] >>= aMultiplePaths; + + if ( !aMultiplePaths.getLength() ) + { + aMultiplePaths.realloc(1); + aMultiplePaths[0] = aSinglePath; + } + lcl_checkPaths( aMultiplePaths, *this ); + // if we survived this, the paths are valid, and we're done here ... + m_aWizardSteps = aMultiplePaths; + + m_bInitialized = true; + } + + //-------------------------------------------------------------------- + Dialog* Wizard::createDialog( Window* i_pParent ) + { + WizardShell* pDialog( new WizardShell( i_pParent, this, m_xController, m_aWizardSteps ) ); + pDialog->SetSmartHelpId( SmartId( m_sHelpURL ) ); + pDialog->setTitleBase( m_sTitle ); + return pDialog; + } + + //-------------------------------------------------------------------- + void Wizard::destroyDialog() + { + if ( m_pDialog ) + m_sHelpURL = m_pDialog->GetSmartHelpId().GetStr(); + + Wizard_Base::destroyDialog(); + } + + //-------------------------------------------------------------------- + ::rtl::OUString SAL_CALL Wizard::getImplementationName_static() throw(RuntimeException) + { + return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.svtools.uno.Wizard" ) ); + } + + //-------------------------------------------------------------------- + Sequence< ::rtl::OUString > SAL_CALL Wizard::getSupportedServiceNames_static() throw(RuntimeException) + { + Sequence< ::rtl::OUString > aServices(1); + aServices[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.ui.dialogs.Wizard" ) ); + return aServices; + } + + //-------------------------------------------------------------------- + ::rtl::OUString SAL_CALL Wizard::getImplementationName() throw(RuntimeException) + { + return getImplementationName_static(); + } + + //-------------------------------------------------------------------- + Sequence< ::rtl::OUString > SAL_CALL Wizard::getSupportedServiceNames() throw(RuntimeException) + { + return getSupportedServiceNames_static(); + } + + //-------------------------------------------------------------------- + Reference< XPropertySetInfo > SAL_CALL Wizard::getPropertySetInfo() throw(RuntimeException) + { + return createPropertySetInfo( getInfoHelper() ); + } + + //-------------------------------------------------------------------- + ::cppu::IPropertyArrayHelper& SAL_CALL Wizard::getInfoHelper() + { + return *const_cast< Wizard* >( this )->getArrayHelper(); + } + + //-------------------------------------------------------------------- + ::cppu::IPropertyArrayHelper* Wizard::createArrayHelper( ) const + { + Sequence< Property > aProps; + describeProperties( aProps ); + return new ::cppu::OPropertyArrayHelper( aProps ); + } + + //------------------------------------------------------------------------------------------------------------------ + ::rtl::OUString SAL_CALL Wizard::getHelpURL() throw (RuntimeException) + { + ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( !m_pDialog ) + return m_sHelpURL; + + const SmartId aSmartId( m_pDialog->GetSmartHelpId() ); + return aSmartId.GetStr(); + } + + //------------------------------------------------------------------------------------------------------------------ + void SAL_CALL Wizard::setHelpURL( const ::rtl::OUString& i_HelpURL ) throw (RuntimeException) + { + ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( !m_pDialog ) + m_sHelpURL = i_HelpURL; + else + m_pDialog->SetSmartHelpId( SmartId( i_HelpURL ) ); + } + + //------------------------------------------------------------------------------------------------------------------ + Reference< XWindow > SAL_CALL Wizard::getDialogWindow() throw (RuntimeException) + { + ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); + ::osl::MutexGuard aGuard( m_aMutex ); + + ENSURE_OR_RETURN( m_pDialog, "Wizard::getDialogWindow: illegal call (execution did not start, yet)!", NULL ); + return Reference< XWindow >( m_pDialog->GetComponentInterface(), UNO_QUERY ); + } + + //------------------------------------------------------------------------------------------------------------------ + void SAL_CALL Wizard::enableButton( ::sal_Int16 i_WizardButton, ::sal_Bool i_Enable ) throw (RuntimeException) + { + ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); + ::osl::MutexGuard aGuard( m_aMutex ); + + WizardShell* pWizardImpl = dynamic_cast< WizardShell* >( m_pDialog ); + ENSURE_OR_RETURN_VOID( pWizardImpl, "Wizard::enableButtons: invalid dialog implementation!" ); + + pWizardImpl->enableButtons( lcl_convertWizardButtonToWZB( i_WizardButton ), i_Enable ); + } + + //------------------------------------------------------------------------------------------------------------------ + void SAL_CALL Wizard::setDefaultButton( ::sal_Int16 i_WizardButton ) throw (RuntimeException) + { + ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); + ::osl::MutexGuard aGuard( m_aMutex ); + + WizardShell* pWizardImpl = dynamic_cast< WizardShell* >( m_pDialog ); + ENSURE_OR_RETURN_VOID( pWizardImpl, "Wizard::setDefaultButton: invalid dialog implementation!" ); + + pWizardImpl->defaultButton( lcl_convertWizardButtonToWZB( i_WizardButton ) ); + } + + //------------------------------------------------------------------------------------------------------------------ + sal_Bool SAL_CALL Wizard::travelNext( ) throw (RuntimeException) + { + ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); + ::osl::MutexGuard aGuard( m_aMutex ); + + WizardShell* pWizardImpl = dynamic_cast< WizardShell* >( m_pDialog ); + ENSURE_OR_RETURN_FALSE( pWizardImpl, "Wizard::travelNext: invalid dialog implementation!" ); + + return pWizardImpl->travelNext(); + } + + //------------------------------------------------------------------------------------------------------------------ + sal_Bool SAL_CALL Wizard::travelPrevious( ) throw (RuntimeException) + { + ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); + ::osl::MutexGuard aGuard( m_aMutex ); + + WizardShell* pWizardImpl = dynamic_cast< WizardShell* >( m_pDialog ); + ENSURE_OR_RETURN_FALSE( pWizardImpl, "Wizard::travelPrevious: invalid dialog implementation!" ); + + return pWizardImpl->travelPrevious(); + } + + //------------------------------------------------------------------------------------------------------------------ + void SAL_CALL Wizard::enablePage( ::sal_Int16 i_PageID, ::sal_Bool i_Enable ) throw (NoSuchElementException, InvalidStateException, RuntimeException) + { + ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); + ::osl::MutexGuard aGuard( m_aMutex ); + + WizardShell* pWizardImpl = dynamic_cast< WizardShell* >( m_pDialog ); + ENSURE_OR_RETURN_VOID( pWizardImpl, "Wizard::enablePage: invalid dialog implementation!" ); + + if ( !pWizardImpl->knowsPage( i_PageID ) ) + throw NoSuchElementException( ::rtl::OUString(), *this ); + + if ( i_PageID == pWizardImpl->getCurrentPage() ) + throw InvalidStateException( ::rtl::OUString(), *this ); + + pWizardImpl->enablePage( i_PageID, i_Enable ); + } + + //------------------------------------------------------------------------------------------------------------------ + void SAL_CALL Wizard::updateTravelUI( ) throw (RuntimeException) + { + ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); + ::osl::MutexGuard aGuard( m_aMutex ); + + WizardShell* pWizardImpl = dynamic_cast< WizardShell* >( m_pDialog ); + ENSURE_OR_RETURN_VOID( pWizardImpl, "Wizard::updateTravelUI: invalid dialog implementation!" ); + + pWizardImpl->updateTravelUI(); + } + + //------------------------------------------------------------------------------------------------------------------ + ::sal_Bool SAL_CALL Wizard::advanceTo( ::sal_Int16 i_PageId ) throw (RuntimeException) + { + ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); + ::osl::MutexGuard aGuard( m_aMutex ); + + WizardShell* pWizardImpl = dynamic_cast< WizardShell* >( m_pDialog ); + ENSURE_OR_RETURN_FALSE( pWizardImpl, "Wizard::advanceTo: invalid dialog implementation!" ); + + return pWizardImpl->advanceTo( i_PageId ); + } + + //------------------------------------------------------------------------------------------------------------------ + ::sal_Bool SAL_CALL Wizard::goBackTo( ::sal_Int16 i_PageId ) throw (RuntimeException) + { + ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); + ::osl::MutexGuard aGuard( m_aMutex ); + + WizardShell* pWizardImpl = dynamic_cast< WizardShell* >( m_pDialog ); + ENSURE_OR_RETURN_FALSE( pWizardImpl, "Wizard::goBackTo: invalid dialog implementation!" ); + + return pWizardImpl->goBackTo( i_PageId ); + } + + //------------------------------------------------------------------------------------------------------------------ + Reference< XWizardPage > SAL_CALL Wizard::getCurrentPage( ) throw (RuntimeException) + { + ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); + ::osl::MutexGuard aGuard( m_aMutex ); + + WizardShell* pWizardImpl = dynamic_cast< WizardShell* >( m_pDialog ); + ENSURE_OR_RETURN( pWizardImpl, "Wizard::getCurrentPage: invalid dialog implementation!", Reference< XWizardPage >() ); + + return pWizardImpl->getCurrentWizardPage(); + } + + //------------------------------------------------------------------------------------------------------------------ + void SAL_CALL Wizard::activatePath( ::sal_Int16 i_PathIndex, ::sal_Bool i_Final ) throw (NoSuchElementException, InvalidStateException, RuntimeException) + { + ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( ( i_PathIndex < 0 ) || ( i_PathIndex >= m_aWizardSteps.getLength() ) ) + throw NoSuchElementException( ::rtl::OUString(), *this ); + + WizardShell* pWizardImpl = dynamic_cast< WizardShell* >( m_pDialog ); + ENSURE_OR_RETURN_VOID( pWizardImpl, "Wizard::activatePath: invalid dialog implementation!" ); + + pWizardImpl->activatePath( i_PathIndex, i_Final ); + } + + //------------------------------------------------------------------------------------------------------------------ + void SAL_CALL Wizard::setTitle( const ::rtl::OUString& i_Title ) throw (RuntimeException) + { + // simply disambiguate + Wizard_Base::OGenericUnoDialog::setTitle( i_Title ); + } + + //------------------------------------------------------------------------------------------------------------------ + ::sal_Int16 SAL_CALL Wizard::execute( ) throw (RuntimeException) + { + return Wizard_Base::OGenericUnoDialog::execute(); + } + +//...................................................................................................................... +} } // namespace svt::uno +//...................................................................................................................... diff --git a/svtools/source/uno/wizard/wizardpagecontroller.cxx b/svtools/source/uno/wizard/wizardpagecontroller.cxx new file mode 100644 index 000000000000..d6f7029b477c --- /dev/null +++ b/svtools/source/uno/wizard/wizardpagecontroller.cxx @@ -0,0 +1,190 @@ +/************************************************************************* + * 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 "precompiled_svtools.hxx" + +#include "wizardpagecontroller.hxx" +#include "wizardshell.hxx" + +/** === begin UNO includes === **/ +#include <com/sun/star/lang/XComponent.hpp> +#include <com/sun/star/awt/XControl.hpp> +/** === end UNO includes === **/ + +#include <toolkit/helper/vclunohelper.hxx> +#include <tools/diagnose_ex.h> + +//...................................................................................................................... +namespace svt { namespace uno +{ +//...................................................................................................................... + + /** === begin UNO using === **/ + using ::com::sun::star::uno::Reference; + using ::com::sun::star::uno::XInterface; + using ::com::sun::star::uno::UNO_QUERY; + using ::com::sun::star::uno::UNO_QUERY_THROW; + using ::com::sun::star::uno::UNO_SET_THROW; + using ::com::sun::star::uno::Exception; + using ::com::sun::star::uno::RuntimeException; + using ::com::sun::star::uno::Any; + using ::com::sun::star::uno::makeAny; + using ::com::sun::star::uno::Sequence; + using ::com::sun::star::uno::Type; + using ::com::sun::star::ui::dialogs::XWizardController; + using ::com::sun::star::awt::XWindow; + using ::com::sun::star::lang::XComponent; + using ::com::sun::star::awt::XControl; + /** === end UNO using === **/ + using namespace ::com::sun::star; + + //================================================================================================================== + //= WizardPageController + //================================================================================================================== + //------------------------------------------------------------------------------------------------------------------ + WizardPageController::WizardPageController( WizardShell& i_rParent, const Reference< XWizardController >& i_rController, + const sal_Int16 i_nPageId ) + :m_xController( i_rController ) + ,m_xWizardPage() + ,m_nPageId( i_nPageId ) + { + ENSURE_OR_THROW( m_xController.is(), "no controller" ); + try + { + m_xWizardPage.set( m_xController->createPage( + Reference< XWindow >( i_rParent.GetComponentInterface( TRUE ), UNO_QUERY_THROW ), + m_nPageId + ), UNO_SET_THROW ); + + Reference< XWindow > xPageWindow( m_xWizardPage->getWindow(), UNO_SET_THROW ); + xPageWindow->setVisible( sal_True ); + + TabPage* pTabPage( getTabPage() ); + if ( pTabPage ) + pTabPage->SetStyle( pTabPage->GetStyle() | WB_CHILDDLGCTRL | WB_DIALOGCONTROL ); + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + } + + //------------------------------------------------------------------------------------------------------------------ + WizardPageController::~WizardPageController() + { + try + { + if ( m_xWizardPage.is() ) + m_xWizardPage->dispose(); + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + } + + //------------------------------------------------------------------------------------------------------------------ + TabPage* WizardPageController::getTabPage() const + { + ENSURE_OR_RETURN( m_xWizardPage.is(), "WizardPageController::getTabPage: no external wizard page!", NULL ); + try + { + Reference< XWindow > xPageWindow( m_xWizardPage->getWindow(), UNO_SET_THROW ); + Window* pPageWindow = VCLUnoHelper::GetWindow( xPageWindow ); + if ( pPageWindow == NULL ) + { + // windows created via the XContainerWindowProvider might be controls, not real windows, so resolve + // that one indirection + const Reference< XControl > xPageControl( m_xWizardPage->getWindow(), UNO_QUERY_THROW ); + xPageWindow.set( xPageControl->getPeer(), UNO_QUERY_THROW ); + pPageWindow = VCLUnoHelper::GetWindow( xPageWindow ); + } + + OSL_ENSURE( pPageWindow != NULL, "WizardPageController::getTabPage: unable to find the Window implementation for the page's window!" ); + return dynamic_cast< TabPage* >( pPageWindow ); + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + return NULL; + } + + //------------------------------------------------------------------------------------------------------------------ + void WizardPageController::initializePage() + { + if ( !m_xWizardPage.is() ) + return; + + try + { + m_xWizardPage->activatePage(); + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + } + + //------------------------------------------------------------------------------------------------------------------ + sal_Bool WizardPageController::commitPage( WizardTypes::CommitPageReason i_eReason ) + { + if ( !m_xWizardPage.is() ) + return sal_True; + + try + { + return m_xWizardPage->commitPage( WizardShell::convertCommitReasonToTravelType( i_eReason ) ); + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + + return sal_True; + } + + //------------------------------------------------------------------------------------------------------------------ + bool WizardPageController::canAdvance() const + { + if ( !m_xWizardPage.is() ) + return true; + + try + { + return m_xWizardPage->canAdvance(); + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + + return true; + } + +//...................................................................................................................... +} } // namespace svt::uno +//...................................................................................................................... diff --git a/svtools/source/uno/wizard/wizardpagecontroller.hxx b/svtools/source/uno/wizard/wizardpagecontroller.hxx new file mode 100644 index 000000000000..9de04d2f0dd4 --- /dev/null +++ b/svtools/source/uno/wizard/wizardpagecontroller.hxx @@ -0,0 +1,75 @@ +/************************************************************************* + * 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. + * + ************************************************************************/ + +#ifndef SVT_UNOWIZ_WIZARDPAGECONTROLLER_HXX +#define SVT_UNOWIZ_WIZARDPAGECONTROLLER_HXX + +#include "svtools/wizardmachine.hxx" + +/** === begin UNO includes === **/ +#include <com/sun/star/ui/dialogs/XWizardController.hpp> +/** === end UNO includes === **/ + +//...................................................................................................................... +namespace svt { namespace uno +{ +//...................................................................................................................... + + class WizardShell; + + //================================================================================================================== + //= WizardPageController + //================================================================================================================== + class WizardPageController : public IWizardPageController + { + public: + WizardPageController( + WizardShell& i_rParent, + const ::com::sun::star::uno::Reference< ::com::sun::star::ui::dialogs::XWizardController >& i_rController, + const sal_Int16 i_nPageId + ); + ~WizardPageController(); + + // IWizardPageController overridables + virtual void initializePage(); + virtual sal_Bool commitPage( WizardTypes::CommitPageReason _eReason ); + virtual bool canAdvance() const; + + const ::com::sun::star::uno::Reference< ::com::sun::star::ui::dialogs::XWizardPage >& + getWizardPage() const { return m_xWizardPage; } + TabPage* getTabPage() const; + + private: + const ::com::sun::star::uno::Reference< ::com::sun::star::ui::dialogs::XWizardController > m_xController; + ::com::sun::star::uno::Reference< ::com::sun::star::ui::dialogs::XWizardPage > m_xWizardPage; + const sal_Int16 m_nPageId; + }; + +//...................................................................................................................... +} } // namespace svt::uno +//...................................................................................................................... + +#endif // SVT_UNOWIZ_WIZARDPAGECONTROLLER_HXX diff --git a/svtools/source/uno/wizard/wizardshell.cxx b/svtools/source/uno/wizard/wizardshell.cxx new file mode 100644 index 000000000000..7737b214ac1f --- /dev/null +++ b/svtools/source/uno/wizard/wizardshell.cxx @@ -0,0 +1,279 @@ +/************************************************************************* + * 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 "precompiled_svtools.hxx" + +#include "wizardshell.hxx" +#include "wizardpagecontroller.hxx" + +#include <tools/diagnose_ex.h> + +/** === begin UNO includes === **/ +#include <com/sun/star/ui/dialogs/WizardTravelType.hpp> +/** === end UNO includes === **/ + +#include <vcl/msgbox.hxx> + +//...................................................................................................................... +namespace svt { namespace uno +{ +//...................................................................................................................... + + /** === begin UNO using === **/ + using ::com::sun::star::uno::Reference; + using ::com::sun::star::uno::XInterface; + using ::com::sun::star::uno::UNO_QUERY; + using ::com::sun::star::uno::UNO_QUERY_THROW; + using ::com::sun::star::uno::UNO_SET_THROW; + using ::com::sun::star::uno::Exception; + using ::com::sun::star::uno::RuntimeException; + using ::com::sun::star::uno::Any; + using ::com::sun::star::uno::makeAny; + using ::com::sun::star::uno::Sequence; + using ::com::sun::star::uno::Type; + using ::com::sun::star::ui::dialogs::XWizardController; + using ::com::sun::star::ui::dialogs::XWizard; + using ::com::sun::star::ui::dialogs::XWizardPage; + /** === end UNO using === **/ + namespace WizardTravelType = ::com::sun::star::ui::dialogs::WizardTravelType; + + //================================================================================================================== + namespace + { + //-------------------------------------------------------------------------------------------------------------- + sal_Int16 lcl_determineFirstPageID( const Sequence< Sequence< sal_Int16 > >& i_rPaths ) + { + ENSURE_OR_THROW( ( i_rPaths.getLength() > 0 ) && ( i_rPaths[0].getLength() > 0 ), "illegal paths" ); + return i_rPaths[0][0]; + } + } + + //================================================================================================================== + //= WizardShell + //================================================================================================================== + //------------------------------------------------------------------------------------------------------------------ + WizardShell::WizardShell( Window* i_pParent, const Reference< XWizard >& i_rWizard, const Reference< XWizardController >& i_rController, + const Sequence< Sequence< sal_Int16 > >& i_rPaths ) + :WizardShell_Base( i_pParent, WB_MOVEABLE | WB_CLOSEABLE ) + ,m_xWizard( i_rWizard ) + ,m_xController( i_rController ) + ,m_nFirstPageID( lcl_determineFirstPageID( i_rPaths ) ) + { + ENSURE_OR_THROW( m_xWizard.is() && m_xController.is(), "invalid wizard/controller" ); + + // declare the paths + for ( sal_Int32 i=0; i<i_rPaths.getLength(); ++i ) + { + const Sequence< sal_Int16 >& rPath( i_rPaths[i] ); + WizardPath aPath( rPath.getLength() ); + for ( sal_Int32 j=0; j<rPath.getLength(); ++j ) + aPath[j] = impl_pageIdToState( rPath[j] ); + declarePath( i, aPath ); + } + + // create the first page, to know the page size + TabPage* pStartPage = GetOrCreatePage( impl_pageIdToState( i_rPaths[0][0] ) ); + SetPageSizePixel( pStartPage->GetSizePixel() ); + + // some defaults + ShowButtonFixedLine( true ); + SetRoadmapInteractive( true ); + enableAutomaticNextButtonState(); + } + + //------------------------------------------------------------------------------------------------------------------ + WizardShell::~WizardShell() + { + } + + //------------------------------------------------------------------------------------------------------------------ + short WizardShell::Execute() + { + ActivatePage(); + return WizardShell_Base::Execute(); + } + + //------------------------------------------------------------------------------------------------------------------ + sal_Int16 WizardShell::convertCommitReasonToTravelType( const CommitPageReason i_eReason ) + { + switch ( i_eReason ) + { + case WizardTypes::eTravelForward: + return WizardTravelType::FORWARD; + + case WizardTypes::eTravelBackward: + return WizardTravelType::BACKWARD; + + case WizardTypes::eFinish: + return WizardTravelType::FINISH; + + default: + break; + } + OSL_ENSURE( false, "WizardShell::convertCommitReasonToTravelType: unsupported CommitPageReason!" ); + return WizardTravelType::FINISH; + } + + //------------------------------------------------------------------------------------------------------------------ + void WizardShell::enterState( WizardState i_nState ) + { + WizardShell_Base::enterState( i_nState ); + + if ( !m_xController.is() ) + return; + + try + { + m_xController->onActivatePage( impl_stateToPageId( i_nState ) ); + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + } + + //------------------------------------------------------------------------------------------------------------------ + sal_Bool WizardShell::leaveState( WizardState i_nState ) + { + if ( !WizardShell_Base::leaveState( i_nState ) ) + return sal_False; + + if ( !m_xController.is() ) + return sal_True; + + try + { + m_xController->onDeactivatePage( impl_stateToPageId( i_nState ) ); + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + + return sal_True; + } + + //------------------------------------------------------------------------------------------------------------------ + PWizardPageController WizardShell::impl_getController( TabPage* i_pPage ) const + { + Page2ControllerMap::const_iterator pos = m_aPageControllers.find( i_pPage ); + ENSURE_OR_RETURN( pos != m_aPageControllers.end(), "WizardShell::impl_getController: no controller for this page!", PWizardPageController() ); + return pos->second; + } + + //------------------------------------------------------------------------------------------------------------------ + Reference< XWizardPage > WizardShell::getCurrentWizardPage() const + { + const WizardState eState = getCurrentState(); + + PWizardPageController pController( impl_getController( GetPage( eState ) ) ); + ENSURE_OR_RETURN( pController, "WizardShell::getCurrentWizardPage: invalid page/controller!", NULL ); + + return pController->getWizardPage(); + } + + //------------------------------------------------------------------------------------------------------------------ + void WizardShell::enablePage( const sal_Int16 i_nPageID, const sal_Bool i_bEnable ) + { + enableState( impl_pageIdToState( i_nPageID ), i_bEnable ); + } + + //------------------------------------------------------------------------------------------------------------------ + TabPage* WizardShell::createPage( WizardState i_nState ) + { + ENSURE_OR_RETURN( m_xController.is(), "WizardShell::createPage: no WizardController!", NULL ); + + ::boost::shared_ptr< WizardPageController > pController( new WizardPageController( *this, m_xController, impl_stateToPageId( i_nState ) ) ); + TabPage* pPage = pController->getTabPage(); + OSL_ENSURE( pPage != NULL, "WizardShell::createPage: illegal tab page!" ); + if ( pPage == NULL ) + { + // fallback for ill-behaved clients: empty page + pPage = new TabPage( this, 0 ); + pPage->SetSizePixel( LogicToPixel( Size( 280, 185 ), MAP_APPFONT ) ); + } + + m_aPageControllers[ pPage ] = pController; + return pPage; + } + + //------------------------------------------------------------------------------------------------------------------ + IWizardPageController* WizardShell::getPageController( TabPage* i_pCurrentPage ) const + { + return impl_getController( i_pCurrentPage ).get(); + } + + //------------------------------------------------------------------------------------------------------------------ + String WizardShell::getStateDisplayName( WizardState i_nState ) const + { + try + { + if ( m_xController.is() ) + return m_xController->getPageTitle( impl_stateToPageId( i_nState ) ); + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + // fallback for ill-behaved clients: the numeric state + return String::CreateFromInt32( i_nState ); + } + + //------------------------------------------------------------------------------------------------------------------ + bool WizardShell::canAdvance() const + { + try + { + if ( m_xController.is() && !m_xController->canAdvance() ) + return false; + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + + return WizardShell_Base::canAdvance(); + } + + //------------------------------------------------------------------------------------------------------------------ + sal_Bool WizardShell::onFinish() + { + try + { + if ( m_xController.is() && !m_xController->confirmFinish() ) + return sal_False; + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + + return WizardShell_Base::onFinish(); + } + +//...................................................................................................................... +} } // namespace svt::uno +//...................................................................................................................... diff --git a/svtools/source/uno/wizard/wizardshell.hxx b/svtools/source/uno/wizard/wizardshell.hxx new file mode 100644 index 000000000000..338b4f38dc4a --- /dev/null +++ b/svtools/source/uno/wizard/wizardshell.hxx @@ -0,0 +1,147 @@ +/************************************************************************* + * 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. + * + ************************************************************************/ + +#ifndef SVT_UNO_WIZARD_SHELL +#define SVT_UNO_WIZARD_SHELL + +/** === begin UNO includes === **/ +#include <com/sun/star/ui/dialogs/XWizardController.hpp> +#include <com/sun/star/ui/dialogs/XWizard.hpp> +/** === end UNO includes === **/ + +#include <svtools/roadmapwizard.hxx> + +#include <boost/shared_ptr.hpp> +#include <map> + +//...................................................................................................................... +namespace svt { namespace uno +{ +//...................................................................................................................... + + class WizardPageController; + typedef ::boost::shared_ptr< WizardPageController > PWizardPageController; + + //================================================================================================================== + //= WizardShell + //================================================================================================================== + typedef ::svt::RoadmapWizard WizardShell_Base; + class WizardShell : public WizardShell_Base + { + public: + WizardShell( + Window* _pParent, + const ::com::sun::star::uno::Reference< ::com::sun::star::ui::dialogs::XWizard >& i_rWizard, + const ::com::sun::star::uno::Reference< ::com::sun::star::ui::dialogs::XWizardController >& i_rController, + const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< sal_Int16 > >& i_rPaths + ); + virtual ~WizardShell(); + + // Dialog overridables + virtual short Execute(); + + // OWizardMachine overridables + virtual TabPage* createPage( WizardState i_nState ); + virtual void enterState( WizardState i_nState ); + virtual sal_Bool leaveState( WizardState i_nState ); + virtual String getStateDisplayName( WizardState i_nState ) const; + virtual bool canAdvance() const; + virtual sal_Bool onFinish(); + virtual IWizardPageController* + getPageController( TabPage* _pCurrentPage ) const; + + // attribute access + const ::com::sun::star::uno::Reference< ::com::sun::star::ui::dialogs::XWizard >& + getWizard() const { return m_xWizard; } + + static sal_Int16 convertCommitReasonToTravelType( const CommitPageReason i_eReason ); + + // operations + sal_Bool advanceTo( const sal_Int16 i_nPageId ) + { + return skipUntil( impl_pageIdToState( i_nPageId ) ); + } + sal_Bool goBackTo( const sal_Int16 i_nPageId ) + { + return skipBackwardUntil( impl_pageIdToState( i_nPageId ) ); + } + sal_Bool travelNext() { return WizardShell_Base::travelNext(); } + sal_Bool travelPrevious() { return WizardShell_Base::travelPrevious(); } + + void activatePath( const sal_Int16 i_nPathID, const sal_Bool i_bFinal ) + { + WizardShell_Base::activatePath( PathId( i_nPathID ), i_bFinal ); + } + + ::com::sun::star::uno::Reference< ::com::sun::star::ui::dialogs::XWizardPage > + getCurrentWizardPage() const; + + sal_Int16 getCurrentPage() const + { + return impl_stateToPageId( getCurrentState() ); + } + + void enablePage( const sal_Int16 i_PageID, const sal_Bool i_Enable ); + + bool knowsPage( const sal_Int16 i_nPageID ) const + { + return knowsState( impl_pageIdToState( i_nPageID ) ); + } + + private: + sal_Int16 impl_stateToPageId( const WizardTypes::WizardState i_nState ) const + { + return static_cast< sal_Int16 >( i_nState + m_nFirstPageID ); + } + + WizardState impl_pageIdToState( const sal_Int16 i_nPageId ) const + { + return static_cast< WizardState >( i_nPageId - m_nFirstPageID ); + } + + PWizardPageController impl_getController( TabPage* i_pPage ) const; + + // prevent outside access to some base class members + using WizardShell_Base::skip; + using WizardShell_Base::skipUntil; + using WizardShell_Base::skipBackwardUntil; + using WizardShell_Base::getCurrentState; + using WizardShell_Base::activatePath; + + private: + typedef ::std::map< TabPage*, PWizardPageController > Page2ControllerMap; + + const ::com::sun::star::uno::Reference< ::com::sun::star::ui::dialogs::XWizard > m_xWizard; + const ::com::sun::star::uno::Reference< ::com::sun::star::ui::dialogs::XWizardController > m_xController; + const sal_Int16 m_nFirstPageID; + Page2ControllerMap m_aPageControllers; + }; + +//...................................................................................................................... +} } // namespace svt::uno +//...................................................................................................................... + +#endif // SVT_UNO_WIZARD_SHELL |