Fix #5856 (No Easy/Intuitive way to refresh a Search Query)

This commit is contained in:
Kovid Goyal 2010-06-17 07:58:30 -06:00
commit 9b3875ea43
4 changed files with 95 additions and 45 deletions

View File

@ -480,8 +480,8 @@ class DeleteAction(object): # {{{
return return
ids = self._get_selected_ids() ids = self._get_selected_ids()
if not ids: if not ids:
#For some reason the delete dialog reports no selection, so #_get_selected_ids shows a dialog box if nothing is selected, so we
#we need to do it here #do not need to show one here
return return
to_delete = {} to_delete = {}
some_to_delete = False some_to_delete = False

View File

@ -3,22 +3,53 @@ __copyright__ = '2008, Kovid Goyal kovid@kovidgoyal.net'
__docformat__ = 'restructuredtext en' __docformat__ = 'restructuredtext en'
__license__ = 'GPL v3' __license__ = 'GPL v3'
from PyQt4.Qt import Qt, QDialog, QTableWidgetItem, QAbstractItemView, QIcon from PyQt4.Qt import Qt, QDialog, QTableWidgetItem, QAbstractItemView
from calibre.ebooks.metadata import authors_to_string from calibre import strftime
from calibre.gui2.dialogs.delete_matching_from_device_ui import Ui_DeleteMatchingFromDeviceDialog from calibre.ebooks.metadata import authors_to_string, authors_to_sort_string, \
title_sort
from calibre.gui2.dialogs.delete_matching_from_device_ui import \
Ui_DeleteMatchingFromDeviceDialog
from calibre.utils.date import UNDEFINED_DATE
class tableItem(QTableWidgetItem): class tableItem(QTableWidgetItem):
def __init__(self, text): def __init__(self, text):
QTableWidgetItem.__init__(self, text) QTableWidgetItem.__init__(self, text)
self.setFlags(Qt.ItemIsEnabled) self.setFlags(Qt.ItemIsEnabled)
self.sort = text.lower()
def __ge__(self, other): def __ge__(self, other):
return unicode(self.text()).lower() >= unicode(other.text()).lower() return self.sort >= other.sort
def __lt__(self, other): def __lt__(self, other):
return unicode(self.text()).lower() < unicode(other.text()).lower() return self.sort < other.sort
class titleTableItem(tableItem):
def __init__(self, text):
tableItem.__init__(self, text)
self.sort = title_sort(text.lower())
class authorTableItem(tableItem):
def __init__(self, book):
tableItem.__init__(self, authors_to_string(book.authors))
if book.author_sort is not None:
self.sort = book.author_sort.lower()
else:
self.sort = authors_to_sort_string(book.authors).lower()
class dateTableItem(tableItem):
def __init__(self, date):
if date is not None:
tableItem.__init__(self, strftime('%x', date))
self.sort = date
else:
tableItem.__init__(self, '')
self.sort = UNDEFINED_DATE
class DeleteMatchingFromDeviceDialog(QDialog, Ui_DeleteMatchingFromDeviceDialog): class DeleteMatchingFromDeviceDialog(QDialog, Ui_DeleteMatchingFromDeviceDialog):
@ -27,13 +58,16 @@ class DeleteMatchingFromDeviceDialog(QDialog, Ui_DeleteMatchingFromDeviceDialog)
Ui_DeleteMatchingFromDeviceDialog.__init__(self) Ui_DeleteMatchingFromDeviceDialog.__init__(self)
self.setupUi(self) self.setupUi(self)
self.explanation.setText('<p>'+_('All checked books will be '
'<b>permanently deleted</b> from your '
'device. Please verify the list.'+'</p>'))
self.buttonBox.accepted.connect(self.accepted) self.buttonBox.accepted.connect(self.accepted)
self.table.cellClicked.connect(self.cell_clicked) self.table.cellClicked.connect(self.cell_clicked)
self.table.setSelectionMode(QAbstractItemView.NoSelection) self.table.setSelectionMode(QAbstractItemView.NoSelection)
self.table.setColumnCount(5) self.table.setColumnCount(5)
self.table.setHorizontalHeaderLabels(['', _('Location'), _('Title'), self.table.setHorizontalHeaderLabels(
_('Author'), _('Format')]) ['', _('Location'), _('Title'),
del_icon = QIcon(I('list_remove.svg')) _('Author'), _('Date'), _('Format')])
rows = 0 rows = 0
for card in items: for card in items:
rows += len(items[card][1]) rows += len(items[card][1])
@ -42,26 +76,34 @@ class DeleteMatchingFromDeviceDialog(QDialog, Ui_DeleteMatchingFromDeviceDialog)
for card in items: for card in items:
(model,books) = items[card] (model,books) = items[card]
for (id,book) in books: for (id,book) in books:
item = QTableWidgetItem(del_icon, '') item = QTableWidgetItem()
item.setFlags(Qt.ItemIsUserCheckable|Qt.ItemIsEnabled)
item.setCheckState(Qt.Checked)
item.setData(Qt.UserRole, (model, id, book.path)) item.setData(Qt.UserRole, (model, id, book.path))
self.table.setItem(row, 0, item) self.table.setItem(row, 0, item)
self.table.setItem(row, 1, tableItem(card)) self.table.setItem(row, 1, tableItem(card))
self.table.setItem(row, 2, tableItem(book.title)) self.table.setItem(row, 2, titleTableItem(book.title))
self.table.setItem(row, 3, tableItem(authors_to_string(book.authors))) self.table.setItem(row, 3, authorTableItem(book))
self.table.setItem(row, 4, tableItem(book.path.rpartition('.')[2])) self.table.setItem(row, 4, dateTableItem(book.datetime))
self.table.setItem(row, 5, tableItem(book.path.rpartition('.')[2]))
row += 1 row += 1
self.table.setCurrentCell(0, 1)
self.table.resizeColumnsToContents() self.table.resizeColumnsToContents()
self.table.setSortingEnabled(True) self.table.setSortingEnabled(True)
self.table.sortByColumn(2, Qt.AscendingOrder) self.table.sortByColumn(2, Qt.AscendingOrder)
self.table.setCurrentCell(0, 1)
def cell_clicked(self, row, col):
if col == 0:
self.table.setCurrentCell(row, 1)
def accepted(self): def accepted(self):
self.result = [] self.result = []
for row in range(self.table.rowCount()): for row in range(self.table.rowCount()):
if self.table.item(row, 0).checkState() == Qt.Unchecked:
continue
(model, id, path) = self.table.item(row, 0).data(Qt.UserRole).toPyObject() (model, id, path) = self.table.item(row, 0).data(Qt.UserRole).toPyObject()
path = unicode(path) path = unicode(path)
self.result.append((model, id, path)) self.result.append((model, id, path))
return return
def cell_clicked(self, row, col):
if col == 0:
self.table.removeRow(row)

View File

@ -20,6 +20,10 @@
<string>Delete from device</string> <string>Delete from device</string>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout"> <layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="explanation">
</widget>
</item>
<item> <item>
<widget class="QTableWidget" name="table"> <widget class="QTableWidget" name="table">
<property name="sizePolicy"> <property name="sizePolicy">

View File

@ -18,17 +18,20 @@ from calibre.utils.config import prefs
from calibre.utils.search_query_parser import saved_searches from calibre.utils.search_query_parser import saved_searches
class SearchLineEdit(QLineEdit): class SearchLineEdit(QLineEdit):
key_pressed = pyqtSignal(object)
mouse_released = pyqtSignal(object)
focus_out = pyqtSignal(object)
def keyPressEvent(self, event): def keyPressEvent(self, event):
self.emit(SIGNAL('key_pressed(PyQt_PyObject)'), event) self.key_pressed.emit(object)
QLineEdit.keyPressEvent(self, event) QLineEdit.keyPressEvent(self, event)
def mouseReleaseEvent(self, event): def mouseReleaseEvent(self, event):
self.emit(SIGNAL('mouse_released(PyQt_PyObject)'), event) self.mouse_released.emit(event)
QLineEdit.mouseReleaseEvent(self, event) QLineEdit.mouseReleaseEvent(self, event)
def focusOutEvent(self, event): def focusOutEvent(self, event):
self.emit(SIGNAL('focus_out(PyQt_PyObject)'), event) self.focus_out.emit(event)
QLineEdit.focusOutEvent(self, event) QLineEdit.focusOutEvent(self, event)
def dropEvent(self, ev): def dropEvent(self, ev):
@ -68,10 +71,10 @@ class SearchBox2(QComboBox):
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.connect(self.line_edit, SIGNAL('key_pressed(PyQt_PyObject)'), self.line_edit.key_pressed.connect(self.key_pressed,
self.key_pressed, Qt.DirectConnection) type=Qt.DirectConnection)
self.connect(self.line_edit, SIGNAL('mouse_released(PyQt_PyObject)'), self.line_edit.mouse_released.connect(self.mouse_released,
self.mouse_released, Qt.DirectConnection) type=Qt.DirectConnection)
self.setEditable(True) self.setEditable(True)
self.help_state = False self.help_state = False
self.as_you_type = True self.as_you_type = True
@ -90,14 +93,18 @@ class SearchBox2(QComboBox):
self.help_text = help_text self.help_text = help_text
self.colorize = colorize self.colorize = colorize
self.clear_to_help() self.clear_to_help()
self.connect(self, SIGNAL('editTextChanged(QString)'), self.text_edited_slot)
def normalize_state(self): def normalize_state(self):
self.setEditText('') if self.help_state:
self.line_edit.setStyleSheet( self.setEditText('')
'QLineEdit { color: black; background-color: %s; }' % self.line_edit.setStyleSheet(
self.normal_background) 'QLineEdit { color: black; background-color: %s; }' %
self.help_state = False 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): def clear_to_help(self):
if self.help_state: if self.help_state:
@ -131,17 +138,15 @@ class SearchBox2(QComboBox):
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):
if self.help_state: self.normalize_state()
self.normalize_state()
if not self.as_you_type: if not self.as_you_type:
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()
else:
self.timer = self.startTimer(self.__class__.INTERVAL)
def mouse_released(self, event): def mouse_released(self, event):
if self.help_state: self.normalize_state()
self.normalize_state()
def text_edited_slot(self, text):
if self.as_you_type: if self.as_you_type:
self.timer = self.startTimer(self.__class__.INTERVAL) self.timer = self.startTimer(self.__class__.INTERVAL)
@ -227,14 +232,13 @@ class SavedSearchBox(QComboBox):
self.line_edit = SearchLineEdit(self) self.line_edit = SearchLineEdit(self)
self.setLineEdit(self.line_edit) self.setLineEdit(self.line_edit)
self.connect(self.line_edit, SIGNAL('key_pressed(PyQt_PyObject)'), self.line_edit.key_pressed.connect(self.key_pressed,
self.key_pressed, Qt.DirectConnection) type=Qt.DirectConnection)
self.connect(self.line_edit, SIGNAL('mouse_released(PyQt_PyObject)'), self.line_edit.mouse_released.connect(self.mouse_released,
self.mouse_released, Qt.DirectConnection) type=Qt.DirectConnection)
self.connect(self.line_edit, SIGNAL('focus_out(PyQt_PyObject)'), self.line_edit.focus_out.connect(self.focus_out,
self.focus_out, Qt.DirectConnection) type=Qt.DirectConnection)
self.connect(self, SIGNAL('activated(const QString&)'), self.activated[str].connect(self.saved_search_selected)
self.saved_search_selected)
completer = QCompleter(self) # turn off auto-completion completer = QCompleter(self) # turn off auto-completion
self.setCompleter(completer) self.setCompleter(completer)
@ -282,7 +286,7 @@ class SavedSearchBox(QComboBox):
if self.help_state: if self.help_state:
self.normalize_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():
return return