[Libreoffice-commits] core.git: 4 commits - sc/inc sc/source
Kohei Yoshida
kohei.yoshida at gmail.com
Tue Mar 26 12:35:03 PDT 2013
sc/inc/cell.hxx | 1
sc/inc/cellvalue.hxx | 57 ++++++-
sc/inc/chgtrack.hxx | 3
sc/inc/column.hxx | 1
sc/inc/conditio.hxx | 9 -
sc/inc/dociter.hxx | 13 -
sc/inc/document.hxx | 11 +
sc/inc/table.hxx | 1
sc/inc/validat.hxx | 15 -
sc/source/core/data/cell.cxx | 3
sc/source/core/data/cellvalue.cxx | 309 ++++++++++++++++++++++++++++----------
sc/source/core/data/column3.cxx | 12 +
sc/source/core/data/conditio.cxx | 112 ++++++-------
sc/source/core/data/dociter.cxx | 194 +++++------------------
sc/source/core/data/documen4.cxx | 12 -
sc/source/core/data/document.cxx | 8
sc/source/core/data/fillinfo.cxx | 8
sc/source/core/data/table2.cxx | 7
sc/source/core/data/validat.cxx | 177 +++++----------------
sc/source/core/tool/chgtrack.cxx | 8
sc/source/core/tool/detfunc.cxx | 3
sc/source/core/tool/interpr1.cxx | 4
sc/source/core/tool/interpr5.cxx | 2
23 files changed, 517 insertions(+), 453 deletions(-)
New commits:
commit 5f5d2cb6d1363bd133053a7c035b6e0163ee4edc
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date: Tue Mar 26 15:04:25 2013 -0400
Make the conditional formatting code free of ScBaseCell.
Change-Id: I93f83a840874c973cdc0821ddeb1913be7f09767
diff --git a/sc/inc/cellvalue.hxx b/sc/inc/cellvalue.hxx
index 7998898..84127cd 100644
--- a/sc/inc/cellvalue.hxx
+++ b/sc/inc/cellvalue.hxx
@@ -80,9 +80,10 @@ struct SC_DLLPUBLIC ScCellValue
};
/**
- * This is very similar to ScCellValue, except that it points to the
+ * This is very similar to ScCellValue, except that it references the
* original value instead of copying it. As such, don't hold an instance of
- * this class any longer than necessary.
+ * this class any longer than necessary, and absolutely not after the
+ * original cell has been destroyed.
*/
struct SC_DLLPUBLIC ScRefCellValue
{
diff --git a/sc/inc/conditio.hxx b/sc/inc/conditio.hxx
index d5a55e3..8592bcb 100644
--- a/sc/inc/conditio.hxx
+++ b/sc/inc/conditio.hxx
@@ -35,10 +35,9 @@
#include <boost/ptr_container/ptr_vector.hpp>
#include <boost/scoped_ptr.hpp>
-class ScBaseCell;
class ScFormulaCell;
class ScTokenArray;
-
+class ScRefCellValue;
// nOptions Flags
#define SC_COND_NOBLANKS 1
@@ -196,7 +195,7 @@ public:
virtual void SetParent( ScConditionalFormat* pNew ) { pCondFormat = pNew; }
- bool IsCellValid( ScBaseCell* pCell, const ScAddress& rPos ) const;
+ bool IsCellValid( ScRefCellValue& rCell, const ScAddress& rPos ) const;
ScConditionMode GetOperation() const { return eOp; }
bool IsIgnoreBlank() const { return ( nOptions & SC_COND_NOBLANKS ) == 0; }
@@ -406,9 +405,9 @@ public:
const ScFormatEntry* GetEntry( sal_uInt16 nPos ) const;
- const rtl::OUString& GetCellStyle( ScBaseCell* pCell, const ScAddress& rPos ) const;
+ const OUString& GetCellStyle( ScRefCellValue& rCell, const ScAddress& rPos ) const;
- ScCondFormatData GetData( ScBaseCell* pCell, const ScAddress& rPos ) const;
+ ScCondFormatData GetData( ScRefCellValue& rCell, const ScAddress& rPos ) const;
bool EqualEntries( const ScConditionalFormat& r ) const;
diff --git a/sc/inc/validat.hxx b/sc/inc/validat.hxx
index 8c73b7d..85737a3 100644
--- a/sc/inc/validat.hxx
+++ b/sc/inc/validat.hxx
@@ -125,12 +125,11 @@ public:
@return true = rStrings has been filled with at least one entry. */
bool FillSelectionList(std::vector<ScTypedStrData>& rStrings, const ScAddress& rPos) const;
- // with string: during input, with cell: for detective / RC_FORCED
- sal_Bool IsDataValid( const String& rTest, const ScPatternAttr& rPattern,
- const ScAddress& rPos ) const;
- sal_Bool IsDataValid( ScBaseCell* pCell, const ScAddress& rPos ) const;
+ // with string: during input, with cell: for detective / RC_FORCED
+ bool IsDataValid(
+ const OUString& rTest, const ScPatternAttr& rPattern, const ScAddress& rPos ) const;
- bool IsDataValid( ScCellIterator& rIter ) const;
+ bool IsDataValid( ScRefCellValue& rCell, const ScAddress& rPos ) const;
// TRUE -> break
sal_Bool DoError( Window* pParent, const String& rInput, const ScAddress& rPos ) const;
@@ -160,14 +159,14 @@ private:
@param rMatch (out-param) the index of the first item that matched, -1 if nothing matched.
@return true = Cell range found, rRange is valid, or an error entry stuffed into the list if pCell==NULL. */
bool GetSelectionFromFormula(
- std::vector<ScTypedStrData>* pStrings, ScBaseCell* pCell, const ScAddress& rPos,
+ std::vector<ScTypedStrData>* pStrings, ScRefCellValue& rCell, const ScAddress& rPos,
const ScTokenArray& rTokArr, int& rMatch) const;
/** Tests, if pCell is equal to what the passed token array represents. */
- bool IsEqualToTokenArray( ScBaseCell* pCell, const ScAddress& rPos, const ScTokenArray& rTokArr ) const;
+ bool IsEqualToTokenArray( ScRefCellValue& rCell, const ScAddress& rPos, const ScTokenArray& rTokArr ) const;
/** Tests, if contents of pCell occur in cell range referenced by own formula, or in a string list. */
- bool IsListValid( ScBaseCell* pCell, const ScAddress& rPos ) const;
+ bool IsListValid( ScRefCellValue& rCell, const ScAddress& rPos ) const;
};
//
diff --git a/sc/source/core/data/cell.cxx b/sc/source/core/data/cell.cxx
index aa777e5..c34e55c 100644
--- a/sc/source/core/data/cell.cxx
+++ b/sc/source/core/data/cell.cxx
@@ -1688,7 +1688,8 @@ void ScFormulaCell::InterpretTail( ScInterpretTailParameter eTailParam )
if ( nValidation )
{
const ScValidationData* pData = pDocument->GetValidationEntry( nValidation );
- if ( pData && !pData->IsDataValid( this, aPos ) )
+ ScRefCellValue aTmpCell(this);
+ if ( pData && !pData->IsDataValid(aTmpCell, aPos))
pData->DoCalcError( this );
}
}
diff --git a/sc/source/core/data/conditio.cxx b/sc/source/core/data/conditio.cxx
index ae4a7e2..0ce3088 100644
--- a/sc/source/core/data/conditio.cxx
+++ b/sc/source/core/data/conditio.cxx
@@ -36,6 +36,8 @@
#include "stlpool.hxx"
#include "rangenam.hxx"
#include "colorscale.hxx"
+#include "cellvalue.hxx"
+#include "editutil.hxx"
using namespace formula;
//------------------------------------------------------------------------
@@ -731,47 +733,40 @@ void ScConditionEntry::Interpret( const ScAddress& rPos )
bFirstRun = false;
}
-static bool lcl_GetCellContent( ScBaseCell* pCell, bool bIsStr1, double& rArg, rtl::OUString& rArgStr )
+static bool lcl_GetCellContent( ScRefCellValue& rCell, bool bIsStr1, double& rArg, OUString& rArgStr )
{
+
+ if (rCell.isEmpty())
+ return !bIsStr1;
+
bool bVal = true;
- if ( pCell )
+ switch (rCell.meType)
{
- CellType eType = pCell->GetCellType();
- switch( eType )
+ case CELLTYPE_VALUE:
+ rArg = rCell.mfValue;
+ break;
+ case CELLTYPE_FORMULA:
{
- case CELLTYPE_VALUE:
- rArg = ((ScValueCell*)pCell)->GetValue();
- break;
- case CELLTYPE_FORMULA:
- {
- ScFormulaCell* pFCell = (ScFormulaCell*)pCell;
- bVal = pFCell->IsValue();
- if (bVal)
- rArg = pFCell->GetValue();
- else
- rArgStr = pFCell->GetString();
- }
- break;
- case CELLTYPE_STRING:
- case CELLTYPE_EDIT:
- bVal = false;
- if ( eType == CELLTYPE_STRING )
- rArgStr = ((ScStringCell*)pCell)->GetString();
- else
- rArgStr = ((ScEditCell*)pCell)->GetString();
- break;
-
- default:
- pCell = NULL; // Note-Zellen wie leere
- break;
+ bVal = rCell.mpFormula->IsValue();
+ if (bVal)
+ rArg = rCell.mpFormula->GetValue();
+ else
+ rArgStr = rCell.mpFormula->GetString();
}
+ break;
+ case CELLTYPE_STRING:
+ case CELLTYPE_EDIT:
+ bVal = false;
+ if (rCell.meType == CELLTYPE_STRING)
+ rArgStr = *rCell.mpString;
+ else if (rCell.mpEditText)
+ rArgStr = ScEditUtil::GetString(*rCell.mpEditText);
+ break;
+ default:
+ ;
}
- if( !pCell )
- if( bIsStr1 )
- bVal = false; // leere Zellen je nach Bedingung
-
return bVal;
}
@@ -803,23 +798,28 @@ void ScConditionEntry::FillCache() const
for( SCROW r = nRowStart; r <= nRow; r++ )
for( SCCOL c = nColStart; c <= nCol; c++ )
{
- double nVal = 0.0;
- ScBaseCell *pCell = NULL;
-
- mpDoc->GetCell( c, r, nTab, pCell );
- if( !pCell )
+ ScRefCellValue aCell;
+ aCell.assign(*mpDoc, ScAddress(c, r, nTab));
+ if (aCell.isEmpty())
continue;
- rtl::OUString aStr;
- if( !lcl_GetCellContent( pCell, false, nVal, aStr ) )
+ double nVal = 0.0;
+ OUString aStr;
+ if (!lcl_GetCellContent(aCell, false, nVal, aStr))
{
- std::pair<ScConditionEntryCache::StringCacheType::iterator, bool> aResult = mpCache->maStrings.insert(std::pair<rtl::OUString, sal_Int32>(aStr, static_cast<sal_Int32>(1)));
+ std::pair<ScConditionEntryCache::StringCacheType::iterator, bool> aResult =
+ mpCache->maStrings.insert(
+ ScConditionEntryCache::StringCacheType::value_type(aStr, 1));
+
if(!aResult.second)
aResult.first->second++;
}
else
{
- std::pair<ScConditionEntryCache::ValueCacheType::iterator, bool> aResult = mpCache->maValues.insert(std::pair<double, sal_Int32>(nVal, (sal_Int32)1));
+ std::pair<ScConditionEntryCache::ValueCacheType::iterator, bool> aResult =
+ mpCache->maValues.insert(
+ ScConditionEntryCache::ValueCacheType::value_type(nVal, 1));
+
if(!aResult.second)
aResult.first->second++;
@@ -978,17 +978,13 @@ bool ScConditionEntry::IsAboveAverage( double nArg, bool bEqual ) const
bool ScConditionEntry::IsError( const ScAddress& rPos ) const
{
- ScBaseCell* pCell = mpDoc->GetCell(rPos);
- if(!pCell)
- return false;
-
- switch(pCell->GetCellType())
+ switch (mpDoc->GetCellType(rPos))
{
case CELLTYPE_VALUE:
return false;
case CELLTYPE_FORMULA:
{
- ScFormulaCell* pFormulaCell = static_cast<ScFormulaCell*>(pCell);
+ ScFormulaCell* pFormulaCell = const_cast<ScFormulaCell*>(mpDoc->GetFormulaCell(rPos));
if(pFormulaCell->GetErrCode())
return true;
}
@@ -1267,13 +1263,13 @@ bool ScConditionEntry::IsValidStr( const rtl::OUString& rArg, const ScAddress& r
return bValid;
}
-bool ScConditionEntry::IsCellValid( ScBaseCell* pCell, const ScAddress& rPos ) const
+bool ScConditionEntry::IsCellValid( ScRefCellValue& rCell, const ScAddress& rPos ) const
{
((ScConditionEntry*)this)->Interpret(rPos); // Formeln auswerten
double nArg = 0.0;
rtl::OUString aArgStr;
- bool bVal = lcl_GetCellContent( pCell, bIsStr1, nArg, aArgStr );
+ bool bVal = lcl_GetCellContent( rCell, bIsStr1, nArg, aArgStr );
if (bVal)
return IsValid( nArg, rPos );
else
@@ -1651,12 +1647,14 @@ ScCondDateFormatEntry::ScCondDateFormatEntry( ScDocument* pDoc, const ScCondDate
bool ScCondDateFormatEntry::IsValid( const ScAddress& rPos ) const
{
- ScBaseCell* pBaseCell = mpDoc->GetCell( rPos );
+ CellType eCellType = mpDoc->GetCellType(rPos);
- if(!pBaseCell)
+ if (eCellType == CELLTYPE_NONE || eCellType == CELLTYPE_NOTE)
+ // empty cell.
return false;
- if(pBaseCell->GetCellType() != CELLTYPE_VALUE && pBaseCell->GetCellType() != CELLTYPE_FORMULA)
+ if (eCellType != CELLTYPE_VALUE && eCellType != CELLTYPE_FORMULA)
+ // non-numerical cell.
return false;
if( !mpCache )
@@ -1903,14 +1901,14 @@ const ScFormatEntry* ScConditionalFormat::GetEntry( sal_uInt16 nPos ) const
return NULL;
}
-const rtl::OUString& ScConditionalFormat::GetCellStyle( ScBaseCell* pCell, const ScAddress& rPos ) const
+const OUString& ScConditionalFormat::GetCellStyle( ScRefCellValue& rCell, const ScAddress& rPos ) const
{
for (CondFormatContainer::const_iterator itr = maEntries.begin(); itr != maEntries.end(); ++itr)
{
if(itr->GetType() == condformat::CONDITION)
{
const ScCondFormatEntry& rEntry = static_cast<const ScCondFormatEntry&>(*itr);
- if ( rEntry.IsCellValid( pCell, rPos ) )
+ if (rEntry.IsCellValid(rCell, rPos))
return rEntry.GetStyle();
}
else if(itr->GetType() == condformat::DATE)
@@ -1924,7 +1922,7 @@ const rtl::OUString& ScConditionalFormat::GetCellStyle( ScBaseCell* pCell, const
return EMPTY_OUSTRING;
}
-ScCondFormatData ScConditionalFormat::GetData( ScBaseCell* pCell, const ScAddress& rPos ) const
+ScCondFormatData ScConditionalFormat::GetData( ScRefCellValue& rCell, const ScAddress& rPos ) const
{
ScCondFormatData aData;
for(CondFormatContainer::const_iterator itr = maEntries.begin(); itr != maEntries.end(); ++itr)
@@ -1932,7 +1930,7 @@ ScCondFormatData ScConditionalFormat::GetData( ScBaseCell* pCell, const ScAddres
if(itr->GetType() == condformat::CONDITION && aData.aStyleName.isEmpty())
{
const ScCondFormatEntry& rEntry = static_cast<const ScCondFormatEntry&>(*itr);
- if ( rEntry.IsCellValid( pCell, rPos ) )
+ if (rEntry.IsCellValid(rCell, rPos))
aData.aStyleName = rEntry.GetStyle();
}
else if(itr->GetType() == condformat::COLORSCALE && !aData.pColorScale)
diff --git a/sc/source/core/data/documen4.cxx b/sc/source/core/data/documen4.cxx
index aad3f4f..3df2fbc 100644
--- a/sc/source/core/data/documen4.cxx
+++ b/sc/source/core/data/documen4.cxx
@@ -631,8 +631,10 @@ const SfxPoolItem* ScDocument::GetEffItem(
const ScConditionalFormat* pForm = pCondFormList->GetFormat( *itr );
if ( pForm )
{
- ScBaseCell* pCell = ((ScDocument*)this)->GetCell(ScAddress(nCol,nRow,nTab));
- rtl::OUString aStyle = pForm->GetCellStyle( pCell, ScAddress(nCol, nRow, nTab) );
+ ScAddress aPos(nCol, nRow, nTab);
+ ScRefCellValue aCell;
+ aCell.assign(const_cast<ScDocument&>(*this), aPos);
+ rtl::OUString aStyle = pForm->GetCellStyle(aCell, aPos);
if (!aStyle.isEmpty())
{
SfxStyleSheetBase* pStyleSheet = xPoolHelper->GetStylePool()->Find(
@@ -663,8 +665,10 @@ const SfxItemSet* ScDocument::GetCondResult( SCCOL nCol, SCROW nRow, SCTAB nTab
if(!pForm)
continue;
- ScBaseCell* pCell = ((ScDocument*)this)->GetCell(ScAddress(nCol,nRow,nTab));
- rtl::OUString aStyle = pForm->GetCellStyle( pCell, ScAddress(nCol, nRow, nTab) );
+ ScAddress aPos(nCol, nRow, nTab);
+ ScRefCellValue aCell;
+ aCell.assign(const_cast<ScDocument&>(*this), aPos);
+ const OUString& aStyle = pForm->GetCellStyle(aCell, aPos);
if (!aStyle.isEmpty())
{
SfxStyleSheetBase* pStyleSheet = xPoolHelper->GetStylePool()->Find( aStyle, SFX_STYLE_FAMILY_PARA );
diff --git a/sc/source/core/data/fillinfo.cxx b/sc/source/core/data/fillinfo.cxx
index f0d4cb4..f7366cd 100644
--- a/sc/source/core/data/fillinfo.cxx
+++ b/sc/source/core/data/fillinfo.cxx
@@ -39,6 +39,7 @@
#include "conditio.hxx"
#include "colorscale.hxx"
#include "stlpool.hxx"
+#include "cellvalue.hxx"
#include <iostream>
@@ -520,8 +521,11 @@ void ScDocument::FillInfo( ScTableInfo& rTabInfo, SCCOL nX1, SCROW nY1, SCCOL nX
if(!pCondForm)
continue;
- ScCondFormatData aData = pCondForm->GetData( pInfo->pCell,
- ScAddress( nX, nCurRow, nTab ) );
+ ScRefCellValue aTmpCell;
+ if (pInfo->pCell)
+ aTmpCell.assign(*pInfo->pCell);
+ ScCondFormatData aData = pCondForm->GetData(
+ aTmpCell, ScAddress(nX, nCurRow, nTab));
if (!aData.aStyleName.isEmpty())
{
SfxStyleSheetBase* pStyleSheet =
diff --git a/sc/source/core/data/validat.cxx b/sc/source/core/data/validat.cxx
index a2d4b4a..cff7da7 100644
--- a/sc/source/core/data/validat.cxx
+++ b/sc/source/core/data/validat.cxx
@@ -41,6 +41,7 @@
#include "dbdata.hxx"
#include "typedstrdata.hxx"
#include "dociter.hxx"
+#include "editutil.hxx"
#include <math.h>
#include <memory>
@@ -414,18 +415,19 @@ sal_Bool ScValidationData::DoError( Window* pParent, const String& rInput,
}
-sal_Bool ScValidationData::IsDataValid( const String& rTest, const ScPatternAttr& rPattern,
- const ScAddress& rPos ) const
+bool ScValidationData::IsDataValid(
+ const OUString& rTest, const ScPatternAttr& rPattern, const ScAddress& rPos ) const
{
if ( eDataMode == SC_VALID_ANY ) // check if any cell content is allowed
return sal_True;
- if ( rTest.GetChar(0) == '=' ) // formulas do not pass the validity test
- return sal_False;
-
- if ( !rTest.Len() ) // check whether empty cells are allowed
+ if (rTest.isEmpty()) // check whether empty cells are allowed
return IsIgnoreBlank();
+ if (rTest[0] == '=') // formulas do not pass the validity test
+ return false;
+
+
SvNumberFormatter* pFormatter = GetDocument()->GetFormatTable();
// get the value if any
@@ -438,7 +440,7 @@ sal_Bool ScValidationData::IsDataValid( const String& rTest, const ScPatternAttr
{
double nLenVal;
if (!bIsVal)
- nLenVal = static_cast<double>( rTest.Len() );
+ nLenVal = static_cast<double>(rTest.getLength());
else
{
// For numeric values use the resulting input line string to
@@ -449,133 +451,55 @@ sal_Bool ScValidationData::IsDataValid( const String& rTest, const ScPatternAttr
pFormatter->GetInputLineString( nVal, nFormat, aStr);
nLenVal = static_cast<double>( aStr.Len() );
}
- ScValueCell aTmpCell( nLenVal );
- bRet = IsCellValid( &aTmpCell, rPos );
+ ScRefCellValue aTmpCell(nLenVal);
+ bRet = IsCellValid(aTmpCell, rPos);
}
else
{
if (bIsVal)
{
- ScValueCell aTmpCell( nVal );
- bRet = IsDataValid( &aTmpCell, rPos );
+ ScRefCellValue aTmpCell(nVal);
+ bRet = IsDataValid(aTmpCell, rPos);
}
else
{
- ScStringCell aTmpCell( rTest );
- bRet = IsDataValid( &aTmpCell, rPos );
+ ScRefCellValue aTmpCell(&rTest);
+ bRet = IsDataValid(aTmpCell, rPos);
}
}
return bRet;
}
-sal_Bool ScValidationData::IsDataValid( ScBaseCell* pCell, const ScAddress& rPos ) const
+bool ScValidationData::IsDataValid( ScRefCellValue& rCell, const ScAddress& rPos ) const
{
if( eDataMode == SC_VALID_LIST )
- return IsListValid( pCell, rPos );
+ return IsListValid(rCell, rPos);
double nVal = 0.0;
- String aString;
- sal_Bool bIsVal = sal_True;
-
- switch (pCell->GetCellType())
- {
- case CELLTYPE_VALUE:
- nVal = ((ScValueCell*)pCell)->GetValue();
- break;
- case CELLTYPE_STRING:
- aString = ((ScStringCell*)pCell)->GetString();
- bIsVal = false;
- break;
- case CELLTYPE_EDIT:
- aString = ((ScEditCell*)pCell)->GetString();
- bIsVal = false;
- break;
- case CELLTYPE_FORMULA:
- {
- ScFormulaCell* pFCell = (ScFormulaCell*)pCell;
- bIsVal = pFCell->IsValue();
- if ( bIsVal )
- nVal = pFCell->GetValue();
- else
- aString = pFCell->GetString();
- }
- break;
- default: // Notizen, Broadcaster
- return IsIgnoreBlank(); // wie eingestellt
- }
-
- sal_Bool bOk = sal_True;
- switch (eDataMode)
- {
- // SC_VALID_ANY schon oben
-
- case SC_VALID_WHOLE:
- case SC_VALID_DECIMAL:
- case SC_VALID_DATE: // Date/Time ist nur Formatierung
- case SC_VALID_TIME:
- bOk = bIsVal;
- if ( bOk && eDataMode == SC_VALID_WHOLE )
- bOk = ::rtl::math::approxEqual( nVal, floor(nVal+0.5) ); // ganze Zahlen
- if ( bOk )
- bOk = IsCellValid( pCell, rPos );
- break;
-
- case SC_VALID_CUSTOM:
- // fuer Custom muss eOp == SC_COND_DIRECT sein
- //! der Wert muss im Dokument stehen !!!!!!!!!!!!!!!!!!!!
- bOk = IsCellValid( pCell, rPos );
- break;
-
- case SC_VALID_TEXTLEN:
- bOk = !bIsVal; // nur Text
- if ( bOk )
- {
- double nLenVal = (double) aString.Len();
- ScValueCell* pTmpCell = new ScValueCell( nLenVal );
- bOk = IsCellValid( pTmpCell, rPos );
- pTmpCell->Delete();
- }
- break;
-
- default:
- OSL_FAIL("not yet done");
- break;
- }
-
- return bOk;
-}
-
-bool ScValidationData::IsDataValid( ScCellIterator& rIter ) const
-{
- const ScAddress& rPos = rIter.GetPos();
-
- if( eDataMode == SC_VALID_LIST )
- {
- ScBaseCell* pBC = rIter.getHackedBaseCell();
- return IsListValid(pBC, rPos);
- }
-
- double fVal = 0.0;
OUString aString;
bool bIsVal = true;
- switch (rIter.getType())
+ switch (rCell.meType)
{
case CELLTYPE_VALUE:
- fVal = rIter.getValue();
- break;
+ nVal = rCell.mfValue;
+ break;
case CELLTYPE_STRING:
+ aString = *rCell.mpString;
+ bIsVal = false;
+ break;
case CELLTYPE_EDIT:
- aString = rIter.getString();
+ if (rCell.mpEditText)
+ aString = ScEditUtil::GetString(*rCell.mpEditText);
bIsVal = false;
- break;
+ break;
case CELLTYPE_FORMULA:
{
- ScFormulaCell* pFCell = rIter.getFormulaCell();
+ ScFormulaCell* pFCell = rCell.mpFormula;
bIsVal = pFCell->IsValue();
if ( bIsVal )
- fVal = pFCell->GetValue();
+ nVal = pFCell->GetValue();
else
aString = pFCell->GetString();
}
@@ -595,30 +519,24 @@ bool ScValidationData::IsDataValid( ScCellIterator& rIter ) const
case SC_VALID_TIME:
bOk = bIsVal;
if ( bOk && eDataMode == SC_VALID_WHOLE )
- bOk = ::rtl::math::approxEqual( fVal, floor(fVal+0.5) ); // ganze Zahlen
+ bOk = ::rtl::math::approxEqual( nVal, floor(nVal+0.5) ); // ganze Zahlen
if ( bOk )
- {
- ScBaseCell* pBC = rIter.getHackedBaseCell();
- bOk = IsCellValid(pBC, rPos);
- }
+ bOk = IsCellValid(rCell, rPos);
break;
case SC_VALID_CUSTOM:
- {
// fuer Custom muss eOp == SC_COND_DIRECT sein
//! der Wert muss im Dokument stehen !!!!!!!!!!!!!!!!!!!!
- ScBaseCell* pBC = rIter.getHackedBaseCell();
- bOk = IsCellValid(pBC, rPos);
- }
- break;
+ bOk = IsCellValid(rCell, rPos);
+ break;
+
case SC_VALID_TEXTLEN:
bOk = !bIsVal; // nur Text
if ( bOk )
{
double nLenVal = (double) aString.getLength();
- ScValueCell* pTmpCell = new ScValueCell( nLenVal );
- bOk = IsCellValid( pTmpCell, rPos );
- pTmpCell->Delete();
+ ScRefCellValue aTmpCell(nLenVal);
+ bOk = IsCellValid(aTmpCell, rPos);
}
break;
@@ -630,8 +548,6 @@ bool ScValidationData::IsDataValid( ScCellIterator& rIter ) const
return bOk;
}
-// ----------------------------------------------------------------------------
-
namespace {
/** Token array helper. Iterates over all string tokens.
@@ -701,7 +617,7 @@ bool ScValidationData::HasSelectionList() const
}
bool ScValidationData::GetSelectionFromFormula(
- std::vector<ScTypedStrData>* pStrings, ScBaseCell* pCell, const ScAddress& rPos,
+ std::vector<ScTypedStrData>* pStrings, ScRefCellValue& rCell, const ScAddress& rPos,
const ScTokenArray& rTokArr, int& rMatch) const
{
bool bOk = true;
@@ -816,7 +732,7 @@ bool ScValidationData::GetSelectionFromFormula(
if( NULL != pStrings )
pEntry = new ScTypedStrData( aValStr, 0.0, ScTypedStrData::Standard);
- if( pCell && rMatch < 0 )
+ if (!rCell.isEmpty() && rMatch < 0)
aCondTokArr.AddString( aValStr );
}
else
@@ -842,7 +758,7 @@ bool ScValidationData::GetSelectionFromFormula(
pFormatter->GetInputLineString( nMatVal.fVal, 0, aValStr );
}
- if( pCell && rMatch < 0 )
+ if (!rCell.isEmpty() && rMatch < 0)
{
// I am not sure errors will work here, but a user can no
// manually enter an error yet so the point is somewhat moot.
@@ -852,7 +768,7 @@ bool ScValidationData::GetSelectionFromFormula(
pEntry = new ScTypedStrData( aValStr, nMatVal.fVal, ScTypedStrData::Value);
}
- if( rMatch < 0 && NULL != pCell && IsEqualToTokenArray( pCell, rPos, aCondTokArr ) )
+ if (rMatch < 0 && !rCell.isEmpty() && IsEqualToTokenArray(rCell, rPos, aCondTokArr))
{
rMatch = n;
// short circuit on the first match if not filling the list
@@ -871,7 +787,7 @@ bool ScValidationData::GetSelectionFromFormula(
// In case of no match needed and an error occurred, return that error
// entry as valid instead of silently failing.
- return bOk || NULL == pCell;
+ return bOk || rCell.isEmpty();
}
bool ScValidationData::FillSelectionList(std::vector<ScTypedStrData>& rStrColl, const ScAddress& rPos) const
@@ -902,7 +818,8 @@ bool ScValidationData::FillSelectionList(std::vector<ScTypedStrData>& rStrColl,
if (!bOk)
{
int nMatch;
- bOk = GetSelectionFromFormula( &rStrColl, NULL, rPos, *pTokArr, nMatch );
+ ScRefCellValue aEmptyCell;
+ bOk = GetSelectionFromFormula(&rStrColl, aEmptyCell, rPos, *pTokArr, nMatch);
}
}
@@ -911,14 +828,14 @@ bool ScValidationData::FillSelectionList(std::vector<ScTypedStrData>& rStrColl,
// ----------------------------------------------------------------------------
-bool ScValidationData::IsEqualToTokenArray( ScBaseCell* pCell, const ScAddress& rPos, const ScTokenArray& rTokArr ) const
+bool ScValidationData::IsEqualToTokenArray( ScRefCellValue& rCell, const ScAddress& rPos, const ScTokenArray& rTokArr ) const
{
// create a condition entry that tests on equality and set the passed token array
ScConditionEntry aCondEntry( SC_COND_EQUAL, &rTokArr, NULL, GetDocument(), rPos );
- return aCondEntry.IsCellValid( pCell, rPos );
+ return aCondEntry.IsCellValid(rCell, rPos);
}
-bool ScValidationData::IsListValid( ScBaseCell* pCell, const ScAddress& rPos ) const
+bool ScValidationData::IsListValid( ScRefCellValue& rCell, const ScAddress& rPos ) const
{
bool bIsValid = false;
@@ -955,7 +872,7 @@ bool ScValidationData::IsListValid( ScBaseCell* pCell, const ScAddress& rPos ) c
else
aCondTokArr.AddString( *pString );
- bIsValid = IsEqualToTokenArray( pCell, rPos, aCondTokArr );
+ bIsValid = IsEqualToTokenArray(rCell, rPos, aCondTokArr);
}
}
@@ -968,7 +885,7 @@ bool ScValidationData::IsListValid( ScBaseCell* pCell, const ScAddress& rPos ) c
if (!bIsValid)
{
int nMatch;
- bIsValid = GetSelectionFromFormula( NULL, pCell, rPos, *pTokArr, nMatch );
+ bIsValid = GetSelectionFromFormula(NULL, rCell, rPos, *pTokArr, nMatch);
bIsValid = bIsValid && nMatch >= 0;
}
diff --git a/sc/source/core/tool/detfunc.cxx b/sc/source/core/tool/detfunc.cxx
index 7aad0cc..958162f 100644
--- a/sc/source/core/tool/detfunc.cxx
+++ b/sc/source/core/tool/detfunc.cxx
@@ -1366,7 +1366,8 @@ sal_Bool ScDetectiveFunc::MarkInvalid(sal_Bool& rOverflow)
DrawCircle( nCol, nRow, aData );
++nInsCount;
}
- if (!pData->IsDataValid(aCellIter))
+ ScRefCellValue aCell = aCellIter.getRefCellValue();
+ if (!pData->IsDataValid(aCell, aCellIter.GetPos()))
{
DrawCircle( nCol, nCellRow, aData );
++nInsCount;
commit 7c2dd80cbee59aadee20b59aacdf0ba437c765db
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date: Tue Mar 26 12:35:36 2013 -0400
By using ScRefCellValue we can remove some duplicated code.
Change-Id: I75652172033e4ce00ac239e85d835c7cc9256fe2
diff --git a/sc/inc/chgtrack.hxx b/sc/inc/chgtrack.hxx
index b30cf1b..6b06c22 100644
--- a/sc/inc/chgtrack.hxx
+++ b/sc/inc/chgtrack.hxx
@@ -37,7 +37,6 @@
class ScDocument;
class ScFormulaCell;
-class ScCellIterator;
enum ScChangeActionType
{
@@ -800,7 +799,7 @@ public:
rtl::OUString& rStr, ScDocument* pDoc, bool bFlag3D = false ) const;
static ScChangeActionContentCellType GetContentCellType( const ScCellValue& rCell );
- static ScChangeActionContentCellType GetContentCellType( const ScCellIterator& rIter );
+ static ScChangeActionContentCellType GetContentCellType( const ScRefCellValue& rIter );
// NewCell
bool IsMatrixOrigin() const;
diff --git a/sc/inc/dociter.hxx b/sc/inc/dociter.hxx
index 58d1215..4f3ab26 100644
--- a/sc/inc/dociter.hxx
+++ b/sc/inc/dociter.hxx
@@ -24,6 +24,7 @@
#include <tools/solar.h>
#include "global.hxx"
#include "scdllapi.h"
+#include "cellvalue.hxx"
#include <memory>
@@ -45,7 +46,6 @@ struct ScQueryParam;
struct ScDBQueryParamInternal;
struct ScDBQueryParamMatrix;
class ScFormulaCell;
-struct ScCellValue;
class ScDocumentIterator // walk through all non-empty cells
{
@@ -222,13 +222,7 @@ private:
SCSIZE mnIndex;
bool mbSubTotal;
- CellType meCurType;
- OUString maCurString;
- union {
- double mfCurValue;
- const EditTextObject* mpCurEditText; // points to the original.
- ScFormulaCell* mpCurFormula; // points to the original.
- };
+ ScRefCellValue maCurCell;
void init();
bool getCurrent();
@@ -245,9 +239,11 @@ public:
const ScFormulaCell* getFormulaCell() const;
double getValue() const;
ScCellValue getCellValue() const;
+ ScRefCellValue getRefCellValue() const;
bool hasString() const;
bool hasNumeric() const;
+ bool hasEmptyData() const;
bool isEmpty() const;
bool equalsWithoutFormat( const ScAddress& rPos ) const;
diff --git a/sc/source/core/data/dociter.cxx b/sc/source/core/data/dociter.cxx
index 9f7dd02..adb7787 100644
--- a/sc/source/core/data/dociter.cxx
+++ b/sc/source/core/data/dociter.cxx
@@ -943,9 +943,7 @@ ScCellIterator::ScCellIterator( ScDocument* pDoc, const ScRange& rRange, bool bS
maStartPos(rRange.aStart),
maEndPos(rRange.aEnd),
mnIndex(0),
- mbSubTotal(bSTotal),
- meCurType(CELLTYPE_NONE),
- mfCurValue(0.0)
+ mbSubTotal(bSTotal)
{
init();
}
@@ -996,7 +994,7 @@ bool ScCellIterator::getCurrent()
maCurPos.IncTab();
if (maCurPos.Tab() > maEndPos.Tab())
{
- meCurType = CELLTYPE_NONE;
+ maCurCell.clear();
return false; // Over and out
}
}
@@ -1021,26 +1019,26 @@ bool ScCellIterator::getCurrent()
else
{
// Found it!
- meCurType = pCell->GetCellType();
- switch (meCurType)
+ maCurCell.meType = pCell->GetCellType();
+ switch (maCurCell.meType)
{
case CELLTYPE_VALUE:
- mfCurValue = static_cast<const ScValueCell*>(pCell)->GetValue();
+ maCurCell.mfValue = static_cast<const ScValueCell*>(pCell)->GetValue();
break;
case CELLTYPE_STRING:
- maCurString = static_cast<const ScStringCell*>(pCell)->GetString();
+ maCurCell.mpString = static_cast<const ScStringCell*>(pCell)->GetStringPtr();
break;
case CELLTYPE_EDIT:
- mpCurEditText = static_cast<const ScEditCell*>(pCell)->GetData();
+ maCurCell.mpEditText = static_cast<const ScEditCell*>(pCell)->GetData();
break;
case CELLTYPE_FORMULA:
- mpCurFormula = static_cast<ScFormulaCell*>(pCell);
+ maCurCell.mpFormula = static_cast<ScFormulaCell*>(pCell);
break;
default:
- meCurType = CELLTYPE_NONE;
+ maCurCell.meType = CELLTYPE_NONE;
}
- if (meCurType != CELLTYPE_NONE)
+ if (maCurCell.meType != CELLTYPE_NONE)
return true;
maCurPos.IncRow();
@@ -1057,21 +1055,21 @@ bool ScCellIterator::getCurrent()
CellType ScCellIterator::getType() const
{
- return meCurType;
+ return maCurCell.meType;
}
OUString ScCellIterator::getString()
{
- switch (meCurType)
+ switch (maCurCell.meType)
{
case CELLTYPE_STRING:
- return maCurString;
+ return *maCurCell.mpString;
case CELLTYPE_EDIT:
- if (mpCurEditText)
- return ScEditUtil::GetString(*mpCurEditText);
+ if (maCurCell.mpEditText)
+ return ScEditUtil::GetString(*maCurCell.mpEditText);
break;
case CELLTYPE_FORMULA:
- return mpCurFormula->GetString();
+ return maCurCell.mpFormula->GetString();
default:
;
}
@@ -1080,27 +1078,27 @@ OUString ScCellIterator::getString()
const EditTextObject* ScCellIterator::getEditText() const
{
- return mpCurEditText;
+ return maCurCell.mpEditText;
}
ScFormulaCell* ScCellIterator::getFormulaCell()
{
- return mpCurFormula;
+ return maCurCell.mpFormula;
}
const ScFormulaCell* ScCellIterator::getFormulaCell() const
{
- return mpCurFormula;
+ return maCurCell.mpFormula;
}
double ScCellIterator::getValue() const
{
- switch (meCurType)
+ switch (maCurCell.meType)
{
case CELLTYPE_VALUE:
- return mfCurValue;
+ return maCurCell.mfValue;
case CELLTYPE_FORMULA:
- return mpCurFormula->GetValue();
+ return maCurCell.mpFormula->GetValue();
default:
;
}
@@ -1110,21 +1108,21 @@ double ScCellIterator::getValue() const
ScCellValue ScCellIterator::getCellValue() const
{
ScCellValue aRet;
- aRet.meType = meCurType;
+ aRet.meType = maCurCell.meType;
- switch (meCurType)
+ switch (maCurCell.meType)
{
case CELLTYPE_STRING:
- aRet.mpString = new OUString(maCurString);
+ aRet.mpString = new OUString(*maCurCell.mpString);
break;
case CELLTYPE_EDIT:
- aRet.mpEditText = mpCurEditText->Clone();
+ aRet.mpEditText = maCurCell.mpEditText->Clone();
break;
case CELLTYPE_VALUE:
- aRet.mfValue = mfCurValue;
+ aRet.mfValue = maCurCell.mfValue;
break;
case CELLTYPE_FORMULA:
- aRet.mpFormula = mpCurFormula->Clone();
+ aRet.mpFormula = maCurCell.mpFormula->Clone();
break;
default:
;
@@ -1133,133 +1131,42 @@ ScCellValue ScCellIterator::getCellValue() const
return aRet;
}
-bool ScCellIterator::hasString() const
+ScRefCellValue ScCellIterator::getRefCellValue() const
{
- switch (meCurType)
- {
- case CELLTYPE_STRING:
- case CELLTYPE_EDIT:
- return true;
- case CELLTYPE_FORMULA:
- return !mpCurFormula->IsValue();
- default:
- ;
- }
+ return maCurCell;
+}
- return false;
+bool ScCellIterator::hasString() const
+{
+ return maCurCell.hasString();
}
bool ScCellIterator::hasNumeric() const
{
- switch (meCurType)
- {
- case CELLTYPE_VALUE:
- return true;
- case CELLTYPE_FORMULA:
- return mpCurFormula->IsValue();
- default:
- ;
- }
-
- return false;
+ return maCurCell.hasNumeric();
}
-bool ScCellIterator::isEmpty() const
+bool ScCellIterator::hasEmptyData() const
{
- switch (meCurType)
- {
- case CELLTYPE_NOTE:
- case CELLTYPE_NONE:
- return true;
- case CELLTYPE_FORMULA:
- return mpCurFormula->IsEmpty();
- default:
- ;
- }
- return false;
-}
+ if (maCurCell.isEmpty())
+ return true;
-namespace {
+ if (maCurCell.meType == CELLTYPE_FORMULA)
+ return maCurCell.mpFormula->IsEmpty();
-CellType adjustCellType( CellType eOrig )
-{
- switch (eOrig)
- {
- case CELLTYPE_NOTE:
- return CELLTYPE_NONE;
- case CELLTYPE_EDIT:
- return CELLTYPE_STRING;
- default:
- ;
- }
- return eOrig;
+ return false;
}
+bool ScCellIterator::isEmpty() const
+{
+ return maCurCell.isEmpty();
}
bool ScCellIterator::equalsWithoutFormat( const ScAddress& rPos ) const
{
- // Fetch the other cell first.
- if (!mpDoc->TableExists(rPos.Tab()))
- return false;
-
- ScTable& rTab = *mpDoc->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;
+ ScRefCellValue aOther;
+ aOther.assign(*mpDoc, rPos);
+ return maCurCell.equalsWithoutFormat(aOther);
}
bool ScCellIterator::first()
diff --git a/sc/source/core/tool/chgtrack.cxx b/sc/source/core/tool/chgtrack.cxx
index b1b683c..b5ce9c9 100644
--- a/sc/source/core/tool/chgtrack.cxx
+++ b/sc/source/core/tool/chgtrack.cxx
@@ -1750,9 +1750,9 @@ ScChangeActionContentCellType ScChangeActionContent::GetContentCellType( const S
}
}
-ScChangeActionContentCellType ScChangeActionContent::GetContentCellType( const ScCellIterator& rIter )
+ScChangeActionContentCellType ScChangeActionContent::GetContentCellType( const ScRefCellValue& rCell )
{
- switch (rIter.getType())
+ switch (rCell.meType)
{
case CELLTYPE_VALUE:
case CELLTYPE_STRING:
@@ -1760,7 +1760,7 @@ ScChangeActionContentCellType ScChangeActionContent::GetContentCellType( const S
return SC_CACCT_NORMAL;
case CELLTYPE_FORMULA:
{
- const ScFormulaCell* pCell = rIter.getFormulaCell();
+ const ScFormulaCell* pCell = rCell.mpFormula;
switch (pCell->GetMatrixFlag())
{
case MM_NONE :
@@ -2676,7 +2676,7 @@ void ScChangeTrack::LookUpContents( const ScRange& rOrgRange,
ScCellIterator aIter( pRefDoc, rOrgRange );
for (bool bHas = aIter.first(); bHas; bHas = aIter.next())
{
- if (!ScChangeActionContent::GetContentCellType(aIter))
+ if (!ScChangeActionContent::GetContentCellType(aIter.getRefCellValue()))
continue;
aBigPos.Set( aIter.GetPos().Col() + nDx, aIter.GetPos().Row() + nDy,
diff --git a/sc/source/core/tool/interpr1.cxx b/sc/source/core/tool/interpr1.cxx
index 1b598cf..574612c 100644
--- a/sc/source/core/tool/interpr1.cxx
+++ b/sc/source/core/tool/interpr1.cxx
@@ -4156,7 +4156,7 @@ double ScInterpreter::IterateParameters( ScIterFunc eFunc, bool bTextAsZero )
ScCellIterator aIter( pDok, aRange, glSubTotal );
for (bool bHas = aIter.first(); bHas; bHas = aIter.next())
{
- if (!aIter.isEmpty())
+ if (!aIter.hasEmptyData())
++nCount;
}
@@ -5372,7 +5372,7 @@ void ScInterpreter::ScCountEmptyCells()
ScCellIterator aIter( pDok, aRange, glSubTotal);
for (bool bHas = aIter.first(); bHas; bHas = aIter.next())
{
- if (!aIter.isEmpty())
+ if (!aIter.hasEmptyData())
++nCount;
}
}
diff --git a/sc/source/core/tool/interpr5.cxx b/sc/source/core/tool/interpr5.cxx
index 8574490..a9a432c 100644
--- a/sc/source/core/tool/interpr5.cxx
+++ b/sc/source/core/tool/interpr5.cxx
@@ -428,7 +428,7 @@ ScMatrixRef ScInterpreter::CreateMatrixFromDoubleRef( const FormulaToken* pToken
{
nThisRow = aCellIter.GetPos().Row();
- if (aCellIter.isEmpty())
+ if (aCellIter.hasEmptyData())
{
aBucket.flush(*pMat, static_cast<SCSIZE>(nCol-nCol1));
continue;
commit 0b0e7ca9b3bae3b3295da33e5980f3f4c6a5f532
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date: Tue Mar 26 12:00:43 2013 -0400
Add ScRefCellValue, which is ScCellValue without copied value.
It directly points to the original cell value instance.
Change-Id: I638ec8b931873d237871b6d8fa9f0e1277520d0f
diff --git a/sc/inc/cell.hxx b/sc/inc/cell.hxx
index 236ad43..0b78f98 100644
--- a/sc/inc/cell.hxx
+++ b/sc/inc/cell.hxx
@@ -175,6 +175,7 @@ public:
inline void SetString( const rtl::OUString& rString ) { maString = rString; }
inline const rtl::OUString& GetString() const { return maString; }
+ const OUString* GetStringPtr() const { return &maString; }
private:
rtl::OUString maString;
diff --git a/sc/inc/cellvalue.hxx b/sc/inc/cellvalue.hxx
index 9dd3a9a..7998898 100644
--- a/sc/inc/cellvalue.hxx
+++ b/sc/inc/cellvalue.hxx
@@ -19,7 +19,8 @@ class ScBaseCell;
/**
* Store arbitrary cell value of any kind. It only stores cell value and
- * nothing else.
+ * nothing else. It creates a copy of the original cell value, and manages
+ * the life cycle of the copied value.
*/
struct SC_DLLPUBLIC ScCellValue
{
@@ -78,6 +79,59 @@ struct SC_DLLPUBLIC ScCellValue
void swap( ScCellValue& r );
};
+/**
+ * This is very similar to ScCellValue, except that it points to the
+ * original value instead of copying it. As such, don't hold an instance of
+ * this class any longer than necessary.
+ */
+struct SC_DLLPUBLIC ScRefCellValue
+{
+ CellType meType;
+ union {
+ double mfValue;
+ const OUString* mpString;
+ const EditTextObject* mpEditText;
+ ScFormulaCell* mpFormula;
+ };
+
+ ScRefCellValue();
+ ScRefCellValue( double fValue );
+ ScRefCellValue( const OUString* pString );
+ ScRefCellValue( const EditTextObject* pEditText );
+ ScRefCellValue( ScFormulaCell* pFormula );
+ ScRefCellValue( const ScRefCellValue& r );
+ ~ScRefCellValue();
+
+ void clear();
+
+ /**
+ * Take cell value from specified position in specified document.
+ */
+ void assign( ScDocument& rDoc, const ScAddress& rPos );
+
+ /**
+ * TODO: Remove this later.
+ */
+ void assign( ScBaseCell& rCell );
+
+ /**
+ * Set cell value at specified position in specified document.
+ */
+ void commit( ScDocument& rDoc, const ScAddress& rPos ) const;
+
+ bool hasString() const;
+
+ bool hasNumeric() const;
+
+ bool isEmpty() const;
+
+ bool equalsWithoutFormat( const ScRefCellValue& r ) const;
+
+ ScRefCellValue& operator= ( const ScRefCellValue& r );
+
+ void swap( ScRefCellValue& r );
+};
+
#endif
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index f25dc78..ac329b2 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -272,6 +272,7 @@ public:
void SetError( SCROW nRow, const sal_uInt16 nError);
void GetString( SCROW nRow, rtl::OUString& rString ) const;
+ const OUString* GetStringCell( SCROW nRow ) const;
void GetInputString( SCROW nRow, rtl::OUString& rString ) const;
double GetValue( SCROW nRow ) const;
const EditTextObject* GetEditText( SCROW nRow ) const;
diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx
index 70c5620..892d18f 100644
--- a/sc/inc/document.hxx
+++ b/sc/inc/document.hxx
@@ -802,6 +802,17 @@ public:
SC_DLLPUBLIC OUString GetString( SCCOL nCol, SCROW nRow, SCTAB nTab ) const;
OUString GetString( const ScAddress& rPos ) const;
+
+ /**
+ * Return a pointer to the string object stored in string cell.
+ *
+ * @param rPos cell position.
+ *
+ * @return pointer to the string object stored in string cell, or NULL if
+ * the cell at specified position is not a string cell. Note that
+ * it returns NULL even for a edit cell.
+ */
+ const OUString* GetStringCell( const ScAddress& rPos ) const;
SC_DLLPUBLIC void GetInputString( SCCOL nCol, SCROW nRow, SCTAB nTab, String& rString );
SC_DLLPUBLIC void GetInputString( SCCOL nCol, SCROW nRow, SCTAB nTab, rtl::OUString& rString );
sal_uInt16 GetStringForFormula( const ScAddress& rPos, rtl::OUString& rString );
diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx
index 461da522..0a12ead 100644
--- a/sc/inc/table.hxx
+++ b/sc/inc/table.hxx
@@ -318,6 +318,7 @@ public:
void SetError( SCCOL nCol, SCROW nRow, sal_uInt16 nError);
void GetString( SCCOL nCol, SCROW nRow, rtl::OUString& rString ) const;
+ const OUString* GetStringCell( SCCOL nCol, SCROW nRow ) const;
void GetInputString( SCCOL nCol, SCROW nRow, rtl::OUString& rString ) const;
double GetValue( const ScAddress& rPos ) const
{
diff --git a/sc/source/core/data/cellvalue.cxx b/sc/source/core/data/cellvalue.cxx
index 8b0baa4..5b853a3 100644
--- a/sc/source/core/data/cellvalue.cxx
+++ b/sc/source/core/data/cellvalue.cxx
@@ -16,6 +16,121 @@
#include "editutil.hxx"
#include "formula/token.hxx"
+namespace {
+
+CellType adjustCellType( CellType eOrig )
+{
+ switch (eOrig)
+ {
+ case CELLTYPE_NOTE:
+ return CELLTYPE_NONE;
+ case CELLTYPE_EDIT:
+ return CELLTYPE_STRING;
+ default:
+ ;
+ }
+ return eOrig;
+}
+
+template<typename _T>
+OUString getString( const _T& rVal )
+{
+ if (rVal.meType == CELLTYPE_STRING)
+ return *rVal.mpString;
+
+ if (rVal.meType == CELLTYPE_EDIT)
+ {
+ OUStringBuffer aRet;
+ size_t n = rVal.mpEditText->GetParagraphCount();
+ for (size_t i = 0; i < n; ++i)
+ {
+ if (i > 0)
+ aRet.append('\n');
+ aRet.append(rVal.mpEditText->GetText(i));
+ }
+ return aRet.makeStringAndClear();
+ }
+
+ return EMPTY_OUSTRING;
+}
+
+bool equalsFormulaCells( const ScFormulaCell* p1, const ScFormulaCell* p2 )
+{
+ const ScTokenArray* pCode1 = p1->GetCode();
+ const ScTokenArray* pCode2 = p2->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;
+}
+
+template<typename _T>
+bool equalsWithoutFormatImpl( const _T& left, const _T& right )
+{
+ CellType eType1 = adjustCellType(left.meType);
+ CellType eType2 = adjustCellType(right.meType);
+ if (eType1 != eType2)
+ return false;
+
+ switch (eType1)
+ {
+ case CELLTYPE_NONE:
+ return true;
+ case CELLTYPE_VALUE:
+ return left.mfValue == right.mfValue;
+ case CELLTYPE_STRING:
+ {
+ OUString aStr1 = getString(left);
+ OUString aStr2 = getString(right);
+ return aStr1 == aStr2;
+ }
+ case CELLTYPE_FORMULA:
+ return equalsFormulaCells(left.mpFormula, right.mpFormula);
+ default:
+ ;
+ }
+ return false;
+}
+
+bool hasStringImpl( CellType eType, ScFormulaCell* pFormula )
+{
+ switch (eType)
+ {
+ case CELLTYPE_STRING:
+ case CELLTYPE_EDIT:
+ return true;
+ case CELLTYPE_FORMULA:
+ return !pFormula->IsValue();
+ default:
+ return false;
+ }
+}
+
+bool hasNumericImpl( CellType eType, ScFormulaCell* pFormula )
+{
+ switch (eType)
+ {
+ case CELLTYPE_VALUE:
+ return true;
+ case CELLTYPE_FORMULA:
+ return pFormula->IsValue();
+ default:
+ return false;
+ }
+}
+
+}
+
ScCellValue::ScCellValue() : meType(CELLTYPE_NONE), mfValue(0.0) {}
ScCellValue::ScCellValue( double fValue ) : meType(CELLTYPE_VALUE), mfValue(fValue) {}
ScCellValue::ScCellValue( const OUString& rString ) : meType(CELLTYPE_STRING), mpString(new OUString(rString)) {}
@@ -223,29 +338,12 @@ void ScCellValue::release( ScDocument& rDoc, const ScAddress& rPos )
bool ScCellValue::hasString() const
{
- switch (meType)
- {
- case CELLTYPE_STRING:
- case CELLTYPE_EDIT:
- return true;
- case CELLTYPE_FORMULA:
- return !mpFormula->IsValue();
- default:
- return false;
- }
+ return hasStringImpl(meType, mpFormula);
}
bool ScCellValue::hasNumeric() const
{
- switch (meType)
- {
- case CELLTYPE_VALUE:
- return true;
- case CELLTYPE_FORMULA:
- return mpFormula->IsValue();
- default:
- return false;
- }
+ return hasNumericImpl(meType, mpFormula);
}
bool ScCellValue::isEmpty() const
@@ -253,97 +351,150 @@ bool ScCellValue::isEmpty() const
return meType == CELLTYPE_NOTE || meType == CELLTYPE_NONE;
}
-namespace {
+bool ScCellValue::equalsWithoutFormat( const ScCellValue& r ) const
+{
+ return equalsWithoutFormatImpl(*this, r);
+}
-CellType adjustCellType( CellType eOrig )
+ScCellValue& ScCellValue::operator= ( const ScCellValue& r )
{
- switch (eOrig)
+ ScCellValue aTmp(r);
+ swap(aTmp);
+ return *this;
+}
+
+void ScCellValue::swap( ScCellValue& r )
+{
+ std::swap(meType, r.meType);
+
+ // double is 8 bytes, whereas a pointer may be 4 or 8 bytes depending on
+ // the platform. Swap by double values.
+ std::swap(mfValue, r.mfValue);
+}
+
+ScRefCellValue::ScRefCellValue() : meType(CELLTYPE_NONE), mfValue(0.0) {}
+ScRefCellValue::ScRefCellValue( double fValue ) : meType(CELLTYPE_VALUE), mfValue(fValue) {}
+ScRefCellValue::ScRefCellValue( const OUString* pString ) : meType(CELLTYPE_STRING), mpString(pString) {}
+ScRefCellValue::ScRefCellValue( const EditTextObject* pEditText ) : meType(CELLTYPE_EDIT), mpEditText(pEditText) {}
+ScRefCellValue::ScRefCellValue( ScFormulaCell* pFormula ) : meType(CELLTYPE_FORMULA), mpFormula(pFormula) {}
+
+// It should be enough to copy the double value, which is at least as large
+// as the pointer values.
+ScRefCellValue::ScRefCellValue( const ScRefCellValue& r ) : meType(r.meType), mfValue(r.mfValue) {}
+
+ScRefCellValue::~ScRefCellValue()
+{
+ clear();
+}
+
+void ScRefCellValue::clear()
+{
+ // Reset to empty value.
+ meType = CELLTYPE_NONE;
+ mfValue = 0.0;
+}
+
+void ScRefCellValue::assign( ScDocument& rDoc, const ScAddress& rPos )
+{
+ clear();
+
+ meType = rDoc.GetCellType(rPos);
+ switch (meType)
{
- case CELLTYPE_NOTE:
- return CELLTYPE_NONE;
+ case CELLTYPE_STRING:
+ mpString = rDoc.GetStringCell(rPos);
+ break;
case CELLTYPE_EDIT:
- return CELLTYPE_STRING;
+ mpEditText = rDoc.GetEditText(rPos);
+ break;
+ case CELLTYPE_VALUE:
+ mfValue = rDoc.GetValue(rPos);
+ break;
+ case CELLTYPE_FORMULA:
+ mpFormula = rDoc.GetFormulaCell(rPos);
+ break;
default:
- ;
+ meType = CELLTYPE_NONE; // reset to empty.
}
- return eOrig;
}
-OUString getString( const ScCellValue& rVal )
+void ScRefCellValue::assign( ScBaseCell& rCell )
{
- if (rVal.meType == CELLTYPE_STRING)
- return *rVal.mpString;
+ clear();
- if (rVal.meType == CELLTYPE_EDIT)
+ meType = rCell.GetCellType();
+ switch (meType)
{
- OUStringBuffer aRet;
- size_t n = rVal.mpEditText->GetParagraphCount();
- for (size_t i = 0; i < n; ++i)
- {
- if (i > 0)
- aRet.append('\n');
- aRet.append(rVal.mpEditText->GetText(i));
- }
- return aRet.makeStringAndClear();
+ case CELLTYPE_STRING:
+ mpString = static_cast<const ScStringCell&>(rCell).GetStringPtr();
+ break;
+ case CELLTYPE_EDIT:
+ mpEditText = static_cast<const ScEditCell&>(rCell).GetData();
+ break;
+ case CELLTYPE_VALUE:
+ mfValue = static_cast<const ScValueCell&>(rCell).GetValue();
+ break;
+ case CELLTYPE_FORMULA:
+ mpFormula = static_cast<ScFormulaCell*>(&rCell);
+ break;
+ default:
+ meType = CELLTYPE_NONE; // reset to empty.
}
-
- return EMPTY_OUSTRING;
}
-}
-
-bool ScCellValue::equalsWithoutFormat( const ScCellValue& r ) const
+void ScRefCellValue::commit( ScDocument& rDoc, const ScAddress& rPos ) const
{
- CellType eType1 = adjustCellType(meType);
- CellType eType2 = adjustCellType(r.meType);
- if (eType1 != eType2)
- return false;
-
switch (meType)
{
- case CELLTYPE_NONE:
- return true;
- case CELLTYPE_VALUE:
- return mfValue == r.mfValue;
case CELLTYPE_STRING:
{
- OUString aStr1 = getString(*this);
- OUString aStr2 = getString(r);
- return aStr1 == aStr2;
+ ScSetStringParam aParam;
+ aParam.setTextInput();
+ rDoc.SetString(rPos, *mpString, &aParam);
}
+ break;
+ case CELLTYPE_EDIT:
+ rDoc.SetEditText(rPos, mpEditText->Clone());
+ break;
+ case CELLTYPE_VALUE:
+ rDoc.SetValue(rPos, mfValue);
+ break;
case CELLTYPE_FORMULA:
- {
- ScTokenArray* pCode1 = mpFormula->GetCode();
- ScTokenArray* pCode2 = r.mpFormula->GetCode();
+ rDoc.SetFormulaCell(rPos, mpFormula->Clone());
+ break;
+ default:
+ rDoc.SetEmptyCell(rPos);
+ }
+}
- if (pCode1->GetLen() != pCode2->GetLen())
- return false;
+bool ScRefCellValue::hasString() const
+{
+ return hasStringImpl(meType, mpFormula);
+}
- 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;
- }
+bool ScRefCellValue::hasNumeric() const
+{
+ return hasNumericImpl(meType, mpFormula);
+}
- return true;
- }
- default:
- ;
- }
- return false;
+bool ScRefCellValue::isEmpty() const
+{
+ return meType == CELLTYPE_NOTE || meType == CELLTYPE_NONE;
}
-ScCellValue& ScCellValue::operator= ( const ScCellValue& r )
+bool ScRefCellValue::equalsWithoutFormat( const ScRefCellValue& r ) const
{
- ScCellValue aTmp(r);
+ return equalsWithoutFormatImpl(*this, r);
+}
+
+ScRefCellValue& ScRefCellValue::operator= ( const ScRefCellValue& r )
+{
+ ScRefCellValue aTmp(r);
swap(aTmp);
return *this;
}
-void ScCellValue::swap( ScCellValue& r )
+void ScRefCellValue::swap( ScRefCellValue& r )
{
std::swap(meType, r.meType);
diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx
index 3297b88..3a591cd 100644
--- a/sc/source/core/data/column3.cxx
+++ b/sc/source/core/data/column3.cxx
@@ -1758,6 +1758,18 @@ void ScColumn::GetString( SCROW nRow, rtl::OUString& rString ) const
rString = rtl::OUString();
}
+const OUString* ScColumn::GetStringCell( SCROW nRow ) const
+{
+ SCSIZE nIndex;
+ if (!Search(nRow, nIndex))
+ return NULL;
+
+ const ScBaseCell* pCell = maItems[nIndex].pCell;
+ if (pCell->GetCellType() != CELLTYPE_STRING)
+ return NULL;
+
+ return static_cast<const ScStringCell*>(pCell)->GetStringPtr();
+}
void ScColumn::GetInputString( SCROW nRow, rtl::OUString& rString ) const
{
diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx
index 6ebbf39..1603d23 100644
--- a/sc/source/core/data/document.cxx
+++ b/sc/source/core/data/document.cxx
@@ -3053,6 +3053,14 @@ OUString ScDocument::GetString( const ScAddress& rPos ) const
return aStr;
}
+const OUString* ScDocument::GetStringCell( const ScAddress& rPos ) const
+{
+ if (!TableExists(rPos.Tab()))
+ return NULL;
+
+ return maTabs[rPos.Tab()]->GetStringCell(rPos.Col(), rPos.Row());
+}
+
void ScDocument::GetInputString( SCCOL nCol, SCROW nRow, SCTAB nTab, OUString& rString )
{
if ( ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab] )
diff --git a/sc/source/core/data/table2.cxx b/sc/source/core/data/table2.cxx
index f6d34c2..319226f 100644
--- a/sc/source/core/data/table2.cxx
+++ b/sc/source/core/data/table2.cxx
@@ -1404,6 +1404,13 @@ void ScTable::GetString( SCCOL nCol, SCROW nRow, rtl::OUString& rString ) const
rString = rtl::OUString();
}
+const OUString* ScTable::GetStringCell( SCCOL nCol, SCROW nRow ) const
+{
+ if (!ValidColRow(nCol,nRow))
+ return NULL;
+
+ return aCol[nCol].GetStringCell(nRow);
+}
void ScTable::GetInputString( SCCOL nCol, SCROW nRow, rtl::OUString& rString ) const
{
commit 0fb1409d9682f118d28f89e27bba7887882dad91
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date: Tue Mar 26 10:42:06 2013 -0400
This method no longer used. Good. Remove it.
Change-Id: I397dedd6c7388b350af0f93151fdf0160698acc7
diff --git a/sc/inc/dociter.hxx b/sc/inc/dociter.hxx
index 8c513aa..58d1215 100644
--- a/sc/inc/dociter.hxx
+++ b/sc/inc/dociter.hxx
@@ -76,7 +76,6 @@ public:
bool GetFirst();
bool GetNext();
- ScBaseCell* GetCell();
ScCellValue GetCellValue() const;
const ScPatternAttr* GetPattern();
void GetPos( SCCOL& rCol, SCROW& rRow, SCTAB& rTab );
diff --git a/sc/source/core/data/dociter.cxx b/sc/source/core/data/dociter.cxx
index 24fd2b3..9f7dd02 100644
--- a/sc/source/core/data/dociter.cxx
+++ b/sc/source/core/data/dociter.cxx
@@ -197,13 +197,6 @@ bool ScDocumentIterator::GetNext()
return GetThis();
}
-//------------------------------------------------------------------------
-
-ScBaseCell* ScDocumentIterator::GetCell()
-{
- return pCell;
-}
-
ScCellValue ScDocumentIterator::GetCellValue() const
{
ScCellValue aRet;
More information about the Libreoffice-commits
mailing list