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]];