diff options
author | Miklos Vajna <vmiklos@collabora.com> | 2023-01-20 09:50:11 +0100 |
---|---|---|
committer | Miklos Vajna <vmiklos@collabora.com> | 2023-01-20 12:41:19 +0000 |
commit | a5a1ea2f7d784c5c6c33f332ba61aceb7af3eca4 (patch) | |
tree | 6aec97d73480ce3f9f47c32ceb8d62a08bfec6f5 | |
parent | 675a3e3d545c5811c35bbd189ff0a241a83443d0 (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.
Change-Id: Ib00a8f592ddbb77c5e8e08ff94bb0eebfcf7cea8
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/145870
Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
Tested-by: Jenkins
-rw-r--r-- | sw/CppunitTest_sw_uibase_shells.mk | 1 | ||||
-rw-r--r-- | sw/inc/cmdid.h | 1 | ||||
-rw-r--r-- | sw/qa/uibase/shells/textsh.cxx | 64 | ||||
-rw-r--r-- | sw/sdi/_textsh.sdi | 6 | ||||
-rw-r--r-- | sw/sdi/swriter.sdi | 14 | ||||
-rw-r--r-- | sw/source/uibase/shells/textsh1.cxx | 50 |
6 files changed, 136 insertions, 0 deletions
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 02d78f338851..ef1cdceec964 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 e7b5735a71ca..d8ec5afef933 100644 --- a/sw/sdi/_textsh.sdi +++ b/sw/sdi/_textsh.sdi @@ -1848,6 +1848,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 8b0f7b2364a7..873cab508584 100644 --- a/sw/sdi/swriter.sdi +++ b/sw/sdi/swriter.sdi @@ -2616,6 +2616,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 e887cad14b99..3ef16213576c 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)) @@ -1128,6 +1171,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 |