From 1d6593dd799ff4eb931ffbb5338e4856fb87f77f Mon Sep 17 00:00:00 2001 From: Miklos Vajna Date: Mon, 16 Jan 2023 08:10:16 +0100 Subject: [PATCH] sw: add a new .uno:DeleteFields UNO command This is similar to 40753de837b9776dd8b33e830be0cceef83f024a (sw: add a new .uno:DeleteBookmarks UNO command, 2023-01-13), but that was about deleting bookmarks matching a given prefix with their name, and this one is about reference marks (fields in general), matching a certain type & prefix with their name. Change-Id: Iec953034cd0e6875f173712b0fb10bfddf16ed3f Reviewed-on: https://gerrit.libreoffice.org/c/core/+/145551 Reviewed-by: Miklos Vajna Tested-by: Jenkins --- sw/inc/cmdid.h | 1 + sw/qa/uibase/shells/shells.cxx | 37 ++++++++++++++++++++ sw/sdi/_textsh.sdi | 6 ++++ sw/sdi/swriter.sdi | 14 ++++++++ sw/source/uibase/shells/textsh1.cxx | 54 +++++++++++++++++++++++++++++ 5 files changed, 112 insertions(+) diff --git a/sw/inc/cmdid.h b/sw/inc/cmdid.h index 73059db65620..c44745a0e861 100644 --- a/sw/inc/cmdid.h +++ b/sw/inc/cmdid.h @@ -328,6 +328,7 @@ class SwUINumRuleItem; #define FN_UPDATE_BOOKMARK (FN_INSERT2 + 37) #define FN_UPDATE_FIELD (FN_INSERT2 + 38) #define FN_DELETE_BOOKMARKS (FN_INSERT2 + 39) +#define FN_DELETE_FIELDS (FN_INSERT2 + 40) // 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 27725c692093..8ed71760baa7 100644 --- a/sw/qa/uibase/shells/shells.cxx +++ b/sw/qa/uibase/shells/shells.cxx @@ -898,6 +898,43 @@ CPPUNIT_TEST_FIXTURE(SwUibaseShellsTest, testDeleteBookmarks) CPPUNIT_ASSERT(it != pDoc->getIDocumentMarkAccess()->getAllMarksEnd()); } +CPPUNIT_TEST_FIXTURE(SwUibaseShellsTest, testDeleteFields) +{ + // Given a document with a refmark: + createSwDoc(); + uno::Sequence aArgs = { + comphelper::makePropertyValue("TypeName", uno::Any(OUString("SetRef"))), + comphelper::makePropertyValue( + "Name", uno::Any(OUString("ZOTERO_ITEM CSL_CITATION {} RNDpyJknp173F"))), + comphelper::makePropertyValue("Content", uno::Any(OUString("aaabbbccc"))), + }; + dispatchCommand(mxComponent, ".uno:InsertField", aArgs); + + // When deleting the refmarks: + std::vector aArgsVec = comphelper::JsonToPropertyValues(R"json( +{ + "TypeName": { + "type": "string", + "value": "SetRef" + }, + "NamePrefix": { + "type": "string", + "value": "ZOTERO_ITEM CSL_CITATION" + } +} +)json"); + aArgs = comphelper::containerToSequence(aArgsVec); + dispatchCommand(mxComponent, ".uno:DeleteFields", aArgs); + + // Then make sure that no refmark is kept: + SwDoc* pDoc = getSwDoc(); + // Without the accompanying fix in place, this test would have failed with: + // - Expected: 0 + // - Actual : 1 + // i.e. the refmark was not deleted. + CPPUNIT_ASSERT_EQUAL(static_cast(0), pDoc->GetRefMarks()); +} + CPPUNIT_PLUGIN_IMPLEMENT(); /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/sdi/_textsh.sdi b/sw/sdi/_textsh.sdi index a4e8ac3cac22..e7b5735a71ca 100644 --- a/sw/sdi/_textsh.sdi +++ b/sw/sdi/_textsh.sdi @@ -1848,6 +1848,12 @@ interface BaseText DisableFlags="SfxDisableFlags::SwOnProtectedCursor"; ] + FN_DELETE_FIELDS + [ + ExecMethod = Execute ; + DisableFlags="SfxDisableFlags::SwOnProtectedCursor"; + ] + SID_FM_CTL_PROPERTIES [ ExecMethod = Execute ; diff --git a/sw/sdi/swriter.sdi b/sw/sdi/swriter.sdi index d2bcb5806666..038f70125909 100644 --- a/sw/sdi/swriter.sdi +++ b/sw/sdi/swriter.sdi @@ -2614,6 +2614,20 @@ SfxVoidItem DeleteBookmarks FN_DELETE_BOOKMARKS GroupId = SfxGroupId::Controls; ] +SfxVoidItem DeleteFields FN_DELETE_FIELDS +(SfxStringItem TypeName FN_PARAM_1, SfxStringItem NamePrefix FN_PARAM_2) +[ + AutoUpdate = TRUE, + FastCall = FALSE, + ReadOnlyDoc = FALSE, + Toggle = FALSE, + Container = FALSE, + RecordAbsolute = FALSE, + RecordPerSet; + + GroupId = SfxGroupId::Controls; +] + SfxVoidItem UpdateBookmark FN_UPDATE_BOOKMARK (SfxStringItem BookmarkNamePrefix FN_PARAM_1, SfxUnoAnyItem Bookmark FN_PARAM_2) [ diff --git a/sw/source/uibase/shells/textsh1.cxx b/sw/source/uibase/shells/textsh1.cxx index 969c4c17c13f..6956317af7bd 100644 --- a/sw/source/uibase/shells/textsh1.cxx +++ b/sw/source/uibase/shells/textsh1.cxx @@ -116,6 +116,7 @@ #include #include #include +#include using namespace ::com::sun::star; using namespace com::sun::star::beans; @@ -660,6 +661,53 @@ void DeleteBookmarks(SfxRequest& rReq, SwWrtShell& rWrtSh) pMarkAccess->deleteMark(pMark); } } + +void DeleteFields(SfxRequest& rReq, SwWrtShell& rWrtSh) +{ + const SfxStringItem* pTypeName = rReq.GetArg(FN_PARAM_1); + if (!pTypeName || pTypeName->GetValue() != "SetRef") + { + // This is implemented so far only for reference marks. + return; + } + + OUString aNamePrefix; + const SfxStringItem* pNamePrefix = rReq.GetArg(FN_PARAM_2); + if (pNamePrefix) + { + aNamePrefix = pNamePrefix->GetValue(); + } + + SwDoc* pDoc = rWrtSh.GetDoc(); + pDoc->GetIDocumentUndoRedo().StartUndo(SwUndoId::DELBOOKMARK, nullptr); + rWrtSh.StartAction(); + comphelper::ScopeGuard g( + [&rWrtSh] + { + rWrtSh.EndAction(); + rWrtSh.GetDoc()->GetIDocumentUndoRedo().EndUndo(SwUndoId::DELBOOKMARK, nullptr); + }); + + std::vector aRemovals; + for (sal_uInt16 i = 0; i < pDoc->GetRefMarks(); ++i) + { + const SwFormatRefMark* pRefMark = pDoc->GetRefMark(i); + if (!aNamePrefix.isEmpty()) + { + if (!pRefMark->GetRefName().startsWith(aNamePrefix)) + { + continue; + } + } + + aRemovals.push_back(pRefMark); + } + + for (const auto& pMark : aRemovals) + { + pDoc->DeleteFormatRefMark(pMark); + } +} } void SwTextShell::Execute(SfxRequest &rReq) @@ -1068,6 +1116,12 @@ void SwTextShell::Execute(SfxRequest &rReq) DeleteBookmarks(rReq, rWrtSh); break; } + case FN_DELETE_FIELDS: + { + // This deletes all fields in the document matching a specified type & prefix. + DeleteFields(rReq, rWrtSh); + break; + } case FN_UPDATE_SECTIONS: { UpdateSections(rReq, rWrtSh);