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

Libreoffice Gerrit user logerrit at kemper.freedesktop.org
Fri Nov 16 14:42:10 UTC 2018


 sw/qa/extras/ooxmlexport/data/tdf79435_legacyInputFields.doc |binary
 sw/qa/extras/ooxmlexport/ooxmlexport12.cxx                   |   59 +++++
 sw/qa/extras/ww8export/data/tdf79435_legacyInputFields.docx  |binary
 sw/qa/extras/ww8export/ww8export.cxx                         |    2 
 sw/qa/extras/ww8export/ww8export3.cxx                        |   53 ++++
 sw/source/filter/ww8/docxattributeoutput.cxx                 |  109 ++++++++-
 sw/source/filter/ww8/wrtww8.cxx                              |  121 +++++++++--
 sw/source/filter/ww8/ww8par.hxx                              |   12 -
 sw/source/filter/ww8/ww8par3.cxx                             |   36 ++-
 writerfilter/source/dmapper/FFDataHandler.cxx                |   28 ++
 writerfilter/source/dmapper/FFDataHandler.hxx                |   12 +
 writerfilter/source/dmapper/FormControlHelper.cxx            |   43 +++
 12 files changed, 433 insertions(+), 42 deletions(-)

New commits:
commit 46c1a75b144a4c5fd1f4ab0113b87fe030bebd27
Author:     Justin Luth <justin.luth at collabora.com>
AuthorDate: Sat Oct 20 19:18:02 2018 +0300
Commit:     Miklos Vajna <vmiklos at collabora.com>
CommitDate: Fri Nov 16 15:41:42 2018 +0100

    tdf79435 doc/docx: round-trip legacy input formfields
    
    GrabBag the settings which LO doesn't implement
    (which is all of them) so that the document
    round-trips without losing the config settings.
    
    Change-Id: I00de6c483af68073634430dd74fd445e981573ab
    Reviewed-on: https://gerrit.libreoffice.org/62241
    Tested-by: Jenkins
    Reviewed-by: Justin Luth <justin_luth at sil.org>
    Reviewed-by: Miklos Vajna <vmiklos at collabora.com>

diff --git a/sw/qa/extras/ooxmlexport/data/tdf79435_legacyInputFields.doc b/sw/qa/extras/ooxmlexport/data/tdf79435_legacyInputFields.doc
new file mode 100644
index 000000000000..da7fade8091c
Binary files /dev/null and b/sw/qa/extras/ooxmlexport/data/tdf79435_legacyInputFields.doc differ
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport12.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport12.cxx
index 8a98742a0532..864d97178cb2 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport12.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport12.cxx
@@ -30,6 +30,7 @@
 #include <com/sun/star/text/WrapTextMode.hpp>
 #include <com/sun/star/text/WritingMode2.hpp>
 #include <com/sun/star/text/XBookmarksSupplier.hpp>
+#include <com/sun/star/text/XFormField.hpp>
 #include <com/sun/star/text/XFootnote.hpp>
 #include <com/sun/star/text/XPageCursor.hpp>
 #include <com/sun/star/text/XTextColumns.hpp>
@@ -723,6 +724,64 @@ DECLARE_OOXMLEXPORT_TEST(testObjectCrossReference, "object_cross_reference.odt")
     CPPUNIT_ASSERT_EQUAL(sal_uInt16(21), nIndex);
 }
 
+DECLARE_OOXMLEXPORT_TEST(testTdf79435_legacyInputFields, "tdf79435_legacyInputFields.doc")
+{
+    //using .doc input file to verify cross-format compatability.
+    uno::Reference<text::XFormField> xFormField;
+    xFormField
+        = getProperty<uno::Reference<text::XFormField>>(getRun(getParagraph(5), 3), "Bookmark");
+    uno::Reference<container::XNameContainer> xParameters(xFormField->getParameters());
+
+    OUString sTmp;
+    xParameters->getByName("EntryMacro") >>= sTmp;
+    CPPUNIT_ASSERT_EQUAL(OUString("test"), sTmp);
+    xParameters->getByName("Help") >>= sTmp;
+    CPPUNIT_ASSERT_EQUAL(OUString("F1Help"), sTmp);
+    xParameters->getByName("ExitMacro") >>= sTmp;
+    CPPUNIT_ASSERT_EQUAL(OUString("test"), sTmp);
+    xParameters->getByName("Hint") >>= sTmp;
+    CPPUNIT_ASSERT_EQUAL(OUString("StatusHelp"), sTmp);
+    xParameters->getByName("Content") >>= sTmp;
+    CPPUNIT_ASSERT_EQUAL(OUString("Camelcase"), sTmp);
+    xParameters->getByName("Format") >>= sTmp;
+    CPPUNIT_ASSERT_EQUAL(OUString("TITLE CASE"), sTmp);
+
+    sal_uInt16 nMaxLength = 0;
+    xParameters->getByName("MaxLength") >>= nMaxLength;
+    CPPUNIT_ASSERT_EQUAL_MESSAGE("Max Length", sal_uInt16(10), nMaxLength);
+
+    // too bad this is based on character runs - just found try trial and error.
+    xFormField
+        = getProperty<uno::Reference<text::XFormField>>(getRun(getParagraph(6), 2), "Bookmark");
+    xParameters.set(xFormField->getParameters());
+    xParameters->getByName("Type") >>= sTmp;
+    CPPUNIT_ASSERT_EQUAL(OUString("calculated"), sTmp);
+
+    xFormField
+        = getProperty<uno::Reference<text::XFormField>>(getRun(getParagraph(7), 2), "Bookmark");
+    xParameters.set(xFormField->getParameters());
+    xParameters->getByName("Type") >>= sTmp;
+    CPPUNIT_ASSERT_EQUAL(OUString("currentDate"), sTmp);
+
+    xFormField
+        = getProperty<uno::Reference<text::XFormField>>(getRun(getParagraph(7), 6), "Bookmark");
+    xParameters.set(xFormField->getParameters());
+    xParameters->getByName("Type") >>= sTmp;
+    CPPUNIT_ASSERT_EQUAL(OUString("currentTime"), sTmp);
+
+    xFormField
+        = getProperty<uno::Reference<text::XFormField>>(getRun(getParagraph(8), 2), "Bookmark");
+    xParameters.set(xFormField->getParameters());
+    xParameters->getByName("Type") >>= sTmp;
+    CPPUNIT_ASSERT_EQUAL(OUString("number"), sTmp);
+
+    xFormField
+        = getProperty<uno::Reference<text::XFormField>>(getRun(getParagraph(8), 6), "Bookmark");
+    xParameters.set(xFormField->getParameters());
+    xParameters->getByName("Type") >>= sTmp;
+    CPPUNIT_ASSERT_EQUAL(OUString("date"), sTmp);
+}
+
 DECLARE_OOXMLEXPORT_TEST(testTdf120224_textControlCrossRef, "tdf120224_textControlCrossRef.docx")
 {
     uno::Reference<text::XTextDocument> xTextDocument(mxComponent, uno::UNO_QUERY);
diff --git a/sw/qa/extras/ww8export/data/tdf79435_legacyInputFields.docx b/sw/qa/extras/ww8export/data/tdf79435_legacyInputFields.docx
new file mode 100644
index 000000000000..55d1a1f22962
Binary files /dev/null and b/sw/qa/extras/ww8export/data/tdf79435_legacyInputFields.docx differ
diff --git a/sw/qa/extras/ww8export/ww8export.cxx b/sw/qa/extras/ww8export/ww8export.cxx
index cb73378615e7..bac74e82d83a 100644
--- a/sw/qa/extras/ww8export/ww8export.cxx
+++ b/sw/qa/extras/ww8export/ww8export.cxx
@@ -1116,7 +1116,7 @@ DECLARE_WW8EXPORT_TEST(testBnc636128, "bnc636128.doc")
     uno::Reference<text::XFormField> xFormField = getProperty< uno::Reference<text::XFormField> >(getRun(getParagraph(1), 2), "Bookmark");
     uno::Reference<container::XNameContainer> xParameters = xFormField->getParameters();
     // This resulted in a container.NoSuchElementException.
-    CPPUNIT_ASSERT_EQUAL(OUString("5"), xParameters->getByName("MaxLength").get<OUString>());
+    CPPUNIT_ASSERT_EQUAL(sal_uInt16(5), xParameters->getByName("MaxLength").get<sal_uInt16>());
 }
 
 
diff --git a/sw/qa/extras/ww8export/ww8export3.cxx b/sw/qa/extras/ww8export/ww8export3.cxx
index d5a888e60dd6..901450dc78e5 100644
--- a/sw/qa/extras/ww8export/ww8export3.cxx
+++ b/sw/qa/extras/ww8export/ww8export3.cxx
@@ -12,6 +12,7 @@
 #include <IDocumentSettingAccess.hxx>
 #include <com/sun/star/beans/XPropertySet.hpp>
 #include <com/sun/star/container/XIndexAccess.hpp>
+#include <com/sun/star/text/XFormField.hpp>
 #include <com/sun/star/text/XTextFramesSupplier.hpp>
 #include <com/sun/star/text/XTextTable.hpp>
 #include <com/sun/star/text/XTextTablesSupplier.hpp>
@@ -66,6 +67,58 @@ DECLARE_WW8EXPORT_TEST(testFdo53985, "fdo53985.doc")
     CPPUNIT_ASSERT_EQUAL_MESSAGE("Section4 is protected", false, getProperty<bool>(xSect, "IsProtected"));
 }
 
+DECLARE_WW8EXPORT_TEST(testTdf79435_legacyInputFields, "tdf79435_legacyInputFields.docx")
+{
+    //using .docx input file to verify cross-format compatability.
+    uno::Reference<text::XFormField> xFormField;
+    xFormField = getProperty< uno::Reference<text::XFormField> >(getRun(getParagraph(5), 3), "Bookmark");
+    uno::Reference<container::XNameContainer> xParameters(xFormField->getParameters());
+
+    OUString sTmp;
+    xParameters->getByName("EntryMacro") >>= sTmp;
+    CPPUNIT_ASSERT_EQUAL(OUString("test"), sTmp);
+    xParameters->getByName("Help") >>= sTmp;
+    CPPUNIT_ASSERT_EQUAL(OUString("F1Help"), sTmp);
+    xParameters->getByName("ExitMacro") >>= sTmp;
+    CPPUNIT_ASSERT_EQUAL(OUString("test"), sTmp);
+    xParameters->getByName("Description") >>= sTmp;
+    CPPUNIT_ASSERT_EQUAL(OUString("StatusHelp"), sTmp);
+    xParameters->getByName("Content") >>= sTmp;
+    CPPUNIT_ASSERT_EQUAL(OUString("Camelcase"), sTmp);
+    xParameters->getByName("Format") >>= sTmp;
+    CPPUNIT_ASSERT_EQUAL(OUString("TITLE CASE"), sTmp);
+
+    sal_uInt16 nMaxLength = 0;
+    xParameters->getByName("MaxLength") >>= nMaxLength;
+    CPPUNIT_ASSERT_EQUAL_MESSAGE("Max Length", sal_uInt16(10), nMaxLength);
+
+    // too bad this is based on character runs - just found try trial and error.
+    xFormField = getProperty< uno::Reference<text::XFormField> >(getRun(getParagraph(6), 2), "Bookmark");
+    xParameters.set(xFormField->getParameters());
+    xParameters->getByName("Type") >>= sTmp;
+    CPPUNIT_ASSERT_EQUAL(OUString("calculated"), sTmp);
+
+    xFormField = getProperty< uno::Reference<text::XFormField> >(getRun(getParagraph(7), 2), "Bookmark");
+    xParameters.set(xFormField->getParameters());
+    xParameters->getByName("Type") >>= sTmp;
+    CPPUNIT_ASSERT_EQUAL(OUString("currentDate"), sTmp);
+
+    xFormField = getProperty< uno::Reference<text::XFormField> >(getRun(getParagraph(7), 6), "Bookmark");
+    xParameters.set(xFormField->getParameters());
+    xParameters->getByName("Type") >>= sTmp;
+    CPPUNIT_ASSERT_EQUAL(OUString("currentTime"), sTmp);
+
+    xFormField = getProperty< uno::Reference<text::XFormField> >(getRun(getParagraph(8), 2), "Bookmark");
+    xParameters.set(xFormField->getParameters());
+    xParameters->getByName("Type") >>= sTmp;
+    CPPUNIT_ASSERT_EQUAL(OUString("number"), sTmp);
+
+    xFormField = getProperty< uno::Reference<text::XFormField> >(getRun(getParagraph(8), 6), "Bookmark");
+    xParameters.set(xFormField->getParameters());
+    xParameters->getByName("Type") >>= sTmp;
+    CPPUNIT_ASSERT_EQUAL(OUString("date"), sTmp);
+}
+
 DECLARE_WW8EXPORT_TEST(testTdf120225_textControlCrossRef, "tdf120225_textControlCrossRef.doc")
 {
     uno::Reference<text::XTextDocument> xTextDocument(mxComponent, uno::UNO_QUERY);
diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx b/sw/source/filter/ww8/docxattributeoutput.cxx
index e2a5ebeee009..81c1b4fecff1 100644
--- a/sw/source/filter/ww8/docxattributeoutput.cxx
+++ b/sw/source/filter/ww8/docxattributeoutput.cxx
@@ -178,7 +178,11 @@ static const sal_Int32 Tag_StartSection = 17;
 class FFDataWriterHelper
 {
     ::sax_fastparser::FSHelperPtr m_pSerializer;
-    void writeCommonStart( const OUString& rName )
+    void writeCommonStart( const OUString& rName,
+                           const OUString& rEntryMacro,
+                           const OUString& rExitMacro,
+                           const OUString& rHelp,
+                           const OUString& rHint )
     {
         m_pSerializer->startElementNS( XML_w, XML_ffData, FSEND );
         m_pSerializer->singleElementNS( XML_w, XML_name,
@@ -188,6 +192,33 @@ class FFDataWriterHelper
         m_pSerializer->singleElementNS( XML_w, XML_calcOnExit,
             FSNS( XML_w, XML_val ),
             "0", FSEND );
+
+        if ( !rEntryMacro.isEmpty() )
+            m_pSerializer->singleElementNS( XML_w, XML_entryMacro,
+                FSNS(XML_w, XML_val),
+                OUStringToOString( rEntryMacro, RTL_TEXTENCODING_UTF8 ).getStr(),
+                FSEND );
+
+        if ( !rExitMacro.isEmpty() )
+            m_pSerializer->singleElementNS( XML_w, XML_exitMacro,
+                FSNS(XML_w, XML_val),
+                OUStringToOString( rExitMacro, RTL_TEXTENCODING_UTF8 ).getStr(),
+                FSEND );
+
+        if ( !rHelp.isEmpty() )
+            m_pSerializer->singleElementNS( XML_w, XML_helpText,
+                FSNS(XML_w, XML_type), OString("text"),
+                FSNS(XML_w, XML_val),
+                OUStringToOString( rHelp, RTL_TEXTENCODING_UTF8 ).getStr(),
+                FSEND );
+
+        if ( !rHint.isEmpty() )
+            m_pSerializer->singleElementNS( XML_w, XML_statusText,
+                FSNS(XML_w, XML_type), OString("text"),
+                FSNS(XML_w, XML_val),
+                OUStringToOString( rHint, RTL_TEXTENCODING_UTF8 ).getStr(),
+                FSEND );
+
     }
     void writeFinish()
     {
@@ -195,9 +226,14 @@ class FFDataWriterHelper
     }
 public:
     explicit FFDataWriterHelper( const ::sax_fastparser::FSHelperPtr& rSerializer ) : m_pSerializer( rSerializer ){}
-    void WriteFormCheckbox( const OUString& rName, bool bChecked )
-    {
-       writeCommonStart( rName );
+    void WriteFormCheckbox( const OUString& rName,
+                            const OUString& rEntryMacro,
+                            const OUString& rExitMacro,
+                            const OUString& rHelp,
+                            const OUString& rHint,
+                            bool bChecked )
+    {
+       writeCommonStart( rName, rEntryMacro, rExitMacro, rHelp, rHint );
        // Checkbox specific bits
        m_pSerializer->startElementNS( XML_w, XML_checkBox, FSEND );
        // currently hardcoding autosize
@@ -209,9 +245,39 @@ public:
         m_pSerializer->endElementNS( XML_w, XML_checkBox );
        writeFinish();
     }
-    void WriteFormText(  const OUString& rName )
-    {
-       writeCommonStart( rName );
+    void WriteFormText(  const OUString& rName,
+                         const OUString& rEntryMacro,
+                         const OUString& rExitMacro,
+                         const OUString& rHelp,
+                         const OUString& rHint,
+                         const OUString& rType,
+                         const OUString& rDefaultText,
+                         sal_uInt16 nMaxLength,
+                         const OUString& rFormat )
+    {
+        writeCommonStart( rName, rEntryMacro, rExitMacro, rHelp, rHint );
+
+        m_pSerializer->startElementNS( XML_w, XML_textInput, FSEND );
+        if ( !rType.isEmpty() )
+            m_pSerializer->singleElementNS( XML_w, XML_type,
+                FSNS(XML_w, XML_val),
+                OUStringToOString( rType, RTL_TEXTENCODING_UTF8 ).getStr(),
+                FSEND );
+        if ( !rDefaultText.isEmpty() )
+            m_pSerializer->singleElementNS( XML_w, XML_default,
+                FSNS(XML_w, XML_val),
+                OUStringToOString( rDefaultText, RTL_TEXTENCODING_UTF8 ).getStr(),
+                FSEND );
+        if ( nMaxLength )
+            m_pSerializer->singleElementNS( XML_w, XML_maxLength,
+                FSNS(XML_w, XML_val), OString::number(nMaxLength), FSEND );
+        if ( !rFormat.isEmpty() )
+            m_pSerializer->singleElementNS( XML_w, XML_format,
+                FSNS(XML_w, XML_val),
+                OUStringToOString( rFormat, RTL_TEXTENCODING_UTF8 ).getStr(),
+                FSEND );
+        m_pSerializer->endElementNS( XML_w, XML_textInput );
+
        writeFinish();
     }
 };
@@ -1641,12 +1707,24 @@ void DocxAttributeOutput::DoWriteAnnotationMarks()
 void DocxAttributeOutput::WriteFFData(  const FieldInfos& rInfos )
 {
     const ::sw::mark::IFieldmark& rFieldmark = *rInfos.pFieldmark;
+    FieldMarkParamsHelper params( rFieldmark );
+
+    OUString sEntryMacro;
+    params.extractParam("EntryMacro", sEntryMacro);
+    OUString sExitMacro;
+    params.extractParam("ExitMacro", sExitMacro);
+    OUString sHelp;
+    params.extractParam("Help", sHelp);
+    OUString sHint;
+    params.extractParam("Hint", sHint); // .docx StatusText
+    if ( sHint.isEmpty() )
+        params.extractParam("Description", sHint); // .doc StatusText
+
     if ( rInfos.eType == ww::eFORMDROPDOWN )
     {
         uno::Sequence< OUString> vListEntries;
         OUString sName, sSelected;
 
-        FieldMarkParamsHelper params( rFieldmark );
         params.extractParam( ODF_FORMDROPDOWN_LISTENTRY, vListEntries );
         sName = params.getName();
         sal_Int32 nSelectedIndex = 0;
@@ -1664,7 +1742,6 @@ void DocxAttributeOutput::WriteFFData(  const FieldInfos& rInfos )
         OUString sName;
         bool bChecked = false;
 
-        FieldMarkParamsHelper params( rFieldmark );
         params.extractParam( ODF_FORMCHECKBOX_NAME, sName );
 
         const sw::mark::ICheckboxFieldmark* pCheckboxFm = dynamic_cast<const sw::mark::ICheckboxFieldmark*>(&rFieldmark);
@@ -1672,13 +1749,21 @@ void DocxAttributeOutput::WriteFFData(  const FieldInfos& rInfos )
             bChecked = true;
 
         FFDataWriterHelper ffdataOut( m_pSerializer );
-        ffdataOut.WriteFormCheckbox( sName, bChecked );
+        ffdataOut.WriteFormCheckbox( sName, sEntryMacro, sExitMacro, sHelp, sHint, bChecked );
     }
     else if ( rInfos.eType == ww::eFORMTEXT )
     {
-        FieldMarkParamsHelper params( rFieldmark );
+        OUString sType;
+        params.extractParam("Type", sType);
+        OUString sDefaultText;
+        params.extractParam("Content", sDefaultText);
+        sal_uInt16 nMaxLength = 0;
+        params.extractParam("MaxLength", nMaxLength);
+        OUString sFormat;
+        params.extractParam("Format", sFormat);
         FFDataWriterHelper ffdataOut( m_pSerializer );
-        ffdataOut.WriteFormText( params.getName() );
+        ffdataOut.WriteFormText( params.getName(), sEntryMacro, sExitMacro, sHelp, sHint,
+                                 sType, sDefaultText, nMaxLength, sFormat );
     }
 }
 
diff --git a/sw/source/filter/ww8/wrtww8.cxx b/sw/source/filter/ww8/wrtww8.cxx
index f0ab7e1ed7c4..1895ae523cb3 100644
--- a/sw/source/filter/ww8/wrtww8.cxx
+++ b/sw/source/filter/ww8/wrtww8.cxx
@@ -3831,10 +3831,16 @@ void WW8Export::WriteFormData( const ::sw::mark::IFieldmark& rFieldmark )
     if ( rFieldmark.GetFieldname() == ODF_FORMDROPDOWN )
         type=2;
 
-    ::sw::mark::IFieldmark::parameter_map_t::const_iterator pNameParameter = rFieldmark.GetParameters()->find("name");
+    ::sw::mark::IFieldmark::parameter_map_t::const_iterator pParameter = rFieldmark.GetParameters()->find("name");
     OUString ffname;
-    if(pNameParameter != rFieldmark.GetParameters()->end())
-        pNameParameter->second >>= ffname;
+    if ( pParameter != rFieldmark.GetParameters()->end() )
+    {
+        OUString aName;
+        pParameter->second >>= aName;
+        assert( aName.getLength() < 21 && "jluth seeing if following documentation will cause problems." );
+        const sal_Int32 nLen = std::min( sal_Int32(20), aName.getLength() );
+        ffname = aName.copy(0, nLen);
+    }
 
     sal_uLong nDataStt = pDataStrm->Tell();
     m_pChpPlc->AppendFkpEntry(Strm().Tell());
@@ -3877,17 +3883,109 @@ void WW8Export::WriteFormData( const ::sw::mark::IFieldmark& rFieldmark )
             ffres = 0;
     }
     aFieldHeader.bits |= ( (ffres<<2) & 0x7C );
+
+    OUString ffdeftext;
+    OUString ffformat;
+    OUString ffhelptext = rFieldmark.GetFieldHelptext();
+    if ( ffhelptext.getLength() > 255 )
+        ffhelptext = ffhelptext.copy(0, 255);
+    OUString ffstattext;
+    OUString ffentrymcr;
+    OUString ffexitmcr;
     if (type == 0) // iTypeText
     {
-        sw::mark::IFieldmark::parameter_map_t::const_iterator pParameter = rFieldmark.GetParameters()->find("MaxLength");
-        if (pParameter != rFieldmark.GetParameters()->end())
+        sal_uInt16 nType = 0;
+        pParameter = rFieldmark.GetParameters()->find("Type");
+        if ( pParameter != rFieldmark.GetParameters()->end() )
+        {
+            OUString aType;
+            pParameter->second >>= aType;
+            if ( aType == "number" )            nType = 1;
+            else if ( aType == "date" )         nType = 2;
+            else if ( aType == "currentTime" )  nType = 3;
+            else if ( aType == "currentDate" )  nType = 4;
+            else if ( aType == "calculated" )   nType = 5;
+            aFieldHeader.bits |= nType<<11; // FFDataBits-F  00111000 00000000
+        }
+
+        if ( nType < 3 || nType == 5 )  // not currentTime or currentDate
+        {
+            pParameter = rFieldmark.GetParameters()->find("Content");
+            if ( pParameter != rFieldmark.GetParameters()->end() )
+            {
+                OUString aDefaultText;
+                pParameter->second >>= aDefaultText;
+                assert( aDefaultText.getLength() < 256 && "jluth seeing if following documentation will cause problems." );
+                const sal_Int32 nLen = std::min( sal_Int32(255), aDefaultText.getLength() );
+                ffdeftext = aDefaultText.copy (0, nLen);
+            }
+        }
+
+        pParameter = rFieldmark.GetParameters()->find("MaxLength");
+        if ( pParameter != rFieldmark.GetParameters()->end() )
+        {
+            sal_uInt16 nLength = 0;
+            pParameter->second >>= nLength;
+            assert( nLength < 32768 && "jluth seeing if following documentation will cause problems." );
+            nLength = std::min( sal_uInt16(32767), nLength );
+            aFieldHeader.cch = nLength;
+        }
+
+        pParameter = rFieldmark.GetParameters()->find("Format");
+        if ( pParameter != rFieldmark.GetParameters()->end() )
         {
-            OUString aLength;
-            pParameter->second >>= aLength;
-            aFieldHeader.cch = aLength.toUInt32();
+            OUString aFormat;
+            pParameter->second >>= aFormat;
+            const sal_Int32 nLen = std::min( sal_Int32(64), aFormat.getLength() );
+            assert( nLen < 65 && "jluth seeing if following documentation will cause problems." );
+            ffformat = aFormat.copy(0, nLen);
         }
     }
 
+    pParameter = rFieldmark.GetParameters()->find("Help"); //help
+    if ( ffhelptext.isEmpty() && pParameter != rFieldmark.GetParameters()->end() )
+    {
+        OUString aHelpText;
+        pParameter->second >>= aHelpText;
+        const sal_Int32 nLen = std::min( sal_Int32(255), aHelpText.getLength() );
+        ffhelptext = aHelpText.copy (0, nLen);
+    }
+    if ( !ffhelptext.isEmpty() )
+        aFieldHeader.bits |= 0x1<<7;
+
+    pParameter = rFieldmark.GetParameters()->find("Description"); // doc tooltip
+    if ( pParameter == rFieldmark.GetParameters()->end() )
+        pParameter = rFieldmark.GetParameters()->find("Hint"); //docx tooltip
+    if ( pParameter != rFieldmark.GetParameters()->end() )
+    {
+        OUString aStatusText;
+        pParameter->second >>= aStatusText;
+        const sal_Int32 nLen = std::min( sal_Int32(138), aStatusText.getLength() );
+        ffstattext = aStatusText.copy (0, nLen);
+    }
+    if ( !ffstattext.isEmpty() )
+        aFieldHeader.bits |= 0x1<<8;
+
+    pParameter = rFieldmark.GetParameters()->find("EntryMacro");
+    if ( pParameter != rFieldmark.GetParameters()->end() )
+    {
+        OUString aEntryMacro;
+        pParameter->second >>= aEntryMacro;
+        assert( aEntryMacro.getLength() < 33 && "jluth seeing if following documentation will cause problems." );
+        const sal_Int32 nLen = std::min( sal_Int32(32), aEntryMacro.getLength() );
+        ffentrymcr = aEntryMacro.copy (0, nLen);
+    }
+
+    pParameter = rFieldmark.GetParameters()->find("ExitMacro");
+    if ( pParameter != rFieldmark.GetParameters()->end() )
+    {
+        OUString aExitMacro;
+        pParameter->second >>= aExitMacro;
+        assert( aExitMacro.getLength() < 33 && "jluth seeing if following documentation will cause problems." );
+        const sal_Int32 nLen = std::min( sal_Int32(32), aExitMacro.getLength() );
+        ffexitmcr = aExitMacro.copy (0, nLen);
+    }
+
     std::vector< OUString > aListItems;
     if (type==2)
     {
@@ -3902,13 +4000,6 @@ void WW8Export::WriteFormData( const ::sw::mark::IFieldmark& rFieldmark )
         }
     }
 
-    const OUString ffdeftext;
-    const OUString ffformat;
-    const OUString ffhelptext;
-    const OUString ffstattext;
-    const OUString ffentrymcr;
-    const OUString ffexitmcr;
-
     const sal_uInt8 aFieldData[] =
     {
         0x44,0,         // the start of "next" data
diff --git a/sw/source/filter/ww8/ww8par.hxx b/sw/source/filter/ww8/ww8par.hxx
index 5cffd97a179e..fc8ab8c5d2b7 100644
--- a/sw/source/filter/ww8/ww8par.hxx
+++ b/sw/source/filter/ww8/ww8par.hxx
@@ -652,17 +652,16 @@ protected:
 public:
     WW8FormulaControl(const OUString& rN, SwWW8ImplReader &rRdr)
         : mrRdr(rRdr), mfUnknown(0), mfDropdownIndex(0),
-        mfToolTip(0), mfNoMark(0), mfUseSize(0), mfNumbersOnly(0), mfDateOnly(0),
-        mfUnused(0), mhpsCheckBox(20), mnChecked(0), mnMaxLen(0), msName( rN )
+        mfToolTip(0), mfNoMark(0), mfType(0),
+        mfUnused(0), mhpsCheckBox(20), mnChecked(0), mnMaxLen(0),
+        mbHelp(false), msName( rN )
     {
     }
     sal_uInt8 mfUnknown:2;
     sal_uInt8 mfDropdownIndex:6;
     sal_uInt8 mfToolTip:1;
     sal_uInt8 mfNoMark:1;
-    sal_uInt8 mfUseSize:1;
-    sal_uInt8 mfNumbersOnly:1;
-    sal_uInt8 mfDateOnly:1;
+    sal_uInt8 mfType:3;
     sal_uInt8 mfUnused:3;
 
     sal_uInt16 mhpsCheckBox;
@@ -673,8 +672,11 @@ public:
     OUString msTitle;
     OUString msDefault;
     OUString msFormatting;
+    bool mbHelp;
     OUString msHelp;
     OUString msToolTip;
+    OUString msEntryMcr;
+    OUString msExitMcr;
     std::vector<OUString> maListEntries;
     virtual ~WW8FormulaControl() {}
     void FormulaRead(SwWw8ControlType nWhich,SvStream *pD);
diff --git a/sw/source/filter/ww8/ww8par3.cxx b/sw/source/filter/ww8/ww8par3.cxx
index 53d5016661ef..0aec993a1159 100644
--- a/sw/source/filter/ww8/ww8par3.cxx
+++ b/sw/source/filter/ww8/ww8par3.cxx
@@ -159,9 +159,31 @@ eF_ResT SwWW8ImplReader::Read_F_FormTextBox( WW8FieldDesc* pF, OUString& rStr )
             m_aFieldStack.back().SetBookmarkName(aBookmarkName);
             m_aFieldStack.back().SetBookmarkType(ODF_FORMTEXT);
             m_aFieldStack.back().getParameters()["Description"] <<= aFormula.msToolTip;
+            if ( aFormula.mbHelp && !aFormula.msHelp.isEmpty() )
+                m_aFieldStack.back().getParameters()["Help"] <<= aFormula.msHelp;
             m_aFieldStack.back().getParameters()["Name"] <<= aFormula.msTitle;
             if (aFormula.mnMaxLen)
-                m_aFieldStack.back().getParameters()["MaxLength"] <<= OUString::number(aFormula.mnMaxLen);
+                m_aFieldStack.back().getParameters()["MaxLength"] <<= aFormula.mnMaxLen;
+
+            if ( aFormula.mfType == 1 )
+                m_aFieldStack.back().getParameters()["Type"] <<= OUString("number");
+            else if ( aFormula.mfType == 2 )
+                m_aFieldStack.back().getParameters()["Type"] <<= OUString("date");
+            else if ( aFormula.mfType == 3 )
+                m_aFieldStack.back().getParameters()["Type"] <<= OUString("currentTime");
+            else if ( aFormula.mfType == 4 )
+                m_aFieldStack.back().getParameters()["Type"] <<= OUString("currentDate");
+            else if ( aFormula.mfType == 5 )
+                m_aFieldStack.back().getParameters()["Type"] <<= OUString("calculated");
+
+            if ( !aFormula.msDefault.isEmpty() )
+                m_aFieldStack.back().getParameters()["Content"] <<= aFormula.msDefault;
+            if ( !aFormula.msFormatting.isEmpty() )
+                m_aFieldStack.back().getParameters()["Format"] <<= aFormula.msFormatting;
+            if ( !aFormula.msEntryMcr.isEmpty() )
+                m_aFieldStack.back().getParameters()["EntryMacro"] <<= aFormula.msEntryMcr;
+            if ( !aFormula.msExitMcr.isEmpty() )
+                m_aFieldStack.back().getParameters()["ExitMacro"] <<= aFormula.msExitMcr;
         }
         return eF_ResT::TEXT;
     }
@@ -2186,8 +2208,10 @@ void WW8FormulaControl::FormulaRead(SwWw8ControlType nWhich,
     // xstzStatText
     msToolTip = read_uInt16_BeltAndBracesString(*pDataStream);
 
-    /*String sEntryMacro =*/ read_uInt16_BeltAndBracesString(*pDataStream);
-    /*String sExitMcr =*/ read_uInt16_BeltAndBracesString(*pDataStream);
+    // xstzEntryMcr
+    msEntryMcr = read_uInt16_BeltAndBracesString(*pDataStream);
+    //xstzExitMcr
+    msExitMcr = read_uInt16_BeltAndBracesString(*pDataStream);
 
     if (nWhich == WW8_CT_DROPDOWN)
     {
@@ -2227,12 +2251,12 @@ void WW8FormulaControl::FormulaRead(SwWw8ControlType nWhich,
     }
     mfDropdownIndex = iRes;
 
+    mbHelp = bits1 & 0x80;
+
     nField = bits2;
     mfToolTip = nField & 0x01;
     mfNoMark = (nField & 0x02)>>1;
-    mfUseSize = (nField & 0x04)>>2;
-    mfNumbersOnly= (nField & 0x08)>>3;
-    mfDateOnly = (nField & 0x10)>>4;
+    mfType = (nField & 0x38)>>3;
     mfUnused = (nField & 0xE0)>>5;
 }
 
diff --git a/writerfilter/source/dmapper/FFDataHandler.cxx b/writerfilter/source/dmapper/FFDataHandler.cxx
index ebd4e2f6538a..2429a77c8f99 100644
--- a/writerfilter/source/dmapper/FFDataHandler.cxx
+++ b/writerfilter/source/dmapper/FFDataHandler.cxx
@@ -32,7 +32,8 @@ LoggedProperties("FFDataHandler"),
 m_nCheckboxHeight(0),
 m_bCheckboxAutoHeight(false),
 m_nCheckboxChecked(-1),
-m_nCheckboxDefault(-1)
+m_nCheckboxDefault(-1),
+m_nTextMaxLength(0)
 {
 }
 
@@ -72,6 +73,16 @@ void FFDataHandler::lcl_sprm(Sprm & r_Sprm)
             resolveSprm(r_Sprm);
         }
         break;
+    case NS_ooxml::LN_CT_FFData_entryMacro:
+        {
+            m_sEntryMacro = r_Sprm.getValue()->getString();
+        }
+        break;
+    case NS_ooxml::LN_CT_FFData_exitMacro:
+        {
+            m_sExitMacro = r_Sprm.getValue()->getString();
+        }
+        break;
     case NS_ooxml::LN_CT_FFCheckBox_size:
         {
             m_nCheckboxHeight = r_Sprm.getValue()->getInt();
@@ -112,11 +123,26 @@ void FFDataHandler::lcl_sprm(Sprm & r_Sprm)
             resolveSprm(r_Sprm);
         }
         break;
+    case NS_ooxml::LN_CT_FFTextInput_type:
+        {
+            m_sTextType = r_Sprm.getValue()->getString();
+        }
+        break;
     case NS_ooxml::LN_CT_FFTextInput_default:
         {
             m_sTextDefault = r_Sprm.getValue()->getString();
         }
         break;
+    case NS_ooxml::LN_CT_FFTextInput_maxLength:
+        {
+            m_nTextMaxLength = r_Sprm.getValue()->getInt();
+        }
+        break;
+    case NS_ooxml::LN_CT_FFTextInput_format:
+        {
+            m_sTextFormat = r_Sprm.getValue()->getString();
+        }
+        break;
     case NS_ooxml::LN_CT_FFData_textInput:
         {
             resolveSprm(r_Sprm);
diff --git a/writerfilter/source/dmapper/FFDataHandler.hxx b/writerfilter/source/dmapper/FFDataHandler.hxx
index 7289d6f6c09f..84ac070e50de 100644
--- a/writerfilter/source/dmapper/FFDataHandler.hxx
+++ b/writerfilter/source/dmapper/FFDataHandler.hxx
@@ -44,6 +44,9 @@ public:
     // member: statusText
     const OUString & getStatusText() const { return m_sStatusText;}
 
+    const OUString & getEntryMacro() const { return m_sEntryMacro;}
+    const OUString & getExitMacro() const { return m_sExitMacro;}
+
     // member: checkboxHeight
     sal_uInt32 getCheckboxHeight() const { return m_nCheckboxHeight;}
 
@@ -62,6 +65,10 @@ public:
     // member: textDefault
     const OUString & getTextDefault() const { return m_sTextDefault;}
 
+    const OUString & getTextType() const { return m_sTextType; }
+    const OUString & getTextFormat() const { return m_sTextFormat; }
+    sal_uInt16 getTextMaxLength() const { return m_nTextMaxLength; }
+
     // sprm
     void resolveSprm(Sprm & r_sprm);
 
@@ -69,6 +76,8 @@ private:
     OUString m_sName;
     OUString m_sHelpText;
     OUString m_sStatusText;
+    OUString m_sEntryMacro;
+    OUString m_sExitMacro;
     sal_uInt32 m_nCheckboxHeight;
     bool m_bCheckboxAutoHeight;
     int m_nCheckboxChecked;
@@ -76,6 +85,9 @@ private:
     OUString m_sDropDownResult;
     DropDownEntries_t m_DropDownEntries;
     OUString m_sTextDefault;
+    OUString m_sTextType;
+    OUString m_sTextFormat;
+    sal_uInt16 m_nTextMaxLength;
 
     // sprm
     void lcl_sprm(Sprm & r_sprm) override;
diff --git a/writerfilter/source/dmapper/FormControlHelper.cxx b/writerfilter/source/dmapper/FormControlHelper.cxx
index 3877763edab1..3088a4a27361 100644
--- a/writerfilter/source/dmapper/FormControlHelper.cxx
+++ b/writerfilter/source/dmapper/FormControlHelper.cxx
@@ -37,6 +37,7 @@
 #include "FormControlHelper.hxx"
 #include <xmloff/odffields.hxx>
 #include <comphelper/sequence.hxx>
+#include <tools/diagnose_ex.h>
 
 namespace writerfilter {
 namespace dmapper {
@@ -205,14 +206,52 @@ void FormControlHelper::processField(uno::Reference<text::XFormField> const& xFo
     uno::Reference<container::XNamed> xNamed( xFormField, uno::UNO_QUERY );
     if ( m_pFFData && xNamed.is() && xNameCont.is() )
     {
+        OUString sTmp = m_pFFData->getEntryMacro();
+        if ( !sTmp.isEmpty() )
+            xNameCont->insertByName( "EntryMacro", uno::makeAny(sTmp) );
+        sTmp = m_pFFData->getExitMacro();
+        if ( !sTmp.isEmpty() )
+            xNameCont->insertByName( "ExitMacro", uno::makeAny(sTmp) );
+
+        sTmp = m_pFFData->getHelpText();
+        if ( !sTmp.isEmpty() )
+            xNameCont->insertByName( "Help", uno::makeAny(sTmp) );
+
+        sTmp = m_pFFData->getStatusText();
+        if ( !sTmp.isEmpty() )
+            xNameCont->insertByName( "Hint", uno::makeAny(sTmp) );
 
         if (m_pImpl->m_eFieldId == FIELD_FORMTEXT )
         {
             xFormField->setFieldType(ODF_FORMTEXT);
-            if (  !m_pFFData->getName().isEmpty() )
+            sTmp = m_pFFData->getName();
+            try
+            {
+                if ( !sTmp.isEmpty() )
+                    xNamed->setName( sTmp );
+            }
+            catch ( uno::Exception& )
+            {
+                DBG_UNHANDLED_EXCEPTION("writerfilter","Set Formfield name failed");
+            }
+
+            sTmp = m_pFFData->getTextType();
+            if ( !sTmp.isEmpty() )
+                xNameCont->insertByName( "Type", uno::makeAny(sTmp) );
+
+            const sal_uInt16 nMaxLength = m_pFFData->getTextMaxLength();
+            if ( nMaxLength )
             {
-                xNamed->setName( m_pFFData->getName() );
+                xNameCont->insertByName( "MaxLength", uno::makeAny(nMaxLength) );
             }
+
+            sTmp = m_pFFData->getTextDefault();
+            if ( !sTmp.isEmpty() )
+                xNameCont->insertByName( "Content", uno::makeAny(sTmp) );
+
+            sTmp = m_pFFData->getTextFormat();
+            if ( !sTmp.isEmpty() )
+                xNameCont->insertByName( "Format", uno::makeAny(sTmp) );
         }
         else if (m_pImpl->m_eFieldId == FIELD_FORMCHECKBOX )
         {


More information about the Libreoffice-commits mailing list