diff options
-rw-r--r-- | sw/qa/uibase/shells/shells.cxx | 31 | ||||
-rw-r--r-- | sw/sdi/swriter.sdi | 2 | ||||
-rw-r--r-- | sw/source/uibase/shells/textsh1.cxx | 43 |
3 files changed, 75 insertions, 1 deletions
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]]; |