gtkfilechooser: provide URI data when dragging files
This commit is contained in:
parent
badfe1295a
commit
d416fe6936
1 changed files with 265 additions and 0 deletions
|
|
@ -6888,6 +6888,77 @@ file_list_drag_motion_cb (GtkWidget *widget,
|
|||
}
|
||||
|
||||
/* Constructs the popup menu for the file list if needed */
|
||||
#define FILE_LIST_DRAG_URIS_KEY "gtk-file-chooser-drag-uris"
|
||||
#define FILE_LIST_DRAG_ACTIVE_KEY "gtk-file-chooser-drag-active"
|
||||
#define FILE_LIST_DRAG_STARTED_KEY "gtk-file-chooser-drag-started"
|
||||
#define FILE_LIST_DRAG_START_X_KEY "gtk-file-chooser-drag-start-x"
|
||||
#define FILE_LIST_DRAG_START_Y_KEY "gtk-file-chooser-drag-start-y"
|
||||
|
||||
static void
|
||||
file_list_drag_uri_foreach_cb (GtkTreeModel *model,
|
||||
GtkTreePath *path,
|
||||
GtkTreeIter *iter,
|
||||
gpointer data)
|
||||
{
|
||||
GPtrArray *uris = data;
|
||||
GFile *file = NULL;
|
||||
gchar *uri;
|
||||
|
||||
gtk_tree_model_get (model, iter,
|
||||
MODEL_COL_FILE, &file,
|
||||
-1);
|
||||
|
||||
if (!file)
|
||||
return;
|
||||
|
||||
uri = g_file_get_uri (file);
|
||||
if (uri)
|
||||
g_ptr_array_add (uris, uri);
|
||||
|
||||
g_object_unref (file);
|
||||
}
|
||||
|
||||
static void
|
||||
file_list_drag_data_get_cb (GtkWidget *widget,
|
||||
GdkDragContext *context,
|
||||
GtkSelectionData *selection_data,
|
||||
guint info,
|
||||
guint time_,
|
||||
GtkFileChooserDefault *impl)
|
||||
{
|
||||
gchar **stored_uris;
|
||||
GPtrArray *uris;
|
||||
|
||||
stored_uris = g_object_get_data (G_OBJECT (widget), FILE_LIST_DRAG_URIS_KEY);
|
||||
if (stored_uris &&
|
||||
g_object_get_data (G_OBJECT (widget), FILE_LIST_DRAG_ACTIVE_KEY))
|
||||
{
|
||||
gtk_selection_data_set_uris (selection_data, stored_uris);
|
||||
g_object_set_data (G_OBJECT (widget), FILE_LIST_DRAG_ACTIVE_KEY, NULL);
|
||||
g_object_set_data (G_OBJECT (widget), FILE_LIST_DRAG_STARTED_KEY, NULL);
|
||||
g_object_set_data (G_OBJECT (widget), FILE_LIST_DRAG_URIS_KEY, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
g_object_set_data (G_OBJECT (widget), FILE_LIST_DRAG_ACTIVE_KEY, NULL);
|
||||
g_object_set_data (G_OBJECT (widget), FILE_LIST_DRAG_STARTED_KEY, NULL);
|
||||
|
||||
uris = g_ptr_array_new ();
|
||||
|
||||
current_selection_selected_foreach (impl,
|
||||
file_list_drag_uri_foreach_cb,
|
||||
uris);
|
||||
|
||||
if (uris->len > 0)
|
||||
{
|
||||
g_ptr_array_add (uris, NULL);
|
||||
gtk_selection_data_set_uris (selection_data, (gchar **) uris->pdata);
|
||||
}
|
||||
|
||||
g_ptr_array_foreach (uris, (GFunc) g_free, NULL);
|
||||
g_ptr_array_free (uris, TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
file_list_build_popup_menu (GtkFileChooserDefault *impl)
|
||||
{
|
||||
|
|
@ -7297,6 +7368,179 @@ browse_files_select_icon_item_at_pos (GtkFileChooserDefault *impl,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
static gboolean
|
||||
browse_files_clicked_item_is_selected (GtkFileChooserDefault *impl,
|
||||
GtkWidget *widget,
|
||||
GdkEventButton *event)
|
||||
{
|
||||
GtkTreePath *path;
|
||||
gboolean selected = FALSE;
|
||||
|
||||
if (widget == impl->browse_files_tree_view)
|
||||
{
|
||||
GtkTreeSelection *selection;
|
||||
|
||||
if (!gtk_tree_view_get_path_at_pos (GTK_TREE_VIEW (impl->browse_files_tree_view),
|
||||
(gint) event->x, (gint) event->y,
|
||||
&path, NULL, NULL, NULL))
|
||||
return FALSE;
|
||||
|
||||
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_files_tree_view));
|
||||
selected = gtk_tree_selection_path_is_selected (selection, path);
|
||||
gtk_tree_path_free (path);
|
||||
|
||||
return selected;
|
||||
}
|
||||
|
||||
if (widget == impl->browse_files_icon_view)
|
||||
{
|
||||
path = gtk_icon_view_get_path_at_pos (GTK_ICON_VIEW (impl->browse_files_icon_view),
|
||||
(gint) event->x, (gint) event->y);
|
||||
if (!path)
|
||||
return FALSE;
|
||||
|
||||
selected = gtk_icon_view_path_is_selected (GTK_ICON_VIEW (impl->browse_files_icon_view), path);
|
||||
gtk_tree_path_free (path);
|
||||
|
||||
return selected;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
file_list_store_drag_uris (GtkWidget *widget,
|
||||
GtkFileChooserDefault *impl)
|
||||
{
|
||||
GPtrArray *uris;
|
||||
gchar **stored_uris;
|
||||
|
||||
uris = g_ptr_array_new ();
|
||||
|
||||
current_selection_selected_foreach (impl,
|
||||
file_list_drag_uri_foreach_cb,
|
||||
uris);
|
||||
|
||||
if (uris->len == 0)
|
||||
{
|
||||
g_ptr_array_free (uris, TRUE);
|
||||
g_object_set_data (G_OBJECT (widget), FILE_LIST_DRAG_URIS_KEY, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
g_ptr_array_add (uris, NULL);
|
||||
stored_uris = (gchar **) g_ptr_array_free (uris, FALSE);
|
||||
|
||||
g_object_set_data_full (G_OBJECT (widget),
|
||||
FILE_LIST_DRAG_URIS_KEY,
|
||||
stored_uris,
|
||||
(GDestroyNotify) g_strfreev);
|
||||
}
|
||||
|
||||
static void
|
||||
file_list_clear_drag_state (GtkWidget *widget)
|
||||
{
|
||||
g_object_set_data (G_OBJECT (widget), FILE_LIST_DRAG_ACTIVE_KEY, NULL);
|
||||
g_object_set_data (G_OBJECT (widget), FILE_LIST_DRAG_STARTED_KEY, NULL);
|
||||
g_object_set_data (G_OBJECT (widget), FILE_LIST_DRAG_START_X_KEY, NULL);
|
||||
g_object_set_data (G_OBJECT (widget), FILE_LIST_DRAG_START_Y_KEY, NULL);
|
||||
g_object_set_data (G_OBJECT (widget), FILE_LIST_DRAG_URIS_KEY, NULL);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
file_list_maybe_store_drag_uris (GtkWidget *widget,
|
||||
GdkEventButton *event,
|
||||
GtkFileChooserDefault *impl)
|
||||
{
|
||||
if (event->button != 1 ||
|
||||
current_selection_count_selected_rows (impl) <= 1 ||
|
||||
!browse_files_clicked_item_is_selected (impl, widget, event))
|
||||
{
|
||||
file_list_clear_drag_state (widget);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
file_list_store_drag_uris (widget, impl);
|
||||
if (!g_object_get_data (G_OBJECT (widget), FILE_LIST_DRAG_URIS_KEY))
|
||||
return FALSE;
|
||||
|
||||
g_object_set_data (G_OBJECT (widget),
|
||||
FILE_LIST_DRAG_ACTIVE_KEY,
|
||||
GINT_TO_POINTER (1));
|
||||
g_object_set_data (G_OBJECT (widget),
|
||||
FILE_LIST_DRAG_START_X_KEY,
|
||||
GINT_TO_POINTER ((gint) event->x));
|
||||
g_object_set_data (G_OBJECT (widget),
|
||||
FILE_LIST_DRAG_START_Y_KEY,
|
||||
GINT_TO_POINTER ((gint) event->y));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
file_list_multi_drag_motion_cb (GtkWidget *widget,
|
||||
GdkEventMotion *event,
|
||||
GtkFileChooserDefault *impl)
|
||||
{
|
||||
gint start_x;
|
||||
gint start_y;
|
||||
GtkTargetList *target_list;
|
||||
|
||||
if (!g_object_get_data (G_OBJECT (widget), FILE_LIST_DRAG_ACTIVE_KEY))
|
||||
return FALSE;
|
||||
|
||||
if (!(event->state & GDK_BUTTON1_MASK))
|
||||
{
|
||||
file_list_clear_drag_state (widget);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (g_object_get_data (G_OBJECT (widget), FILE_LIST_DRAG_STARTED_KEY))
|
||||
return TRUE;
|
||||
|
||||
start_x = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (widget),
|
||||
FILE_LIST_DRAG_START_X_KEY));
|
||||
start_y = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (widget),
|
||||
FILE_LIST_DRAG_START_Y_KEY));
|
||||
|
||||
if (!gtk_drag_check_threshold (widget, start_x, start_y,
|
||||
(gint) event->x, (gint) event->y))
|
||||
return TRUE;
|
||||
|
||||
g_object_set_data (G_OBJECT (widget),
|
||||
FILE_LIST_DRAG_STARTED_KEY,
|
||||
GINT_TO_POINTER (1));
|
||||
|
||||
target_list = gtk_target_list_new (NULL, 0);
|
||||
gtk_target_list_add_uri_targets (target_list, 0);
|
||||
|
||||
gtk_drag_begin (widget,
|
||||
target_list,
|
||||
GDK_ACTION_COPY | GDK_ACTION_MOVE,
|
||||
1,
|
||||
(GdkEvent *) event);
|
||||
|
||||
gtk_target_list_unref (target_list);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
file_list_multi_drag_button_release_cb (GtkWidget *widget,
|
||||
GdkEventButton *event,
|
||||
GtkFileChooserDefault *impl)
|
||||
{
|
||||
if (event->button == 1 &&
|
||||
g_object_get_data (G_OBJECT (widget), FILE_LIST_DRAG_ACTIVE_KEY))
|
||||
{
|
||||
file_list_clear_drag_state (widget);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
browse_files_select_clicked_item (GtkFileChooserDefault *impl,
|
||||
GtkWidget *widget,
|
||||
|
|
@ -7358,6 +7602,9 @@ list_button_press_event_cb (GtkWidget *widget,
|
|||
if (in_press)
|
||||
return FALSE;
|
||||
|
||||
if (file_list_maybe_store_drag_uris (widget, event, impl))
|
||||
return TRUE;
|
||||
|
||||
if (!_gtk_button_event_triggers_context_menu (event))
|
||||
return FALSE;
|
||||
|
||||
|
|
@ -8033,6 +8280,15 @@ create_browse_files_tree_view (GtkFileChooserDefault *impl)
|
|||
NULL, 0,
|
||||
GDK_ACTION_COPY | GDK_ACTION_MOVE);
|
||||
gtk_drag_source_add_uri_targets (impl->browse_files_tree_view);
|
||||
g_signal_connect (impl->browse_files_tree_view, "drag-data-get",
|
||||
G_CALLBACK (file_list_drag_data_get_cb), impl);
|
||||
g_signal_connect (impl->browse_files_tree_view, "motion-notify-event",
|
||||
G_CALLBACK (file_list_multi_drag_motion_cb), impl);
|
||||
g_signal_connect (impl->browse_files_tree_view, "button-release-event",
|
||||
G_CALLBACK (file_list_multi_drag_button_release_cb), impl);
|
||||
|
||||
gtk_widget_add_events (impl->browse_files_tree_view,
|
||||
GDK_BUTTON1_MOTION_MASK | GDK_BUTTON_RELEASE_MASK);
|
||||
|
||||
g_signal_connect (selection, "changed",
|
||||
G_CALLBACK (list_selection_changed), impl);
|
||||
|
|
@ -8139,6 +8395,15 @@ create_browse_files_icon_view (GtkFileChooserDefault *impl)
|
|||
NULL, 0,
|
||||
GDK_ACTION_COPY | GDK_ACTION_MOVE);
|
||||
gtk_drag_source_add_uri_targets (impl->browse_files_icon_view);
|
||||
g_signal_connect (impl->browse_files_icon_view, "drag-data-get",
|
||||
G_CALLBACK (file_list_drag_data_get_cb), impl);
|
||||
g_signal_connect (impl->browse_files_icon_view, "motion-notify-event",
|
||||
G_CALLBACK (file_list_multi_drag_motion_cb), impl);
|
||||
g_signal_connect (impl->browse_files_icon_view, "button-release-event",
|
||||
G_CALLBACK (file_list_multi_drag_button_release_cb), impl);
|
||||
|
||||
gtk_widget_add_events (impl->browse_files_icon_view,
|
||||
GDK_BUTTON1_MOTION_MASK | GDK_BUTTON_RELEASE_MASK);
|
||||
|
||||
impl->list_icon_renderer = gtk_cell_renderer_pixbuf_new ();
|
||||
g_object_set (G_OBJECT (impl->list_icon_renderer),
|
||||
|
|
|
|||
Loading…
Reference in a new issue