from PySide6.QtCore import Qt from PySide6.QtGui import QAction, QIcon, QGuiApplication from PySide6.QtWidgets import QMenu, QMessageBox, QProgressBar, QMdiArea from PySide6.QtWidgets import QLabel, QMainWindow from sqlalchemy import Engine from kontor_schema import KontorDB from .comic_window import ComicWindow from .media_window import MediaWindow from .meta_data_window import MetaDataWindow from .progress import ProgressUpdate from .dialogs import ExportKontorDialog, ImportKontorDialog from .worker import VideoDownloader class MainWindow(QMainWindow): def __init__(self, engine: Engine, log): super().__init__() self.downloader = None self.tick = QIcon('res/tick.png') self.cross = QIcon('res/cross.png') self.import_icon = QIcon("res/application-import.png") self.export_icon = QIcon("res/application-export.png") self.circle_icon = QIcon("res/arrow-circle-double.png") self.data = [] self.filter = {} self.kontor_db = KontorDB(engine, log) self.log = log self._subwindows = {} self.media_dir = "/data/media" self.dl_tool = "yt-dlp" self._setup_ui() def _setup_ui(self): self.setWindowTitle("Kontor") self.setMinimumSize(1200, 800) self._create_actions() self.mdi_area = QMdiArea() self.setCentralWidget(self.mdi_area) self.mdi_area.setObjectName('mdi_area') self.mdi_area.setHorizontalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAsNeeded) self.mdi_area.setVerticalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAsNeeded) self._create_menubar() self._create_toolbars() self.status_progress = QProgressBar() self.progress_update = ProgressUpdate(self.status_progress) self._create_statusbar() center_point = QGuiApplication.screens()[0].geometry().center() self.move(center_point - self.frameGeometry().center()) def _create_actions(self): self.newAction = QAction("&New", self) self.aboutAction = QAction("&Über...", self) self.aboutAction.triggered.connect(self.about) self.showComicWindow = QAction("&Comic Window", self) self.showComicWindow.triggered.connect(self.show_comic_window) self.showTyscWindow = QAction("TYSC Window", self) self.showMediaWindow = QAction("&Media Window", self) self.showMediaWindow.triggered.connect(self.show_media_window) self.showMetaDataWindow = QAction("Meta Data Window", self) self.showMetaDataWindow.triggered.connect(self.show_meta_data_window) self.importAction = QAction(self.import_icon, "&Import", self) self.importAction.triggered.connect(self.import_from_file) self.exportAction = QAction(self.export_icon, "&Export", self) self.exportAction.triggered.connect(self.export_to_file) self.refreshAction = QAction(self.circle_icon, "&Refresh", self) self.refreshAction.triggered.connect(self.refresh) self.updateTitleAction = QAction("&Update Titles", self) self.updateTitleAction.triggered.connect(self.update_title) self.downloadAction = QAction("&Download Videos", self) self.downloadAction.triggered.connect(self.start_download) self.checkFileAction = QAction("&Check files", self) self.checkFileAction.triggered.connect(self.check_files) self.exitAction = QAction("&Beenden", self) self.exitAction.setShortcut("Alt+F4") self.exitAction.triggered.connect(self.close) def _create_menubar(self): menu_bar = self.menuBar() # File menu file_menu = QMenu("&Datei") menu_bar.addMenu(file_menu) file_menu.addAction(self.exitAction) # Kontor menu kontor_menu = QMenu("&Kontor") menu_bar.addMenu(kontor_menu) kontor_menu.addAction(self.importAction) kontor_menu.addAction(self.exportAction) comic_menu = QMenu("&Comic") comic_menu.addAction(self.showComicWindow) tysc_menu = QMenu("&TradeYourSportCards") media_file_menu = QMenu("&MediaFile") media_file_menu.addAction(self.updateTitleAction) media_file_menu.addAction(self.downloadAction) media_file_menu.addAction(self.checkFileAction) kontor_menu.addMenu(comic_menu) kontor_menu.addMenu(tysc_menu) kontor_menu.addMenu(media_file_menu) window_menu = QMenu("&Window") layouts_menu = QMenu("&Layouts") window_menu.addMenu(layouts_menu) window_menu.addAction(self.showComicWindow) window_menu.addAction(self.showMediaWindow) window_menu.addAction(self.showMetaDataWindow) menu_bar.addMenu(window_menu) # Help menu help_menu = QMenu("&Hilfe") menu_bar.addMenu(help_menu) help_menu.addAction(self.aboutAction) def _create_toolbars(self): # Kontor toolbar kontor_tool_bar = self.addToolBar("Kontor") kontor_tool_bar.addAction(self.importAction) kontor_tool_bar.addAction(self.exportAction) kontor_tool_bar.addAction(self.refreshAction) def _create_statusbar(self): self.statusBar = self.statusBar() self.statusBar.showMessage("Kontor ready", 6000) self.status_label = QLabel("") self.status_progress.setEnabled(False) self.statusBar.addPermanentWidget(self.status_progress) def about(self): QMessageBox.about(self, "Über Kontor", "Python: 3.11\nKontor: 0.1.0") def show_comic_window(self): if 'comic' not in self._subwindows: comic = ComicWindow(self) comic.closed.connect(self.sub_window_closed) self._subwindows['comic'] = comic self.mdi_area.addSubWindow(comic) comic.show() else: comic = self._subwindows.pop('comic') comic.close() self.mdi_area.removeSubWindow(comic) def show_media_window(self): if 'media' not in self._subwindows: media = MediaWindow(self) media.closed.connect(self.sub_window_closed) self._subwindows['media'] = media self.mdi_area.addSubWindow(media) media.show() else: media = self._subwindows.pop('media') media.close() self.mdi_area.removeSubWindow(media) def show_meta_data_window(self): if 'meta_data' not in self._subwindows: meta_data = MetaDataWindow(self) meta_data.closed.connect(self.sub_window_closed) self._subwindows['meta_data'] = meta_data self.mdi_area.addSubWindow(meta_data) meta_data.show() else: meta_data = self._subwindows.pop('meta_data') meta_data.close() self.mdi_area.removeSubWindow(meta_data) def remove_sub_window(self, name: str): self.log.info("remove subwindow %s", name) if name in self._subwindows: window = self._subwindows.pop(name) window.close() self.mdi_area.removeSubWindow(window) def sub_window_closed(self): self.log.info("close subwindow") def import_from_file(self): import_dlg = ImportKontorDialog(self) if import_dlg.exec(): print(f"import DB from file {import_dlg.file_name}") self.kontor_db.import_db(import_dlg.file_name) else: print("do nothing for import") def export_to_file(self): export_dlg = ExportKontorDialog(self, self.kontor_db) if export_dlg.exec(): self.log.info(export_dlg.get_tables_to_export()) self.log.info(f"export DB to {export_dlg.file_name}") self.statusBar.showMessage(f"export DB to {export_dlg.file_name}", 3000) self.kontor_db.export_db(export_dlg.current_export_type, export_dlg.file_name) else: self.statusBar.showMessage("Export cancelled", 3000) def update_title(self): self.log.info("update title for table MediaFile") self.statusBar.showMessage("update title for table MediaFile", 3000) self.status_progress.setEnabled(True) self.kontor_db.update_titles() self.status_progress.setEnabled(False) self.refresh() def start_download(self): self.status_progress.setEnabled(True) self.statusBar.showMessage("download videos for table MediaFile", 3000) self.downloader = VideoDownloader(self.kontor_db, self.log) self.downloader.setTotalProgress.connect(self.status_progress.setMaximum) self.downloader.setCurrentProgress.connect(self.downloadProgress) self.downloader.succeeded.connect(self.downloadSucceeded) self.downloader.finished.connect(self.downloadFinished) self.downloader.start() def downloadProgress(self, value: int): self.status_progress.setValue(value) self.refresh() def downloadSucceeded(self): self.status_progress.setValue(self.status_progress.maximum()) self.statusBar.showMessage("Download succeeded", 3000) def downloadFinished(self): self.status_progress.setEnabled(False) del self.downloader def check_files(self): self.log.info("check files") self.statusBar.showMessage("check files for table MediaFile", 3000) self.kontor_db.check_files() def refresh(self): self.log.info("refresh") for (_, window) in self._subwindows.items(): window.refresh() def update_status(self, message, timeout=3000): self.statusBar.showMessage(message, timeout=timeout)