summaryrefslogtreecommitdiffstats
path: root/sc
diff options
context:
space:
mode:
authorKohei Yoshida <kohei.yoshida@gmail.com>2013-03-26 12:00:43 -0400
committerKohei Yoshida <kohei.yoshida@gmail.com>2013-03-26 15:35:04 -0400
commit0b0e7ca9b3bae3b3295da33e5980f3f4c6a5f532 (patch)
tree352d493e794127383ea9b75faf5a7249fbdf3a15 /sc
parentThis method no longer used. Good. Remove it. (diff)
downloadcore-0b0e7ca9b3bae3b3295da33e5980f3f4c6a5f532.tar.gz
core-0b0e7ca9b3bae3b3295da33e5980f3f4c6a5f532.zip
Add ScRefCellValue, which is ScCellValue without copied value.
It directly points to the original cell value instance. Change-Id: I638ec8b931873d237871b6d8fa9f0e1277520d0f
Diffstat (limited to 'sc')
-rw-r--r--sc/inc/cell.hxx1
-rw-r--r--sc/inc/cellvalue.hxx56
-rw-r--r--sc/inc/column.hxx1
-rw-r--r--sc/inc/document.hxx11
-rw-r--r--sc/inc/table.hxx1
-rw-r--r--sc/source/core/data/cellvalue.cxx309
-rw-r--r--sc/source/core/data/column3.cxx12
-rw-r--r--sc/source/core/data/document.cxx8
-rw-r--r--sc/source/core/data/table2.cxx7
9 files changed, 326 insertions, 80 deletions
diff --git a/sc/inc/cell.hxx b/sc/inc/cell.hxx
index 236ad4301df4..0b78f9878cac 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 9dd3a9a72247..7998898fd3ef 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 f25dc78ec716..ac329b273ec9 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 70c562038713..892d18f2b2ec 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 461da52241b2..0a12ead224d8 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 8b0baa445c4b..5b853a32779a 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 3297b88f000d..3a591cd9b9ad 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 6ebbf39975c9..1603d23d1cb3 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 f6d34c2f04fa..319226f5acb9 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
{