# -*- coding: utf-8 -*-
import sys, pluginsystem
from PyQt4 import QtCore, QtGui
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from QCustomTextBrowser import QCustomTextBrowser
class QTextArea(QWidget):
def __init__(self, parent=None):
QWidget.__init__(self, parent)
self.parent = parent
self.setAttribute(Qt.WA_DeleteOnClose)
self.commandHistory = []
self.commandHistory.append("")
self.commandHistoryIndex = 0
self.tablayout = QVBoxLayout(self)
self.textbrowser = QCustomTextBrowser(self)
self.textbrowser.setup(self)
self.textbrowser.setAcceptRichText(True)
self.textbrowser.setReadOnly(True)
self.textbrowser.setOpenExternalLinks(True)
self.tablayout.addWidget(self.textbrowser)
self.setLayout(self.tablayout)
self.cursor = QTextCursor(self.textbrowser.document())
self.scrollBar = self.textbrowser.verticalScrollBar()
self.textbrowser.installEventFilter(self)
if len(self.parent.gconfig_others[2]) > 0:
self.printString(self.parent.gconfig_others[2], False, False)
self.printString("", True, len(self.parent.gconfig_others[2]) > 0)
def closeEvent(self, event):
for child in self.children():
try:
child.deleteLater()
except:
pass
self.setParent(None)
self.deleteLater()
def eventFilter(self, obj, e):
try:
if e.type() == QEvent.KeyPress:
if e.key() == Qt.Key_Up or e.key() == Qt.Key_Down or e.key() == Qt.Key_Left or e.key() == Qt.Key_Right:
self.keyPressEvent(e)
return True
elif e.key() == Qt.Key_Space or e.key() == Qt.Key_Tab:
self.keyPressEvent(e)
return True
else:
return False
else:
return False
except:
return False
def keyPressEvent(self, e):
cmd = "" #Don't touch this!
if e.key() == Qt.Key_Return or e.key() == Qt.Key_Enter:
if not self.cursor.atEnd():
self.cursor.movePosition(QTextCursor.End)
self.cursor.insertHtml(self.parent.lastChar)
self.cursor.select(QTextCursor.LineUnderCursor)
if not self.cursor.selectedText() == self.toPlainText(self.parent.prompt + self.parent.lastChar):
selectedtext = str(self.cursor.selectedText())
if selectedtext.startswith(self.toPlainText(self.parent.prompt)) and selectedtext.endswith(self.toPlainText(self.parent.lastChar)):
if len(self.toPlainText(self.parent.lastChar)) == 0:
cmd = self.cursor.selectedText()[len(self.toPlainText(self.parent.prompt)):]
else:
cmd = self.cursor.selectedText()[len(self.toPlainText(self.parent.prompt)):-len(self.toPlainText(self.parent.lastChar))]
self.cursor.clearSelection()
else:
self.cursor.clearSelection()
self.cursor.movePosition(QTextCursor.PreviousCharacter)
while not self.cursorAtStartOfNewPromptLine():
cmd += self.previousChar()
self.cursor.movePosition(QTextCursor.PreviousCharacter)
cmd = cmd[::-1]
cmd = cmd[len(self.parent.prompt):]
print cmd
self.commandHistory.append(cmd)
self.printString(cmd + "<br>", True, False)
self.analyzeCommand(self.toPlainText(cmd))
else:
self.cursor.clearSelection()
self.printString(cmd + "<br>", True, False)
self.printString("", True, not cmd == "")
self.cursor.movePosition(QTextCursor.Up)
self.cursor.select(QTextCursor.LineUnderCursor)
if self.cursor.selectedText() == "":
self.cursor.clearSelection()
self.cursor.movePosition(QTextCursor.Down)
self.cursor.deletePreviousChar()
self.cursor.movePosition(QTextCursor.End)
else:
self.cursor.clearSelection()
self.cursor.movePosition(QTextCursor.End)
self.commandHistoryIndex = len(self.commandHistory)
self.scrollBar.setValue(self.scrollBar.maximum())
elif e.key() == Qt.Key_X and (e.modifiers() & Qt.ControlModifier):
self.textbrowser.cmcut()
elif e.key() == Qt.Key_C and (e.modifiers() & Qt.ControlModifier):
self.textbrowser.cmcopy()
elif e.key() == Qt.Key_V and (e.modifiers() & Qt.ControlModifier):
self.textbrowser.cmpaste()
elif e.key() == Qt.Key_Left and (e.modifiers() & Qt.ControlModifier):
if self.parent.tabwidget.currentIndex() == 0:
self.parent.tabwidget.setCurrentIndex(self.parent.tabwidget.count()-1)
else:
self.parent.tabwidget.setCurrentIndex(self.parent.tabwidget.currentIndex()-1)
elif e.key() == Qt.Key_Right and (e.modifiers() & Qt.ControlModifier):
if self.parent.tabwidget.currentIndex() == self.parent.tabwidget.count()-1:
self.parent.tabwidget.setCurrentIndex(0)
else:
self.parent.tabwidget.setCurrentIndex(self.parent.tabwidget.currentIndex()+1)
elif e.key() == Qt.Key_Backspace:
if self.cursor.atEnd():
if self.cursorCanMoveLeft():
self.cursor.deletePreviousChar()
self.cursor.deletePreviousChar()
self.cursor.insertHtml(self.parent.lastChar)
else:
if self.cursorCanMoveLeft():
self.cursor.movePosition(QTextCursor.PreviousCharacter)
self.cursor.deletePreviousChar()
self.cursor.movePosition(QTextCursor.NextCharacter)
elif e.key() == Qt.Key_Delete:
if not self.cursor.atEnd():
self.cursor.deletePreviousChar()
char = self.nextChar()
self.cursor.insertHtml("<u>" + char + "</u>")
self.cursor.deleteChar()
elif self.cursor.atEnd() and not self.previousChar() == self.parent.lastChar:
self.cursor.deletePreviousChar()
self.cursor.insertHtml(self.parent.lastChar)
elif e.key() == Qt.Key_Space:
self.cursor.movePosition(QTextCursor.PreviousCharacter)
self.cursor.insertHtml(" ")
self.cursor.movePosition(QTextCursor.NextCharacter)
elif e.key() == Qt.Key_Up:
self.cursor.select(QTextCursor.LineUnderCursor)
self.cursor.removeSelectedText()
if self.commandHistoryIndex == 0:
self.commandHistoryIndex = len(self.commandHistory)-1
else:
self.commandHistoryIndex -= 1
self.printCommandIndex(self.commandHistoryIndex)
elif e.key() == Qt.Key_Down:
self.cursor.select(QTextCursor.LineUnderCursor)
self.cursor.removeSelectedText()
if self.commandHistoryIndex == len(self.commandHistory):
self.commandHistoryIndex = 1
else:
if self.commandHistoryIndex == len(self.commandHistory)-1:
self.commandHistoryIndex = 0
else:
self.commandHistoryIndex += 1
self.printCommandIndex(self.commandHistoryIndex)
elif e.key() == Qt.Key_Left:
if self.cursorCanMoveLeft():
if self.cursor.atEnd() and self.previousChar() == self.parent.lastChar:
self.deleteCursorChar()
else:
char = self.previousChar()
self.cursor.deletePreviousChar()
self.cursor.insertHtml(char)
self.cursor.movePosition(QTextCursor.PreviousCharacter)
char = self.previousChar()
self.cursor.deletePreviousChar()
self.cursor.insertHtml("<u>"+char+"</u>")
elif e.key() == Qt.Key_Right:
char = self.previousChar()
self.cursor.deletePreviousChar()
self.cursor.insertHtml(char)
if self.cursorCanMoveRight():
char = self.nextChar()
self.cursor.deleteChar()
self.cursor.insertHtml("<u>" + char + "</u>")
elif self.cursor.atEnd() and not self.previousChar() == self.parent.lastChar:
self.cursor.insertHtml(self.parent.lastChar)
elif e.key() == Qt.Key_Tab:
self.cursor.select(QTextCursor.LineUnderCursor)
if len(self.toPlainText(self.parent.lastChar)) == 0:
cmd = str(self.cursor.selectedText()[len(self.toPlainText(self.parent.prompt)):])
else:
cmd = str(self.cursor.selectedText()[len(self.toPlainText(self.parent.prompt)):-len(self.toPlainText(self.parent.lastChar))])
self.cursor.clearSelection()
if not len(cmd) == 0:
capabilities = []
for capability in pluginsystem.capabilities:
if str(capability).startswith(self.toPlainText(cmd)):
capabilities.append(str(capability))
capabilities.sort(key=str.lower)
if len(capabilities) == 0:
pass
elif len(capabilities) == 1:
self.printString(capabilities[0], True, False)
else:
sw = True
autocompletecmd = ""
possibleautocompletestring = []
prefix = capabilities[0]
for s in capabilities:
if len(s) < len(prefix):
prefix = prefix[:len(s)]
if not prefix:
autocompletecmd = ''
break
for i in range(len(prefix)):
if prefix[i] != s[i]:
prefix = prefix[:i]
break
autocompletecmd = prefix
if autocompletecmd == cmd:
self.printAutocomplete(cmd, capabilities)
else:
self.printString(autocompletecmd, True, False)
else:
self.printAutocomplete(cmd, pluginsystem.capabilities)
elif e.key() == Qt.Key_Escape:
pluginsystem.trigger_event("quit", data="", obj=self)
self.parent.hms.stopHM()
sys.exit(0)
else:
if not self.cursor.atEnd():
char = self.previousChar()
self.cursor.deletePreviousChar()
self.cursor.insertHtml(e.text())
self.cursor.insertHtml("<u>" + char + "</u>")
else:
self.printString(e.text(), False, False)
def printAutocomplete(self, cmd, capabilities):
fm = QFontMetrics(self.font())
maxlenstr = max(capabilities, key=len)
maxlen = fm.width(maxlenstr) + 40
maxncols = self.width() / maxlen
i = 0
output = "<table><tr>"
for capability in capabilities:
output += "<td width='" + str(maxlen) + "'>" + capability + "</td>"
i += 1
if i == maxncols:
i = 0
output += "</tr><tr>"
output += "</tr></table>"
self.printString(output, False, False)
self.printString(cmd, True, True)
def cursorAtStartOfNewPromptLine(self):
pos = self.cursor.position()
self.cursor.movePosition(QTextCursor.StartOfLine)
if pos == self.cursor.position():
self.cursor.movePosition(QTextCursor.NextCharacter, QTextCursor.KeepAnchor, len(self.parent.prompt))
cmd = self.cursor.selectedText()
self.cursor.clearSelection()
self.cursor.movePosition(QTextCursor.StartOfLine)
if cmd == self.parent.prompt:
return True
else:
return False
else:
self.cursor.setPosition(pos)
return False
def cursorCanMoveLeft(self):
pos = self.cursor.position()
self.cursor.movePosition(QTextCursor.StartOfLine, QTextCursor.KeepAnchor)
cmd = self.cursor.selectedText()
self.cursor.clearSelection()
self.cursor.setPosition(pos)
if not cmd[:-1] == self.toPlainText(self.parent.prompt):
return True
else:
return False
def cursorCanMoveRight(self):
if not self.cursor.atEnd():
return True
else:
return False
def previousChar(self):
self.cursor.movePosition(QTextCursor.PreviousCharacter, QTextCursor.KeepAnchor)
char = self.cursor.selectedText()
self.cursor.movePosition(QTextCursor.NextCharacter, QTextCursor.KeepAnchor)
return char
def nextChar(self):
self.cursor.movePosition(QTextCursor.NextCharacter, QTextCursor.KeepAnchor)
char = self.cursor.selectedText()
self.cursor.movePosition(QTextCursor.PreviousCharacter, QTextCursor.KeepAnchor)
return char
def deleteCursorChar(self):
if len(self.toPlainText(self.parent.lastChar)) == 0:
return
for char in range(len(self.toPlainText(self.parent.lastChar))):
self.cursor.deletePreviousChar()
def printCommandIndex(self, i):
self.printString(self.commandHistory[i], True, False)
def printString(self, s, withPrompt=False, newLine=False):
if withPrompt == False and newLine == False:
self.deleteCursorChar()
elif withPrompt == True and newLine == False:
self.cursor.select(QTextCursor.LineUnderCursor)
self.cursor.removeSelectedText()
self.cursor.insertHtml(self.parent.prompt)
elif withPrompt == False and newLine == True:
self.deleteCursorChar()
self.cursor.insertHtml("<br>")
elif withPrompt == True and newLine == True:
self.deleteCursorChar()
self.cursor.insertHtml("<br>" + self.parent.prompt)
self.cursor.insertHtml(QString.fromUtf8(s) + self.parent.lastChar)
self.scrollBar.setValue(self.scrollBar.maximum())
def analyzeCommand(self, cmd):
pluginsystem.trigger_event("analyze_command", data=cmd, obj=self)
def toPlainText(self, s):
return QTextEdit(s).toPlainText()