~mshinke/nvdajp/betterBraille

« back to all changes in this revision

Viewing changes to source/NVDAObjects/window/edit.py

  • Committer: Masataka Shinke
  • Date: 2011-10-25 12:35:26 UTC
  • mfrom: (4175.1.10 jpmain)
  • mto: (4175.1.36 jpmain)
  • mto: This revision was merged to the branch mainline in revision 4193.
  • Revision ID: mshinke@users.sourceforge.jp-20111025123526-ze527a2rl3z0g2ky
lp:~nishimotz/nvdajp/main : 4185 をマージ

Show diffs side-by-side

added added

removed removed

Lines of Context:
4
4
#See the file COPYING for more details.
5
5
 
6
6
import locale
 
7
import sys
7
8
import comtypes.client
8
9
import struct
9
10
import ctypes
10
11
import pythoncom
11
12
import win32clipboard
12
13
import oleTypes
 
14
import colors
13
15
import globalVars
14
16
import eventHandler
15
17
import comInterfaces.tom
20
22
import api
21
23
import winUser
22
24
import textInfos.offsets
23
 
from keyUtils import key, sendKey
 
25
from keyboardHandler import KeyboardInputGesture
24
26
from scriptHandler import isScriptWaiting
25
27
import IAccessibleHandler
26
28
import controlTypes
27
29
from . import Window
28
30
from .. import NVDAObjectTextInfo
29
 
from ..behaviors import EditableText
 
31
from ..behaviors import EditableTextWithAutoSelectDetection
30
32
import braille
 
33
import watchdog
31
34
 
32
35
selOffsetsAtLastCaretEvent=None
33
36
 
86
89
        ]
87
90
 
88
91
CFM_LINK=0x20
 
92
CFE_AUTOBACKCOLOR=0x4000000
 
93
CFE_AUTOCOLOR=0x40000000
89
94
CFE_BOLD=1
90
95
CFE_ITALIC=2
91
96
CFE_UNDERLINE=4
167
172
                if self.obj.editAPIVersion==1:
168
173
                        processHandle=self.obj.processHandle
169
174
                        internalP=winKernel.virtualAllocEx(processHandle,None,ctypes.sizeof(PointLStruct),winKernel.MEM_COMMIT,winKernel.PAGE_READWRITE)
170
 
                        p=PointLStruct(0,0)
171
 
                        winKernel.writeProcessMemory(processHandle,internalP,ctypes.byref(p),ctypes.sizeof(p),None)
172
 
                        winUser.sendMessage(self.obj.windowHandle,EM_POSFROMCHAR,internalP,offset)
173
 
                        winKernel.readProcessMemory(processHandle,internalP,ctypes.byref(p),ctypes.sizeof(p),None)
174
 
                        winKernel.virtualFreeEx(processHandle,internalP,0,winKernel.MEM_RELEASE)
 
175
                        try:
 
176
                                p=PointLStruct(0,0)
 
177
                                winKernel.writeProcessMemory(processHandle,internalP,ctypes.byref(p),ctypes.sizeof(p),None)
 
178
                                watchdog.cancellableSendMessage(self.obj.windowHandle,EM_POSFROMCHAR,internalP,offset)
 
179
                                winKernel.readProcessMemory(processHandle,internalP,ctypes.byref(p),ctypes.sizeof(p),None)
 
180
                        finally:
 
181
                                winKernel.virtualFreeEx(processHandle,internalP,0,winKernel.MEM_RELEASE)
175
182
                        point=textInfos.Point(p.x,p.y)
176
183
                else:
177
 
                        res=winUser.sendMessage(self.obj.windowHandle,EM_POSFROMCHAR,offset,None)
 
184
                        res=watchdog.cancellableSendMessage(self.obj.windowHandle,EM_POSFROMCHAR,offset,None)
178
185
                        point=textInfos.Point(winUser.LOWORD(res),winUser.HIWORD(res))
179
186
                (left,top,width,height)=self.obj.location
180
187
                if point.x and point.y:
189
196
                if self.obj.editAPIVersion>=1:
190
197
                        processHandle=self.obj.processHandle
191
198
                        internalP=winKernel.virtualAllocEx(processHandle,None,ctypes.sizeof(PointLStruct),winKernel.MEM_COMMIT,winKernel.PAGE_READWRITE)
192
 
                        p=PointLStruct(x-left,y-top)
193
 
                        winKernel.writeProcessMemory(processHandle,internalP,ctypes.byref(p),ctypes.sizeof(p),None)
194
 
                        offset=winUser.sendMessage(self.obj.windowHandle,EM_CHARFROMPOS,0,internalP)
195
 
                        winKernel.virtualFreeEx(processHandle,internalP,0,winKernel.MEM_RELEASE)
 
199
                        try:
 
200
                                p=PointLStruct(x-left,y-top)
 
201
                                winKernel.writeProcessMemory(processHandle,internalP,ctypes.byref(p),ctypes.sizeof(p),None)
 
202
                                offset=watchdog.cancellableSendMessage(self.obj.windowHandle,EM_CHARFROMPOS,0,internalP)
 
203
                        finally:
 
204
                                winKernel.virtualFreeEx(processHandle,internalP,0,winKernel.MEM_RELEASE)
196
205
                else:
197
206
                        p=(x-left)+((y-top)<<16)
198
 
                        offset=winUser.sendMessage(self.obj.windowHandle,EM_CHARFROMPOS,0,p)&0xffff
 
207
                        offset=watchdog.cancellableSendMessage(self.obj.windowHandle,EM_CHARFROMPOS,0,p)&0xffff
199
208
                return offset
200
209
 
201
210
        def _getCharFormat(self,offset):
210
219
                charFormat.cbSize=ctypes.sizeof(charFormatStruct)
211
220
                processHandle=self.obj.processHandle
212
221
                internalCharFormat=winKernel.virtualAllocEx(processHandle,None,ctypes.sizeof(charFormat),winKernel.MEM_COMMIT,winKernel.PAGE_READWRITE)
213
 
                winKernel.writeProcessMemory(processHandle,internalCharFormat,ctypes.byref(charFormat),ctypes.sizeof(charFormat),None)
214
 
                winUser.sendMessage(self.obj.windowHandle,EM_GETCHARFORMAT,SCF_SELECTION, internalCharFormat)
215
 
                winKernel.readProcessMemory(processHandle,internalCharFormat,ctypes.byref(charFormat),ctypes.sizeof(charFormat),None)
216
 
                winKernel.virtualFreeEx(processHandle,internalCharFormat,0,winKernel.MEM_RELEASE)
 
222
                try:
 
223
                        winKernel.writeProcessMemory(processHandle,internalCharFormat,ctypes.byref(charFormat),ctypes.sizeof(charFormat),None)
 
224
                        watchdog.cancellableSendMessage(self.obj.windowHandle,EM_GETCHARFORMAT,SCF_SELECTION, internalCharFormat)
 
225
                        winKernel.readProcessMemory(processHandle,internalCharFormat,ctypes.byref(charFormat),ctypes.sizeof(charFormat),None)
 
226
                finally:
 
227
                        winKernel.virtualFreeEx(processHandle,internalCharFormat,0,winKernel.MEM_RELEASE)
217
228
                if oldSel!=(offset,offset+1):
218
229
                        self._setSelectionOffsets(oldSel[0],oldSel[1])
219
230
                return charFormat
244
255
                                formatField["text-position"]="sub"
245
256
                        elif charFormat.dwEffects&CFE_SUPERSCRIPT:
246
257
                                formatField["text-position"]="super"
 
258
                if formatConfig["reportColor"]:
 
259
                        if charFormat is None: charFormat=self._getCharFormat(offset)
 
260
                        formatField["color"]=colors.RGB.fromCOLORREF(charFormat.crTextColor) if not charFormat.dwEffects&CFE_AUTOCOLOR else _("default color")
 
261
                        formatField["background-color"]=colors.RGB.fromCOLORREF(charFormat.crBackColor) if not charFormat.dwEffects&CFE_AUTOBACKCOLOR else _("default color")
247
262
                if formatConfig["reportLineNumber"]:
248
263
                        formatField["line-number"]=self._getLineNumFromOffset(offset)+1
249
264
                if formatConfig["reportLinks"]:
256
271
                        charRange=CharRangeStruct()
257
272
                        processHandle=self.obj.processHandle
258
273
                        internalCharRange=winKernel.virtualAllocEx(processHandle,None,ctypes.sizeof(charRange),winKernel.MEM_COMMIT,winKernel.PAGE_READWRITE)
259
 
                        winUser.sendMessage(self.obj.windowHandle,EM_EXGETSEL,0, internalCharRange)
260
 
                        winKernel.readProcessMemory(processHandle,internalCharRange,ctypes.byref(charRange),ctypes.sizeof(charRange),None)
261
 
                        winKernel.virtualFreeEx(processHandle,internalCharRange,0,winKernel.MEM_RELEASE)
 
274
                        try:
 
275
                                watchdog.cancellableSendMessage(self.obj.windowHandle,EM_EXGETSEL,0, internalCharRange)
 
276
                                winKernel.readProcessMemory(processHandle,internalCharRange,ctypes.byref(charRange),ctypes.sizeof(charRange),None)
 
277
                        finally:
 
278
                                winKernel.virtualFreeEx(processHandle,internalCharRange,0,winKernel.MEM_RELEASE)
262
279
                        return (charRange.cpMin,charRange.cpMax)
263
280
                else:
264
281
                        start=ctypes.c_uint()
265
282
                        end=ctypes.c_uint()
266
 
                        res=winUser.sendMessage(self.obj.windowHandle,EM_GETSEL,ctypes.byref(start),ctypes.byref(end))
 
283
                        res=watchdog.cancellableSendMessage(self.obj.windowHandle,EM_GETSEL,ctypes.byref(start),ctypes.byref(end))
267
284
                        return start.value,end.value
268
285
 
269
286
        def _setSelectionOffsets(self,start,end):
273
290
                        charRange.cpMax=end
274
291
                        processHandle=self.obj.processHandle
275
292
                        internalCharRange=winKernel.virtualAllocEx(processHandle,None,ctypes.sizeof(charRange),winKernel.MEM_COMMIT,winKernel.PAGE_READWRITE)
276
 
                        winKernel.writeProcessMemory(processHandle,internalCharRange,ctypes.byref(charRange),ctypes.sizeof(charRange),None)
277
 
                        winUser.sendMessage(self.obj.windowHandle,EM_EXSETSEL,0, internalCharRange)
278
 
                        winKernel.virtualFreeEx(processHandle,internalCharRange,0,winKernel.MEM_RELEASE)
 
293
                        try:
 
294
                                winKernel.writeProcessMemory(processHandle,internalCharRange,ctypes.byref(charRange),ctypes.sizeof(charRange),None)
 
295
                                watchdog.cancellableSendMessage(self.obj.windowHandle,EM_EXSETSEL,0, internalCharRange)
 
296
                        finally:
 
297
                                winKernel.virtualFreeEx(processHandle,internalCharRange,0,winKernel.MEM_RELEASE)
279
298
                else:
280
 
                        winUser.sendMessage(self.obj.windowHandle,EM_SETSEL,start,end)
 
299
                        watchdog.cancellableSendMessage(self.obj.windowHandle,EM_SETSEL,start,end)
281
300
                #Make sure the Window is always scrolled to the caret
282
 
                winUser.sendMessage(self.obj.windowHandle,EM_SCROLLCARET,0,0)
 
301
                watchdog.cancellableSendMessage(self.obj.windowHandle,EM_SCROLLCARET,0,0)
283
302
 
284
303
        def _getCaretOffset(self):
285
304
                return self._getSelectionOffsets()[0]
302
321
                                info.codepage=0
303
322
                        processHandle=self.obj.processHandle
304
323
                        internalInfo=winKernel.virtualAllocEx(processHandle,None,ctypes.sizeof(info),winKernel.MEM_COMMIT,winKernel.PAGE_READWRITE)
305
 
                        winKernel.writeProcessMemory(processHandle,internalInfo,ctypes.byref(info),ctypes.sizeof(info),None)
306
 
                        textLen=winUser.sendMessage(self.obj.windowHandle,EM_GETTEXTLENGTHEX,internalInfo,0)
307
 
                        winKernel.virtualFreeEx(processHandle,internalInfo,0,winKernel.MEM_RELEASE)
 
324
                        try:
 
325
                                winKernel.writeProcessMemory(processHandle,internalInfo,ctypes.byref(info),ctypes.sizeof(info),None)
 
326
                                textLen=watchdog.cancellableSendMessage(self.obj.windowHandle,EM_GETTEXTLENGTHEX,internalInfo,0)
 
327
                        finally:
 
328
                                winKernel.virtualFreeEx(processHandle,internalInfo,0,winKernel.MEM_RELEASE)
308
329
                        return textLen+1
309
330
                else:
310
 
                        return winUser.sendMessage(self.obj.windowHandle,winUser.WM_GETTEXTLENGTH,0,0)+1
 
331
                        return watchdog.cancellableSendMessage(self.obj.windowHandle,winUser.WM_GETTEXTLENGTH,0,0)+1
311
332
 
312
333
        def _getLineCount(self):
313
 
                return winUser.sendMessage(self.obj.windowHandle,EM_GETLINECOUNT,0,0)
 
334
                return watchdog.cancellableSendMessage(self.obj.windowHandle,EM_GETLINECOUNT,0,0)
314
335
 
315
336
        def _getTextRange(self,start,end):
316
337
                if self.obj.editAPIVersion>=2:
323
344
                        textRange.chrg.cpMax=end
324
345
                        processHandle=self.obj.processHandle
325
346
                        internalBuf=winKernel.virtualAllocEx(processHandle,None,bufLen,winKernel.MEM_COMMIT,winKernel.PAGE_READWRITE)
326
 
                        textRange.lpstrText=internalBuf
327
 
                        internalTextRange=winKernel.virtualAllocEx(processHandle,None,ctypes.sizeof(textRange),winKernel.MEM_COMMIT,winKernel.PAGE_READWRITE)
328
 
                        winKernel.writeProcessMemory(processHandle,internalTextRange,ctypes.byref(textRange),ctypes.sizeof(textRange),None)
329
 
                        res=winUser.sendMessage(self.obj.windowHandle,EM_GETTEXTRANGE,0,internalTextRange)
330
 
                        winKernel.virtualFreeEx(processHandle,internalTextRange,0,winKernel.MEM_RELEASE)
331
 
                        buf=(ctypes.c_byte*bufLen)()
332
 
                        winKernel.readProcessMemory(processHandle,internalBuf,buf,bufLen,None)
333
 
                        winKernel.virtualFreeEx(processHandle,internalBuf,0,winKernel.MEM_RELEASE)
 
347
                        try:
 
348
                                textRange.lpstrText=internalBuf
 
349
                                internalTextRange=winKernel.virtualAllocEx(processHandle,None,ctypes.sizeof(textRange),winKernel.MEM_COMMIT,winKernel.PAGE_READWRITE)
 
350
                                try:
 
351
                                        winKernel.writeProcessMemory(processHandle,internalTextRange,ctypes.byref(textRange),ctypes.sizeof(textRange),None)
 
352
                                        res=watchdog.cancellableSendMessage(self.obj.windowHandle,EM_GETTEXTRANGE,0,internalTextRange)
 
353
                                finally:
 
354
                                        winKernel.virtualFreeEx(processHandle,internalTextRange,0,winKernel.MEM_RELEASE)
 
355
                                buf=(ctypes.c_byte*bufLen)()
 
356
                                winKernel.readProcessMemory(processHandle,internalBuf,buf,bufLen,None)
 
357
                        finally:
 
358
                                winKernel.virtualFreeEx(processHandle,internalBuf,0,winKernel.MEM_RELEASE)
334
359
                        if self.obj.isWindowUnicode or (res>1 and (buf[res]!=0 or buf[res+1]!=0)): 
335
360
                                return ctypes.cast(buf,ctypes.c_wchar_p).value
336
361
                        else:
340
365
 
341
366
        def _getWordOffsets(self,offset):
342
367
                if self.obj.editAPIVersion>=2:
343
 
                        start=winUser.sendMessage(self.obj.windowHandle,EM_FINDWORDBREAK,WB_MOVEWORDLEFT,offset)
344
 
                        end=winUser.sendMessage(self.obj.windowHandle,EM_FINDWORDBREAK,WB_MOVEWORDRIGHT,start)
 
368
                        start=watchdog.cancellableSendMessage(self.obj.windowHandle,EM_FINDWORDBREAK,WB_MOVEWORDLEFT,offset)
 
369
                        end=watchdog.cancellableSendMessage(self.obj.windowHandle,EM_FINDWORDBREAK,WB_MOVEWORDRIGHT,start)
345
370
                        if end<=offset:
346
371
                                start=end
347
 
                                end=winUser.sendMessage(self.obj.windowHandle,EM_FINDWORDBREAK,WB_MOVEWORDRIGHT,offset)
 
372
                                end=watchdog.cancellableSendMessage(self.obj.windowHandle,EM_FINDWORDBREAK,WB_MOVEWORDRIGHT,offset)
348
373
                        return (start,end)
349
 
                elif self.obj==api.getFocusObject():
350
 
                        if offset>=(self._getStoryLength()-1):
351
 
                                return [offset,offset+1]
352
 
                        oldSel=self._getSelectionOffsets()
353
 
                        self._setSelectionOffsets(offset,offset)
354
 
                        sendKey(key("control+ExtendedLeft"))
355
 
                        back=self._getSelectionOffsets()[0]
356
 
                        sendKey(key("control+ExtendedRight"))
357
 
                        forward=self._getSelectionOffsets()[0]
358
 
                        if (back<=offset) and (forward>offset):
359
 
                                start=back
360
 
                                end=forward
361
 
                        elif (back<offset) and (forward==offset):
362
 
                                start=forward
363
 
                                sendKey(key("control+ExtendedRight"))
364
 
                                forward=self._getSelectionOffsets()[0]
365
 
                                end=forward
 
374
                elif sys.getwindowsversion().major<6: #Implementation of standard edit field wordbreak behaviour (only breaks on space)
 
375
                        lineStart,lineEnd=self._getLineOffsets(offset)
 
376
                        if offset>=lineEnd:
 
377
                                return offset,offset+1
 
378
                        lineText=self._getTextRange(lineStart,lineEnd)
 
379
                        lineTextLen=len(lineText)
 
380
                        relativeOffset=offset-lineStart
 
381
                        if relativeOffset>=lineTextLen:
 
382
                                return offset,offset+1
 
383
                        #cariage returns are always treeted as a word by themselves
 
384
                        if lineText[relativeOffset] in ['\r','\n']:
 
385
                                return offset,offset+1
 
386
                        #Find the start of the word (possibly moving through space to get to the word first)
 
387
                        tempOffset=relativeOffset
 
388
                        while tempOffset>0 and lineText[tempOffset].isspace():
 
389
                                tempOffset-=1
 
390
                        while tempOffset>0 and not lineText[tempOffset].isspace():
 
391
                                tempOffset-=1
 
392
                        start=lineStart+tempOffset
 
393
                        startOnSpace=True if tempOffset<lineTextLen and lineText[tempOffset].isspace() else False
 
394
                        #Find the end of the word and trailing space
 
395
                        tempOffset=relativeOffset
 
396
                        if startOnSpace:
 
397
                                while tempOffset<lineTextLen and lineText[tempOffset].isspace():
 
398
                                        tempOffset+=1
 
399
                        while tempOffset<lineTextLen and not lineText[tempOffset].isspace():
 
400
                                tempOffset+=1
 
401
                        while tempOffset<lineTextLen and lineText[tempOffset].isspace():
 
402
                                tempOffset+=1
 
403
                        end=lineStart+tempOffset
 
404
                        return start,end
 
405
                else:
 
406
                        if self._getTextRange(offset,offset+1) in ['\r','\n']:
 
407
                                return offset,offset+1
366
408
                        else:
367
409
                                return super(EditTextInfo,self)._getWordOffsets(offset)
368
 
                        self._setSelectionOffsets(oldSel[0],oldSel[1])
369
 
                        return [start,end]
370
 
                else:
371
 
                        return super(EditTextInfo,self)._getWordOffsets(offset)
 
410
 
372
411
 
373
412
        def _getLineNumFromOffset(self,offset):
374
413
                if self.obj.editAPIVersion>=1:
375
 
                        res=winUser.sendMessage(self.obj.windowHandle,EM_EXLINEFROMCHAR,0,offset)
 
414
                        res=watchdog.cancellableSendMessage(self.obj.windowHandle,EM_EXLINEFROMCHAR,0,offset)
376
415
                        return res
377
416
                else:
378
 
                        return winUser.sendMessage(self.obj.windowHandle,EM_LINEFROMCHAR,offset,0)
 
417
                        return watchdog.cancellableSendMessage(self.obj.windowHandle,EM_LINEFROMCHAR,offset,0)
379
418
 
380
419
        def _getLineOffsets(self,offset):
381
420
                lineNum=self._getLineNumFromOffset(offset)
382
 
                start=winUser.sendMessage(self.obj.windowHandle,EM_LINEINDEX,lineNum,0)
383
 
                length=winUser.sendMessage(self.obj.windowHandle,EM_LINELENGTH,offset,0)
 
421
                start=watchdog.cancellableSendMessage(self.obj.windowHandle,EM_LINEINDEX,lineNum,0)
 
422
                length=watchdog.cancellableSendMessage(self.obj.windowHandle,EM_LINELENGTH,offset,0)
384
423
                end=start+length
385
424
                #If we just seem to get invalid line info, calculate manually
386
425
                if start<=0 and end<=0 and lineNum<=0 and self._getLineCount()<=0 and self._getStoryLength()>0:
439
478
                charFormat.cbSize=ctypes.sizeof(charFormatStruct)
440
479
                processHandle=self.obj.processHandle
441
480
                internalCharFormat=winKernel.virtualAllocEx(processHandle,None,ctypes.sizeof(charFormat),winKernel.MEM_COMMIT,winKernel.PAGE_READWRITE)
442
 
                winKernel.writeProcessMemory(processHandle,internalCharFormat,ctypes.byref(charFormat),ctypes.sizeof(charFormat),None)
443
 
                winUser.sendMessage(self.obj.windowHandle,EM_GETCHARFORMAT,SCF_SELECTION, internalCharFormat)
444
 
                winKernel.readProcessMemory(processHandle,internalCharFormat,ctypes.byref(charFormat),ctypes.sizeof(charFormat),None)
445
 
                winKernel.virtualFreeEx(processHandle,internalCharFormat,0,winKernel.MEM_RELEASE)
 
481
                try:
 
482
                        winKernel.writeProcessMemory(processHandle,internalCharFormat,ctypes.byref(charFormat),ctypes.sizeof(charFormat),None)
 
483
                        watchdog.cancellableSendMessage(self.obj.windowHandle,EM_GETCHARFORMAT,SCF_SELECTION, internalCharFormat)
 
484
                        winKernel.readProcessMemory(processHandle,internalCharFormat,ctypes.byref(charFormat),ctypes.sizeof(charFormat),None)
 
485
                finally:
 
486
                        winKernel.virtualFreeEx(processHandle,internalCharFormat,0,winKernel.MEM_RELEASE)
446
487
                if not (oldSel.start==range.start and oldSel.end==range.end):
447
488
                        self.obj.ITextSelectionObject.start=oldSel.start
448
489
                        self.obj.ITextSelectionObject.end=oldSel.end
508
549
                if range.start<startLimit:
509
550
                        range.start=startLimit
510
551
 
 
552
        def _getEmbeddedObjectLabel(self,embedRangeObj):
 
553
                label=None
 
554
                try:
 
555
                        o=embedRangeObj.GetEmbeddedObject()
 
556
                except comtypes.COMError:
 
557
                        o=None
 
558
                if not o:
 
559
                        return None
 
560
                import oleacc
 
561
                try:
 
562
                        label=o.QueryInterface(oleacc.IAccessible).accName(0);
 
563
                except comtypes.COMError:
 
564
                        pass
 
565
                if label:
 
566
                        return label
 
567
                left,top=embedRangeObj.GetPoint(comInterfaces.tom.tomStart)
 
568
                right,bottom=embedRangeObj.GetPoint(comInterfaces.tom.tomEnd)
 
569
                import displayModel
 
570
                label=displayModel.getWindowTextInRect(self.obj.appModule.helperLocalBindingHandle, self.obj.windowHandle, left, top, right, bottom+10,1,1)[0]
 
571
                if label and not label.isspace():
 
572
                        return label
 
573
                try:
 
574
                        dataObj=o.QueryInterface(oleTypes.IDataObject)
 
575
                except comtypes.COMError:
 
576
                        dataObj=None
 
577
                if dataObj:
 
578
                        try:
 
579
                                dataObj=pythoncom._univgw.interface(hash(dataObj),pythoncom.IID_IDataObject)
 
580
                                format=(win32clipboard.CF_UNICODETEXT, None, pythoncom.DVASPECT_CONTENT, -1, pythoncom.TYMED_HGLOBAL)
 
581
                                medium=dataObj.GetData(format)
 
582
                                buf=ctypes.create_string_buffer(medium.data)
 
583
                                buf=ctypes.cast(buf,ctypes.c_wchar_p)
 
584
                                label=buf.value
 
585
                        except:
 
586
                                pass
 
587
                if label:
 
588
                        return label
 
589
                try:
 
590
                        oleObj=o.QueryInterface(oleTypes.IOleObject)
 
591
                        label=oleObj.GetUserType(1)
 
592
                except comtypes.COMError:
 
593
                        pass
 
594
                return label
 
595
 
511
596
        def _getTextAtRange(self,rangeObj):
512
597
                embedRangeObj=None
513
598
                bufText=rangeObj.text
518
603
                for offset in range(len(bufText)):
519
604
                        if ord(bufText[offset])==0xfffc:
520
605
                                if embedRangeObj is None: embedRangeObj=rangeObj.duplicate
521
 
                                embedRangeObj.setRange(start+offset,start+offset)
522
 
                                try:
523
 
                                        o=embedRangeObj.GetEmbeddedObject()
524
 
                                        #Fetch a description for this object
525
 
                                        o=o.QueryInterface(oleTypes.IOleObject)
526
 
                                        dataObj=o.GetClipboardData(0)
527
 
                                        dataObj=pythoncom._univgw.interface(hash(dataObj),pythoncom.IID_IDataObject)
528
 
                                        format=(win32clipboard.CF_UNICODETEXT, None, pythoncom.DVASPECT_CONTENT, -1, pythoncom.TYMED_HGLOBAL)
529
 
                                        medium=dataObj.GetData(format)
530
 
                                        buf=ctypes.create_string_buffer(medium.data)
531
 
                                        buf=ctypes.cast(buf,ctypes.c_wchar_p)
532
 
                                        label=buf.value
533
 
                                except comtypes.COMError:
534
 
                                        label=_("unknown")
 
606
                                embedRangeObj.setRange(start+offset,start+offset+1)
 
607
                                label=self._getEmbeddedObjectLabel(embedRangeObj)
535
608
                                if label:
536
 
                                        newTextList.append(_("%s embedded object")%label)
 
609
                                        newTextList.append(label)
537
610
                                else:
538
611
                                        newTextList.append(_("embedded object"))
539
612
                        else:
670
743
                self.obj.ITextSelectionObject.start=self._rangeObj.start
671
744
                self.obj.ITextSelectionObject.end=self._rangeObj.end
672
745
 
673
 
class Edit(EditableText, Window):
 
746
class Edit(EditableTextWithAutoSelectDetection, Window):
674
747
 
675
748
        editAPIVersion=0
676
749
        editAPIUnicode=True
678
751
        editValueUnit=textInfos.UNIT_LINE
679
752
 
680
753
        def _get_TextInfo(self):
681
 
                if self.editAPIVersion>1 and self.useITextDocumentSupport and self.ITextDocumentObject:
 
754
                if self.editAPIVersion>1 and (self.useITextDocumentSupport or self.windowClassName.endswith('PT')) and self.ITextDocumentObject:
682
755
                        return ITextDocumentTextInfo
683
756
                else:
684
757
                        return EditTextInfo
725
798
                self.detectPossibleSelectionChange()
726
799
 
727
800
        def event_valueChange(self):
728
 
                self.hasContentChangedSinceLastSelection=True
729
 
 
730
 
        def event_gainFocus(self):
731
 
                self.initAutoSelectDetection()
732
 
                super(Edit,self).event_gainFocus()
 
801
                self.event_textChange()
733
802
 
734
803
        def _get_states(self):
735
804
                states = super(Edit, self)._get_states()