sw/qa/uibase/shells/shells.cxx      |   32 ++++++++---------------------
 sw/source/uibase/shells/textfld.cxx |   39 +++++++++++++++++++++++++++++++++---
 2 files changed, 45 insertions(+), 26 deletions(-)

New commits:
commit d576aa0a1ba17680f9cb49b23a124eacbe6bb591
Author:     Miklos Vajna <vmik...@collabora.com>
AuthorDate: Wed Nov 16 12:10:30 2022 +0100
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Thu Nov 17 11:17:47 2022 +0100

    sw, .uno:TextFormField command: accept HTML in the FieldResult parameter
    
    - improve the calculation of the SwPaM that decides the start/end of the
      fieldmark: with HTML import the length of the content is not the
      length of the input string anymore
    
    - use SwTranslateHelper::PasteHTMLToPaM() to accept formatted content
      inside a single paragraph
    
    - avoid unwanted last empty paragraph from the HTML import
    
    - this builds on top of commit 6870c0c3385bf5d19e9c80bf973fca255ae38c08
      (sw: add new FieldCode parameter for the .uno:TextFormField command,
      2022-11-15), which introduced plain text support for FieldResult
    
    (cherry picked from commit 1c2ef850db29beb369dcc89a58fc73416ecd9c5c)
    
    Conflicts:
            sw/qa/uibase/shells/shells.cxx
            sw/source/uibase/shells/textfld.cxx
    
    Change-Id: I8332f6ee532ab1e844a4b94f22b1f72d2406eb3a
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/142824
    Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com>
    Reviewed-by: Miklos Vajna <vmik...@collabora.com>

diff --git a/sw/qa/uibase/shells/shells.cxx b/sw/qa/uibase/shells/shells.cxx
index 153b8fc5b479..5a7b2ca8d42c 100644
--- a/sw/qa/uibase/shells/shells.cxx
+++ b/sw/qa/uibase/shells/shells.cxx
@@ -241,25 +241,6 @@ CPPUNIT_TEST_FIXTURE(SwUibaseShellsTest, 
testContentControlPageBreak)
     CPPUNIT_ASSERT_EQUAL(1, getPages());
 }
 
-namespace
-{
-// sw::mark::TextFieldmark::GetContent() on master.
-OUString TextFieldmarkGetContent(sw::mark::IFieldmark* pFieldmark)
-{
-    const SwTextNode& rTextNode = 
*pFieldmark->GetMarkEnd().nNode.GetNode().GetTextNode();
-    SwPosition const sepPos(sw::mark::FindFieldSep(*pFieldmark));
-    const sal_Int32 nStart(sepPos.nContent.GetIndex());
-    const sal_Int32 nEnd(pFieldmark->GetMarkEnd().nContent.GetIndex());
-
-    OUString sContent;
-    const sal_Int32 nLen = rTextNode.GetText().getLength();
-    if (nStart + 1 < nLen && nEnd <= nLen && nEnd > nStart + 2)
-        sContent = rTextNode.GetText().copy(nStart + 1, nEnd - nStart - 2);
-
-    return sContent;
-}
-}
-
 CPPUNIT_TEST_FIXTURE(SwUibaseShellsTest, testInsertTextFormField)
 {
     // Given an empty document:
@@ -267,11 +248,10 @@ CPPUNIT_TEST_FIXTURE(SwUibaseShellsTest, 
testInsertTextFormField)
 
     // When inserting an ODF_UNHANDLED fieldmark:
     OUString aExpectedCommand("ADDIN ZOTERO_BIBL foo bar");
-    OUString aExpectedResult("(Abrikosov, n.d.)");
     uno::Sequence<css::beans::PropertyValue> aArgs = {
         comphelper::makePropertyValue("FieldType", 
uno::Any(OUString(ODF_UNHANDLED))),
         comphelper::makePropertyValue("FieldCommand", 
uno::Any(aExpectedCommand)),
-        comphelper::makePropertyValue("FieldResult", 
uno::Any(aExpectedResult)),
+        comphelper::makePropertyValue("FieldResult", 
uno::Any(OUString("<p>aaa</p><p>bbb</p>"))),
     };
     dispatchCommand(mxComponent, ".uno:TextFormField", aArgs);
 
@@ -294,8 +274,14 @@ CPPUNIT_TEST_FIXTURE(SwUibaseShellsTest, 
testInsertTextFormField)
     it->second >>= aActualCommand;
     CPPUNIT_ASSERT_EQUAL(aExpectedCommand, aActualCommand);
 
-    OUString aActualResult = TextFieldmarkGetContent(pFieldmark);
-    CPPUNIT_ASSERT_EQUAL(aExpectedResult, aActualResult);
+    SwPaM aPam(pFieldmark->GetMarkStart(), pFieldmark->GetMarkEnd());
+    // Ignore the leading field start + sep.
+    aPam.GetMark()->nContent = aPam.GetMark()->nContent.GetIndex() + 2;
+    // Ignore the trailing field end.
+    aPam.GetPoint()->nContent = aPam.GetPoint()->nContent.GetIndex() - 1;
+    CPPUNIT_ASSERT(aPam.HasMark());
+    OUString aActualResult = aPam.GetText();
+    CPPUNIT_ASSERT_EQUAL(OUString("aaa\nbbb"), aActualResult);
 }
 
 CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/sw/source/uibase/shells/textfld.cxx 
b/sw/source/uibase/shells/textfld.cxx
index 2f3c62512171..a3690619122d 100644
--- a/sw/source/uibase/shells/textfld.cxx
+++ b/sw/source/uibase/shells/textfld.cxx
@@ -63,6 +63,7 @@
 #include <IMark.hxx>
 #include <officecfg/Office/Compatibility.hxx>
 #include <ndtxt.hxx>
+#include <translatehelper.hxx>
 
 
 using namespace nsSwDocInfoSubType;
@@ -703,6 +704,9 @@ FIELD_INSERT:
             }
 
             
rSh.GetDoc()->GetIDocumentUndoRedo().StartUndo(SwUndoId::INSERT_FORM_FIELD, 
nullptr);
+            // Don't update the layout after inserting content and before 
deleting temporary
+            // text nodes.
+            rSh.StartAction();
 
             SwPaM* pCursorPos = rSh.GetCursor();
             if(pCursorPos)
@@ -717,12 +721,40 @@ FIELD_INSERT:
                     aFieldResult = pFieldResult->GetValue();
                 }
 
-                bool bSuccess = 
rSh.GetDoc()->getIDocumentContentOperations().InsertString(*pCursorPos, 
aFieldResult);
+                // Split node to remember where the start position is.
+                bool bSuccess = 
rSh.GetDoc()->getIDocumentContentOperations().SplitNode(
+                    *pCursorPos->GetPoint(), false);
                 if(bSuccess)
                 {
+                    SwPaM aFieldPam(*pCursorPos->GetPoint());
+                    aFieldPam.Move(fnMoveBackward, GoInContent);
+                    if (pFieldResult)
+                    {
+                        // Paste HTML content.
+                        SwTranslateHelper::PasteHTMLToPaM(rSh, pCursorPos, 
aFieldResult.toUtf8(),
+                                                          true);
+                        if (pCursorPos->GetPoint()->nContent.GetIndex() == 0)
+                        {
+                            // The paste created a last empty text node, 
remove it.
+                            SwPaM aPam(*pCursorPos->GetPoint());
+                            aPam.SetMark();
+                            aPam.Move(fnMoveBackward, GoInContent);
+                            
rSh.GetDoc()->getIDocumentContentOperations().DeleteAndJoin(aPam);
+                        }
+                    }
+                    else
+                    {
+                        // Insert default placeholder.
+                        
rSh.GetDoc()->getIDocumentContentOperations().InsertString(*pCursorPos,
+                                                                               
    aFieldResult);
+                    }
+                    // Undo the above SplitNode().
+                    aFieldPam.SetMark();
+                    aFieldPam.Move(fnMoveForward, GoInContent);
+                    
rSh.GetDoc()->getIDocumentContentOperations().DeleteAndJoin(aFieldPam);
+                    *aFieldPam.GetMark() = *pCursorPos->GetPoint();
+
                     IDocumentMarkAccess* pMarksAccess = 
rSh.GetDoc()->getIDocumentMarkAccess();
-                    SwPaM aFieldPam(pCursorPos->GetPoint()->nNode, 
pCursorPos->GetPoint()->nContent.GetIndex() - aFieldResult.getLength(),
-                                    pCursorPos->GetPoint()->nNode, 
pCursorPos->GetPoint()->nContent.GetIndex());
                     sw::mark::IFieldmark* pFieldmark = 
pMarksAccess->makeFieldBookmark(
                         aFieldPam, OUString(), aFieldType, aFieldPam.Start());
                     if (pFieldmark && !aFieldCode.isEmpty())
@@ -733,6 +765,7 @@ FIELD_INSERT:
                 }
             }
 
+            rSh.EndAction();
             
rSh.GetDoc()->GetIDocumentUndoRedo().EndUndo(SwUndoId::INSERT_FORM_FIELD, 
nullptr);
             rSh.GetView().GetViewFrame()->GetBindings().Invalidate( SID_UNDO );
         }

Reply via email to