sw/qa/extras/ooxmlexport/ooxmlexport12.cxx        |    2 
 sw/qa/extras/ooxmlexport/ooxmlexport9.cxx         |    2 
 sw/source/filter/ww8/wrtw8nds.cxx                 |   39 +++++-----
 writerfilter/source/dmapper/DomainMapper_Impl.cxx |   79 +++++++++++++---------
 4 files changed, 68 insertions(+), 54 deletions(-)

New commits:
commit 35b93ab6be79e5506248aea2f5b618db54e93c0f
Author:     Michael Stahl <michael.st...@cib.de>
AuthorDate: Mon Oct 14 18:17:24 2019 +0200
Commit:     Michael Stahl <michael.st...@cib.de>
CommitDate: Wed Oct 23 13:06:56 2019 +0200

    sw: remove checks for invalid document model wrt fieldmarks...
    
    ... in MSWordExportBase::OutputTextNode() - better crash so we can fix
    the bugs.
    
    Change-Id: I0d7b58bffa261c9c0c88b4245fcde38c776931f9
    Reviewed-on: https://gerrit.libreoffice.org/80919
    Tested-by: Jenkins
    Reviewed-by: Michael Stahl <michael.st...@cib.de>

diff --git a/sw/source/filter/ww8/wrtw8nds.cxx 
b/sw/source/filter/ww8/wrtw8nds.cxx
index 4ad6d3a721ec..aa70daf65738 100644
--- a/sw/source/filter/ww8/wrtw8nds.cxx
+++ b/sw/source/filter/ww8/wrtw8nds.cxx
@@ -118,10 +118,8 @@ using namespace ::oox::vml;
 
 static OUString lcl_getFieldCode( const IFieldmark* pFieldmark )
 {
-    OSL_ENSURE(pFieldmark!=nullptr, "where is my fieldmark???");
+    assert(pFieldmark);
 
-    if ( !pFieldmark)
-        return OUString();
     if ( pFieldmark->GetFieldname( ) == ODF_FORMTEXT )
         return " FORMTEXT ";
     if ( pFieldmark->GetFieldname( ) == ODF_FORMDROPDOWN )
@@ -139,10 +137,10 @@ static OUString lcl_getFieldCode( const IFieldmark* 
pFieldmark )
     return pFieldmark->GetFieldname();
 }
 
-static ww::eField lcl_getFieldId( const IFieldmark* pFieldmark ) {
-    OSL_ENSURE(pFieldmark!=nullptr, "where is my fieldmark???");
-    if ( !pFieldmark )
-        return ww::eUNKNOWN;
+static ww::eField lcl_getFieldId(const IFieldmark*const pFieldmark)
+{
+    assert(pFieldmark);
+
     if ( pFieldmark->GetFieldname( ) == ODF_FORMTEXT )
         return ww::eFORMTEXT;
     if ( pFieldmark->GetFieldname( ) == ODF_FORMDROPDOWN )
@@ -2335,10 +2333,10 @@ void MSWordExportBase::OutputTextNode( SwTextNode& 
rNode )
                 {
                     SwPosition aPosition( rNode, SwIndex( &rNode, nCurrentPos 
) );
                     ::sw::mark::IFieldmark const*const pFieldmark = 
pMarkAccess->getFieldmarkAt(aPosition);
-                    OSL_ENSURE( pFieldmark, "Looks like this doc is broken...; 
where is the Fieldmark for the FIELDSTART??" );
+                    assert(pFieldmark);
 
                     // Date field is exported as content control, not as a 
simple field
-                    if(pFieldmark && pFieldmark->GetFieldname( ) == 
ODF_FORMDATE)
+                    if (pFieldmark->GetFieldname() == ODF_FORMDATE)
                     {
                         if(GetExportFormat() == 
MSWordExportBase::ExportFormat::DOCX) // supported by DOCX only
                         {
@@ -2351,14 +2349,14 @@ void MSWordExportBase::OutputTextNode( SwTextNode& 
rNode )
                     else
                     {
 
-                        if ( pFieldmark && pFieldmark->GetFieldname() == 
ODF_FORMTEXT
+                        if (pFieldmark->GetFieldname() == ODF_FORMTEXT
                              && GetExportFormat() != 
MSWordExportBase::ExportFormat::DOCX )
                         {
                            AppendBookmark( pFieldmark->GetName() );
                         }
                         ww::eField eFieldId = lcl_getFieldId( pFieldmark );
                         OUString sCode = lcl_getFieldCode( pFieldmark );
-                        if ( pFieldmark && pFieldmark->GetFieldname() == 
ODF_UNHANDLED )
+                        if (pFieldmark->GetFieldname() == ODF_UNHANDLED )
                         {
                             IFieldmark::parameter_map_t::const_iterator it = 
pFieldmark->GetParameters()->find( ODF_ID_PARAM );
                             if ( it != pFieldmark->GetParameters()->end() )
@@ -2377,13 +2375,13 @@ void MSWordExportBase::OutputTextNode( SwTextNode& 
rNode )
 
                         OutputField( nullptr, eFieldId, sCode, 
FieldFlags::Start | FieldFlags::CmdStart );
 
-                        if ( pFieldmark && pFieldmark->GetFieldname( ) == 
ODF_FORMTEXT)
+                        if (pFieldmark->GetFieldname() == ODF_FORMTEXT)
                             WriteFormData( *pFieldmark );
-                        else if ( pFieldmark && pFieldmark->GetFieldname( ) == 
ODF_HYPERLINK )
+                        else if (pFieldmark->GetFieldname() == ODF_HYPERLINK)
                             WriteHyperlinkData( *pFieldmark );
                         OutputField( nullptr, lcl_getFieldId( pFieldmark ), 
OUString(), FieldFlags::CmdEnd );
 
-                        if ( pFieldmark && pFieldmark->GetFieldname() == 
ODF_UNHANDLED )
+                        if (pFieldmark->GetFieldname() == ODF_UNHANDLED)
                         {
                             // Check for the presence of a linked OLE object
                             IFieldmark::parameter_map_t::const_iterator it = 
pFieldmark->GetParameters()->find( ODF_OLE_PARAM );
@@ -2403,9 +2401,9 @@ void MSWordExportBase::OutputTextNode( SwTextNode& rNode )
                     SwPosition aPosition( rNode, SwIndex( &rNode, nCurrentPos 
) );
                     ::sw::mark::IFieldmark const*const pFieldmark = 
pMarkAccess->getFieldmarkAt(aPosition);
 
-                    OSL_ENSURE( pFieldmark, "Looks like this doc is broken...; 
where is the Fieldmark for the FIELDEND??" );
+                    assert(pFieldmark);
 
-                    if(pFieldmark && pFieldmark->GetFieldname( ) == 
ODF_FORMDATE)
+                    if (pFieldmark->GetFieldname() == ODF_FORMDATE)
                     {
                         if(GetExportFormat() == 
MSWordExportBase::ExportFormat::DOCX) // supported by DOCX only
                         {
@@ -2415,7 +2413,7 @@ void MSWordExportBase::OutputTextNode( SwTextNode& rNode )
                     else
                     {
                         ww::eField eFieldId = lcl_getFieldId( pFieldmark );
-                        if ( pFieldmark && pFieldmark->GetFieldname() == 
ODF_UNHANDLED )
+                        if (pFieldmark->GetFieldname() == ODF_UNHANDLED)
                         {
                             IFieldmark::parameter_map_t::const_iterator it = 
pFieldmark->GetParameters()->find( ODF_ID_PARAM );
                             if ( it != pFieldmark->GetParameters()->end() )
@@ -2428,7 +2426,7 @@ void MSWordExportBase::OutputTextNode( SwTextNode& rNode )
 
                         OutputField( nullptr, eFieldId, OUString(), 
FieldFlags::Close );
 
-                        if ( pFieldmark && pFieldmark->GetFieldname() == 
ODF_FORMTEXT
+                        if (pFieldmark->GetFieldname() == ODF_FORMTEXT
                              && GetExportFormat() != 
MSWordExportBase::ExportFormat::DOCX )
                         {
                             AppendBookmark( pFieldmark->GetName() );
@@ -2439,9 +2437,10 @@ void MSWordExportBase::OutputTextNode( SwTextNode& rNode 
)
                 {
                     SwPosition aPosition( rNode, SwIndex( &rNode, nCurrentPos 
) );
                     ::sw::mark::IFieldmark const*const pFieldmark = 
pMarkAccess->getFieldmarkAt(aPosition);
+                    assert(pFieldmark);
 
-                    bool isDropdownOrCheckbox = pFieldmark && 
(pFieldmark->GetFieldname( ) == ODF_FORMDROPDOWN ||
-                                                                
pFieldmark->GetFieldname( ) == ODF_FORMCHECKBOX );
+                    bool const isDropdownOrCheckbox(pFieldmark->GetFieldname() 
== ODF_FORMDROPDOWN ||
+                                                    pFieldmark->GetFieldname() 
== ODF_FORMCHECKBOX);
                     if ( isDropdownOrCheckbox )
                         AppendBookmark( pFieldmark->GetName() );
                     OutputField( nullptr, lcl_getFieldId( pFieldmark ),
commit e47615f1c1b17f66e5b30275e666bc7a7bf43d1c
Author:     Michael Stahl <michael.st...@cib.de>
AuthorDate: Tue Oct 15 18:17:00 2019 +0200
Commit:     Michael Stahl <michael.st...@cib.de>
CommitDate: Wed Oct 23 13:06:34 2019 +0200

    writerfilter: adapt the "real" fieldmark path in CloseFieldCommand()
    
    ... and PopFieldContext() to work the same as the generic fallback path,
    so that the CH_TXT_FIELDSEP is in the proper position, before the
    imported field result.
    
    Change-Id: Ic9b24dce43e7809a183b91cdc97c037f410cbaa8
    Reviewed-on: https://gerrit.libreoffice.org/80918
    Tested-by: Jenkins
    Reviewed-by: Michael Stahl <michael.st...@cib.de>

diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport12.cxx 
b/sw/qa/extras/ooxmlexport/ooxmlexport12.cxx
index c48efcb95cc0..b60c6cd571e6 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport12.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport12.cxx
@@ -678,7 +678,7 @@ DECLARE_OOXMLEXPORT_TEST(testTdf79435_legacyInputFields, 
"tdf79435_legacyInputFi
 {
     //using .doc input file to verify cross-format compatibility.
     uno::Reference<text::XFormField> xFormField
-        = 
getProperty<uno::Reference<text::XFormField>>(getRun(getParagraph(5), 3), 
"Bookmark");
+        = 
getProperty<uno::Reference<text::XFormField>>(getRun(getParagraph(5), 2), 
"Bookmark");
     uno::Reference<container::XNameContainer> 
xParameters(xFormField->getParameters());
 
     OUString sTmp;
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport9.cxx 
b/sw/qa/extras/ooxmlexport/ooxmlexport9.cxx
index 529932ade5f7..2dda95ca0bce 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport9.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport9.cxx
@@ -1142,7 +1142,7 @@ DECLARE_OOXMLEXPORT_TEST(testTdf111964, "tdf111964.docx")
         return;
     // Unicode spaces that are not XML whitespace must not be trimmed
     const sal_Unicode sWSReference [] { 0x2002, 0x2002, 0x2002, 0x2002, 
0x2002, 0 };
-    assertXPathContent(pXmlDoc, "/w:document/w:body/w:p/w:r[4]/w:t", 
sWSReference);
+    assertXPathContent(pXmlDoc, "/w:document/w:body/w:p/w:r[5]/w:t", 
sWSReference);
 }
 
 DECLARE_OOXMLEXPORT_TEST(testWatermark, "watermark-shapetype.docx")
diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.cxx 
b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
index b87e9af77970..f23775bc8731 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
@@ -4284,6 +4284,46 @@ void DomainMapper_Impl::handleIndex
     }
 }
 
+static auto InsertFieldmark(std::stack<TextAppendContext> & rTextAppendStack,
+        uno::Reference<text::XFormField> const& xFormField,
+        uno::Reference<text::XTextRange> const& xStartRange) -> void
+{
+    uno::Reference<text::XTextContent> const xTextContent(xFormField, 
uno::UNO_QUERY_THROW);
+    uno::Reference<text::XTextAppend> const& 
xTextAppend(rTextAppendStack.top().xTextAppend);
+    uno::Reference<text::XTextCursor> const xCursor =
+        xTextAppend->createTextCursorByRange(xStartRange);
+    if (rTextAppendStack.top().xInsertPosition.is())
+    {
+        xCursor->gotoRange(rTextAppendStack.top().xInsertPosition, true);
+    }
+    else
+    {
+        xCursor->gotoEnd(true);
+    }
+    xTextAppend->insertTextContent(xCursor, xTextContent, true);
+    // problem: the fieldmark must be inserted in CloseFieldCommand(), because
+    //          attach() takes 2 positions, not 3!
+    // FAIL: AppendTextNode() ignores the content index!
+    // plan B: insert a spurious paragraph break now and join
+    //         it in PopFieldContext()!
+    xCursor->gotoRange(xTextContent->getAnchor()->getEnd(), false);
+    xCursor->goLeft(1, false); // skip CH_TXT_ATR_FIELDEND
+    xTextAppend->insertControlCharacter(xCursor, 
text::ControlCharacter::PARAGRAPH_BREAK, false);
+    xCursor->goLeft(1, false); // back to previous paragraph
+    rTextAppendStack.push(TextAppendContext(xTextAppend, xCursor));
+}
+
+static auto PopFieldmark(std::stack<TextAppendContext> & rTextAppendStack,
+        uno::Reference<text::XTextCursor> const& xCursor) -> void
+{
+    xCursor->gotoRange(rTextAppendStack.top().xInsertPosition, false);
+    xCursor->goRight(1, true);
+    xCursor->setString(OUString()); // undo SplitNode from CloseFieldCommand()
+    // note: paragraph properties will be overwritten
+    // by finishParagraph() anyway so ignore here
+    rTextAppendStack.pop();
+}
+
 void DomainMapper_Impl::CloseFieldCommand()
 {
     if(m_bDiscardHeaderFooter)
@@ -4562,6 +4602,8 @@ void DomainMapper_Impl::CloseFieldCommand()
                                         xNamed->setName(  
pFFDataHandler->getName() );
                                     pContext->SetFormField( xFormField );
                                 }
+                                InsertFieldmark(m_aTextAppendStack,
+                                    xFormField, pContext->GetStartRange());
                             }
                             else
                             {
@@ -5029,30 +5071,9 @@ void DomainMapper_Impl::CloseFieldCommand()
                 if (std::get<0>(field) != "SHAPE" && m_xTextFactory.is() && 
!m_aTextAppendStack.empty())
                 {
                     xFieldInterface = 
m_xTextFactory->createInstance("com.sun.star.text.Fieldmark");
-                    const uno::Reference<text::XTextContent> 
xTextContent(xFieldInterface, uno::UNO_QUERY_THROW);
-                    uno::Reference< text::XTextAppend > xTextAppend = 
m_aTextAppendStack.top().xTextAppend;
-                    uno::Reference< text::XTextCursor > xCrsr = 
xTextAppend->createTextCursorByRange(pContext->GetStartRange());
-                    if (m_aTextAppendStack.top().xInsertPosition.is())
-                    {
-                        
xCrsr->gotoRange(m_aTextAppendStack.top().xInsertPosition, true);
-                    }
-                    else
-                    {
-                        xCrsr->gotoEnd(true);
-                    }
-                    xTextAppend->insertTextContent(xCrsr, xTextContent, true);
-                    // problem: the fieldmark must be inserted here, because
-                    //          attach() takes 2 positions, not 3!
-                    // FAIL: AppendTextNode() ignores the content index!
-                    // plan B: insert a spurious paragraph break now and join
-                    //         it in PopFieldContext()!
-                    xCrsr->gotoRange(xTextContent->getAnchor()->getEnd(), 
false);
-                    xCrsr->goLeft(1, false); // skip CH_TXT_ATR_FIELDEND
-                    xTextAppend->insertControlCharacter(xCrsr, 
text::ControlCharacter::PARAGRAPH_BREAK, false);
-                    xCrsr->goLeft(1, false); // back to previous paragraph
-                    m_aTextAppendStack.push(TextAppendContext(xTextAppend, 
xCrsr));
-
-                    uno::Reference<text::XFormField> xFormField(xTextContent, 
uno::UNO_QUERY);
+
+                    uno::Reference<text::XFormField> const 
xFormField(xFieldInterface, uno::UNO_QUERY);
+                    InsertFieldmark(m_aTextAppendStack, xFormField, 
pContext->GetStartRange());
                     xFormField->setFieldType(aCode);
                     m_bStartGenericField = true;
                     pContext->SetFormField( xFormField );
@@ -5361,8 +5382,7 @@ void DomainMapper_Impl::PopFieldContext()
                             xToInsert.set(xFormField, uno::UNO_QUERY);
                             if ( xFormField.is() && xToInsert.is() )
                             {
-                                xCrsr->gotoEnd( true );
-                                xToInsert->attach( uno::Reference< 
text::XTextRange >( xCrsr, uno::UNO_QUERY_THROW ));
+                                PopFieldmark(m_aTextAppendStack, xCrsr);
                                 pFormControlHelper->processField( xFormField );
                             }
                             else
@@ -5414,12 +5434,7 @@ void DomainMapper_Impl::PopFieldContext()
                         else if(m_bStartGenericField)
                         {
                             m_bStartGenericField = false;
-                            
xCrsr->gotoRange(m_aTextAppendStack.top().xInsertPosition, false);
-                            xCrsr->goRight(1, true);
-                            xCrsr->setString(OUString()); // undo SplitNode 
from CloseFieldCommand()
-                            // note: paragraph properties will be overwritten
-                            // by finishParagraph() anyway so ignore here
-                            m_aTextAppendStack.pop();
+                            PopFieldmark(m_aTextAppendStack, xCrsr);
                             if(m_bTextInserted)
                             {
                                 m_bTextInserted = false;
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to