sw/inc/cmdid.h | 1 sw/qa/uibase/shells/shells.cxx | 51 +++++++++++++++++++++++++ sw/sdi/_textsh.sdi | 6 ++ sw/sdi/swriter.sdi | 14 ++++++ sw/source/uibase/shells/textsh1.cxx | 73 ++++++++++++++++++++++++++++++++++++ 5 files changed, 145 insertions(+)
New commits: commit cc4f876d05837679caa8c86ffd8be8598b8f429e Author: Pranam Lashkari <[email protected]> AuthorDate: Wed Jan 11 08:14:55 2023 +0530 Commit: Miklos Vajna <[email protected]> CommitDate: Wed Jan 11 13:28:47 2023 +0000 sw: rename .uno:UpdateSections command fields renamed fields name in JSON to be consistent with section insertion and getter Signed-off-by: Pranam Lashkari <[email protected]> Change-Id: Icca0be155542b7dc6df1b29e6c7d4191db8659ac Reviewed-on: https://gerrit.libreoffice.org/c/core/+/145315 Tested-by: Jenkins CollaboraOffice <[email protected]> Reviewed-by: Miklos Vajna <[email protected]> diff --git a/sw/qa/uibase/shells/shells.cxx b/sw/qa/uibase/shells/shells.cxx index 3a7f51f4b537..78a4f339c41b 100644 --- a/sw/qa/uibase/shells/shells.cxx +++ b/sw/qa/uibase/shells/shells.cxx @@ -619,11 +619,11 @@ CPPUNIT_TEST_FIXTURE(SwUibaseShellsTest, testUpdateSections) "type": "[][]com.sun.star.beans.PropertyValue", "value": [ { - "Section": { + "RegionName": { "type": "string", "value": "ZOTERO_BIBL {} CSL_BIBLIOGRAPHY RNDnew" }, - "SectionText": { + "Content": { "type": "string", "value": "new content" } diff --git a/sw/source/uibase/shells/textsh1.cxx b/sw/source/uibase/shells/textsh1.cxx index 1d367594d2a4..817eb6bc1b95 100644 --- a/sw/source/uibase/shells/textsh1.cxx +++ b/sw/source/uibase/shells/textsh1.cxx @@ -419,7 +419,7 @@ void UpdateSections(SfxRequest& rReq, SwWrtShell& rWrtSh) } comphelper::SequenceAsHashMap aMap(aSections[nSectionIndex++]); - OUString aSectionName = aMap["Section"].get<OUString>(); + OUString aSectionName = aMap["RegionName"].get<OUString>(); if (aSectionName != pFormat->GetName()) { const_cast<SwSectionFormat*>(pFormat)->SetName(aSectionName, /*bBroadcast=*/true); @@ -440,7 +440,7 @@ void UpdateSections(SfxRequest& rReq, SwWrtShell& rWrtSh) rIDCO.DeleteAndJoin(*pCursorPos); rWrtSh.EndSelect(); - OUString aSectionText = aMap["SectionText"].get<OUString>(); + OUString aSectionText = aMap["Content"].get<OUString>(); SwTranslateHelper::PasteHTMLToPaM(rWrtSh, pCursorPos, aSectionText.toUtf8(), true); } } commit a6cb4d2e7b85727b5d7cb79359929b466d11c402 Author: Miklos Vajna <[email protected]> AuthorDate: Tue Jan 10 08:16:47 2023 +0100 Commit: Miklos Vajna <[email protected]> CommitDate: Wed Jan 11 13:28:36 2023 +0000 sw: add a new .uno:UpdateSections command There was LOK API to insert a new section with provided HTML content and to query it, but there was no LOK API to update such created section with new names/contents. This is needed in case Zotero wants to store citations with refmarks, in which case it wants to store the bibliography with sections. Introduce a .uno:UpdateSections UNO command that can do this: the sections will be renamed if necessary & the content will be updated. The content update is reasonably straightforward, because the section always contains at least one empty paragraph, so there is no danger in simply deleting the old content before inserting the new one. This is similar to babba472391d26aed68d7ac31c7a918c08e65256 (sw, UpdateFields: add new TypeName, NamePrefix and Fields parameters, 2023-01-04), but that was for refmarks / citations, this is for sections / bibliography. (cherry picked from commit 71a479afb7e9762de930361e6089e23ab8d4af74) Change-Id: Idde6d5ed1b0f25f40df502bb6b7e7ca590ef9151 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/145281 Tested-by: Jenkins CollaboraOffice <[email protected]> Reviewed-by: Justin Luth <[email protected]> Reviewed-by: Miklos Vajna <[email protected]> diff --git a/sw/inc/cmdid.h b/sw/inc/cmdid.h index 7ae4a76c3bff..1d42d0113e41 100644 --- a/sw/inc/cmdid.h +++ b/sw/inc/cmdid.h @@ -312,6 +312,7 @@ #define FN_TABLE_PASTE_ROW_BEFORE (FN_INSERT2 + 31) /* paste table as new table rows */ #define FN_TABLE_PASTE_COL_BEFORE (FN_INSERT2 + 32) /* paste table as new table columns */ #define FN_UPDATE_BOOKMARKS (FN_INSERT2 + 34) +#define FN_UPDATE_SECTIONS (FN_INSERT2 + 35) // 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 33f0d615b250..3a7f51f4b537 100644 --- a/sw/qa/uibase/shells/shells.cxx +++ b/sw/qa/uibase/shells/shells.cxx @@ -597,6 +597,57 @@ CPPUNIT_TEST_FIXTURE(SwUibaseShellsTest, testUpdateFieldmark) CPPUNIT_ASSERT_EQUAL(OUString("new result 1"), aActual); } +CPPUNIT_TEST_FIXTURE(SwUibaseShellsTest, testUpdateSections) +{ + // 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 RNDold"))), + comphelper::makePropertyValue("Content", uno::Any(OUString("old content"))), + }; + dispatchCommand(mxComponent, ".uno:InsertSection", aArgs); + + // When updating that section: + std::vector<beans::PropertyValue> aArgsVec = comphelper::JsonToPropertyValues(R"json( +{ + "SectionNamePrefix": { + "type": "string", + "value": "ZOTERO_BIBL" + }, + "Sections": { + "type": "[][]com.sun.star.beans.PropertyValue", + "value": [ + { + "Section": { + "type": "string", + "value": "ZOTERO_BIBL {} CSL_BIBLIOGRAPHY RNDnew" + }, + "SectionText": { + "type": "string", + "value": "new content" + } + } + ] + } +} +)json"); + aArgs = comphelper::containerToSequence(aArgsVec); + dispatchCommand(mxComponent, ".uno:UpdateSections", aArgs); + + // Then make sure that the section is updated: + SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell(); + pWrtShell->SttEndDoc(/*bStt=*/true); + pWrtShell->EndOfSection(/*bSelect=*/true); + SwCursor* pCursor = pWrtShell->GetCursor(); + OUString aActualResult = pCursor->GetText(); + // Without the accompanying fix in place, this test would have failed with: + // - Expected: new content + // - Actual : old content + // i.e. the content wasn't updated. + CPPUNIT_ASSERT_EQUAL(OUString("new content"), aActualResult); +} + CPPUNIT_PLUGIN_IMPLEMENT(); /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/sdi/_textsh.sdi b/sw/sdi/_textsh.sdi index 39d2b33f7821..a9b9eb998f8a 100644 --- a/sw/sdi/_textsh.sdi +++ b/sw/sdi/_textsh.sdi @@ -146,6 +146,12 @@ interface BaseText StateMethod = GetState ; DisableFlags="SfxDisableFlags::SwOnProtectedCursor"; ] + FN_UPDATE_SECTIONS + [ + ExecMethod = Execute ; + StateMethod = GetState ; + DisableFlags="SfxDisableFlags::SwOnProtectedCursor"; + ] FN_SET_REMINDER [ ExecMethod = Execute ; diff --git a/sw/sdi/swriter.sdi b/sw/sdi/swriter.sdi index 6e039b467379..ddcd53517aa0 100644 --- a/sw/sdi/swriter.sdi +++ b/sw/sdi/swriter.sdi @@ -2568,6 +2568,20 @@ SfxVoidItem UpdateBookmarks FN_UPDATE_BOOKMARKS GroupId = SfxGroupId::Insert; ] +SfxVoidItem UpdateSections FN_UPDATE_SECTIONS +(SfxStringItem SectionNamePrefix FN_PARAM_1, SfxUnoAnyItem Sections FN_PARAM_2) +[ + AutoUpdate = FALSE, + FastCall = FALSE, + ReadOnlyDoc = FALSE, + Toggle = FALSE, + Container = FALSE, + RecordAbsolute = FALSE, + RecordPerSet; + + GroupId = SfxGroupId::Insert; +] + SfxVoidItem SetReminder FN_SET_REMINDER [ diff --git a/sw/source/uibase/shells/textsh1.cxx b/sw/source/uibase/shells/textsh1.cxx index 2acf9b037602..1d367594d2a4 100644 --- a/sw/source/uibase/shells/textsh1.cxx +++ b/sw/source/uibase/shells/textsh1.cxx @@ -109,6 +109,7 @@ #include <translatehelper.hxx> #include <IDocumentContentOperations.hxx> #include <IDocumentUndoRedo.hxx> +#include <fmtcntnt.hxx> using namespace ::com::sun::star; using namespace com::sun::star::beans; @@ -381,6 +382,73 @@ OUString GetLocalURL(const SwWrtShell& rSh) return rLocalURL; } +void UpdateSections(SfxRequest& rReq, SwWrtShell& rWrtSh) +{ + OUString aSectionNamePrefix; + const SfxStringItem* pSectionNamePrefix = rReq.GetArg<SfxStringItem>(FN_PARAM_1); + if (pSectionNamePrefix) + { + aSectionNamePrefix = pSectionNamePrefix->GetValue(); + } + + uno::Sequence<beans::PropertyValues> aSections; + const SfxUnoAnyItem* pSections = rReq.GetArg<SfxUnoAnyItem>(FN_PARAM_2); + if (pSections) + { + pSections->GetValue() >>= aSections; + } + + rWrtSh.GetDoc()->GetIDocumentUndoRedo().StartUndo(SwUndoId::INSSECTION, nullptr); + rWrtSh.StartAction(); + + SwDoc* pDoc = rWrtSh.GetDoc(); + sal_Int32 nSectionIndex = 0; + const SwSectionFormats& rFormats = pDoc->GetSections(); + IDocumentContentOperations& rIDCO = pDoc->getIDocumentContentOperations(); + for (size_t i = 0; i < rFormats.size(); ++i) + { + const SwSectionFormat* pFormat = rFormats[i]; + if (!pFormat->GetName().startsWith(aSectionNamePrefix)) + { + continue; + } + + if (nSectionIndex >= aSections.getLength()) + { + break; + } + + comphelper::SequenceAsHashMap aMap(aSections[nSectionIndex++]); + OUString aSectionName = aMap["Section"].get<OUString>(); + if (aSectionName != pFormat->GetName()) + { + const_cast<SwSectionFormat*>(pFormat)->SetName(aSectionName, /*bBroadcast=*/true); + SwSectionData aSectionData(*pFormat->GetSection()); + aSectionData.SetSectionName(aSectionName); + pDoc->UpdateSection(i, aSectionData); + } + + const SwFormatContent& rContent = pFormat->GetContent(); + const SwNodeIndex* pContentNodeIndex = rContent.GetContentIdx(); + if (pContentNodeIndex) + { + SwPaM aSectionStart(SwPosition{*pContentNodeIndex}); + aSectionStart.Move(fnMoveForward, GoInContent); + SwPaM* pCursorPos = rWrtSh.GetCursor(); + *pCursorPos = aSectionStart; + rWrtSh.EndOfSection(/*bSelect=*/true); + rIDCO.DeleteAndJoin(*pCursorPos); + rWrtSh.EndSelect(); + + OUString aSectionText = aMap["SectionText"].get<OUString>(); + SwTranslateHelper::PasteHTMLToPaM(rWrtSh, pCursorPos, aSectionText.toUtf8(), true); + } + } + + rWrtSh.EndAction(); + rWrtSh.GetDoc()->GetIDocumentUndoRedo().EndUndo(SwUndoId::INSSECTION, nullptr); +} + void UpdateBookmarks(SfxRequest& rReq, SwWrtShell& rWrtSh) { if (rWrtSh.getIDocumentSettingAccess().get(DocumentSettingId::PROTECT_BOOKMARKS)) @@ -854,6 +922,11 @@ void SwTextShell::Execute(SfxRequest &rReq) } break; } + case FN_UPDATE_SECTIONS: + { + UpdateSections(rReq, rWrtSh); + break; + } case FN_SET_REMINDER: { // collect and sort navigator reminder names
