[meld] Implement find previous and replace all.



commit 38092d1331d681736fb894da3bb2e876521e725a
Author: Stephen Kennedy <stevek gnome org>
Date:   Fri Apr 17 22:57:33 2009 +0100

    Implement find previous and replace all.
    Remove popup dialog when text not found - change the bg instead.
    Improve the logic of single replace - make sure the user has seen
    the match we are about to replace
---
 findbar.py           |   51 +++++++++++++++++++++++++++++++++++++++----------
 glade2/findbar.glade |    5 ++-
 2 files changed, 43 insertions(+), 13 deletions(-)

diff --git a/findbar.py b/findbar.py
index 71d8719..60bd380 100644
--- a/findbar.py
+++ b/findbar.py
@@ -27,6 +27,7 @@ class FindBar(gnomeglade.Component):
         gnomeglade.Component.__init__(self, paths.share_dir("glade2/findbar.glade"), "findbar")
         gnomeglade.connect_signal_handlers(self)
         self.textview = None
+        self.orig_base_color = self.find_entry.get_style().base[0]
 
     def hide(self):
         self.textview = None
@@ -37,6 +38,7 @@ class FindBar(gnomeglade.Component):
         self.replace_label.hide()
         self.replace_entry.hide()
         self.replace_button.hide()
+        self.replace_all_button.hide()
         self.widget.show()
         self.find_entry.grab_focus()
 
@@ -64,24 +66,43 @@ class FindBar(gnomeglade.Component):
     def on_find_next_button__clicked(self, button):
         self._find_text()
 
+    def on_find_previous_button__clicked(self, button):
+        self._find_text(backwards=True)
+
     def on_replace_button__clicked(self, entry):
         buf = self.textview.get_buffer()
-        oldpos = buf.props.cursor_position
-        self._find_text(0)
-        if buf.props.cursor_position == oldpos:
+        oldsel = buf.get_selection_bounds()
+        match = self._find_text(0)
+        newsel = buf.get_selection_bounds()
+        # only replace if there is a match at the cursor and it was already selected
+        if match and oldsel and oldsel[0].equal(newsel[0]) and oldsel[1].equal(newsel[1]):
             buf.begin_user_action()
             buf.delete_selection(False,False)
             buf.insert_at_cursor( self.replace_entry.get_text() )
             self._find_text( 0 )
             buf.end_user_action()
 
+    def on_replace_all_button__clicked(self, entry):
+        buf = self.textview.get_buffer()
+        saved_insert = buf.create_mark(None, buf.get_iter_at_mark(buf.get_insert()), True)
+        buf.begin_user_action()
+        while self._find_text(0):
+            buf.delete_selection(False,False)
+            buf.insert_at_cursor( self.replace_entry.get_text() )
+        buf.end_user_action()
+        if not saved_insert.get_deleted():
+            buf.place_cursor( buf.get_iter_at_mark(saved_insert) )
+            self.textview.scroll_to_mark(buf.get_insert(), 0.25)
+
+    def on_find_entry__changed(self, entry):
+        entry.modify_base( gtk.STATE_NORMAL, self.orig_base_color )
+
         #
         # find/replace buffer
         #
-    def _find_text(self, start_offset=1):
+    def _find_text(self, start_offset=1, backwards=False, wrap=True):
         match_case = self.match_case.get_active()
         whole_word = self.whole_word.get_active()
-        wrap = 1
         regex = self.regex.get_active()
         assert self.textview
         buf = self.textview.get_buffer()
@@ -98,19 +119,27 @@ class FindBar(gnomeglade.Component):
         except re.error, e:
             misc.run_dialog( _("Regular expression error\n'%s'") % e, self, messagetype=gtk.MESSAGE_ERROR)
         else:
-            match = pattern.search(text, insert.get_offset() + start_offset)
-            if match == None and wrap:
-                match = pattern.search(text, 0)
+            if backwards == False:
+                match = pattern.search(text, insert.get_offset() + start_offset)
+                if match == None and wrap:
+                    match = pattern.search(text, 0)
+            else:
+                match = None
+                for m in pattern.finditer(text, 0, insert.get_offset()):
+                    match = m
+                if match == None and wrap:
+                    for m in pattern.finditer(text, insert.get_offset()):
+                        match = m
             if match:
                 it = buf.get_iter_at_offset( match.start() )
                 buf.place_cursor( it )
                 it.forward_chars( match.end() - match.start() )
                 buf.move_mark( buf.get_selection_bound(), it )
                 self.textview.scroll_to_mark(buf.get_insert(), 0.25)
-            elif regex:
-                misc.run_dialog( _("The regular expression '%s' was not found.") % tofind_utf8, self, messagetype=gtk.MESSAGE_INFO)
+                return True
             else:
-                misc.run_dialog( _("The text '%s' was not found.") % tofind_utf8, self, messagetype=gtk.MESSAGE_INFO)
+                buf.place_cursor( buf.get_iter_at_mark(buf.get_insert()) )
+                self.find_entry.modify_base(gtk.STATE_NORMAL, gtk.gdk.color_parse("#ffdddd"))
 
 def findbar_create(str1, str2, int1, int2):
     return FindBar().widget
diff --git a/glade2/findbar.glade b/glade2/findbar.glade
index 9e3cdfc..a956164 100644
--- a/glade2/findbar.glade
+++ b/glade2/findbar.glade
@@ -31,8 +31,8 @@
             <child>
               <widget class="GtkButton" id="replace_all_button">
                 <property name="can_focus">True</property>
+                <property name="visible">True</property>
                 <property name="receives_default">True</property>
-                <property name="no_show_all">True</property>
                 <property name="label" translatable="yes">Replace _All</property>
                 <property name="use_underline">True</property>
                 <property name="focus_on_click">False</property>
@@ -58,11 +58,12 @@
             <property name="layout_style">GTK_BUTTONBOX_START</property>
             <child>
               <widget class="GtkButton" id="find_previous_button">
+                <property name="visible">True</property>
                 <property name="can_focus">True</property>
                 <property name="receives_default">True</property>
-                <property name="no_show_all">True</property>
                 <property name="label" translatable="yes">_Previous</property>
                 <property name="use_underline">True</property>
+                <property name="focus_on_click">False</property>
                 <property name="response_id">0</property>
               </widget>
             </child>



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]