[nautilus-actions] Disable edit menu when treeview has not the focus



commit 692cdb580b4649b8c59f8eb00a107ba06c55c8b5
Author: Pierre Wieser <pwieser trychlos org>
Date:   Fri Oct 9 16:59:38 2009 +0200

    Disable edit menu when treeview has not the focus
    
    Track focus-in and focus-out events.
    Propagates to MainWindow and catches in Menubar.
    Enable/disable edition actions depending of where is the focus.

 ChangeLog                     |    3 +
 src/nact/nact-iactions-list.c |   78 ++++++++++++++++++++++++++++
 src/nact/nact-iactions-list.h |    2 +
 src/nact/nact-main-menubar.c  |  113 +++++++++++++++++++++++++++++++---------
 4 files changed, 170 insertions(+), 26 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index b5997d7..80f14d3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -11,12 +11,15 @@
 	* src/nact/nact-iactions-list.h (nact_iactions_list_brief_tree_dump):
 	Briefly dump the tree store content.
 	(nact_iactions_list_runtime_init_toplevel): Grab the focus at start.
+	(on_focus_in, on_focus_out): Track the focus in the treeview.
 
 	* src/nact/nact-main-menubar.c (nact_main_menubar_runtime_init):
 	Display a Maintainer menu when in maintainer mode.
 	Add BriefTreeStoreDumpItem new item.
 	Display a first toolbar.
 	(on_save_activated): Also save non-valid items.
+	(on_update_sensitivities): Disable edit actions when the focus is
+	not in the treeview.
 
 	* src/nact/nact-tree-model.c (nact_tree_model_insert):
 	Add debug traces.
diff --git a/src/nact/nact-iactions-list.c b/src/nact/nact-iactions-list.c
index 8492dd1..3efe487 100644
--- a/src/nact/nact-iactions-list.c
+++ b/src/nact/nact-iactions-list.c
@@ -80,6 +80,8 @@ typedef struct {
 enum {
 	LIST_COUNT_UPDATED,
 	SELECTION_CHANGED,
+	FOCUS_IN,
+	FOCUS_OUT,
 	LAST_SIGNAL
 };
 
@@ -159,6 +161,8 @@ static GtkTreePath *object_to_path( NactIActionsList *instance, NactTreeModel *m
 static gboolean     object_to_path_iter( NactTreeModel *model, GtkTreePath *path, NAObject *object, ObjectToPathIter *otp );
 static gboolean     on_button_press_event( GtkWidget *widget, GdkEventButton *event, NactIActionsList *instance );
 static void         on_edition_status_changed( NactIActionsList *instance, NAIDuplicable *object );
+static gboolean     on_focus_in( GtkWidget *widget, GdkEventFocus *event, NactIActionsList *instance );
+static gboolean     on_focus_out( GtkWidget *widget, GdkEventFocus *event, NactIActionsList *instance );
 static gboolean     on_key_pressed_event( GtkWidget *widget, GdkEventKey *event, NactIActionsList *instance );
 static void         on_treeview_selection_changed( GtkTreeSelection *selection, NactIActionsList *instance );
 static void         on_tab_updatable_item_updated( NactIActionsList *instance, NAObject *object );
@@ -275,6 +279,42 @@ interface_base_init( NactIActionsListInterface *klass )
 				1,
 				G_TYPE_POINTER );
 
+		/**
+		 * nact-iactions-list-focus-in:
+		 *
+		 * This signal is emitted byIActionsList when it gains the focus.
+		 * In particular, edition menu is disabled outside of the treeview.
+		 */
+		st_signals[ FOCUS_IN ] = g_signal_new(
+				IACTIONS_LIST_SIGNAL_FOCUS_IN,
+				G_TYPE_OBJECT,
+				G_SIGNAL_RUN_LAST,
+				0,
+				NULL,
+				NULL,
+				g_cclosure_marshal_VOID__POINTER,
+				G_TYPE_NONE,
+				1,
+				G_TYPE_POINTER );
+
+		/**
+		 * nact-iactions-list-focus-out:
+		 *
+		 * This signal is emitted byIActionsList when it looses the focus.
+		 * In particular, edition menu is disabled outside of the treeview.
+		 */
+		st_signals[ FOCUS_OUT ] = g_signal_new(
+				IACTIONS_LIST_SIGNAL_FOCUS_OUT,
+				G_TYPE_OBJECT,
+				G_SIGNAL_RUN_LAST,
+				0,
+				NULL,
+				NULL,
+				g_cclosure_marshal_VOID__POINTER,
+				G_TYPE_NONE,
+				1,
+				G_TYPE_POINTER );
+
 		st_initialized = TRUE;
 	}
 }
@@ -436,6 +476,20 @@ nact_iactions_list_runtime_init_toplevel( NactIActionsList *instance, GList *ite
 				TAB_UPDATABLE_SIGNAL_ITEM_UPDATED,
 				G_CALLBACK( on_tab_updatable_item_updated ));
 
+		/* enable/disable edit menu item accelerators depending of
+		 * which widget has the focus */
+		base_window_signal_connect(
+				BASE_WINDOW( instance ),
+				G_OBJECT( treeview ),
+				"focus-in-event",
+				G_CALLBACK( on_focus_in ));
+
+		base_window_signal_connect(
+				BASE_WINDOW( instance ),
+				G_OBJECT( treeview ),
+				"focus-out-event",
+				G_CALLBACK( on_focus_out ));
+
 		/* records NactIActionsList as a proxy for edition status
 		 * modification */
 		is_proxy = is_iduplicable_proxy( instance, ialid );
@@ -1709,6 +1763,30 @@ on_edition_status_changed( NactIActionsList *instance, NAIDuplicable *object )
 }
 
 static gboolean
+on_focus_in( GtkWidget *widget, GdkEventFocus *event, NactIActionsList *instance )
+{
+	/*static const gchar *thisfn = "nact_iactions_list_on_focus_in";*/
+	gboolean stop = FALSE;
+
+	/*g_debug( "%s: widget=%p, event=%p, instance=%p", thisfn, ( void * ) widget, ( void * ) event, ( void * ) instance );*/
+	g_signal_emit_by_name( instance, IACTIONS_LIST_SIGNAL_FOCUS_IN, instance );
+
+	return( stop );
+}
+
+static gboolean
+on_focus_out( GtkWidget *widget, GdkEventFocus *event, NactIActionsList *instance )
+{
+	/*static const gchar *thisfn = "nact_iactions_list_on_focus_out";*/
+	gboolean stop = FALSE;
+
+	/*g_debug( "%s: widget=%p, event=%p, instance=%p", thisfn, ( void * ) widget, ( void * ) event, ( void * ) instance );*/
+	g_signal_emit_by_name( instance, IACTIONS_LIST_SIGNAL_FOCUS_OUT, instance );
+
+	return( stop );
+}
+
+static gboolean
 on_key_pressed_event( GtkWidget *widget, GdkEventKey *event, NactIActionsList *instance )
 {
 	/*static const gchar *thisfn = "nact_iactions_list_v_on_key_pressed_event";
diff --git a/src/nact/nact-iactions-list.h b/src/nact/nact-iactions-list.h
index 7400ab3..443e43a 100644
--- a/src/nact/nact-iactions-list.h
+++ b/src/nact/nact-iactions-list.h
@@ -105,6 +105,8 @@ typedef struct {
  */
 #define IACTIONS_LIST_SIGNAL_LIST_COUNT_UPDATED			"nact-iactions-list-count-updated"
 #define IACTIONS_LIST_SIGNAL_SELECTION_CHANGED			"nact-iactions-list-selection-changed"
+#define IACTIONS_LIST_SIGNAL_FOCUS_IN					"nact-iactions-list-focus-in"
+#define IACTIONS_LIST_SIGNAL_FOCUS_OUT					"nact-iactions-list-focus-out"
 
 /* management modes
  * - edition: dnd, filter, multiple selection, item updated signal
diff --git a/src/nact/nact-main-menubar.c b/src/nact/nact-main-menubar.c
index bb4ac9d..b195941 100644
--- a/src/nact/nact-main-menubar.c
+++ b/src/nact/nact-main-menubar.c
@@ -83,6 +83,7 @@ typedef struct {
 	gint     list_profiles;
 	gboolean is_modified;
 	gboolean have_exportables;
+	gboolean treeview_has_focus;
 }
 	MenubarIndicatorsStruct;
 
@@ -90,6 +91,8 @@ typedef struct {
 
 static void     on_iactions_list_count_updated( NactMainWindow *window, gint menus, gint actions, gint profiles );
 static void     on_iactions_list_selection_changed( NactMainWindow *window, GList *selected );
+static void     on_iactions_list_focus_in( NactMainWindow *window, gpointer user_data );
+static void     on_iactions_list_focus_out( NactMainWindow *window, gpointer user_data );
 static void     on_update_sensitivities( NactMainWindow *window, gpointer user_data );
 
 static void     on_new_menu_activated( GtkAction *action, NactMainWindow *window );
@@ -334,6 +337,18 @@ nact_main_menubar_runtime_init( NactMainWindow *window )
 	base_window_signal_connect(
 			BASE_WINDOW( window ),
 			G_OBJECT( window ),
+			IACTIONS_LIST_SIGNAL_FOCUS_IN,
+			G_CALLBACK( on_iactions_list_focus_in ));
+
+	base_window_signal_connect(
+			BASE_WINDOW( window ),
+			G_OBJECT( window ),
+			IACTIONS_LIST_SIGNAL_FOCUS_OUT,
+			G_CALLBACK( on_iactions_list_focus_out ));
+
+	base_window_signal_connect(
+			BASE_WINDOW( window ),
+			G_OBJECT( window ),
 			MAIN_WINDOW_SIGNAL_UPDATE_ACTION_SENSITIVITIES,
 			G_CALLBACK( on_update_sensitivities ));
 
@@ -405,6 +420,32 @@ on_iactions_list_selection_changed( NactMainWindow *window, GList *selected )
 }
 
 static void
+on_iactions_list_focus_in( NactMainWindow *window, gpointer user_data )
+{
+	MenubarIndicatorsStruct *mis;
+
+	g_debug( "nact_main_menubar_on_iactions_list_focus_in" );
+	g_return_if_fail( NACT_IS_MAIN_WINDOW( window ));
+
+	mis = ( MenubarIndicatorsStruct * ) g_object_get_data( G_OBJECT( window ), MENUBAR_PROP_INDICATORS );
+	mis->treeview_has_focus = TRUE;
+	g_signal_emit_by_name( window, MAIN_WINDOW_SIGNAL_UPDATE_ACTION_SENSITIVITIES, NULL );
+}
+
+static void
+on_iactions_list_focus_out( NactMainWindow *window, gpointer user_data )
+{
+	MenubarIndicatorsStruct *mis;
+
+	g_debug( "nact_main_menubar_on_iactions_list_focus_out" );
+	g_return_if_fail( NACT_IS_MAIN_WINDOW( window ));
+
+	mis = ( MenubarIndicatorsStruct * ) g_object_get_data( G_OBJECT( window ), MENUBAR_PROP_INDICATORS );
+	mis->treeview_has_focus = FALSE;
+	g_signal_emit_by_name( window, MAIN_WINDOW_SIGNAL_UPDATE_ACTION_SENSITIVITIES, NULL );
+}
+
+static void
 on_update_sensitivities( NactMainWindow *window, gpointer user_data )
 {
 	static const gchar *thisfn = "nact_main_menubar_on_update_sensitivities";
@@ -414,8 +455,12 @@ on_update_sensitivities( NactMainWindow *window, gpointer user_data )
 	gboolean has_modified;
 	gint count_list;
 	gint count_selected;
+	gboolean cut_enabled;
+	gboolean copy_enabled;
 	gboolean paste_enabled;
 	gboolean paste_into_enabled;
+	gboolean duplicate_enabled;
+	gboolean delete_enabled;
 	gboolean clipboard_is_empty;
 
 	g_debug( "%s: window=%p", thisfn, ( void * ) window );
@@ -437,22 +482,44 @@ on_update_sensitivities( NactMainWindow *window, gpointer user_data )
 
 	clipboard_is_empty = ( mis->clipboard_menus + mis->clipboard_actions + mis->clipboard_profiles == 0 );
 
+	/* edit menu is only enabled when the treeview has the focus
+	 */
+
+	/* cut/copy/duplicate/delete enabled when selection not empty */
+	cut_enabled = mis->treeview_has_focus && count_selected > 0;
+	copy_enabled = mis->treeview_has_focus && count_selected > 0;
+	duplicate_enabled = mis->treeview_has_focus && count_selected > 0;
+	delete_enabled = mis->treeview_has_focus && count_selected > 0;
+
+	/* paste enabled if
+	 * - simple selection
+	 * - clipboard contains only profiles, and current selection is a profile
+	 * - clipboard contains actions or menus, and current selection is a menu or an action */
 	paste_enabled = FALSE;
-	if( !clipboard_is_empty ){
-		if( mis->clipboard_profiles ){
-			paste_enabled = item && NA_IS_OBJECT_ACTION( item );
-		} else {
-			paste_enabled = ( item != NULL );
+	if( mis->treeview_has_focus && count_selected <= 1 ){
+		if( !clipboard_is_empty ){
+			if( mis->clipboard_profiles ){
+				paste_enabled = item && NA_IS_OBJECT_ACTION( item );
+			} else {
+				paste_enabled = ( item != NULL );
+			}
 		}
 	}
 
+	/* paste into enabled if
+	 * - simple selection
+	 * - clipboard has profiles and current item is an action
+	 * - or current item is a menu
+	 * do not paste into if current selection is a profile */
 	paste_into_enabled = FALSE;
-	if( mis->selected_menus + mis->selected_actions ){
-		if( !clipboard_is_empty ){
-			if( mis->clipboard_profiles ){
-				paste_into_enabled = item && NA_IS_OBJECT_ACTION( item );
-			} else {
-				paste_into_enabled = item && NA_IS_OBJECT_MENU( item );
+	if( mis->treeview_has_focus && count_selected <= 1 ){
+		if( mis->selected_menus + mis->selected_actions ){
+			if( !clipboard_is_empty ){
+				if( mis->clipboard_profiles ){
+					paste_into_enabled = item && NA_IS_OBJECT_ACTION( item );
+				} else {
+					paste_into_enabled = item && NA_IS_OBJECT_MENU( item );
+				}
 			}
 		}
 	}
@@ -464,21 +531,15 @@ on_update_sensitivities( NactMainWindow *window, gpointer user_data )
 	/* save enabled if at least one item has been modified */
 	enable_item( window, "SaveItem", has_modified );
 	/* quit always enabled */
-	/* cut/copy enabled if selection not empty */
-	enable_item( window, "CutItem", count_selected > 0 );
-	enable_item( window, "CopyItem", count_selected > 0 );
-	/* paste enabled if
-	 * - clipboard contains only profiles, and current selection is a profile
-	 * - clipboard contains actions or menus, and current selection is a menu or an action */
-	enable_item( window, "PasteItem", count_selected <= 1 && paste_enabled );
-	/* paste into enabled if
-	 * - clipboard has profiles and current item is an action
-	 * - or current item is a menu
-	 * do not paste into if current selection is a profile */
-	enable_item( window, "PasteIntoItem", count_selected <= 1 && paste_into_enabled );
-	/* duplicate/delete enabled if selection not empty */
-	enable_item( window, "DuplicateItem", count_selected > 0 );
-	enable_item( window, "DeleteItem", count_selected > 0 );
+
+	/* edit menu (cf. above) */
+	enable_item( window, "CutItem", cut_enabled );
+	enable_item( window, "CopyItem", copy_enabled );
+	enable_item( window, "PasteItem", paste_enabled );
+	enable_item( window, "PasteIntoItem", paste_into_enabled );
+	enable_item( window, "DuplicateItem", duplicate_enabled );
+	enable_item( window, "DeleteItem", delete_enabled );
+
 	/* reload items always enabled */
 	/* preferences always enabled */
 	/* expand all/collapse all requires at least one item in the list */



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