1
2
3
4
5
6
7 from comtypes import COMError
8 import IAccessibleHandler
9 import appModuleHandler
10 import controlTypes
11 import textInfos
12 import colors
13 from compoundDocuments import CompoundDocument
14 from NVDAObjects.JAB import JAB, JABTextInfo
15 from NVDAObjects.IAccessible import IAccessible, IA2TextTextInfo
16 from NVDAObjects.behaviors import EditableText
17 from logHandler import log
18
20 if len(coordString)<2 or ' ' in coordString or coordString[0].isdigit() or not coordString[-1].isdigit():
21 raise ValueError("bad coord string: %s"%coordString)
22 rowNum=0
23 colNum=0
24 coordStringRowStartIndex=None
25 for index,ch in enumerate(reversed(coordString)):
26 if not ch.isdigit():
27 coordStringRowStartIndex=len(coordString)-index
28 break
29 rowNum=int(coordString[coordStringRowStartIndex:])
30 for index,ch in enumerate(reversed(coordString[0:coordStringRowStartIndex])):
31 colNum+=((ord(ch.upper())-ord('A')+1)*(26**index))
32 return rowNum,colNum
33
41
75
76 -class SymphonyTextInfo(IA2TextTextInfo):
77
79 obj = self.obj
80 try:
81 startOffset,endOffset,attribsString=obj.IAccessibleTextObject.attributes(offset)
82 except COMError:
83 log.debugWarning("could not get attributes",exc_info=True)
84 return textInfos.FormatField(),(self._startOffset,self._endOffset)
85 formatField=textInfos.FormatField()
86 if not attribsString and offset>0:
87 try:
88 attribsString=obj.IAccessibleTextObject.attributes(offset-1)[2]
89 except COMError:
90 pass
91 if attribsString:
92 formatField.update(IAccessibleHandler.splitIA2Attribs(attribsString))
93
94 try:
95 escapement = int(formatField["CharEscapement"])
96 if escapement < 0:
97 textPos = "sub"
98 elif escapement > 0:
99 textPos = "super"
100 else:
101 textPos = "baseline"
102 formatField["text-position"] = textPos
103 except KeyError:
104 pass
105 try:
106 formatField["font-name"] = formatField["CharFontName"]
107 except KeyError:
108 pass
109 try:
110 formatField["font-size"] = "%spt" % formatField["CharHeight"]
111 except KeyError:
112 pass
113 try:
114 formatField["italic"] = formatField["CharPosture"] == "2"
115 except KeyError:
116 pass
117 try:
118 formatField["strikethrough"] = formatField["CharStrikeout"] == "1"
119 except KeyError:
120 pass
121 try:
122 underline = formatField["CharUnderline"]
123 if underline == "10":
124
125 formatField["invalid-spelling"] = True
126 else:
127 formatField["underline"] = underline != "0"
128 except KeyError:
129 pass
130 try:
131 formatField["bold"] = float(formatField["CharWeight"]) > 100
132 except KeyError:
133 pass
134 try:
135 color=formatField.pop('CharColor')
136 except KeyError:
137 color=None
138 if color:
139 formatField['color']=colors.RGB.fromString(color)
140 try:
141 backgroundColor=formatField.pop('CharBackColor')
142 except KeyError:
143 backgroundColor=None
144 if backgroundColor:
145 formatField['background-color']=colors.RGB.fromString(backgroundColor)
146
147
148 try:
149 obj.IAccessibleTextObject.QueryInterface(IAccessibleHandler.IAccessibleHypertext).hyperlinkIndex(offset)
150 formatField["link"] = True
151 except COMError:
152 pass
153
154 if offset == 0:
155
156 numbering = formatField.get("Numbering")
157 if numbering:
158 formatField["line-prefix"] = numbering.get("NumberingPrefix") or numbering.get("BulletChar")
159
160 if obj.hasFocus:
161
162
163 try:
164 docAttribs = obj.treeInterceptor.rootNVDAObject.IA2Attributes
165 except AttributeError:
166
167 pass
168 else:
169 try:
170 formatField["page-number"] = docAttribs["page-number"]
171 except KeyError:
172 pass
173 try:
174 formatField["line-number"] = docAttribs["line-number"]
175 except KeyError:
176 pass
177
178 return formatField,(startOffset,endOffset)
179
180 - def _getLineOffsets(self, offset):
181 start, end = super(SymphonyTextInfo, self)._getLineOffsets(offset)
182 if offset == 0 and start == 0 and end == 0:
183
184
185 return (0, 1)
186 return start, end
187
188 - def _getStoryLength(self):
189
190 return max(super(SymphonyTextInfo, self)._getStoryLength(), 1)
191
192 -class SymphonyText(IAccessible, EditableText):
193 TextInfo = SymphonyTextInfo
194
196 level = self.IA2Attributes.get("heading-level")
197 if level:
198 return {"level": int(level)}
199 return super(SymphonyText, self).positionInfo
200
213
215 """Removes redundant information that can be retreaved in other ways."""
216 value=None
217 description=None
218
220
222 role=obj.role
223 windowClassName=obj.windowClassName
224 if isinstance(obj, IAccessible) and windowClassName in ("SALTMPSUBFRAME", "SALSUBFRAME"):
225 if role==controlTypes.ROLE_TABLECELL:
226 clsList.insert(0, SymphonyTableCell)
227 elif hasattr(obj, "IAccessibleTextObject"):
228 clsList.insert(0, SymphonyText)
229 if role==controlTypes.ROLE_PARAGRAPH:
230 clsList.insert(0, SymphonyParagraph)
231 if isinstance(obj, JAB) and windowClassName == "SALFRAME":
232 if role in (controlTypes.ROLE_PANEL,controlTypes.ROLE_LABEL):
233 parent=obj.parent
234 if parent and parent.role==controlTypes.ROLE_TABLE:
235 clsList.insert(0,JAB_OOTableCell)
236 elif role==controlTypes.ROLE_TABLE:
237 clsList.insert(0,JAB_OOTable)
238
250