[ooo-build-commit] patches/test

Kohei Yoshida kohei at kemper.freedesktop.org
Fri May 29 23:35:34 PDT 2009


 patches/test/calc-perf-table-hidden-flags.diff | 1015 +++++++++++++++++++++----
 1 file changed, 889 insertions(+), 126 deletions(-)

New commits:
commit d48aabe60e166e2dede678d4931772700990db09
Author: Kohei Yoshida <kyoshida at novell.com>
Date:   Sat May 30 02:33:47 2009 -0400

    Refactored filtered row (and column) flag storage.
    
    * patches/test/calc-perf-table-hidden-flags.diff:

diff --git a/patches/test/calc-perf-table-hidden-flags.diff b/patches/test/calc-perf-table-hidden-flags.diff
index 2d06c15..0252532 100644
--- a/patches/test/calc-perf-table-hidden-flags.diff
+++ b/patches/test/calc-perf-table-hidden-flags.diff
@@ -16,10 +16,10 @@ index 0f9586e..e5901fd 100644
  
  	void		CopyToColumn(SCROW nRow1, SCROW nRow2, USHORT nFlags, BOOL bMarked,
 diff --git sc/inc/document.hxx sc/inc/document.hxx
-index b016e1e..f50be06 100644
+index b016e1e..e5609ed 100644
 --- sc/inc/document.hxx
 +++ sc/inc/document.hxx
-@@ -433,9 +433,6 @@ private:
+@@ -433,17 +433,11 @@ private:
  	// for worksheet calculate event
  	::std::vector< SCTAB > maTabs;
  
@@ -29,15 +29,15 @@ index b016e1e..f50be06 100644
  public:
  	SC_DLLPUBLIC ULONG			GetCellCount() const;		// alle Zellen
  	ULONG			GetWeightedCount() const;	// Formeln und Edit staerker gewichtet
-@@ -443,7 +440,6 @@ public:
+ 	ULONG			GetCodeCount() const;		// RPN-Code in Formeln
  	DECL_LINK( GetUserDefinedColor, USHORT * );
-     BOOL        RowFiltered( SCROW nRow, SCTAB nTab ) const;    // FillInfo
-     BOOL        ColFiltered( SCCOL nCol, SCTAB nTab ) const;    // FillInfo
+-    BOOL        RowFiltered( SCROW nRow, SCTAB nTab ) const;    // FillInfo
+-    BOOL        ColFiltered( SCCOL nCol, SCTAB nTab ) const;    // FillInfo
 -																// Numberformatter
  
  public:
  	SC_DLLPUBLIC 				ScDocument( ScDocumentMode eMode = SCDOCMODE_DOCUMENT,
-@@ -1261,7 +1257,6 @@ public:
+@@ -1261,7 +1255,6 @@ public:
                          SCTAB nTab, double fScale ) const;
      SC_DLLPUBLIC inline USHORT	FastGetRowHeight( SCROW nRow, SCTAB nTab ) const;
      inline SCROW	FastGetRowForHeight( SCTAB nTab, ULONG nHeight ) const;
@@ -45,7 +45,7 @@ index b016e1e..f50be06 100644
                      /** No check for flags whether row is hidden, height value
                          is returned unconditionally. */
      inline USHORT   FastGetOriginalRowHeight( SCROW nRow, SCTAB nTab ) const;
-@@ -1312,6 +1307,17 @@ public:
+@@ -1312,6 +1305,26 @@ public:
      ::com::sun::star::uno::Sequence<
          ::com::sun::star::sheet::TablePageBreakData> GetRowBreakData(SCTAB nTab) const;
  
@@ -60,10 +60,28 @@ index b016e1e..f50be06 100644
 +    SC_DLLPUBLIC SCROW          LastVisibleRow(SCROW nStartRow, SCROW nEndRow, SCTAB nTab);
 +    SCROW                       CountVisibleRows(SCROW nStartRow, SCROW nEndRow, SCTAB nTab);
 +
++    bool                        RowFiltered(SCROW nRow, SCTAB nTab, SCROW* pFirstRow = NULL, SCROW* pLastRow = NULL);
++    bool                        HasFilteredRows(SCROW nStartRow, SCROW nEndRow, SCTAB nTab);
++    bool                        ColFiltered(SCCOL nCol, SCTAB nTab, SCCOL* pFirstCol = NULL, SCCOL* pLastCol = NULL);
++    SC_DLLPUBLIC void           SetRowFiltered(SCROW nStartRow, SCROW nEndRow, SCTAB nTab, bool bFiltered);
++    SC_DLLPUBLIC void           SetColFiltered(SCCOL nStartCol, SCCOL nEndCol, SCTAB nTab, bool bFiltered);
++    SCROW                       FirstNonFilteredRow(SCROW nStartRow, SCROW nEndRow, SCTAB nTab);
++    SCROW                       LastNonFilteredRow(SCROW nStartRow, SCROW nEndRow, SCTAB nTab);
++    SCROW                       CountNonFilteredRows(SCROW nStartRow, SCROW nEndRow, SCTAB nTab);
++
      /** 
       * Write all column row flags to table's flag data, because not all column 
       * row attributes are stored in the flag data members.  This is necessary 
-@@ -1806,42 +1812,18 @@ inline void ScDocument::SetSortParam( ScSortParam& rParam, SCTAB nTab )
+@@ -1340,8 +1353,6 @@ public:
+ 	BOOL			GetColDefault( SCTAB nTab, SCCOL nCol, SCROW nLastRow, SCROW& nDefault);
+ 	BOOL			GetRowDefault( SCTAB nTab, SCROW nRow, SCCOL nLastCol, SCCOL& nDefault);
+ 
+-	BOOL			IsFiltered( SCROW nRow, SCTAB nTab ) const;
+-
+ 	BOOL			UpdateOutlineCol( SCCOL nStartCol, SCCOL nEndCol, SCTAB nTab, BOOL bShow );
+ 	BOOL			UpdateOutlineRow( SCROW nStartRow, SCROW nEndRow, SCTAB nTab, BOOL bShow );
+ 
+@@ -1806,58 +1817,24 @@ inline void ScDocument::SetSortParam( ScSortParam& rParam, SCTAB nTab )
  inline ULONG ScDocument::FastGetScaledRowHeight( SCROW nStartRow, SCROW nEndRow,
          SCTAB nTab, double fScale ) const
  {
@@ -110,6 +128,22 @@ index b016e1e..f50be06 100644
  }
  
  inline USHORT ScDocument::FastGetOriginalRowHeight( SCROW nRow, SCTAB nTab ) const
+ {
+     return pTab[nTab]->pRowHeight->GetValue(nRow);
+ }
+-
+-inline BOOL ScDocument::ColFiltered( SCCOL nCol, SCTAB nTab ) const
+-{
+-    return ( pTab[nTab]->pColFlags[nCol] & CR_FILTERED) != 0;
+-}
+-
+-inline BOOL ScDocument::RowFiltered( SCROW nRow, SCTAB nTab ) const
+-{
+-    return pTab[nTab]->IsFiltered(nRow);
+-}
+  
+ #endif
+ 
 diff --git sc/inc/olinetab.hxx sc/inc/olinetab.hxx
 index 592bec1..bba62f5 100644
 --- sc/inc/olinetab.hxx
@@ -185,7 +219,7 @@ index c9a07af..f414002 100644
  
  
 diff --git sc/inc/table.hxx sc/inc/table.hxx
-index a3fc5c9..355710a 100644
+index a3fc5c9..6982c2f 100644
 --- sc/inc/table.hxx
 +++ sc/inc/table.hxx
 @@ -84,6 +84,7 @@ struct ScFunctionData;
@@ -196,15 +230,18 @@ index a3fc5c9..355710a 100644
  
  
  class ScTable
-@@ -123,6 +124,7 @@ private:
+@@ -123,7 +124,10 @@ private:
  
  	BYTE*			pColFlags;
  	ScBitMaskCompressedArray< SCROW, BYTE>*     pRowFlags;
 +    ::boost::shared_ptr<ScFlatBoolColSegments>  mpHiddenCols;
      ::boost::shared_ptr<ScFlatBoolRowSegments>  mpHiddenRows;
++    ::boost::shared_ptr<ScFlatBoolColSegments>  mpFilteredCols;
++    ::boost::shared_ptr<ScFlatBoolRowSegments>  mpFilteredRows;
  
      ::std::set<SCROW>                      maRowPageBreaks;
-@@ -450,7 +452,7 @@ public:
+     ::std::set<SCROW>                      maRowManualBreaks;
+@@ -450,7 +454,7 @@ public:
  								SCCOL& rCol, SCROW& rRow, ScMarkData& rMark,
  								String& rUndoStr, ScDocument* pUndoDoc);
  
@@ -213,7 +250,7 @@ index a3fc5c9..355710a 100644
  
  	void		GetBorderLines( SCCOL nCol, SCROW nRow,
  								const SvxBorderLine** ppLeft, const SvxBorderLine** ppTop,
-@@ -565,19 +567,29 @@ public:
+@@ -565,19 +569,29 @@ public:
  						// nPPT fuer Test auf Veraenderung
  	void		SetManualHeight( SCROW nStartRow, SCROW nEndRow, BOOL bManual );
  
@@ -251,7 +288,16 @@ index a3fc5c9..355710a 100644
  
  	void		ShowCol(SCCOL nCol, BOOL bShow);
  	void		ShowRow(SCROW nRow, BOOL bShow);
-@@ -628,6 +640,23 @@ public:
+@@ -598,8 +612,6 @@ public:
+                 /// @return  the index of the last changed row (flags and row height, auto pagebreak is ignored).
+     SCROW      GetLastChangedRow() const;
+ 
+-	BOOL		IsFiltered(SCROW nRow) const;
+-
+ 	BYTE		GetColFlags( SCCOL nCol ) const;
+ 	BYTE		GetRowFlags( SCROW nRow ) const;
+ 
+@@ -628,6 +640,34 @@ public:
      void        SetColBreak(SCCOL nCol, bool bPage, bool bManual);
      ::com::sun::star::uno::Sequence<
          ::com::sun::star::sheet::TablePageBreakData> GetRowBreakData() const;
@@ -272,10 +318,21 @@ index a3fc5c9..355710a 100644
 +
 +    SCCOLROW    LastHiddenColRow(SCCOLROW nPos, bool bCol);
 +
++    bool        RowFiltered(SCROW nRow, SCROW* pFirstRow = NULL, SCROW* pLastRow = NULL);
++    bool        ColFiltered(SCCOL nCol, SCCOL* pFirstCol = NULL, SCCOL* pLastCol = NULL);
++    bool        HasFilteredRows(SCROW nStartRow, SCROW nEndRow);
++    void        CopyColFiltered(ScTable& rTable, SCCOL nStartCol, SCCOL nEndCol);
++    void        CopyRowFiltered(ScTable& rTable, SCROW nStartRow, SCROW nEndRow);
++    void        SetRowFiltered(SCROW nStartRow, SCROW nEndRow, bool bFiltered);
++    void        SetColFiltered(SCCOL nStartCol, SCCOL nEndCol, bool bFiltered);
++    SCROW       FirstNonFilteredRow(SCROW nStartRow, SCROW nEndRow);
++    SCROW       LastNonFilteredRow(SCROW nStartRow, SCROW nEndRow);
++    SCROW       CountNonFilteredRows(SCROW nStartRow, SCROW nEndRow);
++
      void        SyncColRowFlags();
  
  	void		StripHidden( SCCOL& rX1, SCROW& rY1, SCCOL& rX2, SCROW& rY2 );
-@@ -758,7 +787,7 @@ private:
+@@ -758,7 +798,7 @@ private:
  
  	SCSIZE		FillMaxRot( RowInfo* pRowInfo, SCSIZE nArrCount, SCCOL nX1, SCCOL nX2,
  							SCCOL nCol, SCROW nAttrRow1, SCROW nAttrRow2, SCSIZE nArrY,
@@ -334,11 +391,49 @@ index cc8e369..721082e 100644
  			lcl_UpdateSubTotal( rData, pItems[nIndex].pCell );
  		++nIndex;
  	}
+diff --git sc/source/core/data/dociter.cxx sc/source/core/data/dociter.cxx
+index 03ed0a0..e96e77d 100644
+--- sc/source/core/data/dociter.cxx
++++ sc/source/core/data/dociter.cxx
+@@ -334,7 +334,7 @@ BOOL ScValueIterator::GetThis(double& rValue, USHORT& rErr)
+ 		if ( nColRow < pCol->nCount && pCol->pItems[nColRow].nRow <= nEndRow )
+ 		{
+ 			nRow = pCol->pItems[nColRow].nRow + 1;
+-			if ( !bSubTotal || !pDoc->pTab[nTab]->IsFiltered( nRow-1 ) )
++			if ( !bSubTotal || !pDoc->pTab[nTab]->RowFiltered( nRow-1 ) )
+ 			{
+ 				ScBaseCell* pCell = pCol->pItems[nColRow].pCell;
+ 				++nColRow;
+@@ -725,7 +725,7 @@ ScBaseCell* ScCellIterator::GetThis()
+ 		if ( nColRow < pCol->nCount	&& pCol->pItems[nColRow].nRow <= nEndRow )
+ 		{
+ 			nRow = pCol->pItems[nColRow].nRow;
+-			if ( !bSubTotal || !pDoc->pTab[nTab]->IsFiltered( nRow ) )
++			if ( !bSubTotal || !pDoc->pTab[nTab]->RowFiltered( nRow ) )
+ 			{
+ 				ScBaseCell* pCell = pCol->pItems[nColRow].pCell;
+ 
 diff --git sc/source/core/data/documen3.cxx sc/source/core/data/documen3.cxx
-index aa2164e..6ceb1cd 100644
+index aa2164e..d276f25 100644
 --- sc/source/core/data/documen3.cxx
 +++ sc/source/core/data/documen3.cxx
-@@ -1596,46 +1596,43 @@ ScRange ScDocument::GetRange( SCTAB nTab, const Rectangle& rMMRect )
+@@ -1162,15 +1162,6 @@ BOOL ScDocument::SearchAndReplace(const SvxSearchItem& rSearchItem,
+ 	return bFound;
+ }
+ 
+-BOOL ScDocument::IsFiltered( SCROW nRow, SCTAB nTab ) const
+-{
+-	if (VALIDTAB(nTab))
+-		if (pTab[nTab])
+-			return pTab[nTab]->IsFiltered( nRow );
+-	DBG_ERROR("Falsche Tabellennummer");
+-	return 0;
+-}
+-
+ //	Outline anpassen
+ 
+ BOOL ScDocument::UpdateOutlineCol( SCCOL nStartCol, SCCOL nEndCol, SCTAB nTab, BOOL bShow )
+@@ -1596,46 +1587,43 @@ ScRange ScDocument::GetRange( SCTAB nTab, const Rectangle& rMMRect )
  	nTwips = (long) (aPosRect.Top() / HMM_PER_TWIPS);
  
  	SCROW nY1 = 0;
@@ -408,7 +503,7 @@ index aa2164e..6ceb1cd 100644
  
  	return ScRange( nX1,nY1,nTab, nX2,nY2,nTab );
  }
-@@ -1673,24 +1670,33 @@ void lcl_SnapVer( ScTable* pTable, long& rVal, SCROW& rStartRow )
+@@ -1673,24 +1661,33 @@ void lcl_SnapVer( ScTable* pTable, long& rVal, SCROW& rStartRow )
  	SCROW nRow = 0;
  	long nTwips = (long) (rVal / HMM_PER_TWIPS);
  	long nSnap = 0;
@@ -453,7 +548,7 @@ index aa2164e..6ceb1cd 100644
  	rStartRow = nRow;
  }
 diff --git sc/source/core/data/document.cxx sc/source/core/data/document.cxx
-index 98001ef..e29716d 100644
+index 98001ef..201f9e4 100644
 --- sc/source/core/data/document.cxx
 +++ sc/source/core/data/document.cxx
 @@ -100,6 +100,7 @@
@@ -464,7 +559,61 @@ index 98001ef..e29716d 100644
  
  using namespace ::com::sun::star;
  
-@@ -2972,8 +2973,7 @@ ULONG ScDocument::GetRowHeight( SCROW nStartRow, SCROW nEndRow, SCTAB nTab ) con
+@@ -1876,9 +1877,6 @@ void ScDocument::CopyNonFilteredFromClip( SCCOL nCol1, SCROW nRow1,
+ 	while ( nFlagTab < MAXTAB && !ppClipTab[nFlagTab] )
+ 		++nFlagTab;
+ 
+-    const ScBitMaskCompressedArray< SCROW, BYTE> & rSourceFlags =
+-        pCBFCP->pClipDoc->GetRowFlagsArray( nFlagTab);
+-
+ 	SCROW nSourceRow = rClipStartRow;
+ 	SCROW nSourceEnd = 0;
+     if (pCBFCP->pClipDoc->GetClipParam().maRanges.Count())
+@@ -1888,12 +1886,15 @@ void ScDocument::CopyNonFilteredFromClip( SCCOL nCol1, SCROW nRow1,
+ 	while ( nSourceRow <= nSourceEnd && nDestRow <= nRow2 )
+ 	{
+ 		// skip filtered rows
+-        nSourceRow = rSourceFlags.GetFirstForCondition( nSourceRow, nSourceEnd, CR_FILTERED, 0);
++        nSourceRow = pCBFCP->pClipDoc->FirstNonFilteredRow(nSourceRow, nSourceEnd, nFlagTab);
+ 
+ 		if ( nSourceRow <= nSourceEnd )
+ 		{
+ 			// look for more non-filtered rows following
+-			SCROW nFollow = rSourceFlags.GetBitStateEnd( nSourceRow, CR_FILTERED, 0) - nSourceRow;
++            SCROW nLastRow = nSourceRow;
++            pCBFCP->pClipDoc->RowFiltered(nSourceRow, nFlagTab, NULL, &nLastRow);
++            SCROW nFollow = nLastRow - nSourceRow;
++
+             if (nFollow > nSourceEnd - nSourceRow)
+                 nFollow = nSourceEnd - nSourceRow;
+             if (nFollow > nRow2 - nDestRow)
+@@ -2242,8 +2243,7 @@ void ScDocument::GetClipArea(SCCOL& nClipX, SCROW& nClipY, BOOL bIncludeFiltered
+         while ( nCountTab < MAXTAB && !pTab[nCountTab] )
+             ++nCountTab;
+ 
+-        SCROW nResult = GetRowFlagsArray( nCountTab).CountForCondition(
+-                nStartRow, nEndRow, CR_FILTERED, 0);
++        SCROW nResult = CountNonFilteredRows(nStartRow, nEndRow, nCountTab);
+ 
+         if ( nResult > 0 )
+             nClipY = nResult - 1;
+@@ -2282,8 +2282,13 @@ BOOL ScDocument::HasClipFilteredRows()
+     if (!rClipRanges.Count())
+         return false;
+ 
+-    return GetRowFlagsArray( nCountTab).HasCondition( rClipRanges.First()->aStart.Row(),
+-            rClipRanges.First()->aEnd.Row(), CR_FILTERED, CR_FILTERED);
++    for (ScRange* p = rClipRanges.First(); p; p = rClipRanges.Next())
++    {
++        bool bAnswer = pTab[nCountTab]->HasFilteredRows(p->aStart.Row(), p->aEnd.Row());
++        if (bAnswer)
++            return true;
++    }
++    return false;
+ }
+ 
+ 
+@@ -2972,8 +2977,7 @@ ULONG ScDocument::GetRowHeight( SCROW nStartRow, SCROW nEndRow, SCTAB nTab ) con
  ULONG ScDocument::FastGetRowHeight( SCROW nStartRow, SCROW nEndRow,
          SCTAB nTab ) const
  {
@@ -474,7 +623,7 @@ index 98001ef..e29716d 100644
  }
  
  ULONG ScDocument::GetScaledRowHeight( SCROW nStartRow, SCROW nEndRow,
-@@ -3279,6 +3279,98 @@ Sequence<TablePageBreakData> ScDocument::GetRowBreakData(SCTAB nTab) const
+@@ -3279,6 +3283,163 @@ Sequence<TablePageBreakData> ScDocument::GetRowBreakData(SCTAB nTab) const
      return pTab[nTab]->GetRowBreakData();
  }
  
@@ -497,6 +646,7 @@ index 98001ef..e29716d 100644
 +	return pTab[nTab]->RowHidden(nRow, rLastRow);
 +}
 +
++
 +bool ScDocument::HasHiddenRows(SCROW nStartRow, SCROW nEndRow, SCTAB nTab)
 +{
 +    if (!ValidTab(nTab) || !pTab[nTab])
@@ -570,6 +720,70 @@ index 98001ef..e29716d 100644
 +    return pTab[nTab]->CountVisibleRows(nStartRow, nEndRow);
 +}
 +
++bool ScDocument::RowFiltered(SCROW nRow, SCTAB nTab, SCROW* pFirstRow, SCROW* pLastRow)
++{
++    if (!ValidTab(nTab) || !pTab[nTab])
++		return false;
++
++	return pTab[nTab]->RowFiltered(nRow, pFirstRow, pLastRow);
++}
++
++bool ScDocument::HasFilteredRows(SCROW nStartRow, SCROW nEndRow, SCTAB nTab)
++{
++    if (!ValidTab(nTab) || !pTab[nTab])
++		return false;
++
++	return pTab[nTab]->HasFilteredRows(nStartRow, nEndRow);
++}
++
++bool ScDocument::ColFiltered(SCCOL nCol, SCTAB nTab, SCCOL* pFirstCol, SCCOL* pLastCol)
++{
++    if (!ValidTab(nTab) || !pTab[nTab])
++		return false;
++
++	return pTab[nTab]->ColFiltered(nCol, pFirstCol, pLastCol);
++}
++
++void ScDocument::SetRowFiltered(SCROW nStartRow, SCROW nEndRow, SCTAB nTab, bool bFiltered)
++{
++	if (!ValidTab(nTab) || !pTab[nTab])
++		return;
++
++	pTab[nTab]->SetRowFiltered(nStartRow, nEndRow, bFiltered);
++}
++
++void ScDocument::SetColFiltered(SCCOL nStartCol, SCCOL nEndCol, SCTAB nTab, bool bFiltered)
++{
++	if (!ValidTab(nTab) || !pTab[nTab])
++		return;
++
++	pTab[nTab]->SetColFiltered(nStartCol, nEndCol, bFiltered);
++}
++
++SCROW ScDocument::FirstNonFilteredRow(SCROW nStartRow, SCROW nEndRow, SCTAB nTab)
++{
++	if (!ValidTab(nTab) || !pTab[nTab])
++		return ::std::numeric_limits<SCROW>::max();;
++
++    return pTab[nTab]->FirstNonFilteredRow(nStartRow, nEndRow);
++}
++
++SCROW ScDocument::LastNonFilteredRow(SCROW nStartRow, SCROW nEndRow, SCTAB nTab)
++{
++	if (!ValidTab(nTab) || !pTab[nTab])
++		return ::std::numeric_limits<SCROW>::max();;
++
++    return pTab[nTab]->LastNonFilteredRow(nStartRow, nEndRow);
++}
++
++SCROW ScDocument::CountNonFilteredRows(SCROW nStartRow, SCROW nEndRow, SCTAB nTab)
++{
++	if (!ValidTab(nTab) || !pTab[nTab])
++        return 0;
++
++    return pTab[nTab]->CountNonFilteredRows(nStartRow, nEndRow);
++}
++
  void ScDocument::SyncColRowFlags()
  {
      for (SCTAB i = 0; i <= nMaxTableNumber; ++i)
@@ -925,18 +1139,21 @@ index d0b2b98..b534de1 100644
 +    return true;
 +}
 diff --git sc/source/core/data/table1.cxx sc/source/core/data/table1.cxx
-index 9b2c376..dd4f48a 100644
+index 9b2c376..dc612d3 100644
 --- sc/source/core/data/table1.cxx
 +++ sc/source/core/data/table1.cxx
-@@ -140,6 +140,7 @@ ScTable::ScTable( ScDocument* pDoc, SCTAB nNewTab, const String& rNewName,
+@@ -140,7 +140,10 @@ ScTable::ScTable( ScDocument* pDoc, SCTAB nNewTab, const String& rNewName,
  	pRowHeight( NULL ),
  	pColFlags( NULL ),
  	pRowFlags( NULL ),
 +    mpHiddenCols(new ScFlatBoolColSegments),
      mpHiddenRows(new ScFlatBoolRowSegments),
++    mpFilteredCols(new ScFlatBoolColSegments),
++    mpFilteredRows(new ScFlatBoolRowSegments),
  	pOutlineTable( NULL ),
  	bTableAreaValid( FALSE ),
-@@ -885,9 +886,10 @@ BOOL ScTable::ValidNextPos( SCCOL nCol, SCROW nRow, const ScMarkData& rMark,
+ 	bVisible( TRUE ),
+@@ -885,9 +888,10 @@ BOOL ScTable::ValidNextPos( SCCOL nCol, SCROW nRow, const ScMarkData& rMark,
  		//	auf der naechsten Zelle landet, auch wenn die geschuetzt/nicht markiert ist.
  		//!	per Extra-Parameter steuern, nur fuer Cursor-Bewegung ???
  
@@ -949,7 +1166,7 @@ index 9b2c376..dd4f48a 100644
  			return FALSE;
  	}
  
-@@ -914,8 +916,8 @@ void ScTable::GetNextPos( SCCOL& rCol, SCROW& rRow, SCsCOL nMovX, SCsROW nMovY,
+@@ -914,8 +918,8 @@ void ScTable::GetNextPos( SCCOL& rCol, SCROW& rRow, SCsCOL nMovX, SCsROW nMovY,
  	{
  		BOOL bUp = ( nMovY < 0 );
  		nRow = rMark.GetNextMarked( nCol, nRow, bUp );
@@ -960,7 +1177,7 @@ index 9b2c376..dd4f48a 100644
  		{
  			//	#53697# ausgeblendete ueberspringen (s.o.)
  			nRow += nMovY;
-@@ -925,7 +927,7 @@ void ScTable::GetNextPos( SCCOL& rCol, SCROW& rRow, SCsCOL nMovX, SCsROW nMovY,
+@@ -925,7 +929,7 @@ void ScTable::GetNextPos( SCCOL& rCol, SCROW& rRow, SCsCOL nMovX, SCsROW nMovY,
  		while ( nRow < 0 || nRow > MAXROW )
  		{
              nCol = sal::static_int_cast<SCsCOL>( nCol + static_cast<SCsCOL>(nMovY) );
@@ -969,7 +1186,7 @@ index 9b2c376..dd4f48a 100644
                  nCol = sal::static_int_cast<SCsCOL>( nCol + static_cast<SCsCOL>(nMovY) );   //	#53697# skip hidden rows (see above)
  			if (nCol < 0)
  			{
-@@ -944,8 +946,8 @@ void ScTable::GetNextPos( SCCOL& rCol, SCROW& rRow, SCsCOL nMovX, SCsROW nMovY,
+@@ -944,8 +948,8 @@ void ScTable::GetNextPos( SCCOL& rCol, SCROW& rRow, SCsCOL nMovX, SCsROW nMovY,
  			else if (nRow > MAXROW)
  				nRow = 0;
  			nRow = rMark.GetNextMarked( nCol, nRow, bUp );
@@ -980,7 +1197,7 @@ index 9b2c376..dd4f48a 100644
  			{
  				//	#53697# ausgeblendete ueberspringen (s.o.)
  				nRow += nMovY;
-@@ -1342,19 +1344,14 @@ void ScTable::ExtendPrintArea( OutputDevice* pDev,
+@@ -1342,19 +1346,14 @@ void ScTable::ExtendPrintArea( OutputDevice* pDev,
  
  	SCSIZE nIndex;
  	SCCOL nPrintCol = rEndCol;
@@ -1003,10 +1220,10 @@ index 9b2c376..dd4f48a 100644
  				ScBaseCell* pCell = aCol[nDataCol].GetCell(nRow);
  				if (pCell)
 diff --git sc/source/core/data/table2.cxx sc/source/core/data/table2.cxx
-index 637e2b2..dbb9642 100644
+index 637e2b2..2220604 100644
 --- sc/source/core/data/table2.cxx
 +++ sc/source/core/data/table2.cxx
-@@ -353,20 +353,20 @@ void ScTable::CopyToClip(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
+@@ -353,20 +353,21 @@ void ScTable::CopyToClip(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
  		//	copy widths/heights, and only "hidden", "filtered" and "manual" flags
  		//	also for all preceding columns/rows, to have valid positions for drawing objects
  
@@ -1019,20 +1236,22 @@ index 637e2b2..dbb9642 100644
 -			}
 +
 +        pTable->CopyColHidden(*this, 0, nCol2);
++        pTable->CopyColFiltered(*this, 0, nCol2);
  
  		if (pRowFlags && pTable->pRowFlags && pRowHeight && pTable->pRowHeight)
          {
-             pTable->pRowFlags->CopyFromAnded( *pRowFlags, 0, nRow2,
+-            pTable->pRowFlags->CopyFromAnded( *pRowFlags, 0, nRow2,
 -                    (CR_HIDDEN | CR_FILTERED | CR_MANUALSIZE));
-+                    (CR_FILTERED | CR_MANUALSIZE));
++            pTable->pRowFlags->CopyFromAnded( *pRowFlags, 0, nRow2, CR_MANUALSIZE);
              pTable->pRowHeight->CopyFrom( *pRowHeight, 0, nRow2);
          }
  
 +        pTable->CopyRowHidden(*this, 0, nRow2);
++        pTable->CopyRowFiltered(*this, 0, nRow2);
  
  		//	ggf. Formeln durch Werte ersetzen
  
-@@ -646,10 +646,12 @@ void ScTable::CopyToTable(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
+@@ -646,10 +647,12 @@ void ScTable::CopyToTable(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
  			if (nRow1==0 && nRow2==MAXROW && pColWidth && pDestTab->pColWidth)
  				for (SCCOL i=nCol1; i<=nCol2; i++)
  				{
@@ -1046,7 +1265,7 @@ index 637e2b2..dbb9642 100644
  					//!	Aenderungen zusammenfassen?
  					if (bHiddenChange && pCharts)
  						pCharts->SetRangeDirty(ScRange( i, 0, nTab, i, MAXROW, nTab ));
-@@ -671,8 +673,10 @@ void ScTable::CopyToTable(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
+@@ -671,8 +674,10 @@ void ScTable::CopyToTable(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
                      // TODO: might need some performance improvement, block
                      // operations instead of single GetValue()/SetValue() calls.
                      BYTE nThisRowFlags = pRowFlags->GetValue(i);
@@ -1058,7 +1277,7 @@ index 637e2b2..dbb9642 100644
  					//!	Aenderungen zusammenfassen?
  					if (bHiddenChange && pCharts)
  						pCharts->SetRangeDirty(ScRange( 0, i, nTab, MAXCOL, i, nTab ));
-@@ -1262,7 +1266,7 @@ BOOL ScTable::IsBlockEmpty( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
+@@ -1262,7 +1267,7 @@ BOOL ScTable::IsBlockEmpty( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
  
  SCSIZE ScTable::FillMaxRot( RowInfo* pRowInfo, SCSIZE nArrCount, SCCOL nX1, SCCOL nX2,
  							SCCOL nCol, SCROW nAttrRow1, SCROW nAttrRow2, SCSIZE nArrY,
@@ -1067,7 +1286,7 @@ index 637e2b2..dbb9642 100644
  {
  	//	Rueckgabe = neues nArrY
  
-@@ -1295,7 +1299,7 @@ SCSIZE ScTable::FillMaxRot( RowInfo* pRowInfo, SCSIZE nArrCount, SCCOL nX1, SCCO
+@@ -1295,7 +1300,7 @@ SCSIZE ScTable::FillMaxRot( RowInfo* pRowInfo, SCSIZE nArrCount, SCCOL nX1, SCCO
  
  			for ( SCROW nRow = nAttrRow1; nRow <= nAttrRow2; nRow++ )
  			{
@@ -1076,7 +1295,7 @@ index 637e2b2..dbb9642 100644
  				{
  					BOOL bHitOne = TRUE;
  					if ( nCol > nX2+1 )
-@@ -1329,7 +1333,7 @@ SCSIZE ScTable::FillMaxRot( RowInfo* pRowInfo, SCSIZE nArrCount, SCCOL nX1, SCCO
+@@ -1329,7 +1334,7 @@ SCSIZE ScTable::FillMaxRot( RowInfo* pRowInfo, SCSIZE nArrCount, SCCOL nX1, SCCO
  	return nArrY;
  }
  
@@ -1085,7 +1304,7 @@ index 637e2b2..dbb9642 100644
  {
  	if ( !pColWidth || !pRowHeight || !pColFlags || !pRowFlags )
  	{
-@@ -1344,7 +1348,7 @@ void ScTable::FindMaxRotCol( RowInfo* pRowInfo, SCSIZE nArrCount, SCCOL nX1, SCC
+@@ -1344,7 +1349,7 @@ void ScTable::FindMaxRotCol( RowInfo* pRowInfo, SCSIZE nArrCount, SCCOL nX1, SCC
  
  	for (SCCOL nCol=0; nCol<=MAXCOL; nCol++)
  	{
@@ -1094,7 +1313,7 @@ index 637e2b2..dbb9642 100644
  		{
  			SCSIZE nArrY = 0;
  			ScDocAttrIterator aIter( pDocument, nTab, nCol, nY1, nCol, nY2 );
-@@ -2102,13 +2106,13 @@ void ScTable::SetManualHeight( SCROW nStartRow, SCROW nEndRow, BOOL bManual )
+@@ -2102,13 +2107,13 @@ void ScTable::SetManualHeight( SCROW nStartRow, SCROW nEndRow, BOOL bManual )
  }
  
  
@@ -1110,7 +1329,7 @@ index 637e2b2..dbb9642 100644
  			return 0;
  		else
  			return pColWidth[nCol];
-@@ -2129,7 +2133,7 @@ USHORT ScTable::GetOriginalWidth( SCCOL nCol ) const		// immer die eingestellte
+@@ -2129,7 +2134,7 @@ USHORT ScTable::GetOriginalWidth( SCCOL nCol ) const		// immer die eingestellte
  }
  
  
@@ -1119,7 +1338,7 @@ index 637e2b2..dbb9642 100644
  {
  	//	get the width that is used in the largest continuous column range (up to nEndCol)
  
-@@ -2141,24 +2145,24 @@ USHORT ScTable::GetCommonWidth( SCCOL nEndCol ) const
+@@ -2141,24 +2146,24 @@ USHORT ScTable::GetCommonWidth( SCCOL nEndCol ) const
  
  	USHORT nMaxWidth = 0;
  	USHORT nMaxCount = 0;
@@ -1148,7 +1367,7 @@ index 637e2b2..dbb9642 100644
  					++nRangeEnd;
  			}
  
-@@ -2176,13 +2180,13 @@ USHORT ScTable::GetCommonWidth( SCCOL nEndCol ) const
+@@ -2176,13 +2181,13 @@ USHORT ScTable::GetCommonWidth( SCCOL nEndCol ) const
  }
  
  
@@ -1165,7 +1384,7 @@ index 637e2b2..dbb9642 100644
  			return 0;
  		else
  			return pRowHeight->GetValue(nRow);
-@@ -2192,28 +2196,53 @@ USHORT ScTable::GetRowHeight( SCROW nRow ) const
+@@ -2192,28 +2197,53 @@ USHORT ScTable::GetRowHeight( SCROW nRow ) const
  }
  
  
@@ -1227,7 +1446,7 @@ index 637e2b2..dbb9642 100644
  	}
  	else
  		return (ULONG) ((nEndRow - nStartRow + 1) * ScGlobal::nStdRowHeight * fScale);
-@@ -2234,18 +2263,16 @@ USHORT ScTable::GetOriginalHeight( SCROW nRow ) const		// non-0 even if hidden
+@@ -2234,18 +2264,16 @@ USHORT ScTable::GetOriginalHeight( SCROW nRow ) const		// non-0 even if hidden
  //	Spalten-/Zeilen-Flags
  
  
@@ -1255,7 +1474,7 @@ index 637e2b2..dbb9642 100644
  }
  
  
-@@ -2253,9 +2280,9 @@ SCROW ScTable::GetHiddenRowCount( SCROW nRow ) const
+@@ -2253,9 +2281,9 @@ SCROW ScTable::GetHiddenRowCount( SCROW nRow ) const
  
  void ScTable::ShowCol(SCCOL nCol, BOOL bShow)
  {
@@ -1267,7 +1486,7 @@ index 637e2b2..dbb9642 100644
  		if (bWasVis != bShow)
  		{
  			nRecalcLvl++;
-@@ -2268,10 +2295,8 @@ void ScTable::ShowCol(SCCOL nCol, BOOL bShow)
+@@ -2268,10 +2296,8 @@ void ScTable::ShowCol(SCCOL nCol, BOOL bShow)
  					pDrawLayer->WidthChanged( nTab, nCol, -(long) pColWidth[nCol] );
  			}
  
@@ -1280,10 +1499,11 @@ index 637e2b2..dbb9642 100644
  			if( !--nRecalcLvl )
  				SetDrawPageSize();
  
-@@ -2292,7 +2317,7 @@ void ScTable::ShowRow(SCROW nRow, BOOL bShow)
+@@ -2291,8 +2317,7 @@ void ScTable::ShowRow(SCROW nRow, BOOL bShow)
+ {
  	if (VALIDROW(nRow) && pRowFlags)
  	{
-         BYTE nFlags = pRowFlags->GetValue(nRow);
+-        BYTE nFlags = pRowFlags->GetValue(nRow);
 -		BOOL bWasVis = ( nFlags & CR_HIDDEN ) == 0;
 +        bool bWasVis = !RowHidden(nRow);
  		if (bWasVis != bShow)
@@ -1304,44 +1524,43 @@ index 637e2b2..dbb9642 100644
 -                mpHiddenRows->setTrue(nRow, nRow);    
 -				pRowFlags->SetValue( nRow, nFlags | CR_HIDDEN);
 -            }
-+				pRowFlags->SetValue( nRow, nFlags & ~CR_FILTERED);
++                SetRowFiltered(nRow, nRow, false);
 +
  			if( !--nRecalcLvl )
  				SetDrawPageSize();
  
-@@ -2337,7 +2356,7 @@ void ScTable::DBShowRow(SCROW nRow, BOOL bShow)
+@@ -2336,8 +2355,7 @@ void ScTable::DBShowRow(SCROW nRow, BOOL bShow)
+ {
  	if (VALIDROW(nRow) && pRowFlags)
  	{
-         BYTE nFlags = pRowFlags->GetValue(nRow);
+-        BYTE nFlags = pRowFlags->GetValue(nRow);
 -		BOOL bWasVis = ( nFlags & CR_HIDDEN ) == 0;
 +        bool bWasVis = !RowHidden(nRow);
  		nRecalcLvl++;
  		if (bWasVis != bShow)
  		{
-@@ -2352,16 +2371,14 @@ void ScTable::DBShowRow(SCROW nRow, BOOL bShow)
+@@ -2352,16 +2370,10 @@ void ScTable::DBShowRow(SCROW nRow, BOOL bShow)
  		}
  
  		//	Filter-Flag immer setzen, auch wenn Hidden unveraendert
-+
-+        SetRowHidden(nRow, nRow, !bShow);
-+
- 		if (bShow)
+-		if (bShow)
 -        {    
 -            mpHiddenRows->setFalse(nRow, nRow);    
 -			pRowFlags->SetValue( nRow, nFlags & ~(CR_HIDDEN | CR_FILTERED));
 -        }
-+			pRowFlags->SetValue( nRow, nFlags & ~CR_FILTERED);
- 		else
+-		else
 -        {    
 -            mpHiddenRows->setTrue(nRow, nRow);    
 -			pRowFlags->SetValue( nRow, nFlags | (CR_HIDDEN | CR_FILTERED));
 -        }
-+			pRowFlags->SetValue( nRow, nFlags | CR_FILTERED);
++
++        SetRowHidden(nRow, nRow, !bShow);
++        SetRowFiltered(nRow, nRow, !bShow);
 +
  		if( !--nRecalcLvl )
  			SetDrawPageSize();
  
-@@ -2390,12 +2407,11 @@ void ScTable::DBShowRows(SCROW nRow1, SCROW nRow2, BOOL bShow)
+@@ -2390,12 +2402,11 @@ void ScTable::DBShowRows(SCROW nRow1, SCROW nRow2, BOOL bShow)
  	nRecalcLvl++;
  	while (nStartRow <= nRow2)
  	{
@@ -1356,21 +1575,20 @@ index 637e2b2..dbb9642 100644
  		BOOL bChanged = ( bWasVis != bShow );
  		if ( bChanged )
  		{
-@@ -2410,10 +2426,11 @@ void ScTable::DBShowRows(SCROW nRow1, SCROW nRow2, BOOL bShow)
+@@ -2410,10 +2421,8 @@ void ScTable::DBShowRows(SCROW nRow1, SCROW nRow2, BOOL bShow)
  			}
  		}
  
-+        SetRowHidden(nStartRow, nEndRow, !bShow);
- 		if (bShow)
+-		if (bShow)
 -            pRowFlags->AndValue( nStartRow, nEndRow, sal::static_int_cast<BYTE>(~(CR_HIDDEN | CR_FILTERED)) );
-+            pRowFlags->AndValue( nStartRow, nEndRow, sal::static_int_cast<BYTE>(~CR_FILTERED) );
- 		else
+-		else
 -            pRowFlags->OrValue( nStartRow, nEndRow, (CR_HIDDEN | CR_FILTERED));
-+            pRowFlags->OrValue( nStartRow, nEndRow, CR_FILTERED);
++        SetRowHidden(nStartRow, nEndRow, !bShow);
++        SetRowFiltered(nStartRow, nEndRow, !bShow);
  
  		if ( bChanged )
  		{
-@@ -2425,11 +2442,6 @@ void ScTable::DBShowRows(SCROW nRow1, SCROW nRow2, BOOL bShow)
+@@ -2425,11 +2434,6 @@ void ScTable::DBShowRows(SCROW nRow1, SCROW nRow2, BOOL bShow)
  		nStartRow = nEndRow + 1;
  	}
  
@@ -1382,7 +1600,7 @@ index 637e2b2..dbb9642 100644
  	//	#i12341# For Show/Hide rows, the outlines are updated separately from the outside.
  	//	For filtering, the changes aren't visible to the caller, so UpdateOutlineRow has
  	//	to be done here.
-@@ -2447,12 +2459,11 @@ void ScTable::ShowRows(SCROW nRow1, SCROW nRow2, BOOL bShow)
+@@ -2447,12 +2451,11 @@ void ScTable::ShowRows(SCROW nRow1, SCROW nRow2, BOOL bShow)
  	nRecalcLvl++;
  	while (nStartRow <= nRow2)
  	{
@@ -1397,7 +1615,7 @@ index 637e2b2..dbb9642 100644
  		BOOL bChanged = ( bWasVis != bShow );
  		if ( bChanged )
  		{
-@@ -2467,16 +2478,9 @@ void ScTable::ShowRows(SCROW nRow1, SCROW nRow2, BOOL bShow)
+@@ -2467,16 +2470,9 @@ void ScTable::ShowRows(SCROW nRow1, SCROW nRow2, BOOL bShow)
  			}
  		}
  
@@ -1412,11 +1630,28 @@ index 637e2b2..dbb9642 100644
 -            pRowFlags->OrValue( nStartRow, nEndRow, CR_HIDDEN);
 -            mpHiddenRows->setTrue(nStartRow, nEndRow);
 -        }
-+            pRowFlags->AndValue( nStartRow, nEndRow, sal::static_int_cast<BYTE>(~CR_FILTERED) );
++            SetRowFiltered(nStartRow, nEndRow, false);
  
  		if ( bChanged )
  		{
-@@ -2601,7 +2605,7 @@ BOOL ScTable::UpdateOutlineCol( SCCOL nStartCol, SCCOL nEndCol, BOOL bShow )
+@@ -2494,16 +2490,6 @@ void ScTable::ShowRows(SCROW nRow1, SCROW nRow2, BOOL bShow)
+ }
+ 
+ 
+-BOOL ScTable::IsFiltered(SCROW nRow) const
+-{
+-	if (VALIDROW(nRow) && pRowFlags)
+-		return ( pRowFlags->GetValue(nRow) & CR_FILTERED ) != 0;
+-
+-	DBG_ERROR("Falsche Zeilennummer oder keine Flags");
+-	return FALSE;
+-}
+-
+-
+ void ScTable::SetColFlags( SCCOL nCol, BYTE nNewFlags )
+ {
+ 	if (VALIDCOL(nCol) && pColFlags)
+@@ -2601,7 +2587,7 @@ BOOL ScTable::UpdateOutlineCol( SCCOL nStartCol, SCCOL nEndCol, BOOL bShow )
  	if (pOutlineTable && pColFlags)
      {
          ScBitMaskCompressedArray< SCCOLROW, BYTE> aArray( MAXCOL, pColFlags, MAXCOLCOUNT);
@@ -1425,7 +1660,7 @@ index 637e2b2..dbb9642 100644
      }
  	else
  		return FALSE;
-@@ -2611,7 +2615,7 @@ BOOL ScTable::UpdateOutlineCol( SCCOL nStartCol, SCCOL nEndCol, BOOL bShow )
+@@ -2611,7 +2597,7 @@ BOOL ScTable::UpdateOutlineCol( SCCOL nStartCol, SCCOL nEndCol, BOOL bShow )
  BOOL ScTable::UpdateOutlineRow( SCROW nStartRow, SCROW nEndRow, BOOL bShow )
  {
  	if (pOutlineTable && pRowFlags)
@@ -1434,7 +1669,7 @@ index 637e2b2..dbb9642 100644
  	else
  		return FALSE;
  }
-@@ -2619,55 +2623,59 @@ BOOL ScTable::UpdateOutlineRow( SCROW nStartRow, SCROW nEndRow, BOOL bShow )
+@@ -2619,55 +2605,59 @@ BOOL ScTable::UpdateOutlineRow( SCROW nStartRow, SCROW nEndRow, BOOL bShow )
  
  void ScTable::ExtendHidden( SCCOL& rX1, SCROW& rY1, SCCOL& rX2, SCROW& rY2 )
  {
@@ -1530,7 +1765,31 @@ index 637e2b2..dbb9642 100644
  }
  
  
-@@ -2874,7 +2882,7 @@ void ScTable::SetDrawPageSize()
+@@ -2828,16 +2818,16 @@ BOOL ScTable::RefVisible(ScFormulaCell* pCell)
+ 
+ 	if (pCell->HasOneReference(aRef))
+ 	{
+-		if (aRef.aStart.Col()==aRef.aEnd.Col() && aRef.aStart.Tab()==aRef.aEnd.Tab() && pRowFlags)
++		if (aRef.aStart.Col()==aRef.aEnd.Col() && aRef.aStart.Tab()==aRef.aEnd.Tab())
+ 		{
+-            // while ((value & CR_FILTERED) == CR_FILTERED)
+-            // most times will be faster than
+-            // while ((value & CR_FILTERED) == 0)
+-            SCROW nEndRow = pRowFlags->GetBitStateEnd( aRef.aStart.Row(),
+-                    CR_FILTERED, CR_FILTERED);
++            SCROW nEndRow;
++            if (!RowFiltered(aRef.aStart.Row(), NULL, &nEndRow))
++                // row not filtered.
++                nEndRow = ::std::numeric_limits<SCROW>::max();
++
+             if (!ValidRow(nEndRow) || nEndRow < aRef.aEnd.Row())
+                 return TRUE;    // at least partly visible
+-            return FALSE;       // completely unvisible
++            return FALSE;       // completely invisible
+ 		}
+ 	}
+ 
+@@ -2874,7 +2864,7 @@ void ScTable::SetDrawPageSize()
  }
  
  
@@ -1539,7 +1798,7 @@ index 637e2b2..dbb9642 100644
  {
  	ULONG n = 0;
  	if ( pRowFlags && pRowHeight )
-@@ -2884,8 +2892,7 @@ ULONG ScTable::GetRowOffset( SCROW nRow ) const
+@@ -2884,8 +2874,7 @@ ULONG ScTable::GetRowOffset( SCROW nRow ) const
          else if (nRow == 1)
              return GetRowHeight(0);
  
@@ -1549,7 +1808,7 @@ index 637e2b2..dbb9642 100644
  #ifdef DBG_UTIL
          if (n == ::std::numeric_limits<unsigned long>::max())
              DBG_ERRORFILE("ScTable::GetRowOffset: row heights overflow");
-@@ -2898,18 +2905,42 @@ ULONG ScTable::GetRowOffset( SCROW nRow ) const
+@@ -2898,18 +2887,42 @@ ULONG ScTable::GetRowOffset( SCROW nRow ) const
  	return n;
  }
  
@@ -1600,30 +1859,62 @@ index 637e2b2..dbb9642 100644
  	else
  	{
 diff --git sc/source/core/data/table3.cxx sc/source/core/data/table3.cxx
-index 9082beb..d9de9e9 100644
+index 9082beb..59181da 100644
 --- sc/source/core/data/table3.cxx
 +++ sc/source/core/data/table3.cxx
-@@ -604,10 +604,15 @@ void ScTable::SwapRow(SCROW nRow1, SCROW nRow2)
+@@ -600,14 +600,17 @@ void ScTable::SwapRow(SCROW nRow1, SCROW nRow2)
+ 			}
+ 		}
+ 	}
+-	if (bGlobalKeepQuery && pRowFlags)
++	if (bGlobalKeepQuery)
  	{
- 		BYTE nRow1Flags = pRowFlags->GetValue(nRow1);
- 		BYTE nRow2Flags = pRowFlags->GetValue(nRow2);
+-		BYTE nRow1Flags = pRowFlags->GetValue(nRow1);
+-		BYTE nRow2Flags = pRowFlags->GetValue(nRow2);
 -		BYTE nFlags1 = nRow1Flags & ( CR_HIDDEN | CR_FILTERED );
 -		BYTE nFlags2 = nRow2Flags & ( CR_HIDDEN | CR_FILTERED );
 -		pRowFlags->SetValue( nRow1, (nRow1Flags & ~( CR_HIDDEN | CR_FILTERED )) | nFlags2);
 -		pRowFlags->SetValue( nRow2, (nRow2Flags & ~( CR_HIDDEN | CR_FILTERED )) | nFlags1);
-+		BYTE nFlags1 = nRow1Flags & CR_FILTERED;
-+		BYTE nFlags2 = nRow2Flags & CR_FILTERED;
-+		pRowFlags->SetValue( nRow1, (nRow1Flags & ~CR_FILTERED) | nFlags2);
-+		pRowFlags->SetValue( nRow2, (nRow2Flags & ~CR_FILTERED) | nFlags1);
-+
 +        bool bRow1Hidden = RowHidden(nRow1);
 +        bool bRow2Hidden = RowHidden(nRow2);
 +        SetRowHidden(nRow1, nRow1, bRow2Hidden);
 +        SetRowHidden(nRow2, nRow2, bRow1Hidden);
++
++        bool bRow1Filtered = RowFiltered(nRow1);
++        bool bRow2Filtered = RowFiltered(nRow2);
++        SetRowFiltered(nRow1, nRow1, bRow2Filtered);
++        SetRowFiltered(nRow2, nRow2, bRow1Filtered);
  	}
  }
  
-@@ -1998,8 +2003,8 @@ void ScTable::UpdateSelectionFunction( ScFunctionData& rData,
+@@ -988,13 +991,6 @@ BOOL ScTable::DoSubTotals( ScSubTotalParam& rParam )
+ 						SetString( nGroupCol[aRowEntry.nGroupNo], aRowEntry.nDestRow, nTab, aOutString );
+ 						ApplyStyle( nGroupCol[aRowEntry.nGroupNo], aRowEntry.nDestRow, *pStyle );
+ 
+-/*						if (rParam.bPagebreak && nRow < MAXROW)
+-						{
+-							BYTE nFlags = GetRowFlags( nRow+1 );
+-							nFlags |= CR_MANUALBREAK;
+-							SetRowFlags( nRow+1, nFlags );
+-						}
+-*/
+ 						++nRow;
+ 						++nEndRow;
+ 						aRowEntry.nSubStartRow = nRow;
+@@ -1008,11 +1004,7 @@ BOOL ScTable::DoSubTotals( ScSubTotalParam& rParam )
+ 						}
+ 					}
+ 				}
+-				if (!pRowFlags)
+-					bBlockVis = TRUE;
+-				else
+-					if ( (pRowFlags->GetValue(nRow) & CR_FILTERED) == 0 )
+-						bBlockVis = TRUE;
++                bBlockVis = !RowFiltered(nRow);
+ 			}
+ 		}
+ 		else
+@@ -1998,8 +1990,8 @@ void ScTable::UpdateSelectionFunction( ScFunctionData& rData,
  	SCCOL nCol;
  	if ( rMark.IsMultiMarked() )
  		for (nCol=0; nCol<=MAXCOL && !rData.bError; nCol++)
@@ -1634,7 +1925,7 @@ index 9082beb..d9de9e9 100644
  													bSingle && ( nCol >= nStartCol && nCol <= nEndCol ),
  													nStartRow, nEndRow );
  
-@@ -2007,8 +2012,8 @@ void ScTable::UpdateSelectionFunction( ScFunctionData& rData,
+@@ -2007,8 +1999,8 @@ void ScTable::UpdateSelectionFunction( ScFunctionData& rData,
  
  	if ( bSingle && !rMark.IsMarkNegative() )
  		for (nCol=nStartCol; nCol<=nEndCol && !rData.bError; nCol++)
@@ -1646,7 +1937,7 @@ index 9082beb..d9de9e9 100644
  
  void ScTable::FindConditionalFormat( ULONG nKey, ScRangeList& rList )
 diff --git sc/source/core/data/table5.cxx sc/source/core/data/table5.cxx
-index 618fe75..e26a20f 100644
+index 618fe75..bc647e7 100644
 --- sc/source/core/data/table5.cxx
 +++ sc/source/core/data/table5.cxx
 @@ -53,9 +53,11 @@
@@ -1699,10 +1990,11 @@ index 618fe75..e26a20f 100644
  #ifdef DBG_UTIL
              if (nHeights == ::std::numeric_limits<unsigned long>::max())
                  DBG_ERRORFILE("ScTable::UpdatePageBreaks: row heights overflow");
-@@ -416,12 +416,267 @@ Sequence<TablePageBreakData> ScTable::GetRowBreakData() const
+@@ -416,12 +416,516 @@ Sequence<TablePageBreakData> ScTable::GetRowBreakData() const
      return aSeq;
  }
  
+-void ScTable::SyncColRowFlags()
 +bool ScTable::RowHidden(SCROW nRow, SCROW* pFirstRow, SCROW* pLastRow)
 +{
 +    if (!ValidRow(nRow))
@@ -1852,11 +2144,11 @@ index 618fe75..e26a20f 100644
 +    while (nRow <= nEndRow)
 +    {
 +        if (!ValidRow(nRow))
-+            return ::std::numeric_limits<SCROW>::max();
++            break;
 +
 +        if (!mpHiddenRows->getRangeData(nRow, aData))
 +            // failed to get range data.
-+            return ::std::numeric_limits<SCROW>::max();
++            break;
 +
 +        if (!aData.mbValue)
 +            // visible row found
@@ -1875,11 +2167,11 @@ index 618fe75..e26a20f 100644
 +    while (nRow >= nStartRow)
 +    {
 +        if (!ValidRow(nRow))
-+            return ::std::numeric_limits<SCROW>::max();
++            break;
 +
 +        if (!mpHiddenRows->getRangeData(nRow, aData))
 +            // failed to get range data.
-+            return ::std::numeric_limits<SCROW>::max();
++            break;
 +
 +        if (!aData.mbValue)
 +            // visible row found
@@ -1959,25 +2251,215 @@ index 618fe75..e26a20f 100644
 +    return ::std::numeric_limits<SCCOLROW>::max();
 +}
 +
- void ScTable::SyncColRowFlags()
++bool ScTable::RowFiltered(SCROW nRow, SCROW* pFirstRow, SCROW* pLastRow)
++{
++#if 1
++    if (!ValidRow(nRow))
++        return false;
++
++    ScFlatBoolRowSegments::RangeData aData;
++    if (!mpFilteredRows->getRangeData(nRow, aData))
++        // search failed.
++        return false;
++
++    if (pFirstRow)
++        *pFirstRow = aData.mnRow1;
++    if (pLastRow)
++        *pLastRow = aData.mnRow2;
++
++    return aData.mbValue;
++#else
++    if (pFirstRow)
++        *pFirstRow = nRow;
++    if (pLastRow)
++        *pLastRow = nRow;
++    return (pRowFlags->GetValue(nRow) & CR_FILTERED) == CR_FILTERED;
++#endif
++}
++
++bool ScTable::ColFiltered(SCCOL nCol, SCCOL* pFirstCol, SCCOL* pLastCol)
++{
++#if 1
++    if (!ValidCol(nCol))
++        return false;
++
++    ScFlatBoolColSegments::RangeData aData;
++    if (!mpFilteredCols->getRangeData(nCol, aData))
++        // search failed.
++        return false;
++
++    if (pFirstCol)
++        *pFirstCol = aData.mnCol1;
++    if (pLastCol)
++        *pLastCol = aData.mnCol2;
++
++    return aData.mbValue;
++#else
++    if (pFirstCol)
++        *pFirstCol = nCol;
++    if (pLastCol)
++        *pLastCol = nCol;
++    return (pColFlags[nCol] & CR_FILTERED) == CR_FILTERED;
++#endif
++}
++
++bool ScTable::HasFilteredRows(SCROW nStartRow, SCROW nEndRow)
++{
++    SCROW nRow = nStartRow;
++    while (nRow <= nEndRow)
++    {
++        SCROW nLastRow = nRow;
++        bool bFiltered = RowFiltered(nRow, NULL, &nLastRow);
++        if (bFiltered)
++            return true;
++
++        nRow = nLastRow + 1;
++    }
++    return false;
++}
++
++void ScTable::CopyColFiltered(ScTable& rTable, SCCOL nStartCol, SCCOL nEndCol)
++{
++    SCCOL nCol = nStartCol;
++    while (nCol <= nEndCol)
++    {
++        SCCOL nLastCol;
++        bool bFiltered = rTable.ColFiltered(nCol, NULL, &nLastCol);
++        if (nLastCol > nEndCol)
++            nLastCol = nEndCol;
++
++        SetColFiltered(nCol, nLastCol, bFiltered);
++        nCol = nLastCol + 1;
++    }
++}
++
++void ScTable::CopyRowFiltered(ScTable& rTable, SCROW nStartRow, SCROW nEndRow)
++{
++    SCROW nRow = nStartRow;
++    while (nRow <= nEndRow)
++    {
++        SCROW nLastRow = -1;
++        bool bFiltered = rTable.RowFiltered(nRow, NULL, &nLastRow);
++        if (nLastRow > nEndRow)
++            nLastRow = nEndRow;
++        SetRowFiltered(nRow, nLastRow, bFiltered);
++        nRow = nLastRow + 1;
++    }
++}
++
++void ScTable::SetRowFiltered(SCROW nStartRow, SCROW nEndRow, bool bFiltered)
++{
++    if (bFiltered)
++        mpFilteredRows->setTrue(nStartRow, nEndRow);
++    else
++        mpFilteredRows->setFalse(nStartRow, nEndRow);
++
++#if 0
++    // Remove this once the refactoring is complete.
++    if (bFiltered)
++        pRowFlags->OrValue(nStartRow, nEndRow, CR_FILTERED);
++    else
++        pRowFlags->AndValue(nStartRow, nEndRow, ~CR_FILTERED);
++#endif
++}
++
++void ScTable::SetColFiltered(SCCOL nStartCol, SCCOL nEndCol, bool bFiltered)
++{
++    if (bFiltered)
++        mpFilteredCols->setTrue(nStartCol, nEndCol);
++    else
++        mpFilteredCols->setFalse(nStartCol, nEndCol);
++
++#if 0
++    // Remove this once the refactoring is complete.
++    for (SCCOL nCol = nStartCol; nCol <= nEndCol; ++nCol)
++    {
++        if (bFiltered)
++            pColFlags[nCol] |= CR_FILTERED;
++        else
++            pColFlags[nCol] &= ~CR_FILTERED;
++    }
++#endif
++}
++
++SCROW ScTable::FirstNonFilteredRow(SCROW nStartRow, SCROW nEndRow)
++{
++    SCROW nRow = nStartRow;
++    ScFlatBoolRowSegments::RangeData aData;
++    while (nRow <= nEndRow)
++    {
++        if (!ValidRow(nRow))
++            break;
++
++        if (!mpFilteredRows->getRangeData(nRow, aData))
++            // failed to get range data.
++            break;
++
++        if (!aData.mbValue)
++            // non-filtered row found
++            return nRow;
++
++        nRow = aData.mnRow2 + 1;
++    }
++
++    return ::std::numeric_limits<SCROW>::max();
++}
++
++SCROW ScTable::LastNonFilteredRow(SCROW nStartRow, SCROW nEndRow)
++{
++    SCROW nRow = nEndRow;
++    ScFlatBoolRowSegments::RangeData aData;
++    while (nRow >= nStartRow)
++    {
++        if (!ValidRow(nRow))
++            break;
++
++        if (!mpFilteredRows->getRangeData(nRow, aData))
++            // failed to get range data.
++            break;
++
++        if (!aData.mbValue)
++            // non-filtered row found
++            return nRow;
++
++        nRow = aData.mnRow1 - 1;
++    }
++
++    return ::std::numeric_limits<SCROW>::max();
++}
++
++SCROW ScTable::CountNonFilteredRows(SCROW nStartRow, SCROW nEndRow)
++{
++    SCROW nCount = 0;
++    SCROW nRow = nStartRow;
++    ScFlatBoolRowSegments::RangeData aData;
++    while (nRow <= nEndRow)
++    {
++        if (!mpFilteredRows->getRangeData(nRow, aData))
++            break;
++
++        if (aData.mnRow2 > nEndRow)
++            aData.mnRow2 = nEndRow;
++
++        if (!aData.mbValue)
++            nCount += aData.mnRow2 - nRow + 1;
++
++        nRow = aData.mnRow2 + 1;
++    }
++    return nCount;
++}
++
++namespace {
++
++void lcl_syncFlags(ScFlatBoolColSegments& rColSegments, ScFlatBoolRowSegments& rRowSegments,
++    BYTE* pColFlags, ScBitMaskCompressedArray< SCROW, BYTE>* pRowFlags, const BYTE nFlagMask)
  {
      using ::sal::static_int_cast;
  
 -    // For now, we only need to sync the manual breaks.
--
-+    // Manual breaks.
-     pRowFlags->AndValue(0, MAXROW, static_int_cast<BYTE>(~CR_MANUALBREAK));
-     for (SCCOL i = 0; i <= MAXCOL; ++i)
-         pColFlags[i] &= static_int_cast<BYTE>(~CR_MANUALBREAK);
-@@ -439,6 +694,48 @@ void ScTable::SyncColRowFlags()
-               itr != itrEnd; ++itr)
-             pColFlags[*itr] |= CR_MANUALBREAK;
-     }
-+
-+    // Hidden flags.
-+    pRowFlags->AndValue(0, MAXROW, static_int_cast<BYTE>(~CR_HIDDEN));
++    pRowFlags->AndValue(0, MAXROW, static_int_cast<BYTE>(~nFlagMask));
 +    for (SCCOL i = 0; i <= MAXCOL; ++i)
-+        pColFlags[i] &= static_int_cast<BYTE>(~CR_HIDDEN);
++        pColFlags[i] &= static_int_cast<BYTE>(~nFlagMask);
 +
 +    {
 +        // row hidden flags.
@@ -1986,11 +2468,11 @@ index 618fe75..e26a20f 100644
 +        ScFlatBoolRowSegments::RangeData aData;
 +        while (nRow <= MAXROW)
 +        {
-+            if (!mpHiddenRows->getRangeData(nRow, aData))
++            if (!rRowSegments.getRangeData(nRow, aData))
 +                break;
 +
 +            if (aData.mbValue)
-+                pRowFlags->OrValue(nRow, aData.mnRow2, static_int_cast<BYTE>(CR_HIDDEN));
++                pRowFlags->OrValue(nRow, aData.mnRow2, static_int_cast<BYTE>(nFlagMask));
 +
 +            nRow = aData.mnRow2 + 1;
 +        }
@@ -2003,18 +2485,38 @@ index 618fe75..e26a20f 100644
 +        ScFlatBoolColSegments::RangeData aData;
 +        while (nCol <= MAXCOL)
 +        {
-+            if (!mpHiddenCols->getRangeData(nCol, aData))
++            if (!rColSegments.getRangeData(nCol, aData))
 +                break;
 +
 +            if (aData.mbValue)
 +            {
 +                for (SCCOL i = nCol; i <= aData.mnCol2; ++i)
-+                    pColFlags[i] |= CR_HIDDEN;
++                    pColFlags[i] |= nFlagMask;
 +            }
 +
 +            nCol = aData.mnCol2 + 1;
 +        }
 +    }
++}
++
++}
++
++void ScTable::SyncColRowFlags()
++{
++    using ::sal::static_int_cast;
+ 
++    // Manual breaks.
+     pRowFlags->AndValue(0, MAXROW, static_int_cast<BYTE>(~CR_MANUALBREAK));
+     for (SCCOL i = 0; i <= MAXCOL; ++i)
+         pColFlags[i] &= static_int_cast<BYTE>(~CR_MANUALBREAK);
+@@ -439,6 +943,10 @@ void ScTable::SyncColRowFlags()
+               itr != itrEnd; ++itr)
+             pColFlags[*itr] |= CR_MANUALBREAK;
+     }
++
++    // Hidden flags.
++    lcl_syncFlags(*mpHiddenCols, *mpHiddenRows, pColFlags, pRowFlags, CR_HIDDEN);
++    lcl_syncFlags(*mpFilteredCols, *mpFilteredRows, pColFlags, pRowFlags, CR_FILTERED);
  }
  
  void ScTable::SetPageSize( const Size& rSize )
@@ -2179,6 +2681,19 @@ index b6163ba..ed34d0b 100644
  	return pMemChart;
  }
  
+diff --git sc/source/filter/excel/colrowst.cxx sc/source/filter/excel/colrowst.cxx
+index 43df0d2..9c686fe 100644
+--- sc/source/filter/excel/colrowst.cxx
++++ sc/source/filter/excel/colrowst.cxx
+@@ -309,7 +309,7 @@ void XclImpColRowSettings::ConvertHiddenFlags( SCTAB nScTab )
+             rDoc.ShowRow( nScRow, nScTab, FALSE );
+             // #i38093# rows hidden by filter need extra flag
+             if( (nFirstFilterScRow <= nScRow) && (nScRow <= nLastFilterScRow) )
+-                rDoc.SetRowFlags( nScRow, nScTab, rDoc.GetRowFlags( nScRow, nScTab ) | CR_FILTERED );
++                rDoc.SetRowFiltered(nScRow, nScRow, nScTab, true);
+         }
+     }
+ 
 diff --git sc/source/filter/excel/xetable.cxx sc/source/filter/excel/xetable.cxx
 index 8d27d2d..e289bf4 100644
 --- sc/source/filter/excel/xetable.cxx
@@ -2385,6 +2900,19 @@ index 371ef48..1a634d3 100644
                      pDoc->SetRowBreak(l, static_cast<SCTAB> (TabNo), bPageBreak, bManualBreak);
                  }
  			}
+diff --git sc/source/filter/xlsx/xlsx-colrowst.cxx sc/source/filter/xlsx/xlsx-colrowst.cxx
+index 43df0d2..9c686fe 100644
+--- sc/source/filter/xlsx/xlsx-colrowst.cxx
++++ sc/source/filter/xlsx/xlsx-colrowst.cxx
+@@ -309,7 +309,7 @@ void XclImpColRowSettings::ConvertHiddenFlags( SCTAB nScTab )
+             rDoc.ShowRow( nScRow, nScTab, FALSE );
+             // #i38093# rows hidden by filter need extra flag
+             if( (nFirstFilterScRow <= nScRow) && (nScRow <= nLastFilterScRow) )
+-                rDoc.SetRowFlags( nScRow, nScTab, rDoc.GetRowFlags( nScRow, nScTab ) | CR_FILTERED );
++                rDoc.SetRowFiltered(nScRow, nScRow, nScTab, true);
+         }
+     }
+ 
 diff --git sc/source/filter/xlsx/xlsx-xetable.cxx sc/source/filter/xlsx/xlsx-xetable.cxx
 index e8a208d..92dd71e 100644
 --- sc/source/filter/xlsx/xlsx-xetable.cxx
@@ -2442,24 +2970,39 @@ index 2109a0a..a2a64b8 100644
  }
  
 diff --git sc/source/ui/Accessibility/AccessibleCellBase.cxx sc/source/ui/Accessibility/AccessibleCellBase.cxx
-index 320f211..a03f132 100644
+index 320f211..06cc5a2 100644
 --- sc/source/ui/Accessibility/AccessibleCellBase.cxx
 +++ sc/source/ui/Accessibility/AccessibleCellBase.cxx
-@@ -97,8 +97,12 @@ sal_Bool SAL_CALL ScAccessibleCellBase::isVisible(  )
+@@ -95,10 +95,12 @@ sal_Bool SAL_CALL ScAccessibleCellBase::isVisible(  )
+ 	sal_Bool bVisible(sal_True);
+ 	if (mpDoc)
  	{
- 		BYTE nColFlags = mpDoc->GetColFlags(maCellAddress.Col(), maCellAddress.Tab());
- 		BYTE nRowFlags = mpDoc->GetRowFlags(maCellAddress.Row(), maCellAddress.Tab());
+-		BYTE nColFlags = mpDoc->GetColFlags(maCellAddress.Col(), maCellAddress.Tab());
+-		BYTE nRowFlags = mpDoc->GetRowFlags(maCellAddress.Row(), maCellAddress.Tab());
 -		if (((nColFlags & CR_HIDDEN) == CR_HIDDEN) || ((nColFlags & CR_FILTERED) == CR_FILTERED) ||
 -			((nRowFlags & CR_HIDDEN) == CR_HIDDEN) || ((nRowFlags & CR_FILTERED) == CR_FILTERED))
-+        SCCOL nLastCol;
-+        SCROW nLastRow;
-+        bool bColHidden = mpDoc->ColHidden(maCellAddress.Col(), maCellAddress.Tab(), nLastCol);
-+        bool bRowHidden = mpDoc->RowHidden(maCellAddress.Row(), maCellAddress.Tab(), nLastRow);
-+        if (bColHidden || ((nColFlags & CR_FILTERED) == CR_FILTERED) ||
-+            bRowHidden || ((nRowFlags & CR_FILTERED) == CR_FILTERED))
++        bool bColHidden = mpDoc->ColHidden(maCellAddress.Col(), maCellAddress.Tab());
++        bool bRowHidden = mpDoc->RowHidden(maCellAddress.Row(), maCellAddress.Tab());
++        bool bColFiltered = mpDoc->ColFiltered(maCellAddress.Col(), maCellAddress.Tab());
++        bool bRowFiltered = mpDoc->RowFiltered(maCellAddress.Row(), maCellAddress.Tab());
++
++        if (bColHidden || bColFiltered || bRowHidden || bRowFiltered)
  			bVisible = sal_False;
  	}
  	return bVisible;
+diff --git sc/source/ui/app/inputwin.cxx sc/source/ui/app/inputwin.cxx
+index 5273634..2349ed0 100644
+--- sc/source/ui/app/inputwin.cxx
++++ sc/source/ui/app/inputwin.cxx
+@@ -294,7 +294,7 @@ sal_Bool ScInputWindow::UseSubTotal(ScRangeList* pRangeList) const
+                     SCROW nRow(pRange->aStart.Row());
+                     while (!bSubTotal && nRow <= nRowEnd)
+                     {
+-                        if (pDoc->IsFiltered(nRow, nTab))
++                        if (pDoc->RowFiltered(nRow, nTab))
+                             bSubTotal = sal_True;
+                         else
+                             ++nRow;
 diff --git sc/source/ui/app/transobj.cxx sc/source/ui/app/transobj.cxx
 index 1620f95..375f2b9 100644
 --- sc/source/ui/app/transobj.cxx
@@ -2523,6 +3066,86 @@ index 1477025..aa321fe 100644
  				{
  					USHORT nThisSize = nSizeTwips;
  
+diff --git sc/source/ui/docshell/impex.cxx sc/source/ui/docshell/impex.cxx
+index e2ccdf5..1535fdd 100644
+--- sc/source/ui/docshell/impex.cxx
++++ sc/source/ui/docshell/impex.cxx
+@@ -1319,7 +1319,7 @@ BOOL ScImportExport::Doc2Text( SvStream& rStrm )
+ 
+ 	for (nRow = nStartRow; nRow <= nEndRow; nRow++)
+ 	{
+-		if (bIncludeFiltered || !pDoc->IsFiltered( nRow, aRange.aStart.Tab() ))
++		if (bIncludeFiltered || !pDoc->RowFiltered( nRow, aRange.aStart.Tab() ))
+ 		{
+ 			for (nCol = nStartCol; nCol <= nEndCol; nCol++)
+ 			{
+diff --git sc/source/ui/docshell/olinefun.cxx sc/source/ui/docshell/olinefun.cxx
+index 37023e2..53efc8d 100644
+--- sc/source/ui/docshell/olinefun.cxx
++++ sc/source/ui/docshell/olinefun.cxx
+@@ -411,7 +411,7 @@ BOOL ScOutlineDocFunc::SelectLevel( SCTAB nTab, BOOL bColumns, USHORT nLevel,
+ 			if ( bColumns )
+ 				pDoc->ShowCol( static_cast<SCCOL>(i), nTab, bShow );
+ 			else
+-				if ( !bShow || !pDoc->IsFiltered( i,nTab ) )
++				if ( !bShow || !pDoc->RowFiltered( i,nTab ) )
+ 					pDoc->ShowRow( i, nTab, bShow );
+ 		}
+ 	}
+@@ -509,7 +509,7 @@ BOOL ScOutlineDocFunc::ShowMarkedOutlines( const ScRange& rRange, BOOL bRecord,
+ 			}
+ 		}
+ 		for ( i=nMin; i<=nMax; i++ )
+-			if ( !pDoc->IsFiltered( i,nTab ) )				// weggefilterte nicht einblenden
++			if ( !pDoc->RowFiltered( i,nTab ) )				// weggefilterte nicht einblenden
+ 				pDoc->ShowRow( i, nTab, TRUE );
+ 
+ 		pDoc->UpdatePageBreaks( nTab );
+@@ -669,7 +669,7 @@ BOOL ScOutlineDocFunc::ShowOutline( SCTAB nTab, BOOL bColumns, USHORT nLevel, US
+ 		if ( bColumns )
+ 			pDoc->ShowCol( static_cast<SCCOL>(i), nTab, TRUE );
+ 		else
+-			if ( !pDoc->IsFiltered( i,nTab ) )				// weggefilterte nicht einblenden
++			if ( !pDoc->RowFiltered( i,nTab ) )				// weggefilterte nicht einblenden
+ 				pDoc->ShowRow( i, nTab, TRUE );
+ 	}
+ 
+diff --git sc/source/ui/inc/viewutil.hxx sc/source/ui/inc/viewutil.hxx
+index b397ca5..a9cb792 100644
+--- sc/source/ui/inc/viewutil.hxx
++++ sc/source/ui/inc/viewutil.hxx
+@@ -68,10 +68,10 @@ public:
+ 
+ 	static sal_Int32 GetTransliterationType( USHORT nSlotID );
+ 
+-    static bool HasFiltered( const ScRange& rRange, const ScDocument* pDoc );
++    static bool HasFiltered( const ScRange& rRange, ScDocument* pDoc );
+     /** Fit a range to cover nRows number of unfiltered rows.
+         @return <TRUE/> if the resulting range covers nRows unfiltered rows. */
+-    static bool FitToUnfilteredRows( ScRange & rRange, const ScDocument * pDoc, size_t nRows );
++    static bool FitToUnfilteredRows( ScRange & rRange, ScDocument * pDoc, size_t nRows );
+     static void UnmarkFiltered( ScMarkData& rMark, ScDocument* pDoc );
+ 
+     static void HideDisabledSlot( SfxItemSet& rSet, SfxBindings& rBindings, USHORT nSlotId );
+diff --git sc/source/ui/undo/undoblk.cxx sc/source/ui/undo/undoblk.cxx
+index 4f7ddfd..c1447bb 100644
+--- sc/source/ui/undo/undoblk.cxx
++++ sc/source/ui/undo/undoblk.cxx
+@@ -1151,10 +1151,10 @@ ScUndoDragDrop::ScUndoDragDrop( ScDocShell* pNewDocShell,
+ 	BOOL bIncludeFiltered = bCut;
+ 	if ( !bIncludeFiltered )
+ 	{
+-		//	manually find number of non-filtered rows
+-        SCROW nPastedCount = pDocShell->GetDocument()->GetRowFlagsArray(
+-                aSrcRange.aStart.Tab()).CountForCondition(
+-                aSrcRange.aStart.Row(), aSrcRange.aEnd.Row(), CR_FILTERED, 0);
++        // find number of non-filtered rows
++        SCROW nPastedCount = pDocShell->GetDocument()->CountNonFilteredRows(
++            aSrcRange.aStart.Row(), aSrcRange.aEnd.Row(), aSrcRange.aStart.Tab());
++
+ 		if ( nPastedCount == 0 )
+ 			nPastedCount = 1;
+ 		aDestEnd.SetRow( aNewDestPos.Row() + nPastedCount - 1 );
 diff --git sc/source/ui/undo/undoblk3.cxx sc/source/ui/undo/undoblk3.cxx
 index 8d9baaf..753a1a1 100644
 --- sc/source/ui/undo/undoblk3.cxx
@@ -2551,7 +3174,7 @@ index 8d9baaf..753a1a1 100644
  					USHORT nThisSize = STD_EXTRA_WIDTH + pDoc->GetOptimalColWidth( nCol, nTab,
  												&aVirtDev, nPPTX, nPPTY, aZoomX, aZoomY, bFormula,
 diff --git sc/source/ui/unoobj/cellsuno.cxx sc/source/ui/unoobj/cellsuno.cxx
-index 53f0d52..59b88f4 100644
+index 53f0d52..8248363 100644
 --- sc/source/ui/unoobj/cellsuno.cxx
 +++ sc/source/ui/unoobj/cellsuno.cxx
 @@ -3448,18 +3448,25 @@ uno::Reference<sheet::XSheetCellRanges> SAL_CALL ScCellRangesBase::queryVisibleC
@@ -2603,7 +3226,21 @@ index 53f0d52..59b88f4 100644
  		}
  		else if ( pMap->nWID == SC_WID_UNO_OWIDTH )
  		{
-@@ -9110,8 +9118,9 @@ void ScTableRowObj::GetOnePropertyValue( const SfxItemPropertyMap* pMap,
+@@ -9053,12 +9061,7 @@ void ScTableRowObj::SetOnePropertyValue( const SfxItemPropertyMap* pMap, const u
+ //			ScSizeMode eMode = bVis ? SC_SIZE_SHOW : SC_SIZE_DIRECT;
+ //			aFunc.SetWidthOrHeight( FALSE, 1, nRowArr, nTab, eMode, 0, TRUE, TRUE );
+ 			//	SC_SIZE_DIRECT mit Groesse 0 blendet aus
+-			BYTE nFlags = pDoc->GetRowFlags(nRow, nTab);
+-			if (bFil)
+-				nFlags |= CR_FILTERED;
+-			else
+-				nFlags &= ~CR_FILTERED;
+-			pDoc->SetRowFlags(nRow, nTab, nFlags);
++            pDoc->SetRowFiltered(nRow, nRow, nTab, bFil);
+ 		}
+ 		else if ( pMap->nWID == SC_WID_UNO_OHEIGHT )
+ 		{
+@@ -9110,12 +9113,13 @@ void ScTableRowObj::GetOnePropertyValue( const SfxItemPropertyMap* pMap,
  		}
  		else if ( pMap->nWID == SC_WID_UNO_CELLVIS )
  		{
@@ -2615,6 +3252,11 @@ index 53f0d52..59b88f4 100644
  		}
  		else if ( pMap->nWID == SC_WID_UNO_CELLFILT )
  		{
+-			BOOL bVis = ((pDoc->GetRowFlags( nRow, nTab ) & CR_FILTERED) != 0);
++            bool bVis = pDoc->RowFiltered(nRow, nTab);
+ 			ScUnoHelpFunctions::SetBoolInAny( rAny, bVis );
+ 		}
+ 		else if ( pMap->nWID == SC_WID_UNO_OHEIGHT )
 diff --git sc/source/ui/unoobj/chart2uno.cxx sc/source/ui/unoobj/chart2uno.cxx
 index 9decd68..a3e9919 100644
 --- sc/source/ui/unoobj/chart2uno.cxx
@@ -2640,7 +3282,7 @@ index 9decd68..a3e9919 100644
                          {
                              // hidden cell
 diff --git sc/source/ui/unoobj/docuno.cxx sc/source/ui/unoobj/docuno.cxx
-index 9fac1bb..88b143d 100644
+index 9fac1bb..889c7ad 100644
 --- sc/source/ui/unoobj/docuno.cxx
 +++ sc/source/ui/unoobj/docuno.cxx
 @@ -2660,7 +2660,8 @@ uno::Any SAL_CALL ScTableColumnsObj::getPropertyValue( const rtl::OUString& aPro
@@ -2653,7 +3295,19 @@ index 9fac1bb..88b143d 100644
  		ScUnoHelpFunctions::SetBoolInAny( aAny, bVis );
  	}
  	else if ( aNameString.EqualsAscii( SC_UNONAME_OWIDTH ) )
-@@ -2909,7 +2910,8 @@ uno::Any SAL_CALL ScTableRowsObj::getPropertyValue( const rtl::OUString& aProper
+@@ -2849,9 +2850,9 @@ void SAL_CALL ScTableRowsObj::setPropertyValue(
+ 	{
+ 		//!	undo etc.
+ 		if (ScUnoHelpFunctions::GetBoolFromAny( aValue ))
+-            pDoc->GetRowFlagsArrayModifiable( nTab).OrValue( nStartRow, nEndRow, CR_FILTERED);
++            pDoc->SetRowFiltered(nStartRow, nEndRow, nTab, true);
+         else
+-            pDoc->GetRowFlagsArrayModifiable( nTab).AndValue( nStartRow, nEndRow, sal::static_int_cast<BYTE>(~CR_FILTERED) );
++            pDoc->SetRowFiltered(nStartRow, nEndRow, nTab, false);
+ 	}
+ 	else if ( aNameString.EqualsAscii( SC_UNONAME_OHEIGHT ) )
+ 	{
+@@ -2909,12 +2910,13 @@ uno::Any SAL_CALL ScTableRowsObj::getPropertyValue( const rtl::OUString& aProper
  	}
  	else if ( aNameString.EqualsAscii( SC_UNONAME_CELLVIS ) )
  	{
@@ -2663,6 +3317,12 @@ index 9fac1bb..88b143d 100644
  		ScUnoHelpFunctions::SetBoolInAny( aAny, bVis );
  	}
  	else if ( aNameString.EqualsAscii( SC_UNONAME_CELLFILT ) )
+ 	{
+-		BOOL bVis = ((pDoc->GetRowFlags( nStartRow, nTab ) & CR_FILTERED) != 0);
++        bool bVis = pDoc->RowFiltered(nStartRow, nTab);
+ 		ScUnoHelpFunctions::SetBoolInAny( aAny, bVis );
+ 	}
+ 	else if ( aNameString.EqualsAscii( SC_UNONAME_OHEIGHT ) )
 diff --git sc/source/ui/view/colrowba.cxx sc/source/ui/view/colrowba.cxx
 index 3107d46..b42726e 100644
 --- sc/source/ui/view/colrowba.cxx
@@ -2789,10 +3449,10 @@ index 2e88791..54789c0 100644
  								--nThisY;
  								pPattern = pDoc->GetPattern( nX, nThisY, nTab );
 diff --git sc/source/ui/view/olinewin.cxx sc/source/ui/view/olinewin.cxx
-index a9ed1ae..4a99450 100644
+index a9ed1ae..b2d5f48 100644
 --- sc/source/ui/view/olinewin.cxx
 +++ sc/source/ui/view/olinewin.cxx
-@@ -186,10 +186,9 @@ const ScOutlineEntry* ScOutlineWindow::GetOutlineEntry( size_t nLevel, size_t nE
+@@ -186,16 +186,15 @@ const ScOutlineEntry* ScOutlineWindow::GetOutlineEntry( size_t nLevel, size_t nE
  
  bool ScOutlineWindow::IsHidden( SCCOLROW nColRowIndex ) const
  {
@@ -2806,6 +3466,13 @@ index a9ed1ae..4a99450 100644
  }
  
  bool ScOutlineWindow::IsFiltered( SCCOLROW nColRowIndex ) const
+ {
+     // columns cannot be filtered
+-    return !mbHoriz && GetDoc().IsFiltered( static_cast<SCROW>(nColRowIndex), GetTab() );
++    return !mbHoriz && GetDoc().RowFiltered( static_cast<SCROW>(nColRowIndex), GetTab() );
+ }
+ 
+ bool ScOutlineWindow::IsFirstVisible( SCCOLROW nColRowIndex ) const
 diff --git sc/source/ui/view/output.cxx sc/source/ui/view/output.cxx
 index 1585791..4c20625 100644
 --- sc/source/ui/view/output.cxx
@@ -3327,6 +3994,25 @@ index be4d659..ea04a47 100644
  
  		rSizeXPix = nOutWidth;
  		rSizeYPix = nOutHeight;
+diff --git sc/source/ui/view/viewfun3.cxx sc/source/ui/view/viewfun3.cxx
+index 8540ce9..d38bbe2 100644
+--- sc/source/ui/view/viewfun3.cxx
++++ sc/source/ui/view/viewfun3.cxx
+@@ -1713,10 +1713,10 @@ BOOL ScViewFunc::MoveBlockTo( const ScRange& rSource, const ScAddress& rDestPos,
+ 		BOOL bIncludeFiltered = bCut;
+ 		if ( !bIncludeFiltered )
+ 		{
+-			//	manually find number of non-filtered rows
+-            SCROW nPastedCount = pDocSh->GetDocument()->GetRowFlagsArray(
+-                    rSource.aStart.Tab()).CountForCondition(
+-                    rSource.aStart.Row(), rSource.aEnd.Row(), CR_FILTERED, 0);
++			// find number of non-filtered rows
++            SCROW nPastedCount = pDocSh->GetDocument()->CountNonFilteredRows(
++                rSource.aStart.Row(), rSource.aEnd.Row(), rSource.aStart.Tab());
++
+ 			if ( nPastedCount == 0 )
+ 				nPastedCount = 1;
+ 			aDestEnd.SetRow( rDestPos.Row() + nPastedCount - 1 );
 diff --git sc/source/ui/view/viewfunc.cxx sc/source/ui/view/viewfunc.cxx
 index d8e28ce..ea2ddec 100644
 --- sc/source/ui/view/viewfunc.cxx
@@ -3380,3 +4066,80 @@ index d8e28ce..ea2ddec 100644
  						{
  							USHORT nThisSize = nSizeTwips;
  
+diff --git sc/source/ui/view/viewutil.cxx sc/source/ui/view/viewutil.cxx
+index 67156b6..b7c1dac 100644
+--- sc/source/ui/view/viewutil.cxx
++++ sc/source/ui/view/viewutil.cxx
+@@ -258,20 +258,19 @@ void ScViewUtil::UnmarkFiltered( ScMarkData& rMark, ScDocument* pDoc )
+     for (SCTAB nTab=0; nTab<nTabCount; nTab++)
+         if ( rMark.GetTableSelect(nTab ) )
+         {
+-            ScCompressedArrayIterator<SCROW, BYTE> aIter(pDoc->GetRowFlagsArray(nTab), nStartRow, nEndRow);
+-            do
++            for (SCROW nRow = nStartRow; nRow <= nEndRow; ++nRow)
+             {
+-    			if (*aIter & CR_FILTERED)
+-    			{
++                SCROW nLastRow = nRow;
++                if (pDoc->RowFiltered(nRow, nTab, NULL, &nLastRow))
++                {
+                     // use nStartCol/nEndCol, so the multi mark area isn't extended to all columns
+                     // (visible in repaint for indentation)
+-
+-                    rMark.SetMultiMarkArea( ScRange( nStartCol, aIter.GetRangeStart(), nTab,
+-                                                     nEndCol, aIter.GetRangeEnd(), nTab ), FALSE );
++                    rMark.SetMultiMarkArea(
++                        ScRange(nStartCol, nRow, nTab, nEndCol, nLastRow, nTab), false);
+                     bChanged = true;
+-    			}
++                    nRow = nLastRow;
++                }
+             }
+-            while (aIter.NextRange());
+         }
+ 
+     if ( bChanged && !rMark.HasAnyMultiMarks() )
+@@ -282,13 +281,19 @@ void ScViewUtil::UnmarkFiltered( ScMarkData& rMark, ScDocument* pDoc )
+ 
+ 
+ // static
+-bool ScViewUtil::FitToUnfilteredRows( ScRange & rRange, const ScDocument * pDoc, size_t nRows )
++bool ScViewUtil::FitToUnfilteredRows( ScRange & rRange, ScDocument * pDoc, size_t nRows )
+ {
+     SCTAB nTab = rRange.aStart.Tab();
+     bool bOneTabOnly = (nTab == rRange.aEnd.Tab());
+     // Always fit the range on its first sheet.
+     DBG_ASSERT( bOneTabOnly, "ScViewUtil::ExtendToUnfilteredRows: works only on one sheet");
+     SCROW nStartRow = rRange.aStart.Row();
++#if 1
++    SCROW nLastRow = pDoc->LastNonFilteredRow(nStartRow, MAXROW, nTab);
++    if (ValidRow(nLastRow))
++        rRange.aEnd.SetRow(nLastRow);
++    SCROW nCount = pDoc->CountNonFilteredRows(nStartRow, MAXROW, nTab);
++#else
+     // FillArrayForCondition() usually is the fastest to determine such a set
+     // in one pass, even if the array isn't used but the last element.
+     SCROW* pArr = new SCROW[nRows];
+@@ -297,19 +302,19 @@ bool ScViewUtil::FitToUnfilteredRows( ScRange & rRange, const ScDocument * pDoc,
+     if (nCount)
+         rRange.aEnd.SetRow( pArr[nCount-1]);
+     delete [] pArr;
++#endif
+     return nCount == nRows && bOneTabOnly;
+ }
+ 
+ 
+ // static
+-bool ScViewUtil::HasFiltered( const ScRange& rRange, const ScDocument* pDoc )
++bool ScViewUtil::HasFiltered( const ScRange& rRange, ScDocument* pDoc )
+ {
+     SCROW nStartRow = rRange.aStart.Row();
+     SCROW nEndRow = rRange.aEnd.Row();
+     for (SCTAB nTab=rRange.aStart.Tab(); nTab<=rRange.aEnd.Tab(); nTab++)
+     {
+-        if ( pDoc->GetRowFlagsArray( nTab).HasCondition( nStartRow, nEndRow,
+-                CR_FILTERED, CR_FILTERED ) )
++        if (pDoc->HasFilteredRows(nStartRow, nEndRow, nTab))
+             return true;
+     }
+ 


More information about the ooo-build-commit mailing list