Add 'Search "not in"' and 'Filter "not in'" buttons to Manage authors and Manage Items. Also clean up tooltips to use consistent language.

This commit is contained in:
Charles Haley 2025-06-24 13:55:11 +01:00
parent 42fb76fef7
commit fcdb50df3a
4 changed files with 100 additions and 22 deletions

View File

@ -185,8 +185,9 @@ class EditAuthorsDialog(QDialog, Ui_EditAuthorsDialog):
ac.triggered.connect(self.clear_find)
le.returnPressed.connect(self.do_find)
self.find_box.editTextChanged.connect(self.find_text_changed)
self.find_button.clicked.connect(self.do_find)
self.find_button.clicked.connect(partial(self.do_find, inverted=False))
self.find_button.setDefault(True)
self.find_inverted_button.clicked.connect(partial(self.do_find, inverted=True))
self.filter_box.initialize('manage_authors_filter')
le = self.filter_box.lineEdit()
@ -194,7 +195,8 @@ class EditAuthorsDialog(QDialog, Ui_EditAuthorsDialog):
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.filter_button.clicked.connect(partial(self.do_filter, inverted=False))
self.filter_inverted_button.clicked.connect(partial(self.do_filter, inverted=True))
self.not_found_label = l = QLabel(self.table)
l.setFrameStyle(QFrame.Shape.StyledPanel)
@ -212,6 +214,8 @@ class EditAuthorsDialog(QDialog, Ui_EditAuthorsDialog):
self.table.setContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu)
self.table.customContextMenuRequested.connect(self.show_context_menu)
self.inverted_filter = False
# Fetch the data
self.authors = {}
self.original_authors = {}
@ -274,7 +278,8 @@ class EditAuthorsDialog(QDialog, Ui_EditAuthorsDialog):
self.filter_box.setText('')
self.show_table(None, None, None, False)
def do_filter(self):
def do_filter(self, inverted):
self.inverted_filter = inverted
self.show_table(None, None, None, False)
def show_table(self, id_to_select, select_sort, select_link, is_first_letter):
@ -282,7 +287,8 @@ class EditAuthorsDialog(QDialog, Ui_EditAuthorsDialog):
filter_text = icu_lower(str(self.filter_box.text()))
if filter_text:
auts_to_show = {id_ for id_ in auts_to_show
if self.string_contains(filter_text, icu_lower(self.authors[id_]['name']))}
if self.string_contains(filter_text,
icu_lower(self.authors[id_]['name'])) != self.inverted_filter}
self.table.blockSignals(True)
self.table.clear()
@ -530,7 +536,7 @@ class EditAuthorsDialog(QDialog, Ui_EditAuthorsDialog):
def find_text_changed(self):
self.start_find_pos = -1
def do_find(self):
def do_find(self, inverted=False):
self.not_found_label.setVisible(False)
# For some reason the button box keeps stealing the RETURN shortcut.
# Steal it back
@ -548,7 +554,7 @@ class EditAuthorsDialog(QDialog, Ui_EditAuthorsDialog):
c = self.start_find_pos % 2
item = self.table.item(r, c)
text = icu_lower(str(item.text()))
if st in text:
if (st in text) != inverted:
self.table.setCurrentItem(item)
self.table.setFocus(Qt.FocusReason.OtherFocusReason)
return

View File

@ -37,10 +37,9 @@
</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>
<string>Filter names in the Authors column using the text in this box. The search ignores case.</string>
</property>
<property name="clearButtonEnabled" stdset="0">
<property name="clearButtonEnabled">
<bool>true</bool>
</property>
</widget>
@ -63,13 +62,16 @@
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>Search for names in the Authors column using the text in this box. The search ignores case.</string>
</property>
<property name="minimumSize">
<size>
<width>200</width>
<height>0</height>
</size>
</property>
<property name="clearButtonEnabled" stdset="0">
<property name="clearButtonEnabled">
<bool>true</bool>
</property>
</widget>
@ -89,6 +91,19 @@
<property name="text">
<string>Fi&amp;lter</string>
</property>
<property name="toolTip">
<string>Show all authors containing the filter text</string>
</property>
</widget>
</item>
<item row="1" column="3">
<widget class="QPushButton" name="filter_inverted_button">
<property name="text">
<string>Filter "not in"</string>
</property>
<property name="toolTip">
<string>Show all authors that do not contain the filter text</string>
</property>
</widget>
</item>
<item row="0" column="2">
@ -96,9 +111,22 @@
<property name="text">
<string>S&amp;earch</string>
</property>
<property name="toolTip">
<string>Search for authors containing the search text</string>
</property>
</widget>
</item>
<item row="0" column="3" rowspan="2">
<item row="0" column="3">
<widget class="QPushButton" name="find_inverted_button">
<property name="text">
<string>Search "not in"</string>
</property>
<property name="toolTip">
<string>Search for authors that do not contain the search text</string>
</property>
</widget>
</item>
<item row="0" column="4" rowspan="2">
<layout class="QVBoxLayout" name="show_button_layout">
<item>
<widget class="QRadioButton" name="apply_all_checkbox">
@ -126,7 +154,7 @@
<item>
<widget class="QRadioButton" name="apply_selection_checkbox">
<property name="toolTip">
<string>&lt;p&gt;Show items only if they appear in the
<string>&lt;p&gt;Show authors only if they appear in the
currently selected books. Edits already done may be hidden but will
not be forgotten.
&lt;/p&gt;&lt;p&gt;

View File

@ -405,8 +405,9 @@ class TagListEditor(QDialog, Ui_TagListEditor):
if ac is not None:
ac.triggered.connect(self.clear_search)
self.search_box.textChanged.connect(self.search_text_changed)
self.search_button.clicked.connect(self.do_search)
self.search_button.clicked.connect(partial(self.do_search, inverted=False))
self.search_button.setDefault(True)
self.search_inverted_button.clicked.connect(partial(self.do_search, inverted=True))
self.filter_box.initialize('tag_list_filter_box_' + cat_name)
le = self.filter_box.lineEdit()
@ -414,7 +415,9 @@ class TagListEditor(QDialog, Ui_TagListEditor):
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.filter_button.clicked.connect(partial(self.do_filter, inverted=False))
self.filter_inverted_button.clicked.connect(partial(self.do_filter, inverted=True))
self.filter_inverted = False
self.show_button_layout.setSpacing(0)
self.show_button_layout.setContentsMargins(0, 0, 0, 0)
self.apply_all_checkbox.setContentsMargins(0, 0, 0, 0)
@ -600,14 +603,14 @@ class TagListEditor(QDialog, Ui_TagListEditor):
return 'virtual_library'
return None
def do_search(self):
def do_search(self, inverted=False):
self.not_found_label.setVisible(False)
find_text = str(self.search_box.currentText())
if not find_text:
return
for _ in range(self.table.rowCount()):
r = self.search_item_row = (self.search_item_row + 1) % self.table.rowCount()
if self.string_contains(find_text, self.table.item(r, VALUE_COLUMN).text()):
if self.string_contains(find_text, self.table.item(r, VALUE_COLUMN).text()) != inverted:
self.table.setCurrentItem(self.table.item(r, VALUE_COLUMN))
self.table.setFocus(Qt.FocusReason.OtherFocusReason)
return
@ -717,7 +720,7 @@ class TagListEditor(QDialog, Ui_TagListEditor):
self.all_tags = {}
filter_text = icu_lower(str(self.filter_box.text()))
for k,v,count in data:
if not filter_text or self.string_contains(filter_text, icu_lower(v)):
if not filter_text or self.string_contains(filter_text, icu_lower(v)) != self.filter_inverted:
self.all_tags[v] = {'key': k, 'count': count, 'cur_name': v,
'is_deleted': k in self.to_delete}
self.original_names[k] = v
@ -844,7 +847,8 @@ class TagListEditor(QDialog, Ui_TagListEditor):
self.filter_box.setText(txt)
self.do_filter()
def do_filter(self):
def do_filter(self, inverted=False):
self.filter_inverted = inverted
self.fill_in_table(None, None, False)
def table_column_resized(self, *args):

View File

@ -65,7 +65,7 @@
</size>
</property>
<property name="toolTip">
<string>Search for an item in the first column</string>
<string>Search for an item in the first column using the text in this box. The search ignores case.</string>
</property>
<property name="clearButtonEnabled">
<bool>true</bool>
@ -81,7 +81,7 @@
</sizepolicy>
</property>
<property name="toolTip">
<string>Find items containing the search string</string>
<string>Search for items that contain the search text</string>
</property>
<property name="text">
<string>S&amp;earch</string>
@ -92,6 +92,26 @@
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="search_inverted_button">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Search "not in"</string>
</property>
<property name="toolTip">
<string>Search for items that do not contain the search text</string>
</property>
<property name="icon">
<iconset resource="../../../../resources/images.qrc">
<normaloff>:/images/search.png</normaloff>:/images/search.png</iconset>
</property>
</widget>
</item>
</layout>
</widget>
</item>
@ -135,7 +155,7 @@
</size>
</property>
<property name="toolTip">
<string>Filter items using the text in this box</string>
<string>Filter items in the first column using the text in this box. The search ignores case.</string>
</property>
<property name="clearButtonEnabled">
<bool>true</bool>
@ -151,7 +171,7 @@
</sizepolicy>
</property>
<property name="toolTip">
<string>Show only items containing this text</string>
<string>Show all items that contain the filter text</string>
</property>
<property name="text">
<string>F&amp;ilter</string>
@ -162,6 +182,26 @@
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="filter_inverted_button">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Filter "not in"</string>
</property>
<property name="toolTip">
<string>Show all items that do not contain the filter text</string>
</property>
<property name="icon">
<iconset resource="../../../../resources/images.qrc">
<normaloff>:/images/filter.png</normaloff>:/images/filter.png</iconset>
</property>
</widget>
</item>
</layout>
</widget>
</item>