diff options
Diffstat (limited to 'connectivity/source/inc/calc/CConnection.hxx')
-rw-r--r-- | connectivity/source/inc/calc/CConnection.hxx | 68 |
1 files changed, 65 insertions, 3 deletions
diff --git a/connectivity/source/inc/calc/CConnection.hxx b/connectivity/source/inc/calc/CConnection.hxx index 63b1d4ab084d..a5e46b237b26 100644 --- a/connectivity/source/inc/calc/CConnection.hxx +++ b/connectivity/source/inc/calc/CConnection.hxx @@ -21,7 +21,10 @@ #define INCLUDED_CONNECTIVITY_SOURCE_INC_CALC_CCONNECTION_HXX #include "file/FConnection.hxx" +#include <com/sun/star/frame/XDesktop2.hpp> +#include <com/sun/star/frame/XTerminateListener.hpp> #include <com/sun/star/uno/DeploymentException.hpp> +#include <unotools/closeveto.hxx> namespace com { namespace sun { namespace star { namespace sheet { class XSpreadsheetDocument; } @@ -39,12 +42,71 @@ namespace connectivity { // the spreadsheet document: css::uno::Reference< css::sheet::XSpreadsheetDocument > m_xDoc; - /// close listener that vetoes so nobody disposes m_xDoc - ::std::unique_ptr< ::utl::CloseVeto> m_pCloseListener; OUString m_sPassword; OUString m_aFileName; oslInterlockedCount m_nDocCount; + class CloseVetoButTerminateListener : public cppu::WeakComponentImplHelper<css::frame::XTerminateListener> + { + private: + /// close listener that vetoes so nobody else disposes m_xDoc + std::unique_ptr<utl::CloseVeto> m_pCloseListener; + /// but also listen to XDesktop and if app is terminating anyway, dispose m_xDoc while + /// its still possible to do so properly + css::uno::Reference<css::frame::XDesktop2> m_xDesktop; + osl::Mutex m_aMutex; + public: + CloseVetoButTerminateListener() + : cppu::WeakComponentImplHelper<css::frame::XTerminateListener>(m_aMutex) + { + } + + void start(const css::uno::Reference<css::uno::XInterface>& rCloseable, + const css::uno::Reference<css::frame::XDesktop2>& rDesktop) + { + m_xDesktop = rDesktop; + m_xDesktop->addTerminateListener(this); + m_pCloseListener.reset(new utl::CloseVeto(rCloseable, true)); + } + + void stop() + { + m_pCloseListener.reset(); + if (!m_xDesktop.is()) + return; + m_xDesktop->removeTerminateListener(this); + m_xDesktop.clear(); + } + + // XTerminateListener + virtual void SAL_CALL queryTermination(const css::lang::EventObject& /*rEvent*/) + throw(css::frame::TerminationVetoException, css::uno::RuntimeException, std::exception) override + { + } + + virtual void SAL_CALL notifyTermination(const css::lang::EventObject& /*rEvent*/) + throw(css::uno::RuntimeException, std::exception) override + { + stop(); + } + + virtual void SAL_CALL disposing() override + { + stop(); + cppu::WeakComponentImplHelperBase::disposing(); + } + + virtual void SAL_CALL disposing(const css::lang::EventObject& rEvent) + throw(css::uno::RuntimeException, std::exception) override + { + const bool bShutDown = (rEvent.Source == m_xDesktop); + if (bShutDown) + stop(); + } + }; + + rtl::Reference<CloseVetoButTerminateListener> m_xCloseVetoButTerminateListener; + public: OCalcConnection(ODriver* _pDriver); virtual ~OCalcConnection(); @@ -84,7 +146,7 @@ namespace connectivity } ~ODocHolder() { - m_xDoc.clear(); + m_xDoc.clear(); m_pConnection->releaseDoc(); } const css::uno::Reference< css::sheet::XSpreadsheetDocument>& getDoc() const { return m_xDoc; } |