summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKohei Yoshida <kohei.yoshida@collabora.com>2014-02-17 12:20:57 -0500
committerCaolán McNamara <caolanm@redhat.com>2014-02-21 12:49:37 +0000
commite285e059b6a03b426a0f64ff3686966802d040c3 (patch)
tree5e9169ebd3ddc23c7b0ca3f817ce32d56c73683f
parent50b46373b06545b81c68efc9f183cc5670c8517a (diff)
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@googlemail.com> Tested-by: Markus Mohrhard <markus.mohrhard@googlemail.com> Reviewed-on: https://gerrit.libreoffice.org/8138 Reviewed-by: Caolán McNamara <caolanm@redhat.com> Tested-by: Caolán McNamara <caolanm@redhat.com>
-rw-r--r--sc/inc/column.hxx2
-rw-r--r--sc/inc/mtvcellfunc.hxx11
-rw-r--r--sc/source/core/data/column2.cxx111
3 files changed, 50 insertions, 74 deletions
diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index c6db640a8c64..529f84fff22b 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 fc6d2dcd74b0..d5e79218a350 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 1d287805dec3..ae1a722364e3 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,