summaryrefslogtreecommitdiff
path: root/sw
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@collabora.com>2023-01-10 15:40:34 +0100
committerMiklos Vajna <vmiklos@collabora.com>2023-01-10 21:08:51 +0000
commitc68d06dfa1498f862923eaddf3e5d247650a53d5 (patch)
tree9f0f4dc0662d2a1409c39759aed07433d8ee3246 /sw
parentcec3c719303decd3b811a328fabd71d8c4e5ba3b (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.h1
-rw-r--r--sw/qa/uibase/shells/shells.cxx45
-rw-r--r--sw/sdi/_textsh.sdi6
-rw-r--r--sw/sdi/swriter.sdi14
-rw-r--r--sw/source/uibase/shells/textfld.cxx54
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();