/* * R : A Computer Langage for Statistical Data Analysis * Copyright (C) 1998-2004 Lyndon Drake * and the R Development Core Team * * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifdef HAVE_CONFIG_H # include /* for HAVE_STRING_H / HAVE_STRINGS_H */ #endif /* Avoid braced-groups warning from -Wall */ #define G_STMT_START do #define G_STMT_END while(0) #include "gnome-find-dialog.h" #if defined (HAVE_STRING_H) # include #elif defined (HAVE_STRINGS_H) # include #endif #include #include #include enum { FIND, FIND_AGAIN, LAST_SIGNAL }; static void gnome_find_dialog_class_init (GnomeFindDialogClass *klass); static void gnome_find_dialog_init (GnomeFindDialog *find_dialog); static void gnome_find_dialog_destroy (GtkObject *object); static void find (GnomeFindDialog *find_dialog); static void find_again (GnomeFindDialog *find_dialog); static void close (GnomeFindDialog *find_dialog); static void entry_changed_cb (GtkEditable *editable, gpointer data); static void forwards_clicked_cb (GtkButton *button, gpointer data); static void backwards_clicked_cb (GtkButton *button, gpointer data); static void top_clicked_cb (GtkButton *button, gpointer data); static void cursor_clicked_cb (GtkButton *button, gpointer data); static void bottom_clicked_cb (GtkButton *button, gpointer data); static void case_toggled_cb (GtkToggleButton *button, gpointer data); static void wrap_toggled_cb (GtkToggleButton *button, gpointer data); static void regex_toggled_cb (GtkToggleButton *button, gpointer data); static void dialog_clicked_cb (GnomeDialog *dialog, gint button, gpointer data); static GnomeDialogClass *parent_class = NULL; static guint find_dialog_signals[LAST_SIGNAL] = { 0 }; guint gnome_find_dialog_get_type (void) { static guint find_dialog_type = 0; if(!find_dialog_type) { GtkTypeInfo find_dialog_info = { "GnomeFindDialog", sizeof (GnomeFindDialog), sizeof (GnomeFindDialogClass), (GtkClassInitFunc) gnome_find_dialog_class_init, (GtkObjectInitFunc) gnome_find_dialog_init, /* Reserved */ NULL, /* Reserved */ NULL, (GtkClassInitFunc) NULL, }; find_dialog_type = gtk_type_unique (gnome_dialog_get_type (), &find_dialog_info); } return find_dialog_type; } static void gnome_find_dialog_class_init (GnomeFindDialogClass *klass) { GtkObjectClass *object_class; GtkWidgetClass *widget_class; GtkWindowClass *window_class; object_class = (GtkObjectClass *) klass; widget_class = (GtkWidgetClass *) klass; window_class = (GtkWindowClass *) klass; object_class->destroy = gnome_find_dialog_destroy; parent_class = gtk_type_class (gnome_dialog_get_type ()); find_dialog_signals[FIND] = gtk_signal_new ("find", GTK_RUN_LAST, object_class->type, GTK_SIGNAL_OFFSET (GnomeFindDialogClass, find), gtk_marshal_NONE__NONE, GTK_TYPE_NONE, 0); find_dialog_signals[FIND_AGAIN] = gtk_signal_new ("find_again", GTK_RUN_LAST, object_class->type, GTK_SIGNAL_OFFSET (GnomeFindDialogClass, find_again), gtk_marshal_NONE__NONE, GTK_TYPE_NONE, 0); gtk_object_class_add_signals (object_class, find_dialog_signals, LAST_SIGNAL); klass->find = NULL; klass->find_again = NULL; } static void gnome_find_dialog_init (GnomeFindDialog *find_dialog) { GList *button_list; GtkWidget *hbox, *find_label; GtkWidget *hbox2; GtkWidget *pos_frame, *pos_vbox; GtkWidget *dir_frame, *dir_vbox; gnome_dialog_append_button_with_pixmap(GNOME_DIALOG(find_dialog), "Find", GNOME_STOCK_PIXMAP_SEARCH); gnome_dialog_append_button_with_pixmap(GNOME_DIALOG(find_dialog), "Find Again", GNOME_STOCK_PIXMAP_SEARCH); gnome_dialog_append_buttons (GNOME_DIALOG(find_dialog), GNOME_STOCK_BUTTON_CLOSE, NULL); button_list = GNOME_DIALOG(find_dialog)->buttons; find_dialog->find_button = GTK_WIDGET(button_list->data); gnome_dialog_set_sensitive(GNOME_DIALOG(find_dialog), 0, FALSE); button_list = button_list->next; find_dialog->find_again_button = GTK_WIDGET(button_list->data); gnome_dialog_set_sensitive(GNOME_DIALOG(find_dialog), 1, FALSE); button_list = button_list->next; find_dialog->close_button = GTK_WIDGET(button_list->data); button_list = button_list->next; gtk_signal_connect(GTK_OBJECT(find_dialog), "clicked", GTK_SIGNAL_FUNC(dialog_clicked_cb), NULL); /* text entry */ hbox = gtk_hbox_new(FALSE, GNOME_PAD_SMALL); gtk_container_set_border_width(GTK_CONTAINER(hbox), GNOME_PAD_SMALL); find_label = gtk_label_new("Find what:"); find_dialog->find_entry = gtk_entry_new(); gtk_box_pack_start(GTK_BOX(hbox), find_label, FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(hbox), find_dialog->find_entry, TRUE, TRUE, 0); gtk_widget_show_all(hbox); gtk_box_pack_start(GTK_BOX(GNOME_DIALOG(find_dialog)->vbox), hbox, FALSE, FALSE, 0); gtk_signal_connect(GTK_OBJECT(find_dialog->find_entry), "changed", GTK_SIGNAL_FUNC(entry_changed_cb), (gpointer) find_dialog); /* hbox2 */ hbox2 = gtk_hbox_new(TRUE, GNOME_PAD_SMALL); gtk_widget_show(hbox2); gtk_box_pack_start(GTK_BOX(GNOME_DIALOG(find_dialog)->vbox), hbox2, FALSE, FALSE, 0); /* search direction */ dir_frame = gtk_frame_new("Search direction"); dir_vbox = gtk_vbox_new(FALSE, GNOME_PAD_SMALL); gtk_container_set_border_width(GTK_CONTAINER(dir_frame), GNOME_PAD_SMALL); gtk_container_set_border_width(GTK_CONTAINER(dir_vbox), GNOME_PAD_SMALL); gtk_container_add(GTK_CONTAINER(dir_frame), dir_vbox); find_dialog->forwards_radio = gtk_radio_button_new_with_label(NULL, "Forwards"); find_dialog->backwards_radio = gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(find_dialog->forwards_radio), "Backwards"); gtk_box_pack_start(GTK_BOX(dir_vbox), find_dialog->forwards_radio, FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(dir_vbox), find_dialog->backwards_radio, FALSE, FALSE, 0); gtk_widget_show_all(dir_frame); gtk_box_pack_start(GTK_BOX(hbox2), dir_frame, TRUE, TRUE, 0); gtk_signal_connect(GTK_OBJECT(find_dialog->forwards_radio), "clicked", GTK_SIGNAL_FUNC(forwards_clicked_cb), (gpointer) find_dialog); gtk_signal_connect(GTK_OBJECT(find_dialog->backwards_radio), "clicked", GTK_SIGNAL_FUNC(backwards_clicked_cb), (gpointer) find_dialog); /* start position */ pos_frame = gtk_frame_new("Start position"); pos_vbox = gtk_vbox_new(FALSE, GNOME_PAD_SMALL); gtk_container_set_border_width(GTK_CONTAINER(pos_frame), GNOME_PAD_SMALL); gtk_container_set_border_width(GTK_CONTAINER(pos_vbox), GNOME_PAD_SMALL); gtk_container_add(GTK_CONTAINER(pos_frame), pos_vbox); find_dialog->top_radio = gtk_radio_button_new_with_label(NULL, "Top"); find_dialog->cursor_radio = gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(find_dialog->top_radio), "Cursor position"); find_dialog->bottom_radio = gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(find_dialog->top_radio), "Bottom"); gtk_box_pack_start(GTK_BOX(pos_vbox), find_dialog->top_radio, FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(pos_vbox), find_dialog->cursor_radio, FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(pos_vbox), find_dialog->bottom_radio, FALSE, FALSE, 0); gtk_signal_connect(GTK_OBJECT(find_dialog->top_radio), "clicked", GTK_SIGNAL_FUNC(top_clicked_cb), (gpointer) find_dialog); gtk_signal_connect(GTK_OBJECT(find_dialog->cursor_radio), "clicked", GTK_SIGNAL_FUNC(cursor_clicked_cb), (gpointer) find_dialog); gtk_signal_connect(GTK_OBJECT(find_dialog->bottom_radio), "clicked", GTK_SIGNAL_FUNC(bottom_clicked_cb), (gpointer) find_dialog); /* focus stuff */ gtk_widget_grab_focus(find_dialog->find_entry); gnome_dialog_editable_enters(GNOME_DIALOG(find_dialog), GTK_EDITABLE(find_dialog->find_entry)); gnome_dialog_set_default(GNOME_DIALOG(find_dialog), GNOME_FIND_BUTTON_FIND); /* show it all */ gtk_widget_show_all(pos_frame); gtk_box_pack_start(GTK_BOX(hbox2), pos_frame, TRUE, TRUE, 0); } static void gnome_find_dialog_destroy (GtkObject *object) { GnomeFindDialog *find_dialog; g_return_if_fail(object != NULL); g_return_if_fail(GNOME_IS_FIND_DIALOG(object)); find_dialog = GNOME_FIND_DIALOG(object); if(find_dialog->params.find_text) g_free(find_dialog->params.find_text); GTK_OBJECT_CLASS (parent_class)->destroy(object); } GtkWidget *gnome_find_dialog_new (const gchar *title, const GnomeFindDialogParams *find_params, gboolean show_case_sensitive, gboolean show_wrap_search, gboolean show_regex) { GnomeFindDialog *find_dialog; GtkWidget *options_frame, *options_hbox, *case_check, *wrap_check, *regex_check; find_dialog = gtk_type_new(gnome_find_dialog_get_type()); /* set window title */ if(title) gtk_window_set_title(GTK_WINDOW(find_dialog), title); /* initialise parameters */ if(find_params) { find_dialog->params = *find_params; if(find_params->find_text) { gtk_entry_set_text(GTK_ENTRY(find_dialog->find_entry), find_params->find_text); gtk_editable_select_region(GTK_EDITABLE(find_dialog->find_entry), 0, -1); } } else { find_dialog->params.start_pos = GNOME_FIND_TOP; find_dialog->params.direction = GNOME_FIND_FORWARDS; find_dialog->params.case_sensitive = FALSE; find_dialog->params.wrap_search = FALSE; find_dialog->params.regex = FALSE; } find_dialog->params.find_text = NULL; switch(find_dialog->params.direction) { case GNOME_FIND_FORWARDS: gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(find_dialog->forwards_radio), TRUE); break; case GNOME_FIND_BACKWARDS: gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(find_dialog->backwards_radio), TRUE); break; } switch(find_dialog->params.start_pos) { case GNOME_FIND_TOP: gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(find_dialog->top_radio), TRUE); break; case GNOME_FIND_CURSOR: gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(find_dialog->cursor_radio), TRUE); break; case GNOME_FIND_BOTTOM: gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(find_dialog->bottom_radio), TRUE); break; } /* options checkbuttons */ if(show_case_sensitive || show_wrap_search || show_regex) { options_frame = gtk_frame_new("Options"); options_hbox = gtk_hbox_new(TRUE, GNOME_PAD_SMALL); gtk_container_set_border_width(GTK_CONTAINER(options_frame), GNOME_PAD_SMALL); gtk_container_set_border_width(GTK_CONTAINER(options_hbox), GNOME_PAD_SMALL); gtk_container_add(GTK_CONTAINER(options_frame), options_hbox); if(show_case_sensitive) { case_check = gtk_check_button_new_with_label("Case sensitive"); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(case_check), find_dialog->params.case_sensitive); gtk_box_pack_start(GTK_BOX(options_hbox), case_check, TRUE, TRUE, 0); gtk_signal_connect(GTK_OBJECT(case_check), "toggled", GTK_SIGNAL_FUNC(case_toggled_cb), (gpointer) find_dialog); } if(show_wrap_search) { wrap_check = gtk_check_button_new_with_label("Wrap search"); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(wrap_check), find_dialog->params.wrap_search); gtk_box_pack_start(GTK_BOX(options_hbox), wrap_check, TRUE, TRUE, 0); gtk_signal_connect(GTK_OBJECT(wrap_check), "toggled", GTK_SIGNAL_FUNC(wrap_toggled_cb), (gpointer) find_dialog); } if(show_regex) { regex_check = gtk_check_button_new_with_label("Regular expression"); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(regex_check), find_dialog->params.regex); gtk_box_pack_start(GTK_BOX(options_hbox), regex_check, TRUE, TRUE, 0); gtk_signal_connect(GTK_OBJECT(regex_check), "toggled", GTK_SIGNAL_FUNC(regex_toggled_cb), (gpointer) find_dialog); } gtk_widget_show_all(options_frame); gtk_box_pack_start(GTK_BOX(GNOME_DIALOG(find_dialog)->vbox), options_frame, FALSE, FALSE, 0); } return GTK_WIDGET(find_dialog); } gchar *gnome_find_dialog_get_find_text(GnomeFindDialog *dialog) { g_return_val_if_fail(dialog != NULL, NULL); g_return_val_if_fail(GNOME_IS_FIND_DIALOG(dialog), NULL); return gtk_editable_get_chars(GTK_EDITABLE(dialog->find_entry), 0, -1); } static void entry_changed_cb(GtkEditable *editable, gpointer data) { gchar *entry_chars; GnomeFindDialog *find_dialog; g_return_if_fail(editable != NULL); g_return_if_fail(GTK_IS_EDITABLE(editable)); find_dialog = GNOME_FIND_DIALOG(data); g_return_if_fail(find_dialog != NULL); g_return_if_fail(GNOME_IS_FIND_DIALOG(find_dialog)); entry_chars = gtk_editable_get_chars(editable, 0, -1); if((entry_chars != NULL) && (strlen(entry_chars) > 0)) { gnome_dialog_set_sensitive(GNOME_DIALOG(find_dialog), GNOME_FIND_BUTTON_FIND, TRUE); gnome_dialog_set_sensitive(GNOME_DIALOG(find_dialog), GNOME_FIND_BUTTON_FIND_AGAIN, TRUE); } else { gnome_dialog_set_sensitive(GNOME_DIALOG(find_dialog), GNOME_FIND_BUTTON_FIND, FALSE); gnome_dialog_set_sensitive(GNOME_DIALOG(find_dialog), GNOME_FIND_BUTTON_FIND_AGAIN, FALSE); } gnome_dialog_set_default(GNOME_DIALOG(find_dialog), GNOME_FIND_BUTTON_FIND); g_free(entry_chars); } static void forwards_clicked_cb(GtkButton *button, gpointer data) { GnomeFindDialog *find_dialog; g_return_if_fail(button != NULL); g_return_if_fail(GTK_IS_BUTTON(button)); find_dialog = GNOME_FIND_DIALOG(data); g_return_if_fail(find_dialog != NULL); g_return_if_fail(GNOME_IS_FIND_DIALOG(find_dialog)); find_dialog->params.direction = GNOME_FIND_FORWARDS; } static void backwards_clicked_cb (GtkButton *button, gpointer data) { GnomeFindDialog *find_dialog; g_return_if_fail(button != NULL); g_return_if_fail(GTK_IS_BUTTON(button)); find_dialog = GNOME_FIND_DIALOG(data); g_return_if_fail(find_dialog != NULL); g_return_if_fail(GNOME_IS_FIND_DIALOG(find_dialog)); find_dialog->params.direction = GNOME_FIND_BACKWARDS; } static void top_clicked_cb(GtkButton *button, gpointer data) { GnomeFindDialog *find_dialog; g_return_if_fail(button != NULL); g_return_if_fail(GTK_IS_BUTTON(button)); find_dialog = GNOME_FIND_DIALOG(data); g_return_if_fail(find_dialog != NULL); g_return_if_fail(GNOME_IS_FIND_DIALOG(find_dialog)); find_dialog->params.start_pos = GNOME_FIND_TOP; } static void cursor_clicked_cb(GtkButton *button, gpointer data) { GnomeFindDialog *find_dialog; g_return_if_fail(button != NULL); g_return_if_fail(GTK_IS_BUTTON(button)); find_dialog = GNOME_FIND_DIALOG(data); g_return_if_fail(find_dialog != NULL); g_return_if_fail(GNOME_IS_FIND_DIALOG(find_dialog)); find_dialog->params.start_pos = GNOME_FIND_CURSOR; } static void bottom_clicked_cb(GtkButton *button, gpointer data) { GnomeFindDialog *find_dialog; g_return_if_fail(button != NULL); g_return_if_fail(GTK_IS_BUTTON(button)); find_dialog = GNOME_FIND_DIALOG(data); g_return_if_fail(find_dialog != NULL); g_return_if_fail(GNOME_IS_FIND_DIALOG(find_dialog)); find_dialog->params.start_pos = GNOME_FIND_BOTTOM; } static void case_toggled_cb(GtkToggleButton *button, gpointer data) { GnomeFindDialog *find_dialog; g_return_if_fail(button != NULL); g_return_if_fail(GTK_IS_TOGGLE_BUTTON(button)); find_dialog = GNOME_FIND_DIALOG(data); g_return_if_fail(find_dialog != NULL); g_return_if_fail(GNOME_IS_FIND_DIALOG(find_dialog)); if(button->active) { find_dialog->params.case_sensitive = TRUE; } else { find_dialog->params.case_sensitive = FALSE; } } static void wrap_toggled_cb(GtkToggleButton *button, gpointer data) { GnomeFindDialog *find_dialog; g_return_if_fail(button != NULL); g_return_if_fail(GTK_IS_TOGGLE_BUTTON(button)); find_dialog = GNOME_FIND_DIALOG(data); g_return_if_fail(find_dialog != NULL); g_return_if_fail(GNOME_IS_FIND_DIALOG(find_dialog)); if(button->active) { find_dialog->params.wrap_search = TRUE; } else { find_dialog->params.wrap_search = FALSE; } } static void regex_toggled_cb(GtkToggleButton *button, gpointer data) { GnomeFindDialog *find_dialog; g_return_if_fail(button != NULL); g_return_if_fail(GTK_IS_TOGGLE_BUTTON(button)); find_dialog = GNOME_FIND_DIALOG(data); g_return_if_fail(find_dialog != NULL); g_return_if_fail(GNOME_IS_FIND_DIALOG(find_dialog)); if(button->active) { find_dialog->params.regex = TRUE; } else { find_dialog->params.regex = FALSE; } gnome_dialog_set_default(GNOME_DIALOG(find_dialog), GNOME_FIND_BUTTON_FIND); } static void dialog_clicked_cb(GnomeDialog *dialog, gint button, gpointer data) { GnomeFindDialog *find_dialog; g_return_if_fail(dialog != NULL); g_return_if_fail(GNOME_IS_FIND_DIALOG(dialog)); find_dialog = GNOME_FIND_DIALOG(dialog); switch(button) { case 0: gnome_dialog_set_default(dialog, GNOME_FIND_BUTTON_FIND_AGAIN); find(find_dialog); break; case 1: find_again(find_dialog); break; case 2: close(find_dialog); break; default: g_assert_not_reached(); } } static void find(GnomeFindDialog *find_dialog) { gtk_signal_emit(GTK_OBJECT(find_dialog), find_dialog_signals[FIND]); } static void find_again(GnomeFindDialog *find_dialog) { gtk_signal_emit(GTK_OBJECT(find_dialog), find_dialog_signals[FIND_AGAIN]); } static void close(GnomeFindDialog *find_dialog) { gnome_dialog_close(GNOME_DIALOG(find_dialog)); }