We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Python 3 staging/Notepad++: obtainig font name fails because it is a bytes-like object
#9557 # Steps to reproduce:
1. Install Python 3 staging snapshot.
2. Run Notepad++ or any app that embeds Scintilla controls.
3. Try obtaining formatting info (NVDA+F).

### Actual behavior:
The following traceback is recorded:

```
ERROR - scriptHandler.executeScript (11:07:35.251):
error executing script: <bound method GlobalCommands.script_reportFormatting of <globalCommands.GlobalCommands object at 0x06B54FD0>> with gesture 'NVDA+f'
Traceback (most recent call last):
  File "scriptHandler.pyc", line 189, in executeScript
  File "globalCommands.pyc", line 1393, in script_reportFormatting
  File "globalCommands.pyc", line 1366, in _reportFormattingHelper
  File "textInfos\__init__.pyc", line 500, in getFormatFieldSpeech
  File "speech\__init__.pyc", line 1717, in getFormatFieldSpeech
TypeError: sequence item 0: expected str instance, bytes found
```
### Expected behavior:
No errors.

### System configuration
#### NVDA installed/portable/running from source:
Installed and portable

#### NVDA version:
Python 3 staging 17954

#### Windows version:
Windows 10 Version 1903

#### Name and version of other software in use when reproducing the issue:
notepad++ 7.6.6

#### Other information about your system:
None

### Other questions
#### Does the issue still occur after restarting your PC?
Yes

#### Have you tried any other versions of NVDA? If so, please report their behaviors.
Yes - master snapshot, 2019.1.1.


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `source/NVDAObjects/window/scintilla.py`
Content:
```
1 import ctypes
2 import IAccessibleHandler
3 import speech
4 import textInfos.offsets
5 import winKernel
6 import winUser
7 import globalVars
8 import controlTypes
9 import config
10 from . import Window
11 from .. import NVDAObjectTextInfo
12 from ..behaviors import EditableTextWithAutoSelectDetection
13 import locale
14 import watchdog
15 import eventHandler
16 import locationHelper
17 import textUtils
18 
19 # Window messages
20 SCI_POSITIONFROMPOINT=2022
21 SCI_POINTXFROMPOSITION=2164
22 SCI_POINTYFROMPOSITION=2165
23 SCI_GETTEXTRANGE=2162
24 SCI_GETTEXT=2182
25 SCI_GETTEXTLENGTH=2183
26 SCI_GETLENGTH=2006
27 SCI_GETCURRENTPOS=2008
28 SCI_GETANCHOR=2009
29 SCI_GOTOPOS=2025
30 SCI_SETCURRENTPOS=2141
31 SCI_GETSELECTIONSTART=2143
32 SCI_GETSELECTIONEND=2145
33 SCI_SETSEL=2160
34 SCI_GETLINEENDPOSITION=2136
35 SCI_GETLINECOUNT=2154
36 SCI_LINEFROMPOSITION=2166
37 SCI_POSITIONFROMLINE=2167
38 SCI_LINELENGTH=2350
39 SCI_GETSTYLEAT=2010
40 SCI_STYLEGETFONT=2486
41 SCI_STYLEGETSIZE=2485
42 SCI_STYLEGETBOLD=2483
43 SCI_STYLEGETITALIC=2484
44 SCI_STYLEGETUNDERLINE=2488
45 SCI_WORDSTARTPOSITION=2266
46 SCI_WORDENDPOSITION=2267
47 SC_WRAP_NONE=0
48 SCI_GETWRAPMODE=2269
49 SCI_GETCODEPAGE=2137
50 SCI_POSITIONAFTER=2418
51 
52 #constants
53 #: Represents an invalid position within a document.
54 INVALID_POSITION=-1
55 STYLE_DEFAULT=32
56 SC_CP_UTF8=65001
57 
58 class CharacterRangeStruct(ctypes.Structure):
59 	_fields_=[
60 		('cpMin',ctypes.c_long),
61 		('cpMax',ctypes.c_long),
62 	]
63 
64 class TextRangeStruct(ctypes.Structure):
65 	_fields_=[
66 		('chrg',CharacterRangeStruct),
67 		('lpstrText',ctypes.c_char_p),
68 	]
69 
70 class ScintillaTextInfo(textInfos.offsets.OffsetsTextInfo):
71 
72 	def _get_encoding(self):
73 		cp=watchdog.cancellableSendMessage(self.obj.windowHandle,SCI_GETCODEPAGE,0,0)
74 		if cp==SC_CP_UTF8:
75 			return "utf-8"
76 		else:
77 			return locale.getlocale()[1]
78 
79 	def _getOffsetFromPoint(self,x,y):
80 		x, y = winUser.ScreenToClient(self.obj.windowHandle, x, y)
81 		return watchdog.cancellableSendMessage(self.obj.windowHandle,SCI_POSITIONFROMPOINT,x,y)
82 
83 	def _getPointFromOffset(self,offset):
84 		point=locationHelper.Point(
85 			watchdog.cancellableSendMessage(self.obj.windowHandle,SCI_POINTXFROMPOSITION,None,offset),
86 			watchdog.cancellableSendMessage(self.obj.windowHandle,SCI_POINTYFROMPOSITION,None,offset)
87 		).toScreen(self.obj.windowHandle)
88 		if point.x is not None and point.y is not None:
89 			return point
90 		else:
91 			raise NotImplementedError
92 
93 	def _getFormatFieldAndOffsets(self,offset,formatConfig,calculateOffsets=True):
94 		style=watchdog.cancellableSendMessage(self.obj.windowHandle,SCI_GETSTYLEAT,offset,0)
95 		if calculateOffsets:
96 			#we need to manually see how far the style goes, limit to line
97 			lineStart,lineEnd=self._getLineOffsets(offset)
98 			startOffset=offset
99 			while startOffset>lineStart:
100 				curStyle=watchdog.cancellableSendMessage(self.obj.windowHandle,SCI_GETSTYLEAT,startOffset-1,0)
101 				if curStyle==style:
102 					startOffset-=1
103 				else:
104 					break
105 			endOffset=offset+1
106 			while endOffset<lineEnd:
107 				curStyle=watchdog.cancellableSendMessage(self.obj.windowHandle,SCI_GETSTYLEAT,endOffset,0)
108 				if curStyle==style:
109 					endOffset+=1
110 				else:
111 					break
112 		else:
113 			startOffset,endOffset=(self._startOffset,self._endOffset)
114 		formatField=textInfos.FormatField()
115 		if formatConfig["reportFontName"]:
116 			#To get font name, We need to allocate memory with in Scintilla's process, and then copy it out
117 			fontNameBuf=ctypes.create_string_buffer(32)
118 			internalBuf=winKernel.virtualAllocEx(self.obj.processHandle,None,len(fontNameBuf),winKernel.MEM_COMMIT,winKernel.PAGE_READWRITE)
119 			try:
120 				watchdog.cancellableSendMessage(self.obj.windowHandle,SCI_STYLEGETFONT,style, internalBuf)
121 				winKernel.readProcessMemory(self.obj.processHandle,internalBuf,fontNameBuf,len(fontNameBuf),None)
122 			finally:
123 				winKernel.virtualFreeEx(self.obj.processHandle,internalBuf,0,winKernel.MEM_RELEASE)
124 			formatField["font-name"]=fontNameBuf.value
125 		if formatConfig["reportFontSize"]:
126 			formatField["font-size"]="%spt"%watchdog.cancellableSendMessage(self.obj.windowHandle,SCI_STYLEGETSIZE,style,0)
127 		if formatConfig["reportLineNumber"]:
128 			formatField["line-number"]=self._getLineNumFromOffset(offset)+1
129 		if formatConfig["reportFontAttributes"]:
130 			formatField["bold"]=bool(watchdog.cancellableSendMessage(self.obj.windowHandle,SCI_STYLEGETBOLD,style,0))
131 			formatField["italic"]=bool(watchdog.cancellableSendMessage(self.obj.windowHandle,SCI_STYLEGETITALIC,style,0))
132 			formatField["underline"]=bool(watchdog.cancellableSendMessage(self.obj.windowHandle,SCI_STYLEGETUNDERLINE,style,0))
133 		return formatField,(startOffset,endOffset)
134 
135 	def _getCaretOffset(self):
136 		return watchdog.cancellableSendMessage(self.obj.windowHandle,SCI_GETCURRENTPOS,0,0)
137 
138 	def _setCaretOffset(self,offset):
139 		watchdog.cancellableSendMessage(self.obj.windowHandle,SCI_GOTOPOS,offset,0)
140 		# #5678: A caret event sometimes doesn't get fired when we do this,
141 		# so fake one just in case.
142 		eventHandler.executeEvent("caret", self.obj)
143 
144 	def _getSelectionOffsets(self):
145 		start=watchdog.cancellableSendMessage(self.obj.windowHandle,SCI_GETSELECTIONSTART,0,0)
146 		end=watchdog.cancellableSendMessage(self.obj.windowHandle,SCI_GETSELECTIONEND,0,0)
147 		return (start,end)
148 
149 	def _setSelectionOffsets(self,start,end):
150 		watchdog.cancellableSendMessage(self.obj.windowHandle,SCI_SETSEL,start,end)
151 
152 	def _getStoryText(self):
153 		if not hasattr(self,'_storyText'):
154 			storyLength=self._getStoryLength()
155 			self._storyText=self._getTextRange(0,storyLength)
156 		return self._storyText
157 
158 	def _getStoryLength(self):
159 		if not hasattr(self,'_storyLength'):
160 			self._storyLength=watchdog.cancellableSendMessage(self.obj.windowHandle,SCI_GETTEXTLENGTH,0,0)
161 		return self._storyLength
162 
163 	def _getLineCount(self):
164 		return watchdog.cancellableSendMessage(self.obj.windowHandle,SCI_GETLINECOUNT,0,0)
165 
166 	def _getTextRange(self,start,end):
167 		bufLen = (end - start) + 1
168 		textRange = TextRangeStruct()
169 		textRange.chrg.cpMin = start
170 		textRange.chrg.cpMax = end
171 		processHandle = self.obj.processHandle
172 		internalBuf = winKernel.virtualAllocEx(processHandle, None, bufLen, winKernel.MEM_COMMIT, winKernel.PAGE_READWRITE)
173 		try:
174 			textRange.lpstrText = internalBuf
175 			internalTextRange = winKernel.virtualAllocEx(processHandle, None, ctypes.sizeof(textRange), winKernel.MEM_COMMIT, winKernel.PAGE_READWRITE)
176 			try:
177 				winKernel.writeProcessMemory(processHandle, internalTextRange, ctypes.byref(textRange), ctypes.sizeof(textRange), None)
178 				numBytes = watchdog.cancellableSendMessage(self.obj.windowHandle, SCI_GETTEXTRANGE, 0, internalTextRange)
179 			finally:
180 				winKernel.virtualFreeEx(processHandle, internalTextRange, 0, winKernel.MEM_RELEASE)
181 			buf = ctypes.create_string_buffer(bufLen)
182 			winKernel.readProcessMemory(processHandle, internalBuf, buf, bufLen, None)
183 		finally:
184 			winKernel.virtualFreeEx(processHandle, internalBuf, 0, winKernel.MEM_RELEASE)
185 		return textUtils.getTextFromRawBytes(buf.raw, numChars=numBytes, encoding=self.encoding, errorsFallback="surrogateescape")
186 
187 	def _getWordOffsets(self,offset):
188 		start=watchdog.cancellableSendMessage(self.obj.windowHandle,SCI_WORDSTARTPOSITION,offset,0)
189 		end=watchdog.cancellableSendMessage(self.obj.windowHandle,SCI_WORDENDPOSITION,start,0)
190 		if end<=offset:
191 			start=end
192 			end=watchdog.cancellableSendMessage(self.obj.windowHandle,SCI_WORDENDPOSITION,offset,0)
193 		return [start,end]
194 
195 	def _getLineNumFromOffset(self,offset):
196 		return watchdog.cancellableSendMessage(self.obj.windowHandle,SCI_LINEFROMPOSITION,offset,0)
197 
198 	def _getLineOffsets(self,offset):
199 		if watchdog.cancellableSendMessage(self.obj.windowHandle,SCI_GETWRAPMODE,None,None)!=SC_WRAP_NONE:
200 			# Lines in Scintilla refer to document lines, not wrapped lines.
201 			# There's no way to retrieve wrapped lines, so use screen coordinates.
202 			y = self._getPointFromOffset(offset).y
203 			location=self.obj.location
204 			start = self._getOffsetFromPoint(location.left, y)
205 			end=self._getOffsetFromPoint(location.right, y)
206 			# If this line wraps to the next line,
207 			# end is the first offset of the next line.
208 			if self._getPointFromOffset(end).y==y:
209 				# This is the end of the document line.
210 				# Include the EOL characters in the returned offsets.
211 				end=watchdog.cancellableSendMessage(self.obj.windowHandle,SCI_POSITIONAFTER,end,None)
212 			return (start,end)
213 
214 		line=watchdog.cancellableSendMessage(self.obj.windowHandle,SCI_LINEFROMPOSITION,offset,0)
215 		start=watchdog.cancellableSendMessage(self.obj.windowHandle,SCI_POSITIONFROMLINE,line,0)
216 		end=start+watchdog.cancellableSendMessage(self.obj.windowHandle,SCI_LINELENGTH,line,0)
217 		return (start,end)
218 
219 	def _getParagraphOffsets(self,offset):
220 		return self._getLineOffsets(offset)
221 
222 	def _getCharacterOffsets(self,offset):
223 		if offset>=self._getStoryLength(): return offset,offset+1
224 		end=watchdog.cancellableSendMessage(self.obj.windowHandle,SCI_POSITIONAFTER,offset,0)
225 		start=offset
226 		tempOffset=offset-1
227 		
228 		while tempOffset > INVALID_POSITION:
229 			start=watchdog.cancellableSendMessage(self.obj.windowHandle,SCI_POSITIONAFTER,tempOffset,0)
230 			if start<end:
231 				break
232 			elif tempOffset==0:
233 				start=tempOffset
234 				break
235 			else:
236 				tempOffset-=1
237 		return [start,end]
238 
239 
240 #The Scintilla NVDA object, inherists the generic MSAA NVDA object
241 class Scintilla(EditableTextWithAutoSelectDetection, Window):
242 
243 	TextInfo=ScintillaTextInfo
244 
245 #The name of the object is gotten by the standard way of getting a window name, can't use MSAA name (since it contains all the text)
246 	def _get_name(self):
247 		return winUser.getWindowText(self.windowHandle)
248 
249 #The role of the object should be editable text
250 	def _get_role(self):
251 		return controlTypes.ROLE_EDITABLETEXT
252 
253 	def _get_states(self):
254 		states = super(Scintilla, self)._get_states()
255 		# Scintilla controls are always multiline.
256 		states.add(controlTypes.STATE_MULTILINE)
257 		return states
258
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/source/NVDAObjects/window/scintilla.py b/source/NVDAObjects/window/scintilla.py
--- a/source/NVDAObjects/window/scintilla.py
+++ b/source/NVDAObjects/window/scintilla.py
@@ -1,3 +1,8 @@
+#A part of NonVisual Desktop Access (NVDA)
+#Copyright (C) 2009-2019 NV Access Limited, Arnold Loubriat, Babbage B.V.
+#This file is covered by the GNU General Public License.
+#See the file COPYING for more details.
+
 import ctypes
 import IAccessibleHandler
 import speech
@@ -121,7 +126,7 @@
 				winKernel.readProcessMemory(self.obj.processHandle,internalBuf,fontNameBuf,len(fontNameBuf),None)
 			finally:
 				winKernel.virtualFreeEx(self.obj.processHandle,internalBuf,0,winKernel.MEM_RELEASE)
-			formatField["font-name"]=fontNameBuf.value
+			formatField["font-name"]=fontNameBuf.value.decode("utf-8")
 		if formatConfig["reportFontSize"]:
 			formatField["font-size"]="%spt"%watchdog.cancellableSendMessage(self.obj.windowHandle,SCI_STYLEGETSIZE,style,0)
 		if formatConfig["reportLineNumber"]:

{"golden_diff": "diff --git a/source/NVDAObjects/window/scintilla.py b/source/NVDAObjects/window/scintilla.py\n--- a/source/NVDAObjects/window/scintilla.py\n+++ b/source/NVDAObjects/window/scintilla.py\n@@ -1,3 +1,8 @@\n+#A part of NonVisual Desktop Access (NVDA)\r\n+#Copyright (C) 2009-2019 NV Access Limited, Arnold Loubriat, Babbage B.V.\r\n+#This file is covered by the GNU General Public License.\r\n+#See the file COPYING for more details.\r\n+\r\n import ctypes\r\n import IAccessibleHandler\r\n import speech\r\n@@ -121,7 +126,7 @@\n \t\t\t\twinKernel.readProcessMemory(self.obj.processHandle,internalBuf,fontNameBuf,len(fontNameBuf),None)\r\n \t\t\tfinally:\r\n \t\t\t\twinKernel.virtualFreeEx(self.obj.processHandle,internalBuf,0,winKernel.MEM_RELEASE)\r\n-\t\t\tformatField[\"font-name\"]=fontNameBuf.value\r\n+\t\t\tformatField[\"font-name\"]=fontNameBuf.value.decode(\"utf-8\")\r\n \t\tif formatConfig[\"reportFontSize\"]:\r\n \t\t\tformatField[\"font-size\"]=\"%spt\"%watchdog.cancellableSendMessage(self.obj.windowHandle,SCI_STYLEGETSIZE,style,0)\r\n \t\tif formatConfig[\"reportLineNumber\"]:\n", "issue": "Python 3 staging/Notepad++: obtainig font name fails because it is a bytes-like object\n#9557 # Steps to reproduce:\r\n1. Install Python 3 staging snapshot.\r\n2. Run Notepad++ or any app that embeds Scintilla controls.\r\n3. Try obtaining formatting info (NVDA+F).\r\n\r\n### Actual behavior:\r\nThe following traceback is recorded:\r\n\r\n```\r\nERROR - scriptHandler.executeScript (11:07:35.251):\r\nerror executing script: <bound method GlobalCommands.script_reportFormatting of <globalCommands.GlobalCommands object at 0x06B54FD0>> with gesture 'NVDA+f'\r\nTraceback (most recent call last):\r\n  File \"scriptHandler.pyc\", line 189, in executeScript\r\n  File \"globalCommands.pyc\", line 1393, in script_reportFormatting\r\n  File \"globalCommands.pyc\", line 1366, in _reportFormattingHelper\r\n  File \"textInfos\\__init__.pyc\", line 500, in getFormatFieldSpeech\r\n  File \"speech\\__init__.pyc\", line 1717, in getFormatFieldSpeech\r\nTypeError: sequence item 0: expected str instance, bytes found\r\n```\r\n### Expected behavior:\r\nNo errors.\r\n\r\n### System configuration\r\n#### NVDA installed/portable/running from source:\r\nInstalled and portable\r\n\r\n#### NVDA version:\r\nPython 3 staging 17954\r\n\r\n#### Windows version:\r\nWindows 10 Version 1903\r\n\r\n#### Name and version of other software in use when reproducing the issue:\r\nnotepad++ 7.6.6\r\n\r\n#### Other information about your system:\r\nNone\r\n\r\n### Other questions\r\n#### Does the issue still occur after restarting your PC?\r\nYes\r\n\r\n#### Have you tried any other versions of NVDA? If so, please report their behaviors.\r\nYes - master snapshot, 2019.1.1.\r\n\n", "before_files": [{"content": "import ctypes\r\nimport IAccessibleHandler\r\nimport speech\r\nimport textInfos.offsets\r\nimport winKernel\r\nimport winUser\r\nimport globalVars\r\nimport controlTypes\r\nimport config\r\nfrom . import Window\r\nfrom .. import NVDAObjectTextInfo\r\nfrom ..behaviors import EditableTextWithAutoSelectDetection\r\nimport locale\r\nimport watchdog\r\nimport eventHandler\r\nimport locationHelper\r\nimport textUtils\r\n\r\n# Window messages\r\nSCI_POSITIONFROMPOINT=2022\r\nSCI_POINTXFROMPOSITION=2164\r\nSCI_POINTYFROMPOSITION=2165\r\nSCI_GETTEXTRANGE=2162\r\nSCI_GETTEXT=2182\r\nSCI_GETTEXTLENGTH=2183\r\nSCI_GETLENGTH=2006\r\nSCI_GETCURRENTPOS=2008\r\nSCI_GETANCHOR=2009\r\nSCI_GOTOPOS=2025\r\nSCI_SETCURRENTPOS=2141\r\nSCI_GETSELECTIONSTART=2143\r\nSCI_GETSELECTIONEND=2145\r\nSCI_SETSEL=2160\r\nSCI_GETLINEENDPOSITION=2136\r\nSCI_GETLINECOUNT=2154\r\nSCI_LINEFROMPOSITION=2166\r\nSCI_POSITIONFROMLINE=2167\r\nSCI_LINELENGTH=2350\r\nSCI_GETSTYLEAT=2010\r\nSCI_STYLEGETFONT=2486\r\nSCI_STYLEGETSIZE=2485\r\nSCI_STYLEGETBOLD=2483\r\nSCI_STYLEGETITALIC=2484\r\nSCI_STYLEGETUNDERLINE=2488\r\nSCI_WORDSTARTPOSITION=2266\r\nSCI_WORDENDPOSITION=2267\r\nSC_WRAP_NONE=0\r\nSCI_GETWRAPMODE=2269\r\nSCI_GETCODEPAGE=2137\r\nSCI_POSITIONAFTER=2418\r\n\r\n#constants\r\n#: Represents an invalid position within a document.\r\nINVALID_POSITION=-1\r\nSTYLE_DEFAULT=32\r\nSC_CP_UTF8=65001\r\n\r\nclass CharacterRangeStruct(ctypes.Structure):\r\n\t_fields_=[\r\n\t\t('cpMin',ctypes.c_long),\r\n\t\t('cpMax',ctypes.c_long),\r\n\t]\r\n\r\nclass TextRangeStruct(ctypes.Structure):\r\n\t_fields_=[\r\n\t\t('chrg',CharacterRangeStruct),\r\n\t\t('lpstrText',ctypes.c_char_p),\r\n\t]\r\n\r\nclass ScintillaTextInfo(textInfos.offsets.OffsetsTextInfo):\r\n\r\n\tdef _get_encoding(self):\r\n\t\tcp=watchdog.cancellableSendMessage(self.obj.windowHandle,SCI_GETCODEPAGE,0,0)\r\n\t\tif cp==SC_CP_UTF8:\r\n\t\t\treturn \"utf-8\"\r\n\t\telse:\r\n\t\t\treturn locale.getlocale()[1]\r\n\r\n\tdef _getOffsetFromPoint(self,x,y):\r\n\t\tx, y = winUser.ScreenToClient(self.obj.windowHandle, x, y)\r\n\t\treturn watchdog.cancellableSendMessage(self.obj.windowHandle,SCI_POSITIONFROMPOINT,x,y)\r\n\r\n\tdef _getPointFromOffset(self,offset):\r\n\t\tpoint=locationHelper.Point(\r\n\t\t\twatchdog.cancellableSendMessage(self.obj.windowHandle,SCI_POINTXFROMPOSITION,None,offset),\r\n\t\t\twatchdog.cancellableSendMessage(self.obj.windowHandle,SCI_POINTYFROMPOSITION,None,offset)\r\n\t\t).toScreen(self.obj.windowHandle)\r\n\t\tif point.x is not None and point.y is not None:\r\n\t\t\treturn point\r\n\t\telse:\r\n\t\t\traise NotImplementedError\r\n\r\n\tdef _getFormatFieldAndOffsets(self,offset,formatConfig,calculateOffsets=True):\r\n\t\tstyle=watchdog.cancellableSendMessage(self.obj.windowHandle,SCI_GETSTYLEAT,offset,0)\r\n\t\tif calculateOffsets:\r\n\t\t\t#we need to manually see how far the style goes, limit to line\r\n\t\t\tlineStart,lineEnd=self._getLineOffsets(offset)\r\n\t\t\tstartOffset=offset\r\n\t\t\twhile startOffset>lineStart:\r\n\t\t\t\tcurStyle=watchdog.cancellableSendMessage(self.obj.windowHandle,SCI_GETSTYLEAT,startOffset-1,0)\r\n\t\t\t\tif curStyle==style:\r\n\t\t\t\t\tstartOffset-=1\r\n\t\t\t\telse:\r\n\t\t\t\t\tbreak\r\n\t\t\tendOffset=offset+1\r\n\t\t\twhile endOffset<lineEnd:\r\n\t\t\t\tcurStyle=watchdog.cancellableSendMessage(self.obj.windowHandle,SCI_GETSTYLEAT,endOffset,0)\r\n\t\t\t\tif curStyle==style:\r\n\t\t\t\t\tendOffset+=1\r\n\t\t\t\telse:\r\n\t\t\t\t\tbreak\r\n\t\telse:\r\n\t\t\tstartOffset,endOffset=(self._startOffset,self._endOffset)\r\n\t\tformatField=textInfos.FormatField()\r\n\t\tif formatConfig[\"reportFontName\"]:\r\n\t\t\t#To get font name, We need to allocate memory with in Scintilla's process, and then copy it out\r\n\t\t\tfontNameBuf=ctypes.create_string_buffer(32)\r\n\t\t\tinternalBuf=winKernel.virtualAllocEx(self.obj.processHandle,None,len(fontNameBuf),winKernel.MEM_COMMIT,winKernel.PAGE_READWRITE)\r\n\t\t\ttry:\r\n\t\t\t\twatchdog.cancellableSendMessage(self.obj.windowHandle,SCI_STYLEGETFONT,style, internalBuf)\r\n\t\t\t\twinKernel.readProcessMemory(self.obj.processHandle,internalBuf,fontNameBuf,len(fontNameBuf),None)\r\n\t\t\tfinally:\r\n\t\t\t\twinKernel.virtualFreeEx(self.obj.processHandle,internalBuf,0,winKernel.MEM_RELEASE)\r\n\t\t\tformatField[\"font-name\"]=fontNameBuf.value\r\n\t\tif formatConfig[\"reportFontSize\"]:\r\n\t\t\tformatField[\"font-size\"]=\"%spt\"%watchdog.cancellableSendMessage(self.obj.windowHandle,SCI_STYLEGETSIZE,style,0)\r\n\t\tif formatConfig[\"reportLineNumber\"]:\r\n\t\t\tformatField[\"line-number\"]=self._getLineNumFromOffset(offset)+1\r\n\t\tif formatConfig[\"reportFontAttributes\"]:\r\n\t\t\tformatField[\"bold\"]=bool(watchdog.cancellableSendMessage(self.obj.windowHandle,SCI_STYLEGETBOLD,style,0))\r\n\t\t\tformatField[\"italic\"]=bool(watchdog.cancellableSendMessage(self.obj.windowHandle,SCI_STYLEGETITALIC,style,0))\r\n\t\t\tformatField[\"underline\"]=bool(watchdog.cancellableSendMessage(self.obj.windowHandle,SCI_STYLEGETUNDERLINE,style,0))\r\n\t\treturn formatField,(startOffset,endOffset)\r\n\r\n\tdef _getCaretOffset(self):\r\n\t\treturn watchdog.cancellableSendMessage(self.obj.windowHandle,SCI_GETCURRENTPOS,0,0)\r\n\r\n\tdef _setCaretOffset(self,offset):\r\n\t\twatchdog.cancellableSendMessage(self.obj.windowHandle,SCI_GOTOPOS,offset,0)\r\n\t\t# #5678: A caret event sometimes doesn't get fired when we do this,\r\n\t\t# so fake one just in case.\r\n\t\teventHandler.executeEvent(\"caret\", self.obj)\r\n\r\n\tdef _getSelectionOffsets(self):\r\n\t\tstart=watchdog.cancellableSendMessage(self.obj.windowHandle,SCI_GETSELECTIONSTART,0,0)\r\n\t\tend=watchdog.cancellableSendMessage(self.obj.windowHandle,SCI_GETSELECTIONEND,0,0)\r\n\t\treturn (start,end)\r\n\r\n\tdef _setSelectionOffsets(self,start,end):\r\n\t\twatchdog.cancellableSendMessage(self.obj.windowHandle,SCI_SETSEL,start,end)\r\n\r\n\tdef _getStoryText(self):\r\n\t\tif not hasattr(self,'_storyText'):\r\n\t\t\tstoryLength=self._getStoryLength()\r\n\t\t\tself._storyText=self._getTextRange(0,storyLength)\r\n\t\treturn self._storyText\r\n\r\n\tdef _getStoryLength(self):\r\n\t\tif not hasattr(self,'_storyLength'):\r\n\t\t\tself._storyLength=watchdog.cancellableSendMessage(self.obj.windowHandle,SCI_GETTEXTLENGTH,0,0)\r\n\t\treturn self._storyLength\r\n\r\n\tdef _getLineCount(self):\r\n\t\treturn watchdog.cancellableSendMessage(self.obj.windowHandle,SCI_GETLINECOUNT,0,0)\r\n\r\n\tdef _getTextRange(self,start,end):\r\n\t\tbufLen = (end - start) + 1\r\n\t\ttextRange = TextRangeStruct()\r\n\t\ttextRange.chrg.cpMin = start\r\n\t\ttextRange.chrg.cpMax = end\r\n\t\tprocessHandle = self.obj.processHandle\r\n\t\tinternalBuf = winKernel.virtualAllocEx(processHandle, None, bufLen, winKernel.MEM_COMMIT, winKernel.PAGE_READWRITE)\r\n\t\ttry:\r\n\t\t\ttextRange.lpstrText = internalBuf\r\n\t\t\tinternalTextRange = winKernel.virtualAllocEx(processHandle, None, ctypes.sizeof(textRange), winKernel.MEM_COMMIT, winKernel.PAGE_READWRITE)\r\n\t\t\ttry:\r\n\t\t\t\twinKernel.writeProcessMemory(processHandle, internalTextRange, ctypes.byref(textRange), ctypes.sizeof(textRange), None)\r\n\t\t\t\tnumBytes = watchdog.cancellableSendMessage(self.obj.windowHandle, SCI_GETTEXTRANGE, 0, internalTextRange)\r\n\t\t\tfinally:\r\n\t\t\t\twinKernel.virtualFreeEx(processHandle, internalTextRange, 0, winKernel.MEM_RELEASE)\r\n\t\t\tbuf = ctypes.create_string_buffer(bufLen)\r\n\t\t\twinKernel.readProcessMemory(processHandle, internalBuf, buf, bufLen, None)\r\n\t\tfinally:\r\n\t\t\twinKernel.virtualFreeEx(processHandle, internalBuf, 0, winKernel.MEM_RELEASE)\r\n\t\treturn textUtils.getTextFromRawBytes(buf.raw, numChars=numBytes, encoding=self.encoding, errorsFallback=\"surrogateescape\")\r\n\r\n\tdef _getWordOffsets(self,offset):\r\n\t\tstart=watchdog.cancellableSendMessage(self.obj.windowHandle,SCI_WORDSTARTPOSITION,offset,0)\r\n\t\tend=watchdog.cancellableSendMessage(self.obj.windowHandle,SCI_WORDENDPOSITION,start,0)\r\n\t\tif end<=offset:\r\n\t\t\tstart=end\r\n\t\t\tend=watchdog.cancellableSendMessage(self.obj.windowHandle,SCI_WORDENDPOSITION,offset,0)\r\n\t\treturn [start,end]\r\n\r\n\tdef _getLineNumFromOffset(self,offset):\r\n\t\treturn watchdog.cancellableSendMessage(self.obj.windowHandle,SCI_LINEFROMPOSITION,offset,0)\r\n\r\n\tdef _getLineOffsets(self,offset):\r\n\t\tif watchdog.cancellableSendMessage(self.obj.windowHandle,SCI_GETWRAPMODE,None,None)!=SC_WRAP_NONE:\r\n\t\t\t# Lines in Scintilla refer to document lines, not wrapped lines.\r\n\t\t\t# There's no way to retrieve wrapped lines, so use screen coordinates.\r\n\t\t\ty = self._getPointFromOffset(offset).y\r\n\t\t\tlocation=self.obj.location\r\n\t\t\tstart = self._getOffsetFromPoint(location.left, y)\r\n\t\t\tend=self._getOffsetFromPoint(location.right, y)\r\n\t\t\t# If this line wraps to the next line,\r\n\t\t\t# end is the first offset of the next line.\r\n\t\t\tif self._getPointFromOffset(end).y==y:\r\n\t\t\t\t# This is the end of the document line.\r\n\t\t\t\t# Include the EOL characters in the returned offsets.\r\n\t\t\t\tend=watchdog.cancellableSendMessage(self.obj.windowHandle,SCI_POSITIONAFTER,end,None)\r\n\t\t\treturn (start,end)\r\n\r\n\t\tline=watchdog.cancellableSendMessage(self.obj.windowHandle,SCI_LINEFROMPOSITION,offset,0)\r\n\t\tstart=watchdog.cancellableSendMessage(self.obj.windowHandle,SCI_POSITIONFROMLINE,line,0)\r\n\t\tend=start+watchdog.cancellableSendMessage(self.obj.windowHandle,SCI_LINELENGTH,line,0)\r\n\t\treturn (start,end)\r\n\r\n\tdef _getParagraphOffsets(self,offset):\r\n\t\treturn self._getLineOffsets(offset)\r\n\r\n\tdef _getCharacterOffsets(self,offset):\r\n\t\tif offset>=self._getStoryLength(): return offset,offset+1\r\n\t\tend=watchdog.cancellableSendMessage(self.obj.windowHandle,SCI_POSITIONAFTER,offset,0)\r\n\t\tstart=offset\r\n\t\ttempOffset=offset-1\r\n\t\t\r\n\t\twhile tempOffset > INVALID_POSITION:\r\n\t\t\tstart=watchdog.cancellableSendMessage(self.obj.windowHandle,SCI_POSITIONAFTER,tempOffset,0)\r\n\t\t\tif start<end:\r\n\t\t\t\tbreak\r\n\t\t\telif tempOffset==0:\r\n\t\t\t\tstart=tempOffset\r\n\t\t\t\tbreak\r\n\t\t\telse:\r\n\t\t\t\ttempOffset-=1\r\n\t\treturn [start,end]\r\n\r\n\r\n#The Scintilla NVDA object, inherists the generic MSAA NVDA object\r\nclass Scintilla(EditableTextWithAutoSelectDetection, Window):\r\n\r\n\tTextInfo=ScintillaTextInfo\r\n\r\n#The name of the object is gotten by the standard way of getting a window name, can't use MSAA name (since it contains all the text)\r\n\tdef _get_name(self):\r\n\t\treturn winUser.getWindowText(self.windowHandle)\r\n\r\n#The role of the object should be editable text\r\n\tdef _get_role(self):\r\n\t\treturn controlTypes.ROLE_EDITABLETEXT\r\n\r\n\tdef _get_states(self):\r\n\t\tstates = super(Scintilla, self)._get_states()\r\n\t\t# Scintilla controls are always multiline.\r\n\t\tstates.add(controlTypes.STATE_MULTILINE)\r\n\t\treturn states\r\n", "path": "source/NVDAObjects/window/scintilla.py"}], "after_files": [{"content": "#A part of NonVisual Desktop Access (NVDA)\r\n#Copyright (C) 2009-2019 NV Access Limited, Arnold Loubriat, Babbage B.V.\r\n#This file is covered by the GNU General Public License.\r\n#See the file COPYING for more details.\r\n\r\nimport ctypes\r\nimport IAccessibleHandler\r\nimport speech\r\nimport textInfos.offsets\r\nimport winKernel\r\nimport winUser\r\nimport globalVars\r\nimport controlTypes\r\nimport config\r\nfrom . import Window\r\nfrom .. import NVDAObjectTextInfo\r\nfrom ..behaviors import EditableTextWithAutoSelectDetection\r\nimport locale\r\nimport watchdog\r\nimport eventHandler\r\nimport locationHelper\r\nimport textUtils\r\n\r\n# Window messages\r\nSCI_POSITIONFROMPOINT=2022\r\nSCI_POINTXFROMPOSITION=2164\r\nSCI_POINTYFROMPOSITION=2165\r\nSCI_GETTEXTRANGE=2162\r\nSCI_GETTEXT=2182\r\nSCI_GETTEXTLENGTH=2183\r\nSCI_GETLENGTH=2006\r\nSCI_GETCURRENTPOS=2008\r\nSCI_GETANCHOR=2009\r\nSCI_GOTOPOS=2025\r\nSCI_SETCURRENTPOS=2141\r\nSCI_GETSELECTIONSTART=2143\r\nSCI_GETSELECTIONEND=2145\r\nSCI_SETSEL=2160\r\nSCI_GETLINEENDPOSITION=2136\r\nSCI_GETLINECOUNT=2154\r\nSCI_LINEFROMPOSITION=2166\r\nSCI_POSITIONFROMLINE=2167\r\nSCI_LINELENGTH=2350\r\nSCI_GETSTYLEAT=2010\r\nSCI_STYLEGETFONT=2486\r\nSCI_STYLEGETSIZE=2485\r\nSCI_STYLEGETBOLD=2483\r\nSCI_STYLEGETITALIC=2484\r\nSCI_STYLEGETUNDERLINE=2488\r\nSCI_WORDSTARTPOSITION=2266\r\nSCI_WORDENDPOSITION=2267\r\nSC_WRAP_NONE=0\r\nSCI_GETWRAPMODE=2269\r\nSCI_GETCODEPAGE=2137\r\nSCI_POSITIONAFTER=2418\r\n\r\n#constants\r\n#: Represents an invalid position within a document.\r\nINVALID_POSITION=-1\r\nSTYLE_DEFAULT=32\r\nSC_CP_UTF8=65001\r\n\r\nclass CharacterRangeStruct(ctypes.Structure):\r\n\t_fields_=[\r\n\t\t('cpMin',ctypes.c_long),\r\n\t\t('cpMax',ctypes.c_long),\r\n\t]\r\n\r\nclass TextRangeStruct(ctypes.Structure):\r\n\t_fields_=[\r\n\t\t('chrg',CharacterRangeStruct),\r\n\t\t('lpstrText',ctypes.c_char_p),\r\n\t]\r\n\r\nclass ScintillaTextInfo(textInfos.offsets.OffsetsTextInfo):\r\n\r\n\tdef _get_encoding(self):\r\n\t\tcp=watchdog.cancellableSendMessage(self.obj.windowHandle,SCI_GETCODEPAGE,0,0)\r\n\t\tif cp==SC_CP_UTF8:\r\n\t\t\treturn \"utf-8\"\r\n\t\telse:\r\n\t\t\treturn locale.getlocale()[1]\r\n\r\n\tdef _getOffsetFromPoint(self,x,y):\r\n\t\tx, y = winUser.ScreenToClient(self.obj.windowHandle, x, y)\r\n\t\treturn watchdog.cancellableSendMessage(self.obj.windowHandle,SCI_POSITIONFROMPOINT,x,y)\r\n\r\n\tdef _getPointFromOffset(self,offset):\r\n\t\tpoint=locationHelper.Point(\r\n\t\t\twatchdog.cancellableSendMessage(self.obj.windowHandle,SCI_POINTXFROMPOSITION,None,offset),\r\n\t\t\twatchdog.cancellableSendMessage(self.obj.windowHandle,SCI_POINTYFROMPOSITION,None,offset)\r\n\t\t).toScreen(self.obj.windowHandle)\r\n\t\tif point.x is not None and point.y is not None:\r\n\t\t\treturn point\r\n\t\telse:\r\n\t\t\traise NotImplementedError\r\n\r\n\tdef _getFormatFieldAndOffsets(self,offset,formatConfig,calculateOffsets=True):\r\n\t\tstyle=watchdog.cancellableSendMessage(self.obj.windowHandle,SCI_GETSTYLEAT,offset,0)\r\n\t\tif calculateOffsets:\r\n\t\t\t#we need to manually see how far the style goes, limit to line\r\n\t\t\tlineStart,lineEnd=self._getLineOffsets(offset)\r\n\t\t\tstartOffset=offset\r\n\t\t\twhile startOffset>lineStart:\r\n\t\t\t\tcurStyle=watchdog.cancellableSendMessage(self.obj.windowHandle,SCI_GETSTYLEAT,startOffset-1,0)\r\n\t\t\t\tif curStyle==style:\r\n\t\t\t\t\tstartOffset-=1\r\n\t\t\t\telse:\r\n\t\t\t\t\tbreak\r\n\t\t\tendOffset=offset+1\r\n\t\t\twhile endOffset<lineEnd:\r\n\t\t\t\tcurStyle=watchdog.cancellableSendMessage(self.obj.windowHandle,SCI_GETSTYLEAT,endOffset,0)\r\n\t\t\t\tif curStyle==style:\r\n\t\t\t\t\tendOffset+=1\r\n\t\t\t\telse:\r\n\t\t\t\t\tbreak\r\n\t\telse:\r\n\t\t\tstartOffset,endOffset=(self._startOffset,self._endOffset)\r\n\t\tformatField=textInfos.FormatField()\r\n\t\tif formatConfig[\"reportFontName\"]:\r\n\t\t\t#To get font name, We need to allocate memory with in Scintilla's process, and then copy it out\r\n\t\t\tfontNameBuf=ctypes.create_string_buffer(32)\r\n\t\t\tinternalBuf=winKernel.virtualAllocEx(self.obj.processHandle,None,len(fontNameBuf),winKernel.MEM_COMMIT,winKernel.PAGE_READWRITE)\r\n\t\t\ttry:\r\n\t\t\t\twatchdog.cancellableSendMessage(self.obj.windowHandle,SCI_STYLEGETFONT,style, internalBuf)\r\n\t\t\t\twinKernel.readProcessMemory(self.obj.processHandle,internalBuf,fontNameBuf,len(fontNameBuf),None)\r\n\t\t\tfinally:\r\n\t\t\t\twinKernel.virtualFreeEx(self.obj.processHandle,internalBuf,0,winKernel.MEM_RELEASE)\r\n\t\t\tformatField[\"font-name\"]=fontNameBuf.value.decode(\"utf-8\")\r\n\t\tif formatConfig[\"reportFontSize\"]:\r\n\t\t\tformatField[\"font-size\"]=\"%spt\"%watchdog.cancellableSendMessage(self.obj.windowHandle,SCI_STYLEGETSIZE,style,0)\r\n\t\tif formatConfig[\"reportLineNumber\"]:\r\n\t\t\tformatField[\"line-number\"]=self._getLineNumFromOffset(offset)+1\r\n\t\tif formatConfig[\"reportFontAttributes\"]:\r\n\t\t\tformatField[\"bold\"]=bool(watchdog.cancellableSendMessage(self.obj.windowHandle,SCI_STYLEGETBOLD,style,0))\r\n\t\t\tformatField[\"italic\"]=bool(watchdog.cancellableSendMessage(self.obj.windowHandle,SCI_STYLEGETITALIC,style,0))\r\n\t\t\tformatField[\"underline\"]=bool(watchdog.cancellableSendMessage(self.obj.windowHandle,SCI_STYLEGETUNDERLINE,style,0))\r\n\t\treturn formatField,(startOffset,endOffset)\r\n\r\n\tdef _getCaretOffset(self):\r\n\t\treturn watchdog.cancellableSendMessage(self.obj.windowHandle,SCI_GETCURRENTPOS,0,0)\r\n\r\n\tdef _setCaretOffset(self,offset):\r\n\t\twatchdog.cancellableSendMessage(self.obj.windowHandle,SCI_GOTOPOS,offset,0)\r\n\t\t# #5678: A caret event sometimes doesn't get fired when we do this,\r\n\t\t# so fake one just in case.\r\n\t\teventHandler.executeEvent(\"caret\", self.obj)\r\n\r\n\tdef _getSelectionOffsets(self):\r\n\t\tstart=watchdog.cancellableSendMessage(self.obj.windowHandle,SCI_GETSELECTIONSTART,0,0)\r\n\t\tend=watchdog.cancellableSendMessage(self.obj.windowHandle,SCI_GETSELECTIONEND,0,0)\r\n\t\treturn (start,end)\r\n\r\n\tdef _setSelectionOffsets(self,start,end):\r\n\t\twatchdog.cancellableSendMessage(self.obj.windowHandle,SCI_SETSEL,start,end)\r\n\r\n\tdef _getStoryText(self):\r\n\t\tif not hasattr(self,'_storyText'):\r\n\t\t\tstoryLength=self._getStoryLength()\r\n\t\t\tself._storyText=self._getTextRange(0,storyLength)\r\n\t\treturn self._storyText\r\n\r\n\tdef _getStoryLength(self):\r\n\t\tif not hasattr(self,'_storyLength'):\r\n\t\t\tself._storyLength=watchdog.cancellableSendMessage(self.obj.windowHandle,SCI_GETTEXTLENGTH,0,0)\r\n\t\treturn self._storyLength\r\n\r\n\tdef _getLineCount(self):\r\n\t\treturn watchdog.cancellableSendMessage(self.obj.windowHandle,SCI_GETLINECOUNT,0,0)\r\n\r\n\tdef _getTextRange(self,start,end):\r\n\t\tbufLen = (end - start) + 1\r\n\t\ttextRange = TextRangeStruct()\r\n\t\ttextRange.chrg.cpMin = start\r\n\t\ttextRange.chrg.cpMax = end\r\n\t\tprocessHandle = self.obj.processHandle\r\n\t\tinternalBuf = winKernel.virtualAllocEx(processHandle, None, bufLen, winKernel.MEM_COMMIT, winKernel.PAGE_READWRITE)\r\n\t\ttry:\r\n\t\t\ttextRange.lpstrText = internalBuf\r\n\t\t\tinternalTextRange = winKernel.virtualAllocEx(processHandle, None, ctypes.sizeof(textRange), winKernel.MEM_COMMIT, winKernel.PAGE_READWRITE)\r\n\t\t\ttry:\r\n\t\t\t\twinKernel.writeProcessMemory(processHandle, internalTextRange, ctypes.byref(textRange), ctypes.sizeof(textRange), None)\r\n\t\t\t\tnumBytes = watchdog.cancellableSendMessage(self.obj.windowHandle, SCI_GETTEXTRANGE, 0, internalTextRange)\r\n\t\t\tfinally:\r\n\t\t\t\twinKernel.virtualFreeEx(processHandle, internalTextRange, 0, winKernel.MEM_RELEASE)\r\n\t\t\tbuf = ctypes.create_string_buffer(bufLen)\r\n\t\t\twinKernel.readProcessMemory(processHandle, internalBuf, buf, bufLen, None)\r\n\t\tfinally:\r\n\t\t\twinKernel.virtualFreeEx(processHandle, internalBuf, 0, winKernel.MEM_RELEASE)\r\n\t\treturn textUtils.getTextFromRawBytes(buf.raw, numChars=numBytes, encoding=self.encoding, errorsFallback=\"surrogateescape\")\r\n\r\n\tdef _getWordOffsets(self,offset):\r\n\t\tstart=watchdog.cancellableSendMessage(self.obj.windowHandle,SCI_WORDSTARTPOSITION,offset,0)\r\n\t\tend=watchdog.cancellableSendMessage(self.obj.windowHandle,SCI_WORDENDPOSITION,start,0)\r\n\t\tif end<=offset:\r\n\t\t\tstart=end\r\n\t\t\tend=watchdog.cancellableSendMessage(self.obj.windowHandle,SCI_WORDENDPOSITION,offset,0)\r\n\t\treturn [start,end]\r\n\r\n\tdef _getLineNumFromOffset(self,offset):\r\n\t\treturn watchdog.cancellableSendMessage(self.obj.windowHandle,SCI_LINEFROMPOSITION,offset,0)\r\n\r\n\tdef _getLineOffsets(self,offset):\r\n\t\tif watchdog.cancellableSendMessage(self.obj.windowHandle,SCI_GETWRAPMODE,None,None)!=SC_WRAP_NONE:\r\n\t\t\t# Lines in Scintilla refer to document lines, not wrapped lines.\r\n\t\t\t# There's no way to retrieve wrapped lines, so use screen coordinates.\r\n\t\t\ty = self._getPointFromOffset(offset).y\r\n\t\t\tlocation=self.obj.location\r\n\t\t\tstart = self._getOffsetFromPoint(location.left, y)\r\n\t\t\tend=self._getOffsetFromPoint(location.right, y)\r\n\t\t\t# If this line wraps to the next line,\r\n\t\t\t# end is the first offset of the next line.\r\n\t\t\tif self._getPointFromOffset(end).y==y:\r\n\t\t\t\t# This is the end of the document line.\r\n\t\t\t\t# Include the EOL characters in the returned offsets.\r\n\t\t\t\tend=watchdog.cancellableSendMessage(self.obj.windowHandle,SCI_POSITIONAFTER,end,None)\r\n\t\t\treturn (start,end)\r\n\r\n\t\tline=watchdog.cancellableSendMessage(self.obj.windowHandle,SCI_LINEFROMPOSITION,offset,0)\r\n\t\tstart=watchdog.cancellableSendMessage(self.obj.windowHandle,SCI_POSITIONFROMLINE,line,0)\r\n\t\tend=start+watchdog.cancellableSendMessage(self.obj.windowHandle,SCI_LINELENGTH,line,0)\r\n\t\treturn (start,end)\r\n\r\n\tdef _getParagraphOffsets(self,offset):\r\n\t\treturn self._getLineOffsets(offset)\r\n\r\n\tdef _getCharacterOffsets(self,offset):\r\n\t\tif offset>=self._getStoryLength(): return offset,offset+1\r\n\t\tend=watchdog.cancellableSendMessage(self.obj.windowHandle,SCI_POSITIONAFTER,offset,0)\r\n\t\tstart=offset\r\n\t\ttempOffset=offset-1\r\n\t\t\r\n\t\twhile tempOffset > INVALID_POSITION:\r\n\t\t\tstart=watchdog.cancellableSendMessage(self.obj.windowHandle,SCI_POSITIONAFTER,tempOffset,0)\r\n\t\t\tif start<end:\r\n\t\t\t\tbreak\r\n\t\t\telif tempOffset==0:\r\n\t\t\t\tstart=tempOffset\r\n\t\t\t\tbreak\r\n\t\t\telse:\r\n\t\t\t\ttempOffset-=1\r\n\t\treturn [start,end]\r\n\r\n\r\n#The Scintilla NVDA object, inherists the generic MSAA NVDA object\r\nclass Scintilla(EditableTextWithAutoSelectDetection, Window):\r\n\r\n\tTextInfo=ScintillaTextInfo\r\n\r\n#The name of the object is gotten by the standard way of getting a window name, can't use MSAA name (since it contains all the text)\r\n\tdef _get_name(self):\r\n\t\treturn winUser.getWindowText(self.windowHandle)\r\n\r\n#The role of the object should be editable text\r\n\tdef _get_role(self):\r\n\t\treturn controlTypes.ROLE_EDITABLETEXT\r\n\r\n\tdef _get_states(self):\r\n\t\tstates = super(Scintilla, self)._get_states()\r\n\t\t# Scintilla controls are always multiline.\r\n\t\tstates.add(controlTypes.STATE_MULTILINE)\r\n\t\treturn states\r\n", "path": "source/NVDAObjects/window/scintilla.py"}]}