[nautilus-actions] Fix new action insertion



commit 025e873bbc2e8aa5df1a9b48c8a828c582c0d97d
Author: Pierre Wieser <pwieser trychlos org>
Date:   Sun Sep 20 17:24:40 2009 +0200

    Fix new action insertion

 ChangeLog                     |   14 +++
 src/common/na-object-item.c   |    8 +-
 src/nact/nact-iactions-list.c |   48 ++++++---
 src/nact/nact-main-menubar.c  |   12 +-
 src/nact/nact-tree-model.c    |  230 ++++++++++++++++++++++++++++++++++-------
 5 files changed, 252 insertions(+), 60 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 97deff7..b337b63 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -3,6 +3,10 @@
 	* src/common/na-object-item.c (object_id_new_id):
 	Function becomes recursive.
 
+	src/common/na-object-item.c
+	(na_object_item_append_item, na_object_item_insert_item):
+	Only append/insert child item if not already recorded.
+
 	* src/nact/nact-clipboard.c (renumber_items):
 	Removes recursivity as it is provided by the class.
 
@@ -14,10 +18,20 @@
 	nact_iactions_list_select_row(): no more a public function.
 	Fix row selection code.
 
+	* src/nact/nact-iactions-list.c (select_row_at_path):
+	Simulate a "selection-changed" signal emission with an empty selection
+	in nothing can be selected.
+
+	* src/nact/nact-iactions-list.c (do_insert_items):
+	Do not rely on iter after a store_to_filter_model conversion.
+
 	* src/nact/nact-main-menubar.c:
 	Reorganize code to avoid the need of delete_selection returning
 	a path to be selected.
 
+	* src/nact/nact-tree-model.c (nact_tree_model_insert):
+	Rewrite the code to make the computing process clearer.
+
 2009-09-19 Pierre Wieser <pwieser trychlos org>
 
 	* src/common/na-gconf-provider.c:
diff --git a/src/common/na-object-item.c b/src/common/na-object-item.c
index cf26197..0426209 100644
--- a/src/common/na-object-item.c
+++ b/src/common/na-object-item.c
@@ -706,7 +706,9 @@ na_object_item_append_item( NAObjectItem *item, const NAObject *object )
 	g_return_if_fail( !item->private->dispose_has_run );
 	g_return_if_fail( NA_IS_OBJECT( object ));
 
-	item->private->items = g_list_append( item->private->items, g_object_ref(( gpointer ) object ));
+	if( !g_list_find( item->private->items, ( gpointer ) object )){
+		item->private->items = g_list_append( item->private->items, g_object_ref(( gpointer ) object ));
+	}
 }
 
 /**
@@ -726,7 +728,9 @@ na_object_item_insert_item( NAObjectItem *item, const NAObject *object )
 	g_return_if_fail( !item->private->dispose_has_run );
 	g_return_if_fail( NA_IS_OBJECT( object ));
 
-	item->private->items = g_list_prepend( item->private->items, g_object_ref(( gpointer ) object ));
+	if( !g_list_find( item->private->items, ( gpointer ) object )){
+		item->private->items = g_list_prepend( item->private->items, g_object_ref(( gpointer ) object ));
+	}
 }
 
 /**
diff --git a/src/nact/nact-iactions-list.c b/src/nact/nact-iactions-list.c
index 8a9c732..8d23fc4 100644
--- a/src/nact/nact-iactions-list.c
+++ b/src/nact/nact-iactions-list.c
@@ -121,7 +121,7 @@ static void         on_iactions_list_item_updated( NactIActionsList *instance, N
 static void         on_iactions_list_item_updated_treeview( NactIActionsList *instance, NAObject *object );
 static void         on_iactions_list_selection_changed( NactIActionsList *instance, GSList *selected_items );
 static void         select_first_row( NactIActionsList *instance );
-static void         select_row_at_path( GtkTreeView *treeview, GtkTreeModel *model, GtkTreePath *path );
+static void         select_row_at_path( NactIActionsList *instance, GtkTreeView *treeview, GtkTreeModel *model, GtkTreePath *path );
 static void         set_selection_changed_mode( NactIActionsList *instance, gboolean authorized );
 static void         toggle_collapse( NactIActionsList *instance );
 static gboolean     toggle_collapse_iter( NactIActionsList *instance, GtkTreeView *treeview, GtkTreeModel *model, GtkTreeIter *iter, NAObject *object, gpointer user_data );
@@ -463,7 +463,7 @@ nact_iactions_list_delete_selection( NactIActionsList *instance )
 
 	if( path ){
 		gtk_tree_model_filter_refilter( GTK_TREE_MODEL_FILTER( model ));
-		select_row_at_path( treeview, model, path );
+		select_row_at_path( instance, treeview, model, path );
 		gtk_tree_path_free( path );
 	}
 }
@@ -672,12 +672,11 @@ nact_iactions_list_insert_items( NactIActionsList *instance, GList *items, NAObj
 		na_object_check_edition_status( it->data );
 	}
 
-	select_row_at_path( treeview, model, last_path );
+	gtk_tree_model_filter_refilter( GTK_TREE_MODEL_FILTER( model ));
+	select_row_at_path( instance, treeview, model, last_path );
 
 	gtk_tree_path_free( last_path );
 	gtk_tree_path_free( insert_path );
-
-	gtk_tree_model_filter_refilter( GTK_TREE_MODEL_FILTER( model ));
 }
 
 static GtkTreePath *
@@ -690,7 +689,6 @@ do_insert_items( GtkTreeView *treeview, GtkTreeModel *model, GList *items, GtkTr
 	GList *subitems;
 	GtkTreePath *newpath;
 	NAObject *obj_parent;
-	gchar *newpathstr;
 	GtkTreePath *returned_path;
 
 	returned_path = NULL;
@@ -705,8 +703,16 @@ do_insert_items( GtkTreeView *treeview, GtkTreeModel *model, GList *items, GtkTr
 
 		for( it = items ; it ; it = it->next ){
 
+			/* note that returned iter may have became invalid after conversion
+			 * from store to filter_model, and ran through filter_visible function
+			 * we so cannot rely on it if object is a profile inserted at level > 0
+			 */
 			nact_tree_model_insert( NACT_TREE_MODEL( model ), NA_OBJECT( it->data ), path, &iter, &obj_parent );
-			newpath = gtk_tree_model_get_path( model, &iter );
+
+			newpath = NULL;
+			if( !NA_IS_OBJECT_PROFILE( it->data ) || level == 0 ){
+				newpath = gtk_tree_model_get_path( model, &iter );
+			}
 
 			if( level == 0 ){
 				gtk_tree_view_expand_to_path( treeview, newpath );
@@ -716,17 +722,17 @@ do_insert_items( GtkTreeView *treeview, GtkTreeModel *model, GList *items, GtkTr
 
 			*parents = do_insert_items_add_parent( *parents, treeview, model, obj_parent );
 
-			newpathstr = gtk_tree_path_to_string( newpath );
-			g_debug( "%s: newpath=%s", thisfn, newpathstr );
-			g_free( newpathstr );
-
+			/* recursively insert subitems
+			 */
 			if( NA_IS_OBJECT_ITEM( it->data )){
 				subitems = na_object_get_items( it->data );
 				do_insert_items( treeview, model, subitems, newpath, level+1, parents );
 				na_object_free_items( subitems );
 			}
 
-			gtk_tree_path_free( newpath );
+			if( newpath ){
+				gtk_tree_path_free( newpath );
+			}
 		}
 	}
 
@@ -1289,7 +1295,7 @@ select_first_row( NactIActionsList *instance )
 	model = gtk_tree_view_get_model( treeview );
 
 	path = gtk_tree_path_new_from_string( "0" );
-	select_row_at_path( treeview, model, path );
+	select_row_at_path( instance, treeview, model, path );
 	gtk_tree_path_free( path );
 }
 
@@ -1302,34 +1308,46 @@ select_first_row( NactIActionsList *instance )
  * the immediate previous.
  */
 static void
-select_row_at_path( GtkTreeView *treeview, GtkTreeModel *model, GtkTreePath *path )
+select_row_at_path( NactIActionsList *instance, GtkTreeView *treeview, GtkTreeModel *model, GtkTreePath *path )
 {
 	GtkTreeSelection *selection;
 	GtkTreeIter iter;
+	gboolean anything = FALSE;
 
 	selection = gtk_tree_view_get_selection( treeview );
 	gtk_tree_selection_unselect_all( selection );
 
-	/*g_debug( "nact_iactions_list_select_row: path=%s", gtk_tree_path_to_string( path ));*/
+	g_debug( "nact_iactions_list_select_row_at_path: path=%s", gtk_tree_path_to_string( path ));
 
 	if( gtk_tree_model_get_iter( model, &iter, path )){
 		gtk_tree_view_set_cursor( treeview, path, NULL, FALSE );
+		anything = TRUE;
 
 	} else if( gtk_tree_path_prev( path ) && gtk_tree_model_get_iter( model, &iter, path )){
 		gtk_tree_view_set_cursor( treeview, path, NULL, FALSE );
+		anything = TRUE;
 
 	} else {
 		gtk_tree_path_next( path );
 		if( gtk_tree_model_get_iter( model, &iter, path )){
 			gtk_tree_view_set_cursor( treeview, path, NULL, FALSE );
+			anything = TRUE;
 
 		} else if( gtk_tree_path_get_depth( path ) > 1 &&
 					gtk_tree_path_up( path ) &&
 					gtk_tree_model_get_iter( model, &iter, path )){
 
 						gtk_tree_view_set_cursor( treeview, path, NULL, FALSE );
+						anything = TRUE;
 		}
 	}
+
+	/* if nothing can be selected, at least send a message with empty
+	 *  selection
+	 */
+	if( !anything ){
+		on_treeview_selection_changed( NULL, instance );
+	}
 }
 
 static void
diff --git a/src/nact/nact-main-menubar.c b/src/nact/nact-main-menubar.c
index 7908e58..22543a2 100644
--- a/src/nact/nact-main-menubar.c
+++ b/src/nact/nact-main-menubar.c
@@ -274,13 +274,13 @@ static void
 on_new_menu_activated( GtkAction *gtk_action, NactMainWindow *window )
 {
 	NAObjectMenu *menu;
-	GList *items = NULL;
+	GList *items;
 
 	g_return_if_fail( GTK_IS_ACTION( gtk_action ));
 	g_return_if_fail( NACT_IS_MAIN_WINDOW( window ));
 
 	menu = na_object_menu_new();
-	items = g_list_prepend( items, menu );
+	items = g_list_prepend( NULL, menu );
 	nact_iactions_list_insert_items( NACT_IACTIONS_LIST( window ), items, NULL );
 	na_object_free_items( items );
 }
@@ -289,13 +289,13 @@ static void
 on_new_action_activated( GtkAction *gtk_action, NactMainWindow *window )
 {
 	NAObjectAction *action;
-	GList *items = NULL;
+	GList *items;
 
 	g_return_if_fail( GTK_IS_ACTION( gtk_action ));
 	g_return_if_fail( NACT_IS_MAIN_WINDOW( window ));
 
 	action = na_object_action_new_with_profile();
-	items = g_list_prepend( items, action );
+	items = g_list_prepend( NULL, action );
 	nact_iactions_list_insert_items( NACT_IACTIONS_LIST( window ), items, NULL );
 	na_object_free_items( items );
 }
@@ -306,7 +306,7 @@ on_new_profile_activated( GtkAction *gtk_action, NactMainWindow *window )
 	NAObjectAction *action;
 	NAObjectProfile *profile;
 	gchar *name;
-	GList *items = NULL;
+	GList *items;
 
 	g_return_if_fail( GTK_IS_ACTION( gtk_action ));
 	g_return_if_fail( NACT_IS_MAIN_WINDOW( window ));
@@ -323,7 +323,7 @@ on_new_profile_activated( GtkAction *gtk_action, NactMainWindow *window )
 	na_object_profile_set_action( profile, action );
 	na_object_set_id( profile, name );
 
-	items = g_list_prepend( items, profile );
+	items = g_list_prepend( NULL, profile );
 	nact_iactions_list_insert_items( NACT_IACTIONS_LIST( window ), items, NULL );
 
 	na_object_free_items( items );
diff --git a/src/nact/nact-tree-model.c b/src/nact/nact-tree-model.c
index e0c47ca..8992695 100644
--- a/src/nact/nact-tree-model.c
+++ b/src/nact/nact-tree-model.c
@@ -145,11 +145,19 @@ static void           instance_finalize( GObject *application );
 
 static NactTreeModel *tree_model_new( BaseWindow *window, GtkTreeView *treeview );
 
+static void           fill_tree_store( GtkTreeStore *model, GtkTreeView *treeview, GList *items, gboolean only_actions, GtkTreeIter *parent );
+
+static void           insert_get_iters_action( GtkTreeModel *model, const NAObject *select_object, GtkTreePath *select_path, const NAObject *object, GtkTreeIter *parent_iter, gboolean *has_parent_iter, GtkTreeIter *sibling_iter, gboolean *has_sibling_iter, NAObject **parent_object );
+static void           insert_get_iters_profile( GtkTreeModel *model, const NAObject *select_object, GtkTreePath *select_path, const NAObject *object, GtkTreeIter *parent_iter, gboolean *has_parent_iter, GtkTreeIter *sibling_iter, gboolean *has_sibling_iter, NAObject **parent_object );
+static void           insert_get_iters_menu( GtkTreeModel *model, const NAObject *select_object, GtkTreePath *select_path, const NAObject *object, GtkTreeIter *parent_iter, gboolean *has_parent_iter, GtkTreeIter *sibling_iter, gboolean *has_sibling_iter, NAObject **parent_object );
+static void           insert_before_get_iters( GtkTreeModel *model,  GtkTreePath *select_path, const NAObject *object, GtkTreeIter *parent_iter, gboolean *has_parent_iter, GtkTreeIter *sibling_iter, gboolean *has_sibling_iter, NAObject **parent_object );
+static void           insert_before_parent_get_iters( GtkTreeModel *model,  GtkTreePath *select_path, const NAObject *object, GtkTreeIter *parent_iter, gboolean *has_parent_iter, GtkTreeIter *sibling_iter, gboolean *has_sibling_iter, NAObject **parent_object );
+static void           insert_as_last_child_get_iters( GtkTreeModel *model,  GtkTreePath *select_path, const NAObject *object, GtkTreeIter *parent_iter, gboolean *has_parent_iter, GtkTreeIter *sibling_iter, gboolean *has_sibling_iter, NAObject **parent_object );
+
 static GList         *add_parent( GList *parents, GtkTreeModel *store, GtkTreeIter *obj_iter, GtkTreePath *obj_path );
 static void           append_item( GtkTreeStore *model, GtkTreeView *treeview, GtkTreeIter *parent, GtkTreeIter *iter, const NAObject *object );
 static void           display_item( GtkTreeStore *model, GtkTreeView *treeview, GtkTreeIter *iter, const NAObject *object );
 static gboolean       dump_store( NactTreeModel *model, GtkTreePath *path, NAObject *object, ntmDumpStruct *ntm );
-static void           fill_tree_store( GtkTreeStore *model, GtkTreeView *treeview, GList *items, gboolean only_actions, GtkTreeIter *parent );
 static void           iter_on_store( NactTreeModel *model, GtkTreeModel *store, GtkTreeIter *parent, FnIterOnStore fn, gpointer user_data );
 static gboolean       iter_on_store_item( NactTreeModel *model, GtkTreeModel *store, GtkTreeIter *iter, FnIterOnStore fn, gpointer user_data );
 static gboolean       search_for_object( NactTreeModel *model, GtkTreeModel *store, const NAObject *object, GtkTreeIter *iter );
@@ -615,7 +623,26 @@ fill_tree_store( GtkTreeStore *model, GtkTreeView *treeview,
  * @iter: set to the new row
  * @obj_parent: set to the parent or the object itself.
  *
- * Insert new rows starting at the given position.
+ * Insert a new row at the given position.
+ *
+ * +--------------------+----------------------+----------------------+----------------------+
+ * | inserted object -> |        action        |        profile       |         menu         |
+ * +--------------------+----------------------+----------------------+----------------------+
+ * | currently selected |                      |                      |                      |
+ * |      |             |                      |                      |                      |
+ * |      v             |                      |                      |                      |
+ * |    (nil)           |    insert_before     |          n/a         |    insert_before     |
+ * |                    |                      |                      |                      |
+ * |   action           |    insert_before     | insert_as_last_child |    insert_before     |
+ * |                    |                      |                      |                      |
+ * |   profile          | insert_before_parent |    insert_before     | insert_before_parent |
+ * |                    |                      |                      |                      |
+ * |    menu            | insert_as_last_child |          n/a         | insert_as_last_child |
+ * +-----------------------------------------------------------------------------------------+
+ *
+ * insert_before       : parent=NULL     , sibling_from_path (or null if path was null)
+ * insert_before_parent: parent=NULL     , sibling_from_parent_path
+ * insert_as_last_child: parent_from_path, sibling=NULL
  */
 void
 nact_tree_model_insert( NactTreeModel *model, const NAObject *object, GtkTreePath *path, GtkTreeIter *iter, NAObject **obj_parent )
@@ -623,11 +650,13 @@ nact_tree_model_insert( NactTreeModel *model, const NAObject *object, GtkTreePat
 	static const gchar *thisfn = "nact_tree_model_insert";
 	gchar *path_str;
 	GtkTreeModel *store;
-	GtkTreeIter sibling;
-	GtkTreeIter *parent_iter;
 	GtkTreeIter select_iter;
+	NAObject *select_object;
+	GtkTreeIter parent_iter;
+	GtkTreeIter sibling_iter;
 	GtkTreeIter store_iter;
-	NAObject *selected;
+	gboolean has_parent_iter;
+	gboolean has_sibling_iter;
 
 	path_str = path ? gtk_tree_path_to_string( path ) : NULL;
 	g_debug( "%s: model=%p, object=%p (%s), path=%p (%s), iter=%p",
@@ -642,58 +671,182 @@ nact_tree_model_insert( NactTreeModel *model, const NAObject *object, GtkTreePat
 	g_return_if_fail( iter );
 
 	store = gtk_tree_model_filter_get_model( GTK_TREE_MODEL_FILTER( model ));
-	parent_iter = NULL;
+	has_parent_iter = FALSE;
+	has_sibling_iter = FALSE;
 	*obj_parent = NA_OBJECT( object );
 
 	if( path ){
 		gtk_tree_model_get_iter( GTK_TREE_MODEL( model ), &select_iter, path );
-		gtk_tree_model_get( GTK_TREE_MODEL( model ), &select_iter, IACTIONS_LIST_NAOBJECT_COLUMN, &selected, -1 );
+		gtk_tree_model_get( GTK_TREE_MODEL( model ), &select_iter, IACTIONS_LIST_NAOBJECT_COLUMN, &select_object, -1 );
 
-		g_return_if_fail( selected );
-		g_return_if_fail( NA_IS_OBJECT( selected ));
+		g_return_if_fail( select_object );
+		g_return_if_fail( NA_IS_OBJECT( select_object ));
 
-		if( NA_IS_OBJECT_ITEM( object )){
-			if( !NA_IS_OBJECT_ITEM( selected )){
-				gtk_tree_path_up( path );
-			}
-			gtk_tree_model_get_iter( store, &sibling, path );
-			if( NA_IS_OBJECT_MENU( selected )){
-				parent_iter = gtk_tree_iter_copy( &sibling );
-				na_object_insert_item( selected, object );
-				*obj_parent = selected;
-			}
+		if( NA_IS_OBJECT_ACTION( object )){
+			insert_get_iters_action( GTK_TREE_MODEL( store ), select_object, path, object, &parent_iter, &has_parent_iter, &sibling_iter, &has_sibling_iter, obj_parent );
 		}
 
 		if( NA_IS_OBJECT_PROFILE( object )){
-			if( NA_IS_OBJECT_ACTION( selected )){
-				/*g_debug( "nact_tree_model_insert_item: object_is_action_profile, selected_is_action" );*/
-				na_object_action_attach_profile( NA_OBJECT_ACTION( selected ), NA_OBJECT_PROFILE( object ));
-				gtk_tree_model_get_iter( store, &sibling, path );
-				parent_iter = gtk_tree_iter_copy( &sibling );
-				*obj_parent = selected;
-			} else {
-				g_return_if_fail( NA_IS_OBJECT_PROFILE( selected ));
-				*obj_parent = NA_OBJECT( na_object_profile_get_action( NA_OBJECT_PROFILE( object )));
-				gtk_tree_path_down( path );
-				gtk_tree_model_get_iter( store, &sibling, path );
-			}
+			insert_get_iters_profile( GTK_TREE_MODEL( store ), select_object, path, object, &parent_iter, &has_parent_iter, &sibling_iter, &has_sibling_iter, obj_parent );
 		}
 
-		g_object_unref( selected );
+		if( NA_IS_OBJECT_MENU( object )){
+			insert_get_iters_menu( GTK_TREE_MODEL( store ), select_object, path, object, &parent_iter, &has_parent_iter, &sibling_iter, &has_sibling_iter, obj_parent );
+		}
+
+		g_object_unref( select_object );
 
 	} else {
 		g_return_if_fail( NA_IS_OBJECT_ITEM( object ));
 	}
 
-	gtk_tree_store_insert_before( GTK_TREE_STORE( store ), &store_iter, parent_iter, parent_iter ? NULL : ( path ? &sibling : NULL ));
+	gtk_tree_store_insert_before( GTK_TREE_STORE( store ), &store_iter, has_parent_iter ? &parent_iter : NULL, has_sibling_iter ? &sibling_iter : NULL );
 	gtk_tree_store_set( GTK_TREE_STORE( store ), &store_iter, IACTIONS_LIST_NAOBJECT_COLUMN, object, -1 );
 	display_item( GTK_TREE_STORE( store ), model->private->treeview, &store_iter, object );
 
-	if( parent_iter ){
-		gtk_tree_iter_free( parent_iter );
+	gtk_tree_model_filter_convert_child_iter_to_iter( GTK_TREE_MODEL_FILTER( model ), iter, &store_iter );
+}
+
+static void
+insert_get_iters_action( GtkTreeModel *model, const NAObject *select_object, GtkTreePath *select_path, const NAObject *object, GtkTreeIter *parent_iter, gboolean *has_parent_iter, GtkTreeIter *sibling_iter, gboolean *has_sibling_iter, NAObject **parent_object )
+{
+	g_return_if_fail( NA_IS_OBJECT_ACTION( object ));
+
+	/* (insert_before)
+	 * insert action before selected action
+	 * if selected action has a parent :
+	 * - set parent_object to parent of selected action
+	 * - add object to subitems of parent of selected action
+	 */
+	if( NA_IS_OBJECT_ACTION( select_object )){
+		insert_before_get_iters( model, select_path, object, parent_iter, has_parent_iter, sibling_iter, has_sibling_iter, parent_object );
 	}
 
-	gtk_tree_model_filter_convert_child_iter_to_iter( GTK_TREE_MODEL_FILTER( model ), iter, &store_iter );
+	/* (insert_before_parent)
+	 * insert action before parent of selected profile
+	 * if parent of selected profile has itself a parent :
+	 * - set parent_object to parent of parent of selected profile
+	 * - add object to subitems of parent of parent of selected profile
+	 */
+	if( NA_IS_OBJECT_PROFILE( select_object )){
+		insert_before_parent_get_iters( model, select_path, object, parent_iter, has_parent_iter, sibling_iter, has_sibling_iter, parent_object );
+	}
+
+	/* (insert_as_last_child)
+	 */
+	if( NA_IS_OBJECT_MENU( select_object )){
+		insert_as_last_child_get_iters( model, select_path, object, parent_iter, has_parent_iter, sibling_iter, has_sibling_iter, parent_object );
+	}
+}
+
+static void
+insert_get_iters_profile( GtkTreeModel *model, const NAObject *select_object, GtkTreePath *select_path, const NAObject *object, GtkTreeIter *parent_iter, gboolean *has_parent_iter, GtkTreeIter *sibling_iter, gboolean *has_sibling_iter, NAObject **parent_object )
+{
+	g_return_if_fail( NA_IS_OBJECT_PROFILE( object ));
+
+	if( NA_IS_OBJECT_ACTION( select_object )){
+		insert_as_last_child_get_iters( model, select_path, object, parent_iter, has_parent_iter, sibling_iter, has_sibling_iter, parent_object );
+	}
+
+	if( NA_IS_OBJECT_PROFILE( select_object )){
+		insert_before_get_iters( model, select_path, object, parent_iter, has_parent_iter, sibling_iter, has_sibling_iter, parent_object );
+	}
+
+	if( NA_IS_OBJECT_MENU( select_object )){
+		g_return_if_reached();
+	}
+}
+
+static void
+insert_get_iters_menu( GtkTreeModel *model, const NAObject *select_object, GtkTreePath *select_path, const NAObject *object, GtkTreeIter *parent_iter, gboolean *has_parent_iter, GtkTreeIter *sibling_iter, gboolean *has_sibling_iter, NAObject **parent_object )
+{
+	g_return_if_fail( NA_IS_OBJECT_MENU( object ));
+
+	if( NA_IS_OBJECT_ACTION( select_object )){
+		insert_before_get_iters( model, select_path, object, parent_iter, has_parent_iter, sibling_iter, has_sibling_iter, parent_object );
+	}
+
+	if( NA_IS_OBJECT_PROFILE( select_object )){
+		insert_before_parent_get_iters( model, select_path, object, parent_iter, has_parent_iter, sibling_iter, has_sibling_iter, parent_object );
+	}
+
+	if( NA_IS_OBJECT_MENU( select_object )){
+		insert_as_last_child_get_iters( model, select_path, object, parent_iter, has_parent_iter, sibling_iter, has_sibling_iter, parent_object );
+	}
+}
+
+/*
+ * insert an action or a menu where there is no current selection
+ * insert an action or a menu when the selection is an action
+ * insert a profile before a profile
+ */
+static void
+insert_before_get_iters( GtkTreeModel *model,  GtkTreePath *select_path, const NAObject *object, GtkTreeIter *parent_iter, gboolean *has_parent_iter, GtkTreeIter *sibling_iter, gboolean *has_sibling_iter, NAObject **parent_object )
+{
+	GtkTreePath *path;
+	GtkTreeIter iter;
+
+	g_debug( "nact_tree_model_insert_before_get_iters" );
+
+	gtk_tree_model_get_iter( model, sibling_iter, select_path );
+	*has_sibling_iter = TRUE;
+
+	if( gtk_tree_path_get_depth( select_path ) > 1 ){
+		path = gtk_tree_path_copy( select_path );
+		gtk_tree_path_up( path );
+		gtk_tree_model_get_iter( model, &iter, path );
+		gtk_tree_model_get( model, &iter, IACTIONS_LIST_NAOBJECT_COLUMN, parent_object, -1 );
+		g_return_if_fail( NA_IS_OBJECT_ITEM( *parent_object ));
+		na_object_insert_item( *parent_object, object );
+		g_object_unref( *parent_object );
+		gtk_tree_path_free( path );
+	}
+}
+
+/*
+ * insert an action or a menu when the selection is a profile
+ */
+static void
+insert_before_parent_get_iters( GtkTreeModel *model, GtkTreePath *select_path, const NAObject *object, GtkTreeIter *parent_iter, gboolean *has_parent_iter, GtkTreeIter *sibling_iter, gboolean *has_sibling_iter, NAObject **parent_object )
+{
+	GtkTreePath *path;
+	GtkTreeIter iter;
+
+	g_debug( "nact_tree_model_insert_before_parent_get_iters" );
+
+	path = gtk_tree_path_copy( select_path );
+	gtk_tree_path_up( path );
+	gtk_tree_model_get_iter( model, sibling_iter, path );
+	*has_sibling_iter = TRUE;
+
+	if( gtk_tree_path_get_depth( path ) > 1 ){
+		gtk_tree_path_up( path );
+		gtk_tree_model_get_iter( model, &iter, path );
+		gtk_tree_model_get( model, &iter, IACTIONS_LIST_NAOBJECT_COLUMN, parent_object, -1 );
+		g_return_if_fail( NA_IS_OBJECT_ITEM( *parent_object ));
+		na_object_insert_item( *parent_object, object );
+		g_object_unref( *parent_object );
+	}
+
+	gtk_tree_path_free( path );
+}
+
+/*
+ * insert an action or a menu when the selection is a menu
+ * insert a profile when the selection is an action
+ */
+static void
+insert_as_last_child_get_iters( GtkTreeModel *model, GtkTreePath *select_path, const NAObject *object, GtkTreeIter *parent_iter, gboolean *has_parent_iter, GtkTreeIter *sibling_iter, gboolean *has_sibling_iter, NAObject **parent_object )
+{
+	g_debug( "nact_tree_model_insert_as_last_child_get_iters" );
+
+	gtk_tree_model_get_iter( model, parent_iter, select_path );
+	*has_parent_iter = TRUE;
+
+	gtk_tree_model_get( model, parent_iter, IACTIONS_LIST_NAOBJECT_COLUMN, parent_object, -1 );
+	g_return_if_fail( NA_IS_OBJECT_ITEM( *parent_object ));
+	na_object_insert_item( *parent_object, object );
+	g_object_unref( *parent_object );
 }
 
 void
@@ -1175,6 +1328,7 @@ filter_visible( GtkTreeModel *model, GtkTreeIter *iter, NactIActionsList *window
 	NAObject *object;
 	NAObjectAction *action;
 	gboolean only_actions;
+	gint count;
 
 	/*g_debug( "%s: model=%p, iter=%p, window=%p", thisfn, ( void * ) model, ( void * ) iter, ( void * ) window );*/
 	/*g_debug( "%s at %p", G_OBJECT_TYPE_NAME( model ), ( void * ) model );*/
@@ -1202,8 +1356,10 @@ filter_visible( GtkTreeModel *model, GtkTreeIter *iter, NactIActionsList *window
 			if( NA_IS_OBJECT_PROFILE( object )){
 				action = na_object_profile_get_action( NA_OBJECT_PROFILE( object ));
 				g_object_unref( object );
+				count = na_object_get_items_count( action );
+				/*g_debug( "action=%p: count=%d", ( void * ) action, count );*/
 				/*return( TRUE );*/
-				return( na_object_get_items_count( action ) > 1 );
+				return( count > 1 );
 			}
 
 			g_assert_not_reached();



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