Updating branch refs/heads/master
to fbcfa257342a8ac84b624abc3289daf968621b2a (commit)
from d72dfdd29ff81875b7a78e2f27517353367c5fc3 (commit)
commit fbcfa257342a8ac84b624abc3289daf968621b2a
Author: Eric Koegel <[email protected]>
Date: Fri Jan 6 21:48:08 2012 +0300
Drag and drop for images.
Adds support to open image files into ristretto as well as all the
images in that same directory depending on what files were dropped.
Optionally, the user can just drop a single folder and ristretto
will load all the images in there. For bug 3688.
Signed-off-by: Stephan Arts <[email protected]>
src/image_viewer.c | 46 ++++++++++++++-
src/main_window.c | 157 ++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 200 insertions(+), 3 deletions(-)
diff --git a/src/image_viewer.c b/src/image_viewer.c
index 557e1e3..5aa7d64 100644
--- a/src/image_viewer.c
+++ b/src/image_viewer.c
@@ -188,6 +188,9 @@ static void
cb_rstto_image_loader_closed (GdkPixbufLoader *loader,
RsttoImageViewerTransaction *transaction);
static gboolean
cb_rstto_image_viewer_update_pixbuf (RsttoImageViewer *viewer);
+static void
+cb_rstto_image_viewer_dnd (GtkWidget *widget, GdkDragContext *context, gint x,
gint y, GtkSelectionData *data,
+ guint info, guint time_, RsttoImageViewer *viewer);
static gboolean
rstto_scroll_event (
@@ -307,6 +310,11 @@ rstto_image_viewer_init ( GObject *object )
"notify::revert-zoom-direction",
G_CALLBACK (cb_rstto_zoom_direction_changed),
viewer);
+ g_signal_connect (
+ G_OBJECT(viewer),
+ "drag-data-received",
+ G_CALLBACK (cb_rstto_image_viewer_dnd),
+ viewer);
gtk_widget_set_events (GTK_WIDGET(viewer),
GDK_BUTTON_PRESS_MASK |
@@ -315,10 +323,11 @@ rstto_image_viewer_init ( GObject *object )
GDK_ENTER_NOTIFY_MASK |
GDK_POINTER_MOTION_MASK);
- /*
- gtk_drag_dest_set(GTK_WIDGET(viewer), 0, drop_targets,
G_N_ELEMENTS(drop_targets),
+
+ gtk_drag_dest_set(GTK_WIDGET(viewer), GTK_DEST_DEFAULT_ALL, NULL, 0,
GDK_ACTION_COPY | GDK_ACTION_LINK | GDK_ACTION_MOVE |
GDK_ACTION_PRIVATE);
- */
+ gtk_drag_dest_add_uri_targets (GTK_WIDGET(viewer));
+
}
/**
@@ -378,6 +387,14 @@ rstto_image_viewer_class_init(RsttoImageViewerClass
*viewer_class)
NULL, NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
+ g_signal_new ("files-dnd",
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_FIRST,
+ 0,
+ NULL, NULL,
+ g_cclosure_marshal_VOID__POINTER,
+ G_TYPE_NONE, 1,
+ G_TYPE_POINTER);
}
/**
@@ -2488,3 +2505,26 @@ rstto_popup_menu (
}
return FALSE;
}
+
+static void
+cb_rstto_image_viewer_dnd (GtkWidget *widget, GdkDragContext *context, gint x,
gint y, GtkSelectionData *data,
+ guint info, guint time_, RsttoImageViewer *viewer)
+{
+ g_return_if_fail ( RSTTO_IS_IMAGE_VIEWER(viewer) );
+
+ if ((data->length >= 0) && (data->format == 8))
+ {
+ gchar **uris;
+
+ uris = g_uri_list_extract_uris ((const gchar*)data->data);
+
+ g_signal_emit_by_name (viewer, "files-dnd", uris);
+
+ gtk_drag_finish (context, TRUE, FALSE, time_);
+ g_strfreev (uris);
+ }
+ else
+ {
+ gtk_drag_finish (context, FALSE, FALSE, time_);
+ }
+}
diff --git a/src/main_window.c b/src/main_window.c
index cb13fd4..dab29f2 100644
--- a/src/main_window.c
+++ b/src/main_window.c
@@ -117,6 +117,8 @@ struct _RsttoMainWindowPriv
gboolean playing;
gint play_timeout_id;
+
+ GtkFileFilter *filter;
};
enum
@@ -192,6 +194,8 @@ static void
cb_rstto_main_window_save_copy (GtkWidget *widget, RsttoMainWindow *window);
static void
cb_rstto_main_window_delete (GtkWidget *widget, RsttoMainWindow *window);
+static void
+cb_rstto_main_window_dnd_files (GtkWidget *widget, gchar **uris,
RsttoMainWindow *window);
static void
cb_rstto_main_window_set_as_wallpaper (GtkWidget *widget, RsttoMainWindow
*window);
@@ -452,6 +456,11 @@ rstto_main_window_init (RsttoMainWindow *window)
window->priv->recent_manager = gtk_recent_manager_get_default();
window->priv->settings_manager = rstto_settings_new();
+ /* Setup the image filter list for drag and drop */
+ window->priv->filter = gtk_file_filter_new ();
+ g_object_ref_sink (window->priv->filter);
+ gtk_file_filter_add_pixbuf_formats (window->priv->filter);
+
/* D-Bus stuff */
window->priv->connection = dbus_g_bus_get(DBUS_BUS_SESSION, NULL);
@@ -768,6 +777,7 @@ rstto_main_window_init (RsttoMainWindow *window)
g_signal_connect(G_OBJECT(window->priv->thumbnailbar),
"button-press-event",
G_CALLBACK(cb_rstto_main_window_navigationtoolbar_button_press_event), window);
g_signal_connect(G_OBJECT(window->priv->image_viewer), "size-ready",
G_CALLBACK(cb_rstto_main_window_update_statusbar), window);
g_signal_connect(G_OBJECT(window->priv->image_viewer), "scale-changed",
G_CALLBACK(cb_rstto_main_window_update_statusbar), window);
+ g_signal_connect(G_OBJECT(window->priv->image_viewer), "files-dnd",
G_CALLBACK(cb_rstto_main_window_dnd_files), window);
if ( TRUE == rstto_settings_get_boolean_property
(window->priv->settings_manager, "merge-toolbars"))
{
@@ -869,6 +879,12 @@ rstto_main_window_dispose(GObject *object)
g_object_unref (window->priv->image_list);
window->priv->image_list = NULL;
}
+
+ if (window->priv->filter)
+ {
+ g_object_unref (window->priv->filter);
+ window->priv->filter= NULL;
+ }
g_free (window->priv);
window->priv = NULL;
}
@@ -3112,6 +3128,147 @@ cb_rstto_main_window_delete (
g_object_unref (file);
}
+static gboolean
+rstto_main_window_is_valid_image (RsttoMainWindow *window,
+ RsttoFile *file)
+{
+ GtkFileFilterInfo filter_info;
+
+ filter_info.contains = GTK_FILE_FILTER_MIME_TYPE | GTK_FILE_FILTER_URI;
+ filter_info.uri = rstto_file_get_uri (file);
+ filter_info.mime_type = rstto_file_get_content_type (file);
+
+ return gtk_file_filter_filter (window->priv->filter, &filter_info);
+}
+
+/**
+ * cb_rstto_main_window_dnd_files:
+ * @widget:
+ * @uris:
+ * @window:
+ *
+ */
+static void
+cb_rstto_main_window_dnd_files (GtkWidget *widget,
+ gchar **uris,
+ RsttoMainWindow *window)
+{
+ RsttoFile *file;
+ guint n;
+ gboolean first = TRUE;
+
+ g_return_if_fail ( RSTTO_IS_MAIN_WINDOW(window) );
+
+ /* User dropped an image, load all images in the directory
+ * and select the image.
+ */
+ if ( g_strv_length (uris) == 1)
+ {
+ file = rstto_file_new (g_file_new_for_uri (uris[n]));
+ if ( TRUE == rstto_main_window_is_valid_image (window, file))
+ {
+ GFile *p_file;
+ p_file = g_file_get_parent ( rstto_file_get_file (file) );
+ rstto_image_list_set_directory (
+ window->priv->image_list,
+ p_file,
+ NULL );
+ rstto_image_list_iter_find_file (
+ window->priv->iter,
+ file );
+ return;
+ }
+
+ /* Not a valid image, but it might be a valid directory */
+ g_object_unref (file);
+ }
+
+ for (n = 0; n < g_strv_length (uris); n++)
+ {
+ file = rstto_file_new (g_file_new_for_uri (uris[n]));
+
+ if ( TRUE == rstto_main_window_is_valid_image (window, file))
+ {
+ /* User dropped a selection of images, load only them.
+ * On the first valid image, we reset the thumbnailbar.
+ */
+ if ( TRUE == first )
+ {
+ first = FALSE;
+ rstto_image_list_set_directory (
+ window->priv->image_list,
+ NULL,
+ NULL);
+ }
+
+ rstto_image_list_add_file ( window->priv->image_list, file, NULL);
+ rstto_image_list_iter_find_file ( window->priv->iter,
+ file );
+ }
+ else if ( g_file_query_file_type ( rstto_file_get_file (file),
+ G_FILE_QUERY_INFO_NONE,
+ NULL) == G_FILE_TYPE_DIRECTORY)
+ {
+ GFileEnumerator *enumerator;
+
+ /* User dropped in a directory, get the files in it */
+ enumerator = g_file_enumerate_children (
+ rstto_file_get_file (file),
+ "standard::name,access::can-read",
+ G_FILE_QUERY_INFO_NONE,
+ NULL,
+ NULL);
+
+ if (enumerator)
+ {
+ GFileInfo *f_info;
+ RsttoFile *child;
+
+ /* Check all the files for a valid image */
+ for (f_info = g_file_enumerator_next_file (enumerator, NULL,
NULL);
+ f_info != NULL;
+ f_info = g_file_enumerator_next_file (enumerator, NULL,
NULL))
+ {
+ gchar *path = g_strdup_printf ("%s/%s",
+ rstto_file_get_path (file),
+ g_file_info_get_name
(f_info));
+
+ child = rstto_file_new (g_file_new_for_path (path));
+
+ g_object_unref (f_info);
+ g_free (path);
+
+ if ( TRUE == rstto_main_window_is_valid_image (
+ window,
+ child))
+ {
+ /* Found a valid image, use the directory
+ * and select the first image in the dir */
+ rstto_image_list_set_directory (
+ window->priv->image_list,
+ rstto_file_get_file (file),
+ NULL );
+ rstto_image_list_iter_find_file (
+ window->priv->iter,
+ child );
+
+ break;
+ }
+ /* Not a valid image file */
+ g_object_unref (child);
+ }
+ g_file_enumerator_close (enumerator, NULL, NULL);
+ g_object_unref (enumerator);
+ }
+ }
+ else
+ {
+ /* Not an image file or directory */
+ g_object_unref (file);
+ }
+ }
+}
+
/**********************/
/* PRINTING CALLBACKS */
/**********************/
_______________________________________________
Xfce4-commits mailing list
[email protected]
https://mail.xfce.org/mailman/listinfo/xfce4-commits