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(+)
New commits: commit 1d6593dd799ff4eb931ffbb5338e4856fb87f77f Author: Miklos Vajna <vmik...@collabora.com> AuthorDate: Mon Jan 16 08:10:16 2023 +0100 Commit: Miklos Vajna <vmik...@collabora.com> CommitDate: Mon Jan 16 08:05:45 2023 +0000 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 <vmik...@collabora.com> Tested-by: Jenkins 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<css::beans::PropertyValue> 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("aaa<b>bbb</b>ccc"))), + }; + dispatchCommand(mxComponent, ".uno:InsertField", aArgs); + + // When deleting the refmarks: + std::vector<beans::PropertyValue> 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<sal_uInt16>(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 <IDocumentContentOperations.hxx> #include <IDocumentUndoRedo.hxx> #include <fmtcntnt.hxx> +#include <fmtrfmrk.hxx> 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<SfxStringItem>(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<SfxStringItem>(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<const SwFormatRefMark*> 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);