[nautilus-actions] Refactoring: update NactIActionsList interface



commit e0612c40ae78fe1637e9edc96719d0b8402f982e
Author: Pierre Wieser <pwieser trychlos org>
Date:   Wed Feb 17 12:57:32 2010 +0100

    Refactoring: update NactIActionsList interface

 ChangeLog                         |   12 ++++
 src/api/na-iduplicable.h          |    8 +--
 src/api/na-object-api.h           |    4 +
 src/api/na-object-item.h          |    2 +
 src/api/na-object.h               |   14 +++--
 src/core/na-iduplicable.c         |  112 ++++++++++++++++++++-----------------
 src/core/na-object-item.c         |   24 ++++++++
 src/core/na-object.c              |   85 ++++++++++++++++++++++++++++
 src/nact/nact-iactions-list-bis.c |    4 +-
 src/nact/nact-iactions-list.c     |   13 ++---
 src/nact/nact-window.c            |  102 ++++++++++++++++++++++++++++++++-
 src/nact/nact-window.h            |    6 +-
 12 files changed, 308 insertions(+), 78 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 84b0b79..dd1ec69 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -3,6 +3,18 @@
 	* src/api/na-iduplicable.h:
 	* src/api/na-object-api.h:
 	* src/api/na-object-item.h:
+	* src/api/na-object.h:
+	* src/core/na-iduplicable.c:
+	* src/core/na-object-item.c:
+	* src/core/na-object.c:
+	* src/nact/nact-iactions-list-bis.c:
+	* src/nact/nact-iactions-list.c:
+	* src/nact/nact-window.c:
+	* src/nact/nact-window.h: Update NactIActionsList interface.
+
+	* src/api/na-iduplicable.h:
+	* src/api/na-object-api.h:
+	* src/api/na-object-item.h:
 	* src/core/na-exporter.c:
 	* src/core/na-exporter.h:
 	* src/core/na-iduplicable.c:
diff --git a/src/api/na-iduplicable.h b/src/api/na-iduplicable.h
index f935e4c..f1f2891 100644
--- a/src/api/na-iduplicable.h
+++ b/src/api/na-iduplicable.h
@@ -137,17 +137,15 @@ void           na_iduplicable_check_status( const NAIDuplicable *object );
 
 NAIDuplicable *na_iduplicable_get_origin  ( const NAIDuplicable *object );
 gboolean       na_iduplicable_is_valid    ( const NAIDuplicable *object );
+gboolean       na_iduplicable_is_modified ( const NAIDuplicable *object );
 
 void           na_iduplicable_set_origin  ( NAIDuplicable *object, const NAIDuplicable *origin );
 
+void           na_iduplicable_register_consumer( GObject *consumer );
+
 #if 0
 void           na_iduplicable_init        ( NAIDuplicable *object );
-
 void           na_iduplicable_reset_status( NAIDuplicable *object );
-
-gboolean       na_iduplicable_is_modified( const NAIDuplicable *object );
-
-void           na_iduplicable_register_consumer( GObject *consumer );
 #endif
 
 G_END_DECLS
diff --git a/src/api/na-object-api.h b/src/api/na-object-api.h
index 36ab01e..8b8b91e 100644
--- a/src/api/na-object-api.h
+++ b/src/api/na-object-api.h
@@ -54,9 +54,11 @@ G_BEGIN_DECLS
  */
 #define na_object_duplicate( obj )						na_iduplicable_duplicate( NA_IDUPLICABLE( obj ))
 #define na_object_check_status( obj )					na_object_object_check_status( NA_OBJECT( obj ))
+#define na_object_check_status_up( obj )				na_object_object_check_status_up( NA_OBJECT( obj ))
 
 #define na_object_get_origin( obj )						na_iduplicable_get_origin( NA_IDUPLICABLE( obj ))
 #define na_object_is_valid( obj )						na_iduplicable_is_valid( NA_IDUPLICABLE( obj ))
+#define na_object_is_modified( obj )					na_iduplicable_is_modified( NA_IDUPLICABLE( obj ))
 
 #define na_object_set_origin( obj, origin )				na_iduplicable_set_origin( NA_IDUPLICABLE( obj ), ( NAIDuplicable * )( origin ))
 
@@ -66,6 +68,7 @@ G_BEGIN_DECLS
 #define na_object_dump_norec( obj )						na_object_object_dump_norec( NA_OBJECT( obj ))
 #define na_object_dump_tree( tree )						na_object_object_dump_tree( tree )
 #define na_object_get_hierarchy( obj )					na_object_object_get_hierarchy( NA_OBJECT( obj ))
+#define na_object_ref( obj )							na_object_object_ref( NA_OBJECT( obj ))
 #define na_object_unref( obj )							na_object_object_unref( NA_OBJECT( obj ))
 
 /* NAObjectId
@@ -104,6 +107,7 @@ G_BEGIN_DECLS
 #define na_object_get_item( obj, id )					na_object_item_get_item( NA_OBJECT_ITEM( obj ),( const gchar * )( id ))
 #define na_object_append_item( obj, child )				na_object_item_append_item( NA_OBJECT_ITEM( obj ), NA_OBJECT_ID( child ))
 #define na_object_build_items_slist( obj )				na_object_item_build_items_slist( NA_OBJECT_ITEM( obj ))
+#define na_object_get_items_count( obj )				na_object_item_get_items_count( NA_OBJECT_ITEM( obj ))
 #define na_object_count_items( list, cm, ca, cp, brec )	na_object_item_count_items( list, ( cm ), ( ca ), ( cp ), ( brec ))
 #define na_object_unref_items( tree )					na_object_item_unref_items( tree )
 
diff --git a/src/api/na-object-item.h b/src/api/na-object-item.h
index 3df9579..b1dd45b 100644
--- a/src/api/na-object-item.h
+++ b/src/api/na-object-item.h
@@ -85,6 +85,8 @@ void        na_object_item_append_item( NAObjectItem *object, const NAObjectId *
 
 GSList     *na_object_item_build_items_slist( const NAObjectItem *item );
 
+guint       na_object_item_get_items_count( const NAObjectItem *item );
+
 void        na_object_item_count_items( GList *items, gint *menus, gint *actions, gint *profiles, gboolean recurse );
 void        na_object_item_unref_items( GList *items );
 
diff --git a/src/api/na-object.h b/src/api/na-object.h
index ebf2185..de77be8 100644
--- a/src/api/na-object.h
+++ b/src/api/na-object.h
@@ -133,15 +133,17 @@ typedef struct {
 }
 	NAObjectClass;
 
-GType  na_object_object_get_type( void );
+GType     na_object_object_get_type( void );
 
-void   na_object_object_check_status( const NAObject *object );
+void      na_object_object_check_status   ( const NAObject *object );
+gboolean  na_object_object_check_status_up( const NAObject *object );
 
-void   na_object_object_unref( NAObject *object );
+NAObject *na_object_object_ref  ( NAObject *object );
+void      na_object_object_unref( NAObject *object );
 
-void   na_object_object_dump      ( const NAObject *object );
-void   na_object_object_dump_norec( const NAObject *object );
-void   na_object_object_dump_tree ( GList *tree );
+void      na_object_object_dump      ( const NAObject *object );
+void      na_object_object_dump_norec( const NAObject *object );
+void      na_object_object_dump_tree ( GList *tree );
 
 #if 0
 GList *na_object_object_get_hierarchy( const NAObject *object );
diff --git a/src/core/na-iduplicable.c b/src/core/na-iduplicable.c
index 621d53e..e516c0b 100644
--- a/src/core/na-iduplicable.c
+++ b/src/core/na-iduplicable.c
@@ -84,10 +84,11 @@ static gboolean       set_modified( const NAIDuplicable *object, gboolean is_mod
 static void           set_origin( const NAIDuplicable *object, const NAIDuplicable *origin );
 static gboolean       set_valid( const NAIDuplicable *object, gboolean is_valid );
 
+#endif
+
 static void           status_changed_handler( NAIDuplicable *instance, gpointer user_data );
 static void           propagate_signal_to_consumers( const gchar *signal, NAIDuplicable *instance, gpointer user_data );
 static void           release_signal_consumers( GList *consumers );
-#endif
 
 GType
 na_iduplicable_get_type( void )
@@ -180,9 +181,7 @@ interface_base_finalize( NAIDuplicableInterface *klass )
 
 		st_finalized = TRUE;
 
-#if 0
 		release_signal_consumers( klass->private->consumers );
-#endif
 
 		g_free( klass->private );
 	}
@@ -213,10 +212,16 @@ na_iduplicable_init( NAIDuplicable *object )
 		str->modified = FALSE;
 		str->valid = TRUE;
 
+		str->status_changed_handler_id = g_signal_connect(
+				G_OBJECT( object ),
+				NA_IDUPLICABLE_SIGNAL_STATUS_CHANGED,
+				G_CALLBACK( status_changed_handler ),
+				object );
+
 		g_object_set_data( G_OBJECT( object ), NA_IDUPLICABLE_DATA_DUPLICABLE, str );
 	}
 }
-#endif
+ #endif
 
 /**
  * na_iduplicable_dispose:
@@ -411,8 +416,6 @@ na_iduplicable_get_origin( const NAIDuplicable *object )
 gboolean
 na_iduplicable_is_valid( const NAIDuplicable *object )
 {
-	/*static const gchar *thisfn = "na_iduplicable_is_valid";
-	g_debug( "%s: object=%p", thisfn, object );*/
 	gboolean is_valid;
 	DuplicableStr *str;
 
@@ -430,6 +433,35 @@ na_iduplicable_is_valid( const NAIDuplicable *object )
 }
 
 /**
+ * na_iduplicable_is_modified:
+ * @object: the #NAIDuplicable object whose status is to be returned.
+ *
+ * Returns the current value of the %PROP_IDUPLICABLE_ISMODIFIED
+ * property without rechecking the edition status itself.
+ *
+ * Returns: %TRUE is the provided object has been modified regarding of
+ * the original one.
+ */
+gboolean
+na_iduplicable_is_modified( const NAIDuplicable *object )
+{
+	gboolean is_modified;
+	DuplicableStr *str;
+
+	g_return_val_if_fail( NA_IS_IDUPLICABLE( object ), FALSE );
+
+	is_modified = FALSE;
+
+	if( st_initialized && !st_finalized ){
+
+		str = get_duplicable_str( object );
+		is_modified = str->modified;
+	}
+
+	return( is_modified );
+}
+
+/**
  * na_iduplicable_set_origin:
  * @object: the #NAIDuplicable object whose origin is to be set.
  * @origin: the new original #NAIDuplicable.
@@ -479,48 +511,6 @@ v_is_valid( const NAIDuplicable *object )
 	return( FALSE );
 }
 
-#if 0
-/**
- * na_iduplicable_reset_status:
- * @object: the #NAIDuplicable object whose status is to be reset.
- *
- * Reset validity and modification status of the object.
- */
-void
-na_iduplicable_reset_status( NAIDuplicable *object )
-{
-	g_return_if_fail( st_initialized && !st_finalized );
-	g_return_if_fail( NA_IS_IDUPLICABLE( object ));
-
-	set_valid( object, TRUE );
-	set_modified( object, FALSE );
-}
-
-/**
- * na_iduplicable_is_modified:
- * @object: the #NAIDuplicable object whose status is to be returned.
- *
- * Returns the current value of the %PROP_IDUPLICABLE_ISMODIFIED
- * property without rechecking the edition status itself.
- *
- * Returns: %TRUE is the provided object has been modified regarding of
- * the original one.
- */
-gboolean
-na_iduplicable_is_modified( const NAIDuplicable *object )
-{
-	/*static const gchar *thisfn = "na_iduplicable_is_modified";
-	g_debug( "%s: object=%p", thisfn, object );*/
-	gboolean is_modified = FALSE;
-
-	g_return_val_if_fail( st_initialized && !st_finalized, FALSE );
-	g_return_val_if_fail( NA_IS_IDUPLICABLE( object ), FALSE );
-
-	is_modified = get_modified( object );
-
-	return( is_modified );
-}
-
 /**
  * na_iduplicable_register_consumer:
  * @consumer: the target instance.
@@ -532,12 +522,30 @@ void
 na_iduplicable_register_consumer( GObject *consumer )
 {
 	if( st_initialized && !st_finalized ){
+
 		g_return_if_fail( st_interface );
 		g_debug( "na_iduplicable_register_consumer: consumer=%p", ( void * ) consumer );
 		st_interface->private->consumers = g_list_prepend( st_interface->private->consumers, consumer );
 	}
 }
 
+#if 0
+/**
+ * na_iduplicable_reset_status:
+ * @object: the #NAIDuplicable object whose status is to be reset.
+ *
+ * Reset validity and modification status of the object.
+ */
+void
+na_iduplicable_reset_status( NAIDuplicable *object )
+{
+	g_return_if_fail( st_initialized && !st_finalized );
+	g_return_if_fail( NA_IS_IDUPLICABLE( object ));
+
+	set_valid( object, TRUE );
+	set_modified( object, FALSE );
+}
+
 static NAIDuplicable *
 v_new( const NAIDuplicable *object )
 {
@@ -619,6 +627,7 @@ set_valid( const NAIDuplicable *object, gboolean is_valid )
 
 	return( was_valid );
 }
+#endif
 
 static void
 status_changed_handler( NAIDuplicable *instance, gpointer user_data )
@@ -639,8 +648,10 @@ propagate_signal_to_consumers( const gchar *signal, NAIDuplicable *instance, gpo
 	GList *ic;
 
 	if( st_initialized && !st_finalized ){
+
 		g_return_if_fail( st_interface );
 		for( ic = st_interface->private->consumers ; ic ; ic = ic->next ){
+
 			g_signal_emit_by_name( ic->data, signal, user_data );
 		}
 	}
@@ -651,7 +662,6 @@ release_signal_consumers( GList *consumers )
 {
 	g_list_free( consumers );
 }
-#endif
 
 static DuplicableStr *
 get_duplicable_str( const NAIDuplicable *object )
@@ -667,13 +677,11 @@ get_duplicable_str( const NAIDuplicable *object )
 		str->modified = FALSE;
 		str->valid = TRUE;
 
-#if 0
 		str->status_changed_handler_id = g_signal_connect(
 				G_OBJECT( object ),
 				NA_IDUPLICABLE_SIGNAL_STATUS_CHANGED,
 				G_CALLBACK( status_changed_handler ),
-				object );
-#endif
+				( gpointer ) object );
 
 		g_object_set_data( G_OBJECT( object ), NA_IDUPLICABLE_DATA_DUPLICABLE, str );
 	}
diff --git a/src/core/na-object-item.c b/src/core/na-object-item.c
index ad1b72b..99e2896 100644
--- a/src/core/na-object-item.c
+++ b/src/core/na-object-item.c
@@ -424,6 +424,30 @@ na_object_item_build_items_slist( const NAObjectItem *item )
 }
 
 /**
+ * na_object_item_get_items_count:
+ * @item: the #NAObjectItem from which we want a count of subitems.
+ *
+ * Returns: the count of subitems of @item.
+ */
+guint
+na_object_item_get_items_count( const NAObjectItem *item )
+{
+	guint count = 0;
+	GList *childs;
+
+	/*g_debug( "na_object_item_get_items_count: item=%p (%s)", ( void * ) item, G_OBJECT_TYPE_NAME( item ));*/
+	g_return_val_if_fail( NA_IS_OBJECT_ITEM( item ), 0 );
+
+	if( !item->private->dispose_has_run ){
+
+		childs = na_object_get_items( item );
+		count = childs ? g_list_length( childs ) : 0;
+	}
+
+	return( count );
+}
+
+/**
  * na_object_item_count_items:
  * @items: a list if #NAObject-derived to be counted.
  * @menus: will be set to the count of menus.
diff --git a/src/core/na-object.c b/src/core/na-object.c
index 3c3ce68..7dd0478 100644
--- a/src/core/na-object.c
+++ b/src/core/na-object.c
@@ -387,6 +387,55 @@ na_object_object_check_status( const NAObject *object )
 }
 
 /**
+ * na_object_object_check_status_up:
+ * @object: the object at the start of the hierarchy.
+ *
+ * Checks for modification and validity status of the @object, its
+ * parent, the parent of its parent, etc. up to the top of the hierarchy.
+ *
+ * Returns: %TRUE if at least one of the status has changed, %FALSE else.
+ *
+ * Checking the modification of any of the status should be more
+ * efficient that systematically force the display of the item.
+ */
+gboolean
+na_object_object_check_status_up( const NAObject *object )
+{
+	gboolean changed;
+	gboolean was_modified, is_modified;
+	gboolean was_valid, is_valid;
+	NAObjectItem *parent;
+
+	g_return_val_if_fail( NA_OBJECT( object ), FALSE );
+
+	changed = FALSE;
+
+	if( !object->private->dispose_has_run ){
+
+		was_modified = na_object_is_modified( object );
+		was_valid = na_object_is_valid( object );
+
+		na_iduplicable_check_status( NA_IDUPLICABLE( object ));
+
+		is_modified = na_object_is_modified( object );
+		is_valid = na_object_is_valid( object );
+
+		parent = na_object_get_parent( object );
+		if( parent ){
+			na_object_check_status_up( parent );
+		}
+
+		changed =
+			( was_modified && !is_modified ) ||
+			( !was_modified && is_modified ) ||
+			( was_valid && !is_valid ) ||
+			( !was_valid && is_valid );
+	}
+
+	return( changed );
+}
+
+/**
  * na_object_object_dump:
  * @object: the #NAObject-derived object to be dumped.
  *
@@ -530,6 +579,42 @@ na_object_object_get_hierarchy( const NAObject *object )
 #endif
 
 /**
+ * na_object_object_ref:
+ * @object: a #NAObject-derived object.
+ *
+ * Recursively ref the @object and all its children, incrementing their
+ * reference_count by 1.
+ *
+ * Returns: a reference on the @pbject.
+ */
+NAObject *
+na_object_object_ref( NAObject *object )
+{
+	NAObject *ref = NULL;
+	GList *childs, *ic;
+
+	g_debug( "na_object_object_ref: object=%p (%s, ref_count=%d)",
+			( void * ) object, G_OBJECT_TYPE_NAME( object ), G_OBJECT( object )->ref_count );
+	g_return_val_if_fail( NA_IS_OBJECT( object ), NULL );
+
+	if( !object->private->dispose_has_run ){
+
+		if( NA_IS_OBJECT_ITEM( object )){
+
+			childs = na_object_get_items( object );
+			for( ic = childs ; ic ; ic = ic->next ){
+
+				na_object_ref( ic->data );
+			}
+		}
+
+		ref = g_object_ref( object );
+	}
+
+	return( ref );
+}
+
+/**
  * na_object_object_unref:
  * @object: a #NAObject-derived object.
  *
diff --git a/src/nact/nact-iactions-list-bis.c b/src/nact/nact-iactions-list-bis.c
index f8880cc..8ef39ba 100644
--- a/src/nact/nact-iactions-list-bis.c
+++ b/src/nact/nact-iactions-list-bis.c
@@ -811,7 +811,7 @@ do_insert_items( GtkTreeView *treeview, GtkTreeModel *model, GList *items, GtkTr
 		 */
 		if( NA_IS_OBJECT_ITEM( it->data ) && na_object_get_items_count( it->data )){
 
-			subitems = na_object_get_items_list( it->data );
+			subitems = na_object_get_items( it->data );
 			do_insert_into_first( treeview, model, subitems, inserted_path, NULL );
 		}
 
@@ -851,7 +851,7 @@ do_insert_into_first( GtkTreeView *treeview, GtkTreeModel *model, GList *items,
 	 */
 	if( NA_IS_OBJECT_ITEM( last->data ) && na_object_get_items_count( last->data )){
 
-		subitems = na_object_get_items_list( last->data );
+		subitems = na_object_get_items( last->data );
 		do_insert_into_first( treeview, model, subitems, inserted_path, NULL );
 	}
 
diff --git a/src/nact/nact-iactions-list.c b/src/nact/nact-iactions-list.c
index 66e19c9..00e483c 100644
--- a/src/nact/nact-iactions-list.c
+++ b/src/nact/nact-iactions-list.c
@@ -33,11 +33,10 @@
 #endif
 
 #include <gdk/gdkkeysyms.h>
+#include <glib/gi18n.h>
 
 #include <api/na-object-api.h>
 
-#include <private/na-iduplicable.h>
-
 #include "base-window.h"
 #include "nact-main-menubar.h"
 #include "nact-main-tab.h"
@@ -293,7 +292,7 @@ free_items_callback( NactIActionsList *instance, GList *items )
 	g_debug( "nact_iactions_list_free_items_callback: selection=%p (%d items)",
 			( void * ) items, g_list_length( items ));
 
-	na_object_free_items_list( items );
+	na_object_unref_items( items );
 }
 
 static void
@@ -797,7 +796,7 @@ nact_iactions_list_remove_rec( GList *list, NAObject *object )
 	GList *subitems, *it;
 
 	if( NA_IS_OBJECT_ITEM( object )){
-		subitems = na_object_get_items_list( object );
+		subitems = na_object_get_items( object );
 		for( it = subitems ; it ; it = it->next ){
 			list = nact_iactions_list_remove_rec( list, it->data );
 		}
@@ -855,7 +854,6 @@ display_label( GtkTreeViewColumn *column, GtkCellRenderer *cell, GtkTreeModel *m
 	gboolean valid = TRUE;
 	IActionsListInstanceData *ialid;
 	NAObjectItem *item;
-	NAPivot *pivot;
 	gboolean writable_item;
 
 	gtk_tree_model_get( model, iter, IACTIONS_LIST_NAOBJECT_COLUMN, &object, -1 );
@@ -872,8 +870,7 @@ display_label( GtkTreeViewColumn *column, GtkCellRenderer *cell, GtkTreeModel *m
 		modified = na_object_is_modified( object );
 		valid = na_object_is_valid( object );
 		item = NA_IS_OBJECT_PROFILE( object ) ? na_object_get_parent( object ) : NA_OBJECT_ITEM( object );
-		pivot = nact_window_get_pivot( NACT_WINDOW( instance ));
-		writable_item = na_pivot_is_item_writable( pivot, item, NULL );
+		writable_item = nact_window_is_item_writable( NACT_WINDOW( instance ), item, NULL );
 
 		if( modified ){
 			g_object_set( cell, "style", PANGO_STYLE_ITALIC, "style-set", TRUE, NULL );
@@ -1020,7 +1017,7 @@ filter_selection_set_implicitely_selected_childs( NAObject *object, gboolean sel
 	GList *childs, *ic;
 
 	if( NA_IS_OBJECT_ITEM( object )){
-		childs = na_object_get_items_list( object );
+		childs = na_object_get_items( object );
 		for( ic = childs ; ic ; ic = ic->next ){
 			g_object_set_data( G_OBJECT( ic->data ), "nact-implicit-selection", GUINT_TO_POINTER(( guint ) select ));
 			filter_selection_set_implicitely_selected_childs( NA_OBJECT( ic->data ), select );
diff --git a/src/nact/nact-window.c b/src/nact/nact-window.c
index 243f90f..af2d3b1 100644
--- a/src/nact/nact-window.c
+++ b/src/nact/nact-window.c
@@ -35,12 +35,12 @@
 #include <glib.h>
 #include <glib/gi18n.h>
 
+#include <api/na-core-utils.h>
 #include <api/na-iio-provider.h>
 #include <api/na-object-api.h>
 
-#include <runtime/na-io-provider.h>
-#include <runtime/na-iprefs.h>
-#include <runtime/na-utils.h>
+#include <core/na-io-provider.h>
+#include <core/na-iprefs.h>
 
 #include "nact-application.h"
 #include "nact-window.h"
@@ -174,6 +174,7 @@ instance_finalize( GObject *window )
 	}
 }
 
+#if 0
 /**
  * nact_window_get_pivot:
  * @window: this #NactWindow object.
@@ -199,6 +200,7 @@ nact_window_get_pivot( NactWindow *window )
 
 	return( pivot );
 }
+#endif
 
 /**
  * nact_window_has_writable_providers:
@@ -231,6 +233,100 @@ nact_window_has_writable_providers( NactWindow *window )
 }
 
 /**
+ * nact_window_is_item_writable:
+ * @window: this #NactWindow object.
+ * @item: the #NAObjectItem to be evaluated.
+ * @reason: the reason for what @item may not be writable.
+ *
+ * Returns: %TRUE: if @item is actually writable, given the current
+ * status of its provider, %FALSE else.
+ *
+ * For an item be actually writable:
+ * - the item must not be itself in a read-only store, which has been
+ *   checked when first reading it
+ * - the provider must be willing (resp. able) to write
+ * - the provider must not has been locked by the admin
+ * - the writability of the provider must not have been removed by the user
+ * - the whole configuration must not have been locked by the admin.
+ */
+gboolean
+nact_window_is_item_writable( const NactWindow *window, const NAObjectItem *item, guint *reason )
+{
+	gboolean writable;
+	NAIOProvider *provider;
+
+	g_return_val_if_fail( NA_IS_PIVOT( pivot ), FALSE );
+	g_return_val_if_fail( NA_IS_OBJECT_ITEM( item ), FALSE );
+
+	writable = FALSE;
+	if( reason ){
+		*reason = NA_IIO_PROVIDER_STATUS_UNDETERMINED;
+	}
+
+	if( !pivot->private->dispose_has_run ){
+
+		writable = TRUE;
+		if( reason ){
+			*reason = NA_IIO_PROVIDER_STATUS_WRITABLE;
+		}
+
+		if( writable ){
+			if( na_object_is_readonly( item )){
+				writable = FALSE;
+				if( reason ){
+					*reason = NA_IIO_PROVIDER_STATUS_ITEM_READONLY;
+				}
+			}
+		}
+
+		if( writable ){
+			provider = na_object_get_provider( item );
+			if( provider ){
+				if( !na_io_provider_is_willing_to_write( provider )){
+					writable = FALSE;
+					if( reason ){
+						*reason = NA_IIO_PROVIDER_STATUS_PROVIDER_NOT_WILLING_TO;
+					}
+				} else if( na_io_provider_is_locked_by_admin( provider, pivot )){
+					writable = FALSE;
+					if( reason ){
+						*reason = NA_IIO_PROVIDER_STATUS_PROVIDER_LOCKED_BY_ADMIN;
+					}
+				} else if( !na_io_provider_is_user_writable( provider, pivot )){
+					writable = FALSE;
+					if( reason ){
+						*reason = NA_IIO_PROVIDER_STATUS_PROVIDER_LOCKED_BY_USER;
+					}
+				} else if( na_pivot_is_configuration_locked_by_admin( pivot )){
+					writable = FALSE;
+					if( reason ){
+						*reason = NA_IIO_PROVIDER_STATUS_CONFIGURATION_LOCKED_BY_ADMIN;
+					}
+				} else if( !na_io_provider_has_write_api( provider )){
+					writable = FALSE;
+					if( reason ){
+						*reason = NA_IIO_PROVIDER_STATUS_NO_API;
+					}
+				}
+
+			/* the get_writable_provider() api already takes above checks
+			 */
+			} else {
+				provider = na_io_provider_get_writable_provider( pivot );
+				if( !provider ){
+					writable = FALSE;
+					if( reason ){
+						*reason = NA_IIO_PROVIDER_STATUS_NO_PROVIDER_FOUND;
+					}
+				}
+			}
+		}
+	}
+
+	return( writable );
+}
+
+/**
  * nact_window_save_item:
  * @window: this #NactWindow instance.
  * @item: the #NAObjectItem to be saved.
diff --git a/src/nact/nact-window.h b/src/nact/nact-window.h
index 32a6972..8b4be29 100644
--- a/src/nact/nact-window.h
+++ b/src/nact/nact-window.h
@@ -42,7 +42,7 @@
 
 #include <api/na-object-item.h>
 
-#include <core/na-updater.h>
+/* #include <core/na-updater.h> */
 
 #include "base-window.h"
 
@@ -73,10 +73,12 @@ typedef struct {
 
 GType      nact_window_get_type( void );
 
-NAUpdater *nact_window_get_updater( NactWindow *window );
+/* NAUpdater *nact_window_get_updater( NactWindow *window ); */
 
 gboolean   nact_window_has_writable_providers( NactWindow *window );
 
+gboolean   nact_window_is_item_writable( const NactWindow *window, const NAObjectItem *item, guint *reason );
+
 gboolean   nact_window_save_item  ( NactWindow *window, NAObjectItem *item );
 gboolean   nact_window_delete_item( NactWindow *window, const NAObjectItem *item );
 



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