sw/qa/uibase/shells/shells.cxx      |   41 ++++++++++++++++++++++++++++++++++++
 sw/source/uibase/shells/textfld.cxx |   16 ++++++++++----
 2 files changed, 53 insertions(+), 4 deletions(-)

New commits:
commit 43d80906c8693ca27c5b3077fbaa259df4004924
Author:     Miklos Vajna <vmik...@collabora.com>
AuthorDate: Tue Jan 17 11:38:14 2023 +0100
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Tue Jan 17 13:43:36 2023 +0000

    sw: .uno:TextFormField: handle Endnote as a value for the Wrapper parameter
    
    This is similar to the fieldmark-in-footnote case, but here we need to
    make sure that the layout is calculated before the cursor attempts to
    jump to the endnote, otherwise the fieldmark will be inserted before the
    endnote anchor, not in the endnote body.
    
    The move of StartAction() / EndAction() calls can be done
    unconditionally, it's not a problem for the existing footnote case.
    
    Change-Id: I772d27937456978ca6aa01148eff3163d8877208
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/145660
    Reviewed-by: Miklos Vajna <vmik...@collabora.com>
    Tested-by: Jenkins

diff --git a/sw/qa/uibase/shells/shells.cxx b/sw/qa/uibase/shells/shells.cxx
index 6dfc6ed6e9da..8dd312ad69d9 100644
--- a/sw/qa/uibase/shells/shells.cxx
+++ b/sw/qa/uibase/shells/shells.cxx
@@ -40,6 +40,7 @@
 #include <docsh.hxx>
 #include <ndtxt.hxx>
 #include <ftnidx.hxx>
+#include <txtftn.hxx>
 
 /// Covers sw/source/uibase/shells/ fixes.
 class SwUibaseShellsTest : public SwModelTestBase
@@ -961,6 +962,46 @@ CPPUNIT_TEST_FIXTURE(SwUibaseShellsTest, 
testInsertTextFormFieldFootnote)
     CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), rFootnotes.size());
 }
 
+CPPUNIT_TEST_FIXTURE(SwUibaseShellsTest, testInsertTextFormFieldEndnote)
+{
+    // Given an empty document:
+    createSwDoc();
+    SwDoc* pDoc = getSwDoc();
+
+    // When inserting an ODF_UNHANDLED fieldmark inside an endnote:
+    uno::Sequence<css::beans::PropertyValue> aArgs = {
+        comphelper::makePropertyValue("FieldType", 
uno::Any(OUString(ODF_UNHANDLED))),
+        comphelper::makePropertyValue("FieldCommand",
+                                      uno::Any(OUString("ADDIN ZOTERO_BIBL foo 
bar"))),
+        comphelper::makePropertyValue("FieldResult", 
uno::Any(OUString("result"))),
+        comphelper::makePropertyValue("Wrapper", 
uno::Any(OUString("Endnote"))),
+    };
+    dispatchCommand(mxComponent, ".uno:TextFormField", aArgs);
+
+    // Then make sure that the endnote is created:
+    SwFootnoteIdxs& rFootnotes = pDoc->GetFootnoteIdxs();
+    // Without the accompanying fix in place, this test would have failed with:
+    // - Expected: 1
+    // - Actual  : 0
+    // i.e. no endnote was inserted.
+    CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), rFootnotes.size());
+    SwTextFootnote* pEndnote = rFootnotes[0];
+    const SwFormatFootnote& rFormatEndnote = pEndnote->GetFootnote();
+    CPPUNIT_ASSERT(rFormatEndnote.IsEndNote());
+    // Also check that the endnote body contains the fieldmark:
+    SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
+    pWrtShell->SttEndDoc(/*bStt=*/true);
+    pWrtShell->GotoFootnoteText();
+    pWrtShell->EndOfSection(/*bSelect=*/true);
+    SwCursor* pCursor = pWrtShell->GetCursor();
+    OUString aActual = pCursor->GetText();
+    static sal_Unicode const aForbidden[]
+        = { CH_TXT_ATR_FIELDSTART, CH_TXT_ATR_FIELDSEP, CH_TXT_ATR_FIELDEND, 0 
};
+    aActual = comphelper::string::removeAny(aActual, aForbidden);
+    // Then this was empty: the fieldmark was inserted before the note anchor, 
not in the note body.
+    CPPUNIT_ASSERT_EQUAL(OUString("result"), aActual);
+}
+
 CPPUNIT_PLUGIN_IMPLEMENT();
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/shells/textfld.cxx 
b/sw/source/uibase/shells/textfld.cxx
index 239e4a076812..97f94174e987 100644
--- a/sw/source/uibase/shells/textfld.cxx
+++ b/sw/source/uibase/shells/textfld.cxx
@@ -731,9 +731,6 @@ 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)
@@ -758,8 +755,19 @@ FIELD_INSERT:
                     {
                         rSh.InsertFootnote(OUString());
                     }
+                    else if (aWrapper == "Endnote")
+                    {
+                        // It's important that there is no Start/EndAction() 
around this, so the
+                        // inner EndAction() triggers a layout update and the 
cursor can jump to the
+                        // created SwFootnoteFrame.
+                        rSh.InsertFootnote(OUString(), /*bEndNote=*/true);
+                    }
                 }
 
+                // Don't update the layout after inserting content and before 
deleting temporary
+                // text nodes.
+                rSh.StartAction();
+
                 // Split node to remember where the start position is.
                 bool bSuccess = 
rSh.GetDoc()->getIDocumentContentOperations().SplitNode(
                     *pCursorPos->GetPoint(), false);
@@ -802,9 +810,9 @@ FIELD_INSERT:
                             std::pair<OUString, uno::Any>(ODF_CODE_PARAM, 
uno::Any(aFieldCode)));
                     }
                 }
+                rSh.EndAction();
             }
 
-            rSh.EndAction();
             
rSh.GetDoc()->GetIDocumentUndoRedo().EndUndo(SwUndoId::INSERT_FORM_FIELD, 
nullptr);
             rSh.GetView().GetViewFrame()->GetBindings().Invalidate( SID_UNDO );
         }

Reply via email to