sw/CppunitTest_sw_uibase_shells.mk  |    1 
 sw/inc/cmdid.h                      |    1 
 sw/inc/txtrfmrk.hxx                 |    2 +
 sw/qa/uibase/shells/textsh.cxx      |   64 ++++++++++++++++++++++++++++++++++++
 sw/sdi/_textsh.sdi                  |    6 +++
 sw/sdi/swriter.sdi                  |   14 +++++++
 sw/source/core/crsr/bookmark.cxx    |   21 +++++++++++
 sw/source/core/doc/docbm.cxx        |   18 ++++++++++
 sw/source/core/inc/bookmark.hxx     |    1 
 sw/source/core/txtnode/atrref.cxx   |   26 ++++++++++++++
 sw/source/uibase/shells/textsh1.cxx |   50 ++++++++++++++++++++++++++++
 11 files changed, 204 insertions(+)

New commits:
commit dee8500395dd1b8814f8c8835092125e06eb37f6
Author:     Miklos Vajna <vmik...@collabora.com>
AuthorDate: Fri Jan 20 09:50:11 2023 +0100
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Thu Feb 9 09:14:59 2023 +0100

    sw: add a new .uno:DeleteSections UNO command
    
    This is similiar to commit 1d6593dd799ff4eb931ffbb5338e4856fb87f77f (sw:
    add a new .uno:DeleteFields UNO command, 2023-01-16), but that deleted
    refmarks (used for e.g. Zotero citations), while this deletes sections
    (used for e.g. Zotero bibliography).
    
    Implement the section "unlinking" (delete the section, but not its data)
    by deleting the section format: that will remove the matching section
    node as well, but not the content nodes.
    
    (cherry picked from commit a5a1ea2f7d784c5c6c33f332ba61aceb7af3eca4)
    
    Change-Id: Ib00a8f592ddbb77c5e8e08ff94bb0eebfcf7cea8

diff --git a/sw/CppunitTest_sw_uibase_shells.mk 
b/sw/CppunitTest_sw_uibase_shells.mk
index 932769a421e6..2affe0205e7d 100644
--- a/sw/CppunitTest_sw_uibase_shells.mk
+++ b/sw/CppunitTest_sw_uibase_shells.mk
@@ -15,6 +15,7 @@ $(eval $(call 
gb_CppunitTest_use_common_precompiled_header,sw_uibase_shells))
 
 $(eval $(call gb_CppunitTest_add_exception_objects,sw_uibase_shells, \
     sw/qa/uibase/shells/textfld \
+    sw/qa/uibase/shells/textsh \
     sw/qa/uibase/shells/shells \
 ))
 
diff --git a/sw/inc/cmdid.h b/sw/inc/cmdid.h
index c44745a0e861..634290ebd8c5 100644
--- a/sw/inc/cmdid.h
+++ b/sw/inc/cmdid.h
@@ -329,6 +329,7 @@ class SwUINumRuleItem;
 #define FN_UPDATE_FIELD (FN_INSERT2 + 38)
 #define FN_DELETE_BOOKMARKS (FN_INSERT2 + 39)
 #define FN_DELETE_FIELDS (FN_INSERT2 + 40)
+#define FN_DELETE_SECTIONS (FN_INSERT2 + 41)
 
 // Region: Format
 #define FN_AUTOFORMAT_APPLY     (FN_FORMAT + 1 ) /* apply autoformat options */
diff --git a/sw/qa/uibase/shells/textsh.cxx b/sw/qa/uibase/shells/textsh.cxx
new file mode 100644
index 000000000000..a97fc8bd7f5f
--- /dev/null
+++ b/sw/qa/uibase/shells/textsh.cxx
@@ -0,0 +1,64 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <swmodeltestbase.hxx>
+
+#include <comphelper/propertyvalue.hxx>
+#include <comphelper/propertysequence.hxx>
+#include <comphelper/sequence.hxx>
+
+#include <docary.hxx>
+
+namespace
+{
+/// Covers sw/source/uibase/shells/textsh.cxx fixes.
+class Test : public SwModelTestBase
+{
+public:
+    Test()
+        : SwModelTestBase("/sw/qa/uibase/shells/data/")
+    {
+    }
+};
+
+CPPUNIT_TEST_FIXTURE(Test, testDeleteSections)
+{
+    // Given a document with a section:
+    createSwDoc();
+    SwDoc* pDoc = getSwDoc();
+    uno::Sequence<css::beans::PropertyValue> aArgs = {
+        comphelper::makePropertyValue("RegionName",
+                                      uno::Any(OUString("ZOTERO_BIBL {} 
CSL_BIBLIOGRAPHY RND"))),
+        comphelper::makePropertyValue("Content", uno::Any(OUString("old 
content"))),
+    };
+    dispatchCommand(mxComponent, ".uno:InsertSection", aArgs);
+    CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), pDoc->GetSections().size());
+
+    // When deleting sections:
+    std::vector<beans::PropertyValue> aArgsVec = 
comphelper::JsonToPropertyValues(R"json(
+{
+    "SectionNamePrefix": {
+        "type": "string",
+        "value": "ZOTERO_BIBL"
+    }
+}
+)json");
+    aArgs = comphelper::containerToSequence(aArgsVec);
+    dispatchCommand(mxComponent, ".uno:DeleteSections", aArgs);
+
+    // Then make sure that the section is deleted:
+    // Without the accompanying fix in place, this test would have failed with:
+    // - Expected: 0
+    // - Actual  : 1
+    // i.e. the section was not deleted.
+    CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(0), pDoc->GetSections().size());
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/sdi/_textsh.sdi b/sw/sdi/_textsh.sdi
index 88c77215fc40..38cb24682d33 100644
--- a/sw/sdi/_textsh.sdi
+++ b/sw/sdi/_textsh.sdi
@@ -1843,6 +1843,12 @@ interface BaseText
         DisableFlags="SfxDisableFlags::SwOnProtectedCursor";
     ]
 
+    FN_DELETE_SECTIONS
+    [
+        ExecMethod = Execute ;
+        DisableFlags="SfxDisableFlags::SwOnProtectedCursor";
+    ]
+
     FN_DELETE_FIELDS
     [
         ExecMethod = Execute ;
diff --git a/sw/sdi/swriter.sdi b/sw/sdi/swriter.sdi
index da00008b80e9..663d63b88caf 100644
--- a/sw/sdi/swriter.sdi
+++ b/sw/sdi/swriter.sdi
@@ -2614,6 +2614,20 @@ SfxVoidItem DeleteBookmarks FN_DELETE_BOOKMARKS
     GroupId = SfxGroupId::Controls;
 ]
 
+SfxVoidItem DeleteSections FN_DELETE_SECTIONS
+(SfxStringItem SectionNamePrefix FN_PARAM_1)
+[
+    AutoUpdate = FALSE,
+    FastCall = FALSE,
+    ReadOnlyDoc = FALSE,
+    Toggle = FALSE,
+    Container = FALSE,
+    RecordAbsolute = FALSE,
+    RecordPerSet;
+
+    GroupId = SfxGroupId::Controls;
+]
+
 SfxVoidItem DeleteFields FN_DELETE_FIELDS
 (SfxStringItem TypeName FN_PARAM_1, SfxStringItem NamePrefix FN_PARAM_2)
 [
diff --git a/sw/source/uibase/shells/textsh1.cxx 
b/sw/source/uibase/shells/textsh1.cxx
index c95a78f4d4be..e77f4c9893da 100644
--- a/sw/source/uibase/shells/textsh1.cxx
+++ b/sw/source/uibase/shells/textsh1.cxx
@@ -451,6 +451,49 @@ void UpdateSections(SfxRequest& rReq, SwWrtShell& rWrtSh)
     rWrtSh.GetDoc()->GetIDocumentUndoRedo().EndUndo(SwUndoId::INSSECTION, 
nullptr);
 }
 
+void DeleteSections(SfxRequest& rReq, SwWrtShell& rWrtSh)
+{
+    OUString aSectionNamePrefix;
+    const SfxStringItem* pSectionNamePrefix = 
rReq.GetArg<SfxStringItem>(FN_PARAM_1);
+    if (pSectionNamePrefix)
+    {
+        aSectionNamePrefix = pSectionNamePrefix->GetValue();
+    }
+
+    rWrtSh.GetDoc()->GetIDocumentUndoRedo().StartUndo(SwUndoId::DELSECTION, 
nullptr);
+    rWrtSh.StartAction();
+    comphelper::ScopeGuard g(
+        [&rWrtSh]
+        {
+            rWrtSh.EndAction();
+            
rWrtSh.GetDoc()->GetIDocumentUndoRedo().EndUndo(SwUndoId::DELSECTION, nullptr);
+        });
+
+    SwDoc* pDoc = rWrtSh.GetDoc();
+    SwSectionFormats& rFormats = pDoc->GetSections();
+    std::vector<SwSectionFormat*> aRemovals;
+    for (size_t i = 0; i < rFormats.size(); ++i)
+    {
+        SwSectionFormat* pFormat = rFormats[i];
+
+        if (!aSectionNamePrefix.isEmpty())
+        {
+            if (!pFormat->GetName().startsWith(aSectionNamePrefix))
+            {
+                continue;
+            }
+        }
+
+        aRemovals.push_back(pFormat);
+    }
+
+    for (const auto& pFormat : aRemovals)
+    {
+        // Just delete the format, not the content of the section.
+        pDoc->DelSectionFormat(pFormat);
+    }
+}
+
 void UpdateBookmarks(SfxRequest& rReq, SwWrtShell& rWrtSh)
 {
     if 
(rWrtSh.getIDocumentSettingAccess().get(DocumentSettingId::PROTECT_BOOKMARKS))
@@ -1127,6 +1170,13 @@ void SwTextShell::Execute(SfxRequest &rReq)
             UpdateSections(rReq, rWrtSh);
             break;
         }
+        case FN_DELETE_SECTIONS:
+        {
+            // This deletes all sections in the document matching a specified 
prefix. Note that the
+            // section is deleted, but not its contents.
+            DeleteSections(rReq, rWrtSh);
+            break;
+        }
         case FN_SET_REMINDER:
         {
             // collect and sort navigator reminder names
commit db3f6f20ce7154a19f4e938c45ef384a7e533630
Author:     Pranam Lashkari <lpra...@collabora.com>
AuthorDate: Thu Jan 19 15:27:31 2023 +0530
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Thu Feb 9 09:14:00 2023 +0100

    sw: send LOK call back on refmark deletion
    
    this helps with zotero when user deletes a refmark or use undo
    without this online will be unaware of any such changes made by user
    
    (cherry picked from commit 06f98f94448fdf7b5dc3a55f45da8a27e5b212a8)
    
    Change-Id: Ia4326fd03f6b7d27fdb59ccc25d60331ba7923d5

diff --git a/sw/inc/txtrfmrk.hxx b/sw/inc/txtrfmrk.hxx
index 0d25090197c1..6c9eafc35fb6 100644
--- a/sw/inc/txtrfmrk.hxx
+++ b/sw/inc/txtrfmrk.hxx
@@ -33,6 +33,8 @@ public:
     SwTextRefMark( SwFormatRefMark& rAttr,
             sal_Int32 const nStart, sal_Int32 const*const pEnd = nullptr);
 
+    ~SwTextRefMark();
+
     virtual const sal_Int32* GetEnd() const override;       // SwTextAttr
     virtual void SetEnd(sal_Int32) override;       // SwTextAttr
 
diff --git a/sw/source/core/txtnode/atrref.cxx 
b/sw/source/core/txtnode/atrref.cxx
index 51f913c49236..0c2bb85bd1ae 100644
--- a/sw/source/core/txtnode/atrref.cxx
+++ b/sw/source/core/txtnode/atrref.cxx
@@ -24,6 +24,11 @@
 #include <txtrfmrk.hxx>
 #include <unorefmark.hxx>
 #include <utility>
+#include <sfx2/viewsh.hxx>
+#include <tools/json_writer.hxx>
+#include <LibreOfficeKit/LibreOfficeKitEnums.h>
+#include <doc.hxx>
+#include <ndtxt.hxx>
 
 SwFormatRefMark::~SwFormatRefMark( )
 {
@@ -99,6 +104,27 @@ SwTextRefMark::SwTextRefMark( SwFormatRefMark& rAttr,
     SetOverlapAllowedAttr( true );
 }
 
+SwTextRefMark::~SwTextRefMark()
+{
+    if (GetTextNode().GetDoc().IsClipBoard())
+        return;
+
+    SfxViewShell* pViewShell = SfxViewShell::Current();
+    if (!pViewShell)
+        return;
+
+    OUString fieldCommand = GetRefMark().GetRefName();
+    tools::JsonWriter aJson;
+    aJson.put("commandName", ".uno:DeleteField");
+    aJson.put("success", true);
+    {
+        auto result = aJson.startNode("result");
+        aJson.put("DeleteField", fieldCommand);
+    }
+
+    pViewShell->libreOfficeKitViewCallback(LOK_CALLBACK_UNO_COMMAND_RESULT, 
aJson.extractData());
+}
+
 const sal_Int32* SwTextRefMark::GetEnd() const
 {
     return m_pEnd;
commit 7f9419169ef876d55acc26694447bcbf50301ba9
Author:     Pranam Lashkari <lpra...@collabora.com>
AuthorDate: Thu Jan 19 15:57:26 2023 +0530
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Thu Feb 9 09:12:51 2023 +0100

    sw: send LOK call back on bookmark deletion
    
    this helps with zotero when user deletes a bookmark or use undo
    without this online will be unaware of any such changes made by user
    
    (cherry picked from commit c8e49e7a49a99fd76a25ea825319d2243fed5c22)
    
    Change-Id: Id5ea4ee0ee1d16c399460cd177ec8e33256ce3dd

diff --git a/sw/source/core/crsr/bookmark.cxx b/sw/source/core/crsr/bookmark.cxx
index 8165b30a98b1..c43dd04c2496 100644
--- a/sw/source/core/crsr/bookmark.cxx
+++ b/sw/source/core/crsr/bookmark.cxx
@@ -420,6 +420,27 @@ namespace sw::mark
         m_aName = rName;
     }
 
+    void Bookmark::sendLOKDeleteCallback()
+    {
+        if (GetMarkPos().GetDoc().IsClipBoard())
+            return;
+
+        SfxViewShell* pViewShell = SfxViewShell::Current();
+        if (!pViewShell)
+            return;
+
+        OUString fieldCommand = GetName();
+        tools::JsonWriter aJson;
+        aJson.put("commandName", ".uno:DeleteBookmark");
+        aJson.put("success", true);
+        {
+            auto result = aJson.startNode("result");
+            aJson.put("DeleteBookmark", fieldCommand);
+        }
+
+        
pViewShell->libreOfficeKitViewCallback(LOK_CALLBACK_UNO_COMMAND_RESULT, 
aJson.extractData());
+    }
+
     void Bookmark::InitDoc(SwDoc& io_rDoc,
             sw::mark::InsertMode const, SwPosition const*const)
     {
diff --git a/sw/source/core/doc/docbm.cxx b/sw/source/core/doc/docbm.cxx
index 7152c2a2314a..ac837965cd5c 100644
--- a/sw/source/core/doc/docbm.cxx
+++ b/sw/source/core/doc/docbm.cxx
@@ -1249,6 +1249,24 @@ namespace sw::mark
         switch(IDocumentMarkAccess::GetType(*pMark))
         {
             case IDocumentMarkAccess::MarkType::BOOKMARK:
+                {
+                    auto const ppBookmark = lcl_FindMark(m_vBookmarks, 
*ppMark.get());
+                    if ( ppBookmark != m_vBookmarks.end() )
+                    {
+                        Bookmark* pBookmark = 
dynamic_cast<Bookmark*>(*ppBookmark);
+
+                        if(pBookmark)
+                            pBookmark->sendLOKDeleteCallback();
+
+                        m_vBookmarks.erase(ppBookmark);
+                    }
+                    else
+                    {
+                        assert(false &&
+                            "<MarkManager::deleteMark(..)> - Bookmark not 
found in Bookmark container.");
+                    }
+                }
+                break;
             case IDocumentMarkAccess::MarkType::CROSSREF_HEADING_BOOKMARK:
             case IDocumentMarkAccess::MarkType::CROSSREF_NUMITEM_BOOKMARK:
                 {
diff --git a/sw/source/core/inc/bookmark.hxx b/sw/source/core/inc/bookmark.hxx
index b4630b18701c..6ba9484b3bd8 100644
--- a/sw/source/core/inc/bookmark.hxx
+++ b/sw/source/core/inc/bookmark.hxx
@@ -188,6 +188,7 @@ namespace sw::mark {
             bool IsInClipboard() const override;
             bool IsInUndo() const override;
             bool IsInContent() const override;
+            void sendLOKDeleteCallback();
             css::uno::Reference< css::rdf::XMetadatable > MakeUnoObject() 
override;
 
         private:

Reply via email to