[gnome-documents] views: add support for text/uri-list DnD source
- From: Cosimo Cecchi <cosimoc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-documents] views: add support for text/uri-list DnD source
- Date: Mon, 5 Mar 2012 22:22:21 +0000 (UTC)
commit 8953dd6d789b952fce0c28ff01f9176b33a12c15
Author: Cosimo Cecchi <cosimoc gnome org>
Date: Thu Mar 1 17:24:43 2012 -0500
views: add support for text/uri-list DnD source
Support being a text/uri-list DnD source. This means we're now able to
drag items outside of the views to applications who understand the
protocol.
src/lib/gd-main-icon-view.c | 42 +++++++++++++++++++++++
src/lib/gd-main-list-view.c | 43 +++++++++++++++++++++++
src/lib/gd-main-view-generic.c | 73 ++++++++++++++++++++++++++++++++++++++++
src/lib/gd-main-view-generic.h | 6 +++
src/lib/gd-main-view.c | 6 ++--
5 files changed, 167 insertions(+), 3 deletions(-)
---
diff --git a/src/lib/gd-main-icon-view.c b/src/lib/gd-main-icon-view.c
index b796280..a7f98f2 100644
--- a/src/lib/gd-main-icon-view.c
+++ b/src/lib/gd-main-icon-view.c
@@ -51,11 +51,47 @@ on_icon_selection_changed (GtkIconView *iv,
g_signal_emit_by_name (self, "view-selection-changed");
}
+static GtkTreePath*
+get_source_row (GdkDragContext *context)
+{
+ GtkTreeRowReference *ref;
+
+ ref = g_object_get_data (G_OBJECT (context), "gtk-icon-view-source-row");
+
+ if (ref)
+ return gtk_tree_row_reference_get_path (ref);
+ else
+ return NULL;
+}
+
+static void
+gd_main_icon_view_drag_data_get (GtkWidget *widget,
+ GdkDragContext *drag_context,
+ GtkSelectionData *data,
+ guint info,
+ guint time)
+{
+ GdMainIconView *self = GD_MAIN_ICON_VIEW (widget);
+ GtkTreeModel *model = gtk_icon_view_get_model (GTK_ICON_VIEW (self));
+
+ if (info != 0)
+ return;
+
+ _gd_main_view_generic_dnd_common (model, self->priv->selection_mode,
+ get_source_row (drag_context), data);
+
+ GTK_WIDGET_CLASS (gd_main_icon_view_parent_class)->drag_data_get (widget, drag_context,
+ data, info, time);
+}
+
static void
gd_main_icon_view_constructed (GObject *obj)
{
GdMainIconView *self = GD_MAIN_ICON_VIEW (obj);
GtkCellRenderer *cell;
+ const GtkTargetEntry targets[] = {
+ { "text/uri-list", GTK_TARGET_OTHER_APP, 0 }
+ };
G_OBJECT_CLASS (gd_main_icon_view_parent_class)->constructed (obj);
@@ -95,6 +131,11 @@ gd_main_icon_view_constructed (GObject *obj)
"text", GD_MAIN_COLUMN_TITLE);
gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (self), cell,
"line-two", GD_MAIN_COLUMN_AUTHOR);
+
+ gtk_icon_view_enable_model_drag_source (GTK_ICON_VIEW (self),
+ GDK_BUTTON1_MASK,
+ targets, 1,
+ GDK_ACTION_COPY);
}
static void
@@ -104,6 +145,7 @@ gd_main_icon_view_class_init (GdMainIconViewClass *klass)
GtkWidgetClass *wclass = GTK_WIDGET_CLASS (klass);
oclass->constructed = gd_main_icon_view_constructed;
+ wclass->drag_data_get = gd_main_icon_view_drag_data_get;
gtk_widget_class_install_style_property (wclass,
g_param_spec_int ("check-icon-size",
diff --git a/src/lib/gd-main-list-view.c b/src/lib/gd-main-list-view.c
index 34dabf3..7b9fd51 100644
--- a/src/lib/gd-main-list-view.c
+++ b/src/lib/gd-main-list-view.c
@@ -38,12 +38,48 @@ G_DEFINE_TYPE_WITH_CODE (GdMainListView, gd_main_list_view, GTK_TYPE_TREE_VIEW,
G_IMPLEMENT_INTERFACE (GD_TYPE_MAIN_VIEW_GENERIC,
gd_main_view_generic_iface_init))
+static GtkTreePath*
+get_source_row (GdkDragContext *context)
+{
+ GtkTreeRowReference *ref =
+ g_object_get_data (G_OBJECT (context), "gtk-tree-view-source-row");
+
+ if (ref)
+ return gtk_tree_row_reference_get_path (ref);
+ else
+ return NULL;
+}
+
+static void
+gd_main_list_view_drag_data_get (GtkWidget *widget,
+ GdkDragContext *drag_context,
+ GtkSelectionData *data,
+ guint info,
+ guint time)
+{
+ GdMainListView *self = GD_MAIN_LIST_VIEW (widget);
+ GtkTreeModel *model = gtk_tree_view_get_model (GTK_TREE_VIEW (self));
+
+ if (info != 0)
+ return;
+
+ _gd_main_view_generic_dnd_common (model,
+ self->priv->selection_mode,
+ get_source_row (drag_context), data);
+
+ GTK_WIDGET_CLASS (gd_main_list_view_parent_class)->drag_data_get (widget, drag_context,
+ data, info, time);
+}
+
static void
gd_main_list_view_constructed (GObject *obj)
{
GdMainListView *self = GD_MAIN_LIST_VIEW (obj);
GtkCellRenderer *cell;
GtkTreeSelection *selection;
+ const GtkTargetEntry targets[] = {
+ { "text/uri-list", GTK_TARGET_OTHER_APP, 0 }
+ };
G_OBJECT_CLASS (gd_main_list_view_parent_class)->constructed (obj);
@@ -91,14 +127,21 @@ gd_main_list_view_constructed (GObject *obj)
"text", GD_MAIN_COLUMN_TITLE);
gtk_tree_view_column_add_attribute (self->priv->tree_col, cell,
"line-two", GD_MAIN_COLUMN_AUTHOR);
+
+ gtk_tree_view_enable_model_drag_source (GTK_TREE_VIEW (self),
+ GDK_BUTTON1_MASK,
+ targets, 1,
+ GDK_ACTION_COPY);
}
static void
gd_main_list_view_class_init (GdMainListViewClass *klass)
{
GObjectClass *oclass = G_OBJECT_CLASS (klass);
+ GtkWidgetClass *wclass = GTK_WIDGET_CLASS (klass);
oclass->constructed = gd_main_list_view_constructed;
+ wclass->drag_data_get = gd_main_list_view_drag_data_get;
g_type_class_add_private (klass, sizeof (GdMainListViewPrivate));
}
diff --git a/src/lib/gd-main-view-generic.c b/src/lib/gd-main-view-generic.c
index f3d1600..9b69391 100644
--- a/src/lib/gd-main-view-generic.c
+++ b/src/lib/gd-main-view-generic.c
@@ -19,6 +19,7 @@
*
*/
+#include "gd-main-view.h"
#include "gd-main-view-generic.h"
enum {
@@ -93,3 +94,75 @@ gd_main_view_generic_scroll_to_path (GdMainViewGeneric *self,
(* iface->scroll_to_path) (self, path);
}
+
+static gboolean
+build_selection_uris_foreach (GtkTreeModel *model,
+ GtkTreePath *path,
+ GtkTreeIter *iter,
+ gpointer user_data)
+{
+ GPtrArray *ptr_array = user_data;
+ gchar *uri;
+ gboolean is_selected;
+
+ gtk_tree_model_get (model, iter,
+ GD_MAIN_COLUMN_URI, &uri,
+ GD_MAIN_COLUMN_SELECTED, &is_selected,
+ -1);
+
+ if (is_selected)
+ g_ptr_array_add (ptr_array, uri);
+ else
+ g_free (uri);
+
+ return FALSE;
+}
+
+static gchar **
+model_get_selection_uris (GtkTreeModel *model)
+{
+ GPtrArray *ptr_array = g_ptr_array_new ();
+
+ gtk_tree_model_foreach (model,
+ build_selection_uris_foreach,
+ ptr_array);
+
+ g_ptr_array_add (ptr_array, NULL);
+ return (gchar **) g_ptr_array_free (ptr_array, FALSE);
+}
+
+void
+_gd_main_view_generic_dnd_common (GtkTreeModel *model,
+ gboolean selection_mode,
+ GtkTreePath *path,
+ GtkSelectionData *data)
+{
+ gchar **uris;
+
+ if (selection_mode)
+ {
+ uris = model_get_selection_uris (model);
+ }
+ else
+ {
+ GtkTreeIter iter;
+ gboolean res;
+ gchar *uri = NULL;
+
+ if (path != NULL)
+ {
+ res = gtk_tree_model_get_iter (model, &iter, path);
+ if (res)
+ gtk_tree_model_get (model, &iter,
+ GD_MAIN_COLUMN_URI, &uri,
+ -1);
+ }
+
+ uris = g_new0 (gchar *, 2);
+ uris[0] = uri;
+ uris[1] = NULL;
+ }
+
+ gtk_selection_data_set_uris (data, uris);
+ g_strfreev (uris);
+}
diff --git a/src/lib/gd-main-view-generic.h b/src/lib/gd-main-view-generic.h
index f99a950..b59b547 100644
--- a/src/lib/gd-main-view-generic.h
+++ b/src/lib/gd-main-view-generic.h
@@ -86,6 +86,12 @@ GtkTreePath * gd_main_view_generic_get_path_at_pos (GdMainViewGeneric *self,
gint x,
gint y);
+/* private */
+void _gd_main_view_generic_dnd_common (GtkTreeModel *model,
+ gboolean selection_mode,
+ GtkTreePath *path,
+ GtkSelectionData *data);
+
G_END_DECLS
#endif /* __GD_MAIN_VIEW_GENERIC_H__ */
diff --git a/src/lib/gd-main-view.c b/src/lib/gd-main-view.c
index 1ebd72b..2990e84 100644
--- a/src/lib/gd-main-view.c
+++ b/src/lib/gd-main-view.c
@@ -242,7 +242,7 @@ on_button_release_selection_mode (GdMainView *self,
g_signal_emit_by_name (generic, "view-selection-changed");
- return TRUE;
+ return FALSE;
}
static gboolean
@@ -266,7 +266,7 @@ on_button_release_view_mode (GdMainView *self,
g_signal_emit (self, signals[ITEM_ACTIVATED], 0, id, path);
g_free (id);
- return TRUE;
+ return FALSE;
}
static gboolean
@@ -358,7 +358,7 @@ on_button_press_event (GtkWidget *view,
/* TODO: eat button press events for now; in the future we might want
* to add support for DnD.
*/
- return TRUE;
+ return FALSE;
}
static void
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]