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

Reply via email to