Refactor search boxes to use Qt 4.7 facility for displaying help text. Pressing Enter in the search box int he main calibre GUI now focusses the book list

This commit is contained in:
Kovid Goyal 2010-11-30 10:04:08 -07:00
commit 3fcebe8383
8 changed files with 126 additions and 154 deletions

View File

@ -10,7 +10,8 @@ Scheduler for automated recipe downloads
from datetime import timedelta from datetime import timedelta
from PyQt4.Qt import QDialog, SIGNAL, Qt, QTime, QObject, QMenu, \ from PyQt4.Qt import QDialog, SIGNAL, Qt, QTime, QObject, QMenu, \
QAction, QIcon, QMutex, QTimer, pyqtSignal QAction, QIcon, QMutex, QTimer, pyqtSignal, QWidget, QHBoxLayout, \
QLabel
from calibre.gui2.dialogs.scheduler_ui import Ui_Dialog from calibre.gui2.dialogs.scheduler_ui import Ui_Dialog
from calibre.gui2.search_box import SearchBox2 from calibre.gui2.search_box import SearchBox2
@ -28,15 +29,21 @@ class SchedulerDialog(QDialog, Ui_Dialog):
self.recipe_model = recipe_model self.recipe_model = recipe_model
self.recipe_model.do_refresh() self.recipe_model.do_refresh()
self._cont = QWidget(self)
self._cont.l = QHBoxLayout()
self._cont.setLayout(self._cont.l)
self._cont.la = QLabel(_('&Search:'))
self._cont.l.addWidget(self._cont.la, 1)
self.search = SearchBox2(self) self.search = SearchBox2(self)
self._cont.l.addWidget(self.search, 100)
self._cont.la.setBuddy(self.search)
self.search.setMinimumContentsLength(25) self.search.setMinimumContentsLength(25)
self.search.initialize('scheduler_search_history') self.search.initialize('scheduler_search_history')
self.recipe_box.layout().insertWidget(0, self.search) self.recipe_box.layout().insertWidget(0, self._cont)
self.search.search.connect(self.recipe_model.search) self.search.search.connect(self.recipe_model.search)
self.connect(self.recipe_model, SIGNAL('searched(PyQt_PyObject)'), self.recipe_model.searched.connect(self.search.search_done,
self.search.search_done) type=Qt.QueuedConnection)
self.connect(self.recipe_model, SIGNAL('searched(PyQt_PyObject)'), self.recipe_model.searched.connect(self.search_done)
self.search_done)
self.search.setFocus(Qt.OtherFocusReason) self.search.setFocus(Qt.OtherFocusReason)
self.commit_on_change = True self.commit_on_change = True

View File

@ -127,7 +127,7 @@ class Main(MainWindow, Ui_MainWindow):
self.progress_label.setText('Parsing '+ self.file_name) self.progress_label.setText('Parsing '+ self.file_name)
self.renderer = RenderWorker(self, stream, self.logger, self.opts) self.renderer = RenderWorker(self, stream, self.logger, self.opts)
QObject.connect(self.renderer, SIGNAL('finished()'), self.parsed, Qt.QueuedConnection) QObject.connect(self.renderer, SIGNAL('finished()'), self.parsed, Qt.QueuedConnection)
self.search.clear_to_help() self.search.clear()
self.last_search = None self.last_search = None
else: else:
self.stack.setCurrentIndex(0) self.stack.setCurrentIndex(0)

View File

@ -8,9 +8,8 @@ __docformat__ = 'restructuredtext en'
import re import re
from PyQt4.Qt import QComboBox, Qt, QLineEdit, QStringList, pyqtSlot, \ from PyQt4.Qt import QComboBox, Qt, QLineEdit, QStringList, pyqtSlot, QDialog, \
pyqtSignal, SIGNAL, QObject, QDialog, QCompleter, \ pyqtSignal, QCompleter, QAction, QKeySequence, QTimer
QAction, QKeySequence, QTimer
from calibre.gui2 import config from calibre.gui2 import config
from calibre.gui2.dialogs.confirm_delete import confirm from calibre.gui2.dialogs.confirm_delete import confirm
@ -20,35 +19,30 @@ from calibre.utils.search_query_parser import saved_searches
class SearchLineEdit(QLineEdit): class SearchLineEdit(QLineEdit):
key_pressed = pyqtSignal(object) key_pressed = pyqtSignal(object)
mouse_released = pyqtSignal(object)
focus_out = pyqtSignal(object)
def keyPressEvent(self, event): def keyPressEvent(self, event):
self.key_pressed.emit(event) self.key_pressed.emit(event)
QLineEdit.keyPressEvent(self, event) QLineEdit.keyPressEvent(self, event)
def mouseReleaseEvent(self, event): def mouseReleaseEvent(self, event):
self.mouse_released.emit(event)
QLineEdit.mouseReleaseEvent(self, event) QLineEdit.mouseReleaseEvent(self, event)
QLineEdit.selectAll(self)
def focusOutEvent(self, event): def focusInEvent(self, event):
self.focus_out.emit(event) QLineEdit.focusInEvent(self, event)
QLineEdit.focusOutEvent(self, event) QLineEdit.selectAll(self)
def dropEvent(self, ev): def dropEvent(self, ev):
if self.parent().help_state: self.parent().normalize_state()
self.parent().normalize_state()
return QLineEdit.dropEvent(self, ev) return QLineEdit.dropEvent(self, ev)
def contextMenuEvent(self, ev): def contextMenuEvent(self, ev):
if self.parent().help_state: self.parent().normalize_state()
self.parent().normalize_state()
return QLineEdit.contextMenuEvent(self, ev) return QLineEdit.contextMenuEvent(self, ev)
@pyqtSlot() @pyqtSlot()
def paste(self, *args): def paste(self, *args):
if self.parent().help_state: self.parent().normalize_state()
self.parent().normalize_state()
return QLineEdit.paste(self) return QLineEdit.paste(self)
class SearchBox2(QComboBox): class SearchBox2(QComboBox):
@ -59,14 +53,17 @@ class SearchBox2(QComboBox):
* Call initialize() * Call initialize()
* Connect to the search() and cleared() signals from this widget. * Connect to the search() and cleared() signals from this widget.
* Connect to the cleared() signal to know when the box content changes * Connect to the cleared() signal to know when the box content changes
* Connect to focus_to_library signal to be told to manually change focus
* Call search_done() after every search is complete * Call search_done() after every search is complete
* Use clear() to clear back to the help message
''' '''
INTERVAL = 1500 #: Time to wait before emitting search signal INTERVAL = 1500 #: Time to wait before emitting search signal
MAX_COUNT = 25 MAX_COUNT = 25
search = pyqtSignal(object) search = pyqtSignal(object)
cleared = pyqtSignal()
changed = pyqtSignal()
focus_to_library = pyqtSignal()
def __init__(self, parent=None): def __init__(self, parent=None):
QComboBox.__init__(self, parent) QComboBox.__init__(self, parent)
@ -75,13 +72,9 @@ class SearchBox2(QComboBox):
self.setLineEdit(self.line_edit) self.setLineEdit(self.line_edit)
c = self.line_edit.completer() c = self.line_edit.completer()
c.setCompletionMode(c.PopupCompletion) c.setCompletionMode(c.PopupCompletion)
self.line_edit.key_pressed.connect(self.key_pressed, self.line_edit.key_pressed.connect(self.key_pressed, type=Qt.DirectConnection)
type=Qt.DirectConnection)
self.line_edit.mouse_released.connect(self.mouse_released,
type=Qt.DirectConnection)
self.activated.connect(self.history_selected) self.activated.connect(self.history_selected)
self.setEditable(True) self.setEditable(True)
self.help_state = False
self.as_you_type = True self.as_you_type = True
self.prev_search = '' self.prev_search = ''
self.timer = QTimer() self.timer = QTimer()
@ -98,96 +91,69 @@ class SearchBox2(QComboBox):
self.as_you_type = config['search_as_you_type'] self.as_you_type = config['search_as_you_type']
self.opt_name = opt_name self.opt_name = opt_name
self.addItems(QStringList(list(set(config[opt_name])))) self.addItems(QStringList(list(set(config[opt_name]))))
self.help_text = help_text try:
self.line_edit.setPlaceholderText(help_text)
except:
# Using Qt < 4.7
pass
self.colorize = colorize self.colorize = colorize
self.clear_to_help() self.clear()
def normalize_state(self): def normalize_state(self):
self.setToolTip(self.tool_tip_text) self.setToolTip(self.tool_tip_text)
if self.help_state:
self.setEditText('')
self.line_edit.setStyleSheet(
'QLineEdit { color: black; background-color: %s; }' %
self.normal_background)
self.help_state = False
else:
self.line_edit.setStyleSheet(
'QLineEdit { color: black; background-color: %s; }' %
self.normal_background)
def clear_to_help(self):
self.setToolTip(self.tool_tip_text)
if self.help_state:
return
self.help_state = True
self.search.emit('')
self._in_a_search = False
self.setEditText(self.help_text)
self.line_edit.home(False)
self.line_edit.setStyleSheet( self.line_edit.setStyleSheet(
'QLineEdit { color: gray; background-color: %s; }' % 'QLineEdit{color:black;background-color:%s;}' % self.normal_background)
self.normal_background)
self.emit(SIGNAL('cleared()'))
def text(self): def text(self):
return self.currentText() return self.currentText()
def clear(self): def clear(self, emit_search=False):
self.clear_to_help() self.normalize_state()
self.setEditText('')
self.search.emit('')
self._in_a_search = False
self.cleared.emit()
def search_done(self, ok): def search_done(self, ok):
if isinstance(ok, basestring): if isinstance(ok, basestring):
self.setToolTip(ok) self.setToolTip(ok)
ok = False ok = False
if not unicode(self.currentText()).strip(): if not unicode(self.currentText()).strip():
return self.clear_to_help() self.clear(emit_search=False)
return
self._in_a_search = ok self._in_a_search = ok
col = 'rgba(0,255,0,20%)' if ok else 'rgb(255,0,0,20%)' col = 'rgba(0,255,0,20%)' if ok else 'rgb(255,0,0,20%)'
if not self.colorize: if not self.colorize:
col = self.normal_background col = self.normal_background
self.line_edit.setStyleSheet('QLineEdit { color: black; background-color: %s; }' % col) self.line_edit.setStyleSheet('QLineEdit{color:black;background-color:%s;}' % col)
def key_pressed(self, event): def key_pressed(self, event):
k = event.key() k = event.key()
if k in (Qt.Key_Left, Qt.Key_Right, Qt.Key_Up, Qt.Key_Down, if k in (Qt.Key_Left, Qt.Key_Right, Qt.Key_Up, Qt.Key_Down,
Qt.Key_Home, Qt.Key_End, Qt.Key_PageUp, Qt.Key_PageDown): Qt.Key_Home, Qt.Key_End, Qt.Key_PageUp, Qt.Key_PageDown,
Qt.Key_unknown):
return return
self.normalize_state() self.normalize_state()
if self._in_a_search: if self._in_a_search:
self.emit(SIGNAL('changed()')) self.changed.emit()
self._in_a_search = False self._in_a_search = False
if event.key() in (Qt.Key_Return, Qt.Key_Enter): if event.key() in (Qt.Key_Return, Qt.Key_Enter):
self.do_search() self.do_search()
self.focus_to_library.emit()
if self.as_you_type: if self.as_you_type:
self.timer.start(1500) self.timer.start(1500)
def mouse_released(self, event):
self.normalize_state()
# Dont trigger a search since it make
# re-positioning the cursor using the mouse
# impossible
#if self.as_you_type:
# self.timer.start(1500)
def timer_event(self): def timer_event(self):
self.do_search() self.do_search()
def history_selected(self, text): def history_selected(self, text):
self.emit(SIGNAL('changed()')) self.changed.emit()
self.do_search() self.do_search()
@property
def smart_text(self):
text = unicode(self.currentText()).strip()
if not text or text == self.help_text:
return ''
return text
def do_search(self, *args): def do_search(self, *args):
text = unicode(self.currentText()).strip() text = unicode(self.currentText()).strip()
if not text or text == self.help_text: if not text:
return self.clear() return self.clear()
self.help_state = False
self.prev_search = text self.prev_search = text
self.search.emit(text) self.search.emit(text)
@ -220,7 +186,7 @@ class SearchBox2(QComboBox):
def set_search_string(self, txt): def set_search_string(self, txt):
if not txt: if not txt:
self.clear_to_help() self.clear()
return return
self.normalize_state() self.normalize_state()
self.setEditText(txt) self.setEditText(txt)
@ -243,25 +209,24 @@ class SavedSearchBox(QComboBox):
if you care about changes to the list of saved searches. if you care about changes to the list of saved searches.
''' '''
changed = pyqtSignal()
focus_to_library = pyqtSignal()
def __init__(self, parent=None): def __init__(self, parent=None):
QComboBox.__init__(self, parent) QComboBox.__init__(self, parent)
self.normal_background = 'rgb(255, 255, 255, 0%)' self.normal_background = 'rgb(255, 255, 255, 0%)'
self.line_edit = SearchLineEdit(self) self.line_edit = SearchLineEdit(self)
self.setLineEdit(self.line_edit) self.setLineEdit(self.line_edit)
self.line_edit.key_pressed.connect(self.key_pressed, self.line_edit.key_pressed.connect(self.key_pressed, type=Qt.DirectConnection)
type=Qt.DirectConnection)
self.line_edit.mouse_released.connect(self.mouse_released,
type=Qt.DirectConnection)
self.line_edit.focus_out.connect(self.focus_out,
type=Qt.DirectConnection)
self.activated[str].connect(self.saved_search_selected) self.activated[str].connect(self.saved_search_selected)
completer = QCompleter(self) # turn off auto-completion # Turn off auto-completion so that it doesn't interfere with typing
# names of new searches.
completer = QCompleter(self)
self.setCompleter(completer) self.setCompleter(completer)
self.setEditable(True) self.setEditable(True)
self.help_state = True
self.prev_search = ''
self.setInsertPolicy(self.NoInsert) self.setInsertPolicy(self.NoInsert)
self.setSizeAdjustPolicy(self.AdjustToMinimumContentsLengthWithIcon) self.setSizeAdjustPolicy(self.AdjustToMinimumContentsLengthWithIcon)
self.setMinimumContentsLength(10) self.setMinimumContentsLength(10)
@ -269,50 +234,40 @@ class SavedSearchBox(QComboBox):
def initialize(self, _search_box, colorize=False, help_text=_('Search')): def initialize(self, _search_box, colorize=False, help_text=_('Search')):
self.search_box = _search_box self.search_box = _search_box
self.help_text = help_text self.line_edit.setPlaceholderText(help_text)
self.colorize = colorize self.colorize = colorize
self.clear_to_help() self.clear()
def normalize_state(self): def normalize_state(self):
self.setEditText('') # need this because line_edit will call it in some cases such as paste
self.line_edit.setStyleSheet( pass
'QLineEdit { color: black; background-color: %s; }' %
self.normal_background)
self.help_state = False
def clear_to_help(self): def clear(self):
self.setToolTip(self.tool_tip_text) QComboBox.clear(self)
self.initialize_saved_search_names() self.initialize_saved_search_names()
self.setEditText(self.help_text) self.setEditText('')
self.line_edit.home(False) self.line_edit.home(False)
self.help_state = True
self.line_edit.setStyleSheet(
'QLineEdit { color: gray; background-color: %s; }' %
self.normal_background)
def focus_out(self, event):
if self.currentText() == '':
self.clear_to_help()
def key_pressed(self, event): def key_pressed(self, event):
if self.help_state: if event.key() in (Qt.Key_Return, Qt.Key_Enter):
self.normalize_state() self.saved_search_selected(self.currentText())
self.focus_to_library.emit()
def mouse_released(self, event):
if self.help_state:
self.normalize_state()
def saved_search_selected(self, qname): def saved_search_selected(self, qname):
qname = unicode(qname) qname = unicode(qname)
if qname is None or not qname.strip(): if qname is None or not qname.strip():
self.search_box.clear()
return
if not saved_searches().lookup(qname):
self.search_box.clear()
self.setEditText(qname)
return return
self.normalize_state()
self.search_box.set_search_string(u'search:"%s"' % qname) self.search_box.set_search_string(u'search:"%s"' % qname)
self.setEditText(qname) self.setEditText(qname)
self.setToolTip(saved_searches().lookup(qname)) self.setToolTip(saved_searches().lookup(qname))
self.focus_to_library.emit()
def initialize_saved_search_names(self): def initialize_saved_search_names(self):
self.clear()
qnames = saved_searches().names() qnames = saved_searches().names()
self.addItems(qnames) self.addItems(qnames)
self.setCurrentIndex(-1) self.setCurrentIndex(-1)
@ -330,25 +285,24 @@ class SavedSearchBox(QComboBox):
if ss is None: if ss is None:
return return
saved_searches().delete(unicode(self.currentText())) saved_searches().delete(unicode(self.currentText()))
self.clear_to_help() self.clear()
self.search_box.clear_to_help() self.search_box.clear()
self.emit(SIGNAL('changed()')) self.changed.emit()
# SIGNALed from the main UI # SIGNALed from the main UI
def save_search_button_clicked(self): def save_search_button_clicked(self):
name = unicode(self.currentText()) name = unicode(self.currentText())
if self.help_state or not name.strip(): if not name.strip():
name = unicode(self.search_box.text()).replace('"', '') name = unicode(self.search_box.text()).replace('"', '')
saved_searches().delete(name) saved_searches().delete(name)
saved_searches().add(name, unicode(self.search_box.text())) saved_searches().add(name, unicode(self.search_box.text()))
# now go through an initialization cycle to ensure that the combobox has # 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 # 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. # references the new search instead of the text in the search.
self.clear_to_help() self.clear()
self.normalize_state()
self.setCurrentIndex(self.findText(name)) self.setCurrentIndex(self.findText(name))
self.saved_search_selected (name) self.saved_search_selected (name)
self.emit(SIGNAL('changed()')) self.changed.emit()
# SIGNALed from the main UI # SIGNALed from the main UI
def copy_search_button_clicked (self): def copy_search_button_clicked (self):
@ -362,11 +316,11 @@ class SearchBoxMixin(object):
def __init__(self): def __init__(self):
self.search.initialize('main_search_history', colorize=True, self.search.initialize('main_search_history', colorize=True,
help_text=_('Search (For Advanced Search click the button to the left)')) help_text=_('Search (For Advanced Search click the button to the left)'))
self.connect(self.search, SIGNAL('cleared()'), self.search_box_cleared) self.search.cleared.connect(self.search_box_cleared)
self.connect(self.search, SIGNAL('changed()'), self.search_box_changed) self.search.changed.connect(self.search_box_changed)
self.connect(self.clear_button, SIGNAL('clicked()'), self.search.clear) self.search.focus_to_library.connect(self.focus_to_library)
QObject.connect(self.advanced_search_button, SIGNAL('clicked(bool)'), self.clear_button.clicked.connect(self.search.clear)
self.do_advanced_search) self.advanced_search_button.clicked[bool].connect(self.do_advanced_search)
self.search.clear() self.search.clear()
self.search.setMaximumWidth(self.width()-150) self.search.setMaximumWidth(self.width()-150)
@ -384,11 +338,11 @@ class SearchBoxMixin(object):
def search_box_cleared(self): def search_box_cleared(self):
self.tags_view.clear() self.tags_view.clear()
self.saved_search.clear_to_help() 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_to_help() self.saved_search.clear()
self.tags_view.clear() self.tags_view.clear()
def do_advanced_search(self, *args): def do_advanced_search(self, *args):
@ -396,20 +350,24 @@ class SearchBoxMixin(object):
if d.exec_() == QDialog.Accepted: if d.exec_() == QDialog.Accepted:
self.search.set_search_string(d.search_string()) self.search.set_search_string(d.search_string())
def focus_to_library(self):
self.current_view().setFocus(Qt.OtherFocusReason)
class SavedSearchBoxMixin(object): class SavedSearchBoxMixin(object):
def __init__(self): def __init__(self):
self.connect(self.saved_search, SIGNAL('changed()'), self.saved_searches_changed) self.saved_search.changed.connect(self.saved_searches_changed)
self.clear_button.clicked.connect(self.saved_search.clear)
self.saved_search.focus_to_library.connect(self.focus_to_library)
self.save_search_button.clicked.connect(
self.saved_search.save_search_button_clicked)
self.delete_search_button.clicked.connect(
self.saved_search.delete_search_button_clicked)
self.copy_search_button.clicked.connect(
self.saved_search.copy_search_button_clicked)
self.saved_searches_changed() self.saved_searches_changed()
self.connect(self.clear_button, SIGNAL('clicked()'), self.saved_search.clear_to_help)
self.saved_search.initialize(self.search, colorize=True, self.saved_search.initialize(self.search, colorize=True,
help_text=_('Saved Searches')) help_text=_('Saved Searches'))
self.connect(self.save_search_button, SIGNAL('clicked()'),
self.saved_search.save_search_button_clicked)
self.connect(self.delete_search_button, SIGNAL('clicked()'),
self.saved_search.delete_search_button_clicked)
self.connect(self.copy_search_button, SIGNAL('clicked()'),
self.saved_search.copy_search_button_clicked)
self.saved_search.setToolTip( self.saved_search.setToolTip(
_('Choose saved search or enter name for new saved search')) _('Choose saved search or enter name for new saved search'))
self.saved_search.setStatusTip(self.saved_search.toolTip()) self.saved_search.setStatusTip(self.saved_search.toolTip())
@ -420,7 +378,8 @@ class SavedSearchBoxMixin(object):
def saved_searches_changed(self): def saved_searches_changed(self):
p = sorted(saved_searches().names(), cmp=lambda x,y: cmp(x.lower(), y.lower())) p = sorted(saved_searches().names(), cmp=lambda x,y: cmp(x.lower(), y.lower()))
t = unicode(self.search_restriction.currentText()) t = unicode(self.search_restriction.currentText())
self.search_restriction.clear() # rebuild the restrictions combobox using current saved searches # rebuild the restrictions combobox using current saved searches
self.search_restriction.clear()
self.search_restriction.addItem('') self.search_restriction.addItem('')
self.tags_view.recount() self.tags_view.recount()
for s in p: for s in p:
@ -433,6 +392,8 @@ class SavedSearchBoxMixin(object):
d.exec_() d.exec_()
if d.result() == d.Accepted: if d.result() == d.Accepted:
self.saved_searches_changed() self.saved_searches_changed()
self.saved_search.clear_to_help() self.saved_search.clear()
def focus_to_library(self):
self.current_view().setFocus(Qt.OtherFocusReason)

View File

@ -49,8 +49,8 @@ class SearchRestrictionMixin(object):
restriction = '' restriction = ''
self.restriction_count_of_books_in_view = \ self.restriction_count_of_books_in_view = \
self.library_view.model().set_search_restriction(restriction) self.library_view.model().set_search_restriction(restriction)
self.search.clear_to_help() self.search.clear()
self.saved_search.clear_to_help() self.saved_search.clear()
self.tags_view.set_search_restriction(restriction) self.tags_view.set_search_restriction(restriction)
self.set_number_of_books_shown() self.set_number_of_books_shown()

View File

@ -843,7 +843,7 @@ class TagBrowserMixin(object): # {{{
self.tags_view.set_database(self.library_view.model().db, self.tags_view.set_database(self.library_view.model().db,
self.tag_match, self.sort_by) self.tag_match, self.sort_by)
self.tags_view.tags_marked.connect(self.search.search_from_tags) self.tags_view.tags_marked.connect(self.search.search_from_tags)
self.tags_view.tags_marked.connect(self.saved_search.clear_to_help) self.tags_view.tags_marked.connect(self.saved_search.clear)
self.tags_view.tag_list_edit.connect(self.do_tags_list_edit) self.tags_view.tag_list_edit.connect(self.do_tags_list_edit)
self.tags_view.user_category_edit.connect(self.do_user_categories_edit) self.tags_view.user_category_edit.connect(self.do_user_categories_edit)
self.tags_view.saved_search_edit.connect(self.do_saved_search_edit) self.tags_view.saved_search_edit.connect(self.do_saved_search_edit)
@ -910,14 +910,14 @@ class TagBrowserMixin(object): # {{{
self.library_view.model().refresh() self.library_view.model().refresh()
self.tags_view.set_new_model() self.tags_view.set_new_model()
self.tags_view.recount() self.tags_view.recount()
self.saved_search.clear_to_help() self.saved_search.clear()
self.search.clear_to_help() self.search.clear()
def do_tag_item_renamed(self): def do_tag_item_renamed(self):
# Clean up library view and search # Clean up library view and search
self.library_view.model().refresh() self.library_view.model().refresh()
self.saved_search.clear_to_help() self.saved_search.clear()
self.search.clear_to_help() self.search.clear()
def do_author_sort_edit(self, parent, id): def do_author_sort_edit(self, parent, id):
db = self.library_view.model().db db = self.library_view.model().db

View File

@ -383,8 +383,8 @@ class Main(MainWindow, MainWindowMixin, DeviceMixin, EmailMixin, # {{{
self.tags_view.set_database(db, self.tag_match, self.sort_by) self.tags_view.set_database(db, self.tag_match, self.sort_by)
self.library_view.model().set_book_on_device_func(self.book_on_device) self.library_view.model().set_book_on_device_func(self.book_on_device)
self.status_bar.clear_message() self.status_bar.clear_message()
self.search.clear_to_help() self.search.clear()
self.saved_search.clear_to_help() self.saved_search.clear()
self.book_details.reset_info() self.book_details.reset_info()
self.library_view.model().count_changed() self.library_view.model().count_changed()
prefs['library_path'] = self.library_path prefs['library_path'] = self.library_path

View File

@ -237,9 +237,9 @@ class EbookViewer(MainWindow, Ui_EbookViewer):
self.connect(self.action_previous_page, SIGNAL('triggered(bool)'), self.connect(self.action_previous_page, SIGNAL('triggered(bool)'),
lambda x:self.view.previous_page()) lambda x:self.view.previous_page())
self.connect(self.action_find_next, SIGNAL('triggered(bool)'), self.connect(self.action_find_next, SIGNAL('triggered(bool)'),
lambda x:self.find(self.search.smart_text, repeat=True)) lambda x:self.find(unicode(self.search.text()), repeat=True))
self.connect(self.action_find_previous, SIGNAL('triggered(bool)'), self.connect(self.action_find_previous, SIGNAL('triggered(bool)'),
lambda x:self.find(self.search.smart_text, lambda x:self.find(unicode(self.search.text()),
repeat=True, backwards=True)) repeat=True, backwards=True))
self.connect(self.action_full_screen, SIGNAL('triggered(bool)'), self.connect(self.action_full_screen, SIGNAL('triggered(bool)'),

View File

@ -9,7 +9,7 @@ __docformat__ = 'restructuredtext en'
import os, copy import os, copy
from PyQt4.Qt import QAbstractItemModel, QVariant, Qt, QColor, QFont, QIcon, \ from PyQt4.Qt import QAbstractItemModel, QVariant, Qt, QColor, QFont, QIcon, \
QModelIndex, SIGNAL, QMetaObject, pyqtSlot QModelIndex, QMetaObject, pyqtSlot, pyqtSignal
from calibre.utils.search_query_parser import SearchQueryParser from calibre.utils.search_query_parser import SearchQueryParser
from calibre.gui2 import NONE from calibre.gui2 import NONE
@ -120,6 +120,7 @@ class NewsItem(NewsTreeItem):
class RecipeModel(QAbstractItemModel, SearchQueryParser): class RecipeModel(QAbstractItemModel, SearchQueryParser):
LOCATIONS = ['all'] LOCATIONS = ['all']
searched = pyqtSignal(object)
def __init__(self, db, *args): def __init__(self, db, *args):
QAbstractItemModel.__init__(self, *args) QAbstractItemModel.__init__(self, *args)
@ -254,14 +255,17 @@ class RecipeModel(QAbstractItemModel, SearchQueryParser):
return results return results
def search(self, query): def search(self, query):
results = []
try: try:
results = self.parse(unicode(query)) query = unicode(query).strip()
if not results: if query:
results = None results = self.parse(query)
if not results:
results = None
except ParseException: except ParseException:
results = [] results = []
self.do_refresh(restrict_to_urns=results) self.do_refresh(restrict_to_urns=results)
self.emit(SIGNAL('searched(PyQt_PyObject)'), True) self.searched.emit(True)
def columnCount(self, parent): def columnCount(self, parent):
return 1 return 1