sc/inc/scmod.hxx | 8 +++++ sc/qa/unit/screenshots/screenshots.cxx | 50 +++++++++++++++++++++++++++++++++ sc/source/core/data/documen2.cxx | 12 ------- sc/source/ui/app/drwtrans.cxx | 16 +++++----- sc/source/ui/app/scmod.cxx | 26 ++++++++++++++--- sc/source/ui/app/transobj.cxx | 14 +++------ sc/source/ui/docshell/docsh.cxx | 14 +++++++++ sc/source/ui/inc/drwtrans.hxx | 2 - sc/source/ui/inc/tabvwsh.hxx | 6 +++ sc/source/ui/inc/transobj.hxx | 4 +- sc/source/ui/undo/undoblk.cxx | 2 - sc/source/ui/vba/excelvbahelper.cxx | 14 +++++++-- sc/source/ui/vba/vbarange.cxx | 6 --- sc/source/ui/view/cellsh.cxx | 24 +++++++++++---- sc/source/ui/view/cellsh1.cxx | 17 ++++------- sc/source/ui/view/cliputil.cxx | 3 - sc/source/ui/view/drawvie4.cxx | 5 ++- sc/source/ui/view/gridwin.cxx | 2 - sc/source/ui/view/viewfun3.cxx | 18 ++++++----- sc/source/ui/view/viewfun7.cxx | 3 - 20 files changed, 172 insertions(+), 74 deletions(-)
New commits: commit 8b8b1db5bcca9f6ecb1466cb4e5781c13d1e60bb Author: Henry Castro <hcas...@collabora.com> AuthorDate: Sun May 6 22:40:05 2018 -0400 Commit: Andras Timar <andras.ti...@collabora.com> CommitDate: Mon Aug 27 21:00:23 2018 +0200 tdf#117228: crash in SfxItemSet::GetItemState... (unsigned short, bool, SfxPoolItem const**) when pasting comment of closed document Re-work commit 1b7a8277aa3e9f73ccdf15e933a1ee3b42849a44. In the tiled rendering case, each view has its own clipboard, but not in desktop version which it has a shared clipboard each view. Change-Id: I57b1ab81e4c141829dbad899330e5c22204c384a Reviewed-on: https://gerrit.libreoffice.org/53922 Tested-by: Jenkins <c...@libreoffice.org> Reviewed-by: Eike Rathke <er...@redhat.com> Reviewed-on: https://gerrit.libreoffice.org/59623 Reviewed-by: Andras Timar <andras.ti...@collabora.com> Tested-by: Andras Timar <andras.ti...@collabora.com> diff --git a/sc/inc/scmod.hxx b/sc/inc/scmod.hxx index 1bf98f7078da..d0f81bf4d487 100644 --- a/sc/inc/scmod.hxx +++ b/sc/inc/scmod.hxx @@ -30,6 +30,8 @@ #include <unotools/options.hxx> #include <ooo/vba/XSinkCaller.hpp> +#include <com/sun/star/datatransfer/XTransferable2.hpp> + #include <algorithm> #include <vector> #include <map> @@ -81,6 +83,7 @@ class ScModule: public SfxModule, public SfxListener, public utl::ConfigurationL ScDragData* m_pDragData; ScSelectionTransferObj* m_pSelTransfer; ScMessagePool* m_pMessagePool; + css::uno::Reference<css::datatransfer::XTransferable2> m_xClipData; // Only used by Vba helper functions // there is no global InputHandler anymore, each View has it's own ScInputHandler* m_pRefInputHandler; ScViewCfg* m_pViewCfg; @@ -176,6 +179,11 @@ public: void SetPrintOptions ( const ScPrintOptions& rOpt ); void InsertEntryToLRUList(sal_uInt16 nFIndex); + SC_DLLPUBLIC css::uno::Reference<css::datatransfer::XTransferable2> + GetClipData() { return m_xClipData; } + SC_DLLPUBLIC void SetClipData( + const css::uno::Reference<css::datatransfer::XTransferable2>& xTransferable) { m_xClipData = xTransferable; } + static void GetSpellSettings( LanguageType& rDefLang, LanguageType& rCjkLang, LanguageType& rCtlLang, bool& rAutoSpell ); static void SetAutoSpellProperty( bool bSet ); diff --git a/sc/qa/unit/screenshots/screenshots.cxx b/sc/qa/unit/screenshots/screenshots.cxx index a9c70b2f9e2d..b27c9753d6a1 100644 --- a/sc/qa/unit/screenshots/screenshots.cxx +++ b/sc/qa/unit/screenshots/screenshots.cxx @@ -23,6 +23,7 @@ #include <osl/file.hxx> #include <sfx2/dispatch.hxx> #include <sfx2/viewfrm.hxx> +#include <sfx2/lokhelper.hxx> #include <svl/srchitem.hxx> #include <svx/numinf.hxx> #include <vcl/pngwrite.hxx> @@ -74,9 +75,11 @@ public: ScScreenshotTest(); void testOpeningModalDialogs(); + void testMultiViewCopyPaste(); CPPUNIT_TEST_SUITE(ScScreenshotTest); CPPUNIT_TEST(testOpeningModalDialogs); + CPPUNIT_TEST(testMultiViewCopyPaste); CPPUNIT_TEST_SUITE_END(); }; @@ -287,6 +290,53 @@ void ScScreenshotTest::testOpeningModalDialogs() mxComponent.clear(); } +void ScScreenshotTest::testMultiViewCopyPaste() +{ + initialize(); + + ScDocument& rDoc = mxDocSh->GetDocument(); + + rDoc.SetString(ScAddress(0, 0, 0), "TestCopy1"); + rDoc.SetString(ScAddress(1, 0, 0), "TestCopy2"); + + // view #1 + ScTabViewShell* pView1 = dynamic_cast<ScTabViewShell*>(SfxViewShell::Current()); + CPPUNIT_ASSERT(pView1); + + // view #2 + SfxLokHelper::createView(); + ScTabViewShell* pView2 = dynamic_cast<ScTabViewShell*>(SfxViewShell::Current()); + CPPUNIT_ASSERT(pView1 != pView2); + { + std::unique_ptr<SfxPoolItem> xItem1; + std::unique_ptr<SfxPoolItem> xItem2; + CPPUNIT_ASSERT(SfxItemState::DISABLED != pView1->GetViewFrame()->GetBindings().QueryState(SID_PASTE, xItem1)); + CPPUNIT_ASSERT(SfxItemState::DISABLED != pView2->GetViewFrame()->GetBindings().QueryState(SID_PASTE, xItem2)); + } + + // copy text view 1 + pView1->SetCursor(0, 0); + pView1->GetViewFrame()->GetBindings().Execute(SID_COPY); + + // copy text view 2 + pView2->SetCursor(1, 0); + pView2->GetViewFrame()->GetBindings().Execute(SID_COPY); + + // paste text view 1 + pView1->SetCursor(0, 1); + pView1->GetViewFrame()->GetBindings().Execute(SID_PASTE); + + // paste text view 2 + pView2->SetCursor(1, 1); + pView2->GetViewFrame()->GetBindings().Execute(SID_PASTE); + + CPPUNIT_ASSERT_EQUAL(OUString("TestCopy2"), rDoc.GetString(ScAddress(0, 1, 0))); + CPPUNIT_ASSERT_EQUAL(OUString("TestCopy2"), rDoc.GetString(ScAddress(1, 1, 0))); + + mxComponent->dispose(); + mxComponent.clear(); +} + CPPUNIT_TEST_SUITE_REGISTRATION(ScScreenshotTest); CPPUNIT_PLUGIN_IMPLEMENT(); diff --git a/sc/source/core/data/documen2.cxx b/sc/source/core/data/documen2.cxx index 49b3b0f4ab1e..4132fb350c2b 100644 --- a/sc/source/core/data/documen2.cxx +++ b/sc/source/core/data/documen2.cxx @@ -383,18 +383,6 @@ ScDocument::~ScDocument() pRefreshTimerControl = nullptr; } - if (IsClipboardSource()) - { - // Notes copied to the clipboard have a raw SdrCaptionObj pointer - // copied from this document, forget it as it references this - // document's drawing layer pages and what not, which otherwise when - // pasting to another document after this document was destructed would - // attempt to access non-existing data. Preserve the text data though. - ScDocument* pClipDoc = ScModule::GetClipDoc(); - if (pClipDoc) - pClipDoc->ClosingClipboardSource(); - } - mxFormulaParserPool.reset(); // Destroy the external ref mgr instance here because it has a timer // which needs to be stopped before the app closes. diff --git a/sc/source/ui/app/drwtrans.cxx b/sc/source/ui/app/drwtrans.cxx index b2ac16670efc..fdff7bd49bd3 100644 --- a/sc/source/ui/app/drwtrans.cxx +++ b/sc/source/ui/app/drwtrans.cxx @@ -236,16 +236,18 @@ ScDrawTransferObj::~ScDrawTransferObj() delete m_pDragSourceView; } -ScDrawTransferObj* ScDrawTransferObj::GetOwnClipboard( vcl::Window* pWin ) +ScDrawTransferObj* ScDrawTransferObj::GetOwnClipboard(const uno::Reference<datatransfer::XTransferable2>& xTransferable) { ScDrawTransferObj* pObj = nullptr; - TransferableDataHelper aDataHelper( TransferableDataHelper::CreateFromSystemClipboard( pWin ) ); - uno::Reference<XUnoTunnel> xTunnel( aDataHelper.GetTransferable(), uno::UNO_QUERY ); - if ( xTunnel.is() ) + if (xTransferable.is()) { - sal_Int64 nHandle = xTunnel->getSomething( getUnoTunnelId() ); - if ( nHandle ) - pObj = dynamic_cast<ScDrawTransferObj*>(reinterpret_cast<TransferableHelper*>( (sal_IntPtr) nHandle )); + uno::Reference<XUnoTunnel> xTunnel( xTransferable, uno::UNO_QUERY ); + if ( xTunnel.is() ) + { + sal_Int64 nHandle = xTunnel->getSomething( getUnoTunnelId() ); + if ( nHandle ) + pObj = dynamic_cast<ScDrawTransferObj*>(reinterpret_cast<TransferableHelper*>( static_cast<sal_IntPtr>(nHandle) )); + } } return pObj; diff --git a/sc/source/ui/app/scmod.cxx b/sc/source/ui/app/scmod.cxx index 9f24dfa60ab4..627dba2ec79f 100644 --- a/sc/source/ui/app/scmod.cxx +++ b/sc/source/ui/app/scmod.cxx @@ -71,6 +71,7 @@ #include <com/sun/star/i18n/ScriptType.hpp> #include <com/sun/star/linguistic2/XThesaurus.hpp> #include <com/sun/star/lang/Locale.hpp> +#include <com/sun/star/datatransfer/XTransferable2.hpp> #include <scmod.hxx> #include <global.hxx> @@ -663,11 +664,28 @@ void ScModule::SetDragJump( ScDocument* ScModule::GetClipDoc() { // called from document - vcl::Window* pWin = nullptr; - if( ScTabViewShell* pViewShell = dynamic_cast<ScTabViewShell*>( SfxViewShell::Current() )) - pWin = pViewShell->GetViewData().GetActiveWin(); + ScTabViewShell* pViewShell = nullptr; + const ScTransferObj* pObj = nullptr; + + if ((pViewShell = dynamic_cast<ScTabViewShell*>(SfxViewShell::Current()))) + pObj = ScTransferObj::GetOwnClipboard(pViewShell->GetClipData()); + else if ((pViewShell = dynamic_cast<ScTabViewShell*>(SfxViewShell::GetFirst()))) + pObj = ScTransferObj::GetOwnClipboard(pViewShell->GetClipData()); + else + { + css::uno::Reference<css::datatransfer::clipboard::XClipboard> xClipboard; + + if (SfxViewFrame* pViewFrame = SfxViewFrame::GetFirst()) + xClipboard = pViewFrame->GetWindow().GetClipboard(); + + if (xClipboard.is()) + { + css::uno::Reference<css::datatransfer::XTransferable2> xTransferable( + xClipboard->getContents(), css::uno::UNO_QUERY); + pObj = ScTransferObj::GetOwnClipboard(xTransferable); + } + } - ScTransferObj* pObj = ScTransferObj::GetOwnClipboard( pWin ); if (pObj) { ScDocument* pDoc = pObj->GetDocument(); diff --git a/sc/source/ui/app/transobj.cxx b/sc/source/ui/app/transobj.cxx index d350ee6a5640..8693c229d34b 100644 --- a/sc/source/ui/app/transobj.cxx +++ b/sc/source/ui/app/transobj.cxx @@ -24,6 +24,7 @@ #include <com/sun/star/uno/Sequence.hxx> #include <com/sun/star/embed/XTransactedObject.hpp> #include <com/sun/star/datatransfer/clipboard/XClipboard.hpp> +#include <com/sun/star/datatransfer/clipboard/SystemClipboard.hpp> #include <unotools/tempfile.hxx> #include <unotools/ucbstreamhelper.hxx> @@ -32,8 +33,10 @@ #include <sot/storage.hxx> #include <vcl/svapp.hxx> #include <vcl/virdev.hxx> +#include <vcl/wrkwin.hxx> #include <sfx2/app.hxx> #include <sfx2/docfile.hxx> +#include <sfx2/viewfrm.hxx> #include <transobj.hxx> #include <patattr.hxx> @@ -198,18 +201,11 @@ ScTransferObj::~ScTransferObj() } -ScTransferObj* ScTransferObj::GetOwnClipboard( vcl::Window* pUIWin ) +ScTransferObj* ScTransferObj::GetOwnClipboard(const uno::Reference<datatransfer::XTransferable2>& xTransferable) { ScTransferObj* pObj = nullptr; - uno::Reference<XTransferable> xTransferable; - uno::Reference<datatransfer::clipboard::XClipboard> xClipboard; - - if( pUIWin ) - xClipboard = pUIWin->GetClipboard(); - - if( xClipboard.is() ) + if (xTransferable.is()) { - xTransferable = xClipboard->getContents(); uno::Reference<XUnoTunnel> xTunnel( xTransferable, uno::UNO_QUERY ); if ( xTunnel.is() ) { diff --git a/sc/source/ui/docshell/docsh.cxx b/sc/source/ui/docshell/docsh.cxx index 6993c59a485d..93bdf8d2b507 100644 --- a/sc/source/ui/docshell/docsh.cxx +++ b/sc/source/ui/docshell/docsh.cxx @@ -991,6 +991,20 @@ void ScDocShell::Notify( SfxBroadcaster&, const SfxHint& rHint ) // RegisterNewTargetNames doesn't exist any longer SfxGetpApp()->Broadcast(SfxHint( SfxHintId::ScDocNameChanged )); // Navigator } + else if (rHint.GetId() == SfxHintId::Deinitializing) + { + if (aDocument.IsClipboardSource()) + { + // Notes copied to the clipboard have a raw SdrCaptionObj pointer + // copied from this document, forget it as it references this + // document's drawing layer pages and what not, which otherwise when + // pasting to another document after this document was destructed would + // attempt to access non-existing data. Preserve the text data though. + ScDocument* pClipDoc = ScModule::GetClipDoc(); + if (pClipDoc) + pClipDoc->ClosingClipboardSource(); + } + } if ( const SfxEventHint* pSfxEventHint = dynamic_cast<const SfxEventHint*>(&rHint) ) { diff --git a/sc/source/ui/inc/drwtrans.hxx b/sc/source/ui/inc/drwtrans.hxx index 586b3e910b38..135724f9a0c4 100644 --- a/sc/source/ui/inc/drwtrans.hxx +++ b/sc/source/ui/inc/drwtrans.hxx @@ -92,7 +92,7 @@ public: SdrView* GetDragSourceView() { return m_pDragSourceView; } ScDragSrc GetDragSourceFlags() const { return m_nDragSourceFlags; } - static ScDrawTransferObj* GetOwnClipboard( vcl::Window* ); + static ScDrawTransferObj* GetOwnClipboard(const css::uno::Reference<css::datatransfer::XTransferable2>&); virtual sal_Int64 SAL_CALL getSomething( const css::uno::Sequence< sal_Int8 >& rId ) override; static const css::uno::Sequence< sal_Int8 >& getUnoTunnelId(); diff --git a/sc/source/ui/inc/tabvwsh.hxx b/sc/source/ui/inc/tabvwsh.hxx index ae283f238735..9c82cbce79b9 100644 --- a/sc/source/ui/inc/tabvwsh.hxx +++ b/sc/source/ui/inc/tabvwsh.hxx @@ -167,6 +167,9 @@ private: OUString maName; OUString maScope; + // ClipData + css::uno::Reference<css::datatransfer::XTransferable2> m_xClipData; + private: void Construct( TriState nForceDesignMode ); @@ -393,6 +396,9 @@ public: static void notifyAllViewsHeaderInvalidation(bool Columns, SCTAB nCurrentTabIndex = -1); static bool isAnyEditViewInRange(bool bColumns, SCCOLROW nStart, SCCOLROW nEnd); css::uno::Reference<css::drawing::XShapes> getSelectedXShapes(); + + css::uno::Reference<css::datatransfer::XTransferable2> GetClipData() { return m_xClipData; }; + void SetClipData(const css::uno::Reference<css::datatransfer::XTransferable2>& xTransferable) { m_xClipData = xTransferable; } }; #endif diff --git a/sc/source/ui/inc/transobj.hxx b/sc/source/ui/inc/transobj.hxx index 11f218a4c5b7..ced505cc369e 100644 --- a/sc/source/ui/inc/transobj.hxx +++ b/sc/source/ui/inc/transobj.hxx @@ -78,7 +78,7 @@ public: const css::datatransfer::DataFlavor& rFlavor ) override; virtual void DragFinished( sal_Int8 nDropAction ) override; - ScDocument* GetDocument() { return m_pDoc; } // owned by ScTransferObj + ScDocument* GetDocument() const { return m_pDoc; } // owned by ScTransferObj const ScRange& GetRange() const { return m_aBlock; } SCROW GetNonFilteredRows() const { return m_nNonFiltered; } SCCOL GetDragHandleX() const { return m_nDragHandleX; } @@ -103,7 +103,7 @@ public: void SetDragWasInternal(); SC_DLLPUBLIC void SetUseInApi( bool bSet ); - static SC_DLLPUBLIC ScTransferObj* GetOwnClipboard( vcl::Window* pUIWin ); + static SC_DLLPUBLIC ScTransferObj* GetOwnClipboard(const css::uno::Reference<css::datatransfer::XTransferable2>&); static SfxObjectShell* SetDrawClipDoc( bool bAnyOle ); // update ScGlobal::xDrawClipDocShellRef virtual sal_Int64 SAL_CALL getSomething( const com::sun::star::uno::Sequence< sal_Int8 >& rId ) override; diff --git a/sc/source/ui/undo/undoblk.cxx b/sc/source/ui/undo/undoblk.cxx index a59b5d5c4177..1358d1b1f305 100644 --- a/sc/source/ui/undo/undoblk.cxx +++ b/sc/source/ui/undo/undoblk.cxx @@ -1131,7 +1131,7 @@ void ScUndoPaste::Repeat(SfxRepeatTarget& rTarget) { ScTabViewShell* pViewSh = static_cast<ScTabViewTarget&>(rTarget).GetViewShell(); // keep a reference in case the clipboard is changed during PasteFromClip - rtl::Reference<ScTransferObj> pOwnClip = ScTransferObj::GetOwnClipboard( pViewSh->GetActiveWin() ); + const ScTransferObj* pOwnClip = ScTransferObj::GetOwnClipboard(pViewSh->GetClipData()); if (pOwnClip) { pViewSh->PasteFromClip( nFlags, pOwnClip->GetDocument(), diff --git a/sc/source/ui/vba/excelvbahelper.cxx b/sc/source/ui/vba/excelvbahelper.cxx index 8dcb6e9d55f2..e4cb64b60afa 100644 --- a/sc/source/ui/vba/excelvbahelper.cxx +++ b/sc/source/ui/vba/excelvbahelper.cxx @@ -170,9 +170,13 @@ implnCopy( const uno::Reference< frame::XModel>& xModel ) pViewShell->CopyToClip(nullptr,false,false,true); // mark the copied transfer object so it is used in ScVbaRange::Insert - ScTransferObj* pClipObj = ScTransferObj::GetOwnClipboard( pViewShell->GetViewData().GetActiveWin() ); + uno::Reference<datatransfer::XTransferable2> xTransferable(pViewShell->GetClipData()); + ScTransferObj* pClipObj = ScTransferObj::GetOwnClipboard(xTransferable); if (pClipObj) + { pClipObj->SetUseInApi( true ); + SC_MOD()->SetClipData(xTransferable); + } } } @@ -185,9 +189,13 @@ implnCut( const uno::Reference< frame::XModel>& xModel ) pViewShell->CutToClip(); // mark the copied transfer object so it is used in ScVbaRange::Insert - ScTransferObj* pClipObj = ScTransferObj::GetOwnClipboard( pViewShell->GetViewData().GetActiveWin() ); + uno::Reference<datatransfer::XTransferable2> xTransferable(pViewShell->GetClipData()); + ScTransferObj* pClipObj = ScTransferObj::GetOwnClipboard(xTransferable); if (pClipObj) + { pClipObj->SetUseInApi( true ); + SC_MOD()->SetClipData(xTransferable); + } } } @@ -202,7 +210,7 @@ void implnPasteSpecial( const uno::Reference< frame::XModel>& xModel, InsertDele vcl::Window* pWin = rView.GetActiveWin(); if (pWin) { - ScTransferObj* pOwnClip = ScTransferObj::GetOwnClipboard( pWin ); + const ScTransferObj* pOwnClip = ScTransferObj::GetOwnClipboard(SC_MOD()->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 740e4f65bb7d..8c21241388d4 100644 --- a/sc/source/ui/vba/vbarange.cxx +++ b/sc/source/ui/vba/vbarange.cxx @@ -4684,11 +4684,7 @@ 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. - vcl::Window* pWin = nullptr; - if(ScTabViewShell* pViewShell = excel::getBestViewShell( getUnoModel() )) - pWin = pViewShell->GetViewData().GetActiveWin(); - - ScTransferObj* pClipObj = ScTransferObj::GetOwnClipboard( pWin ); + const ScTransferObj* pClipObj = ScTransferObj::GetOwnClipboard(SC_MOD()->GetClipData()); if ( pClipObj && pClipObj->GetUseInApi() ) { // After the insert ( this range ) actually has moved diff --git a/sc/source/ui/view/cellsh.cxx b/sc/source/ui/view/cellsh.cxx index 2fd9a2beed93..f0b2b3e209c6 100644 --- a/sc/source/ui/view/cellsh.cxx +++ b/sc/source/ui/view/cellsh.cxx @@ -448,7 +448,7 @@ static bool lcl_TestFormat( SvxClipboardFormatItem& rFormats, const Transferable void ScCellShell::GetPossibleClipboardFormats( SvxClipboardFormatItem& rFormats ) { vcl::Window* pWin = GetViewData()->GetActiveWin(); - bool bDraw = ScDrawTransferObj::GetOwnClipboard( pWin ) != nullptr; + bool bDraw = ScDrawTransferObj::GetOwnClipboard(GetViewData()->GetViewShell()->GetClipData()) != nullptr; TransferableDataHelper aDataHelper( TransferableDataHelper::CreateFromSystemClipboard( pWin ) ); @@ -479,10 +479,10 @@ void ScCellShell::GetPossibleClipboardFormats( SvxClipboardFormatItem& rFormats // insert, insert contents -static bool lcl_IsCellPastePossible( const TransferableDataHelper& rData, vcl::Window* pWin ) +static bool lcl_IsCellPastePossible( const TransferableDataHelper& rData, ScTabViewShell* pViewShell ) { bool bPossible = false; - if ( ScTransferObj::GetOwnClipboard( pWin ) || ScDrawTransferObj::GetOwnClipboard( pWin ) ) + if ( ScTransferObj::GetOwnClipboard(pViewShell->GetClipData()) || ScDrawTransferObj::GetOwnClipboard(pViewShell->GetClipData()) ) bPossible = true; else { @@ -521,7 +521,19 @@ bool ScCellShell::HasClipboardFormat( SotClipboardFormatId nFormatId ) IMPL_LINK( ScCellShell, ClipboardChanged, TransferableDataHelper*, pDataHelper, void ) { - bPastePossible = lcl_IsCellPastePossible( *pDataHelper, GetViewData()->GetActiveWin() ); + ScTabViewShell* pViewShell = GetViewData()->GetViewShell(); + css::uno::Reference<css::datatransfer::XTransferable2> xOldTransfer(pViewShell->GetClipData()); + css::uno::Reference<css::datatransfer::XTransferable2> xNewTransfer(pDataHelper->GetXTransferable(), css::uno::UNO_QUERY); + + if ( xNewTransfer.get() != xOldTransfer.get() ) + { + if ( ScTransferObj::GetOwnClipboard(xNewTransfer) || ScDrawTransferObj::GetOwnClipboard(xNewTransfer) ) + pViewShell->SetClipData(xNewTransfer); + else + pViewShell->SetClipData(css::uno::Reference<css::datatransfer::XTransferable2>()); + } + + bPastePossible = lcl_IsCellPastePossible( *pDataHelper, pViewShell ); SfxBindings& rBindings = GetViewData()->GetBindings(); rBindings.Invalidate( SID_PASTE ); @@ -556,7 +568,7 @@ bool checkDestRanges(ScViewData& rViewData) if (!pWin) return false; - ScTransferObj* pOwnClip = ScTransferObj::GetOwnClipboard(pWin); + const ScTransferObj* pOwnClip = ScTransferObj::GetOwnClipboard(rViewData.GetViewShell()->GetClipData()); if (!pOwnClip) // If it's not a Calc document, we won't be picky. return true; @@ -595,7 +607,7 @@ void ScCellShell::GetClipState( SfxItemSet& rSet ) // get initial state TransferableDataHelper aDataHelper( TransferableDataHelper::CreateFromSystemClipboard( pWin ) ); - bPastePossible = lcl_IsCellPastePossible( aDataHelper, pWin ); + bPastePossible = lcl_IsCellPastePossible( aDataHelper, GetViewData()->GetViewShell() ); } bool bDisable = !bPastePossible; diff --git a/sc/source/ui/view/cellsh1.cxx b/sc/source/ui/view/cellsh1.cxx index b94d79208a24..85b17057d803 100644 --- a/sc/source/ui/view/cellsh1.cxx +++ b/sc/source/ui/view/cellsh1.cxx @@ -1309,9 +1309,8 @@ void ScCellShell::ExecuteEdit( SfxRequest& rReq ) if ( nFormat != SotClipboardFormatId::NONE ) { - vcl::Window* pWin = GetViewData()->GetActiveWin(); - bool bCells = ( ScTransferObj::GetOwnClipboard( pWin ) != nullptr ); - bool bDraw = ( ScDrawTransferObj::GetOwnClipboard( pWin ) != nullptr ); + bool bCells = ( ScTransferObj::GetOwnClipboard(GetViewData()->GetViewShell()->GetClipData()) != nullptr ); + bool bDraw = ( ScDrawTransferObj::GetOwnClipboard(GetViewData()->GetViewShell()->GetClipData()) != nullptr ); bool bOle = ( nFormat == SotClipboardFormatId::EMBED_SOURCE ); if ( bCells && bOle ) @@ -1335,11 +1334,10 @@ void ScCellShell::ExecuteEdit( SfxRequest& rReq ) ScPasteFunc nFunction = ScPasteFunc::NONE; InsCellCmd eMoveMode = INS_NONE; - vcl::Window* pWin = GetViewData()->GetActiveWin(); ScDocument* pDoc = GetViewData()->GetDocument(); bool bOtherDoc = !pDoc->IsClipboardSource(); // keep a reference in case the clipboard is changed during dialog or PasteFromClip - rtl::Reference<ScTransferObj> pOwnClip = ScTransferObj::GetOwnClipboard( pWin ); + const ScTransferObj* pOwnClip = ScTransferObj::GetOwnClipboard(GetViewData()->GetViewShell()->GetClipData()); if ( pOwnClip ) { bool bSkipEmpty = false; @@ -1526,8 +1524,7 @@ void ScCellShell::ExecuteEdit( SfxRequest& rReq ) case SID_PASTE_ONLY_TEXT: case SID_PASTE_ONLY_FORMULA: { - vcl::Window* pWin = GetViewData()->GetActiveWin(); - if ( ScTransferObj::GetOwnClipboard( pWin ) ) // own cell data + if ( ScTransferObj::GetOwnClipboard(GetViewData()->GetViewShell()->GetClipData()) ) // own cell data { rReq.SetSlot( FID_INS_CELL_CONTENTS ); OUString aFlags; @@ -1562,7 +1559,7 @@ void ScCellShell::ExecuteEdit( SfxRequest& rReq ) bool bRet=true; { WaitObject aWait( GetViewData()->GetDialogParent() ); - bool bDraw = ( ScDrawTransferObj::GetOwnClipboard( pWin ) != nullptr ); + bool bDraw = ( ScDrawTransferObj::GetOwnClipboard(GetViewData()->GetViewShell()->GetClipData()) != nullptr ); if ( bDraw && nFormat == SotClipboardFormatId::EMBED_SOURCE ) pTabViewShell->PasteDraw(); else @@ -1581,7 +1578,7 @@ void ScCellShell::ExecuteEdit( SfxRequest& rReq ) if ( !pItem ) { - if ( ScTransferObj::GetOwnClipboard( pWin ) ) // own cell data + if ( ScTransferObj::GetOwnClipboard(GetViewData()->GetViewShell()->GetClipData()) ) // own cell data { rReq.SetSlot( FID_INS_CELL_CONTENTS ); ExecuteSlot( rReq, GetInterface() ); @@ -1589,7 +1586,7 @@ void ScCellShell::ExecuteEdit( SfxRequest& rReq ) } else // draw objects or external data { - bool bDraw = ( ScDrawTransferObj::GetOwnClipboard( pWin ) != nullptr ); + bool bDraw = ( ScDrawTransferObj::GetOwnClipboard(GetViewData()->GetViewShell()->GetClipData()) != nullptr ); SvxClipboardFormatItem aFormats( SID_CLIPBOARD_FORMAT_ITEMS ); GetPossibleClipboardFormats( aFormats ); diff --git a/sc/source/ui/view/cliputil.cxx b/sc/source/ui/view/cliputil.cxx index 4eead7dee2f3..a0d22cbb12fe 100644 --- a/sc/source/ui/view/cliputil.cxx +++ b/sc/source/ui/view/cliputil.cxx @@ -46,8 +46,7 @@ bool lcl_checkClassification(ScDocument* pSourceDoc, const ScDocument* pDestinat void ScClipUtil::PasteFromClipboard( ScViewData* pViewData, ScTabViewShell* pTabViewShell, bool bShowDialog ) { - vcl::Window* pWin = pViewData->GetActiveWin(); - ScTransferObj* pOwnClip = ScTransferObj::GetOwnClipboard( pWin ); + const ScTransferObj* pOwnClip = ScTransferObj::GetOwnClipboard(pTabViewShell->GetClipData()); ScDocument* pThisDoc = pViewData->GetDocument(); ScDPObject* pDPObj = pThisDoc->GetDPAtCursor( pViewData->GetCurX(), pViewData->GetCurY(), pViewData->GetTabNo() ); diff --git a/sc/source/ui/view/drawvie4.cxx b/sc/source/ui/view/drawvie4.cxx index 72f06667ce34..b4b12bca3d9a 100644 --- a/sc/source/ui/view/drawvie4.cxx +++ b/sc/source/ui/view/drawvie4.cxx @@ -40,6 +40,7 @@ #include <globstr.hrc> #include <chartarr.hxx> #include <gridwin.hxx> +#include <tabvwsh.hxx> #include <com/sun/star/embed/NoVisualAreaSizeException.hpp> #include <com/sun/star/embed/Aspects.hpp> @@ -368,13 +369,15 @@ void ScDrawView::DoCopy() aObjDesc.maDisplayName = pDocSh->GetMedium()->GetURLObject().GetURLNoPass(); // maSize is set in ScDrawTransferObj ctor - rtl::Reference<ScDrawTransferObj> pTransferObj = new ScDrawTransferObj( pModel, pDocSh, aObjDesc ); + ScDrawTransferObj* pTransferObj = new ScDrawTransferObj( pModel, pDocSh, aObjDesc ); + uno::Reference<css::datatransfer::XTransferable2> xTransferObj = pTransferObj; if ( ScGlobal::xDrawClipDocShellRef.is() ) { pTransferObj->SetDrawPersist( ScGlobal::xDrawClipDocShellRef.get() ); // keep persist for ole objects alive } + pViewData->GetViewShell()->SetClipData(xTransferObj); // internal clipboard pTransferObj->CopyToClipboard( pViewData->GetActiveWin() ); // system clipboard } diff --git a/sc/source/ui/view/gridwin.cxx b/sc/source/ui/view/gridwin.cxx index 07b0f096ec8d..4e73792f1fc8 100644 --- a/sc/source/ui/view/gridwin.cxx +++ b/sc/source/ui/view/gridwin.cxx @@ -5778,7 +5778,7 @@ void ScGridWindow::UpdateCopySourceOverlay() rtl::Reference<sdr::overlay::OverlayManager> xOverlayManager = getOverlayManager(); if (!xOverlayManager.is()) return; - ScTransferObj* pTransObj = ScTransferObj::GetOwnClipboard( pViewData->GetActiveWin() ); + const ScTransferObj* pTransObj = ScTransferObj::GetOwnClipboard(pViewData->GetViewShell()->GetClipData()); if (!pTransObj) return; ScDocument* pClipDoc = pTransObj->GetDocument(); diff --git a/sc/source/ui/view/viewfun3.cxx b/sc/source/ui/view/viewfun3.cxx index 2c50bdfff97b..d026daa27f0b 100644 --- a/sc/source/ui/view/viewfun3.cxx +++ b/sc/source/ui/view/viewfun3.cxx @@ -272,13 +272,15 @@ bool ScViewFunc::CopyToClip( ScDocument* pClipDoc, const ScRangeList& rRanges, b aObjDesc.maDisplayName = pDocSh->GetMedium()->GetURLObject().GetURLNoPass(); // maSize is set in ScTransferObj ctor - rtl::Reference<ScTransferObj> pTransferObj = new ScTransferObj( pClipDoc, aObjDesc ); + ScTransferObj* pTransferObj = new ScTransferObj( pClipDoc, aObjDesc ); + uno::Reference<css::datatransfer::XTransferable2> xTransferObj = pTransferObj; if ( ScGlobal::xDrawClipDocShellRef.is() ) { SfxObjectShellRef aPersistRef( ScGlobal::xDrawClipDocShellRef.get() ); pTransferObj->SetDrawPersist( aPersistRef );// keep persist for ole objects alive } + GetViewData().GetViewShell()->SetClipData(xTransferObj); pTransferObj->CopyToClipboard( GetActiveWin() ); } @@ -378,14 +380,14 @@ bool ScViewFunc::CopyToClip( ScDocument* pClipDoc, const ScRangeList& rRanges, b aObjDesc.maDisplayName = pDocSh->GetMedium()->GetURLObject().GetURLNoPass(); // maSize is set in ScTransferObj ctor - rtl::Reference<ScTransferObj> pTransferObj = new ScTransferObj( pDocClip.release(), aObjDesc ); - + ScTransferObj* pTransferObj = new ScTransferObj( pDocClip.release(), aObjDesc ); + uno::Reference<css::datatransfer::XTransferable2> xTransferObj = pTransferObj; if ( ScGlobal::xDrawClipDocShellRef.is() ) { SfxObjectShellRef aPersistRef( ScGlobal::xDrawClipDocShellRef.get() ); pTransferObj->SetDrawPersist( aPersistRef ); // keep persist for ole objects alive } - + GetViewData().GetViewShell()->SetClipData(xTransferObj); pTransferObj->CopyToClipboard( GetActiveWin() ); // system clipboard } @@ -447,7 +449,7 @@ void ScViewFunc::PasteDraw() vcl::Window* pWin = GetActiveWin(); Point aPos = pWin->PixelToLogic( rViewData.GetScrPos( nPosX, nPosY, rViewData.GetActivePart() ) ); - ScDrawTransferObj* pDrawClip = ScDrawTransferObj::GetOwnClipboard( pWin ); + ScDrawTransferObj* pDrawClip = ScDrawTransferObj::GetOwnClipboard(GetViewData().GetViewShell()->GetClipData()); if (pDrawClip) { OUString aSrcShellID = pDrawClip->GetShellID(); @@ -461,9 +463,9 @@ void ScViewFunc::PasteFromSystem() UpdateInputLine(); vcl::Window* pWin = GetActiveWin(); - ScTransferObj* pOwnClip = ScTransferObj::GetOwnClipboard( pWin ); + const ScTransferObj* pOwnClip = ScTransferObj::GetOwnClipboard(GetViewData().GetViewShell()->GetClipData()); // keep a reference in case the clipboard is changed during PasteFromClip - rtl::Reference<ScDrawTransferObj> pDrawClip = ScDrawTransferObj::GetOwnClipboard( pWin ); + const ScDrawTransferObj* pDrawClip = ScDrawTransferObj::GetOwnClipboard(GetViewData().GetViewShell()->GetClipData()); if (pOwnClip) { PasteFromClip( InsertDeleteFlags::ALL, pOwnClip->GetDocument(), @@ -706,7 +708,7 @@ bool ScViewFunc::PasteFromSystem( SotClipboardFormatId nFormatId, bool bApi ) bool bRet = true; vcl::Window* pWin = GetActiveWin(); // keep a reference in case the clipboard is changed during PasteFromClip - rtl::Reference<ScTransferObj> pOwnClip = ScTransferObj::GetOwnClipboard( pWin ); + const ScTransferObj* pOwnClip = ScTransferObj::GetOwnClipboard(GetViewData().GetViewShell()->GetClipData()); if ( nFormatId == SotClipboardFormatId::NONE && pOwnClip ) { PasteFromClip( InsertDeleteFlags::ALL, pOwnClip->GetDocument(), diff --git a/sc/source/ui/view/viewfun7.cxx b/sc/source/ui/view/viewfun7.cxx index af02d1adc969..525fb738cd6d 100644 --- a/sc/source/ui/view/viewfun7.cxx +++ b/sc/source/ui/view/viewfun7.cxx @@ -249,9 +249,8 @@ void ScViewFunc::PasteDraw( const Point& rLogicPos, SdrModel* pModel, ScDocument* pDocument = GetViewData().GetDocument(); ScDocShell* pDocShell = GetViewData().GetDocShell(); - vcl::Window* pWin = GetViewData().GetActiveWin(); ScModelObj* pModelObj = ( pDocShell ? ScModelObj::getImplementation( pDocShell->GetModel() ) : nullptr ); - ScDrawTransferObj* pTransferObj = ScDrawTransferObj::GetOwnClipboard( pWin ); + const ScDrawTransferObj* pTransferObj = ScDrawTransferObj::GetOwnClipboard(GetViewData().GetViewShell()->GetClipData()); if ( pDocument && pPage && pModelObj && ( pTransferObj || pDrawTrans ) ) { const ScRangeListVector& rProtectedChartRangesVector( _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits