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 import ctypes
38 import objbase
39 from comtypes import IUnknown, IServiceProvider , GUID, COMMETHOD, HRESULT, BSTR
40 from ctypes import POINTER, c_int, c_short, c_ushort, c_ulong
41 import comtypes.client.dynamic
42 from comtypes.automation import IDispatch
43
44 from logHandler import log
45 import textInfos.offsets
46
47 from NVDAObjects.behaviors import EditableTextWithoutAutoSelectDetection
48 from NVDAObjects.window import Window
49
50 from NVDAObjects.window import DisplayModelEditableText
51
52 import appModuleHandler
53
54
55
56
57
58
59 VsRootWindowClassName="wndclass_desked_gsk"
60 VsTextEditPaneClassName="VsTextEditPane"
61
62 SVsTextManager = GUID('{F5E7E71D-1401-11D1-883B-0000F87579D2}')
63 VsVersion_None = 0
64 VsVersion_2002 = 1
65 VsVersion_2003 = 2
66 VsVersion_2005 = 3
67 VsVersion_2008 = 4
68
69
70
71
72
73
74
75
76
77
78
79
80 VsWindowTypeCommand = 15
81 VsWindowTypeDocument = 16
82 VsWindowTypeOutput = 17
83
84
85 SB_HORZ = 0
86 SB_VERT = 1
87
88
99
101
102 try:
103 if self._DTE:
104 return self._DTE
105 except AttributeError:
106 pass
107
108
109 DTEVersion = VsVersion_None
110 bctx = objbase.CreateBindCtx()
111 ROT = objbase.GetRunningObjectTable()
112 for mon in ROT:
113
114 displayName = mon.GetDisplayName(bctx, None)
115 if "!VisualStudio.DTE.9.0:%d"%self.processID==displayName:
116 DTEVersion=VsVersion_2008
117 elif "!VisualStudio.DTE.8.0:%d"%self.processID==displayName:
118 DTEVersion = VsVersion_2005
119 elif "!VisualStudio.DTE.7.1:%d"%self.processID==displayName:
120 DTEVersion = VsVersion_2003
121 elif "!VisualStudio.DTE:%d"%self.processID==displayName:
122 DTEVersion = VsVersion_2002
123
124 if DTEVersion != VsVersion_None:
125 self._DTEVersion = DTEVersion
126 self._DTE = comtypes.client.dynamic.Dispatch(ROT.GetObject(mon).QueryInterface(IDispatch))
127 break
128
129 else:
130
131 log.debugWarning("No top level automation object found")
132 self._DTE = None
133 self._DTEVersion = VsVersion_None
134
135
136 return self._DTE
137
138 - def _getTextManager(self):
139 try:
140 if self._textManager:
141 return self._textManager
142 except AttributeError:
143 pass
144 serviceProvider = self._getDTE().QueryInterface(comtypes.IServiceProvider)
145 self._textManager = serviceProvider.QueryService(SVsTextManager, IVsTextManager)
146 return self._textManager
147
148
149 -class VsTextEditPaneTextInfo(textInfos.offsets.OffsetsTextInfo):
151 log.error("An unsupported window type `%d' was encountered, please inform the NVDA development team." %type)
152 raise NotImplementedError
153
155 Selection = None
156 if self._window.Type == VsWindowTypeDocument:
157 Selection = self._window.Selection
158 elif self._window.Type == VsWindowTypeOutput:
159 Selection = self._window.Object.ActivePane.TextDocument.Selection
160 elif self._window.Type==VsWindowTypeCommand:
161 Selection = self._window.Object.TextDocument.Selection
162 else:
163 self._InformUnsupportedWindowType(self._window.Type)
164 return Selection
165
167 return self._getSelectionObject().ActivePoint.CreateEditPoint()
168
169 - def _getOffsetFromPoint(self,x,y):
170 yMinUnit, yMaxUnit, yVisible, yFirstVisible = self._textView.GetScrollInfo(SB_VERT)
171 hMinUnit, hMaxUnit, hVisible, hFirstVisible = self._textView.GetScrollInfo(SB_HORZ)
172
173
174 lineHeight = self._textView.GetLineHeight()
175 charWidth = self._window.Width / hVisible
176
177 offsetLine = (y - self._window.Top) / lineHeight + yFirstVisible
178 offsetChar = (x - self._window.Left) / charWidth + hFirstVisible
179 return self._textView.GetNearestPosition(offsetLine, offsetChar)[0]
180
181 - def __init__(self, obj, position):
182 self._window = obj._window
183 self._textView = obj._textView
184 super(VsTextEditPaneTextInfo, self).__init__(obj, position)
185
186 - def _getCaretOffset(self):
187 return self._createEditPoint().AbsoluteCharOffset
188
189 - def _setCaretOffset(self,offset):
190 self._getSelectionObject().MoveToAbsoluteOffset(offset)
191
192 - def _setSelectionOffsets(self,start,end):
193 Selection = self._getSelectionObject()
194 Selection.MoveToAbsoluteOffset(start)
195 Selection.MoveToAbsoluteOffset(end,True)
196
198 selection = self._getSelectionObject()
199 startPos = selection.ActivePoint.CreateEditPoint().AbsoluteCharOffset - 1
200 endPos = selection.AnchorPoint.CreateEditPoint().AbsoluteCharOffset - 1
201 return (startPos,endPos)
202
204 editPointStart = self._createEditPoint()
205 editPointStart.StartOfDocument()
206 if start:
207 editPointStart.MoveToAbsoluteOffset(start)
208 else:
209 start = 1
210 return editPointStart.GetText(end-start)
211
212 - def _getWordOffsets(self,startOffset):
213 editPointStart = self._createEditPoint()
214 editPointEnd = editPointStart.CreateEditPoint()
215 editPointEnd.WordRight()
216 return editPointStart.AbsoluteCharOffset,editPointEnd.AbsoluteCharOffset
217
218 - def _getLineOffsets(self,offset):
219 editPointStart = self._createEditPoint()
220 editPointStart.MoveToAbsoluteOffset(offset)
221 editPointStart.StartOfLine()
222 editPointEnd = editPointStart.CreateEditPoint()
223 editPointEnd.EndOfLine()
224 return (editPointStart.AbsoluteCharOffset,editPointEnd.AbsoluteCharOffset)
225
226 - def _getLineNumFromOffset(self,offset):
227 editPoint = self._createEditPoint()
228 editPoint.MoveToAbsoluteOffset(offset)
229 return editPoint.Line
230
231 - def _getStoryLength(self):
232 editPoint = self._createEditPoint()
233 editPoint.EndOfDocument()
234 return editPoint.AbsoluteCharOffset
235
236
237 -class VsTextEditPane(EditableTextWithoutAutoSelectDetection,Window):
238 TextInfo = VsTextEditPaneTextInfo
239
241 self._window = self.appModule._getDTE().ActiveWindow
242 self.location = (self._window.Top,self._window.Left,self._window.Width,self._window.Height)
243 self._textView = self.appModule._getTextManager().GetActiveView(True, None)
244
247
248
249 -class IVsTextView(IUnknown):
250 _case_insensitive_ = True
251 _iid_ = GUID('{BB23A14B-7C61-469A-9890-A95648CED5E6}')
252 _idlflags_ = []
253
254
255 -class IVsTextManager(comtypes.IUnknown):
256 _case_insensitive_ = True
257 _iid_ = GUID('{909F83E3-B3FC-4BBF-8820-64378744B39B}')
258 _idlflags_ = []
259
260 IVsTextManager._methods_ = [
261 COMMETHOD([], HRESULT, 'RegisterView',
262 ( ['in'], POINTER(IVsTextView), 'pView' ),
263 ( ['in'], POINTER(IUnknown), 'pBuffer' )),
264 COMMETHOD([], HRESULT, 'UnregisterView',
265 ( ['in'], POINTER(IVsTextView), 'pView' )),
266 COMMETHOD([], HRESULT, 'EnumViews',
267 ( ['in'], POINTER(IUnknown), 'pBuffer' ),
268 ( ['out'], POINTER(POINTER(IUnknown)), 'ppEnum' )),
269 COMMETHOD([], HRESULT, 'CreateSelectionAction',
270 ( ['in'], POINTER(IUnknown), 'pBuffer' ),
271 ( ['out'], POINTER(POINTER(IUnknown)), 'ppAction' )),
272 COMMETHOD([], HRESULT, 'MapFilenameToLanguageSID',
273 ( ['in'], POINTER(c_ushort), 'pszFileName' ),
274 ( ['out'], POINTER(GUID), 'pguidLangSID' )),
275 COMMETHOD([], HRESULT, 'GetRegisteredMarkerTypeID',
276 ( ['in'], POINTER(GUID), 'pguidMarker' ),
277 ( ['out'], POINTER(c_int), 'piMarkerTypeID' )),
278 COMMETHOD([], HRESULT, 'GetMarkerTypeInterface',
279 ( ['in'], c_int, 'iMarkerTypeID' ),
280 ( ['out'], POINTER(POINTER(IUnknown)), 'ppMarkerType' )),
281 COMMETHOD([], HRESULT, 'GetMarkerTypeCount',
282 ( ['out'], POINTER(c_int), 'piMarkerTypeCount' )),
283 COMMETHOD([], HRESULT, 'GetActiveView',
284 ( ['in'], c_int, 'fMustHaveFocus' ),
285 ( ['in'], POINTER(IUnknown), 'pBuffer' ),
286 ( ['out'], POINTER(POINTER(IVsTextView)), 'ppView' )),
287 COMMETHOD([], HRESULT, 'GetUserPreferences',
288 ( ['out'], POINTER(c_int), 'pViewPrefs' ),
289 ( ['out'], POINTER(c_int), 'pFramePrefs' ),
290 ( ['in', 'out'], POINTER(c_int), 'pLangPrefs' ),
291 ( ['in', 'out'], POINTER(c_int), 'pColorPrefs' )),
292 COMMETHOD([], HRESULT, 'SetUserPreferences',
293 ( ['in'], POINTER(c_int), 'pViewPrefs' ),
294 ( ['in'], POINTER(c_int), 'pFramePrefs' ),
295 ( ['in'], POINTER(c_int), 'pLangPrefs' ),
296 ( ['in'], POINTER(c_int), 'pColorPrefs' )),
297 COMMETHOD([], HRESULT, 'SetFileChangeAdvise',
298 ( ['in'], POINTER(c_ushort), 'pszFileName' ),
299 ( ['in'], c_int, 'fStart' )),
300 COMMETHOD([], HRESULT, 'SuspendFileChangeAdvise',
301 ( ['in'], POINTER(c_ushort), 'pszFileName' ),
302 ( ['in'], c_int, 'fSuspend' )),
303 COMMETHOD([], HRESULT, 'NavigateToPosition',
304 ( ['in'], POINTER(IUnknown), 'pBuffer' ),
305 ( ['in'], POINTER(GUID), 'guidDocViewType' ),
306 ( ['in'], c_int, 'iPos' ),
307 ( ['in'], c_int, 'iLen' )),
308 COMMETHOD([], HRESULT, 'NavigateToLineAndColumn',
309 ( ['in'], POINTER(IUnknown), 'pBuffer' ),
310 ( ['in'], POINTER(GUID), 'guidDocViewType' ),
311 ( ['in'], c_int, 'iStartRow' ),
312 ( ['in'], c_int, 'iStartIndex' ),
313 ( ['in'], c_int, 'iEndRow' ),
314 ( ['in'], c_int, 'iEndIndex' )),
315 COMMETHOD([], HRESULT, 'GetBufferSccStatus',
316 ( ['in'], POINTER(IUnknown), 'pBufData' ),
317 ( ['out'], POINTER(c_int), 'pbNonEditable' )),
318 COMMETHOD([], HRESULT, 'RegisterBuffer',
319 ( ['in'], POINTER(IUnknown), 'pBuffer' )),
320 COMMETHOD([], HRESULT, 'UnregisterBuffer',
321 ( ['in'], POINTER(IUnknown), 'pBuffer' )),
322 COMMETHOD([], HRESULT, 'EnumBuffers',
323 ( ['out'], POINTER(POINTER(IUnknown)), 'ppEnum' )),
324 COMMETHOD([], HRESULT, 'GetPerLanguagePreferences',
325 ( ['out'], POINTER(c_int), 'pLangPrefs' )),
326 COMMETHOD([], HRESULT, 'SetPerLanguagePreferences',
327 ( ['in'], POINTER(c_int), 'pLangPrefs' )),
328 COMMETHOD([], HRESULT, 'AttemptToCheckOutBufferFromScc',
329 ( ['in'], POINTER(IUnknown), 'pBufData' ),
330 ( ['out'], POINTER(c_int), 'pfCheckoutSucceeded' )),
331 COMMETHOD([], HRESULT, 'GetShortcutManager',
332 ( ['out'], POINTER(POINTER(IUnknown)), 'ppShortcutMgr' )),
333 COMMETHOD([], HRESULT, 'RegisterIndependentView',
334 ( ['in'], POINTER(IUnknown), 'punk' ),
335 ( ['in'], POINTER(IUnknown), 'pBuffer' )),
336 COMMETHOD([], HRESULT, 'UnregisterIndependentView',
337 ( ['in'], POINTER(IUnknown), 'punk' ),
338 ( ['in'], POINTER(IUnknown), 'pBuffer' )),
339 COMMETHOD([], HRESULT, 'IgnoreNextFileChange',
340 ( ['in'], POINTER(IUnknown), 'pBuffer' )),
341 COMMETHOD([], HRESULT, 'AdjustFileChangeIgnoreCount',
342 ( ['in'], POINTER(IUnknown), 'pBuffer' ),
343 ( ['in'], c_int, 'fIgnore' )),
344 COMMETHOD([], HRESULT, 'GetBufferSccStatus2',
345 ( ['in'], POINTER(c_ushort), 'pszFileName' ),
346 ( ['out'], POINTER(c_int), 'pbNonEditable' ),
347 ( ['out'], POINTER(c_int), 'piStatusFlags' )),
348 COMMETHOD([], HRESULT, 'AttemptToCheckOutBufferFromScc2',
349 ( ['in'], POINTER(c_ushort), 'pszFileName' ),
350 ( ['out'], POINTER(c_int), 'pfCheckoutSucceeded' ),
351 ( ['out'], POINTER(c_int), 'piStatusFlags' )),
352 COMMETHOD([], HRESULT, 'EnumLanguageServices',
353 ( ['out'], POINTER(POINTER(IUnknown)), 'ppEnum' )),
354 COMMETHOD([], HRESULT, 'EnumIndependentViews',
355 ( ['in'], POINTER(IUnknown), 'pBuffer' ),
356 ( ['out'], POINTER(POINTER(IUnknown)), 'ppEnum' )),
357 ]
358
359
360 IVsTextView._methods_ = [
361 COMMETHOD([], HRESULT, 'Initialize',
362 ( ['in'], POINTER(IUnknown), 'pBuffer' ),
363 ( ['in'], comtypes.wireHWND, 'hwndParent' ),
364 ( ['in'], c_ulong, 'InitFlags' ),
365 ( ['in'], POINTER(c_int), 'pInitView' )),
366 COMMETHOD([], HRESULT, 'CloseView'),
367 COMMETHOD([], HRESULT, 'GetCaretPos',
368 ( ['out'], POINTER(c_int), 'piLine' ),
369 ( ['out'], POINTER(c_int), 'piColumn' )),
370 COMMETHOD([], HRESULT, 'SetCaretPos',
371 ( ['in'], c_int, 'iLine' ),
372 ( ['in'], c_int, 'iColumn' )),
373 COMMETHOD([], HRESULT, 'GetSelectionSpan',
374 ( ['out'], POINTER(c_int), 'pSpan' )),
375 COMMETHOD([], HRESULT, 'GetSelection',
376 ( ['out'], POINTER(c_int), 'piAnchorLine' ),
377 ( ['out'], POINTER(c_int), 'piAnchorCol' ),
378 ( ['out'], POINTER(c_int), 'piEndLine' ),
379 ( ['out'], POINTER(c_int), 'piEndCol' )),
380 COMMETHOD([], HRESULT, 'SetSelection',
381 ( ['in'], c_int, 'iAnchorLine' ),
382 ( ['in'], c_int, 'iAnchorCol' ),
383 ( ['in'], c_int, 'iEndLine' ),
384 ( ['in'], c_int, 'iEndCol' )),
385 COMMETHOD([], c_int, 'GetSelectionMode'),
386 COMMETHOD([], HRESULT, 'SetSelectionMode',
387 ( ['in'], c_int, 'iSelMode' )),
388 COMMETHOD([], HRESULT, 'ClearSelection',
389 ( ['in'], c_int, 'fMoveToAnchor' )),
390 COMMETHOD([], HRESULT, 'CenterLines',
391 ( ['in'], c_int, 'iTopLine' ),
392 ( ['in'], c_int, 'iCount' )),
393 COMMETHOD([], HRESULT, 'GetSelectedText',
394 ( ['out'], POINTER(BSTR), 'pbstrText' )),
395 COMMETHOD([], HRESULT, 'GetSelectionDataObject',
396 ( ['out'], POINTER(POINTER(IUnknown)), 'ppIDataObject' )),
397 COMMETHOD([], HRESULT, 'GetTextStream',
398 ( ['in'], c_int, 'iTopLine' ),
399 ( ['in'], c_int, 'iTopCol' ),
400 ( ['in'], c_int, 'iBottomLine' ),
401 ( ['in'], c_int, 'iBottomCol' ),
402 ( ['out'], POINTER(BSTR), 'pbstrText' )),
403 COMMETHOD([], HRESULT, 'GetBuffer',
404 ( ['out'], POINTER(POINTER(IUnknown)), 'ppBuffer' )),
405 COMMETHOD([], HRESULT, 'SetBuffer',
406 ( ['in'], POINTER(IUnknown), 'pBuffer' )),
407 COMMETHOD([], comtypes.wireHWND, 'GetWindowHandle'),
408 COMMETHOD([], HRESULT, 'GetScrollInfo',
409 ( ['in'], c_int, 'iBar' ),
410 ( ['out'], POINTER(c_int), 'piMinUnit' ),
411 ( ['out'], POINTER(c_int), 'piMaxUnit' ),
412 ( ['out'], POINTER(c_int), 'piVisibleUnits' ),
413 ( ['out'], POINTER(c_int), 'piFirstVisibleUnit' )),
414 COMMETHOD([], HRESULT, 'SetScrollPosition',
415 ( ['in'], c_int, 'iBar' ),
416 ( ['in'], c_int, 'iFirstVisibleUnit' )),
417 COMMETHOD([], HRESULT, 'AddCommandFilter',
418 ( ['in'], POINTER(IUnknown), 'pNewCmdTarg' ),
419 ( ['out'], POINTER(POINTER(IUnknown)), 'ppNextCmdTarg' )),
420 COMMETHOD([], HRESULT, 'RemoveCommandFilter',
421 ( ['in'], POINTER(IUnknown), 'pCmdTarg' )),
422 COMMETHOD([], HRESULT, 'UpdateCompletionStatus',
423 ( ['in'], POINTER(IUnknown), 'pCompSet' ),
424 ( ['in'], c_ulong, 'dwFlags' )),
425 COMMETHOD([], HRESULT, 'UpdateTipWindow',
426 ( ['in'], POINTER(IUnknown), 'pTipWindow' ),
427 ( ['in'], c_ulong, 'dwFlags' )),
428 COMMETHOD([], HRESULT, 'GetWordExtent',
429 ( ['in'], c_int, 'iLine' ),
430 ( ['in'], c_int, 'iCol' ),
431 ( ['in'], c_ulong, 'dwFlags' ),
432 ( ['out'], POINTER(c_int), 'pSpan' )),
433 COMMETHOD([], HRESULT, 'RestrictViewRange',
434 ( ['in'], c_int, 'iMinLine' ),
435 ( ['in'], c_int, 'iMaxLine' ),
436 ( ['in'], POINTER(IUnknown), 'pClient' )),
437 COMMETHOD([], HRESULT, 'ReplaceTextOnLine',
438 ( ['in'], c_int, 'iLine' ),
439 ( ['in'], c_int, 'iStartCol' ),
440 ( ['in'], c_int, 'iCharsToReplace' ),
441 ( ['in'], POINTER(c_ushort), 'pszNewText' ),
442 ( ['in'], c_int, 'iNewLen' )),
443 COMMETHOD([], HRESULT, 'GetLineAndColumn',
444 ( ['in'], c_int, 'iPos' ),
445 ( ['out'], POINTER(c_int), 'piLine' ),
446 ( ['out'], POINTER(c_int), 'piIndex' )),
447 COMMETHOD([], HRESULT, 'GetNearestPosition',
448 ( ['in'], c_int, 'iLine' ),
449 ( ['in'], c_int, 'iCol' ),
450 ( ['out'], POINTER(c_int), 'piPos' ),
451 ( ['out'], POINTER(c_int), 'piVirtualSpaces' )),
452 COMMETHOD([], HRESULT, 'UpdateViewFrameCaption'),
453 COMMETHOD([], HRESULT, 'CenterColumns',
454 ( ['in'], c_int, 'iLine' ),
455 ( ['in'], c_int, 'iLeftCol' ),
456 ( ['in'], c_int, 'iColCount' )),
457 COMMETHOD([], HRESULT, 'EnsureSpanVisible',
458 ( ['in'], c_int, 'span' )),
459 COMMETHOD([], HRESULT, 'PositionCaretForEditing',
460 ( ['in'], c_int, 'iLine' ),
461 ( ['in'], c_int, 'cIndentLevels' )),
462 COMMETHOD([], HRESULT, 'GetPointOfLineColumn',
463 ( ['in'], c_int, 'iLine' ),
464 ( ['in'], c_int, 'iCol' ),
465 ( ['retval', 'out'], POINTER(ctypes.wintypes.tagPOINT), 'ppt' )),
466 COMMETHOD([], HRESULT, 'GetLineHeight',
467 ( ['retval', 'out'], POINTER(c_int), 'piLineHeight' )),
468 COMMETHOD([], HRESULT, 'HighlightMatchingBrace',
469 ( ['in'], c_ulong, 'dwFlags' ),
470 ( ['in'], c_ulong, 'cSpans' ),
471 ( ['in'], POINTER(c_int), 'rgBaseSpans' )),
472 COMMETHOD([], HRESULT, 'SendExplicitFocus'),
473 COMMETHOD([], HRESULT, 'SetTopLine',
474 ( ['in'], c_int, 'iBaseLine' )),
475 ]
476