commit a8ce17de0f28f80d5ea2bf0f4acd7f8bf707f072
Author: phantomjinx <p.g.richard...@phantomjinx.co.uk>
Date:   Sun Sep 11 00:44:09 2011 +0100

    Implement drag n drop cover support for clarity
    
    * In the same way as the coverart display, using fetchcover, a jpg can be
      dragged from the browser and replace the main cover in the index.
    
    * The dnd sends a track update signal and the tracks are all updated
      accordingly.

 plugins/clarity/Makefile.am           |    1 +
 plugins/clarity/clarity_dnd_support.c |  246 +++++++++++++++++++++++++++++++++
 plugins/clarity/clarity_dnd_support.h |   77 ++++++++++
 plugins/clarity/clarity_widget.c      |   25 +++-
 4 files changed, 341 insertions(+), 8 deletions(-)
---
diff --git a/plugins/clarity/Makefile.am b/plugins/clarity/Makefile.am
index c623eda..441b33d 100644
--- a/plugins/clarity/Makefile.am
+++ b/plugins/clarity/Makefile.am
@@ -37,6 +37,7 @@ libclarity_la_SOURCES = plugin.c plugin.h \
                                                          clarity_utils.c 
clarity_utils.h \
                                                          clarity_preferences.c 
clarity_preferences.h \
                                                          
clarity_context_menu.c clarity_context_menu.h \
+                                                         clarity_dnd_support.c 
clarity_dnd_support.h \
                                                          fetchcover.c 
fetchcover.h
 libclarity_la_CFLAGS = $(CLUTTER_GTK_CFLAGS)
 libclarity_la_LDFLAGS = $(GTKPOD_PLUGIN_LDFLAGS)
diff --git a/plugins/clarity/clarity_dnd_support.c 
b/plugins/clarity/clarity_dnd_support.c
new file mode 100644
index 0000000..d2cf79b
--- /dev/null
+++ b/plugins/clarity/clarity_dnd_support.c
@@ -0,0 +1,246 @@
+/*
+ |  Copyright (C) 2002-2011 Jorg Schuler <jcsjcs at users sourceforge net>
+ |                                             Paul Richardson <phantom_sf at 
users.sourceforge.net>
+ |  Part of the gtkpod project.
+ |
+ |  URL: http://www.gtkpod.org/
+ |  URL: http://gtkpod.sourceforge.net/
+ |
+ |  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 2 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, write to the Free Software
+ |  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ |
+ |  iTunes and iPod are trademarks of Apple
+ |
+ |  This product is not supported/written/published by Apple!
+ |
+ */
+
+#ifndef CLARITY_DND_SUPPORT_C_
+#define CLARITY_DND_SUPPORT_C_
+
+#include "libgtkpod/gtkpod_app_iface.h"
+#include "clarity_dnd_support.h"
+#include "fetchcover.h"
+#include "clarity_canvas.h"
+#include "clarity_utils.h"
+
+/**
+ * dnd_clarity_drag_drop:
+ *
+ * Used by the drag and drop of a jpg. When a drop is
+ * made, this determines whether the drop is valid
+ * then requests the data from the source widget.
+ *
+ */
+gboolean dnd_clarity_drag_drop(GtkWidget *widget, GdkDragContext 
*drag_context, gint x, gint y, guint time, gpointer user_data) {
+    GdkAtom target;
+    target = gtk_drag_dest_find_target(widget, drag_context, NULL);
+
+    if (target != GDK_NONE) {
+        gtk_drag_get_data(widget, drag_context, target, time);
+        return TRUE;
+    }
+
+    return FALSE;
+}
+
+/**
+ * dnd_clarity_drag_motion:
+ *
+ * Used by the drag and drop of a jpg. While the jpg is being
+ * dragged, this reports to the source widget whether it is an
+ * acceptable location to allow a drop.
+ *
+ */
+gboolean dnd_clarity_drag_motion(GtkWidget *widget, GdkDragContext *dc, gint 
x, gint y, guint time, gpointer user_data) {
+    GdkAtom target;
+    iTunesDB *itdb;
+    ExtraiTunesDBData *eitdb;
+
+    itdb = gp_get_selected_itdb();
+    /* no drop is possible if no playlist/repository is selected */
+    if (itdb == NULL) {
+        gdk_drag_status(dc, 0, time);
+        return FALSE;
+    }
+
+    eitdb = itdb->userdata;
+    g_return_val_if_fail (eitdb, FALSE);
+    /* no drop is possible if no repository is loaded */
+    if (!eitdb->itdb_imported) {
+        gdk_drag_status(dc, 0, time);
+        return FALSE;
+    }
+
+    target = gtk_drag_dest_find_target(widget, dc, NULL);
+    /* no drop possible if no valid target can be found */
+    if (target == GDK_NONE) {
+        gdk_drag_status(dc, 0, time);
+        return FALSE;
+    }
+
+    gdk_drag_status(dc, gdk_drag_context_get_suggested_action(dc), time);
+
+    return TRUE;
+}
+
+/**
+ * dnd_clarity_drag_data_received:
+ *
+ * Used by the drag and drop of a jpg. When the drop is performed, this
+ * acts on the receipt of the data from the source widget and applies
+ * the jpg to the track.
+ *
+ */
+void dnd_clarity_drag_data_received(GtkWidget *widget, GdkDragContext *dc, 
gint x, gint y, GtkSelectionData *data, guint info, guint time, gpointer 
user_data) {
+    g_return_if_fail(CLARITY_IS_CANVAS(widget));
+    g_return_if_fail (dc);
+    g_return_if_fail (data);
+    g_return_if_fail (gtk_selection_data_get_data(data));
+    g_return_if_fail (gtk_selection_data_get_length(data) > 0);
+
+    /* mozilla bug 402394 */
+
+#if DEBUG
+    printf ("data length = %d\n", gtk_selection_data_get_length(data->length));
+    printf ("data->data = %s\n", gtk_selection_data_get_data(data));
+#endif
+
+    AlbumItem *item;
+    GList *tracks;
+    gchar *url = NULL;
+    Fetch_Cover *fcover;
+    gchar *filename = NULL;
+    gboolean image_status = FALSE;
+    gchar *image_error = NULL;
+    /* For use with DND_IMAGE_JPEG */
+    GdkPixbuf *pixbuf;
+    GError *error = NULL;
+
+    ClarityCanvas *ccanvas = CLARITY_CANVAS(widget);
+
+    /* Find the display cover item in the cover display */
+    item = clarity_canvas_get_current_album_item(ccanvas);
+    if (!item) {
+        /* looks like there are no covers yet something got dragged into it */
+        gtk_drag_finish(dc, FALSE, FALSE, time);
+        return;
+    }
+
+    tracks = item->tracks;
+
+    switch (info) {
+    case DND_IMAGE_JPEG:
+#if DEBUG
+        printf ("Using DND_IMAGE_JPEG\n");
+#endif
+        pixbuf = gtk_selection_data_get_pixbuf(data);
+        if (pixbuf != NULL) {
+            /* initialise the url string with a safe value as not used if 
already have image */
+            url = "local image";
+            /* Initialise a fetchcover object */
+            fcover = fetchcover_new(url, tracks);
+            clarity_canvas_block_change(ccanvas, TRUE);
+
+            /* find the filename with which to save the pixbuf to */
+            if (fetchcover_select_filename(fcover)) {
+                filename = g_build_filename(fcover->dir, fcover->filename, 
NULL);
+                if (!gdk_pixbuf_save(pixbuf, filename, "jpeg", &error, NULL)) {
+                    /* Save failed for some reason */
+                    if (error->message)
+                        fcover->err_msg = g_strdup(error->message);
+                    else
+                        fcover->err_msg = "Saving image to file failed. No 
internal error message was returned.";
+
+                    g_error_free(error);
+                }
+                else {
+                    /* Image successfully saved */
+                    image_status = TRUE;
+                }
+            }
+            /* record any errors and free the fetchcover */
+            if (fcover->err_msg != NULL)
+                image_error = g_strdup(fcover->err_msg);
+
+            free_fetchcover(fcover);
+            g_object_unref(pixbuf);
+            clarity_canvas_block_change(ccanvas, FALSE);
+        }
+        else {
+            /* despite the data being of type image/jpeg, the pixbuf is NULL */
+            image_error = "jpeg data flavour was used but the data did not 
contain a GdkPixbuf object";
+        }
+        break;
+    case DND_TEXT_PLAIN:
+#if DEBUG
+        printf ("Defaulting to using DND_TEXT_PLAIN\n");
+#endif
+
+#ifdef HAVE_CURL
+        /* initialise the url string with the data from the dnd */
+        url = g_strdup ((gchar *) gtk_selection_data_get_data(data));
+        /* Initialise a fetchcover object */
+        fcover = fetchcover_new (url, tracks);
+        clarity_canvas_block_change(ccanvas, TRUE);
+
+        if (fetchcover_net_retrieve_image (fcover))
+        {
+#if DEBUG
+            printf ("Successfully retrieved\n");
+            printf ("Url of fetch cover: %s\n", fcover->url->str);
+            printf ("filename of fetch cover: %s\n", fcover->filename);
+#endif
+
+            filename = g_build_filename(fcover->dir, fcover->filename, NULL);
+            image_status = TRUE;
+        }
+
+        /* record any errors and free the fetchcover */
+        if (fcover->err_msg != NULL)
+        image_error = g_strdup(fcover->err_msg);
+
+        free_fetchcover (fcover);
+        clarity_canvas_block_change(ccanvas, FALSE);
+#else
+        image_error = g_strdup(_("Item had to be downloaded but gtkpod was not 
compiled with curl."));
+        image_status = FALSE;
+#endif
+    }
+
+    if (!image_status || filename == NULL) {
+        gtkpod_warning(_("Error occurred dropping an image onto the clarity 
display: %s\n"), image_error);
+
+        if (image_error)
+            g_free(image_error);
+        if (filename)
+            g_free(filename);
+
+        gtk_drag_finish(dc, FALSE, FALSE, time);
+        return;
+    }
+
+    clarity_util_update_coverart(tracks, filename);
+
+    if (image_error)
+        g_free(image_error);
+
+    g_free(filename);
+
+    gtkpod_statusbar_message(_("Successfully set new cover art for selected 
tracks"));
+    gtk_drag_finish(dc, FALSE, FALSE, time);
+    return;
+}
+
+#endif /* CLARITY_DND_SUPPORT_C_ */
diff --git a/plugins/clarity/clarity_dnd_support.h 
b/plugins/clarity/clarity_dnd_support.h
new file mode 100644
index 0000000..42572b7
--- /dev/null
+++ b/plugins/clarity/clarity_dnd_support.h
@@ -0,0 +1,77 @@
+/*
+ |  Copyright (C) 2002-2011 Jorg Schuler <jcsjcs at users sourceforge net>
+ |                                             Paul Richardson <phantom_sf at 
users.sourceforge.net>
+ |  Part of the gtkpod project.
+ |
+ |  URL: http://www.gtkpod.org/
+ |  URL: http://gtkpod.sourceforge.net/
+ |
+ |  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 2 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, write to the Free Software
+ |  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ |
+ |  iTunes and iPod are trademarks of Apple
+ |
+ |  This product is not supported/written/published by Apple!
+ |
+ */
+
+#ifndef CLARITY_DND_SUPPORT_H_
+#define CLARITY_DND_SUPPORT_H_
+
+#include <gtk/gtk.h>
+#include <libgtkpod/gp_itdb.h>
+#include <libgtkpod/gp_private.h>
+#include "plugin.h"
+
+static GtkTargetEntry clarity_drop_types[] =
+    {
+        /* Konqueror supported flavours */
+        { "image/jpeg", 0, DND_IMAGE_JPEG },
+
+        /* Fallback flavours */
+        { "text/plain", 0, DND_TEXT_PLAIN },
+        { "STRING", 0, DND_TEXT_PLAIN }
+    };
+
+/**
+ * dnd_clarity_drag_drop:
+ *
+ * Used by the drag and drop of a jpg. When a drop is
+ * made, this determines whether the drop is valid
+ * then requests the data from the source widget.
+ *
+ */
+gboolean dnd_clarity_drag_drop(GtkWidget *widget, GdkDragContext 
*drag_context, gint x, gint y, guint time, gpointer user_data);
+
+/**
+ * dnd_clarity_drag_motion:
+ *
+ * Used by the drag and drop of a jpg. While the jpg is being
+ * dragged, this reports to the source widget whether it is an
+ * acceptable location to allow a drop.
+ *
+ */
+gboolean dnd_clarity_drag_motion(GtkWidget *widget, GdkDragContext *dc, gint 
x, gint y, guint time, gpointer user_data);
+
+/**
+ * dnd_clarity_drag_data_received:
+ *
+ * Used by the drag and drop of a jpg. When the drop is performed, this
+ * acts on the receipt of the data from the source widget and applies
+ * the jpg to the track.
+ *
+ */
+void dnd_clarity_drag_data_received(GtkWidget *widget, GdkDragContext *dc, 
gint x, gint y, GtkSelectionData *data, guint info, guint time, gpointer 
user_data);
+
+#endif /* CLARITY_DND_SUPPORT_H_ */
diff --git a/plugins/clarity/clarity_widget.c b/plugins/clarity/clarity_widget.c
index c044d40..df3fa29 100644
--- a/plugins/clarity/clarity_widget.c
+++ b/plugins/clarity/clarity_widget.c
@@ -31,6 +31,7 @@
 #include "clarity_canvas.h"
 #include "clarity_widget.h"
 #include "album_model.h"
+#include "clarity_dnd_support.h"
 
 G_DEFINE_TYPE( ClarityWidget, clarity_widget, GTK_TYPE_BOX);
 
@@ -62,14 +63,6 @@ enum {
     PROP_0
 };
 
-/*
- * TODO
- *
- * popup menu
- * drag n drop
- * set cover from file
- */
-
 static void clarity_widget_dispose(GObject *gobject) {
     ClarityWidget *cw = CLARITY_WIDGET(gobject);
     cw->current_playlist = NULL;
@@ -289,6 +282,22 @@ static void clarity_widget_init (ClarityWidget *self) {
     g_signal_connect (G_OBJECT(priv->rightbutton), "clicked",
                 G_CALLBACK(_on_clarity_button_clicked), priv);
 
+    /* Dnd destinaton for foreign image files */
+    gtk_drag_dest_set(priv->draw_area, 0, clarity_drop_types, 
TGNR(clarity_drop_types), GDK_ACTION_COPY
+            | GDK_ACTION_MOVE);
+
+    g_signal_connect ((gpointer) priv->draw_area, "drag-drop",
+            G_CALLBACK (dnd_clarity_drag_drop),
+            NULL);
+
+    g_signal_connect ((gpointer) priv->draw_area, "drag-data-received",
+            G_CALLBACK (dnd_clarity_drag_data_received),
+            NULL);
+
+    g_signal_connect ((gpointer) priv->draw_area, "drag-motion",
+            G_CALLBACK (dnd_clarity_drag_motion),
+            NULL);
+
     _init_slider_range(priv);
 
     priv->controlbox = gtk_hbox_new(FALSE, 2);

------------------------------------------------------------------------------
Malware Security Report: Protecting Your Business, Customers, and the 
Bottom Line. Protect your business and customers by understanding the 
threat from malware and how it can impact your online business. 
http://www.accelacomm.com/jaw/sfnl/114/51427462/
_______________________________________________
gtkpod-cvs2 mailing list
gtkpod-cvs2@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/gtkpod-cvs2

Reply via email to