sc/qa/filter/html/data/single-cell.html | 1 sc/qa/filter/html/html.cxx | 24 +++++++++++++ sc/source/filter/html/htmlpars.cxx | 57 +++++++++++++++++++++++--------- sc/source/filter/inc/htmlpars.hxx | 4 ++ 4 files changed, 70 insertions(+), 16 deletions(-)
New commits: commit 4b795e4ee74c20e8f13af977eae6f81e37bfbf30 Author: Miklos Vajna <[email protected]> AuthorDate: Tue Feb 13 08:11:54 2024 +0100 Commit: Miklos Vajna <[email protected]> CommitDate: Tue Feb 13 14:12:09 2024 +0100 tdf#159483 sc HTML paste: handle data-sheets- attributes on a span Copy multiple cells, including a formula from google sheets to Calc, the formula is handled as a formula by the HTML paste. Do the same for a single cell, then only the result is pasted. The trouble is that the data-sheets-* attributes appear on <td> elements for multiple cells, but they appear on a <span> for a single cell. Fix the problem by extending ScHTMLLayoutParser::ProcToken() to handle the HtmlTokenId::SPAN_ON token and share the code between the <td> and <span> handler, so this markup works in both cases. Note that this is the paste handler, the no changes to the normal HTML import are made for now. (cherry picked from commit c0da56cb3e9f9678cae7142dee03fb706a2aebd9) Change-Id: Id749df9062d8fcb9a2f0acd928585a304efaae28 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/163296 Tested-by: Miklos Vajna <[email protected]> Reviewed-by: Miklos Vajna <[email protected]> diff --git a/sc/qa/filter/html/data/single-cell.html b/sc/qa/filter/html/data/single-cell.html new file mode 100644 index 000000000000..0b5613f7e2be --- /dev/null +++ b/sc/qa/filter/html/data/single-cell.html @@ -0,0 +1 @@ +<span style="font-size:10pt;font-family:Arial;font-style:normal;text-align:right;" data-sheets-root="1" data-sheets-value="{"1":3,"3":3}" data-sheets-formula="=SUM(R[0]C[-2]:R[0]C[-1])">3</span> diff --git a/sc/qa/filter/html/html.cxx b/sc/qa/filter/html/html.cxx index 83e35d9f8281..c6112e357d80 100644 --- a/sc/qa/filter/html/html.cxx +++ b/sc/qa/filter/html/html.cxx @@ -168,6 +168,30 @@ CPPUNIT_TEST_FIXTURE(Test, testPasteTdAsFormula) pDoc->GetFormula(/*col=*/2, /*row=*/0, /*tab=*/0)); CPPUNIT_ASSERT_EQUAL(static_cast<double>(3), pDoc->GetValue(/*col=*/2, /*row=*/0, /*tab=*/0)); } + +CPPUNIT_TEST_FIXTURE(Test, testPasteSingleCell) +{ + // Given a document with '1' in A1 and '2' in B1: + createScDoc(); + ScDocument* pDoc = getScDoc(); + pDoc->SetValue(ScAddress(0, 0, 0), 1.0); + pDoc->SetValue(ScAddress(1, 0, 0), 2.0); + + // When pasting SUM(A1:B1) into C1: + ScAddress aCellPos(/*nColP=*/2, /*nRowP=*/0, /*nTabP=*/0); + ScImportExport aImporter(*pDoc, aCellPos); + SvFileStream aFile(createFileURL(u"single-cell.html"), StreamMode::READ); + CPPUNIT_ASSERT(aImporter.ImportStream(aFile, OUString(), SotClipboardFormatId::HTML)); + + // Then make sure C1 is a sum and it evaluates to 3: + // Without the accompanying fix in place, this test would have failed with: + // - Expected: =SUM(A1:B1) + // - Actual : + // i.e. data-sheets-* on <td> worked, but not on <span>. + CPPUNIT_ASSERT_EQUAL(OUString("=SUM(A1:B1)"), + pDoc->GetFormula(/*col=*/2, /*row=*/0, /*tab=*/0)); + CPPUNIT_ASSERT_EQUAL(static_cast<double>(3), pDoc->GetValue(/*col=*/2, /*row=*/0, /*tab=*/0)); +} } CPPUNIT_PLUGIN_IMPLEMENT(); diff --git a/sc/source/filter/html/htmlpars.cxx b/sc/source/filter/html/htmlpars.cxx index 5db879db75dd..830dac6f6615 100644 --- a/sc/source/filter/html/htmlpars.cxx +++ b/sc/source/filter/html/htmlpars.cxx @@ -992,6 +992,34 @@ IMPL_LINK( ScHTMLLayoutParser, HTMLImportHdl, HtmlImportInfo&, rInfo, void ) } } +void ScHTMLLayoutParser::HandleDataSheetsAttributes(const HTMLOptions& rOptions) +{ + for (const auto& rOption : rOptions) + { + switch (rOption.GetToken()) + { + case HtmlOptionId::DSVAL: + { + ParseDataSheetsValue(rOption.GetString(), mxActEntry->pValStr, mxActEntry->pNumStr); + break; + } + case HtmlOptionId::DSNUM: + { + ParseDataSheetsNumberformat(rOption.GetString(), mxActEntry->pNumStr); + break; + } + case HtmlOptionId::DSFORMULA: + { + ParseDataSheetsFormula(rOption.GetString(), mxActEntry->moFormulaStr, + mxActEntry->moFormulaGrammar); + break; + } + default: + break; + } + } +} + void ScHTMLLayoutParser::TableDataOn( HtmlImportInfo* pInfo ) { if ( bInCell ) @@ -1072,26 +1100,12 @@ void ScHTMLLayoutParser::TableDataOn( HtmlImportInfo* pInfo ) mxActEntry->pNumStr = rOption.GetString(); } break; - case HtmlOptionId::DSVAL: - { - ParseDataSheetsValue(rOption.GetString(), mxActEntry->pValStr, mxActEntry->pNumStr); - } - break; - case HtmlOptionId::DSNUM: - { - ParseDataSheetsNumberformat(rOption.GetString(), mxActEntry->pNumStr); - } - break; - case HtmlOptionId::DSFORMULA: - { - ParseDataSheetsFormula(rOption.GetString(), mxActEntry->moFormulaStr, - mxActEntry->moFormulaGrammar); - } - break; default: break; } } + HandleDataSheetsAttributes(rOptions); + mxActEntry->nCol = nColCnt; mxActEntry->nRow = nRowCnt; mxActEntry->nTab = nTable; @@ -1101,6 +1115,12 @@ void ScHTMLLayoutParser::TableDataOn( HtmlImportInfo* pInfo ) SvxHorJustifyItem( SvxCellHorJustify::Center, ATTR_HOR_JUSTIFY) ); } +void ScHTMLLayoutParser::SpanOn(HtmlImportInfo* pInfo) +{ + const HTMLOptions& rOptions = static_cast<HTMLParser*>(pInfo->pParser)->GetOptions(); + HandleDataSheetsAttributes(rOptions); +} + void ScHTMLLayoutParser::TableRowOn( const HtmlImportInfo* pInfo ) { if ( nColCnt > nColCntStart ) @@ -1638,6 +1658,11 @@ void ScHTMLLayoutParser::ProcToken( HtmlImportInfo* pInfo ) TableDataOn( pInfo ); } break; + case HtmlTokenId::SPAN_ON: + { + SpanOn(pInfo); + } + break; case HtmlTokenId::TABLEHEADER_OFF: case HtmlTokenId::TABLEDATA_OFF: // Closes cell { diff --git a/sc/source/filter/inc/htmlpars.hxx b/sc/source/filter/inc/htmlpars.hxx index 5b2d441098f3..1ac9aa000225 100644 --- a/sc/source/filter/inc/htmlpars.hxx +++ b/sc/source/filter/inc/htmlpars.hxx @@ -28,6 +28,7 @@ #include <utility> #include <vector> #include <o3tl/sorted_vector.hxx> +#include <svtools/parhtml.hxx> #include <rangelst.hxx> #include "eeparser.hxx" @@ -212,6 +213,9 @@ private: void Image( HtmlImportInfo* ); void AnchorOn( HtmlImportInfo* ); void FontOn( HtmlImportInfo* ); + void SpanOn(HtmlImportInfo* pInfo); + /// Handles the various data-sheets-* attributes on <td> and <span>. + void HandleDataSheetsAttributes(const HTMLOptions& rOptions); public: ScHTMLLayoutParser( EditEngine*, OUString aBaseURL, const Size& aPageSize, ScDocument* );
