diff --git a/cardvault/application.py b/cardvault/application.py index e9056a1..60d8a99 100644 --- a/cardvault/application.py +++ b/cardvault/application.py @@ -28,6 +28,13 @@ from cardvault import wants_funct class Application: # ---------------------------------Initialize the Application---------------------------------------------- def __init__(self): + + # Load configuration file + self.configfile = util.get_root_filename("config.json") + self.config = util.parse_config(self.configfile, util.default_config) + util.LOG_LEVEL = self.config["log_level"] + util.log("Start using config file: '{}'".format(self.configfile), util.LogLevel.Info) + # Load ui files self.ui = Gtk.Builder() self.ui.add_from_file(util.get_ui_filename("mainwindow.glade")) @@ -49,17 +56,13 @@ class Application: "wants": self.ui.get_object("wantsView") } - # Load configuration file - self.configfile = util.get_root_filename("config.json") - self.config = util.parse_config(self.configfile, util.default_config) - - util.LOG_LEVEL = self.config["log_level"] - # Load data from cache path + util.log("Loading image cache...", util.LogLevel.Info) self.image_cache = util.reload_image_cache(util.CACHE_PATH + "images/") self.precon_icons = util.reload_preconstructed_icons(util.CACHE_PATH + "icons/") self.mana_icons = util.load_mana_icons(os.path.dirname(__file__) + "/resources/mana/") + util.log("Loading set list...", util.LogLevel.Info) self.sets = util.load_sets(util.get_root_filename("sets")) self.library = Dict[str, Type[mtgsdk.Card]] @@ -86,6 +89,9 @@ class Application: start_page = [page for page in view_menu.get_children() if page.get_name() == util.START_PAGE] start_page[0].activate() + + util.log("Launching Card Vault version {}".format(util.VERSION), util.LogLevel.Info) + def push_status(self, msg): status_bar = self.ui.get_object("statusBar") status_bar.pop(0) @@ -185,11 +191,14 @@ class Application: dialog.run() dialog.destroy() - def show_rename_dialog(self, name: str) -> str: - dialog = self.ui.get_object("renameDialog") # type: Gtk.Dialog + def show_name_enter_dialog(self, title: str, value: str) -> str: + dialog = self.ui.get_object("nameEnterDialog") # type: Gtk.Dialog dialog.set_transient_for(self.ui.get_object("mainWindow")) - entry = self.ui.get_object("renameDialogEntry") - entry.set_text(name) + label = self.ui.get_object("nameEnterLabel") + label.set_text(title) + entry = self.ui.get_object("nameEnterEntry") + entry.set_text(value) + entry.grab_focus() result = dialog.run() dialog.hide() @@ -197,7 +206,7 @@ class Application: if result == Gtk.ResponseType.OK: return entry.get_text() else: - return name + return value def save_library(self): # Save library file @@ -309,10 +318,10 @@ class Application: def add_want_list(self, name): self.wants[name] = [] util.log("Want list '" + name + "' created", util.LogLevel.Info) - self.push_status("Created want listwantsListContainer '" + name + "'") + self.push_status("Created want list '" + name + "'") self.unsaved_changes = True - def add_card_to_want_list(self, list_name, card): + def add_card_to_want_list(self, list_name: str, card: 'mtgsdk.Card'): self.wants[list_name].append(card) util.log(card.name + " added to want list " + list_name, util.LogLevel.Info) self.unsaved_changes = True @@ -341,7 +350,7 @@ class Application: def get_mana_icons(self, mana_string): if not mana_string: - util.log("No mana string provided", util.LogLevel.Warning) + util.log("No mana string provided", util.LogLevel.Info) return icon_list = re.findall("{(.*?)}", mana_string) icon_name = "_".join(icon_list) diff --git a/cardvault/cardlist.py b/cardvault/cardlist.py index 3f605c9..7787270 100644 --- a/cardvault/cardlist.py +++ b/cardvault/cardlist.py @@ -118,7 +118,7 @@ class CardList(Gtk.ScrolledWindow): self.store.set_sort_column_id(1, Gtk.SortType.ASCENDING) - def get_selected_cards(self): + def get_selected_cards(self) -> dict: (model, pathlist) = self.selection.get_selected_rows() output = {} for path in pathlist: diff --git a/cardvault/gui/dialogs.glade b/cardvault/gui/dialogs.glade index 6573c50..2333c53 100644 --- a/cardvault/gui/dialogs.glade +++ b/cardvault/gui/dialogs.glade @@ -2,7 +2,7 @@ - + False False True @@ -53,7 +53,18 @@ - + + True + False + + + False + True + 0 + + + + True True diff --git a/cardvault/gui/library.glade b/cardvault/gui/library.glade index 3324cf2..825b21e 100644 --- a/cardvault/gui/library.glade +++ b/cardvault/gui/library.glade @@ -118,9 +118,7 @@ True 0 - - center - + 1 diff --git a/cardvault/gui/search.glade b/cardvault/gui/search.glade index 2e46fd2..fb25b9d 100644 --- a/cardvault/gui/search.glade +++ b/cardvault/gui/search.glade @@ -6,6 +6,38 @@ True False + + + True + False + Show Details + True + + + + + + True + False + + + + + True + False + Add to Library + True + + + + + + True + False + Add & Tag + True + + True @@ -260,6 +292,22 @@ 4 + + + Clear All + True + True + True + + + + 1 + 5 + + + + + False diff --git a/cardvault/handlers.py b/cardvault/handlers.py index 04ff724..3677dea 100644 --- a/cardvault/handlers.py +++ b/cardvault/handlers.py @@ -96,12 +96,14 @@ class Handlers: self.app.ui.get_object("searchOverlay").set_visible(False) - def do_clear_mana_filter(self, mana_filter_grid): + @staticmethod + def do_clear_mana_filter(mana_filter_grid): for toggle_button in mana_filter_grid.get_children(): if isinstance(toggle_button, Gtk.ToggleButton): toggle_button.set_active(False) - def do_clear_set_filter(self, entry, icon_pos, button): + @staticmethod + def do_clear_set_filter(entry, icon_pos, button): entry.set_text("") def do_add_clicked(self, button): @@ -117,6 +119,26 @@ class Handlers: self.app.ui.get_object("searchEntry").grab_focus() def search_tree_popup_showed(self, menu): + # Create tag submenu + tags_item = self.app.ui.get_object("searchListPopupAddTag") + tags_sub = Gtk.Menu() + tags_item.set_submenu(tags_sub) + + for list_name in self.app.tags.keys(): + item = Gtk.MenuItem() + tags_sub.add(item) + item.set_label(list_name) + item.connect('activate', self.search_popup_add_tags) + + # Add separator + tags_sub.add(Gtk.SeparatorMenuItem()) + # Add new tag item + new_tag = Gtk.MenuItem("New Tag") + new_tag.connect('activate', self.new_tag_and_add) + tags_sub.add(new_tag) + + tags_item.show_all() + # Create wants Submenu wants_item = self.app.ui.get_object("searchListPopupWants") wants_sub = Gtk.Menu() @@ -127,8 +149,53 @@ class Handlers: wants_sub.add(item) item.set_label(list_name) item.connect('activate', self.search_popup_add_wants) + + # Add separator + wants_sub.add(Gtk.SeparatorMenuItem()) + # Add new tag item + new_want = Gtk.MenuItem("New Want List") + new_want.connect('activate', self.new_wants_and_add) + wants_sub.add(new_want) + wants_item.show_all() + def new_tag_and_add(self, menu_item): + # Get selected cards + card_list = self.app.ui.get_object("searchResults").get_child() + cards = card_list.get_selected_cards() + response = self.app.show_name_enter_dialog("Enter name for new Tag", "") + if not response == "": + self.app.add_tag(response) + for card in cards.values(): + self.app.add_card_to_lib(card, response) + else: + util.log("No tag name entered", util.LogLevel.Warning) + self.app.push_status("No name for new tag entered") + search_funct.reload_search_view(self.app) + + def new_wants_and_add(self, menu_item): + # Get selected cards + card_list = self.app.ui.get_object("searchResults").get_child() + cards = card_list.get_selected_cards() + response = self.app.show_name_enter_dialog("Enter name for new Want List", "") + if not response == "": + self.app.add_want_list(response) + for card in cards.values(): + self.app.add_card_to_want_list(response, card) + else: + util.log("No list name entered", util.LogLevel.Warning) + self.app.push_status("No name for new wants list entered") + search_funct.reload_search_view(self.app) + + def search_popup_add_tags(self, item): + # Get selected cards + card_list = self.app.ui.get_object("searchResults").get_child() + cards = card_list.get_selected_cards() + for card in cards.values(): + self.app.add_card_to_lib(card, item.get_label()) + search_funct.reload_search_view(self.app) + self.app.push_status("Added " + str(len(cards)) + " card(s) to library.") + def search_popup_add_wants(self, item): # Get selected cards card_list = self.app.ui.get_object("searchResults").get_child() @@ -138,6 +205,28 @@ class Handlers: search_funct.reload_search_view(self.app) self.app.push_status("Added " + str(len(cards)) + " card(s) to Want List '" + item.get_label() + "'") + def do_search_clear_all_clicked(self, button): + """ Rest all controls in search view """ + self.app.ui.get_object("searchEntry").set_text("") + self.do_clear_mana_filter(self.app.ui.get_object("manaFilterGrid")) + self.app.ui.get_object("rarityCombo").set_active(0) + self.app.ui.get_object("typeCombo").set_active(0) + self.app.ui.get_object("setEntry").set_text("") + + + def do_show_card_details(self, menu_item): + tree = self.app.ui.get_object("searchResults").get_child() + cards = tree.get_selected_cards() + for card in cards.values(): + self.app.show_card_details(card) + + def do_search_add_to_lib(self, menu_item): + tree = self.app.ui.get_object("searchResults").get_child() + cards = tree.get_selected_cards() + for card in cards.values(): + self.app.add_card_to_lib(card) + search_funct.reload_search_view(self.app) + # ---------------------------------Library---------------------------------------------- def do_reload_library(self, view): @@ -194,7 +283,7 @@ class Handlers: tree_iter = model.get_iter(path) tag = model.get_value(tree_iter, 0) - new_name = self.app.show_rename_dialog(tag) + new_name = self.app.show_name_enter_dialog("Rename Tag", tag) self.app.rename_tag(tag, new_name) self.app.current_page.emit('show') @@ -291,7 +380,7 @@ class Handlers: tree_iter = model.get_iter(path) tag = model.get_value(tree_iter, 0) - new_name = self.app.show_rename_dialog(tag) + new_name = self.app.show_name_enter_dialog("Rename Want List", tag) if not tag == new_name: self.app.rename_want_list(tag, new_name) self.app.current_page.emit('show') diff --git a/cardvault/search_funct.py b/cardvault/search_funct.py index 0080b92..d1c0243 100644 --- a/cardvault/search_funct.py +++ b/cardvault/search_funct.py @@ -1,6 +1,7 @@ from urllib.error import URLError, HTTPError import gi +import time from gi.repository import Gtk, Gdk from cardvault import cardlist @@ -63,6 +64,8 @@ def search_cards(term: str, filters: dict) -> dict: # Load card info from internet try: + util.log("Fetching card info ...", util.LogLevel.Info) + start = time.time() cards = Card.where(name=term) \ .where(colorIdentity=filters["mana"]) \ .where(types=filters["type"]) \ @@ -70,6 +73,8 @@ def search_cards(term: str, filters: dict) -> dict: .where(rarity=filters["rarity"]) \ .where(pageSize=50) \ .where(page=1).all() + end = time.time() + util.log("Card info fetched in {}s".format(round(end - start, 3)), util.LogLevel.Info) except (URLError, HTTPError) as err: util.log(err, util.LogLevel.Error) return diff --git a/cardvault/util.py b/cardvault/util.py index b82be5a..4ad916e 100644 --- a/cardvault/util.py +++ b/cardvault/util.py @@ -6,6 +6,8 @@ import re from urllib import request import gi +import time + gi.require_version('Gtk', '3.0') from gi.repository import GdkPixbuf, GLib import six.moves.cPickle as pickle @@ -184,7 +186,10 @@ def load_mana_icons(path: str) -> dict: def net_load_set_list() -> dict: """ Load the list of all MTG sets from the Gather""" try: + start = time.time() sets = Set.all() + stop = time.time() + log("Fetched set list in {}s".format(round(stop-start, 3)), LogLevel.Info) except MtgException as err: log(str(err), LogLevel.Error) return {} @@ -193,8 +198,7 @@ def net_load_set_list() -> dict: def load_sets(filename: str) -> dict: # TODO Update Data function - # if not os.path.isfile(filename): - if True: + if not os.path.isfile(filename): # use mtgsdk api to retrieve al list of all sets sets = net_load_set_list() # Serialize the loaded data to a file