diff options
author | Laurent Godard <lgodard.libre@laposte.net> | 2013-09-11 09:06:24 +0200 |
---|---|---|
committer | Kohei Yoshida <kohei.yoshida@collabora.com> | 2013-10-23 10:44:20 -0400 |
commit | 759bdbbc348d320994813a9de1a7927b795580a3 (patch) | |
tree | 897cb53c217866ce6b365f76943390e3e6368529 /sc/source | |
parent | ae88290f87acf693fed02140ca384ec15589616b (diff) |
Re-implement cell note storage using mdds::multi_type_vector.
Change-Id: I34ea91e360e2a6b85d65f970c6e43db687d213ca
Diffstat (limited to 'sc/source')
38 files changed, 932 insertions, 927 deletions
diff --git a/sc/source/core/data/clipcontext.cxx b/sc/source/core/data/clipcontext.cxx index 782c0f98f70f..8013684867ee 100644 --- a/sc/source/core/data/clipcontext.cxx +++ b/sc/source/core/data/clipcontext.cxx @@ -29,7 +29,10 @@ CopyFromClipContext::CopyFromClipContext(ScDocument& rDoc, ClipContextBase(rDoc), mnTabStart(-1), mnTabEnd(-1), mpRefUndoDoc(pRefUndoDoc), mpClipDoc(pClipDoc), mnInsertFlag(nInsertFlag), - mbAsLink(bAsLink), mbSkipAttrForEmptyCells(bSkipAttrForEmptyCells) {} + mbAsLink(bAsLink), mbSkipAttrForEmptyCells(bSkipAttrForEmptyCells), + mbCloneNotes (mnInsertFlag & (IDF_NOTE|IDF_ADDNOTES) ) +{ +} CopyFromClipContext::~CopyFromClipContext() { @@ -76,6 +79,11 @@ bool CopyFromClipContext::isSkipAttrForEmptyCells() const return mbSkipAttrForEmptyCells; } +bool CopyFromClipContext::isCloneNotes() const +{ + return mbCloneNotes; +} + CopyToClipContext::CopyToClipContext( ScDocument& rDoc, bool bKeepScenarioFlags, bool bCloneNotes) : ClipContextBase(rDoc), mbKeepScenarioFlags(bKeepScenarioFlags), mbCloneNotes(bCloneNotes) {} diff --git a/sc/source/core/data/column.cxx b/sc/source/core/data/column.cxx index 6e356ee73fb8..63433c558353 100644 --- a/sc/source/core/data/column.cxx +++ b/sc/source/core/data/column.cxx @@ -76,6 +76,7 @@ ScNeededSizeOptions::ScNeededSizeOptions() : ScColumn::ScColumn() : maCellTextAttrs(MAXROWCOUNT), + maCellNotes(MAXROWCOUNT), maBroadcasters(MAXROWCOUNT), maCells(MAXROWCOUNT), nCol( 0 ), @@ -887,6 +888,7 @@ void ScColumn::SwapRow(SCROW nRow1, SCROW nRow2) } SwapCellTextAttrs(nRow1, nRow2); + SwapCellNotes(nRow1, nRow2); CellStorageModified(); BroadcastCells(aRows); return; @@ -934,6 +936,7 @@ void ScColumn::SwapRow(SCROW nRow1, SCROW nRow2) } SwapCellTextAttrs(nRow1, nRow2); + SwapCellNotes(nRow1, nRow2); CellStorageModified(); BroadcastCells(aRows); return; @@ -978,6 +981,7 @@ void ScColumn::SwapRow(SCROW nRow1, SCROW nRow2) } SwapCellTextAttrs(nRow1, nRow2); + SwapCellNotes(nRow1, nRow2); CellStorageModified(); BroadcastCells(aRows); return; @@ -1111,6 +1115,7 @@ void ScColumn::SwapRow(SCROW nRow1, SCROW nRow2) } SwapCellTextAttrs(nRow1, nRow2); + SwapCellNotes(nRow1, nRow2); CellStorageModified(); BroadcastCells(aRows); } @@ -1153,6 +1158,7 @@ void ScColumn::SwapCell( SCROW nRow, ScColumn& rCol) maCells.swap(nRow, nRow, rCol.maCells, nRow); maCellTextAttrs.swap(nRow, nRow, rCol.maCellTextAttrs, nRow); + maCellNotes.swap(nRow, nRow, rCol.maCellNotes, nRow); aPos1 = maCells.position(nRow); aPos2 = rCol.maCells.position(nRow); @@ -1232,6 +1238,9 @@ void ScColumn::InsertRow( SCROW nStartRow, SCSIZE nSize ) { pAttrArray->InsertRow( nStartRow, nSize ); + maCellNotes.insert_empty(nStartRow, nSize); + maCellNotes.resize(MAXROWCOUNT); + maBroadcasters.insert_empty(nStartRow, nSize); maBroadcasters.resize(MAXROWCOUNT); @@ -1255,6 +1264,7 @@ class CopyToClipHandler ScColumn& mrDestCol; sc::ColumnBlockPosition maDestPos; sc::ColumnBlockPosition* mpDestPos; + bool mbCopyNotes; void setDefaultAttrsToDest(size_t nRow, size_t nSize) { @@ -1293,9 +1303,14 @@ class CopyToClipHandler } } + void duplicateNotes(SCROW nStartRow, size_t nDataSize ) + { + mrSrcCol.DuplicateNotes(nStartRow, nDataSize, mrDestCol, maDestPos); + } + public: - CopyToClipHandler(const ScColumn& rSrcCol, ScColumn& rDestCol, sc::ColumnBlockPosition* pDestPos) : - mrSrcCol(rSrcCol), mrDestCol(rDestCol), mpDestPos(pDestPos) + CopyToClipHandler(const ScColumn& rSrcCol, ScColumn& rDestCol, sc::ColumnBlockPosition* pDestPos, bool bCopyNotes) : + mrSrcCol(rSrcCol), mrDestCol(rDestCol), mpDestPos(pDestPos), mbCopyNotes(bCopyNotes) { if (mpDestPos) maDestPos = *mpDestPos; @@ -1313,6 +1328,8 @@ public: { size_t nTopRow = aNode.position + nOffset; + bool bSet = true; + switch (aNode.type) { case sc::element_type_numeric: @@ -1322,7 +1339,6 @@ public: sc::numeric_block::const_iterator itEnd = it; std::advance(itEnd, nDataSize); maDestPos.miCellPos = mrDestCol.GetCellStore().set(maDestPos.miCellPos, nTopRow, it, itEnd); - setDefaultAttrsToDest(nTopRow, nDataSize); } break; case sc::element_type_string: @@ -1332,7 +1348,7 @@ public: sc::string_block::const_iterator itEnd = it; std::advance(itEnd, nDataSize); maDestPos.miCellPos = mrDestCol.GetCellStore().set(maDestPos.miCellPos, nTopRow, it, itEnd); - setDefaultAttrsToDest(nTopRow, nDataSize); + } break; case sc::element_type_edittext: @@ -1349,8 +1365,6 @@ public: maDestPos.miCellPos = mrDestCol.GetCellStore().set( maDestPos.miCellPos, nTopRow, aCloned.begin(), aCloned.end()); - - setDefaultAttrsToDest(nTopRow, nDataSize); } break; case sc::element_type_formula: @@ -1391,13 +1405,17 @@ public: aPos = rDestCells.position(maDestPos.miCellPos, nLastRow+1); sc::SharedFormulaUtil::joinFormulaCellAbove(aPos); } - - setDefaultAttrsToDest(nTopRow, nDataSize); } break; default: - ; + bSet = false; } + + if (bSet) + setDefaultAttrsToDest(nTopRow, nDataSize); + + if (mbCopyNotes) + duplicateNotes(nTopRow, nDataSize); } }; @@ -1409,8 +1427,9 @@ void ScColumn::CopyToClip( pAttrArray->CopyArea( nRow1, nRow2, 0, *rColumn.pAttrArray, rCxt.isKeepScenarioFlags() ? (SC_MF_ALL & ~SC_MF_SCENARIO) : SC_MF_ALL ); - CopyToClipHandler aFunc(*this, rColumn, rCxt.getBlockPosition(rColumn.nTab, rColumn.nCol)); + CopyToClipHandler aFunc(*this, rColumn, rCxt.getBlockPosition(rColumn.nTab, rColumn.nCol), rCxt.isCloneNotes()); sc::ParseBlock(maCells.begin(), maCells, aFunc, nRow1, nRow2); + rColumn.CellStorageModified(); } @@ -1421,6 +1440,7 @@ void ScColumn::CopyStaticToDocument(SCROW nRow1, SCROW nRow2, ScColumn& rDestCol sc::ColumnBlockPosition aDestPos; CopyCellTextAttrsToDocument(nRow1, nRow2, rDestCol); + CopyCellNotesToDocument(nRow1, nRow2, rDestCol); // First, clear the destination column for the specified row range. rDestCol.maCells.set_empty(nRow1, nRow2); @@ -1567,9 +1587,17 @@ void ScColumn::CopyCellToDocument( SCROW nSrcRow, SCROW nDestRow, ScColumn& rDes } if (bSet) + { rDestCol.maCellTextAttrs.set(nDestRow, maCellTextAttrs.get<sc::CellTextAttr>(nSrcRow)); + ScPostIt* pNote = maCellNotes.get<ScPostIt*>(nSrcRow); + rDestCol.maCellNotes.set(nDestRow, pNote); + pNote->UpdateCaptionPos(ScAddress(rDestCol.nCol, nDestRow, rDestCol.nTab)); + } else + { rDestCol.maCellTextAttrs.set_empty(nDestRow, nDestRow); + rDestCol.maCellNotes.set_empty(nDestRow, nDestRow); + } rDestCol.CellStorageModified(); } @@ -1631,6 +1659,11 @@ class CopyAsLinkHandler setDefaultAttrsToDest(nTopRow, nDataSize); } + void duplicateNotes(SCROW nStartRow, size_t nDataSize, bool bCloneCaption ) + { + mrSrcCol.DuplicateNotes(nStartRow, nDataSize, mrDestCol, maDestPos, bCloneCaption); + } + public: CopyAsLinkHandler(const ScColumn& rSrcCol, ScColumn& rDestCol, sc::ColumnBlockPosition* pDestPos, sal_uInt16 nCopyFlags) : mrSrcCol(rSrcCol), mrDestCol(rDestCol), mpDestPos(pDestPos), mnCopyFlags(nCopyFlags) @@ -1649,6 +1682,12 @@ public: { size_t nRow = aNode.position + nOffset; + if (mnCopyFlags & (IDF_NOTE|IDF_ADDNOTES)) + { + bool bCloneCaption = (mnCopyFlags & IDF_NOCAPTIONS) == 0; + duplicateNotes(nRow, nDataSize, bCloneCaption ); + } + switch (aNode.type) { case sc::element_type_numeric: @@ -1808,6 +1847,11 @@ class CopyByCloneHandler } } + void duplicateNotes(SCROW nStartRow, size_t nDataSize, bool bCloneCaption ) + { + mrSrcCol.DuplicateNotes(nStartRow, nDataSize, mrDestCol, maDestPos, bCloneCaption); + } + public: CopyByCloneHandler(const ScColumn& rSrcCol, ScColumn& rDestCol, sc::ColumnBlockPosition* pDestPos, sal_uInt16 nCopyFlags) : mrSrcCol(rSrcCol), mrDestCol(rDestCol), mpDestPos(pDestPos), mnCopyFlags(nCopyFlags) @@ -1826,6 +1870,12 @@ public: { size_t nRow = aNode.position + nOffset; + if (mnCopyFlags & (IDF_NOTE|IDF_ADDNOTES)) + { + bool bCloneCaption = (mnCopyFlags & IDF_NOCAPTIONS) == 0; + duplicateNotes(nRow, nDataSize, bCloneCaption ); + } + switch (aNode.type) { case sc::element_type_numeric: @@ -1891,7 +1941,7 @@ public: std::vector<EditTextObject*> aCloned; aCloned.reserve(nDataSize); - for (; it != itEnd; ++it) + for (; it != itEnd; ++it, ++nRow) aCloned.push_back(ScEditUtil::Clone(**it, mrDestCol.GetDoc())); maDestPos.miCellPos = mrDestCol.GetCellStore().set( @@ -2011,7 +2061,8 @@ void ScColumn::CopyUpdated( const ScColumn& rPosCol, ScColumn& rDestCol ) const sc::SingleColumnSpanSet::SpansType aRanges; aRangeSet.getSpans(aRanges); - CopyToClipHandler aFunc(*this, rDestCol, NULL); + bool bCopyNotes = true; + CopyToClipHandler aFunc(*this, rDestCol, NULL, bCopyNotes); sc::CellStoreType::const_iterator itPos = maCells.begin(); sc::SingleColumnSpanSet::SpansType::const_iterator it = aRanges.begin(), itEnd = aRanges.end(); for (; it != itEnd; ++it) @@ -2144,11 +2195,44 @@ void resetColumnPosition(sc::CellStoreType& rCells, SCCOL nCol) } +void ScColumn::UpdateNoteCaptions() +{ + sc::CellNoteStoreType::const_iterator itBlk = maCellNotes.begin(), itBlkEnd = maCellNotes.end(); + sc::cellnote_block::const_iterator itData, itDataEnd; + + SCROW curRow = 0; + for (;itBlk==itBlkEnd;++itBlk) + { + if (itBlk->data) + { + // non empty block + itData = sc::cellnote_block::begin(*itBlk->data); + itDataEnd = sc::cellnote_block::end(*itBlk->data); + for(;itData==itDataEnd; ++itData) + { + ScPostIt* pNote = *itData; + pNote->UpdateCaptionPos(ScAddress(nCol, curRow, nTab)); + curRow +=1; + } + } + else + { + // empty block + curRow += itBlk->size; + } + } +} + void ScColumn::SwapCol(ScColumn& rCol) { maBroadcasters.swap(rCol.maBroadcasters); maCells.swap(rCol.maCells); maCellTextAttrs.swap(rCol.maCellTextAttrs); + maCellNotes.swap(rCol.maCellNotes); + + // notes update caption + UpdateNoteCaptions(); + rCol.UpdateNoteCaptions(); ScAttrArray* pTempAttr = rCol.pAttrArray; rCol.pAttrArray = pAttrArray; @@ -2195,6 +2279,10 @@ void ScColumn::MoveTo(SCROW nStartRow, SCROW nEndRow, ScColumn& rCol) maCells.transfer(nStartRow, nEndRow, rCol.maCells, nStartRow); maCellTextAttrs.transfer(nStartRow, nEndRow, rCol.maCellTextAttrs, nStartRow); + // move the notes to the destination column + maCellNotes.transfer(nStartRow, nEndRow, rCol.maCellNotes, nStartRow); + UpdateNoteCaptions(); + // Re-group transferred formula cells. aPos = rCol.maCells.position(nStartRow); sc::SharedFormulaUtil::joinFormulaCellAbove(aPos); diff --git a/sc/source/core/data/column2.cxx b/sc/source/core/data/column2.cxx index e3393057eae9..0027ed8d2a91 100644 --- a/sc/source/core/data/column2.cxx +++ b/sc/source/core/data/column2.cxx @@ -1197,6 +1197,23 @@ bool ScColumn::IsEmptyBlock(SCROW nStartRow, SCROW nEndRow) const return nEndRow < nNextRow; } +bool ScColumn::IsNotesEmptyBlock(SCROW nStartRow, SCROW nEndRow) const +{ + std::pair<sc::CellNoteStoreType::const_iterator,size_t> aPos = maCellNotes.position(nStartRow); + sc::CellNoteStoreType::const_iterator it = aPos.first; + if (it == maCellNotes.end()) + // Invalid row number. + return false; + + if (it->type != sc::element_type_empty) + // Non-empty cell at the start position. + return false; + + // start position of next block which is not empty. + SCROW nNextRow = nStartRow + it->size - aPos.second; + return nEndRow < nNextRow; +} + SCSIZE ScColumn::GetEmptyLinesInBlock( SCROW nStartRow, SCROW nEndRow, ScDirection eDir ) const { // Given a range of rows, find a top or bottom empty segment. @@ -1629,21 +1646,107 @@ void ScColumn::CopyCellTextAttrsToDocument(SCROW nRow1, SCROW nRow2, ScColumn& r } } -void ScColumn::SwapCellTextAttrs( SCROW nRow1, SCROW nRow2 ) +void ScColumn::CopyCellNotesToDocument(SCROW nRow1, SCROW nRow2, ScColumn& rDestCol, bool bCloneCaption, SCROW nRowOffsetDest) const { - typedef std::pair<sc::CellTextAttrStoreType::iterator,size_t> PosType; + SCCOL nDestCol = rDestCol.GetCol(); + SCTAB nDestTab = rDestCol.GetTab(); + + rDestCol.maCellNotes.set_empty(nRow1 + nRowOffsetDest, nRow2 + nRowOffsetDest); // Empty the destination range first. + + sc::CellNoteStoreType::const_iterator itBlk = maCellNotes.begin(), itBlkEnd = 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) + { + // Found. + nOffsetInBlock = nRowPos - nBlockStart; + break; + } + } + + 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::DuplicateNotes(SCROW nStartRow, size_t nDataSize, ScColumn& rDestCol, sc::ColumnBlockPosition& maDestBlockPos, + bool bCloneCaption, SCROW nRowOffsetDest ) const +{ + CopyCellNotesToDocument(nStartRow, nStartRow + nDataSize -1, rDestCol, bCloneCaption, nRowOffsetDest); + maDestBlockPos.miCellNotePos = rDestCol.maCellNotes.begin(); +} + +void ScColumn::SwapCellTextAttrs( SCROW nRow1, SCROW nRow2 ) +{ if (nRow1 == nRow2) return; if (nRow1 > nRow2) std::swap(nRow1, nRow2); - PosType aPos1 = maCellTextAttrs.position(nRow1); + sc::CellTextAttrStoreType::position_type aPos1 = maCellTextAttrs.position(nRow1); if (aPos1.first == maCellTextAttrs.end()) return; - PosType aPos2 = maCellTextAttrs.position(aPos1.first, nRow2); + sc::CellTextAttrStoreType::position_type aPos2 = maCellTextAttrs.position(aPos1.first, nRow2); if (aPos2.first == maCellTextAttrs.end()) return; @@ -1680,6 +1783,66 @@ void ScColumn::SwapCellTextAttrs( SCROW nRow1, SCROW nRow2 ) CellStorageModified(); } +void ScColumn::SwapCellNotes( SCROW nRow1, SCROW nRow2 ) +{ + if (nRow1 == nRow2) + return; + + if (nRow1 > nRow2) + std::swap(nRow1, nRow2); + + sc::CellNoteStoreType::position_type aPos1 = maCellNotes.position(nRow1); + if (aPos1.first == maCellNotes.end()) + return; + + sc::CellNoteStoreType::position_type aPos2 = maCellNotes.position(aPos1.first, nRow2); + if (aPos2.first == maCellNotes.end()) + return; + + ScPostIt* aNote; + + sc::CellNoteStoreType::iterator it1 = aPos1.first, it2 = aPos2.first; + if (it1->type == it2->type) + { + if (it1->type == sc::element_type_empty) + // Both are empty. Nothing to swap. + return; + + // Both are non-empty. Simply swap their values. + std::swap( + sc::cellnote_block::at(*it1->data, aPos1.second), + sc::cellnote_block::at(*it2->data, aPos2.second)); + + //update Note caption with position + aNote = sc::cellnote_block::at(*it1->data, aPos1.second); + aNote->UpdateCaptionPos(ScAddress(nCol,nRow2,nTab)); + aNote = sc::cellnote_block::at(*it2->data, aPos2.second); + aNote->UpdateCaptionPos(ScAddress(nCol,nRow1,nTab)); + + return; + } + + // One is empty while the other isn't. + if (it1->type == sc::element_type_empty) + { + // row 1 is empty while row 2 is non-empty. + ScPostIt* pVal2 = sc::cellnote_block::at(*it2->data, aPos2.second); + it1 = maCellNotes.set(it1, nRow1, pVal2); + maCellNotes.set_empty(it1, nRow2, nRow2); + pVal2->UpdateCaptionPos(ScAddress(nCol,nRow1,nTab)); //update Note caption with position + + return; + } + + // row 1 is non-empty while row 2 is empty. + ScPostIt* pVal1 = sc::cellnote_block::at(*it1->data, aPos1.second); + it1 = maCellNotes.set_empty(it1, nRow1, nRow1); + maCellNotes.set(it1, nRow2, pVal1); + pVal1->UpdateCaptionPos(ScAddress(nCol,nRow1,nTab)); //update Note caption with position + + CellStorageModified(); +} + SvtBroadcaster* ScColumn::GetBroadcaster(SCROW nRow) { return maBroadcasters.get<SvtBroadcaster*>(nRow); @@ -1708,6 +1871,72 @@ bool ScColumn::HasBroadcaster() const return false; } +ScPostIt* ScColumn::GetCellNote(SCROW nRow) +{ + return maCellNotes.get<ScPostIt*>(nRow); +} + +const ScPostIt* ScColumn::GetCellNote(SCROW nRow) const +{ + return maCellNotes.get<ScPostIt*>(nRow); +} + +void ScColumn::SetCellNote(SCROW nRow, ScPostIt* pNote) +{ + //pNote->UpdateCaptionPos(ScAddress(nCol, nRow, nTab)); // TODO notes usefull ? slow import with many notes + maCellNotes.set(nRow, pNote); +} +void ScColumn::DeleteCellNote(SCROW nRow) +{ + maCellNotes.set_empty(nRow, nRow); +} +void ScColumn::DeleteCellNotes( sc::ColumnBlockPosition& rBlockPos, SCROW nRow1, SCROW nRow2 ) +{ + rBlockPos.miCellNotePos = + maCellNotes.set_empty(rBlockPos.miCellNotePos, nRow1, nRow2); +} + +bool ScColumn::HasCellNotes() const +{ + sc::CellNoteStoreType::const_iterator it = maCellNotes.begin(), itEnd = maCellNotes.end(); + for (; it != itEnd; ++it) + { + if (it->type == sc::element_type_cellnote) + // Having a cellnote block automatically means there is at least one cell note. + return true; + } + return false; +} + +SCROW ScColumn::GetCellNotesMaxRow() const +{ + // hypothesis : the column has cell notes (should be checked before) + SCROW maxRow = 0; + sc::CellNoteStoreType::const_iterator it = maCellNotes.begin(), itEnd = maCellNotes.end(); + for (; it != itEnd; ++it) + { + if (it->type == sc::element_type_cellnote) + maxRow = it->position + it->size -1; + } + return maxRow; +} +SCROW ScColumn::GetCellNotesMinRow() const +{ + // hypothesis : the column has cell notes (should be checked before) + SCROW minRow = 0; + bool bFound = false; + sc::CellNoteStoreType::const_iterator it = maCellNotes.begin(), itEnd = maCellNotes.end(); + for (; it != itEnd && !bFound; ++it) + { + if (it->type == sc::element_type_cellnote) + { + bFound = true; + minRow = it->position; + } + } + return minRow; +} + sal_uInt16 ScColumn::GetTextWidth(SCROW nRow) const { return maCellTextAttrs.get<sc::CellTextAttr>(nRow).mnTextWidth; diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx index b344e37e6028..c90a33e11644 100644 --- a/sc/source/core/data/column3.cxx +++ b/sc/source/core/data/column3.cxx @@ -119,6 +119,7 @@ void ScColumn::Delete( SCROW nRow ) } maCells.set_empty(nRow, nRow); maCellTextAttrs.set_empty(nRow, nRow); + maCellNotes.set_empty(nRow, nRow); Broadcast(nRow); CellStorageModified(); @@ -131,6 +132,8 @@ void ScColumn::FreeAll() maCells.resize(MAXROWCOUNT); maCellTextAttrs.clear(); maCellTextAttrs.resize(MAXROWCOUNT); + maCellNotes.clear(); + maCellNotes.resize(MAXROWCOUNT); CellStorageModified(); } @@ -216,6 +219,9 @@ void ScColumn::DeleteRow( SCROW nStartRow, SCSIZE nSize ) maBroadcasters.erase(nStartRow, nEndRow); maBroadcasters.resize(MAXROWCOUNT); + maCellNotes.erase(nStartRow, nEndRow); + maCellNotes.resize(MAXROWCOUNT); + // See if we have any cells that would get deleted or shifted by deletion. sc::CellStoreType::position_type aPos = maCells.position(nStartRow); sc::CellStoreType::iterator itCell = aPos.first; @@ -285,6 +291,10 @@ void ScColumn::DeleteRow( SCROW nStartRow, SCSIZE nSize ) maCellTextAttrs.erase(nStartRow, nEndRow); maCellTextAttrs.resize(MAXROWCOUNT); + // Shift the cell notes array too (before the broadcast). + maCellNotes.erase(nStartRow, nEndRow); + maCellNotes.resize(MAXROWCOUNT); + CellStorageModified(); if (!bShiftCells) @@ -588,6 +598,10 @@ void ScColumn::DeleteArea(SCROW nStartRow, SCROW nEndRow, sal_uInt16 nDelFlag) sc::ColumnBlockPosition aBlockPos; aBlockPos.miCellPos = itPos; aBlockPos.miCellTextAttrPos = maCellTextAttrs.begin(); + aBlockPos.miCellNotePos = maCellNotes.begin(); + + if ( nDelFlag & IDF_NOTE ) + DeleteCellNotes( aBlockPos, nStartRow, nEndRow ); // Delete the cells for real. std::for_each(aSpans.begin(), aSpans.end(), EmptyCells(aBlockPos, *this)); @@ -614,6 +628,7 @@ void ScColumn::DeleteArea(SCROW nStartRow, SCROW nEndRow, sal_uInt16 nDelFlag) bool ScColumn::InitBlockPosition( sc::ColumnBlockPosition& rBlockPos ) { rBlockPos.miBroadcasterPos = maBroadcasters.begin(); + rBlockPos.miCellNotePos = maCellNotes.begin(); rBlockPos.miCellTextAttrPos = maCellTextAttrs.begin(); rBlockPos.miCellPos = maCells.begin(); return true; @@ -622,6 +637,7 @@ bool ScColumn::InitBlockPosition( sc::ColumnBlockPosition& rBlockPos ) bool ScColumn::InitBlockPosition( sc::ColumnBlockConstPosition& rBlockPos ) const { rBlockPos.miBroadcasterPos = maBroadcasters.begin(); + rBlockPos.miCellNotePos = maCellNotes.begin(); rBlockPos.miCellTextAttrPos = maCellTextAttrs.begin(); rBlockPos.miCellPos = maCells.begin(); return true; @@ -652,6 +668,8 @@ class CopyCellsFromClipHandler ScColumn& mrDestCol; SCTAB mnTab; SCCOL mnCol; + SCTAB mnSrcTab; + SCCOL mnSrcCol; long mnRowOffset; sc::ColumnBlockPosition maDestBlockPos; sc::ColumnBlockPosition* mpDestBlockPos; // to save it for next iteration. @@ -679,6 +697,11 @@ class CopyCellsFromClipHandler maDestBlockPos, nDestRow, new ScFormulaCell(&mrDestCol.GetDoc(), aDestPos, &aArr)); } + void duplicateNotes(SCROW nStartRow, size_t nDataSize, bool bCloneCaption ) + { + mrSrcCol.DuplicateNotes(nStartRow, nDataSize, mrDestCol, maDestBlockPos, bCloneCaption, mnRowOffset); + } + public: CopyCellsFromClipHandler(sc::CopyFromClipContext& rCxt, ScColumn& rSrcCol, ScColumn& rDestCol, SCTAB nDestTab, SCCOL nDestCol, long nRowOffset) : mrCxt(rCxt), @@ -686,6 +709,8 @@ public: mrDestCol(rDestCol), mnTab(nDestTab), mnCol(nDestCol), + mnSrcTab(rSrcCol.GetTab()), + mnSrcCol(rSrcCol.GetCol()), mnRowOffset(nRowOffset), mpDestBlockPos(mrCxt.getBlockPosition(nDestTab, nDestCol)) { @@ -704,12 +729,22 @@ public: void operator() (const sc::CellStoreType::value_type& node, size_t nOffset, size_t nDataSize) { - if (node.type == sc::element_type_empty) - return; SCROW nSrcRow1 = node.position + nOffset; + bool bCopyCellNotes = mrCxt.isCloneNotes(); sal_uInt16 nFlags = mrCxt.getInsertFlag(); + + if (node.type == sc::element_type_empty) + { + if (bCopyCellNotes) + { + bool bCloneCaption = (nFlags & IDF_NOCAPTIONS) == 0; + duplicateNotes(nSrcRow1, nDataSize, bCloneCaption ); + } + return; + } + bool bNumeric = (nFlags & IDF_VALUE) != 0; bool bDateTime = (nFlags & IDF_DATETIME) != 0; bool bString = (nFlags & IDF_STRING) != 0; @@ -871,6 +906,11 @@ public: default: ; } + if (bCopyCellNotes) + { + bool bCloneCaption = (nFlags & IDF_NOCAPTIONS) == 0; + duplicateNotes(nSrcRow1, nDataSize, bCloneCaption ); + } } }; @@ -1622,6 +1662,7 @@ void ScColumn::SetEditText( sc::ColumnBlockPosition& rBlockPos, SCROW nRow, Edit rBlockPos.miCellPos = maCells.set(rBlockPos.miCellPos, nRow, pEditText); rBlockPos.miCellTextAttrPos = maCellTextAttrs.set( rBlockPos.miCellTextAttrPos, nRow, sc::CellTextAttr()); + CellStorageModified(); BroadcastNewCell(nRow); @@ -1672,6 +1713,9 @@ void ScColumn::SetFormula( SCROW nRow, const ScTokenArray& rArray, formula::Form pCell->SetNeedNumberFormat(true); it = maCells.set(it, nRow, pCell); maCellTextAttrs.set(nRow, sc::CellTextAttr()); +// ScPostIt* pPostIt; +// maCellNotes.set(nRow, pPostIt); + CellStorageModified(); ActivateNewFormulaCell(it, nRow, *pCell); @@ -1688,6 +1732,9 @@ void ScColumn::SetFormula( SCROW nRow, const OUString& rFormula, formula::Formul pCell->SetNeedNumberFormat(true); it = maCells.set(it, nRow, pCell); maCellTextAttrs.set(nRow, sc::CellTextAttr()); +// ScPostIt* pPostIt; +// maCellNotes.set(nRow, pPostIt); + CellStorageModified(); ActivateNewFormulaCell(it, nRow, *pCell); @@ -1701,6 +1748,9 @@ ScFormulaCell* ScColumn::SetFormulaCell( SCROW nRow, ScFormulaCell* pCell ) pCell->SetNeedNumberFormat(true); it = maCells.set(it, nRow, pCell); maCellTextAttrs.set(nRow, sc::CellTextAttr()); +// ScPostIt* pPostIt; +// maCellNotes.set(nRow, pPostIt); + CellStorageModified(); ActivateNewFormulaCell(it, nRow, *pCell); @@ -1716,6 +1766,7 @@ ScFormulaCell* ScColumn::SetFormulaCell( sc::ColumnBlockPosition& rBlockPos, SCR rBlockPos.miCellPos = maCells.set(rBlockPos.miCellPos, nRow, pCell); rBlockPos.miCellTextAttrPos = maCellTextAttrs.set( rBlockPos.miCellTextAttrPos, nRow, sc::CellTextAttr()); + CellStorageModified(); ActivateNewFormulaCell(rBlockPos.miCellPos, nRow, *pCell); @@ -1730,6 +1781,9 @@ bool ScColumn::SetGroupFormulaCell( SCROW nRow, ScFormulaCell* pCell ) pCell->SetNeedNumberFormat(true); it = maCells.set(it, nRow, pCell); maCellTextAttrs.set(nRow, sc::CellTextAttr()); +// ScPostIt* pPostIt; +// maCellNotes.set(nRow, pPostIt); + CellStorageModified(); ActivateNewFormulaCell(it, nRow, *pCell, false); @@ -2148,6 +2202,9 @@ void ScColumn::SetError( SCROW nRow, const sal_uInt16 nError) sc::CellStoreType::iterator it = GetPositionToInsert(nRow); it = maCells.set(it, nRow, pCell); maCellTextAttrs.set(nRow, sc::CellTextAttr()); +// ScPostIt* pPostIt; +// maCellNotes.set(nRow, pPostIt); + CellStorageModified(); ActivateNewFormulaCell(it, nRow, *pCell); @@ -2173,6 +2230,9 @@ void ScColumn::SetRawString( SCROW nRow, const svl::SharedString& rStr, bool bBr sc::CellStoreType::iterator it = GetPositionToInsert(nRow); maCells.set(it, nRow, rStr); maCellTextAttrs.set(nRow, sc::CellTextAttr()); +// ScPostIt* pPostIt; +// maCellNotes.set(nRow, pPostIt); + CellStorageModified(); if (bBroadcast) @@ -2199,6 +2259,7 @@ void ScColumn::SetRawString( rBlockPos.miCellPos = maCells.set(rBlockPos.miCellPos, nRow, rStr); rBlockPos.miCellTextAttrPos = maCellTextAttrs.set( rBlockPos.miCellTextAttrPos, nRow, sc::CellTextAttr()); + CellStorageModified(); if (bBroadcast) @@ -2213,6 +2274,9 @@ void ScColumn::SetValue( SCROW nRow, double fVal ) sc::CellStoreType::iterator it = GetPositionToInsert(nRow); maCells.set(it, nRow, fVal); maCellTextAttrs.set(nRow, sc::CellTextAttr()); +// ScPostIt* pPostIt; +// maCellNotes.set(nRow, pPostIt); + CellStorageModified(); BroadcastNewCell(nRow); @@ -2228,6 +2292,7 @@ void ScColumn::SetValue( rBlockPos.miCellPos = maCells.set(rBlockPos.miCellPos, nRow, fVal); rBlockPos.miCellTextAttrPos = maCellTextAttrs.set( rBlockPos.miCellTextAttrPos, nRow, sc::CellTextAttr()); + CellStorageModified(); if (bBroadcast) diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx index dee85dddab83..a6180bc946b4 100644 --- a/sc/source/core/data/document.cxx +++ b/sc/source/core/data/document.cxx @@ -101,6 +101,8 @@ #include <limits> #include <boost/scoped_ptr.hpp> +#include "mtvelements.hxx" + using ::editeng::SvxBorderLine; using namespace ::com::sun::star; @@ -3501,12 +3503,6 @@ bool ScDocument::HasSelectionData( SCCOL nCol, SCROW nRow, SCTAB nTab ) const } -void ScDocument::InitializeNoteCaptions( SCTAB nTab, bool bForced ) -{ - if( ValidTab( nTab ) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[ nTab ] ) - maTabs[ nTab ]->InitializeNoteCaptions( bForced ); -} - void ScDocument::SetDirty() { bool bOldAutoCalc = GetAutoCalc(); @@ -6064,12 +6060,102 @@ bool ScDocument::IsInVBAMode() const return false; } -ScNotes* ScDocument::GetNotes(SCTAB nTab) +ScPostIt* ScDocument::GetNote(const ScAddress& rPos) +{ + return GetNote(rPos.Col(), rPos.Row(), rPos.Tab()); +} + +ScPostIt* ScDocument::GetNote(SCCOL nCol, SCROW nRow, SCTAB nTab) { if (ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size())) - return maTabs[nTab]->GetNotes(); + return maTabs[nTab]->aCol[nCol].GetCellNote(nRow); + else + return NULL; - return NULL; +} +sc::CellNoteStoreType& ScDocument::GetColNotes(SCCOL nCol, SCTAB nTab) +{ + return maTabs[nTab]->aCol[nCol].maCellNotes; +} +void ScDocument::SetNote(const ScAddress& rPos, ScPostIt* pNote) +{ + return SetNote(rPos.Col(), rPos.Row(), rPos.Tab(), pNote); +} + +void ScDocument::SetNote(SCCOL nCol, SCROW nRow, SCTAB nTab, ScPostIt* pNote) +{ + return maTabs[nTab]->aCol[nCol].SetCellNote(nRow, pNote); +} + +bool ScDocument::HasNote(const ScAddress& rPos) +{ + return HasNote(rPos.Col(), rPos.Row(), rPos.Tab()); +} +bool ScDocument::HasNote(SCCOL nCol, SCROW nRow, SCTAB nTab) +{ + ScPostIt* pNote = maTabs[nTab]->aCol[nCol].GetCellNote(nRow); + return pNote != NULL; +} +bool ScDocument::HasColNotes(SCCOL nCol, SCTAB nTab) +{ + return maTabs[nTab]->aCol[nCol].HasCellNotes(); +} + +bool ScDocument::HasTabNotes(SCTAB nTab) +{ + bool hasNotes = false; + for (SCCOL nCol=0; nCol<MAXCOLCOUNT && !hasNotes; ++nCol) + hasNotes = HasColNotes(nCol, nTab); + + return hasNotes; +} + +ScPostIt* ScDocument::ReleaseNote(const ScAddress& rPos) +{ + return ReleaseNote(rPos.Col(), rPos.Row(), rPos.Tab()); +} +ScPostIt* ScDocument::ReleaseNote(SCCOL nCol, SCROW nRow, SCTAB nTab) +{ + + ScPostIt* pPostIt = GetNote(nCol, nRow, nTab); + if (pPostIt != NULL) + maTabs[nTab]->aCol[nCol].DeleteCellNote(nRow); + + return pPostIt; +} + +ScPostIt* ScDocument::GetOrCreateNote(const ScAddress& rPos) +{ + if (HasNote(rPos)) + return GetNote(rPos); + else + return CreateNote(rPos); +} +ScPostIt* ScDocument::CreateNote(const ScAddress& rPos) +{ + ScPostIt* pPostIt = new ScPostIt(*this, rPos, false); + SetNote(rPos, pPostIt); + return pPostIt; +} + +sal_uLong ScDocument::CountNotes() +{ + sal_uLong nCount = 0; + SCTAB nTabCount = GetTableCount(); + for (SCTAB nTab=0; nTab<nTabCount; nTab++) + { + for (SCCOL nCol=0; nCol<MAXCOLCOUNT; nCol++) + { + sc::CellNoteStoreType& maCellNotes = GetColNotes(nCol, nTab); + sc::CellNoteStoreType::const_iterator it = maCellNotes.begin(), itEnd = maCellNotes.end(); + for (; it != itEnd; ++it) + { + if (it->type == sc::element_type_cellnote) + nCount +=it->size; + } + } + } + return nCount; } void ScDocument::SetAutoNameCache( ScAutoNameCache* pCache ) diff --git a/sc/source/core/data/drwlayer.cxx b/sc/source/core/data/drwlayer.cxx index 7f95a070d234..5d52b0c1c9c7 100644 --- a/sc/source/core/data/drwlayer.cxx +++ b/sc/source/core/data/drwlayer.cxx @@ -627,7 +627,7 @@ void ScDrawLayer::RecalcPos( SdrObject* pObj, ScDrawObjData& rData, bool bNegati where cell note is already deleted (thus document cannot find the note object anymore). The caption will be deleted later with drawing undo. */ - if( ScPostIt* pNote = pDoc->GetNotes( rData.maStart.Tab() )->findByAddress( rData.maStart ) ) + if( ScPostIt* pNote = pDoc->GetNote( rData.maStart ) ) pNote->UpdateCaptionPos( rData.maStart ); return; } diff --git a/sc/source/core/data/postit.cxx b/sc/source/core/data/postit.cxx index ccbe256d29d5..67f730344ca5 100644 --- a/sc/source/core/data/postit.cxx +++ b/sc/source/core/data/postit.cxx @@ -38,6 +38,7 @@ #include <svx/sdsxyitm.hxx> #include <tools/gen.hxx> +#include "table.hxx" #include "document.hxx" #include "docpool.hxx" #include "patattr.hxx" @@ -792,16 +793,6 @@ void ScPostIt::RemoveCaption() // ============================================================================ -void ScNoteUtil::UpdateCaptionPositions( ScDocument& rDoc, const ScRange& rRange ) -{ - // do not use ScCellIterator, it skips filtered and subtotal cells - for( ScAddress aPos( rRange.aStart ); aPos.Tab() <= rRange.aEnd.Tab(); aPos.IncTab() ) - for( aPos.SetCol( rRange.aStart.Col() ); aPos.Col() <= rRange.aEnd.Col(); aPos.IncCol() ) - for( aPos.SetRow( rRange.aStart.Row() ); aPos.Row() <= rRange.aEnd.Row(); aPos.IncRow() ) - if( ScPostIt* pNote = rDoc.GetNotes(aPos.Tab())->findByAddress( aPos ) ) - pNote->UpdateCaptionPos( aPos ); -} - SdrCaptionObj* ScNoteUtil::CreateTempCaption( ScDocument& rDoc, const ScAddress& rPos, SdrPage& rDrawPage, const OUString& rUserText, const Rectangle& rVisRect, bool bTailFront ) @@ -809,7 +800,7 @@ SdrCaptionObj* ScNoteUtil::CreateTempCaption( OUStringBuffer aBuffer( rUserText ); // add plain text of invisible (!) cell note (no formatting etc.) SdrCaptionObj* pNoteCaption = 0; - const ScPostIt* pNote = rDoc.GetNotes(rPos.Tab())->findByAddress( rPos ); + const ScPostIt* pNote = rDoc.GetNote( rPos ); if( pNote && !pNote->IsCaptionShown() ) { if( !aBuffer.isEmpty() ) @@ -873,7 +864,8 @@ ScPostIt* ScNoteUtil::CreateNoteFromCaption( pNote->AutoStamp(); // if pNote still points to the note after TakeNote(), insertion was successful - if( rDoc.GetNotes(rPos.Tab())->insert( rPos, pNote ) ) + rDoc.SetNote(rPos, pNote); + if( pNote ) { // ScNoteCaptionCreator c'tor updates the caption object to be part of a note ScNoteCaptionCreator aCreator( rDoc, rPos, rCaption, bShown ); @@ -911,7 +903,10 @@ ScPostIt* ScNoteUtil::CreateNoteFromObjectData( visible, the caption object will be created automatically. */ ScPostIt* pNote = new ScPostIt( rDoc, rPos, aNoteData, bAlwaysCreateCaption ); pNote->AutoStamp(); - if(rDoc.GetNotes(rPos.Tab())->insert( rPos, pNote )) + + rDoc.SetNote(rPos, pNote); + + if(pNote) return pNote; else return NULL; @@ -935,207 +930,10 @@ ScPostIt* ScNoteUtil::CreateNoteFromString( pNote = new ScPostIt( rDoc, rPos, aNoteData, bAlwaysCreateCaption ); pNote->AutoStamp(); //insert takes ownership - if(!rDoc.GetNotes(rPos.Tab())->insert( rPos, pNote )) + rDoc.SetNote(rPos, pNote); + if(!pNote) pNote = NULL; } return pNote; } - -// ============================================================================ -// ScNotes -// ============================================================================ - -ScNotes::ScNotes(ScDocument* pDoc): - mpDoc(pDoc) -{ - -} - -ScNotes::~ScNotes() -{ - clear(); -} - -ScNotes::iterator ScNotes::begin() -{ - return maNoteMap.begin(); -} - -ScNotes::iterator ScNotes::end() -{ - return maNoteMap.end(); -} - -ScNotes::const_iterator ScNotes::begin() const -{ - return maNoteMap.begin(); -} - -ScNotes::const_iterator ScNotes::end() const -{ - return maNoteMap.end(); -} - -size_t ScNotes::size() const -{ - return maNoteMap.size(); -} - -bool ScNotes::empty() const -{ - return maNoteMap.empty(); -} - -ScPostIt* ScNotes::findByAddress(SCCOL nCol, SCROW nRow) -{ - ScNoteMap::iterator itr = maNoteMap.find(std::pair<SCCOL, SCROW>(nCol, nRow)); - if (itr != maNoteMap.end()) - return itr->second; - - return NULL; -} - -const ScPostIt* ScNotes::findByAddress(SCCOL nCol, SCROW nRow) const -{ - ScNoteMap::const_iterator itr = maNoteMap.find(std::pair<SCCOL, SCROW>(nCol, nRow)); - if (itr != maNoteMap.end()) - return itr->second; - - return NULL; -} - -ScPostIt* ScNotes::findByAddress(const ScAddress& rPos) -{ - return findByAddress(rPos.Col(), rPos.Row()); -} - -const ScPostIt* ScNotes::findByAddress(const ScAddress& rPos) const -{ - return findByAddress(rPos.Col(), rPos.Row()); -} - -bool ScNotes::insert(SCCOL nCol, SCROW nRow, ScPostIt* pPostIt) -{ - std::pair<iterator, bool> aResult = maNoteMap.insert(std::pair<ScAddress2D, ScPostIt*>(std::pair<SCCOL, SCROW>(nCol, nRow), pPostIt)); - if (!aResult.second) - delete pPostIt; - - return aResult.second; -} - -bool ScNotes::insert(const ScAddress& rPos, ScPostIt* pPostIt) -{ - return insert(rPos.Col(), rPos.Row(), pPostIt); -} - -void ScNotes::erase(SCCOL nCol, SCROW nRow, bool bForgetCaption) -{ - iterator itr = maNoteMap.find(std::pair<SCCOL, SCROW>(nCol, nRow)); - if (itr != maNoteMap.end()) - { - if (bForgetCaption) - itr->second->ForgetCaption(); - - delete itr->second; - maNoteMap.erase(itr); - } -} - -void ScNotes::erase(const ScAddress& rPos) -{ - erase(rPos.Col(), rPos.Row()); -} - -ScPostIt* ScNotes::ReleaseNote(SCCOL nCol, SCROW nRow) -{ - ScPostIt* pPostIt = NULL; - iterator itr = maNoteMap.find(std::pair<SCCOL, SCROW>(nCol, nRow)); - if (itr!= maNoteMap.end()) - { - pPostIt = itr->second; - maNoteMap.erase(itr); - } - return pPostIt; -} - -ScPostIt* ScNotes::ReleaseNote(const ScAddress& rPos) -{ - return ReleaseNote(rPos.Col(), rPos.Row()); -} - -ScPostIt* ScNotes::GetOrCreateNote(const ScAddress& rPos) -{ - iterator itr = maNoteMap.find(std::pair<SCCOL, SCROW>(rPos.Col(), rPos.Row())); - if (itr != maNoteMap.end()) - return itr->second; - else - { - ScPostIt* pPostIt = new ScPostIt(*mpDoc, rPos, false); - if(!insert(rPos, pPostIt)) - assert(false); - return pPostIt; - } -} - -void ScNotes::clear() -{ - for (iterator itr = maNoteMap.begin(); itr != maNoteMap.end(); ++itr) - { - delete itr->second; - } - maNoteMap.clear(); -} - -void ScNotes::clone(ScDocument* pDoc, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, bool bCloneNoteCaption, SCTAB nTab, ScNotes& rTarget) -{ - rTarget.clear(); - for (ScNotes::iterator itr = maNoteMap.begin(); itr != maNoteMap.end(); ++itr) - { - SCCOL nCol = itr->first.first; - SCROW nRow = itr->first.second; - - if (nCol >= nCol1 && nCol <= nCol2 && nRow >= nRow1 && nRow <= nRow2) - { - rTarget.insert(nCol, nRow, itr->second->Clone( ScAddress(nCol, nRow, nTab), *pDoc, ScAddress(nCol, nRow, nTab), bCloneNoteCaption)); - } - } -} - -void ScNotes::CopyFromClip(const ScNotes& rNotes, ScDocument* pDoc, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, SCsCOL nDx, SCsROW nDy, SCTAB nTab, bool bCloneCaption) -{ - for (ScNotes::const_iterator itr = rNotes.begin(); itr != rNotes.end(); ++itr) - { - SCCOL nCol = itr->first.first; - SCROW nRow = itr->first.second; - if (nCol+nDx >= nCol1 && nCol+nDx <= nCol2 && nRow+nDy >= nRow1 && nRow+nDy <= nRow2) - { - erase(nCol+nDx, nRow+nDy); - insert(nCol+nDx, nRow+nDy, itr->second->Clone( ScAddress(nCol, nRow, nTab), *pDoc, ScAddress(nCol+nDx, nRow+nDy, nTab), bCloneCaption )); - } - } -} - -void ScNotes::erase(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, bool bForgetCaption) -{ - ScNotes::iterator itr = maNoteMap.begin(); - while(itr != maNoteMap.end()) - { - SCCOL nCol = itr->first.first; - SCROW nRow = itr->first.second; - ++itr; - if (nCol >= nCol1 && nCol <= nCol2 && nRow >= nRow1 && nRow <= nRow2) - { - erase(nCol, nRow, bForgetCaption); - } - } -} - -void ScNotes::CreateAllNoteCaptions(SCTAB nTab) -{ - for(iterator itr = begin(), itrEnd = end(); itr != itrEnd; ++itr) - { - itr->second->GetOrCreateCaption(ScAddress(itr->first.first, itr->first.second, nTab)); - } -} - /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/source/core/data/table1.cxx b/sc/source/core/data/table1.cxx index 5a63338aacd1..45762fab390f 100644 --- a/sc/source/core/data/table1.cxx +++ b/sc/source/core/data/table1.cxx @@ -259,7 +259,6 @@ ScTable::ScTable( ScDocument* pDoc, SCTAB nNewTab, const OUString& rNewName, pDBDataNoName(NULL), mpRangeName(NULL), mpCondFormatList( new ScConditionalFormatList() ), - maNotes(pDoc), bScenario(false), bLayoutRTL(false), bLoadingRTL(false), @@ -520,26 +519,31 @@ bool ScTable::GetCellArea( SCCOL& rEndCol, SCROW& rEndRow ) const SCCOL nMaxX = 0; SCROW nMaxY = 0; for (SCCOL i=0; i<=MAXCOL; i++) - if (!aCol[i].IsEmptyData()) { - bFound = true; - nMaxX = i; - SCROW nColY = aCol[i].GetLastDataPos(); - if (nColY > nMaxY) - nMaxY = nColY; + if (!aCol[i].IsEmptyData()) + { + bFound = true; + nMaxX = i; + SCROW nRow = aCol[i].GetLastDataPos(); + if (nRow > nMaxY) + nMaxY = nRow; + } + if ( aCol[i].HasCellNotes() ) + { + SCROW maxNoteRow = aCol[i].GetCellNotesMaxRow(); + if (maxNoteRow >= nMaxY) + { + bFound = true; + nMaxY = maxNoteRow; + } + if (i>nMaxX) + { + bFound = true; + nMaxX = i; + } + } } - for (ScNotes::const_iterator itr = maNotes.begin(); itr != maNotes.end(); ++itr) - { - SCCOL nCol = itr->first.first; - SCROW nRow = itr->first.second; - - if (nMaxX < nCol) - nMaxX = nCol; - if (nMaxY < nRow) - nMaxY = nRow; - } - rEndCol = nMaxX; rEndRow = nMaxY; return bFound; @@ -568,29 +572,34 @@ bool ScTable::GetPrintArea( SCCOL& rEndCol, SCROW& rEndRow, bool bNotes, bool bF SCCOL i; for (i=0; i<=MAXCOL; i++) // Daten testen - if (!aCol[i].IsEmptyData()) - { - bFound = true; - if (i>nMaxX) - nMaxX = i; - SCROW nColY = aCol[i].GetLastDataPos(); - if (nColY > nMaxY) - nMaxY = nColY; - } - - if (bNotes) - { - for (ScNotes::const_iterator itr = maNotes.begin(); itr != maNotes.end(); ++itr) { - SCCOL nCol = itr->first.first; - SCROW nRow = itr->first.second; - - if (nMaxX < nCol) - nMaxX = nCol; - if (nMaxY < nRow) - nMaxY = nRow; + if (!aCol[i].IsEmptyData()) + { + bFound = true; + if (i>nMaxX) + nMaxX = i; + SCROW nColY = aCol[i].GetLastDataPos(); + if (nColY > nMaxY) + nMaxY = nColY; + } + if (bNotes) + { + if ( aCol[i].HasCellNotes() ) + { + SCROW maxNoteRow = aCol[i].GetCellNotesMaxRow(); + if (maxNoteRow >= nMaxY) + { + bFound = true; + nMaxY = maxNoteRow; + } + if (i>nMaxX) + { + bFound = true; + nMaxX = i; + } + } + } } - } SCCOL nMaxDataX = nMaxX; @@ -701,6 +710,7 @@ bool ScTable::GetPrintAreaVer( SCCOL nStartCol, SCCOL nEndCol, } for (i=nStartCol; i<=nEndCol; i++) // Daten testen + { if (!aCol[i].IsEmptyData()) { bFound = true; @@ -708,19 +718,17 @@ bool ScTable::GetPrintAreaVer( SCCOL nStartCol, SCCOL nEndCol, if (nColY > nMaxY) nMaxY = nColY; } - - if (bNotes) - { - for (ScNotes::const_iterator itr = maNotes.begin(); itr != maNotes.end(); ++itr) + if (bNotes) { - SCCOL nCol = itr->first.first; - SCROW nRow = itr->first.second; - - if (nStartCol > nCol || nEndCol < nCol) - continue; - - if (nMaxY < nRow) - nMaxY = nRow; + if ( aCol[i].HasCellNotes() ) + { + SCROW maxNoteRow =aCol[i].GetCellNotesMaxRow(); + if (maxNoteRow > nMaxY) + { + bFound = true; + nMaxY = maxNoteRow; + } + } } } @@ -760,28 +768,31 @@ bool ScTable::GetDataStart( SCCOL& rStartCol, SCROW& rStartRow ) const bool bDatFound = false; for (i=0; i<=MAXCOL; i++) // Daten testen + { if (!aCol[i].IsEmptyData()) { if (!bDatFound && i<nMinX) nMinX = i; bFound = bDatFound = true; - SCROW nColY = aCol[i].GetFirstDataPos(); - if (nColY < nMinY) - nMinY = nColY; + SCROW nRow = aCol[i].GetFirstDataPos(); + if (nRow < nMinY) + nMinY = nRow; + } + if ( aCol[i].HasCellNotes() ) + { + SCROW minNoteRow = aCol[i].GetCellNotesMinRow(); + if (minNoteRow <= nMinY) + { + bFound = true; + nMinY = minNoteRow; + } + if (i<nMinX) + { + bFound = true; + nMinX = i; + } } - - for (ScNotes::const_iterator itr = maNotes.begin(); itr != maNotes.end(); ++itr) - { - bFound = bDatFound = true; - SCCOL nCol = itr->first.first; - SCROW nRow = itr->first.second; - - if (nMinX > nCol) - nMinX = nCol; - if (nMinY > nRow) - nMinY = nRow; } - rStartCol = nMinX; rStartRow = nMinY; return bFound; @@ -1447,7 +1458,6 @@ void ScTable::UpdateDrawRef( UpdateRefMode eUpdateRefMode, SCCOL nCol1, SCROW nR { if ( nTab >= nTab1 && nTab <= nTab2 && nDz == 0 ) // only within the table { - InitializeNoteCaptions(); ScDrawLayer* pDrawLayer = pDocument->GetDrawLayer(); if ( eUpdateRefMode != URM_COPY && pDrawLayer ) { diff --git a/sc/source/core/data/table2.cxx b/sc/source/core/data/table2.cxx index aa4f7fba7c12..312aa22b77a4 100644 --- a/sc/source/core/data/table2.cxx +++ b/sc/source/core/data/table2.cxx @@ -188,36 +188,6 @@ void ScTable::InsertRow( SCCOL nStartCol, SCCOL nEndCol, SCROW nStartRow, SCSIZE for (SCCOL j=nStartCol; j<=nEndCol; j++) aCol[j].InsertRow( nStartRow, nSize ); - // Transfer those notes that will get shifted into another container. - ScNotes aNotes(pDocument); - ScNotes::iterator itr = maNotes.begin(); - while( itr != maNotes.end() ) - { - SCCOL nCol = itr->first.first; - SCROW nRow = itr->first.second; - ScPostIt* pPostIt = itr->second; - ++itr; - - if (nStartRow <= nRow && nStartCol <= nCol && nCol <= nEndCol) - { - aNotes.insert(nCol, nRow + nSize, pPostIt); - maNotes.ReleaseNote(nCol, nRow); - } - } - - // Re-insert the shifted notes. - itr = aNotes.begin(); - while( itr != aNotes.end() ) - { - SCCOL nCol = itr->first.first; - SCROW nRow = itr->first.second; - ScPostIt* pPostIt = itr->second; - ++itr; - - maNotes.insert( nCol, nRow, pPostIt); - aNotes.ReleaseNote( nCol, nRow); - } - mpCondFormatList->InsertRow(nTab, nStartCol, nEndCol, nStartRow, nSize); InvalidatePageBreaks(); @@ -273,44 +243,6 @@ void ScTable::DeleteRow( rRegroupCols.getColumns(nTab, aRegroupCols); std::for_each(aRegroupCols.begin(), aRegroupCols.end(), ColumnRegroupFormulaCells(aCol)); - // Transfer those notes that will get shifted into another container. - ScNotes aNotes(pDocument); - ScNotes::iterator itr = maNotes.begin(); - while( itr != maNotes.end() ) - { - SCCOL nCol = itr->first.first; - SCROW nRow = itr->first.second; - ScPostIt* pPostIt = itr->second; - ++itr; - - if (nStartRow <= nRow && nStartCol <= nCol && nCol <= nEndCol) - { - SCROW nEndRow = nStartRow + nSize - 1; // last row of deleted region - if (nEndRow < nRow) - { - // This note will get shifted. - aNotes.insert(nCol, nRow - nSize, pPostIt); - maNotes.ReleaseNote(nCol, nRow); - } - else - // Note is in the deleted area. Remove it. - maNotes.erase(nCol, nRow); - } - } - - // Re-insert the shifted notes. - itr = aNotes.begin(); - while( itr != aNotes.end() ) - { - SCCOL nCol = itr->first.first; - SCROW nRow = itr->first.second; - ScPostIt* pPostIt = itr->second; - ++itr; - - maNotes.insert( nCol, nRow, pPostIt); - aNotes.ReleaseNote( nCol, nRow); - } - { // scope for bulk broadcast ScBulkBroadcast aBulkBroadcast( pDocument->GetBASM()); for (SCCOL j=nStartCol; j<=nEndCol; j++) @@ -395,36 +327,6 @@ void ScTable::InsertCol( rRegroupCols.getColumns(nTab, aRegroupCols); std::for_each(aRegroupCols.begin(), aRegroupCols.end(), ColumnRegroupFormulaCells(aCol)); - // Transfer those notes that will get shifted into another container. - ScNotes aNotes(pDocument); - ScNotes::iterator itr = maNotes.begin(); - while( itr != maNotes.end() ) - { - SCCOL nCol = itr->first.first; - SCROW nRow = itr->first.second; - ScPostIt* pPostIt = itr->second; - ++itr; - - if (nStartCol <= nCol && nStartRow <= nRow && nRow <= nEndRow) - { - aNotes.insert(nCol + nSize, nRow, pPostIt); - maNotes.ReleaseNote(nCol, nRow); - } - } - - // Re-insert the shifted notes. - itr = aNotes.begin(); - while( itr != aNotes.end() ) - { - SCCOL nCol = itr->first.first; - SCROW nRow = itr->first.second; - ScPostIt* pPostIt = itr->second; - ++itr; - - maNotes.insert( nCol, nRow, pPostIt); - aNotes.ReleaseNote( nCol, nRow); - } - if (nStartCol>0) // copy old attributes { sal_uInt16 nWhichArray[2]; @@ -508,44 +410,6 @@ void ScTable::DeleteCol( rRegroupCols.getColumns(nTab, aRegroupCols); std::for_each(aRegroupCols.begin(), aRegroupCols.end(), ColumnRegroupFormulaCells(aCol)); - // Transfer those notes that will get shifted into another container. - ScNotes aNotes(pDocument); - ScNotes::iterator itr = maNotes.begin(); - while( itr != maNotes.end() ) - { - SCCOL nCol = itr->first.first; - SCROW nRow = itr->first.second; - ScPostIt* pPostIt = itr->second; - ++itr; - - if (nStartCol <= nCol && nStartRow <= nRow && nRow <= nEndRow) - { - SCCOL nEndCol = nStartCol + nSize - 1; - if (nEndCol < nCol) - { - // This note will get shifted. - aNotes.insert(nCol - nSize, nRow, pPostIt); - maNotes.ReleaseNote(nCol, nRow); - } - else - // The note is in the deleted region. Remove it. - maNotes.erase(nCol, nRow); - } - } - - // Re-insert the shifted notes. - itr = aNotes.begin(); - while( itr != aNotes.end() ) - { - SCCOL nCol = itr->first.first; - SCROW nRow = itr->first.second; - ScPostIt* pPostIt = itr->second; - ++itr; - - maNotes.insert( nCol, nRow, pPostIt); - aNotes.ReleaseNote( nCol, nRow); - } - InvalidatePageBreaks(); if (IsStreamValid()) @@ -582,9 +446,6 @@ void ScTable::DeleteArea(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, sal mpCondFormatList->DeleteArea( nCol1, nRow1, nCol2, nRow2 ); } - if (nDelFlag & IDF_NOTE) - maNotes.erase( nCol1, nRow1, nCol2, nRow2 ); - if (IsStreamValid()) // TODO: In the future we may want to check if the table has been // really modified before setting the stream invalid. @@ -606,10 +467,6 @@ void ScTable::DeleteSelection( sal_uInt16 nDelFlag, const ScMarkData& rMark ) for (size_t i = 0; i < aRangeList.size(); ++i) { ScRange* pRange = aRangeList[i]; - if (nDelFlag & IDF_NOTE && pRange) - { - maNotes.erase(pRange->aStart.Col(), pRange->aStart.Row(), pRange->aEnd.Col(), pRange->aEnd.Row(), nDelFlag & IDF_NOCAPTIONS); - } if((nDelFlag & IDF_ATTRIB) && pRange && pRange->aStart.Tab() == nTab) mpCondFormatList->DeleteArea( pRange->aStart.Col(), pRange->aStart.Row(), pRange->aEnd.Col(), pRange->aEnd.Row() ); @@ -647,14 +504,10 @@ void ScTable::CopyToClip( if (!pTable->mpRangeName && mpRangeName) pTable->mpRangeName = new ScRangeName(*mpRangeName); - // notes - maNotes.clone( - pTable->pDocument, nCol1, nRow1, nCol2, nRow2, rCxt.isCloneNotes(), nTab, pTable->maNotes); - SCCOL i; for ( i = nCol1; i <= nCol2; i++) - aCol[i].CopyToClip(rCxt, nRow1, nRow2, pTable->aCol[i]); + aCol[i].CopyToClip(rCxt, nRow1, nRow2, pTable->aCol[i]); // notes are handled at column level // copy widths/heights, and only "hidden", "filtered" and "manual" flags // also for all preceding columns/rows, to have valid positions for drawing objects @@ -807,8 +660,7 @@ void ScTable::CopyFromClip( if (ValidColRow(nCol1, nRow1) && ValidColRow(nCol2, nRow2)) { for ( SCCOL i = nCol1; i <= nCol2; i++) - aCol[i].CopyFromClip(rCxt, nRow1, nRow2, nDy, pTable->aCol[i - nDx]); - + aCol[i].CopyFromClip(rCxt, nRow1, nRow2, nDy, pTable->aCol[i - nDx]); // notes are handles at column level if (rCxt.getInsertFlag() == IDF_ATTRIB) { @@ -820,18 +672,6 @@ void ScTable::CopyFromClip( aCol[i].ClearItems(nRow1, nRow2, nWhichArray); } - //remove old notes - if (rCxt.getInsertFlag() & (IDF_NOTE|IDF_ADDNOTES)) - maNotes.erase(nCol1, nRow1, nCol2, nRow2); - - bool bAddNotes = rCxt.getInsertFlag() & (IDF_NOTE | IDF_ADDNOTES); - if (bAddNotes) - { - bool bCloneCaption = (rCxt.getInsertFlag() & IDF_NOCAPTIONS) == 0; - maNotes.CopyFromClip(pTable->maNotes, pDocument, nCol1, nRow1, nCol2, nRow2, nDx, nDy, nTab, bCloneCaption); - } - - if ((rCxt.getInsertFlag() & IDF_ATTRIB) != 0) { if (nRow1==0 && nRow2==MAXROW && pColWidth && pTable->pColWidth) @@ -1087,23 +927,100 @@ void ScTable::TransposeClip( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, } } } + + // Cell Notes - fdo#68381 paste cell notes on Transpose + if ( pDocument->HasColNotes(nCol, nTab) ) + TransposeColNotes(pTransClip, nCol1, nCol, nRow1, nRow2); } +} - // fdo#68381 paste cell notes on Transpose +void ScTable::TransposeColNotes(ScTable* pTransClip, SCCOL nCol1, SCCOL nCol, SCROW nRow1, SCROW nRow2) +{ bool bCloneCaption = true; - for (ScNotes::const_iterator itr = maNotes.begin(); itr != maNotes.end(); ++itr) + + 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) { - SCCOL nCol = itr->first.first; - SCROW nRow = itr->first.second; - if (nCol >= nCol1 && nCol <= nCol2 && nRow >= nRow1 && nRow <= nRow2) + nBlockEnd = nBlockStart + itBlk->size; + if (nBlockStart <= nRowPos && nRowPos < nBlockEnd) { - ScAddress aDestPos( static_cast<SCCOL>(nRow-nRow1), static_cast<SCROW>(nCol-nCol1), pTransClip->nTab ); - pTransClip->maNotes.erase(aDestPos); - pTransClip->maNotes.insert(aDestPos, itr->second->Clone( ScAddress(nCol, nRow, nTab), *pTransClip->pDocument, aDestPos, bCloneCaption )); + // 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) + { + itData = sc::cellnote_block::begin(*itBlk->data); + std::advance(itData, nOffsetInBlock); + + 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 + { + 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() { @@ -1157,17 +1074,6 @@ void ScTable::CopyToTable( if (!bColRowFlags) // Spaltenbreiten/Zeilenhoehen/Flags return; - //remove old notes - if (nFlags & IDF_NOTE) - pDestTab->maNotes.erase(nCol1, nRow1, nCol2, nRow2); - - bool bAddNotes = nFlags & (IDF_NOTE | IDF_ADDNOTES); - if (bAddNotes) - { - bool bCloneCaption = (nFlags & IDF_NOCAPTIONS) == 0; - pDestTab->maNotes.CopyFromClip(maNotes, pDestTab->pDocument, nCol1, nRow1, nCol2, nRow2, 0, 0, pDestTab->nTab, bCloneCaption); - } - if(pDestTab->pDocument->IsUndo() && (nFlags & IDF_ATTRIB)) { pDestTab->mpCondFormatList.reset(new ScConditionalFormatList(pDestTab->pDocument, *mpCondFormatList)); @@ -1290,19 +1196,9 @@ void ScTable::UndoToTable( aCol[i].CopyToColumn(rCxt, 0, MAXROW, IDF_FORMULA, false, pDestTab->aCol[i]); } - //remove old notes - if (nFlags & IDF_CONTENTS) - pDestTab->maNotes.erase(nCol1, nRow1, nCol2, nRow2); - if (nFlags & IDF_ATTRIB) pDestTab->mpCondFormatList.reset(new ScConditionalFormatList(pDestTab->pDocument, *mpCondFormatList)); - bool bAddNotes = nFlags & (IDF_NOTE | IDF_ADDNOTES); - if (bAddNotes) - { - bool bCloneCaption = (nFlags & IDF_NOCAPTIONS) == 0; - pDestTab->maNotes.CopyFromClip(maNotes, pDocument, nCol1, nRow1, nCol2, nRow2, 0, 0, pDestTab->nTab, bCloneCaption); - } if (bWidth||bHeight) { @@ -1326,16 +1222,6 @@ void ScTable::CopyUpdated( const ScTable* pPosTab, ScTable* pDestTab ) const { for (SCCOL i=0; i<=MAXCOL; i++) aCol[i].CopyUpdated( pPosTab->aCol[i], pDestTab->aCol[i] ); - - // insert notes with captions - for(ScNotes::iterator itr = pDestTab->maNotes.begin(); itr != pDestTab->maNotes.end(); ++itr) - { - SCCOL nCol = itr->first.first; - SCROW nRow = itr->first.second; - ScPostIt* pPostIt = itr->second; - - pDestTab->maNotes.insert(nCol, nRow, pPostIt->Clone( ScAddress(nCol, nRow, nTab),*pDestTab->pDocument, ScAddress(nCol, nRow, pDestTab->nTab), true )); - } } void ScTable::InvalidateTableArea() @@ -1611,21 +1497,9 @@ ScFormulaCell* ScTable::GetFormulaCell( SCCOL nCol, SCROW nRow ) return aCol[nCol].GetFormulaCell(nRow); } -ScNotes* ScTable::GetNotes() -{ - return &maNotes; -} - - -void ScTable::InitializeNoteCaptions( bool bForced ) +ScPostIt* ScTable::GetNote(const SCCOL nCol, const SCROW nRow) { - if( mxUninitNotes.get() && (bForced || pDocument->IsUndoEnabled()) ) - { - for( ScAddress2DVec::iterator aIt = mxUninitNotes->begin(), aEnd = mxUninitNotes->end(); aIt != aEnd; ++aIt ) - if( ScPostIt* pNote = maNotes.findByAddress( aIt->first, aIt->second ) ) - pNote->GetOrCreateCaption( ScAddress( aIt->first, aIt->second, nTab ) ); - mxUninitNotes.reset(); - } + return pDocument->GetNote(nCol, nRow, nTab); } CellType ScTable::GetCellType( SCCOL nCol, SCROW nRow ) const @@ -1954,16 +1828,9 @@ bool ScTable::IsBlockEmpty( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, for (SCCOL i=nCol1; i<=nCol2 && bEmpty; i++) { bEmpty = aCol[i].IsEmptyBlock( nRow1, nRow2 ); - if (!bIgnoreNotes) + if (!bIgnoreNotes && bEmpty) { - for (ScNotes::const_iterator itr = maNotes.begin(); itr != maNotes.end() && bEmpty; ++itr) - { - SCCOL nCol = itr->first.first; - SCROW nRow = itr->first.second; - - if (nCol >= nCol1 && nCol <= nCol2 && nRow >= nRow1 && nRow <= nRow2) - bEmpty = false; - } + bEmpty = aCol[i].IsNotesEmptyBlock(nRow1, nRow2); } } return bEmpty; diff --git a/sc/source/core/data/table3.cxx b/sc/source/core/data/table3.cxx index 73a514b87a16..a79add4ae65d 100644 --- a/sc/source/core/data/table3.cxx +++ b/sc/source/core/data/table3.cxx @@ -559,44 +559,6 @@ void ScTable::SwapCol(SCCOL nCol1, SCCOL nCol2) } } } - - ScNotes aNoteMap(pDocument); - ScNotes::iterator itr = maNotes.begin(); - while(itr != maNotes.end()) - { - SCCOL nCol = itr->first.first; - SCROW nRow = itr->first.second; - ScPostIt* pPostIt = itr->second; - ++itr; - - if(nRow >= nRowStart && nRow <= nRowEnd) - { - if (nCol == nCol1) - { - aNoteMap.insert(nCol2, nRow, pPostIt); - maNotes.ReleaseNote(nCol, nRow); - } - else if (nCol == nCol2) - { - aNoteMap.insert(nCol1, nRow, pPostIt); - maNotes.ReleaseNote(nCol, nRow); - - } - } - } - - itr = aNoteMap.begin(); - while(itr != aNoteMap.end()) - { - //we can here assume that there is no note in the target location - SCCOL nCol = itr->first.first; - SCROW nRow = itr->first.second; - ScPostIt* pPostIt = itr->second; - ++itr; - - maNotes.insert(nCol, nRow, pPostIt); - aNoteMap.ReleaseNote(nCol, nRow); - } } void ScTable::SwapRow(SCROW nRow1, SCROW nRow2) @@ -631,43 +593,6 @@ void ScTable::SwapRow(SCROW nRow1, SCROW nRow2) SetRowFiltered(nRow1, nRow1, bRow2Filtered); SetRowFiltered(nRow2, nRow2, bRow1Filtered); } - - ScNotes aNoteMap(pDocument); - ScNotes::iterator itr = maNotes.begin(); - while(itr != maNotes.end()) - { - SCCOL nCol = itr->first.first; - SCROW nRow = itr->first.second; - ScPostIt* pPostIt = itr->second; - ++itr; - - if( nCol >= nColStart && nCol <= nColEnd ) - { - if (nRow == nRow1) - { - aNoteMap.insert(nCol, nRow2, pPostIt); - maNotes.ReleaseNote(nCol, nRow); - } - else if (nRow == nRow2) - { - aNoteMap.insert(nCol, nRow1, pPostIt); - maNotes.ReleaseNote(nCol, nRow); - } - } - } - - itr = aNoteMap.begin(); - while(itr != aNoteMap.end()) - { - //we can here assume that there is no note in the target location - SCCOL nCol = itr->first.first; - SCROW nRow = itr->first.second; - ScPostIt* pPostIt = itr->second; - ++itr; - - maNotes.insert(nCol, nRow, pPostIt); - aNoteMap.ReleaseNote(nCol, nRow); - } } short ScTable::Compare(SCCOLROW nIndex1, SCCOLROW nIndex2) const @@ -743,8 +668,7 @@ void ScTable::Sort(const ScSortParam& rSortParam, bool bKeepQuery, ScProgress* p QuickSort( pArray, nRow1, nLastRow ); SortReorder( pArray, pProgress ); delete pArray; - // #i59745# update position of caption objects of cell notes - ScNoteUtil::UpdateCaptionPositions( *pDocument, ScRange( aSortParam.nCol1, nRow1, nTab, aSortParam.nCol2, nLastRow, nTab ) ); + // #i59745# update position of caption objects of cell notes --> reported at (SortReorder) ScColumn::SwapCellNotes level } } else @@ -764,8 +688,7 @@ void ScTable::Sort(const ScSortParam& rSortParam, bool bKeepQuery, ScProgress* p QuickSort( pArray, nCol1, nLastCol ); SortReorder( pArray, pProgress ); delete pArray; - // #i59745# update position of caption objects of cell notes - ScNoteUtil::UpdateCaptionPositions( *pDocument, ScRange( nCol1, aSortParam.nRow1, nTab, nLastCol, aSortParam.nRow2, nTab ) ); + // #i59745# update position of caption objects of cell notes --> reported at (SortReorder) ScColumn::SwapCellNotes level } } DestroySortCollator(); @@ -1924,10 +1847,6 @@ SCSIZE ScTable::Query(ScQueryParam& rParamOrg, bool bKeepSub) aParam.nDestCol, aParam.nDestRow, aParam.nDestTab ); } - - if (aParam.bInplace) - InitializeNoteCaptions(); - SCROW nRealRow2 = aParam.nRow2; for (SCROW j = aParam.nRow1 + nHeader; j <= nRealRow2; ++j) { diff --git a/sc/source/core/tool/consoli.cxx b/sc/source/core/tool/consoli.cxx index 87d5b1a71852..25492bb3e304 100644 --- a/sc/source/core/tool/consoli.cxx +++ b/sc/source/core/tool/consoli.cxx @@ -767,7 +767,6 @@ void ScConsData::OutputToDocument( ScDocument* pDestDoc, SCCOL nCol, SCROW nRow, SCROW nOutEnd = nRow+nArrY+nNeeded-1; bool bSize = false; pOutArr->Insert( nOutStart, nOutEnd, bSize ); - pDestDoc->InitializeNoteCaptions(nTab); for (SCROW nOutRow=nOutStart; nOutRow<=nOutEnd; nOutRow++) pDestDoc->ShowRow( nOutRow, nTab, false ); pDestDoc->SetDrawPageSize(nTab); diff --git a/sc/source/core/tool/detfunc.cxx b/sc/source/core/tool/detfunc.cxx index 0ddd765cb60f..d69ba93a98ec 100644 --- a/sc/source/core/tool/detfunc.cxx +++ b/sc/source/core/tool/detfunc.cxx @@ -1422,7 +1422,6 @@ void ScDetectiveFunc::UpdateAllComments( ScDocument& rDoc ) for( SCTAB nObjTab = 0, nTabCount = rDoc.GetTableCount(); nObjTab < nTabCount; ++nObjTab ) { - rDoc.InitializeNoteCaptions( nObjTab ); SdrPage* pPage = pModel->GetPage( static_cast< sal_uInt16 >( nObjTab ) ); OSL_ENSURE( pPage, "Page ?" ); if( pPage ) @@ -1432,7 +1431,7 @@ void ScDetectiveFunc::UpdateAllComments( ScDocument& rDoc ) { if ( ScDrawObjData* pData = ScDrawLayer::GetNoteCaptionData( pObject, nObjTab ) ) { - ScPostIt* pNote = rDoc.GetNotes( pData->maStart.Tab() )->findByAddress( pData->maStart ); + ScPostIt* pNote = rDoc.GetNote( pData->maStart ); // caption should exist, we iterate over drawing objects... OSL_ENSURE( pNote && (pNote->GetCaption() == pObject), "ScDetectiveFunc::UpdateAllComments - invalid cell note" ); if( pNote ) diff --git a/sc/source/filter/excel/excdoc.cxx b/sc/source/filter/excel/excdoc.cxx index e2c050a75523..32db2e80c81f 100644 --- a/sc/source/filter/excel/excdoc.cxx +++ b/sc/source/filter/excel/excdoc.cxx @@ -417,15 +417,35 @@ void ExcTable::FillAsTable( SCTAB nCodeNameIdx ) mxCellTable.reset( new XclExpCellTable( GetRoot() ) ); //export cell notes - ScNotes::iterator itr = rDoc.GetNotes(mnScTab)->begin(); - ScNotes::iterator itrEnd = rDoc.GetNotes(mnScTab)->end(); - for (; itr != itrEnd; ++itr) - { - // notes - const ScPostIt* pScNote = itr->second; - ScAddress aScPos( itr->first.first, itr->first.second, mnScTab ); - mxNoteList->AppendNewRecord( new XclExpNote( GetRoot(), aScPos, pScNote, OUString() ) ); - } + for (SCCOL nCol=0; nCol<MAXCOLCOUNT; nCol++) + { + if ( rDoc.HasColNotes(nCol, mnScTab) ) + { + sc::CellNoteStoreType& maCellNotes = rDoc.GetColNotes(nCol, mnScTab); + + sc::CellNoteStoreType::const_iterator itBlk = maCellNotes.begin(), itBlkEnd = maCellNotes.end(); + sc::cellnote_block::const_iterator itData, itDataEnd; + + for(;itBlk != itBlkEnd; ++itBlk) + { + if (itBlk->data) + { + SCROW nRow = itBlk->position; + itData = sc::cellnote_block::begin(*itBlk->data); + itDataEnd = sc::cellnote_block::end(*itBlk->data); + for (; itData != itDataEnd; ++itData, ++nRow) + { + ScPostIt* pScNote = *itData; + if (pScNote) + { + ScAddress aScPos( nCol, nRow, mnScTab ); + mxNoteList->AppendNewRecord( new XclExpNote( GetRoot(), aScPos, pScNote, OUString() ) ); + } + } + } + } + } + } if( GetOutput() != EXC_OUTPUT_BINARY ) { diff --git a/sc/source/filter/xml/XMLExportIterator.cxx b/sc/source/filter/xml/XMLExportIterator.cxx index 976f3878cfa2..afc05fdad835 100644 --- a/sc/source/filter/xml/XMLExportIterator.cxx +++ b/sc/source/filter/xml/XMLExportIterator.cxx @@ -160,14 +160,12 @@ bool ScMyNoteShapesContainer::GetFirstAddress( table::CellAddress& rCellAddress void ScMyNoteShapesContainer::SetCellData( ScMyCell& rMyCell ) { - rMyCell.xNoteShape.clear(); ScAddress aAddress; ScUnoConversion::FillScAddress( aAddress, rMyCell.aCellAddress ); ScMyNoteShapeList::iterator aItr = aNoteShapeList.begin(); while( (aItr != aNoteShapeList.end()) && (aItr->aPos == aAddress) ) { - rMyCell.xNoteShape = aItr->xShape; aItr = aNoteShapeList.erase(aItr); } } @@ -618,15 +616,6 @@ ScMyCell::~ScMyCell() //============================================================================== -bool ScMyExportAnnotation::operator<(const ScMyExportAnnotation& rAnno) const -{ - if( aCellAddress.Row != rAnno.aCellAddress.Row ) - return (aCellAddress.Row < rAnno.aCellAddress.Row); - else - return (aCellAddress.Column < rAnno.aCellAddress.Column); -} - - ScMyNotEmptyCellsIterator::ScMyNotEmptyCellsIterator(ScXMLExport& rTempXMLExport) : pShapes(NULL), pNoteShapes(NULL), @@ -648,12 +637,6 @@ ScMyNotEmptyCellsIterator::~ScMyNotEmptyCellsIterator() void ScMyNotEmptyCellsIterator::Clear() { - if (!aAnnotations.empty()) - { - OSL_FAIL("not all Annotations saved"); - aAnnotations.clear(); - } - maNoteExportList.clear(); mpCellItr.reset(); pShapes = NULL; pNoteShapes = NULL; @@ -720,39 +703,27 @@ void ScMyNotEmptyCellsIterator::SetCellData( ScMyCell& rMyCell, table::CellAddre void ScMyNotEmptyCellsIterator::HasAnnotation(ScMyCell& aCell) { aCell.bHasAnnotation = false; - if (!aAnnotations.empty()) + ScAddress aAddress; + ScUnoConversion::FillScAddress( aAddress, aCell.aCellAddress ); + + ScPostIt* pNote = rExport.GetDocument()->GetNote(aAddress); + + if(pNote) { - ScMyExportAnnotationList::iterator aItr(aAnnotations.begin()); - if ((aCell.aCellAddress.Column == aItr->aCellAddress.Column) && - (aCell.aCellAddress.Row == aItr->aCellAddress.Row)) - { - aCell.xAnnotation.set(aItr->xAnnotation); - uno::Reference<text::XSimpleText> xSimpleText(aCell.xAnnotation, uno::UNO_QUERY); - if (aCell.xAnnotation.is() && xSimpleText.is()) - { - if (!xSimpleText->getString().isEmpty()) - aCell.bHasAnnotation = true; - } - aAnnotations.erase(aItr); - } + aCell.bHasAnnotation = true; + aCell.pNote = pNote; } - - // test - bypass the API - // if (xCellRange.is()) - // aCell.xCell.set(xCellRange->getCellByPosition(aCell.aCellAddress.Column, aCell.aCellAddress.Row)); } void ScMyNotEmptyCellsIterator::SetCurrentTable(const SCTAB nTable, uno::Reference<sheet::XSpreadsheet>& rxTable) { - OSL_ENSURE(aAnnotations.empty(), "not all Annotations saved"); aLastAddress.Row = 0; aLastAddress.Column = 0; aLastAddress.Sheet = nTable; if (nCurrentTable != nTable) { - maNoteExportList.clear(); nCurrentTable = nTable; mpCellItr.reset( @@ -761,53 +732,15 @@ void ScMyNotEmptyCellsIterator::SetCurrentTable(const SCTAB nTable, static_cast<SCCOL>(rExport.GetSharedData()->GetLastColumn(nCurrentTable)), static_cast<SCROW>(rExport.GetSharedData()->GetLastRow(nCurrentTable)))); - ScNotes* pNotes = rExport.GetDocument()->GetNotes(nTable); - if(pNotes) - { - for(ScNotes::iterator itr = pNotes->begin(), itrEnd = pNotes->end(); itr != itrEnd; ++itr) - { - ScNoteExportData aExportData; - aExportData.nCol = itr->first.first; - aExportData.nRow = itr->first.second; - aExportData.pNote = itr->second; - maNoteExportList.insert( aExportData ); - } - } - maNoteExportListItr = maNoteExportList.begin(); - xTable.set(rxTable); xCellRange.set(xTable, uno::UNO_QUERY); - uno::Reference<sheet::XSheetAnnotationsSupplier> xSheetAnnotationsSupplier (xTable, uno::UNO_QUERY); - if (xSheetAnnotationsSupplier.is()) - { - uno::Reference<container::XEnumerationAccess> xAnnotationAccess ( xSheetAnnotationsSupplier->getAnnotations(), uno::UNO_QUERY); - if (xAnnotationAccess.is()) - { - uno::Reference<container::XEnumeration> xAnnotations(xAnnotationAccess->createEnumeration()); - if (xAnnotations.is()) - { - while (xAnnotations->hasMoreElements()) - { - ScMyExportAnnotation aAnnotation; - aAnnotation.xAnnotation.set(xAnnotations->nextElement(), uno::UNO_QUERY); - if (aAnnotation.xAnnotation.is()) - { - aAnnotation.aCellAddress = aAnnotation.xAnnotation->getPosition(); - aAnnotations.push_back(aAnnotation); - } - } - if (!aAnnotations.empty()) - aAnnotations.sort(); - } - } - } } } void ScMyNotEmptyCellsIterator::SkipTable(SCTAB nSkip) { // Skip entries for a sheet that is copied instead of saving normally. - // Cells (including aAnnotations) are handled separately in SetCurrentTable. + // Cells are handled separately in SetCurrentTable. if( pShapes ) pShapes->SkipTable(nSkip); diff --git a/sc/source/filter/xml/XMLExportIterator.hxx b/sc/source/filter/xml/XMLExportIterator.hxx index 9fa520de1be4..857f98c9f118 100644 --- a/sc/source/filter/xml/XMLExportIterator.hxx +++ b/sc/source/filter/xml/XMLExportIterator.hxx @@ -294,8 +294,6 @@ public: // contains data to export for the current cell position struct ScMyCell { - com::sun::star::uno::Reference<com::sun::star::sheet::XSheetAnnotation> xAnnotation; - com::sun::star::uno::Reference<com::sun::star::drawing::XShape> xNoteShape; com::sun::star::table::CellAddress aCellAddress; com::sun::star::table::CellRangeAddress aMergeRange; com::sun::star::table::CellRangeAddress aMatrixRange; @@ -305,6 +303,8 @@ struct ScMyCell ScMyDetectiveObjVec aDetectiveObjVec; ScMyDetectiveOpVec aDetectiveOpVec; + ScPostIt* pNote; + sal_Int32 nValidationIndex; sal_Int32 nStyleIndex; sal_Int32 nNumberFormat; @@ -332,44 +332,11 @@ struct ScMyCell //============================================================================== -struct ScMyExportAnnotation -{ - com::sun::star::uno::Reference<com::sun::star::sheet::XSheetAnnotation> xAnnotation; - com::sun::star::table::CellAddress aCellAddress; - bool operator<(const ScMyExportAnnotation& rAnno) const; -}; - -struct ScNoteExportData -{ - SCROW nRow; - SCCOL nCol; - ScPostIt* pNote; - - bool operator<(const ScNoteExportData& r) const - { - if(nRow < r.nRow) - return true; - else if(nRow > r.nRow) - return false; - else - { - if(nCol < r.nCol) - return true; - else - return false; - } - } -}; - -typedef ::std::list< ScMyExportAnnotation > ScMyExportAnnotationList; -typedef ::std::set< ScNoteExportData > ScMyNoteExportDataList; - class ScMyNotEmptyCellsIterator : boost::noncopyable { com::sun::star::uno::Reference<com::sun::star::sheet::XSpreadsheet> xTable; com::sun::star::uno::Reference<com::sun::star::table::XCellRange> xCellRange; com::sun::star::table::CellAddress aLastAddress; - ScMyExportAnnotationList aAnnotations; ScMyShapesContainer* pShapes; ScMyNoteShapesContainer* pNoteShapes; @@ -378,8 +345,6 @@ class ScMyNotEmptyCellsIterator : boost::noncopyable ScMyAreaLinksContainer* pAreaLinks; ScMyDetectiveObjContainer* pDetectiveObj; ScMyDetectiveOpContainer* pDetectiveOp; - ScMyNoteExportDataList maNoteExportList; - ScMyNoteExportDataList::iterator maNoteExportListItr; ScXMLExport& rExport; boost::scoped_ptr<ScHorizontalCellIterator> mpCellItr; diff --git a/sc/source/filter/xml/xmlexprt.cxx b/sc/source/filter/xml/xmlexprt.cxx index 08a38fc59475..9dc411d7c3db 100644 --- a/sc/source/filter/xml/xmlexprt.cxx +++ b/sc/source/filter/xml/xmlexprt.cxx @@ -655,7 +655,6 @@ void ScXMLExport::CollectSharedData(sal_Int32& nTableCount, sal_Int32& nShapesCo for (SCTAB nTable = 0; nTable < nTableCount; ++nTable) { - pDoc->GetNotes(nTable)->CreateAllNoteCaptions(nTable); nCurrentTable = sal::static_int_cast<sal_uInt16>(nTable); uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplier(xIndex->getByIndex(nTable), uno::UNO_QUERY); if (!xDrawPageSupplier.is()) @@ -2433,7 +2432,7 @@ void ScXMLExport::_ExportAutoStyles() { //! separate method AddStyleFromNote needed? - ScPostIt* pNote = pDoc->GetNotes( nTable )->findByAddress(aPos); + ScPostIt* pNote = pDoc->GetNote(aPos); OSL_ENSURE( pNote, "note not found" ); if (pNote) { @@ -2479,7 +2478,7 @@ void ScXMLExport::_ExportAutoStyles() bool bCopySheet = pDoc->IsStreamValid( nTable ); if (bCopySheet) { - ScPostIt* pNote = pDoc->GetNotes(nTable)->findByAddress( aPos ); + ScPostIt* pNote = pDoc->GetNote( aPos ); OSL_ENSURE( pNote, "note not found" ); if (pNote) { @@ -2514,7 +2513,7 @@ void ScXMLExport::_ExportAutoStyles() bool bCopySheet = pDoc->IsStreamValid( nTable ); if (bCopySheet) { - ScPostIt* pNote = pDoc->GetNotes(nTable)->findByAddress( aPos ); + ScPostIt* pNote = pDoc->GetNote( aPos ); OSL_ENSURE( pNote, "note not found" ); if (pNote) { @@ -2764,7 +2763,7 @@ void ScXMLExport::CollectInternalShape( uno::Reference< drawing::XShape > xShape // collect note caption objects from all layers (internal or hidden) if( ScDrawObjData* pCaptData = ScDrawLayer::GetNoteCaptionData( pObject, static_cast< SCTAB >( nCurrentTable ) ) ) { - if(pDoc->GetNotes(nCurrentTable)->findByAddress(pCaptData->maStart)) + if(pDoc->GetNote(pCaptData->maStart)) { pSharedData->AddNoteObj( xShape, pCaptData->maStart ); @@ -3643,9 +3642,22 @@ void ScXMLExport::WriteAreaLink( const ScMyCell& rMyCell ) void ScXMLExport::exportAnnotationMeta( const uno::Reference < drawing::XShape >& xShape) { - if (pCurrentCell && pCurrentCell->xNoteShape.is() && pCurrentCell->xNoteShape.get() == xShape.get() && pCurrentCell->xAnnotation.is()) + ScAddress aCellPos; + ScUnoConversion::FillScAddress( aCellPos, pCurrentCell->aCellAddress ); + + ScPostIt* pNote = pCurrentCell->pNote; + + if (pNote) { - OUString sAuthor(pCurrentCell->xAnnotation->getAuthor()); + // TODO : notes + //is it still usefull, as this call back is only called from ScXMLExport::WriteAnnotation + // and should be in sync with pCurrentCell + SdrCaptionObj* pNoteCaption = pNote->GetOrCreateCaption(aCellPos); + Reference<drawing::XShape> xCurrentShape( pNoteCaption->getUnoShape(), uno::UNO_QUERY ); + if (xCurrentShape.get()!=xShape.get()) + return; + + OUString sAuthor(pNote->GetAuthor()); if (!sAuthor.isEmpty()) { SvXMLElementExport aCreatorElem( *this, XML_NAMESPACE_DC, @@ -3654,7 +3666,7 @@ void ScXMLExport::exportAnnotationMeta( const uno::Reference < drawing::XShape > Characters(sAuthor); } - OUString aDate(pCurrentCell->xAnnotation->getDate()); + OUString aDate(pNote->GetDate()); if (pDoc) { SvNumberFormatter* pNumForm = pDoc->GetFormatTable(); @@ -3689,20 +3701,25 @@ void ScXMLExport::exportAnnotationMeta( const uno::Reference < drawing::XShape > void ScXMLExport::WriteAnnotation(ScMyCell& rMyCell) { - if( rMyCell.bHasAnnotation && rMyCell.xAnnotation.is()) - { - if (rMyCell.xAnnotation->getIsVisible()) + ScAddress aCellPos; + ScUnoConversion::FillScAddress( aCellPos, rMyCell.aCellAddress ); + + ScPostIt* pNote = pDoc->GetNote(aCellPos); + if (pNote) + { + if (pNote->IsCaptionShown()) AddAttribute(XML_NAMESPACE_OFFICE, XML_DISPLAY, XML_TRUE); pCurrentCell = &rMyCell; - if(rMyCell.xNoteShape.is()) - GetShapeExport()->exportShape(rMyCell.xNoteShape, SEF_DEFAULT|SEF_EXPORT_ANNOTATION, NULL); + SdrCaptionObj* pNoteCaption = pNote->GetOrCreateCaption(aCellPos); + Reference<drawing::XShape> xShape( pNoteCaption->getUnoShape(), uno::UNO_QUERY ); + + GetShapeExport()->exportShape(xShape, SEF_DEFAULT|SEF_EXPORT_ANNOTATION, NULL); pCurrentCell = NULL; - rMyCell.xNoteShape.clear(); } } diff --git a/sc/source/ui/Accessibility/AccessibleDocumentPagePreview.cxx b/sc/source/ui/Accessibility/AccessibleDocumentPagePreview.cxx index a3ab93dcb0c5..e69201f9ae9c 100644 --- a/sc/source/ui/Accessibility/AccessibleDocumentPagePreview.cxx +++ b/sc/source/ui/Accessibility/AccessibleDocumentPagePreview.cxx @@ -182,7 +182,7 @@ sal_Int32 ScNotesChildren::AddNotes(const ScPreviewLocationData& rData, const Re } else { - if( ScPostIt* pNote = pDoc->GetNotes( aNote.maNoteCell.Tab() )->findByAddress( aNote.maNoteCell ) ) + if( ScPostIt* pNote = pDoc->GetNote( aNote.maNoteCell ) ) aNote.maNoteText = pNote->GetText(); aNote.mpTextHelper = CreateTextHelper(aNote.maNoteText, aNote.maRect, aNote.maNoteCell, aNote.mbMarkNote, nParagraphs + mnOffset); if (aNote.mpTextHelper) @@ -359,7 +359,7 @@ sal_Int32 ScNotesChildren::CheckChanges(const ScPreviewLocationData& rData, } else { - if( ScPostIt* pNote = pDoc->GetNotes( aNote.maNoteCell.Tab() )->findByAddress( aNote.maNoteCell ) ) + if( ScPostIt* pNote = pDoc->GetNote( aNote.maNoteCell ) ) aNote.maNoteText = pNote->GetText(); } diff --git a/sc/source/ui/docshell/dbdocfun.cxx b/sc/source/ui/docshell/dbdocfun.cxx index 2190a1a0293e..4dcdc59dc9bc 100644 --- a/sc/source/ui/docshell/dbdocfun.cxx +++ b/sc/source/ui/docshell/dbdocfun.cxx @@ -1134,7 +1134,6 @@ sal_Bool ScDBDocFunc::DoSubTotals( SCTAB nTab, const ScSubTotalParam& rParam, Sort( nTab, aSortParam, false, false, bApi ); } - pDoc->InitializeNoteCaptions(nTab); bSuccess = pDoc->DoSubTotals( nTab, aNewParam ); pDoc->SetDrawPageSize(nTab); } diff --git a/sc/source/ui/docshell/docfunc.cxx b/sc/source/ui/docshell/docfunc.cxx index 9f2195ebcb9e..56008a2c691d 100644 --- a/sc/source/ui/docshell/docfunc.cxx +++ b/sc/source/ui/docshell/docfunc.cxx @@ -1155,7 +1155,7 @@ bool ScDocFunc::SetCellText( bool ScDocFunc::ShowNote( const ScAddress& rPos, bool bShow ) { ScDocument& rDoc = *rDocShell.GetDocument(); - ScPostIt* pNote = rDoc.GetNotes( rPos.Tab() )->findByAddress( rPos ); + ScPostIt* pNote = rDoc.GetNote( rPos ); if( !pNote || (bShow == pNote->IsCaptionShown()) ) return false; // move the caption to internal or hidden layer and create undo action @@ -1188,7 +1188,7 @@ bool ScDocFunc::SetNoteText( const ScAddress& rPos, const OUString& rText, sal_B OUString aNewText = convertLineEnd(rText, GetSystemLineEnd()); //! ist das noetig ??? - if( ScPostIt* pNote = (!aNewText.isEmpty()) ? pDoc->GetNotes(rPos.Tab())->GetOrCreateNote( rPos ) : pDoc->GetNotes( rPos.Tab() )->findByAddress(rPos) ) + if( ScPostIt* pNote = (!aNewText.isEmpty()) ? pDoc->GetOrCreateNote( rPos ) : pDoc->GetNote(rPos) ) pNote->SetText( rPos, aNewText ); //! Undo !!! @@ -1217,7 +1217,7 @@ bool ScDocFunc::ReplaceNote( const ScAddress& rPos, const OUString& rNoteText, c ::svl::IUndoManager* pUndoMgr = (pDrawLayer && rDoc.IsUndoEnabled()) ? rDocShell.GetUndoManager() : 0; ScNoteData aOldData; - ScPostIt* pOldNote = rDoc.GetNotes(rPos.Tab())->ReleaseNote( rPos ); + ScPostIt* pOldNote = rDoc.ReleaseNote( rPos ); if( pOldNote ) { // ensure existing caption object before draw undo tracking starts @@ -1724,8 +1724,6 @@ bool ScDocFunc::InsertCells( const ScRange& rRange, const ScMarkData* pTabMark, itr = aMark.begin(); for (; itr != itrEnd && nTabCount; ++itr) { - pDoc->InitializeNoteCaptions(*itr); - i = *itr; if( pDoc->HasAttrib( nMergeTestStartCol, nMergeTestStartRow, i, nMergeTestEndCol, nMergeTestEndRow, i, HASATTR_MERGED | HASATTR_OVERLAPPED ) ) { @@ -2141,8 +2139,6 @@ bool ScDocFunc::DeleteCells( const ScRange& rRange, const ScMarkData* pTabMark, itr = aMark.begin(); for (; itr != itrEnd && *itr < nTabCount; ++itr) { - pDoc->InitializeNoteCaptions(*itr); - SCTAB i = *itr; if ( pDoc->HasAttrib( nUndoStartCol, nUndoStartRow, i, nMergeTestEndCol, nMergeTestEndRow, i, HASATTR_MERGED | HASATTR_OVERLAPPED )) { @@ -2715,14 +2711,14 @@ sal_Bool ScDocFunc::MoveBlock( const ScRange& rSource, const ScAddress& rDestPos aDestMark.SelectTable( nTab, sal_True ); // Destination selektieren aDestMark.SetMarkArea( aPasteDest ); - /* Do not copy cell notes and drawing objects here. While pasting, the + /* Do not drawing objects here. While pasting, the function ScDocument::UpdateReference() is called which calls ScDrawLayer::MoveCells() which may move away inserted objects to wrong - positions (e.g. if source and destination range overlaps). Cell notes - and drawing objects are pasted below after doing all adjusting. */ - pDoc->CopyFromClip( aPasteDest, aDestMark, IDF_ALL & ~(IDF_NOTE | IDF_OBJECTS), + positions (e.g. if source and destination range overlaps).*/ + pDoc->CopyFromClip( aPasteDest, aDestMark, IDF_ALL & ~(IDF_OBJECTS), pRefUndoDoc, pClipDoc, sal_True, false, bIncludeFiltered ); + // skipped rows and merged cells don't mix if ( !bIncludeFiltered && pClipDoc->HasClipFilteredRows() ) UnmergeCells( aPasteDest, false ); @@ -2732,15 +2728,11 @@ sal_Bool ScDocFunc::MoveBlock( const ScRange& rSource, const ScAddress& rDestPos ScRange( 0,nDestRow,nDestTab, MAXCOL,nDestEndRow,nDestEndTab ), false ); - /* Paste cell notes and drawing objects after adjusting formula references + /* Paste drawing objects after adjusting formula references and row heights. There are no cell notes or drawing objects, if the - clipdoc does not contain a drawing layer. - #i102056# Passing IDF_NOTE only would overwrite cell contents with - empty note cells, therefore the special modifier IDF_ADDNOTES is passed - here too which changes the behaviour of ScColumn::CopyFromClip() to not - touch existing cells. */ + clipdoc does not contain a drawing layer.*/ if ( pClipDoc->GetDrawLayer() ) - pDoc->CopyFromClip( aPasteDest, aDestMark, IDF_NOTE | IDF_ADDNOTES | IDF_OBJECTS, + pDoc->CopyFromClip( aPasteDest, aDestMark, IDF_OBJECTS, pRefUndoDoc, pClipDoc, sal_True, false, bIncludeFiltered ); if (bRecord) @@ -3407,7 +3399,6 @@ sal_Bool ScDocFunc::SetWidthOrHeight( sal_Bool bWidth, SCCOLROW nRangeCnt, SCCOL sal_Bool bShow = nSizeTwips > 0 || eMode != SC_SIZE_DIRECT; sal_Bool bOutline = false; - pDoc->InitializeNoteCaptions(nTab); for (SCCOLROW nRangeNo=0; nRangeNo<nRangeCnt; nRangeNo++) { SCCOLROW nStartNo = *(pRanges++); @@ -4693,7 +4684,7 @@ sal_Bool ScDocFunc::MergeCells( const ScCellMergeOption& rOption, sal_Bool bCont bool bHasNotes = false; for( ScAddress aPos( nStartCol, nStartRow, nTab ); !bHasNotes && (aPos.Col() <= nEndCol); aPos.IncCol() ) for( aPos.SetRow( nStartRow ); !bHasNotes && (aPos.Row() <= nEndRow); aPos.IncRow() ) - bHasNotes = ((aPos.Col() != nStartCol) || (aPos.Row() != nStartRow)) && (pDoc->GetNotes( aPos.Tab() )->findByAddress(aPos) != 0); + bHasNotes = ((aPos.Col() != nStartCol) || (aPos.Row() != nStartRow)) && (pDoc->HasNote(aPos)); if (!pUndoDoc) { diff --git a/sc/source/ui/docshell/docsh.cxx b/sc/source/ui/docshell/docsh.cxx index 51f8544c32bb..b8f35791707d 100644 --- a/sc/source/ui/docshell/docsh.cxx +++ b/sc/source/ui/docshell/docsh.cxx @@ -247,7 +247,7 @@ sal_uInt16 ScDocShell::GetHiddenInformationState( sal_uInt16 nStates ) bool bFound = false; for (SCTAB nTab = 0; nTab < nTableCount && !bFound; ++nTab) { - if (!aDocument.GetNotes(nTab)->empty()) + if (aDocument.HasTabNotes(nTab)) //TODO: bFound = true; } diff --git a/sc/source/ui/docshell/olinefun.cxx b/sc/source/ui/docshell/olinefun.cxx index dae37214f2c0..8be9257a1716 100644 --- a/sc/source/ui/docshell/olinefun.cxx +++ b/sc/source/ui/docshell/olinefun.cxx @@ -374,7 +374,6 @@ sal_Bool ScOutlineDocFunc::SelectLevel( SCTAB nTab, sal_Bool bColumns, sal_uInt1 bColumns, nLevel ) ); } - pDoc->InitializeNoteCaptions(nTab); ScSubOutlineIterator aIter( pArray ); // alle Eintraege ScOutlineEntry* pEntry; while ((pEntry=aIter.GetNext()) != NULL) @@ -469,8 +468,6 @@ sal_Bool ScOutlineDocFunc::ShowMarkedOutlines( const ScRange& rRange, sal_Bool b pUndoDoc, pUndoTab, sal_True ) ); } - pDoc->InitializeNoteCaptions(nTab); - // Spalten nMin=MAXCOL; @@ -498,7 +495,6 @@ sal_Bool ScOutlineDocFunc::ShowMarkedOutlines( const ScRange& rRange, sal_Bool b nMax=0; pArray = pTable->GetRowArray(); ScSubOutlineIterator aRowIter( pArray ); - pDoc->InitializeNoteCaptions(nTab); while ((pEntry=aRowIter.GetNext()) != NULL) { nStart = pEntry->GetStart(); @@ -588,8 +584,6 @@ sal_Bool ScOutlineDocFunc::HideMarkedOutlines( const ScRange& rRange, sal_Bool b pUndoDoc, pUndoTab, false ) ); } - pDoc->InitializeNoteCaptions(nTab); - // Spalten nCount = pColArray->GetCount(nColLevel); @@ -667,7 +661,6 @@ sal_Bool ScOutlineDocFunc::ShowOutline( SCTAB nTab, sal_Bool bColumns, sal_uInt1 bColumns, nLevel, nEntry, sal_True ) ); } - pDoc->InitializeNoteCaptions(nTab); pEntry->SetHidden(false); SCCOLROW i; for ( i = nStart; i <= nEnd; i++ ) @@ -752,7 +745,6 @@ sal_Bool ScOutlineDocFunc::HideOutline( SCTAB nTab, sal_Bool bColumns, sal_uInt1 bColumns, nLevel, nEntry, false ) ); } - pDoc->InitializeNoteCaptions(nTab); pEntry->SetHidden(true); SCCOLROW i; if ( bColumns ) diff --git a/sc/source/ui/drawfunc/futext3.cxx b/sc/source/ui/drawfunc/futext3.cxx index 8a119956e585..e2f301b12f0c 100644 --- a/sc/source/ui/drawfunc/futext3.cxx +++ b/sc/source/ui/drawfunc/futext3.cxx @@ -70,7 +70,7 @@ void FuText::StopEditMode(sal_Bool /*bTextDirection*/) if( const ScDrawObjData* pCaptData = ScDrawLayer::GetNoteCaptionData( pObject, rViewData.GetTabNo() ) ) { aNotePos = pCaptData->maStart; - pNote = rDoc.GetNotes( aNotePos.Tab() )->findByAddress( aNotePos ); + pNote = rDoc.GetNote( aNotePos ); OSL_ENSURE( pNote && (pNote->GetCaption() == pObject), "FuText::StopEditMode - missing or invalid cell note" ); } @@ -142,13 +142,13 @@ void FuText::StopEditMode(sal_Bool /*bTextDirection*/) // rescue note data before deletion ScNoteData aNoteData( pNote->GetNoteData() ); // delete note from document (removes caption, but does not delete it) - rDoc.GetNotes( aNotePos.Tab() )->erase( aNotePos ); + rDoc.ReleaseNote(aNotePos); // create undo action for removed note pUndoMgr->AddUndoAction( new ScUndoReplaceNote( *pDocShell, aNotePos, aNoteData, false, pDrawLayer->GetCalcUndo() ) ); } else { - rDoc.GetNotes( aNotePos.Tab() )->erase( aNotePos ); + rDoc.ReleaseNote(aNotePos); } // ScDocument::DeleteNote has deleted the note that pNote points to pNote = 0; diff --git a/sc/source/ui/navipi/content.cxx b/sc/source/ui/navipi/content.cxx index f2ba4a0c3f3b..6ee7650a6a5a 100644 --- a/sc/source/ui/navipi/content.cxx +++ b/sc/source/ui/navipi/content.cxx @@ -58,6 +58,9 @@ #include "clipparam.hxx" #include "markdata.hxx" +#include "table.hxx" +#include "column.hxx" + using namespace com::sun::star; // Reihenfolge der Kategorien im Navigator ------------------------------------- @@ -848,6 +851,7 @@ static OUString lcl_NoteString( const ScPostIt& rNote ) return aText; } + void ScContentTree::GetNoteStrings() { if ( nRootType && nRootType != SC_CONTENT_NOTE ) // ausgeblendet ? @@ -857,14 +861,35 @@ void ScContentTree::GetNoteStrings() if (!pDoc) return; + // loop over cell notes SCTAB nTabCount = pDoc->GetTableCount(); for (SCTAB nTab=0; nTab<nTabCount; nTab++) { - ScNotes::iterator itr = pDoc->GetNotes(nTab)->begin(); - ScNotes::iterator itrEnd = pDoc->GetNotes(nTab)->end(); - for (; itr != itrEnd; ++itr) + for (SCCOL nCol=0; nCol<MAXCOLCOUNT; nCol++) { - InsertContent(SC_CONTENT_NOTE, lcl_NoteString(*itr->second)); + if ( pDoc->HasColNotes(nCol, nTab) ) + { + sc::CellNoteStoreType& maCellNotes = pDoc->GetColNotes(nCol, nTab); + + sc::CellNoteStoreType::const_iterator itBlk = maCellNotes.begin(), itBlkEnd = maCellNotes.end(); + sc::cellnote_block::const_iterator itData, itDataEnd; + + for(;itBlk != itBlkEnd; ++itBlk) + { + if (itBlk->data) + { + itData = sc::cellnote_block::begin(*itBlk->data); + itDataEnd = sc::cellnote_block::end(*itBlk->data); + for (; itData != itDataEnd; ++itData) + { + ScPostIt* pNote = *itData; + if (pNote) + InsertContent(SC_CONTENT_NOTE, lcl_NoteString( *pNote )); + } + } + + } + } } } } @@ -877,27 +902,46 @@ ScAddress ScContentTree::GetNotePos( sal_uLong nIndex ) sal_uLong nFound = 0; SCTAB nTabCount = pDoc->GetTableCount(); + for (SCTAB nTab=0; nTab<nTabCount; nTab++) { - ScNotes* pNotes = pDoc->GetNotes(nTab); - if (nFound + pNotes->size() >= nIndex) + for (SCCOL nCol=0; nCol<MAXCOLCOUNT; nCol++) { - for (ScNotes::const_iterator itr = pNotes->begin(); itr != pNotes->end(); ++itr) + if ( pDoc->HasColNotes(nCol, nTab) ) { - if (nFound == nIndex) - return ScAddress( itr->first.first, itr->first.second, nTab ); // gefunden + sc::CellNoteStoreType& maCellNotes = pDoc->GetColNotes(nCol, nTab); + + sc::CellNoteStoreType::const_iterator itBlk = maCellNotes.begin(), itBlkEnd = maCellNotes.end(); + sc::cellnote_block::const_iterator itData, itDataEnd; - ++nFound; + for(;itBlk != itBlkEnd; ++itBlk) + { + if (itBlk->data) + { + SCROW nRow = itBlk->position; + itData = sc::cellnote_block::begin(*itBlk->data); + itDataEnd = sc::cellnote_block::end(*itBlk->data); + for (; itData != itDataEnd; ++itData, ++nRow) + { + ScPostIt* pNote = *itData; + if (pNote) + { + if (nFound == nIndex) + return ScAddress(nCol, nRow, nTab); + ++nFound; + } + } + } + } } } - else - nFound += pNotes->size(); } OSL_FAIL("note not found"); return ScAddress(); } + sal_Bool ScContentTree::NoteStringsChanged() { ScDocument* pDoc = GetSourceDocument(); @@ -914,19 +958,30 @@ sal_Bool ScContentTree::NoteStringsChanged() SCTAB nTabCount = pDoc->GetTableCount(); for (SCTAB nTab=0; nTab<nTabCount && bEqual; nTab++) { - ScNotes* pNotes = pDoc->GetNotes(nTab); - for (ScNotes::const_iterator itr = pNotes->begin(); itr != pNotes->end(); ++itr) + for (SCCOL nCol=0; nCol<MAXCOLCOUNT; nCol++) { - if( const ScPostIt* pNote = itr->second ) + if ( pDoc->HasColNotes(nCol, nTab) ) { - if ( !pEntry ) - bEqual = false; - else + sc::CellNoteStoreType& maCellNotes = pDoc->GetColNotes(nCol, nTab); + sc::CellNoteStoreType::const_iterator it = maCellNotes.begin(), itEnd = maCellNotes.end(); + for (; it != itEnd; ++it) { - if ( lcl_NoteString( *pNote ) != GetEntryText(pEntry) ) - bEqual = false; - - pEntry = NextSibling( pEntry ); + if (it->type == sc::element_type_cellnote) + { + SCROW nRow = it->position; + ScPostIt* pNote = maCellNotes.get<ScPostIt*>(nRow); + if (pNote) + { + if ( !pEntry ) + bEqual = false; + else + { + if ( lcl_NoteString( *pNote ) != GetEntryText(pEntry) ) + bEqual = false; + pEntry = NextSibling( pEntry ); + } + } + } } } } diff --git a/sc/source/ui/undo/undoblk.cxx b/sc/source/ui/undo/undoblk.cxx index 7b7d726f8710..946ed998d751 100644 --- a/sc/source/ui/undo/undoblk.cxx +++ b/sc/source/ui/undo/undoblk.cxx @@ -1284,8 +1284,9 @@ void ScUndoDragDrop::Redo() aSourceMark.SelectTable( nTab, sal_True ); // do not clone objects and note captions into clipdoc (see above) + // but at least copy notes ScClipParam aClipParam(aSrcRange, bCut); - pDoc->CopyToClip(aClipParam, pClipDoc, &aSourceMark, false, bKeepScenarioFlags, false, false); + pDoc->CopyToClip(aClipParam, pClipDoc, &aSourceMark, false, bKeepScenarioFlags, false, true); if (bCut) { diff --git a/sc/source/ui/undo/undoblk3.cxx b/sc/source/ui/undo/undoblk3.cxx index 53fb213f774f..2037eb7bb1ec 100644 --- a/sc/source/ui/undo/undoblk3.cxx +++ b/sc/source/ui/undo/undoblk3.cxx @@ -999,7 +999,7 @@ void ScUndoReplace::Undo() } else if (pSearchItem->GetCellType() == SVX_SEARCHIN_NOTE) { - ScPostIt* pNote = pDoc->GetNotes( aCursorPos.Tab() )->findByAddress( aCursorPos ); + ScPostIt* pNote = pDoc->GetNote(aCursorPos); OSL_ENSURE( pNote, "ScUndoReplace::Undo - cell does not contain a note" ); if (pNote) pNote->SetText( aCursorPos, aUndoStr ); diff --git a/sc/source/ui/undo/undocell.cxx b/sc/source/ui/undo/undocell.cxx index 106a0771894c..2a22f5991e37 100644 --- a/sc/source/ui/undo/undocell.cxx +++ b/sc/source/ui/undo/undocell.cxx @@ -850,9 +850,9 @@ void ScUndoReplaceNote::DoInsertNote( const ScNoteData& rNoteData ) if( rNoteData.mpCaption ) { ScDocument& rDoc = *pDocShell->GetDocument(); - OSL_ENSURE( !rDoc.GetNotes( maPos.Tab() )->findByAddress(maPos), "ScUndoReplaceNote::DoInsertNote - unexpected cell note" ); + OSL_ENSURE( !rDoc.GetNote(maPos), "ScUndoReplaceNote::DoInsertNote - unexpected cell note" ); ScPostIt* pNote = new ScPostIt( rDoc, maPos, rNoteData, false ); - rDoc.GetNotes(maPos.Tab())->insert( maPos, pNote ); + rDoc.SetNote( maPos, pNote ); } } @@ -861,8 +861,8 @@ void ScUndoReplaceNote::DoRemoveNote( const ScNoteData& rNoteData ) if( rNoteData.mpCaption ) { ScDocument& rDoc = *pDocShell->GetDocument(); - OSL_ENSURE( rDoc.GetNotes( maPos.Tab() )->findByAddress(maPos), "ScUndoReplaceNote::DoRemoveNote - missing cell note" ); - if( ScPostIt* pNote = rDoc.GetNotes(maPos.Tab())->ReleaseNote( maPos ) ) + OSL_ENSURE( rDoc.GetNote(maPos), "ScUndoReplaceNote::DoRemoveNote - missing cell note" ); + if( ScPostIt* pNote = rDoc.ReleaseNote( maPos ) ) { /* Forget pointer to caption object to suppress removing the caption object from the drawing layer while deleting pNote @@ -887,7 +887,7 @@ ScUndoShowHideNote::~ScUndoShowHideNote() void ScUndoShowHideNote::Undo() { BeginUndo(); - if( ScPostIt* pNote = pDocShell->GetDocument()->GetNotes( maPos.Tab() )->findByAddress(maPos) ) + if( ScPostIt* pNote = pDocShell->GetDocument()->GetNote(maPos) ) pNote->ShowCaption( maPos, !mbShown ); EndUndo(); } @@ -895,7 +895,7 @@ void ScUndoShowHideNote::Undo() void ScUndoShowHideNote::Redo() { BeginRedo(); - if( ScPostIt* pNote = pDocShell->GetDocument()->GetNotes( maPos.Tab() )->findByAddress(maPos) ) + if( ScPostIt* pNote = pDocShell->GetDocument()->GetNote(maPos) ) pNote->ShowCaption( maPos, mbShown ); EndRedo(); } diff --git a/sc/source/ui/unoobj/docuno.cxx b/sc/source/ui/unoobj/docuno.cxx index 0858adbac50b..3fbac19eebb8 100644 --- a/sc/source/ui/unoobj/docuno.cxx +++ b/sc/source/ui/unoobj/docuno.cxx @@ -3433,15 +3433,33 @@ bool ScAnnotationsObj::GetAddressByIndex_Impl( sal_Int32 nIndex, ScAddress& rPos { sal_Int32 nFound = 0; ScDocument* pDoc = pDocShell->GetDocument(); - const ScNotes* pNotes = pDoc->GetNotes(nTab); - for (ScNotes::const_iterator itr = pNotes->begin(); itr != pNotes->end(); ++itr) + SCTAB nTabCount = pDoc->GetTableCount(); + for (SCTAB aTab=0; aTab<nTabCount; aTab++) { - if (nFound == nIndex) + for (SCCOL nCol=0; nCol<MAXCOLCOUNT; nCol++) { - rPos = ScAddress( itr->first.first, itr->first.second, nTab ); - return true; + sc::CellNoteStoreType& maNotes = pDoc->GetColNotes(nCol, aTab); + std::pair<sc::CellNoteStoreType::const_iterator,size_t> aPos = maNotes.position(0); + sc::CellNoteStoreType::const_iterator it = aPos.first; + size_t nOffset = aPos.second; + size_t nDataSize = 0; + size_t nRow = 0; + if (nFound + maNotes.size() >= nIndex) + { + for (; it != maNotes.end(); ++it, nOffset = 0, nRow += nDataSize) + { + nDataSize = it->size - nOffset; + if (nFound == nIndex) + { + rPos = ScAddress(nCol, nRow, nTab); + return true; + } + ++nFound; + } + } + else + nFound += maNotes.size(); } - ++nFound; } } return false; @@ -3510,7 +3528,7 @@ sal_Int32 SAL_CALL ScAnnotationsObj::getCount() throw(uno::RuntimeException) if (pDocShell) { ScDocument* pDoc = pDocShell->GetDocument(); - nCount = pDoc->GetNotes(nTab)->size(); + nCount = pDoc->CountNotes(); } return nCount; } diff --git a/sc/source/ui/unoobj/editsrc.cxx b/sc/source/ui/unoobj/editsrc.cxx index 6f64090c7875..b48ae1ba33cd 100644 --- a/sc/source/ui/unoobj/editsrc.cxx +++ b/sc/source/ui/unoobj/editsrc.cxx @@ -137,7 +137,7 @@ SvxEditSource* ScAnnotationEditSource::Clone() const SdrObject* ScAnnotationEditSource::GetCaptionObj() { - ScPostIt* pNote = pDocShell->GetDocument()->GetNotes( aCellPos.Tab() )->findByAddress(aCellPos); + ScPostIt* pNote = pDocShell->GetDocument()->GetNote(aCellPos); return pNote ? pNote->GetOrCreateCaption( aCellPos ) : 0; } @@ -163,7 +163,7 @@ SvxTextForwarder* ScAnnotationEditSource::GetTextForwarder() return pForwarder; if ( pDocShell ) - if ( ScPostIt* pNote = pDocShell->GetDocument()->GetNotes( aCellPos.Tab() )->findByAddress(aCellPos) ) + if ( ScPostIt* pNote = pDocShell->GetDocument()->GetNote(aCellPos) ) if ( const EditTextObject* pEditObj = pNote->GetEditTextObject() ) pEditEngine->SetText( *pEditObj ); // incl. Umbrueche diff --git a/sc/source/ui/unoobj/notesuno.cxx b/sc/source/ui/unoobj/notesuno.cxx index be5bc1f107ef..1822003b5b4d 100644 --- a/sc/source/ui/unoobj/notesuno.cxx +++ b/sc/source/ui/unoobj/notesuno.cxx @@ -251,6 +251,6 @@ SvxUnoText& ScAnnotationObj::GetUnoText() const ScPostIt* ScAnnotationObj::ImplGetNote() const { - return pDocShell ? pDocShell->GetDocument()->GetNotes( aCellPos.Tab() )->findByAddress(aCellPos) : 0; + return pDocShell ? pDocShell->GetDocument()->GetNote(aCellPos) : 0; } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/source/ui/view/cellsh.cxx b/sc/source/ui/view/cellsh.cxx index 6fe7c0e2ffff..e1ed032bcadd 100644 --- a/sc/source/ui/view/cellsh.cxx +++ b/sc/source/ui/view/cellsh.cxx @@ -602,7 +602,7 @@ void ScCellShell::GetState(SfxItemSet &rSet) { // always take cursor position, do not use top-left cell of selection OUString aNoteText; - if ( const ScPostIt* pNote = pDoc->GetNotes(nTab)->findByAddress(nPosX, nPosY) ) + if ( const ScPostIt* pNote = pDoc->GetNote(nPosX, nPosY, nTab) ) aNoteText = pNote->GetText(); rSet.Put( SfxStringItem( nWhich, aNoteText ) ); } @@ -906,7 +906,7 @@ void ScCellShell::GetState(SfxItemSet &rSet) case FID_NOTE_VISIBLE: { - const ScPostIt* pNote = pDoc->GetNotes(nTab)->findByAddress(nPosX, nPosY); + const ScPostIt* pNote = pDoc->GetNote(nPosX, nPosY, nTab); if ( pNote && pDoc->IsBlockEditable( nTab, nPosX,nPosY, nPosX,nPosY ) ) rSet.Put( SfxBoolItem( nWhich, pNote->IsCaptionShown() ) ); else @@ -922,7 +922,7 @@ void ScCellShell::GetState(SfxItemSet &rSet) if (!rMark.IsMarked() && !rMark.IsMultiMarked()) { // Check current cell - const ScPostIt* pNote = pDoc->GetNotes(nTab)->findByAddress(nPosX, nPosY); + const ScPostIt* pNote = pDoc->GetNote(nPosX, nPosY, nTab); if ( pNote && pDoc->IsBlockEditable( nTab, nPosX,nPosY, nPosX,nPosY ) ) if ( pNote->IsCaptionShown() != bSearchForHidden) bEnable = true; @@ -943,41 +943,18 @@ void ScCellShell::GetState(SfxItemSet &rSet) const SCCOL nCol0 = pRange->aStart.Col(); const SCCOL nCol1 = pRange->aEnd.Col(); const SCTAB nRangeTab = pRange->aStart.Tab(); - const size_t nCellNumber = ( nRow1 - nRow0 ) * ( nCol1 - nCol0 ); - const ScNotes *pNotes = pDoc->GetNotes(nRangeTab); - - if ( nCellNumber < pNotes->size() ) - { - // Check by each cell - for ( SCROW nRow = nRow0; nRow <= nRow1 && !bEnable; ++nRow ) - { - for ( SCCOL nCol = nCol0; nCol <= nCol1; ++nCol ) - { - const ScPostIt* pNote = pNotes->findByAddress(nCol, nRow); - if ( pNote && pDoc->IsBlockEditable( nRangeTab, nCol,nRow, nCol,nRow ) ) - { - if ( pNote->IsCaptionShown() != bSearchForHidden) - { - bEnable = true; - break; - } - } - } - } - } - else + // Check by each cell + // nCellNumber < pDoc->CountNotes() with const size_t nCellNumber = ( nRow1 - nRow0 ) * ( nCol1 - nCol0 ); + for ( SCROW nRow = nRow0; nRow <= nRow1 && !bEnable; ++nRow ) { - // Check by each document note - for (ScNotes::const_iterator itr = pNotes->begin(); itr != pNotes->end(); ++itr) + for ( SCCOL nCol = nCol0; nCol <= nCol1; ++nCol ) { - SCCOL nCol = itr->first.first; - SCROW nRow = itr->first.second; - - if ( nCol <= nCol1 && nRow <= nRow1 && nCol >= nCol0 && nRow >= nRow0 ) + const ScPostIt* pNote = pDoc->GetNote(nCol, nRow, nRangeTab); + if ( pNote && pDoc->IsBlockEditable( nRangeTab, nCol,nRow, nCol,nRow ) ) { - if ( itr->second->IsCaptionShown() != bSearchForHidden) + if ( pNote->IsCaptionShown() != bSearchForHidden) { - bEnable = true; //note found + bEnable = true; break; } } @@ -1003,17 +980,16 @@ void ScCellShell::GetState(SfxItemSet &rSet) size_t nCount = aRanges.size(); for (size_t nPos = 0; nPos < nCount && !bEnable; ++nPos) { - ScNotes* pNotes = pDoc->GetNotes( aRanges[nPos]->aStart.Tab() ); - for (ScNotes::const_iterator itr = pNotes->begin(); itr != pNotes->end(); ++itr) + SCTAB aTab = aRanges[nPos]->aStart.Tab(); + for (SCCOL aCol=aRanges[nPos]->aStart.Col(); aCol <= aRanges[nPos]->aEnd.Col() && !bEnable; aCol++) { - SCCOL nCol = itr->first.first; - SCROW nRow = itr->first.second; - - if ( nCol <= aRanges[nPos]->aEnd.Col() && nRow <= aRanges[nPos]->aEnd.Row() - && nCol >= aRanges[nPos]->aStart.Col() && nRow >= aRanges[nPos]->aStart.Row() ) + for (SCROW aRow=aRanges[nPos]->aStart.Row(); aRow <= aRanges[nPos]->aEnd.Row(); aRow++) { - bEnable = true; //note found - break; + if (pDoc->HasNote(aCol, aRow, aTab)) + { + bEnable = true; + break; + } } } } @@ -1022,7 +998,7 @@ void ScCellShell::GetState(SfxItemSet &rSet) else { bEnable = pDoc->IsBlockEditable( nTab, nPosX,nPosY, nPosX,nPosY ) && - pDoc->GetNotes(nTab)->findByAddress( nPosX, nPosY ); + pDoc->GetNote(nPosX, nPosY, nTab); } if ( !bEnable ) rSet.DisableItem( nWhich ); diff --git a/sc/source/ui/view/cellsh1.cxx b/sc/source/ui/view/cellsh1.cxx index 75d4a8dfa88b..83901a69e971 100644 --- a/sc/source/ui/view/cellsh1.cxx +++ b/sc/source/ui/view/cellsh1.cxx @@ -2113,7 +2113,7 @@ void ScCellShell::ExecuteEdit( SfxRequest& rReq ) { ScDocument* pDoc = GetViewData()->GetDocument(); ScAddress aPos( GetViewData()->GetCurX(), GetViewData()->GetCurY(), GetViewData()->GetTabNo() ); - if( ScPostIt* pNote = pDoc->GetNotes( aPos.Tab() )->findByAddress(aPos) ) + if( ScPostIt* pNote = pDoc->GetNote(aPos) ) { bool bShow; const SfxPoolItem* pItem; @@ -2148,7 +2148,7 @@ void ScCellShell::ExecuteEdit( SfxRequest& rReq ) { // Check current cell ScAddress aPos( pData->GetCurX(), pData->GetCurY(), pData->GetTabNo() ); - if( pDoc->GetNotes( aPos.Tab() )->findByAddress(aPos) ) + if( pDoc->GetNote(aPos) ) { pData->GetDocShell()->GetDocFunc().ShowNote( aPos, bShowNote ); bDone = true; @@ -2173,35 +2173,12 @@ void ScCellShell::ExecuteEdit( SfxRequest& rReq ) const SCCOL nCol0 = pRange->aStart.Col(); const SCCOL nCol1 = pRange->aEnd.Col(); const SCTAB nRangeTab = pRange->aStart.Tab(); - const size_t nCellNumber = ( nRow1 - nRow0 ) * ( nCol1 - nCol0 ); - ScNotes *pNotes = pDoc->GetNotes(nRangeTab); - - if ( nCellNumber < pNotes->size() ) + // Check by each cell + for ( SCROW nRow = nRow0; nRow <= nRow1; ++nRow ) { - // Check by each cell - for ( SCROW nRow = nRow0; nRow <= nRow1; ++nRow ) + for ( SCCOL nCol = nCol0; nCol <= nCol1; ++nCol ) { - for ( SCCOL nCol = nCol0; nCol <= nCol1; ++nCol ) - { - ScPostIt* pNote = pNotes->findByAddress(nCol, nRow); - if ( pNote && pDoc->IsBlockEditable( nRangeTab, nCol,nRow, nCol,nRow ) ) - { - ScAddress aPos( nCol, nRow, nRangeTab ); - pData->GetDocShell()->GetDocFunc().ShowNote( aPos, bShowNote ); - bDone = true; - } - } - } - } - else - { - // Check by each document note - for (ScNotes::const_iterator itr = pNotes->begin(); itr != pNotes->end(); ++itr) - { - SCCOL nCol = itr->first.first; - SCROW nRow = itr->first.second; - - if ( nCol <= nCol1 && nRow <= nRow1 && nCol >= nCol0 && nRow >= nRow0 ) + if ( pDoc->HasNote(nCol, nRow, nRangeTab) && pDoc->IsBlockEditable( nRangeTab, nCol,nRow, nCol,nRow ) ) { ScAddress aPos( nCol, nRow, nRangeTab ); pData->GetDocShell()->GetDocFunc().ShowNote( aPos, bShowNote ); diff --git a/sc/source/ui/view/drawview.cxx b/sc/source/ui/view/drawview.cxx index 5300a096121a..18cd6fec9e38 100644 --- a/sc/source/ui/view/drawview.cxx +++ b/sc/source/ui/view/drawview.cxx @@ -749,7 +749,7 @@ void ScDrawView::DeleteMarked() bool bUndo = pDrawLayer && pDocShell && pUndoMgr && pDoc->IsUndoEnabled(); // remove the cell note from document, we are its owner now - ScPostIt* pNote = pDoc->GetNotes(pCaptData->maStart.Tab())->ReleaseNote( pCaptData->maStart ); + ScPostIt* pNote = pDoc->ReleaseNote( pCaptData->maStart ); OSL_ENSURE( pNote, "ScDrawView::DeleteMarked - cell note missing in document" ); if( pNote ) { diff --git a/sc/source/ui/view/gridwin.cxx b/sc/source/ui/view/gridwin.cxx index f70b838b22ff..beef8046b8dd 100644 --- a/sc/source/ui/view/gridwin.cxx +++ b/sc/source/ui/view/gridwin.cxx @@ -384,7 +384,7 @@ static void lcl_UnLockComment( ScDrawView* pView, SdrPageView* pPV, SdrModel* pD ScDocument& rDoc = *pViewData->GetDocument(); ScAddress aCellPos( pViewData->GetCurX(), pViewData->GetCurY(), pViewData->GetTabNo() ); - ScPostIt* pNote = rDoc.GetNotes( aCellPos.Tab() )->findByAddress( aCellPos ); + ScPostIt* pNote = rDoc.GetNote( aCellPos ); SdrObject* pObj = pNote ? pNote->GetCaption() : 0; if( pObj && pObj->GetLogicRect().IsInside( rPos ) && ScDrawLayer::IsNoteCaption( pObj ) ) { diff --git a/sc/source/ui/view/gridwin5.cxx b/sc/source/ui/view/gridwin5.cxx index fc08d7e4ef13..41328c1007bb 100644 --- a/sc/source/ui/view/gridwin5.cxx +++ b/sc/source/ui/view/gridwin5.cxx @@ -163,7 +163,7 @@ bool ScGridWindow::ShowNoteMarker( SCsCOL nPosX, SCsROW nPosY, bool bKeyboard ) } // Notiz nur, wenn sie nicht schon auf dem Drawing-Layer angezeigt wird: - const ScPostIt* pNote = pDoc->GetNotes( aCellPos.Tab() )->findByAddress( aCellPos ); + const ScPostIt* pNote = pDoc->GetNote( aCellPos ); if ( (!aTrackText.isEmpty()) || (pNote && !pNote->IsCaptionShown()) ) { bool bNew = true; diff --git a/sc/source/ui/view/output.cxx b/sc/source/ui/view/output.cxx index 58673afd7eb7..089d4d8c07fb 100644 --- a/sc/source/ui/view/output.cxx +++ b/sc/source/ui/view/output.cxx @@ -2356,7 +2356,7 @@ void ScOutputData::DrawNoteMarks() // use origin's pCell for NotePtr test below } - if ( mpDoc->GetNotes(nTab)->findByAddress(nX, pRowInfo[nArrY].nRowNo) && ( bIsMerged || + if ( mpDoc->GetNote(nX, pRowInfo[nArrY].nRowNo, nTab) && ( bIsMerged || ( !pInfo->bHOverlapped && !pInfo->bVOverlapped ) ) ) { if (bFirst) @@ -2432,7 +2432,7 @@ void ScOutputData::AddPDFNotes() // use origin's pCell for NotePtr test below } - if ( mpDoc->GetNotes(nTab)->findByAddress(nMergeX, nMergeY) && ( bIsMerged || + if ( mpDoc->GetNote(nMergeX, nMergeY, nTab) && ( bIsMerged || ( !pInfo->bHOverlapped && !pInfo->bVOverlapped ) ) ) { long nNoteWidth = (long)( SC_CLIPMARK_SIZE * mnPPTX ); @@ -2452,7 +2452,7 @@ void ScOutputData::AddPDFNotes() if ( bLayoutRTL ? ( nMarkX >= 0 ) : ( nMarkX < nScrX+nScrW ) ) { Rectangle aNoteRect( nMarkX, nPosY, nMarkX+nNoteWidth*nLayoutSign, nPosY+nNoteHeight ); - const ScPostIt* pNote = mpDoc->GetNotes(nTab)->findByAddress(nMergeX, nMergeY); + const ScPostIt* pNote = mpDoc->GetNote(nMergeX, nMergeY, nTab); // Note title is the cell address (as on printed note pages) ScAddress aAddress( nMergeX, nMergeY, nTab ); diff --git a/sc/source/ui/view/printfun.cxx b/sc/source/ui/view/printfun.cxx index 814a6ceb6cbe..6584bb83dbc3 100644 --- a/sc/source/ui/view/printfun.cxx +++ b/sc/source/ui/view/printfun.cxx @@ -1863,7 +1863,7 @@ long ScPrintFunc::DoNotes( long nNoteStart, sal_Bool bDoPrint, ScPreviewLocation { ScAddress &rPos = aNotePosList[ nNoteStart + nCount ]; - if( const ScPostIt* pNote = pDoc->GetNotes(rPos.Tab())->findByAddress( rPos ) ) + if( const ScPostIt* pNote = pDoc->GetNote( rPos ) ) { if(const EditTextObject *pEditText = pNote->GetEditTextObject()) pEditEngine->SetText(*pEditText); @@ -2465,8 +2465,6 @@ long ScPrintFunc::CountNotePages() if ( !aTableParam.bNotes || !bPrintCurrentTable ) return 0; - long nCount=0; - sal_Bool bError = false; if (!aAreaParam.bPrintArea) bError = !AdjustPrintArea(sal_True); // completely search in Doc @@ -2495,20 +2493,16 @@ long ScPrintFunc::CountNotePages() if (bDoThis) { - ScNotes::const_iterator itr = pDoc->GetNotes(nPrintTab)->begin(); - ScNotes::const_iterator itrEnd = pDoc->GetNotes(nPrintTab)->end(); - for (; itr != itrEnd; ++itr) + for ( SCCOL nCol = nStartCol; nCol <= nEndCol; ++nCol ) { - SCCOL nCol = itr->first.first; - SCROW nRow = itr->first.second; - if (nCol > nEndCol || nRow > nEndRow) - continue; - - if (nCol < nStartCol || nRow < nStartRow) - continue; - - aNotePosList.push_back( ScAddress( nCol, nRow, nPrintTab ) ); - ++nCount; + if (pDoc->HasColNotes(nCol, nPrintTab)) + { + for ( SCROW nRow = nStartRow; nRow <= nEndRow; ++nRow ) + { + if ( pDoc->HasNote(nCol, nRow, nPrintTab) ) + aNotePosList.push_back( ScAddress( nCol, nRow, nPrintTab ) ); + } + } } } } diff --git a/sc/source/ui/view/viewfun6.cxx b/sc/source/ui/view/viewfun6.cxx index 16fa92c04645..9c25516c94eb 100644 --- a/sc/source/ui/view/viewfun6.cxx +++ b/sc/source/ui/view/viewfun6.cxx @@ -292,7 +292,7 @@ void ScViewFunc::EditNote() // generated undo action is processed in FuText::StopEditMode // get existing note or create a new note (including caption drawing object) - if( ScPostIt* pNote = pDoc->GetNotes(aPos.Tab())->GetOrCreateNote( aPos ) ) + if( ScPostIt* pNote = pDoc->GetOrCreateNote( aPos ) ) { // hide temporary note caption HideNoteMarker(); diff --git a/sc/source/ui/view/viewfunc.cxx b/sc/source/ui/view/viewfunc.cxx index fcf4fec85c6a..ec2abd28caf7 100644 --- a/sc/source/ui/view/viewfunc.cxx +++ b/sc/source/ui/view/viewfunc.cxx @@ -2043,7 +2043,6 @@ void ScViewFunc::SetWidthOrHeight( bool bWidth, SCCOLROW nRangeCnt, SCCOLROW* pR nTab = *itr; const SCCOLROW* pTabRanges = pRanges; - pDoc->InitializeNoteCaptions( nTab ); for (SCCOLROW nRangeNo=0; nRangeNo<nRangeCnt; nRangeNo++) { SCCOLROW nStartNo = *(pTabRanges++); |