1 # -*- tab-width: 4; indent-tabs-mode: nil; py-indent-offset: 4 -*-
3 # This file is part of the LibreOffice project.
5 # This Source Code Form is subject to the terms of the Mozilla Public
6 # License, v. 2.0. If a copy of the MPL was not distributed with this
7 # file, You can obtain one at https://mozilla.org/MPL/2.0/.
12 from com
.sun
.star
.awt
import XKeyHandler
13 from com
.sun
.star
.awt
import XKeyListener
14 from com
.sun
.star
.awt
import XMouseClickHandler
15 from com
.sun
.star
.awt
import XMouseMotionHandler
16 from com
.sun
.star
.awt
import XMouseListener
17 from com
.sun
.star
.awt
import XMouseMotionListener
18 from com
.sun
.star
.accessibility
import AccessibleRole
22 This example illustrates how to register to keyboard or mouse events.
24 There are two families of interfaces for this, called Listeners and Handlers.
25 In many cases the Handlers are easier to use and provide more flexibility. But
26 sometimes it's necessary to use the Listeners, as being shown below.
28 The Listeners usually need to be added exactly to the correct widget. So this
29 example adds them recursively them to all widgets below the given one.
33 SOFFICE_CONNECTION_URI
= "uno:socket,host=localhost,port=2083;urp;StarOffice.ComponentContext"
37 # Connect to LibreOffice process
38 localComponentContext
= uno
.getComponentContext()
39 localServiceManager
= localComponentContext
.getServiceManager()
40 resolver
= localServiceManager
.createInstanceWithContext("com.sun.star.bridge.UnoUrlResolver", localComponentContext
)
41 remoteComponentContext
= resolver
.resolve(SOFFICE_CONNECTION_URI
)
43 # Get the currently opened view context.
44 remoteServiceManager
= remoteComponentContext
.getServiceManager()
45 desktop
= remoteServiceManager
.createInstance("com.sun.star.frame.Desktop")
46 xComponent
= desktop
.getCurrentComponent() # e.g. SwXTextDocument, ScModelObj, SdXImpressDocument
47 if "com.sun.star.document.OfficeDocument" not in xComponent
.getSupportedServiceNames():
48 print("No OfficeDocument opened.")
51 handler
= MyXKeyMouseClickMotionHandler("handler")
52 # Events in the document view area. Not in the surrounding UI.
53 xController
= xComponent
.getCurrentController() # xModel.getCurrentController()
54 xController
.addKeyHandler(handler
) # XUserInputInterception.addKeyHandler()
55 xController
.addMouseClickHandler(handler
) # XUserInputInterception.addMouseClickHandler()
57 listener
= MyXKeyMouseClickMotionHandler("listener")
58 # TODO: Register to e.value.Source of Handler events.
59 # That's the correct source.
60 xWindow
= xController
.ComponentWindow
61 # In writer we're usually looking for:
62 # xWindow.Windows[0].Windows[0]
63 recursive_windows("", xWindow
, lambda subXWindow
: (
64 subXWindow
.addKeyListener(listener
),
65 subXWindow
.addMouseListener(listener
),
66 #subXWindow.addMouseMotionListener(listener), # very much events
69 # Maybe the event handlers can also be registered via one of the objects
70 # this function iterates through. But currently this function just
71 # prints the accessible roles of the objects.
72 #recursive_acc_ctx("", xWindow.AccessibleContext.AccessibleParent);
73 #recursive_acc_ctx("", xWindow);
75 input("Waiting for events. Press Enter to quit...\n")
78 def recursive_acc_ctx(path
, obj
):
79 print("recursive_acc_ctx: " + path
+ find_accessible_role(obj
.getAccessibleContext().getAccessibleRole()))
80 for i
in range(obj
.getAccessibleContext().AccessibleChildCount
):
81 recursive_acc_ctx(path
+str(i
)+": ", obj
.getAccessibleContext().getAccessibleChild(i
))
84 def recursive_windows(path
, xWindow
, func
):
85 print("recursive_windows: " + path
+ find_accessible_role(xWindow
.getAccessibleContext().getAccessibleRole()))
88 windows
= xWindow
.getWindows() # XVclContainer.getWindows()
91 for i
in range(len(windows
)):
92 subXWindow
= windows
[i
]
93 recursive_windows(path
+str(i
)+": ", subXWindow
, func
)
96 def find_accessible_role(role_int
):
97 for role_name
in dir(AccessibleRole
):
98 if role_int
== eval("AccessibleRole." + role_name
):
102 class MyXKeyMouseClickMotionHandler(unohelper
.Base
, XKeyHandler
, XKeyListener
, XMouseClickHandler
, XMouseMotionHandler
, XMouseListener
, XMouseMotionListener
):
103 def __init__(self
, name
): # XKeyHandler, XKeyListener
105 def keyPressed(self
, e
): # XKeyHandler, XKeyListener
106 self
.key_evt(e
, "pressed")
107 return False # False: don't consume (run other event handlers)
108 def keyReleased(self
, e
):
109 self
.key_evt(e
, "released")
111 def mousePressed(self
, e
): # XMouseClickHandler, XMouseListener
112 self
.mouse_evt(e
, "pressed")
114 def mouseReleased(self
, e
): # XMouseClickHandler, XMouseListener
115 self
.mouse_evt(e
, "released")
117 def mouseEntered(self
, e
): # XMouseListener
118 self
.mouse_evt(e
, "entered")
120 def mouseExited(self
, e
): # XMouseListener
121 self
.mouse_evt(e
, "exited")
123 def mouseDragged(self
, e
): # XMouseMotionHandler, XMouseMotionListener
124 self
.mouse_evt(e
, "dragged")
126 def mouseMoved(self
, e
): # XMouseMotionHandler, XMouseMotionListener
127 self
.mouse_evt(e
, "moved")
130 def disposing(self
, s
):
131 print(self
.name
+ "# disposing")
132 def key_evt(self
, e
, action
):
133 #print(self.name + "# key "+action+": " + str(e)); # very much output
134 print(self
.name
+ "# key "+action
+" (code: " + str(e
.value
.KeyCode
.real
) + "): " + e
.value
.KeyChar
.value
)
135 def mouse_evt(self
, e
, action
):
136 #print(self.name + "# mouse "+action+": " + str(e)); # very much output
137 print(self
.name
+ "# mouse "+action
+": Modifiers: "+str(e
.value
.Modifiers
)+"; Buttons: "+str(e
.value
.Buttons
)+"; X: "+str(e
.value
.X
)+"; Y: "+str(e
.value
.Y
)+"; ClickCount: "+str(e
.value
.ClickCount
)+"; PopupTrigger: "+str(e
.value
.PopupTrigger
))
143 # vim: set shiftwidth=4 softtabstop=4 expandtab: