poedit.py
4.65 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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
#appModules/poedit.py
#A part of NonVisual Desktop Access (NVDA)
#Copyright (C) 2012-2013 Mesar Hameed, NV Access Limited
#This file is covered by the GNU General Public License.
#See the file COPYING for more details.
"""App module for Poedit.
"""
import api
import appModuleHandler
import controlTypes
import displayModel
import textInfos
import tones
import ui
from NVDAObjects.IAccessible import sysListView32
import windowUtils
import NVDAObjects.IAccessible
import winUser
def getPath(obj, ancestor):
"""Gets the path of the object with respect to its ancestor.
the ancestor is typically the forground object.
@returns: A list of coordinates relative to the ansestor.
@rtype: L{list}
"""
path = []
cancel = 0
if obj == stopObj: return []
p = obj
while p != stopObj:
counter = 0
while p.previous:
p = p.previous
counter += 1
cancel += 1
# Looks like we have an infinite ancestry, so get out
if cancel == 50: return [-1]
path.append(counter)
p = p.parent
path.reverse()
return path
def fetchObject(obj, path):
"""Fetch the child object described by path.
@returns: requested object if found, or None
@rtype: L{NVDAObjects.NVDAObject}
"""
path.reverse()
p = obj
while len(path) and p.firstChild:
p = p.firstChild
steps = path.pop()
i=0
while i<steps and p.next:
p = p.next
i += 1
# the path requests us to look for further siblings, but none found.
if i<steps: return None
# the path requests us to look for further children, but none found.
if len(path): return None
return p
class AppModule(appModuleHandler.AppModule):
def script_reportAutoCommentsWindow(self,gesture):
obj = fetchObject(api.getForegroundObject(), [2, 0, 1, 0, 1, 0, 1])
if obj and obj.windowControlID != 101:
try:
obj = obj.next.firstChild
except AttributeError:
obj = None
elif obj:
obj = obj.firstChild
if obj:
try:
ui.message(obj.name + " " + obj.value)
except:
# Translators: this message is reported when there are no
# notes for translators to be presented to the user in Poedit.
ui.message(_("No notes for translators."))
else:
# Translators: this message is reported when NVDA is unable to find
# the 'Notes for translators' window in poedit.
ui.message(_("Could not find Notes for translators window."))
# Translators: The description of an NVDA command for Poedit.
script_reportAutoCommentsWindow.__doc__ = _("Reports any notes for translators")
def script_reportCommentsWindow(self,gesture):
try:
obj = NVDAObjects.IAccessible.getNVDAObjectFromEvent(
windowUtils.findDescendantWindow(api.getForegroundObject().windowHandle, visible=True, controlID=104),
winUser.OBJID_CLIENT, 0)
except LookupError:
# Translators: this message is reported when NVDA is unable to find
# the 'comments' window in poedit.
ui.message(_("Could not find comment window."))
return None
try:
ui.message(obj.name + " " + obj.value)
except:
# Translators: this message is reported when there are no
# comments to be presented to the user in the translator
# comments window in poedit.
ui.message(_("No comment."))
# Translators: The description of an NVDA command for Poedit.
script_reportCommentsWindow.__doc__ = _("Reports any comments in the comments window")
__gestures = {
"kb:control+shift+c": "reportCommentsWindow",
"kb:control+shift+a": "reportAutoCommentsWindow",
}
def chooseNVDAObjectOverlayClasses(self, obj, clsList):
if "SysListView32" in obj.windowClassName and obj.role==controlTypes.ROLE_LISTITEM:
clsList.insert(0,PoeditListItem)
def event_NVDAObject_init(self, obj):
if obj.role == controlTypes.ROLE_EDITABLETEXT and controlTypes.STATE_MULTILINE in obj.states and obj.isInForeground:
# Oleacc often gets the name wrong.
# The label object is positioned just above the field on the screen.
l, t, w, h = obj.location
try:
obj.name = NVDAObjects.NVDAObject.objectFromPoint(l + 10, t - 10).name
except AttributeError:
pass
return
class PoeditListItem(sysListView32.ListItem):
def _get_isBold(self):
info=displayModel.DisplayModelTextInfo(self,position=textInfos.POSITION_FIRST)
info.expand(textInfos.UNIT_CHARACTER)
fields=info.getTextWithFields()
try:
return fields[0].field['bold']
except:
return False
def _get_name(self):
# If this item is untranslated or fuzzy, then it will be bold.
# Other info on the web says that the background color of
# the item changes, but this doesn't seem to be true while testing.
name = super(PoeditListItem,self).name
return "* " + name if self.isBold else name
def event_gainFocus(self):
super(sysListView32.ListItem, self).event_gainFocus()
if self.isBold:
tones.beep(550, 50)