sw/qa/uibase/shells/shells.cxx      |   31 +++++++++++++++++++++++++
 sw/sdi/swriter.sdi                  |    2 -
 sw/source/uibase/shells/textsh1.cxx |   43 ++++++++++++++++++++++++++++++++++++
 3 files changed, 75 insertions(+), 1 deletion(-)

New commits:
commit fa82e151d80d15eeb6dfae434f1dbb3b68907188
Author:     Miklos Vajna <vmik...@collabora.com>
AuthorDate: Tue Dec 6 14:41:45 2022 +0100
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Tue Dec 6 18:08:58 2022 +0000

    sw, .uno:InsertBookmark: add a new BookmarkText parameter and accept HTML 
there
    
    There was already an UNO command to insert a new bookmark with the
    provided name, in a non-interactive way.
    
    What was missing is to allow specifying the bookmark text, which is to
    some extent not part of the bookmark, but e.g. the bookmark dialog
    allows editing that still.
    
    Add a new BookmarkText parameter to .uno:InsertBookmark, in case it's
    specified then we interpret this as HTML and we create the bookmark on
    the imported content, not simply at the current cursor position.
    
    This is similar to commit 1c2ef850db29beb369dcc89a58fc73416ecd9c5c (sw,
    .uno:TextFormField command: accept HTML in the FieldResult parameter,
    2022-11-16), but that was for the field mode, while this is for the
    bookmark mode of Zotero.
    
    Change-Id: I4928d173e197796d40fdb53f81e84b6bfd77cdc5
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/143736
    Reviewed-by: Miklos Vajna <vmik...@collabora.com>
    Tested-by: Jenkins

diff --git a/sw/qa/uibase/shells/shells.cxx b/sw/qa/uibase/shells/shells.cxx
index 01be5fda10b3..1f89211e52e8 100644
--- a/sw/qa/uibase/shells/shells.cxx
+++ b/sw/qa/uibase/shells/shells.cxx
@@ -377,6 +377,37 @@ CPPUNIT_TEST_FIXTURE(SwUibaseShellsTest, 
testUpdateFieldmarks)
     CPPUNIT_ASSERT_EQUAL(OUString("new result 1new result 2"), aActual);
 }
 
+CPPUNIT_TEST_FIXTURE(SwUibaseShellsTest, testInsertBookmark)
+{
+    // Given an empty document:
+    createSwDoc();
+    SwDoc* pDoc = getSwDoc();
+
+    // When inserting a bookmark with text:
+    OUString aExpectedBookmarkName("ZOTERO_BREF_GiQ7DAWQYWLy");
+    uno::Sequence<css::beans::PropertyValue> aArgs = {
+        comphelper::makePropertyValue("Bookmark", 
uno::Any(aExpectedBookmarkName)),
+        comphelper::makePropertyValue("BookmarkText", 
uno::Any(OUString("<p>aaa</p><p>bbb</p>"))),
+    };
+    dispatchCommand(mxComponent, ".uno:InsertBookmark", aArgs);
+
+    // Then make sure that we create a bookmark that covers that text:
+    IDocumentMarkAccess& rIDMA = *pDoc->getIDocumentMarkAccess();
+    CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(1), rIDMA.getBookmarksCount());
+    for (auto it = rIDMA.getBookmarksBegin(); it != rIDMA.getBookmarksEnd(); 
++it)
+    {
+        sw::mark::IMark* pMark = *it;
+        CPPUNIT_ASSERT_EQUAL(aExpectedBookmarkName, pMark->GetName());
+        SwPaM aPam(pMark->GetMarkStart(), pMark->GetMarkEnd());
+        OUString aActualResult = aPam.GetText();
+        // Without the accompanying fix in place, this test would have failed 
with:
+        // - Expected: aaa\nbbb
+        // - Actual  :
+        // i.e. no text was inserted, the bookmark was collapsed.
+        CPPUNIT_ASSERT_EQUAL(OUString("aaa\nbbb"), aActualResult);
+    }
+}
+
 CPPUNIT_PLUGIN_IMPLEMENT();
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/sdi/swriter.sdi b/sw/sdi/swriter.sdi
index 42e24f93e878..84ca0997f982 100644
--- a/sw/sdi/swriter.sdi
+++ b/sw/sdi/swriter.sdi
@@ -2537,7 +2537,7 @@ SfxVoidItem InsertAuthoritiesEntry 
FN_INSERT_AUTH_ENTRY_DLG
 ]
 
 SfxVoidItem InsertBookmark FN_INSERT_BOOKMARK
-(SfxStringItem Bookmark FN_INSERT_BOOKMARK)
+(SfxStringItem Bookmark FN_INSERT_BOOKMARK, SfxStringItem BookmarkText 
FN_PARAM_1)
 [
     AutoUpdate = FALSE,
     FastCall = FALSE,
diff --git a/sw/source/uibase/shells/textsh1.cxx 
b/sw/source/uibase/shells/textsh1.cxx
index bf3f65e677d8..3b556b677415 100644
--- a/sw/source/uibase/shells/textsh1.cxx
+++ b/sw/source/uibase/shells/textsh1.cxx
@@ -109,6 +109,7 @@
 #include <svtools/deeplcfg.hxx>
 #include <translatehelper.hxx>
 #endif // ENABLE_WASM_STRIP_EXTRA
+#include <IDocumentContentOperations.hxx>
 
 using namespace ::com::sun::star;
 using namespace com::sun::star::beans;
@@ -688,10 +689,52 @@ void SwTextShell::Execute(SfxRequest &rReq)
         }
         case FN_INSERT_BOOKMARK:
         {
+            const SfxStringItem* pBookmarkText = 
rReq.GetArg<SfxStringItem>(FN_PARAM_1);
+            SwPaM* pCursorPos = rWrtSh.GetCursor();
             if ( pItem )
             {
+                rWrtSh.StartAction();
                 OUString sName = static_cast<const 
SfxStringItem*>(pItem)->GetValue();
+
+                if (pBookmarkText)
+                {
+                    OUString aBookmarkText = pBookmarkText->GetValue();
+                    // Split node to remember where the start position is.
+                    bool bSuccess = 
rWrtSh.GetDoc()->getIDocumentContentOperations().SplitNode(
+                        *pCursorPos->GetPoint(), /*bChkTableStart=*/false);
+                    if (bSuccess)
+                    {
+                        SwPaM aBookmarkPam(*pCursorPos->GetPoint());
+                        aBookmarkPam.Move(fnMoveBackward, GoInContent);
+
+                        // Paste HTML content.
+                        SwTranslateHelper::PasteHTMLToPaM(
+                            rWrtSh, pCursorPos, aBookmarkText.toUtf8(), 
/*bSetSelection=*/true);
+                        if (pCursorPos->GetPoint()->GetContentIndex() == 0)
+                        {
+                            // The paste created a last empty text node, 
remove it.
+                            SwPaM aPam(*pCursorPos->GetPoint());
+                            aPam.SetMark();
+                            aPam.Move(fnMoveBackward, GoInContent);
+                            
rWrtSh.GetDoc()->getIDocumentContentOperations().DeleteAndJoin(aPam);
+                        }
+
+                        // Undo the above SplitNode().
+                        aBookmarkPam.SetMark();
+                        aBookmarkPam.Move(fnMoveForward, GoInContent);
+                        
rWrtSh.GetDoc()->getIDocumentContentOperations().DeleteAndJoin(
+                            aBookmarkPam);
+                        *aBookmarkPam.GetMark() = *pCursorPos->GetPoint();
+                        *pCursorPos = aBookmarkPam;
+                    }
+                }
+
                 rWrtSh.SetBookmark( vcl::KeyCode(), sName );
+                if (pBookmarkText)
+                {
+                    pCursorPos->DeleteMark();
+                }
+                rWrtSh.EndAction();
                 break;
             }
             [[fallthrough]];

Reply via email to