From f9a37be30cbb23c941f519c92ed2de6f9a44f924 Mon Sep 17 00:00:00 2001 From: "Frank Schoenheit [fs]" Date: Thu, 2 Dec 2010 11:11:43 +0100 Subject: [PATCH] dba34c: #i77025# don't allow closign the app window when a wizard is running --- dbaccess/source/ui/app/AppController.cxx | 98 +++++++----- dbaccess/source/ui/app/closeveto.cxx | 180 +++++++++++++++++++++++ dbaccess/source/ui/app/closeveto.hxx | 67 +++++++++ dbaccess/source/ui/app/makefile.mk | 3 +- 4 files changed, 311 insertions(+), 37 deletions(-) create mode 100755 dbaccess/source/ui/app/closeveto.cxx create mode 100755 dbaccess/source/ui/app/closeveto.hxx diff --git a/dbaccess/source/ui/app/AppController.cxx b/dbaccess/source/ui/app/AppController.cxx index d75272e796a4..263214125f59 100644 --- a/dbaccess/source/ui/app/AppController.cxx +++ b/dbaccess/source/ui/app/AppController.cxx @@ -32,6 +32,7 @@ #include "dbustrings.hrc" #include "advancedsettingsdlg.hxx" #include "subcomponentmanager.hxx" +#include "closeveto.hxx" /** === begin UNO includes === **/ #include @@ -1953,6 +1954,9 @@ IMPL_LINK( OApplicationController, OnCreateWithPilot, void*, _pType ) // ----------------------------------------------------------------------------- void OApplicationController::newElementWithPilot( ElementType _eType ) { + CloseVeto aKeepDoc( getFrame() ); + // prevent the document being closed while the wizard is open + OSL_ENSURE( getContainer(), "OApplicationController::newElementWithPilot: without a view?" ); switch ( _eType ) @@ -2714,61 +2718,83 @@ void SAL_CALL OApplicationController::attachFrame( const Reference< XFrame > & i sal_Bool SAL_CALL OApplicationController::attachModel(const Reference< XModel > & _rxModel) throw( RuntimeException ) { ::osl::MutexGuard aGuard( getMutex() ); - Reference< XOfficeDatabaseDocument > xOfficeDoc( _rxModel, UNO_QUERY ); - if ( !xOfficeDoc.is() && _rxModel.is() ) + const Reference< XOfficeDatabaseDocument > xOfficeDoc( _rxModel, UNO_QUERY ); + const Reference< XModifiable > xDocModify( _rxModel, UNO_QUERY ); + if ( ( !xOfficeDoc.is() || !xDocModify.is() ) && _rxModel.is() ) { DBG_ERROR( "OApplicationController::attachModel: invalid model!" ); return sal_False; } - DBG_ASSERT( !( m_xModel.is() && ( m_xModel != _rxModel ) ), - "OApplicationController::attachModel: missing implementation: setting a new model while we have another one!" ); - // at least: remove as property change listener from the old model/data source + if ( m_xModel.is() && ( m_xModel != _rxModel ) && ( _rxModel.is() ) ) + { + OSL_ENSURE( false, "OApplicationController::attachModel: missing implementation: setting a new model while we have another one!" ); + // we'd need to completely update our view here, close sub components, and the like + return sal_False; + } + + const ::rtl::OUString aPropertyNames[] = + { + PROPERTY_URL, PROPERTY_USER + }; + + // disconnect from old model + try + { + if ( m_xDataSource.is() ) + { + for ( size_t i=0; i < sizeof( aPropertyNames ) / sizeof( aPropertyNames[0] ); ++i ) + { + m_xDataSource->removePropertyChangeListener( aPropertyNames[i], this ); + } + } + + Reference< XModifyBroadcaster > xBroadcaster( m_xModel, UNO_QUERY ); + if ( xBroadcaster.is() ) + xBroadcaster->removeModifyListener( this ); + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } m_xModel = _rxModel; - if ( m_xModel.is() ) + m_xDocumentModify = xDocModify; + m_xDataSource.set( xOfficeDoc.is() ? xOfficeDoc->getDataSource() : Reference< XDataSource >(), UNO_QUERY ); + + // connect to new model + try { - m_xDocumentModify.set( m_xModel, UNO_QUERY_THROW ); + if ( m_xDataSource.is() ) + { + for ( size_t i=0; i < sizeof( aPropertyNames ) / sizeof( aPropertyNames[0] ); ++i ) + { + m_xDataSource->addPropertyChangeListener( aPropertyNames[i], this ); + } + } + + Reference< XModifyBroadcaster > xBroadcaster( m_xModel, UNO_QUERY_THROW ); + xBroadcaster->addModifyListener( this ); + } - else + catch( const Exception& ) { - m_xDocumentModify.clear(); + DBG_UNHANDLED_EXCEPTION(); } - m_xDataSource.set(xOfficeDoc.is() ? xOfficeDoc->getDataSource() : Reference(),UNO_QUERY); + // initial preview mode if ( m_xDataSource.is() ) { try { - m_xDataSource->addPropertyChangeListener(PROPERTY_INFO, this); - m_xDataSource->addPropertyChangeListener(PROPERTY_URL, this); - m_xDataSource->addPropertyChangeListener(PROPERTY_ISPASSWORDREQUIRED, this); - m_xDataSource->addPropertyChangeListener(PROPERTY_LAYOUTINFORMATION, this); - m_xDataSource->addPropertyChangeListener(PROPERTY_SUPPRESSVERSIONCL, this); - m_xDataSource->addPropertyChangeListener(PROPERTY_TABLEFILTER, this); - m_xDataSource->addPropertyChangeListener(PROPERTY_TABLETYPEFILTER, this); - m_xDataSource->addPropertyChangeListener(PROPERTY_USER, this); // to get the 'modified' for the data source - Reference< XModifyBroadcaster > xBroadcaster(m_xModel, UNO_QUERY); - if ( xBroadcaster.is() ) - xBroadcaster->addModifyListener(static_cast(this)); - - Sequence aFields; - m_xDataSource->getPropertyValue(PROPERTY_LAYOUTINFORMATION) >>= aFields; - PropertyValue *pIter = aFields.getArray(); - PropertyValue *pEnd = pIter + aFields.getLength(); - for (; pIter != pEnd && pIter->Name != INFO_PREVIEW; ++pIter) - ; - - if ( pIter != pEnd ) + ::comphelper::NamedValueCollection aLayoutInfo( m_xDataSource->getPropertyValue( PROPERTY_LAYOUTINFORMATION ) ); + if ( aLayoutInfo.has( (rtl::OUString)INFO_PREVIEW ) ) { - sal_Int32 nValue = 0; - pIter->Value >>= nValue; - m_ePreviewMode = static_cast(nValue); + const sal_Int32 nPreviewMode( aLayoutInfo.getOrDefault( (rtl::OUString)INFO_PREVIEW, (sal_Int32)0 ) ); + m_ePreviewMode = static_cast< PreviewMode >( nPreviewMode ); if ( getView() ) - { - getContainer()->switchPreview(m_ePreviewMode); - } + getContainer()->switchPreview( m_ePreviewMode ); } } catch( const Exception& ) diff --git a/dbaccess/source/ui/app/closeveto.cxx b/dbaccess/source/ui/app/closeveto.cxx new file mode 100755 index 000000000000..558df26b643e --- /dev/null +++ b/dbaccess/source/ui/app/closeveto.cxx @@ -0,0 +1,180 @@ +/************************************************************************* + * 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 + * + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include "precompiled_dbaccess.hxx" + +#include "closeveto.hxx" + +/** === begin UNO includes === **/ +#include +/** === end UNO includes === **/ + +#include +#include +#include + +//...................................................................................................................... +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::util::XCloseable; + using ::com::sun::star::util::XCloseListener; + using ::com::sun::star::util::CloseVetoException; + using ::com::sun::star::lang::EventObject; + /** === end UNO using === **/ + + //================================================================================================================== + //= CloseListener_Impl + //================================================================================================================== + typedef ::cppu::WeakImplHelper1 < XCloseListener + > CloseListener_Base; + class DBACCESS_DLLPRIVATE CloseListener_Impl : public CloseListener_Base + { + public: + CloseListener_Impl() + :m_bHasOwnership( false ) + { + } + + // XCloseListener + virtual void SAL_CALL queryClosing( const EventObject& Source, ::sal_Bool GetsOwnership ) throw (CloseVetoException, RuntimeException); + virtual void SAL_CALL notifyClosing( const EventObject& Source ) throw (RuntimeException); + + // XEventListener + virtual void SAL_CALL disposing( const EventObject& Source) throw (RuntimeException); + + bool hasOwnership() const { return m_bHasOwnership; } + + protected: + ~CloseListener_Impl() + { + } + + private: + bool m_bHasOwnership; + }; + + //------------------------------------------------------------------------------------------------------------------ + void SAL_CALL CloseListener_Impl::queryClosing( const EventObject& i_source, ::sal_Bool i_deliverOwnership ) throw (CloseVetoException, RuntimeException) + { + (void)i_source; + + if ( !m_bHasOwnership ) + m_bHasOwnership = i_deliverOwnership; + + throw CloseVetoException(); + } + + //------------------------------------------------------------------------------------------------------------------ + void SAL_CALL CloseListener_Impl::notifyClosing( const EventObject& i_source ) throw (RuntimeException) + { + (void)i_source; + } + + //------------------------------------------------------------------------------------------------------------------ + void SAL_CALL CloseListener_Impl::disposing( const EventObject& i_source ) throw (RuntimeException) + { + (void)i_source; + } + + //================================================================================================================== + //= CloseVeto_Data + //================================================================================================================== + struct DBACCESS_DLLPRIVATE CloseVeto_Data + { + Reference< XCloseable > xCloseable; + ::rtl::Reference< CloseListener_Impl > pListener; + }; + + //================================================================================================================== + //= operations + //================================================================================================================== + namespace + { + //-------------------------------------------------------------------------------------------------------------- + void lcl_init( CloseVeto_Data& i_data, const Reference< XInterface >& i_closeable ) + { + i_data.xCloseable.set( i_closeable, UNO_QUERY ); + ENSURE_OR_RETURN_VOID( i_data.xCloseable.is(), "CloseVeto: the component is not closeable!" ); + + i_data.pListener = new CloseListener_Impl; + i_data.xCloseable->addCloseListener( i_data.pListener.get() ); + } + + //-------------------------------------------------------------------------------------------------------------- + void lcl_deinit( CloseVeto_Data& i_data ) + { + if ( !i_data.xCloseable.is() ) + return; + + i_data.xCloseable->removeCloseListener( i_data.pListener.get() ); + if ( i_data.pListener->hasOwnership() ) + { + try + { + i_data.xCloseable->close( sal_True ); + } + catch( const CloseVetoException& ) { } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + } + } + } + + //================================================================================================================== + //= CloseVeto + //================================================================================================================== + //------------------------------------------------------------------------------------------------------------------ + CloseVeto::CloseVeto( const Reference< XInterface >& i_closeable ) + :m_pData( new CloseVeto_Data ) + { + lcl_init( *m_pData, i_closeable ); + } + + //------------------------------------------------------------------------------------------------------------------ + CloseVeto::~CloseVeto() + { + lcl_deinit( *m_pData ); + } + +//...................................................................................................................... +} // namespace dbaui +//...................................................................................................................... diff --git a/dbaccess/source/ui/app/closeveto.hxx b/dbaccess/source/ui/app/closeveto.hxx new file mode 100755 index 000000000000..f7e1c83644d1 --- /dev/null +++ b/dbaccess/source/ui/app/closeveto.hxx @@ -0,0 +1,67 @@ +/************************************************************************* + * 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 + * + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef DBACCESS_CLOSEVETO_HXX +#define DBACCESS_CLOSEVETO_HXX + +#include "dbaccessdllapi.h" + +/** === begin UNO includes === **/ +#include +/** === end UNO includes === **/ + +#include + +//...................................................................................................................... +namespace dbaui +{ +//...................................................................................................................... + + //================================================================================================================== + //= CloseVeto + //================================================================================================================== + struct CloseVeto_Data; + /** will add a XCloseListener to a given component, and veto its closing as long as the CloseVeto + instance is alive. + + If closing has been requested and vetoed while the CloseVeto instance is alive, and the ownership + went to the CloseVeto instance, then it will close the component in its dtor. + */ + class DBACCESS_DLLPRIVATE CloseVeto + { + public: + CloseVeto( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& i_closeable ); + ~CloseVeto(); + + private: + ::boost::scoped_ptr< CloseVeto_Data > m_pData; + }; + +//...................................................................................................................... +} // namespace dbaui +//...................................................................................................................... + +#endif // DBACCESS_CLOSEVETO_HXX diff --git a/dbaccess/source/ui/app/makefile.mk b/dbaccess/source/ui/app/makefile.mk index a7097b4330e1..e26927d99628 100644 --- a/dbaccess/source/ui/app/makefile.mk +++ b/dbaccess/source/ui/app/makefile.mk @@ -48,7 +48,8 @@ EXCEPTIONSFILES=\ $(SLO)$/AppSwapWindow.obj \ $(SLO)$/AppTitleWindow.obj \ $(SLO)$/AppView.obj \ - $(SLO)$/subcomponentmanager.obj + $(SLO)$/subcomponentmanager.obj \ + $(SLO)$/closeveto.obj SLOFILES =\