Allow searching for plugins by name in the install plugins dialog

Merge branch 'master' of https://github.com/tamasmajor/calibre
This commit is contained in:
Kovid Goyal 2013-12-06 09:41:26 +05:30
commit 54c6e0e0cd

View File

@ -14,10 +14,12 @@ from PyQt4.Qt import (Qt, QUrl, QFrame, QVBoxLayout, QLabel, QBrush, QTextEdit,
QAbstractTableModel, QVariant, QTableView, QModelIndex,
QSortFilterProxyModel, QAction, QIcon, QDialog,
QFont, QPixmap, QSize)
from PyQt4.QtGui import QLineEdit
from calibre import browser, prints
from calibre.constants import numeric_version, iswindows, isosx, DEBUG
from calibre.customize.ui import (initialized_plugins, is_disabled, remove_plugin,
add_plugin, enable_plugin, disable_plugin,
from calibre.customize.ui import (
initialized_plugins, is_disabled, remove_plugin, add_plugin, enable_plugin, disable_plugin,
NameConflict, has_external_plugins)
from calibre.gui2 import error_dialog, question_dialog, info_dialog, NONE, open_url, gprefs
from calibre.gui2.preferences.plugins import ConfigWidget
@ -105,6 +107,7 @@ def get_installed_plugin_status(display_plugin):
class ImageTitleLayout(QHBoxLayout):
'''
A reusable layout widget displaying an image followed by a title
'''
@ -130,6 +133,7 @@ class ImageTitleLayout(QHBoxLayout):
class SizePersistedDialog(QDialog):
'''
This dialog is a base class for any dialogs that want their size/position
restored when they are next opened.
@ -176,6 +180,7 @@ class VersionHistoryDialog(SizePersistedDialog):
class PluginFilterComboBox(QComboBox):
def __init__(self, parent):
QComboBox.__init__(self, parent)
items = [_('All'), _('Installed'), _('Update available'), _('Not installed')]
@ -208,6 +213,10 @@ class DisplayPlugin(object):
def is_installed(self):
return self.installed_version is not None
def name_matches_filter(self, filter_text):
# filter_text is already lowercase @set_filter_text
return filter_text in icu_lower(self.name) # case-insensitive filtering
def is_upgrade_available(self):
return self.is_installed() and (self.installed_version < self.available_version
or self.is_deprecated)
@ -233,24 +242,29 @@ class DisplayPluginSortFilterModel(QSortFilterProxyModel):
self.setSortRole(Qt.UserRole)
self.setSortCaseSensitivity(Qt.CaseInsensitive)
self.filter_criteria = FILTER_ALL
self.filter_text = ""
def filterAcceptsRow(self, sourceRow, sourceParent):
index = self.sourceModel().index(sourceRow, 0, sourceParent)
display_plugin = self.sourceModel().display_plugins[index.row()]
if self.filter_criteria == FILTER_ALL:
return not (display_plugin.is_deprecated and not display_plugin.is_installed())
return not (display_plugin.is_deprecated and not display_plugin.is_installed()) and display_plugin.name_matches_filter(self.filter_text)
if self.filter_criteria == FILTER_INSTALLED:
return display_plugin.is_installed()
return display_plugin.is_installed() and display_plugin.name_matches_filter(self.filter_text)
if self.filter_criteria == FILTER_UPDATE_AVAILABLE:
return display_plugin.is_upgrade_available()
return display_plugin.is_upgrade_available() and display_plugin.name_matches_filter(self.filter_text)
if self.filter_criteria == FILTER_NOT_INSTALLED:
return not display_plugin.is_installed() and not display_plugin.is_deprecated
return not display_plugin.is_installed() and not display_plugin.is_deprecated and display_plugin.name_matches_filter(self.filter_text)
return False
def set_filter_criteria(self, filter_value):
self.filter_criteria = filter_value
self.invalidateFilter()
def set_filter_text(self, filter_text_value):
self.filter_text = icu_lower(unicode(filter_text_value))
self.invalidateFilter()
class DisplayPluginModel(QAbstractTableModel):
@ -456,6 +470,14 @@ class PluginUpdaterDialog(SizePersistedDialog):
header_layout.addWidget(self.filter_combo)
header_layout.addStretch(10)
# filter plugins by name
header_layout.addWidget(QLabel(_('Filter by name')+':', self))
self.filter_by_name_lineedit = QLineEdit(self)
self.filter_by_name_lineedit.setText("")
self.filter_by_name_lineedit.textChanged.connect(self._filter_name_lineedit_changed)
header_layout.addWidget(self.filter_by_name_lineedit)
self.plugin_view = QTableView(self)
self.plugin_view.horizontalHeader().setStretchLastSection(True)
self.plugin_view.setSelectionBehavior(QAbstractItemView.SelectRows)
@ -601,6 +623,7 @@ class PluginUpdaterDialog(SizePersistedDialog):
self.plugin_view.setFocus()
def _filter_combo_changed(self, idx):
self.filter_by_name_lineedit.setText("") # clear the name filter text when a different group was selected
self.proxy_model.set_filter_criteria(idx)
if idx == FILTER_NOT_INSTALLED:
self.plugin_view.sortByColumn(5, Qt.DescendingOrder)
@ -608,6 +631,9 @@ class PluginUpdaterDialog(SizePersistedDialog):
self.plugin_view.sortByColumn(0, Qt.AscendingOrder)
self._select_and_focus_view()
def _filter_name_lineedit_changed(self, text):
self.proxy_model.set_filter_text(text) # set the filter text for filterAcceptsRow
def _forum_label_activated(self):
if self.forum_link:
open_url(QUrl(self.forum_link))