summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sw/inc/IDocumentMarkAccess.hxx2
-rw-r--r--sw/qa/uibase/uno/uno.cxx33
-rw-r--r--sw/source/core/doc/docbm.cxx23
-rw-r--r--sw/source/core/inc/MarkManager.hxx1
-rw-r--r--sw/source/uibase/uno/loktxdoc.cxx44
5 files changed, 101 insertions, 2 deletions
diff --git a/sw/inc/IDocumentMarkAccess.hxx b/sw/inc/IDocumentMarkAccess.hxx
index 93690fb2b305..20f876d16495 100644
--- a/sw/inc/IDocumentMarkAccess.hxx
+++ b/sw/inc/IDocumentMarkAccess.hxx
@@ -313,6 +313,8 @@ class IDocumentMarkAccess
*/
virtual const_iterator_t findFirstBookmarkStartsAfter(const SwPosition& rPos) const =0;
+ /// Get the innermost bookmark that contains rPos.
+ virtual sw::mark::IMark* getBookmarkFor(const SwPosition& rPos) const = 0;
// Fieldmarks
/** returns a STL-like random access iterator to the begin of the sequence of fieldmarks.
diff --git a/sw/qa/uibase/uno/uno.cxx b/sw/qa/uibase/uno/uno.cxx
index 4b21bca0bb0c..d2be66457b81 100644
--- a/sw/qa/uibase/uno/uno.cxx
+++ b/sw/qa/uibase/uno/uno.cxx
@@ -442,6 +442,39 @@ CPPUNIT_TEST_FIXTURE(SwUibaseUnoTest, testGetSections)
CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), aTree.get_child("sections").count(""));
}
+CPPUNIT_TEST_FIXTURE(SwUibaseUnoTest, testGetBookmark)
+{
+ // Given a document with a bookmark:
+ createSwDoc();
+ uno::Sequence<css::beans::PropertyValue> aArgs = {
+ comphelper::makePropertyValue("Bookmark", uno::Any(OUString("ZOTERO_BREF_1"))),
+ comphelper::makePropertyValue("BookmarkText", uno::Any(OUString("<p>aaa</p><p>bbb</p>"))),
+ };
+ dispatchCommand(mxComponent, ".uno:InsertBookmark", aArgs);
+
+ // When stepping into the bookmark with the cursor and getting the command value for
+ // .uno:Bookmark:
+ SwDoc* pDoc = getSwDoc();
+ SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
+ pWrtShell->SttEndDoc(/*bStt=*/false);
+ pWrtShell->Left(SwCursorSkipMode::Chars, /*bSelect=*/false, 1, /*bBasicCall=*/false);
+ tools::JsonWriter aJsonWriter;
+ std::string_view aCommand(".uno:Bookmark?namePrefix=ZOTERO_BREF_");
+ auto pXTextDocument = dynamic_cast<SwXTextDocument*>(mxComponent.get());
+ pXTextDocument->getCommandValues(aJsonWriter, aCommand);
+
+ // Then make sure we find the inserted bookmark:
+ std::unique_ptr<char[], o3tl::free_delete> pJSON(aJsonWriter.extractData());
+ std::stringstream aStream(pJSON.get());
+ boost::property_tree::ptree aTree;
+ boost::property_tree::read_json(aStream, aTree);
+ boost::property_tree::ptree aBookmark = aTree.get_child("bookmark");
+ // Without the accompanying fix in place, this test would have failed with:
+ // - No such node (bookmark)
+ // i.e. the returned JSON was an empty object.
+ CPPUNIT_ASSERT_EQUAL(std::string("ZOTERO_BREF_1"), aBookmark.get<std::string>("name"));
+}
+
CPPUNIT_PLUGIN_IMPLEMENT();
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/doc/docbm.cxx b/sw/source/core/doc/docbm.cxx
index 8e4d2ef72e95..7152c2a2314a 100644
--- a/sw/source/core/doc/docbm.cxx
+++ b/sw/source/core/doc/docbm.cxx
@@ -1437,6 +1437,29 @@ namespace sw::mark
return dynamic_cast<IFieldmark*>(pFieldmark);
}
+ IMark* MarkManager::getBookmarkFor(const SwPosition& rPos) const
+ {
+ auto it = std::find_if(m_vBookmarks.begin(), m_vBookmarks.end(),
+ [&rPos](const sw::mark::MarkBase* pMark)
+ { return pMark->IsCoveringPosition(rPos); });
+ if (it == m_vBookmarks.end())
+ {
+ return nullptr;
+ }
+ sw::mark::IMark* pBookmark = *it;
+ for (; it != m_vBookmarks.end() && (*it)->GetMarkStart() <= rPos; ++it)
+ {
+ // Find the innermost bookmark.
+ if (rPos < (*it)->GetMarkEnd()
+ && (pBookmark->GetMarkStart() < (*it)->GetMarkStart()
+ || (*it)->GetMarkEnd() < pBookmark->GetMarkEnd()))
+ {
+ pBookmark = *it;
+ }
+ }
+ return pBookmark;
+ }
+
void MarkManager::deleteFieldmarkAt(const SwPosition& rPos)
{
auto const pFieldmark = dynamic_cast<Fieldmark*>(getFieldmarkAt(rPos));
diff --git a/sw/source/core/inc/MarkManager.hxx b/sw/source/core/inc/MarkManager.hxx
index d362036b5464..1599996ae055 100644
--- a/sw/source/core/inc/MarkManager.hxx
+++ b/sw/source/core/inc/MarkManager.hxx
@@ -88,6 +88,7 @@ namespace sw::mark {
virtual sal_Int32 getBookmarksCount() const override;
virtual const_iterator_t findBookmark(const OUString& rName) const override;
virtual const_iterator_t findFirstBookmarkStartsAfter(const SwPosition& rPos) const override;
+ virtual ::sw::mark::IMark* getBookmarkFor(const SwPosition& rPos) const override;
// Fieldmarks
virtual const_iterator_t getFieldmarksBegin() const override;
diff --git a/sw/source/uibase/uno/loktxdoc.cxx b/sw/source/uibase/uno/loktxdoc.cxx
index a2f5b3cdd131..44b72d4f1eae 100644
--- a/sw/source/uibase/uno/loktxdoc.cxx
+++ b/sw/source/uibase/uno/loktxdoc.cxx
@@ -230,6 +230,41 @@ void GetBookmarks(tools::JsonWriter& rJsonWriter, SwDocShell* pDocShell,
}
}
+/// Implements getCommandValues(".uno:Bookmark").
+///
+/// Parameters:
+///
+/// - namePrefix: bookmark name prefix to not return all bookmarks
+void GetBookmark(tools::JsonWriter& rJsonWriter, SwDocShell* pDocShell,
+ const std::map<OUString, OUString>& rArguments)
+{
+ OUString aNamePrefix;
+ {
+ auto it = rArguments.find("namePrefix");
+ if (it != rArguments.end())
+ {
+ aNamePrefix = it->second;
+ }
+ }
+
+ IDocumentMarkAccess& rIDMA = *pDocShell->GetDoc()->getIDocumentMarkAccess();
+ SwWrtShell* pWrtShell = pDocShell->GetWrtShell();
+ SwPosition& rCursor = *pWrtShell->GetCursor()->GetPoint();
+ sw::mark::IMark* pBookmark = rIDMA.getBookmarkFor(rCursor);
+ tools::ScopedJsonWriterNode aBookmark = rJsonWriter.startNode("bookmark");
+ if (!pBookmark)
+ {
+ return;
+ }
+
+ if (!pBookmark->GetName().startsWith(aNamePrefix))
+ {
+ return;
+ }
+
+ rJsonWriter.put("name", pBookmark->GetName());
+}
+
/// Implements getCommandValues(".uno:Fields").
///
/// Parameters:
@@ -326,8 +361,8 @@ void GetSections(tools::JsonWriter& rJsonWriter, SwDocShell* pDocShell,
bool SwXTextDocument::supportsCommand(std::u16string_view rCommand)
{
static const std::initializer_list<std::u16string_view> vForward
- = { u"TextFormFields", u"TextFormField", u"SetDocumentProperties",
- u"Bookmarks", u"Fields", u"Sections" };
+ = { u"TextFormFields", u"TextFormField", u"SetDocumentProperties", u"Bookmarks", u"Fields",
+ u"Sections", u"Bookmark" };
return std::find(vForward.begin(), vForward.end(), rCommand) != vForward.end();
}
@@ -342,6 +377,7 @@ void SwXTextDocument::getCommandValues(tools::JsonWriter& rJsonWriter, std::stri
static constexpr OStringLiteral aBookmarks(".uno:Bookmarks");
static constexpr OStringLiteral aFields(".uno:Fields");
static constexpr OStringLiteral aSections(".uno:Sections");
+ static constexpr OStringLiteral aBookmark(".uno:Bookmark");
INetURLObject aParser(OUString::fromUtf8(rCommand));
OUString aArguments = aParser.GetParam();
@@ -389,6 +425,10 @@ void SwXTextDocument::getCommandValues(tools::JsonWriter& rJsonWriter, std::stri
{
GetSections(rJsonWriter, m_pDocShell, aMap);
}
+ else if (o3tl::starts_with(rCommand, aBookmark))
+ {
+ GetBookmark(rJsonWriter, m_pDocShell, aMap);
+ }
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */