Author: kelnos Date: 2008-04-09 05:30:06 +0000 (Wed, 09 Apr 2008) New Revision: 26803
Added: xfconf/trunk/docs/reference/tmpl/xfconf-gtk.sgml xfconf/trunk/xfconf-gtk/ xfconf/trunk/xfconf-gtk/Makefile.am xfconf/trunk/xfconf-gtk/libxfconf-gtk-0.pc.in xfconf/trunk/xfconf-gtk/xfconf-gtk.c xfconf/trunk/xfconf-gtk/xfconf-gtk.h Modified: xfconf/trunk/Makefile.am xfconf/trunk/configure.ac.in xfconf/trunk/docs/reference/Makefile.am xfconf/trunk/docs/reference/xfconf-docs.sgml xfconf/trunk/docs/reference/xfconf-sections.txt Log: add first pass at xfconf-gtk convenience library it only supports widgets that implement GtkEditable, but more to come soon Modified: xfconf/trunk/Makefile.am =================================================================== --- xfconf/trunk/Makefile.am 2008-04-09 05:29:53 UTC (rev 26802) +++ xfconf/trunk/Makefile.am 2008-04-09 05:30:06 UTC (rev 26803) @@ -4,6 +4,7 @@ xfconfd \ xfconf-query \ xfsettingsd \ + xfconf-gtk \ po \ docs \ tests Modified: xfconf/trunk/configure.ac.in =================================================================== --- xfconf/trunk/configure.ac.in 2008-04-09 05:29:53 UTC (rev 26802) +++ xfconf/trunk/configure.ac.in 2008-04-09 05:30:06 UTC (rev 26803) @@ -8,6 +8,8 @@ dnl version info m4_define([libxfconf_verinfo], [0:0:0]) m4_define([libxfconf_version_api], [0]) +m4_define([libxfconf_gtk_verinfo], [0:0:0]) +m4_define([libxfconf_gtk_version_api], [0]) m4_define([xfconf_version_major], [0]) m4_define([xfconf_version_minor], [1]) m4_define([xfconf_version_micro], [0]) @@ -52,9 +54,13 @@ XFCONF_VERSION=xfconf_version LIBXFCONF_VERSION_API=libxfconf_version_api LIBXFCONF_VERINFO=libxfconf_verinfo +LIBXFCONF_GTK_VERSION_API=libxfconf_gtk_version_api +LIBXFCONF_GTK_VERINFO=libxfconf_gtk_verinfo AC_SUBST(XFCONF_VERSION) AC_SUBST(LIBXFCONF_VERSION_API) AC_SUBST(LIBXFCONF_VERINFO) +AC_SUBST(LIBXFCONF_GTK_VERSION_API) +AC_SUBST(LIBXFCONF_GTK_VERINFO) dnl Check for i18n support XDT_I18N([EMAIL PROTECTED]@]) @@ -72,13 +78,22 @@ dnl make xsettings daemon optional (so gtk dep is optional) AC_ARG_ENABLE([xsettings-daemon], [AC_HELP_STRING([--disable-xsettings-daemon], - [Don't build the XSETTINGS daemon])], + [Don't build the XSETTINGS daemon (default=yes)])], [build_xfsettingsd=$enableval], [build_xfsettingsd=yes]) -if test "x$build_xfsettingsd" = "xyes"; then +AM_CONDITIONAL([BUILD_XFSETTINGSD], [test "x$build_xfsettingsd" = "xyes"]) + +dnl make xfconf-gtk lib optional (so gtk dep is optional) +AC_ARG_ENABLE([xfconf-gtk], + [AC_HELP_STRING([--disable-xfconf-gtk], + [Don't build xfconf-gtk convenience library (default=yes)])], + [build_xfconf_gtk=$enableval], + [build_xfconf_gtk=yes]) +AM_CONDITIONAL([BUILD_XFCONF_GTK], [test "x$build_xfconf_gtk" = "xyes"]) + +if test "x$build_xfsettingsd" = "xyes" -o "x$build_xfconf_gtk" = "xyes"; then XDT_CHECK_PACKAGE([GTK], [gtk+-2.0], [2.10.0]) fi -AM_CONDITIONAL([BUILD_XFSETTINGSD], [test "x$build_xfsettingsd" = "xyes"]) dnl check alignment for struct returns AC_DEFUN([BT_GLIB_CHECK_ALIGNOF], @@ -176,6 +191,8 @@ tests/Makefile xfconf/Makefile xfconf/libxfconf-0.pc +xfconf-gtk/Makefile +xfconf-gtk/libxfconf-gtk-0.pc xfconf-query/Makefile xfconfd/Makefile xfsettingsd/Makefile Modified: xfconf/trunk/docs/reference/Makefile.am =================================================================== --- xfconf/trunk/docs/reference/Makefile.am 2008-04-09 05:29:53 UTC (rev 26802) +++ xfconf/trunk/docs/reference/Makefile.am 2008-04-09 05:30:06 UTC (rev 26803) @@ -23,10 +23,12 @@ # Used for dependencies HFILE_GLOB = \ $(top_srcdir)/xfconf/*.h \ - $(top_srcdir)/xfconfd/*.h + $(top_srcdir)/xfconfd/*.h \ + $(top_srcdir)/xfconf-gtk/*.h CFILE_GLOB = \ $(top_srcdir)/xfconf/*.c \ $(top_srcdir)/xfconfd/*.c \ + $(top_srcdir)/xfconf-gtk/*.c \ $(top_srcdir)/common/xfconf-errors.c # Header files to ignore when scanning @@ -62,6 +64,7 @@ GTKDOC_LIBS = \ $(top_builddir)/xfconf/libxfconf-$(LIBXFCONF_VERSION_API).la \ + $(top_builddir)/xfconf-gtk/libxfconf-gtk-$(LIBXFCONF_GTK_VERSION_API).la \ $(top_builddir)/xfconfd/xfconfd-xfconf-backend.o include $(top_srcdir)/gtk-doc.make Added: xfconf/trunk/docs/reference/tmpl/xfconf-gtk.sgml =================================================================== --- xfconf/trunk/docs/reference/tmpl/xfconf-gtk.sgml (rev 0) +++ xfconf/trunk/docs/reference/tmpl/xfconf-gtk.sgml 2008-04-09 05:30:06 UTC (rev 26803) @@ -0,0 +1,47 @@ +<!-- ##### SECTION Title ##### --> +Xfconf-Gtk Library + +<!-- ##### SECTION Short_Description ##### --> +Xfconf Gtk widget binding convenience library + +<!-- ##### SECTION Long_Description ##### --> +<para> +Often applications will have configuration dialogs that allow users +to modify settings that are retrieved from and stored to an Xfconf +configuration store. This library makes creating configuration dialogs +a breeze by allowing developers to bind a normal Gtk widget (such as a +GtkEntry or GtkSpinButton) to an Xfconf channel and property string. +The Gtk widget is automatically populated with the current value in +Xfconf, and if that value changes, the widget will be automatically +updated. If the Gtk widget is editable and the user edits the value +in the widget, the binding will also automatically set the new value +in the Xfconf store. +</para> + +<!-- ##### SECTION See_Also ##### --> +<para> + +</para> + +<!-- ##### SECTION Stability_Level ##### --> + + +<!-- ##### FUNCTION xfconf_gtk_widget_bind_property ##### --> +<para> + +</para> + [EMAIL PROTECTED]: [EMAIL PROTECTED]: [EMAIL PROTECTED]: [EMAIL PROTECTED]: + + +<!-- ##### FUNCTION xfconf_gtk_widget_unbind ##### --> +<para> + +</para> + [EMAIL PROTECTED]: + + Modified: xfconf/trunk/docs/reference/xfconf-docs.sgml =================================================================== --- xfconf/trunk/docs/reference/xfconf-docs.sgml 2008-04-09 05:29:53 UTC (rev 26802) +++ xfconf/trunk/docs/reference/xfconf-docs.sgml 2008-04-09 05:30:06 UTC (rev 26803) @@ -22,4 +22,9 @@ <xi:include href="xml/xfconf.xml"/> <xi:include href="xml/xfconf-channel.xml"/> </chapter> + + <chapter> + <title>Xfconf Gtk Convenience Library</title> + <xi:include href="xml/xfconf-gtk.xml"/> + </chapter> </book> Modified: xfconf/trunk/docs/reference/xfconf-sections.txt =================================================================== --- xfconf/trunk/docs/reference/xfconf-sections.txt 2008-04-09 05:29:53 UTC (rev 26802) +++ xfconf/trunk/docs/reference/xfconf-sections.txt 2008-04-09 05:30:06 UTC (rev 26803) @@ -83,3 +83,9 @@ xfconf_g_value_set_int16 xfconf_g_value_set_uint16 </SECTION> + +<SECTION> +<FILE>xfconf-gtk</FILE> +xfconf_gtk_widget_bind_property +xfconf_gtk_widget_unbind +</SECTION> Added: xfconf/trunk/xfconf-gtk/Makefile.am =================================================================== --- xfconf/trunk/xfconf-gtk/Makefile.am (rev 0) +++ xfconf/trunk/xfconf-gtk/Makefile.am 2008-04-09 05:30:06 UTC (rev 26803) @@ -0,0 +1,41 @@ +if BUILD_XFCONF_GTK + +lib_LTLIBRARIES = libxfconf-gtk-0.la + +libxfconfgtkincludedir = $(includedir)/xfce4/xfconf-gtk-$(LIBXFCONF_GTK_VERSION_API)/xfconf-gtk +libxfconfgtkinclude_HEADERS = \ + xfconf-gtk.h + +libxfconf_gtk_0_la_SOURCES = \ + $(libxfconfgtkinclude_HEADERS) \ + xfconf-gtk.c + +libxfconf_gtk_0_la_CFLAGS = \ + -I$(top_srcdir) \ + -I$(top_srcdir)/common \ + -DLIBXFCONF_COMPILATION \ + -DLIBXFCONF_GTK_COMPILATION \ + -DG_LOG_DOMAIN=\"xfconf-gtk\" \ + $(GTK_CFLAGS) + +libxfconf_gtk_0_la_LDFLAGS = \ + -export-dynamic \ + -version-info $(LIBXFCONF_GTK_VERINFO) \ + -export-symbols-regex "^[^_].*" \ + -no-undefined + +libxfconf_gtk_0_la_LIBADD = \ + $(top_builddir)/common/libxfconf-gvaluefuncs.la \ + $(top_builddir)/xfconf/libxfconf-$(LIBXFCONF_VERSION_API).la \ + $(GTK_LIBS) + +libxfconf_gtk_0_la_DEPENDENCIES = \ + $(top_builddir)/xfconf/libxfconf-$(LIBXFCONF_VERSION_API).la + +pkgconfigdir = $(libdir)/pkgconfig +pkgconfig_DATA = libxfconf-gtk-$(LIBXFCONF_GTK_VERSION_API).pc + +endif + +EXTRA_DIST = \ + libxfconf-gtk-$(LIBXFCONF_GTK_VERSION_API).pc.in Added: xfconf/trunk/xfconf-gtk/libxfconf-gtk-0.pc.in =================================================================== --- xfconf/trunk/xfconf-gtk/libxfconf-gtk-0.pc.in (rev 0) +++ xfconf/trunk/xfconf-gtk/libxfconf-gtk-0.pc.in 2008-04-09 05:30:06 UTC (rev 26803) @@ -0,0 +1,13 @@ [EMAIL PROTECTED]@ [EMAIL PROTECTED]@ [EMAIL PROTECTED]@ [EMAIL PROTECTED]@ + [EMAIL PROTECTED]@ + +Name: @PACKAGE_TARNAME@ +Description: Xfconf Gtk convenience library for Xfce +Requires: [EMAIL PROTECTED]@ gtk+-2.0 +Version: @PACKAGE_VERSION@ +Libs: -L${libdir} -lxfconf-gtk-${libxfconf_gtk_api_version} +Cflags: -I${includedir}/xfce4/xfconf-gtk-${libxfconf_gtk_api_version} Added: xfconf/trunk/xfconf-gtk/xfconf-gtk.c =================================================================== --- xfconf/trunk/xfconf-gtk/xfconf-gtk.c (rev 0) +++ xfconf/trunk/xfconf-gtk/xfconf-gtk.c 2008-04-09 05:30:06 UTC (rev 26803) @@ -0,0 +1,271 @@ +/* + * xfconf + * + * Copyright (c) 2007 Brian Tarricone <[EMAIL PROTECTED]> + * + * 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; version 2 of the License ONLY. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#ifdef HAVE_STRING_H +#include <string.h> +#endif + +#ifdef GETTEXT_PACKAGE +#include <glib/gi18n-lib.h> +#else +#include <glib/gi18n.h> +#endif + +#include "xfconf-gtk.h" +#include "xfconf-gvaluefuncs.h" + +typedef struct +{ + GtkWidget *widget; + XfconfChannel *channel; + gchar *property; + GType property_type; + GCallback xfconf_callback; + GCallback gtk_callback; +} XfconfGtkBinding; + + +static void +xfconf_gtk_channel_freed(gpointer data, + GObject *where_the_object_was) +{ + XfconfGtkBinding *binding = data; + binding->channel = NULL; + g_object_set_data(G_OBJECT(binding->widget), "--xfconf-gtk-binding", + NULL); +} + +static void +xfconf_gtk_binding_free(XfconfGtkBinding *binding) +{ + if(binding->channel) { + g_signal_handlers_disconnect_by_func(G_OBJECT(binding->channel), + binding->xfconf_callback, + binding); + g_object_weak_unref(G_OBJECT(binding->channel), + xfconf_gtk_channel_freed, binding); + } + + if(binding->widget) { + g_signal_handlers_disconnect_by_func(G_OBJECT(binding->widget), + binding->gtk_callback, + binding); + } + + g_free(binding->property); + g_free(binding); +} + + + +static gchar * +xfconf_gtk_string_from_gvalue(GValue *val) +{ + g_return_val_if_fail(val && G_VALUE_TYPE(val), NULL); + + switch(G_VALUE_TYPE(val)) { + case G_TYPE_STRING: + return g_value_dup_string(val); + case G_TYPE_UCHAR: + return g_strdup_printf("%u", (guint)g_value_get_uchar(val)); + case G_TYPE_CHAR: + return g_strdup_printf("%d", (gint)g_value_get_char(val)); + case G_TYPE_UINT: + return g_strdup_printf("%u", g_value_get_uint(val)); + case G_TYPE_INT: + return g_strdup_printf("%d", g_value_get_int(val)); + case G_TYPE_UINT64: + return g_strdup_printf("%" G_GUINT64_FORMAT, + g_value_get_uint64(val)); + case G_TYPE_INT64: + return g_strdup_printf("%" G_GINT64_FORMAT, + g_value_get_int64(val)); + case G_TYPE_FLOAT: + return g_strdup_printf("%f", (gdouble)g_value_get_float(val)); + case G_TYPE_DOUBLE: + return g_strdup_printf("%f", g_value_get_double(val)); + case G_TYPE_BOOLEAN: + return g_strdup(g_value_get_boolean(val) ? _("true") + : _("false")); + default: + if(G_VALUE_TYPE(val) == XFCONF_TYPE_UINT16) { + return g_strdup_printf("%u", + (guint)xfconf_g_value_get_uint16(val)); + } else if(G_VALUE_TYPE(val) == XFCONF_TYPE_INT16) { + return g_strdup_printf("%d", + (gint)xfconf_g_value_get_int16(val)); + } + break; + } + + g_warning("Unable to convert GValue to string"); + return NULL; +} + +static gboolean +xfconf_gtk_update_property_from_string(XfconfGtkBinding *binding, + const gchar *value) +{ + gboolean ret = FALSE; + GValue val = { 0, }; + + g_value_init(&val, binding->property_type); + + if(_xfconf_gvalue_from_string(&val, value)) { + ret = xfconf_channel_set_property(binding->channel, + binding->property, + &val); + } else { + g_warning("Unable to convert string \"%s\" to GType \"%s\"", + value, G_VALUE_TYPE_NAME(&val)); + } + + g_value_unset(&val); + + return ret; +} + +static void +xfconf_gtk_editable_binding(XfconfChannel *channel, + const gchar *property, + gpointer user_data) +{ + XfconfGtkBinding *binding = user_data; + GValue val = { 0, }; + gchar *cur_val, *new_val; + gint strpos = 0; + + if(!xfconf_channel_get_property(channel, property, &val)) + return; + + new_val = xfconf_gtk_string_from_gvalue(&val); + g_value_unset(&val); + if(!new_val) + return; + + cur_val = gtk_editable_get_chars(GTK_EDITABLE(binding->widget), 0, -1); + if(!strcmp(cur_val, new_val)) { + g_free(cur_val); + g_free(new_val); + return; + } + g_free(cur_val); + + g_signal_handlers_block_by_func(G_OBJECT(binding->widget), + binding->gtk_callback, binding); + + gtk_editable_delete_text(GTK_EDITABLE(binding->widget), 0, -1); + gtk_editable_insert_text(GTK_EDITABLE(binding->widget), new_val, + strlen(new_val), &strpos); + + g_signal_handlers_unblock_by_func(G_OBJECT(binding->widget), + binding->gtk_callback, binding); + + g_free(new_val); +} + +static void +xfconf_gtk_editable_changed(GtkEditable *editable, + gpointer user_data) +{ + XfconfGtkBinding *binding = user_data; + gchar *str; + + str = gtk_editable_get_chars(editable, 0, -1); + xfconf_gtk_update_property_from_string(binding, str); + g_free(str); +} + + + +/** + * xfconf_gtk_widget_bind_property: + * @widget: A #GtkWidget. + * @channel: An #XfconfChannel. + * @property: A string property name. + * @property_type: The #GType of @property. + * + * Binds @widget to @property on @channel such that @widget will + * always display the value of @property, even if that value changes + * via any other means. If @widget is editable, the binding will also + * cause @property to be updated in the Xfconf configuration store. + * + * Note that not all types of #GtkWidget are supported. Specifically, + * the following widgets are supported: + * FIXME: list widgets + **/ +void +xfconf_gtk_widget_bind_property(GtkWidget *widget, + XfconfChannel *channel, + const gchar *property, + GType property_type) +{ + XfconfGtkBinding *binding; + + g_return_if_fail(GTK_IS_WIDGET(widget) && XFCONF_IS_CHANNEL(channel) + && property && *property); + + if(GTK_IS_EDITABLE(widget)) { + binding = g_new0(XfconfGtkBinding, 1); + + binding->widget = widget; + binding->channel = channel; + binding->property = g_strdup(property); + binding->property_type = property_type; + binding->xfconf_callback = G_CALLBACK(xfconf_gtk_editable_binding); + binding->gtk_callback = G_CALLBACK(xfconf_gtk_editable_changed); + + /* set initial entry value */ + xfconf_gtk_editable_binding(channel, property, binding); + + g_signal_connect(G_OBJECT(widget), "changed", + binding->gtk_callback, binding); + } else { + g_warning("GtkWidget type %s cannot be bound to an xfconf property", + G_OBJECT_TYPE_NAME(widget)); + return; + } + + g_signal_connect(G_OBJECT(channel), "property-changed", + binding->xfconf_callback, binding); + + g_object_set_data_full(G_OBJECT(widget), "--xfconf-gtk-binding", + binding, + (GDestroyNotify)xfconf_gtk_binding_free); + + g_object_weak_ref(G_OBJECT(channel), xfconf_gtk_channel_freed, + binding); +} + +/** + * xfconf_gtk_widget_unbind: + * @widget: A #GtkWidget. + * + * Causes a widget previously bound to an Xfconf property + * (via xfconf_gtk_widget_bind_property()) to no longer be bound. + **/ +void +xfconf_gtk_widget_unbind(GtkWidget *widget) +{ + g_object_set_data(G_OBJECT(widget), "--xfconf-gtk-binding", NULL); +} Added: xfconf/trunk/xfconf-gtk/xfconf-gtk.h =================================================================== --- xfconf/trunk/xfconf-gtk/xfconf-gtk.h (rev 0) +++ xfconf/trunk/xfconf-gtk/xfconf-gtk.h 2008-04-09 05:30:06 UTC (rev 26803) @@ -0,0 +1,37 @@ +/* + * xfconf-gtk + * + * Copyright (c) 2008 Brian Tarricone <[EMAIL PROTECTED]> + * + * 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; version 2 of the License ONLY. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef __XFCONF_GTK_H__ +#define __XFCONF_GTK_H__ + +#include <xfconf/xfconf.h> +#include <gtk/gtk.h> + +G_BEGIN_DECLS + +void xfconf_gtk_widget_bind_property(GtkWidget *widget, + XfconfChannel *channel, + const gchar *property, + GType property_type); + +void xfconf_gtk_widget_unbind(GtkWidget *widget); + +G_END_DECLS + +#endif /* __XFCONF_GTK_H__ */ _______________________________________________ Xfce4-commits mailing list Xfce4-commits@xfce.org http://foo-projects.org/mailman/listinfo/xfce4-commits