[nautilus-actions] Define NAIDataFactory interface



commit 667616281188ef4bd0b7994d5f3533d70ef0571e
Author: Pierre Wieser <pwieser trychlos org>
Date:   Mon Feb 15 18:00:27 2010 +0100

    Define NAIDataFactory interface

 ChangeLog                       |    9 +
 src/api/Makefile.am             |    3 +
 src/api/na-idata-factory-enum.h |   98 +++++
 src/api/na-idata-factory-str.h  |  122 ++++++
 src/api/na-idata-factory.h      |  151 ++++++++
 src/core/Makefile.am            |    3 +
 src/core/na-data-factory.c      |  768 +++++++++++++++++++++++++++++++++++++++
 src/core/na-data-factory.h      |   63 ++++
 src/core/na-idata-factory.c     |  171 +++++++++
 9 files changed, 1388 insertions(+), 0 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index f58097a..094485b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,14 @@
 2009-02-15 Pierre Wieser <pwieser trychlos org>
 
+	Define NAIDataFactory interface.
+
+	* src/api/na-idata-factory.h:
+	* src/api/na-idata-factory-enum.h:
+	* src/api/na-idata-factory-str.h:
+	* src/core/na-idata-factory.c:
+	* src/core/na-data-factory.c:
+	* src/core/na-data-factory.h: New files.
+
 	Define NAIIOFactory interface.
 
 	* src/api/na-iio-factory.h:
diff --git a/src/api/Makefile.am b/src/api/Makefile.am
index 3fa71f4..1b49289 100644
--- a/src/api/Makefile.am
+++ b/src/api/Makefile.am
@@ -32,6 +32,9 @@ api_include_HEADERS = \
 	na-extension.h										\
 	\
 	na-dbus.h											\
+	na-idata-factory.h									\
+	na-idata-factory-enum.h								\
+	na-idata-factory-str.h								\
 	na-iio-factory.h									\
 	na-iio-factory-factory.h							\
 	na-iio-provider.h									\
diff --git a/src/api/na-idata-factory-enum.h b/src/api/na-idata-factory-enum.h
new file mode 100644
index 0000000..06dbc39
--- /dev/null
+++ b/src/api/na-idata-factory-enum.h
@@ -0,0 +1,98 @@
+/*
+ * Nautilus Actions
+ * A Nautilus extension which offers configurable context menu actions.
+ *
+ * Copyright (C) 2005 The GNOME Foundation
+ * Copyright (C) 2006, 2007, 2008 Frederic Ruaudel and others (see AUTHORS)
+ * Copyright (C) 2009, 2010 Pierre Wieser and others (see AUTHORS)
+ *
+ * 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 of
+ * the License, 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 Library; see the file COPYING.  If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place,
+ * Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Authors:
+ *   Frederic Ruaudel <grumz grumz net>
+ *   Rodrigo Moya <rodrigo gnome-db org>
+ *   Pierre Wieser <pwieser trychlos org>
+ *   ... and many others (see AUTHORS)
+ */
+
+#ifndef __NAUTILUS_ACTIONS_API_NA_IDATA_FACTORY_ENUM_H__
+#define __NAUTILUS_ACTIONS_API_NA_IDATA_FACTORY_ENUM_H__
+
+#include <glib.h>
+
+/**
+ * SECTION: na_idata_factory
+ * @short_description: Enumeration of all serializable elementary datas.
+ * @include: nautilus-actions/na-idata-factory-enum.h
+ */
+
+G_BEGIN_DECLS
+
+/*
+ * IMPORTANT NOTE
+ * Please note that this enumeration may  be compiled in by extensions.
+ * They must so remain fixed, unless you want see strange effects (e.g.
+ * an extension has been compiled with NADF_TYPE_STRING = 2, while you
+ * have inserted another element, making it to 3 !) - or you know what
+ * you are doing...
+ */
+
+enum {
+	NA_DATA_FACTORY_ID_GROUP = 1,
+	NADF_DATA_ID,
+	NADF_DATA_LABEL,
+	NADF_DATA_PARENT,
+
+	NA_DATA_FACTORY_ITEM_GROUP = 20,
+	NADF_DATA_TOOLTIP,
+	NADF_DATA_ICON,
+	NADF_DATA_DESCRIPTION,
+	NADF_DATA_SUBITEMS,
+	NADF_DATA_SUBITEMS_SLIST,
+	NADF_DATA_ENABLED,
+	NADF_DATA_READONLY,
+	NADF_DATA_PROVIDER,
+	NADF_DATA_PROVIDER_DATA,
+
+	NA_DATA_FACTORY_ACTION_GROUP = 40,
+	NADF_DATA_VERSION,
+	NADF_DATA_TARGET_SELECTION,
+	NADF_DATA_TARGET_BACKGROUND,
+	NADF_DATA_TARGET_TOOLBAR,
+	NADF_DATA_TOOLBAR_LABEL,
+	NADF_DATA_TOOLBAR_SAME_LABEL,
+	NADF_DATA_LAST_ALLOCATED,
+
+	NA_DATA_FACTORY_MENU_GROUP = 60,
+
+	NA_DATA_FACTORY_PROFILE_GROUP = 80,
+	NADF_DATA_PATH,
+	NADF_DATA_PARAMETERS,
+	NADF_DATA_BASENAMES,
+	NADF_DATA_MATCHCASE,
+	NADF_DATA_MIMETYPES,
+	NADF_DATA_ISFILE,
+	NADF_DATA_ISDIR,
+	NADF_DATA_MULTIPLE,
+	NADF_DATA_SCHEMES,
+	NADF_DATA_FOLDERS,
+
+	NA_DATA_FACTORY_CONDITIONS_GROUP = 100,
+};
+
+G_END_DECLS
+
+#endif /* __NAUTILUS_ACTIONS_API_NA_IDATA_FACTORY_ENUM_H__ */
diff --git a/src/api/na-idata-factory-str.h b/src/api/na-idata-factory-str.h
new file mode 100644
index 0000000..03a85ec
--- /dev/null
+++ b/src/api/na-idata-factory-str.h
@@ -0,0 +1,122 @@
+/*
+ * Nautilus Actions
+ * A Nautilus extension which offers configurable context menu actions.
+ *
+ * Copyright (C) 2005 The GNOME Foundation
+ * Copyright (C) 2006, 2007, 2008 Frederic Ruaudel and others (see AUTHORS)
+ * Copyright (C) 2009, 2010 Pierre Wieser and others (see AUTHORS)
+ *
+ * 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 of
+ * the License, 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 Library; see the file COPYING.  If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place,
+ * Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Authors:
+ *   Frederic Ruaudel <grumz grumz net>
+ *   Rodrigo Moya <rodrigo gnome-db org>
+ *   Pierre Wieser <pwieser trychlos org>
+ *   ... and many others (see AUTHORS)
+ */
+
+#ifndef __NAUTILUS_ACTIONS_API_NA_IDATA_FACTORY_STR_H__
+#define __NAUTILUS_ACTIONS_API_NA_IDATA_FACTORY_STR_H__
+
+/**
+ * SECTION: na_idata_factory
+ * @short_description: Data Factory Definitions.
+ * @include: nautilus-actions/na-data-factory-str.h
+ */
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+/**
+ * Elementary data types
+ * Each object data item must be typed as one of these
+ * IIOFactory implementations should provide a primitive for reading
+ * (resp. writing) a value for each of these elementary data types.
+ *
+ * IMPORTANT NOTE
+ * Please note that this enumeration may  be compiled in by extensions.
+ * They must so remain fixed, unless you want see strange effects (e.g.
+ * an extension has been compiled with NADF_TYPE_STRING = 2, while you
+ * have inserted another element, making it to 3 !) - or you know what
+ * you are doing...
+ */
+
+enum {
+	NADF_TYPE_STRING = 1,				/* an ASCII string */
+
+	NADF_TYPE_LOCALE_STRING,			/* a localized UTF-8 string */
+
+	NADF_TYPE_BOOLEAN,					/* a boolean
+										 * can be initialized with "true" or "false" (case insensitive) */
+
+	NADF_TYPE_STRING_LIST,				/* a list of ASCII strings */
+
+	NADF_TYPE_POINTER,					/* a ( void * ) pointer
+										 * should be initialized to NULL */
+
+	NADF_TYPE_UINT,						/* an unsigned integer */
+};
+
+/**
+ * The structure which fully describe an elementary data
+ * Each #NAIDataFactory item definition may include several groups of
+ * this structure
+ */
+typedef struct {
+	guint    id;						/* the id of the object data item
+										 * must only be unique inside of the given group */
+
+	gchar   *name;						/* canonical name, used when getting/setting properties */
+
+	gboolean serializable;				/* whether the data is serializable
+										 * if FALSE, then no attempt will be made to read/write it
+										 * and the data will must be set dynamically */
+
+	gchar   *short_label;				/* short descriptive name, used in GParamSpec */
+
+	gchar   *long_label;				/* long, if not complete, description, used in GParamSpec */
+
+	guint    type;						/* the elementary NADF_TYPE_xxx data type */
+
+	gchar   *default_value;				/* the default to assign when creating a new object
+										 * this default is also displayed in command-line help
+										 * of nautilus-actions-new utility */
+
+	gboolean copyable;					/* whether this data should be automatically copied when
+										 * we are duplicating an object to another
+										 * in all cases, the implementation is always triggered
+										 * by the copy() interface method */
+
+	gboolean comparable;				/* whether this data should be compared when we
+										 * are testing two objects for equality */
+}
+	NadfIdType;
+
+/**
+ * The structure which fully describe a logical group of data
+ * Each #NAIDataFactory item may definition may be built from a list of
+ * these groups
+ */
+typedef struct {
+	guint       idgroup;				/* cf. na-idata-factory-enum.h */
+	NadfIdType *iddef;
+}
+	NadfIdGroup;
+
+G_END_DECLS
+
+#endif /* __NAUTILUS_ACTIONS_API_NA_IDATA_FACTORY_STR_H__ */
diff --git a/src/api/na-idata-factory.h b/src/api/na-idata-factory.h
new file mode 100644
index 0000000..85340e6
--- /dev/null
+++ b/src/api/na-idata-factory.h
@@ -0,0 +1,151 @@
+/*
+ * Nautilus Actions
+ * A Nautilus extension which offers configurable context menu actions.
+ *
+ * Copyright (C) 2005 The GNOME Foundation
+ * Copyright (C) 2006, 2007, 2008 Frederic Ruaudel and others (see AUTHORS)
+ * Copyright (C) 2009, 2010 Pierre Wieser and others (see AUTHORS)
+ *
+ * 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 of
+ * the License, 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 Library; see the file COPYING.  If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place,
+ * Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Authors:
+ *   Frederic Ruaudel <grumz grumz net>
+ *   Rodrigo Moya <rodrigo gnome-db org>
+ *   Pierre Wieser <pwieser trychlos org>
+ *   ... and many others (see AUTHORS)
+ */
+
+#ifndef __NAUTILUS_ACTIONS_API_NA_IDATA_FACTORY_H__
+#define __NAUTILUS_ACTIONS_API_NA_IDATA_FACTORY_H__
+
+/**
+ * SECTION: na_idata_factory
+ * @short_description: #NAIDataFactory interface definition.
+ * @include: nautilus-actions/na-idata_factory.h
+ *
+ * This interface must be implemented by #NAObject-derived objects which
+ * should take advantage of data factory management system.
+ *
+ * A #NAObject which would implement this #NAIDataFactory interface
+ * must meet following conditions:
+ * - must accept an empty constructor
+ *
+ * Nautilus-Actions v 2.30 - API version:  1
+ */
+
+#include "na-idata-factory-enum.h"
+#include "na-idata-factory-str.h"
+#include "na-iio-factory-factory.h"
+
+G_BEGIN_DECLS
+
+#define NA_IDATA_FACTORY_TYPE						( na_idata_factory_get_type())
+#define NA_IDATA_FACTORY( instance )				( G_TYPE_CHECK_INSTANCE_CAST( instance, NA_IDATA_FACTORY_TYPE, NAIDataFactory ))
+#define NA_IS_IDATA_FACTORY( instance )				( G_TYPE_CHECK_INSTANCE_TYPE( instance, NA_IDATA_FACTORY_TYPE ))
+#define NA_IDATA_FACTORY_GET_INTERFACE( instance )	( G_TYPE_INSTANCE_GET_INTERFACE(( instance ), NA_IDATA_FACTORY_TYPE, NAIDataFactoryInterface ))
+
+typedef struct NAIDataFactory                 NAIDataFactory;
+
+typedef struct NAIDataFactoryInterfacePrivate NAIDataFactoryInterfacePrivate;
+
+typedef struct {
+	GTypeInterface                  parent;
+	NAIDataFactoryInterfacePrivate *private;
+
+	/**
+	 * get_version:
+	 * @instance: this #NAIDataFactory instance.
+	 *
+	 * Returns: the version of this interface supported by @instance implementation.
+	 *
+	 * Defaults to 1.
+	 */
+	guint    ( *get_version )( const NAIDataFactory *instance );
+
+	/**
+	 * get_default:
+	 * @instance: this #NAIDataFactory instance.
+	 * @iddef: the #NadfIdType structure which defines the data whose
+	 * default value is searched for.
+	 *
+	 * The @instance may take advantage of this method to setup a default
+	 * value for a specific instance, or even for instances of a class when
+	 * several classes share some elementary data via common #NadfIdGroup.
+	 *
+	 * Returns: a newly allocated string which defines the suitable
+	 * default value, or %NULL.
+	 */
+	gchar *  ( *get_default )( const NAIDataFactory *instance, const NadfIdType *iddef );
+
+	/**
+	 * copy:
+	 * @instance: the target #NAIDataFactory instance.
+	 * @source: the source #NAIDataFactory instance.
+	 *
+	 * This function is triggered when copying one instance to another,
+	 * after all copyable elementary dats have been copied themselves.
+	 * The target @instance may take advantage of this call to do some
+	 * particular copy tasks.
+	 */
+	void     ( *copy )       ( NAIDataFactory *instance, const NAIDataFactory *source );
+
+	/**
+	 * are_equal:
+	 * @a: the first #NAIDataFactory instance.
+	 * @b: the second #NAIDataFactory instance.
+	 *
+	 * Returns: %TRUE if @a is equal to @b.
+	 *
+	 * This function is triggered after all elementary data comparisons
+	 * have been sucessfully made.
+	 */
+	gboolean ( *are_equal )  ( const NAIDataFactory *a, const NAIDataFactory *b );
+
+	/**
+	 * read_done:
+	 * @instance: this #NAIDataFactory instance.
+	 * @reader: the instance which has provided read services.
+	 * @reader_data: the data associated to @reader.
+	 * @messages: a pointer to a #GSList list of strings; the instance
+	 *  may append messages to this list, but shouldn't reinitialize it.
+	 *
+	 * Called when the object has been unserialized.
+	 */
+	void     ( *read_done )  ( NAIDataFactory *instance, const NAIIOFactory *reader, void *reader_data, GSList **messages );
+
+	/**
+	 * write_done:
+	 * @instance: this #NAIDataFactory instance.
+	 * @writer: the instance which has provided writing services.
+	 * @writer_data: the data associated to @writer.
+	 * @messages: a pointer to a #GSList list of strings; the instance
+	 *  may append messages to this list, but shouldn't reinitialize it.
+	 *
+	 * Called when the object has been serialized.
+	 */
+	void     ( *write_done ) ( NAIDataFactory *instance, const NAIIOFactory *writer, void *writer_data, GSList **messages );
+}
+	NAIDataFactoryInterface;
+
+GType  na_idata_factory_get_type( void );
+
+void  *na_idata_factory_get( const NAIDataFactory *object, guint data_id );
+
+void   na_idata_factory_set( NAIDataFactory *object, guint data_id, const void *data );
+
+G_END_DECLS
+
+#endif /* __NAUTILUS_ACTIONS_API_NA_IDATA_FACTORY_H__ */
diff --git a/src/core/Makefile.am b/src/core/Makefile.am
index 68f41e9..2ae418e 100644
--- a/src/core/Makefile.am
+++ b/src/core/Makefile.am
@@ -38,9 +38,12 @@ AM_CPPFLAGS += \
 
 libna_core_la_SOURCES = \
 	na-core-utils.c										\
+	na-data-factory.c									\
+	na-data-factory.h									\
 	na-gconf-monitor.c									\
 	na-gconf-utils.c									\
 	na-iduplicable.c									\
+	na-idata-factory.c									\
 	na-iio-factory.c									\
 	na-iio-provider.c									\
 	na-io-factory.c										\
diff --git a/src/core/na-data-factory.c b/src/core/na-data-factory.c
new file mode 100644
index 0000000..b9375b2
--- /dev/null
+++ b/src/core/na-data-factory.c
@@ -0,0 +1,768 @@
+/*
+ * Nautilus Actions
+ * A Nautilus extension which offers configurable context menu actions.
+ *
+ * Copyright (C) 2005 The GNOME Foundation
+ * Copyright (C) 2006, 2007, 2008 Frederic Ruaudel and others (see AUTHORS)
+ * Copyright (C) 2009, 2010 Pierre Wieser and others (see AUTHORS)
+ *
+ * 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 of
+ * the License, 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 Library; see the file COPYING.  If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place,
+ * Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Authors:
+ *   Frederic Ruaudel <grumz grumz net>
+ *   Rodrigo Moya <rodrigo gnome-db org>
+ *   Pierre Wieser <pwieser trychlos org>
+ *   ... and many others (see AUTHORS)
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdarg.h>
+#include <stdlib.h>
+
+#include <api/na-core-utils.h>
+#include <api/na-iio-factory.h>
+
+#include "na-data-element.h"
+#include "na-data-factory.h"
+#include "na-io-factory.h"
+
+typedef gboolean ( *IdGroupIterFunc )( NadfIdType *iddef, void *user_data );
+
+/* while iterating on read/write item
+ */
+typedef struct {
+	NAIDataFactory *object;
+	NAIIOFactory   *reader;
+	void           *reader_data;
+	GSList        **messages;
+}
+	NadfRWIter;
+
+/* while iterating on set defaults
+ */
+typedef struct {
+	NAIDataFactory *object;
+	gboolean        creation;
+}
+	NadfNewIter;
+
+/* object values are set on a list of this structure
+ */
+typedef struct {
+	NadfIdType    *iddef;
+	NADataElement *element;
+}
+	NadfDataValue;
+
+#define NA_IDATA_FACTORY_PROP_DATA				"na-idata-factory-prop-data"
+
+extern gboolean idata_factory_initialized;		/* defined in na-idata-factory.c */
+extern gboolean idata_factory_finalized;		/* defined in na-idata-factory.c */
+
+static gboolean       define_class_properties_iter( const NadfIdType *iddef, GObjectClass *class );
+static gboolean       data_factory_init_iter( const NadfIdType *iddef, NAIDataFactory *object );
+static gchar         *v_get_default( const NAIDataFactory *object, const NadfIdType *iddef );
+static void           v_copy( NAIDataFactory *target, const NAIDataFactory *source );
+static gboolean       v_are_equal( const NAIDataFactory *a, const NAIDataFactory *b );
+static void           data_factory_read_data( NAIDataFactory *serializable, const NAIIOFactory *reader, void *reader_data, NadfIdGroup *groups, GSList **messages );
+static gboolean       data_factory_read_data_iter( NadfIdType *iddef, NadfRWIter *iter );
+static void           v_read_done( NAIDataFactory *serializable, const NAIIOFactory *reader, void *reader_data, GSList **messages );
+static void           data_factory_write_data( NAIDataFactory *serializable, const NAIIOFactory *writer, void *writer_data, NadfIdGroup *groups, GSList **messages );
+static gboolean       data_factory_write_data_iter( NadfIdType *iddef, NadfRWIter *iter );
+static void           v_write_done( NAIDataFactory *serializable, const NAIIOFactory *reader, void *reader_data, GSList **messages );
+static NADataElement *data_element_from_id( const NAIDataFactory *object, guint data_id );
+static void           iter_on_id_groups( const NadfIdGroup *idgroups, gboolean serializable_only, IdGroupIterFunc pfn, void *user_data );
+static void           free_gvalue( GValue *value, guint type );
+
+/**
+ * na_data_factory_properties:
+ * @class: the #GObjectClass.
+ *
+ * Initializes the serializable properties.
+ */
+void
+na_data_factory_properties( GObjectClass *class )
+{
+	static const gchar *thisfn = "na_data_factory_properties";
+	NadfIdGroup *groups;
+
+	if( idata_factory_initialized && !idata_factory_finalized ){
+
+		g_debug( "%s: class=%p (%s)",
+				thisfn, ( void * ) class, G_OBJECT_CLASS_NAME( class ));
+
+		g_return_if_fail( G_IS_OBJECT_CLASS( class ));
+
+		/* define class properties
+		 */
+		groups = na_io_factory_get_groups( G_OBJECT_CLASS_TYPE( class ));
+		if( groups ){
+			iter_on_id_groups(
+					groups,
+					FALSE,
+					( IdGroupIterFunc ) &define_class_properties_iter,
+					class );
+		}
+	}
+}
+
+static gboolean
+define_class_properties_iter( const NadfIdType *iddef, GObjectClass *class )
+{
+	static const gchar *thisfn = "na_data_factory_define_class_properties_iter";
+	gboolean stop;
+	GParamSpec *spec;
+
+	g_debug( "%s: iddef=%s", thisfn, iddef->name );
+
+	stop = FALSE;
+
+	switch( iddef->type ){
+
+		case NADF_TYPE_LOCALE_STRING:
+		case NADF_TYPE_STRING:
+		case NADF_TYPE_BOOLEAN:
+		case NADF_TYPE_STRING_LIST:
+		case NADF_TYPE_POINTER:
+			spec = g_param_spec_pointer(
+					iddef->name,
+					iddef->short_label,
+					iddef->long_label,
+					G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE );
+			g_object_class_install_property( class, iddef->id, spec );
+			break;
+
+		case NADF_TYPE_UINT:
+			spec = g_param_spec_uint(
+					iddef->name,
+					iddef->short_label,
+					iddef->long_label,
+					0, UINT_MAX, atoi( iddef->default_value ),
+					G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE );
+			g_object_class_install_property( class, iddef->id, spec );
+			break;
+
+		default:
+			g_debug( "%s: type=%d", thisfn, iddef->type );
+			g_return_val_if_reached( FALSE );
+	}
+
+	return( stop );
+}
+
+/**
+ * na_data_factory_new:
+ * @type: the GType type of the object we want allocate.
+ *
+ * Returns: a newly allocated #NAObject-derived object, or %NULL.
+ *
+ * The function checks that @type has been previously registered in the
+ * data factory management system (cf. #na_data_factory_init_class()),
+ * and if so invoke an empty constructor with this @type.
+ */
+NAIDataFactory *
+na_data_factory_new( GType type )
+{
+	NAIDataFactory *object;
+	NadfIdGroup *groups;
+
+	object = NULL;
+
+	/* check that @type has been registered
+	 */
+	groups = na_io_factory_get_groups( type );
+	if( groups ){
+
+		object = NA_IDATA_FACTORY( g_object_new( type, NULL ));
+	}
+
+	return( object );
+}
+
+/**
+ * na_data_factory_init:
+ * @object: the #NAIDataFactory being initialized.
+ *
+ * Initializes properties attached to the @object.
+ *
+ * This essentially consists of creating a #NADataElement for each
+ * defined elementary data, initializing it to its default value.
+ */
+void
+na_data_factory_init( NAIDataFactory *object )
+{
+	static const gchar *thisfn = "na_data_factory_init";
+	NadfIdGroup *groups;
+
+	g_debug( "%s: object=%p (%s)", thisfn, ( void * ) object, G_OBJECT_TYPE_NAME( object ));
+	g_return_if_fail( NA_IS_IDATA_FACTORY( object ));
+
+	groups = na_io_factory_get_groups( G_OBJECT_TYPE( object ));
+	if( groups ){
+
+		iter_on_id_groups( groups, FALSE, ( IdGroupIterFunc ) &data_factory_init_iter, object );
+	}
+}
+
+static gboolean
+data_factory_init_iter( const NadfIdType *iddef, NAIDataFactory *object )
+{
+	gboolean stop;
+	GList *list;
+	NADataElement *element;
+	NadfDataValue *data;
+	gchar *default_value;
+
+	stop = FALSE;
+
+	default_value = v_get_default( object, iddef );
+	element = na_data_element_new( iddef->type );
+	na_data_element_set_from_string( element, ( const void * )( default_value ? default_value : iddef->default_value ));
+	g_free( default_value );
+
+	data = g_new0( NadfDataValue, 1 );
+	data->iddef = ( NadfIdType * ) iddef;
+	data->element = element;
+
+	list = g_object_get_data( G_OBJECT( object ), NA_IDATA_FACTORY_PROP_DATA );
+	list = g_list_prepend( list, data );
+	g_object_set_data( G_OBJECT( object ), NA_IDATA_FACTORY_PROP_DATA, list );
+
+	return( stop );
+}
+
+static gchar *
+v_get_default( const NAIDataFactory *object, const NadfIdType *iddef )
+{
+	gchar *default_value;
+
+	default_value = NULL;
+
+	if( NA_IDATA_FACTORY_GET_INTERFACE( object )->get_default ){
+		default_value = NA_IDATA_FACTORY_GET_INTERFACE( object )->get_default( object, iddef );
+	}
+
+	return( default_value );
+}
+
+/**
+ * na_data_factory_copy:
+ * @target: the target #NAIDataFactory instance.
+ * @source: the source #NAIDataFactory instance.
+ *
+ * Copies one instance to another.
+ */
+void
+na_data_factory_copy( NAIDataFactory *target, const NAIDataFactory *source )
+{
+	GList *src_list, *isrc;
+	NadfDataValue *src_data;
+	NADataElement *tgt_element;
+
+	src_list = g_object_get_data( G_OBJECT( source ), NA_IDATA_FACTORY_PROP_DATA );
+	for( isrc = src_list ; isrc ; isrc = isrc->next ){
+
+		src_data = ( NadfDataValue * ) isrc->data;
+		if( src_data->iddef->copyable ){
+
+			tgt_element = data_element_from_id( target, src_data->iddef->id );
+			if( tgt_element ){
+
+				na_data_element_set( tgt_element, src_data->element );
+			}
+		}
+	}
+
+	v_copy( target, source );
+}
+
+static void
+v_copy( NAIDataFactory *target, const NAIDataFactory *source )
+{
+	if( NA_IDATA_FACTORY_GET_INTERFACE( target )->copy ){
+		NA_IDATA_FACTORY_GET_INTERFACE( target )->copy( target, source );
+	}
+}
+
+/**
+ * na_data_factory_are_equal:
+ * @a: the first #NAIDataFactory instance.
+ * @b: the second #NAIDataFactory isntance.
+ *
+ * Returns: %TRUE if @a is equal to @b, %FALSE else.
+ */
+gboolean
+na_data_factory_are_equal( const NAIDataFactory *a, const NAIDataFactory *b )
+{
+	gboolean are_equal;
+	GList *a_list, *b_list, *ia;
+	NadfDataValue *a_data;
+	NADataElement *b_element;
+
+	are_equal = FALSE;
+
+	a_list = g_object_get_data( G_OBJECT( a ), NA_IDATA_FACTORY_PROP_DATA );
+	b_list = g_object_get_data( G_OBJECT( b ), NA_IDATA_FACTORY_PROP_DATA );
+
+	if( g_list_length( a_list ) == g_list_length( b_list )){
+
+		are_equal = TRUE;
+		for( ia = a_list ; ia && are_equal ; ia = ia->next ){
+
+			a_data = ( NadfDataValue * ) ia->data;
+			if( a_data->iddef->comparable ){
+
+				b_element = data_element_from_id( b, a_data->iddef->id );
+				if( b_element ){
+					are_equal = na_data_element_are_equal( a_data->element, b_element);
+
+				} else {
+					are_equal = FALSE;
+				}
+			}
+		}
+	}
+
+	if( are_equal ){
+		are_equal = v_are_equal( a, b );
+	}
+
+	return( are_equal );
+}
+
+static gboolean
+v_are_equal( const NAIDataFactory *a, const NAIDataFactory *b )
+{
+	gboolean are_equal;
+
+	are_equal = TRUE;
+
+	if( NA_IDATA_FACTORY_GET_INTERFACE( a )->are_equal ){
+		are_equal = NA_IDATA_FACTORY_GET_INTERFACE( a )->are_equal( a, b );
+	}
+
+	return( are_equal );
+}
+
+/**
+ * na_data_factory_dump:
+ * @object: this #NAIDataFactory instance.
+ *
+ * Dumps the content of @object.
+ */
+void
+na_data_factory_dump( const NAIDataFactory *object )
+{
+	GList *list, *it;
+	NadfDataValue *str;
+
+	list = g_object_get_data( G_OBJECT( object ), NA_IDATA_FACTORY_PROP_DATA );
+	for( it = list ; it ; it = it->next ){
+
+		str = ( NadfDataValue * ) it->data;
+		na_data_element_dump( str->element, str->iddef->name );
+	}
+}
+
+/**
+ * na_data_factory_finalize:
+ * @object: the #NAIDataFactory being finalized.
+ *
+ * Clears all data associated with this @object.
+ */
+void
+na_data_factory_finalize( NAIDataFactory *object )
+{
+	GList *list, *it;
+	NadfDataValue *str;
+
+	list = g_object_get_data( G_OBJECT( object ), NA_IDATA_FACTORY_PROP_DATA );
+	for( it = list ; it ; it = it->next ){
+
+		str = ( NadfDataValue * ) it->data;
+		g_object_unref( str->element );
+		g_free( str );
+	}
+
+	g_list_free( list );
+}
+
+/**
+ * na_data_factory_read:
+ * @serializable: this #NAIDataFactory instance.
+ * @reader: the #NAIIOFactory which is at the origin of this read.
+ * @reader_data: reader data.
+ * @messages: a pointer to a #GSList list of strings; the implementation
+ *  may append messages to this list, but shouldn't reinitialize it.
+ *
+ * Unserializes the object.
+ */
+void
+na_data_factory_read( NAIDataFactory *serializable, const NAIIOFactory *reader, void *reader_data, GSList **messages )
+{
+	static const gchar *thisfn = "na_data_factory_read";
+	NadfIdGroup *groups;
+	gchar *msg;
+
+	if( idata_factory_initialized && !idata_factory_finalized ){
+
+		g_return_if_fail( NA_IS_IDATA_FACTORY( serializable ));
+		g_return_if_fail( NA_IS_IIO_FACTORY( reader ));
+
+		groups = na_io_factory_get_groups( G_OBJECT_TYPE( serializable ));
+
+		if( groups ){
+			data_factory_read_data( serializable, reader, reader_data, groups, messages );
+			v_read_done( serializable, reader, reader_data, messages );
+
+		} else {
+			msg = g_strdup_printf( "%s: instance %s doesn't return any NadfIdGroup structure",
+					thisfn, G_OBJECT_TYPE_NAME( serializable ));
+			g_warning( "%s", msg );
+			*messages = g_slist_append( *messages, msg );
+		}
+	}
+}
+
+/*
+ * data_factory_read_data:
+ * @serializable: this #NAIDataFactory instance.
+ * @reader: the #NAIIOFactory which is at the origin of this read.
+ * @reader_data: reader data.
+ * @groups: the list of NadfIdGroup structure which define @serializable.
+ * @messages: a pointer to a #GSList list of strings; the implementation
+ *  may append messages to this list, but shouldn't reinitialize it.
+ *
+ * Unserializes the object.
+ */
+static void
+data_factory_read_data( NAIDataFactory *serializable, const NAIIOFactory *reader, void *reader_data, NadfIdGroup *groups, GSList **messages )
+{
+	NadfRWIter *iter;
+
+	iter = g_new0( NadfRWIter, 1 );
+	iter->object = serializable;
+	iter->reader = ( NAIIOFactory * ) reader;
+	iter->reader_data = reader_data;
+	iter->messages = messages;
+
+	iter_on_id_groups( groups, TRUE, ( IdGroupIterFunc ) &data_factory_read_data_iter, iter );
+
+	g_free( iter );
+}
+
+static gboolean
+data_factory_read_data_iter( NadfIdType *iddef, NadfRWIter *iter )
+{
+	gboolean stop;
+	GValue *value;
+	NADataElement *element;
+
+	stop = FALSE;
+
+	value = na_io_factory_read_value( iter->reader, iter->reader_data, iddef, iter->messages );
+	if( value ){
+
+		element = data_element_from_id( iter->object, iddef->id );
+		if( element ){
+
+			na_data_element_set_from_value( element, value );
+		}
+
+		free_gvalue( value, iddef->type );
+	}
+
+	return( stop );
+}
+
+static void
+v_read_done( NAIDataFactory *serializable, const NAIIOFactory *reader, void *reader_data, GSList **messages )
+{
+	if( NA_IDATA_FACTORY_GET_INTERFACE( serializable )->read_done ){
+		NA_IDATA_FACTORY_GET_INTERFACE( serializable )->read_done( serializable, reader, reader_data, messages );
+	}
+}
+
+/**
+ * na_data_factory_write:
+ * @serializable: this #NAIDataFactory instance.
+ * @writer: the #NAIIOFactory which is at the origin of this write.
+ * @writer_data: writer data.
+ * @messages: a pointer to a #GSList list of strings; the implementation
+ *  may append messages to this list, but shouldn't reinitialize it.
+ *
+ * Serializes the object down to the @writer.
+ */
+void
+na_data_factory_write( NAIDataFactory *serializable, const NAIIOFactory *writer, void *writer_data, GSList **messages )
+{
+	static const gchar *thisfn = "na_data_factory_write";
+	NadfIdGroup *groups;
+	gchar *msg;
+
+	g_return_if_fail( NA_IS_IDATA_FACTORY( serializable ));
+	g_return_if_fail( NA_IS_IIO_FACTORY( writer ));
+
+	groups = na_io_factory_get_groups( G_OBJECT_TYPE( serializable ));
+
+	if( groups ){
+		data_factory_write_data( serializable, writer, writer_data, groups, messages );
+		v_write_done( serializable, writer, writer_data, messages );
+
+	} else {
+		msg = g_strdup_printf( "%s: instance %s doesn't return any NadfIdGroup structure",
+				thisfn, G_OBJECT_TYPE_NAME( serializable ));
+		g_warning( "%s", msg );
+		*messages = g_slist_append( *messages, msg );
+	}
+}
+
+/*
+ * data_factory_write_data:
+ * @serializable: this #NAIDataFactory instance.
+ * @writer: the #NAIIOFactory which is at the origin of this writ.
+ * @writer_data: writer data.
+ * @groups: the list of NadfIdGroup structure which define @serializable.
+ * @messages: a pointer to a #GSList list of strings; the implementation
+ *  may append messages to this list, but shouldn't reinitialize it.
+ *
+ * Serializes the object.
+ */
+static void
+data_factory_write_data( NAIDataFactory *serializable, const NAIIOFactory *writer, void *writer_data, NadfIdGroup *groups, GSList **messages )
+{
+	NadfRWIter *iter;
+
+	iter = g_new0( NadfRWIter, 1 );
+	iter->object = serializable;
+	iter->reader = ( NAIIOFactory * ) writer;
+	iter->reader_data = writer_data;
+	iter->messages = messages;
+
+	iter_on_id_groups( groups, TRUE, ( IdGroupIterFunc ) &data_factory_write_data_iter, iter );
+
+	g_free( iter );
+}
+
+static gboolean
+data_factory_write_data_iter( NadfIdType *iddef, NadfRWIter *iter )
+{
+	gboolean stop;
+
+	stop = FALSE;
+
+	/*na_io_factory_set_value( iter->reader, iter->reader_data, iddef, iter->messages );*/
+
+	return( stop );
+}
+
+static void
+v_write_done( NAIDataFactory *serializable, const NAIIOFactory *writer, void *writer_data, GSList **messages )
+{
+	if( NA_IDATA_FACTORY_GET_INTERFACE( serializable )->write_done ){
+		NA_IDATA_FACTORY_GET_INTERFACE( serializable )->write_done( serializable, writer, writer_data, messages );
+	}
+}
+
+/**
+ * na_data_factory_set:
+ * @object: this #NAIDataFactory instance.
+ * @data_id: the elementary data whose value is to be set.
+ * @data: the value to set.
+ *
+ * Set the elementary data with the given value.
+ */
+void
+na_data_factory_set( NAIDataFactory *object, guint data_id, const void *data )
+{
+	static const gchar *thisfn = "na_data_factory_set";
+	NADataElement *element;
+
+	/*g_debug( "%s: object=%p (%s), data_id=%d, data=%p",
+			thisfn, ( void * ) object, G_OBJECT_TYPE_NAME( object ), data_id, ( void * ) data );*/
+
+	g_return_if_fail( NA_IS_IDATA_FACTORY( object ));
+
+	element = data_element_from_id( object, data_id );
+	if( element ){
+		na_data_element_set_from_void( element, data );
+
+	} else {
+		g_warning( "%s: unknown property id %d", thisfn, data_id );
+	}
+}
+
+/**
+ * na_data_factory_get_value:
+ * @object: this #NAIDataFactory instance.
+ * @property_id: the elementary data id.
+ * @value: the #GValue whose content is to be got.
+ * @spec: the #GParamSpec which describes this data.
+ *
+ * Get from the @value the content to be set in the #NADataElement
+ * attached to @property_id.
+ *
+ * This is to be readen as "set data element from value".
+ */
+void
+na_data_factory_get_value( NAIDataFactory *object, guint property_id, const GValue *value, GParamSpec *spec )
+{
+	static const gchar *thisfn = "na_data_factory_get_value";
+	NADataElement *element;
+
+	g_return_if_fail( NA_IS_IDATA_FACTORY( object ));
+
+	element = data_element_from_id( object, property_id );
+	if( element ){
+		na_data_element_set_from_value( element, value );
+
+	} else {
+		g_warning( "%s: unknown property id %d", thisfn, property_id );
+	}
+}
+
+/**
+ * na_data_factory_get:
+ * @object: this #NAIDataFactory instance.
+ * @data_id: the elementary data whose value is to be got.
+ *
+ * Returns: the searched value.
+ *
+ * If the type of the value is NADF_TYPE_STRING, NADF_TYPE_LOCALE_STRING,
+ * or NADF_TYPE_STRING_LIST, then the returned value is a newly allocated
+ * one and should be g_free() (resp. na_core_utils_slist_free()) by the
+ * caller.
+ */
+void *
+na_data_factory_get( const NAIDataFactory *object, guint data_id )
+{
+	static const gchar *thisfn = "na_data_factory_get";
+	void *value;
+	NADataElement *element;
+
+	g_return_val_if_fail( NA_IS_IDATA_FACTORY( object ), NULL );
+
+	value = NULL;
+
+	element = data_element_from_id( object, data_id );
+	if( element ){
+		value = na_data_element_get( element );
+
+	} else {
+		g_warning( "%s: unknown property id %d", thisfn, data_id );
+	}
+
+	return( value );
+}
+
+/**
+ * na_data_factory_set_value:
+ * @object: this #NAIDataFactory instance.
+ * @property_id: the elementary data id.
+ * @value: the #GValue to be set.
+ * @spec: the #GParamSpec which describes this data.
+ *
+ * Set the @value with the current content of the #NADataElement attached
+ * to @property_id.
+ *
+ * This is to be readen as "set value from data element".
+ */
+void
+na_data_factory_set_value( const NAIDataFactory *object, guint property_id, GValue *value, GParamSpec *spec )
+{
+	static const gchar *thisfn = "na_data_factory_set_value";
+	NADataElement *element;
+
+	g_return_if_fail( NA_IS_IDATA_FACTORY( object ));
+
+	element = data_element_from_id( object, property_id );
+	if( element ){
+		na_data_element_set_to_value( element, value );
+
+	} else {
+		g_warning( "%s: unknown property id %d", thisfn, property_id );
+	}
+}
+
+static NADataElement *
+data_element_from_id( const NAIDataFactory *object, guint data_id )
+{
+	GList *list, *ip;
+	NADataElement *element;
+
+	element = NULL;
+
+	list = g_object_get_data( G_OBJECT( object ), NA_IDATA_FACTORY_PROP_DATA );
+
+	for( ip = list ; ip && !element ; ip = ip->next ){
+		NadfDataValue *ndv = ( NadfDataValue * ) ip->data;
+		if( ndv->iddef->id == data_id ){
+			element = ndv->element;
+		}
+	}
+
+	return( element );
+}
+
+/*
+ * the iter function must return TRUE to stops the enumeration
+ */
+static void
+iter_on_id_groups( const NadfIdGroup *groups, gboolean serializable_only, IdGroupIterFunc pfn, void *user_data )
+{
+	NadfIdType *iddef;
+	gboolean stop;
+
+	stop = FALSE;
+
+	while( groups->idgroup && !stop ){
+
+		if( groups->iddef ){
+
+			iddef = groups->iddef;
+			while( iddef->id && !stop ){
+
+				/*g_debug( "serializable_only=%s, iddef->serializable=%s",
+						serializable_only ? "True":"False", iddef->serializable ? "True":"False" );*/
+
+				if( !serializable_only || iddef->serializable ){
+					stop = ( *pfn )( iddef, user_data );
+				}
+
+				iddef++;
+			}
+		}
+
+		groups++;
+	}
+}
+
+static void
+free_gvalue( GValue *value, guint type )
+{
+	GSList *slist;
+
+	if( type == NADF_TYPE_STRING_LIST ){
+		slist = g_value_get_pointer( value );
+		na_core_utils_slist_free( slist );
+	}
+
+	g_value_unset( value );
+	g_free( value );
+}
diff --git a/src/core/na-data-factory.h b/src/core/na-data-factory.h
new file mode 100644
index 0000000..93312a2
--- /dev/null
+++ b/src/core/na-data-factory.h
@@ -0,0 +1,63 @@
+/*
+ * Nautilus Actions
+ * A Nautilus extension which offers configurable context menu actions.
+ *
+ * Copyright (C) 2005 The GNOME Foundation
+ * Copyright (C) 2006, 2007, 2008 Frederic Ruaudel and others (see AUTHORS)
+ * Copyright (C) 2009, 2010 Pierre Wieser and others (see AUTHORS)
+ *
+ * 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 of
+ * the License, 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 Library; see the file COPYING.  If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place,
+ * Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Authors:
+ *   Frederic Ruaudel <grumz grumz net>
+ *   Rodrigo Moya <rodrigo gnome-db org>
+ *   Pierre Wieser <pwieser trychlos org>
+ *   ... and many others (see AUTHORS)
+ */
+
+#ifndef __CORE_NA_DATA_FACTORY_H__
+#define __CORE_NA_DATA_FACTORY_H__
+
+/**
+ * SECTION: na_idata_factory
+ * @short_description: #NAIDataFactory internal functions.
+ * @include: core/na-data-factory.h
+ */
+
+#include <api/na-iio-factory.h>
+
+G_BEGIN_DECLS
+
+void            na_data_factory_properties( GObjectClass *class );
+NAIDataFactory *na_data_factory_new       ( GType type );
+
+void            na_data_factory_init      ( NAIDataFactory *object );
+void            na_data_factory_copy      ( NAIDataFactory *target, const NAIDataFactory *source );
+gboolean        na_data_factory_are_equal ( const NAIDataFactory *a, const NAIDataFactory *b );
+void            na_data_factory_dump      ( const NAIDataFactory *object );
+void            na_data_factory_finalize  ( NAIDataFactory *object );
+
+void            na_data_factory_read      ( NAIDataFactory *object, const NAIIOFactory *reader, void *reader_data, GSList **messages );
+void            na_data_factory_write     ( NAIDataFactory *object, const NAIIOFactory *writer, void *writer_data, GSList **messages );
+
+void            na_data_factory_set       ( NAIDataFactory *object, guint data_id, const void *data );
+void            na_data_factory_get_value ( NAIDataFactory *object, guint property_id, const GValue *value, GParamSpec *spec );
+void           *na_data_factory_get       ( const NAIDataFactory *object, guint data_id );
+void            na_data_factory_set_value ( const NAIDataFactory *object, guint property_id, GValue *value, GParamSpec *spec );
+
+G_END_DECLS
+
+#endif /* __CORE_NA_DATA_FACTORY_H__ */
diff --git a/src/core/na-idata-factory.c b/src/core/na-idata-factory.c
new file mode 100644
index 0000000..29f4e58
--- /dev/null
+++ b/src/core/na-idata-factory.c
@@ -0,0 +1,171 @@
+/*
+ * Nautilus Actions
+ * A Nautilus extension which offers configurable context menu actions.
+ *
+ * Copyright (C) 2005 The GNOME Foundation
+ * Copyright (C) 2006, 2007, 2008 Frederic Ruaudel and others (see AUTHORS)
+ * Copyright (C) 2009, 2010 Pierre Wieser and others (see AUTHORS)
+ *
+ * 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 of
+ * the License, 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 Library; see the file COPYING.  If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place,
+ * Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Authors:
+ *   Frederic Ruaudel <grumz grumz net>
+ *   Rodrigo Moya <rodrigo gnome-db org>
+ *   Pierre Wieser <pwieser trychlos org>
+ *   ... and many others (see AUTHORS)
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <api/na-idata-factory.h>
+
+#include "na-data-factory.h"
+
+/* private interface data
+ */
+struct NAIDataFactoryInterfacePrivate {
+	void *empty;						/* so that gcc -pedantic is happy */
+};
+
+gboolean idata_factory_initialized = FALSE;
+gboolean idata_factory_finalized   = FALSE;
+
+static GType register_type( void );
+static void  interface_base_init( NAIDataFactoryInterface *klass );
+static void  interface_base_finalize( NAIDataFactoryInterface *klass );
+
+static guint idata_factory_get_version( const NAIDataFactory *instance );
+
+/**
+ * Registers the GType of this interface.
+ */
+GType
+na_idata_factory_get_type( void )
+{
+	static GType object_type = 0;
+
+	if( !object_type ){
+		object_type = register_type();
+	}
+
+	return( object_type );
+}
+
+static GType
+register_type( void )
+{
+	static const gchar *thisfn = "na_idata_factory_register_type";
+	GType type;
+
+	static const GTypeInfo info = {
+		sizeof( NAIDataFactoryInterface ),
+		( GBaseInitFunc ) interface_base_init,
+		( GBaseFinalizeFunc ) interface_base_finalize,
+		NULL,
+		NULL,
+		NULL,
+		0,
+		0,
+		NULL
+	};
+
+	g_debug( "%s", thisfn );
+
+	type = g_type_register_static( G_TYPE_INTERFACE, "NAIDataFactory", &info, 0 );
+
+	g_type_interface_add_prerequisite( type, G_TYPE_OBJECT );
+
+	return( type );
+}
+
+static void
+interface_base_init( NAIDataFactoryInterface *klass )
+{
+	static const gchar *thisfn = "na_idata_factory_interface_base_init";
+
+	if( !idata_factory_initialized ){
+
+		g_debug( "%s: klass=%p (%s)", thisfn, ( void * ) klass, G_OBJECT_CLASS_NAME( klass ));
+
+		klass->private = g_new0( NAIDataFactoryInterfacePrivate, 1 );
+
+		klass->get_version = idata_factory_get_version;
+		klass->get_default = NULL;
+		klass->read_done = NULL;
+		klass->write_done = NULL;
+
+		idata_factory_initialized = TRUE;
+	}
+}
+
+static void
+interface_base_finalize( NAIDataFactoryInterface *klass )
+{
+	static const gchar *thisfn = "na_idata_factory_interface_base_finalize";
+
+	if( idata_factory_initialized && !idata_factory_finalized ){
+
+		g_debug( "%s: klass=%p", thisfn, ( void * ) klass );
+
+		idata_factory_finalized = TRUE;
+
+		g_free( klass->private );
+	}
+}
+
+static guint
+idata_factory_get_version( const NAIDataFactory *instance )
+{
+	return( 1 );
+}
+
+/**
+ * na_idata_factory_get:
+ * @object: this #NAIDataFactory instance.
+ * @data_id: the elementary data whose value is to be got.
+ *
+ * Returns: the searched value.
+ *
+ * If the type of the value is NADF_TYPE_STRING, NADF_TYPE_LOCALE_STRING,
+ * or NADF_TYPE_STRING_LIST, then the returned value is a newly allocated
+ * one and should be g_free() (resp. na_core_utils_slist_free()) by the
+ * caller.
+ */
+void *
+na_idata_factory_get( const NAIDataFactory *object, guint data_id )
+{
+	g_return_val_if_fail( NA_IS_IDATA_FACTORY( object ), NULL );
+
+	return( na_data_factory_get( object, data_id ));
+}
+
+/**
+ * na_idata_factory_set:
+ * @object: this #NAIDataFactory instance.
+ * @data_id: the elementary data whose value is to be set.
+ * @data: the value to set.
+ *
+ * Set the elementary data with the given value.
+ */
+void
+na_idata_factory_set( NAIDataFactory *object, guint data_id, const void *data )
+{
+	g_return_if_fail( NA_IS_IDATA_FACTORY( object ));
+
+	na_data_factory_set( object, data_id, data );
+}



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]