diff options
author | Henry Castro <hcastro@collabora.com> | 2018-05-17 11:12:56 -0400 |
---|---|---|
committer | Andras Timar <andras.timar@collabora.com> | 2018-08-27 21:17:59 +0200 |
commit | 16bbe4cddecb407203a754284ce538195d4f06e1 (patch) | |
tree | a0245e197f423421ebb82de0a275226ccf05cd41 /sc/source | |
parent | 8b8b1db5bcca9f6ecb1466cb4e5781c13d1e60bb (diff) |
sc: release XTransferable2 when used with VBA compatibility helpers
Copy, Cut, PasteSpecial and Insert is used by Range excel object,
so after finishing executing the VBA script ensure to release XTransferable2
interface
Change-Id: I967a7ba1a1d101282f7a1b9d4b2e2ac3004f1c07
Reviewed-on: https://gerrit.libreoffice.org/54497
Tested-by: Jenkins <ci@libreoffice.org>
Reviewed-by: Henry Castro <hcastro@collabora.com>
Reviewed-on: https://gerrit.libreoffice.org/59624
Reviewed-by: Andras Timar <andras.timar@collabora.com>
Tested-by: Andras Timar <andras.timar@collabora.com>
Diffstat (limited to 'sc/source')
-rw-r--r-- | sc/source/ui/docshell/docsh.cxx | 47 | ||||
-rw-r--r-- | sc/source/ui/inc/docsh.hxx | 10 | ||||
-rw-r--r-- | sc/source/ui/vba/excelvbahelper.cxx | 15 | ||||
-rw-r--r-- | sc/source/ui/vba/vbarange.cxx | 3 |
4 files changed, 68 insertions, 7 deletions
diff --git a/sc/source/ui/docshell/docsh.cxx b/sc/source/ui/docshell/docsh.cxx index 93bdf8d2b507..a1bab9b3fb62 100644 --- a/sc/source/ui/docshell/docsh.cxx +++ b/sc/source/ui/docshell/docsh.cxx @@ -47,7 +47,10 @@ #include <com/sun/star/container/XContentEnumerationAccess.hpp> #include <com/sun/star/document/UpdateDocMode.hpp> #include <com/sun/star/script/vba/VBAEventId.hpp> +#include <com/sun/star/script/vba/VBAScriptEventId.hpp> #include <com/sun/star/script/vba/XVBAEventProcessor.hpp> +#include <com/sun/star/script/vba/XVBAScriptListener.hpp> +#include <com/sun/star/script/vba/XVBACompatibility.hpp> #include <com/sun/star/sheet/XSpreadsheetView.hpp> #include <com/sun/star/task/XJob.hpp> #include <com/sun/star/ui/theModuleUIConfigurationManagerSupplier.hpp> @@ -427,6 +430,31 @@ void processDataStream( ScDocShell& rShell, const sc::ImportPostProcessData& rDa rMgr.setDataStream(pStrm); } +class VBAScriptListener : public ::cppu::WeakImplHelper< css::script::vba::XVBAScriptListener > +{ +private: + ScDocShell* m_pDocSh; +public: + VBAScriptListener(ScDocShell* pDocSh) : m_pDocSh(pDocSh) + { + } + + // XVBAScriptListener + virtual void SAL_CALL notifyVBAScriptEvent( const ::css::script::vba::VBAScriptEvent& aEvent ) override + { + if (aEvent.Identifier == script::vba::VBAScriptEventId::SCRIPT_STOPPED && + m_pDocSh->GetClipData().is()) + { + m_pDocSh->SetClipData(uno::Reference<datatransfer::XTransferable2>()); + } + } + + // XEventListener + virtual void SAL_CALL disposing( const ::css::lang::EventObject& /*Source*/ ) override + { + } +}; + } bool ScDocShell::LoadXML( SfxMedium* pLoadMedium, const css::uno::Reference< css::embed::XStorage >& xStor ) @@ -672,6 +700,7 @@ void ScDocShell::Notify( SfxBroadcaster&, const SfxHint& rHint ) else if ( dynamic_cast<const SfxEventHint*>(&rHint) ) { SfxEventHintId nEventId = static_cast<const SfxEventHint*>(&rHint)->GetEventId(); + switch ( nEventId ) { case SfxEventHintId::LoadFinished: @@ -701,6 +730,15 @@ void ScDocShell::Notify( SfxBroadcaster&, const SfxHint& rHint ) break; case SfxEventHintId::ViewCreated: { + #if HAVE_FEATURE_SCRIPTING + uno::Reference<script::vba::XVBACompatibility> xVBACompat(GetBasicContainer(), uno::UNO_QUERY); + if ( !m_xVBAListener.is() && xVBACompat.is() ) + { + m_xVBAListener.set(new VBAScriptListener(this)); + xVBACompat->addVBAScriptListener(m_xVBAListener); + } +#endif + #if HAVE_FEATURE_MULTIUSER_ENVIRONMENT if ( IsDocShared() && !SC_MOD()->IsInSharedDocLoading() ) { @@ -993,6 +1031,15 @@ void ScDocShell::Notify( SfxBroadcaster&, const SfxHint& rHint ) } else if (rHint.GetId() == SfxHintId::Deinitializing) { + +#if HAVE_FEATURE_SCRIPTING + uno::Reference<script::vba::XVBACompatibility> xVBACompat(GetBasicContainer(), uno::UNO_QUERY); + if (m_xVBAListener.is() && xVBACompat.is()) + { + xVBACompat->removeVBAScriptListener(m_xVBAListener); + } +#endif + if (aDocument.IsClipboardSource()) { // Notes copied to the clipboard have a raw SdrCaptionObj pointer diff --git a/sc/source/ui/inc/docsh.hxx b/sc/source/ui/inc/docsh.hxx index ebd07bb18279..62723b131910 100644 --- a/sc/source/ui/inc/docsh.hxx +++ b/sc/source/ui/inc/docsh.hxx @@ -65,6 +65,10 @@ class ScFlatBoolRowSegments; class HelperModelObj; struct ScColWidthParam; +namespace com { namespace sun { namespace star { namespace script { namespace vba { + class XVBAScriptListener; +} } } } } + namespace sfx2 { class FileDialogHelper; } struct DocShell_Impl; @@ -111,6 +115,9 @@ class SC_DLLPUBLIC ScDocShell final: public SfxObjectShell, public SfxListener ScDocShellModificator* pModificator; // #109979#; is used to load XML (created in BeforeXMLLoading and destroyed in AfterXMLLoading) css::uno::Reference< ooo::vba::excel::XWorkbook> mxAutomationWorkbookObject; + // Only used by Vba helper functions + css::uno::Reference<css::script::vba::XVBAScriptListener> m_xVBAListener; + css::uno::Reference<css::datatransfer::XTransferable2> m_xClipData; SAL_DLLPRIVATE void InitItems(); SAL_DLLPRIVATE void DoEnterHandler(); @@ -219,6 +226,9 @@ public: ScDocument& GetDocument() { return aDocument; } ScDocFunc& GetDocFunc() { return *pDocFunc; } + css::uno::Reference<css::datatransfer::XTransferable2> GetClipData() { return m_xClipData; } + void SetClipData(const css::uno::Reference<css::datatransfer::XTransferable2>& xTransferable) { m_xClipData = xTransferable; } + SfxPrinter* GetPrinter( bool bCreateIfNotExist = true ); sal_uInt16 SetPrinter( VclPtr<SfxPrinter> const & pNewPrinter, SfxPrinterChangeFlags nDiffFlags = SFX_PRINTER_ALL ); diff --git a/sc/source/ui/vba/excelvbahelper.cxx b/sc/source/ui/vba/excelvbahelper.cxx index e4cb64b60afa..0bcd3fb9aa0f 100644 --- a/sc/source/ui/vba/excelvbahelper.cxx +++ b/sc/source/ui/vba/excelvbahelper.cxx @@ -165,7 +165,8 @@ void implnCopy( const uno::Reference< frame::XModel>& xModel ) { ScTabViewShell* pViewShell = getBestViewShell( xModel ); - if ( pViewShell ) + ScDocShell* pDocShell = getDocShell( xModel ); + if ( pViewShell && pDocShell ) { pViewShell->CopyToClip(nullptr,false,false,true); @@ -175,7 +176,7 @@ implnCopy( const uno::Reference< frame::XModel>& xModel ) if (pClipObj) { pClipObj->SetUseInApi( true ); - SC_MOD()->SetClipData(xTransferable); + pDocShell->SetClipData(xTransferable); } } } @@ -184,7 +185,8 @@ void implnCut( const uno::Reference< frame::XModel>& xModel ) { ScTabViewShell* pViewShell = getBestViewShell( xModel ); - if ( pViewShell ) + ScDocShell* pDocShell = getDocShell( xModel ); + if ( pViewShell && pDocShell ) { pViewShell->CutToClip(); @@ -194,7 +196,7 @@ implnCut( const uno::Reference< frame::XModel>& xModel ) if (pClipObj) { pClipObj->SetUseInApi( true ); - SC_MOD()->SetClipData(xTransferable); + pDocShell->SetClipData(xTransferable); } } } @@ -204,13 +206,14 @@ void implnPasteSpecial( const uno::Reference< frame::XModel>& xModel, InsertDele PasteCellsWarningReseter resetWarningBox; ScTabViewShell* pTabViewShell = getBestViewShell( xModel ); - if ( pTabViewShell ) + ScDocShell* pDocShell = getDocShell( xModel ); + if ( pTabViewShell && pDocShell ) { ScViewData& rView = pTabViewShell->GetViewData(); vcl::Window* pWin = rView.GetActiveWin(); if (pWin) { - const ScTransferObj* pOwnClip = ScTransferObj::GetOwnClipboard(SC_MOD()->GetClipData()); + const ScTransferObj* pOwnClip = ScTransferObj::GetOwnClipboard(pDocShell->GetClipData()); ScDocument* pDoc = nullptr; if ( pOwnClip ) pDoc = pOwnClip->GetDocument(); diff --git a/sc/source/ui/vba/vbarange.cxx b/sc/source/ui/vba/vbarange.cxx index 8c21241388d4..17f55b9eafb6 100644 --- a/sc/source/ui/vba/vbarange.cxx +++ b/sc/source/ui/vba/vbarange.cxx @@ -4684,7 +4684,8 @@ ScVbaRange::Insert( const uno::Any& Shift, const uno::Any& /*CopyOrigin*/ ) // Paste from clipboard only if the clipboard content was copied via VBA, and not already pasted via VBA again. // "Insert" behavior should not depend on random clipboard content previously copied by the user. - const ScTransferObj* pClipObj = ScTransferObj::GetOwnClipboard(SC_MOD()->GetClipData()); + ScDocShell* pDocShell = getDocShellFromRange( mxRange ); + const ScTransferObj* pClipObj = pDocShell ? ScTransferObj::GetOwnClipboard(pDocShell->GetClipData()) : nullptr; if ( pClipObj && pClipObj->GetUseInApi() ) { // After the insert ( this range ) actually has moved |