sw/qa/uitest/navigator/tdf154521.py |  114 ++++++++++++++++++++++++++++++++++++
 sw/source/uibase/utlui/content.cxx  |   42 +++++++++++++
 2 files changed, 156 insertions(+)

New commits:
commit 8c234976c1d3536aab506a30487d8f5d26767c6a
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: Tue Jun 20 14:54:42 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>
    (cherry picked from commit 8e869f2c6a2d20bb47f263a9bcf9c2486c2ac240)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/153140
    Tested-by: Jenkins

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    :

Reply via email to