sc/inc/dociter.hxx | 22 ++- sc/inc/editutil.hxx | 2 sc/source/core/data/autonamecache.cxx | 19 +- sc/source/core/data/dociter.cxx | 179 ++++++++++++++++++++++---- sc/source/core/tool/detfunc.cxx | 9 - sc/source/core/tool/editutil.cxx | 14 ++ sc/source/filter/xml/xmlexprt.cxx | 12 + sc/source/ui/Accessibility/AccessibleCell.cxx | 5 sc/source/ui/docshell/dbdocfun.cxx | 2 sc/source/ui/unoobj/cellsuno.cxx | 27 +-- 10 files changed, 225 insertions(+), 66 deletions(-)
New commits: commit 1dccacc26854cb2af8476f163450bd0f0eb97128 Author: Kohei Yoshida <kohei.yosh...@gmail.com> Date: Fri Mar 22 19:49:41 2013 -0400 Re-did ScCellIterator to avoid copying every single iterated cell. ScCellValue copies the cell value. Let's not use it in ScCellIterator. Change-Id: Id478b607c702077751878f557b8779c98b68db28 diff --git a/sc/inc/dociter.hxx b/sc/inc/dociter.hxx index 80f3738..8e3b28b 100644 --- a/sc/inc/dociter.hxx +++ b/sc/inc/dociter.hxx @@ -24,7 +24,6 @@ #include <tools/solar.h> #include "global.hxx" #include "scdllapi.h" -#include "cellvalue.hxx" #include <memory> @@ -45,6 +44,7 @@ struct ScDBQueryParamBase; struct ScQueryParam; struct ScDBQueryParamInternal; struct ScDBQueryParamMatrix; +class ScFormulaCell; class ScDocumentIterator // walk through all non-empty cells { @@ -218,10 +218,17 @@ private: ScAddress maStartPos; ScAddress maEndPos; ScAddress maCurPos; - ScCellValue maCurCell; SCSIZE nColRow; bool bSubTotal; + CellType meCurType; + OUString maCurString; + union { + double mfCurValue; + const EditTextObject* mpCurEditText; // points to the original. + ScFormulaCell* mpCurFormula; // points to the original. + }; + ScBaseCell* GetThis(); void init(); bool getCurrent(); @@ -236,10 +243,17 @@ public: ScBaseCell* GetNext(); const ScAddress& GetPos() const { return maCurPos; } + CellType getType() const; + const OUString& getString() const; + const EditTextObject* getEditText() const; + ScFormulaCell* getFormulaCell(); + bool hasString() const; + bool hasNumeric() const; + bool isEmpty() const; + bool equalsWithoutFormat( const ScAddress& rPos ) const; + bool first(); bool next(); - - const ScCellValue& get() const; }; class ScQueryCellIterator // walk through all non-empty cells in an area diff --git a/sc/inc/editutil.hxx b/sc/inc/editutil.hxx index 3bdbb32..556e749 100644 --- a/sc/inc/editutil.hxx +++ b/sc/inc/editutil.hxx @@ -59,6 +59,8 @@ public: /// Retrieves string with paragraphs delimited by new lines ('\n'). static String GetMultilineString( const EditEngine& rEngine ); + static OUString GetString( const EditTextObject& rEditText ); + public: ScEditUtil( ScDocument* pDocument, SCCOL nX, SCROW nY, SCTAB nZ, const Point& rScrPosPixel, diff --git a/sc/source/core/data/autonamecache.cxx b/sc/source/core/data/autonamecache.cxx index 2bbc4b2..6629c51 100644 --- a/sc/source/core/data/autonamecache.cxx +++ b/sc/source/core/data/autonamecache.cxx @@ -57,23 +57,26 @@ const ScAutoNameAddresses& ScAutoNameCache::GetNameOccurrences( const String& rN { // don't check code length here, always use the stored result // (AutoCalc is disabled during CompileXML) - const ScCellValue& rVal = aIter.get(); - if (rVal.hasString()) + if (aIter.hasString()) { OUString aStr; - switch (rVal.meType) + switch (aIter.getType()) { case CELLTYPE_STRING: - aStr = *rVal.mpString; + aStr = aIter.getString(); break; case CELLTYPE_FORMULA: - aStr = rVal.mpFormula->GetString(); + aStr = aIter.getFormulaCell()->GetString(); break; case CELLTYPE_EDIT: { - ScFieldEditEngine& rEngine = pDoc->GetEditEngine(); - rEngine.SetText(*rVal.mpEditText); - aStr = ScEditUtil::GetMultilineString(rEngine); // string with line separators between paragraphs + const EditTextObject* p = aIter.getEditText(); + if (p) + { + ScFieldEditEngine& rEngine = pDoc->GetEditEngine(); + rEngine.SetText(*p); + aStr = ScEditUtil::GetMultilineString(rEngine); // string with line separators between paragraphs + } } break; case CELLTYPE_NONE: diff --git a/sc/source/core/data/dociter.cxx b/sc/source/core/data/dociter.cxx index 5446bbc..6517f5b 100644 --- a/sc/source/core/data/dociter.cxx +++ b/sc/source/core/data/dociter.cxx @@ -35,6 +35,8 @@ #include "queryparam.hxx" #include "queryentry.hxx" #include "globstr.hrc" +#include "editutil.hxx" + #include "tools/fract.hxx" #include "editeng/editobj.hxx" @@ -943,7 +945,9 @@ ScCellIterator::ScCellIterator( ScDocument* pDocument, maStartPos(nSCol, nSRow, nSTab), maEndPos(nECol, nERow, nETab), nColRow(0), - bSubTotal(bSTotal) + bSubTotal(bSTotal), + meCurType(CELLTYPE_NONE), + mfCurValue(0.0) { init(); } @@ -953,7 +957,9 @@ ScCellIterator::ScCellIterator( ScDocument* pDocument, const ScRange& rRange, bo maStartPos(rRange.aStart), maEndPos(rRange.aEnd), nColRow(0), - bSubTotal(bSTotal) + bSubTotal(bSTotal), + meCurType(CELLTYPE_NONE), + mfCurValue(0.0) { init(); } @@ -1068,7 +1074,7 @@ bool ScCellIterator::getCurrent() maCurPos.IncTab(); if (maCurPos.Tab() > maEndPos.Tab()) { - maCurCell.clear(); + meCurType = CELLTYPE_NONE; return false; // Over and out } } @@ -1093,33 +1099,26 @@ bool ScCellIterator::getCurrent() else { // Found it! - maCurCell.clear(); - maCurCell.meType = pCell->GetCellType(); - switch (maCurCell.meType) + meCurType = pCell->GetCellType(); + switch (meCurType) { case CELLTYPE_VALUE: - maCurCell.mfValue = static_cast<const ScValueCell*>(pCell)->GetValue(); + mfCurValue = static_cast<const ScValueCell*>(pCell)->GetValue(); break; case CELLTYPE_STRING: - { - const OUString& rStr = static_cast<const ScStringCell*>(pCell)->GetString(); - maCurCell.mpString = new OUString(rStr); - } + maCurString = static_cast<const ScStringCell*>(pCell)->GetString(); break; case CELLTYPE_EDIT: - { - const EditTextObject* pData = static_cast<const ScEditCell*>(pCell)->GetData(); - maCurCell.mpEditText = pData->Clone(); - } + mpCurEditText = static_cast<const ScEditCell*>(pCell)->GetData(); break; case CELLTYPE_FORMULA: - maCurCell.mpFormula = static_cast<const ScFormulaCell*>(pCell)->Clone(); + mpCurFormula = static_cast<ScFormulaCell*>(pCell); break; default: - maCurCell.meType = CELLTYPE_NONE; + meCurType = CELLTYPE_NONE; } - if (maCurCell.meType != CELLTYPE_NONE) + if (meCurType != CELLTYPE_NONE) return true; maCurPos.IncRow(); @@ -1134,6 +1133,145 @@ bool ScCellIterator::getCurrent() return false; } +CellType ScCellIterator::getType() const +{ + return meCurType; +} + +const OUString& ScCellIterator::getString() const +{ + return maCurString; +} + +const EditTextObject* ScCellIterator::getEditText() const +{ + return mpCurEditText; +} + +ScFormulaCell* ScCellIterator::getFormulaCell() +{ + return mpCurFormula; +} + +bool ScCellIterator::hasString() const +{ + switch (meCurType) + { + case CELLTYPE_STRING: + case CELLTYPE_EDIT: + return true; + case CELLTYPE_FORMULA: + return !mpCurFormula->IsValue(); + default: + ; + } + + return false; +} + +bool ScCellIterator::hasNumeric() const +{ + switch (meCurType) + { + case CELLTYPE_VALUE: + return true; + case CELLTYPE_FORMULA: + return mpCurFormula->IsValue(); + default: + ; + } + + return false; +} + +bool ScCellIterator::isEmpty() const +{ + return meCurType == CELLTYPE_NOTE || meCurType == CELLTYPE_NONE; +} + +namespace { + +CellType adjustCellType( CellType eOrig ) +{ + switch (eOrig) + { + case CELLTYPE_NOTE: + return CELLTYPE_NONE; + case CELLTYPE_EDIT: + return CELLTYPE_STRING; + default: + ; + } + return eOrig; +} + +} + +bool ScCellIterator::equalsWithoutFormat( const ScAddress& rPos ) const +{ + // Fetch the other cell first. + if (!pDoc->TableExists(rPos.Tab())) + return false; + + ScTable& rTab = *pDoc->maTabs[rPos.Tab()]; + if (!ValidColRow(rPos.Col(), rPos.Row())) + return false; + + ScColumn& rCol = rTab.aCol[rPos.Col()]; + SCSIZE nIndex; + if (!rCol.Search(rPos.Row(), nIndex)) + return false; + + ScBaseCell* pCell2 = rCol.maItems[nIndex].pCell; + + CellType eType1 = adjustCellType(meCurType); + CellType eType2 = adjustCellType(pCell2->GetCellType()); + if (eType1 != eType2) + return false; + + switch (eType1) + { + case CELLTYPE_NONE: + // Both are empty. + return true; + case CELLTYPE_VALUE: + return mfCurValue == static_cast<ScValueCell*>(pCell2)->GetValue(); + case CELLTYPE_STRING: + { + OUString aStr1; + if (meCurType == CELLTYPE_STRING) + aStr1 = maCurString; + else if (meCurType == CELLTYPE_EDIT) + aStr1 = ScEditUtil::GetString(*mpCurEditText); + + OUString aStr2 = pCell2->GetStringData(); + return aStr1 == aStr2; + } + case CELLTYPE_FORMULA: + { + ScTokenArray* pCode1 = mpCurFormula->GetCode(); + ScTokenArray* pCode2 = static_cast<ScFormulaCell*>(pCell2)->GetCode(); + + if (pCode1->GetLen() != pCode2->GetLen()) + return false; + + sal_uInt16 n = pCode1->GetLen(); + formula::FormulaToken** ppToken1 = pCode1->GetArray(); + formula::FormulaToken** ppToken2 = pCode2->GetArray(); + for (sal_uInt16 i = 0; i < n; ++i) + { + if (!ppToken1[i]->TextEqual(*(ppToken2[i]))) + return false; + } + + return true; + } + default: + ; + } + return false; +} + bool ScCellIterator::first() { if (!ValidTab(maCurPos.Tab())) @@ -1151,11 +1289,6 @@ bool ScCellIterator::next() return getCurrent(); } -const ScCellValue& ScCellIterator::get() const -{ - return maCurCell; -} - //------------------------------------------------------------------------------- ScQueryCellIterator::ScQueryCellIterator(ScDocument* pDocument, SCTAB nTable, diff --git a/sc/source/core/tool/detfunc.cxx b/sc/source/core/tool/detfunc.cxx index 280658e..ee5f820 100644 --- a/sc/source/core/tool/detfunc.cxx +++ b/sc/source/core/tool/detfunc.cxx @@ -302,11 +302,10 @@ sal_Bool ScDetectiveFunc::HasError( const ScRange& rRange, ScAddress& rErrPos ) ScCellIterator aIter( pDoc, rRange); for (bool bHasCell = aIter.first(); bHasCell; bHasCell = aIter.next()) { - const ScCellValue& rVal = aIter.get(); - if (rVal.meType != CELLTYPE_FORMULA) + if (aIter.getType() != CELLTYPE_FORMULA) continue; - nError = rVal.mpFormula->GetErrCode(); + nError = aIter.getFormulaCell()->GetErrCode(); if (nError) rErrPos = aIter.GetPos(); } @@ -794,7 +793,7 @@ sal_uInt16 ScDetectiveFunc::InsertPredLevelArea( const ScRange& rRef, ScCellIterator aIter( pDoc, rRef); for (bool bHasCell = aIter.first(); bHasCell; bHasCell = aIter.next()) { - if (aIter.get().meType != CELLTYPE_FORMULA) + if (aIter.getType() != CELLTYPE_FORMULA) continue; const ScAddress& rPos = aIter.GetPos(); @@ -896,7 +895,7 @@ sal_uInt16 ScDetectiveFunc::FindPredLevelArea( const ScRange& rRef, ScCellIterator aCellIter( pDoc, rRef); for (bool bHasCell = aCellIter.first(); bHasCell; bHasCell = aCellIter.next()) { - if (aCellIter.get().meType != CELLTYPE_FORMULA) + if (aCellIter.getType() != CELLTYPE_FORMULA) continue; sal_uInt16 nTemp = FindPredLevel(aCellIter.GetPos().Col(), aCellIter.GetPos().Row(), nLevel, nDeleteLevel); diff --git a/sc/source/core/tool/editutil.cxx b/sc/source/core/tool/editutil.cxx index 66ba2fc..67ff543 100644 --- a/sc/source/core/tool/editutil.cxx +++ b/sc/source/core/tool/editutil.cxx @@ -29,6 +29,7 @@ #include <editeng/flditem.hxx> #include <editeng/numitem.hxx> #include <editeng/justifyitem.hxx> +#include "editeng/editobj.hxx" #include <vcl/svapp.hxx> #include <vcl/outdev.hxx> #include <svl/inethist.hxx> @@ -90,6 +91,19 @@ String ScEditUtil::GetMultilineString( const EditEngine& rEngine ) return lcl_GetDelimitedString(rEngine, '\n'); } +OUString ScEditUtil::GetString( const EditTextObject& rEditText ) +{ + OUStringBuffer aRet; + size_t n = rEditText.GetParagraphCount(); + for (size_t i = 0; i < n; ++i) + { + if (i > 0) + aRet.append('\n'); + aRet.append(rEditText.GetText(i)); + } + return aRet.makeStringAndClear(); +} + //------------------------------------------------------------------------ Rectangle ScEditUtil::GetEditArea( const ScPatternAttr* pPattern, sal_Bool bForceToTop ) diff --git a/sc/source/filter/xml/xmlexprt.cxx b/sc/source/filter/xml/xmlexprt.cxx index dd727ae..11ba412 100644 --- a/sc/source/filter/xml/xmlexprt.cxx +++ b/sc/source/filter/xml/xmlexprt.cxx @@ -2062,12 +2062,14 @@ void ScXMLExport::_ExportAutoStyles() if (pDoc->IsStreamValid(nTab)) { ScCellIterator aIter( pDoc, 0,0,nTab, MAXCOL,MAXROW,nTab ); - ScBaseCell* pCell = aIter.GetFirst(); - while (pCell) + for (bool bHas = aIter.first(); bHas; bHas = aIter.next()) { - if (pCell->GetCellType() == CELLTYPE_FORMULA) - static_cast<ScFormulaCell*>(pCell)->IsValue(); // interpret if dirty - pCell = aIter.GetNext(); + if (aIter.getType() != CELLTYPE_FORMULA) + continue; + + ScFormulaCell* pFC = aIter.getFormulaCell(); + if (pFC) + pFC->IsValue(); // interpret if dirty } } diff --git a/sc/source/ui/Accessibility/AccessibleCell.cxx b/sc/source/ui/Accessibility/AccessibleCell.cxx index 33a99a1..7eb84d5 100644 --- a/sc/source/ui/Accessibility/AccessibleCell.cxx +++ b/sc/source/ui/Accessibility/AccessibleCell.cxx @@ -367,11 +367,10 @@ void ScAccessibleCell::FillDependends(utl::AccessibleRelationSetHelper* pRelatio for (bool bHasCell = aCellIter.first(); bHasCell; bHasCell = aCellIter.next()) { - const ScCellValue& rVal = aCellIter.get(); - if (rVal.meType == CELLTYPE_FORMULA) + if (aCellIter.getType() == CELLTYPE_FORMULA) { bool bFound = false; - ScDetectiveRefIter aIter(rVal.mpFormula); + ScDetectiveRefIter aIter(aCellIter.getFormulaCell()); ScRange aRef; while ( !bFound && aIter.GetNextRef( aRef ) ) { diff --git a/sc/source/ui/docshell/dbdocfun.cxx b/sc/source/ui/docshell/dbdocfun.cxx index 6e91815..6e4ca2b 100644 --- a/sc/source/ui/docshell/dbdocfun.cxx +++ b/sc/source/ui/docshell/dbdocfun.cxx @@ -1180,7 +1180,7 @@ bool lcl_EmptyExcept( ScDocument* pDoc, const ScRange& rRange, const ScRange& rE ScCellIterator aIter( pDoc, rRange ); for (bool bHasCell = aIter.first(); bHasCell; bHasCell = aIter.next()) { - if (!aIter.get().isEmpty()) // real content? + if (!aIter.isEmpty()) // real content? { if (!rExcept.In(aIter.GetPos())) return false; // cell found diff --git a/sc/source/ui/unoobj/cellsuno.cxx b/sc/source/ui/unoobj/cellsuno.cxx index 7bff6dd..2ff086f 100644 --- a/sc/source/ui/unoobj/cellsuno.cxx +++ b/sc/source/ui/unoobj/cellsuno.cxx @@ -3561,7 +3561,7 @@ uno::Reference<sheet::XSheetCellRanges> SAL_CALL ScCellRangesBase::queryEmptyCel for (bool bHasCell = aIter.first(); bHasCell; bHasCell = aIter.next()) { // Notizen zaehlen als nicht-leer - if (!aIter.get().isEmpty()) + if (!aIter.isEmpty()) aMarkData.SetMultiMarkArea(aIter.GetPos(), false); } } @@ -3597,8 +3597,7 @@ uno::Reference<sheet::XSheetCellRanges> SAL_CALL ScCellRangesBase::queryContentC for (bool bHasCell = aIter.first(); bHasCell; bHasCell = aIter.next()) { bool bAdd = false; - const ScCellValue& rVal = aIter.get(); - switch (rVal.meType) + switch (aIter.getType()) { case CELLTYPE_STRING: if ( nContentFlags & sheet::CellFlags::STRING ) @@ -3677,9 +3676,9 @@ uno::Reference<sheet::XSheetCellRanges> SAL_CALL ScCellRangesBase::queryFormulaC ScCellIterator aIter( pDoc, aRange ); for (bool bHasCell = aIter.first(); bHasCell; bHasCell = aIter.next()) { - if (aIter.get().meType == CELLTYPE_FORMULA) + if (aIter.getType() == CELLTYPE_FORMULA) { - ScFormulaCell* pFCell = aIter.get().mpFormula; + ScFormulaCell* pFCell = aIter.getFormulaCell(); bool bAdd = false; if (pFCell->GetErrCode()) { @@ -3737,7 +3736,7 @@ uno::Reference<sheet::XSheetCellRanges> ScCellRangesBase::QueryDifferences_Impl( ScCellIterator aCmpIter( pDoc, aCmpRange ); for (bool bHasCell = aCmpIter.first(); bHasCell; bHasCell = aCmpIter.next()) { - if (aCmpIter.get().meType != CELLTYPE_NOTE) + if (aCmpIter.getType() != CELLTYPE_NOTE) { SCCOLROW nCellPos = bColumnDiff ? static_cast<SCCOLROW>(aCmpIter.GetPos().Col()) : static_cast<SCCOLROW>(aCmpIter.GetPos().Row()); if (bColumnDiff) @@ -3778,17 +3777,13 @@ uno::Reference<sheet::XSheetCellRanges> ScCellRangesBase::QueryDifferences_Impl( ScCellIterator aIter( pDoc, aRange ); for (bool bHasCell = aIter.first(); bHasCell; bHasCell = aIter.next()) { - const ScCellValue& rCell = aIter.get(); - if (bColumnDiff) aCmpAddr = ScAddress( aIter.GetPos().Col(), nCmpPos, aIter.GetPos().Tab() ); else aCmpAddr = ScAddress( static_cast<SCCOL>(nCmpPos), aIter.GetPos().Row(), aIter.GetPos().Tab() ); - ScCellValue aOtherCell; - aOtherCell.assign(*pDoc, aCmpAddr); ScRange aOneRange(aIter.GetPos()); - if (!rCell.equalsWithoutFormat(aOtherCell)) + if (!aIter.equalsWithoutFormat(aCmpAddr)) aMarkData.SetMultiMarkArea( aOneRange ); else aMarkData.SetMultiMarkArea( aOneRange, false ); // deselect @@ -3868,11 +3863,10 @@ uno::Reference<sheet::XSheetCellRanges> SAL_CALL ScCellRangesBase::queryPreceden ScCellIterator aIter( pDoc, aRange ); for (bool bHasCell = aIter.first(); bHasCell; bHasCell = aIter.next()) { - const ScCellValue& rVal = aIter.get(); - if (rVal.meType != CELLTYPE_FORMULA) + if (aIter.getType() != CELLTYPE_FORMULA) continue; - ScDetectiveRefIter aRefIter(rVal.mpFormula); + ScDetectiveRefIter aRefIter(aIter.getFormulaCell()); ScRange aRefRange; while ( aRefIter.GetNextRef( aRefRange) ) { @@ -3917,12 +3911,11 @@ uno::Reference<sheet::XSheetCellRanges> SAL_CALL ScCellRangesBase::queryDependen ScCellIterator aCellIter( pDoc, 0,0, nTab, MAXCOL,MAXROW, nTab ); for (bool bHasCell = aCellIter.first(); bHasCell; bHasCell = aCellIter.next()) { - const ScCellValue& rVal = aCellIter.get(); - if (rVal.meType != CELLTYPE_FORMULA) + if (aCellIter.getType() != CELLTYPE_FORMULA) continue; bool bMark = false; - ScDetectiveRefIter aIter(rVal.mpFormula); + ScDetectiveRefIter aIter(aCellIter.getFormulaCell()); ScRange aRefRange; while ( aIter.GetNextRef( aRefRange) ) { _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits