##// END OF EJS Templates
Merging Laurent's WX branch, reviewed by Gael....
Fernando Perez -
r1862:321357e1 merge
parent child Browse files
Show More
@@ -62,10 +62,9 class _Helper(object):
62 ##############################################################################
62 ##############################################################################
63 class _CodeExecutor(ThreadEx):
63 class _CodeExecutor(ThreadEx):
64 ''' Thread that execute ipython code '''
64 ''' Thread that execute ipython code '''
65 def __init__(self, instance, after):
65 def __init__(self, instance):
66 ThreadEx.__init__(self)
66 ThreadEx.__init__(self)
67 self.instance = instance
67 self.instance = instance
68 self._afterExecute = after
69
68
70 def run(self):
69 def run(self):
71 '''Thread main loop'''
70 '''Thread main loop'''
@@ -74,7 +73,7 class _CodeExecutor(ThreadEx):
74 self.instance._help_text = None
73 self.instance._help_text = None
75 self.instance._execute()
74 self.instance._execute()
76 # used for uper class to generate event after execution
75 # used for uper class to generate event after execution
77 self._afterExecute()
76 self.instance._after_execute()
78
77
79 except KeyboardInterrupt:
78 except KeyboardInterrupt:
80 pass
79 pass
@@ -114,8 +113,7 class NonBlockingIPShell(object):
114 '''
113 '''
115 #ipython0 initialisation
114 #ipython0 initialisation
116 self._IP = None
115 self._IP = None
117 self._term = None
116 self.init_ipython0(argv, user_ns, user_global_ns,
118 self.initIpython0(argv, user_ns, user_global_ns,
119 cin, cout, cerr,
117 cin, cout, cerr,
120 ask_exit_handler)
118 ask_exit_handler)
121
119
@@ -127,6 +125,7 class NonBlockingIPShell(object):
127
125
128 #thread working vars
126 #thread working vars
129 self._line_to_execute = ''
127 self._line_to_execute = ''
128 self._threading = True
130
129
131 #vars that will be checked by GUI loop to handle thread states...
130 #vars that will be checked by GUI loop to handle thread states...
132 #will be replaced later by PostEvent GUI funtions...
131 #will be replaced later by PostEvent GUI funtions...
@@ -134,26 +133,24 class NonBlockingIPShell(object):
134 self._help_text = None
133 self._help_text = None
135 self._add_button = None
134 self._add_button = None
136
135
137 def initIpython0(self, argv=[], user_ns={}, user_global_ns=None,
136 def init_ipython0(self, argv=[], user_ns={}, user_global_ns=None,
138 cin=None, cout=None, cerr=None,
137 cin=None, cout=None, cerr=None,
139 ask_exit_handler=None):
138 ask_exit_handler=None):
140 ''' Initialize an ithon0 instance '''
139 ''' Initialize an ipython0 instance '''
141
140
142 #first we redefine in/out/error functions of IPython
141 #first we redefine in/out/error functions of IPython
142 #BUG: we've got a limitation form ipython0 there
143 #only one instance can be instanciated else tehre will be
144 #cin/cout/cerr clash...
143 if cin:
145 if cin:
144 IPython.Shell.Term.cin = cin
146 IPython.genutils.Term.cin = cin
145 if cout:
147 if cout:
146 IPython.Shell.Term.cout = cout
148 IPython.genutils.Term.cout = cout
147 if cerr:
149 if cerr:
148 IPython.Shell.Term.cerr = cerr
150 IPython.genutils.Term.cerr = cerr
149
150 # This is to get rid of the blockage that accurs during
151 # IPython.Shell.InteractiveShell.user_setup()
152 IPython.iplib.raw_input = lambda x: None
153
154 self._term = IPython.genutils.IOTerm(cin=cin, cout=cout, cerr=cerr)
155
151
156 excepthook = sys.excepthook
152 excepthook = sys.excepthook
153
157 #Hack to save sys.displayhook, because ipython seems to overwrite it...
154 #Hack to save sys.displayhook, because ipython seems to overwrite it...
158 self.sys_displayhook_ori = sys.displayhook
155 self.sys_displayhook_ori = sys.displayhook
159
156
@@ -163,7 +160,8 class NonBlockingIPShell(object):
163 embedded=True,
160 embedded=True,
164 shell_class=IPython.Shell.InteractiveShell)
161 shell_class=IPython.Shell.InteractiveShell)
165
162
166 #we restore sys.displayhook
163 #we save ipython0 displayhook and we restore sys.displayhook
164 self.displayhook = sys.displayhook
167 sys.displayhook = self.sys_displayhook_ori
165 sys.displayhook = self.sys_displayhook_ori
168
166
169 #we replace IPython default encoding by wx locale encoding
167 #we replace IPython default encoding by wx locale encoding
@@ -173,11 +171,12 class NonBlockingIPShell(object):
173 #we replace the ipython default pager by our pager
171 #we replace the ipython default pager by our pager
174 self._IP.set_hook('show_in_pager', self._pager)
172 self._IP.set_hook('show_in_pager', self._pager)
175
173
176 #we replace the ipython default shell command caller by our shell handler
174 #we replace the ipython default shell command caller
175 #by our shell handler
177 self._IP.set_hook('shell_hook', self._shell)
176 self._IP.set_hook('shell_hook', self._shell)
178
177
179 #we replace the ipython default input command caller by our method
178 #we replace the ipython default input command caller by our method
180 IPython.iplib.raw_input_original = self._raw_input
179 IPython.iplib.raw_input_original = self._raw_input_original
181 #we replace the ipython default exit command by our method
180 #we replace the ipython default exit command by our method
182 self._IP.exit = ask_exit_handler
181 self._IP.exit = ask_exit_handler
183 #we replace the help command
182 #we replace the help command
@@ -186,26 +185,68 class NonBlockingIPShell(object):
186 #we disable cpase magic... until we found a way to use it properly.
185 #we disable cpase magic... until we found a way to use it properly.
187 #import IPython.ipapi
186 #import IPython.ipapi
188 ip = IPython.ipapi.get()
187 ip = IPython.ipapi.get()
189 def bypassMagic(self, arg):
188 def bypass_magic(self, arg):
190 print '%this magic is currently disabled.'
189 print '%this magic is currently disabled.'
191 ip.expose_magic('cpaste', bypassMagic)
190 ip.expose_magic('cpaste', bypass_magic)
191
192 import __builtin__
193 __builtin__.raw_input = self._raw_input
192
194
193 sys.excepthook = excepthook
195 sys.excepthook = excepthook
194
196
195 #----------------------- Thread management section ----------------------
197 #----------------------- Thread management section ----------------------
196 def doExecute(self, line):
198 def do_execute(self, line):
197 """
199 """
198 Tell the thread to process the 'line' command
200 Tell the thread to process the 'line' command
199 """
201 """
200
202
201 self._line_to_execute = line
203 self._line_to_execute = line
202 #we launch the ipython line execution in a thread to make it interruptible
204
203 #with include it in self namespace to be able to call ce.raise_exc(KeyboardInterrupt)
205 if self._threading:
204 self.ce = _CodeExecutor(self, self._afterExecute)
206 #we launch the ipython line execution in a thread to make it
207 #interruptible with include it in self namespace to be able
208 #to call ce.raise_exc(KeyboardInterrupt)
209 self.ce = _CodeExecutor(self)
205 self.ce.start()
210 self.ce.start()
211 else:
212 try:
213 self._doc_text = None
214 self._help_text = None
215 self._execute()
216 # used for uper class to generate event after execution
217 self._after_execute()
218
219 except KeyboardInterrupt:
220 pass
206
221
207 #----------------------- IPython management section ----------------------
222 #----------------------- IPython management section ----------------------
208 def getDocText(self):
223 def get_threading(self):
224 """
225 Returns threading status, is set to True, then each command sent to
226 the interpreter will be executed in a separated thread allowing,
227 for example, breaking a long running commands.
228 Disallowing it, permits better compatibilty with instance that is embedding
229 IPython instance.
230
231 @return: Execution method
232 @rtype: bool
233 """
234 return self._threading
235
236 def set_threading(self, state):
237 """
238 Sets threading state, if set to True, then each command sent to
239 the interpreter will be executed in a separated thread allowing,
240 for example, breaking a long running commands.
241 Disallowing it, permits better compatibilty with instance that is embedding
242 IPython instance.
243
244 @param state: Sets threading state
245 @type bool
246 """
247 self._threading = state
248
249 def get_doc_text(self):
209 """
250 """
210 Returns the output of the processing that need to be paged (if any)
251 Returns the output of the processing that need to be paged (if any)
211
252
@@ -214,7 +255,7 class NonBlockingIPShell(object):
214 """
255 """
215 return self._doc_text
256 return self._doc_text
216
257
217 def getHelpText(self):
258 def get_help_text(self):
218 """
259 """
219 Returns the output of the processing that need to be paged via help pager(if any)
260 Returns the output of the processing that need to be paged via help pager(if any)
220
261
@@ -223,7 +264,7 class NonBlockingIPShell(object):
223 """
264 """
224 return self._help_text
265 return self._help_text
225
266
226 def getBanner(self):
267 def get_banner(self):
227 """
268 """
228 Returns the IPython banner for useful info on IPython instance
269 Returns the IPython banner for useful info on IPython instance
229
270
@@ -232,7 +273,7 class NonBlockingIPShell(object):
232 """
273 """
233 return self._IP.BANNER
274 return self._IP.BANNER
234
275
235 def getPromptCount(self):
276 def get_prompt_count(self):
236 """
277 """
237 Returns the prompt number.
278 Returns the prompt number.
238 Each time a user execute a line in the IPython shell the prompt count is increased
279 Each time a user execute a line in the IPython shell the prompt count is increased
@@ -242,7 +283,7 class NonBlockingIPShell(object):
242 """
283 """
243 return self._IP.outputcache.prompt_count
284 return self._IP.outputcache.prompt_count
244
285
245 def getPrompt(self):
286 def get_prompt(self):
246 """
287 """
247 Returns current prompt inside IPython instance
288 Returns current prompt inside IPython instance
248 (Can be In [...]: ot ...:)
289 (Can be In [...]: ot ...:)
@@ -252,7 +293,7 class NonBlockingIPShell(object):
252 """
293 """
253 return self._prompt
294 return self._prompt
254
295
255 def getIndentation(self):
296 def get_indentation(self):
256 """
297 """
257 Returns the current indentation level
298 Returns the current indentation level
258 Usefull to put the caret at the good start position if we want to do autoindentation.
299 Usefull to put the caret at the good start position if we want to do autoindentation.
@@ -262,7 +303,7 class NonBlockingIPShell(object):
262 """
303 """
263 return self._IP.indent_current_nsp
304 return self._IP.indent_current_nsp
264
305
265 def updateNamespace(self, ns_dict):
306 def update_namespace(self, ns_dict):
266 '''
307 '''
267 Add the current dictionary to the shell namespace.
308 Add the current dictionary to the shell namespace.
268
309
@@ -286,7 +327,7 class NonBlockingIPShell(object):
286 possibilities = self._IP.complete(split_line[-1])
327 possibilities = self._IP.complete(split_line[-1])
287 if possibilities:
328 if possibilities:
288
329
289 def _commonPrefix(str1, str2):
330 def _common_prefix(str1, str2):
290 '''
331 '''
291 Reduction function. returns common prefix of two given strings.
332 Reduction function. returns common prefix of two given strings.
292
333
@@ -302,13 +343,13 class NonBlockingIPShell(object):
302 if not str2.startswith(str1[:i+1]):
343 if not str2.startswith(str1[:i+1]):
303 return str1[:i]
344 return str1[:i]
304 return str1
345 return str1
305 common_prefix = reduce(_commonPrefix, possibilities)
346 common_prefix = reduce(_common_prefix, possibilities)
306 completed = line[:-len(split_line[-1])]+common_prefix
347 completed = line[:-len(split_line[-1])]+common_prefix
307 else:
348 else:
308 completed = line
349 completed = line
309 return completed, possibilities
350 return completed, possibilities
310
351
311 def historyBack(self):
352 def history_back(self):
312 '''
353 '''
313 Provides one history command back.
354 Provides one history command back.
314
355
@@ -320,10 +361,10 class NonBlockingIPShell(object):
320 while((history == '' or history == '\n') and self._history_level >0):
361 while((history == '' or history == '\n') and self._history_level >0):
321 if self._history_level >= 1:
362 if self._history_level >= 1:
322 self._history_level -= 1
363 self._history_level -= 1
323 history = self._getHistory()
364 history = self._get_history()
324 return history
365 return history
325
366
326 def historyForward(self):
367 def history_forward(self):
327 '''
368 '''
328 Provides one history command forward.
369 Provides one history command forward.
329
370
@@ -333,38 +374,38 class NonBlockingIPShell(object):
333 history = ''
374 history = ''
334 #the below while loop is used to suppress empty history lines
375 #the below while loop is used to suppress empty history lines
335 while((history == '' or history == '\n') \
376 while((history == '' or history == '\n') \
336 and self._history_level <= self._getHistoryMaxIndex()):
377 and self._history_level <= self._get_history_max_index()):
337 if self._history_level < self._getHistoryMaxIndex():
378 if self._history_level < self._get_history_max_index():
338 self._history_level += 1
379 self._history_level += 1
339 history = self._getHistory()
380 history = self._get_history()
340 else:
381 else:
341 if self._history_level == self._getHistoryMaxIndex():
382 if self._history_level == self._get_history_max_index():
342 history = self._getHistory()
383 history = self._get_history()
343 self._history_level += 1
384 self._history_level += 1
344 else:
385 else:
345 history = ''
386 history = ''
346 return history
387 return history
347
388
348 def initHistoryIndex(self):
389 def init_history_index(self):
349 '''
390 '''
350 set history to last command entered
391 set history to last command entered
351 '''
392 '''
352 self._history_level = self._getHistoryMaxIndex()+1
393 self._history_level = self._get_history_max_index()+1
353
394
354 #----------------------- IPython PRIVATE management section --------------
395 #----------------------- IPython PRIVATE management section --------------
355 def _afterExecute(self):
396 def _after_execute(self):
356 '''
397 '''
357 Can be redefined to generate post event after excution is done
398 Can be redefined to generate post event after excution is done
358 '''
399 '''
359 pass
400 pass
360
401
361 #def _askExit(self):
402 def _ask_exit(self):
362 # '''
403 '''
363 # Can be redefined to generate post event to exit the Ipython shell
404 Can be redefined to generate post event to exit the Ipython shell
364 # '''
405 '''
365 # pass
406 pass
366
407
367 def _getHistoryMaxIndex(self):
408 def _get_history_max_index(self):
368 '''
409 '''
369 returns the max length of the history buffer
410 returns the max length of the history buffer
370
411
@@ -373,7 +414,7 class NonBlockingIPShell(object):
373 '''
414 '''
374 return len(self._IP.input_hist_raw)-1
415 return len(self._IP.input_hist_raw)-1
375
416
376 def _getHistory(self):
417 def _get_history(self):
377 '''
418 '''
378 Get's the command string of the current history level.
419 Get's the command string of the current history level.
379
420
@@ -388,7 +429,7 class NonBlockingIPShell(object):
388 This function is used as a callback replacment to IPython help pager function
429 This function is used as a callback replacment to IPython help pager function
389
430
390 It puts the 'text' value inside the self._help_text string that can be retrived via
431 It puts the 'text' value inside the self._help_text string that can be retrived via
391 getHelpText function.
432 get_help_text function.
392 '''
433 '''
393 if self._help_text == None:
434 if self._help_text == None:
394 self._help_text = text
435 self._help_text = text
@@ -400,11 +441,11 class NonBlockingIPShell(object):
400 This function is used as a callback replacment to IPython pager function
441 This function is used as a callback replacment to IPython pager function
401
442
402 It puts the 'text' value inside the self._doc_text string that can be retrived via
443 It puts the 'text' value inside the self._doc_text string that can be retrived via
403 getDocText function.
444 get_doc_text function.
404 '''
445 '''
405 self._doc_text = text
446 self._doc_text = text
406
447
407 def _raw_input(self, prompt=''):
448 def _raw_input_original(self, prompt=''):
408 '''
449 '''
409 Custom raw_input() replacement. Get's current line from console buffer.
450 Custom raw_input() replacement. Get's current line from console buffer.
410
451
@@ -416,12 +457,20 class NonBlockingIPShell(object):
416 '''
457 '''
417 return self._line_to_execute
458 return self._line_to_execute
418
459
460 def _raw_input(self, prompt=''):
461 """ A replacement from python's raw_input.
462 """
463 raise NotImplementedError
464
419 def _execute(self):
465 def _execute(self):
420 '''
466 '''
421 Executes the current line provided by the shell object.
467 Executes the current line provided by the shell object.
422 '''
468 '''
469
423 orig_stdout = sys.stdout
470 orig_stdout = sys.stdout
424 sys.stdout = IPython.Shell.Term.cout
471 sys.stdout = IPython.Shell.Term.cout
472 #self.sys_displayhook_ori = sys.displayhook
473 #sys.displayhook = self.displayhook
425
474
426 try:
475 try:
427 line = self._IP.raw_input(None, self._iter_more)
476 line = self._IP.raw_input(None, self._iter_more)
@@ -440,8 +489,10 class NonBlockingIPShell(object):
440 except:
489 except:
441 self._IP.showtraceback()
490 self._IP.showtraceback()
442 else:
491 else:
492 self._IP.write(str(self._IP.outputcache.prompt_out).strip())
443 self._iter_more = self._IP.push(line)
493 self._iter_more = self._IP.push(line)
444 if (self._IP.SyntaxTB.last_syntax_error and self._IP.rc.autoedit_syntax):
494 if (self._IP.SyntaxTB.last_syntax_error and \
495 self._IP.rc.autoedit_syntax):
445 self._IP.edit_syntax_error()
496 self._IP.edit_syntax_error()
446 if self._iter_more:
497 if self._iter_more:
447 self._prompt = str(self._IP.outputcache.prompt2).strip()
498 self._prompt = str(self._IP.outputcache.prompt2).strip()
@@ -450,7 +501,9 class NonBlockingIPShell(object):
450 else:
501 else:
451 self._prompt = str(self._IP.outputcache.prompt1).strip()
502 self._prompt = str(self._IP.outputcache.prompt1).strip()
452 self._IP.indent_current_nsp = 0 #we set indentation to 0
503 self._IP.indent_current_nsp = 0 #we set indentation to 0
504
453 sys.stdout = orig_stdout
505 sys.stdout = orig_stdout
506 #sys.displayhook = self.sys_displayhook_ori
454
507
455 def _shell(self, ip, cmd):
508 def _shell(self, ip, cmd):
456 '''
509 '''
@@ -462,7 +515,8 class NonBlockingIPShell(object):
462 @type cmd: string
515 @type cmd: string
463 '''
516 '''
464 stdin, stdout = os.popen4(cmd)
517 stdin, stdout = os.popen4(cmd)
465 result = stdout.read().decode('cp437').encode(locale.getpreferredencoding())
518 result = stdout.read().decode('cp437').\
519 encode(locale.getpreferredencoding())
466 #we use print command because the shell command is called
520 #we use print command because the shell command is called
467 #inside IPython instance and thus is redirected to thread cout
521 #inside IPython instance and thus is redirected to thread cout
468 #"\x01\x1b[1;36m\x02" <-- add colour to the text...
522 #"\x01\x1b[1;36m\x02" <-- add colour to the text...
@@ -29,16 +29,20 class IPythonHistoryPanel(wx.Panel):
29 self.filter_magic = wx.CheckBox(self, -1, "%: Magic keys")
29 self.filter_magic = wx.CheckBox(self, -1, "%: Magic keys")
30
30
31 self.options={'filter_empty':{'value':'True',
31 self.options={'filter_empty':{'value':'True',
32 'checkbox':self.filter_empty,'True':True,'False':False,
32 'checkbox':self.filter_empty, \
33 'True':True,'False':False,
33 'setfunc':lambda x:None},
34 'setfunc':lambda x:None},
34 'filter_doc':{'value':'True',
35 'filter_doc':{'value':'True',
35 'checkbox':self.filter_doc,'True':True,'False':False,
36 'checkbox':self.filter_doc, \
37 'True':True,'False':False,
36 'setfunc':lambda x:None},
38 'setfunc':lambda x:None},
37 'filter_cmd':{'value':'True',
39 'filter_cmd':{'value':'True',
38 'checkbox':self.filter_cmd,'True':True,'False':False,
40 'checkbox':self.filter_cmd, \
41 'True':True,'False':False,
39 'setfunc':lambda x:None},
42 'setfunc':lambda x:None},
40 'filter_magic':{'value':'True',
43 'filter_magic':{'value':'True',
41 'checkbox':self.filter_magic,'True':True,'False':False,
44 'checkbox':self.filter_magic, \
45 'True':True,'False':False,
42 'setfunc':lambda x:None},
46 'setfunc':lambda x:None},
43 }
47 }
44 self.reloadOptions(self.options)
48 self.reloadOptions(self.options)
@@ -199,51 +203,81 class PythonSTC(stc.StyledTextCtrl):
199 self.SetLayoutCache(stc.STC_CACHE_PAGE)
203 self.SetLayoutCache(stc.STC_CACHE_PAGE)
200
204
201 # Setup a margin to hold fold markers
205 # Setup a margin to hold fold markers
202 #self.SetFoldFlags(16) ### WHAT IS THIS VALUE? WHAT ARE THE OTHER FLAGS? DOES IT MATTER?
206 #self.SetFoldFlags(16)
207 ### WHAT IS THIS VALUE? WHAT ARE THE OTHER FLAGS? DOES IT MATTER?
203 self.SetMarginType(2, stc.STC_MARGIN_SYMBOL)
208 self.SetMarginType(2, stc.STC_MARGIN_SYMBOL)
204 self.SetMarginMask(2, stc.STC_MASK_FOLDERS)
209 self.SetMarginMask(2, stc.STC_MASK_FOLDERS)
205 self.SetMarginSensitive(2, True)
210 self.SetMarginSensitive(2, True)
206 self.SetMarginWidth(2, 12)
211 self.SetMarginWidth(2, 12)
207
212
208 if self.fold_symbols == 0:
213 if self.fold_symbols == 0:
209 # Arrow pointing right for contracted folders, arrow pointing down for expanded
214 # Arrow pointing right for contracted folders,
210 self.MarkerDefine(stc.STC_MARKNUM_FOLDEROPEN, stc.STC_MARK_ARROWDOWN, "black", "black")
215 # arrow pointing down for expanded
211 self.MarkerDefine(stc.STC_MARKNUM_FOLDER, stc.STC_MARK_ARROW, "black", "black")
216 self.MarkerDefine(stc.STC_MARKNUM_FOLDEROPEN, \
212 self.MarkerDefine(stc.STC_MARKNUM_FOLDERSUB, stc.STC_MARK_EMPTY, "black", "black")
217 stc.STC_MARK_ARROWDOWN, "black", "black")
213 self.MarkerDefine(stc.STC_MARKNUM_FOLDERTAIL, stc.STC_MARK_EMPTY, "black", "black")
218 self.MarkerDefine(stc.STC_MARKNUM_FOLDER, \
214 self.MarkerDefine(stc.STC_MARKNUM_FOLDEREND, stc.STC_MARK_EMPTY, "white", "black")
219 stc.STC_MARK_ARROW, "black", "black")
215 self.MarkerDefine(stc.STC_MARKNUM_FOLDEROPENMID, stc.STC_MARK_EMPTY, "white", "black")
220 self.MarkerDefine(stc.STC_MARKNUM_FOLDERSUB, \
216 self.MarkerDefine(stc.STC_MARKNUM_FOLDERMIDTAIL, stc.STC_MARK_EMPTY, "white", "black")
221 stc.STC_MARK_EMPTY, "black", "black")
222 self.MarkerDefine(stc.STC_MARKNUM_FOLDERTAIL, \
223 stc.STC_MARK_EMPTY, "black", "black")
224 self.MarkerDefine(stc.STC_MARKNUM_FOLDEREND, \
225 stc.STC_MARK_EMPTY, "white", "black")
226 self.MarkerDefine(stc.STC_MARKNUM_FOLDEROPENMID, \
227 stc.STC_MARK_EMPTY, "white", "black")
228 self.MarkerDefine(stc.STC_MARKNUM_FOLDERMIDTAIL, \
229 stc.STC_MARK_EMPTY, "white", "black")
217
230
218 elif self.fold_symbols == 1:
231 elif self.fold_symbols == 1:
219 # Plus for contracted folders, minus for expanded
232 # Plus for contracted folders, minus for expanded
220 self.MarkerDefine(stc.STC_MARKNUM_FOLDEROPEN, stc.STC_MARK_MINUS, "white", "black")
233 self.MarkerDefine(stc.STC_MARKNUM_FOLDEROPEN, \
221 self.MarkerDefine(stc.STC_MARKNUM_FOLDER, stc.STC_MARK_PLUS, "white", "black")
234 stc.STC_MARK_MINUS, "white", "black")
222 self.MarkerDefine(stc.STC_MARKNUM_FOLDERSUB, stc.STC_MARK_EMPTY, "white", "black")
235 self.MarkerDefine(stc.STC_MARKNUM_FOLDER, \
223 self.MarkerDefine(stc.STC_MARKNUM_FOLDERTAIL, stc.STC_MARK_EMPTY, "white", "black")
236 stc.STC_MARK_PLUS, "white", "black")
224 self.MarkerDefine(stc.STC_MARKNUM_FOLDEREND, stc.STC_MARK_EMPTY, "white", "black")
237 self.MarkerDefine(stc.STC_MARKNUM_FOLDERSUB, \
225 self.MarkerDefine(stc.STC_MARKNUM_FOLDEROPENMID, stc.STC_MARK_EMPTY, "white", "black")
238 stc.STC_MARK_EMPTY, "white", "black")
226 self.MarkerDefine(stc.STC_MARKNUM_FOLDERMIDTAIL, stc.STC_MARK_EMPTY, "white", "black")
239 self.MarkerDefine(stc.STC_MARKNUM_FOLDERTAIL, \
240 stc.STC_MARK_EMPTY, "white", "black")
241 self.MarkerDefine(stc.STC_MARKNUM_FOLDEREND, \
242 stc.STC_MARK_EMPTY, "white", "black")
243 self.MarkerDefine(stc.STC_MARKNUM_FOLDEROPENMID, \
244 stc.STC_MARK_EMPTY, "white", "black")
245 self.MarkerDefine(stc.STC_MARKNUM_FOLDERMIDTAIL, \
246 stc.STC_MARK_EMPTY, "white", "black")
227
247
228 elif self.fold_symbols == 2:
248 elif self.fold_symbols == 2:
229 # Like a flattened tree control using circular headers and curved joins
249 # Like a flattened tree control using circular headers and curved joins
230 self.MarkerDefine(stc.STC_MARKNUM_FOLDEROPEN, stc.STC_MARK_CIRCLEMINUS, "white", "#404040")
250 self.MarkerDefine(stc.STC_MARKNUM_FOLDEROPEN, \
231 self.MarkerDefine(stc.STC_MARKNUM_FOLDER, stc.STC_MARK_CIRCLEPLUS, "white", "#404040")
251 stc.STC_MARK_CIRCLEMINUS, "white", "#404040")
232 self.MarkerDefine(stc.STC_MARKNUM_FOLDERSUB, stc.STC_MARK_VLINE, "white", "#404040")
252 self.MarkerDefine(stc.STC_MARKNUM_FOLDER, \
233 self.MarkerDefine(stc.STC_MARKNUM_FOLDERTAIL, stc.STC_MARK_LCORNERCURVE, "white", "#404040")
253 stc.STC_MARK_CIRCLEPLUS, "white", "#404040")
234 self.MarkerDefine(stc.STC_MARKNUM_FOLDEREND, stc.STC_MARK_CIRCLEPLUSCONNECTED, "white", "#404040")
254 self.MarkerDefine(stc.STC_MARKNUM_FOLDERSUB, \
235 self.MarkerDefine(stc.STC_MARKNUM_FOLDEROPENMID, stc.STC_MARK_CIRCLEMINUSCONNECTED, "white", "#404040")
255 stc.STC_MARK_VLINE, "white", "#404040")
236 self.MarkerDefine(stc.STC_MARKNUM_FOLDERMIDTAIL, stc.STC_MARK_TCORNERCURVE, "white", "#404040")
256 self.MarkerDefine(stc.STC_MARKNUM_FOLDERTAIL, \
257 stc.STC_MARK_LCORNERCURVE, "white", "#404040")
258 self.MarkerDefine(stc.STC_MARKNUM_FOLDEREND, \
259 stc.STC_MARK_CIRCLEPLUSCONNECTED, "white", "#404040")
260 self.MarkerDefine(stc.STC_MARKNUM_FOLDEROPENMID, \
261 stc.STC_MARK_CIRCLEMINUSCONNECTED, "white", "#404040")
262 self.MarkerDefine(stc.STC_MARKNUM_FOLDERMIDTAIL, \
263 stc.STC_MARK_TCORNERCURVE, "white", "#404040")
237
264
238 elif self.fold_symbols == 3:
265 elif self.fold_symbols == 3:
239 # Like a flattened tree control using square headers
266 # Like a flattened tree control using square headers
240 self.MarkerDefine(stc.STC_MARKNUM_FOLDEROPEN, stc.STC_MARK_BOXMINUS, "white", "#808080")
267 self.MarkerDefine(stc.STC_MARKNUM_FOLDEROPEN, \
241 self.MarkerDefine(stc.STC_MARKNUM_FOLDER, stc.STC_MARK_BOXPLUS, "white", "#808080")
268 stc.STC_MARK_BOXMINUS, "white", "#808080")
242 self.MarkerDefine(stc.STC_MARKNUM_FOLDERSUB, stc.STC_MARK_VLINE, "white", "#808080")
269 self.MarkerDefine(stc.STC_MARKNUM_FOLDER, \
243 self.MarkerDefine(stc.STC_MARKNUM_FOLDERTAIL, stc.STC_MARK_LCORNER, "white", "#808080")
270 stc.STC_MARK_BOXPLUS, "white", "#808080")
244 self.MarkerDefine(stc.STC_MARKNUM_FOLDEREND, stc.STC_MARK_BOXPLUSCONNECTED, "white", "#808080")
271 self.MarkerDefine(stc.STC_MARKNUM_FOLDERSUB, \
245 self.MarkerDefine(stc.STC_MARKNUM_FOLDEROPENMID, stc.STC_MARK_BOXMINUSCONNECTED, "white", "#808080")
272 stc.STC_MARK_VLINE, "white", "#808080")
246 self.MarkerDefine(stc.STC_MARKNUM_FOLDERMIDTAIL, stc.STC_MARK_TCORNER, "white", "#808080")
273 self.MarkerDefine(stc.STC_MARKNUM_FOLDERTAIL, \
274 stc.STC_MARK_LCORNER, "white", "#808080")
275 self.MarkerDefine(stc.STC_MARKNUM_FOLDEREND, \
276 stc.STC_MARK_BOXPLUSCONNECTED, "white", "#808080")
277 self.MarkerDefine(stc.STC_MARKNUM_FOLDEROPENMID, \
278 stc.STC_MARK_BOXMINUSCONNECTED, "white", "#808080")
279 self.MarkerDefine(stc.STC_MARKNUM_FOLDERMIDTAIL, \
280 stc.STC_MARK_TCORNER, "white", "#808080")
247
281
248
282
249 self.Bind(stc.EVT_STC_UPDATEUI, self.OnUpdateUI)
283 self.Bind(stc.EVT_STC_UPDATEUI, self.OnUpdateUI)
@@ -19,7 +19,7 available under the terms of the BSD which accompanies this distribution, and
19 is available at U{http://www.opensource.org/licenses/bsd-license.php}
19 is available at U{http://www.opensource.org/licenses/bsd-license.php}
20 '''
20 '''
21
21
22 __version__ = 0.8
22 __version__ = 0.9
23 __author__ = "Laurent Dufrechou"
23 __author__ = "Laurent Dufrechou"
24 __email__ = "laurent.dufrechou _at_ gmail.com"
24 __email__ = "laurent.dufrechou _at_ gmail.com"
25 __license__ = "BSD"
25 __license__ = "BSD"
@@ -33,6 +33,8 from StringIO import StringIO
33 import sys
33 import sys
34 import codecs
34 import codecs
35 import locale
35 import locale
36 import time
37
36 for enc in (locale.getpreferredencoding(),
38 for enc in (locale.getpreferredencoding(),
37 sys.getfilesystemencoding(),
39 sys.getfilesystemencoding(),
38 sys.getdefaultencoding()):
40 sys.getdefaultencoding()):
@@ -63,17 +65,43 class WxNonBlockingIPShell(NonBlockingIPShell):
63 self.parent = parent
65 self.parent = parent
64
66
65 self.ask_exit_callback = ask_exit_handler
67 self.ask_exit_callback = ask_exit_handler
66 self._IP.exit = self._askExit
68 self._IP.exit = self._ask_exit
67
69
68 def addGUIShortcut(self, text, func):
70 def addGUIShortcut(self, text, func):
69 wx.CallAfter(self.parent.add_button_handler,
71 wx.CallAfter(self.parent.add_button_handler,
70 button_info={ 'text':text,
72 button_info={ 'text':text,
71 'func':self.parent.doExecuteLine(func)})
73 'func':self.parent.doExecuteLine(func)})
72
74
73 def _askExit(self):
75 def _raw_input(self, prompt=''):
76 """ A replacement from python's raw_input.
77 """
78 self.answer = None
79 if(self._threading == True):
80 wx.CallAfter(self._yesNoBox, prompt)
81 while self.answer is None:
82 time.sleep(.1)
83 else:
84 self._yesNoBox(prompt)
85 return self.answer
86
87 def _yesNoBox(self, prompt):
88 """ yes/no box managed with wx.CallAfter jsut in case caler is executed in a thread"""
89 dlg = wx.TextEntryDialog(
90 self.parent, prompt,
91 'Input requested', 'Python')
92 dlg.SetValue("")
93
94 answer = ''
95 if dlg.ShowModal() == wx.ID_OK:
96 answer = dlg.GetValue()
97
98 dlg.Destroy()
99 self.answer = answer
100
101 def _ask_exit(self):
74 wx.CallAfter(self.ask_exit_callback, ())
102 wx.CallAfter(self.ask_exit_callback, ())
75
103
76 def _afterExecute(self):
104 def _after_execute(self):
77 wx.CallAfter(self.parent.evtStateExecuteDone, ())
105 wx.CallAfter(self.parent.evtStateExecuteDone, ())
78
106
79
107
@@ -249,22 +277,15 class WxConsoleView(stc.StyledTextCtrl):
249 @type text: string
277 @type text: string
250 '''
278 '''
251 try:
279 try:
252 #print >>sys.__stdout__,'entering'
253 wx.MutexGuiEnter()
280 wx.MutexGuiEnter()
254 #print >>sys.__stdout__,'locking the GUI'
255
281
256 #be sure not to be interrutpted before the MutexGuiLeave!
282 #be sure not to be interrutpted before the MutexGuiLeave!
257 self.write(text)
283 self.write(text)
258
284
259 #print >>sys.__stdout__,'done'
260
261 except KeyboardInterrupt:
285 except KeyboardInterrupt:
262 #print >>sys.__stdout__,'got keyboard interrupt'
263 wx.MutexGuiLeave()
286 wx.MutexGuiLeave()
264 #print >>sys.__stdout__,'interrupt unlock the GUI'
265 raise KeyboardInterrupt
287 raise KeyboardInterrupt
266 wx.MutexGuiLeave()
288 wx.MutexGuiLeave()
267 #print >>sys.__stdout__,'normal unlock the GUI'
268
289
269
290
270 def write(self, text):
291 def write(self, text):
@@ -419,7 +440,7 class WxConsoleView(stc.StyledTextCtrl):
419 self.AutoCompSetIgnoreCase(False)
440 self.AutoCompSetIgnoreCase(False)
420 self.AutoCompSetAutoHide(False)
441 self.AutoCompSetAutoHide(False)
421 #let compute the length ot last word
442 #let compute the length ot last word
422 splitter = [' ', '(', '[', '{']
443 splitter = [' ', '(', '[', '{','=']
423 last_word = self.getCurrentLine()
444 last_word = self.getCurrentLine()
424 for breaker in splitter:
445 for breaker in splitter:
425 last_word = last_word.split(breaker)[-1]
446 last_word = last_word.split(breaker)[-1]
@@ -439,7 +460,6 class WxConsoleView(stc.StyledTextCtrl):
439 @return: Return True if event as been catched.
460 @return: Return True if event as been catched.
440 @rtype: boolean
461 @rtype: boolean
441 '''
462 '''
442
443 if not self.AutoCompActive():
463 if not self.AutoCompActive():
444 if event.GetKeyCode() == wx.WXK_HOME:
464 if event.GetKeyCode() == wx.WXK_HOME:
445 if event.Modifiers == wx.MOD_NONE:
465 if event.Modifiers == wx.MOD_NONE:
@@ -554,24 +574,30 class IPShellWidget(wx.Panel):
554 #with intro=''
574 #with intro=''
555 if intro is None:
575 if intro is None:
556 welcome_text = "Welcome to WxIPython Shell.\n\n"
576 welcome_text = "Welcome to WxIPython Shell.\n\n"
557 welcome_text+= self.IP.getBanner()
577 welcome_text+= self.IP.get_banner()
558 welcome_text+= "!command -> Execute command in shell\n"
578 welcome_text+= "!command -> Execute command in shell\n"
559 welcome_text+= "TAB -> Autocompletion\n"
579 welcome_text+= "TAB -> Autocompletion\n"
560 else:
580 else:
561 welcome_text = intro
581 welcome_text = intro
562
582
563 self.text_ctrl = WxConsoleView(self,
583 self.text_ctrl = WxConsoleView(self,
564 self.IP.getPrompt(),
584 self.IP.get_prompt(),
565 intro=welcome_text,
585 intro=welcome_text,
566 background_color=background_color)
586 background_color=background_color)
567
587
568 self.cout.write = self.text_ctrl.asyncWrite
569
570 option_text = wx.StaticText(self, -1, "Options:")
588 option_text = wx.StaticText(self, -1, "Options:")
571 self.completion_option = wx.CheckBox(self, -1, "Scintilla Completion")
589 self.completion_option = wx.CheckBox(self, -1, "Scintilla Completion")
590 self.completion_option.SetToolTip(wx.ToolTip(
591 "Selects the completion type:\nEither Ipython default style or Scintilla one"))
572 #self.completion_option.SetValue(False)
592 #self.completion_option.SetValue(False)
573 self.background_option = wx.CheckBox(self, -1, "White Background")
593 self.background_option = wx.CheckBox(self, -1, "White Background")
594 self.background_option.SetToolTip(wx.ToolTip(
595 "Selects the back ground color: BLACK or WHITE"))
574 #self.background_option.SetValue(False)
596 #self.background_option.SetValue(False)
597 self.threading_option = wx.CheckBox(self, -1, "Execute in thread")
598 self.threading_option.SetToolTip(wx.ToolTip(
599 "Use threading: infinite loop don't freeze the GUI and commands can be breaked\nNo threading: maximum compatibility"))
600 #self.threading_option.SetValue(False)
575
601
576 self.options={'completion':{'value':'IPYTHON',
602 self.options={'completion':{'value':'IPYTHON',
577 'checkbox':self.completion_option,'STC':True,'IPYTHON':False,
603 'checkbox':self.completion_option,'STC':True,'IPYTHON':False,
@@ -579,12 +605,20 class IPShellWidget(wx.Panel):
579 'background_color':{'value':'BLACK',
605 'background_color':{'value':'BLACK',
580 'checkbox':self.background_option,'WHITE':True,'BLACK':False,
606 'checkbox':self.background_option,'WHITE':True,'BLACK':False,
581 'setfunc':self.text_ctrl.setBackgroundColor},
607 'setfunc':self.text_ctrl.setBackgroundColor},
608 'threading':{'value':'True',
609 'checkbox':self.threading_option,'True':True,'False':False,
610 'setfunc':self.IP.set_threading},
582 }
611 }
612
613 #self.cout.write dEfault option is asynchroneous because default sate is threading ON
614 self.cout.write = self.text_ctrl.asyncWrite
615 #we reloard options
583 self.reloadOptions(self.options)
616 self.reloadOptions(self.options)
584
617
585 self.text_ctrl.Bind(wx.EVT_KEY_DOWN, self.keyPress)
618 self.text_ctrl.Bind(wx.EVT_KEY_DOWN, self.keyPress)
586 self.completion_option.Bind(wx.EVT_CHECKBOX, self.evtCheckOptionCompletion)
619 self.completion_option.Bind(wx.EVT_CHECKBOX, self.evtCheckOptionCompletion)
587 self.background_option.Bind(wx.EVT_CHECKBOX, self.evtCheckOptionBackgroundColor)
620 self.background_option.Bind(wx.EVT_CHECKBOX, self.evtCheckOptionBackgroundColor)
621 self.threading_option.Bind(wx.EVT_CHECKBOX, self.evtCheckOptionThreading)
588
622
589 ### making the layout of the panel ###
623 ### making the layout of the panel ###
590 sizer = wx.BoxSizer(wx.VERTICAL)
624 sizer = wx.BoxSizer(wx.VERTICAL)
@@ -596,7 +630,9 class IPShellWidget(wx.Panel):
596 (5, 5),
630 (5, 5),
597 (self.completion_option, 0, wx.ALIGN_CENTER_VERTICAL),
631 (self.completion_option, 0, wx.ALIGN_CENTER_VERTICAL),
598 (8, 8),
632 (8, 8),
599 (self.background_option, 0, wx.ALIGN_CENTER_VERTICAL)
633 (self.background_option, 0, wx.ALIGN_CENTER_VERTICAL),
634 (8, 8),
635 (self.threading_option, 0, wx.ALIGN_CENTER_VERTICAL)
600 ])
636 ])
601 self.SetAutoLayout(True)
637 self.SetAutoLayout(True)
602 sizer.Fit(self)
638 sizer.Fit(self)
@@ -619,13 +655,15 class IPShellWidget(wx.Panel):
619 self.text_ctrl.write('\n')
655 self.text_ctrl.write('\n')
620 lines_to_execute = lines.replace('\t',' '*4)
656 lines_to_execute = lines.replace('\t',' '*4)
621 lines_to_execute = lines_to_execute.replace('\r','')
657 lines_to_execute = lines_to_execute.replace('\r','')
622 self.IP.doExecute(lines_to_execute.encode(ENCODING))
658 self.IP.do_execute(lines_to_execute.encode(ENCODING))
623 self.updateHistoryTracker(lines)
659 self.updateHistoryTracker(lines)
660 if(self.text_ctrl.getCursorPos()!=0):
661 self.text_ctrl.removeCurrentLine()
624 self.setCurrentState('WAIT_END_OF_EXECUTION')
662 self.setCurrentState('WAIT_END_OF_EXECUTION')
625
663
626 def evtStateExecuteDone(self,evt):
664 def evtStateExecuteDone(self,evt):
627 self.doc = self.IP.getDocText()
665 self.doc = self.IP.get_doc_text()
628 self.help = self.IP.getHelpText()
666 self.help = self.IP.get_help_text()
629 if self.doc:
667 if self.doc:
630 self.pager_lines = self.doc[7:].split('\n')
668 self.pager_lines = self.doc[7:].split('\n')
631 self.pager_state = 'INIT'
669 self.pager_state = 'INIT'
@@ -637,15 +675,17 class IPShellWidget(wx.Panel):
637 self.setCurrentState('SHOW_DOC')
675 self.setCurrentState('SHOW_DOC')
638 self.pager(self.help)
676 self.pager(self.help)
639 else:
677 else:
678 if(self.text_ctrl.getCursorPos()!=0):
679 self.text_ctrl.removeCurrentLine()
640 self.stateShowPrompt()
680 self.stateShowPrompt()
641
681
642 def stateShowPrompt(self):
682 def stateShowPrompt(self):
643 self.setCurrentState('SHOW_PROMPT')
683 self.setCurrentState('SHOW_PROMPT')
644 self.text_ctrl.setPrompt(self.IP.getPrompt())
684 self.text_ctrl.setPrompt(self.IP.get_prompt())
645 self.text_ctrl.setIndentation(self.IP.getIndentation())
685 self.text_ctrl.setIndentation(self.IP.get_indentation())
646 self.text_ctrl.setPromptCount(self.IP.getPromptCount())
686 self.text_ctrl.setPromptCount(self.IP.get_prompt_count())
647 self.text_ctrl.showPrompt()
687 self.text_ctrl.showPrompt()
648 self.IP.initHistoryIndex()
688 self.IP.init_history_index()
649 self.setCurrentState('IDLE')
689 self.setCurrentState('IDLE')
650
690
651 def setCurrentState(self, state):
691 def setCurrentState(self, state):
@@ -751,11 +791,11 class IPShellWidget(wx.Panel):
751
791
752 if self.cur_state == 'IDLE':
792 if self.cur_state == 'IDLE':
753 if event.KeyCode == wx.WXK_UP:
793 if event.KeyCode == wx.WXK_UP:
754 history = self.IP.historyBack()
794 history = self.IP.history_back()
755 self.text_ctrl.writeHistory(history)
795 self.text_ctrl.writeHistory(history)
756 return
796 return
757 if event.KeyCode == wx.WXK_DOWN:
797 if event.KeyCode == wx.WXK_DOWN:
758 history = self.IP.historyForward()
798 history = self.IP.history_forward()
759 self.text_ctrl.writeHistory(history)
799 self.text_ctrl.writeHistory(history)
760 return
800 return
761 if event.KeyCode == wx.WXK_TAB:
801 if event.KeyCode == wx.WXK_TAB:
@@ -803,6 +843,19 class IPShellWidget(wx.Panel):
803 self.options['background_color']['value'])
843 self.options['background_color']['value'])
804 self.text_ctrl.SetFocus()
844 self.text_ctrl.SetFocus()
805
845
846 def evtCheckOptionThreading(self, event):
847 if event.IsChecked():
848 self.options['threading']['value']='True'
849 self.IP.set_threading(True)
850 self.cout.write = self.text_ctrl.asyncWrite
851 else:
852 self.options['threading']['value']='False'
853 self.IP.set_threading(False)
854 self.cout.write = self.text_ctrl.write
855 self.updateOptionTracker('threading',
856 self.options['threading']['value'])
857 self.text_ctrl.SetFocus()
858
806 def getOptions(self):
859 def getOptions(self):
807 return self.options
860 return self.options
808
861
@@ -813,6 +866,12 class IPShellWidget(wx.Panel):
813 self.options[key]['checkbox'].SetValue(self.options[key][value])
866 self.options[key]['checkbox'].SetValue(self.options[key][value])
814 self.options[key]['setfunc'](value)
867 self.options[key]['setfunc'](value)
815
868
869 if self.options['threading']['value']=='True':
870 self.IP.set_threading(True)
871 self.cout.write = self.text_ctrl.asyncWrite
872 else:
873 self.IP.set_threading(False)
874 self.cout.write = self.text_ctrl.write
816
875
817 #------------------------ Hook Section -----------------------------------
876 #------------------------ Hook Section -----------------------------------
818 def updateOptionTracker(self,name,value):
877 def updateOptionTracker(self,name,value):
@@ -10,10 +10,18 from wx.lib.wordwrap import wordwrap
10 from IPython.gui.wx.ipython_view import IPShellWidget
10 from IPython.gui.wx.ipython_view import IPShellWidget
11 from IPython.gui.wx.ipython_history import IPythonHistoryPanel
11 from IPython.gui.wx.ipython_history import IPythonHistoryPanel
12
12
13 #used to invoke ipython1 wx implementation
14 ### FIXME ### temporary disabled due to interference with 'show_in_pager' hook
15 is_sync_frontend_ok = False
16 try:
17 from IPython.frontend.wx.ipythonx import IPythonXController
18 except ImportError:
19 is_sync_frontend_ok = False
20
13 #used to create options.conf file in user directory
21 #used to create options.conf file in user directory
14 from IPython.ipapi import get
22 from IPython.ipapi import get
15
23
16 __version__ = 0.8
24 __version__ = 0.91
17 __author__ = "Laurent Dufrechou"
25 __author__ = "Laurent Dufrechou"
18 __email__ = "laurent.dufrechou _at_ gmail.com"
26 __email__ = "laurent.dufrechou _at_ gmail.com"
19 __license__ = "BSD"
27 __license__ = "BSD"
@@ -27,7 +35,7 class MyFrame(wx.Frame):
27 application with movables windows"""
35 application with movables windows"""
28 def __init__(self, parent=None, id=-1, title="WxIPython",
36 def __init__(self, parent=None, id=-1, title="WxIPython",
29 pos=wx.DefaultPosition,
37 pos=wx.DefaultPosition,
30 size=(800, 600), style=wx.DEFAULT_FRAME_STYLE):
38 size=(800, 600), style=wx.DEFAULT_FRAME_STYLE, sync_ok=False):
31 wx.Frame.__init__(self, parent, id, title, pos, size, style)
39 wx.Frame.__init__(self, parent, id, title, pos, size, style)
32 self._mgr = wx.aui.AuiManager()
40 self._mgr = wx.aui.AuiManager()
33
41
@@ -41,12 +49,18 class MyFrame(wx.Frame):
41
49
42 self.ipython_panel = IPShellWidget(self,background_color = "BLACK")
50 self.ipython_panel = IPShellWidget(self,background_color = "BLACK")
43 #self.ipython_panel = IPShellWidget(self,background_color = "WHITE")
51 #self.ipython_panel = IPShellWidget(self,background_color = "WHITE")
44
52 if(sync_ok):
53 self.ipython_panel2 = IPythonXController(self)
54 else:
55 self.ipython_panel2 = None
45 self.ipython_panel.setHistoryTrackerHook(self.history_panel.write)
56 self.ipython_panel.setHistoryTrackerHook(self.history_panel.write)
46 self.ipython_panel.setStatusTrackerHook(self.updateStatus)
57 self.ipython_panel.setStatusTrackerHook(self.updateStatus)
47 self.ipython_panel.setAskExitHandler(self.OnExitDlg)
58 self.ipython_panel.setAskExitHandler(self.OnExitDlg)
48 self.ipython_panel.setOptionTrackerHook(self.optionSave)
59 self.ipython_panel.setOptionTrackerHook(self.optionSave)
49
60
61 #Create a notebook to display different IPython shell implementations
62 self.nb = wx.aui.AuiNotebook(self)
63
50 self.optionLoad()
64 self.optionLoad()
51
65
52 self.statusbar = self.createStatus()
66 self.statusbar = self.createStatus()
@@ -55,7 +69,11 class MyFrame(wx.Frame):
55 ########################################################################
69 ########################################################################
56 ### add the panes to the manager
70 ### add the panes to the manager
57 # main panels
71 # main panels
58 self._mgr.AddPane(self.ipython_panel , wx.CENTER, "IPython Shell")
72 self._mgr.AddPane(self.nb , wx.CENTER, "IPython Shells")
73 self.nb.AddPage(self.ipython_panel , "IPython0 Shell")
74 if(sync_ok):
75 self.nb.AddPage(self.ipython_panel2, "IPython1 Synchroneous Shell")
76
59 self._mgr.AddPane(self.history_panel , wx.RIGHT, "IPython history")
77 self._mgr.AddPane(self.history_panel , wx.RIGHT, "IPython history")
60
78
61 # now we specify some panel characteristics
79 # now we specify some panel characteristics
@@ -77,6 +95,9 class MyFrame(wx.Frame):
77 warn_text = 'Hello from IPython and wxPython.\n'
95 warn_text = 'Hello from IPython and wxPython.\n'
78 warn_text +='Please Note that this work is still EXPERIMENTAL\n'
96 warn_text +='Please Note that this work is still EXPERIMENTAL\n'
79 warn_text +='It does NOT emulate currently all the IPython functions.\n'
97 warn_text +='It does NOT emulate currently all the IPython functions.\n'
98 warn_text +="\nIf you use MATPLOTLIB with show() you'll need to deactivate the THREADING option.\n"
99 if(not sync_ok):
100 warn_text +="\n->No twisted package detected, IPython1 example deactivated."
80
101
81 dlg = wx.MessageDialog(self,
102 dlg = wx.MessageDialog(self,
82 warn_text,
103 warn_text,
@@ -146,13 +167,6 class MyFrame(wx.Frame):
146 about_menu = wx.Menu()
167 about_menu = wx.Menu()
147 about_menu.Append(wx.ID_HIGHEST+3, "About")
168 about_menu.Append(wx.ID_HIGHEST+3, "About")
148
169
149 #view_menu.AppendSeparator()
150 #options_menu = wx.Menu()
151 #options_menu.AppendCheckItem(wx.ID_HIGHEST+7, "Allow Floating")
152 #options_menu.AppendCheckItem(wx.ID_HIGHEST+8, "Transparent Hint")
153 #options_menu.AppendCheckItem(wx.ID_HIGHEST+9, "Transparent Hint Fade-in")
154
155
156 mb.Append(file_menu, "File")
170 mb.Append(file_menu, "File")
157 mb.Append(view_menu, "View")
171 mb.Append(view_menu, "View")
158 mb.Append(about_menu, "About")
172 mb.Append(about_menu, "About")
@@ -233,17 +247,17 class MyFrame(wx.Frame):
233 #-----------------------------------------
247 #-----------------------------------------
234 class MyApp(wx.PySimpleApp):
248 class MyApp(wx.PySimpleApp):
235 """Creating our application"""
249 """Creating our application"""
236 def __init__(self):
250 def __init__(self, sync_ok=False):
237 wx.PySimpleApp.__init__(self)
251 wx.PySimpleApp.__init__(self)
238
252
239 self.frame = MyFrame()
253 self.frame = MyFrame(sync_ok=sync_ok)
240 self.frame.Show()
254 self.frame.Show()
241
255
242 #-----------------------------------------
256 #-----------------------------------------
243 #Main loop
257 #Main loop
244 #-----------------------------------------
258 #-----------------------------------------
245 def main():
259 def main():
246 app = MyApp()
260 app = MyApp(is_sync_frontend_ok)
247 app.SetTopWindow(app.frame)
261 app.SetTopWindow(app.frame)
248 app.MainLoop()
262 app.MainLoop()
249
263
General Comments 0
You need to be logged in to leave comments. Login now