[nautilus-actions: 7/19] The plugin now uses the new object hierarchy to handle menu items



commit fe10a641841c410da17ecbf8d566cac9fdfc11d1
Author: Pierre Wieser <pwieser trychlos org>
Date:   Tue Jun 9 20:56:54 2009 +0200

    The plugin now uses the new object hierarchy to handle menu items
---
 ChangeLog                        |   15 ++
 src/common/nact-action-profile.c |  292 +++++++++++++++++++++++++++++++++-----
 src/common/nact-action-profile.h |    8 +-
 src/common/nact-action.c         |  113 ++++++---------
 src/common/nact-action.h         |    5 +-
 src/common/nact-gconf.c          |    5 +-
 src/common/nact-object.c         |   53 +++++++-
 src/common/nact-object.h         |    4 +
 src/common/nact-pivot.c          |   32 +++--
 src/common/nact-pivot.h          |    1 +
 src/plugin/nautilus-actions.c    |  170 ++++++++++++-----------
 11 files changed, 492 insertions(+), 206 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 0ea915f..dab7e9c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,18 @@
+2009-06-09 Pierre Wieser <pwieser trychlos org>
+
+	* src/common/nact-action-profile.c:
+	* src/common/nact-action-profile.h:
+	* src/common/nact-action.c:
+	* src/common/nact-action.h:
+	* src/common/nact-gconf.c:
+	* src/common/nact-object.c:
+	* src/common/nact-object.h:
+	* src/common/nact-pivot.c:
+	* src/common/nact-pivot.h:
+	* src/plugin/nautilus-actions.c:
+	The plugin now uses the new object hierarchy to handle menu items.
+	Fix #580378 (context menu doesn't update) reported by James Campos.
+
 2009-06-08 Pierre Wieser <pwieser trychlos org>
 
 	* src/common/nact-action-profile.c:
diff --git a/src/common/nact-action-profile.c b/src/common/nact-action-profile.c
index 09eac28..e7097ea 100644
--- a/src/common/nact-action-profile.c
+++ b/src/common/nact-action-profile.c
@@ -34,6 +34,8 @@
 
 #include <string.h>
 
+#include <libgnomevfs/gnome-vfs.h>
+
 #include <libnautilus-extension/nautilus-file-info.h>
 
 #include "nact-action.h"
@@ -103,17 +105,19 @@ enum {
 
 static NactObjectClass *st_parent_class = NULL;
 
-static GType register_type( void );
-static void  class_init( NactActionProfileClass *klass );
-static void  instance_init( GTypeInstance *instance, gpointer klass );
-static void  instance_dispose( GObject *object );
-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_finalize( GObject *object );
+static GType  register_type( void );
+static void   class_init( NactActionProfileClass *klass );
+static void   instance_init( GTypeInstance *instance, gpointer klass );
+static void   instance_dispose( GObject *object );
+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_finalize( GObject *object );
 
-static void  do_dump( const NactObject *profile );
-static void  do_dump_list( const gchar *thisfn, const gchar *label, GSList *list );
-static int   validate_schemes( GSList* schemes2test, NautilusFileInfo* file );
+static void   do_dump( const NactObject *profile );
+static void   do_dump_list( const gchar *thisfn, const gchar *label, GSList *list );
+static gchar *do_get_id( const NactObject *object );
+static gchar *do_get_label( const NactObject *object );
+static int    validate_schemes( GSList* schemes2test, NautilusFileInfo* file );
 
 NactActionProfile *
 nact_action_profile_new( const NactObject *action, const gchar *name )
@@ -129,6 +133,44 @@ nact_action_profile_new( const NactObject *action, const gchar *name )
 	return( profile );
 }
 
+NactActionProfile *
+nact_action_profile_copy( const NactActionProfile *profile )
+{
+	g_assert( NACT_IS_ACTION_PROFILE( profile ));
+
+	NactActionProfile *new =
+		nact_action_profile_new( profile->private->action, profile->private->name );
+
+	g_object_set( G_OBJECT( new ),
+			PROP_LABEL_STR, profile->private->label,
+			PROP_PATH_STR, profile->private->path,
+			PROP_PARAMETERS_STR, profile->private->parameters,
+			PROP_ACCEPT_MULTIPLE_STR, profile->private->accept_multiple_files,
+			PROP_BASENAMES_STR, profile->private->basenames,
+			PROP_ISDIR_STR, profile->private->is_dir,
+			PROP_ISFILE_STR, profile->private->is_file,
+			PROP_MATCHCASE_STR, profile->private->match_case,
+			PROP_MIMETYPES_STR, profile->private->mimetypes,
+			PROP_SCHEMES_STR, profile->private->schemes,
+			NULL );
+
+	return( new );
+}
+
+void
+nact_action_profile_free( NactActionProfile *profile )
+{
+	g_assert( NACT_IS_ACTION_PROFILE( profile ));
+
+	g_free( profile->private->name );
+	g_free( profile->private->label );
+	g_free( profile->private->path );
+	g_free( profile->private->parameters );
+	nactuti_free_string_list( profile->private->basenames );
+	nactuti_free_string_list( profile->private->mimetypes );
+	nactuti_free_string_list( profile->private->schemes );
+}
+
 GType
 nact_action_profile_get_type( void )
 {
@@ -262,6 +304,8 @@ class_init( NactActionProfileClass *klass )
 	klass->private = g_new0( NactActionProfileClassPrivate, 1 );
 
 	NACT_OBJECT_CLASS( klass )->dump = do_dump;
+	NACT_OBJECT_CLASS( klass )->get_id = do_get_id;
+	NACT_OBJECT_CLASS( klass )->get_label = do_get_label;
 }
 
 static void
@@ -438,13 +482,7 @@ instance_finalize( GObject *object )
 	g_assert( NACT_IS_ACTION_PROFILE( object ));
 	NactActionProfile *self = ( NactActionProfile * ) object;
 
-	g_free( self->private->name );
-	g_free( self->private->label );
-	g_free( self->private->path );
-	g_free( self->private->parameters );
-	nactuti_free_string_list( self->private->basenames );
-	nactuti_free_string_list( self->private->mimetypes );
-	nactuti_free_string_list( self->private->schemes );
+	nact_action_profile_free( self );
 
 	/* chain call to parent class */
 	if((( GObjectClass * ) st_parent_class )->finalize ){
@@ -494,6 +532,56 @@ do_dump_list( const gchar *thisfn, const gchar *label, GSList *list )
 	g_string_free( str, TRUE );
 }
 
+static gchar *
+do_get_id( const NactObject *profile )
+{
+	g_assert( NACT_IS_ACTION_PROFILE( profile ));
+
+	gchar *name;
+	g_object_get( G_OBJECT( profile ), PROP_PROFILE_NAME_STR, &name, NULL );
+
+	return( name );
+}
+
+/**
+ * Return the internal id (name) of the profile.
+ *
+ * @action: an NactActionProfile object.
+ *
+ * The returned string must be g_freed by the caller.
+ */
+gchar *
+nact_action_profile_get_name( const NactActionProfile *profile )
+{
+	g_assert( NACT_IS_ACTION_PROFILE( profile ));
+	return( nact_object_get_id( NACT_OBJECT( profile )));
+}
+
+static gchar *
+do_get_label( const NactObject *profile )
+{
+	g_assert( NACT_IS_ACTION_PROFILE( profile ));
+
+	gchar *label;
+	g_object_get( G_OBJECT( profile ), PROP_LABEL_STR, &label, NULL );
+
+	return( label );
+}
+
+/**
+ * Return the descriptive name (label) of the profile.
+ *
+ * @action: an NactAction object.
+ *
+ * The returned string must be g_freed by the caller.
+ */
+gchar *
+nact_action_profile_get_label( const NactActionProfile *profile )
+{
+	g_assert( NACT_IS_ACTION_PROFILE( profile ));
+	return( nact_object_get_label( NACT_OBJECT( profile )));
+}
+
 /*
  * Check if the given profile is empty, i.e. all its attributes are
  * empty.
@@ -542,24 +630,6 @@ nact_action_profile_get_action( const NactActionProfile *profile )
 }
 
 /**
- * Returns the profile name.
- *
- * The returned string should be g_freed by the caller.
- *
- * The profile name is also the GConf-key of the profile.
- */
-gchar *
-nact_action_profile_get_name( const NactActionProfile *profile )
-{
-	g_assert( NACT_IS_ACTION_PROFILE( profile ));
-
-	gchar *name;
-	g_object_get( G_OBJECT( profile ), PROP_PROFILE_NAME_STR, &name, NULL );
-
-	return( name );
-}
-
-/**
  * Returns the path of the command in the profile.
  *
  * The returned string should be g_freed by the caller.
@@ -617,7 +687,7 @@ validate_schemes( GSList* schemes2test, NautilusFileInfo* file )
 }
 
 gboolean
-nact_action_profile_validate( const NactActionProfile *profile, GList* files )
+nact_action_profile_is_candidate( const NactActionProfile *profile, GList* files )
 {
 	gboolean retv = FALSE;
 	gboolean test_multiple_file = FALSE;
@@ -833,3 +903,153 @@ nact_action_profile_validate( const NactActionProfile *profile, GList* files )
 
 	return retv;
 }
+
+/*
+ * Valid parameters :
+ *
+ * %u : gnome-vfs URI
+ * %d : base dir of the selected file(s)/folder(s)
+ * %f : the name of the selected file/folder or the 1st one if many are selected
+ * %m : list of the basename of the selected files/directories separated by space.
+ * %M : list of the selected files/directories with their complete path separated by space.
+ * %s : scheme of the gnome-vfs URI
+ * %h : hostname of the gnome-vfs URI
+ * %U : username of the gnome-vfs URI
+ * %% : a percent sign
+ */
+gchar *
+nact_action_profile_parse_parameters( const NactActionProfile *profile, GList* files )
+{
+	gchar* retv = NULL;
+	g_return_val_if_fail( NACT_IS_ACTION_PROFILE( profile ), NULL );
+
+	if (files != NULL){
+		const gchar *param_template = profile->private->parameters;
+		GString* tmp_string = g_string_new ("");
+		gchar* iter = g_strdup (param_template);
+		gchar* old_iter = iter;
+		/*int current_len = strlen (iter);*/
+		gchar* uri = nautilus_file_info_get_uri ((NautilusFileInfo*)files->data);
+		GnomeVFSURI* gvfs_uri = gnome_vfs_uri_new (uri);
+		gchar* filename;
+		gchar* dirname;
+		gchar* scheme = nautilus_file_info_get_uri_scheme ((NautilusFileInfo*)files->data);
+		gchar* hostname = g_strdup (gnome_vfs_uri_get_host_name (gvfs_uri));
+		gchar* username = g_strdup (gnome_vfs_uri_get_user_name (gvfs_uri));
+		gchar* file_list;
+		gchar* path_file_list;
+		GList* file_iter = NULL;
+		GString* tmp_file_list;
+		GString* tmp_path_file_list;
+		gchar* tmp;
+		gchar* tmp2;
+
+		tmp = gnome_vfs_uri_extract_dirname (gvfs_uri);
+		dirname = (gchar*)gnome_vfs_unescape_string ((const gchar*)tmp, "");
+		g_free (tmp);
+
+		tmp = nautilus_file_info_get_name ((NautilusFileInfo*)files->data);
+		if (!tmp)
+		{
+			tmp = g_strdup ("");
+		}
+
+		filename = g_shell_quote (tmp);
+		tmp2 = g_build_path ("/", dirname, tmp, NULL);
+		g_free (tmp);
+		tmp_file_list = g_string_new (filename);
+		tmp = g_shell_quote (tmp2);
+		tmp_path_file_list = g_string_new (tmp);
+		g_free (tmp2);
+		g_free (tmp);
+
+		/* We already have the first item, so we start with the next one if any */
+		for (file_iter = files->next; file_iter; file_iter = file_iter->next)
+		{
+			gchar* tmp_filename = nautilus_file_info_get_name ((NautilusFileInfo*)file_iter->data);
+			gchar* tmp_uri = nautilus_file_info_get_uri ((NautilusFileInfo*)file_iter->data);
+			GnomeVFSURI* tmp_gvfs_uri = gnome_vfs_uri_new (tmp_uri);
+			tmp = gnome_vfs_uri_extract_dirname (tmp_gvfs_uri);
+			gchar* tmp_dirname = (gchar*)gnome_vfs_unescape_string ((const gchar*)tmp, "");
+			g_free (tmp);
+
+			if (!tmp_filename)
+			{
+				tmp_filename = g_strdup ("");
+			}
+
+			gchar* quoted_tmp_filename = g_shell_quote (tmp_filename);
+			g_string_append_printf (tmp_file_list, " %s", quoted_tmp_filename);
+
+			tmp = g_build_path ("/", tmp_dirname, tmp_filename, NULL);
+			tmp2 = g_shell_quote (tmp);
+			g_string_append_printf (tmp_path_file_list, " %s", tmp2);
+
+			g_free (tmp2);
+			g_free (tmp);
+			g_free (tmp_filename);
+			g_free (quoted_tmp_filename);
+			g_free (tmp_dirname);
+			g_free (tmp_uri);
+			gnome_vfs_uri_unref (tmp_gvfs_uri);
+		}
+		file_list = g_string_free (tmp_file_list, FALSE);
+		path_file_list = g_string_free (tmp_path_file_list, FALSE);
+
+
+		while ((iter = g_strstr_len (iter, strlen (iter), "%")))
+		{
+			tmp_string = g_string_append_len (tmp_string, old_iter, strlen (old_iter) - strlen (iter));
+			switch (iter[1])
+			{
+				case 'u': /* gnome-vfs URI */
+					tmp_string = g_string_append (tmp_string, uri);
+					break;
+				case 'd': /* base dir of the selected file(s)/folder(s) */
+					tmp = g_shell_quote (dirname);
+					tmp_string = g_string_append (tmp_string, tmp);
+					g_free (tmp);
+					break;
+				case 'f': /* the basename of the selected file/folder or the 1st one if many are selected */
+					tmp_string = g_string_append (tmp_string, filename);
+					break;
+				case 'm': /* list of the basename of the selected files/directories separated by space */
+					tmp_string = g_string_append (tmp_string, file_list);
+					break;
+	 			case 'M': /* list of the selected files/directories with their complete path separated by space. */
+					tmp_string = g_string_append (tmp_string, path_file_list);
+					break;
+				case 's': /* scheme of the gnome-vfs URI */
+					tmp_string = g_string_append (tmp_string, scheme);
+					break;
+				case 'h': /* hostname of the gnome-vfs URI */
+					tmp_string = g_string_append (tmp_string, hostname);
+					break;
+				case 'U': /* username of the gnome-vfs URI */
+					tmp_string = g_string_append (tmp_string, username);
+					break;
+				case '%': /* a percent sign */
+					tmp_string = g_string_append_c (tmp_string, '%');
+					break;
+			}
+			iter+=2; /* skip the % sign and the character after. */
+			old_iter = iter; /* store the new start of the string */
+		}
+		tmp_string = g_string_append_len (tmp_string, old_iter, strlen (old_iter));
+
+		g_free (uri);
+		g_free (dirname);
+		g_free (filename);
+		g_free (file_list);
+		g_free (path_file_list);
+		g_free (scheme);
+		g_free (hostname);
+		g_free (username);
+		g_free (iter);
+		gnome_vfs_uri_unref (gvfs_uri);
+
+		retv = g_string_free (tmp_string, FALSE); /* return the content of the GString */
+	}
+
+	return retv;
+}
diff --git a/src/common/nact-action-profile.h b/src/common/nact-action-profile.h
index fb4786d..d60d155 100644
--- a/src/common/nact-action-profile.h
+++ b/src/common/nact-action-profile.h
@@ -71,17 +71,19 @@ typedef struct {
 GType              nact_action_profile_get_type( void );
 
 NactActionProfile *nact_action_profile_new( const NactObject *action, const gchar *name );
+NactActionProfile *nact_action_profile_copy( const NactActionProfile *profile );
+void               nact_action_profile_free( NactActionProfile *profile );
 
 void               nact_action_profile_load( NactObject *profile );
 
-/*gboolean           nact_action_profile_is_empty( const NactActionProfile *profile );*/
-
 NactObject        *nact_action_profile_get_action( const NactActionProfile *profile );
 gchar             *nact_action_profile_get_name( const NactActionProfile *profile );
+gchar             *nact_action_profile_get_label( const NactActionProfile *profile );
 gchar             *nact_action_profile_get_path( const NactActionProfile *profile );
 gchar             *nact_action_profile_get_parameters( const NactActionProfile *profile );
 
-gboolean           nact_action_profile_validate( const NactActionProfile *profile, GList *files );
+gboolean           nact_action_profile_is_candidate( const NactActionProfile *profile, GList *files );
+gchar             *nact_action_profile_parse_parameters( const NactActionProfile *profile, GList *files );
 
 G_END_DECLS
 
diff --git a/src/common/nact-action.c b/src/common/nact-action.c
index 4aec226..3b7fb17 100644
--- a/src/common/nact-action.c
+++ b/src/common/nact-action.c
@@ -94,6 +94,8 @@ static void               free_profiles( NactAction *action );
 static NactActionProfile *get_profile( const NactAction *action, const gchar *profile_name );
 
 static void     do_dump( const NactObject *action );
+static gchar   *do_get_id( const NactObject *action );
+static gchar   *do_get_label( const NactObject *action );
 
 /**
  * Allocate a new NactAction object.
@@ -198,6 +200,8 @@ class_init( NactActionClass *klass )
 	klass->private = g_new0( NactActionClassPrivate, 1 );
 
 	NACT_OBJECT_CLASS( klass )->dump = do_dump;
+	NACT_OBJECT_CLASS( klass )->get_id = do_get_id;
+	NACT_OBJECT_CLASS( klass )->get_label = do_get_label;
 }
 
 static void
@@ -331,39 +335,20 @@ free_profiles( NactAction *action )
 {
 	g_assert( NACT_IS_ACTION( action ));
 
-	GSList *ip;
-	for( ip = action->private->profiles ; ip ; ip = ip->next ){
-		g_object_unref( NACT_ACTION_PROFILE( ip->data ));
-	}
-	g_slist_free( action->private->profiles );
+	nact_action_free_profiles( action->private->profiles );
+
 	action->private->profiles = NULL;
 }
 
-/**
- * Create a new NactAction object, with the given parm and value.
- *
- * Note that the parm may actually be a profile's parm.
- */
-/*NactAction *
-nact_action_create( const gchar *key, const gchar *parm, const NactPivotValue *value )
-{
-	static const gchar *thisfn = "nact_action_create";
-	g_debug( "%s: key='%s', parm='%s', value=%p", thisfn, key, parm, value );
-
-	NactAction *action = g_object_new( NACT_ACTION_TYPE, NULL );
-	nact_action_update( action, parm, value );
-	return( action );
-}*/
-
-/**
- * Update the given parameter of an action.
- */
-/*void
-nact_action_update( NactAction *action, const gchar *parm, const NactPivotValue *value )
+void
+nact_action_free_profiles( GSList * list )
 {
-	static const gchar *thisfn = "nact_action_update";
-	g_debug( "%s: action=%p, parm='%s', value=%p", thisfn, action, parm, value );
-}*/
+	GSList *ip;
+	for( ip = list ; ip ; ip = ip->next ){
+		g_object_unref( NACT_ACTION_PROFILE( ip->data ));
+	}
+	g_slist_free( list );
+}
 
 static void
 do_dump( const NactObject *action )
@@ -391,72 +376,54 @@ do_dump( const NactObject *action )
 	}
 }
 
-/**
- * Check if the given action is empty, i.e. all its attributes are empty.
- */
-/*gboolean
-nact_action_is_empty( const NactAction *action )
+static gchar *
+do_get_id( const NactObject *action )
 {
 	g_assert( NACT_IS_ACTION( action ));
 
-	if( action->private->uuid && strlen( action->private->uuid )){
-		return( FALSE );
-	}
-	if( action->private->version && strlen( action->private->version )){
-		return( FALSE );
-	}
-	if( action->private->label && strlen( action->private->label )){
-		return( FALSE );
-	}
-	if( action->private->tooltip && strlen( action->private->tooltip )){
-		return( FALSE );
-	}
-	if( action->private->icon && strlen( action->private->icon )){
-		return( FALSE );
-	}
-	GSList *ip;
-	for( ip = action->private->profiles ; ip ; ip = ip->next ){
-		if( !nact_action_profile_is_empty( NACT_ACTION_PROFILE( ip->data ))){
-			return( FALSE );
-		}
-	}
-	return( TRUE );
-}*/
+	gchar *uuid;
+	g_object_get( G_OBJECT( action ), PROP_UUID_STR, &uuid, NULL );
+
+	return( uuid );
+}
 
 /**
  * Return the globally unique identifier (UUID) of the action.
  *
  * @action: an NactAction object.
  *
- * The returned string must be g_free by the caller.
+ * The returned string must be g_freed by the caller.
  */
 gchar *
 nact_action_get_uuid( const NactAction *action )
 {
 	g_assert( NACT_IS_ACTION( action ));
+	return( nact_object_get_id( NACT_OBJECT( action )));
+}
 
-	gchar *uuid;
-	g_object_get( G_OBJECT( action ), PROP_UUID_STR, &uuid, NULL );
+static gchar *
+do_get_label( const NactObject *action )
+{
+	g_assert( NACT_IS_ACTION( action ));
 
-	return( uuid );
+	gchar *label;
+	g_object_get( G_OBJECT( action ), PROP_LABEL_STR, &label, NULL );
+
+	return( label );
 }
 
 /**
- * Return the label of the context menu item for the action.
+ * Return the label of the action.
  *
  * @action: an NactAction object.
  *
- * The returned string must be g_free by the caller.
+ * The returned string must be g_freed by the caller.
  */
 gchar *
 nact_action_get_label( const NactAction *action )
 {
 	g_assert( NACT_IS_ACTION( action ));
-
-	gchar *label;
-	g_object_get( G_OBJECT( action ), PROP_LABEL_STR, &label, NULL );
-
-	return( label );
+	return( nact_object_get_label( NACT_OBJECT( action )));
 }
 
 /**
@@ -464,7 +431,7 @@ nact_action_get_label( const NactAction *action )
  *
  * @action: an NactAction object.
  *
- * The returned string must be g_free by the caller.
+ * The returned string must be g_freed by the caller.
  */
 gchar *
 nact_action_get_tooltip( const NactAction *action )
@@ -532,7 +499,13 @@ nact_action_set_profiles( NactAction *action, GSList *list )
 	g_assert( NACT_IS_ACTION( action ));
 
 	free_profiles( action );
-	action->private->profiles = list;
+	GSList *ip;
+	for( ip = list ; ip ; ip = ip->next ){
+		action->private->profiles = g_slist_prepend(
+							action->private->profiles,
+							nact_action_profile_copy( NACT_ACTION_PROFILE( ip->data ))
+		);
+	}
 }
 
 guint
diff --git a/src/common/nact-action.h b/src/common/nact-action.h
index e9633cf..b1e2817 100644
--- a/src/common/nact-action.h
+++ b/src/common/nact-action.h
@@ -71,10 +71,6 @@ GType       nact_action_get_type( void );
 
 NactAction *nact_action_new( const gchar *uuid );
 
-/*NactAction *nact_action_create( const gchar *key, const gchar *parm, const NactPivotValue *value );
-void        nact_action_update( NactAction *action, const gchar *parm, const NactPivotValue *value );
-gboolean    nact_action_is_empty( const NactAction *action );*/
-
 gchar      *nact_action_get_uuid( const NactAction *action );
 gchar      *nact_action_get_label( const NactAction *action );
 gchar      *nact_action_get_tooltip( const NactAction *action );
@@ -82,6 +78,7 @@ gchar      *nact_action_get_verified_icon_name( const 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 );
 
 guint       nact_action_get_profiles_count( const NactAction *action );
 GSList     *nact_action_get_profile_ids( const NactAction *action );
diff --git a/src/common/nact-gconf.c b/src/common/nact-gconf.c
index 4f0683c..e21384b 100644
--- a/src/common/nact-gconf.c
+++ b/src/common/nact-gconf.c
@@ -274,6 +274,7 @@ do_load_actions( NactIIOProvider *provider )
 	GSList *items = NULL;
 	GSList *ip;
 	GSList *listpath = load_subdirs( self, NACT_GCONF_CONFIG_PATH );
+	GSList *profiles;
 
 	for( ip = listpath ; ip ; ip = ip->next ){
 
@@ -281,7 +282,9 @@ do_load_actions( NactIIOProvider *provider )
 
 		NactAction *action = nact_action_new( key );
 		load_action_properties( self, action );
-		nact_action_set_profiles( action, load_profiles( self, action ));
+		profiles = load_profiles( self, action );
+		nact_action_set_profiles( action, profiles );
+		nact_action_free_profiles( profiles );
 
 #ifdef NACT_MAINTAINER_MODE
 		nact_object_dump( NACT_OBJECT( action ));
diff --git a/src/common/nact-object.c b/src/common/nact-object.c
index 5f3cf5c..76e0995 100644
--- a/src/common/nact-object.c
+++ b/src/common/nact-object.c
@@ -56,6 +56,8 @@ static void    instance_finalize( GObject *object );
 
 static void    do_dump( const NactObject *object );
 static void    do_empty_property( NactObject *object, const gchar *property );
+static gchar  *do_get_id( const NactObject *object );
+static gchar  *do_get_label( const NactObject *object );
 
 GType
 nact_object_get_type( void )
@@ -103,6 +105,8 @@ class_init( NactObjectClass *klass )
 
 	klass->dump = do_dump;
 	klass->empty_property = do_empty_property;
+	klass->get_id = do_get_id;
+	klass->get_label = do_get_label;
 }
 
 static void
@@ -199,6 +203,53 @@ void
 nact_object_empty_property( NactObject *object, const gchar *property )
 {
 	g_assert( NACT_IS_OBJECT( object ));
-
 	NACT_OBJECT_GET_CLASS( object )->empty_property( object, property );
 }
+
+static gchar *
+do_get_id( const NactObject *object )
+{
+	g_assert( NACT_IS_OBJECT( object ));
+	return(( gchar * ) NULL );
+}
+
+/**
+ * Returns the id of the object as new string.
+ *
+ * This is a virtual function which should be implemented by the
+ * derived class ; if not, this parent object returns NULL.
+ *
+ * @object: targeted NactObject object.
+ *
+ * The returned string should be g_freed by the caller.
+ */
+gchar *
+nact_object_get_id( const NactObject *object )
+{
+	g_assert( NACT_IS_OBJECT( object ));
+	return( NACT_OBJECT_GET_CLASS( object )->get_id( object ));
+}
+
+static gchar *
+do_get_label( const NactObject *object )
+{
+	g_assert( NACT_IS_OBJECT( object ));
+	return(( gchar * ) NULL );
+}
+
+/**
+ * Returns the label of the object as new string.
+ *
+ * This is a virtual function which should be implemented by the
+ * derived class ; if not, this parent object returns NULL.
+ *
+ * @object: targeted NactObject object.
+ *
+ * The returned string should be g_freed by the caller.
+ */
+gchar *
+nact_object_get_label( const NactObject *object )
+{
+	g_assert( NACT_IS_OBJECT( object ));
+	return( NACT_OBJECT_GET_CLASS( object )->get_label( object ));
+}
diff --git a/src/common/nact-object.h b/src/common/nact-object.h
index d81febe..d900df0 100644
--- a/src/common/nact-object.h
+++ b/src/common/nact-object.h
@@ -69,6 +69,8 @@ typedef struct {
 	/* virtual public functions */
 	void    ( *dump )( const NactObject *object );
 	void    ( *empty_property )( NactObject *object, const gchar *property );
+	gchar * ( *get_id )( const NactObject *object );
+	gchar * ( *get_label )( const NactObject *object );
 }
 	NactObjectClass;
 
@@ -76,6 +78,8 @@ GType    nact_object_get_type( void );
 
 void     nact_object_dump( const NactObject *object );
 void     nact_object_empty_property( NactObject *object, const gchar *property );
+gchar   *nact_object_get_id( const NactObject *object );
+gchar   *nact_object_get_label( const NactObject *object );
 
 G_END_DECLS
 
diff --git a/src/common/nact-pivot.c b/src/common/nact-pivot.c
index 4b76b15..e0eba5e 100644
--- a/src/common/nact-pivot.c
+++ b/src/common/nact-pivot.c
@@ -98,8 +98,8 @@ static void        instance_set_property( GObject *object, guint property_id, co
 static void        instance_dispose( GObject *object );
 static void        instance_finalize( GObject *object );
 
-static void        action_changed_handler( NactPivot *pivot, gpointer user_data );
 static void        free_actions( GSList *list );
+static void        action_changed_handler( NactPivot *pivot, gpointer user_data );
 static NactAction *get_action( GSList *list, const gchar *uuid );
 static gboolean    on_action_changed_timeout( gpointer user_data );
 static gulong      time_val_diff( const GTimeVal *recent, const GTimeVal *old );
@@ -287,6 +287,16 @@ instance_finalize( GObject *object )
 	}
 }
 
+static void
+free_actions( GSList *list )
+{
+	GSList *ia;
+	for( ia = list ; ia ; ia = ia->next ){
+		g_object_unref( NACT_ACTION( ia->data ));
+	}
+	g_slist_free( list );
+}
+
 /**
  * Returns the list of providers of the required interface.
  *
@@ -316,6 +326,16 @@ nact_pivot_get_providers( const NactPivot *pivot, GType type )
 	return( list );
 }
 
+/**
+ * Return the list of actions.
+ */
+GSList *
+nact_pivot_get_actions( const NactPivot *pivot )
+{
+	g_assert( NACT_IS_PIVOT( pivot ));
+	return( pivot->private->actions );
+}
+
 /*
  * this handler is trigerred by IIOProviders when an action is changed
  * in the underlying storage subsystems
@@ -343,16 +363,6 @@ action_changed_handler( NactPivot *self, gpointer user_data  )
 	}
 }
 
-static void
-free_actions( GSList *list )
-{
-	GSList *ia;
-	for( ia = list ; ia ; ia = ia->next ){
-		g_object_unref( NACT_ACTION( ia->data ));
-	}
-	g_slist_free( list );
-}
-
 static NactAction *
 get_action( GSList *list, const gchar *uuid )
 {
diff --git a/src/common/nact-pivot.h b/src/common/nact-pivot.h
index ab8a612..35f0c0d 100644
--- a/src/common/nact-pivot.h
+++ b/src/common/nact-pivot.h
@@ -73,6 +73,7 @@ NactPivot *nact_pivot_new( const GObject *notified );
 
 GSList    *nact_pivot_get_providers( const NactPivot *pivot, GType type );
 
+GSList    *nact_pivot_get_actions( const NactPivot *pivot );
 GObject   *nact_pivot_get_action( NactPivot *pivot, const gchar *uuid );
 
 /* data passed from the storage subsystem when an action is changed
diff --git a/src/plugin/nautilus-actions.c b/src/plugin/nautilus-actions.c
index 09cb3a3..a082221 100644
--- a/src/plugin/nautilus-actions.c
+++ b/src/plugin/nautilus-actions.c
@@ -44,12 +44,13 @@
 #include <libnautilus-extension/nautilus-menu-provider.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-reader.h>
 #include "nautilus-actions.h"
-#include "nautilus-actions-test.h"
-#include "nautilus-actions-utils.h"
+/*#include "nautilus-actions-test.h"
+#include "nautilus-actions-utils.h"*/
 
 /* private class data
  */
@@ -103,11 +104,11 @@ static void instance_finalize( GObject *object );
 
 static GList            *get_background_items( NautilusMenuProvider *provider, GtkWidget *window, NautilusFileInfo *current_folder );
 static GList            *get_file_items( NautilusMenuProvider *provider, GtkWidget *window, GList *files );
-static const gchar      *get_verified_icon_name( const gchar* icon_name );
-static NautilusMenuItem *create_menu_item( NautilusActionsConfigAction *action, GList *files, NautilusActionsConfigActionProfile* action_profile );
-static void              execute_action( NautilusMenuItem *item, NautilusActionsConfigActionProfile *action_profile );
+/*static const gchar      *get_verified_icon_name( const gchar* icon_name );*/
+static NautilusMenuItem *create_menu_item( NactAction *action, NactActionProfile *profile, GList *files );
+static void              execute_action( NautilusMenuItem *item, NactActionProfile *profile );
 static void              action_changed_handler( NautilusActions *instance, gpointer user_data );
-static void              action_changed_handler_old( NautilusActionsConfig* config, NautilusActionsConfigAction* action, gpointer user_data );
+/*static void              action_changed_handler_old( NautilusActionsConfig* config, NautilusActionsConfigAction* action, gpointer user_data );*/
 
 GType
 nautilus_actions_get_type( void )
@@ -216,6 +217,7 @@ instance_init( GTypeInstance *instance, gpointer klass )
 	gnome_vfs_init ();
 
 	self->private = g_new0( NautilusActionsPrivate, 1 );
+	self->private->dispose_has_run = FALSE;
 
 	/* from nact-pivot */
 	self->private->pivot = nact_pivot_new( G_OBJECT( self ));
@@ -232,11 +234,10 @@ instance_init( GTypeInstance *instance, gpointer klass )
 			NULL
 	);*/
 
-	self->private->configs = NULL;
+	/*self->private->configs = NULL;
 	self->private->configs = nautilus_actions_config_gconf_reader_get ();
 	self->private->config_list = NULL;
 	self->private->config_list = nautilus_actions_config_get_actions (NAUTILUS_ACTIONS_CONFIG (self->private->configs));
-	self->private->dispose_has_run = FALSE;
 
 	g_signal_connect_after(
 			G_OBJECT( self->private->configs ),
@@ -255,7 +256,7 @@ instance_init( GTypeInstance *instance, gpointer klass )
 			"action_removed",
 			( GCallback ) action_changed_handler_old,
 			self
-	);
+	);*/
 }
 
 static void
@@ -325,57 +326,59 @@ get_file_items( NautilusMenuProvider *provider, GtkWidget *window, GList *files
 	g_debug( "%s provider=%p, window=%p, files=%p, count=%d", thisfn, provider, window, files, g_list_length( files ));
 
 	GList *items = NULL;
-	GSList *iter;
+	GSList* profiles;
+	GSList *ia, *ip;
 	NautilusMenuItem *item;
-	NautilusActions* self = NAUTILUS_ACTIONS (provider);
-	gchar* profile_name = NULL;
-	GSList* profile_list = NULL;
-	GSList* iter2;
-	gboolean found;
+	gchar *debug_label;
+	GSList *actions = NULL;
 
-	g_return_val_if_fail (NAUTILUS_IS_ACTIONS (self), NULL);
+	g_return_val_if_fail( NAUTILUS_IS_ACTIONS( provider ), NULL );
+	NautilusActions *self = NAUTILUS_ACTIONS( provider );
 
 	/* no need to go further if there is no files in the list */
 	if( !g_list_length( files )){
 		return(( GList * ) NULL );
 	}
 
-	if (!self->private->dispose_has_run)
-	{
-		for (iter = self->private->config_list; iter; iter = iter->next)
-		{
-			/* Foreach configured action, check if we add a menu item */
-			NautilusActionsConfigAction *action = (NautilusActionsConfigAction*)iter->data;
-
-			/* Retrieve all profile name */
-			/*g_hash_table_foreach (action->profiles, (GHFunc)get_hash_keys, &profile_list);*/
-			profile_list = nautilus_actions_config_action_get_all_profile_names( action );
-
-			iter2 = profile_list;
-			found = FALSE;
-			while (iter2 && !found)
-			{
-				profile_name = (gchar*)iter2->data;
-				NautilusActionsConfigActionProfile* action_profile = nautilus_actions_config_action_get_profile (action, profile_name);
-				g_debug( "%s: profile='%s' (%p)", thisfn, profile_name, action_profile );
-
-				if (nautilus_actions_test_validate (action_profile, files))
-				{
-					item = create_menu_item (action, files, action_profile);
-					items = g_list_append (items, item);
-					found = TRUE;
-				}
+	if( !self->private->dispose_has_run ){
+		actions = nact_pivot_get_actions( self->private->pivot );
+
+		for( ia = actions ; ia ; ia = ia->next ){
+
+			NactAction *action = NACT_ACTION( ia->data );
+
+#ifdef NACT_MAINTAINER_MODE
+			debug_label = nact_action_get_label( action );
+			g_debug( "%s: examining '%s' action", thisfn, debug_label );
+			g_free( debug_label );
+#endif
+
+			profiles = nact_action_get_profiles( action );
+
+			for( ip = profiles ; ip ; ip = ip->next ){
 
-				iter2 = iter2->next;
+				NactActionProfile *profile = NACT_ACTION_PROFILE( ip->data );
+
+#ifdef NACT_MAINTAINER_MODE
+				debug_label = nact_action_profile_get_label( profile );
+				g_debug( "%s: examining '%s' profile", thisfn, debug_label );
+				g_free( debug_label );
+#endif
+
+				/*if( nautilus_actions_test_validate( profile, files )){*/
+				if( nact_action_profile_is_candidate( profile, files )){
+					item = create_menu_item( action, profile, files );
+					items = g_list_append( items, item );
+					break;
+				}
 			}
-			nautilus_actions_config_action_free_all_profile_names( profile_list );
 		}
 	}
 
-	return items;
+	return( items );
 }
 
-static const gchar *
+/*static const gchar *
 get_verified_icon_name( const gchar* icon_name )
 {
 	if (icon_name[0] == '/')
@@ -391,70 +394,77 @@ get_verified_icon_name( const gchar* icon_name )
 	}
 
 	return icon_name;
-}
+}*/
 
 static NautilusMenuItem *
-create_menu_item( NautilusActionsConfigAction *action, GList *files, NautilusActionsConfigActionProfile* action_profile )
+create_menu_item( NactAction *action, NactActionProfile *profile, GList *files )
 {
 	static const gchar *thisfn = "nautilus_actions_create_menu_item";
 	g_debug( "%s", thisfn );
 
 	NautilusMenuItem *item;
-	gchar* name;
-	const gchar* icon_name = get_verified_icon_name (g_strstrip (action->icon));
-	NautilusActionsConfigActionProfile* action_profile4menu = nautilus_actions_config_action_profile_dup (action_profile);
 
-	name = g_strdup_printf ("NautilusActions::%s", action->uuid);
+	gchar *uuid = nact_action_get_uuid( action );
+	gchar *name = g_strdup_printf( "NautilusActions::%s", uuid );
+	gchar *label = nact_action_get_label( action );
+	gchar *tooltip = nact_action_get_tooltip( action );
+	gchar* icon_name = nact_action_get_verified_icon_name( action );
 
-	item = nautilus_menu_item_new (name,
-				action->label,
-				action->tooltip,
-				icon_name);
+	NactActionProfile *dup4menu = nact_action_profile_copy( profile );
 
-	g_signal_connect_data (item,
+	item = nautilus_menu_item_new( name, label, tooltip, icon_name );
+
+	g_signal_connect_data( item,
 				"activate",
-				G_CALLBACK (execute_action),
-				action_profile4menu,
-				(GClosureNotify)nautilus_actions_config_action_profile_free,
-				0);
+				G_CALLBACK( execute_action ),
+				dup4menu,
+				( GClosureNotify ) nact_action_profile_free,
+				0
+	);
 
-	g_object_set_data_full (G_OBJECT (item),
+	g_object_set_data_full( G_OBJECT( item ),
 			"files",
-			nautilus_file_info_list_copy (files),
-			(GDestroyNotify) nautilus_file_info_list_free);
-
+			nautilus_file_info_list_copy( files ),
+			( GDestroyNotify ) nautilus_file_info_list_free
+	);
 
-	g_free (name);
+	g_free( icon_name );
+	g_free( tooltip );
+	g_free( label );
+	g_free( name );
+	g_free( uuid );
 
-	return item;
+	return( item );
 }
 
 static void
-execute_action( NautilusMenuItem *item, NautilusActionsConfigActionProfile *action_profile )
+execute_action( NautilusMenuItem *item, NactActionProfile *profile )
 {
 	static const gchar *thisfn = "nautilus_actions_execute_action";
-	g_debug( "%s", thisfn );
+	g_debug( "%s: item=%p, profile=%p", thisfn, item, profile );
 
 	GList *files;
 	GString *cmd;
-	gchar* param = NULL;
+	gchar *param, *path;
 
-	files = (GList*)g_object_get_data (G_OBJECT (item), "files");
+	files = ( GList* ) g_object_get_data( G_OBJECT( item ), "files" );
 
-	cmd = g_string_new (action_profile->path);
+	path = nact_action_profile_get_path( profile );
+	cmd = g_string_new( path );
 
-	param = nautilus_actions_utils_parse_parameter (action_profile->parameters, files);
+	/*param = nautilus_actions_utils_parse_parameter (action_profile->parameters, files);*/
+	param = nact_action_profile_parse_parameters( profile, files );
 
-	if (param != NULL)
-	{
-		g_string_append_printf (cmd, " %s", param);
-		g_free (param);
+	if( param != NULL ){
+		g_string_append_printf( cmd, " %s", param );
+		g_free( param );
 	}
 
-	g_spawn_command_line_async (cmd->str, NULL);
-	g_debug( "%s: commande='%s'", thisfn, cmd->str );
+	g_debug( "%s: executing '%s'", thisfn, cmd->str );
+	g_spawn_command_line_async( cmd->str, NULL );
 
 	g_string_free (cmd, TRUE);
+	g_free( path );
 
 }
 
@@ -472,7 +482,7 @@ action_changed_handler( NautilusActions *self, gpointer user_data )
 	}
 }
 
-static void
+/*static void
 action_changed_handler_old( NautilusActionsConfig* config,
 						NautilusActionsConfigAction* action,
 						gpointer user_data )
@@ -491,4 +501,4 @@ action_changed_handler_old( NautilusActionsConfig* config,
 		nautilus_actions_config_free_actions_list (self->private->config_list);
 		self->private->config_list = nautilus_actions_config_get_actions (NAUTILUS_ACTIONS_CONFIG (self->private->configs));
 	}
-}
+}*/



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