summaryrefslogtreecommitdiff
path: root/sc/source/core/data
diff options
context:
space:
mode:
authorDennis Francis <dennisfrancis.in@gmail.com>2015-11-24 01:34:47 +0530
committerEike Rathke <erack@redhat.com>2016-01-21 20:48:07 +0000
commit3536fe8f4cdbacf5702e743407f34d918b6f4d38 (patch)
tree24ae7b9048003baadd5408db08662cbcd8782895 /sc/source/core/data
parenteb3ee586e420ee4e38f9ef8c579e1a37d2dc0c10 (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.cxx40
-rw-r--r--sc/source/core/data/table1.cxx1
-rw-r--r--sc/source/core/data/table2.cxx54
-rw-r--r--sc/source/core/data/table5.cxx31
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