wxIPython.py
266 lines
| 10.2 KiB
| text/x-python
|
PythonLexer
ville
|
r988 | #!/usr/bin/python | ||
# -*- coding: iso-8859-15 -*- | ||||
import wx.aui | ||||
Laurent Dufréchou
|
r1548 | import sys | ||
ldufrechou
|
r1108 | #used for about dialog | ||
ville
|
r988 | from wx.lib.wordwrap import wordwrap | ||
ldufrechou
|
r1108 | #used for ipython GUI objects | ||
ldufrechou
|
r1168 | from IPython.gui.wx.ipython_view import IPShellWidget | ||
ldufrechou
|
r1108 | from IPython.gui.wx.ipython_history import IPythonHistoryPanel | ||
ville
|
r988 | |||
ldufrechou
|
r1623 | #used to invoke ipython1 wx implementation | ||
laurent dufrechou
|
r1838 | ### FIXME ### temporary disabled due to interference with 'show_in_pager' hook | ||
is_sync_frontend_ok = False | ||||
laurent dufrechou
|
r1809 | try: | ||
from IPython.frontend.wx.ipythonx import IPythonXController | ||||
except ImportError: | ||||
is_sync_frontend_ok = False | ||||
ldufrechou
|
r1623 | |||
Laurent Dufréchou
|
r1548 | #used to create options.conf file in user directory | ||
Brian Granger
|
r2027 | from IPython.core.ipapi import get | ||
Laurent Dufréchou
|
r1548 | |||
laurent dufrechou
|
r1809 | __version__ = 0.91 | ||
ville
|
r988 | __author__ = "Laurent Dufrechou" | ||
__email__ = "laurent.dufrechou _at_ gmail.com" | ||||
__license__ = "BSD" | ||||
#----------------------------------------- | ||||
# Creating one main frame for our | ||||
# application with movables windows | ||||
#----------------------------------------- | ||||
class MyFrame(wx.Frame): | ||||
"""Creating one main frame for our | ||||
application with movables windows""" | ||||
Gael Varoquaux
|
r1107 | def __init__(self, parent=None, id=-1, title="WxIPython", | ||
pos=wx.DefaultPosition, | ||||
laurent dufrechou
|
r1809 | size=(800, 600), style=wx.DEFAULT_FRAME_STYLE, sync_ok=False): | ||
ville
|
r988 | wx.Frame.__init__(self, parent, id, title, pos, size, style) | ||
self._mgr = wx.aui.AuiManager() | ||||
# notify PyAUI which frame to use | ||||
self._mgr.SetManagedWindow(self) | ||||
#create differents panels and make them persistant | ||||
self.history_panel = IPythonHistoryPanel(self) | ||||
ldufrechou
|
r1176 | |||
self.history_panel.setOptionTrackerHook(self.optionSave) | ||||
ville
|
r988 | |||
ldufrechou
|
r1130 | self.ipython_panel = IPShellWidget(self,background_color = "BLACK") | ||
ldufrechou
|
r1133 | #self.ipython_panel = IPShellWidget(self,background_color = "WHITE") | ||
laurent dufrechou
|
r1809 | if(sync_ok): | ||
self.ipython_panel2 = IPythonXController(self) | ||||
else: | ||||
self.ipython_panel2 = None | ||||
ville
|
r988 | self.ipython_panel.setHistoryTrackerHook(self.history_panel.write) | ||
self.ipython_panel.setStatusTrackerHook(self.updateStatus) | ||||
ldufrechou
|
r1130 | self.ipython_panel.setAskExitHandler(self.OnExitDlg) | ||
ldufrechou
|
r1168 | self.ipython_panel.setOptionTrackerHook(self.optionSave) | ||
ldufrechou
|
r1091 | |||
ldufrechou
|
r1623 | #Create a notebook to display different IPython shell implementations | ||
self.nb = wx.aui.AuiNotebook(self) | ||||
ldufrechou
|
r1176 | self.optionLoad() | ||
ldufrechou
|
r1168 | |||
ville
|
r988 | self.statusbar = self.createStatus() | ||
self.createMenu() | ||||
######################################################################## | ||||
### add the panes to the manager | ||||
# main panels | ||||
ldufrechou
|
r1623 | self._mgr.AddPane(self.nb , wx.CENTER, "IPython Shells") | ||
self.nb.AddPage(self.ipython_panel , "IPython0 Shell") | ||||
laurent dufrechou
|
r1809 | if(sync_ok): | ||
self.nb.AddPage(self.ipython_panel2, "IPython1 Synchroneous Shell") | ||||
ldufrechou
|
r1623 | |||
ville
|
r988 | self._mgr.AddPane(self.history_panel , wx.RIGHT, "IPython history") | ||
Gael Varoquaux
|
r1103 | |||
ville
|
r988 | # now we specify some panel characteristics | ||
self._mgr.GetPane(self.ipython_panel).CaptionVisible(True); | ||||
self._mgr.GetPane(self.history_panel).CaptionVisible(True); | ||||
self._mgr.GetPane(self.history_panel).MinSize((200,400)); | ||||
# tell the manager to "commit" all the changes just made | ||||
self._mgr.Update() | ||||
#global event handling | ||||
self.Bind(wx.EVT_CLOSE, self.OnClose) | ||||
self.Bind(wx.EVT_MENU, self.OnClose,id=wx.ID_EXIT) | ||||
self.Bind(wx.EVT_MENU, self.OnShowIPythonPanel,id=wx.ID_HIGHEST+1) | ||||
self.Bind(wx.EVT_MENU, self.OnShowHistoryPanel,id=wx.ID_HIGHEST+2) | ||||
self.Bind(wx.EVT_MENU, self.OnShowAbout, id=wx.ID_HIGHEST+3) | ||||
self.Bind(wx.EVT_MENU, self.OnShowAllPanel,id=wx.ID_HIGHEST+6) | ||||
ldufrechou
|
r1168 | |||
ville
|
r988 | warn_text = 'Hello from IPython and wxPython.\n' | ||
warn_text +='Please Note that this work is still EXPERIMENTAL\n' | ||||
warn_text +='It does NOT emulate currently all the IPython functions.\n' | ||||
laurent dufrechou
|
r1807 | warn_text +="\nIf you use MATPLOTLIB with show() you'll need to deactivate the THREADING option.\n" | ||
laurent dufrechou
|
r1810 | if(not sync_ok): | ||
warn_text +="\n->No twisted package detected, IPython1 example deactivated." | ||||
ville
|
r988 | dlg = wx.MessageDialog(self, | ||
warn_text, | ||||
'Warning Box', | ||||
wx.OK | wx.ICON_INFORMATION | ||||
) | ||||
dlg.ShowModal() | ||||
dlg.Destroy() | ||||
ldufrechou
|
r1168 | |||
def optionSave(self, name, value): | ||||
Laurent Dufréchou
|
r1548 | ip = get() | ||
Brian Granger
|
r2205 | path = ip.config.IPYTHONDIR | ||
Laurent Dufréchou
|
r1548 | opt = open(path + '/options.conf','w') | ||
ldufrechou
|
r1176 | |||
try: | ||||
options_ipython_panel = self.ipython_panel.getOptions() | ||||
options_history_panel = self.history_panel.getOptions() | ||||
for key in options_ipython_panel.keys(): | ||||
opt.write(key + '=' + options_ipython_panel[key]['value']+'\n') | ||||
for key in options_history_panel.keys(): | ||||
opt.write(key + '=' + options_history_panel[key]['value']+'\n') | ||||
finally: | ||||
opt.close() | ||||
ldufrechou
|
r1168 | |||
def optionLoad(self): | ||||
Laurent Dufréchou
|
r1548 | try: | ||
ip = get() | ||||
Brian Granger
|
r2205 | path = ip.config.IPYTHONDIR | ||
Laurent Dufréchou
|
r1548 | opt = open(path + '/options.conf','r') | ||
lines = opt.readlines() | ||||
opt.close() | ||||
ldufrechou
|
r1168 | |||
Laurent Dufréchou
|
r1548 | options_ipython_panel = self.ipython_panel.getOptions() | ||
options_history_panel = self.history_panel.getOptions() | ||||
for line in lines: | ||||
key = line.split('=')[0] | ||||
value = line.split('=')[1].replace('\n','').replace('\r','') | ||||
if key in options_ipython_panel.keys(): | ||||
options_ipython_panel[key]['value'] = value | ||||
elif key in options_history_panel.keys(): | ||||
options_history_panel[key]['value'] = value | ||||
else: | ||||
print >>sys.__stdout__,"Warning: key ",key,"not found in widget options. Check Options.conf" | ||||
self.ipython_panel.reloadOptions(options_ipython_panel) | ||||
self.history_panel.reloadOptions(options_history_panel) | ||||
ldufrechou
|
r1168 | |||
Laurent Dufréchou
|
r1548 | except IOError: | ||
print >>sys.__stdout__,"Could not open Options.conf, defaulting to default values." | ||||
ldufrechou
|
r1168 | |||
ville
|
r988 | def createMenu(self): | ||
"""local method used to create one menu bar""" | ||||
mb = wx.MenuBar() | ||||
file_menu = wx.Menu() | ||||
file_menu.Append(wx.ID_EXIT, "Exit") | ||||
view_menu = wx.Menu() | ||||
view_menu.Append(wx.ID_HIGHEST+1, "Show IPython Panel") | ||||
view_menu.Append(wx.ID_HIGHEST+2, "Show History Panel") | ||||
view_menu.AppendSeparator() | ||||
view_menu.Append(wx.ID_HIGHEST+6, "Show All") | ||||
about_menu = wx.Menu() | ||||
about_menu.Append(wx.ID_HIGHEST+3, "About") | ||||
mb.Append(file_menu, "File") | ||||
mb.Append(view_menu, "View") | ||||
mb.Append(about_menu, "About") | ||||
#mb.Append(options_menu, "Options") | ||||
self.SetMenuBar(mb) | ||||
def createStatus(self): | ||||
statusbar = self.CreateStatusBar(2, wx.ST_SIZEGRIP) | ||||
statusbar.SetStatusWidths([-2, -3]) | ||||
statusbar.SetStatusText("Ready", 0) | ||||
statusbar.SetStatusText("WxIPython "+str(__version__), 1) | ||||
return statusbar | ||||
def updateStatus(self,text): | ||||
states = {'IDLE':'Idle', | ||||
'DO_EXECUTE_LINE':'Send command', | ||||
'WAIT_END_OF_EXECUTION':'Running command', | ||||
ldufrechou
|
r1134 | 'WAITING_USER_INPUT':'Waiting user input', | ||
ville
|
r988 | 'SHOW_DOC':'Showing doc', | ||
'SHOW_PROMPT':'Showing prompt'} | ||||
self.statusbar.SetStatusText(states[text], 0) | ||||
def OnClose(self, event): | ||||
"""#event used to close program """ | ||||
# deinitialize the frame manager | ||||
self._mgr.UnInit() | ||||
self.Destroy() | ||||
event.Skip() | ||||
def OnExitDlg(self, event): | ||||
dlg = wx.MessageDialog(self, 'Are you sure you want to quit WxIPython', | ||||
'WxIPython exit', | ||||
wx.ICON_QUESTION | | ||||
wx.YES_NO | wx.NO_DEFAULT | ||||
) | ||||
if dlg.ShowModal() == wx.ID_YES: | ||||
dlg.Destroy() | ||||
self._mgr.UnInit() | ||||
self.Destroy() | ||||
dlg.Destroy() | ||||
#event to display IPython pannel | ||||
def OnShowIPythonPanel(self,event): | ||||
""" #event to display Boxpannel """ | ||||
self._mgr.GetPane(self.ipython_panel).Show(True) | ||||
self._mgr.Update() | ||||
#event to display History pannel | ||||
def OnShowHistoryPanel(self,event): | ||||
self._mgr.GetPane(self.history_panel).Show(True) | ||||
self._mgr.Update() | ||||
def OnShowAllPanel(self,event): | ||||
"""#event to display all Pannels""" | ||||
self._mgr.GetPane(self.ipython_panel).Show(True) | ||||
self._mgr.GetPane(self.history_panel).Show(True) | ||||
self._mgr.Update() | ||||
def OnShowAbout(self, event): | ||||
# First we create and fill the info object | ||||
info = wx.AboutDialogInfo() | ||||
info.Name = "WxIPython" | ||||
info.Version = str(__version__) | ||||
info.Copyright = "(C) 2007 Laurent Dufrechou" | ||||
info.Description = wordwrap( | ||||
"A Gui that embbed a multithreaded IPython Shell", | ||||
350, wx.ClientDC(self)) | ||||
info.WebSite = ("http://ipython.scipy.org/", "IPython home page") | ||||
info.Developers = [ "Laurent Dufrechou" ] | ||||
licenseText="BSD License.\nAll rights reserved. This program and the accompanying materials are made available under the terms of the BSD which accompanies this distribution, and is available at http://www.opensource.org/licenses/bsd-license.php" | ||||
info.License = wordwrap(licenseText, 500, wx.ClientDC(self)) | ||||
# Then we call wx.AboutBox giving it that info object | ||||
wx.AboutBox(info) | ||||
#----------------------------------------- | ||||
#Creating our application | ||||
#----------------------------------------- | ||||
class MyApp(wx.PySimpleApp): | ||||
"""Creating our application""" | ||||
laurent dufrechou
|
r1809 | def __init__(self, sync_ok=False): | ||
ville
|
r988 | wx.PySimpleApp.__init__(self) | ||
laurent dufrechou
|
r1809 | self.frame = MyFrame(sync_ok=sync_ok) | ||
ville
|
r988 | self.frame.Show() | ||
#----------------------------------------- | ||||
#Main loop | ||||
#----------------------------------------- | ||||
laurent.dufrechou@gmail.com
|
r1822 | def main(): | ||
app = MyApp(is_sync_frontend_ok) | ||||
ville
|
r988 | app.SetTopWindow(app.frame) | ||
app.MainLoop() | ||||
#if launched as main program run this | ||||
if __name__ == '__main__': | ||||
laurent.dufrechou@gmail.com
|
r1822 | main() | ||