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