[Libreoffice-commits] core.git: sc/inc sc/qa sc/source

Henry Castro hcastro at collabora.com
Wed May 23 11:19:47 UTC 2018


 sc/inc/scmod.hxx                       |   10 +++++-
 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          |    4 +-
 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, 174 insertions(+), 76 deletions(-)

New commits:
commit a2e6f31c6f90e446d1462e7c80f6b1317f7825bc
Author: Henry Castro <hcastro at collabora.com>
Date:   Sun May 6 22:40:05 2018 -0400

    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 <ci at libreoffice.org>
    Reviewed-by: Eike Rathke <erack at redhat.com>

diff --git a/sc/inc/scmod.hxx b/sc/inc/scmod.hxx
index 253c5cb637e0..76e512424d89 100644
--- a/sc/inc/scmod.hxx
+++ b/sc/inc/scmod.hxx
@@ -29,6 +29,8 @@
 #include "shellids.hxx"
 #include <unotools/options.hxx>
 
+#include <com/sun/star/datatransfer/XTransferable2.hpp>
+
 #include <algorithm>
 #include <vector>
 #include <map>
@@ -80,7 +82,8 @@ class ScModule: public SfxModule, public SfxListener, public utl::ConfigurationL
     ScDragData*         m_pDragData;
     ScSelectionTransferObj* m_pSelTransfer;
     ScMessagePool*      m_pMessagePool;
-    // there is no global InputHandler anymore, each View has its own
+    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;
     ScDocCfg*           m_pDocCfg;
@@ -172,6 +175,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 59a10ef21dd9..9eb753dd61fd 100644
--- a/sc/qa/unit/screenshots/screenshots.cxx
+++ b/sc/qa/unit/screenshots/screenshots.cxx
@@ -20,6 +20,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>
@@ -72,9 +73,11 @@ public:
     ScScreenshotTest();
 
     void testOpeningModalDialogs();
+    void testMultiViewCopyPaste();
 
     CPPUNIT_TEST_SUITE(ScScreenshotTest);
     CPPUNIT_TEST(testOpeningModalDialogs);
+    CPPUNIT_TEST(testMultiViewCopyPaste);
     CPPUNIT_TEST_SUITE_END();
 };
 
@@ -286,6 +289,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 7bbf5ccf7c94..ba48bff57ced 100644
--- a/sc/source/core/data/documen2.cxx
+++ b/sc/source/core/data/documen2.cxx
@@ -376,18 +376,6 @@ ScDocument::~ScDocument()
         pRefreshTimerControl.reset();
     }
 
-    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 0f6d0d62a0da..8d00e3f59f65 100644
--- a/sc/source/ui/app/drwtrans.cxx
+++ b/sc/source/ui/app/drwtrans.cxx
@@ -236,16 +236,18 @@ ScDrawTransferObj::~ScDrawTransferObj()
     m_pDragSourceView.reset();
 }
 
-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*>( static_cast<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 dd096a53655c..fc8145365871 100644
--- a/sc/source/ui/app/scmod.cxx
+++ b/sc/source/ui/app/scmod.cxx
@@ -70,6 +70,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>
@@ -661,11 +662,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 37d37b9fd2e1..febb0793c980 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>
@@ -33,8 +34,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 e83aad315aec..b814ddceb6b9 100644
--- a/sc/source/ui/docshell/docsh.cxx
+++ b/sc/source/ui/docshell/docsh.cxx
@@ -1018,6 +1018,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();
+        }
+    }
 }
 
 // Load contents for organizer
diff --git a/sc/source/ui/inc/drwtrans.hxx b/sc/source/ui/inc/drwtrans.hxx
index 7550575a33b0..e403e967b7c8 100644
--- a/sc/source/ui/inc/drwtrans.hxx
+++ b/sc/source/ui/inc/drwtrans.hxx
@@ -79,7 +79,7 @@ public:
                                         const css::datatransfer::DataFlavor& rFlavor ) override;
     virtual void        DragFinished( sal_Int8 nDropAction ) override;
 
-    SdrModel*           GetModel()  { return m_pModel.get(); }
+    SdrModel*           GetModel() const { return m_pModel.get(); }
 
     void                SetDrawPersist( const SfxObjectShellRef& rRef );
     void                SetDragSource( const ScDrawView* pView );
@@ -92,7 +92,7 @@ public:
     SdrView*            GetDragSourceView()             { return m_pDragSourceView.get(); }
     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 8a897123a89c..0c6bb6b119ec 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 );
 
@@ -391,6 +394,9 @@ public:
     static void notifyAllViewsHeaderInvalidation(bool Columns, SCTAB nCurrentTabIndex);
     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 20632b5abd77..107fe23fd21f 100644
--- a/sc/source/ui/undo/undoblk.cxx
+++ b/sc/source/ui/undo/undoblk.cxx
@@ -1132,7 +1132,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 869f40a7c756..2ad45a3716a8 100644
--- a/sc/source/ui/vba/vbarange.cxx
+++ b/sc/source/ui/vba/vbarange.cxx
@@ -4681,11 +4681,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 9e546006803f..c247fdbf3332 100644
--- a/sc/source/ui/view/cellsh.cxx
+++ b/sc/source/ui/view/cellsh.cxx
@@ -447,7 +447,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 ) );
 
@@ -478,10 +478,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
     {
@@ -520,7 +520,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 );
@@ -555,7 +567,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;
@@ -594,7 +606,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 896465c74933..feb677e6a335 100644
--- a/sc/source/ui/view/cellsh1.cxx
+++ b/sc/source/ui/view/cellsh1.cxx
@@ -1312,9 +1312,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 )
@@ -1338,11 +1337,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;
@@ -1497,8 +1495,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;
@@ -1533,7 +1530,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
@@ -1552,7 +1549,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() );
@@ -1560,7 +1557,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 f3cd331e94e3..254352de014f 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 83fcb408c9a4..2a6aec9af9b7 100644
--- a/sc/source/ui/view/drawvie4.cxx
+++ b/sc/source/ui/view/drawvie4.cxx
@@ -42,6 +42,7 @@
 #include <chartarr.hxx>
 #include <gridwin.hxx>
 #include <userdat.hxx>
+#include <tabvwsh.hxx>
 
 #include <com/sun/star/embed/NoVisualAreaSizeException.hpp>
 #include <com/sun/star/embed/Aspects.hpp>
@@ -370,13 +371,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 64f8012891d6..96a3f7e16239 100644
--- a/sc/source/ui/view/gridwin.cxx
+++ b/sc/source/ui/view/gridwin.cxx
@@ -5738,7 +5738,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 e80d79d7122a..3cfccc50c760 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 );
+    const 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 8bc10782a632..b264ac317289 100644
--- a/sc/source/ui/view/viewfun7.cxx
+++ b/sc/source/ui/view/viewfun7.cxx
@@ -252,9 +252,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(


More information about the Libreoffice-commits mailing list