219 lines
7.6 KiB
Python
219 lines
7.6 KiB
Python
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()
|