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.yosh...@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.mohrh...@googlemail.com> Tested-by: Markus Mohrhard <markus.mohrh...@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, _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits