Kaydet (Commit) 7368b6ca authored tarafından Michael Stahl's avatar Michael Stahl

rhbz#1213173: connectivity: Calc driver: prevent document being disposed

... by adding a XCloseListener that vetoes any attempt to close it.

The Calc document can be opened by the user in the UI and closed again.

Change-Id: Ied427b67274d925c911e516c0a50a4c0b2b18db9
üst 7259901b
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
#include "calc/CPreparedStatement.hxx" #include "calc/CPreparedStatement.hxx"
#include "calc/CStatement.hxx" #include "calc/CStatement.hxx"
#include <unotools/pathoptions.hxx> #include <unotools/pathoptions.hxx>
#include <unotools/closeveto.hxx>
#include <connectivity/dbexception.hxx> #include <connectivity/dbexception.hxx>
#include <cppuhelper/exc_hlp.hxx> #include <cppuhelper/exc_hlp.hxx>
#include <comphelper/processfactory.hxx> #include <comphelper/processfactory.hxx>
...@@ -165,13 +166,17 @@ Reference< XSpreadsheetDocument> OCalcConnection::acquireDoc() ...@@ -165,13 +166,17 @@ Reference< XSpreadsheetDocument> OCalcConnection::acquireDoc()
::dbtools::throwGenericSQLException( sError, *this, aErrorDetails ); ::dbtools::throwGenericSQLException( sError, *this, aErrorDetails );
} }
osl_atomic_increment(&m_nDocCount); osl_atomic_increment(&m_nDocCount);
m_pCloseListener.reset(new utl::CloseVeto(m_xDoc, true));
return m_xDoc; return m_xDoc;
} }
void OCalcConnection::releaseDoc() void OCalcConnection::releaseDoc()
{ {
if ( osl_atomic_decrement(&m_nDocCount) == 0 ) if ( osl_atomic_decrement(&m_nDocCount) == 0 )
::comphelper::disposeComponent( m_xDoc ); {
m_pCloseListener.reset(); // dispose m_xDoc
m_xDoc.clear();
}
} }
void OCalcConnection::disposing() void OCalcConnection::disposing()
...@@ -179,7 +184,8 @@ void OCalcConnection::disposing() ...@@ -179,7 +184,8 @@ void OCalcConnection::disposing()
::osl::MutexGuard aGuard(m_aMutex); ::osl::MutexGuard aGuard(m_aMutex);
m_nDocCount = 0; m_nDocCount = 0;
::comphelper::disposeComponent( m_xDoc ); m_pCloseListener.reset(); // dispose m_xDoc
m_xDoc.clear();
OConnection::disposing(); OConnection::disposing();
} }
......
...@@ -23,9 +23,11 @@ ...@@ -23,9 +23,11 @@
#include "file/FConnection.hxx" #include "file/FConnection.hxx"
#include <com/sun/star/uno/DeploymentException.hpp> #include <com/sun/star/uno/DeploymentException.hpp>
namespace com { namespace sun { namespace star { namespace sheet { namespace com { namespace sun { namespace star {
class XSpreadsheetDocument; namespace sheet { class XSpreadsheetDocument; }
} } } } } } }
namespace utl { class CloseVeto; }
namespace connectivity namespace connectivity
...@@ -37,6 +39,8 @@ namespace connectivity ...@@ -37,6 +39,8 @@ namespace connectivity
{ {
// the spreadsheet document: // the spreadsheet document:
::com::sun::star::uno::Reference< ::com::sun::star::sheet::XSpreadsheetDocument > m_xDoc; ::com::sun::star::uno::Reference< ::com::sun::star::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_sPassword;
OUString m_aFileName; OUString m_aFileName;
oslInterlockedCount m_nDocCount; oslInterlockedCount m_nDocCount;
......
...@@ -38,7 +38,8 @@ namespace utl ...@@ -38,7 +38,8 @@ namespace utl
class UNOTOOLS_DLLPUBLIC CloseVeto class UNOTOOLS_DLLPUBLIC CloseVeto
{ {
public: public:
CloseVeto( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& i_closeable ); CloseVeto( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& i_closeable,
bool bHasOwnership = false);
~CloseVeto(); ~CloseVeto();
private: private:
......
...@@ -51,8 +51,8 @@ namespace utl ...@@ -51,8 +51,8 @@ namespace utl
class CloseListener_Impl : public CloseListener_Base class CloseListener_Impl : public CloseListener_Base
{ {
public: public:
CloseListener_Impl() CloseListener_Impl(bool const bHasOwnership)
:m_bHasOwnership( false ) : m_bHasOwnership(bHasOwnership)
{ {
} }
...@@ -107,12 +107,13 @@ namespace utl ...@@ -107,12 +107,13 @@ namespace utl
namespace namespace
{ {
void lcl_init( CloseVeto_Data& i_data, const Reference< XInterface >& i_closeable ) void lcl_init( CloseVeto_Data& i_data, const Reference< XInterface >& i_closeable,
bool const hasOwnership)
{ {
i_data.xCloseable.set( i_closeable, UNO_QUERY ); i_data.xCloseable.set( i_closeable, UNO_QUERY );
ENSURE_OR_RETURN_VOID( i_data.xCloseable.is(), "CloseVeto: the component is not closeable!" ); ENSURE_OR_RETURN_VOID( i_data.xCloseable.is(), "CloseVeto: the component is not closeable!" );
i_data.pListener = new CloseListener_Impl; i_data.pListener = new CloseListener_Impl(hasOwnership);
i_data.xCloseable->addCloseListener( i_data.pListener.get() ); i_data.xCloseable->addCloseListener( i_data.pListener.get() );
} }
...@@ -138,10 +139,11 @@ namespace utl ...@@ -138,10 +139,11 @@ namespace utl
} }
//= CloseVeto //= CloseVeto
CloseVeto::CloseVeto( const Reference< XInterface >& i_closeable ) CloseVeto::CloseVeto(const Reference< XInterface >& i_closeable,
bool const hasOwnership)
: m_xData(new CloseVeto_Data) : m_xData(new CloseVeto_Data)
{ {
lcl_init(*m_xData, i_closeable); lcl_init(*m_xData, i_closeable, hasOwnership);
} }
CloseVeto::~CloseVeto() CloseVeto::~CloseVeto()
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment