[Libreoffice-commits] core.git: Branch 'feature/formula-core-rework' - sc/inc sc/source
Kohei Yoshida
kohei.yoshida at gmail.com
Fri Mar 22 16:50:39 PDT 2013
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.yoshida at 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) )
{
More information about the Libreoffice-commits
mailing list