sw/qa/uibase/shells/shells.cxx | 34 ++++++++++++++++++++++++++++++++++ sw/sdi/swriter.sdi | 2 +- sw/source/core/inc/bookmark.hxx | 2 +- sw/source/uibase/shells/textfld.cxx | 29 +++++++++++++++++++++++++---- 4 files changed, 61 insertions(+), 6 deletions(-)
New commits: commit e02b71a13ecb5f98ba7ffea35e5b11bcb48f6d3e Author: Miklos Vajna <vmik...@collabora.com> AuthorDate: Tue Nov 15 09:53:20 2022 +0100 Commit: Miklos Vajna <vmik...@collabora.com> CommitDate: Wed Nov 16 11:12:42 2022 +0100 sw: add new FieldCode parameter for the .uno:TextFormField command The field code/command is the input of the field expand. Also allow setting a field result, given that the entire point of "unhandled" fieldmarks is that Writer itself doesn't know how to compute the field result / expanded string. Note that a field result can be a multi-paragraph and formatted content, so far we only allow single-paragraph plain text. (cherry picked from commit 6870c0c3385bf5d19e9c80bf973fca255ae38c08) Conflicts: sw/source/uibase/shells/textfld.cxx Change-Id: I1739cb985d1d4ed8e45068f15a4e0d82fd118d83 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/142755 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 3d5342f7a121..153b8fc5b479 100644 --- a/sw/qa/uibase/shells/shells.cxx +++ b/sw/qa/uibase/shells/shells.cxx @@ -34,6 +34,8 @@ #include <IDocumentDrawModelAccess.hxx> #include <drawdoc.hxx> #include <docsh.hxx> +#include <bookmark.hxx> +#include <ndtxt.hxx> constexpr OUStringLiteral DATA_DIRECTORY = u"/sw/qa/uibase/shells/data/"; @@ -239,14 +241,37 @@ 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: SwDoc* pDoc = createSwDoc(); // 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)), }; dispatchCommand(mxComponent, ".uno:TextFormField", aArgs); @@ -262,6 +287,15 @@ CPPUNIT_TEST_FIXTURE(SwUibaseShellsTest, testInsertTextFormField) // - Actual : vnd.oasis.opendocument.field.FORMTEXT // i.e. the custom type parameter was ignored. CPPUNIT_ASSERT_EQUAL(OUString(ODF_UNHANDLED), pFieldmark->GetFieldname()); + + auto it = pFieldmark->GetParameters()->find(ODF_CODE_PARAM); + CPPUNIT_ASSERT(it != pFieldmark->GetParameters()->end()); + OUString aActualCommand; + it->second >>= aActualCommand; + CPPUNIT_ASSERT_EQUAL(aExpectedCommand, aActualCommand); + + OUString aActualResult = TextFieldmarkGetContent(pFieldmark); + CPPUNIT_ASSERT_EQUAL(aExpectedResult, aActualResult); } CPPUNIT_PLUGIN_IMPLEMENT(); diff --git a/sw/sdi/swriter.sdi b/sw/sdi/swriter.sdi index 7aa6aab89a17..ab71c6c32914 100644 --- a/sw/sdi/swriter.sdi +++ b/sw/sdi/swriter.sdi @@ -8203,7 +8203,7 @@ SfxBoolItem ShowInlineTooltips FN_SHOW_INLINETOOLTIPS ] SfxVoidItem TextFormField FN_INSERT_TEXT_FORMFIELD -(SfxStringItem FieldType FN_PARAM_1) +(SfxStringItem FieldType FN_PARAM_1, SfxStringItem FieldCommand FN_PARAM_2, SfxStringItem FieldResult FN_PARAM_3) [ AutoUpdate = TRUE, FastCall = FALSE, diff --git a/sw/source/core/inc/bookmark.hxx b/sw/source/core/inc/bookmark.hxx index 39afc6e70271..7399ea28cd0e 100644 --- a/sw/source/core/inc/bookmark.hxx +++ b/sw/source/core/inc/bookmark.hxx @@ -336,7 +336,7 @@ namespace sw::mark { }; /// return position of the CH_TXT_ATR_FIELDSEP for rMark - SwPosition FindFieldSep(IFieldmark const& rMark); + SW_DLLPUBLIC SwPosition FindFieldSep(IFieldmark const& rMark); /// check if rPaM is valid range of new fieldmark bool IsFieldmarkOverlap(SwPaM const& rPaM); diff --git a/sw/source/uibase/shells/textfld.cxx b/sw/source/uibase/shells/textfld.cxx index 17030cba23a3..2f3c62512171 100644 --- a/sw/source/uibase/shells/textfld.cxx +++ b/sw/source/uibase/shells/textfld.cxx @@ -694,6 +694,14 @@ FIELD_INSERT: aFieldType = pFieldType->GetValue(); } + OUString aFieldCode; + const SfxStringItem* pFieldCode = rReq.GetArg<SfxStringItem>(FN_PARAM_2); + if (pFieldCode) + { + // Allow specifying a field code/command. + aFieldCode = pFieldCode->GetValue(); + } + rSh.GetDoc()->GetIDocumentUndoRedo().StartUndo(SwUndoId::INSERT_FORM_FIELD, nullptr); SwPaM* pCursorPos = rSh.GetCursor(); @@ -701,14 +709,27 @@ FIELD_INSERT: { // Insert five En Space into the text field so the field has extent static constexpr OUStringLiteral vEnSpaces = u"\u2002\u2002\u2002\u2002\u2002"; - bool bSuccess = rSh.GetDoc()->getIDocumentContentOperations().InsertString(*pCursorPos, vEnSpaces); + OUString aFieldResult(vEnSpaces); + const SfxStringItem* pFieldResult = rReq.GetArg<SfxStringItem>(FN_PARAM_3); + if (pFieldResult) + { + // Allow specifying a field result / expanded value. + aFieldResult = pFieldResult->GetValue(); + } + + bool bSuccess = rSh.GetDoc()->getIDocumentContentOperations().InsertString(*pCursorPos, aFieldResult); if(bSuccess) { IDocumentMarkAccess* pMarksAccess = rSh.GetDoc()->getIDocumentMarkAccess(); - SwPaM aFieldPam(pCursorPos->GetPoint()->nNode, pCursorPos->GetPoint()->nContent.GetIndex() - vEnSpaces.getLength(), + SwPaM aFieldPam(pCursorPos->GetPoint()->nNode, pCursorPos->GetPoint()->nContent.GetIndex() - aFieldResult.getLength(), pCursorPos->GetPoint()->nNode, pCursorPos->GetPoint()->nContent.GetIndex()); - pMarksAccess->makeFieldBookmark(aFieldPam, OUString(), aFieldType, - aFieldPam.Start()); + sw::mark::IFieldmark* pFieldmark = pMarksAccess->makeFieldBookmark( + aFieldPam, OUString(), aFieldType, aFieldPam.Start()); + if (pFieldmark && !aFieldCode.isEmpty()) + { + pFieldmark->GetParameters()->insert( + std::pair<OUString, uno::Any>(ODF_CODE_PARAM, uno::Any(aFieldCode))); + } } }