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

Kohei Yoshida kohei.yoshida at collabora.com
Tue Feb 18 22:46:14 CET 2014


 sc/inc/clipcontext.hxx              |   31 +++++++++++
 sc/inc/column.hxx                   |    4 +
 sc/inc/document.hxx                 |    2 
 sc/inc/table.hxx                    |    2 
 sc/qa/unit/ucalc.hxx                |    2 
 sc/source/core/data/clipcontext.cxx |   58 ++++++++++++++++++++-
 sc/source/core/data/column3.cxx     |   52 +++++++++----------
 sc/source/core/data/column4.cxx     |   98 ++++++++++++++++++++++++++++++++++++
 sc/source/core/data/document.cxx    |   14 +++--
 sc/source/core/data/document10.cxx  |   24 ++++++++
 sc/source/core/data/table7.cxx      |   32 +++++++++++
 11 files changed, 285 insertions(+), 34 deletions(-)

New commits:
commit b3043662f41b605242784d56802a44e3856187b7
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Tue Feb 18 16:49:43 2014 -0500

    This test now passes. Re-enable it.
    
    Change-Id: I04a499666d1704277c24524f9e7cb827600a47db

diff --git a/sc/qa/unit/ucalc.hxx b/sc/qa/unit/ucalc.hxx
index 242d2c1..01cb908 100644
--- a/sc/qa/unit/ucalc.hxx
+++ b/sc/qa/unit/ucalc.hxx
@@ -411,7 +411,7 @@ public:
     CPPUNIT_TEST(testCopyPaste);
     CPPUNIT_TEST(testCopyPasteAsLink);
     CPPUNIT_TEST(testCopyPasteTranspose);
-//  CPPUNIT_TEST(testCopyPasteSkipEmpty); TODO : fix this later
+    CPPUNIT_TEST(testCopyPasteSkipEmpty);
     //CPPUNIT_TEST(testCopyPasteSkipEmptyConditionalFormatting);
     CPPUNIT_TEST(testUndoCut);
     CPPUNIT_TEST(testMoveBlock);
commit cdc8ebf9646e773351c91039a62f2414c7b02105
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Tue Feb 18 16:45:02 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.
    
    Change-Id: Ia8a2cbe57cd2fa9ca9ad46635a91a1d8b99b0e7d

diff --git a/sc/inc/clipcontext.hxx b/sc/inc/clipcontext.hxx
index 77abcf8..d016410 100644
--- a/sc/inc/clipcontext.hxx
+++ b/sc/inc/clipcontext.hxx
@@ -22,6 +22,7 @@ class ScDocument;
 class ScColumn;
 class ScPatternAttr;
 class ScPostIt;
+class ScConditionalFormatList;
 
 namespace sc {
 
@@ -43,21 +44,37 @@ public:
 
 class CopyFromClipContext : public ClipContextBase
 {
+    SCCOL mnDestCol1;
+    SCCOL mnDestCol2;
+    SCROW mnDestRow1;
+    SCROW mnDestRow2;
     SCTAB mnTabStart;
     SCTAB mnTabEnd;
     ScDocument* mpRefUndoDoc;
     ScDocument* mpClipDoc;
-    sal_uInt16  mnInsertFlag;
+    sal_uInt16 mnInsertFlag;
+    sal_uInt16 mnDeleteFlag;
     ScCellValue maSingleCell;
+    ScConditionalFormatList* mpCondFormatList;
     const ScPatternAttr* mpSinglePattern;
     const ScPostIt* mpSingleNote;
     bool mbAsLink:1;
     bool mbSkipAttrForEmptyCells:1;
     bool mbCloneNotes:1;
+    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);
@@ -69,18 +86,30 @@ 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;
+
     ScCellValue& getSingleCell();
 
+    void setCondFormatList( ScConditionalFormatList* pCondFormatList );
+    ScConditionalFormatList* getCondFormatList();
+
     const ScPatternAttr* getSingleCellPattern() const;
     void setSingleCellPattern( const ScPatternAttr* pAttr );
 
     const ScPostIt* getSingleCellNote() const;
     void setSingleCellNote( const ScPostIt* pNote );
 
+    void setTableProtected( bool b );
+    bool isTableProtected() const;
+
     bool isAsLink() const;
     bool isSkipAttrForEmptyCells() const;
     bool isCloneNotes() const;
diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index 9b36270..7f0c365 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -232,6 +232,7 @@ public:
     bool InitBlockPosition( sc::ColumnBlockPosition& rBlockPos );
     bool InitBlockPosition( sc::ColumnBlockConstPosition& rBlockPos ) const;
 
+    void DeleteBeforeCopyFromClip( sc::CopyFromClipContext& rCxt, const ScColumn& rClipCol );
     void CopyOneCellFromClip( sc::CopyFromClipContext& rCxt, SCROW nRow1, SCROW nRow2 );
 
     void CopyFromClip(
@@ -592,6 +593,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 1294503..12b2bee 100644
--- a/sc/inc/document.hxx
+++ b/sc/inc/document.hxx
@@ -1207,6 +1207,8 @@ public:
 
     bool InitColumnBlockPosition( sc::ColumnBlockPosition& rBlokPos, SCTAB nTab, SCCOL nCol );
 
+    void DeleteBeforeCopyFromClip( sc::CopyFromClipContext& rCxt, const ScMarkData& rMark );
+
     bool CopyOneCellFromClip(
         sc::CopyFromClipContext& rCxt, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 );
     void CopyBlockFromClip(
diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx
index 1e8764b..563f17d 100644
--- a/sc/inc/table.hxx
+++ b/sc/inc/table.hxx
@@ -418,6 +418,8 @@ public:
 
     bool InitColumnBlockPosition( sc::ColumnBlockPosition& rBlockPos, SCCOL nCol );
 
+    void DeleteBeforeCopyFromClip( sc::CopyFromClipContext& rCxt, const ScTable& rClipTab );
+
     void CopyOneCellFromClip(
         sc::CopyFromClipContext& rCxt, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 );
 
diff --git a/sc/source/core/data/clipcontext.cxx b/sc/source/core/data/clipcontext.cxx
index 35cde4e..c70d9d4 100644
--- a/sc/source/core/data/clipcontext.cxx
+++ b/sc/source/core/data/clipcontext.cxx
@@ -31,11 +31,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),
-    mpSinglePattern(NULL), mpSingleNote(NULL),
+    mpRefUndoDoc(pRefUndoDoc), mpClipDoc(pClipDoc),
+    mnInsertFlag(nInsertFlag), mnDeleteFlag(IDF_NONE),
+    mpCondFormatList(NULL), mpSinglePattern(NULL), mpSingleNote(NULL),
     mbAsLink(bAsLink), mbSkipAttrForEmptyCells(bSkipAttrForEmptyCells),
-    mbCloneNotes (mnInsertFlag & (IDF_NOTE|IDF_ADDNOTES))
+    mbCloneNotes (mnInsertFlag & (IDF_NOTE|IDF_ADDNOTES)),
+    mbTableProtected(false)
 {
 }
 
@@ -59,6 +63,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;
@@ -74,11 +96,31 @@ sal_uInt16 CopyFromClipContext::getInsertFlag() const
     return mnInsertFlag;
 }
 
+void CopyFromClipContext::setDeleteFlag( sal_uInt16 nFlag )
+{
+    mnDeleteFlag = nFlag;
+}
+
+sal_uInt16 CopyFromClipContext::getDeleteFlag() const
+{
+    return mnDeleteFlag;
+}
+
 ScCellValue& CopyFromClipContext::getSingleCell()
 {
     return maSingleCell;
 }
 
+void CopyFromClipContext::setCondFormatList( ScConditionalFormatList* pCondFormatList )
+{
+    mpCondFormatList = pCondFormatList;
+}
+
+ScConditionalFormatList* CopyFromClipContext::getCondFormatList()
+{
+    return mpCondFormatList;
+}
+
 const ScPatternAttr* CopyFromClipContext::getSingleCellPattern() const
 {
     return mpSinglePattern;
@@ -99,6 +141,16 @@ void CopyFromClipContext::setSingleCellNote( const ScPostIt* pNote )
     mpSingleNote = pNote;
 }
 
+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 5bc149b..1445848 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 )
     {
diff --git a/sc/source/core/data/column4.cxx b/sc/source/core/data/column4.cxx
index 5848183..fa18818 100644
--- a/sc/source/core/data/column4.cxx
+++ b/sc/source/core/data/column4.cxx
@@ -17,6 +17,11 @@
 #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>
 
@@ -28,6 +33,99 @@ bool ScColumn::IsMerged( SCROW nRow ) const
     return pAttrArray->IsMerged(nRow);
 }
 
+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);
+}
+
 void ScColumn::CopyOneCellFromClip( sc::CopyFromClipContext& rCxt, SCROW nRow1, SCROW nRow2 )
 {
     assert(nRow1 <= nRow2);
diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx
index f825a79..92d1f7e 100644
--- a/sc/source/core/data/document.cxx
+++ b/sc/source/core/data/document.cxx
@@ -2661,14 +2661,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)
@@ -2690,7 +2690,13 @@ void ScDocument::CopyFromClip( const ScRange& rDestRange, const ScMarkData& rMar
         SCCOL nCol2 = pRange->aEnd.Col();
         SCROW nRow2 = pRange->aEnd.Row();
 
-        if (!bSkipAttrForEmpty)
+        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);
 
         if (CopyOneCellFromClip(aCxt, nCol1, nRow1, nCol2, nRow2))
diff --git a/sc/source/core/data/document10.cxx b/sc/source/core/data/document10.cxx
index d36df55..3e1a69b 100644
--- a/sc/source/core/data/document10.cxx
+++ b/sc/source/core/data/document10.cxx
@@ -26,6 +26,30 @@ bool ScDocument::IsMerged( const ScAddress& rPos ) const
     return pTab->IsMerged(rPos.Col(), rPos.Row());
 }
 
+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;
+    }
+}
+
 bool ScDocument::CopyOneCellFromClip(
     sc::CopyFromClipContext& rCxt, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 )
 {
diff --git a/sc/source/core/data/table7.cxx b/sc/source/core/data/table7.cxx
index 8a7391c..a5936cb 100644
--- a/sc/source/core/data/table7.cxx
+++ b/sc/source/core/data/table7.cxx
@@ -8,6 +8,10 @@
  */
 
 #include <table.hxx>
+#include <clipcontext.hxx>
+#include <document.hxx>
+#include <clipparam.hxx>
+#include <bcaslot.hxx>
 
 bool ScTable::IsMerged( SCCOL nCol, SCROW nRow ) const
 {
@@ -17,6 +21,34 @@ bool ScTable::IsMerged( SCCOL nCol, SCROW nRow ) const
     return aCol[nCol].IsMerged(nRow);
 }
 
+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);
+}
+
 void ScTable::CopyOneCellFromClip(
     sc::CopyFromClipContext& rCxt, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 )
 {


More information about the Libreoffice-commits mailing list