1
2
3
4
5
6
7 """
8 Implementation of cursor managers.
9 A cursor manager provides caret navigation and selection commands for a virtual text range.
10 """
11
12 import wx
13 import baseObject
14 import gui
15 import textInfos
16 import api
17 import speech
18 import config
19 import braille
20
22 """
23 A mix-in providing caret navigation and selection commands for the object's virtual text range.
24 This is required where a text range is not linked to a physical control and thus does not provide commands to move the cursor, select and copy text, etc.
25 This base cursor manager requires that the text range being used stores its own caret and selection information.
26
27 This is a mix-in class; i.e. it should be inherited alongside another L{baseObject.ScriptableObject}.
28 The class into which it is inherited must provide a C{makeTextInfo(position)} method.
29
30 @ivar selection: The current caret/selection range.
31 @type selection: L{textInfos.TextInfo}
32 """
33
34 _lastFindText=""
35
39
41 """Performs automatic initialisation if this is being used as an overlay class."""
42 self.initCursorManager()
43
45 """Initialise this cursor manager.
46 This must be called before the cursor manager functionality can be used.
47 It is normally called by L{__init__} or L{initOverlayClass}.
48 """
49 self._lastSelectionMovedStart=False
50
53
57
78
80 d = wx.TextEntryDialog(gui.mainFrame, _("Type the text you wish to find"), _("Find"), defaultValue=self._lastFindText)
81 def callback(result):
82 if result == wx.ID_OK:
83
84 wx.CallLater(100, self.doFindText, d.GetValue())
85 gui.runScriptModalDialog(d, callback)
86
87 - def doFindText(self,text,reverse=False):
88 if not text:
89 return
90 info=self.makeTextInfo(textInfos.POSITION_CARET)
91 res=info.find(text,reverse=reverse)
92 if res:
93 self.selection=info
94 speech.cancelSpeech()
95 info.move(textInfos.UNIT_LINE,1,endPoint="end")
96 speech.speakTextInfo(info,reason=speech.REASON_CARET)
97 else:
98 wx.CallAfter(gui.messageBox,_('text "%s" not found')%text,_("Find Error"),wx.OK|wx.ICON_ERROR)
99 CursorManager._lastFindText=text
100
102 self.doFindTextDialog()
103 script_find.__doc__ = _("find a text string from the current cursor position")
104
110 script_findNext.__doc__ = _("find the next occurrence of the previously entered text string from the current cursor's position")
111
117 script_findPrevious.__doc__ = _("find the previous occurrence of the previously entered text string from the current cursor's position")
118
119 - def script_moveByPage_back(self,gesture):
120 self._caretMovementScriptHelper(textInfos.UNIT_LINE,-config.conf["virtualBuffers"]["linesPerPage"],extraDetail=False)
121
123 self._caretMovementScriptHelper(textInfos.UNIT_LINE,config.conf["virtualBuffers"]["linesPerPage"],extraDetail=False)
124
127
130
133
136
139
142
145
148
151
154
157
160
162 oldInfo=self.makeTextInfo(textInfos.POSITION_SELECTION)
163 if toPosition:
164 newInfo=self.makeTextInfo(toPosition)
165 if newInfo.compareEndPoints(oldInfo,"startToStart")>0:
166 newInfo.setEndPoint(oldInfo,"startToStart")
167 if newInfo.compareEndPoints(oldInfo,"endToEnd")<0:
168 newInfo.setEndPoint(oldInfo,"endToEnd")
169 elif unit:
170 newInfo=oldInfo.copy()
171 if unit:
172 if self._lastSelectionMovedStart:
173 newInfo.move(unit,direction,endPoint="start")
174 else:
175 newInfo.move(unit,direction,endPoint="end")
176 self.selection = newInfo
177 if newInfo.compareEndPoints(oldInfo,"startToStart")!=0:
178 self._lastSelectionMovedStart=True
179 else:
180 self._lastSelectionMovedStart=False
181 if newInfo.compareEndPoints(oldInfo,"endToEnd")!=0:
182 self._lastSelectionMovedStart=False
183 speech.speakSelectionChange(oldInfo,newInfo)
184
187
190
193
196
199
202
204 self._selectionMovementScriptHelper(unit=textInfos.UNIT_LINE,direction=config.conf["virtualBuffers"]["linesPerPage"])
205
206 - def script_selectPage_back(self,gesture):
207 self._selectionMovementScriptHelper(unit=textInfos.UNIT_LINE,direction=-config.conf["virtualBuffers"]["linesPerPage"])
208
211
214
222
231
234
237
240
248
249 __gestures = {
250 "kb:pageUp": "moveByPage_back",
251 "kb:pageDown": "moveByPage_forward",
252 "kb:upArrow": "moveByLine_back",
253 "kb:downArrow": "moveByLine_forward",
254 "kb:leftArrow": "moveByCharacter_back",
255 "kb:rightArrow": "moveByCharacter_forward",
256 "kb:control+leftArrow": "moveByWord_back",
257 "kb:control+rightArrow": "moveByWord_forward",
258 "kb:control+upArrow": "moveByParagraph_back",
259 "kb:control+downArrow": "moveByParagraph_forward",
260 "kb:home": "startOfLine",
261 "kb:end": "endOfLine",
262 "kb:control+home": "topOfDocument",
263 "kb:control+end": "bottomOfDocument",
264 "kb:shift+rightArrow": "selectCharacter_forward",
265 "kb:shift+leftArrow": "selectCharacter_back",
266 "kb:shift+control+rightArrow": "selectWord_forward",
267 "kb:shift+control+leftArrow": "selectWord_back",
268 "kb:shift+downArrow": "selectLine_forward",
269 "kb:shift+upArrow": "selectLine_back",
270 "kb:shift+pageDown": "selectPage_forward",
271 "kb:shift+pageUp": "selectPage_back",
272 "kb:shift+control+downArrow": "selectParagraph_forward",
273 "kb:shift+control+upArrow": "selectParagraph_back",
274 "kb:shift+end": "selectToEndOfLine",
275 "kb:shift+home": "selectToBeginningOfLine",
276 "kb:shift+control+end": "selectToBottomOfDocument",
277 "kb:shift+control+home": "selectToTopOfDocument",
278 "kb:control+a": "selectAll",
279 "kb:control+c": "copyToClipboard",
280 "kb:NVDA+Control+f": "find",
281 "kb:NVDA+f3": "findNext",
282 "kb:NVDA+shift+f3": "findPrevious",
283 }
284
285 -class _ReviewCursorManagerTextInfo(textInfos.TextInfo):
286 """For use with L{ReviewCursorManager}.
287 Overrides L{updateCaret} and L{updateSelection} to use the selection property on the underlying object.
288 """
289
290 - def updateCaret(self):
291 self.obj.selection = self
292
293 - def updateSelection(self):
294 self.obj.selection = self
295
297 """
298 A cursor manager used for review.
299 This cursor manager maintains its own caret and selection information.
300 Thus, the underlying text range need not support updating the caret or selection.
301 """
302
308
309 - def makeTextInfo(self, position):
310 if position == textInfos.POSITION_SELECTION:
311 return self.selection
312 elif position == textInfos.POSITION_CARET:
313 sel = self.selection
314 sel.collapse()
315 return sel
316 return super(ReviewCursorManager, self).makeTextInfo(position)
317
319 return self._selection.copy()
320
324