diff options
Diffstat (limited to 'sc')
-rw-r--r-- | sc/inc/documentimport.hxx | 2 | ||||
-rw-r--r-- | sc/source/core/data/documentimport.cxx | 35 | ||||
-rw-r--r-- | sc/source/filter/inc/orcusinterface.hxx | 4 | ||||
-rw-r--r-- | sc/source/filter/orcus/interface.cxx | 19 | ||||
-rw-r--r-- | sc/source/ui/xmlsource/xmlsourcedlg.cxx | 43 |
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)); |