diff options
author | Kohei Yoshida <kohei.yoshida@collabora.com> | 2014-02-17 21:57:01 -0500 |
---|---|---|
committer | Kohei Yoshida <kohei.yoshida@collabora.com> | 2014-02-17 22:26:40 -0500 |
commit | 575e88da278f536ebfb6562dfd98f341240afec4 (patch) | |
tree | c1791559e13589647c88e4d4e09ab3034c876604 | |
parent | 93d2cd25597c519029ec12bbaefd6c518890beed (diff) |
fdo#75032: Handle note copying correctly.
Change-Id: I1b8fa5231b23554c856fb63b580cb13ea9223b08
-rw-r--r-- | sc/inc/column.hxx | 2 | ||||
-rw-r--r-- | sc/inc/mtvcellfunc.hxx | 11 | ||||
-rw-r--r-- | sc/source/core/data/column2.cxx | 111 | ||||
-rw-r--r-- | sc/source/ui/undo/undoblk.cxx | 5 |
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 ); |