~ubuntu-branches/debian/experimental/thunar/experimental

« back to all changes in this revision

Viewing changes to thunar/thunar-dnd.c

  • Committer: Bazaar Package Importer
  • Author(s): Yves-Alexis Perez
  • Date: 2006-01-02 23:42:32 UTC
  • Revision ID: james.westby@ubuntu.com-20060102234232-8xeq0lqhyn70syr0
Tags: upstream-0.1.4svn+r18850
ImportĀ upstreamĀ versionĀ 0.1.4svn+r18850

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* $Id: thunar-dnd.c 18843 2005-11-14 14:25:58Z benny $ */
 
2
/*-
 
3
 * Copyright (c) 2005 Benedikt Meurer <benny@xfce.org>
 
4
 *
 
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)
 
8
 * any later version.
 
9
 *
 
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
 
13
 * more details.
 
14
 *
 
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
 
18
 */
 
19
 
 
20
#ifdef HAVE_CONFIG_H
 
21
#include <config.h>
 
22
#endif
 
23
 
 
24
#include <thunar/thunar-application.h>
 
25
#include <thunar/thunar-dialogs.h>
 
26
#include <thunar/thunar-dnd.h>
 
27
 
 
28
 
 
29
 
 
30
static void
 
31
action_selected (GtkWidget     *item,
 
32
                 GdkDragAction *action)
 
33
{
 
34
  *action = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (item), "action"));
 
35
}
 
36
 
 
37
 
 
38
 
 
39
/**
 
40
 * thunar_dnd_ask:
 
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.
 
44
 *
 
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
 
49
 * returned.
 
50
 *
 
51
 * This method can be used to implement a response to the
 
52
 * #GDK_ACTION_ASK action on drops.
 
53
 *
 
54
 * Return value: the selected #GdkDragAction or 0 to cancel.
 
55
 **/
 
56
GdkDragAction
 
57
thunar_dnd_ask (GtkWidget    *widget,
 
58
                guint         time,
 
59
                GdkDragAction actions)
 
60
{
 
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 };
 
64
 
 
65
  GdkDragAction action = 0;
 
66
  GtkWidget    *image;
 
67
  GtkWidget    *menu;
 
68
  GtkWidget    *item;
 
69
  GMainLoop    *loop;
 
70
  guint         n;
 
71
 
 
72
  g_return_val_if_fail (GTK_IS_WIDGET (widget), 0);
 
73
 
 
74
  /* prepare the internal loop */
 
75
  loop = g_main_loop_new (NULL, FALSE);
 
76
 
 
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);
 
81
 
 
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))
 
85
      {
 
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);
 
91
 
 
92
        /* add image to the menu item */
 
93
        if (G_LIKELY (action_icons[n] != NULL))
 
94
          {
 
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);
 
98
          }
 
99
      }
 
100
 
 
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);
 
105
 
 
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);
 
110
 
 
111
  /* run the internal loop */
 
112
  gtk_grab_add (menu);
 
113
  gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL, 3, time);
 
114
  g_main_loop_run (loop);
 
115
  gtk_grab_remove (menu);
 
116
 
 
117
  /* clean up */
 
118
  gtk_object_sink (GTK_OBJECT (menu));
 
119
  g_main_loop_unref (loop);
 
120
 
 
121
  return action;
 
122
}
 
123
 
 
124
 
 
125
 
 
126
/**
 
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.
 
136
 *
 
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.
 
140
 *
 
141
 * Return value: %TRUE if the DnD operation was started
 
142
 *               successfully, else %FALSE.
 
143
 **/
 
144
gboolean
 
145
thunar_dnd_perform (GtkWidget    *widget,
 
146
                    ThunarFile   *file,
 
147
                    GList        *path_list,
 
148
                    GdkDragAction action,
 
149
                    GClosure     *new_files_closure)
 
150
{
 
151
  ThunarApplication *application;
 
152
  gboolean           succeed = TRUE;
 
153
  GError            *error = NULL;
 
154
 
 
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);
 
158
 
 
159
  /* query a reference on the application object */
 
160
  application = thunar_application_get ();
 
161
 
 
162
  /* check if the file is a directory */
 
163
  if (thunar_file_is_directory (file))
 
164
    {
 
165
      /* perform the given directory operation */
 
166
      switch (action)
 
167
        {
 
168
        case GDK_ACTION_COPY:
 
169
          thunar_application_copy_into (application, widget, path_list, thunar_file_get_path (file), new_files_closure);
 
170
          break;
 
171
 
 
172
        case GDK_ACTION_MOVE:
 
173
          thunar_application_move_into (application, widget, path_list, thunar_file_get_path (file), new_files_closure);
 
174
          break;
 
175
 
 
176
        case GDK_ACTION_LINK:
 
177
          thunar_application_link_into (application, widget, path_list, thunar_file_get_path (file), new_files_closure);
 
178
          break;
 
179
 
 
180
        default:
 
181
          succeed = FALSE;
 
182
        }
 
183
    }
 
184
  else if (thunar_file_is_executable (file))
 
185
    {
 
186
      succeed = thunar_file_execute (file, gtk_widget_get_screen (widget), path_list, &error);
 
187
      if (G_UNLIKELY (!succeed))
 
188
        {
 
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));
 
191
 
 
192
          /* release the error */
 
193
          g_error_free (error);
 
194
        }
 
195
    }
 
196
  else
 
197
    {
 
198
      succeed = FALSE;
 
199
    }
 
200
 
 
201
  /* release the application reference */
 
202
  g_object_unref (G_OBJECT (application));
 
203
 
 
204
  return succeed;
 
205
}
 
206
 
 
207
 
 
208