diff --git a/ArtNet/artnet_manager.py b/ArtNet/artnet_manager.py
index 9b2831d..d76bb5e 100644
--- a/ArtNet/artnet_manager.py
+++ b/ArtNet/artnet_manager.py
@@ -75,6 +75,8 @@ class ArtNetManager:
self.import_window = ImporterWindow(self)
self.browse_window = BrowseWindow(self)
+ self.curr_active_window = self.import_window
+
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 ...")
@@ -92,10 +94,9 @@ class ArtNetManager:
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.import_window.show()
+ self.curr_active_window.show()
status = self.__app.exec_()
logging.info(f"Shutting client down with status: {status}")
@@ -106,7 +107,8 @@ class ArtNetManager:
if displayed_image_index is not None:
self.curr_image_index = displayed_image_index
self.refresh_shown_image()
- self.curr_active_window.hide()
+ if self.curr_active_window is not None:
+ self.curr_active_window.hide()
self.browse_window.show()
self.curr_active_window = self.browse_window
@@ -116,7 +118,8 @@ class ArtNetManager:
if displayed_image_index is not None:
self.curr_image_index = displayed_image_index
self.refresh_shown_image()
- self.curr_active_window.hide()
+ if self.curr_active_window is not None:
+ self.curr_active_window.hide()
self.import_window.show()
self.curr_active_window = self.browse_window
diff --git a/ArtNet/gui/browse_window.py b/ArtNet/gui/browse_window.py
index f3cbc6b..dfdc39f 100644
--- a/ArtNet/gui/browse_window.py
+++ b/ArtNet/gui/browse_window.py
@@ -1,12 +1,17 @@
import logging
+from PyQt5.QtCore import Qt
+
from ArtNet.gui.windows.browser.picture_browser import Ui_MainWindow
from ArtNet.gui.windows.artnet_mainwindow import ArtnetMainWindow
+from ArtNet.gui.dialogs.image_info_dialog.image_dialog import ArtInfoDialog
+
class BrowseWindow(ArtnetMainWindow):
UNKNOWN_TITLE = "-Title Unknown-"
+ UNKNOWN_PRESENCE = "(Not in Database)"
def __init__(self, main):
super().__init__(main)
@@ -14,14 +19,114 @@ class BrowseWindow(ArtnetMainWindow):
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
+ self.__showing_search_param_frame: bool = True
+ self.__showing_detail_frame: bool = True
+
+ self.curr_art_id: int = None
+ self.curr_image_title: str = None
+ self.curr_link: str = None
+ self.curr_art_path: str = None
+ self.curr_file_name: str = None
+ self.curr_presences: list = list()
+ self.curr_tags: list = list()
+ self.curr_imply_tags: list = list()
+ self.curr_tag_aliases: list = list()
+
+ # callbacks
+ # action
self.ui.actionArtNet_Importer.triggered.connect(self.on_importer_clicked)
+ # buttons
+ self.ui.toggle_search_frame_button.clicked.connect(self.on_toggle_search_frame_clicked)
+ self.ui.toggle_detail_frame_button.clicked.connect(self.on_toggle_detail_frame_clicked)
+ self.ui.image_info_button.clicked.connect(self.on_image_info_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
"""
+ logging.debug(f"Asked browser to display image ID:\"{art_ID}\", title:\"{image_title}\", path:\"{full_path}\"")
+ self.set_presences(image_authors)
+
+ def set_tag_list(self, tags: list, set_checked: bool = True, no_implication: bool = False):
+ pass # TODO to implement
+
+ def set_presences(self, presences: list):
+ """
+ Set the presences for this window
+ """
+ if len(presences) > 1:
+ for name, domain in presences:
+ if domain == BrowseWindow.UNKNOWN_PRESENCE:
+ presences.remove((name, domain))
+ elif len(presences) == 0:
+ presences = [(self.curr_art_path.split("/")[0], BrowseWindow.UNKNOWN_PRESENCE)]
+ self.curr_presences = presences
+
+ self.data_changed = True
+
+ def convert_presences_to_text(self, presences: list) -> str:
+ """
+ Prepares the presence variable to be printed as a label.
+ """
+ s = ""
+ for name, domain in presences:
+ full_data = self.get_presence(name, domain)
+ if full_data is None:
+ link = ""
+ else:
+ name, domain, _, link = full_data[0]
+ text = name + ":" + domain
+ if link is None or len(link) == 0: # no link, then just do plain text
+ hyperlink = text
+ else:
+ hyperlink = "{1}".format(link, text)
+
+ s += hyperlink
+ s += "|"
+
+ s = s[:-1]
+ return s
+
+ # callback methods
def on_importer_clicked(self):
logging.debug("Clicked on open ArtNet importer!")
self.main.switch_to_importer()
+
+ def on_toggle_search_frame_clicked(self):
+ logging.debug("Clicked on button to toggle the search frame!")
+
+ if self.__showing_search_param_frame:
+ logging.debug("Hiding search param frame")
+ self.ui.search_param_frame.hide()
+ self.__showing_search_param_frame = False
+ self.ui.toggle_search_frame_button.setArrowType(Qt.RightArrow)
+ else:
+ logging.debug("Showing search param frame")
+ self.ui.search_param_frame.show()
+ self.__showing_search_param_frame = True
+ self.ui.toggle_search_frame_button.setArrowType(Qt.LeftArrow)
+
+ def on_toggle_detail_frame_clicked(self):
+ logging.debug("Clicked on button to toggle the detail frame!")
+
+ if self.__showing_detail_frame:
+ logging.debug("Hiding detail frame")
+ self.ui.bottom_frame.hide()
+ self.__showing_detail_frame = False
+ self.ui.toggle_detail_frame_button.setArrowType(Qt.DownArrow)
+ else:
+ logging.debug("Showing detail frame")
+ self.ui.bottom_frame.show()
+ self.__showing_detail_frame = True
+ self.ui.toggle_detail_frame_button.setArrowType(Qt.UpArrow)
+
+ def on_image_info_clicked(self):
+ logging.debug("Clicked on button to show image info!")
+ if self.main.curr_image_index is not None:
+ dialog = ArtInfoDialog(self)
+ #dialog.set_image_info() # TODO see image_info_dialog/
+ dialog.exec_()
+ else:
+ pass
diff --git a/ArtNet/gui/dialogs/category_modify_dialog/__init__.py b/ArtNet/gui/dialogs/category_modify_dialog/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/ArtNet/gui/dialogs/image_info_dialog/__init__.py b/ArtNet/gui/dialogs/image_info_dialog/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/ArtNet/gui/dialogs/image_info_dialog/image_dialog.py b/ArtNet/gui/dialogs/image_info_dialog/image_dialog.py
new file mode 100644
index 0000000..1369170
--- /dev/null
+++ b/ArtNet/gui/dialogs/image_info_dialog/image_dialog.py
@@ -0,0 +1,25 @@
+
+from PyQt5 import QtWidgets
+from PyQt5.QtGui import QStandardItemModel, QStandardItem
+
+from ArtNet.gui.dialogs.image_info_dialog.image_info_dialog import Ui_Dialog
+
+
+class ArtInfoDialog(QtWidgets.QDialog):
+ """
+ Dialog popup to display more detailed information about a given Art Entry
+ """
+
+ def __init__(self, parent=None):
+ super().__init__(parent)
+ self.ui = Ui_Dialog()
+ self.ui.setupUi(self)
+
+ def set_image_info(self, image_title: str, presences: str, path: str, artists: str, collections: str, source: str):
+ """
+ Set the image info of this dialog.
+ """
+ self.ui.table_view
+
+ self.ui.table_view.setModel()
+
diff --git a/ArtNet/gui/dialogs/link_input_dialog/__init__.py b/ArtNet/gui/dialogs/link_input_dialog/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/ArtNet/gui/dialogs/link_input_dialog/link_dialog.py b/ArtNet/gui/dialogs/link_input_dialog/link_dialog.py
new file mode 100644
index 0000000..441db27
--- /dev/null
+++ b/ArtNet/gui/dialogs/link_input_dialog/link_dialog.py
@@ -0,0 +1,23 @@
+from PyQt5 import QtWidgets
+
+from ArtNet.gui.dialogs.link_input_dialog.link_input_dialog import Ui_Dialog
+
+
+class LinkInputDialog(QtWidgets.QDialog):
+
+ def __init__(self, parent=None, link: str = None):
+ super().__init__(parent)
+ self.ui = Ui_Dialog()
+ self.ui.setupUi(self)
+
+ if link is not None:
+ self.ui.link_line.setText(link)
+
+ def get_link_text(self) -> str:
+ return self.ui.link_line.text()
+
+ def exec_(self) -> str:
+ if super(LinkInputDialog, self).exec_() == QtWidgets.QDialog.Rejected:
+ return None
+ return self.get_link_text()
+
diff --git a/ArtNet/gui/dialogs/tag_import_dialog/__init__.py b/ArtNet/gui/dialogs/tag_import_dialog/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/ArtNet/gui/importer_window.py b/ArtNet/gui/importer_window.py
index 2216d59..a0e35c9 100644
--- a/ArtNet/gui/importer_window.py
+++ b/ArtNet/gui/importer_window.py
@@ -16,14 +16,15 @@ from ArtNet.gui.dialogs.tag_select_dialog.tag_select_dialog import TagSelectDial
from ArtNet.gui.dockers.presence.presence_dock import PresenceDocker
from ArtNet.gui.dialogs.category_modify_dialog.category_mod_dialog import CategoryModDialog
from ArtNet.gui.dialogs.tag_import_dialog.tag_imp_dialog import TagImportDialog
+from ArtNet.gui.dialogs.link_input_dialog.link_dialog import LinkInputDialog
from ArtNet.web.link_generator import LinkGenerator
class ImporterWindow(ArtnetMainWindow):
-
UNKNOWN_TITLE = "-Title Unknown-"
UNKNOWN_PRESENCE = "(Not in Database)"
+ UNKNOWN_LINK = "No Source Available"
def __init__(self, main):
super().__init__(main)
@@ -72,7 +73,9 @@ class ImporterWindow(ArtnetMainWindow):
self.ui.import_button.clicked.connect(self.on_import_tags_clicked)
self.ui.prev_unknown_image_button.clicked.connect(self.on_prev_unknown_image_clicked)
self.ui.next_unknown_image_button.clicked.connect(self.on_next_unknown_image_clicked)
+ self.ui.collections_button.clicked.connect(self.on_collection_button_clicked)
self.ui.delete_button.clicked.connect(self.on_delete_image_clicked)
+ self.ui.link_button.clicked.connect(self.on_source_link_button_clicked)
self.ui.link_label.linkActivated.connect(self.on_link_label_activated)
self.ui.image_author_label.linkActivated.connect(self.on_image_author_label_activated)
@@ -81,12 +84,10 @@ class ImporterWindow(ArtnetMainWindow):
self.ui.tag_search_bar.textChanged.connect(self.on_tag_search_change)
self.ui.image_title_line.textChanged.connect(self.on_image_title_change)
- self.ui.link_line.textChanged.connect(self.on_link_line_change)
self.ui.description_edit.textChanged.connect(self.on_description_change)
- self.ui.link_label.setText("No Source Available")
+ self.ui.link_label.setText(ImporterWindow.UNKNOWN_LINK)
self.ui.image_file_label.setTextInteractionFlags(Qt.TextSelectableByMouse)
- self.set_image_title_link()
self.ui.description_edit.setReadOnly(False)
@@ -155,9 +156,9 @@ class ImporterWindow(ArtnetMainWindow):
return False
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"])
+ 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"])
self.set_temporary_status_message("Saved {0} ({1}) to ArtNet DB!"
.format(image_data["title"], image_data["ID"]), 5000)
@@ -320,14 +321,14 @@ class ImporterWindow(ArtnetMainWindow):
return self.main.db_connection.search_fuzzy_categories(search)
- def get_image_link_from_line(self) -> str:
+ def get_image_link_from_label(self) -> str:
"""
- Gets the image link from the QLineEdit if it is a valid link.
+ Gets the image link from the label if it is a valid link.
Otherwise an empty string
:return:
"""
- return self.ui.link_line.text()
+ return self.ui.link_label.text()
def set_presence_label_text(self, presences: list):
"""
@@ -335,7 +336,6 @@ class ImporterWindow(ArtnetMainWindow):
:param presences:
:return:
"""
- links = []
s = ""
for name, domain in presences:
full_data = self.get_presence(name, domain)
@@ -355,24 +355,24 @@ class ImporterWindow(ArtnetMainWindow):
s = s[:-1]
self.ui.image_author_label.setText(s)
- def set_image_title_link(self) -> str:
+ def set_image_title_link(self, link: str) -> str:
"""
Sets the Image title to a link if there is link data given for this image.
- :return:
+ :return: Returns the result that has been set to see if a successful link was constructed
"""
- self.ui.link_label.setText("No Source Available")
- link = self.ui.link_line.text()
+ self.ui.link_label.setText(ImporterWindow.UNKNOWN_LINK)
if validators.url(link):
self.curr_link = link
self.data_changed = True
hyperlink = "{1}".format(link, "Source")
self.ui.link_label.setText(hyperlink)
+ self.ui.link_label.setToolTip(link)
return link
elif len(link) == 0:
return ""
else:
- self.ui.link_label.setText("No Source Available")
+ self.ui.link_label.setText(ImporterWindow.UNKNOWN_LINK)
self.set_temporary_status_message("Invalid link \"{0}\" detected!".format(link), 5000)
return ""
@@ -421,11 +421,11 @@ class ImporterWindow(ArtnetMainWindow):
item = QStandardItem(tag)
flags = Qt.ItemIsEnabled
- if tag not in self.curr_imply_tags+self.curr_tag_aliases and tag not in self.curr_tags:
+ if tag not in self.curr_imply_tags + self.curr_tag_aliases and tag not in self.curr_tags:
# new tag and not implied yet
item.setData(Qt.Unchecked, Qt.CheckStateRole)
flags |= Qt.ItemIsUserCheckable
- if self.curr_tags is not None and tag in (self.curr_tags+self.curr_imply_tags+self.curr_tag_aliases):
+ if self.curr_tags is not None and tag in (self.curr_tags + self.curr_imply_tags + self.curr_tag_aliases):
# already selected, implied or aliased tags
item.setCheckState(Qt.Checked)
item.setFlags(flags)
@@ -472,7 +472,7 @@ class ImporterWindow(ArtnetMainWindow):
self.set_implied_list(implied_tags)
self.curr_tag_aliases = list()
- for tag in tags+implied_tags:
+ for tag in tags + implied_tags:
self.curr_tag_aliases += self.main.db_connection.get_tag_aliases_by_name(tag)
self.data_changed = True
@@ -520,7 +520,7 @@ class ImporterWindow(ArtnetMainWindow):
file_ending = relative_path.split(".")[-1]
if self.__showing_video: # remove old video from image layout
- #self.ui.image_frame.layout().removeWidget(self.__video)
+ # self.ui.image_frame.layout().removeWidget(self.__video)
self.__video.hide()
self.ui.image_label.show()
if self.__showing_text: # remove text are from image layout
@@ -576,10 +576,9 @@ class ImporterWindow(ArtnetMainWindow):
self.ui.image_label.setAlignment(Qt.AlignCenter)
self.ui.image_title_line.setText(image_title)
self.update_window_title()
- self.ui.link_line.setText(link)
self.ui.image_file_label.setText(file_name)
self.ui.description_edit.setText(description)
- self.set_image_title_link()
+ self.set_image_title_link(link)
self.set_image_id_spinbox()
self.data_changed = False # reset any triggered change detection
@@ -591,7 +590,7 @@ class ImporterWindow(ArtnetMainWindow):
"""
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):
"""
@@ -599,7 +598,7 @@ class ImporterWindow(ArtnetMainWindow):
:return:
"""
self.ui.imageNumberSpinBox.setMinimum(0)
- self.ui.imageNumberSpinBox.setMaximum(len(self.main.all_images)-1)
+ self.ui.imageNumberSpinBox.setMaximum(len(self.main.all_images) - 1)
self.ui.imageNumberSpinBox.setValue(self.main.curr_image_index)
def __image_resize(self):
@@ -613,7 +612,7 @@ class ImporterWindow(ArtnetMainWindow):
size = QSize(min(rect.width(), rect.height()), min(rect.width(), rect.height()))
if type(self.__pixmap) != QMovie: # using QVideoWidget?
pass
- #self.__player.setScaledSize(size)
+ # self.__player.setScaledSize(size)
else:
self.__pixmap.setScaledSize(size)
return
@@ -688,22 +687,22 @@ class ImporterWindow(ArtnetMainWindow):
def on_save_clicked(self):
logging.info("Clicked Save!")
- self.set_image_title_link()
self.save_changes()
def on_import_tags_clicked(self):
logging.info("Clicked Import!")
dialog = TagImportDialog(self)
- if len(self.get_image_link_from_line()) == 0 or self.get_image_link_from_line() == '(Unknown)':
+ if len(self.get_image_link_from_label()) == 0 \
+ or self.get_image_link_from_label() == ImporterWindow.UNKNOWN_LINK:
url = LinkGenerator.get_instance().construct_link(self.curr_file_name,
LinkGenerator.get_instance()
.predict_domain(self.curr_file_name))
- self.ui.link_line.setText(url) # Update no link to the predicted link
+ self.set_image_title_link(url) # Update no link to the predicted link
else:
- url = self.get_image_link_from_line()
+ url = self.get_image_link_from_label()
r = self.main.scrape_tags(self.curr_file_name, url=url,
- art_ID=self.curr_art_id)
+ art_ID=self.curr_art_id)
if r is None:
msg = QtWidgets.QMessageBox()
@@ -713,8 +712,7 @@ class ImporterWindow(ArtnetMainWindow):
msg.exec_()
return
- self.ui.link_line.setText(url)
- self.set_image_title_link()
+ self.set_image_title_link(url)
tags, artists = r
i = 0
@@ -788,12 +786,12 @@ class ImporterWindow(ArtnetMainWindow):
self.presence_docker = PresenceDocker(self)
self.ui.presence_docker_layout.addWidget(self.presence_docker)
self.presence_docker.set_selected_presences_list(self.get_current_presences())
- self.ui.presence_docker_button.setText(">")
+ self.ui.presence_docker_button.setArrowType(Qt.RightArrow)
self.presence_docker_open = True
else:
logging.info("Closed presence docker!")
self.presence_docker.setParent(None)
- self.ui.presence_docker_button.setText("<")
+ self.ui.presence_docker_button.setArrowType(Qt.LeftArrow)
self.presence_docker.destroy()
self.presence_docker = None
@@ -822,8 +820,8 @@ class ImporterWindow(ArtnetMainWindow):
if len(db_data.keys()) == 0:
return
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"])
+ user=db_data["user"], password=db_data["password"],
+ database=db_data["database"])
def on_tag_creation_clicked(self):
logging.info("Clicked Tag Creation!")
@@ -839,8 +837,8 @@ class ImporterWindow(ArtnetMainWindow):
.format(tag_data["name"]))
return
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"])
+ aliases=tag_data["aliases"], implications=tag_data["implications"],
+ category=tag_data["category"])
self.on_tag_search_change()
def on_tag_deletion_clicked(self):
@@ -889,8 +887,8 @@ class ImporterWindow(ArtnetMainWindow):
"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"],
- aliases=tag_data["aliases"], implications=tag_data["implications"],
- category=tag_data["category"])
+ aliases=tag_data["aliases"], implications=tag_data["implications"],
+ category=tag_data["category"])
self.on_tag_search_change()
return tag_data
@@ -924,9 +922,10 @@ class ImporterWindow(ArtnetMainWindow):
tag_data["old_tag_name"] = None
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])
+ 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])
self.on_tag_search_change()
def on_tag_search_item_changed(self, item: QStandardItem):
@@ -976,9 +975,6 @@ class ImporterWindow(ArtnetMainWindow):
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()
logging.info("Previous unknown image clicked!")
@@ -1057,3 +1053,22 @@ class ImporterWindow(ArtnetMainWindow):
def on_browser_clicked(self):
logging.debug("Clicked on open ArtNet browser!")
self.main.switch_to_browser()
+
+ def on_source_link_button_clicked(self):
+ logging.debug("Clicked on link button!")
+ dialog = LinkInputDialog(self, self.curr_link)
+ link = dialog.exec_()
+
+ if link is None: # dialog was cancelled
+ logging.debug("Cancelled link dialog.")
+ return
+
+ logging.info(f"Setting source link to \"{link}\"")
+ self.set_image_title_link(link)
+
+ def on_collection_button_clicked(self):
+ logging.debug("Clicked on collection button!")
+ QtWidgets.QMessageBox.information(self, "Not Implemented", "This feature has not been implemented yet!")
+ # TODO open dialog with collection selection and buttons for edit, creation and deletion
+ # TODO allow editing of the rank string
+ # TODO make collection inspectable (a list of all entries with their rank string would suffice)