summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@collabora.com>2024-02-13 08:11:54 +0100
committerMiklos Vajna <vmiklos@collabora.com>2024-02-13 11:48:25 +0100
commitc0da56cb3e9f9678cae7142dee03fb706a2aebd9 (patch)
treef917a3df41032b601fa1b701fb9ff38f12a1ce17
parent0cb78e2f6f76d5bb32487c6cf76a78bafedbbd45 (diff)
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 <vmiklos@collabora.com> Tested-by: Jenkins
-rw-r--r--sc/qa/filter/html/data/single-cell.html1
-rw-r--r--sc/qa/filter/html/html.cxx24
-rw-r--r--sc/source/filter/html/htmlpars.cxx57
-rw-r--r--sc/source/filter/inc/htmlpars.hxx4
4 files changed, 70 insertions, 16 deletions
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="{&quot;1&quot;:3,&quot;3&quot;: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* );