summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@collabora.com>2023-01-20 09:50:11 +0100
committerMiklos Vajna <vmiklos@collabora.com>2023-01-24 12:52:16 +0000
commitf6d7d914049fc16b051ccdb7a6aaa54bb13f83d9 (patch)
tree3e975ce0ac1218410470a8f17fef732776fbf518
parent03625a00e7d147251d916a09f0bf9dbdf3a51913 (diff)
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 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/145895 Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice@gmail.com> Reviewed-by: Justin Luth <jluth@mail.com>
-rw-r--r--sw/CppunitTest_sw_uibase_shells.mk1
-rw-r--r--sw/inc/cmdid.h1
-rw-r--r--sw/qa/uibase/shells/textsh.cxx63
-rw-r--r--sw/sdi/_textsh.sdi6
-rw-r--r--sw/sdi/swriter.sdi14
-rw-r--r--sw/source/uibase/shells/textsh1.cxx50
6 files changed, 135 insertions, 0 deletions
diff --git a/sw/CppunitTest_sw_uibase_shells.mk b/sw/CppunitTest_sw_uibase_shells.mk
index c4a1cee37a74..ea651ae573a7 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 113be21a7e77..483abfaf6400 100644
--- a/sw/inc/cmdid.h
+++ b/sw/inc/cmdid.h
@@ -318,6 +318,7 @@
#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..f367510b7a2f
--- /dev/null
+++ b/sw/qa/uibase/shells/textsh.cxx
@@ -0,0 +1,63 @@
+/* -*- 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:
+ SwDoc* pDoc = createSwDoc();
+ 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 a39f9187dff3..c22a1571d022 100644
--- a/sw/sdi/_textsh.sdi
+++ b/sw/sdi/_textsh.sdi
@@ -1831,6 +1831,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 ea549387516c..8e3db7463783 100644
--- a/sw/sdi/swriter.sdi
+++ b/sw/sdi/swriter.sdi
@@ -2582,6 +2582,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 be80f441b525..6f51980d6d0d 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))
@@ -1121,6 +1164,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