class PythonWindow(KeyListener): def __init__(self): self.frame = JFrame("Python Window") self.historyList = JList(DefaultListModel()) self.historyList.cellRenderer = MyListCellRenderer() #self.historyPanel.layout = BoxLayout( # self.historyPanel, # BoxLayout.Y_AXIS #) scrollpane = JScrollPane() # JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, # JScrollPane.HORIZONTAL_SCROLLBAR_NEVER #) # scrollpane.preferredSize = 400, 800 inputPanel = JPanel() inputPanel.layout = GridLayout(1, 1) self.input = JTextArea("") self.input.border = BorderFactory.createEmptyBorder(5, 5, 5, 5) self.input.tabSize = 4 self.input.font = Font("Monospaced", Font.PLAIN, 12) #self.input.preferredSize = 500, 200 self.input.addKeyListener(self) #self.button = JButton('Run', actionPerformed=self.run) inputPanel.add(self.input) #inputPanel.add(self.button) scrollpane.viewport.view = self.historyList self.frame.add(scrollpane, BorderLayout.CENTER) self.frame.add(inputPanel, BorderLayout.PAGE_END) self.frame.size = 500, 600 self.frame.visible = False def toggle_visibility(self): self.frame.visible = not self.frame.visible def add(self, text, type="input"): self.historyList.model.addElement({"text": text, "type": type}) self.historyList.validate() self.frame.validate() last = self.historyList.model.getSize() - 1 self.historyList.ensureIndexIsVisible(last) def write(self, text): self.add(text, "output") def run(self, evt): source = self.input.text if not source.strip(): self.input.text = "" return processed_source = source.replace("$", "geo.") code = interface.compileinteractive(processed_source) if code in ("continue", "error"): code = interface.compilemodule(processed_source) if code == "error": return self.add(source.strip()) result = interface.run(code) if result == "OK": self.input.text = "" def keyPressed(self, evt): pass def keyReleased(self, evt): pass def keyTyped(self, evt): if evt.keyChar == '\n': # Only try to run compound statements when they end with # two \n source = self.input.text lines = source.split("\n") if lines[0].rstrip().endswith(":") and not source.endswith("\n\n"): for i, c in enumerate(lines[-2]): if c not in ' \t': break else: self.run(evt) return prefix = lines[-2][:i] if lines[-2].endswith(":"): prefix += '\t' self.input.text = source + prefix else: self.run(evt)
class PythonWindow(KeyListener): def __init__(self): self.frame = JFrame("Python Window") #self.historyList = JList(DefaultListModel()) #self.historyList.cellRenderer = MyListCellRenderer() scrollpane = JScrollPane() inputPanel = JPanel() inputPanel.layout = GridLayout(1, 1) self.input = JTextArea("") self.input.border = BorderFactory.createEmptyBorder(5, 5, 5, 5) self.input.tabSize = 4 self.input.font = Font("Monospaced", Font.PLAIN, 12) self.input.addKeyListener(self) inputPanel.add(self.input) self.outputpane = OutputPane() scrollpane.viewport.view = self.outputpane.textpane #self.historyList self.frame.add(scrollpane, BorderLayout.CENTER) self.frame.add(inputPanel, BorderLayout.PAGE_END) self.frame.size = 500, 600 self.frame.visible = False self.component = None def toggle_visibility(self): self.frame.visible = not self.frame.visible def add_component(self, c): self.remove_component() self.frame.add(c, BorderLayout.PAGE_START) self.component = c def remove_component(self): if self.component is not None: self.frame.remove(self.component) self.component = None def add(self, text, type="input"): self.outputpane.addtext(text, type) #self.historyList.model.addElement({"text": text, "type": type}) #self.historyList.validate() self.frame.validate() #last = self.historyList.model.getSize() - 1 #self.historyList.ensureIndexIsVisible(last) def error(self, text): self.outputpane.addtext(text, "error", ensure_newline=True) def write(self, text): self.add(text, "output") def run(self, evt): source = self.input.text if not source.strip(): self.input.text = "" return processed_source = source.replace("$", "geo.") code = interface.compileinteractive(processed_source) if code in ("continue", "error"): code = interface.compilemodule(processed_source) if code == "error": return source = source.strip() + '\n' self.outputpane.addtext(source, "input", ensure_newline=True) result = interface.run(code) if result == "OK": self.input.text = "" def keyPressed(self, evt): pass def keyReleased(self, evt): pass def keyTyped(self, evt): if evt.keyChar == '\n': # Only try to run compound statements when they end with # two \n source = self.input.text lines = source.split("\n") if lines[0].rstrip().endswith(":") and not source.endswith("\n\n"): for i, c in enumerate(lines[-2]): if c not in ' \t': break else: self.run(evt) return prefix = lines[-2][:i] if lines[-2].endswith(":"): prefix += '\t' self.input.text = source + prefix else: self.run(evt)
class PythonWindow(KeyListener, DocumentListener, ActionListener): def __init__(self, interface): self.interface = interface self.frame = JFrame("Python Window") tabs = JTabbedPane() # Create Interactive Pane interactive_pane = JPanel(BorderLayout()) scrollpane = JScrollPane() inputPanel = JPanel() inputPanel.layout = GridLayout(1, 1) self.check_disabled = LockManager() self.input = InteractiveInput(self.check_disabled, self.runcode) self.input.component.document.addDocumentListener(self) inputPanel.add(self.input.component) self.outputpane = OutputPane() scrollpane.viewport.view = self.outputpane.textpane interactive_pane.add(scrollpane, BorderLayout.CENTER) interactive_pane.add(inputPanel, BorderLayout.PAGE_END) # Create Script Pane script_pane = JPanel(BorderLayout()) scrollpane = JScrollPane() self.script_area = script_area = InputPane() line_numbers = LineNumbering(self.script_area.component) scrollpane.viewport.view = self.script_area.component scrollpane.rowHeaderView = line_numbers.component script_pane.add(scrollpane, BorderLayout.CENTER) tabs.addTab("Interactive", interactive_pane) tabs.addTab("Script", script_pane) self.frame.add(tabs) self.frame.size = 500, 600 self.frame.visible = False self.component = None self.make_menubar() self.history = InputHistory() def make_menubar(self): shortcut = Toolkit.getDefaultToolkit().menuShortcutKeyMask menubar = JMenuBar() def new_item(title, cmd, key, mod=shortcut): item = JMenuItem(title, actionCommand=cmd) item.accelerator = KeyStroke.getKeyStroke(key, mod) item.addActionListener(self) return item filemenu = JMenu("File") menubar.add(filemenu) fm = self.file_manager = FileManager(self) item = new_item("Run Python File...", "load", KeyEvent.VK_L) filemenu.add(item) item = new_item("Run Python File", "reload", KeyEvent.VK_R) item.enabled = False self.reload_menuitem = item filemenu.add(item) filemenu.addSeparator() item = new_item("Open Python Script...", "open", KeyEvent.VK_O) filemenu.add(item) item = new_item("Save Python Script", "save", KeyEvent.VK_S) item.enabled = False self.save_menuitem = item filemenu.add(item) item = new_item("Save Python Script As...", "save_as", KeyEvent.VK_S, mod = shortcut + ActionEvent.SHIFT_MASK) filemenu.add(item) editmenu = JMenu("Edit") menubar.add(editmenu) editmenu.add(new_item("Cut", "cut", KeyEvent.VK_X)) editmenu.add(new_item("Copy", "copy", KeyEvent.VK_C)) editmenu.add(new_item("Paste", "paste", KeyEvent.VK_V)) editmenu.addSeparator() item = new_item("Run Script", "runscript", KeyEvent.VK_E) editmenu.add(item) item = new_item("Run Selection", "runselection", KeyEvent.VK_E, mod=shortcut | ActionEvent.SHIFT_MASK) editmenu.add(item) editmenu.addSeparator() item = new_item("Indent Selection", "indentselection", KeyEvent.VK_CLOSE_BRACKET) editmenu.add(item) item = new_item("Dedent Selection", "dedentselection", KeyEvent.VK_OPEN_BRACKET) editmenu.add(item) shellmenu = JMenu("Interactive") menubar.add(shellmenu) item = new_item("Previous Input", "up", KeyEvent.VK_UP, mod=ActionEvent.ALT_MASK) shellmenu.add(item) item = new_item("Next Input", "down", KeyEvent.VK_DOWN, mod=ActionEvent.ALT_MASK) shellmenu.add(item) self.frame.setJMenuBar(menubar) def toggle_visibility(self): self.frame.visible = not self.frame.visible def add_component(self, c): self.remove_component() self.frame.add(c, BorderLayout.PAGE_START) self.component = c def remove_component(self): if self.component is not None: self.frame.remove(self.component) self.component = None def add(self, text, type="input"): self.outputpane.addtext(text, type) self.frame.validate() def error(self, text): self.outputpane.addtext(text, "error", ensure_newline=True) def write(self, text): self.add(text, "output") # Code execution methods def runcode(self, source, interactive=True): if not source.strip(): return True processed_source = source.replace("$", "geo.") code = self.interface.compileinteractive(processed_source) if code in ("continue", "error"): code = self.interface.compilemodule(processed_source) if code == "error": return if code == "error": return False source = source.strip() if interactive: self.history.append(source) self.current_text = "" self.outputpane.addtext(source +'\n', "input", ensure_newline=True) self.interface.run(code) return True def run(self): source = self.input.text if not source.strip(): self.input.text = "" return processed_source = source.replace("$", "geo.") code = self.interface.compileinteractive(processed_source) if code in ("continue", "error"): code = self.interface.compilemodule(processed_source) if code == "error": return source = source.strip() self.history.append(source) self.outputpane.addtext(source +'\n', "input", ensure_newline=True) result = self.interface.run(code) if result == "OK": self.input.text = "" def execfile(self, path): return execfile(path, self.interface.namespace) # Implementation of KeyListener def keyPressed(self, evt): pass def keyReleased(self, evt): pass def keyTyped(self, evt): if evt.keyChar == '\n': text = self.input.text if text.endswith('\n\n'): self.run() return t = text.rstrip() if '\n' not in t and not t.endswith(':'): self.run() return offset = self.input.caretPosition - 1 indent = None if offset: lines = text[:offset].rsplit('\n', 1) if len(lines) == 1: line = text[:offset] else: line = lines[1] indent = re.match('\\s*', line).group(0) if len(indent) == len(line): # No non-whitespace on this line if len(text) == offset + 1: self.run() return elif text[offset - 1] == ':': indent += '\t' if indent: with self.check_disabled: self.input.text = text[:offset + 1] + indent + text[offset + 1:] self.input.caretPosition = offset + len(indent) + 1 # Implementation of DocumentListener def update_current_text(self): if not self.check_disabled: self.current_text = self.input.input self.history.reset_position() def changedUpdate(self, evt): pass def insertUpdate(self, evt): self.update_current_text() def removeUpdate(self, evt): self.update_current_text() # Implementation of ActionListener def actionPerformed(self, evt): try: getattr(self, "action_" + evt.actionCommand)(evt) except AttributeError: pass # Navigating history def action_up(self, evt): """Move back in history""" try: with self.check_disabled: self.input.input = self.history.back() except InputHistory.OutOfBounds: pass def action_down(self, evt): """Move forward in history""" try: with self.check_disabled: self.input.input = self.history.forward() except InputHistory.OutOfBounds: self.input.input = self.current_text self.history.reset_position() # Script actions def action_runscript(self, evt): """Run script""" self.runcode(self.script_area.input, interactive=False) def action_runselection(self, evt): """Run selected text in script""" code = self.script_area.component.selectedText.strip() self.runcode(code, interactive=False) def action_indentselection(self, evt): component = self.script_area.component lines = component.selectedText.split("\n") for i, line in enumerate(lines): if line: lines[i] = "\t" + line component.replaceSelection("\n".join(lines)) def action_dedentselection(self, evt): component = self.script_area.component lines = component.selectedText.split("\n") for i, line in enumerate(lines): if line.startswith("\t"): lines[i] = line[1:] elif line.startswith(" "): lines[i] = line[4:] component.replaceSelection("\n".join(lines)) # Saving / loading scripts def action_open(self, evt): self.file_manager.open_script() if self.file_manager.script_path: self.save_menuitem.enabled = True self.save_menuitem.text = "Save " + self.file_manager.script_path def action_save(self, evt): self.file_manager.save_script() def action_save_as(self, evt): self.file_manager.save_script_as() if self.file_manager.script_path: self.save_menuitem.enabled = True self.save_menuitem.text = "Save " + self.file_manager.script_path def action_load(self, evt): self.file_manager.load_script() if self.file_manager.load_path: self.reload_menuitem.enabled = True self.reload_menuitem.text = "Run " + self.file_manager.load_path def action_reload(self, evt): self.file_manager.reload_script()