From 2bb9b06a8f7a22f3f17ed0ed77de5e60932d99c0 Mon Sep 17 00:00:00 2001 From: Peery Date: Sat, 9 Apr 2022 01:43:17 +0200 Subject: [PATCH] Added Browser Window (WIP) Added the first draft of the browser window and implemented switching between it and the importer window via menu action. Also renamed window.py to importer_window and abstracted some features into a superclass from which the browser window can also inherit. This allows an equal interface for them. Also fixed a bug in the db_adapter.py where an old column name was used for a query. --- ArtNet/artnet_manager.py | 64 +++++-- ArtNet/db/db_adapter.py | 2 +- ArtNet/gui/browse_window.py | 27 +++ ArtNet/gui/{window.py => importer_window.py} | 176 +++++++++---------- ArtNet/gui/manual_picture_importer.py | 104 ----------- ArtNet/gui/windows/__init__.py | 0 ArtNet/gui/windows/artnet_mainwindow.py | 57 ++++++ ArtNet/gui/windows/browser/__init__.py | 0 ArtNet/gui/windows/importer/__init__.py | 0 9 files changed, 212 insertions(+), 218 deletions(-) create mode 100644 ArtNet/gui/browse_window.py rename ArtNet/gui/{window.py => importer_window.py} (86%) delete mode 100644 ArtNet/gui/manual_picture_importer.py create mode 100644 ArtNet/gui/windows/__init__.py create mode 100644 ArtNet/gui/windows/artnet_mainwindow.py create mode 100644 ArtNet/gui/windows/browser/__init__.py create mode 100644 ArtNet/gui/windows/importer/__init__.py diff --git a/ArtNet/artnet_manager.py b/ArtNet/artnet_manager.py index 1460426..9b2831d 100644 --- a/ArtNet/artnet_manager.py +++ b/ArtNet/artnet_manager.py @@ -10,7 +10,8 @@ from PyQt5.QtWidgets import QApplication from ArtNet.db.db_adapter import DBAdapter from ArtNet.file.file_reader import FileReader from ArtNet.file.config_reader import ConfigReader -from ArtNet.gui.window import Window +from ArtNet.gui.importer_window import ImporterWindow +from ArtNet.gui.browse_window import BrowseWindow from ArtNet.gui.dialogs.db_connection_dialog.db_dialog import DBDialog from ArtNet.web.link_generator import LinkGenerator @@ -69,12 +70,15 @@ class ArtNetManager: self.change_db_connection(host=db_data["host"], port=db_data["port"], user=db_data["user"], password=db_data["password"], database=db_data["database"]) - self.window = Window(self) + self.curr_active_window = None + + self.import_window = ImporterWindow(self) + self.browse_window = BrowseWindow(self) if len(self.config.data["file_root"]) == 0 or not os.path.isdir( self.config.data["file_root"]): # no file_root given by config or invalid logging.info("Querying for new file root due to lack of valid one ...") - self.window.on_artnet_root_change_clicked() + self.import_window.on_artnet_root_change_clicked() self.__file_reader = FileReader(self.config.data["file_root"]) self.curr_image_index: int = None @@ -82,20 +86,41 @@ class ArtNetManager: self.all_images: list = None self.update_all_images_list() - self.window.set_temporary_status_message("Hello o7", 5000) + self.import_window.set_temporary_status_message("Hello o7", 5000) def run(self): if len(self.all_images) == 0: raise FileNotFoundError("No files or folders were in artnet root!") self.curr_image_index = 0 + self.curr_active_window = self.import_window self.refresh_shown_image() - self.window.show() + self.import_window.show() status = self.__app.exec_() logging.info(f"Shutting client down with status: {status}") sys.exit(status) + def switch_to_browser(self, displayed_image_index: int = None): + logging.debug("Switching to browser window ...") + if displayed_image_index is not None: + self.curr_image_index = displayed_image_index + self.refresh_shown_image() + self.curr_active_window.hide() + + self.browse_window.show() + self.curr_active_window = self.browse_window + + def switch_to_importer(self, displayed_image_index: int = None): + logging.debug("Switching to importer window ...") + if displayed_image_index is not None: + self.curr_image_index = displayed_image_index + self.refresh_shown_image() + self.curr_active_window.hide() + + self.import_window.show() + self.curr_active_window = self.browse_window + def update_all_images_list(self): """ Updates the internal list of all images in the artnet root @@ -114,7 +139,7 @@ class ArtNetManager: if self.db_connection.get_art_by_path(image) is not None: self.known_image_amount += 1 - self.window.ui.imageNumberSpinBox.setMaximum(len(self.all_images)) + self.import_window.ui.imageNumberSpinBox.setMaximum(len(self.all_images)) def scrape_tags(self, file_name: str, art_ID: int, url: str = None): """ @@ -186,7 +211,7 @@ class ArtNetManager: for tag in tags: if len(self.db_connection.get_tag_by_name(tag)) == 0: # tag doesn't exist yet - result = self.window.force_edit_tag_dialog(name=tag) + result = self.import_window.force_edit_tag_dialog(name=tag) if result is None: # tag creation was aborted continue @@ -194,8 +219,8 @@ class ArtNetManager: tag = result['name'] # overwrite with possibly new tag name tag = self.db_connection.get_tag_by_name(tag)[0][0] - self.window.curr_tags.append(tag) - self.window.data_changed = True + self.import_window.curr_tags.append(tag) + self.import_window.data_changed = True def get_md5_of_image(self, path: str): """ @@ -348,10 +373,11 @@ class ArtNetManager: def refresh_shown_image(self): """ - Refresh the image display to show the most current data according to the selected image + Refresh the image display to show the most current data according to self.curr_image_index. + This index points to the image displayed as an index on self.all_images :return: """ - self.window.setting_up_data = True + self.curr_active_window.setting_up_data = True image_db_result = self.db_connection.get_art_by_hash( self.get_md5_of_image(self.all_images[self.curr_image_index]) @@ -360,7 +386,7 @@ class ArtNetManager: s = self.all_images[self.curr_image_index].split(os.path.sep) if image_db_result is not None: image_title = image_db_result["title"] if isinstance(image_db_result["title"], str) and \ - len(image_db_result["title"]) > 0 else self.window.UNKNOWN_TITLE + len(image_db_result["title"]) > 0 else self.import_window.UNKNOWN_TITLE image_author = self.db_connection.get_authors_of_art_by_ID(image_db_result["ID"]) image_link = image_db_result["link"] image_description = image_db_result["description"] @@ -375,15 +401,15 @@ class ArtNetManager: image_description = None logging.info(f"Displaying #{self.curr_image_index} \"{self.all_images[self.curr_image_index]}\"") - self.window.display_image(image_title, image_author, - os.path.join(self.config.data["file_root"], self.all_images[self.curr_image_index]), - self.all_images[self.curr_image_index], - art_ID, image_link, file_name=s[-1], description=image_description) - self.window.set_tag_list( + self.curr_active_window.display_image(image_title, image_author, + os.path.join(self.config.data["file_root"], self.all_images[self.curr_image_index]), + self.all_images[self.curr_image_index], + art_ID, image_link, file_name=s[-1], description=image_description) + self.curr_active_window.set_tag_list( [self.db_connection.get_tag_by_ID(x)[0][1].strip() for x in self.db_connection.get_art_tags_by_ID(art_ID)]) - self.window.data_changed = False - self.window.setting_up_data = False + self.curr_active_window.data_changed = False + self.curr_active_window.setting_up_data = False def create_db_connection(self, host: str, port: int, database: str, user: str, password: str) -> DBAdapter: logging.info(f"Changing db connection to {host}:{port} {user}@{database} ...") diff --git a/ArtNet/db/db_adapter.py b/ArtNet/db/db_adapter.py index 19f0d2b..d445ee4 100644 --- a/ArtNet/db/db_adapter.py +++ b/ArtNet/db/db_adapter.py @@ -328,7 +328,7 @@ class DBAdapter: :return: """ d = {"id": id} - self.db_cursor.execute("SELECT name, domain, artist FROM Presence WHERE artist = %(id)s", d) + self.db_cursor.execute("SELECT name, domain, artist_id FROM Presence WHERE artist_id = %(id)s", d) return self.db_cursor.fetchall() diff --git a/ArtNet/gui/browse_window.py b/ArtNet/gui/browse_window.py new file mode 100644 index 0000000..f3cbc6b --- /dev/null +++ b/ArtNet/gui/browse_window.py @@ -0,0 +1,27 @@ +import logging + +from ArtNet.gui.windows.browser.picture_browser import Ui_MainWindow +from ArtNet.gui.windows.artnet_mainwindow import ArtnetMainWindow + + +class BrowseWindow(ArtnetMainWindow): + + UNKNOWN_TITLE = "-Title Unknown-" + + def __init__(self, main): + super().__init__(main) + + self.ui = Ui_MainWindow() + self.ui.setupUi(self) + + self.ui.actionArtNet_Importer.triggered.connect(self.on_importer_clicked) + + def display_image(self, image_title: str, image_authors: list, full_path: str, relative_path: str, art_ID: int, + link: str, file_name: str, description: str): + """ + Display the described image in the GraphicsView + """ + + def on_importer_clicked(self): + logging.debug("Clicked on open ArtNet importer!") + self.main.switch_to_importer() diff --git a/ArtNet/gui/window.py b/ArtNet/gui/importer_window.py similarity index 86% rename from ArtNet/gui/window.py rename to ArtNet/gui/importer_window.py index ee015a9..2216d59 100644 --- a/ArtNet/gui/window.py +++ b/ArtNet/gui/importer_window.py @@ -7,7 +7,9 @@ from PyQt5.QtGui import QPixmap, QResizeEvent, QKeyEvent, QStandardItemModel, QS from PyQt5 import QtMultimedia from PyQt5.QtMultimediaWidgets import QVideoWidget -from ArtNet.gui.windows.picture_importer import Ui_MainWindow +from ArtNet.gui.windows.importer.picture_importer import Ui_MainWindow +from ArtNet.gui.windows.artnet_mainwindow import ArtnetMainWindow + from ArtNet.gui.dialogs.db_connection_dialog.db_dialog import DBDialog from ArtNet.gui.dialogs.tag_modify_dialog.tag_mod_dialog import TagModifyDialog from ArtNet.gui.dialogs.tag_select_dialog.tag_select_dialog import TagSelectDialog @@ -18,15 +20,13 @@ from ArtNet.gui.dialogs.tag_import_dialog.tag_imp_dialog import TagImportDialog from ArtNet.web.link_generator import LinkGenerator -class Window(QtWidgets.QMainWindow): +class ImporterWindow(ArtnetMainWindow): UNKNOWN_TITLE = "-Title Unknown-" UNKNOWN_PRESENCE = "(Not in Database)" def __init__(self, main): - super(Window, self).__init__() - - self.__main = main + super().__init__(main) self.__pixmap: QPixmap = None self.__video: QVideoWidget = None @@ -49,7 +49,6 @@ class Window(QtWidgets.QMainWindow): self.curr_imply_tags: list = list() self.curr_tag_aliases: list = list() - self.setting_up_data: bool = True self.__data_changed: bool = False self.ui = Ui_MainWindow() @@ -63,6 +62,7 @@ class Window(QtWidgets.QMainWindow): self.ui.actionDelete_a_Tag.triggered.connect(self.on_tag_deletion_clicked) self.ui.actionCreate_New_Category_2.triggered.connect(self.on_category_creation_clicked) self.ui.actionDelete_a_Category_2.triggered.connect(self.on_category_deletion_clicked) + self.ui.actionArtNet_Browser.triggered.connect(self.on_browser_clicked) self.ui.imageNumberSpinBox.valueChanged.connect(self.on_image_id_spinbox_changed) @@ -93,22 +93,6 @@ class Window(QtWidgets.QMainWindow): self.on_tag_search_change() self.center() - @property - def data_changed(self): - return self.__data_changed - - @data_changed.setter - def data_changed(self, v: bool): - self.__data_changed = v - - if self.curr_image_title is None: - return - if " (Not in Database)" in self.curr_image_title and v and not self.setting_up_data: - self.curr_image_title = self.curr_image_title.replace(" (Not in Database)", "") - self.setting_up_data = True - self.ui.image_title_line.setText(self.curr_image_title) - self.setting_up_data = False - def center(self): """ Centers the window in the middle of the screen @@ -143,7 +127,7 @@ class Window(QtWidgets.QMainWindow): """ new_title = self.curr_image_title new_description = self.ui.description_edit.toPlainText().strip() - if new_title == self.curr_file_name or len(new_title) == 0 or new_title == Window.UNKNOWN_TITLE: + if new_title == self.curr_file_name or len(new_title) == 0 or new_title == ImporterWindow.UNKNOWN_TITLE: new_title = None if new_description is None or len(new_description) == 0: new_description = None @@ -156,12 +140,12 @@ class Window(QtWidgets.QMainWindow): "path": self.curr_art_path, "tags": self.curr_tags, "link": self.curr_link, - "md5_hash": self.__main.get_md5_of_image(self.curr_art_path), + "md5_hash": self.main.get_md5_of_image(self.curr_art_path), "description": new_description, } for presence in self.curr_presences: - if presence[-1] == Window.UNKNOWN_PRESENCE: + if presence[-1] == ImporterWindow.UNKNOWN_PRESENCE: msg = QtWidgets.QMessageBox() msg.setWindowTitle("Invalid Presence Domain") msg.setInformativeText("You've tried to save with a not working presence entry! " + @@ -170,7 +154,7 @@ class Window(QtWidgets.QMainWindow): msg.exec_() return False - self.__main.db_connection.save_image(ID=image_data["ID"], title=image_data["title"], + self.main.db_connection.save_image(ID=image_data["ID"], title=image_data["title"], authors=image_data["authors"], path=image_data["path"], tags=image_data["tags"], link=image_data["link"], md5_hash=image_data["md5_hash"], desc=image_data["description"]) @@ -201,7 +185,7 @@ class Window(QtWidgets.QMainWindow): """ if len(name) == 0 or len(domain) == 0 or artist is None: return - self.__main.db_connection.save_presence(name=name, domain=domain, artist_ID=artist[0], link=link) + self.main.db_connection.save_presence(name=name, domain=domain, artist_ID=artist[0], link=link) def get_authors(self, presence_name: str, presence_domain: str) -> list: """ @@ -210,7 +194,7 @@ class Window(QtWidgets.QMainWindow): :param presence_domain: :return: a list of tuples of (presence_name, presence_domain) """ - return self.__main.db_connection.search_fuzzy_presence(presence_name, presence_domain, all_if_empty=True) + return self.main.db_connection.search_fuzzy_presence(presence_name, presence_domain, all_if_empty=True) def create_artist(self, ID: int, description: str): """ @@ -219,7 +203,7 @@ class Window(QtWidgets.QMainWindow): :param description: :return: """ - self.__main.db_connection.save_artist(ID, description) + self.main.db_connection.save_artist(ID, description) self.set_temporary_status_message("Created Artist {0}!".format(description), 3000) def get_artists(self, search: str) -> list: @@ -235,7 +219,7 @@ class Window(QtWidgets.QMainWindow): ID_int = None description = search - return self.__main.db_connection.search_fuzzy_artists(ID_int, description) + return self.main.db_connection.search_fuzzy_artists(ID_int, description) def get_artist(self, id: int) -> list: """ @@ -243,7 +227,7 @@ class Window(QtWidgets.QMainWindow): :param id: :return: """ - return self.__main.db_connection.get_artist(id) + return self.main.db_connection.get_artist(id) def remove_artist(self, id: int): """ @@ -251,7 +235,7 @@ class Window(QtWidgets.QMainWindow): :param id: :return: """ - self.__main.db_connection.remove_artist(id) + self.main.db_connection.remove_artist(id) def get_artist_presences(self, id: int) -> list: """ @@ -259,14 +243,14 @@ class Window(QtWidgets.QMainWindow): :param id: :return: """ - return self.__main.db_connection.get_artist_presences(id) + return self.main.db_connection.get_artist_presences(id) def get_all_artists(self) -> list: """ Queries the database for a list of all available arists (not presences). :return: """ - return self.__main.db_connection.get_all_artists() + return self.main.db_connection.get_all_artists() def get_presence(self, name: str, domain: str): """ @@ -275,7 +259,7 @@ class Window(QtWidgets.QMainWindow): :param domain: :return: """ - result = self.__main.db_connection.get_presence(name, domain) + result = self.main.db_connection.get_presence(name, domain) return result if len(result) != 0 else None @@ -286,7 +270,7 @@ class Window(QtWidgets.QMainWindow): :param domain: :return: """ - self.__main.db_connection.remove_presence(name, domain) + self.main.db_connection.remove_presence(name, domain) def get_presences_art(self, name: str, domain: str): """ @@ -295,7 +279,7 @@ class Window(QtWidgets.QMainWindow): :param domain: :return: """ - return self.__main.db_connection.get_presences_art(name, domain) + return self.main.db_connection.get_presences_art(name, domain) def get_current_presences(self) -> list: """ @@ -311,10 +295,10 @@ class Window(QtWidgets.QMainWindow): """ if len(presences) > 1: for name, domain in presences: - if domain == Window.UNKNOWN_PRESENCE: + if domain == ImporterWindow.UNKNOWN_PRESENCE: presences.remove((name, domain)) elif len(presences) == 0: - presences = [(self.curr_art_path.split("/")[0], Window.UNKNOWN_PRESENCE)] + presences = [(self.curr_art_path.split("/")[0], ImporterWindow.UNKNOWN_PRESENCE)] self.curr_presences = presences if self.curr_presences is not None: @@ -332,9 +316,9 @@ class Window(QtWidgets.QMainWindow): :return: """ if all_if_empty and len(search) == 0: - return self.__main.db_connection.get_all_categories() + return self.main.db_connection.get_all_categories() - return self.__main.db_connection.search_fuzzy_categories(search) + return self.main.db_connection.search_fuzzy_categories(search) def get_image_link_from_line(self) -> str: """ @@ -398,7 +382,7 @@ class Window(QtWidgets.QMainWindow): :param name: :return: """ - return self.__main.db_connection.get_tag_by_name(name) + return self.main.db_connection.get_tag_by_name(name) def get_tag_aliases(self, name: str) -> list: """ @@ -408,7 +392,7 @@ class Window(QtWidgets.QMainWindow): :param name: :return: """ - return self.__main.db_connection.get_tag_aliases_by_name(name) + return self.main.db_connection.get_tag_aliases_by_name(name) def get_tag_implications(self, name: str) -> list: """ @@ -416,14 +400,14 @@ class Window(QtWidgets.QMainWindow): :param name: :return: """ - return self.__main.db_connection.get_tag_implications(name) + return self.main.db_connection.get_tag_implications(name) def get_tag_search_result(self, name: str) -> list: """ Query a search for tags to the DB that are like name :return: """ - return self.__main.db_connection.search_fuzzy_tag(name, all_if_empty=True) + return self.main.db_connection.search_fuzzy_tag(name, all_if_empty=True) def set_tag_search_result_list(self, tags: list): """ @@ -484,12 +468,12 @@ class Window(QtWidgets.QMainWindow): implied_tags = [] for x in self.curr_tags: # collect all implied tags into a list - implied_tags += self.__main.db_connection.get_all_tag_implications_by_name(x) + implied_tags += self.main.db_connection.get_all_tag_implications_by_name(x) self.set_implied_list(implied_tags) self.curr_tag_aliases = list() for tag in tags+implied_tags: - self.curr_tag_aliases += self.__main.db_connection.get_tag_aliases_by_name(tag) + self.curr_tag_aliases += self.main.db_connection.get_tag_aliases_by_name(tag) self.data_changed = True @@ -607,7 +591,7 @@ class Window(QtWidgets.QMainWindow): """ image_title = self.ui.image_title_line.text() self.setWindowTitle(self.main_title + " - " + image_title - + f" ({round(self.__main.known_image_amount/len(self.__main.all_images), 5)}%)") + + f" ({round(self.main.known_image_amount/len(self.main.all_images), 5)}%)") def set_image_id_spinbox(self): """ @@ -615,8 +599,8 @@ class Window(QtWidgets.QMainWindow): :return: """ self.ui.imageNumberSpinBox.setMinimum(0) - self.ui.imageNumberSpinBox.setMaximum(len(self.__main.all_images)-1) - self.ui.imageNumberSpinBox.setValue(self.__main.curr_image_index) + self.ui.imageNumberSpinBox.setMaximum(len(self.main.all_images)-1) + self.ui.imageNumberSpinBox.setValue(self.main.curr_image_index) def __image_resize(self): """ @@ -645,7 +629,7 @@ class Window(QtWidgets.QMainWindow): self.__image_resize() def keyPressEvent(self, a0: QKeyEvent) -> None: - super(Window, self).keyPressEvent(a0) + super(ImporterWindow, self).keyPressEvent(a0) if a0.key() == Qt.Key_Left: self.on_previous_clicked() elif a0.key() == Qt.Key_Right: @@ -718,7 +702,7 @@ class Window(QtWidgets.QMainWindow): else: url = self.get_image_link_from_line() - r = self.__main.scrape_tags(self.curr_file_name, url=url, + r = self.main.scrape_tags(self.curr_file_name, url=url, art_ID=self.curr_art_id) if r is None: @@ -735,7 +719,7 @@ class Window(QtWidgets.QMainWindow): i = 0 while i < len(tags): # workaround for an issue with altering lists during iteration - r = self.__main.db_connection.get_tag_by_name(tags[i]) + r = self.main.db_connection.get_tag_by_name(tags[i]) if len(r) > 0: self.curr_tags.append(tags[i]) self.data_changed = True @@ -762,7 +746,7 @@ class Window(QtWidgets.QMainWindow): self.set_tag_list(self.curr_tags) return - self.__main.import_tags(result) + self.main.import_tags(result) self.set_tag_list(self.curr_tags) def on_next_clicked(self): @@ -770,10 +754,10 @@ class Window(QtWidgets.QMainWindow): if not self.check_save_changes(): return - self.__main.curr_image_index += 1 - if self.__main.curr_image_index >= len(self.__main.all_images): - self.__main.curr_image_index = 0 - self.__main.refresh_shown_image() + self.main.curr_image_index += 1 + if self.main.curr_image_index >= len(self.main.all_images): + self.main.curr_image_index = 0 + self.main.refresh_shown_image() if self.presence_docker_open: self.toggle_presence_docker() @@ -788,11 +772,11 @@ class Window(QtWidgets.QMainWindow): if not self.check_save_changes(): return - self.__main.curr_image_index -= 1 - if self.__main.curr_image_index < 0: - self.__main.curr_image_index += len(self.__main.all_images) + self.main.curr_image_index -= 1 + if self.main.curr_image_index < 0: + self.main.curr_image_index += len(self.main.all_images) - self.__main.refresh_shown_image() + self.main.refresh_shown_image() if self.presence_docker_open: self.toggle_presence_docker() @@ -822,12 +806,12 @@ class Window(QtWidgets.QMainWindow): dialog.setOptions(QtWidgets.QFileDialog.ShowDirsOnly) directory = dialog.getExistingDirectory() - self.__main.change_root(directory) + self.main.change_root(directory) def on_db_connection_change_clicked(self): logging.info("Clicked db connection change!") dialog = DBDialog(self) - prev_db_data = self.__main.get_db_connection_details() + prev_db_data = self.main.get_db_connection_details() dialog.ui.user_line_edit.setText(prev_db_data["user"]) dialog.ui.password_line_edit.setText(prev_db_data["password"]) dialog.ui.host_line_edit.setText(prev_db_data["host"]) @@ -837,7 +821,7 @@ class Window(QtWidgets.QMainWindow): db_data: dict = dialog.exec_() if len(db_data.keys()) == 0: return - self.__main.change_db_connection(host=db_data["host"], port=db_data["port"], + self.main.change_db_connection(host=db_data["host"], port=db_data["port"], user=db_data["user"], password=db_data["password"], database=db_data["database"]) @@ -854,7 +838,7 @@ class Window(QtWidgets.QMainWindow): QtWidgets.QMessageBox.information(self, "Duplicate Tag", "The tag \"{0}\" already exists in the db!" .format(tag_data["name"])) return - self.__main.db_connection.create_tag(name=tag_data["name"], description=tag_data["description"], + self.main.db_connection.create_tag(name=tag_data["name"], description=tag_data["description"], aliases=tag_data["aliases"], implications=tag_data["implications"], category=tag_data["category"]) self.on_tag_search_change() @@ -875,7 +859,7 @@ class Window(QtWidgets.QMainWindow): if confirmation_reply == QtWidgets.QMessageBox.No: return - self.__main.db_connection.remove_tag_by_name(tag["name"]) + self.main.db_connection.remove_tag_by_name(tag["name"]) self.on_tag_search_change() def force_edit_tag_dialog(self, name: str): @@ -891,7 +875,7 @@ class Window(QtWidgets.QMainWindow): edit_dialog.set_all_categories() tag_data = edit_dialog.exec_() - logging.debug("Got Tag data", tag_data) + logging.debug(f"Got Tag data: {tag_data}") if tag_data is None or len(tag_data.keys()) == 0: return None if len(tag_data["category"]) == 0: @@ -904,7 +888,7 @@ class Window(QtWidgets.QMainWindow): QtWidgets.QMessageBox.information(self, "Tag already exists", "The Tag \"{0}\" you wanted to create already exists! Skipping...") else: - self.__main.db_connection.create_tag(name=tag_data["name"], description=tag_data["description"], + self.main.db_connection.create_tag(name=tag_data["name"], description=tag_data["description"], aliases=tag_data["aliases"], implications=tag_data["implications"], category=tag_data["category"]) self.on_tag_search_change() @@ -918,8 +902,8 @@ class Window(QtWidgets.QMainWindow): if tag is None or len(tag) == 0: return - tag['aliases'] = self.__main.db_connection.get_tag_aliases_by_name(tag["name"]) - tag['implications'] = self.__main.db_connection.get_tag_implications(tag["name"]) + tag['aliases'] = self.main.db_connection.get_tag_aliases_by_name(tag["name"]) + tag['implications'] = self.main.db_connection.get_tag_implications(tag["name"]) edit_dialog = TagModifyDialog(self, create_tag=False) edit_dialog.ui.tag_name_line.setText(tag["name"]) @@ -928,7 +912,7 @@ class Window(QtWidgets.QMainWindow): edit_dialog.alias_selection = tag["aliases"] edit_dialog.set_selected_implicated_tags(tag["implications"], set_checked=True) edit_dialog.implication_selection = tag["implications"] - edit_dialog.category_selection = self.__main.db_connection.get_category_by_ID(tag["category_id"])[1] + edit_dialog.category_selection = self.main.db_connection.get_category_by_ID(tag["category_id"])[1] edit_dialog.set_all_categories() tag_data = edit_dialog.exec_() @@ -939,10 +923,10 @@ class Window(QtWidgets.QMainWindow): if "old_tag_name" not in tag_data.keys(): tag_data["old_tag_name"] = None - self.__main.db_connection.edit_tag(tag_id=tag["ID"], + self.main.db_connection.edit_tag(tag_id=tag["ID"], name=tag_data["name"], description=tag_data["description"], aliases=tag_data["aliases"], implications=tag_data["implications"], - category_id=self.__main.db_connection.get_category_by_name(tag_data["category"])[0]) + category_id=self.main.db_connection.get_category_by_name(tag_data["category"])[0]) self.on_tag_search_change() def on_tag_search_item_changed(self, item: QStandardItem): @@ -966,7 +950,7 @@ class Window(QtWidgets.QMainWindow): raise Exception("Something went terribly wrong!") def on_tag_search_change(self): - tags = self.__main.db_connection.search_fuzzy_tag(self.ui.tag_search_bar.text(), all_if_empty=True) + tags = self.main.db_connection.search_fuzzy_tag(self.ui.tag_search_bar.text(), all_if_empty=True) result = [] for tag_name, tag_desc, tag_category in tags: @@ -981,7 +965,7 @@ class Window(QtWidgets.QMainWindow): if data is None: return - self.__main.db_connection.save_category(data["name"]) + self.main.db_connection.save_category(data["name"]) def on_category_deletion_clicked(self): dialog = CategoryModDialog(self, delete_category=True) @@ -990,34 +974,34 @@ class Window(QtWidgets.QMainWindow): if data is None: return - self.__main.db_connection.remove_category(data["name"]) + self.main.db_connection.remove_category(data["name"]) def on_link_line_change(self): self.data_changed = True def on_prev_unknown_image_clicked(self): - unknown_image_index = self.__main.get_prev_unknown_image() + unknown_image_index = self.main.get_prev_unknown_image() logging.info("Previous unknown image clicked!") result = QtWidgets.QMessageBox.question(self, "Switch Image?", "Do you really want to skip to image #{1} \"{0}\"?" - .format(self.__main.all_images[unknown_image_index], + .format(self.main.all_images[unknown_image_index], unknown_image_index)) if result == QtWidgets.QMessageBox.Yes: - self.__main.curr_image_index = unknown_image_index - self.__main.refresh_shown_image() + self.main.curr_image_index = unknown_image_index + self.main.refresh_shown_image() def on_next_unknown_image_clicked(self): - unknown_image_index = self.__main.get_next_unknown_image() + unknown_image_index = self.main.get_next_unknown_image() logging.info("Next unknown image clicked!") result = QtWidgets.QMessageBox.question(self, "Switch Image?", "Do you really want to skip to image #{1} \"{0}\"?" - .format(self.__main.all_images[unknown_image_index], + .format(self.main.all_images[unknown_image_index], unknown_image_index)) if result == QtWidgets.QMessageBox.Yes: - self.__main.curr_image_index = unknown_image_index - self.__main.refresh_shown_image() + self.main.curr_image_index = unknown_image_index + self.main.refresh_shown_image() def on_image_id_spinbox_changed(self, v: int): if self.__tmp_imageid_spinbox == v: @@ -1027,22 +1011,22 @@ class Window(QtWidgets.QMainWindow): .format(self.__main.all_images[v], v)) if result == QtWidgets.QMessageBox.Yes: - self.__main.curr_image_index = v - self.__main.refresh_shown_image() + self.main.curr_image_index = v + self.main.refresh_shown_image() self.__tmp_imageid_spinbox: int = v def on_delete_image_clicked(self): logging.info("Delete clicked!") - art_hash = self.__main.get_md5_of_image(self.curr_art_path) - if self.__main.db_connection.get_art_by_hash(art_hash) is not None: + art_hash = self.main.get_md5_of_image(self.curr_art_path) + if self.main.db_connection.get_art_by_hash(art_hash) is not None: logging.debug("Delete on known image") confirm_result = QtWidgets.QMessageBox.question(self, "Delete data?", "Do you really wish to delete all " "data from the DB about this image?") if confirm_result == QtWidgets.QMessageBox.Yes: logging.info(f"deleting image data of \"{self.curr_image_title}\"") - self.__main.db_connection.remove_image(art_hash) + self.main.db_connection.remove_image(art_hash) else: return @@ -1053,19 +1037,23 @@ class Window(QtWidgets.QMainWindow): if confirm_result == QtWidgets.QMessageBox.Yes: logging.info(f"deleting image file {self.curr_art_path}") - self.__main.delete_image(self.curr_art_path) + self.main.delete_image(self.curr_art_path) else: return - self.__main.refresh_shown_image() + self.main.refresh_shown_image() def on_link_label_activated(self, link: str): - logging.debug("Source link activated!", link) + logging.debug(f"Source link activated! {link}") QDesktopServices.openUrl(QUrl(link)) def on_image_author_label_activated(self, link: str): - logging.debug("Image author link activated!", link) + logging.debug(f"Image author link activated! {link}") QDesktopServices.openUrl(QUrl(link)) def on_description_change(self): self.data_changed = True + + def on_browser_clicked(self): + logging.debug("Clicked on open ArtNet browser!") + self.main.switch_to_browser() diff --git a/ArtNet/gui/manual_picture_importer.py b/ArtNet/gui/manual_picture_importer.py deleted file mode 100644 index 30cfcb0..0000000 --- a/ArtNet/gui/manual_picture_importer.py +++ /dev/null @@ -1,104 +0,0 @@ -from PyQt5.QtWidgets import QMainWindow, QWidget, QLabel, QDesktopWidget, QToolBar, QPushButton, QGroupBox, QGridLayout -from PyQt5.QtWidgets import QVBoxLayout -from PyQt5.QtGui import QPixmap -from PyQt5.QtCore import Qt - - -class PictureImporter(QMainWindow): - - def __init__(self, parent=None, max_relative_resize_width: float = 0.8, max_relative_resize_height: float = 0.8,): - super().__init__(parent) - - # Menubar - self.__menu_bar = self.menuBar() - self.__menu_bar.addAction("Action1") - self.__menu_bar.addAction("Action2") - - # Toolbar - open = QToolBar() - open.addAction("Open") - self.addToolBar(open) - close = QToolBar() - close.addAction("Close") - self.addToolBar(close) - - # layout - self.__layout = QGridLayout() - - # Central Component Settings - self.__window = QWidget() - - self.setCentralWidget(self.__window) - - # Statusbar Settings - self.__status_bar = self.statusBar() - self.__status_bar.showMessage("Welcome to ArtNet! :)", 5000) - label = QLabel("ArtNet - v0.1") - self.__status_bar.addPermanentWidget(label) - - self.resize(800, 600) - self.setWindowTitle("ArtNet - Picture Importer") - self.center() - - def center(self): - """ - Centers the window in the middle of the screen - - :return: - """ - screen = QDesktopWidget().screenGeometry() - size = self.geometry() - self.move((screen.width() - size.width()) / 2, (screen.height() - size.height()) / 2) - - @DeprecationWarning - def display_geometry(self): - x = self.x() - y = self.y() - print("x: {0}, y: {1}".format(x, y)) - x = self.pos().x() - y = self.pos().y() - print("x: {0}, y: {1}".format(x, y)) - x = self.frameGeometry().x() - y = self.frameGeometry().y() - print("x: {0}, y: {1}".format(x, y)) - x = self.geometry().x() - y = self.geometry().y() - print("x: {0}, y: {1}".format(x, y)) - print("geometry: ", self.geometry()) - print("frameGeometry: ", self.frameGeometry()) - - def set_temporary_status_message(self, text: str, duration: int): - """ - Set a temporary status message (bottom left) for the given duration in milliseconds. - :param text: - :param duration: - :return: - """ - self.__status_bar.showMessage("Welcome to ArtNet! :)", 5000) - - def display_image(self, full_path: str): - """ - Display an image in the central widget - :param full_path: - :return: - """ - label = QLabel(self) - pixmap = self.__image_resize(QPixmap(full_path)) - - label.setPixmap(pixmap) - label.setAlignment(Qt.AlignCenter) - - self.setCentralWidget(label) - self.center() - - def __image_resize(self, pixmap: QPixmap) -> QPixmap: - """ - Resize the given pixmap so that we're not out of the desktop. - - :return: new scaled QPixmap - """ - return pixmap - screen_rect = QDesktopWidget().screenGeometry() - print("Resizing pixmap to", int(screen_rect.width()*0.4), int(screen_rect.height()*0.6)) - return pixmap.scaled(int(screen_rect.width()*0.6), int(screen_rect.height()*0.7), Qt.KeepAspectRatio) - diff --git a/ArtNet/gui/windows/__init__.py b/ArtNet/gui/windows/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/ArtNet/gui/windows/artnet_mainwindow.py b/ArtNet/gui/windows/artnet_mainwindow.py new file mode 100644 index 0000000..e6deb05 --- /dev/null +++ b/ArtNet/gui/windows/artnet_mainwindow.py @@ -0,0 +1,57 @@ +from PyQt5 import QtWidgets + + +class ArtnetMainWindow(QtWidgets.QMainWindow): + + def __init__(self, main): + super(ArtnetMainWindow, self).__init__() + + self.main = main + self.curr_image_title: str = "" + + self.setting_up_data: bool = True + self.__data_changed: bool = False + + @property + def data_changed(self): + return self.__data_changed + + @data_changed.setter + def data_changed(self, v: bool): + self.__data_changed = v + + if self.curr_image_title is None: + return + if " (Not in Database)" in self.curr_image_title and v and not self.setting_up_data: + self.curr_image_title = self.curr_image_title.replace(" (Not in Database)", "") + self.setting_up_data = True + self.ui.image_title_line.setText(self.curr_image_title) + self.setting_up_data = False + + def display_image(self, image_title: str, image_authors: list, full_path: str, relative_path: str, art_ID: int, + link: str, file_name: str, description: str): + """ + Display an image in the central widget + :param image_authors: + :param image_title: + :param full_path: + :param relative_path: + :param art_ID: + :param link: + :param file_name: + :param description: + :return: + """ + raise NotImplementedError + + def set_tag_list(self, tags: list, set_checked: bool = True, no_implication: bool = False): + """ + Set the tags in the tag list to this. + Also updates the tag implication list if no_implication is False + :param tags: + :param set_checked: + :param no_implication: bool indicating if the implication list should also be updated + :return: + """ + raise NotImplementedError + diff --git a/ArtNet/gui/windows/browser/__init__.py b/ArtNet/gui/windows/browser/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/ArtNet/gui/windows/importer/__init__.py b/ArtNet/gui/windows/importer/__init__.py new file mode 100644 index 0000000..e69de29