diff options
-rw-r--r-- | sc/inc/documentimport.hxx | 9 | ||||
-rw-r--r-- | sc/inc/mtvelements.hxx | 19 | ||||
-rw-r--r-- | sc/source/core/data/documentimport.cxx | 55 | ||||
-rw-r--r-- | sc/source/core/data/mtvelements.cxx | 40 |
4 files changed, 101 insertions, 22 deletions
diff --git a/sc/inc/documentimport.hxx b/sc/inc/documentimport.hxx index eeafbba44c47..afd954bf93d5 100644 --- a/sc/inc/documentimport.hxx +++ b/sc/inc/documentimport.hxx @@ -15,10 +15,13 @@ #include "rtl/ustring.hxx" +#include <boost/noncopyable.hpp> + class ScDocument; class ScAddress; class ScTokenArray; class ScBaseCell; +struct ScDocumentImportImpl; /** * Accessor class to ScDocument. Its purpose is to allow import filter to @@ -27,15 +30,15 @@ class ScBaseCell; * position calculation, or anything else that requires expensive * computation which are unnecessary and undesirable during import. */ -class SC_DLLPUBLIC ScDocumentImport +class SC_DLLPUBLIC ScDocumentImport : boost::noncopyable { - ScDocument& mrDoc; + ScDocumentImportImpl* mpImpl; ScDocumentImport(); // disabled public: ScDocumentImport(ScDocument& rDoc); - ScDocumentImport(const ScDocumentImport& r); + ~ScDocumentImport(); ScDocument& getDoc(); const ScDocument& getDoc() const; diff --git a/sc/inc/mtvelements.hxx b/sc/inc/mtvelements.hxx index b21f7c7cc6ca..162838115da9 100644 --- a/sc/inc/mtvelements.hxx +++ b/sc/inc/mtvelements.hxx @@ -10,6 +10,7 @@ #ifndef SC_MTVELEMENTS_HXX #define SC_MTVELEMENTS_HXX +#include "address.hxx" #include "svl/broadcast.hxx" #define DEBUG_COLUMN_STORAGE 0 @@ -25,6 +26,10 @@ #include <mdds/multi_type_vector.hpp> #include <mdds/multi_type_vector_custom_func1.hpp> +#include <boost/unordered_map.hpp> + +class ScDocument; + namespace sc { struct CellTextAttr @@ -74,6 +79,20 @@ struct ColumnBlockPosition CellTextAttrStoreType::iterator miCellTextAttrPos; }; +class ColumnBlockPositionSet +{ + typedef boost::unordered_map<SCCOL, ColumnBlockPosition> ColumnsType; + typedef boost::unordered_map<SCTAB, ColumnsType> TablesType; + + ScDocument& mrDoc; + TablesType maTables; + +public: + ColumnBlockPositionSet(ScDocument& rDoc); + + ColumnBlockPosition* getBlockPosition(SCTAB nTab, SCCOL nCol); +}; + } #endif diff --git a/sc/source/core/data/documentimport.cxx b/sc/source/core/data/documentimport.cxx index c92688f1ada2..ced09363ccc4 100644 --- a/sc/source/core/data/documentimport.cxx +++ b/sc/source/core/data/documentimport.cxx @@ -15,24 +15,36 @@ #include "formulacell.hxx" #include "docoptio.hxx" #include "globalnames.hxx" +#include "mtvelements.hxx" -ScDocumentImport::ScDocumentImport(ScDocument& rDoc) : mrDoc(rDoc) {} -ScDocumentImport::ScDocumentImport(const ScDocumentImport& r) : mrDoc(r.mrDoc) {} +struct ScDocumentImportImpl +{ + ScDocument& mrDoc; + sc::ColumnBlockPositionSet maBlockPosSet; + + ScDocumentImportImpl(ScDocument& rDoc) : mrDoc(rDoc), maBlockPosSet(rDoc) {} +}; + +ScDocumentImport::ScDocumentImport(ScDocument& rDoc) : mpImpl(new ScDocumentImportImpl(rDoc)) {} +ScDocumentImport::~ScDocumentImport() +{ + delete mpImpl; +} ScDocument& ScDocumentImport::getDoc() { - return mrDoc; + return mpImpl->mrDoc; } const ScDocument& ScDocumentImport::getDoc() const { - return mrDoc; + return mpImpl->mrDoc; } SCTAB ScDocumentImport::getSheetIndex(const OUString& rName) const { SCTAB nTab = -1; - if (!mrDoc.GetTable(rName, nTab)) + if (!mpImpl->mrDoc.GetTable(rName, nTab)) return -1; return nTab; @@ -40,33 +52,34 @@ SCTAB ScDocumentImport::getSheetIndex(const OUString& rName) const SCTAB ScDocumentImport::getSheetCount() const { - return mrDoc.maTabs.size(); + return mpImpl->mrDoc.maTabs.size(); } bool ScDocumentImport::appendSheet(const OUString& rName) { - SCTAB nTabCount = mrDoc.maTabs.size(); + SCTAB nTabCount = mpImpl->mrDoc.maTabs.size(); if (!ValidTab(nTabCount)) return false; - mrDoc.maTabs.push_back(new ScTable(&mrDoc, nTabCount, rName)); + mpImpl->mrDoc.maTabs.push_back(new ScTable(&mpImpl->mrDoc, nTabCount, rName)); return true; } void ScDocumentImport::setOriginDate(sal_uInt16 nYear, sal_uInt16 nMonth, sal_uInt16 nDay) { - if (!mrDoc.pDocOptions) - mrDoc.pDocOptions = new ScDocOptions; + if (!mpImpl->mrDoc.pDocOptions) + mpImpl->mrDoc.pDocOptions = new ScDocOptions; - mrDoc.pDocOptions->SetDate(nDay, nMonth, nYear); + mpImpl->mrDoc.pDocOptions->SetDate(nDay, nMonth, nYear); } void ScDocumentImport::setAutoInput(const ScAddress& rPos, const OUString& rStr) { - if (!mrDoc.TableExists(rPos.Tab())) + if (!mpImpl->mrDoc.TableExists(rPos.Tab())) return; - mrDoc.maTabs[rPos.Tab()]->aCol[rPos.Col()].SetString(rPos.Row(), rPos.Tab(), rStr, mrDoc.GetAddressConvention()); + mpImpl->mrDoc.maTabs[rPos.Tab()]->aCol[rPos.Col()].SetString( + rPos.Row(), rPos.Tab(), rStr, mpImpl->mrDoc.GetAddressConvention()); } void ScDocumentImport::setNumericCell(const ScAddress& rPos, double fVal) @@ -82,18 +95,18 @@ void ScDocumentImport::setStringCell(const ScAddress& rPos, const OUString& rStr void ScDocumentImport::setFormulaCell( const ScAddress& rPos, const OUString& rFormula, formula::FormulaGrammar::Grammar eGrammar) { - insertCell(rPos, new ScFormulaCell(&mrDoc, rPos, rFormula, eGrammar)); + insertCell(rPos, new ScFormulaCell(&mpImpl->mrDoc, rPos, rFormula, eGrammar)); } void ScDocumentImport::setFormulaCell(const ScAddress& rPos, const ScTokenArray& rArray) { - insertCell(rPos, new ScFormulaCell(&mrDoc, rPos, &rArray)); + insertCell(rPos, new ScFormulaCell(&mpImpl->mrDoc, rPos, &rArray)); } void ScDocumentImport::finalize() { // Populate the text width and script type arrays in all columns. - ScDocument::TableContainer::iterator itTab = mrDoc.maTabs.begin(), itTabEnd = mrDoc.maTabs.end(); + ScDocument::TableContainer::iterator itTab = mpImpl->mrDoc.maTabs.begin(), itTabEnd = mpImpl->mrDoc.maTabs.end(); for (; itTab != itTabEnd; ++itTab) { if (!*itTab) @@ -119,14 +132,18 @@ void ScDocumentImport::finalize() void ScDocumentImport::insertCell(const ScAddress& rPos, ScBaseCell* pCell) { - if (!mrDoc.TableExists(rPos.Tab())) + if (!mpImpl->mrDoc.TableExists(rPos.Tab())) { pCell->Delete(); return; } - ScColumn& rCol = mrDoc.maTabs[rPos.Tab()]->aCol[rPos.Col()]; - rCol.SetCell(rPos.Row(), pCell); + 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); + else + rCol.SetCell(rPos.Row(), pCell); } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/source/core/data/mtvelements.cxx b/sc/source/core/data/mtvelements.cxx index 45c06dd4506b..efe07cff5ad7 100644 --- a/sc/source/core/data/mtvelements.cxx +++ b/sc/source/core/data/mtvelements.cxx @@ -9,6 +9,7 @@ #include "mtvelements.hxx" #include "globalnames.hxx" +#include "document.hxx" namespace sc { @@ -24,6 +25,45 @@ CellTextAttr::CellTextAttr(sal_uInt16 nTextWidth, sal_uInt8 nScriptType) : mnTextWidth(nTextWidth), mnScriptType(nScriptType) {} +ColumnBlockPositionSet::ColumnBlockPositionSet(ScDocument& rDoc) : mrDoc(rDoc) {} + +ColumnBlockPosition* ColumnBlockPositionSet::getBlockPosition(SCTAB nTab, SCCOL nCol) +{ + TablesType::iterator itTab = maTables.find(nTab); + if (itTab == maTables.end()) + { + std::pair<TablesType::iterator,bool> r = + maTables.insert(TablesType::value_type(nTab, ColumnsType())); + if (!r.second) + // insertion failed. + return NULL; + + itTab = r.first; + } + + ColumnsType& rCols = itTab->second; + + ColumnsType::iterator it = rCols.find(nCol); + if (it != rCols.end()) + // Block position for this column has already been fetched. + return &it->second; + + std::pair<ColumnsType::iterator,bool> r = + rCols.insert( + ColumnsType::value_type(nCol, ColumnBlockPosition())); + + if (!r.second) + // insertion failed. + return NULL; + + it = r.first; + + if (!mrDoc.InitColumnBlockPosition(it->second, nTab, nCol)) + return NULL; + + return &it->second; +} + } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |