Package mathbench :: Package lab :: Module notebook
[hide private]

Source Code for Module mathbench.lab.notebook

  1  #!/usr/bin/python 
  2  # -*- coding: utf-8 -*- 
  3   
  4  """ 
  5  Inspired by 
  6  PyAlaCarte and PyAlaMode editors from wxPython 
  7   
  8  Combines the lab_bench and offers the possibility to transform the 
  9  current work into script files. 
 10  """ 
 11   
 12  import sys 
 13  import os 
 14   
 15  import wx 
 16  import wx.lib.dialogs 
 17   
 18  import wx.py 
 19  import wx.py.frame as PyFrame  
 20  import wx.py.dispatcher as dispatcher 
 21   
 22  from wx.py.editor import * 
 23   
 24  from mathbench.basement.history_manager import HistoryManager 
 25   
 26  from mathbench.lab.labbench import LabBench 
 27  import mathbench.lab.advisor as advisor 
 28   
 29  from mathbench.basement.librarian import LibrarianSingleton 
 30   
 31  ID_EXECUTE = wx.NewId() 
 32  ID_EXECUTE_MAIN = wx.NewId() 
 33  ID_PREFERENCE = wx.NewId() 
 34  ID_LIBRARY = wx.NewId() 
 35  ID_HISTORY_TO_SCRIPT = wx.NewId() 
 36  ID_LOAD_OLD_SESSION = wx.NewId() 
 37   
 38   
 39  from wx.html import HtmlEasyPrinting 
 40   
41 -class Printer(HtmlEasyPrinting):
42 """ 43 Small printing class taken from: http://wiki.wxpython.org/Printing 44 """
45 - def __init__(self):
46 HtmlEasyPrinting.__init__(self)
47
48 - def GetHtmlText(self,text):
49 "Simple conversion of text. Use a more powerful version" 50 html_text = text.replace('\n', '<BR>') 51 return html_text
52
53 - def Print(self, text, doc_name):
54 self.SetHeader(doc_name) 55 self.PrintText(self.GetHtmlText(text),doc_name)
56
57 - def PreviewText(self, text, doc_name):
58 self.SetHeader(doc_name) 59 HtmlEasyPrinting.PreviewText(self, self.GetHtmlText(text))
60
61 -class LabEditorNotebook(EditorNotebook):
62 """ 63 Very light customisation of the base class 64 """
65 - def __init__(self,parent,config):
66 """ 67 Create the instance 68 """ 69 EditorNotebook.__init__(self,parent) 70 self.config = config 71 self.parent = parent
72
73 - def AddPage(self,page,text="Page",select=False):
74 """ 75 Also enforce the configuration options for each new element. 76 """ 77 EditorNotebook.AddPage(self,page,text=text,select=select) 78 dispatcher.send(signal='NewPageOnNotebook', sender=self)
79 80
81 -class LabBook(EditorNotebookFrame):
82 """ 83 LabBook instance that manage all the sutff displayed on screen 84 (editors and shells). 85 86 To add the singleton behaviour to a LabBench instance. 87 88 implemented in a similar way as in : 89 http://www.haypocalc.com/blog/index.php/2006/05/12/3-motifs-de-conception-et-python 90 """ 91 92 # storage for the instance reference 93 __instance = None 94 95 # the commant to be executed when the shell starts 96 _init_shell_session = [] 97 98
99 - def __init__(self, parent=None, id=-1, title='MathBench', 100 config=None, 101 pos=wx.DefaultPosition, size=(800, 600), 102 style=wx.DEFAULT_FRAME_STYLE | wx.NO_FULL_REPAINT_ON_RESIZE, 103 filename=None, history_dir=None):
104 """Create LabBookFrame instance.""" 105 self.config = config 106 self.history_dir = history_dir 107 EditorNotebookFrame.__init__(self, parent, id, title, pos, 108 size, style, filename) 109 self._modify_menus() 110 # keep track of the option frame to avoir having two of them 111 self.options_frame = None 112 # keep track of the shells opened for the exectution of a spectific file 113 self.execution_shells = {}
114
115 - def __new__(cls,parent=None, id=-1, title='Math Bench', config=None, 116 pos=wx.DefaultPosition, size=(800, 600), 117 style=wx.DEFAULT_FRAME_STYLE | wx.NO_FULL_REPAINT_ON_RESIZE, 118 filename=None, history_dir=None):
119 """ 120 Make sure only one instance is ever created 121 """ 122 if cls.__instance is None: 123 cls.__instance = object.__new__(cls) 124 return cls.__instance
125 126 # now the implementation 127
128 - def _init_notebook(self):
129 """ 130 Create the top level widgets contained by the frame 131 """ 132 # create the notebook that will hold the shell and editors 133 self.notebook = LabEditorNotebook(parent=self,config=self.config) 134 dispatcher.connect(receiver=self._newPageOnNotebook, 135 signal='NewPageOnNotebook', sender=self.notebook)
136
137 - def _init_helpbar(self):
138 """ 139 Create a toolbar showing some helping options 140 """ 141 self.helpbar = wx.Panel( self,-1, size=wx.Size(-1,20)) 142 help_sizer = wx.BoxSizer(wx.HORIZONTAL) 143 tb_img_size = (16,16) 144 bt_size = (20,20) 145 art_prov = wx.ArtProvider() 146 # show library 147 img = art_prov.GetBitmap(wx.ART_HELP_BOOK, 148 wx.ART_TOOLBAR, 149 tb_img_size) 150 btn = wx.BitmapButton(self.helpbar, 50, img) 151 btn.SetToolTipString("Show the library desk.") 152 self.Bind(wx.EVT_BUTTON, self.OnHelpToolClick, id=50) 153 help_sizer.Add(btn,proportion=0,border=3,flag=wx.ALL) 154 155 # search query widget 156 dummylongtext = wx.StaticText(self.helpbar,-1,"mathbench.basement.configuration.py") 157 dummylongtext.Fit() 158 nice_width = dummylongtext.GetBestSize().width 159 dummylongtext.Hide() 160 self.query_widget = wx.TextCtrl(name='query', 161 parent=self.helpbar, 162 size=wx.Size(nice_width,-1)) 163 self.query_widget.SetToolTipString("Press 'Enter' to launch the search") 164 self.query_widget.Bind(wx.EVT_KEY_DOWN,self.OnQueryKeyDown) 165 help_sizer.Add(self.query_widget,proportion=1,flag=wx.EXPAND | wx.ALL, border=3) 166 167 # delete button 168 img = art_prov.GetBitmap(wx.ART_DELETE, 169 wx.ART_TOOLBAR, 170 tb_img_size) 171 btn = wx.BitmapButton(self.helpbar, 30, img) 172 btn.SetToolTipString("Clear the search form.") 173 self.Bind(wx.EVT_BUTTON, self.OnHelpToolClick, id=30) 174 help_sizer.Add(btn,proportion=0,border=3,flag=wx.ALL) 175 self.helpbar.SetSizer(help_sizer) 176 177 # search button 178 img = art_prov.GetBitmap(wx.ART_FIND, 179 wx.ART_TOOLBAR, 180 tb_img_size) 181 btn = wx.BitmapButton(self.helpbar,35, img) 182 btn.SetToolTipString("Search the documentation.") 183 self.Bind(wx.EVT_BUTTON, self.OnHelpToolClick, id=35) 184 help_sizer.Add(btn,proportion=0,border=3,flag=wx.ALL) 185 186 self.helpbar.SetSizer(help_sizer)
187
188 - def _init_shell_widget(self):
189 """ 190 Create the widget that will be used as the main shell 191 """ 192 import imp 193 module = imp.new_module('__main__') 194 import __builtin__ 195 module.__dict__['__builtins__'] = __builtin__ 196 namespace = module.__dict__.copy() 197 intro = "Welcome in MathBench" 198 self.labBench = LabBench(parent=self.notebook, intro=intro, locals=namespace) 199 self.shell = self.labBench.shell 200 # if a directory to put the session files in is provided, then 201 # instanciate a History manager. 202 if self.history_dir is not None: 203 self.historyman = HistoryManager(self.shell, self.history_dir) 204 dispatcher.connect(receiver=self.historyman.save_current_session, signal='LabBook.close') 205 self.historyman.load_latest_session() 206 self.historyman.put_landmark()
207
208 - def _setup(self):
209 """ 210 Setup prior to first buffer creation. 211 212 Called automatically by base class during init. 213 """ 214 sizer = wx.BoxSizer(wx.VERTICAL) 215 # create the base widgets 216 self._init_notebook() 217 sizer.Add(self.notebook,proportion=1,flag=wx.EXPAND) 218 # create the help bar 219 self._init_helpbar() 220 sizer.Add(self.helpbar,proportion=0,flag=wx.EXPAND) 221 self.SetSizer(sizer) 222 # create the shell 223 self._init_shell_widget() 224 # # Override the logBook so that status messages go to the status bar. 225 # self.labBench.logBook.setStatusText = self.SetStatusText 226 # # And tell the logBook to use our sink when the user wants to extract the log 227 # self.labBench.logBook.log_sink = self.log_sink_to_file 228 # Override the shell so that status messages go to the status bar. 229 self.shell.setStatusText = self.SetStatusText 230 # make sure the std::cout & co are shown in the shell 231 self.shell.redirectStdout(True) 232 self.shell.redirectStderr(True) 233 # Fix a problem with the sash shrinking to nothing. 234 self.notebook.AddPage(page=self.labBench, text='*Shell*', select=True) 235 self.setEditor(self.labBench.editor) 236 # make sure the shell gets the focus 237 wx.CallAfter(self.shell.SetFocus) 238 # launch session initialisation 239 self.init_worksession()
240
241 - def _newPageOnNotebook(self,):
242 """ 243 When a new page is added perform some necessary checking and 244 settings. 245 """ 246 page_nb = self.notebook.GetPageCount() 247 if page_nb>1: 248 self.enforce_options(self.notebook.GetPage(page_nb-1).editor.window) 249 else: 250 # this is the shell 251 self.enforce_options(self.shell)
252
253 - def init_worksession(self):
254 """ 255 Put here the functions to call at the begining of the working 256 session of the shell. 257 258 This is separated from the init function, so that anybody can 259 overwrite the content of this function. 260 """ 261 for cmd_str in LabBook._init_shell_session: 262 self.shell.run(cmd_str)
263
264 - def enforce_options(self,window):
265 """ 266 Enforce the choices the user made with the options. 267 """ 268 if self.config is None: 269 return 270 # set the options relative to autocompletion 271 section_name = "Auto Completion" 272 if self.config.has_section(section_name): 273 window.autoComplete = (self.config.get(section_name,"Show_Auto_Completion")=="1") 274 window.autoCompleteIncludeMagic = (self.config.get(section_name,"Include_Magic_Attributes")=="1") 275 window.autoCompleteIncludeSingle = (self.config.get(section_name,"Include_Single_Underscores")=="1") 276 window.autoCompleteIncludeDouble = (self.config.get(section_name,"Include_Double_Underscores")=="1") 277 # set the options relative to autocompletion 278 section_name = "Call Tips" 279 if self.config.has_section(section_name): 280 window.autoCallTip = (self.config.get(section_name,"Show_Call_Tips")=="1") 281 window.callTipInsert = (self.config.get(section_name,"Insert_Call_Tips")=="1") 282 # set the options relative to the view 283 section_name = "View" 284 if self.config.has_section(section_name): 285 window.SetWrapMode((self.config.get(section_name,"Wrap_Lines")=="1")) 286 wx.FutureCall(1, self.shell.EnsureCaretVisible) 287 window.lineNumbers = (self.config.get(section_name,"Show_Line_Numbers")=="1") 288 window.setDisplayLineNumbers(window.lineNumbers)
289
290 - def _modify_menus(self):
291 """ 292 Recreate the menus, overwritting what has been done in the 293 wx/py/frame.py 294 """ 295 art_prov = wx.ArtProvider() 296 # Remove predefined menus 297 for i in reversed(range(self.menuBar.GetMenuCount())): 298 self.menuBar.Remove(i) 299 # File Menu 300 m = self.fileMenu = wx.Menu() 301 m.Append(PyFrame.ID_NEW, '&New \tCtrl+N', 302 'New file') 303 m.Append(PyFrame.ID_OPEN, '&Open... \tCtrl+O', 304 'Open file') 305 m.AppendSeparator() 306 m.Append(PyFrame.ID_REVERT, '&Revert \tCtrl+R', 307 'Revert to last saved version') 308 m.Append(PyFrame.ID_CLOSE, '&Close \tCtrl+W', 309 'Close file') 310 m.AppendSeparator() 311 m.Append(PyFrame.ID_SAVE, '&Save... \tCtrl+S', 312 'Save file') 313 m.Append(PyFrame.ID_SAVEAS, 'Save &As \tCtrl+Shift+S', 314 'Save file with new name') 315 m.AppendSeparator() 316 m.Append(PyFrame.ID_PRINT, '&Print... \tCtrl+P', 317 'Print file') 318 m.AppendSeparator() 319 m.Append(ID_HISTORY_TO_SCRIPT, 'Session &To Script', 320 "Create a script from the session's history") 321 m.Append(ID_LOAD_OLD_SESSION, "Recover &Older Session", 322 'Load (and exectute) the history of a previous session') 323 m.AppendSeparator() 324 m.Append(ID_EXECUTE, '&Execute \tF9', 325 'Execute the script in a new shell') 326 m.Append(ID_EXECUTE_MAIN, 'Execute in &main shell \tShift+F9', 327 'Execute the script in the main shell') 328 m.Append(PyFrame.ID_NAMESPACE, '&Update Namespace \tCtrl+Shift+N', 329 'Update namespace for autocompletion and calltips') 330 m.AppendSeparator() 331 m.Append(PyFrame.ID_EXIT, 'E&xit\tCtrl+Q', 'Exit Program') 332 333 # Edit 334 m = self.editMenu = wx.Menu() 335 m.Append(PyFrame.ID_UNDO, '&Undo \tCtrl+Z', 336 'Undo the last action') 337 m.Append(PyFrame.ID_REDO, '&Redo \tCtrl+Y', 338 'Redo the last undone action') 339 m.AppendSeparator() 340 m.Append(PyFrame.ID_CUT, 'Cu&t \tCtrl+X', 341 'Cut the selection') 342 m.Append(PyFrame.ID_COPY, '&Copy \tCtrl+C', 343 'Copy the selection') 344 m.Append(PyFrame.ID_COPY_PLUS, 'Cop&y Plus \tCtrl+Shift+C', 345 'Copy the selection - retaining prompts') 346 m.Append(PyFrame.ID_PASTE, '&Paste \tCtrl+V', 'Paste from clipboard') 347 m.Append(PyFrame.ID_PASTE_PLUS, "Past&e'n'run \tCtrl+Shift+V", 348 'Paste and run commands') 349 m.AppendSeparator() 350 m.Append(PyFrame.ID_EMPTYBUFFER, 'E&mpty Buffer...', 351 'Delete all the contents of the edit buffer') 352 m.Append(PyFrame.ID_SELECTALL, 'Select A&ll \tCtrl+A', 353 'Select all text') 354 if wx.Platform == '__WXGTK__': 355 m.AppendSeparator() 356 m.Append(ID_PREFERENCE,"&Preferences", 357 "Open the preference panel") 358 359 # View 360 m = self.autocompMenu = wx.Menu() 361 m.Append(PyFrame.ID_AUTOCOMP_SHOW, 'Show &Auto Completion\tCtrl+Shift+A', 362 'Show auto completion list', wx.ITEM_CHECK) 363 m.Append(PyFrame.ID_AUTOCOMP_MAGIC, 'Include &Magic Attributes\tCtrl+Shift+M', 364 'Include attributes visible to __getattr__ and __setattr__', 365 wx.ITEM_CHECK) 366 m.Append(PyFrame.ID_AUTOCOMP_SINGLE, 'Include Single &Underscores\tCtrl+Shift+U', 367 'Include attibutes prefixed by a single underscore', wx.ITEM_CHECK) 368 m.Append(PyFrame.ID_AUTOCOMP_DOUBLE, 'Include &Double Underscores\tCtrl+Shift+D', 369 'Include attibutes prefixed by a double underscore', wx.ITEM_CHECK) 370 m = self.calltipsMenu = wx.Menu() 371 m.Append(PyFrame.ID_CALLTIPS_SHOW, 'Show Call &Tips\tCtrl+Shift+T', 372 'Show call tips with argument signature and docstring', wx.ITEM_CHECK) 373 m.Append(PyFrame.ID_CALLTIPS_INSERT, '&Insert Call Tips\tCtrl+Shift+I', 374 '&Insert Call Tips', wx.ITEM_CHECK) 375 376 m = self.viewMenu = wx.Menu() 377 m.AppendMenu(PyFrame.ID_AUTOCOMP, '&Auto Completion', self.autocompMenu, 378 'Auto Completion Options') 379 m.AppendMenu(PyFrame.ID_CALLTIPS, '&Call Tips', self.calltipsMenu, 380 'Call Tip Options') 381 m.Append(PyFrame.ID_WRAP, '&Wrap Lines\tCtrl+Shift+W', 382 'Wrap lines at right edge', wx.ITEM_CHECK) 383 m.Append(PyFrame.ID_SHOW_LINENUMBERS, '&Show Line Numbers\tCtrl+Shift+L', 'Show Line Numbers', wx.ITEM_CHECK) 384 m.AppendSeparator() 385 m.Append(PyFrame.ID_TOGGLE_MAXIMIZE, '&Toggle Maximize\tF11', 'Maximize/Restore Application') 386 # add library menu 387 if wx.Platform == '__WXMAC__': 388 m.AppendSeparator() 389 m.Append(ID_LIBRARY,"&Library desk", 390 "Show the library desk and its useful pointers") 391 m.Append(PyFrame.ID_HELP, '&Help\tF1', 'Help!') 392 m.Append(PyFrame.ID_ABOUT, '&About...', 'About this program') 393 if wx.Platform != '__WXGTK__': 394 if wx.Platform == '__WXMAC__': 395 wx.App.SetMacPreferencesMenuItemId(ID_PREFERENCE) 396 m.Append(ID_PREFERENCE,"&Preferences", 397 "Open the preference panel") 398 399 # Search 400 m = self.searchMenu = wx.Menu() 401 m.Append(PyFrame.ID_FIND, '&Find Text... \tCtrl+F', 402 'Search for text in the edit buffer') 403 m.Append(PyFrame.ID_FINDNEXT, 'Find &Next \tF3', 404 'Find next/previous instance of the search text') 405 406 # Help menu (with a workaround for mac...) 407 m = self.helpMenu = wx.Menu() 408 m.Append(PyFrame.ID_HELP, '&Help\tF1', 'Help!') 409 if wx.Platform != "__WXMAC__": 410 m.AppendSeparator() 411 m.Append(ID_LIBRARY,"&Library desk", 412 "Show the library desk and its useful pointers") 413 m.AppendSeparator() 414 m.Append(PyFrame.ID_ABOUT, '&About...', 'About this program') 415 416 b = self.menuBar 417 b.Append(self.fileMenu, '&Script') 418 b.Append(self.editMenu, '&Edit') 419 b.Append(self.viewMenu, '&View') 420 b.Append(self.searchMenu, '&Search') 421 if wx.Platform != "__WXMAC__": 422 b.Append(self.helpMenu, '&Help') 423 424 # Bindings 425 self.Bind(wx.EVT_MENU, self.OnExecute, id=ID_EXECUTE) 426 self.Bind(wx.EVT_MENU, self.OnExecuteInMainShell, id=ID_EXECUTE_MAIN) 427 self.Bind(wx.EVT_MENU, self.OnPreference, id=ID_PREFERENCE) 428 self.Bind(wx.EVT_MENU, self.OnLibrary, id=ID_LIBRARY) 429 self.Bind(wx.EVT_MENU, self.OnHistoryToScript, id=ID_HISTORY_TO_SCRIPT) 430 self.Bind(wx.EVT_MENU, self.OnLoadOldSession, id=ID_LOAD_OLD_SESSION) 431 self.shell.Bind(wx.EVT_CLOSE, self.OnClose)
432
433 - def _checkCurrentBufferSaved(self,title="Savind required"):
434 """ 435 Check is the content of the current buffer has been saved (at 436 its latest version). 437 """ 438 if not self.bufferHasChanged(): 439 return True 440 else: 441 d = wx.MessageDialog(self,u'You need to save the script first.\nDo you want to do is now ?',u'%s'%title, wx.YES_NO | wx.ICON_WARNING) 442 yes_no = d.ShowModal() 443 if yes_no != wx.ID_YES: 444 return False 445 cancel = self.bufferSave() 446 return not cancel
447
448 - def _editorChange(self, editor):
449 """ 450 When the editor change, update the menu options. 451 """ 452 EditorNotebookFrame._editorChange(self,editor) 453 # enable/disable menu items that make sense 454 if isinstance(editor,wx.py.shell.Shell): 455 self.fileMenu.Enable(ID_EXECUTE,False) 456 self.fileMenu.Enable(ID_EXECUTE_MAIN,False) 457 self.fileMenu.Enable(ID_HISTORY_TO_SCRIPT,True) 458 self.fileMenu.Enable(ID_LOAD_OLD_SESSION,True) 459 else: 460 self.fileMenu.Enable(ID_EXECUTE,True) 461 self.fileMenu.Enable(ID_EXECUTE_MAIN,True) 462 self.fileMenu.Enable(ID_HISTORY_TO_SCRIPT,False) 463 self.fileMenu.Enable(ID_LOAD_OLD_SESSION,False)
464
465 - def log_sink_to_file(self, text):
466 """ 467 Create a new file from the given text 468 """ 469 self.bufferNew() 470 self.editor.setText(text)
471
472 - def bufferNew(self):
473 """ 474 Create new buffer. 475 476 This method is redefined only to include a workaround for 477 bug#1752674 478 """ 479 cancel = EditorNotebookFrame.bufferNew(self) 480 if not cancel: 481 self.editor.buffer.overwriteConfirm = lambda s,filepath=None: True 482 self.editor.buffer.confirmed = False 483 return cancel
484
485 - def bufferPrint(self):
486 """ 487 printing ability 488 """ 489 printer = Printer() 490 if isinstance(self.editor,wx.py.shell.Shell): 491 printer.Print(self.editor.GetText(), 492 "*Shell*") 493 else: 494 printer.Print(self.editor.getText(), 495 self.editor.buffer.name)
496 497
498 - def OnClose(self,event):
499 """ 500 Close everything and don't let a creepy plugin hold the end of the app. 501 """ 502 dispatcher.send(signal="LabBook.close") 503 sys.exit(0)
504
505 - def OnHelp(self,event):
506 """ 507 Display a small helpign text 508 """ 509 msg = """\ 510 Basic usage 511 ----------- 512 513 1) type and execute a few commands in the shell 514 515 2) ask for this commands to be transformed into a plain script file 516 (via the menu "Script"->"Session To script") 517 518 3) edit the script 519 520 4) execute it with Script->Execute 521 522 5) save it when you're done ! 523 524 and later on... 525 526 - open an existing script and edit it 527 528 - restart an old shell session (see "Script"->"Recover Old Session") 529 530 Search for documentation 531 ------------------------ 532 533 Code samples and documentation are available at the library desk: 534 535 - type a query at the bottom of the application's window 536 537 or 538 539 - launch the desk via the menu "Help"->"Library Desk" 540 541 542 Shortcut keys 543 ------------- 544 545 (also accessible by typing shell.help()) 546 547 %s 548 """ % wx.py.shell.HELP_TEXT 549 dlg =wx.lib.dialogs.ScrolledMessageDialog(self, msg, "Help about Mathbench") 550 dlg.Show()
551
552 - def OnAbout(self, event):
553 """Display an About window.""" 554 title = 'MathBench' 555 text = """ 556 Not a whole laboratory, just a small bench' 557 558 That is: another fine, flaky program for lazy scientists :) 559 560 Written by Thibauld Nion 561 And heavily based on wxPython's py library. 562 """ 563 dialog = wx.MessageDialog(self, text, title, 564 wx.OK | wx.ICON_INFORMATION) 565 dialog.ShowModal() 566 dialog.Destroy()
567
568 - def OnLibrary(self,event):
569 """ 570 Show the library desk 571 """ 572 LibrarianSingleton.popup()
573 574
575 - def OnExecute(self,event):
576 """ 577 Execute the script in a new shell frame. 578 """ 579 if not self._checkCurrentBufferSaved(): 580 return 581 script_filepath = self.editor.buffer.doc.filepath 582 if self.execution_shells.has_key(script_filepath): 583 execframe = self.execution_shells[script_filepath] 584 else: 585 # create a new shell 586 execframe = wx.py.shell.ShellFrame() 587 self.execution_shells[script_filepath] = execframe 588 def OnCloseExecShell(event): 589 """ 590 remove any reference to this shell 591 """ 592 self.execution_shells.pop(script_filepath) 593 event.Skip()
594 execframe.Bind(wx.EVT_CLOSE,OnCloseExecShell) 595 # don't want the history of this new shell to be recorded 596 execframe.shell.addHistory = lambda x: None 597 # amke sure the window is visible 598 execframe.Hide() 599 execframe.Show() 600 # exec the file 601 # execframe.shell.run("execfile('%s')" % script_filepath) 602 execframe.shell.runfile(script_filepath)
603
604 - def OnExecuteInMainShell(self,event):
605 """ 606 Execute the script in the main shell. 607 """ 608 if not self._checkCurrentBufferSaved(): 609 return 610 filepath = self.editor.buffer.doc.filepath 611 self.notebook.SetSelection(0) 612 # exec the file (maybe there is a cleaner way to do this ?) 613 self.shell.run("execfile('%s')" % filepath)
614
615 - def OnPreference(self,event):
616 """ 617 Show the preference panel 618 """ 619 if self.options_frame is None: 620 self.options_frame = advisor.OptionsFrame(self,self.config) 621 dispatcher.connect(signal='OptionsChanged', 622 receiver=self._onOptionsChanged,sender=self.options_frame) 623 dispatcher.connect(signal="OptionsClosed", 624 receiver=self._onOptionsClosed,sender=self.options_frame) 625 else: 626 self.options_frame.Hide() 627 self.options_frame.Show()
628 629
630 - def OnHistoryToScript(self,event):
631 """ 632 Pass the shell's history to a new script. 633 """ 634 txtL = self.historyman.get_history_from_landmark() 635 txtL.reverse() 636 script = os.linesep.join(txtL) 637 return self.log_sink_to_file(script)
638 639
640 - def OnLoadOldSession(self,event):
641 """ 642 Load an older session from its history file. 643 """ 644 d = wx.FileDialog(self,"Please chose a session to load",self.history_dir, 645 wildcard="*.session", style=wx.FD_OPEN) 646 ok_cancel = d.ShowModal() 647 path = d.GetPath() 648 d.Destroy() 649 if ok_cancel==wx.ID_OK and os.path.isfile(path): 650 f = open(path) 651 txt = f.read() 652 txtL = txt.split(self.historyman.COMMANDS_SEPARATOR) 653 txtL.reverse() 654 # print txtL 655 sesname = os.path.splitext(os.path.basename(path))[0] 656 self.shell.run("# Recovering session: %s" % sesname) 657 # for c in txtL: 658 # self.shell.run(c) 659 self.shell.Execute("\n\n".join(txtL))
660 661
662 - def _onOptionsChanged(self):
663 """ 664 Take into accout a change in the options 665 """ 666 # this is the shell 667 self.enforce_options(self.shell) 668 for page_id in range(1,self.notebook.GetPageCount()): 669 self.enforce_options(self.notebook.GetPage(page_id).editor.window)
670
671 - def _onOptionsClosed(self):
672 """ 673 Remove the reference to the options frame 674 """ 675 self.options_frame = None
676
677 - def OnHelpToolClick(self,event):
678 """ 679 When the user clicks on the helpbar, find which button has 680 been clicked and act ! 681 """ 682 eid = event.GetId() 683 if eid==30: #< Clear 684 self.query_widget.Clear() 685 elif eid==35: #< Search 686 LibrarianSingleton.search(self.query_widget.GetValue()) 687 elif eid==50: #< Desk 688 LibrarianSingleton.popup() 689 else: 690 raise Exception("Event from unknown source!")
691 692
693 - def OnQueryKeyDown(self,event):
694 """ 695 When user clicks on enter while typing in the query widget, 696 then launch the search ! 697 """ 698 if event.GetKeyCode() == wx.WXK_RETURN: 699 LibrarianSingleton.search(self.query_widget.GetValue()) 700 event.Skip() 701 702 # --- Static interface 703 # class/static methods easily accessible by the plugins for 704 # instance 705
706 - def initShellSessionAppend(self,cmd_str):
707 """ 708 Add a command to be executed at session init. 709 """ 710 self._init_shell_session.append(cmd_str)
711 initShellSessionAppend = classmethod(initShellSessionAppend) 712