mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Allow changing the icons for categories in the Tag Browser. Right click on a category and choose 'Change category icon'. Fixes #1092098 (UserCategory Icons (Whishlist))
This commit is contained in:
commit
30e073fbeb
@ -106,6 +106,7 @@ gprefs.defaults['tag_browser_old_look'] = False
|
||||
gprefs.defaults['book_list_tooltips'] = True
|
||||
gprefs.defaults['bd_show_cover'] = True
|
||||
gprefs.defaults['bd_overlay_cover_size'] = False
|
||||
gprefs.defaults['tags_browser_category_icons'] = {}
|
||||
# }}}
|
||||
|
||||
NONE = QVariant() #: Null value to return from the data function of item models
|
||||
|
@ -8,11 +8,12 @@ __license__ = 'GPL v3'
|
||||
__copyright__ = '2011, Kovid Goyal <kovid@kovidgoyal.net>'
|
||||
__docformat__ = 'restructuredtext en'
|
||||
|
||||
import traceback, cPickle, copy
|
||||
import traceback, cPickle, copy, os
|
||||
|
||||
from PyQt4.Qt import (QAbstractItemModel, QIcon, QVariant, QFont, Qt,
|
||||
QMimeData, QModelIndex, pyqtSignal, QObject)
|
||||
|
||||
from calibre.constants import config_dir
|
||||
from calibre.gui2 import NONE, gprefs, config, error_dialog
|
||||
from calibre.library.database2 import Tag
|
||||
from calibre.utils.config import tweaks
|
||||
@ -213,6 +214,11 @@ class TagsModel(QAbstractItemModel): # {{{
|
||||
for key in category_icon_map:
|
||||
iconmap[key] = QIcon(I(category_icon_map[key]))
|
||||
self.category_icon_map = TagsIcons(iconmap)
|
||||
self.category_custom_icons = dict()
|
||||
for k, v in gprefs['tags_browser_category_icons'].iteritems():
|
||||
icon = QIcon(os.path.join(config_dir, 'tb_icons', v))
|
||||
if len(icon.availableSizes()) > 0:
|
||||
self.category_custom_icons[k] = icon
|
||||
self.categories_with_ratings = ['authors', 'series', 'publisher', 'tags']
|
||||
self.icon_state_map = [None, QIcon(I('plus.png')), QIcon(I('plusplus.png')),
|
||||
QIcon(I('minus.png')), QIcon(I('minusminus.png'))]
|
||||
@ -231,6 +237,23 @@ class TagsModel(QAbstractItemModel): # {{{
|
||||
def gui_parent(self):
|
||||
return QObject.parent(self)
|
||||
|
||||
def set_custom_category_icon(self, key, path):
|
||||
d = gprefs['tags_browser_category_icons']
|
||||
if path:
|
||||
d[key] = path
|
||||
self.category_custom_icons[key] = QIcon(os.path.join(config_dir,
|
||||
'tb_icons', path))
|
||||
else:
|
||||
if key in d:
|
||||
path = os.path.join(config_dir, 'tb_icons', d[key])
|
||||
try:
|
||||
os.remove(path)
|
||||
except:
|
||||
pass
|
||||
del d[key]
|
||||
del self.category_custom_icons[key]
|
||||
gprefs['tags_browser_category_icons'] = d
|
||||
|
||||
def reread_collapse_model(self, state_map, rebuild=True):
|
||||
if gprefs['tags_browser_collapse_at'] == 0:
|
||||
self.collapse_model = 'disable'
|
||||
@ -304,13 +327,18 @@ class TagsModel(QAbstractItemModel): # {{{
|
||||
continue
|
||||
is_gst = False
|
||||
if key.startswith('@') and key[1:] in gst:
|
||||
tt = _(u'The grouped search term name is "{0}"').format(key[1:])
|
||||
tt = _(u'The grouped search term name is "{0}"').format(key)
|
||||
is_gst = True
|
||||
elif key == 'news':
|
||||
tt = ''
|
||||
else:
|
||||
tt = _(u'The lookup/search name is "{0}"').format(key)
|
||||
|
||||
if self.category_custom_icons.get(key, None) is None:
|
||||
self.category_custom_icons[key] = (
|
||||
self.category_icon_map['gst'] if is_gst else
|
||||
self.category_icon_map.get(key, self.category_icon_map['custom:']))
|
||||
|
||||
if key.startswith('@'):
|
||||
path_parts = [p for p in key.split('.')]
|
||||
path = ''
|
||||
@ -319,14 +347,12 @@ class TagsModel(QAbstractItemModel): # {{{
|
||||
for i,p in enumerate(path_parts):
|
||||
path += p
|
||||
if path not in category_node_map:
|
||||
icon = self.category_icon_map['gst'] if is_gst else \
|
||||
self.category_icon_map[key]
|
||||
node = self.create_node(parent=last_category_node,
|
||||
data=p[1:] if i == 0 else p,
|
||||
category_icon=icon,
|
||||
tooltip=tt if path == key else path,
|
||||
category_key=path,
|
||||
icon_map=self.icon_state_map)
|
||||
data=p[1:] if i == 0 else p,
|
||||
category_icon=self.category_custom_icons[key],
|
||||
tooltip=tt if path == key else path,
|
||||
category_key=path,
|
||||
icon_map=self.icon_state_map)
|
||||
last_category_node = node
|
||||
category_node_map[path] = node
|
||||
self.category_nodes.append(node)
|
||||
@ -343,7 +369,7 @@ class TagsModel(QAbstractItemModel): # {{{
|
||||
else:
|
||||
node = self.create_node(parent=self.root_item,
|
||||
data=self.categories[key],
|
||||
category_icon=self.category_icon_map[key],
|
||||
category_icon=self.category_custom_icons[key],
|
||||
tooltip=tt, category_key=key,
|
||||
icon_map=self.icon_state_map)
|
||||
node.is_gst = False
|
||||
@ -504,6 +530,7 @@ class TagsModel(QAbstractItemModel): # {{{
|
||||
if (not tag.is_hierarchical) and (in_uc or
|
||||
(fm['is_custom'] and fm['display'].get('is_names', False)) or
|
||||
not category_is_hierarchical or len(components) == 1):
|
||||
tag.icon = self.category_custom_icons[key]
|
||||
n = self.create_node(parent=node_parent, data=tag, tooltip=tt,
|
||||
icon_map=self.icon_state_map)
|
||||
if tag.id_set is not None:
|
||||
@ -540,6 +567,7 @@ class TagsModel(QAbstractItemModel): # {{{
|
||||
t.is_hierarchical = \
|
||||
'5state' if t.category != 'search' else '3state'
|
||||
t.name = comp
|
||||
t.icon = self.category_custom_icons[key]
|
||||
node_parent = self.create_node(parent=node_parent, data=t,
|
||||
tooltip=tt, icon_map=self.icon_state_map)
|
||||
child_map[(comp,tag.category)] = node_parent
|
||||
|
@ -7,7 +7,7 @@ __license__ = 'GPL v3'
|
||||
__copyright__ = '2011, Kovid Goyal <kovid@kovidgoyal.net>'
|
||||
__docformat__ = 'restructuredtext en'
|
||||
|
||||
import cPickle
|
||||
import cPickle, os
|
||||
from functools import partial
|
||||
from itertools import izip
|
||||
|
||||
@ -15,9 +15,11 @@ from PyQt4.Qt import (QStyledItemDelegate, Qt, QTreeView, pyqtSignal, QSize,
|
||||
QIcon, QApplication, QMenu, QPoint, QModelIndex, QToolTip, QCursor,
|
||||
QDrag)
|
||||
|
||||
from calibre import sanitize_file_name_unicode
|
||||
from calibre.constants import config_dir
|
||||
from calibre.gui2.tag_browser.model import (TagTreeItem, TAG_SEARCH_STATES,
|
||||
TagsModel)
|
||||
from calibre.gui2 import config, gprefs
|
||||
from calibre.gui2 import config, gprefs, choose_files, pixmap_to_data
|
||||
from calibre.utils.search_query_parser import saved_searches
|
||||
from calibre.utils.icu import sort_key
|
||||
|
||||
@ -296,6 +298,33 @@ class TagsView(QTreeView): # {{{
|
||||
if not action:
|
||||
return
|
||||
try:
|
||||
if action == 'set_icon':
|
||||
try:
|
||||
path = choose_files(self, 'choose_category_icon',
|
||||
_('Change Icon for: %s')%key, filters=[
|
||||
('Images', ['png', 'gif', 'jpg', 'jpeg'])],
|
||||
all_files=False, select_only_single_file=True)
|
||||
if path:
|
||||
path = path[0]
|
||||
p = QIcon(path).pixmap(QSize(128, 128))
|
||||
d = os.path.join(config_dir, 'tb_icons')
|
||||
if not os.path.exists(d):
|
||||
os.makedirs(d)
|
||||
with open(os.path.join(d, 'icon_'+
|
||||
sanitize_file_name_unicode(key)+'.png'), 'wb') as f:
|
||||
f.write(pixmap_to_data(p, format='PNG'))
|
||||
path = os.path.basename(f.name)
|
||||
self._model.set_custom_category_icon(key, unicode(path))
|
||||
self.recount()
|
||||
except:
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
return
|
||||
if action == 'clear_icon':
|
||||
self._model.set_custom_category_icon(key, None)
|
||||
self.recount()
|
||||
return
|
||||
|
||||
if action == 'edit_item':
|
||||
self.edit(index)
|
||||
return
|
||||
@ -533,6 +562,12 @@ class TagsView(QTreeView): # {{{
|
||||
partial(self.context_menu_handler, action='manage_searches',
|
||||
category=tag.name if tag else None))
|
||||
|
||||
self.context_menu.addSeparator()
|
||||
self.context_menu.addAction(_('Change category icon'),
|
||||
partial(self.context_menu_handler, action='set_icon', key=key))
|
||||
self.context_menu.addAction(_('Restore default icon'),
|
||||
partial(self.context_menu_handler, action='clear_icon', key=key))
|
||||
|
||||
# Always show the user categories editor
|
||||
self.context_menu.addSeparator()
|
||||
if key.startswith('@') and \
|
||||
@ -551,6 +586,7 @@ class TagsView(QTreeView): # {{{
|
||||
self.context_menu.addAction(_('Show all categories'),
|
||||
partial(self.context_menu_handler, action='defaults'))
|
||||
|
||||
|
||||
m = self.context_menu.addMenu(_('Change sub-categorization scheme'))
|
||||
da = m.addAction(_('Disable'),
|
||||
partial(self.context_menu_handler, action='categorization', category='disable'))
|
||||
|
Loading…
x
Reference in New Issue
Block a user