[Libreoffice-commits] core.git: Branch 'feature/sc-notes-storage' - sc/inc sc/source

Laurent Godard lgodard.libre at laposte.net
Fri Oct 4 06:17:47 PDT 2013


 sc/inc/table.hxx               |    3 +
 sc/source/core/data/table2.cxx |   92 ++++++++++++++++++++++++++++++++++++-----
 2 files changed, 85 insertions(+), 10 deletions(-)

New commits:
commit 01cf555fce17302df186ce90584297bcfa074952
Author: Laurent Godard <lgodard.libre at laposte.net>
Date:   Fri Oct 4 15:16:39 2013 +0200

    refactor transpose clipboard for notes
    
    Change-Id: I174ac8b6e1a741513be4736cbca8d3d032f5a77f

diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx
index e35a656..43d18e7 100644
--- a/sc/inc/table.hxx
+++ b/sc/inc/table.hxx
@@ -1010,6 +1010,9 @@ private:
 
     SCCOL       FindNextVisibleCol(SCCOL nCol, bool bRight) const;
 
+    // Clipboard transpose for notes
+    void TransposeColNotes(ScTable* pTransClip, SCCOL nCol1, SCCOL nCol, SCROW nRow1, SCROW nRow2);
+
     /**
      * Use this to iterate through non-empty visible cells in a single column.
      */
diff --git a/sc/source/core/data/table2.cxx b/sc/source/core/data/table2.cxx
index d34dac6..1ed6ae1 100644
--- a/sc/source/core/data/table2.cxx
+++ b/sc/source/core/data/table2.cxx
@@ -929,27 +929,99 @@ void ScTable::TransposeClip( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
         }
 
         // Cell Notes - fdo#68381 paste cell notes on Transpose
-        bool bCloneCaption = true;
         if ( pDocument->HasColNotes(nCol, nTab) )
+            TransposeColNotes(pTransClip, nCol1, nCol, nRow1, nRow2);
+    }
+}
+
+void ScTable::TransposeColNotes(ScTable* pTransClip, SCCOL nCol1, SCCOL nCol, SCROW nRow1, SCROW nRow2)
+{
+    bool bCloneCaption = true;
+
+    sc::CellNoteStoreType::const_iterator itBlk = aCol[nCol].maCellNotes.begin(), itBlkEnd = aCol[nCol].maCellNotes.end();
+
+    // 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)
         {
-            sc::CellNoteStoreType& maCellNotes = pDocument->GetColNotes(nCol, nTab);
-            for (nRow=nRow1; nRow <= nRow2; nRow++) // TODO : notes suboptimal ?
+            // Found.
+            nOffsetInBlock = nRowPos - nBlockStart;
+            break;
+        }
+    }
+
+    if (itBlk != itBlkEnd)
+        // Specified range found
+    {
+        nRowPos = static_cast<size_t>(nRow2); // End row position.
+
+        // Keep processing 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)
             {
-                ScAddress aDestPos( static_cast<SCCOL>(nRow-nRow1), static_cast<SCROW>(nCol-nCol1), pTransClip->nTab );
-                pTransClip->pDocument->ReleaseNote(aDestPos);
+                itData = sc::cellnote_block::begin(*itBlk->data);
+                std::advance(itData, nOffsetInBlock);
 
-                ScPostIt* pNote = maCellNotes.get<ScPostIt*>(nRow);
-                if (pNote)
+                if (nBlockStart <= nRowPos && nRowPos < nBlockEnd)
+                {
+                    // This block contains the end row. Only process partially.
+                    size_t nOffsetEnd = nRowPos - nBlockStart + 1;
+                    itDataEnd = sc::cellnote_block::begin(*itBlk->data);
+                    std::advance(itDataEnd, nOffsetEnd);
+                    size_t curRow = nBlockStart + nOffsetInBlock;
+                    for (; itData != itDataEnd; ++itData, ++curRow)
+                    {
+                        ScAddress aDestPos( static_cast<SCCOL>(curRow-nRow1), static_cast<SCROW>(nCol-nCol1), pTransClip->nTab );
+                        pTransClip->pDocument->ReleaseNote(aDestPos);
+                        ScPostIt* pNote = *itData;
+                        if (pNote)
+                        {
+                            ScPostIt* pClonedNote = pNote->Clone( ScAddress(nCol, curRow, nTab), *pTransClip->pDocument, aDestPos, bCloneCaption );
+                            pTransClip->pDocument->SetNote(aDestPos, pClonedNote);
+                        }
+                    }
+                    break; // we reached the last valid block
+                }
+                else
                 {
-                    ScPostIt* pClonedNote = pNote->Clone( ScAddress(nCol, nRow, nTab), *pDestDoc, aDestPos, bCloneCaption );
-                    pTransClip->pDocument->SetNote(aDestPos, pClonedNote);
+                    itDataEnd = sc::cellnote_block::end(*itBlk->data);
+                    size_t curRow = nBlockStart + nOffsetInBlock;
+                    for (; itData != itDataEnd; ++itData, ++curRow)
+                    {
+                        ScAddress aDestPos( static_cast<SCCOL>(curRow-nRow1), static_cast<SCROW>(nCol-nCol1), pTransClip->nTab );
+                        pTransClip->pDocument->ReleaseNote(aDestPos);
+                        ScPostIt* pNote = *itData;
+                        if (pNote)
+                        {
+                            ScPostIt* pClonedNote = pNote->Clone( ScAddress(nCol, curRow, nTab), *pTransClip->pDocument, aDestPos, bCloneCaption );
+                            pTransClip->pDocument->SetNote(aDestPos, pClonedNote);
+                        }
+                    }
+                }
+            }
+            else
+            {
+                size_t curRow;
+                for ( curRow = nBlockStart + nOffsetInBlock; curRow <= nBlockEnd && curRow <= nRowPos; ++curRow)
+                {
+                    ScAddress aDestPos( static_cast<SCCOL>(curRow-nRow1), static_cast<SCROW>(nCol-nCol1), pTransClip->nTab );
+                    pTransClip->pDocument->ReleaseNote(aDestPos);
                 }
+                if (curRow == nRowPos)
+                    break;
             }
         }
     }
 }
 
-
 void ScTable::StartAllListeners()
 {
     for (SCCOL i=0; i<=MAXCOL; i++)


More information about the Libreoffice-commits mailing list