[Libreoffice-commits] core.git: Branch 'libreoffice-4-2' - sc/inc sc/Library_sc.mk sc/source

Kohei Yoshida kohei.yoshida at collabora.com
Tue Feb 25 21:01:51 PST 2014


 sc/Library_sc.mk                    |    3 
 sc/inc/clipcontext.hxx              |   40 ++++++++++-
 sc/inc/column.hxx                   |    6 +
 sc/inc/document.hxx                 |    2 
 sc/inc/table.hxx                    |    2 
 sc/source/core/data/clipcontext.cxx |   57 ++++++++++++++++
 sc/source/core/data/column3.cxx     |   55 ++++++++--------
 sc/source/core/data/column4.cxx     |  123 ++++++++++++++++++++++++++++++++++++
 sc/source/core/data/document.cxx    |   15 +++-
 sc/source/core/data/document10.cxx  |   44 ++++++++++++
 sc/source/core/data/table7.cxx      |   44 ++++++++++++
 sc/source/ui/view/viewfun3.cxx      |    3 
 12 files changed, 355 insertions(+), 39 deletions(-)

New commits:
commit 166e2775d80b7e45ab258a4175d7b9e8a15a5dba
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Thu Feb 6 14:11:43 2014 -0500

    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 at googlemail.com>
    Tested-by: Markus Mohrhard <markus.mohrhard at googlemail.com>

diff --git a/sc/Library_sc.mk b/sc/Library_sc.mk
index efdea71..58d8048 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 dd63ba6..dca1fed 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 529f84f..07da1ca 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 3ac1089..f26c3c7 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 f6164ce..4aab32e 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 8013684..0f95fdd 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 50c52ce..75ad544 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 0000000..a024665
--- /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 5f59e0f..ec2c21a 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 0000000..00640b3
--- /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 0000000..858514c
--- /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 f96d913d..210b3202 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 );


More information about the Libreoffice-commits mailing list