summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKohei Yoshida <kohei.yoshida@gmail.com>2013-08-01 22:01:26 -0400
committerKohei Yoshida <kohei.yoshida@gmail.com>2013-08-02 14:22:10 -0400
commitbf846ac0510da21f7faa601fbd30d9147dc3ee71 (patch)
treed6acca38a7b233b24ba5f1331320efab7fcadc69
parenteace5e0a1c4bab37699429447b1a17e3c9410503 (diff)
fdo#67099: Remove overheads on inserting cells during ods import.
We will switch to using ScDocumentImport to populate the document from import filters, instead of using ScDocument directly. Change-Id: Ie59d6877d1ac4fc04751a84b663772a9dc9a3efc
-rw-r--r--sc/inc/column.hxx11
-rw-r--r--sc/inc/documentimport.hxx13
-rw-r--r--sc/source/core/data/column2.cxx35
-rw-r--r--sc/source/core/data/column3.cxx260
-rw-r--r--sc/source/core/data/documentimport.cxx231
-rw-r--r--sc/source/filter/xml/xmlcelli.cxx33
-rw-r--r--sc/source/filter/xml/xmlimprt.cxx12
-rw-r--r--sc/source/filter/xml/xmlimprt.hxx7
-rw-r--r--sc/source/filter/xml/xmlsubti.cxx14
9 files changed, 404 insertions, 212 deletions
diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index a42ac8f19c29..045b76a844a3 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -136,6 +136,11 @@ friend class sc::ColumnSpanSet;
ScColumn(const ScColumn&); // disabled
ScColumn& operator= (const ScColumn&); // disabled
+ bool ParseString(
+ ScCellValue& rCell,
+ SCROW nRow, SCTAB nTab, const String& rString, formula::FormulaGrammar::AddressConvention eConv,
+ ScSetStringParam* pParam );
+
public:
ScColumn();
~ScColumn();
@@ -523,12 +528,6 @@ private:
void CopyCellTextAttrsToDocument(SCROW nRow1, SCROW nRow2, ScColumn& rDestCol) const;
- /**
- * Clear and re-populate the cell text attribute array from the non-empty
- * cells stored in the cell array.
- */
- void ResetCellTextAttrs();
-
void SwapCellTextAttrs( SCROW nRow1, SCROW nRow2 );
};
diff --git a/sc/inc/documentimport.hxx b/sc/inc/documentimport.hxx
index 9fddf2b86282..06203019b042 100644
--- a/sc/inc/documentimport.hxx
+++ b/sc/inc/documentimport.hxx
@@ -17,9 +17,12 @@
#include <boost/noncopyable.hpp>
+class EditTextObject;
class ScDocument;
+class ScColumn;
class ScAddress;
class ScTokenArray;
+class ScFormulaCell;
struct ScDocumentImportImpl;
/**
@@ -42,6 +45,8 @@ public:
ScDocument& getDoc();
const ScDocument& getDoc() const;
+ void setDefaultNumericScript(sal_uInt16 nScript);
+
/**
* @param rName sheet name.
*
@@ -57,10 +62,18 @@ public:
void setAutoInput(const ScAddress& rPos, const OUString& rStr);
void setNumericCell(const ScAddress& rPos, double fVal);
void setStringCell(const ScAddress& rPos, const OUString& rStr);
+ void setEditCell(const ScAddress& rPos, EditTextObject* pEditText);
void setFormulaCell(const ScAddress& rPos, const OUString& rFormula, formula::FormulaGrammar::Grammar eGrammar);
void setFormulaCell(const ScAddress& rPos, const ScTokenArray& rArray);
+ void setFormulaCell(const ScAddress& rPos, ScFormulaCell* pCell);
+
+ void setMatrixCells(
+ const ScRange& rRange, const ScTokenArray& rArray, formula::FormulaGrammar::Grammar eGrammar);
void finalize();
+
+private:
+ void initColumn(ScColumn& rCol);
};
#endif
diff --git a/sc/source/core/data/column2.cxx b/sc/source/core/data/column2.cxx
index ab6c88a2e1a5..6a52d8cc8447 100644
--- a/sc/source/core/data/column2.cxx
+++ b/sc/source/core/data/column2.cxx
@@ -1626,41 +1626,6 @@ void ScColumn::CopyCellTextAttrsToDocument(SCROW nRow1, SCROW nRow2, ScColumn& r
}
}
-namespace {
-
-class CellTextAttrInitializer
-{
- sc::CellTextAttrStoreType maAttrs;
- sc::CellTextAttrStoreType::iterator miPos;
-public:
- CellTextAttrInitializer() : maAttrs(MAXROWCOUNT), miPos(maAttrs.begin()) {}
-
- void operator() (const sc::CellStoreType::value_type& node)
- {
- if (node.type == sc::element_type_empty)
- return;
-
- // Fill with default values for non-empty cell segments.
- std::vector<sc::CellTextAttr> aDefaults(node.size);
- miPos = maAttrs.set(miPos, node.position, aDefaults.begin(), aDefaults.end());
- }
-
- void swap(sc::CellTextAttrStoreType& rAttrs)
- {
- maAttrs.swap(rAttrs);
- }
-};
-
-}
-
-void ScColumn::ResetCellTextAttrs()
-{
- CellTextAttrInitializer aFunc;
- std::for_each(maCells.begin(), maCells.end(), aFunc);
- aFunc.swap(maCellTextAttrs);
- CellStorageModified();
-}
-
void ScColumn::SwapCellTextAttrs( SCROW nRow1, SCROW nRow2 )
{
typedef std::pair<sc::CellTextAttrStoreType::iterator,size_t> PosType;
diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx
index a3ccfd1abe40..4474aecebd39 100644
--- a/sc/source/core/data/column3.cxx
+++ b/sc/source/core/data/column3.cxx
@@ -1409,162 +1409,172 @@ void ScColumn::StartListeningInArea( sc::StartListeningContext& rCxt, SCROW nRow
sc::ProcessFormula(maCells.begin(), maCells, nRow1, nRow2, aFunc);
}
-
-/**
- * Returns true if the cell format was set as well
- */
-bool ScColumn::SetString( SCROW nRow, SCTAB nTabP, const String& rString,
- formula::FormulaGrammar::AddressConvention eConv,
- ScSetStringParam* pParam )
+bool ScColumn::ParseString(
+ ScCellValue& rCell, SCROW nRow, SCTAB nTabP, const String& rString,
+ formula::FormulaGrammar::AddressConvention eConv,
+ ScSetStringParam* pParam )
{
- bool bNumFmtSet = false;
- if (!ValidRow(nRow))
+ if (!rString.Len())
return false;
- ScCellValue aNewCell;
- if (rString.Len() > 0)
- {
- ScSetStringParam aParam;
- if (pParam)
- aParam = *pParam;
-
- sal_uInt32 nIndex = 0;
- sal_uInt32 nOldIndex = 0;
- sal_Unicode cFirstChar;
- if (!aParam.mpNumFormatter)
- aParam.mpNumFormatter = pDocument->GetFormatTable();
-
- nIndex = nOldIndex = GetNumberFormat( nRow );
- if ( rString.Len() > 1
- && aParam.mpNumFormatter->GetType(nIndex) != NUMBERFORMAT_TEXT )
- cFirstChar = rString.GetChar(0);
- else
- cFirstChar = 0; // Text
+ bool bNumFmtSet = false;
+
+ ScSetStringParam aParam;
+
+ if (pParam)
+ aParam = *pParam;
+
+ sal_uInt32 nIndex = 0;
+ sal_uInt32 nOldIndex = 0;
+ sal_Unicode cFirstChar;
+ if (!aParam.mpNumFormatter)
+ aParam.mpNumFormatter = pDocument->GetFormatTable();
- if ( cFirstChar == '=' )
+ nIndex = nOldIndex = GetNumberFormat( nRow );
+ if ( rString.Len() > 1
+ && aParam.mpNumFormatter->GetType(nIndex) != NUMBERFORMAT_TEXT )
+ cFirstChar = rString.GetChar(0);
+ else
+ cFirstChar = 0; // Text
+
+ if ( cFirstChar == '=' )
+ {
+ if ( rString.Len() == 1 ) // = Text
+ rCell.set(rString);
+ else // = Formula
+ rCell.set(
+ new ScFormulaCell(
+ pDocument, ScAddress(nCol, nRow, nTabP), rString,
+ formula::FormulaGrammar::mergeToGrammar(formula::FormulaGrammar::GRAM_DEFAULT, eConv),
+ MM_NONE));
+ }
+ else if ( cFirstChar == '\'') // 'Text
+ {
+ bool bNumeric = false;
+ if (aParam.mbHandleApostrophe)
{
- if ( rString.Len() == 1 ) // = Text
- aNewCell.set(rString);
- else // = Formula
- aNewCell.set(
- new ScFormulaCell(
- pDocument, ScAddress(nCol, nRow, nTabP), rString,
- formula::FormulaGrammar::mergeToGrammar(formula::FormulaGrammar::GRAM_DEFAULT, eConv),
- MM_NONE));
+ // Cell format is not 'Text', and the first char
+ // is an apostrophe. Check if the input is considered a number.
+ String aTest = rString.Copy(1);
+ double fTest;
+ bNumeric = aParam.mpNumFormatter->IsNumberFormat(aTest, nIndex, fTest);
+ if (bNumeric)
+ // This is a number. Strip out the first char.
+ rCell.set(aTest);
}
- else if ( cFirstChar == '\'') // 'Text
+ if (!bNumeric)
+ // This is normal text. Take it as-is.
+ rCell.set(rString);
+ }
+ else
+ {
+ double nVal;
+
+ do
{
- bool bNumeric = false;
- if (aParam.mbHandleApostrophe)
+ if (aParam.mbDetectNumberFormat)
{
- // Cell format is not 'Text', and the first char
- // is an apostrophe. Check if the input is considered a number.
- String aTest = rString.Copy(1);
- double fTest;
- bNumeric = aParam.mpNumFormatter->IsNumberFormat(aTest, nIndex, fTest);
- if (bNumeric)
- // This is a number. Strip out the first char.
- aNewCell.set(aTest);
- }
- if (!bNumeric)
- // This is normal text. Take it as-is.
- aNewCell.set(rString);
- }
- else
- {
- double nVal;
+ if (!aParam.mpNumFormatter->IsNumberFormat(rString, nIndex, nVal))
+ break;
- do
- {
- if (aParam.mbDetectNumberFormat)
+ if ( aParam.mpNumFormatter )
{
- if (!aParam.mpNumFormatter->IsNumberFormat(rString, nIndex, nVal))
- break;
+ // convert back to the original language if a built-in format was detected
+ const SvNumberformat* pOldFormat = aParam.mpNumFormatter->GetEntry( nOldIndex );
+ if ( pOldFormat )
+ nIndex = aParam.mpNumFormatter->GetFormatForLanguageIfBuiltIn( nIndex, pOldFormat->GetLanguage() );
+ }
- if ( aParam.mpNumFormatter )
- {
- // convert back to the original language if a built-in format was detected
- const SvNumberformat* pOldFormat = aParam.mpNumFormatter->GetEntry( nOldIndex );
- if ( pOldFormat )
- nIndex = aParam.mpNumFormatter->GetFormatForLanguageIfBuiltIn( nIndex, pOldFormat->GetLanguage() );
- }
+ rCell.set(nVal);
+ if ( nIndex != nOldIndex)
+ {
+ // #i22345# New behavior: Apply the detected number format only if
+ // the old one was the default number, date, time or boolean format.
+ // Exception: If the new format is boolean, always apply it.
- aNewCell.set(nVal);
- if ( nIndex != nOldIndex)
+ bool bOverwrite = false;
+ const SvNumberformat* pOldFormat = aParam.mpNumFormatter->GetEntry( nOldIndex );
+ if ( pOldFormat )
{
- // #i22345# New behavior: Apply the detected number format only if
- // the old one was the default number, date, time or boolean format.
- // Exception: If the new format is boolean, always apply it.
-
- sal_Bool bOverwrite = false;
- const SvNumberformat* pOldFormat = aParam.mpNumFormatter->GetEntry( nOldIndex );
- if ( pOldFormat )
+ short nOldType = pOldFormat->GetType() & ~NUMBERFORMAT_DEFINED;
+ if ( nOldType == NUMBERFORMAT_NUMBER || nOldType == NUMBERFORMAT_DATE ||
+ nOldType == NUMBERFORMAT_TIME || nOldType == NUMBERFORMAT_LOGICAL )
{
- short nOldType = pOldFormat->GetType() & ~NUMBERFORMAT_DEFINED;
- if ( nOldType == NUMBERFORMAT_NUMBER || nOldType == NUMBERFORMAT_DATE ||
- nOldType == NUMBERFORMAT_TIME || nOldType == NUMBERFORMAT_LOGICAL )
+ if ( nOldIndex == aParam.mpNumFormatter->GetStandardFormat(
+ nOldType, pOldFormat->GetLanguage() ) )
{
- if ( nOldIndex == aParam.mpNumFormatter->GetStandardFormat(
- nOldType, pOldFormat->GetLanguage() ) )
- {
- bOverwrite = true; // default of these types can be overwritten
- }
+ bOverwrite = true; // default of these types can be overwritten
}
}
- if ( !bOverwrite && aParam.mpNumFormatter->GetType( nIndex ) == NUMBERFORMAT_LOGICAL )
- {
- bOverwrite = true; // overwrite anything if boolean was detected
- }
+ }
+ if ( !bOverwrite && aParam.mpNumFormatter->GetType( nIndex ) == NUMBERFORMAT_LOGICAL )
+ {
+ bOverwrite = true; // overwrite anything if boolean was detected
+ }
- if ( bOverwrite )
- {
- ApplyAttr( nRow, SfxUInt32Item( ATTR_VALUE_FORMAT,
- (sal_uInt32) nIndex) );
- bNumFmtSet = true;
- }
+ if ( bOverwrite )
+ {
+ ApplyAttr( nRow, SfxUInt32Item( ATTR_VALUE_FORMAT,
+ (sal_uInt32) nIndex) );
+ bNumFmtSet = true;
}
}
- else if (aParam.meSetTextNumFormat != ScSetStringParam::Always)
- {
- // Only check if the string is a regular number.
- const LocaleDataWrapper* pLocale = aParam.mpNumFormatter->GetLocaleData();
- if (!pLocale)
- break;
+ }
+ else if (aParam.meSetTextNumFormat != ScSetStringParam::Always)
+ {
+ // Only check if the string is a regular number.
+ const LocaleDataWrapper* pLocale = aParam.mpNumFormatter->GetLocaleData();
+ if (!pLocale)
+ break;
- LocaleDataItem aLocaleItem = pLocale->getLocaleItem();
- const OUString& rDecSep = aLocaleItem.decimalSeparator;
- const OUString& rGroupSep = aLocaleItem.thousandSeparator;
- if (rDecSep.getLength() != 1 || rGroupSep.getLength() != 1)
- break;
+ LocaleDataItem aLocaleItem = pLocale->getLocaleItem();
+ const OUString& rDecSep = aLocaleItem.decimalSeparator;
+ const OUString& rGroupSep = aLocaleItem.thousandSeparator;
+ if (rDecSep.getLength() != 1 || rGroupSep.getLength() != 1)
+ break;
- sal_Unicode dsep = rDecSep.getStr()[0];
- sal_Unicode gsep = rGroupSep.getStr()[0];
+ sal_Unicode dsep = rDecSep.getStr()[0];
+ sal_Unicode gsep = rGroupSep.getStr()[0];
- if (!ScStringUtil::parseSimpleNumber(rString, dsep, gsep, nVal))
- break;
+ if (!ScStringUtil::parseSimpleNumber(rString, dsep, gsep, nVal))
+ break;
- aNewCell.set(nVal);
- }
+ rCell.set(nVal);
}
- while (false);
+ }
+ while (false);
- if (aNewCell.meType == CELLTYPE_NONE)
+ if (rCell.meType == CELLTYPE_NONE)
+ {
+ if (aParam.meSetTextNumFormat != ScSetStringParam::Never && aParam.mpNumFormatter->IsNumberFormat(rString, nIndex, nVal))
{
- if (aParam.meSetTextNumFormat != ScSetStringParam::Never && aParam.mpNumFormatter->IsNumberFormat(rString, nIndex, nVal))
- {
- // Set the cell format type to Text.
- sal_uInt32 nFormat = aParam.mpNumFormatter->GetStandardFormat(NUMBERFORMAT_TEXT);
- ScPatternAttr aNewAttrs(pDocument->GetPool());
- SfxItemSet& rSet = aNewAttrs.GetItemSet();
- rSet.Put( SfxUInt32Item(ATTR_VALUE_FORMAT, nFormat) );
- ApplyPattern(nRow, aNewAttrs);
- }
-
- aNewCell.set(rString);
+ // Set the cell format type to Text.
+ sal_uInt32 nFormat = aParam.mpNumFormatter->GetStandardFormat(NUMBERFORMAT_TEXT);
+ ScPatternAttr aNewAttrs(pDocument->GetPool());
+ SfxItemSet& rSet = aNewAttrs.GetItemSet();
+ rSet.Put( SfxUInt32Item(ATTR_VALUE_FORMAT, nFormat) );
+ ApplyPattern(nRow, aNewAttrs);
}
+
+ rCell.set(rString);
}
}
+ return bNumFmtSet;
+}
+
+/**
+ * Returns true if the cell format was set as well
+ */
+bool ScColumn::SetString( SCROW nRow, SCTAB nTabP, const String& rString,
+ formula::FormulaGrammar::AddressConvention eConv,
+ ScSetStringParam* pParam )
+{
+ if (!ValidRow(nRow))
+ return false;
+
+ ScCellValue aNewCell;
+ bool bNumFmtSet = ParseString(aNewCell, nRow, nTabP, rString, eConv, pParam);
aNewCell.release(*this, nRow);
// Do not set Formats and Formulas here anymore!
diff --git a/sc/source/core/data/documentimport.cxx b/sc/source/core/data/documentimport.cxx
index 679e04f6b040..bfda2f5a0f2f 100644
--- a/sc/source/core/data/documentimport.cxx
+++ b/sc/source/core/data/documentimport.cxx
@@ -15,13 +15,15 @@
#include "docoptio.hxx"
#include "globalnames.hxx"
#include "mtvelements.hxx"
+#include "tokenarray.hxx"
struct ScDocumentImportImpl
{
ScDocument& mrDoc;
sc::ColumnBlockPositionSet maBlockPosSet;
+ sal_uInt16 mnDefaultScriptNumeric;
- ScDocumentImportImpl(ScDocument& rDoc) : mrDoc(rDoc), maBlockPosSet(rDoc) {}
+ ScDocumentImportImpl(ScDocument& rDoc) : mrDoc(rDoc), maBlockPosSet(rDoc), mnDefaultScriptNumeric(SC_SCRIPTTYPE_UNKNOWN) {}
};
ScDocumentImport::ScDocumentImport(ScDocument& rDoc) : mpImpl(new ScDocumentImportImpl(rDoc)) {}
@@ -40,6 +42,11 @@ const ScDocument& ScDocumentImport::getDoc() const
return mpImpl->mrDoc;
}
+void ScDocumentImport::setDefaultNumericScript(sal_uInt16 nScript)
+{
+ mpImpl->mnDefaultScriptNumeric = nScript;
+}
+
SCTAB ScDocumentImport::getSheetIndex(const OUString& rName) const
{
SCTAB nTab = -1;
@@ -78,8 +85,39 @@ void ScDocumentImport::setAutoInput(const ScAddress& rPos, const OUString& rStr)
if (!pTab)
return;
- pTab->aCol[rPos.Col()].SetString(
- rPos.Row(), rPos.Tab(), rStr, mpImpl->mrDoc.GetAddressConvention());
+ sc::ColumnBlockPosition* pBlockPos =
+ mpImpl->maBlockPosSet.getBlockPosition(rPos.Tab(), rPos.Col());
+
+ if (!pBlockPos)
+ return;
+
+ ScCellValue aCell;
+ pTab->aCol[rPos.Col()].ParseString(
+ aCell, rPos.Row(), rPos.Tab(), rStr, mpImpl->mrDoc.GetAddressConvention(), NULL);
+
+ sc::CellStoreType& rCells = pTab->aCol[rPos.Col()].maCells;
+ switch (aCell.meType)
+ {
+ case CELLTYPE_STRING:
+ // string is copied.
+ pBlockPos->miCellPos = rCells.set(pBlockPos->miCellPos, rPos.Row(), *aCell.mpString);
+ break;
+ case CELLTYPE_EDIT:
+ // Cell takes the ownership of the text object.
+ pBlockPos->miCellPos = rCells.set(pBlockPos->miCellPos, rPos.Row(), aCell.mpEditText);
+ aCell.mpEditText = NULL;
+ break;
+ case CELLTYPE_VALUE:
+ pBlockPos->miCellPos = rCells.set(pBlockPos->miCellPos, rPos.Row(), aCell.mfValue);
+ break;
+ case CELLTYPE_FORMULA:
+ // This formula cell instance is directly placed in the document without copying.
+ pBlockPos->miCellPos = rCells.set(pBlockPos->miCellPos, rPos.Row(), aCell.mpFormula);
+ aCell.mpFormula = NULL;
+ break;
+ default:
+ pBlockPos->miCellPos = rCells.set_empty(pBlockPos->miCellPos, rPos.Row(), rPos.Row());
+ }
}
void ScDocumentImport::setNumericCell(const ScAddress& rPos, double fVal)
@@ -88,7 +126,14 @@ void ScDocumentImport::setNumericCell(const ScAddress& rPos, double fVal)
if (!pTab)
return;
- pTab->aCol[rPos.Col()].SetValue(rPos.Row(), fVal);
+ sc::ColumnBlockPosition* pBlockPos =
+ mpImpl->maBlockPosSet.getBlockPosition(rPos.Tab(), rPos.Col());
+
+ if (!pBlockPos)
+ return;
+
+ sc::CellStoreType& rCells = pTab->aCol[rPos.Col()].maCells;
+ pBlockPos->miCellPos = rCells.set(pBlockPos->miCellPos, rPos.Row(), fVal);
}
void ScDocumentImport::setStringCell(const ScAddress& rPos, const OUString& rStr)
@@ -97,7 +142,30 @@ void ScDocumentImport::setStringCell(const ScAddress& rPos, const OUString& rStr
if (!pTab)
return;
- pTab->aCol[rPos.Col()].SetRawString(rPos.Row(), rStr);
+ sc::ColumnBlockPosition* pBlockPos =
+ mpImpl->maBlockPosSet.getBlockPosition(rPos.Tab(), rPos.Col());
+
+ if (!pBlockPos)
+ return;
+
+ sc::CellStoreType& rCells = pTab->aCol[rPos.Col()].maCells;
+ pBlockPos->miCellPos = rCells.set(pBlockPos->miCellPos, rPos.Row(), rStr);
+}
+
+void ScDocumentImport::setEditCell(const ScAddress& rPos, EditTextObject* pEditText)
+{
+ ScTable* pTab = mpImpl->mrDoc.FetchTable(rPos.Tab());
+ if (!pTab)
+ return;
+
+ sc::ColumnBlockPosition* pBlockPos =
+ mpImpl->maBlockPosSet.getBlockPosition(rPos.Tab(), rPos.Col());
+
+ if (!pBlockPos)
+ return;
+
+ sc::CellStoreType& rCells = pTab->aCol[rPos.Col()].maCells;
+ pBlockPos->miCellPos = rCells.set(pBlockPos->miCellPos, rPos.Row(), pEditText);
}
void ScDocumentImport::setFormulaCell(
@@ -107,8 +175,15 @@ void ScDocumentImport::setFormulaCell(
if (!pTab)
return;
- pTab->aCol[rPos.Col()].SetFormulaCell(
- rPos.Row(), new ScFormulaCell(&mpImpl->mrDoc, rPos, rFormula, eGrammar));
+ sc::ColumnBlockPosition* pBlockPos =
+ mpImpl->maBlockPosSet.getBlockPosition(rPos.Tab(), rPos.Col());
+
+ if (!pBlockPos)
+ return;
+
+ sc::CellStoreType& rCells = pTab->aCol[rPos.Col()].maCells;
+ pBlockPos->miCellPos =
+ rCells.set(pBlockPos->miCellPos, rPos.Row(), new ScFormulaCell(&mpImpl->mrDoc, rPos, rFormula, eGrammar));
}
void ScDocumentImport::setFormulaCell(const ScAddress& rPos, const ScTokenArray& rArray)
@@ -117,8 +192,133 @@ void ScDocumentImport::setFormulaCell(const ScAddress& rPos, const ScTokenArray&
if (!pTab)
return;
- pTab->aCol[rPos.Col()].SetFormulaCell(
- rPos.Row(), new ScFormulaCell(&mpImpl->mrDoc, rPos, &rArray));
+ sc::ColumnBlockPosition* pBlockPos =
+ mpImpl->maBlockPosSet.getBlockPosition(rPos.Tab(), rPos.Col());
+
+ if (!pBlockPos)
+ return;
+
+ sc::CellStoreType& rCells = pTab->aCol[rPos.Col()].maCells;
+ pBlockPos->miCellPos =
+ rCells.set(pBlockPos->miCellPos, rPos.Row(), new ScFormulaCell(&mpImpl->mrDoc, rPos, &rArray));
+}
+
+void ScDocumentImport::setFormulaCell(const ScAddress& rPos, ScFormulaCell* pCell)
+{
+ ScTable* pTab = mpImpl->mrDoc.FetchTable(rPos.Tab());
+ if (!pTab)
+ return;
+
+ sc::ColumnBlockPosition* pBlockPos =
+ mpImpl->maBlockPosSet.getBlockPosition(rPos.Tab(), rPos.Col());
+
+ if (!pBlockPos)
+ return;
+
+ sc::CellStoreType& rCells = pTab->aCol[rPos.Col()].maCells;
+ pBlockPos->miCellPos =
+ rCells.set(pBlockPos->miCellPos, rPos.Row(), pCell);
+}
+
+void ScDocumentImport::setMatrixCells(
+ const ScRange& rRange, const ScTokenArray& rArray, formula::FormulaGrammar::Grammar eGram)
+{
+ const ScAddress& rBasePos = rRange.aStart;
+
+ ScTable* pTab = mpImpl->mrDoc.FetchTable(rBasePos.Tab());
+ if (!pTab)
+ return;
+
+ sc::ColumnBlockPosition* pBlockPos =
+ mpImpl->maBlockPosSet.getBlockPosition(rBasePos.Tab(), rBasePos.Col());
+
+ if (!pBlockPos)
+ return;
+
+ sc::CellStoreType& rCells = pTab->aCol[rBasePos.Col()].maCells;
+
+ // Set the master cell.
+ ScFormulaCell* pCell = new ScFormulaCell(&mpImpl->mrDoc, rBasePos, &rArray, eGram, MM_FORMULA);
+
+ pBlockPos->miCellPos =
+ rCells.set(pBlockPos->miCellPos, rBasePos.Row(), pCell);
+
+ // Set the reference cells.
+ ScSingleRefData aRefData;
+ aRefData.InitFlags();
+ aRefData.SetColRel(true);
+ aRefData.SetRowRel(true);
+ aRefData.SetTabRel(true);
+ aRefData.SetAddress(rBasePos, rBasePos);
+
+ ScTokenArray aArr; // consists only of one single reference token.
+ ScToken* t = static_cast<ScToken*>(aArr.AddMatrixSingleReference(aRefData));
+
+ ScAddress aPos = rBasePos;
+ for (SCROW nRow = rRange.aStart.Row()+1; nRow <= rRange.aEnd.Row(); ++nRow)
+ {
+ // Token array must be cloned so that each formula cell receives its own copy.
+ aPos.SetRow(nRow);
+ // Reference in each cell must point to the origin cell relative to the current cell.
+ aRefData.SetAddress(rBasePos, aPos);
+ t->GetSingleRef() = aRefData;
+ boost::scoped_ptr<ScTokenArray> pTokArr(aArr.Clone());
+ pCell = new ScFormulaCell(&mpImpl->mrDoc, aPos, pTokArr.get(), eGram, MM_REFERENCE);
+ pBlockPos->miCellPos =
+ rCells.set(pBlockPos->miCellPos, aPos.Row(), pCell);
+ }
+
+ for (SCCOL nCol = rRange.aStart.Col()+1; nCol <= rRange.aEnd.Col(); ++nCol)
+ {
+ pBlockPos = mpImpl->maBlockPosSet.getBlockPosition(rBasePos.Tab(), nCol);
+ if (!pBlockPos)
+ return;
+
+ sc::CellStoreType& rColCells = pTab->aCol[nCol].maCells;
+
+ aPos.SetCol(nCol);
+ for (SCROW nRow = rRange.aStart.Row(); nRow <= rRange.aEnd.Row(); ++nRow)
+ {
+ aPos.SetRow(nRow);
+ aRefData.SetAddress(rBasePos, aPos);
+ t->GetSingleRef() = aRefData;
+ boost::scoped_ptr<ScTokenArray> pTokArr(aArr.Clone());
+ pCell = new ScFormulaCell(&mpImpl->mrDoc, aPos, pTokArr.get(), eGram, MM_REFERENCE);
+ pBlockPos->miCellPos =
+ rColCells.set(pBlockPos->miCellPos, aPos.Row(), pCell);
+ }
+ }
+}
+
+namespace {
+
+class CellTextAttrInitializer
+{
+ sc::CellTextAttrStoreType maAttrs;
+ sc::CellTextAttrStoreType::iterator miPos;
+ sal_uInt16 mnScriptNumeric;
+public:
+ CellTextAttrInitializer(sal_uInt16 nScriptNumeric) : maAttrs(MAXROWCOUNT), miPos(maAttrs.begin()), mnScriptNumeric(nScriptNumeric) {}
+
+ void operator() (const sc::CellStoreType::value_type& node)
+ {
+ if (node.type == sc::element_type_empty)
+ return;
+
+ // Fill with default values for non-empty cell segments.
+ sc::CellTextAttr aDefault;
+ if (node.type == sc::element_type_numeric)
+ aDefault.mnScriptType = mnScriptNumeric;
+ std::vector<sc::CellTextAttr> aDefaults(node.size, aDefault);
+ miPos = maAttrs.set(miPos, node.position, aDefaults.begin(), aDefaults.end());
+ }
+
+ void swap(sc::CellTextAttrStoreType& rAttrs)
+ {
+ maAttrs.swap(rAttrs);
+ }
+};
+
}
void ScDocumentImport::finalize()
@@ -134,11 +334,16 @@ void ScDocumentImport::finalize()
ScColumn* pCol = &rTab.aCol[0];
ScColumn* pColEnd = pCol + static_cast<size_t>(MAXCOLCOUNT);
for (; pCol != pColEnd; ++pCol)
- {
- ScColumn& rCol = *pCol;
- rCol.ResetCellTextAttrs();
- }
+ initColumn(*pCol);
}
}
+void ScDocumentImport::initColumn(ScColumn& rCol)
+{
+ CellTextAttrInitializer aFunc(mpImpl->mnDefaultScriptNumeric);
+ std::for_each(rCol.maCells.begin(), rCol.maCells.end(), aFunc);
+ aFunc.swap(rCol.maCellTextAttrs);
+ rCol.CellStorageModified();
+}
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/xml/xmlcelli.cxx b/sc/source/filter/xml/xmlcelli.cxx
index 5b1c58fa69a8..318f591dd6f8 100644
--- a/sc/source/filter/xml/xmlcelli.cxx
+++ b/sc/source/filter/xml/xmlcelli.cxx
@@ -51,6 +51,7 @@
#include "stringutil.hxx"
#include "tokenarray.hxx"
#include "scmatrix.hxx"
+#include "documentimport.hxx"
#include <xmloff/xmltkmap.hxx>
#include <xmloff/xmltoken.hxx>
@@ -1050,10 +1051,10 @@ void ScXMLTableRowCellContext::PutTextCell( const ScAddress& rCurrentPos,
}
else //regular text cells
{
- ScDocument* pDoc = rXMLImport.GetDocument();
+ ScDocumentImport& rDoc = rXMLImport.GetDoc();
if (maStringValue)
{
- pDoc->SetTextCell(rCurrentPos, *maStringValue);
+ rDoc.setStringCell(rCurrentPos, *maStringValue);
bDoIncrement = true;
}
else if (mbEditEngineHasText)
@@ -1061,9 +1062,7 @@ void ScXMLTableRowCellContext::PutTextCell( const ScAddress& rCurrentPos,
if (maFields.empty() && maFormats.empty() && mpEditEngine->GetParagraphCount() == 1)
{
// This is a normal text without format runs.
- ScSetStringParam aParam;
- aParam.setTextInput();
- pDoc->SetString(rCurrentPos, mpEditEngine->GetText(), &aParam);
+ rDoc.setStringCell(rCurrentPos, mpEditEngine->GetText());
}
else
{
@@ -1083,13 +1082,13 @@ void ScXMLTableRowCellContext::PutTextCell( const ScAddress& rCurrentPos,
// This edit engine uses the SfxItemPool instance returned
// from pDoc->GetEditPool() to create the text object, which
// is a prerequisite for using this constructor of ScEditCell.
- pDoc->SetEditText(rCurrentPos, mpEditEngine->CreateTextObject());
+ rDoc.setEditCell(rCurrentPos, mpEditEngine->CreateTextObject());
}
bDoIncrement = true;
}
else if ( nCurrentCol > 0 && pOUText && !pOUText->isEmpty() )
{
- pDoc->SetTextCell(rCurrentPos, *pOUText);
+ rDoc.setStringCell(rCurrentPos, *pOUText);
bDoIncrement = true;
}
else
@@ -1123,10 +1122,7 @@ void ScXMLTableRowCellContext::PutValueCell( const ScAddress& rCurrentPos )
// style's number format is latin-only. If the cell uses a different
// format, the script type will be reset when the style is applied.
- ScDocument* pDoc = rXMLImport.GetDocument();
- pDoc->SetValue(rCurrentPos, fValue);
- if ( rXMLImport.IsLatinDefaultStyle() )
- pDoc->SetScriptType(rCurrentPos, SCRIPTTYPE_LATIN);
+ rXMLImport.GetDoc().setNumericCell(rCurrentPos, fValue);
}
rXMLImport.ProgressBarIncrement(false);
}
@@ -1324,6 +1320,7 @@ void ScXMLTableRowCellContext::AddNonFormulaCell( const ScAddress& rCellPos )
void ScXMLTableRowCellContext::PutFormulaCell( const ScAddress& rCellPos )
{
ScDocument* pDoc = rXMLImport.GetDocument();
+ ScDocumentImport& rDoc = rXMLImport.GetDoc();
OUString aText = maFormula->first;
OUString aFormulaNmsp = maFormula->second;
@@ -1331,7 +1328,6 @@ void ScXMLTableRowCellContext::PutFormulaCell( const ScAddress& rCellPos )
::boost::scoped_ptr<ScExternalRefManager::ApiGuard> pExtRefGuard (
new ScExternalRefManager::ApiGuard(pDoc));
-
if ( !aText.isEmpty() )
{
if ( aText[0] == '=' && aText.getLength() > 1 )
@@ -1342,18 +1338,17 @@ void ScXMLTableRowCellContext::PutFormulaCell( const ScAddress& rCellPos )
if( (eGrammar == formula::FormulaGrammar::GRAM_EXTERNAL) && !aFormulaNmsp.isEmpty() )
pCode->AddStringXML( aFormulaNmsp );
- pDoc->IncXMLImportedFormulaCount( aText.getLength() );
+ rDoc.getDoc().IncXMLImportedFormulaCount( aText.getLength() );
ScFormulaCell* pNewCell = new ScFormulaCell(pDoc, rCellPos, pCode.get(), eGrammar, MM_NONE);
SetFormulaCell(pNewCell);
- pNewCell = pDoc->SetFormulaCell(rCellPos, pNewCell);
- if (pNewCell)
- pNewCell->SetNeedNumberFormat( true );
+ rDoc.setFormulaCell(rCellPos, pNewCell);
+ pNewCell->SetNeedNumberFormat( true );
}
else if ( aText[0] == '\'' && aText.getLength() > 1 )
{
// for bEnglish, "'" at the beginning is always interpreted as text
// marker and stripped
- pDoc->SetTextCell(rCellPos, aText.copy(1));
+ rDoc.setStringCell(rCellPos, aText.copy(1));
}
else
{
@@ -1361,11 +1356,11 @@ void ScXMLTableRowCellContext::PutFormulaCell( const ScAddress& rCellPos )
sal_uInt32 nEnglish = pFormatter->GetStandardIndex(LANGUAGE_ENGLISH_US);
double fVal;
if ( pFormatter->IsNumberFormat( aText, nEnglish, fVal ) )
- pDoc->SetValue(rCellPos, fVal);
+ rDoc.setNumericCell(rCellPos, fVal);
//the (english) number format will not be set
//search matching local format and apply it
else
- pDoc->SetTextCell(rCellPos, aText);
+ rDoc.setStringCell(rCellPos, aText);
}
}
}
diff --git a/sc/source/filter/xml/xmlimprt.cxx b/sc/source/filter/xml/xmlimprt.cxx
index 3396b01b8235..c1bbd3a0592b 100644
--- a/sc/source/filter/xml/xmlimprt.cxx
+++ b/sc/source/filter/xml/xmlimprt.cxx
@@ -66,6 +66,7 @@
#include "externalrefmgr.hxx"
#include "editutil.hxx"
#include "editattributemap.hxx"
+#include "documentimport.hxx"
#include <comphelper/extract.hxx>
@@ -2073,7 +2074,6 @@ ScXMLImport::ScXMLImport(
bRemoveLastChar(false),
bNullDateSetted(false),
bSelfImportingXMLSet(false),
- bLatinDefaultStyle(false),
bFromWrapper(false),
mbHasNewCondFormatData(false)
{
@@ -2314,6 +2314,11 @@ void ScXMLImport::SetStatistics(
}
}
+ScDocumentImport& ScXMLImport::GetDoc()
+{
+ return *mpDocImport;
+}
+
sal_Int16 ScXMLImport::GetCellType(const OUString& rStrValue) const
{
CellTypeMap::const_iterator itr = aCellTypeMap.find(rStrValue);
@@ -2420,7 +2425,7 @@ void ScXMLImport::ExamineDefaultStyle()
sal_uInt8 nScript = pDoc->GetStringScriptType( aDecSep );
if ( nScript == 0 || nScript == SCRIPTTYPE_LATIN )
- bLatinDefaultStyle = true;
+ mpDocImport->setDefaultNumericScript(SCRIPTTYPE_LATIN);
}
}
}
@@ -2928,6 +2933,7 @@ throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::R
if (!pDoc)
throw lang::IllegalArgumentException();
+ mpDocImport.reset(new ScDocumentImport(*pDoc));
mpComp.reset(new ScCompiler(pDoc, ScAddress()));
mpComp->SetGrammar(formula::FormulaGrammar::GRAM_ODFF);
@@ -3198,6 +3204,8 @@ throw( ::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeE
{
if (GetModel().is())
{
+ mpDocImport->finalize();
+
uno::Reference<document::XViewDataSupplier> xViewDataSupplier(GetModel(), uno::UNO_QUERY);
if (xViewDataSupplier.is())
{
diff --git a/sc/source/filter/xml/xmlimprt.hxx b/sc/source/filter/xml/xmlimprt.hxx
index db952dbd510f..d4d45a79db1a 100644
--- a/sc/source/filter/xml/xmlimprt.hxx
+++ b/sc/source/filter/xml/xmlimprt.hxx
@@ -53,6 +53,7 @@
class ScMyStyleNumberFormats;
class XMLNumberFormatAttributesExportHelper;
class ScEditEngineDefaulter;
+class ScDocumentImport;
enum ScXMLDocTokens
{
@@ -802,6 +803,7 @@ class ScXMLImport: public SvXMLImport, boost::noncopyable
CellTypeMap aCellTypeMap;
ScDocument* pDoc;
+ boost::scoped_ptr<ScDocumentImport> mpDocImport;
boost::scoped_ptr<ScCompiler> mpComp; // For error-checking of cached string cell values.
boost::scoped_ptr<ScEditEngineDefaulter> mpEditEngine;
mutable boost::scoped_ptr<ScXMLEditAttributeMap> mpEditAttrMap;
@@ -935,7 +937,6 @@ class ScXMLImport: public SvXMLImport, boost::noncopyable
bool bRemoveLastChar;
bool bNullDateSetted;
bool bSelfImportingXMLSet;
- bool bLatinDefaultStyle; // latin-only number format in default style?
bool bFromWrapper; // called from ScDocShell / ScXMLImportWrapper?
bool mbHasNewCondFormatData;
@@ -976,6 +977,8 @@ public:
virtual void SetStatistics(
const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue> & i_rStats);
+ ScDocumentImport& GetDoc();
+
inline ScDocument* GetDocument() { return pDoc; }
inline const ScDocument* GetDocument() const { return pDoc; }
@@ -984,8 +987,6 @@ public:
sal_uInt16 GetStyleFamilyMask() const { return nStyleFamilyMask; }
bool IsStylesOnlyMode() const { return !bLoadDoc; }
- bool IsLatinDefaultStyle() const { return bLatinDefaultStyle; }
-
sal_Int16 GetCellType(const OUString& rStrValue) const;
UniReference < XMLPropertySetMapper > GetCellStylesPropertySetMapper() const { return xCellStylesPropertySetMapper; }
diff --git a/sc/source/filter/xml/xmlsubti.cxx b/sc/source/filter/xml/xmlsubti.cxx
index b7d8ed3fe372..3cc05839ccd3 100644
--- a/sc/source/filter/xml/xmlsubti.cxx
+++ b/sc/source/filter/xml/xmlsubti.cxx
@@ -31,6 +31,8 @@
#include "tabprotection.hxx"
#include "tokenarray.hxx"
#include "convuno.hxx"
+#include "documentimport.hxx"
+
#include <svx/svdpage.hxx>
#include <sax/tools/converter.hxx>
@@ -279,19 +281,13 @@ void ScMyTables::AddMatrixRange(
maMatrixRangeList.Append(aScRange);
- ScDocument* pDoc = rImport.GetDocument();
- ScMarkData aMark;
- aMark.SetMarkArea( aScRange );
- aMark.SelectTable( aScRange.aStart.Tab(), sal_True );
+ ScDocumentImport& rDoc = rImport.GetDoc();
boost::scoped_ptr<ScTokenArray> pCode(new ScTokenArray);
pCode->AddStringXML( rFormula );
if( (eGrammar == formula::FormulaGrammar::GRAM_EXTERNAL) && !rFormulaNmsp.isEmpty() )
pCode->AddStringXML( rFormulaNmsp );
- pDoc->InsertMatrixFormula(
- nStartColumn, nStartRow,
- nEndColumn, nEndRow,
- aMark, EMPTY_OUSTRING, pCode.get(), eGrammar, false );
- pDoc->IncXMLImportedFormulaCount( rFormula.getLength() );
+ rDoc.setMatrixCells(aScRange, *pCode, eGrammar);
+ rDoc.getDoc().IncXMLImportedFormulaCount( rFormula.getLength() );
}
bool ScMyTables::IsPartOfMatrix(const ScAddress& rScAddress) const