--- old/org.gvsig.scripting/org.gvsig.scripting.app/org.gvsig.scripting.app.mainplugin/src/main/resources-plugin/scripting/lib/console/console.py 2016-09-06 11:49:08.286049214 +0200 +++ new/org.gvsig.scripting/org.gvsig.scripting.app/org.gvsig.scripting.app.mainplugin/src/main/resources-plugin/scripting/lib/console/console.py 2016-09-06 16:21:49.628916688 +0200 @@ -41,7 +41,7 @@ self.frame = frame # TODO do I need a reference to frame after the constructor? self.history = History(self) - self.bs = 0 # what is this? + self.promptPosition = 0 # command buffer self.buffer = [] @@ -59,6 +59,7 @@ keyBindings = [ (KeyEvent.VK_ENTER, 0, "jython.enter", self.enter), (KeyEvent.VK_DELETE, 0, "jython.delete", self.delete), + (KeyEvent.VK_BACK_SPACE, 0, "jython.backspace", self.backspace), (KeyEvent.VK_HOME, 0, "jython.home", self.home), (KeyEvent.VK_UP, 0, "jython.up", self.history.historyUp), (KeyEvent.VK_DOWN, 0, "jython.down", self.history.historyDown), @@ -183,6 +184,20 @@ self.popup.show() self.popup.list.setSelectedIndex(0) + def beyondPrompt(self, considerCurrent=True, considerSelection=False): + """Determines wheter the cursor is in the editable area + (i.e. beyond the last prompt position)""" + caret = self.output.caretPosition + caret0 = caret + if considerCurrent: + caret = caret + 1 + if considerSelection: + if self.output.selectedText: + caret = self.output.selectionEnd + if caret > self.promptPosition: + return True + return False + def inLastLine(self, include = 1): """ Determines whether the cursor is in the last line """ limits = self.__lastLine() @@ -240,35 +255,40 @@ self.doc.remove(offset[0], offset[1]-offset[0]-1) self.__addOutput(self.infoColor, text) + def __do_delete(self, event, pos=0): + if self.output.selectedText: + start = max(self.output.selectionStart, self.promptPosition) + self.doc.remove(start, self.output.selectionEnd - start) + else: + self.doc.remove(self.output.caretPosition + pos, 1) + # don't allow prompt to be deleted - # this will cause problems when history can contain multiple lines def delete(self, event): - """ Intercepts delete events only allowing it to work in the last line """ - if self.inLastLine(): - if self.output.selectedText: - self.doc.remove(self.output.selectionStart, self.output.selectionEnd - self.output.selectionStart) - elif self.output.caretPosition < self.doc.length: - self.doc.remove(self.output.caretPosition, 1) + """ Intercepts backspace events only allowing it to work in the last line """ + if self.beyondPrompt(considerCurrent=True, considerSelection=True): + self.__do_delete(event) + + + # don't allow prompt to be deleted + def backspace(self, event): + """ Intercepts backspace events only allowing it to work in the last line """ + if self.beyondPrompt(considerCurrent=False, considerSelection=True): + self.__do_delete(event, -1) # why is there a keyTyped and a keyPressed? def keyTyped(self, event): - #print >> sys.stderr, "keyTyped", event.getKeyCode() - if not self.inLastLine(): - event.consume() - if self.bs: - event.consume() - self.bs=0 + if not self.beyondPrompt(): + self.output.setCaretPosition(self.doc.length) def keyPressed(self, event): + # skip Shift + delete and shift + backspace as the are incorrectly managed + if event.keyCode == KeyEvent.VK_BACK_SPACE or event.keyCode == KeyEvent.VK_DELETE: + if event.modifiers > 0: + event.consume() + if self.popup.visible: self.popup.key(event) - #print >> sys.stderr, "keyPressed", event.getKeyCode() - if event.keyCode == KeyEvent.VK_BACK_SPACE: - offsets = self.__lastLine() - if not self.inLastLine(include=0): - self.bs = 1 - else: - self.bs = 0 + # TODO refactor me def write(self, text): @@ -276,21 +296,27 @@ def printResult(self, msg): """ Prints the results of an operation """ - self.__addOutput(self.output.foreground, "\n" + str(msg)) + self.__addOutput(self.output.foreground, msg, True) def printError(self, msg): - self.__addOutput(self.errorColor, "\n" + str(msg)) + self.__addOutput(self.errorColor, msg, True) def printOnProcess(self): """ Prints the process symbol """ - self.__addOutput(self.infoColor, "\n" + Console.PROCESS) + self.__addOutput(self.infoColor, Console.PROCESS, True) def printPrompt(self): """ Prints the prompt """ - self.__addOutput(self.infoColor, "\n" + Console.PROMPT) + self.__addOutput(self.infoColor, Console.PROMPT, True) + self.promptPosition = self.doc.length - def __addOutput(self, color, msg): + def __addOutput(self, color, msg, new_line=False): """ Adds the output to the text area using a given color """ + if new_line: + if isinstance(msg, unicode): + msg = u"\n" + msg + else: + msg = "\n" + str(msg) from javax.swing.text import BadLocationException style = SimpleAttributeSet()