This commit is contained in:
Kovid Goyal 2022-10-19 20:48:24 +05:30
commit 49a2150b08
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
8 changed files with 90 additions and 230 deletions

View File

@ -522,12 +522,6 @@ content_server_thumbnail_compression_quality = 75
# cover_drop_exclude = {'tiff', 'webp'} # cover_drop_exclude = {'tiff', 'webp'}
cover_drop_exclude = () cover_drop_exclude = ()
#: Show the Saved searches box in the Search bar
# In newer versions of calibre, only a single button that allows you to add a
# new Saved search is shown in the Search bar. If you would like to have the
# old Saved searches box with its two buttons back, set this tweak to True.
show_saved_search_box = False
#: Exclude fields when copy/pasting metadata #: Exclude fields when copy/pasting metadata
# You can ask calibre to not paste some metadata fields when using the # You can ask calibre to not paste some metadata fields when using the
# Edit metadata->Copy metadata/Paste metadata actions. For example, # Edit metadata->Copy metadata/Paste metadata actions. For example,

View File

@ -284,6 +284,8 @@ def create_defs():
defs['action-layout-toolbar-child'] = () defs['action-layout-toolbar-child'] = ()
defs['action-layout-searchbar'] = ('Saved searches',)
defs['action-layout-context-menu'] = ( defs['action-layout-context-menu'] = (
'Edit Metadata', 'Send To Device', 'Save To Disk', 'Edit Metadata', 'Send To Device', 'Save To Disk',
'Connect Share', 'Copy To Library', None, 'Connect Share', 'Copy To Library', None,
@ -395,6 +397,7 @@ def create_defs():
defs['edit_metadata_templates_only_F2_on_booklist'] = False defs['edit_metadata_templates_only_F2_on_booklist'] = False
# JSON dumps converts integer keys to strings, so do it explicitly # JSON dumps converts integer keys to strings, so do it explicitly
defs['tb_search_order'] = {'0': 1, '1': 2, '2': 3, '3': 4, '4': 0} defs['tb_search_order'] = {'0': 1, '1': 2, '2': 3, '3': 4, '4': 0}
defs['search_tool_bar_shows_text'] = True
def migrate_tweak(tweak_name, pref_name): def migrate_tweak(tweak_name, pref_name):
# If the tweak has been changed then leave the tweak in the file so # If the tweak has been changed then leave the tweak in the file so

View File

@ -8,7 +8,8 @@ __docformat__ = 'restructuredtext en'
from functools import partial from functools import partial
from qt.core import ( from qt.core import (
Qt, QAction, QMenu, QObject, QToolBar, QToolButton, QSize, pyqtSignal, QKeySequence, QMenuBar, Qt, QAction, QMenu, QObject, QToolBar, QToolButton, QSize, pyqtSignal, QKeySequence, QMenuBar,
QTimer, QPropertyAnimation, QEasingCurve, pyqtProperty, QPainter, QWidget, QPalette, sip) QTimer, QPropertyAnimation, QEasingCurve, pyqtProperty, QPainter, QWidget, QPalette, sip,
QHBoxLayout, QFrame)
from calibre.constants import ismacos from calibre.constants import ismacos
from calibre.gui2 import gprefs, native_menubar_defaults, config from calibre.gui2 import gprefs, native_menubar_defaults, config
@ -628,6 +629,7 @@ class BarsManager(QObject):
self.main_bars = tuple(bars[:2]) self.main_bars = tuple(bars[:2])
self.child_bars = tuple(bars[2:]) self.child_bars = tuple(bars[2:])
self.reveal_bar = RevealBar(parent) self.reveal_bar = RevealBar(parent)
self.search_tool_bar = QHBoxLayout()
self.menu_bar = MenuBar(self.location_manager, self.parent()) self.menu_bar = MenuBar(self.location_manager, self.parent())
is_native_menubar = self.menu_bar.is_native_menubar is_native_menubar = self.menu_bar.is_native_menubar
@ -636,6 +638,7 @@ class BarsManager(QObject):
self.menubar_device_fallback = native_menubar_defaults['action-layout-menubar-device'] if is_native_menubar else () self.menubar_device_fallback = native_menubar_defaults['action-layout-menubar-device'] if is_native_menubar else ()
self.apply_settings() self.apply_settings()
self.search_tool_bar_actions = []
self.init_bars() self.init_bars()
def database_changed(self, db): def database_changed(self, db):
@ -669,6 +672,41 @@ class BarsManager(QObject):
for bar, actions in zip(self.bars, self.bar_actions[:3]): for bar, actions in zip(self.bars, self.bar_actions[:3]):
bar.init_bar(actions) bar.init_bar(actions)
# Build the layout containing the buttons to go into the search bar
self.build_search_tool_bar()
def build_search_tool_bar(self):
for ac in self.search_tool_bar_actions:
self.search_tool_bar.removeWidget(ac)
self.search_tool_bar.setContentsMargins(0, 0, 0, 0)
self.search_tool_bar.setSpacing(0)
self.search_tool_bar_actions = []
for what in gprefs['action-layout-searchbar']:
if what is None:
frame = QFrame()
frame.setFrameShape(QFrame.Shape.VLine)
frame.setFrameShadow(QFrame.Shadow.Sunken)
frame.setLineWidth(1)
frame.setContentsMargins(0, 5, 0, 5)
self.search_tool_bar.addWidget(frame)
self.search_tool_bar_actions.append(frame)
elif what in self.parent().iactions:
qact = self.parent().iactions[what].qaction
tb = QToolButton()
tb.setContentsMargins(0, 0, 0, 0)
tb.setDefaultAction(qact)
if not gprefs['search_tool_bar_shows_text']:
tb.setText(None)
else:
tb.setToolButtonStyle(Qt.ToolButtonStyle.ToolButtonTextBesideIcon)
tb.setCursor(Qt.CursorShape.PointingHandCursor)
tb.setPopupMode(QToolButton.ToolButtonPopupMode.InstantPopup)
tb.setAutoRaise(True)
self.search_tool_bar.addWidget(tb)
self.search_tool_bar_actions.append(tb)
def update_bars(self, reveal_bar=False): def update_bars(self, reveal_bar=False):
''' '''
This shows the correct main toolbar and rebuilds the menubar based on This shows the correct main toolbar and rebuilds the menubar based on
@ -693,6 +731,9 @@ class BarsManager(QObject):
self.menu_bar.init_bar(self.bar_actions[4 if showing_device else 3]) self.menu_bar.init_bar(self.bar_actions[4 if showing_device else 3])
self.menu_bar.update_lm_actions() self.menu_bar.update_lm_actions()
self.menu_bar.setVisible(bool(self.menu_bar.added_actions)) self.menu_bar.setVisible(bool(self.menu_bar.added_actions))
self.build_search_tool_bar()
from calibre.gui2.ui import get_gui
get_gui().search_bar.update()
def apply_settings(self): def apply_settings(self):
sz = gprefs['toolbar_icon_size'] sz = gprefs['toolbar_icon_size']

View File

@ -14,8 +14,7 @@ from qt.core import (
from calibre import human_readable from calibre import human_readable
from calibre.constants import __appname__ from calibre.constants import __appname__
from calibre.gui2.bars import BarsManager from calibre.gui2.bars import BarsManager
from calibre.gui2.search_box import SavedSearchBox, SearchBox2 from calibre.gui2.search_box import SearchBox2
from calibre.gui2.widgets2 import RightClickButton
from calibre.utils.config_base import tweaks from calibre.utils.config_base import tweaks
@ -265,40 +264,8 @@ class SearchBar(QFrame): # {{{
x.setIcon(QIcon.ic('arrow-down.png')) x.setIcon(QIcon.ic('arrow-down.png'))
l.addWidget(x) l.addWidget(x)
x = parent.saved_search = SavedSearchBox(self) # Add the searchbar tool buttons to the bar
x.setObjectName("saved_search") l.addLayout(self.parent().bars_manager.search_tool_bar)
l.addWidget(x)
x.setVisible(tweaks['show_saved_search_box'])
x = parent.copy_search_button = QToolButton(self)
x.setAutoRaise(True)
x.setCursor(Qt.CursorShape.PointingHandCursor)
x.setIcon(QIcon.ic("search_copy_saved.png"))
x.setObjectName("copy_search_button")
l.addWidget(x)
x.setToolTip(_("Copy current search text (instead of search name)"))
x.setVisible(tweaks['show_saved_search_box'])
x = parent.save_search_button = RightClickButton(self)
x.setAutoRaise(True)
x.setCursor(Qt.CursorShape.PointingHandCursor)
x.setIcon(QIcon.ic("search_add_saved.png"))
x.setObjectName("save_search_button")
l.addWidget(x)
x.setVisible(tweaks['show_saved_search_box'])
x = parent.add_saved_search_button = RightClickButton(self)
x.setToolTip(_(
'Use an existing Saved search or create a new one'
))
x.setText(_('Saved search'))
x.setToolButtonStyle(Qt.ToolButtonStyle.ToolButtonTextBesideIcon)
x.setCursor(Qt.CursorShape.PointingHandCursor)
x.setPopupMode(QToolButton.ToolButtonPopupMode.InstantPopup)
x.setAutoRaise(True)
x.setIcon(QIcon.ic("folder_saved_search.png"))
l.addWidget(x)
x.setVisible(not tweaks['show_saved_search_box'])
def populate_sort_menu(self): def populate_sort_menu(self):
from calibre.gui2.ui import get_gui from calibre.gui2.ui import get_gui
@ -342,9 +309,10 @@ class MainWindowMixin: # {{{
self.iactions['Fetch News'].init_scheduler() self.iactions['Fetch News'].init_scheduler()
self.search_bar = SearchBar(self)
self.bars_manager = BarsManager(self.donate_action, self.bars_manager = BarsManager(self.donate_action,
self.location_manager, self) self.location_manager, self)
# instantiating SearchBar must happen after setting bars manager
self.search_bar = SearchBar(self)
for bar in self.bars_manager.main_bars: for bar in self.bars_manager.main_bars:
self.addToolBar(Qt.ToolBarArea.TopToolBarArea, bar) self.addToolBar(Qt.ToolBarArea.TopToolBarArea, bar)
bar.setStyleSheet('QToolBar { border: 0px }') bar.setStyleSheet('QToolBar { border: 0px }')

View File

@ -32,6 +32,7 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form):
r('show_highlight_toggle_button', gprefs) r('show_highlight_toggle_button', gprefs)
r('limit_search_columns', prefs) r('limit_search_columns', prefs)
r('use_primary_find_in_search', prefs) r('use_primary_find_in_search', prefs)
r('search_tool_bar_shows_text', gprefs)
r('case_sensitive', prefs) r('case_sensitive', prefs)
fl = db.field_metadata.get_search_terms() fl = db.field_metadata.get_search_terms()
r('limit_search_columns_to', prefs, setting=CommaSeparatedList, choices=fl) r('limit_search_columns_to', prefs, setting=CommaSeparatedList, choices=fl)
@ -236,6 +237,7 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form):
return ConfigWidgetBase.commit(self) return ConfigWidgetBase.commit(self)
def refresh_gui(self, gui): def refresh_gui(self, gui):
gui.refresh_search_bar_widgets()
gui.current_db.new_api.clear_caches() gui.current_db.new_api.clear_caches()
set_use_primary_find_in_search(prefs['use_primary_find_in_search']) set_use_primary_find_in_search(prefs['use_primary_find_in_search'])
gui.set_highlight_only_button_icon() gui.set_highlight_only_button_icon()

View File

@ -24,7 +24,7 @@
<string>Genera&amp;l</string> <string>Genera&amp;l</string>
</attribute> </attribute>
<layout class="QGridLayout" name="gridLayout_6"> <layout class="QGridLayout" name="gridLayout_6">
<item row="6" column="0"> <item row="11" column="0">
<widget class="QPushButton" name="clear_history_button"> <widget class="QPushButton" name="clear_history_button">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed"> <sizepolicy hsizetype="Maximum" vsizetype="Fixed">
@ -40,7 +40,7 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="5" column="0" colspan="2"> <item row="10" column="0" colspan="2">
<widget class="QGroupBox" name="groupBox"> <widget class="QGroupBox" name="groupBox">
<property name="title"> <property name="title">
<string>What to search by default</string> <string>What to search by default</string>
@ -120,7 +120,7 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="7" column="0"> <item row="20" column="0">
<spacer name="verticalSpacer_2"> <spacer name="verticalSpacer_2">
<property name="orientation"> <property name="orientation">
<enum>Qt::Vertical</enum> <enum>Qt::Vertical</enum>
@ -140,6 +140,13 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="5" column="0">
<widget class="QCheckBox" name="opt_search_tool_bar_shows_text">
<property name="text">
<string>Show text next to buttons in the search bar</string>
</property>
</widget>
</item>
</layout> </layout>
</widget> </widget>
<widget class="QWidget" name="tab_2"> <widget class="QWidget" name="tab_2">

View File

@ -245,6 +245,7 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form):
('toolbar', _('The main toolbar')), ('toolbar', _('The main toolbar')),
('toolbar-device', _('The main toolbar when a device is connected')), ('toolbar-device', _('The main toolbar when a device is connected')),
('toolbar-child', _('The optional second toolbar')), ('toolbar-child', _('The optional second toolbar')),
('searchbar', ('The buttons on the search bar')),
('menubar', _('The menubar')), ('menubar', _('The menubar')),
('menubar-device', _('The menubar when a device is connected')), ('menubar-device', _('The menubar when a device is connected')),
('context-menu', _('The context menu for the books in the ' ('context-menu', _('The context menu for the books in the '

View File

@ -12,10 +12,9 @@ from functools import partial
from qt.core import ( from qt.core import (
QComboBox, Qt, QLineEdit, pyqtSlot, QDialog, QEvent, QComboBox, Qt, QLineEdit, pyqtSlot, QDialog, QEvent,
pyqtSignal, QCompleter, QAction, QKeySequence, QTimer, pyqtSignal, QCompleter, QAction, QKeySequence, QTimer,
QIcon, QMenu, QApplication, QKeyEvent) QIcon, QApplication, QKeyEvent)
from calibre.gui2 import config, error_dialog, question_dialog, gprefs, QT_HIDDEN_CLEAR_ACTION from calibre.gui2 import config, question_dialog, gprefs, QT_HIDDEN_CLEAR_ACTION
from calibre.gui2.dialogs.confirm_delete import confirm
from calibre.gui2.dialogs.saved_search_editor import SavedSearchEditor from calibre.gui2.dialogs.saved_search_editor import SavedSearchEditor
from calibre.gui2.dialogs.search import SearchDialog from calibre.gui2.dialogs.search import SearchDialog
from calibre.utils.icu import primary_sort_key from calibre.utils.icu import primary_sort_key
@ -320,147 +319,6 @@ class SearchBox2(QComboBox): # {{{
# }}} # }}}
class SavedSearchBox(QComboBox): # {{{
'''
To use this class:
* Call initialize()
* Connect to the changed() signal from this widget
if you care about changes to the list of saved searches.
'''
changed = pyqtSignal()
def __init__(self, parent=None):
QComboBox.__init__(self, parent)
self.line_edit = SearchLineEdit(self)
self.setLineEdit(self.line_edit)
self.line_edit.key_pressed.connect(self.key_pressed, type=Qt.ConnectionType.DirectConnection)
self.textActivated.connect(self.saved_search_selected)
# Turn off auto-completion so that it doesn't interfere with typing
# names of new searches.
completer = QCompleter(self)
self.setCompleter(completer)
self.setEditable(True)
self.setMaxVisibleItems(25)
self.setInsertPolicy(QComboBox.InsertPolicy.NoInsert)
self.setSizeAdjustPolicy(QComboBox.SizeAdjustPolicy.AdjustToMinimumContentsLengthWithIcon)
self.setMinimumContentsLength(25)
self.tool_tip_text = self.toolTip()
def initialize(self, _search_box, colorize=False, help_text=_('Search')):
self.search_box = _search_box
try:
self.line_edit.setPlaceholderText(help_text)
except:
# Using Qt < 4.7
pass
self.colorize = colorize
self.clear()
def normalize_state(self):
# need this because line_edit will call it in some cases such as paste
pass
def clear(self):
QComboBox.clear(self)
self.initialize_saved_search_names()
self.setEditText('')
self.setToolTip(self.tool_tip_text)
self.line_edit.home(False)
def key_pressed(self, event):
if event.key() in (Qt.Key.Key_Return, Qt.Key.Key_Enter):
self.saved_search_selected(self.currentText())
def saved_search_selected(self, qname):
from calibre.gui2.ui import get_gui
db = get_gui().current_db
qname = str(qname)
if qname is None or not qname.strip():
self.search_box.clear()
return
if not db.saved_search_lookup(qname):
self.search_box.clear()
self.setEditText(qname)
return
self.search_box.set_search_string('search:"%s"' % qname, emit_changed=False)
self.setEditText(qname)
self.setToolTip(db.saved_search_lookup(qname))
def initialize_saved_search_names(self):
from calibre.gui2.ui import get_gui
gui = get_gui()
try:
names = gui.current_db.saved_search_names()
except AttributeError:
# Happens during gui initialization
names = []
self.addItems(names)
self.setCurrentIndex(-1)
# SIGNALed from the main UI
def save_search_button_clicked(self):
from calibre.gui2.ui import get_gui
db = get_gui().current_db
name = str(self.currentText())
if not name.strip():
name = str(self.search_box.text()).replace('"', '')
name = name.replace('\\', '')
if not name:
error_dialog(self, _('Create saved search'),
_('Invalid saved search name. '
'It must contain at least one letter or number'), show=True)
return
if not self.search_box.text():
error_dialog(self, _('Create saved search'),
_('There is no search to save'), show=True)
return
db.saved_search_delete(name)
db.saved_search_add(name, str(self.search_box.text()))
# now go through an initialization cycle to ensure that the combobox has
# the new search in it, that it is selected, and that the search box
# references the new search instead of the text in the search.
self.clear()
self.setCurrentIndex(self.findText(name))
self.saved_search_selected(name)
self.changed.emit()
def delete_current_search(self):
from calibre.gui2.ui import get_gui
db = get_gui().current_db
idx = self.currentIndex()
if idx <= 0:
error_dialog(self, _('Delete current search'),
_('No search is selected'), show=True)
return
if not confirm('<p>'+_('The selected search will be '
'<b>permanently deleted</b>. Are you sure?') +
'</p>', 'saved_search_delete', self):
return
ss = db.saved_search_lookup(str(self.currentText()))
if ss is None:
return
db.saved_search_delete(str(self.currentText()))
self.clear()
self.search_box.clear()
self.changed.emit()
# SIGNALed from the main UI
def copy_search_button_clicked(self):
from calibre.gui2.ui import get_gui
db = get_gui().current_db
idx = self.currentIndex()
if idx < 0:
return
self.search_box.set_search_string(db.saved_search_lookup(str(self.currentText())))
# }}}
class SearchBoxMixin: # {{{ class SearchBoxMixin: # {{{
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
@ -497,6 +355,16 @@ class SearchBoxMixin: # {{{
self.highlight_only_action = ac = QAction(self) self.highlight_only_action = ac = QAction(self)
self.addAction(ac), ac.triggered.connect(self.highlight_only_clicked) self.addAction(ac), ac.triggered.connect(self.highlight_only_clicked)
self.keyboard.register_shortcut('highlight search results', _('Highlight search results'), action=self.highlight_only_action) self.keyboard.register_shortcut('highlight search results', _('Highlight search results'), action=self.highlight_only_action)
self.refresh_search_bar_widgets()
def refresh_search_bar_widgets(self):
self.set_highlight_only_button_icon()
if gprefs['search_tool_bar_shows_text']:
self.search_bar.search_button.setText(_('Search'))
self.search_bar.search_button.setToolButtonStyle(Qt.ToolButtonStyle.ToolButtonTextBesideIcon)
else:
self.search_bar.search_button.setText(None)
self.search_bar.search_button.setToolButtonStyle(Qt.ToolButtonStyle.ToolButtonIconOnly)
def highlight_only_clicked(self, state): def highlight_only_clicked(self, state):
if not config['highlight_search_matches'] and not question_dialog(self, _('Are you sure?'), if not config['highlight_search_matches'] and not question_dialog(self, _('Are you sure?'),
@ -513,10 +381,20 @@ class SearchBoxMixin: # {{{
b = self.highlight_only_button b = self.highlight_only_button
if config['highlight_search_matches']: if config['highlight_search_matches']:
b.setIcon(QIcon.ic('highlight_only_on.png')) b.setIcon(QIcon.ic('highlight_only_on.png'))
b.setText(_('Filter')) if gprefs['search_tool_bar_shows_text']:
b.setText(_('Filter'))
b.setToolButtonStyle(Qt.ToolButtonStyle.ToolButtonTextBesideIcon)
else:
b.setText(None)
b.setToolButtonStyle(Qt.ToolButtonStyle.ToolButtonIconOnly)
else: else:
b.setIcon(QIcon.ic('highlight_only_off.png')) b.setIcon(QIcon.ic('highlight_only_off.png'))
b.setText(_('Highlight')) if gprefs['search_tool_bar_shows_text']:
b.setText(_('Highlight'))
b.setToolButtonStyle(Qt.ToolButtonStyle.ToolButtonTextBesideIcon)
else:
b.setText(None)
b.setToolButtonStyle(Qt.ToolButtonStyle.ToolButtonIconOnly)
self.highlight_only_button.setVisible(gprefs['show_highlight_toggle_button']) self.highlight_only_button.setVisible(gprefs['show_highlight_toggle_button'])
self.library_view.model().set_highlight_only(config['highlight_search_matches']) self.library_view.model().set_highlight_only(config['highlight_search_matches'])
@ -526,11 +404,9 @@ class SearchBoxMixin: # {{{
def search_box_cleared(self): def search_box_cleared(self):
self.tags_view.clear() self.tags_view.clear()
self.saved_search.clear()
self.set_number_of_books_shown() self.set_number_of_books_shown()
def search_box_changed(self): def search_box_changed(self):
self.saved_search.clear()
self.tags_view.conditional_clear(self.search.current_text) self.tags_view.conditional_clear(self.search.current_text)
def do_advanced_search(self, *args): def do_advanced_search(self, *args):
@ -554,41 +430,10 @@ class SavedSearchBoxMixin: # {{{
pass pass
def init_saved_seach_box_mixin(self): def init_saved_seach_box_mixin(self):
self.saved_search.changed.connect(self.saved_searches_changed) pass
ac = self.search.findChild(QAction, QT_HIDDEN_CLEAR_ACTION)
if ac is not None:
ac.triggered.connect(self.saved_search.clear)
self.save_search_button.clicked.connect(
self.saved_search.save_search_button_clicked)
self.copy_search_button.clicked.connect(
self.saved_search.copy_search_button_clicked)
# self.saved_searches_changed()
self.saved_search.initialize(self.search, colorize=True,
help_text=_('Saved searches'))
self.saved_search.tool_tip_text=_('Choose saved search or enter name for new saved search')
self.saved_search.setToolTip(self.saved_search.tool_tip_text)
self.saved_search.setStatusTip(self.saved_search.tool_tip_text)
for x in ('copy', 'save'):
b = getattr(self, x+'_search_button')
b.setStatusTip(b.toolTip())
self.save_search_button.setToolTip('<p>' +
_("Save current search under the name shown in the box. "
"Press and hold for a pop-up options menu.") + '</p>')
self.save_search_button.setMenu(QMenu(self.save_search_button))
self.save_search_button.menu().addAction(
QIcon.ic('search_add_saved.png'),
_('Create Saved search'),
self.saved_search.save_search_button_clicked)
self.save_search_button.menu().addAction(
QIcon.ic('search_delete_saved.png'), _('Delete Saved search'), self.saved_search.delete_current_search)
self.save_search_button.menu().addAction(
QIcon.ic('search.png'), _('Manage Saved searches'), partial(self.do_saved_search_edit, None))
self.add_saved_search_button.setMenu(QMenu(self.add_saved_search_button))
self.add_saved_search_button.menu().aboutToShow.connect(self.populate_add_saved_search_menu)
def populate_add_saved_search_menu(self, to_menu):
def populate_add_saved_search_menu(self, to_menu=None): m = to_menu
m = to_menu if to_menu is not None else self.add_saved_search_button.menu()
m.clear() m.clear()
m.clear() m.clear()
m.addAction(QIcon.ic('search_add_saved.png'), _('Add Saved search'), self.add_saved_search) m.addAction(QIcon.ic('search_add_saved.png'), _('Add Saved search'), self.add_saved_search)
@ -631,7 +476,6 @@ class SavedSearchBoxMixin: # {{{
def do_rebuild_saved_searches(self): def do_rebuild_saved_searches(self):
self.saved_searches_changed() self.saved_searches_changed()
self.saved_search.clear()
def add_saved_search(self): def add_saved_search(self):
from calibre.gui2.dialogs.saved_search_editor import AddSavedSearch from calibre.gui2.dialogs.saved_search_editor import AddSavedSearch