[gtk+/places-sidebar] Redo the logic for computing drop positions



commit fafec940b379879cf31479616338c041ece668a9
Author: Federico Mena Quintero <federico gnome org>
Date:   Tue Jan 29 01:14:10 2013 -0600

    Redo the logic for computing drop positions
    
    Instead of having an accept_uri_drops flag, we'll always advertise as accepting URI drops.
    However, we'll see if the caller actually handles the drag-action-requested signal.  If it
    does, we'll indeed allow performing file operations when URIs are dropped.  Otherwise,
    we'll only allow creating bookmarks from dragged URIs.
    
    Dragging URIs directly into a places item will cause the sidebar to check if the caller
    allows file operations.  Dragging URIs between places items will cause the sidebar
    to create bookmarks for those URIs instead.
    
    Signed-off-by: Federico Mena Quintero <federico gnome org>

 gtk/gtkplacessidebar.c |  159 ++++++++++++++++++++++++++++++------------------
 1 files changed, 100 insertions(+), 59 deletions(-)
---
diff --git a/gtk/gtkplacessidebar.c b/gtk/gtkplacessidebar.c
index 0eef2f5..5110607 100644
--- a/gtk/gtkplacessidebar.c
+++ b/gtk/gtkplacessidebar.c
@@ -1225,6 +1225,12 @@ clicked_eject_button (GtkPlacesSidebar *sidebar,
 	return FALSE;
 }
 
+static gboolean
+pos_is_into_or_before (GtkTreeViewDropPosition pos)
+{
+	return (pos == GTK_TREE_VIEW_DROP_BEFORE || pos == GTK_TREE_VIEW_DROP_INTO_OR_BEFORE);
+}
+
 /* Computes the appropriate row and position for dropping */
 static gboolean
 compute_drop_position (GtkTreeView             *tree_view,
@@ -1238,6 +1244,7 @@ compute_drop_position (GtkTreeView             *tree_view,
 	GtkTreeIter iter;
 	PlaceType place_type;
 	SectionType section_type;
+	gboolean drop_possible;
 
 	if (!gtk_tree_view_get_dest_row_at_pos (tree_view,
 						x, y,
@@ -1253,41 +1260,62 @@ compute_drop_position (GtkTreeView             *tree_view,
 			    PLACES_SIDEBAR_COLUMN_SECTION_TYPE, &section_type,
 			    -1);
 
+	drop_possible = TRUE;
+
 	/* Never drop on headings, but special case the bookmarks heading,
 	 * so we can drop bookmarks in between it and the first bookmark.
 	 */
 	if (place_type == PLACES_HEADING
-	    && section_type != SECTION_BOOKMARKS) {
-		gtk_tree_path_free (*path);
-		*path = NULL;
-
-		return FALSE;
-	}
+	    && section_type != SECTION_BOOKMARKS)
+		drop_possible = FALSE;
 
 	/* Dragging a bookmark? */
 	if (sidebar->drag_data_received
 	    && sidebar->drag_data_info == GTK_TREE_MODEL_ROW) {
 		/* Don't allow reordering bookmarks into non-bookmark areas */
-		if (section_type != SECTION_BOOKMARKS) {
-			gtk_tree_path_free (*path);
-			*path = NULL;
+		if (section_type != SECTION_BOOKMARKS)
+			drop_possible = FALSE;
 
-			return FALSE;
+		/* Bookmarks can only be reordered.  Disallow dropping directly into them; only allow dropping between them. */
+		if (place_type == PLACES_HEADING) {
+			if (pos_is_into_or_before (*pos))
+				drop_possible = FALSE;
+			else
+				*pos = GTK_TREE_VIEW_DROP_AFTER;
+		} else {
+			if (pos_is_into_or_before (*pos))
+				*pos = GTK_TREE_VIEW_DROP_BEFORE;
+			else
+				*pos = GTK_TREE_VIEW_DROP_AFTER;
 		}
-
-		printf ("dragging a bookmark, pos = %d\n", *pos);
 	} else {
-		printf ("dragging a file, pos = %d\n", *pos);
+		/* Dragging a file */
+
+		/* Outside the bookmarks section, URIs can only be dropped
+		 * directly into places items.  Inside the bookmarks section,
+		 * they can be dropped between items (to create new bookmarks)
+		 * or in items themselves (to request a move/copy file
+		 * operation).
+		 */
+		if (section_type != SECTION_BOOKMARKS)
+			*pos = GTK_TREE_VIEW_DROP_INTO_OR_BEFORE;
+		else {
+			if (place_type == PLACES_HEADING) {
+				if (pos_is_into_or_before (*pos))
+					drop_possible = FALSE;
+				else
+					*pos = GTK_TREE_VIEW_DROP_AFTER;
+			}
+		}
 	}
-#if 0
-	if (sidebar->drag_data_received &&
-	    sidebar->drag_data_info == GTK_TREE_MODEL_ROW) {
-		/* bookmark rows can only be reordered */
-		*pos = GTK_TREE_VIEW_DROP_AFTER;
-	} else {
-		*pos = GTK_TREE_VIEW_DROP_INTO_OR_BEFORE;
+
+	if (!drop_possible) {
+		gtk_tree_path_free (*path);
+		*path = NULL;
+
+		return FALSE;
 	}
-#endif
+
 	return TRUE;
 }
 
@@ -1323,6 +1351,18 @@ free_drag_data (GtkPlacesSidebar *sidebar)
 	}
 }
 
+static const char *
+pos_to_string (GtkTreeViewDropPosition pos)
+{
+	switch (pos) {
+	case GTK_TREE_VIEW_DROP_BEFORE:         return "BEFORE";
+	case GTK_TREE_VIEW_DROP_AFTER:          return "AFTER";
+	case GTK_TREE_VIEW_DROP_INTO_OR_BEFORE: return "INTO_OR_BEFORE";
+	case GTK_TREE_VIEW_DROP_INTO_OR_AFTER:  return "INTO_OR_AFTER";
+	default: return "INVALID";
+	}
+}
+
 static gboolean
 drag_motion_callback (GtkTreeView *tree_view,
 		      GdkDragContext *context,
@@ -1349,35 +1389,39 @@ drag_motion_callback (GtkTreeView *tree_view,
 	path = NULL;
 	res = compute_drop_position (tree_view, x, y, &path, &pos, sidebar);
 
-	printf ("compute_drop_position(): pos %d, result %d\n", pos, res);
-
 	if (!res) {
 		goto out;
 	}
 
-	if (pos == GTK_TREE_VIEW_DROP_AFTER) {
-		if (sidebar->drag_data_received &&
-		    sidebar->drag_data_info == GTK_TREE_MODEL_ROW) {
-			action = GDK_ACTION_MOVE;
-		}
+	printf ("compute_drop_position(): path %d, pos %s\n", gtk_tree_path_get_indices (path)[0], pos_to_string (pos));
+
+	if (sidebar->drag_data_received &&
+	    sidebar->drag_data_info == GTK_TREE_MODEL_ROW) {
+		/* Dragging bookmarks always moves them to another position in the bookmarks list */
+		action = GDK_ACTION_MOVE;
 	} else {
-		if (sidebar->accept_uri_drops) {
-			if (sidebar->drag_list != NULL) {
-				GFile *dest_file;
-
-				gtk_tree_model_get_iter (GTK_TREE_MODEL (sidebar->store),
-							 &iter, path);
-				gtk_tree_model_get (GTK_TREE_MODEL (sidebar->store),
-						    &iter,
-						    PLACES_SIDEBAR_COLUMN_URI, &uri,
-						    -1);
-
-				dest_file = g_file_new_for_uri (uri);
-				g_free (uri);
+		/* URIs are being dragged.  See if the caller wants to handle a
+		 * file move/copy operation itself, or if we should only try to
+		 * create bookmarks out of the dragged URIs.
+		 */
+		if (sidebar->drag_list != NULL) {
+			GFile *dest_file;
 
-				emit_drag_action_requested (sidebar, context, dest_file, sidebar->drag_list, &action);
-				g_object_unref (dest_file);
-			}
+			gtk_tree_model_get_iter (GTK_TREE_MODEL (sidebar->store),
+						 &iter, path);
+			gtk_tree_model_get (GTK_TREE_MODEL (sidebar->store),
+					    &iter,
+					    PLACES_SIDEBAR_COLUMN_URI, &uri,
+					    -1);
+
+			dest_file = g_file_new_for_uri (uri);
+
+			emit_drag_action_requested (sidebar, context, dest_file, sidebar->drag_list, &action);
+
+			printf ("dragging URIs, dest_file = %s, action_requested = %d\n", uri, action);
+
+			g_object_unref (dest_file);
+			g_free (uri);
 		}
 	}
 
@@ -1503,7 +1547,9 @@ drag_data_received_callback (GtkWidget *widget,
 
 	success = FALSE;
 
-	if (tree_pos == GTK_TREE_VIEW_DROP_AFTER) {
+	if (sidebar->drag_data_info == GTK_TREE_MODEL_ROW) {
+		/* A bookmark got reordered */
+
 		model = gtk_tree_view_get_model (tree_view);
 
 		if (!gtk_tree_model_get_iter (model, &iter, tree_path)) {
@@ -1520,21 +1566,16 @@ drag_data_received_callback (GtkWidget *widget,
 			goto out;
 		}
 
-		if (tree_pos == GTK_TREE_VIEW_DROP_AFTER && place_type != PLACES_HEADING) {
-			/* heading already has position 0 */
+		if (place_type == PLACES_HEADING)
+			position = 0;
+		else if (tree_pos == GTK_TREE_VIEW_DROP_AFTER)
 			position++;
-		}
 
-		switch (info) {
-		case GTK_TREE_MODEL_ROW:
-			reorder_bookmarks (sidebar, position);
-			success = TRUE;
-			break;
-		default:
-			g_assert_not_reached ();
-			break;
-		}
+		reorder_bookmarks (sidebar, position);
+		success = TRUE;
 	} else {
+		/* Dropping URIs! */
+
 		GdkDragAction real_action;
 		char **uris;
 		GList *source_file_list;



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