Edit Book: Add support for saved searches. Click Search->Saved searches to bring up a dialog where you can create and manage saved searches

Needs testing
This commit is contained in:
Kovid Goyal 2014-03-20 22:40:35 +05:30
parent cb2b41f28e
commit 4a34618df4
3 changed files with 52 additions and 1 deletions

View File

@ -106,6 +106,8 @@ class Boss(QObject):
self.gui.image_browser.image_activated.connect(self.image_activated)
self.gui.checkpoints.revert_requested.connect(self.revert_requested)
self.gui.checkpoints.compare_requested.connect(self.compare_requested)
self.gui.saved_searches.run_saved_searches.connect(self.run_saved_searches)
self.gui.central.search_panel.save_search.connect(self.save_search)
def preferences(self):
p = Preferences(self.gui)
@ -683,6 +685,27 @@ class Boss(QObject):
run_search(state, action, ed, name, searchable_names,
self.gui, self.show_editor, self.edit_file, self.show_current_diff, self.add_savepoint, self.rewind_savepoint, self.set_modified)
def saved_searches(self):
self.gui.saved_searches.show(), self.gui.saved_searches.raise_()
def save_search(self):
state = self.gui.central.search_panel.state
self.gui.saved_searches.show(), self.gui.saved_searches.raise_()
self.gui.saved_searches.add_predefined_search(state)
def run_saved_searches(self, searches, action):
ed = self.gui.central.current_editor
name = None
for n, x in editors.iteritems():
if x is ed:
name = n
break
searchable_names = self.gui.file_list.searchable_names
if not searches or not validate_search_request(name, searchable_names, getattr(ed, 'has_marked_text', False), searches[0], self.gui):
return
run_search(searches, action, ed, name, searchable_names,
self.gui, self.show_editor, self.edit_file, self.show_current_diff, self.add_savepoint, self.rewind_savepoint, self.set_modified)
def create_checkpoint(self):
text, ok = QInputDialog.getText(self.gui, _('Choose name'), _(
'Choose a name for the checkpoint.\nYou can later restore the book'

View File

@ -39,6 +39,7 @@ class PushButton(QPushButton):
class HistoryLineEdit(HistoryLineEdit2):
max_history_items = 100
save_search = pyqtSignal()
def __init__(self, parent, clear_msg):
HistoryLineEdit2.__init__(self, parent)
@ -51,6 +52,8 @@ class HistoryLineEdit(HistoryLineEdit2):
menu.addAction(self.clear_msg, self.clear_history)
menu.addAction((_('Enable completion based on search history') if self.disable_popup else _(
'Disable completion based on search history')), self.toggle_popups)
menu.addSeparator()
menu.addAction(_('Save current search'), self.save_search.emit)
menu.exec_(event.globalPos())
def toggle_popups(self):
@ -123,6 +126,7 @@ class SearchWidget(QWidget):
}
search_triggered = pyqtSignal(object)
save_search = pyqtSignal()
def __init__(self, parent=None):
QWidget.__init__(self, parent)
@ -133,6 +137,7 @@ class SearchWidget(QWidget):
self.fl = fl = QLabel(_('&Find:'))
fl.setAlignment(Qt.AlignRight | Qt.AlignCenter)
self.find_text = ft = HistoryLineEdit(self, _('Clear search history'))
ft.save_search.connect(self.save_search)
ft.initialize('tweak_book_find_edit')
ft.returnPressed.connect(lambda : self.search_triggered.emit('find'))
fl.setBuddy(ft)
@ -142,6 +147,7 @@ class SearchWidget(QWidget):
self.rl = rl = QLabel(_('&Replace:'))
rl.setAlignment(Qt.AlignRight | Qt.AlignCenter)
self.replace_text = rt = HistoryLineEdit(self, _('Clear replace history'))
rt.save_search.connect(self.save_search)
rt.initialize('tweak_book_replace_edit')
rl.setBuddy(rt)
l.addWidget(rl, 1, 0)
@ -298,6 +304,7 @@ regex_cache = {}
class SearchPanel(QWidget): # {{{
search_triggered = pyqtSignal(object)
save_search = pyqtSignal()
def __init__(self, parent=None):
QWidget.__init__(self, parent)
@ -316,6 +323,7 @@ class SearchPanel(QWidget): # {{{
l.addWidget(self.widget)
self.restore_state, self.save_state = self.widget.restore_state, self.widget.save_state
self.widget.search_triggered.connect(self.search_triggered)
self.widget.save_search.connect(self.save_search)
self.pre_fill = self.widget.pre_fill
def hide_panel(self):
@ -401,11 +409,16 @@ class SearchesModel(QAbstractListModel):
class EditSearch(Dialog): # {{{
def __init__(self, search=None, search_index=-1, parent=None):
def __init__(self, search=None, search_index=-1, parent=None, state=None):
self.search = search or {}
self.original_name = self.search.get('name', None)
self.search_index = search_index
Dialog.__init__(self, _('Edit search'), 'edit-saved-search', parent=parent)
if state is not None:
self.find.setText(state['find'])
self.replace.setText(state['replace'])
self.case_sensitive.setChecked(state['case_sensitive'])
self.dot_all.setChecked(state['dot_all'])
def sizeHint(self):
ans = Dialog.sizeHint(self)
@ -481,6 +494,8 @@ class SearchDelegate(QStyledItemDelegate):
class SavedSearches(Dialog):
run_saved_searches = pyqtSignal(object, object)
def __init__(self, parent=None):
Dialog.__init__(self, _('Saved Searches'), 'saved-searches', parent=parent)
@ -633,6 +648,7 @@ class SavedSearches(Dialog):
searches.append(search)
if not searches:
return
self.run_saved_searches.emit(searches, action)
def move_entry(self, delta):
rows = {index.row() for index in self.searches.selectionModel().selectedIndexes()} - {-1}
@ -661,6 +677,9 @@ class SavedSearches(Dialog):
def add_search(self):
d = EditSearch(parent=self)
self._add_search(d)
def _add_search(self, d):
if d.exec_() == d.Accepted:
self.model.add_search()
index = self.model.index(self.model.rowCount() - 1)
@ -669,6 +688,10 @@ class SavedSearches(Dialog):
sm.setCurrentIndex(index, sm.ClearAndSelect)
self.show_details()
def add_predefined_search(self, state):
d = EditSearch(parent=self, state=state)
self._add_search(d)
def show_details(self):
self.description.setText(' \n \n ')
i = self.searches.currentIndex()

View File

@ -29,6 +29,7 @@ from calibre.gui2.tweak_book.undo import CheckpointView
from calibre.gui2.tweak_book.preview import Preview
from calibre.gui2.tweak_book.search import SearchPanel
from calibre.gui2.tweak_book.check import Check
from calibre.gui2.tweak_book.search import SavedSearches
from calibre.gui2.tweak_book.toc import TOCViewer
from calibre.gui2.tweak_book.char_select import CharSelect
from calibre.gui2.tweak_book.editor.widget import register_text_editor_actions
@ -221,6 +222,7 @@ class Main(MainWindow):
self.setCentralWidget(self.central)
self.check_book = Check(self)
self.toc_view = TOCViewer(self)
self.saved_searches = SavedSearches(self)
self.image_browser = InsertImage(self, for_browsing=True)
self.insert_char = CharSelect(self)
@ -393,6 +395,7 @@ class Main(MainWindow):
'count', keys=('Ctrl+N'), description=_('Count number of matches'))
self.action_mark = reg(None, _('&Mark selected text'), self.boss.mark_selected_text, 'mark-selected-text', ('Ctrl+Shift+M',), _('Mark selected text'))
self.action_go_to_line = reg(None, _('Go to &line'), self.boss.go_to_line_number, 'go-to-line-number', ('Ctrl+.',), _('Go to line number'))
self.action_saved_searches = reg(None, _('Sa&ved searches'), self.boss.saved_searches, 'saved-searches', (), _('Show the saved searches dialog'))
# Check Book actions
group = _('Check Book')
@ -507,6 +510,8 @@ class Main(MainWindow):
a(self.action_mark)
e.addSeparator()
a(self.action_go_to_line)
e.addSeparator()
a(self.action_saved_searches)
e = b.addMenu(_('&Help'))
a = e.addAction