[nautilus-actions] Reset the selection to the most accurate action



commit e4dbdc936841c41eebf9f9e4d6cfcd4e7de77a37
Author: Pierre Wieser <pwieser trychlos org>
Date:   Thu Jul 2 16:35:22 2009 +0200

    Reset the selection to the most accurate action

 ChangeLog                                |   14 ++++-
 src/nact/nact-action-conditions-editor.c |   22 ++++++-
 src/nact/nact-iactions-list.c            |   50 +++++++++++++++
 src/nact/nact-iactions-list.h            |    1 +
 src/nact/nact-main-window.c              |   87 +++++++++++++++++++--------
 src/nact/nact-window.c                   |   96 +++++++++++++++++-------------
 src/nact/nact-window.h                   |    2 +
 7 files changed, 199 insertions(+), 73 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 4cd4adc..c50e271 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -5,10 +5,13 @@
 
 	* src/nact/nact-action-conditions-editor.c
 	(on_initial_load_dialog): Make labels and buttons the same size.
-
-	* src/nact/nact-action-conditions-editor.c
 	(on_all_widgets_showed): Call
 	nact_iprofile_conditions_all_widgets_showed function.
+	(on_dialog_response): Advertize parent window of a new action.
+
+	* src/nact/nact-iactions-list.c:
+	* src/nact/nact-iactions-list.h
+	(nact_iactions_list_set_selection): New function.
 
 	* src/nact/nact-imenu-item.c:
 	* src/nact/nact-imenu-item.h (nact_imenu_item_size_labels,
@@ -25,6 +28,13 @@
 	(nact_iprofile_conditions_size_labels,
 	nact_iprofile_conditions_size_buttons): New functions.
 
+	* src/nact/nact-main-window.c:
+	Do not trigger on_selection_changed when filling the Actions list.
+
+	* src/nact/nact-window.c:
+	* src/nact/nact-window.h (set_current_action):
+	New virtual function.
+
 	* src/nact/nautilus-actions-config.ui:
 	Add tooltips to AddAction and EditAction buttons.
 	Encapsulates the IconImage into a IconFrame.
diff --git a/src/nact/nact-action-conditions-editor.c b/src/nact/nact-action-conditions-editor.c
index 4695a62..c2b9245 100644
--- a/src/nact/nact-action-conditions-editor.c
+++ b/src/nact/nact-action-conditions-editor.c
@@ -51,10 +51,11 @@ struct NactActionConditionsEditorClassPrivate {
 /* private instance data
  */
 struct NactActionConditionsEditorPrivate {
-	gboolean  dispose_has_run;
-	NAAction *original;
-	NAAction *edited;
-	gboolean  is_new;
+	gboolean    dispose_has_run;
+	NactWindow *parent;
+	NAAction   *original;
+	NAAction   *edited;
+	gboolean    is_new;
 };
 
 static GObjectClass *st_parent_class = NULL;
@@ -83,6 +84,7 @@ static gboolean on_dialog_response( GtkDialog *dialog, gint code, BaseWindow *wi
 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 )
@@ -277,6 +279,7 @@ nact_action_conditions_editor_run_editor( NactWindow *parent, gpointer user_data
 	g_assert( NACT_IS_APPLICATION( application ));
 
 	NactActionConditionsEditor *dialog = action_conditions_editor_new( application );
+	dialog->private->parent = parent;
 
 	g_assert( NA_IS_ACTION( user_data ) || !user_data );
 	NAAction *action = NA_ACTION( user_data );
@@ -487,6 +490,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 ));
 				}
 			}
 			break;
@@ -514,3 +518,13 @@ 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-iactions-list.c b/src/nact/nact-iactions-list.c
index 4feb530..dece094 100644
--- a/src/nact/nact-iactions-list.c
+++ b/src/nact/nact-iactions-list.c
@@ -181,6 +181,56 @@ nact_iactions_list_fill( NactWindow *window )
 }
 
 /**
+ * Set the selection to the named action.
+ * If not found, we select the first following, else the previous one.
+ */
+void
+nact_iactions_list_set_selection( NactWindow *window, const gchar *uuid, const gchar *label )
+{
+	static const gchar *thisfn = "nact_iactions_list_set_selection";
+	g_debug( "%s: window=%p, uuid=%s, label=%s", thisfn, window, uuid, label );
+
+	GtkWidget *list = get_actions_list_widget( window );
+	GtkTreeSelection *selection = gtk_tree_view_get_selection( GTK_TREE_VIEW( list ));
+	GtkTreeModel *model = gtk_tree_view_get_model( GTK_TREE_VIEW( list ));
+	GtkTreeIter iter, previous;
+
+	gtk_tree_selection_unselect_all( selection );
+
+	gboolean iterok = gtk_tree_model_get_iter_first( model, &iter );
+	gboolean found = FALSE;
+	gchar *iter_uuid, *iter_label;
+	gint count = 0;
+
+	while( iterok && !found ){
+		count += 1;
+		gtk_tree_model_get(
+				model,
+				&iter,
+				IACTIONS_LIST_UUID_COLUMN, &iter_uuid, IACTIONS_LIST_LABEL_COLUMN, &iter_label,
+				-1 );
+
+		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 ){
+			gtk_tree_selection_select_iter( selection, &iter );
+			found = TRUE;
+
+		} else {
+			previous = iter;
+		}
+
+		g_free( iter_uuid );
+		g_free( iter_label );
+		iterok = gtk_tree_model_iter_next( model, &iter );
+	}
+
+	if( !found && count ){
+		gtk_tree_selection_select_iter( selection, &previous );
+	}
+}
+
+/**
  * Reset the focus on the ActionsList listbox.
  */
 void
diff --git a/src/nact/nact-iactions-list.h b/src/nact/nact-iactions-list.h
index 06dd60a..caf3269 100644
--- a/src/nact/nact-iactions-list.h
+++ b/src/nact/nact-iactions-list.h
@@ -74,6 +74,7 @@ void     nact_iactions_list_initial_load( NactWindow *window );
 void     nact_iactions_list_runtime_init( NactWindow *window );
 void     nact_iactions_list_fill( NactWindow *window );
 GObject *nact_iactions_list_get_selected_action( NactWindow *window );
+void     nact_iactions_list_set_selection( NactWindow *window, const gchar *uuid, const gchar *label );
 void     nact_iactions_list_set_focus( NactWindow *window );
 
 G_END_DECLS
diff --git a/src/nact/nact-main-window.c b/src/nact/nact-main-window.c
index a3902d6..c8e6fb5 100644
--- a/src/nact/nact-main-window.c
+++ b/src/nact/nact-main-window.c
@@ -58,7 +58,10 @@ struct NactMainWindowClassPrivate {
 /* private instance data
  */
 struct NactMainWindowPrivate {
-	gboolean dispose_has_run;
+	gboolean  dispose_has_run;
+	gboolean  selection_changed_authorized;
+	gchar    *current_uuid;
+	gchar    *current_label;
 };
 
 static GObjectClass *st_parent_class = NULL;
@@ -89,6 +92,9 @@ static gboolean on_dialog_response( GtkDialog *dialog, gint response_id, BaseWin
 
 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 gint     count_actions( BaseWindow *window );*/
 
 GType
@@ -168,6 +174,7 @@ class_init( NactMainWindowClass *klass )
 
 	NactWindowClass *nact_class = NACT_WINDOW_CLASS( klass );
 	nact_class->get_iprefs_window_id = get_iprefs_window_id;
+	nact_class->set_current_action = do_set_current_action;
 }
 
 static void
@@ -218,6 +225,9 @@ instance_dispose( GObject *window )
 
 		self->private->dispose_has_run = TRUE;
 
+		g_free( self->private->current_uuid );
+		g_free( self->private->current_label );
+
 		/* chain up to the parent class */
 		G_OBJECT_CLASS( st_parent_class )->dispose( window );
 	}
@@ -302,6 +312,8 @@ on_runtime_init_toplevel( BaseWindow *window )
 	base_window_connect( window, "DuplicateActionButton", "clicked", G_CALLBACK( on_duplicate_button_clicked ));
 	base_window_connect( window, "DeleteActionButton", "clicked", G_CALLBACK( on_delete_button_clicked ));
 	base_window_connect( window, "ImExportButton", "clicked", G_CALLBACK( on_import_export_button_clicked ));
+
+	NACT_MAIN_WINDOW( window )->private->selection_changed_authorized = TRUE;
 }
 
 static void
@@ -310,18 +322,24 @@ on_actions_list_selection_changed( GtkTreeSelection *selection, gpointer user_da
 	/*static const gchar *thisfn = "nact_main_window_on_actions_list_selection_changed";
 	g_debug( "%s: selection=%p, user_data=%p", thisfn, selection, user_data );*/
 
-	g_assert( BASE_IS_WINDOW( user_data ));
-	BaseWindow *window = BASE_WINDOW( user_data );
+	g_assert( NACT_IS_MAIN_WINDOW( user_data ));
+	if( NACT_MAIN_WINDOW( user_data )->private->selection_changed_authorized ){
+
+		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" );
+		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 );
+		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 );
+		gtk_widget_set_sensitive( edit_button, enabled );
+		gtk_widget_set_sensitive( delete_button, enabled );
+		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 );
+	}
 }
 
 static gboolean
@@ -420,8 +438,6 @@ on_add_button_clicked( GtkButton *button, gpointer user_data )
 
 	nact_action_conditions_editor_run_editor( wndmain, NULL );
 
-	/* TODO: set the selection to the newly created action
-	 * or restore the previous selection */
 	nact_iactions_list_set_focus( wndmain );
 }
 
@@ -461,8 +477,6 @@ on_edit_button_clicked( GtkButton *button, gpointer user_data )
 		g_assert_not_reached();
 	}
 
-	/* TODO: reset the selection to the edited action
-	 * set focus to actions list */
 	nact_iactions_list_set_focus( wndmain );
 }
 
@@ -493,15 +507,18 @@ on_duplicate_button_clicked( GtkButton *button, gpointer user_data )
 			base_window_error_dlg( BASE_WINDOW( wndmain ), GTK_MESSAGE_ERROR, first, msg );
 			g_free( first );
 			g_free( msg );
+
+		} else {
+			set_current_action( NACT_MAIN_WINDOW( wndmain ), duplicate );
 		}
 
+		g_object_unref( duplicate );
 		g_free( label );
 
 	} else {
 		g_assert_not_reached();
 	}
 
-	/* TODO: set the selection to the newly created action */
 	nact_iactions_list_set_focus( wndmain );
 }
 
@@ -537,8 +554,7 @@ on_delete_button_clicked( GtkButton *button, gpointer user_data )
 	} else {
 		g_assert_not_reached();
 	}
-	/* TODO: set the selection to the previous action if any
-	 * or to the next one */
+
 	nact_iactions_list_set_focus( wndmain );
 }
 
@@ -577,17 +593,8 @@ on_dialog_response( GtkDialog *dialog, gint response_id, BaseWindow *window )
 			/* Free any profile in the clipboard */
 			/*nautilus_actions_config_action_profile_free (g_object_steal_data (G_OBJECT (paste_button), "profile"));*/
 
-			/* FIXME : update pref settings
-			nact_prefs_set_main_dialog_size (GTK_WINDOW (dialog));
-			nact_prefs_set_main_dialog_position (GTK_WINDOW (dialog));
-			nact_prefs_save_preferences ();
-			 */
-
 			g_object_unref( window );
 			return( TRUE );
-			/*gtk_widget_destroy (GTK_WIDGET (dialog));
-			nact_destroy_glade_objects ();
-			gtk_main_quit ();*/
 			break;
 	}
 
@@ -603,9 +610,37 @@ on_actions_changed( NAIPivotContainer *instance, gpointer user_data )
 	g_assert( NACT_IS_MAIN_WINDOW( instance ));
 	NactMainWindow *self = NACT_MAIN_WINDOW( instance );
 
+	self->private->selection_changed_authorized = FALSE;
+
 	if( !self->private->dispose_has_run ){
 		nact_iactions_list_fill( NACT_WINDOW( instance ));
 	}
+
+	self->private->selection_changed_authorized = TRUE;
+	nact_iactions_list_set_selection(
+			NACT_WINDOW( self ), self->private->current_uuid, self->private->current_label );
+}
+
+static void
+set_current_action( NactMainWindow *window, const NAAction *action )
+{
+	g_free( window->private->current_uuid );
+	g_free( window->private->current_label );
+	if( action ){
+		g_assert( NA_IS_ACTION( action ));
+		window->private->current_uuid = na_action_get_uuid( 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 );
 }
 
 /*static gint
diff --git a/src/nact/nact-window.c b/src/nact/nact-window.c
index bd948e4..3b61103 100644
--- a/src/nact/nact-window.c
+++ b/src/nact/nact-window.c
@@ -214,47 +214,6 @@ instance_finalize( GObject *window )
 	}
 }
 
-static gchar *
-v_get_iprefs_window_id( NactWindow *window )
-{
-	g_assert( NACT_IS_IPREFS( window ));
-
-	if( NACT_WINDOW_GET_CLASS( window )->get_iprefs_window_id ){
-		return( NACT_WINDOW_GET_CLASS( window )->get_iprefs_window_id( window ));
-	}
-
-	return( NULL );
-}
-
-static void
-on_runtime_init_toplevel( BaseWindow *window )
-{
-	static const gchar *thisfn = "nact_window_on_runtime_init_toplevel";
-
-	/* 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( window );
-	}
-
-	g_debug( "%s: window=%p", thisfn, window );
-	g_assert( NACT_IS_WINDOW( window ));
-
-	nact_iprefs_position_window( NACT_WINDOW( window ));
-}
-
-static void
-on_all_widgets_showed( BaseWindow *dialog )
-{
-	static const gchar *thisfn = "nact_window_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 );
-}
-
 /**
  * Returns a pointer to the list of actions.
  */
@@ -285,6 +244,20 @@ nact_window_get_action( NactWindow *window, const gchar *uuid )
 }
 
 /**
+ * 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 )
+{
+	if( NACT_WINDOW_GET_CLASS( window )->set_current_action ){
+		NACT_WINDOW_GET_CLASS( window )->set_current_action( window, uuid, label );
+	}
+}
+
+/**
  * Saves a modified action to the I/O storage subsystem.
  *
  * @window: this NactWindow object.
@@ -372,3 +345,44 @@ nact_window_signal_connect( NactWindow *window, GObject *instance, const gchar *
 
 	/*g_debug( "%s: connecting signal handler %p:%lu", thisfn, instance, handler_id );*/
 }
+
+static gchar *
+v_get_iprefs_window_id( NactWindow *window )
+{
+	g_assert( NACT_IS_IPREFS( window ));
+
+	if( NACT_WINDOW_GET_CLASS( window )->get_iprefs_window_id ){
+		return( NACT_WINDOW_GET_CLASS( window )->get_iprefs_window_id( window ));
+	}
+
+	return( NULL );
+}
+
+static void
+on_runtime_init_toplevel( BaseWindow *window )
+{
+	static const gchar *thisfn = "nact_window_on_runtime_init_toplevel";
+
+	/* 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( window );
+	}
+
+	g_debug( "%s: window=%p", thisfn, window );
+	g_assert( NACT_IS_WINDOW( window ));
+
+	nact_iprefs_position_window( NACT_WINDOW( window ));
+}
+
+static void
+on_all_widgets_showed( BaseWindow *dialog )
+{
+	static const gchar *thisfn = "nact_window_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 );
+}
diff --git a/src/nact/nact-window.h b/src/nact/nact-window.h
index 705bb63..315f727 100644
--- a/src/nact/nact-window.h
+++ b/src/nact/nact-window.h
@@ -67,6 +67,7 @@ typedef struct {
 
 	/* api */
 	gchar * ( *get_iprefs_window_id )( NactWindow *window );
+	void    ( *set_current_action )  ( NactWindow *window, const gchar *uuid, const gchar *label );
 }
 	NactWindowClass;
 
@@ -75,6 +76,7 @@ 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 );
 gboolean nact_window_save_action( NactWindow *window, const NAAction *action );
 
 gboolean nact_window_warn_action_modified( NactWindow *window, const NAAction *action );



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