home *** CD-ROM | disk | FTP | other *** search
Wrap
# Source Generated with Decompyle++ # File: in.pyc (Python 2.6) __version__ = 0.9 __author__ = 'Laurent Dufrechou' __email__ = 'laurent.dufrechou _at_ gmail.com' __license__ = 'BSD' import wx import wx.stc as stc import re from StringIO import StringIO import sys import codecs import locale import time for enc in (locale.getpreferredencoding(), sys.getfilesystemencoding(), sys.getdefaultencoding()): try: codecs.lookup(enc) ENCODING = enc except LookupError: pass else: ENCODING = 'utf-8' from ipshell_nonblocking import NonBlockingIPShell class WxNonBlockingIPShell(NonBlockingIPShell): def __init__(self, parent, argv = [], user_ns = { }, user_global_ns = None, cin = None, cout = None, cerr = None, ask_exit_handler = None): NonBlockingIPShell.__init__(self, argv, user_ns, user_global_ns, cin, cout, cerr, ask_exit_handler) self.parent = parent self.ask_exit_callback = ask_exit_handler self._IP.exit = self._ask_exit def addGUIShortcut(self, text, func): wx.CallAfter(self.parent.add_button_handler, button_info = { 'text': text, 'func': self.parent.doExecuteLine(func) }) def _raw_input(self, prompt = ''): self.answer = None if self._threading == True: wx.CallAfter(self._yesNoBox, prompt) while self.answer is None: time.sleep(0.1) else: self._yesNoBox(prompt) return self.answer def _yesNoBox(self, prompt): dlg = wx.TextEntryDialog(self.parent, prompt, 'Input requested', 'Python') dlg.SetValue('') answer = '' if dlg.ShowModal() == wx.ID_OK: answer = dlg.GetValue() dlg.Destroy() self.answer = answer def _ask_exit(self): wx.CallAfter(self.ask_exit_callback, ()) def _after_execute(self): wx.CallAfter(self.parent.evtStateExecuteDone, ()) class WxConsoleView(stc.StyledTextCtrl): ANSI_STYLES_BLACK = { '0;30': [ 0, 'WHITE'], '0;31': [ 1, 'RED'], '0;32': [ 2, 'GREEN'], '0;33': [ 3, 'BROWN'], '0;34': [ 4, 'BLUE'], '0;35': [ 5, 'PURPLE'], '0;36': [ 6, 'CYAN'], '0;37': [ 7, 'LIGHT GREY'], '1;30': [ 8, 'DARK GREY'], '1;31': [ 9, 'RED'], '1;32': [ 10, 'SEA GREEN'], '1;33': [ 11, 'YELLOW'], '1;34': [ 12, 'LIGHT BLUE'], '1;35': [ 13, 'MEDIUM VIOLET RED'], '1;36': [ 14, 'LIGHT STEEL BLUE'], '1;37': [ 15, 'YELLOW'] } ANSI_STYLES_WHITE = { '0;30': [ 0, 'BLACK'], '0;31': [ 1, 'RED'], '0;32': [ 2, 'GREEN'], '0;33': [ 3, 'BROWN'], '0;34': [ 4, 'BLUE'], '0;35': [ 5, 'PURPLE'], '0;36': [ 6, 'CYAN'], '0;37': [ 7, 'LIGHT GREY'], '1;30': [ 8, 'DARK GREY'], '1;31': [ 9, 'RED'], '1;32': [ 10, 'SEA GREEN'], '1;33': [ 11, 'YELLOW'], '1;34': [ 12, 'LIGHT BLUE'], '1;35': [ 13, 'MEDIUM VIOLET RED'], '1;36': [ 14, 'LIGHT STEEL BLUE'], '1;37': [ 15, 'YELLOW'] } def __init__(self, parent, prompt, intro = '', background_color = 'BLACK', pos = wx.DefaultPosition, ID = -1, size = wx.DefaultSize, style = 0, autocomplete_mode = 'IPYTHON'): stc.StyledTextCtrl.__init__(self, parent, ID, pos, size, style) self.CmdKeyAssign(ord('B'), stc.STC_SCMOD_CTRL, stc.STC_CMD_ZOOMIN) self.CmdKeyAssign(ord('N'), stc.STC_SCMOD_CTRL, stc.STC_CMD_ZOOMOUT) self.SetEdgeMode(stc.STC_EDGE_LINE) self.SetEdgeColumn(80) self.SetEdgeColour(wx.LIGHT_GREY) self.SetEOLMode(stc.STC_EOL_CRLF) self.SetBufferedDraw(True) self.SetLayoutCache(stc.STC_CACHE_PAGE) self.SetUndoCollection(False) self.SetUseTabs(True) self.SetIndent(4) self.SetTabWidth(4) self.EnsureCaretVisible() self.SetMargins(3, 3) self.SetMarginWidth(0, 0) self.SetMarginWidth(1, 0) self.SetMarginWidth(2, 0) self.background_color = background_color self.buildStyles() self.indent = 0 self.prompt_count = 0 self.color_pat = re.compile('\x01?\x1b\\[(.*?)m\x02?') self.write(intro) self.setPrompt(prompt) self.showPrompt() self.autocomplete_mode = autocomplete_mode self.Bind(wx.EVT_KEY_DOWN, self._onKeypress) def buildStyles(self): if wx.Platform == '__WXMSW__': faces = { 'times': 'Times New Roman', 'mono': 'Courier New', 'helv': 'Arial', 'other': 'Comic Sans MS', 'size': 10, 'size2': 8 } elif wx.Platform == '__WXMAC__': faces = { 'times': 'Times New Roman', 'mono': 'Monaco', 'helv': 'Arial', 'other': 'Comic Sans MS', 'size': 10, 'size2': 8 } else: faces = { 'times': 'Times', 'mono': 'Courier', 'helv': 'Helvetica', 'other': 'new century schoolbook', 'size': 10, 'size2': 8 } if self.background_color != 'BLACK': self.background_color = 'WHITE' self.SetCaretForeground('BLACK') self.ANSI_STYLES = self.ANSI_STYLES_WHITE else: self.SetCaretForeground('WHITE') self.ANSI_STYLES = self.ANSI_STYLES_BLACK self.StyleSetSpec(stc.STC_STYLE_DEFAULT, 'fore:%s,back:%s,size:%d,face:%s' % (self.ANSI_STYLES['0;30'][1], self.background_color, faces['size'], faces['mono'])) self.StyleClearAll() self.StyleSetSpec(stc.STC_STYLE_BRACELIGHT, 'fore:#FF0000,back:#0000FF,bold') self.StyleSetSpec(stc.STC_STYLE_BRACEBAD, 'fore:#000000,back:#FF0000,bold') for style in self.ANSI_STYLES.values(): self.StyleSetSpec(style[0], 'bold,fore:%s' % style[1]) def setBackgroundColor(self, color): self.background_color = color self.buildStyles() def getBackgroundColor(self, color): return self.background_color def asyncWrite(self, text): try: wx.MutexGuiEnter() self.write(text) except KeyboardInterrupt: wx.MutexGuiLeave() raise KeyboardInterrupt wx.MutexGuiLeave() def write(self, text): segments = self.color_pat.split(text) segment = segments.pop(0) self.StartStyling(self.getCurrentLineEnd(), 255) self.AppendText(segment) if segments: ansi_tags = self.color_pat.findall(text) for tag in ansi_tags: i = segments.index(tag) self.StartStyling(self.getCurrentLineEnd(), 255) self.AppendText(segments[i + 1]) if tag != '0': self.SetStyling(len(segments[i + 1]), self.ANSI_STYLES[tag][0]) segments.pop(i) self.moveCursor(self.getCurrentLineEnd()) def getPromptLen(self): return len(str(self.prompt_count)) + 7 def setPrompt(self, prompt): self.prompt = prompt def setIndentation(self, indentation): self.indent = indentation def setPromptCount(self, count): self.prompt_count = count def showPrompt(self): self.write(self.prompt) self.current_start = self.getCurrentLineEnd() autoindent = self.indent * ' ' autoindent = autoindent.replace(' ', '\t') self.write(autoindent) def changeLine(self, text): self.SetSelection(self.getCurrentPromptStart(), self.getCurrentLineEnd()) self.ReplaceSelection(text) self.moveCursor(self.getCurrentLineEnd()) def getCurrentPromptStart(self): return self.current_start def getCurrentLineStart(self): return self.GotoLine(self.LineFromPosition(self.GetCurrentPos())) def getCurrentLineEnd(self): return self.GetLength() def getCurrentLine(self): return self.GetTextRange(self.getCurrentPromptStart(), self.getCurrentLineEnd()) def moveCursorOnNewValidKey(self): if self.GetCurrentPos() < self.getCurrentPromptStart(): self.GotoPos(self.getCurrentPromptStart()) def removeFromTo(self, from_pos, to_pos): if from_pos < to_pos: self.SetSelection(from_pos, to_pos) self.DeleteBack() def removeCurrentLine(self): self.LineDelete() def moveCursor(self, position): self.GotoPos(position) def getCursorPos(self): return self.GetCurrentPos() def selectFromTo(self, from_pos, to_pos): self.SetSelectionStart(from_pos) self.SetSelectionEnd(to_pos) def writeHistory(self, history): self.removeFromTo(self.getCurrentPromptStart(), self.getCurrentLineEnd()) self.changeLine(history) def setCompletionMethod(self, completion): if completion in ('IPYTHON', 'STC'): self.autocomplete_mode = completion else: raise AttributeError return completion in ('IPYTHON', 'STC') def getCompletionMethod(self, completion): return self.autocomplete_mode def writeCompletion(self, possibilities): if self.autocomplete_mode == 'IPYTHON': max_len = len(max(possibilities, key = len)) max_symbol = ' ' * max_len test_buffer = max_symbol + ' ' allowed_symbols = 80 / len(test_buffer) if allowed_symbols == 0: allowed_symbols = 1 pos = 1 buf = '' for symbol in possibilities: if pos < allowed_symbols: spaces = (max_len - len(symbol)) + 4 buf += symbol + ' ' * spaces pos += 1 continue buf += symbol + '\n' pos = 1 self.write(buf) else: possibilities.sort() self.AutoCompSetIgnoreCase(False) self.AutoCompSetAutoHide(False) splitter = [ ' ', '(', '[', '{', '='] last_word = self.getCurrentLine() for breaker in splitter: last_word = last_word.split(breaker)[-1] self.AutoCompShow(len(last_word), ' '.join(possibilities)) def _onKeypress(self, event, skip = True): if not self.AutoCompActive(): if event.GetKeyCode() == wx.WXK_HOME: if event.Modifiers == wx.MOD_NONE: self.moveCursorOnNewValidKey() self.moveCursor(self.getCurrentPromptStart()) return True if event.Modifiers == wx.MOD_SHIFT: self.moveCursorOnNewValidKey() self.selectFromTo(self.getCurrentPromptStart(), self.getCursorPos()) return True return False event.GetKeyCode() == wx.WXK_HOME if event.GetKeyCode() == wx.WXK_LEFT: if event.Modifiers == wx.MOD_NONE: self.moveCursorOnNewValidKey() self.moveCursor(self.getCursorPos() - 1) if self.getCursorPos() < self.getCurrentPromptStart(): self.moveCursor(self.getCurrentPromptStart()) return True elif event.GetKeyCode() == wx.WXK_BACK: self.moveCursorOnNewValidKey() if self.getCursorPos() > self.getCurrentPromptStart(): event.Skip() return True if skip: if event.GetKeyCode() not in [ wx.WXK_PAGEUP, wx.WXK_PAGEDOWN] and event.Modifiers == wx.MOD_NONE: self.moveCursorOnNewValidKey() event.Skip() return True return False event.Skip() def OnUpdateUI(self, evt): braceAtCaret = -1 braceOpposite = -1 charBefore = None caretPos = self.GetCurrentPos() if caretPos > 0: charBefore = self.GetCharAt(caretPos - 1) styleBefore = self.GetStyleAt(caretPos - 1) if charBefore and chr(charBefore) in '[]{}()' and styleBefore == stc.STC_P_OPERATOR: braceAtCaret = caretPos - 1 if braceAtCaret < 0: charAfter = self.GetCharAt(caretPos) styleAfter = self.GetStyleAt(caretPos) if charAfter and chr(charAfter) in '[]{}()' and styleAfter == stc.STC_P_OPERATOR: braceAtCaret = caretPos if braceAtCaret >= 0: braceOpposite = self.BraceMatch(braceAtCaret) if braceAtCaret != -1 and braceOpposite == -1: self.BraceBadLight(braceAtCaret) else: self.BraceHighlight(braceAtCaret, braceOpposite) class IPShellWidget(wx.Panel): def __init__(self, parent, intro = None, background_color = 'BLACK', add_button_handler = None, wx_ip_shell = None, user_ns = { }, user_global_ns = None): wx.Panel.__init__(self, parent, wx.ID_ANY) self.parent = parent self.cout = StringIO() self.add_button_handler = add_button_handler if wx_ip_shell is not None: self.IP = wx_ip_shell else: self.IP = WxNonBlockingIPShell(self, cout = self.cout, cerr = self.cout, ask_exit_handler = self.askExitCallback) if intro is None: welcome_text = 'Welcome to WxIPython Shell.\n\n' welcome_text += self.IP.get_banner() welcome_text += '!command -> Execute command in shell\n' welcome_text += 'TAB -> Autocompletion\n' else: welcome_text = intro self.text_ctrl = WxConsoleView(self, self.IP.get_prompt(), intro = welcome_text, background_color = background_color) option_text = wx.StaticText(self, -1, 'Options:') self.completion_option = wx.CheckBox(self, -1, 'Scintilla Completion') self.completion_option.SetToolTip(wx.ToolTip('Selects the completion type:\nEither Ipython default style or Scintilla one')) self.background_option = wx.CheckBox(self, -1, 'White Background') self.background_option.SetToolTip(wx.ToolTip('Selects the back ground color: BLACK or WHITE')) self.threading_option = wx.CheckBox(self, -1, 'Execute in thread') self.threading_option.SetToolTip(wx.ToolTip("Use threading: infinite loop don't freeze the GUI and commands can be breaked\nNo threading: maximum compatibility")) self.options = { 'completion': { 'value': 'IPYTHON', 'checkbox': self.completion_option, 'STC': True, 'IPYTHON': False, 'setfunc': self.text_ctrl.setCompletionMethod }, 'background_color': { 'value': 'BLACK', 'checkbox': self.background_option, 'WHITE': True, 'BLACK': False, 'setfunc': self.text_ctrl.setBackgroundColor }, 'threading': { 'value': 'True', 'checkbox': self.threading_option, 'True': True, 'False': False, 'setfunc': self.IP.set_threading } } self.cout.write = self.text_ctrl.asyncWrite self.reloadOptions(self.options) self.text_ctrl.Bind(wx.EVT_KEY_DOWN, self.keyPress) self.completion_option.Bind(wx.EVT_CHECKBOX, self.evtCheckOptionCompletion) self.background_option.Bind(wx.EVT_CHECKBOX, self.evtCheckOptionBackgroundColor) self.threading_option.Bind(wx.EVT_CHECKBOX, self.evtCheckOptionThreading) sizer = wx.BoxSizer(wx.VERTICAL) sizer.Add(self.text_ctrl, 1, wx.EXPAND) option_sizer = wx.BoxSizer(wx.HORIZONTAL) sizer.Add(option_sizer, 0) option_sizer.AddMany([ (10, 20), (option_text, 0, wx.ALIGN_CENTER_VERTICAL), (5, 5), (self.completion_option, 0, wx.ALIGN_CENTER_VERTICAL), (8, 8), (self.background_option, 0, wx.ALIGN_CENTER_VERTICAL), (8, 8), (self.threading_option, 0, wx.ALIGN_CENTER_VERTICAL)]) self.SetAutoLayout(True) sizer.Fit(self) sizer.SetSizeHints(self) self.SetSizer(sizer) self.SetFocus() self.setCurrentState('IDLE') self.pager_state = 'DONE' self.raw_input_current_line = 0 def askExitCallback(self, event): self.askExitHandler(event) def stateDoExecuteLine(self): lines = self.text_ctrl.getCurrentLine() self.text_ctrl.write('\n') lines_to_execute = lines.replace('\t', ' ') lines_to_execute = lines_to_execute.replace('\r', '') self.IP.do_execute(lines_to_execute.encode(ENCODING)) self.updateHistoryTracker(lines) if self.text_ctrl.getCursorPos() != 0: self.text_ctrl.removeCurrentLine() self.setCurrentState('WAIT_END_OF_EXECUTION') def evtStateExecuteDone(self, evt): self.doc = self.IP.get_doc_text() self.help = self.IP.get_help_text() if self.doc: self.pager_lines = self.doc[7:].split('\n') self.pager_state = 'INIT' self.setCurrentState('SHOW_DOC') self.pager(self.doc) elif self.help: self.pager_lines = self.help.split('\n') self.pager_state = 'INIT' self.setCurrentState('SHOW_DOC') self.pager(self.help) elif self.text_ctrl.getCursorPos() != 0: self.text_ctrl.removeCurrentLine() self.stateShowPrompt() def stateShowPrompt(self): self.setCurrentState('SHOW_PROMPT') self.text_ctrl.setPrompt(self.IP.get_prompt()) self.text_ctrl.setIndentation(self.IP.get_indentation()) self.text_ctrl.setPromptCount(self.IP.get_prompt_count()) self.text_ctrl.showPrompt() self.IP.init_history_index() self.setCurrentState('IDLE') def setCurrentState(self, state): self.cur_state = state self.updateStatusTracker(self.cur_state) def pager(self, text): if self.pager_state == 'INIT': self.pager_nb_lines = len(self.pager_lines) self.pager_index = 0 self.pager_do_remove = False self.text_ctrl.write('\n') self.pager_state = 'PROCESS_LINES' if self.pager_state == 'PROCESS_LINES': if self.pager_do_remove == True: self.text_ctrl.removeCurrentLine() self.pager_do_remove = False if self.pager_nb_lines > 10: if self.pager_index > 0: self.text_ctrl.write('>\x01\x1b[1;36m\x02' + self.pager_lines[self.pager_index] + '\n') else: self.text_ctrl.write('\x01\x1b[1;36m\x02 ' + self.pager_lines[self.pager_index] + '\n') for line in self.pager_lines[self.pager_index + 1:self.pager_index + 9]: self.text_ctrl.write('\x01\x1b[1;36m\x02 ' + line + '\n') self.pager_index += 10 self.pager_nb_lines -= 10 self.text_ctrl.write("--- Push Enter to continue or 'Q' to quit---") self.pager_do_remove = True self.pager_state = 'WAITING' return None if self.pager_nb_lines > 0: for line in self.pager_lines[self.pager_index:]: self.text_ctrl.write('\x01\x1b[1;36m\x02 ' + line + '\n') self.pager_nb_lines = 0 self.pager_state = 'DONE' self.stateShowPrompt() def keyPress(self, event): if event.GetKeyCode() == ord('C'): if event.Modifiers == wx.MOD_CONTROL or event.Modifiers == wx.MOD_ALT: if self.cur_state == 'WAIT_END_OF_EXECUTION': self.IP.ce.raise_exc(KeyboardInterrupt) return None if self.cur_state == 'COMPLETING': if not self.text_ctrl.AutoCompActive(): self.cur_state = 'IDLE' else: event.Skip() if self.cur_state == 'WAITING_USER_INPUT': event.Skip() def evtCheckOptionCompletion(self, event): if event.IsChecked(): self.options['completion']['value'] = 'STC' else: self.options['completion']['value'] = 'IPYTHON' self.text_ctrl.setCompletionMethod(self.options['completion']['value']) self.updateOptionTracker('completion', self.options['completion']['value']) self.text_ctrl.SetFocus() def evtCheckOptionBackgroundColor(self, event): if event.IsChecked(): self.options['background_color']['value'] = 'WHITE' else: self.options['background_color']['value'] = 'BLACK' self.text_ctrl.setBackgroundColor(self.options['background_color']['value']) self.updateOptionTracker('background_color', self.options['background_color']['value']) self.text_ctrl.SetFocus() def evtCheckOptionThreading(self, event): if event.IsChecked(): self.options['threading']['value'] = 'True' self.IP.set_threading(True) self.cout.write = self.text_ctrl.asyncWrite else: self.options['threading']['value'] = 'False' self.IP.set_threading(False) self.cout.write = self.text_ctrl.write self.updateOptionTracker('threading', self.options['threading']['value']) self.text_ctrl.SetFocus() def getOptions(self): return self.options def reloadOptions(self, options): self.options = options for key in self.options.keys(): value = self.options[key]['value'] self.options[key]['checkbox'].SetValue(self.options[key][value]) self.options[key]['setfunc'](value) if self.options['threading']['value'] == 'True': self.IP.set_threading(True) self.cout.write = self.text_ctrl.asyncWrite else: self.IP.set_threading(False) self.cout.write = self.text_ctrl.write def updateOptionTracker(self, name, value): pass def setOptionTrackerHook(self, func): self.updateOptionTracker = func def updateHistoryTracker(self, command_line): pass def setHistoryTrackerHook(self, func): self.updateHistoryTracker = func def updateStatusTracker(self, status): pass def setStatusTrackerHook(self, func): self.updateStatusTracker = func def askExitHandler(self, event): self.text_ctrl.write('\nExit callback has not been set.') def setAskExitHandler(self, func): self.askExitHandler = func if __name__ == '__main__': class MainWindow(wx.Frame): def __init__(self, parent, id, title): wx.Frame.__init__(self, parent, id, title, size = (300, 250)) self._sizer = wx.BoxSizer(wx.VERTICAL) self.shell = IPShellWidget(self) self._sizer.Add(self.shell, 1, wx.EXPAND) self.SetSizer(self._sizer) self.SetAutoLayout(1) self.Show(True) app = wx.PySimpleApp() frame = MainWindow(None, wx.ID_ANY, 'Ipython') frame.SetSize((780, 460)) shell = frame.shell app.MainLoop()