11# A part of NonVisual Desktop Access (NVDA)
22# This file is covered by the GNU General Public License.
33# See the file COPYING for more details.
4- # Copyright (C) 2010-2019 NV Access Limited, Soronel Haetir, Babbage B.V., Francisco Del Roio
4+ # Copyright (C) 2010-2022 NV Access Limited, Soronel Haetir, Babbage B.V., Francisco Del Roio,
5+ # Leonard de Ruijter
56
67import objbase
78import comtypes
1415from comtypes .automation import IDispatch
1516from NVDAObjects .window import DisplayModelEditableText
1617from NVDAObjects .IAccessible import IAccessible
17- from NVDAObjects .UIA import UIA
18+ from NVDAObjects .UIA import UIA , WpfTextView , UIATextInfo
1819from enum import IntEnum
1920import appModuleHandler
2021import controlTypes
2122import threading
23+ import UIAHandler
2224
2325
2426# A few helpful constants
@@ -43,9 +45,12 @@ def __init__(self, *args, **kwargs):
4345 self .vsMajor , self .vsMinor = int (vsMajor ), int (vsMinor )
4446
4547 def chooseNVDAObjectOverlayClasses (self , obj , clsList ):
48+ if WpfTextView in clsList :
49+ clsList .remove (WpfTextView )
50+ clsList .insert (0 , VsWpfTextView )
4651 # Only use this overlay class if the top level automation object for the IDE can be retrieved,
4752 # as it will not work otherwise.
48- if obj .windowClassName == "VsTextEditPane" and self .DTE :
53+ elif obj .windowClassName == "VsTextEditPane" and self .DTE :
4954 try :
5055 clsList .remove (DisplayModelEditableText )
5156 except ValueError :
@@ -82,6 +87,41 @@ def _get_DTE(self):
8287 return DTE
8388
8489
90+ class VsWpfTextViewTextInfo (UIATextInfo ):
91+
92+ def _getLineNumberString (self , textRange ):
93+ # Visual Studio exposes line numbers as part of the actual text.
94+ # We want to store the line number in a format field instead.
95+ lineNumberRange = textRange .Clone ()
96+ lineNumberRange .MoveEndpointByRange (
97+ UIAHandler .TextPatternRangeEndpoint_End ,
98+ lineNumberRange ,
99+ UIAHandler .TextPatternRangeEndpoint_Start
100+ )
101+ return lineNumberRange .GetText (- 1 )
102+
103+ def _getFormatFieldAtRange (self , textRange , formatConfig , ignoreMixedValues = False ):
104+ formatField = super ()._getFormatFieldAtRange (textRange , formatConfig , ignoreMixedValues = ignoreMixedValues )
105+ if not formatField or not formatConfig ['reportLineNumber' ]:
106+ return formatField
107+ lineNumberStr = self ._getLineNumberString (textRange )
108+ if lineNumberStr :
109+ try :
110+ formatField .field ['line-number' ] = int (lineNumberStr )
111+ except ValueError :
112+ pass
113+ return formatField
114+
115+ def _getTextFromUIARange (self , textRange ):
116+ text = super ()._getTextFromUIARange (textRange )
117+ lineNumberStr = self ._getLineNumberString (textRange )
118+ return text [(0 if not lineNumberStr else len (lineNumberStr )):]
119+
120+
121+ class VsWpfTextView (WpfTextView ):
122+ TextInfo = VsWpfTextViewTextInfo
123+
124+
85125class VsTextEditPaneTextInfo (textInfos .offsets .OffsetsTextInfo ):
86126
87127 def _get__selectionObject (self ):
0 commit comments