summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/caja-places-sidebar.c129
1 files changed, 115 insertions, 14 deletions
diff --git a/src/caja-places-sidebar.c b/src/caja-places-sidebar.c
index 9f79e15e..f7974970 100644
--- a/src/caja-places-sidebar.c
+++ b/src/caja-places-sidebar.c
@@ -1130,12 +1130,11 @@ compute_drop_position (GtkTreeView *tree_view,
PLACES_SIDEBAR_COLUMN_SECTION_TYPE, &section_type,
-1);
- if (section_type != SECTION_BOOKMARKS &&
- place_type == PLACES_HEADING) {
+ if (place_type == PLACES_HEADING && section_type != SECTION_BOOKMARKS) {
/* never drop on headings, but special case the bookmarks heading,
- * so we can drop bookmarks in between it and the first item when
- * reordering.
+ * so we can drop bookmarks in between it and the first item.
*/
+
gtk_tree_path_free (*path);
*path = NULL;
@@ -1146,18 +1145,25 @@ compute_drop_position (GtkTreeView *tree_view,
sidebar->drag_data_received &&
sidebar->drag_data_info == GTK_TREE_MODEL_ROW) {
/* don't allow dropping bookmarks into non-bookmark areas */
- gtk_tree_path_free (*path);
- *path = NULL;
+
+ gtk_tree_path_free (*path);
+ *path = NULL;
return FALSE;
}
- 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;
+ if (section_type == SECTION_BOOKMARKS) {
+ *pos = GTK_TREE_VIEW_DROP_AFTER;
} else {
- *pos = GTK_TREE_VIEW_DROP_INTO_OR_BEFORE;
+ /* non-bookmark shortcuts can only be dragged into */
+ *pos = GTK_TREE_VIEW_DROP_INTO_OR_BEFORE;
+ }
+
+ if (*pos != GTK_TREE_VIEW_DROP_BEFORE &&
+ sidebar->drag_data_received &&
+ sidebar->drag_data_info == GTK_TREE_MODEL_ROW) {
+ /* bookmark rows are never dragged into other bookmark rows */
+ *pos = GTK_TREE_VIEW_DROP_AFTER;
}
return TRUE;
@@ -1198,6 +1204,38 @@ free_drag_data (CajaPlacesSidebar *sidebar)
}
static gboolean
+can_accept_file_as_bookmark (CajaFile *file)
+{
+ return (caja_file_is_directory (file) &&
+ !is_built_in_bookmark (file));
+}
+
+static gboolean
+can_accept_items_as_bookmarks (const GList *items)
+{
+ int max;
+ char *uri;
+ CajaFile *file;
+
+ /* Iterate through selection checking if item will get accepted as a bookmark.
+ * If more than 100 items selected, return an over-optimistic result.
+ */
+ for (max = 100; items != NULL && max >= 0; items = items->next, max--)
+ {
+ uri = ((CajaDragSelectionItem *)items->data)->uri;
+ file = caja_file_get_by_uri (uri);
+ if (!can_accept_file_as_bookmark (file))
+ {
+ caja_file_unref (file);
+ return FALSE;
+ }
+ caja_file_unref (file);
+ }
+
+ return TRUE;
+}
+
+static gboolean
drag_motion_callback (GtkTreeView *tree_view,
GdkDragContext *context,
int x,
@@ -1227,13 +1265,18 @@ drag_motion_callback (GtkTreeView *tree_view,
goto out;
}
- if (pos == GTK_TREE_VIEW_DROP_AFTER )
+ if (pos == GTK_TREE_VIEW_DROP_BEFORE ||
+ pos == GTK_TREE_VIEW_DROP_AFTER )
{
if (sidebar->drag_data_received &&
sidebar->drag_data_info == GTK_TREE_MODEL_ROW)
{
action = GDK_ACTION_MOVE;
}
+ else if (can_accept_items_as_bookmarks (sidebar->drag_list))
+ {
+ action = GDK_ACTION_COPY;
+ }
else
{
action = 0;
@@ -1290,10 +1333,62 @@ drag_leave_callback (GtkTreeView *tree_view,
CajaPlacesSidebar *sidebar)
{
free_drag_data (sidebar);
- gtk_tree_view_set_drag_dest_row (tree_view, NULL, 0);
+ gtk_tree_view_set_drag_dest_row (tree_view, NULL, GTK_TREE_VIEW_DROP_BEFORE);
g_signal_stop_emission_by_name (tree_view, "drag-leave");
}
+/* Parses a "text/uri-list" string and inserts its URIs as bookmarks */
+static void
+bookmarks_drop_uris (CajaPlacesSidebar *sidebar,
+ GtkSelectionData *selection_data,
+ int position)
+{
+ CajaBookmark *bookmark;
+ CajaFile *file;
+ char *uri, *name;
+ char **uris;
+ int i;
+ GFile *location;
+ GIcon *icon;
+
+ uris = gtk_selection_data_get_uris (selection_data);
+ if (!uris)
+ return;
+
+ for (i = 0; uris[i]; i++)
+ {
+ uri = uris[i];
+ file = caja_file_get_by_uri (uri);
+
+ if (!can_accept_file_as_bookmark (file))
+ {
+ caja_file_unref (file);
+ continue;
+ }
+
+ uri = caja_file_get_drop_target_uri (file);
+ location = g_file_new_for_uri (uri);
+ caja_file_unref (file);
+
+ name = caja_compute_title_for_location (location);
+ icon = g_themed_icon_new (CAJA_ICON_FOLDER);
+ bookmark = caja_bookmark_new (location, name, TRUE, icon);
+
+ if (!caja_bookmark_list_contains (sidebar->bookmarks, bookmark))
+ {
+ caja_bookmark_list_insert_item (sidebar->bookmarks, bookmark, position++);
+ }
+
+ g_object_unref (location);
+ g_object_unref (bookmark);
+ g_object_unref (icon);
+ g_free (name);
+ g_free (uri);
+ }
+
+ g_strfreev (uris);
+}
+
static GList *
uri_list_from_selection (GList *selection)
{
@@ -1431,7 +1526,9 @@ drag_data_received_callback (GtkWidget *widget,
success = FALSE;
- if (tree_pos == GTK_TREE_VIEW_DROP_AFTER) {
+ if (tree_pos == GTK_TREE_VIEW_DROP_BEFORE ||
+ tree_pos == GTK_TREE_VIEW_DROP_AFTER)
+ {
model = gtk_tree_view_get_model (tree_view);
if (!gtk_tree_model_get_iter (model, &iter, tree_path))
@@ -1456,6 +1553,10 @@ drag_data_received_callback (GtkWidget *widget,
switch (info)
{
+ case TEXT_URI_LIST:
+ bookmarks_drop_uris (sidebar, selection_data, position);
+ success = TRUE;
+ break;
case GTK_TREE_MODEL_ROW:
reorder_bookmarks (sidebar, position);
success = TRUE;