Implement the replace all and count actions

This commit is contained in:
Kovid Goyal 2013-11-15 11:32:05 +05:30
parent 2f38fb20b7
commit 2a48eb80bb
3 changed files with 65 additions and 0 deletions

View File

@ -374,6 +374,36 @@ class Boss(QObject):
'Currently selected text does not match the search query.'))
return True
def count_message(action, count):
msg = _('%(action)s %(num)s occurrences of %(query)s' % dict(num=count, query=state['find'], action=action))
info_dialog(self.gui, _('Searching done'), msg, show=True)
def do_all(replace=True):
count = 0
if not files and editor is None:
return 0
lfiles = files or {name:editor.syntax}
for n, syntax in lfiles.iteritems():
if n in editors:
raw = editors[n].get_raw_data()
else:
raw = current_container().raw_data(n)
if replace:
raw, num = pat.subn(state['replace'], raw)
else:
num = len(pat.findall(raw))
count += num
if replace and num > 0:
if n in editors:
editors[n].replace_data(raw)
else:
with current_container().open(n, 'wb') as f:
f.write(raw.encode('utf-8'))
QApplication.restoreOverrideCursor()
count_message(_('Replaced') if replace else _('Found'), count)
return count
QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
try:
if action == 'find':
@ -382,6 +412,18 @@ class Boss(QObject):
return do_replace()
if action == 'replace-find' and do_replace():
return do_find()
if action == 'replace-all':
if marked:
return count_message(_('Replaced'), editor.all_in_marked(pat, state['replace']))
self.add_savepoint(_('Replace all'))
count = do_all()
if count == 0:
self.rewind_savepoint()
return
if action == 'count':
if marked:
return count_message(_('Found'), editor.all_in_marked(pat))
return do_all(replace=False)
finally:
QApplication.restoreOverrideCursor()

View File

@ -141,6 +141,7 @@ class TextEdit(QPlainTextEdit):
sel.append(self.current_search_mark)
self.setExtraSelections(sel)
# Search and replace {{{
def mark_selected_text(self):
sel = QTextEdit.ExtraSelection()
sel.format.setBackground(self.highlight_color)
@ -196,6 +197,22 @@ class TextEdit(QPlainTextEdit):
self.setTextCursor(c)
return True
def all_in_marked(self, pat, template=None):
if self.current_search_mark is None:
return 0
c = self.current_search_mark.cursor
raw = unicode(c.selectedText()).replace(PARAGRAPH_SEPARATOR, '\n')
if template is None:
count = len(pat.findall(raw))
else:
raw, count = pat.subn(template, raw)
if count > 0:
c.setKeepPositionOnInsert(True)
c.insertText(raw)
c.setKeepPositionOnInsert(False)
self.update_extra_selections()
return count
def find(self, pat, wrap=False, marked=False, complete=False):
if marked:
return self.find_in_marked(pat, wrap=wrap)
@ -242,6 +259,7 @@ class TextEdit(QPlainTextEdit):
text = m.expand(template)
c.insertText(text)
return True
# }}}
# Line numbers and cursor line {{{
def highlight_cursor_line(self):

View File

@ -67,6 +67,7 @@ class Editor(QMainWindow):
def redo(self):
self.editor.redo()
# Search and replace {{{
def mark_selected_text(self):
self.editor.mark_selected_text()
@ -76,6 +77,10 @@ class Editor(QMainWindow):
def replace(self, *args, **kwargs):
return self.editor.replace(*args, **kwargs)
def all_in_marked(self, *args, **kwargs):
return self.editor.all_in_marked(*args, **kwargs)
# }}}
@property
def has_marked_text(self):
return self.editor.current_search_mark is not None