bool NotebooksTreeView::on_drag_motion(const Glib::RefPtr<Gdk::DragContext> &, int x, int y, guint ) { Gtk::TreePath treepath; Gtk::TreeViewDropPosition pos; if (get_dest_row_at_pos (x, y, treepath,pos) == false) { gtk_tree_view_set_drag_dest_row (gobj(), NULL, GTK_TREE_VIEW_DROP_INTO_OR_AFTER); return false; } Gtk::TreeIter iter = get_model()->get_iter (treepath); if (!iter) { gtk_tree_view_set_drag_dest_row (gobj(), NULL, GTK_TREE_VIEW_DROP_INTO_OR_AFTER); return false; } Notebook::Ptr destNotebook; iter->get_value(0, destNotebook); if(std::dynamic_pointer_cast<AllNotesNotebook>(destNotebook)) { gtk_tree_view_set_drag_dest_row (gobj(), NULL, GTK_TREE_VIEW_DROP_INTO_OR_AFTER); return true; } set_drag_dest_row (treepath , Gtk::TREE_VIEW_DROP_INTO_OR_AFTER); return true; }
static gboolean drag_motion (GtkWidget *widget, GdkDragContext *context, gint x, gint y, guint time_) { EmpathyPersonaView *self = EMPATHY_PERSONA_VIEW (widget); GdkAtom target; guint i; DndDragType drag_type = DND_DRAG_TYPE_UNKNOWN; target = gtk_drag_dest_find_target (GTK_WIDGET (self), context, NULL); /* Determine the DndDragType of the data */ for (i = 0; i < G_N_ELEMENTS (drag_atoms_dest); i++) { if (target == drag_atoms_dest[i]) { drag_type = drag_types_dest[i].info; break; } } if (drag_type == DND_DRAG_TYPE_INDIVIDUAL_ID) { GtkTreePath *path; /* FIXME: It doesn't make sense for us to highlight a specific row or * position to drop an Individual in, so just highlight the entire * widget. * Since I can't find a way to do this, just highlight the first possible * position in the tree. */ gdk_drag_status (context, gdk_drag_context_get_suggested_action (context), time_); path = gtk_tree_path_new_first (); gtk_tree_view_set_drag_dest_row (GTK_TREE_VIEW (self), path, GTK_TREE_VIEW_DROP_BEFORE); gtk_tree_path_free (path); return TRUE; } /* Unknown or unhandled drag target */ gdk_drag_status (context, GDK_ACTION_DEFAULT, time_); gtk_tree_view_set_drag_dest_row (GTK_TREE_VIEW (self), NULL, 0); return FALSE; }
static void fm_list_view_highlight_path (FMDirectoryView *view, GtkTreePath *path) { g_return_if_fail (FM_IS_LIST_VIEW (view)); //gtk_tree_view_set_drag_dest_row (GTK_TREE_VIEW (GTK_BIN (standard_view)->child), path, GTK_TREE_VIEW_DROP_INTO_OR_AFTER); gtk_tree_view_set_drag_dest_row (FM_LIST_VIEW (view)->tree, path, GTK_TREE_VIEW_DROP_INTO_OR_AFTER); }
static GtkTreePath* get_drop_path(FmFolderView* fv, gint x, gint y) { GtkTreePath* tp = NULL; gboolean droppable = TRUE; switch(fv->mode) { case FM_FV_LIST_VIEW: { GtkTreeViewDropPosition pos; GtkTreeViewColumn* col; gtk_tree_view_convert_widget_to_bin_window_coords(GTK_TREE_VIEW(fv->view), x, y, &x, &y); /* if(gtk_tree_view_get_dest_row_at_pos((GtkTreeView*)fv->view, x, y, &tp, NULL)) */ if(gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(fv->view), x, y, &tp, &col, NULL, NULL)) { if(gtk_tree_view_column_get_sort_column_id(col)!=COL_FILE_NAME) { gtk_tree_path_free(tp); tp = NULL; } } gtk_tree_view_set_drag_dest_row(GTK_TREE_VIEW(fv->view), tp, GTK_TREE_VIEW_DROP_INTO_OR_AFTER); break; } case FM_FV_ICON_VIEW: case FM_FV_COMPACT_VIEW: case FM_FV_THUMBNAIL_VIEW: { tp = exo_icon_view_get_path_at_pos((const struct ExoIconView *)(const struct ExoIconView *)fv->view, x, y); exo_icon_view_set_drag_dest_item(EXO_ICON_VIEW(fv->view), tp, EXO_ICON_VIEW_DROP_INTO); break; } } return tp; }
static gint bar_pane_keywords_dnd_motion(GtkWidget *tree_view, GdkDragContext *context, gint x, gint y, guint time, gpointer data) { GtkTreePath *tpath = NULL; GtkTreeViewDropPosition pos; gtk_tree_view_get_dest_row_at_pos(GTK_TREE_VIEW(tree_view), x, y, &tpath, &pos); if (tpath) { GtkTreeModel *model; GtkTreeIter dest_iter; model = gtk_tree_view_get_model(GTK_TREE_VIEW(tree_view)); gtk_tree_model_get_iter(model, &dest_iter, tpath); if (pos == GTK_TREE_VIEW_DROP_INTO_OR_BEFORE && gtk_tree_model_iter_has_child(model, &dest_iter)) pos = GTK_TREE_VIEW_DROP_BEFORE; if (pos == GTK_TREE_VIEW_DROP_INTO_OR_AFTER && gtk_tree_model_iter_has_child(model, &dest_iter)) pos = GTK_TREE_VIEW_DROP_AFTER; } gtk_tree_view_set_drag_dest_row(GTK_TREE_VIEW(tree_view), tpath, pos); gtk_tree_path_free(tpath); if (tree_view == gtk_drag_get_source_widget(context)) gdk_drag_status(context, GDK_ACTION_MOVE, time); else gdk_drag_status(context, GDK_ACTION_COPY, time); return TRUE; }
static void set_drag_dest_row (NautilusTreeViewDragDest *dest, GtkTreePath *path) { if (path) { set_widget_highlight (dest, FALSE); gtk_tree_view_set_drag_dest_row (dest->details->tree_view, path, GTK_TREE_VIEW_DROP_INTO_OR_BEFORE); } else { set_widget_highlight (dest, TRUE); gtk_tree_view_set_drag_dest_row (dest->details->tree_view, NULL, 0); } }
static VALUE rg_set_drag_dest_row(VALUE self, VALUE path, VALUE pos) { gtk_tree_view_set_drag_dest_row(_SELF(self), NIL_P(path)?NULL:RVAL2GTKTREEPATH(path), RVAL2GENUM(pos, GTK_TYPE_TREE_VIEW_DROP_POSITION)); return self; }
static void set_drag_dest_row (EphyNodeView *view, GtkTreePath *path) { if (path) { gtk_tree_view_set_drag_dest_row (GTK_TREE_VIEW (view), path, GTK_TREE_VIEW_DROP_INTO_OR_BEFORE); } else { gtk_tree_view_set_drag_dest_row (GTK_TREE_VIEW (view), NULL, 0); } }
static gboolean on_drag_leave ( GtkWidget *dest_widget, GdkDragContext *drag_context, guint time) { FmPlacesView* view = FM_PLACES_VIEW(dest_widget); gtk_tree_view_set_drag_dest_row(GTK_TREE_VIEW(view), NULL, 0); g_debug("drag_leave"); fm_dnd_dest_drag_leave(view->dnd_dest, drag_context, time); return FALSE; }
void gimp_container_tree_view_drag_leave (GtkWidget *widget, GdkDragContext *context, guint time, GimpContainerTreeView *tree_view) { if (tree_view->priv->scroll_timeout_id) { g_source_remove (tree_view->priv->scroll_timeout_id); tree_view->priv->scroll_timeout_id = 0; } gtk_tree_view_set_drag_dest_row (tree_view->view, NULL, 0); }
static gboolean rb_tree_dnd_drag_drop_cb (GtkWidget *widget, GdkDragContext *context, gint x, gint y, guint time) { GtkTreeView *tree_view; GtkTreePath *path; GtkTreeModel *model; GtkTreeViewDropPosition pos; RbTreeDndData *priv_data; tree_view = GTK_TREE_VIEW (widget); model = gtk_tree_view_get_model (tree_view); priv_data = g_object_get_data (G_OBJECT (widget), RB_TREE_DND_STRING); gtk_tree_view_get_dest_row_at_pos (tree_view, x, y, &path, &pos); remove_scroll_timeout (tree_view); /* Unset this thing */ gtk_tree_view_set_drag_dest_row (tree_view, NULL, GTK_TREE_VIEW_DROP_BEFORE); if (path || priv_data->dest_flags & RB_TREE_DEST_EMPTY_VIEW_DROP) { GdkAtom target; RbTreeDragDestIface *iface = RB_TREE_DRAG_DEST_GET_IFACE (model); if (iface->rb_get_drag_target) { RbTreeDragDest *dest = RB_TREE_DRAG_DEST (model); target = (* iface->rb_get_drag_target) (dest, widget, context, path, priv_data->dest_target_list); } else { target = gtk_drag_dest_find_target (widget, context, priv_data->dest_target_list); } if (path) gtk_tree_path_free (path); if (target != GDK_NONE) { gtk_drag_get_data (widget, context, target, time); return TRUE; } } return FALSE; }
static gboolean individual_view_drag_motion_cb (GtkWidget *widget, GdkDragContext *context, gint x, gint y, guint time_) { EmpathyIndividualView *view = EMPATHY_INDIVIDUAL_VIEW (widget); GdkAtom target; target = gtk_drag_dest_find_target (GTK_WIDGET (view), context, NULL); if (target == gdk_atom_intern_static_string ("text/x-persona-id")) { GtkTreePath *path; /* FIXME: It doesn't make sense for us to highlight a specific row or * position to drop a Persona in, so just highlight the entire widget. * Since I can't find a way to do this, just highlight the first possible * position in the tree. */ gdk_drag_status (context, gdk_drag_context_get_suggested_action (context), time_); path = gtk_tree_path_new_first (); gtk_tree_view_set_drag_dest_row (GTK_TREE_VIEW (view), path, GTK_TREE_VIEW_DROP_BEFORE); gtk_tree_path_free (path); return TRUE; } /* Unknown or unhandled drag target */ gdk_drag_status (context, GDK_ACTION_DEFAULT, time_); gtk_tree_view_set_drag_dest_row (GTK_TREE_VIEW (view), NULL, 0); return FALSE; }
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 void rc_gui_list2_dnd_motion(GtkWidget *widget, GdkDragContext *context, gint x, gint y, guint time, gpointer data) { GtkTreeViewDropPosition pos; GtkTreePath *path_drop = NULL; gtk_tree_view_get_dest_row_at_pos(GTK_TREE_VIEW( rc_ui->list2_tree_view), x, y, &path_drop, &pos); if(pos==GTK_TREE_VIEW_DROP_INTO_OR_BEFORE) pos=GTK_TREE_VIEW_DROP_BEFORE; if(pos==GTK_TREE_VIEW_DROP_INTO_OR_AFTER) pos=GTK_TREE_VIEW_DROP_AFTER; if(path_drop) { gtk_tree_view_set_drag_dest_row(GTK_TREE_VIEW( rc_ui->list2_tree_view), path_drop, pos); if(pos==GTK_TREE_VIEW_DROP_AFTER) gtk_tree_path_next(path_drop); else gtk_tree_path_prev(path_drop); gtk_tree_view_scroll_to_cell(GTK_TREE_VIEW( rc_ui->list2_tree_view), path_drop, NULL, FALSE, 0.0, 0.0); gtk_tree_path_free(path_drop); } }
G_MODULE_EXPORT void gw_settingswindow_dictionary_drag_motion_cb ( GtkWidget *widget, GdkDragContext *context, gint x, gint y, guint time, gpointer data) { //Declarations GwSettingsWindow *window; GwSettingsWindowPrivate *priv; GtkTreeView *view; GtkTreeViewDropPosition drop_position; GtkTreePath *path; GtkTreeView *source; //Initializations window = GW_SETTINGSWINDOW (gtk_widget_get_ancestor (GTK_WIDGET (widget), GW_TYPE_SETTINGSWINDOW)); g_return_if_fail (window != NULL); priv = window->priv; view = GTK_TREE_VIEW (widget); source = GTK_TREE_VIEW (gtk_drag_get_source_widget (context)); if (source == priv->manage_dictionaries_treeview) { gtk_tree_view_get_dest_row_at_pos (view, x, y, &path, &drop_position); if (path != NULL) { if (drop_position == GTK_TREE_VIEW_DROP_INTO_OR_BEFORE) drop_position = GTK_TREE_VIEW_DROP_BEFORE; else if (drop_position == GTK_TREE_VIEW_DROP_INTO_OR_AFTER) drop_position = GTK_TREE_VIEW_DROP_AFTER; gtk_tree_view_set_drag_dest_row (view, path, drop_position); } } if (path != NULL) gtk_tree_path_free (path); path = NULL; }
static gboolean rb_tree_dnd_drag_motion_cb (GtkWidget *widget, GdkDragContext *context, gint x, gint y, guint time) { GtkTreeView *tree_view; GtkTreePath *path = NULL; GtkTreeModel *model; GtkTreeViewDropPosition pos; RbTreeDndData *priv_data; GdkDragAction action; rb_debug ("drag and drop motion: (%i,%i)", x, y); tree_view = GTK_TREE_VIEW (widget); model = gtk_tree_view_get_model (tree_view); priv_data = g_object_get_data (G_OBJECT (widget), RB_TREE_DND_STRING); gtk_tree_view_get_dest_row_at_pos (tree_view, x, y, &path, &pos); if ((priv_data->previous_dest_path == NULL) || (path == NULL) || gtk_tree_path_compare(path,priv_data->previous_dest_path)) { remove_select_on_drag_timeout(tree_view); } if (path == NULL) { gtk_tree_view_set_drag_dest_row (GTK_TREE_VIEW (widget), NULL, GTK_TREE_VIEW_DROP_BEFORE); if (!(priv_data->dest_flags & RB_TREE_DEST_EMPTY_VIEW_DROP)) { /* Can't drop here. */ gdk_drag_status (context, 0, time); return TRUE; } else if (!filter_drop_position (widget, context, path, &pos)) { gdk_drag_status (context, 0, time); return TRUE; } } else { if (!filter_drop_position (widget, context, path, &pos)) { gdk_drag_status (context, 0, time); return TRUE; } if (priv_data->scroll_timeout == 0) { priv_data->scroll_timeout = g_timeout_add (150, scroll_row_timeout, tree_view); } } if (GTK_WIDGET (tree_view) == gtk_drag_get_source_widget (context) && context->actions & GDK_ACTION_MOVE) action = GDK_ACTION_MOVE; else action = context->suggested_action; if (path) { gtk_tree_view_set_drag_dest_row (tree_view, path, pos); if (priv_data->dest_flags & RB_TREE_DEST_SELECT_ON_DRAG_TIMEOUT) { if (priv_data->previous_dest_path != NULL) { gtk_tree_path_free (priv_data->previous_dest_path); } priv_data->previous_dest_path = path; if (priv_data->select_on_drag_timeout == 0) { rb_debug("Setting up a new select on drag timeout"); priv_data->select_on_drag_timeout = g_timeout_add_seconds (2, select_on_drag_timeout, tree_view); } } else { gtk_tree_path_free (path); } } gdk_drag_status (context, action, time); return TRUE; }
void NotebooksTreeView::on_drag_leave(const Glib::RefPtr<Gdk::DragContext> & , guint ) { gtk_tree_view_set_drag_dest_row (gobj(), NULL, GTK_TREE_VIEW_DROP_INTO_OR_AFTER); }
gboolean gimp_container_tree_view_drag_motion (GtkWidget *widget, GdkDragContext *context, gint x, gint y, guint time, GimpContainerTreeView *tree_view) { GtkAllocation allocation; GtkTreePath *drop_path; GtkTreeViewDropPosition drop_pos; gtk_widget_get_allocation (widget, &allocation); if (y < SCROLL_DISTANCE || y > (allocation.height - SCROLL_DISTANCE)) { gint distance; if (y < SCROLL_DISTANCE) { tree_view->priv->scroll_dir = GDK_SCROLL_UP; distance = MIN (-y, -1); } else { tree_view->priv->scroll_dir = GDK_SCROLL_DOWN; distance = MAX (allocation.height - y, 1); } tree_view->priv->scroll_timeout_interval = SCROLL_INTERVAL * ABS (distance); #ifdef SCROLL_DEBUG g_print ("drag_motion: scroll_distance = %d scroll_interval = %d\n", distance, tree_view->priv->scroll_timeout_interval); #endif if (! tree_view->priv->scroll_timeout_id) tree_view->priv->scroll_timeout_id = g_timeout_add (tree_view->priv->scroll_timeout_interval, gimp_container_tree_view_scroll_timeout, tree_view); } else if (tree_view->priv->scroll_timeout_id) { g_source_remove (tree_view->priv->scroll_timeout_id); tree_view->priv->scroll_timeout_id = 0; } if (gimp_container_tree_view_drop_status (tree_view, context, x, y, time, &drop_path, NULL, NULL, NULL, NULL, &drop_pos)) { gtk_tree_view_set_drag_dest_row (tree_view->view, drop_path, drop_pos); gtk_tree_path_free (drop_path); } else { gtk_tree_view_set_drag_dest_row (tree_view->view, NULL, 0); } /* always return TRUE so drag_leave() is called */ return TRUE; }
// This little bit is needed to prevent the default drag motion // handler from expanding rows if you hover over them while // dragging. // Also controls where valid drop locations are G_MODULE_EXPORT gboolean queue_drag_motion_cb( GtkTreeView *tv, GdkDragContext *ctx, gint x, gint y, guint time, signal_user_data_t *ud) { GtkTreePath *path = NULL; GtkTreeViewDropPosition pos; gint *indices, row, status, finished; GValue *js; GtkTreeIter iter; GtkTreeView *srctv; GtkTreeModel *model; GtkTreeSelection *select; GtkWidget *widget; widget = gtk_drag_get_source_widget(ctx); if (widget == NULL || widget != GTK_WIDGET(tv)) return TRUE; // This bit checks to see if the source is allowed to be // moved. Only pending and canceled items may be moved. srctv = GTK_TREE_VIEW(gtk_drag_get_source_widget(ctx)); select = gtk_tree_view_get_selection (srctv); gtk_tree_selection_get_selected (select, &model, &iter); path = gtk_tree_model_get_path (model, &iter); indices = gtk_tree_path_get_indices(path); row = indices[0]; gtk_tree_path_free(path); js = ghb_array_get_nth(ud->queue, row); status = ghb_settings_get_int(js, "job_status"); if (status != GHB_QUEUE_PENDING && status != GHB_QUEUE_CANCELED) { gdk_drag_status(ctx, 0, time); return TRUE; } // The reset checks that the destination is a valid position // in the list. Can not move above any finished or running items gtk_tree_view_get_dest_row_at_pos (tv, x, y, &path, &pos); if (path == NULL) { gdk_drag_status(ctx, GDK_ACTION_MOVE, time); return TRUE; } // Don't allow *drop into* if (pos == GTK_TREE_VIEW_DROP_INTO_OR_BEFORE) pos = GTK_TREE_VIEW_DROP_BEFORE; if (pos == GTK_TREE_VIEW_DROP_INTO_OR_AFTER) pos = GTK_TREE_VIEW_DROP_AFTER; // Don't allow droping int child items if (gtk_tree_path_get_depth(path) > 1) { gtk_tree_path_up(path); pos = GTK_TREE_VIEW_DROP_AFTER; } indices = gtk_tree_path_get_indices(path); row = indices[0]; js = ghb_array_get_nth(ud->queue, row); finished = find_last_finished(ud->queue); if (row < finished) { gtk_tree_path_free(path); gdk_drag_status(ctx, 0, time); return TRUE; } if (pos != GTK_TREE_VIEW_DROP_AFTER && row == finished) { gtk_tree_path_free(path); gdk_drag_status(ctx, 0, time); return TRUE; } gtk_tree_view_set_drag_dest_row(tv, path, pos); gtk_tree_path_free(path); gdk_drag_status(ctx, GDK_ACTION_MOVE, time); return TRUE; }
static void clear_drag_dest_row (NautilusTreeViewDragDest *dest) { gtk_tree_view_set_drag_dest_row (dest->details->tree_view, NULL, 0); set_widget_highlight (dest, FALSE); }
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; }
static void clear_drag_dest_row (EphyNodeView *view) { gtk_tree_view_set_drag_dest_row (GTK_TREE_VIEW (view), NULL, 0); }
static void bar_pane_keywords_dnd_receive(GtkWidget *tree_view, GdkDragContext *context, gint x, gint y, GtkSelectionData *selection_data, guint info, guint time, gpointer data) { PaneKeywordsData *pkd = data; GtkTreePath *tpath = NULL; GtkTreeViewDropPosition pos; GtkTreeModel *model; GtkTreeModel *keyword_tree; gboolean src_valid = FALSE; GList *new_keywords = NULL; GList *work; /* iterators for keyword_tree */ GtkTreeIter src_kw_iter; GtkTreeIter dest_kw_iter; GtkTreeIter new_kw_iter; g_signal_stop_emission_by_name(tree_view, "drag_data_received"); model = gtk_tree_view_get_model(GTK_TREE_VIEW(tree_view)); keyword_tree = gtk_tree_model_filter_get_model(GTK_TREE_MODEL_FILTER(model)); gtk_tree_view_get_dest_row_at_pos(GTK_TREE_VIEW(tree_view), x, y, &tpath, &pos); gtk_tree_view_set_drag_dest_row(GTK_TREE_VIEW(tree_view), NULL, pos); switch (info) { case TARGET_APP_KEYWORD_PATH: { GList *path = *(gpointer *)gtk_selection_data_get_data(selection_data); src_valid = keyword_tree_get_iter(keyword_tree, &src_kw_iter, path); string_list_free(path); break; } default: new_keywords = string_to_keywords_list((gchar *)gtk_selection_data_get_data(selection_data)); break; } if (tpath) { GtkTreeIter dest_iter; gtk_tree_model_get_iter(model, &dest_iter, tpath); gtk_tree_path_free(tpath); gtk_tree_model_filter_convert_iter_to_child_iter(GTK_TREE_MODEL_FILTER(model), &dest_kw_iter, &dest_iter); if (src_valid && gtk_tree_store_is_ancestor(GTK_TREE_STORE(keyword_tree), &src_kw_iter, &dest_kw_iter)) { /* can't move to it's own child */ return; } if (src_valid && keyword_compare(keyword_tree, &src_kw_iter, &dest_kw_iter) == 0) { /* can't move to itself */ return; } if ((pos == GTK_TREE_VIEW_DROP_INTO_OR_BEFORE || pos == GTK_TREE_VIEW_DROP_INTO_OR_AFTER) && !gtk_tree_model_iter_has_child(keyword_tree, &dest_kw_iter)) { /* the node has no children, all keywords can be added */ gtk_tree_store_append(GTK_TREE_STORE(keyword_tree), &new_kw_iter, &dest_kw_iter); } else { if (src_valid && !bar_pane_keywords_dnd_can_move(keyword_tree, &src_kw_iter, &dest_kw_iter)) { /* the keyword can't be moved if the same name already exist */ return; } if (new_keywords && !bar_pane_keywords_dnd_skip_existing(keyword_tree, &dest_kw_iter, &new_keywords)) { /* the keywords can't be added if the same name already exist */ return; } switch (pos) { case GTK_TREE_VIEW_DROP_INTO_OR_BEFORE: case GTK_TREE_VIEW_DROP_BEFORE: gtk_tree_store_insert_before(GTK_TREE_STORE(keyword_tree), &new_kw_iter, NULL, &dest_kw_iter); break; case GTK_TREE_VIEW_DROP_INTO_OR_AFTER: case GTK_TREE_VIEW_DROP_AFTER: gtk_tree_store_insert_after(GTK_TREE_STORE(keyword_tree), &new_kw_iter, NULL, &dest_kw_iter); break; } } } else { if (src_valid && !bar_pane_keywords_dnd_can_move(keyword_tree, &src_kw_iter, NULL)) { /* the keyword can't be moved if the same name already exist */ return; } if (new_keywords && !bar_pane_keywords_dnd_skip_existing(keyword_tree, NULL, &new_keywords)) { /* the keywords can't be added if the same name already exist */ return; } gtk_tree_store_append(GTK_TREE_STORE(keyword_tree), &new_kw_iter, NULL); } if (src_valid) { keyword_move_recursive(GTK_TREE_STORE(keyword_tree), &new_kw_iter, &src_kw_iter); } work = new_keywords; while (work) { gchar *keyword = work->data; keyword_set(GTK_TREE_STORE(keyword_tree), &new_kw_iter, keyword, TRUE); work = work->next; if (work) { GtkTreeIter add; gtk_tree_store_insert_after(GTK_TREE_STORE(keyword_tree), &add, NULL, &new_kw_iter); new_kw_iter = add; } } string_list_free(new_keywords); bar_keyword_tree_sync(pkd); }