diff --git a/extra-options/simple-PyQt6-gui.py b/extra-options/simple-PyQt6-gui.py new file mode 100644 index 0000000..f95e19d --- /dev/null +++ b/extra-options/simple-PyQt6-gui.py @@ -0,0 +1,218 @@ +from PyQt6.QtWidgets import QApplication, QMainWindow, QTextEdit, QMenuBar +from PyQt6.QtWidgets import QTabWidget, QVBoxLayout, QWidget, QFileDialog, QTabBar +from PyQt6.QtGui import QAction +from PyQt6.QtCore import Qt, QEvent +import os, sys + +application_name = "MSG Viewer" + +""" +This is simple PyQt6 interface to open text files in tabs. +""" + +class TabContent(QWidget): + def __init__(self): + super().__init__() + # Create the text editor for each tab + self.text_area = QTextEdit(self) + self.text_area.setObjectName("Container") + self.text_area.setStyleSheet( + """#Container { + background: qlineargradient(x1:0 y1:0, x2:1 y2:1, stop:0 #051c2a stop:1 #44315f); + border-radius: 5px; + }""" + ) + layout = QVBoxLayout(self) + layout.addWidget(self.text_area) + self.setLayout(layout) + + def setText(self, text): + self.text_area.setPlainText(text) + + def getText(self): + return self.text_area.toPlainText() + + def setReadOnly(self, readonly): + self.text_area.setReadOnly(readonly) + + def isReadOnly(self): + return self.text_area.isReadOnly() + + +class AppMainWindow(QMainWindow): + def __init__(self): + super().__init__() + self.initUI() + + def initUI(self): + # Create the tab widget that will hold the tabs + self.tabs = QTabWidget(self) + self.tabs.setTabsClosable(True) # Enable the close button on tabs + self.tabs.setMovable(True) # Enable the moving (reordering) of tabs + self.tabs.tabCloseRequested.connect(self.close_tab) # Connect to tab close event + self.tabs.currentChanged.connect(self.on_tab_changed) # Listen for tab change event + self.setCentralWidget(self.tabs) + + # Enable middle-click closing for tabs + self.tabs.tabBar().installEventFilter(self) + + # Set the window title and size + self.setWindowTitle(application_name) + self.setGeometry(100, 100, 800, 600) + + # Create the menu bar with toolbar buttons + self.createToolbar() + + def createToolbar(self): + # Create a menu bar + self.menuBar = QMenuBar() + self.setMenuBar(self.menuBar) + + # Action to open a file + self.open_btn = QAction("Open", self) + self.open_btn.triggered.connect(self.open_file) + self.open_btn.setStatusTip("Open MSG file") + self.menuBar.addAction(self.open_btn) + + # Action to toggle between Edit and Read-Only modes + self.edit_btn = QAction("ReadOnly", self) # Default to "ReadOnly" + self.edit_btn.setStatusTip("Make message read-only") + self.edit_btn.triggered.connect(self.edit_file) + self.edit_btn.setVisible(False) + self.menuBar.addAction(self.edit_btn) + + # Action to save the file + self.save_btn = QAction("Extract", self) + self.save_btn.setStatusTip("Save current file") + self.save_btn.triggered.connect(self.save_file) + self.save_btn.setVisible(False) + self.menuBar.addAction(self.save_btn) + + self.menuBar.setStyleSheet(""" + QMenuBar { + background-color: #9a9c9a; + border-bottom: 1px solid #000000; + padding: 2px; + } + QMenuBar::item { + background-color: #292626; + padding: 5px 10px; + border: 1px solid transparent; + margin: 2px; + font-weight: bold; + } + QMenuBar::item:selected { + background-color: #d0d0d0; + border: 1px solid #999999; + color: black; + border-radius: 3px; + } + QMenuBar::item:pressed { + background-color: #b0b0b0; + } + """) + + def open_file(self): + # Open a file using a file dialog + file, _ = QFileDialog.getOpenFileName( + self, + "Open File", + "", + "All Files (*);;HTML Files (*.html);;Text Files (*.txt)" + ) + if file: + try: + # Read the content of the file + with open(file, 'r', encoding="utf-8") as f: + file_content = f.read() + + # Create a new tab + tab_content = TabContent() + tab_content.setText(file_content) + tab_index = self.tabs.addTab(tab_content, os.path.basename(file)) + self.tabs.setCurrentIndex(tab_index) + + # Enable save and edit actions + self.save_btn.setVisible(True) + self.edit_btn.setVisible(True) + + # Set the editor to Read-Only mode by default + tab_content.setReadOnly(True) + self.edit_btn.setText("Edit") + + except Exception as e: + print(f"Error opening file: {e}") + + def edit_file(self): + # Get the current active tab + current_tab = self.tabs.currentWidget() + + # Toggle between Edit and ReadOnly modes + if self.edit_btn.text() == "Edit": + current_tab.setReadOnly(False) # Allow editing + self.edit_btn.setText("ReadOnly") + self.edit_btn.setStatusTip("Make message read-only") + else: + current_tab.setReadOnly(True) # Make read-only + self.edit_btn.setText("Edit") + self.edit_btn.setStatusTip("Allows Editing of the message") + + def save_file(self): + # Get the current active tab + current_tab = self.tabs.currentWidget() + + # Open a file dialog to save the file + file, _ = QFileDialog.getSaveFileName( + self, + "Save File", + "", + "All Files (*);;HTML Files (*.html);;Text Files (*.txt)" + ) + if file: + try: + # Save the content of the text area to the file + with open(file, 'w', encoding="utf-8") as f: + f.write(current_tab.getText()) + self.setWindowTitle(f"{application_name} - {os.path.basename(file)}") + except Exception as e: + print(f"Error saving file: {e}") + + def close_tab(self, index): + # This function will be triggered when a user clicks on the "X" button of a tab + widget = self.tabs.widget(index) + if widget: + self.tabs.removeTab(index) + widget.deleteLater() # Free up the memory of the widget + + def on_tab_changed(self, index): + # This function is called when the user switches between tabs + current_tab = self.tabs.widget(index) + if current_tab: + # Set the "Edit/ReadOnly" button text based on the current tab's state + if current_tab.isReadOnly(): + self.edit_btn.setText("Edit") + self.edit_btn.setStatusTip("Allows Editing of the message") + else: + self.edit_btn.setText("ReadOnly") + self.edit_btn.setStatusTip("Make message read-only") + + def eventFilter(self, source, event): + # Listen for middle mouse button clicks to close tabs + if source == self.tabs.tabBar() and event.type() == QEvent.Type.MouseButtonPress: + if event.button() == Qt.MouseButton.MiddleButton: + index = self.tabs.tabBar().tabAt(event.pos()) + if index != -1: + self.tabs.removeTab(index) + return True + return super().eventFilter(source, event) + + +def main(): + app = QApplication(sys.argv) + app.setStyle("Fusion") + app_window = AppMainWindow() + app_window.show() + sys.exit(app.exec()) + +if __name__ == "__main__": + main()