##// END OF EJS Templates
ENH: Deal with multiline input.
gvaroquaux -
Show More
@@ -1,435 +1,438 b''
1 1 # encoding: utf-8
2 2 """
3 3 A Wx widget to act as a console and input commands.
4 4
5 5 This widget deals with prompts and provides an edit buffer
6 6 restricted to after the last prompt.
7 7 """
8 8
9 9 __docformat__ = "restructuredtext en"
10 10
11 11 #-------------------------------------------------------------------------------
12 12 # Copyright (C) 2008 The IPython Development Team
13 13 #
14 14 # Distributed under the terms of the BSD License. The full license is
15 15 # in the file COPYING, distributed as part of this software.
16 16 #-------------------------------------------------------------------------------
17 17
18 18 #-------------------------------------------------------------------------------
19 19 # Imports
20 20 #-------------------------------------------------------------------------------
21 21
22 22 import wx
23 23 import wx.stc as stc
24 24
25 from wx.py import editwindow
26
25 27 import re
26 28
27 29 # FIXME: Need to provide an API for non user-generated display on the
28 30 # screen: this should not be editable by the user.
29 31
30 32 if wx.Platform == '__WXMSW__':
31 33 _DEFAULT_SIZE = 80
32 34 else:
33 35 _DEFAULT_SIZE = 10
34 36
35 37 _DEFAULT_STYLE = {
36 38 'stdout' : 'fore:#0000FF',
37 39 'stderr' : 'fore:#007f00',
38 40 'trace' : 'fore:#FF0000',
39 41
40 42 'default' : 'size:%d' % _DEFAULT_SIZE,
41 43 'bracegood' : 'fore:#FFFFFF,back:#0000FF,bold',
42 44 'bracebad' : 'fore:#000000,back:#FF0000,bold',
43 45
44 46 # properties for the various Python lexer styles
45 47 'comment' : 'fore:#007F00',
46 48 'number' : 'fore:#007F7F',
47 49 'string' : 'fore:#7F007F,italic',
48 50 'char' : 'fore:#7F007F,italic',
49 51 'keyword' : 'fore:#00007F,bold',
50 52 'triple' : 'fore:#7F0000',
51 53 'tripledouble': 'fore:#7F0000',
52 54 'class' : 'fore:#0000FF,bold,underline',
53 55 'def' : 'fore:#007F7F,bold',
54 56 'operator' : 'bold',
55 57
56 58 }
57 59
58 60 # new style numbers
59 61 _STDOUT_STYLE = 15
60 62 _STDERR_STYLE = 16
61 63 _TRACE_STYLE = 17
62 64
63 65
64 66 #-------------------------------------------------------------------------------
65 67 # The console widget class
66 68 #-------------------------------------------------------------------------------
67 class ConsoleWidget(stc.StyledTextCtrl):
69 class ConsoleWidget(editwindow.EditWindow):
68 70 """ Specialized styled text control view for console-like workflow.
69 71
70 72 This widget is mainly interested in dealing with the prompt and
71 73 keeping the cursor inside the editing line.
72 74 """
73 75
74 76 style = _DEFAULT_STYLE.copy()
75 77
76 78 # Translation table from ANSI escape sequences to color. Override
77 79 # this to specify your colors.
78 80 ANSI_STYLES = {'0;30': [0, 'BLACK'], '0;31': [1, 'RED'],
79 81 '0;32': [2, 'GREEN'], '0;33': [3, 'BROWN'],
80 82 '0;34': [4, 'BLUE'], '0;35': [5, 'PURPLE'],
81 83 '0;36': [6, 'CYAN'], '0;37': [7, 'LIGHT GREY'],
82 84 '1;30': [8, 'DARK GREY'], '1;31': [9, 'RED'],
83 85 '1;32': [10, 'SEA GREEN'], '1;33': [11, 'YELLOW'],
84 86 '1;34': [12, 'LIGHT BLUE'], '1;35':
85 87 [13, 'MEDIUM VIOLET RED'],
86 88 '1;36': [14, 'LIGHT STEEL BLUE'], '1;37': [15, 'YELLOW']}
87 89
88 90 # The color of the carret (call _apply_style() after setting)
89 91 carret_color = 'BLACK'
90 92
91 93
92 94 #--------------------------------------------------------------------------
93 95 # Public API
94 96 #--------------------------------------------------------------------------
95 97
96 98 def __init__(self, parent, id=wx.ID_ANY, pos=wx.DefaultPosition,
97 99 size=wx.DefaultSize, style=0,
98 100 autocomplete_mode='IPYTHON'):
99 101 """ Autocomplete_mode: Can be 'IPYTHON' or 'STC'
100 102 'IPYTHON' show autocompletion the ipython way
101 103 'STC" show it scintilla text control way
102 104 """
103 stc.StyledTextCtrl.__init__(self, parent, id, pos, size, style)
105 #stc.StyledTextCtrl.__init__(self, parent, id, pos, size, style)
106 editwindow.EditWindow.__init__(self, parent, id, pos, size, style)
104 107 self.configure_scintilla()
105 108
106 109 # FIXME: we need to retrieve this from the interpreter.
107 110 self.prompt = \
108 111 '\n\x01\x1b[0;34m\x02In [\x01\x1b[1;34m\x02%i\x01\x1b[0;34m\x02]: \x01\x1b[0m\x02'
109 112 self.new_prompt(self.prompt % 1)
110 113
111 114 self.autocomplete_mode = autocomplete_mode
112 115
113 116 self.Bind(wx.EVT_KEY_DOWN, self._onKeypress)
114 117
115 118
116 119 def configure_scintilla(self):
117 120 # Ctrl"+" or Ctrl "-" can be used to zoomin/zoomout the text inside
118 121 # the widget
119 122 self.CmdKeyAssign(ord('+'), stc.STC_SCMOD_CTRL, stc.STC_CMD_ZOOMIN)
120 123 self.CmdKeyAssign(ord('-'), stc.STC_SCMOD_CTRL, stc.STC_CMD_ZOOMOUT)
121 124 # Also allow Ctrl Shift "=" for poor non US keyboard users.
122 125 self.CmdKeyAssign(ord('='), stc.STC_SCMOD_CTRL|stc.STC_SCMOD_SHIFT,
123 126 stc.STC_CMD_ZOOMIN)
124 127
125 128 self.SetEOLMode(stc.STC_EOL_CRLF)
126 129 self.SetWrapMode(stc.STC_WRAP_CHAR)
127 130 self.SetWrapMode(stc.STC_WRAP_WORD)
128 131 self.SetBufferedDraw(True)
129 132 self.SetUseAntiAliasing(True)
130 133 self.SetLayoutCache(stc.STC_CACHE_PAGE)
131 134 self.SetUndoCollection(False)
132 135 self.SetUseTabs(True)
133 136 self.SetIndent(4)
134 137 self.SetTabWidth(4)
135 138
136 139 self.EnsureCaretVisible()
137 140
138 141 self.SetMargins(3, 3) #text is moved away from border with 3px
139 142 # Suppressing Scintilla margins
140 143 self.SetMarginWidth(0, 0)
141 144 self.SetMarginWidth(1, 0)
142 145 self.SetMarginWidth(2, 0)
143 146
144 147 self._apply_style()
145 148
146 149 self.indent = 0
147 150 self.color_pat = re.compile('\x01?\x1b\[(.*?)m\x02?')
148 151
149 152 #self.SetEdgeMode(stc.STC_EDGE_LINE)
150 153 #self.SetEdgeColumn(80)
151 154
152 155 # styles
153 156 p = self.style
154 157 self.StyleSetSpec(stc.STC_STYLE_DEFAULT, p['default'])
155 158 self.StyleClearAll()
156 159 self.StyleSetSpec(_STDOUT_STYLE, p['stdout'])
157 160 self.StyleSetSpec(_STDERR_STYLE, p['stderr'])
158 161 self.StyleSetSpec(_TRACE_STYLE, p['trace'])
159 162
160 163 self.StyleSetSpec(stc.STC_STYLE_BRACELIGHT, p['bracegood'])
161 164 self.StyleSetSpec(stc.STC_STYLE_BRACEBAD, p['bracebad'])
162 165 self.StyleSetSpec(stc.STC_P_COMMENTLINE, p['comment'])
163 166 self.StyleSetSpec(stc.STC_P_NUMBER, p['number'])
164 167 self.StyleSetSpec(stc.STC_P_STRING, p['string'])
165 168 self.StyleSetSpec(stc.STC_P_CHARACTER, p['char'])
166 169 self.StyleSetSpec(stc.STC_P_WORD, p['keyword'])
167 170 self.StyleSetSpec(stc.STC_P_TRIPLE, p['triple'])
168 171 self.StyleSetSpec(stc.STC_P_TRIPLEDOUBLE, p['tripledouble'])
169 172 self.StyleSetSpec(stc.STC_P_CLASSNAME, p['class'])
170 173 self.StyleSetSpec(stc.STC_P_DEFNAME, p['def'])
171 174 self.StyleSetSpec(stc.STC_P_OPERATOR, p['operator'])
172 175 self.StyleSetSpec(stc.STC_P_COMMENTBLOCK, p['comment'])
173 176
174 177
175 178
176 179
177 180
178 181 def write(self, text):
179 182 """ Write given text to buffer, while translating the ansi escape
180 183 sequences.
181 184 """
182 185 segments = self.color_pat.split(text)
183 186 segment = segments.pop(0)
184 187 self.StartStyling(self.GetLength(), 0xFF)
185 188 self.AppendText(segment)
186 189
187 190 if segments:
188 191 ansi_tags = self.color_pat.findall(text)
189 192
190 193 for tag in ansi_tags:
191 194 i = segments.index(tag)
192 195 self.StartStyling(self.GetLength(), 0xFF)
193 196 self.AppendText(segments[i+1])
194 197
195 198 if tag != '0':
196 199 self.SetStyling(len(segments[i+1]),
197 200 self.ANSI_STYLES[tag][0])
198 201
199 202 segments.pop(i)
200 203
201 204 self.GotoPos(self.GetLength())
202 205
203 206
204 207 def new_prompt(self, prompt):
205 208 """ Prints a prompt at start of line, and move the start of the
206 209 current block there.
207 210
208 211 The prompt can be give with ascii escape sequences.
209 212 """
210 213 self.write(prompt)
211 214 # now we update our cursor giving end of prompt
212 215 self.current_prompt_pos = self.GetLength()
213 216 self.current_prompt_line = self.GetCurrentLine()
214 217
215 218 autoindent = self.indent * ' '
216 219 autoindent = autoindent.replace(' ','\t')
217 220 self.write(autoindent)
218 221
219 222
220 223 def replace_current_edit_buffer(self, text):
221 224 """ Replace currently entered command line with given text.
222 225 """
223 226 self.SetSelection(self.current_prompt_pos, self.GetLength())
224 227 self.ReplaceSelection(text)
225 228 self.GotoPos(self.GetLength())
226 229
227 230
228 231 def get_current_edit_buffer(self):
229 232 """ Returns the text in current edit buffer.
230 233 """
231 234 return self.GetTextRange(self.current_prompt_pos,
232 235 self.GetLength())
233 236
234 237
235 238 #--------------------------------------------------------------------------
236 239 # Private API
237 240 #--------------------------------------------------------------------------
238 241
239 242 def _apply_style(self):
240 243 """ Applies the colors for the different text elements and the
241 244 carret.
242 245 """
243 246 # FIXME: We need to do something for the fonts, but this is
244 247 # clearly not the right option.
245 248 #we define platform specific fonts
246 249 # if wx.Platform == '__WXMSW__':
247 250 # faces = { 'times': 'Times New Roman',
248 251 # 'mono' : 'Courier New',
249 252 # 'helv' : 'Arial',
250 253 # 'other': 'Comic Sans MS',
251 254 # 'size' : 10,
252 255 # 'size2': 8,
253 256 # }
254 257 # elif wx.Platform == '__WXMAC__':
255 258 # faces = { 'times': 'Times New Roman',
256 259 # 'mono' : 'Monaco',
257 260 # 'helv' : 'Arial',
258 261 # 'other': 'Comic Sans MS',
259 262 # 'size' : 10,
260 263 # 'size2': 8,
261 264 # }
262 265 # else:
263 266 # faces = { 'times': 'Times',
264 267 # 'mono' : 'Courier',
265 268 # 'helv' : 'Helvetica',
266 269 # 'other': 'new century schoolbook',
267 270 # 'size' : 10,
268 271 # 'size2': 8,
269 272 # }
270 273 # self.StyleSetSpec(stc.STC_STYLE_DEFAULT,
271 274 # "fore:%s,back:%s,size:%d,face:%s"
272 275 # % (self.ANSI_STYLES['0;30'][1],
273 276 # self.background_color,
274 277 # faces['size'], faces['mono']))
275 278
276 279 self.SetCaretForeground(self.carret_color)
277 280
278 281 self.StyleClearAll()
279 282 self.StyleSetSpec(stc.STC_STYLE_BRACELIGHT,
280 283 "fore:#FF0000,back:#0000FF,bold")
281 284 self.StyleSetSpec(stc.STC_STYLE_BRACEBAD,
282 285 "fore:#000000,back:#FF0000,bold")
283 286
284 287 for style in self.ANSI_STYLES.values():
285 288 self.StyleSetSpec(style[0], "bold,fore:%s" % style[1])
286 289
287 290
288 291 def removeFromTo(self, from_pos, to_pos):
289 292 if from_pos < to_pos:
290 293 self.SetSelection(from_pos, to_pos)
291 294 self.DeleteBack()
292 295
293 296
294 297 def selectFromTo(self, from_pos, to_pos):
295 298 self.SetSelectionStart(from_pos)
296 299 self.SetSelectionEnd(to_pos)
297 300
298 301
299 302 def writeCompletion(self, possibilities):
300 303 if self.autocomplete_mode == 'IPYTHON':
301 304 max_len = len(max(possibilities, key=len))
302 305 max_symbol = ' '*max_len
303 306
304 307 #now we check how much symbol we can put on a line...
305 308 test_buffer = max_symbol + ' '*4
306 309
307 310 allowed_symbols = 80/len(test_buffer)
308 311 if allowed_symbols == 0:
309 312 allowed_symbols = 1
310 313
311 314 pos = 1
312 315 buf = ''
313 316 for symbol in possibilities:
314 317 #buf += symbol+'\n'#*spaces)
315 318 if pos < allowed_symbols:
316 319 spaces = max_len - len(symbol) + 4
317 320 buf += symbol+' '*spaces
318 321 pos += 1
319 322 else:
320 323 buf += symbol+'\n'
321 324 pos = 1
322 325 self.write(buf)
323 326 else:
324 327 possibilities.sort() # Python sorts are case sensitive
325 328 self.AutoCompSetIgnoreCase(False)
326 329 self.AutoCompSetAutoHide(False)
327 330 #let compute the length ot last word
328 331 splitter = [' ', '(', '[', '{']
329 332 last_word = self.get_current_edit_buffer()
330 333 for breaker in splitter:
331 334 last_word = last_word.split(breaker)[-1]
332 335 self.AutoCompShow(len(last_word), " ".join(possibilities))
333 336
334 337
335 338 def _onKeypress(self, event, skip=True):
336 339 """ Key press callback used for correcting behavior for
337 340 console-like interfaces: the cursor is constraint to be after
338 341 the last prompt.
339 342
340 343 Return True if event as been catched.
341 344 """
342 345 catched = False
343 346 if self.AutoCompActive():
344 347 event.Skip()
345 348 else:
346 349 if event.KeyCode == wx.WXK_HOME:
347 350 if event.Modifiers in (wx.MOD_NONE, wx.MOD_WIN):
348 351 self.GotoPos(self.current_prompt_pos)
349 352 catched = True
350 353
351 354 elif event.Modifiers == wx.MOD_SHIFT:
352 355 self.selectFromTo(self.current_prompt_pos,
353 356 self.GetCurrentPos())
354 357 catched = True
355 358
356 359 elif event.KeyCode == wx.WXK_UP:
357 360 if self.GetCurrentLine() > self.current_prompt_line:
358 361 if self.GetCurrentLine() == self.current_prompt_line + 1 \
359 362 and self.GetColumn(self.GetCurrentPos()) < \
360 363 self.GetColumn(self.current_prompt_pos):
361 364 self.GotoPos(self.current_prompt_pos)
362 365 else:
363 366 event.Skip()
364 367 catched = True
365 368
366 369 elif event.KeyCode in (wx.WXK_LEFT, wx.WXK_BACK):
367 370 if self.GetCurrentPos() > self.current_prompt_pos:
368 371 event.Skip()
369 372 catched = True
370 373
371 374 if skip and not catched:
372 375 event.Skip()
373 376
374 377 if event.KeyCode not in (wx.WXK_PAGEUP, wx.WXK_PAGEDOWN)\
375 378 and event.Modifiers in (wx.MOD_NONE, wx.MOD_WIN,
376 379 wx.MOD_SHIFT):
377 380 # If cursor is outside the editing region, put it back.
378 381 if self.GetCurrentPos() < self.current_prompt_pos:
379 382 self.GotoPos(self.current_prompt_pos)
380 383
381 384 return catched
382 385
383 386
384 387 def OnUpdateUI(self, evt):
385 388 # check for matching braces
386 389 braceAtCaret = -1
387 390 braceOpposite = -1
388 391 charBefore = None
389 392 caretPos = self.GetCurrentPos()
390 393
391 394 if caretPos > 0:
392 395 charBefore = self.GetCharAt(caretPos - 1)
393 396 styleBefore = self.GetStyleAt(caretPos - 1)
394 397
395 398 # check before
396 399 if charBefore and chr(charBefore) in "[]{}()" and styleBefore == stc.STC_P_OPERATOR:
397 400 braceAtCaret = caretPos - 1
398 401
399 402 # check after
400 403 if braceAtCaret < 0:
401 404 charAfter = self.GetCharAt(caretPos)
402 405 styleAfter = self.GetStyleAt(caretPos)
403 406
404 407 if charAfter and chr(charAfter) in "[]{}()" and styleAfter == stc.STC_P_OPERATOR:
405 408 braceAtCaret = caretPos
406 409
407 410 if braceAtCaret >= 0:
408 411 braceOpposite = self.BraceMatch(braceAtCaret)
409 412
410 413 if braceAtCaret != -1 and braceOpposite == -1:
411 414 self.BraceBadLight(braceAtCaret)
412 415 else:
413 416 self.BraceHighlight(braceAtCaret, braceOpposite)
414 417
415 418
416 419 if __name__ == '__main__':
417 420 # Some simple code to test the console widget.
418 421 class MainWindow(wx.Frame):
419 422 def __init__(self, parent, id, title):
420 423 wx.Frame.__init__(self, parent, id, title, size=(300,250))
421 424 self._sizer = wx.BoxSizer(wx.VERTICAL)
422 425 self.console_widget = ConsoleWidget(self)
423 426 self._sizer.Add(self.console_widget, 1, wx.EXPAND)
424 427 self.SetSizer(self._sizer)
425 428 self.SetAutoLayout(1)
426 429 self.Show(True)
427 430
428 431 app = wx.PySimpleApp()
429 432 w = MainWindow(None, wx.ID_ANY, 'ConsoleWidget')
430 433 w.SetSize((780, 460))
431 434 w.Show()
432 435
433 436 app.MainLoop()
434 437
435 438
@@ -1,147 +1,180 b''
1 1 # encoding: utf-8
2 2 # -*- test-case-name: ipython1.frontend.cocoa.tests.test_cocoa_frontend -*-
3 3
4 4 """Classes to provide a Wx frontend to the
5 5 ipython1.kernel.engineservice.EngineService.
6 6
7 7 """
8 8
9 9 __docformat__ = "restructuredtext en"
10 10
11 11 #-------------------------------------------------------------------------------
12 12 # Copyright (C) 2008 The IPython Development Team
13 13 #
14 14 # Distributed under the terms of the BSD License. The full license is in
15 15 # the file COPYING, distributed as part of this software.
16 16 #-------------------------------------------------------------------------------
17 17
18 18 #-------------------------------------------------------------------------------
19 19 # Imports
20 20 #-------------------------------------------------------------------------------
21 21
22 22
23 23 import wx
24 24 from console_widget import ConsoleWidget
25
25 import re
26 26
27 27 import IPython
28 28 from IPython.kernel.engineservice import EngineService
29 29 from IPython.frontend.frontendbase import FrontEndBase
30 30
31 31
32 32 #-------------------------------------------------------------------------------
33 33 # Classes to implement the Wx frontend
34 34 #-------------------------------------------------------------------------------
35 35
36 36
37 37
38 38
39 39 class IPythonWxController(FrontEndBase, ConsoleWidget):
40 40
41 41 output_prompt = \
42 42 '\n\x01\x1b[0;31m\x02Out[\x01\x1b[1;31m\x02%i\x01\x1b[0;31m\x02]: \x01\x1b[0m\x02'
43 43
44 # Are we entering multi line input?
45 multi_line_input = False
46
47 # The added tab stop to the string. It may, for instance, come from
48 # copy and pasting something with tabs.
49 tab_stop = 0
50 # FIXME: We still have to deal with this.
51
44 52 #--------------------------------------------------------------------------
45 53 # Public API
46 54 #--------------------------------------------------------------------------
47 55
48 56 def __init__(self, parent, id=wx.ID_ANY, pos=wx.DefaultPosition,
49 57 size=wx.DefaultSize, style=wx.CLIP_CHILDREN,
50 58 *args, **kwds):
51 59 """ Create Shell instance.
52 60 """
53 61 ConsoleWidget.__init__(self, parent, id, pos, size, style)
54 62 FrontEndBase.__init__(self, engine=EngineService())
55 63
56 64 self.lines = {}
57 65
58 66 # Start the IPython engine
59 67 self.engine.startService()
60 68
61 69 # Capture Character keys
62 70 self.Bind(wx.EVT_KEY_UP, self._on_key_up)
63 71
64 72 #FIXME: print banner.
65 73 banner = """IPython1 %s -- An enhanced Interactive Python.""" \
66 74 % IPython.__version__
67 75
68 76
69 77 def appWillTerminate_(self, notification):
70 78 """appWillTerminate"""
71 79
72 80 self.engine.stopService()
73 81
74 82
75 83 def complete(self, token):
76 84 """Complete token in engine's user_ns
77 85
78 86 Parameters
79 87 ----------
80 88 token : string
81 89
82 90 Result
83 91 ------
84 92 Deferred result of
85 93 IPython.kernel.engineservice.IEngineBase.complete
86 94 """
87 95
88 96 return self.engine.complete(token)
89 97
90 98
91 99 def render_result(self, result):
92 100 if 'stdout' in result:
93 101 self.write(result['stdout'])
94 102 if 'display' in result:
95 103 self.write(self.output_prompt % result['number']
96 104 + result['display']['pprint'])
97 105
98 106
99 107 def render_error(self, failure):
100 108 self.insert_text('\n\n'+str(failure)+'\n\n')
101 109 return failure
102 110
103 111
104 112 #--------------------------------------------------------------------------
105 113 # Private API
106 114 #--------------------------------------------------------------------------
107 115
108 116
109 117 def _on_key_up(self, event, skip=True):
110 118 """ Capture the character events, let the parent
111 119 widget handle them, and put our logic afterward.
112 120 """
113 121 event.Skip()
114 122 # Capture enter
115 123 if event.KeyCode == 13 and \
116 124 event.Modifiers in (wx.MOD_NONE, wx.MOD_WIN):
117 125 self._on_enter()
118 126
119 127
120 128 def _on_enter(self):
121 129 """ Called when the return key is pressed in a line editing
122 130 buffer.
123 131 """
124 result = self.engine.shell.execute(self.get_current_edit_buffer())
132 current_buffer = self.get_current_edit_buffer()
133 current_buffer = current_buffer.replace('\r\n', '\n')
134 current_buffer = current_buffer.replace('\t', 4*' ')
135 if ( not self.multi_line_input
136 or re.findall(r"\n[\t ]*\n[\t ]*$", current_buffer)):
137 if self.is_complete(current_buffer):
138 result = self.engine.shell.execute(current_buffer)
125 139 self.render_result(result)
126 140 self.new_prompt(self.prompt % result['number'])
141 self.multi_line_input = False
142 else:
143 if self.multi_line_input:
144 self.write(self._get_indent_string(current_buffer[:-1]))
145 else:
146 self.multi_line_input = True
147 self.write('\t')
148 else:
149 self.write(self._get_indent_string(current_buffer[:-1]))
150
151
152 def _get_indent_string(self, string):
153 string = string.split('\n')[-1]
154 indent_chars = len(string) - len(string.lstrip())
155 indent_string = '\t'*(indent_chars // 4) + \
156 ' '*(indent_chars % 4)
157
158 return indent_string
159
127 160
128 161
129 162 if __name__ == '__main__':
130 163 class MainWindow(wx.Frame):
131 164 def __init__(self, parent, id, title):
132 165 wx.Frame.__init__(self, parent, id, title, size=(300,250))
133 166 self._sizer = wx.BoxSizer(wx.VERTICAL)
134 167 self.shell = IPythonWxController(self)
135 168 self._sizer.Add(self.shell, 1, wx.EXPAND)
136 169 self.SetSizer(self._sizer)
137 170 self.SetAutoLayout(1)
138 171 self.Show(True)
139 172
140 173 app = wx.PySimpleApp()
141 174 frame = MainWindow(None, wx.ID_ANY, 'Ipython')
142 175 frame.shell.SetFocus()
143 176 frame.SetSize((780, 460))
144 177 shell = frame.shell
145 178
146 179 #app.MainLoop()
147 180
General Comments 0
You need to be logged in to leave comments. Login now