~noskcaj/ubuntu/trusty/xfdesktop4/4.11.2-1

« back to all changes in this revision

Viewing changes to .pc/0007-Icon-positions-are-saved-restored-per-resolution.patch/src/xfdesktop-file-icon-manager.c

  • Committer: Package Import Robot
  • Author(s): Lionel Le Folgoc
  • Date: 2012-05-18 22:18:02 UTC
  • mfrom: (3.1.7 experimental)
  • Revision ID: package-import@ubuntu.com-20120518221802-htmj6h4apaij25l2
Tags: 4.10.0-1ubuntu1
* Merge from Debian experimental, remaining Ubuntu change:
  - debian/patches/xubuntu_improve-nautilus-interactions.patch: added,
    should prevent nautilus from taking over the desktop if xfdesktop is
    running (and vice-versa).

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 *  xfdesktop - xfce4's desktop manager
3
 
 *
4
 
 *  Copyright(c) 2006      Brian Tarricone, <bjt23@cornell.edu>
5
 
 *  Copyright(c) 2006      Benedikt Meurer, <benny@xfce.org>
6
 
 *  Copyright(c) 2010-2011 Jannis Pohlmann, <jannis@xfce.org>
7
 
 *
8
 
 *  This program is free software; you can redistribute it and/or modify
9
 
 *  it under the terms of the GNU General Public License as published by
10
 
 *  the Free Software Foundation; either version 2 of the License, or
11
 
 *  (at your option) any later version.
12
 
 *
13
 
 *  This program is distributed in the hope that it will be useful,
14
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 
 *  GNU Library General Public License for more details.
17
 
 *
18
 
 *  You should have received a copy of the GNU General Public License
19
 
 *  along with this program; if not, write to the Free Software
20
 
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21
 
 */
22
 
 
23
 
#ifdef HAVE_CONFIG_H
24
 
#include <config.h>
25
 
#endif
26
 
 
27
 
#ifdef HAVE_STRING_H
28
 
#include <string.h>
29
 
#endif
30
 
 
31
 
#ifdef HAVE_TIME_H
32
 
#include <time.h>
33
 
#endif
34
 
 
35
 
#ifdef HAVE_UNISTD_H
36
 
#include <unistd.h>
37
 
#endif
38
 
 
39
 
#ifdef HAVE_SYS_STAT_H
40
 
#include <sys/stat.h>
41
 
#endif
42
 
 
43
 
#ifdef HAVE_SYS_TYPES_H
44
 
#include <sys/types.h>
45
 
#endif
46
 
 
47
 
#ifdef HAVE_ERRNO_H
48
 
#include <errno.h>
49
 
#endif
50
 
 
51
 
#ifndef PATH_MAX
52
 
#define PATH_MAX 4096
53
 
#endif
54
 
 
55
 
#include <gio/gio.h>
56
 
#include <gdk/gdkkeysyms.h>
57
 
 
58
 
#ifdef HAVE_THUNARX
59
 
#include <thunarx/thunarx.h>
60
 
#endif
61
 
 
62
 
#include "xfce-desktop.h"
63
 
#include "xfdesktop-clipboard-manager.h"
64
 
#include "xfdesktop-common.h"
65
 
#include "xfdesktop-file-icon.h"
66
 
#include "xfdesktop-file-icon-manager.h"
67
 
#include "xfdesktop-file-utils.h"
68
 
#include "xfdesktop-file-manager-proxy.h"
69
 
#include "xfdesktop-icon-view.h"
70
 
#include "xfdesktop-regular-file-icon.h"
71
 
#include "xfdesktop-special-file-icon.h"
72
 
#include "xfdesktop-trash-proxy.h"
73
 
#include "xfdesktop-volume-icon.h"
74
 
#include "xfdesktop-thumbnailer.h"
75
 
 
76
 
#include <libxfce4util/libxfce4util.h>
77
 
#include <libxfce4ui/libxfce4ui.h>
78
 
 
79
 
#define SAVE_DELAY 7000
80
 
#define BORDER     8
81
 
 
82
 
#define SETTING_SHOW_FILESYSTEM  "/desktop-icons/file-icons/show-filesystem"
83
 
#define SETTING_SHOW_HOME        "/desktop-icons/file-icons/show-home"
84
 
#define SETTING_SHOW_TRASH       "/desktop-icons/file-icons/show-trash"
85
 
#define SETTING_SHOW_REMOVABLE   "/desktop-icons/file-icons/show-removable"
86
 
#define SETTING_SHOW_THUMBNAILS  "/desktop-icons/show-thumbnails"
87
 
 
88
 
enum
89
 
{
90
 
    PROP0 = 0,
91
 
    PROP_FOLDER,
92
 
    PROP_SHOW_FILESYSTEM,
93
 
    PROP_SHOW_HOME,
94
 
    PROP_SHOW_TRASH,
95
 
    PROP_SHOW_REMOVABLE,
96
 
    PROP_SHOW_THUMBNAILS
97
 
};
98
 
 
99
 
struct _XfdesktopFileIconManagerPrivate
100
 
{
101
 
    gboolean inited;
102
 
 
103
 
    XfconfChannel *channel;
104
 
    
105
 
    GtkWidget *desktop;
106
 
    XfdesktopIconView *icon_view;
107
 
    
108
 
    GdkScreen *gscreen;
109
 
    
110
 
    GFile *folder;
111
 
    XfdesktopFileIcon *desktop_icon;
112
 
    GFileMonitor *monitor;
113
 
    GFileEnumerator *enumerator;
114
 
 
115
 
    GVolumeMonitor *volume_monitor;
116
 
    
117
 
    GHashTable *icons;
118
 
    GHashTable *removable_icons;
119
 
    GHashTable *special_icons;
120
 
    
121
 
    gboolean show_removable_media;
122
 
    gboolean show_special[XFDESKTOP_SPECIAL_FILE_ICON_TRASH+1];
123
 
    gboolean show_thumbnails;
124
 
    
125
 
    guint save_icons_id;
126
 
    
127
 
    GList *deferred_icons;
128
 
    
129
 
    GtkTargetList *drag_targets;
130
 
    GtkTargetList *drop_targets;
131
 
    
132
 
#ifdef HAVE_THUNARX
133
 
    GList *thunarx_menu_providers;
134
 
    GList *thunarx_properties_providers;
135
 
#endif
136
 
 
137
 
    XfdesktopThumbnailer *thumbnailer;
138
 
};
139
 
 
140
 
static void xfdesktop_file_icon_manager_set_property(GObject *object,
141
 
                                                     guint property_id,
142
 
                                                     const GValue *value,
143
 
                                                     GParamSpec *pspec);
144
 
static void xfdesktop_file_icon_manager_get_property(GObject *object,
145
 
                                                     guint property_id,
146
 
                                                     GValue *value,
147
 
                                                     GParamSpec *pspec);
148
 
static void xfdesktop_file_icon_manager_finalize(GObject *obj);
149
 
static void xfdesktop_file_icon_manager_icon_view_manager_init(XfdesktopIconViewManagerIface *iface);
150
 
 
151
 
static gboolean xfdesktop_file_icon_manager_real_init(XfdesktopIconViewManager *manager,
152
 
                                                      XfdesktopIconView *icon_view);
153
 
static void xfdesktop_file_icon_manager_fini(XfdesktopIconViewManager *manager);
154
 
 
155
 
static gboolean xfdesktop_file_icon_manager_drag_drop(XfdesktopIconViewManager *manager,
156
 
                                                      XfdesktopIcon *drop_icon,
157
 
                                                      GdkDragContext *context,
158
 
                                                      guint16 row,
159
 
                                                      guint16 col,
160
 
                                                      guint time_);
161
 
static void xfdesktop_file_icon_manager_drag_data_received(XfdesktopIconViewManager *manager,
162
 
                                                           XfdesktopIcon *drop_icon,
163
 
                                                           GdkDragContext *context,
164
 
                                                           guint16 row,
165
 
                                                           guint16 col,
166
 
                                                           GtkSelectionData *data,
167
 
                                                           guint info,
168
 
                                                           guint time_);
169
 
static void xfdesktop_file_icon_manager_drag_data_get(XfdesktopIconViewManager *manager,
170
 
                                                      GList *drag_icons,
171
 
                                                      GdkDragContext *context,
172
 
                                                      GtkSelectionData *data,
173
 
                                                      guint info,
174
 
                                                      guint time_);
175
 
 
176
 
static gboolean xfdesktop_file_icon_manager_check_create_desktop_folder(GFile *file);
177
 
static void xfdesktop_file_icon_manager_load_desktop_folder(XfdesktopFileIconManager *fmanager);
178
 
static void xfdesktop_file_icon_manager_load_removable_media(XfdesktopFileIconManager *fmanager);
179
 
static void xfdesktop_file_icon_manager_remove_removable_media(XfdesktopFileIconManager *fmanager);
180
 
 
181
 
static void xfdesktop_file_icon_position_changed(XfdesktopFileIcon *icon,
182
 
                                                 gpointer user_data);
183
 
 
184
 
static void xfdesktop_file_icon_manager_update_image(GtkWidget *widget,
185
 
                                                     gchar *srcfile,
186
 
                                                     gchar *thumbfile,
187
 
                                                     XfdesktopFileIconManager *fmanager);
188
 
 
189
 
G_DEFINE_TYPE_EXTENDED(XfdesktopFileIconManager,
190
 
                       xfdesktop_file_icon_manager,
191
 
                       G_TYPE_OBJECT, 0,
192
 
                       G_IMPLEMENT_INTERFACE(XFDESKTOP_TYPE_ICON_VIEW_MANAGER,
193
 
                                             xfdesktop_file_icon_manager_icon_view_manager_init))
194
 
 
195
 
 
196
 
typedef struct
197
 
{
198
 
    XfdesktopFileIconManager *fmanager;
199
 
    DBusGProxy *proxy;
200
 
    DBusGProxyCall *call;
201
 
    GList *files;
202
 
} XfdesktopTrashFilesData;
203
 
 
204
 
enum
205
 
{
206
 
    TARGET_TEXT_URI_LIST = 0,
207
 
    TARGET_XDND_DIRECT_SAVE0,
208
 
    TARGET_NETSCAPE_URL,
209
 
};
210
 
 
211
 
static const GtkTargetEntry drag_targets[] = {
212
 
    { "text/uri-list", 0, TARGET_TEXT_URI_LIST, },
213
 
};
214
 
static const gint n_drag_targets = (sizeof(drag_targets)/sizeof(drag_targets[0]));
215
 
static const GtkTargetEntry drop_targets[] = {
216
 
    { "text/uri-list", 0, TARGET_TEXT_URI_LIST, },
217
 
    { "XdndDirectSave0", 0, TARGET_XDND_DIRECT_SAVE0, },
218
 
    { "_NETSCAPE_URL", 0, TARGET_NETSCAPE_URL },
219
 
};
220
 
static const gint n_drop_targets = (sizeof(drop_targets)/sizeof(drop_targets[0]));
221
 
 
222
 
static XfdesktopClipboardManager *clipboard_manager = NULL;
223
 
 
224
 
static GQuark xfdesktop_app_info_quark = 0;
225
 
 
226
 
 
227
 
static void
228
 
xfdesktop_file_icon_manager_class_init(XfdesktopFileIconManagerClass *klass)
229
 
{
230
 
    GObjectClass *gobject_class = (GObjectClass *)klass;
231
 
    
232
 
    g_type_class_add_private(klass, sizeof(XfdesktopFileIconManagerPrivate));
233
 
    
234
 
    gobject_class->set_property = xfdesktop_file_icon_manager_set_property;
235
 
    gobject_class->get_property = xfdesktop_file_icon_manager_get_property;
236
 
    gobject_class->finalize = xfdesktop_file_icon_manager_finalize;
237
 
    
238
 
    g_object_class_install_property(gobject_class, PROP_FOLDER,
239
 
                                    g_param_spec_object("folder", "Desktop Folder",
240
 
                                                       "Folder this icon manager manages",
241
 
                                                       G_TYPE_FILE,
242
 
                                                       G_PARAM_READWRITE
243
 
                                                       | G_PARAM_CONSTRUCT_ONLY
244
 
                                                       | G_PARAM_STATIC_NAME
245
 
                                                       | G_PARAM_STATIC_NICK
246
 
                                                       | G_PARAM_STATIC_BLURB));
247
 
 
248
 
#define XFDESKTOP_PARAM_FLAGS  (G_PARAM_READWRITE \
249
 
                                | G_PARAM_CONSTRUCT \
250
 
                                | G_PARAM_STATIC_NAME \
251
 
                                | G_PARAM_STATIC_NICK \
252
 
                                | G_PARAM_STATIC_BLURB)
253
 
    g_object_class_install_property(gobject_class, PROP_SHOW_FILESYSTEM,
254
 
                                    g_param_spec_boolean("show-filesystem",
255
 
                                                         "show filesystem",
256
 
                                                         "show filesystem",
257
 
                                                         TRUE,
258
 
                                                         XFDESKTOP_PARAM_FLAGS));
259
 
    g_object_class_install_property(gobject_class, PROP_SHOW_HOME,
260
 
                                    g_param_spec_boolean("show-home",
261
 
                                                         "show home",
262
 
                                                         "show home",
263
 
                                                         TRUE,
264
 
                                                         XFDESKTOP_PARAM_FLAGS));
265
 
    g_object_class_install_property(gobject_class, PROP_SHOW_TRASH,
266
 
                                    g_param_spec_boolean("show-trash",
267
 
                                                         "show trash",
268
 
                                                         "show trash",
269
 
                                                         TRUE,
270
 
                                                         XFDESKTOP_PARAM_FLAGS));
271
 
    g_object_class_install_property(gobject_class, PROP_SHOW_REMOVABLE,
272
 
                                    g_param_spec_boolean("show-removable",
273
 
                                                         "show removable",
274
 
                                                         "show removable",
275
 
                                                         TRUE,
276
 
                                                         XFDESKTOP_PARAM_FLAGS));
277
 
    g_object_class_install_property(gobject_class, PROP_SHOW_THUMBNAILS,
278
 
                                    g_param_spec_boolean("show-thumbnails",
279
 
                                                         "show-thumbnails",
280
 
                                                         "show-thumbnails",
281
 
                                                         FALSE,
282
 
                                                         XFDESKTOP_PARAM_FLAGS));
283
 
#undef XFDESKTOP_PARAM_FLAGS
284
 
 
285
 
    xfdesktop_app_info_quark = g_quark_from_static_string("xfdesktop-app-info-quark");
286
 
}
287
 
 
288
 
static void
289
 
xfdesktop_file_icon_manager_init(XfdesktopFileIconManager *fmanager)
290
 
{
291
 
    fmanager->priv = G_TYPE_INSTANCE_GET_PRIVATE(fmanager,
292
 
                                                 XFDESKTOP_TYPE_FILE_ICON_MANAGER,
293
 
                                                 XfdesktopFileIconManagerPrivate);
294
 
    
295
 
    /* be safe */
296
 
    fmanager->priv->gscreen = gdk_screen_get_default();
297
 
    fmanager->priv->drag_targets = gtk_target_list_new(drag_targets,
298
 
                                                       n_drag_targets);
299
 
    fmanager->priv->drop_targets = gtk_target_list_new(drop_targets,
300
 
                                                       n_drop_targets);
301
 
 
302
 
    fmanager->priv->thumbnailer = xfdesktop_thumbnailer_new();
303
 
 
304
 
    g_signal_connect(G_OBJECT(fmanager->priv->thumbnailer), "thumbnail-ready", G_CALLBACK(xfdesktop_file_icon_manager_update_image), fmanager);
305
 
}
306
 
 
307
 
static void
308
 
xfdesktop_file_icon_manager_set_property(GObject *object,
309
 
                                         guint property_id,
310
 
                                         const GValue *value,
311
 
                                         GParamSpec *pspec)
312
 
{
313
 
    XfdesktopFileIconManager *fmanager = XFDESKTOP_FILE_ICON_MANAGER(object);
314
 
    
315
 
    switch(property_id) {
316
 
        case PROP_FOLDER:
317
 
            fmanager->priv->folder = g_value_dup_object(value);
318
 
            xfdesktop_file_icon_manager_check_create_desktop_folder(fmanager->priv->folder);
319
 
            break;
320
 
 
321
 
        case PROP_SHOW_FILESYSTEM:
322
 
            xfdesktop_file_icon_manager_set_show_special_file(fmanager,
323
 
                                                              XFDESKTOP_SPECIAL_FILE_ICON_FILESYSTEM,
324
 
                                                              g_value_get_boolean(value));
325
 
            break;
326
 
 
327
 
        case PROP_SHOW_HOME:
328
 
            xfdesktop_file_icon_manager_set_show_special_file(fmanager,
329
 
                                                              XFDESKTOP_SPECIAL_FILE_ICON_HOME,
330
 
                                                              g_value_get_boolean(value));
331
 
            break;
332
 
 
333
 
        case PROP_SHOW_TRASH:
334
 
            xfdesktop_file_icon_manager_set_show_special_file(fmanager,
335
 
                                                              XFDESKTOP_SPECIAL_FILE_ICON_TRASH,
336
 
                                                              g_value_get_boolean(value));
337
 
            break;
338
 
 
339
 
        case PROP_SHOW_REMOVABLE:
340
 
            xfdesktop_file_icon_manager_set_show_removable_media(fmanager,
341
 
                                                                 g_value_get_boolean(value));
342
 
            break;
343
 
 
344
 
        case PROP_SHOW_THUMBNAILS:
345
 
            xfdesktop_file_icon_manager_set_show_thumbnails(fmanager,
346
 
                                                            g_value_get_boolean(value));
347
 
            break;
348
 
 
349
 
        default:
350
 
            G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
351
 
    }
352
 
}
353
 
 
354
 
static void
355
 
xfdesktop_file_icon_manager_get_property(GObject *object,
356
 
                                         guint property_id,
357
 
                                         GValue *value,
358
 
                                         GParamSpec *pspec)
359
 
{
360
 
    XfdesktopFileIconManager *fmanager = XFDESKTOP_FILE_ICON_MANAGER(object);
361
 
    
362
 
    switch(property_id) {
363
 
        case PROP_FOLDER:
364
 
            g_value_set_object(value, fmanager->priv->folder);
365
 
            break;
366
 
 
367
 
        case PROP_SHOW_FILESYSTEM:
368
 
            g_value_set_boolean(value,
369
 
                                fmanager->priv->show_special[XFDESKTOP_SPECIAL_FILE_ICON_FILESYSTEM]);
370
 
            break;
371
 
 
372
 
        case PROP_SHOW_HOME:
373
 
            g_value_set_boolean(value,
374
 
                                fmanager->priv->show_special[XFDESKTOP_SPECIAL_FILE_ICON_HOME]);
375
 
            break;
376
 
 
377
 
        case PROP_SHOW_TRASH:
378
 
            g_value_set_boolean(value,
379
 
                                fmanager->priv->show_special[XFDESKTOP_SPECIAL_FILE_ICON_TRASH]);
380
 
            break;
381
 
 
382
 
        case PROP_SHOW_REMOVABLE:
383
 
            g_value_set_boolean(value, fmanager->priv->show_removable_media);
384
 
            break;
385
 
 
386
 
        case PROP_SHOW_THUMBNAILS:
387
 
            g_value_set_boolean(value, fmanager->priv->show_thumbnails);
388
 
            break;
389
 
        
390
 
        default:
391
 
            G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
392
 
    }
393
 
}
394
 
 
395
 
static void
396
 
xfdesktop_file_icon_manager_finalize(GObject *obj)
397
 
{
398
 
    XfdesktopFileIconManager *fmanager = XFDESKTOP_FILE_ICON_MANAGER(obj);
399
 
    
400
 
    if(fmanager->priv->inited)
401
 
        xfdesktop_file_icon_manager_fini(XFDESKTOP_ICON_VIEW_MANAGER(fmanager));
402
 
    
403
 
    g_object_unref(G_OBJECT(fmanager->priv->channel));
404
 
 
405
 
    gtk_target_list_unref(fmanager->priv->drag_targets);
406
 
    gtk_target_list_unref(fmanager->priv->drop_targets);
407
 
    
408
 
    g_object_unref(fmanager->priv->folder);
409
 
    g_object_unref(fmanager->priv->thumbnailer);
410
 
    
411
 
    G_OBJECT_CLASS(xfdesktop_file_icon_manager_parent_class)->finalize(obj);
412
 
}
413
 
 
414
 
static void
415
 
xfdesktop_file_icon_manager_icon_view_manager_init(XfdesktopIconViewManagerIface *iface)
416
 
{
417
 
    iface->manager_init = xfdesktop_file_icon_manager_real_init;
418
 
    iface->manager_fini = xfdesktop_file_icon_manager_fini;
419
 
    iface->drag_drop = xfdesktop_file_icon_manager_drag_drop;
420
 
    iface->drag_data_received = xfdesktop_file_icon_manager_drag_data_received;
421
 
    iface->drag_data_get = xfdesktop_file_icon_manager_drag_data_get;
422
 
}
423
 
 
424
 
 
425
 
 
426
 
/* FIXME: remove this before 4.4.0; leave it for now to migrate older beta
427
 
* installs from the old location */
428
 
static void
429
 
__migrate_old_icon_positions(XfdesktopFileIconManager *fmanager)
430
 
{
431
 
    gchar relpath[PATH_MAX], *old_file;
432
 
    
433
 
    g_snprintf(relpath, PATH_MAX, "xfce4/desktop/icons.screen%d.rc",
434
 
               gdk_screen_get_number(fmanager->priv->gscreen));
435
 
    
436
 
    old_file = xfce_resource_save_location(XFCE_RESOURCE_CACHE, relpath, FALSE);
437
 
    
438
 
    if(G_UNLIKELY(old_file) && g_file_test(old_file, G_FILE_TEST_EXISTS)) {
439
 
        gchar *new_file = xfce_resource_save_location(XFCE_RESOURCE_CONFIG,
440
 
                                                      relpath, FALSE);
441
 
        if(G_LIKELY(new_file)) {
442
 
            if(rename(old_file, new_file)) {
443
 
                /* grumble, have to do this the hard way */
444
 
                gchar *contents = NULL;
445
 
                gsize length = 0;
446
 
                GError *error = NULL;
447
 
                
448
 
                if(g_file_get_contents(old_file, &contents, &length, &error)) {
449
 
                    if(!g_file_set_contents(new_file, contents, length,
450
 
                                            &error))
451
 
                    {
452
 
                        g_critical("Unable to write to %s: %s", new_file,
453
 
                                   error->message);
454
 
                        g_error_free(error);
455
 
                    }
456
 
 
457
 
                    g_free(contents);
458
 
                } else {
459
 
                    g_critical("Unable to read from %s: %s", old_file,
460
 
                               error->message);
461
 
                    g_error_free(error);
462
 
                }
463
 
            }
464
 
        } else
465
 
            g_critical("Unable to migrate icon position file to new location.");
466
 
        
467
 
        /* i debate removing the old file even if the migration failed,
468
 
         * but i think this is the best way to avoid bug reports that
469
 
         * aren't my problem. */
470
 
        unlink(old_file);
471
 
        
472
 
        g_free(new_file);
473
 
    }
474
 
    
475
 
    g_free(old_file);
476
 
}
477
 
 
478
 
static gboolean
479
 
xfdesktop_file_icon_manager_check_create_desktop_folder(GFile *folder)
480
 
{
481
 
    GFileInfo *info;
482
 
    GError *error = NULL;
483
 
    gboolean result = TRUE;
484
 
    gchar *primary;
485
 
    
486
 
    g_return_val_if_fail(G_IS_FILE(folder), FALSE);
487
 
 
488
 
    info = g_file_query_info(folder, XFDESKTOP_FILE_INFO_NAMESPACE,
489
 
                             G_FILE_QUERY_INFO_NONE, NULL, NULL);
490
 
 
491
 
    if(info == NULL) {
492
 
        if(!g_file_make_directory_with_parents(folder, NULL, &error)) {
493
 
            gchar *uri = g_file_get_uri(folder);
494
 
            gchar *display_name = g_filename_display_basename(uri);
495
 
            primary = g_markup_printf_escaped(_("Could not create the desktop folder \"%s\""),
496
 
                                              display_name);
497
 
            g_free(display_name);
498
 
            g_free(uri);
499
 
 
500
 
            xfce_message_dialog(NULL, _("Desktop Folder Error"),
501
 
                                GTK_STOCK_DIALOG_WARNING, primary,
502
 
                                error->message, GTK_STOCK_CLOSE,
503
 
                                GTK_RESPONSE_ACCEPT, NULL);
504
 
            g_free(primary);
505
 
 
506
 
            result = FALSE;
507
 
        }
508
 
    } else {
509
 
        if(g_file_info_get_file_type(info) != G_FILE_TYPE_DIRECTORY) {
510
 
            gchar *uri = g_file_get_uri(folder);
511
 
            gchar *display_name = g_filename_display_basename(uri);
512
 
            primary = g_markup_printf_escaped(_("Could not create the desktop folder \"%s\""),
513
 
                                              display_name);
514
 
            g_free(display_name);
515
 
            g_free(uri);
516
 
 
517
 
            xfce_message_dialog(NULL, _("Desktop Folder Error"),
518
 
                                GTK_STOCK_DIALOG_WARNING, primary,
519
 
                                _("A normal file with the same name already exists. "
520
 
                                  "Please delete or rename it."), GTK_STOCK_CLOSE,
521
 
                                GTK_RESPONSE_ACCEPT, NULL);
522
 
            g_free(primary);
523
 
 
524
 
            result = FALSE;
525
 
        }
526
 
    }
527
 
 
528
 
    return result;
529
 
}
530
 
 
531
 
 
532
 
/* icon signal handlers */
533
 
 
534
 
static void
535
 
xfdesktop_file_icon_menu_executed(GtkWidget *widget,
536
 
                                  gpointer user_data)
537
 
{
538
 
    XfdesktopFileIconManager *fmanager = XFDESKTOP_FILE_ICON_MANAGER(user_data);
539
 
    XfdesktopIcon *icon;
540
 
    GList *selected;
541
 
    
542
 
    selected = xfdesktop_icon_view_get_selected_items(fmanager->priv->icon_view);
543
 
    g_return_if_fail(g_list_length(selected) == 1);
544
 
    icon = XFDESKTOP_ICON(selected->data);
545
 
    g_list_free(selected);
546
 
    
547
 
    xfdesktop_icon_activated(icon);
548
 
}
549
 
 
550
 
static void
551
 
xfdesktop_file_icon_menu_open_all(GtkWidget *widget,
552
 
                                  gpointer user_data)
553
 
{
554
 
    XfdesktopFileIconManager *fmanager = XFDESKTOP_FILE_ICON_MANAGER(user_data);
555
 
    GList *selected;
556
 
    
557
 
    selected = xfdesktop_icon_view_get_selected_items(fmanager->priv->icon_view);
558
 
    g_return_if_fail(selected);
559
 
    
560
 
    g_list_foreach(selected, (GFunc)xfdesktop_icon_activated, NULL);
561
 
    g_list_free(selected);
562
 
}
563
 
 
564
 
static void
565
 
xfdesktop_file_icon_menu_rename(GtkWidget *widget,
566
 
                                gpointer user_data)
567
 
{
568
 
    XfdesktopFileIconManager *fmanager = XFDESKTOP_FILE_ICON_MANAGER(user_data);
569
 
    XfdesktopFileIcon *icon;
570
 
    GList *selected;
571
 
    GFile *file;
572
 
    GtkWidget *toplevel;
573
 
    
574
 
    selected = xfdesktop_icon_view_get_selected_items(fmanager->priv->icon_view);
575
 
    g_return_if_fail(g_list_length(selected) == 1);
576
 
    icon = XFDESKTOP_FILE_ICON(selected->data);
577
 
    g_list_free(selected);
578
 
    
579
 
    file = xfdesktop_file_icon_peek_file(icon);
580
 
    toplevel = gtk_widget_get_toplevel(GTK_WIDGET(fmanager->priv->icon_view));
581
 
    
582
 
    xfdesktop_file_utils_rename_file(file, fmanager->priv->gscreen, 
583
 
                                     GTK_WINDOW(toplevel));
584
 
}
585
 
 
586
 
enum
587
 
{
588
 
    COL_PIX = 0,
589
 
    COL_NAME,
590
 
    N_COLS
591
 
};
592
 
 
593
 
static void
594
 
xfdesktop_file_icon_manager_delete_files(XfdesktopFileIconManager *fmanager,
595
 
                                         GList *files)
596
 
{
597
 
    GtkWidget *toplevel = gtk_widget_get_toplevel(GTK_WIDGET(fmanager->priv->icon_view));
598
 
    GList *gfiles = NULL, *lp;
599
 
 
600
 
    for(lp = g_list_last(files); lp != NULL; lp = lp->prev)
601
 
        gfiles = g_list_prepend(gfiles, xfdesktop_file_icon_peek_file(lp->data));
602
 
 
603
 
    xfdesktop_file_utils_unlink_files(gfiles, fmanager->priv->gscreen, 
604
 
                                      GTK_WINDOW(toplevel));
605
 
 
606
 
    g_list_free(gfiles);
607
 
}
608
 
 
609
 
static void
610
 
xfdesktop_file_icon_manager_trash_files_cb(DBusGProxy *proxy,
611
 
                                           GError *error,
612
 
                                           gpointer user_data)
613
 
{
614
 
    XfdesktopFileIconManager *fmanager = user_data;
615
 
 
616
 
    g_return_if_fail(fmanager);
617
 
 
618
 
    if(error) {
619
 
        GtkWidget *parent = gtk_widget_get_toplevel(GTK_WIDGET(fmanager->priv->icon_view));
620
 
 
621
 
        xfce_message_dialog(GTK_WINDOW(parent),
622
 
                            _("Trash Error"), GTK_STOCK_DIALOG_ERROR,
623
 
                            _("The selected files could not be trashed"),
624
 
                            _("This feature requires a file manager service to "
625
 
                              "be present (such as the one supplied by Thunar)."),
626
 
                            GTK_STOCK_CLOSE, GTK_RESPONSE_ACCEPT, NULL);
627
 
    }
628
 
}
629
 
 
630
 
static gboolean
631
 
xfdesktop_file_icon_manager_trash_files(XfdesktopFileIconManager *fmanager,
632
 
                                        GList *files)
633
 
{
634
 
    DBusGProxy *trash_proxy = xfdesktop_file_utils_peek_trash_proxy();
635
 
    gboolean result = TRUE;
636
 
    gchar **uris, *display_name, *startup_id;
637
 
    GList *l;
638
 
    gint i, nfiles;
639
 
    GFile *file;
640
 
    
641
 
    g_return_val_if_fail(files, TRUE);
642
 
    
643
 
    if(!trash_proxy)
644
 
        return FALSE;
645
 
    
646
 
    nfiles = g_list_length(files);
647
 
    uris = g_new(gchar *, nfiles + 1);
648
 
    
649
 
    for(l = files, i = 0; l; l = l->next, ++i) {
650
 
        file = xfdesktop_file_icon_peek_file(XFDESKTOP_FILE_ICON(l->data));
651
 
        uris[i] = g_file_get_uri(file);
652
 
    }
653
 
    uris[nfiles] = NULL;
654
 
    
655
 
    display_name = gdk_screen_make_display_name(fmanager->priv->gscreen);
656
 
    startup_id = g_strdup_printf("_TIME%d", gtk_get_current_event_time());
657
 
    
658
 
    if (!xfdesktop_trash_proxy_move_to_trash_async(trash_proxy, (const char **)uris,
659
 
                                                   display_name, startup_id,
660
 
                                                   xfdesktop_file_icon_manager_trash_files_cb, 
661
 
                                                   fmanager))
662
 
    {
663
 
        GtkWidget *parent = gtk_widget_get_toplevel(GTK_WIDGET(fmanager->priv->icon_view));
664
 
 
665
 
        xfce_message_dialog(GTK_WINDOW(parent),
666
 
                            _("Trash Error"), GTK_STOCK_DIALOG_ERROR,
667
 
                            _("The selected files could not be trashed"),
668
 
                            _("This feature requires a file manager service to "
669
 
                              "be present (such as the one supplied by Thunar)."),
670
 
                            GTK_STOCK_CLOSE, GTK_RESPONSE_ACCEPT, NULL);
671
 
 
672
 
        result = FALSE;
673
 
    }
674
 
    
675
 
    g_free(startup_id);
676
 
    g_strfreev(uris);
677
 
    g_free(display_name);
678
 
    
679
 
    return result;
680
 
}
681
 
 
682
 
static void
683
 
xfdesktop_file_icon_manager_delete_selected(XfdesktopFileIconManager *fmanager,
684
 
                                            gboolean force_delete)
685
 
{
686
 
    GList *selected, *l;
687
 
    
688
 
    selected = xfdesktop_icon_view_get_selected_items(fmanager->priv->icon_view);
689
 
    if(!selected)
690
 
        return;
691
 
    
692
 
    /* remove anybody that's not deletable */
693
 
    for(l = selected; l; ) {
694
 
        if(!xfdesktop_file_icon_can_delete_file(XFDESKTOP_FILE_ICON(l->data))) {
695
 
            GList *next = l->next;
696
 
            
697
 
            if(l->prev)
698
 
                l->prev->next = l->next;
699
 
            else  /* this is the first item; reset |selected| */
700
 
                selected = l->next;
701
 
            
702
 
            if(l->next)
703
 
                l->next->prev = l->prev;
704
 
            
705
 
            l->next = l->prev = NULL;
706
 
            g_list_free_1(l);
707
 
            
708
 
            l = next;
709
 
        } else
710
 
            l = l->next;
711
 
    }
712
 
    
713
 
    if(G_UNLIKELY(!selected))
714
 
        return;
715
 
    
716
 
    /* make sure the icons don't get destroyed while we're working */
717
 
    g_list_foreach(selected, (GFunc)g_object_ref, NULL);
718
 
    
719
 
    if (!force_delete) {
720
 
        xfdesktop_file_icon_manager_trash_files(fmanager, selected);
721
 
    } else {
722
 
        xfdesktop_file_icon_manager_delete_files(fmanager, selected);
723
 
    }
724
 
      
725
 
    g_list_foreach(selected, (GFunc)g_object_unref, NULL);
726
 
    g_list_free(selected);
727
 
    
728
 
    xfdesktop_file_icon_position_changed(NULL, fmanager);
729
 
}
730
 
 
731
 
static void
732
 
xfdesktop_file_icon_menu_app_info_executed(GtkWidget *widget,
733
 
                                           gpointer user_data)
734
 
{
735
 
    XfdesktopFileIconManager *fmanager = XFDESKTOP_FILE_ICON_MANAGER(user_data);
736
 
    XfdesktopFileIcon *icon;
737
 
    GdkAppLaunchContext *context;
738
 
    GAppInfo *app_info;
739
 
    GFile *file;
740
 
    GList files, *selected;
741
 
    GtkWidget *toplevel;
742
 
    GError *error = NULL;
743
 
    
744
 
    selected = xfdesktop_icon_view_get_selected_items(fmanager->priv->icon_view);
745
 
    g_return_if_fail(g_list_length(selected) == 1);
746
 
    icon = XFDESKTOP_FILE_ICON(selected->data);
747
 
    g_list_free(selected);
748
 
    
749
 
    /* get the app info related to this menu item */
750
 
    app_info = g_object_get_qdata(G_OBJECT(widget), xfdesktop_app_info_quark);
751
 
    if(!app_info)
752
 
        return;
753
 
 
754
 
    /* build a fake file list */
755
 
    file = xfdesktop_file_icon_peek_file(icon);
756
 
    files.prev = files.next = NULL;
757
 
    files.data = file;
758
 
 
759
 
    /* prepare the launch context and configure its screen */
760
 
    context = gdk_app_launch_context_new();
761
 
    toplevel = gtk_widget_get_toplevel(GTK_WIDGET(fmanager->priv->icon_view));
762
 
    gdk_app_launch_context_set_screen(context, gtk_widget_get_screen(toplevel));
763
 
    
764
 
    /* try to launch the application */
765
 
    if(!xfdesktop_file_utils_app_info_launch(app_info, fmanager->priv->folder, &files,
766
 
                                             G_APP_LAUNCH_CONTEXT(context), &error))
767
 
    {
768
 
        gchar *primary = g_markup_printf_escaped(_("Unable to launch \"%s\":"),
769
 
                                                 g_app_info_get_name(app_info));
770
 
        xfce_message_dialog(GTK_WINDOW(toplevel), _("Launch Error"),
771
 
                            GTK_STOCK_DIALOG_ERROR, primary, error->message,
772
 
                            GTK_STOCK_CLOSE, GTK_RESPONSE_ACCEPT, NULL);
773
 
        g_free(primary);
774
 
        g_error_free(error);
775
 
    }
776
 
}
777
 
 
778
 
static void
779
 
xfdesktop_file_icon_menu_open_folder(GtkWidget *widget,
780
 
                                     gpointer user_data)
781
 
{
782
 
    XfdesktopFileIconManager *fmanager = XFDESKTOP_FILE_ICON_MANAGER(user_data);
783
 
    XfdesktopFileIcon *icon;
784
 
    GList *selected;
785
 
    GFile *file;
786
 
    GtkWidget *toplevel;
787
 
    
788
 
    selected = xfdesktop_icon_view_get_selected_items(fmanager->priv->icon_view);
789
 
    g_return_if_fail(g_list_length(selected) == 1);
790
 
    icon = XFDESKTOP_FILE_ICON(selected->data);
791
 
    g_list_free(selected);
792
 
    
793
 
    file = xfdesktop_file_icon_peek_file(icon);
794
 
    
795
 
    toplevel = gtk_widget_get_toplevel(GTK_WIDGET(fmanager->priv->icon_view));
796
 
    
797
 
    xfdesktop_file_utils_open_folder(file, fmanager->priv->gscreen,
798
 
                                     GTK_WINDOW(toplevel));
799
 
}
800
 
 
801
 
static void
802
 
xfdesktop_file_icon_menu_open_desktop(GtkWidget *widget,
803
 
                                      gpointer user_data)
804
 
{
805
 
    XfdesktopFileIconManager *fmanager = XFDESKTOP_FILE_ICON_MANAGER(user_data);
806
 
    XfdesktopFileIcon *icon = fmanager->priv->desktop_icon;
807
 
    GFile *file;
808
 
    GtkWidget *toplevel;
809
 
    
810
 
    file = xfdesktop_file_icon_peek_file(icon);
811
 
    if(!file)
812
 
        return;
813
 
    
814
 
    toplevel = gtk_widget_get_toplevel(GTK_WIDGET(fmanager->priv->icon_view));
815
 
    
816
 
    xfdesktop_file_utils_open_folder(file, fmanager->priv->gscreen,
817
 
                                     GTK_WINDOW(toplevel));
818
 
}
819
 
 
820
 
static void
821
 
xfdesktop_file_icon_menu_other_app(GtkWidget *widget,
822
 
                                   gpointer user_data)
823
 
{
824
 
    XfdesktopFileIconManager *fmanager = XFDESKTOP_FILE_ICON_MANAGER(user_data);
825
 
    XfdesktopFileIcon *icon;
826
 
    GtkWidget *toplevel;
827
 
    GList *selected;
828
 
    GFile *file;
829
 
    
830
 
    selected = xfdesktop_icon_view_get_selected_items(fmanager->priv->icon_view);
831
 
    g_return_if_fail(g_list_length(selected) == 1);
832
 
    icon = XFDESKTOP_FILE_ICON(selected->data);
833
 
    g_list_free(selected);
834
 
    
835
 
    toplevel = gtk_widget_get_toplevel(GTK_WIDGET(fmanager->priv->icon_view));
836
 
 
837
 
    file = xfdesktop_file_icon_peek_file(icon);
838
 
 
839
 
    xfdesktop_file_utils_display_chooser_dialog(file, TRUE, 
840
 
                                                fmanager->priv->gscreen, 
841
 
                                                GTK_WINDOW(toplevel));
842
 
}
843
 
 
844
 
static void
845
 
xfdesktop_file_icon_menu_cut(GtkWidget *widget,
846
 
                             gpointer user_data)
847
 
{
848
 
    XfdesktopFileIconManager *fmanager = XFDESKTOP_FILE_ICON_MANAGER(user_data);
849
 
    GList *files;
850
 
    
851
 
    files = xfdesktop_icon_view_get_selected_items(fmanager->priv->icon_view);
852
 
    if(!files)
853
 
        return;
854
 
    
855
 
    xfdesktop_clipboard_manager_cut_files(clipboard_manager, files);
856
 
    
857
 
    g_list_free(files);
858
 
}
859
 
 
860
 
static void
861
 
xfdesktop_file_icon_menu_copy(GtkWidget *widget,
862
 
                              gpointer user_data)
863
 
{
864
 
    XfdesktopFileIconManager *fmanager = XFDESKTOP_FILE_ICON_MANAGER(user_data);
865
 
    GList *files;
866
 
    
867
 
    files = xfdesktop_icon_view_get_selected_items(fmanager->priv->icon_view);
868
 
    if(!files)
869
 
        return;
870
 
    
871
 
    xfdesktop_clipboard_manager_copy_files(clipboard_manager, files);
872
 
    
873
 
    g_list_free(files);
874
 
}
875
 
 
876
 
static void
877
 
xfdesktop_file_icon_menu_delete(GtkWidget *widget,
878
 
                                gpointer user_data)
879
 
{
880
 
    XfdesktopFileIconManager *fmanager = XFDESKTOP_FILE_ICON_MANAGER(user_data);
881
 
    GdkModifierType state;
882
 
    gboolean force_delete = FALSE;
883
 
    
884
 
    if(gtk_get_current_event_state(&state) && state & GDK_SHIFT_MASK)
885
 
        force_delete = TRUE;
886
 
    
887
 
    xfdesktop_file_icon_manager_delete_selected(fmanager, force_delete);
888
 
}
889
 
 
890
 
static void
891
 
xfdesktop_file_icon_menu_paste(GtkWidget *widget,
892
 
                               gpointer user_data)
893
 
{
894
 
    XfdesktopFileIconManager *fmanager = XFDESKTOP_FILE_ICON_MANAGER(user_data);
895
 
    if(widget && fmanager)
896
 
        xfdesktop_clipboard_manager_paste_files(clipboard_manager, fmanager->priv->folder, widget, NULL);
897
 
}
898
 
 
899
 
static void
900
 
xfdesktop_file_icon_menu_properties(GtkWidget *widget,
901
 
                                    gpointer user_data)
902
 
{
903
 
    XfdesktopFileIconManager *fmanager = XFDESKTOP_FILE_ICON_MANAGER(user_data);
904
 
    GList *selected;
905
 
    XfdesktopFileIcon *icon;
906
 
    GtkWidget *toplevel;
907
 
    GFile *file;
908
 
    
909
 
    selected = xfdesktop_icon_view_get_selected_items(fmanager->priv->icon_view);
910
 
    g_return_if_fail(g_list_length(selected) == 1);
911
 
    icon = XFDESKTOP_FILE_ICON(selected->data);
912
 
    g_list_free(selected);
913
 
    
914
 
    file = xfdesktop_file_icon_peek_file(icon);
915
 
    toplevel = gtk_widget_get_toplevel(GTK_WIDGET(fmanager->priv->icon_view));
916
 
    
917
 
    xfdesktop_file_utils_show_properties_dialog(file, fmanager->priv->gscreen, 
918
 
                                                GTK_WINDOW(toplevel));
919
 
}
920
 
 
921
 
static void
922
 
xfdesktop_file_icon_manager_desktop_properties(GtkWidget *widget,
923
 
                                               gpointer user_data)
924
 
{
925
 
    XfdesktopFileIconManager *fmanager = XFDESKTOP_FILE_ICON_MANAGER(user_data);
926
 
    GtkWidget *parent = gtk_widget_get_toplevel(GTK_WIDGET(fmanager->priv->icon_view));
927
 
    GFile *file = xfdesktop_file_icon_peek_file (fmanager->priv->desktop_icon);
928
 
    
929
 
    xfdesktop_file_utils_show_properties_dialog(file, fmanager->priv->gscreen,
930
 
                                                GTK_WINDOW(parent));
931
 
}
932
 
 
933
 
static GtkWidget *
934
 
xfdesktop_menu_item_from_app_info(XfdesktopFileIconManager *fmanager,
935
 
                                  XfdesktopFileIcon *icon,
936
 
                                  GAppInfo *app_info,
937
 
                                  gboolean with_mnemonic,
938
 
                                  gboolean with_title_prefix)
939
 
{
940
 
    GtkWidget *mi, *img;
941
 
    gchar *title;
942
 
    GIcon *gicon;
943
 
 
944
 
    if(!with_title_prefix)
945
 
        title = g_strdup(g_app_info_get_name(app_info));
946
 
    else if(with_mnemonic) {
947
 
        title = g_strdup_printf(_("_Open With \"%s\""),
948
 
                                g_app_info_get_name(app_info));
949
 
    } else {
950
 
        title = g_strdup_printf(_("Open With \"%s\""),
951
 
                                g_app_info_get_name(app_info));
952
 
    }
953
 
 
954
 
    if(with_mnemonic)
955
 
        mi = gtk_image_menu_item_new_with_mnemonic(title);
956
 
    else
957
 
        mi = gtk_image_menu_item_new_with_label(title);
958
 
    g_free(title);
959
 
    
960
 
    g_object_set_qdata_full(G_OBJECT(mi), xfdesktop_app_info_quark,
961
 
                            g_object_ref(app_info), g_object_unref);
962
 
    
963
 
    gicon = g_app_info_get_icon(app_info);
964
 
    img = gtk_image_new_from_gicon(gicon, GTK_ICON_SIZE_MENU);
965
 
    gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(mi),
966
 
                                  img);
967
 
    gtk_widget_show(img);
968
 
    gtk_widget_show(mi);
969
 
    
970
 
    g_signal_connect(G_OBJECT(mi), "activate",
971
 
                     G_CALLBACK(xfdesktop_file_icon_menu_app_info_executed),
972
 
                     fmanager);
973
 
    
974
 
    return mi;
975
 
}
976
 
 
977
 
static gboolean
978
 
xfdesktop_file_icon_menu_free_icon_list_idled(gpointer user_data)
979
 
{
980
 
    GList *icon_list = user_data;
981
 
    
982
 
    g_list_foreach(icon_list, (GFunc)g_object_unref, NULL);
983
 
    g_list_free(icon_list);
984
 
    
985
 
    return FALSE;
986
 
}
987
 
 
988
 
static void
989
 
xfdesktop_file_icon_menu_free_icon_list(GtkMenu *menu,
990
 
                                        gpointer user_data)
991
 
{
992
 
    g_idle_add(xfdesktop_file_icon_menu_free_icon_list_idled, user_data);
993
 
}
994
 
 
995
 
static void
996
 
xfdesktop_file_icon_menu_create_launcher(GtkWidget *widget,
997
 
                                         gpointer user_data)
998
 
{
999
 
    XfdesktopFileIconManager *fmanager = XFDESKTOP_FILE_ICON_MANAGER(user_data);
1000
 
    GFile *file;
1001
 
    gchar *cmd = NULL, *uri = NULL, *display_name;
1002
 
    GError *error = NULL;
1003
 
    
1004
 
    display_name = gdk_screen_make_display_name(fmanager->priv->gscreen);
1005
 
    
1006
 
    file = g_object_get_data(G_OBJECT(widget), "file");
1007
 
 
1008
 
    if(file) {
1009
 
        uri = g_file_get_uri(file);
1010
 
        cmd = g_strdup_printf("exo-desktop-item-edit \"--display=%s\" \"%s\"",
1011
 
                              display_name, uri);
1012
 
    } else {
1013
 
        const gchar *type = g_object_get_data(G_OBJECT(widget), "xfdesktop-launcher-type");
1014
 
        uri = g_file_get_uri(fmanager->priv->folder);
1015
 
        if(G_UNLIKELY(!type))
1016
 
            type = "Application";
1017
 
        cmd = g_strdup_printf("exo-desktop-item-edit \"--display=%s\" --create-new --type %s \"%s\"",
1018
 
                              display_name, type, uri);
1019
 
    }
1020
 
    
1021
 
    if(!xfce_spawn_command_line_on_screen(NULL, cmd, FALSE, FALSE, &error)) {
1022
 
        GtkWidget *toplevel = gtk_widget_get_toplevel(GTK_WIDGET(fmanager->priv->icon_view));
1023
 
        xfce_message_dialog(GTK_WINDOW(toplevel), _("Launch Error"),
1024
 
                            GTK_STOCK_DIALOG_ERROR, 
1025
 
                            _("Unable to launch \"exo-desktop-item-edit\", which is required to create and edit launchers and links on the desktop."),
1026
 
                            error->message, GTK_STOCK_CLOSE,
1027
 
                            GTK_RESPONSE_ACCEPT, NULL);
1028
 
        g_error_free(error);
1029
 
    }
1030
 
    
1031
 
    g_free(display_name);
1032
 
    g_free(uri);
1033
 
    g_free(cmd);
1034
 
}
1035
 
 
1036
 
static void
1037
 
xfdesktop_file_icon_menu_create_folder(GtkWidget *widget,
1038
 
                                       gpointer user_data)
1039
 
{
1040
 
    XfdesktopFileIconManager *fmanager = XFDESKTOP_FILE_ICON_MANAGER(user_data);
1041
 
    GtkWidget *toplevel;
1042
 
    
1043
 
    toplevel = gtk_widget_get_toplevel(GTK_WIDGET(fmanager->priv->icon_view));
1044
 
    
1045
 
    xfdesktop_file_utils_create_file(fmanager->priv->folder, "inode/directory",
1046
 
                                     fmanager->priv->gscreen,
1047
 
                                     GTK_WINDOW(toplevel));
1048
 
}
1049
 
 
1050
 
static void
1051
 
xfdesktop_file_icon_template_item_activated(GtkWidget *mi,
1052
 
                                            gpointer user_data)
1053
 
{
1054
 
    XfdesktopFileIconManager *fmanager = XFDESKTOP_FILE_ICON_MANAGER(user_data);
1055
 
    GtkWidget *toplevel;
1056
 
    GFile *file = g_object_get_data(G_OBJECT(mi), "file");
1057
 
    
1058
 
    toplevel = gtk_widget_get_toplevel(GTK_WIDGET(fmanager->priv->icon_view));
1059
 
    
1060
 
    if(file) {
1061
 
        xfdesktop_file_utils_create_file_from_template(fmanager->priv->folder, file,
1062
 
                                                       fmanager->priv->gscreen,
1063
 
                                                        GTK_WINDOW(toplevel));
1064
 
    } else {
1065
 
        xfdesktop_file_utils_create_file(fmanager->priv->folder, "text/plain",
1066
 
                                         fmanager->priv->gscreen,
1067
 
                                         GTK_WINDOW(toplevel));
1068
 
    }
1069
 
}
1070
 
 
1071
 
static gint
1072
 
compare_template_files(gconstpointer a,
1073
 
                       gconstpointer b)
1074
 
{
1075
 
  GFileInfo *info_a = g_object_get_data(G_OBJECT(a), "info");
1076
 
  GFileInfo *info_b = g_object_get_data(G_OBJECT(b), "info");
1077
 
  GFileType type_a = g_file_info_get_file_type(info_a);
1078
 
  GFileType type_b = g_file_info_get_file_type(info_b);
1079
 
  const gchar* name_a = g_file_info_get_display_name(info_a);
1080
 
  const gchar* name_b = g_file_info_get_display_name(info_b);
1081
 
 
1082
 
  if(!info_a || !info_b)
1083
 
    return 0;
1084
 
 
1085
 
  if(type_a == type_b) {
1086
 
      return g_strcmp0(name_a, name_b);
1087
 
  } else {
1088
 
      if(type_a == G_FILE_TYPE_DIRECTORY)
1089
 
          return -1;
1090
 
      else
1091
 
          return 1;
1092
 
  }
1093
 
}
1094
 
 
1095
 
static gboolean
1096
 
xfdesktop_file_icon_menu_fill_template_menu(GtkWidget *menu,
1097
 
                                            GFile *template_dir,
1098
 
                                            XfdesktopFileIconManager *fmanager)
1099
 
{
1100
 
  GFileEnumerator *enumerator;
1101
 
  GtkWidget *item, *image, *submenu;
1102
 
  GFileInfo *info;
1103
 
  GFile *file;
1104
 
  GIcon *icon;
1105
 
  GList *files = NULL, *lp;
1106
 
  gchar *label, *dot;
1107
 
  gboolean have_templates = FALSE;
1108
 
  
1109
 
  g_return_val_if_fail(G_IS_FILE(template_dir), FALSE);
1110
 
 
1111
 
  enumerator = g_file_enumerate_children(template_dir,
1112
 
                                         XFDESKTOP_FILE_INFO_NAMESPACE,
1113
 
                                         G_FILE_QUERY_INFO_NONE,
1114
 
                                         NULL, NULL);
1115
 
 
1116
 
  if(enumerator) {
1117
 
      while((info = g_file_enumerator_next_file(enumerator, NULL, NULL))) {
1118
 
          file = g_file_get_child(template_dir, g_file_info_get_name(info));
1119
 
          g_object_set_data_full(G_OBJECT(file), "info", info, g_object_unref);
1120
 
          files = g_list_prepend(files, file);
1121
 
      }
1122
 
 
1123
 
      g_object_unref(enumerator);
1124
 
  }
1125
 
 
1126
 
  files = g_list_sort(files, compare_template_files);
1127
 
 
1128
 
  for(lp = files; lp != NULL; lp = lp->next) {
1129
 
      file = lp->data;
1130
 
      info = g_object_get_data(G_OBJECT(file), "info");
1131
 
 
1132
 
      if(g_file_info_get_file_type(info) == G_FILE_TYPE_DIRECTORY) {
1133
 
          /* allocate a new submenu for the directory */
1134
 
          submenu = gtk_menu_new();
1135
 
          g_object_ref_sink(submenu);
1136
 
          gtk_menu_set_screen(GTK_MENU(submenu), gtk_widget_get_screen(menu));
1137
 
 
1138
 
          /* fill the submenu from the folder contents */
1139
 
          have_templates = xfdesktop_file_icon_menu_fill_template_menu(submenu, file, fmanager)
1140
 
                           || have_templates;
1141
 
 
1142
 
          /* check if any items were added to the submenu */
1143
 
          if (GTK_MENU_SHELL(submenu)->children)
1144
 
            {
1145
 
              /* create a new menu item for the submenu */
1146
 
              item = gtk_image_menu_item_new_with_label (g_file_info_get_display_name(info));
1147
 
              icon = g_file_info_get_icon(info);
1148
 
              image = gtk_image_new_from_gicon(icon, GTK_ICON_SIZE_MENU);
1149
 
              gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image);
1150
 
              gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), submenu);
1151
 
              gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
1152
 
              gtk_widget_show (item);
1153
 
            }
1154
 
 
1155
 
          /* cleanup */
1156
 
          g_object_unref (submenu);
1157
 
      } else {
1158
 
          /* generate a label by stripping off the extension */
1159
 
          label = g_strdup(g_file_info_get_display_name(info));
1160
 
          dot = g_utf8_strrchr(label, -1, '.');
1161
 
          if(dot)
1162
 
              *dot = '\0';
1163
 
 
1164
 
          /* allocate a new menu item */
1165
 
          item = gtk_image_menu_item_new_with_label(label);
1166
 
          icon = g_file_info_get_icon(info);
1167
 
          image = gtk_image_new_from_gicon(icon, GTK_ICON_SIZE_MENU);
1168
 
          gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item), image);
1169
 
          gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
1170
 
          gtk_widget_show(item);
1171
 
 
1172
 
          g_object_set_data_full(G_OBJECT(item), "file", 
1173
 
                                 g_object_ref(file), g_object_unref);
1174
 
 
1175
 
          g_signal_connect (G_OBJECT(item), "activate",
1176
 
                            G_CALLBACK(xfdesktop_file_icon_template_item_activated),
1177
 
                            fmanager);
1178
 
 
1179
 
          have_templates = TRUE;
1180
 
      }
1181
 
 
1182
 
      g_object_unref(file);
1183
 
  }
1184
 
 
1185
 
  g_list_free(files);
1186
 
 
1187
 
  return have_templates;
1188
 
#if 0
1189
 
  dp = g_dir_open (absolute_path, 0, NULL);
1190
 
  g_free (absolute_path);
1191
 
 
1192
 
  /* read the directory contents (if opened successfully) */
1193
 
  if (G_LIKELY (dp != NULL))
1194
 
    {
1195
 
      /* process all files within the directory */
1196
 
      for (;;)
1197
 
        {
1198
 
          /* read the name of the next file */
1199
 
          name = g_dir_read_name (dp);
1200
 
          if (G_UNLIKELY (name == NULL))
1201
 
            break;
1202
 
          else if (name[0] == '.')
1203
 
            continue;
1204
 
 
1205
 
          /* determine the info for that file */
1206
 
          path = thunar_vfs_path_relative (templates_path, name);
1207
 
          info = thunar_vfs_info_new_for_path (path, NULL);
1208
 
          thunar_vfs_path_unref (path);
1209
 
 
1210
 
          /* add the info (if any) to our list */
1211
 
          if (G_LIKELY (info != NULL))
1212
 
            info_list = g_list_insert_sorted (info_list, info, info_compare);
1213
 
        }
1214
 
 
1215
 
      /* close the directory handle */
1216
 
      g_dir_close (dp);
1217
 
    }
1218
 
 
1219
 
  /* check if we have any infos */
1220
 
  if (G_UNLIKELY (info_list == NULL))
1221
 
    return FALSE;
1222
 
 
1223
 
  /* determine the icon theme for the menu */
1224
 
  icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (menu));
1225
 
 
1226
 
  /* add menu items for all infos */
1227
 
  for (lp = info_list; lp != NULL; lp = lp->next)
1228
 
    {
1229
 
      /* determine the info */
1230
 
      info = lp->data;
1231
 
 
1232
 
      /* check if we have a regular file or a directory here */
1233
 
      if (G_LIKELY (info->type == THUNAR_VFS_FILE_TYPE_REGULAR))
1234
 
        {
1235
 
          /* generate a label by stripping off the extension */
1236
 
          label = g_strdup (info->display_name);
1237
 
          dot = g_utf8_strrchr (label, -1, '.');
1238
 
          if (G_LIKELY (dot != NULL))
1239
 
            *dot = '\0';
1240
 
 
1241
 
          /* allocate a new menu item */
1242
 
          item = gtk_image_menu_item_new_with_label (label);
1243
 
          g_object_set_data_full (G_OBJECT (item), I_("thunar-vfs-info"), thunar_vfs_info_ref (info), (GDestroyNotify) thunar_vfs_info_unref);
1244
 
          g_signal_connect (G_OBJECT (item), "activate",
1245
 
                            G_CALLBACK (xfdesktop_file_icon_template_item_activated),
1246
 
                            fmanager);
1247
 
          gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
1248
 
          gtk_widget_show (item);
1249
 
 
1250
 
          /* lookup the icon for the mime type of that file */
1251
 
          icon_name = thunar_vfs_mime_info_lookup_icon_name (info->mime_info, icon_theme);
1252
 
 
1253
 
          /* generate an image based on the named icon */
1254
 
          image = gtk_image_new_from_icon_name (icon_name, GTK_ICON_SIZE_MENU);
1255
 
          gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image);
1256
 
          gtk_widget_show (image);
1257
 
 
1258
 
          /* cleanup */
1259
 
          g_free (label);
1260
 
          
1261
 
          have_templates = TRUE;
1262
 
        }
1263
 
      else if (info->type == THUNAR_VFS_FILE_TYPE_DIRECTORY)
1264
 
        {
1265
 
          /* allocate a new submenu for the directory */
1266
 
          submenu = gtk_menu_new ();
1267
 
          g_object_ref_sink (G_OBJECT (submenu));
1268
 
          gtk_menu_set_screen (GTK_MENU (submenu), gtk_widget_get_screen (menu));
1269
 
 
1270
 
          /* fill the submenu from the folder contents */
1271
 
          have_templates = xfdesktop_file_icon_menu_fill_template_menu(submenu,
1272
 
                                                                       info->path,
1273
 
                                                                       fmanager)
1274
 
                           || have_templates;
1275
 
 
1276
 
          /* check if any items were added to the submenu */
1277
 
          if (G_LIKELY (GTK_MENU_SHELL (submenu)->children != NULL))
1278
 
            {
1279
 
              /* hook up the submenu */
1280
 
              item = gtk_image_menu_item_new_with_label (info->display_name);
1281
 
              gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), submenu);
1282
 
              gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
1283
 
              gtk_widget_show (item);
1284
 
 
1285
 
              /* lookup the icon for the mime type of that file */
1286
 
              icon_name = thunar_vfs_mime_info_lookup_icon_name (info->mime_info, icon_theme);
1287
 
 
1288
 
              /* generate an image based on the named icon */
1289
 
              image = gtk_image_new_from_icon_name (icon_name, GTK_ICON_SIZE_MENU);
1290
 
              gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image);
1291
 
              gtk_widget_show (image);
1292
 
            }
1293
 
 
1294
 
          /* cleanup */
1295
 
          g_object_unref (G_OBJECT (submenu));
1296
 
        }
1297
 
    }
1298
 
 
1299
 
  /* release the info list */
1300
 
  thunar_vfs_info_list_free (info_list);
1301
 
#endif
1302
 
  
1303
 
  return have_templates;
1304
 
}
1305
 
 
1306
 
#ifdef HAVE_THUNARX
1307
 
static inline void
1308
 
xfdesktop_menu_shell_append_action_list(GtkMenuShell *menu_shell,
1309
 
                                        GList *actions)
1310
 
{
1311
 
    GList *l;
1312
 
    GtkAction *action;
1313
 
    GtkWidget *mi;
1314
 
    
1315
 
    for(l = actions; l; l = l->next) {
1316
 
        action = GTK_ACTION(l->data);
1317
 
        mi = gtk_action_create_menu_item(action);
1318
 
        gtk_widget_show(mi);
1319
 
        gtk_menu_shell_append(menu_shell, mi);    
1320
 
    }
1321
 
}
1322
 
#endif
1323
 
 
1324
 
static void
1325
 
xfdesktop_settings_launch(GtkWidget *w,
1326
 
                          gpointer user_data)
1327
 
{
1328
 
    XfdesktopFileIconManager *fmanager = XFDESKTOP_FILE_ICON_MANAGER(user_data);
1329
 
    gchar *cmd;
1330
 
    GError *error = NULL;
1331
 
    
1332
 
    cmd = g_find_program_in_path("xfdesktop-settings");
1333
 
    if(!cmd)
1334
 
        cmd = g_strdup(BINDIR "/xfdesktop-settings");
1335
 
    
1336
 
    if(!xfce_spawn_command_line_on_screen(fmanager->priv->gscreen, cmd, FALSE, TRUE, &error)) {
1337
 
        GtkWidget *toplevel = gtk_widget_get_toplevel(GTK_WIDGET(fmanager->priv->icon_view));
1338
 
        /* printf is to be translator-friendly */
1339
 
        gchar *primary = g_strdup_printf(_("Unable to launch \"%s\":"), cmd);
1340
 
        xfce_message_dialog(GTK_WINDOW(toplevel), _("Launch Error"),
1341
 
                            GTK_STOCK_DIALOG_ERROR, primary, error->message,
1342
 
                            GTK_STOCK_CLOSE, GTK_RESPONSE_ACCEPT, NULL);
1343
 
        g_free(primary);
1344
 
        g_error_free(error);
1345
 
    }
1346
 
 
1347
 
    g_free(cmd);
1348
 
}
1349
 
 
1350
 
static void
1351
 
xfdesktop_file_icon_manager_populate_context_menu(XfceDesktop *desktop,
1352
 
                                                  GtkMenuShell *menu,
1353
 
                                                  gpointer user_data)
1354
 
{
1355
 
    XfdesktopFileIconManager *fmanager = XFDESKTOP_FILE_ICON_MANAGER(user_data);
1356
 
    XfdesktopFileIcon *file_icon = NULL;
1357
 
    GFileInfo *info = NULL;
1358
 
    GList *selected, *app_infos, *l;
1359
 
    GtkWidget *mi, *img, *tmpl_menu;
1360
 
    gboolean multi_sel, got_custom_menu = FALSE;
1361
 
    GFile *templates_dir = NULL, *home_dir;
1362
 
    const gchar *templates_dir_path = NULL;
1363
 
#ifdef HAVE_THUNARX
1364
 
    GtkWidget *toplevel = gtk_widget_get_toplevel(GTK_WIDGET(fmanager->priv->icon_view));
1365
 
#endif
1366
 
    
1367
 
    TRACE("ENTERING");
1368
 
    
1369
 
    selected = xfdesktop_icon_view_get_selected_items(fmanager->priv->icon_view);
1370
 
    if(selected)
1371
 
        file_icon = selected->data;
1372
 
    else {
1373
 
        /* assume click on the desktop itself */
1374
 
        selected = g_list_append(selected, fmanager->priv->desktop_icon);
1375
 
        file_icon = fmanager->priv->desktop_icon;
1376
 
    }
1377
 
    info = xfdesktop_file_icon_peek_file_info(file_icon);
1378
 
    
1379
 
    multi_sel = (g_list_length(selected) > 1);
1380
 
    
1381
 
    if(!multi_sel) {
1382
 
        got_custom_menu = xfdesktop_icon_populate_context_menu(XFDESKTOP_ICON(selected->data),
1383
 
                                                               GTK_WIDGET(menu));
1384
 
    }
1385
 
    
1386
 
    /* make sure icons don't get destroyed while menu is open */
1387
 
    g_list_foreach(selected, (GFunc)g_object_ref, NULL);
1388
 
    g_object_set_data(G_OBJECT(menu), "--xfdesktop-icon-list", selected);
1389
 
    g_signal_connect(G_OBJECT(menu), "deactivate",
1390
 
                     G_CALLBACK(xfdesktop_file_icon_menu_free_icon_list),
1391
 
                     selected);
1392
 
    
1393
 
    if(!got_custom_menu) {
1394
 
        if(multi_sel) {
1395
 
            img = gtk_image_new_from_stock(GTK_STOCK_OPEN, GTK_ICON_SIZE_MENU);
1396
 
            gtk_widget_show(img);
1397
 
            mi = gtk_image_menu_item_new_with_mnemonic(_("_Open all"));
1398
 
            gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(mi), img);
1399
 
            gtk_widget_show(mi);
1400
 
            gtk_menu_shell_append(GTK_MENU_SHELL(menu), mi);
1401
 
            g_signal_connect(G_OBJECT(mi), "activate",
1402
 
                             G_CALLBACK(xfdesktop_file_icon_menu_open_all),
1403
 
                             fmanager);
1404
 
            
1405
 
            mi = gtk_separator_menu_item_new();
1406
 
            gtk_widget_show(mi);
1407
 
            gtk_menu_shell_append(GTK_MENU_SHELL(menu), mi);
1408
 
        } else if(info) {
1409
 
            if(g_file_info_get_file_type(info) == G_FILE_TYPE_DIRECTORY) {
1410
 
                img = gtk_image_new_from_stock(GTK_STOCK_OPEN, GTK_ICON_SIZE_MENU);
1411
 
                gtk_widget_show(img);
1412
 
                if(file_icon == fmanager->priv->desktop_icon)
1413
 
                    mi = gtk_image_menu_item_new_with_mnemonic(_("_Open in New Window"));
1414
 
                else
1415
 
                    mi = gtk_image_menu_item_new_with_mnemonic(_("_Open"));
1416
 
                gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(mi), img);
1417
 
                gtk_widget_show(mi);
1418
 
                gtk_menu_shell_append(GTK_MENU_SHELL(menu), mi);
1419
 
                g_signal_connect(G_OBJECT(mi), "activate",
1420
 
                                 file_icon == fmanager->priv->desktop_icon
1421
 
                                 ? G_CALLBACK(xfdesktop_file_icon_menu_open_desktop)
1422
 
                                 : G_CALLBACK(xfdesktop_file_icon_menu_open_folder),
1423
 
                                 fmanager);
1424
 
                
1425
 
                mi = gtk_separator_menu_item_new();
1426
 
                gtk_widget_show(mi);
1427
 
                gtk_menu_shell_append(GTK_MENU_SHELL(menu), mi);
1428
 
                
1429
 
                if(file_icon == fmanager->priv->desktop_icon) {
1430
 
                    GIcon *icon;
1431
 
 
1432
 
                    /* create launcher item */
1433
 
 
1434
 
                    mi = gtk_image_menu_item_new_with_mnemonic(_("Create _Launcher..."));
1435
 
                    g_object_set_data(G_OBJECT(mi), "xfdesktop-launcher-type", "Application");
1436
 
                    gtk_menu_shell_append(GTK_MENU_SHELL(menu), mi);
1437
 
                    gtk_widget_show(mi);
1438
 
 
1439
 
                    g_signal_connect(G_OBJECT(mi), "activate",
1440
 
                                     G_CALLBACK(xfdesktop_file_icon_menu_create_launcher),
1441
 
                                     fmanager);
1442
 
 
1443
 
                    icon = g_content_type_get_icon("application/x-desktop");
1444
 
                    img = gtk_image_new_from_gicon(icon, GTK_ICON_SIZE_MENU);
1445
 
                    gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(mi), img);
1446
 
                    gtk_widget_show(img);
1447
 
 
1448
 
                    /* create link item */
1449
 
                    
1450
 
                    mi = gtk_image_menu_item_new_with_mnemonic(_("Create _URL Link..."));
1451
 
                    g_object_set_data(G_OBJECT(mi), "xfdesktop-launcher-type", "Link");
1452
 
                    gtk_menu_shell_append(GTK_MENU_SHELL(menu), mi);
1453
 
                    gtk_widget_show(mi);
1454
 
 
1455
 
                    g_signal_connect(G_OBJECT(mi), "activate",
1456
 
                                     G_CALLBACK(xfdesktop_file_icon_menu_create_launcher),
1457
 
                                     fmanager);
1458
 
                    
1459
 
                    icon = g_themed_icon_new("insert-link");
1460
 
                    img = gtk_image_new_from_gicon(icon, GTK_ICON_SIZE_MENU);
1461
 
                    gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(mi), img);
1462
 
                    gtk_widget_show(img);
1463
 
 
1464
 
                    /* create folder item */
1465
 
 
1466
 
                    mi = gtk_image_menu_item_new_with_mnemonic(_("Create _Folder..."));
1467
 
                    gtk_menu_shell_append(GTK_MENU_SHELL(menu), mi);
1468
 
                    gtk_widget_show(mi);
1469
 
 
1470
 
                    g_signal_connect(G_OBJECT(mi), "activate",
1471
 
                                     G_CALLBACK(xfdesktop_file_icon_menu_create_folder),
1472
 
                                     fmanager);
1473
 
 
1474
 
                    icon = g_content_type_get_icon("inode/directory");
1475
 
                    img = gtk_image_new_from_gicon(icon, GTK_ICON_SIZE_MENU);
1476
 
                    gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(mi), img);
1477
 
                    gtk_widget_show(img);
1478
 
                    
1479
 
                    /* create from template submenu */
1480
 
 
1481
 
                    mi = gtk_menu_item_new_with_mnemonic(_("Create From _Template"));
1482
 
                    gtk_widget_show(mi);
1483
 
                    gtk_menu_shell_append(GTK_MENU_SHELL(menu), mi);
1484
 
                    
1485
 
                    tmpl_menu = gtk_menu_new();
1486
 
                    gtk_menu_item_set_submenu(GTK_MENU_ITEM(mi), tmpl_menu);
1487
 
                    
1488
 
                    home_dir = g_file_new_for_path(xfce_get_homedir());
1489
 
                    templates_dir_path = g_get_user_special_dir(G_USER_DIRECTORY_TEMPLATES);
1490
 
                    if(templates_dir_path) {
1491
 
                        templates_dir = g_file_new_for_path(templates_dir_path);
1492
 
                    }
1493
 
 
1494
 
                    if(templates_dir && !g_file_equal(home_dir, templates_dir))
1495
 
                    {
1496
 
                        xfdesktop_file_icon_menu_fill_template_menu(tmpl_menu,
1497
 
                                                                    templates_dir,
1498
 
                                                                    fmanager);
1499
 
                    }
1500
 
 
1501
 
                    if(templates_dir)
1502
 
                        g_object_unref(templates_dir);
1503
 
                    g_object_unref(home_dir);
1504
 
 
1505
 
                    img = gtk_image_new_from_stock(GTK_STOCK_NEW, GTK_ICON_SIZE_MENU);
1506
 
                    gtk_widget_show(img);
1507
 
                    mi = gtk_image_menu_item_new_with_mnemonic(_("_Empty File"));
1508
 
                    gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(mi), img);
1509
 
                    gtk_widget_show(mi);
1510
 
                    gtk_menu_shell_append(GTK_MENU_SHELL(tmpl_menu), mi);
1511
 
                    g_signal_connect(G_OBJECT(mi), "activate",
1512
 
                                     G_CALLBACK(xfdesktop_file_icon_template_item_activated),
1513
 
                                     fmanager);
1514
 
                    
1515
 
                    mi = gtk_separator_menu_item_new();
1516
 
                    gtk_widget_show(mi);
1517
 
                    gtk_menu_shell_append(GTK_MENU_SHELL(menu), mi);
1518
 
                }
1519
 
            } else {
1520
 
                if(xfdesktop_file_utils_file_is_executable(info)) {
1521
 
                    img = gtk_image_new_from_stock(GTK_STOCK_OPEN, GTK_ICON_SIZE_MENU);
1522
 
                    gtk_widget_show(img);
1523
 
                    mi = gtk_image_menu_item_new_with_mnemonic(_("_Execute"));
1524
 
                    gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(mi), img);
1525
 
                    gtk_widget_show(mi);
1526
 
                    gtk_menu_shell_append(GTK_MENU_SHELL(menu), mi);
1527
 
 
1528
 
                    g_signal_connect(G_OBJECT(mi), "activate",
1529
 
                                     G_CALLBACK(xfdesktop_file_icon_menu_executed),
1530
 
                                     fmanager);
1531
 
                    
1532
 
                    mi = gtk_separator_menu_item_new();
1533
 
                    gtk_widget_show(mi);
1534
 
                    gtk_menu_shell_append(GTK_MENU_SHELL(menu), mi);
1535
 
                    
1536
 
                    if(g_content_type_equals(g_file_info_get_content_type(info),
1537
 
                                             "application/x-desktop"))
1538
 
                    {
1539
 
                        GFile *file = xfdesktop_file_icon_peek_file(file_icon);
1540
 
 
1541
 
                        img = gtk_image_new_from_stock(GTK_STOCK_EDIT, GTK_ICON_SIZE_MENU);
1542
 
                        gtk_widget_show(img);
1543
 
                        mi = gtk_image_menu_item_new_with_mnemonic(_("_Edit Launcher"));
1544
 
                        gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(mi), img);
1545
 
                        g_object_set_data_full(G_OBJECT(mi), "file", 
1546
 
                                               g_object_ref(file), g_object_unref);
1547
 
                        gtk_widget_show(mi);
1548
 
                        gtk_menu_shell_append(GTK_MENU_SHELL(menu), mi);
1549
 
                        g_signal_connect(G_OBJECT(mi), "activate",
1550
 
                                         G_CALLBACK(xfdesktop_file_icon_menu_create_launcher),
1551
 
                                         fmanager);
1552
 
                    }
1553
 
                }
1554
 
                
1555
 
                app_infos = g_app_info_get_all_for_type(g_file_info_get_content_type(info));
1556
 
                if(app_infos) {
1557
 
                    GAppInfo *app_info = G_APP_INFO(app_infos->data);
1558
 
                    
1559
 
                    mi = xfdesktop_menu_item_from_app_info(fmanager, file_icon,
1560
 
                                                           app_info, TRUE, TRUE);
1561
 
                    gtk_menu_shell_append(GTK_MENU_SHELL(menu), mi);
1562
 
                    
1563
 
                    g_object_unref(app_info);
1564
 
 
1565
 
                    if(app_infos->next) {
1566
 
                        GtkWidget *app_infos_menu;
1567
 
                        gint list_len = g_list_length(app_infos->next);
1568
 
                        
1569
 
                        if(!xfdesktop_file_utils_file_is_executable(info)
1570
 
                           && list_len <= 3)
1571
 
                        {
1572
 
                            mi = gtk_separator_menu_item_new();
1573
 
                            gtk_widget_show(mi);
1574
 
                            gtk_menu_shell_append(GTK_MENU_SHELL(menu), mi);
1575
 
                        }
1576
 
                        
1577
 
                        if(list_len > 3) {
1578
 
                            mi = gtk_menu_item_new_with_label(_("Open With"));
1579
 
                            gtk_widget_show(mi);
1580
 
                            gtk_menu_shell_append(GTK_MENU_SHELL(menu), mi);
1581
 
                            
1582
 
                            app_infos_menu = gtk_menu_new();
1583
 
                            gtk_menu_item_set_submenu(GTK_MENU_ITEM(mi),
1584
 
                                                      app_infos_menu);
1585
 
                        } else
1586
 
                            app_infos_menu = (GtkWidget *)menu;
1587
 
                        
1588
 
                        for(l = app_infos->next; l; l = l->next) {
1589
 
                            app_info = G_APP_INFO(l->data);
1590
 
                            mi = xfdesktop_menu_item_from_app_info(fmanager,
1591
 
                                                                   file_icon, app_info,
1592
 
                                                                   FALSE, TRUE);
1593
 
                            gtk_menu_shell_append(GTK_MENU_SHELL(app_infos_menu), mi);
1594
 
                            g_object_unref(app_info);
1595
 
                        }
1596
 
                    }
1597
 
                    
1598
 
                    /* free the app info list */
1599
 
                    g_list_free(app_infos);
1600
 
                }
1601
 
                
1602
 
                img = gtk_image_new_from_stock(GTK_STOCK_OPEN, GTK_ICON_SIZE_MENU);
1603
 
                gtk_widget_show(img);
1604
 
                mi = gtk_image_menu_item_new_with_mnemonic(_("Open With Other _Application..."));
1605
 
                gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(mi), img);
1606
 
                gtk_widget_show(mi);
1607
 
                gtk_menu_shell_append(GTK_MENU_SHELL(menu), mi);
1608
 
                g_signal_connect(G_OBJECT(mi), "activate",
1609
 
                                 G_CALLBACK(xfdesktop_file_icon_menu_other_app),
1610
 
                                 fmanager);
1611
 
                
1612
 
                mi = gtk_separator_menu_item_new();
1613
 
                gtk_widget_show(mi);
1614
 
                gtk_menu_shell_append(GTK_MENU_SHELL(menu), mi);
1615
 
            }
1616
 
        }
1617
 
        
1618
 
#ifdef HAVE_THUNARX
1619
 
        if(!multi_sel && fmanager->priv->thunarx_menu_providers) {
1620
 
            GList *menu_actions = NULL;
1621
 
            ThunarxMenuProvider *provider;
1622
 
 
1623
 
            if(g_file_info_get_file_type(info) == G_FILE_TYPE_DIRECTORY) {
1624
 
                for(l = fmanager->priv->thunarx_menu_providers; l; l = l->next) {
1625
 
                    provider = THUNARX_MENU_PROVIDER(l->data);
1626
 
                    menu_actions = g_list_concat(menu_actions,
1627
 
                                                 thunarx_menu_provider_get_folder_actions(provider,
1628
 
                                                                                          toplevel,
1629
 
                                                                                          THUNARX_FILE_INFO(file_icon)));
1630
 
                }
1631
 
            } else {
1632
 
                for(l = fmanager->priv->thunarx_menu_providers; l; l = l->next) {
1633
 
                    provider = THUNARX_MENU_PROVIDER(l->data);
1634
 
                    menu_actions = g_list_concat(menu_actions,
1635
 
                                                 thunarx_menu_provider_get_file_actions(provider,
1636
 
                                                                                        toplevel,
1637
 
                                                                                        selected));
1638
 
                }
1639
 
            }
1640
 
            
1641
 
            if(menu_actions) {
1642
 
                xfdesktop_menu_shell_append_action_list(GTK_MENU_SHELL(menu),
1643
 
                                                        menu_actions);
1644
 
                g_list_foreach(menu_actions, (GFunc)g_object_unref, NULL);
1645
 
                g_list_free(menu_actions);
1646
 
                
1647
 
                mi = gtk_separator_menu_item_new();
1648
 
                gtk_widget_show(mi);
1649
 
                gtk_menu_shell_append(GTK_MENU_SHELL(menu), mi);
1650
 
            }
1651
 
        }
1652
 
#endif
1653
 
        
1654
 
        if(file_icon == fmanager->priv->desktop_icon) {
1655
 
            mi = gtk_image_menu_item_new_from_stock(GTK_STOCK_PASTE, NULL);
1656
 
            gtk_widget_show(mi);
1657
 
            gtk_menu_shell_append(GTK_MENU_SHELL(menu), mi);
1658
 
            if(xfdesktop_clipboard_manager_get_can_paste(clipboard_manager)) {
1659
 
                g_signal_connect(G_OBJECT(mi), "activate",
1660
 
                                 G_CALLBACK(xfdesktop_file_icon_menu_paste),
1661
 
                                 fmanager);
1662
 
            } else
1663
 
            gtk_widget_set_sensitive(mi, FALSE);
1664
 
        } else {
1665
 
            mi = gtk_image_menu_item_new_from_stock(GTK_STOCK_COPY, NULL);
1666
 
            gtk_widget_show(mi);
1667
 
            gtk_menu_shell_append(GTK_MENU_SHELL(menu), mi);
1668
 
            g_signal_connect(G_OBJECT(mi), "activate",
1669
 
                             G_CALLBACK(xfdesktop_file_icon_menu_copy),
1670
 
                             fmanager);
1671
 
            
1672
 
            mi = gtk_image_menu_item_new_from_stock(GTK_STOCK_CUT, NULL);
1673
 
            gtk_widget_show(mi);
1674
 
            gtk_menu_shell_append(GTK_MENU_SHELL(menu), mi);
1675
 
            if(multi_sel || xfdesktop_file_icon_can_delete_file(file_icon)) {
1676
 
                g_signal_connect(G_OBJECT(mi), "activate",
1677
 
                                 G_CALLBACK(xfdesktop_file_icon_menu_cut),
1678
 
                                 fmanager);
1679
 
            } else
1680
 
                gtk_widget_set_sensitive(mi, FALSE);
1681
 
            
1682
 
            mi = gtk_image_menu_item_new_from_stock(GTK_STOCK_DELETE, NULL);
1683
 
            gtk_widget_show(mi);
1684
 
            gtk_menu_shell_append(GTK_MENU_SHELL(menu), mi);
1685
 
            if(multi_sel || xfdesktop_file_icon_can_delete_file(file_icon)) {
1686
 
                g_signal_connect(G_OBJECT(mi), "activate",
1687
 
                                 G_CALLBACK(xfdesktop_file_icon_menu_delete), 
1688
 
                                 fmanager);
1689
 
            } else
1690
 
                gtk_widget_set_sensitive(mi, FALSE);
1691
 
            
1692
 
            mi = gtk_separator_menu_item_new();
1693
 
            gtk_widget_show(mi);
1694
 
            gtk_menu_shell_append(GTK_MENU_SHELL(menu), mi);
1695
 
            
1696
 
            mi = gtk_image_menu_item_new_with_mnemonic(_("_Rename..."));
1697
 
            gtk_widget_show(mi);
1698
 
            gtk_menu_shell_append(GTK_MENU_SHELL(menu), mi);
1699
 
            if(!multi_sel && xfdesktop_file_icon_can_rename_file(file_icon)) {
1700
 
                g_signal_connect(G_OBJECT(mi), "activate",
1701
 
                                 G_CALLBACK(xfdesktop_file_icon_menu_rename),
1702
 
                                 fmanager);
1703
 
            } else
1704
 
                gtk_widget_set_sensitive(mi, FALSE);
1705
 
        }
1706
 
        
1707
 
        mi = gtk_separator_menu_item_new();
1708
 
        gtk_widget_show(mi);
1709
 
        gtk_menu_shell_append(GTK_MENU_SHELL(menu), mi);
1710
 
        
1711
 
        if(file_icon == fmanager->priv->desktop_icon) {
1712
 
            img = gtk_image_new_from_stock(GTK_STOCK_PREFERENCES, GTK_ICON_SIZE_MENU);
1713
 
            gtk_widget_show(img);
1714
 
            mi = gtk_image_menu_item_new_with_mnemonic(_("Desktop _Settings..."));
1715
 
            gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(mi), img);
1716
 
            gtk_widget_show(mi);
1717
 
            gtk_menu_shell_append(GTK_MENU_SHELL(menu), mi);
1718
 
            g_signal_connect(G_OBJECT(mi), "activate",
1719
 
                             G_CALLBACK(xfdesktop_settings_launch), fmanager);
1720
 
        }
1721
 
        
1722
 
        img = gtk_image_new_from_stock(GTK_STOCK_PROPERTIES, GTK_ICON_SIZE_MENU);
1723
 
        gtk_widget_show(img);
1724
 
        mi = gtk_image_menu_item_new_with_mnemonic(_("_Properties..."));
1725
 
        gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(mi), img);
1726
 
        gtk_widget_show(mi);
1727
 
        gtk_menu_shell_append(GTK_MENU_SHELL(menu), mi);
1728
 
        if(multi_sel || !info)
1729
 
            gtk_widget_set_sensitive(mi, FALSE);
1730
 
        else {
1731
 
            g_signal_connect(G_OBJECT(mi), "activate",
1732
 
                             file_icon == fmanager->priv->desktop_icon
1733
 
                             ? G_CALLBACK(xfdesktop_file_icon_manager_desktop_properties)
1734
 
                             : G_CALLBACK(xfdesktop_file_icon_menu_properties),
1735
 
                             fmanager);
1736
 
        }
1737
 
    }
1738
 
    
1739
 
    /* don't free |selected|.  the menu deactivated handler does that */
1740
 
}
1741
 
 
1742
 
static void
1743
 
file_icon_hash_write_icons(gpointer key,
1744
 
                           gpointer value,
1745
 
                           gpointer data)
1746
 
{
1747
 
    XfceRc *rcfile = data;
1748
 
    XfdesktopIcon *icon = value;
1749
 
    guint16 row, col;
1750
 
    
1751
 
    if(xfdesktop_icon_get_position(icon, &row, &col)) {
1752
 
        xfce_rc_set_group(rcfile, xfdesktop_icon_peek_label(icon));
1753
 
        xfce_rc_write_int_entry(rcfile, "row", row);
1754
 
        xfce_rc_write_int_entry(rcfile, "col", col);
1755
 
    }
1756
 
}
1757
 
 
1758
 
static gboolean
1759
 
xfdesktop_file_icon_manager_save_icons(gpointer user_data)
1760
 
{
1761
 
    XfdesktopFileIconManager *fmanager = XFDESKTOP_FILE_ICON_MANAGER(user_data);
1762
 
    gchar relpath[PATH_MAX], *tmppath, *path;
1763
 
    XfceRc *rcfile;
1764
 
    
1765
 
    fmanager->priv->save_icons_id = 0;
1766
 
    
1767
 
    g_snprintf(relpath, PATH_MAX, "xfce4/desktop/icons.screen%d.rc",
1768
 
               gdk_screen_get_number(fmanager->priv->gscreen));
1769
 
    path = xfce_resource_save_location(XFCE_RESOURCE_CONFIG, relpath, TRUE);
1770
 
    if(!path)
1771
 
        return FALSE;
1772
 
    
1773
 
    tmppath = g_strconcat(path, ".new", NULL);
1774
 
    
1775
 
    rcfile = xfce_rc_simple_open(tmppath, FALSE);
1776
 
    if(!rcfile) {
1777
 
        g_warning("Unable to determine location of icon position cache file.  " \
1778
 
                  "Icon positions will not be saved.");
1779
 
        g_free(path);
1780
 
        g_free(tmppath);
1781
 
        return FALSE;
1782
 
    }
1783
 
    
1784
 
    g_hash_table_foreach(fmanager->priv->icons,
1785
 
                         file_icon_hash_write_icons, rcfile);
1786
 
    if(fmanager->priv->show_removable_media) {
1787
 
        g_hash_table_foreach(fmanager->priv->removable_icons,
1788
 
                             file_icon_hash_write_icons, rcfile);
1789
 
    }
1790
 
    g_hash_table_foreach(fmanager->priv->special_icons,
1791
 
                         file_icon_hash_write_icons, rcfile);
1792
 
    
1793
 
    xfce_rc_flush(rcfile);
1794
 
    xfce_rc_close(rcfile);
1795
 
    
1796
 
    if(rename(tmppath, path)) {
1797
 
        g_warning("Unable to rename temp file to %s: %s", path,
1798
 
                  strerror(errno));
1799
 
        unlink(tmppath);
1800
 
    }
1801
 
    
1802
 
    g_free(path);
1803
 
    g_free(tmppath);
1804
 
    
1805
 
    return FALSE;
1806
 
}
1807
 
 
1808
 
static void
1809
 
xfdesktop_file_icon_position_changed(XfdesktopFileIcon *icon,
1810
 
                                     gpointer user_data)
1811
 
{
1812
 
    XfdesktopFileIconManager *fmanager = XFDESKTOP_FILE_ICON_MANAGER(user_data);
1813
 
    
1814
 
    if(fmanager->priv->save_icons_id)
1815
 
        g_source_remove(fmanager->priv->save_icons_id);
1816
 
    
1817
 
    fmanager->priv->save_icons_id = g_timeout_add(SAVE_DELAY,
1818
 
                                                  xfdesktop_file_icon_manager_save_icons,
1819
 
                                                  fmanager);
1820
 
}
1821
 
 
1822
 
 
1823
 
/*   *****   */
1824
 
 
1825
 
static gboolean
1826
 
xfdesktop_file_icon_manager_get_cached_icon_position(XfdesktopFileIconManager *fmanager,
1827
 
                                                     const gchar *name,
1828
 
                                                     gint16 *row,
1829
 
                                                     gint16 *col)
1830
 
{
1831
 
    gchar relpath[PATH_MAX];
1832
 
    XfceRc *rcfile;
1833
 
    gboolean ret = FALSE;
1834
 
    
1835
 
    g_snprintf(relpath, PATH_MAX, "xfce4/desktop/icons.screen%d.rc",
1836
 
               gdk_screen_get_number(fmanager->priv->gscreen));
1837
 
    rcfile = xfce_rc_config_open(XFCE_RESOURCE_CONFIG, relpath, TRUE);
1838
 
    if(rcfile) {
1839
 
        if(xfce_rc_has_group(rcfile, name)) {
1840
 
            xfce_rc_set_group(rcfile, name);
1841
 
            *row = xfce_rc_read_int_entry(rcfile, "row", -1);
1842
 
            *col = xfce_rc_read_int_entry(rcfile, "col", -1);
1843
 
            if(*row >= 0 && *col >= 0)
1844
 
                ret = TRUE;
1845
 
        }
1846
 
        xfce_rc_close(rcfile);
1847
 
    }
1848
 
    
1849
 
    return ret;
1850
 
}
1851
 
 
1852
 
 
1853
 
#if defined(DEBUG) && DEBUG > 0
1854
 
static GList *_alive_icon_list = NULL;
1855
 
 
1856
 
static void
1857
 
_icon_notify_destroy(gpointer data,
1858
 
                     GObject *obj)
1859
 
{
1860
 
    g_assert(g_list_find(_alive_icon_list, obj));
1861
 
    _alive_icon_list = g_list_remove(_alive_icon_list, obj);
1862
 
    
1863
 
    DBG("icon finalized: '%s'", xfdesktop_icon_peek_label(XFDESKTOP_ICON(obj)));
1864
 
}
1865
 
#endif
1866
 
 
1867
 
static gboolean
1868
 
xfdesktop_file_icon_manager_add_icon(XfdesktopFileIconManager *fmanager,
1869
 
                                     XfdesktopFileIcon *icon,
1870
 
                                     gboolean defer_if_missing)
1871
 
{
1872
 
    gint16 row = -1, col = -1;
1873
 
    gboolean do_add = FALSE;
1874
 
    const gchar *name;
1875
 
    GFile *file;
1876
 
 
1877
 
    file = xfdesktop_file_icon_peek_file(icon);
1878
 
 
1879
 
    if(fmanager->priv->show_thumbnails && g_file_get_path(file) != NULL) {
1880
 
        xfdesktop_thumbnailer_queue_thumbnail(fmanager->priv->thumbnailer,
1881
 
                                              g_file_get_path(file));
1882
 
    }
1883
 
 
1884
 
    
1885
 
    name = xfdesktop_icon_peek_label(XFDESKTOP_ICON(icon));
1886
 
    if(xfdesktop_file_icon_manager_get_cached_icon_position(fmanager, name,
1887
 
                                                            &row, &col))
1888
 
    {
1889
 
        DBG("attempting to set icon '%s' to position (%d,%d)", name, row, col);
1890
 
        xfdesktop_icon_set_position(XFDESKTOP_ICON(icon), row, col);
1891
 
        do_add = TRUE;
1892
 
    } else {
1893
 
        if(defer_if_missing) {
1894
 
            fmanager->priv->deferred_icons = g_list_prepend(fmanager->priv->deferred_icons,
1895
 
                                                            g_object_ref(file));
1896
 
        } else
1897
 
            do_add = TRUE;
1898
 
    }
1899
 
    
1900
 
    if(do_add) {
1901
 
        g_signal_connect(G_OBJECT(icon), "position-changed",
1902
 
                         G_CALLBACK(xfdesktop_file_icon_position_changed),
1903
 
                         fmanager);
1904
 
        xfdesktop_icon_view_add_item(fmanager->priv->icon_view,
1905
 
                                     XFDESKTOP_ICON(icon));
1906
 
    }
1907
 
    
1908
 
#if defined(DEBUG) && DEBUG > 0
1909
 
    if(do_add) {
1910
 
        _alive_icon_list = g_list_prepend(_alive_icon_list, icon);
1911
 
        g_object_weak_ref(G_OBJECT(icon), _icon_notify_destroy, NULL);
1912
 
    }
1913
 
#endif
1914
 
    
1915
 
    return do_add;
1916
 
}
1917
 
 
1918
 
static XfdesktopFileIcon *
1919
 
xfdesktop_file_icon_manager_add_regular_icon(XfdesktopFileIconManager *fmanager,
1920
 
                                             GFile *file,
1921
 
                                             GFileInfo *info,
1922
 
                                             gboolean defer_if_missing)
1923
 
{
1924
 
    XfdesktopRegularFileIcon *icon = NULL;
1925
 
    gboolean is_desktop_file = FALSE;
1926
 
    
1927
 
    g_return_val_if_fail(fmanager && G_IS_FILE(file) && G_IS_FILE_INFO(info), NULL);
1928
 
 
1929
 
    if(g_content_type_equals(g_file_info_get_content_type(info), 
1930
 
                             "application/x-desktop")) 
1931
 
    {
1932
 
        is_desktop_file = TRUE;
1933
 
    }
1934
 
    else
1935
 
    {
1936
 
      gchar *uri = g_file_get_uri(file);
1937
 
      if(g_str_has_suffix(uri, ".desktop"))
1938
 
          is_desktop_file = TRUE;
1939
 
      g_free(uri);
1940
 
    }
1941
 
 
1942
 
    /* if it's a .desktop file, and it has Hidden=true, or an
1943
 
     * OnlyShowIn Or NotShowIn that would hide it from Xfce, don't
1944
 
     * show it on the desktop (bug #4022) */
1945
 
    if(is_desktop_file)
1946
 
    {
1947
 
        gchar *path = g_file_get_path(file);
1948
 
        XfceRc *rcfile = xfce_rc_simple_open(path, TRUE);
1949
 
        g_free(path);
1950
 
 
1951
 
        if(rcfile) {
1952
 
            const gchar *value;
1953
 
 
1954
 
            xfce_rc_set_group(rcfile, "Desktop Entry");
1955
 
            if(xfce_rc_read_bool_entry(rcfile, "Hidden", FALSE)) {
1956
 
                xfce_rc_close(rcfile);
1957
 
                return NULL;
1958
 
            }
1959
 
 
1960
 
            value = xfce_rc_read_entry(rcfile, "OnlyShowIn", NULL);
1961
 
            if(value && strncmp(value, "XFCE;", 5) && !strstr(value, ";XFCE;")) {
1962
 
                xfce_rc_close(rcfile);
1963
 
                return NULL;
1964
 
            }
1965
 
 
1966
 
            value = xfce_rc_read_entry(rcfile, "NotShowIn", NULL);
1967
 
            if(value && (!strncmp(value, "XFCE;", 5) || strstr(value, ";XFCE;"))) {
1968
 
                xfce_rc_close(rcfile);
1969
 
                return NULL;
1970
 
            }
1971
 
 
1972
 
            xfce_rc_close(rcfile);
1973
 
        }
1974
 
    }
1975
 
    
1976
 
    /* should never return NULL */
1977
 
    icon = xfdesktop_regular_file_icon_new(file, info, fmanager->priv->gscreen);
1978
 
    
1979
 
    if(xfdesktop_file_icon_manager_add_icon(fmanager,
1980
 
                                             XFDESKTOP_FILE_ICON(icon),
1981
 
                                             defer_if_missing))
1982
 
    {
1983
 
        g_hash_table_replace(fmanager->priv->icons, g_object_ref(file), icon);
1984
 
        return XFDESKTOP_FILE_ICON(icon);
1985
 
    } else {
1986
 
        g_object_unref(G_OBJECT(icon));
1987
 
        return NULL;
1988
 
    }
1989
 
}
1990
 
 
1991
 
static XfdesktopFileIcon *
1992
 
xfdesktop_file_icon_manager_add_volume_icon(XfdesktopFileIconManager *fmanager,
1993
 
                                            GVolume *volume)
1994
 
{
1995
 
    XfdesktopVolumeIcon *icon;
1996
 
    
1997
 
    g_return_val_if_fail(fmanager && G_IS_VOLUME(volume), NULL);
1998
 
    
1999
 
    /* should never return NULL */
2000
 
    icon = xfdesktop_volume_icon_new(volume, fmanager->priv->gscreen);
2001
 
    
2002
 
    if(xfdesktop_file_icon_manager_add_icon(fmanager,
2003
 
                                            XFDESKTOP_FILE_ICON(icon),
2004
 
                                            FALSE))
2005
 
    {
2006
 
        g_hash_table_replace(fmanager->priv->removable_icons,
2007
 
                             g_object_ref(G_OBJECT(volume)), icon);
2008
 
        return XFDESKTOP_FILE_ICON(icon);
2009
 
    } else {
2010
 
        g_object_unref(G_OBJECT(icon));
2011
 
        return NULL;
2012
 
    }
2013
 
}
2014
 
 
2015
 
static XfdesktopFileIcon *
2016
 
xfdesktop_file_icon_manager_add_special_file_icon(XfdesktopFileIconManager *fmanager,
2017
 
                                                  XfdesktopSpecialFileIconType type)
2018
 
{
2019
 
    XfdesktopSpecialFileIcon *icon;
2020
 
    
2021
 
    /* can return NULL if it's the trash icon and dbus isn't around */
2022
 
    icon = xfdesktop_special_file_icon_new(type, fmanager->priv->gscreen);
2023
 
    if(!icon)
2024
 
        return NULL;
2025
 
    
2026
 
    if(xfdesktop_file_icon_manager_add_icon(fmanager,
2027
 
                                            XFDESKTOP_FILE_ICON(icon),
2028
 
                                            FALSE))
2029
 
    {
2030
 
        g_hash_table_replace(fmanager->priv->special_icons,
2031
 
                             GINT_TO_POINTER(type), icon);
2032
 
        return XFDESKTOP_FILE_ICON(icon);
2033
 
    } else {
2034
 
        g_object_unref(G_OBJECT(icon));
2035
 
        return NULL;
2036
 
    }
2037
 
}
2038
 
 
2039
 
static gboolean
2040
 
xfdesktop_remove_icons_ht(gpointer key,
2041
 
                          gpointer value,
2042
 
                          gpointer user_data)
2043
 
{
2044
 
    xfdesktop_icon_view_remove_item(XFDESKTOP_ICON_VIEW(user_data),
2045
 
                                    XFDESKTOP_ICON(value));
2046
 
    return TRUE;
2047
 
}
2048
 
 
2049
 
static void
2050
 
xfdesktop_file_icon_manager_refresh_icons(XfdesktopFileIconManager *fmanager)
2051
 
{
2052
 
    gint i;
2053
 
    
2054
 
    /* if a save is pending, flush icon positions */
2055
 
    if(fmanager->priv->save_icons_id) {
2056
 
        g_source_remove(fmanager->priv->save_icons_id);
2057
 
        fmanager->priv->save_icons_id = 0;
2058
 
        xfdesktop_file_icon_manager_save_icons(fmanager);
2059
 
    }
2060
 
    
2061
 
    /* ditch removable media */
2062
 
    if(fmanager->priv->show_removable_media)
2063
 
        xfdesktop_file_icon_manager_remove_removable_media(fmanager);
2064
 
    
2065
 
    /* ditch special icons */
2066
 
    for(i = 0; i <= XFDESKTOP_SPECIAL_FILE_ICON_TRASH; ++i) {
2067
 
        XfdesktopIcon *icon = g_hash_table_lookup(fmanager->priv->special_icons,
2068
 
                                                  GINT_TO_POINTER(i));
2069
 
        if(icon) {
2070
 
            xfdesktop_icon_view_remove_item(fmanager->priv->icon_view, icon);
2071
 
            g_hash_table_remove(fmanager->priv->special_icons,
2072
 
                                GINT_TO_POINTER(i));
2073
 
        }
2074
 
    }
2075
 
 
2076
 
    /* ditch normal icons */
2077
 
    if(fmanager->priv->icons) {
2078
 
        g_hash_table_foreach_remove(fmanager->priv->icons,
2079
 
                                    (GHRFunc)xfdesktop_remove_icons_ht,
2080
 
                                    fmanager->priv->icon_view);
2081
 
    }
2082
 
    
2083
 
#if defined(DEBUG) && DEBUG > 0
2084
 
    g_assert(_xfdesktop_icon_view_n_items(fmanager->priv->icon_view) == 0);
2085
 
    g_assert(g_list_length(_alive_icon_list) == 0);
2086
 
#endif
2087
 
    
2088
 
    /* clear out anything left in the icon view */
2089
 
    xfdesktop_icon_view_remove_all(fmanager->priv->icon_view);
2090
 
    
2091
 
    /* add back the special icons */
2092
 
    for(i = 0; i <= XFDESKTOP_SPECIAL_FILE_ICON_TRASH; ++i) {
2093
 
        if(fmanager->priv->show_special[i])
2094
 
            xfdesktop_file_icon_manager_add_special_file_icon(fmanager, i);
2095
 
    }
2096
 
    
2097
 
    /* add back removable media */
2098
 
    if(fmanager->priv->show_removable_media)
2099
 
        xfdesktop_file_icon_manager_load_removable_media(fmanager);
2100
 
 
2101
 
    /* reload and add ~/Desktop/ */
2102
 
    xfdesktop_file_icon_manager_load_desktop_folder(fmanager);
2103
 
}
2104
 
 
2105
 
static gboolean
2106
 
xfdesktop_file_icon_manager_key_press(GtkWidget *widget,
2107
 
                                      GdkEventKey *evt,
2108
 
                                      gpointer user_data)
2109
 
{
2110
 
    XfdesktopFileIconManager *fmanager = XFDESKTOP_FILE_ICON_MANAGER(user_data);
2111
 
    GList *selected;
2112
 
    gboolean force_delete = FALSE;
2113
 
    
2114
 
    switch(evt->keyval) {
2115
 
        case GDK_Delete:
2116
 
        case GDK_KP_Delete:
2117
 
            if(evt->state & GDK_SHIFT_MASK)
2118
 
                force_delete = TRUE;
2119
 
            xfdesktop_file_icon_manager_delete_selected(fmanager, force_delete);
2120
 
            break;
2121
 
        
2122
 
        case GDK_c:
2123
 
        case GDK_C:
2124
 
            if(!(evt->state & GDK_CONTROL_MASK)
2125
 
               || (evt->state & (GDK_SHIFT_MASK|GDK_MOD1_MASK|GDK_MOD4_MASK)))
2126
 
            {
2127
 
                return FALSE;
2128
 
            }
2129
 
            selected = xfdesktop_icon_view_get_selected_items(fmanager->priv->icon_view);
2130
 
            if(selected) {
2131
 
                xfdesktop_clipboard_manager_copy_files(clipboard_manager,
2132
 
                                                       selected);
2133
 
                g_list_free(selected);
2134
 
            }
2135
 
            break;
2136
 
        
2137
 
        case GDK_x:
2138
 
        case GDK_X:
2139
 
            if(!(evt->state & GDK_CONTROL_MASK)
2140
 
               || (evt->state & (GDK_SHIFT_MASK|GDK_MOD1_MASK|GDK_MOD4_MASK)))
2141
 
            {
2142
 
                return FALSE;
2143
 
            }
2144
 
            selected = xfdesktop_icon_view_get_selected_items(fmanager->priv->icon_view);
2145
 
            if(selected) {
2146
 
                xfdesktop_clipboard_manager_cut_files(clipboard_manager,
2147
 
                                                       selected);
2148
 
                g_list_free(selected);
2149
 
            }
2150
 
            return TRUE;
2151
 
        
2152
 
        case GDK_v:
2153
 
        case GDK_V:
2154
 
            if(!(evt->state & GDK_CONTROL_MASK)
2155
 
               || (evt->state & (GDK_SHIFT_MASK|GDK_MOD1_MASK|GDK_MOD4_MASK)))
2156
 
            {
2157
 
                return FALSE;
2158
 
            }
2159
 
            if(xfdesktop_clipboard_manager_get_can_paste(clipboard_manager)) {
2160
 
                xfdesktop_clipboard_manager_paste_files(clipboard_manager, fmanager->priv->folder, widget, NULL);
2161
 
            }
2162
 
            return TRUE;
2163
 
 
2164
 
        case GDK_r:
2165
 
        case GDK_R:
2166
 
            if(!(evt->state & GDK_CONTROL_MASK)
2167
 
               || (evt->state & (GDK_SHIFT_MASK|GDK_MOD1_MASK|GDK_MOD4_MASK)))
2168
 
            {
2169
 
                return FALSE;
2170
 
            }
2171
 
            /* fall through */
2172
 
        case GDK_F5:
2173
 
            xfdesktop_file_icon_manager_refresh_icons(fmanager);
2174
 
            return TRUE;
2175
 
        
2176
 
        case GDK_F2:
2177
 
            selected = xfdesktop_icon_view_get_selected_items(fmanager->priv->icon_view);
2178
 
            if(g_list_length(selected) == 1) {
2179
 
                XfdesktopFileIcon *icon = XFDESKTOP_FILE_ICON(selected->data);
2180
 
                if(xfdesktop_file_icon_can_rename_file(icon)) {
2181
 
                    xfdesktop_file_icon_menu_rename(NULL, fmanager);
2182
 
                    return TRUE;
2183
 
                }
2184
 
            }
2185
 
            if(selected)
2186
 
                g_list_free(selected);
2187
 
            break; 
2188
 
    }
2189
 
    
2190
 
    return FALSE;
2191
 
}
2192
 
 
2193
 
static void
2194
 
xfdesktop_file_icon_manager_file_changed(GFileMonitor     *monitor,
2195
 
                                         GFile            *file,
2196
 
                                         GFile            *other_file,
2197
 
                                         GFileMonitorEvent event,
2198
 
                                         gpointer          user_data)
2199
 
{
2200
 
    XfdesktopFileIconManager *fmanager = XFDESKTOP_FILE_ICON_MANAGER(user_data);
2201
 
    XfdesktopFileIcon *icon;
2202
 
    GFileInfo *file_info;
2203
 
 
2204
 
    switch(event) {
2205
 
        case G_FILE_MONITOR_EVENT_CHANGED:
2206
 
            DBG("got changed event: %s", g_file_get_path(file));
2207
 
            
2208
 
            icon = g_hash_table_lookup(fmanager->priv->icons, file);
2209
 
            if(icon) {
2210
 
                file_info = g_file_query_info(file, XFDESKTOP_FILE_INFO_NAMESPACE,
2211
 
                                              G_FILE_QUERY_INFO_NONE, NULL, NULL);
2212
 
                
2213
 
                if(file_info) {
2214
 
                    /* update the icon if the file still exists */
2215
 
                    xfdesktop_file_icon_update_file_info(icon, file_info);
2216
 
                    g_object_unref(file_info);
2217
 
                } else {
2218
 
                    /* remove the icon as the file no longer seems to be existing */
2219
 
                    xfdesktop_icon_view_remove_item(fmanager->priv->icon_view,
2220
 
                                                    XFDESKTOP_ICON(icon));
2221
 
                    g_hash_table_remove(fmanager->priv->icons, file);
2222
 
                }
2223
 
            }
2224
 
            break;
2225
 
        case G_FILE_MONITOR_EVENT_CREATED:
2226
 
            DBG("got created event");
2227
 
 
2228
 
            /* make sure it's not the desktop folder itself */
2229
 
            if(g_file_equal(fmanager->priv->folder, file))
2230
 
                return;
2231
 
 
2232
 
            /* first make sure we don't already have an icon for this path.
2233
 
             * this seems to be necessary to avoid inconsistencies */
2234
 
            icon = g_hash_table_lookup(fmanager->priv->icons, file);
2235
 
            if(icon) {
2236
 
                xfdesktop_icon_view_remove_item(fmanager->priv->icon_view,
2237
 
                                                XFDESKTOP_ICON(icon));
2238
 
                g_hash_table_remove(fmanager->priv->icons, file);
2239
 
            }
2240
 
            
2241
 
            file_info = g_file_query_info(file, XFDESKTOP_FILE_INFO_NAMESPACE,
2242
 
                                          G_FILE_QUERY_INFO_NONE, NULL, NULL);
2243
 
            if(file_info) {
2244
 
                gboolean is_hidden = g_file_info_get_attribute_boolean(file_info,
2245
 
                                                                       G_FILE_ATTRIBUTE_STANDARD_IS_HIDDEN);
2246
 
                if(!is_hidden) {
2247
 
                    xfdesktop_file_icon_manager_add_regular_icon(fmanager,
2248
 
                                                                 file, file_info, 
2249
 
                                                                 FALSE);
2250
 
                }
2251
 
 
2252
 
                g_object_unref(file_info);
2253
 
            }
2254
 
 
2255
 
            break;
2256
 
        case G_FILE_MONITOR_EVENT_DELETED:
2257
 
            DBG("got deleted event");
2258
 
 
2259
 
            icon = g_hash_table_lookup(fmanager->priv->icons, file);
2260
 
            if(icon) {
2261
 
                /* Always try to remove thumbnail so it doesn't take up
2262
 
                 * space on the user's disk.
2263
 
                 */
2264
 
                xfdesktop_thumbnailer_delete_thumbnail(fmanager->priv->thumbnailer,
2265
 
                                                       g_file_get_path(file));
2266
 
                xfdesktop_icon_delete_thumbnail(XFDESKTOP_ICON(icon));
2267
 
 
2268
 
                xfdesktop_icon_view_remove_item(fmanager->priv->icon_view,
2269
 
                                                XFDESKTOP_ICON(icon));
2270
 
                g_hash_table_remove(fmanager->priv->icons, file);
2271
 
            } else {
2272
 
                if(g_file_equal(file, fmanager->priv->folder)) {
2273
 
                    DBG("~/Desktop disappeared!");
2274
 
                    /* yes, refresh before and after is correct */
2275
 
                    xfdesktop_file_icon_manager_refresh_icons(fmanager);
2276
 
                    xfdesktop_file_icon_manager_check_create_desktop_folder(fmanager->priv->folder);
2277
 
                    xfdesktop_file_icon_manager_refresh_icons(fmanager);
2278
 
                }
2279
 
            }
2280
 
            break;
2281
 
        default:
2282
 
            break;
2283
 
    }
2284
 
}
2285
 
 
2286
 
static void
2287
 
xfdesktop_file_icon_manager_files_ready(GFileEnumerator *enumerator,
2288
 
                                        GAsyncResult *result,
2289
 
                                        gpointer user_data)
2290
 
{
2291
 
    XfdesktopFileIconManager *fmanager = XFDESKTOP_FILE_ICON_MANAGER(user_data);
2292
 
    GError *error = NULL;
2293
 
    GList *files, *l;
2294
 
    gboolean is_hidden;
2295
 
 
2296
 
    g_return_if_fail(enumerator == fmanager->priv->enumerator);
2297
 
 
2298
 
    files = g_file_enumerator_next_files_finish(enumerator, result, &error);
2299
 
 
2300
 
    if(!files) {
2301
 
        if(error) {
2302
 
            GtkWidget *toplevel = gtk_widget_get_toplevel(GTK_WIDGET(fmanager->priv->icon_view));
2303
 
#if GTK_CHECK_VERSION (2, 18, 0)
2304
 
            xfce_message_dialog(gtk_widget_is_toplevel(toplevel) ? GTK_WINDOW(toplevel) : NULL,
2305
 
#else
2306
 
            xfce_message_dialog(GTK_WIDGET_TOPLEVEL(toplevel) ? GTK_WINDOW(toplevel) : NULL,
2307
 
#endif
2308
 
                                _("Load Error"),
2309
 
                                GTK_STOCK_DIALOG_WARNING, 
2310
 
                                _("Failed to load the desktop folder"), error->message,
2311
 
                                GTK_STOCK_CLOSE, GTK_RESPONSE_ACCEPT, NULL);
2312
 
        }
2313
 
 
2314
 
        g_object_unref(fmanager->priv->enumerator);
2315
 
        fmanager->priv->enumerator = NULL;
2316
 
 
2317
 
        if(fmanager->priv->deferred_icons) {
2318
 
            for(l = fmanager->priv->deferred_icons; l; l = l->next) {
2319
 
                GFile *file = G_FILE(l->data);
2320
 
                GFileInfo *info = g_file_query_info(file, 
2321
 
                                                    XFDESKTOP_FILE_INFO_NAMESPACE,
2322
 
                                                    G_FILE_QUERY_INFO_NONE, 
2323
 
                                                    NULL, NULL);
2324
 
 
2325
 
                xfdesktop_file_icon_manager_add_regular_icon(fmanager, 
2326
 
                                                             file, info, 
2327
 
                                                             FALSE);
2328
 
                g_object_unref(info);
2329
 
                g_object_unref(file);
2330
 
            }
2331
 
            g_list_free(fmanager->priv->deferred_icons);
2332
 
            fmanager->priv->deferred_icons = NULL;
2333
 
        }
2334
 
 
2335
 
 
2336
 
        if(!fmanager->priv->monitor) {
2337
 
            fmanager->priv->monitor = g_file_monitor(fmanager->priv->folder,
2338
 
                                                     G_FILE_MONITOR_NONE,
2339
 
                                                     NULL, NULL);
2340
 
            g_signal_connect(fmanager->priv->monitor, "changed",
2341
 
                             G_CALLBACK(xfdesktop_file_icon_manager_file_changed),
2342
 
                             fmanager);
2343
 
        }
2344
 
    } else {
2345
 
        for(l = files; l; l = l->next) {
2346
 
            DBG("got a GFileInfo: %s", g_file_info_get_display_name(l->data));
2347
 
            
2348
 
            is_hidden = g_file_info_get_attribute_boolean(l->data,
2349
 
                                                          G_FILE_ATTRIBUTE_STANDARD_IS_HIDDEN);
2350
 
            if(!is_hidden) {
2351
 
                const gchar *name = g_file_info_get_name(l->data);
2352
 
                GFile *file = g_file_get_child(fmanager->priv->folder, name);
2353
 
 
2354
 
                xfdesktop_file_icon_manager_add_regular_icon(fmanager, 
2355
 
                                                             file, l->data,
2356
 
                                                             TRUE);
2357
 
 
2358
 
                g_object_unref(file);
2359
 
            }
2360
 
 
2361
 
            g_object_unref(l->data);
2362
 
        }
2363
 
 
2364
 
        g_list_free(files);
2365
 
 
2366
 
        g_file_enumerator_next_files_async(fmanager->priv->enumerator,
2367
 
                                           10, G_PRIORITY_DEFAULT, NULL,
2368
 
                                           (GAsyncReadyCallback) xfdesktop_file_icon_manager_files_ready,
2369
 
                                           fmanager);
2370
 
    }
2371
 
}
2372
 
 
2373
 
static void
2374
 
xfdesktop_file_icon_manager_load_desktop_folder(XfdesktopFileIconManager *fmanager)
2375
 
{
2376
 
    if(fmanager->priv->deferred_icons) {
2377
 
        g_list_foreach(fmanager->priv->deferred_icons, (GFunc)g_object_unref, NULL);
2378
 
        g_list_free(fmanager->priv->deferred_icons);
2379
 
        fmanager->priv->deferred_icons = NULL;
2380
 
    }
2381
 
    
2382
 
    if(fmanager->priv->enumerator) {
2383
 
        g_object_unref(fmanager->priv->enumerator);
2384
 
        fmanager->priv->enumerator = NULL;
2385
 
    }
2386
 
 
2387
 
    fmanager->priv->enumerator = g_file_enumerate_children(fmanager->priv->folder,
2388
 
                                                           XFDESKTOP_FILE_INFO_NAMESPACE,
2389
 
                                                           G_FILE_QUERY_INFO_NONE,
2390
 
                                                           NULL, NULL);
2391
 
 
2392
 
    if(fmanager->priv->enumerator) {
2393
 
        g_file_enumerator_next_files_async(fmanager->priv->enumerator,
2394
 
                                           10, G_PRIORITY_DEFAULT, NULL,
2395
 
                                           (GAsyncReadyCallback) xfdesktop_file_icon_manager_files_ready,
2396
 
                                           fmanager);
2397
 
 
2398
 
    }
2399
 
}
2400
 
 
2401
 
static void
2402
 
xfdesktop_file_icon_manager_check_icons_opacity(gpointer key,
2403
 
                                                gpointer value,
2404
 
                                                gpointer data)
2405
 
{
2406
 
    XfdesktopRegularFileIcon *icon = XFDESKTOP_REGULAR_FILE_ICON(value);
2407
 
    XfdesktopClipboardManager *cmanager = XFDESKTOP_CLIPBOARD_MANAGER(data);
2408
 
    
2409
 
    if(G_UNLIKELY(xfdesktop_clipboard_manager_has_cutted_file(cmanager, XFDESKTOP_FILE_ICON(icon))))
2410
 
        xfdesktop_regular_file_icon_set_pixbuf_opacity(icon, 50);
2411
 
    else
2412
 
        xfdesktop_regular_file_icon_set_pixbuf_opacity(icon, 100);
2413
 
}
2414
 
 
2415
 
static void
2416
 
xfdesktop_file_icon_manager_clipboard_changed(XfdesktopClipboardManager *cmanager,
2417
 
                                              gpointer user_data)
2418
 
{
2419
 
    XfdesktopFileIconManager *fmanager = XFDESKTOP_FILE_ICON_MANAGER(user_data);
2420
 
    
2421
 
    TRACE("entering");
2422
 
    
2423
 
    /* slooow? */
2424
 
    g_hash_table_foreach(fmanager->priv->icons,
2425
 
                         xfdesktop_file_icon_manager_check_icons_opacity,
2426
 
                         cmanager);
2427
 
}
2428
 
 
2429
 
 
2430
 
static void
2431
 
xfdesktop_file_icon_manager_volume_changed(GVolume *volume,
2432
 
                                           gpointer user_data)
2433
 
{
2434
 
    XfdesktopFileIconManager *fmanager = XFDESKTOP_FILE_ICON_MANAGER(user_data);
2435
 
    XfdesktopIcon *icon;
2436
 
    gboolean is_present = xfdesktop_file_utils_volume_is_present(volume);
2437
 
    
2438
 
    icon = g_hash_table_lookup(fmanager->priv->removable_icons, volume);
2439
 
 
2440
 
    if(is_present && !icon)
2441
 
        xfdesktop_file_icon_manager_add_volume_icon(fmanager, volume);
2442
 
    else if(!is_present && icon) {
2443
 
        xfdesktop_icon_view_remove_item(fmanager->priv->icon_view, icon);
2444
 
        g_hash_table_remove(fmanager->priv->removable_icons, volume);
2445
 
    }
2446
 
}
2447
 
 
2448
 
static void
2449
 
xfdesktop_file_icon_manager_add_removable_volume(XfdesktopFileIconManager *fmanager,
2450
 
                                                 GVolume *volume)
2451
 
{
2452
 
    if(!xfdesktop_file_utils_volume_is_removable(volume))
2453
 
        return;
2454
 
    
2455
 
    if(xfdesktop_file_utils_volume_is_present(volume))
2456
 
        xfdesktop_file_icon_manager_add_volume_icon(fmanager, volume);
2457
 
    
2458
 
    g_signal_connect(G_OBJECT(volume), "changed",
2459
 
                     G_CALLBACK(xfdesktop_file_icon_manager_volume_changed),
2460
 
                     fmanager);
2461
 
}
2462
 
 
2463
 
static void
2464
 
xfdesktop_file_icon_manager_volume_added(GVolumeMonitor *monitor,
2465
 
                                         GVolume *volume,
2466
 
                                         gpointer user_data)
2467
 
{
2468
 
    XfdesktopFileIconManager *fmanager = XFDESKTOP_FILE_ICON_MANAGER(user_data);
2469
 
 
2470
 
    xfdesktop_file_icon_manager_add_removable_volume(fmanager, volume);
2471
 
}
2472
 
 
2473
 
static void
2474
 
xfdesktop_file_icon_manager_volume_removed(GVolumeMonitor *monitor,
2475
 
                                           GVolume *volume,
2476
 
                                           gpointer user_data)
2477
 
{
2478
 
    XfdesktopFileIconManager *fmanager = XFDESKTOP_FILE_ICON_MANAGER(user_data);
2479
 
    XfdesktopIcon *icon;
2480
 
    
2481
 
    icon = g_hash_table_lookup(fmanager->priv->removable_icons, volume);
2482
 
    if(icon) {
2483
 
        xfdesktop_icon_view_remove_item(fmanager->priv->icon_view, icon);
2484
 
        g_hash_table_remove(fmanager->priv->removable_icons, volume);
2485
 
    }
2486
 
}
2487
 
 
2488
 
static void
2489
 
xfdesktop_file_icon_manager_load_removable_media(XfdesktopFileIconManager *fmanager)
2490
 
{
2491
 
    GList *volumes, *l;
2492
 
    
2493
 
    /* ensure we don't re-enter if we're already set up */
2494
 
    if(fmanager->priv->removable_icons)
2495
 
        return;
2496
 
    
2497
 
    if(!fmanager->priv->volume_monitor) {
2498
 
        fmanager->priv->volume_monitor = g_volume_monitor_get();
2499
 
        g_object_add_weak_pointer(G_OBJECT(fmanager->priv->volume_monitor),
2500
 
                                  (gpointer)&fmanager->priv->volume_monitor);
2501
 
    } else
2502
 
       g_object_ref(G_OBJECT(fmanager->priv->volume_monitor));
2503
 
    
2504
 
    fmanager->priv->removable_icons = g_hash_table_new_full(g_direct_hash,
2505
 
                                                            g_direct_equal,
2506
 
                                                            (GDestroyNotify)g_object_unref,
2507
 
                                                            (GDestroyNotify)g_object_unref);
2508
 
    
2509
 
    volumes = g_volume_monitor_get_volumes(fmanager->priv->volume_monitor);
2510
 
    for(l = volumes; l; l = l->next) {
2511
 
        xfdesktop_file_icon_manager_add_removable_volume(fmanager, l->data);
2512
 
        g_object_unref(l->data);
2513
 
    }
2514
 
    g_list_free(volumes);
2515
 
    
2516
 
    g_signal_connect(G_OBJECT(fmanager->priv->volume_monitor), "volume-added",
2517
 
                     G_CALLBACK(xfdesktop_file_icon_manager_volume_added),
2518
 
                     fmanager);
2519
 
    g_signal_connect(G_OBJECT(fmanager->priv->volume_monitor), "volume-removed",
2520
 
                     G_CALLBACK(xfdesktop_file_icon_manager_volume_removed),
2521
 
                     fmanager);
2522
 
}
2523
 
 
2524
 
static void
2525
 
xfdesktop_file_icon_manager_ht_remove_removable_media(gpointer key,
2526
 
                                                      gpointer value,
2527
 
                                                      gpointer user_data)
2528
 
{
2529
 
    XfdesktopIcon *icon = XFDESKTOP_ICON(value);
2530
 
    XfdesktopFileIconManager *fmanager = XFDESKTOP_FILE_ICON_MANAGER(user_data);
2531
 
    GVolume *volume;
2532
 
 
2533
 
    volume = xfdesktop_volume_icon_peek_volume(XFDESKTOP_VOLUME_ICON(icon));
2534
 
    if(volume) {
2535
 
        g_signal_handlers_disconnect_by_func(volume,
2536
 
                                             G_CALLBACK(xfdesktop_file_icon_manager_volume_changed),
2537
 
                                             fmanager);
2538
 
    }
2539
 
    
2540
 
    xfdesktop_icon_view_remove_item(fmanager->priv->icon_view, icon);
2541
 
}
2542
 
 
2543
 
static void
2544
 
xfdesktop_file_icon_manager_remove_removable_media(XfdesktopFileIconManager *fmanager)
2545
 
{
2546
 
    if(fmanager->priv->removable_icons) {
2547
 
        g_hash_table_foreach(fmanager->priv->removable_icons,
2548
 
                             xfdesktop_file_icon_manager_ht_remove_removable_media,
2549
 
                             fmanager);
2550
 
        g_hash_table_destroy(fmanager->priv->removable_icons);
2551
 
        fmanager->priv->removable_icons = NULL;
2552
 
    }
2553
 
    
2554
 
    if(fmanager->priv->volume_monitor) {
2555
 
        g_signal_handlers_disconnect_by_func(G_OBJECT(fmanager->priv->volume_monitor),
2556
 
                                             G_CALLBACK(xfdesktop_file_icon_manager_volume_added),
2557
 
                                             fmanager);
2558
 
        g_signal_handlers_disconnect_by_func(G_OBJECT(fmanager->priv->volume_monitor),
2559
 
                                             G_CALLBACK(xfdesktop_file_icon_manager_volume_removed),
2560
 
                                             fmanager);
2561
 
    
2562
 
        g_object_unref(fmanager->priv->volume_monitor);
2563
 
    }
2564
 
}
2565
 
 
2566
 
 
2567
 
/* virtual functions */
2568
 
 
2569
 
static gboolean
2570
 
xfdesktop_file_icon_manager_real_init(XfdesktopIconViewManager *manager,
2571
 
                                      XfdesktopIconView *icon_view)
2572
 
{
2573
 
    XfdesktopFileIconManager *fmanager = XFDESKTOP_FILE_ICON_MANAGER(manager);
2574
 
    GFileInfo *desktop_info;
2575
 
    gint i;
2576
 
#ifdef HAVE_THUNARX
2577
 
    ThunarxProviderFactory *thunarx_pfac;
2578
 
#endif
2579
 
 
2580
 
    if(fmanager->priv->inited) {
2581
 
        g_warning("Initializing icon manager when already inited");
2582
 
        return FALSE;
2583
 
    }
2584
 
 
2585
 
    fmanager->priv->icon_view = icon_view;
2586
 
    
2587
 
    fmanager->priv->desktop = gtk_widget_get_toplevel(GTK_WIDGET(icon_view));
2588
 
    g_signal_connect(G_OBJECT(fmanager->priv->desktop), "populate-root-menu",
2589
 
                     G_CALLBACK(xfdesktop_file_icon_manager_populate_context_menu),
2590
 
                     fmanager);
2591
 
    
2592
 
    fmanager->priv->gscreen = gtk_widget_get_screen(GTK_WIDGET(icon_view));
2593
 
    
2594
 
    /* FIXME: remove for 4.4.0 */
2595
 
    __migrate_old_icon_positions(fmanager);
2596
 
    
2597
 
    if(!clipboard_manager) {
2598
 
        GdkDisplay *gdpy = gdk_screen_get_display(fmanager->priv->gscreen);
2599
 
        clipboard_manager = xfdesktop_clipboard_manager_get_for_display(gdpy);
2600
 
        g_object_add_weak_pointer(G_OBJECT(clipboard_manager),
2601
 
                                  (gpointer)&clipboard_manager);
2602
 
    } else
2603
 
        g_object_ref(G_OBJECT(clipboard_manager));
2604
 
    
2605
 
    g_signal_connect(G_OBJECT(clipboard_manager), "changed",
2606
 
                     G_CALLBACK(xfdesktop_file_icon_manager_clipboard_changed),
2607
 
                     fmanager);
2608
 
    
2609
 
    xfdesktop_icon_view_set_selection_mode(icon_view, GTK_SELECTION_MULTIPLE);
2610
 
    xfdesktop_icon_view_enable_drag_source(icon_view,
2611
 
                                           GDK_SHIFT_MASK | GDK_CONTROL_MASK,
2612
 
                                           drag_targets, n_drag_targets,
2613
 
                                           GDK_ACTION_LINK | GDK_ACTION_COPY
2614
 
                                           | GDK_ACTION_MOVE);
2615
 
    xfdesktop_icon_view_enable_drag_dest(icon_view, drop_targets,
2616
 
                                         n_drop_targets, GDK_ACTION_LINK
2617
 
                                         | GDK_ACTION_COPY | GDK_ACTION_MOVE);
2618
 
    
2619
 
    g_signal_connect(G_OBJECT(xfdesktop_icon_view_get_window_widget(icon_view)),
2620
 
                     "key-press-event",
2621
 
                     G_CALLBACK(xfdesktop_file_icon_manager_key_press),
2622
 
                     fmanager);
2623
 
    
2624
 
    fmanager->priv->icons = g_hash_table_new_full((GHashFunc)g_file_hash,
2625
 
                                                  (GEqualFunc)g_file_equal,
2626
 
                                                  (GDestroyNotify)g_object_unref,
2627
 
                                                  (GDestroyNotify)g_object_unref);
2628
 
    
2629
 
    fmanager->priv->special_icons = g_hash_table_new_full(g_direct_hash,
2630
 
                                                          g_direct_equal,
2631
 
                                                          NULL,
2632
 
                                                          (GDestroyNotify)g_object_unref);
2633
 
    
2634
 
    if(!xfdesktop_file_utils_dbus_init())
2635
 
        g_warning("Unable to initialise D-Bus.  Some xfdesktop features may be unavailable.");
2636
 
    
2637
 
    /* do this in the reverse order stuff should be displayed */
2638
 
    xfdesktop_file_icon_manager_load_desktop_folder(fmanager);
2639
 
    if(fmanager->priv->show_removable_media)
2640
 
        xfdesktop_file_icon_manager_load_removable_media(fmanager);
2641
 
    for(i = XFDESKTOP_SPECIAL_FILE_ICON_TRASH; i >= 0; --i) {
2642
 
        if(fmanager->priv->show_special[i])
2643
 
            xfdesktop_file_icon_manager_add_special_file_icon(fmanager, i);
2644
 
    }
2645
 
    
2646
 
#ifdef HAVE_THUNARX
2647
 
    thunarx_pfac = thunarx_provider_factory_get_default();
2648
 
    
2649
 
    fmanager->priv->thunarx_menu_providers =
2650
 
        thunarx_provider_factory_list_providers(thunarx_pfac,
2651
 
                                                THUNARX_TYPE_MENU_PROVIDER);
2652
 
    fmanager->priv->thunarx_properties_providers =
2653
 
        thunarx_provider_factory_list_providers(thunarx_pfac,
2654
 
                                                THUNARX_TYPE_PROPERTY_PAGE_PROVIDER);
2655
 
    
2656
 
    g_object_unref(G_OBJECT(thunarx_pfac));    
2657
 
#endif
2658
 
    
2659
 
    desktop_info = g_file_query_info(fmanager->priv->folder,
2660
 
                                     XFDESKTOP_FILE_INFO_NAMESPACE,
2661
 
                                     G_FILE_QUERY_INFO_NONE,
2662
 
                                     NULL, NULL);
2663
 
 
2664
 
    fmanager->priv->desktop_icon = XFDESKTOP_FILE_ICON(xfdesktop_regular_file_icon_new(fmanager->priv->folder,
2665
 
                                                                                       desktop_info,
2666
 
                                                                                       fmanager->priv->gscreen));
2667
 
    
2668
 
    g_object_unref(desktop_info);
2669
 
 
2670
 
    fmanager->priv->inited = TRUE;
2671
 
    
2672
 
    return TRUE;
2673
 
}
2674
 
 
2675
 
static void
2676
 
xfdesktop_file_icon_manager_fini(XfdesktopIconViewManager *manager)
2677
 
{
2678
 
    XfdesktopFileIconManager *fmanager = XFDESKTOP_FILE_ICON_MANAGER(manager);
2679
 
    gint i;
2680
 
 
2681
 
    if(!fmanager->priv->inited) {
2682
 
        g_warning("Trying to de-init icon manager when it was never inited");
2683
 
        return;
2684
 
    }
2685
 
 
2686
 
    fmanager->priv->inited = FALSE;
2687
 
    
2688
 
    if(fmanager->priv->enumerator) {
2689
 
        g_object_unref(fmanager->priv->enumerator);
2690
 
        fmanager->priv->enumerator = NULL;
2691
 
    }
2692
 
    
2693
 
    g_signal_handlers_disconnect_by_func(G_OBJECT(fmanager->priv->desktop),
2694
 
                                         G_CALLBACK(xfdesktop_file_icon_manager_populate_context_menu),
2695
 
                                         fmanager);
2696
 
    
2697
 
    if(fmanager->priv->save_icons_id) {
2698
 
        g_source_remove(fmanager->priv->save_icons_id);
2699
 
        fmanager->priv->save_icons_id = 0;
2700
 
        xfdesktop_file_icon_manager_save_icons(fmanager);
2701
 
    }
2702
 
    
2703
 
    g_signal_handlers_disconnect_by_func(G_OBJECT(clipboard_manager),
2704
 
                                         G_CALLBACK(xfdesktop_file_icon_manager_clipboard_changed),
2705
 
                                         fmanager);
2706
 
    
2707
 
    g_object_unref(G_OBJECT(clipboard_manager));
2708
 
    
2709
 
    if(fmanager->priv->show_removable_media)
2710
 
        xfdesktop_file_icon_manager_remove_removable_media(fmanager);
2711
 
    
2712
 
    for(i = 0; i <= XFDESKTOP_SPECIAL_FILE_ICON_TRASH; ++i) {
2713
 
        XfdesktopIcon *icon = g_hash_table_lookup(fmanager->priv->special_icons,
2714
 
                                                  GINT_TO_POINTER(i));
2715
 
        if(icon) {
2716
 
            xfdesktop_icon_view_remove_item(fmanager->priv->icon_view, icon);
2717
 
            g_hash_table_remove(fmanager->priv->special_icons,
2718
 
                                GINT_TO_POINTER(i));
2719
 
        }
2720
 
    }
2721
 
 
2722
 
    if(fmanager->priv->icons) {
2723
 
        g_hash_table_foreach_remove(fmanager->priv->icons,
2724
 
                                    (GHRFunc)xfdesktop_remove_icons_ht,
2725
 
                                    fmanager->priv->icon_view);
2726
 
    }
2727
 
    
2728
 
    if(fmanager->priv->deferred_icons) {
2729
 
        g_list_foreach(fmanager->priv->deferred_icons, (GFunc)g_object_unref, NULL);
2730
 
        g_list_free(fmanager->priv->deferred_icons);
2731
 
        fmanager->priv->deferred_icons = NULL;
2732
 
    }
2733
 
    
2734
 
    /* disconnect from the file monitor and release it */
2735
 
    g_signal_handlers_disconnect_by_func(fmanager->priv->monitor,
2736
 
                                         G_CALLBACK(xfdesktop_file_icon_manager_file_changed),
2737
 
                                         fmanager);
2738
 
    g_object_unref(fmanager->priv->monitor);
2739
 
    fmanager->priv->monitor = NULL;
2740
 
    
2741
 
    g_object_unref(G_OBJECT(fmanager->priv->desktop_icon));
2742
 
    fmanager->priv->desktop_icon = NULL;
2743
 
    
2744
 
#ifdef HAVE_THUNARX
2745
 
    g_list_foreach(fmanager->priv->thunarx_menu_providers,
2746
 
                   (GFunc)g_object_unref, NULL);
2747
 
    g_list_free(fmanager->priv->thunarx_menu_providers);
2748
 
    
2749
 
    g_list_foreach(fmanager->priv->thunarx_properties_providers,
2750
 
                   (GFunc)g_object_unref, NULL);
2751
 
    g_list_free(fmanager->priv->thunarx_properties_providers);
2752
 
#endif
2753
 
    
2754
 
    g_hash_table_destroy(fmanager->priv->special_icons);
2755
 
    fmanager->priv->special_icons = NULL;
2756
 
    
2757
 
    g_hash_table_destroy(fmanager->priv->icons);
2758
 
    fmanager->priv->icons = NULL;
2759
 
    
2760
 
    xfdesktop_file_utils_dbus_cleanup();
2761
 
    
2762
 
    g_signal_handlers_disconnect_by_func(G_OBJECT(xfdesktop_icon_view_get_window_widget(fmanager->priv->icon_view)),
2763
 
                                         G_CALLBACK(xfdesktop_file_icon_manager_key_press),
2764
 
                                         fmanager);
2765
 
    
2766
 
    xfdesktop_icon_view_unset_drag_source(fmanager->priv->icon_view);
2767
 
    xfdesktop_icon_view_unset_drag_dest(fmanager->priv->icon_view);
2768
 
}
2769
 
 
2770
 
static gboolean
2771
 
xfdesktop_file_icon_manager_drag_drop(XfdesktopIconViewManager *manager,
2772
 
                                      XfdesktopIcon *drop_icon,
2773
 
                                      GdkDragContext *context,
2774
 
                                      guint16 row,
2775
 
                                      guint16 col,
2776
 
                                      guint time_)
2777
 
{
2778
 
    XfdesktopFileIconManager *fmanager = XFDESKTOP_FILE_ICON_MANAGER(manager);
2779
 
    GtkWidget *widget = GTK_WIDGET(fmanager->priv->icon_view);
2780
 
    GdkAtom target;
2781
 
    
2782
 
    TRACE("entering");
2783
 
    
2784
 
    target = gtk_drag_dest_find_target(widget, context,
2785
 
                                       fmanager->priv->drop_targets);
2786
 
    if(target == GDK_NONE)
2787
 
        return FALSE;
2788
 
    else if(target == gdk_atom_intern("XdndDirectSave0", FALSE)) {
2789
 
        /* X direct save protocol implementation copied more or less from
2790
 
         * Thunar, Copyright (c) Benedikt Meurer */
2791
 
        gint prop_len;
2792
 
        guchar *prop_text = NULL;
2793
 
        GFile *source_file, *file;
2794
 
        gchar *uri = NULL;
2795
 
        
2796
 
        if(drop_icon) {
2797
 
            GFileInfo *info = xfdesktop_file_icon_peek_file_info(XFDESKTOP_FILE_ICON(drop_icon));
2798
 
            if(!info)
2799
 
                return FALSE;
2800
 
            
2801
 
            if(g_file_info_get_file_type(info) != G_FILE_TYPE_DIRECTORY)
2802
 
                return FALSE;
2803
 
            
2804
 
            source_file = xfdesktop_file_icon_peek_file(XFDESKTOP_FILE_ICON(drop_icon));
2805
 
            
2806
 
        } else
2807
 
            source_file = fmanager->priv->folder;
2808
 
        
2809
 
        if(gdk_property_get(context->source_window,
2810
 
                            gdk_atom_intern("XdndDirectSave0", FALSE),
2811
 
                            gdk_atom_intern("text/plain", FALSE),
2812
 
                            0, 1024, FALSE, NULL, NULL, &prop_len,
2813
 
                            &prop_text) && prop_text)
2814
 
        {
2815
 
            prop_text = g_realloc(prop_text, prop_len + 1);
2816
 
            prop_text[prop_len] = 0;
2817
 
 
2818
 
            file = g_file_resolve_relative_path(source_file, (const gchar *)prop_text);
2819
 
            uri = g_file_get_uri(file);
2820
 
            g_object_unref(file);
2821
 
            
2822
 
            gdk_property_change(context->source_window,
2823
 
                                gdk_atom_intern("XdndDirectSave0", FALSE),
2824
 
                                gdk_atom_intern("text/plain", FALSE), 8,
2825
 
                                GDK_PROP_MODE_REPLACE, (const guchar *)uri,
2826
 
                                strlen(uri));
2827
 
            
2828
 
            g_free(prop_text);
2829
 
            g_free(uri);
2830
 
        }
2831
 
        
2832
 
        if(!uri)
2833
 
            return FALSE;
2834
 
    } else if(target == gdk_atom_intern("_NETSCAPE_URL", FALSE)) {
2835
 
        if(drop_icon) {
2836
 
            /* don't allow a drop on an icon that isn't a folder (i.e., not
2837
 
             * on an icon that's an executable */
2838
 
            GFileInfo *info = xfdesktop_file_icon_peek_file_info(XFDESKTOP_FILE_ICON(drop_icon));
2839
 
            if(!info || g_file_info_get_file_type(info) != G_FILE_TYPE_DIRECTORY)
2840
 
                return FALSE;
2841
 
        }
2842
 
    }
2843
 
    
2844
 
    TRACE("target good");
2845
 
    
2846
 
    gtk_drag_get_data(widget, context, target, time_);
2847
 
    
2848
 
    return TRUE;
2849
 
}
2850
 
 
2851
 
static void xfdesktop_dnd_item(GtkWidget *item, GdkDragAction *action)
2852
 
{
2853
 
    *action = GPOINTER_TO_UINT(g_object_get_data(G_OBJECT(item), "action"));
2854
 
}
2855
 
 
2856
 
static void xfdesktop_dnd_item_cancel(GtkWidget *item, GdkDragAction *action)
2857
 
{
2858
 
    *action = 0;
2859
 
}
2860
 
 
2861
 
/**
2862
 
 * xfdesktop_dnd_menu:
2863
 
 * @manager     : the #XfdesktopIconViewManager instance
2864
 
 * @drop_icon   : the #XfdesktopIcon to which is being dropped.
2865
 
 * @context     : the #GdkDragContext of the icons being dropped.
2866
 
 * @row         : the row on the desktop to drop to.
2867
 
 * @col         : the col on the desktop to drop to.
2868
 
 * @ time_      : the starting time of the drag event.
2869
 
 * Pops up a menu that asks the user to choose one of the
2870
 
 * actions or to cancel the drop. Sets context->action to
2871
 
 * the new action the user selected or 0 on cancel.
2872
 
 * Portions of this code was copied from thunar-dnd.c
2873
 
 * Copyright (c) 2005-2006 Benedikt Meurer <benny@xfce.org>
2874
 
 * Copyright (c) 2009-2011 Jannis Pohlmann <jannis@xfce.org>
2875
 
 **/
2876
 
static void xfdesktop_dnd_menu (XfdesktopIconViewManager *manager,
2877
 
                                XfdesktopIcon *drop_icon,
2878
 
                                GdkDragContext *context,
2879
 
                                guint16 row,
2880
 
                                guint16 col,
2881
 
                                guint time_)
2882
 
{
2883
 
    static GdkDragAction    actions[] = { GDK_ACTION_COPY, GDK_ACTION_MOVE, GDK_ACTION_LINK };
2884
 
    static const gchar      *action_names[] = { N_ ("_Copy here") , N_ ("_Move here") , N_ ("_Link here") };
2885
 
    static const gchar      *action_icons[] = { "stock_folder-copy", "stock_folder-move", NULL };
2886
 
    GtkWidget *menu;
2887
 
    GtkWidget *item;
2888
 
    GtkWidget  *image;
2889
 
    guint menu_item, signal_id;
2890
 
    GMainLoop *loop;
2891
 
    gint response;
2892
 
    menu = gtk_menu_new();
2893
 
 
2894
 
    /* This adds the Copy, Move, & Link options */
2895
 
    for(menu_item = 0; menu_item < G_N_ELEMENTS(actions); menu_item++) {
2896
 
        item = gtk_image_menu_item_new_with_mnemonic(_(action_names[menu_item]));
2897
 
        gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
2898
 
        g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(xfdesktop_dnd_item), &response);
2899
 
        g_object_set_data(G_OBJECT(item), "action", GUINT_TO_POINTER(actions[menu_item]));
2900
 
        /* add image to the menu item */
2901
 
        if(G_LIKELY(action_icons[menu_item] != NULL)) {
2902
 
            image = gtk_image_new_from_icon_name(action_icons[menu_item], GTK_ICON_SIZE_MENU);
2903
 
            gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item), image);
2904
 
            gtk_widget_show(image);
2905
 
        }
2906
 
 
2907
 
        gtk_widget_show(item);
2908
 
    }
2909
 
 
2910
 
    /* Add a seperator */
2911
 
    item = gtk_separator_menu_item_new();
2912
 
    gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
2913
 
    gtk_widget_show(item);
2914
 
 
2915
 
    /* Cancel option */
2916
 
    item = gtk_image_menu_item_new_from_stock(GTK_STOCK_CANCEL, NULL);
2917
 
    gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
2918
 
    g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(xfdesktop_dnd_item_cancel), &response);
2919
 
    gtk_widget_show(item);
2920
 
 
2921
 
    gtk_widget_show(menu);
2922
 
    g_object_ref_sink(G_OBJECT(menu));
2923
 
 
2924
 
    /* Loop until we get a user response */
2925
 
    loop = g_main_loop_new(NULL, FALSE);
2926
 
    signal_id = g_signal_connect_swapped(G_OBJECT(menu), "deactivate", G_CALLBACK(g_main_loop_quit), loop);
2927
 
    gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, 3, time_);
2928
 
    g_main_loop_run(loop);
2929
 
    g_signal_handler_disconnect(G_OBJECT(menu), signal_id);
2930
 
    g_main_loop_unref(loop);
2931
 
 
2932
 
    context->action = response;
2933
 
 
2934
 
    g_object_unref(G_OBJECT(menu));
2935
 
}
2936
 
 
2937
 
static void
2938
 
xfdesktop_file_icon_manager_drag_data_received(XfdesktopIconViewManager *manager,
2939
 
                                               XfdesktopIcon *drop_icon,
2940
 
                                               GdkDragContext *context,
2941
 
                                               guint16 row,
2942
 
                                               guint16 col,
2943
 
                                               GtkSelectionData *data,
2944
 
                                               guint info,
2945
 
                                               guint time_)
2946
 
{
2947
 
    XfdesktopFileIconManager *fmanager = XFDESKTOP_FILE_ICON_MANAGER(manager);
2948
 
    XfdesktopFileIcon *file_icon = NULL;
2949
 
    GFileInfo *tinfo = NULL;
2950
 
    GFile *tfile = NULL;
2951
 
    gboolean copy_only = TRUE, drop_ok = FALSE;
2952
 
    GList *file_list;
2953
 
    gboolean user_selected_action = FALSE;
2954
 
 
2955
 
    TRACE("entering");
2956
 
 
2957
 
    if(context->action == GDK_ACTION_ASK) {
2958
 
        xfdesktop_dnd_menu(manager, drop_icon, context, row, col, time_);
2959
 
 
2960
 
        if(context->action == 0) {
2961
 
            gtk_drag_finish(context, FALSE, FALSE, time_);
2962
 
            return;
2963
 
        }
2964
 
        /* The user picked whether to move or copy the files */
2965
 
        user_selected_action = TRUE;
2966
 
    }
2967
 
 
2968
 
    if(info == TARGET_XDND_DIRECT_SAVE0) {
2969
 
        /* we don't suppose XdndDirectSave stage 3, result F, i.e., the app
2970
 
         * has to save the data itself given the filename we provided in
2971
 
         * stage 1 */
2972
 
        if(8 == data->format && 1 == data->length && 'F' == data->data[0]) {
2973
 
            gdk_property_change(context->source_window,
2974
 
                                gdk_atom_intern("XdndDirectSave0", FALSE),
2975
 
                                gdk_atom_intern("text/plain", FALSE), 8,
2976
 
                                GDK_PROP_MODE_REPLACE, (const guchar *)"", 0);
2977
 
        } else if(8 == data->format && data->length == 1
2978
 
                  && 'S' == data->data[0])
2979
 
        {
2980
 
            /* FIXME: do we really need to do anything here?  xfdesktop should
2981
 
             * detect when something changes on its own */
2982
 
        }
2983
 
        
2984
 
        drop_ok = TRUE;
2985
 
    } else if(info == TARGET_NETSCAPE_URL) {
2986
 
        /* data is "URL\nTITLE" */
2987
 
        GFile *source_file = NULL;
2988
 
        gchar *exo_desktop_item_edit = g_find_program_in_path("exo-desktop-item-edit");
2989
 
 
2990
 
        if(drop_icon) {
2991
 
            GFileInfo *finfo = xfdesktop_file_icon_peek_file_info(XFDESKTOP_FILE_ICON(drop_icon));
2992
 
            if(g_file_info_get_file_type(finfo) == G_FILE_TYPE_DIRECTORY)
2993
 
                source_file = xfdesktop_file_icon_peek_file(XFDESKTOP_FILE_ICON(drop_icon));
2994
 
        } else
2995
 
            source_file = fmanager->priv->folder;
2996
 
        
2997
 
        if(source_file && exo_desktop_item_edit) {
2998
 
            gchar **parts = g_strsplit((const gchar *)data->data, "\n", -1);
2999
 
            
3000
 
            if(2 == g_strv_length(parts)) {
3001
 
                gchar *cwd = g_file_get_uri(source_file);
3002
 
                gchar *myargv[16];
3003
 
                gint i = 0;
3004
 
                
3005
 
                /* use the argv form so we don't have to worry about quoting
3006
 
                 * the link title */
3007
 
                myargv[i++] = exo_desktop_item_edit;
3008
 
                myargv[i++] = "--type=Link";
3009
 
                myargv[i++] = "--url";
3010
 
                myargv[i++] = parts[0];
3011
 
                myargv[i++] = "--name";
3012
 
                myargv[i++] = parts[1];
3013
 
                myargv[i++] = "--create-new";
3014
 
                myargv[i++] = cwd;
3015
 
                myargv[i++] = NULL;
3016
 
                
3017
 
                if(xfce_spawn_on_screen(fmanager->priv->gscreen, NULL, myargv,
3018
 
                                        NULL, G_SPAWN_SEARCH_PATH, TRUE,
3019
 
                                        gtk_get_current_event_time(),
3020
 
                                        NULL, NULL))
3021
 
                {
3022
 
                    drop_ok = TRUE;
3023
 
                }
3024
 
                
3025
 
                g_free(cwd);
3026
 
            }
3027
 
            
3028
 
            g_strfreev(parts);
3029
 
        }
3030
 
        
3031
 
        g_free(exo_desktop_item_edit);
3032
 
    } else if(info == TARGET_TEXT_URI_LIST) {
3033
 
        if(drop_icon) {
3034
 
            file_icon = XFDESKTOP_FILE_ICON(drop_icon);
3035
 
            tfile = xfdesktop_file_icon_peek_file(file_icon);
3036
 
            tinfo = xfdesktop_file_icon_peek_file_info(file_icon);
3037
 
        }
3038
 
        
3039
 
        copy_only = (context->action == GDK_ACTION_COPY);
3040
 
        
3041
 
        if(tfile && g_file_has_uri_scheme(tfile, "trash") && copy_only) {
3042
 
            gtk_drag_finish(context, FALSE, FALSE, time_);
3043
 
            return;
3044
 
        }
3045
 
        
3046
 
        file_list = xfdesktop_file_utils_file_list_from_string((const gchar *)data->data);
3047
 
        if(file_list) {
3048
 
            GtkWidget *toplevel = gtk_widget_get_toplevel(GTK_WIDGET(fmanager->priv->icon_view));
3049
 
 
3050
 
            if(tinfo && xfdesktop_file_utils_file_is_executable(tinfo)) {
3051
 
                drop_ok = xfdesktop_file_utils_execute(fmanager->priv->folder,
3052
 
                                                       tfile, file_list,
3053
 
                                                       fmanager->priv->gscreen,
3054
 
                                                       GTK_WINDOW(toplevel));
3055
 
            } else if(tfile && g_file_has_uri_scheme(tfile, "trash")) {
3056
 
                /* move files to the trash */
3057
 
                xfdesktop_file_utils_trash_files(file_list,
3058
 
                                                 fmanager->priv->gscreen,
3059
 
                                                 GTK_WINDOW(toplevel));
3060
 
            } else {
3061
 
                GFile *base_dest_file = NULL;
3062
 
                GList *l, *dest_file_list = NULL;
3063
 
                gboolean dest_is_volume = (drop_icon
3064
 
                                           && XFDESKTOP_IS_VOLUME_ICON(drop_icon));
3065
 
                
3066
 
                /* if it's a volume, but we don't have |tinfo|, this just isn't
3067
 
                 * going to work */
3068
 
                if(!tinfo && dest_is_volume) {
3069
 
                    xfdesktop_file_utils_file_list_free(file_list);
3070
 
                    gtk_drag_finish(context, FALSE, FALSE, time_);
3071
 
                    return;
3072
 
                }
3073
 
 
3074
 
                if(tinfo && g_file_info_get_file_type(tinfo) == G_FILE_TYPE_DIRECTORY) {
3075
 
                    base_dest_file = g_object_ref(tfile);
3076
 
                } else {
3077
 
                    base_dest_file = g_object_ref(fmanager->priv->folder);
3078
 
                }
3079
 
 
3080
 
                /* If the user didn't pick whether to copy or move via
3081
 
                 * a GDK_ACTION_ASK then determine if we should move/copy
3082
 
                 * by checking if the files are on the same file system.
3083
 
                 */
3084
 
                if(user_selected_action == FALSE) {
3085
 
                    GFileInfo *src_info, *dest_info;
3086
 
                    const gchar *src_name, *dest_name;
3087
 
                    dest_info = g_file_query_info(base_dest_file,
3088
 
                                                  G_FILE_ATTRIBUTE_ID_FILESYSTEM,
3089
 
                                                  G_FILE_QUERY_INFO_NONE,
3090
 
                                                  NULL,
3091
 
                                                  NULL);
3092
 
                    src_info = g_file_query_info(file_list->data,
3093
 
                                                 G_FILE_ATTRIBUTE_ID_FILESYSTEM,
3094
 
                                                 G_FILE_QUERY_INFO_NONE,
3095
 
                                                 NULL,
3096
 
                                                 NULL);
3097
 
 
3098
 
                    if(dest_info != NULL && src_info != NULL) {
3099
 
                        dest_name = g_file_info_get_attribute_string(dest_info,
3100
 
                                                G_FILE_ATTRIBUTE_ID_FILESYSTEM);
3101
 
                        src_name = g_file_info_get_attribute_string(src_info,
3102
 
                                                G_FILE_ATTRIBUTE_ID_FILESYSTEM);
3103
 
 
3104
 
                        if(g_strcmp0(src_name, dest_name) == 0) {
3105
 
                            copy_only = FALSE;
3106
 
                            context->action = GDK_ACTION_MOVE;
3107
 
                        }
3108
 
                    }
3109
 
 
3110
 
                    if(dest_info != NULL)
3111
 
                        g_object_unref(dest_info);
3112
 
                    if(src_info != NULL)
3113
 
                        g_object_unref(src_info);
3114
 
                }
3115
 
 
3116
 
                for (l = file_list; l; l = l->next) {
3117
 
                    gchar *dest_basename = g_file_get_basename(l->data);
3118
 
 
3119
 
                    if(dest_basename && *dest_basename != '\0') {
3120
 
                        /* If we copy a file, we need to use the new absolute filename
3121
 
                         * as the destination. If we move or link, we need to use the destination
3122
 
                         * directory. */
3123
 
                        if(copy_only) {
3124
 
                            GFile *dest_file = g_file_get_child(base_dest_file, dest_basename);
3125
 
                            dest_file_list = g_list_prepend(dest_file_list, dest_file);
3126
 
                        } else {
3127
 
                            dest_file_list = g_list_prepend(dest_file_list, base_dest_file);
3128
 
                        }
3129
 
                    }
3130
 
 
3131
 
                    g_free(dest_basename);
3132
 
                }
3133
 
 
3134
 
                g_object_unref(base_dest_file);
3135
 
 
3136
 
                if(dest_file_list) {
3137
 
                    dest_file_list = g_list_reverse(dest_file_list);
3138
 
 
3139
 
                    drop_ok = xfdesktop_file_utils_transfer_files(context->action, 
3140
 
                                                                  file_list, 
3141
 
                                                                  dest_file_list,
3142
 
                                                                  fmanager->priv->gscreen);
3143
 
                }
3144
 
 
3145
 
                if(copy_only) {
3146
 
                    xfdesktop_file_utils_file_list_free(dest_file_list);
3147
 
                } else {
3148
 
                    g_list_free(dest_file_list);
3149
 
                }
3150
 
            }
3151
 
        }
3152
 
    }
3153
 
    
3154
 
    DBG("finishing drop on desktop from external source: drop_ok=%s, copy_only=%s",
3155
 
        drop_ok?"TRUE":"FALSE", copy_only?"TRUE":"FALSE");
3156
 
    
3157
 
    gtk_drag_finish(context, drop_ok, !copy_only, time_);
3158
 
}
3159
 
 
3160
 
static void
3161
 
xfdesktop_file_icon_manager_drag_data_get(XfdesktopIconViewManager *manager,
3162
 
                                          GList *drag_icons,
3163
 
                                          GdkDragContext *context,
3164
 
                                          GtkSelectionData *data,
3165
 
                                          guint info,
3166
 
                                          guint time_)
3167
 
{
3168
 
    GList *file_list;
3169
 
    gchar *str;
3170
 
    
3171
 
    TRACE("entering");
3172
 
    
3173
 
    g_return_if_fail(drag_icons);
3174
 
    g_return_if_fail(info == TARGET_TEXT_URI_LIST);
3175
 
    
3176
 
    file_list = xfdesktop_file_utils_file_icon_list_to_file_list(drag_icons);
3177
 
    str = xfdesktop_file_utils_file_list_to_string(file_list);
3178
 
 
3179
 
    gtk_selection_data_set(data, data->target, 8, (guchar *)str, strlen(str));
3180
 
    
3181
 
    g_free(str);
3182
 
    xfdesktop_file_utils_file_list_free(file_list);
3183
 
}
3184
 
 
3185
 
 
3186
 
/* public api */
3187
 
 
3188
 
XfdesktopIconViewManager *
3189
 
xfdesktop_file_icon_manager_new(GFile *folder,
3190
 
                                XfconfChannel *channel)
3191
 
{
3192
 
    XfdesktopFileIconManager *fmanager;
3193
 
    
3194
 
    g_return_val_if_fail(folder && channel, NULL);
3195
 
 
3196
 
    fmanager = g_object_new(XFDESKTOP_TYPE_FILE_ICON_MANAGER,
3197
 
                            "folder", folder,
3198
 
                            NULL);
3199
 
    fmanager->priv->channel = g_object_ref(G_OBJECT(channel));
3200
 
 
3201
 
    xfconf_g_property_bind(channel, SETTING_SHOW_FILESYSTEM, G_TYPE_BOOLEAN,
3202
 
                           G_OBJECT(fmanager), "show-filesystem");
3203
 
    xfconf_g_property_bind(channel, SETTING_SHOW_HOME, G_TYPE_BOOLEAN,
3204
 
                           G_OBJECT(fmanager), "show-home");
3205
 
    xfconf_g_property_bind(channel, SETTING_SHOW_TRASH, G_TYPE_BOOLEAN,
3206
 
                           G_OBJECT(fmanager), "show-trash");
3207
 
    xfconf_g_property_bind(channel, SETTING_SHOW_REMOVABLE, G_TYPE_BOOLEAN,
3208
 
                           G_OBJECT(fmanager), "show-removable");
3209
 
    xfconf_g_property_bind(channel, SETTING_SHOW_THUMBNAILS, G_TYPE_BOOLEAN,
3210
 
                           G_OBJECT(fmanager), "show-thumbnails");
3211
 
 
3212
 
    return XFDESKTOP_ICON_VIEW_MANAGER(fmanager);
3213
 
}
3214
 
 
3215
 
void
3216
 
xfdesktop_file_icon_manager_set_show_removable_media(XfdesktopFileIconManager *manager,
3217
 
                                                     gboolean show_removable_media)
3218
 
{
3219
 
    g_return_if_fail(XFDESKTOP_IS_FILE_ICON_MANAGER(manager));
3220
 
    
3221
 
    if(show_removable_media == manager->priv->show_removable_media)
3222
 
        return;
3223
 
    
3224
 
    manager->priv->show_removable_media = show_removable_media;
3225
 
    
3226
 
    if(!manager->priv->inited)
3227
 
        return;
3228
 
    
3229
 
    if(show_removable_media)
3230
 
        xfdesktop_file_icon_manager_load_removable_media(manager);
3231
 
    else
3232
 
        xfdesktop_file_icon_manager_remove_removable_media(manager);
3233
 
}
3234
 
 
3235
 
gboolean
3236
 
xfdesktop_file_icon_manager_get_show_removable_media(XfdesktopFileIconManager *manager)
3237
 
{
3238
 
    g_return_val_if_fail(XFDESKTOP_IS_FILE_ICON_MANAGER(manager), FALSE);
3239
 
    return manager->priv->show_removable_media;
3240
 
}
3241
 
 
3242
 
static void
3243
 
xfdesktop_file_icon_manager_requeue_thumbnails(gpointer key,
3244
 
                                               gpointer value,
3245
 
                                               gpointer data)
3246
 
{
3247
 
    GFile *file = key;
3248
 
    XfdesktopFileIconManager *fmanager = XFDESKTOP_FILE_ICON_MANAGER(data);
3249
 
 
3250
 
    xfdesktop_thumbnailer_queue_thumbnail(fmanager->priv->thumbnailer,
3251
 
                                          g_file_get_path(file));
3252
 
}
3253
 
 
3254
 
static void
3255
 
xfdesktop_file_icon_manager_remove_thumbnails(gpointer key,
3256
 
                                              gpointer value,
3257
 
                                              gpointer data)
3258
 
{
3259
 
    XfdesktopRegularFileIcon *icon = XFDESKTOP_REGULAR_FILE_ICON(value);
3260
 
 
3261
 
    xfdesktop_icon_delete_thumbnail(XFDESKTOP_ICON(icon));
3262
 
}
3263
 
 
3264
 
void
3265
 
xfdesktop_file_icon_manager_set_show_thumbnails(XfdesktopFileIconManager *manager,
3266
 
                                                gboolean show_thumbnails)
3267
 
{
3268
 
    g_return_if_fail(XFDESKTOP_IS_FILE_ICON_MANAGER(manager));
3269
 
 
3270
 
    if(show_thumbnails == manager->priv->show_thumbnails)
3271
 
        return;
3272
 
 
3273
 
    manager->priv->show_thumbnails = show_thumbnails;
3274
 
 
3275
 
    if(!manager->priv->inited)
3276
 
        return;
3277
 
 
3278
 
    if(show_thumbnails) {
3279
 
        /* We have to request to create the thumbnails everytime. */
3280
 
         g_hash_table_foreach(manager->priv->icons,
3281
 
                         xfdesktop_file_icon_manager_requeue_thumbnails,
3282
 
                         manager);
3283
 
    } else {
3284
 
        /* We have to remove the thumbnails because the regular file
3285
 
         * icons can't easily check if thumbnails are allowed.
3286
 
         */
3287
 
         g_hash_table_foreach(manager->priv->icons,
3288
 
                         xfdesktop_file_icon_manager_remove_thumbnails,
3289
 
                         manager);
3290
 
    }
3291
 
}
3292
 
 
3293
 
gboolean
3294
 
xfdesktop_file_icon_manager_get_show_thumbnails(XfdesktopFileIconManager *manager)
3295
 
{
3296
 
    g_return_val_if_fail(XFDESKTOP_IS_FILE_ICON_MANAGER(manager), FALSE);
3297
 
    return manager->priv->show_thumbnails;
3298
 
}
3299
 
 
3300
 
void
3301
 
xfdesktop_file_icon_manager_set_show_special_file(XfdesktopFileIconManager *manager,
3302
 
                                                  XfdesktopSpecialFileIconType type,
3303
 
                                                  gboolean show_special_file)
3304
 
{
3305
 
    g_return_if_fail(XFDESKTOP_IS_FILE_ICON_MANAGER(manager));
3306
 
    g_return_if_fail((int)type >= 0 && type <= XFDESKTOP_SPECIAL_FILE_ICON_TRASH);
3307
 
    
3308
 
    if(manager->priv->show_special[type] == show_special_file)
3309
 
        return;
3310
 
    
3311
 
    manager->priv->show_special[type] = show_special_file;
3312
 
    
3313
 
    if(!manager->priv->inited)
3314
 
        return;
3315
 
    
3316
 
    if(show_special_file) {
3317
 
        g_return_if_fail(!g_hash_table_lookup(manager->priv->special_icons,
3318
 
                                              GINT_TO_POINTER(type)));
3319
 
        xfdesktop_file_icon_manager_add_special_file_icon(manager, type);
3320
 
    } else {
3321
 
        XfdesktopIcon *icon = g_hash_table_lookup(manager->priv->special_icons,
3322
 
                                                  GINT_TO_POINTER(type));
3323
 
        if(icon) {
3324
 
            xfdesktop_icon_view_remove_item(manager->priv->icon_view, icon);
3325
 
            g_hash_table_remove(manager->priv->special_icons,
3326
 
                                GINT_TO_POINTER(type));
3327
 
        }
3328
 
    }
3329
 
}
3330
 
 
3331
 
gboolean
3332
 
xfdesktop_file_icon_manager_get_show_special_file(XfdesktopFileIconManager *manager,
3333
 
                                                  XfdesktopSpecialFileIconType type)
3334
 
{
3335
 
    g_return_val_if_fail(XFDESKTOP_IS_FILE_ICON_MANAGER(manager), FALSE);
3336
 
    g_return_val_if_fail((int)type >= 0 && type <= XFDESKTOP_SPECIAL_FILE_ICON_TRASH,
3337
 
                         FALSE);
3338
 
    
3339
 
    return manager->priv->show_special[type];
3340
 
}
3341
 
 
3342
 
static void
3343
 
xfdesktop_file_icon_manager_update_image(GtkWidget *widget,
3344
 
                                         gchar *srcfile,
3345
 
                                         gchar *thumbfile,
3346
 
                                         XfdesktopFileIconManager *manager)
3347
 
{
3348
 
    GFile *file;
3349
 
    XfdesktopIcon *icon;
3350
 
 
3351
 
    g_return_if_fail(srcfile && thumbfile);
3352
 
    g_return_if_fail(XFDESKTOP_FILE_ICON_MANAGER(manager));
3353
 
 
3354
 
    file = g_file_new_for_path(srcfile);
3355
 
 
3356
 
    icon = g_hash_table_lookup(manager->priv->icons, file);
3357
 
    if(icon)
3358
 
    {
3359
 
        g_object_unref(file);
3360
 
        file = g_file_new_for_path(thumbfile);
3361
 
        xfdesktop_icon_set_thumbnail_file(icon, file);
3362
 
    }
3363
 
}