[Libreoffice-commits] core.git: Branch 'feature/formula-core-rework' - sc/inc sc/source

Kohei Yoshida kohei.yoshida at gmail.com
Tue Mar 26 12:05:49 PDT 2013


 sc/inc/cellvalue.hxx             |    5 -
 sc/inc/conditio.hxx              |    9 -
 sc/inc/validat.hxx               |   15 +--
 sc/source/core/data/cell.cxx     |    3 
 sc/source/core/data/conditio.cxx |  112 ++++++++++++------------
 sc/source/core/data/documen4.cxx |   12 +-
 sc/source/core/data/fillinfo.cxx |    8 +
 sc/source/core/data/validat.cxx  |  177 ++++++++++-----------------------------
 sc/source/core/tool/detfunc.cxx  |    3 
 9 files changed, 134 insertions(+), 210 deletions(-)

New commits:
commit 1fda609106ffdabf4c200c1fa8138134504895fd
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;


More information about the Libreoffice-commits mailing list