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:
Charles Haley 2010-05-06 12:06:17 +01:00
parent e7970c71c6
commit c8a92fb7c5
5 changed files with 43 additions and 19 deletions

View File

@ -39,7 +39,7 @@ class TagCategories(QDialog, Ui_TagCategories):
category_icons = [None, QIcon(I('user_profile.svg')), QIcon(I('series.svg')), category_icons = [None, QIcon(I('user_profile.svg')), QIcon(I('series.svg')),
QIcon(I('publisher.png')), QIcon(I('tags.svg'))] QIcon(I('publisher.png')), QIcon(I('tags.svg'))]
category_values = [None, 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_series()],
lambda: [n for (id, n) in self.db.all_publishers()], lambda: [n for (id, n) in self.db.all_publishers()],
lambda: self.db.all_tags() lambda: self.db.all_tags()

View File

@ -1,7 +1,7 @@
__license__ = 'GPL v3' __license__ = 'GPL v3'
__copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>' __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 operator import attrgetter
from math import cos, sin, pi from math import cos, sin, pi
@ -10,7 +10,7 @@ from contextlib import closing
from PyQt4.QtGui import QTableView, QAbstractItemView, QColor, \ from PyQt4.QtGui import QTableView, QAbstractItemView, QColor, \
QPainterPath, QLinearGradient, QBrush, \ QPainterPath, QLinearGradient, QBrush, \
QPen, QStyle, QPainter, QStyleOptionViewItemV4, \ QPen, QStyle, QPainter, QStyleOptionViewItemV4, \
QIcon, QImage, QMenu, \ QIcon, QImage, QMenu, QSpinBox, QDoubleSpinBox, \
QStyledItemDelegate, QCompleter, QIntValidator, \ QStyledItemDelegate, QCompleter, QIntValidator, \
QDoubleValidator, QComboBox QDoubleValidator, QComboBox
from PyQt4.QtCore import QAbstractTableModel, QVariant, Qt, pyqtSignal, \ from PyQt4.QtCore import QAbstractTableModel, QVariant, Qt, pyqtSignal, \
@ -186,12 +186,18 @@ class CcTextDelegate(QStyledItemDelegate):
m = index.model() m = index.model()
col = m.column_map[index.column()] col = m.column_map[index.column()]
typ = m.custom_columns[col]['datatype'] typ = m.custom_columns[col]['datatype']
editor = EnLineEdit(parent)
if typ == 'int': if typ == 'int':
editor.setValidator(QIntValidator(parent)) editor = QSpinBox(parent)
editor.setRange(-100, sys.maxint)
editor.setSpecialValueText(_('Undefined'))
editor.setSingleStep(1)
elif typ == 'float': elif typ == 'float':
editor.setValidator(QDoubleValidator(parent)) editor = QDoubleSpinBox(parent)
editor.setSpecialValueText(_('Undefined'))
editor.setRange(-100., float(sys.maxint))
editor.setDecimals(2)
else: else:
editor = EnLineEdit(parent)
complete_items = sorted(list(m.db.all_custom(label=col))) complete_items = sorted(list(m.db.all_custom(label=col)))
completer = QCompleter(complete_items, self) completer = QCompleter(complete_items, self)
completer.setCaseSensitivity(Qt.CaseInsensitive) completer.setCaseSensitivity(Qt.CaseInsensitive)

View File

@ -195,10 +195,10 @@ class TagTreeItem(object):
class TagsModel(QAbstractItemModel): class TagsModel(QAbstractItemModel):
categories_orig = [_('Authors'), _('Series'), _('Formats'), _('Publishers'), categories_orig = [_('Authors'), _('Series'), _('Formats'), _('Publishers'),
_('Ratings'), _('News'), _('All tags')] _('Ratings'), _('News'), _('Tags')]
row_map_orig = ['author', 'series', 'format', 'publisher', 'rating', row_map_orig = ['author', 'series', 'format', 'publisher', 'rating',
'news', 'tag'] 'news', 'tag']
tags_categories_start= 5 tags_categories_start= 7
search_keys=['search', _('Searches')] search_keys=['search', _('Searches')]
def __init__(self, db, parent=None): def __init__(self, db, parent=None):
@ -231,7 +231,11 @@ class TagsModel(QAbstractItemModel):
self.row_map = [] self.row_map = []
self.categories = [] self.categories = []
# strip the icons after the 'standard' categories. We will put them back later # strip the icons after the 'standard' categories. We will put them back later
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)] 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']) self.user_categories = dict.copy(config['user_categories'])
column_map = config['column_map'] column_map = config['column_map']
@ -256,12 +260,17 @@ class TagsModel(QAbstractItemModel):
self.categories.append(self.categories_orig[i]) self.categories.append(self.categories_orig[i])
self.cat_icon_map.append(self.cat_icon_map_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. # 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 # 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. # loop much faster, at the cost of duplicating the categories lists.
taglist = {} taglist = {}
for c in self.row_map: 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: for c in self.user_categories:
l = [] l = []

View File

@ -145,9 +145,7 @@ class CustomColumns(object):
if v['normalized']: if v['normalized']:
tn = 'custom_column_{0}'.format(i) tn = 'custom_column_{0}'.format(i)
self.tag_browser_categories[tn] = [v['label'], 'value'] self.tag_browser_categories[tn] = [v['label'], 'value']
if v['datatype'] == 'rating': self.tag_browser_datatype[v['label']] = v['datatype']
self.tag_browser_formatters[tn] = lambda x:u'\u2605'*int(round(x/2.))
def get_custom(self, idx, label=None, num=None, index_is_id=False): def get_custom(self, idx, label=None, num=None, index_is_id=False):
if label is not None: if label is not None:

View File

@ -128,7 +128,16 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
'news' : ['news', 'name'], 'news' : ['news', 'name'],
'ratings' : ['rating', 'rating'] '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.connect()
self.is_case_sensitive = not iswindows and not isosx and \ self.is_case_sensitive = not iswindows and not isosx and \
@ -630,14 +639,16 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
if icon_map: if icon_map:
if category in icon_map: if category in icon_map:
icon = icon_map[category] icon = icon_map[category]
tooltip = ''
else: else:
icon = icon_map['*custom'] icon = icon_map['*custom']
tooltip = self.custom_column_label_map[category]['name'] tooltip = self.custom_column_label_map[category]['name']
formatter = self.tag_browser_formatters.get(tn, lambda x: x) datatype = self.tag_browser_datatype[category]
categories[category] = [Tag(formatter(r[1]), count=r[2], id=r[0], icon=icon, tooltip = tooltip) 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 for r in data
if r[2] > 0 and (category != 'rating' or len(formatter(r[1])) > 0)] if r[2] > 0 and
(datatype != 'rating' or len(formatter(r[1])) > 0)]
categories['format'] = [] categories['format'] = []
for fmt in self.conn.get('SELECT DISTINCT format FROM data'): for fmt in self.conn.get('SELECT DISTINCT format FROM data'):
fmt = fmt[0] fmt = fmt[0]