summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKohei Yoshida <kohei.yoshida@collabora.com>2014-02-06 14:11:43 -0500
committerMarkus Mohrhard <markus.mohrhard@googlemail.com>2014-02-25 23:01:23 -0600
commit166e2775d80b7e45ab258a4175d7b9e8a15a5dba (patch)
treef576c3595ead02daa6cc2c8721efee64c6760078
parent5a13bf7bc741aeb7543b9ff736563b89c086d4fd (diff)
fdo#74573: Delete ranges that are non-empty before pasting from clipboard.
The conditional formatting part is still not working. But other bits appear to be working now. Also, adjust handling of mix document aka paste functions with this change. When using paste function (add, subtract, etc), the behavior between the 'skip empty' flag on and off makes no difference. Let's set the flag to off when paste function is used. (cherry picked from commit 0c12aa670b83b76241077dfb8bc21f40a55b1667) (cherry picked from commit 2f55cee39379a76920f3a4fb14e6c2774093bfcd) (cherry picked from commit cdc8ebf9646e773351c91039a62f2414c7b02105) Conflicts: sc/inc/clipcontext.hxx sc/inc/column.hxx sc/inc/document.hxx sc/inc/table.hxx sc/source/core/data/clipcontext.cxx sc/source/core/data/column4.cxx sc/source/core/data/document10.cxx sc/source/core/data/table7.cxx Change-Id: I67724ba923c9260b2c14464e4123b8445712dbaf Reviewed-on: https://gerrit.libreoffice.org/7906 Reviewed-by: Markus Mohrhard <markus.mohrhard@googlemail.com> Tested-by: Markus Mohrhard <markus.mohrhard@googlemail.com>
-rw-r--r--sc/Library_sc.mk3
-rw-r--r--sc/inc/clipcontext.hxx40
-rw-r--r--sc/inc/column.hxx6
-rw-r--r--sc/inc/document.hxx2
-rw-r--r--sc/inc/table.hxx2
-rw-r--r--sc/source/core/data/clipcontext.cxx57
-rw-r--r--sc/source/core/data/column3.cxx55
-rw-r--r--sc/source/core/data/column4.cxx123
-rw-r--r--sc/source/core/data/document.cxx15
-rw-r--r--sc/source/core/data/document10.cxx44
-rw-r--r--sc/source/core/data/table7.cxx44
-rw-r--r--sc/source/ui/view/viewfun3.cxx3
12 files changed, 355 insertions, 39 deletions
diff --git a/sc/Library_sc.mk b/sc/Library_sc.mk
index efdea71aa458..58d8048e86dd 100644
--- a/sc/Library_sc.mk
+++ b/sc/Library_sc.mk
@@ -104,6 +104,7 @@ $(eval $(call gb_Library_add_exception_objects,sc,\
sc/source/core/data/column \
sc/source/core/data/column2 \
sc/source/core/data/column3 \
+ sc/source/core/data/column4 \
sc/source/core/data/columniterator \
sc/source/core/data/columnset \
sc/source/core/data/columnspanset \
@@ -123,6 +124,7 @@ $(eval $(call gb_Library_add_exception_objects,sc,\
sc/source/core/data/documen8 \
sc/source/core/data/documen9 \
sc/source/core/data/document \
+ sc/source/core/data/document10 \
sc/source/core/data/documentimport \
sc/source/core/data/documentstreamaccess \
sc/source/core/data/dpdimsave \
@@ -179,6 +181,7 @@ $(eval $(call gb_Library_add_exception_objects,sc,\
sc/source/core/data/table4 \
sc/source/core/data/table5 \
sc/source/core/data/table6 \
+ sc/source/core/data/table7 \
sc/source/core/data/tabprotection \
sc/source/core/data/types \
sc/source/core/data/userdat \
diff --git a/sc/inc/clipcontext.hxx b/sc/inc/clipcontext.hxx
index dd63ba6c36c6..dca1fedcd1fd 100644
--- a/sc/inc/clipcontext.hxx
+++ b/sc/inc/clipcontext.hxx
@@ -18,6 +18,7 @@
#include <boost/scoped_ptr.hpp>
class ScDocument;
+class ScConditionalFormatList;
namespace sc {
@@ -39,18 +40,34 @@ public:
class CopyFromClipContext : public ClipContextBase
{
+ SCCOL mnDestCol1;
+ SCCOL mnDestCol2;
+ SCROW mnDestRow1;
+ SCROW mnDestRow2;
SCTAB mnTabStart;
SCTAB mnTabEnd;
ScDocument* mpRefUndoDoc;
ScDocument* mpClipDoc;
- sal_uInt16 mnInsertFlag;
- bool mbAsLink:1;
- bool mbSkipAttrForEmptyCells:1;
- bool mbCloneNotes;
+ sal_uInt16 mnInsertFlag;
+ sal_uInt16 mnDeleteFlag;
+ ScConditionalFormatList* mpCondFormatList;
+ bool mbAsLink:1;
+ bool mbSkipAttrForEmptyCells:1;
+ bool mbCloneNotes;
+ bool mbTableProtected:1;
CopyFromClipContext(); // disabled
public:
+
+ struct Range
+ {
+ SCCOL mnCol1;
+ SCCOL mnCol2;
+ SCROW mnRow1;
+ SCROW mnRow2;
+ };
+
CopyFromClipContext(ScDocument& rDoc,
ScDocument* pRefUndoDoc, ScDocument* pClipDoc, sal_uInt16 nInsertFlag,
bool bAsLink, bool bSkipAttrForEmptyCells);
@@ -62,12 +79,25 @@ public:
SCTAB getTabStart() const;
SCTAB getTabEnd() const;
+ void setDestRange( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 );
+ Range getDestRange() const;
+
ScDocument* getUndoDoc();
ScDocument* getClipDoc();
sal_uInt16 getInsertFlag() const;
+
+ void setDeleteFlag( sal_uInt16 nFlag );
+ sal_uInt16 getDeleteFlag() const;
+
+ void setCondFormatList( ScConditionalFormatList* pCondFormatList );
+ ScConditionalFormatList* getCondFormatList();
+
+ void setTableProtected( bool b );
+ bool isTableProtected() const;
+
bool isAsLink() const;
bool isSkipAttrForEmptyCells() const;
- bool isCloneNotes() const;
+ bool isCloneNotes() const;
};
class CopyToClipContext : public ClipContextBase
diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index 529f84fff22b..07da1ca16a89 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -224,6 +224,9 @@ public:
void CopyCellToDocument( SCROW nSrcRow, SCROW nDestRow, ScColumn& rDestCol );
bool InitBlockPosition( sc::ColumnBlockPosition& rBlockPos );
bool InitBlockPosition( sc::ColumnBlockConstPosition& rBlockPos ) const;
+
+ void DeleteBeforeCopyFromClip( sc::CopyFromClipContext& rCxt, const ScColumn& rClipCol );
+
void CopyFromClip(
sc::CopyFromClipContext& rCxt, SCROW nRow1, SCROW nRow2, long nDy, ScColumn& rColumn );
@@ -571,6 +574,9 @@ private:
// cell notes
void SwapCellNotes( SCROW nRow1, SCROW nRow2 );
+ void DeleteCells(
+ sc::ColumnBlockPosition& rBlockPos, SCROW nRow1, SCROW nRow2, sal_uInt16 nDelFlag,
+ std::vector<SCROW>& rDeleted );
};
#endif
diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx
index 3ac1089be1bf..f26c3c7395fb 100644
--- a/sc/inc/document.hxx
+++ b/sc/inc/document.hxx
@@ -1202,6 +1202,8 @@ public:
bool InitColumnBlockPosition( sc::ColumnBlockPosition& rBlokPos, SCTAB nTab, SCCOL nCol );
+ void DeleteBeforeCopyFromClip( sc::CopyFromClipContext& rCxt, const ScMarkData& rMark );
+
void CopyBlockFromClip(
sc::CopyFromClipContext& rCxt, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
const ScMarkData& rMark, SCsCOL nDx, SCsROW nDy );
diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx
index f6164ced3330..4aab32e5d298 100644
--- a/sc/inc/table.hxx
+++ b/sc/inc/table.hxx
@@ -411,6 +411,8 @@ public:
bool InitColumnBlockPosition( sc::ColumnBlockPosition& rBlockPos, SCCOL nCol );
+ void DeleteBeforeCopyFromClip( sc::CopyFromClipContext& rCxt, const ScTable& rClipTab );
+
void CopyFromClip(
sc::CopyFromClipContext& rCxt, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
SCsCOL nDx, SCsROW nDy, ScTable* pTable );
diff --git a/sc/source/core/data/clipcontext.cxx b/sc/source/core/data/clipcontext.cxx
index 8013684867ee..0f95fdd75b41 100644
--- a/sc/source/core/data/clipcontext.cxx
+++ b/sc/source/core/data/clipcontext.cxx
@@ -27,10 +27,15 @@ CopyFromClipContext::CopyFromClipContext(ScDocument& rDoc,
ScDocument* pRefUndoDoc, ScDocument* pClipDoc, sal_uInt16 nInsertFlag,
bool bAsLink, bool bSkipAttrForEmptyCells) :
ClipContextBase(rDoc),
+ mnDestCol1(-1), mnDestCol2(-1),
+ mnDestRow1(-1), mnDestRow2(-1),
mnTabStart(-1), mnTabEnd(-1),
- mpRefUndoDoc(pRefUndoDoc), mpClipDoc(pClipDoc), mnInsertFlag(nInsertFlag),
+ mpRefUndoDoc(pRefUndoDoc), mpClipDoc(pClipDoc),
+ mnInsertFlag(nInsertFlag), mnDeleteFlag(IDF_NONE),
+ mpCondFormatList(NULL),
mbAsLink(bAsLink), mbSkipAttrForEmptyCells(bSkipAttrForEmptyCells),
- mbCloneNotes (mnInsertFlag & (IDF_NOTE|IDF_ADDNOTES) )
+ mbCloneNotes(mnInsertFlag & (IDF_NOTE|IDF_ADDNOTES)),
+ mbTableProtected(false)
{
}
@@ -54,6 +59,24 @@ SCTAB CopyFromClipContext::getTabEnd() const
return mnTabEnd;
}
+void CopyFromClipContext::setDestRange( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 )
+{
+ mnDestCol1 = nCol1;
+ mnDestRow1 = nRow1;
+ mnDestCol2 = nCol2;
+ mnDestRow2 = nRow2;
+}
+
+CopyFromClipContext::Range CopyFromClipContext::getDestRange() const
+{
+ Range aRet;
+ aRet.mnCol1 = mnDestCol1;
+ aRet.mnCol2 = mnDestCol2;
+ aRet.mnRow1 = mnDestRow1;
+ aRet.mnRow2 = mnDestRow2;
+ return aRet;
+}
+
ScDocument* CopyFromClipContext::getUndoDoc()
{
return mpRefUndoDoc;
@@ -69,6 +92,36 @@ sal_uInt16 CopyFromClipContext::getInsertFlag() const
return mnInsertFlag;
}
+void CopyFromClipContext::setDeleteFlag( sal_uInt16 nFlag )
+{
+ mnDeleteFlag = nFlag;
+}
+
+sal_uInt16 CopyFromClipContext::getDeleteFlag() const
+{
+ return mnDeleteFlag;
+}
+
+void CopyFromClipContext::setCondFormatList( ScConditionalFormatList* pCondFormatList )
+{
+ mpCondFormatList = pCondFormatList;
+}
+
+ScConditionalFormatList* CopyFromClipContext::getCondFormatList()
+{
+ return mpCondFormatList;
+}
+
+void CopyFromClipContext::setTableProtected( bool b )
+{
+ mbTableProtected = b;
+}
+
+bool CopyFromClipContext::isTableProtected() const
+{
+ return mbTableProtected;
+}
+
bool CopyFromClipContext::isAsLink() const
{
return mbAsLink;
diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx
index 50c52cee5ed8..75ad544c1d38 100644
--- a/sc/source/core/data/column3.cxx
+++ b/sc/source/core/data/column3.cxx
@@ -570,6 +570,29 @@ public:
}
+void ScColumn::DeleteCells(
+ sc::ColumnBlockPosition& rBlockPos, SCROW nRow1, SCROW nRow2, sal_uInt16 nDelFlag,
+ std::vector<SCROW>& rDeleted )
+{
+ // Determine which cells to delete based on the deletion flags.
+ DeleteAreaHandler aFunc(*pDocument, nDelFlag);
+ sc::CellStoreType::iterator itPos = maCells.position(rBlockPos.miCellPos, nRow1).first;
+ sc::ProcessBlock(itPos, maCells, aFunc, nRow1, nRow2);
+ aFunc.endFormulas(); // Have the formula cells stop listening.
+
+ std::vector<SCROW> aDeletedRows;
+ aFunc.getSpans().getRows(aDeletedRows);
+ std::copy(aDeletedRows.begin(), aDeletedRows.end(), std::back_inserter(rDeleted));
+
+ // Get the deletion spans.
+ sc::SingleColumnSpanSet::SpansType aSpans;
+ aFunc.getSpans().getSpans(aSpans);
+
+ // Delete the cells for real.
+ std::for_each(aSpans.begin(), aSpans.end(), EmptyCells(rBlockPos, *this));
+ CellStorageModified();
+}
+
void ScColumn::DeleteArea(
SCROW nStartRow, SCROW nEndRow, sal_uInt16 nDelFlag, bool bBroadcast )
{
@@ -581,35 +604,14 @@ void ScColumn::DeleteArea(
std::vector<SCROW> aDeletedRows;
- if (!IsEmptyData() && nContFlag)
- {
- // There are cells to delete. Determine which cells to delete based on the deletion flags.
- DeleteAreaHandler aFunc(*pDocument, nDelFlag);
- sc::CellStoreType::iterator itPos = maCells.position(nStartRow).first;
- sc::ProcessBlock(itPos, maCells, aFunc, nStartRow, nEndRow);
- aFunc.endFormulas(); // Have the formula cells stop listening.
- aFunc.getSpans().getRows(aDeletedRows);
-
- // Get the deletion spans.
- sc::SingleColumnSpanSet::SpansType aSpans;
- aFunc.getSpans().getSpans(aSpans);
+ sc::ColumnBlockPosition aBlockPos;
+ InitBlockPosition(aBlockPos);
- sc::ColumnBlockPosition aBlockPos;
- aBlockPos.miCellPos = itPos;
- aBlockPos.miCellTextAttrPos = maCellTextAttrs.begin();
- aBlockPos.miCellNotePos = maCellNotes.begin();
-
- // Delete the cells for real.
- std::for_each(aSpans.begin(), aSpans.end(), EmptyCells(aBlockPos, *this));
- CellStorageModified();
- }
+ if (!IsEmptyData() && nContFlag)
+ DeleteCells(aBlockPos, nStartRow, nEndRow, nDelFlag, aDeletedRows);
if (nDelFlag & IDF_NOTE)
- {
- sc::ColumnBlockPosition aBlockPos;
- aBlockPos.miCellNotePos = maCellNotes.begin();
DeleteCellNotes(aBlockPos, nStartRow, nEndRow);
- }
if ( nDelFlag & IDF_EDITATTR )
{
@@ -737,7 +739,6 @@ public:
void operator() (const sc::CellStoreType::value_type& node, size_t nOffset, size_t nDataSize)
{
-
SCROW nSrcRow1 = node.position + nOffset;
bool bCopyCellNotes = mrCxt.isCloneNotes();
@@ -745,7 +746,7 @@ public:
if (node.type == sc::element_type_empty)
{
- if (bCopyCellNotes)
+ if (bCopyCellNotes && !mrCxt.isSkipAttrForEmptyCells())
{
bool bCloneCaption = (nFlags & IDF_NOCAPTIONS) == 0;
duplicateNotes(nSrcRow1, nDataSize, bCloneCaption );
diff --git a/sc/source/core/data/column4.cxx b/sc/source/core/data/column4.cxx
new file mode 100644
index 000000000000..a02466563a47
--- /dev/null
+++ b/sc/source/core/data/column4.cxx
@@ -0,0 +1,123 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <column.hxx>
+#include <clipcontext.hxx>
+#include <clipparam.hxx>
+#include <cellvalue.hxx>
+#include <attarray.hxx>
+#include <document.hxx>
+#include <columnspanset.hxx>
+#include <listenercontext.hxx>
+#include <mtvcellfunc.hxx>
+#include <clipcontext.hxx>
+#include <attrib.hxx>
+#include <patattr.hxx>
+#include <docpool.hxx>
+#include <conditio.hxx>
+
+#include <svl/sharedstringpool.hxx>
+
+#include <vector>
+#include <cassert>
+
+void ScColumn::DeleteBeforeCopyFromClip( sc::CopyFromClipContext& rCxt, const ScColumn& rClipCol )
+{
+ sc::CopyFromClipContext::Range aRange = rCxt.getDestRange();
+ if (!ValidRow(aRange.mnRow1) || !ValidRow(aRange.mnRow2))
+ return;
+
+ ScRange aClipRange = rCxt.getClipDoc()->GetClipParam().getWholeRange();
+ SCROW nClipRow1 = aClipRange.aStart.Row();
+ SCROW nClipRow2 = aClipRange.aEnd.Row();
+ SCROW nClipRowLen = nClipRow2 - nClipRow1 + 1;
+
+ // Check for non-empty cell ranges in the clip column.
+ sc::SingleColumnSpanSet aSpanSet;
+ aSpanSet.scan(rClipCol, nClipRow1, nClipRow2);
+ sc::SingleColumnSpanSet::SpansType aSpans;
+ aSpanSet.getSpans(aSpans);
+
+ // Translate the clip column spans into the destination column, and repeat as needed.
+ std::vector<sc::RowSpan> aDestSpans;
+ SCROW nDestOffset = aRange.mnRow1 - nClipRow1;
+ bool bContinue = true;
+ while (bContinue)
+ {
+ sc::SingleColumnSpanSet::SpansType::const_iterator it = aSpans.begin(), itEnd = aSpans.end();
+ for (; it != itEnd && bContinue; ++it)
+ {
+ const sc::RowSpan& r = *it;
+ SCROW nDestRow1 = r.mnRow1 + nDestOffset;
+ SCROW nDestRow2 = r.mnRow2 + nDestOffset;
+
+ if (nDestRow1 > aRange.mnRow2)
+ {
+ // We're done.
+ bContinue = false;
+ continue;
+ }
+
+ if (nDestRow2 > aRange.mnRow2)
+ {
+ // Truncate this range, and set it as the last span.
+ nDestRow2 = aRange.mnRow2;
+ bContinue = false;
+ }
+
+ aDestSpans.push_back(sc::RowSpan(nDestRow1, nDestRow2));
+ }
+
+ nDestOffset += nClipRowLen;
+ }
+
+ std::vector<SCROW> aDeletedRows;
+ sal_uInt16 nDelFlag = rCxt.getDeleteFlag();
+ sc::ColumnBlockPosition aBlockPos;
+ InitBlockPosition(aBlockPos);
+
+ std::vector<sc::RowSpan>::const_iterator it = aDestSpans.begin(), itEnd = aDestSpans.end();
+ for (; it != itEnd; ++it)
+ {
+ SCROW nRow1 = it->mnRow1;
+ SCROW nRow2 = it->mnRow2;
+
+ if (nDelFlag & IDF_CONTENTS)
+ DeleteCells(aBlockPos, nRow1, nRow2, nDelFlag, aDeletedRows);
+
+ if (nDelFlag & IDF_NOTE)
+ DeleteCellNotes(aBlockPos, nRow1, nRow2);
+
+ if (nDelFlag & IDF_EDITATTR)
+ RemoveEditAttribs(nRow1, nRow2);
+
+ // Delete attributes just now
+ if (nDelFlag & IDF_ATTRIB)
+ {
+ pAttrArray->DeleteArea(nRow1, nRow2);
+
+ if (rCxt.isTableProtected())
+ {
+ ScPatternAttr aPattern(pDocument->GetPool());
+ aPattern.GetItemSet().Put(ScProtectionAttr(false));
+ ApplyPatternArea(nRow1, nRow2, aPattern);
+ }
+
+ ScConditionalFormatList* pCondList = rCxt.getCondFormatList();
+ if (pCondList)
+ pCondList->DeleteArea(nCol, nRow1, nCol, nRow2);
+ }
+ else if ((nDelFlag & IDF_HARDATTR) == IDF_HARDATTR)
+ pAttrArray->DeleteHardAttr(nRow1, nRow2);
+ }
+
+ BroadcastCells(aDeletedRows, SC_HINT_DATACHANGED);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx
index 5f59e0f786ff..ec2c21a07627 100644
--- a/sc/source/core/data/document.cxx
+++ b/sc/source/core/data/document.cxx
@@ -2662,14 +2662,14 @@ void ScDocument::CopyFromClip( const ScRange& rDestRange, const ScMarkData& rMar
nDelFlag |= IDF_NOTE;
else if ( nInsFlag & IDF_CONTENTS )
nDelFlag |= IDF_CONTENTS;
- // With bSkipAttrForEmpty, don't remove attributes, copy
- // on top of existing attributes instead.
- if ( ( nInsFlag & IDF_ATTRIB ) && !bSkipAttrForEmpty )
+
+ if (nInsFlag & IDF_ATTRIB)
nDelFlag |= IDF_ATTRIB;
sc::CopyFromClipContext aCxt(*this, pRefUndoDoc, pClipDoc, nInsFlag, bAsLink, bSkipAttrForEmpty);
std::pair<SCTAB,SCTAB> aTabRanges = getMarkedTableRange(maTabs, rMark);
aCxt.setTabRange(aTabRanges.first, aTabRanges.second);
+ aCxt.setDeleteFlag(nDelFlag);
ScRangeList aLocalRangeList;
if (!pDestRanges)
@@ -2691,7 +2691,14 @@ void ScDocument::CopyFromClip( const ScRange& rDestRange, const ScMarkData& rMar
SCCOL nCol2 = pRange->aEnd.Col();
SCROW nRow2 = pRange->aEnd.Row();
- DeleteArea(nCol1, nRow1, nCol2, nRow2, rMark, nDelFlag);
+ if (bSkipAttrForEmpty)
+ {
+ // Delete cells in the destination only if their corresponding clip cells are not empty.
+ aCxt.setDestRange(nCol1, nRow1, nCol2, nRow2);
+ DeleteBeforeCopyFromClip(aCxt, rMark);
+ }
+ else
+ DeleteArea(nCol1, nRow1, nCol2, nRow2, rMark, nDelFlag);
SCCOL nC1 = nCol1;
SCROW nR1 = nRow1;
diff --git a/sc/source/core/data/document10.cxx b/sc/source/core/data/document10.cxx
new file mode 100644
index 000000000000..00640b347316
--- /dev/null
+++ b/sc/source/core/data/document10.cxx
@@ -0,0 +1,44 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <document.hxx>
+#include <clipcontext.hxx>
+#include <formulacell.hxx>
+#include <clipparam.hxx>
+#include <table.hxx>
+#include <tokenarray.hxx>
+#include <editutil.hxx>
+
+// Add totally brand-new methods to this source file.
+
+void ScDocument::DeleteBeforeCopyFromClip( sc::CopyFromClipContext& rCxt, const ScMarkData& rMark )
+{
+ SCTAB nClipTab = 0;
+ const TableContainer& rClipTabs = rCxt.getClipDoc()->maTabs;
+ SCTAB nClipTabCount = rClipTabs.size();
+
+ for (SCTAB nTab = rCxt.getTabStart(); nTab <= rCxt.getTabEnd(); ++nTab)
+ {
+ ScTable* pTab = FetchTable(nTab);
+ if (!pTab)
+ continue;
+
+ if (!rMark.GetTableSelect(nTab))
+ continue;
+
+ while (!rClipTabs[nClipTab])
+ nClipTab = (nClipTab+1) % nClipTabCount;
+
+ pTab->DeleteBeforeCopyFromClip(rCxt, *rClipTabs[nClipTab]);
+
+ nClipTab = (nClipTab+1) % nClipTabCount;
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/core/data/table7.cxx b/sc/source/core/data/table7.cxx
new file mode 100644
index 000000000000..858514c7685a
--- /dev/null
+++ b/sc/source/core/data/table7.cxx
@@ -0,0 +1,44 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <table.hxx>
+#include <clipcontext.hxx>
+#include <document.hxx>
+#include <clipparam.hxx>
+#include <bcaslot.hxx>
+
+void ScTable::DeleteBeforeCopyFromClip( sc::CopyFromClipContext& rCxt, const ScTable& rClipTab )
+{
+ sc::CopyFromClipContext::Range aRange = rCxt.getDestRange();
+ if (!ValidCol(aRange.mnCol1) || !ValidCol(aRange.mnCol2))
+ return;
+
+ // Pass some stuff to the columns via context.
+ rCxt.setTableProtected(IsProtected());
+ rCxt.setCondFormatList(mpCondFormatList.get());
+
+ ScRange aClipRange = rCxt.getClipDoc()->GetClipParam().getWholeRange();
+ SCCOL nClipCol = aClipRange.aStart.Col();
+ {
+ ScBulkBroadcast aBulkBroadcast(pDocument->GetBASM());
+
+ for (SCCOL nCol = aRange.mnCol1; nCol <= aRange.mnCol2; ++nCol, ++nClipCol)
+ {
+ if (nClipCol > aClipRange.aEnd.Col())
+ nClipCol = aClipRange.aStart.Col(); // loop through columns.
+
+ const ScColumn& rClipCol = rClipTab.aCol[nClipCol];
+ aCol[nCol].DeleteBeforeCopyFromClip(rCxt, rClipCol);
+ }
+ }
+
+ SetStreamValid(false);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/view/viewfun3.cxx b/sc/source/ui/view/viewfun3.cxx
index f96d913d73a1..210b3202e10c 100644
--- a/sc/source/ui/view/viewfun3.cxx
+++ b/sc/source/ui/view/viewfun3.cxx
@@ -1188,8 +1188,9 @@ bool ScViewFunc::PasteFromClip( sal_uInt16 nFlags, ScDocument* pClipDoc,
//
ScDocument* pMixDoc = NULL;
- if ( bSkipEmpty || nFunction )
+ if (nFunction)
{
+ bSkipEmpty = false;
if ( nFlags & IDF_CONTENTS )
{
pMixDoc = new ScDocument( SCDOCMODE_UNDO );