sw/inc/dbmgr.hxx | 10 +++- sw/source/core/doc/docnew.cxx | 6 ++ sw/source/uibase/app/applab.cxx | 2 sw/source/uibase/dbui/dbmgr.cxx | 100 +++++++++++++++++++++++++++++++++++++++- 4 files changed, 114 insertions(+), 4 deletions(-)
New commits: commit b8b4ac9e6e8f03fb84bddb714d3c5908a45153b1 Author: Miklos Vajna <vmik...@collabora.co.uk> Date: Wed Jun 10 19:04:04 2015 +0200 sw: remove embedded data source on location deregistration Change-Id: I5b2a24fee50a25a41ba26787f7e30409348d7808 diff --git a/sw/inc/dbmgr.hxx b/sw/inc/dbmgr.hxx index 5bf1542..0b809f9 100644 --- a/sw/inc/dbmgr.hxx +++ b/sw/inc/dbmgr.hxx @@ -184,6 +184,7 @@ struct SwMergeDescriptor struct SwDBManager_Impl; class SwConnectionDisposedListener_Impl; class AbstractMailMergeDlg; +class SwDoc; class SW_DLLPUBLIC SwDBManager { @@ -205,6 +206,9 @@ friend class SwConnectionDisposedListener_Impl; /// Name of the embedded database that's included in the current document. OUString m_sEmbeddedName; + /// The document that owns this manager. + SwDoc* m_pDoc; + SAL_DLLPRIVATE SwDSParam* FindDSData(const SwDBData& rData, bool bCreate); SAL_DLLPRIVATE SwDSParam* FindDSConnection(const OUString& rSource, bool bCreate); @@ -222,7 +226,7 @@ friend class SwConnectionDisposedListener_Impl; SAL_DLLPRIVATE bool ToNextRecord(SwDSParam* pParam); public: - SwDBManager(); + SwDBManager(SwDoc* pDoc); ~SwDBManager(); enum DBConnURITypes { @@ -421,6 +425,10 @@ public: const css::uno::Reference<css::embed::XStorage>& xStorage, const OUString& rStreamRelPath, const OUString& rOwnURL); + + SwDoc* getDoc() const; + /// Stop reacting to removed database registrations. + void releaseRevokeListener(); }; #endif diff --git a/sw/source/core/doc/docnew.cxx b/sw/source/core/doc/docnew.cxx index ef6b904..939f270 100644 --- a/sw/source/core/doc/docnew.cxx +++ b/sw/source/core/doc/docnew.cxx @@ -343,7 +343,7 @@ SwDoc::SwDoc() #if HAVE_FEATURE_DBCONNECTIVITY // Create DBManager - mpDBManager = new SwDBManager; + mpDBManager = new SwDBManager(this); #endif // create TOXTypes @@ -543,7 +543,11 @@ SwDoc::~SwDoc() // On load, SwDBManager::setEmbeddedName() may register a data source. // If we have an embedded one, then sDataSoure points to the registered name, so revoke it here. if (!mpDBManager->getEmbeddedName().isEmpty() && !maDBData.sDataSource.isEmpty()) + { + // Remove the revoke listener here first, so that we don't remove the data source from the document. + mpDBManager->releaseRevokeListener(); SwDBManager::RevokeDataSource(maDBData.sDataSource); + } DELETEZ( mpDBManager ); #endif diff --git a/sw/source/uibase/app/applab.cxx b/sw/source/uibase/app/applab.cxx index 2521c99..4858f89 100644 --- a/sw/source/uibase/app/applab.cxx +++ b/sw/source/uibase/app/applab.cxx @@ -159,7 +159,7 @@ void SwModule::InsertLab(SfxRequest& rReq, bool bLabel) #if HAVE_FEATURE_DBCONNECTIVITY // Create DB-Manager - boost::scoped_ptr<SwDBManager> pDBManager(new SwDBManager); + boost::scoped_ptr<SwDBManager> pDBManager(new SwDBManager(0)); #endif // Read SwLabItem from Config diff --git a/sw/source/uibase/dbui/dbmgr.cxx b/sw/source/uibase/dbui/dbmgr.cxx index 6dc0bb4..48077f6 100644 --- a/sw/source/uibase/dbui/dbmgr.cxx +++ b/sw/source/uibase/dbui/dbmgr.cxx @@ -204,11 +204,90 @@ public: }; +/// Listens to removed data sources, and if it's one that's embedded into this document, triggers embedding removal. +class SwDataSourceRemovedListener : public cppu::WeakImplHelper<sdb::XDatabaseRegistrationsListener> +{ + uno::Reference<sdb::XDatabaseContext> m_xDatabaseContext; + SwDBManager* m_pDBManager; + +public: + SwDataSourceRemovedListener(SwDBManager& rDBManager); + virtual ~SwDataSourceRemovedListener(); + virtual void SAL_CALL registeredDatabaseLocation(const sdb::DatabaseRegistrationEvent& rEvent) throw (uno::RuntimeException, std::exception) SAL_OVERRIDE; + virtual void SAL_CALL revokedDatabaseLocation(const sdb::DatabaseRegistrationEvent& rEvent) throw (uno::RuntimeException, std::exception) SAL_OVERRIDE; + virtual void SAL_CALL changedDatabaseLocation(const sdb::DatabaseRegistrationEvent& rEvent) throw (uno::RuntimeException, std::exception) SAL_OVERRIDE; + virtual void SAL_CALL disposing(const lang::EventObject& rObject) throw (uno::RuntimeException, std::exception) SAL_OVERRIDE; + void Dispose(); +}; + +SwDataSourceRemovedListener::SwDataSourceRemovedListener(SwDBManager& rDBManager) + : m_pDBManager(&rDBManager) +{ + uno::Reference<uno::XComponentContext> xComponentContext(comphelper::getProcessComponentContext()); + m_xDatabaseContext = sdb::DatabaseContext::create(xComponentContext); + m_xDatabaseContext->addDatabaseRegistrationsListener(this); +} + +SwDataSourceRemovedListener::~SwDataSourceRemovedListener() +{ + if (m_xDatabaseContext.is()) + m_xDatabaseContext->removeDatabaseRegistrationsListener(this); +} + +void SAL_CALL SwDataSourceRemovedListener::registeredDatabaseLocation(const sdb::DatabaseRegistrationEvent& /*rEvent*/) throw (uno::RuntimeException, std::exception) +{ +} + +void SAL_CALL SwDataSourceRemovedListener::revokedDatabaseLocation(const sdb::DatabaseRegistrationEvent& rEvent) throw (uno::RuntimeException, std::exception) +{ + if (!m_pDBManager || m_pDBManager->getEmbeddedName().isEmpty()) + return; + + SwDoc* pDoc = m_pDBManager->getDoc(); + if (!pDoc) + return; + + SwDocShell* pDocShell = pDoc->GetDocShell(); + if (!pDocShell) + return; + + OUString aOwnURL = pDocShell->GetMedium()->GetURLObject().GetMainURL(INetURLObject::DECODE_WITH_CHARSET); + OUString sTmpName = "vnd.sun.star.pkg://"; + sTmpName += INetURLObject::encode(aOwnURL, INetURLObject::PART_AUTHORITY, INetURLObject::ENCODE_ALL); + sTmpName += "/" + m_pDBManager->getEmbeddedName(); + + if (sTmpName != rEvent.OldLocation) + return; + + // The revoked database location is inside this document, then remove the + // embedding, as otherwise it would be back on the next reload of the + // document. + pDocShell->GetStorage()->removeElement(m_pDBManager->getEmbeddedName()); + m_pDBManager->setEmbeddedName(OUString(), *pDocShell); +} + +void SAL_CALL SwDataSourceRemovedListener::changedDatabaseLocation(const sdb::DatabaseRegistrationEvent& rEvent) throw (uno::RuntimeException, std::exception) +{ + if (rEvent.OldLocation != rEvent.NewLocation) + revokedDatabaseLocation(rEvent); +} + +void SwDataSourceRemovedListener::disposing(const lang::EventObject& /*rObject*/) throw (uno::RuntimeException, std::exception) +{ + m_xDatabaseContext.clear(); +} + +void SwDataSourceRemovedListener::Dispose() +{ + m_pDBManager = 0; +} + struct SwDBManager_Impl { SwDSParam* pMergeData; AbstractMailMergeDlg* pMergeDialog; ::rtl::Reference<SwConnectionDisposedListener_Impl> m_xDisposeListener; + rtl::Reference<SwDataSourceRemovedListener> m_xDataSourceRemovedListener; explicit SwDBManager_Impl(SwDBManager& rDBManager) :pMergeData(0) @@ -219,6 +298,8 @@ struct SwDBManager_Impl ~SwDBManager_Impl() { m_xDisposeListener->Dispose(); + if (m_xDataSourceRemovedListener.is()) + m_xDataSourceRemovedListener->Dispose(); } }; @@ -693,7 +774,7 @@ void SwDBManager::GetColumnNames(ListBox* pListBox, } } -SwDBManager::SwDBManager() +SwDBManager::SwDBManager(SwDoc* pDoc) : bCancel(false) , bInitDBFields(false) , bSingleJobs(false) @@ -702,6 +783,7 @@ SwDBManager::SwDBManager() , bMergeLock(false) , pImpl(new SwDBManager_Impl(*this)) , pMergeEvtSrc(NULL) + , m_pDoc(pDoc) { } @@ -2973,6 +3055,7 @@ uno::Reference<sdbc::XResultSet> SwDBManager::createCursor(const OUString& _sDat void SwDBManager::setEmbeddedName(const OUString& rEmbeddedName, SwDocShell& rDocShell) { bool bLoad = m_sEmbeddedName != rEmbeddedName && !rEmbeddedName.isEmpty(); + bool bRegisterListener = m_sEmbeddedName.isEmpty() && !rEmbeddedName.isEmpty(); m_sEmbeddedName = rEmbeddedName; @@ -2984,6 +3067,10 @@ void SwDBManager::setEmbeddedName(const OUString& rEmbeddedName, SwDocShell& rDo if (xStorage->hasByName(rEmbeddedName)) LoadAndRegisterEmbeddedDataSource(rDocShell.GetDoc()->GetDBData(), rDocShell); } + + if (bRegisterListener) + // Register a remove listener, so we know when the embedded data source is removed. + pImpl->m_xDataSourceRemovedListener = new SwDataSourceRemovedListener(*this); } OUString SwDBManager::getEmbeddedName() const @@ -2991,6 +3078,17 @@ OUString SwDBManager::getEmbeddedName() const return m_sEmbeddedName; } +SwDoc* SwDBManager::getDoc() const +{ + return m_pDoc; +} + +void SwDBManager::releaseRevokeListener() +{ + pImpl->m_xDataSourceRemovedListener->Dispose(); + pImpl->m_xDataSourceRemovedListener.clear(); +} + SwConnectionDisposedListener_Impl::SwConnectionDisposedListener_Impl(SwDBManager& rManager) : m_pDBManager(&rManager) { _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits