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

Kohei Yoshida kohei.yoshida at collabora.com
Thu Feb 20 03:16:25 CET 2014


 sc/inc/column.hxx               |    2 
 sc/inc/mtvcellfunc.hxx          |   11 +++
 sc/source/core/data/column2.cxx |  111 +++++++++++++---------------------------
 3 files changed, 50 insertions(+), 74 deletions(-)

New commits:
commit f0b4fe210200a3620cf05f30242771b01d991658
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Mon Feb 17 12:20:57 2014 -0500

    fdo#75032: Handle note copying correctly.
    
    (cherry picked from commit 575e88da278f536ebfb6562dfd98f341240afec4)
    
    Conflicts:
    	sc/source/core/data/column2.cxx
    
    Change-Id: Iae37ac86889d7a25f25e6dd0b69f724107c6798a
    Reviewed-on: https://gerrit.libreoffice.org/8089
    Reviewed-by: Markus Mohrhard <markus.mohrhard at googlemail.com>
    Tested-by: Markus Mohrhard <markus.mohrhard at googlemail.com>

diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index c6db640..529f84f 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -167,6 +167,8 @@ public:
     const sc::CellStoreType& GetCellStore() const { return maCells; }
     sc::CellTextAttrStoreType& GetCellAttrStore() { return maCellTextAttrs; }
     const sc::CellTextAttrStoreType& GetCellAttrStore() const { return maCellTextAttrs; }
+    sc::CellNoteStoreType& GetCellNoteStore() { return maCellNotes; }
+    const sc::CellNoteStoreType& GetCellNoteStore() const { return maCellNotes; }
 
     ScRefCellValue GetCellValue( SCROW nRow ) const;
     ScRefCellValue GetCellValue( const sc::CellStoreType::const_iterator& itPos, size_t nOffset ) const;
diff --git a/sc/inc/mtvcellfunc.hxx b/sc/inc/mtvcellfunc.hxx
index fc6d2dc..d5e7921 100644
--- a/sc/inc/mtvcellfunc.hxx
+++ b/sc/inc/mtvcellfunc.hxx
@@ -166,6 +166,17 @@ void ProcessNote(CellNoteStoreType& rStore, _Func& rFunc)
     ProcessElements1<CellNoteStoreType, cellnote_block, _Func, FuncElseNoOp<size_t> >(rStore, rFunc, aElse);
 }
 
+template<typename _Func>
+typename CellNoteStoreType::const_iterator
+ParseNote(
+    const CellNoteStoreType::const_iterator& itPos, const CellNoteStoreType& rStore,
+    SCROW nStart, SCROW nEnd, _Func& rFunc)
+{
+    FuncElseNoOp<size_t> aElse;
+    return ParseElements1<CellNoteStoreType, cellnote_block, _Func, FuncElseNoOp<size_t> >(
+        itPos, rStore, nStart, nEnd, rFunc, aElse);
+}
+
 template<typename _FuncElem>
 typename CellNoteStoreType::iterator
 ProcessNote(
diff --git a/sc/source/core/data/column2.cxx b/sc/source/core/data/column2.cxx
index 1d28780..ae1a722 100644
--- a/sc/source/core/data/column2.cxx
+++ b/sc/source/core/data/column2.cxx
@@ -1798,85 +1798,48 @@ void ScColumn::CopyCellTextAttrsToDocument(SCROW nRow1, SCROW nRow2, ScColumn& r
     }
 }
 
-void ScColumn::CopyCellNotesToDocument(SCROW nRow1, SCROW nRow2, ScColumn& rDestCol, bool bCloneCaption, SCROW nRowOffsetDest) const
-{
-    SCCOL nDestCol = rDestCol.GetCol();
-    SCTAB nDestTab = rDestCol.GetTab();
-
-    rDestCol.maCellNotes.set_empty(nRow1 + nRowOffsetDest, nRow2 + nRowOffsetDest); // Empty the destination range first.
+namespace {
 
-    sc::CellNoteStoreType::const_iterator itBlk = maCellNotes.begin(), itBlkEnd = maCellNotes.end();
+class CopyCellNotesHandler
+{
+    ScColumn& mrDestCol;
+    sc::CellNoteStoreType& mrDestNotes;
+    sc::CellNoteStoreType::iterator miPos;
+    SCTAB mnSrcTab;
+    SCCOL mnSrcCol;
+    SCTAB mnDestTab;
+    SCCOL mnDestCol;
+    SCROW mnDestOffset; /// Add this to the source row position to get the destination row.
+    bool mbCloneCaption;
 
-    // Locate the top row position.
-    size_t nOffsetInBlock = 0;
-    size_t nBlockStart = 0, nBlockEnd = 0, nRowPos = static_cast<size_t>(nRow1);
-    for (; itBlk != itBlkEnd; ++itBlk, nBlockStart = nBlockEnd)
-    {
-        nBlockEnd = nBlockStart + itBlk->size;
-        if (nBlockStart <= nRowPos && nRowPos < nBlockEnd)
-        {
-            // Found.
-            nOffsetInBlock = nRowPos - nBlockStart;
-            break;
-        }
+public:
+    CopyCellNotesHandler( const ScColumn& rSrcCol, ScColumn& rDestCol, SCROW nDestOffset, bool bCloneCaption ) :
+        mrDestCol(rDestCol),
+        mrDestNotes(rDestCol.GetCellNoteStore()),
+        miPos(mrDestNotes.begin()),
+        mnSrcTab(rSrcCol.GetTab()),
+        mnSrcCol(rSrcCol.GetCol()),
+        mnDestTab(rDestCol.GetTab()),
+        mnDestCol(rDestCol.GetCol()),
+        mnDestOffset(nDestOffset),
+        mbCloneCaption(bCloneCaption) {}
+
+    void operator() ( size_t nRow, const ScPostIt* p )
+    {
+        SCROW nDestRow = nRow + mnDestOffset;
+        ScAddress aSrcPos(mnSrcCol, nRow, mnSrcTab);
+        ScAddress aDestPos(mnDestCol, nDestRow, mnDestTab);
+        miPos = mrDestNotes.set(miPos, nDestRow, p->Clone(aSrcPos, mrDestCol.GetDoc(), aDestPos, mbCloneCaption));
     }
+};
 
-    if (itBlk == itBlkEnd)
-        // Specified range not found. Bail out.
-        return;
-
-    nRowPos = static_cast<size_t>(nRow2); // End row position.
-
-    // Keep copying until we hit the end row position.
-    sc::cellnote_block::const_iterator itData, itDataEnd;
-    for (; itBlk != itBlkEnd; ++itBlk, nBlockStart = nBlockEnd, nOffsetInBlock = 0)
-    {
-        nBlockEnd = nBlockStart + itBlk->size;
-
-        if (itBlk->data) // Non-empty block.
-        {
-            itData = sc::cellnote_block::begin(*itBlk->data);
-            itDataEnd = sc::cellnote_block::end(*itBlk->data);
-            std::advance(itData, nOffsetInBlock);
-
-            if (nBlockStart <= nRowPos && nRowPos < nBlockEnd)
-            {
-                // This block contains the end row. Only copy partially.
-                size_t nOffset = nRowPos - nBlockStart + 1;
-                itDataEnd = sc::cellnote_block::begin(*itBlk->data);
-                std::advance(itDataEnd, nOffset);
-                // need to clone notes
-                std::vector<ScPostIt*> vCloned;
-                vCloned.reserve(nOffset);
-                SCROW curRow = nBlockStart + nOffsetInBlock;
-                for (; itData != itDataEnd; ++itData, ++curRow)
-                {
-                    ScPostIt* pSrcNote = *itData;
-                    ScAddress aDestAddress = ScAddress(nDestCol, curRow + nRowOffsetDest, nDestTab);
-                    ScAddress aSrcAddress = ScAddress(nCol, curRow, nTab );
-                    ScPostIt* pClonedNote = pSrcNote->Clone(aSrcAddress, rDestCol.GetDoc(), aDestAddress, bCloneCaption );
-                    vCloned.push_back(pClonedNote);
-                }
-
-                rDestCol.maCellNotes.set(rDestCol.maCellNotes.begin(), nBlockStart + nOffsetInBlock + nRowOffsetDest, vCloned.begin(), vCloned.end());
-                break;
-            }
-            // need to clone notes
-            std::vector<ScPostIt*> vCloned;
-            vCloned.reserve(itBlk->size - nOffsetInBlock);
-            SCROW curRow = nBlockStart + nOffsetInBlock;
-            for (; itData != itDataEnd; ++itData, ++curRow)
-            {
-                ScPostIt* pSrcNote = *itData;
-                ScAddress aDestAddress = ScAddress(nDestCol, curRow + nRowOffsetDest, nDestTab);
-                ScAddress aSrcAddress = ScAddress(nCol, curRow, nTab );
-                ScPostIt* pClonedNote = pSrcNote->Clone(aSrcAddress, rDestCol.GetDoc(), aDestAddress, bCloneCaption );
-                vCloned.push_back(pClonedNote);
-            }
-            rDestCol.maCellNotes.set(rDestCol.maCellNotes.begin(), nBlockStart + nOffsetInBlock + nRowOffsetDest, vCloned.begin(), vCloned.end());
+}
 
-        }
-    }
+void ScColumn::CopyCellNotesToDocument(
+    SCROW nRow1, SCROW nRow2, ScColumn& rDestCol, bool bCloneCaption, SCROW nRowOffsetDest ) const
+{
+    CopyCellNotesHandler aFunc(*this, rDestCol, nRowOffsetDest, bCloneCaption);
+    sc::ParseNote(maCellNotes.begin(), maCellNotes, nRow1, nRow2, aFunc);
 }
 
 void ScColumn::DuplicateNotes(SCROW nStartRow, size_t nDataSize, ScColumn& rDestCol, sc::ColumnBlockPosition& maDestBlockPos,


More information about the Libreoffice-commits mailing list