1 """PyAlaCarte and PyAlaMode editors.""" 
   3 __author__ 
= "Patrick K. O'Brien <pobrien@orbtech.com>" 
   5 __revision__ 
= "$Revision$"[11:-2] 
   9 from buffer import Buffer
 
  14 from shell 
import Shell
 
  18 class EditorFrame(frame
.Frame
): 
  19     """Frame containing one editor.""" 
  21     def __init__(self
, parent
=None, id=-1, title
='PyAlaCarte', 
  22                  pos
=wx
.DefaultPosition
, size
=(800, 600),  
  23                  style
=wx
.DEFAULT_FRAME_STYLE | wx
.NO_FULL_REPAINT_ON_RESIZE
, 
  25         """Create EditorFrame instance.""" 
  26         frame
.Frame
.__init
__(self
, parent
, id, title
, pos
, size
, style
) 
  28         self
.buffer = None  # Current buffer. 
  30         self
._defaultText 
= title 
+ ' - the tastiest Python editor.' 
  31         self
._statusText 
= self
._defaultText
 
  32         self
.SetStatusText(self
._statusText
) 
  33         wx
.EVT_IDLE(self
, self
.OnIdle
) 
  36             self
.bufferCreate(filename
) 
  39         """Setup prior to first buffer creation. 
  41         Useful for subclasses.""" 
  44     def setEditor(self
, editor
): 
  46         self
.buffer = self
.editor
.buffer 
  47         self
.buffers
[self
.buffer.id] = self
.buffer 
  49     def OnAbout(self
, event
): 
  50         """Display an About window.""" 
  51         title 
= 'About PyAlaCarte' 
  52         text 
= 'Another fine, flaky program.' 
  53         dialog 
= wx
.MessageDialog(self
, text
, title
, 
  54                                   wx
.OK | wx
.ICON_INFORMATION
) 
  58     def OnClose(self
, event
): 
  59         """Event handler for closing.""" 
  60         for buffer in self
.buffers
.values(): 
  62             if buffer.hasChanged(): 
  63                 cancel 
= self
.bufferSuggestSave() 
  64                 if cancel 
and event
.CanVeto(): 
  69     def OnIdle(self
, event
): 
  70         """Event handler for idle time.""" 
  72         if hasattr(self
, 'notebook'): 
  77     def _updateStatus(self
): 
  78         """Show current status information.""" 
  79         if self
.editor 
and hasattr(self
.editor
, 'getStatus'): 
  80             status 
= self
.editor
.getStatus() 
  81             text 
= 'File: %s  |  Line: %d  |  Column: %d' % status
 
  83             text 
= self
._defaultText
 
  84         if text 
!= self
._statusText
: 
  85             self
.SetStatusText(text
) 
  86             self
._statusText 
= text
 
  88     def _updateTabText(self
): 
  89         """Show current buffer information on notebook tab.""" 
  91 ##         notebook = self.notebook 
  92 ##         selection = notebook.GetSelection() 
  93 ##         if selection == -1: 
  95 ##         text = notebook.GetPageText(selection) 
  96 ##         window = notebook.GetPage(selection) 
  97 ##         if window.editor and window.editor.buffer.hasChanged(): 
  98 ##             if text.endswith(suffix): 
 101 ##                 notebook.SetPageText(selection, text + suffix) 
 103 ##             if text.endswith(suffix): 
 104 ##                 notebook.SetPageText(selection, text[:len(suffix)]) 
 106     def _updateTitle(self
): 
 107         """Show current title information.""" 
 108         title 
= self
.GetTitle() 
 109         if self
.bufferHasChanged(): 
 110             if title
.startswith('* '): 
 113                 self
.SetTitle('* ' + title
) 
 115             if title
.startswith('* '): 
 116                 self
.SetTitle(title
[2:]) 
 119         """Return True if there is a current buffer.""" 
 125     def bufferClose(self
): 
 127         if self
.bufferHasChanged(): 
 128             cancel 
= self
.bufferSuggestSave() 
 135     def bufferCreate(self
, filename
=None): 
 136         """Create new buffer.""" 
 139         self
.panel 
= panel 
= wx
.Panel(parent
=self
, id=-1) 
 140         wx
.EVT_ERASE_BACKGROUND(panel
, lambda x
: x
)         
 141         editor 
= Editor(parent
=panel
) 
 142         panel
.editor 
= editor
 
 143         sizer 
= wx
.BoxSizer(wx
.VERTICAL
) 
 144         sizer
.Add(editor
.window
, 1, wx
.EXPAND
) 
 145         panel
.SetSizer(sizer
) 
 146         panel
.SetAutoLayout(True) 
 148         buffer.addEditor(editor
) 
 149         buffer.open(filename
) 
 150         self
.setEditor(editor
) 
 151         self
.editor
.setFocus() 
 155     def bufferDestroy(self
): 
 156         """Destroy the current buffer.""" 
 158             for editor 
in self
.buffer.editors
.values(): 
 161             del self
.buffers
[self
.buffer.id] 
 166     def bufferHasChanged(self
): 
 167         """Return True if buffer has changed since last save.""" 
 169             return self
.buffer.hasChanged() 
 174         """Create new buffer.""" 
 175         if self
.bufferHasChanged(): 
 176             cancel 
= self
.bufferSuggestSave() 
 183     def bufferOpen(self
): 
 184         """Open file in buffer.""" 
 185         if self
.bufferHasChanged(): 
 186             cancel 
= self
.bufferSuggestSave() 
 190         if self
.buffer and self
.buffer.doc
.filedir
: 
 191             filedir 
= self
.buffer.doc
.filedir
 
 192         result 
= openSingle(directory
=filedir
) 
 194             self
.bufferCreate(result
.path
) 
 198 ##     def bufferPrint(self): 
 199 ##         """Print buffer.""" 
 202 ##     def bufferRevert(self): 
 203 ##         """Revert buffer to version of file on disk.""" 
 206     def bufferSave(self
): 
 207         """Save buffer to its file.""" 
 208         if self
.buffer.doc
.filepath
: 
 212             cancel 
= self
.bufferSaveAs() 
 215     def bufferSaveAs(self
): 
 216         """Save buffer to a new filename.""" 
 217         if self
.bufferHasChanged() and self
.buffer.doc
.filepath
: 
 218             cancel 
= self
.bufferSuggestSave() 
 222         if self
.buffer and self
.buffer.doc
.filedir
: 
 223             filedir 
= self
.buffer.doc
.filedir
 
 224         result 
= saveSingle(directory
=filedir
) 
 226             self
.buffer.saveAs(result
.path
) 
 232     def bufferSuggestSave(self
): 
 233         """Suggest saving changes.  Return True if user selected Cancel.""" 
 234         result 
= messageDialog(parent
=None, 
 235                                message
='%s has changed.\n' 
 236                                        'Would you like to save it first' 
 237                                        '?' % self
.buffer.name
, 
 238                                title
='Save current file?') 
 240             cancel 
= self
.bufferSave() 
 242             cancel 
= result
.text 
== 'Cancel' 
 245     def updateNamespace(self
): 
 246         """Update the buffer namespace for autocompletion and calltips.""" 
 247         if self
.buffer.updateNamespace(): 
 248             self
.SetStatusText('Namespace updated') 
 250             self
.SetStatusText('Error executing, unable to update namespace') 
 253 class EditorNotebookFrame(EditorFrame
): 
 254     """Frame containing one or more editors in a notebook.""" 
 256     def __init__(self
, parent
=None, id=-1, title
='PyAlaMode', 
 257                  pos
=wx
.DefaultPosition
, size
=(800, 600),  
 258                  style
=wx
.DEFAULT_FRAME_STYLE | wx
.NO_FULL_REPAINT_ON_RESIZE
, 
 260         """Create EditorNotebookFrame instance.""" 
 262         EditorFrame
.__init
__(self
, parent
, id, title
, pos
, 
 263                              size
, style
, filename
) 
 265             dispatcher
.connect(receiver
=self
._editorChange
, 
 266                                signal
='EditorChange', sender
=self
.notebook
) 
 269         """Setup prior to first buffer creation. 
 271         Called automatically by base class during init.""" 
 272         self
.notebook 
= EditorNotebook(parent
=self
) 
 273         intro 
= 'Py %s' % version
.VERSION
 
 275         module 
= imp
.new_module('__main__') 
 277         module
.__dict
__['__builtins__'] = __builtin__
 
 278         namespace 
= module
.__dict
__.copy() 
 279         self
.crust 
= crust
.Crust(parent
=self
.notebook
, intro
=intro
, locals=namespace
) 
 280         self
.shell 
= self
.crust
.shell
 
 281         # Override the filling so that status messages go to the status bar. 
 282         self
.crust
.filling
.tree
.setStatusText 
= self
.SetStatusText
 
 283         # Override the shell so that status messages go to the status bar. 
 284         self
.shell
.setStatusText 
= self
.SetStatusText
 
 285         # Fix a problem with the sash shrinking to nothing. 
 286         self
.crust
.filling
.SetSashPosition(200) 
 287         self
.notebook
.AddPage(page
=self
.crust
, text
='*Shell*', select
=True) 
 288         self
.setEditor(self
.crust
.editor
) 
 289         self
.crust
.editor
.SetFocus() 
 291     def _editorChange(self
, editor
): 
 292         """Editor change signal receiver.""" 
 293         self
.setEditor(editor
) 
 295     def OnAbout(self
, event
): 
 296         """Display an About window.""" 
 297         title 
= 'About PyAlaMode' 
 298         text 
= 'Another fine, flaky program.' 
 299         dialog 
= wx
.MessageDialog(self
, text
, title
, 
 300                                   wx
.OK | wx
.ICON_INFORMATION
) 
 304     def _updateTitle(self
): 
 305         """Show current title information.""" 
 307 ##         title = self.GetTitle() 
 308 ##         if self.bufferHasChanged(): 
 309 ##             if title.startswith('* '): 
 312 ##                 self.SetTitle('* ' + title) 
 314 ##             if title.startswith('* '): 
 315 ##                 self.SetTitle(title[2:]) 
 317     def bufferCreate(self
, filename
=None): 
 318         """Create new buffer.""" 
 320         panel 
= wx
.Panel(parent
=self
.notebook
, id=-1) 
 321         wx
.EVT_ERASE_BACKGROUND(panel
, lambda x
: x
)         
 322         editor 
= Editor(parent
=panel
) 
 323         panel
.editor 
= editor
 
 324         sizer 
= wx
.BoxSizer(wx
.VERTICAL
) 
 325         sizer
.Add(editor
.window
, 1, wx
.EXPAND
) 
 326         panel
.SetSizer(sizer
) 
 327         panel
.SetAutoLayout(True) 
 329         buffer.addEditor(editor
) 
 330         buffer.open(filename
) 
 331         self
.setEditor(editor
) 
 332         self
.notebook
.AddPage(page
=panel
, text
=self
.buffer.name
, select
=True) 
 333         self
.editor
.setFocus() 
 335     def bufferDestroy(self
): 
 336         """Destroy the current buffer.""" 
 337         selection 
= self
.notebook
.GetSelection() 
 338 ##         print "Destroy Selection:", selection 
 339         if selection 
> 0:  # Don't destroy the PyCrust tab. 
 341                 del self
.buffers
[self
.buffer.id] 
 342                 self
.buffer = None  # Do this before DeletePage(). 
 343             self
.notebook
.DeletePage(selection
) 
 346         """Create new buffer.""" 
 351     def bufferOpen(self
): 
 352         """Open file in buffer.""" 
 354         if self
.buffer and self
.buffer.doc
.filedir
: 
 355             filedir 
= self
.buffer.doc
.filedir
 
 356         result 
= openMultiple(directory
=filedir
) 
 357         for path 
in result
.paths
: 
 358             self
.bufferCreate(path
) 
 363 class EditorNotebook(wx
.Notebook
): 
 364     """A notebook containing a page for each editor.""" 
 366     def __init__(self
, parent
): 
 367         """Create EditorNotebook instance.""" 
 368         wx
.Notebook
.__init
__(self
, parent
, id=-1, style
=wx
.CLIP_CHILDREN
) 
 369         wx
.EVT_NOTEBOOK_PAGE_CHANGING(self
, self
.GetId(), 
 371         wx
.EVT_NOTEBOOK_PAGE_CHANGED(self
, self
.GetId(), 
 373         wx
.EVT_IDLE(self
, self
.OnIdle
) 
 375     def OnIdle(self
, event
): 
 376         """Event handler for idle time.""" 
 377         self
._updateTabText
() 
 380     def _updateTabText(self
): 
 381         """Show current buffer display name on all but first tab.""" 
 385         selection 
= self
.GetSelection() 
 388         text 
= self
.GetPageText(selection
) 
 389         window 
= self
.GetPage(selection
) 
 390         if not window
.editor
: 
 392         if text
.endswith(changed
) or text
.endswith(unchanged
): 
 396         if name 
!= window
.editor
.buffer.name
: 
 397             text 
= window
.editor
.buffer.name
 
 398         if window
.editor
.buffer.hasChanged(): 
 399             if text
.endswith(changed
): 
 401             elif text
.endswith(unchanged
): 
 402                 text 
= text
[:-size
] + changed
 
 406             if text
.endswith(changed
): 
 407                 text 
= text
[:-size
] + unchanged
 
 408             elif text
.endswith(unchanged
): 
 413             self
.SetPageText(selection
, text
) 
 414             self
.Refresh()  # Needed on Win98. 
 416     def OnPageChanging(self
, event
): 
 417         """Page changing event handler.""" 
 420     def OnPageChanged(self
, event
): 
 421         """Page changed event handler.""" 
 422         new 
= event
.GetSelection() 
 423         window 
= self
.GetPage(new
) 
 424         dispatcher
.send(signal
='EditorChange', sender
=self
, 
 425                         editor
=window
.editor
) 
 430 class EditorShellNotebookFrame(EditorNotebookFrame
): 
 431     """Frame containing a notebook containing EditorShellNotebooks.""" 
 433     def __init__(self
, parent
=None, id=-1, title
='PyAlaModeTest', 
 434                  pos
=wx
.DefaultPosition
, size
=(600, 400),  
 435                  style
=wx
.DEFAULT_FRAME_STYLE
, 
 436                  filename
=None, singlefile
=False): 
 437         """Create EditorShellNotebookFrame instance.""" 
 438         self
._singlefile 
= singlefile
 
 439         EditorNotebookFrame
.__init
__(self
, parent
, id, title
, pos
, 
 440                                      size
, style
, filename
) 
 443         """Setup prior to first buffer creation. 
 445         Called automatically by base class during init.""" 
 446         if not self
._singlefile
: 
 447             self
.notebook 
= EditorNotebook(parent
=self
) 
 449     def OnAbout(self
, event
): 
 450         """Display an About window.""" 
 451         title 
= 'About PyAlaModePlus' 
 452         text 
= 'Another fine, flaky program.' 
 453         dialog 
= wx
.MessageDialog(self
, text
, title
, 
 454                                   wx
.OK | wx
.ICON_INFORMATION
) 
 458     def bufferCreate(self
, filename
=None): 
 459         """Create new buffer.""" 
 462             notebook 
= EditorShellNotebook(parent
=self
, 
 464             self
.notebook 
= notebook
 
 466             notebook 
= EditorShellNotebook(parent
=self
.notebook
, 
 468         self
.setEditor(notebook
.editor
) 
 469         if not self
._singlefile
: 
 470             self
.notebook
.AddPage(page
=notebook
, text
=self
.buffer.name
, 
 472         self
.editor
.setFocus() 
 474     def bufferDestroy(self
): 
 475         """Destroy the current buffer.""" 
 478             del self
.buffers
[self
.buffer.id] 
 479             self
.buffer = None  # Do this before DeletePage(). 
 481             self
.notebook
.Destroy() 
 484             selection 
= self
.notebook
.GetSelection() 
 485 ##             print "Destroy Selection:", selection 
 486             self
.notebook
.DeletePage(selection
) 
 489         """Create new buffer.""" 
 490         if self
._singlefile 
and self
.bufferHasChanged(): 
 491             cancel 
= self
.bufferSuggestSave() 
 498     def bufferOpen(self
): 
 499         """Open file in buffer.""" 
 500         if self
._singlefile 
and self
.bufferHasChanged(): 
 501             cancel 
= self
.bufferSuggestSave() 
 505         if self
.buffer and self
.buffer.doc
.filedir
: 
 506             filedir 
= self
.buffer.doc
.filedir
 
 508             result 
= openSingle(directory
=filedir
) 
 510                 self
.bufferCreate(result
.path
) 
 512             result 
= openMultiple(directory
=filedir
) 
 513             for path 
in result
.paths
: 
 514                 self
.bufferCreate(path
) 
 519 class EditorShellNotebook(wx
.Notebook
): 
 520     """A notebook containing an editor page and a shell page.""" 
 522     def __init__(self
, parent
, filename
=None): 
 523         """Create EditorShellNotebook instance.""" 
 524         wx
.Notebook
.__init
__(self
, parent
, id=-1) 
 527             editorparent 
= editorpanel 
= wx
.Panel(self
, -1) 
 528             shellparent 
= shellpanel 
= wx
.Panel(self
, -1) 
 532         self
.buffer = Buffer() 
 533         self
.editor 
= Editor(parent
=editorparent
) 
 534         self
.buffer.addEditor(self
.editor
) 
 535         self
.buffer.open(filename
) 
 536         self
.shell 
= Shell(parent
=shellparent
, locals=self
.buffer.interp
.locals, 
 537                            style
=wx
.CLIP_CHILDREN | wx
.SUNKEN_BORDER
) 
 538         self
.buffer.interp
.locals.clear() 
 540             self
.AddPage(page
=editorpanel
, text
='Editor', select
=True) 
 541             self
.AddPage(page
=shellpanel
, text
='Shell') 
 543             editorsizer 
= wx
.BoxSizer(wx
.VERTICAL
) 
 544             editorsizer
.Add(self
.editor
.window
, 1, wx
.EXPAND
) 
 545             editorpanel
.SetSizer(editorsizer
) 
 546             editorpanel
.SetAutoLayout(True) 
 547             shellsizer 
= wx
.BoxSizer(wx
.VERTICAL
) 
 548             shellsizer
.Add(self
.shell
, 1, wx
.EXPAND
) 
 549             shellpanel
.SetSizer(shellsizer
) 
 550             shellpanel
.SetAutoLayout(True) 
 552             self
.AddPage(page
=self
.editor
.window
, text
='Editor', select
=True) 
 553             self
.AddPage(page
=self
.shell
, text
='Shell') 
 554         self
.editor
.setFocus() 
 555         wx
.EVT_NOTEBOOK_PAGE_CHANGED(self
, self
.GetId(), self
.OnPageChanged
) 
 557     def OnPageChanged(self
, event
): 
 558         """Page changed event handler.""" 
 559         selection 
= event
.GetSelection() 
 561             self
.editor
.setFocus() 
 563             self
.shell
.SetFocus() 
 567         wx
.Notebook
.SetFocus(self
) 
 568         selection 
= self
.GetSelection() 
 570             self
.editor
.setFocus() 
 572             self
.shell
.SetFocus() 
 576     """Editor having an EditWindow.""" 
 578     def __init__(self
, parent
, id=-1, pos
=wx
.DefaultPosition
, 
 580                  style
=wx
.CLIP_CHILDREN | wx
.SUNKEN_BORDER
): 
 581         """Create Editor instance.""" 
 582         self
.window 
= EditWindow(self
, parent
, id, pos
, size
, style
) 
 583         self
.id = self
.window
.GetId() 
 585         # Assign handlers for keyboard events. 
 586         wx
.EVT_CHAR(self
.window
, self
.OnChar
) 
 587         wx
.EVT_KEY_DOWN(self
.window
, self
.OnKeyDown
) 
 589     def _setBuffer(self
, buffer, text
): 
 590         """Set the editor to a buffer.  Private callback called by buffer.""" 
 592         self
.autoCompleteKeys 
= buffer.interp
.getAutoCompleteKeys() 
 595         self
.emptyUndoBuffer() 
 599         """Destroy all editor objects.""" 
 600         self
.window
.Destroy() 
 603         self
.window
.ClearAll() 
 605     def emptyUndoBuffer(self
): 
 606         self
.window
.EmptyUndoBuffer() 
 609         """Return (filepath, line, column) status tuple.""" 
 611             pos 
= self
.window
.GetCurrentPos() 
 612             line 
= self
.window
.LineFromPosition(pos
) + 1 
 613             col 
= self
.window
.GetColumn(pos
) 
 615                 name 
= self
.buffer.doc
.filepath 
or self
.buffer.name
 
 618             status 
= (name
, line
, col
) 
 624         """Return contents of editor.""" 
 625         return self
.window
.GetText() 
 627     def hasChanged(self
): 
 628         """Return True if contents have changed.""" 
 629         return self
.window
.GetModify() 
 632         """Set the input focus to the editor window.""" 
 633         self
.window
.SetFocus() 
 635     def setSavePoint(self
): 
 636         self
.window
.SetSavePoint() 
 638     def setText(self
, text
): 
 639         """Set contents of editor.""" 
 640         self
.window
.SetText(text
) 
 642     def OnChar(self
, event
): 
 643         """Keypress event handler. 
 645         Only receives an event if OnKeyDown calls event.Skip() for the 
 646         corresponding event.""" 
 648         key 
= event
.KeyCode() 
 649         if key 
in self
.autoCompleteKeys
: 
 650             # Usually the dot (period) key activates auto completion. 
 651             if self
.window
.AutoCompActive():  
 652                 self
.window
.AutoCompCancel() 
 653             self
.window
.ReplaceSelection('') 
 654             self
.window
.AddText(chr(key
)) 
 655             text
, pos 
= self
.window
.GetCurLine() 
 657             if self
.window
.autoComplete
:  
 658                 self
.autoCompleteShow(text
) 
 659         elif key 
== ord('('): 
 660             # The left paren activates a call tip and cancels an 
 661             # active auto completion. 
 662             if self
.window
.AutoCompActive():  
 663                 self
.window
.AutoCompCancel() 
 664             self
.window
.ReplaceSelection('') 
 665             self
.window
.AddText('(') 
 666             text
, pos 
= self
.window
.GetCurLine() 
 668             self
.autoCallTipShow(text
) 
 670             # Allow the normal event handling to take place. 
 673     def OnKeyDown(self
, event
): 
 674         """Key down event handler.""" 
 676         key 
= event
.KeyCode() 
 677         # If the auto-complete window is up let it do its thing. 
 678         if self
.window
.AutoCompActive(): 
 681         controlDown 
= event
.ControlDown() 
 682         altDown 
= event
.AltDown() 
 683         shiftDown 
= event
.ShiftDown() 
 684         # Let Ctrl-Alt-* get handled normally. 
 685         if controlDown 
and altDown
: 
 687         # Increase font size. 
 688         elif controlDown 
and key 
in (ord(']'),): 
 689             dispatcher
.send(signal
='FontIncrease') 
 690         # Decrease font size. 
 691         elif controlDown 
and key 
in (ord('['),): 
 692             dispatcher
.send(signal
='FontDecrease') 
 694         elif controlDown 
and key 
in (ord('='),): 
 695             dispatcher
.send(signal
='FontDefault') 
 699     def autoCompleteShow(self
, command
): 
 700         """Display auto-completion popup list.""" 
 701         list = self
.buffer.interp
.getAutoCompleteList(command
,  
 702                     includeMagic
=self
.window
.autoCompleteIncludeMagic
,  
 703                     includeSingle
=self
.window
.autoCompleteIncludeSingle
,  
 704                     includeDouble
=self
.window
.autoCompleteIncludeDouble
) 
 706             options 
= ' '.join(list) 
 708             self
.window
.AutoCompShow(offset
, options
) 
 710     def autoCallTipShow(self
, command
): 
 711         """Display argument spec and docstring in a popup window.""" 
 712         if self
.window
.CallTipActive(): 
 713             self
.window
.CallTipCancel() 
 714         (name
, argspec
, tip
) = self
.buffer.interp
.getCallTip(command
) 
 716             dispatcher
.send(signal
='Shell.calltip', sender
=self
, calltip
=tip
) 
 717         if not self
.window
.autoCallTip
: 
 720             startpos 
= self
.window
.GetCurrentPos() 
 721             self
.window
.AddText(argspec 
+ ')') 
 722             endpos 
= self
.window
.GetCurrentPos() 
 723             self
.window
.SetSelection(endpos
, startpos
) 
 725             curpos 
= self
.window
.GetCurrentPos() 
 727             tippos 
= curpos 
- (size 
+ 1) 
 728             fallback 
= curpos 
- self
.window
.GetColumn(curpos
) 
 729             # In case there isn't enough room, only go back to the 
 731             tippos 
= max(tippos
, fallback
) 
 732             self
.window
.CallTipShow(tippos
, tip
) 
 733             self
.window
.CallTipSetHighlight(0, size
) 
 736 class EditWindow(editwindow
.EditWindow
): 
 737     """EditWindow based on StyledTextCtrl.""" 
 739     def __init__(self
, editor
, parent
, id=-1, pos
=wx
.DefaultPosition
, 
 741                  style
=wx
.CLIP_CHILDREN | wx
.SUNKEN_BORDER
): 
 742         """Create EditWindow instance.""" 
 743         editwindow
.EditWindow
.__init
__(self
, parent
, id, pos
, size
, style
) 
 748     """DialogResults class.""" 
 750     def __init__(self
, returned
): 
 751         """Create wrapper for results returned by dialog.""" 
 752         self
.returned 
= returned
 
 753         self
.positive 
= returned 
in (wx
.ID_OK
, wx
.ID_YES
) 
 754         self
.text 
= self
._asString
() 
 758         return str(self
.__dict
__) 
 761         returned 
= self
.returned
 
 762         if returned 
== wx
.ID_OK
: 
 764         elif returned 
== wx
.ID_CANCEL
: 
 766         elif returned 
== wx
.ID_YES
: 
 768         elif returned 
== wx
.ID_NO
: 
 772 def fileDialog(parent
=None, title
='Open', directory
='', filename
='', 
 773                wildcard
='All Files (*.*)|*.*', 
 774                style
=wx
.OPEN | wx
.MULTIPLE
): 
 775     """File dialog wrapper function.""" 
 776     dialog 
= wx
.FileDialog(parent
, title
, directory
, filename
, 
 778     result 
= DialogResults(dialog
.ShowModal()) 
 780         result
.paths 
= dialog
.GetPaths() 
 787 def openSingle(parent
=None, title
='Open', directory
='', filename
='', 
 788                wildcard
='All Files (*.*)|*.*', style
=wx
.OPEN
): 
 789     """File dialog wrapper function.""" 
 790     dialog 
= wx
.FileDialog(parent
, title
, directory
, filename
, 
 792     result 
= DialogResults(dialog
.ShowModal()) 
 794         result
.path 
= dialog
.GetPath() 
 801 def openMultiple(parent
=None, title
='Open', directory
='', filename
='', 
 802                  wildcard
='All Files (*.*)|*.*', 
 803                  style
=wx
.OPEN | wx
.MULTIPLE
): 
 804     """File dialog wrapper function.""" 
 805     return fileDialog(parent
, title
, directory
, filename
, wildcard
, style
) 
 808 def saveSingle(parent
=None, title
='Save', directory
='', filename
='', 
 809                wildcard
='All Files (*.*)|*.*', 
 810                style
=wx
.SAVE | wx
.HIDE_READONLY | wx
.OVERWRITE_PROMPT
): 
 811     """File dialog wrapper function.""" 
 812     dialog 
= wx
.FileDialog(parent
, title
, directory
, filename
, 
 814     result 
= DialogResults(dialog
.ShowModal()) 
 816         result
.path 
= dialog
.GetPath() 
 823 def directory(parent
=None, message
='Choose a directory', path
='', style
=0, 
 824               pos
=wx
.DefaultPosition
, size
=wx
.DefaultSize
): 
 825     """Dir dialog wrapper function.""" 
 826     dialog 
= wx
.DirDialog(parent
, message
, path
, style
, pos
, size
) 
 827     result 
= DialogResults(dialog
.ShowModal()) 
 829         result
.path 
= dialog
.GetPath() 
 836 def messageDialog(parent
=None, message
='', title
='Message box', 
 837                   style
=wx
.YES_NO | wx
.CANCEL | wx
.CENTRE | wx
.ICON_QUESTION
, 
 838                   pos
=wx
.DefaultPosition
): 
 839     """Message dialog wrapper function.""" 
 840     dialog 
= wx
.MessageDialog(parent
, message
, title
, style
, pos
) 
 841     result 
= DialogResults(dialog
.ShowModal())