New tag & want functions for context menu in search view.

This commit is contained in:
luxick
2017-07-02 15:40:46 +02:00
parent 8a0995d74f
commit f5cd7d5d1c
8 changed files with 190 additions and 26 deletions

View File

@@ -28,6 +28,13 @@ from cardvault import wants_funct
class Application: class Application:
# ---------------------------------Initialize the Application---------------------------------------------- # ---------------------------------Initialize the Application----------------------------------------------
def __init__(self): 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 # Load ui files
self.ui = Gtk.Builder() self.ui = Gtk.Builder()
self.ui.add_from_file(util.get_ui_filename("mainwindow.glade")) self.ui.add_from_file(util.get_ui_filename("mainwindow.glade"))
@@ -49,17 +56,13 @@ class Application:
"wants": self.ui.get_object("wantsView") "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 # 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.image_cache = util.reload_image_cache(util.CACHE_PATH + "images/")
self.precon_icons = util.reload_preconstructed_icons(util.CACHE_PATH + "icons/") self.precon_icons = util.reload_preconstructed_icons(util.CACHE_PATH + "icons/")
self.mana_icons = util.load_mana_icons(os.path.dirname(__file__) + "/resources/mana/") 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.sets = util.load_sets(util.get_root_filename("sets"))
self.library = Dict[str, Type[mtgsdk.Card]] 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 = [page for page in view_menu.get_children() if page.get_name() == util.START_PAGE]
start_page[0].activate() start_page[0].activate()
util.log("Launching Card Vault version {}".format(util.VERSION), util.LogLevel.Info)
def push_status(self, msg): def push_status(self, msg):
status_bar = self.ui.get_object("statusBar") status_bar = self.ui.get_object("statusBar")
status_bar.pop(0) status_bar.pop(0)
@@ -185,11 +191,14 @@ class Application:
dialog.run() dialog.run()
dialog.destroy() dialog.destroy()
def show_rename_dialog(self, name: str) -> str: def show_name_enter_dialog(self, title: str, value: str) -> str:
dialog = self.ui.get_object("renameDialog") # type: Gtk.Dialog dialog = self.ui.get_object("nameEnterDialog") # type: Gtk.Dialog
dialog.set_transient_for(self.ui.get_object("mainWindow")) dialog.set_transient_for(self.ui.get_object("mainWindow"))
entry = self.ui.get_object("renameDialogEntry") label = self.ui.get_object("nameEnterLabel")
entry.set_text(name) label.set_text(title)
entry = self.ui.get_object("nameEnterEntry")
entry.set_text(value)
entry.grab_focus()
result = dialog.run() result = dialog.run()
dialog.hide() dialog.hide()
@@ -197,7 +206,7 @@ class Application:
if result == Gtk.ResponseType.OK: if result == Gtk.ResponseType.OK:
return entry.get_text() return entry.get_text()
else: else:
return name return value
def save_library(self): def save_library(self):
# Save library file # Save library file
@@ -309,10 +318,10 @@ class Application:
def add_want_list(self, name): def add_want_list(self, name):
self.wants[name] = [] self.wants[name] = []
util.log("Want list '" + name + "' created", util.LogLevel.Info) 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 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) self.wants[list_name].append(card)
util.log(card.name + " added to want list " + list_name, util.LogLevel.Info) util.log(card.name + " added to want list " + list_name, util.LogLevel.Info)
self.unsaved_changes = True self.unsaved_changes = True
@@ -341,7 +350,7 @@ class Application:
def get_mana_icons(self, mana_string): def get_mana_icons(self, mana_string):
if not 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 return
icon_list = re.findall("{(.*?)}", mana_string) icon_list = re.findall("{(.*?)}", mana_string)
icon_name = "_".join(icon_list) icon_name = "_".join(icon_list)

View File

@@ -118,7 +118,7 @@ class CardList(Gtk.ScrolledWindow):
self.store.set_sort_column_id(1, Gtk.SortType.ASCENDING) 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() (model, pathlist) = self.selection.get_selected_rows()
output = {} output = {}
for path in pathlist: for path in pathlist:

View File

@@ -2,7 +2,7 @@
<!-- Generated with glade 3.20.0 --> <!-- Generated with glade 3.20.0 -->
<interface> <interface>
<requires lib="gtk+" version="3.20"/> <requires lib="gtk+" version="3.20"/>
<object class="GtkDialog" id="renameDialog"> <object class="GtkDialog" id="nameEnterDialog">
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="resizable">False</property> <property name="resizable">False</property>
<property name="modal">True</property> <property name="modal">True</property>
@@ -53,7 +53,18 @@
</packing> </packing>
</child> </child>
<child> <child>
<object class="GtkEntry" id="renameDialogEntry"> <object class="GtkLabel" id="nameEnterLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="nameEnterEntry">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">True</property> <property name="can_focus">True</property>
</object> </object>

View File

@@ -118,9 +118,7 @@
<property name="sort_indicator">True</property> <property name="sort_indicator">True</property>
<property name="sort_column_id">0</property> <property name="sort_column_id">0</property>
<child> <child>
<object class="GtkCellRendererText" id="cell_tag"> <object class="GtkCellRendererText" id="cell_tag"/>
<property name="alignment">center</property>
</object>
<attributes> <attributes>
<attribute name="text">1</attribute> <attribute name="text">1</attribute>
</attributes> </attributes>

View File

@@ -6,6 +6,38 @@
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can_focus">False</property>
<signal name="show" handler="search_tree_popup_showed" swapped="no"/> <signal name="show" handler="search_tree_popup_showed" swapped="no"/>
<child>
<object class="GtkMenuItem" id="searchListPopupDetails">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Show Details</property>
<property name="use_underline">True</property>
<signal name="activate" handler="do_show_card_details" swapped="no"/>
</object>
</child>
<child>
<object class="GtkSeparatorMenuItem">
<property name="visible">True</property>
<property name="can_focus">False</property>
</object>
</child>
<child>
<object class="GtkMenuItem" id="searchListPopupAdd">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Add to Library</property>
<property name="use_underline">True</property>
<signal name="activate" handler="do_search_add_to_lib" swapped="no"/>
</object>
</child>
<child>
<object class="GtkMenuItem" id="searchListPopupAddTag">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Add &amp; Tag</property>
<property name="use_underline">True</property>
</object>
</child>
<child> <child>
<object class="GtkMenuItem" id="searchListPopupWants"> <object class="GtkMenuItem" id="searchListPopupWants">
<property name="visible">True</property> <property name="visible">True</property>
@@ -260,6 +292,22 @@
<property name="top_attach">4</property> <property name="top_attach">4</property>
</packing> </packing>
</child> </child>
<child>
<object class="GtkButton" id="searchClearAll">
<property name="label" translatable="yes">Clear All</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<signal name="clicked" handler="do_search_clear_all_clicked" swapped="no"/>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">5</property>
</packing>
</child>
<child>
<placeholder/>
</child>
</object> </object>
<packing> <packing>
<property name="expand">False</property> <property name="expand">False</property>

View File

@@ -96,12 +96,14 @@ class Handlers:
self.app.ui.get_object("searchOverlay").set_visible(False) 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(): for toggle_button in mana_filter_grid.get_children():
if isinstance(toggle_button, Gtk.ToggleButton): if isinstance(toggle_button, Gtk.ToggleButton):
toggle_button.set_active(False) 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("") entry.set_text("")
def do_add_clicked(self, button): def do_add_clicked(self, button):
@@ -117,6 +119,26 @@ class Handlers:
self.app.ui.get_object("searchEntry").grab_focus() self.app.ui.get_object("searchEntry").grab_focus()
def search_tree_popup_showed(self, menu): 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 # Create wants Submenu
wants_item = self.app.ui.get_object("searchListPopupWants") wants_item = self.app.ui.get_object("searchListPopupWants")
wants_sub = Gtk.Menu() wants_sub = Gtk.Menu()
@@ -127,8 +149,53 @@ class Handlers:
wants_sub.add(item) wants_sub.add(item)
item.set_label(list_name) item.set_label(list_name)
item.connect('activate', self.search_popup_add_wants) 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() 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): def search_popup_add_wants(self, item):
# Get selected cards # Get selected cards
card_list = self.app.ui.get_object("searchResults").get_child() card_list = self.app.ui.get_object("searchResults").get_child()
@@ -138,6 +205,28 @@ class Handlers:
search_funct.reload_search_view(self.app) search_funct.reload_search_view(self.app)
self.app.push_status("Added " + str(len(cards)) + " card(s) to Want List '" + item.get_label() + "'") 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---------------------------------------------- # ---------------------------------Library----------------------------------------------
def do_reload_library(self, view): def do_reload_library(self, view):
@@ -194,7 +283,7 @@ class Handlers:
tree_iter = model.get_iter(path) tree_iter = model.get_iter(path)
tag = model.get_value(tree_iter, 0) 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.rename_tag(tag, new_name)
self.app.current_page.emit('show') self.app.current_page.emit('show')
@@ -291,7 +380,7 @@ class Handlers:
tree_iter = model.get_iter(path) tree_iter = model.get_iter(path)
tag = model.get_value(tree_iter, 0) 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: if not tag == new_name:
self.app.rename_want_list(tag, new_name) self.app.rename_want_list(tag, new_name)
self.app.current_page.emit('show') self.app.current_page.emit('show')

View File

@@ -1,6 +1,7 @@
from urllib.error import URLError, HTTPError from urllib.error import URLError, HTTPError
import gi import gi
import time
from gi.repository import Gtk, Gdk from gi.repository import Gtk, Gdk
from cardvault import cardlist from cardvault import cardlist
@@ -63,6 +64,8 @@ def search_cards(term: str, filters: dict) -> dict:
# Load card info from internet # Load card info from internet
try: try:
util.log("Fetching card info ...", util.LogLevel.Info)
start = time.time()
cards = Card.where(name=term) \ cards = Card.where(name=term) \
.where(colorIdentity=filters["mana"]) \ .where(colorIdentity=filters["mana"]) \
.where(types=filters["type"]) \ .where(types=filters["type"]) \
@@ -70,6 +73,8 @@ def search_cards(term: str, filters: dict) -> dict:
.where(rarity=filters["rarity"]) \ .where(rarity=filters["rarity"]) \
.where(pageSize=50) \ .where(pageSize=50) \
.where(page=1).all() .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: except (URLError, HTTPError) as err:
util.log(err, util.LogLevel.Error) util.log(err, util.LogLevel.Error)
return return

View File

@@ -6,6 +6,8 @@ import re
from urllib import request from urllib import request
import gi import gi
import time
gi.require_version('Gtk', '3.0') gi.require_version('Gtk', '3.0')
from gi.repository import GdkPixbuf, GLib from gi.repository import GdkPixbuf, GLib
import six.moves.cPickle as pickle import six.moves.cPickle as pickle
@@ -184,7 +186,10 @@ def load_mana_icons(path: str) -> dict:
def net_load_set_list() -> dict: def net_load_set_list() -> dict:
""" Load the list of all MTG sets from the Gather""" """ Load the list of all MTG sets from the Gather"""
try: try:
start = time.time()
sets = Set.all() sets = Set.all()
stop = time.time()
log("Fetched set list in {}s".format(round(stop-start, 3)), LogLevel.Info)
except MtgException as err: except MtgException as err:
log(str(err), LogLevel.Error) log(str(err), LogLevel.Error)
return {} return {}
@@ -193,8 +198,7 @@ def net_load_set_list() -> dict:
def load_sets(filename: str) -> dict: def load_sets(filename: str) -> dict:
# TODO Update Data function # TODO Update Data function
# if not os.path.isfile(filename): if not os.path.isfile(filename):
if True:
# use mtgsdk api to retrieve al list of all sets # use mtgsdk api to retrieve al list of all sets
sets = net_load_set_list() sets = net_load_set_list()
# Serialize the loaded data to a file # Serialize the loaded data to a file