1
/* $Id: thunar-dnd.c 18843 2005-11-14 14:25:58Z benny $ */
3
* Copyright (c) 2005 Benedikt Meurer <benny@xfce.org>
5
* This program is free software; you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License as published by the Free
7
* Software Foundation; either version 2 of the License, or (at your option)
10
* This program is distributed in the hope that it will be useful, but WITHOUT
11
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15
* You should have received a copy of the GNU General Public License along with
16
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
17
* Place, Suite 330, Boston, MA 02111-1307 USA
24
#include <thunar/thunar-application.h>
25
#include <thunar/thunar-dialogs.h>
26
#include <thunar/thunar-dnd.h>
31
action_selected (GtkWidget *item,
32
GdkDragAction *action)
34
*action = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (item), "action"));
41
* @widget : the widget on which the drop was performed.
42
* @time : the time of the drop event.
43
* @actions : the list of actions supported for the drop.
45
* Pops up a menu that asks the user to choose one of the
46
* @actions or to cancel the drop. If the user chooses a
47
* valid #GdkDragAction from @actions, then this action is
48
* returned. Else if the user cancels the drop, 0 will be
51
* This method can be used to implement a response to the
52
* #GDK_ACTION_ASK action on drops.
54
* Return value: the selected #GdkDragAction or 0 to cancel.
57
thunar_dnd_ask (GtkWidget *widget,
59
GdkDragAction actions)
61
static const GdkDragAction action_items[] = { GDK_ACTION_COPY, GDK_ACTION_MOVE, GDK_ACTION_LINK };
62
static const gchar *action_names[] = { N_ ("_Copy here"), N_ ("_Move here"), N_ ("_Link here") };
63
static const gchar *action_icons[] = { "stock_folder-copy", "stock_folder-move", NULL };
65
GdkDragAction action = 0;
72
g_return_val_if_fail (GTK_IS_WIDGET (widget), 0);
74
/* prepare the internal loop */
75
loop = g_main_loop_new (NULL, FALSE);
77
/* prepare the popup menu */
78
menu = gtk_menu_new ();
79
gtk_menu_set_screen (GTK_MENU (menu), gtk_widget_get_screen (widget));
80
g_signal_connect_swapped (G_OBJECT (menu), "deactivate", G_CALLBACK (g_main_loop_quit), loop);
82
/* append the various items */
83
for (n = 0; n < G_N_ELEMENTS (action_items); ++n)
84
if (G_LIKELY ((actions & action_items[n]) != 0))
86
item = gtk_image_menu_item_new_with_mnemonic (_(action_names[n]));
87
g_object_set_data (G_OBJECT (item), "action", GUINT_TO_POINTER (action_items[n]));
88
g_signal_connect (G_OBJECT (item), "activate", G_CALLBACK (action_selected), &action);
89
gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
90
gtk_widget_show (item);
92
/* add image to the menu item */
93
if (G_LIKELY (action_icons[n] != NULL))
95
image = gtk_image_new_from_icon_name (action_icons[n], GTK_ICON_SIZE_MENU);
96
gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image);
97
gtk_widget_show (image);
101
/* append the separator */
102
item = gtk_separator_menu_item_new ();
103
gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
104
gtk_widget_show (item);
106
/* append the cancel item */
107
item = gtk_image_menu_item_new_from_stock (GTK_STOCK_CANCEL, NULL);
108
gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
109
gtk_widget_show (item);
111
/* run the internal loop */
113
gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL, 3, time);
114
g_main_loop_run (loop);
115
gtk_grab_remove (menu);
118
gtk_object_sink (GTK_OBJECT (menu));
119
g_main_loop_unref (loop);
127
* thunar_dnd_perform:
128
* @widget : the #GtkWidget on which the drop was done.
129
* @file : the #ThunarFile on which the @path_list was dropped.
130
* @path_list : the list of #ThunarVfsPath<!---->s that was dropped.
131
* @action : the #GdkDragAction that was performed.
132
* @new_files_closure : a #GClosure to connect to the job's "new-files" signal,
133
* which will be emitted when the job finishes with the
134
* list of #ThunarVfsPath<!---->s created by the job, or
135
* %NULL if you're not interested in the signal.
137
* Performs the drop of @path_list on @file in @widget, as given in
138
* @action and returns %TRUE if the drop was started successfully
139
* (or even completed successfully), else %FALSE.
141
* Return value: %TRUE if the DnD operation was started
142
* successfully, else %FALSE.
145
thunar_dnd_perform (GtkWidget *widget,
148
GdkDragAction action,
149
GClosure *new_files_closure)
151
ThunarApplication *application;
152
gboolean succeed = TRUE;
153
GError *error = NULL;
155
g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
156
g_return_val_if_fail (THUNAR_IS_FILE (file), FALSE);
157
g_return_val_if_fail (GTK_WIDGET_REALIZED (widget), FALSE);
159
/* query a reference on the application object */
160
application = thunar_application_get ();
162
/* check if the file is a directory */
163
if (thunar_file_is_directory (file))
165
/* perform the given directory operation */
168
case GDK_ACTION_COPY:
169
thunar_application_copy_into (application, widget, path_list, thunar_file_get_path (file), new_files_closure);
172
case GDK_ACTION_MOVE:
173
thunar_application_move_into (application, widget, path_list, thunar_file_get_path (file), new_files_closure);
176
case GDK_ACTION_LINK:
177
thunar_application_link_into (application, widget, path_list, thunar_file_get_path (file), new_files_closure);
184
else if (thunar_file_is_executable (file))
186
succeed = thunar_file_execute (file, gtk_widget_get_screen (widget), path_list, &error);
187
if (G_UNLIKELY (!succeed))
189
/* display an error to the user */
190
thunar_dialogs_show_error (widget, error, _("Unable to execute file `%s'"), thunar_file_get_display_name (file));
192
/* release the error */
193
g_error_free (error);
201
/* release the application reference */
202
g_object_unref (G_OBJECT (application));