[balsa/gtk4] mblist: drag-and-drop
- From: Peter Bloomfield <peterb src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [balsa/gtk4] mblist: drag-and-drop
- Date: Thu, 22 Oct 2020 17:20:47 +0000 (UTC)
commit cf91a042aec0c4560d7ce5abb8366bd5eef2fb1e
Author: Peter Bloomfield <PeterBloomfield bellsouth net>
Date: Wed Oct 21 13:50:52 2020 -0400
mblist: drag-and-drop
src/balsa-mblist.c | 126 +++++++++++++++++++++++++++++------------------------
1 file changed, 68 insertions(+), 58 deletions(-)
---
diff --git a/src/balsa-mblist.c b/src/balsa-mblist.c
index d4ce91f0c..3db3d695f 100644
--- a/src/balsa-mblist.c
+++ b/src/balsa-mblist.c
@@ -75,18 +75,11 @@ enum {
};
static gint balsa_mblist_signals[LAST_SIGNAL] = { 0 };
-static GtkTargetEntry bmbl_drop_types[] = {
- {"x-application/x-message-list", GTK_TARGET_SAME_APP, TARGET_MESSAGES}
-};
-
/* class methods */
static void bmbl_set_property(GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec);
static void bmbl_get_property(GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec);
-static gboolean bmbl_drag_motion(GtkWidget * mblist,
- GdkDragContext * context, gint x, gint y,
- guint time);
static gboolean bmbl_selection_func(GtkTreeSelection * selection,
GtkTreeModel * model,
GtkTreePath * path,
@@ -104,10 +97,14 @@ static gint bmbl_row_compare(GtkTreeModel * model,
static void bmbl_column_resize(GObject *gobject,
GParamSpec *pspec,
gpointer user_data);
-static void bmbl_drag_cb(GtkWidget * widget, GdkDragContext * context,
- gint x, gint y,
- GtkSelectionData * selection_data, guint info,
- guint32 time, gpointer data);
+static gboolean bmbl_drag_accept(GtkDropTarget *drop_target,
+ GdkDrop *drop,
+ gpointer user_data);
+static gboolean bmbl_drag_drop(GtkDropTarget *drop_target,
+ GValue *value,
+ gdouble x,
+ gdouble y,
+ gpointer user_data);
static void bmbl_row_activated_cb(GtkTreeView * tree_view,
GtkTreePath * path,
GtkTreeViewColumn * column,
@@ -152,10 +149,8 @@ static void
balsa_mblist_class_init(BalsaMBListClass * klass)
{
GObjectClass *object_class;
- GtkWidgetClass *widget_class;
object_class = (GObjectClass *) klass;
- widget_class = (GtkWidgetClass *) klass;
/* HAS_UNREAD_MAILBOX is emitted when the number of mailboxes with
* unread mail might have changed. */
@@ -173,9 +168,6 @@ balsa_mblist_class_init(BalsaMBListClass * klass)
object_class->set_property = bmbl_set_property;
object_class->get_property = bmbl_get_property;
- /* GtkWidget signals */
- widget_class->drag_motion = bmbl_drag_motion;
-
/* Properties */
g_object_class_install_property(object_class, PROP_SHOW_CONTENT_INFO,
g_param_spec_boolean
@@ -271,23 +263,26 @@ bmbl_get_property(GObject * object, guint prop_id, GValue * value,
}
}
+/*
+ * bmbl_drag_accept
+ *
+ * Handler for the "accept" signal
+ */
+
static gboolean
-bmbl_drag_motion(GtkWidget * mblist, GdkDragContext * context, gint x,
- gint y, guint time)
+bmbl_drag_accept(GtkDropTarget *drop_target,
+ GdkDrop *drop,
+ gpointer user_data)
{
+ BalsaMBList *mblist = user_data;
GtkTreeView *tree_view = GTK_TREE_VIEW(mblist);
GtkTreePath *path;
GtkTreeSelection *selection = gtk_tree_view_get_selection(tree_view);
GtkTreeModel *model = gtk_tree_view_get_model(tree_view);
- gboolean ret_val;
gboolean can_drop;
- ret_val =
- GTK_WIDGET_CLASS(balsa_mblist_parent_class)->drag_motion(mblist, context, x, y,
- time);
-
gtk_tree_view_get_drag_dest_row(tree_view, &path, NULL);
- if (!path)
+ if (path == NULL)
return FALSE;
can_drop = bmbl_selection_func(selection, model, path, FALSE, NULL);
@@ -295,12 +290,7 @@ bmbl_drag_motion(GtkWidget * mblist, GdkDragContext * context, gint x,
GTK_TREE_VIEW_DROP_INTO_OR_BEFORE);
gtk_tree_path_free(path);
- gdk_drag_status(context,
- (gdk_drag_context_get_actions(context) ==
- GDK_ACTION_COPY) ? GDK_ACTION_COPY :
- GDK_ACTION_MOVE, time);
-
- return (ret_val && can_drop);
+ return can_drop;
}
/*
@@ -746,21 +736,25 @@ bmbl_column_resize(GObject *gobject,
}
}
-/* bmbl_drag_cb
+/*
+ * bmbl_drag_drop_callback
*
- * Description: This is the drag_data_received signal handler for the
+ * Description: This is the async callback for the
* BalsaMBList. It retrieves the source BalsaIndex and transfers the
* index's selected messages to the target
* mailbox. Depending on what key is held down when the message(s)
* are dropped they are either copied or moved. The default action is
* to copy.
- * */
+ */
static void
-bmbl_drag_cb(GtkWidget * widget, GdkDragContext * context,
- gint x, gint y, GtkSelectionData * selection_data,
- guint info, guint32 time, gpointer data)
+bmbl_drag_drop_callback(GObject *source_object,
+ GAsyncResult *res,
+ gpointer user_data)
{
- GtkTreeView *tree_view = GTK_TREE_VIEW(widget);
+ GdkDrop *drop = GDK_DROP(source_object);
+ BalsaMBList *mblist = user_data;
+ const GValue *value;
+ GtkTreeView *tree_view = GTK_TREE_VIEW(mblist);
GtkTreeModel *model = gtk_tree_view_get_model(tree_view);
GtkTreeSelection *selection = gtk_tree_view_get_selection(tree_view);
GtkTreePath *path;
@@ -770,12 +764,8 @@ bmbl_drag_cb(GtkWidget * widget, GdkDragContext * context,
BalsaIndex *orig_index;
GArray *selected;
- if (!selection_data || !gtk_selection_data_get_data(selection_data))
- /* Drag'n'drop is weird... */
- return;
-
- orig_index =
- *(BalsaIndex **) gtk_selection_data_get_data(selection_data);
+ value = gdk_drop_read_value_finish(drop, res, NULL);
+ orig_index = g_value_get_pointer(value);
selected = balsa_index_selected_msgnos_new(orig_index);
if (selected->len == 0) {
/* it is actually possible to drag from GtkTreeView when no rows
@@ -787,13 +777,8 @@ bmbl_drag_cb(GtkWidget * widget, GdkDragContext * context,
orig_mailbox = balsa_index_get_mailbox(orig_index);
/* find the node and mailbox */
-
- /* we should be able to use:
- * gtk_tree_view_get_drag_dest_row(tree_view, &path, NULL);
- * but it sets path to NULL for some reason, so we'll go down to a
- * lower level. */
- if (gtk_tree_view_get_dest_row_at_pos(tree_view,
- x, y, &path, NULL)) {
+ gtk_tree_view_get_drag_dest_row(tree_view, &path, NULL);
+ if (path != NULL) {
BalsaMailboxNode *mbnode;
gtk_tree_model_get_iter(model, &iter, path);
@@ -804,8 +789,7 @@ bmbl_drag_cb(GtkWidget * widget, GdkDragContext * context,
/* cannot transfer to the originating mailbox */
if (mailbox != NULL && mailbox != orig_mailbox)
balsa_index_transfer(orig_index, selected, mailbox,
- gdk_drag_context_get_selected_action
- (context) != GDK_ACTION_MOVE);
+ gdk_drop_get_actions(drop) != GDK_ACTION_MOVE);
gtk_tree_path_free(path);
}
balsa_index_selected_msgnos_free(orig_index, selected);
@@ -814,6 +798,31 @@ bmbl_drag_cb(GtkWidget * widget, GdkDragContext * context,
gtk_tree_selection_select_iter(selection, &iter);
}
+/*
+ * bmbl_drag_drop
+ *
+ * Description: This is the "drop" signal handler for the
+ * BalsaMBList. It launches the async operation that carries out the
+ * actual drop.
+ */
+static gboolean
+bmbl_drag_drop(GtkDropTarget *drop_target,
+ GValue *value,
+ gdouble x,
+ gdouble y,
+ gpointer user_data)
+{
+ GdkDrop *drop;
+
+ drop = gtk_drop_target_get_drop(drop_target);
+ if (drop == NULL)
+ return FALSE;
+
+ gdk_drop_read_value_async(drop, BALSA_TYPE_INDEX, 0, NULL, bmbl_drag_drop_callback, user_data);
+
+ return TRUE;
+}
+
/*
* bmbl_row_activated_cb: callback for the "row-activated" signal
*
@@ -1138,6 +1147,7 @@ balsa_mblist_default_signal_bindings(BalsaMBList * mblist)
GtkGesture *gesture;
int n;
GtkTreeViewColumn *column;
+ GtkDropTarget *drop_target;
gesture = gtk_gesture_click_new();
gtk_widget_add_controller(GTK_WIDGET(mblist), GTK_EVENT_CONTROLLER(gesture));
@@ -1148,14 +1158,14 @@ balsa_mblist_default_signal_bindings(BalsaMBList * mblist)
for (n = 0; (column = gtk_tree_view_get_column(GTK_TREE_VIEW(mblist), n)) != NULL; n++)
g_signal_connect(column, "notify::width", G_CALLBACK(bmbl_column_resize), mblist);
- gtk_tree_view_enable_model_drag_dest(GTK_TREE_VIEW(mblist),
- bmbl_drop_types, G_N_ELEMENTS(bmbl_drop_types),
- GDK_ACTION_DEFAULT | GDK_ACTION_COPY | GDK_ACTION_MOVE);
- g_signal_connect(mblist, "drag-data-received",
- G_CALLBACK(bmbl_drag_cb), NULL);
-
g_signal_connect(mblist, "row-activated",
G_CALLBACK(bmbl_row_activated_cb), NULL);
+
+ /* Drag and drop */
+ drop_target = gtk_drop_target_new(BALSA_TYPE_INDEX, GDK_ACTION_COPY | GDK_ACTION_MOVE);
+ gtk_widget_add_controller(GTK_WIDGET(mblist), GTK_EVENT_CONTROLLER(drop_target));
+ g_signal_connect(drop_target, "accept", G_CALLBACK(bmbl_drag_accept), mblist);
+ g_signal_connect(drop_target, "drop", G_CALLBACK(bmbl_drag_drop), mblist);
}
/* bmbl_disconnect_mailbox_signals
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]