[nautilus-actions] Define NASettings class



commit 932c2298fff9ecd7213e87ce5a1241595da52b5e
Author: Pierre Wieser <pwieser trychlos org>
Date:   Fri Jan 7 19:17:30 2011 +0100

    Define NASettings class

 ChangeLog              |    3 +
 src/core/na-settings.c |  377 ++++++++++++++++++++++++++++++++++++++++++++++++
 src/core/na-settings.h |   99 +++++++++++++
 3 files changed, 479 insertions(+), 0 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 534b2cf..6ecd685 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -94,6 +94,9 @@
 
 2011-01-07 Pierre Wieser <pwieser trychlos org>
 
+	* src/core/na-settings.c:
+	* src/core/na-settings.h: New files.
+
 	* src/utils/na-gconf2key.sh.in:
 	Make sure that GConf is at the end of the list of I/O providers.
 	Make sure that GConf is locked.
diff --git a/src/core/na-settings.c b/src/core/na-settings.c
new file mode 100644
index 0000000..2dfd818
--- /dev/null
+++ b/src/core/na-settings.c
@@ -0,0 +1,377 @@
+/*
+ * 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, 2011 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-data-types.h>
+
+#include "na-settings.h"
+
+/* private class data
+ */
+struct _NASettingsClassPrivate {
+	void *empty;						/* so that gcc -pedantic is happy */
+};
+
+/* private instance data
+ */
+struct _NASettingsPrivate {
+	gboolean  dispose_has_run;
+	GKeyFile     *global_conf;
+	GFileMonitor *global_monitor;
+	gulong        global_handler;
+	GKeyFile     *user_conf;
+	GFileMonitor *user_monitor;
+	gulong        user_handler;
+	GList        *consumers;
+};
+
+#define GROUP_NACT						"nact"
+#define GROUP_RUNTIME					"runtime"
+#define GROUP_IO_PROVIDER				"io-provider"
+
+typedef struct {
+	const gchar *key;
+	const gchar *group;
+	guint        data_type;				/* picked up from NADataFactory */
+	const gchar *default_value;
+}
+	KeyDef;
+
+static const KeyDef st_def_keys[] = {
+		{ NA_SETTINGS_RUNTIME_ITEMS_ADD_ABOUT_ITEM,   GROUP_RUNTIME, NAFD_TYPE_BOOLEAN, "true" },
+		{ NA_SETTINGS_RUNTIME_ITEMS_CREATE_ROOT_MENU, GROUP_RUNTIME, NAFD_TYPE_BOOLEAN, "true" },
+		{ 0 }
+};
+
+typedef struct {
+	gchar             *key;
+	NASettingsCallback callback;
+	gpointer           user_data;
+}
+	Consumer;
+
+static GObjectClass *st_parent_class = NULL;
+
+static GType     register_type( void );
+static void      class_init( NASettingsClass *klass );
+static void      instance_init( GTypeInstance *instance, gpointer klass );
+static void      instance_dispose( GObject *object );
+static void      instance_finalize( GObject *object );
+
+static GKeyFile *initialize_settings( NASettings* settings, const gchar *dir, GFileMonitor **monitor, gulong *handler );
+static void      release_consumer( Consumer *consumer );
+
+GType
+na_settings_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_settings_register_type";
+	GType type;
+
+	static GTypeInfo info = {
+		sizeof( NASettingsClass ),
+		( GBaseInitFunc ) NULL,
+		( GBaseFinalizeFunc ) NULL,
+		( GClassInitFunc ) class_init,
+		NULL,
+		NULL,
+		sizeof( NASettings ),
+		0,
+		( GInstanceInitFunc ) instance_init
+	};
+
+	g_debug( "%s", thisfn );
+
+	type = g_type_register_static( G_TYPE_OBJECT, "NASettings", &info, 0 );
+
+	return( type );
+}
+
+static void
+class_init( NASettingsClass *klass )
+{
+	static const gchar *thisfn = "na_settings_class_init";
+	GObjectClass *object_class;
+
+	g_debug( "%s: klass=%p", thisfn, ( void * ) klass );
+
+	st_parent_class = g_type_class_peek_parent( klass );
+
+	object_class = G_OBJECT_CLASS( klass );
+	object_class->dispose = instance_dispose;
+	object_class->finalize = instance_finalize;
+
+	klass->private = g_new0( NASettingsClassPrivate, 1 );
+}
+
+static void
+instance_init( GTypeInstance *instance, gpointer klass )
+{
+	static const gchar *thisfn = "na_settings_instance_init";
+	NASettings *self;
+
+	g_return_if_fail( NA_IS_SETTINGS( instance ));
+
+	self = NA_SETTINGS( instance );
+
+	g_debug( "%s: instance=%p (%s), klass=%p",
+			thisfn, ( void * ) instance, G_OBJECT_TYPE_NAME( instance ), ( void * ) klass );
+
+	self->private = g_new0( NASettingsPrivate, 1 );
+
+	self->private->dispose_has_run = FALSE;
+	self->private->global_conf = NULL;
+	self->private->global_monitor = NULL;
+	self->private->global_handler = 0;
+	self->private->user_conf = NULL;
+	self->private->user_monitor = NULL;
+	self->private->user_handler = 0;
+	self->private->consumers = NULL;
+}
+
+static void
+instance_dispose( GObject *object )
+{
+	static const gchar *thisfn = "na_settings_instance_dispose";
+	NASettings *self;
+
+	g_return_if_fail( NA_IS_SETTINGS( object ));
+
+	self = NA_SETTINGS( object );
+
+	if( !self->private->dispose_has_run ){
+
+		g_debug( "%s: object=%p (%s)", thisfn, ( void * ) object, G_OBJECT_TYPE_NAME( object ));
+
+		self->private->dispose_has_run = TRUE;
+
+		g_key_file_free( self->private->global_conf );
+		if( self->private->global_monitor ){
+			if( self->private->global_handler ){
+				g_signal_disconnect( self->private->global_monitor, self->private->global_handler );
+			}
+			g_file_monitor_cancel( self->private->global_monitor );
+			g_object_unref( self->private->global_monitor );
+		}
+
+		g_key_file_free( self->private->user_conf );
+		if( self->private->user_monitor ){
+			if( self->private->user_handler ){
+				g_signal_disconnect( self->private->user_monitor, self->private->user_handler );
+			}
+			g_file_monitor_cancel( self->private->user_monitor );
+			g_object_unref( self->private->user_monitor );
+		}
+
+		if( G_OBJECT_CLASS( st_parent_class )->dispose ){
+			G_OBJECT_CLASS( st_parent_class )->dispose( object );
+		}
+	}
+}
+
+static void
+instance_finalize( GObject *object )
+{
+	static const gchar *thisfn = "na_settings_instance_finalize";
+	NASettings *self;
+
+	g_return_if_fail( NA_IS_SETTINGS( object ));
+
+	self = NA_SETTINGS( object );
+
+	g_debug( "%s: object=%p", thisfn, ( void * ) object );
+
+	g_list_foreach( self->private->consumers, ( GFunc ) release_consumer, NULL );
+	g_list_free( self->private->consumers );
+
+	g_free( self->private );
+
+	/* chain call to parent class */
+	if( G_OBJECT_CLASS( st_parent_class )->finalize ){
+		G_OBJECT_CLASS( st_parent_class )->finalize( object );
+	}
+}
+
+/**
+ * na_settings_new:
+ *
+ * Returns: a new #NASettings object which should be g_object_unref()
+ * by the caller.
+ */
+NASettings *
+na_settings_new( void )
+{
+	NASettings *settings;
+
+	settings = g_object_new( NA_SETTINGS_TYPE, NULL );
+
+	settings->private->global_conf = initialize_settings(
+			settings, SYSCONFDIR,
+			&settings->private->global_monitor,
+			&settings->private->global_handler );
+
+	settings->private->user_conf = initialize_settings(
+			settings, g_get_home_dir(),
+			&settings->private->user_monitor,
+			&settings->private->user_handler );
+
+	return( settings );
+}
+
+/**
+ * na_settings_register:
+ * @settings: this #NASettings instance.
+ * @key: the key to be monitored.
+ * @callback: the function to be called when the value of the key changes.
+ * @user_data: data to be passed to the @callback function.
+ *
+ * Registers a new consumer of the monitoring of the @key.
+ *
+ * Since: 3.1.0
+ */
+void
+na_settings_register( NASettings *settings, const gchar *key, NASettingsCallback callback, gpointer user_data )
+{
+	g_return_if_fail( NA_IS_SETTINGS( settings ));
+
+	if( !settings->private->dispose_has_run ){
+
+		Consumer *consumer = g_new0( Consumer, 1 );
+
+		consumer->key = g_strdup( key );
+		consumer->callback = callback;
+		consumer->user_data = user_data;
+		settings->private->consumers = g_list_prepend( settings->private->consumers, consumer );
+	}
+
+}
+
+/**
+ * na_settings_get_value:
+ * @settings: this #NASettings instance.
+ * @key: the key whose value is to be returned.
+ * @found: if not %NULL, a pointer to a gboolean in which we will store
+ *  whether the searched @key has been found (%TRUE), or if the returned
+ *  value comes from default (%FALSE).
+ * @global: if not %NULL, a pointer to a gboolean in which we will store
+ *  whether the returned value has been readen from global preferences
+ *  (%TRUE), or from the user preferences (%FALSE). Global preferences
+ *  are usually read-only. When the @key has not been found, @global
+ *  is set to %FALSE.
+ *
+ * Returns: the value of the key, of its default value if not found.
+ *
+ * Since: 3.1.0
+ */
+gpointer
+na_settings_get_value( NASettings *settings, const gchar *key, gboolean *found, gboolean *global )
+{
+	gpointer value;
+
+	g_return_val_if_fail( NA_IS_SETTINGS( settings ), NULL );
+
+	value = NULL;
+
+	if( !settings->private->dispose_has_run ){
+
+	}
+
+	return( value );
+}
+
+/*
+ * called from na_settings_new
+ * allocate and load the key files for global and user preferences
+ */
+static GKeyFile *
+initialize_settings( NASettings* settings, const gchar *dir, GFileMonitor **monitor, gulong *handler )
+{
+	static const gchar *thisfn = "na_settings_initialize_settings";
+	GKeyFile *key_file;
+	GError *error;
+	gchar *path;
+	GFile *file;
+
+	key_file = g_key_file_new();
+
+	error = NULL;
+	path = g_strdup_printf( "%s/%s.conf", dir, PACKAGE );
+	if( !g_key_file_load_from_file( key_file, path, G_KEY_FILE_KEEP_COMMENTS, &error )){
+		g_warning( "%s: %s", thisfn, error->message );
+		g_error_free( error );
+		error = NULL;
+	}
+
+	file = g_file_new_for_path( path );
+	*monitor = g_file_monitor_file( file, 0, NULL, &error );
+	if( error ){
+		g_warning( "%s: %s", thisfn, error->message );
+		g_error_free( error );
+		error = NULL;
+
+	} else {
+		*handler = g_signal_connect( *monitor, "changed", ( GCallback ) on_conf_changed, settings );
+	}
+	g_object_unref( file );
+
+	g_free( path );
+	return( key_file );
+}
+
+void on_conf_changed( GFileMonitor *monitor,
+		GFile *file, GFile *other_file, GFileMonitorEvent event_type, NASettings *settings )
+{
+	g_return_if_fail( NA_IS_SETTINGS( settings ));
+}
+
+/*
+ * called from instance_finalize
+ * release the list of registered consumers
+ */
+static void
+release_consumer( Consumer *consumer )
+{
+	g_free( consumer->key );
+	g_free( consumer );
+}
diff --git a/src/core/na-settings.h b/src/core/na-settings.h
new file mode 100644
index 0000000..8c6bf63
--- /dev/null
+++ b/src/core/na-settings.h
@@ -0,0 +1,99 @@
+/*
+ * Nautilus-Actions
+ * A Nautilus extension which offers configurable context menu modules.
+ *
+ * Copyright (C) 2005 The GNOME Foundation
+ * Copyright (C) 2006, 2007, 2008 Frederic Ruaudel and others (see AUTHORS)
+ * Copyright (C) 2009, 2010, 2011 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_SETTINGS_H__
+#define __CORE_NA_SETTINGS_H__
+
+/* @title: NASettings
+ * @short_description: The Settings Class Definition
+ * @include: core/na-settings.h
+ *
+ * The #NASettings class manages users preferences.
+ *
+ * Actual configuration may come from two sources:
+ * - a global configuration, which apply to all users, as read-only
+ *   parameters;
+ * - a per-user configuration.
+ *
+ * The configuration is implemented as keyed files:
+ * - global configuration is sysconfdir/nautilus-actions.conf
+ * - per-user configuration is HOME/.config/nautilus-actions.conf
+ *
+ * Each setting has so its own read-only attribute, whether it
+ * has been readen from the global configuration or from the
+ * per-user one.
+ */
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define NA_SETTINGS_TYPE                  ( na_settings_get_type())
+#define NA_SETTINGS( object )             ( G_TYPE_CHECK_INSTANCE_CAST( object, NA_SETTINGS_TYPE, NASettings ))
+#define NA_SETTINGS_CLASS( klass )        ( G_TYPE_CHECK_CLASS_CAST( klass, NA_SETTINGS_TYPE, NASettingsClass ))
+#define NA_IS_SETTINGS( object )          ( G_TYPE_CHECK_INSTANCE_TYPE( object, NA_SETTINGS_TYPE ))
+#define NA_IS_SETTINGS_CLASS( klass )     ( G_TYPE_CHECK_CLASS_TYPE(( klass ), NA_SETTINGS_TYPE ))
+#define NA_SETTINGS_GET_CLASS( object )   ( G_TYPE_INSTANCE_GET_CLASS(( object ), NA_SETTINGS_TYPE, NASettingsClass ))
+
+typedef struct _NASettingsPrivate         NASettingsPrivate;
+typedef struct _NASettingsClassPrivate    NASettingsClassPrivate;
+
+typedef struct {
+	/*< private >*/
+	GObject            parent;
+	NASettingsPrivate *private;
+}
+	NASettings;
+
+typedef struct {
+	/*< private >*/
+	GObjectClass            parent;
+	NASettingsClassPrivate *private;
+}
+	NASettingsClass;
+
+GType na_settings_get_type( void );
+
+typedef void ( *NASettingsCallback )( const gchar *key, gpointer new_value, gpointer user_data );
+
+#define NA_SETTINGS_RUNTIME_ITEMS_ADD_ABOUT_ITEM		"items-add-about-item"
+#define NA_SETTINGS_RUNTIME_ITEMS_CREATE_ROOT_MENU		"items-create-root-menu"
+
+NASettings *na_settings_new      ( void );
+
+void        na_settings_register ( NASettings *settings, const gchar *key, NASettingsCallback callback, gpointer user_data );
+
+#define     na_settings_get_bool ( settings, key ) (( gboolean ) GPOINTER_TO_UINT( na_settings_get_value( settings, key, NULL, NULL )))
+
+gpointer    na_settings_get_value( NASettings *settings, const gchar *key, gboolean *found, gboolean *global );
+
+G_END_DECLS
+
+#endif /* __CORE_NA_SETTINGS_H__ */



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