sc/qa/unit/data/ods/tdf129940.ods            |binary
 sc/qa/unit/subsequent_filters-test.cxx       |   21 ++++
 sc/source/filter/xml/celltextparacontext.cxx |  120 ++++++++++++++++++++++++---
 sc/source/filter/xml/celltextparacontext.hxx |   45 ++++++++++
 4 files changed, 177 insertions(+), 9 deletions(-)

New commits:
commit 297f511263db7434bb10cdc91230b4d3f8ac9aa0
Author:     Mark Hung <mark...@gmail.com>
AuthorDate: Thu Jan 28 22:53:49 2021 +0800
Commit:     Michael Stahl <michael.st...@allotropia.de>
CommitDate: Wed Feb 10 10:54:46 2021 +0100

    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 <mark...@gmail.com>
    (cherry picked from commit e630da1ed8a27c64bc9f22ecb71afd10bf252d93)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/110567
    Reviewed-by: Michael Stahl <michael.st...@allotropia.de>

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
Binary files /dev/null and b/sc/qa/unit/data/ods/tdf129940.ods 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: */
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to