You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

248 lines
9.3 KiB
Python

import logging
import os.path
from PyQt5 import QtWidgets
from PyQt5.QtCore import Qt, QSize, QModelIndex
from PyQt5.QtGui import QStandardItem, QStandardItemModel, QIcon
from ArtNet.gui.dialogs.image_select_dialog.image_select_dialog import Ui_Dialog
from ArtNet.db.db_adapter import DBAdapter
from ArtNet.singleton_manager import SingletonManager
class ImageSelectDialog(QtWidgets.QDialog):
def __init__(self, db_connection, parent=None):
super().__init__(parent)
self.parent = parent
self.__config = SingletonManager.get_manager().config.data
self.__file_root = self.__config["file_root"]
self.db_connection: DBAdapter = db_connection
self.data: dict = None # data to be returned by this dialog to the parent
self.__tag_search_result = list()
self.__presence_search_result = list()
self.__art_list_dict = dict()
self.curr_selected_tags = list()
self.curr_selected_presences = list()
self.setWindowTitle("Select Art")
self.ui = Ui_Dialog()
self.ui.setupUi(self)
self.ui.search_tag_line.textChanged.connect(self.on_tag_search_changed)
self.ui.search_presence_name_line.textChanged.connect(self.on_presence_search_changed)
self.ui.search_presence_domain_line.textChanged.connect(self.on_presence_search_changed)
self.ui.art_selection_list.hide()
self.ui.art_selection_list.doubleClicked.connect(self.on_art_doubleclicked)
self.on_presence_search_changed("")
self.on_tag_search_changed("")
def set_tag_search_result_list(self, tags: list):
"""
Set the tag search result list given the tags from the search
"""
item_model = QStandardItemModel(self.ui.search_tag_list)
self.__tag_search_result = tags
for tag in tags:
item = QStandardItem(tag)
flags = Qt.ItemIsEnabled
item.setData(Qt.Unchecked, Qt.CheckStateRole)
flags |= Qt.ItemIsUserCheckable
if self.curr_selected_tags is not None and tag in self.curr_selected_tags:
# already selected, implied or aliased tags
item.setCheckState(Qt.Checked)
item.setFlags(flags)
item_model.appendRow(item)
item_model.itemChanged.connect(self.on_tag_search_item_changed)
self.ui.search_tag_list.setModel(item_model)
def refresh_selected_tags_list(self):
"""
Refreshes the selected tags list according to self.curr_selected_tags
"""
item_model = QStandardItemModel(self.ui.selected_tag_list)
for tag in self.curr_selected_tags:
item = QStandardItem(tag)
flags = Qt.ItemIsEnabled
item.setData(Qt.Unchecked, Qt.CheckStateRole)
flags |= Qt.ItemIsUserCheckable
item.setCheckState(Qt.Checked)
item.setFlags(flags)
item_model.appendRow(item)
item_model.itemChanged.connect(self.on_tag_selected_item_changed)
self.ui.selected_tag_list.setModel(item_model)
self.refresh_image_selection()
def refresh_selected_presences_list(self):
"""
Refreshes the selected presences list according to self.curr_selected_presences
"""
item_model = QStandardItemModel(self.ui.selected_presence_list)
for name, domain in self.curr_selected_presences:
item = QStandardItem(f"{name}:{domain}")
flags = Qt.ItemIsEnabled
item.setData(Qt.Unchecked, Qt.CheckStateRole)
flags |= Qt.ItemIsUserCheckable
item.setCheckState(Qt.Checked)
item.setFlags(flags)
item_model.appendRow(item)
item_model.itemChanged.connect(self.on_presence_selected_item_changed)
self.ui.selected_presence_list.setModel(item_model)
self.refresh_image_selection()
def refresh_image_selection(self):
"""
Refreshes the images available for selection by using self.curr_selected_presences and self.curr_selected_tags
"""
logging.debug(f"Refreshing info selection with tags {self.curr_selected_tags} "
f"and presences {self.curr_selected_presences}")
arts = self.db_connection.search_art(tags=self.curr_selected_tags, resolve_tags=True,
presences=self.curr_selected_presences)
#print("Result:", arts)
self.ui.art_placeholder_label.hide()
self.ui.art_selection_list.show()
self.ui.art_selection_list.setViewMode(QtWidgets.QListView.IconMode)
self.__art_list_dict = dict()
item_model = QStandardItemModel(self.ui.art_selection_list)
items = list()
if len(arts) > 100:
arts = arts[:100]
for art in arts:
art_data = self.db_connection.get_art_by_ID(art)
full_path = os.path.join(self.__file_root, art_data["path"])
if not os.path.isfile(full_path):
continue
icon = QIcon()
icon.addFile(full_path)
flags = Qt.ItemIsEnabled
item = QStandardItem(
art_data["title"] if art_data["title"] is not None else os.path.basename(art_data["path"]))
item.setData(icon, role=Qt.DecorationRole)
item.setData(art_data["ID"], role=Qt.UserRole) # allows the item to be identified again
presences = self.db_connection.get_authors_of_art_by_ID(art_data["ID"])
p = ""
for presence in presences:
p += f"{presence[0]}:{presence[1]}|"
p = p[:-1]
item.setData(f"{art_data['title']} \nby \n{p} \n\nDescription:\n{art_data['description']}", role=Qt.ToolTipRole) # tooltip for the item
item.setFlags(flags)
items.append(item)
self.__art_list_dict[art_data["ID"]] = art_data
#print("Adding to last row", items)
item_model.appendColumn(items)
self.ui.art_selection_list.setIconSize(QSize(150, 150))
self.ui.art_selection_list.setModel(item_model)
def set_presence_search_result_list(self, presences: list):
"""
Set the presence search result list as given by presences.
"""
item_model = QStandardItemModel(self.ui.search_presence_list)
self.__presence_search_result = presences
for name, domain in presences:
item = QStandardItem(f"{name}:{domain}")
flags = Qt.ItemIsEnabled
item.setData(Qt.Unchecked, Qt.CheckStateRole)
flags |= Qt.ItemIsUserCheckable
item.setFlags(flags)
item_model.appendRow(item)
item_model.itemChanged.connect(self.on_presence_search_item_changed)
self.ui.search_presence_list.setModel(item_model)
def on_art_doubleclicked(self, index: QModelIndex):
art_id = index.model().itemData(index)[Qt.UserRole]
print(f"Double-clicked: {self.__art_list_dict[art_id]}")
self.data = self.__art_list_dict[art_id]
self.done(QtWidgets.QDialog.Accepted)
def on_tag_search_changed(self, v: str):
result = self.db_connection.search_fuzzy_tag(v, all_if_empty=True)
self.set_tag_search_result_list([r[0] for r in result])
def on_presence_search_changed(self, v: str):
presence_name = self.ui.search_presence_name_line.text()
presence_domain = self.ui.search_presence_domain_line.text()
result = self.db_connection.search_fuzzy_presence(name=presence_name, domain=presence_domain, all_if_empty=True)
presences = list()
for name, domain in result:
presences.append((name, domain))
self.set_presence_search_result_list(presences)
def on_tag_search_item_changed(self, item: QStandardItem):
logging.info(f"Tag search item {item.text()} has changed!")
if item.checkState() == Qt.Checked:
self.curr_selected_tags.append(item.text())
if item.checkState() == Qt.Unchecked:
self.curr_selected_tags.remove(item.text())
self.refresh_selected_tags_list()
def on_tag_selected_item_changed(self, item: QStandardItem):
logging.info(f"Tag select item {item.text()} has changed!")
self.curr_selected_tags.remove(item.text())
self.refresh_selected_tags_list()
self.set_tag_search_result_list(self.__tag_search_result)
def on_presence_search_item_changed(self, item: QStandardItem):
logging.info(f"Presence search item {item.text()} has changed!")
name, domain = item.text().split(":")
if item.checkState() == Qt.Checked:
self.curr_selected_presences.append((name, domain))
elif item.checkState() == Qt.Unchecked:
self.curr_selected_presences.remove((name, domain))
self.refresh_selected_presences_list()
def on_presence_selected_item_changed(self, item: QStandardItem):
logging.info(f"Presence select item {item.text()} has changed!")
name, domain = item.text().split(":")
self.curr_selected_presences.remove((name, domain))
self.set_presence_search_result_list(self.__presence_search_result)
self.refresh_selected_presences_list()
def exec_(self) -> dict:
if super(ImageSelectDialog, self).exec_() == QtWidgets.QDialog.Rejected:
return None
if self.data is None:
self.done(QtWidgets.QDialog.Rejected)
return self.data