Thu Aug 7 15:23:08 2003 Jonathan Blandford <jrb@redhat.com> * gconf-property-editor.c (gconf_property_editor_set_prop): damn it Jonathan. Save the @#*&$@# file before committing.
1794 lines
48 KiB
C
1794 lines
48 KiB
C
/* -*- mode: c; style: linux -*- */
|
|
|
|
/* gconf-property-editor.c
|
|
* Copyright (C) 2001 Ximian, Inc.
|
|
*
|
|
* Written by Bradford Hovinen <hovinen@ximian.com>
|
|
*
|
|
* 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.
|
|
*/
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
# include "config.h"
|
|
#endif
|
|
|
|
#include <string.h>
|
|
#include <stdarg.h>
|
|
|
|
#include "gconf-property-editor.h"
|
|
#include "gconf-property-editor-marshal.h"
|
|
|
|
#include "preview-file-selection.h"
|
|
|
|
enum {
|
|
VALUE_CHANGED,
|
|
LAST_SIGNAL
|
|
};
|
|
|
|
enum {
|
|
PROP_0,
|
|
PROP_KEY,
|
|
PROP_CALLBACK,
|
|
PROP_CHANGESET,
|
|
PROP_CONV_TO_WIDGET_CB,
|
|
PROP_CONV_FROM_WIDGET_CB,
|
|
PROP_UI_CONTROL,
|
|
PROP_DATA,
|
|
PROP_DATA_FREE_CB
|
|
};
|
|
|
|
typedef void (*GConfPropertyEditorDataFreeCb) (gpointer data);
|
|
|
|
struct _GConfPropertyEditorPrivate
|
|
{
|
|
gchar *key;
|
|
guint handler_id;
|
|
GConfChangeSet *changeset;
|
|
GObject *ui_control;
|
|
GConfPEditorValueConvFn conv_to_widget_cb;
|
|
GConfPEditorValueConvFn conv_from_widget_cb;
|
|
GConfClientNotifyFunc callback;
|
|
gboolean inited;
|
|
|
|
gpointer data;
|
|
GConfPropertyEditorDataFreeCb data_free_cb;
|
|
};
|
|
|
|
typedef struct
|
|
{
|
|
GType enum_type;
|
|
GConfPEditorGetValueFn enum_val_true_fn;
|
|
gpointer enum_val_true_fn_data;
|
|
guint enum_val_false;
|
|
gboolean use_nick;
|
|
} GConfPropertyEditorEnumData;
|
|
|
|
static guint peditor_signals[LAST_SIGNAL];
|
|
|
|
static GObjectClass *parent_class;
|
|
|
|
static void gconf_property_editor_init (GConfPropertyEditor *gconf_property_editor,
|
|
GConfPropertyEditorClass *class);
|
|
static void gconf_property_editor_class_init (GConfPropertyEditorClass *class);
|
|
static void gconf_property_editor_base_init (GConfPropertyEditorClass *class);
|
|
|
|
static void gconf_property_editor_set_prop (GObject *object,
|
|
guint prop_id,
|
|
const GValue *value,
|
|
GParamSpec *pspec);
|
|
static void gconf_property_editor_get_prop (GObject *object,
|
|
guint prop_id,
|
|
GValue *value,
|
|
GParamSpec *pspec);
|
|
|
|
static void gconf_property_editor_finalize (GObject *object);
|
|
|
|
static GObject *gconf_peditor_new (gchar *key,
|
|
GConfClientNotifyFunc cb,
|
|
GConfChangeSet *changeset,
|
|
GObject *ui_control,
|
|
const gchar *first_prop_name,
|
|
va_list var_args,
|
|
const gchar *first_custom,
|
|
...);
|
|
|
|
GType
|
|
gconf_property_editor_get_type (void)
|
|
{
|
|
static GType gconf_property_editor_type = 0;
|
|
|
|
if (!gconf_property_editor_type) {
|
|
GTypeInfo gconf_property_editor_info = {
|
|
sizeof (GConfPropertyEditorClass),
|
|
(GBaseInitFunc) gconf_property_editor_base_init,
|
|
NULL, /* GBaseFinalizeFunc */
|
|
(GClassInitFunc) gconf_property_editor_class_init,
|
|
NULL, /* GClassFinalizeFunc */
|
|
NULL, /* user-supplied data */
|
|
sizeof (GConfPropertyEditor),
|
|
0, /* n_preallocs */
|
|
(GInstanceInitFunc) gconf_property_editor_init,
|
|
NULL
|
|
};
|
|
|
|
gconf_property_editor_type =
|
|
g_type_register_static (G_TYPE_OBJECT,
|
|
"GConfPropertyEditor",
|
|
&gconf_property_editor_info, 0);
|
|
}
|
|
|
|
return gconf_property_editor_type;
|
|
}
|
|
|
|
static GConfValue*
|
|
gconf_property_editor_conv_default (GConfPropertyEditor *peditor,
|
|
const GConfValue *value)
|
|
{
|
|
return gconf_value_copy (value);
|
|
}
|
|
|
|
static void
|
|
gconf_property_editor_init (GConfPropertyEditor *gconf_property_editor,
|
|
GConfPropertyEditorClass *class)
|
|
{
|
|
gconf_property_editor->p = g_new0 (GConfPropertyEditorPrivate, 1);
|
|
gconf_property_editor->p->conv_to_widget_cb = gconf_property_editor_conv_default;
|
|
gconf_property_editor->p->conv_from_widget_cb = gconf_property_editor_conv_default;
|
|
gconf_property_editor->p->inited = FALSE;
|
|
}
|
|
|
|
static void
|
|
gconf_property_editor_base_init (GConfPropertyEditorClass *class)
|
|
{
|
|
}
|
|
|
|
static void
|
|
gconf_property_editor_class_init (GConfPropertyEditorClass *class)
|
|
{
|
|
GObjectClass *object_class;
|
|
|
|
object_class = G_OBJECT_CLASS (class);
|
|
|
|
object_class->finalize = gconf_property_editor_finalize;
|
|
object_class->set_property = gconf_property_editor_set_prop;
|
|
object_class->get_property = gconf_property_editor_get_prop;
|
|
|
|
g_object_class_install_property
|
|
(object_class, PROP_KEY,
|
|
g_param_spec_string ("key",
|
|
_("Key"),
|
|
_("GConf key to which this property editor is attached"),
|
|
NULL,
|
|
G_PARAM_READWRITE));
|
|
g_object_class_install_property
|
|
(object_class, PROP_CALLBACK,
|
|
g_param_spec_pointer ("callback",
|
|
_("Callback"),
|
|
_("Issue this callback when the value associated with key gets changed"),
|
|
G_PARAM_WRITABLE));
|
|
g_object_class_install_property
|
|
(object_class, PROP_CHANGESET,
|
|
g_param_spec_pointer ("changeset",
|
|
_("Change set"),
|
|
_("GConf change set containing data to be forwarded to the gconf client on apply"),
|
|
G_PARAM_READWRITE));
|
|
g_object_class_install_property
|
|
(object_class, PROP_CONV_TO_WIDGET_CB,
|
|
g_param_spec_pointer ("conv-to-widget-cb",
|
|
_("Conversion to widget callback"),
|
|
_("Callback to be issued when data are to be converted from GConf to the widget"),
|
|
G_PARAM_WRITABLE));
|
|
g_object_class_install_property
|
|
(object_class, PROP_CONV_FROM_WIDGET_CB,
|
|
g_param_spec_pointer ("conv-from-widget-cb",
|
|
_("Conversion from widget callback"),
|
|
_("Callback to be issued when data are to be converted to GConf from the widget"),
|
|
G_PARAM_WRITABLE));
|
|
g_object_class_install_property
|
|
(object_class, PROP_UI_CONTROL,
|
|
g_param_spec_object ("ui-control",
|
|
_("UI Control"),
|
|
_("Object that controls the property (normally a widget)"),
|
|
G_TYPE_OBJECT,
|
|
G_PARAM_WRITABLE));
|
|
|
|
peditor_signals[VALUE_CHANGED] =
|
|
g_signal_new ("value-changed",
|
|
G_TYPE_FROM_CLASS (object_class), 0,
|
|
G_STRUCT_OFFSET (GConfPropertyEditorClass, value_changed),
|
|
NULL, NULL,
|
|
(GSignalCMarshaller) gconf_property_editor_marshal_VOID__STRING_POINTER,
|
|
G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_POINTER);
|
|
|
|
g_object_class_install_property
|
|
(object_class, PROP_DATA,
|
|
g_param_spec_pointer ("data",
|
|
_("Property editor object data"),
|
|
_("Custom data required by the specific property editor"),
|
|
G_PARAM_WRITABLE));
|
|
|
|
g_object_class_install_property
|
|
(object_class, PROP_DATA_FREE_CB,
|
|
g_param_spec_pointer ("data-free-cb",
|
|
_("Property editor data freeing callback"),
|
|
_("Callback to be issued when property editor object data is to be freed"),
|
|
G_PARAM_WRITABLE));
|
|
|
|
parent_class = G_OBJECT_CLASS
|
|
(g_type_class_ref (G_TYPE_OBJECT));
|
|
}
|
|
|
|
static void
|
|
gconf_property_editor_set_prop (GObject *object,
|
|
guint prop_id,
|
|
const GValue *value,
|
|
GParamSpec *pspec)
|
|
{
|
|
GConfPropertyEditor *peditor;
|
|
GConfClient *client;
|
|
GConfNotifyFunc cb;
|
|
|
|
g_return_if_fail (object != NULL);
|
|
g_return_if_fail (IS_GCONF_PROPERTY_EDITOR (object));
|
|
|
|
peditor = GCONF_PROPERTY_EDITOR (object);
|
|
|
|
switch (prop_id) {
|
|
case PROP_KEY:
|
|
peditor->p->key = g_value_dup_string (value);
|
|
break;
|
|
|
|
case PROP_CALLBACK:
|
|
client = gconf_client_get_default ();
|
|
cb = g_value_get_pointer (value);
|
|
peditor->p->callback = (GConfClientNotifyFunc) cb;
|
|
if (peditor->p->handler_id != 0) {
|
|
gconf_client_notify_remove (client,
|
|
peditor->p->handler_id);
|
|
}
|
|
peditor->p->handler_id =
|
|
gconf_client_notify_add (client, peditor->p->key,
|
|
peditor->p->callback,
|
|
peditor, NULL, NULL);
|
|
break;
|
|
|
|
case PROP_CHANGESET:
|
|
peditor->p->changeset = g_value_get_pointer (value);
|
|
break;
|
|
|
|
case PROP_CONV_TO_WIDGET_CB:
|
|
peditor->p->conv_to_widget_cb = g_value_get_pointer (value);
|
|
break;
|
|
|
|
case PROP_CONV_FROM_WIDGET_CB:
|
|
peditor->p->conv_from_widget_cb = g_value_get_pointer (value);
|
|
break;
|
|
|
|
case PROP_UI_CONTROL:
|
|
peditor->p->ui_control = g_value_get_object (value);
|
|
g_object_weak_ref (peditor->p->ui_control, (GWeakNotify) g_object_unref, object);
|
|
break;
|
|
case PROP_DATA:
|
|
peditor->p->data = g_value_get_pointer (value);
|
|
break;
|
|
case PROP_DATA_FREE_CB:
|
|
peditor->p->data_free_cb = g_value_get_pointer (value);
|
|
break;
|
|
default:
|
|
g_warning ("Bad argument set");
|
|
break;
|
|
}
|
|
}
|
|
|
|
static void
|
|
gconf_property_editor_get_prop (GObject *object,
|
|
guint prop_id,
|
|
GValue *value,
|
|
GParamSpec *pspec)
|
|
{
|
|
GConfPropertyEditor *peditor;
|
|
|
|
g_return_if_fail (object != NULL);
|
|
g_return_if_fail (IS_GCONF_PROPERTY_EDITOR (object));
|
|
|
|
peditor = GCONF_PROPERTY_EDITOR (object);
|
|
|
|
switch (prop_id) {
|
|
case PROP_KEY:
|
|
g_value_set_string (value, peditor->p->key);
|
|
break;
|
|
|
|
case PROP_CHANGESET:
|
|
g_value_set_pointer (value, peditor->p->changeset);
|
|
break;
|
|
|
|
default:
|
|
g_warning ("Bad argument get");
|
|
break;
|
|
}
|
|
}
|
|
|
|
static void
|
|
gconf_property_editor_finalize (GObject *object)
|
|
{
|
|
GConfPropertyEditor *gconf_property_editor;
|
|
|
|
g_return_if_fail (object != NULL);
|
|
g_return_if_fail (IS_GCONF_PROPERTY_EDITOR (object));
|
|
|
|
gconf_property_editor = GCONF_PROPERTY_EDITOR (object);
|
|
|
|
if (gconf_property_editor->p->data_free_cb)
|
|
gconf_property_editor->p->data_free_cb (gconf_property_editor->p->data);
|
|
|
|
if (gconf_property_editor->p->handler_id != 0) {
|
|
GConfClient *client;
|
|
|
|
client = gconf_client_get_default ();
|
|
gconf_client_notify_remove (client,
|
|
gconf_property_editor->p->handler_id);
|
|
}
|
|
|
|
g_free (gconf_property_editor->p);
|
|
|
|
G_OBJECT_CLASS (parent_class)->finalize (object);
|
|
}
|
|
|
|
static GObject *
|
|
gconf_peditor_new (gchar *key,
|
|
GConfClientNotifyFunc cb,
|
|
GConfChangeSet *changeset,
|
|
GObject *ui_control,
|
|
const gchar *first_prop_name,
|
|
va_list var_args,
|
|
const gchar *first_custom,
|
|
...)
|
|
{
|
|
GObject *obj;
|
|
GConfClient *client;
|
|
GConfEntry *gconf_entry;
|
|
|
|
g_return_val_if_fail (key != NULL, NULL);
|
|
g_return_val_if_fail (cb != NULL, NULL);
|
|
|
|
obj = g_object_new (gconf_property_editor_get_type (),
|
|
"key", key,
|
|
"callback", cb,
|
|
"changeset", changeset,
|
|
"ui-control", ui_control,
|
|
NULL);
|
|
|
|
g_object_set_valist (obj, first_prop_name, var_args);
|
|
|
|
if (first_custom)
|
|
{
|
|
va_list custom_args;
|
|
va_start (custom_args, first_custom);
|
|
g_object_set_valist (obj, first_custom, custom_args);
|
|
va_end (custom_args);
|
|
}
|
|
|
|
client = gconf_client_get_default ();
|
|
gconf_entry = gconf_client_get_entry (client, GCONF_PROPERTY_EDITOR (obj)->p->key, NULL, TRUE, NULL);
|
|
GCONF_PROPERTY_EDITOR (obj)->p->callback (client, 0, gconf_entry, obj);
|
|
GCONF_PROPERTY_EDITOR (obj)->p->inited = TRUE;
|
|
gconf_entry_free (gconf_entry);
|
|
g_object_unref (G_OBJECT (client));
|
|
|
|
return obj;
|
|
}
|
|
|
|
const gchar *
|
|
gconf_property_editor_get_key (GConfPropertyEditor *peditor)
|
|
{
|
|
return peditor->p->key;
|
|
}
|
|
|
|
GObject *
|
|
gconf_property_editor_get_ui_control (GConfPropertyEditor *peditor)
|
|
{
|
|
return peditor->p->ui_control;
|
|
}
|
|
|
|
static void
|
|
peditor_set_gconf_value (GConfPropertyEditor *peditor,
|
|
const gchar *key,
|
|
GConfValue *value)
|
|
{
|
|
if (peditor->p->changeset != NULL)
|
|
gconf_change_set_set (peditor->p->changeset, peditor->p->key, value);
|
|
else
|
|
gconf_client_set (gconf_client_get_default (), peditor->p->key, value, NULL);
|
|
}
|
|
|
|
static void
|
|
peditor_boolean_value_changed (GConfClient *client,
|
|
guint cnxn_id,
|
|
GConfEntry *entry,
|
|
GConfPropertyEditor *peditor)
|
|
{
|
|
GConfValue *value, *value_wid;
|
|
|
|
if (peditor->p->changeset != NULL)
|
|
gconf_change_set_remove (peditor->p->changeset, peditor->p->key);
|
|
|
|
value = gconf_entry_get_value (entry);
|
|
|
|
if (value != NULL) {
|
|
value_wid = peditor->p->conv_to_widget_cb (peditor, value);
|
|
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (peditor->p->ui_control), gconf_value_get_bool (value_wid));
|
|
gconf_value_free (value_wid);
|
|
}
|
|
}
|
|
|
|
static void
|
|
peditor_boolean_widget_changed (GConfPropertyEditor *peditor,
|
|
GtkToggleButton *tb)
|
|
{
|
|
GConfValue *value, *value_wid;
|
|
|
|
if (!peditor->p->inited) return;
|
|
value_wid = gconf_value_new (GCONF_VALUE_BOOL);
|
|
gconf_value_set_bool (value_wid, gtk_toggle_button_get_active (tb));
|
|
value = peditor->p->conv_from_widget_cb (peditor, value_wid);
|
|
peditor_set_gconf_value (peditor, peditor->p->key, value);
|
|
g_signal_emit (peditor, peditor_signals[VALUE_CHANGED], 0, peditor->p->key, value);
|
|
gconf_value_free (value_wid);
|
|
gconf_value_free (value);
|
|
}
|
|
|
|
GObject *
|
|
gconf_peditor_new_boolean (GConfChangeSet *changeset,
|
|
gchar *key,
|
|
GtkWidget *checkbox,
|
|
gchar *first_property_name,
|
|
...)
|
|
{
|
|
GObject *peditor;
|
|
va_list var_args;
|
|
|
|
g_return_val_if_fail (key != NULL, NULL);
|
|
g_return_val_if_fail (checkbox != NULL, NULL);
|
|
g_return_val_if_fail (GTK_IS_TOGGLE_BUTTON (checkbox), NULL);
|
|
|
|
va_start (var_args, first_property_name);
|
|
|
|
peditor = gconf_peditor_new
|
|
(key,
|
|
(GConfClientNotifyFunc) peditor_boolean_value_changed,
|
|
changeset,
|
|
G_OBJECT (checkbox),
|
|
first_property_name,
|
|
var_args,
|
|
NULL);
|
|
|
|
va_end (var_args);
|
|
|
|
g_signal_connect_swapped (G_OBJECT (checkbox), "toggled",
|
|
(GCallback) peditor_boolean_widget_changed, peditor);
|
|
|
|
return peditor;
|
|
}
|
|
|
|
static void
|
|
peditor_integer_value_changed (GConfClient *client,
|
|
guint cnxn_id,
|
|
GConfEntry *entry,
|
|
GConfPropertyEditor *peditor)
|
|
{
|
|
GConfValue *value, *value_wid;
|
|
const char *entry_current_text;
|
|
int entry_current_integer;
|
|
|
|
if (peditor->p->changeset != NULL)
|
|
gconf_change_set_remove (peditor->p->changeset, peditor->p->key);
|
|
|
|
value = gconf_entry_get_value (entry);
|
|
|
|
if (value != NULL) {
|
|
value_wid = peditor->p->conv_to_widget_cb (peditor, value);
|
|
entry_current_text = gtk_entry_get_text (GTK_ENTRY (peditor->p->ui_control));
|
|
entry_current_integer = strtol (entry_current_text, NULL, 10);
|
|
if (entry_current_integer != gconf_value_get_int (value)) {
|
|
char *buf = g_strdup_printf ("%d", gconf_value_get_int (value_wid));
|
|
gtk_entry_set_text (GTK_ENTRY (peditor->p->ui_control), buf);
|
|
g_free (buf);
|
|
}
|
|
gconf_value_free (value_wid);
|
|
}
|
|
}
|
|
|
|
static void
|
|
peditor_integer_widget_changed (GConfPropertyEditor *peditor,
|
|
GtkEntry *entry)
|
|
{
|
|
GConfValue *value, *value_wid;
|
|
|
|
if (!peditor->p->inited) return;
|
|
|
|
value_wid = gconf_value_new (GCONF_VALUE_INT);
|
|
|
|
gconf_value_set_int (value_wid, strtol (gtk_entry_get_text (entry), NULL, 10));
|
|
value = peditor->p->conv_from_widget_cb (peditor, value_wid);
|
|
|
|
peditor_set_gconf_value (peditor, peditor->p->key, value);
|
|
|
|
g_signal_emit (peditor, peditor_signals[VALUE_CHANGED], 0, peditor->p->key, value);
|
|
gconf_value_free (value_wid);
|
|
gconf_value_free (value);
|
|
}
|
|
|
|
static GObject *
|
|
gconf_peditor_new_integer_valist (GConfChangeSet *changeset,
|
|
gchar *key,
|
|
GtkWidget *entry,
|
|
gchar *first_property_name,
|
|
va_list var_args)
|
|
{
|
|
GObject *peditor;
|
|
|
|
peditor = gconf_peditor_new
|
|
(key,
|
|
(GConfClientNotifyFunc) peditor_integer_value_changed,
|
|
changeset,
|
|
G_OBJECT (entry),
|
|
first_property_name,
|
|
var_args, NULL);
|
|
|
|
g_signal_connect_swapped (G_OBJECT (entry), "changed",
|
|
(GCallback) peditor_integer_widget_changed, peditor);
|
|
|
|
return peditor;
|
|
}
|
|
|
|
GObject *
|
|
gconf_peditor_new_integer (GConfChangeSet *changeset,
|
|
gchar *key,
|
|
GtkWidget *entry,
|
|
gchar *first_property_name,
|
|
...)
|
|
{
|
|
GObject *peditor;
|
|
va_list var_args;
|
|
|
|
g_return_val_if_fail (key != NULL, NULL);
|
|
g_return_val_if_fail (entry != NULL, NULL);
|
|
g_return_val_if_fail (GTK_IS_ENTRY (entry), NULL);
|
|
|
|
va_start (var_args, first_property_name);
|
|
|
|
peditor = gconf_peditor_new_integer_valist
|
|
(changeset, key, entry,
|
|
first_property_name, var_args);
|
|
|
|
va_end (var_args);
|
|
|
|
return peditor;
|
|
}
|
|
|
|
static void
|
|
peditor_string_value_changed (GConfClient *client,
|
|
guint cnxn_id,
|
|
GConfEntry *entry,
|
|
GConfPropertyEditor *peditor)
|
|
{
|
|
GConfValue *value, *value_wid;
|
|
const char *entry_current_text;
|
|
|
|
if (peditor->p->changeset != NULL)
|
|
gconf_change_set_remove (peditor->p->changeset, peditor->p->key);
|
|
|
|
value = gconf_entry_get_value (entry);
|
|
|
|
if (value != NULL) {
|
|
value_wid = peditor->p->conv_to_widget_cb (peditor, value);
|
|
entry_current_text = gtk_entry_get_text (GTK_ENTRY (peditor->p->ui_control));
|
|
if (strcmp (entry_current_text, gconf_value_get_string (value)) != 0) {
|
|
gtk_entry_set_text (GTK_ENTRY (peditor->p->ui_control), gconf_value_get_string (value_wid));
|
|
}
|
|
gconf_value_free (value_wid);
|
|
}
|
|
}
|
|
|
|
static void
|
|
peditor_string_widget_changed (GConfPropertyEditor *peditor,
|
|
GtkEntry *entry)
|
|
{
|
|
GConfValue *value, *value_wid;
|
|
|
|
if (!peditor->p->inited) return;
|
|
|
|
value_wid = gconf_value_new (GCONF_VALUE_STRING);
|
|
|
|
gconf_value_set_string (value_wid, gtk_entry_get_text (entry));
|
|
value = peditor->p->conv_from_widget_cb (peditor, value_wid);
|
|
|
|
peditor_set_gconf_value (peditor, peditor->p->key, value);
|
|
|
|
g_signal_emit (peditor, peditor_signals[VALUE_CHANGED], 0, peditor->p->key, value);
|
|
gconf_value_free (value_wid);
|
|
gconf_value_free (value);
|
|
}
|
|
|
|
static GObject *
|
|
gconf_peditor_new_string_valist (GConfChangeSet *changeset,
|
|
gchar *key,
|
|
GtkWidget *entry,
|
|
gchar *first_property_name,
|
|
va_list var_args)
|
|
{
|
|
GObject *peditor;
|
|
|
|
peditor = gconf_peditor_new
|
|
(key,
|
|
(GConfClientNotifyFunc) peditor_string_value_changed,
|
|
changeset,
|
|
G_OBJECT (entry),
|
|
first_property_name,
|
|
var_args, NULL);
|
|
|
|
g_signal_connect_swapped (G_OBJECT (entry), "changed",
|
|
(GCallback) peditor_string_widget_changed, peditor);
|
|
|
|
return peditor;
|
|
}
|
|
|
|
GObject *
|
|
gconf_peditor_new_string (GConfChangeSet *changeset,
|
|
gchar *key,
|
|
GtkWidget *entry,
|
|
gchar *first_property_name,
|
|
...)
|
|
{
|
|
GObject *peditor;
|
|
va_list var_args;
|
|
|
|
g_return_val_if_fail (key != NULL, NULL);
|
|
g_return_val_if_fail (entry != NULL, NULL);
|
|
g_return_val_if_fail (GTK_IS_ENTRY (entry), NULL);
|
|
|
|
va_start (var_args, first_property_name);
|
|
|
|
peditor = gconf_peditor_new_string_valist
|
|
(changeset, key, entry,
|
|
first_property_name, var_args);
|
|
|
|
va_end (var_args);
|
|
|
|
return peditor;
|
|
}
|
|
|
|
GObject *
|
|
gconf_peditor_new_filename (GConfChangeSet *changeset,
|
|
gchar *key,
|
|
GtkWidget *file_entry,
|
|
gchar *first_property_name,
|
|
...)
|
|
{
|
|
GObject *peditor;
|
|
va_list var_args;
|
|
|
|
g_return_val_if_fail (key != NULL, NULL);
|
|
g_return_val_if_fail (file_entry != NULL, NULL);
|
|
g_return_val_if_fail (GNOME_IS_FILE_ENTRY (file_entry), NULL);
|
|
|
|
va_start (var_args, first_property_name);
|
|
|
|
peditor = gconf_peditor_new_string_valist
|
|
(changeset, key,
|
|
gnome_file_entry_gtk_entry (GNOME_FILE_ENTRY (file_entry)),
|
|
first_property_name, var_args);
|
|
|
|
va_end (var_args);
|
|
|
|
return peditor;
|
|
}
|
|
|
|
static void
|
|
peditor_color_value_changed (GConfClient *client,
|
|
guint cnxn_id,
|
|
GConfEntry *entry,
|
|
GConfPropertyEditor *peditor)
|
|
{
|
|
GConfValue *value, *value_wid;
|
|
GdkColor color;
|
|
|
|
if (peditor->p->changeset != NULL)
|
|
gconf_change_set_remove (peditor->p->changeset, peditor->p->key);
|
|
|
|
value = gconf_entry_get_value (entry);
|
|
|
|
if (value != NULL) {
|
|
value_wid = peditor->p->conv_to_widget_cb (peditor, value);
|
|
gdk_color_parse (gconf_value_get_string (value_wid), &color);
|
|
gnome_color_picker_set_i16 (GNOME_COLOR_PICKER (peditor->p->ui_control), color.red, color.green, color.blue, 65535);
|
|
gconf_value_free (value_wid);
|
|
}
|
|
}
|
|
|
|
static void
|
|
peditor_color_widget_changed (GConfPropertyEditor *peditor,
|
|
guint r,
|
|
guint g,
|
|
guint b,
|
|
guint a,
|
|
GnomeColorPicker *cp)
|
|
{
|
|
gchar *str;
|
|
GConfValue *value, *value_wid;
|
|
|
|
if (!peditor->p->inited) return;
|
|
|
|
value_wid = gconf_value_new (GCONF_VALUE_STRING);
|
|
str = g_strdup_printf ("#%02x%02x%02x", r >> 8, g >> 8, b >> 8);
|
|
gconf_value_set_string (value_wid, str);
|
|
g_free (str);
|
|
|
|
value = peditor->p->conv_from_widget_cb (peditor, value_wid);
|
|
|
|
peditor_set_gconf_value (peditor, peditor->p->key, value);
|
|
g_signal_emit (peditor, peditor_signals[VALUE_CHANGED], 0, peditor->p->key, value);
|
|
|
|
gconf_value_free (value_wid);
|
|
gconf_value_free (value);
|
|
}
|
|
|
|
GObject *
|
|
gconf_peditor_new_color (GConfChangeSet *changeset,
|
|
gchar *key,
|
|
GtkWidget *cp,
|
|
gchar *first_property_name,
|
|
...)
|
|
{
|
|
GObject *peditor;
|
|
va_list var_args;
|
|
|
|
g_return_val_if_fail (key != NULL, NULL);
|
|
g_return_val_if_fail (cp != NULL, NULL);
|
|
g_return_val_if_fail (GNOME_IS_COLOR_PICKER (cp), NULL);
|
|
|
|
va_start (var_args, first_property_name);
|
|
|
|
peditor = gconf_peditor_new
|
|
(key,
|
|
(GConfClientNotifyFunc) peditor_color_value_changed,
|
|
changeset,
|
|
G_OBJECT (cp),
|
|
first_property_name,
|
|
var_args, NULL);
|
|
|
|
va_end (var_args);
|
|
|
|
g_signal_connect_swapped (G_OBJECT (cp), "color_set",
|
|
(GCallback) peditor_color_widget_changed, peditor);
|
|
|
|
return peditor;
|
|
}
|
|
|
|
static int
|
|
peditor_enum_int_from_string (GType type, const gchar *str, gboolean use_nick)
|
|
{
|
|
GEnumClass *klass;
|
|
GEnumValue *val;
|
|
int ret = -1;
|
|
|
|
klass = g_type_class_ref (type);
|
|
if (use_nick)
|
|
val = g_enum_get_value_by_nick (klass, str);
|
|
else
|
|
val = g_enum_get_value_by_name (klass, str);
|
|
|
|
g_type_class_unref (klass);
|
|
|
|
if (val)
|
|
ret = val->value;
|
|
|
|
return ret;
|
|
}
|
|
|
|
static gchar*
|
|
peditor_enum_string_from_int (GType type, const int index, gboolean use_nick)
|
|
{
|
|
GEnumClass *klass;
|
|
GEnumValue *val;
|
|
gchar *ret = NULL;
|
|
|
|
klass = g_type_class_ref (type);
|
|
val = g_enum_get_value (klass, index);
|
|
if (val)
|
|
{
|
|
if (val->value_nick && use_nick)
|
|
ret = g_strdup (val->value_nick);
|
|
else
|
|
ret = g_strdup (val->value_name);
|
|
}
|
|
|
|
g_type_class_unref (klass);
|
|
|
|
return ret;
|
|
}
|
|
|
|
static GConfValue*
|
|
peditor_enum_conv_to_widget (GConfPropertyEditor *peditor,
|
|
const GConfValue *value)
|
|
{
|
|
GConfValue *ret;
|
|
GConfPropertyEditorEnumData *data = peditor->p->data;
|
|
int index;
|
|
|
|
if (value->type == GCONF_VALUE_INT)
|
|
return gconf_value_copy (value);
|
|
|
|
ret = gconf_value_new (GCONF_VALUE_INT);
|
|
|
|
index = peditor_enum_int_from_string (data->enum_type,
|
|
gconf_value_get_string (value),
|
|
data->use_nick);
|
|
|
|
gconf_value_set_int (ret, index);
|
|
|
|
return ret;
|
|
}
|
|
|
|
static GConfValue*
|
|
peditor_enum_conv_from_widget (GConfPropertyEditor *peditor,
|
|
const GConfValue *value)
|
|
{
|
|
GConfValue *ret;
|
|
GConfPropertyEditorEnumData *data = peditor->p->data;
|
|
gchar *str;
|
|
|
|
if (value->type == GCONF_VALUE_STRING)
|
|
return gconf_value_copy (value);
|
|
|
|
ret = gconf_value_new (GCONF_VALUE_STRING);
|
|
str = peditor_enum_string_from_int (data->enum_type,
|
|
gconf_value_get_int (value),
|
|
data->use_nick);
|
|
gconf_value_set_string (ret, str);
|
|
g_free (str);
|
|
|
|
return ret;
|
|
}
|
|
|
|
static void
|
|
peditor_select_menu_value_changed (GConfClient *client,
|
|
guint cnxn_id,
|
|
GConfEntry *entry,
|
|
GConfPropertyEditor *peditor)
|
|
{
|
|
GConfValue *value, *value_wid;
|
|
|
|
if (peditor->p->changeset != NULL)
|
|
gconf_change_set_remove (peditor->p->changeset, peditor->p->key);
|
|
|
|
value = gconf_entry_get_value (entry);
|
|
|
|
if (value != NULL) {
|
|
value_wid = peditor->p->conv_to_widget_cb (peditor, value);
|
|
gtk_option_menu_set_history (GTK_OPTION_MENU (peditor->p->ui_control), gconf_value_get_int (value_wid));
|
|
gconf_value_free (value_wid);
|
|
}
|
|
}
|
|
|
|
static void
|
|
peditor_select_menu_widget_changed (GConfPropertyEditor *peditor,
|
|
GtkOptionMenu *option_menu)
|
|
{
|
|
GConfValue *value, *value_wid;
|
|
|
|
if (!peditor->p->inited) return;
|
|
value_wid = gconf_value_new (GCONF_VALUE_INT);
|
|
gconf_value_set_int (value_wid, gtk_option_menu_get_history (option_menu));
|
|
value = peditor->p->conv_from_widget_cb (peditor, value_wid);
|
|
peditor_set_gconf_value (peditor, peditor->p->key, value);
|
|
g_signal_emit (peditor, peditor_signals[VALUE_CHANGED], 0, peditor->p->key, value);
|
|
gconf_value_free (value_wid);
|
|
gconf_value_free (value);
|
|
}
|
|
|
|
GObject *
|
|
gconf_peditor_new_select_menu (GConfChangeSet *changeset,
|
|
gchar *key,
|
|
GtkWidget *option_menu,
|
|
gchar *first_property_name,
|
|
...)
|
|
{
|
|
GObject *peditor;
|
|
va_list var_args;
|
|
|
|
g_return_val_if_fail (key != NULL, NULL);
|
|
g_return_val_if_fail (option_menu != NULL, NULL);
|
|
g_return_val_if_fail (GTK_IS_OPTION_MENU (option_menu), NULL);
|
|
|
|
va_start (var_args, first_property_name);
|
|
|
|
peditor = gconf_peditor_new
|
|
(key,
|
|
(GConfClientNotifyFunc) peditor_select_menu_value_changed,
|
|
changeset,
|
|
G_OBJECT (option_menu),
|
|
first_property_name,
|
|
var_args, NULL);
|
|
|
|
va_end (var_args);
|
|
|
|
g_signal_connect_swapped (G_OBJECT (option_menu), "changed",
|
|
(GCallback) peditor_select_menu_widget_changed, peditor);
|
|
|
|
return peditor;
|
|
}
|
|
|
|
GObject *
|
|
gconf_peditor_new_select_menu_with_enum (GConfChangeSet *changeset,
|
|
gchar *key,
|
|
GtkWidget *option_menu,
|
|
GType enum_type,
|
|
gboolean use_nick,
|
|
gchar *first_property_name,
|
|
...)
|
|
{
|
|
GConfPropertyEditor *peditor;
|
|
GConfPropertyEditorEnumData *data;
|
|
va_list var_args;
|
|
|
|
g_return_val_if_fail (key != NULL, NULL);
|
|
g_return_val_if_fail (option_menu != NULL, NULL);
|
|
g_return_val_if_fail (GTK_IS_OPTION_MENU (option_menu), NULL);
|
|
g_return_val_if_fail (enum_type != G_TYPE_NONE, NULL);
|
|
|
|
data = g_new0 (GConfPropertyEditorEnumData, 1);
|
|
data->enum_type = enum_type;
|
|
data->use_nick = use_nick;
|
|
|
|
va_start (var_args, first_property_name);
|
|
|
|
peditor = GCONF_PROPERTY_EDITOR (
|
|
gconf_peditor_new
|
|
(key,
|
|
(GConfClientNotifyFunc) peditor_select_menu_value_changed,
|
|
changeset,
|
|
G_OBJECT (option_menu),
|
|
first_property_name,
|
|
var_args,
|
|
"conv-to-widget-cb",
|
|
peditor_enum_conv_to_widget,
|
|
"conv-from-widget-cb",
|
|
peditor_enum_conv_from_widget,
|
|
"data",
|
|
data,
|
|
"data-free-cb",
|
|
g_free,
|
|
NULL
|
|
));
|
|
|
|
va_end (var_args);
|
|
|
|
g_signal_connect_swapped (G_OBJECT (option_menu), "changed",
|
|
(GCallback) peditor_select_menu_widget_changed, peditor);
|
|
|
|
return G_OBJECT (peditor);
|
|
}
|
|
|
|
static void
|
|
peditor_select_radio_value_changed (GConfClient *client,
|
|
guint cnxn_id,
|
|
GConfEntry *entry,
|
|
GConfPropertyEditor *peditor)
|
|
{
|
|
GSList *group, *link;
|
|
GConfValue *value, *value_wid;
|
|
|
|
if (peditor->p->changeset != NULL)
|
|
gconf_change_set_remove (peditor->p->changeset, peditor->p->key);
|
|
|
|
value = gconf_entry_get_value (entry);
|
|
|
|
if (value != NULL) {
|
|
value_wid = peditor->p->conv_to_widget_cb (peditor, value);
|
|
group = g_slist_copy (gtk_radio_button_get_group (GTK_RADIO_BUTTON (peditor->p->ui_control)));
|
|
group = g_slist_reverse (group);
|
|
link = g_slist_nth (group, gconf_value_get_int (value_wid));
|
|
if (link && link->data)
|
|
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (link->data), TRUE);
|
|
gconf_value_free (value_wid);
|
|
g_slist_free (group);
|
|
}
|
|
}
|
|
|
|
static void
|
|
peditor_select_radio_widget_changed (GConfPropertyEditor *peditor,
|
|
GtkToggleButton *tb)
|
|
{
|
|
GSList *group;
|
|
GConfValue *value, *value_wid;
|
|
|
|
if (!peditor->p->inited) return;
|
|
if (!tb->active) return;
|
|
|
|
value_wid = gconf_value_new (GCONF_VALUE_INT);
|
|
group = g_slist_copy (gtk_radio_button_get_group (GTK_RADIO_BUTTON (peditor->p->ui_control)));
|
|
group = g_slist_reverse (group);
|
|
|
|
gconf_value_set_int (value_wid, g_slist_index (group, tb));
|
|
value = peditor->p->conv_from_widget_cb (peditor, value_wid);
|
|
|
|
peditor_set_gconf_value (peditor, peditor->p->key, value);
|
|
g_signal_emit (peditor, peditor_signals[VALUE_CHANGED], 0, peditor->p->key, value);
|
|
|
|
gconf_value_free (value_wid);
|
|
gconf_value_free (value);
|
|
g_slist_free (group);
|
|
}
|
|
|
|
GObject *
|
|
gconf_peditor_new_select_radio (GConfChangeSet *changeset,
|
|
gchar *key,
|
|
GSList *radio_group,
|
|
gchar *first_property_name,
|
|
...)
|
|
{
|
|
GObject *peditor;
|
|
GtkRadioButton *first_button;
|
|
GSList *item;
|
|
va_list var_args;
|
|
|
|
g_return_val_if_fail (key != NULL, NULL);
|
|
g_return_val_if_fail (radio_group != NULL, NULL);
|
|
g_return_val_if_fail (radio_group->data != NULL, NULL);
|
|
g_return_val_if_fail (GTK_IS_RADIO_BUTTON (radio_group->data), NULL);
|
|
|
|
first_button = GTK_RADIO_BUTTON (radio_group->data);
|
|
|
|
va_start (var_args, first_property_name);
|
|
|
|
peditor = gconf_peditor_new
|
|
(key,
|
|
(GConfClientNotifyFunc) peditor_select_radio_value_changed,
|
|
changeset,
|
|
G_OBJECT (first_button),
|
|
first_property_name,
|
|
var_args, NULL);
|
|
|
|
va_end (var_args);
|
|
|
|
for (item = radio_group; item != NULL; item = item->next)
|
|
g_signal_connect_swapped (G_OBJECT (item->data), "toggled",
|
|
(GCallback) peditor_select_radio_widget_changed, peditor);
|
|
|
|
return peditor;
|
|
}
|
|
|
|
static void
|
|
peditor_numeric_range_value_changed (GConfClient *client,
|
|
guint cnxn_id,
|
|
GConfEntry *entry,
|
|
GConfPropertyEditor *peditor)
|
|
{
|
|
GConfValue *value, *value_wid;
|
|
|
|
if (peditor->p->changeset != NULL)
|
|
gconf_change_set_remove (peditor->p->changeset, peditor->p->key);
|
|
|
|
value = gconf_entry_get_value (entry);
|
|
|
|
if (value != NULL) {
|
|
value_wid = peditor->p->conv_to_widget_cb (peditor, value);
|
|
|
|
switch (value_wid->type) {
|
|
case GCONF_VALUE_FLOAT:
|
|
gtk_adjustment_set_value (GTK_ADJUSTMENT (peditor->p->ui_control), gconf_value_get_float (value_wid));
|
|
break;
|
|
case GCONF_VALUE_INT:
|
|
gtk_adjustment_set_value (GTK_ADJUSTMENT (peditor->p->ui_control), gconf_value_get_int (value_wid));
|
|
break;
|
|
default:
|
|
g_warning ("Unknown type in range peditor: %d\n", value_wid->type);
|
|
}
|
|
gconf_value_free (value_wid);
|
|
}
|
|
}
|
|
|
|
static void
|
|
peditor_numeric_range_widget_changed (GConfPropertyEditor *peditor,
|
|
GtkAdjustment *adjustment)
|
|
{
|
|
GConfValue *value, *value_wid, *default_value;
|
|
|
|
if (!peditor->p->inited) return;
|
|
|
|
/* We try to get the default type from the schemas. if not, we default
|
|
* to a float.
|
|
*/
|
|
default_value = gconf_client_get_default_from_schema (gconf_client_get_default (),
|
|
peditor->p->key,
|
|
NULL);
|
|
if (default_value)
|
|
value_wid = gconf_value_new (default_value->type);
|
|
else
|
|
value_wid = gconf_value_new (GCONF_VALUE_FLOAT);
|
|
|
|
gconf_value_free (default_value);
|
|
|
|
g_assert (value_wid);
|
|
|
|
if (value_wid->type == GCONF_VALUE_INT)
|
|
gconf_value_set_int (value_wid, gtk_adjustment_get_value (adjustment));
|
|
else if (value_wid->type == GCONF_VALUE_FLOAT)
|
|
gconf_value_set_float (value_wid, gtk_adjustment_get_value (adjustment));
|
|
else {
|
|
g_warning ("unable to set a gconf key for %s of type %d\n",
|
|
peditor->p->key,
|
|
value_wid->type);
|
|
gconf_value_free (value_wid);
|
|
return;
|
|
}
|
|
value = peditor->p->conv_from_widget_cb (peditor, value_wid);
|
|
peditor_set_gconf_value (peditor, peditor->p->key, value);
|
|
g_signal_emit (peditor, peditor_signals[VALUE_CHANGED], 0, peditor->p->key, value);
|
|
gconf_value_free (value_wid);
|
|
gconf_value_free (value);
|
|
}
|
|
|
|
GObject *
|
|
gconf_peditor_new_numeric_range (GConfChangeSet *changeset,
|
|
gchar *key,
|
|
GtkWidget *range,
|
|
gchar *first_property_name,
|
|
...)
|
|
{
|
|
GObject *peditor;
|
|
GObject *adjustment = NULL;
|
|
va_list var_args;
|
|
|
|
g_return_val_if_fail (key != NULL, NULL);
|
|
g_return_val_if_fail (range != NULL, NULL);
|
|
g_return_val_if_fail (GTK_IS_RANGE (range)||GTK_IS_SPIN_BUTTON (range), NULL);
|
|
|
|
if (GTK_IS_RANGE (range))
|
|
adjustment = G_OBJECT (gtk_range_get_adjustment (GTK_RANGE (range)));
|
|
else if (GTK_IS_SPIN_BUTTON (range))
|
|
adjustment = G_OBJECT (gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (range)));
|
|
else
|
|
g_assert_not_reached ();
|
|
|
|
va_start (var_args, first_property_name);
|
|
|
|
peditor = gconf_peditor_new
|
|
(key,
|
|
(GConfClientNotifyFunc) peditor_numeric_range_value_changed,
|
|
changeset,
|
|
G_OBJECT (adjustment),
|
|
first_property_name,
|
|
var_args, NULL);
|
|
|
|
va_end (var_args);
|
|
|
|
g_signal_connect_swapped (adjustment, "value_changed",
|
|
(GCallback) peditor_numeric_range_widget_changed, peditor);
|
|
|
|
return peditor;
|
|
}
|
|
|
|
static gboolean
|
|
guard_get_bool (GConfPropertyEditor *peditor, const GConfValue *value)
|
|
{
|
|
if (value->type == GCONF_VALUE_BOOL)
|
|
return gconf_value_get_bool (value);
|
|
else
|
|
{
|
|
GConfPropertyEditorEnumData *data = peditor->p->data;
|
|
int index = peditor_enum_int_from_string (data->enum_type, gconf_value_get_string (value), data->use_nick);
|
|
return (index != data->enum_val_false);
|
|
}
|
|
}
|
|
|
|
static void
|
|
guard_value_changed (GConfPropertyEditor *peditor,
|
|
const gchar *key,
|
|
const GConfValue *value,
|
|
GtkWidget *widget)
|
|
{
|
|
gtk_widget_set_sensitive (widget, guard_get_bool (peditor, value));
|
|
}
|
|
|
|
void
|
|
gconf_peditor_widget_set_guard (GConfPropertyEditor *peditor,
|
|
GtkWidget *widget)
|
|
{
|
|
GConfClient *client;
|
|
GConfValue *value;
|
|
|
|
g_return_if_fail (peditor != NULL);
|
|
g_return_if_fail (IS_GCONF_PROPERTY_EDITOR (peditor));
|
|
g_return_if_fail (widget != NULL);
|
|
g_return_if_fail (GTK_IS_WIDGET (widget));
|
|
|
|
client = gconf_client_get_default ();
|
|
|
|
value = gconf_client_get (client, peditor->p->key, NULL);
|
|
|
|
if (value) {
|
|
gtk_widget_set_sensitive (widget, guard_get_bool (peditor, value));
|
|
gconf_value_free (value);
|
|
} else {
|
|
g_warning ("NULL GConf value: %s: possibly incomplete setup", peditor->p->key);
|
|
}
|
|
|
|
g_signal_connect (G_OBJECT (peditor), "value-changed", (GCallback) guard_value_changed, widget);
|
|
}
|
|
|
|
GConfValue *
|
|
gconf_value_int_to_float (GConfPropertyEditor *ignored, const GConfValue *value)
|
|
{
|
|
GConfValue *new_value;
|
|
|
|
new_value = gconf_value_new (GCONF_VALUE_FLOAT);
|
|
gconf_value_set_float (new_value, gconf_value_get_int (value));
|
|
return new_value;
|
|
}
|
|
|
|
GConfValue *
|
|
gconf_value_float_to_int (GConfPropertyEditor *ignored, const GConfValue *value)
|
|
{
|
|
GConfValue *new_value;
|
|
|
|
new_value = gconf_value_new (GCONF_VALUE_INT);
|
|
gconf_value_set_int (new_value, gconf_value_get_float (value));
|
|
return new_value;
|
|
}
|
|
|
|
static gint
|
|
peditor_font_get_size (const gchar *font_str)
|
|
{
|
|
PangoFontDescription *desc;
|
|
int size;
|
|
|
|
g_return_val_if_fail (font_str != NULL, -1);
|
|
|
|
desc = pango_font_description_from_string (font_str);
|
|
size = pango_font_description_get_size (desc);
|
|
pango_font_description_free (desc);
|
|
|
|
return size / PANGO_SCALE;
|
|
}
|
|
|
|
static gchar*
|
|
peditor_font_get_name (const gchar *font_str)
|
|
{
|
|
PangoFontDescription *desc;
|
|
gchar *name;
|
|
|
|
g_return_val_if_fail (font_str != NULL, NULL);
|
|
|
|
desc = pango_font_description_from_string (font_str);
|
|
pango_font_description_unset_fields (desc, PANGO_FONT_MASK_SIZE);
|
|
name = pango_font_description_to_string (desc);
|
|
pango_font_description_free (desc);
|
|
|
|
return name;
|
|
}
|
|
|
|
static void
|
|
peditor_font_merge_setting (GnomeFontPicker *font_picker, GConfValue *value, GConfPEditorFontType font_type)
|
|
{
|
|
PangoFontDescription *desc;
|
|
gchar *font_str;
|
|
|
|
g_return_if_fail (GNOME_IS_FONT_PICKER (font_picker));
|
|
g_return_if_fail (value != NULL);
|
|
|
|
|
|
desc = pango_font_description_from_string (gnome_font_picker_get_font_name (font_picker));
|
|
|
|
if (font_type == PEDITOR_FONT_SIZE)
|
|
{
|
|
pango_font_description_set_size (desc, gconf_value_get_int (value) * PANGO_SCALE);
|
|
}
|
|
else
|
|
{
|
|
PangoFontDescription *new_desc;
|
|
new_desc = pango_font_description_from_string (gconf_value_get_string (value));
|
|
if (font_type == PEDITOR_FONT_NAME)
|
|
pango_font_description_set_size (new_desc, pango_font_description_get_size (desc));
|
|
pango_font_description_free (desc);
|
|
desc = new_desc;
|
|
}
|
|
|
|
font_str = pango_font_description_to_string (desc);
|
|
g_object_set (G_OBJECT (font_picker),
|
|
"font_name", font_str,
|
|
"label-font-size", pango_font_description_get_size (desc) / PANGO_SCALE,
|
|
NULL);
|
|
g_free (font_str);
|
|
pango_font_description_free (desc);
|
|
}
|
|
|
|
static void
|
|
peditor_font_value_changed (GConfClient *client,
|
|
guint cnxn_id,
|
|
GConfEntry *entry,
|
|
GConfPropertyEditor *peditor)
|
|
{
|
|
GConfValue *value, *value_wid;
|
|
GConfPEditorFontType font_type;
|
|
|
|
if (peditor->p->changeset != NULL)
|
|
gconf_change_set_remove (peditor->p->changeset, peditor->p->key);
|
|
|
|
font_type = GPOINTER_TO_UINT (peditor->p->data);
|
|
value = gconf_entry_get_value (entry);
|
|
|
|
if (value != NULL) {
|
|
value_wid = peditor->p->conv_to_widget_cb (peditor, value);
|
|
peditor_font_merge_setting (GNOME_FONT_PICKER (peditor->p->ui_control), value_wid, font_type);
|
|
gconf_value_free (value_wid);
|
|
}
|
|
}
|
|
|
|
static void
|
|
peditor_font_widget_changed (GConfPropertyEditor *peditor,
|
|
gchar *font_str,
|
|
GnomeFontPicker *font_picker)
|
|
{
|
|
GConfValue *value, *value_wid = NULL;
|
|
GConfPEditorFontType font_type;
|
|
gchar *font_name;
|
|
int font_size;
|
|
|
|
if (!peditor->p->inited) return;
|
|
|
|
font_type = GPOINTER_TO_UINT (peditor->p->data);
|
|
|
|
font_size = peditor_font_get_size (font_str);
|
|
g_object_set (G_OBJECT (peditor->p->ui_control),
|
|
"label-font-size", font_size,
|
|
NULL);
|
|
|
|
switch (font_type)
|
|
{
|
|
case PEDITOR_FONT_NAME:
|
|
value_wid = gconf_value_new (GCONF_VALUE_STRING);
|
|
font_name = peditor_font_get_name (font_str);
|
|
gconf_value_set_string (value_wid, font_name);
|
|
g_free (font_name);
|
|
break;
|
|
case PEDITOR_FONT_SIZE:
|
|
value_wid = gconf_value_new (GCONF_VALUE_INT);
|
|
gconf_value_set_int (value_wid, font_size);
|
|
break;
|
|
case PEDITOR_FONT_COMBINED:
|
|
value_wid = gconf_value_new (GCONF_VALUE_STRING);
|
|
gconf_value_set_string (value_wid, font_str);
|
|
break;
|
|
}
|
|
|
|
value = peditor->p->conv_from_widget_cb (peditor, value_wid);
|
|
|
|
peditor_set_gconf_value (peditor, peditor->p->key, value);
|
|
g_signal_emit (peditor, peditor_signals[VALUE_CHANGED], 0, peditor->p->key, value);
|
|
|
|
gconf_value_free (value_wid);
|
|
gconf_value_free (value);
|
|
}
|
|
|
|
GObject *
|
|
gconf_peditor_new_font (GConfChangeSet *changeset,
|
|
gchar *key,
|
|
GtkWidget *font_picker,
|
|
GConfPEditorFontType font_type,
|
|
gchar *first_property_name,
|
|
...)
|
|
{
|
|
GObject *peditor;
|
|
va_list var_args;
|
|
|
|
g_return_val_if_fail (key != NULL, NULL);
|
|
g_return_val_if_fail (font_picker != NULL, NULL);
|
|
g_return_val_if_fail (GNOME_IS_FONT_PICKER (font_picker), NULL);
|
|
|
|
va_start (var_args, first_property_name);
|
|
|
|
peditor = gconf_peditor_new
|
|
(key,
|
|
(GConfClientNotifyFunc) peditor_font_value_changed,
|
|
changeset,
|
|
G_OBJECT (font_picker),
|
|
first_property_name,
|
|
var_args,
|
|
"data", GUINT_TO_POINTER (font_type),
|
|
NULL);
|
|
|
|
va_end (var_args);
|
|
|
|
g_signal_connect_swapped (G_OBJECT (font_picker), "font_set",
|
|
(GCallback) peditor_font_widget_changed, peditor);
|
|
|
|
return peditor;
|
|
}
|
|
|
|
static GConfValue*
|
|
peditor_enum_toggle_conv_to_widget (GConfPropertyEditor *peditor,
|
|
const GConfValue *value)
|
|
{
|
|
GConfValue *ret;
|
|
GConfPropertyEditorEnumData *data = peditor->p->data;
|
|
int index;
|
|
|
|
if (value->type == GCONF_VALUE_BOOL)
|
|
return gconf_value_copy (value);
|
|
|
|
ret = gconf_value_new (GCONF_VALUE_BOOL);
|
|
|
|
index = peditor_enum_int_from_string (data->enum_type,
|
|
gconf_value_get_string (value),
|
|
data->use_nick);
|
|
gconf_value_set_bool (ret, (index != data->enum_val_false));
|
|
|
|
return ret;
|
|
}
|
|
|
|
static GConfValue*
|
|
peditor_enum_toggle_conv_from_widget (GConfPropertyEditor *peditor,
|
|
const GConfValue *value)
|
|
{
|
|
GConfValue *ret;
|
|
GConfPropertyEditorEnumData *data = peditor->p->data;
|
|
gchar *str;
|
|
int index;
|
|
|
|
if (value->type == GCONF_VALUE_STRING)
|
|
return gconf_value_copy (value);
|
|
|
|
ret = gconf_value_new (GCONF_VALUE_STRING);
|
|
if (gconf_value_get_bool (value))
|
|
index = data->enum_val_true_fn (peditor, data->enum_val_true_fn_data);
|
|
else
|
|
index = data->enum_val_false;
|
|
|
|
str = peditor_enum_string_from_int (data->enum_type, index, data->use_nick);
|
|
gconf_value_set_string (ret, str);
|
|
g_free (str);
|
|
|
|
return ret;
|
|
}
|
|
|
|
GObject *
|
|
gconf_peditor_new_enum_toggle (GConfChangeSet *changeset,
|
|
gchar *key,
|
|
GtkWidget *checkbox,
|
|
GType enum_type,
|
|
GConfPEditorGetValueFn val_true_fn,
|
|
guint val_false,
|
|
gboolean use_nick,
|
|
gpointer data,
|
|
gchar *first_property_name,
|
|
...)
|
|
{
|
|
GConfPropertyEditor *peditor;
|
|
GConfPropertyEditorEnumData *enum_data;
|
|
va_list var_args;
|
|
|
|
g_return_val_if_fail (key != NULL, NULL);
|
|
g_return_val_if_fail (checkbox != NULL, NULL);
|
|
g_return_val_if_fail (GTK_IS_TOGGLE_BUTTON (checkbox), NULL);
|
|
|
|
enum_data = g_new0 (GConfPropertyEditorEnumData, 1);
|
|
enum_data->enum_type = enum_type;
|
|
enum_data->enum_val_true_fn = val_true_fn;
|
|
enum_data->enum_val_true_fn_data = data;
|
|
enum_data->enum_val_false = val_false;
|
|
enum_data->use_nick = use_nick;
|
|
|
|
va_start (var_args, first_property_name);
|
|
|
|
peditor = GCONF_PROPERTY_EDITOR (
|
|
gconf_peditor_new
|
|
(key,
|
|
(GConfClientNotifyFunc) peditor_boolean_value_changed,
|
|
changeset,
|
|
G_OBJECT (checkbox),
|
|
first_property_name,
|
|
var_args,
|
|
"conv-to-widget-cb",
|
|
peditor_enum_toggle_conv_to_widget,
|
|
"conv-from-widget-cb",
|
|
peditor_enum_toggle_conv_from_widget,
|
|
"data",
|
|
enum_data,
|
|
"data-free-cb",
|
|
g_free,
|
|
NULL));
|
|
|
|
va_end (var_args);
|
|
|
|
g_signal_connect_swapped (G_OBJECT (checkbox), "toggled",
|
|
(GCallback) peditor_boolean_widget_changed, peditor);
|
|
|
|
return G_OBJECT (peditor);
|
|
}
|
|
|
|
gboolean
|
|
peditor_image_set_filename (GConfPropertyEditor *peditor, const gchar *filename)
|
|
{
|
|
GdkPixbuf *pixbuf = NULL;
|
|
GdkPixbuf *scaled;
|
|
GtkImage *image = NULL;
|
|
const int scale = 100;
|
|
gchar *message = NULL;
|
|
GList *l;
|
|
|
|
/* NULL is not valid, however "" is, but not an error (it's
|
|
* the default) */
|
|
g_return_val_if_fail (filename != NULL, FALSE);
|
|
|
|
|
|
if (!g_file_test (filename, G_FILE_TEST_EXISTS))
|
|
{
|
|
message = g_strdup_printf (_("Couldn't find the file '%s'.\n\nPlease make "
|
|
"sure it exists and try again, "
|
|
"or choose a different background picture."),
|
|
filename);
|
|
|
|
}
|
|
else if (!(pixbuf = gdk_pixbuf_new_from_file (filename, NULL)))
|
|
{
|
|
message = g_strdup_printf (_("I don't know how to open the file '%s'.\n"
|
|
"Perhaps it's "
|
|
"a kind of picture that is not yet supported.\n\n"
|
|
"Please select a different picture instead."),
|
|
filename);
|
|
}
|
|
|
|
if (GTK_IS_IMAGE (GTK_BIN (peditor->p->ui_control)->child))
|
|
image = GTK_IMAGE (GTK_BIN (peditor->p->ui_control)->child);
|
|
else
|
|
{
|
|
for (l = gtk_container_get_children (GTK_CONTAINER (GTK_BIN (peditor->p->ui_control)->child)); l != NULL; l = l->next)
|
|
{
|
|
if (GTK_IS_IMAGE (l->data))
|
|
image = GTK_IMAGE (l->data);
|
|
else if (GTK_IS_LABEL (l->data) && message == NULL)
|
|
{
|
|
gchar *base = g_path_get_basename (filename);
|
|
gtk_label_set_text (GTK_LABEL (l->data), base);
|
|
g_free (base);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (message)
|
|
{
|
|
if (peditor->p->inited)
|
|
{
|
|
GtkWidget *box;
|
|
|
|
box = gtk_message_dialog_new (NULL,
|
|
GTK_DIALOG_MODAL,
|
|
GTK_MESSAGE_ERROR,
|
|
GTK_BUTTONS_OK,
|
|
message);
|
|
gtk_dialog_run (GTK_DIALOG (box));
|
|
gtk_widget_destroy (box);
|
|
} else {
|
|
gtk_image_set_from_stock (image, GTK_STOCK_MISSING_IMAGE,
|
|
GTK_ICON_SIZE_BUTTON);
|
|
}
|
|
g_free (message);
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
scaled = preview_file_selection_intelligent_scale (pixbuf,
|
|
scale);
|
|
|
|
gtk_image_set_from_pixbuf (image, scaled);
|
|
g_object_unref (G_OBJECT (pixbuf));
|
|
g_object_unref (G_OBJECT (scaled));
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void
|
|
peditor_image_fsel_ok_cb (GtkFileSelection *fsel, gpointer data)
|
|
{
|
|
GConfValue *value, *value_wid;
|
|
GConfPropertyEditor *peditor;
|
|
const gchar *filename;
|
|
|
|
peditor = g_object_get_data (G_OBJECT (fsel), "peditor");
|
|
|
|
if (!peditor->p->inited)
|
|
return;
|
|
|
|
filename = gtk_file_selection_get_filename (fsel);
|
|
if (!(filename && peditor_image_set_filename (peditor, filename)))
|
|
return;
|
|
|
|
value_wid = gconf_value_new (GCONF_VALUE_STRING);
|
|
gconf_value_set_string (value_wid, gtk_file_selection_get_filename (fsel));
|
|
value = peditor->p->conv_from_widget_cb (peditor, value_wid);
|
|
|
|
peditor_set_gconf_value (peditor, peditor->p->key, value);
|
|
g_signal_emit (peditor, peditor_signals[VALUE_CHANGED], 0, peditor->p->key, value);
|
|
|
|
gconf_value_free (value_wid);
|
|
gconf_value_free (value);
|
|
gtk_widget_destroy (GTK_WIDGET (fsel));
|
|
}
|
|
|
|
void
|
|
peditor_image_clicked_cb (GConfPropertyEditor *peditor, GtkButton *button)
|
|
{
|
|
GConfValue *value = NULL, *value_wid;
|
|
const gchar *filename;
|
|
GtkWidget *fsel;
|
|
|
|
fsel = preview_file_selection_new (_("Please select an image."), TRUE);
|
|
gtk_window_set_modal (GTK_WINDOW (fsel), TRUE);
|
|
|
|
/* need the current filename */
|
|
if (peditor->p->changeset)
|
|
gconf_change_set_check_value (peditor->p->changeset, peditor->p->key, &value);
|
|
|
|
if (value)
|
|
{
|
|
/* the one we got is not a copy */
|
|
value = gconf_value_copy (value);
|
|
}
|
|
else
|
|
{
|
|
GConfClient *client = gconf_client_get_default ();
|
|
value = gconf_client_get (client, peditor->p->key, NULL);
|
|
}
|
|
|
|
value_wid = peditor->p->conv_to_widget_cb (peditor, value);
|
|
filename = gconf_value_get_string (value_wid);
|
|
|
|
if (filename && strcmp (filename, ""))
|
|
gtk_file_selection_set_filename (GTK_FILE_SELECTION (fsel), filename);
|
|
|
|
g_object_set_data (G_OBJECT (fsel), "peditor", peditor);
|
|
|
|
g_signal_connect_swapped (G_OBJECT (GTK_FILE_SELECTION (fsel)->ok_button),
|
|
"clicked",
|
|
(GCallback) peditor_image_fsel_ok_cb,
|
|
fsel);
|
|
|
|
g_signal_connect_swapped (G_OBJECT (GTK_FILE_SELECTION (fsel)->cancel_button),
|
|
"clicked",
|
|
(GCallback) gtk_widget_destroy,
|
|
fsel);
|
|
|
|
if (gtk_grab_get_current ())
|
|
gtk_grab_add (fsel);
|
|
|
|
gtk_widget_show (fsel);
|
|
|
|
gconf_value_free (value);
|
|
gconf_value_free (value_wid);
|
|
}
|
|
|
|
static void
|
|
peditor_image_value_changed (GConfClient *client,
|
|
guint cnxn_id,
|
|
GConfEntry *entry,
|
|
GConfPropertyEditor *peditor)
|
|
{
|
|
GConfValue *value, *value_wid;
|
|
|
|
if (peditor->p->changeset != NULL)
|
|
gconf_change_set_remove (peditor->p->changeset, peditor->p->key);
|
|
|
|
value = gconf_entry_get_value (entry);
|
|
|
|
if (value != NULL) {
|
|
const gchar *filename;
|
|
|
|
value_wid = peditor->p->conv_to_widget_cb (peditor, value);
|
|
filename = gconf_value_get_string (value_wid);
|
|
peditor_image_set_filename (peditor, filename);
|
|
gconf_value_free (value_wid);
|
|
}
|
|
}
|
|
|
|
GObject *
|
|
gconf_peditor_new_image (GConfChangeSet *changeset,
|
|
gchar *key,
|
|
GtkWidget *button,
|
|
gchar *first_property_name,
|
|
...)
|
|
{
|
|
GObject *peditor;
|
|
va_list var_args;
|
|
|
|
g_return_val_if_fail (key != NULL, NULL);
|
|
g_return_val_if_fail (button != NULL, NULL);
|
|
g_return_val_if_fail (GTK_IS_BUTTON (button), NULL);
|
|
|
|
va_start (var_args, first_property_name);
|
|
|
|
peditor = gconf_peditor_new
|
|
(key,
|
|
(GConfClientNotifyFunc) peditor_image_value_changed,
|
|
changeset,
|
|
G_OBJECT (button),
|
|
first_property_name,
|
|
var_args, NULL);
|
|
|
|
va_end (var_args);
|
|
|
|
g_signal_connect_swapped (G_OBJECT (button), "clicked",
|
|
(GCallback) peditor_image_clicked_cb, peditor);
|
|
|
|
return peditor;
|
|
}
|
|
|
|
GObject *
|
|
gconf_peditor_new_select_radio_with_enum (GConfChangeSet *changeset,
|
|
gchar *key,
|
|
GSList *radio_group,
|
|
GType enum_type,
|
|
gboolean use_nick,
|
|
gchar *first_property_name,
|
|
...)
|
|
{
|
|
GConfPropertyEditor *peditor;
|
|
GConfPropertyEditorEnumData *enum_data;
|
|
GtkRadioButton *first_button;
|
|
GSList *item;
|
|
va_list var_args;
|
|
|
|
g_return_val_if_fail (key != NULL, NULL);
|
|
g_return_val_if_fail (radio_group != NULL, NULL);
|
|
g_return_val_if_fail (radio_group->data != NULL, NULL);
|
|
g_return_val_if_fail (GTK_IS_RADIO_BUTTON (radio_group->data), NULL);
|
|
|
|
enum_data = g_new0 (GConfPropertyEditorEnumData, 1);
|
|
enum_data->enum_type = enum_type;
|
|
enum_data->use_nick = use_nick;
|
|
|
|
first_button = GTK_RADIO_BUTTON (radio_group->data);
|
|
|
|
va_start (var_args, first_property_name);
|
|
|
|
peditor = GCONF_PROPERTY_EDITOR (
|
|
gconf_peditor_new
|
|
(key,
|
|
(GConfClientNotifyFunc) peditor_select_radio_value_changed,
|
|
changeset,
|
|
G_OBJECT (first_button),
|
|
first_property_name,
|
|
var_args,
|
|
"conv-to-widget-cb",
|
|
peditor_enum_conv_to_widget,
|
|
"conv-from-widget-cb",
|
|
peditor_enum_conv_from_widget,
|
|
"data",
|
|
enum_data,
|
|
"data-free-cb",
|
|
g_free,
|
|
NULL));
|
|
|
|
va_end (var_args);
|
|
|
|
for (item = radio_group; item != NULL; item = item->next)
|
|
g_signal_connect_swapped (G_OBJECT (item->data), "toggled",
|
|
(GCallback) peditor_select_radio_widget_changed, peditor);
|
|
|
|
return G_OBJECT (peditor);
|
|
}
|
|
|