mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Allow sorting of tags view by popularity
This commit is contained in:
parent
ab6a567334
commit
54bf6f0a7e
@ -37,6 +37,8 @@ def _config():
|
||||
help=_('Notify when a new version is available'))
|
||||
c.add_opt('use_roman_numerals_for_series_number', default=True,
|
||||
help=_('Use Roman numerals for series number'))
|
||||
c.add_opt('sort_by_popularity', default=False,
|
||||
help=_('Sort tags list by popularity'))
|
||||
c.add_opt('cover_flow_queue_length', default=6,
|
||||
help=_('Number of covers to show in the cover browsing mode'))
|
||||
c.add_opt('LRF_conversion_defaults', default=[],
|
||||
|
@ -250,7 +250,8 @@ class Main(MainWindow, Ui_MainWindow):
|
||||
self.tags_view.setVisible(False)
|
||||
self.match_all.setVisible(False)
|
||||
self.match_any.setVisible(False)
|
||||
self.tags_view.set_database(db, self.match_all)
|
||||
self.popularity.setVisible(False)
|
||||
self.tags_view.set_database(db, self.match_all, self.popularity)
|
||||
self.connect(self.tags_view, SIGNAL('tags_marked(PyQt_PyObject, PyQt_PyObject)'),
|
||||
self.search.search_from_tokens)
|
||||
self.connect(self.status_bar.tag_view_button, SIGNAL('toggled(bool)'), self.toggle_tags_view)
|
||||
@ -300,11 +301,13 @@ class Main(MainWindow, Ui_MainWindow):
|
||||
self.tags_view.setVisible(True)
|
||||
self.match_all.setVisible(True)
|
||||
self.match_any.setVisible(True)
|
||||
self.popularity.setVisible(True)
|
||||
self.tags_view.setFocus(Qt.OtherFocusReason)
|
||||
else:
|
||||
self.tags_view.setVisible(False)
|
||||
self.match_all.setVisible(False)
|
||||
self.match_any.setVisible(False)
|
||||
self.popularity.setVisible(False)
|
||||
|
||||
def sync_cf_to_listview(self, index, *args):
|
||||
if not hasattr(index, 'row') and self.library_view.currentIndex().row() != index:
|
||||
|
@ -262,6 +262,13 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="popularity" >
|
||||
<property name="text" >
|
||||
<string>Sort by &popularity</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="TagsView" name="tags_view" >
|
||||
<property name="tabKeyNavigation" >
|
||||
|
@ -8,7 +8,7 @@ Browsing book collection by tags.
|
||||
'''
|
||||
from PyQt4.Qt import QAbstractItemModel, Qt, QVariant, QTreeView, QModelIndex, \
|
||||
QFont, SIGNAL, QSize, QColor, QIcon
|
||||
|
||||
from calibre.gui2 import config
|
||||
NONE = QVariant()
|
||||
|
||||
class TagsView(QTreeView):
|
||||
@ -19,23 +19,24 @@ class TagsView(QTreeView):
|
||||
self.setCursor(Qt.PointingHandCursor)
|
||||
self.setIconSize(QSize(30, 30))
|
||||
|
||||
def set_database(self, db, match_all):
|
||||
def set_database(self, db, match_all, popularity):
|
||||
self._model = TagsModel(db)
|
||||
self.popularity = popularity
|
||||
self.match_all = match_all
|
||||
self.setModel(self._model)
|
||||
self.connect(self, SIGNAL('clicked(QModelIndex)'), self.toggle)
|
||||
self.popularity.setChecked(config['sort_by_popularity'])
|
||||
self.connect(self.popularity, SIGNAL('stateChanged(int)'), self.sort_changed)
|
||||
|
||||
def sort_changed(self, state):
|
||||
config.set('sort_by_popularity', state == Qt.Checked)
|
||||
self.model().refresh()
|
||||
|
||||
def toggle(self, index):
|
||||
if self._model.toggle(index):
|
||||
self.emit(SIGNAL('tags_marked(PyQt_PyObject, PyQt_PyObject)'),
|
||||
self._model.tokens(), self.match_all.isChecked())
|
||||
|
||||
class Tag(unicode):
|
||||
|
||||
def __init__(self, name):
|
||||
unicode.__init__(self, name)
|
||||
self.state = 0
|
||||
|
||||
class TagsModel(QAbstractItemModel):
|
||||
|
||||
categories = [_('Authors'), _('Series'), _('Formats'), _('Publishers'), _('Tags')]
|
||||
@ -61,9 +62,9 @@ class TagsModel(QAbstractItemModel):
|
||||
|
||||
def refresh(self):
|
||||
old_data = self._data
|
||||
self._data = self.db.get_categories()
|
||||
self._data = self.db.get_categories(config['sort_by_popularity'])
|
||||
for key in self._data:
|
||||
self._data[key] = list(map(Tag, self._data[key]))
|
||||
self._data[key] = self._data[key]
|
||||
for key in old_data.keys():
|
||||
for tag in old_data[key]:
|
||||
try:
|
||||
@ -152,7 +153,7 @@ class TagsModel(QAbstractItemModel):
|
||||
def tag_data(self, index, role):
|
||||
category = self.row_map[index.parent().row()]
|
||||
if role == Qt.DisplayRole:
|
||||
return QVariant(self._data[category][index.row()])
|
||||
return QVariant(self._data[category][index.row()].as_string())
|
||||
if role == Qt.DecorationRole:
|
||||
return self.status_map[self._data[category][index.row()].state]
|
||||
return NONE
|
||||
|
@ -326,6 +326,16 @@ class ResultCache(object):
|
||||
ans = (no_tags + ans) if order == 'ASC' else (ans + no_tags)
|
||||
return ans
|
||||
|
||||
class Tag(unicode):
|
||||
|
||||
def __init__(self, name):
|
||||
unicode.__init__(self, name)
|
||||
self.count = 0
|
||||
self.state = 0
|
||||
|
||||
def as_string(self):
|
||||
return u'[%d] %s'%(self.count, self)
|
||||
|
||||
class LibraryDatabase2(LibraryDatabase):
|
||||
'''
|
||||
An ebook metadata database that stores references to ebook files on disk.
|
||||
@ -683,7 +693,7 @@ class LibraryDatabase2(LibraryDatabase):
|
||||
self.conn.execute(st%dict(ltable='series', table='series', ltable_col='series'))
|
||||
self.conn.commit()
|
||||
|
||||
def get_categories(self):
|
||||
def get_categories(self, sort_on_count=False):
|
||||
categories = {}
|
||||
def get(name, category, field='name'):
|
||||
ans = self.conn.execute('SELECT DISTINCT %s FROM %s'%(field, name)).fetchall()
|
||||
@ -691,9 +701,23 @@ class LibraryDatabase2(LibraryDatabase):
|
||||
try:
|
||||
ans.remove('')
|
||||
except ValueError: pass
|
||||
ans.sort()
|
||||
categories[category] = ans
|
||||
for x in (('authors', 'author'), ('tags', 'tag'), ('publishers', 'publisher'), ('series', 'series')):
|
||||
categories[category] = list(map(Tag, ans))
|
||||
tags = categories[category]
|
||||
if name != 'data':
|
||||
for tag in tags:
|
||||
id = self.conn.execute('SELECT id FROM %s WHERE %s=?'%(name, field), (tag,)).fetchone()
|
||||
if id:
|
||||
id = id[0]
|
||||
tag.id = id
|
||||
for tag in tags:
|
||||
if tag.id is not None:
|
||||
tag.count = self.conn.execute('SELECT COUNT(id) FROM books_%s_link WHERE %s=?'%(name, category), (tag.id,)).fetchone()[0]
|
||||
else:
|
||||
for tag in tags:
|
||||
tag.count = self.conn.execute('SELECT COUNT(format) FROM data WHERE format=?', (tag,)).fetchone()[0]
|
||||
tags.sort(reverse=sort_on_count, cmp=(lambda x,y:cmp(x.count,y.count)) if sort_on_count else cmp)
|
||||
for x in (('authors', 'author'), ('tags', 'tag'), ('publishers', 'publisher'),
|
||||
('series', 'series')):
|
||||
get(*x)
|
||||
get('data', 'format', 'format')
|
||||
return categories
|
||||
|
Loading…
x
Reference in New Issue
Block a user