from PySide6.QtGui import QGuiApplication, QAction, QIcon from PySide6.QtQml import QQmlApplicationEngine from PySide6 import QtWidgets, QtCore from PySide6.QtWidgets import QMessageBox, QFileDialog from PySide6.QtCore import QStandardPaths from ui.dashboard.dashboard import LibraryDashboard from ui.main_window_tabs.member_list.member_list import MemberList from ui.book_editor.book_editor import BookEditor from ui.member_editor.member_editor import MemberEditor from ui.settings import SettingsDialog from ui.import_preview import PreviewDialog from export.book_exporter import BookExporter from importer.book.book_importer import BookImporter from utils.errors.export_error import ExportError from utils.errors.import_error.import_error import ImportError class LibraryWindow(QtWidgets.QMainWindow): def __init__(self): super().__init__() # Set up main window properties self.setWindowTitle("Library App") self.setWindowIcon(QIcon.fromTheme("x-content-ebook-reader")) self.setGeometry(0, 0, 800, 600) self.center_window() # Set up menu bar self.create_menu_bar() # Central widget and layout central_widget = QtWidgets.QTabWidget() self.setCentralWidget(central_widget) self.dashboard = LibraryDashboard() self.member_list = MemberList() central_widget.addTab(self.dashboard, "Dashboard") central_widget.addTab(self.member_list, "Members") self.file_types = { "XML files (*.xml)": ".xml", "Any file type (*)": ""} def center_window(self): # Get the screen geometry screen = QtWidgets.QApplication.primaryScreen() screen_geometry = screen.geometry() # Get the dimensions of the window window_geometry = self.frameGeometry() # Calculate the center point of the screen center_point = screen_geometry.center() # Move the window geometry to the center of the screen window_geometry.moveCenter(center_point) # Move the window to the calculated geometry self.move(window_geometry.topLeft()) def create_menu_bar(self): # Create the menu bar menu_bar = self.menuBar() # File menu file_menu = menu_bar.addMenu("File") # New submenu new_submenu = QtWidgets.QMenu(self) new_submenu.setTitle("New") file_menu.addMenu(new_submenu) # New book action new_book_action = QAction("New book", self) new_book_action.triggered.connect(self.new_book) new_submenu.addAction(new_book_action) # New book action new_member_action = QAction("New member", self) new_member_action.triggered.connect(self.new_member) new_submenu.addAction(new_member_action) # Import submenu import_submenu = QtWidgets.QMenu(self) import_submenu.setTitle("Import") file_menu.addMenu(import_submenu) import_books_action = QAction("Import books", self) import_books_action.triggered.connect(self.import_books) import_submenu.addAction(import_books_action) import_members_action = QAction("Import members", self) import_members_action.triggered.connect(self.import_data) import_submenu.addAction(import_members_action) # Export submenu export_submenu = QtWidgets.QMenu(self) export_submenu.setTitle("Export") file_menu.addMenu(export_submenu) # Export overview export_overview_action = QAction("Export overview", self) export_overview_action.triggered.connect(self.export_data) export_submenu.addAction(export_overview_action) # Export books export_books_action = QAction("Export books", self) export_books_action.triggered.connect(self.export_books) export_submenu.addAction(export_books_action) # Export members export_members_action = QAction("Export members", self) export_members_action.triggered.connect(self.export_data) export_submenu.addAction(export_members_action) file_menu.addSeparator() exit_action = QAction("Exit", self) exit_action.setShortcut("Ctrl+Q") exit_action.triggered.connect(self.close) file_menu.addAction(exit_action) # Edit menu edit_menu = menu_bar.addMenu("Edit") # Preferences menu preferences_action = QAction("Preferences", self) preferences_action.setShortcut("Ctrl+,") preferences_action.triggered.connect(self.edit_preferences) edit_menu.addAction(preferences_action) # Help menu help_menu = menu_bar.addMenu("Help") about_action = QAction("About", self) about_action.triggered.connect(self.about) help_menu.addAction(about_action) # Menu action slots def edit_preferences(self): dialog = SettingsDialog(parent=self) if dialog.exec() == QtWidgets.QDialog.Accepted: print("Settings were saved.") # region Menu Actions def export_books(self): try: home_dir = QStandardPaths.writableLocation( QStandardPaths.HomeLocation) file_path, selected_filter = QFileDialog.getSaveFileName(self, "Save book export", home_dir, ";;".join(self.file_types.keys())) if file_path: selected_filetype = self.file_types[selected_filter] if file_path.endswith(selected_filetype): selected_filetype = "" book_exporter = BookExporter() book_exporter.save_xml(file_path + selected_filetype) except OSError as e: QMessageBox.critical(self, "Error saving file", f"Error occurred when saving the exported data: { e}", QMessageBox.StandardButton.Ok, QMessageBox.StandardButton.NoButton) except ExportError as e: QMessageBox.critical(self, "Error exporting books", f"An error occurred when exporting books: { e}", QMessageBox.StandardButton.Ok, QMessageBox.StandardButton.NoButton) def import_books(self): try: home_dir = QStandardPaths.writableLocation( QStandardPaths.HomeLocation) file_path, _ = QFileDialog.getOpenFileName( self, "Choose import file", home_dir, ";;".join( self.file_types.keys()) ) if not file_path: return # User canceled importer = BookImporter() books = importer.parse_xml(file_path) if not books: QMessageBox.information( self, "No New Books", "No new books to import.", QMessageBox.Ok) return # Show preview dialog dialog = PreviewDialog(books, self) if dialog.exec() == QtWidgets.QDialog.Accepted: # User confirmed, proceed with importing importer.save_books(books) QMessageBox.information( self, "Success", "Books imported successfully!", QMessageBox.Ok) self.dashboard.redraw_cards() else: QMessageBox.information( self, "Canceled", "Import was canceled.", QMessageBox.Ok) except ImportError as e: QMessageBox.critical(self, "Error importing books", f"An error occurred when importing books from the file provided: { e}", QMessageBox.StandardButton.Ok, QMessageBox.StandardButton.NoButton) def new_book(self): pass def new_member(self): MemberEditor().exec() def import_data(self): pass def export_data(self): pass def about(self): QtWidgets.QMessageBox.information( self, "About", "Library app demonstrating the phantom read problem") # endregion