cache cell positions when opening standard filter in calc (tdf#80853)

Part of the performance problem in the bugreport. Mdds otherwise
always starts a search from the beginning of the contaier.

Change-Id: Ic5c542220b7a8dc3aec0cfa93a0888997435fbfe
Reviewed-on: https://gerrit.libreoffice.org/72347
Tested-by: Jenkins
Reviewed-by: Dennis Francis <dennis.francis@collabora.com>
diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index 023e774..f55bc63 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -216,6 +216,8 @@ public:
    SCSIZE      GetEmptyLinesInBlock( SCROW nStartRow, SCROW nEndRow, ScDirection eDir ) const;
    bool        HasDataAt(SCROW nRow, bool bConsiderCellNotes=false,
                          bool bConsiderCellDrawObjects=false) const;
    bool        HasDataAt(sc::ColumnBlockConstPosition& rBlockPos, SCROW nRow, bool bConsiderCellNotes=false,
                          bool bConsiderCellDrawObjects=false) const;
    bool        HasVisibleDataAt(SCROW nRow) const;
    SCROW       GetFirstDataPos() const;
    SCROW       GetLastDataPos() const;
diff --git a/sc/source/core/data/column2.cxx b/sc/source/core/data/column2.cxx
index bea0497..2568041 100644
--- a/sc/source/core/data/column2.cxx
+++ b/sc/source/core/data/column2.cxx
@@ -3084,6 +3084,22 @@ bool ScColumn::HasDataAt(SCROW nRow, bool bConsiderCellNotes, bool bConsiderCell
    return maCells.get_type(nRow) != sc::element_type_empty;
}

bool ScColumn::HasDataAt(sc::ColumnBlockConstPosition& rBlockPos, SCROW nRow,
                         bool bConsiderCellNotes, bool bConsiderCellDrawObjects) const
{
    if (bConsiderCellNotes && !IsNotesEmptyBlock(nRow, nRow))
        return true;

    if (bConsiderCellDrawObjects && !IsDrawObjectsEmptyBlock(nRow, nRow))
        return true;

    std::pair<sc::CellStoreType::const_iterator,size_t> aPos = maCells.position(rBlockPos.miCellPos, nRow);
    if (aPos.first == maCells.end())
        return false;
    rBlockPos.miCellPos = aPos.first; // Store this for next call.
    return aPos.first->type != sc::element_type_empty;
}

bool ScColumn::IsAllAttrEqual( const ScColumn& rCol, SCROW nStartRow, SCROW nEndRow ) const
{
    if (pAttrArray && rCol.pAttrArray)
diff --git a/sc/source/core/data/table1.cxx b/sc/source/core/data/table1.cxx
index 24d0439..c18c039 100644
--- a/sc/source/core/data/table1.cxx
+++ b/sc/source/core/data/table1.cxx
@@ -801,6 +801,11 @@ void ScTable::GetDataArea( SCCOL& rStartCol, SCROW& rStartRow, SCCOL& rEndCol, S
    bool bBottom = false;
    bool bChanged = false;

    // We need to cache sc::ColumnBlockConstPosition per each column.
    std::vector< sc::ColumnBlockConstPosition > blockPos( rEndCol + 1 );
    for( SCCOL i = 0; i <= rEndCol; ++i )
        aCol[ i ].InitBlockPosition( blockPos[ i ] );

    do
    {
        bChanged = false;
@@ -815,7 +820,10 @@ void ScTable::GetDataArea( SCCOL& rStartCol, SCROW& rStartRow, SCCOL& rEndCol, S
            if (rEndCol < (aCol.size()-1))
                if (!aCol[rEndCol+1].IsEmptyBlock(nStart,nEnd))
                {
                    assert( int( blockPos.size()) == rEndCol + 1 );
                    ++rEndCol;
                    blockPos.resize( blockPos.size() + 1 );
                    aCol[ rEndCol ].InitBlockPosition( blockPos[ rEndCol ] );
                    bChanged = true;
                    bRight = true;
                }
@@ -833,7 +841,7 @@ void ScTable::GetDataArea( SCCOL& rStartCol, SCROW& rStartRow, SCCOL& rEndCol, S
                SCROW nTest = rStartRow-1;
                bool needExtend = false;
                for ( SCCOL i = rStartCol; i<=rEndCol && !needExtend; i++)
                    if (aCol[i].HasDataAt(nTest))
                    if (aCol[i].HasDataAt(blockPos[i], nTest))
                        needExtend = true;
                if (needExtend)
                {
@@ -849,7 +857,7 @@ void ScTable::GetDataArea( SCCOL& rStartCol, SCROW& rStartRow, SCCOL& rEndCol, S
            SCROW nTest = rEndRow+1;
            bool needExtend = false;
            for ( SCCOL i = rStartCol; i<=rEndCol && !needExtend; i++)
                if (aCol[i].HasDataAt(nTest))
                if (aCol[i].HasDataAt(blockPos[ i ], nTest))
                    needExtend = true;
            if (needExtend)
            {