summaryrefslogtreecommitdiff
path: root/portato/gui/qt/terminal.py
diff options
context:
space:
mode:
Diffstat (limited to 'portato/gui/qt/terminal.py')
-rw-r--r--portato/gui/qt/terminal.py71
1 files changed, 57 insertions, 14 deletions
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)