GNOME 2.0 port. Changes too numerous to mention.

Removed bonobo-conf support entirely. Added simple GConf-based
property editors. These will be replaced by PonG when that gets
ported.
This commit is contained in:
Bradford Hovinen (Gdict maintainer) 2001-11-10 20:52:31 +00:00
parent 467b92037d
commit d3133da76a
9 changed files with 735 additions and 336 deletions

View file

@ -18,13 +18,4 @@
<oaf_attribute name="name" type="string" value="@SHORT_CAPPLET_NAME@ capplet"/>
</oaf_server>
<oaf_server iid="OAFIID:Bonobo_Listener_Config_@SHORT_CAPPLET_NAME@" type="factory"
location="OAFIID:Bonobo_@SHORT_CAPPLET_NAME@_properties_Factory">
<oaf_attribute name="repo_ids" type="stringv">
<item value="IDL:Bonobo/Listener:1.0"/>
<item value="IDL:Bonobo/Unknown:1.0"/>
</oaf_attribute>
<oaf_attribute name="name" type="string" value="Listener for changes to @SHORT_CAPPLET_NAME@ properties"/>
</oaf_server>
</oaf_info>

View file

@ -1,3 +1,12 @@
2001-11-03 Bradford Hovinen <hovinen@ximian.com>
* Makefile.am (libcommon_a_SOURCES): Added gconf-property-editor.[ch]
2001-10-27 Bradford Hovinen <hovinen@ximian.com>
* capplet-util.c (get_default_moniker): Switch to gconf: moniker
(capplet_init): Remove legacy file hack
2001-10-18 Bradford Hovinen <hovinen@ximian.com>
* Bonobo_Control_Capplet_generic.oaf.in: Update listener name

View file

@ -12,4 +12,5 @@ noinst_LIBRARIES = libcommon.a
libcommon_a_SOURCES = \
capplet-util.c capplet-util.h \
bonobo-property-editor-range.c bonobo-property-editor-range.h
gconf-property-editor.c gconf-property-editor.h \
gconf-property-editor-marshal.c gconf-property-editor-marshal.h

View file

@ -36,10 +36,9 @@
static CreateDialogFn create_dialog_cb = NULL;
static ApplySettingsFn apply_settings_cb = NULL;
static SetupPropertyEditorsFn setup_cb = NULL;
static SetupPropertyEditorsFn setup_property_editors_cb = NULL;
static BonoboListener *listener = NULL;
static Bonobo_EventSource_ListenerId listener_id;
static GConfChangeSet *changeset;
/* apply_cb
*
@ -50,120 +49,21 @@ static Bonobo_EventSource_ListenerId listener_id;
static void
apply_cb (BonoboPropertyControl *pc, Bonobo_PropertyControl_Action action)
{
BonoboPropertyFrame *pf;
Bonobo_ConfigDatabase db;
CORBA_Environment ev;
if (action == Bonobo_PropertyControl_APPLY) {
CORBA_exception_init (&ev);
pf = gtk_object_get_data (GTK_OBJECT (pc), "property-frame");
db = gtk_object_get_data (GTK_OBJECT (pf), "config-database");
bonobo_pbproxy_update (pf->proxy);
Bonobo_ConfigDatabase_sync (db, &ev);
CORBA_exception_free (&ev);
}
if (action == Bonobo_PropertyControl_APPLY)
gconf_engine_commit_change_set (gconf_engine_get_default (),
changeset, TRUE, NULL);
}
/* changed_cb
/* properties_changed_cb
*
* Callback issued when a setting in the ConfigDatabase changes.
* Callback issued when some setting has changed
*/
static void
changed_cb (BonoboListener *listener,
gchar *event_name,
CORBA_any *any,
CORBA_Environment *ev,
Bonobo_ConfigDatabase db)
properties_changed_cb (GConfEngine *engine, guint cnxn_id, GConfEntry *entry, gpointer user_data)
{
if (apply_settings_cb != NULL)
apply_settings_cb (db);
}
/* get_moniker_cb
*
* Callback issued to retrieve the name of the moniker being used. This function
* is just a formality.
*/
static void
get_moniker_cb (BonoboPropertyBag *bag, BonoboArg *arg, guint arg_id,
CORBA_Environment *ev, BonoboControl *control)
{
BONOBO_ARG_SET_STRING (arg, gtk_object_get_data (GTK_OBJECT (control), "moniker"));
}
/* pf_destroy_cb
*
* Callback issued when the property frame is destroyed. Ensures that the
* configuration database is properly unrefed
*/
static void
pf_destroy_cb (BonoboPropertyFrame *pf, Bonobo_ConfigDatabase db)
{
bonobo_object_release_unref (db, NULL);
}
/* set_moniker_cb
*
* Callback issued when the name of the moniker to be used is set. This function
* does most of the dirty work -- creating the property editors that connect
* properties to the dialog box.
*/
static void
set_moniker_cb (BonoboPropertyBag *bag,
BonoboArg *arg,
guint arg_id,
CORBA_Environment *ev,
BonoboControl *control)
{
gchar *moniker;
gchar *full_moniker;
BonoboPropertyFrame *pf;
Bonobo_PropertyBag proxy;
Bonobo_ConfigDatabase db;
gboolean need_setup_cb = TRUE;
if (arg_id != 1) return;
moniker = BONOBO_ARG_GET_STRING (arg);
full_moniker = g_strconcat (moniker, "#config:/main", NULL);
pf = BONOBO_PROPERTY_FRAME (bonobo_control_get_widget (control));
bonobo_property_frame_set_moniker (pf, full_moniker);
g_free (full_moniker);
if (pf->proxy->bag == CORBA_OBJECT_NIL) {
bonobo_exception_set (ev, ex_Bonobo_Property_InvalidValue);
return;
}
proxy = BONOBO_OBJREF (pf->proxy);
db = gtk_object_get_data (GTK_OBJECT (pf), "config-database");
if (db != CORBA_OBJECT_NIL) {
gtk_signal_disconnect_by_func (GTK_OBJECT (pf),
GTK_SIGNAL_FUNC (pf_destroy_cb), db);
bonobo_object_release_unref (db, ev);
need_setup_cb = FALSE;
}
db = bonobo_get_object (moniker, "IDL:Bonobo/ConfigDatabase:1.0", ev);
if (BONOBO_EX (ev) || db == CORBA_OBJECT_NIL)
g_critical ("Could not resolve configuration moniker; will not be able to apply settings");
gtk_object_set_data (GTK_OBJECT (pf), "config-database", db);
gtk_signal_connect (GTK_OBJECT (pf), "destroy",
GTK_SIGNAL_FUNC (pf_destroy_cb), db);
if (setup_cb != NULL && need_setup_cb)
setup_cb (GTK_BIN (pf)->child, proxy);
apply_settings_cb ();
}
/* get_control_cb
@ -176,8 +76,6 @@ set_moniker_cb (BonoboPropertyBag *bag,
static BonoboObject *
get_control_cb (BonoboPropertyControl *property_control, gint page_number)
{
BonoboPropertyBag *pb;
GtkWidget *pf;
BonoboControl *control;
GtkWidget *widget;
@ -186,23 +84,8 @@ get_control_cb (BonoboPropertyControl *property_control, gint page_number)
if (widget == NULL)
return NULL;
pf = bonobo_property_frame_new (NULL, NULL);
gtk_object_set_data (GTK_OBJECT (property_control),
"property-frame", pf);
gtk_container_add (GTK_CONTAINER (pf), widget);
gtk_widget_show_all (pf);
control = bonobo_control_new (pf);
pb = bonobo_property_bag_new ((BonoboPropertyGetFn) get_moniker_cb,
(BonoboPropertySetFn) set_moniker_cb,
control);
bonobo_control_set_properties (control, pb);
bonobo_object_unref (BONOBO_OBJECT (pb));
bonobo_property_bag_add (pb, "moniker", 1, BONOBO_ARG_STRING, NULL,
"Moniker for configuration",
BONOBO_PROPERTY_WRITEABLE);
control = bonobo_control_new (widget);
setup_property_editors_cb (widget, changeset);
bonobo_control_set_automerge (control, TRUE);
@ -215,26 +98,21 @@ get_control_cb (BonoboPropertyControl *property_control, gint page_number)
*/
static BonoboObject *
create_control_cb (BonoboGenericFactory *factory, const gchar *component_id, gchar *default_moniker)
create_control_cb (BonoboGenericFactory *factory, const gchar *component_id)
{
BonoboObject *obj;
BonoboPropertyControl *property_control;
static const gchar *prefix1 = "OAFIID:Bonobo_Control_Capplet_";
static const gchar *prefix2 = "OAFIID:Bonobo_Listener_Config_";
g_message ("%s: Enter", __FUNCTION__);
if (!strncmp (component_id, prefix1, strlen (prefix1))) {
property_control = bonobo_property_control_new
((BonoboPropertyControlGetControlFn) get_control_cb, 1, NULL);
gtk_signal_connect (GTK_OBJECT (property_control), "action",
GTK_SIGNAL_FUNC (apply_cb), NULL);
g_signal_connect (G_OBJECT (property_control), "action",
G_CALLBACK (apply_cb), NULL);
obj = BONOBO_OBJECT (property_control);
}
else if (!strncmp (component_id, prefix2, strlen (prefix2))) {
obj = BONOBO_OBJECT (listener);
bonobo_object_ref (obj);
} else {
g_critical ("Not creating %s", component_id);
obj = NULL;
@ -266,28 +144,6 @@ get_factory_name (const gchar *binary)
return res;
}
/* get_default_moniker
*
* Construct the default moniker for configuration from the binary name
*/
static gchar *
get_default_moniker (const gchar *binary)
{
gchar *s, *tmp, *tmp1, *res;
s = g_strdup (binary);
tmp = strrchr (s, '/');
if (tmp == NULL) tmp = s;
else tmp++;
if ((tmp1 = strstr (tmp, "-control")) != NULL) *tmp1 = '\0';
if ((tmp1 = strstr (tmp, "-capplet")) != NULL) *tmp1 = '\0';
res = g_strconcat ("archive:user-archive#archiverdb:", tmp, NULL);
g_free (s);
return res;
}
/* get_property_name
*
* Get the property name associated with this capplet
@ -324,6 +180,9 @@ get_property_name (const gchar *binary)
static void
setup_session_mgmt (const gchar *binary_name)
{
/* Disabled. I never really understood this code anyway, and I am absolutely
* unclear about how to port it to GNOME 2.0 */
#if 0
GnomeClient *client;
GnomeClientFlags flags;
gint token;
@ -356,93 +215,7 @@ setup_session_mgmt (const gchar *binary_name)
(client, GNOME_RESTART_NEVER);
}
}
}
static gboolean
legacy_is_modified (Bonobo_ConfigDatabase db, const gchar *filename)
{
time_t legacy_val, log_val;
CORBA_Environment ev;
Bonobo_PropertyBag pb;
BonoboArg *arg;
struct stat stbuf;
gchar *realfile;
struct tm *legacy_tm;
gboolean ret;
g_return_val_if_fail (db != CORBA_OBJECT_NIL, FALSE);
CORBA_exception_init (&ev);
pb = Bonobo_Unknown_queryInterface (db, "IDL:Bonobo/PropertyBag:1.0", &ev);
if (pb == CORBA_OBJECT_NIL || BONOBO_EX (&ev))
return FALSE;
arg = bonobo_property_bag_client_get_value_any (pb, "last_modified", &ev);
bonobo_object_release_unref (pb, NULL);
if (arg == NULL || BONOBO_EX (&ev))
return FALSE;
log_val = BONOBO_ARG_GET_GENERAL (arg, TC_ulonglong, CORBA_unsigned_long_long, NULL);
bonobo_arg_release (arg);
if (filename[0] == '/')
realfile = g_strdup (filename);
else
realfile = g_strconcat (g_get_home_dir (),
"/.gnome/",
filename,
NULL);
if (stat (realfile, &stbuf) != 0) {
ret = FALSE;
} else {
legacy_tm = localtime (&stbuf.st_mtime);
legacy_val = mktime (legacy_tm);
ret = (legacy_val > log_val);
}
g_free (realfile);
CORBA_exception_free (&ev);
return ret;
}
static int
add_listener_cb (Bonobo_ConfigDatabase db)
{
Bonobo_EventSource es;
CORBA_Environment ev;
CORBA_exception_init (&ev);
/* We do this manually so that we have access to the resulting listener object */
es = Bonobo_Unknown_queryInterface (db, "IDL:Bonobo/EventSource:1.0", &ev);
if (BONOBO_EX (&ev) || es == CORBA_OBJECT_NIL) {
g_critical ("Cannot get event source interface (%s)",
bonobo_exception_get_text (&ev));
} else {
listener = bonobo_listener_new ((BonoboListenerCallbackFn) changed_cb, db);
listener_id = Bonobo_EventSource_addListenerWithMask (es, BONOBO_OBJREF (listener),
"Bonobo/ConfigDatabase:sync", &ev);
if (BONOBO_EX (&ev) || listener_id == 0) {
g_critical ("Could not add the listener to the event source (%s)",
bonobo_exception_get_text (&ev));
}
bonobo_object_release_unref (es, NULL);
bonobo_running_context_auto_exit_unref (BONOBO_OBJECT (listener));
}
CORBA_exception_free (&ev);
return FALSE;
#endif
}
/* capplet_init -- see documentation in capplet-util.h
@ -451,32 +224,21 @@ add_listener_cb (Bonobo_ConfigDatabase db)
void
capplet_init (int argc,
char **argv,
const gchar **legacy_files,
ApplySettingsFn apply_fn,
CreateDialogFn create_dialog_fn,
SetupPropertyEditorsFn setup_fn,
GetLegacySettingsFn get_legacy_fn)
{
gchar *factory_iid;
gchar *default_moniker;
gboolean needs_legacy = FALSE;
int i;
BonoboGenericFactory *factory;
CORBA_ORB orb;
Bonobo_ConfigDatabase db;
CORBA_Environment ev;
static gboolean apply_only;
static gboolean init_session;
static gboolean get_legacy;
static struct poptOption cap_options[] = {
{ "apply", '\0', POPT_ARG_NONE, &apply_only, 0,
N_("Just apply settings and quit"), NULL },
{ "init-session-settings", '\0', POPT_ARG_NONE, &init_session, 0,
N_("Initialize the session"), NULL },
{ "init-session-settings", '\0', POPT_ARG_NONE, &apply_only, 0,
N_("Just apply settings and quit"), NULL },
{ "get-legacy", '\0', POPT_ARG_NONE, &get_legacy, 0,
N_("Retrieve and store legacy settings"), NULL },
{ NULL, '\0', 0, NULL, 0, NULL, NULL }
@ -485,71 +247,37 @@ capplet_init (int argc,
bindtextdomain (PACKAGE, GNOMELOCALEDIR);
textdomain (PACKAGE);
CORBA_exception_init (&ev);
gnome_program_init (argv[0], VERSION, LIBGNOMEUI_MODULE, argc, argv,
GNOME_PARAM_POPT_TABLE, cap_options,
NULL);
gnomelib_register_popt_table (cap_options, _("Capplet options"));
gnome_init_with_popt_table (argv[0], VERSION, argc, argv,
oaf_popt_options, 0, NULL);
orb = oaf_init (argc, argv);
if (bonobo_init (orb, CORBA_OBJECT_NIL, CORBA_OBJECT_NIL) == FALSE)
if (!bonobo_init (&argc, argv))
g_error ("Cannot initialize bonobo");
default_moniker = get_default_moniker (argv[0]);
db = bonobo_get_object (default_moniker, "IDL:Bonobo/ConfigDatabase:1.0", &ev);
if (db == CORBA_OBJECT_NIL) {
g_critical ("Cannot open configuration database %s", default_moniker);
exit (-1);
}
if (legacy_files && get_legacy_fn && !get_legacy) {
for (i = 0; legacy_files[i] != NULL; i++) {
if (legacy_is_modified (db, legacy_files[i])) {
needs_legacy = TRUE;
break;
}
}
}
if ((apply_only || init_session) && apply_fn != NULL) {
if (apply_only && apply_fn != NULL) {
setup_session_mgmt (argv[0]);
if (needs_legacy)
get_legacy_fn (db);
apply_fn (db);
apply_fn ();
}
else if (get_legacy && get_legacy_fn != NULL) {
setup_session_mgmt (argv[0]);
get_legacy_fn (db);
Bonobo_ConfigDatabase_sync (db, &ev);
get_legacy_fn ();
} else {
setup_session_mgmt (argv[0]);
if (needs_legacy)
get_legacy_fn (db);
create_dialog_cb = create_dialog_fn;
apply_settings_cb = apply_fn;
setup_cb = setup_fn;
setup_property_editors_cb = setup_fn;
factory_iid = get_factory_name (argv[0]);
factory = bonobo_generic_factory_new_multi
(factory_iid, (GnomeFactoryCallback) create_control_cb, default_moniker);
factory = bonobo_generic_factory_new
(factory_iid, (BonoboFactoryCallback) create_control_cb, NULL);
g_free (factory_iid);
bonobo_running_context_auto_exit_unref (BONOBO_OBJECT (factory));
gtk_idle_add ((GtkFunction) add_listener_cb, db);
changeset = gconf_change_set_new ();
bonobo_main ();
if (listener_id != 0) {
bonobo_event_source_client_remove_listener (db, listener_id, &ev);
if (BONOBO_EX (&ev))
g_critical ("Could not remove listener (%s)", bonobo_exception_get_text (&ev));
}
gconf_change_set_unref (changeset);
}
g_free (default_moniker);
bonobo_object_release_unref (db, NULL);
CORBA_exception_free (&ev);
}

View file

@ -26,12 +26,9 @@
#include <gnome.h>
#include <bonobo.h>
/* FIXME: We should really have a single bonobo-conf.h header */
#include <bonobo-conf/bonobo-config-database.h>
#include <bonobo-conf/bonobo-property-editor.h>
#include <bonobo-conf/bonobo-property-frame.h>
#include <bonobo/bonobo-property-control.h>
#include <gconf/gconf.h>
#include <gconf/gconf-changeset.h>
/* Macros to make certain repetitive tasks a bit easier */
@ -51,29 +48,20 @@
val_##type = gnome_config_get_##legacy_type##_with_default (legacy_key, &def); \
\
if (!def) \
bonobo_config_set_##type (db, key, val_##type, NULL);
/* Create a property editor */
#define CREATE_PEDITOR(type, key, widget) \
{ \
BonoboPEditor *ed = BONOBO_PEDITOR \
(bonobo_peditor_##type##_construct (WID (widget))); \
bonobo_peditor_set_property (ed, bag, key, TC_##type, NULL); \
}
gconf_engine_set_##type (engine, key, val_##type, NULL);
/* Callback to apply the settings in the given database */
typedef void (*ApplySettingsFn) (Bonobo_ConfigDatabase db);
typedef void (*ApplySettingsFn) (void);
/* Callback to set up the dialog proper */
typedef GtkWidget *(*CreateDialogFn) (void);
/* Callback to set up property editors for the dialog */
typedef void (*SetupPropertyEditorsFn) (GtkWidget *dialog, Bonobo_PropertyBag bag);
typedef void (*SetupPropertyEditorsFn) (GtkWidget *dialog, GConfChangeSet *changeset);
/* Callback to retrieve legacy settings and store them in the new configuration
* database */
typedef void (*GetLegacySettingsFn) (Bonobo_ConfigDatabase db);
typedef void (*GetLegacySettingsFn) (void);
/* Wrapper function for the entire capplet. This handles all initialization and
* runs the capplet for you. Just supply the appropriate callbacks and your argc
@ -93,7 +81,6 @@ typedef void (*GetLegacySettingsFn) (Bonobo_ConfigDatabase db);
void capplet_init (int argc,
gchar **argv,
const gchar **legacy_files,
ApplySettingsFn apply_fn,
CreateDialogFn create_dialog_fn,
SetupPropertyEditorsFn setup_property_editors_fn,

View file

@ -0,0 +1,41 @@
#include <glib.h>
#include <glib-object.h>
#include "gconf-property-editor-marshal.h"
/* VOID:STRING,POINTER (peditor-marshal.list:25) */
void
gconf_property_editor_marshal_VOID__STRING_POINTER (GClosure *closure,
GValue *return_value,
guint n_param_values,
const GValue *param_values,
gpointer invocation_hint,
gpointer marshal_data)
{
typedef void (*GMarshalFunc_VOID__STRING_POINTER) (gpointer data1,
gpointer arg_1,
gpointer arg_2,
gpointer data2);
register GMarshalFunc_VOID__STRING_POINTER callback;
register GCClosure *cc = (GCClosure*) closure;
register gpointer data1, data2;
g_return_if_fail (n_param_values == 3);
if (G_CCLOSURE_SWAP_DATA (closure))
{
data1 = closure->data;
data2 = g_value_peek_pointer (param_values + 0);
}
else
{
data1 = g_value_peek_pointer (param_values + 0);
data2 = closure->data;
}
callback = (GMarshalFunc_VOID__STRING_POINTER) (marshal_data ? marshal_data : cc->callback);
callback (data1,
(char*) g_value_get_string (param_values + 1),
g_value_get_pointer (param_values + 2),
data2);
}

View file

@ -0,0 +1,15 @@
#include <gobject/gmarshal.h>
G_BEGIN_DECLS
/* VOID:STRING,POINTER (peditor-marshal.list:25) */
extern void gconf_property_editor_marshal_VOID__STRING_POINTER (GClosure *closure,
GValue *return_value,
guint n_param_values,
const GValue *param_values,
gpointer invocation_hint,
gpointer marshal_data);
G_END_DECLS

View file

@ -0,0 +1,545 @@
/* -*- 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 "gconf-property-editor.h"
#include "gconf-property-editor-marshal.h"
enum {
VALUE_CHANGED,
LAST_SIGNAL
};
enum {
PROP_0,
PROP_KEY,
PROP_CALLBACK,
PROP_CHANGESET,
PROP_OBJECT
};
struct _GConfPropertyEditorPrivate
{
gchar *key;
guint handler_id;
GConfChangeSet *changeset;
};
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);
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 void
gconf_property_editor_init (GConfPropertyEditor *gconf_property_editor, GConfPropertyEditorClass *class)
{
gconf_property_editor->p = g_new0 (GConfPropertyEditorPrivate, 1);
}
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);
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_OBJECT,
g_param_spec_object ("object",
_("Destroy notify object"),
_("Destroy the property editor when this object gets destroyed"),
G_TYPE_OBJECT,
G_PARAM_WRITABLE));
g_object_class_install_property
(object_class, PROP_CHANGESET,
g_param_spec_object ("changeset",
_("Change set"),
_("GConf change set containing data to be forwarded to the gconf engine on apply"),
G_TYPE_OBJECT,
G_PARAM_READWRITE));
peditor_signals[VALUE_CHANGED] =
g_signal_new ("value-changed",
0, G_TYPE_FROM_CLASS (object_class),
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);
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;
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;
GConfEngine *engine;
GConfNotifyFunc cb;
GObject *det_obj;
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:
engine = gconf_engine_get_default ();
cb = g_value_get_pointer (value);
peditor->p->handler_id =
gconf_engine_notify_add (engine, peditor->p->key,
cb, peditor, NULL);
break;
case PROP_CHANGESET:
peditor->p->changeset = g_value_get_pointer (value);
break;
case PROP_OBJECT:
det_obj = g_value_get_pointer (value);
g_signal_connect_swapped (det_obj, "destroy",
(GCallback) g_object_unref,
object);
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);
g_free (gconf_property_editor->p);
G_OBJECT_CLASS (parent_class)->finalize (object);
}
static void
peditor_boolean_value_changed (GConfEngine *engine, guint cnxn_id, GConfEntry *entry, GConfPropertyEditor *peditor)
{
GtkToggleButton *tb;
GConfValue *value;
tb = g_object_get_data (G_OBJECT (peditor), "toggle-button");
value = gconf_entry_get_value (entry);
if (gtk_toggle_button_get_active (tb) != gconf_value_get_bool (value))
gtk_toggle_button_set_active (tb, gconf_value_get_bool (value));
}
static void
peditor_boolean_widget_changed (GConfPropertyEditor *peditor, GtkToggleButton *tb)
{
GConfValue *value;
gconf_change_set_set_bool (peditor->p->changeset, peditor->p->key, gtk_toggle_button_get_active (tb));
gconf_change_set_check_value (peditor->p->changeset, peditor->p->key, &value);
g_signal_emit (peditor, peditor_signals[VALUE_CHANGED], 0, peditor->p->key, value);
gconf_value_free (value);
}
GObject *
gconf_peditor_new_boolean (GConfChangeSet *changeset, gchar *key, GtkWidget *checkbox)
{
GObject *peditor;
GConfEngine *engine;
GConfEntry *gconf_entry;
peditor = g_object_new (gconf_property_editor_get_type (),
"key", key,
"callback", peditor_boolean_value_changed,
"changeset", changeset,
"object", checkbox);
g_signal_connect_swapped (G_OBJECT (checkbox), "toggled",
(GCallback) peditor_boolean_widget_changed, peditor);
g_object_set_data (peditor, "toggle-button", checkbox);
engine = gconf_engine_get_default ();
gconf_entry = gconf_engine_get_entry (engine, key, NULL, TRUE, NULL);
peditor_boolean_value_changed (engine, 0, gconf_entry, GCONF_PROPERTY_EDITOR (peditor));
return peditor;
}
static void
peditor_string_value_changed (GConfEngine *engine, guint cnxn_id, GConfEntry *entry, GConfPropertyEditor *peditor)
{
GtkEntry *gtk_entry;
GConfValue *value;
gtk_entry = g_object_get_data (G_OBJECT (peditor), "entry");
value = gconf_entry_get_value (entry);
if (strcmp (gtk_entry_get_text (gtk_entry), gconf_value_get_string (value))) {
gconf_change_set_remove (peditor->p->changeset, peditor->p->key);
gtk_entry_set_text (gtk_entry, gconf_value_get_string (value));
}
}
static void
peditor_string_widget_changed (GConfPropertyEditor *peditor, GtkEntry *entry)
{
GConfValue *value;
gconf_change_set_set_string (peditor->p->changeset, peditor->p->key, gtk_entry_get_text (entry));
gconf_change_set_check_value (peditor->p->changeset, peditor->p->key, &value);
g_signal_emit (peditor, peditor_signals[VALUE_CHANGED], 0, peditor->p->key, value);
gconf_value_free (value);
}
GObject *
gconf_peditor_new_string (GConfChangeSet *changeset, gchar *key, GtkWidget *entry)
{
GObject *peditor;
GConfEngine *engine;
GConfEntry *gconf_entry;
peditor = g_object_new (gconf_property_editor_get_type (),
"key", key,
"callback", peditor_string_value_changed,
"changeset", changeset,
"object", entry);
g_signal_connect_swapped (G_OBJECT (entry), "insert_at_cursor",
(GCallback) peditor_string_widget_changed, peditor);
g_signal_connect_swapped (G_OBJECT (entry), "delete_from_cursor",
(GCallback) peditor_string_widget_changed, peditor);
g_signal_connect_swapped (G_OBJECT (entry), "paste_clipboard",
(GCallback) peditor_string_widget_changed, peditor);
g_object_set_data (peditor, "entry", entry);
engine = gconf_engine_get_default ();
gconf_entry = gconf_engine_get_entry (engine, key, NULL, TRUE, NULL);
peditor_string_value_changed (engine, 0, gconf_entry, GCONF_PROPERTY_EDITOR (peditor));
return peditor;
}
GObject *
gconf_peditor_new_filename (GConfChangeSet *changeset, gchar *key, GtkWidget *file_entry)
{
gconf_peditor_new_string (changeset, key, gnome_file_entry_gtk_entry (GNOME_FILE_ENTRY (file_entry)));
}
static void
peditor_color_value_changed (GConfEngine *engine, guint cnxn_id, GConfEntry *entry, GConfPropertyEditor *peditor)
{
GnomeColorPicker *cp;
GConfValue *value;
GdkColor *color;
guint16 r, g, b, a;
cp = g_object_get_data (G_OBJECT (peditor), "cp");
value = gconf_entry_get_value (entry);
gdk_color_parse (gconf_value_get_string (value), color);
gnome_color_picker_get_i16 (cp, &r, &g, &b, &a);
if (r != color->red || g != color->green || b != color->blue) {
gconf_change_set_remove (peditor->p->changeset, peditor->p->key);
gnome_color_picker_set_i16 (cp, color->red, color->green, color->blue, 65535);
}
}
static void
peditor_color_widget_changed (GConfPropertyEditor *peditor, GnomeColorPicker *cp)
{
gchar *str;
guint8 r, g, b, a;
GConfValue *value;
gnome_color_picker_get_i8 (cp, &r, &g, &b, &a);
str = g_strdup_printf ("#%02x%02x%02x", r, g, b);
gconf_change_set_set_string (peditor->p->changeset, peditor->p->key, str);
gconf_change_set_check_value (peditor->p->changeset, peditor->p->key, &value);
g_signal_emit (peditor, peditor_signals[VALUE_CHANGED], 0, peditor->p->key, value);
gconf_value_free (value);
}
GObject *
gconf_peditor_new_color (GConfChangeSet *changeset, gchar *key, GtkWidget *cp)
{
GObject *peditor;
GConfEngine *engine;
GConfEntry *gconf_entry;
peditor = g_object_new (gconf_property_editor_get_type (),
"key", key,
"callback", peditor_color_value_changed,
"changeset", changeset,
"object", cp);
g_signal_connect_swapped (G_OBJECT (cp), "color_set",
(GCallback) peditor_color_widget_changed, peditor);
g_object_set_data (peditor, "cp", cp);
engine = gconf_engine_get_default ();
gconf_entry = gconf_engine_get_entry (engine, key, NULL, TRUE, NULL);
peditor_color_value_changed (engine, 0, gconf_entry, GCONF_PROPERTY_EDITOR (peditor));
return peditor;
}
static void
peditor_select_menu_value_changed (GConfEngine *engine, guint cnxn_id, GConfEntry *entry, GConfPropertyEditor *peditor)
{
GtkOptionMenu *option_menu;
GtkMenu *menu;
GList *item;
GConfValue *value;
gconf_change_set_remove (peditor->p->changeset, peditor->p->key);
value = gconf_entry_get_value (entry);
option_menu = g_object_get_data (G_OBJECT (peditor), "option-menu");
menu = GTK_MENU (gtk_option_menu_get_menu (option_menu));
item = g_list_nth (GTK_MENU_SHELL (menu)->children, gconf_value_get_int (value));
gtk_menu_item_activate (GTK_MENU_ITEM (item->data));
}
static void
peditor_select_menu_widget_changed (GConfPropertyEditor *peditor, GtkMenuItem *item)
{
GtkOptionMenu *option_menu;
GtkMenu *menu;
gint idx;
GConfValue *value;
option_menu = g_object_get_data (G_OBJECT (peditor), "option-menu");
menu = GTK_MENU (gtk_option_menu_get_menu (option_menu));
idx = g_list_index (GTK_MENU_SHELL (menu)->children, item);
gconf_change_set_set_int (peditor->p->changeset, peditor->p->key, idx);
gconf_change_set_check_value (peditor->p->changeset, peditor->p->key, &value);
g_signal_emit (peditor, peditor_signals[VALUE_CHANGED], 0, peditor->p->key, value);
gconf_value_free (value);
}
GObject *
gconf_peditor_new_select_menu (GConfChangeSet *changeset, gchar *key, GtkWidget *option_menu)
{
GObject *peditor;
GConfEngine *engine;
GConfEntry *gconf_entry;
GtkMenu *menu;
GList *item;
peditor = g_object_new (gconf_property_editor_get_type (),
"key", key,
"callback", peditor_select_menu_value_changed,
"changeset", changeset,
"object", option_menu);
menu = GTK_MENU (gtk_option_menu_get_menu (GTK_OPTION_MENU (option_menu)));
for (item = GTK_MENU_SHELL (menu)->children; item != NULL; item = item->next)
g_signal_connect_swapped (G_OBJECT (item->data), "activate",
(GCallback) peditor_select_menu_widget_changed, peditor);
g_object_set_data (peditor, "option-menu", option_menu);
engine = gconf_engine_get_default ();
gconf_entry = gconf_engine_get_entry (engine, key, NULL, TRUE, NULL);
peditor_select_menu_value_changed (engine, 0, gconf_entry, GCONF_PROPERTY_EDITOR (peditor));
return peditor;
}
static void
peditor_select_radio_value_changed (GConfEngine *engine, guint cnxn_id, GConfEntry *entry, GConfPropertyEditor *peditor)
{
GSList *group;
GConfValue *value;
gconf_change_set_remove (peditor->p->changeset, peditor->p->key);
value = gconf_entry_get_value (entry);
group = g_object_get_data (G_OBJECT (peditor), "group");
group = g_slist_nth (group, gconf_value_get_int (value));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (group->data), TRUE);
}
static void
peditor_select_radio_widget_changed (GConfPropertyEditor *peditor, GtkToggleButton *tb)
{
GSList *group;
gint idx;
GConfValue *value;
group = g_object_get_data (G_OBJECT (peditor), "group");
idx = g_slist_index (group, tb);
gconf_change_set_set_int (peditor->p->changeset, peditor->p->key, idx);
gconf_change_set_check_value (peditor->p->changeset, peditor->p->key, &value);
g_signal_emit (peditor, peditor_signals[VALUE_CHANGED], 0, peditor->p->key, value);
gconf_value_free (value);
}
GObject *
gconf_peditor_new_select_radio (GConfChangeSet *changeset, gchar *key, GSList *radio_group)
{
GObject *peditor;
GConfEngine *engine;
GConfEntry *gconf_entry;
GSList *item;
peditor = g_object_new (gconf_property_editor_get_type (),
"key", key,
"callback", peditor_select_radio_value_changed,
"changeset", changeset,
"object", radio_group);
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);
g_object_set_data (peditor, "group", radio_group);
engine = gconf_engine_get_default ();
gconf_entry = gconf_engine_get_entry (engine, key, NULL, TRUE, NULL);
peditor_select_radio_value_changed (engine, 0, gconf_entry, GCONF_PROPERTY_EDITOR (peditor));
return peditor;
}
static void
guard_value_changed (GConfEngine *engine, guint cnxn_id, GConfEntry *entry, GtkWidget *widget)
{
}
static void
guard_widget_changed (GConfPropertyEditor *peditor, gchar *key, GConfValue *value, GtkWidget *widget)
{
}
void
peditor_widget_set_guard (GConfPropertyEditor *peditor, GtkWidget *widget, gchar *key)
{
}

View file

@ -0,0 +1,82 @@
/* -*- mode: c; style: linux -*- */
/* gconf-property-editor.h
* 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.
*/
#ifndef __GCONF_PROPERTY_EDITOR_H
#define __GCONF_PROPERTY_EDITOR_H
#include <gnome.h>
#include <gconf/gconf.h>
#include <gconf/gconf-changeset.h>
G_BEGIN_DECLS
#define GCONF_PROPERTY_EDITOR(obj) G_TYPE_CHECK_INSTANCE_CAST (obj, gconf_property_editor_get_type (), GConfPropertyEditor)
#define GCONF_PROPERTY_EDITOR_CLASS(klass) G_TYPE_CHECK_CLASS_CAST (klass, gconf_property_editor_get_type (), GConfPropertyEditorClass)
#define IS_GCONF_PROPERTY_EDITOR(obj) G_TYPE_CHECK_INSTANCE_TYPE (obj, gconf_property_editor_get_type ())
typedef struct _GConfPropertyEditor GConfPropertyEditor;
typedef struct _GConfPropertyEditorClass GConfPropertyEditorClass;
typedef struct _GConfPropertyEditorPrivate GConfPropertyEditorPrivate;
struct _GConfPropertyEditor
{
GObject parent;
GConfPropertyEditorPrivate *p;
};
struct _GConfPropertyEditorClass
{
GObjectClass g_object_class;
void (*value_changed) (GConfPropertyEditor *peditor, gchar *key, GConfValue *value);
};
GType gconf_property_editor_get_type (void);
GObject *gconf_peditor_new_boolean (GConfChangeSet *changeset,
gchar *key,
GtkWidget *checkbox);
GObject *gconf_peditor_new_string (GConfChangeSet *changeset,
gchar *key,
GtkWidget *entry);
GObject *gconf_peditor_new_filename (GConfChangeSet *changeset,
gchar *key,
GtkWidget *file_entry);
GObject *gconf_peditor_new_color (GConfChangeSet *changeset,
gchar *key,
GtkWidget *color_entry);
GObject *gconf_peditor_new_select_menu (GConfChangeSet *changeset,
gchar *key,
GtkWidget *option_menu);
GObject *gconf_peditor_new_select_radio (GConfChangeSet *changeset,
gchar *key,
GSList *radio_group);
void gconf_peditor_widget_set_guard (GConfPropertyEditor *peditor,
GtkWidget *widget,
gchar *key);
G_END_DECLS
#endif /* __GCONF_PROPERTY_EDITOR_H */