diff options
author | Dennis Francis <dennisfrancis.in@gmail.com> | 2015-11-24 01:34:47 +0530 |
---|---|---|
committer | Eike Rathke <erack@redhat.com> | 2016-01-21 20:48:07 +0000 |
commit | 3536fe8f4cdbacf5702e743407f34d918b6f4d38 (patch) | |
tree | 24ae7b9048003baadd5408db08662cbcd8782895 /sc/source/core/data | |
parent | eb3ee586e420ee4e38f9ef8c579e1a37d2dc0c10 (diff) |
tdf#34873 : Show autofilter row count in status bar
Change-Id: I91aa637d654c1f4d828832f2e43ad21f03036ad0
Reviewed-on: https://gerrit.libreoffice.org/20134
Reviewed-by: Eike Rathke <erack@redhat.com>
Tested-by: Eike Rathke <erack@redhat.com>
Diffstat (limited to 'sc/source/core/data')
-rw-r--r-- | sc/source/core/data/documen3.cxx | 40 | ||||
-rw-r--r-- | sc/source/core/data/table1.cxx | 1 | ||||
-rw-r--r-- | sc/source/core/data/table2.cxx | 54 | ||||
-rw-r--r-- | sc/source/core/data/table5.cxx | 31 |
4 files changed, 126 insertions, 0 deletions
diff --git a/sc/source/core/data/documen3.cxx b/sc/source/core/data/documen3.cxx index 48f01cf2c401..5f632d922049 100644 --- a/sc/source/core/data/documen3.cxx +++ b/sc/source/core/data/documen3.cxx @@ -1464,6 +1464,46 @@ bool ScDocument::HasRowHeader( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, return ValidTab(nTab) && maTabs[nTab] && maTabs[nTab]->HasRowHeader( nStartCol, nStartRow, nEndCol, nEndRow ); } +void ScDocument::GetFilterSelCount( SCCOL nCol, SCROW nRow, SCTAB nTab, SCSIZE& nSelected, SCSIZE& nTotal ) +{ + nSelected = 0; + nTotal = 0; + if ( ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab] ) + { + const ScDBData* pDBData = GetDBAtCursor( nCol, nRow, nTab, ScDBDataPortion::AREA ); + if( pDBData && pDBData->HasAutoFilter() ) + { + SCTAB nAreaTab; + SCCOL nStartCol; + SCROW nStartRow; + SCCOL nEndCol; + SCROW nEndRow; + pDBData->GetArea( nAreaTab, nStartCol, nStartRow, nEndCol, nEndRow ); + + if( pDBData->HasHeader() ) + ++nStartRow; + + nTotal = nEndRow - nStartRow + 1; + + ScTable::FilteredRowCountData* pFilteredRowCount = &(maTabs[nTab]->maFilteredRowCount); + // Exact range match, cache hit, early exit + if( ( pFilteredRowCount->nStartRow == nStartRow ) && ( pFilteredRowCount->nEndRow == nEndRow ) && + ( pFilteredRowCount->nCount != SCSIZE_MAX ) ) + { + nSelected = nTotal - pFilteredRowCount->nCount; + return; + } + + // Compute the count + nSelected = CountNonFilteredRows( nStartRow, nEndRow, nTab ); + // and store it in the cache + pFilteredRowCount->nStartRow = nStartRow; + pFilteredRowCount->nEndRow = nEndRow; + pFilteredRowCount->nCount = nTotal - nSelected; + } + } +} + /** * Entries for AutoFilter listbox */ diff --git a/sc/source/core/data/table1.cxx b/sc/source/core/data/table1.cxx index 2bc27053d964..e09018d6d6fa 100644 --- a/sc/source/core/data/table1.cxx +++ b/sc/source/core/data/table1.cxx @@ -245,6 +245,7 @@ ScTable::ScTable( ScDocument* pDoc, SCTAB nNewTab, const OUString& rNewName, mpHiddenRows(new ScFlatBoolRowSegments), mpFilteredCols(new ScFlatBoolColSegments), mpFilteredRows(new ScFlatBoolRowSegments), + maFilteredRowCount(0, MAXROW, SCSIZE_MAX), pOutlineTable( nullptr ), pSheetEvents( nullptr ), nTableAreaX( 0 ), diff --git a/sc/source/core/data/table2.cxx b/sc/source/core/data/table2.cxx index 11c0d58c7bd9..23121cbac275 100644 --- a/sc/source/core/data/table2.cxx +++ b/sc/source/core/data/table2.cxx @@ -171,6 +171,13 @@ void ScTable::InsertRow( SCCOL nStartCol, SCCOL nEndCol, SCROW nStartRow, SCSIZE mpFilteredRows->insertSegment(nStartRow, nSize, true); mpHiddenRows->insertSegment(nStartRow, nSize, true); + if( ( nStartRow <= maFilteredRowCount.nEndRow ) && ( maFilteredRowCount.nCount != SCSIZE_MAX ) ) + { + if( nStartRow < maFilteredRowCount.nStartRow ) + maFilteredRowCount.nStartRow += nSize; + maFilteredRowCount.nEndRow += nSize; + } + if (!maRowManualBreaks.empty()) { // Copy all breaks up to nStartRow (non-inclusive). @@ -217,6 +224,53 @@ void ScTable::DeleteRow( if (pUndoOutline) *pUndoOutline = true; + if( ( maFilteredRowCount.nCount != SCSIZE_MAX ) && ( nStartRow <= maFilteredRowCount.nEndRow ) ) + { + SCROW nEndRow = nStartRow + nSize - 1; + // rows to be deleted has some overlap with autofilter + if( nEndRow >= maFilteredRowCount.nStartRow ) + { + SCROW nStartRowInside = ( nStartRow >= maFilteredRowCount.nStartRow ) ? nStartRow : maFilteredRowCount.nStartRow; + SCROW nEndRowInside = ( nEndRow <= maFilteredRowCount.nEndRow ) ? nEndRow : maFilteredRowCount.nEndRow; + + // All rows inside the autofilter are to be deleted, so set dirty flag. + if( ( nStartRowInside == maFilteredRowCount.nStartRow ) && ( nEndRowInside == maFilteredRowCount.nEndRow ) ) + maFilteredRowCount.nCount = SCSIZE_MAX; + else + { + SCSIZE nChange = 0; + ScFlatBoolRowSegments::RangeData aData; + SCROW nRowItr = nStartRowInside; + while( nRowItr <= nEndRowInside ) + { + if( !mpFilteredRows->getRangeData( nRowItr, aData ) ) + break; + if( aData.mnRow2 > nEndRowInside ) + aData.mnRow2 = nEndRowInside; + + if( aData.mbValue ) + nChange += aData.mnRow2 - nRowItr + 1; + + nRowItr = aData.mnRow2 + 1; + } + if( nStartRowInside == maFilteredRowCount.nStartRow ) + maFilteredRowCount.nStartRow = ( nEndRowInside + 1 - nSize ); + + if( nEndRowInside == maFilteredRowCount.nEndRow ) + maFilteredRowCount.nEndRow = ( nStartRowInside - 1 ); + else + maFilteredRowCount.nEndRow -= nSize; + maFilteredRowCount.nCount -= nChange; + } + } + // No overlap but the rows to be deleted are above the autofilter area. + else + { + maFilteredRowCount.nStartRow -= nSize; + maFilteredRowCount.nEndRow -= nSize; + } + } + mpFilteredRows->removeSegment(nStartRow, nStartRow+nSize); mpHiddenRows->removeSegment(nStartRow, nStartRow+nSize); diff --git a/sc/source/core/data/table5.cxx b/sc/source/core/data/table5.cxx index 8ba078cb4e84..f35338353b37 100644 --- a/sc/source/core/data/table5.cxx +++ b/sc/source/core/data/table5.cxx @@ -859,6 +859,37 @@ void ScTable::CopyRowFiltered(ScTable& rTable, SCROW nStartRow, SCROW nEndRow) void ScTable::SetRowFiltered(SCROW nStartRow, SCROW nEndRow, bool bFiltered) { + // First adjust the maFilteredRowCount cache + if( ( nStartRow >= maFilteredRowCount.nStartRow ) || ( nEndRow <= maFilteredRowCount.nEndRow ) ) + { + if( ( nStartRow >= maFilteredRowCount.nStartRow ) && ( nEndRow <= maFilteredRowCount.nEndRow ) && + ( maFilteredRowCount.nCount != SCSIZE_MAX ) ) + { + SCSIZE nChange = 0; + ScFlatBoolRowSegments::RangeData aData; + SCROW nRowItr = nStartRow; + while( nRowItr <= nEndRow ) + { + if( !mpFilteredRows->getRangeData( nRowItr, aData ) ) + break; + if( aData.mnRow2 > nEndRow ) + aData.mnRow2 = nEndRow; + // rows not filtered and going to be filtered + if( bFiltered && !aData.mbValue ) + nChange += aData.mnRow2 - nRowItr + 1; + // rows filtered and not going to be filtered any more + else if( !bFiltered && aData.mbValue ) + nChange -= aData.mnRow2 - nRowItr + 1; + + nRowItr = aData.mnRow2 + 1; + } + + maFilteredRowCount.nCount += nChange; + } + else + maFilteredRowCount.nCount = SCSIZE_MAX; + } + if (bFiltered) mpFilteredRows->setTrue(nStartRow, nEndRow); else |