[nautilus-actions] Fix destination path when dragging top to bottom



commit d1fcd4c2ecf9251fe2eda653628eec80fc8d1040
Author: Pierre Wieser <pwieser trychlos org>
Date:   Mon Oct 12 06:59:21 2009 +0200

    Fix destination path when dragging top to bottom

 ChangeLog                  |    5 +
 src/nact/nact-tree-model.c |  174 ++++++++++++++++++++++++++++++++++++++++----
 2 files changed, 165 insertions(+), 14 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index f0f1ab9..f85f94f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2009-10-12 Pierre Wieser <pwieser trychlos org>
+
+	* src/nact/nact-tree-model.c (drop_inside):
+	Adjust the dest when moving items down.
+
 2009-10-11 Pierre Wieser <pwieser trychlos org>
 
 	* src/nact/nact-iactions-list.c (do_insert_into_first):
diff --git a/src/nact/nact-tree-model.c b/src/nact/nact-tree-model.c
index 13a055c..ba9dfae 100644
--- a/src/nact/nact-tree-model.c
+++ b/src/nact/nact-tree-model.c
@@ -189,8 +189,9 @@ static GtkTargetList *imulti_drag_source_get_target_list( EggTreeMultiDragSource
 static GdkDragAction  imulti_drag_source_get_drag_actions( EggTreeMultiDragSource *drag_source );
 
 static gboolean       idrag_dest_drag_data_received( GtkTreeDragDest *drag_dest, GtkTreePath *dest, GtkSelectionData  *selection_data );
-static gboolean       inside_drag_and_drop( NactTreeModel *model, GtkTreePath *dest, GtkSelectionData  *selection_data );
-static GtkTreePath   *is_drop_possible( NactTreeModel *model, GtkTreePath *dest, NAObjectAction **parent );
+static gboolean       drop_inside( NactTreeModel *model, GtkTreePath *dest, GtkSelectionData  *selection_data );
+static GtkTreePath   *drop_inside_adjust_dest( NactTreeModel *model, GtkTreePath *dest, NAObjectAction **parent );
+static void           drop_inside_move_dest( NactTreeModel *model, GList *rows, GtkTreePath **dest );
 static gboolean       drop_uri_list( NactTreeModel *model, GtkTreePath *dest, GtkSelectionData  *selection_data );
 static gboolean       idrag_dest_row_drop_possible( GtkTreeDragDest *drag_dest, GtkTreePath *dest_path, GtkSelectionData *selection_data );
 
@@ -1423,7 +1424,7 @@ idrag_dest_drag_data_received( GtkTreeDragDest *drag_dest, GtkTreePath *dest, Gt
 
 	switch( info ){
 		case NACT_XCHANGE_FORMAT_NACT:
-			result = inside_drag_and_drop( NACT_TREE_MODEL( drag_dest ), dest, selection_data );
+			result = drop_inside( NACT_TREE_MODEL( drag_dest ), dest, selection_data );
 			break;
 
 		/* drop some actions from outside
@@ -1446,9 +1447,20 @@ idrag_dest_drag_data_received( GtkTreeDragDest *drag_dest, GtkTreePath *dest, Gt
  *
  * Returns: %TRUE if the specified rows were successfully inserted at
  * the given dest, %FALSE else.
+ *
+ * The dest path is computed based on the current appearance of the list
+ * Drop should so occurs inside an inchanged list to keep a valid path
+ * in the case of a move, this leads to :
+ *  1) marks dragged items as 'to be deleted'
+ *  2) insert new dropped items
+ *  3) remove 'to be deleted' items
+ * -> not an easy idea as we want modify the id of all the dragged
+ *    hierarchy
+ *
+ * adjusting the path: quid if the target dest is not at the same level
  */
 static gboolean
-inside_drag_and_drop( NactTreeModel *model, GtkTreePath *dest, GtkSelectionData  *selection_data )
+drop_inside( NactTreeModel *model, GtkTreePath *dest, GtkSelectionData  *selection_data )
 {
 	static const gchar *thisfn = "nact_tree_model_inside_drag_and_drop";
 	gboolean drop_done;
@@ -1478,10 +1490,13 @@ inside_drag_and_drop( NactTreeModel *model, GtkTreePath *dest, GtkSelectionData
 	 */
 	drop_done = FALSE;
 	parent = NULL;
-	new_dest = is_drop_possible( model, dest, &parent );
+	rows = nact_clipboard_dnd_get_data( model->private->clipboard, &copy_data );
+	new_dest = drop_inside_adjust_dest( model, dest, &parent );
+	if( !copy_data ){
+		drop_inside_move_dest( model, rows, &new_dest );
+	}
 
 	if( new_dest ){
-		rows = nact_clipboard_dnd_get_data( model->private->clipboard, &copy_data );
 		g_debug( "%s: rows has %d items, copy_data=%s", thisfn, g_list_length( rows ), copy_data ? "True":"False" );
 		object_list = NULL;
 		for( it = rows ; it ; it = it->next ){
@@ -1492,12 +1507,13 @@ inside_drag_and_drop( NactTreeModel *model, GtkTreePath *dest, GtkSelectionData
 					g_object_unref( current );
 					if( copy_data ){
 						inserted = na_object_duplicate( current );
-						na_object_set_origin( inserted, NULL );
+						na_object_reset_origin( inserted, NULL );
 						na_object_prepare_for_paste( inserted, pivot, TRUE, parent );
 					} else {
 						inserted = na_object_ref( current );
 					}
 					object_list = g_list_prepend( object_list, inserted );
+					g_debug( "%s: dropped=%s", thisfn, na_object_get_label( inserted ));
 				}
 				gtk_tree_path_free( path );
 			}
@@ -1508,7 +1524,95 @@ inside_drag_and_drop( NactTreeModel *model, GtkTreePath *dest, GtkSelectionData
 			nact_iactions_list_delete( NACT_IACTIONS_LIST( main_window ), object_list );
 		}
 
-		nact_iactions_list_insert_at_path( NACT_IACTIONS_LIST( main_window ), object_list, dest );
+		nact_iactions_list_insert_at_path( NACT_IACTIONS_LIST( main_window ), object_list, new_dest );
+
+		if( !copy_data ){
+			g_signal_emit_by_name( main_window, MAIN_WINDOW_SIGNAL_LEVEL_ZERO_ORDER_CHANGED, NULL );
+		}
+
+		g_list_foreach( object_list, ( GFunc ) na_object_object_unref, NULL );
+		g_list_free( object_list );
+		gtk_tree_path_free( new_dest );
+
+		drop_done = TRUE;
+	}
+
+	g_list_foreach( rows, ( GFunc ) gtk_tree_row_reference_free, NULL );
+	g_list_free( rows );
+
+	return( drop_done );
+}
+
+#if 0
+static gboolean
+drop_inside( NactTreeModel *model, GtkTreePath *dest, GtkSelectionData  *selection_data )
+{
+	static const gchar *thisfn = "nact_tree_model_inside_drag_and_drop";
+	gboolean drop_done;
+	NactApplication *application;
+	NAPivot *pivot;
+	NactMainWindow *main_window;
+	NAObjectAction *parent;
+	gboolean copy_data;
+	GList *rows;
+	GtkTreePath *new_dest;
+	GtkTreePath *path;
+	NAObject *current;
+	NAObject *inserted;
+	GList *object_list, *it;
+	GList *deletables;
+	GtkTreeIter iter;
+
+	application = NACT_APPLICATION( base_window_get_application( model->private->window ));
+	pivot = nact_application_get_pivot( application );
+	main_window = NACT_MAIN_WINDOW( base_application_get_main_window( BASE_APPLICATION( application )));
+
+	/*
+	 * NACT format (may embed profiles, or not)
+	 * 	with profiles: only valid dest is inside an action
+	 *  without profile: only valid dest is outside (besides of) an action
+	 * URI format only involves actions
+	 *  ony valid dest in outside (besides of) an action
+	 */
+	drop_done = FALSE;
+	parent = NULL;
+	rows = nact_clipboard_dnd_get_data( model->private->clipboard, &copy_data );
+	new_dest = drop_inside_adjust_dest( model, dest, &parent );
+	if( 0 && !copy_data ){
+		drop_inside_move_dest( model, rows, &new_dest );
+	}
+
+	if( new_dest ){
+		g_debug( "%s: rows has %d items, copy_data=%s", thisfn, g_list_length( rows ), copy_data ? "True":"False" );
+		object_list = NULL;
+		deletables = NULL;
+		for( it = rows ; it ; it = it->next ){
+			path = gtk_tree_row_reference_get_path(( GtkTreeRowReference * ) it->data );
+			if( path ){
+				if( gtk_tree_model_get_iter( GTK_TREE_MODEL( model ), &iter, path )){
+					gtk_tree_model_get( GTK_TREE_MODEL( model ), &iter, IACTIONS_LIST_NAOBJECT_COLUMN, &current, -1 );
+					g_object_unref( current );
+					inserted = na_object_duplicate( current );
+					if( copy_data ){
+						na_object_reset_origin( inserted, NULL );
+						na_object_prepare_for_paste( inserted, pivot, TRUE, parent );
+					} else {
+						na_object_set_new_id( current, parent );
+						deletables = g_list_prepend( deletables, current );
+					}
+					object_list = g_list_prepend( object_list, inserted );
+					g_debug( "%s: dropped=%s", thisfn, na_object_get_label( inserted ));
+				}
+				gtk_tree_path_free( path );
+			}
+		}
+		object_list = g_list_reverse( object_list );
+
+		nact_iactions_list_insert_at_path( NACT_IACTIONS_LIST( main_window ), object_list, new_dest );
+
+		if( !copy_data ){
+			nact_iactions_list_delete( NACT_IACTIONS_LIST( main_window ), deletables );
+		}
 
 		if( !copy_data ){
 			g_signal_emit_by_name( main_window, MAIN_WINDOW_SIGNAL_LEVEL_ZERO_ORDER_CHANGED, NULL );
@@ -1516,24 +1620,28 @@ inside_drag_and_drop( NactTreeModel *model, GtkTreePath *dest, GtkSelectionData
 
 		g_list_foreach( object_list, ( GFunc ) na_object_object_unref, NULL );
 		g_list_free( object_list );
-		g_list_foreach( rows, ( GFunc ) gtk_tree_row_reference_free, NULL );
-		g_list_free( rows );
+		g_list_foreach( deletables, ( GFunc ) na_object_object_unref, NULL );
+		g_list_free( deletables );
 		gtk_tree_path_free( new_dest );
 
 		drop_done = TRUE;
 	}
 
+	g_list_foreach( rows, ( GFunc ) gtk_tree_row_reference_free, NULL );
+	g_list_free( rows );
+
 	return( drop_done );
 }
+#endif
 
 /*
  * is a drop possible at given dest ?
  * may slightly adjust the dest to drop profile inside an action
  */
 static GtkTreePath *
-is_drop_possible( NactTreeModel *model, GtkTreePath *dest, NAObjectAction **parent )
+drop_inside_adjust_dest( NactTreeModel *model, GtkTreePath *dest, NAObjectAction **parent )
 {
-	static const gchar *thisfn = "nact_tree_model_is_drop_possible";
+	static const gchar *thisfn = "nact_tree_model_drop_inside_adjust_dest";
 	static const gchar *refuse_profile = N_( "Unable to drop a profile here" );
 	static const gchar *refuse_action_menu = N_( "Unable to drop an action or a menu here" );
 	GtkTreePath *new_dest;
@@ -1636,6 +1744,44 @@ is_drop_possible( NactTreeModel *model, GtkTreePath *dest, NAObjectAction **pare
 	return( new_dest );
 }
 
+static void
+drop_inside_move_dest( NactTreeModel *model, GList *rows, GtkTreePath **dest )
+{
+	GList *it;
+	GtkTreePath *path;
+	gint before;
+	gint i;
+	gint *indices;
+
+	before = 0;
+	for( it = rows ; it ; it = it->next ){
+		path = gtk_tree_row_reference_get_path(( GtkTreeRowReference * ) it->data );
+		if( path ){
+			if( gtk_tree_path_compare( path, *dest ) == -1 ){
+				before += 1;
+			}
+			gtk_tree_path_free( path );
+		}
+	}
+
+	g_debug( "drop_inside_move_dest: before=%d", before );
+	g_debug( "drop_inside_move_dest: dest=%s", gtk_tree_path_to_string( *dest ));
+
+	if( before ){
+		indices = gtk_tree_path_get_indices( *dest );
+		indices[0] -= before;
+		path = gtk_tree_path_new_from_indices( indices[0], -1 );
+		for( i = 1 ; i< gtk_tree_path_get_depth( *dest ); ++i ){
+			gtk_tree_path_append_index( path, indices[i] );
+		}
+		gtk_tree_path_free( *dest );
+		*dest = gtk_tree_path_copy( path );
+		gtk_tree_path_free( path );
+	}
+
+	g_debug( "drop_inside_move_dest: dest=%s", gtk_tree_path_to_string( *dest ));
+}
+
 /*
  * called when a drop from the outside occurs in the treeview
  *
@@ -1645,7 +1791,7 @@ is_drop_possible( NactTreeModel *model, GtkTreePath *dest, NAObjectAction **pare
 static gboolean
 drop_uri_list( NactTreeModel *model, GtkTreePath *dest, GtkSelectionData  *selection_data )
 {
-	/*static const gchar *thisfn = "nact_tree_model_drop_from_outside";*/
+	/*static const gchar *thisfn = "nact_tree_model_drop_uri_list";*/
 	gboolean drop_done = FALSE;
 	GSList *uri_list, *is, *msg;
 	NactApplication *application;
@@ -1659,7 +1805,7 @@ drop_uri_list( NactTreeModel *model, GtkTreePath *dest, GtkSelectionData  *selec
 	pivot = nact_application_get_pivot( application );
 	main_window = NACT_MAIN_WINDOW( base_application_get_main_window( BASE_APPLICATION( application )));
 
-	uri_list = na_utils_lines_to_string_list(( const gchar * ) selection_data->data );
+	uri_list = g_slist_reverse( na_utils_lines_to_string_list(( const gchar * ) selection_data->data ));
 	import_mode = na_iprefs_get_import_mode( NA_IPREFS( pivot ));
 
 	for( is = uri_list ; is ; is = is->next ){



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