adobeFlash.py
3.69 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
#NVDAObjects/IAccessible/adobeFlash.py
#A part of NonVisual Desktop Access (NVDA)
#Copyright (C) 2009 NVDA Contributors <http://www.nvda-project.org/>
#This file is covered by the GNU General Public License.
#See the file COPYING for more details.
import winUser
import oleacc
from . import IAccessible, getNVDAObjectFromEvent
from NVDAObjects import NVDAObjectTextInfo
from NVDAObjects.behaviors import EditableTextWithoutAutoSelectDetection
from comtypes import COMError, IServiceProvider, hresult
from comtypes.gen.FlashAccessibility import ISimpleTextSelection, IFlashAccessibility
from logHandler import log
class InputTextFieldTextInfo(NVDAObjectTextInfo):
def _getStoryText(self):
return self.obj.value or ""
def _getRawSelectionOffsets(self):
try:
return self.obj.ISimpleTextSelectionObject.GetSelection()
except COMError, e:
if e.hresult == hresult.E_FAIL:
# The documentation says that an empty field should return 0 for both values, but instead, we seem to get E_FAIL.
# An empty field still has a valid caret.
return 0, 0
else:
raise RuntimeError
except AttributeError:
raise RuntimeError
def _getCaretOffset(self):
# We want the active (moving) end of the selection.
return self._getRawSelectionOffsets()[1]
def _getSelectionOffsets(self):
# This might be a backwards selection, but for now, we should always return the values in ascending order.
return sorted(self._getRawSelectionOffsets())
class InputTextField(EditableTextWithoutAutoSelectDetection, IAccessible):
TextInfo = InputTextFieldTextInfo
class Root(IAccessible):
def _get_presentationType(self):
return self.presType_content
def _get_treeInterceptorClass(self):
import virtualBuffers.adobeFlash
return virtualBuffers.adobeFlash.AdobeFlash
#Flash root client has broken accParent, force to return the flash root window root IAccessible
def _get_parent(self):
return getNVDAObjectFromEvent(self.windowHandle,0,0)
class PluginClientWithBrokenFocus(IAccessible):
"""The client of a Flash plugin with broken focus behaviour.
#2546: In Flash protected mode, the Flash content is in another window beneath the plugin window.
Unfortunately, Flash doesn't bother to set focus to this window.
To work around this, when focus hits this object, focus is forced to the child.
"""
def event_gainFocus(self):
try:
self.firstChild.firstChild.setFocus()
except AttributeError:
super(PluginClientWithBrokenFocus, self).event_gainFocus()
def findExtraOverlayClasses(obj, clsList):
"""Determine the most appropriate class if this is a Flash object.
This works similarly to L{NVDAObjects.NVDAObject.findOverlayClasses} except that it never calls any other findOverlayClasses method.
"""
iaRole = obj.IAccessibleRole
if obj.windowClassName == "GeckoPluginWindow" and iaRole == oleacc.ROLE_SYSTEM_CLIENT and obj.childCount == 1 and obj.firstChild.windowClassName == "GeckoFPSandboxChildWindow":
clsList.append(PluginClientWithBrokenFocus)
return
try:
servProv = obj.IAccessibleObject.QueryInterface(IServiceProvider)
except COMError:
return
# Check whether this is the Flash root accessible.
if iaRole == oleacc.ROLE_SYSTEM_CLIENT:
try:
servProv.QueryService(IFlashAccessibility._iid_, IFlashAccessibility)
clsList.append(Root)
except COMError:
pass
# If this is a client and IFlashAccessibility wasn't present, this is not a Flash object.
return
# Check whether this is a Flash input text field.
try:
# We have to fetch ISimpleTextSelectionObject in order to check whether this is an input text field, so store it on the instance.
obj.ISimpleTextSelectionObject = servProv.QueryService(ISimpleTextSelection._iid_, ISimpleTextSelection)
clsList.append(InputTextField)
except COMError:
pass