Show More
@@ -55,9 +55,8 b' class _Helper(object):' | |||||
55 |
|
55 | |||
56 | #helper.output.write = self.doc.append |
|
56 | #helper.output.write = self.doc.append | |
57 | return pydoc.help(*args, **kwds) |
|
57 | return pydoc.help(*args, **kwds) | |
58 |
|
58 | |||
59 |
|
59 | class IterableIPShell(object): | ||
60 | class IterableIPShell(Thread): |
|
|||
61 | ''' |
|
60 | ''' | |
62 | Create an IPython instance inside a dedicated thread. |
|
61 | Create an IPython instance inside a dedicated thread. | |
63 | Does not start a blocking event loop, instead allow single iterations. |
|
62 | Does not start a blocking event loop, instead allow single iterations. | |
@@ -70,7 +69,7 b' class IterableIPShell(Thread):' | |||||
70 | def __init__(self,argv |
|
69 | def __init__(self,argv | |
71 | =[],user_ns={},user_global_ns=None, |
|
70 | =[],user_ns={},user_global_ns=None, | |
72 | cin=None, cout=None, cerr=None, |
|
71 | cin=None, cout=None, cerr=None, | |
73 | exit_handler=None,time_loop = 0.1): |
|
72 | ask_exit_handler=None, do_exit_handler=None, time_loop = 0.1): | |
74 | ''' |
|
73 | ''' | |
75 | @param argv: Command line options for IPython |
|
74 | @param argv: Command line options for IPython | |
76 | @type argv: list |
|
75 | @type argv: list | |
@@ -89,7 +88,6 b' class IterableIPShell(Thread):' | |||||
89 | @param time_loop: Define the sleep time between two thread's loop |
|
88 | @param time_loop: Define the sleep time between two thread's loop | |
90 | @type int |
|
89 | @type int | |
91 | ''' |
|
90 | ''' | |
92 | Thread.__init__(self) |
|
|||
93 |
|
91 | |||
94 | #first we redefine in/out/error functions of IPython |
|
92 | #first we redefine in/out/error functions of IPython | |
95 | if cin: |
|
93 | if cin: | |
@@ -127,7 +125,11 b' class IterableIPShell(Thread):' | |||||
127 | IPython.iplib.raw_input_original = self._raw_input |
|
125 | IPython.iplib.raw_input_original = self._raw_input | |
128 | #we replace the ipython default exit command by our method |
|
126 | #we replace the ipython default exit command by our method | |
129 | self._IP.exit = self._setAskExit |
|
127 | self._IP.exit = self._setAskExit | |
130 |
|
128 | #we modify Exit and Quit Magic | ||
|
129 | ip = IPython.ipapi.get() | |||
|
130 | ip.expose_magic('Exit', self._setDoExit) | |||
|
131 | ip.expose_magic('Quit', self._setDoExit) | |||
|
132 | ||||
131 | sys.excepthook = excepthook |
|
133 | sys.excepthook = excepthook | |
132 |
|
134 | |||
133 | self._iter_more = 0 |
|
135 | self._iter_more = 0 | |
@@ -136,9 +138,6 b' class IterableIPShell(Thread):' | |||||
136 | self._prompt = str(self._IP.outputcache.prompt1).strip() |
|
138 | self._prompt = str(self._IP.outputcache.prompt1).strip() | |
137 |
|
139 | |||
138 | #thread working vars |
|
140 | #thread working vars | |
139 | self._terminate = False |
|
|||
140 | self._time_loop = time_loop |
|
|||
141 | self._do_execute = False |
|
|||
142 | self._line_to_execute = '' |
|
141 | self._line_to_execute = '' | |
143 |
|
142 | |||
144 | #vars that will be checked by GUI loop to handle thread states... |
|
143 | #vars that will be checked by GUI loop to handle thread states... | |
@@ -152,46 +151,30 b' class IterableIPShell(Thread):' | |||||
152 | self._IP.user_ns['help'] = _Helper(self._pager_help) |
|
151 | self._IP.user_ns['help'] = _Helper(self._pager_help) | |
153 |
|
152 | |||
154 | #----------------------- Thread management section ---------------------- |
|
153 | #----------------------- 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): |
|
154 | def doExecute(self,line): | |
183 | """ |
|
155 | """ | |
184 | Tell the thread to process the 'line' command |
|
156 | Tell the thread to process the 'line' command | |
185 | """ |
|
157 | """ | |
186 | self._do_execute = True |
|
158 | ||
187 | self._line_to_execute = line |
|
159 | self._line_to_execute = line | |
|
160 | class CodeExecutor(Thread): | |||
|
161 | def __init__(self,instance,after): | |||
|
162 | Thread.__init__(self) | |||
|
163 | self.instance = instance | |||
|
164 | self._afterExecute=after | |||
|
165 | def run(self): | |||
|
166 | try: | |||
|
167 | self.instance._doc_text = None | |||
|
168 | self.instance._help_text = None | |||
|
169 | self.instance._execute() | |||
|
170 | self._afterExecute() #used for uper class to generate event after execution | |||
|
171 | ||||
|
172 | except KeyboardInterrupt: | |||
|
173 | pass | |||
|
174 | ||||
|
175 | self.ce = CodeExecutor(self,self._afterExecute) | |||
|
176 | self.ce.start() | |||
188 |
|
177 | |||
189 | def isExecuteDone(self): |
|
|||
190 | """ |
|
|||
191 | Returns the processing state |
|
|||
192 | """ |
|
|||
193 | return not self._do_execute |
|
|||
194 |
|
||||
195 | #----------------------- IPython management section ---------------------- |
|
178 | #----------------------- IPython management section ---------------------- | |
196 | def getAskExit(self): |
|
179 | def getAskExit(self): | |
197 | ''' |
|
180 | ''' | |
@@ -360,10 +343,17 b' class IterableIPShell(Thread):' | |||||
360 |
|
343 | |||
361 | def _setAskExit(self): |
|
344 | def _setAskExit(self): | |
362 | ''' |
|
345 | ''' | |
363 |
set the _ask_exit variable that can be c |
|
346 | set the _ask_exit variable that can be checked by GUI to see if | |
364 | IPython request an exit handling |
|
347 | IPython request an exit handling | |
365 | ''' |
|
348 | ''' | |
366 | self._ask_exit = True |
|
349 | self._ask_exit = True | |
|
350 | ||||
|
351 | def _setDoExit(self, toto, arg): | |||
|
352 | ''' | |||
|
353 | set the _do_exit variable that can be checked by GUI to see if | |||
|
354 | IPython do a direct exit of the app | |||
|
355 | ''' | |||
|
356 | self._do_exit = True | |||
367 |
|
357 | |||
368 | def _getHistoryMaxIndex(self): |
|
358 | def _getHistoryMaxIndex(self): | |
369 | ''' |
|
359 | ''' | |
@@ -378,7 +368,7 b' class IterableIPShell(Thread):' | |||||
378 | ''' |
|
368 | ''' | |
379 | Get's the command string of the current history level. |
|
369 | Get's the command string of the current history level. | |
380 |
|
370 | |||
381 |
@return: Historic command stri |
|
371 | @return: Historic command stri | |
382 | @rtype: string |
|
372 | @rtype: string | |
383 | ''' |
|
373 | ''' | |
384 | rv = self._IP.input_hist_raw[self._history_level].strip('\n') |
|
374 | rv = self._IP.input_hist_raw[self._history_level].strip('\n') |
@@ -51,24 +51,27 b' class WxIterableIPShell(IterableIPShell):' | |||||
51 | def __init__(self,wx_instance, |
|
51 | def __init__(self,wx_instance, | |
52 | argv=[],user_ns={},user_global_ns=None, |
|
52 | argv=[],user_ns={},user_global_ns=None, | |
53 | cin=None, cout=None, cerr=None, |
|
53 | cin=None, cout=None, cerr=None, | |
54 | exit_handler=None,time_loop = 0.1): |
|
54 | ask_exit_handler=None,do_exit_handler=None,time_loop = 0.1): | |
55 |
|
55 | |||
56 | user_ns['addGUIShortcut'] = self.addGUIShortcut |
|
56 | #user_ns['addGUIShortcut'] = self.addGUIShortcut | |
57 | IterableIPShell.__init__(self,argv,user_ns,user_global_ns, |
|
57 | IterableIPShell.__init__(self,argv,user_ns,user_global_ns, | |
58 | cin, cout, cerr, |
|
58 | cin, cout, cerr, | |
59 | exit_handler,time_loop) |
|
59 | ask_exit_handler, do_exit_handler, time_loop) | |
60 |
|
60 | |||
61 | # This creates a new Event class and a EVT binder function |
|
61 | # This creates a new Event class and a EVT binder function | |
62 | (self.IPythonAskExitEvent, EVT_IP_ASK_EXIT) = wx.lib.newevent.NewEvent() |
|
62 | (self.IPythonAskExitEvent, EVT_IP_ASK_EXIT) = wx.lib.newevent.NewEvent() | |
|
63 | (self.IPythonDoExitEvent, EVT_IP_DO_EXIT) = wx.lib.newevent.NewEvent() | |||
63 | (self.IPythonAddButtonEvent, EVT_IP_ADD_BUTTON_EXIT) = wx.lib.newevent.NewEvent() |
|
64 | (self.IPythonAddButtonEvent, EVT_IP_ADD_BUTTON_EXIT) = wx.lib.newevent.NewEvent() | |
64 | (self.IPythonExecuteDoneEvent, EVT_IP_EXECUTE_DONE) = wx.lib.newevent.NewEvent() |
|
65 | (self.IPythonExecuteDoneEvent, EVT_IP_EXECUTE_DONE) = wx.lib.newevent.NewEvent() | |
65 |
|
66 | |||
66 | wx_instance.Bind(EVT_IP_ASK_EXIT, wx_instance.exit_handler) |
|
67 | wx_instance.Bind(EVT_IP_ASK_EXIT, wx_instance.ask_exit_handler) | |
|
68 | wx_instance.Bind(EVT_IP_DO_EXIT, wx_instance.do_exit_handler) | |||
67 | wx_instance.Bind(EVT_IP_ADD_BUTTON_EXIT, wx_instance.add_button_handler) |
|
69 | wx_instance.Bind(EVT_IP_ADD_BUTTON_EXIT, wx_instance.add_button_handler) | |
68 | wx_instance.Bind(EVT_IP_EXECUTE_DONE, wx_instance.evtStateExecuteDone) |
|
70 | wx_instance.Bind(EVT_IP_EXECUTE_DONE, wx_instance.evtStateExecuteDone) | |
69 |
|
71 | |||
70 | self.wx_instance = wx_instance |
|
72 | self.wx_instance = wx_instance | |
71 | self._IP.exit = self._AskExit |
|
73 | self._IP.ask_exit = self._AskExit | |
|
74 | self._IP.do_exit = self._DoExit | |||
72 |
|
75 | |||
73 | def addGUIShortcut(self,text,func): |
|
76 | def addGUIShortcut(self,text,func): | |
74 | evt = self.IPythonAddButtonEvent(button_info={'text':text,'func':self.wx_instance.doExecuteLine(func)}) |
|
77 | evt = self.IPythonAddButtonEvent(button_info={'text':text,'func':self.wx_instance.doExecuteLine(func)}) | |
@@ -78,6 +81,10 b' class WxIterableIPShell(IterableIPShell):' | |||||
78 | evt = self.IPythonAskExitEvent() |
|
81 | evt = self.IPythonAskExitEvent() | |
79 | wx.PostEvent(self.wx_instance, evt) |
|
82 | wx.PostEvent(self.wx_instance, evt) | |
80 |
|
83 | |||
|
84 | def _DoExit(self): | |||
|
85 | evt = self.IPythonDoExitEvent() | |||
|
86 | wx.PostEvent(self.wx_instance, evt) | |||
|
87 | ||||
81 | def _afterExecute(self): |
|
88 | def _afterExecute(self): | |
82 | evt = self.IPythonExecuteDoneEvent() |
|
89 | evt = self.IPythonExecuteDoneEvent() | |
83 | wx.PostEvent(self.wx_instance, evt) |
|
90 | wx.PostEvent(self.wx_instance, evt) | |
@@ -464,7 +471,7 b' class WxIPythonViewPanel(wx.Panel):' | |||||
464 | I've choosed to derivate from a wx.Panel because it seems to be ore usefull |
|
471 | I've choosed to derivate from a wx.Panel because it seems to be ore usefull | |
465 | Any idea to make it more 'genric' welcomed. |
|
472 | Any idea to make it more 'genric' welcomed. | |
466 | ''' |
|
473 | ''' | |
467 | def __init__(self,parent,exit_handler=None,intro=None, |
|
474 | def __init__(self,parent,ask_exit_handler=None,do_exit_handler=None,intro=None, | |
468 | background_color="BLACK",add_button_handler=None): |
|
475 | background_color="BLACK",add_button_handler=None): | |
469 | ''' |
|
476 | ''' | |
470 | Initialize. |
|
477 | Initialize. | |
@@ -478,14 +485,14 b' class WxIPythonViewPanel(wx.Panel):' | |||||
478 | self.cout = StringIO() |
|
485 | self.cout = StringIO() | |
479 |
|
486 | |||
480 | self.add_button_handler = add_button_handler |
|
487 | self.add_button_handler = add_button_handler | |
481 | self.exit_handler = exit_handler |
|
488 | self.ask_exit_handler = ask_exit_handler | |
|
489 | self.do_exit_handler = do_exit_handler | |||
482 |
|
490 | |||
483 | self.IP = WxIterableIPShell(self, |
|
491 | self.IP = WxIterableIPShell(self, | |
484 | cout=self.cout,cerr=self.cout, |
|
492 | cout=self.cout,cerr=self.cout, | |
485 | exit_handler = exit_handler, |
|
493 | ask_exit_handler = ask_exit_handler, | |
|
494 | do_exit_handler = do_exit_handler, | |||
486 | time_loop = 0.1) |
|
495 | time_loop = 0.1) | |
487 | self.IP.start() |
|
|||
488 |
|
||||
489 | ### IPython wx console view instanciation ### |
|
496 | ### IPython wx console view instanciation ### | |
490 | #If user didn't defined an intro text, we create one for him |
|
497 | #If user didn't defined an intro text, we create one for him | |
491 | #If you really wnat an empty intrp just call wxIPythonViewPanel with intro='' |
|
498 | #If you really wnat an empty intrp just call wxIPythonViewPanel with intro='' | |
@@ -537,8 +544,6 b' class WxIPythonViewPanel(wx.Panel):' | |||||
537 | #self.Bind(wx.EVT_IDLE, self.runStateMachine) |
|
544 | #self.Bind(wx.EVT_IDLE, self.runStateMachine) | |
538 |
|
545 | |||
539 | def __del__(self): |
|
546 | def __del__(self): | |
540 | self.IP.shutdown() |
|
|||
541 | self.IP.join() |
|
|||
542 | WxConsoleView.__del__() |
|
547 | WxConsoleView.__del__() | |
543 |
|
548 | |||
544 | #---------------------------- IPython Thread Management --------------------------------------- |
|
549 | #---------------------------- IPython Thread Management --------------------------------------- | |
@@ -701,7 +706,7 b' class WxIPythonViewPanel(wx.Panel):' | |||||
701 | if event.Modifiers == wx.MOD_CONTROL: |
|
706 | if event.Modifiers == wx.MOD_CONTROL: | |
702 | if self.cur_state == 'WAIT_END_OF_EXECUTION': |
|
707 | if self.cur_state == 'WAIT_END_OF_EXECUTION': | |
703 | #we raise an exception inside the IPython thread container |
|
708 | #we raise an exception inside the IPython thread container | |
704 | self.IP.raise_exc(KeyboardInterrupt) |
|
709 | self.IP.ce.raise_exc(KeyboardInterrupt) | |
705 | return |
|
710 | return | |
706 |
|
711 | |||
707 | if event.KeyCode == wx.WXK_RETURN: |
|
712 | if event.KeyCode == wx.WXK_RETURN: |
General Comments 0
You need to be logged in to leave comments.
Login now