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);

Reply via email to