summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKohei Yoshida <kohei.yoshida@collabora.com>2014-02-17 21:57:01 -0500
committerKohei Yoshida <kohei.yoshida@collabora.com>2014-02-17 22:26:40 -0500
commit575e88da278f536ebfb6562dfd98f341240afec4 (patch)
treec1791559e13589647c88e4d4e09ab3034c876604
parent93d2cd25597c519029ec12bbaefd6c518890beed (diff)
fdo#75032: Handle note copying correctly.
Change-Id: I1b8fa5231b23554c856fb63b580cb13ea9223b08
-rw-r--r--sc/inc/column.hxx2
-rw-r--r--sc/inc/mtvcellfunc.hxx11
-rw-r--r--sc/source/core/data/column2.cxx111
-rw-r--r--sc/source/ui/undo/undoblk.cxx5
4 files changed, 51 insertions, 78 deletions
diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index 7f91d9050949..9b362702a6ad 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -171,6 +171,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 639097933b8e..e203878ed561 100644
--- a/sc/source/core/data/column2.cxx
+++ b/sc/source/core/data/column2.cxx
@@ -1644,85 +1644,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,
diff --git a/sc/source/ui/undo/undoblk.cxx b/sc/source/ui/undo/undoblk.cxx
index 694e17122c34..2b30fed702f8 100644
--- a/sc/source/ui/undo/undoblk.cxx
+++ b/sc/source/ui/undo/undoblk.cxx
@@ -414,11 +414,8 @@ void ScUndoDeleteCells::DoChange( const sal_Bool bUndo )
// if Undo, restore references
for( i=0; i<nCount && bUndo; i++ )
{
- // Cell note objects are handled separately. Ignore them here.
- sal_uInt16 nFlags = IDF_ALL;
- nFlags &= ~IDF_NOTE;
pRefUndoDoc->CopyToDocument( aEffRange.aStart.Col(), aEffRange.aStart.Row(), pTabs[i], aEffRange.aEnd.Col(), aEffRange.aEnd.Row(), pTabs[i]+pScenarios[i],
- nFlags, false, pDoc );
+ IDF_ALL | IDF_NOCAPTIONS, false, pDoc );
}
ScRange aWorkRange( aEffRange );