sw/qa/extras/rtfexport/data/FORMDROPDOWN.rtf      |   33 ++++++++++++
 sw/qa/extras/rtfexport/rtfexport4.cxx             |   21 +++++++
 sw/source/filter/ww8/rtfexport.cxx                |   58 +++++++++++++++++++++-
 writerfilter/source/dmapper/FormControlHelper.cxx |    5 +
 writerfilter/source/rtftok/rtfdocumentimpl.cxx    |    4 +
 5 files changed, 117 insertions(+), 4 deletions(-)

New commits:
commit 47b08551a77918e4d35a98197ac99c1c3d5dec73
Author:     Michael Stahl <michael.st...@allotropia.de>
AuthorDate: Fri Aug 5 12:57:57 2022 +0200
Commit:     Michael Stahl <michael.st...@allotropia.de>
CommitDate: Mon Aug 8 15:50:08 2022 +0200

    tdf#148518 writerfilter,sw: RTF import/export of FORMDROPDOWN field
    
    On import, the values overwrote each other; export of the form data
    was missing completely.
    
    Change-Id: I918b3cfced39dc2602c6de03cdaf5848a9825dd2
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/137861
    Tested-by: Jenkins
    Reviewed-by: Michael Stahl <michael.st...@allotropia.de>

diff --git a/sw/qa/extras/rtfexport/data/FORMDROPDOWN.rtf 
b/sw/qa/extras/rtfexport/data/FORMDROPDOWN.rtf
new file mode 100644
index 000000000000..ef1d3af744db
--- /dev/null
+++ b/sw/qa/extras/rtfexport/data/FORMDROPDOWN.rtf
@@ -0,0 +1,33 @@
+{\rtf1\adeflang1025\ansi\ansicpg1250\uc1\adeff0\deff0\stshfdbch0\stshfloch0\stshfhich0\stshfbi0\deflang1038\deflangfe1038\themelang1031\themelangfe0\themelangcs0{\fonttbl{\f0\fbidi
 \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New 
Roman;}{\f0\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times 
New Roman;}
+}{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0;
+\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;
+\red192\green192\blue192;}{\*\defchp \fs22 }{\*\defpap \ql 
\li0\ri0\sa200\sl276\slmult1\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0
 }\noqfpromote {\stylesheet{
+\ql 
\li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0
 \rtlch\fcs1 \af0\afs24\alang1025 \ltrch\fcs0 
\fs24\lang3079\langfe3079\cgrid\langnp3079\langfenp3079 \snext0 \sqformat 
\spriority0 Normal;}{\*\cs10 \additive 
+\ssemihidden Default Paragraph 
Font;}{\*\ts11\tsrowd\trftsWidthB3\trpaddl108\trpaddr108\trpaddfl3\trpaddft3\trpaddfb3\trpaddfr3\trcbpat1\trcfpat1\tblind0\tblindtype3\tsvertalt\tsbrdrt\tsbrdrl\tsbrdrb\tsbrdrr\tsbrdrdgl\tsbrdrdgr\tsbrdrh\tsbrdrv
 
+\ql 
\li0\ri0\sa200\sl276\slmult1\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0
 \rtlch\fcs1 \af0\afs22\alang1025 \ltrch\fcs0 
\fs22\lang1038\langfe1038\cgrid\langnp1038\langfenp1038 \snext11 \ssemihidden 
\sunhideused 
+Normal Table;}{\*\ts15\tsrowd\trbrdrt\brdrs\brdrw10 \trbrdrl\brdrs\brdrw10 
\trbrdrb\brdrs\brdrw10 \trbrdrr\brdrs\brdrw10 \trbrdrh\brdrs\brdrw10 
\trbrdrv\brdrs\brdrw10 
+\trftsWidthB3\trpaddl108\trpaddr108\trpaddfl3\trpaddft3\trpaddfb3\trpaddfr3\trcbpat1\trcfpat1\tblind0\tblindtype3\tsvertalt\tsbrdrt\tsbrdrl\tsbrdrb\tsbrdrr\tsbrdrdgl\tsbrdrdgr\tsbrdrh\tsbrdrv
 
+\ql 
\li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0
 \rtlch\fcs1 \af0\afs20\alang1025 \ltrch\fcs0 
\fs20\lang1031\langfe1031\cgrid\langnp1031\langfenp1031 \sbasedon11 \snext15 
\styrsid6366418 Table Grid;}{
+\s16\ql 
\li0\ri0\widctlpar\tqc\tx4513\tqr\tx9026\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0
 \rtlch\fcs1 \af0\afs24\alang1025 \ltrch\fcs0 
\fs24\lang3079\langfe3079\cgrid\langnp3079\langfenp3079 
+\sbasedon0 \snext16 \slink17 \styrsid14450383 header;}{\*\cs17 \additive 
\rtlch\fcs1 \af0\afs24 \ltrch\fcs0 
\fs24\lang3079\langfe3079\langnp3079\langfenp3079 \sbasedon10 \slink16 \slocked 
\styrsid14450383 Header Char;}{\s18\ql \li0\ri0\widctlpar
+\tqc\tx4513\tqr\tx9026\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0
 \rtlch\fcs1 \af0\afs24\alang1025 \ltrch\fcs0 
\fs24\lang3079\langfe3079\cgrid\langnp3079\langfenp3079 \sbasedon0 \snext18 
\slink19 \styrsid14450383 footer;}{\*\cs19 
+\additive \rtlch\fcs1 \af0\afs24 \ltrch\fcs0 
\fs24\lang3079\langfe3079\langnp3079\langfenp3079 \sbasedon10 \slink18 \slocked 
\styrsid14450383 Footer Char;}}{\*\rsidtbl 
\rsid1922796\rsid2437734\rsid4346699\rsid4392934\rsid5467240\rsid5720824\rsid6366418
+\rsid6843717\rsid7742502\rsid7807608\rsid7872863\rsid7957046\rsid8722154\rsid8811273\rsid9708480\rsid9904672\rsid10167906\rsid11299441\rsid12799272\rsid13922319\rsid14183170\rsid14450383\rsid14632381\rsid14900426\rsid15207980\rsid15864162\rsid16002556
+\rsid16275940}{\mmathPr\mmathFont34\mbrkBin0\mbrkBinSub0\msmallFrac0\mdispDef1\mlMargin0\mrMargin0\mdefJc1\mwrapIndent1440\mintLim0\mnaryLim1}{\info{\creatim\yr2022\mo4\dy6\hr15\min54}{\revtim\yr2022\mo4\dy6\hr15\min59}{\version1}{\edmins0}{\nofpages1}
+{\nofwords7}{\nofchars56}{\nofcharsws62}{\vern57453}}
+\paperw11906\paperh16838\margl1417\margr1417\margt1417\margb1134\gutter0\ltrsect
+\deftab708\widowctrl\ftnbj\aenddoc\hyphhotz425\trackmoves0\trackformatting1\donotembedsysfont1\relyonvml0\donotembedlingdata0\grfdocevents0\validatexml1\showplaceholdtext0\ignoremixedcontent0\saveinvalidxml0
+\showxmlerrors1\noxlattoyen\expshrtn\noultrlspc\dntblnsbdb\nospaceforul\formshade\horzdoc\dgmargin\dghspace180\dgvspace180\dghorigin1417\dgvorigin1417\dghshow1\dgvshow1
+\jexpand\viewkind1\viewscale100\pgbrdrhead\pgbrdrfoot\splytwnine\ftnlytwnine\nolnhtadjtbl\useltbaln\alntblind\lytcalctblwd\lyttblrtgr\lnbrkrule\nobrkwrptbl\snaptogridincell\rempersonalinfo\allowfieldendsel
+\wrppunct\asianbrkrule\rsidroot13922319\newtblstyruls\nogrowautofit\remdttm 
\fet0{\*\wgrffmtfilter 013f}\ilfomacatclnup0
+\ltrpar \sectd 
\ltrsect\linex0\headery708\footery708\colsx708\endnhere\sectlinegrid360\sectdefaultcl\sftnbj
+\pard\plain \ltrpar\ql 
\li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid6366418
 
+\rtlch\fcs1 \af0\afs24\alang1025 \ltrch\fcs0 
\fs24\lang3079\langfe3079\cgrid\langnp3079\langfenp3079 \sectd \ltrsect
+\linex0\headery708\footery708\colsx708\endnhere\sectlinegrid360\sectdefaultcl\sftnbj
+{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid10167906 
+\par }{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid7872863 {\*\bkmkstart 
Dropdown1}Dropdown list}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid10167906 : 
}{\field\fldpriv{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid10167906  
FORMDROPDOWN }{\rtlch\fcs1 \af0 \ltrch\fcs0 
+\insrsid10167906 {\*\datafield 
66800000000000000944726f70646f776e31000000000000000000000000000c000300030000000a00060008000a00017801760164}{\*\formfield{\fftype2\ffres1\fftypetxt0\ffhaslistbox{\*\ffname
 Dropdown1}\ffdefres0{\*\ffl x}{\*\ffl v}{\*\ffl d}}}
+}}{\fldrslt }}\sectd 
\ltrsect\linex0\headery708\footery708\colsx708\endnhere\sectlinegrid360\sectdefaultcl\sftnbj
 {\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid10167906 {\*\bkmkend Dropdown1}
+\par 
+\par }
+}
diff --git a/sw/qa/extras/rtfexport/rtfexport4.cxx 
b/sw/qa/extras/rtfexport/rtfexport4.cxx
index 367b75ac34d8..f730afd93c25 100644
--- a/sw/qa/extras/rtfexport/rtfexport4.cxx
+++ b/sw/qa/extras/rtfexport/rtfexport4.cxx
@@ -19,6 +19,8 @@
 #include <com/sun/star/text/XTextTable.hpp>
 #include <o3tl/cppunittraitshelper.hxx>
 
+#include <xmloff/odffields.hxx>
+
 #include <docsh.hxx>
 #include <unotxdoc.hxx>
 #include <pam.hxx>
@@ -96,6 +98,25 @@ DECLARE_RTFEXPORT_TEST(testCjklist31, "cjklist31.rtf")
     CPPUNIT_ASSERT_EQUAL(style::NumberingType::DI_ZI_ZH, numFormat);
 }
 
+DECLARE_RTFEXPORT_TEST(test148518, "FORMDROPDOWN.rtf")
+{
+    SwXTextDocument* const 
pTextDoc(dynamic_cast<SwXTextDocument*>(mxComponent.get()));
+    CPPUNIT_ASSERT(pTextDoc);
+    SwDoc* const pDoc(pTextDoc->GetDocShell()->GetDoc());
+
+    CPPUNIT_ASSERT(pDoc->getIDocumentMarkAccess()->getFieldmarksBegin()
+                   != pDoc->getIDocumentMarkAccess()->getFieldmarksEnd());
+    ::sw::mark::IFieldmark* pFieldmark = dynamic_cast<::sw::mark::IFieldmark*>(
+        *pDoc->getIDocumentMarkAccess()->getFieldmarksBegin());
+    uno::Sequence<OUString> entries;
+    (*pFieldmark->GetParameters())[ODF_FORMDROPDOWN_LISTENTRY] >>= entries;
+    uno::Sequence<OUString> const expected{ OUString("x"), OUString("v"), 
OUString("d") };
+    CPPUNIT_ASSERT_EQUAL(expected, entries);
+    sal_Int32 result(-1);
+    (*pFieldmark->GetParameters())[ODF_FORMDROPDOWN_RESULT] >>= result;
+    CPPUNIT_ASSERT_EQUAL(sal_Int32(1), result);
+}
+
 DECLARE_RTFEXPORT_TEST(testAnchoredAtSamePosition, "anchor.fodt")
 {
     SwXTextDocument* const pTextDoc = 
dynamic_cast<SwXTextDocument*>(mxComponent.get());
diff --git a/sw/source/filter/ww8/rtfexport.cxx 
b/sw/source/filter/ww8/rtfexport.cxx
index f51ea6f62182..7a0dee9c743b 100644
--- a/sw/source/filter/ww8/rtfexport.cxx
+++ b/sw/source/filter/ww8/rtfexport.cxx
@@ -55,6 +55,7 @@
 #include <svtools/rtfkeywd.hxx>
 #include <filter/msfilter/rtfutil.hxx>
 #include <unotools/docinfohelper.hxx>
+#include <xmloff/odffields.hxx>
 #include <o3tl/string_view.hxx>
 #include <osl/diagnose.h>
 #include <rtl/tencinfo.h>
@@ -318,9 +319,62 @@ void RtfExport::OutputField(const SwField* pField, 
ww::eField eFieldType, const
     m_pAttrOutput->WriteField_Impl(pField, eFieldType, rFieldCmd, nMode);
 }
 
-void RtfExport::WriteFormData(const ::sw::mark::IFieldmark& /*rFieldmark*/)
+void RtfExport::WriteFormData(const ::sw::mark::IFieldmark& rFieldmark)
 {
-    SAL_INFO("sw.rtf", "TODO: " << __func__);
+    sal_Int32 nType;
+    if (rFieldmark.GetFieldname() == ODF_FORMDROPDOWN)
+    {
+        nType = 2;
+    }
+    /* TODO
+    else if (rFieldmark.GetFieldname() == ODF_FORMCHECKBOX)
+    {
+        nType = 1;
+    }
+    else if (rFieldmark.GetFieldname() == ODF_FORMTEXT)
+    {
+        nType = 0;
+    }
+*/
+    else
+    {
+        SAL_INFO("sw.rtf", "unknown field type");
+        return;
+    }
+    m_pAttrOutput->RunText().append(
+        "{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_FORMFIELD
+        "{" OOO_STRING_SVTOOLS_RTF_FFTYPE);
+    m_pAttrOutput->RunText().append(nType);
+    if (rFieldmark.GetFieldname() == ODF_FORMDROPDOWN)
+    {
+        m_pAttrOutput->RunText().append(OOO_STRING_SVTOOLS_RTF_FFHASLISTBOX 
"1");
+        uno::Sequence<OUString> entries;
+        if (auto const it = 
rFieldmark.GetParameters()->find(ODF_FORMDROPDOWN_LISTENTRY);
+            it != rFieldmark.GetParameters()->end())
+        {
+            it->second >>= entries;
+        }
+        if (auto const it = 
rFieldmark.GetParameters()->find(ODF_FORMDROPDOWN_RESULT);
+            it != rFieldmark.GetParameters()->end())
+        {
+            sal_Int32 result(-1);
+            it->second >>= result;
+            if (0 <= result && result < entries.getLength())
+            {
+                m_pAttrOutput->RunText().append(OOO_STRING_SVTOOLS_RTF_FFRES);
+                m_pAttrOutput->RunText().append(result);
+            }
+        }
+        for (OUString const& rEntry : entries)
+        {
+            m_pAttrOutput->RunText().append(
+                "{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_FFL " 
");
+            m_pAttrOutput->RunText().append(
+                msfilter::rtfutil::OutString(rEntry, m_eDefaultEncoding));
+            m_pAttrOutput->RunText().append("}");
+        }
+    }
+    m_pAttrOutput->RunText().append("}}"); // close FORMFIELD destination
 }
 
 void RtfExport::WriteHyperlinkData(const ::sw::mark::IFieldmark& 
/*rFieldmark*/)
diff --git a/writerfilter/source/dmapper/FormControlHelper.cxx 
b/writerfilter/source/dmapper/FormControlHelper.cxx
index 4e2cd3ecd50a..6e51543abad2 100644
--- a/writerfilter/source/dmapper/FormControlHelper.cxx
+++ b/writerfilter/source/dmapper/FormControlHelper.cxx
@@ -34,6 +34,8 @@
 #include <com/sun/star/text/VertOrientation.hpp>
 #include <com/sun/star/uno/Any.hxx>
 
+#include <o3tl/safeint.hxx>
+
 #include "FormControlHelper.hxx"
 #include <utility>
 #include <xmloff/odffields.hxx>
@@ -286,7 +288,8 @@ void 
FormControlHelper::processField(uno::Reference<text::XFormField> const& xFo
                 xNameCont->insertByName(ODF_FORMDROPDOWN_LISTENTRY, 
uno::Any(comphelper::containerToSequence(rEntries)));
 
             sal_Int32 nResult = m_pFFData->getDropDownResult().toInt32();
-            if ( nResult )
+            // 0 is valid, but also how toInt32 reports parse error, but it's 
a sensible default...
+            if (0 <= nResult && o3tl::make_unsigned(nResult) < rEntries.size())
             {
                 if ( xNameCont->hasByName(ODF_FORMDROPDOWN_RESULT) )
                     xNameCont->replaceByName(ODF_FORMDROPDOWN_RESULT, 
uno::Any( nResult ) );
diff --git a/writerfilter/source/rtftok/rtfdocumentimpl.cxx 
b/writerfilter/source/rtftok/rtfdocumentimpl.cxx
index 71e25f4571f8..840a6bb5bdef 100644
--- a/writerfilter/source/rtftok/rtfdocumentimpl.cxx
+++ b/writerfilter/source/rtftok/rtfdocumentimpl.cxx
@@ -2545,7 +2545,9 @@ RTFError RTFDocumentImpl::beforePopState(RTFParserState& 
rState)
                 break; // not for nested group
             auto pValue
                 = new 
RTFValue(m_aStates.top().getCurrentDestinationText()->makeStringAndClear());
-            m_aFormfieldSprms.set(NS_ooxml::LN_CT_FFDDList_listEntry, pValue);
+            // OOXML puts these into a LN_CT_FFData_ddList but FFDataHandler 
should handle this too
+            m_aFormfieldSprms.set(NS_ooxml::LN_CT_FFDDList_listEntry, pValue,
+                                  RTFOverwrite::NO_APPEND);
         }
         break;
         case Destination::DATAFIELD:

Reply via email to