Skip to content

Commit fe7e42e

Browse files
authored
Merge 4c076b0 into d113c08
2 parents d113c08 + 4c076b0 commit fe7e42e

1 file changed

Lines changed: 43 additions & 3 deletions

File tree

source/appModules/devenv.py

Lines changed: 43 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
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

67
import objbase
78
import comtypes
@@ -14,11 +15,12 @@
1415
from comtypes.automation import IDispatch
1516
from NVDAObjects.window import DisplayModelEditableText
1617
from NVDAObjects.IAccessible import IAccessible
17-
from NVDAObjects.UIA import UIA
18+
from NVDAObjects.UIA import UIA, WpfTextView, UIATextInfo
1819
from enum import IntEnum
1920
import appModuleHandler
2021
import controlTypes
2122
import 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+
85125
class VsTextEditPaneTextInfo(textInfos.offsets.OffsetsTextInfo):
86126

87127
def _get__selectionObject(self):

0 commit comments

Comments
 (0)