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
.NO_FULL_REPAINT_ON_RESIZE
)
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())