From 6aec5d5a3a26bd973e46b6c593373e2f03f51a37 Mon Sep 17 00:00:00 2001 From: Noel Grandin Date: Sun, 16 May 2021 13:16:52 +0200 Subject: small perf improvement in checking for note Change-Id: Ib92e04da47d910662eb765c9c68b561647570ecd Reviewed-on: https://gerrit.libreoffice.org/c/core/+/115673 Tested-by: Jenkins Reviewed-by: Noel Grandin --- sc/inc/column.hxx | 1 + sc/inc/document.hxx | 1 + sc/source/core/data/column4.cxx | 32 ++++++++++++++++++++++++++++++++ sc/source/core/data/document.cxx | 14 ++++++++++++++ sc/source/ui/docshell/docfunc.cxx | 6 +----- 5 files changed, 49 insertions(+), 5 deletions(-) (limited to 'sc') diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx index 197dc17d4134..58374fe37d28 100644 --- a/sc/inc/column.hxx +++ b/sc/inc/column.hxx @@ -621,6 +621,7 @@ public: ScPostIt* GetCellNote( sc::ColumnBlockConstPosition& rBlockPos, SCROW nRow ); const ScPostIt* GetCellNote( sc::ColumnBlockConstPosition& rBlockPos, SCROW nRow ) const; void DeleteCellNotes( sc::ColumnBlockPosition& rBlockPos, SCROW nRow1, SCROW nRow2, bool bForgetCaptionOwnership ); + bool HasCellNote(SCROW nStartRow, SCROW nEndRow) const; bool HasCellNotes() const; void SetCellNote( SCROW nRow, std::unique_ptr pNote); bool IsNotesEmptyBlock(SCROW nStartRow, SCROW nEndRow) const; diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx index e129897941a2..a40324f63cd2 100644 --- a/sc/inc/document.hxx +++ b/sc/inc/document.hxx @@ -1234,6 +1234,7 @@ public: void SetNote(SCCOL nCol, SCROW nRow, SCTAB nTab, std::unique_ptr pNote); SC_DLLPUBLIC bool HasNote(const ScAddress& rPos) const; bool HasNote(SCCOL nCol, SCROW nRow, SCTAB nTab) const; + bool HasNote(SCTAB nTab, SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow) const; SC_DLLPUBLIC bool HasColNotes(SCCOL nCol, SCTAB nTab) const; SC_DLLPUBLIC bool HasTabNotes(SCTAB nTab) const; bool HasNotes() const; diff --git a/sc/source/core/data/column4.cxx b/sc/source/core/data/column4.cxx index 827b9d76831b..54213f2cd582 100644 --- a/sc/source/core/data/column4.cxx +++ b/sc/source/core/data/column4.cxx @@ -767,6 +767,38 @@ void ScColumn::GetNotesInRange(SCROW nStartRow, SCROW nEndRow, std::for_each(it, ++itEnd, NoteEntryCollector(rNotes, nTab, nCol, nStartRow, nEndRow)); } +bool ScColumn::HasCellNote(SCROW nStartRow, SCROW nEndRow) const +{ + std::pair aStartPos = + maCellNotes.position(nStartRow); + if (aStartPos.first == maCellNotes.end()) + // Invalid row number. + return false; + + std::pair aEndPos = + maCellNotes.position(nEndRow); + + for (sc::CellNoteStoreType::const_iterator it = aStartPos.first; it != aEndPos.first; ++it) + { + if (it->type != sc::element_type_cellnote) + continue; + size_t nTopRow = it->position; + sc::cellnote_block::const_iterator blockIt = sc::cellnote_block::begin(*(it->data)); + sc::cellnote_block::const_iterator blockItEnd = sc::cellnote_block::end(*(it->data)); + size_t nOffset = 0; + if(nTopRow < o3tl::make_unsigned(nStartRow)) + { + std::advance(blockIt, nStartRow - nTopRow); + nOffset = nStartRow - nTopRow; + } + + if (blockIt != blockItEnd && nTopRow + nOffset <= o3tl::make_unsigned(nEndRow)) + return true; + } + + return false; +} + void ScColumn::GetUnprotectedCells( SCROW nStartRow, SCROW nEndRow, ScRangeList& rRangeList ) const { SCROW nTmpStartRow = nStartRow, nTmpEndRow = nEndRow; diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx index a0690931540c..29ce6fa3c77a 100644 --- a/sc/source/core/data/document.cxx +++ b/sc/source/core/data/document.cxx @@ -6596,6 +6596,20 @@ bool ScDocument::HasNote(SCCOL nCol, SCROW nRow, SCTAB nTab) const return pNote != nullptr; } +bool ScDocument::HasNote(SCTAB nTab, SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow) const +{ + const ScTable* pTab = FetchTable(nTab); + if (!pTab) + return false; + + nStartCol = pTab->ClampToAllocatedColumns(nStartCol); + nEndCol = pTab->ClampToAllocatedColumns(nEndCol); + for (SCCOL nCol = nStartCol; nCol < nEndCol; ++nCol) + if (pTab->aCol[nCol].HasCellNote(nStartRow, nEndRow)) + return true; + return false; +} + bool ScDocument::HasColNotes(SCCOL nCol, SCTAB nTab) const { if (!ValidCol(nCol)) diff --git a/sc/source/ui/docshell/docfunc.cxx b/sc/source/ui/docshell/docfunc.cxx index 3a26bffadfa6..f98350f0963c 100644 --- a/sc/source/ui/docshell/docfunc.cxx +++ b/sc/source/ui/docshell/docfunc.cxx @@ -4977,11 +4977,7 @@ bool ScDocFunc::MergeCells( const ScCellMergeOption& rOption, bool bContents, bo if (bRecord) { // test if the range contains other notes which also implies that we need an undo document - 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)) && (rDoc.HasNote(aPos)); - + bool bHasNotes = rDoc.HasNote(nTab, nStartCol, nStartRow, nEndCol, nEndRow); if (!pUndoDoc) { pUndoDoc.reset(new ScDocument( SCDOCMODE_UNDO )); -- cgit v1.2.3