Index: sc/inc/attarray.hxx =================================================================== --- sc/inc/attarray.hxx (revision 1330076) +++ sc/inc/attarray.hxx (working copy) @@ -83,8 +83,8 @@ ScDocument* pDocument; SCSIZE nCount; - SCSIZE nLimit; - ScAttrEntry* pData; + mutable SCSIZE nLimit; + mutable ScAttrEntry* pData; friend class ScDocument; // fuer FillInfo friend class ScDocumentIterator; @@ -184,6 +184,9 @@ void DeleteHardAttr( SCROW nStartRow, SCROW nEndRow ); //UNUSED2008-05 void ConvertFontsAfterLoad(); // old binary file format + bool Reserve( SCSIZE nCount ) const; + SCSIZE Count() const{ return nCount; } + SCSIZE Count( SCROW nRw1, SCROW nRw2 ) const; }; Index: sc/inc/column.hxx =================================================================== --- sc/inc/column.hxx (revision 1330076) +++ sc/inc/column.hxx (working copy) @@ -395,6 +395,9 @@ xub_StrLen GetMaxNumberStringLen( sal_uInt16& nPrecision, SCROW nRowStart, SCROW nRowEnd ) const; + SCSIZE GetPatternCount( ) const; + SCSIZE GetPatternCount( SCROW nRw1, SCROW nRw2 ) const; + bool ReservedPatternCount( SCSIZE nReserved ) const; private: ScBaseCell* CloneCell(SCSIZE nIndex, sal_uInt16 nFlags, ScDocument& rDestDoc, const ScAddress& rDestPos); //UNUSED2008-05 void CorrectSymbolCells( CharSet eStreamCharSet ); Index: sc/inc/document.hxx =================================================================== --- sc/inc/document.hxx (revision 1330076) +++ sc/inc/document.hxx (working copy) @@ -1872,6 +1872,10 @@ std::map< SCTAB, ScSortParam > mSheetSortParams; +private: + SCSIZE GetPatternCount( SCTAB nTab, SCCOL nCol ) const; + SCSIZE GetPatternCount( SCTAB nTab, SCCOL nCol, SCROW nRw1, SCROW nRw2 ) const; + bool ReservedPatternCount( SCTAB nTab, SCCOL nCol, SCSIZE nReserved ) const; }; inline void ScDocument::GetSortParam( ScSortParam& rParam, SCTAB nTab ) { Index: sc/inc/table.hxx =================================================================== --- sc/inc/table.hxx (revision 1330076) +++ sc/inc/table.hxx (working copy) @@ -311,6 +311,9 @@ SvNumberFormatter* pFormatter = NULL, bool bDetectNumberFormat = true ); void SetValue( SCCOL nCol, SCROW nRow, const double& rVal ); void SetError( SCCOL nCol, SCROW nRow, sal_uInt16 nError); + SCSIZE GetPatternCount( SCCOL nCol ) const; + SCSIZE GetPatternCount( SCCOL nCol, SCROW nRw1, SCROW nRw2 ) const; + bool ReservedPatternCount( SCCOL nCol, SCSIZE nReserved ) const; void GetString( SCCOL nCol, SCROW nRow, String& rString ); void GetInputString( SCCOL nCol, SCROW nRow, String& rString ); Index: sc/source/core/data/attarray.cxx =================================================================== --- sc/source/core/data/attarray.cxx (revision 1330076) +++ sc/source/core/data/attarray.cxx (working copy) @@ -295,6 +295,24 @@ SetPatternArea( nRow, nRow, pPattern, bPutToPool ); } +bool ScAttrArray::Reserve( SCSIZE nReserve ) const +{ + if ( nCount <= nReserve ) + { + if( ScAttrEntry* pNewData = new (std::nothrow) ScAttrEntry[nReserve] ) + { + nLimit = nReserve; + memcpy( pNewData, pData, nCount*sizeof(ScAttrEntry) ); + delete[] pData; + pData = pNewData; + return true; + } + else + return false; + } + else + return false; +} void ScAttrArray::SetPatternArea(SCROW nStartRow, SCROW nEndRow, const ScPatternAttr *pPattern, sal_Bool bPutToPool ) { @@ -2605,3 +2623,15 @@ //UNUSED2008-05 } //UNUSED2008-05 } +SCSIZE ScAttrArray::Count( SCROW nStartRow, SCROW nEndRow ) const +{ + SCSIZE nIndex1, nIndex2; + + if( !Search( nStartRow, nIndex1 ) ) + return 0; + + if( !Search( nEndRow, nIndex2 ) ) + nIndex2 = this->nCount - 1; + + return nIndex2 - nIndex1 + 1; +} Index: sc/source/core/data/column2.cxx =================================================================== --- sc/source/core/data/column2.cxx (revision 1330076) +++ sc/source/core/data/column2.cxx (working copy) @@ -1872,7 +1872,19 @@ return nCodeCount; } +SCSIZE ScColumn::GetPatternCount() const +{ + return this->pAttrArray ? this->pAttrArray->Count() : 0; +} +SCSIZE ScColumn::GetPatternCount( SCROW nRw1, SCROW nRw2 ) const +{ + return this->pAttrArray ? this->pAttrArray->Count( nRw1, nRw2 ) : 0; +} +bool ScColumn::ReservedPatternCount( SCSIZE nReserved ) const +{ + return this->pAttrArray ? this->pAttrArray->Reserve( nReserved ) : false; +} Index: sc/source/core/data/documen3.cxx =================================================================== --- sc/source/core/data/documen3.cxx (revision 1330076) +++ sc/source/core/data/documen3.cxx (working copy) @@ -2152,3 +2152,26 @@ } } // End Comments +SCSIZE ScDocument::GetPatternCount( SCTAB nTab, SCCOL nCol ) const +{ + if( ValidTab(nTab) && pTab[nTab] ) + return pTab[nTab]->GetPatternCount( nCol ); + else + return 0; +} + +SCSIZE ScDocument::GetPatternCount( SCTAB nTab, SCCOL nCol, SCROW nRw1, SCROW nRw2 ) const +{ + if( ValidTab(nTab) && pTab[nTab] ) + return pTab[nTab]->GetPatternCount( nCol, nRw1, nRw2 ); + else + return 0; +} + +bool ScDocument::ReservedPatternCount( SCTAB nTab, SCCOL nCol, SCSIZE nReserved ) const +{ + if( ValidTab(nTab) && pTab[nTab] ) + return pTab[nTab]->ReservedPatternCount( nCol, nReserved ); + else + return false; +} Index: sc/source/core/data/document.cxx =================================================================== --- sc/source/core/data/document.cxx (revision 1330076) +++ sc/source/core/data/document.cxx (working copy) @@ -2178,7 +2178,26 @@ SCROW nR2 = nR1 + nYw; if (nR2 > nRow2) nR2 = nRow2; + const unsigned PERFORMANCEOPTIMIZATION4PATTERNTHRESHOLD = 8192; + bool bNeedPerformanceOptimization4Pattern = nRow2 - nRow1 > PERFORMANCEOPTIMIZATION4PATTERNTHRESHOLD; + std::vector< std::vector< SCSIZE > > vvPatternCount( bNeedPerformanceOptimization4Pattern ? nCol2 - nCol1 + 1 : 0 ); + std::vector< SCTAB > vTables; + if( bNeedPerformanceOptimization4Pattern ) + { + for (SCTAB i = aCBFCP.nTabStart; i <= aCBFCP.nTabEnd; i++) + if (pTab[i] && rMark.GetTableSelect( i ) ) + vTables.push_back( i ); + + for( SCSIZE i = 0; i < vvPatternCount.size(); i++ ) + { + vvPatternCount[i].resize( vTables.size() ); + + for( std::vector< SCTAB >::size_type j = 0; jGetPatternCount( vTables[j], nCol1+i ); + } + } + do { // Pasting is done column-wise, when pasting to a filtered @@ -2215,6 +2234,19 @@ nC2 = nC1 + nXw; if (nC2 > nCol2) nC2 = nCol2; + if( bNeedPerformanceOptimization4Pattern && vvPatternCount.size() ) + { + for( SCSIZE i = 0; i < vvPatternCount.size(); i++ ) + { + vvPatternCount[i].resize( vTables.size() ); + + for( std::vector< SCTAB >::size_type j = 0; jReservedPatternCount( vTables[j], nCol1+i, vvPatternCount[i][j] + ( this->GetPatternCount( vTables[j], nCol1+i, nR1, nR2 ) ) * ( ( nRow2 - nRow1 + 1 ) / ( nYw + 1 ) ) ); + } + + bNeedPerformanceOptimization4Pattern = false; + vvPatternCount.clear(); + } nR1 = nR2 + 1; nR2 = Min((SCROW)(nR1 + nYw), nRow2); } while (nR1 <= nRow2); Index: sc/source/core/data/table4.cxx =================================================================== --- sc/source/core/data/table4.cxx (revision 1330076) +++ sc/source/core/data/table4.cxx (working copy) @@ -2024,8 +2024,29 @@ for (SCCOL i=0; i<=MAXCOL; i++) aCol[i].CompileColRowNameFormula(); } +SCSIZE ScTable::GetPatternCount( SCCOL nCol ) const +{ + if( ValidCol( nCol ) ) + return aCol[nCol].GetPatternCount(); + else + return 0; +} +SCSIZE ScTable::GetPatternCount( SCCOL nCol, SCROW nRw1, SCROW nRw2 ) const +{ + if( ValidCol( nCol ) && ValidRow( nRw1 ) && ValidRow( nRw2 ) ) + return aCol[nCol].GetPatternCount( nRw1, nRw2 ); + else + return 0; +} +bool ScTable::ReservedPatternCount( SCCOL nCol, SCSIZE nReserved ) const +{ + if( ValidCol( nCol ) ) + return aCol[nCol].ReservedPatternCount( nReserved ); + else + return false; +}