Kaydet (Commit) 252a3060 authored tarafından Kohei Yoshida's avatar Kohei Yoshida

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
üst 430d81e1
......@@ -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;
......
......@@ -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
......
......@@ -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: */
......@@ -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: */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment