Use library icons in the choose and copy menus

This commit is contained in:
Kovid Goyal 2022-01-14 14:34:54 +05:30
parent cff77aab39
commit afd1aaeb24
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
2 changed files with 33 additions and 16 deletions

View File

@ -9,7 +9,7 @@ import posixpath
import sys import sys
import weakref import weakref
from contextlib import suppress from contextlib import suppress
from functools import partial from functools import partial, lru_cache
from qt.core import ( from qt.core import (
QAction, QCoreApplication, QDialog, QDialogButtonBox, QGridLayout, QIcon, QAction, QCoreApplication, QDialog, QDialogButtonBox, QGridLayout, QIcon,
QInputDialog, QLabel, QLineEdit, QMenu, QSize, Qt, QTimer, QToolButton, QInputDialog, QLabel, QLineEdit, QMenu, QSize, Qt, QTimer, QToolButton,
@ -39,6 +39,14 @@ def library_icon_path(lib_name=''):
return os.path.join(config_dir, 'library_icons', sanitize_file_name(lib_name or current_library_name()) + '.png') return os.path.join(config_dir, 'library_icons', sanitize_file_name(lib_name or current_library_name()) + '.png')
@lru_cache(maxsize=512)
def library_qicon(lib_name=''):
q = library_icon_path(lib_name)
if os.path.exists(q):
return QIcon(q)
return getattr(library_qicon, 'default_icon', None) or QIcon.ic('lt.png')
class LibraryUsageStats: # {{{ class LibraryUsageStats: # {{{
def __init__(self): def __init__(self):
@ -268,7 +276,7 @@ class ChooseLibraryAction(InterfaceAction):
self.remove_library_icon_action.triggered.connect(partial(self.remove_library_icon, '')) self.remove_library_icon_action.triggered.connect(partial(self.remove_library_icon, ''))
self.choose_library_icon_menu.addAction(self.choose_library_icon_action) self.choose_library_icon_menu.addAction(self.choose_library_icon_action)
self.choose_library_icon_menu.addAction(self.remove_library_icon_action) self.choose_library_icon_menu.addAction(self.remove_library_icon_action)
self.original_library_icon = self.qaction.icon() self.original_library_icon = library_qicon.default_icon = self.qaction.icon()
if not os.environ.get('CALIBRE_OVERRIDE_DATABASE_PATH', None): if not os.environ.get('CALIBRE_OVERRIDE_DATABASE_PATH', None):
self.choose_menu.addAction(self.action_choose) self.choose_menu.addAction(self.action_choose)
@ -357,6 +365,7 @@ class ChooseLibraryAction(InterfaceAction):
with open(icp, 'wb') as f: with open(icp, 'wb') as f:
f.write(pixmap_to_data(p, format='PNG')) f.write(pixmap_to_data(p, format='PNG'))
self.set_library_icon() self.set_library_icon()
library_qicon.cache_clear()
except Exception: except Exception:
import traceback import traceback
traceback.print_exc() traceback.print_exc()
@ -367,6 +376,7 @@ class ChooseLibraryAction(InterfaceAction):
try: try:
if os.path.exists(old_path): if os.path.exists(old_path):
os.replace(old_path, new_path) os.replace(old_path, new_path)
library_qicon.cache_clear()
except Exception: except Exception:
import traceback import traceback
traceback.print_exc() traceback.print_exc()
@ -376,6 +386,7 @@ class ChooseLibraryAction(InterfaceAction):
with suppress(FileNotFoundError): with suppress(FileNotFoundError):
os.remove(library_icon_path(name or current_library_name())) os.remove(library_icon_path(name or current_library_name()))
self.set_library_icon() self.set_library_icon()
library_qicon.cache_clear()
except Exception: except Exception:
import traceback import traceback
traceback.print_exc() traceback.print_exc()
@ -468,8 +479,9 @@ class ChooseLibraryAction(InterfaceAction):
quick_actions, rename_actions, delete_actions = [], [], [] quick_actions, rename_actions, delete_actions = [], [], []
for name, loc in locations: for name, loc in locations:
is_prev_lib = name == self.prev_lname is_prev_lib = name == self.prev_lname
ic = library_qicon(name)
name = name.replace('&', '&&') name = name.replace('&', '&&')
ac = self.quick_menu.addAction(name, Dispatcher(partial(self.switch_requested, ac = self.quick_menu.addAction(ic, name, Dispatcher(partial(self.switch_requested,
loc))) loc)))
ac.setStatusTip(_('Switch to: %s') % loc) ac.setStatusTip(_('Switch to: %s') % loc)
if is_prev_lib: if is_prev_lib:
@ -494,9 +506,11 @@ class ChooseLibraryAction(InterfaceAction):
locations_by_frequency = list(self.stats.locations(db, limit=sys.maxsize)) locations_by_frequency = list(self.stats.locations(db, limit=sys.maxsize))
for i, x in enumerate(locations_by_frequency[:len(self.switch_actions)]): for i, x in enumerate(locations_by_frequency[:len(self.switch_actions)]):
name, loc = x name, loc = x
ic = library_qicon(name)
name = name.replace('&', '&&') name = name.replace('&', '&&')
ac = self.switch_actions[i] ac = self.switch_actions[i]
ac.setText(name) ac.setText(name)
ac.setIcon(ic)
ac.setStatusTip(_('Switch to: %s') % loc) ac.setStatusTip(_('Switch to: %s') % loc)
ac.setVisible(True) ac.setVisible(True)
qs_actions.append(ac) qs_actions.append(ac)

View File

@ -6,26 +6,28 @@ __copyright__ = '2010, Kovid Goyal <kovid@kovidgoyal.net>'
__docformat__ = 'restructuredtext en' __docformat__ = 'restructuredtext en'
import os import os
from functools import partial
from threading import Thread
from contextlib import closing
from collections import defaultdict from collections import defaultdict
from contextlib import closing
from functools import partial
from qt.core import ( from qt.core import (
QToolButton, QDialog, QGridLayout, QIcon, QLabel, QDialogButtonBox, QAbstractItemView, QApplication, QCheckBox, QDialog, QDialogButtonBox,
QApplication, QLineEdit, QHBoxLayout, QFormLayout, QCheckBox, QWidget, QFormLayout, QGridLayout, QHBoxLayout, QIcon, QLabel, QLineEdit, QListWidget,
QScrollArea, QVBoxLayout, Qt, QListWidgetItem, QListWidget, QSize, QAbstractItemView) QListWidgetItem, QScrollArea, QSize, Qt, QToolButton, QVBoxLayout, QWidget
)
from threading import Thread
from calibre import as_unicode from calibre import as_unicode
from calibre.constants import ismacos from calibre.constants import ismacos
from calibre.db.copy_to_library import copy_one_book
from calibre.gui2 import (
Dispatcher, choose_dir, error_dialog, gprefs, info_dialog, warning_dialog
)
from calibre.gui2.actions import InterfaceAction from calibre.gui2.actions import InterfaceAction
from calibre.gui2 import (error_dialog, Dispatcher, warning_dialog, gprefs, from calibre.gui2.actions.choose_library import library_qicon
info_dialog, choose_dir)
from calibre.gui2.dialogs.progress import ProgressDialog from calibre.gui2.dialogs.progress import ProgressDialog
from calibre.gui2.widgets2 import Dialog from calibre.gui2.widgets2 import Dialog
from calibre.utils.config import prefs from calibre.utils.config import prefs
from calibre.utils.icu import sort_key, numeric_sort_key from calibre.utils.icu import numeric_sort_key, sort_key
from calibre.db.copy_to_library import copy_one_book
from polyglot.builtins import iteritems, itervalues from polyglot.builtins import iteritems, itervalues
@ -363,10 +365,11 @@ class CopyToLibraryAction(InterfaceAction):
self.menu.addAction(_('Choose library...'), self.choose_library) self.menu.addAction(_('Choose library...'), self.choose_library)
self.menu.addSeparator() self.menu.addSeparator()
for name, loc in locations: for name, loc in locations:
ic = library_qicon(name)
name = name.replace('&', '&&') name = name.replace('&', '&&')
self.menu.addAction(name, partial(self.copy_to_library, self.menu.addAction(ic, name, partial(self.copy_to_library,
loc)) loc))
self.menu.addAction(name + ' ' + _('(delete after copy)'), self.menu.addAction(ic, name + ' ' + _('(delete after copy)'),
partial(self.copy_to_library, loc, delete_after=True)) partial(self.copy_to_library, loc, delete_after=True))
self.menu.addSeparator() self.menu.addSeparator()
if len(locations) <= 5: if len(locations) <= 5: