##// END OF EJS Templates
fix crlf on ipy_winpdb
Ville M. Vainio -
r1137:be020659 merge
parent child Browse files
Show More
@@ -0,0 +1,73 b''
1 """ Debug a script (like %run -d) in IPython process, Using WinPdb
2
3 Usage:
4
5 %wdb test.py
6 run test.py, with a winpdb breakpoint at start of the file
7
8 %wdb pass
9 Change the password (e.g. if you have forgotten the old one)
10 """
11
12 import os
13
14 import IPython.ipapi
15 import rpdb2
16
17 ip = IPython.ipapi.get()
18
19 rpdb_started = False
20
21 def wdb_f(self, arg):
22 """ Debug a script (like %run -d) in IPython process, Using WinPdb
23
24 Usage:
25
26 %wdb test.py
27 run test.py, with a winpdb breakpoint at start of the file
28
29 %wdb pass
30 Change the password (e.g. if you have forgotten the old one)
31
32 Note that after the script has been run, you need to do "Go" (f5)
33 in WinPdb to resume normal IPython operation.
34 """
35
36 global rpdb_started
37 if not arg.strip():
38 print __doc__
39 return
40
41 if arg.strip() == 'pass':
42 passwd = raw_input('Enter new winpdb session password: ')
43 ip.db['winpdb_pass'] = passwd
44 print "Winpdb password changed"
45 if rpdb_started:
46 print "You need to restart IPython to use the new password"
47 return
48
49 path = os.path.abspath(arg)
50 if not os.path.isfile(path):
51 raise IPython.ipapi.UsageError("%%wdb: file %s does not exist" % path)
52 if not rpdb_started:
53 passwd = ip.db.get('winpdb_pass', None)
54 if passwd is None:
55 import textwrap
56 print textwrap.dedent("""\
57 Winpdb sessions need a password that you use for attaching the external
58 winpdb session. IPython will remember this. You can change the password later
59 by '%wpdb pass'
60 """)
61 passwd = raw_input('Enter new winpdb session password: ')
62 ip.db['winpdb_pass'] = passwd
63
64 print "Starting rpdb2 in IPython process"
65 rpdb2.start_embedded_debugger(passwd, timeout = 0)
66 rpdb_started = True
67
68 rpdb2.set_temp_breakpoint(path)
69 print 'It is time to attach with WinPdb (launch WinPdb if needed, File -> Attach)'
70 ip.magic('%run ' + arg)
71
72
73 ip.expose_magic('wdb', wdb_f)
@@ -1,100 +1,102 b''
1 """ User configuration file for IPython
1 """ User configuration file for IPython
2
2
3 This is a more flexible and safe way to configure ipython than *rc files
3 This is a more flexible and safe way to configure ipython than *rc files
4 (ipythonrc, ipythonrc-pysh etc.)
4 (ipythonrc, ipythonrc-pysh etc.)
5
5
6 This file is always imported on ipython startup. You can import the
6 This file is always imported on ipython startup. You can import the
7 ipython extensions you need here (see IPython/Extensions directory).
7 ipython extensions you need here (see IPython/Extensions directory).
8
8
9 Feel free to edit this file to customize your ipython experience.
9 Feel free to edit this file to customize your ipython experience.
10
10
11 Note that as such this file does nothing, for backwards compatibility.
11 Note that as such this file does nothing, for backwards compatibility.
12 Consult e.g. file 'ipy_profile_sh.py' for an example of the things
12 Consult e.g. file 'ipy_profile_sh.py' for an example of the things
13 you can do here.
13 you can do here.
14
14
15 See http://ipython.scipy.org/moin/IpythonExtensionApi for detailed
15 See http://ipython.scipy.org/moin/IpythonExtensionApi for detailed
16 description on what you could do here.
16 description on what you could do here.
17 """
17 """
18
18
19 # Most of your config files and extensions will probably start with this import
19 # Most of your config files and extensions will probably start with this import
20
20
21 import IPython.ipapi
21 import IPython.ipapi
22 ip = IPython.ipapi.get()
22 ip = IPython.ipapi.get()
23
23
24 # You probably want to uncomment this if you did %upgrade -nolegacy
24 # You probably want to uncomment this if you did %upgrade -nolegacy
25 # import ipy_defaults
25 # import ipy_defaults
26
26
27 import os
27 import os
28
28
29 def main():
29 def main():
30
30
31 # uncomment if you want to get ipython -p sh behaviour
31 # uncomment if you want to get ipython -p sh behaviour
32 # without having to use command line switches
32 # without having to use command line switches
33 # import ipy_profile_sh
33 # import ipy_profile_sh
34
34
35 # Configure your favourite editor?
35 # Configure your favourite editor?
36 # Good idea e.g. for %edit os.path.isfile
36 # Good idea e.g. for %edit os.path.isfile
37
37
38 #import ipy_editors
38 #import ipy_editors
39
39
40 # Choose one of these:
40 # Choose one of these:
41
41
42 #ipy_editors.scite()
42 #ipy_editors.scite()
43 #ipy_editors.scite('c:/opt/scite/scite.exe')
43 #ipy_editors.scite('c:/opt/scite/scite.exe')
44 #ipy_editors.komodo()
44 #ipy_editors.komodo()
45 #ipy_editors.idle()
45 #ipy_editors.idle()
46 # ... or many others, try 'ipy_editors??' after import to see them
46 # ... or many others, try 'ipy_editors??' after import to see them
47
47
48 # Or roll your own:
48 # Or roll your own:
49 #ipy_editors.install_editor("c:/opt/jed +$line $file")
49 #ipy_editors.install_editor("c:/opt/jed +$line $file")
50
50
51
51
52 o = ip.options
52 o = ip.options
53 # An example on how to set options
53 # An example on how to set options
54 #o.autocall = 1
54 #o.autocall = 1
55 o.system_verbose = 0
55 o.system_verbose = 0
56
56
57 #import_all("os sys")
57 #import_all("os sys")
58 #execf('~/_ipython/ns.py')
58 #execf('~/_ipython/ns.py')
59
59
60
60
61 # -- prompt
61 # -- prompt
62 # A different, more compact set of prompts from the default ones, that
62 # A different, more compact set of prompts from the default ones, that
63 # always show your current location in the filesystem:
63 # always show your current location in the filesystem:
64
64
65 #o.prompt_in1 = r'\C_LightBlue[\C_LightCyan\Y2\C_LightBlue]\C_Normal\n\C_Green|\#>'
65 #o.prompt_in1 = r'\C_LightBlue[\C_LightCyan\Y2\C_LightBlue]\C_Normal\n\C_Green|\#>'
66 #o.prompt_in2 = r'.\D: '
66 #o.prompt_in2 = r'.\D: '
67 #o.prompt_out = r'[\#] '
67 #o.prompt_out = r'[\#] '
68
68
69 # Try one of these color settings if you can't read the text easily
69 # Try one of these color settings if you can't read the text easily
70 # autoexec is a list of IPython commands to execute on startup
70 # autoexec is a list of IPython commands to execute on startup
71 #o.autoexec.append('%colors LightBG')
71 #o.autoexec.append('%colors LightBG')
72 #o.autoexec.append('%colors NoColor')
72 #o.autoexec.append('%colors NoColor')
73 #o.autoexec.append('%colors Linux')
73 #o.autoexec.append('%colors Linux')
74
74
75 # for sane integer division that converts to float (1/2 == 0.5)
75 # for sane integer division that converts to float (1/2 == 0.5)
76 #o.autoexec.append('from __future__ import division')
76 #o.autoexec.append('from __future__ import division')
77
77
78 # For %tasks and %kill
78 # For %tasks and %kill
79 #import jobctrl
79 #import jobctrl
80
80
81 # For autoreloading of modules (%autoreload, %aimport)
81 # For autoreloading of modules (%autoreload, %aimport)
82 #import ipy_autoreload
82 #import ipy_autoreload
83
83
84 # For winpdb support (%wdb)
84 # For winpdb support (%wdb)
85 #import ipy_winpdb
85 #import ipy_winpdb
86
86
87 # For bzr completer, requires bzrlib (the python installation of bzr)
87 # For bzr completer, requires bzrlib (the python installation of bzr)
88 #import ipy_bzr
88 #import ipy_bzr
89
89
90
91
90 # some config helper functions you can use
92 # some config helper functions you can use
91 def import_all(modules):
93 def import_all(modules):
92 """ Usage: import_all("os sys") """
94 """ Usage: import_all("os sys") """
93 for m in modules.split():
95 for m in modules.split():
94 ip.ex("from %s import *" % m)
96 ip.ex("from %s import *" % m)
95
97
96 def execf(fname):
98 def execf(fname):
97 """ Execute a file in user namespace """
99 """ Execute a file in user namespace """
98 ip.ex('execfile("%s")' % os.path.expanduser(fname))
100 ip.ex('execfile("%s")' % os.path.expanduser(fname))
99
101
100 main()
102 main()
@@ -1,453 +1,436 b''
1 #!/usr/bin/python
1 #!/usr/bin/python
2 # -*- coding: iso-8859-15 -*-
2 # -*- coding: iso-8859-15 -*-
3 '''
3 '''
4 Provides IPython remote instance.
4 Provides IPython remote instance.
5
5
6 @author: Laurent Dufrechou
6 @author: Laurent Dufrechou
7 laurent.dufrechou _at_ gmail.com
7 laurent.dufrechou _at_ gmail.com
8 @license: BSD
8 @license: BSD
9
9
10 All rights reserved. This program and the accompanying materials are made
10 All rights reserved. This program and the accompanying materials are made
11 available under the terms of the BSD which accompanies this distribution, and
11 available under the terms of the BSD which accompanies this distribution, and
12 is available at U{http://www.opensource.org/licenses/bsd-license.php}
12 is available at U{http://www.opensource.org/licenses/bsd-license.php}
13 '''
13 '''
14
14
15 __version__ = 0.9
15 __version__ = 0.9
16 __author__ = "Laurent Dufrechou"
16 __author__ = "Laurent Dufrechou"
17 __email__ = "laurent.dufrechou _at_ gmail.com"
17 __email__ = "laurent.dufrechou _at_ gmail.com"
18 __license__ = "BSD"
18 __license__ = "BSD"
19
19
20 import re
20 import re
21 import sys
21 import sys
22 import os
22 import os
23 import locale
23 import locale
24 import time
24 import time
25 import pydoc,__builtin__,site
25 import pydoc,__builtin__,site
26 from thread_ex import ThreadEx
26 from thread_ex import ThreadEx
27 from StringIO import StringIO
27 from StringIO import StringIO
28
28
29 try:
29 try:
30 import IPython
30 import IPython
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 ##############################################################################
35 class _Helper(object):
35 class _Helper(object):
36 """Redefine the built-in 'help'.
36 """Redefine the built-in 'help'.
37 This is a wrapper around pydoc.help (with a twist).
37 This is a wrapper around pydoc.help (with a twist).
38 """
38 """
39
39
40 def __init__(self,pager):
40 def __init__(self,pager):
41 self._pager = pager
41 self._pager = pager
42
42
43 def __repr__(self):
43 def __repr__(self):
44 return "Type help() for interactive help, " \
44 return "Type help() for interactive help, " \
45 "or help(object) for help about object."
45 "or help(object) for help about object."
46
46
47 def __call__(self, *args, **kwds):
47 def __call__(self, *args, **kwds):
48 class DummyWriter(object):
48 class DummyWriter(object):
49 def __init__(self,pager):
49 def __init__(self,pager):
50 self._pager = pager
50 self._pager = pager
51
51
52 def write(self,data):
52 def write(self,data):
53 self._pager(data)
53 self._pager(data)
54
54
55 import pydoc
55 import pydoc
56 pydoc.help.output = DummyWriter(self._pager)
56 pydoc.help.output = DummyWriter(self._pager)
57 pydoc.help.interact = lambda :1
57 pydoc.help.interact = lambda :1
58
58
59 return pydoc.help(*args, **kwds)
59 return pydoc.help(*args, **kwds)
60
60
61
61
62 ##############################################################################
62 ##############################################################################
63 class _CodeExecutor(ThreadEx):
63 class _CodeExecutor(ThreadEx):
64
64
65 def __init__(self, instance, after):
65 def __init__(self, instance, after):
66 ThreadEx.__init__(self)
66 ThreadEx.__init__(self)
67 self.instance = instance
67 self.instance = instance
68 self._afterExecute=after
68 self._afterExecute=after
69
69
70 def run(self):
70 def run(self):
71 try:
71 try:
72 self.instance._doc_text = None
72 self.instance._doc_text = None
73 self.instance._help_text = None
73 self.instance._help_text = None
74 self.instance._execute()
74 self.instance._execute()
75 # used for uper class to generate event after execution
75 # used for uper class to generate event after execution
76 self._afterExecute()
76 self._afterExecute()
77
77
78 except KeyboardInterrupt:
78 except KeyboardInterrupt:
79 pass
79 pass
80
80
81
81
82 ##############################################################################
82 ##############################################################################
83 class NonBlockingIPShell(object):
83 class NonBlockingIPShell(object):
84 '''
84 '''
85 Create an IPython instance, running the commands in a separate,
85 Create an IPython instance, running the commands in a separate,
86 non-blocking thread.
86 non-blocking thread.
87 This allows embedding in any GUI without blockage.
87 This allows embedding in any GUI without blockage.
88
88
89 Note: The ThreadEx class supports asynchroneous function call
89 Note: The ThreadEx class supports asynchroneous function call
90 via raise_exc()
90 via raise_exc()
91 '''
91 '''
92
92
93 def __init__(self,argv=[],user_ns={},user_global_ns=None,
93 def __init__(self,argv=[],user_ns={},user_global_ns=None,
94 cin=None, cout=None, cerr=None,
94 cin=None, cout=None, cerr=None,
95 ask_exit_handler=None):
95 ask_exit_handler=None, rawinput=None):
96 '''
96 '''
97 @param argv: Command line options for IPython
97 @param argv: Command line options for IPython
98 @type argv: list
98 @type argv: list
99 @param user_ns: User namespace.
99 @param user_ns: User namespace.
100 @type user_ns: dictionary
100 @type user_ns: dictionary
101 @param user_global_ns: User global namespace.
101 @param user_global_ns: User global namespace.
102 @type user_global_ns: dictionary.
102 @type user_global_ns: dictionary.
103 @param cin: Console standard input.
103 @param cin: Console standard input.
104 @type cin: IO stream
104 @type cin: IO stream
105 @param cout: Console standard output.
105 @param cout: Console standard output.
106 @type cout: IO stream
106 @type cout: IO stream
107 @param cerr: Console standard error.
107 @param cerr: Console standard error.
108 @type cerr: IO stream
108 @type cerr: IO stream
109 @param exit_handler: Replacement for builtin exit() function
109 @param exit_handler: Replacement for builtin exit() function
110 @type exit_handler: function
110 @type exit_handler: function
111 @param time_loop: Define the sleep time between two thread's loop
111 @param time_loop: Define the sleep time between two thread's loop
112 @type int
112 @type int
113 '''
113 '''
114 #ipython0 initialisation
114 #ipython0 initialisation
115 self.initIpython0(argv, user_ns, user_global_ns,
115 self.initIpython0(argv, user_ns, user_global_ns,
116 cin, cout, cerr,
116 cin, cout, cerr,
117 ask_exit_handler)
117 ask_exit_handler, rawinput)
118
118
119 #vars used by _execute
119 #vars used by _execute
120 self._iter_more = 0
120 self._iter_more = 0
121 self._history_level = 0
121 self._history_level = 0
122 self._complete_sep = re.compile('[\s\{\}\[\]\(\)]')
122 self._complete_sep = re.compile('[\s\{\}\[\]\(\)]')
123 self._prompt = str(self._IP.outputcache.prompt1).strip()
123 self._prompt = str(self._IP.outputcache.prompt1).strip()
124
124
125 #thread working vars
125 #thread working vars
126 self._line_to_execute = ''
126 self._line_to_execute = ''
127
127
128 #vars that will be checked by GUI loop to handle thread states...
128 #vars that will be checked by GUI loop to handle thread states...
129 #will be replaced later by PostEvent GUI funtions...
129 #will be replaced later by PostEvent GUI funtions...
130 self._doc_text = None
130 self._doc_text = None
131 self._help_text = None
131 self._help_text = None
132 self._add_button = None
132 self._add_button = None
133
133
134 def initIpython0(self, argv=[], user_ns={}, user_global_ns=None,
134 def initIpython0(self, argv=[], user_ns={}, user_global_ns=None,
135 cin=None, cout=None, cerr=None,
135 cin=None, cout=None, cerr=None,
136 ask_exit_handler=None):
136 ask_exit_handler=None, rawinput=None):
137 #first we redefine in/out/error functions of IPython
137 #first we redefine in/out/error functions of IPython
138 if cin:
138 if cin:
139 IPython.Shell.Term.cin = cin
139 IPython.Shell.Term.cin = cin
140 if cout:
140 if cout:
141 IPython.Shell.Term.cout = cout
141 IPython.Shell.Term.cout = cout
142 if cerr:
142 if cerr:
143 IPython.Shell.Term.cerr = cerr
143 IPython.Shell.Term.cerr = cerr
144
144
145 # This is to get rid of the blockage that accurs during
145 # This is to get rid of the blockage that accurs during
146 # IPython.Shell.InteractiveShell.user_setup()
146 # IPython.Shell.InteractiveShell.user_setup()
147 IPython.iplib.raw_input = lambda x: None
147 IPython.iplib.raw_input = lambda x: None
148
148
149 self._term = IPython.genutils.IOTerm(cin=cin, cout=cout, cerr=cerr)
149 self._term = IPython.genutils.IOTerm(cin=cin, cout=cout, cerr=cerr)
150
150
151 excepthook = sys.excepthook
151 excepthook = sys.excepthook
152
152
153 self._IP = IPython.Shell.make_IPython(
153 self._IP = IPython.Shell.make_IPython(
154 argv,user_ns=user_ns,
154 argv,user_ns=user_ns,
155 user_global_ns=user_global_ns,
155 user_global_ns=user_global_ns,
156 embedded=True,
156 embedded=True,
157 shell_class=IPython.Shell.InteractiveShell)
157 shell_class=IPython.Shell.InteractiveShell)
158
158
159 #we replace IPython default encoding by wx locale encoding
159 #we replace IPython default encoding by wx locale encoding
160 loc = locale.getpreferredencoding()
160 loc = locale.getpreferredencoding()
161 if loc:
161 if loc:
162 self._IP.stdin_encoding = loc
162 self._IP.stdin_encoding = loc
163 #we replace the ipython default pager by our pager
163 #we replace the ipython default pager by our pager
164 self._IP.set_hook('show_in_pager',self._pager)
164 self._IP.set_hook('show_in_pager',self._pager)
165
165
166 #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
167 self._IP.set_hook('shell_hook',self._shell)
167 self._IP.set_hook('shell_hook',self._shell)
168
168
169 #we replace the ipython default input command caller by our method
169 #we replace the ipython default input command caller by our method
170 IPython.iplib.raw_input_original = self._raw_input
170 IPython.iplib.raw_input_original = rawinput
171
171 #we replace the ipython default exit command by our method
172 #we replace the ipython default exit command by our method
172 self._IP.exit = ask_exit_handler
173 self._IP.exit = ask_exit_handler
173 #we replace the help command
174 #we replace the help command
174 self._IP.user_ns['help'] = _Helper(self._pager_help)
175 self._IP.user_ns['help'] = _Helper(self._pager_help)
175
176
176 sys.excepthook = excepthook
177 sys.excepthook = excepthook
177
178
178 #----------------------- Thread management section ----------------------
179 #----------------------- Thread management section ----------------------
179 def doExecute(self,line):
180 def doExecute(self,line):
180 """
181 """
181 Tell the thread to process the 'line' command
182 Tell the thread to process the 'line' command
182 """
183 """
183
184
184 self._line_to_execute = line
185 self._line_to_execute = line
185 #we launch the ipython line execution in a thread to make it interruptible
186 #we launch the ipython line execution in a thread to make it interruptible
186 self.ce = _CodeExecutor(self,self._afterExecute)
187 self.ce = _CodeExecutor(self,self._afterExecute)
187 self.ce.start()
188 self.ce.start()
188
189
189 #----------------------- IPython management section ----------------------
190 #----------------------- IPython management section ----------------------
190 def getDocText(self):
191 def getDocText(self):
191 """
192 """
192 Returns the output of the processing that need to be paged (if any)
193 Returns the output of the processing that need to be paged (if any)
193
194
194 @return: The std output string.
195 @return: The std output string.
195 @rtype: string
196 @rtype: string
196 """
197 """
197 return self._doc_text
198 return self._doc_text
198
199
199 def getHelpText(self):
200 def getHelpText(self):
200 """
201 """
201 Returns the output of the processing that need to be paged via help pager(if any)
202 Returns the output of the processing that need to be paged via help pager(if any)
202
203
203 @return: The std output string.
204 @return: The std output string.
204 @rtype: string
205 @rtype: string
205 """
206 """
206 return self._help_text
207 return self._help_text
207
208
208 def getBanner(self):
209 def getBanner(self):
209 """
210 """
210 Returns the IPython banner for useful info on IPython instance
211 Returns the IPython banner for useful info on IPython instance
211
212
212 @return: The banner string.
213 @return: The banner string.
213 @rtype: string
214 @rtype: string
214 """
215 """
215 return self._IP.BANNER
216 return self._IP.BANNER
216
217
217 def getPromptCount(self):
218 def getPromptCount(self):
218 """
219 """
219 Returns the prompt number.
220 Returns the prompt number.
220 Each time a user execute a line in the IPython shell the prompt count is increased
221 Each time a user execute a line in the IPython shell the prompt count is increased
221
222
222 @return: The prompt number
223 @return: The prompt number
223 @rtype: int
224 @rtype: int
224 """
225 """
225 return self._IP.outputcache.prompt_count
226 return self._IP.outputcache.prompt_count
226
227
227 def getPrompt(self):
228 def getPrompt(self):
228 """
229 """
229 Returns current prompt inside IPython instance
230 Returns current prompt inside IPython instance
230 (Can be In [...]: ot ...:)
231 (Can be In [...]: ot ...:)
231
232
232 @return: The current prompt.
233 @return: The current prompt.
233 @rtype: string
234 @rtype: string
234 """
235 """
235 return self._prompt
236 return self._prompt
236
237
237 def getIndentation(self):
238 def getIndentation(self):
238 """
239 """
239 Returns the current indentation level
240 Returns the current indentation level
240 Usefull to put the caret at the good start position if we want to do autoindentation.
241 Usefull to put the caret at the good start position if we want to do autoindentation.
241
242
242 @return: The indentation level.
243 @return: The indentation level.
243 @rtype: int
244 @rtype: int
244 """
245 """
245 return self._IP.indent_current_nsp
246 return self._IP.indent_current_nsp
246
247
247 def updateNamespace(self, ns_dict):
248 def updateNamespace(self, ns_dict):
248 '''
249 '''
249 Add the current dictionary to the shell namespace.
250 Add the current dictionary to the shell namespace.
250
251
251 @param ns_dict: A dictionary of symbol-values.
252 @param ns_dict: A dictionary of symbol-values.
252 @type ns_dict: dictionary
253 @type ns_dict: dictionary
253 '''
254 '''
254 self._IP.user_ns.update(ns_dict)
255 self._IP.user_ns.update(ns_dict)
255
256
256 def complete(self, line):
257 def complete(self, line):
257 '''
258 '''
258 Returns an auto completed line and/or posibilities for completion.
259 Returns an auto completed line and/or posibilities for completion.
259
260
260 @param line: Given line so far.
261 @param line: Given line so far.
261 @type line: string
262 @type line: string
262
263
263 @return: Line completed as for as possible,
264 @return: Line completed as for as possible,
264 and possible further completions.
265 and possible further completions.
265 @rtype: tuple
266 @rtype: tuple
266 '''
267 '''
267 split_line = self._complete_sep.split(line)
268 split_line = self._complete_sep.split(line)
268 possibilities = self._IP.complete(split_line[-1])
269 possibilities = self._IP.complete(split_line[-1])
269 if possibilities:
270 if possibilities:
270
271
271 def _commonPrefix(str1, str2):
272 def _commonPrefix(str1, str2):
272 '''
273 '''
273 Reduction function. returns common prefix of two given strings.
274 Reduction function. returns common prefix of two given strings.
274
275
275 @param str1: First string.
276 @param str1: First string.
276 @type str1: string
277 @type str1: string
277 @param str2: Second string
278 @param str2: Second string
278 @type str2: string
279 @type str2: string
279
280
280 @return: Common prefix to both strings.
281 @return: Common prefix to both strings.
281 @rtype: string
282 @rtype: string
282 '''
283 '''
283 for i in range(len(str1)):
284 for i in range(len(str1)):
284 if not str2.startswith(str1[:i+1]):
285 if not str2.startswith(str1[:i+1]):
285 return str1[:i]
286 return str1[:i]
286 return str1
287 return str1
287 common_prefix = reduce(_commonPrefix, possibilities)
288 common_prefix = reduce(_commonPrefix, possibilities)
288 completed = line[:-len(split_line[-1])]+common_prefix
289 completed = line[:-len(split_line[-1])]+common_prefix
289 else:
290 else:
290 completed = line
291 completed = line
291 return completed, possibilities
292 return completed, possibilities
292
293
293 def historyBack(self):
294 def historyBack(self):
294 '''
295 '''
295 Provides one history command back.
296 Provides one history command back.
296
297
297 @return: The command string.
298 @return: The command string.
298 @rtype: string
299 @rtype: string
299 '''
300 '''
300 history = ''
301 history = ''
301 #the below while loop is used to suppress empty history lines
302 #the below while loop is used to suppress empty history lines
302 while((history == '' or history == '\n') and self._history_level >0):
303 while((history == '' or history == '\n') and self._history_level >0):
303 if self._history_level>=1:
304 if self._history_level>=1:
304 self._history_level -= 1
305 self._history_level -= 1
305 history = self._getHistory()
306 history = self._getHistory()
306 return history
307 return history
307
308
308 def historyForward(self):
309 def historyForward(self):
309 '''
310 '''
310 Provides one history command forward.
311 Provides one history command forward.
311
312
312 @return: The command string.
313 @return: The command string.
313 @rtype: string
314 @rtype: string
314 '''
315 '''
315 history = ''
316 history = ''
316 #the below while loop is used to suppress empty history lines
317 #the below while loop is used to suppress empty history lines
317 while((history == '' or history == '\n') and self._history_level <= self._getHistoryMaxIndex()):
318 while((history == '' or history == '\n') and self._history_level <= self._getHistoryMaxIndex()):
318 if self._history_level < self._getHistoryMaxIndex():
319 if self._history_level < self._getHistoryMaxIndex():
319 self._history_level += 1
320 self._history_level += 1
320 history = self._getHistory()
321 history = self._getHistory()
321 else:
322 else:
322 if self._history_level == self._getHistoryMaxIndex():
323 if self._history_level == self._getHistoryMaxIndex():
323 history = self._getHistory()
324 history = self._getHistory()
324 self._history_level += 1
325 self._history_level += 1
325 else:
326 else:
326 history = ''
327 history = ''
327 return history
328 return history
328
329
329 def initHistoryIndex(self):
330 def initHistoryIndex(self):
330 '''
331 '''
331 set history to last command entered
332 set history to last command entered
332 '''
333 '''
333 self._history_level = self._getHistoryMaxIndex()+1
334 self._history_level = self._getHistoryMaxIndex()+1
334
335
335 #----------------------- IPython PRIVATE management section --------------
336 #----------------------- IPython PRIVATE management section --------------
336 def _afterExecute(self):
337 def _afterExecute(self):
337 '''
338 '''
338 Can be redefined to generate post event after excution is done
339 Can be redefined to generate post event after excution is done
339 '''
340 '''
340 pass
341 pass
341
342
342 #def _askExit(self):
343 # '''
344 # Can be redefined to generate post event to exit the Ipython shell
345 # '''
346 # pass
347
348 def _getHistoryMaxIndex(self):
343 def _getHistoryMaxIndex(self):
349 '''
344 '''
350 returns the max length of the history buffer
345 returns the max length of the history buffer
351
346
352 @return: history length
347 @return: history length
353 @rtype: int
348 @rtype: int
354 '''
349 '''
355 return len(self._IP.input_hist_raw)-1
350 return len(self._IP.input_hist_raw)-1
356
351
357 def _getHistory(self):
352 def _getHistory(self):
358 '''
353 '''
359 Get's the command string of the current history level.
354 Get's the command string of the current history level.
360
355
361 @return: Historic command stri
356 @return: Historic command stri
362 @rtype: string
357 @rtype: string
363 '''
358 '''
364 rv = self._IP.input_hist_raw[self._history_level].strip('\n')
359 rv = self._IP.input_hist_raw[self._history_level].strip('\n')
365 return rv
360 return rv
366
361
367 def _pager_help(self,text):
362 def _pager_help(self,text):
368 '''
363 '''
369 This function is used as a callback replacment to IPython help pager function
364 This function is used as a callback replacment to IPython help pager function
370
365
371 It puts the 'text' value inside the self._help_text string that can be retrived via getHelpText
366 It puts the 'text' value inside the self._help_text string that can be retrived via getHelpText
372 function.
367 function.
373 '''
368 '''
374 if self._help_text == None:
369 if self._help_text == None:
375 self._help_text = text
370 self._help_text = text
376 else:
371 else:
377 self._help_text += text
372 self._help_text += text
378
373
379 def _pager(self,IP,text):
374 def _pager(self,IP,text):
380 '''
375 '''
381 This function is used as a callback replacment to IPython pager function
376 This function is used as a callback replacment to IPython pager function
382
377
383 It puts the 'text' value inside the self._doc_text string that can be retrived via getDocText
378 It puts the 'text' value inside the self._doc_text string that can be retrived via getDocText
384 function.
379 function.
385 '''
380 '''
386 self._doc_text = text
381 self._doc_text = text
387
382
388 def _raw_input(self, prompt=''):
389 '''
390 Custom raw_input() replacement. Get's current line from console buffer.
391
392 @param prompt: Prompt to print. Here for compatability as replacement.
393 @type prompt: string
394
395 @return: The current command line text.
396 @rtype: string
397 '''
398 return self._line_to_execute
399
400 def _execute(self):
383 def _execute(self):
401 '''
384 '''
402 Executes the current line provided by the shell object.
385 Executes the current line provided by the shell object.
403 '''
386 '''
404 orig_stdout = sys.stdout
387 orig_stdout = sys.stdout
405 sys.stdout = IPython.Shell.Term.cout
388 sys.stdout = IPython.Shell.Term.cout
406
389
407 try:
390 try:
408 line = self._IP.raw_input(None, self._iter_more)
391 line = self._IP.raw_input(None, self._iter_more)
409 if self._IP.autoindent:
392 if self._IP.autoindent:
410 self._IP.readline_startup_hook(None)
393 self._IP.readline_startup_hook(None)
411
394
412 except KeyboardInterrupt:
395 except KeyboardInterrupt:
413 self._IP.write('\nKeyboardInterrupt\n')
396 self._IP.write('\nKeyboardInterrupt\n')
414 self._IP.resetbuffer()
397 self._IP.resetbuffer()
415 # keep cache in sync with the prompt counter:
398 # keep cache in sync with the prompt counter:
416 self._IP.outputcache.prompt_count -= 1
399 self._IP.outputcache.prompt_count -= 1
417
400
418 if self._IP.autoindent:
401 if self._IP.autoindent:
419 self._IP.indent_current_nsp = 0
402 self._IP.indent_current_nsp = 0
420 self._iter_more = 0
403 self._iter_more = 0
421 except:
404 except:
422 self._IP.showtraceback()
405 self._IP.showtraceback()
423 else:
406 else:
424 self._iter_more = self._IP.push(line)
407 self._iter_more = self._IP.push(line)
425 if (self._IP.SyntaxTB.last_syntax_error and
408 if (self._IP.SyntaxTB.last_syntax_error and
426 self._IP.rc.autoedit_syntax):
409 self._IP.rc.autoedit_syntax):
427 self._IP.edit_syntax_error()
410 self._IP.edit_syntax_error()
428 if self._iter_more:
411 if self._iter_more:
429 self._prompt = str(self._IP.outputcache.prompt2).strip()
412 self._prompt = str(self._IP.outputcache.prompt2).strip()
430 if self._IP.autoindent:
413 if self._IP.autoindent:
431 self._IP.readline_startup_hook(self._IP.pre_readline)
414 self._IP.readline_startup_hook(self._IP.pre_readline)
432 else:
415 else:
433 self._prompt = str(self._IP.outputcache.prompt1).strip()
416 self._prompt = str(self._IP.outputcache.prompt1).strip()
434 self._IP.indent_current_nsp = 0 #we set indentation to 0
417 self._IP.indent_current_nsp = 0 #we set indentation to 0
435 sys.stdout = orig_stdout
418 sys.stdout = orig_stdout
436
419
437 def _shell(self, ip, cmd):
420 def _shell(self, ip, cmd):
438 '''
421 '''
439 Replacement method to allow shell commands without them blocking.
422 Replacement method to allow shell commands without them blocking.
440
423
441 @param ip: Ipython instance, same as self._IP
424 @param ip: Ipython instance, same as self._IP
442 @type cmd: Ipython instance
425 @type cmd: Ipython instance
443 @param cmd: Shell command to execute.
426 @param cmd: Shell command to execute.
444 @type cmd: string
427 @type cmd: string
445 '''
428 '''
446 stdin, stdout = os.popen4(cmd)
429 stdin, stdout = os.popen4(cmd)
447 result = stdout.read().decode('cp437').encode(locale.getpreferredencoding())
430 result = stdout.read().decode('cp437').encode(locale.getpreferredencoding())
448 #we use print command because the shell command is called inside IPython instance and thus is
431 #we use print command because the shell command is called inside IPython instance and thus is
449 #redirected to thread cout
432 #redirected to thread cout
450 #"\x01\x1b[1;36m\x02" <-- add colour to the text...
433 #"\x01\x1b[1;36m\x02" <-- add colour to the text...
451 print "\x01\x1b[1;36m\x02"+result
434 print "\x01\x1b[1;36m\x02"+result
452 stdout.close()
435 stdout.close()
453 stdin.close()
436 stdin.close()
@@ -1,729 +1,735 b''
1 #!/usr/bin/python
1 #!/usr/bin/python
2 # -*- coding: iso-8859-15 -*-
2 # -*- coding: iso-8859-15 -*-
3 '''
3 '''
4 Provides IPython WX console widgets.
4 Provides IPython WX console widgets.
5
5
6 @author: Laurent Dufrechou
6 @author: Laurent Dufrechou
7 laurent.dufrechou _at_ gmail.com
7 laurent.dufrechou _at_ gmail.com
8 This WX widget is based on the original work of Eitan Isaacson
8 This WX widget is based on the original work of Eitan Isaacson
9 that provided the console for the GTK toolkit.
9 that provided the console for the GTK toolkit.
10
10
11 Original work from:
11 Original work from:
12 @author: Eitan Isaacson
12 @author: Eitan Isaacson
13 @organization: IBM Corporation
13 @organization: IBM Corporation
14 @copyright: Copyright (c) 2007 IBM Corporation
14 @copyright: Copyright (c) 2007 IBM Corporation
15 @license: BSD
15 @license: BSD
16
16
17 All rights reserved. This program and the accompanying materials are made
17 All rights reserved. This program and the accompanying materials are made
18 available under the terms of the BSD which accompanies this distribution, and
18 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.8
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"
26
26
27 import wx
27 import wx
28 import wx.stc as stc
28 import wx.stc as stc
29 import wx.lib.newevent
29 import wx.lib.newevent
30
30
31 import re
31 import re
32 import sys
32 import sys
33 import locale
33 import locale
34 from StringIO import StringIO
34 from StringIO import StringIO
35 try:
35 try:
36 import IPython
36 import IPython
37 except Exception,e:
37 except Exception,e:
38 raise "Error importing IPython (%s)" % str(e)
38 raise "Error importing IPython (%s)" % str(e)
39
39
40 from ipshell_nonblocking import NonBlockingIPShell
40 from ipshell_nonblocking import NonBlockingIPShell
41
41
42
42
43 class WxNonBlockingIPShell(NonBlockingIPShell):
43 class WxNonBlockingIPShell(NonBlockingIPShell):
44 '''
44 '''
45 An NonBlockingIPShell Thread that is WX dependent.
45 An NonBlockingIPShell Thread that is WX dependent.
46 '''
46 '''
47 def __init__(self, parent,
47 def __init__(self, parent,
48 argv=[],user_ns={},user_global_ns=None,
48 argv=[],user_ns={},user_global_ns=None,
49 cin=None, cout=None, cerr=None,
49 cin=None, cout=None, cerr=None,
50 ask_exit_handler=None):
50 ask_exit_handler=None, rawinput=None):
51
51
52 NonBlockingIPShell.__init__(self,argv,user_ns,user_global_ns,
52 NonBlockingIPShell.__init__(self,argv,user_ns,user_global_ns,
53 cin, cout, cerr,
53 cin, cout, cerr,
54 ask_exit_handler)
54 ask_exit_handler,
55 rawinput)
55
56
56 self.parent = parent
57 self.parent = parent
57
58
58 self.ask_exit_callback = ask_exit_handler
59 self.ask_exit_callback = ask_exit_handler
59 self._IP.exit = self._askExit
60 self._IP.exit = self._askExit
60
61
61 def addGUIShortcut(self,text,func):
62 def addGUIShortcut(self,text,func):
62 wx.CallAfter(self.parent.add_button_handler,
63 wx.CallAfter(self.parent.add_button_handler,
63 button_info={ 'text':text,
64 button_info={ 'text':text,
64 'func':self.parent.doExecuteLine(func)})
65 'func':self.parent.doExecuteLine(func)})
65
66
66 def _askExit(self):
67 def _askExit(self):
67 wx.CallAfter(self.ask_exit_callback, ())
68 wx.CallAfter(self.ask_exit_callback, ())
68
69
69 def _afterExecute(self):
70 def _afterExecute(self):
70 wx.CallAfter(self.parent.evtStateExecuteDone, ())
71 wx.CallAfter(self.parent.evtStateExecuteDone, ())
71
72
72
73
73 class WxConsoleView(stc.StyledTextCtrl):
74 class WxConsoleView(stc.StyledTextCtrl):
74 '''
75 '''
75 Specialized styled text control view for console-like workflow.
76 Specialized styled text control view for console-like workflow.
76 We use here a scintilla frontend thus it can be reused in any GUI that
77 We use here a scintilla frontend thus it can be reused in any GUI that
77 supports scintilla with less work.
78 supports scintilla with less work.
78
79
79 @cvar ANSI_COLORS_BLACK: Mapping of terminal colors to X11 names.
80 @cvar ANSI_COLORS_BLACK: Mapping of terminal colors to X11 names.
80 (with Black background)
81 (with Black background)
81 @type ANSI_COLORS_BLACK: dictionary
82 @type ANSI_COLORS_BLACK: dictionary
82
83
83 @cvar ANSI_COLORS_WHITE: Mapping of terminal colors to X11 names.
84 @cvar ANSI_COLORS_WHITE: Mapping of terminal colors to X11 names.
84 (with White background)
85 (with White background)
85 @type ANSI_COLORS_WHITE: dictionary
86 @type ANSI_COLORS_WHITE: dictionary
86
87
87 @ivar color_pat: Regex of terminal color pattern
88 @ivar color_pat: Regex of terminal color pattern
88 @type color_pat: _sre.SRE_Pattern
89 @type color_pat: _sre.SRE_Pattern
89 '''
90 '''
90 ANSI_STYLES_BLACK={'0;30': [0,'WHITE'], '0;31': [1,'RED'],
91 ANSI_STYLES_BLACK={'0;30': [0,'WHITE'], '0;31': [1,'RED'],
91 '0;32': [2,'GREEN'], '0;33': [3,'BROWN'],
92 '0;32': [2,'GREEN'], '0;33': [3,'BROWN'],
92 '0;34': [4,'BLUE'], '0;35': [5,'PURPLE'],
93 '0;34': [4,'BLUE'], '0;35': [5,'PURPLE'],
93 '0;36': [6,'CYAN'], '0;37': [7,'LIGHT GREY'],
94 '0;36': [6,'CYAN'], '0;37': [7,'LIGHT GREY'],
94 '1;30': [8,'DARK GREY'], '1;31': [9,'RED'],
95 '1;30': [8,'DARK GREY'], '1;31': [9,'RED'],
95 '1;32': [10,'SEA GREEN'], '1;33': [11,'YELLOW'],
96 '1;32': [10,'SEA GREEN'], '1;33': [11,'YELLOW'],
96 '1;34': [12,'LIGHT BLUE'], '1;35':
97 '1;34': [12,'LIGHT BLUE'], '1;35':
97 [13,'MEDIUM VIOLET RED'],
98 [13,'MEDIUM VIOLET RED'],
98 '1;36': [14,'LIGHT STEEL BLUE'],'1;37': [15,'YELLOW']}
99 '1;36': [14,'LIGHT STEEL BLUE'],'1;37': [15,'YELLOW']}
99
100
100 ANSI_STYLES_WHITE={'0;30': [0,'BLACK'], '0;31': [1,'RED'],
101 ANSI_STYLES_WHITE={'0;30': [0,'BLACK'], '0;31': [1,'RED'],
101 '0;32': [2,'GREEN'], '0;33': [3,'BROWN'],
102 '0;32': [2,'GREEN'], '0;33': [3,'BROWN'],
102 '0;34': [4,'BLUE'], '0;35': [5,'PURPLE'],
103 '0;34': [4,'BLUE'], '0;35': [5,'PURPLE'],
103 '0;36': [6,'CYAN'], '0;37': [7,'LIGHT GREY'],
104 '0;36': [6,'CYAN'], '0;37': [7,'LIGHT GREY'],
104 '1;30': [8,'DARK GREY'], '1;31': [9,'RED'],
105 '1;30': [8,'DARK GREY'], '1;31': [9,'RED'],
105 '1;32': [10,'SEA GREEN'], '1;33': [11,'YELLOW'],
106 '1;32': [10,'SEA GREEN'], '1;33': [11,'YELLOW'],
106 '1;34': [12,'LIGHT BLUE'], '1;35':
107 '1;34': [12,'LIGHT BLUE'], '1;35':
107 [13,'MEDIUM VIOLET RED'],
108 [13,'MEDIUM VIOLET RED'],
108 '1;36': [14,'LIGHT STEEL BLUE'],'1;37': [15,'YELLOW']}
109 '1;36': [14,'LIGHT STEEL BLUE'],'1;37': [15,'YELLOW']}
109
110
110 def __init__(self,parent,prompt,intro="",background_color="BLACK",
111 def __init__(self,parent,prompt,intro="",background_color="BLACK",
111 pos=wx.DefaultPosition, ID = -1, size=wx.DefaultSize,
112 pos=wx.DefaultPosition, ID = -1, size=wx.DefaultSize,
112 style=0):
113 style=0):
113 '''
114 '''
114 Initialize console view.
115 Initialize console view.
115
116
116 @param parent: Parent widget
117 @param parent: Parent widget
117 @param prompt: User specified prompt
118 @param prompt: User specified prompt
118 @type intro: string
119 @type intro: string
119 @param intro: User specified startup introduction string
120 @param intro: User specified startup introduction string
120 @type intro: string
121 @type intro: string
121 @param background_color: Can be BLACK or WHITE
122 @param background_color: Can be BLACK or WHITE
122 @type background_color: string
123 @type background_color: string
123 @param other: init param of styledTextControl (can be used as-is)
124 @param other: init param of styledTextControl (can be used as-is)
124 '''
125 '''
125 stc.StyledTextCtrl.__init__(self, parent, ID, pos, size, style)
126 stc.StyledTextCtrl.__init__(self, parent, ID, pos, size, style)
126
127
127 ####### Scintilla configuration ###################################
128 ####### Scintilla configuration ###################################
128
129
129 # Ctrl + B or Ctrl + N can be used to zoomin/zoomout the text inside
130 # Ctrl + B or Ctrl + N can be used to zoomin/zoomout the text inside
130 # the widget
131 # the widget
131 self.CmdKeyAssign(ord('B'), stc.STC_SCMOD_CTRL, stc.STC_CMD_ZOOMIN)
132 self.CmdKeyAssign(ord('B'), stc.STC_SCMOD_CTRL, stc.STC_CMD_ZOOMIN)
132 self.CmdKeyAssign(ord('N'), stc.STC_SCMOD_CTRL, stc.STC_CMD_ZOOMOUT)
133 self.CmdKeyAssign(ord('N'), stc.STC_SCMOD_CTRL, stc.STC_CMD_ZOOMOUT)
133
134
134 #we define platform specific fonts
135 #we define platform specific fonts
135 if wx.Platform == '__WXMSW__':
136 if wx.Platform == '__WXMSW__':
136 faces = { 'times': 'Times New Roman',
137 faces = { 'times': 'Times New Roman',
137 'mono' : 'Courier New',
138 'mono' : 'Courier New',
138 'helv' : 'Arial',
139 'helv' : 'Arial',
139 'other': 'Comic Sans MS',
140 'other': 'Comic Sans MS',
140 'size' : 10,
141 'size' : 10,
141 'size2': 8,
142 'size2': 8,
142 }
143 }
143 elif wx.Platform == '__WXMAC__':
144 elif wx.Platform == '__WXMAC__':
144 faces = { 'times': 'Times New Roman',
145 faces = { 'times': 'Times New Roman',
145 'mono' : 'Monaco',
146 'mono' : 'Monaco',
146 'helv' : 'Arial',
147 'helv' : 'Arial',
147 'other': 'Comic Sans MS',
148 'other': 'Comic Sans MS',
148 'size' : 10,
149 'size' : 10,
149 'size2': 8,
150 'size2': 8,
150 }
151 }
151 else:
152 else:
152 faces = { 'times': 'Times',
153 faces = { 'times': 'Times',
153 'mono' : 'Courier',
154 'mono' : 'Courier',
154 'helv' : 'Helvetica',
155 'helv' : 'Helvetica',
155 'other': 'new century schoolbook',
156 'other': 'new century schoolbook',
156 'size' : 10,
157 'size' : 10,
157 'size2': 8,
158 'size2': 8,
158 }
159 }
159
160
160 #We draw a line at position 80
161 #We draw a line at position 80
161 self.SetEdgeMode(stc.STC_EDGE_LINE)
162 self.SetEdgeMode(stc.STC_EDGE_LINE)
162 self.SetEdgeColumn(80)
163 self.SetEdgeColumn(80)
163 self.SetEdgeColour(wx.LIGHT_GREY)
164 self.SetEdgeColour(wx.LIGHT_GREY)
164
165
165 #self.SetViewWhiteSpace(True)
166 #self.SetViewWhiteSpace(True)
166 #self.SetViewEOL(True)
167 #self.SetViewEOL(True)
167 self.SetEOLMode(stc.STC_EOL_CRLF)
168 self.SetEOLMode(stc.STC_EOL_CRLF)
168 #self.SetWrapMode(stc.STC_WRAP_CHAR)
169 #self.SetWrapMode(stc.STC_WRAP_CHAR)
169 #self.SetWrapMode(stc.STC_WRAP_WORD)
170 #self.SetWrapMode(stc.STC_WRAP_WORD)
170 self.SetBufferedDraw(True)
171 self.SetBufferedDraw(True)
171 #self.SetUseAntiAliasing(True)
172 #self.SetUseAntiAliasing(True)
172 self.SetLayoutCache(stc.STC_CACHE_PAGE)
173 self.SetLayoutCache(stc.STC_CACHE_PAGE)
173
174
174 self.EnsureCaretVisible()
175 self.EnsureCaretVisible()
175
176
176 self.SetMargins(3,3) #text is moved away from border with 3px
177 self.SetMargins(3,3) #text is moved away from border with 3px
177 # Suppressing Scintilla margins
178 # Suppressing Scintilla margins
178 self.SetMarginWidth(0,0)
179 self.SetMarginWidth(0,0)
179 self.SetMarginWidth(1,0)
180 self.SetMarginWidth(1,0)
180 self.SetMarginWidth(2,0)
181 self.SetMarginWidth(2,0)
181
182
182 # make some styles
183 # make some styles
183 if background_color != "BLACK":
184 if background_color != "BLACK":
184 self.background_color = "WHITE"
185 self.background_color = "WHITE"
185 self.SetCaretForeground("BLACK")
186 self.SetCaretForeground("BLACK")
186 self.ANSI_STYLES = self.ANSI_STYLES_WHITE
187 self.ANSI_STYLES = self.ANSI_STYLES_WHITE
187 else:
188 else:
188 self.background_color = background_color
189 self.background_color = background_color
189 self.SetCaretForeground("WHITE")
190 self.SetCaretForeground("WHITE")
190 self.ANSI_STYLES = self.ANSI_STYLES_BLACK
191 self.ANSI_STYLES = self.ANSI_STYLES_BLACK
191
192
192 self.StyleSetSpec(stc.STC_STYLE_DEFAULT,
193 self.StyleSetSpec(stc.STC_STYLE_DEFAULT,
193 "fore:%s,back:%s,size:%d,face:%s"
194 "fore:%s,back:%s,size:%d,face:%s"
194 % (self.ANSI_STYLES['0;30'][1],
195 % (self.ANSI_STYLES['0;30'][1],
195 self.background_color,
196 self.background_color,
196 faces['size'], faces['mono']))
197 faces['size'], faces['mono']))
197 self.StyleClearAll()
198 self.StyleClearAll()
198 self.StyleSetSpec(stc.STC_STYLE_BRACELIGHT,
199 self.StyleSetSpec(stc.STC_STYLE_BRACELIGHT,
199 "fore:#FF0000,back:#0000FF,bold")
200 "fore:#FF0000,back:#0000FF,bold")
200 self.StyleSetSpec(stc.STC_STYLE_BRACEBAD,
201 self.StyleSetSpec(stc.STC_STYLE_BRACEBAD,
201 "fore:#000000,back:#FF0000,bold")
202 "fore:#000000,back:#FF0000,bold")
202
203
203 for style in self.ANSI_STYLES.values():
204 for style in self.ANSI_STYLES.values():
204 self.StyleSetSpec(style[0], "bold,fore:%s" % style[1])
205 self.StyleSetSpec(style[0], "bold,fore:%s" % style[1])
205
206
206 #######################################################################
207 #######################################################################
207
208
208 self.indent = 0
209 self.indent = 0
209 self.prompt_count = 0
210 self.prompt_count = 0
210 self.color_pat = re.compile('\x01?\x1b\[(.*?)m\x02?')
211 self.color_pat = re.compile('\x01?\x1b\[(.*?)m\x02?')
211
212
212 self.write(intro)
213 self.write(intro)
213 self.setPrompt(prompt)
214 self.setPrompt(prompt)
214 self.showPrompt()
215 self.showPrompt()
215
216
216 self.Bind(wx.EVT_KEY_DOWN, self._onKeypress, self)
217 self.Bind(wx.EVT_KEY_DOWN, self._onKeypress, self)
217
218
218 def write(self, text):
219 def write(self, text):
219 '''
220 '''
220 Write given text to buffer.
221 Write given text to buffer.
221
222
222 @param text: Text to append.
223 @param text: Text to append.
223 @type text: string
224 @type text: string
224 '''
225 '''
225 segments = self.color_pat.split(text)
226 segments = self.color_pat.split(text)
226 segment = segments.pop(0)
227 segment = segments.pop(0)
227 self.StartStyling(self.getCurrentLineEnd(),0xFF)
228 self.StartStyling(self.getCurrentLineEnd(),0xFF)
228 self.AppendText(segment)
229 self.AppendText(segment)
229
230
230 if segments:
231 if segments:
231 ansi_tags = self.color_pat.findall(text)
232 ansi_tags = self.color_pat.findall(text)
232
233
233 for tag in ansi_tags:
234 for tag in ansi_tags:
234 i = segments.index(tag)
235 i = segments.index(tag)
235 self.StartStyling(self.getCurrentLineEnd(),0xFF)
236 self.StartStyling(self.getCurrentLineEnd(),0xFF)
236 self.AppendText(segments[i+1])
237 self.AppendText(segments[i+1])
237
238
238 if tag != '0':
239 if tag != '0':
239 self.SetStyling(len(segments[i+1]),self.ANSI_STYLES[tag][0])
240 self.SetStyling(len(segments[i+1]),self.ANSI_STYLES[tag][0])
240
241
241 segments.pop(i)
242 segments.pop(i)
242
243
243 self.moveCursor(self.getCurrentLineEnd())
244 self.moveCursor(self.getCurrentLineEnd())
244
245
245 def getPromptLen(self):
246 def getPromptLen(self):
246 '''
247 '''
247 Return the length of current prompt
248 Return the length of current prompt
248 '''
249 '''
249 return len(str(self.prompt_count)) + 7
250 return len(str(self.prompt_count)) + 7
250
251
251 def setPrompt(self,prompt):
252 def setPrompt(self,prompt):
252 self.prompt = prompt
253 self.prompt = prompt
253
254
254 def setIndentation(self,indentation):
255 def setIndentation(self,indentation):
255 self.indent = indentation
256 self.indent = indentation
256
257
257 def setPromptCount(self,count):
258 def setPromptCount(self,count):
258 self.prompt_count = count
259 self.prompt_count = count
259
260
260 def showPrompt(self):
261 def showPrompt(self):
261 '''
262 '''
262 Prints prompt at start of line.
263 Prints prompt at start of line.
263
264
264 @param prompt: Prompt to print.
265 @param prompt: Prompt to print.
265 @type prompt: string
266 @type prompt: string
266 '''
267 '''
267 self.write(self.prompt)
268 self.write(self.prompt)
268 #now we update the position of end of prompt
269 #now we update the position of end of prompt
269 self.current_start = self.getCurrentLineEnd()
270 self.current_start = self.getCurrentLineEnd()
270
271
271 autoindent = self.indent*' '
272 autoindent = self.indent*' '
272 autoindent = autoindent.replace(' ','\t')
273 autoindent = autoindent.replace(' ','\t')
273 self.write(autoindent)
274 self.write(autoindent)
274
275
275 def changeLine(self, text):
276 def changeLine(self, text):
276 '''
277 '''
277 Replace currently entered command line with given text.
278 Replace currently entered command line with given text.
278
279
279 @param text: Text to use as replacement.
280 @param text: Text to use as replacement.
280 @type text: string
281 @type text: string
281 '''
282 '''
282 self.SetSelection(self.getCurrentPromptStart(),self.getCurrentLineEnd())
283 self.SetSelection(self.getCurrentPromptStart(),self.getCurrentLineEnd())
283 self.ReplaceSelection(text)
284 self.ReplaceSelection(text)
284 self.moveCursor(self.getCurrentLineEnd())
285 self.moveCursor(self.getCurrentLineEnd())
285
286
286 def getCurrentPromptStart(self):
287 def getCurrentPromptStart(self):
287 return self.current_start
288 return self.current_start
288
289
289 def getCurrentLineStart(self):
290 def getCurrentLineStart(self):
290 return self.GotoLine(self.LineFromPosition(self.GetCurrentPos()))
291 return self.GotoLine(self.LineFromPosition(self.GetCurrentPos()))
291
292
292 def getCurrentLineEnd(self):
293 def getCurrentLineEnd(self):
293 return self.GetLength()
294 return self.GetLength()
294
295
295 def getCurrentLine(self):
296 def getCurrentLine(self):
296 '''
297 '''
297 Get text in current command line.
298 Get text in current command line.
298
299
299 @return: Text of current command line.
300 @return: Text of current command line.
300 @rtype: string
301 @rtype: string
301 '''
302 '''
302 return self.GetTextRange(self.getCurrentPromptStart(),
303 return self.GetTextRange(self.getCurrentPromptStart(),
303 self.getCurrentLineEnd())
304 self.getCurrentLineEnd())
304
305
305 def showReturned(self, text):
306 '''
307 Show returned text from last command and print new prompt.
308
309 @param text: Text to show.
310 @type text: string
311 '''
312 self.write('\n'+text)
313 if text:
314 self.write('\n')
315 self.showPrompt()
316
317 def moveCursorOnNewValidKey(self):
306 def moveCursorOnNewValidKey(self):
318 #If cursor is at wrong position put it at last line...
307 #If cursor is at wrong position put it at last line...
319 if self.GetCurrentPos() < self.getCurrentPromptStart():
308 if self.GetCurrentPos() < self.getCurrentPromptStart():
320 self.GotoPos(self.getCurrentPromptStart())
309 self.GotoPos(self.getCurrentPromptStart())
321
310
322 def removeFromTo(self,from_pos,to_pos):
311 def removeFromTo(self,from_pos,to_pos):
323 if from_pos < to_pos:
312 if from_pos < to_pos:
324 self.SetSelection(from_pos,to_pos)
313 self.SetSelection(from_pos,to_pos)
325 self.DeleteBack()
314 self.DeleteBack()
326
315
327 def removeCurrentLine(self):
316 def removeCurrentLine(self):
328 self.LineDelete()
317 self.LineDelete()
329
318
330 def moveCursor(self,position):
319 def moveCursor(self,position):
331 self.GotoPos(position)
320 self.GotoPos(position)
332
321
333 def getCursorPos(self):
322 def getCursorPos(self):
334 return self.GetCurrentPos()
323 return self.GetCurrentPos()
335
324
336 def selectFromTo(self,from_pos,to_pos):
325 def selectFromTo(self,from_pos,to_pos):
337 self.SetSelectionStart(from_pos)
326 self.SetSelectionStart(from_pos)
338 self.SetSelectionEnd(to_pos)
327 self.SetSelectionEnd(to_pos)
339
328
340 def writeHistory(self,history):
329 def writeHistory(self,history):
341 self.removeFromTo(self.getCurrentPromptStart(),self.getCurrentLineEnd())
330 self.removeFromTo(self.getCurrentPromptStart(),self.getCurrentLineEnd())
342 self.changeLine(history)
331 self.changeLine(history)
343
332
344 def writeCompletion(self, possibilities):
333 def writeCompletion(self, possibilities):
345 max_len = len(max(possibilities,key=len))
334 max_len = len(max(possibilities,key=len))
346 max_symbol =' '*max_len
335 max_symbol =' '*max_len
347
336
348 #now we check how much symbol we can put on a line...
337 #now we check how much symbol we can put on a line...
349 cursor_pos = self.getCursorPos()
338 cursor_pos = self.getCursorPos()
350 test_buffer = max_symbol + ' '*4
339 test_buffer = max_symbol + ' '*4
351 current_lines = self.GetLineCount()
340 current_lines = self.GetLineCount()
352
341
353 allowed_symbols = 80/len(test_buffer)
342 allowed_symbols = 80/len(test_buffer)
354 if allowed_symbols == 0:
343 if allowed_symbols == 0:
355 allowed_symbols = 1
344 allowed_symbols = 1
356
345
357 pos = 1
346 pos = 1
358 buf = ''
347 buf = ''
359 for symbol in possibilities:
348 for symbol in possibilities:
360 #buf += symbol+'\n'#*spaces)
349 #buf += symbol+'\n'#*spaces)
361 if pos<allowed_symbols:
350 if pos<allowed_symbols:
362 spaces = max_len - len(symbol) + 4
351 spaces = max_len - len(symbol) + 4
363 buf += symbol+' '*spaces
352 buf += symbol+' '*spaces
364 pos += 1
353 pos += 1
365 else:
354 else:
366 buf+=symbol+'\n'
355 buf+=symbol+'\n'
367 pos = 1
356 pos = 1
368 self.write(buf)
357 self.write(buf)
369
358
370 def _onKeypress(self, event, skip=True):
359 def _onKeypress(self, event, skip=True):
371 '''
360 '''
372 Key press callback used for correcting behavior for console-like
361 Key press callback used for correcting behavior for console-like
373 interfaces. For example 'home' should go to prompt, not to begining of
362 interfaces. For example 'home' should go to prompt, not to begining of
374 line.
363 line.
375
364
376 @param widget: Widget that key press accored in.
365 @param widget: Widget that key press accored in.
377 @type widget: gtk.Widget
366 @type widget: gtk.Widget
378 @param event: Event object
367 @param event: Event object
379 @type event: gtk.gdk.Event
368 @type event: gtk.gdk.Event
380
369
381 @return: Return True if event as been catched.
370 @return: Return True if event as been catched.
382 @rtype: boolean
371 @rtype: boolean
383 '''
372 '''
384
373
385 if event.GetKeyCode() == wx.WXK_HOME:
374 if event.GetKeyCode() == wx.WXK_HOME:
386 if event.Modifiers == wx.MOD_NONE:
375 if event.Modifiers == wx.MOD_NONE:
387 self.moveCursorOnNewValidKey()
376 self.moveCursorOnNewValidKey()
388 self.moveCursor(self.getCurrentPromptStart())
377 self.moveCursor(self.getCurrentPromptStart())
389 return True
378 return True
390 elif event.Modifiers == wx.MOD_SHIFT:
379 elif event.Modifiers == wx.MOD_SHIFT:
391 self.moveCursorOnNewValidKey()
380 self.moveCursorOnNewValidKey()
392 self.selectFromTo(self.getCurrentPromptStart(),self.getCursorPos())
381 self.selectFromTo(self.getCurrentPromptStart(),self.getCursorPos())
393 return True
382 return True
394 else:
383 else:
395 return False
384 return False
396
385
397 elif event.GetKeyCode() == wx.WXK_LEFT:
386 elif event.GetKeyCode() == wx.WXK_LEFT:
398 if event.Modifiers == wx.MOD_NONE:
387 if event.Modifiers == wx.MOD_NONE:
399 self.moveCursorOnNewValidKey()
388 self.moveCursorOnNewValidKey()
400
389
401 self.moveCursor(self.getCursorPos()-1)
390 self.moveCursor(self.getCursorPos()-1)
402 if self.getCursorPos() < self.getCurrentPromptStart():
391 if self.getCursorPos() < self.getCurrentPromptStart():
403 self.moveCursor(self.getCurrentPromptStart())
392 self.moveCursor(self.getCurrentPromptStart())
404 return True
393 return True
405
394
406 elif event.GetKeyCode() == wx.WXK_BACK:
395 elif event.GetKeyCode() == wx.WXK_BACK:
407 self.moveCursorOnNewValidKey()
396 self.moveCursorOnNewValidKey()
408 if self.getCursorPos() > self.getCurrentPromptStart():
397 if self.getCursorPos() > self.getCurrentPromptStart():
409 self.removeFromTo(self.getCursorPos()-1,self.getCursorPos())
398 event.Skip()
410 return True
399 return True
411
400
412 if skip:
401 if skip:
413 if event.GetKeyCode() not in [wx.WXK_PAGEUP,wx.WXK_PAGEDOWN] and event.Modifiers == wx.MOD_NONE:
402 if event.GetKeyCode() not in [wx.WXK_PAGEUP,wx.WXK_PAGEDOWN] and event.Modifiers == wx.MOD_NONE:
414 self.moveCursorOnNewValidKey()
403 self.moveCursorOnNewValidKey()
415
404
416 event.Skip()
405 event.Skip()
417 return True
406 return True
418 return False
407 return False
419
408
420 def OnUpdateUI(self, evt):
409 def OnUpdateUI(self, evt):
421 # check for matching braces
410 # check for matching braces
422 braceAtCaret = -1
411 braceAtCaret = -1
423 braceOpposite = -1
412 braceOpposite = -1
424 charBefore = None
413 charBefore = None
425 caretPos = self.GetCurrentPos()
414 caretPos = self.GetCurrentPos()
426
415
427 if caretPos > 0:
416 if caretPos > 0:
428 charBefore = self.GetCharAt(caretPos - 1)
417 charBefore = self.GetCharAt(caretPos - 1)
429 styleBefore = self.GetStyleAt(caretPos - 1)
418 styleBefore = self.GetStyleAt(caretPos - 1)
430
419
431 # check before
420 # check before
432 if charBefore and chr(charBefore) in "[]{}()" and styleBefore == stc.STC_P_OPERATOR:
421 if charBefore and chr(charBefore) in "[]{}()" and styleBefore == stc.STC_P_OPERATOR:
433 braceAtCaret = caretPos - 1
422 braceAtCaret = caretPos - 1
434
423
435 # check after
424 # check after
436 if braceAtCaret < 0:
425 if braceAtCaret < 0:
437 charAfter = self.GetCharAt(caretPos)
426 charAfter = self.GetCharAt(caretPos)
438 styleAfter = self.GetStyleAt(caretPos)
427 styleAfter = self.GetStyleAt(caretPos)
439
428
440 if charAfter and chr(charAfter) in "[]{}()" and styleAfter == stc.STC_P_OPERATOR:
429 if charAfter and chr(charAfter) in "[]{}()" and styleAfter == stc.STC_P_OPERATOR:
441 braceAtCaret = caretPos
430 braceAtCaret = caretPos
442
431
443 if braceAtCaret >= 0:
432 if braceAtCaret >= 0:
444 braceOpposite = self.BraceMatch(braceAtCaret)
433 braceOpposite = self.BraceMatch(braceAtCaret)
445
434
446 if braceAtCaret != -1 and braceOpposite == -1:
435 if braceAtCaret != -1 and braceOpposite == -1:
447 self.BraceBadLight(braceAtCaret)
436 self.BraceBadLight(braceAtCaret)
448 else:
437 else:
449 self.BraceHighlight(braceAtCaret, braceOpposite)
438 self.BraceHighlight(braceAtCaret, braceOpposite)
450 #pt = self.PointFromPosition(braceOpposite)
439 #pt = self.PointFromPosition(braceOpposite)
451 #self.Refresh(True, wxRect(pt.x, pt.y, 5,5))
440 #self.Refresh(True, wxRect(pt.x, pt.y, 5,5))
452 #print pt
441 #print pt
453 #self.Refresh(False)
442 #self.Refresh(False)
454
443
455 class IPShellWidget(wx.Panel):
444 class IPShellWidget(wx.Panel):
456 '''
445 '''
457 This is wx.Panel that embbed the IPython Thread and the wx.StyledTextControl
446 This is wx.Panel that embbed the IPython Thread and the wx.StyledTextControl
458 If you want to port this to any other GUI toolkit, just replace the
447 If you want to port this to any other GUI toolkit, just replace the
459 WxConsoleView by YOURGUIConsoleView and make YOURGUIIPythonView derivate
448 WxConsoleView by YOURGUIConsoleView and make YOURGUIIPythonView derivate
460 from whatever container you want. I've choosed to derivate from a wx.Panel
449 from whatever container you want. I've choosed to derivate from a wx.Panel
461 because it seems to be more useful
450 because it seems to be more useful
462 Any idea to make it more 'generic' welcomed.
451 Any idea to make it more 'generic' welcomed.
463 '''
452 '''
453
464 def __init__(self, parent, intro=None,
454 def __init__(self, parent, intro=None,
465 background_color="BLACK", add_button_handler=None,
455 background_color="BLACK", add_button_handler=None,
466 wx_ip_shell=None,
456 wx_ip_shell=None,
467 ):
457 ):
468 '''
458 '''
469 Initialize.
459 Initialize.
470 Instanciate an IPython thread.
460 Instanciate an IPython thread.
471 Instanciate a WxConsoleView.
461 Instanciate a WxConsoleView.
472 Redirect I/O to console.
462 Redirect I/O to console.
473 '''
463 '''
474 wx.Panel.__init__(self,parent,-1)
464 wx.Panel.__init__(self,parent,-1)
475
465
476 ### IPython non blocking shell instanciation ###
466 ### IPython non blocking shell instanciation ###
477 self.cout = StringIO()
467 self.cout = StringIO()
478
479 self.add_button_handler = add_button_handler
468 self.add_button_handler = add_button_handler
480
469
481 if wx_ip_shell is not None:
470 if wx_ip_shell is not None:
482 self.IP = wx_ip_shell
471 self.IP = wx_ip_shell
483 else:
472 else:
484 self.IP = WxNonBlockingIPShell(self,
473 self.IP = WxNonBlockingIPShell(self,
485 cout = self.cout,cerr = self.cout,
474 cout = self.cout, cerr = self.cout,
486 ask_exit_handler = self.askExitCallback)
475 ask_exit_handler = self.askExitCallback,
476 rawinput = self.rawInput)
487
477
488 ### IPython wx console view instanciation ###
478 ### IPython wx console view instanciation ###
489 #If user didn't defined an intro text, we create one for him
479 #If user didn't defined an intro text, we create one for him
490 #If you really wnat an empty intrp just call wxIPythonViewPanel
480 #If you really wnat an empty intrp just call wxIPythonViewPanel
491 #with intro=''
481 #with intro=''
492 if intro is None:
482 if intro is None:
493 welcome_text = "Welcome to WxIPython Shell.\n\n"
483 welcome_text = "Welcome to WxIPython Shell.\n\n"
494 welcome_text+= self.IP.getBanner()
484 welcome_text+= self.IP.getBanner()
495 welcome_text+= "!command -> Execute command in shell\n"
485 welcome_text+= "!command -> Execute command in shell\n"
496 welcome_text+= "TAB -> Autocompletion\n"
486 welcome_text+= "TAB -> Autocompletion\n"
497 else:
487 else:
498 welcome_text = intro
488 welcome_text = intro
499
489
500 self.text_ctrl = WxConsoleView(self,
490 self.text_ctrl = WxConsoleView(self,
501 self.IP.getPrompt(),
491 self.IP.getPrompt(),
502 intro=welcome_text,
492 intro=welcome_text,
503 background_color=background_color)
493 background_color=background_color)
494
495 self.cout.write = self.text_ctrl.write
504
496
505 self.text_ctrl.Bind(wx.EVT_KEY_DOWN, self.keyPress, self.text_ctrl)
497 self.text_ctrl.Bind(wx.EVT_KEY_DOWN, self.keyPress, self.text_ctrl)
506
498
507 ### making the layout of the panel ###
499 ### making the layout of the panel ###
508 sizer = wx.BoxSizer(wx.VERTICAL)
500 sizer = wx.BoxSizer(wx.VERTICAL)
509 sizer.Add(self.text_ctrl, 1, wx.EXPAND)
501 sizer.Add(self.text_ctrl, 1, wx.EXPAND)
510 self.SetAutoLayout(True)
502 self.SetAutoLayout(True)
511 sizer.Fit(self)
503 sizer.Fit(self)
512 sizer.SetSizeHints(self)
504 sizer.SetSizeHints(self)
513 self.SetSizer(sizer)
505 self.SetSizer(sizer)
514 #and we focus on the widget :)
506 #and we focus on the widget :)
515 self.SetFocus()
507 self.SetFocus()
516
508
517 #widget state management (for key handling different cases)
509 #widget state management (for key handling different cases)
518 self.setCurrentState('IDLE')
510 self.setCurrentState('IDLE')
519 self.pager_state = 'DONE'
511 self.pager_state = 'DONE'
520
512
521 def askExitCallback(self, event):
513 def askExitCallback(self, event):
522 self.askExitHandler(event)
514 self.askExitHandler(event)
523
515
524 #---------------------- IPython Thread Management ------------------------
516 #---------------------- IPython Thread Management ------------------------
525 def stateDoExecuteLine(self):
517 def stateDoExecuteLine(self):
526 #print >>sys.__stdout__,"command:",self.getCurrentLine()
518 #print >>sys.__stdout__,"command:",self.getCurrentLine()
527 line=self.text_ctrl.getCurrentLine()
519 line=self.text_ctrl.getCurrentLine()
520 self.text_ctrl.write('\n')
528 self.IP.doExecute((line.replace('\t',' '*4)).encode('cp1252'))
521 self.IP.doExecute((line.replace('\t',' '*4)).encode('cp1252'))
529 self.updateHistoryTracker(self.text_ctrl.getCurrentLine())
522 self.updateHistoryTracker(self.text_ctrl.getCurrentLine())
530 self.setCurrentState('WAIT_END_OF_EXECUTION')
523 self.setCurrentState('WAIT_END_OF_EXECUTION')
531
524
532 def evtStateExecuteDone(self,evt):
525 def evtStateExecuteDone(self,evt):
533 self.doc = self.IP.getDocText()
526 self.doc = self.IP.getDocText()
534 self.help = self.IP.getHelpText()
527 self.help = self.IP.getHelpText()
535 if self.doc:
528 if self.doc:
536 self.pager_lines = self.doc[7:].split('\n')
529 self.pager_lines = self.doc[7:].split('\n')
537 self.pager_state = 'INIT'
530 self.pager_state = 'INIT'
538 self.setCurrentState('SHOW_DOC')
531 self.setCurrentState('SHOW_DOC')
539 self.pager(self.doc)
532 self.pager(self.doc)
540 elif self.help:
533 elif self.help:
541 self.pager_lines = self.help.split('\n')
534 self.pager_lines = self.help.split('\n')
542 self.pager_state = 'INIT'
535 self.pager_state = 'INIT'
543 self.setCurrentState('SHOW_DOC')
536 self.setCurrentState('SHOW_DOC')
544 self.pager(self.help)
537 self.pager(self.help)
545 else:
538 else:
546 self.stateShowPrompt()
539 self.stateShowPrompt()
547
540
548 def stateShowPrompt(self):
541 def stateShowPrompt(self):
549 self.setCurrentState('SHOW_PROMPT')
542 self.setCurrentState('SHOW_PROMPT')
550 self.text_ctrl.setPrompt(self.IP.getPrompt())
543 self.text_ctrl.setPrompt(self.IP.getPrompt())
551 self.text_ctrl.setIndentation(self.IP.getIndentation())
544 self.text_ctrl.setIndentation(self.IP.getIndentation())
552 self.text_ctrl.setPromptCount(self.IP.getPromptCount())
545 self.text_ctrl.setPromptCount(self.IP.getPromptCount())
553 rv = self.cout.getvalue()
546 self.text_ctrl.showPrompt()
554 if rv: rv = rv.strip('\n')
555 self.text_ctrl.showReturned(rv)
556 self.cout.truncate(0)
557 self.IP.initHistoryIndex()
547 self.IP.initHistoryIndex()
558 self.setCurrentState('IDLE')
548 self.setCurrentState('IDLE')
559
549
560 def setCurrentState(self, state):
550 def setCurrentState(self, state):
561 self.cur_state = state
551 self.cur_state = state
562 self.updateStatusTracker(self.cur_state)
552 self.updateStatusTracker(self.cur_state)
563
553 #---------------------------- Ipython raw_input -----------------------------------
554 def rawInput(self, prompt=''):
555 self.setCurrentState('WAITING_USER_INPUT')
556 while self.cur_state != 'WAIT_END_OF_EXECUTION':
557 pass
558 line = self.text_ctrl.getCurrentLine()
559 line = line.split('\n')
560 return line[-2]
561
564 #---------------------------- IPython pager ---------------------------------------
562 #---------------------------- IPython pager ---------------------------------------
565 def pager(self,text):#,start=0,screen_lines=0,pager_cmd = None):
563 def pager(self,text):
566
564
567 if self.pager_state == 'INIT':
565 if self.pager_state == 'INIT':
568 #print >>sys.__stdout__,"PAGER state:",self.pager_state
566 #print >>sys.__stdout__,"PAGER state:",self.pager_state
569 self.pager_nb_lines = len(self.pager_lines)
567 self.pager_nb_lines = len(self.pager_lines)
570 self.pager_index = 0
568 self.pager_index = 0
571 self.pager_do_remove = False
569 self.pager_do_remove = False
572 self.text_ctrl.write('\n')
570 self.text_ctrl.write('\n')
573 self.pager_state = 'PROCESS_LINES'
571 self.pager_state = 'PROCESS_LINES'
574
572
575 if self.pager_state == 'PROCESS_LINES':
573 if self.pager_state == 'PROCESS_LINES':
576 #print >>sys.__stdout__,"PAGER state:",self.pager_state
574 #print >>sys.__stdout__,"PAGER state:",self.pager_state
577 if self.pager_do_remove == True:
575 if self.pager_do_remove == True:
578 self.text_ctrl.removeCurrentLine()
576 self.text_ctrl.removeCurrentLine()
579 self.pager_do_remove = False
577 self.pager_do_remove = False
580
578
581 if self.pager_nb_lines > 10:
579 if self.pager_nb_lines > 10:
582 #print >>sys.__stdout__,"PAGER processing 10 lines"
580 #print >>sys.__stdout__,"PAGER processing 10 lines"
583 if self.pager_index > 0:
581 if self.pager_index > 0:
584 self.text_ctrl.write(">\x01\x1b[1;36m\x02"+self.pager_lines[self.pager_index]+'\n')
582 self.text_ctrl.write(">\x01\x1b[1;36m\x02"+self.pager_lines[self.pager_index]+'\n')
585 else:
583 else:
586 self.text_ctrl.write("\x01\x1b[1;36m\x02 "+self.pager_lines[self.pager_index]+'\n')
584 self.text_ctrl.write("\x01\x1b[1;36m\x02 "+self.pager_lines[self.pager_index]+'\n')
587
585
588 for line in self.pager_lines[self.pager_index+1:self.pager_index+9]:
586 for line in self.pager_lines[self.pager_index+1:self.pager_index+9]:
589 self.text_ctrl.write("\x01\x1b[1;36m\x02 "+line+'\n')
587 self.text_ctrl.write("\x01\x1b[1;36m\x02 "+line+'\n')
590 self.pager_index += 10
588 self.pager_index += 10
591 self.pager_nb_lines -= 10
589 self.pager_nb_lines -= 10
592 self.text_ctrl.write("--- Push Enter to continue or 'Q' to quit---")
590 self.text_ctrl.write("--- Push Enter to continue or 'Q' to quit---")
593 self.pager_do_remove = True
591 self.pager_do_remove = True
594 self.pager_state = 'WAITING'
592 self.pager_state = 'WAITING'
595 return
593 return
596 else:
594 else:
597 #print >>sys.__stdout__,"PAGER processing last lines"
595 #print >>sys.__stdout__,"PAGER processing last lines"
598 if self.pager_nb_lines > 0:
596 if self.pager_nb_lines > 0:
599 if self.pager_index > 0:
597 if self.pager_index > 0:
600 self.text_ctrl.write(">\x01\x1b[1;36m\x02"+self.pager_lines[self.pager_index]+'\n')
598 self.text_ctrl.write(">\x01\x1b[1;36m\x02"+self.pager_lines[self.pager_index]+'\n')
601 else:
599 else:
602 self.text_ctrl.write("\x01\x1b[1;36m\x02 "+self.pager_lines[self.pager_index]+'\n')
600 self.text_ctrl.write("\x01\x1b[1;36m\x02 "+self.pager_lines[self.pager_index]+'\n')
603
601
604 self.pager_index += 1
602 self.pager_index += 1
605 self.pager_nb_lines -= 1
603 self.pager_nb_lines -= 1
606 if self.pager_nb_lines > 0:
604 if self.pager_nb_lines > 0:
607 for line in self.pager_lines[self.pager_index:]:
605 for line in self.pager_lines[self.pager_index:]:
608 self.text_ctrl.write("\x01\x1b[1;36m\x02 "+line+'\n')
606 self.text_ctrl.write("\x01\x1b[1;36m\x02 "+line+'\n')
609 self.pager_nb_lines = 0
607 self.pager_nb_lines = 0
610 self.pager_state = 'DONE'
608 self.pager_state = 'DONE'
611 self.stateShowPrompt()
609 self.stateShowPrompt()
612
610
613 #------------------------ Key Handler ------------------------------------
611 #------------------------ Key Handler ------------------------------------
614 def keyPress(self, event):
612 def keyPress(self, event):
615 '''
613 '''
616 Key press callback with plenty of shell goodness, like history,
614 Key press callback with plenty of shell goodness, like history,
617 autocompletions, etc.
615 autocompletions, etc.
618 '''
616 '''
619
617
620 if event.GetKeyCode() == ord('C'):
618 if event.GetKeyCode() == ord('C'):
621 if event.Modifiers == wx.MOD_CONTROL:
619 if event.Modifiers == wx.MOD_CONTROL:
622 if self.cur_state == 'WAIT_END_OF_EXECUTION':
620 if self.cur_state == 'WAIT_END_OF_EXECUTION':
623 #we raise an exception inside the IPython thread container
621 #we raise an exception inside the IPython thread container
624 self.IP.ce.raise_exc(KeyboardInterrupt)
622 self.IP.ce.raise_exc(KeyboardInterrupt)
625 return
623 return
626
624
627 if event.KeyCode == wx.WXK_RETURN:
625 if event.KeyCode == wx.WXK_RETURN:
628 if self.cur_state == 'IDLE':
626 if self.cur_state == 'IDLE':
629 #we change the state ot the state machine
627 #we change the state ot the state machine
630 self.setCurrentState('DO_EXECUTE_LINE')
628 self.setCurrentState('DO_EXECUTE_LINE')
631 self.stateDoExecuteLine()
629 self.stateDoExecuteLine()
632 return
630 return
633 if self.pager_state == 'WAITING':
631 if self.pager_state == 'WAITING':
634 self.pager_state = 'PROCESS_LINES'
632 self.pager_state = 'PROCESS_LINES'
635 self.pager(self.doc)
633 self.pager(self.doc)
636 return
634 return
637
635
636 if self.cur_state == 'WAITING_USER_INPUT':
637 line=self.text_ctrl.getCurrentLine()
638 self.text_ctrl.write('\n')
639 self.setCurrentState('WAIT_END_OF_EXECUTION')
640 return
641
638 if event.GetKeyCode() in [ord('q'),ord('Q')]:
642 if event.GetKeyCode() in [ord('q'),ord('Q')]:
639 if self.pager_state == 'WAITING':
643 if self.pager_state == 'WAITING':
640 self.pager_state = 'DONE'
644 self.pager_state = 'DONE'
641 self.stateShowPrompt()
645 self.stateShowPrompt()
642 return
646 return
643
647
644 #scroll_position = self.text_ctrl.GetScrollPos(wx.VERTICAL)
648 if self.cur_state == 'WAITING_USER_INPUT':
649 event.Skip()
650
645 if self.cur_state == 'IDLE':
651 if self.cur_state == 'IDLE':
646 if event.KeyCode == wx.WXK_UP:
652 if event.KeyCode == wx.WXK_UP:
647 history = self.IP.historyBack()
653 history = self.IP.historyBack()
648 self.text_ctrl.writeHistory(history)
654 self.text_ctrl.writeHistory(history)
649 return
655 return
650 if event.KeyCode == wx.WXK_DOWN:
656 if event.KeyCode == wx.WXK_DOWN:
651 history = self.IP.historyForward()
657 history = self.IP.historyForward()
652 self.text_ctrl.writeHistory(history)
658 self.text_ctrl.writeHistory(history)
653 return
659 return
654 if event.KeyCode == wx.WXK_TAB:
660 if event.KeyCode == wx.WXK_TAB:
655 #if line empty we disable tab completion
661 #if line empty we disable tab completion
656 if not self.text_ctrl.getCurrentLine().strip():
662 if not self.text_ctrl.getCurrentLine().strip():
657 self.text_ctrl.write('\t')
663 self.text_ctrl.write('\t')
658 return
664 return
659 completed, possibilities = self.IP.complete(self.text_ctrl.getCurrentLine())
665 completed, possibilities = self.IP.complete(self.text_ctrl.getCurrentLine())
660 if len(possibilities) > 1:
666 if len(possibilities) > 1:
661 cur_slice = self.text_ctrl.getCurrentLine()
667 cur_slice = self.text_ctrl.getCurrentLine()
662 self.text_ctrl.write('\n')
668 self.text_ctrl.write('\n')
663 self.text_ctrl.writeCompletion(possibilities)
669 self.text_ctrl.writeCompletion(possibilities)
664 self.text_ctrl.write('\n')
670 self.text_ctrl.write('\n')
665
671
666 self.text_ctrl.showPrompt()
672 self.text_ctrl.showPrompt()
667 self.text_ctrl.write(cur_slice)
673 self.text_ctrl.write(cur_slice)
668 self.text_ctrl.changeLine(completed or cur_slice)
674 self.text_ctrl.changeLine(completed or cur_slice)
669
675
670 return
676 return
671 event.Skip()
677 event.Skip()
672
678
673 #------------------------ Hook Section -----------------------------------
679 #------------------------ Hook Section -----------------------------------
674 def updateHistoryTracker(self,command_line):
680 def updateHistoryTracker(self,command_line):
675 '''
681 '''
676 Default history tracker (does nothing)
682 Default history tracker (does nothing)
677 '''
683 '''
678 pass
684 pass
679
685
680 def setHistoryTrackerHook(self,func):
686 def setHistoryTrackerHook(self,func):
681 '''
687 '''
682 Define a new history tracker
688 Define a new history tracker
683 '''
689 '''
684 self.updateHistoryTracker = func
690 self.updateHistoryTracker = func
685
691
686 def updateStatusTracker(self,status):
692 def updateStatusTracker(self,status):
687 '''
693 '''
688 Default status tracker (does nothing)
694 Default status tracker (does nothing)
689 '''
695 '''
690 pass
696 pass
691
697
692 def setStatusTrackerHook(self,func):
698 def setStatusTrackerHook(self,func):
693 '''
699 '''
694 Define a new status tracker
700 Define a new status tracker
695 '''
701 '''
696 self.updateStatusTracker = func
702 self.updateStatusTracker = func
697
703
698 def askExitHandler(self, event):
704 def askExitHandler(self, event):
699 '''
705 '''
700 Default exit handler
706 Default exit handler
701 '''
707 '''
702 self.text_ctrl.write('\nExit callback has not been set.')
708 self.text_ctrl.write('\nExit callback has not been set.')
703
709
704 def setAskExitHandler(self, func):
710 def setAskExitHandler(self, func):
705 '''
711 '''
706 Define an exit handler
712 Define an exit handler
707 '''
713 '''
708 self.askExitHandler = func
714 self.askExitHandler = func
709
715
710 if __name__ == '__main__':
716 if __name__ == '__main__':
711 # Some simple code to test the shell widget.
717 # Some simple code to test the shell widget.
712 class MainWindow(wx.Frame):
718 class MainWindow(wx.Frame):
713 def __init__(self, parent, id, title):
719 def __init__(self, parent, id, title):
714 wx.Frame.__init__(self, parent, id, title, size=(300,250))
720 wx.Frame.__init__(self, parent, id, title, size=(300,250))
715 self._sizer = wx.BoxSizer(wx.VERTICAL)
721 self._sizer = wx.BoxSizer(wx.VERTICAL)
716 self.shell = IPShellWidget(self)
722 self.shell = IPShellWidget(self)
717 self._sizer.Add(self.shell, 1, wx.EXPAND)
723 self._sizer.Add(self.shell, 1, wx.EXPAND)
718 self.SetSizer(self._sizer)
724 self.SetSizer(self._sizer)
719 self.SetAutoLayout(1)
725 self.SetAutoLayout(1)
720 self.Show(True)
726 self.Show(True)
721
727
722 app = wx.PySimpleApp()
728 app = wx.PySimpleApp()
723 frame = MainWindow(None, wx.ID_ANY, 'Ipython')
729 frame = MainWindow(None, wx.ID_ANY, 'Ipython')
724 frame.SetSize((780, 460))
730 frame.SetSize((780, 460))
725 shell = frame.shell
731 shell = frame.shell
726
732
727 app.MainLoop()
733 app.MainLoop()
728
734
729
735
@@ -1,202 +1,202 b''
1 #!/usr/bin/python
1 #!/usr/bin/python
2 # -*- coding: iso-8859-15 -*-
2 # -*- coding: iso-8859-15 -*-
3
3
4 import wx.aui
4 import wx.aui
5
5
6 #used for about dialog
6 #used for about dialog
7 from wx.lib.wordwrap import wordwrap
7 from wx.lib.wordwrap import wordwrap
8
8
9 #used for ipython GUI objects
9 #used for ipython GUI objects
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 __version__ = 0.8
13 __version__ = 0.8
14 __author__ = "Laurent Dufrechou"
14 __author__ = "Laurent Dufrechou"
15 __email__ = "laurent.dufrechou _at_ gmail.com"
15 __email__ = "laurent.dufrechou _at_ gmail.com"
16 __license__ = "BSD"
16 __license__ = "BSD"
17
17
18 #-----------------------------------------
18 #-----------------------------------------
19 # Creating one main frame for our
19 # Creating one main frame for our
20 # application with movables windows
20 # application with movables windows
21 #-----------------------------------------
21 #-----------------------------------------
22 class MyFrame(wx.Frame):
22 class MyFrame(wx.Frame):
23 """Creating one main frame for our
23 """Creating one main frame for our
24 application with movables windows"""
24 application with movables windows"""
25 def __init__(self, parent=None, id=-1, title="WxIPython",
25 def __init__(self, parent=None, id=-1, title="WxIPython",
26 pos=wx.DefaultPosition,
26 pos=wx.DefaultPosition,
27 size=(800, 600), style=wx.DEFAULT_FRAME_STYLE):
27 size=(800, 600), style=wx.DEFAULT_FRAME_STYLE):
28 wx.Frame.__init__(self, parent, id, title, pos, size, style)
28 wx.Frame.__init__(self, parent, id, title, pos, size, style)
29 self._mgr = wx.aui.AuiManager()
29 self._mgr = wx.aui.AuiManager()
30
30
31 # notify PyAUI which frame to use
31 # notify PyAUI which frame to use
32 self._mgr.SetManagedWindow(self)
32 self._mgr.SetManagedWindow(self)
33
33
34 #create differents panels and make them persistant
34 #create differents panels and make them persistant
35 self.history_panel = IPythonHistoryPanel(self)
35 self.history_panel = IPythonHistoryPanel(self)
36
36
37 self.ipython_panel = IPShellWidget(self,background_color = "BLACK")
37 self.ipython_panel = IPShellWidget(self,background_color = "BLACK")
38
38
39 #self.ipython_panel = WxIPythonViewPanel(self,
39 #self.ipython_panel = IPShellWidget(self,background_color = "WHITE")
40 # background_color = "WHITE")
41
40
42 self.ipython_panel.setHistoryTrackerHook(self.history_panel.write)
41 self.ipython_panel.setHistoryTrackerHook(self.history_panel.write)
43 self.ipython_panel.setStatusTrackerHook(self.updateStatus)
42 self.ipython_panel.setStatusTrackerHook(self.updateStatus)
44 self.ipython_panel.setAskExitHandler(self.OnExitDlg)
43 self.ipython_panel.setAskExitHandler(self.OnExitDlg)
45
44
46 self.statusbar = self.createStatus()
45 self.statusbar = self.createStatus()
47 self.createMenu()
46 self.createMenu()
48
47
49 ########################################################################
48 ########################################################################
50 ### add the panes to the manager
49 ### add the panes to the manager
51 # main panels
50 # main panels
52 self._mgr.AddPane(self.ipython_panel , wx.CENTER, "IPython Shell")
51 self._mgr.AddPane(self.ipython_panel , wx.CENTER, "IPython Shell")
53 self._mgr.AddPane(self.history_panel , wx.RIGHT, "IPython history")
52 self._mgr.AddPane(self.history_panel , wx.RIGHT, "IPython history")
54
53
55 # now we specify some panel characteristics
54 # now we specify some panel characteristics
56 self._mgr.GetPane(self.ipython_panel).CaptionVisible(True);
55 self._mgr.GetPane(self.ipython_panel).CaptionVisible(True);
57 self._mgr.GetPane(self.history_panel).CaptionVisible(True);
56 self._mgr.GetPane(self.history_panel).CaptionVisible(True);
58 self._mgr.GetPane(self.history_panel).MinSize((200,400));
57 self._mgr.GetPane(self.history_panel).MinSize((200,400));
59
58
60 # tell the manager to "commit" all the changes just made
59 # tell the manager to "commit" all the changes just made
61 self._mgr.Update()
60 self._mgr.Update()
62
61
63 #global event handling
62 #global event handling
64 self.Bind(wx.EVT_CLOSE, self.OnClose)
63 self.Bind(wx.EVT_CLOSE, self.OnClose)
65 self.Bind(wx.EVT_MENU, self.OnClose,id=wx.ID_EXIT)
64 self.Bind(wx.EVT_MENU, self.OnClose,id=wx.ID_EXIT)
66 self.Bind(wx.EVT_MENU, self.OnShowIPythonPanel,id=wx.ID_HIGHEST+1)
65 self.Bind(wx.EVT_MENU, self.OnShowIPythonPanel,id=wx.ID_HIGHEST+1)
67 self.Bind(wx.EVT_MENU, self.OnShowHistoryPanel,id=wx.ID_HIGHEST+2)
66 self.Bind(wx.EVT_MENU, self.OnShowHistoryPanel,id=wx.ID_HIGHEST+2)
68 self.Bind(wx.EVT_MENU, self.OnShowAbout, id=wx.ID_HIGHEST+3)
67 self.Bind(wx.EVT_MENU, self.OnShowAbout, id=wx.ID_HIGHEST+3)
69 self.Bind(wx.EVT_MENU, self.OnShowAllPanel,id=wx.ID_HIGHEST+6)
68 self.Bind(wx.EVT_MENU, self.OnShowAllPanel,id=wx.ID_HIGHEST+6)
70
69
71 warn_text = 'Hello from IPython and wxPython.\n'
70 warn_text = 'Hello from IPython and wxPython.\n'
72 warn_text +='Please Note that this work is still EXPERIMENTAL\n'
71 warn_text +='Please Note that this work is still EXPERIMENTAL\n'
73 warn_text +='It does NOT emulate currently all the IPython functions.\n'
72 warn_text +='It does NOT emulate currently all the IPython functions.\n'
74
73
75 dlg = wx.MessageDialog(self,
74 dlg = wx.MessageDialog(self,
76 warn_text,
75 warn_text,
77 'Warning Box',
76 'Warning Box',
78 wx.OK | wx.ICON_INFORMATION
77 wx.OK | wx.ICON_INFORMATION
79 )
78 )
80 dlg.ShowModal()
79 dlg.ShowModal()
81 dlg.Destroy()
80 dlg.Destroy()
82
81
83 def createMenu(self):
82 def createMenu(self):
84 """local method used to create one menu bar"""
83 """local method used to create one menu bar"""
85
84
86 mb = wx.MenuBar()
85 mb = wx.MenuBar()
87
86
88 file_menu = wx.Menu()
87 file_menu = wx.Menu()
89 file_menu.Append(wx.ID_EXIT, "Exit")
88 file_menu.Append(wx.ID_EXIT, "Exit")
90
89
91 view_menu = wx.Menu()
90 view_menu = wx.Menu()
92 view_menu.Append(wx.ID_HIGHEST+1, "Show IPython Panel")
91 view_menu.Append(wx.ID_HIGHEST+1, "Show IPython Panel")
93 view_menu.Append(wx.ID_HIGHEST+2, "Show History Panel")
92 view_menu.Append(wx.ID_HIGHEST+2, "Show History Panel")
94 view_menu.AppendSeparator()
93 view_menu.AppendSeparator()
95 view_menu.Append(wx.ID_HIGHEST+6, "Show All")
94 view_menu.Append(wx.ID_HIGHEST+6, "Show All")
96
95
97 about_menu = wx.Menu()
96 about_menu = wx.Menu()
98 about_menu.Append(wx.ID_HIGHEST+3, "About")
97 about_menu.Append(wx.ID_HIGHEST+3, "About")
99
98
100 #view_menu.AppendSeparator()
99 #view_menu.AppendSeparator()
101 #options_menu = wx.Menu()
100 #options_menu = wx.Menu()
102 #options_menu.AppendCheckItem(wx.ID_HIGHEST+7, "Allow Floating")
101 #options_menu.AppendCheckItem(wx.ID_HIGHEST+7, "Allow Floating")
103 #options_menu.AppendCheckItem(wx.ID_HIGHEST+8, "Transparent Hint")
102 #options_menu.AppendCheckItem(wx.ID_HIGHEST+8, "Transparent Hint")
104 #options_menu.AppendCheckItem(wx.ID_HIGHEST+9, "Transparent Hint Fade-in")
103 #options_menu.AppendCheckItem(wx.ID_HIGHEST+9, "Transparent Hint Fade-in")
105
104
106
105
107 mb.Append(file_menu, "File")
106 mb.Append(file_menu, "File")
108 mb.Append(view_menu, "View")
107 mb.Append(view_menu, "View")
109 mb.Append(about_menu, "About")
108 mb.Append(about_menu, "About")
110 #mb.Append(options_menu, "Options")
109 #mb.Append(options_menu, "Options")
111
110
112 self.SetMenuBar(mb)
111 self.SetMenuBar(mb)
113
112
114 def createStatus(self):
113 def createStatus(self):
115 statusbar = self.CreateStatusBar(2, wx.ST_SIZEGRIP)
114 statusbar = self.CreateStatusBar(2, wx.ST_SIZEGRIP)
116 statusbar.SetStatusWidths([-2, -3])
115 statusbar.SetStatusWidths([-2, -3])
117 statusbar.SetStatusText("Ready", 0)
116 statusbar.SetStatusText("Ready", 0)
118 statusbar.SetStatusText("WxIPython "+str(__version__), 1)
117 statusbar.SetStatusText("WxIPython "+str(__version__), 1)
119 return statusbar
118 return statusbar
120
119
121 def updateStatus(self,text):
120 def updateStatus(self,text):
122 states = {'IDLE':'Idle',
121 states = {'IDLE':'Idle',
123 'DO_EXECUTE_LINE':'Send command',
122 'DO_EXECUTE_LINE':'Send command',
124 'WAIT_END_OF_EXECUTION':'Running command',
123 'WAIT_END_OF_EXECUTION':'Running command',
124 'WAITING_USER_INPUT':'Waiting user input',
125 'SHOW_DOC':'Showing doc',
125 'SHOW_DOC':'Showing doc',
126 'SHOW_PROMPT':'Showing prompt'}
126 'SHOW_PROMPT':'Showing prompt'}
127 self.statusbar.SetStatusText(states[text], 0)
127 self.statusbar.SetStatusText(states[text], 0)
128
128
129 def OnClose(self, event):
129 def OnClose(self, event):
130 """#event used to close program """
130 """#event used to close program """
131 # deinitialize the frame manager
131 # deinitialize the frame manager
132 self._mgr.UnInit()
132 self._mgr.UnInit()
133 self.Destroy()
133 self.Destroy()
134 event.Skip()
134 event.Skip()
135
135
136 def OnExitDlg(self, event):
136 def OnExitDlg(self, event):
137 dlg = wx.MessageDialog(self, 'Are you sure you want to quit WxIPython',
137 dlg = wx.MessageDialog(self, 'Are you sure you want to quit WxIPython',
138 'WxIPython exit',
138 'WxIPython exit',
139 wx.ICON_QUESTION |
139 wx.ICON_QUESTION |
140 wx.YES_NO | wx.NO_DEFAULT
140 wx.YES_NO | wx.NO_DEFAULT
141 )
141 )
142 if dlg.ShowModal() == wx.ID_YES:
142 if dlg.ShowModal() == wx.ID_YES:
143 dlg.Destroy()
143 dlg.Destroy()
144 self._mgr.UnInit()
144 self._mgr.UnInit()
145 self.Destroy()
145 self.Destroy()
146 dlg.Destroy()
146 dlg.Destroy()
147
147
148 #event to display IPython pannel
148 #event to display IPython pannel
149 def OnShowIPythonPanel(self,event):
149 def OnShowIPythonPanel(self,event):
150 """ #event to display Boxpannel """
150 """ #event to display Boxpannel """
151 self._mgr.GetPane(self.ipython_panel).Show(True)
151 self._mgr.GetPane(self.ipython_panel).Show(True)
152 self._mgr.Update()
152 self._mgr.Update()
153 #event to display History pannel
153 #event to display History pannel
154 def OnShowHistoryPanel(self,event):
154 def OnShowHistoryPanel(self,event):
155 self._mgr.GetPane(self.history_panel).Show(True)
155 self._mgr.GetPane(self.history_panel).Show(True)
156 self._mgr.Update()
156 self._mgr.Update()
157
157
158 def OnShowAllPanel(self,event):
158 def OnShowAllPanel(self,event):
159 """#event to display all Pannels"""
159 """#event to display all Pannels"""
160 self._mgr.GetPane(self.ipython_panel).Show(True)
160 self._mgr.GetPane(self.ipython_panel).Show(True)
161 self._mgr.GetPane(self.history_panel).Show(True)
161 self._mgr.GetPane(self.history_panel).Show(True)
162 self._mgr.Update()
162 self._mgr.Update()
163
163
164 def OnShowAbout(self, event):
164 def OnShowAbout(self, event):
165 # First we create and fill the info object
165 # First we create and fill the info object
166 info = wx.AboutDialogInfo()
166 info = wx.AboutDialogInfo()
167 info.Name = "WxIPython"
167 info.Name = "WxIPython"
168 info.Version = str(__version__)
168 info.Version = str(__version__)
169 info.Copyright = "(C) 2007 Laurent Dufrechou"
169 info.Copyright = "(C) 2007 Laurent Dufrechou"
170 info.Description = wordwrap(
170 info.Description = wordwrap(
171 "A Gui that embbed a multithreaded IPython Shell",
171 "A Gui that embbed a multithreaded IPython Shell",
172 350, wx.ClientDC(self))
172 350, wx.ClientDC(self))
173 info.WebSite = ("http://ipython.scipy.org/", "IPython home page")
173 info.WebSite = ("http://ipython.scipy.org/", "IPython home page")
174 info.Developers = [ "Laurent Dufrechou" ]
174 info.Developers = [ "Laurent Dufrechou" ]
175 licenseText="BSD License.\nAll rights reserved. This program and the accompanying materials are made available under the terms of the BSD which accompanies this distribution, and is available at http://www.opensource.org/licenses/bsd-license.php"
175 licenseText="BSD License.\nAll rights reserved. This program and the accompanying materials are made available under the terms of the BSD which accompanies this distribution, and is available at http://www.opensource.org/licenses/bsd-license.php"
176 info.License = wordwrap(licenseText, 500, wx.ClientDC(self))
176 info.License = wordwrap(licenseText, 500, wx.ClientDC(self))
177
177
178 # Then we call wx.AboutBox giving it that info object
178 # Then we call wx.AboutBox giving it that info object
179 wx.AboutBox(info)
179 wx.AboutBox(info)
180
180
181 #-----------------------------------------
181 #-----------------------------------------
182 #Creating our application
182 #Creating our application
183 #-----------------------------------------
183 #-----------------------------------------
184 class MyApp(wx.PySimpleApp):
184 class MyApp(wx.PySimpleApp):
185 """Creating our application"""
185 """Creating our application"""
186 def __init__(self):
186 def __init__(self):
187 wx.PySimpleApp.__init__(self)
187 wx.PySimpleApp.__init__(self)
188
188
189 self.frame = MyFrame()
189 self.frame = MyFrame()
190 self.frame.Show()
190 self.frame.Show()
191
191
192 #-----------------------------------------
192 #-----------------------------------------
193 #Main loop
193 #Main loop
194 #-----------------------------------------
194 #-----------------------------------------
195 def main():
195 def main():
196 app = MyApp()
196 app = MyApp()
197 app.SetTopWindow(app.frame)
197 app.SetTopWindow(app.frame)
198 app.MainLoop()
198 app.MainLoop()
199
199
200 #if launched as main program run this
200 #if launched as main program run this
201 if __name__ == '__main__':
201 if __name__ == '__main__':
202 main()
202 main()
General Comments 0
You need to be logged in to leave comments. Login now