[gnome-builder] app: Implement support for drag and drop
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder] app: Implement support for drag and drop
- Date: Mon, 19 Jan 2015 01:50:31 +0000 (UTC)
commit 5261beb638391d61411dbeeed4706eb62ee6943f
Author: Dimitris Zenios <dimitris zenios gmail com>
Date: Sat Jan 17 15:15:22 2015 +0200
app: Implement support for drag and drop
- Current support "text/uri-list" drop type on GbEditorWorkspace and GbSourceView
- Missing support for dnd on GbDevhelpView
- Missing support for dnd on GbHtmlView
- Missing support for XdndDirectSave0 drop type
https://bugzilla.gnome.org/show_bug.cgi?id=742865
src/editor/gb-editor-frame.c | 39 ++++++++++++++
src/editor/gb-editor-workspace.c | 103 ++++++++++++++++++++++++++++++++++++-
src/editor/gb-source-view.c | 63 +++++++++++++++++++++++
src/editor/gb-source-view.h | 2 +
src/gnome-builder.mk | 2 +
src/util/gb-dnd.c | 41 +++++++++++++++
src/util/gb-dnd.h | 30 +++++++++++
7 files changed, 277 insertions(+), 3 deletions(-)
---
diff --git a/src/editor/gb-editor-frame.c b/src/editor/gb-editor-frame.c
index eee712b..d67f7b1 100644
--- a/src/editor/gb-editor-frame.c
+++ b/src/editor/gb-editor-frame.c
@@ -1128,6 +1128,39 @@ gb_editor_frame_on_jump_to_doc (GbEditorFrame *self,
}
static void
+gb_editor_frame_on_drop_uris (GbEditorFrame *self,
+ const gchar **uri_list,
+ GbSourceView *source_view)
+{
+ GActionGroup *action_group;
+ GbWorkbench *workbench;
+ GVariantBuilder *builder;
+ GVariant *variant;
+ int i;
+
+ ENTRY;
+
+ g_return_if_fail (GB_IS_EDITOR_FRAME (self));
+ g_return_if_fail (GB_IS_SOURCE_VIEW (source_view));
+ g_return_if_fail (uri_list);
+
+ builder = g_variant_builder_new (G_VARIANT_TYPE_STRING_ARRAY);
+ for (i = 0; uri_list[i] != NULL; i++)
+ {
+ g_variant_builder_add (builder, "s", uri_list[i]);
+ }
+ variant = g_variant_builder_end (builder);
+ g_variant_builder_unref (builder);
+
+ workbench = gb_widget_get_workbench (GTK_WIDGET (self));
+ action_group = gtk_widget_get_action_group (GTK_WIDGET (workbench),
+ "workspace");
+ g_action_group_activate_action (action_group, "open-uri-list", variant);
+
+ EXIT;
+}
+
+static void
gb_editor_frame_grab_focus (GtkWidget *widget)
{
GbEditorFrame *self = (GbEditorFrame *)widget;
@@ -1481,6 +1514,12 @@ gb_editor_frame_constructed (GObject *object)
G_CONNECT_SWAPPED);
g_signal_connect_object (priv->source_view,
+ "drop-uris",
+ G_CALLBACK (gb_editor_frame_on_drop_uris),
+ self,
+ G_CONNECT_SWAPPED);
+
+ g_signal_connect_object (priv->source_view,
"focus-in-event",
G_CALLBACK (gb_editor_frame_on_focus_in_event),
self,
diff --git a/src/editor/gb-editor-workspace.c b/src/editor/gb-editor-workspace.c
index 11b9048..239ed2e 100644
--- a/src/editor/gb-editor-workspace.c
+++ b/src/editor/gb-editor-workspace.c
@@ -30,6 +30,16 @@
#include "gb-tree.h"
#include "gb-widget.h"
#include "gb-workbench.h"
+#include "gb-dnd.h"
+
+enum
+{
+ TARGET_URI_LIST = 100
+};
+
+static const GtkTargetEntry drop_types [] = {
+ { "text/uri-list", 0, TARGET_URI_LIST}
+};
struct _GbEditorWorkspacePrivate
{
@@ -73,6 +83,59 @@ gb_editor_workspace_open (GbEditorWorkspace *workspace,
}
static void
+gb_editor_workspace_open_uri_list (GbEditorWorkspace *workspace,
+ const gchar **uri_list)
+{
+ int i;
+ GFile *file;
+
+ g_return_if_fail (GB_IS_EDITOR_WORKSPACE (workspace));
+ g_return_if_fail (uri_list);
+
+ for (i = 0; uri_list[i] != NULL; i++)
+ {
+ file = g_file_new_for_commandline_arg (uri_list[i]);
+ gb_editor_workspace_open (workspace, file);
+ g_clear_object (&file);
+ }
+}
+
+static void
+gb_editor_workspace_drag_data_received (GtkWidget *widget,
+ GdkDragContext *context,
+ gint x,
+ gint y,
+ GtkSelectionData *selection_data,
+ guint info,
+ guint timestamp,
+ gpointer data)
+{
+ GbEditorWorkspace *workspace = (GbEditorWorkspace *)widget;
+ gchar **uri_list;
+ gboolean handled = FALSE;
+
+ g_return_if_fail (GB_IS_EDITOR_WORKSPACE (workspace));
+
+ switch (info)
+ {
+ case TARGET_URI_LIST:
+ uri_list = gb_dnd_get_uri_list (selection_data);
+ if (uri_list != NULL)
+ {
+ gb_editor_workspace_open_uri_list (workspace, (const gchar **) uri_list);
+ g_strfreev (uri_list);
+ }
+ handled = TRUE;
+ break;
+
+ default:
+ break;
+ }
+
+ gtk_drag_finish (context, handled, FALSE, timestamp);
+}
+
+static void
gb_editor_workspace_action_jump_to_doc (GSimpleAction *action,
GVariant *parameter,
gpointer user_data)
@@ -112,6 +175,24 @@ gb_editor_workspace_action_jump_to_doc (GSimpleAction *action,
}
static void
+gb_editor_workspace_action_open_uri_list (GSimpleAction *action,
+ GVariant *parameter,
+ gpointer user_data)
+{
+ GbEditorWorkspace *workspace = user_data;
+ const gchar **uri_list;
+
+ g_return_if_fail (GB_IS_EDITOR_WORKSPACE (workspace));
+
+ uri_list = g_variant_get_strv (parameter, NULL);
+ if(uri_list != NULL)
+ {
+ gb_editor_workspace_open_uri_list (workspace, uri_list);
+ g_free (uri_list);
+ }
+}
+
+static void
gb_editor_workspace_action_new_document (GSimpleAction *action,
GVariant *parameter,
gpointer user_data)
@@ -275,9 +356,10 @@ static void
gb_editor_workspace_init (GbEditorWorkspace *workspace)
{
const GActionEntry entries[] = {
- { "open", gb_editor_workspace_action_open },
- { "new-document", gb_editor_workspace_action_new_document },
- { "jump-to-doc", gb_editor_workspace_action_jump_to_doc, "s" },
+ { "open", gb_editor_workspace_action_open },
+ { "new-document", gb_editor_workspace_action_new_document },
+ { "jump-to-doc", gb_editor_workspace_action_jump_to_doc, "s" },
+ { "open-uri-list", gb_editor_workspace_action_open_uri_list, "as" }
};
GSimpleActionGroup *actions;
@@ -295,4 +377,19 @@ gb_editor_workspace_init (GbEditorWorkspace *workspace)
gtk_widget_insert_action_group (GTK_WIDGET (workspace), "workspace",
G_ACTION_GROUP (actions));
g_clear_object (&actions);
+
+ /* Drag and drop support*/
+ gtk_drag_dest_set (GTK_WIDGET (workspace),
+ GTK_DEST_DEFAULT_MOTION |
+ GTK_DEST_DEFAULT_HIGHLIGHT |
+ GTK_DEST_DEFAULT_DROP,
+ drop_types,
+ G_N_ELEMENTS (drop_types),
+ GDK_ACTION_COPY);
+
+ g_signal_connect (workspace,
+ "drag-data-received",
+ G_CALLBACK(gb_editor_workspace_drag_data_received),
+ NULL);
+
}
diff --git a/src/editor/gb-source-view.c b/src/editor/gb-source-view.c
index 56a175b..886c59e 100644
--- a/src/editor/gb-source-view.c
+++ b/src/editor/gb-source-view.c
@@ -29,6 +29,7 @@
#include "gb-source-auto-indenter-xml.h"
#include "gb-box-theatric.h"
#include "gb-cairo.h"
+#include "gb-dnd.h"
#include "gb-editor-document.h"
#include "gb-gtk.h"
#include "gb-html-completion-provider.h"
@@ -45,6 +46,11 @@
#include "gb-source-vim.h"
#include "gb-widget.h"
+enum
+{
+ TARGET_URI_LIST = 100
+};
+
struct _GbSourceViewPrivate
{
GQueue *snippets;
@@ -101,6 +107,7 @@ enum {
POP_SNIPPET,
PUSH_SNIPPET,
REQUEST_DOCUMENTATION,
+ DROP_URIS,
LAST_SIGNAL
};
@@ -1982,6 +1989,42 @@ gb_source_view_constructed (GObject *object)
NULL);
}
+static void
+gb_source_view_drag_data_received (GtkWidget *widget,
+ GdkDragContext *context,
+ gint x,
+ gint y,
+ GtkSelectionData *selection_data,
+ guint info,
+ guint timestamp)
+{
+ gchar **uri_list;
+
+ g_return_if_fail (GB_IS_SOURCE_VIEW (widget));
+
+ switch (info)
+ {
+ case TARGET_URI_LIST:
+ uri_list = gb_dnd_get_uri_list (selection_data);
+ if (uri_list != NULL)
+ {
+ g_signal_emit (widget, gSignals[DROP_URIS], 0, uri_list);
+ g_strfreev (uri_list);
+ }
+ gtk_drag_finish (context, TRUE, FALSE, timestamp);
+ break;
+
+ default:
+ GTK_WIDGET_CLASS (gb_source_view_parent_class)->drag_data_received (widget,
+ context,
+ x, y,
+ selection_data,
+ info,
+ timestamp);
+ break;
+ }
+}
+
static gboolean
gb_source_view_focus_in_event (GtkWidget *widget,
GdkEventFocus *event)
@@ -2159,6 +2202,7 @@ gb_source_view_class_init (GbSourceViewClass *klass)
widget_class->focus_out_event = gb_source_view_focus_out_event;
widget_class->grab_focus = gb_source_view_grab_focus;
widget_class->key_press_event = gb_source_view_key_press_event;
+ widget_class->drag_data_received = gb_source_view_drag_data_received;
text_view_class->draw_layer = gb_source_view_draw_layer;
@@ -2308,6 +2352,17 @@ gb_source_view_class_init (GbSourceViewClass *klass)
G_TYPE_NONE,
0);
+ gSignals [DROP_URIS] =
+ g_signal_new ("drop-uris",
+ GB_TYPE_SOURCE_VIEW,
+ G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+ G_STRUCT_OFFSET (GbSourceViewClass, drop_uris),
+ NULL, NULL,
+ g_cclosure_marshal_generic,
+ G_TYPE_NONE,
+ 1,
+ G_TYPE_STRV);
+
binding_set = gtk_binding_set_by_class (klass);
gtk_binding_entry_add_signal (binding_set,
GDK_KEY_k,
@@ -2320,6 +2375,7 @@ static void
gb_source_view_init (GbSourceView *view)
{
GtkSourceCompletion *completion;
+ GtkTargetList *tl;
view->priv = gb_source_view_get_instance_private (view);
@@ -2359,4 +2415,11 @@ gb_source_view_init (GbSourceView *view)
completion = gtk_source_view_get_completion (GTK_SOURCE_VIEW (view));
gtk_source_completion_block_interactive (completion);
+
+ /* Drag and drop support */
+ tl = gtk_drag_dest_get_target_list (GTK_WIDGET (view));
+ if (tl != NULL)
+ {
+ gtk_target_list_add_uri_targets (tl, TARGET_URI_LIST);
+ }
}
diff --git a/src/editor/gb-source-view.h b/src/editor/gb-source-view.h
index 9746c6f..d1be242 100644
--- a/src/editor/gb-source-view.h
+++ b/src/editor/gb-source-view.h
@@ -66,6 +66,8 @@ struct _GbSourceViewClass
void (*request_documentation) (GbSourceView *view);
void (*display_documentation) (GbSourceView *view,
const gchar *search_text);
+ void (*drop_uris) (GbSourceViewClass *view,
+ const gchar **uri_list);
};
void gb_source_view_begin_search (GbSourceView *view,
diff --git a/src/gnome-builder.mk b/src/gnome-builder.mk
index b1df7df..8dd5f32 100644
--- a/src/gnome-builder.mk
+++ b/src/gnome-builder.mk
@@ -203,6 +203,8 @@ libgnome_builder_la_SOURCES = \
src/util/gb-string.h \
src/util/gb-widget.c \
src/util/gb-widget.h \
+ src/util/gb-dnd.c \
+ src/util/gb-dnd.h \
src/vim/gb-source-vim.c \
src/vim/gb-source-vim.h \
src/workbench/gb-workbench-types.h \
diff --git a/src/util/gb-dnd.c b/src/util/gb-dnd.c
new file mode 100644
index 0000000..0e0820b
--- /dev/null
+++ b/src/util/gb-dnd.c
@@ -0,0 +1,41 @@
+/* gb-dnd.c
+ *
+ * Copyright (C) 2014 Christian Hergert <christian hergert me>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "gb-dnd.h"
+
+/**
+ * gb_dnd_get_uri_list:
+ * @selection_data: the #GtkSelectionData from drag_data_received
+ *
+ * Create a list of valid uri's from a uri-list drop.
+ *
+ * Returns: (transfer full): a string array which will hold the uris or
+ * %NULL if there were no valid uris. g_strfreev should be used when
+ * the string array is no longer used
+ */
+gchar **
+gb_dnd_get_uri_list (GtkSelectionData *selection_data)
+{
+ const gchar *data;
+
+ g_return_val_if_fail (selection_data, NULL);
+ g_return_val_if_fail (gtk_selection_data_get_length (selection_data) > 0, NULL);
+
+ data = (const gchar*) gtk_selection_data_get_data (selection_data);
+ return g_uri_list_extract_uris (data);
+}
diff --git a/src/util/gb-dnd.h b/src/util/gb-dnd.h
new file mode 100644
index 0000000..3e440fd
--- /dev/null
+++ b/src/util/gb-dnd.h
@@ -0,0 +1,30 @@
+/* gb-dnd.h
+ *
+ * Copyright (C) 2014 Christian Hergert <christian hergert me>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GB_DND_H
+#define GB_DND_H
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+gchar **gb_dnd_get_uri_list (GtkSelectionData *selection_data);
+
+G_END_DECLS
+
+#endif /* GB_RGBA_H */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]