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
24 class EditorFrame(frame
.Frame
):
25 """Frame containing one editor."""
27 def __init__(self
, parent
=None, id=-1, title
='PyAlaCarte',
28 pos
=wx
.DefaultPosition
, size
=(800, 600),
29 style
=wx
.DEFAULT_FRAME_STYLE | wx
.NO_FULL_REPAINT_ON_RESIZE
,
31 """Create EditorFrame instance."""
32 frame
.Frame
.__init
__(self
, parent
, id, title
, pos
, size
, style
)
34 self
.buffer = None # Current buffer.
36 self
._defaultText
= title
+ ' - the tastiest Python editor.'
37 self
._statusText
= self
._defaultText
38 self
.SetStatusText(self
._statusText
)
39 wx
.EVT_IDLE(self
, self
.OnIdle
)
42 self
.bufferCreate(filename
)
45 """Setup prior to first buffer creation.
47 Useful for subclasses."""
50 def setEditor(self
, editor
):
52 self
.buffer = self
.editor
.buffer
53 self
.buffers
[self
.buffer.id] = self
.buffer
55 def OnAbout(self
, event
):
56 """Display an About window."""
57 title
= 'About PyAlaCarte'
58 text
= 'Another fine, flaky program.'
59 dialog
= wx
.MessageDialog(self
, text
, title
,
60 wx
.OK | wx
.ICON_INFORMATION
)
64 def OnClose(self
, event
):
65 """Event handler for closing."""
66 for buffer in self
.buffers
.values():
68 if buffer.hasChanged():
69 cancel
= self
.bufferSuggestSave()
70 if cancel
and event
.CanVeto():
75 def OnIdle(self
, event
):
76 """Event handler for idle time."""
78 if hasattr(self
, 'notebook'):
83 def _updateStatus(self
):
84 """Show current status information."""
85 if self
.editor
and hasattr(self
.editor
, 'getStatus'):
86 status
= self
.editor
.getStatus()
87 text
= 'File: %s | Line: %d | Column: %d' % status
89 text
= self
._defaultText
90 if text
!= self
._statusText
:
91 self
.SetStatusText(text
)
92 self
._statusText
= text
94 def _updateTabText(self
):
95 """Show current buffer information on notebook tab."""
97 ## notebook = self.notebook
98 ## selection = notebook.GetSelection()
99 ## if selection == -1:
101 ## text = notebook.GetPageText(selection)
102 ## window = notebook.GetPage(selection)
103 ## if window.editor and window.editor.buffer.hasChanged():
104 ## if text.endswith(suffix):
107 ## notebook.SetPageText(selection, text + suffix)
109 ## if text.endswith(suffix):
110 ## notebook.SetPageText(selection, text[:len(suffix)])
112 def _updateTitle(self
):
113 """Show current title information."""
114 title
= self
.GetTitle()
115 if self
.bufferHasChanged():
116 if title
.startswith('* '):
119 self
.SetTitle('* ' + title
)
121 if title
.startswith('* '):
122 self
.SetTitle(title
[2:])
125 """Return True if there is a current buffer."""
131 def bufferClose(self
):
133 if self
.bufferHasChanged():
134 cancel
= self
.bufferSuggestSave()
141 def bufferCreate(self
, filename
=None):
142 """Create new buffer."""
145 self
.panel
= panel
= wx
.Panel(parent
=self
, id=-1)
146 wx
.EVT_ERASE_BACKGROUND(panel
, lambda x
: x
)
147 editor
= Editor(parent
=panel
)
148 panel
.editor
= editor
149 sizer
= wx
.BoxSizer(wx
.VERTICAL
)
150 sizer
.Add(editor
.window
, 1, wx
.EXPAND
)
151 panel
.SetSizer(sizer
)
152 panel
.SetAutoLayout(True)
154 buffer.addEditor(editor
)
155 buffer.open(filename
)
156 self
.setEditor(editor
)
157 self
.editor
.setFocus()
161 def bufferDestroy(self
):
162 """Destroy the current buffer."""
164 for editor
in self
.buffer.editors
.values():
167 del self
.buffers
[self
.buffer.id]
172 def bufferHasChanged(self
):
173 """Return True if buffer has changed since last save."""
175 return self
.buffer.hasChanged()
180 """Create new buffer."""
181 if self
.bufferHasChanged():
182 cancel
= self
.bufferSuggestSave()
189 def bufferOpen(self
):
190 """Open file in buffer."""
191 if self
.bufferHasChanged():
192 cancel
= self
.bufferSuggestSave()
196 if self
.buffer and self
.buffer.doc
.filedir
:
197 filedir
= self
.buffer.doc
.filedir
198 result
= openSingle(directory
=filedir
)
200 self
.bufferCreate(result
.path
)
204 ## def bufferPrint(self):
205 ## """Print buffer."""
208 ## def bufferRevert(self):
209 ## """Revert buffer to version of file on disk."""
212 def bufferSave(self
):
213 """Save buffer to its file."""
214 if self
.buffer.doc
.filepath
:
218 cancel
= self
.bufferSaveAs()
221 def bufferSaveAs(self
):
222 """Save buffer to a new filename."""
223 if self
.bufferHasChanged() and self
.buffer.doc
.filepath
:
224 cancel
= self
.bufferSuggestSave()
228 if self
.buffer and self
.buffer.doc
.filedir
:
229 filedir
= self
.buffer.doc
.filedir
230 result
= saveSingle(directory
=filedir
)
232 self
.buffer.saveAs(result
.path
)
238 def bufferSuggestSave(self
):
239 """Suggest saving changes. Return True if user selected Cancel."""
240 result
= messageDialog(parent
=None,
241 message
='%s has changed.\n'
242 'Would you like to save it first'
243 '?' % self
.buffer.name
,
244 title
='Save current file?')
246 cancel
= self
.bufferSave()
248 cancel
= result
.text
== 'Cancel'
251 def updateNamespace(self
):
252 """Update the buffer namespace for autocompletion and calltips."""
253 if self
.buffer.updateNamespace():
254 self
.SetStatusText('Namespace updated')
256 self
.SetStatusText('Error executing, unable to update namespace')
259 class EditorNotebookFrame(EditorFrame
):
260 """Frame containing one or more editors in a notebook."""
262 def __init__(self
, parent
=None, id=-1, title
='PyAlaMode',
263 pos
=wx
.DefaultPosition
, size
=(800, 600),
264 style
=wx
.DEFAULT_FRAME_STYLE | wx
.NO_FULL_REPAINT_ON_RESIZE
,
266 """Create EditorNotebookFrame instance."""
268 EditorFrame
.__init
__(self
, parent
, id, title
, pos
,
269 size
, style
, filename
)
271 dispatcher
.connect(receiver
=self
._editorChange
,
272 signal
='EditorChange', sender
=self
.notebook
)
275 """Setup prior to first buffer creation.
277 Called automatically by base class during init."""
278 self
.notebook
= EditorNotebook(parent
=self
)
279 intro
= 'Py %s' % version
.VERSION
281 module
= imp
.new_module('__main__')
283 module
.__dict
__['__builtins__'] = __builtin__
284 namespace
= module
.__dict
__.copy()
285 self
.crust
= crust
.Crust(parent
=self
.notebook
, intro
=intro
, locals=namespace
)
286 self
.shell
= self
.crust
.shell
287 # Override the filling so that status messages go to the status bar.
288 self
.crust
.filling
.tree
.setStatusText
= self
.SetStatusText
289 # Override the shell so that status messages go to the status bar.
290 self
.shell
.setStatusText
= self
.SetStatusText
291 # Fix a problem with the sash shrinking to nothing.
292 self
.crust
.filling
.SetSashPosition(200)
293 self
.notebook
.AddPage(page
=self
.crust
, text
='*Shell*', select
=True)
294 self
.setEditor(self
.crust
.editor
)
295 self
.crust
.editor
.SetFocus()
297 def _editorChange(self
, editor
):
298 """Editor change signal receiver."""
299 self
.setEditor(editor
)
301 def OnAbout(self
, event
):
302 """Display an About window."""
303 title
= 'About PyAlaMode'
304 text
= 'Another fine, flaky program.'
305 dialog
= wx
.MessageDialog(self
, text
, title
,
306 wx
.OK | wx
.ICON_INFORMATION
)
310 def _updateTitle(self
):
311 """Show current title information."""
313 ## title = self.GetTitle()
314 ## if self.bufferHasChanged():
315 ## if title.startswith('* '):
318 ## self.SetTitle('* ' + title)
320 ## if title.startswith('* '):
321 ## self.SetTitle(title[2:])
323 def bufferCreate(self
, filename
=None):
324 """Create new buffer."""
326 panel
= wx
.Panel(parent
=self
.notebook
, id=-1)
327 wx
.EVT_ERASE_BACKGROUND(panel
, lambda x
: x
)
328 editor
= Editor(parent
=panel
)
329 panel
.editor
= editor
330 sizer
= wx
.BoxSizer(wx
.VERTICAL
)
331 sizer
.Add(editor
.window
, 1, wx
.EXPAND
)
332 panel
.SetSizer(sizer
)
333 panel
.SetAutoLayout(True)
335 buffer.addEditor(editor
)
336 buffer.open(filename
)
337 self
.setEditor(editor
)
338 self
.notebook
.AddPage(page
=panel
, text
=self
.buffer.name
, select
=True)
339 self
.editor
.setFocus()
341 def bufferDestroy(self
):
342 """Destroy the current buffer."""
343 selection
= self
.notebook
.GetSelection()
344 ## print "Destroy Selection:", selection
345 if selection
> 0: # Don't destroy the PyCrust tab.
347 del self
.buffers
[self
.buffer.id]
348 self
.buffer = None # Do this before DeletePage().
349 self
.notebook
.DeletePage(selection
)
352 """Create new buffer."""
357 def bufferOpen(self
):
358 """Open file in buffer."""
360 if self
.buffer and self
.buffer.doc
.filedir
:
361 filedir
= self
.buffer.doc
.filedir
362 result
= openMultiple(directory
=filedir
)
363 for path
in result
.paths
:
364 self
.bufferCreate(path
)
369 class EditorNotebook(wx
.Notebook
):
370 """A notebook containing a page for each editor."""
372 def __init__(self
, parent
):
373 """Create EditorNotebook instance."""
374 wx
.Notebook
.__init
__(self
, parent
, id=-1, style
=wx
.NO_FULL_REPAINT_ON_RESIZE
)
375 wx
.EVT_NOTEBOOK_PAGE_CHANGING(self
, self
.GetId(),
377 wx
.EVT_NOTEBOOK_PAGE_CHANGED(self
, self
.GetId(),
379 wx
.EVT_IDLE(self
, self
.OnIdle
)
381 def OnIdle(self
, event
):
382 """Event handler for idle time."""
383 self
._updateTabText
()
386 def _updateTabText(self
):
387 """Show current buffer display name on all but first tab."""
391 selection
= self
.GetSelection()
394 text
= self
.GetPageText(selection
)
395 window
= self
.GetPage(selection
)
396 if not window
.editor
:
398 if text
.endswith(changed
) or text
.endswith(unchanged
):
402 if name
!= window
.editor
.buffer.name
:
403 text
= window
.editor
.buffer.name
404 if window
.editor
.buffer.hasChanged():
405 if text
.endswith(changed
):
407 elif text
.endswith(unchanged
):
408 text
= text
[:-size
] + changed
412 if text
.endswith(changed
):
413 text
= text
[:-size
] + unchanged
414 elif text
.endswith(unchanged
):
419 self
.SetPageText(selection
, text
)
420 self
.Refresh() # Needed on Win98.
422 def OnPageChanging(self
, event
):
423 """Page changing event handler."""
426 def OnPageChanged(self
, event
):
427 """Page changed event handler."""
428 new
= event
.GetSelection()
429 window
= self
.GetPage(new
)
430 dispatcher
.send(signal
='EditorChange', sender
=self
,
431 editor
=window
.editor
)
436 class EditorShellNotebookFrame(EditorNotebookFrame
):
437 """Frame containing a notebook containing EditorShellNotebooks."""
439 def __init__(self
, parent
=None, id=-1, title
='PyAlaModeTest',
440 pos
=wx
.DefaultPosition
, size
=(600, 400),
441 style
=wx
.DEFAULT_FRAME_STYLE
,
442 filename
=None, singlefile
=False):
443 """Create EditorShellNotebookFrame instance."""
444 self
._singlefile
= singlefile
445 EditorNotebookFrame
.__init
__(self
, parent
, id, title
, pos
,
446 size
, style
, filename
)
449 """Setup prior to first buffer creation.
451 Called automatically by base class during init."""
452 if not self
._singlefile
:
453 self
.notebook
= EditorNotebook(parent
=self
)
455 def OnAbout(self
, event
):
456 """Display an About window."""
457 title
= 'About PyAlaModePlus'
458 text
= 'Another fine, flaky program.'
459 dialog
= wx
.MessageDialog(self
, text
, title
,
460 wx
.OK | wx
.ICON_INFORMATION
)
464 def bufferCreate(self
, filename
=None):
465 """Create new buffer."""
468 notebook
= EditorShellNotebook(parent
=self
,
470 self
.notebook
= notebook
472 notebook
= EditorShellNotebook(parent
=self
.notebook
,
474 self
.setEditor(notebook
.editor
)
475 if not self
._singlefile
:
476 self
.notebook
.AddPage(page
=notebook
, text
=self
.buffer.name
,
478 self
.editor
.setFocus()
480 def bufferDestroy(self
):
481 """Destroy the current buffer."""
484 del self
.buffers
[self
.buffer.id]
485 self
.buffer = None # Do this before DeletePage().
487 self
.notebook
.Destroy()
490 selection
= self
.notebook
.GetSelection()
491 ## print "Destroy Selection:", selection
492 self
.notebook
.DeletePage(selection
)
495 """Create new buffer."""
496 if self
._singlefile
and self
.bufferHasChanged():
497 cancel
= self
.bufferSuggestSave()
504 def bufferOpen(self
):
505 """Open file in buffer."""
506 if self
._singlefile
and self
.bufferHasChanged():
507 cancel
= self
.bufferSuggestSave()
511 if self
.buffer and self
.buffer.doc
.filedir
:
512 filedir
= self
.buffer.doc
.filedir
514 result
= openSingle(directory
=filedir
)
516 self
.bufferCreate(result
.path
)
518 result
= openMultiple(directory
=filedir
)
519 for path
in result
.paths
:
520 self
.bufferCreate(path
)
525 class EditorShellNotebook(wx
.Notebook
):
526 """A notebook containing an editor page and a shell page."""
528 def __init__(self
, parent
, filename
=None):
529 """Create EditorShellNotebook instance."""
530 wx
.Notebook
.__init
__(self
, parent
, id=-1)
533 editorparent
= editorpanel
= wx
.Panel(self
, -1)
534 shellparent
= shellpanel
= wx
.Panel(self
, -1)
538 self
.buffer = Buffer()
539 self
.editor
= Editor(parent
=editorparent
)
540 self
.buffer.addEditor(self
.editor
)
541 self
.buffer.open(filename
)
542 self
.shell
= Shell(parent
=shellparent
, locals=self
.buffer.interp
.locals,
543 style
=wx
.CLIP_CHILDREN | wx
.SUNKEN_BORDER
)
544 self
.buffer.interp
.locals.clear()
546 self
.AddPage(page
=editorpanel
, text
='Editor', select
=True)
547 self
.AddPage(page
=shellpanel
, text
='Shell')
549 editorsizer
= wx
.BoxSizer(wx
.VERTICAL
)
550 editorsizer
.Add(self
.editor
.window
, 1, wx
.EXPAND
)
551 editorpanel
.SetSizer(editorsizer
)
552 editorpanel
.SetAutoLayout(True)
553 shellsizer
= wx
.BoxSizer(wx
.VERTICAL
)
554 shellsizer
.Add(self
.shell
, 1, wx
.EXPAND
)
555 shellpanel
.SetSizer(shellsizer
)
556 shellpanel
.SetAutoLayout(True)
558 self
.AddPage(page
=self
.editor
.window
, text
='Editor', select
=True)
559 self
.AddPage(page
=self
.shell
, text
='Shell')
560 self
.editor
.setFocus()
561 wx
.EVT_NOTEBOOK_PAGE_CHANGED(self
, self
.GetId(), self
.OnPageChanged
)
563 def OnPageChanged(self
, event
):
564 """Page changed event handler."""
565 selection
= event
.GetSelection()
567 self
.editor
.setFocus()
569 self
.shell
.SetFocus()
573 wx
.Notebook
.SetFocus(self
)
574 selection
= self
.GetSelection()
576 self
.editor
.setFocus()
578 self
.shell
.SetFocus()
582 """Editor having an EditWindow."""
584 def __init__(self
, parent
, id=-1, pos
=wx
.DefaultPosition
,
586 style
=wx
.CLIP_CHILDREN | wx
.SUNKEN_BORDER
):
587 """Create Editor instance."""
588 self
.window
= EditWindow(self
, parent
, id, pos
, size
, style
)
589 self
.id = self
.window
.GetId()
591 # Assign handlers for keyboard events.
592 wx
.EVT_CHAR(self
.window
, self
.OnChar
)
593 wx
.EVT_KEY_DOWN(self
.window
, self
.OnKeyDown
)
595 def _setBuffer(self
, buffer, text
):
596 """Set the editor to a buffer. Private callback called by buffer."""
598 self
.autoCompleteKeys
= buffer.interp
.getAutoCompleteKeys()
601 self
.emptyUndoBuffer()
605 """Destroy all editor objects."""
606 self
.window
.Destroy()
609 self
.window
.ClearAll()
611 def emptyUndoBuffer(self
):
612 self
.window
.EmptyUndoBuffer()
615 """Return (filepath, line, column) status tuple."""
616 pos
= self
.window
.GetCurrentPos()
617 line
= self
.window
.LineFromPosition(pos
) + 1
618 col
= self
.window
.GetColumn(pos
)
620 name
= self
.buffer.doc
.filepath
or self
.buffer.name
623 status
= (name
, line
, col
)
627 """Return contents of editor."""
628 return self
.window
.GetText()
630 def hasChanged(self
):
631 """Return True if contents have changed."""
632 return self
.window
.GetModify()
635 """Set the input focus to the editor window."""
636 self
.window
.SetFocus()
638 def setSavePoint(self
):
639 self
.window
.SetSavePoint()
641 def setText(self
, text
):
642 """Set contents of editor."""
643 self
.window
.SetText(text
)
645 def OnChar(self
, event
):
646 """Keypress event handler.
648 Only receives an event if OnKeyDown calls event.Skip() for the
649 corresponding event."""
651 key
= event
.KeyCode()
652 if key
in self
.autoCompleteKeys
:
653 # Usually the dot (period) key activates auto completion.
654 if self
.window
.AutoCompActive():
655 self
.window
.AutoCompCancel()
656 self
.window
.ReplaceSelection('')
657 self
.window
.AddText(chr(key
))
658 text
, pos
= self
.window
.GetCurLine()
660 if self
.window
.autoComplete
:
661 self
.autoCompleteShow(text
)
662 elif key
== ord('('):
663 # The left paren activates a call tip and cancels an
664 # active auto completion.
665 if self
.window
.AutoCompActive():
666 self
.window
.AutoCompCancel()
667 self
.window
.ReplaceSelection('')
668 self
.window
.AddText('(')
669 text
, pos
= self
.window
.GetCurLine()
671 self
.autoCallTipShow(text
)
673 # Allow the normal event handling to take place.
676 def OnKeyDown(self
, event
):
677 """Key down event handler."""
679 key
= event
.KeyCode()
680 # If the auto-complete window is up let it do its thing.
681 if self
.window
.AutoCompActive():
684 controlDown
= event
.ControlDown()
685 altDown
= event
.AltDown()
686 shiftDown
= event
.ShiftDown()
687 # Let Ctrl-Alt-* get handled normally.
688 if controlDown
and altDown
:
690 # Increase font size.
691 elif controlDown
and key
in (ord(']'),):
692 dispatcher
.send(signal
='FontIncrease')
693 # Decrease font size.
694 elif controlDown
and key
in (ord('['),):
695 dispatcher
.send(signal
='FontDecrease')
697 elif controlDown
and key
in (ord('='),):
698 dispatcher
.send(signal
='FontDefault')
702 def autoCompleteShow(self
, command
):
703 """Display auto-completion popup list."""
704 list = self
.buffer.interp
.getAutoCompleteList(command
,
705 includeMagic
=self
.window
.autoCompleteIncludeMagic
,
706 includeSingle
=self
.window
.autoCompleteIncludeSingle
,
707 includeDouble
=self
.window
.autoCompleteIncludeDouble
)
709 options
= ' '.join(list)
711 self
.window
.AutoCompShow(offset
, options
)
713 def autoCallTipShow(self
, command
):
714 """Display argument spec and docstring in a popup window."""
715 if self
.window
.CallTipActive():
716 self
.window
.CallTipCancel()
717 (name
, argspec
, tip
) = self
.buffer.interp
.getCallTip(command
)
719 dispatcher
.send(signal
='Shell.calltip', sender
=self
, calltip
=tip
)
720 if not self
.window
.autoCallTip
:
723 startpos
= self
.window
.GetCurrentPos()
724 self
.window
.AddText(argspec
+ ')')
725 endpos
= self
.window
.GetCurrentPos()
726 self
.window
.SetSelection(endpos
, startpos
)
728 curpos
= self
.window
.GetCurrentPos()
730 tippos
= curpos
- (size
+ 1)
731 fallback
= curpos
- self
.window
.GetColumn(curpos
)
732 # In case there isn't enough room, only go back to the
734 tippos
= max(tippos
, fallback
)
735 self
.window
.CallTipShow(tippos
, tip
)
736 self
.window
.CallTipSetHighlight(0, size
)
739 class EditWindow(editwindow
.EditWindow
):
740 """EditWindow based on StyledTextCtrl."""
742 def __init__(self
, editor
, parent
, id=-1, pos
=wx
.DefaultPosition
,
744 style
=wx
.CLIP_CHILDREN | wx
.SUNKEN_BORDER
):
745 """Create EditWindow instance."""
746 editwindow
.EditWindow
.__init
__(self
, parent
, id, pos
, size
, style
)
751 """DialogResults class."""
753 def __init__(self
, returned
):
754 """Create wrapper for results returned by dialog."""
755 self
.returned
= returned
756 self
.positive
= returned
in (wx
.ID_OK
, wx
.ID_YES
)
757 self
.text
= self
._asString
()
761 return str(self
.__dict
__)
764 returned
= self
.returned
765 if returned
== wx
.ID_OK
:
767 elif returned
== wx
.ID_CANCEL
:
769 elif returned
== wx
.ID_YES
:
771 elif returned
== wx
.ID_NO
:
775 def fileDialog(parent
=None, title
='Open', directory
='', filename
='',
776 wildcard
='All Files (*.*)|*.*',
777 style
=wx
.OPEN | wx
.MULTIPLE
):
778 """File dialog wrapper function."""
779 dialog
= wx
.FileDialog(parent
, title
, directory
, filename
,
781 result
= DialogResults(dialog
.ShowModal())
783 result
.paths
= dialog
.GetPaths()
790 def openSingle(parent
=None, title
='Open', directory
='', filename
='',
791 wildcard
='All Files (*.*)|*.*', style
=wx
.OPEN
):
792 """File dialog wrapper function."""
793 dialog
= wx
.FileDialog(parent
, title
, directory
, filename
,
795 result
= DialogResults(dialog
.ShowModal())
797 result
.path
= dialog
.GetPath()
804 def openMultiple(parent
=None, title
='Open', directory
='', filename
='',
805 wildcard
='All Files (*.*)|*.*',
806 style
=wx
.OPEN | wx
.MULTIPLE
):
807 """File dialog wrapper function."""
808 return fileDialog(parent
, title
, directory
, filename
, wildcard
, style
)
811 def saveSingle(parent
=None, title
='Save', directory
='', filename
='',
812 wildcard
='All Files (*.*)|*.*',
813 style
=wx
.SAVE | wx
.HIDE_READONLY | wx
.OVERWRITE_PROMPT
):
814 """File dialog wrapper function."""
815 dialog
= wx
.FileDialog(parent
, title
, directory
, filename
,
817 result
= DialogResults(dialog
.ShowModal())
819 result
.path
= dialog
.GetPath()
826 def directory(parent
=None, message
='Choose a directory', path
='', style
=0,
827 pos
=wx
.DefaultPosition
, size
=wx
.DefaultSize
):
828 """Dir dialog wrapper function."""
829 dialog
= wx
.DirDialog(parent
, message
, path
, style
, pos
, size
)
830 result
= DialogResults(dialog
.ShowModal())
832 result
.path
= dialog
.GetPath()
839 def messageDialog(parent
=None, message
='', title
='Message box',
840 style
=wx
.YES_NO | wx
.CANCEL | wx
.CENTRE | wx
.ICON_QUESTION
,
841 pos
=wx
.DefaultPosition
):
842 """Message dialog wrapper function."""
843 dialog
= wx
.MessageDialog(parent
, message
, title
, style
, pos
)
844 result
= DialogResults(dialog
.ShowModal())