Half-done collections and UI changes
Minor tweaks and refactors. A half-baked collection support and several UI tweaks. Just committing these are they are "old" changes and the current state turns out to be pretty stable.dev
							parent
							
								
									a66c601410
								
							
						
					
					
						commit
						b37a21d785
					
				| @ -0,0 +1,247 @@ | ||||
| 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 | ||||
| @ -0,0 +1,13 @@ | ||||
| 
 | ||||
| class SingletonManager: | ||||
| 
 | ||||
|     __instance = None | ||||
| 
 | ||||
|     @staticmethod | ||||
|     def set_instance(instance): | ||||
|         SingletonManager.__instance = instance | ||||
| 
 | ||||
|     @staticmethod | ||||
|     def get_manager(): | ||||
|         if SingletonManager.__instance is not None: | ||||
|             return SingletonManager.__instance | ||||
| @ -1 +1 @@ | ||||
| Subproject commit 7a0b0dfc88e46f1ec31842a34c18d408f23f041d | ||||
| Subproject commit 4d9059b55790d9e758c129fbbf3c706266e999a4 | ||||
					Loading…
					
					
				
		Reference in New Issue