From 7a6f5b2c1d83fe62c62f0c30cad28eb091d52dfe Mon Sep 17 00:00:00 2001 From: necoro <> Date: Fri, 20 Apr 2007 14:44:45 +0000 Subject: Made qt plugin-ready; lots of documentation --- portato/gui/qt/terminal.py | 71 +++++++++++++++++++++++++++++++++++++--------- 1 file changed, 57 insertions(+), 14 deletions(-) (limited to 'portato/gui/qt/terminal.py') diff --git a/portato/gui/qt/terminal.py b/portato/gui/qt/terminal.py index 2734aaf..85bea0e 100644 --- a/portato/gui/qt/terminal.py +++ b/portato/gui/qt/terminal.py @@ -46,6 +46,7 @@ backspace = 8 title_seq = ("\x1b", "]") title_end = "\x07" +# the attributes attr = {} attr[0] = None # normal attr[1] = BoldFormat() # bold @@ -61,8 +62,15 @@ attr[37] = ColorFormat("white") attr[39] = None # default class QtConsole (Console, Qt.QTextEdit): + """Self implemented emulation of a terminal emulation. + This only supports a subset of instructions known to normal terminals.""" def __init__ (self, parent): + """Constructor. + + @param parent: parent widget + @type parent: Qt.QWidget""" + Qt.QTextEdit.__init__(self, parent) self.pty = None @@ -74,14 +82,23 @@ class QtConsole (Console, Qt.QTextEdit): self.setReadOnly(True) + # we need these two signals, as threads are not allowed to access the GUI + # solution: thread sends signal, which is handled by the main loop Qt.QObject.connect(self, Qt.SIGNAL("doSomeWriting"), self._write) Qt.QObject.connect(self, Qt.SIGNAL("deletePrevChar()"), self._deletePrev) def _deletePrev (self): + """Deletes the previous character.""" self.textCursor().deletePreviousChar() def _write (self, text): - if text == esc_seq[0]: + """Writes some text. A text of "\\x1b" signals _write() to reload + the current char format. + + @param text: the text to print + @type text: string""" + + if text == esc_seq[0]: # \x1b -> reload format self.setCurrentCharFormat(self.get_format()) else: @@ -97,13 +114,16 @@ class QtConsole (Console, Qt.QTextEdit): self.ensureCursorVisible() def write(self, text): + """Convenience function for emitting the writing signal.""" self.emit(Qt.SIGNAL("doSomeWriting"), text) def start_new_thread (self): - self.run = True - self.current = Thread(target=self.__run, name="QtTerminal Listener") - self.current.setDaemon(True) # close application even if this thread is running - self.current.start() + """Starts a new thread, which will listen for some input. + @see: QtTerminal.__run()""" + self.run = True + self.current = Thread(target=self.__run, name="QtTerminal Listener") + self.current.setDaemon(True) # close application even if this thread is running + self.current.start() def set_pty (self, pty): if not self.running: @@ -111,21 +131,22 @@ class QtConsole (Console, Qt.QTextEdit): self.start_new_thread() self.running = True - else: - # quit current thread + else: # quit current thread self.run = False - # self.current.join() self.clear() self.pty = pty # set this after clearing to lose no chars :) self.start_new_thread() def __run (self): + """This function is mainly a loop, which looks for some new input at the terminal, + and parses it for text attributes.""" + while self.run: s = read(self.pty, 1) - if s == "": break + if s == "": break # nothing read -> finish - if ord(s) == backspace: + if ord(s) == backspace: # BS self.emit(Qt.SIGNAL("deletePrevChar()")) continue @@ -154,9 +175,16 @@ class QtConsole (Console, Qt.QTextEdit): self.write(s) def parse_seq (self, seq): - global attr + """Parses a sequence of bytes. + If a new attribute has been encountered, a new format is created and added + to the internal format queue. + + @param seq: sequence to parse + @type seq: string""" + + global attr # the dict of attributes - format = self.virgin_format() + format = self.virgin_format() if seq != reset_seq: # resettet -> done seq = seq.split(seq_sep) @@ -178,10 +206,9 @@ class QtConsole (Console, Qt.QTextEdit): break self.add_format(format) - self.write(esc_seq[0]) + self.write(esc_seq[0]) # write \x1b to signal the occurence of a new format def parse_title (self, seq): - if not seq.startswith("0;"): return @@ -191,15 +218,31 @@ class QtConsole (Console, Qt.QTextEdit): return self.title def add_format (self, format): + """Adds a format to the queue. + We have to take a queue, because the write-signals might occur asynchronus, + so we set a format for the wrong characters. + + @param format: the format to add + @type format: Qt.QTextCharFormat""" + self.formatLock.acquire() self.formatQueue.append(format) self.formatLock.release() def get_format (self): + """Returns a format from the queue. + We have to take a queue, because the write-signals might occur asynchronus, + so we set a format for the wrong characters. + + @returns: the popped format + @rtype: Qt.QTextCharFormat""" + self.formatLock.acquire() f = self.formatQueue.pop(0) self.formatLock.release() return f def virgin_format (self): + """The normal standard format. It is necessary to create it as a new one for some + dubious reasons ... only Qt.QGod knows why.""" return Qt.QTextCharFormat(self.stdFormat) -- cgit v1.2.3-70-g09d2