[nautilus-actions: 1/3] Begin with porting NACT to new object hierarchy



commit ec204bc9876d50905a0f0caa1ce8333ff2c601b6
Author: Pierre Wieser <pwieser trychlos org>
Date:   Fri Jun 19 00:42:12 2009 +0200

    Begin with porting NACT to new object hierarchy

 ChangeLog                      |   24 ++
 m4/.gitignore                  |    5 +
 src/common/nact-action.c       |   93 +++++
 src/common/nact-action.h       |    5 +
 src/common/nact-iio-provider.c |   47 +++
 src/common/nact-iio-provider.h |    6 +-
 src/common/nact-pivot.c        |   99 +++++
 src/common/nact-pivot.h        |    5 +
 src/nact/Makefile.am           |    2 +
 src/nact/base-application.c    |  830 ++++++++++++++++++++++++++++++++++++++++
 src/nact/base-application.h    |   96 +++++
 src/nact/nact-application.c    |  244 +++---------
 src/nact/nact-application.h    |    9 +-
 src/nact/nact-main.c           |    6 +-
 src/nact/nact.c                |  142 ++++---
 src/nact/nact.h                |    3 +-
 16 files changed, 1356 insertions(+), 260 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index ffcb644..005e898 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,27 @@
+2009-06-18 Pierre Wieser <pwieser trychlos org>
+
+	Begin with porting NACT to new object hierarchy.
+
+	* src/common/nact-action.c:
+	* src/common/nact-action.h (nact_action_duplicate,
+	nact_action_get_version, nact_action_get_icon,
+	nact_action_set_new_uuid): New functions.
+
+	* src/common/nact-iio-provider.c:
+	* src/common/nact-iio-provider.h (+nact_iio_provider_write_action):
+	New function.
+
+	* src/common/nact-pivot.c:
+	* src/common/nact-pivot.h (nact_pivot_get_label_sorted_actions,
+	nact_pivot_get_action, nact_pivot_add_action):
+	New functions.
+
+	* src/nact/base-application.c:
+	* src/nact/base-application.h: New base class.
+
+	* src/nact/nact-application.c:
+	* src/nact/nact-application.h: Updated accordingly.
+
 2009-06-14 Pierre Wieser <pwieser trychlos org>
 
 	* po/POTFILES.in: Add src/nact-application.c.
diff --git a/m4/.gitignore b/m4/.gitignore
index 9f841b0..55eaa80 100644
--- a/m4/.gitignore
+++ b/m4/.gitignore
@@ -1 +1,6 @@
 intltool.m4
+libtool.m4
+ltoptions.m4
+ltsugar.m4
+ltversion.m4
+lt~obsolete.m4
diff --git a/src/common/nact-action.c b/src/common/nact-action.c
index d81ee66..95f6bd2 100644
--- a/src/common/nact-action.c
+++ b/src/common/nact-action.c
@@ -33,6 +33,7 @@
 #endif
 
 #include <string.h>
+#include <uuid/uuid.h>
 
 #include "nact-action.h"
 #include "nact-action-profile.h"
@@ -325,6 +326,39 @@ nact_action_new( const gchar *uuid )
 	return( action );
 }
 
+/**
+ * Allocates a new NactAction object, and initializes it as an exact
+ * copy of the specified action.
+ *
+ * @action: the action to be duplicated.
+ *
+ * Return a newly allocated NactAction object.
+ *
+ * Please note than "an exact copy" here means that the newly allocated
+ * returned object has the _same_ UUID than the original one.
+ */
+NactAction *
+nact_action_duplicate( const NactAction *action )
+{
+	g_assert( NACT_IS_ACTION( action ));
+
+	gchar *uuid = do_get_id( NACT_OBJECT( action ));
+	NactAction *duplicate = g_object_new( NACT_ACTION_TYPE, PROP_UUID_STR, uuid, NULL );
+	g_free( uuid );
+
+	duplicate->private->version = g_strdup( action->private->version );
+	duplicate->private->label = g_strdup( action->private->label );
+	duplicate->private->tooltip = g_strdup( action->private->tooltip );
+	duplicate->private->icon = g_strdup( action->private->icon );
+
+	GSList *ip;
+	for( ip = action->private->profiles ; ip ; ip = ip->next ){
+
+	}
+
+	return( duplicate );
+}
+
 static void
 do_dump( const NactObject *action )
 {
@@ -376,6 +410,28 @@ nact_action_get_uuid( const NactAction *action )
 	return( nact_object_get_id( NACT_OBJECT( action )));
 }
 
+/**
+ * Returns the version attached to the action.
+ *
+ * @action: an NactAction object.
+ *
+ * The returned string must be g_freed by the caller.
+ *
+ * The version is always upgraded to the latest when the action is
+ * readen from the I/O provider. So we could assert here that the
+ * returned version is also the latest.
+ */
+gchar *
+nact_action_get_version( const NactAction *action )
+{
+	g_assert( NACT_IS_ACTION( action ));
+
+	gchar *version;
+	g_object_get( G_OBJECT( action ), PROP_VERSION_STR, &version, NULL );
+
+	return( version );
+}
+
 static gchar *
 do_get_label( const NactObject *action )
 {
@@ -421,6 +477,25 @@ nact_action_get_tooltip( const NactAction *action )
 }
 
 /**
+ * Returns the name of the icon attached to the context menu item for
+ * the action.
+ *
+ * @action: an NactAction object.
+ *
+ * The returned string must be g_freed by the caller.
+ */
+gchar *
+nact_action_get_icon( const NactAction *action )
+{
+	g_assert( NACT_IS_ACTION( action ));
+
+	gchar *icon;
+	g_object_get( G_OBJECT( action ), PROP_ICON_STR, &icon, NULL );
+
+	return( icon );
+}
+
+/**
  * Returns the icon name attached to the context menu item for the
  * action.
  *
@@ -450,6 +525,24 @@ nact_action_get_verified_icon_name( const NactAction *action )
 }
 
 /**
+ * Set a new UUID for the action.
+ *
+ * @action: action whose UUID is to be set.
+ */
+void
+nact_action_set_new_uuid( NactAction *action )
+{
+	g_assert( NACT_IS_ACTION( action ));
+	uuid_t uuid;
+	gchar uuid_str[64];
+
+	uuid_generate( uuid );
+	uuid_unparse_lower( uuid, uuid_str );
+
+	g_object_set( G_OBJECT( action ), PROP_UUID_STR, uuid_str, NULL );
+}
+
+/**
  * Returns the list of profiles of the actions as a GSList of
  * NactActionProfile GObjects.
  *
diff --git a/src/common/nact-action.h b/src/common/nact-action.h
index 4b073a9..01e4107 100644
--- a/src/common/nact-action.h
+++ b/src/common/nact-action.h
@@ -70,12 +70,17 @@ typedef struct {
 GType       nact_action_get_type( void );
 
 NactAction *nact_action_new( const gchar *uuid );
+NactAction *nact_action_duplicate( const NactAction *action );
 
 gchar      *nact_action_get_uuid( const NactAction *action );
+gchar      *nact_action_get_version( const NactAction *action );
 gchar      *nact_action_get_label( const NactAction *action );
 gchar      *nact_action_get_tooltip( const NactAction *action );
+gchar      *nact_action_get_icon( const NactAction *action );
 gchar      *nact_action_get_verified_icon_name( const NactAction *action );
 
+void        nact_action_set_new_uuid( NactAction *action );
+
 GSList     *nact_action_get_profiles( const NactAction *action );
 void        nact_action_set_profiles( NactAction *action, GSList *list );
 void        nact_action_free_profiles( GSList *list );
diff --git a/src/common/nact-iio-provider.c b/src/common/nact-iio-provider.c
index 048e4f2..14d5d69 100644
--- a/src/common/nact-iio-provider.c
+++ b/src/common/nact-iio-provider.c
@@ -32,6 +32,10 @@
 #include <config.h>
 #endif
 
+#include <glib.h>
+
+#include "nact-action.h"
+#include "nact-action-profile.h"
 #include "nact-iio-provider.h"
 #include "nact-pivot.h"
 
@@ -152,3 +156,46 @@ nact_iio_provider_load_actions( const GObject *object )
 
 	return( actions );
 }
+
+/**
+ * Writes an action to a willing-to storage subsystem.
+ *
+ * @obj_pivot: the pivot object which owns the list of registered
+ * interface providers.
+ *
+ * @obj_action: the action to be written.
+ *
+ * @message: the I/O provider can allocate and store here an error
+ * message.
+ *
+ * Returns TRUE if the write is successfull, FALSE else.
+ */
+gboolean
+nact_iio_provider_write_action( const GObject *obj_pivot, const GObject *obj_action, gchar **message )
+{
+	static const gchar *thisfn = "nact_iio_provider_write_action";
+	g_debug( "%s", thisfn );
+
+	g_assert( NACT_IS_PIVOT( obj_pivot ));
+	NactPivot *pivot = NACT_PIVOT( obj_pivot );
+
+	g_assert( NACT_IS_ACTION( obj_action ));
+
+	gboolean ret = TRUE;
+	GSList *ip;
+	NactIIOProvider *instance;
+
+	GSList *providers = nact_pivot_get_providers( pivot, NACT_IIO_PROVIDER_TYPE );
+
+	for( ip = providers ; ip ; ip = ip->next ){
+
+		instance = NACT_IIO_PROVIDER( ip->data );
+
+		/*if( NACT_IIO_PROVIDER_GET_INTERFACE( instance )->write_action ){
+			list = NACT_IIO_PROVIDER_GET_INTERFACE( instance )->load_actions( instance );
+			actions = g_slist_concat( actions, list );
+		}*/
+	}
+
+	return( ret );
+}
diff --git a/src/common/nact-iio-provider.h b/src/common/nact-iio-provider.h
index b58697b..1d747e4 100644
--- a/src/common/nact-iio-provider.h
+++ b/src/common/nact-iio-provider.h
@@ -61,12 +61,14 @@ typedef struct {
 
 	/* i/o api */
 	GSList * ( *load_actions )( NactIIOProvider *instance );
+	gboolean ( *write_action )( NactIIOProvider *instance, const GObject *action, gchar **message );
 }
 	NactIIOProviderInterface;
 
-GType   nact_iio_provider_get_type( void );
+GType    nact_iio_provider_get_type( void );
 
-GSList *nact_iio_provider_load_actions( const GObject *pivot );
+GSList  *nact_iio_provider_load_actions( const GObject *pivot );
+gboolean nact_iio_provider_write_action( const GObject *pivot, const GObject *action, gchar **message );
 
 G_END_DECLS
 
diff --git a/src/common/nact-pivot.c b/src/common/nact-pivot.c
index 5a162dc..83a2c67 100644
--- a/src/common/nact-pivot.c
+++ b/src/common/nact-pivot.c
@@ -33,6 +33,7 @@
 #endif
 
 #include <string.h>
+#include <uuid/uuid.h>
 
 #include "nact-action.h"
 #include "nact-gconf.h"
@@ -99,6 +100,7 @@ static void        instance_dispose( GObject *object );
 static void        instance_finalize( GObject *object );
 
 static void        free_actions( GSList *list );
+static gint        sort_actions_by_label( gconstpointer a1, gconstpointer a2 );
 static void        action_changed_handler( NactPivot *pivot, gpointer user_data );
 static gboolean    on_action_changed_timeout( gpointer user_data );
 static gulong      time_val_diff( const GTimeVal *recent, const GTimeVal *old );
@@ -326,7 +328,28 @@ nact_pivot_get_providers( const NactPivot *pivot, GType type )
 }
 
 /**
+ * Return the list of actions, sorted by label.
+ *
+ * @pivot: this NactPivot object.
+ *
+ * The returned list is owned by this NactPivot object, and should not
+ * be freed, nor unref by the caller.
+ */
+GSList *
+nact_pivot_get_label_sorted_actions( const NactPivot *pivot )
+{
+	g_assert( NACT_IS_PIVOT( pivot ));
+	GSList *sorted = g_slist_sort( pivot->private->actions, ( GCompareFunc ) sort_actions_by_label );
+	return( sorted );
+}
+
+/**
  * Return the list of actions.
+ *
+ * @pivot: this NactPivot object.
+ *
+ * The returned list is owned by this NactPivot object, and should not
+ * be freed, nor unref by the caller.
  */
 GSList *
 nact_pivot_get_actions( const NactPivot *pivot )
@@ -345,6 +368,82 @@ free_actions( GSList *list )
 	g_slist_free( list );
 }
 
+static gint
+sort_actions_by_label( gconstpointer a1, gconstpointer a2 )
+{
+	NactAction *action1 = NACT_ACTION( a1 );
+	gchar *label1 = nact_action_get_label( action1 );
+
+	NactAction *action2 = NACT_ACTION( a2 );
+	gchar *label2 = nact_action_get_label( action2 );
+
+	gint ret = g_utf8_collate( label1, label2 );
+
+	g_free( label1 );
+	g_free( label2 );
+
+	return( ret );
+}
+
+/**
+ * Return the specified action.
+ *
+ * @pivot: this NactPivot object.
+ *
+ * @uuid: required globally unique identifier (uuid).
+ *
+ * Returns the specified NactAction object, or NULL if not found.
+ *
+ * The returned pointer is owned by NactPivot, and should not be freed
+ * nor unref by the caller.
+ */
+GObject *
+nact_pivot_get_action( NactPivot *pivot, const gchar *uuid )
+{
+	GSList *ia;
+	NactAction *act;
+	GObject *found = NULL;
+	uuid_t uua, uub;
+	gchar *uuid_act;
+
+	g_assert( NACT_IS_PIVOT( pivot ));
+
+	uuid_parse( uuid, uua );
+	for( ia = pivot->private->actions ; ia ; ia = ia->next ){
+		act = NACT_ACTION( ia->data );
+		uuid_act = nact_action_get_uuid( act );
+		uuid_parse( uuid_act, uub );
+		g_free( uuid_act );
+		if( !uuid_compare( uua, uub )){
+			found = G_OBJECT( act );
+			break;
+		}
+	}
+
+	return( found );
+}
+
+/**
+ * Write an action.
+ *
+ * @pivot: this NactPivot object.
+ *
+ * @action: action to be written by the storage subsystem.
+ *
+ * @message: the I/O provider can allocate and store here an error
+ * message.
+ *
+ * Returns TRUE if the write is successfull, FALSE else.
+ */
+gboolean
+nact_pivot_add_action( NactPivot *pivot, const GObject *action, gchar **message )
+{
+	g_assert( NACT_IS_PIVOT( pivot ));
+	g_assert( NACT_IS_ACTION( action ));
+	g_assert( message );
+	return( nact_iio_provider_write_action( G_OBJECT( pivot ), action, message ));
+}
+
 /*
  * this handler is trigerred by IIOProviders when an action is changed
  * in the underlying storage subsystems
diff --git a/src/common/nact-pivot.h b/src/common/nact-pivot.h
index 81299c0..26ed1dd 100644
--- a/src/common/nact-pivot.h
+++ b/src/common/nact-pivot.h
@@ -73,8 +73,13 @@ NactPivot *nact_pivot_new( const GObject *notified );
 
 GSList    *nact_pivot_get_providers( const NactPivot *pivot, GType type );
 
+GSList    *nact_pivot_get_label_sorted_actions( const NactPivot *pivot );
 GSList    *nact_pivot_get_actions( const NactPivot *pivot );
 
+GObject   *nact_pivot_get_action( NactPivot *pivot, const gchar *uuid );
+
+gboolean   nact_pivot_add_action( NactPivot *pivot, const GObject *action, gchar **message );
+
 /* data passed from the storage subsystem when an action is changed
  */
 enum {
diff --git a/src/nact/Makefile.am b/src/nact/Makefile.am
index 615a929..5bce652 100644
--- a/src/nact/Makefile.am
+++ b/src/nact/Makefile.am
@@ -40,6 +40,8 @@ AM_CPPFLAGS += \
 	$(NULL)
 
 nautilus_actions_config_SOURCES = \
+	base-application.c									\
+	base-application.h									\
 	nact.c												\
 	nact.h												\
 	nact-application.c									\
diff --git a/src/nact/base-application.c b/src/nact/base-application.c
new file mode 100644
index 0000000..74f910b
--- /dev/null
+++ b/src/nact/base-application.c
@@ -0,0 +1,830 @@
+/*
+ * 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 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 <glib/gi18n.h>
+#include <string.h>
+#include <unique/unique.h>
+
+#include "base-application.h"
+
+/* private class data
+ */
+struct BaseApplicationClassPrivate {
+};
+
+/* private instance data
+ */
+struct BaseApplicationPrivate {
+	gboolean   dispose_has_run;
+	int        argc;
+	gpointer   argv;
+	gchar     *unique_name;
+	UniqueApp *unique_app;
+	gchar     *application_name;
+	gchar     *icon_name;
+	GtkWindow *main_window;
+};
+
+/* private instance properties
+ */
+enum {
+	PROP_ARGC = 1,
+	PROP_ARGV,
+	PROP_UNIQUE_NAME,
+	PROP_UNIQUE_APP,
+	PROP_MAIN_WINDOW,
+	PROP_APPLICATION_NAME,
+	PROP_ICON_NAME
+};
+
+#define PROP_ARGC_STR					"argc"
+#define PROP_ARGV_STR					"argv"
+#define PROP_UNIQUE_NAME_STR			"unique-name"
+#define PROP_UNIQUE_APP_STR				"unique-app"
+#define PROP_MAIN_WINDOW_STR			"main-window"
+#define PROP_APPLICATION_NAME_STR		"application-name"
+#define PROP_ICON_NAME_STR				"icon-name"
+
+static GObjectClass *st_parent_class = NULL;
+
+static GType          register_type( void );
+static void           class_init( BaseApplicationClass *klass );
+static void           instance_init( GTypeInstance *instance, gpointer klass );
+static void           instance_get_property( GObject *object, guint property_id, GValue *value, GParamSpec *spec );
+static void           instance_set_property( GObject *object, guint property_id, const GValue *value, GParamSpec *spec );
+static void           instance_dispose( GObject *application );
+static void           instance_finalize( GObject *application );
+
+static int            do_run( BaseApplication *application );
+
+static void           v_initialize( BaseApplication *application );
+static void           v_initialize_i18n( BaseApplication *application );
+static void           v_initialize_gtk( BaseApplication *application );
+static void           v_initialize_application_name( BaseApplication *application );
+static void           v_initialize_icon_name( BaseApplication *application );
+static void           v_initialize_unique( BaseApplication *application );
+static gboolean       v_is_willing_to_run( BaseApplication *application );
+static void           v_advertise_willing_to_run( BaseApplication *application );
+static void           v_advertise_not_willing_to_run( BaseApplication *application );
+static void           v_start( BaseApplication *application );
+static int            v_finish( BaseApplication *application );
+static gchar         *v_get_unique_name( BaseApplication *application );
+static gchar         *v_get_application_name( BaseApplication *application );
+static gchar         *v_get_icon_name( BaseApplication *application );
+
+static void           do_initialize( BaseApplication *application );
+static void           do_initialize_i18n( BaseApplication *application );
+static void           do_initialize_gtk( BaseApplication *application );
+static void           do_initialize_application_name( BaseApplication *application );
+static void           do_initialize_icon_name( BaseApplication *application );
+static void           do_initialize_unique( BaseApplication *application );
+static gboolean       is_willing_to_run( BaseApplication *application );
+static gboolean       check_for_unique_app( BaseApplication *application );
+static void           do_advertise_willing_to_run( BaseApplication *application );
+static void           do_advertise_not_willing_to_run( BaseApplication *application );
+static void           do_start( BaseApplication *application );
+static int            do_finish( BaseApplication *application );
+static gchar         *do_get_unique_name( BaseApplication *application );
+static gchar         *do_get_application_name( BaseApplication *application );
+static gchar         *do_get_icon_name( BaseApplication *application );
+
+/*static UniqueResponse on_unique_message_received( UniqueApp *app, UniqueCommand command, UniqueMessageData *message, guint time, gpointer user_data );*/
+
+GType
+base_application_get_type( void )
+{
+	static GType application_type = 0;
+
+	if( !application_type ){
+		application_type = register_type();
+	}
+
+	return( application_type );
+}
+
+static GType
+register_type( void )
+{
+	static const gchar *thisfn = "base_application_register_type";
+	g_debug( "%s", thisfn );
+
+	g_type_init();
+
+	static GTypeInfo info = {
+		sizeof( BaseApplicationClass ),
+		( GBaseInitFunc ) NULL,
+		( GBaseFinalizeFunc ) NULL,
+		( GClassInitFunc ) class_init,
+		NULL,
+		NULL,
+		sizeof( BaseApplication ),
+		0,
+		( GInstanceInitFunc ) instance_init
+	};
+
+	return( g_type_register_static( G_TYPE_OBJECT, "BaseApplication", &info, 0 ));
+}
+
+static void
+class_init( BaseApplicationClass *klass )
+{
+	static const gchar *thisfn = "base_application_class_init";
+	g_debug( "%s: klass=%p", thisfn, klass );
+
+	st_parent_class = g_type_class_peek_parent( klass );
+
+	GObjectClass *object_class = G_OBJECT_CLASS( klass );
+	object_class->dispose = instance_dispose;
+	object_class->finalize = instance_finalize;
+	object_class->get_property = instance_get_property;
+	object_class->set_property = instance_set_property;
+
+	GParamSpec *spec;
+	spec = g_param_spec_int(
+			PROP_ARGC_STR,
+			PROP_ARGC_STR,
+			"Command-line arguments count", 0, 65535, 0,
+			G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE );
+	g_object_class_install_property( object_class, PROP_ARGC, spec );
+
+	spec = g_param_spec_pointer(
+			PROP_ARGV_STR,
+			PROP_ARGV_STR,
+			"Command-line arguments",
+			G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE );
+	g_object_class_install_property( object_class, PROP_ARGV, spec );
+
+	spec = g_param_spec_string(
+			PROP_UNIQUE_NAME_STR,
+			PROP_UNIQUE_NAME_STR,
+			"DBUS name for unique application", "",
+			G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE );
+	g_object_class_install_property( object_class, PROP_UNIQUE_NAME, spec );
+
+	spec = g_param_spec_pointer(
+			PROP_UNIQUE_APP_STR,
+			PROP_UNIQUE_APP_STR,
+			"UniqueApp object pointer",
+			G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE );
+	g_object_class_install_property( object_class, PROP_UNIQUE_APP, spec );
+
+	spec = g_param_spec_pointer(
+			PROP_MAIN_WINDOW_STR,
+			PROP_MAIN_WINDOW_STR,
+			"Main window widget",
+			G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE );
+	g_object_class_install_property( object_class, PROP_MAIN_WINDOW, spec );
+
+	spec = g_param_spec_string(
+			PROP_APPLICATION_NAME_STR,
+			PROP_APPLICATION_NAME_STR,
+			"Localized application name", "",
+			G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE );
+	g_object_class_install_property( object_class, PROP_APPLICATION_NAME, spec );
+
+	spec = g_param_spec_string(
+			PROP_ICON_NAME_STR,
+			PROP_ICON_NAME_STR,
+			"Default themed icon name", "",
+			G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE );
+	g_object_class_install_property( object_class, PROP_ICON_NAME, spec );
+
+	klass->private = g_new0( BaseApplicationClassPrivate, 1 );
+
+	klass->run = do_run;
+	klass->initialize = do_initialize;
+	klass->initialize_i18n = do_initialize_i18n;
+	klass->initialize_gtk = do_initialize_gtk;
+	klass->initialize_application_name = do_initialize_application_name;
+	klass->initialize_icon_name = do_initialize_icon_name;
+	klass->initialize_unique = do_initialize_unique;
+	klass->is_willing_to_run = is_willing_to_run;
+	klass->advertise_willing_to_run = do_advertise_willing_to_run;
+	klass->advertise_not_willing_to_run = do_advertise_not_willing_to_run;
+	klass->start = do_start;
+	klass->finish = do_finish;
+	klass->get_unique_name = do_get_unique_name;
+	klass->get_application_name = do_get_application_name;
+	klass->get_icon_name = do_get_icon_name;
+}
+
+static void
+instance_init( GTypeInstance *instance, gpointer klass )
+{
+	static const gchar *thisfn = "base_application_instance_init";
+	g_debug( "%s: instance=%p, klass=%p", thisfn, instance, klass );
+
+	g_assert( BASE_IS_APPLICATION( instance ));
+	BaseApplication *self = BASE_APPLICATION( instance );
+
+	self->private = g_new0( BaseApplicationPrivate, 1 );
+
+	self->private->dispose_has_run = FALSE;
+}
+
+static void
+instance_get_property( GObject *object, guint property_id, GValue *value, GParamSpec *spec )
+{
+	g_assert( BASE_IS_APPLICATION( object ));
+	BaseApplication *self = BASE_APPLICATION( object );
+
+	switch( property_id ){
+		case PROP_ARGC:
+			g_value_set_int( value, self->private->argc );
+			break;
+
+		case PROP_ARGV:
+			g_value_set_pointer( value, self->private->argv );
+			break;
+
+		case PROP_UNIQUE_NAME:
+			g_value_set_string( value, self->private->unique_name );
+			break;
+
+		case PROP_UNIQUE_APP:
+			g_value_set_pointer( value, self->private->unique_app );
+			break;
+
+		case PROP_MAIN_WINDOW:
+			g_value_set_pointer( value, self->private->main_window );
+			break;
+
+		case PROP_APPLICATION_NAME:
+			g_value_set_string( value, self->private->application_name );
+			break;
+
+		case PROP_ICON_NAME:
+			g_value_set_string( value, self->private->icon_name );
+			break;
+
+		default:
+			G_OBJECT_WARN_INVALID_PROPERTY_ID( object, property_id, spec );
+			break;
+	}
+}
+
+static void
+instance_set_property( GObject *object, guint property_id, const GValue *value, GParamSpec *spec )
+{
+	g_assert( BASE_IS_APPLICATION( object ));
+	BaseApplication *self = BASE_APPLICATION( object );
+
+	switch( property_id ){
+		case PROP_ARGC:
+			self->private->argc = g_value_get_int( value );
+			break;
+
+		case PROP_ARGV:
+			self->private->argv = g_value_get_pointer( value );
+			break;
+
+		case PROP_UNIQUE_NAME:
+			g_free( self->private->unique_name );
+			self->private->unique_name = g_value_dup_string( value );
+			break;
+
+		case PROP_UNIQUE_APP:
+			self->private->unique_app = g_value_get_pointer( value );
+			break;
+
+		case PROP_MAIN_WINDOW:
+			self->private->main_window = g_value_get_pointer( value );
+			break;
+
+		case PROP_APPLICATION_NAME:
+			g_free( self->private->application_name );
+			self->private->application_name = g_value_dup_string( value );
+			break;
+
+		case PROP_ICON_NAME:
+			g_free( self->private->icon_name );
+			self->private->icon_name = g_value_dup_string( value );
+			break;
+
+		default:
+			G_OBJECT_WARN_INVALID_PROPERTY_ID( object, property_id, spec );
+			break;
+	}
+}
+
+static void
+instance_dispose( GObject *application )
+{
+	static const gchar *thisfn = "base_application_instance_dispose";
+	g_debug( "%s: application=%p", thisfn, application );
+
+	g_assert( BASE_IS_APPLICATION( application ));
+	BaseApplication *self = BASE_APPLICATION( application );
+
+	if( !self->private->dispose_has_run ){
+
+		self->private->dispose_has_run = TRUE;
+
+		g_object_unref( self->private->unique_app );
+		g_object_unref( self->private->main_window );
+
+		/* chain up to the parent class */
+		G_OBJECT_CLASS( st_parent_class )->dispose( application );
+	}
+}
+
+static void
+instance_finalize( GObject *application )
+{
+	static const gchar *thisfn = "base_application_instance_finalize";
+	g_debug( "%s: application=%p", thisfn, application );
+
+	g_assert( BASE_IS_APPLICATION( application ));
+	BaseApplication *self = ( BaseApplication * ) application;
+
+	g_free( self->private->unique_name );
+	g_free( self->private->application_name );
+	g_free( self->private->icon_name );
+
+	/* chain call to parent class */
+	if( st_parent_class->finalize ){
+		G_OBJECT_CLASS( st_parent_class )->finalize( application );
+	}
+}
+
+/**
+ * Returns a newly allocated BaseApplication object.
+ */
+BaseApplication *
+base_application_new( void )
+{
+	return( g_object_new( BASE_APPLICATION_TYPE, NULL ));
+}
+
+/**
+ * Returns a newly allocated BaseApplication object.
+ *
+ * @argc: count of command-line arguments.
+ *
+ * @argv: command-line arguments.
+ */
+BaseApplication *
+base_application_new_with_args( int argc, char **argv )
+{
+	return( g_object_new( BASE_APPLICATION_TYPE, PROP_ARGC_STR, argc, PROP_ARGV_STR, argv, NULL ));
+}
+
+/**
+ * Executes the application.
+ *
+ * @application: the considered BaseApplication object.
+ *
+ * The returned integer should be returned to the OS.
+ *
+ * This a the main function management of the application. We iniialize
+ * it, test command line options, if it is willing to run, then start
+ * it and finally finish it.
+ *
+ * All these steps are implemented by virtual functions which provider
+ * some suitable defaults, and can be overriden by a derived class.
+ */
+int
+base_application_run( BaseApplication *application )
+{
+	static const gchar *thisfn = "base_application_run";
+	g_debug( "%s: application=%p", thisfn, application );
+
+	g_assert( BASE_IS_APPLICATION( application ));
+
+	return( BASE_APPLICATION_GET_CLASS( application )->run( application ));
+}
+
+static int
+do_run( BaseApplication *application )
+{
+	static const gchar *thisfn = "base_application_do_run";
+	g_debug( "%s: application=%p", thisfn, application );
+
+	g_assert( BASE_IS_APPLICATION( application ));
+
+	int code = 0;
+
+	v_initialize( application );
+
+	if( v_is_willing_to_run( application )){
+
+		v_advertise_willing_to_run( application );
+		v_start( application );
+		code = v_finish( application );
+
+	} else {
+
+		v_advertise_not_willing_to_run( application );
+
+	}
+
+	return( code );
+}
+
+static void
+v_initialize( BaseApplication *application )
+{
+	static const gchar *thisfn = "base_application_v_initialize";
+	g_debug( "%s: application=%p", thisfn, application );
+
+	g_assert( BASE_IS_APPLICATION( application ));
+
+	BASE_APPLICATION_GET_CLASS( application )->initialize( application );
+}
+
+static void
+v_initialize_i18n( BaseApplication *application )
+{
+	static const gchar *thisfn = "base_application_v_initialize_i18n";
+	g_debug( "%s: application=%p", thisfn, application );
+
+	g_assert( BASE_IS_APPLICATION( application ));
+
+	BASE_APPLICATION_GET_CLASS( application )->initialize_i18n( application );
+}
+
+static void
+v_initialize_gtk( BaseApplication *application )
+{
+	static const gchar *thisfn = "base_application_v_initialize_gtk";
+	g_debug( "%s: application=%p", thisfn, application );
+
+	g_assert( BASE_IS_APPLICATION( application ));
+
+	BASE_APPLICATION_GET_CLASS( application )->initialize_gtk( application );
+}
+
+static void
+v_initialize_application_name( BaseApplication *application )
+{
+	static const gchar *thisfn = "base_application_v_initialize_application_name";
+	g_debug( "%s: application=%p", thisfn, application );
+
+	g_assert( BASE_IS_APPLICATION( application ));
+
+	BASE_APPLICATION_GET_CLASS( application )->initialize_application_name( application );
+}
+
+static void
+v_initialize_icon_name( BaseApplication *application )
+{
+	static const gchar *thisfn = "base_application_v_initialize_icon_name";
+	g_debug( "%s: application=%p", thisfn, application );
+
+	g_assert( BASE_IS_APPLICATION( application ));
+
+	BASE_APPLICATION_GET_CLASS( application )->initialize_icon_name( application );
+}
+
+static void
+v_initialize_unique( BaseApplication *application )
+{
+	static const gchar *thisfn = "base_application_v_initialize_unique";
+	g_debug( "%s: application=%p", thisfn, application );
+
+	g_assert( BASE_IS_APPLICATION( application ));
+
+	BASE_APPLICATION_GET_CLASS( application )->initialize_unique( application );
+}
+
+static gboolean
+v_is_willing_to_run( BaseApplication *application )
+{
+	static const gchar *thisfn = "base_application_v_is_willing_to_run";
+	g_debug( "%s: application=%p", thisfn, application );
+
+	g_assert( BASE_IS_APPLICATION( application ));
+
+	return( BASE_APPLICATION_GET_CLASS( application )->is_willing_to_run( application ));
+}
+
+static void
+v_advertise_willing_to_run( BaseApplication *application )
+{
+	static const gchar *thisfn = "base_application_v_advertise_willing_to_run";
+	g_debug( "%s: application=%p", thisfn, application );
+
+	g_assert( BASE_IS_APPLICATION( application ));
+
+	return( BASE_APPLICATION_GET_CLASS( application )->advertise_willing_to_run( application ));
+}
+
+static void
+v_advertise_not_willing_to_run( BaseApplication *application )
+{
+	static const gchar *thisfn = "base_application_v_advertise_not_willing_to_run";
+	g_debug( "%s: application=%p", thisfn, application );
+
+	g_assert( BASE_IS_APPLICATION( application ));
+
+	return( BASE_APPLICATION_GET_CLASS( application )->advertise_not_willing_to_run( application ));
+}
+
+static void
+v_start( BaseApplication *application )
+{
+	static const gchar *thisfn = "base_application_v_start";
+	g_debug( "%s: application=%p", thisfn, application );
+
+	g_assert( BASE_IS_APPLICATION( application ));
+
+	BASE_APPLICATION_GET_CLASS( application )->start( application );
+}
+
+static int
+v_finish( BaseApplication *application )
+{
+	static const gchar *thisfn = "base_application_v_finish";
+	g_debug( "%s: application=%p", thisfn, application );
+
+	g_assert( BASE_IS_APPLICATION( application ));
+
+	return( BASE_APPLICATION_GET_CLASS( application )->finish( application ));
+}
+
+static gchar *
+v_get_unique_name( BaseApplication *application )
+{
+	static const gchar *thisfn = "base_application_v_get_unique_name";
+	g_debug( "%s: application=%p", thisfn, application );
+
+	g_assert( BASE_IS_APPLICATION( application ));
+
+	gchar *name;
+	g_object_get( G_OBJECT( application ), PROP_UNIQUE_NAME_STR, &name, NULL );
+
+	if( !name || !strlen( name )){
+		name = BASE_APPLICATION_GET_CLASS( application )->get_unique_name( application );
+		if( name && strlen( name )){
+			g_object_set( G_OBJECT( application ), PROP_UNIQUE_NAME_STR, name, NULL );
+		}
+	}
+
+	return( name );
+}
+
+static gchar *
+v_get_application_name( BaseApplication *application )
+{
+	static const gchar *thisfn = "base_application_v_get_application_name";
+	g_debug( "%s: application=%p", thisfn, application );
+
+	g_assert( BASE_IS_APPLICATION( application ));
+
+	gchar *name;
+	g_object_get( G_OBJECT( application ), PROP_APPLICATION_NAME_STR, &name, NULL );
+
+	if( !name || !strlen( name )){
+		name = BASE_APPLICATION_GET_CLASS( application )->get_application_name( application );
+		if( name && strlen( name )){
+			g_object_set( G_OBJECT( application ), PROP_APPLICATION_NAME_STR, name, NULL );
+		}
+	}
+
+	return( name );
+}
+
+static gchar *
+v_get_icon_name( BaseApplication *application )
+{
+	static const gchar *thisfn = "base_application_v_get_icon_name";
+	g_debug( "%s: icon=%p", thisfn, application );
+
+	g_assert( BASE_IS_APPLICATION( application ));
+
+	gchar *name;
+	g_object_get( G_OBJECT( application ), PROP_ICON_NAME_STR, &name, NULL );
+
+	if( !name || !strlen( name )){
+		name = BASE_APPLICATION_GET_CLASS( application )->get_icon_name( application );
+		if( name && strlen( name )){
+			g_object_set( G_OBJECT( application ), PROP_ICON_NAME_STR, name, NULL );
+		}
+	}
+
+	return( name );
+}
+
+static void
+do_initialize( BaseApplication *application )
+{
+	v_initialize_i18n( application );
+	v_initialize_gtk( application );
+	v_initialize_application_name( application );
+	v_initialize_icon_name( application );
+	v_initialize_unique( application );
+}
+
+static void
+do_initialize_i18n( BaseApplication *application )
+{
+#ifdef ENABLE_NLS
+        bindtextdomain( GETTEXT_PACKAGE, GNOMELOCALEDIR );
+# ifdef HAVE_BIND_TEXTDOMAIN_CODESET
+        bind_textdomain_codeset( GETTEXT_PACKAGE, "UTF-8" );
+# endif
+        textdomain( GETTEXT_PACKAGE );
+#endif
+}
+
+static void
+do_initialize_gtk( BaseApplication *application )
+{
+	int argc;
+	gpointer argv;
+	g_object_get( G_OBJECT( application ), PROP_ARGC_STR, &argc, PROP_ARGV_STR, &argv, NULL );
+	gtk_init( &argc, ( char *** ) &argv );
+	g_object_set( G_OBJECT( application ), PROP_ARGC_STR, argc, PROP_ARGV_STR, argv, NULL );
+}
+
+static void
+do_initialize_application_name( BaseApplication *application )
+{
+	gchar *name = v_get_application_name( application );
+	if( name && strlen( name )){
+		g_set_application_name( name );
+	}
+	g_free( name );
+}
+
+static void
+do_initialize_icon_name( BaseApplication *application )
+{
+	gchar *name = v_get_icon_name( application );
+	if( name && strlen( name )){
+		gtk_window_set_default_icon_name( name );
+	}
+	g_free( name );
+}
+
+static void
+do_initialize_unique( BaseApplication *application )
+{
+	gchar *unique_name = v_get_unique_name( application );
+
+	if( unique_name && strlen( unique_name )){
+		application->private->unique_app = unique_app_new( unique_name, NULL );
+	}
+
+	g_free( unique_name );
+}
+
+static gboolean
+is_willing_to_run( BaseApplication *application )
+{
+	gboolean is_willing = TRUE;
+
+	if( application->private->unique_app ){
+		is_willing = check_for_unique_app( application );
+	}
+
+	return( is_willing );
+}
+
+/*
+ * returns TRUE if we are the first instance
+ */
+static gboolean
+check_for_unique_app( BaseApplication *application )
+{
+	gboolean is_first = TRUE;
+
+	g_assert( BASE_IS_APPLICATION( application ));
+
+	if( unique_app_is_running( application->private->unique_app )){
+
+		is_first = FALSE;
+
+		unique_app_send_message( application->private->unique_app, UNIQUE_ACTIVATE, NULL );
+
+	/* default from libunique is actually to activate the first window
+	 * so we rely on the default..
+	 */
+	/*} else {
+		g_signal_connect(
+				application->private->unique,
+				"message-received",
+				G_CALLBACK( on_unique_message_received ),
+				application
+		);*/
+	}
+
+	return( is_first );
+}
+
+static void
+do_advertise_willing_to_run( BaseApplication *application )
+{
+
+}
+
+static void
+do_advertise_not_willing_to_run( BaseApplication *application )
+{
+
+}
+
+static void
+do_start( BaseApplication *application )
+{
+	if( application->private->unique_app && application->private->main_window ){
+		unique_app_watch_window( application->private->unique_app, application->private->main_window );
+	}
+
+	gtk_main();
+}
+
+static int
+do_finish( BaseApplication *application )
+{
+	int code = 0;
+	return( code );
+}
+
+static gchar *
+do_get_unique_name( BaseApplication *application )
+{
+	return( NULL );
+}
+
+static gchar *
+do_get_application_name( BaseApplication *application )
+{
+	return( NULL );
+}
+
+static gchar *
+do_get_icon_name( BaseApplication *application )
+{
+	return( NULL );
+}
+
+/*static UniqueResponse
+on_unique_message_received(
+		UniqueApp *app, UniqueCommand command, UniqueMessageData *message, guint time, gpointer user_data )
+{
+	static const gchar *thisfn = "base_application_check_for_unique_app";
+	UniqueResponse resp = UNIQUE_RESPONSE_OK;
+
+	switch( command ){
+		case UNIQUE_ACTIVATE:
+			g_debug( "%s: received message UNIQUE_ACTIVATE", thisfn );
+			break;
+		default:
+			resp = UNIQUE_RESPONSE_PASSTHROUGH;
+			break;
+	}
+
+	return( resp );
+}*/
+
+void
+base_application_error_dlg(
+		BaseApplication *application, GtkMessageType type, gchar *primary, gchar *secondary )
+{
+	g_assert( BASE_IS_APPLICATION( application ));
+
+	GtkWidget *dialog = gtk_message_dialog_new(
+			NULL, GTK_DIALOG_MODAL, type, GTK_BUTTONS_OK, primary );
+
+	gtk_message_dialog_format_secondary_text( GTK_MESSAGE_DIALOG( dialog ), secondary );
+
+	const gchar *name = g_get_application_name();
+
+	g_object_set( G_OBJECT( dialog ) , "title", name, NULL );
+
+	gtk_dialog_run( GTK_DIALOG( dialog ));
+
+	gtk_widget_destroy( dialog );
+}
diff --git a/src/nact/base-application.h b/src/nact/base-application.h
new file mode 100644
index 0000000..bf1575c
--- /dev/null
+++ b/src/nact/base-application.h
@@ -0,0 +1,96 @@
+/*
+ * 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 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 __BASE_APPLICATION_H__
+#define __BASE_APPLICATION_H__
+
+/*
+ * BaseApplication class definition.
+ *
+ * This is a base class for Gtk+ programs.
+ */
+
+#include <glib-object.h>
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define BASE_APPLICATION_TYPE					( base_application_get_type())
+#define BASE_APPLICATION( object )				( G_TYPE_CHECK_INSTANCE_CAST( object, BASE_APPLICATION_TYPE, BaseApplication ))
+#define BASE_APPLICATION_CLASS( klass )			( G_TYPE_CHECK_CLASS_CAST( klass, BASE_APPLICATION_TYPE, BaseApplicationClass ))
+#define BASE_IS_APPLICATION( object )			( G_TYPE_CHECK_INSTANCE_TYPE( object, BASE_APPLICATION_TYPE ))
+#define BASE_IS_APPLICATION_CLASS( klass )		( G_TYPE_CHECK_CLASS_TYPE(( klass ), BASE_APPLICATION_TYPE ))
+#define BASE_APPLICATION_GET_CLASS( object )	( G_TYPE_INSTANCE_GET_CLASS(( object ), BASE_APPLICATION_TYPE, BaseApplicationClass ))
+
+typedef struct BaseApplicationPrivate BaseApplicationPrivate;
+
+typedef struct {
+	GObject                 parent;
+	BaseApplicationPrivate *private;
+}
+	BaseApplication;
+
+typedef struct BaseApplicationClassPrivate BaseApplicationClassPrivate;
+
+typedef struct {
+	GObjectClass                 parent;
+	BaseApplicationClassPrivate *private;
+
+	/* virtual functions */
+	int      ( *run )                         ( BaseApplication *appli );
+	void     ( *initialize )                  ( BaseApplication *appli );
+	void     ( *initialize_i18n )             ( BaseApplication *appli );
+	void     ( *initialize_gtk )              ( BaseApplication *appli );
+	void     ( *initialize_application_name ) ( BaseApplication *appli );
+	void     ( *initialize_icon_name )        ( BaseApplication *appli );
+	void     ( *initialize_unique )           ( BaseApplication *appli );
+	gboolean ( *is_willing_to_run )           ( BaseApplication *appli );
+	void     ( *advertise_willing_to_run )    ( BaseApplication *appli );
+	void     ( *advertise_not_willing_to_run )( BaseApplication *appli );
+	void     ( *start )                       ( BaseApplication *appli );
+	int      ( *finish )                      ( BaseApplication *appli );
+	gchar  * ( *get_unique_name )             ( BaseApplication *appli );
+	gchar  * ( *get_application_name )        ( BaseApplication *appli );
+	gchar  * ( *get_icon_name )               ( BaseApplication *appli );
+}
+	BaseApplicationClass;
+
+GType            base_application_get_type( void );
+
+BaseApplication *base_application_new( void );
+BaseApplication *base_application_new_with_args( int argc, char **argv );
+
+int              base_application_run( BaseApplication *application );
+
+void             base_application_error_dlg( BaseApplication *application, GtkMessageType type, gchar *primary, gchar *secondary );
+
+G_END_DECLS
+
+#endif /* __BASE_APPLICATION_H__ */
diff --git a/src/nact/nact-application.c b/src/nact/nact-application.c
index 3eb7987..35cb239 100644
--- a/src/nact/nact-application.c
+++ b/src/nact/nact-application.c
@@ -34,8 +34,8 @@
 
 #include <glib/gi18n.h>
 #include <gtk/gtk.h>
-#include <unique/unique.h>
 
+#include <common/nact-pivot.h>
 #include "nact.h"
 #include "nact-application.h"
 
@@ -48,39 +48,31 @@ struct NactApplicationClassPrivate {
  */
 struct NactApplicationPrivate {
 	gboolean   dispose_has_run;
-	int        argc;
-	gpointer   argv;
-	UniqueApp *unique;
-	GtkWindow *main;
+	NactPivot *pivot;
 };
 
 /* private instance properties
  */
 enum {
-	PROP_ARGC = 1,
-	PROP_ARGV
+	PROP_PIVOT = 1
 };
 
-#define PROP_ARGC_STR		"argc"
-#define PROP_ARGV_STR		"argv"
+#define PROP_PIVOT_STR					"pivot"
 
 static GObjectClass *st_parent_class = NULL;
 
-static GType          register_type( void );
-static void           class_init( NactApplicationClass *klass );
-static void           instance_init( GTypeInstance *instance, gpointer klass );
-static void           instance_get_property( GObject *object, guint property_id, GValue *value, GParamSpec *spec );
-static void           instance_set_property( GObject *object, guint property_id, const GValue *value, GParamSpec *spec );
-static void           instance_dispose( GObject *application );
-static void           instance_finalize( GObject *application );
-
-/*static UniqueResponse on_unique_message_received( UniqueApp *app, UniqueCommand command, UniqueMessageData *message, guint time, gpointer user_data );*/
-static void           warn_other_instance( NactApplication *application );
-static gboolean       check_for_unique_app( NactApplication *application );
-static void           initialize_i18n( NactApplication *application );
-static gboolean       startup_appli( NactApplication *application );
-static int            run_appli( NactApplication *application );
-static void           finish_appli( NactApplication *application );
+static GType  register_type( void );
+static void   class_init( NactApplicationClass *klass );
+static void   instance_init( GTypeInstance *instance, gpointer klass );
+static void   instance_get_property( GObject *object, guint property_id, GValue *value, GParamSpec *spec );
+static void   instance_set_property( GObject *object, guint property_id, const GValue *value, GParamSpec *spec );
+static void   instance_dispose( GObject *application );
+static void   instance_finalize( GObject *application );
+
+static void   warn_other_instance( BaseApplication *application );
+static gchar *get_application_name( BaseApplication *application );
+static gchar *get_icon_name( BaseApplication *application );
+static gchar *get_unique_name( BaseApplication *application );
 
 GType
 nact_application_get_type( void )
@@ -112,7 +104,7 @@ register_type( void )
 		( GInstanceInitFunc ) instance_init
 	};
 
-	return( g_type_register_static( G_TYPE_OBJECT, "NactApplication", &info, 0 ));
+	return( g_type_register_static( BASE_APPLICATION_TYPE, "NactApplication", &info, 0 ));
 }
 
 static void
@@ -130,21 +122,21 @@ class_init( NactApplicationClass *klass )
 	object_class->set_property = instance_set_property;
 
 	GParamSpec *spec;
-	spec = g_param_spec_int(
-			PROP_ARGC_STR,
-			PROP_ARGC_STR,
-			"Command-line arguments count", 0, 65535, 0,
-			G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE );
-	g_object_class_install_property( object_class, PROP_ARGC, spec );
-
 	spec = g_param_spec_pointer(
-			PROP_ARGV_STR,
-			PROP_ARGV_STR,
-			"Command-line arguments",
-			G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE );
-	g_object_class_install_property( object_class, PROP_ARGV, spec );
+			PROP_PIVOT_STR,
+			PROP_PIVOT_STR,
+			"NactPivot object pointer",
+			G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE );
+	g_object_class_install_property( object_class, PROP_PIVOT, spec );
 
 	klass->private = g_new0( NactApplicationClassPrivate, 1 );
+
+	BaseApplicationClass *appli_class = BASE_APPLICATION_CLASS( klass );
+
+	appli_class->advertise_not_willing_to_run = warn_other_instance;
+	appli_class->get_application_name = get_application_name;
+	appli_class->get_icon_name = get_icon_name;
+	appli_class->get_unique_name = get_unique_name;
 }
 
 static void
@@ -159,8 +151,6 @@ instance_init( GTypeInstance *instance, gpointer klass )
 	self->private = g_new0( NactApplicationPrivate, 1 );
 
 	self->private->dispose_has_run = FALSE;
-
-	self->private->unique = unique_app_new( "org.nautilus-actions.Config", NULL );
 }
 
 static void
@@ -170,12 +160,8 @@ instance_get_property( GObject *object, guint property_id, GValue *value, GParam
 	NactApplication *self = NACT_APPLICATION( object );
 
 	switch( property_id ){
-		case PROP_ARGC:
-			g_value_set_int( value, self->private->argc );
-			break;
-
-		case PROP_ARGV:
-			g_value_set_pointer( value, self->private->argv );
+		case PROP_PIVOT:
+			g_value_set_pointer( value, self->private->pivot );
 			break;
 
 		default:
@@ -191,12 +177,8 @@ instance_set_property( GObject *object, guint property_id, const GValue *value,
 	NactApplication *self = NACT_APPLICATION( object );
 
 	switch( property_id ){
-		case PROP_ARGC:
-			self->private->argc = g_value_get_int( value );
-			break;
-
-		case PROP_ARGV:
-			self->private->argv = g_value_get_pointer( value );
+		case PROP_PIVOT:
+			self->private->pivot = g_value_get_pointer( value );
 			break;
 
 		default:
@@ -218,7 +200,7 @@ instance_dispose( GObject *application )
 
 		self->private->dispose_has_run = TRUE;
 
-		g_object_unref( self->private->unique );
+		g_object_unref( self->private->pivot );
 
 		/* chain up to the parent class */
 		G_OBJECT_CLASS( st_parent_class )->dispose( application );
@@ -242,15 +224,6 @@ instance_finalize( GObject *application )
 
 /**
  * Returns a newly allocated NactApplication object.
- */
-NactApplication *
-nact_application_new( void )
-{
-	return( g_object_new( NACT_APPLICATION_TYPE, NULL ));
-}
-
-/**
- * Returns a newly allocated NactApplication object.
  *
  * @argc: count of command-line arguments.
  *
@@ -259,155 +232,62 @@ nact_application_new( void )
 NactApplication *
 nact_application_new_with_args( int argc, char **argv )
 {
-	return( g_object_new( NACT_APPLICATION_TYPE, PROP_ARGC_STR, argc, PROP_ARGV_STR, argv, NULL ));
+	return( g_object_new( NACT_APPLICATION_TYPE, "argc", argc, "argv", argv, NULL ));
 }
 
-/*static UniqueResponse
-on_unique_message_received(
-		UniqueApp *app, UniqueCommand command, UniqueMessageData *message, guint time, gpointer user_data )
-{
-	static const gchar *thisfn = "nact_application_check_for_unique_app";
-	UniqueResponse resp = UNIQUE_RESPONSE_OK;
-
-	switch( command ){
-		case UNIQUE_ACTIVATE:
-			g_debug( "%s: received message UNIQUE_ACTIVATE", thisfn );
-			break;
-		default:
-			resp = UNIQUE_RESPONSE_PASSTHROUGH;
-			break;
-	}
-
-	return( resp );
-}*/
-
 static void
-warn_other_instance( NactApplication *application )
+warn_other_instance( BaseApplication *application )
 {
 	g_assert( NACT_IS_APPLICATION( application ));
-	gchar *msg;
 
-	msg = g_strdup_printf( "<b>%s</b>\n\n%s",
+	base_application_error_dlg(
+			application,
+			GTK_MESSAGE_INFO,
 			_( "Another instance of Nautilus Actions Configurator is already running." ),
 			_( "Please switch back to it." ));
-
-	GtkWidget *dialog = gtk_message_dialog_new_with_markup(
-			NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_INFO, GTK_BUTTONS_OK, msg );
-
-	/* i18n: window title */
-	g_object_set( G_OBJECT( dialog ) , "title", _( "Nautilus Actions" ), NULL );
-
-	gtk_dialog_run( GTK_DIALOG( dialog ));
-
-	gtk_widget_destroy( dialog );
-	g_free( msg );
 }
 
-/*
- * returns TRUE if we are the first instance
- */
-static gboolean
-check_for_unique_app( NactApplication *application )
+static gchar *
+get_application_name( BaseApplication *application )
 {
-	gboolean is_first = TRUE;
-
-	g_assert( NACT_IS_APPLICATION( application ));
-
-	if( unique_app_is_running( application->private->unique )){
-
-		is_first = FALSE;
-
-		unique_app_send_message( application->private->unique, UNIQUE_ACTIVATE, NULL );
-
-		/* the screen is not actually modified, nor the main window is
-		 * switched back to the current screen ; the icon in the deskbar
-		 * applet is just highlighted
-		 * so a message is not too much !
-		 */
-		warn_other_instance( application );
+	static const gchar *thisfn = "nact_application_get_application_name";
+	g_debug( "%s: application=%p", thisfn, application );
 
-	/* default from libunique is actually to activate the first window
-	 * so we rely on the default..
+	/* i18n: this is the application name, used in window title
 	 */
-	/*} else {
-		g_signal_connect(
-				application->private->unique,
-				"message-received",
-				G_CALLBACK( on_unique_message_received ),
-				application
-		);*/
-	}
-
-	return( is_first );
+	return( g_strdup( _( "Nautilus Actions Configuration Tool" )));
 }
 
-static void
-initialize_i18n( NactApplication *application )
+static gchar *
+get_icon_name( BaseApplication *application )
 {
-#ifdef ENABLE_NLS
-        bindtextdomain( GETTEXT_PACKAGE, GNOMELOCALEDIR );
-# ifdef HAVE_BIND_TEXTDOMAIN_CODESET
-        bind_textdomain_codeset( GETTEXT_PACKAGE, "UTF-8" );
-# endif
-        textdomain( GETTEXT_PACKAGE );
-#endif
+	static const gchar *thisfn = "nact_application_get_icon_name";
+	g_debug( "%s: application=%p", thisfn, application );
+
+	return( g_strdup( PACKAGE ));
 }
 
-static gboolean
-startup_appli( NactApplication *application )
+static gchar *
+get_unique_name( BaseApplication *application )
 {
-	int ret;
-
-	initialize_i18n( application );
-
-	g_set_application_name( PACKAGE );
-
-	gtk_window_set_default_icon_name( PACKAGE );
-
-	ret = check_for_unique_app( application );
+	static const gchar *thisfn = "nact_application_get_unique_name";
+	g_debug( "%s: application=%p", thisfn, application );
 
-	return( ret );
+	return( g_strdup( "org.nautilus-actions.ConfigurationTool" ));
 }
 
-static int
+/*static int
 run_appli( NactApplication *application )
 {
 	int code = 0;
 
-	application->private->main = nact_init_dialog();
-	unique_app_watch_window( application->private->unique, application->private->main );
-
-	gtk_main();
-
-	return( code );
-}
-
-static void
-finish_appli( NactApplication *application )
-{
-}
-
-/**
- * This a the whole run management for the NactApplication Object.
- *
- * @app: the considered NactApplication object.
- *
- * The returned integer should be returned to the OS.
- */
-int
-nact_application_run( NactApplication *application )
-{
-	static const gchar *thisfn = "nact_application_run";
-	g_debug( "%s: application=%p", thisfn, application );
+	g_object_set( G_OBJECT( application ), PROP_PIVOT_STR, nact_pivot_new( NULL ), NULL );
 
-	g_assert( NACT_IS_APPLICATION( application ));
+	g_object_set( G_OBJECT( application ), PROP_MAINWINDOW_STR, nact_init_dialog( G_OBJECT( application ), NULL );
 
-	int code = 0;
+	unique_app_watch_window( application->private->unique, application->private->main );
 
-	if( startup_appli( application )){
-		code = run_appli( application );
-		finish_appli( application );
-	}
+	gtk_main();
 
 	return( code );
-}
+}*/
diff --git a/src/nact/nact-application.h b/src/nact/nact-application.h
index be9ee78..58d59b9 100644
--- a/src/nact/nact-application.h
+++ b/src/nact/nact-application.h
@@ -37,7 +37,7 @@
  * This is the main class for UI programs.
  */
 
-#include <glib-object.h>
+#include "base-application.h"
 
 G_BEGIN_DECLS
 
@@ -51,7 +51,7 @@ G_BEGIN_DECLS
 typedef struct NactApplicationPrivate NactApplicationPrivate;
 
 typedef struct {
-	GObject                 parent;
+	BaseApplication         parent;
 	NactApplicationPrivate *private;
 }
 	NactApplication;
@@ -59,18 +59,15 @@ typedef struct {
 typedef struct NactApplicationClassPrivate NactApplicationClassPrivate;
 
 typedef struct {
-	GObjectClass                 parent;
+	BaseApplicationClass         parent;
 	NactApplicationClassPrivate *private;
 }
 	NactApplicationClass;
 
 GType            nact_application_get_type( void );
 
-NactApplication *nact_application_new( void );
 NactApplication *nact_application_new_with_args( int argc, char **argv );
 
-int              nact_application_run( NactApplication *application );
-
 G_END_DECLS
 
 #endif /* __NACT_APPLICATION_H__ */
diff --git a/src/nact/nact-main.c b/src/nact/nact-main.c
index d1ae147..30c7ac4 100644
--- a/src/nact/nact-main.c
+++ b/src/nact/nact-main.c
@@ -39,13 +39,9 @@
 int
 main( int argc, char *argv[] )
 {
-	/* need to gtk_init before unique_app_new (see Bug #585536)
-	 */
-	gtk_init( &argc, &argv );
-
 	NactApplication *app = nact_application_new_with_args( argc, argv );
 
-	int ret = nact_application_run( app );
+	int ret = base_application_run( BASE_APPLICATION( app ));
 
 	g_object_unref( app );
 
diff --git a/src/nact/nact.c b/src/nact/nact.c
index 672790f..6382426 100644
--- a/src/nact/nact.c
+++ b/src/nact/nact.c
@@ -28,8 +28,12 @@
  *   ... and many others (see AUTHORS)
  */
 
+#ifdef HAVE_CONFIG_H
 #include <config.h>
+#endif
+
 #include <stdlib.h>
+
 #include <glib/gi18n.h>
 #include <gtk/gtkbutton.h>
 #include <gtk/gtkliststore.h>
@@ -37,14 +41,20 @@
 #include <gtk/gtkmessagedialog.h>
 #include <gtk/gtktreeview.h>
 #include <glade/glade-xml.h>
+
+#include <common/nact-action.h>
+#include <common/nact-action-profile.h>
+#include <common/nact-pivot.h>
 #include <common/nautilus-actions-config.h>
 #include <common/nautilus-actions-config-gconf-writer.h>
-#include "nact-utils.h"
+
 #include "nact.h"
+#include "nact-application.h"
 #include "nact-editor.h"
 #include "nact-import-export.h"
 #include "nact-prefs.h"
 #include "nact-action-editor.h"
+#include "nact-utils.h"
 
 /* gui callback functions */
 void     dialog_response_cb (GtkDialog *dialog, gint response_id, gpointer user_data);
@@ -55,13 +65,12 @@ void     edit_button_clicked_cb (GtkButton *button, gpointer user_data);
 void     im_export_button_clicked_cb (GtkButton *button, gpointer user_data);
 gboolean on_ActionsList_button_press_event( GtkWidget *widget, GdkEventButton *event, gpointer data );
 
-static gint  actions_list_sort_by_label (gconstpointer a1, gconstpointer a2);
-static guint get_profiles_count( const NautilusActionsConfigAction *action );
-static void  list_selection_changed_cb (GtkTreeSelection *selection, gpointer user_data);
-static void  fill_actions_list (GtkWidget *list);
-static void  setup_actions_list (GtkWidget *list);
+static NactApplication *st_application = NULL;
+static NactPivot       *st_pivot = NULL;
 
-static NautilusActionsConfigGconfWriter *config = NULL;
+static void  list_selection_changed_cb (GtkTreeSelection *selection, gpointer user_data);
+static void  fill_actions_list( GtkWidget *list );
+static void  setup_actions_list( GtkWidget *list );
 
 gboolean
 on_ActionsList_button_press_event( GtkWidget *widget, GdkEventButton *event, gpointer data )
@@ -74,21 +83,6 @@ on_ActionsList_button_press_event( GtkWidget *widget, GdkEventButton *event, gpo
 	return( FALSE );
 }
 
-static guint
-get_profiles_count( const NautilusActionsConfigAction *action )
-{
-	return( nautilus_actions_config_action_get_profiles_count( action ));
-}
-
-static gint
-actions_list_sort_by_label (gconstpointer a1, gconstpointer a2)
-{
-	NautilusActionsConfigAction* action1 = (NautilusActionsConfigAction*)a1;
-	NautilusActionsConfigAction* action2 = (NautilusActionsConfigAction*)a2;
-
-	return g_utf8_collate (action1->label, action2->label);
-}
-
 static void
 fill_actions_list (GtkWidget *list)
 {
@@ -97,25 +91,34 @@ fill_actions_list (GtkWidget *list)
 
 	gtk_list_store_clear (model);
 
-	actions = nautilus_actions_config_get_actions (NAUTILUS_ACTIONS_CONFIG (config));
-	actions = g_slist_sort (actions, (GCompareFunc)actions_list_sort_by_label);
-	for (l = actions; l != NULL; l = l->next) {
+	actions = nact_pivot_get_label_sorted_actions( st_pivot );
+
+	for( l = actions ; l != NULL ; l = l->next ){
 		GtkTreeIter iter;
 		GtkStockItem item;
 		GdkPixbuf* icon = NULL;
-		NautilusActionsConfigAction *action = l->data;
 
-		if (action->icon != NULL) {
-			if (gtk_stock_lookup (action->icon, &item)) {
-				icon = gtk_widget_render_icon (list, action->icon, GTK_ICON_SIZE_MENU, NULL);
-			} else if (g_file_test (action->icon, G_FILE_TEST_EXISTS)
-				   && g_file_test (action->icon, G_FILE_TEST_IS_REGULAR)) {
+		NactAction *action = NACT_ACTION( l->data );
+		gchar *uuid = nact_action_get_uuid( action );
+		gchar *label = nact_action_get_label( action );
+		gchar *iconname = nact_action_get_icon( action );
+
+		/* TODO: use the same algorythm than Nautilus to find and
+		 * display an icon + move the code to NactAction class +
+		 * remove nact_action_get_verified_icon_name
+		 */
+		if( icon ){
+			if( gtk_stock_lookup( iconname, &item )){
+				icon = gtk_widget_render_icon( list, iconname, GTK_ICON_SIZE_MENU, NULL );
+
+			} else if( g_file_test( iconname, G_FILE_TEST_EXISTS )
+				   && g_file_test( iconname, G_FILE_TEST_IS_REGULAR )){
 				gint width;
 				gint height;
 				GError* error = NULL;
 
 				gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, &width, &height);
-				icon = gdk_pixbuf_new_from_file_at_size (action->icon, width, height, &error);
+				icon = gdk_pixbuf_new_from_file_at_size( iconname, width, height, &error );
 				if (error)
 				{
 					icon = NULL;
@@ -126,9 +129,13 @@ fill_actions_list (GtkWidget *list)
 		gtk_list_store_append (model, &iter);
 		gtk_list_store_set (model, &iter,
 				    MENU_ICON_COLUMN, icon,
-				    MENU_LABEL_COLUMN, action->label,
-				    UUID_COLUMN, action->uuid,
+				    MENU_LABEL_COLUMN, label,
+				    UUID_COLUMN, uuid,
 				    -1);
+
+		g_free( iconname );
+		g_free( label );
+		g_free( uuid );
 	}
 
 	nautilus_actions_config_free_actions_list (actions);
@@ -173,18 +180,19 @@ edit_button_clicked_cb (GtkButton *button, gpointer user_data)
 
 	if (gtk_tree_selection_get_selected (selection, &model, &iter)) {
 		gchar *uuid;
-		NautilusActionsConfigAction *action;
+		NactAction *action;
 
 		gtk_tree_model_get (model, &iter, UUID_COLUMN, &uuid, -1);
 
-		action = nautilus_actions_config_get_action (NAUTILUS_ACTIONS_CONFIG (config), uuid);
+		action = NACT_ACTION( nact_pivot_get_action( st_pivot, uuid ));
+
 		if( action ){
-			guint count = get_profiles_count( action );
+			guint count = nact_action_get_profiles_count( action );
 			if( count > 1 ){
-				if (nact_editor_edit_action (action))
+				if (nact_editor_edit_action (( NautilusActionsConfigAction *) action))
 					fill_actions_list (nact_actions_list);
 			} else {
-				if( nact_action_editor_edit( action ))
+				if( nact_action_editor_edit( ( NautilusActionsConfigAction *) action ))
 					fill_actions_list( nact_actions_list );
 			}
 		}
@@ -200,8 +208,8 @@ duplicate_button_clicked_cb (GtkButton *button, gpointer user_data)
 	GtkTreeIter iter;
 	GtkWidget *nact_actions_list;
 	GtkTreeModel* model;
-	GError* error = NULL;
-	gchar* tmp;
+	gchar *error = NULL;
+	gchar *tmp, *label;
 
 	nact_actions_list = nact_get_glade_widget ("ActionsList");
 
@@ -210,29 +218,29 @@ duplicate_button_clicked_cb (GtkButton *button, gpointer user_data)
 	if (gtk_tree_selection_get_selected (selection, &model, &iter))
 	{
 		gchar *uuid;
-		NautilusActionsConfigAction *action;
-		NautilusActionsConfigAction* new_action;
+		NactAction *action;
+		NactAction* new_action;
 
 		gtk_tree_model_get (model, &iter, UUID_COLUMN, &uuid, -1);
 
-		action = nautilus_actions_config_get_action (NAUTILUS_ACTIONS_CONFIG (config), uuid);
-		new_action = nautilus_actions_config_action_dup_new (action);
-		if (new_action)
-		{
-			if (nautilus_actions_config_add_action (NAUTILUS_ACTIONS_CONFIG (config), new_action, &error))
-			{
-				fill_actions_list (nact_actions_list);
-			}
-			else
-			{
-				/* i18n notes: will be displayed in a dialog */
-				tmp = g_strdup_printf (_("Can't duplicate action '%s'!"), action->label);
-				nautilus_actions_display_error (tmp, error->message);
-				g_error_free (error);
-				g_free (tmp);
-			}
+		action = NACT_ACTION( nact_pivot_get_action( st_pivot, uuid ));
+		new_action = nact_action_duplicate( action );
+		nact_action_set_new_uuid( new_action );
+
+		/*if( nautilus_actions_config_add_action( NAUTILUS_ACTIONS_CONFIG (config), new_action, &error )){*/
+		if( nact_pivot_add_action( st_pivot, G_OBJECT( new_action ), &error )){
+			fill_actions_list (nact_actions_list);
+		} else {
+			/* i18n notes: will be displayed in a dialog */
+			label = nact_action_get_label( action );
+			tmp = g_strdup_printf (_("Can't duplicate action '%s'!"), label);
+			nautilus_actions_display_error( tmp, error );
+			g_free( error );
+			g_free( label );
+			g_free( tmp );
 		}
-		g_free (uuid);
+
+		g_free( uuid );
 	}
 }
 
@@ -252,7 +260,7 @@ delete_button_clicked_cb (GtkButton *button, gpointer user_data)
 		gchar *uuid;
 
 		gtk_tree_model_get (model, &iter, UUID_COLUMN, &uuid, -1);
-		nautilus_actions_config_remove_action (NAUTILUS_ACTIONS_CONFIG (config), uuid);
+		/*nautilus_actions_config_remove_action (NAUTILUS_ACTIONS_CONFIG (config), uuid);*/
 		fill_actions_list (nact_actions_list);
 
 		g_free (uuid);
@@ -358,7 +366,7 @@ setup_actions_list (GtkWidget *list)
 }
 
 GtkWindow *
-nact_init_dialog (void)
+nact_init_dialog( GObject *application )
 {
 	gint width, height, x, y;
 	GtkWidget *nact_dialog;
@@ -366,7 +374,13 @@ nact_init_dialog (void)
 	/*GtkWidget* nact_edit_button;*/
 	GtkWidget* nact_about_button;
 
-	config = nautilus_actions_config_gconf_writer_get ();
+	g_assert( NACT_IS_APPLICATION( application ));
+	st_application = NACT_APPLICATION( application );
+
+	g_object_get( G_OBJECT( st_application ), "pivot", &st_pivot, NULL );
+	g_assert( NACT_IS_PIVOT( st_pivot ));
+
+	/*config = nautilus_actions_config_gconf_writer_get ();*/
 
 	GladeXML *gui = nact_get_glade_xml_object (GLADE_MAIN_WIDGET);
 	if (!gui) {
@@ -379,7 +393,7 @@ nact_init_dialog (void)
 	nact_dialog = nact_get_glade_widget ("ActionsDialog");
 
 	nact_actions_list = nact_get_glade_widget ("ActionsList");
-	setup_actions_list (nact_actions_list);
+	setup_actions_list( nact_actions_list );
 
 	/* Get the default dialog size */
 	gtk_window_get_default_size (GTK_WINDOW (nact_dialog), &width, &height);
diff --git a/src/nact/nact.h b/src/nact/nact.h
index 21af99f..a641592 100644
--- a/src/nact/nact.h
+++ b/src/nact/nact.h
@@ -31,6 +31,7 @@
 #ifndef __NACT_H__
 #define __NACT_H__
 
+#include <glib.h>
 #include <gtk/gtk.h>
 
 G_BEGIN_DECLS
@@ -42,7 +43,7 @@ enum {
 	N_COLUMN
 };
 
-GtkWindow *nact_init_dialog( void );
+GtkWindow *nact_init_dialog( GObject *application );
 
 G_END_DECLS
 



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