Changed Source Link editing; Added Collection UI

Replaced the link LineEdit with a tool button and a dialog to make room for another label that displays selected collections.
dev
Peery 3 years ago
parent 2bb9b06a8f
commit 8a30dc2cb9

@ -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

@ -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 = "<a href=\"{0}\">{1}</a>".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

@ -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()

@ -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()

@ -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 = "<a href=\"{0}\">{1}</a>".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)

Loading…
Cancel
Save