summaryrefslogtreecommitdiff
path: root/sc
diff options
context:
space:
mode:
authorKohei Yoshida <kohei.yoshida@gmail.com>2013-05-17 16:39:15 -0400
committerKohei Yoshida <kohei.yoshida@gmail.com>2013-05-20 20:18:46 -0400
commit252a30609357a5b2691b7796cc8f3f4f1319f655 (patch)
tree0f8c23f89a8d9e3f98951dd3c6718b57fa77cd82 /sc
parent430d81e1fd44f51a91b81da91504a004ab7373d8 (diff)
Keep track of column block positions in ScDocumentImport too.
This currently only affects document import via orcus, but it'll be good to put this in place. Change-Id: I8cc6d54aba6fab1f2774127f92c2a764f7b690fb
Diffstat (limited to 'sc')
-rw-r--r--sc/inc/documentimport.hxx9
-rw-r--r--sc/inc/mtvelements.hxx19
-rw-r--r--sc/source/core/data/documentimport.cxx55
-rw-r--r--sc/source/core/data/mtvelements.cxx40
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: */