import gi gi.require_version('Gtk', '3.0') from gi.repository import Gtk from cardvault import application from cardvault import util from cardvault import cardlist class LibraryHandlers: def __init__(self, app: 'application.Application'): """Initialize the library view""" self.app = app self.active_tag = "All" # Create Tree View for library container = self.app.ui.get_object("libraryContainer") card_list = cardlist.CardList(True, self.app, util.GENERIC_TREE_COLORS) card_list.set_name("libScroller") # Show details card_list.tree.connect("row-activated", self.on_library_card_selected) # Show Context menu card_list.tree.connect("button-press-event", self.on_library_tree_press_event) card_list.filter.set_visible_func(self.app.filter_lib_func) container.add(card_list) container.add_overlay(self.app.ui.get_object("noResults")) container.show_all() self.app.ui.get_object("noResults").set_visible(False) def do_reload_library(self, view): """Handler for the 'show' signal""" self.reload_library() def do_tag_entry_changed(self, entry): input_valid = entry.get_text() and entry.get_text() != "" self.app.ui.get_object("newTagButton").set_sensitive(input_valid) def do_new_tag_clicked(self, entry): self.add_new_tag(entry.get_text()) entry.set_text("") def do_show_all_clicked(self, button): # Clear selection in tag list self.app.ui.get_object("tagTree").get_selection().unselect_all() self.active_tag = "All" self.reload_library("All") def do_show_untagged_clicked(self, button): # Clear selection in tag list self.app.ui.get_object("tagTree").get_selection().unselect_all() self.active_tag = "Untagged" self.reload_library("Untagged") def do_tag_cards(self, entry): card_view = self.app.ui.get_object("libraryContainer").get_child() selected_cards = card_view.get_selected_cards() tag = entry.get_text() if tag != "": self.tag_cards(selected_cards, tag) self.reload_library(tag) entry.set_text("") def on_tag_selected(self, selection, path, column): (model, pathlist) = selection.get_selected_rows() for path in pathlist: tree_iter = model.get_iter(path) tag = model.get_value(tree_iter, 0) self.active_tag = tag self.reload_library(tag) def do_tag_tree_press_event(self, tree, event): if event.button == 3: # right click path = tree.get_path_at_pos(int(event.x), int(event.y)) if path: tree_iter = tree.get_model().get_iter(path[0]) tag = tree.get_model().get_value(tree_iter, 0) self.app.ui.get_object("tagListPopup").popup(None, None, None, None, 0, event.time) def do_tag_list_rename(self, tree): (model, pathlist) = tree.get_selection().get_selected_rows() for path in pathlist: tree_iter = model.get_iter(path) tag = model.get_value(tree_iter, 0) new_name = self.app.show_name_enter_dialog("Rename Tag", tag) if new_name and new_name != "": self.app.tag_rename(tag, new_name) self.app.current_page.emit('show') def do_tag_list_delete(self, tree): (model, pathlist) = tree.get_selection().get_selected_rows() for path in pathlist: tree_iter = model.get_iter(path) tag = model.get_value(tree_iter, 0) question = "Really delete '{}'?".format(tag) response = self.app.show_dialog_yn("Delete Tag", question) if response == Gtk.ResponseType.YES: self.app.tag_delete(tag) self.app.current_page.emit('show') @staticmethod def do_refilter_library(container): # Access Card View inside of container container.get_child().filter.refilter() def lib_tree_popup_showed(self, menu): """ Construct the context menu for the card tree in library view. Menu items can vary if one or more cards are selected an if they are already tagged. Called By: libListPopup UI Element """ tree = self.app.ui.get_object("libraryContainer").get_child() selected = tree.get_selected_cards() root = self.app.ui.get_object("tagItem") tags_men = Gtk.Menu() root.set_submenu(tags_men) for list_name in self.app.tags.keys(): item = Gtk.MenuItem() tags_men.add(item) item.set_label(list_name) item.connect('activate', self.tag_cards_sig, selected, list_name) # Add separator tags_men.add(Gtk.SeparatorMenuItem()) # Add new tag item new_tag = Gtk.MenuItem("New Tag") new_tag.connect('activate', self.lib_new_tag_and_add, selected) tags_men.add(new_tag) root.show_all() # Check if a selected card is tagged for id_list in self.app.tags.values(): for card_id in selected.keys(): if id_list.__contains__(card_id): self.app.ui.get_object("untagItem").set_sensitive(True) return def do_popup_untag_cards(self, item): # Get selected cards card_list = self.app.ui.get_object("libraryContainer").get_child() cards = card_list.get_selected_cards() tag = self.active_tag for card in cards.values(): self.app.untag_card(card, tag) self.reload_library(tag) self.reload_tag_list(clear_selection=True) def do_popup_remove_card(self, item): # Get selected cards card_list = self.app.ui.get_object("libraryContainer").get_child() cards = card_list.get_selected_cards() # Remove selected cards for card in cards.values(): self.app.lib_card_remove(card) self.reload_library(self.active_tag) self.reload_tag_list(clear_selection=True) # ---------------------------------Library Tree---------------------------------------------- def on_library_card_selected(self, tree, row_no, column): (model, path_list) = tree.get_selection().get_selected_rows() for path in path_list: tree_iter = model.get_iter(path) card_id = model.get_value(tree_iter, 0) card_list = self.app.ui.get_object("libraryContainer").get_child() card = card_list.lib[card_id] self.app.show_card_details(card) def on_library_tree_press_event(self, treeview, event): if event.button == 3: # right click path = treeview.get_path_at_pos(int(event.x), int(event.y)) # Get the selection selection = treeview.get_selection() # Get the selected path(s) rows = selection.get_selected_rows() # If not clicked on selection, change selected rows if path[0] not in rows[1]: selection.unselect_all() selection.select_path(path[0]) self.app.ui.get_object("libListPopup").emit('show') self.app.ui.get_object("libListPopup").popup(None, None, None, None, 0, event.time) return True # -------------------------- Class Functions ------------------------------- def reload_library(self, tag="All"): if tag == "Untagged": lib = self.app.get_untagged_cards() elif tag == "All": lib = self.app.library else: lib = self.app.get_tagged_cards(tag) self.reload_tag_list(not (tag == "All" or tag == "Untagged")) tag_combo = self.app.ui.get_object("tagCardCombo") tag_combo.set_model(self.app.ui.get_object("tagStore")) card_tree = self.app.ui.get_object("libraryContainer").get_child() if lib: self.app.ui.get_object("noResults").set_visible(False) card_tree.update(lib) else: card_tree.store.clear() self.app.ui.get_object("noResults").set_visible(True) self.app.ui.get_object("lib_title").set_text(tag) def lib_new_tag_and_add(self, item, cards): response = self.app.show_name_enter_dialog("Enter name for new Tag", "") if not response == "": self.app.tag_new(response) self.tag_cards(cards, response) else: util.log("No tag name entered", util.LogLevel.Warning) self.app.push_status("No name for new tag entered") self.reload_library(self.active_tag) def add_new_tag(self, name): self.app.tag_new(name) self.reload_tag_list(True) def reload_tag_list(self, clear_selection=False): """Reload left pane tag list""" tree = self.app.ui.get_object("tagTree") (path, column) = tree.get_cursor() store = tree.get_model() store.clear() for tag, ids in self.app.tags.items(): store.append([tag, tag + " (" + str(len(ids)) + ")"]) if clear_selection: tree.set_cursor(path if path else 0) store.set_sort_column_id(1, Gtk.SortType.ASCENDING) def tag_cards_sig(self, wigdet, cards, tag): self.tag_cards(cards, tag) self.reload_library(self.active_tag) def tag_cards(self, card_list, tag): # Check if tag exist and create if necessary if not self.app.tags.__contains__(tag): self.app.tag_new(tag) for card in card_list.values(): if not self.app.tags[tag].__contains__(card.multiverse_id): self.app.tag_card(card, tag)