diff options
author | Miklos Vajna <vmiklos@collabora.com> | 2023-01-10 15:40:34 +0100 |
---|---|---|
committer | Miklos Vajna <vmiklos@collabora.com> | 2023-01-10 21:08:51 +0000 |
commit | c68d06dfa1498f862923eaddf3e5d247650a53d5 (patch) | |
tree | 9f0f4dc0662d2a1409c39759aed07433d8ee3246 /sw | |
parent | cec3c719303decd3b811a328fabd71d8c4e5ba3b (diff) |
sw: add a new .uno:DeleteTextFormFields UNO command
Users sometimes want to "unlink" their citations, which means deleting
the fieldmarks (if fieldmarks are used to represent citations, e.g.
with Zotero), which means keeping the field result as-is, but removing
the field metadata and the actual field start/seprator/end characters.
Do this similar to .uno:TextFormFields, which can do an update of such
fieldmarks, i.e. add the ability to filter for a certain type and field
command prefix. This is meant to allow removal af all fieldmark that
belongs to one one feature, e.g. Zotero.
This is similar to 7765b442e13048f857fd7ee49ced1731caee297e (sw: add a
new .uno:TextFormFields UNO command, 2022-11-28), but this is about
deleting (the field commands, not the result), while that was about
updating.
The same for bookmarks & refmarks are not yet supported.
Change-Id: I02548b030b1822f7b36d3bc5ff9553d728f065c2
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/145272
Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
Tested-by: Jenkins
Diffstat (limited to 'sw')
-rw-r--r-- | sw/inc/cmdid.h | 1 | ||||
-rw-r--r-- | sw/qa/uibase/shells/shells.cxx | 45 | ||||
-rw-r--r-- | sw/sdi/_textsh.sdi | 6 | ||||
-rw-r--r-- | sw/sdi/swriter.sdi | 14 | ||||
-rw-r--r-- | sw/source/uibase/shells/textfld.cxx | 54 |
5 files changed, 120 insertions, 0 deletions
diff --git a/sw/inc/cmdid.h b/sw/inc/cmdid.h index bec1acbe5446..befe8e26d607 100644 --- a/sw/inc/cmdid.h +++ b/sw/inc/cmdid.h @@ -324,6 +324,7 @@ class SwUINumRuleItem; #define FN_EDIT_BOOKMARK (FN_INSERT2 + 33 ) /* Bookmark */ #define FN_UPDATE_BOOKMARKS (FN_INSERT2 + 34) #define FN_UPDATE_SECTIONS (FN_INSERT2 + 35) +#define FN_DELETE_TEXT_FORMFIELDS (FN_INSERT2 + 36) // Region: Format #define FN_AUTOFORMAT_APPLY (FN_FORMAT + 1 ) /* apply autoformat options */ diff --git a/sw/qa/uibase/shells/shells.cxx b/sw/qa/uibase/shells/shells.cxx index 8dbdee89267c..edfe255f4ad7 100644 --- a/sw/qa/uibase/shells/shells.cxx +++ b/sw/qa/uibase/shells/shells.cxx @@ -713,6 +713,51 @@ CPPUNIT_TEST_FIXTURE(SwUibaseShellsTest, testUpdateSections) CPPUNIT_ASSERT_EQUAL(OUString("new content"), aActualResult); } +CPPUNIT_TEST_FIXTURE(SwUibaseShellsTest, testDeleteFieldmarks) +{ + // Given a document with 2 fieldmarks: + createSwDoc(); + { + uno::Sequence<css::beans::PropertyValue> aArgs = { + comphelper::makePropertyValue("FieldType", uno::Any(OUString(ODF_UNHANDLED))), + comphelper::makePropertyValue("FieldCommand", + uno::Any(OUString("ADDIN ZOTERO_ITEM old command 1"))), + comphelper::makePropertyValue("FieldResult", uno::Any(OUString("result 1"))), + }; + dispatchCommand(mxComponent, ".uno:TextFormField", aArgs); + } + { + uno::Sequence<css::beans::PropertyValue> aArgs = { + comphelper::makePropertyValue("FieldType", uno::Any(OUString(ODF_UNHANDLED))), + comphelper::makePropertyValue("FieldCommand", + uno::Any(OUString("ADDIN ZOTERO_ITEM old command 2"))), + comphelper::makePropertyValue("FieldResult", uno::Any(OUString("result 2"))), + }; + dispatchCommand(mxComponent, ".uno:TextFormField", aArgs); + } + + // When deleting those fieldmarks: + uno::Sequence<css::beans::PropertyValue> aArgs + = { comphelper::makePropertyValue("FieldType", uno::Any(OUString(ODF_UNHANDLED))), + comphelper::makePropertyValue("FieldCommandPrefix", + uno::Any(OUString("ADDIN ZOTERO_ITEM"))) }; + dispatchCommand(mxComponent, ".uno:DeleteTextFormFields", aArgs); + + // Then make sure that the document doesn't contain fields anymore: + SwDoc* pDoc = getSwDoc(); + // Without the accompanying fix in place, this test would have failed with: + // - Expected: 0 + // - Actual : 2 + // i.e. the fieldmarks were not deleted. + CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0), + pDoc->getIDocumentMarkAccess()->getAllMarksCount()); + SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell(); + pWrtShell->SttEndDoc(/*bStt=*/true); + SwCursor* pCursor = pWrtShell->GetCursor(); + OUString aActual = pCursor->Start()->GetNode().GetTextNode()->GetText(); + CPPUNIT_ASSERT_EQUAL(OUString("result 1result 2"), aActual); +} + CPPUNIT_PLUGIN_IMPLEMENT(); /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/sdi/_textsh.sdi b/sw/sdi/_textsh.sdi index f712ea376776..99f50c8e3b27 100644 --- a/sw/sdi/_textsh.sdi +++ b/sw/sdi/_textsh.sdi @@ -1820,6 +1820,12 @@ interface BaseText StateMethod = StateField ; ] + FN_DELETE_TEXT_FORMFIELDS + [ + ExecMethod = ExecField ; + StateMethod = StateField ; + ] + FN_PROTECT_FIELDS [ ExecMethod = Execute ; diff --git a/sw/sdi/swriter.sdi b/sw/sdi/swriter.sdi index bc0c5456aef8..76939d94c03a 100644 --- a/sw/sdi/swriter.sdi +++ b/sw/sdi/swriter.sdi @@ -8330,6 +8330,20 @@ SfxVoidItem TextFormFields FN_UPDATE_TEXT_FORMFIELDS GroupId = SfxGroupId::Controls; ] +SfxVoidItem DeleteTextFormFields FN_DELETE_TEXT_FORMFIELDS +(SfxStringItem FieldType FN_PARAM_1, SfxStringItem FieldCommandPrefix FN_PARAM_2) +[ + AutoUpdate = TRUE, + FastCall = FALSE, + ReadOnlyDoc = FALSE, + Toggle = FALSE, + Container = FALSE, + RecordAbsolute = FALSE, + RecordPerSet; + + GroupId = SfxGroupId::Controls; +] + SfxVoidItem UpdateTextFormField FN_UPDATE_TEXT_FORMFIELD (SfxStringItem FieldType FN_PARAM_1, SfxStringItem FieldCommandPrefix FN_PARAM_2, SfxUnoAnyItem Field FN_PARAM_3) [ diff --git a/sw/source/uibase/shells/textfld.cxx b/sw/source/uibase/shells/textfld.cxx index 71e57ba0ae47..7e10b7a8673d 100644 --- a/sw/source/uibase/shells/textfld.cxx +++ b/sw/source/uibase/shells/textfld.cxx @@ -933,6 +933,60 @@ FIELD_INSERT: rSh.GetDoc()->GetIDocumentUndoRedo().EndUndo(SwUndoId::INSERT_FORM_FIELD, nullptr); } break; + case FN_DELETE_TEXT_FORMFIELDS: + { + // This deletes all fieldmarks that match the provided field type & field command prefix. + OUString aFieldType; + const SfxStringItem* pFieldType = rReq.GetArg<SfxStringItem>(FN_PARAM_1); + if (pFieldType) + { + aFieldType = pFieldType->GetValue(); + } + OUString aFieldCommandPrefix; + const SfxStringItem* pFieldCommandPrefix = rReq.GetArg<SfxStringItem>(FN_PARAM_2); + if (pFieldCommandPrefix) + { + aFieldCommandPrefix = pFieldCommandPrefix->GetValue(); + } + rSh.GetDoc()->GetIDocumentUndoRedo().StartUndo(SwUndoId::INSERT_FORM_FIELD, nullptr); + rSh.StartAction(); + + IDocumentMarkAccess* pMarkAccess = rSh.GetDoc()->getIDocumentMarkAccess(); + std::vector<sw::mark::IMark*> aRemovals; + for (auto it = pMarkAccess->getFieldmarksBegin(); it != pMarkAccess->getFieldmarksEnd(); ++it) + { + auto pFieldmark = dynamic_cast<sw::mark::IFieldmark*>(*it); + assert(pFieldmark); + if (pFieldmark->GetFieldname() != aFieldType) + { + continue; + } + + auto itParam = pFieldmark->GetParameters()->find(ODF_CODE_PARAM); + if (itParam == pFieldmark->GetParameters()->end()) + { + continue; + } + + OUString aCommand; + itParam->second >>= aCommand; + if (!aCommand.startsWith(aFieldCommandPrefix)) + { + continue; + } + + aRemovals.push_back(pFieldmark); + } + + for (const auto& pMark : aRemovals) + { + pMarkAccess->deleteMark(pMark); + } + + rSh.EndAction(); + rSh.GetDoc()->GetIDocumentUndoRedo().EndUndo(SwUndoId::INSERT_FORM_FIELD, nullptr); + } + break; case FN_PGNUMBER_WIZARD: { SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create(); |