summaryrefslogtreecommitdiff
path: root/sc
diff options
context:
space:
mode:
authorKohei Yoshida <kohei.yoshida@gmail.com>2013-08-01 22:01:26 -0400
committerEike Rathke <erack@redhat.com>2013-08-05 15:09:13 +0000
commit09ce92dc51ebf75cfe021ccbaa4020b87b27360b (patch)
tree98c32f71592071f772b8dd74bccf53adc469b7ed /sc
parentcce481aa3184e3b00f7cc6f0a6d2a496ab19a6fd (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. Conflicts: sc/inc/column.hxx sc/inc/documentimport.hxx sc/source/core/data/column2.cxx sc/source/core/data/column3.cxx sc/source/core/data/documentimport.cxx sc/source/filter/xml/xmlcelli.cxx and a whole bunch of changes backported in order retrofit this code in the 4.1 branch. Change-Id: Ie59d6877d1ac4fc04751a84b663772a9dc9a3efc Reviewed-on: https://gerrit.libreoffice.org/5258 Reviewed-by: Michael Meeks <michael.meeks@suse.com> Reviewed-by: Eike Rathke <erack@redhat.com> Tested-by: Eike Rathke <erack@redhat.com>
Diffstat (limited to 'sc')
-rw-r--r--sc/inc/cellvalue.hxx9
-rw-r--r--sc/inc/column.hxx7
-rw-r--r--sc/inc/documentimport.hxx13
-rw-r--r--sc/source/core/data/cellvalue.cxx66
-rw-r--r--sc/source/core/data/column3.cxx347
-rw-r--r--sc/source/core/data/documentimport.cxx239
-rw-r--r--sc/source/filter/xml/xmlcelli.cxx31
-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
10 files changed, 485 insertions, 260 deletions
diff --git a/sc/inc/cellvalue.hxx b/sc/inc/cellvalue.hxx
index bdb483e3bd4d..674fc722a16b 100644
--- a/sc/inc/cellvalue.hxx
+++ b/sc/inc/cellvalue.hxx
@@ -13,6 +13,7 @@
#include "global.hxx"
class ScDocument;
+class ScColumn;
class ScFormulaCell;
class EditTextObject;
class ScBaseCell;
@@ -42,6 +43,12 @@ struct SC_DLLPUBLIC ScCellValue
void clear();
+ void set( double fValue );
+ void set( const OUString& rStr );
+ void set( const EditTextObject& rEditText );
+ void set( const ScFormulaCell& rFormula );
+ void set( ScFormulaCell* pFormula );
+
/**
* Take cell value from specified position in specified document.
*/
@@ -66,6 +73,8 @@ struct SC_DLLPUBLIC ScCellValue
*/
void release( ScDocument& rDoc, const ScAddress& rPos );
+ void release( ScColumn& rColumn, SCROW nRow );
+
bool hasString() const;
bool hasNumeric() const;
diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index 935c07e9ca15..1dd462d1b7b4 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -76,6 +76,7 @@ struct ScSetStringParam;
struct ScColWidthParam;
class ScColumnTextWidthIterator;
struct ScFormulaCellGroup;
+struct ScCellValue;
struct ScRefCellValue;
class ScDocumentImport;
@@ -156,6 +157,11 @@ friend class ScDocumentImport;
std::vector<ColEntry>::iterator Search( SCROW nRow );
std::vector<ColEntry>::const_iterator Search( SCROW nRow ) const;
+ bool ParseString(
+ ScCellValue& rCell,
+ SCROW nRow, SCTAB nTab, const String& rString, formula::FormulaGrammar::AddressConvention eConv,
+ ScSetStringParam* pParam );
+
public:
ScColumn();
~ScColumn();
@@ -287,6 +293,7 @@ public:
void SetFormula( SCROW nRow, const OUString& rFormula, formula::FormulaGrammar::Grammar eGram );
void SetFormulaCell( SCROW nRow, ScFormulaCell* pCell );
+ void SetRawString( SCROW nRow, const OUString& rStr );
void SetValue( SCROW nRow, const double& rVal);
void SetError( SCROW nRow, const sal_uInt16 nError);
diff --git a/sc/inc/documentimport.hxx b/sc/inc/documentimport.hxx
index afd954bf93d5..8a980c43c342 100644
--- a/sc/inc/documentimport.hxx
+++ b/sc/inc/documentimport.hxx
@@ -17,10 +17,13 @@
#include <boost/noncopyable.hpp>
+class EditTextObject;
class ScDocument;
+class ScColumn;
class ScAddress;
class ScTokenArray;
class ScBaseCell;
+class ScFormulaCell;
struct ScDocumentImportImpl;
/**
@@ -43,6 +46,8 @@ public:
ScDocument& getDoc();
const ScDocument& getDoc() const;
+ void setDefaultNumericScript(sal_uInt16 nScript);
+
/**
* @param rName sheet name.
*
@@ -58,13 +63,19 @@ 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 insertCell(const ScAddress& rPos, ScBaseCell* pCell);
+ void setCell(ScColumn& rCol, SCROW nRow, ScBaseCell* pCell);
+ void initColumn(ScColumn& rCol);
};
#endif
diff --git a/sc/source/core/data/cellvalue.cxx b/sc/source/core/data/cellvalue.cxx
index 78683e65de26..c82f2904e624 100644
--- a/sc/source/core/data/cellvalue.cxx
+++ b/sc/source/core/data/cellvalue.cxx
@@ -16,6 +16,7 @@
#include "stringutil.hxx"
#include "editutil.hxx"
#include "tokenarray.hxx"
+#include "column.hxx"
#include "formula/token.hxx"
namespace {
@@ -182,6 +183,41 @@ void ScCellValue::clear()
mfValue = 0.0;
}
+void ScCellValue::set( double fValue )
+{
+ clear();
+ meType = CELLTYPE_VALUE;
+ mfValue = fValue;
+}
+
+void ScCellValue::set( const OUString& rStr )
+{
+ clear();
+ meType = CELLTYPE_STRING;
+ mpString = new OUString(rStr);
+}
+
+void ScCellValue::set( const EditTextObject& rEditText )
+{
+ clear();
+ meType = CELLTYPE_EDIT;
+ mpEditText = rEditText.Clone();
+}
+
+void ScCellValue::set( const ScFormulaCell& rFormula )
+{
+ clear();
+ meType = CELLTYPE_FORMULA;
+ mpFormula = rFormula.Clone();
+}
+
+void ScCellValue::set( ScFormulaCell* pFormula )
+{
+ clear();
+ meType = CELLTYPE_FORMULA;
+ mpFormula = pFormula;
+}
+
void ScCellValue::assign( const ScDocument& rDoc, const ScAddress& rPos )
{
clear();
@@ -340,6 +376,36 @@ void ScCellValue::release( ScDocument& rDoc, const ScAddress& rPos )
mfValue = 0.0;
}
+void ScCellValue::release( ScColumn& rColumn, SCROW nRow )
+{
+ switch (meType)
+ {
+ case CELLTYPE_STRING:
+ {
+ // Currently, string cannot be placed without copying.
+ rColumn.SetRawString(nRow, *mpString);
+ delete mpString;
+ }
+ break;
+ case CELLTYPE_EDIT:
+ // Cell takes the ownership of the text object.
+ rColumn.SetEditText(nRow, mpEditText);
+ break;
+ case CELLTYPE_VALUE:
+ rColumn.SetValue(nRow, mfValue);
+ break;
+ case CELLTYPE_FORMULA:
+ // This formula cell instance is directly placed in the document without copying.
+ rColumn.SetFormulaCell(nRow, mpFormula);
+ break;
+ default:
+ rColumn.Delete(nRow);
+ }
+
+ meType = CELLTYPE_NONE;
+ mfValue = 0.0;
+}
+
bool ScCellValue::hasString() const
{
return hasStringImpl(meType, mpFormula);
diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx
index 2a242207ede1..c5e629a09ae2 100644
--- a/sc/source/core/data/column3.cxx
+++ b/sc/source/core/data/column3.cxx
@@ -1185,248 +1185,173 @@ void ScColumn::StartListeningInArea( sc::StartListeningContext& rCxt, SCROW nRow
}
}
-
-/**
- * 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;
- ScBaseCell* pNewCell = NULL;
- sal_Bool bIsLoading = false;
- if (rString.Len() > 0)
+ 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();
+
+ nIndex = nOldIndex = GetNumberFormat( nRow );
+ if ( rString.Len() > 1
+ && aParam.mpNumFormatter->GetType(nIndex) != NUMBERFORMAT_TEXT )
+ cFirstChar = rString.GetChar(0);
+ else
+ cFirstChar = 0; // Text
+
+ if ( cFirstChar == '=' )
{
- ScSetStringParam aParam;
- if (pParam)
- aParam = *pParam;
-
- sal_uInt32 nIndex = 0;
- sal_uInt32 nOldIndex = 0;
- sal_Unicode cFirstChar;
- if (!aParam.mpNumFormatter)
- aParam.mpNumFormatter = pDocument->GetFormatTable();
- SfxObjectShell* pDocSh = pDocument->GetDocumentShell();
- if ( pDocSh )
- bIsLoading = pDocSh->IsLoading();
- // IsLoading for ConvertFrom import
- if ( !bIsLoading )
+ 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)
{
- nIndex = nOldIndex = GetNumberFormat( nRow );
- if ( rString.Len() > 1
- && aParam.mpNumFormatter->GetType(nIndex) != NUMBERFORMAT_TEXT )
- cFirstChar = rString.GetChar(0);
- else
- cFirstChar = 0; // Text
- }
- else
- { // There are not applied formats when importing during ConvertFrom
- cFirstChar = rString.GetChar(0);
+ // 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);
}
+ if (!bNumeric)
+ // This is normal text. Take it as-is.
+ rCell.set(rString);
+ }
+ else
+ {
+ double nVal;
- if ( cFirstChar == '=' )
- {
- if ( rString.Len() == 1 ) // = Text
- pNewCell = new ScStringCell( rString );
- else // = Formula
- pNewCell = new ScFormulaCell( pDocument,
- ScAddress( nCol, nRow, nTabP ), rString,
- formula::FormulaGrammar::mergeToGrammar( formula::FormulaGrammar::GRAM_DEFAULT,
- eConv), MM_NONE );
- }
- else if ( cFirstChar == '\'') // 'Text
+ 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.
- pNewCell = new ScStringCell(aTest);
- }
- if (!bNumeric)
- // This is normal text. Take it as-is.
- pNewCell = new ScStringCell(rString);
- }
- else
- {
- double nVal;
- sal_Bool bIsText = false;
- if ( bIsLoading )
- {
- if ( !maItems.empty() )
- {
- String aStr;
- SCSIZE i = maItems.size();
- SCSIZE nStop = (i >= 3 ? i - 3 : 0);
- // Compare the last lines and see whether same String
- // and IsNumberFormat can be made obsolete
- do
- {
- i--;
- ScBaseCell* pCell = maItems[i].pCell;
- switch ( pCell->GetCellType() )
- {
- case CELLTYPE_STRING :
- aStr = ((ScStringCell*)pCell)->GetString();
- if ( rString == aStr )
- bIsText = true;
- break;
- default:
- if ( i == maItems.size() - 1 )
- i = 0;
- // Probably whole column and no String
- }
- } while ( i && i > nStop && !bIsText );
- }
- // Prefill nIndex for IsNumberFormat
- if ( !bIsText )
- nIndex = nOldIndex = aParam.mpNumFormatter->GetStandardIndex();
- }
-
- do
- {
- if (bIsText)
+ if (!aParam.mpNumFormatter->IsNumberFormat(rString, nIndex, nVal))
break;
- 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.
- pNewCell = new ScValueCell( 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;
- pNewCell = new ScValueCell(nVal);
- }
+ rCell.set(nVal);
}
- while (false);
+ }
+ while (false);
- if (!pNewCell)
+ 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);
- }
-
- pNewCell = new ScStringCell(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);
}
}
- if ( bIsLoading && (maItems.empty() || nRow > maItems.back().nRow) )
- { // Save search and build up Listener without a detour via Insert
- // Broadcast comes after Loading
- if ( pNewCell )
- Append( nRow, pNewCell );
- }
- else
- {
- SCSIZE i;
- if (Search(nRow, i))
- {
- ScBaseCell* pOldCell = maItems[i].pCell;
- if (pNewCell)
- {
- if ( pOldCell->GetCellType() == CELLTYPE_FORMULA )
- static_cast<ScFormulaCell*>(pOldCell)->EndListeningTo(pDocument);
+ return bNumFmtSet;
+}
- pOldCell->Delete();
- maItems[i].pCell = pNewCell; // Replace
- maCellTextAttrs.set<sc::CellTextAttr>(nRow, sc::CellTextAttr());
- CellStorageModified();
+/**
+ * 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;
- if ( pNewCell->GetCellType() == CELLTYPE_FORMULA )
- {
- static_cast<ScFormulaCell*>(pNewCell)->StartListeningTo(pDocument);
- ((ScFormulaCell*)pNewCell)->SetDirty();
- }
- else
- pDocument->Broadcast(
- ScHint(SC_HINT_DATACHANGED, ScAddress(nCol, nRow, nTabP)));
- }
- else
- {
- DeleteAtIndex(i); // Delete and Broadcast
- }
- }
- else if (pNewCell)
- {
- Insert(nRow, pNewCell); // Re-insert and Broadcast
- }
- }
+ ScCellValue aNewCell;
+ bool bNumFmtSet = ParseString(aNewCell, nRow, nTabP, rString, eConv, pParam);
+ aNewCell.release(*this, nRow);
// Do not set Formats and Formulas here anymore!
// These are queried during output
@@ -1685,6 +1610,14 @@ void ScColumn::SetError( SCROW nRow, const sal_uInt16 nError)
}
}
+void ScColumn::SetRawString( SCROW nRow, const OUString& rStr )
+{
+ if (!ValidRow(nRow))
+ return;
+
+ ScBaseCell* pCell = new ScStringCell(rStr);
+ Insert(nRow, pCell);
+}
void ScColumn::SetValue( SCROW nRow, const double& rVal)
{
diff --git a/sc/source/core/data/documentimport.cxx b/sc/source/core/data/documentimport.cxx
index ec5b1c498d24..77687166dc43 100644
--- a/sc/source/core/data/documentimport.cxx
+++ b/sc/source/core/data/documentimport.cxx
@@ -16,13 +16,16 @@
#include "docoptio.hxx"
#include "globalnames.hxx"
#include "mtvelements.hxx"
+#include "tokenarray.hxx"
+#include "cellvalue.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)) {}
@@ -41,6 +44,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;
@@ -75,32 +83,195 @@ void ScDocumentImport::setOriginDate(sal_uInt16 nYear, sal_uInt16 nMonth, sal_uI
void ScDocumentImport::setAutoInput(const ScAddress& rPos, const OUString& rStr)
{
- if (!mpImpl->mrDoc.TableExists(rPos.Tab()))
+ ScTable* pTab = mpImpl->mrDoc.FetchTable(rPos.Tab());
+ if (!pTab)
return;
- mpImpl->mrDoc.maTabs[rPos.Tab()]->aCol[rPos.Col()].SetString(
- rPos.Row(), rPos.Tab(), rStr, mpImpl->mrDoc.GetAddressConvention());
+ ScCellValue aCell;
+ pTab->aCol[rPos.Col()].ParseString(
+ aCell, rPos.Row(), rPos.Tab(), rStr, mpImpl->mrDoc.GetAddressConvention(), NULL);
+
+ ScColumn& rCol = pTab->aCol[rPos.Col()];
+ switch (aCell.meType)
+ {
+ case CELLTYPE_STRING:
+ // string is copied.
+ setCell(rCol, rPos.Row(), new ScStringCell(*aCell.mpString));
+ break;
+ case CELLTYPE_EDIT:
+ // Cell takes the ownership of the text object.
+ setCell(rCol, rPos.Row(), new ScEditCell(aCell.mpEditText, &mpImpl->mrDoc));
+ aCell.mpEditText = NULL;
+ break;
+ case CELLTYPE_VALUE:
+ setCell(rCol, rPos.Row(), new ScValueCell(aCell.mfValue));
+ break;
+ case CELLTYPE_FORMULA:
+ // This formula cell instance is directly placed in the document without copying.
+ setCell(rCol, rPos.Row(), aCell.mpFormula);
+ aCell.mpFormula = NULL;
+ break;
+ default:
+ ;
+ }
}
void ScDocumentImport::setNumericCell(const ScAddress& rPos, double fVal)
{
- insertCell(rPos, new ScValueCell(fVal));
+ ScTable* pTab = mpImpl->mrDoc.FetchTable(rPos.Tab());
+ if (!pTab)
+ return;
+
+ ScColumn& rCol = pTab->aCol[rPos.Col()];
+ setCell(rCol, rPos.Row(), new ScValueCell(fVal));
}
void ScDocumentImport::setStringCell(const ScAddress& rPos, const OUString& rStr)
{
- insertCell(rPos, new ScStringCell(rStr));
+ ScTable* pTab = mpImpl->mrDoc.FetchTable(rPos.Tab());
+ if (!pTab)
+ return;
+
+ ScColumn& rCol = pTab->aCol[rPos.Col()];
+ setCell(rCol, rPos.Row(), new ScStringCell(rStr));
+}
+
+void ScDocumentImport::setEditCell(const ScAddress& rPos, EditTextObject* pEditText)
+{
+ ScTable* pTab = mpImpl->mrDoc.FetchTable(rPos.Tab());
+ if (!pTab)
+ return;
+
+ ScColumn& rCol = pTab->aCol[rPos.Col()];
+ setCell(rCol, rPos.Row(), new ScEditCell(pEditText, &mpImpl->mrDoc));
}
void ScDocumentImport::setFormulaCell(
const ScAddress& rPos, const OUString& rFormula, formula::FormulaGrammar::Grammar eGrammar)
{
- insertCell(rPos, new ScFormulaCell(&mpImpl->mrDoc, rPos, rFormula, eGrammar));
+ ScTable* pTab = mpImpl->mrDoc.FetchTable(rPos.Tab());
+ if (!pTab)
+ return;
+
+ ScColumn& rCol = pTab->aCol[rPos.Col()];
+ setCell(rCol, rPos.Row(), new ScFormulaCell(&mpImpl->mrDoc, rPos, rFormula, eGrammar));
}
void ScDocumentImport::setFormulaCell(const ScAddress& rPos, const ScTokenArray& rArray)
{
- insertCell(rPos, new ScFormulaCell(&mpImpl->mrDoc, rPos, &rArray));
+ ScTable* pTab = mpImpl->mrDoc.FetchTable(rPos.Tab());
+ if (!pTab)
+ return;
+
+ ScColumn& rCol = pTab->aCol[rPos.Col()];
+ setCell(rCol, 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;
+
+ ScColumn& rCol = pTab->aCol[rPos.Col()];
+ setCell(rCol, 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;
+
+ ScColumn& rCol = pTab->aCol[rBasePos.Col()];
+
+ // Set the master cell.
+ ScFormulaCell* pCell = new ScFormulaCell(&mpImpl->mrDoc, rBasePos, &rArray, eGram, MM_FORMULA);
+ setCell(rCol, rBasePos.Row(), pCell);
+
+ // Set the reference cells.
+ ScSingleRefData aRefData;
+ aRefData.InitFlags();
+ aRefData.SetColRel(true);
+ aRefData.SetRowRel(true);
+ aRefData.SetTabRel(true);
+ aRefData.nRelCol = 0;
+ aRefData.nRelRow = 0;
+ aRefData.nRelTab = 0;
+
+ 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.nRelRow = rBasePos.Row() - nRow;
+ t->GetSingleRef() = aRefData;
+ boost::scoped_ptr<ScTokenArray> pTokArr(aArr.Clone());
+ pCell = new ScFormulaCell(&mpImpl->mrDoc, aPos, pTokArr.get(), eGram, MM_REFERENCE);
+ setCell(rCol, 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;
+
+ ScColumn& rCol2 = pTab->aCol[nCol];
+
+ aPos.SetCol(nCol);
+ aRefData.nRelRow = 0;
+ aRefData.nRelCol = rBasePos.Col() - nCol;
+
+ for (SCROW nRow = rRange.aStart.Row(); nRow <= rRange.aEnd.Row(); ++nRow)
+ {
+ aPos.SetRow(nRow);
+ aRefData.nRelRow = rBasePos.Row() - nRow;
+ t->GetSingleRef() = aRefData;
+ boost::scoped_ptr<ScTokenArray> pTokArr(aArr.Clone());
+ pCell = new ScFormulaCell(&mpImpl->mrDoc, aPos, pTokArr.get(), eGram, MM_REFERENCE);
+ setCell(rCol2, 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 ColEntry& rEntry)
+ {
+ sc::CellTextAttr aDefault;
+ if (rEntry.pCell->GetCellType() == CELLTYPE_VALUE)
+ aDefault.mnScriptType = mnScriptNumeric;
+ miPos = maAttrs.set(miPos, rEntry.nRow, aDefault);
+ }
+
+ void swap(sc::CellTextAttrStoreType& rAttrs)
+ {
+ maAttrs.swap(rAttrs);
+ }
+};
+
}
void ScDocumentImport::finalize()
@@ -116,27 +287,53 @@ 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::insertCell(const ScAddress& rPos, ScBaseCell* pCell)
+void ScDocumentImport::setCell(ScColumn& rCol, SCROW nRow, ScBaseCell* pCell)
{
- if (!mpImpl->mrDoc.TableExists(rPos.Tab()))
+ if (pCell->GetCellType() == CELLTYPE_FORMULA)
{
- pCell->Delete();
- return;
+ ScFormulaCell* pFCell = static_cast<ScFormulaCell*>(pCell);
+ sal_uInt32 nCellFormat = rCol.GetNumberFormat(nRow);
+ if ((nCellFormat % SV_COUNTRY_LANGUAGE_OFFSET) == 0)
+ pFCell->SetNeedNumberFormat(true);
+ }
+
+ std::vector<ColEntry>& rItems = rCol.maItems;
+ if (!rItems.empty())
+ {
+ if (rItems.back().nRow < nRow)
+ {
+ rItems.push_back(ColEntry());
+ rItems.back().pCell = pCell;
+ rItems.back().nRow = nRow;
+ return;
+ }
}
- ScColumn& rCol = mpImpl->mrDoc.maTabs[rPos.Tab()]->aCol[rPos.Col()];
- sc::ColumnBlockPosition* p = mpImpl->maBlockPosSet.getBlockPosition(rPos.Tab(), rPos.Col());
- if (p)
- rCol.SetCell(*p, rPos.Row(), pCell);
+ SCSIZE nIndex;
+ if (rCol.Search(nRow, nIndex))
+ {
+ ScBaseCell* pOldCell = rItems[nIndex].pCell;
+ pOldCell->Delete();
+ rItems[nIndex].pCell = pCell;
+ }
else
- rCol.SetCell(rPos.Row(), pCell);
+ {
+ rItems.insert(rItems.begin() + nIndex, ColEntry());
+ rItems[nIndex].pCell = pCell;
+ rItems[nIndex].nRow = nRow;
+ }
+}
+
+void ScDocumentImport::initColumn(ScColumn& rCol)
+{
+ CellTextAttrInitializer aFunc(mpImpl->mnDefaultScriptNumeric);
+ std::for_each(rCol.maItems.begin(), rCol.maItems.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 0fef98fac854..73d5f7e53977 100644
--- a/sc/source/filter/xml/xmlcelli.cxx
+++ b/sc/source/filter/xml/xmlcelli.cxx
@@ -50,6 +50,8 @@
#include "editattributemap.hxx"
#include "stringutil.hxx"
#include "tokenarray.hxx"
+#include "scmatrix.hxx"
+#include "documentimport.hxx"
#include <xmloff/xmltkmap.hxx>
#include <xmloff/xmltoken.hxx>
@@ -1049,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)
@@ -1060,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
{
@@ -1082,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
@@ -1122,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);
}
@@ -1323,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;
@@ -1330,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 )
@@ -1341,17 +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);
- pDoc->SetFormulaCell(rCellPos, pNewCell);
+ 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
{
@@ -1359,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 87a781a5e2dc..fd40dc7b9852 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>
@@ -2071,7 +2072,6 @@ ScXMLImport::ScXMLImport(
bRemoveLastChar(false),
bNullDateSetted(false),
bSelfImportingXMLSet(false),
- bLatinDefaultStyle(false),
bFromWrapper(false),
mbHasNewCondFormatData(false)
{
@@ -2312,6 +2312,11 @@ void ScXMLImport::SetStatistics(
}
}
+ScDocumentImport& ScXMLImport::GetDoc()
+{
+ return *mpDocImport;
+}
+
sal_Int16 ScXMLImport::GetCellType(const OUString& rStrValue) const
{
CellTypeMap::const_iterator itr = aCellTypeMap.find(rStrValue);
@@ -2418,7 +2423,7 @@ void ScXMLImport::ExamineDefaultStyle()
sal_uInt8 nScript = pDoc->GetStringScriptType( aDecSep );
if ( nScript == 0 || nScript == SCRIPTTYPE_LATIN )
- bLatinDefaultStyle = true;
+ mpDocImport->setDefaultNumericScript(SCRIPTTYPE_LATIN);
}
}
}
@@ -2926,6 +2931,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);
@@ -3196,6 +3202,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 938661431c19..0957a9f2973a 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
{
@@ -800,6 +801,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;
@@ -933,7 +935,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;
@@ -974,6 +975,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; }
@@ -982,8 +985,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