##// END OF EJS Templates
Merged the work with gael
ldufrechou -
r1109:2bff973c merge
parent child Browse files
Show More
@@ -90,8 +90,7 b' class NonBlockingIPShell(object):'
90 90 via raise_exc()
91 91 '''
92 92
93 def __init__(self,argv
94 =[],user_ns={},user_global_ns=None,
93 def __init__(self,argv=[],user_ns={},user_global_ns=None,
95 94 cin=None, cout=None, cerr=None,
96 95 ask_exit_handler=None):
97 96 '''
@@ -158,14 +157,14 b' class NonBlockingIPShell(object):'
158 157 shell_class=IPython.Shell.InteractiveShell)
159 158
160 159 #we replace IPython default encoding by wx locale encoding
161 loc = locale.getpreferredencoding()
162 if loc:
163 self._IP.stdin_encoding = loc
160 loc = locale.getpreferredencoding()
161 if loc:
162 self._IP.stdin_encoding = loc
164 163 #we replace the ipython default pager by our pager
165 164 self._IP.set_hook('show_in_pager',self._pager)
166 165
167 166 #we replace the ipython default shell command caller by our shell handler
168 self._IP.set_hook('shell_hook',self._shell)
167 self._IP.set_hook('shell_hook',self._shell)
169 168
170 169 #we replace the ipython default input command caller by our method
171 170 IPython.iplib.raw_input_original = self._raw_input
@@ -300,10 +299,10 b' class NonBlockingIPShell(object):'
300 299 '''
301 300 history = ''
302 301 #the below while loop is used to suppress empty history lines
303 while((history == '' or history == '\n') and self._history_level >0):
304 if self._history_level>=1:
305 self._history_level -= 1
306 history = self._getHistory()
302 while((history == '' or history == '\n') and self._history_level >0):
303 if self._history_level>=1:
304 self._history_level -= 1
305 history = self._getHistory()
307 306 return history
308 307
309 308 def historyForward(self):
@@ -313,18 +312,18 b' class NonBlockingIPShell(object):'
313 312 @return: The command string.
314 313 @rtype: string
315 314 '''
316 history = ''
317 #the below while loop is used to suppress empty history lines
318 while((history == '' or history == '\n') and self._history_level <= self._getHistoryMaxIndex()):
319 if self._history_level < self._getHistoryMaxIndex():
320 self._history_level += 1
321 history = self._getHistory()
322 else:
323 if self._history_level == self._getHistoryMaxIndex():
324 history = self._getHistory()
325 self._history_level += 1
326 else:
327 history = ''
315 history = ''
316 #the below while loop is used to suppress empty history lines
317 while((history == '' or history == '\n') and self._history_level <= self._getHistoryMaxIndex()):
318 if self._history_level < self._getHistoryMaxIndex():
319 self._history_level += 1
320 history = self._getHistory()
321 else:
322 if self._history_level == self._getHistoryMaxIndex():
323 history = self._getHistory()
324 self._history_level += 1
325 else:
326 history = ''
328 327 return history
329 328
330 329 def initHistoryIndex(self):
@@ -70,8 +70,8 b' class IPythonHistoryPanel(wx.Panel):'
70 70 add = False
71 71 if self.filter_magic.GetValue() == True and history_line[0] == '%':
72 72 add = False
73 if add:
74 self.text_ctrl.AppendText(history_line+'\n')
73 if add:
74 self.text_ctrl.AppendText(history_line+'\n')
75 75
76 76
77 77 #----------------------------------------------------------------------
@@ -39,52 +39,37 b' try:'
39 39 except Exception,e:
40 40 raise "Error importing IPython (%s)" % str(e)
41 41
42
43 42 from ipshell_nonblocking import NonBlockingIPShell
44 43
44
45 45 class WxNonBlockingIPShell(NonBlockingIPShell):
46 46 '''
47 47 An NonBlockingIPShell Thread that is WX dependent.
48 Thus it permits direct interaction with a WX GUI without OnIdle event state machine trick...
49 48 '''
50 def __init__(self,wx_instance,
49 def __init__(self, parent,
51 50 argv=[],user_ns={},user_global_ns=None,
52 51 cin=None, cout=None, cerr=None,
53 52 ask_exit_handler=None):
54 53
55 #user_ns['addGUIShortcut'] = self.addGUIShortcut
56 54 NonBlockingIPShell.__init__(self,argv,user_ns,user_global_ns,
57 55 cin, cout, cerr,
58 56 ask_exit_handler)
59 57
60 # This creates a new Event class and a EVT binder function
61 (self.IPythonAskExitEvent, EVT_IP_ASK_EXIT) = wx.lib.newevent.NewEvent()
62 #(self.IPythonAddButtonEvent, EVT_IP_ADD_BUTTON_EXIT) = \
63 # wx.lib.newevent.NewEvent()
64 (self.IPythonExecuteDoneEvent, EVT_IP_EXECUTE_DONE) = \
65 wx.lib.newevent.NewEvent()
58 self.parent = parent
66 59
67 wx_instance.Bind(EVT_IP_ASK_EXIT, wx_instance.ask_exit_handler)
68 #wx_instance.Bind(EVT_IP_ADD_BUTTON_EXIT, wx_instance.add_button_handler)
69 wx_instance.Bind(EVT_IP_EXECUTE_DONE, wx_instance.evtStateExecuteDone)
70
71 self.wx_instance = wx_instance
72 self._IP.ask_exit = self._askExit
60 self.ask_exit_callback = ask_exit_handler
73 61 self._IP.exit = self._askExit
74
75 #def addGUIShortcut(self,text,func):
76 # evt = self.IPythonAddButtonEvent(
77 # button_info={ 'text':text,
78 # 'func':self.wx_instance.doExecuteLine(func)})
79 # wx.PostEvent(self.wx_instance, evt)
80
62
63 def addGUIShortcut(self,text,func):
64 wx.CallAfter(self.parent.add_button_handler,
65 button_info={ 'text':text,
66 'func':self.parent.doExecuteLine(func)})
67
81 68 def _askExit(self):
82 evt = self.IPythonAskExitEvent()
83 wx.PostEvent(self.wx_instance, evt)
69 wx.CallAfter(self.ask_exit_callback, ())
84 70
85 71 def _afterExecute(self):
86 evt = self.IPythonExecuteDoneEvent()
87 wx.PostEvent(self.wx_instance, evt)
72 wx.CallAfter(self.parent.evtStateExecuteDone, ())
88 73
89 74
90 75 class WxConsoleView(stc.StyledTextCtrl):
@@ -120,7 +105,8 b' class WxConsoleView(stc.StyledTextCtrl):'
120 105 '1;34': [12,'LIGHT BLUE'], '1;35': [13,'MEDIUM VIOLET RED'],
121 106 '1;36': [14,'LIGHT STEEL BLUE'], '1;37': [15,'YELLOW']}
122 107
123 def __init__(self,parent,prompt,intro="",background_color="BLACK",pos=wx.DefaultPosition, ID = -1, size=wx.DefaultSize,
108 def __init__(self,parent,prompt,intro="",background_color="BLACK",
109 pos=wx.DefaultPosition, ID = -1, size=wx.DefaultSize,
124 110 style=0):
125 111 '''
126 112 Initialize console view.
@@ -136,9 +122,10 b' class WxConsoleView(stc.StyledTextCtrl):'
136 122 '''
137 123 stc.StyledTextCtrl.__init__(self, parent, ID, pos, size, style)
138 124
139 ####### Scintilla configuration ##################################################
125 ####### Scintilla configuration ###################################
140 126
141 # Ctrl + B or Ctrl + N can be used to zoomin/zoomout the text inside the widget
127 # Ctrl + B or Ctrl + N can be used to zoomin/zoomout the text inside
128 # the widget
142 129 self.CmdKeyAssign(ord('B'), stc.STC_SCMOD_CTRL, stc.STC_CMD_ZOOMIN)
143 130 self.CmdKeyAssign(ord('N'), stc.STC_SCMOD_CTRL, stc.STC_CMD_ZOOMOUT)
144 131
@@ -200,12 +187,16 b' class WxConsoleView(stc.StyledTextCtrl):'
200 187 self.SetCaretForeground("WHITE")
201 188 self.ANSI_STYLES = self.ANSI_STYLES_BLACK
202 189
203 self.StyleSetSpec(stc.STC_STYLE_DEFAULT, "fore:%s,back:%s,size:%d,face:%s" % (self.ANSI_STYLES['0;30'][1],
204 self.background_color,
205 faces['size'], faces['mono']))
190 self.StyleSetSpec(stc.STC_STYLE_DEFAULT,
191 "fore:%s,back:%s,size:%d,face:%s"
192 % (self.ANSI_STYLES['0;30'][1],
193 self.background_color,
194 faces['size'], faces['mono']))
206 195 self.StyleClearAll()
207 self.StyleSetSpec(stc.STC_STYLE_BRACELIGHT, "fore:#FF0000,back:#0000FF,bold")
208 self.StyleSetSpec(stc.STC_STYLE_BRACEBAD, "fore:#000000,back:#FF0000,bold")
196 self.StyleSetSpec(stc.STC_STYLE_BRACELIGHT,
197 "fore:#FF0000,back:#0000FF,bold")
198 self.StyleSetSpec(stc.STC_STYLE_BRACEBAD,
199 "fore:#000000,back:#FF0000,bold")
209 200
210 201 for style in self.ANSI_STYLES.values():
211 202 self.StyleSetSpec(style[0], "bold,fore:%s" % style[1])
@@ -221,7 +212,6 b' class WxConsoleView(stc.StyledTextCtrl):'
221 212 self.showPrompt()
222 213
223 214 self.Bind(wx.EVT_KEY_DOWN, self._onKeypress, self)
224 #self.Bind(stc.EVT_STC_UPDATEUI, self.OnUpdateUI)
225 215
226 216 def write(self, text):
227 217 '''
@@ -389,7 +379,7 b' class WxConsoleView(stc.StyledTextCtrl):'
389 379 @return: Return True if event as been catched.
390 380 @rtype: boolean
391 381 '''
392
382
393 383 if event.GetKeyCode() == wx.WXK_HOME:
394 384 if event.Modifiers == wx.MOD_NONE:
395 385 self.moveCursorOnNewValidKey()
@@ -413,9 +403,9 b' class WxConsoleView(stc.StyledTextCtrl):'
413 403
414 404 elif event.GetKeyCode() == wx.WXK_BACK:
415 405 self.moveCursorOnNewValidKey()
416 if self.getCursorPos() > self.getCurrentPromptStart():
406 if self.getCursorPos() > self.getCurrentPromptStart():
417 407 self.removeFromTo(self.getCursorPos()-1,self.getCursorPos())
418 return True
408 return True
419 409
420 410 if skip:
421 411 if event.GetKeyCode() not in [wx.WXK_PAGEUP,wx.WXK_PAGEDOWN] and event.Modifiers == wx.MOD_NONE:
@@ -496,7 +486,8 b' class WxIPythonViewPanel(wx.Panel):'
496 486
497 487 ### IPython wx console view instanciation ###
498 488 #If user didn't defined an intro text, we create one for him
499 #If you really wnat an empty intrp just call wxIPythonViewPanel with intro=''
489 #If you really wnat an empty intrp just call wxIPythonViewPanel
490 #with intro=''
500 491 if intro == None:
501 492 welcome_text = "Welcome to WxIPython Shell.\n\n"
502 493 welcome_text+= self.IP.getBanner()
@@ -523,11 +514,11 b' class WxIPythonViewPanel(wx.Panel):'
523 514 #widget state management (for key handling different cases)
524 515 self.setCurrentState('IDLE')
525 516 self.pager_state = 'DONE'
526
517
527 518 def __del__(self):
528 519 WxConsoleView.__del__()
529 520
530 #---------------------------- IPython Thread Management ---------------------------------------
521 #---------------------- IPython Thread Management ------------------------
531 522 def stateDoExecuteLine(self):
532 523 #print >>sys.__stdout__,"command:",self.getCurrentLine()
533 524 line=self.text_ctrl.getCurrentLine()
@@ -609,20 +600,20 b' class WxIPythonViewPanel(wx.Panel):'
609 600
610 601 self.pager_index += 1
611 602 self.pager_nb_lines -= 1
612 if self.pager_nb_lines > 0:
613 for line in self.pager_lines[self.pager_index:]:
614 self.text_ctrl.write("\x01\x1b[1;36m\x02 "+line+'\n')
615 self.pager_nb_lines = 0
616 self.pager_state = 'DONE'
617 self.stateShowPrompt()
603 if self.pager_nb_lines > 0:
604 for line in self.pager_lines[self.pager_index:]:
605 self.text_ctrl.write("\x01\x1b[1;36m\x02 "+line+'\n')
606 self.pager_nb_lines = 0
607 self.pager_state = 'DONE'
608 self.stateShowPrompt()
618 609
619 #---------------------------- Key Handler --------------------------------------------
610 #------------------------ Key Handler ------------------------------------
620 611 def keyPress(self, event):
621 612 '''
622 613 Key press callback with plenty of shell goodness, like history,
623 614 autocompletions, etc.
624 615 '''
625
616
626 617 if event.GetKeyCode() == ord('C'):
627 618 if event.Modifiers == wx.MOD_CONTROL:
628 619 if self.cur_state == 'WAIT_END_OF_EXECUTION':
@@ -648,7 +639,7 b' class WxIPythonViewPanel(wx.Panel):'
648 639 return
649 640
650 641 #scroll_position = self.text_ctrl.GetScrollPos(wx.VERTICAL)
651 if self.cur_state == 'IDLE':
642 if self.cur_state == 'IDLE':
652 643 if event.KeyCode == wx.WXK_UP:
653 644 history = self.IP.historyBack()
654 645 self.text_ctrl.writeHistory(history)
@@ -675,8 +666,8 b' class WxIPythonViewPanel(wx.Panel):'
675 666
676 667 return
677 668 event.Skip()
678
679 #---------------------------- Hook Section --------------------------------------------
669
670 #------------------------ Hook Section -----------------------------------
680 671 def updateHistoryTracker(self,command_line):
681 672 '''
682 673 Default history tracker (does nothing)
@@ -688,6 +679,7 b' class WxIPythonViewPanel(wx.Panel):'
688 679 Define a new history tracker
689 680 '''
690 681 self.updateHistoryTracker = func
682
691 683 def updateStatusTracker(self,status):
692 684 '''
693 685 Default status tracker (does nothing)
@@ -50,7 +50,7 b' class MyFrame(wx.Frame):'
50 50 # main panels
51 51 self._mgr.AddPane(self.ipython_panel , wx.CENTER, "IPython Shell")
52 52 self._mgr.AddPane(self.history_panel , wx.RIGHT, "IPython history")
53
53
54 54 # now we specify some panel characteristics
55 55 self._mgr.GetPane(self.ipython_panel).CaptionVisible(True);
56 56 self._mgr.GetPane(self.history_panel).CaptionVisible(True);
General Comments 0
You need to be logged in to leave comments. Login now