From 9b7c40cb7350c5eb04f6c0bc472f25c44bd55025 Mon Sep 17 00:00:00 2001 From: bl0ckeduser Date: Fri, 31 May 2013 13:46:48 -0400 Subject: Fix search/replace of strings containing backslashes --- pluma/pluma-commands-search.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/pluma/pluma-commands-search.c b/pluma/pluma-commands-search.c index ee1b5129..298325eb 100644 --- a/pluma/pluma-commands-search.c +++ b/pluma/pluma-commands-search.c @@ -241,7 +241,7 @@ do_find (PlumaSearchDialog *dialog, doc = PLUMA_DOCUMENT (gtk_text_view_get_buffer (GTK_TEXT_VIEW (active_view))); - entry_text = pluma_search_dialog_get_search_text (dialog); + entry_text = pluma_utils_escape_search_text (pluma_search_dialog_get_search_text (dialog)); match_case = pluma_search_dialog_get_match_case (dialog); entire_word = pluma_search_dialog_get_entire_word (dialog); @@ -269,7 +269,7 @@ do_find (PlumaSearchDialog *dialog, if (found) text_found (window, 0); else - text_not_found (window, entry_text); + text_not_found (window, pluma_utils_unescape_search_text (entry_text)); gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), PLUMA_SEARCH_DIALOG_REPLACE_RESPONSE, @@ -335,12 +335,12 @@ do_replace (PlumaSearchDialog *dialog, if (doc == NULL) return; - search_entry_text = pluma_search_dialog_get_search_text (dialog); + search_entry_text = pluma_utils_escape_search_text (pluma_search_dialog_get_search_text (dialog)); g_return_if_fail ((search_entry_text) != NULL); g_return_if_fail ((*search_entry_text) != '\0'); /* replace text may be "", we just delete */ - replace_entry_text = pluma_search_dialog_get_replace_text (dialog); + replace_entry_text = pluma_utils_escape_search_text (pluma_search_dialog_get_replace_text (dialog)); g_return_if_fail ((replace_entry_text) != NULL); unescaped_search_text = pluma_utils_unescape_search_text (search_entry_text); @@ -394,12 +394,12 @@ do_replace_all (PlumaSearchDialog *dialog, doc = PLUMA_DOCUMENT (gtk_text_view_get_buffer (GTK_TEXT_VIEW (active_view))); - search_entry_text = pluma_search_dialog_get_search_text (dialog); + search_entry_text = pluma_utils_escape_search_text( pluma_search_dialog_get_search_text (dialog)); g_return_if_fail ((search_entry_text) != NULL); g_return_if_fail ((*search_entry_text) != '\0'); /* replace text may be "", we just delete all occurrencies */ - replace_entry_text = pluma_search_dialog_get_replace_text (dialog); + replace_entry_text = pluma_utils_escape_search_text (pluma_search_dialog_get_replace_text (dialog)); g_return_if_fail ((replace_entry_text) != NULL); match_case = pluma_search_dialog_get_match_case (dialog); @@ -419,7 +419,7 @@ do_replace_all (PlumaSearchDialog *dialog, } else { - text_not_found (window, search_entry_text); + text_not_found (window, pluma_utils_unescape_search_text (search_entry_text)); } gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), -- cgit v1.2.1 From 24dc1853b70b34301034c28e2d0a0e2bb416e8f6 Mon Sep 17 00:00:00 2001 From: bl0ckeduser Date: Sun, 22 Sep 2013 11:29:49 -0400 Subject: Make escape sequence parsing in search a GUI checkbox option --- pluma/dialogs/pluma-search-dialog.c | 20 ++++++++++++++ pluma/dialogs/pluma-search-dialog.h | 5 ++++ pluma/dialogs/pluma-search-dialog.ui | 18 ++++++++++++ pluma/pluma-commands-search.c | 53 ++++++++++++++++++++++++++++++------ pluma/pluma-document.h | 7 ++++- pluma/pluma-view.c | 18 ++++++++++++ 6 files changed, 111 insertions(+), 10 deletions(-) diff --git a/pluma/dialogs/pluma-search-dialog.c b/pluma/dialogs/pluma-search-dialog.c index 7db2a2bc..7e199225 100755 --- a/pluma/dialogs/pluma-search-dialog.c +++ b/pluma/dialogs/pluma-search-dialog.c @@ -70,6 +70,7 @@ struct _PlumaSearchDialogPrivate GtkWidget *entire_word_checkbutton; GtkWidget *backwards_checkbutton; GtkWidget *wrap_around_checkbutton; + GtkWidget *parse_escapes_checkbutton; GtkWidget *find_button; GtkWidget *replace_button; GtkWidget *replace_all_button; @@ -357,6 +358,7 @@ pluma_search_dialog_init (PlumaSearchDialog *dlg) "entire_word_checkbutton", &dlg->priv->entire_word_checkbutton, "search_backwards_checkbutton", &dlg->priv->backwards_checkbutton, "wrap_around_checkbutton", &dlg->priv->wrap_around_checkbutton, + "parse_escapes_checkbutton", &dlg->priv->parse_escapes_checkbutton, NULL); g_free (file); @@ -632,3 +634,21 @@ pluma_search_dialog_get_wrap_around (PlumaSearchDialog *dialog) return gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dialog->priv->wrap_around_checkbutton)); } + +void +pluma_search_dialog_set_parse_escapes (PlumaSearchDialog *dialog, + gboolean parse_escapes) +{ + g_return_if_fail (PLUMA_IS_SEARCH_DIALOG (dialog)); + + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->priv->parse_escapes_checkbutton), + parse_escapes); +} + +gboolean +pluma_search_dialog_get_parse_escapes (PlumaSearchDialog *dialog) +{ + g_return_val_if_fail (PLUMA_IS_SEARCH_DIALOG (dialog), FALSE); + + return gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dialog->priv->parse_escapes_checkbutton)); +} diff --git a/pluma/dialogs/pluma-search-dialog.h b/pluma/dialogs/pluma-search-dialog.h index 967f6a9f..fb92efba 100755 --- a/pluma/dialogs/pluma-search-dialog.h +++ b/pluma/dialogs/pluma-search-dialog.h @@ -123,6 +123,11 @@ void pluma_search_dialog_set_wrap_around (PlumaSearchDialog *dialog, gboolean wrap_around); gboolean pluma_search_dialog_get_wrap_around (PlumaSearchDialog *dialog); + +void pluma_search_dialog_set_parse_escapes (PlumaSearchDialog *dialog, + gboolean parse_escapes); +gboolean pluma_search_dialog_get_parse_escapes (PlumaSearchDialog *dialog); + G_END_DECLS #endif /* __PLUMA_SEARCH_DIALOG_H__ */ diff --git a/pluma/dialogs/pluma-search-dialog.ui b/pluma/dialogs/pluma-search-dialog.ui index 35b6c390..4f137b19 100755 --- a/pluma/dialogs/pluma-search-dialog.ui +++ b/pluma/dialogs/pluma-search-dialog.ui @@ -229,6 +229,24 @@ False + + + True + True + _Parse escape sequences (e.g. \n) + True + GTK_RELIEF_NORMAL + True + True + False + True + + + 0 + False + False + + 0 diff --git a/pluma/pluma-commands-search.c b/pluma/pluma-commands-search.c index 298325eb..4c92b65e 100644 --- a/pluma/pluma-commands-search.c +++ b/pluma/pluma-commands-search.c @@ -229,6 +229,7 @@ do_find (PlumaSearchDialog *dialog, gboolean entire_word; gboolean wrap_around; gboolean search_backwards; + gboolean parse_escapes; guint flags = 0; guint old_flags = 0; gboolean found; @@ -241,12 +242,17 @@ do_find (PlumaSearchDialog *dialog, doc = PLUMA_DOCUMENT (gtk_text_view_get_buffer (GTK_TEXT_VIEW (active_view))); - entry_text = pluma_utils_escape_search_text (pluma_search_dialog_get_search_text (dialog)); - match_case = pluma_search_dialog_get_match_case (dialog); entire_word = pluma_search_dialog_get_entire_word (dialog); search_backwards = pluma_search_dialog_get_backwards (dialog); wrap_around = pluma_search_dialog_get_wrap_around (dialog); + parse_escapes = pluma_search_dialog_get_parse_escapes (dialog); + + if (!parse_escapes) { + entry_text = pluma_utils_escape_search_text (pluma_search_dialog_get_search_text (dialog)); + } else { + entry_text = pluma_search_dialog_get_search_text (dialog); + } PLUMA_SEARCH_SET_CASE_SENSITIVE (flags, match_case); PLUMA_SEARCH_SET_ENTIRE_WORD (flags, entire_word); @@ -268,8 +274,13 @@ do_find (PlumaSearchDialog *dialog, if (found) text_found (window, 0); - else - text_not_found (window, pluma_utils_unescape_search_text (entry_text)); + else { + if (!parse_escapes) { + text_not_found (window, pluma_utils_unescape_search_text (entry_text)); + } else { + text_not_found (window, entry_text); + } + } gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), PLUMA_SEARCH_DIALOG_REPLACE_RESPONSE, @@ -330,17 +341,27 @@ do_replace (PlumaSearchDialog *dialog, gchar *unescaped_replace_text; gchar *selected_text = NULL; gboolean match_case; + gboolean parse_escapes; doc = pluma_window_get_active_document (window); if (doc == NULL) return; - search_entry_text = pluma_utils_escape_search_text (pluma_search_dialog_get_search_text (dialog)); + parse_escapes = pluma_search_dialog_get_parse_escapes (dialog); + if (!parse_escapes) { + search_entry_text = pluma_utils_escape_search_text (pluma_search_dialog_get_search_text (dialog)); + } else { + search_entry_text = pluma_search_dialog_get_search_text (dialog); + } g_return_if_fail ((search_entry_text) != NULL); g_return_if_fail ((*search_entry_text) != '\0'); /* replace text may be "", we just delete */ - replace_entry_text = pluma_utils_escape_search_text (pluma_search_dialog_get_replace_text (dialog)); + if (!parse_escapes) { + replace_entry_text = pluma_utils_escape_search_text (pluma_search_dialog_get_replace_text (dialog)); + } else { + replace_entry_text = pluma_search_dialog_get_replace_text (dialog); + } g_return_if_fail ((replace_entry_text) != NULL); unescaped_search_text = pluma_utils_unescape_search_text (search_entry_text); @@ -385,6 +406,7 @@ do_replace_all (PlumaSearchDialog *dialog, const gchar *replace_entry_text; gboolean match_case; gboolean entire_word; + gboolean parse_escapes; guint flags = 0; gint count; @@ -394,12 +416,21 @@ do_replace_all (PlumaSearchDialog *dialog, doc = PLUMA_DOCUMENT (gtk_text_view_get_buffer (GTK_TEXT_VIEW (active_view))); - search_entry_text = pluma_utils_escape_search_text( pluma_search_dialog_get_search_text (dialog)); + parse_escapes = pluma_search_dialog_get_parse_escapes (dialog); + if (!parse_escapes) { + search_entry_text = pluma_utils_escape_search_text(pluma_search_dialog_get_search_text (dialog)); + } else { + search_entry_text = pluma_search_dialog_get_search_text (dialog); + } g_return_if_fail ((search_entry_text) != NULL); g_return_if_fail ((*search_entry_text) != '\0'); /* replace text may be "", we just delete all occurrencies */ - replace_entry_text = pluma_utils_escape_search_text (pluma_search_dialog_get_replace_text (dialog)); + if (!parse_escapes) { + replace_entry_text = pluma_utils_escape_search_text (pluma_search_dialog_get_replace_text (dialog)); + } else { + replace_entry_text = pluma_search_dialog_get_replace_text (dialog); + } g_return_if_fail ((replace_entry_text) != NULL); match_case = pluma_search_dialog_get_match_case (dialog); @@ -419,7 +450,11 @@ do_replace_all (PlumaSearchDialog *dialog, } else { - text_not_found (window, pluma_utils_unescape_search_text (search_entry_text)); + if (!parse_escapes) { + text_not_found (window, pluma_utils_unescape_search_text (search_entry_text)); + } else { + text_not_found (window, search_entry_text); + } } gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), diff --git a/pluma/pluma-document.h b/pluma/pluma-document.h index a8cf5020..099aaae1 100644 --- a/pluma/pluma-document.h +++ b/pluma/pluma-document.h @@ -78,7 +78,8 @@ typedef enum { PLUMA_SEARCH_DONT_SET_FLAGS = 1 << 0, PLUMA_SEARCH_ENTIRE_WORD = 1 << 1, - PLUMA_SEARCH_CASE_SENSITIVE = 1 << 2 + PLUMA_SEARCH_CASE_SENSITIVE = 1 << 2, + PLUMA_SEARCH_PARSE_ESCAPES = 1 << 3 } PlumaSearchFlags; @@ -322,6 +323,10 @@ void _pluma_document_search_region (PlumaDocument *doc, #define PLUMA_SEARCH_SET_CASE_SENSITIVE(sflags,state) ((state == TRUE) ? \ (sflags |= PLUMA_SEARCH_CASE_SENSITIVE) : (sflags &= ~PLUMA_SEARCH_CASE_SENSITIVE)) +#define PLUMA_SEARCH_IS_PARSE_ESCAPES(sflags) ((sflags & PLUMA_SEARCH_PARSE_ESCAPES) != 0) +#define PLUMA_SEARCH_SET_PARSE_ESCAPES(sflags,state) ((state == TRUE) ? \ +(sflags |= PLUMA_SEARCH_PARSE_ESCAPES) : (sflags &= ~PLUMA_SEARCH_PARSE_ESCAPES)) + typedef GMountOperation *(*PlumaMountOperationFactory)(PlumaDocument *doc, gpointer userdata); diff --git a/pluma/pluma-view.c b/pluma/pluma-view.c index cbd2299c..63191279 100644 --- a/pluma/pluma-view.c +++ b/pluma/pluma-view.c @@ -1165,6 +1165,14 @@ match_case_menu_item_toggled (GtkCheckMenuItem *checkmenuitem, gtk_check_menu_item_get_active (checkmenuitem)); } +static void +parse_escapes_menu_item_toggled (GtkCheckMenuItem *checkmenuitem, + PlumaView *view) +{ + PLUMA_SEARCH_SET_PARSE_ESCAPES (view->priv->search_flags, + gtk_check_menu_item_get_active (checkmenuitem)); +} + static gboolean real_search_enable_popdown (gpointer data) { @@ -1243,6 +1251,16 @@ search_entry_populate_popup (GtkEntry *entry, gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (menu_item), PLUMA_SEARCH_IS_CASE_SENSITIVE (view->priv->search_flags)); gtk_widget_show (menu_item); + + /* create "Parse escapes" menu item. */ + menu_item = gtk_check_menu_item_new_with_mnemonic (_("_Parse escape sequences (e.g. \n)")); + g_signal_connect (G_OBJECT (menu_item), "toggled", + G_CALLBACK (parse_escapes_menu_item_toggled), + view); + gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), menu_item); + gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (menu_item), + PLUMA_SEARCH_IS_PARSE_ESCAPES (view->priv->search_flags)); + gtk_widget_show (menu_item); } static void -- cgit v1.2.1 From 1bf710e2a1addeada225b94006d3479ccdc43230 Mon Sep 17 00:00:00 2001 From: bl0ckeduser Date: Sun, 22 Sep 2013 12:06:08 -0400 Subject: Gracefully handle a rare search/replace special case --- pluma/pluma-commands-search.c | 46 +++++++++++++++++++++++++++++++++++++++---- 1 file changed, 42 insertions(+), 4 deletions(-) diff --git a/pluma/pluma-commands-search.c b/pluma/pluma-commands-search.c index 4c92b65e..d6a75ef2 100644 --- a/pluma/pluma-commands-search.c +++ b/pluma/pluma-commands-search.c @@ -546,7 +546,9 @@ _pluma_cmd_search_find (GtkAction *action, GtkWidget *search_dialog; PlumaDocument *doc; gboolean selection_exists; + gboolean parse_escapes; gchar *find_text = NULL; + const gchar *search_text = NULL; gint sel_len; pluma_debug (DEBUG_COMMANDS); @@ -578,8 +580,25 @@ _pluma_cmd_search_find (GtkAction *action, if (selection_exists && find_text != NULL && sel_len < 80) { - pluma_search_dialog_set_search_text (PLUMA_SEARCH_DIALOG (search_dialog), - find_text); + /* + * Special case: if the currently selected text + * is the same as the unescaped search text and + * escape sequence parsing is activated, use the + * same old search text. (Without this, if you e.g. + * search for '\n' in escaped mode and then open + * the search dialog again, you'll get an unprintable + * single-character literal '\n' in the "search for" + * box). + */ + parse_escapes = pluma_search_dialog_get_parse_escapes (PLUMA_SEARCH_DIALOG (search_dialog)); + search_text = pluma_search_dialog_get_search_text (PLUMA_SEARCH_DIALOG (search_dialog)); + if (!(search_text != NULL + && !strcmp(pluma_utils_unescape_search_text(search_text), find_text) + && parse_escapes)) { + /* General case */ + pluma_search_dialog_set_search_text (PLUMA_SEARCH_DIALOG (search_dialog), + find_text); + } g_free (find_text); } else @@ -601,7 +620,9 @@ _pluma_cmd_search_replace (GtkAction *action, GtkWidget *replace_dialog; PlumaDocument *doc; gboolean selection_exists; + gboolean parse_escapes; gchar *find_text = NULL; + const gchar *search_text = NULL; gint sel_len; pluma_debug (DEBUG_COMMANDS); @@ -633,8 +654,25 @@ _pluma_cmd_search_replace (GtkAction *action, if (selection_exists && find_text != NULL && sel_len < 80) { - pluma_search_dialog_set_search_text (PLUMA_SEARCH_DIALOG (replace_dialog), - find_text); + /* + * Special case: if the currently selected text + * is the same as the unescaped search text and + * escape sequence parsing is activated, use the + * same old search text. (Without this, if you e.g. + * search for '\n' in escaped mode and then open + * the search dialog again, you'll get an unprintable + * single-character literal '\n' in the "search for" + * box). + */ + parse_escapes = pluma_search_dialog_get_parse_escapes (PLUMA_SEARCH_DIALOG (replace_dialog)); + search_text = pluma_search_dialog_get_search_text (PLUMA_SEARCH_DIALOG (replace_dialog)); + if (!(search_text != NULL + && !strcmp(pluma_utils_unescape_search_text(search_text), find_text) + && parse_escapes)) { + /* General case */ + pluma_search_dialog_set_search_text (PLUMA_SEARCH_DIALOG (replace_dialog), + find_text); + } g_free (find_text); } else -- cgit v1.2.1