We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
NVDA's support for Scintilla controls. is broken in alpha snapshots, if "line wrap" is enabled in the text editor
### Steps to reproduce:
1. Install a text editor like Notepad++.
2. In it, open a text file containing a few lines of text.
3. Enable the text editor's "line wrap" feature.
4. Start reading line by line with the up/down arrow keys.
5. Enable NVDA's mouse tracking and use the mouse to hover over and read the separate lines of text.

### Actual behavior:
With the up/down arrow keys, NVDA reads another line of text and not the one on which the cursor is positioned. This behavior affects only reading line by line - reading by word or character seams to be working as expected. The situation when reading with the mouse is similar - NVDA does not read the line which the mouse is pointing, but another one. And this occurs only if the "line wrap" feature of the text editor is enabled, so long lines of text are wrapped on multiple lines if necessary.

### Expected behavior:
NVDA should read the line on which the cursor is positioned or the one which the mouse is pointing, even if the "line wrap" feature of the text editor is enabled.

### System configuration
- Operating system: Windows 10 Pro version 1809 (build 17763.379), 64-bit, in Bulgarian with all locale settings set to "Bulgarian".
- NVDA version: alpha-16976,7fc6c71f.
- Processor: Intel Core i5-4670 at 3.40GHz.
- RAM Memory: 8.00GB.
- Graphics: MSI GeForce GTX-1050TI Gaming X 4G, 4096MB dedicated memory + 4065MB shared system memory, desktop resolution set to 1920x1080.
- Sound Card: Realtek ALC887 at Intel Lynx Point PCH - High Definition Audio Controller.

### Other questions
#### Does the issue still occur after restarting your PC?
Yes, it does.

#### Have you tried any other versions of NVDA?
No, because this started occurring only with the latest "alpha" snapshots of NVDA. I guess this is probably caused by #9233 (Fixing incorrect text reporting when hovering mouse over Scintilla controls), though I might be wrong.

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

{"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@@ -70,10 +70,11 @@\n \t\treturn watchdog.cancellableSendMessage(self.obj.windowHandle,SCI_POSITIONFROMPOINT,x,y)\r\n \r\n \tdef _getPointFromOffset(self,offset):\r\n-\t\tpoint=textInfos.Point(\r\n-\t\twatchdog.cancellableSendMessage(self.obj.windowHandle,SCI_POINTXFROMPOSITION,None,offset),\r\n-\t\twatchdog.cancellableSendMessage(self.obj.windowHandle,SCI_POINTYFROMPOSITION,None,offset)\r\n+\t\tx, y = winUser.ClientToScreen(self.obj.windowHandle,\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)\r\n+\t\tpoint=textInfos.Point(x, y)\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@@ -192,10 +193,10 @@\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=watchdog.cancellableSendMessage(self.obj.windowHandle,SCI_POINTYFROMPOSITION,None,offset)\r\n-\t\t\ttop,left,width,height=self.obj.location\r\n-\t\t\tstart = self._getOffsetFromPoint(0,y)\r\n-\t\t\tend=self._getOffsetFromPoint(width,y)\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 watchdog.cancellableSendMessage(self.obj.windowHandle,SCI_POINTYFROMPOSITION,None,end)==y:\n", "issue": "NVDA's support for Scintilla controls. is broken in alpha snapshots, if \"line wrap\" is enabled in the text editor\n### Steps to reproduce:\r\n1. Install a text editor like Notepad++.\r\n2. In it, open a text file containing a few lines of text.\r\n3. Enable the text editor's \"line wrap\" feature.\r\n4. Start reading line by line with the up/down arrow keys.\r\n5. Enable NVDA's mouse tracking and use the mouse to hover over and read the separate lines of text.\r\n\r\n### Actual behavior:\r\nWith the up/down arrow keys, NVDA reads another line of text and not the one on which the cursor is positioned. This behavior affects only reading line by line - reading by word or character seams to be working as expected. The situation when reading with the mouse is similar - NVDA does not read the line which the mouse is pointing, but another one. And this occurs only if the \"line wrap\" feature of the text editor is enabled, so long lines of text are wrapped on multiple lines if necessary.\r\n\r\n### Expected behavior:\r\nNVDA should read the line on which the cursor is positioned or the one which the mouse is pointing, even if the \"line wrap\" feature of the text editor is enabled.\r\n\r\n### System configuration\r\n- Operating system: Windows 10 Pro version 1809 (build 17763.379), 64-bit, in Bulgarian with all locale settings set to \"Bulgarian\".\r\n- NVDA version: alpha-16976,7fc6c71f.\r\n- Processor: Intel Core i5-4670 at 3.40GHz.\r\n- RAM Memory: 8.00GB.\r\n- Graphics: MSI GeForce GTX-1050TI Gaming X 4G, 4096MB dedicated memory + 4065MB shared system memory, desktop resolution set to 1920x1080.\r\n- Sound Card: Realtek ALC887 at Intel Lynx Point PCH - High Definition Audio Controller.\r\n\r\n### Other questions\r\n#### Does the issue still occur after restarting your PC?\r\nYes, it does.\r\n\r\n#### Have you tried any other versions of NVDA?\r\nNo, because this started occurring only with the latest \"alpha\" snapshots of NVDA. I guess this is probably caused by #9233 (Fixing incorrect text reporting when hovering mouse over Scintilla controls), though I might be wrong.\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\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\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 _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=textInfos.Point(\r\n\t\twatchdog.cancellableSendMessage(self.obj.windowHandle,SCI_POINTXFROMPOSITION,None,offset),\r\n\t\twatchdog.cancellableSendMessage(self.obj.windowHandle,SCI_POINTYFROMPOSITION,None,offset)\r\n\t\t)\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\twatchdog.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\tcp=watchdog.cancellableSendMessage(self.obj.windowHandle,SCI_GETCODEPAGE,0,0)\r\n\t\tif cp==SC_CP_UTF8:\r\n\t\t\treturn unicode(buf.value, errors=\"replace\", encoding=\"utf-8\")\r\n\t\telse:\r\n\t\t\treturn unicode(buf.value, errors=\"replace\", encoding=locale.getlocale()[1])\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=watchdog.cancellableSendMessage(self.obj.windowHandle,SCI_POINTYFROMPOSITION,None,offset)\r\n\t\t\ttop,left,width,height=self.obj.location\r\n\t\t\tstart = self._getOffsetFromPoint(0,y)\r\n\t\t\tend=self._getOffsetFromPoint(width,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 watchdog.cancellableSendMessage(self.obj.windowHandle,SCI_POINTYFROMPOSITION,None,end)==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\twhile True:\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": "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\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\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 _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\tx, y = winUser.ClientToScreen(self.obj.windowHandle,\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)\r\n\t\tpoint=textInfos.Point(x, y)\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\twatchdog.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\tcp=watchdog.cancellableSendMessage(self.obj.windowHandle,SCI_GETCODEPAGE,0,0)\r\n\t\tif cp==SC_CP_UTF8:\r\n\t\t\treturn unicode(buf.value, errors=\"replace\", encoding=\"utf-8\")\r\n\t\telse:\r\n\t\t\treturn unicode(buf.value, errors=\"replace\", encoding=locale.getlocale()[1])\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 watchdog.cancellableSendMessage(self.obj.windowHandle,SCI_POINTYFROMPOSITION,None,end)==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\twhile True:\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"}]}