Show More
@@ -50,30 +50,34 b' class WxNonBlockingIPShell(NonBlockingIPShell):' | |||||
50 | def __init__(self,wx_instance, |
|
50 | def __init__(self,wx_instance, | |
51 | argv=[],user_ns={},user_global_ns=None, |
|
51 | argv=[],user_ns={},user_global_ns=None, | |
52 | cin=None, cout=None, cerr=None, |
|
52 | cin=None, cout=None, cerr=None, | |
53 |
exit_handler=None |
|
53 | ask_exit_handler=None): | |
54 |
|
54 | |||
55 | user_ns['addGUIShortcut'] = self.addGUIShortcut |
|
55 | #user_ns['addGUIShortcut'] = self.addGUIShortcut | |
56 | NonBlockingIPShell.__init__(self,argv,user_ns,user_global_ns, |
|
56 | NonBlockingIPShell.__init__(self,argv,user_ns,user_global_ns, | |
57 | cin, cout, cerr, |
|
57 | cin, cout, cerr, | |
58 |
exit_handler |
|
58 | ask_exit_handler) | |
59 |
|
59 | |||
60 | # This creates a new Event class and a EVT binder function |
|
60 | # This creates a new Event class and a EVT binder function | |
61 | (self.IPythonAskExitEvent, EVT_IP_ASK_EXIT) = wx.lib.newevent.NewEvent() |
|
61 | (self.IPythonAskExitEvent, EVT_IP_ASK_EXIT) = wx.lib.newevent.NewEvent() | |
62 |
(self.IPythonAddButtonEvent, EVT_IP_ADD_BUTTON_EXIT) = |
|
62 | (self.IPythonAddButtonEvent, EVT_IP_ADD_BUTTON_EXIT) = \ | |
63 | (self.IPythonExecuteDoneEvent, EVT_IP_EXECUTE_DONE) = wx.lib.newevent.NewEvent() |
|
63 | wx.lib.newevent.NewEvent() | |
|
64 | (self.IPythonExecuteDoneEvent, EVT_IP_EXECUTE_DONE) = \ | |||
|
65 | wx.lib.newevent.NewEvent() | |||
64 |
|
66 | |||
65 | wx_instance.Bind(EVT_IP_ASK_EXIT, wx_instance.exit_handler) |
|
67 | wx_instance.Bind(EVT_IP_ASK_EXIT, wx_instance.ask_exit_handler) | |
66 | wx_instance.Bind(EVT_IP_ADD_BUTTON_EXIT, wx_instance.add_button_handler) |
|
68 | wx_instance.Bind(EVT_IP_ADD_BUTTON_EXIT, wx_instance.add_button_handler) | |
67 | wx_instance.Bind(EVT_IP_EXECUTE_DONE, wx_instance.evtStateExecuteDone) |
|
69 | wx_instance.Bind(EVT_IP_EXECUTE_DONE, wx_instance.evtStateExecuteDone) | |
68 |
|
70 | |||
69 | self.wx_instance = wx_instance |
|
71 | self.wx_instance = wx_instance | |
70 |
self._IP.exit = self._ |
|
72 | self._IP.ask_exit = self._askExit | |
71 |
|
73 | |||
72 | def addGUIShortcut(self,text,func): |
|
74 | def addGUIShortcut(self,text,func): | |
73 | evt = self.IPythonAddButtonEvent(button_info={'text':text,'func':self.wx_instance.doExecuteLine(func)}) |
|
75 | evt = self.IPythonAddButtonEvent( | |
|
76 | button_info={ 'text':text, | |||
|
77 | 'func':self.wx_instance.doExecuteLine(func)}) | |||
74 | wx.PostEvent(self.wx_instance, evt) |
|
78 | wx.PostEvent(self.wx_instance, evt) | |
75 |
|
79 | |||
76 |
def _ |
|
80 | def _askExit(self): | |
77 | evt = self.IPythonAskExitEvent() |
|
81 | evt = self.IPythonAskExitEvent() | |
78 | wx.PostEvent(self.wx_instance, evt) |
|
82 | wx.PostEvent(self.wx_instance, evt) | |
79 |
|
83 | |||
@@ -463,7 +467,8 b' class WxIPythonViewPanel(wx.Panel):' | |||||
463 | I've choosed to derivate from a wx.Panel because it seems to be ore usefull |
|
467 | I've choosed to derivate from a wx.Panel because it seems to be ore usefull | |
464 | Any idea to make it more 'genric' welcomed. |
|
468 | Any idea to make it more 'genric' welcomed. | |
465 | ''' |
|
469 | ''' | |
466 | def __init__(self, parent, exit_handler=None, intro=None, |
|
470 | ||
|
471 | def __init__(self, parent, ask_exit_handler=None, intro=None, | |||
467 | background_color="BLACK", add_button_handler=None, |
|
472 | background_color="BLACK", add_button_handler=None, | |
468 | wx_ip_shell=None, |
|
473 | wx_ip_shell=None, | |
469 | ): |
|
474 | ): | |
@@ -479,17 +484,14 b' class WxIPythonViewPanel(wx.Panel):' | |||||
479 | self.cout = StringIO() |
|
484 | self.cout = StringIO() | |
480 |
|
485 | |||
481 | self.add_button_handler = add_button_handler |
|
486 | self.add_button_handler = add_button_handler | |
482 | self.exit_handler = exit_handler |
|
487 | self.ask_exit_handler = ask_exit_handler | |
483 |
|
488 | |||
484 | if wx_ip_shell is not None: |
|
489 | if wx_ip_shell is not None: | |
485 | self.IP = wx_ip_shell |
|
490 | self.IP = wx_ip_shell | |
486 | else: |
|
491 | else: | |
487 | self.IP = WxNonBlockingIPShell(self, |
|
492 | self.IP = WxNonBlockingIPShell(self, | |
488 | cout=self.cout,cerr=self.cout, |
|
493 | cout=self.cout,cerr=self.cout, | |
489 |
exit_handler = exit_handler |
|
494 | ask_exit_handler = ask_exit_handler) | |
490 | time_loop = 0.1) |
|
|||
491 | self.IP.start() |
|
|||
492 |
|
||||
493 | ### IPython wx console view instanciation ### |
|
495 | ### IPython wx console view instanciation ### | |
494 | #If user didn't defined an intro text, we create one for him |
|
496 | #If user didn't defined an intro text, we create one for him | |
495 | #If you really wnat an empty intrp just call wxIPythonViewPanel with intro='' |
|
497 | #If you really wnat an empty intrp just call wxIPythonViewPanel with intro='' | |
@@ -541,8 +543,6 b' class WxIPythonViewPanel(wx.Panel):' | |||||
541 | #self.Bind(wx.EVT_IDLE, self.runStateMachine) |
|
543 | #self.Bind(wx.EVT_IDLE, self.runStateMachine) | |
542 |
|
544 | |||
543 | def __del__(self): |
|
545 | def __del__(self): | |
544 | self.IP.shutdown() |
|
|||
545 | self.IP.join() |
|
|||
546 | WxConsoleView.__del__() |
|
546 | WxConsoleView.__del__() | |
547 |
|
547 | |||
548 | #---------------------------- IPython Thread Management --------------------------------------- |
|
548 | #---------------------------- IPython Thread Management --------------------------------------- | |
@@ -705,7 +705,7 b' class WxIPythonViewPanel(wx.Panel):' | |||||
705 | if event.Modifiers == wx.MOD_CONTROL: |
|
705 | if event.Modifiers == wx.MOD_CONTROL: | |
706 | if self.cur_state == 'WAIT_END_OF_EXECUTION': |
|
706 | if self.cur_state == 'WAIT_END_OF_EXECUTION': | |
707 | #we raise an exception inside the IPython thread container |
|
707 | #we raise an exception inside the IPython thread container | |
708 | self.IP.raise_exc(KeyboardInterrupt) |
|
708 | self.IP.ce.raise_exc(KeyboardInterrupt) | |
709 | return |
|
709 | return | |
710 |
|
710 | |||
711 | if event.KeyCode == wx.WXK_RETURN: |
|
711 | if event.KeyCode == wx.WXK_RETURN: |
@@ -31,16 +31,19 b' try:' | |||||
31 | except Exception,e: |
|
31 | except Exception,e: | |
32 | raise "Error importing IPython (%s)" % str(e) |
|
32 | raise "Error importing IPython (%s)" % str(e) | |
33 |
|
33 | |||
|
34 | ############################################################################## | |||
34 | class _Helper(object): |
|
35 | class _Helper(object): | |
35 | """Redefine the built-in 'help'. |
|
36 | """Redefine the built-in 'help'. | |
36 | This is a wrapper around pydoc.help (with a twist). |
|
37 | This is a wrapper around pydoc.help (with a twist). | |
37 | """ |
|
38 | """ | |
|
39 | ||||
38 | def __init__(self,pager): |
|
40 | def __init__(self,pager): | |
39 | self._pager = pager |
|
41 | self._pager = pager | |
40 |
|
42 | |||
41 | def __repr__(self): |
|
43 | def __repr__(self): | |
42 | return "Type help() for interactive help, " \ |
|
44 | return "Type help() for interactive help, " \ | |
43 | "or help(object) for help about object." |
|
45 | "or help(object) for help about object." | |
|
46 | ||||
44 | def __call__(self, *args, **kwds): |
|
47 | def __call__(self, *args, **kwds): | |
45 | class DummyWriter(object): |
|
48 | class DummyWriter(object): | |
46 | def __init__(self,pager): |
|
49 | def __init__(self,pager): | |
@@ -57,20 +60,41 b' class _Helper(object):' | |||||
57 | return pydoc.help(*args, **kwds) |
|
60 | return pydoc.help(*args, **kwds) | |
58 |
|
61 | |||
59 |
|
62 | |||
60 | class NonBlockingIPShell(ThreadEx): |
|
63 | ############################################################################## | |
|
64 | class _CodeExecutor(ThreadEx): | |||
|
65 | ||||
|
66 | def __init__(self, instance, after): | |||
|
67 | ThreadEx.__init__(self) | |||
|
68 | self.instance = instance | |||
|
69 | self._afterExecute=after | |||
|
70 | ||||
|
71 | def run(self): | |||
|
72 | try: | |||
|
73 | self.instance._doc_text = None | |||
|
74 | self.instance._help_text = None | |||
|
75 | self.instance._execute() | |||
|
76 | # used for uper class to generate event after execution | |||
|
77 | self._afterExecute() | |||
|
78 | ||||
|
79 | except KeyboardInterrupt: | |||
|
80 | pass | |||
|
81 | ||||
|
82 | ||||
|
83 | ############################################################################## | |||
|
84 | class NonBlockingIPShell(object): | |||
61 | ''' |
|
85 | ''' | |
62 |
Create an IPython instance |
|
86 | Create an IPython instance, running the commands in a separate, | |
63 | Does not start a blocking event loop, instead allow single iterations. |
|
87 | non-blocking thread. | |
64 | This allows embedding in any GUI without blockage. |
|
88 | This allows embedding in any GUI without blockage. | |
65 | The thread is a slave one, in that it doesn't interact directly with the GUI. |
|
89 | ||
66 | Note ThreadEx class supports asynchroneous function call |
|
90 | Note: The ThreadEx class supports asynchroneous function call | |
67 | via raise_exc() |
|
91 | via raise_exc() | |
68 | ''' |
|
92 | ''' | |
69 |
|
93 | |||
70 | def __init__(self,argv |
|
94 | def __init__(self,argv | |
71 | =[],user_ns={},user_global_ns=None, |
|
95 | =[],user_ns={},user_global_ns=None, | |
72 | cin=None, cout=None, cerr=None, |
|
96 | cin=None, cout=None, cerr=None, | |
73 |
exit_handler=None |
|
97 | ask_exit_handler=None): | |
74 | ''' |
|
98 | ''' | |
75 | @param argv: Command line options for IPython |
|
99 | @param argv: Command line options for IPython | |
76 | @type argv: list |
|
100 | @type argv: list | |
@@ -89,8 +113,6 b' class NonBlockingIPShell(ThreadEx):' | |||||
89 | @param time_loop: Define the sleep time between two thread's loop |
|
113 | @param time_loop: Define the sleep time between two thread's loop | |
90 | @type int |
|
114 | @type int | |
91 | ''' |
|
115 | ''' | |
92 | ThreadEx.__init__(self) |
|
|||
93 |
|
||||
94 | #first we redefine in/out/error functions of IPython |
|
116 | #first we redefine in/out/error functions of IPython | |
95 | if cin: |
|
117 | if cin: | |
96 | IPython.Shell.Term.cin = cin |
|
118 | IPython.Shell.Term.cin = cin | |
@@ -127,7 +149,11 b' class NonBlockingIPShell(ThreadEx):' | |||||
127 | IPython.iplib.raw_input_original = self._raw_input |
|
149 | IPython.iplib.raw_input_original = self._raw_input | |
128 | #we replace the ipython default exit command by our method |
|
150 | #we replace the ipython default exit command by our method | |
129 | self._IP.exit = self._setAskExit |
|
151 | self._IP.exit = self._setAskExit | |
130 |
|
152 | #we modify Exit and Quit Magic | ||
|
153 | ip = IPython.ipapi.get() | |||
|
154 | ip.expose_magic('Exit', self._setDoExit) | |||
|
155 | ip.expose_magic('Quit', self._setDoExit) | |||
|
156 | ||||
131 | sys.excepthook = excepthook |
|
157 | sys.excepthook = excepthook | |
132 |
|
158 | |||
133 | self._iter_more = 0 |
|
159 | self._iter_more = 0 | |
@@ -136,9 +162,6 b' class NonBlockingIPShell(ThreadEx):' | |||||
136 | self._prompt = str(self._IP.outputcache.prompt1).strip() |
|
162 | self._prompt = str(self._IP.outputcache.prompt1).strip() | |
137 |
|
163 | |||
138 | #thread working vars |
|
164 | #thread working vars | |
139 | self._terminate = False |
|
|||
140 | self._time_loop = time_loop |
|
|||
141 | self._do_execute = False |
|
|||
142 | self._line_to_execute = '' |
|
165 | self._line_to_execute = '' | |
143 |
|
166 | |||
144 | #vars that will be checked by GUI loop to handle thread states... |
|
167 | #vars that will be checked by GUI loop to handle thread states... | |
@@ -152,46 +175,16 b' class NonBlockingIPShell(ThreadEx):' | |||||
152 | self._IP.user_ns['help'] = _Helper(self._pager_help) |
|
175 | self._IP.user_ns['help'] = _Helper(self._pager_help) | |
153 |
|
176 | |||
154 | #----------------------- Thread management section ---------------------- |
|
177 | #----------------------- Thread management section ---------------------- | |
155 | def run (self): |
|
|||
156 | """ |
|
|||
157 | Thread main loop |
|
|||
158 | The thread will run until self._terminate will be set to True via shutdown() function |
|
|||
159 | Command processing can be interrupted with Instance.raise_exc(KeyboardInterrupt) call in the |
|
|||
160 | GUI thread. |
|
|||
161 | """ |
|
|||
162 | while(not self._terminate): |
|
|||
163 | try: |
|
|||
164 | if self._do_execute: |
|
|||
165 | self._doc_text = None |
|
|||
166 | self._help_text = None |
|
|||
167 | self._execute() |
|
|||
168 | self._do_execute = False |
|
|||
169 | self._afterExecute() #used for uper class to generate event after execution |
|
|||
170 |
|
||||
171 | except KeyboardInterrupt: |
|
|||
172 | pass |
|
|||
173 |
|
||||
174 | time.sleep(self._time_loop) |
|
|||
175 |
|
||||
176 | def shutdown(self): |
|
|||
177 | """ |
|
|||
178 | Shutdown the tread |
|
|||
179 | """ |
|
|||
180 | self._terminate = True |
|
|||
181 |
|
||||
182 | def doExecute(self,line): |
|
178 | def doExecute(self,line): | |
183 | """ |
|
179 | """ | |
184 | Tell the thread to process the 'line' command |
|
180 | Tell the thread to process the 'line' command | |
185 | """ |
|
181 | """ | |
186 | self._do_execute = True |
|
182 | ||
187 | self._line_to_execute = line |
|
183 | self._line_to_execute = line | |
|
184 | ||||
|
185 | self.ce = _CodeExecutor(self,self._afterExecute) | |||
|
186 | self.ce.start() | |||
188 |
|
187 | |||
189 | def isExecuteDone(self): |
|
|||
190 | """ |
|
|||
191 | Returns the processing state |
|
|||
192 | """ |
|
|||
193 | return not self._do_execute |
|
|||
194 |
|
||||
195 | #----------------------- IPython management section ---------------------- |
|
188 | #----------------------- IPython management section ---------------------- | |
196 | def getAskExit(self): |
|
189 | def getAskExit(self): | |
197 | ''' |
|
190 | ''' | |
@@ -351,7 +344,7 b' class NonBlockingIPShell(ThreadEx):' | |||||
351 | ''' |
|
344 | ''' | |
352 | self._history_level = self._getHistoryMaxIndex()+1 |
|
345 | self._history_level = self._getHistoryMaxIndex()+1 | |
353 |
|
346 | |||
354 |
#----------------------- IPython PRIVATE management section -------------- |
|
347 | #----------------------- IPython PRIVATE management section -------------- | |
355 | def _afterExecute(self): |
|
348 | def _afterExecute(self): | |
356 | ''' |
|
349 | ''' | |
357 | Can be redefined to generate post event after excution is done |
|
350 | Can be redefined to generate post event after excution is done | |
@@ -360,10 +353,17 b' class NonBlockingIPShell(ThreadEx):' | |||||
360 |
|
353 | |||
361 | def _setAskExit(self): |
|
354 | def _setAskExit(self): | |
362 | ''' |
|
355 | ''' | |
363 |
set the _ask_exit variable that can be c |
|
356 | set the _ask_exit variable that can be checked by GUI to see if | |
364 | IPython request an exit handling |
|
357 | IPython request an exit handling | |
365 | ''' |
|
358 | ''' | |
366 | self._ask_exit = True |
|
359 | self._ask_exit = True | |
|
360 | ||||
|
361 | def _setDoExit(self, toto, arg): | |||
|
362 | ''' | |||
|
363 | set the _do_exit variable that can be checked by GUI to see if | |||
|
364 | IPython do a direct exit of the app | |||
|
365 | ''' | |||
|
366 | self._do_exit = True | |||
367 |
|
367 | |||
368 | def _getHistoryMaxIndex(self): |
|
368 | def _getHistoryMaxIndex(self): | |
369 | ''' |
|
369 | ''' | |
@@ -378,7 +378,7 b' class NonBlockingIPShell(ThreadEx):' | |||||
378 | ''' |
|
378 | ''' | |
379 | Get's the command string of the current history level. |
|
379 | Get's the command string of the current history level. | |
380 |
|
380 | |||
381 |
@return: Historic command stri |
|
381 | @return: Historic command stri | |
382 | @rtype: string |
|
382 | @rtype: string | |
383 | ''' |
|
383 | ''' | |
384 | rv = self._IP.input_hist_raw[self._history_level].strip('\n') |
|
384 | rv = self._IP.input_hist_raw[self._history_level].strip('\n') |
General Comments 0
You need to be logged in to leave comments.
Login now