diff options
author | Mark Hung <marklh9@gmail.com> | 2021-01-28 22:53:49 +0800 |
---|---|---|
committer | Mark Hung <marklh9@gmail.com> | 2021-02-08 14:07:07 +0100 |
commit | e630da1ed8a27c64bc9f22ecb71afd10bf252d93 (patch) | |
tree | 1567f3bc9ef0c6a39ae69f3090ec1ff23ae75bf0 /sc | |
parent | 667a84c69140bae1020fa1cc019d310b0d382d14 (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>
Diffstat (limited to 'sc')
-rw-r--r-- | sc/qa/unit/data/ods/tdf129940.ods | bin | 0 -> 3773 bytes | |||
-rw-r--r-- | sc/qa/unit/subsequent_filters-test.cxx | 21 | ||||
-rw-r--r-- | sc/source/filter/xml/celltextparacontext.cxx | 120 | ||||
-rw-r--r-- | sc/source/filter/xml/celltextparacontext.hxx | 45 |
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 Binary files differnew file mode 100644 index 000000000000..5cc5369acd49 --- /dev/null +++ b/sc/qa/unit/data/ods/tdf129940.ods diff --git a/sc/qa/unit/subsequent_filters-test.cxx b/sc/qa/unit/subsequent_filters-test.cxx index d0553d74e3c4..7e7c62500674 100644 --- a/sc/qa/unit/subsequent_filters-test.cxx +++ b/sc/qa/unit/subsequent_filters-test.cxx @@ -304,6 +304,7 @@ public: void testDeleteCircles(); void testDrawCircleInMergeCells(); void testDeleteCirclesInRowAndCol(); + void testTdf129940(); CPPUNIT_TEST_SUITE(ScFiltersTest); CPPUNIT_TEST(testCondFormatFormulaIsXLSX); @@ -491,6 +492,7 @@ public: CPPUNIT_TEST(testDeleteCircles); CPPUNIT_TEST(testDrawCircleInMergeCells); CPPUNIT_TEST(testDeleteCirclesInRowAndCol); + CPPUNIT_TEST(testTdf129940); CPPUNIT_TEST_SUITE_END(); @@ -5434,6 +5436,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: */ |