import json import sys from PySide6 import QtWidgets, QtGui, QtCore from Highlighter import Highlighter, Rule from MainWindow_ui import Ui_MainWindow from SettingsDialog import SettingsWindow from TextFormat import TextFormat def loadSettingsFromFile() -> dict: try: with open("settings.json", 'r') as f: return json.load(f) except IOError: return None def saveSettingsToFile(settings: dict) -> None: with open("settings.json", 'w') as f: json.dump(settings, f, indent=4) class CommandStack: def __init__(self) -> None: self.__stack = list() self.__curIndex = -1 def add(self, cmd: str) -> None: self.__stack.append(cmd) self.__curIndex = len(self.__stack) # print("lenght: ", len(self.__stack)) def hasPrevious(self) -> bool: return self.__curIndex > 0 def hasNext(self) -> bool: return (self.__curIndex + 1 < len(self.__stack)) and (len(self.__stack) != 0) def getPrevious(self) -> str: if len(self.__stack) < 1: return "" self.__curIndex -= 1 if self.__curIndex < 0: self.__curIndex = 0 # print("index: ", self.__curIndex) return self.__stack[self.__curIndex] def getNext(self): if len(self.__stack) < 1: return "" self.__curIndex = min(self.__curIndex + 1, len(self.__stack)) if self.__curIndex == len(self.__stack): return self.__stack[self.__curIndex-1] return self.__stack[self.__curIndex] class MainWindow(QtWidgets.QMainWindow): def __init__(self) -> None: super().__init__() self.ui = Ui_MainWindow() self.ui.setupUi(self) settings = loadSettingsFromFile() self.ui_settings = SettingsWindow(settings=settings) self.stack = CommandStack() self.highlighter = Highlighter(self.ui.txtEdit_mainTerminal.document()) self.setup() self.ruleItemList = [] def setup(self): # header buttons self.ui.btn_settings.clicked.connect(self.on_settingsClicked) self.ui.btn_connect.clicked.connect(self.on_connectClicked) # left side self.ui.btn_addPattern.clicked.connect(self.on_addPaternClicked) # self.ui.btn_removePattern.clicked.connect(self.on_removePatternClicked) self.ui.lst_regex.model().rowsMoved.connect(self.on_item_move) # right side # main side self.ui.lineEdit.returnPressed.connect(self.on_returnPressed) self.ui.lineEdit.installEventFilter(self) def on_connectClicked(self): pass def on_settingsClicked(self): if self.ui_settings.exec(): self.setTerminalFont(**self.ui_settings.fontsOption["terminal"]) self.setCommandFont(**self.ui_settings.fontsOption["echo"]) saveSettingsToFile(self.ui_settings.getSettings()) def on_addPaternClicked(self): item = QtWidgets.QListWidgetItem(f"regex{str(self.ui.lst_regex.count())}") item.setFlags(item.flags() | QtGui.Qt.ItemIsUserCheckable) item.setCheckState(QtGui.Qt.Unchecked) self.ui.lst_regex.addItem(item) textFormat = TextFormat() regex = QtCore.QRegularExpression() rule = Rule(item.text(), True, textFormat, regex) self.ruleItemList.append((item, rule)) print( [ ( i.text(), r.name )for i, r in self.ruleItemList ] ) self.highlighter.setListOfRules([ r for i, r in self.ruleItemList]) def on_item_move(self): itemList = [self.ui.lst_regex.item(row) for row in range(self.ui.lst_regex.count())] self.ruleItemList.sort(key=lambda t: itemList.index(t[0])) print( [ ( i.text(), r.name )for i, r in self.ruleItemList ] ) self.highlighter.setListOfRules([ r for i, r in self.ruleItemList]) def on_returnPressed(self): cmd = self.ui.lineEdit.text() self.stack.add(cmd) self.ui.txtEdit_mainTerminal.appendPlainText(cmd) self.ui.lineEdit.clear() def setTerminalFont(self, font_family: str, font_size: str, bold: bool, italic: bool, underline: bool, fg_color: tuple, bg_color: tuple): font = list() font.append(f'font-family: "{font_family}"') font.append(f"font-size: {font_size}pt") font.append(f'font-weight: {"bold" if bold else "normal"}') font.append(f'font-style: {"italic" if italic else "normal"}') font.append(f'text-decoration: {"underline" if underline else "none"}') font.append(f"color: rgb({fg_color[0]}, {fg_color[1]}, {fg_color[2]})") font.append(f"background-color: rgb({bg_color[0]}, {bg_color[1]}, {bg_color[2]})") self.ui.txtEdit_mainTerminal.setStyleSheet(";".join(font)) self.ui.lbl_examplePattern.setStyleSheet(";".join(font)) def setCommandFont(self, font_family: str, font_size: str, bold: bool, italic: bool, underline: bool, fg_color: tuple, enable: bool): textFormat = TextFormat(font_family, font_size, bold, italic, underline, fg_color) regex = QtCore.QRegularExpression(r"^<<[\s]*(.*)") rule = Rule("command", enable, textFormat, regex) self.highlighter.addRule(rule) self.highlighter.rehighlight() def eventFilter(self, watched: QtCore.QObject, event: QtCore.QEvent) -> bool: if watched is self.ui.lineEdit: if event.type() == QtCore.QEvent.KeyPress: keyEvent = QtGui.QKeyEvent(event) if keyEvent.key() == QtCore.Qt.Key_Up: self.on_upArrow() if keyEvent.key() == QtCore.Qt.Key_Down: self.on_downArrow() return super().eventFilter(watched, event) def on_upArrow(self): if self.stack.hasPrevious(): self.ui.lineEdit.setText(self.stack.getPrevious()) def on_downArrow(self): if self.stack.hasNext(): self.ui.lineEdit.setText(self.stack.getNext()) def main(): app = QtWidgets.QApplication(sys.argv) window = MainWindow() window.show() sys.exit(app.exec()) if __name__ == "__main__": main()