/************************************************************************* * * $RCSfile: singledoccontroller.cxx,v $ * * $Revision: 1.5 $ * * last change: $Author: fs $ $Date: 2001-09-07 10:03:53 $ * * The Contents of this file are made available subject to the terms of * either of the following licenses * * - GNU Lesser General Public License Version 2.1 * - Sun Industry Standards Source License Version 1.1 * * Sun Microsystems Inc., October, 2000 * * GNU Lesser General Public License Version 2.1 * ============================================= * Copyright 2000 by Sun Microsystems, Inc. * 901 San Antonio Road, Palo Alto, CA 94303, USA * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License version 2.1, as published by the Free Software Foundation. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA * * * Sun Industry Standards Source License Version 1.1 * ================================================= * The contents of this file are subject to the Sun Industry Standards * Source License Version 1.1 (the "License"); You may not use this file * except in compliance with the License. You may obtain a copy of the * License at http://www.openoffice.org/license.html. * * Software provided under this License is provided on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. * See the License for the specific provisions governing your rights and * obligations concerning the Software. * * The Initial Developer of the Original Code is: Sun Microsystems, Inc.. * * Copyright: 2000 by Sun Microsystems, Inc. * * All Rights Reserved. * * Contributor(s): _______________________________________ * * ************************************************************************/ #ifndef DBAUI_SINGLEDOCCONTROLLER_HXX #include "singledoccontroller.hxx" #endif #ifndef _COMPHELPER_SEQUENCE_HXX_ #include #endif #ifndef DBACCESS_SHARED_DBUSTRINGS_HRC #include "dbustrings.hrc" #endif #ifndef _COM_SUN_STAR_BEANS_PROPERTYATTRIBUTE_HPP_ #include #endif #ifndef _COM_SUN_STAR_CONTAINER_XNAMEACCESS_HPP_ #include #endif #ifndef _COM_SUN_STAR_SDBC_XDATASOURCE_HPP_ #include #endif #ifndef _COM_SUN_STAR_CONTAINER_XCHILD_HPP_ #include #endif #ifndef _TOOLS_DEBUG_HXX #include #endif #ifndef _COMPHELPER_TYPES_HXX_ #include #endif #ifndef _SV_MSGBOX_HXX #include #endif #ifndef _DBU_RESOURCE_HRC_ #include "dbu_resource.hrc" #endif #ifndef DBAUI_DATAVIEW_HXX #include "dataview.hxx" #endif #ifndef _CPPUHELPER_TYPEPROVIDER_HXX_ #include #endif //........................................................................ namespace dbaui { //........................................................................ using namespace ::com::sun::star::uno; using namespace ::com::sun::star::beans; using namespace ::com::sun::star::lang; using namespace ::com::sun::star::container; using namespace ::com::sun::star::sdbc; //==================================================================== //= OConnectionChangeBroadcaster //==================================================================== class OConnectionChangeBroadcaster { private: OSingleDocumentController* m_pController; Reference< XConnection > m_xOldConnection; public: OConnectionChangeBroadcaster( OSingleDocumentController* _pController ); ~OConnectionChangeBroadcaster(); }; DBG_NAME(OConnectionChangeBroadcaster) //-------------------------------------------------------------------- OConnectionChangeBroadcaster::OConnectionChangeBroadcaster( OSingleDocumentController* _pController ) :m_pController( _pController ) { DBG_CTOR(OConnectionChangeBroadcaster,NULL); DBG_ASSERT( m_pController, "OConnectionChangeBroadcaster::OConnectionChangeBroadcaster: invalid controller!" ); if ( m_pController ) m_xOldConnection = m_pController->getConnection(); } //-------------------------------------------------------------------- OConnectionChangeBroadcaster::~OConnectionChangeBroadcaster() { if ( m_pController ) { // has the connection change while we were constructed? Reference< XConnection > xNewConnection = m_pController->getConnection(); if ( m_xOldConnection.get() != xNewConnection.get() ) { // yes -> fire the property change sal_Int32 mHandle = PROPERTY_ID_ACTIVECONNECTION; Any aNewValue = makeAny( xNewConnection ); Any aOldValue = makeAny( m_xOldConnection ); m_pController->fire( &mHandle, &aNewValue, &aOldValue, 1, sal_False ); } } DBG_DTOR(OConnectionChangeBroadcaster,NULL); } //==================================================================== //= OSingleDocumentController //==================================================================== //-------------------------------------------------------------------- OSingleDocumentController::OSingleDocumentController(const Reference< XMultiServiceFactory >& _rxORB) :OSingleDocumentController_CBASE( _rxORB ) ,OSingleDocumentController_PBASE( getBroadcastHelper() ) ,m_bOwnConnection( sal_False ) { registerProperty( PROPERTY_ACTIVECONNECTION, PROPERTY_ID_ACTIVECONNECTION, PropertyAttribute::READONLY | PropertyAttribute::BOUND, &m_xConnection, ::getCppuType( &m_xConnection ) ); } //-------------------------------------------------------------------- Any SAL_CALL OSingleDocumentController::queryInterface( const Type& _rType ) throw (RuntimeException) { Any aReturn = OSingleDocumentController_CBASE::queryInterface( _rType ); if ( !aReturn.hasValue() ) aReturn = OSingleDocumentController_PBASE::queryInterface( _rType ); return aReturn; } //-------------------------------------------------------------------- void SAL_CALL OSingleDocumentController::acquire( ) throw () { OSingleDocumentController_CBASE::acquire(); } //-------------------------------------------------------------------- void SAL_CALL OSingleDocumentController::release( ) throw () { OSingleDocumentController_CBASE::release(); } //-------------------------------------------------------------------- Sequence SAL_CALL OSingleDocumentController::getImplementationId( ) throw(RuntimeException) { static ::cppu::OImplementationId * pId = 0; if (! pId) { ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() ); if (! pId) { static ::cppu::OImplementationId aId; pId = &aId; } } return pId->getImplementationId(); } //-------------------------------------------------------------------- Sequence< Type > SAL_CALL OSingleDocumentController::getTypes( ) throw (RuntimeException) { return ::comphelper::concatSequences( OSingleDocumentController_CBASE::getTypes(), OSingleDocumentController_PBASE::getTypes() ); } //------------------------------------------------------------------------- Reference SAL_CALL OSingleDocumentController::getPropertySetInfo() throw(RuntimeException) { Reference xInfo( createPropertySetInfo( getInfoHelper() ) ); return xInfo; } //------------------------------------------------------------------------- ::cppu::IPropertyArrayHelper& OSingleDocumentController::getInfoHelper() { return *const_cast(this)->getArrayHelper(); } //-------------------------------------------------------------------- ::cppu::IPropertyArrayHelper* OSingleDocumentController::createArrayHelper( ) const { Sequence< Property > aProps; describeProperties(aProps); return new ::cppu::OPropertyArrayHelper(aProps); } //-------------------------------------------------------------------- void OSingleDocumentController::initializeDataSourceName( const ::rtl::OUString& _rName ) { DBG_ASSERT( _rName.getLength(), "OSingleDocumentController::initializeDataSourceName: invalid new name!" ); DBG_ASSERT( !m_sDataSourceName.getLength(), "OSingleDocumentController::initializeDataSourceName: already have a name!" ); m_sDataSourceName = _rName; // referesh the UNO object m_xDataSource.clear(); try { // get the context Reference< XNameAccess > xContext( getORB()->createInstance( SERVICE_SDB_DATABASECONTEXT ), UNO_QUERY ); // the DS Reference< XDataSource > xDS; if ( xContext.is() ) xContext->getByName( m_sDataSourceName ) >>= xDS; // (take the indirection through XDataSource to ensure we have a correct object ....) m_xDataSource = Reference< XPropertySet >( xDS, UNO_QUERY); DBG_ASSERT( m_xDataSource.is(), "OSingleDocumentController::initializeDataSourceName: could not retrieve the data source!" ); #ifdef DBG_UTIL if ( m_xConnection.is() ) { Reference< XChild > xConnAsChild( m_xConnection, UNO_QUERY ); DBG_ASSERT( xConnAsChild->getParent() == m_xDataSource, "OSingleDocumentController::initializeDataSourceName: invalid connection/data source combination!" ); // this initialize method is intended to be used from the XInitialization::initialize of derived classes // within this initialize, if both parameters (data source name and connection) are passed, they must // be consistent } #endif } catch( const Exception& ) { DBG_ERROR( "OSingleDocumentController::initializeDataSourceName: caught an exception!" ); } } //-------------------------------------------------------------------- void OSingleDocumentController::initializeConnection( const Reference< XConnection >& _rxForeignConn ) { OConnectionChangeBroadcaster( this ); DBG_ASSERT( !isConnected(), "OSingleDocumentController::initializeConnection: not to be called when already connected!" ); // usually this gets called from within initialize of derived classes ... if ( isConnected() ) disconnect(); m_xConnection = _rxForeignConn; m_bOwnConnection = sal_False; startConnectionListening( m_xConnection ); // get the data source the connection belongs to OSL_ENSURE( (m_sDataSourceName.getLength() != 0) == (m_xDataSource.is() == sal_True), "OSingleDocumentController::initializeConnection: inconsistence!" ); if ( !m_xDataSource.is() ) { try { Reference< XChild > xConnAsChild( m_xConnection, UNO_QUERY ); Reference< XDataSource > xDS; if ( xConnAsChild.is() ) xDS = Reference< XDataSource >( xConnAsChild->getParent(), UNO_QUERY ); // (take the indirection through XDataSource to ensure we have a correct object ....) m_xDataSource = Reference< XPropertySet >( xDS, UNO_QUERY); DBG_ASSERT( m_xDataSource.is(), "OSingleDocumentController::initializeConnection: could not retrieve the data source!" ); if ( m_xDataSource.is() ) { m_xDataSource->getPropertyValue( PROPERTY_NAME ) >>= m_sDataSourceName; DBG_ASSERT( m_sDataSourceName.getLength(), "OSingleDocumentController::initializeConnection: invalid data source name!" ); } } catch( const Exception& ) { DBG_ERROR( "OSingleDocumentController::initializeConnection: caught an exception!" ); } } } //-------------------------------------------------------------------- void OSingleDocumentController::reconnect( sal_Bool _bUI ) { OConnectionChangeBroadcaster( this ); stopConnectionListening(m_xConnection); if ( m_bOwnConnection ) { try { ::comphelper::disposeComponent( m_xConnection ); } catch( const Exception& ) { /* allowed: if we reconnect because the old connection has been disposed .... */ } } m_xConnection = NULL; m_bOwnConnection = sal_False; // reconnect sal_Bool bReConnect = sal_True; if ( _bUI ) { QueryBox aQuery( getView(), ModuleRes(TABLE_QUERY_CONNECTION_LOST) ); bReConnect = ( RET_YES == aQuery.Execute() ); } // now really reconnect ... if ( bReConnect ) { m_xConnection = connect( m_sDataSourceName, sal_True ); m_bOwnConnection = m_xConnection.is(); } // invalidate all slots InvalidateAll(); } //-------------------------------------------------------------------- void OSingleDocumentController::disconnect() { OConnectionChangeBroadcaster( this ); stopConnectionListening(m_xConnection); try { if ( m_bOwnConnection ) ::comphelper::disposeComponent( m_xConnection ); } catch(const Exception&) { } m_xConnection = NULL; m_bOwnConnection = sal_False; InvalidateAll(); } //-------------------------------------------------------------------- void OSingleDocumentController::losingConnection() { // our connection was disposed so we need a new one reconnect( sal_True ); } //-------------------------------------------------------------------- void SAL_CALL OSingleDocumentController::disposing() { OSingleDocumentController_CBASE::disposing(); disconnect(); m_xDataSource.clear(); } //-------------------------------------------------------------------- sal_Bool OSingleDocumentController::Construct(Window* _pParent) { DBG_ASSERT( getView(), "OSingleDocumentController::Construct: have no view!" ); if ( getView() ) getView()->enableSeparator( ); return OSingleDocumentController_CBASE::Construct( _pParent ); } //-------------------------------------------------------------------- void SAL_CALL OSingleDocumentController::disposing(const EventObject& _rSource) throw( RuntimeException ) { if ( !getBroadcastHelper().bInDispose && !getBroadcastHelper().bDisposed && isConnected() && ( _rSource.Source == getConnection() ) ) { losingConnection(); } else OSingleDocumentController_CBASE::disposing( _rSource ); } //........................................................................ } // namespace dbaui //........................................................................ /************************************************************************* * history: * $Log: not supported by cvs2svn $ * Revision 1.4 2001/08/16 13:00:02 hr * #65293#: syntax * * Revision 1.3 2001/08/15 13:36:51 fs * #88637# add a separator above the toolbox * * Revision 1.2 2001/08/15 13:16:25 oj * #88644# insert some DBG's * * Revision 1.1 2001/08/14 12:00:02 fs * initial checkin - base class for controller which work on one single object belonging to a data source connection * * * Revision 1.0 14.08.01 09:45:39 fs ************************************************************************/