summaryrefslogtreecommitdiff
path: root/sc
diff options
context:
space:
mode:
Diffstat (limited to 'sc')
-rw-r--r--sc/inc/documentimport.hxx2
-rw-r--r--sc/source/core/data/documentimport.cxx35
-rw-r--r--sc/source/filter/inc/orcusinterface.hxx4
-rw-r--r--sc/source/filter/orcus/interface.cxx19
-rw-r--r--sc/source/ui/xmlsource/xmlsourcedlg.cxx43
5 files changed, 72 insertions, 31 deletions
diff --git a/sc/inc/documentimport.hxx b/sc/inc/documentimport.hxx
index 7680f7880dae..758469f258a6 100644
--- a/sc/inc/documentimport.hxx
+++ b/sc/inc/documentimport.hxx
@@ -112,6 +112,8 @@ public:
void setTableOpCells(const ScRange& rRange, const ScTabOpParam& rParam);
+ void fillDownCells(const ScAddress& rPos, SCROW nFillSize);
+
/**
* Set an array of cell attributes to specified column. This call
* transfers the ownership of the ScAttrEntry array from the caller to the
diff --git a/sc/source/core/data/documentimport.cxx b/sc/source/core/data/documentimport.cxx
index ebe1b8a6dfc8..d4c3227a8b72 100644
--- a/sc/source/core/data/documentimport.cxx
+++ b/sc/source/core/data/documentimport.cxx
@@ -537,6 +537,41 @@ void ScDocumentImport::setTableOpCells(const ScRange& rRange, const ScTabOpParam
}
}
+void ScDocumentImport::fillDownCells(const ScAddress& rPos, SCROW nFillSize)
+{
+ ScTable* pTab = mpImpl->mrDoc.FetchTable(rPos.Tab());
+ if (!pTab)
+ return;
+
+ sc::ColumnBlockPosition* pBlockPos = mpImpl->getBlockPosition(rPos.Tab(), rPos.Col());
+
+ if (!pBlockPos)
+ return;
+
+ sc::CellStoreType& rCells = pTab->aCol[rPos.Col()].maCells;
+ ScRefCellValue aRefCell = pTab->aCol[rPos.Col()].GetCellValue(*pBlockPos, rPos.Row());
+
+ switch (aRefCell.meType)
+ {
+ case CELLTYPE_VALUE:
+ {
+ std::vector<double> aCopied(nFillSize, aRefCell.mfValue);
+ pBlockPos->miCellPos = rCells.set(
+ pBlockPos->miCellPos, rPos.Row()+1, aCopied.begin(), aCopied.end());
+ break;
+ }
+ case CELLTYPE_STRING:
+ {
+ std::vector<svl::SharedString> aCopied(nFillSize, *aRefCell.mpString);
+ pBlockPos->miCellPos = rCells.set(
+ pBlockPos->miCellPos, rPos.Row()+1, aCopied.begin(), aCopied.end());
+ break;
+ }
+ default:
+ break;
+ }
+}
+
void ScDocumentImport::setAttrEntries( SCTAB nTab, SCCOL nCol, Attrs&& rAttrs )
{
ScTable* pTab = mpImpl->mrDoc.FetchTable(nTab);
diff --git a/sc/source/filter/inc/orcusinterface.hxx b/sc/source/filter/inc/orcusinterface.hxx
index 7c7c4f20bb3c..ecf8f21168ec 100644
--- a/sc/source/filter/inc/orcusinterface.hxx
+++ b/sc/source/filter/inc/orcusinterface.hxx
@@ -587,7 +587,8 @@ class ScOrcusFactory : public orcus::spreadsheet::iface::import_factory
FormulaWithResult,
SharedFormula,
SharedFormulaWithResult,
- Matrix
+ Matrix,
+ FillDownCells
};
ScAddress const maPos;
@@ -650,6 +651,7 @@ public:
void pushCellStoreToken( const ScAddress& rPos, double fValue );
void pushCellStoreToken(
const ScAddress& rPos, const OUString& rFormula, formula::FormulaGrammar::Grammar eGrammar );
+ void pushFillDownCellsToken( const ScAddress& rPos, uint32_t nFillSize );
void pushSharedFormulaToken( const ScAddress& rPos, uint32_t nIndex );
void pushMatrixFormulaToken(
diff --git a/sc/source/filter/orcus/interface.cxx b/sc/source/filter/orcus/interface.cxx
index 23f17a1dc854..fbd384be5a76 100644
--- a/sc/source/filter/orcus/interface.cxx
+++ b/sc/source/filter/orcus/interface.cxx
@@ -470,6 +470,14 @@ void ScOrcusFactory::finalize()
maDoc.setMatrixCells(aRange, *pArray, rToken.meGrammar);
break;
}
+ case CellStoreToken::Type::FillDownCells:
+ {
+ if (!rToken.mnIndex1)
+ break;
+
+ maDoc.fillDownCells(rToken.maPos, rToken.mnIndex1);
+ break;
+ }
default:
;
}
@@ -538,6 +546,12 @@ void ScOrcusFactory::pushCellStoreToken(
maCellStoreTokens.emplace_back(rPos, rFormula, eGrammar);
}
+void ScOrcusFactory::pushFillDownCellsToken( const ScAddress& rPos, uint32_t nFillSize )
+{
+ maCellStoreTokens.emplace_back(rPos, CellStoreToken::Type::FillDownCells);
+ maCellStoreTokens.back().mnIndex1 = nFillSize;
+}
+
void ScOrcusFactory::pushSharedFormulaToken( const ScAddress& rPos, uint32_t nIndex )
{
maCellStoreTokens.emplace_back(rPos, CellStoreToken::Type::SharedFormula);
@@ -1187,9 +1201,10 @@ orcus::spreadsheet::range_size_t ScOrcusSheet::get_sheet_size() const
return ret;
}
-void ScOrcusSheet::fill_down_cells(os::row_t /*row*/, os::col_t /*col*/, os::row_t /*range_size*/)
+void ScOrcusSheet::fill_down_cells(os::row_t row, os::col_t col, os::row_t range_size)
{
- // TODO : implement this.
+ mrFactory.pushFillDownCellsToken(ScAddress(col, row, mnTab), range_size);
+ cellInserted();
}
const sc::SharedFormulaGroups& ScOrcusSheet::getSharedFormulaGroups() const
diff --git a/sc/source/ui/xmlsource/xmlsourcedlg.cxx b/sc/source/ui/xmlsource/xmlsourcedlg.cxx
index dd78ab5e18b9..0cd202c8dec6 100644
--- a/sc/source/ui/xmlsource/xmlsourcedlg.cxx
+++ b/sc/source/ui/xmlsource/xmlsourcedlg.cxx
@@ -205,10 +205,10 @@ void ScXMLSourceDlg::LoadSourceFileStructure(const OUString& rPath)
namespace {
/**
- * When the current entry is a direct or indirect child of a mappable
- * repeat element entry, that entry becomes the reference entry.
- * Otherwise the reference entry equals the current entry. A reference
- * entry is the entry that stores mapped cell position.
+ * The current entry is the reference entry for a cell link. For a range
+ * link, the reference entry is the shallowest repeat element entry up from
+ * the current entry position. The mapped cell position for a range link is
+ * stored with the reference entry.
*/
std::unique_ptr<weld::TreeIter> getReferenceEntry(const weld::TreeView& rTree, weld::TreeIter& rCurEntry)
{
@@ -221,14 +221,7 @@ std::unique_ptr<weld::TreeIter> getReferenceEntry(const weld::TreeView& rTree, w
OSL_ASSERT(pUserData);
if (pUserData->meType == ScOrcusXMLTreeParam::ElementRepeat)
{
- // This is a repeat element.
- if (xRefEntry)
- {
- // Second repeat element encountered. Not good.
- std::unique_ptr<weld::TreeIter> xCurEntry(rTree.make_iterator(&rCurEntry));
- return xCurEntry;
- }
-
+ // This is a repeat element - a potential reference entry.
xRefEntry = rTree.make_iterator(xParent.get());
}
bParent = rTree.iter_parent(*xParent);
@@ -332,9 +325,7 @@ void ScXMLSourceDlg::RepeatElementSelected(weld::TreeIter& rEntry)
}
// Check all its child elements / attributes and make sure non of them are
- // linked or repeat elements. In the future we will support range linking
- // of repeat element who has another repeat elements. But first I need to
- // support that scenario in orcus.
+ // linked.
if (IsChildrenDirty(&rEntry))
{
@@ -420,11 +411,6 @@ bool ScXMLSourceDlg::IsParentDirty(weld::TreeIter* pEntry) const
// This parent is already linked.
return true;
}
- if (pUserData->meType == ScOrcusXMLTreeParam::ElementRepeat)
- {
- // This is a repeat element.
- return true;
- }
}
while (mxLbTree->iter_parent(*xParent));
return false;
@@ -444,10 +430,6 @@ bool ScXMLSourceDlg::IsChildrenDirty(weld::TreeIter* pEntry) const
// Already linked.
return true;
- if (pUserData->meType == ScOrcusXMLTreeParam::ElementRepeat)
- // We don't support linking of nested repeat elements (yet).
- return true;
-
if (pUserData->meType == ScOrcusXMLTreeParam::ElementDefault)
{
// Check recursively.
@@ -478,9 +460,14 @@ void getFieldLinks(
OUString aPath = getXPath(rTree, *xChild, rNamespaces);
const ScOrcusXMLTreeParam::EntryData* pUserData = ScOrcusXMLTreeParam::getUserData(rTree, *xChild);
- if (pUserData && pUserData->mbLeafNode)
+ if (pUserData)
{
- if (!aPath.isEmpty())
+ if (pUserData->meType == ScOrcusXMLTreeParam::ElementRepeat)
+ // nested repeat element automatically becomes a row-group node.
+ rRangeLink.maRowGroups.push_back(
+ OUStringToOString(aPath, RTL_TEXTENCODING_UTF8));
+
+ if (pUserData->mbLeafNode && !aPath.isEmpty())
// XPath should never be empty anyway, but it won't hurt to check...
rRangeLink.maFieldPaths.push_back(OUStringToOString(aPath, RTL_TEXTENCODING_UTF8));
}
@@ -533,8 +520,8 @@ void ScXMLSourceDlg::OkPressed()
// Go through all its child elements.
getFieldLinks(aRangeLink, aParam.maNamespaces, *mxLbTree, *rEntry);
- // Add the anchor node as a grouping node, which will be used as a
- // row position increment point.
+ // Add the reference entry as a row-group node, which will be used
+ // as a row position increment point.
OUString aThisEntry = getXPath(*mxLbTree, *rEntry, aParam.maNamespaces);
aRangeLink.maRowGroups.push_back(
OUStringToOString(aThisEntry, RTL_TEXTENCODING_UTF8));