mirror of
git://github.com/kovidgoyal/calibre.git
synced 2026-01-29 05:15:07 +01:00
1) change editing directly on library to use spinbox and value constraints
2) fix tag browser to ignore 0-valued rating custom columns. Also, refactor to save datatype in a map and use this datatype to find the tag formatter 3) fix tag browser and user category editor to display author names with comma instead of vertical bar
This commit is contained in:
parent
e7970c71c6
commit
c8a92fb7c5
5 changed files with 43 additions and 19 deletions
|
|
@ -39,7 +39,7 @@ def __init__(self, window, db, index=None):
|
|||
category_icons = [None, QIcon(I('user_profile.svg')), QIcon(I('series.svg')),
|
||||
QIcon(I('publisher.png')), QIcon(I('tags.svg'))]
|
||||
category_values = [None,
|
||||
lambda: [n for (id, n) in self.db.all_authors()],
|
||||
lambda: [n.replace('|', ',') for (id, n) in self.db.all_authors()],
|
||||
lambda: [n for (id, n) in self.db.all_series()],
|
||||
lambda: [n for (id, n) in self.db.all_publishers()],
|
||||
lambda: self.db.all_tags()
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
__license__ = 'GPL v3'
|
||||
__copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>'
|
||||
|
||||
import os, textwrap, traceback, re, shutil, functools
|
||||
import os, textwrap, traceback, re, shutil, functools, sys
|
||||
|
||||
from operator import attrgetter
|
||||
from math import cos, sin, pi
|
||||
|
|
@ -10,7 +10,7 @@
|
|||
from PyQt4.QtGui import QTableView, QAbstractItemView, QColor, \
|
||||
QPainterPath, QLinearGradient, QBrush, \
|
||||
QPen, QStyle, QPainter, QStyleOptionViewItemV4, \
|
||||
QIcon, QImage, QMenu, \
|
||||
QIcon, QImage, QMenu, QSpinBox, QDoubleSpinBox, \
|
||||
QStyledItemDelegate, QCompleter, QIntValidator, \
|
||||
QDoubleValidator, QComboBox
|
||||
from PyQt4.QtCore import QAbstractTableModel, QVariant, Qt, pyqtSignal, \
|
||||
|
|
@ -186,12 +186,18 @@ def createEditor(self, parent, option, index):
|
|||
m = index.model()
|
||||
col = m.column_map[index.column()]
|
||||
typ = m.custom_columns[col]['datatype']
|
||||
editor = EnLineEdit(parent)
|
||||
if typ == 'int':
|
||||
editor.setValidator(QIntValidator(parent))
|
||||
editor = QSpinBox(parent)
|
||||
editor.setRange(-100, sys.maxint)
|
||||
editor.setSpecialValueText(_('Undefined'))
|
||||
editor.setSingleStep(1)
|
||||
elif typ == 'float':
|
||||
editor.setValidator(QDoubleValidator(parent))
|
||||
editor = QDoubleSpinBox(parent)
|
||||
editor.setSpecialValueText(_('Undefined'))
|
||||
editor.setRange(-100., float(sys.maxint))
|
||||
editor.setDecimals(2)
|
||||
else:
|
||||
editor = EnLineEdit(parent)
|
||||
complete_items = sorted(list(m.db.all_custom(label=col)))
|
||||
completer = QCompleter(complete_items, self)
|
||||
completer.setCaseSensitivity(Qt.CaseInsensitive)
|
||||
|
|
|
|||
|
|
@ -195,10 +195,10 @@ def toggle(self):
|
|||
|
||||
class TagsModel(QAbstractItemModel):
|
||||
categories_orig = [_('Authors'), _('Series'), _('Formats'), _('Publishers'),
|
||||
_('Ratings'), _('News'), _('All tags')]
|
||||
_('Ratings'), _('News'), _('Tags')]
|
||||
row_map_orig = ['author', 'series', 'format', 'publisher', 'rating',
|
||||
'news', 'tag']
|
||||
tags_categories_start= 5
|
||||
tags_categories_start= 7
|
||||
search_keys=['search', _('Searches')]
|
||||
|
||||
def __init__(self, db, parent=None):
|
||||
|
|
@ -231,7 +231,11 @@ def get_node_tree(self, sort):
|
|||
self.row_map = []
|
||||
self.categories = []
|
||||
# strip the icons after the 'standard' categories. We will put them back later
|
||||
self.cat_icon_map = self.cat_icon_map_orig[:self.tags_categories_start-len(self.row_map_orig)]
|
||||
if self.tags_categories_start < len(self.row_map_orig):
|
||||
self.cat_icon_map = self.cat_icon_map_orig[:self.tags_categories_start-len(self.row_map_orig)]
|
||||
else:
|
||||
self.cat_icon_map = self.cat_icon_map_orig[:]
|
||||
|
||||
self.user_categories = dict.copy(config['user_categories'])
|
||||
column_map = config['column_map']
|
||||
|
||||
|
|
@ -256,12 +260,17 @@ def get_node_tree(self, sort):
|
|||
self.categories.append(self.categories_orig[i])
|
||||
self.cat_icon_map.append(self.cat_icon_map_orig[i])
|
||||
|
||||
# Clean up the author's tags, getting rid of the '|' characters
|
||||
if data['author'] is not None:
|
||||
for t in data['author']:
|
||||
t.name = t.name.replace('|', ',')
|
||||
|
||||
# Now do the user-defined categories. There is a time/space tradeoff here.
|
||||
# By converting the tags into a map, we can do the verification in the category
|
||||
# loop much faster, at the cost of duplicating the categories lists.
|
||||
taglist = {}
|
||||
for c in self.row_map:
|
||||
taglist[c] = dict(map(lambda t:(t.name if c != 'author' else t.name.replace('|', ','), t), data[c]))
|
||||
taglist[c] = dict(map(lambda t:(t.name, t), data[c]))
|
||||
|
||||
for c in self.user_categories:
|
||||
l = []
|
||||
|
|
|
|||
|
|
@ -145,9 +145,7 @@ def adapt_bool(x, d):
|
|||
if v['normalized']:
|
||||
tn = 'custom_column_{0}'.format(i)
|
||||
self.tag_browser_categories[tn] = [v['label'], 'value']
|
||||
if v['datatype'] == 'rating':
|
||||
self.tag_browser_formatters[tn] = lambda x:u'\u2605'*int(round(x/2.))
|
||||
|
||||
self.tag_browser_datatype[v['label']] = v['datatype']
|
||||
|
||||
def get_custom(self, idx, label=None, num=None, index_is_id=False):
|
||||
if label is not None:
|
||||
|
|
|
|||
|
|
@ -128,7 +128,16 @@ def __init__(self, library_path, row_factory=False):
|
|||
'news' : ['news', 'name'],
|
||||
'ratings' : ['rating', 'rating']
|
||||
}
|
||||
self.tag_browser_formatters = {'ratings': lambda x:u'\u2605'*int(round(x/2.))}
|
||||
self.tag_browser_datatype = {
|
||||
'tag' : 'textmult',
|
||||
'series' : None,
|
||||
'publisher' : 'text',
|
||||
'author' : 'text',
|
||||
'news' : None,
|
||||
'rating' : 'rating',
|
||||
}
|
||||
|
||||
self.tag_browser_formatters = {'rating': lambda x:u'\u2605'*int(round(x/2.))}
|
||||
|
||||
self.connect()
|
||||
self.is_case_sensitive = not iswindows and not isosx and \
|
||||
|
|
@ -630,14 +639,16 @@ def get_categories(self, sort_on_count=False, ids=None, icon_map=None):
|
|||
if icon_map:
|
||||
if category in icon_map:
|
||||
icon = icon_map[category]
|
||||
tooltip = ''
|
||||
else:
|
||||
icon = icon_map['*custom']
|
||||
tooltip = self.custom_column_label_map[category]['name']
|
||||
formatter = self.tag_browser_formatters.get(tn, lambda x: x)
|
||||
categories[category] = [Tag(formatter(r[1]), count=r[2], id=r[0], icon=icon, tooltip = tooltip)
|
||||
for r in data
|
||||
if r[2] > 0 and (category != 'rating' or len(formatter(r[1])) > 0)]
|
||||
datatype = self.tag_browser_datatype[category]
|
||||
formatter = self.tag_browser_formatters.get(datatype, lambda x: x)
|
||||
categories[category] = [Tag(formatter(r[1]), count=r[2], id=r[0],
|
||||
icon=icon, tooltip = tooltip)
|
||||
for r in data
|
||||
if r[2] > 0 and
|
||||
(datatype != 'rating' or len(formatter(r[1])) > 0)]
|
||||
categories['format'] = []
|
||||
for fmt in self.conn.get('SELECT DISTINCT format FROM data'):
|
||||
fmt = fmt[0]
|
||||
|
|
|
|||
Loading…
Reference in a new issue