📄 dialog-replace.c
字号:
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- *//* Cleaned 10-00 by Chema *//* * gedit * * Copyright (C) 2000 Jose M Celorio * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * Author: * Chema Celorio <chema@celorio.com> * */#include <config.h>#include <glib.h>#include <gtk/gtkwidget.h>#include <gtk/gtkentry.h>#include <gtk/gtkeditable.h>#include <libgnome/gnome-defs.h>#include <libgnome/gnome-i18n.h>#include <libgnomeui/gnome-dialog.h>#include <libgnomeui/gnome-messagebox.h>#include <libgnomeui/gnome-stock.h>#include <glade/glade-xml.h>#include <string.h> /* For strlen */#include "window.h"#include "search.h"#include "view.h"#include "utils.h"#include "dialogs/dialogs.h"typedef struct{ GeditView *view; GladeXML *gui; GnomeDialog *dialog; gboolean done; gboolean not_found; gboolean replacements; GtkWidget *search_entry; GtkWidget *replace_entry; GtkWidget *find_button; GtkWidget *replace_button; GtkWidget *replace_all_button; GtkWidget *replace_hbox; GtkWidget *case_sensitive; GtkWidget *position;}GeditReplaceDialog;static GeditReplaceDialog *get_dialog (void){ static GeditReplaceDialog *dialog = NULL; gedit_debug (DEBUG_SEARCH, ""); if (dialog != NULL) return dialog; dialog = g_new0 (GeditReplaceDialog, 1); dialog->gui = glade_xml_new (GEDIT_GLADEDIR "/replace.glade", NULL); if (!dialog->gui) { g_warning ("Could not find replace.glade."); g_free (dialog); dialog = NULL; return NULL; } dialog->dialog = GNOME_DIALOG (glade_xml_get_widget (dialog->gui, "dialog")); dialog->search_entry = glade_xml_get_widget (dialog->gui, "search_for_text_entry"); dialog->replace_entry = glade_xml_get_widget (dialog->gui, "replace_with_text_entry"); dialog->find_button = glade_xml_get_widget (dialog->gui, "find_next_button"); dialog->replace_button = glade_xml_get_widget (dialog->gui, "replace_button"); dialog->replace_all_button = glade_xml_get_widget (dialog->gui, "replace_all_button"); dialog->replace_hbox = glade_xml_get_widget (dialog->gui, "hbox_replace_with"); dialog->case_sensitive = glade_xml_get_widget (dialog->gui, "case_sensitive"); dialog->position = glade_xml_get_widget (dialog->gui, "radio_button_1"); g_return_val_if_fail (dialog->dialog, NULL); g_return_val_if_fail (dialog->search_entry, NULL); g_return_val_if_fail (dialog->replace_entry, NULL); g_return_val_if_fail (dialog->find_button, NULL); g_return_val_if_fail (dialog->replace_button, NULL); g_return_val_if_fail (dialog->replace_all_button, NULL); g_return_val_if_fail (dialog->replace_hbox, NULL); g_return_val_if_fail (dialog->case_sensitive, NULL); g_return_val_if_fail (dialog->position, NULL); /* Now, set the properties of the gnome_dialog */ gnome_dialog_editable_enters (dialog->dialog, GTK_EDITABLE (dialog->search_entry)); gnome_dialog_editable_enters (dialog->dialog, GTK_EDITABLE (dialog->replace_entry)); gnome_dialog_close_hides (dialog->dialog, TRUE); gtk_object_unref (GTK_OBJECT (dialog->gui)); return dialog;}static voiddialog_set (GeditReplaceDialog *dialog, gboolean replace, gboolean first){ GtkLabel *label; gedit_debug (DEBUG_SEARCH, ""); label = GTK_LABEL(GTK_BIN ((GTK_BUTTON (dialog->find_button)))->child); g_return_if_fail (GTK_IS_LABEL (label)); if (replace) { gtk_widget_show (dialog->replace_hbox); gtk_widget_show (dialog->replace_button); gtk_widget_show (dialog->replace_all_button); gtk_widget_set_sensitive (dialog->replace_button, !first); gtk_window_set_title ( GTK_WINDOW (dialog->dialog), _("Replace")); } else { gtk_widget_hide (dialog->replace_hbox); gtk_widget_hide (dialog->replace_button); gtk_widget_hide (dialog->replace_all_button); gtk_window_set_title ( GTK_WINDOW (dialog->dialog), _("Find")); } if (first) { dialog->view = gedit_view_active (); gtk_label_set_text (label, "Find"); gtk_widget_grab_focus (dialog->search_entry); gtk_entry_set_position (GTK_ENTRY (dialog->replace_entry), 0); gtk_entry_select_region (GTK_ENTRY (dialog->replace_entry), 0, GTK_ENTRY (dialog->replace_entry)->text_length); gtk_entry_set_position (GTK_ENTRY (dialog->search_entry), 0); gtk_entry_select_region (GTK_ENTRY (dialog->search_entry), 0, GTK_ENTRY (dialog->search_entry)->text_length); gtk_radio_button_select (GTK_RADIO_BUTTON(dialog->position)->group, 0); gnome_dialog_set_parent (dialog->dialog, gedit_window_active ()); } else { gtk_entry_select_region (GTK_ENTRY (dialog->replace_entry), 0, 0); gtk_entry_select_region (GTK_ENTRY (dialog->search_entry), 0, 0); gtk_label_set_text (label, "Find Next"); gtk_radio_button_select (GTK_RADIO_BUTTON(dialog->position)->group, 1); } gnome_dialog_set_default (dialog->dialog, replace ? (first ? 0 : 1) : 0); }static voidaction_find (GeditReplaceDialog *dialog, guint start_pos, const gchar *search_text, gboolean case_sensitive){ gboolean found = FALSE; guint pos_found; gint line_found, total_lines; gedit_debug (DEBUG_SEARCH, ""); found = gedit_search_execute (start_pos, case_sensitive, search_text, &pos_found, &line_found, &total_lines, TRUE); if (!found) { dialog->not_found = TRUE; dialog->done = TRUE; return; } gedit_view_set_window_position_from_lines (dialog->view, line_found, total_lines); gedit_view_set_position (dialog->view, pos_found); gedit_view_set_selection (dialog->view, pos_found, pos_found + strlen (search_text)); gtk_radio_button_select (GTK_RADIO_BUTTON(dialog->position)->group, 1);}static voidaction_replace (GeditReplaceDialog *dialog, guint start_pos, const gchar *search_text, const gchar *replace_text, gboolean case_sensitive){ gedit_debug (DEBUG_SEARCH, ""); gedit_document_replace_text (dialog->view->doc, replace_text, strlen (search_text), start_pos - strlen (search_text), TRUE); /* We need to reload the buffer since we changed it */ gedit_search_end(); gedit_search_start(); start_pos += strlen (replace_text) - strlen (search_text); action_find (dialog, start_pos, search_text, case_sensitive);}static voidaction_replace_all (GeditReplaceDialog *dialog, gint start_pos, const gchar *search_text, const gchar *replace_text, gboolean case_sensitive){ guchar *new_buffer = NULL; gint cursor_position; gint num_lines; gint line; gedit_debug (DEBUG_SEARCH, ""); start_pos -= strlen (search_text); if (start_pos < 0) start_pos = 0; cursor_position = gedit_view_get_position (dialog->view); dialog->replacements = gedit_replace_all_execute (dialog->view, start_pos, search_text, replace_text, case_sensitive, &cursor_position, &new_buffer); if (dialog->replacements > 0) { gedit_document_replace_text (dialog->view->doc, new_buffer, gedit_document_get_buffer_length (dialog->view->doc), 0, TRUE); line = gedit_search_pos_to_line (cursor_position, &num_lines); gedit_view_set_window_position_from_lines (dialog->view, line, num_lines); gedit_view_set_position (dialog->view, cursor_position); } else dialog->done = TRUE; if (new_buffer!=NULL) g_free (new_buffer);}static voiddialog_action (GeditReplaceDialog *dialog, gint button, gboolean replace){ const gchar *search_text; const gchar *replace_text; gboolean case_sensitive; guint start_pos; guint end_pos; gint selected; gedit_debug (DEBUG_SEARCH, ""); g_return_if_fail (gedit_search_verify ()); search_text = gtk_entry_get_text (GTK_ENTRY (dialog->search_entry)); replace_text = gtk_entry_get_text (GTK_ENTRY (dialog->replace_entry)); g_return_if_fail (search_text != NULL); g_return_if_fail (replace_text != NULL); if (*search_text == 0) { dialog->done = TRUE; return; } /* Get the initial position, selected = start of doc, !selected = current pos */ selected = gtk_radio_group_get_selected (GTK_RADIO_BUTTON(dialog->position)->group); switch (selected) { case 0: start_pos = 0; break; case 1: if (gedit_view_get_selection (dialog->view, &start_pos, &end_pos)) start_pos = end_pos; else start_pos = gedit_view_get_position (dialog->view); break; default: g_warning ("Invalid radio button selection."); return; } case_sensitive = GTK_TOGGLE_BUTTON (dialog->case_sensitive)->active; switch (button) { case 2: action_replace_all (dialog, start_pos, search_text, replace_text, case_sensitive); break; case 1: action_replace (dialog, start_pos, search_text, replace_text, case_sensitive); break; case 0: action_find (dialog, start_pos, search_text, case_sensitive); break; }}static voidsearch_not_found_notify (GeditView * view){ GtkWidget *gnome_dialog; gchar * msg; gedit_debug (DEBUG_SEARCH, ""); gedit_flash_va (_("Search string not found")); if (gedit_view_get_selection (view, NULL, NULL)) gedit_view_set_selection (view, 0, 0); msg = g_strdup (_("Search string not found.")); gnome_dialog = gnome_message_box_new (msg, GNOME_MESSAGE_BOX_INFO, GNOME_STOCK_BUTTON_OK, NULL); gnome_dialog_set_parent (GNOME_DIALOG (gnome_dialog), GTK_WINDOW (mdi->active_window)); gnome_dialog_run_and_close (GNOME_DIALOG(gnome_dialog)); g_free (msg);}static voiddialog_display_messages (GeditReplaceDialog *dialog){ gchar *msg; gedit_debug (DEBUG_SEARCH, ""); /* This is done like this, since we need to close the other dialog before poping this dialogs*/ if (dialog->not_found || dialog->replacements == 0) search_not_found_notify (dialog->view); if (dialog->replacements > 0) { msg = g_strdup_printf (_("Found and replaced %i occurrences."), dialog->replacements); gnome_dialog_run_and_close ((GnomeDialog *) gnome_message_box_new (msg, GNOME_MESSAGE_BOX_INFO, GNOME_STOCK_BUTTON_OK, NULL)); g_free (msg); } if (dialog->replacements == -1) {#if 0 /* warning: too many arguments for format */ msg = g_strdup_printf (_("Could not allocate the memory for the Replace all request."), dialog->replacements);#endif msg = g_strdup_printf (_("Could not allocate the memory for the Replace all request.")); gnome_dialog_run_and_close ((GnomeDialog *) gnome_message_box_new (msg, GNOME_MESSAGE_BOX_INFO, GNOME_STOCK_BUTTON_OK, NULL)); g_free (msg); }}/** * gedit_dialog_replace: * @replace: If true, it pops up a replace dialog. If false, it pops up a Find dialog * * Takes care of creating and actions of the replace dialog, **/voidgedit_dialog_replace (gboolean replace){ static GeditReplaceDialog *dialog = NULL; gint button; gedit_debug (DEBUG_SEARCH, ""); if (dialog == NULL) { dialog = get_dialog (); if (dialog == NULL) return; } dialog_set (dialog, replace, TRUE); if (dialog->view == NULL) return; dialog->done = FALSE; dialog->not_found = FALSE; dialog->replacements = -2; while (!dialog->done) { button = gnome_dialog_run (dialog->dialog); if (button == -1) return; if (button == 3) break; gedit_search_start (); dialog_action (dialog, button, replace); gedit_search_end (); if (button == 2) break; dialog_set (dialog, replace, FALSE); } gnome_dialog_close (dialog->dialog); dialog_display_messages (dialog);}voidgedit_find_again (void){ GeditReplaceDialog *dialog; const gchar *search_text; gedit_debug (DEBUG_SEARCH, ""); dialog = get_dialog (); g_return_if_fail (dialog != NULL); search_text = gtk_entry_get_text (GTK_ENTRY (dialog->search_entry)); if (*search_text == 0) { gedit_dialog_replace (FALSE); return; } /* We always find again from the current position, since we don't have a dialog up */ gtk_radio_button_select (GTK_RADIO_BUTTON(dialog->position)->group, 1); gedit_search_start (); dialog_action (dialog, 0, FALSE); gedit_search_end (); dialog_display_messages (dialog);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -