summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sc/inc/cellvalue.hxx8
-rw-r--r--sc/source/core/data/autonamecache.cxx28
-rw-r--r--sc/source/core/data/cellvalue.cxx116
-rw-r--r--sc/source/ui/unoobj/cellsuno.cxx132
4 files changed, 199 insertions, 85 deletions
diff --git a/sc/inc/cellvalue.hxx b/sc/inc/cellvalue.hxx
index ac9627460890..16af46fc4c12 100644
--- a/sc/inc/cellvalue.hxx
+++ b/sc/inc/cellvalue.hxx
@@ -49,6 +49,14 @@ struct ScCellValue
* Set cell value at specified position in specified document.
*/
void commit( ScDocument& rDoc, const ScAddress& rPos );
+
+ bool hasString() const;
+
+ bool hasNumeric() const;
+
+ bool isEmpty() const;
+
+ bool equalsWithoutFormat( const ScCellValue& r ) const;
};
// TODO: temporary workaround. To be removed later.
diff --git a/sc/source/core/data/autonamecache.cxx b/sc/source/core/data/autonamecache.cxx
index 8a79864a442d..2bbc4b20c924 100644
--- a/sc/source/core/data/autonamecache.cxx
+++ b/sc/source/core/data/autonamecache.cxx
@@ -21,10 +21,11 @@
#include "autonamecache.hxx"
#include "dociter.hxx"
-#include "cell.hxx"
#include "queryparam.hxx"
-
-// -----------------------------------------------------------------------
+#include "cell.hxx"
+#include "cellvalue.hxx"
+#include "editutil.hxx"
+#include "document.hxx"
ScAutoNameCache::ScAutoNameCache( ScDocument* pD ) :
pDoc( pD ),
@@ -52,25 +53,28 @@ const ScAutoNameAddresses& ScAutoNameCache::GetNameOccurrences( const String& rN
ScAutoNameAddresses& rAddresses = aNames[rName];
ScCellIterator aIter( pDoc, ScRange( 0, 0, nCurrentTab, MAXCOL, MAXROW, nCurrentTab ) );
- for ( ScBaseCell* pCell = aIter.GetFirst(); pCell; pCell = aIter.GetNext() )
+ for (bool bHasCell = aIter.first(); bHasCell; bHasCell = aIter.next())
{
// don't check code length here, always use the stored result
// (AutoCalc is disabled during CompileXML)
-
- if ( pCell->HasStringData() )
+ const ScCellValue& rVal = aIter.get();
+ if (rVal.hasString())
{
- String aStr;
- CellType eType = pCell->GetCellType();
- switch ( eType )
+ OUString aStr;
+ switch (rVal.meType)
{
case CELLTYPE_STRING:
- aStr = ((ScStringCell*)pCell)->GetString();
+ aStr = *rVal.mpString;
break;
case CELLTYPE_FORMULA:
- aStr = ((ScFormulaCell*)pCell)->GetString();
+ aStr = rVal.mpFormula->GetString();
break;
case CELLTYPE_EDIT:
- aStr = ((ScEditCell*)pCell)->GetString();
+ {
+ ScFieldEditEngine& rEngine = pDoc->GetEditEngine();
+ rEngine.SetText(*rVal.mpEditText);
+ aStr = ScEditUtil::GetMultilineString(rEngine); // string with line separators between paragraphs
+ }
break;
case CELLTYPE_NONE:
case CELLTYPE_VALUE:
diff --git a/sc/source/core/data/cellvalue.cxx b/sc/source/core/data/cellvalue.cxx
index 6a51c68a2734..370627844f4e 100644
--- a/sc/source/core/data/cellvalue.cxx
+++ b/sc/source/core/data/cellvalue.cxx
@@ -12,6 +12,7 @@
#include "cell.hxx"
#include "editeng/editobj.hxx"
#include "stringutil.hxx"
+#include "formula/token.hxx"
ScCellValue::ScCellValue() : meType(CELLTYPE_NONE), mfValue(0.0) {}
ScCellValue::ScCellValue( double fValue ) : meType(CELLTYPE_VALUE), mfValue(fValue) {}
@@ -113,6 +114,121 @@ void ScCellValue::commit( 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;
+ }
+}
+
+bool ScCellValue::hasNumeric() const
+{
+ switch (meType)
+ {
+ case CELLTYPE_VALUE:
+ return true;
+ case CELLTYPE_FORMULA:
+ return mpFormula->IsValue();
+ default:
+ return false;
+ }
+}
+
+bool ScCellValue::isEmpty() const
+{
+ return meType == CELLTYPE_NOTE || meType == CELLTYPE_NONE;
+}
+
+namespace {
+
+CellType adjustCellType( CellType eOrig )
+{
+ switch (eOrig)
+ {
+ case CELLTYPE_NOTE:
+ return CELLTYPE_NONE;
+ case CELLTYPE_EDIT:
+ return CELLTYPE_STRING;
+ default:
+ ;
+ }
+ return eOrig;
+}
+
+OUString getString( const ScCellValue& 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 ScCellValue::equalsWithoutFormat( const ScCellValue& r ) 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;
+ }
+ case CELLTYPE_FORMULA:
+ {
+ ScTokenArray* pCode1 = mpFormula->GetCode();
+ ScTokenArray* pCode2 = r.mpFormula->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;
+}
+
ScBaseCell* getHackedBaseCell( ScDocument* pDoc, const ScCellValue& rVal )
{
switch (rVal.meType)
diff --git a/sc/source/ui/unoobj/cellsuno.cxx b/sc/source/ui/unoobj/cellsuno.cxx
index a64feb1a448f..7bff6ddc2b07 100644
--- a/sc/source/ui/unoobj/cellsuno.cxx
+++ b/sc/source/ui/unoobj/cellsuno.cxx
@@ -3558,14 +3558,11 @@ uno::Reference<sheet::XSheetCellRanges> SAL_CALL ScCellRangesBase::queryEmptyCel
ScRange aRange = *aRanges[ i ];
ScCellIterator aIter( pDoc, aRange );
- ScBaseCell* pCell = aIter.GetFirst();
- while (pCell)
+ for (bool bHasCell = aIter.first(); bHasCell; bHasCell = aIter.next())
{
// Notizen zaehlen als nicht-leer
- if ( !pCell->IsBlank() )
+ if (!aIter.get().isEmpty())
aMarkData.SetMultiMarkArea(aIter.GetPos(), false);
-
- pCell = aIter.GetNext();
}
}
@@ -3597,28 +3594,28 @@ uno::Reference<sheet::XSheetCellRanges> SAL_CALL ScCellRangesBase::queryContentC
ScRange aRange = *aRanges[ i ];
ScCellIterator aIter( pDoc, aRange );
- ScBaseCell* pCell = aIter.GetFirst();
- while (pCell)
+ for (bool bHasCell = aIter.first(); bHasCell; bHasCell = aIter.next())
{
- sal_Bool bAdd = false;
- switch ( pCell->GetCellType() )
+ bool bAdd = false;
+ const ScCellValue& rVal = aIter.get();
+ switch (rVal.meType)
{
case CELLTYPE_STRING:
if ( nContentFlags & sheet::CellFlags::STRING )
- bAdd = sal_True;
+ bAdd = true;
break;
case CELLTYPE_EDIT:
if ( (nContentFlags & sheet::CellFlags::STRING) || (nContentFlags & sheet::CellFlags::FORMATTED) )
- bAdd = sal_True;
+ bAdd = true;
break;
case CELLTYPE_FORMULA:
if ( nContentFlags & sheet::CellFlags::FORMULA )
- bAdd = sal_True;
+ bAdd = true;
break;
case CELLTYPE_VALUE:
if ( (nContentFlags & (sheet::CellFlags::VALUE|sheet::CellFlags::DATETIME))
== (sheet::CellFlags::VALUE|sheet::CellFlags::DATETIME) )
- bAdd = sal_True;
+ bAdd = true;
else
{
// Date/Time Erkennung
@@ -3630,12 +3627,12 @@ uno::Reference<sheet::XSheetCellRanges> SAL_CALL ScCellRangesBase::queryContentC
(nTyp == NUMBERFORMAT_DATETIME))
{
if ( nContentFlags & sheet::CellFlags::DATETIME )
- bAdd = sal_True;
+ bAdd = true;
}
else
{
if ( nContentFlags & sheet::CellFlags::VALUE )
- bAdd = sal_True;
+ bAdd = true;
}
}
break;
@@ -3647,8 +3644,6 @@ uno::Reference<sheet::XSheetCellRanges> SAL_CALL ScCellRangesBase::queryContentC
if (bAdd)
aMarkData.SetMultiMarkArea(aIter.GetPos(), true);
-
- pCell = aIter.GetNext();
}
}
@@ -3680,34 +3675,31 @@ uno::Reference<sheet::XSheetCellRanges> SAL_CALL ScCellRangesBase::queryFormulaC
ScRange aRange = *aRanges[ i ];
ScCellIterator aIter( pDoc, aRange );
- ScBaseCell* pCell = aIter.GetFirst();
- while (pCell)
+ for (bool bHasCell = aIter.first(); bHasCell; bHasCell = aIter.next())
{
- if (pCell->GetCellType() == CELLTYPE_FORMULA)
+ if (aIter.get().meType == CELLTYPE_FORMULA)
{
- ScFormulaCell* pFCell = (ScFormulaCell*)pCell;
- sal_Bool bAdd = false;
+ ScFormulaCell* pFCell = aIter.get().mpFormula;
+ bool bAdd = false;
if (pFCell->GetErrCode())
{
if ( nResultFlags & sheet::FormulaResult::ERROR )
- bAdd = sal_True;
+ bAdd = true;
}
else if (pFCell->IsValue())
{
if ( nResultFlags & sheet::FormulaResult::VALUE )
- bAdd = sal_True;
+ bAdd = true;
}
else // String
{
if ( nResultFlags & sheet::FormulaResult::STRING )
- bAdd = sal_True;
+ bAdd = true;
}
if (bAdd)
aMarkData.SetMultiMarkArea(aIter.GetPos(), true);
}
-
- pCell = aIter.GetNext();
}
}
@@ -3743,10 +3735,9 @@ uno::Reference<sheet::XSheetCellRanges> ScCellRangesBase::QueryDifferences_Impl(
else
aCmpRange = ScRange( static_cast<SCCOL>(nCmpPos),0,nTab, static_cast<SCCOL>(nCmpPos),MAXROW,nTab );
ScCellIterator aCmpIter( pDoc, aCmpRange );
- ScBaseCell* pCmpCell = aCmpIter.GetFirst();
- while (pCmpCell)
+ for (bool bHasCell = aCmpIter.first(); bHasCell; bHasCell = aCmpIter.next())
{
- if (pCmpCell->GetCellType() != CELLTYPE_NOTE)
+ if (aCmpIter.get().meType != CELLTYPE_NOTE)
{
SCCOLROW nCellPos = bColumnDiff ? static_cast<SCCOLROW>(aCmpIter.GetPos().Col()) : static_cast<SCCOLROW>(aCmpIter.GetPos().Row());
if (bColumnDiff)
@@ -3774,7 +3765,6 @@ uno::Reference<sheet::XSheetCellRanges> ScCellRangesBase::QueryDifferences_Impl(
}
}
}
- pCmpCell = aCmpIter.GetNext();
}
// alle nichtleeren Zellen mit der Vergleichsspalte vergleichen und entsprechend
@@ -3786,22 +3776,22 @@ uno::Reference<sheet::XSheetCellRanges> ScCellRangesBase::QueryDifferences_Impl(
ScRange aRange( *aRanges[ i ] );
ScCellIterator aIter( pDoc, aRange );
- ScBaseCell* pCell = aIter.GetFirst();
- while (pCell)
+ for (bool bHasCell = aIter.first(); bHasCell; bHasCell = aIter.next())
{
+ const ScCellValue& rCell = aIter.get();
+
if (bColumnDiff)
aCmpAddr = ScAddress( aIter.GetPos().Col(), nCmpPos, aIter.GetPos().Tab() );
else
aCmpAddr = ScAddress( static_cast<SCCOL>(nCmpPos), aIter.GetPos().Row(), aIter.GetPos().Tab() );
- const ScBaseCell* pOtherCell = pDoc->GetCell( aCmpAddr );
+ ScCellValue aOtherCell;
+ aOtherCell.assign(*pDoc, aCmpAddr);
ScRange aOneRange(aIter.GetPos());
- if ( !ScBaseCell::CellEqual( pCell, pOtherCell ) )
+ if (!rCell.equalsWithoutFormat(aOtherCell))
aMarkData.SetMultiMarkArea( aOneRange );
else
aMarkData.SetMultiMarkArea( aOneRange, false ); // deselect
-
- pCell = aIter.GetNext();
}
}
@@ -3876,23 +3866,20 @@ uno::Reference<sheet::XSheetCellRanges> SAL_CALL ScCellRangesBase::queryPreceden
{
ScRange aRange( *aNewRanges[ nR] );
ScCellIterator aIter( pDoc, aRange );
- ScBaseCell* pCell = aIter.GetFirst();
- while (pCell)
+ for (bool bHasCell = aIter.first(); bHasCell; bHasCell = aIter.next())
{
- if ( pCell->GetCellType() == CELLTYPE_FORMULA )
- {
- ScFormulaCell* pFCell = (ScFormulaCell*) pCell;
+ const ScCellValue& rVal = aIter.get();
+ if (rVal.meType != CELLTYPE_FORMULA)
+ continue;
- ScDetectiveRefIter aRefIter( pFCell );
- ScRange aRefRange;
- while ( aRefIter.GetNextRef( aRefRange) )
- {
- if ( bRecursive && !bFound && !aMarkData.IsAllMarked( aRefRange ) )
- bFound = sal_True;
- aMarkData.SetMultiMarkArea( aRefRange, sal_True );
- }
+ ScDetectiveRefIter aRefIter(rVal.mpFormula);
+ ScRange aRefRange;
+ while ( aRefIter.GetNextRef( aRefRange) )
+ {
+ if ( bRecursive && !bFound && !aMarkData.IsAllMarked( aRefRange ) )
+ bFound = true;
+ aMarkData.SetMultiMarkArea(aRefRange, true);
}
- pCell = aIter.GetNext();
}
}
@@ -3928,33 +3915,32 @@ uno::Reference<sheet::XSheetCellRanges> SAL_CALL ScCellRangesBase::queryDependen
SCTAB nTab = lcl_FirstTab(aNewRanges); //! alle Tabellen
ScCellIterator aCellIter( pDoc, 0,0, nTab, MAXCOL,MAXROW, nTab );
- ScBaseCell* pCell = aCellIter.GetFirst();
- while (pCell)
+ for (bool bHasCell = aCellIter.first(); bHasCell; bHasCell = aCellIter.next())
{
- if (pCell->GetCellType() == CELLTYPE_FORMULA)
+ const ScCellValue& rVal = aCellIter.get();
+ if (rVal.meType != CELLTYPE_FORMULA)
+ continue;
+
+ bool bMark = false;
+ ScDetectiveRefIter aIter(rVal.mpFormula);
+ ScRange aRefRange;
+ while ( aIter.GetNextRef( aRefRange) )
{
- sal_Bool bMark = false;
- ScDetectiveRefIter aIter( (ScFormulaCell*) pCell );
- ScRange aRefRange;
- while ( aIter.GetNextRef( aRefRange) )
- {
- size_t nRangesCount = aNewRanges.size();
- for (size_t nR = 0; nR < nRangesCount; ++nR)
- {
- ScRange aRange( *aNewRanges[ nR ] );
- if (aRange.Intersects(aRefRange))
- bMark = sal_True; // von Teil des Ranges abhaengig
- }
- }
- if (bMark)
+ size_t nRangesCount = aNewRanges.size();
+ for (size_t nR = 0; nR < nRangesCount; ++nR)
{
- ScRange aCellRange(aCellIter.GetPos());
- if ( bRecursive && !bFound && !aMarkData.IsAllMarked( aCellRange ) )
- bFound = sal_True;
- aMarkData.SetMultiMarkArea( aCellRange, sal_True );
+ ScRange aRange( *aNewRanges[ nR ] );
+ if (aRange.Intersects(aRefRange))
+ bMark = sal_True; // von Teil des Ranges abhaengig
}
}
- pCell = aCellIter.GetNext();
+ if (bMark)
+ {
+ ScRange aCellRange(aCellIter.GetPos());
+ if ( bRecursive && !bFound && !aMarkData.IsAllMarked( aCellRange ) )
+ bFound = true;
+ aMarkData.SetMultiMarkArea(aCellRange, true);
+ }
}
aMarkData.FillRangeListWithMarks( &aNewRanges, sal_True );