diff options
Diffstat (limited to 'dbaccess/source/core/dataaccess/intercept.cxx')
-rw-r--r-- | dbaccess/source/core/dataaccess/intercept.cxx | 447 |
1 files changed, 447 insertions, 0 deletions
diff --git a/dbaccess/source/core/dataaccess/intercept.cxx b/dbaccess/source/core/dataaccess/intercept.cxx new file mode 100644 index 000000000000..8a24bbcdf4a3 --- /dev/null +++ b/dbaccess/source/core/dataaccess/intercept.cxx @@ -0,0 +1,447 @@ +/************************************************************************* + * + * 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_dbaccess.hxx" + +#include "intercept.hxx" +#include "dbastrings.hrc" + +#include <com/sun/star/embed/EmbedStates.hpp> +#include <com/sun/star/document/XEventBroadcaster.hpp> +#include <com/sun/star/util/XModifiable.hpp> +#include <cppuhelper/weak.hxx> + +#include <comphelper/types.hxx> +#include <tools/debug.hxx> +#include <tools/diagnose_ex.h> + + +namespace dbaccess +{ +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::util; +using namespace ::com::sun::star::ucb; +using namespace ::com::sun::star::beans; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::sdbc; +using namespace ::com::sun::star::frame; +using namespace ::com::sun::star::io; +using namespace ::com::sun::star::embed; +using namespace ::com::sun::star::container; +using namespace ::comphelper; +using namespace ::cppu; + +#define DISPATCH_SAVEAS 0 +#define DISPATCH_SAVE 1 +#define DISPATCH_CLOSEDOC 2 +#define DISPATCH_CLOSEWIN 3 +#define DISPATCH_CLOSEFRAME 4 +#define DISPATCH_RELOAD 5 +// the OSL_ENSURE in CTOR has to be changed too, when adding new defines + +void SAL_CALL OInterceptor::dispose() + throw( RuntimeException ) +{ + EventObject aEvt( *this ); + + osl::MutexGuard aGuard(m_aMutex); + + if ( m_pDisposeEventListeners && m_pDisposeEventListeners->getLength() ) + m_pDisposeEventListeners->disposeAndClear( aEvt ); + + if ( m_pStatCL ) + m_pStatCL->disposeAndClear( aEvt ); + + m_xSlaveDispatchProvider.clear(); + m_xMasterDispatchProvider.clear(); + + m_pContentHolder = NULL; +} + + +DBG_NAME(OInterceptor) + +OInterceptor::OInterceptor( ODocumentDefinition* _pContentHolder,sal_Bool _bAllowEditDoc ) + :m_pContentHolder( _pContentHolder ) + ,m_aInterceptedURL(7) + ,m_pDisposeEventListeners(0) + ,m_pStatCL(0) + ,m_bAllowEditDoc(_bAllowEditDoc) +{ + DBG_CTOR(OInterceptor,NULL); + + OSL_ENSURE(DISPATCH_RELOAD < m_aInterceptedURL.getLength(),"Illegal size."); + + m_aInterceptedURL[DISPATCH_SAVEAS] = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(".uno:SaveAs")); + m_aInterceptedURL[DISPATCH_SAVE] = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(".uno:Save")); + m_aInterceptedURL[DISPATCH_CLOSEDOC] = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(".uno:CloseDoc")); + m_aInterceptedURL[DISPATCH_CLOSEWIN] = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(".uno:CloseWin")); + m_aInterceptedURL[DISPATCH_CLOSEFRAME] = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(".uno:CloseFrame")); + m_aInterceptedURL[DISPATCH_RELOAD] = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(".uno:Reload")); +} + + +OInterceptor::~OInterceptor() +{ + if( m_pDisposeEventListeners ) + delete m_pDisposeEventListeners; + + if(m_pStatCL) + delete m_pStatCL; + + DBG_DTOR(OInterceptor,NULL); +} + +struct DispatchHelper +{ + URL aURL; + Sequence<PropertyValue > aArguments; +}; + +//XDispatch +void SAL_CALL OInterceptor::dispatch( const URL& _URL,const Sequence<PropertyValue >& Arguments ) throw (RuntimeException) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + if ( !m_pContentHolder ) + return; + + if ( _URL.Complete == m_aInterceptedURL[ DISPATCH_SAVE ] ) + { + m_pContentHolder->save( sal_False ); + return; + } + + if ( _URL.Complete == m_aInterceptedURL[ DISPATCH_RELOAD ] ) + { + ODocumentDefinition::fillReportData( + m_pContentHolder->getContext(), + m_pContentHolder->getComponent(), + m_pContentHolder->getConnection() + ); + return; + } + + if( _URL.Complete == m_aInterceptedURL[ DISPATCH_SAVEAS ] ) + { + if ( m_pContentHolder->isNewReport() ) + { + m_pContentHolder->saveAs(); + } + else if ( m_xSlaveDispatchProvider.is() ) + { + Sequence< PropertyValue > aNewArgs = Arguments; + sal_Int32 nInd = 0; + + while( nInd < aNewArgs.getLength() ) + { + if ( aNewArgs[nInd].Name.equalsAscii( "SaveTo" ) ) + { + aNewArgs[nInd].Value <<= sal_True; + break; + } + nInd++; + } + + if ( nInd == aNewArgs.getLength() ) + { + aNewArgs.realloc( nInd + 1 ); + aNewArgs[nInd].Name = ::rtl::OUString::createFromAscii( "SaveTo" ); + aNewArgs[nInd].Value <<= sal_True; + } + + Reference< XDispatch > xDispatch = m_xSlaveDispatchProvider->queryDispatch( + _URL, ::rtl::OUString::createFromAscii( "_self" ), 0 ); + if ( xDispatch.is() ) + xDispatch->dispatch( _URL, aNewArgs ); + } + return; + } + + if ( _URL.Complete == m_aInterceptedURL[ DISPATCH_CLOSEDOC ] + || _URL.Complete == m_aInterceptedURL[ DISPATCH_CLOSEWIN ] + || _URL.Complete == m_aInterceptedURL[ DISPATCH_CLOSEFRAME ] + ) + { + DispatchHelper* pHelper = new DispatchHelper; + pHelper->aArguments = Arguments; + pHelper->aURL = _URL; + Application::PostUserEvent( LINK( this, OInterceptor, OnDispatch ), reinterpret_cast< void* >( pHelper ) ); + return; + } +} + +IMPL_LINK( OInterceptor, OnDispatch, void*, _pDispatcher ) +{ + ::std::auto_ptr<DispatchHelper> pHelper( reinterpret_cast< DispatchHelper* >( _pDispatcher ) ); + try + { + if ( m_pContentHolder && m_pContentHolder->prepareClose() && m_xSlaveDispatchProvider.is() ) + { + Reference< XDispatch > xDispatch = m_xSlaveDispatchProvider->queryDispatch( + pHelper->aURL, ::rtl::OUString::createFromAscii( "_self" ), 0 ); + if ( xDispatch.is() ) + { + Reference< ::com::sun::star::document::XEventBroadcaster> xEvtB(m_pContentHolder->getComponent(),UNO_QUERY); + if ( xEvtB.is() ) + xEvtB->removeEventListener(this); + + Reference< XInterface > xKeepContentHolderAlive( *m_pContentHolder ); + xDispatch->dispatch( pHelper->aURL,pHelper->aArguments); + } + } + } + catch ( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + + return 0L; +} + +void SAL_CALL OInterceptor::addStatusListener( + const Reference< + XStatusListener >& Control, + const URL& _URL ) + throw ( + RuntimeException + ) +{ + if(!Control.is()) + return; + + if ( m_pContentHolder && _URL.Complete == m_aInterceptedURL[DISPATCH_SAVEAS] ) + { // SaveAs + + if ( !m_pContentHolder->isNewReport() ) + { + FeatureStateEvent aStateEvent; + aStateEvent.FeatureURL.Complete = m_aInterceptedURL[DISPATCH_SAVEAS]; + aStateEvent.FeatureDescriptor = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SaveCopyTo")); + aStateEvent.IsEnabled = sal_True; + aStateEvent.Requery = sal_False; + aStateEvent.State <<= (rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("($3)"))); + Control->statusChanged(aStateEvent); + } + + { + osl::MutexGuard aGuard(m_aMutex); + if(!m_pStatCL) + m_pStatCL = new PropertyChangeListenerContainer(m_aMutex); + } + + m_pStatCL->addInterface(_URL.Complete,Control); + } + else if ( m_pContentHolder && _URL.Complete == m_aInterceptedURL[DISPATCH_SAVE] ) + { // Save + FeatureStateEvent aStateEvent; + aStateEvent.FeatureURL.Complete = m_aInterceptedURL[DISPATCH_SAVE]; + aStateEvent.FeatureDescriptor = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Update")); + aStateEvent.IsEnabled = m_pContentHolder != NULL && m_pContentHolder->isModified(); + aStateEvent.Requery = sal_False; + + Control->statusChanged(aStateEvent); + { + osl::MutexGuard aGuard(m_aMutex); + if(!m_pStatCL) + m_pStatCL = new PropertyChangeListenerContainer(m_aMutex); + } + + m_pStatCL->addInterface(_URL.Complete,Control); + Reference< ::com::sun::star::document::XEventBroadcaster> xEvtB(m_pContentHolder->getComponent(),UNO_QUERY); + if ( xEvtB.is() ) + xEvtB->addEventListener(this); + } + else + { + sal_Int32 i = 2; + if(_URL.Complete == m_aInterceptedURL[i] || + _URL.Complete == m_aInterceptedURL[++i] || + _URL.Complete == m_aInterceptedURL[++i] || + _URL.Complete == m_aInterceptedURL[i = DISPATCH_RELOAD] ) + { // Close and return + FeatureStateEvent aStateEvent; + aStateEvent.FeatureURL.Complete = m_aInterceptedURL[i]; + aStateEvent.FeatureDescriptor = rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM("Close and Return")); + aStateEvent.IsEnabled = sal_True; + aStateEvent.Requery = sal_False; + Control->statusChanged(aStateEvent); + + + { + osl::MutexGuard aGuard(m_aMutex); + if(!m_pStatCL) + m_pStatCL = new PropertyChangeListenerContainer(m_aMutex); + } + + m_pStatCL->addInterface(_URL.Complete,Control); + return; + } + } +} + + +void SAL_CALL OInterceptor::removeStatusListener( + const Reference< + XStatusListener >& Control, + const URL& _URL ) + throw ( + RuntimeException + ) +{ + if(!(Control.is() && m_pStatCL)) + return; + else + { + m_pStatCL->removeInterface(_URL.Complete,Control); + return; + } +} + + +//XInterceptorInfo +Sequence< ::rtl::OUString > SAL_CALL OInterceptor::getInterceptedURLs( ) throw ( RuntimeException ) +{ + // now implemented as update + return m_aInterceptedURL; +} + + +// XDispatchProvider + +Reference< XDispatch > SAL_CALL OInterceptor::queryDispatch( const URL& _URL,const ::rtl::OUString& TargetFrameName,sal_Int32 SearchFlags ) + throw (RuntimeException) +{ + osl::MutexGuard aGuard(m_aMutex); + const ::rtl::OUString* pIter = m_aInterceptedURL.getConstArray(); + const ::rtl::OUString* pEnd = pIter + m_aInterceptedURL.getLength(); + for(;pIter != pEnd;++pIter) + { + if ( _URL.Complete == *pIter ) + return (XDispatch*)this; + } + + if(m_xSlaveDispatchProvider.is()) + return m_xSlaveDispatchProvider->queryDispatch(_URL,TargetFrameName,SearchFlags); + else + return Reference<XDispatch>(); +} + +Sequence< Reference< XDispatch > > SAL_CALL OInterceptor::queryDispatches( const Sequence<DispatchDescriptor >& Requests ) throw ( RuntimeException ) +{ + Sequence< Reference< XDispatch > > aRet; + osl::MutexGuard aGuard(m_aMutex); + if(m_xSlaveDispatchProvider.is()) + aRet = m_xSlaveDispatchProvider->queryDispatches(Requests); + else + aRet.realloc(Requests.getLength()); + + for(sal_Int32 i = 0; i < Requests.getLength(); ++i) + { + const ::rtl::OUString* pIter = m_aInterceptedURL.getConstArray(); + const ::rtl::OUString* pEnd = pIter + m_aInterceptedURL.getLength(); + for(;pIter != pEnd;++pIter) + { + if ( Requests[i].FeatureURL.Complete == *pIter ) + { + aRet[i] = (XDispatch*) this; + break; + } + } + } + + return aRet; +} + + + +//XDispatchProviderInterceptor + +Reference< XDispatchProvider > SAL_CALL OInterceptor::getSlaveDispatchProvider( ) throw ( RuntimeException ) +{ + osl::MutexGuard aGuard(m_aMutex); + return m_xSlaveDispatchProvider; +} + +void SAL_CALL +OInterceptor::setSlaveDispatchProvider( const Reference< XDispatchProvider >& NewDispatchProvider ) + throw ( RuntimeException ) +{ + osl::MutexGuard aGuard(m_aMutex); + m_xSlaveDispatchProvider = NewDispatchProvider; +} + + +Reference< XDispatchProvider > SAL_CALL OInterceptor::getMasterDispatchProvider( ) + throw ( + RuntimeException + ) +{ + osl::MutexGuard aGuard(m_aMutex); + return m_xMasterDispatchProvider; +} + + +void SAL_CALL OInterceptor::setMasterDispatchProvider( + const Reference< XDispatchProvider >& NewSupplier ) + throw ( + RuntimeException + ) +{ + osl::MutexGuard aGuard(m_aMutex); + m_xMasterDispatchProvider = NewSupplier; +} +// ----------------------------------------------------------------------------- +void SAL_CALL OInterceptor::notifyEvent( const ::com::sun::star::document::EventObject& Event ) throw (::com::sun::star::uno::RuntimeException) +{ + osl::ResettableMutexGuard _rGuard(m_aMutex); + if ( m_pStatCL && Event.EventName == ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("OnModifyChanged")) ) + { + OInterfaceContainerHelper* pListener = m_pStatCL->getContainer(m_aInterceptedURL[DISPATCH_SAVE]); + if ( pListener ) + { + FeatureStateEvent aEvt; + aEvt.FeatureURL.Complete = m_aInterceptedURL[DISPATCH_SAVE]; + aEvt.FeatureDescriptor = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Update")); + Reference<XModifiable> xModel(Event.Source,UNO_QUERY); + aEvt.IsEnabled = xModel.is() && xModel->isModified(); + aEvt.Requery = sal_False; + + NOTIFY_LISTERNERS((*pListener),XStatusListener,statusChanged) + } + } +} +// ----------------------------------------------------------------------------- +void SAL_CALL OInterceptor::disposing( const ::com::sun::star::lang::EventObject& /*Source*/ ) throw (::com::sun::star::uno::RuntimeException) +{ +} + +//........................................................................ +} // namespace dbaccess +//........................................................................ + |