summaryrefslogtreecommitdiff
path: root/plugins
diff options
context:
space:
mode:
authorGravatar Alexey Yakovenko <wakeroid@gmail.com>2010-04-15 22:07:28 +0200
committerGravatar Alexey Yakovenko <wakeroid@gmail.com>2010-04-15 22:07:28 +0200
commitdb25ef2216cc7e5ba9d7ff7c30ac3b184ee11577 (patch)
tree0033f905b14f9cfc854433a9a9b9cdeef9670edc /plugins
parente575295f6e6e85b8a408347ab4536720ccb26ed2 (diff)
multiple drag-n-drop improvements
Diffstat (limited to 'plugins')
-rw-r--r--plugins/gtkui/ddblistview.c28
-rw-r--r--plugins/gtkui/ddblistview.h42
-rw-r--r--plugins/gtkui/ddbtabstrip.c131
-rw-r--r--plugins/gtkui/fileman.c4
4 files changed, 201 insertions, 4 deletions
diff --git a/plugins/gtkui/ddblistview.c b/plugins/gtkui/ddblistview.c
index 8ffebc74..40e5ea3c 100644
--- a/plugins/gtkui/ddblistview.c
+++ b/plugins/gtkui/ddblistview.c
@@ -789,11 +789,31 @@ ddb_listview_list_drag_motion (GtkWidget *widget,
{
DdbListview *pl = DDB_LISTVIEW (gtk_object_get_data (GTK_OBJECT (widget), "owner"));
ddb_listview_list_track_dragdrop (pl, y);
- if (pl->drag_source_playlist != deadbeef->plt_get_curr ()) {
+ int cnt = g_list_length (drag_context->targets);
+ int i;
+ for (i = 0; i < cnt; i++) {
+ GdkAtom a = GDK_POINTER_TO_ATOM (g_list_nth_data (drag_context->targets, i));
+ gchar *nm = gdk_atom_name (a);
+ if (!strcmp (nm, "text/uri-list")) {
+ g_free (nm);
+ break;
+ }
+ g_free (nm);
+ }
+ if (i != cnt) {
gdk_drag_status (drag_context, GDK_ACTION_COPY, time);
}
else {
- gdk_drag_status (drag_context, GDK_ACTION_MOVE, time);
+ GdkModifierType mask;
+
+ gdk_window_get_pointer (gtk_widget_get_window (widget),
+ NULL, NULL, &mask);
+ if (mask & GDK_CONTROL_MASK) {
+ gdk_drag_status (drag_context, GDK_ACTION_COPY, time);
+ }
+ else {
+ gdk_drag_status (drag_context, GDK_ACTION_MOVE, time);
+ }
}
return FALSE;
}
@@ -807,6 +827,8 @@ ddb_listview_list_drag_drop (GtkWidget *widget,
guint time,
gpointer user_data)
{
+ return TRUE;
+#if 0
if (drag_context->targets) {
GdkAtom target_type = GDK_POINTER_TO_ATOM (g_list_nth_data (drag_context->targets, TARGET_SAMEWIDGET));
if (!target_type) {
@@ -816,6 +838,7 @@ ddb_listview_list_drag_drop (GtkWidget *widget,
return TRUE;
}
return FALSE;
+#endif
}
@@ -1940,6 +1963,7 @@ ddb_listview_list_drag_end (GtkWidget *widget,
GdkDragContext *drag_context,
gpointer user_data)
{
+ printf ("ddb_listview_list_drag_end\n");
DdbListview *ps = DDB_LISTVIEW (gtk_object_get_data (GTK_OBJECT (widget), "owner"));
ddb_listview_refresh (ps, DDB_REFRESH_LIST|DDB_EXPOSE_LIST);
ps->scroll_direction = 0;
diff --git a/plugins/gtkui/ddblistview.h b/plugins/gtkui/ddblistview.h
index cdf7517f..e75ca059 100644
--- a/plugins/gtkui/ddblistview.h
+++ b/plugins/gtkui/ddblistview.h
@@ -205,6 +205,48 @@ enum {
void ddb_listview_refresh (DdbListview *listview, uint32_t flags);
+gboolean
+ddb_listview_list_drag_drop (GtkWidget *widget,
+ GdkDragContext *drag_context,
+ gint x,
+ gint y,
+ guint time,
+ gpointer user_data);
+
+void
+ddb_listview_list_drag_data_get (GtkWidget *widget,
+ GdkDragContext *drag_context,
+ GtkSelectionData *data,
+ guint info,
+ guint time,
+ gpointer user_data);
+
+void
+ddb_listview_list_drag_end (GtkWidget *widget,
+ GdkDragContext *drag_context,
+ gpointer user_data);
+
+void
+ddb_listview_list_drag_data_received (GtkWidget *widget,
+ GdkDragContext *drag_context,
+ gint x,
+ gint y,
+ GtkSelectionData *data,
+ guint target_type,
+ guint time,
+ gpointer user_data);
+
+void
+ddb_listview_list_drag_leave (GtkWidget *widget,
+ GdkDragContext *drag_context,
+ guint time,
+ gpointer user_data);
+
+void
+ddb_listview_list_drag_end (GtkWidget *widget,
+ GdkDragContext *drag_context,
+ gpointer user_data);
+
G_END_DECLS
#endif // __DDBLISTVIEW_H
diff --git a/plugins/gtkui/ddbtabstrip.c b/plugins/gtkui/ddbtabstrip.c
index 7e71c6f1..aeb5868b 100644
--- a/plugins/gtkui/ddbtabstrip.c
+++ b/plugins/gtkui/ddbtabstrip.c
@@ -18,11 +18,13 @@
*/
#include <gtk/gtk.h>
#include <string.h>
+#include <assert.h>
#include "ddbtabstrip.h"
#include "drawing.h"
#include "gtkui.h"
#include "interface.h"
#include "support.h"
+#include "ddblistview.h"
#define GLADE_HOOKUP_OBJECT(component,widget,name) \
g_object_set_data_full (G_OBJECT (component), name, \
@@ -92,9 +94,10 @@ ddb_tabstrip_realize (GtkWidget *widget) {
GtkTargetEntry entry = {
.target = "STRING",
.flags = GTK_TARGET_SAME_APP,
- 0
+ TARGET_SAMEWIDGET
};
gtk_drag_dest_set (widget, GTK_DEST_DEFAULT_MOTION | GTK_DEST_DEFAULT_DROP, &entry, 1, GDK_ACTION_COPY | GDK_ACTION_MOVE);
+ gtk_drag_dest_add_uri_targets (widget);
gtk_drag_dest_set_track_motion (widget, TRUE);
}
@@ -145,6 +148,34 @@ on_tabstrip_drag_motion_event (GtkWidget *widget,
gint y,
guint time);
+gboolean
+on_tabstrip_drag_drop (GtkWidget *widget,
+ GdkDragContext *drag_context,
+ gint x,
+ gint y,
+ guint time);
+
+void
+on_tabstrip_drag_data_received (GtkWidget *widget,
+ GdkDragContext *drag_context,
+ gint x,
+ gint y,
+ GtkSelectionData *data,
+ guint target_type,
+ guint time);
+
+void
+on_tabstrip_drag_leave (GtkWidget *widget,
+ GdkDragContext *drag_context,
+ guint time);
+
+void
+on_tabstrip_drag_end (GtkWidget *widget,
+ GdkDragContext *drag_context);
+
+static int
+get_tab_under_cursor (int x);
+
static void
ddb_tabstrip_destroy(GtkObject *object)
{
@@ -175,9 +206,75 @@ ddb_tabstrip_class_init(DdbTabStripClass *class)
widget_class->configure_event = on_tabstrip_configure_event;
widget_class->motion_notify_event = on_tabstrip_motion_notify_event;
widget_class->drag_motion = on_tabstrip_drag_motion_event;
+ widget_class->drag_drop = on_tabstrip_drag_drop;
+ widget_class->drag_end = on_tabstrip_drag_end;
+ widget_class->drag_data_received = on_tabstrip_drag_data_received;
+ widget_class->drag_leave = on_tabstrip_drag_leave;
+
object_class->destroy = ddb_tabstrip_destroy;
}
+gboolean
+on_tabstrip_drag_drop (GtkWidget *widget,
+ GdkDragContext *drag_context,
+ gint x,
+ gint y,
+ guint time)
+{
+ return TRUE;
+}
+
+void
+on_tabstrip_drag_data_received (GtkWidget *widget,
+ GdkDragContext *drag_context,
+ gint x,
+ gint y,
+ GtkSelectionData *data,
+ guint target_type,
+ guint time)
+{
+ DdbListview *ps = DDB_LISTVIEW (lookup_widget (mainwin, "playlist"));
+
+ gchar *ptr=(char*)data->data;
+ if (target_type == 0) { // uris
+ // this happens when dropped from file manager
+ char *mem = malloc (data->length+1);
+ memcpy (mem, ptr, data->length);
+ mem[data->length] = 0;
+ // we don't pass control structure, but there's only one drag-drop view currently
+ ps->binding->external_drag_n_drop (NULL, mem, data->length);
+ }
+ else if (target_type == 1) {
+ uint32_t *d= (uint32_t *)ptr;
+ int plt = *d;
+ d++;
+ int length = (data->length/4)-1;
+ if (plt == deadbeef->plt_get_curr ()) {
+ gtk_drag_finish (drag_context, TRUE, FALSE, time);
+ return;
+ }
+ ps->binding->drag_n_drop (NULL, plt, d, length);
+ }
+ gtk_drag_finish (drag_context, TRUE, FALSE, time);
+}
+
+void
+on_tabstrip_drag_leave (GtkWidget *widget,
+ GdkDragContext *drag_context,
+ guint time)
+{
+ DdbListview *pl = DDB_LISTVIEW (lookup_widget (mainwin, "playlist"));
+ ddb_listview_list_drag_leave (pl->list, drag_context, time, NULL);
+}
+
+void
+on_tabstrip_drag_end (GtkWidget *widget,
+ GdkDragContext *drag_context)
+{
+ DdbListview *pl = DDB_LISTVIEW (lookup_widget (mainwin, "playlist"));
+ ddb_listview_list_drag_end (pl->list, drag_context, NULL);
+}
+
GtkWidget * ddb_tabstrip_new() {
return g_object_new (DDB_TYPE_TABSTRIP, NULL);
}
@@ -715,10 +812,40 @@ on_tabstrip_drag_motion_event (GtkWidget *widget,
guint time)
{
int tab = get_tab_under_cursor (x);
- if (tab != -1) {
+ int prev = deadbeef->plt_get_curr ();
+ if (tab != -1 && tab != prev) {
deadbeef->plt_set_curr (tab);
deadbeef->conf_set_int ("playlist.current", tab);
}
+
+ GtkWidget *pl = lookup_widget (mainwin, "playlist");
+
+ int cnt = g_list_length (drag_context->targets);
+ int i;
+ for (i = 0; i < cnt; i++) {
+ GdkAtom a = GDK_POINTER_TO_ATOM (g_list_nth_data (drag_context->targets, i));
+ gchar *nm = gdk_atom_name (a);
+ if (!strcmp (nm, "text/uri-list")) {
+ g_free (nm);
+ break;
+ }
+ g_free (nm);
+ }
+ if (i != cnt) {
+ gdk_drag_status (drag_context, GDK_ACTION_COPY, time);
+ }
+ else {
+ GdkModifierType mask;
+
+ gdk_window_get_pointer (gtk_widget_get_window (widget),
+ NULL, NULL, &mask);
+ if (mask & GDK_CONTROL_MASK) {
+ gdk_drag_status (drag_context, GDK_ACTION_COPY, time);
+ }
+ else {
+ gdk_drag_status (drag_context, GDK_ACTION_MOVE, time);
+ }
+ }
return FALSE;
}
void
diff --git a/plugins/gtkui/fileman.c b/plugins/gtkui/fileman.c
index 8ef81238..0a5fb851 100644
--- a/plugins/gtkui/fileman.c
+++ b/plugins/gtkui/fileman.c
@@ -156,6 +156,10 @@ strcopy_special (char *dest, const char *src, int len) {
static gboolean
set_dnd_cursor_idle (gpointer data) {
DdbListview *listview = DDB_LISTVIEW (lookup_widget (mainwin, "playlist"));
+ if (!data) {
+ ddb_listview_set_cursor (listview, -1);
+ return FALSE;
+ }
int cursor = deadbeef->pl_get_idx_of (DB_PLAYITEM (data));
ddb_listview_set_cursor (listview, cursor);
return FALSE;