mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-08 10:44:09 -04:00
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:
parent
cb2b41f28e
commit
4a34618df4
@ -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'
|
||||
|
@ -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()
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user