summaryrefslogtreecommitdiff
path: root/gtk/gtkfilechooserbutton.c
diff options
context:
space:
mode:
Diffstat (limited to 'gtk/gtkfilechooserbutton.c')
-rw-r--r--gtk/gtkfilechooserbutton.c292
1 files changed, 114 insertions, 178 deletions
diff --git a/gtk/gtkfilechooserbutton.c b/gtk/gtkfilechooserbutton.c
index f73f52add8..ce15326723 100644
--- a/gtk/gtkfilechooserbutton.c
+++ b/gtk/gtkfilechooserbutton.c
@@ -37,7 +37,7 @@
#include "gtkcellrendererpixbuf.h"
#include "gtkcombobox.h"
#include "gtkcssiconthemevalueprivate.h"
-#include "gtkdragdest.h"
+#include "gtkdroptarget.h"
#include "gtkicontheme.h"
#include "gtkimage.h"
#include "gtklabel.h"
@@ -268,11 +268,6 @@ static void gtk_file_chooser_button_finalize (GObject *ob
/* GtkWidget Functions */
static void gtk_file_chooser_button_destroy (GtkWidget *widget);
-static gboolean gtk_file_chooser_button_drag_drop (GtkDropTarget *dest,
- GdkDrop *drop,
- int x,
- int y,
- GtkWidget *widget);
static void gtk_file_chooser_button_show (GtkWidget *widget);
static void gtk_file_chooser_button_hide (GtkWidget *widget);
static void gtk_file_chooser_button_root (GtkWidget *widget);
@@ -350,6 +345,115 @@ G_DEFINE_TYPE_WITH_CODE (GtkFileChooserButton, gtk_file_chooser_button, GTK_TYPE
G_IMPLEMENT_INTERFACE (GTK_TYPE_FILE_CHOOSER,
gtk_file_chooser_button_file_chooser_iface_init))
+struct DndSelectFolderData
+{
+ GtkFileSystem *file_system;
+ GtkFileChooserButton *button;
+ GtkFileChooserAction action;
+ GFile *file;
+ gchar **uris;
+ guint i;
+ gboolean selected;
+};
+
+static void
+dnd_select_folder_get_info_cb (GCancellable *cancellable,
+ GFileInfo *info,
+ const GError *error,
+ gpointer user_data)
+{
+ struct DndSelectFolderData *data = user_data;
+ GtkFileChooserButton *button = data->button;
+ GtkFileChooserButtonPrivate *priv = gtk_file_chooser_button_get_instance_private (button);
+ gboolean cancelled = g_cancellable_is_cancelled (cancellable);
+
+ if (cancellable != priv->dnd_select_folder_cancellable)
+ {
+ g_object_unref (data->button);
+ g_object_unref (data->file);
+ g_strfreev (data->uris);
+ g_free (data);
+
+ g_object_unref (cancellable);
+ return;
+ }
+
+ priv->dnd_select_folder_cancellable = NULL;
+
+ if (!cancelled && !error && info != NULL)
+ {
+ gboolean is_folder;
+
+ is_folder = _gtk_file_info_consider_as_directory (info);
+
+ data->selected =
+ (((data->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER && is_folder) ||
+ (data->action == GTK_FILE_CHOOSER_ACTION_OPEN && !is_folder)) &&
+ gtk_file_chooser_select_file (GTK_FILE_CHOOSER (data->button), data->file, NULL));
+ }
+ else
+ data->selected = FALSE;
+
+ if (data->selected || data->uris[++data->i] == NULL)
+ {
+ g_signal_emit (data->button, file_chooser_button_signals[FILE_SET], 0);
+
+ g_object_unref (data->button);
+ g_object_unref (data->file);
+ g_strfreev (data->uris);
+ g_free (data);
+
+ g_object_unref (cancellable);
+ return;
+ }
+
+ if (data->file)
+ g_object_unref (data->file);
+
+ data->file = g_file_new_for_uri (data->uris[data->i]);
+
+ priv->dnd_select_folder_cancellable =
+ _gtk_file_system_get_info (data->file_system, data->file,
+ "standard::type",
+ dnd_select_folder_get_info_cb, user_data);
+
+ g_object_unref (cancellable);
+}
+
+static gboolean
+gtk_file_chooser_button_drop (GtkDropTarget *target,
+ const GValue *value,
+ double x,
+ double y,
+ GtkFileChooserButton *button)
+{
+ GtkFileChooserButtonPrivate *priv = gtk_file_chooser_button_get_instance_private (button);
+ struct DndSelectFolderData *info;
+ GFile *file;
+
+ file = g_value_get_object (value);
+
+ info = g_new0 (struct DndSelectFolderData, 1);
+ info->button = g_object_ref (button);
+ info->i = 0;
+ info->uris = g_new0 (char *, 2);
+ info->selected = FALSE;
+ info->file_system = priv->fs;
+ g_object_get (priv->chooser, "action", &info->action, NULL);
+
+ info->file = g_object_ref (file);
+
+ if (priv->dnd_select_folder_cancellable)
+ g_cancellable_cancel (priv->dnd_select_folder_cancellable);
+
+ priv->dnd_select_folder_cancellable =
+ _gtk_file_system_get_info (priv->fs, info->file,
+ "standard::type",
+ dnd_select_folder_get_info_cb, info);
+
+ return TRUE;
+}
+
static void
gtk_file_chooser_button_class_init (GtkFileChooserButtonClass * class)
{
@@ -441,8 +545,7 @@ gtk_file_chooser_button_init (GtkFileChooserButton *button)
GtkFileChooserButtonPrivate *priv = gtk_file_chooser_button_get_instance_private (button);
GtkWidget *box;
GtkWidget *icon;
- GdkContentFormatsBuilder *builder;
- GtkDropTarget *dest;
+ GtkDropTarget *target;
priv->button = gtk_button_new ();
g_signal_connect (priv->button, "clicked", G_CALLBACK (button_clicked_cb), button);
@@ -494,13 +597,9 @@ gtk_file_chooser_button_init (GtkFileChooserButton *button)
NULL, NULL);
/* DnD */
- builder = gdk_content_formats_builder_new ();
- gdk_content_formats_builder_add_gtype (builder, G_TYPE_STRING);
- gdk_content_formats_builder_add_gtype (builder, GDK_TYPE_FILE_LIST);
- dest = gtk_drop_target_new (gdk_content_formats_builder_free_to_formats (builder),
- GDK_ACTION_COPY);
- g_signal_connect (dest, "drag-drop", G_CALLBACK (gtk_file_chooser_button_drag_drop), button);
- gtk_widget_add_controller (GTK_WIDGET (button), GTK_EVENT_CONTROLLER (dest));
+ target = gtk_drop_target_new (G_TYPE_FILE, GDK_ACTION_COPY);
+ g_signal_connect (target, "drop", G_CALLBACK (gtk_file_chooser_button_drop), button);
+ gtk_widget_add_controller (GTK_WIDGET (button), GTK_EVENT_CONTROLLER (target));
}
@@ -1045,169 +1144,6 @@ gtk_file_chooser_button_destroy (GtkWidget *widget)
GTK_WIDGET_CLASS (gtk_file_chooser_button_parent_class)->destroy (widget);
}
-struct DndSelectFolderData
-{
- GtkFileSystem *file_system;
- GtkFileChooserButton *button;
- GtkFileChooserAction action;
- GFile *file;
- gchar **uris;
- guint i;
- gboolean selected;
-};
-
-static void
-dnd_select_folder_get_info_cb (GCancellable *cancellable,
- GFileInfo *info,
- const GError *error,
- gpointer user_data)
-{
- struct DndSelectFolderData *data = user_data;
- GtkFileChooserButton *button = data->button;
- GtkFileChooserButtonPrivate *priv = gtk_file_chooser_button_get_instance_private (button);
- gboolean cancelled = g_cancellable_is_cancelled (cancellable);
-
- if (cancellable != priv->dnd_select_folder_cancellable)
- {
- g_object_unref (data->button);
- g_object_unref (data->file);
- g_strfreev (data->uris);
- g_free (data);
-
- g_object_unref (cancellable);
- return;
- }
-
- priv->dnd_select_folder_cancellable = NULL;
-
- if (!cancelled && !error && info != NULL)
- {
- gboolean is_folder;
-
- is_folder = _gtk_file_info_consider_as_directory (info);
-
- data->selected =
- (((data->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER && is_folder) ||
- (data->action == GTK_FILE_CHOOSER_ACTION_OPEN && !is_folder)) &&
- gtk_file_chooser_select_file (GTK_FILE_CHOOSER (data->button), data->file, NULL));
- }
- else
- data->selected = FALSE;
-
- if (data->selected || data->uris[++data->i] == NULL)
- {
- g_signal_emit (data->button, file_chooser_button_signals[FILE_SET], 0);
-
- g_object_unref (data->button);
- g_object_unref (data->file);
- g_strfreev (data->uris);
- g_free (data);
-
- g_object_unref (cancellable);
- return;
- }
-
- if (data->file)
- g_object_unref (data->file);
-
- data->file = g_file_new_for_uri (data->uris[data->i]);
-
- priv->dnd_select_folder_cancellable =
- _gtk_file_system_get_info (data->file_system, data->file,
- "standard::type",
- dnd_select_folder_get_info_cb, user_data);
-
- g_object_unref (cancellable);
-}
-
-static void
-dnd_select_file (GtkFileChooserButton *button,
- GFile *file)
-{
- GtkFileChooserButtonPrivate *priv = gtk_file_chooser_button_get_instance_private (button);
- struct DndSelectFolderData *info;
-
- info = g_new0 (struct DndSelectFolderData, 1);
- info->button = g_object_ref (button);
- info->i = 0;
- info->uris = g_new0 (char *, 2);
- info->selected = FALSE;
- info->file_system = priv->fs;
- g_object_get (priv->chooser, "action", &info->action, NULL);
-
- info->file = g_object_ref (file);
-
- if (priv->dnd_select_folder_cancellable)
- g_cancellable_cancel (priv->dnd_select_folder_cancellable);
-
- priv->dnd_select_folder_cancellable =
- _gtk_file_system_get_info (priv->fs, info->file,
- "standard::type",
- dnd_select_folder_get_info_cb, info);
-}
-
-static void
-got_file (GObject *source,
- GAsyncResult *result,
- gpointer data)
-{
- GtkFileChooserButton *button = GTK_FILE_CHOOSER_BUTTON (data);
- GdkDrop *drop = GDK_DROP (source);
- const GValue *value;
-
- value = gdk_drop_read_value_finish (drop, result, NULL);
- if (value)
- {
- GFile *file;
-
- file = g_value_get_object (value);
- dnd_select_file (button, file);
- }
-}
-
-static void
-got_text (GObject *source,
- GAsyncResult *result,
- gpointer data)
-{
- GtkFileChooserButton *button = GTK_FILE_CHOOSER_BUTTON (data);
- GdkDrop *drop = GDK_DROP (source);
- char *str;
-
- str = gdk_drop_read_text_finish (drop, result, NULL);
- if (str)
- {
- GFile *file;
-
- file = g_file_new_for_uri (str);
- dnd_select_file (button, file);
- g_object_unref (file);
- }
-
-}
-
-static gboolean
-gtk_file_chooser_button_drag_drop (GtkDropTarget *dest,
- GdkDrop *drop,
- int x,
- int y,
- GtkWidget *button)
-{
- if (gdk_drop_has_value (drop, G_TYPE_FILE))
- {
- gdk_drop_read_value_async (drop, G_TYPE_FILE, G_PRIORITY_DEFAULT, NULL, got_file, button);
- return TRUE;
- }
- else
- {
- gdk_drop_read_text_async (drop, NULL, got_text, button);
- return TRUE;
- }
-
- return FALSE;
-
-}
-
static void
gtk_file_chooser_button_show (GtkWidget *widget)
{