mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Fix #5856 (No Easy/Intuitive way to refresh a Search Query)
This commit is contained in:
commit
9b3875ea43
@ -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
|
||||||
|
@ -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)
|
|
@ -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">
|
||||||
|
@ -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
|
||||||
|
Loading…
x
Reference in New Issue
Block a user