[Libreoffice-commits] core.git: sw/qa writerfilter/source

Jean-Sebastien Bevilacqua realitix at gmail.com
Tue Mar 28 07:05:51 UTC 2017


 sw/qa/extras/ooxmlexport/ooxmlfieldexport.cxx     |    2 
 sw/qa/extras/ooxmlimport/data/105975.docx         |binary
 sw/qa/extras/ooxmlimport/ooxmlimport.cxx          |    8 +++
 writerfilter/source/dmapper/DomainMapper_Impl.cxx |   46 ++++++++++++++++++++--
 writerfilter/source/dmapper/DomainMapper_Impl.hxx |    4 +
 5 files changed, 55 insertions(+), 5 deletions(-)

New commits:
commit 4d5ce76d894d2335b551f8c2b29437e2049894f0
Author: Jean-Sebastien Bevilacqua <realitix at gmail.com>
Date:   Thu Feb 16 10:16:50 2017 +0100

    tdf#105975 Add Set field parsing (docx) in LibreOffice Writer
    
    Introduction
    ------------
    
    In MSWord, you can create a variable with `SET` field and then
    reference it later in a formula. When you save your file as `docx`,
    this `SET` field is registered in you file. In its current state,
    LibreOffice can't parse the `SET` field in `docx` file.
    
    Context of this fix
    -------------------
    
    This fix is entirely located in the `DomainMapper_Impl.cxx` file
    because it's where the parsing is done.
    
    How this fix works
    ------------------
    
    First, we add `SET` support by adding it to the `aFields[]` variable.
    Next, to handle the `SET` constant, we add a condition (swith case) in
    `DomainMapper_Impl::CloseFieldCommand()` to call `handleFieldSet`.
    Finally, `handleFieldSet` works like `handleFieldAsk` with small
    differences.
    
    Note
    ----
    
    I have renamed `lcl_ExctractAskVariableAndHint` to
    `lcl_ExctractVariableAndHint` because this function is used for both `ASK` and
    `SET` fields.
    
    Change-Id: I2bf948e26e8506ac151d1d0bc8556721bbe0392b
    Reviewed-on: https://gerrit.libreoffice.org/34333
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Miklos Vajna <vmiklos at collabora.co.uk>

diff --git a/sw/qa/extras/ooxmlexport/ooxmlfieldexport.cxx b/sw/qa/extras/ooxmlexport/ooxmlfieldexport.cxx
index ec8b13621001..d473a13f73e2 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlfieldexport.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlfieldexport.cxx
@@ -432,7 +432,7 @@ DECLARE_OOXMLEXPORT_TEST(testFDO76163 , "fdo76163.docx")
     if (!pXmlDoc)
         return;
     //docx file after RT is getting corrupted.
-    assertXPath ( pXmlDoc, "/w:document/w:body/w:p[2]/w:hyperlink/w:r[11]/w:fldChar", "fldCharType", "end" );
+    assertXPath ( pXmlDoc, "/w:document/w:body/w:p[2]/w:hyperlink/w:r[10]/w:fldChar", "fldCharType", "end" );
 }
 
 DECLARE_OOXMLEXPORT_TEST(testFDO78659, "fdo78659.docx")
diff --git a/sw/qa/extras/ooxmlimport/data/105975.docx b/sw/qa/extras/ooxmlimport/data/105975.docx
new file mode 100644
index 000000000000..b902aa168a9a
Binary files /dev/null and b/sw/qa/extras/ooxmlimport/data/105975.docx differ
diff --git a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx
index 77880b935b96..87c71b8afb6b 100644
--- a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx
+++ b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx
@@ -699,6 +699,14 @@ DECLARE_OOXMLIMPORT_TEST(testTdf105143, "tdf105143.docx")
     CPPUNIT_ASSERT_EQUAL(OUString("6674"), aTop);
 }
 
+DECLARE_OOXMLIMPORT_TEST(testTdf105975, "105975.docx")
+{
+    uno::Reference<text::XTextFieldsSupplier> xTextFieldsSupplier(mxComponent, uno::UNO_QUERY);
+    uno::Reference<container::XNameAccess> xMasters(xTextFieldsSupplier->getTextFieldMasters());
+    // Make sure we have a variable named TEST_VAR.
+    CPPUNIT_ASSERT(xMasters->hasByName("com.sun.star.text.FieldMaster.SetExpression.TEST_VAR"));
+}
+
 DECLARE_OOXMLIMPORT_TEST(testfdo76583, "fdo76583.docx")
 {
     // The problem was that the floating table was imported as a non-floating one.
diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.cxx b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
index c64d9de17889..6189f9f139ab 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
@@ -2367,7 +2367,7 @@ std::tuple<OUString, std::vector<OUString>, std::vector<OUString> > splitFieldCo
     return std::make_tuple(sType, arguments, switches);
 }
 
-OUString lcl_ExctractAskVariableAndHint( const OUString& rCommand, OUString& rHint )
+OUString lcl_ExctractVariableAndHint( const OUString& rCommand, OUString& rHint )
 {
     // the first word after "ASK " is the variable
     // the text after the variable and before a '\' is the hint
@@ -2862,7 +2862,7 @@ if(!bFilled)
 //            {OUString("SECTION"),       "",                         FIELD_SECTION      },
 //            {OUString("SECTIONPAGES"),  "",                         FIELD_SECTIONPAGES },
             {OUString("SEQ"),           "SetExpression",            FIELD_SEQ          },
-//            {OUString("SET"),           FIELD_SET          },
+            {OUString("SET"),           "SetExpression",            FIELD_SET          },
 //            {OUString("SKIPIF"),"",                                 FIELD_SKIPIF       },
 //            {OUString("STYLEREF"),"",                               FIELD_STYLEREF     },
             {OUString("SUBJECT"),       "DocInfo.Subject",          FIELD_SUBJECT      },
@@ -2928,6 +2928,42 @@ const FieldConversionMap_t & lcl_GetEnhancedFieldConversion()
     return aEnhancedFieldConversionMap;
 }
 
+void DomainMapper_Impl::handleFieldSet
+    (const FieldContextPtr& pContext,
+     uno::Reference< uno::XInterface > & xFieldInterface,
+     uno::Reference< beans::XPropertySet > const& xFieldProperties)
+{
+    OUString sVariable, sHint;
+
+    sVariable = lcl_ExctractVariableAndHint(pContext->GetCommand(), sHint);
+
+    // remove surrounding "" if exists
+    if( sHint.getLength() >= 2 && sHint.startsWith("\"") )
+    {
+        sHint = sHint.trim().copy(1, sHint.getLength() - 2);
+    }
+
+    // determine field master name
+    uno::Reference< beans::XPropertySet > xMaster =
+        FindOrCreateFieldMaster
+        ("com.sun.star.text.FieldMaster.SetExpression", sVariable );
+
+    // a set field is a string
+    xMaster->setPropertyValue(getPropertyName(PROP_SUB_TYPE), uno::makeAny(text::SetVariableType::STRING));
+
+    // attach the master to the field
+    uno::Reference< text::XDependentTextField > xDependentField
+        ( xFieldInterface, uno::UNO_QUERY_THROW );
+    xDependentField->attachTextFieldMaster( xMaster );
+
+    xFieldProperties->setPropertyValue(getPropertyName(PROP_HINT), uno::makeAny( sHint ));
+    xFieldProperties->setPropertyValue(getPropertyName(PROP_CONTENT), uno::makeAny( sHint ));
+    xFieldProperties->setPropertyValue(getPropertyName(PROP_SUB_TYPE), uno::makeAny(text::SetVariableType::STRING));
+
+    // Mimic MS Word behavior (hide the SET)
+    xFieldProperties->setPropertyValue(getPropertyName(PROP_IS_VISIBLE), uno::makeAny(false));
+}
+
 void DomainMapper_Impl::handleFieldAsk
     (const FieldContextPtr& pContext,
      uno::Reference< uno::XInterface > & xFieldInterface,
@@ -2936,7 +2972,7 @@ void DomainMapper_Impl::handleFieldAsk
     //doesn the command contain a variable name?
     OUString sVariable, sHint;
 
-    sVariable = lcl_ExctractAskVariableAndHint( pContext->GetCommand(),
+    sVariable = lcl_ExctractVariableAndHint( pContext->GetCommand(),
         sHint );
     if(!sVariable.isEmpty())
     {
@@ -4099,7 +4135,9 @@ void DomainMapper_Impl::CloseFieldCommand()
                                 uno::makeAny(nNumberingType));
                     }
                     break;
-                    case FIELD_SET          : break;
+                    case FIELD_SET          :
+                        handleFieldSet(pContext, xFieldInterface, xFieldProperties);
+                    break;
                     case FIELD_SKIPIF       : break;
                     case FIELD_STYLEREF     : break;
                     case FIELD_SUBJECT      :
diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.hxx b/writerfilter/source/dmapper/DomainMapper_Impl.hxx
index e3071b9abe78..f8924f1e75f4 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.hxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.hxx
@@ -651,6 +651,10 @@ public:
     //collect the pieces of the command
     void AppendFieldCommand(OUString& rPartOfCommand);
     void handleRubyEQField( const FieldContextPtr& pContext);
+    void handleFieldSet
+        (const FieldContextPtr& pContext,
+        css::uno::Reference< css::uno::XInterface > & xFieldInterface,
+        css::uno::Reference< css::beans::XPropertySet > const& xFieldProperties);
     void handleFieldAsk
         (const FieldContextPtr& pContext,
         css::uno::Reference< css::uno::XInterface > & xFieldInterface,


More information about the Libreoffice-commits mailing list