source: sasview/calculatorview/src/sans/perspectives/calculator/pyconsole.py @ dc9660d

ESS_GUIESS_GUI_DocsESS_GUI_batch_fittingESS_GUI_bumps_abstractionESS_GUI_iss1116ESS_GUI_iss879ESS_GUI_iss959ESS_GUI_openclESS_GUI_orderingESS_GUI_sync_sascalccostrafo411magnetic_scattrelease-4.1.1release-4.1.2release-4.2.2release_4.0.1ticket-1009ticket-1094-headlessticket-1242-2d-resolutionticket-1243ticket-1249ticket885unittest-saveload
Last change on this file since dc9660d was f706e09c, checked in by Jae Cho <jhjcho@…>, 13 years ago

fixed a saveas bug

  • Property mode set to 100644
File size: 10.1 KB
Line 
1"""
2Console Module display Python console
3"""
4import sys
5import os
6import wx
7import wx.lib.dialogs
8import wx.py.editor as editor
9import wx.py.frame as frame
10import py_compile
11
12if sys.platform.count("win32")>0:
13    PANEL_WIDTH = 800
14    PANEL_HEIGHT = 700
15    FONT_VARIANT = 0
16else:
17    PANEL_WIDTH = 830
18    PANEL_HEIGHT = 730
19    FONT_VARIANT = 1
20ID_COMPILE = wx.NewId() 
21ID_RUN = wx.NewId() 
22
23def compile_file(path):
24    """
25    Compile a python file
26    """
27    try:
28        import py_compile
29        py_compile.compile(file=path, doraise=True)
30    except:
31        type, value, traceback = sys.exc_info()
32        return value
33    return None 
34
35class PyConsole(editor.EditorNotebookFrame):
36    ## Internal nickname for the window, used by the AUI manager
37    window_name = "Custom Model Editor"
38    ## Name to appear on the window title bar
39    window_caption = "Custom Model Editor"
40    ## Flag to tell the AUI manager to put this panel in the center pane
41    CENTER_PANE = False
42    def __init__(self, parent=None, manager=None, panel=None,
43                    title='Python Shell/Editor', filename=None,
44                    size=(PANEL_WIDTH, PANEL_HEIGHT)):
45        self.config = None
46        editor.EditorNotebookFrame.__init__(self, parent=parent, 
47                                        title=title, size=size,
48                                        filename=filename)
49        self.parent = parent
50        self._manager = manager
51        self.panel = panel
52        self._add_menu()
53        if filename != None:
54            dataDir = os.path.dirname(filename)
55        elif self.parent != None:
56            dataDir = self.parent._default_save_location
57        else:
58             dataDir = None
59        self.dataDir = dataDir
60        self.Centre()
61       
62        self.Bind(wx.EVT_MENU, self.OnNewFile, id=wx.ID_NEW)
63        self.Bind(wx.EVT_MENU, self.OnOpenFile, id=wx.ID_OPEN)
64        self.Bind(wx.EVT_MENU, self.OnSaveFile, id=wx.ID_SAVE)
65        self.Bind(wx.EVT_MENU, self.OnSaveAsFile, id=wx.ID_SAVEAS)
66        self.Bind(wx.EVT_MENU, self.OnCompile, id=ID_COMPILE)
67        self.Bind(wx.EVT_MENU, self.OnRun, id=ID_RUN)
68        self.Bind(wx.EVT_UPDATE_UI, self.OnUpdateCompileMenu, id=ID_COMPILE)
69        self.Bind(wx.EVT_UPDATE_UI, self.OnUpdateCompileMenu, id=ID_RUN)
70        if not title.count('Python Shell'):
71            # Delete menu item (open and new) if not python shell
72            #self.fileMenu.Delete(wx.ID_NEW)
73            self.fileMenu.Delete(wx.ID_OPEN)
74       
75   
76    def _add_menu(self):
77        """
78        Add menu
79        """
80        self.compileMenu = wx.Menu()
81        self.compileMenu.Append(ID_COMPILE, 'Compile',
82                 'Compile the file')
83        self.compileMenu.AppendSeparator()
84        self.compileMenu.Append(ID_RUN, 'Run in Shell',
85                 'Run the file in the Python Shell')
86        self.MenuBar.Insert(3, self.compileMenu, '&Run')
87   
88    def OnHelp(self, event):
89        """
90        Show a help dialog.
91        """
92        import  wx.lib.dialogs
93        title = 'Help on key bindings'
94        text = wx.py.shell.HELP_TEXT
95        dlg = wx.lib.dialogs.ScrolledMessageDialog(self, text, title,
96                                                   size = ((700, 540)))
97        fnt = wx.Font(10, wx.TELETYPE, wx.NORMAL, wx.NORMAL)
98        dlg.GetChildren()[0].SetFont(fnt)
99        dlg.GetChildren()[0].SetInsertionPoint(0)
100        dlg.ShowModal()
101        dlg.Destroy()
102
103    def set_manager(self, manager):
104        """
105        Set the manager of this window
106        """
107        self._manager = manager
108       
109    def OnAbout(self, event):
110        """
111        On About
112        """
113        message = ABOUT
114        dial = wx.MessageDialog(self, message, 'About',
115                           wx.OK|wx.ICON_INFORMATION) 
116        dial.ShowModal()
117       
118    def OnNewFile(self, event):
119        """
120        OnFileOpen 
121        """
122        self.OnFileNew(event)
123
124    def OnOpenFile(self, event):
125        """
126        OnFileOpen 
127        """
128        self.OnFileOpen(event)
129        self.Show(False)
130        self.Show(True)
131       
132    def OnSaveFile(self, event):
133        """
134        OnFileSave overwrite   
135        """
136        self.OnFileSave(event)
137        self.Show(False)
138        self.Show(True)
139       
140    def OnSaveAsFile(self, event):
141        """
142        OnFileSaveAs overwrite   
143        """
144        self.OnFileSaveAs(event)
145        self.Show(False)
146        self.Show(True)
147
148    def bufferOpen(self):
149        """
150        Open file in buffer, bypassing editor bufferOpen
151        """
152        if self.bufferHasChanged():
153            cancel = self.bufferSuggestSave()
154            if cancel:
155                return cancel
156        filedir = ''
157        if self.buffer and self.buffer.doc.filedir:
158            filedir = self.buffer.doc.filedir
159        if not filedir:
160            filedir = self.dataDir
161        result = editor.openSingle(directory=filedir, 
162                            wildcard='Python Files (*.py)|*.py')
163        if result.path:
164            self.bufferCreate(result.path)
165        cancel = False
166        return cancel
167   
168    def bufferSaveAs(self):
169        """
170        Save buffer to a new filename: Bypassing editor bufferSaveAs
171        """
172        filedir = ''
173        if self.buffer and self.buffer.doc.filedir:
174            filedir = self.buffer.doc.filedir
175        if not filedir:
176            filedir = self.dataDir
177        result = editor.saveSingle(directory=filedir, 
178                                   filename='untitled.py',
179                                   wildcard='Python Files (*.py)|*.py')
180        if result.path:
181            self.buffer.confirmed = True
182            self.buffer.saveAs(result.path)
183            cancel = False
184        else:
185            cancel = True
186        return cancel
187       
188    def OnRun(self, event):
189        """
190        Run
191        """
192        if self._check_changed():
193            return True
194        if self.buffer and self.buffer.doc.filepath:
195            self.editor.setFocus()
196            # Why we have to do this (Otherwise problems on Windows)?
197            forward_path = self.buffer.doc.filepath.replace('\\', '/')
198            self.shell.Execute("execfile('%s')"% forward_path) 
199            self.shell.Hide()
200            self.shell.Show(True)
201            return self.shell.GetText().split(">>>")[-2]
202        else:
203            mssg = "\n This is not a python file."
204            title = 'Error'
205            icon = wx.ICON_ERROR
206            wx.MessageBox(str(mssg), title, style=icon)
207            return 0
208       
209    def OnCompile(self, event):
210        """
211        Compile
212        """
213        if self._check_changed():
214            return True
215        run_out = self.OnRun(None)
216        if self._get_err_msg(run_out):
217            if self._manager != None and self.panel != None:
218                self._manager.set_edit_menu_helper(self.parent)
219                # Update custom model list in fitpage combobox
220                wx.CallAfter(self._manager.update_custom_combo)
221   
222    def _check_changed(self):   
223        """
224        If content was changed, suggest to save it first
225        """
226        if self.bufferHasChanged() and self.buffer.doc.filepath:
227            cancel = self.bufferSuggestSave()
228            if cancel:
229                return cancel
230             
231    def _get_err_msg(self, text=''):
232        """
233        Get err_msg
234        """
235        name = None
236        mssg = "\n This is not a python file."
237        title = 'Error'
238        icon = wx.ICON_ERROR
239        try:
240            fname = self.editor.getStatus()[0]
241            name = os.path.basename(fname)
242            if name.split('.')[-1] != 'py':
243                wx.MessageBox(str(mssg), title, style=icon)
244                return False
245            msg = compile_file(fname)
246        except:
247            msg = None
248        if name == None:
249            wx.MessageBox(str(mssg), title, style=icon)
250            return False
251        mssg = "Compiling '%s'...\n"% name
252        if msg != None:
253            mssg += "Error occurred:\n"
254            mssg += str(msg) + "\n\n"
255            if text:
256                mssg += "Run-Test results:\n"
257                mssg += str(text)
258                title = 'Warning'
259                icon = wx.ICON_WARNING
260        else:
261            mssg += "Successful.\n\n"
262            if text:
263                if text.count('Failed') or text.count('Error:') > 0:
264                    mssg += "But Simple Test FAILED: Please check your code.\n"
265                mssg += "Run-Test results:\n"
266                mssg += str(text)
267            title = 'Info'
268            icon = wx.ICON_INFORMATION
269        dlg = wx.lib.dialogs.ScrolledMessageDialog(self, mssg, title, 
270                                                   size = ((550, 250)))
271        fnt = wx.Font(10, wx.TELETYPE, wx.NORMAL, wx.NORMAL)
272        dlg.GetChildren()[0].SetFont(fnt)
273        dlg.GetChildren()[0].SetInsertionPoint(0)
274        dlg.ShowModal()
275        dlg.Destroy()
276        return True
277   
278    def OnUpdateCompileMenu(self, event):
279        """
280        Update Compile menu items based on current tap.
281        """
282        win = wx.Window.FindFocus()
283        id = event.GetId()
284        event.Enable(True)
285        try:
286            if id == ID_COMPILE or id == ID_RUN:
287                menu_on = False
288                if self.buffer and self.buffer.doc.filepath:
289                    menu_on = True
290                event.Enable(menu_on)
291        except AttributeError:
292            # This menu option is not supported in the current context.
293            event.Enable(False)
294           
295ABOUT =  "Welcome to Python %s! \n\n"% sys.version.split()[0]
296ABOUT += "This uses Py Shell/Editor in wx (developed by Patrick K. O'Brien).\n"
297ABOUT += "If this is your first time using Python, \n"
298ABOUT += "you should definitely check out the tutorial "
299ABOUT += "on the Internet at http://www.python.org/doc/tut/."
300 
301       
302if __name__ == "__main__":
303   
304    app  = wx.App()
305    dlg = PyConsole()
306    dlg.Show()
307    app.MainLoop()
Note: See TracBrowser for help on using the repository browser.