diff options
Diffstat (limited to 'gtk/gtkfilechooserbutton.c')
-rw-r--r-- | gtk/gtkfilechooserbutton.c | 144 |
1 files changed, 88 insertions, 56 deletions
diff --git a/gtk/gtkfilechooserbutton.c b/gtk/gtkfilechooserbutton.c index 64ea59563e..00bacca83f 100644 --- a/gtk/gtkfilechooserbutton.c +++ b/gtk/gtkfilechooserbutton.c @@ -37,7 +37,6 @@ #include "gtkcellrendererpixbuf.h" #include "gtkcombobox.h" #include "gtkcssiconthemevalueprivate.h" -#include "gtkdnd.h" #include "gtkdragdest.h" #include "gtkicontheme.h" #include "gtkimage.h" @@ -61,6 +60,7 @@ #include "gtksettings.h" #include "gtkstylecontextprivate.h" #include "gtkbitmaskprivate.h" +#include "gtkeventcontroller.h" /** * SECTION:gtkfilechooserbutton @@ -267,9 +267,11 @@ static void gtk_file_chooser_button_finalize (GObject *ob /* GtkWidget Functions */ static void gtk_file_chooser_button_destroy (GtkWidget *widget); -static void gtk_file_chooser_button_drag_data_received (GtkWidget *widget, - GdkDrop *drop, - GtkSelectionData *data); +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); @@ -366,7 +368,6 @@ gtk_file_chooser_button_class_init (GtkFileChooserButtonClass * class) gobject_class->finalize = gtk_file_chooser_button_finalize; widget_class->destroy = gtk_file_chooser_button_destroy; - widget_class->drag_data_received = gtk_file_chooser_button_drag_data_received; widget_class->show = gtk_file_chooser_button_show; widget_class->hide = gtk_file_chooser_button_hide; widget_class->map = gtk_file_chooser_button_map; @@ -443,7 +444,9 @@ gtk_file_chooser_button_init (GtkFileChooserButton *button) GtkFileChooserButtonPrivate *priv = gtk_file_chooser_button_get_instance_private (button); GtkWidget *box; GtkWidget *icon; + GdkContentFormatsBuilder *builder; GdkContentFormats *target_list; + GtkDropTarget *dest; priv->button = gtk_button_new (); g_signal_connect (priv->button, "clicked", G_CALLBACK (button_clicked_cb), button); @@ -495,13 +498,13 @@ gtk_file_chooser_button_init (GtkFileChooserButton *button) NULL, NULL); /* DnD */ - target_list = gdk_content_formats_new (NULL, 0); - target_list = gtk_content_formats_add_uri_targets (target_list); - target_list = gtk_content_formats_add_text_targets (target_list); - gtk_drag_dest_set (GTK_WIDGET (button), - (GTK_DEST_DEFAULT_ALL), - target_list, - GDK_ACTION_COPY); + 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); + target_list = gdk_content_formats_builder_free_to_formats (builder); + dest = gtk_drop_target_new (target_list, 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)); gdk_content_formats_unref (target_list); } @@ -1146,62 +1149,91 @@ dnd_select_folder_get_info_cb (GCancellable *cancellable, } static void -gtk_file_chooser_button_drag_data_received (GtkWidget *widget, - GdkDrop *drop, - GtkSelectionData *data) +dnd_select_file (GtkFileChooserButton *button, + GFile *file) { - GtkFileChooserButton *button = GTK_FILE_CHOOSER_BUTTON (widget); GtkFileChooserButtonPrivate *priv = gtk_file_chooser_button_get_instance_private (button); - GFile *file; - gchar *text; + struct DndSelectFolderData *info; - if (GTK_WIDGET_CLASS (gtk_file_chooser_button_parent_class)->drag_data_received != NULL) - GTK_WIDGET_CLASS (gtk_file_chooser_button_parent_class)->drag_data_received (widget, - drop, - data); + 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); - if (widget == NULL || gtk_selection_data_get_length (data) < 0) - return; + info->file = g_object_ref (file); - if (gtk_selection_data_targets_include_uri (data)) - { - gchar **uris; - struct DndSelectFolderData *info; + if (priv->dnd_select_folder_cancellable) + g_cancellable_cancel (priv->dnd_select_folder_cancellable); - uris = gtk_selection_data_get_uris (data); + priv->dnd_select_folder_cancellable = + _gtk_file_system_get_info (priv->fs, info->file, + "standard::type", + dnd_select_folder_get_info_cb, info); +} - if (uris != NULL) - { - info = g_new0 (struct DndSelectFolderData, 1); - info->button = g_object_ref (button); - info->i = 0; - info->uris = uris; - info->selected = FALSE; - info->file_system = priv->fs; - g_object_get (priv->chooser, "action", &info->action, NULL); - - info->file = g_file_new_for_uri (info->uris[info->i]); - - 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); } - else if (gtk_selection_data_targets_include_text (data)) +} + +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) { - text = (char*) gtk_selection_data_get_text (data); - file = g_file_new_for_uri (text); - gtk_file_chooser_select_file (GTK_FILE_CHOOSER (priv->chooser), file, NULL); + GFile *file; + + file = g_file_new_for_uri (str); + dnd_select_file (button, file); g_object_unref (file); - g_free (text); - g_signal_emit (button, file_chooser_button_signals[FILE_SET], 0); } - gdk_drop_finish (drop, GDK_ACTION_COPY); +} + +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 |