summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Hung <marklh9@gmail.com>2021-01-28 22:53:49 +0800
committerMichael Stahl <michael.stahl@allotropia.de>2021-02-10 10:54:46 +0100
commit297f511263db7434bb10cdc91230b4d3f8ac9aa0 (patch)
tree14289bfc9b011e49b9eae5a7b046104634a4df4b
parentd803e27ab9fd779720bcf970834d74b41ab90f65 (diff)
tdf#129940 handle text:ruby element inside text:p
Implement ScXMLCellTextRubyContext for text:ruby. It creates two types of child elements: ScXMLCellRubyBaseContext for text:ruby-base, and ScXMLCellRubyTextContext, for text:ruby-text. Ruby text isn't used now, but can serve for future application. Change-Id: I33b778838032458ffbefc6a2835d2ae59dff30cf Reviewed-on: https://gerrit.libreoffice.org/c/core/+/110088 Tested-by: Jenkins Reviewed-by: Mark Hung <marklh9@gmail.com> (cherry picked from commit e630da1ed8a27c64bc9f22ecb71afd10bf252d93) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/110567 Reviewed-by: Michael Stahl <michael.stahl@allotropia.de>
-rw-r--r--sc/qa/unit/data/ods/tdf129940.odsbin0 -> 3773 bytes
-rw-r--r--sc/qa/unit/subsequent_filters-test.cxx21
-rw-r--r--sc/source/filter/xml/celltextparacontext.cxx120
-rw-r--r--sc/source/filter/xml/celltextparacontext.hxx45
4 files changed, 177 insertions, 9 deletions
diff --git a/sc/qa/unit/data/ods/tdf129940.ods b/sc/qa/unit/data/ods/tdf129940.ods
new file mode 100644
index 000000000000..5cc5369acd49
--- /dev/null
+++ b/sc/qa/unit/data/ods/tdf129940.ods
Binary files differ
diff --git a/sc/qa/unit/subsequent_filters-test.cxx b/sc/qa/unit/subsequent_filters-test.cxx
index 3d5621da963d..47837905f407 100644
--- a/sc/qa/unit/subsequent_filters-test.cxx
+++ b/sc/qa/unit/subsequent_filters-test.cxx
@@ -297,6 +297,7 @@ public:
void testDeleteCircles();
void testDrawCircleInMergeCells();
void testDeleteCirclesInRowAndCol();
+ void testTdf129940();
CPPUNIT_TEST_SUITE(ScFiltersTest);
CPPUNIT_TEST(testCondFormatFormulaIsXLSX);
@@ -479,6 +480,7 @@ public:
CPPUNIT_TEST(testDeleteCircles);
CPPUNIT_TEST(testDrawCircleInMergeCells);
CPPUNIT_TEST(testDeleteCirclesInRowAndCol);
+ CPPUNIT_TEST(testTdf129940);
CPPUNIT_TEST_SUITE_END();
@@ -5367,6 +5369,25 @@ void ScFiltersTest::testDeleteCirclesInRowAndCol()
xDocSh->DoClose();
}
+void ScFiltersTest::testTdf129940()
+{
+ // Test pure span elements inside text:ruby-base
+ ScDocShellRef xDocSh = loadDoc(u"tdf129940.", FORMAT_ODS);
+ CPPUNIT_ASSERT_MESSAGE("Failed to load tdf129940.ods", xDocSh.is());
+ ScDocument& rDoc = xDocSh->GetDocument();
+ // Pure text within text:ruby-base
+ OUString aStr = rDoc.GetString(ScAddress(0,0,0));
+ CPPUNIT_ASSERT_EQUAL(OUString(u"小笠原"), aStr);
+ aStr = rDoc.GetString(ScAddress(1,0,0));
+ CPPUNIT_ASSERT_EQUAL(OUString(u"徳彦"), aStr);
+
+ // Multiple text:span within text:ruby-base
+ aStr = rDoc.GetString(ScAddress(2,0,0));
+ CPPUNIT_ASSERT_EQUAL(OUString(u"注音符號"), aStr);
+
+ xDocSh->DoClose();
+}
+
ScFiltersTest::ScFiltersTest()
: ScBootstrapFixture( "sc/qa/unit/data" )
{
diff --git a/sc/source/filter/xml/celltextparacontext.cxx b/sc/source/filter/xml/celltextparacontext.cxx
index 8a54d38c2b32..ce7f90651645 100644
--- a/sc/source/filter/xml/celltextparacontext.cxx
+++ b/sc/source/filter/xml/celltextparacontext.cxx
@@ -60,6 +60,8 @@ uno::Reference< xml::sax::XFastContextHandler > SAL_CALL ScXMLCellTextParaContex
return new ScXMLCellFieldTitleContext(GetScImport(), *this);
case XML_ELEMENT( TEXT, XML_A ):
return new ScXMLCellFieldURLContext(GetScImport(), *this);
+ case XML_ELEMENT( TEXT, XML_RUBY ):
+ return new ScXMLCellTextRubyContext(GetScImport(), *this);
default:
;
}
@@ -118,10 +120,7 @@ void SAL_CALL ScXMLCellTextSpanContext::startFastElement( sal_Int32 /*nElement*/
void SAL_CALL ScXMLCellTextSpanContext::endFastElement( sal_Int32 /*nElement*/ )
{
- if (!maContent.isEmpty())
- {
- mrParentCxt.PushSpan(maContent, maStyleName);
- }
+ submitContentAndClear();
}
void SAL_CALL ScXMLCellTextSpanContext::characters( const OUString& rChars )
@@ -132,11 +131,7 @@ void SAL_CALL ScXMLCellTextSpanContext::characters( const OUString& rChars )
uno::Reference< xml::sax::XFastContextHandler > SAL_CALL ScXMLCellTextSpanContext::createFastChildContext(
sal_Int32 nElement, const uno::Reference< xml::sax::XFastAttributeList >& /*xAttrList*/ )
{
- if (!maContent.isEmpty())
- {
- mrParentCxt.PushSpan(maContent, maStyleName);
- maContent.clear();
- }
+ submitContentAndClear();
switch (nElement)
{
@@ -177,6 +172,15 @@ uno::Reference< xml::sax::XFastContextHandler > SAL_CALL ScXMLCellTextSpanContex
return nullptr;
}
+void ScXMLCellTextSpanContext::submitContentAndClear()
+{
+ if (!maContent.isEmpty())
+ {
+ mrParentCxt.PushSpan(maContent, maStyleName);
+ maContent.clear();
+ }
+}
+
ScXMLCellFieldSheetNameContext::ScXMLCellFieldSheetNameContext(
ScXMLImport& rImport, ScXMLCellTextParaContext& rParent) :
ScXMLImportContext(rImport),
@@ -337,4 +341,102 @@ void ScXMLCellFieldSContext::PushSpaces()
}
}
+ScXMLCellTextRubyContext::ScXMLCellTextRubyContext(
+ ScXMLImport& rImport, ScXMLCellTextParaContext& rParent) :
+ ScXMLImportContext(rImport),
+ mrParentCxt(rParent)
+{
+}
+
+void SAL_CALL ScXMLCellTextRubyContext::startFastElement( sal_Int32 /*nElement*/,
+ const uno::Reference< xml::sax::XFastAttributeList >& xAttrList )
+{
+ for (auto &aIter : sax_fastparser::castToFastAttributeList( xAttrList ))
+ {
+ switch (aIter.getToken())
+ {
+ case XML_ELEMENT( TEXT, XML_STYLE_NAME ):
+ // This is ruby style instead of text style.
+ maRubyStyleName = aIter.toString();
+ break;
+ default:
+ ;
+ }
+ }
+}
+
+uno::Reference< xml::sax::XFastContextHandler > SAL_CALL ScXMLCellTextRubyContext::createFastChildContext(
+ sal_Int32 nElement, const uno::Reference< xml::sax::XFastAttributeList >& /*xAttrList*/ )
+{
+
+ switch (nElement)
+ {
+ case XML_ELEMENT( TEXT, XML_RUBY_BASE ):
+ {
+ ScXMLCellRubyBaseContext* p = new ScXMLCellRubyBaseContext(GetScImport(), mrParentCxt);
+ return p;
+ }
+ case XML_ELEMENT( TEXT, XML_RUBY_TEXT ):
+ {
+ ScXMLCellRubyTextContext* p = new ScXMLCellRubyTextContext(GetScImport(), maRubyText, maRubyTextStyle);
+ return p;
+ }
+ default:
+ ;
+ }
+
+ return nullptr;
+}
+
+ScXMLCellRubyBaseContext::ScXMLCellRubyBaseContext(
+ ScXMLImport& rImport, ScXMLCellTextParaContext& rParent) :
+ ScXMLCellTextSpanContext( rImport, rParent),
+ mrParentCxt(rParent)
+{
+}
+
+uno::Reference< xml::sax::XFastContextHandler > SAL_CALL ScXMLCellRubyBaseContext::createFastChildContext(
+ sal_Int32 nElement, const uno::Reference< xml::sax::XFastAttributeList >& /*xAttrList*/ )
+{
+ submitContentAndClear();
+
+ switch (nElement)
+ {
+ case XML_ELEMENT( TEXT, XML_SPAN ):
+ return new ScXMLCellTextSpanContext(GetScImport(), mrParentCxt);
+ default:
+ ;
+ }
+ return nullptr;
+}
+
+ScXMLCellRubyTextContext::ScXMLCellRubyTextContext(
+ ScXMLImport& rImport, OUString& rRubyText, OUString& rRubyTextStyle) :
+ ScXMLImportContext(rImport),
+ mrRubyText(rRubyText),
+ mrRubyTextStyle(rRubyTextStyle)
+{
+}
+
+void SAL_CALL ScXMLCellRubyTextContext::startFastElement( sal_Int32 /*nElement*/,
+ const uno::Reference< xml::sax::XFastAttributeList >& xAttrList )
+{
+ for (auto &aIter : sax_fastparser::castToFastAttributeList( xAttrList ))
+ {
+ switch (aIter.getToken())
+ {
+ case XML_ELEMENT( TEXT, XML_STYLE_NAME ):
+ mrRubyTextStyle = aIter.toString();
+ break;
+ default:
+ ;
+ }
+ }
+}
+
+void SAL_CALL ScXMLCellRubyTextContext::characters( const OUString& rChars )
+{
+ mrRubyText+= rChars;
+}
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/xml/celltextparacontext.hxx b/sc/source/filter/xml/celltextparacontext.hxx
index 35a553ce7f9c..3758bdba5bba 100644
--- a/sc/source/filter/xml/celltextparacontext.hxx
+++ b/sc/source/filter/xml/celltextparacontext.hxx
@@ -54,6 +54,7 @@ public:
virtual void SAL_CALL characters( const OUString& aChars ) override;
virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext(
sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList ) override;
+ void submitContentAndClear();
};
/**
@@ -144,6 +145,50 @@ public:
sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList ) override;
};
+/**
+ * This context handles <text:ruby> element inside <text:p>.
+ */
+class ScXMLCellTextRubyContext : public ScXMLImportContext
+{
+ ScXMLCellTextParaContext& mrParentCxt;
+ OUString maRubyStyleName;
+ OUString maRubyTextStyle;
+ OUString maRubyText;
+public:
+ ScXMLCellTextRubyContext(ScXMLImport& rImport, ScXMLCellTextParaContext& rParent);
+
+ virtual void SAL_CALL startFastElement( sal_Int32 nElement,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList ) override;
+ virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext(
+ sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList ) override;
+};
+
+/**
+ * This context handles <text:ruby-base> element inside <text:ruby>.
+ */
+class ScXMLCellRubyBaseContext : public ScXMLCellTextSpanContext
+{
+ ScXMLCellTextParaContext& mrParentCxt;
+public:
+ ScXMLCellRubyBaseContext(ScXMLImport& rImport, ScXMLCellTextParaContext& rParent);
+ virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext(
+ sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList ) override;
+};
+
+/**
+ * This context handles <text:ruby-text> element inside <text:ruby>.
+ */
+class ScXMLCellRubyTextContext : public ScXMLImportContext
+{
+ OUString& mrRubyText;
+ OUString& mrRubyTextStyle;
+public:
+ ScXMLCellRubyTextContext(ScXMLImport& rImport, OUString& rRubyText, OUString& rRubyTextStyle);
+
+ virtual void SAL_CALL startFastElement( sal_Int32 nElement,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList ) override;
+ virtual void SAL_CALL characters( const OUString& aChars ) override;
+};
#endif
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */