Add a search for individual tweaks to Preferences->Tweaks

This commit is contained in:
Kovid Goyal 2011-08-23 00:29:02 -06:00
parent 2afef9211e
commit b3f5484cbe
3 changed files with 174 additions and 20 deletions

View File

@ -173,6 +173,8 @@ def _config(): # {{{
help='Search history for the plugin preferences') help='Search history for the plugin preferences')
c.add_opt('shortcuts_search_history', default=[], c.add_opt('shortcuts_search_history', default=[],
help='Search history for the keyboard preferences') help='Search history for the keyboard preferences')
c.add_opt('tweaks_search_history', default=[],
help='Search history for tweaks')
c.add_opt('worker_limit', default=6, c.add_opt('worker_limit', default=6,
help=_( help=_(
'Maximum number of simultaneous conversion/news download jobs. ' 'Maximum number of simultaneous conversion/news download jobs. '

View File

@ -9,14 +9,19 @@ import textwrap
from calibre.gui2.preferences import ConfigWidgetBase, test_widget, AbortCommit from calibre.gui2.preferences import ConfigWidgetBase, test_widget, AbortCommit
from calibre.gui2.preferences.tweaks_ui import Ui_Form from calibre.gui2.preferences.tweaks_ui import Ui_Form
from calibre.gui2 import error_dialog, NONE from calibre.gui2 import error_dialog, NONE, info_dialog
from calibre.utils.config import read_raw_tweaks, write_tweaks from calibre.utils.config import read_raw_tweaks, write_tweaks
from calibre.gui2.widgets import PythonHighlighter from calibre.gui2.widgets import PythonHighlighter
from calibre import isbytestring from calibre import isbytestring
from calibre.utils.icu import lower
from calibre.utils.search_query_parser import (ParseException,
SearchQueryParser)
from PyQt4.Qt import (QAbstractListModel, Qt, QStyledItemDelegate, QStyle, from PyQt4.Qt import (QAbstractListModel, Qt, QStyledItemDelegate, QStyle,
QStyleOptionViewItem, QFont, QDialogButtonBox, QDialog, QStyleOptionViewItem, QFont, QDialogButtonBox, QDialog,
QVBoxLayout, QPlainTextEdit, QLabel) QVBoxLayout, QPlainTextEdit, QLabel, QModelIndex)
ROOT = QModelIndex()
class Delegate(QStyledItemDelegate): # {{{ class Delegate(QStyledItemDelegate): # {{{
def __init__(self, view): def __init__(self, view):
@ -35,7 +40,7 @@ class Delegate(QStyledItemDelegate): # {{{
class Tweak(object): # {{{ class Tweak(object): # {{{
def __init__(self, name, doc, var_names, defaults, custom): def __init__(self, name, doc, var_names, defaults, custom):
translate = __builtins__['_'] translate = _
self.name = translate(name) self.name = translate(name)
self.doc = translate(doc.strip()) self.doc = translate(doc.strip())
self.var_names = var_names self.var_names = var_names
@ -87,10 +92,11 @@ class Tweak(object): # {{{
# }}} # }}}
class Tweaks(QAbstractListModel): # {{{ class Tweaks(QAbstractListModel, SearchQueryParser): # {{{
def __init__(self, parent=None): def __init__(self, parent=None):
QAbstractListModel.__init__(self, parent) QAbstractListModel.__init__(self, parent)
SearchQueryParser.__init__(self, ['all'])
raw_defaults, raw_custom = read_raw_tweaks() raw_defaults, raw_custom = read_raw_tweaks()
self.parse_tweaks(raw_defaults, raw_custom) self.parse_tweaks(raw_defaults, raw_custom)
@ -223,6 +229,54 @@ class Tweaks(QAbstractListModel): # {{{
def set_plugin_tweaks(self, d): def set_plugin_tweaks(self, d):
self.plugin_tweaks = d self.plugin_tweaks = d
def universal_set(self):
return set(xrange(self.rowCount()))
def get_matches(self, location, query, candidates=None):
if candidates is None:
candidates = self.universal_set()
ans = set()
if not query:
return ans
query = lower(query)
for r in candidates:
dat = self.data(self.index(r), Qt.UserRole)
if query in lower(dat.name):# or query in lower(dat.doc):
ans.add(r)
return ans
def find(self, query):
query = query.strip()
if not query:
return ROOT
matches = self.parse(query)
if not matches:
return ROOT
matches = list(sorted(matches))
return self.index(matches[0])
def find_next(self, idx, query, backwards=False):
query = query.strip()
if not query:
return idx
matches = self.parse(query)
if not matches:
return idx
loc = idx.row()
if loc not in matches:
return self.find(query)
if len(matches) == 1:
return ROOT
matches = list(sorted(matches))
i = matches.index(loc)
if backwards:
ans = i - 1 if i - 1 >= 0 else len(matches)-1
else:
ans = i + 1 if i + 1 < len(matches) else 0
ans = matches[ans]
return self.index(ans)
# }}} # }}}
class PluginTweaks(QDialog): # {{{ class PluginTweaks(QDialog): # {{{
@ -257,12 +311,18 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form):
self.delegate = Delegate(self.tweaks_view) self.delegate = Delegate(self.tweaks_view)
self.tweaks_view.setItemDelegate(self.delegate) self.tweaks_view.setItemDelegate(self.delegate)
self.tweaks_view.currentChanged = self.current_changed self.tweaks_view.currentChanged = self.current_changed
self.view = self.tweaks_view
self.highlighter = PythonHighlighter(self.edit_tweak.document()) self.highlighter = PythonHighlighter(self.edit_tweak.document())
self.restore_default_button.clicked.connect(self.restore_to_default) self.restore_default_button.clicked.connect(self.restore_to_default)
self.apply_button.clicked.connect(self.apply_tweak) self.apply_button.clicked.connect(self.apply_tweak)
self.plugin_tweaks_button.clicked.connect(self.plugin_tweaks) self.plugin_tweaks_button.clicked.connect(self.plugin_tweaks)
self.splitter.setStretchFactor(0, 1) self.splitter.setStretchFactor(0, 1)
self.splitter.setStretchFactor(1, 100) self.splitter.setStretchFactor(1, 100)
self.next_button.clicked.connect(self.find_next)
self.previous_button.clicked.connect(self.find_previous)
self.search.initialize('tweaks_search_history', help_text=
_('Search for tweak'))
self.search.search.connect(self.find)
def plugin_tweaks(self): def plugin_tweaks(self):
@ -290,7 +350,7 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form):
self.changed_signal.emit() self.changed_signal.emit()
def initialize(self): def initialize(self):
self.tweaks = Tweaks() self.tweaks = self._model = Tweaks()
self.tweaks_view.setModel(self.tweaks) self.tweaks_view.setModel(self.tweaks)
def restore_to_default(self, *args): def restore_to_default(self, *args):
@ -338,6 +398,45 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form):
ConfigWidgetBase.commit(self) ConfigWidgetBase.commit(self)
return True return True
def find(self, query):
if not query:
return
try:
idx = self._model.find(query)
except ParseException:
self.search.search_done(False)
return
self.search.search_done(True)
if not idx.isValid():
info_dialog(self, _('No matches'),
_('Could not find any shortcuts matching %s')%query,
show=True, show_copy_button=False)
return
self.highlight_index(idx)
def highlight_index(self, idx):
if not idx.isValid(): return
self.view.scrollTo(idx)
self.view.selectionModel().select(idx,
self.view.selectionModel().ClearAndSelect)
self.view.setCurrentIndex(idx)
def find_next(self, *args):
idx = self.view.currentIndex()
if not idx.isValid():
idx = self._model.index(0)
idx = self._model.find_next(idx,
unicode(self.search.currentText()))
self.highlight_index(idx)
def find_previous(self, *args):
idx = self.view.currentIndex()
if not idx.isValid():
idx = self._model.index(0)
idx = self._model.find_next(idx,
unicode(self.search.currentText()), backwards=True)
self.highlight_index(idx)
if __name__ == '__main__': if __name__ == '__main__':
from PyQt4.Qt import QApplication from PyQt4.Qt import QApplication

View File

@ -6,7 +6,7 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>660</width> <width>756</width>
<height>531</height> <height>531</height>
</rect> </rect>
</property> </property>
@ -14,8 +14,24 @@
<string>Form</string> <string>Form</string>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout_4"> <layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<widget class="QLabel" name="label_18">
<property name="text">
<string>Values for the tweaks are shown below. Edit them to change the behavior of calibre. Your changes will only take effect &lt;b&gt;after a restart&lt;/b&gt; of calibre.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item> <item>
<widget class="QSplitter" name="splitter"> <widget class="QSplitter" name="splitter">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>10</verstretch>
</sizepolicy>
</property>
<property name="orientation"> <property name="orientation">
<enum>Qt::Horizontal</enum> <enum>Qt::Horizontal</enum>
</property> </property>
@ -24,16 +40,6 @@
</property> </property>
<widget class="QWidget" name="layoutWidget"> <widget class="QWidget" name="layoutWidget">
<layout class="QVBoxLayout" name="verticalLayout_2"> <layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QLabel" name="label_18">
<property name="text">
<string>Values for the tweaks are shown below. Edit them to change the behavior of calibre. Your changes will only take effect &lt;b&gt;after a restart&lt;/b&gt; of calibre.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item> <item>
<widget class="QListView" name="tweaks_view"> <widget class="QListView" name="tweaks_view">
<property name="sizePolicy"> <property name="sizePolicy">
@ -72,8 +78,8 @@
</layout> </layout>
</widget> </widget>
<widget class="QWidget" name="layoutWidget"> <widget class="QWidget" name="layoutWidget">
<layout class="QVBoxLayout" name="verticalLayout_3"> <layout class="QGridLayout" name="gridLayout_3">
<item> <item row="1" column="0" colspan="3">
<widget class="QGroupBox" name="groupBox"> <widget class="QGroupBox" name="groupBox">
<property name="title"> <property name="title">
<string>Help</string> <string>Help</string>
@ -92,7 +98,7 @@
</layout> </layout>
</widget> </widget>
</item> </item>
<item> <item row="2" column="0" colspan="3">
<widget class="QGroupBox" name="groupBox_2"> <widget class="QGroupBox" name="groupBox_2">
<property name="title"> <property name="title">
<string>Edit tweak</string> <string>Edit tweak</string>
@ -128,12 +134,59 @@
</layout> </layout>
</widget> </widget>
</item> </item>
<item row="0" column="0">
<widget class="SearchBox2" name="search">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>10</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="sizeAdjustPolicy">
<enum>QComboBox::AdjustToMinimumContentsLength</enum>
</property>
<property name="minimumContentsLength">
<number>10</number>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QPushButton" name="next_button">
<property name="text">
<string>&amp;Next</string>
</property>
<property name="icon">
<iconset resource="../../../../resources/images.qrc">
<normaloff>:/images/arrow-down.png</normaloff>:/images/arrow-down.png</iconset>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QPushButton" name="previous_button">
<property name="text">
<string>&amp;Previous</string>
</property>
<property name="icon">
<iconset resource="../../../../resources/images.qrc">
<normaloff>:/images/arrow-up.png</normaloff>:/images/arrow-up.png</iconset>
</property>
</widget>
</item>
</layout> </layout>
</widget> </widget>
</widget> </widget>
</item> </item>
</layout> </layout>
</widget> </widget>
<resources/> <customwidgets>
<customwidget>
<class>SearchBox2</class>
<extends>QComboBox</extends>
<header>calibre/gui2/search_box.h</header>
</customwidget>
</customwidgets>
<resources>
<include location="../../../../resources/images.qrc"/>
</resources>
<connections/> <connections/>
</ui> </ui>