[nautilus-actions] Get rid of unwanted update notifications



commit 1759528c71f13ca0082546e71c143d6b83e0bcbb
Author: Pierre Wieser <pwieser trychlos org>
Date:   Sun Aug 23 12:57:25 2009 +0200

    Get rid of unwanted update notifications

 ChangeLog                       |   12 ++++++++
 src/common/na-ipivot-consumer.c |   58 +++++++++++++++++++++++++++++++-------
 src/common/na-ipivot-consumer.h |    2 +
 src/common/na-object.c          |    1 +
 src/nact/nact-imenubar.c        |   47 ++++++++++++++-----------------
 src/nact/nact-imenubar.h        |    1 -
 src/nact/nact-main-window.c     |   39 --------------------------
 7 files changed, 83 insertions(+), 77 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index f3fb65a..3cb9278 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,9 +1,21 @@
 2009-08-23 Pierre Wieser <pwieser trychlos org>
 
+	Get rid of unwanted notifications.
+
+	* src/common/na-ipivot-consumer.c:
+	* src/common/na-ipivot-consumer.h (na_ipivot_consumer_delay_notify):
+	New function.
+
+	* src/common/na-object.c: Accept NULL origin.
+
 	* src/nact/base-application.c:
 	Fix #592781: use explicit format strings.
 	Fix test of virtual functions which caused double calls.
 
+	* src/nact/nact-imenubar.c:
+	Rewrite save function to allow saving all modified actions in one pass.
+	Take advantage of na_ipivot_consumer_delay_notify().
+
 2009-08-21 Pierre Wieser <pwieser trychlos org>
 
 	Add About Nautilus Actions item in Nautilus context menu.
diff --git a/src/common/na-ipivot-consumer.c b/src/common/na-ipivot-consumer.c
index e0e2ec2..4b7689c 100644
--- a/src/common/na-ipivot-consumer.c
+++ b/src/common/na-ipivot-consumer.c
@@ -41,11 +41,11 @@
 struct NAIPivotConsumerInterfacePrivate {
 };
 
-static GType register_type( void );
-static void  interface_base_init( NAIPivotConsumerInterface *klass );
-static void  interface_base_finalize( NAIPivotConsumerInterface *klass );
+static GType    register_type( void );
+static void     interface_base_init( NAIPivotConsumerInterface *klass );
+static void     interface_base_finalize( NAIPivotConsumerInterface *klass );
 
-/*static void  do_actions_changed( NAIPivotConsumer *instance, gpointer user_data );*/
+static gboolean is_notify_allowed( const NAIPivotConsumer *instance );
 
 /**
  * Registers the GType of this interface.
@@ -120,6 +120,30 @@ interface_base_finalize( NAIPivotConsumerInterface *klass )
 }
 
 /**
+ * na_ipivot_consumer_delay_notify:
+ * @instance: the #NAIPivotConsumer instance.
+ *
+ * Informs the #NAIPivotconsumer instance that the next notification
+ * message should only be handled if a short delay has expired. This
+ * let us to no be polluted by notifications that we create ourselves
+ * (e.g. when saving actions).
+ */
+void
+na_ipivot_consumer_delay_notify( NAIPivotConsumer *instance )
+{
+	GTimeVal *last_delay;
+
+	last_delay = ( GTimeVal * ) g_object_get_data( G_OBJECT( instance ), "na-ipivot-consumer-delay-notify" );
+
+	if( !last_delay ){
+		last_delay = g_new0( GTimeVal, 1 );
+		g_object_set_data( G_OBJECT( instance ), "na-ipivot-consumer-delay-notify", last_delay );
+	}
+
+	g_get_current_time( last_delay );
+}
+
+/**
  * na_ipivot_consumer_notify:
  * @instance: the #NAIPivotConsumer instance to be notified of the end
  * of the modifications.
@@ -131,14 +155,26 @@ void na_ipivot_consumer_notify( NAIPivotConsumer *instance )
 	static const gchar *thisfn = "na_ipivot_consumer_notify";
 	g_debug( "%s: instance=%p", thisfn, instance );
 
-	if( NA_IPIVOT_CONSUMER_GET_INTERFACE( instance )->on_actions_changed ){
-		NA_IPIVOT_CONSUMER_GET_INTERFACE( instance )->on_actions_changed( instance, NULL );
+	if( is_notify_allowed( instance )){
+		if( NA_IPIVOT_CONSUMER_GET_INTERFACE( instance )->on_actions_changed ){
+			NA_IPIVOT_CONSUMER_GET_INTERFACE( instance )->on_actions_changed( instance, NULL );
+		}
 	}
 }
 
-/*static void
-do_actions_changed( NAIPivotConsumer *instance, gpointer user_data )
+static gboolean
+is_notify_allowed( const NAIPivotConsumer *instance )
 {
-	static const gchar *thisfn = "na_ipivot_consumer_do_actions_changed";
-	g_debug( "%s: instance=%p, user_data=%p", thisfn, instance, user_data );
-}*/
+	GTimeVal *last_delay;
+	GTimeVal now;
+
+	last_delay = ( GTimeVal * ) g_object_get_data( G_OBJECT( instance ), "na-ipivot-consumer-delay-notify" );
+	if( !last_delay ){
+		return( TRUE );
+	}
+
+	g_get_current_time( &now );
+	glong ecart = 1000000 * ( now.tv_sec - last_delay->tv_sec );
+	ecart += now.tv_usec - last_delay->tv_usec;
+	return( ecart > 1000000 );
+}
diff --git a/src/common/na-ipivot-consumer.h b/src/common/na-ipivot-consumer.h
index da84f4d..dc3ce56 100644
--- a/src/common/na-ipivot-consumer.h
+++ b/src/common/na-ipivot-consumer.h
@@ -75,6 +75,8 @@ typedef struct {
 
 GType na_ipivot_consumer_get_type( void );
 
+void  na_ipivot_consumer_delay_notify( NAIPivotConsumer *instance );
+
 void  na_ipivot_consumer_notify( NAIPivotConsumer *instance );
 
 G_END_DECLS
diff --git a/src/common/na-object.c b/src/common/na-object.c
index 507b4f0..c3ea6a2 100644
--- a/src/common/na-object.c
+++ b/src/common/na-object.c
@@ -455,6 +455,7 @@ void
 na_object_set_origin( NAObject *object, const NAObject *origin )
 {
 	g_assert( NA_IS_OBJECT( object ));
+	g_assert( NA_IS_OBJECT( origin ) || !origin );
 
 	na_iduplicable_set_origin( object, origin );
 }
diff --git a/src/nact/nact-imenubar.c b/src/nact/nact-imenubar.c
index f23e3b0..3b0a131 100644
--- a/src/nact/nact-imenubar.c
+++ b/src/nact/nact-imenubar.c
@@ -35,6 +35,7 @@
 #include <glib/gi18n.h>
 
 #include <common/na-about.h>
+#include <common/na-ipivot-consumer.h>
 
 #include "nact-application.h"
 #include "nact-assistant-export.h"
@@ -117,7 +118,6 @@ static void       v_select_actions_list( NactWindow *window, GType type, const g
 static gint       v_count_actions( NactWindow *window );
 static gint       v_count_modified_actions( NactWindow *window );
 static void       v_reload_actions( NactWindow *window );
-static void       v_on_save( NactWindow *window );
 
 static GtkWidget *get_new_profile_item( NactWindow *window );
 static void       set_new_profile_item( NactWindow *window, GtkWidget *item );
@@ -471,9 +471,13 @@ on_new_profile_selected( GtkItem *item, NactWindow *window )
 static void
 on_save_activated( GtkMenuItem *item, NactWindow *window )
 {
+	static const gchar *thisfn = "nact_imenubar_on_save_activated";
+	g_debug( "%s: item=%p, window=%p", thisfn, item, window );
+
 	NactApplication *application = NACT_APPLICATION( base_window_get_application( BASE_WINDOW( window )));
 	NAPivot *pivot = nact_application_get_pivot( application );
 	GSList *actions = v_get_actions( window );
+	g_debug( "%s: %d actions", thisfn, g_slist_length( actions ));
 	GSList *ia;
 
 	/* keep the current selection
@@ -500,33 +504,31 @@ on_save_activated( GtkMenuItem *item, NactWindow *window )
 	}
 
 	/* save the valid modified actions
-	 * - remove the origin of pivot if any
-	 * - add a duplicate of this action to pivot
+	 * - add a duplicate of this action to pivot or update the origin
 	 * - set the duplicate as the origin of this action
 	 * - reset the status
 	 */
 	for( ia = actions ; ia ; ia = ia->next ){
+
 		NAAction *current = NA_ACTION( ia->data );
-		if( na_object_get_modified_status( NA_OBJECT( current )) &&
-			na_object_get_valid_status( NA_OBJECT( current ))){
 
-			if( nact_window_save_action( window, current )){
+		if( na_object_get_modified_status( NA_OBJECT( current )) &&
+			na_object_get_valid_status( NA_OBJECT( current )) &&
+			nact_window_save_action( window, current )){
 
 				NAAction *origin = NA_ACTION( na_object_get_origin( NA_OBJECT( current )));
-				if( origin ){
-					na_pivot_remove_action( pivot, origin );
-				}
 
-				NAAction *dup_pivot = NA_ACTION( na_object_duplicate( NA_OBJECT( current )));
-				na_pivot_add_action( pivot, dup_pivot );
+				if( origin ){
+					na_object_copy( NA_OBJECT( origin ), NA_OBJECT( current ));
 
-				v_remove_action( window, current );
-				g_object_unref( current );
+				} else {
+					NAAction *dup_pivot = NA_ACTION( na_object_duplicate( NA_OBJECT( current )));
+					na_object_set_origin( NA_OBJECT( dup_pivot ), NULL );
+					na_object_set_origin( NA_OBJECT( current ), NA_OBJECT( dup_pivot ));
+					na_pivot_add_action( pivot, dup_pivot );
+				}
 
-				NAAction *dup_window = NA_ACTION( na_object_duplicate( NA_OBJECT( dup_pivot )));
-				v_add_action( window, dup_window );
-				na_object_check_edited_status( NA_OBJECT( dup_window ));
-			}
+				na_object_check_edited_status( NA_OBJECT( current ));
 		}
 	}
 
@@ -545,7 +547,6 @@ on_save_activated( GtkMenuItem *item, NactWindow *window )
 		}
 	}
 	v_free_deleted_actions( window );
-	v_on_save( window );
 
 	v_setup_dialog_title( window );
 
@@ -555,6 +556,8 @@ on_save_activated( GtkMenuItem *item, NactWindow *window )
 		g_free( label );
 		g_free( uuid );
 	}
+
+	na_ipivot_consumer_delay_notify( NA_IPIVOT_CONSUMER( window ));
 }
 
 static void
@@ -981,14 +984,6 @@ v_reload_actions( NactWindow *window )
 	}
 }
 
-static void
-v_on_save( NactWindow *window )
-{
-	if( NACT_IMENUBAR_GET_INTERFACE( window )->on_save ){
-		NACT_IMENUBAR_GET_INTERFACE( window )->on_save( window );
-	}
-}
-
 static GtkWidget *
 get_new_profile_item( NactWindow *window )
 {
diff --git a/src/nact/nact-imenubar.h b/src/nact/nact-imenubar.h
index c9410ca..eb37c23 100644
--- a/src/nact/nact-imenubar.h
+++ b/src/nact/nact-imenubar.h
@@ -69,7 +69,6 @@ typedef struct {
 	gint        ( *count_actions )         ( NactWindow *window );
 	gint        ( *count_modified_actions )( NactWindow *window );
 	void        ( *reload_actions )        ( NactWindow *window );
-	void        ( *on_save )               ( NactWindow *window );
 }
 	NactIMenubarInterface;
 
diff --git a/src/nact/nact-main-window.c b/src/nact/nact-main-window.c
index 216d7f1..0209fe9 100644
--- a/src/nact/nact-main-window.c
+++ b/src/nact/nact-main-window.c
@@ -65,7 +65,6 @@ struct NactMainWindowPrivate {
 	NAAction        *edited_action;
 	NAActionProfile *edited_profile;
 	GSList          *deleted;
-	GTimeVal         last_saved;
 };
 
 /* the GConf key used to read/write size and position of auxiliary dialogs
@@ -126,7 +125,6 @@ static gint             count_actions( NactWindow *window );
 static gint             count_modified_actions( NactWindow *window );
 static void             reload_actions( NactWindow *window );
 static GSList          *free_actions( GSList *actions );
-static void             on_save( NactWindow *window );
 static void             on_actions_changed( NAIPivotConsumer *instance, gpointer user_data );
 
 GType
@@ -331,7 +329,6 @@ imenubar_iface_init( NactIMenubarInterface *iface )
 	iface->count_actions = count_actions;
 	iface->count_modified_actions = count_modified_actions;
 	iface->reload_actions = reload_actions;
-	iface->on_save = on_save;
 }
 
 static void
@@ -396,9 +393,6 @@ instance_finalize( GObject *window )
 	g_assert( NACT_IS_MAIN_WINDOW( window ));
 	NactMainWindow *self = ( NactMainWindow * ) window;
 
-	/*g_free( self->private->current_uuid );
-	g_free( self->private->current_label );*/
-
 	g_free( self->private );
 
 	/* chain call to parent class */
@@ -552,8 +546,6 @@ on_runtime_init_toplevel( BaseWindow *window )
 		na_object_check_edited_status( NA_OBJECT( ia->data ));
 	}
 
-	g_get_current_time( &wnd->private->last_saved );
-
 	g_debug( "%s: window=%p", thisfn, window );
 	g_assert( NACT_IS_MAIN_WINDOW( window ));
 	/*NactMainWindow *wnd = NACT_MAIN_WINDOW( window );*/
@@ -1076,29 +1068,6 @@ free_actions( GSList *actions )
 }
 
 /*
- * in initial_load_toplevel(), we have forbidden the automatic reload
- * of the list of actions in NAPivot, as we take care of updating it of
- * the modifications entered in the UI
- *
- * this doesn't prevent NAPivot to advertise us when it detects some
- * modifications in an I/O provider ; so that we are able to ask the
- * user for a reload
- *
- * but we don't want be advertized when this is our own save which
- * triggers the NAPivot advertising - so we forbids such advertisings
- * during one seconde after each save
- *
- * note that last_saved is initialized in initial_load_toplevel()
- * so we will not be advertised if NAPivot detects a modification
- * in the seconde after this initialization - just ignore this case
- */
-static void
-on_save( NactWindow *window )
-{
-	g_get_current_time( &NACT_MAIN_WINDOW( window )->private->last_saved );
-}
-
-/*
  * called by NAPivot because this window implements the IIOConsumer
  * interface, i.e. it wish to be advertised when the list of actions
  * changes in the underlying I/O storage subsystem (typically, when we
@@ -1116,14 +1085,6 @@ on_actions_changed( NAIPivotConsumer *instance, gpointer user_data )
 	g_assert( NACT_IS_MAIN_WINDOW( instance ));
 	NactMainWindow *self = NACT_MAIN_WINDOW( instance );
 
-	GTimeVal now;
-	g_get_current_time( &now );
-	glong ecart = 1000000 * ( now.tv_sec - self->private->last_saved.tv_sec );
-	ecart += now.tv_usec - self->private->last_saved.tv_usec;
-	if( ecart < 1000000 ){
-		return;
-	}
-
 	NactApplication *application = NACT_APPLICATION( base_window_get_application( BASE_WINDOW( instance )));
 	NAPivot *pivot = nact_application_get_pivot( application );
 



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