1 """Shell is an interactive text control in which a user types in 
   2 commands to be sent to the interpreter.  This particular shell is 
   3 based on wxPython's wxStyledTextCtrl. 
   5 Sponsored by Orbtech - Your source for Python programming expertise.""" 
   7 __author__ 
= "Patrick K. O'Brien <pobrien@orbtech.com>" 
   9 __revision__ 
= "$Revision$"[11:-2] 
  19 from buffer import Buffer
 
  23 from pseudo 
import PseudoFileIn
 
  24 from pseudo 
import PseudoFileOut
 
  25 from pseudo 
import PseudoFileErr
 
  26 from version 
import VERSION
 
  28 sys
.ps3 
= '<-- '  # Input prompt. 
  30 NAVKEYS 
= (wx
.WXK_END
, wx
.WXK_LEFT
, wx
.WXK_RIGHT
, 
  31            wx
.WXK_UP
, wx
.WXK_DOWN
, wx
.WXK_PRIOR
, wx
.WXK_NEXT
) 
  34 class ShellFrame(frame
.Frame
, frame
.ShellFrameMixin
): 
  35     """Frame containing the shell component.""" 
  38     revision 
= __revision__
 
  40     def __init__(self
, parent
=None, id=-1, title
='PyShell', 
  41                  pos
=wx
.DefaultPosition
, size
=wx
.DefaultSize
, 
  42                  style
=wx
.DEFAULT_FRAME_STYLE
, locals=None, 
  44                  config
=None, dataDir
=None, 
  46         """Create ShellFrame instance.""" 
  47         frame
.Frame
.__init
__(self
, parent
, id, title
, pos
, size
, style
) 
  48         frame
.ShellFrameMixin
.__init
__(self
, config
, dataDir
) 
  50         if size 
== wx
.DefaultSize
: 
  51             self
.SetSize((750, 525)) 
  53         intro 
= 'PyShell %s - The Flakiest Python Shell' % VERSION
 
  54         self
.SetStatusText(intro
.replace('\n', ', ')) 
  55         self
.shell 
= Shell(parent
=self
, id=-1, introText
=intro
, 
  56                            locals=locals, InterpClass
=InterpClass
, 
  57                            startupScript
=self
.startupScript
, 
  58                            execStartupScript
=self
.execStartupScript
, 
  61         # Override the shell so that status messages go to the status bar. 
  62         self
.shell
.setStatusText 
= self
.SetStatusText
 
  68     def OnClose(self
, event
): 
  69         """Event handler for closing.""" 
  70         # This isn't working the way I want, but I'll leave it for now. 
  71         if self
.shell
.waiting
: 
  79     def OnAbout(self
, event
): 
  80         """Display an About window.""" 
  81         title 
= 'About PyShell' 
  82         text 
= 'PyShell %s\n\n' % VERSION 
+ \
 
  83                'Yet another Python shell, only flakier.\n\n' + \
 
  84                'Half-baked by Patrick K. O\'Brien,\n' + \
 
  85                'the other half is still in the oven.\n\n' + \
 
  86                'Shell Revision: %s\n' % self
.shell
.revision 
+ \
 
  87                'Interpreter Revision: %s\n\n' % self
.shell
.interp
.revision 
+ \
 
  88                'Platform: %s\n' % sys
.platform 
+ \
 
  89                'Python Version: %s\n' % sys
.version
.split()[0] + \
 
  90                'wxPython Version: %s\n' % wx
.VERSION_STRING 
+ \
 
  91                ('\t(%s)\n' % ", ".join(wx
.PlatformInfo
[1:]))  
  92         dialog 
= wx
.MessageDialog(self
, text
, title
, 
  93                                   wx
.OK | wx
.ICON_INFORMATION
) 
  98     def OnHelp(self
, event
): 
  99         """Show a help dialog.""" 
 100         frame
.ShellFrameMixin
.OnHelp(self
, event
) 
 103     def LoadSettings(self
): 
 104         if self
.config 
is not None: 
 105             frame
.ShellFrameMixin
.LoadSettings(self
) 
 106             frame
.Frame
.LoadSettings(self
, self
.config
) 
 107             self
.shell
.LoadSettings(self
.config
) 
 109     def SaveSettings(self
, force
=False): 
 110         if self
.config 
is not None: 
 111             frame
.ShellFrameMixin
.SaveSettings(self
) 
 112             if self
.autoSaveSettings 
or force
: 
 113                 frame
.Frame
.SaveSettings(self
, self
.config
) 
 114                 self
.shell
.SaveSettings(self
.config
) 
 116     def DoSaveSettings(self
): 
 117         if self
.config 
is not None: 
 118             self
.SaveSettings(force
=True) 
 126 Home              Go to the beginning of the command or line. 
 127 Shift+Home        Select to the beginning of the command or line. 
 128 Shift+End         Select to the end of the line. 
 129 End               Go to the end of the line. 
 130 Ctrl+C            Copy selected text, removing prompts. 
 131 Ctrl+Shift+C      Copy selected text, retaining prompts. 
 132 Alt+C             Copy to the clipboard, including prefixed prompts. 
 133 Ctrl+X            Cut selected text. 
 134 Ctrl+V            Paste from clipboard. 
 135 Ctrl+Shift+V      Paste and run multiple commands from clipboard. 
 136 Ctrl+Up Arrow     Retrieve Previous History item. 
 137 Alt+P             Retrieve Previous History item. 
 138 Ctrl+Down Arrow   Retrieve Next History item. 
 139 Alt+N             Retrieve Next History item. 
 140 Shift+Up Arrow    Insert Previous History item. 
 141 Shift+Down Arrow  Insert Next History item. 
 142 F8                Command-completion of History item. 
 143                   (Type a few characters of a previous command and press F8.) 
 144 Ctrl+Enter        Insert new line into multiline command. 
 145 Ctrl+]            Increase font size. 
 146 Ctrl+[            Decrease font size. 
 147 Ctrl+=            Default font size. 
 148 Ctrl-Space        Show Auto Completion. 
 149 Ctrl-Alt-Space    Show Call Tip. 
 150 Shift+Enter       Complete Text from History. 
 153 Ctrl+H            "hide" lines containing selection / "unhide" 
 154 F12               on/off "free-edit" mode 
 158     """Simplified interface to all shell-related functionality. 
 160     This is a semi-transparent facade, in that all attributes of other 
 161     are accessible, even though only some are visible to the user.""" 
 163     name 
= 'Shell Interface' 
 164     revision 
= __revision__
 
 166     def __init__(self
, other
): 
 167         """Create a ShellFacade instance.""" 
 170         d
['helpText'] = HELP_TEXT
 
 171         d
['this'] = other
.this
 
 174         """Display some useful information about how to use the shell.""" 
 175         self
.write(self
.helpText
) 
 177     def __getattr__(self
, name
): 
 178         if hasattr(self
.other
, name
): 
 179             return getattr(self
.other
, name
) 
 181             raise AttributeError, name
 
 183     def __setattr__(self
, name
, value
): 
 184         if self
.__dict
__.has_key(name
): 
 185             self
.__dict
__[name
] = value
 
 186         elif hasattr(self
.other
, name
): 
 187             setattr(self
.other
, name
, value
) 
 189             raise AttributeError, name
 
 191     def _getAttributeNames(self
): 
 192         """Return list of magic attributes to extend introspection.""" 
 198             'autoCompleteAutoHide', 
 199             'autoCompleteCaseInsensitive', 
 200             'autoCompleteIncludeDouble', 
 201             'autoCompleteIncludeMagic', 
 202             'autoCompleteIncludeSingle', 
 221 class Shell(editwindow
.EditWindow
): 
 222     """Shell based on StyledTextCtrl.""" 
 225     revision 
= __revision__
 
 227     def __init__(self
, parent
, id=-1, pos
=wx
.DefaultPosition
, 
 228                  size
=wx
.DefaultSize
, style
=wx
.CLIP_CHILDREN
, 
 229                  introText
='', locals=None, InterpClass
=None, 
 230                  startupScript
=None, execStartupScript
=True, 
 232         """Create Shell instance.""" 
 233         editwindow
.EditWindow
.__init
__(self
, parent
, id, pos
, size
, style
) 
 237             locals = __main__
.__dict
__ 
 239         # Grab these so they can be restored by self.redirect* methods. 
 240         self
.stdin 
= sys
.stdin
 
 241         self
.stdout 
= sys
.stdout
 
 242         self
.stderr 
= sys
.stderr
 
 244         # Import a default interpreter class if one isn't provided. 
 245         if InterpClass 
== None: 
 246             from interpreter 
import Interpreter
 
 248             Interpreter 
= InterpClass
 
 250         # Create a replacement for stdin. 
 251         self
.reader 
= PseudoFileIn(self
.readline
, self
.readlines
) 
 252         self
.reader
.input = '' 
 253         self
.reader
.isreading 
= False 
 255         # Set up the interpreter. 
 256         self
.interp 
= Interpreter(locals=locals, 
 257                                   rawin
=self
.raw_input, 
 259                                   stdout
=PseudoFileOut(self
.writeOut
), 
 260                                   stderr
=PseudoFileErr(self
.writeErr
), 
 264         self
.buffer = Buffer() 
 266         # Find out for which keycodes the interpreter will autocomplete. 
 267         self
.autoCompleteKeys 
= self
.interp
.getAutoCompleteKeys() 
 269         # Keep track of the last non-continuation prompt positions. 
 270         self
.promptPosStart 
= 0 
 271         self
.promptPosEnd 
= 0 
 273         # Keep track of multi-line commands. 
 276         # Create the command history.  Commands are added into the 
 277         # front of the list (ie. at index 0) as they are entered. 
 278         # self.historyIndex is the current position in the history; it 
 279         # gets incremented as you retrieve the previous command, 
 280         # decremented as you retrieve the next, and reset when you hit 
 281         # Enter.  self.historyIndex == -1 means you're on the current 
 282         # command, not in the history. 
 284         self
.historyIndex 
= -1 
 286         #seb add mode for "free edit" 
 288         self
.MarkerDefine(0,stc
.STC_MARK_ROUNDRECT
)  # marker for hidden 
 291         # Assign handlers for keyboard events. 
 292         self
.Bind(wx
.EVT_CHAR
, self
.OnChar
) 
 293         self
.Bind(wx
.EVT_KEY_DOWN
, self
.OnKeyDown
) 
 295         # Assign handler for idle time. 
 297         self
.Bind(wx
.EVT_IDLE
, self
.OnIdle
) 
 299         # Display the introductory banner information. 
 300         self
.showIntro(introText
) 
 302         # Assign some pseudo keywords to the interpreter's namespace. 
 303         self
.setBuiltinKeywords() 
 305         # Add 'shell' to the interpreter's local namespace. 
 308         ## NOTE:  See note at bottom of this file... 
 309         ## #seb: File drag and drop 
 310         ## self.SetDropTarget( FileDropTarget(self) ) 
 312         # Do this last so the user has complete control over their 
 313         # environment.  They can override anything they want. 
 314         if execStartupScript
: 
 315             if startupScript 
is None: 
 316                 startupScript 
= os
.environ
.get('PYTHONSTARTUP') 
 317             self
.execStartupScript(startupScript
) 
 321         wx
.CallAfter(self
.ScrollToLine
, 0) 
 324     def clearHistory(self
): 
 326         self
.historyIndex 
= -1 
 327         dispatcher
.send(signal
="Shell.clearHistory") 
 334         """Set focus to the shell.""" 
 337     def OnIdle(self
, event
): 
 338         """Free the CPU to do other things.""" 
 343     def showIntro(self
, text
=''): 
 344         """Display introductory text in the shell.""" 
 348             if self
.interp
.introText
: 
 349                 if text 
and not text
.endswith(os
.linesep
): 
 350                     self
.write(os
.linesep
) 
 351                 self
.write(self
.interp
.introText
) 
 352         except AttributeError: 
 355     def setBuiltinKeywords(self
): 
 356         """Create pseudo keywords as part of builtins. 
 358         This sets "close", "exit" and "quit" to a helpful string. 
 361         __builtin__
.close 
= __builtin__
.exit 
= __builtin__
.quit 
= \
 
 362             'Click on the close button to leave the application.' 
 366         """Quit the application.""" 
 367         # XXX Good enough for now but later we want to send a close event. 
 368         # In the close event handler we can make sure they want to 
 369         # quit.  Other applications, like PythonCard, may choose to 
 370         # hide rather than quit so we should just post the event and 
 371         # let the surrounding app decide what it wants to do. 
 372         self
.write('Click on the close button to leave the application.') 
 375     def setLocalShell(self
): 
 376         """Add 'shell' to locals as reference to ShellFacade instance.""" 
 377         self
.interp
.locals['shell'] = ShellFacade(other
=self
) 
 380     def execStartupScript(self
, startupScript
): 
 381         """Execute the user's PYTHONSTARTUP script if they have one.""" 
 382         if startupScript 
and os
.path
.isfile(startupScript
): 
 383             text 
= 'Startup script executed: ' + startupScript
 
 384             self
.push('print %r; execfile(%r)' % (text
, startupScript
)) 
 385             self
.interp
.startupScript 
= startupScript
 
 391         """Display information about Py.""" 
 395 Py Shell Revision: %s 
 396 Py Interpreter Revision: %s 
 399 wxPython PlatformInfo: %s 
 401         (__author__
, VERSION
, self
.revision
, self
.interp
.revision
, 
 402          sys
.version
.split()[0], wx
.VERSION_STRING
, str(wx
.PlatformInfo
), 
 404         self
.write(text
.strip()) 
 407     def OnChar(self
, event
): 
 408         """Keypress event handler. 
 410         Only receives an event if OnKeyDown calls event.Skip() for the 
 411         corresponding event.""" 
 417         # Prevent modification of previously submitted 
 418         # commands/responses. 
 419         if not self
.CanEdit(): 
 421         key 
= event
.GetKeyCode() 
 422         currpos 
= self
.GetCurrentPos() 
 423         stoppos 
= self
.promptPosEnd
 
 424         # Return (Enter) needs to be ignored in this handler. 
 425         if key 
in [wx
.WXK_RETURN
, wx
.WXK_NUMPAD_ENTER
]: 
 427         elif key 
in self
.autoCompleteKeys
: 
 428             # Usually the dot (period) key activates auto completion. 
 429             # Get the command between the prompt and the cursor.  Add 
 430             # the autocomplete character to the end of the command. 
 431             if self
.AutoCompActive(): 
 432                 self
.AutoCompCancel() 
 433             command 
= self
.GetTextRange(stoppos
, currpos
) + chr(key
) 
 435             if self
.autoComplete
: 
 436                 self
.autoCompleteShow(command
) 
 437         elif key 
== ord('('): 
 438             # The left paren activates a call tip and cancels an 
 439             # active auto completion. 
 440             if self
.AutoCompActive(): 
 441                 self
.AutoCompCancel() 
 442             # Get the command between the prompt and the cursor.  Add 
 443             # the '(' to the end of the command. 
 444             self
.ReplaceSelection('') 
 445             command 
= self
.GetTextRange(stoppos
, currpos
) + '(' 
 447             self
.autoCallTipShow(command
, self
.GetCurrentPos() == self
.GetTextLength()) 
 449             # Allow the normal event handling to take place. 
 453     def OnKeyDown(self
, event
): 
 454         """Key down event handler.""" 
 456         key 
= event
.GetKeyCode() 
 457         # If the auto-complete window is up let it do its thing. 
 458         if self
.AutoCompActive(): 
 462         # Prevent modification of previously submitted 
 463         # commands/responses. 
 464         controlDown 
= event
.ControlDown() 
 465         altDown 
= event
.AltDown() 
 466         shiftDown 
= event
.ShiftDown() 
 467         currpos 
= self
.GetCurrentPos() 
 468         endpos 
= self
.GetTextLength() 
 469         selecting 
= self
.GetSelectionStart() != self
.GetSelectionEnd() 
 471         if controlDown 
and shiftDown 
and key 
in (ord('F'), ord('f')):  
 472             li 
= self
.GetCurrentLine() 
 473             m 
= self
.MarkerGet(li
) 
 475                 startP 
= self
.PositionFromLine(li
) 
 476                 self
.MarkerDelete(li
, 0) 
 477                 maxli 
= self
.GetLineCount() 
 478                 li 
+= 1 # li stayed visible as header-line 
 480                 while li
<maxli 
and self
.GetLineVisible(li
) == 0: 
 482                 endP 
= self
.GetLineEndPosition(li
-1) 
 483                 self
.ShowLines(li0
, li
-1) 
 484                 self
.SetSelection( startP
, endP 
) # select reappearing text to allow "hide again" 
 486             startP
,endP 
= self
.GetSelection() 
 488             startL
,endL 
= self
.LineFromPosition(startP
), self
.LineFromPosition(endP
) 
 490             if endL 
== self
.LineFromPosition(self
.promptPosEnd
): # never hide last prompt 
 493             m 
= self
.MarkerGet(startL
) 
 494             self
.MarkerAdd(startL
, 0) 
 495             self
.HideLines(startL
+1,endL
) 
 496             self
.SetCurrentPos( startP 
) # to ensure caret stays visible ! 
 498         if key 
== wx
.WXK_F12
: #seb 
 500                 # self.promptPosStart not used anyway - or ?  
 501                 self
.promptPosEnd 
= self
.PositionFromLine( self
.GetLineCount()-1 ) + len(str(sys
.ps1
)) 
 502                 self
.GotoLine(self
.GetLineCount()) 
 503                 self
.GotoPos(self
.promptPosEnd
) 
 504                 self
.prompt()  #make sure we have a prompt 
 505                 self
.SetCaretForeground("black") 
 506                 self
.SetCaretWidth(1)    #default 
 507                 self
.SetCaretPeriod(500) #default 
 509                 self
.SetCaretForeground("red") 
 510                 self
.SetCaretWidth(4) 
 511                 self
.SetCaretPeriod(0) #steady 
 513             self
.noteMode 
= not self
.noteMode
 
 519         # Return (Enter) is used to submit a command to the 
 521         if (not controlDown 
and not shiftDown 
and not altDown
) and key 
in [wx
.WXK_RETURN
, wx
.WXK_NUMPAD_ENTER
]: 
 522             if self
.CallTipActive(): 
 526         # Complete Text (from already typed words)     
 527         elif shiftDown 
and key 
in [wx
.WXK_RETURN
, wx
.WXK_NUMPAD_ENTER
]: 
 528             self
.OnShowCompHistory() 
 530         # Ctrl+Return (Ctrl+Enter) is used to insert a line break. 
 531         elif controlDown 
and key 
in [wx
.WXK_RETURN
, wx
.WXK_NUMPAD_ENTER
]: 
 532             if self
.CallTipActive(): 
 534             if currpos 
== endpos
: 
 537                 self
.insertLineBreak() 
 539         # Let Ctrl-Alt-* get handled normally. 
 540         elif controlDown 
and altDown
: 
 543         # Clear the current, unexecuted command. 
 544         elif key 
== wx
.WXK_ESCAPE
: 
 545             if self
.CallTipActive(): 
 550         # Clear the current command 
 551         elif key 
== wx
.WXK_BACK 
and controlDown 
and shiftDown
: 
 554         # Increase font size. 
 555         elif controlDown 
and key 
in (ord(']'), wx
.WXK_NUMPAD_ADD
): 
 556             dispatcher
.send(signal
='FontIncrease') 
 558         # Decrease font size. 
 559         elif controlDown 
and key 
in (ord('['), wx
.WXK_NUMPAD_SUBTRACT
): 
 560             dispatcher
.send(signal
='FontDecrease') 
 563         elif controlDown 
and key 
in (ord('='), wx
.WXK_NUMPAD_DIVIDE
): 
 564             dispatcher
.send(signal
='FontDefault') 
 566         # Cut to the clipboard. 
 567         elif (controlDown 
and key 
in (ord('X'), ord('x'))) \
 
 568                  or (shiftDown 
and key 
== wx
.WXK_DELETE
): 
 571         # Copy to the clipboard. 
 572         elif controlDown 
and not shiftDown \
 
 573                  and key 
in (ord('C'), ord('c'), wx
.WXK_INSERT
): 
 576         # Copy to the clipboard, including prompts. 
 577         elif controlDown 
and shiftDown \
 
 578                  and key 
in (ord('C'), ord('c'), wx
.WXK_INSERT
): 
 579             self
.CopyWithPrompts() 
 581         # Copy to the clipboard, including prefixed prompts. 
 582         elif altDown 
and not controlDown \
 
 583                  and key 
in (ord('C'), ord('c'), wx
.WXK_INSERT
): 
 584             self
.CopyWithPromptsPrefixed() 
 586         # Home needs to be aware of the prompt. 
 587         elif key 
== wx
.WXK_HOME
: 
 588             home 
= self
.promptPosEnd
 
 590                 self
.SetCurrentPos(home
) 
 591                 if not selecting 
and not shiftDown
: 
 593                     self
.EnsureCaretVisible() 
 598         # The following handlers modify text, so we need to see if 
 599         # there is a selection that includes text prior to the prompt. 
 601         # Don't modify a selection with text prior to the prompt. 
 602         elif selecting 
and key 
not in NAVKEYS 
and not self
.CanEdit(): 
 605         # Paste from the clipboard. 
 606         elif (controlDown 
and not shiftDown 
and key 
in (ord('V'), ord('v'))) \
 
 607                  or (shiftDown 
and not controlDown 
and key 
== wx
.WXK_INSERT
): 
 610         # manually invoke AutoComplete and Calltips 
 611         elif controlDown 
and key 
== wx
.WXK_SPACE
: 
 612             self
.OnCallTipAutoCompleteManually(shiftDown
) 
 614         # Paste from the clipboard, run commands. 
 615         elif controlDown 
and shiftDown 
and key 
in (ord('V'), ord('v')): 
 618         # Replace with the previous command from the history buffer. 
 619         elif (controlDown 
and key 
== wx
.WXK_UP
) \
 
 620                  or (altDown 
and key 
in (ord('P'), ord('p'))): 
 621             self
.OnHistoryReplace(step
=+1) 
 623         # Replace with the next command from the history buffer. 
 624         elif (controlDown 
and key 
== wx
.WXK_DOWN
) \
 
 625                  or (altDown 
and key 
in (ord('N'), ord('n'))): 
 626             self
.OnHistoryReplace(step
=-1) 
 628         # Insert the previous command from the history buffer. 
 629         elif (shiftDown 
and key 
== wx
.WXK_UP
) and self
.CanEdit(): 
 630             self
.OnHistoryInsert(step
=+1) 
 632         # Insert the next command from the history buffer. 
 633         elif (shiftDown 
and key 
== wx
.WXK_DOWN
) and self
.CanEdit(): 
 634             self
.OnHistoryInsert(step
=-1) 
 636         # Search up the history for the text in front of the cursor. 
 637         elif key 
== wx
.WXK_F8
: 
 638             self
.OnHistorySearch() 
 640         # Don't backspace over the latest non-continuation prompt. 
 641         elif key 
== wx
.WXK_BACK
: 
 642             if selecting 
and self
.CanEdit(): 
 644             elif currpos 
> self
.promptPosEnd
: 
 647         # Only allow these keys after the latest prompt. 
 648         elif key 
in (wx
.WXK_TAB
, wx
.WXK_DELETE
): 
 652         # Don't toggle between insert mode and overwrite mode. 
 653         elif key 
== wx
.WXK_INSERT
: 
 656         # Don't allow line deletion. 
 657         elif controlDown 
and key 
in (ord('L'), ord('l')): 
 660         # Don't allow line transposition. 
 661         elif controlDown 
and key 
in (ord('T'), ord('t')): 
 664         # Basic navigation keys should work anywhere. 
 668         # Protect the readonly portion of the shell. 
 669         elif not self
.CanEdit(): 
 676     def OnShowCompHistory(self
): 
 677         """Show possible autocompletion Words from already typed words.""" 
 680         his 
= self
.history
[:] 
 682         #put together in one string 
 683         joined 
= " ".join (his
) 
 686         #sort out only "good" words 
 687         newlist 
= re
.split("[ \.\[\]=}(\)\,0-9\"]", joined
) 
 689         #length > 1 (mix out "trash") 
 695         #unique (no duplicate words 
 696         #oneliner from german python forum => unique list 
 697         unlist 
= [thlist
[i
] for i 
in xrange(len(thlist
)) if thlist
[i
] not in thlist
[:i
]] 
 700         unlist
.sort(lambda a
, b
: cmp(a
.lower(), b
.lower())) 
 702         #this is more convenient, isn't it? 
 703         self
.AutoCompSetIgnoreCase(True) 
 705         #join again together in a string 
 706         stringlist 
= " ".join(unlist
) 
 708         #pos von 0 noch ausrechnen 
 710         #how big is the offset? 
 711         cpos 
= self
.GetCurrentPos() - 1 
 712         while chr (self
.GetCharAt (cpos
)).isalnum(): 
 715         #the most important part 
 716         self
.AutoCompShow(self
.GetCurrentPos() - cpos 
-1, stringlist
) 
 719     def clearCommand(self
): 
 720         """Delete the current, unexecuted command.""" 
 721         startpos 
= self
.promptPosEnd
 
 722         endpos 
= self
.GetTextLength() 
 723         self
.SetSelection(startpos
, endpos
) 
 724         self
.ReplaceSelection('') 
 727     def OnHistoryReplace(self
, step
): 
 728         """Replace with the previous/next command from the history buffer.""" 
 730         self
.replaceFromHistory(step
) 
 732     def replaceFromHistory(self
, step
): 
 733         """Replace selection with command from the history buffer.""" 
 735         self
.ReplaceSelection('') 
 736         newindex 
= self
.historyIndex 
+ step
 
 737         if -1 <= newindex 
<= len(self
.history
): 
 738             self
.historyIndex 
= newindex
 
 739         if 0 <= newindex 
<= len(self
.history
)-1: 
 740             command 
= self
.history
[self
.historyIndex
] 
 741             command 
= command
.replace('\n', os
.linesep 
+ ps2
) 
 742             self
.ReplaceSelection(command
) 
 744     def OnHistoryInsert(self
, step
): 
 745         """Insert the previous/next command from the history buffer.""" 
 746         if not self
.CanEdit(): 
 748         startpos 
= self
.GetCurrentPos() 
 749         self
.replaceFromHistory(step
) 
 750         endpos 
= self
.GetCurrentPos() 
 751         self
.SetSelection(endpos
, startpos
) 
 753     def OnHistorySearch(self
): 
 754         """Search up the history buffer for the text in front of the cursor.""" 
 755         if not self
.CanEdit(): 
 757         startpos 
= self
.GetCurrentPos() 
 758         # The text up to the cursor is what we search for. 
 759         numCharsAfterCursor 
= self
.GetTextLength() - startpos
 
 760         searchText 
= self
.getCommand(rstrip
=False) 
 761         if numCharsAfterCursor 
> 0: 
 762             searchText 
= searchText
[:-numCharsAfterCursor
] 
 765         # Search upwards from the current history position and loop 
 766         # back to the beginning if we don't find anything. 
 767         if (self
.historyIndex 
<= -1) \
 
 768         or (self
.historyIndex 
>= len(self
.history
)-2): 
 769             searchOrder 
= range(len(self
.history
)) 
 771             searchOrder 
= range(self
.historyIndex
+1, len(self
.history
)) + \
 
 772                           range(self
.historyIndex
) 
 773         for i 
in searchOrder
: 
 774             command 
= self
.history
[i
] 
 775             if command
[:len(searchText
)] == searchText
: 
 776                 # Replace the current selection with the one we found. 
 777                 self
.ReplaceSelection(command
[len(searchText
):]) 
 778                 endpos 
= self
.GetCurrentPos() 
 779                 self
.SetSelection(endpos
, startpos
) 
 780                 # We've now warped into middle of the history. 
 781                 self
.historyIndex 
= i
 
 784     def setStatusText(self
, text
): 
 785         """Display status information.""" 
 787         # This method will likely be replaced by the enclosing app to 
 788         # do something more interesting, like write to a status bar. 
 791     def insertLineBreak(self
): 
 792         """Insert a new line break.""" 
 794             self
.write(os
.linesep
) 
 798     def processLine(self
): 
 799         """Process the line of text at which the user hit Enter.""" 
 801         # The user hit ENTER and we need to decide what to do. They 
 802         # could be sitting on any line in the shell. 
 804         thepos 
= self
.GetCurrentPos() 
 805         startpos 
= self
.promptPosEnd
 
 806         endpos 
= self
.GetTextLength() 
 808         # If they hit RETURN inside the current command, execute the 
 811             self
.SetCurrentPos(endpos
) 
 812             self
.interp
.more 
= False 
 813             command 
= self
.GetTextRange(startpos
, endpos
) 
 814             lines 
= command
.split(os
.linesep 
+ ps2
) 
 815             lines 
= [line
.rstrip() for line 
in lines
] 
 816             command 
= '\n'.join(lines
) 
 817             if self
.reader
.isreading
: 
 819                     # Match the behavior of the standard Python shell 
 820                     # when the user hits return without entering a 
 823                 self
.reader
.input = command
 
 824                 self
.write(os
.linesep
) 
 827                 wx
.FutureCall(1, self
.EnsureCaretVisible
) 
 828         # Or replace the current command with the other command. 
 830             # If the line contains a command (even an invalid one). 
 831             if self
.getCommand(rstrip
=False): 
 832                 command 
= self
.getMultilineCommand() 
 835             # Otherwise, put the cursor back where we started. 
 837                 self
.SetCurrentPos(thepos
) 
 838                 self
.SetAnchor(thepos
) 
 840     def getMultilineCommand(self
, rstrip
=True): 
 841         """Extract a multi-line command from the editor. 
 843         The command may not necessarily be valid Python syntax.""" 
 844         # XXX Need to extract real prompts here. Need to keep track of 
 845         # the prompt every time a command is issued. 
 850         # This is a total hack job, but it works. 
 851         text 
= self
.GetCurLine()[0] 
 852         line 
= self
.GetCurrentLine() 
 853         while text
[:ps2size
] == ps2 
and line 
> 0: 
 856             text 
= self
.GetCurLine()[0] 
 857         if text
[:ps1size
] == ps1
: 
 858             line 
= self
.GetCurrentLine() 
 860             startpos 
= self
.GetCurrentPos() + ps1size
 
 863             while self
.GetCurLine()[0][:ps2size
] == ps2
: 
 866             stoppos 
= self
.GetCurrentPos() 
 867             command 
= self
.GetTextRange(startpos
, stoppos
) 
 868             command 
= command
.replace(os
.linesep 
+ ps2
, '\n') 
 869             command 
= command
.rstrip() 
 870             command 
= command
.replace('\n', os
.linesep 
+ ps2
) 
 874             command 
= command
.rstrip() 
 877     def getCommand(self
, text
=None, rstrip
=True): 
 878         """Extract a command from text which may include a shell prompt. 
 880         The command may not necessarily be valid Python syntax.""" 
 882             text 
= self
.GetCurLine()[0] 
 883         # Strip the prompt off the front leaving just the command. 
 884         command 
= self
.lstripPrompt(text
) 
 886             command 
= ''  # Real commands have prompts. 
 888             command 
= command
.rstrip() 
 891     def lstripPrompt(self
, text
): 
 892         """Return text without a leading prompt.""" 
 897         # Strip the prompt off the front of text. 
 898         if text
[:ps1size
] == ps1
: 
 899             text 
= text
[ps1size
:] 
 900         elif text
[:ps2size
] == ps2
: 
 901             text 
= text
[ps2size
:] 
 904     def push(self
, command
, silent 
= False): 
 905         """Send command to the interpreter for execution.""" 
 907             self
.write(os
.linesep
) 
 908         busy 
= wx
.BusyCursor() 
 910         self
.more 
= self
.interp
.push(command
) 
 914             self
.addHistory(command
.rstrip()) 
 918     def addHistory(self
, command
): 
 919         """Add command to the command history.""" 
 920         # Reset the history position. 
 921         self
.historyIndex 
= -1 
 922         # Insert this command into the history, unless it's a blank 
 923         # line or the same as the last command. 
 925         and (len(self
.history
) == 0 or command 
!= self
.history
[0]): 
 926             self
.history
.insert(0, command
) 
 927             dispatcher
.send(signal
="Shell.addHistory", command
=command
) 
 929     def write(self
, text
): 
 930         """Display text in the shell. 
 932         Replace line endings with OS-specific endings.""" 
 933         text 
= self
.fixLineEndings(text
) 
 935         self
.EnsureCaretVisible() 
 937     def fixLineEndings(self
, text
): 
 938         """Return text with line endings replaced by OS-specific endings.""" 
 939         lines 
= text
.split('\r\n') 
 940         for l 
in range(len(lines
)): 
 941             chunks 
= lines
[l
].split('\r') 
 942             for c 
in range(len(chunks
)): 
 943                 chunks
[c
] = os
.linesep
.join(chunks
[c
].split('\n')) 
 944             lines
[l
] = os
.linesep
.join(chunks
) 
 945         text 
= os
.linesep
.join(lines
) 
 949         """Display proper prompt for the context: ps1, ps2 or ps3. 
 951         If this is a continuation line, autoindent as necessary.""" 
 952         isreading 
= self
.reader
.isreading
 
 955             prompt 
= str(sys
.ps3
) 
 957             prompt 
= str(sys
.ps2
) 
 959             prompt 
= str(sys
.ps1
) 
 960         pos 
= self
.GetCurLine()[1] 
 965                 self
.write(os
.linesep
) 
 967             self
.promptPosStart 
= self
.GetCurrentPos() 
 971             self
.promptPosEnd 
= self
.GetCurrentPos() 
 972             # Keep the undo feature from undoing previous responses. 
 973             self
.EmptyUndoBuffer() 
 974         # XXX Add some autoindent magic here if more. 
 976             self
.write(' '*4)  # Temporary hack indentation. 
 977         self
.EnsureCaretVisible() 
 978         self
.ScrollToColumn(0) 
 981         """Replacement for stdin.readline().""" 
 984         reader
.isreading 
= True 
 987             while not reader
.input: 
 992             reader
.isreading 
= False 
 993         input = str(input)  # In case of Unicode. 
 997         """Replacement for stdin.readlines().""" 
 999         while lines
[-1:] != ['\n']: 
1000             lines
.append(self
.readline()) 
1003     def raw_input(self
, prompt
=''): 
1004         """Return string based on user input.""" 
1007         return self
.readline() 
1009     def ask(self
, prompt
='Please enter your response:'): 
1010         """Get response from the user using a dialog box.""" 
1011         dialog 
= wx
.TextEntryDialog(None, prompt
, 
1012                                     'Input Dialog (Raw)', '') 
1014             if dialog
.ShowModal() == wx
.ID_OK
: 
1015                 text 
= dialog
.GetValue() 
1022         """Halt execution pending a response from the user.""" 
1023         self
.ask('Press enter to continue:') 
1026         """Delete all text from the shell.""" 
1029     def run(self
, command
, prompt
=True, verbose
=True): 
1030         """Execute command as if it was typed in directly. 
1031         >>> shell.run('print "this"') 
1036         # Go to the very bottom of the text. 
1037         endpos 
= self
.GetTextLength() 
1038         self
.SetCurrentPos(endpos
) 
1039         command 
= command
.rstrip() 
1040         if prompt
: self
.prompt() 
1041         if verbose
: self
.write(command
) 
1044     def runfile(self
, filename
): 
1045         """Execute all commands in file as if they were typed into the 
1047         file = open(filename
) 
1050             for command 
in file.readlines(): 
1051                 if command
[:6] == 'shell.': 
1052                     # Run shell methods silently. 
1053                     self
.run(command
, prompt
=False, verbose
=False) 
1055                     self
.run(command
, prompt
=False, verbose
=True) 
1059     def autoCompleteShow(self
, command
, offset 
= 0): 
1060         """Display auto-completion popup list.""" 
1061         self
.AutoCompSetAutoHide(self
.autoCompleteAutoHide
) 
1062         self
.AutoCompSetIgnoreCase(self
.autoCompleteCaseInsensitive
) 
1063         list = self
.interp
.getAutoCompleteList(command
, 
1064                     includeMagic
=self
.autoCompleteIncludeMagic
, 
1065                     includeSingle
=self
.autoCompleteIncludeSingle
, 
1066                     includeDouble
=self
.autoCompleteIncludeDouble
) 
1068             options 
= ' '.join(list) 
1070             self
.AutoCompShow(offset
, options
) 
1072     def autoCallTipShow(self
, command
, insertcalltip 
= True, forceCallTip 
= False): 
1073         """Display argument spec and docstring in a popup window.""" 
1074         if self
.CallTipActive(): 
1075             self
.CallTipCancel() 
1076         (name
, argspec
, tip
) = self
.interp
.getCallTip(command
) 
1078             dispatcher
.send(signal
='Shell.calltip', sender
=self
, calltip
=tip
) 
1079         if not self
.autoCallTip 
and not forceCallTip
: 
1081         if argspec 
and insertcalltip 
and self
.callTipInsert
: 
1082             startpos 
= self
.GetCurrentPos() 
1083             self
.write(argspec 
+ ')') 
1084             endpos 
= self
.GetCurrentPos() 
1085             self
.SetSelection(endpos
, startpos
) 
1087             curpos 
= self
.GetCurrentPos() 
1088             tippos 
= curpos 
- (len(name
) + 1) 
1089             fallback 
= curpos 
- self
.GetColumn(curpos
) 
1090             # In case there isn't enough room, only go back to the 
1092             tippos 
= max(tippos
, fallback
) 
1093             self
.CallTipShow(tippos
, tip
) 
1095     def OnCallTipAutoCompleteManually (self
, shiftDown
): 
1096         """AutoComplete and Calltips manually.""" 
1097         if self
.AutoCompActive(): 
1098             self
.AutoCompCancel() 
1099         currpos 
= self
.GetCurrentPos() 
1100         stoppos 
= self
.promptPosEnd
 
1103         #go back until '.' is found 
1105         while cpos 
>= stoppos
: 
1106             if self
.GetCharAt(cpos
) == ord ('.'): 
1107                 pointavailpos 
= cpos
 
1111         #word from non whitespace until '.' 
1112         if pointavailpos 
!= -1: 
1113             #look backward for first whitespace char 
1114             textbehind 
= self
.GetTextRange (pointavailpos 
+ 1, currpos
) 
1119                 stoppos 
= self
.promptPosEnd
 
1120                 textbefore 
= self
.GetTextRange(stoppos
, pointavailpos
) 
1121                 self
.autoCompleteShow(textbefore
, len (textbehind
)) 
1124                 cpos 
= pointavailpos
 
1126                 while cpos 
> stoppos
: 
1127                     if chr(self
.GetCharAt(cpos
)).isspace(): 
1133                 ctips 
= self
.GetTextRange (begpos
, currpos
) 
1134                 ctindex 
= ctips
.find ('(') 
1135                 if ctindex 
!= -1 and not self
.CallTipActive(): 
1136                     #insert calltip, if current pos is '(', otherwise show it only 
1137                     self
.autoCallTipShow(ctips
[:ctindex 
+ 1],  
1138                         self
.GetCharAt(currpos 
- 1) == ord('(') and self
.GetCurrentPos() == self
.GetTextLength(), 
1142     def writeOut(self
, text
): 
1143         """Replacement for stdout.""" 
1146     def writeErr(self
, text
): 
1147         """Replacement for stderr.""" 
1150     def redirectStdin(self
, redirect
=True): 
1151         """If redirect is true then sys.stdin will come from the shell.""" 
1153             sys
.stdin 
= self
.reader
 
1155             sys
.stdin 
= self
.stdin
 
1157     def redirectStdout(self
, redirect
=True): 
1158         """If redirect is true then sys.stdout will go to the shell.""" 
1160             sys
.stdout 
= PseudoFileOut(self
.writeOut
) 
1162             sys
.stdout 
= self
.stdout
 
1164     def redirectStderr(self
, redirect
=True): 
1165         """If redirect is true then sys.stderr will go to the shell.""" 
1167             sys
.stderr 
= PseudoFileErr(self
.writeErr
) 
1169             sys
.stderr 
= self
.stderr
 
1172         """Return true if text is selected and can be cut.""" 
1173         if self
.GetSelectionStart() != self
.GetSelectionEnd() \
 
1174                and self
.GetSelectionStart() >= self
.promptPosEnd \
 
1175                and self
.GetSelectionEnd() >= self
.promptPosEnd
: 
1181         """Return true if a paste should succeed.""" 
1182         if self
.CanEdit() and editwindow
.EditWindow
.CanPaste(self
): 
1188         """Return true if editing should succeed.""" 
1189         if self
.GetSelectionStart() != self
.GetSelectionEnd(): 
1190             if self
.GetSelectionStart() >= self
.promptPosEnd \
 
1191                    and self
.GetSelectionEnd() >= self
.promptPosEnd
: 
1196             return self
.GetCurrentPos() >= self
.promptPosEnd
 
1199         """Remove selection and place it on the clipboard.""" 
1200         if self
.CanCut() and self
.CanCopy(): 
1201             if self
.AutoCompActive(): 
1202                 self
.AutoCompCancel() 
1203             if self
.CallTipActive(): 
1204                 self
.CallTipCancel() 
1206             self
.ReplaceSelection('') 
1209         """Copy selection and place it on the clipboard.""" 
1213             command 
= self
.GetSelectedText() 
1214             command 
= command
.replace(os
.linesep 
+ ps2
, os
.linesep
) 
1215             command 
= command
.replace(os
.linesep 
+ ps1
, os
.linesep
) 
1216             command 
= self
.lstripPrompt(text
=command
) 
1217             data 
= wx
.TextDataObject(command
) 
1220     def CopyWithPrompts(self
): 
1221         """Copy selection, including prompts, and place it on the clipboard.""" 
1223             command 
= self
.GetSelectedText() 
1224             data 
= wx
.TextDataObject(command
) 
1227     def CopyWithPromptsPrefixed(self
): 
1228         """Copy selection, including prompts prefixed with four 
1229         spaces, and place it on the clipboard.""" 
1231             command 
= self
.GetSelectedText() 
1233             command 
= spaces 
+ command
.replace(os
.linesep
, 
1234                                                os
.linesep 
+ spaces
) 
1235             data 
= wx
.TextDataObject(command
) 
1238     def _clip(self
, data
): 
1239         if wx
.TheClipboard
.Open(): 
1240             wx
.TheClipboard
.UsePrimarySelection(False) 
1241             wx
.TheClipboard
.SetData(data
) 
1242             wx
.TheClipboard
.Flush() 
1243             wx
.TheClipboard
.Close() 
1246         """Replace selection with clipboard contents.""" 
1247         if self
.CanPaste() and wx
.TheClipboard
.Open(): 
1249             if wx
.TheClipboard
.IsSupported(wx
.DataFormat(wx
.DF_TEXT
)): 
1250                 data 
= wx
.TextDataObject() 
1251                 if wx
.TheClipboard
.GetData(data
): 
1252                     self
.ReplaceSelection('') 
1253                     command 
= data
.GetText() 
1254                     command 
= command
.rstrip() 
1255                     command 
= self
.fixLineEndings(command
) 
1256                     command 
= self
.lstripPrompt(text
=command
) 
1257                     command 
= command
.replace(os
.linesep 
+ ps2
, '\n') 
1258                     command 
= command
.replace(os
.linesep
, '\n') 
1259                     command 
= command
.replace('\n', os
.linesep 
+ ps2
) 
1261             wx
.TheClipboard
.Close() 
1264     def PasteAndRun(self
): 
1265         """Replace selection with clipboard contents, run commands.""" 
1267         if wx
.TheClipboard
.Open(): 
1268             if wx
.TheClipboard
.IsSupported(wx
.DataFormat(wx
.DF_TEXT
)): 
1269                 data 
= wx
.TextDataObject() 
1270                 if wx
.TheClipboard
.GetData(data
): 
1271                     text 
= data
.GetText() 
1272             wx
.TheClipboard
.Close() 
1277     def Execute(self
, text
): 
1278         """Replace selection with text and run commands.""" 
1281         endpos 
= self
.GetTextLength() 
1282         self
.SetCurrentPos(endpos
) 
1283         startpos 
= self
.promptPosEnd
 
1284         self
.SetSelection(startpos
, endpos
) 
1285         self
.ReplaceSelection('') 
1286         text 
= text
.lstrip() 
1287         text 
= self
.fixLineEndings(text
) 
1288         text 
= self
.lstripPrompt(text
) 
1289         text 
= text
.replace(os
.linesep 
+ ps1
, '\n') 
1290         text 
= text
.replace(os
.linesep 
+ ps2
, '\n') 
1291         text 
= text
.replace(os
.linesep
, '\n') 
1292         lines 
= text
.split('\n') 
1296             if line
.strip() == ps2
.strip(): 
1297                 # If we are pasting from something like a 
1298                 # web page that drops the trailing space 
1299                 # from the ps2 prompt of a blank line. 
1301             lstrip 
= line
.lstrip() 
1302             if line
.strip() != '' and lstrip 
== line 
and \
 
1303                     lstrip
[:4] not in ['else','elif'] and \
 
1304                     lstrip
[:6] != 'except': 
1307                     # Add the previous command to the list. 
1308                     commands
.append(command
) 
1309                 # Start a new command, which may be multiline. 
1312                 # Multiline command. Add to the command. 
1315         commands
.append(command
) 
1316         for command 
in commands
: 
1317             command 
= command
.replace('\n', os
.linesep 
+ ps2
) 
1322     def wrap(self
, wrap
=True): 
1323         """Sets whether text is word wrapped.""" 
1325             self
.SetWrapMode(wrap
) 
1326         except AttributeError: 
1327             return 'Wrapping is not available in this version.' 
1329     def zoom(self
, points
=0): 
1330         """Set the zoom level. 
1332         This number of points is added to the size of all fonts.  It 
1333         may be positive to magnify or negative to reduce.""" 
1334         self
.SetZoom(points
) 
1338     def LoadSettings(self
, config
): 
1339         self
.autoComplete              
= config
.ReadBool('Options/AutoComplete', True) 
1340         self
.autoCompleteIncludeMagic  
= config
.ReadBool('Options/AutoCompleteIncludeMagic', True) 
1341         self
.autoCompleteIncludeSingle 
= config
.ReadBool('Options/AutoCompleteIncludeSingle', True) 
1342         self
.autoCompleteIncludeDouble 
= config
.ReadBool('Options/AutoCompleteIncludeDouble', True) 
1344         self
.autoCallTip 
= config
.ReadBool('Options/AutoCallTip', True) 
1345         self
.callTipInsert 
= config
.ReadBool('Options/CallTipInsert', True) 
1346         self
.SetWrapMode(config
.ReadBool('View/WrapMode', True)) 
1348         useAA 
= config
.ReadBool('Options/UseAntiAliasing', self
.GetUseAntiAliasing()) 
1349         self
.SetUseAntiAliasing(useAA
) 
1350         self
.lineNumbers 
= config
.ReadBool('View/ShowLineNumbers', True) 
1351         self
.setDisplayLineNumbers (self
.lineNumbers
) 
1352         zoom 
= config
.ReadInt('View/Zoom/Shell', -99) 
1358     def SaveSettings(self
, config
): 
1359         config
.WriteBool('Options/AutoComplete', self
.autoComplete
) 
1360         config
.WriteBool('Options/AutoCompleteIncludeMagic', self
.autoCompleteIncludeMagic
) 
1361         config
.WriteBool('Options/AutoCompleteIncludeSingle', self
.autoCompleteIncludeSingle
) 
1362         config
.WriteBool('Options/AutoCompleteIncludeDouble', self
.autoCompleteIncludeDouble
) 
1363         config
.WriteBool('Options/AutoCallTip', self
.autoCallTip
) 
1364         config
.WriteBool('Options/CallTipInsert', self
.callTipInsert
) 
1365         config
.WriteBool('Options/UseAntiAliasing', self
.GetUseAntiAliasing()) 
1366         config
.WriteBool('View/WrapMode', self
.GetWrapMode()) 
1367         config
.WriteBool('View/ShowLineNumbers', self
.lineNumbers
) 
1368         config
.WriteInt('View/Zoom/Shell', self
.GetZoom()) 
1372 ## NOTE: The DnD of file names is disabled until I can figure out how 
1373 ## best to still allow DnD of text. 
1376 ## #seb : File drag and drop 
1377 ## class FileDropTarget(wx.FileDropTarget): 
1378 ##     def __init__(self, obj): 
1379 ##         wx.FileDropTarget.__init__(self) 
1381 ##     def OnDropFiles(self, x, y, filenames): 
1382 ##         if len(filenames) == 1: 
1383 ##             txt = 'r\"%s\"' % filenames[0] 
1386 ##             for f in filenames: 
1387 ##                 txt += 'r\"%s\" , ' % f 
1389 ##         self.obj.AppendText(txt) 
1390 ##         pos = self.obj.GetCurrentPos() 
1391 ##         self.obj.SetCurrentPos( pos ) 
1392 ##         self.obj.SetSelection( pos, pos ) 
1396 ## class TextAndFileDropTarget(wx.DropTarget): 
1397 ##     def __init__(self, shell): 
1398 ##         wx.DropTarget.__init__(self) 
1399 ##         self.shell = shell 
1400 ##         self.compdo = wx.DataObjectComposite() 
1401 ##         self.textdo = wx.TextDataObject() 
1402 ##         self.filedo = wx.FileDataObject() 
1403 ##         self.compdo.Add(self.textdo) 
1404 ##         self.compdo.Add(self.filedo, True) 
1406 ##         self.SetDataObject(self.compdo) 
1408 ##     def OnDrop(self, x, y): 
1411 ##     def OnData(self, x, y, result): 
1413 ##         if self.textdo.GetTextLength() > 1: 
1414 ##             text = self.textdo.GetText() 
1415 ##             # *** Do somethign with the dragged text here... 
1416 ##             self.textdo.SetText('') 
1418 ##             filenames = str(self.filename.GetFilenames()) 
1419 ##             if len(filenames) == 1: 
1420 ##                 txt = 'r\"%s\"' % filenames[0] 
1423 ##                 for f in filenames: 
1424 ##                     txt += 'r\"%s\" , ' % f 
1426 ##             self.shell.AppendText(txt) 
1427 ##             pos = self.shell.GetCurrentPos() 
1428 ##             self.shell.SetCurrentPos( pos ) 
1429 ##             self.shell.SetSelection( pos, pos )