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

Reply via email to