diff options
author | Kohei Yoshida <kohei.yoshida@gmail.com> | 2013-03-26 15:04:25 -0400 |
---|---|---|
committer | Kohei Yoshida <kohei.yoshida@gmail.com> | 2013-03-26 15:36:02 -0400 |
commit | 5f5d2cb6d1363bd133053a7c035b6e0163ee4edc (patch) | |
tree | 228d251e1f9f258acdb1b402a57528e4d295e158 /sc | |
parent | By using ScRefCellValue we can remove some duplicated code. (diff) | |
download | core-5f5d2cb6d1363bd133053a7c035b6e0163ee4edc.tar.gz core-5f5d2cb6d1363bd133053a7c035b6e0163ee4edc.zip |
Make the conditional formatting code free of ScBaseCell.
Change-Id: I93f83a840874c973cdc0821ddeb1913be7f09767
Diffstat (limited to 'sc')
-rw-r--r-- | sc/inc/cellvalue.hxx | 5 | ||||
-rw-r--r-- | sc/inc/conditio.hxx | 9 | ||||
-rw-r--r-- | sc/inc/validat.hxx | 15 | ||||
-rw-r--r-- | sc/source/core/data/cell.cxx | 3 | ||||
-rw-r--r-- | sc/source/core/data/conditio.cxx | 112 | ||||
-rw-r--r-- | sc/source/core/data/documen4.cxx | 12 | ||||
-rw-r--r-- | sc/source/core/data/fillinfo.cxx | 8 | ||||
-rw-r--r-- | sc/source/core/data/validat.cxx | 177 | ||||
-rw-r--r-- | sc/source/core/tool/detfunc.cxx | 3 |
9 files changed, 134 insertions, 210 deletions
diff --git a/sc/inc/cellvalue.hxx b/sc/inc/cellvalue.hxx index 7998898fd3ef..84127cd959a6 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 d5a55e3fd29a..8592bcb9a7e1 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 8c73b7d095e1..85737a3a989f 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 aa777e58d830..c34e55c9d96d 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 ae4a7e2d9ebd..0ce3088eddb1 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 aad3f4f9ca81..3df2fbc5f830 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 f0d4cb4a302e..f7366cd99468 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 a2d4b4ad2180..cff7da794831 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 7aad0cc5438d..958162fd0b8c 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; |