aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/ephy-dialog.c1672
-rw-r--r--lib/ephy-dialog.h113
-rw-r--r--lib/ephy-file-chooser.c5
3 files changed, 995 insertions, 795 deletions
diff --git a/lib/ephy-dialog.c b/lib/ephy-dialog.c
index 78e72af93..b82b0faef 100644
--- a/lib/ephy-dialog.c
+++ b/lib/ephy-dialog.c
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2000-2003 Marco Pesenti Gritti
+ * Copyright (C) 2003 Christian Persch
*
* 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
@@ -18,56 +19,26 @@
* $Id$
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include "ephy-dialog.h"
#include "ephy-glade.h"
#include "ephy-state.h"
#include "ephy-gui.h"
#include "eel-gconf-extensions.h"
+#include "ephy-debug.h"
#include <stdlib.h>
#include <string.h>
#include <gtk/gtktogglebutton.h>
-
-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 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);
+#include <gtk/gtkradiobutton.h>
+#include <gtk/gtkoptionmenu.h>
+#include <gtk/gtkcombobox.h>
+#include <gtk/gtkspinbutton.h>
+#include <gtk/gtkeditable.h>
+#include <gtk/gtkentry.h>
enum
{
@@ -78,197 +49,300 @@ enum
typedef enum
{
- PT_TOGGLEBUTTON,
- PT_RADIOBUTTON,
- PT_SPINBUTTON,
- PT_OPTIONMENU,
- PT_ENTRY,
+ PT_TOGGLEBUTTON,
+ PT_RADIOBUTTON,
+ PT_SPINBUTTON,
+ PT_OPTIONMENU,
+ PT_COMBOBOX,
+ PT_EDITABLE,
PT_UNKNOWN
-} PrefType;
+} WidgetType;
typedef struct
{
- int id;
+ const char *id;
+ char *pref;
+ EphyDialogApplyType apply_type;
GtkWidget *widget;
- const char *pref;
- int *sg;
- PropertyType type;
+ WidgetType widget_type;
+ GType data_type;
GList *string_enum;
+ int data_col;
+ gboolean loaded;
+ gboolean sane_state;
} PropertyInfo;
#define EPHY_DIALOG_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), EPHY_TYPE_DIALOG, EphyDialogPrivate))
struct EphyDialogPrivate
{
+ char *name;
+
+ GHashTable *props;
GtkWidget *parent;
GtkWidget *dialog;
- GtkWidget *container;
- PropertyInfo *props;
gboolean modal;
gboolean has_default_size;
gboolean disposing;
- char *name;
-
- int spin_item_id;
- GTimer *spin_timer;
gboolean initialized;
};
#define SPIN_DELAY 0.20
+static void ephy_dialog_class_init (EphyDialogClass *klass);
+static void ephy_dialog_init (EphyDialog *window);
+
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_dispose (GObject *object)
-{
- EphyDialog *dialog = EPHY_DIALOG (object);
+ static GType type = 0;
- if (dialog->priv->dialog)
+ if (type == 0)
{
- dialog->priv->disposing = TRUE;
- gtk_widget_destroy (dialog->priv->dialog);
- dialog->priv->dialog = NULL;
+ 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
+ };
+
+ type = g_type_register_static (G_TYPE_OBJECT,
+ "EphyDialog",
+ &our_info, 0);
}
+
+ return type;
}
-static void
-ephy_dialog_class_init (EphyDialogClass *klass)
+static PropertyInfo *
+lookup_info (EphyDialog *dialog, const char *id)
{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
- parent_class = g_type_class_peek_parent (klass);
-
- object_class->finalize = ephy_dialog_finalize;
- object_class->dispose = ephy_dialog_dispose;
- object_class->set_property = ephy_dialog_set_property;
- object_class->get_property = ephy_dialog_get_property;
+ return g_hash_table_lookup (dialog->priv->props, id);
+}
- klass->construct = impl_construct;
- klass->get_control = impl_get_control;
- klass->get_value = impl_get_value;
- klass->run = impl_run;
- klass->show = impl_show;
+static void
+set_sensitivity (PropertyInfo *info, gboolean sensitive)
+{
+ g_return_if_fail (info->widget != NULL);
- g_object_class_install_property (object_class,
- PROP_PARENT_WINDOW,
- g_param_spec_object ("ParentWindow",
- "ParentWindow",
- "Parent window",
- GTK_TYPE_WIDGET,
- G_PARAM_READWRITE));
+ if (info->widget_type == PT_RADIOBUTTON)
+ {
+ GSList *list, *l;
- g_object_class_install_property (object_class,
- PROP_MODAL,
- g_param_spec_boolean ("Modal",
- "Modal",
- "Modal dialog",
- FALSE,
- G_PARAM_READWRITE));
+ list = gtk_radio_button_get_group (GTK_RADIO_BUTTON (info->widget));
- g_type_class_add_private (object_class, sizeof (EphyDialogPrivate));
+ for (l = list; l != NULL; l = l->next)
+ {
+ gtk_widget_set_sensitive (GTK_WIDGET (l->data), sensitive);
+ }
+ }
+ else
+ {
+ gtk_widget_set_sensitive (info->widget, sensitive);
+ }
}
static void
-set_config_from_editable (GtkWidget *editable, const char *config_name)
+set_value_from_pref (PropertyInfo *info, GValue *value)
{
- GConfValue *gcvalue = eel_gconf_get_value (config_name);
+ GConfValue *gcvalue;
GConfValueType value_type;
- char *value;
- gint ivalue;
- gfloat fvalue;
+ char *text;
- if (gcvalue == NULL) {
+ gcvalue = eel_gconf_get_value (info->pref);
+ 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 {
+ }
+ 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);
+ switch (value_type)
+ {
+ case GCONF_VALUE_STRING:
+ g_value_init (value, G_TYPE_STRING);
+ text = eel_gconf_get_string (info->pref);
+ g_value_take_string (value, text ? text : g_strdup (""));
+ break;
+ case GCONF_VALUE_INT:
+ g_value_init (value, G_TYPE_INT);
+ g_value_set_int (value, eel_gconf_get_integer (info->pref));
+ break;
+ case GCONF_VALUE_FLOAT:
+ g_value_init (value, G_TYPE_FLOAT);
+ g_value_set_float (value, eel_gconf_get_float (info->pref));
+ break;
+ case GCONF_VALUE_BOOL:
+ g_value_init (value, G_TYPE_BOOLEAN);
+ g_value_set_boolean (value, eel_gconf_get_boolean (info->pref));
+ break;
+ default:
+ g_warning ("Unsupported value read from pref %s\n", info->pref);
+ break;
+ }
+
+ if (!G_VALUE_HOLDS (value, info->data_type))
+ {
+ g_warning ("Pref %s has wrong value type for id %s!\n", info->pref, info->id);
+ }
+
+ LOG ("id[%s], pref[%s]: %s", info->id, info->pref, g_strdup_value_contents (value))
+}
+
+static void
+set_pref_from_value (PropertyInfo *info, GValue *value)
+{
+ const char *pref = info->pref;
+ g_return_if_fail (G_VALUE_HOLDS (value, info->data_type));
+
+ switch (info->data_type)
+ {
+ case G_TYPE_STRING:
+ eel_gconf_set_string (pref, g_value_get_string (value));
+ break;
+ case G_TYPE_INT:
+ eel_gconf_set_integer (pref, g_value_get_int (value));
+ break;
+ case G_TYPE_FLOAT:
+ eel_gconf_set_float (pref, g_value_get_float (value));
+ break;
+ case G_TYPE_BOOLEAN:
+ eel_gconf_set_boolean (pref, g_value_get_boolean (value));
+ break;
+ default:
+ break;
+ }
+}
+
+static void
+set_value_from_editable (PropertyInfo *info, GValue *value)
+{
+ char *text;
+ gboolean free_text = TRUE;
+
+ g_return_if_fail (GTK_IS_EDITABLE (info->widget));
+
+ text = gtk_editable_get_chars (GTK_EDITABLE (info->widget), 0, -1);
+
+ g_value_init (value, info->data_type);
+ switch (info->data_type)
+ {
+ case G_TYPE_STRING:
+ g_value_take_string (value, text);
+ free_text = FALSE;
+ break;
+ /* FIXME : handle possible errors in the input for int and float */
+ case G_TYPE_INT:
+ g_value_set_int (value, atoi (text));
+ break;
+ case G_TYPE_FLOAT:
+ g_value_set_float (value, strtod (text, NULL));
+ break;
+ default:
+ g_warning ("Unsupported value type for editable %s", info->id);
+ break;
+ }
+
+ if (free_text)
+ {
+ g_free (text);
+ }
}
static void
-set_config_from_optionmenu (GtkWidget *optionmenu, const char *config_name, GList *senum)
+set_value_from_optionmenu (PropertyInfo *info, GValue *value)
{
- int index = gtk_option_menu_get_history (GTK_OPTION_MENU (optionmenu));
+ int index;
+
+ g_return_if_fail (GTK_IS_OPTION_MENU (info->widget));
+
+ index = gtk_option_menu_get_history (GTK_OPTION_MENU (info->widget));
+ g_return_if_fail (index >= 0);
+
+ g_value_init (value, info->data_type);
+
+ if (info->data_type == G_TYPE_STRING)
+ {
+ g_return_if_fail (info->string_enum != NULL);
- if (senum)
+ g_value_set_string (value, g_list_nth_data (info->string_enum, index));
+ }
+ else if (info->data_type == G_TYPE_INT)
{
- eel_gconf_set_string (config_name, g_list_nth_data (senum, index));
+ g_value_set_int (value, index);
}
else
{
- eel_gconf_set_integer (config_name, index);
+ g_warning ("Unsupported data type for optionmenu %s\n", info->id);
+ }
+}
+
+static void
+set_value_from_combobox (PropertyInfo *info, GValue *value)
+{
+ int index;
+
+ g_return_if_fail (GTK_IS_COMBO_BOX (info->widget));
+
+ index = gtk_combo_box_get_active (GTK_COMBO_BOX (info->widget));
+ g_return_if_fail (index >= 0);
+
+ if (info->data_col != -1)
+ {
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+
+ model = gtk_combo_box_get_model (GTK_COMBO_BOX (info->widget));
+
+ g_return_if_fail (gtk_tree_model_get_column_type (model, info->data_col) == info->data_type);
+
+ if (gtk_tree_model_iter_nth_child (model, &iter, NULL, index))
+ {
+ gtk_tree_model_get_value (model, &iter, info->data_col, value);
+ }
+ else
+ {
+ g_warning ("Invalid index in combo model for %s\n", info->id);
+ }
+ }
+ else if (info->data_type == G_TYPE_INT)
+ {
+ g_value_init (value, G_TYPE_INT);
+ g_value_set_int (value, index);
+ }
+ else
+ {
+ g_warning ("Unsupported data type for combo %s\n", info->id);
}
}
static int
get_radio_button_active_index (GtkWidget *radiobutton)
{
- gint index;
GtkToggleButton *toggle_button;
- gint i, length;
- GSList *list;
+ GSList *list;
+ int index, i, length;
/* get group list */
- list = gtk_radio_button_get_group (GTK_RADIO_BUTTON (radiobutton));
- length = g_slist_length (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))
+ for (i = 0; list != NULL; i++, list = list->next)
{
/* get button and text */
toggle_button = GTK_TOGGLE_BUTTON (list->data);
@@ -286,933 +360,1061 @@ get_radio_button_active_index (GtkWidget *radiobutton)
}
static void
-set_config_from_radiobuttongroup (GtkWidget *radiobutton, const char *config_name, GList *senum)
+set_value_from_radiobuttongroup (PropertyInfo *info, GValue *value)
{
int index;
- index = get_radio_button_active_index (radiobutton);
+ g_return_if_fail (GTK_IS_RADIO_BUTTON (info->widget));
+
+ index = get_radio_button_active_index (info->widget);
+ g_return_if_fail (index >= 0);
- if (senum)
+ g_value_init (value, info->data_type);
+ if (info->data_type == G_TYPE_STRING)
+ {
+ g_return_if_fail (info->string_enum != NULL);
+
+ g_value_set_string (value, (char*) g_list_nth_data (info->string_enum, index));
+ }
+ else if (info->data_type == G_TYPE_INT)
{
- eel_gconf_set_string (config_name, g_list_nth_data (senum, index));
+ g_value_set_int (value, index);
}
else
{
- eel_gconf_set_integer (config_name, index);
+ g_warning ("unsupported data type for radio button %s\n", info->id);
}
}
static void
-set_config_from_spin_button (GtkWidget *spinbutton, const char *config_name)
+set_value_from_spin_button (PropertyInfo *info, GValue *value)
{
- gdouble value;
- gboolean use_int;
+ gdouble f;
+ gboolean is_int;
- /* read the value as an integer */
- value = gtk_spin_button_get_value (GTK_SPIN_BUTTON(spinbutton));
+ g_return_if_fail (GTK_IS_SPIN_BUTTON (info->widget));
- use_int = (gtk_spin_button_get_digits (GTK_SPIN_BUTTON(spinbutton)) == 0);
+ f = gtk_spin_button_get_value (GTK_SPIN_BUTTON (info->widget));
- if (use_int)
+ is_int = (gtk_spin_button_get_digits (GTK_SPIN_BUTTON(info->widget)) == 0);
+
+ g_value_init (value, info->data_type);
+ if (info->data_type == G_TYPE_INT && is_int)
+ {
+ g_value_set_int (value, (int) f);
+ }
+ else if (info->data_type == G_TYPE_FLOAT)
{
- eel_gconf_set_integer (config_name, value);
+ g_value_set_float (value, f);
}
else
{
- eel_gconf_set_float (config_name, value);
+ g_warning ("Unsupported data type for spin button %s\n", info->id);
}
}
static void
-set_config_from_togglebutton (GtkWidget *togglebutton, const char *config_name)
+set_value_from_togglebutton (PropertyInfo *info, GValue *value)
{
- gboolean value;
+ gboolean active;
- /* read the value */
- value = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(togglebutton));
+ g_return_if_fail (GTK_IS_TOGGLE_BUTTON (info->widget));
- eel_gconf_set_boolean (config_name, value);
+ active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (info->widget));
+
+ g_value_init (value, info->data_type);
+ if (info->data_type == G_TYPE_BOOLEAN)
+ {
+ g_value_set_boolean (value, active);
+ }
+ else
+ {
+ g_warning ("Unsupported data type for toggle button %s\n", info->id);
+ }
}
static void
-set_editable_from_config (GtkWidget *editable, const char *config_name)
+set_value_from_info (PropertyInfo *info, GValue *value)
{
- GConfValue *gcvalue = eel_gconf_get_value (config_name);
- GConfValueType value_type;
- gchar *value;
-
- if (gcvalue == NULL)
+ if (info->sane_state == FALSE)
{
- /* 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;
+ g_warning ("id[%s] has insane state when trying to get value!\n", info->id);
}
- else
+
+ switch (info->widget_type)
{
- value_type = gcvalue->type;
- gconf_value_free (gcvalue);
+ case PT_SPINBUTTON:
+ set_value_from_spin_button (info, value);
+ break;
+ case PT_RADIOBUTTON:
+ set_value_from_radiobuttongroup (info, value);
+ break;
+ case PT_TOGGLEBUTTON:
+ set_value_from_togglebutton (info, value);
+ break;
+ case PT_EDITABLE:
+ set_value_from_editable (info, value);
+ break;
+ case PT_OPTIONMENU:
+ set_value_from_optionmenu (info, value);
+ break;
+ case PT_COMBOBOX:
+ set_value_from_combobox (info, value);
+ break;
+ default:
+ g_warning ("Unsupported widget type\n");
+ break;
}
+}
- switch (value_type)
+static void
+set_editable_from_value (PropertyInfo *info, const GValue *value)
+{
+ char *text = NULL;
+ int pos;
+
+ g_return_if_fail (GTK_IS_EDITABLE (info->widget));
+
+ switch (info->data_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;
+ case G_TYPE_STRING:
+ text = g_value_dup_string (value);
+ break;
+ case G_TYPE_INT:
+ text = g_strdup_printf ("%d", g_value_get_int (value));
+ break;
+ case G_TYPE_FLOAT:
+ text = g_strdup_printf ("%.2f", g_value_get_float (value));
+ break;
+ default:
+ break;
}
- /* set this string value in the widget */
- if (value)
+ if (text == NULL)
{
- gtk_entry_set_text(GTK_ENTRY(editable), value);
+ text = g_strdup ("");
}
+ info->sane_state = TRUE;
+
+ gtk_editable_delete_text (GTK_EDITABLE (info->widget), 0, -1);
+ gtk_editable_insert_text (GTK_EDITABLE (info->widget), text, strlen (text), &pos);
- /* free the allocated string */
- g_free (value);
+ g_free (text);
}
static int
-get_index (const char *config_name, GList *senum)
+get_index_from_value (const GValue *value, GList *string_enum)
{
- int index = 0;
- char *val;
+ int index = -1;
+ const char *val;
GList *s = NULL;
- if (senum)
+ if (string_enum)
{
- val = eel_gconf_get_string (config_name);
+ val = g_value_get_string (value);
if (val)
{
- s = g_list_find_custom (senum, val, (GCompareFunc)strcmp);
- g_free (val);
+ s = g_list_find_custom (string_enum, val, (GCompareFunc) strcmp);
}
if (s)
{
- index = g_list_position (senum, s);
+ index = g_list_position (string_enum, s);
}
}
else
{
- index = eel_gconf_get_integer (config_name);
+ index = g_value_get_int (value);
}
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)
+set_optionmenu_from_value (PropertyInfo *info, const GValue *value)
{
- GtkToggleButton *button;
- GSList *list;
- gint length;
int index;
- index = get_index (config_name, senum);
+ g_return_if_fail (GTK_IS_OPTION_MENU (info->widget));
- /* get the list */
- list = gtk_radio_button_get_group (GTK_RADIO_BUTTON (radiobutton));
+ index = get_index_from_value (value, info->string_enum);
+ if (index < 0)
+ {
+ info->sane_state = FALSE;
+ g_warning ("Index < 0 when setting optionmenu %s\n", info->id);
+ return;
+ }
- /* check out the length */
- length = g_slist_length (list);
+ info->sane_state = TRUE;
- /* new buttons are *preppended* to the list, so button added as first
- * has last position in the list */
- index = (length - 1) - index;
+ gtk_option_menu_set_history (GTK_OPTION_MENU (info->widget), index);
+}
- /* find the right button */
- button = GTK_TOGGLE_BUTTON (g_slist_nth_data (list, index));
+static gboolean
+compare_values (const GValue *a, const GValue *b)
+{
+ if (G_VALUE_HOLDS (a, G_TYPE_STRING))
+ {
+ const char *ta, *tb;
- /* set it... this will de-activate the others in the group */
- if (gtk_toggle_button_get_active (button) == FALSE)
+ ta = g_value_get_string (a);
+ tb = g_value_get_string (b);
+
+ return (ta && tb && strcmp (ta, tb) == 0);
+ }
+ else if (G_VALUE_HOLDS (a, G_TYPE_INT))
{
- gtk_toggle_button_set_active (button, TRUE);
+ return g_value_get_int (a) == g_value_get_int (b);
+ }
+ else if (G_VALUE_HOLDS (a, G_TYPE_FLOAT))
+ {
+ return g_value_get_float (a) == g_value_get_float (b);
+ }
+ else if (G_VALUE_HOLDS (a, G_TYPE_BOOLEAN))
+ {
+ return g_value_get_boolean (a) == g_value_get_boolean (b);
}
+
+ return FALSE;
}
static void
-set_spin_button_from_config (GtkWidget *spinbutton, const char *config_name)
+set_combo_box_from_value (PropertyInfo *info, const GValue *value)
{
- gdouble value;
- gint use_int;
+ int index = -1;
- use_int = (gtk_spin_button_get_digits (GTK_SPIN_BUTTON(spinbutton)) == 0);
+ g_return_if_fail (GTK_IS_COMBO_BOX (info->widget));
- if (use_int)
+ if (info->data_col != -1)
{
- /* get the current value from the configuration space */
- value = eel_gconf_get_integer (config_name);
+ GValue data = { 0, };
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+ gboolean valid, found = FALSE;
+
+ model = gtk_combo_box_get_model (GTK_COMBO_BOX (info->widget));
+
+ g_return_if_fail (gtk_tree_model_get_column_type (model, info->data_col) == info->data_type);
+
+ valid = gtk_tree_model_get_iter_first (model, &iter);
+ while (valid)
+ {
+ gtk_tree_model_get_value (model, &iter, info->data_col, &data);
+ found = compare_values (&data, value);
+ if (found) break;
+
+ g_value_unset (&data);
+ valid = gtk_tree_model_iter_next (model, &iter);
+ }
+
+ if (found)
+ {
+ GtkTreePath *path;
+ gint *indices;
+
+ path = gtk_tree_model_get_path (model, &iter);
+ indices = gtk_tree_path_get_indices (path);
+ index = indices[0];
+ gtk_tree_path_free (path);
+ }
+ }
+ else if (info->data_type == G_TYPE_INT)
+ {
+ index = g_value_get_int (value);
}
else
{
- /* get the current value from the configuration space */
- value = eel_gconf_get_float (config_name);
+ g_warning ("Unsupported data type for combo box %s\n", info->id);
+ }
+
+ if (index < 0)
+ {
+ info->sane_state = FALSE;
+
+ g_return_if_fail (index >= 0);
}
- /* set this option value in the widget */
- gtk_spin_button_set_value(GTK_SPIN_BUTTON(spinbutton), value);
+ LOG ("index[%s] is %d", info->id, index)
+
+ info->sane_state = TRUE;
+
+ gtk_combo_box_set_active (GTK_COMBO_BOX (info->widget), index);
}
static void
-set_togglebutton_from_config (GtkWidget *togglebutton, const char *config_name)
+set_radiobuttongroup_from_value (PropertyInfo *info, const GValue *value)
{
- gboolean value;
+ GtkToggleButton *button;
+ GSList *list;
+ gint length;
+ int index;
- /* get the current value from the configuration space */
- value = eel_gconf_get_boolean (config_name);
+ g_return_if_fail (GTK_IS_RADIO_BUTTON (info->widget));
- /* set this option value in the widget */
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (togglebutton), value);
-}
+ list = gtk_radio_button_get_group (GTK_RADIO_BUTTON (info->widget));
-static PrefType
-get_pref_type_from_widget (GtkWidget *widget)
-{
- if (GTK_IS_OPTION_MENU (widget))
+ length = g_slist_length (list);
+
+ index = get_index_from_value (value, info->string_enum);
+
+ /* new buttons are *prepended* to the list, so button added as first
+ * has last position in the list */
+ index = (length - 1) - index;
+
+ if (index < 0 || index >= length)
{
- return PT_OPTIONMENU;
+ info->sane_state = FALSE;
+ g_return_if_fail (index >= 0 && index < length);
}
- else if (GTK_IS_SPIN_BUTTON (widget))
+
+ button = GTK_TOGGLE_BUTTON (g_slist_nth_data (list, index));
+ g_return_if_fail (button != NULL);
+
+ info->sane_state = TRUE;
+
+ if (gtk_toggle_button_get_active (button) == FALSE)
{
- return PT_SPINBUTTON;
+ gtk_toggle_button_set_active (button, TRUE);
}
- else if (GTK_IS_RADIO_BUTTON (widget))
+}
+
+static void
+set_spin_button_from_value (PropertyInfo *info, const GValue *value)
+{
+ gdouble f = 0.0;
+ gboolean is_int;
+
+ g_return_if_fail (GTK_IS_SPIN_BUTTON (info->widget));
+
+ is_int = (gtk_spin_button_get_digits (GTK_SPIN_BUTTON (info->widget)) == 0);
+
+ if (info->data_type == G_TYPE_INT && is_int)
{
- return PT_RADIOBUTTON;
+ f = (float) g_value_get_int (value);
}
- else if (GTK_IS_TOGGLE_BUTTON (widget))
+ else if (info->data_type == G_TYPE_FLOAT)
{
- return PT_TOGGLEBUTTON;
+ f = g_value_get_float (value);
}
- else if (GTK_IS_ENTRY (widget))
+ else
{
- return PT_ENTRY;
+ info->sane_state = FALSE;
+ g_warning ("Unsupported data type for spin button %s\n", info->id);
+ return;
}
- return PT_UNKNOWN;
+ info->sane_state = TRUE;
+
+ gtk_spin_button_set_value (GTK_SPIN_BUTTON (info->widget), f);
}
-static int *
-set_controls_sensitivity (EphyDialog *dialog,
- int *sg, gboolean s)
+static void
+set_togglebutton_from_value (PropertyInfo *info, const GValue *value)
{
- GtkWidget *widget;
+ gboolean active;
- while (*sg != SY_END_GROUP)
- {
- widget = ephy_dialog_get_control (dialog,
- *sg);
- gtk_widget_set_sensitive (widget, s);
+ g_return_if_fail (GTK_IS_TOGGLE_BUTTON (info->widget));
+ g_return_if_fail (info->data_type == G_TYPE_BOOLEAN);
- sg++;
- }
+ active = g_value_get_boolean (value);
+
+ info->sane_state = TRUE;
- return sg;
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (info->widget), active);
}
static void
-prefs_set_group_sensitivity (GtkWidget *widget,
- PrefType type, int *sg)
+set_info_from_value (PropertyInfo *info, const GValue *value)
{
- 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))
+ if (!G_VALUE_HOLDS (value, info->data_type))
{
- group = !gtk_toggle_button_get_active
- (GTK_TOGGLE_BUTTON(widget));
+ g_warning ("Incompatible value types for id %s\n", info->id);
+ return;
}
- else
+
+ switch (info->widget_type)
{
- g_assert (FALSE);
+ case PT_SPINBUTTON:
+ set_spin_button_from_value (info, value);
+ break;
+ case PT_RADIOBUTTON:
+ set_radiobuttongroup_from_value (info, value);
+ break;
+ case PT_TOGGLEBUTTON:
+ set_togglebutton_from_value (info, value);
+ break;
+ case PT_EDITABLE:
+ set_editable_from_value (info, value);
+ break;
+ case PT_OPTIONMENU:
+ set_optionmenu_from_value (info, value);
+ break;
+ case PT_COMBOBOX:
+ set_combo_box_from_value (info, value);
+ break;
+ default:
+ g_warning ("Unknown widget type\n");
+ break;
}
+}
- while (*sg != SY_END)
- {
- if ((*sg == SY_BEGIN_GROUP) ||
- (*sg == SY_BEGIN_GROUP_INVERSE))
- {
- gboolean b;
+/* widget changed callbacks */
- b = (i == group);
- if (*sg == SY_BEGIN_GROUP_INVERSE) b = !b;
+static void
+set_pref_from_info (PropertyInfo *info)
+{
+ GValue value = { 0, };
- sg++;
- sg = set_controls_sensitivity
- (dialog, sg, b);
- }
+ if (info->pref != NULL && info->sane_state)
+ {
+ set_value_from_info (info, &value);
+ set_pref_from_value (info, &value);
+ g_value_unset (&value);
+ }
- i++;
- sg++;
+ if (info->pref != NULL && !info->sane_state)
+ {
+ g_warning ("Not persisting insane state of id[%s] to pref %s!\n", info->id, info->pref);
}
}
static void
-prefs_togglebutton_clicked_cb (GtkWidget *widget, PropertyInfo *pi)
+togglebutton_clicked_cb (GtkWidget *widget, PropertyInfo *info)
{
- if (pi->type == PT_AUTOAPPLY)
+ if (info->apply_type == PT_AUTOAPPLY)
{
- set_config_from_togglebutton (widget, pi->pref);
+ set_pref_from_info (info);
}
-
- prefs_set_group_sensitivity (widget, pi->type, pi->sg);
}
static void
-prefs_radiobutton_clicked_cb (GtkWidget *widget, PropertyInfo *pi)
+radiobutton_clicked_cb (GtkWidget *widget, PropertyInfo *info)
{
if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(widget)))
{
return;
}
- if (pi->type == PT_AUTOAPPLY)
+ if (info->apply_type == PT_AUTOAPPLY)
{
- set_config_from_radiobuttongroup (widget, pi->pref, pi->string_enum);
+ set_pref_from_info (info);
}
-
- prefs_set_group_sensitivity (widget, pi->type, pi->sg);
}
-static gint
-prefs_spinbutton_timeout_cb (EphyDialog *dialog)
+static gboolean
+spinbutton_timeout_cb (PropertyInfo *info)
{
- PropertyInfo pi = dialog->priv->props[dialog->priv->spin_item_id];
+ GTimer *spin_timer;
- /* timer still valid? */
- if (dialog->priv->spin_timer == NULL)
- {
- return FALSE;
- }
+ spin_timer = (GTimer *) g_object_get_data (G_OBJECT (info->widget), "timer");
+
+ /* timer still valid? */
+ if (spin_timer == NULL)
+ {
+ /* don't call me again */
+ 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;
+ /* okay, we're ready to set */
+ if (g_timer_elapsed (spin_timer, NULL) >= SPIN_DELAY)
+ {
+ /* kill off the timer */
+ g_timer_destroy (spin_timer);
+ g_object_set_data (G_OBJECT (info->widget), "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));
+ gtk_spin_button_update (GTK_SPIN_BUTTON (info->widget));
- /* set */
- set_config_from_spin_button (pi.widget, pi.pref);
+ set_pref_from_info (info);
- /* done now */
- return FALSE;
- }
+ /* done, don't run again */
+ return FALSE;
+ }
- /* call me again */
- return TRUE;
+ /* not elapsed yet, call me again */
+ return TRUE;
}
static void
-prefs_spinbutton_changed_cb (GtkWidget *widget, PropertyInfo *pi)
+spinbutton_changed_cb (GtkWidget *widget, PropertyInfo *info)
{
- EphyDialog *dialog;
-
- if (pi->type != PT_AUTOAPPLY) return;
+ GTimer *spin_timer;
- dialog = EPHY_DIALOG (g_object_get_data
- (G_OBJECT(widget), "dialog"));
+ if (info->apply_type != PT_AUTOAPPLY) return;
- dialog->priv->spin_item_id = pi->id;
+ spin_timer = g_object_get_data (G_OBJECT (info->widget), "timer");
- /* destroy any existing timer */
- if (dialog->priv->spin_timer != NULL)
+ /* destroy an existing timer */
+ if (spin_timer != NULL)
{
- g_timer_destroy (dialog->priv->spin_timer);
+ g_timer_destroy (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);
+ /* start tnew timer */
+ spin_timer = g_timer_new();
+ g_timer_start (spin_timer);
+ g_object_set_data (G_OBJECT (info->widget), "timer", spin_timer);
+
+ g_timeout_add (50, (GSourceFunc) spinbutton_timeout_cb, info);
}
static void
-prefs_entry_changed_cb (GtkWidget *widget, PropertyInfo *pi)
+changed_cb (GtkWidget *widget, PropertyInfo *info)
{
- if (pi->type == PT_AUTOAPPLY)
+ if (info->apply_type == PT_AUTOAPPLY)
{
- set_config_from_editable (widget, pi->pref);
+ set_pref_from_info (info);
}
}
static void
-prefs_optionmenu_selected_cb (GtkWidget *widget, PropertyInfo *pi)
+set_info_from_pref (PropertyInfo *info)
{
- if (pi->type == PT_AUTOAPPLY)
+ GValue value = { 0, };
+
+ g_return_if_fail (info->widget != NULL);
+
+ if (info->pref != NULL)
{
- set_config_from_optionmenu (widget, pi->pref, pi->string_enum);
+ set_value_from_pref (info, &value);
+ set_info_from_value (info, &value);
+ g_value_unset (&value);
+
+ if (eel_gconf_key_is_writable (info->pref) == FALSE)
+ {
+ set_sensitivity (info, FALSE);
+ }
}
}
static void
-prefs_connect_signals (EphyDialog *dialog)
+connect_signals (gpointer key, PropertyInfo *info, EphyDialog *dialog)
{
- int i;
GSList *list;
- PropertyInfo *props = dialog->priv->props;
- for (i = 0; props[i].widget != NULL; i++)
- {
- PrefType type;
- PropertyInfo *info;
+ g_return_if_fail (info->widget != NULL);
- if ((props[i].type != PT_AUTOAPPLY) &&
- (props[i].sg == NULL))
- continue;
+ if (info->apply_type != PT_AUTOAPPLY) return;
- info = &dialog->priv->props[i];
- type = get_pref_type_from_widget
- (dialog->priv->props[i].widget);
-
- switch (type)
- {
+ switch (info->widget_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),
+ G_CALLBACK (togglebutton_clicked_cb),
(gpointer)info);
break;
case PT_RADIOBUTTON:
list = gtk_radio_button_get_group
- (GTK_RADIO_BUTTON(info->widget));
+ (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);
+ G_CALLBACK (radiobutton_clicked_cb),
+ 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);
+ G_CALLBACK (spinbutton_changed_cb),
+ info);
break;
case PT_OPTIONMENU:
- g_signal_connect (G_OBJECT (info->widget),
- "changed",
- G_CALLBACK(prefs_optionmenu_selected_cb),
- (gpointer)info);
+ g_signal_connect (G_OBJECT (info->widget), "changed",
+ G_CALLBACK (changed_cb), info);
break;
- case PT_ENTRY:
+ case PT_COMBOBOX:
g_signal_connect (G_OBJECT (info->widget), "changed",
- G_CALLBACK(prefs_entry_changed_cb),
- (gpointer)info);
+ G_CALLBACK (changed_cb), info);
+ break;
+ case PT_EDITABLE:
+ g_signal_connect (G_OBJECT (info->widget), "changed",
+ G_CALLBACK (changed_cb), info);
break;
case PT_UNKNOWN:
+ g_warning ("Unsupported widget type\n");
break;
- }
}
}
static void
-ephy_dialog_init (EphyDialog *dialog)
+disconnect_signals (gpointer key, PropertyInfo *info, EphyDialog *dialog)
{
- dialog->priv = EPHY_DIALOG_GET_PRIVATE (dialog);
-
- 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;
- dialog->priv->has_default_size = FALSE;
- dialog->priv->disposing = 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 (info->widget != NULL);
- 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);
- }
- }
+ g_signal_handlers_disconnect_matched (info->widget, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, info);
}
static void
-load_props (PropertyInfo *props)
+init_props (EphyDialog *dialog, const EphyDialogProperty *properties, GladeXML *gxml)
{
int i;
- for (i=0 ; props[i].id >= 0; i++)
+ for (i = 0 ; properties[i].id != NULL; 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))
+ PropertyInfo *info = g_new0 (PropertyInfo, 1);
+
+ info->id = properties[i].id;
+ info->pref = g_strdup (properties[i].pref);
+ info->apply_type = properties[i].apply_type;
+ info->string_enum = NULL;
+ info->data_col = -1;
+
+ info->widget = glade_xml_get_widget (gxml, info->id);
+
+ if (GTK_IS_OPTION_MENU (info->widget))
{
- set_togglebutton_from_config (props[i].widget,
- props[i].pref);
+ info->widget_type = PT_OPTIONMENU;
+ info->data_type = G_TYPE_INT;
}
- else if (GTK_IS_EDITABLE(props[i].widget))
+ else if (GTK_IS_COMBO_BOX (info->widget))
{
- set_editable_from_config (props[i].widget,
- props[i].pref);
+ info->widget_type = PT_COMBOBOX;
+ info->data_type = G_TYPE_INT;
}
- else if (GTK_IS_OPTION_MENU(props[i].widget))
+ else if (GTK_IS_SPIN_BUTTON (info->widget))
{
- set_optionmenu_from_config (props[i].widget,
- props[i].pref,
- props[i].string_enum);
+ info->widget_type = PT_SPINBUTTON;
+ info->data_type = G_TYPE_INT;
}
- }
-
-}
-
-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))
+ else if (GTK_IS_RADIO_BUTTON (info->widget))
{
- set_config_from_spin_button (props[i].widget,
- props[i].pref);
+ info->widget_type = PT_RADIOBUTTON;
+ info->data_type = G_TYPE_INT;
}
- else if (GTK_IS_RADIO_BUTTON(props[i].widget))
+ else if (GTK_IS_TOGGLE_BUTTON (info->widget))
{
- set_config_from_radiobuttongroup (props[i].widget,
- props[i].pref,
- props[i].string_enum);
+ info->widget_type = PT_TOGGLEBUTTON;
+ info->data_type = G_TYPE_BOOLEAN;
}
- else if (GTK_IS_TOGGLE_BUTTON(props[i].widget))
+ else if (GTK_IS_EDITABLE (info->widget))
{
- set_config_from_togglebutton (props[i].widget,
- props[i].pref);
+ info->widget_type = PT_EDITABLE;
+ info->data_type = G_TYPE_STRING;
}
- else if (GTK_IS_EDITABLE(props[i].widget))
+ else
{
- set_config_from_editable (props[i].widget,
- props[i].pref);
+ info->widget_type = PT_UNKNOWN;
+ info->data_type = G_TYPE_INVALID;
}
- else if (GTK_IS_OPTION_MENU(props[i].widget))
+
+ if (properties[i].data_type != 0)
{
- set_config_from_optionmenu (props[i].widget,
- props[i].pref,
- props[i].string_enum);
+ info->data_type = properties[i].data_type;
}
+
+ info->loaded = FALSE;
+ info->sane_state = FALSE;
+
+ g_hash_table_insert (dialog->priv->props, (char *) info->id, info);
}
}
static void
-free_props (PropertyInfo *properties)
+load_info (gpointer key, PropertyInfo *info, EphyDialog *dialog)
{
- int i;
+ set_info_from_pref (info);
- for (i = 0; properties[i].string_enum != NULL; i++)
+ info->loaded = TRUE;
+}
+
+static void
+save_info (gpointer key, PropertyInfo *info, EphyDialog *dialog)
+{
+ if (info->apply_type == PT_NORMAL)
{
- g_list_foreach (properties[i].string_enum, (GFunc)g_free, NULL);
- g_list_free (properties[i].string_enum);
+ set_pref_from_info (info);
}
}
static void
-ephy_dialog_finalize (GObject *object)
+setup_default_size (EphyDialog *dialog)
{
- EphyDialog *dialog = EPHY_DIALOG (object);
-
- free_props (dialog->priv->props);
-
- g_free (dialog->priv->name);
- g_free (dialog->priv->props);
+ if (dialog->priv->has_default_size == FALSE)
+ {
+ ephy_state_add_window (dialog->priv->dialog,
+ dialog->priv->name, -1, -1,
+ EPHY_STATE_WINDOW_SAVE_SIZE);
- G_OBJECT_CLASS (parent_class)->finalize (object);
+ dialog->priv->has_default_size = TRUE;
+ }
}
static void
-ephy_dialog_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
+dialog_destroy_cb (GtkWidget *widget, EphyDialog *dialog)
{
- EphyDialog *d = EPHY_DIALOG (object);
+ g_hash_table_foreach (dialog->priv->props, (GHFunc) save_info, dialog);
- 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;
- }
+ if (dialog->priv->disposing == FALSE)
+ {
+ g_object_unref (dialog);
+ }
}
static void
-ephy_dialog_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
+impl_construct (EphyDialog *dialog,
+ const EphyDialogProperty *properties,
+ const char *file,
+ const char *name)
{
- EphyDialog *d = EPHY_DIALOG (object);
+ GladeXML *gxml;
- 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);
- }
+ gxml = ephy_glade_widget_new (file, name, &(dialog->priv->dialog), dialog);
+
+ if (dialog->priv->name == NULL)
+ {
+ dialog->priv->name = g_strdup (name);
+ }
+
+ if (properties)
+ {
+ init_props (dialog, properties, gxml);
+ }
+
+ g_signal_connect_object (dialog->priv->dialog,
+ "destroy",
+ G_CALLBACK(dialog_destroy_cb),
+ dialog, 0);
+
+ g_object_unref (gxml);
}
static void
-ephy_dialog_set_parent (EphyDialog *dialog,
- GtkWidget *parent)
+impl_show (EphyDialog *dialog)
{
- 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));
+ if (dialog->priv->initialized == FALSE)
+ {
+ dialog->priv->initialized = TRUE;
- dialog->priv->parent = parent;
+ g_hash_table_foreach (dialog->priv->props, (GHFunc) load_info, dialog);
+ g_hash_table_foreach (dialog->priv->props, (GHFunc) connect_signals, dialog);
+ }
- gtk_window_set_transient_for (GTK_WINDOW (dialog->priv->dialog),
- GTK_WINDOW (parent));
+ setup_default_size (dialog);
- g_object_notify (G_OBJECT (dialog), "ParentWindow");
-}
+ 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));
+ }
-EphyDialog *
-ephy_dialog_new (void)
-{
- return EPHY_DIALOG (g_object_new (EPHY_TYPE_DIALOG, NULL));
+ gtk_window_present (GTK_WINDOW (dialog->priv->dialog));
}
-EphyDialog *
-ephy_dialog_new_with_parent (GtkWidget *parent_window)
+void
+ephy_dialog_set_modal (EphyDialog *dialog,
+ gboolean is_modal)
{
- return EPHY_DIALOG (g_object_new (EPHY_TYPE_DIALOG,
- "ParentWindow", parent_window,
- NULL));
+ dialog->priv->modal = is_modal;
+
+ gtk_window_set_modal (GTK_WINDOW(dialog->priv->dialog), is_modal);
}
void
ephy_dialog_add_enum (EphyDialog *dialog,
- int id,
+ const char *id,
guint n_items,
const char **items)
{
+ PropertyInfo *info;
int i = 0;
GList *l = NULL;
+ info = lookup_info (dialog, id);
+ g_return_if_fail (info != NULL);
+
for (i = 0; i < n_items; i++)
{
- l = g_list_append (l, g_strdup (items[i]));
+ l = g_list_prepend (l, g_strdup (items[i]));
}
- dialog->priv->props[id].string_enum = l;
+ info->string_enum = g_list_reverse (l);
}
-static PropertyInfo *
-init_props (const EphyDialogProperty *properties, GladeXML *gxml)
+void
+ephy_dialog_set_data_column (EphyDialog *dialog,
+ const char *id,
+ int column)
{
- PropertyInfo *props;
- int i;
+ PropertyInfo *info;
- for (i=0 ; properties[i].control_name != NULL; i++);
+ info = lookup_info (dialog, id);
+ g_return_if_fail (info != NULL);
- props = g_new0 (PropertyInfo, i+1);
+ info->data_col = column;
+}
- 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;
- }
+void
+ephy_dialog_set_pref (EphyDialog *dialog,
+ const char *property_id,
+ const char *pref)
+{
+ PropertyInfo *info;
- 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;
+ info = lookup_info (dialog, property_id);
+ g_return_if_fail (info != NULL);
- return props;
-}
+ disconnect_signals (NULL, info, dialog);
-static void
-dialog_destroy_cb (GtkWidget *widget, EphyDialog *dialog)
-{
- if (dialog->priv->props)
- {
- save_props (dialog->priv->props);
- }
+ info->loaded = FALSE;
+ info->sane_state = FALSE;
+ g_free (info->pref);
+ info->pref = g_strdup (pref);
- if (!dialog->priv->disposing)
+ if (dialog->priv->initialized)
{
- g_object_unref (dialog);
+ /* dialog is already initialised, so initialise this here */
+ load_info (NULL, info, dialog);
+ connect_signals (NULL, info, dialog);
}
}
-static void
-impl_construct (EphyDialog *dialog,
- const EphyDialogProperty *properties,
- const char *file,
- const char *name)
+void
+ephy_dialog_set_size_group (EphyDialog *dialog,
+ const char **controls_id,
+ guint n_controls)
{
- GladeXML *gxml;
+ GtkSizeGroup *size_group;
+ int i;
- gxml = ephy_glade_widget_new
- (file, name, &(dialog->priv->dialog), dialog);
+ size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
- if (dialog->priv->name == NULL)
+ for (i = 0; i < n_controls; i++)
{
- dialog->priv->name = g_strdup (name);
- }
+ PropertyInfo *info;
- if (properties)
- {
- dialog->priv->props = init_props (properties, gxml);
+ info = lookup_info (dialog, controls_id[i]);
+ g_return_if_fail (info != NULL);
+
+ g_return_if_fail (info->widget != NULL);
+
+ gtk_size_group_add_widget (size_group, info->widget);
}
+}
- g_signal_connect_object (dialog->priv->dialog,
- "destroy",
- G_CALLBACK(dialog_destroy_cb),
- dialog, 0);
+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);
+}
- g_object_unref (gxml);
+void
+ephy_dialog_show (EphyDialog *dialog)
+{
+ EphyDialogClass *klass = EPHY_DIALOG_GET_CLASS (dialog);
+ klass->show (dialog);
}
-static GtkWidget *
-impl_get_control (EphyDialog *dialog,
- int property_id)
+int
+ephy_dialog_run (EphyDialog *dialog)
{
- return dialog->priv->props[property_id].widget;
+ ephy_dialog_show (dialog);
+
+ return gtk_dialog_run (GTK_DIALOG (dialog->priv->dialog));
}
-static void
-impl_get_value (EphyDialog *dialog,
- int property_id,
- GValue *value)
+GtkWidget *
+ephy_dialog_get_control (EphyDialog *dialog,
+ const char *property_id)
{
- GtkWidget *widget = ephy_dialog_get_control (dialog,
- property_id);
+ PropertyInfo *info;
- 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);
- }
+ info = lookup_info (dialog, property_id);
+ g_return_val_if_fail (info != NULL, NULL);
+
+ return info->widget;
}
-static void
-setup_default_size (EphyDialog *dialog)
+void
+ephy_dialog_get_value (EphyDialog *dialog,
+ const char *property_id,
+ GValue *value)
{
- if (!dialog->priv->has_default_size)
- {
- ephy_state_add_window (dialog->priv->dialog,
- dialog->priv->name, -1, -1,
- EPHY_STATE_WINDOW_SAVE_SIZE);
- }
+ PropertyInfo *info;
- dialog->priv->has_default_size = TRUE;
+ info = lookup_info (dialog, property_id);
+ g_return_if_fail (info != NULL);
+
+ set_value_from_info (info, value);
}
-static gint
-impl_run (EphyDialog *dialog)
+void
+ephy_dialog_set_value (EphyDialog *dialog,
+ const char *property_id,
+ const GValue *value)
{
- ephy_dialog_show (dialog);
+ PropertyInfo *info;
- return gtk_dialog_run (GTK_DIALOG(dialog->priv->dialog));
+ info = lookup_info (dialog, property_id);
+ g_return_if_fail (info != NULL);
+
+ set_info_from_value (info, value);
}
static void
-impl_show (EphyDialog *dialog)
+free_prop_info (PropertyInfo *info)
{
- if (dialog->priv->props && !dialog->priv->initialized)
+ if (info->string_enum)
{
- load_props (dialog->priv->props);
- prefs_connect_signals (dialog);
- prefs_set_sensitivity (dialog->priv->props);
- dialog->priv->initialized = TRUE;
+ g_list_foreach (info->string_enum, (GFunc)g_free, NULL);
+ g_list_free (info->string_enum);
}
- setup_default_size (dialog);
+ g_free (info->pref);
- 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));
+ g_free (info);
}
-void
-ephy_dialog_set_modal (EphyDialog *dialog,
- gboolean is_modal)
+static void
+ephy_dialog_init (EphyDialog *dialog)
{
- dialog->priv->modal = is_modal;
+ dialog->priv = EPHY_DIALOG_GET_PRIVATE (dialog);
- gtk_window_set_modal (GTK_WINDOW(dialog->priv->dialog),
- is_modal);
+ dialog->priv->parent = NULL;
+ dialog->priv->dialog = NULL;
+ dialog->priv->name = NULL;
+ dialog->priv->initialized = FALSE;
+ dialog->priv->has_default_size = FALSE;
+ dialog->priv->disposing = FALSE;
+
+ dialog->priv->props = g_hash_table_new_full
+ (g_str_hash, g_str_equal, NULL, (GDestroyNotify) free_prop_info);
}
-void
-ephy_dialog_construct (EphyDialog *dialog,
- const EphyDialogProperty *properties,
- const char *file,
- const char *name)
+static void
+ephy_dialog_dispose (GObject *object)
{
- EphyDialogClass *klass = EPHY_DIALOG_GET_CLASS (dialog);
- return klass->construct (dialog, properties, file, name);
+ EphyDialog *dialog = EPHY_DIALOG (object);
+
+ if (dialog->priv->dialog)
+ {
+ dialog->priv->disposing = TRUE;
+ gtk_widget_destroy (dialog->priv->dialog);
+ dialog->priv->dialog = NULL;
+ }
}
-gint
-ephy_dialog_run (EphyDialog *dialog)
+static void
+ephy_dialog_finalize (GObject *object)
{
- EphyDialogClass *klass = EPHY_DIALOG_GET_CLASS (dialog);
- return klass->run (dialog);
+ EphyDialog *dialog = EPHY_DIALOG (object);
+
+ g_hash_table_destroy (dialog->priv->props);
+
+ g_free (dialog->priv->name);
+
+ G_OBJECT_CLASS (parent_class)->finalize (object);
}
-void
-ephy_dialog_show (EphyDialog *dialog)
+static void
+ephy_dialog_set_parent (EphyDialog *dialog,
+ GtkWidget *parent)
{
- EphyDialogClass *klass = EPHY_DIALOG_GET_CLASS (dialog);
- klass->show (dialog);
+ 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));
+
+ g_object_notify (G_OBJECT (dialog), "parent-window");
}
-GtkWidget *
-ephy_dialog_get_control (EphyDialog *dialog,
- int property_id)
+static void
+ephy_dialog_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
{
- EphyDialogClass *klass = EPHY_DIALOG_GET_CLASS (dialog);
- return klass->get_control (dialog, property_id);
+ EphyDialog *dialog = EPHY_DIALOG (object);
+
+ switch (prop_id)
+ {
+ case PROP_PARENT_WINDOW:
+ ephy_dialog_set_parent (dialog, g_value_get_object (value));
+ break;
+ case PROP_MODAL:
+ ephy_dialog_set_modal (dialog, g_value_get_boolean (value));
+ break;
+ }
}
-void
-ephy_dialog_get_value (EphyDialog *dialog,
- int property_id,
- GValue *value)
+static void
+ephy_dialog_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
{
- EphyDialogClass *klass = EPHY_DIALOG_GET_CLASS (dialog);
- return klass->get_value (dialog, property_id, value);
+ EphyDialog *dialog = EPHY_DIALOG (object);
+
+ switch (prop_id)
+ {
+ case PROP_PARENT_WINDOW:
+ g_value_set_object (value, dialog->priv->parent);
+ break;
+ case PROP_MODAL:
+ g_value_set_boolean (value, dialog->priv->modal);
+ }
}
-void
-ephy_dialog_set_size_group (EphyDialog *dialog,
- int *controls_id,
- guint n_controls)
+static void
+ephy_dialog_class_init (EphyDialogClass *klass)
{
- GtkSizeGroup *size_group;
- int i;
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
- size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
+ parent_class = g_type_class_peek_parent (klass);
- for (i = 0; i < n_controls; i++)
- {
- GtkWidget *widget;
- guint id;
+ object_class->finalize = ephy_dialog_finalize;
+ object_class->dispose = ephy_dialog_dispose;
+ object_class->set_property = ephy_dialog_set_property;
+ object_class->get_property = ephy_dialog_get_property;
- id = controls_id[i];
- widget = dialog->priv->props[id].widget;
- g_return_if_fail (GTK_IS_WIDGET (widget));
+ klass->construct = impl_construct;
+ klass->show = impl_show;
+
+ g_object_class_install_property (object_class,
+ PROP_PARENT_WINDOW,
+ g_param_spec_object ("parent-window",
+ "Parent window",
+ "Parent window",
+ GTK_TYPE_WINDOW,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (object_class,
+ PROP_MODAL,
+ g_param_spec_boolean ("Modal",
+ "Modal",
+ "Modal dialog",
+ FALSE,
+ G_PARAM_READWRITE));
- gtk_size_group_add_widget (size_group, widget);
- }
+ g_type_class_add_private (object_class, sizeof (EphyDialogPrivate));
+}
+
+EphyDialog *
+ephy_dialog_new (void)
+{
+ return EPHY_DIALOG (g_object_new (EPHY_TYPE_DIALOG, NULL));
+}
+
+EphyDialog *
+ephy_dialog_new_with_parent (GtkWidget *parent_window)
+{
+ return EPHY_DIALOG (g_object_new (EPHY_TYPE_DIALOG,
+ "parent-window", parent_window,
+ NULL));
}
diff --git a/lib/ephy-dialog.h b/lib/ephy-dialog.h
index a440dd625..a1ed97f1f 100644
--- a/lib/ephy-dialog.h
+++ b/lib/ephy-dialog.h
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2000-2003 Marco Pesenti Gritti
+ * Copyright (C) 2003 Christian Persch
*
* 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
@@ -27,102 +28,96 @@
G_BEGIN_DECLS
-#define EPHY_TYPE_DIALOG (ephy_dialog_get_type ())
-#define EPHY_DIALOG(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), EPHY_TYPE_DIALOG, EphyDialog))
-#define EPHY_DIALOG_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), EPHY_TYPE_DIALOG, EphyDialogClass))
-#define EPHY_IS_DIALOG(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), EPHY_TYPE_DIALOG))
-#define EPHY_IS_DIALOG_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), EPHY_TYPE_DIALOG))
-#define EPHY_DIALOG_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), EPHY_TYPE_DIALOG, EphyDialogClass))
+#define EPHY_TYPE_DIALOG (ephy_dialog_get_type ())
+#define EPHY_DIALOG(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), EPHY_TYPE_DIALOG, EphyDialog))
+#define EPHY_DIALOG_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), EPHY_TYPE_DIALOG, EphyDialogClass))
+#define EPHY_IS_DIALOG(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), EPHY_TYPE_DIALOG))
+#define EPHY_IS_DIALOG_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), EPHY_TYPE_DIALOG))
+#define EPHY_DIALOG_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), EPHY_TYPE_DIALOG, EphyDialogClass))
-typedef struct EphyDialogClass EphyDialogClass;
-typedef struct EphyDialog EphyDialog;
-typedef struct EphyDialogPrivate EphyDialogPrivate;
-
-#define SY_BEGIN_GROUP -20
-#define SY_END_GROUP -21
-#define SY_END -22
-#define SY_BEGIN_GROUP_INVERSE -23
-
-struct EphyDialog
-{
- GObject parent;
-
- /*< private >*/
- EphyDialogPrivate *priv;
-};
+typedef struct EphyDialogClass EphyDialogClass;
+typedef struct EphyDialog EphyDialog;
+typedef struct EphyDialogPrivate EphyDialogPrivate;
typedef enum
{
PT_NORMAL,
PT_AUTOAPPLY
-} PropertyType;
+} EphyDialogApplyType;
typedef struct
{
- int id;
- const char *control_name;
- const char *state_pref;
- PropertyType type;
- int *sg;
+ const char *id;
+ const char *pref;
+ EphyDialogApplyType apply_type;
+ GType data_type;
} EphyDialogProperty;
struct EphyDialogClass
{
- GObjectClass parent_class;
+ GObjectClass parent_class;
- void (* construct) (EphyDialog *dialog,
+ void (* construct) (EphyDialog *dialog,
const EphyDialogProperty *properties,
const char *file,
- const char *name);
- gint (* run) (EphyDialog *dialog);
- void (* show) (EphyDialog *dialog);
- GtkWidget * (* get_control) (EphyDialog *dialog,
- int property_id);
- void (* get_value) (EphyDialog *dialog,
- int property_id,
- GValue *value);
+ const char *name);
+ void (* show) (EphyDialog *dialog);
};
-GType ephy_dialog_get_type (void);
+struct EphyDialog
+{
+ GObject parent;
-EphyDialog *ephy_dialog_new (void);
+ /*< private >*/
+ EphyDialogPrivate *priv;
+};
-EphyDialog *ephy_dialog_new_with_parent (GtkWidget *parent_window);
+GType ephy_dialog_get_type (void);
-void ephy_dialog_construct (EphyDialog *dialog,
+EphyDialog *ephy_dialog_new (void);
+
+EphyDialog *ephy_dialog_new_with_parent (GtkWidget *parent_window);
+
+void ephy_dialog_construct (EphyDialog *dialog,
const EphyDialogProperty *properties,
const char *file,
const char *name);
-void ephy_dialog_add_enum (EphyDialog *dialog,
- int id,
+void ephy_dialog_add_enum (EphyDialog *dialog,
+ const char *id,
guint n_items,
const char **items);
-void ephy_dialog_set_size_group (EphyDialog *dialog,
- int *controls_id,
- guint n_controls);
+void ephy_dialog_set_data_column (EphyDialog *dialog,
+ const char *id,
+ int col);
-gint ephy_dialog_run (EphyDialog *dialog);
-
-void ephy_dialog_show (EphyDialog *dialog);
+void ephy_dialog_set_size_group (EphyDialog *dialog,
+ const char **controls_id,
+ guint n_controls);
-void ephy_dialog_show_embedded (EphyDialog *dialog,
- GtkWidget *container);
+int ephy_dialog_run (EphyDialog *dialog);
-void ephy_dialog_remove_embedded (EphyDialog *dialog);
+void ephy_dialog_show (EphyDialog *dialog);
-void ephy_dialog_set_modal (EphyDialog *dialog,
+void ephy_dialog_set_modal (EphyDialog *dialog,
gboolean is_modal);
-GtkWidget *ephy_dialog_get_control (EphyDialog *dialog,
- int property_id);
+GtkWidget *ephy_dialog_get_control (EphyDialog *dialog,
+ const char *property_id);
-void ephy_dialog_get_value (EphyDialog *dialog,
- int property_id,
+void ephy_dialog_get_value (EphyDialog *dialog,
+ const char *property_id,
GValue *value);
+void ephy_dialog_set_value (EphyDialog *dialog,
+ const char *property_id,
+ const GValue *value);
+
+void ephy_dialog_set_pref (EphyDialog *dialog,
+ const char *property_id,
+ const char *pref);
+
G_END_DECLS
#endif
-
diff --git a/lib/ephy-file-chooser.c b/lib/ephy-file-chooser.c
index ec8cf2d27..668c7b522 100644
--- a/lib/ephy-file-chooser.c
+++ b/lib/ephy-file-chooser.c
@@ -237,7 +237,10 @@ ephy_file_chooser_new (const char *title,
* _after_ our instance_init and construct-param setters will have
* run.
*/
- ephy_file_chooser_set_persist_key (dialog, persist_key);
+ if (persist_key != NULL)
+ {
+ ephy_file_chooser_set_persist_key (dialog, persist_key);
+ }
if (action == GTK_FILE_CHOOSER_ACTION_OPEN)
{