[gnome-latex: 133/205] Replace: under the source view instead of a dialog



commit f8a699f3e59e503daac4a4434c4137aef96a2eb7
Author: Sébastien Wilmet <sebastien wilmet gmail com>
Date:   Tue Dec 8 22:11:58 2009 +0100

    Replace: under the source view instead of a dialog

 TODO            |   2 +-
 src/callbacks.c | 260 ++++++++++++++++++++++++++++++--------------------------
 src/callbacks.h |   4 +
 src/main.c      |  74 ++++++++++++++++
 src/main.h      |   5 ++
 5 files changed, 223 insertions(+), 122 deletions(-)
---
diff --git a/TODO b/TODO
index a7e00c4..e25cdf2 100644
--- a/TODO
+++ b/TODO
@@ -8,4 +8,4 @@ TODO LaTeXila
 
 [-] BibTeX support
 
-[-] search and replace like the Goto Line (under the source view)
+[x] search and replace like the Goto Line (under the source view)
diff --git a/src/callbacks.c b/src/callbacks.c
index 72f2f58..c97acdf 100644
--- a/src/callbacks.c
+++ b/src/callbacks.c
@@ -349,6 +349,9 @@ cb_find (void)
        if (latexila.active_doc == NULL)
                return;
 
+       // reset the background color
+       set_entry_background (latexila.under_source_view.find_entry, FALSE);
+
        gtk_widget_show_all (latexila.under_source_view.find);
        gtk_widget_grab_focus (latexila.under_source_view.find_entry);
 }
@@ -386,158 +389,173 @@ cb_find_previous (GtkWidget *widget, gpointer user_data)
 }
 
 void
-cb_replace (void)
+cb_close_replace (GtkWidget *widget, gpointer user_data)
 {
+       gtk_widget_hide (latexila.under_source_view.replace);
+
+       guint context_id = gtk_statusbar_get_context_id (latexila.statusbar,
+                       "replace");
+       gtk_statusbar_pop (latexila.statusbar, context_id);
+       
        if (latexila.active_doc == NULL)
                return;
 
-       GtkWidget *dialog = gtk_dialog_new ();
-       gtk_window_set_title (GTK_WINDOW (dialog), _("Replace"));
-       gtk_dialog_add_buttons (GTK_DIALOG (dialog),
-                       GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,
-                       _("Replace All"), GTK_RESPONSE_APPLY,
-                       NULL);
+       gtk_widget_grab_focus (latexila.active_doc->source_view);
+}
 
-       // button replace
-       // we must set the sensitivity of this button so we create it by hand
-       GtkWidget *button_replace = gtk_button_new_with_label (_("Replace"));
-       GtkWidget *icon = gtk_image_new_from_stock (GTK_STOCK_FIND_AND_REPLACE,
-                       GTK_ICON_SIZE_BUTTON);
-       gtk_button_set_image (GTK_BUTTON (button_replace), icon);
-       gtk_dialog_add_action_widget (GTK_DIALOG (dialog), button_replace,
-                       GTK_RESPONSE_YES);
+void
+cb_replace_find (GtkWidget *widget, gpointer user_data)
+{
+       if (latexila.active_doc == NULL)
+               return;
+
+       guint context_id = gtk_statusbar_get_context_id (latexila.statusbar,
+                       "replace");
 
-       gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_FIND, GTK_RESPONSE_OK);
+       const gchar *what = gtk_entry_get_text (
+                       GTK_ENTRY (latexila.under_source_view.replace_entry_search));
 
+       gboolean tmp = gtk_toggle_button_get_active (
+                       GTK_TOGGLE_BUTTON (latexila.under_source_view.replace_match_case));
+       GtkSourceSearchFlags flags = tmp ? 0 : GTK_SOURCE_SEARCH_CASE_INSENSITIVE;
 
-       GtkWidget *content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
-       GtkWidget *table = gtk_table_new (2, 2, FALSE);
+       GtkTextIter match_start, match_end;
+
+       gboolean match_found = find_next_match (what, flags, FALSE, &match_start,
+                       &match_end);
+       if (! match_found)
+       {
+               gtk_statusbar_pop (latexila.statusbar, context_id);
+               gtk_statusbar_push (latexila.statusbar, context_id,
+                               _("Phrase not found"));
 
-       GtkWidget *label = gtk_label_new (_("Search for:"));
-       // align the label to the left
-       gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
-       GtkWidget *entry_search = gtk_entry_new ();
-       gtk_table_attach_defaults (GTK_TABLE (table), label, 0, 1, 0, 1);
-       gtk_table_attach_defaults (GTK_TABLE (table), entry_search, 1, 2, 0, 1);
+               gtk_widget_set_sensitive (latexila.under_source_view.replace_button,
+                               FALSE);
 
-       label = gtk_label_new (_("Replace with:"));
-       gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
-       GtkWidget *entry_replace = gtk_entry_new ();
-       gtk_table_attach_defaults (GTK_TABLE (table), label, 0, 1, 1, 2);
-       gtk_table_attach_defaults (GTK_TABLE (table), entry_replace, 1, 2, 1, 2);
+               // red background
+               set_entry_background (latexila.under_source_view.replace_entry_search,
+                               TRUE);
+       }
+       else
+       {
+               gtk_statusbar_pop (latexila.statusbar, context_id);
 
-       gtk_box_pack_start (GTK_BOX (content_area), table, TRUE, TRUE, 5);
+               gtk_widget_set_sensitive (latexila.under_source_view.replace_button,
+                               TRUE);
 
-       GtkWidget *case_sensitive = gtk_check_button_new_with_label (
-                       _("Case sensitive"));
-       gtk_box_pack_start (GTK_BOX (content_area), case_sensitive, TRUE, TRUE, 5);
+               // normal background
+               set_entry_background (latexila.under_source_view.replace_entry_search,
+                               FALSE);
+       }
+}
 
-       gtk_widget_show_all (content_area);
+void
+cb_replace_replace (GtkWidget *widget, gpointer user_data)
+{
+       if (latexila.active_doc == NULL)
+               return;
 
        GtkTextBuffer *buffer = GTK_TEXT_BUFFER (latexila.active_doc->source_buffer);
 
-       /* backward desactivated because there is a little problem with the position
-        * of the insert mark after making a replacement... The insert mark should
-        * be at the beginning of the replacement and not at the end.
-        */
-       gboolean backward = FALSE;
+       const gchar *replacement = gtk_entry_get_text (
+                       GTK_ENTRY (latexila.under_source_view.replace_entry_replace));
 
-       guint context_id = gtk_statusbar_get_context_id (latexila.statusbar,
-                       "searching");
+       GtkTextIter match_start, match_end;
+       gtk_text_buffer_get_selection_bounds (buffer, &match_start, &match_end);
 
-       gboolean stop = FALSE;
-       gboolean match_found = FALSE;
-       GtkTextIter match_start, match_end, iter;
-       while (! stop)
-       {
-               gtk_widget_set_sensitive (button_replace, match_found);
-               gint result = gtk_dialog_run (GTK_DIALOG (dialog));
+       gtk_text_buffer_begin_user_action (buffer);
+       gtk_text_buffer_delete (buffer, &match_start, &match_end);
+       gtk_text_buffer_insert (buffer, &match_start, replacement, -1);
+       gtk_text_buffer_end_user_action (buffer);
+
+       cb_replace_find (NULL, NULL);
+}
 
-               const gchar *what = gtk_entry_get_text (GTK_ENTRY (entry_search));
-               const gchar *replacement = gtk_entry_get_text (GTK_ENTRY (entry_replace));
+void
+cb_replace_replace_all (GtkWidget *widget, gpointer user_data)
+{
+       if (latexila.active_doc == NULL)
+               return;
 
-               gboolean tmp = gtk_toggle_button_get_active (
-                               GTK_TOGGLE_BUTTON (case_sensitive));
-               GtkSourceSearchFlags flags = tmp ? 0 : GTK_SOURCE_SEARCH_CASE_INSENSITIVE;
+       const gchar *what = gtk_entry_get_text (
+                       GTK_ENTRY (latexila.under_source_view.replace_entry_search));
+       const gchar *replacement = gtk_entry_get_text (
+                       GTK_ENTRY (latexila.under_source_view.replace_entry_replace));
 
-               switch (result)
-               {
-                       case GTK_RESPONSE_CLOSE:
-                               stop = TRUE;
-                               break;
+       gboolean tmp = gtk_toggle_button_get_active (
+                       GTK_TOGGLE_BUTTON (latexila.under_source_view.replace_match_case));
+       GtkSourceSearchFlags flags = tmp ? 0 : GTK_SOURCE_SEARCH_CASE_INSENSITIVE;
 
-                       /* replace all */
-                       case GTK_RESPONSE_APPLY:
-                               gtk_text_buffer_begin_user_action (buffer);
-
-                               // begin at the start of the buffer
-                               gtk_text_buffer_get_start_iter (buffer, &iter);
-                               gint i = 0;
-                               while (gtk_source_iter_forward_search (&iter, what, flags,
-                                                       &match_start, &match_end, NULL))
-                               {
-                                       // make the replacement
-                                       gtk_text_buffer_delete (buffer, &match_start, &match_end);
-                                       gtk_text_buffer_insert (buffer, &match_start, replacement, -1);
-
-                                       // iter points to the end of the inserted text
-                                       iter = match_start;
-
-                                       i++;
-                               }
-
-                               gtk_text_buffer_end_user_action (buffer);
-
-                               // print a message in the statusbar
-                               gchar *msg;
-                               if (i == 0)
-                                       msg = g_strdup (_("Phrase not found"));
-                               else if (i == 1)
-                                       msg = g_strdup (_("Found and replaced one occurence"));
-                               else
-                                       msg = g_strdup_printf (_("Found and replaced %d occurences"), i);
-
-                               gtk_statusbar_pop (latexila.statusbar, context_id);
-                               gtk_statusbar_push (latexila.statusbar, context_id, msg);
-                               g_free (msg);
+       GtkTextBuffer *buffer = GTK_TEXT_BUFFER (latexila.active_doc->source_buffer);
 
-                               break;
+       GtkTextIter match_start, match_end, iter;
 
-                       /* replace */
-                       case GTK_RESPONSE_YES:
-                               // the user must find the first match
-                               if (! match_found)
-                                       break;
+       gtk_text_buffer_begin_user_action (buffer);
 
-                               gtk_text_buffer_begin_user_action (buffer);
-                               gtk_text_buffer_delete (buffer, &match_start, &match_end);
-                               gtk_text_buffer_insert (buffer, &match_start, replacement, -1);
-                               gtk_text_buffer_end_user_action (buffer);
+       // begin at the start of the buffer
+       gtk_text_buffer_get_start_iter (buffer, &iter);
+       gint i = 0;
+       while (gtk_source_iter_forward_search (&iter, what, flags, &match_start,
+                               &match_end, NULL))
+       {
+               // make the replacement
+               gtk_text_buffer_delete (buffer, &match_start, &match_end);
+               gtk_text_buffer_insert (buffer, &match_start, replacement, -1);
 
-                               match_found = find_next_match (what, flags, backward,
-                                               &match_start, &match_end);
-                               break;
+               // iter points to the end of the inserted text
+               iter = match_start;
 
-                       /* just find the next match */
-                       case GTK_RESPONSE_OK:
-                               match_found = find_next_match (what, flags, backward,
-                                               &match_start, &match_end);
-                               if (! match_found)
-                               {
-                                       gtk_statusbar_pop (latexila.statusbar, context_id);
-                                       gtk_statusbar_push (latexila.statusbar, context_id,
-                                                       _("Phrase not found"));
-                               }
-                               break;
+               i++;
+       }
 
-                       default:
-                               stop = TRUE;
-                               break;
-               }
+       gtk_text_buffer_end_user_action (buffer);
+
+       // normal background (overwritten if the phrase was not found)
+       set_entry_background (latexila.under_source_view.replace_entry_search,
+                       FALSE);
+
+       // print a message in the statusbar
+       gchar *msg;
+       if (i == 0)
+       {
+               msg = g_strdup (_("Phrase not found"));
+
+               // red background
+               set_entry_background (latexila.under_source_view.replace_entry_search,
+                               TRUE);
        }
+       else if (i == 1)
+               msg = g_strdup (_("Found and replaced one occurence"));
+       else
+               msg = g_strdup_printf (_("Found and replaced %d occurences"), i);
 
+       guint context_id = gtk_statusbar_get_context_id (latexila.statusbar,
+                       "replace");
        gtk_statusbar_pop (latexila.statusbar, context_id);
-       gtk_widget_destroy (dialog);
+       gtk_statusbar_push (latexila.statusbar, context_id, msg);
+       g_free (msg);
+
+       // the user must do a find before doing a replace
+       gtk_widget_set_sensitive (latexila.under_source_view.replace_button,
+                       FALSE);
+}
+
+void
+cb_replace (void)
+{
+       if (latexila.active_doc == NULL)
+               return;
+
+       // reset the background color
+       set_entry_background (latexila.under_source_view.replace_entry_search,
+                       FALSE);
+
+       // the user must do a find before doing a replace
+       gtk_widget_set_sensitive (latexila.under_source_view.replace_button,
+                       FALSE);
+
+       gtk_widget_show_all (latexila.under_source_view.replace);
+       gtk_widget_grab_focus (latexila.under_source_view.replace_entry_search);
 }
 
 void
diff --git a/src/callbacks.h b/src/callbacks.h
index 798113a..43036eb 100644
--- a/src/callbacks.h
+++ b/src/callbacks.h
@@ -42,6 +42,10 @@ void cb_close_find (GtkWidget *widget, gpointer user_data);
 void cb_find_entry (GtkEntry *entry, gpointer user_data);
 void cb_find_next (GtkWidget *widget, gpointer user_data);
 void cb_find_previous (GtkWidget *widget, gpointer user_data);
+void cb_close_replace (GtkWidget *widget, gpointer user_data);
+void cb_replace_find (GtkWidget *widget, gpointer user_data);
+void cb_replace_replace (GtkWidget *widget, gpointer user_data);
+void cb_replace_replace_all (GtkWidget *widget, gpointer user_data);
 void cb_replace (void);
 void cb_go_to_line (void);
 void cb_close_go_to_line (GtkWidget *widget, gpointer user_data);
diff --git a/src/main.c b/src/main.c
index 7a589c5..10510b0 100644
--- a/src/main.c
+++ b/src/main.c
@@ -42,6 +42,7 @@ static void init_side_pane (void);
 static void init_source_view (GtkWidget *vbox_source_view);
 static void init_go_to_line (GtkWidget *vbox_source_view);
 static void init_find (GtkWidget *vbox_source_view);
+static void init_replace (GtkWidget *vbox_source_view);
 static void init_log_zone (void);
 static void init_statusbar (GtkWidget *main_vbox);
 
@@ -221,6 +222,77 @@ init_find (GtkWidget *vbox_source_view)
        gtk_box_pack_start (GTK_BOX (find), match_case, FALSE, FALSE, 0);
 }
 
+static void
+init_replace (GtkWidget *vbox_source_view)
+{
+       GtkWidget *replace = gtk_hbox_new (FALSE, 3);
+       latexila.under_source_view.replace = replace;
+       gtk_box_pack_start (GTK_BOX (vbox_source_view), replace, FALSE, FALSE, 0);
+
+       // see the result to understand ;)
+       GtkWidget *vbox = gtk_vbox_new (FALSE, 2);
+       GtkWidget *hbox1 = gtk_hbox_new (FALSE, 3);
+       GtkWidget *hbox2 = gtk_hbox_new (FALSE, 3);
+       gtk_box_pack_start (GTK_BOX (vbox), hbox1, FALSE, FALSE, 0);
+       gtk_box_pack_start (GTK_BOX (vbox), hbox2, FALSE, FALSE, 0);
+
+       // left: close button
+       GtkWidget *close_button = gtk_button_new ();
+       gtk_button_set_relief (GTK_BUTTON (close_button), GTK_RELIEF_NONE);
+       GtkWidget *image = gtk_image_new_from_stock (GTK_STOCK_CLOSE,
+                       GTK_ICON_SIZE_MENU);
+       gtk_container_add (GTK_CONTAINER (close_button), image);
+       g_signal_connect (G_OBJECT (close_button), "clicked",
+                       G_CALLBACK (cb_close_replace), NULL);
+       gtk_box_pack_start (GTK_BOX (replace), close_button, FALSE, FALSE, 0);
+
+       // right: the two hbox
+       gtk_box_pack_start (GTK_BOX (replace), vbox, FALSE, FALSE, 0);
+       
+       /* first hbox */
+       GtkWidget *label = gtk_label_new (_("Search for:"));
+       gtk_box_pack_start (GTK_BOX (hbox1), label, FALSE, FALSE, 0);
+
+       GtkWidget *replace_entry_search = gtk_entry_new ();
+       latexila.under_source_view.replace_entry_search = replace_entry_search;
+       gtk_box_pack_start (GTK_BOX (hbox1), replace_entry_search, FALSE, FALSE, 5);
+
+       label = gtk_label_new (_("Replace with:"));
+       gtk_box_pack_start (GTK_BOX (hbox1), label, FALSE, FALSE, 0);
+
+       GtkWidget *replace_entry_replace = gtk_entry_new ();
+       latexila.under_source_view.replace_entry_replace = replace_entry_replace;
+       gtk_box_pack_start (GTK_BOX (hbox1), replace_entry_replace, FALSE, FALSE, 5);
+
+       GtkWidget *match_case = gtk_check_button_new_with_label (_("Match case"));
+       latexila.under_source_view.replace_match_case = match_case;
+       gtk_box_pack_start (GTK_BOX (hbox1), match_case, FALSE, FALSE, 0);
+
+       /* second hbox */
+       GtkWidget *button_replace_all = gtk_button_new_with_label (_("Replace All"));
+       gtk_button_set_relief (GTK_BUTTON (button_replace_all), GTK_RELIEF_NONE);
+       g_signal_connect (G_OBJECT (button_replace_all), "clicked",
+                       G_CALLBACK (cb_replace_replace_all), NULL);
+       gtk_box_pack_start (GTK_BOX (hbox2), button_replace_all, FALSE, FALSE, 0);
+
+       GtkWidget *button_replace = gtk_button_new_with_label (_("Replace"));
+       latexila.under_source_view.replace_button = button_replace;
+       image = gtk_image_new_from_stock (GTK_STOCK_FIND_AND_REPLACE, GTK_ICON_SIZE_MENU);
+       gtk_button_set_image (GTK_BUTTON (button_replace), image);
+       gtk_button_set_relief (GTK_BUTTON (button_replace), GTK_RELIEF_NONE);
+       // we can not make a replace before finding the first occurence
+       gtk_widget_set_sensitive (button_replace, FALSE);
+       g_signal_connect (G_OBJECT (button_replace), "clicked",
+                       G_CALLBACK (cb_replace_replace), NULL);
+       gtk_box_pack_start (GTK_BOX (hbox2), button_replace, FALSE, FALSE, 0);
+
+       GtkWidget *button_find = gtk_button_new_from_stock (GTK_STOCK_FIND);
+       gtk_button_set_relief (GTK_BUTTON (button_find), GTK_RELIEF_NONE);
+       g_signal_connect (G_OBJECT (button_find), "clicked",
+                       G_CALLBACK (cb_replace_find), NULL);
+       gtk_box_pack_start (GTK_BOX (hbox2), button_find, FALSE, FALSE, 0);
+}
+
 static void
 init_log_zone (void)
 {
@@ -397,6 +469,7 @@ main (int argc, char *argv[])
        init_source_view (vbox_source_view);
        init_go_to_line (vbox_source_view);
        init_find (vbox_source_view);
+       init_replace (vbox_source_view);
 
        /* log zone */
        // horizontal pane:
@@ -423,6 +496,7 @@ main (int argc, char *argv[])
 
        gtk_widget_hide (latexila.under_source_view.go_to_line);
        gtk_widget_hide (latexila.under_source_view.find);
+       gtk_widget_hide (latexila.under_source_view.replace);
 
        /* reopen files on startup */
        gchar ** list_opened_docs = (gchar **) latexila.prefs.list_opened_docs->pdata;
diff --git a/src/main.h b/src/main.h
index 9e24b81..90e0772 100644
--- a/src/main.h
+++ b/src/main.h
@@ -118,6 +118,11 @@ typedef struct
        GtkWidget       *find;
        GtkWidget       *find_entry;
        GtkWidget       *find_match_case;
+       GtkWidget       *replace;
+       GtkWidget       *replace_entry_search;
+       GtkWidget       *replace_entry_replace;
+       GtkWidget       *replace_match_case;
+       GtkWidget       *replace_button;
 } under_source_view_t;
 
 typedef struct


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