[nautilus-actions] Define the NASelectedInfo class



commit bb57a1ce8b4b9d4843dfff3903b465fabf998a85
Author: Pierre Wieser <pwieser trychlos org>
Date:   Tue Mar 9 19:48:08 2010 +0100

    Define the NASelectedInfo class

 ChangeLog                                  |    5 +
 po/POTFILES.in                             |    2 +-
 src/api/Makefile.am                        |    1 +
 src/{core => api}/na-icontext-conditions.h |   29 ++-
 src/api/na-object-action.h                 |    3 +-
 src/api/na-object-api.h                    |   10 +-
 src/api/na-object-profile.h                |    9 +-
 src/core/Makefile.am                       |    3 +-
 src/core/na-icontext-conditions.c          |  301 ++++++++++++-------
 src/core/na-object-action.c                |    9 +-
 src/core/na-object-profile.c               |  318 +++++---------------
 src/core/na-selected-info.c                |  467 ++++++++++++++++++++++++++++
 src/core/na-selected-info.h                |   93 ++++++
 src/nact/nact-ifolders-tab.c               |    2 +-
 src/nact/nact-schemes-list.c               |    4 +-
 src/plugin-menu/nautilus-actions.c         |  117 ++++----
 src/plugin-tracker/na-tracker-dbus.c       |   16 +-
 src/utils/nautilus-actions-new.c           |    4 -
 src/utils/nautilus-actions-run.c           |   89 +++---
 19 files changed, 984 insertions(+), 498 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 2179e2c..3e70e8c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,10 @@
 2009-03-05 Pierre Wieser <pwieser trychlos org>
 
+	* src/core/na-selected-info.c:
+	* src/core/na-selected-info.h: New files.
+
+	* src/core/Makefile.am: Updated accordingly.
+
 	Refactor NactIBackgroundTab class as NactIFoldersTab.
 
 	* src/nact/nact-ibackground-tab.c:
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 13d7870..7a1fa96 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -29,8 +29,8 @@ src/nact/nact.desktop.in
 src/nact/nact-export-ask.c
 src/nact/nact-export-format.c
 src/nact/nact-iaction-tab.c
-src/nact/nact-ibackground-tab.c
 src/nact/nact-icommand-tab.c
+src/nact/nact-ifolders-tab.c
 src/nact/nact-main-menubar.c
 src/nact/nact-main-window.c
 src/nact/nact-preferences.ui
diff --git a/src/api/Makefile.am b/src/api/Makefile.am
index 83a4ecf..d467413 100644
--- a/src/api/Makefile.am
+++ b/src/api/Makefile.am
@@ -44,6 +44,7 @@ api_include_HEADERS = \
 	na-data-types.h										\
 	na-gconf-monitor.h									\
 	na-gconf-utils.h									\
+	na-icontext-conditions.h							\
 	na-iduplicable.h									\
 	na-ifactory-object.h								\
 	na-ifactory-object-data.h							\
diff --git a/src/core/na-icontext-conditions.h b/src/api/na-icontext-conditions.h
similarity index 67%
rename from src/core/na-icontext-conditions.h
rename to src/api/na-icontext-conditions.h
index d3f9536..b6f38a1 100644
--- a/src/core/na-icontext-conditions.h
+++ b/src/api/na-icontext-conditions.h
@@ -28,13 +28,13 @@
  *   ... and many others (see AUTHORS)
  */
 
-#ifndef __CORE_NA_ICONTEXT_CONDITIONS_H__
-#define __CORE_NA_ICONTEXT_CONDITIONS_H__
+#ifndef __NAUTILUS_ACTIONS_API_NA_ICONTEXT_CONDITIONS_H__
+#define __NAUTILUS_ACTIONS_API_NA_ICONTEXT_CONDITIONS_H__
 
 /**
  * SECTION: na_icontext_conditions
  * @short_description: #NAIContextConditions interface definition.
- * @include: core/na-icontext_conditions.h
+ * @include: nautilus-actions/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
@@ -61,13 +61,34 @@ typedef struct NAIContextConditionsInterfacePrivate NAIContextConditionsInterfac
 typedef struct {
 	GTypeInterface                        parent;
 	NAIContextConditionsInterfacePrivate *private;
+
+	/**
+	 * is_candidate:
+	 * @object: this #NAIContextConditions object.
+	 * @target: the initial target which triggered this function's stack.
+	 *  This target is defined in na-object-item.h.
+	 * @selection: the current selection as a #GList of #NautilusFileInfo.
+	 *
+	 * Returns: %TRUE if the @object may be a potential candidate, %FALSE
+	 * else.
+	 *
+	 * The #NAIContextConditions implementor may take advantage of this
+	 * virtual function to check for its own specific data. Only if the
+	 * implementor does return %TRUE (or just doesn't implement this
+	 * virtual), the conditions themselves will be checked.
+	 */
+	gboolean ( *is_candidate )( NAIContextConditions *object, guint target, GList *selection );
 }
 	NAIContextConditionsInterface;
 
 GType    na_icontext_conditions_get_type( void );
 
 gboolean na_icontext_conditions_is_candidate( const NAIContextConditions *object, guint target, GList *selection );
+gboolean na_icontext_conditions_is_valid    ( const NAIContextConditions *object );
+
+void     na_icontext_conditions_set_scheme    ( NAIContextConditions *object, const gchar *scheme, gboolean selected );
+void     na_icontext_conditions_replace_folder( NAIContextConditions *object, const gchar *old, const gchar *new );
 
 G_END_DECLS
 
-#endif /* __CORE_NA_ICONTEXT_CONDITIONS_H__ */
+#endif /* __NAUTILUS_ACTIONS_API_NA_ICONTEXT_CONDITIONS_H__ */
diff --git a/src/api/na-object-action.h b/src/api/na-object-action.h
index 3af150c..3287a54 100644
--- a/src/api/na-object-action.h
+++ b/src/api/na-object-action.h
@@ -80,9 +80,10 @@ NAObjectAction *na_object_action_new_with_profile( void );
 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, guint target );
+gboolean        na_object_action_is_candidate( const NAObjectAction *action, guint target, GList *selection );
 
 G_END_DECLS
 
diff --git a/src/api/na-object-api.h b/src/api/na-object-api.h
index f34a517..7ae5a78 100644
--- a/src/api/na-object-api.h
+++ b/src/api/na-object-api.h
@@ -44,6 +44,7 @@
 #include "na-ifactory-object.h"
 #include "na-ifactory-object-data.h"
 #include "na-iduplicable.h"
+#include "na-icontext-conditions.h"
 #include "na-object-action.h"
 #include "na-object-profile.h"
 #include "na-object-menu.h"
@@ -129,7 +130,6 @@ G_BEGIN_DECLS
  */
 #define na_object_get_version( obj )					(( gchar * ) na_ifactory_object_get_as_void( NA_IFACTORY_OBJECT( obj ), NAFO_DATA_VERSION ))
 #define na_object_is_target_selection( obj )			(( gboolean ) GPOINTER_TO_UINT( na_ifactory_object_get_as_void( NA_IFACTORY_OBJECT( obj ), NAFO_DATA_TARGET_SELECTION )))
-#define na_object_is_target_background( obj )			(( gboolean ) GPOINTER_TO_UINT( na_ifactory_object_get_as_void( NA_IFACTORY_OBJECT( obj ), NAFO_DATA_TARGET_BACKGROUND )))
 #define na_object_is_target_toolbar( obj )				(( gboolean ) GPOINTER_TO_UINT( na_ifactory_object_get_as_void( NA_IFACTORY_OBJECT( obj ), NAFO_DATA_TARGET_TOOLBAR )))
 #define na_object_get_toolbar_label( obj )				(( gchar * ) na_ifactory_object_get_as_void( NA_IFACTORY_OBJECT( obj ), NAFO_DATA_TOOLBAR_LABEL ))
 #define na_object_is_toolbar_same_label( obj )			(( gboolean ) GPOINTER_TO_UINT( na_ifactory_object_get_as_void( NA_IFACTORY_OBJECT( obj ), NAFO_DATA_TOOLBAR_SAME_LABEL )))
@@ -137,7 +137,6 @@ G_BEGIN_DECLS
 
 #define na_object_set_version( obj, version )			na_ifactory_object_set_from_void( NA_IFACTORY_OBJECT( obj ), NAFO_DATA_VERSION, ( const void * )( version ))
 #define na_object_set_target_selection( obj, target )	na_ifactory_object_set_from_void( NA_IFACTORY_OBJECT( obj ), NAFO_DATA_TARGET_SELECTION, ( const void * ) GUINT_TO_POINTER( target ))
-#define na_object_set_target_background( obj, target )	na_ifactory_object_set_from_void( NA_IFACTORY_OBJECT( obj ), NAFO_DATA_TARGET_BACKGROUND, ( const void * ) GUINT_TO_POINTER( target ))
 #define na_object_set_target_toolbar( obj, target )		na_ifactory_object_set_from_void( NA_IFACTORY_OBJECT( obj ), NAFO_DATA_TARGET_TOOLBAR, ( const void * ) GUINT_TO_POINTER( target ))
 #define na_object_set_toolbar_label( obj, label )		na_ifactory_object_set_from_void( NA_IFACTORY_OBJECT( obj ), NAFO_DATA_TOOLBAR_LABEL, ( const void * )( label ))
 #define na_object_set_toolbar_same_label( obj, same )	na_ifactory_object_set_from_void( NA_IFACTORY_OBJECT( obj ), NAFO_DATA_TOOLBAR_SAME_LABEL, ( const void * ) GUINT_TO_POINTER( same ))
@@ -158,6 +157,7 @@ G_BEGIN_DECLS
 #define na_object_is_multiple( obj )					(( gboolean ) GPOINTER_TO_UINT( na_ifactory_object_get_as_void( NA_IFACTORY_OBJECT( obj ), NAFO_DATA_MULTIPLE )))
 #define na_object_get_schemes( obj )					(( GSList * ) na_ifactory_object_get_as_void( NA_IFACTORY_OBJECT( obj ), NAFO_DATA_SCHEMES ))
 #define na_object_get_folders( obj )					(( GSList * ) na_ifactory_object_get_as_void( NA_IFACTORY_OBJECT( obj ), NAFO_DATA_FOLDERS ))
+#define na_object_is_target_background( obj )			na_object_profile_is_target_background( NA_OBJECT_PROFILE( obj ))
 
 #define na_object_set_path( obj, path )					na_ifactory_object_set_from_void( NA_IFACTORY_OBJECT( obj ), NAFO_DATA_PATH, ( const void * )( path ))
 #define na_object_set_parameters( obj, parms )			na_ifactory_object_set_from_void( NA_IFACTORY_OBJECT( obj ), NAFO_DATA_PARAMETERS, ( const void * )( parms ))
@@ -170,8 +170,10 @@ G_BEGIN_DECLS
 #define na_object_set_schemes( obj, schemes )			na_ifactory_object_set_from_void( NA_IFACTORY_OBJECT( obj ), NAFO_DATA_SCHEMES, ( const void * )( schemes ))
 #define na_object_set_folders( obj, folders )			na_ifactory_object_set_from_void( NA_IFACTORY_OBJECT( obj ), NAFO_DATA_FOLDERS, ( const void * )( folders ))
 
-#define na_object_set_scheme( obj, scheme, add )		na_object_profile_set_scheme( NA_OBJECT_PROFILE( obj ), ( const gchar * )( scheme ), ( add ))
-#define na_object_replace_folder( obj, old, new )		na_object_profile_replace_folder( NA_OBJECT_PROFILE( obj ), ( const gchar * )( old ), ( const gchar * )( new ))
+/* NAIContextConditions
+ */
+#define na_object_set_scheme( obj, scheme, add )		na_icontext_conditions_set_scheme( NA_ICONTEXT_CONDITIONS( obj ), ( const gchar * )( scheme ), ( add ))
+#define na_object_replace_folder( obj, old, new )		na_icontext_conditions_replace_folder( NA_ICONTEXT_CONDITIONS( obj ), ( const gchar * )( old ), ( const gchar * )( new ))
 
 G_END_DECLS
 
diff --git a/src/api/na-object-profile.h b/src/api/na-object-profile.h
index c874e11..dec1509 100644
--- a/src/api/na-object-profile.h
+++ b/src/api/na-object-profile.h
@@ -72,14 +72,9 @@ GType            na_object_profile_get_type( void );
 NAObjectProfile *na_object_profile_new( void );
 NAObjectProfile *na_object_profile_new_with_defaults( void );
 
-void             na_object_profile_set_scheme    ( NAObjectProfile *profile, const gchar *scheme, gboolean selected );
-void             na_object_profile_replace_folder( NAObjectProfile *profile, const gchar *old, const gchar *new );
+gboolean         na_object_profile_is_target_background( const NAObjectProfile *profile );
 
-gboolean         na_object_profile_is_candidate                ( const NAObjectProfile *profile, gint target, GList *files );
-gboolean         na_object_profile_is_candidate_for_tracked    ( const NAObjectProfile *profile, GList *tracked );
-
-gchar           *na_object_profile_parse_parameters            ( const NAObjectProfile *profile, gint target, GList *files );
-gchar           *na_object_profile_parse_parameters_for_tracked( const NAObjectProfile *profile, GList *tracked );
+gchar           *na_object_profile_parse_parameters    ( const NAObjectProfile *profile, gint target, GList *selected );
 
 G_END_DECLS
 
diff --git a/src/core/Makefile.am b/src/core/Makefile.am
index 5493e17..7fb22ac 100644
--- a/src/core/Makefile.am
+++ b/src/core/Makefile.am
@@ -60,7 +60,6 @@ libna_core_la_SOURCES = \
 	na-iabout.c											\
 	na-iabout.h											\
 	na-icontext-conditions.c							\
-	na-icontext-conditions.h							\
 	na-icontext-conditions-factory.c					\
 	na-iduplicable.c									\
 	na-iexporter.c										\
@@ -93,6 +92,8 @@ libna_core_la_SOURCES = \
 	na-object-menu-factory.c							\
 	na-pivot.c											\
 	na-pivot.h											\
+	na-selected-info.c									\
+	na-selected-info.h									\
 	na-updater.c										\
 	na-updater.h										\
 	$(NULL)
diff --git a/src/core/na-icontext-conditions.c b/src/core/na-icontext-conditions.c
index ce550bd..547ae0e 100644
--- a/src/core/na-icontext-conditions.c
+++ b/src/core/na-icontext-conditions.c
@@ -39,9 +39,9 @@
 #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"
+#include "na-selected-info.h"
 
 /* private interface data
  */
@@ -56,16 +56,19 @@ 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 v_is_candidate( NAIContextConditions *object, guint target, GList *selection );
 
-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 );
+static gboolean is_target_background_candidate( const NAIContextConditions *object, NASelectedInfo *current_folder );
+static gboolean is_target_toolbar_candidate( const NAIContextConditions *object, NASelectedInfo *current_folder );
+static gboolean is_current_folder_inside( const NAIContextConditions *object, NASelectedInfo *current_folder );
+static gboolean is_target_selection_candidate( const NAIContextConditions *object, GList *files );
+static gboolean is_valid_basenames( const NAIContextConditions *object );
+static gboolean is_valid_mimetypes( const NAIContextConditions *object );
+static gboolean is_valid_isfiledir( const NAIContextConditions *object );
+static gboolean is_valid_schemes( const NAIContextConditions *object );
+static gboolean is_valid_folders( const NAIContextConditions *object );
+
+static gboolean validate_schemes( GSList *object_schemes, NASelectedInfo *iter );
 
 /**
  * na_icontext_conditions_get_type:
@@ -147,23 +150,18 @@ interface_base_finalize( NAIContextConditionsInterface *klass )
 }
 
 /**
- * na_object_profile_is_candidate:
- * @profile: the #NAObjectProfile to be checked.
+ * na_icontext_conditions_is_candidate:
+ * @object: a #NAIContextConditions 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
+ * Determines if the given object may be candidate to be displayed in
+ * the Nautilus context menu, depending of the list of currently selected
  * items.
  *
- * Returns: %TRUE if this profile succeeds to all tests and is so a
+ * Returns: %TRUE if this object 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 )
@@ -172,31 +170,123 @@ na_icontext_conditions_is_candidate( const NAIContextConditions *object, guint t
 
 	g_return_val_if_fail( NA_IS_ICONTEXT_CONDITIONS( object ), FALSE );
 
-	if( !na_object_is_valid( object )){
-		return( FALSE );
-	}
-
-	is_candidate = FALSE;
+	is_candidate = v_is_candidate( NA_ICONTEXT_CONDITIONS( object ), target, files );
 
 	switch( target ){
 		case ITEM_TARGET_BACKGROUND:
-			is_candidate = is_target_background_candidate( object, ( NautilusFileInfo * ) files->data );
+			is_candidate = is_target_background_candidate( object, ( NASelectedInfo * ) files->data );
 			break;
 
 		case ITEM_TARGET_TOOLBAR:
-			is_candidate = is_target_toolbar_candidate( object, ( NautilusFileInfo * ) files->data );
+			is_candidate = is_target_toolbar_candidate( object, ( NASelectedInfo * ) files->data );
 			break;
 
 		case ITEM_TARGET_SELECTION:
 		default:
-			is_candidate = is_target_selection_candidate( object, files, TRUE );
+			is_candidate = is_target_selection_candidate( object, files );
 	}
 
 	return( is_candidate );
 }
 
+/**
+ * na_icontext_conditions_is_valid:
+ * @profile: the #NAObjectProfile to be checked.
+ *
+ * Returns: %TRUE if this profile is valid, %FALSE else.
+ *
+ * This function is part of NAIDuplicable::check_status() and is called
+ * by NAIDuplicable objects which also implement NAIContextConditions
+ * interface. It so doesn't make sense of asking the object for its
+ * validity status as it has already been checked before calling the
+ * function.
+ */
+gboolean
+na_icontext_conditions_is_valid( const NAIContextConditions *object )
+{
+	gboolean is_valid;
+
+	g_return_val_if_fail( NA_IS_ICONTEXT_CONDITIONS( object ), FALSE );
+
+	is_valid =
+		is_valid_basenames( object ) &&
+		is_valid_mimetypes( object ) &&
+		is_valid_isfiledir( object ) &&
+		is_valid_schemes( object ) &&
+		is_valid_folders( object );
+
+	return( is_valid );
+}
+
+/**
+ * na_icontext_conditions_set_scheme:
+ * @profile: the #NAIContextConditions to be updated.
+ * @scheme: name of the scheme.
+ * @selected: whether this scheme is candidate to this profile.
+ *
+ * Sets the status of a scheme relative to this profile.
+ */
+void
+na_icontext_conditions_set_scheme( NAIContextConditions *profile, const gchar *scheme, gboolean selected )
+{
+	/*static const gchar *thisfn = "na_icontext_conditions_set_scheme";*/
+	gboolean exist;
+	GSList *schemes;
+
+	g_return_if_fail( NA_IS_ICONTEXT_CONDITIONS( profile ));
+
+	schemes = na_object_get_schemes( profile );
+	exist = na_core_utils_slist_find( schemes, scheme );
+	/*g_debug( "%s: scheme=%s exist=%s", thisfn, scheme, exist ? "True":"False" );*/
+
+	if( selected && !exist ){
+		schemes = g_slist_prepend( schemes, g_strdup( scheme ));
+	}
+	if( !selected && exist ){
+		schemes = na_core_utils_slist_remove_ascii( schemes, scheme );
+	}
+	na_object_set_schemes( profile, schemes );
+	na_core_utils_slist_free( schemes );
+}
+
+/**
+ * na_icontext_conditions_replace_folder:
+ * @profile: the #NAIContextConditions to be updated.
+ * @old: the old uri.
+ * @new: the new uri.
+ *
+ * Replaces the @old URI by the @new one.
+ */
+void
+na_icontext_conditions_replace_folder( NAIContextConditions *profile, const gchar *old, const gchar *new )
+{
+	GSList *folders;
+
+	g_return_if_fail( NA_IS_ICONTEXT_CONDITIONS( profile ));
+
+	folders = na_object_get_folders( profile );
+	folders = na_core_utils_slist_remove_utf8( folders, old );
+	folders = g_slist_append( folders, ( gpointer ) g_strdup( new ));
+	na_object_set_folders( profile, folders );
+	na_core_utils_slist_free( folders );
+}
+
 static gboolean
-is_target_background_candidate( const NAIContextConditions *object, NautilusFileInfo *current_folder )
+v_is_candidate( NAIContextConditions *object, guint target, GList *selection )
+{
+	gboolean is_candidate;
+
+	is_candidate = TRUE;
+
+	if( NA_ICONTEXT_CONDITIONS_GET_INTERFACE( object )->is_candidate ){
+		is_candidate = NA_ICONTEXT_CONDITIONS_GET_INTERFACE( object )->is_candidate( object, target, selection );
+	}
+
+	return( is_candidate );
+}
+
+static gboolean
+is_target_background_candidate( const NAIContextConditions *object, NASelectedInfo *current_folder )
 {
 	gboolean is_candidate;
 
@@ -206,7 +296,7 @@ is_target_background_candidate( const NAIContextConditions *object, NautilusFile
 }
 
 static gboolean
-is_target_toolbar_candidate( const NAIContextConditions *object, NautilusFileInfo *current_folder )
+is_target_toolbar_candidate( const NAIContextConditions *object, NASelectedInfo *current_folder )
 {
 	gboolean is_candidate;
 
@@ -216,7 +306,7 @@ is_target_toolbar_candidate( const NAIContextConditions *object, NautilusFileInf
 }
 
 static gboolean
-is_current_folder_inside( const NAIContextConditions *object, NautilusFileInfo *current_folder )
+is_current_folder_inside( const NAIContextConditions *object, NASelectedInfo *current_folder )
 {
 	gboolean is_inside;
 	GSList *folders, *ifold;
@@ -224,7 +314,7 @@ is_current_folder_inside( const NAIContextConditions *object, NautilusFileInfo *
 	gchar *current_folder_uri;
 
 	is_inside = FALSE;
-	current_folder_uri = nautilus_file_info_get_uri( current_folder );
+	current_folder_uri = na_selected_info_get_uri( current_folder );
 	folders = na_object_get_folders( object );
 
 	for( ifold = folders ; ifold && !is_inside ; ifold = ifold->next ){
@@ -246,7 +336,7 @@ is_current_folder_inside( const NAIContextConditions *object, NautilusFileInfo *
 }
 
 static gboolean
-is_target_selection_candidate( const NAIContextConditions *object, GList *files, gboolean from_nautilus )
+is_target_selection_candidate( const NAIContextConditions *object, GList *files )
 {
 	gboolean retv = FALSE;
 	GSList *basenames, *mimetypes, *schemes;
@@ -320,12 +410,12 @@ is_target_selection_candidate( const NAIContextConditions *object, GList *files,
 		}
 	}
 
-	for( iter1 = files; iter1; iter1 = iter1->next ){
+	for( iter1 = files ; iter1 ; iter1 = iter1->next ){
 
-		tmp_filename = tracked_to_basename( iter1->data, from_nautilus );
+		tmp_filename = na_selected_info_get_name( NA_SELECTED_INFO( iter1->data ));
 
 		if( tmp_filename ){
-			tmp_mimetype = tracked_to_mimetype( iter1->data, from_nautilus );
+			tmp_mimetype = na_selected_info_get_mime_type( NA_SELECTED_INFO( iter1->data ));
 
 			if( !matchcase ){
 				/* --> if case-insensitive asked, lower all the string
@@ -342,13 +432,13 @@ is_target_selection_candidate( const NAIContextConditions *object, GList *files,
 			g_free( tmp_mimetype );
 			tmp_mimetype = tmp_mimetype2;
 
-			if( tracked_is_directory( iter1->data, from_nautilus )){
+			if( na_selected_info_is_directory( NA_SELECTED_INFO( iter ))){
 				dir_count++;
 			} else {
 				file_count++;
 			}
 
-			scheme_ok_count += validate_schemes( schemes, iter1->data, from_nautilus );
+			scheme_ok_count += validate_schemes( schemes, NA_SELECTED_INFO( iter1->data ));
 
 			if( !test_basename ){ /* if it is already ok, skip the test to improve performance */
 				basename_match_ok = FALSE;
@@ -440,114 +530,109 @@ is_target_selection_candidate( const NAIContextConditions *object, GList *files,
 }
 
 static gboolean
-tracked_is_directory( void *iter, gboolean from_nautilus )
+is_valid_basenames( const NAIContextConditions *object )
 {
-	gboolean is_dir;
-	GFile *file;
-	GFileType type;
+	gboolean valid;
+	GSList *basenames;
 
-	if( from_nautilus ){
-		is_dir = nautilus_file_info_is_directory(( NautilusFileInfo * ) iter );
+	basenames = na_object_get_basenames( object );
+	valid = basenames && g_slist_length( basenames ) > 0;
+	na_core_utils_slist_free( basenames );
 
-	} 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 );
+	if( !valid ){
+		na_object_debug_invalid( object, "basenames" );
 	}
 
-	return( is_dir );
+	return( valid );
 }
 
-static gchar *
-tracked_to_basename( void *iter, gboolean from_nautilus )
+static gboolean
+is_valid_mimetypes( const NAIContextConditions *object )
 {
-	gchar *bname;
-	GFile *file;
+	gboolean valid;
+	GSList *mimetypes;
 
-	if( from_nautilus ){
-		bname = nautilus_file_info_get_name(( NautilusFileInfo * ) iter );
+	mimetypes = na_object_get_mimetypes( object );
+	valid = mimetypes && g_slist_length( mimetypes ) > 0;
+	na_core_utils_slist_free( mimetypes );
 
-	} else {
-		file = g_file_new_for_uri((( NATrackedItem * ) iter )->uri );
-		bname = g_file_get_basename( file );
-		g_object_unref( file );
+	if( !valid ){
+		na_object_debug_invalid( object, "mimetypes" );
 	}
 
-	return( bname );
+	return( valid );
 }
 
-static gchar *
-tracked_to_mimetype( void *iter, gboolean from_nautilus )
+static gboolean
+is_valid_isfiledir( const NAIContextConditions *object )
 {
-	gchar *type;
-	NATrackedItem *tracked;
-	GFile *file;
-	GFileInfo *info;
+	gboolean valid;
+	gboolean isfile, isdir;
 
-	type = NULL;
-	if( from_nautilus ){
-		type = nautilus_file_info_get_mime_type(( NautilusFileInfo * ) iter );
+	isfile = na_object_is_file( object );
+	isdir = na_object_is_dir( object );
 
-	} 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 );
-		}
+	valid = isfile || isdir;
+
+	if( !valid ){
+		na_object_debug_invalid( object, "isfiledir" );
 	}
 
-	return( type );
+	return( valid );
 }
 
-static gchar *
-tracked_to_scheme( void *iter, gboolean from_nautilus )
+static gboolean
+is_valid_schemes( const NAIContextConditions *object )
 {
-	gchar *scheme;
-	NAGnomeVFSURI *vfs;
+	gboolean valid;
+	GSList *schemes;
 
-	if( from_nautilus ){
-		scheme = nautilus_file_info_get_uri_scheme(( NautilusFileInfo * ) iter );
+	schemes = na_object_get_schemes( object );
+	valid = schemes && g_slist_length( schemes ) > 0;
+	na_core_utils_slist_free( schemes );
 
-	} 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 );
+	if( !valid ){
+		na_object_debug_invalid( object, "schemes" );
+	}
+
+	return( valid );
+}
+
+static gboolean
+is_valid_folders( const NAIContextConditions *object )
+{
+	gboolean valid;
+	GSList *folders;
+
+	folders = na_object_get_folders( object );
+	valid = folders && g_slist_length( folders ) > 0;
+	na_core_utils_slist_free( folders );
+
+	if( !valid ){
+		na_object_debug_invalid( object, "folders" );
 	}
 
-	return( scheme );
+	return( valid );
 }
 
-static int
-validate_schemes( GSList* schemes2test, void* tracked_iter, gboolean from_nautilus )
+static gboolean
+validate_schemes( GSList *object_schemes, NASelectedInfo *nfi )
 {
-	int retv = 0;
+	gboolean is_ok;
 	GSList* iter;
-	gboolean found = FALSE;
 	gchar *scheme;
 
-	iter = schemes2test;
-	while( iter && !found ){
+	is_ok = FALSE;
 
-		scheme = tracked_to_scheme( tracked_iter, from_nautilus );
+	for( iter = object_schemes ; iter && !is_ok ; iter = iter->next ){
+		scheme = na_selected_info_get_uri_scheme( nfi );
 
 		if( g_ascii_strncasecmp( scheme, ( gchar * ) iter->data, strlen(( gchar * ) iter->data )) == 0 ){
-			found = TRUE;
-			retv = 1;
+			is_ok = TRUE;
 		}
 
 		g_free( scheme );
-		iter = iter->next;
 	}
 
-	return retv;
+	return( is_ok );
 }
diff --git a/src/core/na-object-action.c b/src/core/na-object-action.c
index 77dc25b..b53d7a8 100644
--- a/src/core/na-object-action.c
+++ b/src/core/na-object-action.c
@@ -485,7 +485,7 @@ object_object_is_valid( const NAObjectAction *action )
 		}
 
 		if( is_valid ){
-			if( na_object_is_target_selection( action ) || na_object_is_target_background( action )){
+			if( na_object_is_target_selection( action )){
 				is_valid = is_valid_label( action );
 			}
 		}
@@ -684,11 +684,15 @@ na_object_action_attach_profile( NAObjectAction *action, NAObjectProfile *profil
  * na_object_action_is_candidate:
  * @action: the #NAObjectAction to be tested.
  * @target: the current target.
+ * @selection: the current Nautilus selection.
  *
  * Returns: %TRUE if the @action may be candidate for this @target.
+ *
+ * Note that this public function will become NAIContextConditions::is_candidate
+ * when NAObjectAction will implement the interface.
  */
 gboolean
-na_object_action_is_candidate( const NAObjectAction *action, guint target )
+na_object_action_is_candidate( const NAObjectAction *action, guint target, GList *selection )
 {
 	gboolean is_candidate = FALSE;
 
@@ -698,7 +702,6 @@ na_object_action_is_candidate( const NAObjectAction *action, guint target )
 
 		is_candidate =
 			( 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 );
 	}
 
diff --git a/src/core/na-object-profile.c b/src/core/na-object-profile.c
index 1327b62..a209134 100644
--- a/src/core/na-object-profile.c
+++ b/src/core/na-object-profile.c
@@ -42,10 +42,10 @@
 #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"
+#include "na-selected-info.h"
 #include "na-gnome-vfs-uri.h"
 
 /* private class data
@@ -58,6 +58,11 @@ struct NAObjectProfileClassPrivate {
  */
 struct NAObjectProfilePrivate {
 	gboolean dispose_has_run;
+
+	/* dynamic data set when reading from I/O providers (see read_done())
+	 * may also be a NADataBoxed, left as private variable as an exercise
+	 */
+	gboolean target_background;
 };
 
 #define PROFILE_NAME_PREFIX					"profile-"
@@ -84,27 +89,24 @@ 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         set_target_background( NAObjectProfile *profile );
+
 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 );
-static gboolean     is_valid_basenames( const NAObjectProfile *profile );
-static gboolean     is_valid_mimetypes( const NAObjectProfile *profile );
-static gboolean     is_valid_isfiledir( const NAObjectProfile *profile );
-static gboolean     is_valid_schemes( const NAObjectProfile *profile );
-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_selection_candidate( const NAObjectProfile *profile, GList *files, gboolean from_nautilus );
+#if 0
 static gchar       *parse_parameters( const NAObjectProfile *profile, gint target, GList* files, gboolean from_nautilus );
+static gboolean     is_target_selection_candidate( const NAObjectProfile *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 GFile       *tracked_to_location( 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 gchar       *tracked_to_uri( void *iter, gboolean from_nautilus );
 static int          validate_schemes( GSList *schemes2test, void *iter, gboolean from_nautilus );
+#endif
 
 GType
 na_object_profile_get_type( void )
@@ -343,9 +345,51 @@ ifactory_object_is_valid( const NAIFactoryObject *object )
 static void
 ifactory_object_read_done( NAIFactoryObject *instance, const NAIFactoryProvider *reader, void *reader_data, GSList **messages )
 {
+	set_target_background( NA_OBJECT_PROFILE( instance ));
+
 	na_factory_object_set_defaults( instance );
 }
 
+/*
+ * set the target_background dynamic flag as a private data
+ *
+ * a profile is candidate for display on background callback, if:
+ * - it doesn't target files, but only dirs
+ * - it doesn't require a multiple selection
+ * - basenames are set as default
+ *
+ * as of actions v2, this means:
+ * - ifile is false
+ * - isdir is true
+ * - basenames = '*'
+ * - mimetypes = '*'
+ *
+ * note that, though the conditions may be modified in NACT user
+ * interface, they will be reloaded, and so this flag recomputed, when
+ * the pivot reloads its tree after a save; and, as this flag is only
+ * needed in the plugins, then we only need to compute at read_done()
+ * time.
+ */
+static void
+set_target_background( NAObjectProfile *profile )
+{
+	GSList *basenames = na_object_get_basenames( profile );
+	GSList *mimetypes = na_object_get_mimetypes( profile );
+
+	profile->private->target_background = \
+			!na_object_is_file( profile ) && \
+			na_object_is_dir( profile ) && \
+			( basenames == NULL ||
+					( g_slist_length( basenames ) == 1 &&
+							strcmp(( const char * ) basenames->data, "*" ) == 0 )) && \
+			( mimetypes == NULL ||
+					( g_slist_length( mimetypes ) == 1 &&
+							strcmp(( const char * ) mimetypes->data, "*" ) == 0 ));
+
+	na_core_utils_slist_free( basenames );
+	na_core_utils_slist_free( mimetypes );
+}
+
 static guint
 ifactory_object_write_done( NAIFactoryObject *instance, const NAIFactoryProvider *writer, void *writer_data, GSList **messages )
 {
@@ -364,31 +408,14 @@ static gboolean
 profile_is_valid( const NAObjectProfile *profile )
 {
 	gboolean is_valid;
-	NAObjectItem *parent;
 
 	is_valid = FALSE;
 
 	if( !profile->private->dispose_has_run ){
 
-		is_valid = TRUE;
-		parent = na_object_get_parent( profile );
-
-		if( is_valid && na_object_is_target_background( parent )){
-			is_valid =
-					is_valid_path_parameters( profile ) &&
-					is_valid_folders( profile );
-		}
-
-		if( is_valid ){
-			if( na_object_is_target_selection( parent ) || na_object_is_target_toolbar( parent )){
-				is_valid =
-					is_valid_path_parameters( profile ) &&
-					is_valid_basenames( profile ) &&
-					is_valid_mimetypes( profile ) &&
-					is_valid_isfiledir( profile ) &&
-					is_valid_schemes( profile );
-			}
-		}
+		is_valid = \
+				is_valid_path_parameters( profile ) &&
+				na_icontext_conditions_is_valid( NA_ICONTEXT_CONDITIONS( profile ));
 	}
 
 	return( is_valid );
@@ -424,92 +451,6 @@ is_valid_path_parameters( const NAObjectProfile *profile )
 	return( valid );
 }
 
-static gboolean
-is_valid_basenames( const NAObjectProfile *profile )
-{
-	gboolean valid;
-	GSList *basenames;
-
-	basenames = na_object_get_basenames( profile );
-	valid = basenames && g_slist_length( basenames ) > 0;
-	na_core_utils_slist_free( basenames );
-
-	if( !valid ){
-		na_object_debug_invalid( profile, "basenames" );
-	}
-
-	return( valid );
-}
-
-static gboolean
-is_valid_mimetypes( const NAObjectProfile *profile )
-{
-	gboolean valid;
-	GSList *mimetypes;
-
-	mimetypes = na_object_get_mimetypes( profile );
-	valid = mimetypes && g_slist_length( mimetypes ) > 0;
-	na_core_utils_slist_free( mimetypes );
-
-	if( !valid ){
-		na_object_debug_invalid( profile, "mimetypes" );
-	}
-
-	return( valid );
-}
-
-static gboolean
-is_valid_isfiledir( const NAObjectProfile *profile )
-{
-	gboolean valid;
-	gboolean isfile, isdir;
-
-	isfile = na_object_is_file( profile );
-	isdir = na_object_is_dir( profile );
-
-	valid = isfile || isdir;
-
-	if( !valid ){
-		na_object_debug_invalid( profile, "isfiledir" );
-	}
-
-	return( valid );
-}
-
-static gboolean
-is_valid_schemes( const NAObjectProfile *profile )
-{
-	gboolean valid;
-	GSList *schemes;
-
-	schemes = na_object_get_schemes( profile );
-	valid = schemes && g_slist_length( schemes ) > 0;
-	na_core_utils_slist_free( schemes );
-
-	if( !valid ){
-		na_object_debug_invalid( profile, "schemes" );
-	}
-
-	return( valid );
-}
-
-static gboolean
-is_valid_folders( const NAObjectProfile *profile )
-{
-	gboolean valid;
-	GSList *folders;
-
-	folders = na_object_get_folders( profile );
-	valid = folders && g_slist_length( folders ) > 0;
-	na_core_utils_slist_free( folders );
-
-	if( !valid ){
-		na_object_debug_invalid( profile, "folders" );
-	}
-
-	return( valid );
-}
-
 /*
  * new_parent is specifically set to be able to allocate a new id for
  * the current profile into the target parent
@@ -567,97 +508,30 @@ na_object_profile_new_with_defaults( void )
 }
 
 /**
- * na_object_profile_set_scheme:
- * @profile: the #NAObjectProfile to be updated.
- * @scheme: name of the scheme.
- * @selected: whether this scheme is candidate to this profile.
- *
- * Sets the status of a scheme relative to this profile.
- */
-void
-na_object_profile_set_scheme( NAObjectProfile *profile, const gchar *scheme, gboolean selected )
-{
-	/*static const gchar *thisfn = "na_object_profile_set_scheme";*/
-	gboolean exist;
-	GSList *schemes;
-
-	g_return_if_fail( NA_IS_OBJECT_PROFILE( profile ));
-
-	if( !profile->private->dispose_has_run ){
-
-		schemes = na_object_get_schemes( profile );
-		exist = na_core_utils_slist_find( schemes, scheme );
-		/*g_debug( "%s: scheme=%s exist=%s", thisfn, scheme, exist ? "True":"False" );*/
-
-		if( selected && !exist ){
-			schemes = g_slist_prepend( schemes, g_strdup( scheme ));
-		}
-		if( !selected && exist ){
-			schemes = na_core_utils_slist_remove_ascii( schemes, scheme );
-		}
-		na_object_set_schemes( profile, schemes );
-		na_core_utils_slist_free( schemes );
-	}
-}
-
-/**
- * na_object_profile_replace_folder:
- * @profile: the #NAObjectProfile to be updated.
- * @old: the old uri.
- * @new: the new uri.
- *
- * Replaces the @old URI by the @new one.
- */
-void
-na_object_profile_replace_folder( NAObjectProfile *profile, const gchar *old, const gchar *new )
-{
-	GSList *folders;
-
-	g_return_if_fail( NA_IS_OBJECT_PROFILE( profile ));
-
-	if( !profile->private->dispose_has_run ){
-
-		folders = na_object_get_folders( profile );
-		folders = na_core_utils_slist_remove_utf8( folders, old );
-		folders = g_slist_append( folders, ( gpointer ) g_strdup( new ));
-		na_object_set_folders( profile, folders );
-		na_core_utils_slist_free( folders );
-	}
-}
-
-/**
- * na_object_profile_is_candidate_for_tracked:
+ * na_object_profile_is_target_background:
  * @profile: the #NAObjectProfile to be checked.
- * @files: the currently selected items, as a list of uris.
- *
- * 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.
- *
- * The case where we only have URIs for target files is when we have
- * got this list through the org.nautilus_actions.DBus service (or
- * another equivalent) - typically for use in a command-line tool.
+ * Returns: %TRUE if this profile may be candidate when displaying
+ * background actions, %FALSE else.
  */
 gboolean
-na_object_profile_is_candidate_for_tracked( const NAObjectProfile *profile, GList *tracked_items )
+na_object_profile_is_target_background( const NAObjectProfile *profile )
 {
 	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;
 
-	is_candidate = is_target_selection_candidate( profile, tracked_items, FALSE );
+	if( !profile->private->dispose_has_run ){
+
+		is_candidate = profile->private->target_background;
+	}
 
 	return( is_candidate );
 }
 
+#if 0
 static gboolean
 is_target_selection_candidate( const NAObjectProfile *profile, GList *files, gboolean from_nautilus )
 {
@@ -851,13 +725,14 @@ is_target_selection_candidate( const NAObjectProfile *profile, GList *files, gbo
 
 	return retv;
 }
+#endif
 
 /**
  * Expands the parameters path, in function of the found tokens.
  *
  * @profile: the selected profile.
  * @target: the current target.
- * @files: the list of currently selected items, as provided by Nautilus.
+ * @files: the list of currently selected #NASelectedInfo items.
  *
  * Valid parameters are :
  *
@@ -874,34 +749,13 @@ is_target_selection_candidate( const NAObjectProfile *profile, GList *files, gbo
  * %% : a percent sign
  *
  * Adding a parameter requires updating of :
- * - nautilus-actions/private/na-action-profile.c:na_object_profile_parse_parameters()
- * - nautilus-actions/runtime/na-xml-names.h
+ * - nautilus-actions/core/na-object-profile.c::na_object_profile_parse_parameters()
  * - nautilus-actions/nact/nact-icommand-tab.c:parse_parameters()
  * - nautilus-actions/nact/nautilus-actions-config-tool.ui:LegendDialog
  */
 gchar *
 na_object_profile_parse_parameters( const NAObjectProfile *profile, gint target, GList* files )
 {
-	return( parse_parameters( profile, target, files, TRUE ));
-}
-
-/**
- * na_object_profile_parse_parameters_for_tracked:
- * @profile: the selected profile.
- * @tracked_items: current selection.
- */
-gchar *
-na_object_profile_parse_parameters_for_tracked( const NAObjectProfile *profile, GList *tracked_items )
-{
-	return( parse_parameters( profile, ITEM_TARGET_SELECTION, tracked_items, FALSE ));
-}
-
-/*
- * Expands the parameters path, in function of the found tokens.
- */
-static gchar *
-parse_parameters( const NAObjectProfile *profile, gint target, GList* files, gboolean from_nautilus )
-{
 	gchar *parsed = NULL;
 	GString *string;
 	GList *ifi;
@@ -933,8 +787,8 @@ parse_parameters( const NAObjectProfile *profile, gint target, GList* files, gbo
 
 	for( ifi = files ; ifi ; ifi = ifi->next ){
 
-		iuri = tracked_to_uri( ifi->data, from_nautilus );
-		iloc = tracked_to_location( ifi->data, from_nautilus );
+		iuri = na_selected_info_get_uri( NA_SELECTED_INFO( ifi->data ));
+		iloc = na_selected_info_get_location( NA_SELECTED_INFO( ifi->data ));
 		ipath = g_file_get_path( iloc );
 		ibname = g_file_get_basename( iloc );
 
@@ -1074,6 +928,7 @@ parse_parameters( const NAObjectProfile *profile, gint target, GList* files, gbo
 	return( parsed );
 }
 
+#if 0
 static gboolean
 tracked_is_directory( void *iter, gboolean from_nautilus )
 {
@@ -1112,20 +967,6 @@ tracked_to_basename( void *iter, gboolean from_nautilus )
 	return( bname );
 }
 
-static GFile *
-tracked_to_location( void *iter, gboolean from_nautilus )
-{
-	GFile *file;
-
-	if( from_nautilus ){
-		file = nautilus_file_info_get_location(( NautilusFileInfo * ) iter );
-	} else {
-		file = g_file_new_for_uri((( NATrackedItem * ) iter )->uri );
-	}
-
-	return( file );
-}
-
 static gchar *
 tracked_to_mimetype( void *iter, gboolean from_nautilus )
 {
@@ -1176,20 +1017,6 @@ tracked_to_scheme( void *iter, gboolean from_nautilus )
 	return( scheme );
 }
 
-static gchar *
-tracked_to_uri( void *iter, gboolean from_nautilus )
-{
-	gchar *uri;
-
-	if( from_nautilus ){
-		uri = nautilus_file_info_get_uri(( NautilusFileInfo * ) iter );
-	} else {
-		uri = g_strdup((( NATrackedItem * ) iter )->uri );
-	}
-
-	return( uri );
-}
-
 static int
 validate_schemes( GSList* schemes2test, void* tracked_iter, gboolean from_nautilus )
 {
@@ -1214,3 +1041,4 @@ validate_schemes( GSList* schemes2test, void* tracked_iter, gboolean from_nautil
 
 	return retv;
 }
+#endif
diff --git a/src/core/na-selected-info.c b/src/core/na-selected-info.c
new file mode 100644
index 0000000..41a9a17
--- /dev/null
+++ b/src/core/na-selected-info.c
@@ -0,0 +1,467 @@
+/*
+ * 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 "na-gnome-vfs-uri.h"
+#include "na-selected-info.h"
+
+/* private class data
+ */
+struct NASelectedInfoClassPrivate {
+	void *empty;						/* so that gcc -pedantic is happy */
+};
+
+/* private instance data
+ */
+struct NASelectedInfoPrivate {
+	gboolean       dispose_has_run;
+	gchar         *uri;
+	NAGnomeVFSURI *vfs;;
+	GFile         *location;
+	gchar         *mimetype;
+	GFileType      file_type;
+};
+
+
+static GObjectClass *st_parent_class = NULL;
+
+static GType           register_type( void );
+static void            class_init( NASelectedInfoClass *klass );
+static void            instance_init( GTypeInstance *instance, gpointer klass );
+static void            instance_dispose( GObject *object );
+static void            instance_finalize( GObject *object );
+
+static NASelectedInfo *new_from_nautilus_file_info( NautilusFileInfo *item );
+static NASelectedInfo *new_from_uri( const gchar *uri );
+static void            query_file_attributes( NASelectedInfo *info );
+
+GType
+na_selected_info_get_type( void )
+{
+	static GType object_type = 0;
+
+	if( !object_type ){
+		object_type = register_type();
+	}
+
+	return( object_type );
+}
+
+static GType
+register_type( void )
+{
+	static const gchar *thisfn = "na_selected_info_register_type";
+	GType type;
+
+	static GTypeInfo info = {
+		sizeof( NASelectedInfoClass ),
+		( GBaseInitFunc ) NULL,
+		( GBaseFinalizeFunc ) NULL,
+		( GClassInitFunc ) class_init,
+		NULL,
+		NULL,
+		sizeof( NASelectedInfo ),
+		0,
+		( GInstanceInitFunc ) instance_init
+	};
+
+	g_debug( "%s", thisfn );
+
+	type = g_type_register_static( G_TYPE_OBJECT, "NASelectedInfo", &info, 0 );
+
+	return( type );
+}
+
+static void
+class_init( NASelectedInfoClass *klass )
+{
+	static const gchar *thisfn = "na_selected_info_class_init";
+	GObjectClass *object_class;
+
+	g_debug( "%s: klass=%p", thisfn, ( void * ) klass );
+
+	st_parent_class = g_type_class_peek_parent( klass );
+
+	object_class = G_OBJECT_CLASS( klass );
+	object_class->dispose = instance_dispose;
+	object_class->finalize = instance_finalize;
+
+	klass->private = g_new0( NASelectedInfoClassPrivate, 1 );
+}
+
+static void
+instance_init( GTypeInstance *instance, gpointer klass )
+{
+	static const gchar *thisfn = "na_selected_info_instance_init";
+	NASelectedInfo *self;
+
+	g_debug( "%s: instance=%p (%s), klass=%p",
+			thisfn, ( void * ) instance, G_OBJECT_TYPE_NAME( instance ), ( void * ) klass );
+	g_return_if_fail( NA_IS_SELECTED_INFO( instance ));
+	self = NA_SELECTED_INFO( instance );
+
+	self->private = g_new0( NASelectedInfoPrivate, 1 );
+
+	self->private->dispose_has_run = FALSE;
+	self->private->uri = NULL;
+}
+
+static void
+instance_dispose( GObject *object )
+{
+	static const gchar *thisfn = "na_selected_info_instance_dispose";
+	NASelectedInfo *self;
+
+	g_debug( "%s: object=%p (%s)", thisfn, ( void * ) object, G_OBJECT_TYPE_NAME( object ));
+	g_return_if_fail( NA_IS_SELECTED_INFO( object ));
+	self = NA_SELECTED_INFO( object );
+
+	if( !self->private->dispose_has_run ){
+
+		self->private->dispose_has_run = TRUE;
+
+		g_object_unref( self->private->location );
+		na_gnome_vfs_uri_free( self->private->vfs );
+
+		/* chain up to the parent class */
+		if( G_OBJECT_CLASS( st_parent_class )->dispose ){
+			G_OBJECT_CLASS( st_parent_class )->dispose( object );
+		}
+	}
+}
+
+static void
+instance_finalize( GObject *object )
+{
+	static const gchar *thisfn = "na_selected_info_instance_finalize";
+	NASelectedInfo *self;
+
+	g_debug( "%s: object=%p", thisfn, ( void * ) object );
+	g_return_if_fail( NA_IS_SELECTED_INFO( object ));
+	self = NA_SELECTED_INFO( object );
+
+	g_free( self->private->uri );
+	g_free( self->private->mimetype );
+
+	g_free( self->private );
+
+	/* chain call to parent class */
+	if( G_OBJECT_CLASS( st_parent_class )->finalize ){
+		G_OBJECT_CLASS( st_parent_class )->finalize( object );
+	}
+}
+
+/**
+ * na_selected_info_get_list_from_item:
+ * @item: a #NautilusFileInfo item
+ *
+ * Returns: a #GList list which contains a #NASelectedInfo item with the
+ * same URI that the @item.
+ */
+GList *
+na_selected_info_get_list_from_item( NautilusFileInfo *item )
+{
+	GList *selected;
+
+	gchar *uri = nautilus_file_info_get_uri( item );
+	NASelectedInfo *info = na_selected_info_create_for_uri( uri );
+	g_free( uri );
+
+	selected = g_list_prepend( NULL, info );
+
+	return( selected );
+}
+
+/**
+ * na_selected_info_get_list_from_list:
+ * @nautilus_selection: a #GList list of #NautilusFileInfo items.
+ *
+ * Returns: a #GList list of #NASelectedInfo items whose URI correspond
+ * to those of @nautilus_selection.
+ */
+GList *
+na_selected_info_get_list_from_list( GList *nautilus_selection )
+{
+	GList *selected;
+	GList *it;
+
+	selected = NULL;
+
+	for( it = nautilus_selection ; it ; it = it->next ){
+		NASelectedInfo *info = new_from_nautilus_file_info( NAUTILUS_FILE_INFO( it->data ));
+		selected = g_list_prepend( selected, info );
+	}
+
+	return( g_list_reverse( selected ));
+}
+
+/**
+ * na_selected_info_copy_list:
+ * @files: a #GList list of #NASelectedInfo items.
+ *
+ * Returns: a copy of the provided @files list.
+ */
+GList *
+na_selected_info_copy_list( GList *files )
+{
+	GList *copy;
+	GList *l;
+
+	copy = g_list_copy( files );
+
+	for( l = copy ; l != NULL ; l = l->next ){
+		g_object_ref( G_OBJECT( l->data ));
+	}
+
+	return( copy );
+}
+
+/**
+ * na_selected_info_free_list:
+ * @list: a #GList of #NASelectedInfo items.
+ *
+ * Frees up the #GList @list.
+ */
+void
+na_selected_info_free_list( GList *list )
+{
+	g_list_foreach( list, ( GFunc ) g_object_unref, NULL );
+	g_list_free( list );
+}
+
+/**
+ * na_selected_info_get_location:
+ * @nsi: this #NASelectedInfo object.
+ *
+ * Returns: a pointer to the #GFile location.
+ */
+GFile *
+na_selected_info_get_location( const NASelectedInfo *nsi )
+{
+	GFile *location;
+
+	g_return_val_if_fail( NA_IS_SELECTED_INFO( nsi ), NULL );
+
+	location = NULL;
+
+	if( !nsi->private->dispose_has_run ){
+
+		location = nsi->private->location;
+	}
+
+	return( location );
+}
+
+/**
+ * na_selected_info_get_mime_type:
+ * @nsi: this #NASelectedInfo object.
+ *
+ * Returns: the mime type associated with this #NASelectedInfo object,
+ * as a newly allocated string which should be g_free() by the caller.
+ */
+gchar *
+na_selected_info_get_mime_type( const NASelectedInfo *nsi )
+{
+	gchar *mimetype;
+
+	g_return_val_if_fail( NA_IS_SELECTED_INFO( nsi ), NULL );
+
+	mimetype = NULL;
+
+	if( !nsi->private->dispose_has_run ){
+
+		mimetype = g_strdup( nsi->private->mimetype );
+	}
+
+	return( mimetype );
+}
+
+/**
+ * na_selected_info_get_name:
+ * @nsi: this #NASelectedInfo object.
+ *
+ * Returns: the filename of the item.
+ */
+gchar *
+na_selected_info_get_name( const NASelectedInfo *nsi )
+{
+	gchar *name;
+
+	g_return_val_if_fail( NA_IS_SELECTED_INFO( nsi ), NULL );
+
+	name = NULL;
+
+	if( !nsi->private->dispose_has_run ){
+
+		name = g_strdup( nsi->private->vfs->path );
+	}
+
+	return( name );
+}
+
+/**
+ * na_selected_info_get_uri:
+ * @nsi: this #NASelectedInfo object.
+ *
+ * Returns: the URI associated with this #NASelectedInfo object, as a
+ * newly allocated string which should be g_free() by the caller.
+ */
+gchar *
+na_selected_info_get_uri( const NASelectedInfo *nsi )
+{
+	gchar *uri;
+
+	g_return_val_if_fail( NA_IS_SELECTED_INFO( nsi ), NULL );
+
+	uri = NULL;
+
+	if( !nsi->private->dispose_has_run ){
+
+		uri = g_strdup( nsi->private->uri );
+	}
+
+	return( uri );
+}
+
+/**
+ * na_selected_info_get_uri_scheme:
+ * @nsi: this #NASelectedInfo object.
+ *
+ * Returns: the scheme associated to this @nsi object, as a
+ * newly allocated string which should be g_free() by the caller.
+ */
+gchar *
+na_selected_info_get_uri_scheme( const NASelectedInfo *nsi )
+{
+	gchar *scheme;
+
+	g_return_val_if_fail( NA_IS_SELECTED_INFO( nsi ), NULL );
+
+	scheme = NULL;
+
+	if( !nsi->private->dispose_has_run ){
+
+		scheme = g_strdup( nsi->private->vfs->scheme );
+	}
+
+	return( scheme );
+}
+
+/**
+ * na_selected_info_is_directory:
+ * @nsi: this #NASelectedInfo object.
+ *
+ * Returns: %TRUE if the item is a directory, %FALSE else.
+ */
+gboolean
+na_selected_info_is_directory( const NASelectedInfo *nsi )
+{
+	gboolean is_dir;
+
+	g_return_val_if_fail( NA_IS_SELECTED_INFO( nsi ), FALSE );
+
+	is_dir = FALSE;
+
+	if( !nsi->private->dispose_has_run ){
+
+		is_dir = ( nsi->private->file_type == G_FILE_TYPE_DIRECTORY );
+	}
+
+	return( is_dir );
+}
+
+/**
+ * na_selected_info_create_for_uri:
+ * @uri: an URI.
+ *
+ * Returns: a newly allocated #NASelectedInfo object for the given @uri.
+ */
+NASelectedInfo *
+na_selected_info_create_for_uri( const gchar *uri )
+{
+	static const gchar *thisfn = "na_selected_info_create_for_uri";
+
+	g_debug( "%s", thisfn );
+
+	NASelectedInfo *obj = new_from_uri( uri );
+
+	return( obj );
+}
+
+static NASelectedInfo *
+new_from_nautilus_file_info( NautilusFileInfo *item )
+{
+	gchar *uri = nautilus_file_info_get_uri( item );
+	NASelectedInfo *info = new_from_uri( uri );
+	g_free( uri );
+
+	return( info );
+}
+
+static NASelectedInfo *
+new_from_uri( const gchar *uri )
+{
+	NASelectedInfo *info = g_object_new( NA_SELECTED_INFO_TYPE, NULL );
+
+	info->private->uri = g_strdup( uri );
+	info->private->location = g_file_new_for_uri( uri );
+	info->private->vfs = g_new0( NAGnomeVFSURI, 1 );
+
+	query_file_attributes( info );
+	na_gnome_vfs_uri_parse( info->private->vfs, info->private->uri );
+
+	return( info );
+}
+
+static void
+query_file_attributes( NASelectedInfo *nsi )
+{
+	static const gchar *thisfn = "na_selected_info_query_file_attributes";
+	GError *error;
+
+	error = NULL;
+	GFileInfo *info = g_file_query_info( nsi->private->location,
+			G_FILE_ATTRIBUTE_STANDARD_TYPE "," G_FILE_ATTRIBUTE_STANDARD_FAST_CONTENT_TYPE,
+			G_FILE_QUERY_INFO_NONE, NULL, &error );
+
+	if( error ){
+		g_warning( "%s: g_file_query_info: %s", thisfn, error->message );
+		g_error_free( error );
+		return;
+	}
+
+	nsi->private->mimetype = g_strdup( g_file_info_get_attribute_as_string( info, G_FILE_ATTRIBUTE_STANDARD_FAST_CONTENT_TYPE ));
+	nsi->private->file_type = ( GFileType ) g_file_info_get_attribute_int32( info, G_FILE_ATTRIBUTE_STANDARD_TYPE );
+
+	g_object_unref( info );
+}
diff --git a/src/core/na-selected-info.h b/src/core/na-selected-info.h
new file mode 100644
index 0000000..18d3cb4
--- /dev/null
+++ b/src/core/na-selected-info.h
@@ -0,0 +1,93 @@
+/*
+ * Nautilus Actions
+ * A Nautilus extension which offers configurable context menu selected_infos.
+ *
+ * Copyright (C) 2005 The GNOME Foundation
+ * Copyright (C) 2006, 2007, 2008 Frederic Ruaudel and others (see AUTHORS)
+ * Copyright (C) 2009, 2010 Pierre Wieser and others (see AUTHORS)
+ *
+ * This Program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this Library; see the file COPYING.  If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place,
+ * Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Authors:
+ *   Frederic Ruaudel <grumz grumz net>
+ *   Rodrigo Moya <rodrigo gnome-db org>
+ *   Pierre Wieser <pwieser trychlos org>
+ *   ... and many others (see AUTHORS)
+ */
+
+#ifndef __CORE_NA_SELECTED_INFO_H__
+#define __CORE_NA_SELECTED_INFO_H__
+
+/**
+ * SECTION: na_selected_info
+ * @short_description: #NASelectedInfo class definition.
+ * @include: core/na-selected-info.h
+ *
+ * An object is instantiated for each Nautilus selected item, in order
+ * to gather some common properties for the selected item, mainly its
+ * mime type for example.
+ *
+ * This class should be replaced by NautilusFileInfo class, as soon as
+ * the required Nautilus version will have the
+ * nautilus_file_info_create_for_uri() API (after 2.28)
+ */
+
+#include <libnautilus-extension/nautilus-file-info.h>
+
+G_BEGIN_DECLS
+
+#define NA_SELECTED_INFO_TYPE					( na_selected_info_get_type())
+#define NA_SELECTED_INFO( object )				( G_TYPE_CHECK_INSTANCE_CAST( object, NA_SELECTED_INFO_TYPE, NASelectedInfo ))
+#define NA_SELECTED_INFO_CLASS( klass )			( G_TYPE_CHECK_CLASS_CAST( klass, NA_SELECTED_INFO_TYPE, NASelectedInfoClass ))
+#define NA_IS_SELECTED_INFO( object )			( G_TYPE_CHECK_INSTANCE_TYPE( object, NA_SELECTED_INFO_TYPE ))
+#define NA_IS_SELECTED_INFO_CLASS( klass )		( G_TYPE_CHECK_CLASS_TYPE(( klass ), NA_SELECTED_INFO_TYPE ))
+#define NA_SELECTED_INFO_GET_CLASS( object )	( G_TYPE_INSTANCE_GET_CLASS(( object ), NA_SELECTED_INFO_TYPE, NASelectedInfoClass ))
+
+typedef struct NASelectedInfoPrivate      NASelectedInfoPrivate;
+
+typedef struct {
+	GObject                parent;
+	NASelectedInfoPrivate *private;
+}
+	NASelectedInfo;
+
+typedef struct NASelectedInfoClassPrivate NASelectedInfoClassPrivate;
+
+typedef struct {
+	GObjectClass                parent;
+	NASelectedInfoClassPrivate *private;
+}
+	NASelectedInfoClass;
+
+GType           na_selected_info_get_type( void );
+
+GList          *na_selected_info_get_list_from_item( NautilusFileInfo *item );
+GList          *na_selected_info_get_list_from_list( GList *nautilus_selection );
+GList          *na_selected_info_copy_list         ( GList *list );
+void            na_selected_info_free_list         ( GList *list );
+
+GFile          *na_selected_info_get_location  ( const NASelectedInfo *nsi );
+gchar          *na_selected_info_get_mime_type ( const NASelectedInfo *nsi );
+gchar          *na_selected_info_get_name      ( const NASelectedInfo *nsi );
+gchar          *na_selected_info_get_uri       ( const NASelectedInfo *nsi );
+gchar          *na_selected_info_get_uri_scheme( const NASelectedInfo *nsi );
+gboolean        na_selected_info_is_directory  ( const NASelectedInfo *nsi );
+
+NASelectedInfo *na_selected_info_create_for_uri( const gchar *uri );
+
+G_END_DECLS
+
+#endif /* __CORE_NA_SELECTED_INFO_H__ */
diff --git a/src/nact/nact-ifolders-tab.c b/src/nact/nact-ifolders-tab.c
index fd54888..7304667 100644
--- a/src/nact/nact-ifolders-tab.c
+++ b/src/nact/nact-ifolders-tab.c
@@ -709,7 +709,7 @@ treeview_cell_edited( NactIFoldersTab *instance, const gchar *path_string, const
 			TAB_UPDATABLE_PROP_EDITED_PROFILE, &edited,
 			NULL );
 
-	na_object_profile_replace_folder( edited, previous_text, text );
+	na_object_replace_folder( edited, previous_text, text );
 
 	if( old_text ){
 		*old_text = g_strdup( previous_text );
diff --git a/src/nact/nact-schemes-list.c b/src/nact/nact-schemes-list.c
index b43cbfd..3807f74 100644
--- a/src/nact/nact-schemes-list.c
+++ b/src/nact/nact-schemes-list.c
@@ -678,7 +678,7 @@ on_active_toggled( GtkCellRendererToggle *renderer, gchar *path, BaseWindow *win
 						TAB_UPDATABLE_PROP_EDITED_PROFILE, &edited,
 						NULL );
 				if( edited ){
-					na_object_profile_set_scheme( edited, scheme, !state );
+					na_object_set_scheme( edited, scheme, !state );
 					g_signal_emit_by_name( G_OBJECT( window ), TAB_UPDATABLE_SIGNAL_ITEM_UPDATED, edited, FALSE );
 				}
 			}
@@ -827,7 +827,7 @@ delete_row( BaseWindow *window )
 						TAB_UPDATABLE_PROP_EDITED_PROFILE, &edited,
 						NULL );
 				if( edited ){
-					na_object_profile_set_scheme( edited, scheme, FALSE );
+					na_object_set_scheme( edited, scheme, FALSE );
 					g_signal_emit_by_name( G_OBJECT( window ), TAB_UPDATABLE_SIGNAL_ITEM_UPDATED, edited, FALSE );
 				}
 			}
diff --git a/src/plugin-menu/nautilus-actions.c b/src/plugin-menu/nautilus-actions.c
index 05a2972..f25e38c 100644
--- a/src/plugin-menu/nautilus-actions.c
+++ b/src/plugin-menu/nautilus-actions.c
@@ -44,9 +44,9 @@
 
 #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>
+#include <core/na-selected-info.h>
 
 #include "nautilus-actions.h"
 
@@ -87,7 +87,7 @@ static GList            *menu_provider_get_file_items( NautilusMenuProvider *pro
 static GList            *menu_provider_get_toolbar_items( NautilusMenuProvider *provider, GtkWidget *window, NautilusFileInfo *current_folder );
 
 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 NAObjectProfile  *get_candidate_profile( 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 );
@@ -402,7 +402,7 @@ menu_provider_get_background_items( NautilusMenuProvider *provider, GtkWidget *w
 	static const gchar *thisfn = "nautilus_actions_menu_provider_get_background_items";
 	GList *nautilus_menus_list = NULL;
 	gchar *uri;
-	GList *files;
+	GList *selected;
 	GList *pivot_tree;
 	gboolean add_about;
 	gboolean root_menu;
@@ -414,12 +414,14 @@ menu_provider_get_background_items( NautilusMenuProvider *provider, GtkWidget *w
 				thisfn, ( void * ) provider, ( void * ) window, ( void * ) current_folder, uri );
 		g_free( uri );
 
-		files = g_list_prepend( NULL, current_folder );
-
 		pivot_tree = na_pivot_get_items( NAUTILUS_ACTIONS( provider )->private->pivot );
 
+		selected = na_selected_info_get_list_from_item( current_folder );
+
 		nautilus_menus_list = build_nautilus_menus(
-				NAUTILUS_ACTIONS( provider ), pivot_tree, ITEM_TARGET_BACKGROUND, files );
+				NAUTILUS_ACTIONS( provider ), pivot_tree, ITEM_TARGET_BACKGROUND, selected );
+
+		na_selected_info_free_list( selected );
 
 		root_menu = na_iprefs_read_bool( NA_IPREFS( NAUTILUS_ACTIONS( provider )->private->pivot ), IPREFS_CREATE_ROOT_MENU, FALSE );
 		if( root_menu ){
@@ -431,8 +433,6 @@ menu_provider_get_background_items( NautilusMenuProvider *provider, GtkWidget *w
 		if( add_about ){
 			nautilus_menus_list = add_about_item( NAUTILUS_ACTIONS( provider ), nautilus_menus_list );
 		}
-
-		g_list_free( files );
 	}
 
 	return( nautilus_menus_list );
@@ -453,6 +453,7 @@ menu_provider_get_file_items( NautilusMenuProvider *provider, GtkWidget *window,
 	GList *pivot_tree;
 	gboolean add_about;
 	gboolean root_menu;
+	GList *selected;
 
 	g_debug( "%s: provider=%p, window=%p, files=%p, count=%d",
 			thisfn, ( void * ) provider, ( void * ) window, ( void * ) files, g_list_length( files ));
@@ -473,10 +474,14 @@ menu_provider_get_file_items( NautilusMenuProvider *provider, GtkWidget *window,
 
 		pivot_tree = na_pivot_get_items( self->private->pivot );
 
+		selected = na_selected_info_get_list_from_list( files );
+
 		nautilus_menus_list = build_nautilus_menus(
-				self, pivot_tree, ITEM_TARGET_SELECTION, files );
+				self, pivot_tree, ITEM_TARGET_SELECTION, selected );
 		/*g_debug( "%s: menus has %d level zero items", thisfn, g_list_length( nautilus_menus_list ));*/
 
+		na_selected_info_free_list( selected );
+
 		root_menu = na_iprefs_read_bool( NA_IPREFS( self->private->pivot ), IPREFS_CREATE_ROOT_MENU, FALSE );
 		if( root_menu ){
 			nautilus_menus_list = create_root_menu( self, nautilus_menus_list );
@@ -503,7 +508,7 @@ menu_provider_get_toolbar_items( NautilusMenuProvider *provider, GtkWidget *wind
 	static const gchar *thisfn = "nautilus_actions_menu_provider_get_toolbar_items";
 	GList *nautilus_menus_list = NULL;
 	gchar *uri;
-	GList *files;
+	GList *selected;
 	GList *pivot_tree;
 
 	uri = nautilus_file_info_get_uri( current_folder );
@@ -513,14 +518,14 @@ menu_provider_get_toolbar_items( NautilusMenuProvider *provider, GtkWidget *wind
 
 	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 );
 
+		selected = na_selected_info_get_list_from_item( current_folder );
+
 		nautilus_menus_list = build_nautilus_menus(
-				NAUTILUS_ACTIONS( provider ), pivot_tree, ITEM_TARGET_TOOLBAR, files );
+				NAUTILUS_ACTIONS( provider ), pivot_tree, ITEM_TARGET_TOOLBAR, selected );
 
-		g_list_free( files );
+		na_selected_info_free_list( selected );
 	}
 
 	return( nautilus_menus_list );
@@ -538,7 +543,6 @@ build_nautilus_menus( NautilusActions *plugin, GList *tree, guint target, GList
 	GList *it;
 	NAObjectProfile *profile;
 	NautilusMenuItem *item;
-	gchar *label;
 
 	g_debug( "%s: plugin=%p, tree=%p, target=%d, files=%p (count=%d)",
 			thisfn, ( void * ) plugin, ( void * ) tree, target,
@@ -548,19 +552,23 @@ build_nautilus_menus( NautilusActions *plugin, GList *tree, guint target, GList
 
 		g_return_val_if_fail( NA_IS_OBJECT_ITEM( it->data ), NULL );
 
+#ifdef NA_MAINTAINER_MODE
 		/* 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 )){
-
-				label = na_object_get_label( it->data );
-				g_warning( "%s: '%s' item: enabled=%s, valid=%s", thisfn, label,
-						na_object_is_enabled( it->data ) ? "True":"False",
-						na_object_is_valid( it->data ) ? "True":"False" );
-				g_free( label );
-				continue;
+		if( !na_object_is_enabled( it->data ) || !na_object_is_valid( it->data )){
+			gchar *label = na_object_get_label( it->data );
+			g_warning( "%s: '%s' item: enabled=%s, valid=%s", thisfn, label,
+					na_object_is_enabled( it->data ) ? "True":"False",
+					na_object_is_valid( it->data ) ? "True":"False" );
+			g_free( label );
+			continue;
 		}
+#endif
+
+		/*if( !na_icontext_conditions_is_candidate( it->data, target, files )){
+			continue;
+		}*/
 
 		/* recursively build sub-menus
 		 */
@@ -583,7 +591,13 @@ build_nautilus_menus( NautilusActions *plugin, GList *tree, guint target, GList
 
 		g_return_val_if_fail( NA_IS_OBJECT_ACTION( it->data ), NULL );
 
-		profile = is_action_candidate( plugin, NA_OBJECT_ACTION( it->data ), target, files );
+		/* to be removed when NAObjectAction will implement NAIContextConditions interface
+		 */
+		if( !na_object_action_is_candidate( it->data, target, files )){
+			continue;
+		}
+
+		profile = get_candidate_profile( plugin, NA_OBJECT_ACTION( it->data ), target, files );
 		if( profile ){
 			item = create_item_from_profile( profile, target, files );
 			menus_list = g_list_append( menus_list, item );
@@ -597,7 +611,7 @@ build_nautilus_menus( NautilusActions *plugin, GList *tree, guint target, GList
  * could also be a NAObjectAction method - but this is not used elsewhere
  */
 static NAObjectProfile *
-is_action_candidate( NautilusActions *plugin, NAObjectAction *action, guint target, GList *files )
+get_candidate_profile( NautilusActions *plugin, NAObjectAction *action, guint target, GList *files )
 {
 	static const gchar *thisfn = "nautilus_actions_is_action_candidate";
 	NAObjectProfile *candidate = NULL;
@@ -605,23 +619,20 @@ is_action_candidate( NautilusActions *plugin, NAObjectAction *action, guint targ
 	gchar *profile_label;
 	GList *profiles, *ip;
 
-	if( na_object_action_is_candidate( action, target )){
+	action_label = na_object_get_label( action );
+	profiles = na_object_get_items( action );
 
-		action_label = na_object_get_label( action );
-		profiles = na_object_get_items( action );
+	for( ip = profiles ; ip && !candidate ; ip = ip->next ){
+		NAObjectProfile *profile = NA_OBJECT_PROFILE( ip->data );
 
-		for( ip = profiles ; ip && !candidate ; ip = ip->next ){
-			NAObjectProfile *profile = NA_OBJECT_PROFILE( ip->data );
+		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_free( profile_label );
 
-			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_free( profile_label );
-
-				candidate = profile;
-			}
- 		}
- 	}
+			candidate = profile;
+		}
+	}
 
 	g_free( action_label );
 
@@ -633,38 +644,24 @@ create_item_from_profile( NAObjectProfile *profile, guint target, GList *files )
 {
 	NautilusMenuItem *item;
 	NAObjectAction *action;
-	NAObjectProfile *dup4menu;
 
 	action = NA_OBJECT_ACTION( na_object_get_parent( profile ));
 
 	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 );*/
-
-	/* 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 );*/
-
-	/* rather attach a weak ref on the Nautilus menu item: our duplicated
-	 * profile will so be disposed during the session
+	/* attach a weak ref on the Nautilus menu item: our profile will be
+	 * unreffed in weak notify function
 	 */
 	g_signal_connect( item,
 				"activate",
 				G_CALLBACK( execute_action ),
-				dup4menu );
+				g_object_ref( profile ));
 
-	g_object_weak_ref( G_OBJECT( item ), ( GWeakNotify ) weak_notify_profile, dup4menu );
+	g_object_weak_ref( G_OBJECT( item ), ( GWeakNotify ) weak_notify_profile, profile );
 
 	g_object_set_data_full( G_OBJECT( item ),
 			"nautilus-actions-files",
-			nautilus_file_info_list_copy( files ),
+			na_selected_info_copy_list( files ),
 			( GDestroyNotify ) destroy_notify_file_list );
 
 	g_object_set_data( G_OBJECT( item ),
@@ -686,7 +683,7 @@ static void
 destroy_notify_file_list( GList *list)
 {
 	g_debug( "nautilus_actions_destroy_notify_file_list" );
-	nautilus_file_info_list_free( list );
+	na_selected_info_free_list( list );
 }
 
 /*
diff --git a/src/plugin-tracker/na-tracker-dbus.c b/src/plugin-tracker/na-tracker-dbus.c
index 10d184a..bdef115 100644
--- a/src/plugin-tracker/na-tracker-dbus.c
+++ b/src/plugin-tracker/na-tracker-dbus.c
@@ -37,10 +37,10 @@
 #include <config.h>
 #endif
 
-#include <libnautilus-extension/nautilus-file-info.h>
-
 #include <dbus/dbus-glib.h>
 
+#include <libnautilus-extension/nautilus-file-info.h>
+
 #include <core/na-dbus-tracker.h>
 
 #include "na-tracker-dbus.h"
@@ -212,13 +212,7 @@ na_tracker_dbus_set_uris( NATrackerDBus *tracker, GList *files )
  * @paths: the location in which copy the strings to be sent.
  * @error: the location of a GError.
  *
- * Send on session DBus the list of currently selected items, as two
- * strings for each item :
- * - its uri
- * - its mimetype.
- *
- * Note that this _must_ correspond to the content of the NATrackedItem
- * structure, as described in private/na-object-profile-class.h
+ * Send on session DBus the list of URIs of currently selected items.
  *
  * Exported as GetSelectedPaths method on Tracker.Status interface.
  */
@@ -238,7 +232,7 @@ na_tracker_dbus_get_selected_paths( NATrackerDBus *tracker, char ***paths, GErro
 
 	if( !tracker->private->dispose_has_run ){
 
-		count = 2 * g_list_length( tracker->private->selected );
+		count = g_list_length( tracker->private->selected );
 		*paths = ( char ** ) g_new0( gchar *, 1+count );
 		iter = *paths;
 
@@ -246,8 +240,6 @@ na_tracker_dbus_get_selected_paths( NATrackerDBus *tracker, char ***paths, GErro
 
 			*iter = nautilus_file_info_get_uri(( NautilusFileInfo * ) it->data );
 			iter++;
-			*iter = nautilus_file_info_get_mime_type(( NautilusFileInfo * ) it->data );
-			iter++;
 		}
 	}
 
diff --git a/src/utils/nautilus-actions-new.c b/src/utils/nautilus-actions-new.c
index 932078f..dd2ebac 100644
--- a/src/utils/nautilus-actions-new.c
+++ b/src/utils/nautilus-actions-new.c
@@ -53,7 +53,6 @@ static gchar     *icon             = "";
 static gboolean   enabled          = FALSE;
 static gboolean   disabled         = FALSE;
 static gboolean   target_selection = FALSE;
-static gboolean   target_folders   = FALSE;
 static gboolean   target_toolbar   = FALSE;
 static gchar     *label_toolbar    = "";
 static gchar     *command          = "";
@@ -84,8 +83,6 @@ static GOptionEntry entries[] = {
 			N_( "Set it if the action should be disabled at creation" ), NULL },
 	{ "target-selection"     , 'S', 0, G_OPTION_ARG_NONE        , &target_selection,
 			N_( "Set it if the action should be displayed in selection menus" ), NULL },
-	{ "target-folders"       , 'F', 0, G_OPTION_ARG_NONE        , &target_folders,
-			N_( "Set it if the action should be displayed in folders menus" ), NULL },
 	{ "target-toolbar"       , 'O', 0, G_OPTION_ARG_NONE        , &target_toolbar,
 			N_( "Set it if the action should be displayed in toolbar" ), NULL },
 	{ "label-toolbar"        , 'L', 0, G_OPTION_ARG_STRING      , &label_toolbar,
@@ -296,7 +293,6 @@ get_action_from_cmdline( void )
 	na_object_set_icon( action, icon );
 	na_object_set_enabled( action, enabled );
 	na_object_set_target_selection( action, target_selection );
-	na_object_set_target_background( action, target_folders );
 	na_object_set_target_toolbar( action, target_toolbar );
 
 	if( target_toolbar ){
diff --git a/src/utils/nautilus-actions-run.c b/src/utils/nautilus-actions-run.c
index d6fb8f9..e0ccd98 100644
--- a/src/utils/nautilus-actions-run.c
+++ b/src/utils/nautilus-actions-run.c
@@ -42,6 +42,7 @@
 
 #include <core/na-dbus-tracker.h>
 #include <core/na-pivot.h>
+#include <core/na-selected-info.h>
 
 #include <plugin-tracker/na-tracker.h>
 #include <plugin-tracker/na-tracker-dbus.h>
@@ -73,6 +74,7 @@ static GOptionContext  *init_options( void );
 static NAObjectAction  *get_action( const gchar *id );
 static GList           *targets_from_selection( void );
 static GList           *targets_from_commandline( void );
+static GList           *get_selection_from_strv( const gchar **strv );
 static NAObjectProfile *get_profile_for_targets( NAObjectAction *action, GList *targets );
 static void             execute_action( NAObjectAction *action, NAObjectProfile *profile, GList *targets );
 static void             dump_targets( GList *targets );
@@ -146,7 +148,12 @@ main( int argc, char** argv )
 	dump_targets( targets );
 
 	if( g_list_length( targets ) == 0 ){
-		g_print( "No current selection. Nothing to do. Exiting...\n" );
+		g_print( "No current selection. Nothing to do. Exiting.\n" );
+		exit( status );
+	}
+
+	if( !na_object_action_is_candidate( action, ITEM_TARGET_SELECTION, targets )){
+		g_printerr( _( "Action %s is not a valid candidate. Exiting.\n" ), id );
 		exit( status );
 	}
 
@@ -244,22 +251,20 @@ get_action( const gchar *id )
 
 /*
  * the DBus.Tracker.Status interface returns a list of strings
- * each item has two slots in this list:
- * - uri
- * - mimetype
+ * where each item is the URI of a selected item.
+ *
+ * We return to the caller a GList of NautilusFileInfo
  */
 static GList *
 targets_from_selection( void )
 {
 	static const gchar *thisfn = "nautilus_actions_run_targets_from_selection";
 	GList *selection;
-	NATrackedItem *tracked;
 	DBusGConnection *connection;
 	DBusGProxy *proxy;
 	GError *error;
-	gchar **paths, **iter;
+	gchar **paths;
 
-	selection = NULL;
 	error = NULL;
 	proxy = NULL;
 	paths = NULL;
@@ -297,17 +302,9 @@ targets_from_selection( void )
 	}
 	g_debug( "%s: function call is ok", thisfn );
 
-	iter = paths;
-	while( *iter ){
-		tracked = g_new0( NATrackedItem, 1 );
-		tracked->uri = g_strdup( *iter );
-		iter++;
-		tracked->mimetype = g_strdup( *iter );
-		iter++;
-		selection = g_list_prepend( selection, tracked );
-	}
+	selection = get_selection_from_strv(( const gchar ** ) paths );
+
 	g_strfreev( paths );
-	selection = g_list_reverse( selection );
 
 	/* TODO: unref proxy */
 	dbus_g_connection_unref( connection );
@@ -317,30 +314,38 @@ targets_from_selection( void )
 
 /*
  * get targets from command-line
+ *
+ * We return to the caller a GList of NautilusFileInfo
  */
 static GList *
 targets_from_commandline( void )
 {
 	static const gchar *thisfn = "nautilus_actions_run_targets_from_commandline";
 	GList *targets;
-	NATrackedItem *tracked;
-	gchar **iter;
 
 	g_debug( "%s", thisfn );
 
-	targets = NULL;
-	iter = targets_array;
+	targets = get_selection_from_strv(( const gchar ** ) targets_array );
+
+	return( targets );
+}
+
+static GList *
+get_selection_from_strv( const gchar **strv )
+{
+	GList *list;
+	gchar **iter;
+
+	list = NULL;
+	iter = ( gchar ** ) strv;
 
 	while( *iter ){
-		tracked = g_new0( NATrackedItem, 1 );
-		tracked->uri = g_strdup( *iter );
+		NASelectedInfo *nsi = na_selected_info_create_for_uri( *iter );
+		list = g_list_prepend( list, nsi );
 		iter++;
-		targets = g_list_prepend( targets, tracked );
 	}
 
-	targets = g_list_reverse( targets );
-
-	return( targets );
+	return( g_list_reverse( list ));
 }
 
 /*
@@ -350,16 +355,15 @@ static NAObjectProfile *
 get_profile_for_targets( NAObjectAction *action, GList *targets )
 {
 	/*static const gchar *thisfn = "nautilus_actions_run_get_profile_for_targets";*/
-	NAObjectProfile *candidate;
 	GList *profiles, *ip;
+	NAObjectProfile *candidate;
 
 	candidate = NULL;
 	profiles = na_object_get_items( action );
 	for( ip = profiles ; ip && !candidate ; ip = ip->next ){
 
-		NAObjectProfile *profile = NA_OBJECT_PROFILE( ip->data );
-		if( na_object_profile_is_candidate_for_tracked( profile, targets )){
-			candidate = profile;
+		if( na_icontext_conditions_is_candidate( NA_ICONTEXT_CONDITIONS( ip->data ), ITEM_TARGET_SELECTION, targets )){
+			candidate = NA_OBJECT_PROFILE( ip->data );
 		}
 	}
 
@@ -376,7 +380,7 @@ execute_action( NAObjectAction *action, NAObjectProfile *profile, GList *targets
 	path = na_object_get_path( profile );
 	cmd = g_string_new( path );
 
-	param = na_object_profile_parse_parameters_for_tracked( profile, targets );
+	param = na_object_profile_parse_parameters( profile, ITEM_TARGET_SELECTION, targets );
 
 	if( param != NULL ){
 		g_string_append_printf( cmd, " %s", param );
@@ -396,12 +400,16 @@ execute_action( NAObjectAction *action, NAObjectProfile *profile, GList *targets
 static void
 dump_targets( GList *targets )
 {
-	NATrackedItem *tracked;
 	GList *it;
+	gchar *uri, *mimetype;
 
 	for( it = targets ; it ; it = it->next ){
-		tracked = ( NATrackedItem * ) it->data;
-		g_print( "%s\t[%s]\n", tracked->uri, tracked->mimetype );
+		NASelectedInfo *nsi = NA_SELECTED_INFO( it->data );
+		uri = na_selected_info_get_uri( nsi );
+		mimetype = na_selected_info_get_mime_type( nsi );
+		g_print( "%s\t[%s]\n", uri, mimetype );
+		g_free( mimetype );
+		g_free( uri );
 	}
 }
 
@@ -411,16 +419,7 @@ dump_targets( GList *targets )
 static void
 free_targets( GList *targets )
 {
-	NATrackedItem *tracked;
-	GList *it;
-
-	for( it = targets ; it ; it = it->next ){
-		tracked = ( NATrackedItem * ) it->data;
-		g_free( tracked->uri );
-		g_free( tracked->mimetype );
-		g_free( tracked );
-	}
-
+	g_list_foreach( targets, ( GFunc ) g_object_unref, NULL );
 	g_list_free( targets );
 }
 



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