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
16
17 SCI_POSITIONFROMPOINT=2022
18 SCI_POINTXFROMPOSITION=2164
19 SCI_POINTYFROMPOSITION=2165
20 SCI_GETTEXTRANGE=2162
21 SCI_GETTEXT=2182
22 SCI_GETTEXTLENGTH=2183
23 SCI_GETLENGTH=2006
24 SCI_GETCURRENTPOS=2008
25 SCI_GETANCHOR=2009
26 SCI_GOTOPOS=2025
27 SCI_SETCURRENTPOS=2141
28 SCI_GETSELECTIONSTART=2143
29 SCI_GETSELECTIONEND=2145
30 SCI_SETSEL=2160
31 SCI_GETLINEENDPOSITION=2136
32 SCI_GETLINECOUNT=2154
33 SCI_LINEFROMPOSITION=2166
34 SCI_POSITIONFROMLINE=2167
35 SCI_LINELENGTH=2350
36 SCI_GETSTYLEAT=2010
37 SCI_STYLEGETFONT=2486
38 SCI_STYLEGETSIZE=2485
39 SCI_STYLEGETBOLD=2483
40 SCI_STYLEGETITALIC=2484
41 SCI_STYLEGETUNDERLINE=2488
42 SCI_WORDSTARTPOSITION=2266
43 SCI_WORDENDPOSITION=2267
44 SCI_GETCODEPAGE=2137
45 SCI_POSITIONAFTER=2418
46
47
48 STYLE_DEFAULT=32
49 SC_CP_UTF8=65001
50
52 _fields_=[
53 ('cpMin',ctypes.c_long),
54 ('cpMax',ctypes.c_long),
55 ]
56
58 _fields_=[
59 ('chrg',CharacterRangeStruct),
60 ('lpstrText',ctypes.c_char_p),
61 ]
62
63 -class ScintillaTextInfo(textInfos.offsets.OffsetsTextInfo):
64
67
68 - def _getPointFromOffset(self,offset):
69 point=textInfos.Point(
70 watchdog.cancellableSendMessage(self.obj.windowHandle,SCI_POINTXFROMPOSITION,None,offset),
71 watchdog.cancellableSendMessage(self.obj.windowHandle,SCI_POINTYFROMPOSITION,None,offset)
72 )
73 if point.x and point.y:
74 return point
75 else:
76 raise NotImplementedError
77
79 style=watchdog.cancellableSendMessage(self.obj.windowHandle,SCI_GETSTYLEAT,offset,0)
80 if calculateOffsets:
81
82 lineStart,lineEnd=self._getLineOffsets(offset)
83 startOffset=offset
84 while startOffset>lineStart:
85 curStyle=watchdog.cancellableSendMessage(self.obj.windowHandle,SCI_GETSTYLEAT,startOffset-1,0)
86 if curStyle==style:
87 startOffset-=1
88 else:
89 break
90 endOffset=offset+1
91 while endOffset<lineEnd:
92 curStyle=watchdog.cancellableSendMessage(self.obj.windowHandle,SCI_GETSTYLEAT,endOffset,0)
93 if curStyle==style:
94 endOffset+=1
95 else:
96 break
97 else:
98 startOffset,endOffset=(self._startOffset,self._endOffset)
99 formatField=textInfos.FormatField()
100 if formatConfig["reportFontName"]:
101
102 fontNameBuf=ctypes.create_string_buffer(32)
103 internalBuf=winKernel.virtualAllocEx(self.obj.processHandle,None,len(fontNameBuf),winKernel.MEM_COMMIT,winKernel.PAGE_READWRITE)
104 try:
105 watchdog.cancellableSendMessage(self.obj.windowHandle,SCI_STYLEGETFONT,style, internalBuf)
106 winKernel.readProcessMemory(self.obj.processHandle,internalBuf,fontNameBuf,len(fontNameBuf),None)
107 finally:
108 winKernel.virtualFreeEx(self.obj.processHandle,internalBuf,0,winKernel.MEM_RELEASE)
109 formatField["font-name"]=fontNameBuf.value
110 if formatConfig["reportFontSize"]:
111 formatField["font-size"]="%spt"%watchdog.cancellableSendMessage(self.obj.windowHandle,SCI_STYLEGETSIZE,style,0)
112 if formatConfig["reportLineNumber"]:
113 formatField["line-number"]=self._getLineNumFromOffset(offset)+1
114 if formatConfig["reportFontAttributes"]:
115 formatField["bold"]=bool(watchdog.cancellableSendMessage(self.obj.windowHandle,SCI_STYLEGETBOLD,style,0))
116 formatField["italic"]=bool(watchdog.cancellableSendMessage(self.obj.windowHandle,SCI_STYLEGETITALIC,style,0))
117 formatField["underline"]=bool(watchdog.cancellableSendMessage(self.obj.windowHandle,SCI_STYLEGETUNDERLINE,style,0))
118 return formatField,(startOffset,endOffset)
119
120 - def _getCaretOffset(self):
122
123 - def _setCaretOffset(self,offset):
125
127 start=watchdog.cancellableSendMessage(self.obj.windowHandle,SCI_GETSELECTIONSTART,0,0)
128 end=watchdog.cancellableSendMessage(self.obj.windowHandle,SCI_GETSELECTIONEND,0,0)
129 return (start,end)
130
131 - def _setSelectionOffsets(self,start,end):
133
134 - def _getStoryText(self):
135 if not hasattr(self,'_storyText'):
136 storyLength=self._getStoryLength()
137 self._storyText=self._getTextRange(0,storyLength)
138 return self._storyText
139
140 - def _getStoryLength(self):
141 if not hasattr(self,'_storyLength'):
142 self._storyLength=watchdog.cancellableSendMessage(self.obj.windowHandle,SCI_GETTEXTLENGTH,0,0)
143 return self._storyLength
144
145 - def _getLineCount(self):
147
149 bufLen=(end-start)+1
150 textRange=TextRangeStruct()
151 textRange.chrg.cpMin=start
152 textRange.chrg.cpMax=end
153 processHandle=self.obj.processHandle
154 internalBuf=winKernel.virtualAllocEx(processHandle,None,bufLen,winKernel.MEM_COMMIT,winKernel.PAGE_READWRITE)
155 try:
156 textRange.lpstrText=internalBuf
157 internalTextRange=winKernel.virtualAllocEx(processHandle,None,ctypes.sizeof(textRange),winKernel.MEM_COMMIT,winKernel.PAGE_READWRITE)
158 try:
159 winKernel.writeProcessMemory(processHandle,internalTextRange,ctypes.byref(textRange),ctypes.sizeof(textRange),None)
160 watchdog.cancellableSendMessage(self.obj.windowHandle,SCI_GETTEXTRANGE,0,internalTextRange)
161 finally:
162 winKernel.virtualFreeEx(processHandle,internalTextRange,0,winKernel.MEM_RELEASE)
163 buf=ctypes.create_string_buffer(bufLen)
164 winKernel.readProcessMemory(processHandle,internalBuf,buf,bufLen,None)
165 finally:
166 winKernel.virtualFreeEx(processHandle,internalBuf,0,winKernel.MEM_RELEASE)
167 cp=watchdog.cancellableSendMessage(self.obj.windowHandle,SCI_GETCODEPAGE,0,0)
168 if cp==SC_CP_UTF8:
169 return unicode(buf.value, errors="replace", encoding="utf-8")
170 else:
171 return unicode(buf.value, errors="replace", encoding=locale.getlocale()[1])
172
173 - def _getWordOffsets(self,offset):
174 start=watchdog.cancellableSendMessage(self.obj.windowHandle,SCI_WORDSTARTPOSITION,offset,0)
175 end=watchdog.cancellableSendMessage(self.obj.windowHandle,SCI_WORDENDPOSITION,start,0)
176 if end<=offset:
177 start=end
178 end=watchdog.cancellableSendMessage(self.obj.windowHandle,SCI_WORDENDPOSITION,offset,0)
179 return [start,end]
180
181 - def _getLineNumFromOffset(self,offset):
183
184 - def _getLineOffsets(self,offset):
185 line=watchdog.cancellableSendMessage(self.obj.windowHandle,SCI_LINEFROMPOSITION,offset,0)
186 start=watchdog.cancellableSendMessage(self.obj.windowHandle,SCI_POSITIONFROMLINE,line,0)
187 end=start+watchdog.cancellableSendMessage(self.obj.windowHandle,SCI_LINELENGTH,line,0)
188 return (start,end)
189
190 - def _getParagraphOffsets(self,offset):
191 return self._getLineOffsets(offset)
192
193 - def _getCharacterOffsets(self,offset):
194 return [offset,watchdog.cancellableSendMessage(self.obj.windowHandle,SCI_POSITIONAFTER,offset,0)]
195
196
197 -class Scintilla(EditableTextWithAutoSelectDetection, Window):
214