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 2ec403de8f74699130cc80e1eda7862cb123cbfd Author: Miklos Vajna <vmik...@collabora.com> AuthorDate: Tue Feb 13 08:11:54 2024 +0100 Commit: Xisco Fauli <xiscofa...@libreoffice.org> CommitDate: Tue Feb 13 16:53:24 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. Change-Id: Id749df9062d8fcb9a2f0acd928585a304efaae28 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/163291 Reviewed-by: Miklos Vajna <vmik...@collabora.com> Tested-by: Jenkins (cherry picked from commit c0da56cb3e9f9678cae7142dee03fb706a2aebd9) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/163289 Reviewed-by: Xisco Fauli <xiscofa...@libreoffice.org> 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 917a690c7090..c9d53d93bed7 100644 --- a/sc/source/filter/html/htmlpars.cxx +++ b/sc/source/filter/html/htmlpars.cxx @@ -989,6 +989,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 ) @@ -1069,26 +1097,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; @@ -1098,6 +1112,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 ) @@ -1628,6 +1648,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* );