Manage tags/authors/etc dialogs: Allow searching and filtering the list of items. Fixes #1879134 [[Enhancement] Add filters to all the Category editor (Authors, Series, Publishers and Tags)](https://bugs.launchpad.net/calibre/+bug/1879134)

Merge branch 'master' of https://github.com/cbhaley/calibre
This commit is contained in:
Kovid Goyal 2020-05-17 23:13:28 +05:30
commit a74ed3ae64
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
4 changed files with 308 additions and 146 deletions

View File

@ -7,14 +7,17 @@ __license__ = 'GPL v3'
from PyQt5.Qt import (Qt, QDialog, QTableWidgetItem, QAbstractItemView, QIcon, from PyQt5.Qt import (Qt, QDialog, QTableWidgetItem, QAbstractItemView, QIcon,
QDialogButtonBox, QFrame, QLabel, QTimer, QMenu, QApplication, QDialogButtonBox, QFrame, QLabel, QTimer, QMenu, QApplication,
QByteArray, QItemDelegate) QByteArray, QItemDelegate, QAction)
from calibre.ebooks.metadata import author_to_author_sort, string_to_authors from calibre.ebooks.metadata import author_to_author_sort, string_to_authors
from calibre.gui2 import error_dialog, gprefs from calibre.gui2 import error_dialog, gprefs
from calibre.gui2.dialogs.edit_authors_dialog_ui import Ui_EditAuthorsDialog from calibre.gui2.dialogs.edit_authors_dialog_ui import Ui_EditAuthorsDialog
from calibre.utils.icu import sort_key from calibre.utils.config import prefs
from calibre.utils.icu import sort_key, primary_contains, contains
from polyglot.builtins import unicode_type from polyglot.builtins import unicode_type
QT_HIDDEN_CLEAR_ACTION = '_q_qlineeditclearaction'
class tableItem(QTableWidgetItem): class tableItem(QTableWidgetItem):
@ -92,23 +95,33 @@ class EditAuthorsDialog(QDialog, Ui_EditAuthorsDialog):
hh.sectionClicked.connect(self.do_sort) hh.sectionClicked.connect(self.do_sort)
hh.setSortIndicatorShown(True) hh.setSortIndicatorShown(True)
# set up the search box # set up the search & filter boxes
self.find_box.initialize('manage_authors_search') self.find_box.initialize('manage_authors_search')
self.find_box.lineEdit().returnPressed.connect(self.do_find) le = self.find_box.lineEdit()
ac = le.findChild(QAction, QT_HIDDEN_CLEAR_ACTION)
if ac is not None:
ac.triggered.connect(self.clear_find)
le.returnPressed.connect(self.do_find)
self.find_box.editTextChanged.connect(self.find_text_changed) self.find_box.editTextChanged.connect(self.find_text_changed)
self.find_button.clicked.connect(self.do_find) self.find_button.clicked.connect(self.do_find)
self.find_button.setDefault(True) self.find_button.setDefault(True)
l = QLabel(self.table) self.filter_box.initialize('manage_authors_filter')
self.not_found_label = l le = self.filter_box.lineEdit()
ac = le.findChild(QAction, QT_HIDDEN_CLEAR_ACTION)
if ac is not None:
ac.triggered.connect(self.clear_filter)
self.filter_box.lineEdit().returnPressed.connect(self.do_filter)
self.filter_button.clicked.connect(self.do_filter)
self.not_found_label = l = QLabel(self.table)
l.setFrameStyle(QFrame.StyledPanel) l.setFrameStyle(QFrame.StyledPanel)
l.setAutoFillBackground(True) l.setAutoFillBackground(True)
l.setText(_('No matches found')) l.setText(_('No matches found'))
l.setAlignment(Qt.AlignVCenter) l.setAlignment(Qt.AlignVCenter)
l.resize(l.sizeHint()) l.resize(l.sizeHint())
l.move(10,20) l.move(10, 2)
l.setVisible(False) l.setVisible(False)
self.not_found_label.move(40, 40)
self.not_found_label_timer = QTimer() self.not_found_label_timer = QTimer()
self.not_found_label_timer.setSingleShot(True) self.not_found_label_timer.setSingleShot(True)
self.not_found_label_timer.timeout.connect( self.not_found_label_timer.timeout.connect(
@ -131,6 +144,11 @@ class EditAuthorsDialog(QDialog, Ui_EditAuthorsDialog):
'link': v['link']} 'link': v['link']}
self.edited_icon = QIcon(I('modified.png')) self.edited_icon = QIcon(I('modified.png'))
if prefs['use_primary_find_in_search']:
self.string_contains = primary_contains
else:
self.string_contains = contains
self.last_sorted_by = 'sort' self.last_sorted_by = 'sort'
self.author_order = 1 self.author_order = 1
self.author_sort_order = 0 self.author_sort_order = 0
@ -140,9 +158,19 @@ class EditAuthorsDialog(QDialog, Ui_EditAuthorsDialog):
def use_vl_changed(self, x): def use_vl_changed(self, x):
self.show_table(None, None, None) self.show_table(None, None, None)
def clear_filter(self):
self.filter_box.setText('')
self.show_table(None, None, None)
def do_filter(self):
self.show_table(None, None, None)
def show_table(self, id_to_select, select_sort, select_link): def show_table(self, id_to_select, select_sort, select_link):
auts_to_show = [t[0] for t in filter_text = icu_lower(unicode_type(self.filter_box.text()))
self.find_aut_func(use_virtual_library=self.apply_vl_checkbox.isChecked())] auts_to_show = []
for t in self.find_aut_func(use_virtual_library=self.apply_vl_checkbox.isChecked()):
if self.string_contains(filter_text, icu_lower(t[1])):
auts_to_show.append(t[0])
self.table.blockSignals(True) self.table.blockSignals(True)
self.table.clear() self.table.clear()
self.table.setColumnCount(3) self.table.setColumnCount(3)
@ -184,13 +212,13 @@ class EditAuthorsDialog(QDialog, Ui_EditAuthorsDialog):
self.table.setHorizontalHeaderLabels([_('Author'), _('Author sort'), _('Link')]) self.table.setHorizontalHeaderLabels([_('Author'), _('Author sort'), _('Link')])
if self.last_sorted_by == 'sort': if self.last_sorted_by == 'sort':
self.author_sort_order = 1 if self.author_sort_order == 0 else 0 self.author_sort_order = 1 - self.author_sort_order
self.do_sort_by_author_sort() self.do_sort_by_author_sort()
elif self.last_sorted_by == 'author': elif self.last_sorted_by == 'author':
self.author_order = 1 if self.author_order == 0 else 0 self.author_order = 1 - self.author_order
self.do_sort_by_author() self.do_sort_by_author()
else: else:
self.link_order = 1 if self.link_order == 0 else 0 self.link_order = 1 - self.link_order
self.do_sort_by_link() self.do_sort_by_link()
# Position on the desired item # Position on the desired item
@ -308,6 +336,11 @@ class EditAuthorsDialog(QDialog, Ui_EditAuthorsDialog):
def not_found_label_timer_event(self): def not_found_label_timer_event(self):
self.not_found_label.setVisible(False) self.not_found_label.setVisible(False)
def clear_find(self):
self.find_box.setText('')
self.start_find_pos = -1
self.do_find()
def find_text_changed(self): def find_text_changed(self):
self.start_find_pos = -1 self.start_find_pos = -1
@ -319,9 +352,11 @@ class EditAuthorsDialog(QDialog, Ui_EditAuthorsDialog):
self.buttonBox.button(QDialogButtonBox.Ok).setAutoDefault(False) self.buttonBox.button(QDialogButtonBox.Ok).setAutoDefault(False)
self.buttonBox.button(QDialogButtonBox.Cancel).setDefault(False) self.buttonBox.button(QDialogButtonBox.Cancel).setDefault(False)
self.buttonBox.button(QDialogButtonBox.Cancel).setAutoDefault(False) self.buttonBox.button(QDialogButtonBox.Cancel).setAutoDefault(False)
st = icu_lower(unicode_type(self.find_box.currentText()))
for i in range(0, self.table.rowCount()*2): st = icu_lower(unicode_type(self.find_box.currentText()))
if not st:
return
for _ in range(0, self.table.rowCount()*2):
self.start_find_pos = (self.start_find_pos + 1) % (self.table.rowCount()*2) self.start_find_pos = (self.start_find_pos + 1) % (self.table.rowCount()*2)
r = (self.start_find_pos//2) % self.table.rowCount() r = (self.start_find_pos//2) % self.table.rowCount()
c = self.start_find_pos % 2 c = self.start_find_pos % 2
@ -405,8 +440,8 @@ class EditAuthorsDialog(QDialog, Ui_EditAuthorsDialog):
item = self.table.item(row, col) item = self.table.item(row, col)
item.setIcon(self.edited_icon) item.setIcon(self.edited_icon)
if col == 1: if col == 1:
self.authors[id_]['sort'] = item.text() self.authors[id_]['sort'] = unicode_type(item.text())
else: else:
self.authors[id_]['link'] = item.text() self.authors[id_]['link'] = unicode_type(item.text())
self.table.setCurrentItem(item) self.table.setCurrentItem(item)
self.table.scrollToItem(item) self.table.scrollToItem(item)

View File

@ -21,8 +21,8 @@
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout"> <layout class="QVBoxLayout" name="verticalLayout">
<item > <item >
<layout class="QHBoxLayout" name=""> <layout class="QGridLayout" name="">
<item> <item row="0" column="0">
<widget class="QLabel"> <widget class="QLabel">
<property name="text"> <property name="text">
<string>&amp;Search for:</string> <string>&amp;Search for:</string>
@ -32,7 +32,7 @@
</property> </property>
</widget> </widget>
</item> </item>
<item> <item row="0" column="1">
<widget class="HistoryLineEdit" name="find_box"> <widget class="HistoryLineEdit" name="find_box">
<property name="minimumSize"> <property name="minimumSize">
<size> <size>
@ -40,16 +40,19 @@
<height>0</height> <height>0</height>
</size> </size>
</property> </property>
</widget> <property name="clearButtonEnabled">
</item> <bool>true</bool>
<item>
<widget class="QPushButton" name="find_button">
<property name="text">
<string>F&amp;ind</string>
</property> </property>
</widget> </widget>
</item> </item>
<item> <item row="0" column="2">
<widget class="QPushButton" name="find_button">
<property name="text">
<string>S&amp;earch</string>
</property>
</widget>
</item>
<item row="0" column="3">
<spacer> <spacer>
<property name="orientation"> <property name="orientation">
<enum>Qt::Horizontal</enum> <enum>Qt::Horizontal</enum>
@ -62,15 +65,49 @@
</property> </property>
</spacer> </spacer>
</item> </item>
<item> <item row="0" column="4">
<widget class="QCheckBox" name="apply_vl_checkbox"> <widget class="QCheckBox" name="apply_vl_checkbox">
<property name="toolTip"> <property name="toolTip">
<string>&lt;p&gt;Show authors only if they appear in the <string>&lt;p&gt;Only show authors in the
current Virtual library. Edits already done may be hidden but will current Virtual library. Edits already done may be hidden but will
not be forgotten.&lt;/p&gt;</string> not be forgotten.&lt;/p&gt;</string>
</property> </property>
<property name="text"> <property name="text">
<string>&amp;Show only available items in current Virtual library</string> <string>Only show authors in the current &amp;virtual library</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel">
<property name="text">
<string>Filter &amp;By:</string>
</property>
<property name="buddy">
<cstring>filter_box</cstring>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="HistoryLineEdit" name="filter_box">
<property name="minimumSize">
<size>
<width>200</width>
<height>0</height>
</size>
</property>
<property name="toolTip">
<string>&lt;p&gt;Only show authors that contain the text in this box.
The match ignores case.&lt;/p&gt;</string>
</property>
<property name="clearButtonEnabled">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QPushButton" name="filter_button">
<property name="text">
<string>Fi&amp;lter</string>
</property> </property>
</widget> </widget>
</item> </item>

View File

@ -5,16 +5,19 @@ from __future__ import absolute_import, division, print_function, unicode_litera
from PyQt5.Qt import (Qt, QDialog, QTableWidgetItem, QIcon, QByteArray, QSize, from PyQt5.Qt import (Qt, QDialog, QTableWidgetItem, QIcon, QByteArray, QSize,
QDialogButtonBox, QTableWidget, QItemDelegate, QApplication, QDialogButtonBox, QTableWidget, QItemDelegate, QApplication,
pyqtSignal) pyqtSignal, QAction, QFrame, QLabel, QTimer)
from calibre.gui2.dialogs.tag_list_editor_ui import Ui_TagListEditor from calibre.gui2.dialogs.tag_list_editor_ui import Ui_TagListEditor
from calibre.gui2.complete2 import EditWithComplete from calibre.gui2.complete2 import EditWithComplete
from calibre.gui2.dialogs.confirm_delete import confirm from calibre.gui2.dialogs.confirm_delete import confirm
from calibre.gui2.widgets import EnLineEdit from calibre.gui2.widgets import EnLineEdit
from calibre.gui2 import question_dialog, error_dialog, gprefs from calibre.gui2 import question_dialog, error_dialog, gprefs
from calibre.utils.icu import sort_key from calibre.utils.config import prefs
from calibre.utils.icu import sort_key, contains, primary_contains
from polyglot.builtins import unicode_type from polyglot.builtins import unicode_type
QT_HIDDEN_CLEAR_ACTION = '_q_qlineeditclearaction'
class NameTableWidgetItem(QTableWidgetItem): class NameTableWidgetItem(QTableWidgetItem):
@ -137,6 +140,7 @@ class TagListEditor(QDialog, Ui_TagListEditor):
# Put the category name into the title bar # Put the category name into the title bar
t = self.windowTitle() t = self.windowTitle()
self.category_name = cat_name
self.setWindowTitle(t + ' (' + cat_name + ')') self.setWindowTitle(t + ' (' + cat_name + ')')
# Remove help icon on title bar # Remove help icon on title bar
icon = self.windowIcon() icon = self.windowIcon()
@ -161,16 +165,14 @@ class TagListEditor(QDialog, Ui_TagListEditor):
self.get_book_ids = get_book_ids self.get_book_ids = get_book_ids
self.text_before_editing = '' self.text_before_editing = ''
# Set up the column headings
self.down_arrow_icon = QIcon(I('arrow-down.png'))
self.up_arrow_icon = QIcon(I('arrow-up.png'))
self.blank_icon = QIcon(I('blank.png'))
# Capture clicks on the horizontal header to sort the table columns # Capture clicks on the horizontal header to sort the table columns
hh = self.table.horizontalHeader() hh = self.table.horizontalHeader()
hh.setSectionsClickable(True)
hh.sectionClicked.connect(self.header_clicked)
hh.sectionResized.connect(self.table_column_resized) hh.sectionResized.connect(self.table_column_resized)
hh.setSectionsClickable(True)
hh.sectionClicked.connect(self.do_sort)
hh.setSortIndicatorShown(True)
self.last_sorted_by = 'name'
self.name_order = 0 self.name_order = 0
self.count_order = 1 self.count_order = 1
self.was_order = 1 self.was_order = 1
@ -180,12 +182,10 @@ class TagListEditor(QDialog, Ui_TagListEditor):
self.edit_delegate.editing_started.connect(self.start_editing) self.edit_delegate.editing_started.connect(self.start_editing)
self.table.setItemDelegateForColumn(0, self.edit_delegate) self.table.setItemDelegateForColumn(0, self.edit_delegate)
# Add the data if prefs['use_primary_find_in_search']:
select_item = self.fill_in_table(None, tag_to_match) self.string_contains = primary_contains
else:
# Scroll to the selected item if there is one self.string_contains = contains
if select_item is not None:
self.table.setCurrentItem(select_item)
self.delete_button.clicked.connect(self.delete_tags) self.delete_button.clicked.connect(self.delete_tags)
self.rename_button.clicked.connect(self.rename_tag) self.rename_button.clicked.connect(self.rename_tag)
@ -198,8 +198,35 @@ class TagListEditor(QDialog, Ui_TagListEditor):
self.buttonBox.accepted.connect(self.accepted) self.buttonBox.accepted.connect(self.accepted)
self.search_box.initialize('tag_list_search_box_' + cat_name) self.search_box.initialize('tag_list_search_box_' + cat_name)
self.search_button.clicked.connect(self.all_matching_clicked) le = self.search_box.lineEdit()
ac = le.findChild(QAction, QT_HIDDEN_CLEAR_ACTION)
if ac is not None:
ac.triggered.connect(self.clear_search)
le.returnPressed.connect(self.do_search)
self.search_box.textChanged.connect(self.search_text_changed)
self.search_button.clicked.connect(self.do_search)
self.search_button.setDefault(True) self.search_button.setDefault(True)
l = QLabel(self.table)
self.not_found_label = l
l.setFrameStyle(QFrame.StyledPanel)
l.setAutoFillBackground(True)
l.setText(_('No matches found'))
l.setAlignment(Qt.AlignVCenter)
l.resize(l.sizeHint())
l.move(10, 0)
l.setVisible(False)
self.not_found_label_timer = QTimer()
self.not_found_label_timer.setSingleShot(True)
self.not_found_label_timer.timeout.connect(
self.not_found_label_timer_event, type=Qt.QueuedConnection)
self.filter_box.initialize('tag_list_filter_box_' + cat_name)
le = self.filter_box.lineEdit()
ac = le.findChild(QAction, QT_HIDDEN_CLEAR_ACTION)
if ac is not None:
ac.triggered.connect(self.clear_filter)
le.returnPressed.connect(self.do_filter)
self.filter_button.clicked.connect(self.do_filter)
self.apply_vl_checkbox.clicked.connect(self.vl_box_changed) self.apply_vl_checkbox.clicked.connect(self.vl_box_changed)
@ -213,14 +240,43 @@ class TagListEditor(QDialog, Ui_TagListEditor):
self.resize(self.sizeHint()+QSize(150, 100)) self.resize(self.sizeHint()+QSize(150, 100))
except: except:
pass pass
# Add the data
self.search_item_row = -1
self.fill_in_table(None, tag_to_match)
def vl_box_changed(self): def vl_box_changed(self):
self.search_item_row = -1
self.fill_in_table(None, None) self.fill_in_table(None, None)
def do_search(self):
self.not_found_label.setVisible(False)
find_text = icu_lower(unicode_type(self.search_box.currentText()))
if not find_text:
return
for _ in range(0, self.table.rowCount()):
r = self.search_item_row = (self.search_item_row + 1) % self.table.rowCount()
if self.string_contains(find_text,
self.all_tags[self.ordered_tags[r]]['cur_name']):
self.table.setCurrentItem(self.table.item(r, 0))
self.table.setFocus(True)
return
# Nothing found. Pop up the little dialog for 1.5 seconds
self.not_found_label.setVisible(True)
self.not_found_label_timer.start(1500)
def search_text_changed(self):
self.search_item_row = -1
def clear_search(self):
self.search_item_row = -1
self.search_box.setText('')
def fill_in_table(self, tags, tag_to_match): def fill_in_table(self, tags, tag_to_match):
data = self.get_book_ids(self.apply_vl_checkbox.isChecked()) data = self.get_book_ids(self.apply_vl_checkbox.isChecked())
self.all_tags = {} self.all_tags = {}
filter_text = icu_lower(unicode_type(self.filter_box.text()))
for k,v,count in data: for k,v,count in data:
if not filter_text or self.string_contains(filter_text, icu_lower(v)):
self.all_tags[v] = {'key': k, 'count': count, 'cur_name': v, self.all_tags[v] = {'key': k, 'count': count, 'cur_name': v,
'is_deleted': k in self.to_delete} 'is_deleted': k in self.to_delete}
self.original_names[k] = v self.original_names[k] = v
@ -234,18 +290,14 @@ class TagListEditor(QDialog, Ui_TagListEditor):
self.table.blockSignals(True) self.table.blockSignals(True)
self.table.clear() self.table.clear()
self.table.setColumnCount(3) self.table.setColumnCount(3)
self.name_col = QTableWidgetItem(_('Tag')) self.name_col = QTableWidgetItem(self.category_name)
self.table.setHorizontalHeaderItem(0, self.name_col) self.table.setHorizontalHeaderItem(0, self.name_col)
self.name_col.setIcon(self.up_arrow_icon)
self.count_col = QTableWidgetItem(_('Count')) self.count_col = QTableWidgetItem(_('Count'))
self.table.setHorizontalHeaderItem(1, self.count_col) self.table.setHorizontalHeaderItem(1, self.count_col)
self.count_col.setIcon(self.blank_icon)
self.was_col = QTableWidgetItem(_('Was')) self.was_col = QTableWidgetItem(_('Was'))
self.table.setHorizontalHeaderItem(2, self.was_col) self.table.setHorizontalHeaderItem(2, self.was_col)
self.count_col.setIcon(self.blank_icon)
self.table.setRowCount(len(tags)) self.table.setRowCount(len(tags))
for row,tag in enumerate(tags): for row,tag in enumerate(tags):
item = NameTableWidgetItem() item = NameTableWidgetItem()
item.set_is_deleted(self.all_tags[tag]['is_deleted']) item.set_is_deleted(self.all_tags[tag]['is_deleted'])
@ -260,7 +312,6 @@ class TagListEditor(QDialog, Ui_TagListEditor):
self.table.setItem(row, 0, item) self.table.setItem(row, 0, item)
if tag == tag_to_match: if tag == tag_to_match:
select_item = item select_item = item
item = CountTableWidgetItem(self.all_tags[tag]['count']) item = CountTableWidgetItem(self.all_tags[tag]['count'])
# only the name column can be selected # only the name column can be selected
item.setFlags(item.flags() & ~(Qt.ItemIsSelectable|Qt.ItemIsEditable)) item.setFlags(item.flags() & ~(Qt.ItemIsSelectable|Qt.ItemIsEditable))
@ -271,27 +322,31 @@ class TagListEditor(QDialog, Ui_TagListEditor):
if _id in self.to_rename or _id in self.to_delete: if _id in self.to_rename or _id in self.to_delete:
item.setData(Qt.DisplayRole, tag) item.setData(Qt.DisplayRole, tag)
self.table.setItem(row, 2, item) self.table.setItem(row, 2, item)
self.table.blockSignals(False)
return select_item
def all_matching_clicked(self): if self.last_sorted_by == 'name':
for i in range(0, self.table.rowCount()): self.table.sortByColumn(0, self.name_order)
item = self.table.item(i, 0) elif self.last_sorted_by == 'count':
tag = item.initial_text() self.table.sortByColumn(1, self.count_order)
self.all_tags[tag]['cur_name'] = item.text() else:
self.all_tags[tag]['is_deleted'] = item.is_deleted self.table.sortByColumn(2, self.was_order)
search_for = icu_lower(unicode_type(self.search_box.text()))
if len(search_for) == 0: if select_item is not None:
self.table.setCurrentItem(select_item)
self.start_find_pos = select_item.row()
else:
self.table.setCurrentCell(0, 0)
self.start_find_pos = -1
self.table.blockSignals(False)
def not_found_label_timer_event(self):
self.not_found_label.setVisible(False)
def clear_filter(self):
self.filter_box.setText('')
self.fill_in_table(None, None)
def do_filter(self):
self.fill_in_table(None, None) self.fill_in_table(None, None)
result = []
for k in self.ordered_tags:
tag = self.all_tags[k]
if (
search_for in icu_lower(unicode_type(tag['cur_name'])) or
search_for in icu_lower(unicode_type(self.original_names.get(tag['key'], '')))
):
result.append(k)
self.fill_in_table(result, None)
def table_column_resized(self, col, old, new): def table_column_resized(self, col, old, new):
self.table_column_widths = [] self.table_column_widths = []
@ -445,37 +500,23 @@ class TagListEditor(QDialog, Ui_TagListEditor):
if row >= 0: if row >= 0:
self.table.scrollToItem(self.table.item(row, 0)) self.table.scrollToItem(self.table.item(row, 0))
def header_clicked(self, idx): def do_sort(self, section):
if idx == 0: (self.do_sort_by_name, self.do_sort_by_count, self.do_sort_by_was)[section]()
self.do_sort_by_name()
elif idx == 1:
self.do_sort_by_count()
else:
self.do_sort_by_was()
def do_sort_by_name(self): def do_sort_by_name(self):
self.name_order = 1 if self.name_order == 0 else 0 self.name_order = 1 - self.name_order
self.last_sorted_by = 'name'
self.table.sortByColumn(0, self.name_order) self.table.sortByColumn(0, self.name_order)
self.name_col.setIcon(self.down_arrow_icon if self.name_order
else self.up_arrow_icon)
self.count_col.setIcon(self.blank_icon)
self.was_col.setIcon(self.blank_icon)
def do_sort_by_count(self): def do_sort_by_count(self):
self.count_order = 1 if self.count_order == 0 else 0 self.count_order = 1 - self.count_order
self.last_sorted_by = 'count'
self.table.sortByColumn(1, self.count_order) self.table.sortByColumn(1, self.count_order)
self.count_col.setIcon(self.down_arrow_icon if self.count_order
else self.up_arrow_icon)
self.name_col.setIcon(self.blank_icon)
self.was_col.setIcon(self.blank_icon)
def do_sort_by_was(self): def do_sort_by_was(self):
self.was_order = 1 if self.was_order == 0 else 0 self.was_order = 1 - self.was_order
self.last_sorted_by = 'count'
self.table.sortByColumn(2, self.was_order) self.table.sortByColumn(2, self.was_order)
self.was_col.setIcon(self.down_arrow_icon if self.was_order
else self.up_arrow_icon)
self.name_col.setIcon(self.blank_icon)
self.count_col.setIcon(self.blank_icon)
def accepted(self): def accepted(self):
self.save_geometry() self.save_geometry()

View File

@ -18,9 +18,7 @@
<normaloff>:/images/chapters.png</normaloff>:/images/chapters.png</iconset> <normaloff>:/images/chapters.png</normaloff>:/images/chapters.png</iconset>
</property> </property>
<layout class="QGridLayout"> <layout class="QGridLayout">
<item row="0" column="0" colspan="2"> <item row="0" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_11">
<item>
<widget class="QLabel" name="label"> <widget class="QLabel" name="label">
<property name="text"> <property name="text">
<string>&amp;Search for:</string> <string>&amp;Search for:</string>
@ -30,29 +28,29 @@
</property> </property>
</widget> </widget>
</item> </item>
<item> <item row="0" column="1">
<widget class="HistoryLineEdit" name="search_box"> <widget class="HistoryLineEdit" name="search_box">
<property name="sizePolicy"> <property name="minimumSize">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed"> <size>
<horstretch>100</horstretch> <width>200</width>
<verstretch>0</verstretch> <height>0</height>
</sizepolicy> </size>
</property> </property>
<property name="toolTip"> <property name="toolTip">
<string>Search for an item in the Tag column</string> <string>Search for an item in the first column</string>
</property> </property>
<property name="clearButtonEnabled"> <property name="clearButtonEnabled">
<bool>true</bool> <bool>true</bool>
</property> </property>
</widget> </widget>
</item> </item>
<item> <item row="0" column="2">
<widget class="QPushButton" name="search_button"> <widget class="QPushButton" name="search_button">
<property name="toolTip"> <property name="toolTip">
<string>Display items containing the search string</string> <string>Find items containing the search string</string>
</property> </property>
<property name="text"> <property name="text">
<string>&amp;Find</string> <string>S&amp;earch</string>
</property> </property>
<property name="icon"> <property name="icon">
<iconset resource="../../../../resources/images.qrc"> <iconset resource="../../../../resources/images.qrc">
@ -60,9 +58,20 @@
</property> </property>
</widget> </widget>
</item> </item>
</layout> <item row="0" column="3">
<spacer>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item> </item>
<item row="1" column="0" colspan="3"> <item row="0" column="4">
<widget class="QCheckBox" name="apply_vl_checkbox"> <widget class="QCheckBox" name="apply_vl_checkbox">
<property name="toolTip"> <property name="toolTip">
<string>&lt;p&gt;Show items only if they appear in the <string>&lt;p&gt;Show items only if they appear in the
@ -70,7 +79,47 @@
not be forgotten.&lt;/p&gt;</string> not be forgotten.&lt;/p&gt;</string>
</property> </property>
<property name="text"> <property name="text">
<string>&amp;Show only available items in current Virtual library</string> <string>Only show items in the current &amp;virtual library</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>&amp;Filter by:</string>
</property>
<property name="buddy">
<cstring>filter_box</cstring>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="HistoryLineEdit" name="filter_box">
<property name="minimumSize">
<size>
<width>200</width>
<height>0</height>
</size>
</property>
<property name="toolTip">
<string>Filter items using the text in this box</string>
</property>
<property name="clearButtonEnabled">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QPushButton" name="filter_button">
<property name="toolTip">
<string>Show only items containing this text</string>
</property>
<property name="text">
<string>F&amp;ilter</string>
</property>
<property name="icon">
<iconset resource="../../../../resources/images.qrc">
<normaloff>:/images/search.png</normaloff>:/images/search.png</iconset>
</property> </property>
</widget> </widget>
</item> </item>
@ -147,7 +196,7 @@
</item> </item>
</layout> </layout>
</item> </item>
<item row="2" column="1"> <item row="2" column="1" colspan="4">
<widget class="QTableWidget" name="table"> <widget class="QTableWidget" name="table">
<property name="alternatingRowColors"> <property name="alternatingRowColors">
<bool>true</bool> <bool>true</bool>
@ -160,7 +209,7 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="3" column="0" colspan="2"> <item row="3" column="0" colspan="5">
<widget class="QDialogButtonBox" name="buttonBox"> <widget class="QDialogButtonBox" name="buttonBox">
<property name="standardButtons"> <property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>