[nautilus-actions] New na_icontext_conditions_is_candidate() function



commit 3ff722e001a3e99082b1a87019eacd76953308d6
Author: Pierre Wieser <pwieser trychlos org>
Date:   Thu Mar 4 02:11:46 2010 +0100

    New na_icontext_conditions_is_candidate() function

 ChangeLog                                          |   19 +
 src/api/Makefile.am                                |    1 -
 src/api/na-object-action.h                         |    2 +-
 src/core/Makefile.am                               |    5 +-
 src/core/na-iconditions.c                          |  127 -----
 ...-factory.c => na-icontext-conditions-factory.c} |    0
 src/core/na-icontext-conditions.c                  |  553 ++++++++++++++++++++
 .../na-icontext-conditions.h}                      |   36 +-
 src/core/na-object-action.c                        |   10 +-
 src/core/na-object-profile.c                       |  123 +----
 src/plugin-menu/nautilus-actions.c                 |  112 +++-
 11 files changed, 690 insertions(+), 298 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index fcb80da..8389701 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,24 @@
 2009-03-03 Pierre Wieser <pwieser trychlos org>
 
+	Rename the NAIConditions interface to NAIContextConditions
+	(hopefully, there will be a NAIContextParameters some day :)).
+
+	* src/core/na-iconditions-factory.c:
+	Renamed as src/core/na-icontext-conditions-factory.c.
+
+	* src/core/na-iconditions.c:
+	Renamed as src/core/na-icontext-conditions.c.
+
+	* src/api/na-iconditions.h:
+	Renamed as src/core/na-icontext-conditions.h.
+
+	* src/api/Makefile.am:
+	* src/core/Makefile.am: Updated accordingly.
+
+	* src/core/na-object-profile.c:
+	* src/plugin-menu/nautilus-actions.c:
+	Use new na_icontext_conditions_is_candidate() function.
+
 	Define the NAIConditions interface, to be implemented by actions,
 	profiles and menus (for now, only profiles).
 
diff --git a/src/api/Makefile.am b/src/api/Makefile.am
index c28c776..83a4ecf 100644
--- a/src/api/Makefile.am
+++ b/src/api/Makefile.am
@@ -44,7 +44,6 @@ api_include_HEADERS = \
 	na-data-types.h										\
 	na-gconf-monitor.h									\
 	na-gconf-utils.h									\
-	na-iconditions.h									\
 	na-iduplicable.h									\
 	na-ifactory-object.h								\
 	na-ifactory-object-data.h							\
diff --git a/src/api/na-object-action.h b/src/api/na-object-action.h
index 37923a1..3af150c 100644
--- a/src/api/na-object-action.h
+++ b/src/api/na-object-action.h
@@ -82,7 +82,7 @@ NAObjectAction *na_object_action_new_with_defaults( void );
 gchar          *na_object_action_get_new_profile_name( const NAObjectAction *action );
 void            na_object_action_attach_profile( NAObjectAction *action, NAObjectProfile *profile );
 
-gboolean        na_object_action_is_candidate( const NAObjectAction *action, gint target );
+gboolean        na_object_action_is_candidate( const NAObjectAction *action, guint target );
 
 G_END_DECLS
 
diff --git a/src/core/Makefile.am b/src/core/Makefile.am
index 5d536d4..67d7533 100644
--- a/src/core/Makefile.am
+++ b/src/core/Makefile.am
@@ -59,8 +59,9 @@ libna_core_la_SOURCES = \
 	na-gtk-utils.h										\
 	na-iabout.c											\
 	na-iabout.h											\
-	na-iconditions.c									\
-	na-iconditions-factory.c							\
+	na-icontext-conditions.c							\
+	na-icontext-conditions.h							\
+	na-icontext-conditions-factory.c					\
 	na-iduplicable.c									\
 	na-iexporter.c										\
 	na-ifactory-object.c								\
diff --git a/src/core/na-iconditions-factory.c b/src/core/na-icontext-conditions-factory.c
similarity index 100%
rename from src/core/na-iconditions-factory.c
rename to src/core/na-icontext-conditions-factory.c
diff --git a/src/core/na-icontext-conditions.c b/src/core/na-icontext-conditions.c
new file mode 100644
index 0000000..ce550bd
--- /dev/null
+++ b/src/core/na-icontext-conditions.c
@@ -0,0 +1,553 @@
+/*
+ * Nautilus Actions
+ * A Nautilus extension which offers configurable context menu actions.
+ *
+ * Copyright (C) 2005 The GNOME Foundation
+ * Copyright (C) 2006, 2007, 2008 Frederic Ruaudel and others (see AUTHORS)
+ * Copyright (C) 2009, 2010 Pierre Wieser and others (see AUTHORS)
+ *
+ * This Program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this Library; see the file COPYING.  If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place,
+ * Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Authors:
+ *   Frederic Ruaudel <grumz grumz net>
+ *   Rodrigo Moya <rodrigo gnome-db org>
+ *   Pierre Wieser <pwieser trychlos org>
+ *   ... and many others (see AUTHORS)
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string.h>
+
+#include <libnautilus-extension/nautilus-file-info.h>
+
+#include <api/na-core-utils.h>
+#include <api/na-object-api.h>
+
+#include "na-icontext-conditions.h"
+#include "na-dbus-tracker.h"
+#include "na-gnome-vfs-uri.h"
+
+/* private interface data
+ */
+struct NAIContextConditionsInterfacePrivate {
+	void *empty;						/* so that gcc -pedantic is happy */
+};
+
+static gboolean st_initialized = FALSE;
+static gboolean st_finalized   = FALSE;
+
+static GType    register_type( void );
+static void     interface_base_init( NAIContextConditionsInterface *klass );
+static void     interface_base_finalize( NAIContextConditionsInterface *klass );
+
+static gboolean is_target_background_candidate( const NAIContextConditions *profile, NautilusFileInfo *current_folder );
+static gboolean is_target_toolbar_candidate( const NAIContextConditions *profile, NautilusFileInfo *current_folder );
+static gboolean is_current_folder_inside( const NAIContextConditions *profile, NautilusFileInfo *current_folder );
+static gboolean is_target_selection_candidate( const NAIContextConditions *profile, GList *files, gboolean from_nautilus );
+
+static gboolean tracked_is_directory( void *iter, gboolean from_nautilus );
+static gchar   *tracked_to_basename( void *iter, gboolean from_nautilus );
+static gchar   *tracked_to_mimetype( void *iter, gboolean from_nautilus );
+static gchar   *tracked_to_scheme( void *iter, gboolean from_nautilus );
+static int      validate_schemes( GSList *schemes2test, void *iter, gboolean from_nautilus );
+
+/**
+ * na_icontext_conditions_get_type:
+ *
+ * Returns: the #GType type of this interface.
+ */
+GType
+na_icontext_conditions_get_type( void )
+{
+	static GType type = 0;
+
+	if( !type ){
+		type = register_type();
+	}
+
+	return( type );
+}
+
+/*
+ * na_icontext_conditions_register_type:
+ *
+ * Registers this interface.
+ */
+static GType
+register_type( void )
+{
+	static const gchar *thisfn = "na_icontext_conditions_register_type";
+	GType type;
+
+	static const GTypeInfo info = {
+		sizeof( NAIContextConditionsInterface ),
+		( GBaseInitFunc ) interface_base_init,
+		( GBaseFinalizeFunc ) interface_base_finalize,
+		NULL,
+		NULL,
+		NULL,
+		0,
+		0,
+		NULL
+	};
+
+	g_debug( "%s", thisfn );
+
+	type = g_type_register_static( G_TYPE_INTERFACE, "NAIContextConditions", &info, 0 );
+
+	g_type_interface_add_prerequisite( type, G_TYPE_OBJECT );
+
+	return( type );
+}
+
+static void
+interface_base_init( NAIContextConditionsInterface *klass )
+{
+	static const gchar *thisfn = "na_icontext_conditions_interface_base_init";
+
+	if( !st_initialized ){
+
+		g_debug( "%s: klass%p (%s)", thisfn, ( void * ) klass, G_OBJECT_CLASS_NAME( klass ));
+
+		klass->private = g_new0( NAIContextConditionsInterfacePrivate, 1 );
+
+		st_initialized = TRUE;
+	}
+}
+
+static void
+interface_base_finalize( NAIContextConditionsInterface *klass )
+{
+	static const gchar *thisfn = "na_icontext_conditions_interface_base_finalize";
+
+	if( st_initialized && !st_finalized ){
+
+		g_debug( "%s: klass=%p", thisfn, ( void * ) klass );
+
+		st_finalized = TRUE;
+
+		g_free( klass->private );
+	}
+}
+
+/**
+ * na_object_profile_is_candidate:
+ * @profile: the #NAObjectProfile to be checked.
+ * @target: the current target.
+ * @files: the currently selected items, as provided by Nautilus.
+ *
+ * Determines if the given profile is candidate to be displayed in the
+ * Nautilus context menu, regarding the list of currently selected
+ * items.
+ *
+ * Returns: %TRUE if this profile succeeds to all tests and is so a
+ * valid candidate to be displayed in Nautilus context menu, %FALSE
+ * else.
+ *
+ * This method could have been left outside of the #NAObjectProfile
+ * class, as it is only called by the plugin. Nonetheless, it is much
+ * more easier to code here (because we don't need all get methods, nor
+ * free the parameters after).
+ */
+gboolean
+na_icontext_conditions_is_candidate( const NAIContextConditions *object, guint target, GList *files )
+{
+	gboolean is_candidate;
+
+	g_return_val_if_fail( NA_IS_ICONTEXT_CONDITIONS( object ), FALSE );
+
+	if( !na_object_is_valid( object )){
+		return( FALSE );
+	}
+
+	is_candidate = FALSE;
+
+	switch( target ){
+		case ITEM_TARGET_BACKGROUND:
+			is_candidate = is_target_background_candidate( object, ( NautilusFileInfo * ) files->data );
+			break;
+
+		case ITEM_TARGET_TOOLBAR:
+			is_candidate = is_target_toolbar_candidate( object, ( NautilusFileInfo * ) files->data );
+			break;
+
+		case ITEM_TARGET_SELECTION:
+		default:
+			is_candidate = is_target_selection_candidate( object, files, TRUE );
+	}
+
+	return( is_candidate );
+}
+
+static gboolean
+is_target_background_candidate( const NAIContextConditions *object, NautilusFileInfo *current_folder )
+{
+	gboolean is_candidate;
+
+	is_candidate = is_current_folder_inside( object, current_folder );
+
+	return( is_candidate );
+}
+
+static gboolean
+is_target_toolbar_candidate( const NAIContextConditions *object, NautilusFileInfo *current_folder )
+{
+	gboolean is_candidate;
+
+	is_candidate = is_current_folder_inside( object, current_folder );
+
+	return( is_candidate );
+}
+
+static gboolean
+is_current_folder_inside( const NAIContextConditions *object, NautilusFileInfo *current_folder )
+{
+	gboolean is_inside;
+	GSList *folders, *ifold;
+	const gchar *path;
+	gchar *current_folder_uri;
+
+	is_inside = FALSE;
+	current_folder_uri = nautilus_file_info_get_uri( current_folder );
+	folders = na_object_get_folders( object );
+
+	for( ifold = folders ; ifold && !is_inside ; ifold = ifold->next ){
+		path = ( const gchar * ) ifold->data;
+		if( path && g_utf8_strlen( path, -1 )){
+			if( !strcmp( path, "*" )){
+				is_inside = TRUE;
+			} else {
+				is_inside = g_str_has_prefix( current_folder_uri, path );
+				g_debug( "na_object_object_is_current_folder_inside: current_folder_uri=%s, path=%s, is_inside=%s", current_folder_uri, path, is_inside ? "True":"False" );
+			}
+		}
+	}
+
+	na_core_utils_slist_free( folders );
+	g_free( current_folder_uri );
+
+	return( is_inside );
+}
+
+static gboolean
+is_target_selection_candidate( const NAIContextConditions *object, GList *files, gboolean from_nautilus )
+{
+	gboolean retv = FALSE;
+	GSList *basenames, *mimetypes, *schemes;
+	gboolean matchcase, multiple, isdir, isfile;
+	gboolean test_multiple_file = FALSE;
+	gboolean test_file_type = FALSE;
+	gboolean test_scheme = FALSE;
+	gboolean test_basename = FALSE;
+	gboolean test_mimetype = FALSE;
+	GList* glob_patterns = NULL;
+	GList* glob_mime_patterns = NULL;
+	GSList* iter;
+	GList* iter1;
+	GList* iter2;
+	guint dir_count = 0;
+	guint file_count = 0;
+	guint total_count = 0;
+	guint scheme_ok_count = 0;
+	guint glob_ok_count = 0;
+	guint mime_glob_ok_count = 0;
+	gboolean basename_match_ok = FALSE;
+	gboolean mimetype_match_ok = FALSE;
+	gchar *tmp_pattern, *tmp_filename, *tmp_filename2, *tmp_mimetype, *tmp_mimetype2;
+
+	basenames = na_object_get_basenames( object );
+	matchcase = na_object_is_matchcase( object );
+	multiple = na_object_is_multiple( object );
+	isdir = na_object_is_dir( object );
+	isfile = na_object_is_file( object );
+	mimetypes = na_object_get_mimetypes( object );
+	schemes = na_object_get_schemes( object );
+
+	if( basenames && basenames->next != NULL &&
+			g_ascii_strcasecmp(( gchar * )( basenames->data ), "*" ) == 0 ){
+		/* if the only pattern is '*' then all files will match, so it
+		 * is not necessary to make the test for each of them
+		 */
+		test_basename = TRUE;
+
+	} else {
+		for (iter = basenames ; iter ; iter = iter->next ){
+
+			tmp_pattern = ( gchar * ) iter->data;
+			if( !matchcase ){
+				/* --> if case-insensitive asked, lower all the string
+				 * since the pattern matching function don't manage it
+				 * itself.
+				 */
+				tmp_pattern = g_ascii_strdown(( gchar * ) iter->data, strlen(( gchar * ) iter->data ));
+			}
+
+			glob_patterns = g_list_append( glob_patterns, g_pattern_spec_new( tmp_pattern ));
+
+			if( !matchcase ){
+				g_free( tmp_pattern );
+			}
+		}
+	}
+
+	if( mimetypes && mimetypes->next != NULL &&
+			( g_ascii_strcasecmp(( gchar * )( mimetypes->data ), "*" ) == 0 ||
+			  g_ascii_strcasecmp(( gchar * )( mimetypes->data), "*/*") == 0 )){
+		/* if the only pattern is '*' or * / * then all mimetypes will
+		 * match, so it is not necessary to make the test for each of them
+		 */
+		test_mimetype = TRUE;
+
+	} else {
+		for( iter = mimetypes ; iter ; iter = iter->next ){
+			glob_mime_patterns = g_list_append( glob_mime_patterns, g_pattern_spec_new(( gchar * ) iter->data ));
+		}
+	}
+
+	for( iter1 = files; iter1; iter1 = iter1->next ){
+
+		tmp_filename = tracked_to_basename( iter1->data, from_nautilus );
+
+		if( tmp_filename ){
+			tmp_mimetype = tracked_to_mimetype( iter1->data, from_nautilus );
+
+			if( !matchcase ){
+				/* --> if case-insensitive asked, lower all the string
+				 * since the pattern matching function don't manage it
+				 * itself.
+				 */
+				tmp_filename2 = g_ascii_strdown( tmp_filename, strlen( tmp_filename ));
+				g_free( tmp_filename );
+				tmp_filename = tmp_filename2;
+			}
+
+			/* --> for the moment we deal with all mimetypes case-insensitively */
+			tmp_mimetype2 = g_ascii_strdown( tmp_mimetype, strlen( tmp_mimetype ));
+			g_free( tmp_mimetype );
+			tmp_mimetype = tmp_mimetype2;
+
+			if( tracked_is_directory( iter1->data, from_nautilus )){
+				dir_count++;
+			} else {
+				file_count++;
+			}
+
+			scheme_ok_count += validate_schemes( schemes, iter1->data, from_nautilus );
+
+			if( !test_basename ){ /* if it is already ok, skip the test to improve performance */
+				basename_match_ok = FALSE;
+				iter2 = glob_patterns;
+				while( iter2 && !basename_match_ok ){
+					if( g_pattern_match_string(( GPatternSpec * ) iter2->data, tmp_filename )){
+						basename_match_ok = TRUE;
+					}
+					iter2 = iter2->next;
+				}
+
+				if( basename_match_ok ){
+					glob_ok_count++;
+				}
+			}
+
+			if( !test_mimetype ){ /* if it is already ok, skip the test to improve performance */
+				mimetype_match_ok = FALSE;
+				iter2 = glob_mime_patterns;
+				while( iter2 && !mimetype_match_ok ){
+					if (g_pattern_match_string(( GPatternSpec * ) iter2->data, tmp_mimetype )){
+						mimetype_match_ok = TRUE;
+					}
+					iter2 = iter2->next;
+				}
+
+				if( mimetype_match_ok ){
+					mime_glob_ok_count++;
+				}
+			}
+
+			g_free( tmp_mimetype );
+			g_free( tmp_filename );
+		}
+
+		total_count++;
+	}
+
+	if(( files != NULL ) && ( files->next == NULL ) && ( !multiple )){
+		test_multiple_file = TRUE;
+
+	} else if( multiple ){
+		test_multiple_file = TRUE;
+	}
+
+	if( isdir && isfile ){
+		if( dir_count > 0 || file_count > 0 ){
+			test_file_type = TRUE;
+		}
+	} else if( isdir && !isfile ){
+		if( file_count == 0 ){
+			test_file_type = TRUE;
+		}
+	} else if( !isdir && isfile ){
+		if( dir_count == 0 ){
+			test_file_type = TRUE;
+		}
+	}
+
+	if( scheme_ok_count == total_count ){
+		test_scheme = TRUE;
+	}
+
+	if( !test_basename ){ /* if not already tested */
+		if( glob_ok_count == total_count ){
+			test_basename = TRUE;
+		}
+	}
+
+	if( !test_mimetype ){ /* if not already tested */
+		if( mime_glob_ok_count == total_count ){
+			test_mimetype = TRUE;
+		}
+	}
+
+	if( test_basename && test_mimetype && test_file_type && test_scheme && test_multiple_file ){
+		retv = TRUE;
+	}
+
+	g_list_foreach (glob_patterns, (GFunc) g_pattern_spec_free, NULL);
+	g_list_free (glob_patterns);
+	g_list_foreach (glob_mime_patterns, (GFunc) g_pattern_spec_free, NULL);
+	g_list_free (glob_mime_patterns);
+	na_core_utils_slist_free( schemes );
+	na_core_utils_slist_free( mimetypes );
+	na_core_utils_slist_free( basenames );
+
+	return retv;
+}
+
+static gboolean
+tracked_is_directory( void *iter, gboolean from_nautilus )
+{
+	gboolean is_dir;
+	GFile *file;
+	GFileType type;
+
+	if( from_nautilus ){
+		is_dir = nautilus_file_info_is_directory(( NautilusFileInfo * ) iter );
+
+	} else {
+		file = g_file_new_for_uri((( NATrackedItem * ) iter )->uri );
+		type = g_file_query_file_type( file, G_FILE_QUERY_INFO_NONE, NULL );
+		is_dir = ( type == G_FILE_TYPE_DIRECTORY );
+		g_object_unref( file );
+	}
+
+	return( is_dir );
+}
+
+static gchar *
+tracked_to_basename( void *iter, gboolean from_nautilus )
+{
+	gchar *bname;
+	GFile *file;
+
+	if( from_nautilus ){
+		bname = nautilus_file_info_get_name(( NautilusFileInfo * ) iter );
+
+	} else {
+		file = g_file_new_for_uri((( NATrackedItem * ) iter )->uri );
+		bname = g_file_get_basename( file );
+		g_object_unref( file );
+	}
+
+	return( bname );
+}
+
+static gchar *
+tracked_to_mimetype( void *iter, gboolean from_nautilus )
+{
+	gchar *type;
+	NATrackedItem *tracked;
+	GFile *file;
+	GFileInfo *info;
+
+	type = NULL;
+	if( from_nautilus ){
+		type = nautilus_file_info_get_mime_type(( NautilusFileInfo * ) iter );
+
+	} else {
+		tracked = ( NATrackedItem * ) iter;
+		if( tracked->mimetype ){
+			type = g_strdup( tracked->mimetype );
+
+		} else {
+			file = g_file_new_for_uri((( NATrackedItem * ) iter )->uri );
+			info = g_file_query_info( file, G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE, G_FILE_QUERY_INFO_NONE, NULL, NULL );
+			if( info ){
+				type = g_strdup( g_file_info_get_content_type( info ));
+				g_object_unref( info );
+			}
+			g_object_unref( file );
+		}
+	}
+
+	return( type );
+}
+
+static gchar *
+tracked_to_scheme( void *iter, gboolean from_nautilus )
+{
+	gchar *scheme;
+	NAGnomeVFSURI *vfs;
+
+	if( from_nautilus ){
+		scheme = nautilus_file_info_get_uri_scheme(( NautilusFileInfo * ) iter );
+
+	} else {
+		vfs = g_new0( NAGnomeVFSURI, 1 );
+		na_gnome_vfs_uri_parse( vfs, (( NATrackedItem * ) iter )->uri );
+		scheme = g_strdup( vfs->scheme );
+		na_gnome_vfs_uri_free( vfs );
+	}
+
+	return( scheme );
+}
+
+static int
+validate_schemes( GSList* schemes2test, void* tracked_iter, gboolean from_nautilus )
+{
+	int retv = 0;
+	GSList* iter;
+	gboolean found = FALSE;
+	gchar *scheme;
+
+	iter = schemes2test;
+	while( iter && !found ){
+
+		scheme = tracked_to_scheme( tracked_iter, from_nautilus );
+
+		if( g_ascii_strncasecmp( scheme, ( gchar * ) iter->data, strlen(( gchar * ) iter->data )) == 0 ){
+			found = TRUE;
+			retv = 1;
+		}
+
+		g_free( scheme );
+		iter = iter->next;
+	}
+
+	return retv;
+}
diff --git a/src/api/na-iconditions.h b/src/core/na-icontext-conditions.h
similarity index 55%
rename from src/api/na-iconditions.h
rename to src/core/na-icontext-conditions.h
index 17273a3..d3f9536 100644
--- a/src/api/na-iconditions.h
+++ b/src/core/na-icontext-conditions.h
@@ -28,13 +28,13 @@
  *   ... and many others (see AUTHORS)
  */
 
-#ifndef __NAUTILUS_ACTIONS_API_NA_ICONDITIONS_H__
-#define __NAUTILUS_ACTIONS_API_NA_ICONDITIONS_H__
+#ifndef __CORE_NA_ICONTEXT_CONDITIONS_H__
+#define __CORE_NA_ICONTEXT_CONDITIONS_H__
 
 /**
- * SECTION: na_iconditions
- * @short_description: #NAIConditions interface definition.
- * @include: nautilus-actions/na-iconditions.h
+ * SECTION: na_icontext_conditions
+ * @short_description: #NAIContextConditions interface definition.
+ * @include: core/na-icontext_conditions.h
  *
  * This interface is implemented by all #NAObject-derived objects
  * which must met some conditions in order to be displayed in the
@@ -45,27 +45,29 @@
  * data group.
  */
 
-#include "na-object.h"
+#include <glib-object.h>
 
 G_BEGIN_DECLS
 
-#define NA_ICONDITIONS_TYPE							( na_iobject_conditions_get_type())
-#define NA_ICONDITIONS( instance )					( G_TYPE_CHECK_INSTANCE_CAST( instance, NA_ICONDITIONS_TYPE, NAIConditions ))
-#define NA_IS_ICONDITIONS( instance )				( G_TYPE_CHECK_INSTANCE_TYPE( instance, NA_ICONDITIONS_TYPE ))
-#define NA_ICONDITIONS_GET_INTERFACE( instance )	( G_TYPE_INSTANCE_GET_INTERFACE(( instance ), NA_ICONDITIONS_TYPE, NAIConditionsInterface ))
+#define NA_ICONTEXT_CONDITIONS_TYPE							( na_icontext_conditions_get_type())
+#define NA_ICONTEXT_CONDITIONS( instance )					( G_TYPE_CHECK_INSTANCE_CAST( instance, NA_ICONTEXT_CONDITIONS_TYPE, NAIContextConditions ))
+#define NA_IS_ICONTEXT_CONDITIONS( instance )				( G_TYPE_CHECK_INSTANCE_TYPE( instance, NA_ICONTEXT_CONDITIONS_TYPE ))
+#define NA_ICONTEXT_CONDITIONS_GET_INTERFACE( instance )	( G_TYPE_INSTANCE_GET_INTERFACE(( instance ), NA_ICONTEXT_CONDITIONS_TYPE, NAIContextConditionsInterface ))
 
-typedef struct NAIConditions                 NAIConditions;
+typedef struct NAIContextConditions                 NAIContextConditions;
 
-typedef struct NAIConditionsInterfacePrivate NAIConditionsInterfacePrivate;
+typedef struct NAIContextConditionsInterfacePrivate NAIContextConditionsInterfacePrivate;
 
 typedef struct {
-	GTypeInterface                 parent;
-	NAIConditionsInterfacePrivate *private;
+	GTypeInterface                        parent;
+	NAIContextConditionsInterfacePrivate *private;
 }
-	NAIConditionsInterface;
+	NAIContextConditionsInterface;
 
-GType na_iconditions_get_type( void );
+GType    na_icontext_conditions_get_type( void );
+
+gboolean na_icontext_conditions_is_candidate( const NAIContextConditions *object, guint target, GList *selection );
 
 G_END_DECLS
 
-#endif /* __NAUTILUS_ACTIONS_API_NA_ICONDITIONS_H__ */
+#endif /* __CORE_NA_ICONTEXT_CONDITIONS_H__ */
diff --git a/src/core/na-object-action.c b/src/core/na-object-action.c
index 35d374b..2f4c8c7 100644
--- a/src/core/na-object-action.c
+++ b/src/core/na-object-action.c
@@ -629,21 +629,19 @@ na_object_action_attach_profile( NAObjectAction *action, NAObjectProfile *profil
  * Returns: %TRUE if the @action may be candidate for this @target.
  */
 gboolean
-na_object_action_is_candidate( const NAObjectAction *action, gint target )
+na_object_action_is_candidate( const NAObjectAction *action, guint target )
 {
 	gboolean is_candidate = FALSE;
 
-#if 0
 	g_return_val_if_fail( NA_IS_OBJECT_ACTION( action ), is_candidate );
 
 	if( !action->private->dispose_has_run ){
 
 		is_candidate =
-			( action->private->target_selection && target == ITEM_TARGET_SELECTION ) ||
-			( action->private->target_background && target == ITEM_TARGET_BACKGROUND ) ||
-			( action->private->target_toolbar && target == ITEM_TARGET_TOOLBAR );
+			( na_object_is_target_selection( action ) && target == ITEM_TARGET_SELECTION ) ||
+			( na_object_is_target_background( action ) && target == ITEM_TARGET_BACKGROUND ) ||
+			( na_object_is_target_toolbar( action ) && target == ITEM_TARGET_TOOLBAR );
 	}
-#endif
 
 	return( is_candidate );
 }
diff --git a/src/core/na-object-profile.c b/src/core/na-object-profile.c
index e5ff88a..1327b62 100644
--- a/src/core/na-object-profile.c
+++ b/src/core/na-object-profile.c
@@ -38,11 +38,11 @@
 #include <libnautilus-extension/nautilus-file-info.h>
 
 #include <api/na-core-utils.h>
-#include <api/na-iconditions.h>
 #include <api/na-iio-provider.h>
 #include <api/na-ifactory-object.h>
 #include <api/na-object-api.h>
 
+#include "na-icontext-conditions.h"
 #include "na-factory-provider.h"
 #include "na-factory-object.h"
 #include "na-dbus-tracker.h"
@@ -84,7 +84,7 @@ static gboolean     ifactory_object_is_valid( const NAIFactoryObject *object );
 static void         ifactory_object_read_done( NAIFactoryObject *instance, const NAIFactoryProvider *reader, void *reader_data, GSList **messages );
 static guint        ifactory_object_write_done( NAIFactoryObject *instance, const NAIFactoryProvider *writer, void *writer_data, GSList **messages );
 
-static void         iconditions_iface_init( NAIConditionsInterface *iface );
+static void         icontext_conditions_iface_init( NAIContextConditionsInterface *iface );
 
 static gboolean     profile_is_valid( const NAObjectProfile *profile );
 static gboolean     is_valid_path_parameters( const NAObjectProfile *profile );
@@ -96,11 +96,7 @@ static gboolean     is_valid_folders( const NAObjectProfile *profile );
 
 static gchar       *object_id_new_id( const NAObjectId *item, const NAObjectId *new_parent );
 
-static gboolean     is_target_background_candidate( const NAObjectProfile *profile, NautilusFileInfo *current_folder );
-static gboolean     is_target_toolbar_candidate( const NAObjectProfile *profile, NautilusFileInfo *current_folder );
-static gboolean     is_current_folder_inside( const NAObjectProfile *profile, NautilusFileInfo *current_folder );
 static gboolean     is_target_selection_candidate( const NAObjectProfile *profile, GList *files, gboolean from_nautilus );
-
 static gchar       *parse_parameters( const NAObjectProfile *profile, gint target, GList* files, gboolean from_nautilus );
 static gboolean     tracked_is_directory( void *iter, gboolean from_nautilus );
 static gchar       *tracked_to_basename( void *iter, gboolean from_nautilus );
@@ -140,8 +136,8 @@ register_type( void )
 		( GInstanceInitFunc ) instance_init
 	};
 
-	static const GInterfaceInfo iconditions_iface_info = {
-		( GInterfaceInitFunc ) iconditions_iface_init,
+	static const GInterfaceInfo icontext_conditions_iface_info = {
+		( GInterfaceInitFunc ) icontext_conditions_iface_init,
 		NULL,
 		NULL
 	};
@@ -156,7 +152,7 @@ register_type( void )
 
 	type = g_type_register_static( NA_OBJECT_ID_TYPE, "NAObjectProfile", &info, 0 );
 
-	g_type_add_interface_static( type, NA_ICONDITIONS_TYPE, &iconditions_iface_info );
+	g_type_add_interface_static( type, NA_ICONTEXT_CONDITIONS_TYPE, &icontext_conditions_iface_info );
 
 	g_type_add_interface_static( type, NA_IFACTORY_OBJECT_TYPE, &ifactory_object_iface_info );
 
@@ -357,9 +353,9 @@ ifactory_object_write_done( NAIFactoryObject *instance, const NAIFactoryProvider
 }
 
 static void
-iconditions_iface_init( NAIConditionsInterface *iface )
+icontext_conditions_iface_init( NAIContextConditionsInterface *iface )
 {
-	static const gchar *thisfn = "na_object_profile_iconditions_iface_init";
+	static const gchar *thisfn = "na_object_profile_icontext_conditions_iface_init";
 
 	g_debug( "%s: iface=%p", thisfn, ( void * ) iface );
 }
@@ -630,55 +626,6 @@ na_object_profile_replace_folder( NAObjectProfile *profile, const gchar *old, co
 }
 
 /**
- * na_object_profile_is_candidate:
- * @profile: the #NAObjectProfile to be checked.
- * @target: the current target.
- * @files: the currently selected items, as provided by Nautilus.
- *
- * Determines if the given profile is candidate to be displayed in the
- * Nautilus context menu, regarding the list of currently selected
- * items.
- *
- * Returns: %TRUE if this profile succeeds to all tests and is so a
- * valid candidate to be displayed in Nautilus context menu, %FALSE
- * else.
- *
- * This method could have been left outside of the #NAObjectProfile
- * class, as it is only called by the plugin. Nonetheless, it is much
- * more easier to code here (because we don't need all get methods, nor
- * free the parameters after).
- */
-gboolean
-na_object_profile_is_candidate( const NAObjectProfile *profile, gint target, GList *files )
-{
-	gboolean is_candidate;
-
-	g_return_val_if_fail( NA_IS_OBJECT_PROFILE( profile ), FALSE );
-
-	if( !na_object_is_valid( profile )){
-		return( FALSE );
-	}
-
-	is_candidate = FALSE;
-
-	switch( target ){
-		case ITEM_TARGET_BACKGROUND:
-			is_candidate = is_target_background_candidate( profile, ( NautilusFileInfo * ) files->data );
-			break;
-
-		case ITEM_TARGET_TOOLBAR:
-			is_candidate = is_target_toolbar_candidate( profile, ( NautilusFileInfo * ) files->data );
-			break;
-
-		case ITEM_TARGET_SELECTION:
-		default:
-			is_candidate = is_target_selection_candidate( profile, files, TRUE );
-	}
-
-	return( is_candidate );
-}
-
-/**
  * na_object_profile_is_candidate_for_tracked:
  * @profile: the #NAObjectProfile to be checked.
  * @files: the currently selected items, as a list of uris.
@@ -712,56 +659,6 @@ na_object_profile_is_candidate_for_tracked( const NAObjectProfile *profile, GLis
 }
 
 static gboolean
-is_target_background_candidate( const NAObjectProfile *profile, NautilusFileInfo *current_folder )
-{
-	gboolean is_candidate;
-
-	is_candidate = is_current_folder_inside( profile, current_folder );
-
-	return( is_candidate );
-}
-
-static gboolean
-is_target_toolbar_candidate( const NAObjectProfile *profile, NautilusFileInfo *current_folder )
-{
-	gboolean is_candidate;
-
-	is_candidate = is_current_folder_inside( profile, current_folder );
-
-	return( is_candidate );
-}
-
-static gboolean
-is_current_folder_inside( const NAObjectProfile *profile, NautilusFileInfo *current_folder )
-{
-	gboolean is_inside;
-	GSList *folders, *ifold;
-	const gchar *path;
-	gchar *current_folder_uri;
-
-	is_inside = FALSE;
-	current_folder_uri = nautilus_file_info_get_uri( current_folder );
-	folders = na_object_get_folders( profile );
-
-	for( ifold = folders ; ifold && !is_inside ; ifold = ifold->next ){
-		path = ( const gchar * ) ifold->data;
-		if( path && g_utf8_strlen( path, -1 )){
-			if( !strcmp( path, "*" )){
-				is_inside = TRUE;
-			} else {
-				is_inside = g_str_has_prefix( current_folder_uri, path );
-				g_debug( "na_object_profile_is_current_folder_inside: current_folder_uri=%s, path=%s, is_inside=%s", current_folder_uri, path, is_inside ? "True":"False" );
-			}
-		}
-	}
-
-	na_core_utils_slist_free( folders );
-	g_free( current_folder_uri );
-
-	return( is_inside );
-}
-
-static gboolean
 is_target_selection_candidate( const NAObjectProfile *profile, GList *files, gboolean from_nautilus )
 {
 	gboolean retv = FALSE;
@@ -787,12 +684,6 @@ is_target_selection_candidate( const NAObjectProfile *profile, GList *files, gbo
 	gboolean mimetype_match_ok = FALSE;
 	gchar *tmp_pattern, *tmp_filename, *tmp_filename2, *tmp_mimetype, *tmp_mimetype2;
 
-	g_return_val_if_fail( NA_IS_OBJECT_PROFILE( profile ), FALSE );
-
-	if( profile->private->dispose_has_run ){
-		return( FALSE );
-	}
-
 	basenames = na_object_get_basenames( profile );
 	matchcase = na_object_is_matchcase( profile );
 	multiple = na_object_is_multiple( profile );
diff --git a/src/plugin-menu/nautilus-actions.c b/src/plugin-menu/nautilus-actions.c
index 352da89..5099314 100644
--- a/src/plugin-menu/nautilus-actions.c
+++ b/src/plugin-menu/nautilus-actions.c
@@ -44,6 +44,7 @@
 
 #include <core/na-pivot.h>
 #include <core/na-iabout.h>
+#include <core/na-icontext-conditions.h>
 #include <core/na-iprefs.h>
 #include <core/na-ipivot-consumer.h>
 
@@ -81,16 +82,18 @@ static void              ipivot_consumer_display_about_changed( NAIPivotConsumer
 static void              ipivot_consumer_display_order_changed( NAIPivotConsumer *instance, gint order_mode );
 
 static void              menu_provider_iface_init( NautilusMenuProviderIface *iface );
+static GList            *menu_provider_get_background_items( NautilusMenuProvider *provider, GtkWidget *window, NautilusFileInfo *current_folder );
+static GList            *menu_provider_get_file_items( NautilusMenuProvider *provider, GtkWidget *window, GList *files );
+static GList            *menu_provider_get_toolbar_items( NautilusMenuProvider *provider, GtkWidget *window, NautilusFileInfo *current_folder );
 
-static GList            *get_background_items( NautilusMenuProvider *provider, GtkWidget *window, NautilusFileInfo *current_folder );
-static GList            *get_file_items( NautilusMenuProvider *provider, GtkWidget *window, GList *files );
-static GList            *get_toolbar_items( NautilusMenuProvider *provider, GtkWidget *window, NautilusFileInfo *current_folder );
-static GList            *build_nautilus_menus( NautilusActions *plugin, GList *tree, gint target, GList *files );
-static NAObjectProfile  *is_action_candidate( NautilusActions *plugin, NAObjectAction *action, gint target, GList *files );
-static NautilusMenuItem *create_item_from_profile( NAObjectProfile *profile, gint target, GList *files );
+static GList            *build_nautilus_menus( NautilusActions *plugin, GList *tree, guint target, GList *files );
+static NAObjectProfile  *is_action_candidate( NautilusActions *plugin, NAObjectAction *action, guint target, GList *files );
+static NautilusMenuItem *create_item_from_profile( NAObjectProfile *profile, guint target, GList *files );
 static NautilusMenuItem *create_item_from_menu( NAObjectMenu *menu, GList *subitems );
 static NautilusMenuItem *create_menu_item( NAObjectItem *item );
 static void              attach_submenu_to_item( NautilusMenuItem *item, GList *subitems );
+static void              weak_notify_profile( NAObjectProfile *profile, NautilusMenuItem *item );
+static void              destroy_notify_file_list( GList *list);
 
 static void              execute_action( NautilusMenuItem *item, NAObjectProfile *profile );
 
@@ -374,9 +377,9 @@ menu_provider_iface_init( NautilusMenuProviderIface *iface )
 
 	g_debug( "%s: iface=%p", thisfn, ( void * ) iface );
 
-	iface->get_file_items = get_file_items;
-	iface->get_background_items = get_background_items;
-	iface->get_toolbar_items = get_toolbar_items;
+	iface->get_file_items = menu_provider_get_file_items;
+	iface->get_background_items = menu_provider_get_background_items;
+	iface->get_toolbar_items = menu_provider_get_toolbar_items;
 }
 
 /*
@@ -393,13 +396,15 @@ menu_provider_iface_init( NautilusMenuProviderIface *iface )
  * - or when there is only one selected directory
  */
 static GList *
-get_background_items( NautilusMenuProvider *provider, GtkWidget *window, NautilusFileInfo *current_folder )
+menu_provider_get_background_items( NautilusMenuProvider *provider, GtkWidget *window, NautilusFileInfo *current_folder )
 {
-	static const gchar *thisfn = "nautilus_actions_get_background_items";
+	static const gchar *thisfn = "nautilus_actions_menu_provider_get_background_items";
 	GList *nautilus_menus_list = NULL;
 	gchar *uri;
 	GList *files;
 	GList *pivot_tree;
+	gboolean add_about;
+	gboolean root_menu;
 
 	if( !NAUTILUS_ACTIONS( provider )->private->dispose_has_run ){
 
@@ -409,9 +414,23 @@ get_background_items( NautilusMenuProvider *provider, GtkWidget *window, Nautilu
 		g_free( uri );
 
 		files = g_list_prepend( NULL, current_folder );
+
 		pivot_tree = na_pivot_get_items( NAUTILUS_ACTIONS( provider )->private->pivot );
+
 		nautilus_menus_list = build_nautilus_menus(
 				NAUTILUS_ACTIONS( provider ), pivot_tree, ITEM_TARGET_BACKGROUND, files );
+
+		root_menu = na_iprefs_read_bool( NA_IPREFS( NAUTILUS_ACTIONS( provider )->private->pivot ), IPREFS_CREATE_ROOT_MENU, FALSE );
+		if( root_menu ){
+			nautilus_menus_list = create_root_menu( NAUTILUS_ACTIONS( provider ), nautilus_menus_list );
+		}
+
+		add_about = na_iprefs_read_bool( NA_IPREFS( NAUTILUS_ACTIONS( provider )->private->pivot ), IPREFS_ADD_ABOUT_ITEM, TRUE );
+		/*g_debug( "%s: add_about=%s", thisfn, add_about ? "True":"False" );*/
+		if( add_about ){
+			nautilus_menus_list = add_about_item( NAUTILUS_ACTIONS( provider ), nautilus_menus_list );
+		}
+
 		g_list_free( files );
 	}
 
@@ -425,9 +444,9 @@ get_background_items( NautilusMenuProvider *provider, GtkWidget *window, Nautilu
  * b) in contextual menu while the selection stays unchanged
  */
 static GList *
-get_file_items( NautilusMenuProvider *provider, GtkWidget *window, GList *files )
+menu_provider_get_file_items( NautilusMenuProvider *provider, GtkWidget *window, GList *files )
 {
-	static const gchar *thisfn = "nautilus_actions_get_file_items";
+	static const gchar *thisfn = "nautilus_actions_menu_provider_get_file_items";
 	GList *nautilus_menus_list = NULL;
 	NautilusActions *self;
 	GList *pivot_tree;
@@ -478,9 +497,9 @@ get_file_items( NautilusMenuProvider *provider, GtkWidget *window, GList *files
  * get_background_items ; also, only actions (not menus) are displayed
  */
 static GList *
-get_toolbar_items( NautilusMenuProvider *provider, GtkWidget *window, NautilusFileInfo *current_folder )
+menu_provider_get_toolbar_items( NautilusMenuProvider *provider, GtkWidget *window, NautilusFileInfo *current_folder )
 {
-	static const gchar *thisfn = "nautilus_actions_get_toolbar_items";
+	static const gchar *thisfn = "nautilus_actions_menu_provider_get_toolbar_items";
 	GList *nautilus_menus_list = NULL;
 	gchar *uri;
 	GList *files;
@@ -494,9 +513,12 @@ get_toolbar_items( NautilusMenuProvider *provider, GtkWidget *window, NautilusFi
 	if( !NAUTILUS_ACTIONS( provider )->private->dispose_has_run ){
 
 		files = g_list_prepend( NULL, current_folder );
+
 		pivot_tree = na_pivot_get_items( NAUTILUS_ACTIONS( provider )->private->pivot );
+
 		nautilus_menus_list = build_nautilus_menus(
 				NAUTILUS_ACTIONS( provider ), pivot_tree, ITEM_TARGET_TOOLBAR, files );
+
 		g_list_free( files );
 	}
 
@@ -507,7 +529,7 @@ get_toolbar_items( NautilusMenuProvider *provider, GtkWidget *window, NautilusFi
  * when building a menu for the toolbar, do not use menus hierarchy
  */
 static GList *
-build_nautilus_menus( NautilusActions *plugin, GList *tree, gint target, GList *files )
+build_nautilus_menus( NautilusActions *plugin, GList *tree, guint target, GList *files )
 {
 	static const gchar *thisfn = "nautilus_actions_build_file_selection_menus";
 	GList *menus_list = NULL;
@@ -525,6 +547,9 @@ build_nautilus_menus( NautilusActions *plugin, GList *tree, gint target, GList *
 
 		g_return_val_if_fail( NA_IS_OBJECT_ITEM( it->data ), NULL );
 
+		/* check this here as a security though NAPivot should only have
+		 * loaded valid and enabled items
+		 */
 		if( !na_object_is_enabled( it->data ) ||
 			!na_object_is_valid( it->data )){
 
@@ -536,14 +561,18 @@ build_nautilus_menus( NautilusActions *plugin, GList *tree, gint target, GList *
 				continue;
 		}
 
+		/* recursively build sub-menus
+		 */
 		if( NA_IS_OBJECT_MENU( it->data )){
 			subitems = na_object_get_items( it->data );
 			submenu = build_nautilus_menus( plugin, subitems, target, files );
 			/*g_debug( "%s: submenu has %d items", thisfn, g_list_length( submenu ));*/
+
 			if( submenu ){
 				if( target != ITEM_TARGET_TOOLBAR ){
 					item = create_item_from_menu( NA_OBJECT_MENU( it->data ), submenu );
 					menus_list = g_list_append( menus_list, item );
+
 				} else {
 					menus_list = g_list_concat( menus_list, submenu );
 				}
@@ -567,7 +596,7 @@ build_nautilus_menus( NautilusActions *plugin, GList *tree, gint target, GList *
  * could also be a NAObjectAction method - but this is not used elsewhere
  */
 static NAObjectProfile *
-is_action_candidate( NautilusActions *plugin, NAObjectAction *action, gint target, GList *files )
+is_action_candidate( NautilusActions *plugin, NAObjectAction *action, guint target, GList *files )
 {
 	static const gchar *thisfn = "nautilus_actions_is_action_candidate";
 	NAObjectProfile *candidate = NULL;
@@ -578,15 +607,14 @@ is_action_candidate( NautilusActions *plugin, NAObjectAction *action, gint targe
 	if( na_object_action_is_candidate( action, target )){
 
 		action_label = na_object_get_label( action );
-
 		profiles = na_object_get_items( action );
-		for( ip = profiles ; ip && !candidate ; ip = ip->next ){
 
+		for( ip = profiles ; ip && !candidate ; ip = ip->next ){
 			NAObjectProfile *profile = NA_OBJECT_PROFILE( ip->data );
-			if( na_object_profile_is_candidate( profile, target, files )){
 
+			if( na_icontext_conditions_is_candidate( NA_ICONTEXT_CONDITIONS( profile ), target, files )){
 				profile_label = na_object_get_label( profile );
-				g_debug( "%s: selecting %s - %s", thisfn, action_label, profile_label );
+				g_debug( "%s: selecting %s (%s)", thisfn, action_label, profile_label );
 				g_free( profile_label );
 
 				candidate = profile;
@@ -600,7 +628,7 @@ is_action_candidate( NautilusActions *plugin, NAObjectAction *action, gint targe
 }
 
 static NautilusMenuItem *
-create_item_from_profile( NAObjectProfile *profile, gint target, GList *files )
+create_item_from_profile( NAObjectProfile *profile, guint target, GList *files )
 {
 	NautilusMenuItem *item;
 	NAObjectAction *action;
@@ -611,26 +639,54 @@ create_item_from_profile( NAObjectProfile *profile, gint target, GList *files )
 	item = create_menu_item( NA_OBJECT_ITEM( action ));
 
 	dup4menu = NA_OBJECT_PROFILE( na_object_duplicate( profile ));
+	g_debug( "nautilus_actions_create_item_from_profile: creating profile=%p", ( void * ) dup4menu );
 
-	g_signal_connect_data( item,
+	/* closure is only called when signal is disconnected
+	 * potentially only at the end of the session if Nautilus paints the desktop !
+	 */
+	/*g_signal_connect_data( item,
 				"activate",
 				G_CALLBACK( execute_action ),
 				dup4menu,
 				( GClosureNotify ) g_object_unref,
-				0 );
+				0 );*/
+
+	/* rather attach a weak ref on the Nautilus menu item: our duplicated
+	 * profile will so be disposed during the session
+	 */
+	g_signal_connect( item,
+				"activate",
+				G_CALLBACK( execute_action ),
+				dup4menu );
+	g_object_weak_ref( G_OBJECT( item ), ( GWeakNotify ) weak_notify_profile, dup4menu );
 
 	g_object_set_data_full( G_OBJECT( item ),
 			"nautilus-actions-files",
 			nautilus_file_info_list_copy( files ),
-			( GDestroyNotify ) nautilus_file_info_list_free );
+			( GDestroyNotify ) destroy_notify_file_list );
 
 	g_object_set_data( G_OBJECT( item ),
 			"nautilus-actions-target",
-			GINT_TO_POINTER( target ));
+			GUINT_TO_POINTER( target ));
 
 	return( item );
 }
 
+static void
+weak_notify_profile( NAObjectProfile *profile, NautilusMenuItem *item )
+{
+	g_debug( "nautilus_actions_weak_notify_profile: profile=%p (ref_count=%d)",
+			( void * ) profile, G_OBJECT( profile )->ref_count );
+	g_object_unref( profile );
+}
+
+static void
+destroy_notify_file_list( GList *list)
+{
+	g_debug( "nautilus_actions_destroy_notify_file_list" );
+	nautilus_file_info_list_free( list );
+}
+
 /*
  * note that each appended NautilusMenuItem is ref-ed by the NautilusMenu
  * we can so safely release our own ref on subitems after this function
@@ -694,12 +750,12 @@ execute_action( NautilusMenuItem *item, NAObjectProfile *profile )
 	GList *files;
 	GString *cmd;
 	gchar *param, *path;
-	gint target;
+	guint target;
 
 	g_debug( "%s: item=%p, profile=%p", thisfn, ( void * ) item, ( void * ) profile );
 
 	files = ( GList * ) g_object_get_data( G_OBJECT( item ), "nautilus-actions-files" );
-	target = GPOINTER_TO_INT( g_object_get_data( G_OBJECT( item ), "nautilus-actions-target" ));
+	target = GPOINTER_TO_UINT( g_object_get_data( G_OBJECT( item ), "nautilus-actions-target" ));
 
 	path = na_object_get_path( profile );
 	cmd = g_string_new( path );



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