[nautilus-actions: 7/45] Window title and menu are updated depending on the currently selected action



commit 4e6168afff254514e9a611301aacc6e7caf77a98
Author: Pierre Wieser <pwieser trychlos org>
Date:   Sat Jul 18 11:46:52 2009 +0200

    Window title and menu are updated depending on the currently selected action

 ChangeLog                     |   23 ++++++
 src/common/na-action.c        |    2 +-
 src/common/na-action.h        |    2 +-
 src/nact/base-application.c   |    4 +-
 src/nact/nact-iaction-tab.c   |    4 +-
 src/nact/nact-iactions-list.c |   16 ++++-
 src/nact/nact-iactions-list.h |    3 +-
 src/nact/nact-main-window.c   |  156 +++++++++++++++++++++++++++++-----------
 src/nact/nact-window.c        |   30 ++++++++
 src/nact/nact-window.h        |    4 +
 10 files changed, 193 insertions(+), 51 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 1383b2d..3f4aa40 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,26 @@
+2009-07-18 Pierre Wieser <pwieser trychlos org>
+
+	* src/common/na-action.c:
+	* src/common/na-action.c (na_action_are_equal):
+	Function takes const arguments.
+
+	* src/nact/base-application.c:
+	* src/nact/nact-iaction-tab.c:
+	Disable debug message.
+
+	* src/nact/nact-iactions-list.c:
+	* src/nact/nact-iactions-list.h (set_sorted_actions):
+	New virtual function: advertise the implementer of the interface
+	of the new address of the sorted list.
+
+	* src/nact/nact-main-window.c:
+	Setup display of the window title and of the menu depending of
+	the currently selected action and its status.
+
+	* src/nact/nact-window.c:
+	* src/nact/nact-window.c (nact_window_warn_count_modified):
+	New function.
+
 2009-07-16 Pierre Wieser <pwieser trychlos org>
 
 	* configure.ac:
diff --git a/src/common/na-action.c b/src/common/na-action.c
index 51a289e..ff8df22 100644
--- a/src/common/na-action.c
+++ b/src/common/na-action.c
@@ -727,7 +727,7 @@ na_action_set_icon( NAAction *action, const gchar *icon )
  * @second: second action to be compared to @first.
  */
 gboolean
-na_action_are_equal( NAAction *first, NAAction *second )
+na_action_are_equal( const NAAction *first, const NAAction *second )
 {
 	gboolean equal =
 		( g_utf8_collate( first->private->label, second->private->label ) == 0 ) &&
diff --git a/src/common/na-action.h b/src/common/na-action.h
index 4c6c6f3..3a6a6fd 100644
--- a/src/common/na-action.h
+++ b/src/common/na-action.h
@@ -106,7 +106,7 @@ void      na_action_set_label( NAAction *action, const gchar *label );
 void      na_action_set_tooltip( NAAction *action, const gchar *tooltip );
 void      na_action_set_icon( NAAction *action, const gchar *icon_name );
 
-gboolean  na_action_are_equal( NAAction *first, NAAction *second );
+gboolean  na_action_are_equal( const NAAction *first, const NAAction *second );
 
 gchar    *na_action_get_new_profile_name( const NAAction *action );
 NAObject *na_action_get_profile( const NAAction *action, const gchar *name );
diff --git a/src/nact/base-application.c b/src/nact/base-application.c
index f602b67..6008e90 100644
--- a/src/nact/base-application.c
+++ b/src/nact/base-application.c
@@ -466,8 +466,8 @@ base_application_run( BaseApplication *application )
 gchar *
 base_application_get_name( BaseApplication *application )
 {
-	static const gchar *thisfn = "base_application_get_name";
-	g_debug( "%s: icon=%p", thisfn, application );
+	/*static const gchar *thisfn = "base_application_get_name";
+	g_debug( "%s: application=%p", thisfn, application );*/
 
 	g_assert( BASE_IS_APPLICATION( application ));
 
diff --git a/src/nact/nact-iaction-tab.c b/src/nact/nact-iaction-tab.c
index 70590fb..336b6c2 100644
--- a/src/nact/nact-iaction-tab.c
+++ b/src/nact/nact-iaction-tab.c
@@ -188,8 +188,8 @@ nact_iaction_tab_dispose( NactWindow *dialog )
 void
 nact_iaction_tab_set_action( NactWindow *dialog, const NAAction *action )
 {
-	static const gchar *thisfn = "nact_iaction_tab_set_action";
-	g_debug( "%s: dialog=%p, action=%p", thisfn, dialog, action );
+	/*static const gchar *thisfn = "nact_iaction_tab_set_action";
+	g_debug( "%s: dialog=%p, action=%p", thisfn, dialog, action );*/
 
 	GtkWidget *label_widget = base_window_get_widget( BASE_WINDOW( dialog ), "ActionLabelEntry" );
 	gchar *label = na_action_get_label( action );
diff --git a/src/nact/nact-iactions-list.c b/src/nact/nact-iactions-list.c
index 33b40a6..de7ffd0 100644
--- a/src/nact/nact-iactions-list.c
+++ b/src/nact/nact-iactions-list.c
@@ -64,6 +64,7 @@ static void       interface_base_init( NactIActionsListInterface *klass );
 static void       interface_base_finalize( NactIActionsListInterface *klass );
 
 static GSList    *v_get_actions( NactWindow *window );
+static void       v_set_sorted_actions( NactWindow *window, GSList *actions );
 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 );
@@ -235,6 +236,7 @@ nact_iactions_list_fill( NactWindow *window )
 
 	GSList *actions = v_get_actions( window );
 	actions = g_slist_sort( actions, ( GCompareFunc ) sort_actions_by_label );
+	v_set_sorted_actions( window, actions );
 
 	GSList *ia;
 	/*g_debug( "%s: actions has %d elements", thisfn, g_slist_length( actions ));*/
@@ -278,6 +280,7 @@ nact_iactions_list_fill( NactWindow *window )
 				    IACTIONS_LIST_LABEL_COLUMN, label,
 				    IACTIONS_LIST_ACTION_COLUMN, action,
 				    -1);
+		g_debug( "%s: action=%p", thisfn, action );
 
 		g_free( iconname );
 		g_free( label );
@@ -400,7 +403,7 @@ nact_iactions_list_get_selected_actions( NactWindow *window )
 
 
 void
-nact_iactions_list_set_modified( NactWindow *window, gboolean is_modified )
+nact_iactions_list_set_modified( NactWindow *window, gboolean is_modified, gboolean can_save )
 {
 }
 
@@ -453,6 +456,17 @@ v_get_actions( NactWindow *window )
 }
 
 static void
+v_set_sorted_actions( NactWindow *window, GSList *actions )
+{
+	g_assert( NACT_IS_IACTIONS_LIST( window ));
+	NactIActionsList *instance = NACT_IACTIONS_LIST( window );
+
+	if( NACT_IACTIONS_LIST_GET_INTERFACE( instance )->set_sorted_actions ){
+		NACT_IACTIONS_LIST_GET_INTERFACE( instance )->set_sorted_actions( window, actions );
+	}
+}
+
+static void
 v_on_selection_changed( GtkTreeSelection *selection, gpointer user_data )
 {
 	g_assert( NACT_IS_IACTIONS_LIST( user_data ));
diff --git a/src/nact/nact-iactions-list.h b/src/nact/nact-iactions-list.h
index 06366a5..35925e6 100644
--- a/src/nact/nact-iactions-list.h
+++ b/src/nact/nact-iactions-list.h
@@ -60,6 +60,7 @@ typedef struct {
 
 	/* api */
 	GSList * ( *get_actions )          ( NactWindow *window );
+	void     ( *set_sorted_actions )   ( NactWindow *window, GSList *actions );
 	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 );
@@ -77,7 +78,7 @@ NAAction *nact_iactions_list_get_selected_action( NactWindow *window );
 GSList  * nact_iactions_list_get_selected_actions( NactWindow *window );
 void      nact_iactions_list_set_selection( NactWindow *window, const gchar *uuid, const gchar *label );
 void      nact_iactions_list_set_focus( NactWindow *window );
-void      nact_iactions_list_set_modified( NactWindow *window, gboolean is_modified );
+void      nact_iactions_list_set_modified( NactWindow *window, gboolean is_modified, gboolean can_save );
 
 void      nact_iactions_list_set_multiple_selection( NactWindow *window, gboolean multiple );
 void      nact_iactions_list_set_send_selection_changed_on_fill_list( NactWindow *window, gboolean send_message );
diff --git a/src/nact/nact-main-window.c b/src/nact/nact-main-window.c
index 0c3755d..83ba739 100644
--- a/src/nact/nact-main-window.c
+++ b/src/nact/nact-main-window.c
@@ -64,6 +64,7 @@ struct NactMainWindowPrivate {
 	guint         status_context;
 	GtkWidget    *save_item;
 	GSList       *actions;
+	NAAction     *edited;
 	/*gchar        *current_uuid;
 	gchar        *current_label;*/
 };
@@ -86,22 +87,25 @@ static void      instance_finalize( GObject *application );
 static gchar    *get_iprefs_window_id( NactWindow *window );
 static gchar    *get_toplevel_name( BaseWindow *window );
 static GSList   *get_actions( NactWindow *window );
+static void      set_sorted_actions( NactWindow *window, GSList *actions );
 
 static void      on_initial_load_toplevel( BaseWindow *window );
 static void      create_file_menu( BaseWindow *window, GtkMenuBar *menubar );
 static void      create_tools_menu( BaseWindow *window, GtkMenuBar *menubar );
 static void      create_help_menu( BaseWindow *window, GtkMenuBar *menubar );
 static void      on_runtime_init_toplevel( BaseWindow *window );
-static void      setup_dialog_title( NactWindow *window, gboolean is_modified );
-static void      setup_dialog_menu( NactWindow *window, gboolean can_save );
+static void      setup_dialog_title( NactMainWindow *window );
+static void      setup_dialog_menu( NactMainWindow *window );
 
 static void      on_actions_list_selection_changed( GtkTreeSelection *selection, gpointer user_data );
 static gboolean  on_actions_list_double_click( GtkWidget *widget, GdkEventButton *event, gpointer data );
 static gboolean  on_actions_list_enter_key_pressed( GtkWidget *widget, GdkEventKey *event, gpointer data );
-static void      set_current_action( NactMainWindow *window, const NAAction *action );
+static void      set_current_action( NactMainWindow *window );
 static NAAction *get_edited_action( NactWindow *window );
 static void      on_modified_field( NactWindow *window );
-static gboolean  is_edited_modified( NactMainWindow *window );
+static void      check_edited_status( NactWindow *window, const NAAction *action );
+static gboolean  is_action_modified( const NAAction *action );
+static gboolean  is_action_to_save( const NAAction *action );
 
 static void      on_import_activated( GtkMenuItem *item, gpointer user_data );
 static void      on_import_selected( GtkItem *item, gpointer user_data );
@@ -118,6 +122,7 @@ static gboolean on_dialog_response( GtkDialog *dialog, gint response_id, BaseWin
 static void      on_close( GtkMenuItem *item, gpointer user_data );
 static gboolean  on_delete_event( BaseWindow *window, GtkWindow *toplevel, GdkEvent *event );
 
+static gint      count_modified_actions( NactMainWindow *window );
 static void      on_actions_changed( NAIPivotContainer *instance, gpointer user_data );
 
 GType
@@ -212,6 +217,7 @@ iactions_list_iface_init( NactIActionsListInterface *iface )
 	g_debug( "%s: iface=%p", thisfn, iface );
 
 	iface->get_actions = get_actions;
+	iface->set_sorted_actions = set_sorted_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;
@@ -328,6 +334,13 @@ get_actions( NactWindow *window )
 	return( NACT_MAIN_WINDOW( window )->private->actions );
 }
 
+static void
+set_sorted_actions( NactWindow *window, GSList *actions )
+{
+	g_assert( NACT_IS_MAIN_WINDOW( window ));
+	NACT_MAIN_WINDOW( window )->private->actions = actions;
+}
+
 /*
  * note that for this NactMainWindow, on_initial_load_toplevel and
  * on_runtime_init_toplevel are equivalent, as there is only one
@@ -489,48 +502,52 @@ on_runtime_init_toplevel( BaseWindow *window )
 }
 
 static void
-setup_dialog_title( NactWindow *window, gboolean is_modified )
+setup_dialog_title( NactMainWindow *window )
 {
 	BaseApplication *appli = BASE_APPLICATION( base_window_get_application( BASE_WINDOW( window )));
 	gchar *title = base_application_get_name( appli );
-	gchar *newtitle = g_strdup_printf( "%s%s", is_modified ? "*":"", title );
+
+	if( window->private->edited ){
+		gchar *label = na_action_get_label( window->private->edited );
+		gchar *tmp = g_strdup_printf( "%s - %s", title, label );
+		g_free( label );
+		g_free( title );
+		title = tmp;
+	}
+
+	if( count_modified_actions( window )){
+		gchar *tmp = g_strdup_printf( "*%s", title );
+		g_free( title );
+		title = tmp;
+	}
 
 	GtkWindow *toplevel = base_window_get_toplevel_dialog( BASE_WINDOW( window ));
-	gtk_window_set_title( toplevel, newtitle );
+	gtk_window_set_title( toplevel, title );
 
-	g_free( newtitle );
 	g_free( title );
 }
 
 static void
-setup_dialog_menu( NactWindow *window, gboolean can_save )
+setup_dialog_menu( NactMainWindow *window )
 {
-	gtk_widget_set_sensitive( NACT_MAIN_WINDOW( window )->private->save_item, can_save );
+	GSList *ia;
+	gboolean to_save = FALSE;
+	for( ia = window->private->actions ; ia && !to_save ; ia = ia->next ){
+		gboolean elt_to_save = is_action_to_save( NA_ACTION( ia->data ));
+		to_save |= elt_to_save;
+	}
+
+	gtk_widget_set_sensitive( NACT_MAIN_WINDOW( window )->private->save_item, to_save );
 }
 
 static void
 on_actions_list_selection_changed( GtkTreeSelection *selection, gpointer user_data )
 {
-	/*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( NACT_IS_MAIN_WINDOW( user_data ));
 	NactMainWindow *window = NACT_MAIN_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 );*/
-
-	NAAction *action = NA_ACTION( nact_iactions_list_get_selected_action( NACT_WINDOW( window )));
-	if( action ){
-		set_current_action( window, action );
-	}
+	window->private->edited = NA_ACTION( nact_iactions_list_get_selected_action( NACT_WINDOW( window )));
+	set_current_action( window );
 }
 
 static gboolean
@@ -555,7 +572,7 @@ on_actions_list_enter_key_pressed( GtkWidget *widget, GdkEventKey *event, gpoint
  * update the notebook when selection changes in IActionsList
  */
 static void
-set_current_action( NactMainWindow *window, const NAAction *action )
+set_current_action( NactMainWindow *window )
 {
 	/*NactMainWindow *window = NACT_MAIN_WINDOW( wnd );*/
 
@@ -571,18 +588,19 @@ set_current_action( NactMainWindow *window, const NAAction *action )
 		window->private->current_label = na_action_get_label( action );
 	}*/
 
-	nact_iaction_tab_set_action( NACT_WINDOW( window ), action );
+	g_debug( "set_current_action: current=%p", window->private->edited );
+	nact_iaction_tab_set_action( NACT_WINDOW( window ), window->private->edited );
 }
 
 /*
- * update the currently edited action when an field is modified
+ * update the currently edited NAAction when a field is modified
  * (called as a virtual function by each interface tab)
  */
 static NAAction *
 get_edited_action( NactWindow *window )
 {
 	g_assert( NACT_IS_MAIN_WINDOW( window ));
-	return( nact_iactions_list_get_selected_action( window ));
+	return( NACT_MAIN_WINDOW( window )->private->edited );
 }
 
 /*
@@ -595,25 +613,58 @@ on_modified_field( NactWindow *window )
 {
 	g_assert( NACT_IS_MAIN_WINDOW( window ));
 
-	gboolean is_modified = is_edited_modified( NACT_MAIN_WINDOW( window ));
-	/*g_debug( "on_modified_field: is_modified=%s", is_modified ? "True":"False" );*/
-	setup_dialog_title( window, is_modified );
-	nact_iactions_list_set_modified( window, is_modified );
+	check_edited_status( window, NACT_MAIN_WINDOW( window )->private->edited );
 
-	gboolean can_save = is_modified && nact_iaction_tab_has_label( window );
-	setup_dialog_menu( window, can_save );
+	setup_dialog_title( NACT_MAIN_WINDOW( window ));
+	setup_dialog_menu( NACT_MAIN_WINDOW( window ));
 }
 
-static gboolean
-is_edited_modified( NactMainWindow *window )
+static void
+check_edited_status( NactWindow *window, const NAAction *edited )
 {
-	NAAction *edited = nact_iactions_list_get_selected_action( NACT_WINDOW( window ));
-	gchar *uuid = na_action_get_uuid( edited );
+	g_assert( edited );
+
 	NactApplication *application = NACT_APPLICATION( base_window_get_application( BASE_WINDOW( window )));
 	NAPivot *pivot = NA_PIVOT( nact_application_get_pivot( application ));
+	gchar *uuid = na_action_get_uuid( edited );
 	NAAction *original = NA_ACTION( na_pivot_get_action( pivot, uuid ));
 	g_free( uuid );
-	return( !na_action_are_equal( edited, original ));
+	gboolean is_modified = !na_action_are_equal( edited, original );
+	g_object_set_data( G_OBJECT( edited ), "nact-main-window-action-modified", GINT_TO_POINTER( is_modified ));
+
+	/*gboolean check = is_action_modified( edited );
+	g_debug( "check_edited_status: edited=%p, is_modified=%s, check=%s", edited, is_modified ? "True":"False", check ? "True":"False" );*/
+
+	gboolean can_save = FALSE;
+	if( is_modified ){
+		gchar *label = na_action_get_label( edited );
+		if( label && g_utf8_strlen( label, -1 )){
+			GSList *ip;
+			GSList *profiles = na_action_get_profiles( edited );
+			for( ip = profiles ; ip ; ip = ip->next ){
+				NAActionProfile *prof = NA_ACTION_PROFILE( ip->data );
+				gchar *prof_label = na_action_profile_get_label( prof );
+				if( prof_label && g_utf8_strlen( prof_label, -1 )){
+					can_save = TRUE;
+				}
+				g_free( prof_label );
+			}
+			g_free( label );
+		}
+	}
+	g_object_set_data( G_OBJECT( edited ), "nact-main-window-action-can-save", GINT_TO_POINTER( can_save));
+}
+
+static gboolean
+is_action_modified( const NAAction *action )
+{
+	return( GPOINTER_TO_INT( g_object_get_data( G_OBJECT( action ), "nact-main-window-action-modified" )));
+}
+
+static gboolean
+is_action_to_save( const NAAction *action )
+{
+	return( GPOINTER_TO_INT( g_object_get_data( G_OBJECT( action ), "nact-main-window-action-can-save" )));
 }
 
 static void
@@ -921,7 +972,10 @@ on_close( GtkMenuItem *item, gpointer user_data )
 	g_assert( NACT_IS_MAIN_WINDOW( user_data ));
 	NactMainWindow *window = NACT_MAIN_WINDOW( user_data );
 
-	g_object_unref( window );
+	gint count = count_modified_actions( window );
+	if( !count || nact_window_warn_count_modified( NACT_WINDOW( window ), count )){
+		g_object_unref( window );
+	}
 }
 
 static gboolean
@@ -937,6 +991,22 @@ on_delete_event( BaseWindow *window, GtkWindow *toplevel, GdkEvent *event )
 	return( TRUE );
 }
 
+static gint
+count_modified_actions( NactMainWindow *window )
+{
+	gint count = 0;
+	GSList *ia;
+	for( ia = window->private->actions ; ia ; ia = ia->next ){
+		gboolean is_modified = is_action_modified( NA_ACTION( ia->data ));
+		if( is_modified ){
+			count += 1;
+		}
+		/*g_debug( "count_modified_actions: action=%p, is_modified=%s", ia->data, is_modified ? "True":"False" );*/
+	}
+	/*g_debug( "count_modified_actions: length=%d, count=%d", g_slist_length( window->private->actions ), count );*/
+	return( count );
+}
+
 /*
  * called by NAPivot because this window implements the IIOContainer
  * interface, i.e. it wish to be advertised when the list of actions
diff --git a/src/nact/nact-window.c b/src/nact/nact-window.c
index 4bb6e58..9854d85 100644
--- a/src/nact/nact-window.c
+++ b/src/nact/nact-window.c
@@ -282,6 +282,36 @@ nact_window_save_action( NactWindow *window, const NAAction *action )
  *
  * @window: this NactWindow object.
  *
+ * @count
+ *
+ * Returns TRUE if the user confirms he wants to quit.
+ */
+gboolean
+nact_window_warn_count_modified( NactWindow *window, gint count )
+{
+	gchar *first;
+	gchar *second;
+	if( count == 1 ){
+		first = g_strdup_printf( _( "One action has been modified." ));
+		second = g_strdup( _( "Are you sure you want to quit without saving it ?" ));
+	} else {
+		first = g_strdup_printf( _( "%d actions have been modified." ), count );
+		second = g_strdup( _( "Are you sure you want to quit without saving them ?" ));
+	}
+
+	gboolean ok = base_window_yesno_dlg( BASE_WINDOW( window ), GTK_MESSAGE_QUESTION, first, second );
+
+	g_free( second );
+	g_free( first );
+
+	return( ok );
+}
+
+/**
+ * Emits a warning if the action has been modified.
+ *
+ * @window: this NactWindow object.
+ *
  * @action: the modified action.
  *
  * Returns TRUE if the user confirms he wants to quit.
diff --git a/src/nact/nact-window.h b/src/nact/nact-window.h
index d1b2498..e75e0a5 100644
--- a/src/nact/nact-window.h
+++ b/src/nact/nact-window.h
@@ -76,9 +76,13 @@ GType    nact_window_get_type( void );
 
 GObject *nact_window_get_pivot( NactWindow *window );
 
+/* TODO: check these functions */
 void     nact_window_set_current_action( NactWindow *window, const NAAction *action );
 gboolean nact_window_save_action( NactWindow *window, const NAAction *action );
 
+/* TODO: move the function to nact-main-window */
+gboolean nact_window_warn_count_modified( NactWindow *window, gint count );
+/* TODO: remove the function */
 gboolean nact_window_warn_action_modified( NactWindow *window, const NAAction *action );
 gboolean nact_window_warn_profile_modified( NactWindow *window, const NAActionProfile *profile );
 



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