sw/qa/uitest/navigator/tdf154521.py | 114 ++++++++++++++++++++++++++++++++++++ sw/source/uibase/utlui/content.cxx | 42 +++++++++++++ 2 files changed, 156 insertions(+)
New commits: commit c5b1578784c7179bde458640d78e1384ef190a21 Author: László Németh <nem...@numbertext.org> AuthorDate: Thu Jun 15 23:36:20 2023 +0200 Commit: László Németh <nem...@numbertext.org> CommitDate: Fri Jun 16 11:16:21 2023 +0200 tdf#154521 sw navigator: allow to query selected bookmark via UNO If the hidden title of SwNavigatorPanel was emptied via UNO XPanel interface, store the name of the selected bookmark there. This allows to query the selected bookmark using UNO e.g. in add-ons, i.e. to disambiguate when multiple bookmarks are there on the selected text range. Note: this is a workaround because getDialog() of XPanel is not implemented for SwNavigatorPanel. Follow-up to commit c4a58634753a84b09f20f7271d6525a6656522d3 "tdf#154545 sw Navigator: select & track nested bookmarks" and commit 6eb1d540a1e599aa4fe0a321eddb9cc22e0546d3 "tdf#154521 sw Navigator: fix selection change event of bookmark". Change-Id: I94f79daf59516331155e0b36502821c769771207 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/153162 Tested-by: László Németh <nem...@numbertext.org> Reviewed-by: László Németh <nem...@numbertext.org> diff --git a/sw/qa/uitest/navigator/tdf154521.py b/sw/qa/uitest/navigator/tdf154521.py index ac3c21de3c56..7b2125646ec6 100644 --- a/sw/qa/uitest/navigator/tdf154521.py +++ b/sw/qa/uitest/navigator/tdf154521.py @@ -85,4 +85,118 @@ class tdf154521(UITestCase): self.xUITest.executeCommand(".uno:Sidebar") + def getTitle(self, document): + xController = document.getCurrentController() + xSidebar = xController.getSidebar() + xDecks = xSidebar.getDecks() + xNavigator = xDecks['NavigatorDeck'] + xPanels = xNavigator.getPanels() + xPanel = xPanels['SwNavigatorPanel'] + title = xPanel.getTitle() + # empty title of SwNavigatorPanel to allow to query the name of the selected bookmark + xPanel.setTitle("") + return title + + def test_query_selected_bookmark(self): + global selectionChangedResult + with self.ui_test.create_doc_in_start_center("writer") as xDoc: + + # click on the bookmark name in the Navigator + + xWriterDoc = self.xUITest.getTopFocusWindow() + xWriterEdit = xWriterDoc.getChild("writer_edit") + + self.xUITest.executeCommand(".uno:Sidebar") + xWriterEdit.executeAction("SIDEBAR", mkPropertyValues({"PANEL": "SwNavigatorPanel"})) + + xNavigatorPanel = xWriterEdit.getChild("NavigatorPanel") + xToolBar = xNavigatorPanel.getChild("content5") + xToolBar.executeAction("CLICK", mkPropertyValues({"POS": "0"})) # 'root' button + + # type "foo", and create 3 bookmarks on it + + self.xUITest.executeCommand(".uno:Escape") + + xDoc.Text.insertString(xDoc.Text.getStart(), "foo", False) + self.xUITest.executeCommand(".uno:SelectAll") + + for i in range(3): + with self.ui_test.execute_dialog_through_command(".uno:InsertBookmark", close_button="insert"): + pass + + # check selected bookmarks in Navigator + + xWriterEdit.executeAction("FOCUS", tuple()) + + xContentTree = xNavigatorPanel.getChild("contenttree") + + self.ui_test.wait_until_property_is_updated(xContentTree, "SelectEntryText", "Bookmark 1") + self.assertEqual(get_state_as_dict(xContentTree)["SelectEntryText"], "Bookmark 1") + self.assertEqual(get_state_as_dict(xContentTree)["SelectionCount"], "1") + +# self.xUITest.executeCommand(".uno:Escape") + + # get the title of SwNavigatorPanel with emptying it to access to the selected bookmark + self.assertEqual(self.getTitle(xDoc), "Navigator") + # title was emptied + self.assertEqual(self.getTitle(xDoc), "") + + # Select nested bookmark in Navigator + + xContentTree.executeAction("TYPE", mkPropertyValues({"KEYCODE": "RETURN"})) + + # This jumped to Bookmark 1 after selection + self.ui_test.wait_until_property_is_updated(xContentTree, "SelectEntryText", "Bookmark 1") + self.assertEqual(get_state_as_dict(xContentTree)["SelectEntryText"], "Bookmark 1") + self.assertEqual(get_state_as_dict(xContentTree)["SelectionCount"], "1") + + # This was "Navigator" + self.assertEqual(self.getTitle(xDoc), "Bookmark 1") + + # Try the same selection with Bookmark 2 + xContentTree.executeAction("TYPE", mkPropertyValues({"KEYCODE": "UP"})) + self.ui_test.wait_until_property_is_updated(xContentTree, "SelectEntryText", "Bookmark 2") + self.assertEqual(get_state_as_dict(xContentTree)["SelectEntryText"], "Bookmark 2") + self.assertEqual(get_state_as_dict(xContentTree)["SelectionCount"], "1") + xContentTree.executeAction("TYPE", mkPropertyValues({"KEYCODE": "RETURN"})) + self.ui_test.wait_until_property_is_updated(xContentTree, "SelectEntryText", "Bookmark 2") + self.assertEqual(get_state_as_dict(xContentTree)["SelectEntryText"], "Bookmark 2") + self.assertEqual(get_state_as_dict(xContentTree)["SelectionCount"], "1") + + # This was "Navigator" + self.assertEqual(self.getTitle(xDoc), "Bookmark 2") + + # Try the same selection with Bookmark 3 + + # why we need this extra UP? + xContentTree.executeAction("TYPE", mkPropertyValues({"KEYCODE": "UP"})) + self.ui_test.wait_until_property_is_updated(xContentTree, "SelectEntryText", "Bookmark 2") + xContentTree.executeAction("TYPE", mkPropertyValues({"KEYCODE": "UP"})) + self.ui_test.wait_until_property_is_updated(xContentTree, "SelectEntryText", "Bookmark 3") + + self.assertEqual(get_state_as_dict(xContentTree)["SelectEntryText"], "Bookmark 3") + self.assertEqual(get_state_as_dict(xContentTree)["SelectionCount"], "1") + xContentTree.executeAction("TYPE", mkPropertyValues({"KEYCODE": "RETURN"})) + self.ui_test.wait_until_property_is_updated(xContentTree, "SelectEntryText", "Bookmark 3") + self.assertEqual(get_state_as_dict(xContentTree)["SelectEntryText"], "Bookmark 3") + self.assertEqual(get_state_as_dict(xContentTree)["SelectionCount"], "1") + + # This was "Navigator" + self.assertEqual(self.getTitle(xDoc), "Bookmark 3") + + # go to the previous item + + # why we need this extra UP? + xContentTree.executeAction("TYPE", mkPropertyValues({"KEYCODE": "UP"})) + self.ui_test.wait_until_property_is_updated(xContentTree, "SelectEntryText", "Bookmark 3") + xContentTree.executeAction("TYPE", mkPropertyValues({"KEYCODE": "UP"})) + self.ui_test.wait_until_property_is_updated(xContentTree, "SelectEntryText", "Bookmarks") + self.assertEqual(get_state_as_dict(xContentTree)["SelectEntryText"], "Bookmarks") + xContentTree.executeAction("TYPE", mkPropertyValues({"KEYCODE": "RETURN"})) + + # This was "Navigator" + self.assertEqual(self.getTitle(xDoc), "") + + self.xUITest.executeCommand(".uno:Sidebar") + # vim: set shiftwidth=4 softtabstop=4 expandtab: diff --git a/sw/source/uibase/utlui/content.cxx b/sw/source/uibase/utlui/content.cxx index 6d22bc53a91e..1284dc7a0d0e 100644 --- a/sw/source/uibase/utlui/content.cxx +++ b/sw/source/uibase/utlui/content.cxx @@ -71,6 +71,11 @@ #include <com/sun/star/text/XBookmarksSupplier.hpp> #include <com/sun/star/text/XTextEmbeddedObjectsSupplier.hpp> #include <com/sun/star/text/XTextFramesSupplier.hpp> +#include <com/sun/star/ui/XSidebarProvider.hpp> +#include <com/sun/star/ui/XDecks.hpp> +#include <com/sun/star/ui/XDeck.hpp> +#include <com/sun/star/ui/XPanels.hpp> +#include <com/sun/star/ui/XPanel.hpp> #include <svx/svdpage.hxx> #include <svx/svdview.hxx> #include <SwRewriter.hxx> @@ -5381,6 +5386,43 @@ void SwContentTree::GotoContent(const SwContent* pCnt) m_pActiveShell->GotoMark(pCnt->GetName()); m_pActiveShell->EndAction(); m_sSelectedItem = pCnt->GetName(); + + // If the hidden title of SwNavigatorPanel was emptied via UNO XPanel interface, + // store the name of the selected bookmark there. This allows to query the + // selected bookmark using UNO e.g. in add-ons, i.e. to disambiguate when + // multiple bookmarks are there on the selected text range. + // Note: this is a workaround because getDialog() of XPanel is not implemented + // for SwNavigatorPanel. + uno::Reference< frame::XModel > xModel = m_pActiveShell->GetView().GetDocShell()->GetBaseModel(); + + Reference<frame::XController2> xController( xModel->getCurrentController(), uno::UNO_QUERY); + if ( !xController.is() ) + break; + + Reference<ui::XSidebarProvider> xSidebarProvider = xController->getSidebar(); + if ( !xSidebarProvider.is() ) + break; + + Reference<ui::XDecks> xDecks = xSidebarProvider->getDecks(); + if ( !xDecks.is() ) + break; + + Reference<ui::XDeck> xDeck ( xDecks->getByName("NavigatorDeck"), uno::UNO_QUERY); + if ( !xDeck.is() ) + break; + + Reference<ui::XPanels> xPanels = xDeck->getPanels(); + if ( !xPanels.is() ) + break; + + if (xPanels->hasByName("SwNavigatorPanel")) + { + Reference<ui::XPanel> xPanel ( xPanels->getByName("SwNavigatorPanel"), uno::UNO_QUERY); + if ( !xPanel.is() || !xPanel->getTitle().isEmpty() ) + break; + + xPanel->setTitle( pCnt->GetName() ); + } } break; case ContentTypeId::REGION :