[nautilus-actions] Begin with implementation of multiple profiles



commit 5aae8ed9eb6f1194eabb5388c0323d194e56f37e
Author: Pierre Wieser <pwieser trychlos org>
Date:   Wed Jul 15 00:47:12 2009 +0200

    Begin with implementation of multiple profiles

 ChangeLog                                |   27 ++
 src/nact/Makefile.am                     |    2 +
 src/nact/nact-action-conditions-editor.c |   27 +-
 src/nact/nact-action-profiles-editor.c   |  308 ++++++++++++++++++++---
 src/nact/nact-action-profiles-editor.h   |    4 +-
 src/nact/nact-iactions-list.c            |  284 +++++++++-----------
 src/nact/nact-iactions-list.h            |    4 +-
 src/nact/nact-imenu-item.c               |   16 +-
 src/nact/nact-iprofile-conditions.c      |    3 +
 src/nact/nact-iprofiles-list.c           |  412 ++++++++++++++++++++++++++++++
 src/nact/nact-iprofiles-list.h           |   88 +++++++
 src/nact/nact-main-window.c              |   66 ++----
 src/nact/nact-window.c                   |   36 +---
 src/nact/nact-window.h                   |    7 +-
 src/nact/nautilus-actions-config.ui      |  151 ++++++-----
 15 files changed, 1071 insertions(+), 364 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 6cbdec6..e6d159a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,30 @@
+2009-07-15 Pierre Wieser <pwieser trychlos org>
+
+	* src/nact/nact-action-conditions-editor.c (on_save_clicked):
+	New function (do not know why it used to work without it!).
+
+	* src/nact/nact-action-conditions-editor.c
+	(set_current_action): Removed function.
+
+	* src/nact/nact-action-profiles-editor.c:
+	Begin with the rewriting with the new object hierarchy and the
+	new interfaces.
+
+	* src/nact/nact-iprofiles-list.c:
+	* src/nact/nact-iprofiles-list.h: New files.
+
+	* src/nact/nact-iactions-list.c:
+	* src/nact/nact-iactions-list.h:
+	Remove references to NAPivot, rather use interface.
+	Now directly attach the NAAction to each line of the listbox.
+
+	* src/nact/Makefile.am: Updated accordingly.
+
+	* src/nact/nact-window.c:
+	* src/nact/nact-window.h
+	(nact_window_get_action, nact_window_get_actions):
+	Removed functions.
+
 2009-07-14 Pierre Wieser <pwieser trychlos org>
 
 	* src/common/na-utils.c:
diff --git a/src/nact/Makefile.am b/src/nact/Makefile.am
index 754fc15..f3752d7 100644
--- a/src/nact/Makefile.am
+++ b/src/nact/Makefile.am
@@ -69,6 +69,8 @@ nautilus_actions_config_SOURCES = \
 	nact-iprefs.h										\
 	nact-iprofile-conditions.c							\
 	nact-iprofile-conditions.h							\
+	nact-iprofiles-list.c								\
+	nact-iprofiles-list.h								\
 	nact-main.c											\
 	nact-main-window.c									\
 	nact-main-window.h									\
diff --git a/src/nact/nact-action-conditions-editor.c b/src/nact/nact-action-conditions-editor.c
index 6f1b489..709fc93 100644
--- a/src/nact/nact-action-conditions-editor.c
+++ b/src/nact/nact-action-conditions-editor.c
@@ -79,12 +79,12 @@ static void     setup_dialog_title( NactActionConditionsEditor *dialog, gboolean
 static void     setup_buttons( NactActionConditionsEditor *dialog, gboolean can_save );
 static void     on_modified_field( NactWindow *dialog );
 static void     on_cancel_clicked( GtkButton *button, gpointer user_data );
+static void     on_save_clicked( GtkButton *button, gpointer user_data );
 static gboolean on_dialog_response( GtkDialog *dialog, gint code, BaseWindow *window );
 
 static GObject *get_edited_action( NactWindow *window );
 static GObject *get_edited_profile( NactWindow *window );
 static gboolean is_edited_modified( NactActionConditionsEditor *dialog );
-static void     set_current_action( NactActionConditionsEditor *dialog );
 
 GType
 nact_action_conditions_editor_get_type( void )
@@ -243,10 +243,10 @@ instance_finalize( GObject *dialog )
 	}
 }
 
-/**
+/*
  * Returns a newly allocated NactActionConditionsEditor object.
  *
- * @parent: is the BaseWindow parent of this dialog (usually, the main
+ * @parent: the BaseWindow parent of this dialog (usually, the main
  * toplevel window of the application).
  */
 static NactActionConditionsEditor *
@@ -369,6 +369,7 @@ on_runtime_init_dialog( BaseWindow *dialog )
 	nact_iprofile_conditions_runtime_init( NACT_WINDOW( window ), profile );
 
 	nact_window_signal_connect_by_name( NACT_WINDOW( window ), "CancelButton", "clicked", G_CALLBACK( on_cancel_clicked ));
+	nact_window_signal_connect_by_name( NACT_WINDOW( window ), "SaveButton", "clicked", G_CALLBACK( on_save_clicked ));
 }
 
 static void
@@ -411,7 +412,6 @@ setup_dialog_title( NactActionConditionsEditor *dialog, gboolean is_modified )
 	}
 
 	gtk_window_set_title( toplevel, title );
-
 	g_free( title );
 }
 
@@ -459,6 +459,13 @@ on_cancel_clicked( GtkButton *button, gpointer user_data )
 	gtk_dialog_response( GTK_DIALOG( toplevel ), GTK_RESPONSE_CLOSE );
 }
 
+static void
+on_save_clicked( GtkButton *button, gpointer user_data )
+{
+	GtkWindow *toplevel = base_window_get_toplevel_dialog( BASE_WINDOW( user_data ));
+	gtk_dialog_response( GTK_DIALOG( toplevel ), GTK_RESPONSE_OK );
+}
+
 static gboolean
 on_dialog_response( GtkDialog *dialog, gint code, BaseWindow *window )
 {
@@ -489,7 +496,7 @@ on_dialog_response( GtkDialog *dialog, gint code, BaseWindow *window )
 					editor->private->original = na_action_duplicate( editor->private->edited );
 					editor->private->is_new = FALSE;
 					on_modified_field( NACT_WINDOW( editor ));
-					set_current_action( NACT_ACTION_CONDITIONS_EDITOR( window ));
+					nact_window_set_current_action( editor->private->parent, editor->private->original );
 				}
 			}
 			break;
@@ -517,13 +524,3 @@ is_edited_modified( NactActionConditionsEditor *dialog )
 {
 	return( !na_action_are_equal( dialog->private->original, dialog->private->edited ));
 }
-
-static void
-set_current_action( NactActionConditionsEditor *dialog )
-{
-	gchar *uuid = na_action_get_uuid( dialog->private->original );
-	gchar *label = na_action_get_label( dialog->private->original );
-	nact_window_set_current_action( dialog->private->parent, uuid, label );
-	g_free( label );
-	g_free( uuid );
-}
diff --git a/src/nact/nact-action-profiles-editor.c b/src/nact/nact-action-profiles-editor.c
index 98ffd25..7b0ad79 100644
--- a/src/nact/nact-action-profiles-editor.c
+++ b/src/nact/nact-action-profiles-editor.c
@@ -35,11 +35,13 @@
 #include <glib/gi18n.h>
 
 #include <common/na-action.h>
+#include <common/na-action-profile.h>
 
 #include "nact-application.h"
 #include "nact-action-profiles-editor.h"
 #include "nact-imenu-item.h"
-#include "nact-main-window.h"
+#include "nact-iprofiles-list.h"
+#include "nact-iprefs.h"
 
 /* private class data
  */
@@ -49,9 +51,11 @@ struct NactActionProfilesEditorClassPrivate {
 /* private instance data
  */
 struct NactActionProfilesEditorPrivate {
-	gboolean  dispose_has_run;
-	NAAction *action;
-	gboolean  is_new;
+	gboolean    dispose_has_run;
+	NactWindow *parent;
+	NAAction   *original;
+	NAAction   *edited;
+	gboolean    is_new;
 };
 
 static GObjectClass *st_parent_class = NULL;
@@ -59,18 +63,34 @@ static GObjectClass *st_parent_class = NULL;
 static GType    register_type( void );
 static void     class_init( NactActionProfilesEditorClass *klass );
 static void     imenu_item_iface_init( NactIMenuItemInterface *iface );
+static void     iprofiles_list_iface_init( NactIProfilesListInterface *iface );
 static void     instance_init( GTypeInstance *instance, gpointer klass );
 static void     instance_dispose( GObject *dialog );
 static void     instance_finalize( GObject *dialog );
 
 static NactActionProfilesEditor *action_profiles_editor_new( BaseApplication *application );
 
+static gchar   *do_get_iprefs_window_id( NactWindow *window );
 static gchar   *do_get_dialog_name( BaseWindow *dialog );
 static void     on_initial_load_dialog( BaseWindow *dialog );
 static void     on_runtime_init_dialog( BaseWindow *dialog );
-static void     init_dialog_title( NactActionProfilesEditor *dialog );
+static void     on_all_widgets_showed( BaseWindow *dialog );
+static void     setup_dialog_title( NactActionProfilesEditor *dialog, gboolean is_modified );
+static void     setup_buttons( NactActionProfilesEditor *dialog, gboolean can_save );
+
+static void     on_profiles_list_selection_changed( GtkTreeSelection *selection, gpointer user_data );
+static gboolean on_profiles_list_double_click( GtkWidget *widget, GdkEventButton *event, gpointer data );
+static gboolean on_profiles_list_enter_key_pressed( GtkWidget *widget, GdkEventKey *event, gpointer data );
+static void     on_modified_field( NactWindow *dialog );
+static void     on_edit_button_clicked( GtkButton *button, gpointer user_data );
+static void     on_cancel_clicked( GtkButton *button, gpointer user_data );
 static gboolean on_dialog_response( GtkDialog *dialog, gint code, BaseWindow *window );
 
+static GSList  *do_get_profiles( NactWindow *window );
+static GObject *get_edited_action( NactWindow *window );
+static gboolean is_edited_modified( NactActionProfilesEditor *dialog );
+static void     do_set_current_profile( NactActionProfilesEditor *dialog, const NAActionProfile *profile );
+
 GType
 nact_action_profiles_editor_get_type( void )
 {
@@ -113,6 +133,16 @@ register_type( void )
 
 	g_type_add_interface_static( type, NACT_IMENU_ITEM_TYPE, &imenu_item_iface_info );
 
+	/* implement IProfilesList interface
+	 */
+	static const GInterfaceInfo iprofiles_list_iface_info = {
+		( GInterfaceInitFunc ) iprofiles_list_iface_init,
+		NULL,
+		NULL
+	};
+
+	g_type_add_interface_static( type, NACT_IPROFILES_LIST_TYPE, &iprofiles_list_iface_info );
+
 	return( type );
 }
 
@@ -133,8 +163,12 @@ class_init( NactActionProfilesEditorClass *klass )
 	BaseWindowClass *base_class = BASE_WINDOW_CLASS( klass );
 	base_class->initial_load_toplevel = on_initial_load_dialog;
 	base_class->runtime_init_toplevel = on_runtime_init_dialog;
+	base_class->all_widgets_showed = on_all_widgets_showed;
 	base_class->dialog_response = on_dialog_response;
 	base_class->get_toplevel_name = do_get_dialog_name;
+
+	NactWindowClass *nact_class = NACT_WINDOW_CLASS( klass );
+	nact_class->get_iprefs_window_id = do_get_iprefs_window_id;
 }
 
 static void
@@ -142,6 +176,21 @@ imenu_item_iface_init( NactIMenuItemInterface *iface )
 {
 	static const gchar *thisfn = "nact_action_profiles_editor_imenu_item_iface_init";
 	g_debug( "%s: iface=%p", thisfn, iface );
+
+	iface->get_edited_action = get_edited_action;
+	iface->field_modified = on_modified_field;
+}
+
+static void
+iprofiles_list_iface_init( NactIProfilesListInterface *iface )
+{
+	static const gchar *thisfn = "nact_action_profiles_editor_iprofiles_list_iface_init";
+	g_debug( "%s: iface=%p", thisfn, iface );
+
+	iface->get_profiles = do_get_profiles;
+	iface->on_selection_changed = on_profiles_list_selection_changed;
+	iface->on_double_click = on_profiles_list_double_click;
+	iface->on_enter_key_pressed = on_profiles_list_enter_key_pressed;
 }
 
 static void
@@ -156,6 +205,8 @@ instance_init( GTypeInstance *instance, gpointer klass )
 	self->private = g_new0( NactActionProfilesEditorPrivate, 1 );
 
 	self->private->dispose_has_run = FALSE;
+	self->private->original = NULL;
+	self->private->edited = NULL;
 }
 
 static void
@@ -171,6 +222,11 @@ instance_dispose( GObject *dialog )
 
 		self->private->dispose_has_run = TRUE;
 
+		nact_imenu_item_dispose( NACT_WINDOW( dialog ));
+
+		g_object_unref( self->private->original );
+		g_object_unref( self->private->edited );
+
 		/* chain up to the parent class */
 		G_OBJECT_CLASS( st_parent_class )->dispose( dialog );
 	}
@@ -183,7 +239,9 @@ instance_finalize( GObject *dialog )
 	g_debug( "%s: dialog=%p", thisfn, dialog );
 
 	g_assert( NACT_IS_ACTION_PROFILES_EDITOR( dialog ));
-	/*NactActionProfilesEditor *self = ( NactActionProfilesEditor * ) dialog;*/
+	NactActionProfilesEditor *self = ( NactActionProfilesEditor * ) dialog;
+
+	g_free( self->private );
 
 	/* chain call to parent class */
 	if( st_parent_class->finalize ){
@@ -191,10 +249,10 @@ instance_finalize( GObject *dialog )
 	}
 }
 
-/**
+/*
  * Returns a newly allocated NactActionProfilesEditor object.
  *
- * @parent: is the BaseWindow parent of this dialog (usually, the main
+ * @parent: the BaseWindow parent of this dialog (usually, the main
  * toplevel window of the application).
  */
 static NactActionProfilesEditor *
@@ -215,82 +273,221 @@ action_profiles_editor_new( BaseApplication *application )
  * Returns TRUE if the NAAction has been edited and saved, or FALSE if
  * there has been no modification at all.
  */
-gboolean
+void
 nact_action_profiles_editor_run_editor( NactWindow *parent, gpointer user_data )
 {
-	g_assert( NACT_IS_MAIN_WINDOW( parent ));
+	g_assert( NACT_IS_ACTION_PROFILES_EDITOR( parent ));
 
 	BaseApplication *application = BASE_APPLICATION( base_window_get_application( BASE_WINDOW( parent )));
 	g_assert( NACT_IS_APPLICATION( application ));
 
 	NactActionProfilesEditor *dialog = action_profiles_editor_new( application );
+	dialog->private->parent = parent;
 
 	g_assert( NA_IS_ACTION( user_data ) || !user_data );
 	NAAction *action = NA_ACTION( user_data );
 
 	if( !action ){
-		dialog->private->action = na_action_new( NULL );
+		dialog->private->original = na_action_new_with_profile();
 		dialog->private->is_new = TRUE;
 
 	} else {
-		dialog->private->action = na_action_duplicate( action );
+		dialog->private->original = na_action_duplicate( action );
 		dialog->private->is_new = FALSE;
 	}
 
+	dialog->private->edited = na_action_duplicate( dialog->private->original );
+
+	g_assert( na_action_get_profiles_count( dialog->private->original ) > 1 );
+	g_assert( na_action_get_profiles_count( dialog->private->edited ) > 1 );
+
 	base_window_run( BASE_WINDOW( dialog ));
+}
 
-	g_object_unref( dialog->private->action );
-	return( TRUE );
+static gchar *
+do_get_iprefs_window_id( NactWindow *window )
+{
+	return( g_strdup( "action-profiles-editor" ));
 }
 
 static gchar *
 do_get_dialog_name( BaseWindow *dialog )
 {
-	/*g_debug( "nact_action_profiles_editor_do_get_dialog_name" );*/
-	return( g_strdup( "EditActionDialogExt"));
+	return( g_strdup( "EditActionDialog"));
 }
 
 static void
 on_initial_load_dialog( BaseWindow *dialog )
 {
 	static const gchar *thisfn = "nact_action_profiles_editor_on_initial_load_dialog";
-	g_debug( "%s: dialog=%p", thisfn, dialog );
 
+	/* call parent class at the very beginning */
+	if( BASE_WINDOW_CLASS( st_parent_class )->initial_load_toplevel ){
+		BASE_WINDOW_CLASS( st_parent_class )->initial_load_toplevel( dialog );
+	}
+
+	g_debug( "%s: dialog=%p", thisfn, dialog );
 	g_assert( NACT_IS_ACTION_PROFILES_EDITOR( dialog ));
 	NactActionProfilesEditor *window = NACT_ACTION_PROFILES_EDITOR( dialog );
 
-	init_dialog_title( window );
-	nact_imenu_item_initial_load( NACT_WINDOW( window ), window->private->action );
+	nact_imenu_item_initial_load( NACT_WINDOW( window ), window->private->edited );
+
+	g_assert( NACT_IS_IPROFILES_LIST( window ));
+	nact_iprofiles_list_initial_load( NACT_WINDOW( window ));
+	nact_iprofiles_list_set_multiple_selection( NACT_WINDOW( window ), FALSE );
+	nact_iprofiles_list_set_send_selection_changed_on_fill_list( NACT_WINDOW( window ), FALSE );
 }
 
 static void
 on_runtime_init_dialog( BaseWindow *dialog )
 {
 	static const gchar *thisfn = "nact_action_profiles_editor_on_runtime_init_dialog";
-	g_debug( "%s: dialog=%p", thisfn, dialog );
 
+	/* call parent class at the very beginning */
+	if( BASE_WINDOW_CLASS( st_parent_class )->runtime_init_toplevel ){
+		BASE_WINDOW_CLASS( st_parent_class )->runtime_init_toplevel( dialog );
+	}
+
+	g_debug( "%s: dialog=%p", thisfn, dialog );
 	g_assert( NACT_IS_ACTION_PROFILES_EDITOR( dialog ));
 	NactActionProfilesEditor *window = NACT_ACTION_PROFILES_EDITOR( dialog );
 
-	init_dialog_title( window );
-	nact_imenu_item_runtime_init( NACT_WINDOW( window ), window->private->action );
+	setup_dialog_title( window, FALSE );
+
+	nact_imenu_item_runtime_init( NACT_WINDOW( window ), window->private->edited );
+	nact_iprofiles_list_runtime_init( NACT_WINDOW( window ));
+
+	nact_window_signal_connect_by_name( NACT_WINDOW( window ), "CancelButton", "clicked", G_CALLBACK( on_cancel_clicked ));
 }
 
 static void
-init_dialog_title( NactActionProfilesEditor *dialog )
+on_all_widgets_showed( BaseWindow *dialog )
+{
+	static const gchar *thisfn = "nact_action_profiles_editor_on_all_widgets_showed";
+
+	/* call parent class at the very beginning */
+	if( BASE_WINDOW_CLASS( st_parent_class )->all_widgets_showed ){
+		BASE_WINDOW_CLASS( st_parent_class )->all_widgets_showed( dialog );
+	}
+
+	g_debug( "%s: dialog=%p", thisfn, dialog );
+
+	nact_imenu_item_all_widgets_showed( NACT_WINDOW( dialog ));
+}
+
+static void
+setup_dialog_title( NactActionProfilesEditor *dialog, gboolean is_modified )
 {
 	GtkWindow *toplevel = base_window_get_toplevel_dialog( BASE_WINDOW( dialog ));
 
+	gchar *title;
 	if( dialog->private->is_new ){
-		gtk_window_set_title( toplevel, _( "Adding a new action" ));
-
+		title = g_strdup( _( "Adding a new action" ));
 	} else {
-		gchar *label = na_action_get_label( dialog->private->action );
-		gchar* title = g_strdup_printf( _( "Editing \"%s\" action" ), label );
-		gtk_window_set_title( toplevel, title );
+		gchar *label = na_action_get_label( dialog->private->original );
+		title = g_strdup_printf( _( "Editing \"%s\" action" ), label );
 		g_free( label );
+	}
+
+	if( is_modified ){
+		gchar *tmp = g_strdup_printf( "*%s", title );
 		g_free( title );
+		title = tmp;
 	}
+
+	gtk_window_set_title( toplevel, title );
+	g_free( title );
+}
+
+/*
+ * rationale:
+ * while the action is not modified, only the cancel button is activated
+ * when the action has been modified, we have a save and a cancel buttons
+ * + a label is mandatory to enable the save button
+ */
+static void
+setup_buttons( NactActionProfilesEditor *dialog, gboolean can_save )
+{
+	GtkWidget *cancel_button = gtk_button_new_from_stock( GTK_STOCK_CANCEL );
+	GtkWidget *close_button = gtk_button_new_from_stock( GTK_STOCK_CLOSE );
+	GtkWidget *button = base_window_get_widget( BASE_WINDOW( dialog ), "CancelButton" );
+	gtk_button_set_label( GTK_BUTTON( button ), can_save ? _( "_Cancel" ) : _( "_Close" ));
+	gtk_button_set_image( GTK_BUTTON( button ), can_save ? gtk_button_get_image( GTK_BUTTON( cancel_button )) : gtk_button_get_image( GTK_BUTTON( close_button )));
+	gtk_widget_destroy( cancel_button );
+	gtk_widget_destroy( close_button );
+
+	button = base_window_get_widget( BASE_WINDOW( dialog ), "SaveButton" );
+	gtk_widget_set_sensitive( button, can_save );
+}
+
+static void
+on_profiles_list_selection_changed( GtkTreeSelection *selection, gpointer user_data )
+{
+	/*static const gchar *thisfn = "nact_main_window_on_profiles_list_selection_changed";
+	g_debug( "%s: selection=%p, user_data=%p", thisfn, selection, user_data );*/
+
+	g_assert( NACT_IS_ACTION_PROFILES_EDITOR( user_data ));
+	BaseWindow *window = BASE_WINDOW( user_data );
+
+	GtkWidget *edit_button = base_window_get_widget( window, "EditActionButton" );
+	GtkWidget *delete_button = base_window_get_widget( window, "DeleteActionButton" );
+	GtkWidget *duplicate_button = base_window_get_widget( window, "DuplicateActionButton" );
+
+	gboolean enabled = ( gtk_tree_selection_count_selected_rows( selection ) > 0 );
+
+	gtk_widget_set_sensitive( edit_button, enabled );
+	gtk_widget_set_sensitive( delete_button, enabled );
+	gtk_widget_set_sensitive( duplicate_button, enabled );
+
+	NAActionProfile *profile = NA_ACTION_PROFILE( nact_iprofiles_list_get_selected_profile( NACT_WINDOW( window )));
+	do_set_current_profile( NACT_ACTION_PROFILES_EDITOR( window ), profile );
+}
+
+static gboolean
+on_profiles_list_double_click( GtkWidget *widget, GdkEventButton *event, gpointer user_data )
+{
+	g_assert( event->type == GDK_2BUTTON_PRESS );
+
+	on_edit_button_clicked( NULL, user_data );
+
+	return( TRUE );
+}
+
+static gboolean
+on_profiles_list_enter_key_pressed( GtkWidget *widget, GdkEventKey *event, gpointer user_data )
+{
+	on_edit_button_clicked( NULL, user_data );
+
+	return( TRUE );
+}
+
+static void
+on_modified_field( NactWindow *window )
+{
+	/*static const gchar *thisfn = "nact_action_profiles_editor_on_modified_field";*/
+
+	g_assert( NACT_IS_ACTION_PROFILES_EDITOR( window ));
+	NactActionProfilesEditor *dialog = ( NACT_ACTION_PROFILES_EDITOR( window ));
+
+	gboolean is_modified = is_edited_modified( dialog );
+	/*g_debug( "%s: is_modified=%s", thisfn, is_modified ? "True":"False" );*/
+	setup_dialog_title( dialog, is_modified );
+
+	gboolean can_save = is_modified && nact_imenu_item_has_label( window );
+	setup_buttons( dialog, can_save );
+}
+
+static void
+on_edit_button_clicked( GtkButton *button, gpointer user_data )
+{
+
+}
+
+static void
+on_cancel_clicked( GtkButton *button, gpointer user_data )
+{
+	GtkWindow *toplevel = base_window_get_toplevel_dialog( BASE_WINDOW( user_data ));
+	gtk_dialog_response( GTK_DIALOG( toplevel ), GTK_RESPONSE_CLOSE );
 }
 
 static gboolean
@@ -300,14 +497,65 @@ on_dialog_response( GtkDialog *dialog, gint code, BaseWindow *window )
 	g_debug( "%s: dialog=%p, code=%d, window=%p", thisfn, dialog, code, window );
 
 	g_assert( NACT_IS_ACTION_PROFILES_EDITOR( window ));
+	NactActionProfilesEditor *editor = NACT_ACTION_PROFILES_EDITOR( window );
+
+	gboolean is_modified = is_edited_modified( editor );
 
 	switch( code ){
 		case GTK_RESPONSE_NONE:
 		case GTK_RESPONSE_DELETE_EVENT:
 		case GTK_RESPONSE_CLOSE:
-			g_object_unref( window );
+		case GTK_RESPONSE_CANCEL:
+			if( !is_modified ||
+				nact_window_warn_action_modified( NACT_WINDOW( editor ), editor->private->original )){
+					g_object_unref( window );
+					return( TRUE );
+			}
+			break;
+
+		case GTK_RESPONSE_OK:
+			if( is_modified ){
+				if( nact_window_save_action( NACT_WINDOW( editor ), editor->private->edited )){
+					g_object_unref( editor->private->original );
+					editor->private->original = na_action_duplicate( editor->private->edited );
+					editor->private->is_new = FALSE;
+					on_modified_field( NACT_WINDOW( editor ));
+					/*do_set_current_action( NACT_ACTION_PROFILES_EDITOR( window ));*/
+				}
+			}
 			break;
 	}
 
-	return( TRUE );
+	return( FALSE );
+}
+
+static GSList *
+do_get_profiles( NactWindow *window )
+{
+	g_assert( NACT_IS_ACTION_PROFILES_EDITOR( window ));
+
+	return( NULL );
+}
+
+static GObject *
+get_edited_action( NactWindow *window )
+{
+	g_assert( NACT_IS_ACTION_PROFILES_EDITOR( window ));
+	return( G_OBJECT( NACT_ACTION_PROFILES_EDITOR( window )->private->edited ));
+}
+
+static gboolean
+is_edited_modified( NactActionProfilesEditor *dialog )
+{
+	return( !na_action_are_equal( dialog->private->original, dialog->private->edited ));
+}
+
+static void
+do_set_current_profile( NactActionProfilesEditor *dialog, const NAActionProfile *profile )
+{
+	/*gchar *uuid = na_action_get_uuid( dialog->private->original );
+	gchar *label = na_action_get_label( dialog->private->original );
+	nact_window_set_current_action( dialog->private->parent, uuid, label );
+	g_free( label );
+	g_free( uuid );*/
 }
diff --git a/src/nact/nact-action-profiles-editor.h b/src/nact/nact-action-profiles-editor.h
index 99f8896..79bdf0d 100644
--- a/src/nact/nact-action-profiles-editor.h
+++ b/src/nact/nact-action-profiles-editor.h
@@ -65,9 +65,9 @@ typedef struct {
 }
 	NactActionProfilesEditorClass;
 
-GType    nact_action_profiles_editor_get_type( void );
+GType nact_action_profiles_editor_get_type( void );
 
-gboolean nact_action_profiles_editor_run_editor( NactWindow *parent, gpointer user_data );
+void  nact_action_profiles_editor_run_editor( NactWindow *parent, gpointer user_data );
 
 G_END_DECLS
 
diff --git a/src/nact/nact-iactions-list.c b/src/nact/nact-iactions-list.c
index 3cbcfab..9325793 100644
--- a/src/nact/nact-iactions-list.c
+++ b/src/nact/nact-iactions-list.c
@@ -35,7 +35,6 @@
 #include <gdk/gdkkeysyms.h>
 
 #include <common/na-action.h>
-#include <common/na-pivot.h>
 
 #include "nact-application.h"
 #include "nact-iactions-list.h"
@@ -50,7 +49,7 @@ struct NactIActionsListInterfacePrivate {
 enum {
 	IACTIONS_LIST_ICON_COLUMN = 0,
 	IACTIONS_LIST_LABEL_COLUMN,
-	IACTIONS_LIST_UUID_COLUMN,
+	IACTIONS_LIST_ACTION_COLUMN,
 	IACTIONS_LIST_N_COLUMN
 };
 
@@ -64,13 +63,11 @@ static GType      register_type( void );
 static void       interface_base_init( NactIActionsListInterface *klass );
 static void       interface_base_finalize( NactIActionsListInterface *klass );
 
+static GSList    *v_get_actions( NactWindow *window );
 static void       v_on_selection_changed( GtkTreeSelection *selection, gpointer user_data );
 static gboolean   v_on_button_press_event( GtkWidget *widget, GdkEventButton *event, gpointer data );
 static gboolean   v_on_key_pressed_event( GtkWidget *widget, GdkEventKey *event, gpointer data );
 
-static void       do_initial_load_widget( NactWindow *window );
-static void       do_runtime_init_widget( NactWindow *window );
-static void       do_fill_actions_list( NactWindow *window );
 static GtkWidget *get_actions_list_widget( NactWindow *window );
 
 GType
@@ -121,10 +118,6 @@ interface_base_init( NactIActionsListInterface *klass )
 
 		klass->private = g_new0( NactIActionsListInterfacePrivate, 1 );
 
-		klass->initial_load_widget = do_initial_load_widget;
-		klass->runtime_init_widget = do_runtime_init_widget;
-		klass->on_selection_changed = NULL;
-
 		initialized = TRUE;
 	}
 }
@@ -150,16 +143,34 @@ interface_base_finalize( NactIActionsListInterface *klass )
 void
 nact_iactions_list_initial_load( NactWindow *window )
 {
+	static const gchar *thisfn = "nact_iactions_list_initial_load";
+	g_debug( "%s: window=%p", thisfn, window );
+
 	g_assert( NACT_IS_IACTIONS_LIST( window ));
+	g_assert( NACT_IS_WINDOW( window ));
 
 	nact_iactions_list_set_send_selection_changed_on_fill_list( window, FALSE );
 	nact_iactions_list_set_is_filling_list( window, FALSE );
 
-	if( NACT_IACTIONS_LIST_GET_INTERFACE( window )->initial_load_widget ){
-		NACT_IACTIONS_LIST_GET_INTERFACE( window )->initial_load_widget( window );
-	} else {
-		do_initial_load_widget( window );
-	}
+	GtkListStore *model;
+	GtkTreeViewColumn *column;
+	GtkWidget *widget = get_actions_list_widget( window );
+
+	/* create the model */
+	model = gtk_list_store_new(
+			IACTIONS_LIST_N_COLUMN, GDK_TYPE_PIXBUF, G_TYPE_STRING, NA_ACTION_TYPE );
+	gtk_tree_view_set_model( GTK_TREE_VIEW( widget ), GTK_TREE_MODEL( model ));
+	nact_iactions_list_fill( window );
+	g_object_unref( model );
+
+	/* create visible columns on the tree view */
+	column = gtk_tree_view_column_new_with_attributes(
+			"icon", gtk_cell_renderer_pixbuf_new(), "pixbuf", IACTIONS_LIST_ICON_COLUMN, NULL );
+	gtk_tree_view_append_column( GTK_TREE_VIEW( widget ), column );
+
+	column = gtk_tree_view_column_new_with_attributes(
+			"label", gtk_cell_renderer_text_new(), "text", IACTIONS_LIST_LABEL_COLUMN, NULL );
+	gtk_tree_view_append_column( GTK_TREE_VIEW( widget ), column );
 }
 
 /**
@@ -168,13 +179,39 @@ nact_iactions_list_initial_load( NactWindow *window )
 void
 nact_iactions_list_runtime_init( NactWindow *window )
 {
+	static const gchar *thisfn = "nact_iactions_list_runtime_init";
+	g_debug( "%s: window=%p", thisfn, window );
+
 	g_assert( NACT_IS_IACTIONS_LIST( window ));
+	g_assert( NACT_IS_WINDOW( window ));
 
-	if( NACT_IACTIONS_LIST_GET_INTERFACE( window )->runtime_init_widget ){
-		NACT_IACTIONS_LIST_GET_INTERFACE( window )->runtime_init_widget( window );
-	} else {
-		do_runtime_init_widget( window );
-	}
+	GtkWidget *widget = get_actions_list_widget( window );
+	g_assert( GTK_IS_WIDGET( widget ));
+
+	/* set up selection */
+	nact_window_signal_connect(
+			window,
+			G_OBJECT( gtk_tree_view_get_selection( GTK_TREE_VIEW( widget ))),
+			"changed",
+			G_CALLBACK( v_on_selection_changed ));
+
+	/* catch press 'Enter' */
+	nact_window_signal_connect(
+			window,
+			G_OBJECT( widget ),
+			"key-press-event",
+			G_CALLBACK( v_on_key_pressed_event ));
+
+	/* catch double-click */
+	nact_window_signal_connect(
+			window,
+			G_OBJECT( widget ),
+			"button-press-event",
+			G_CALLBACK( v_on_button_press_event ));
+
+	/* clear the selection */
+	GtkTreeSelection *selection = gtk_tree_view_get_selection( GTK_TREE_VIEW( widget ));
+	gtk_tree_selection_unselect_all( selection );
 }
 
 /**
@@ -183,15 +220,65 @@ nact_iactions_list_runtime_init( NactWindow *window )
 void
 nact_iactions_list_fill( NactWindow *window )
 {
+	static const gchar *thisfn = "nact_iactions_list_fill";
+	g_debug( "%s: window=%p", thisfn, window );
+
 	g_assert( NACT_IS_IACTIONS_LIST( window ));
 
 	nact_iactions_list_set_is_filling_list( window, TRUE );
 
-	if( NACT_IACTIONS_LIST_GET_INTERFACE( window )->fill_actions_list ){
-		NACT_IACTIONS_LIST_GET_INTERFACE( window )->fill_actions_list( window );
-	} else {
-		do_fill_actions_list( window );
+	GtkWidget *widget = get_actions_list_widget( window );
+	GtkListStore *model = GTK_LIST_STORE( gtk_tree_view_get_model( GTK_TREE_VIEW( widget )));
+	gtk_list_store_clear( model );
+
+	GSList *actions = v_get_actions( window );
+	GSList *ia;
+	/*g_debug( "%s: actions has %d elements", thisfn, g_slist_length( actions ));*/
+
+	for( ia = actions ; ia != NULL ; ia = ia->next ){
+		GtkTreeIter iter;
+		GtkStockItem item;
+		GdkPixbuf* icon = NULL;
+
+		NAAction *action = NA_ACTION( ia->data );
+		gchar *label = na_action_get_label( action );
+		gchar *iconname = na_action_get_icon( action );
+
+		/* TODO: use the same algorythm than Nautilus to find and
+		 * display an icon + move the code to NAAction class +
+		 * remove na_action_get_verified_icon_name
+		 */
+		if( iconname ){
+			if( gtk_stock_lookup( iconname, &item )){
+				icon = gtk_widget_render_icon( widget, iconname, GTK_ICON_SIZE_MENU, NULL );
+
+			} else if( g_file_test( iconname, G_FILE_TEST_EXISTS )
+				   && g_file_test( iconname, G_FILE_TEST_IS_REGULAR )){
+				gint width;
+				gint height;
+				GError* error = NULL;
+
+				gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, &width, &height);
+				icon = gdk_pixbuf_new_from_file_at_size( iconname, width, height, &error );
+				if( error ){
+					g_warning( "%s: iconname=%s, error=%s", thisfn, iconname, error->message );
+					g_error_free( error );
+					error = NULL;
+					icon = NULL;
+				}
+			}
+		}
+		gtk_list_store_append( model, &iter );
+		gtk_list_store_set( model, &iter,
+				    IACTIONS_LIST_ICON_COLUMN, icon,
+				    IACTIONS_LIST_LABEL_COLUMN, label,
+				    IACTIONS_LIST_ACTION_COLUMN, action,
+				    -1);
+
+		g_free( iconname );
+		g_free( label );
 	}
+	/*g_debug( "%s: at end, actions has %d elements", thisfn, g_slist_length( actions ));*/
 
 	nact_iactions_list_set_is_filling_list( window, FALSE );
 }
@@ -215,6 +302,7 @@ nact_iactions_list_set_selection( NactWindow *window, const gchar *uuid, const g
 
 	gboolean iterok = gtk_tree_model_get_iter_first( model, &iter );
 	gboolean found = FALSE;
+	NAAction *action;
 	gchar *iter_uuid, *iter_label;
 	gint count = 0;
 
@@ -223,9 +311,10 @@ nact_iactions_list_set_selection( NactWindow *window, const gchar *uuid, const g
 		gtk_tree_model_get(
 				model,
 				&iter,
-				IACTIONS_LIST_UUID_COLUMN, &iter_uuid, IACTIONS_LIST_LABEL_COLUMN, &iter_label,
+				IACTIONS_LIST_ACTION_COLUMN, &action, IACTIONS_LIST_LABEL_COLUMN, &iter_label,
 				-1 );
 
+		iter_uuid = na_action_get_uuid( action );
 		gint ret_uuid = g_ascii_strcasecmp( iter_uuid, uuid );
 		gint ret_label = g_utf8_collate( iter_label, label );
 		if(( ret_uuid == 0 && ret_label == 0 ) || ret_label > 0 ){
@@ -287,18 +376,16 @@ nact_iactions_list_get_selected_actions( NactWindow *window )
 
 	GtkTreeModel *model;
 	GtkTreeIter iter;
-	gchar *uuid;
 	GList *it;
+	NAAction *action;
 
 	GList *listrows = gtk_tree_selection_get_selected_rows( selection, &model );
 	for( it = listrows ; it ; it = it->next ){
 		GtkTreePath *path = ( GtkTreePath * ) it->data;
 		gtk_tree_model_get_iter( model, &iter, path );
 
-		gtk_tree_model_get( model, &iter, IACTIONS_LIST_UUID_COLUMN, &uuid, -1 );
-		NAAction *action = NA_ACTION( nact_window_get_action( window, uuid ));
+		gtk_tree_model_get( model, &iter, IACTIONS_LIST_ACTION_COLUMN, &action, -1 );
 		actions = g_slist_prepend( actions, action );
-		g_free (uuid);
 	}
 
 	g_list_foreach( listrows, ( GFunc ) gtk_tree_path_free, NULL );
@@ -342,6 +429,19 @@ nact_iactions_list_set_is_filling_list( NactWindow *window, gboolean is_filling
 	g_object_set_data( G_OBJECT( window ), IS_FILLING_LIST, GINT_TO_POINTER( is_filling ));
 }
 
+static GSList *
+v_get_actions( NactWindow *window )
+{
+	g_assert( NACT_IS_IACTIONS_LIST( window ));
+	NactIActionsList *instance = NACT_IACTIONS_LIST( window );
+
+	if( NACT_IACTIONS_LIST_GET_INTERFACE( instance )->get_actions ){
+		return( NACT_IACTIONS_LIST_GET_INTERFACE( instance )->get_actions( window ));
+	}
+
+	return( NULL );
+}
+
 static void
 v_on_selection_changed( GtkTreeSelection *selection, gpointer user_data )
 {
@@ -414,134 +514,6 @@ v_on_key_pressed_event( GtkWidget *widget, GdkEventKey *event, gpointer user_dat
 	return( stop );
 }
 
-void
-do_initial_load_widget( NactWindow *window )
-{
-	static const gchar *thisfn = "nact_iactions_list_do_initial_load_widget";
-	g_debug( "%s: window=%p", thisfn, window );
-
-	GtkListStore *model;
-	GtkTreeViewColumn *column;
-
-	g_assert( BASE_IS_WINDOW( window ));
-
-	GtkWidget *widget = get_actions_list_widget( window );
-
-	/* create the model */
-	model = gtk_list_store_new( IACTIONS_LIST_N_COLUMN, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_STRING );
-	gtk_tree_view_set_model( GTK_TREE_VIEW( widget ), GTK_TREE_MODEL( model ));
-	nact_iactions_list_fill( window );
-	g_object_unref( model );
-
-	/* create visible columns on the tree view */
-	column = gtk_tree_view_column_new_with_attributes(
-			"icon", gtk_cell_renderer_pixbuf_new(), "pixbuf", IACTIONS_LIST_ICON_COLUMN, NULL );
-	gtk_tree_view_append_column( GTK_TREE_VIEW( widget ), column );
-
-	column = gtk_tree_view_column_new_with_attributes(
-			"label", gtk_cell_renderer_text_new(), "text", IACTIONS_LIST_LABEL_COLUMN, NULL );
-	gtk_tree_view_append_column( GTK_TREE_VIEW( widget ), column );
-}
-
-void
-do_runtime_init_widget( NactWindow *window )
-{
-	static const gchar *thisfn = "nact_iactions_list_do_runtime_init_widget";
-	g_debug( "%s: window=%p", thisfn, window );
-
-	g_assert( BASE_IS_WINDOW( window ));
-
-	GtkWidget *widget = get_actions_list_widget( window );
-	g_assert( GTK_IS_WIDGET( widget ));
-
-	/* set up selection */
-	nact_window_signal_connect(
-			window,
-			G_OBJECT( gtk_tree_view_get_selection( GTK_TREE_VIEW( widget ))),
-			"changed",
-			G_CALLBACK( v_on_selection_changed ));
-
-	/* catch press 'Enter' */
-	nact_window_signal_connect(
-			window,
-			G_OBJECT( widget ),
-			"key-press-event",
-			G_CALLBACK( v_on_key_pressed_event ));
-
-	/* catch double-click */
-	nact_window_signal_connect(
-			window,
-			G_OBJECT( widget ),
-			"button-press-event",
-			G_CALLBACK( v_on_button_press_event ));
-
-	/* clear the selection */
-	GtkTreeSelection *selection = gtk_tree_view_get_selection( GTK_TREE_VIEW( widget ));
-	gtk_tree_selection_unselect_all( selection );
-}
-
-static void
-do_fill_actions_list( NactWindow *window )
-{
-	static const gchar *thisfn = "nact_iactions_list_do_fill_actions_list";
-	g_debug( "%s: window=%p", thisfn, window );
-
-	GtkWidget *widget = get_actions_list_widget( window );
-	GtkListStore *model = GTK_LIST_STORE( gtk_tree_view_get_model( GTK_TREE_VIEW( widget )));
-	gtk_list_store_clear( model );
-
-	GSList *actions = nact_window_get_actions( window );
-	GSList *ia;
-	/*g_debug( "%s: actions has %d elements", thisfn, g_slist_length( actions ));*/
-
-	for( ia = actions ; ia != NULL ; ia = ia->next ){
-		GtkTreeIter iter;
-		GtkStockItem item;
-		GdkPixbuf* icon = NULL;
-
-		NAAction *action = NA_ACTION( ia->data );
-		gchar *uuid = na_action_get_uuid( action );
-		gchar *label = na_action_get_label( action );
-		gchar *iconname = na_action_get_icon( action );
-
-		/* TODO: use the same algorythm than Nautilus to find and
-		 * display an icon + move the code to NAAction class +
-		 * remove na_action_get_verified_icon_name
-		 */
-		if( iconname ){
-			if( gtk_stock_lookup( iconname, &item )){
-				icon = gtk_widget_render_icon( widget, iconname, GTK_ICON_SIZE_MENU, NULL );
-
-			} else if( g_file_test( iconname, G_FILE_TEST_EXISTS )
-				   && g_file_test( iconname, G_FILE_TEST_IS_REGULAR )){
-				gint width;
-				gint height;
-				GError* error = NULL;
-
-				gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, &width, &height);
-				icon = gdk_pixbuf_new_from_file_at_size( iconname, width, height, &error );
-				if( error ){
-					g_warning( "%s: iconname=%s, error=%s", thisfn, iconname, error->message );
-					g_error_free( error );
-					error = NULL;
-					icon = NULL;
-				}
-			}
-		}
-		gtk_list_store_append( model, &iter );
-		gtk_list_store_set( model, &iter,
-				    IACTIONS_LIST_ICON_COLUMN, icon,
-				    IACTIONS_LIST_LABEL_COLUMN, label,
-				    IACTIONS_LIST_UUID_COLUMN, uuid,
-				    -1);
-
-		g_free( iconname );
-		g_free( label );
-		g_free( uuid );
-	}
-	/*g_debug( "%s: at end, actions has %d elements", thisfn, g_slist_length( actions ));*/
-}
-
 static GtkWidget *
 get_actions_list_widget( NactWindow *window )
 {
diff --git a/src/nact/nact-iactions-list.h b/src/nact/nact-iactions-list.h
index a399249..3089033 100644
--- a/src/nact/nact-iactions-list.h
+++ b/src/nact/nact-iactions-list.h
@@ -59,9 +59,7 @@ typedef struct {
 	NactIActionsListInterfacePrivate *private;
 
 	/* api */
-	void     ( *initial_load_widget )  ( NactWindow *window );
-	void     ( *runtime_init_widget )  ( NactWindow *window );
-	void     ( *fill_actions_list )    ( NactWindow *window );
+	GSList * ( *get_actions )          ( NactWindow *window );
 	void     ( *on_selection_changed ) ( GtkTreeSelection *selection, gpointer user_data );
 	gboolean ( *on_button_press_event )( GtkWidget *widget, GdkEventButton *event, gpointer data );
 	gboolean ( *on_key_pressed_event ) ( GtkWidget *widget, GdkEventKey *event, gpointer data );
diff --git a/src/nact/nact-imenu-item.c b/src/nact/nact-imenu-item.c
index f9062e1..1a4c97b 100644
--- a/src/nact/nact-imenu-item.c
+++ b/src/nact/nact-imenu-item.c
@@ -38,6 +38,7 @@
 #include <common/na-action.h>
 #include <common/na-action-profile.h>
 
+#include "nact-application.h"
 #include "nact-imenu-item.h"
 
 /* private interface data
@@ -146,10 +147,14 @@ nact_imenu_item_initial_load( NactWindow *dialog, NAAction *action )
 	static const gchar *thisfn = "nact_imenu_item_initial_load";
 	g_debug( "%s: dialog=%p, action=%p", thisfn, dialog, action );
 
-	GtkWidget *icon_widget = base_window_get_widget( BASE_WINDOW( dialog ), "MenuIconComboBoxEntry" );
+	/*BaseApplication *appli = BASE_APPLICATION( base_window_get_application( BASE_WINDOW( dialog )));
+	GtkWindow *toplevel = base_application_get_dialog( appli, "MenuItemWindow" );
+	GtkWidget *vbox = base_application_search_for_widget( appli, toplevel, "MenuItemVBox" );
+	GtkWidget *dest = base_application_get_widget( appli, BASE_WINDOW( dialog ), "MenuItemVBox" );
+	gtk_widget_reparent( vbox, dest );*/
 
+	GtkWidget *icon_widget = base_window_get_widget( BASE_WINDOW( dialog ), "MenuIconComboBoxEntry" );
 	gtk_combo_box_set_model( GTK_COMBO_BOX( icon_widget ), create_stock_icon_model());
-
 	icon_combo_list_fill( GTK_COMBO_BOX_ENTRY( icon_widget ));
 }
 
@@ -236,6 +241,13 @@ nact_imenu_item_has_label( NactWindow *window )
 void
 nact_imenu_item_dispose( NactWindow *dialog )
 {
+	static const gchar *thisfn = "nact_imenu_item_dispose";
+	g_debug( "%s: dialog=%p", thisfn, dialog );
+
+	/*BaseApplication *appli = BASE_APPLICATION( base_window_get_application( BASE_WINDOW( dialog )));
+	GtkWindow *toplevel = base_application_get_dialog( appli, "MenuItemWindow" );
+	GtkWidget *vbox = base_application_get_widget( appli, BASE_WINDOW( dialog ), "MenuItemVBox" );
+	gtk_widget_reparent( vbox, GTK_WIDGET( toplevel ));*/
 }
 
 static GObject *
diff --git a/src/nact/nact-iprofile-conditions.c b/src/nact/nact-iprofile-conditions.c
index 1336a27..543a14c 100644
--- a/src/nact/nact-iprofile-conditions.c
+++ b/src/nact/nact-iprofile-conditions.c
@@ -313,6 +313,9 @@ nact_iprofile_conditions_all_widgets_showed( NactWindow *dialog )
 void
 nact_iprofile_conditions_dispose( NactWindow *dialog )
 {
+	static const gchar *thisfn = "nact_iprofile_conditions_dispose";
+	g_debug( "%s: dialog=%p", thisfn, dialog );
+
 	hide_legend_dialog( dialog );
 }
 
diff --git a/src/nact/nact-iprofiles-list.c b/src/nact/nact-iprofiles-list.c
new file mode 100644
index 0000000..d6076b1
--- /dev/null
+++ b/src/nact/nact-iprofiles-list.c
@@ -0,0 +1,412 @@
+/*
+ * Nautilus Actions
+ * A Nautilus extension which offers configurable context menu actions.
+ *
+ * Copyright (C) 2005 The GNOME Foundation
+ * Copyright (C) 2006, 2007, 2008 Frederic Ruaudel and others (see AUTHORS)
+ * Copyright (C) 2009 Pierre Wieser and others (see AUTHORS)
+ *
+ * This Program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this Library; see the file COPYING.  If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place,
+ * Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Authors:
+ *   Frederic Ruaudel <grumz grumz net>
+ *   Rodrigo Moya <rodrigo gnome-db org>
+ *   Pierre Wieser <pwieser trychlos org>
+ *   ... and many others (see AUTHORS)
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gdk/gdkkeysyms.h>
+
+#include <common/na-action.h>
+#include <common/na-action-profile.h>
+
+#include "nact-application.h"
+#include "nact-iprofiles-list.h"
+
+/* private interface data
+ */
+struct NactIProfilesListInterfacePrivate {
+};
+
+/* column ordering
+ */
+enum {
+	IPROFILES_LIST_LABEL_COLUMN = 0,
+	IPROFILES_LIST_PROFILE_COLUMN,
+	IPROFILES_LIST_N_COLUMN
+};
+
+/* data set against GObject
+ */
+#define ACCEPT_MULTIPLE_SELECTION		"iprofiles-list-accept-multiple-selection"
+#define IS_FILLING_LIST					"iprofiles-list-is-filling-list"
+#define SEND_SELECTION_CHANGED_MESSAGE	"iprofiles-list-send-selection-changed-message"
+
+static GType      register_type( void );
+static void       interface_base_init( NactIProfilesListInterface *klass );
+static void       interface_base_finalize( NactIProfilesListInterface *klass );
+
+static GSList    *v_get_profiles( NactWindow *window );
+static void       v_on_selection_changed( GtkTreeSelection *selection, gpointer user_data );
+static gboolean   v_on_button_press_event( GtkWidget *widget, GdkEventButton *event, gpointer data );
+static gboolean   v_on_key_pressed_event( GtkWidget *widget, GdkEventKey *event, gpointer data );
+
+static GtkWidget *get_profiles_list_widget( NactWindow *window );
+
+GType
+nact_iprofiles_list_get_type( void )
+{
+	static GType iface_type = 0;
+
+	if( !iface_type ){
+		iface_type = register_type();
+	}
+
+	return( iface_type );
+}
+
+static GType
+register_type( void )
+{
+	static const gchar *thisfn = "nact_iprofiles_list_register_type";
+	g_debug( "%s", thisfn );
+
+	static const GTypeInfo info = {
+		sizeof( NactIProfilesListInterface ),
+		( GBaseInitFunc ) interface_base_init,
+		( GBaseFinalizeFunc ) interface_base_finalize,
+		NULL,
+		NULL,
+		NULL,
+		0,
+		0,
+		NULL
+	};
+
+	GType type = g_type_register_static( G_TYPE_INTERFACE, "NactIProfilesList", &info, 0 );
+
+	g_type_interface_add_prerequisite( type, G_TYPE_OBJECT );
+
+	return( type );
+}
+
+static void
+interface_base_init( NactIProfilesListInterface *klass )
+{
+	static const gchar *thisfn = "nact_iprofiles_list_interface_base_init";
+	static gboolean initialized = FALSE;
+
+	if( !initialized ){
+		g_debug( "%s: klass=%p", thisfn, klass );
+
+		klass->private = g_new0( NactIProfilesListInterfacePrivate, 1 );
+
+		initialized = TRUE;
+	}
+}
+
+static void
+interface_base_finalize( NactIProfilesListInterface *klass )
+{
+	static const gchar *thisfn = "nact_iprofiles_list_interface_base_finalize";
+	static gboolean finalized = FALSE ;
+
+	if( !finalized ){
+		g_debug( "%s: klass=%p", thisfn, klass );
+
+		g_free( klass->private );
+
+		finalized = TRUE;
+	}
+}
+
+/**
+ * Allocates and initializes the ActionsList widget.
+ */
+void
+nact_iprofiles_list_initial_load( NactWindow *window )
+{
+	static const gchar *thisfn = "nact_iprofiles_list_initial_load";
+	g_debug( "%s: window=%p", thisfn, window );
+
+	g_assert( NACT_IS_IPROFILES_LIST( window ));
+	g_assert( NACT_IS_WINDOW( window ));
+
+	nact_iprofiles_list_set_send_selection_changed_on_fill_list( window, FALSE );
+	nact_iprofiles_list_set_is_filling_list( window, FALSE );
+
+	GtkListStore *model;
+	GtkTreeViewColumn *column;
+
+	GtkWidget *widget = get_profiles_list_widget( window );
+
+	/* create the model */
+	model = gtk_list_store_new( IPROFILES_LIST_N_COLUMN, G_TYPE_STRING, NA_ACTION_PROFILE_TYPE );
+	gtk_tree_view_set_model( GTK_TREE_VIEW( widget ), GTK_TREE_MODEL( model ));
+	nact_iprofiles_list_fill( window );
+	g_object_unref( model );
+
+	/* create visible columns on the tree view */
+	column = gtk_tree_view_column_new_with_attributes(
+			"label", gtk_cell_renderer_text_new(), "text", IPROFILES_LIST_LABEL_COLUMN, NULL );
+	gtk_tree_view_append_column( GTK_TREE_VIEW( widget ), column );
+}
+
+/**
+ * Allocates and initializes the ProfilesList widget.
+ */
+void
+nact_iprofiles_list_runtime_init( NactWindow *window )
+{
+	static const gchar *thisfn = "nact_iprofiles_list_do_runtime_init_widget";
+	g_debug( "%s: window=%p", thisfn, window );
+
+	g_assert( NACT_IS_IPROFILES_LIST( window ));
+	g_assert( NACT_IS_WINDOW( window ));
+
+	GtkWidget *widget = get_profiles_list_widget( window );
+	g_assert( GTK_IS_WIDGET( widget ));
+
+	/* set up selection */
+	nact_window_signal_connect(
+			window,
+			G_OBJECT( gtk_tree_view_get_selection( GTK_TREE_VIEW( widget ))),
+			"changed",
+			G_CALLBACK( v_on_selection_changed ));
+
+	/* catch press 'Enter' */
+	nact_window_signal_connect(
+			window,
+			G_OBJECT( widget ),
+			"key-press-event",
+			G_CALLBACK( v_on_key_pressed_event ));
+
+	/* catch double-click */
+	nact_window_signal_connect(
+			window,
+			G_OBJECT( widget ),
+			"button-press-event",
+			G_CALLBACK( v_on_button_press_event ));
+
+	/* clear the selection */
+	GtkTreeSelection *selection = gtk_tree_view_get_selection( GTK_TREE_VIEW( widget ));
+	gtk_tree_selection_unselect_all( selection );
+}
+
+/**
+ * Fill the listbox with current profiles.
+ */
+void
+nact_iprofiles_list_fill( NactWindow *window )
+{
+	static const gchar *thisfn = "nact_iprofiles_list_do_fill_profiles_list";
+	g_debug( "%s: window=%p", thisfn, window );
+
+	g_assert( NACT_IS_IPROFILES_LIST( window ));
+	g_assert( NACT_IS_WINDOW( window ));
+
+	nact_iprofiles_list_set_is_filling_list( window, TRUE );
+
+	GtkWidget *widget = get_profiles_list_widget( window );
+	GtkListStore *model = GTK_LIST_STORE( gtk_tree_view_get_model( GTK_TREE_VIEW( widget )));
+	gtk_list_store_clear( model );
+
+	GSList *profiles = v_get_profiles( window );
+	GSList *ip;
+	/*g_debug( "%s: actions has %d elements", thisfn, g_slist_length( actions ));*/
+
+	for( ip = profiles ; ip ; ip = ip->next ){
+
+		GtkTreeIter iter;
+		NAActionProfile *profile = NA_ACTION_PROFILE( ip->data );
+		gchar *label = na_action_profile_get_label( profile );
+
+		gtk_list_store_append( model, &iter );
+		gtk_list_store_set( model, &iter,
+				    IPROFILES_LIST_LABEL_COLUMN, label,
+				    IPROFILES_LIST_PROFILE_COLUMN, profile,
+				    -1);
+
+		g_free( label );
+	}
+
+	nact_iprofiles_list_set_is_filling_list( window, FALSE );
+}
+
+/**
+ * Reset the focus on the ProfilesList listbox.
+ */
+void
+nact_iprofiles_list_set_focus( NactWindow *window )
+{
+	GtkWidget *list = get_profiles_list_widget( window );
+	gtk_widget_grab_focus( list );
+}
+
+/**
+ * Returns the currently selected profile.
+ */
+GObject *
+nact_iprofiles_list_get_selected_profile( NactWindow *window )
+{
+	GtkWidget *treeview = get_profiles_list_widget( window );
+	GtkTreeSelection *selection = gtk_tree_view_get_selection( GTK_TREE_VIEW( treeview ));
+
+	GtkTreeModel *model;
+	GtkTreeIter iter;
+	GObject *profile;
+
+	GList *listrows = gtk_tree_selection_get_selected_rows( selection, &model );
+	GtkTreePath *path = ( GtkTreePath * ) listrows->data;
+	gtk_tree_model_get_iter( model, &iter, path );
+
+	gtk_tree_model_get( model, &iter, IPROFILES_LIST_PROFILE_COLUMN, &profile, -1 );
+
+	g_list_foreach( listrows, ( GFunc ) gtk_tree_path_free, NULL );
+	g_list_free( listrows );
+
+	return( profile );
+}
+
+/**
+ * Does the IProfilesList box support multiple selection ?
+ */
+void
+nact_iprofiles_list_set_multiple_selection( NactWindow *window, gboolean multiple )
+{
+	g_assert( NACT_IS_IPROFILES_LIST( window ));
+	g_object_set_data( G_OBJECT( window ), ACCEPT_MULTIPLE_SELECTION, GINT_TO_POINTER( multiple ));
+
+	GtkWidget *list = get_profiles_list_widget( window );
+	GtkTreeSelection *selection = gtk_tree_view_get_selection( GTK_TREE_VIEW( list ));
+	gtk_tree_selection_set_mode( selection, multiple ? GTK_SELECTION_MULTIPLE : GTK_SELECTION_SINGLE );
+}
+
+/**
+ * Should the IProfilesList interface trigger a 'on_selection_changed'
+ * message when the ActionsList list is filled ?
+ */
+void
+nact_iprofiles_list_set_send_selection_changed_on_fill_list( NactWindow *window, gboolean send_message )
+{
+	g_assert( NACT_IS_IPROFILES_LIST( window ));
+	g_object_set_data( G_OBJECT( window ), SEND_SELECTION_CHANGED_MESSAGE, GINT_TO_POINTER( send_message ));
+}
+
+/**
+ * Is the IProfilesList interface currently filling the ActionsList ?
+ */
+void
+nact_iprofiles_list_set_is_filling_list( NactWindow *window, gboolean is_filling )
+{
+	g_assert( NACT_IS_IPROFILES_LIST( window ));
+	g_object_set_data( G_OBJECT( window ), IS_FILLING_LIST, GINT_TO_POINTER( is_filling ));
+}
+
+static GSList *
+v_get_profiles( NactWindow *window )
+{
+	g_assert( NACT_IS_IPROFILES_LIST( window ));
+	NactIProfilesList *instance = NACT_IPROFILES_LIST( window );
+
+	if( NACT_IPROFILES_LIST_GET_INTERFACE( instance )->get_profiles ){
+		return( NACT_IPROFILES_LIST_GET_INTERFACE( instance )->get_profiles( window ));
+	}
+
+	return( NULL );
+}
+
+static void
+v_on_selection_changed( GtkTreeSelection *selection, gpointer user_data )
+{
+	g_assert( NACT_IS_IPROFILES_LIST( user_data ));
+	g_assert( BASE_IS_WINDOW( user_data ));
+
+	NactIProfilesList *instance = NACT_IPROFILES_LIST( user_data );
+
+	g_assert( NACT_IS_WINDOW( user_data ));
+	gboolean send_message = GPOINTER_TO_INT( g_object_get_data( G_OBJECT( user_data ), SEND_SELECTION_CHANGED_MESSAGE ));
+	gboolean is_filling = GPOINTER_TO_INT( g_object_get_data( G_OBJECT( user_data ), IS_FILLING_LIST ));
+
+	if( send_message || !is_filling ){
+		if( NACT_IPROFILES_LIST_GET_INTERFACE( instance )->on_selection_changed ){
+			NACT_IPROFILES_LIST_GET_INTERFACE( instance )->on_selection_changed( selection, user_data );
+		}
+	}
+}
+
+static gboolean
+v_on_button_press_event( GtkWidget *widget, GdkEventButton *event, gpointer user_data )
+{
+	/*static const gchar *thisfn = "nact_iprofiles_list_v_on_button_pres_event";
+	g_debug( "%s: widget=%p, event=%p, user_data=%p", thisfn, widget, event, user_data );*/
+
+	g_assert( NACT_IS_IPROFILES_LIST( user_data ));
+	g_assert( NACT_IS_WINDOW( user_data ));
+
+	gboolean stop = FALSE;
+	NactIProfilesList *instance = NACT_IPROFILES_LIST( user_data );
+
+	if( NACT_IPROFILES_LIST_GET_INTERFACE( instance )->on_button_press_event ){
+		stop = NACT_IPROFILES_LIST_GET_INTERFACE( instance )->on_button_press_event( widget, event, user_data );
+	}
+
+	if( !stop ){
+		if( event->type == GDK_2BUTTON_PRESS ){
+			if( NACT_IPROFILES_LIST_GET_INTERFACE( instance )->on_double_click ){
+				stop = NACT_IPROFILES_LIST_GET_INTERFACE( instance )->on_double_click( widget, event, user_data );
+			}
+		}
+	}
+	return( stop );
+}
+
+static gboolean
+v_on_key_pressed_event( GtkWidget *widget, GdkEventKey *event, gpointer user_data )
+{
+	/*static const gchar *thisfn = "nact_iprofiles_list_v_on_key_pressed_event";
+	g_debug( "%s: widget=%p, event=%p, user_data=%p", thisfn, widget, event, user_data );*/
+
+	g_assert( NACT_IS_IPROFILES_LIST( user_data ));
+	g_assert( NACT_IS_WINDOW( user_data ));
+	g_assert( event->type == GDK_KEY_PRESS );
+
+	gboolean stop = FALSE;
+	NactIProfilesList *instance = NACT_IPROFILES_LIST( user_data );
+
+	if( NACT_IPROFILES_LIST_GET_INTERFACE( instance )->on_key_pressed_event ){
+		stop = NACT_IPROFILES_LIST_GET_INTERFACE( instance )->on_key_pressed_event( widget, event, user_data );
+	}
+
+	if( !stop ){
+		if( event->keyval == GDK_Return || event->keyval == GDK_KP_Enter ){
+			if( NACT_IPROFILES_LIST_GET_INTERFACE( instance )->on_enter_key_pressed ){
+				stop = NACT_IPROFILES_LIST_GET_INTERFACE( instance )->on_enter_key_pressed( widget, event, user_data );
+			}
+		}
+	}
+	return( stop );
+}
+
+static GtkWidget *
+get_profiles_list_widget( NactWindow *window )
+{
+	return( base_window_get_widget( BASE_WINDOW( window ), "ProfilesList" ));
+}
diff --git a/src/nact/nact-iprofiles-list.h b/src/nact/nact-iprofiles-list.h
new file mode 100644
index 0000000..b264c3d
--- /dev/null
+++ b/src/nact/nact-iprofiles-list.h
@@ -0,0 +1,88 @@
+/*
+ * Nautilus Actions
+ * A Nautilus extension which offers configurable context menu actions.
+ *
+ * Copyright (C) 2005 The GNOME Foundation
+ * Copyright (C) 2006, 2007, 2008 Frederic Ruaudel and others (see AUTHORS)
+ * Copyright (C) 2009 Pierre Wieser and others (see AUTHORS)
+ *
+ * This Program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this Library; see the file COPYING.  If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place,
+ * Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Authors:
+ *   Frederic Ruaudel <grumz grumz net>
+ *   Rodrigo Moya <rodrigo gnome-db org>
+ *   Pierre Wieser <pwieser trychlos org>
+ *   ... and many others (see AUTHORS)
+ */
+
+#ifndef __NACT_IPROFILES_LIST_H__
+#define __NACT_IPROFILES_LIST_H__
+
+/*
+ * NactIProfilesList interface definition.
+ *
+ * This interface defines some API against the ActionsList listbox.
+ * Our NactWindow may implement it in order to personalize the
+ * behaviour of the listbox.
+ */
+
+#include <gtk/gtk.h>
+
+#include "nact-window.h"
+
+G_BEGIN_DECLS
+
+#define NACT_IPROFILES_LIST_TYPE							( nact_iprofiles_list_get_type())
+#define NACT_IPROFILES_LIST( object )					( G_TYPE_CHECK_INSTANCE_CAST( object, NACT_IPROFILES_LIST_TYPE, NactIProfilesList ))
+#define NACT_IS_IPROFILES_LIST( object )					( G_TYPE_CHECK_INSTANCE_TYPE( object, NACT_IPROFILES_LIST_TYPE ))
+#define NACT_IPROFILES_LIST_GET_INTERFACE( instance )	( G_TYPE_INSTANCE_GET_INTERFACE(( instance ), NACT_IPROFILES_LIST_TYPE, NactIProfilesListInterface ))
+
+typedef struct NactIProfilesList NactIProfilesList;
+
+typedef struct NactIProfilesListInterfacePrivate NactIProfilesListInterfacePrivate;
+
+typedef struct {
+	GTypeInterface                    parent;
+	NactIProfilesListInterfacePrivate *private;
+
+	/* api */
+	GSList * ( *get_profiles )         ( NactWindow *window );
+	void     ( *initial_load_widget )  ( NactWindow *window );
+	void     ( *runtime_init_widget )  ( NactWindow *window );
+	void     ( *fill_actions_list )    ( NactWindow *window );
+	void     ( *on_selection_changed ) ( GtkTreeSelection *selection, gpointer user_data );
+	gboolean ( *on_button_press_event )( GtkWidget *widget, GdkEventButton *event, gpointer data );
+	gboolean ( *on_key_pressed_event ) ( GtkWidget *widget, GdkEventKey *event, gpointer data );
+	gboolean ( *on_double_click )      ( GtkWidget *widget, GdkEventButton *event, gpointer data );
+	gboolean ( *on_enter_key_pressed ) ( GtkWidget *widget, GdkEventKey *event, gpointer data );
+}
+	NactIProfilesListInterface;
+
+GType    nact_iprofiles_list_get_type( void );
+
+void     nact_iprofiles_list_initial_load( NactWindow *window );
+void     nact_iprofiles_list_runtime_init( NactWindow *window );
+void     nact_iprofiles_list_fill( NactWindow *window );
+GObject *nact_iprofiles_list_get_selected_profile( NactWindow *window );
+void     nact_iprofiles_list_set_focus( NactWindow *window );
+
+void     nact_iprofiles_list_set_multiple_selection( NactWindow *window, gboolean multiple );
+void     nact_iprofiles_list_set_send_selection_changed_on_fill_list( NactWindow *window, gboolean send_message );
+void     nact_iprofiles_list_set_is_filling_list( NactWindow *window, gboolean is_filling );
+
+G_END_DECLS
+
+#endif /* __NACT_IPROFILES_LIST_H__ */
diff --git a/src/nact/nact-main-window.c b/src/nact/nact-main-window.c
index 545174d..d3cc00f 100644
--- a/src/nact/nact-main-window.c
+++ b/src/nact/nact-main-window.c
@@ -97,9 +97,9 @@ static void     on_import_button_clicked( GtkButton *button, gpointer user_data
 static void     on_export_button_clicked( GtkButton *button, gpointer user_data );
 static gboolean on_dialog_response( GtkDialog *dialog, gint response_id, BaseWindow *window );
 
+static GSList  *do_get_actions( NactWindow *window );
 static void     on_actions_changed( NAIPivotContainer *instance, gpointer user_data );
-static void     set_current_action( NactMainWindow *window, const NAAction *action );
-static void     do_set_current_action( NactWindow *window, const gchar *uuid, const gchar *label );
+static void     do_set_current_action( NactWindow *window, const NAAction *action );
 
 GType
 nact_main_window_get_type( void )
@@ -187,8 +187,7 @@ iactions_list_iface_init( NactIActionsListInterface *iface )
 	static const gchar *thisfn = "nact_main_window_iactions_list_iface_init";
 	g_debug( "%s: iface=%p", thisfn, iface );
 
-	iface->initial_load_widget = NULL;
-	iface->runtime_init_widget = NULL;
+	iface->get_actions = do_get_actions;
 	iface->on_selection_changed = on_actions_list_selection_changed;
 	iface->on_double_click = on_actions_list_double_click;
 	iface->on_enter_key_pressed = on_actions_list_enter_key_pressed;
@@ -343,7 +342,7 @@ on_actions_list_selection_changed( GtkTreeSelection *selection, gpointer user_da
 	gtk_widget_set_sensitive( duplicate_button, enabled );
 
 	NAAction *action = NA_ACTION( nact_iactions_list_get_selected_action( NACT_WINDOW( window )));
-	set_current_action( NACT_MAIN_WINDOW( window ), action );
+	do_set_current_action( NACT_WINDOW( window ), action );
 }
 
 static gboolean
@@ -523,7 +522,7 @@ on_duplicate_button_clicked( GtkButton *button, gpointer user_data )
 			g_free( msg );
 
 		} else {
-			set_current_action( NACT_MAIN_WINDOW( wndmain ), duplicate );
+			do_set_current_action( NACT_WINDOW( wndmain ), duplicate );
 		}
 
 		g_object_unref( duplicate );
@@ -583,39 +582,6 @@ on_import_button_clicked( GtkButton *button, gpointer user_data )
 	g_assert( NACT_IS_MAIN_WINDOW( user_data ));
 	NactWindow *wndmain = NACT_WINDOW( user_data );
 	nact_iactions_list_set_focus( wndmain );
-
-	/*g_assert( NACT_IS_MAIN_WINDOW( user_data ));
-	NactWindow *wndmain = NACT_WINDOW( user_data );
-
-	GtkWidget *dialog = gtk_file_chooser_dialog_new(
-			_( "Importing new actions" ),
-			NULL,
-			GTK_FILE_CHOOSER_ACTION_OPEN,
-			GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
-			GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
-			NULL
-			);
-
-	nact_iprefs_position_named_window( NACT_WINDOW( user_data ), GTK_WINDOW( dialog ), IPREFS_IMPORT_ACTIONS );
-	gchar *uri = nact_iprefs_get_import_folder_uri( NACT_WINDOW( user_data ));
-	gtk_file_chooser_set_current_folder_uri( GTK_FILE_CHOOSER( dialog ), uri );
-	g_free( uri );
-
-	if( gtk_dialog_run( GTK_DIALOG( dialog )) == GTK_RESPONSE_ACCEPT ){
-		gchar *filename = gtk_file_chooser_get_filename( GTK_FILE_CHOOSER( dialog ));
-		do_import_actions( NACT_MAIN_WINDOW( wndmain ), filename );
-	    g_free (filename);
-	  }
-
-	uri = gtk_file_chooser_get_current_folder_uri( GTK_FILE_CHOOSER( dialog ));
-	nact_iprefs_save_import_folder_uri( NACT_WINDOW( user_data ), uri );
-	g_free( uri );
-
-	nact_iprefs_save_named_window_position( NACT_WINDOW( user_data ), GTK_WINDOW( dialog ), IPREFS_IMPORT_ACTIONS );
-
-	gtk_widget_destroy( dialog );
-
-	nact_iactions_list_set_focus( wndmain );*/
 }
 
 /*
@@ -660,6 +626,14 @@ on_dialog_response( GtkDialog *dialog, gint response_id, BaseWindow *window )
 	return( FALSE );
 }
 
+static GSList *
+do_get_actions( NactWindow *window )
+{
+	NactApplication *application = NACT_APPLICATION( base_window_get_application( BASE_WINDOW( window )));
+	NAPivot *pivot = NA_PIVOT( nact_application_get_pivot( application ));
+	return( na_pivot_get_actions( pivot ));
+}
+
 static void
 on_actions_changed( NAIPivotContainer *instance, gpointer user_data )
 {
@@ -678,8 +652,10 @@ on_actions_changed( NAIPivotContainer *instance, gpointer user_data )
 }
 
 static void
-set_current_action( NactMainWindow *window, const NAAction *action )
+do_set_current_action( NactWindow *wnd, const NAAction *action )
 {
+	NactMainWindow *window = NACT_MAIN_WINDOW( wnd );
+
 	g_free( window->private->current_uuid );
 	window->private->current_uuid = NULL;
 
@@ -692,13 +668,3 @@ set_current_action( NactMainWindow *window, const NAAction *action )
 		window->private->current_label = na_action_get_label( action );
 	}
 }
-
-static void
-do_set_current_action( NactWindow *window, const gchar *uuid, const gchar *label )
-{
-	g_debug( "nact_main_window_do_set_current_action: window=%p, uuid=%s, label=%s", window, uuid, label );
-	g_free( NACT_MAIN_WINDOW( window )->private->current_uuid );
-	g_free( NACT_MAIN_WINDOW( window )->private->current_label );
-	NACT_MAIN_WINDOW( window )->private->current_uuid = g_strdup( uuid );
-	NACT_MAIN_WINDOW( window )->private->current_label = g_strdup( label );
-}
diff --git a/src/nact/nact-window.c b/src/nact/nact-window.c
index 83df734..9e54177 100644
--- a/src/nact/nact-window.c
+++ b/src/nact/nact-window.c
@@ -234,32 +234,16 @@ nact_window_get_pivot( NactWindow *window )
 }
 
 /**
- * Returns a pointer to the specified action.
- *
- * The returned pointer is owned by NAPivot, and should not be freed
- * nor unref by the caller.
- */
-GObject *
-nact_window_get_action( NactWindow *window, const gchar *uuid )
-{
-	NAPivot *pivot = NA_PIVOT( nact_window_get_pivot( window ));
-	g_return_val_if_fail( NA_IS_PIVOT( pivot ), NULL );
-
-	GObject *action = na_pivot_get_action( pivot, uuid );
-	return( action );
-}
-
-/**
  * Set the current action.
  *
  * This is called by one of the editors to advertize the main window
  * that the newly selected action has changed.
  */
 void
-nact_window_set_current_action( NactWindow *window, const gchar *uuid, const gchar *label )
+nact_window_set_current_action( NactWindow *window, const NAAction *action )
 {
 	if( NACT_WINDOW_GET_CLASS( window )->set_current_action ){
-		NACT_WINDOW_GET_CLASS( window )->set_current_action( window, uuid, label );
+		NACT_WINDOW_GET_CLASS( window )->set_current_action( window, action );
 	}
 }
 
@@ -273,6 +257,9 @@ nact_window_set_current_action( NactWindow *window, const gchar *uuid, const gch
 gboolean
 nact_window_save_action( NactWindow *window, const NAAction *action )
 {
+	static const gchar *thisfn = "nact_window_save_action";
+	g_debug( "%s: window=%p, action=%p", thisfn, window, action );
+
 	NAPivot *pivot = NA_PIVOT( nact_window_get_pivot( window ));
 	g_assert( NA_IS_PIVOT( pivot ));
 
@@ -322,19 +309,6 @@ nact_window_warn_action_modified( NactWindow *window, const NAAction *action )
 }
 
 /**
- * Returns a pointer to the list of actions.
- */
-GSList *
-nact_window_get_actions( NactWindow *window )
-{
-	NAPivot *pivot = NA_PIVOT( nact_window_get_pivot( window ));
-	g_return_val_if_fail( NA_IS_PIVOT( pivot ), NULL );
-
-	GSList *actions = na_pivot_get_actions( pivot );
-	return( actions );
-}
-
-/**
  * Records a connected signal, to be disconnected at NactWindow dispose.
  */
 void
diff --git a/src/nact/nact-window.h b/src/nact/nact-window.h
index 400368b..e2cb8e8 100644
--- a/src/nact/nact-window.h
+++ b/src/nact/nact-window.h
@@ -67,7 +67,7 @@ typedef struct {
 
 	/* api */
 	gchar *  ( *get_iprefs_window_id )( NactWindow *window );
-	void     ( *set_current_action )  ( NactWindow *window, const gchar *uuid, const gchar *label );
+	void     ( *set_current_action )  ( NactWindow *window, const NAAction *action );
 }
 	NactWindowClass;
 
@@ -75,14 +75,11 @@ GType    nact_window_get_type( void );
 
 GObject *nact_window_get_pivot( NactWindow *window );
 
-GObject *nact_window_get_action( NactWindow *window, const gchar *uuid );
-void     nact_window_set_current_action( NactWindow *window, const gchar *uuid, const gchar *label );
+void     nact_window_set_current_action( NactWindow *window, const NAAction *action );
 gboolean nact_window_save_action( NactWindow *window, const NAAction *action );
 
 gboolean nact_window_warn_action_modified( NactWindow *window, const NAAction *action );
 
-GSList  *nact_window_get_actions( NactWindow *window );
-
 void     nact_window_signal_connect( NactWindow *window, GObject *instance, const gchar *signal, GCallback fn );
 void     nact_window_signal_connect_by_name( NactWindow *window, const gchar *name, const gchar *signal, GCallback fn );
 
diff --git a/src/nact/nautilus-actions-config.ui b/src/nact/nautilus-actions-config.ui
index e09c352..cba0e1b 100644
--- a/src/nact/nautilus-actions-config.ui
+++ b/src/nact/nautilus-actions-config.ui
@@ -216,15 +216,13 @@
                 <child>
                   <object class="GtkVBox" id="vbox1">
                     <property name="visible">True</property>
-                    <property name="border_width">6</property>
                     <property name="orientation">vertical</property>
-                    <property name="spacing">4</property>
                     <child>
                       <object class="GtkLabel" id="label159">
                         <property name="visible">True</property>
                         <property name="xalign">0</property>
-                        <property name="ypad">4</property>
-                        <property name="label" translatable="yes">&lt;b&gt;Nautilus Menu Item&lt;/b&gt;</property>
+                        <property name="label" translatable="yes">&lt;b&gt;Nautilus Menu Item&lt;/b&gt;
+</property>
                         <property name="use_markup">True</property>
                       </object>
                       <packing>
@@ -1120,7 +1118,8 @@ file(s)/folder(s)</property>
                   <object class="GtkLabel" id="label159">
                     <property name="visible">True</property>
                     <property name="xalign">0</property>
-                    <property name="label" translatable="yes">&lt;b&gt;Nautilus Menu Item&lt;/b&gt;</property>
+                    <property name="label" translatable="yes">&lt;b&gt;Nautilus Menu Item&lt;/b&gt;
+</property>
                     <property name="use_markup">True</property>
                   </object>
                   <packing>
@@ -1132,7 +1131,6 @@ file(s)/folder(s)</property>
                 <child>
                   <object class="GtkTable" id="table3">
                     <property name="visible">True</property>
-                    <property name="border_width">10</property>
                     <property name="n_rows">3</property>
                     <property name="n_columns">2</property>
                     <property name="column_spacing">6</property>
@@ -1152,12 +1150,72 @@ file(s)/folder(s)</property>
                       </packing>
                     </child>
                     <child>
+                      <object class="GtkLabel" id="MenuIconLabel">
+                        <property name="visible">True</property>
+                        <property name="xalign">1</property>
+                        <property name="label" translatable="yes">Icon :</property>
+                      </object>
+                      <packing>
+                        <property name="top_attach">2</property>
+                        <property name="bottom_attach">3</property>
+                        <property name="x_options"></property>
+                        <property name="y_options"></property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkLabel" id="MenuTooltipLabel">
+                        <property name="visible">True</property>
+                        <property name="xalign">1</property>
+                        <property name="label" translatable="yes">Tooltip :</property>
+                      </object>
+                      <packing>
+                        <property name="top_attach">1</property>
+                        <property name="bottom_attach">2</property>
+                        <property name="x_options"></property>
+                        <property name="y_options"></property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkLabel" id="MenuLabelLabel">
+                        <property name="visible">True</property>
+                        <property name="xalign">1</property>
+                        <property name="label" translatable="yes">Label :</property>
+                      </object>
+                      <packing>
+                        <property name="x_options"></property>
+                        <property name="y_options"></property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkEntry" id="MenuLabelEntry">
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="invisible_char">&#x25CF;</property>
+                      </object>
+                      <packing>
+                        <property name="left_attach">1</property>
+                        <property name="right_attach">2</property>
+                        <property name="y_options"></property>
+                      </packing>
+                    </child>
+                    <child>
                       <object class="GtkHBox" id="hbox63">
                         <property name="visible">True</property>
                         <property name="spacing">6</property>
                         <child>
-                          <object class="GtkImage" id="IconImage">
-                            <property name="icon-size">1</property>
+                          <object class="GtkAspectFrame" id="IconFrame">
+                            <property name="width_request">24</property>
+                            <property name="height_request">24</property>
+                            <property name="visible">True</property>
+                            <property name="label_xalign">0</property>
+                            <property name="shadow_type">in</property>
+                            <property name="obey_child">False</property>
+                            <child>
+                              <object class="GtkImage" id="IconImage">
+                                <property name="stock">gnome-stock-blank</property>
+                                <property name="icon-size">4</property>
+                              </object>
+                            </child>
                           </object>
                           <packing>
                             <property name="expand">False</property>
@@ -1181,7 +1239,7 @@ file(s)/folder(s)</property>
                         </child>
                         <child>
                           <object class="GtkButton" id="IconBrowseButton">
-                            <property name="label" translatable="yes">_Browse</property>
+                            <property name="label" translatable="yes">_Browse...</property>
                             <property name="visible">True</property>
                             <property name="can_focus">True</property>
                             <property name="receives_default">True</property>
@@ -1203,58 +1261,10 @@ file(s)/folder(s)</property>
                         <property name="y_options">GTK_FILL</property>
                       </packing>
                     </child>
-                    <child>
-                      <object class="GtkLabel" id="LabelAlign3">
-                        <property name="visible">True</property>
-                        <property name="xalign">0</property>
-                        <property name="label" translatable="yes">Icon:</property>
-                      </object>
-                      <packing>
-                        <property name="top_attach">2</property>
-                        <property name="bottom_attach">3</property>
-                        <property name="x_options">GTK_FILL</property>
-                        <property name="y_options">GTK_FILL</property>
-                      </packing>
-                    </child>
-                    <child>
-                      <object class="GtkLabel" id="LabelAlign2">
-                        <property name="visible">True</property>
-                        <property name="xalign">0</property>
-                        <property name="label" translatable="yes">Tooltip:</property>
-                      </object>
-                      <packing>
-                        <property name="top_attach">1</property>
-                        <property name="bottom_attach">2</property>
-                        <property name="x_options">GTK_FILL</property>
-                        <property name="y_options">GTK_FILL</property>
-                      </packing>
-                    </child>
-                    <child>
-                      <object class="GtkLabel" id="LabelAlign1">
-                        <property name="visible">True</property>
-                        <property name="xalign">0</property>
-                        <property name="label" translatable="yes">Label:</property>
-                      </object>
-                      <packing>
-                        <property name="x_options">GTK_FILL</property>
-                        <property name="y_options">GTK_FILL</property>
-                      </packing>
-                    </child>
-                    <child>
-                      <object class="GtkEntry" id="MenuLabelEntry">
-                        <property name="visible">True</property>
-                        <property name="can_focus">True</property>
-                        <property name="invisible_char">&#x25CF;</property>
-                      </object>
-                      <packing>
-                        <property name="left_attach">1</property>
-                        <property name="right_attach">2</property>
-                        <property name="y_options"></property>
-                      </packing>
-                    </child>
                   </object>
                   <packing>
                     <property name="expand">False</property>
+                    <property name="fill">False</property>
                     <property name="position">1</property>
                   </packing>
                 </child>
@@ -1296,6 +1306,7 @@ file(s)/folder(s)</property>
                           <object class="GtkTreeView" id="ProfilesList">
                             <property name="visible">True</property>
                             <property name="can_focus">True</property>
+                            <property name="events">GDK_BUTTON_PRESS_MASK | GDK_KEY_PRESS_MASK | GDK_STRUCTURE_MASK</property>
                             <property name="headers_visible">False</property>
                             <property name="rules_hint">True</property>
                           </object>
@@ -1417,7 +1428,7 @@ file(s)/folder(s)</property>
             <property name="visible">True</property>
             <property name="layout_style">end</property>
             <child>
-              <object class="GtkButton" id="cancelbutton3">
+              <object class="GtkButton" id="CancelButton">
                 <property name="label">gtk-cancel</property>
                 <property name="visible">True</property>
                 <property name="can_focus">True</property>
@@ -1432,8 +1443,8 @@ file(s)/folder(s)</property>
               </packing>
             </child>
             <child>
-              <object class="GtkButton" id="okbutton4">
-                <property name="label">gtk-ok</property>
+              <object class="GtkButton" id="SaveButton">
+                <property name="label">gtk-save</property>
                 <property name="visible">True</property>
                 <property name="can_focus">True</property>
                 <property name="can_default">True</property>
@@ -1456,8 +1467,8 @@ file(s)/folder(s)</property>
       </object>
     </child>
     <action-widgets>
-      <action-widget response="-6">cancelbutton3</action-widget>
-      <action-widget response="-5">okbutton4</action-widget>
+      <action-widget response="-6">CancelButton</action-widget>
+      <action-widget response="-5">SaveButton</action-widget>
     </action-widgets>
   </object>
   <object class="GtkAssistant" id="ExportAssistant">
@@ -1523,10 +1534,10 @@ to extend a selection.</property>
           <object class="GtkFileChooserWidget" id="ExportFolderChooser">
             <property name="visible">True</property>
             <property name="orientation">vertical</property>
+            <property name="action">select-folder</property>
             <property name="local_only">False</property>
-            <property name="preview_widget_active">False</property>
             <property name="use_preview_label">False</property>
-            <property name="action">select-folder</property>
+            <property name="preview_widget_active">False</property>
           </object>
           <packing>
             <property name="position">0</property>
@@ -1576,8 +1587,8 @@ to extend a selection.</property>
         <property name="visible">True</property>
         <property name="orientation">vertical</property>
         <property name="local_only">False</property>
-        <property name="preview_widget_active">False</property>
         <property name="use_preview_label">False</property>
+        <property name="preview_widget_active">False</property>
         <property name="select_multiple">True</property>
       </object>
     </child>
@@ -1620,11 +1631,11 @@ to extend a selection.</property>
   </object>
   <object class="GtkSizeGroup" id="IProfileConditionsLabelSizeGroup">
     <widgets>
-      <widget name="ActionParametersLabel"/>
-      <widget name="ActionPathLabel"/>
-      <widget name="MenuIconLabel"/>
-      <widget name="MenuTooltipLabel"/>
       <widget name="MenuLabelLabel"/>
+      <widget name="MenuTooltipLabel"/>
+      <widget name="MenuIconLabel"/>
+      <widget name="ActionPathLabel"/>
+      <widget name="ActionParametersLabel"/>
     </widgets>
   </object>
 </interface>



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