diff options
author | Release Engineers <releng@openoffice.org> | 2008-12-01 12:31:27 +0000 |
---|---|---|
committer | Release Engineers <releng@openoffice.org> | 2008-12-01 12:31:27 +0000 |
commit | 2363c961947028ee152cbdfca7e4b4d1099ca019 (patch) | |
tree | d4e60312f0d4cca1098aa9ea181329711867e53e /dbaccess/source/ui/app/subcomponentmanager.cxx | |
parent | CWS-TOOLING: integrate CWS sqlsyntaxhighlighting (diff) | |
download | core-2363c961947028ee152cbdfca7e4b4d1099ca019.tar.gz core-2363c961947028ee152cbdfca7e4b4d1099ca019.zip |
CWS-TOOLING: integrate CWS dba31e
2008-11-19 12:36:23 +0100 msc r263980 : i96104
2008-11-19 12:31:19 +0100 msc r263979 : i96104
2008-11-19 12:21:55 +0100 msc r263977 : i96104
2008-11-19 12:18:53 +0100 msc r263976 : i96104
2008-11-18 09:09:45 +0100 oj r263746 : disable color entry when area is set
2008-11-18 08:37:52 +0100 oj r263741 : #remove sub report entry
2008-11-17 11:20:25 +0100 fs r263708 : #i10000#
2008-11-17 11:06:52 +0100 fs r263706 : minimal version now is 3.1
2008-11-12 22:25:59 +0100 fs r263621 : #i96150#
2008-11-12 22:20:02 +0100 fs r263620 : rebased to m34
2008-11-12 21:39:41 +0100 fs r263618 : MANUAL REBASE: rebase CWS dba31d to DEV300_m34
2008-11-12 13:54:58 +0100 fs r263597 : #i96134# MediaDescriptor.URL is to be preferred over MediaDescriptor.FileName. Nonetheless, ensure both are handled
2008-11-12 13:53:40 +0100 fs r263596 : #i96134# re-enabled the code for #i41897#, a better fix is to come
2008-11-12 12:48:21 +0100 fs r263585 : #i96134# disable saving URLs of file-base databases relatively
2008-11-11 16:11:11 +0100 msc r263566 : #i96104#
2008-11-05 09:09:47 +0100 oj r263342 : #i88727# color noe added
2008-11-05 08:41:43 +0100 oj r263341 : #i77916# zoom added
2008-11-04 21:24:15 +0100 fs r263339 : disposing: call disposeAndClear without own mutex locked - some of our listeners insist on locking the SolarMutex, which sometimes led to deadlocks on the complex test cases
2008-11-04 21:23:15 +0100 fs r263338 : remove SolarMutex locking - this happned in CWS dba31c (in the CVS version), which this CWS was created from, but seems to got lost during resync
2008-11-04 20:49:50 +0100 fs r263335 : docu formatting
2008-11-04 20:06:39 +0100 fs r263334 : #i95826# use m_aMutex, not a DocumentGuard (wrongly resolved merge conflicts)
2008-11-04 17:36:29 +0100 fs r263332 : #i92688# properly revoke as XEventListener from m_xActiveController when disposing
2008-11-04 14:49:34 +0100 fs r263324 : #i92322# enable Input Required if EmptyIsNULL does not exist at the control
2008-10-31 11:10:04 +0100 oj r262857 : merge from cvs to svn
2008-10-31 09:46:45 +0100 oj r262853 : merge from cvs to svn
2008-10-31 08:46:37 +0100 oj r262849 : merge from cvs to svn
2008-10-31 08:44:24 +0100 oj r262848 : merge from cvs to svn
2008-10-31 08:43:33 +0100 oj r262847 : merge from cvs to svn
2008-10-31 08:42:28 +0100 oj r262846 : merge from cvs to svn
2008-10-31 08:41:58 +0100 oj r262845 : merge from cvs to svn
2008-10-31 08:41:32 +0100 oj r262844 : merge from cvs to svn
2008-10-28 12:19:50 +0100 oj r262733 : #iXXXXX#: migrate CWS dba31e to SVN
2008-10-28 12:19:42 +0100 oj r262732 : #iXXXXX#: migrate CWS dba31e to SVN
2008-10-28 12:19:36 +0100 oj r262731 : #iXXXXX#: migrate CWS dba31e to SVN
2008-10-28 12:19:31 +0100 oj r262730 : #iXXXXX#: migrate CWS dba31e to SVN
2008-10-28 12:19:22 +0100 oj r262729 : #iXXXXX#: migrate CWS dba31e to SVN
2008-10-28 12:19:18 +0100 oj r262728 : #iXXXXX#: migrate CWS dba31e to SVN
2008-10-28 12:19:10 +0100 oj r262727 : #iXXXXX#: migrate CWS dba31e to SVN
2008-10-28 12:19:06 +0100 oj r262726 : #iXXXXX#: migrate CWS dba31e to SVN
2008-10-28 12:19:05 +0100 oj r262725 : #iXXXXX#: migrate CWS dba31e to SVN
2008-10-28 12:19:01 +0100 oj r262724 : #iXXXXX#: migrate CWS dba31e to SVN
2008-10-28 12:18:50 +0100 oj r262723 : #iXXXXX#: migrate CWS dba31e to SVN
2008-10-28 12:18:41 +0100 oj r262722 : #iXXXXX#: migrate CWS dba31e to SVN
2008-10-28 12:18:40 +0100 oj r262721 : #iXXXXX#: migrate CWS dba31e to SVN
2008-10-28 12:18:27 +0100 oj r262720 : #iXXXXX#: migrate CWS dba31e to SVN
2008-10-28 12:18:10 +0100 oj r262719 : #iXXXXX#: migrate CWS dba31e to SVN
2008-10-28 12:18:01 +0100 oj r262718 : #iXXXXX#: migrate CWS dba31e to SVN
2008-10-28 12:17:39 +0100 oj r262717 : #iXXXXX#: migrate CWS dba31e to SVN
Diffstat (limited to 'dbaccess/source/ui/app/subcomponentmanager.cxx')
-rw-r--r-- | dbaccess/source/ui/app/subcomponentmanager.cxx | 432 |
1 files changed, 432 insertions, 0 deletions
diff --git a/dbaccess/source/ui/app/subcomponentmanager.cxx b/dbaccess/source/ui/app/subcomponentmanager.cxx new file mode 100644 index 000000000000..c3ce4923b9c2 --- /dev/null +++ b/dbaccess/source/ui/app/subcomponentmanager.cxx @@ -0,0 +1,432 @@ +/************************************************************************* +* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +* +* Copyright 2008 by Sun Microsystems, Inc. +* +* OpenOffice.org - a multi-platform office productivity suite +* +* $RCSfile: subcomponentmanager.cxx,v $ +* +* $Revision: 1.1.2.2 $ +* +* 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 "subcomponentmanager.hxx" + +/** === begin UNO includes === **/ +#include <com/sun/star/frame/XFrame.hpp> +#include <com/sun/star/frame/XModel.hpp> +#include <com/sun/star/frame/XModel2.hpp> +#include <com/sun/star/util/XCloseable.hpp> +#include <com/sun/star/awt/XTopWindow.hpp> +/** === end UNO includes === **/ + +#include <tools/diagnose_ex.h> +#include <vcl/svapp.hxx> +#include <vos/mutex.hxx> + +#include <hash_map> +#include <algorithm> +#include <functional> + +//........................................................................ +namespace dbaui +{ +//........................................................................ + + /** === 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::frame::XFrame; + using ::com::sun::star::frame::XController; + using ::com::sun::star::frame::XModel; + using ::com::sun::star::lang::EventObject; + using ::com::sun::star::lang::XComponent; + using ::com::sun::star::frame::XModel2; + using ::com::sun::star::container::XEnumeration; + using ::com::sun::star::util::XCloseable; + using ::com::sun::star::awt::XTopWindow; + /** === end UNO using === **/ + + //============================================================================== + //= helper structs + //============================================================================== + namespace + { + struct SubComponentDescriptor + { + /// the frame which the component resides in. Must not be <NULL/> + Reference< XFrame > xFrame; + /// the controller of the sub component. Must not be <NULL/> + Reference< XController > xController; + /// the model of the sub component. Might be <NULL/> + Reference< XModel > xModel; + + SubComponentDescriptor() + :xFrame() + ,xController() + ,xModel() + { + } + + SubComponentDescriptor( const Reference< XComponent >& _rxComponent ) + { + xModel.set( _rxComponent, UNO_QUERY ); + + if ( xModel.is() ) + xController.set( xModel->getCurrentController(), UNO_SET_THROW ); + else + xController.set( _rxComponent, UNO_QUERY ); + + if ( xController.is() ) + xFrame.set( xController->getFrame(), UNO_SET_THROW ); + else + xFrame.set( _rxComponent, UNO_QUERY_THROW ); + + // if the given component was a frame, then ensure we have a controller + if ( xFrame.is() && !xController.is() ) + xController.set( xFrame->getController(), UNO_SET_THROW ); + + // if the component was a frame or a controller, then check wether there is a model (not required) + if ( !xModel.is() ) + xModel.set( xController->getModel() ); + } + }; + + struct SelectSubComponent : public ::std::unary_function< SubComponentDescriptor, Reference< XComponent > > + { + Reference< XComponent > operator()( const SubComponentDescriptor _desc ) const + { + if ( _desc.xModel.is() ) + return _desc.xModel.get(); + OSL_ENSURE( _desc.xController.is(), "SelectSubComponent::operator(): illegal component!" ); + return _desc.xController.get(); + } + }; + + struct SubComponentAccessor + { + /// the name of the sub component + ::rtl::OUString sName; + /// type of the component - usually an ElementType value + sal_Int32 nComponentType; + /// the mode in which the sub component has been opened + ElementOpenMode eOpenMode; + + SubComponentAccessor() + :sName() + ,nComponentType( sal_Int32( E_NONE ) ) + ,eOpenMode( E_OPEN_NORMAL ) + { + } + + SubComponentAccessor( const ::rtl::OUString& _rName, const sal_Int32 _nCompType, const ElementOpenMode _eMode ) + :sName( _rName ) + ,nComponentType( _nCompType ) + ,eOpenMode( _eMode ) + { + } + }; + + struct SubComponentAccessorHash : public ::std::unary_function< SubComponentAccessor, size_t > + { + size_t operator()( const SubComponentAccessor& _lhs ) const + { + return _lhs.sName.hashCode() + _lhs.nComponentType + size_t( _lhs.eOpenMode ); + } + }; + struct SubComponentAccessorEqual : public ::std::binary_function< SubComponentAccessor, SubComponentAccessor, bool > + { + bool operator()( const SubComponentAccessor& _lhs, const SubComponentAccessor& _rhs ) const + { + return ( _lhs.sName == _rhs.sName ) + && ( _lhs.nComponentType == _rhs.nComponentType ) + && ( _lhs.eOpenMode == _rhs.eOpenMode ); + } + }; + + typedef ::std::hash_map< SubComponentAccessor, SubComponentDescriptor, SubComponentAccessorHash, SubComponentAccessorEqual > + SubComponentMap; + + } + + //============================================================================== + //= SubComponentManager_Data + //============================================================================== + struct SubComponentManager_Data + { + SubComponentManager_Data( const ::comphelper::SharedMutex& _rMutex ) + :m_aMutex( _rMutex ) + { + } + + mutable ::comphelper::SharedMutex m_aMutex; + SubComponentMap m_aComponents; + + ::osl::Mutex& getMutex() const { return m_aMutex; } + }; + + //==================================================================== + //= SubComponentManager + //==================================================================== + //-------------------------------------------------------------------- + SubComponentManager::SubComponentManager( const ::comphelper::SharedMutex& _rMutex ) + :m_pData( new SubComponentManager_Data( _rMutex ) ) + { + } + + //-------------------------------------------------------------------- + SubComponentManager::~SubComponentManager() + { + } + + //-------------------------------------------------------------------- + void SubComponentManager::disposing() + { + ::osl::MutexGuard aGuard( m_pData->getMutex() ); + m_pData->m_aComponents.clear(); + } + + //-------------------------------------------------------------------- + namespace + { + bool lcl_fallbackToAnotherController( SubComponentDescriptor& _rCompDesc ) + { + Reference< XController > xFallback; + OSL_PRECOND( _rCompDesc.xModel.is(), "lcl_fallbackToAnotherController: illegal call!" ); + if ( !_rCompDesc.xModel.is() ) + return false; + + xFallback.set( _rCompDesc.xModel->getCurrentController() ); + if ( xFallback == _rCompDesc.xController ) + // don't accept the very same controller as fallback + xFallback.clear(); + + if ( !xFallback.is() ) + { + // perhaps XModel2 can be of help here + Reference< XModel2 > xModel2( _rCompDesc.xModel, UNO_QUERY ); + Reference< XEnumeration > xControllerEnum; + if ( xModel2.is() ) + xControllerEnum = xModel2->getControllers(); + while ( xControllerEnum.is() && xControllerEnum->hasMoreElements() ) + { + xFallback.set( xControllerEnum->nextElement(), UNO_QUERY ); + if ( xFallback == _rCompDesc.xController ) + xFallback.clear(); + } + } + + if ( xFallback.is() ) + { + _rCompDesc.xController = xFallback; + _rCompDesc.xFrame.set( xFallback->getFrame(), UNO_SET_THROW ); + return true; + } + + return false; + } + + //---------------------------------------------------------------- + bool lcl_closeComponent( const SubComponentDescriptor& _rComponent ) + { + Reference< XController > xController( _rComponent.xController ); + OSL_ENSURE( xController.is(), "lcl_closeComponent: invalid controller!" ); + + // suspend the controller in the document + if ( xController.is() ) + if ( !xController->suspend( sal_True ) ) + return false; + + bool bSuccess = false; + try + { + Reference< XCloseable > xCloseable( _rComponent.xFrame, UNO_QUERY_THROW ); + xCloseable->close( sal_True ); + bSuccess = true; + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + return bSuccess; + } + } + + //-------------------------------------------------------------------- + void SAL_CALL SubComponentManager::disposing( const EventObject& _rSource ) throw (RuntimeException) + { + ::osl::MutexGuard aGuard( m_pData->getMutex() ); + + for ( SubComponentMap::iterator comp = m_pData->m_aComponents.begin(); + comp != m_pData->m_aComponents.end(); + ++comp + ) + { + bool bRemove = false; + + if ( comp->second.xController == _rSource.Source ) + { + if ( !comp->second.xModel.is() ) + { + bRemove = true; + } + else + { + // maybe this is just one view to the sub document, and only this view is closed + if ( !lcl_fallbackToAnotherController( comp->second ) ) + { + bRemove = true; + } + } + } + else if ( comp->second.xModel == _rSource.Source ) + { + bRemove = true; + } + + if ( bRemove ) + { + m_pData->m_aComponents.erase( comp ); + break; + } + } + } + + //-------------------------------------------------------------------- + Sequence< Reference< XComponent> > SubComponentManager::getSubComponents() const + { + ::osl::MutexGuard aGuard( m_pData->getMutex() ); + + Sequence< Reference< XComponent > > aComponents( m_pData->m_aComponents.size() ); + ::std::transform( + m_pData->m_aComponents.begin(), + m_pData->m_aComponents.end(), + aComponents.getArray(), + ::std::compose1( SelectSubComponent(), ::std::select2nd< SubComponentMap::value_type >() ) + ); + return aComponents; + } + + // ----------------------------------------------------------------------------- + sal_Bool SubComponentManager::closeSubComponents() + { + ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); + ::osl::MutexGuard aGuard( m_pData->getMutex() ); + + try + { + typedef ::std::vector< SubComponentAccessor > ComponentAccessors; + ComponentAccessors aClosedComponents; + + SubComponentMap aComponents( m_pData->m_aComponents ); + for ( SubComponentMap::const_iterator comp = aComponents.begin(); + comp != aComponents.end(); + ++comp + ) + { + lcl_closeComponent( comp->second ); + } + } + catch ( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + + return empty(); + } + + // ----------------------------------------------------------------------------- + bool SubComponentManager::empty() const + { + ::osl::MutexGuard aGuard( m_pData->getMutex() ); + return m_pData->m_aComponents.empty(); + } + + // ----------------------------------------------------------------------------- + void SubComponentManager::onSubComponentOpened( const ::rtl::OUString& _rName, const sal_Int32 _nComponentType, + const ElementOpenMode _eOpenMode, const Reference< XComponent >& _rxComponent ) + { + ::osl::MutexGuard aGuard( m_pData->getMutex() ); + + // put into map + SubComponentAccessor aKey( _rName, _nComponentType, _eOpenMode ); + SubComponentDescriptor aElement( _rxComponent ); + + m_pData->m_aComponents.insert( SubComponentMap::value_type( + aKey, aElement + ) ) ; + + // add as listener + aElement.xController->addEventListener( this ); + if ( aElement.xModel.is() ) + aElement.xModel->addEventListener( this ); + } + + // ----------------------------------------------------------------------------- + bool SubComponentManager::activateSubFrame( const ::rtl::OUString& _rName, const sal_Int32 _nComponentType, const ElementOpenMode _eOpenMode ) const + { + ::osl::MutexGuard aGuard( m_pData->getMutex() ); + + SubComponentAccessor aKey( _rName, _nComponentType, _eOpenMode ); + SubComponentMap::const_iterator pos = m_pData->m_aComponents.find( aKey ); + if ( pos == m_pData->m_aComponents.end() ) + // no component with this name/type/open mode + return false; + + const Reference< XFrame > xFrame( pos->second.xFrame, UNO_SET_THROW ); + const Reference< XTopWindow > xTopWindow( xFrame->getContainerWindow(), UNO_QUERY_THROW ); + xTopWindow->toFront(); + + return true; + } + + // ----------------------------------------------------------------------------- + bool SubComponentManager::closeSubFrames( const ::rtl::OUString& _rName, const sal_Int32 _nComponentType ) + { + ::osl::MutexGuard aGuard( m_pData->getMutex() ); + + SubComponentMap aWorkingCopy( m_pData->m_aComponents ); + for ( SubComponentMap::const_iterator comp = aWorkingCopy.begin(); + comp != aWorkingCopy.end(); + ++comp + ) + { + if ( ( comp->first.sName != _rName ) || ( comp->first.nComponentType != _nComponentType ) ) + continue; + + if ( !lcl_closeComponent( comp->second ) ) + return false; + } + + return true; + } + +//........................................................................ +} // namespace dbaui +//........................................................................ |