/* * Copyright (C) 2000, 2001, 2002 Marco Pesenti Gritti * * 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, 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. */ #include "ephy-dialog.h" #include "ephy-glade.h" #include "ephy-state.h" #include "ephy-gui.h" #include "eel-gconf-extensions.h" #include #include static void ephy_dialog_class_init (EphyDialogClass *klass); static void ephy_dialog_init (EphyDialog *window); static void ephy_dialog_finalize (GObject *object); static void ephy_dialog_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec); static void ephy_dialog_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec); static void ephy_dialog_set_parent (EphyDialog *dialog, GtkWidget *parent); static void impl_construct (EphyDialog *dialog, const EphyDialogProperty *properties, const char *file, const char *name); static void impl_destruct (EphyDialog *dialog); static GtkWidget * impl_get_control (EphyDialog *dialog, int property_id); static void impl_get_value (EphyDialog *dialog, int property_id, GValue *value); static gint impl_run (EphyDialog *dialog); static void impl_show (EphyDialog *dialog); void ephy_dialog_destroy_cb (GtkWidget *widget, EphyDialog *dialog); enum { PROP_0, PROP_PARENT_WINDOW, PROP_MODAL }; typedef enum { PT_TOGGLEBUTTON, PT_RADIOBUTTON, PT_SPINBUTTON, PT_COLOR, PT_OPTIONMENU, PT_ENTRY, PT_UNKNOWN } PrefType; typedef struct { int id; GtkWidget *widget; const char *pref; int *sg; PropertyType type; GList *string_enum; } PropertyInfo; struct EphyDialogPrivate { GtkWidget *parent; GtkWidget *dialog; GtkWidget *container; PropertyInfo *props; gboolean modal; char *name; int spin_item_id; GTimer *spin_timer; gboolean initialized; }; #define SPIN_DELAY 0.20 static GObjectClass *parent_class = NULL; GType ephy_dialog_get_type (void) { static GType ephy_dialog_type = 0; if (ephy_dialog_type == 0) { static const GTypeInfo our_info = { sizeof (EphyDialogClass), NULL, /* base_init */ NULL, /* base_finalize */ (GClassInitFunc) ephy_dialog_class_init, NULL, NULL, /* class_data */ sizeof (EphyDialog), 0, /* n_preallocs */ (GInstanceInitFunc) ephy_dialog_init }; ephy_dialog_type = g_type_register_static (G_TYPE_OBJECT, "EphyDialog", &our_info, 0); } return ephy_dialog_type; } static void ephy_dialog_class_init (EphyDialogClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); parent_class = g_type_class_peek_parent (klass); object_class->finalize = ephy_dialog_finalize; object_class->set_property = ephy_dialog_set_property; object_class->get_property = ephy_dialog_get_property; klass->construct = impl_construct; klass->get_control = impl_get_control; klass->get_value = impl_get_value; klass->run = impl_run; klass->show = impl_show; klass->destruct = impl_destruct; g_object_class_install_property (object_class, PROP_PARENT_WINDOW, g_param_spec_object ("ParentWindow", "ParentWindow", "Parent window", GTK_TYPE_WIDGET, G_PARAM_READWRITE)); g_object_class_install_property (object_class, PROP_MODAL, g_param_spec_boolean ("Modal", "Modal", "Modal dialog", FALSE, G_PARAM_READWRITE)); } static void set_config_from_editable (GtkWidget *editable, const char *config_name) { GConfValue *gcvalue = eel_gconf_get_value (config_name); GConfValueType value_type; char *value; gint ivalue; gfloat fvalue; if (gcvalue == NULL) { /* ugly hack around what appears to be a gconf bug * it returns a NULL GConfValue for a valid string pref * which is "" by default */ value_type = GCONF_VALUE_STRING; } else { value_type = gcvalue->type; gconf_value_free (gcvalue); } /* get all the text into a new string */ value = gtk_editable_get_chars (GTK_EDITABLE(editable), 0, -1); switch (value_type) { case GCONF_VALUE_STRING: eel_gconf_set_string (config_name, value); break; /* FIXME : handle possible errors in the input for int and float */ case GCONF_VALUE_INT: ivalue = atoi (value); eel_gconf_set_integer (config_name, ivalue); break; case GCONF_VALUE_FLOAT: fvalue = strtod (value, (char**)NULL); eel_gconf_set_float (config_name, fvalue); break; default: break; } /* free the allocated strings */ g_free (value); } static void set_config_from_optionmenu (GtkWidget *optionmenu, const char *config_name, GList *senum) { int index = gtk_option_menu_get_history (GTK_OPTION_MENU (optionmenu)); if (senum) { eel_gconf_set_string (config_name, g_list_nth_data (senum, index)); } else { eel_gconf_set_integer (config_name, index); } } static int get_radio_button_active_index (GtkWidget *radiobutton) { gint index; GtkToggleButton *toggle_button; gint i, length; GSList *list; /* get group list */ list = gtk_radio_button_get_group (GTK_RADIO_BUTTON (radiobutton)); length = g_slist_length (list); /* iterate over list to find active button */ for (i = 0; list != NULL; i++, list = g_slist_next (list)) { /* get button and text */ toggle_button = GTK_TOGGLE_BUTTON (list->data); if (gtk_toggle_button_get_active (toggle_button)) { break; } } /* check we didn't run off end */ g_assert (list != NULL); /* return index (reverse order!) */ return index = (length - 1) - i; } static void set_config_from_radiobuttongroup (GtkWidget *radiobutton, const char *config_name, GList *senum) { int index; index = get_radio_button_active_index (radiobutton); if (senum) { eel_gconf_set_string (config_name, g_list_nth_data (senum, index)); } else { eel_gconf_set_integer (config_name, index); } } static void set_config_from_spin_button (GtkWidget *spinbutton, const char *config_name) { gdouble value; gboolean use_int; /* read the value as an integer */ value = gtk_spin_button_get_value (GTK_SPIN_BUTTON(spinbutton)); use_int = (gtk_spin_button_get_digits (GTK_SPIN_BUTTON(spinbutton)) == 0); if (use_int) { eel_gconf_set_integer (config_name, value); } else { eel_gconf_set_float (config_name, value); } } static void set_config_from_togglebutton (GtkWidget *togglebutton, const char *config_name) { gboolean value; /* read the value */ value = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(togglebutton)); eel_gconf_set_boolean (config_name, value); } static void set_config_from_color (GtkWidget *colorpicker, const char *config_name) { guint8 r, g, b, a; gchar color_string[9]; /* get color values from color picker */ gnome_color_picker_get_i8 (GNOME_COLOR_PICKER (colorpicker), &r, &g, &b, &a); /* write into string (bounded size) */ snprintf (color_string, 9, "#%02X%02X%02X", r, g, b); /* set the configuration value */ eel_gconf_set_string (config_name, color_string); } static void set_editable_from_config (GtkWidget *editable, const char *config_name) { GConfValue *gcvalue = eel_gconf_get_value (config_name); GConfValueType value_type; gchar *value; if (gcvalue == NULL) { /* ugly hack around what appears to be a gconf bug * it returns a NULL GConfValue for a valid string pref * which is "" by default */ value_type = GCONF_VALUE_STRING; } else { value_type = gcvalue->type; gconf_value_free (gcvalue); } switch (value_type) { case GCONF_VALUE_STRING: value = eel_gconf_get_string (config_name); break; case GCONF_VALUE_INT: value = g_strdup_printf ("%d",eel_gconf_get_integer (config_name)); break; case GCONF_VALUE_FLOAT: value = g_strdup_printf ("%.2f",eel_gconf_get_float (config_name)); break; default: value = NULL; } /* set this string value in the widget */ if (value) { gtk_entry_set_text(GTK_ENTRY(editable), value); } /* free the allocated string */ g_free (value); } static int get_index (const char *config_name, GList *senum) { int index = 0; char *val; GList *s = NULL; if (senum) { val = eel_gconf_get_string (config_name); if (val) { s = g_list_find_custom (senum, val, (GCompareFunc)strcmp); g_free (val); } if (s) { index = g_list_position (senum, s); } } else { index = eel_gconf_get_integer (config_name); } return index; } static void set_optionmenu_from_config (GtkWidget *optionmenu, const char *config_name, GList *senum) { gtk_option_menu_set_history (GTK_OPTION_MENU (optionmenu), get_index (config_name, senum)); } static void set_radiobuttongroup_from_config (GtkWidget *radiobutton, const char *config_name, GList *senum) { GtkToggleButton *button; GSList *list; gint length; int index; index = get_index (config_name, senum); /* get the list */ list = gtk_radio_button_get_group (GTK_RADIO_BUTTON (radiobutton)); /* check out the length */ length = g_slist_length (list); /* new buttons are *preppended* to the list, so button added as first * has last position in the list */ index = (length - 1) - index; /* find the right button */ button = GTK_TOGGLE_BUTTON (g_slist_nth_data (list, index)); /* set it... this will de-activate the others in the group */ if (gtk_toggle_button_get_active (button) == FALSE) { gtk_toggle_button_set_active (button, TRUE); } } static void set_spin_button_from_config (GtkWidget *spinbutton, const char *config_name) { gdouble value; gint use_int; use_int = (gtk_spin_button_get_digits (GTK_SPIN_BUTTON(spinbutton)) == 0); if (use_int) { /* get the current value from the configuration space */ value = eel_gconf_get_integer (config_name); } else { /* get the current value from the configuration space */ value = eel_gconf_get_float (config_name); } /* set this option value in the widget */ gtk_spin_button_set_value(GTK_SPIN_BUTTON(spinbutton), value); } static void set_togglebutton_from_config (GtkWidget *togglebutton, const char *config_name) { gboolean value; /* get the current value from the configuration space */ value = eel_gconf_get_boolean (config_name); /* set this option value in the widget */ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (togglebutton), value); } static void set_color_from_config (GtkWidget *colorpicker, const char *config_name) { gchar *color_string; guint r, g, b; /* get the string from config */ color_string = eel_gconf_get_string (config_name); if (color_string) { /* parse it and setup the color picker */ sscanf (color_string, "#%2X%2X%2X", &r, &g, &b); gnome_color_picker_set_i8 (GNOME_COLOR_PICKER (colorpicker), r, g, b, 0); /* free the string */ g_free (color_string); } } static PrefType get_pref_type_from_widget (GtkWidget *widget) { if (GTK_IS_OPTION_MENU (widget)) { return PT_OPTIONMENU; } else if (GTK_IS_SPIN_BUTTON (widget)) { return PT_SPINBUTTON; } else if (GTK_IS_RADIO_BUTTON (widget)) { return PT_RADIOBUTTON; } else if (GTK_IS_TOGGLE_BUTTON (widget)) { return PT_TOGGLEBUTTON; } else if (GTK_IS_ENTRY (widget)) { return PT_ENTRY; } else if (GNOME_IS_COLOR_PICKER (widget)) { return PT_COLOR; } return PT_UNKNOWN; } static int * set_controls_sensitivity (EphyDialog *dialog, int *sg, gboolean s) { GtkWidget *widget; while (*sg != SY_END_GROUP) { widget = ephy_dialog_get_control (dialog, *sg); gtk_widget_set_sensitive (widget, s); sg++; } return sg; } static void prefs_set_group_sensitivity (GtkWidget *widget, PrefType type, int *sg) { int group = -1; EphyDialog *dialog; int i = 0; if (sg == NULL) return; dialog = EPHY_DIALOG (g_object_get_data (G_OBJECT(widget), "dialog")); if (GTK_IS_RADIO_BUTTON (widget)) { group = get_radio_button_active_index (widget); } else if (GTK_IS_TOGGLE_BUTTON (widget)) { group = !gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(widget)); } else { g_assert (FALSE); } while (*sg != SY_END) { if ((*sg == SY_BEGIN_GROUP) || (*sg == SY_BEGIN_GROUP_INVERSE)) { gboolean b; b = (i == group); if (*sg == SY_BEGIN_GROUP_INVERSE) b = !b; sg++; sg = set_controls_sensitivity (dialog, sg, b); } i++; sg++; } } static void prefs_togglebutton_clicked_cb (GtkWidget *widget, PropertyInfo *pi) { if (pi->type == PT_AUTOAPPLY) { set_config_from_togglebutton (widget, pi->pref); } prefs_set_group_sensitivity (widget, pi->type, pi->sg); } static void prefs_radiobutton_clicked_cb (GtkWidget *widget, PropertyInfo *pi) { if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(widget))) { return; } if (pi->type == PT_AUTOAPPLY) { set_config_from_radiobuttongroup (widget, pi->pref, pi->string_enum); } prefs_set_group_sensitivity (widget, pi->type, pi->sg); } static gint prefs_spinbutton_timeout_cb (EphyDialog *dialog) { PropertyInfo pi = dialog->priv->props[dialog->priv->spin_item_id]; /* timer still valid? */ if (dialog->priv->spin_timer == NULL) { return FALSE; } /* okay, we're ready to set */ if (g_timer_elapsed (dialog->priv->spin_timer, NULL) >= SPIN_DELAY) { /* kill off the timer */ g_timer_destroy (dialog->priv->spin_timer); dialog->priv->spin_timer = NULL; /* HACK update the spinbutton here so that the * changes made directly in the entry are accepted * and set in the pref. Otherwise the old value is used */ gtk_spin_button_update (GTK_SPIN_BUTTON(pi.widget)); /* set */ set_config_from_spin_button (pi.widget, pi.pref); /* done now */ return FALSE; } /* call me again */ return TRUE; } static void prefs_spinbutton_changed_cb (GtkWidget *widget, PropertyInfo *pi) { EphyDialog *dialog; if (pi->type != PT_AUTOAPPLY) return; dialog = EPHY_DIALOG (g_object_get_data (G_OBJECT(widget), "dialog")); dialog->priv->spin_item_id = pi->id; /* destroy any existing timer */ if (dialog->priv->spin_timer != NULL) { g_timer_destroy (dialog->priv->spin_timer); } /* start the new one */ dialog->priv->spin_timer = g_timer_new(); g_timer_start (dialog->priv->spin_timer); g_timeout_add (50, (GSourceFunc) prefs_spinbutton_timeout_cb, dialog); } static void prefs_color_changed_cb (GtkWidget *widget, guint r, guint g, guint b, guint a, const PropertyInfo *pi) { if (pi->type == PT_AUTOAPPLY) { set_config_from_color (widget, pi->pref); } } static void prefs_entry_changed_cb (GtkWidget *widget, PropertyInfo *pi) { if (pi->type == PT_AUTOAPPLY) { set_config_from_editable (widget, pi->pref); } } static void prefs_optionmenu_selected_cb (GtkWidget *widget, PropertyInfo *pi) { if (pi->type == PT_AUTOAPPLY) { set_config_from_optionmenu (widget, pi->pref, pi->string_enum); } } static void prefs_connect_signals (EphyDialog *dialog) { int i; GSList *list; PropertyInfo *props = dialog->priv->props; for (i = 0; props[i].widget != NULL; i++) { PrefType type; PropertyInfo *info; if ((props[i].type != PT_AUTOAPPLY) && (props[i].sg == NULL)) continue; info = &dialog->priv->props[i]; type = get_pref_type_from_widget (dialog->priv->props[i].widget); switch (type) { case PT_TOGGLEBUTTON: g_object_set_data (G_OBJECT(info->widget), "dialog", dialog); g_signal_connect (G_OBJECT (info->widget), "clicked", G_CALLBACK(prefs_togglebutton_clicked_cb), (gpointer)info); break; case PT_RADIOBUTTON: list = gtk_radio_button_get_group (GTK_RADIO_BUTTON(info->widget)); for (; list != NULL; list = list->next) { g_object_set_data (G_OBJECT(list->data), "dialog", dialog); g_signal_connect (G_OBJECT (list->data), "clicked", G_CALLBACK(prefs_radiobutton_clicked_cb), (gpointer)info); } break; case PT_SPINBUTTON: g_object_set_data (G_OBJECT(info->widget), "dialog", dialog); g_signal_connect (G_OBJECT (info->widget), "changed", G_CALLBACK(prefs_spinbutton_changed_cb), (gpointer)info); break; case PT_COLOR: g_signal_connect (G_OBJECT (info->widget), "color_set", G_CALLBACK(prefs_color_changed_cb), (gpointer)info); break; case PT_OPTIONMENU: g_signal_connect (G_OBJECT (info->widget), "changed", G_CALLBACK(prefs_optionmenu_selected_cb), (gpointer)info); break; case PT_ENTRY: g_signal_connect (G_OBJECT (info->widget), "changed", G_CALLBACK(prefs_entry_changed_cb), (gpointer)info); break; case PT_UNKNOWN: break; } } } static void ephy_dialog_init (EphyDialog *dialog) { dialog->priv = g_new0 (EphyDialogPrivate, 1); dialog->priv->parent = NULL; dialog->priv->dialog = NULL; dialog->priv->props = NULL; dialog->priv->spin_timer = NULL; dialog->priv->name = NULL; dialog->priv->initialized = FALSE; } static void prefs_set_sensitivity (PropertyInfo *props) { int i; for (i=0 ; props[i].id >= 0; i++) { if (props[i].sg == NULL) continue; g_return_if_fail (props[i].widget != NULL); if (GTK_IS_RADIO_BUTTON(props[i].widget) || GTK_IS_TOGGLE_BUTTON(props[i].widget)) { prefs_set_group_sensitivity (props[i].widget, props[i].type, props[i].sg); } } } static void load_props (PropertyInfo *props) { int i; for (i=0 ; props[i].id >= 0; i++) { if (props[i].pref == NULL) continue; g_return_if_fail (props[i].widget != NULL); if (GTK_IS_SPIN_BUTTON(props[i].widget)) { set_spin_button_from_config (props[i].widget, props[i].pref); } else if (GTK_IS_RADIO_BUTTON(props[i].widget)) { set_radiobuttongroup_from_config (props[i].widget, props[i].pref, props[i].string_enum); } else if (GTK_IS_TOGGLE_BUTTON(props[i].widget)) { set_togglebutton_from_config (props[i].widget, props[i].pref); } else if (GTK_IS_EDITABLE(props[i].widget)) { set_editable_from_config (props[i].widget, props[i].pref); } else if (GTK_IS_OPTION_MENU(props[i].widget)) { set_optionmenu_from_config (props[i].widget, props[i].pref, props[i].string_enum); } else if (GNOME_IS_COLOR_PICKER(props[i].widget)) { set_color_from_config (props[i].widget, props[i].pref); } } } static void save_props (PropertyInfo *props) { int i; for (i=0 ; props[i].id >= 0; i++) { if ((props[i].pref == NULL) || (props[i].type != PT_NORMAL)) continue; g_return_if_fail (props[i].widget != NULL); if (GTK_IS_SPIN_BUTTON(props[i].widget)) { set_config_from_spin_button (props[i].widget, props[i].pref); } else if (GTK_IS_RADIO_BUTTON(props[i].widget)) { set_config_from_radiobuttongroup (props[i].widget, props[i].pref, props[i].string_enum); } else if (GTK_IS_TOGGLE_BUTTON(props[i].widget)) { set_config_from_togglebutton (props[i].widget, props[i].pref); } else if (GTK_IS_EDITABLE(props[i].widget)) { set_config_from_editable (props[i].widget, props[i].pref); } else if (GTK_IS_OPTION_MENU(props[i].widget)) { set_config_from_optionmenu (props[i].widget, props[i].pref, props[i].string_enum); } else if (GNOME_IS_COLOR_PICKER(props[i].widget)) { set_config_from_color (props[i].widget, props[i].pref); } } } static void free_props (PropertyInfo *properties) { int i; for (i = 0; properties[i].string_enum != NULL; i++) { g_list_foreach (properties[i].string_enum, (GFunc)g_free, NULL); g_list_free (properties[i].string_enum); } } static void ephy_dialog_finalize (GObject *object) { EphyDialog *dialog; g_return_if_fail (object != NULL); g_return_if_fail (IS_EPHY_DIALOG (object)); dialog = EPHY_DIALOG (object); g_return_if_fail (dialog->priv != NULL); if (dialog->priv->dialog) { ephy_dialog_destruct (dialog); } free_props (dialog->priv->props); g_free (dialog->priv->name); g_free (dialog->priv->props); g_free (dialog->priv); G_OBJECT_CLASS (parent_class)->finalize (object); } static void ephy_dialog_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { EphyDialog *d = EPHY_DIALOG (object); switch (prop_id) { case PROP_PARENT_WINDOW: ephy_dialog_set_parent (d, g_value_get_object (value)); break; case PROP_MODAL: ephy_dialog_set_modal (d, g_value_get_boolean (value)); break; } } static void ephy_dialog_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { EphyDialog *d = EPHY_DIALOG (object); switch (prop_id) { case PROP_PARENT_WINDOW: g_value_set_object (value, d->priv->parent); break; case PROP_MODAL: g_value_set_boolean (value, d->priv->modal); } } static void ephy_dialog_set_parent (EphyDialog *dialog, GtkWidget *parent) { g_return_if_fail (dialog->priv->parent == NULL); g_return_if_fail (GTK_IS_WINDOW(parent)); g_return_if_fail (GTK_IS_WINDOW(dialog->priv->dialog)); dialog->priv->parent = parent; gtk_window_set_transient_for (GTK_WINDOW (dialog->priv->dialog), GTK_WINDOW (parent)); } EphyDialog * ephy_dialog_new (void) { return EPHY_DIALOG (g_object_new (EPHY_DIALOG_TYPE, NULL)); } EphyDialog * ephy_dialog_new_with_parent (GtkWidget *parent_window) { return EPHY_DIALOG (g_object_new (EPHY_DIALOG_TYPE, "ParentWindow", parent_window, NULL)); } void ephy_dialog_add_enum (EphyDialog *dialog, int id, guint n_items, const char **items) { int i = 0; GList *l = NULL; for (i = 0; i < n_items; i++) { l = g_list_append (l, g_strdup (items[i])); } dialog->priv->props[id].string_enum = l; } static PropertyInfo * init_props (const EphyDialogProperty *properties, GladeXML *gxml) { PropertyInfo *props; int i; for (i=0 ; properties[i].control_name != NULL; i++); props = g_new0 (PropertyInfo, i+1); for (i=0 ; properties[i].control_name != NULL; i++) { props[i].id = properties[i].id; props[i].widget = glade_xml_get_widget (gxml, properties[i].control_name); props[i].pref = properties[i].state_pref; props[i].sg = properties[i].sg; props[i].type = properties[i].type; props[i].string_enum = NULL; } props[i].id = -1; props[i].widget = NULL; props[i].pref = NULL; props[i].sg = NULL; props[i].type = 0; props[i].string_enum = NULL; return props; } static void dialog_destruction_notify (EphyDialog *dialog, GObject *where_the_object_was) { dialog->priv->dialog = NULL; ephy_dialog_destruct (dialog); g_object_unref (dialog); } static void dialog_destroy_cb (GtkWidget *widget, EphyDialog *dialog) { if (dialog->priv->props && dialog->priv->dialog) { save_props (dialog->priv->props); } } static void impl_construct (EphyDialog *dialog, const EphyDialogProperty *properties, const char *file, const char *name) { GladeXML *gxml; gxml = ephy_glade_widget_new (file, name, &(dialog->priv->dialog), dialog); if (dialog->priv->name == NULL) { dialog->priv->name = g_strdup (name); } if (properties) { dialog->priv->props = init_props (properties, gxml); } g_signal_connect (dialog->priv->dialog, "destroy", G_CALLBACK(dialog_destroy_cb), dialog); g_object_unref (gxml); g_object_weak_ref (G_OBJECT(dialog->priv->dialog), (GWeakNotify)dialog_destruction_notify, dialog); } static void impl_destruct (EphyDialog *dialog) { if (dialog->priv->dialog) { g_object_weak_unref (G_OBJECT(dialog->priv->dialog), (GWeakNotify)dialog_destruction_notify, dialog); gtk_widget_destroy (dialog->priv->dialog); dialog->priv->dialog = NULL; } } static GtkWidget * impl_get_control (EphyDialog *dialog, int property_id) { return dialog->priv->props[property_id].widget; } static void impl_get_value (EphyDialog *dialog, int property_id, GValue *value) { GtkWidget *widget = ephy_dialog_get_control (dialog, property_id); if (GTK_IS_SPIN_BUTTON (widget)) { float val; g_value_init (value, G_TYPE_FLOAT); val = gtk_spin_button_get_value (GTK_SPIN_BUTTON(widget)); g_value_set_float (value, val); } else if (GTK_IS_RADIO_BUTTON (widget)) { int val; g_value_init (value, G_TYPE_INT); val = get_radio_button_active_index (widget); g_value_set_int (value, val); } else if (GTK_IS_TOGGLE_BUTTON (widget)) { g_value_init (value, G_TYPE_BOOLEAN); g_value_set_boolean (value, gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(widget))); } else if (GTK_IS_EDITABLE (widget)) { gchar *text = gtk_editable_get_chars (GTK_EDITABLE (widget), 0, -1); g_value_init (value, G_TYPE_STRING); g_value_set_string (value, text); g_free (text); } else if (GTK_IS_OPTION_MENU (widget)) { int val; g_value_init (value, G_TYPE_INT); val = gtk_option_menu_get_history (GTK_OPTION_MENU(widget)); g_value_set_int (value, val); } } static void setup_default_size (EphyDialog *dialog) { ephy_state_add_window (dialog->priv->dialog, dialog->priv->name, -1, -1, EPHY_STATE_WINDOW_SAVE_SIZE); } static gint impl_run (EphyDialog *dialog) { setup_default_size (dialog); return gtk_dialog_run (GTK_DIALOG(dialog->priv->dialog)); } static void impl_show (EphyDialog *dialog) { if (dialog->priv->props && !dialog->priv->initialized) { load_props (dialog->priv->props); prefs_connect_signals (dialog); prefs_set_sensitivity (dialog->priv->props); dialog->priv->initialized = TRUE; } setup_default_size (dialog); if (dialog->priv->parent) { /* make the dialog transient again, because it seems to get * forgotten after gtk_widget_hide */ gtk_window_set_transient_for (GTK_WINDOW (dialog->priv->dialog), GTK_WINDOW (dialog->priv->parent)); } gtk_window_present (GTK_WINDOW(dialog->priv->dialog)); } void ephy_dialog_set_modal (EphyDialog *dialog, gboolean is_modal) { dialog->priv->modal = is_modal; gtk_window_set_modal (GTK_WINDOW(dialog->priv->dialog), is_modal); } void ephy_dialog_construct (EphyDialog *dialog, const EphyDialogProperty *properties, const char *file, const char *name) { EphyDialogClass *klass = EPHY_DIALOG_GET_CLASS (dialog); return klass->construct (dialog, properties, file, name); } void ephy_dialog_destruct (EphyDialog *dialog) { EphyDialogClass *klass = EPHY_DIALOG_GET_CLASS (dialog); klass->destruct (dialog); } gint ephy_dialog_run (EphyDialog *dialog) { EphyDialogClass *klass = EPHY_DIALOG_GET_CLASS (dialog); return klass->run (dialog); } void ephy_dialog_show (EphyDialog *dialog) { EphyDialogClass *klass = EPHY_DIALOG_GET_CLASS (dialog); klass->show (dialog); } GtkWidget * ephy_dialog_get_control (EphyDialog *dialog, int property_id) { EphyDialogClass *klass = EPHY_DIALOG_GET_CLASS (dialog); return klass->get_control (dialog, property_id); } void ephy_dialog_get_value (EphyDialog *dialog, int property_id, GValue *value) { EphyDialogClass *klass = EPHY_DIALOG_GET_CLASS (dialog); return klass->get_value (dialog, property_id, value); }