summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHenry Castro <hcastro@collabora.com>2018-05-06 22:40:05 -0400
committerEike Rathke <erack@redhat.com>2018-05-23 13:19:20 +0200
commita2e6f31c6f90e446d1462e7c80f6b1317f7825bc (patch)
tree3e009520526d97336d29ba6a45fb1ff22e7b14f5
parent40cf5a9b3dd619a650a94d8b65bf6987125b75fb (diff)
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@libreoffice.org> Reviewed-by: Eike Rathke <erack@redhat.com>
-rw-r--r--sc/inc/scmod.hxx10
-rw-r--r--sc/qa/unit/screenshots/screenshots.cxx50
-rw-r--r--sc/source/core/data/documen2.cxx12
-rw-r--r--sc/source/ui/app/drwtrans.cxx16
-rw-r--r--sc/source/ui/app/scmod.cxx26
-rw-r--r--sc/source/ui/app/transobj.cxx14
-rw-r--r--sc/source/ui/docshell/docsh.cxx14
-rw-r--r--sc/source/ui/inc/drwtrans.hxx4
-rw-r--r--sc/source/ui/inc/tabvwsh.hxx6
-rw-r--r--sc/source/ui/inc/transobj.hxx4
-rw-r--r--sc/source/ui/undo/undoblk.cxx2
-rw-r--r--sc/source/ui/vba/excelvbahelper.cxx14
-rw-r--r--sc/source/ui/vba/vbarange.cxx6
-rw-r--r--sc/source/ui/view/cellsh.cxx24
-rw-r--r--sc/source/ui/view/cellsh1.cxx17
-rw-r--r--sc/source/ui/view/cliputil.cxx3
-rw-r--r--sc/source/ui/view/drawvie4.cxx5
-rw-r--r--sc/source/ui/view/gridwin.cxx2
-rw-r--r--sc/source/ui/view/viewfun3.cxx18
-rw-r--r--sc/source/ui/view/viewfun7.cxx3
20 files changed, 174 insertions, 76 deletions
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(