static gboolean on_drag_motion(GtkWidget *dest_widget, GdkDragContext *drag_context, gint x, gint y, guint time, FmFolderView* fv) { gboolean ret; GdkDragAction action = 0; GdkAtom target = gtk_drag_dest_find_target(dest_widget, drag_context, NULL); if(target == GDK_NONE) return FALSE; ret = FALSE; /* files are being dragged */ if(fm_dnd_dest_is_target_supported(fv->dnd_dest, target)) { GtkTreePath* tp = get_drop_path(fv, x, y); if(tp) { GtkTreeIter it; if(gtk_tree_model_get_iter(fv->model, &it, tp)) { FmFileInfo* fi; gtk_tree_model_get(fv->model, &it, COL_FILE_INFO, &fi, -1); fm_dnd_dest_set_dest_file(fv->dnd_dest, fi); } gtk_tree_path_free(tp); } else { /* FIXME: prevent direct access to data members. */ FmFolderModel* model = (FmFolderModel*)fv->model; FmPath* dir_path = model->dir->dir_path; fm_dnd_dest_set_dest_file(fv->dnd_dest, model->dir->dir_fi); } action = fm_dnd_dest_get_default_action(fv->dnd_dest, drag_context, target); ret = action != 0; } if (action) gdk_drag_status(drag_context, action, time); return ret; }
gboolean on_dnd_dest_query_info(FmDndDest* dd, int x, int y, GdkDragAction* action, FmPlacesView* view) { GtkTreeViewDropPosition pos; GtkTreePath* tp = NULL; GtkTreeViewColumn* col; if(gtk_tree_view_get_dest_row_at_pos((GtkTreeView*)view, x, y, &tp, &pos)) { /* FIXME: this is inefficient. we should record the index of separator instead. */ if(pos == GTK_TREE_VIEW_DROP_INTO_OR_BEFORE || pos == GTK_TREE_VIEW_DROP_INTO_OR_AFTER) { } else { GtkTreePath* sep = gtk_tree_model_get_path(GTK_TREE_MODEL(model), &sep_it); if(gtk_tree_path_compare(sep, tp) < 0) /* tp is after sep */ { *action = GDK_ACTION_LINK; } else { *action = 0; gtk_tree_path_free(tp); tp = NULL; } gtk_tree_path_free(sep); } } else { tp = gtk_tree_path_new_from_indices(gtk_tree_model_iter_n_children(GTK_TREE_MODEL(model), NULL)-1, -1); pos = GTK_TREE_VIEW_DROP_AFTER; *action = GDK_ACTION_LINK; } gtk_tree_view_set_drag_dest_row((GtkTreeView*)view, tp, pos); fm_dnd_dest_set_dest_file(view->dnd_dest, NULL); if(view->dest_row) gtk_tree_path_free(view->dest_row); view->dest_row = tp; view->dest_pos = pos; return TRUE; }
static gboolean on_drag_motion (GtkWidget *dest_widget, GdkDragContext *drag_context, gint x, gint y, guint time) { FmPlacesView* view = FM_PLACES_VIEW(dest_widget); /* fm_drag_context_has_target_name(drag_context, "GTK_TREE_MODEL_ROW"); */ GdkAtom target; GtkTreeViewDropPosition pos; GtkTreePath* tp, *sep; gboolean ret = FALSE; GdkDragAction action = 0; target = gtk_drag_dest_find_target(dest_widget, drag_context, NULL); if(target == GDK_NONE) return FALSE; gtk_tree_view_get_dest_row_at_pos((GtkTreeView*)view, x, y, &tp, &pos); /* handle reordering bookmark items first */ if(target == gdk_atom_intern_static_string("GTK_TREE_MODEL_ROW")) { /* bookmark item is being dragged */ ret = get_bookmark_drag_dest(view, &tp, &pos); action = ret ? GDK_ACTION_MOVE : 0; /* bookmark items can only be moved */ } /* try FmDndDest */ else if(fm_dnd_dest_is_target_supported(view->dnd_dest, target)) { /* the user is dragging files. get FmFileInfo of drop site. */ if(pos == GTK_TREE_VIEW_DROP_INTO_OR_BEFORE || pos == GTK_TREE_VIEW_DROP_INTO_OR_AFTER) /* drag into items */ { FmPlaceItem* item = NULL; GtkTreeIter it; /* FIXME: handle adding bookmarks with Dnd */ if(tp && gtk_tree_model_get_iter(GTK_TREE_MODEL(model), &it, tp)) gtk_tree_model_get(GTK_TREE_MODEL(model), &it, FM_PLACES_MODEL_COL_INFO, &item, -1); fm_dnd_dest_set_dest_file(view->dnd_dest, item && item->fi ? item->fi : NULL); action = fm_dnd_dest_get_default_action(view->dnd_dest, drag_context, target); ret = action != 0; } else /* drop between items, create bookmark items for dragged files */ { if( (!tp || fm_places_model_path_is_bookmark(FM_PLACES_MODEL(model), tp)) && get_bookmark_drag_dest(view, &tp, &pos)) /* tp is after separator */ { action = GDK_ACTION_LINK; ret = TRUE; } else { action = 0; ret = FALSE; } } } gdk_drag_status(drag_context, action, time); if(ret) gtk_tree_view_set_drag_dest_row(GTK_TREE_VIEW(view), tp, pos); else gtk_tree_view_set_drag_dest_row(GTK_TREE_VIEW(view), NULL, 0); if(tp) gtk_tree_path_free(tp); return ret; }