[nautilus-actions] Only load enabled valid items in Nautilus plugin



commit 845fd4d62523d7373d414ead5773f4deace106db
Author: Pierre Wieser <pwieser trychlos org>
Date:   Mon Dec 7 06:37:37 2009 +0100

    Only load enabled valid items in Nautilus plugin

 ChangeLog                                  |   26 ++++
 TODO                                       |    6 +
 nautilus-actions/nact/nact-application.c   |    1 +
 nautilus-actions/nact/nact-main-window.c   |    2 +-
 nautilus-actions/plugin/nautilus-actions.c |    3 +-
 nautilus-actions/private/na-object-item.c  |    4 +
 nautilus-actions/runtime/na-io-provider.c  |  175 ++++++++++++++++++++--------
 nautilus-actions/runtime/na-pivot.c        |  118 +++++++++++++------
 nautilus-actions/runtime/na-pivot.h        |   14 ++-
 9 files changed, 256 insertions(+), 93 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 0000820..50b6a8c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,29 @@
+2009-12-07 Pierre Wieser <pwieser trychlos org>
+
+	Only load in the Nautilus plugin valid and enabled candidate items.
+
+	* nautilus-actions/nact/nact-application.c
+	(appli_initialize_application): Explicitely load items.
+
+	* nautilus-actions/nact/nact-main-window.c (reload):
+	Call na_pivot_load_items() function.
+
+	* nautilus-actions/plugin/nautilus-actions.c (instance_init):
+	Explicitely load items after having set filtering criteria.
+
+	* nautilus-actions/private/na-object-item.c
+	(na_object_item_set_items_list): Free previous GList structure.
+
+	* nautilus-actions/runtime/na-io-provider.c
+	(na_io_provider_read_items): Filter the returned hierarchy.
+
+	* nautilus-actions/runtime/na-pivot.c:
+	* nautilus-actions/runtime/na-pivot.h
+	(na_pivot_check_status): Removed function.
+	(na_pivot_reload_items): Renamed as na_pivot_load_items().
+	(na_pivot_set_population, na_pivot_is_disable_loadable,
+	na_pivot_is_invalid_loadable): New functions.
+
 2009-12-03 Pierre Wieser <pwieser trychlos org>
 
 	* nautilus-actions/private/na-object-profile.c (object_is_valid):
diff --git a/TODO b/TODO
index 1727519..0f12ca9 100644
--- a/TODO
+++ b/TODO
@@ -102,3 +102,9 @@
 - nact: shouldn't be able to paste into a read-only item
 
 - nact: when pasting an item, should reset provider and read-only flag
+
+- desktop provider: fix default toolbar label
+
+- dump clipboard: test if null
+
+- na-object-api: set parenthesis around args
diff --git a/nautilus-actions/nact/nact-application.c b/nautilus-actions/nact/nact-application.c
index 97c9724..83e10cd 100644
--- a/nautilus-actions/nact/nact-application.c
+++ b/nautilus-actions/nact/nact-application.c
@@ -395,6 +395,7 @@ appli_initialize_application( BaseApplication *application )
 	g_object_unref( fake );
 
 	NACT_APPLICATION( application )->private->pivot = na_pivot_new();
+	na_pivot_load_items( NACT_APPLICATION( application )->private->pivot );
 
 	/* call parent class */
 	ok = BASE_APPLICATION_CLASS( st_parent_class )->initialize_application( application );
diff --git a/nautilus-actions/nact/nact-main-window.c b/nautilus-actions/nact/nact-main-window.c
index 7328560..38c5753 100644
--- a/nautilus-actions/nact/nact-main-window.c
+++ b/nautilus-actions/nact/nact-main-window.c
@@ -1320,7 +1320,7 @@ reload( NactMainWindow *window )
 
 		application = NACT_APPLICATION( base_window_get_application( BASE_WINDOW( window )));
 		pivot = nact_application_get_pivot( application );
-		na_pivot_reload_items( pivot );
+		na_pivot_load_items( pivot );
 		nact_iactions_list_fill( NACT_IACTIONS_LIST( window ), na_pivot_get_items( pivot ));
 
 		na_object_free_items_list( window->private->deleted );
diff --git a/nautilus-actions/plugin/nautilus-actions.c b/nautilus-actions/plugin/nautilus-actions.c
index bb32184..7159758 100644
--- a/nautilus-actions/plugin/nautilus-actions.c
+++ b/nautilus-actions/plugin/nautilus-actions.c
@@ -220,7 +220,8 @@ instance_init( GTypeInstance *instance, gpointer klass )
 	self->private->pivot = na_pivot_new();
 	na_pivot_register_consumer( self->private->pivot, NA_IPIVOT_CONSUMER( self ));
 	na_pivot_set_automatic_reload( self->private->pivot, TRUE );
-	na_pivot_check_status( self->private->pivot );
+	na_pivot_set_population( self->private->pivot, !PIVOT_LOAD_DISABLED & !PIVOT_LOAD_INVALID );
+	na_pivot_load_items( self->private->pivot );
 }
 
 static void
diff --git a/nautilus-actions/private/na-object-item.c b/nautilus-actions/private/na-object-item.c
index 7e96829..2462cfc 100644
--- a/nautilus-actions/private/na-object-item.c
+++ b/nautilus-actions/private/na-object-item.c
@@ -788,6 +788,10 @@ na_object_item_set_items_list( NAObjectItem *item, GList *items )
 
 	if( !item->private->dispose_has_run ){
 
+		if( item->private->items ){
+			g_list_free( item->private->items );
+		}
+
 		item->private->items = items;
 
 		for( is = items ; is ; is = is->next ){
diff --git a/nautilus-actions/runtime/na-io-provider.c b/nautilus-actions/runtime/na-io-provider.c
index 5c38075..0ef709d 100644
--- a/nautilus-actions/runtime/na-io-provider.c
+++ b/nautilus-actions/runtime/na-io-provider.c
@@ -41,13 +41,14 @@
 #include "na-iprefs.h"
 #include "na-utils.h"
 
-static GList   *build_hierarchy( GList **tree, GSList *level_zero, gboolean list_if_empty );
-static gint     search_item( const NAObject *obj, const gchar *uuid );
-static GList   *get_merged_items_list( const NAPivot *pivot, GList *providers, GSList **messages );
+static GList *get_merged_items_list( const NAPivot *pivot, GList *providers, GSList **messages );
+static GList *build_hierarchy( GList **tree, GSList *level_zero, gboolean list_if_empty );
+static gint   search_item( const NAObject *obj, const gchar *uuid );
+static GList *sort_tree( const NAPivot *pivot, GList *tree, GCompareFunc fn );
+static GList *filter_unwanted_items( const NAPivot *pivot, GList *merged );
+static GList *filter_unwanted_items_rec( GList *merged, gboolean load_disabled, gboolean load_invalid );
 
-static guint    try_write_item( const NAIIOProvider *instance, NAObjectItem *item, GSList **messages );
-
-static GList   *sort_tree( const NAPivot *pivot, GList *tree, GCompareFunc fn );
+static guint  try_write_item( const NAIIOProvider *instance, NAObjectItem *item, GSList **messages );
 
 /**
  * na_io_provider_register_callbacks:
@@ -108,7 +109,7 @@ na_io_provider_read_items( const NAPivot *pivot, GSList **messages )
 {
 	static const gchar *thisfn = "na_io_provider_read_items";
 	GList *providers;
-	GList *merged, *hierarchy;
+	GList *merged, *hierarchy, *filtered;
 	GSList *level_zero;
 	gint order_mode;
 
@@ -141,10 +142,6 @@ na_io_provider_read_items( const NAPivot *pivot, GSList **messages )
 
 	na_utils_free_string_list( level_zero );
 
-	g_debug( "%s: tree before alphabetical reordering (if any)", thisfn );
-	na_object_dump_tree( hierarchy );
-	g_debug( "%s: end of tree", thisfn );
-
 	order_mode = na_iprefs_get_order_mode( NA_IPREFS( pivot ));
 	switch( order_mode ){
 		case IPREFS_ORDER_ALPHA_ASCENDING:
@@ -160,7 +157,45 @@ na_io_provider_read_items( const NAPivot *pivot, GSList **messages )
 			break;
 	}
 
-	return( hierarchy );
+	filtered = filter_unwanted_items( pivot, hierarchy );
+	g_list_free( hierarchy );
+
+	g_debug( "%s: tree after filtering and reordering (if any)", thisfn );
+	na_object_dump_tree( filtered );
+	g_debug( "%s: end of tree", thisfn );
+
+	return( filtered );
+}
+
+/*
+ * returns a concatened list of readen actions / menus
+ */
+static GList *
+get_merged_items_list( const NAPivot *pivot, GList *providers, GSList **messages )
+{
+	GList *ip;
+	GList *merged = NULL;
+	GList *list, *item;
+	NAIIOProvider *instance;
+
+	for( ip = providers ; ip ; ip = ip->next ){
+
+		instance = NA_IIO_PROVIDER( ip->data );
+		if( NA_IIO_PROVIDER_GET_INTERFACE( instance )->read_items ){
+
+			list = NA_IIO_PROVIDER_GET_INTERFACE( instance )->read_items( instance, messages );
+
+			for( item = list ; item ; item = item->next ){
+
+				na_object_set_provider( item->data, instance );
+				na_object_dump( item->data );
+			}
+
+			merged = g_list_concat( merged, list );
+		}
+	}
+
+	return( merged );
 }
 
 /*
@@ -233,35 +268,96 @@ search_item( const NAObject *obj, const gchar *uuid )
 	return( ret );
 }
 
-/*
- * returns a concatened list of readen actions / menus
- */
 static GList *
-get_merged_items_list( const NAPivot *pivot, GList *providers, GSList **messages )
+sort_tree( const NAPivot *pivot, GList *tree, GCompareFunc fn )
 {
-	GList *ip;
-	GList *merged = NULL;
-	GList *list, *item;
-	NAIIOProvider *instance;
+	GList *sorted;
+	GList *items, *it;
 
-	for( ip = providers ; ip ; ip = ip->next ){
+	sorted = g_list_sort( tree, fn );
 
-		instance = NA_IIO_PROVIDER( ip->data );
-		if( NA_IIO_PROVIDER_GET_INTERFACE( instance )->read_items ){
+	/* recursively sort each level of the tree
+	 */
+	for( it = sorted ; it ; it = it->next ){
+		if( NA_IS_OBJECT_MENU( it->data )){
+			items = na_object_get_items_list( it->data );
+			items = sort_tree( pivot, items, fn );
+			na_object_set_items_list( it->data, items );
+		}
+	}
 
-			list = NA_IIO_PROVIDER_GET_INTERFACE( instance )->read_items( instance, messages );
+	return( sorted );
+}
 
-			for( item = list ; item ; item = item->next ){
+static GList *
+filter_unwanted_items( const NAPivot *pivot, GList *hierarchy )
+{
+	gboolean load_disabled;
+	gboolean load_invalid;
+	GList *it;
+	GList *filtered;
 
-				na_object_set_provider( item->data, instance );
-				na_object_dump( item->data );
+	load_disabled = na_pivot_is_disable_loadable( pivot );
+	load_invalid = na_pivot_is_invalid_loadable( pivot );
+
+	for( it = hierarchy ; it ; it = it->next ){
+		na_object_check_status( it->data );
+	}
+
+	filtered = filter_unwanted_items_rec( hierarchy, load_disabled, load_invalid );
+
+	return( filtered );
+}
+
+/*
+ * build a dest tree from a source tree, removing filtered items
+ * an item is filtered if it is invalid (and not loading invalid ones)
+ * or disabled (and not loading disabled ones)
+ */
+static GList *
+filter_unwanted_items_rec( GList *hierarchy, gboolean load_disabled, gboolean load_invalid )
+{
+	static const gchar *thisfn = "na_io_provider_filter_unwanted_items_rec";
+	GList *subitems, *subitems_f;
+	GList *it, *itnext;
+	GList *filtered;
+	gboolean selected;
+	gchar *label;
+
+	filtered = NULL;
+	for( it = hierarchy ; it ; it = itnext ){
+
+		itnext = it->next;
+		selected = FALSE;
+
+		if( NA_IS_OBJECT_PROFILE( it->data )){
+			if( na_object_is_valid( it->data ) || load_invalid ){
+				filtered = g_list_append( filtered, it->data );
+				selected = TRUE;
+			}
+		}
+
+		if( NA_IS_OBJECT_ITEM( it->data )){
+			if(( na_object_is_enabled( it->data ) || load_disabled ) &&
+				( na_object_is_valid( it->data ) || load_invalid )){
+
+				subitems = na_object_get_items_list( it->data );
+				subitems_f = filter_unwanted_items_rec( subitems, load_disabled, load_invalid );
+				na_object_set_items_list( it->data, subitems_f );
+				filtered = g_list_append( filtered, it->data );
+				selected = TRUE;
 			}
+		}
 
-			merged = g_list_concat( merged, list );
+		if( !selected ){
+			label = na_object_get_label( it->data );
+			g_debug( "%s: filtering %p (%s) '%s'", thisfn, ( void * ) it->data, G_OBJECT_TYPE_NAME( it->data ), label );
+			g_free( label );
+			na_object_unref( it->data );
 		}
 	}
 
-	return( merged );
+	return( filtered );
 }
 
 /**
@@ -402,24 +498,3 @@ na_io_provider_delete_item( const NAPivot *pivot, const NAObjectItem *item, GSLi
 
 	return( ret );
 }
-
-static GList *
-sort_tree( const NAPivot *pivot, GList *tree, GCompareFunc fn )
-{
-	GList *sorted;
-	GList *items, *it;
-
-	sorted = g_list_sort( tree, fn );
-
-	/* recursively sort each level of the tree
-	 */
-	for( it = sorted ; it ; it = it->next ){
-		if( NA_IS_OBJECT_MENU( it->data )){
-			items = na_object_get_items_list( it->data );
-			items = sort_tree( pivot, items, fn );
-			na_object_set_items_list( it->data, items );
-		}
-	}
-
-	return( sorted );
-}
diff --git a/nautilus-actions/runtime/na-pivot.c b/nautilus-actions/runtime/na-pivot.c
index 906dedb..e5709f6 100644
--- a/nautilus-actions/runtime/na-pivot.c
+++ b/nautilus-actions/runtime/na-pivot.c
@@ -78,6 +78,10 @@ struct NAPivotPrivate {
 	guint    event_source_id;
 	gulong   action_changed_handler;
 
+	/* whether to load all items, or only a part
+	 */
+	gint     population;
+
 	/* list of monitoring objects on runtime preferences
 	 */
 	GList   *monitors;
@@ -221,6 +225,7 @@ instance_init( GTypeInstance *instance, gpointer klass )
 	self->private->tree = NULL;
 	self->private->automatic_reload = FALSE;
 	self->private->event_source_id = 0;
+	self->private->population = PIVOT_LOAD_ALL;
 }
 
 static void
@@ -294,52 +299,23 @@ na_pivot_new( void )
 {
 	static const gchar *thisfn = "na_pivot_new";
 	NAPivot *pivot;
-	GSList *messages, *im;
 
 	g_debug( "%s", thisfn );
 
 	pivot = g_object_new( NA_PIVOT_TYPE, NULL );
 
 	pivot->private->modules = na_module_load_modules();
+
 	na_io_provider_register_callbacks( pivot );
 	/*g_debug( "%s: modules=%p, count=%d",
 			thisfn, ( void * ) pivot->private->modules, g_list_length( pivot->private->modules ));*/
 
 	monitor_runtime_preferences( pivot );
 
-	pivot->private->tree = na_io_provider_read_items( pivot, &messages );
-	for( im = messages ; im ; im = im->next ){
-		g_warning( "%s: %s", thisfn, ( const gchar * ) im->data );
-	}
-	na_utils_free_string_list( messages );
-
 	return( pivot );
 }
 
 /**
- * na_pivot_check_status:
- * @pivot: this #NAPivot object.
- *
- * Recursively checks the status of items in @pivot.
- */
-void
-na_pivot_check_status( const NAPivot *pivot )
-{
-	static const gchar *thisfn = "na_pivot_check_status";
-	GList *it;
-
-	g_debug( "%s: pivot=%p", thisfn, ( void * ) pivot );
-	g_return_if_fail( NA_IS_PIVOT( pivot ));
-
-	if( !pivot->private->dispose_has_run ){
-
-		for( it = pivot->private->tree ; it ; it = it->next ){
-			na_object_check_status( it->data );
-		}
-	}
-}
-
-/**
  * na_pivot_dump:
  * @pivot: the #NAPivot object do be dumped.
  *
@@ -354,9 +330,11 @@ na_pivot_dump( const NAPivot *pivot )
 
 	if( !pivot->private->dispose_has_run ){
 
-		g_debug( "%s:   modules=%p (%d elts)", thisfn, ( void * ) pivot->private->modules, g_list_length( pivot->private->modules ));
-		g_debug( "%s: consumers=%p (%d elts)", thisfn, ( void * ) pivot->private->consumers, g_list_length( pivot->private->consumers ));
-		g_debug( "%s:      tree=%p (%d elts)", thisfn, ( void * ) pivot->private->tree, g_list_length( pivot->private->tree ));
+		g_debug( "%s:          modules=%p (%d elts)", thisfn, ( void * ) pivot->private->modules, g_list_length( pivot->private->modules ));
+		g_debug( "%s:        consumers=%p (%d elts)", thisfn, ( void * ) pivot->private->consumers, g_list_length( pivot->private->consumers ));
+		g_debug( "%s:             tree=%p (%d elts)", thisfn, ( void * ) pivot->private->tree, g_list_length( pivot->private->tree ));
+		g_debug( "%s: automatic_reload=%s", thisfn, pivot->private->automatic_reload ? "True":"False" );
+		g_debug( "%s:       population=%d", thisfn, pivot->private->population );
 
 		for( it = pivot->private->tree, i = 0 ; it ; it = it->next ){
 			g_debug( "%s:     [%d]: %p", thisfn, i++, it->data );
@@ -520,15 +498,15 @@ na_pivot_get_items( const NAPivot *pivot )
 }
 
 /**
- * na_pivot_reload_items:
+ * na_pivot_load_items:
  * @pivot: this #NAPivot instance.
  *
- * Reloads the hierarchical list of items from I/O providers.
+ * Loads the hierarchical list of items from I/O providers.
  */
 void
-na_pivot_reload_items( NAPivot *pivot )
+na_pivot_load_items( NAPivot *pivot )
 {
-	static const gchar *thisfn = "na_pivot_reload_items";
+	static const gchar *thisfn = "na_pivot_load_items";
 	GSList *messages, *im;
 
 	g_debug( "%s: pivot=%p", thisfn, ( void * ) pivot );
@@ -754,6 +732,69 @@ na_pivot_set_automatic_reload( NAPivot *pivot, gboolean reload )
 }
 
 /**
+ * na_pivot_set_population:
+ * @pivot: this #NAPivot instance.
+ * @population: an indicator of the population to be loaded.
+ *
+ * @population may be a OR of PIVOT_LOAD_DISABLED and PIVOT_LOAD_INVALID.
+ * It is initialized to PIVOT_LOAD_DISABLED | PIVOT_LOAD_INVALID,
+ * which mean 'loads all'.
+ */
+void
+na_pivot_set_population( NAPivot *pivot, gint population )
+{
+	g_return_if_fail( NA_IS_PIVOT( pivot ));
+
+	if( !pivot->private->dispose_has_run ){
+		pivot->private->population = population;
+	}
+}
+
+/**
+ * na_pivot_is_disable_loadable:
+ * @pivot: this #NAPivot instance.
+ *
+ * Returns: %TRUE if disabled items should be loaded, %FALSE else.
+ */
+gboolean
+na_pivot_is_disable_loadable( const NAPivot *pivot )
+{
+	gboolean is_loadable;
+
+	is_loadable = FALSE;
+	g_return_val_if_fail( NA_IS_PIVOT( pivot ), is_loadable );
+
+	if( !pivot->private->dispose_has_run ){
+
+		is_loadable = ( pivot->private->population & PIVOT_LOAD_DISABLED );
+	}
+
+	return( is_loadable );
+}
+
+/**
+ * na_pivot_is_invalid_loadable:
+ * @pivot: this #NAPivot instance.
+ *
+ * Returns: %TRUE if invalid items should be loaded, %FALSE else.
+ */
+gboolean
+na_pivot_is_invalid_loadable( const NAPivot *pivot )
+{
+	gboolean is_loadable;
+
+	is_loadable = FALSE;
+	g_return_val_if_fail( NA_IS_PIVOT( pivot ), is_loadable );
+
+	if( !pivot->private->dispose_has_run ){
+
+		is_loadable = ( pivot->private->population & PIVOT_LOAD_INVALID );
+	}
+
+	return( is_loadable );
+}
+
+/**
  * na_pivot_sort_alpha_asc:
  * @a: first #NAObjectId.
  * @b: second #NAObjectId.
@@ -885,8 +926,7 @@ on_item_changed_timeout( NAPivot *pivot )
 	}
 
 	if( pivot->private->automatic_reload ){
-		na_pivot_reload_items( pivot );
-		na_pivot_check_status( pivot );
+		na_pivot_load_items( pivot );
 	}
 
 	for( ic = pivot->private->consumers ; ic ; ic = ic->next ){
diff --git a/nautilus-actions/runtime/na-pivot.h b/nautilus-actions/runtime/na-pivot.h
index 44a42c0..331bacc 100644
--- a/nautilus-actions/runtime/na-pivot.h
+++ b/nautilus-actions/runtime/na-pivot.h
@@ -109,8 +109,14 @@ typedef struct {
 
 GType         na_pivot_get_type( void );
 
+enum {
+	PIVOT_LOAD_DISABLED = 1 << 0,
+	PIVOT_LOAD_INVALID  = 1 << 1,
+	PIVOT_LOAD_ALL      = 0xff,
+};
+
+
 NAPivot      *na_pivot_new( void );
-void          na_pivot_check_status( const NAPivot *pivot );
 void          na_pivot_dump( const NAPivot *pivot );
 
 void          na_pivot_item_changed_handler( NAIIOProvider *provider, const gchar *id, NAPivot *pivot );
@@ -123,7 +129,7 @@ void          na_pivot_release_provider( const GObject *provider );
 void          na_pivot_free_providers( GList *providers );
 
 GList        *na_pivot_get_items( const NAPivot *pivot );
-void          na_pivot_reload_items( NAPivot *pivot );
+void          na_pivot_load_items( NAPivot *pivot );
 
 void          na_pivot_add_item( NAPivot *pivot, const NAObjectItem *item );
 NAObjectItem *na_pivot_get_item( const NAPivot *pivot, const gchar *uuid );
@@ -137,6 +143,10 @@ void          na_pivot_register_consumer( NAPivot *pivot, const NAIPivotConsumer
 gboolean      na_pivot_get_automatic_reload( const NAPivot *pivot );
 void          na_pivot_set_automatic_reload( NAPivot *pivot, gboolean reload );
 
+void          na_pivot_set_population( NAPivot *pivot, gint population );
+gboolean      na_pivot_is_disable_loadable( const NAPivot *pivot );
+gboolean      na_pivot_is_invalid_loadable( const NAPivot *pivot );
+
 gint          na_pivot_sort_alpha_asc( const NAObjectId *a, const NAObjectId *b );
 gint          na_pivot_sort_alpha_desc( const NAObjectId *a, const NAObjectId *b );
 



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