2
* xfdesktop - xfce4's desktop manager
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>
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.
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.
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.
39
#ifdef HAVE_SYS_STAT_H
43
#ifdef HAVE_SYS_TYPES_H
44
#include <sys/types.h>
56
#include <gdk/gdkkeysyms.h>
59
#include <thunarx/thunarx.h>
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"
76
#include <libxfce4util/libxfce4util.h>
77
#include <libxfce4ui/libxfce4ui.h>
79
#define SAVE_DELAY 7000
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"
99
struct _XfdesktopFileIconManagerPrivate
103
XfconfChannel *channel;
106
XfdesktopIconView *icon_view;
111
XfdesktopFileIcon *desktop_icon;
112
GFileMonitor *monitor;
113
GFileEnumerator *enumerator;
115
GVolumeMonitor *volume_monitor;
118
GHashTable *removable_icons;
119
GHashTable *special_icons;
121
gboolean show_removable_media;
122
gboolean show_special[XFDESKTOP_SPECIAL_FILE_ICON_TRASH+1];
123
gboolean show_thumbnails;
127
GList *deferred_icons;
129
GtkTargetList *drag_targets;
130
GtkTargetList *drop_targets;
133
GList *thunarx_menu_providers;
134
GList *thunarx_properties_providers;
137
XfdesktopThumbnailer *thumbnailer;
140
static void xfdesktop_file_icon_manager_set_property(GObject *object,
144
static void xfdesktop_file_icon_manager_get_property(GObject *object,
148
static void xfdesktop_file_icon_manager_finalize(GObject *obj);
149
static void xfdesktop_file_icon_manager_icon_view_manager_init(XfdesktopIconViewManagerIface *iface);
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);
155
static gboolean xfdesktop_file_icon_manager_drag_drop(XfdesktopIconViewManager *manager,
156
XfdesktopIcon *drop_icon,
157
GdkDragContext *context,
161
static void xfdesktop_file_icon_manager_drag_data_received(XfdesktopIconViewManager *manager,
162
XfdesktopIcon *drop_icon,
163
GdkDragContext *context,
166
GtkSelectionData *data,
169
static void xfdesktop_file_icon_manager_drag_data_get(XfdesktopIconViewManager *manager,
171
GdkDragContext *context,
172
GtkSelectionData *data,
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);
181
static void xfdesktop_file_icon_position_changed(XfdesktopFileIcon *icon,
184
static void xfdesktop_file_icon_manager_update_image(GtkWidget *widget,
187
XfdesktopFileIconManager *fmanager);
189
G_DEFINE_TYPE_EXTENDED(XfdesktopFileIconManager,
190
xfdesktop_file_icon_manager,
192
G_IMPLEMENT_INTERFACE(XFDESKTOP_TYPE_ICON_VIEW_MANAGER,
193
xfdesktop_file_icon_manager_icon_view_manager_init))
198
XfdesktopFileIconManager *fmanager;
200
DBusGProxyCall *call;
202
} XfdesktopTrashFilesData;
206
TARGET_TEXT_URI_LIST = 0,
207
TARGET_XDND_DIRECT_SAVE0,
211
static const GtkTargetEntry drag_targets[] = {
212
{ "text/uri-list", 0, TARGET_TEXT_URI_LIST, },
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 },
220
static const gint n_drop_targets = (sizeof(drop_targets)/sizeof(drop_targets[0]));
222
static XfdesktopClipboardManager *clipboard_manager = NULL;
224
static GQuark xfdesktop_app_info_quark = 0;
228
xfdesktop_file_icon_manager_class_init(XfdesktopFileIconManagerClass *klass)
230
GObjectClass *gobject_class = (GObjectClass *)klass;
232
g_type_class_add_private(klass, sizeof(XfdesktopFileIconManagerPrivate));
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;
238
g_object_class_install_property(gobject_class, PROP_FOLDER,
239
g_param_spec_object("folder", "Desktop Folder",
240
"Folder this icon manager manages",
243
| G_PARAM_CONSTRUCT_ONLY
244
| G_PARAM_STATIC_NAME
245
| G_PARAM_STATIC_NICK
246
| G_PARAM_STATIC_BLURB));
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",
258
XFDESKTOP_PARAM_FLAGS));
259
g_object_class_install_property(gobject_class, PROP_SHOW_HOME,
260
g_param_spec_boolean("show-home",
264
XFDESKTOP_PARAM_FLAGS));
265
g_object_class_install_property(gobject_class, PROP_SHOW_TRASH,
266
g_param_spec_boolean("show-trash",
270
XFDESKTOP_PARAM_FLAGS));
271
g_object_class_install_property(gobject_class, PROP_SHOW_REMOVABLE,
272
g_param_spec_boolean("show-removable",
276
XFDESKTOP_PARAM_FLAGS));
277
g_object_class_install_property(gobject_class, PROP_SHOW_THUMBNAILS,
278
g_param_spec_boolean("show-thumbnails",
282
XFDESKTOP_PARAM_FLAGS));
283
#undef XFDESKTOP_PARAM_FLAGS
285
xfdesktop_app_info_quark = g_quark_from_static_string("xfdesktop-app-info-quark");
289
xfdesktop_file_icon_manager_init(XfdesktopFileIconManager *fmanager)
291
fmanager->priv = G_TYPE_INSTANCE_GET_PRIVATE(fmanager,
292
XFDESKTOP_TYPE_FILE_ICON_MANAGER,
293
XfdesktopFileIconManagerPrivate);
296
fmanager->priv->gscreen = gdk_screen_get_default();
297
fmanager->priv->drag_targets = gtk_target_list_new(drag_targets,
299
fmanager->priv->drop_targets = gtk_target_list_new(drop_targets,
302
fmanager->priv->thumbnailer = xfdesktop_thumbnailer_new();
304
g_signal_connect(G_OBJECT(fmanager->priv->thumbnailer), "thumbnail-ready", G_CALLBACK(xfdesktop_file_icon_manager_update_image), fmanager);
308
xfdesktop_file_icon_manager_set_property(GObject *object,
313
XfdesktopFileIconManager *fmanager = XFDESKTOP_FILE_ICON_MANAGER(object);
315
switch(property_id) {
317
fmanager->priv->folder = g_value_dup_object(value);
318
xfdesktop_file_icon_manager_check_create_desktop_folder(fmanager->priv->folder);
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));
328
xfdesktop_file_icon_manager_set_show_special_file(fmanager,
329
XFDESKTOP_SPECIAL_FILE_ICON_HOME,
330
g_value_get_boolean(value));
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));
339
case PROP_SHOW_REMOVABLE:
340
xfdesktop_file_icon_manager_set_show_removable_media(fmanager,
341
g_value_get_boolean(value));
344
case PROP_SHOW_THUMBNAILS:
345
xfdesktop_file_icon_manager_set_show_thumbnails(fmanager,
346
g_value_get_boolean(value));
350
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
355
xfdesktop_file_icon_manager_get_property(GObject *object,
360
XfdesktopFileIconManager *fmanager = XFDESKTOP_FILE_ICON_MANAGER(object);
362
switch(property_id) {
364
g_value_set_object(value, fmanager->priv->folder);
367
case PROP_SHOW_FILESYSTEM:
368
g_value_set_boolean(value,
369
fmanager->priv->show_special[XFDESKTOP_SPECIAL_FILE_ICON_FILESYSTEM]);
373
g_value_set_boolean(value,
374
fmanager->priv->show_special[XFDESKTOP_SPECIAL_FILE_ICON_HOME]);
377
case PROP_SHOW_TRASH:
378
g_value_set_boolean(value,
379
fmanager->priv->show_special[XFDESKTOP_SPECIAL_FILE_ICON_TRASH]);
382
case PROP_SHOW_REMOVABLE:
383
g_value_set_boolean(value, fmanager->priv->show_removable_media);
386
case PROP_SHOW_THUMBNAILS:
387
g_value_set_boolean(value, fmanager->priv->show_thumbnails);
391
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
396
xfdesktop_file_icon_manager_finalize(GObject *obj)
398
XfdesktopFileIconManager *fmanager = XFDESKTOP_FILE_ICON_MANAGER(obj);
400
if(fmanager->priv->inited)
401
xfdesktop_file_icon_manager_fini(XFDESKTOP_ICON_VIEW_MANAGER(fmanager));
403
g_object_unref(G_OBJECT(fmanager->priv->channel));
405
gtk_target_list_unref(fmanager->priv->drag_targets);
406
gtk_target_list_unref(fmanager->priv->drop_targets);
408
g_object_unref(fmanager->priv->folder);
409
g_object_unref(fmanager->priv->thumbnailer);
411
G_OBJECT_CLASS(xfdesktop_file_icon_manager_parent_class)->finalize(obj);
415
xfdesktop_file_icon_manager_icon_view_manager_init(XfdesktopIconViewManagerIface *iface)
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;
426
/* FIXME: remove this before 4.4.0; leave it for now to migrate older beta
427
* installs from the old location */
429
__migrate_old_icon_positions(XfdesktopFileIconManager *fmanager)
431
gchar relpath[PATH_MAX], *old_file;
433
g_snprintf(relpath, PATH_MAX, "xfce4/desktop/icons.screen%d.rc",
434
gdk_screen_get_number(fmanager->priv->gscreen));
436
old_file = xfce_resource_save_location(XFCE_RESOURCE_CACHE, relpath, FALSE);
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,
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;
446
GError *error = NULL;
448
if(g_file_get_contents(old_file, &contents, &length, &error)) {
449
if(!g_file_set_contents(new_file, contents, length,
452
g_critical("Unable to write to %s: %s", new_file,
459
g_critical("Unable to read from %s: %s", old_file,
465
g_critical("Unable to migrate icon position file to new location.");
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. */
479
xfdesktop_file_icon_manager_check_create_desktop_folder(GFile *folder)
482
GError *error = NULL;
483
gboolean result = TRUE;
486
g_return_val_if_fail(G_IS_FILE(folder), FALSE);
488
info = g_file_query_info(folder, XFDESKTOP_FILE_INFO_NAMESPACE,
489
G_FILE_QUERY_INFO_NONE, NULL, 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\""),
497
g_free(display_name);
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);
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\""),
514
g_free(display_name);
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);
532
/* icon signal handlers */
535
xfdesktop_file_icon_menu_executed(GtkWidget *widget,
538
XfdesktopFileIconManager *fmanager = XFDESKTOP_FILE_ICON_MANAGER(user_data);
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);
547
xfdesktop_icon_activated(icon);
551
xfdesktop_file_icon_menu_open_all(GtkWidget *widget,
554
XfdesktopFileIconManager *fmanager = XFDESKTOP_FILE_ICON_MANAGER(user_data);
557
selected = xfdesktop_icon_view_get_selected_items(fmanager->priv->icon_view);
558
g_return_if_fail(selected);
560
g_list_foreach(selected, (GFunc)xfdesktop_icon_activated, NULL);
561
g_list_free(selected);
565
xfdesktop_file_icon_menu_rename(GtkWidget *widget,
568
XfdesktopFileIconManager *fmanager = XFDESKTOP_FILE_ICON_MANAGER(user_data);
569
XfdesktopFileIcon *icon;
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);
579
file = xfdesktop_file_icon_peek_file(icon);
580
toplevel = gtk_widget_get_toplevel(GTK_WIDGET(fmanager->priv->icon_view));
582
xfdesktop_file_utils_rename_file(file, fmanager->priv->gscreen,
583
GTK_WINDOW(toplevel));
594
xfdesktop_file_icon_manager_delete_files(XfdesktopFileIconManager *fmanager,
597
GtkWidget *toplevel = gtk_widget_get_toplevel(GTK_WIDGET(fmanager->priv->icon_view));
598
GList *gfiles = NULL, *lp;
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));
603
xfdesktop_file_utils_unlink_files(gfiles, fmanager->priv->gscreen,
604
GTK_WINDOW(toplevel));
610
xfdesktop_file_icon_manager_trash_files_cb(DBusGProxy *proxy,
614
XfdesktopFileIconManager *fmanager = user_data;
616
g_return_if_fail(fmanager);
619
GtkWidget *parent = gtk_widget_get_toplevel(GTK_WIDGET(fmanager->priv->icon_view));
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);
631
xfdesktop_file_icon_manager_trash_files(XfdesktopFileIconManager *fmanager,
634
DBusGProxy *trash_proxy = xfdesktop_file_utils_peek_trash_proxy();
635
gboolean result = TRUE;
636
gchar **uris, *display_name, *startup_id;
641
g_return_val_if_fail(files, TRUE);
646
nfiles = g_list_length(files);
647
uris = g_new(gchar *, nfiles + 1);
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);
655
display_name = gdk_screen_make_display_name(fmanager->priv->gscreen);
656
startup_id = g_strdup_printf("_TIME%d", gtk_get_current_event_time());
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,
663
GtkWidget *parent = gtk_widget_get_toplevel(GTK_WIDGET(fmanager->priv->icon_view));
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);
677
g_free(display_name);
683
xfdesktop_file_icon_manager_delete_selected(XfdesktopFileIconManager *fmanager,
684
gboolean force_delete)
688
selected = xfdesktop_icon_view_get_selected_items(fmanager->priv->icon_view);
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;
698
l->prev->next = l->next;
699
else /* this is the first item; reset |selected| */
703
l->next->prev = l->prev;
705
l->next = l->prev = NULL;
713
if(G_UNLIKELY(!selected))
716
/* make sure the icons don't get destroyed while we're working */
717
g_list_foreach(selected, (GFunc)g_object_ref, NULL);
720
xfdesktop_file_icon_manager_trash_files(fmanager, selected);
722
xfdesktop_file_icon_manager_delete_files(fmanager, selected);
725
g_list_foreach(selected, (GFunc)g_object_unref, NULL);
726
g_list_free(selected);
728
xfdesktop_file_icon_position_changed(NULL, fmanager);
732
xfdesktop_file_icon_menu_app_info_executed(GtkWidget *widget,
735
XfdesktopFileIconManager *fmanager = XFDESKTOP_FILE_ICON_MANAGER(user_data);
736
XfdesktopFileIcon *icon;
737
GdkAppLaunchContext *context;
740
GList files, *selected;
742
GError *error = NULL;
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);
749
/* get the app info related to this menu item */
750
app_info = g_object_get_qdata(G_OBJECT(widget), xfdesktop_app_info_quark);
754
/* build a fake file list */
755
file = xfdesktop_file_icon_peek_file(icon);
756
files.prev = files.next = NULL;
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));
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))
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);
779
xfdesktop_file_icon_menu_open_folder(GtkWidget *widget,
782
XfdesktopFileIconManager *fmanager = XFDESKTOP_FILE_ICON_MANAGER(user_data);
783
XfdesktopFileIcon *icon;
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);
793
file = xfdesktop_file_icon_peek_file(icon);
795
toplevel = gtk_widget_get_toplevel(GTK_WIDGET(fmanager->priv->icon_view));
797
xfdesktop_file_utils_open_folder(file, fmanager->priv->gscreen,
798
GTK_WINDOW(toplevel));
802
xfdesktop_file_icon_menu_open_desktop(GtkWidget *widget,
805
XfdesktopFileIconManager *fmanager = XFDESKTOP_FILE_ICON_MANAGER(user_data);
806
XfdesktopFileIcon *icon = fmanager->priv->desktop_icon;
810
file = xfdesktop_file_icon_peek_file(icon);
814
toplevel = gtk_widget_get_toplevel(GTK_WIDGET(fmanager->priv->icon_view));
816
xfdesktop_file_utils_open_folder(file, fmanager->priv->gscreen,
817
GTK_WINDOW(toplevel));
821
xfdesktop_file_icon_menu_other_app(GtkWidget *widget,
824
XfdesktopFileIconManager *fmanager = XFDESKTOP_FILE_ICON_MANAGER(user_data);
825
XfdesktopFileIcon *icon;
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);
835
toplevel = gtk_widget_get_toplevel(GTK_WIDGET(fmanager->priv->icon_view));
837
file = xfdesktop_file_icon_peek_file(icon);
839
xfdesktop_file_utils_display_chooser_dialog(file, TRUE,
840
fmanager->priv->gscreen,
841
GTK_WINDOW(toplevel));
845
xfdesktop_file_icon_menu_cut(GtkWidget *widget,
848
XfdesktopFileIconManager *fmanager = XFDESKTOP_FILE_ICON_MANAGER(user_data);
851
files = xfdesktop_icon_view_get_selected_items(fmanager->priv->icon_view);
855
xfdesktop_clipboard_manager_cut_files(clipboard_manager, files);
861
xfdesktop_file_icon_menu_copy(GtkWidget *widget,
864
XfdesktopFileIconManager *fmanager = XFDESKTOP_FILE_ICON_MANAGER(user_data);
867
files = xfdesktop_icon_view_get_selected_items(fmanager->priv->icon_view);
871
xfdesktop_clipboard_manager_copy_files(clipboard_manager, files);
877
xfdesktop_file_icon_menu_delete(GtkWidget *widget,
880
XfdesktopFileIconManager *fmanager = XFDESKTOP_FILE_ICON_MANAGER(user_data);
881
GdkModifierType state;
882
gboolean force_delete = FALSE;
884
if(gtk_get_current_event_state(&state) && state & GDK_SHIFT_MASK)
887
xfdesktop_file_icon_manager_delete_selected(fmanager, force_delete);
891
xfdesktop_file_icon_menu_paste(GtkWidget *widget,
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);
900
xfdesktop_file_icon_menu_properties(GtkWidget *widget,
903
XfdesktopFileIconManager *fmanager = XFDESKTOP_FILE_ICON_MANAGER(user_data);
905
XfdesktopFileIcon *icon;
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);
914
file = xfdesktop_file_icon_peek_file(icon);
915
toplevel = gtk_widget_get_toplevel(GTK_WIDGET(fmanager->priv->icon_view));
917
xfdesktop_file_utils_show_properties_dialog(file, fmanager->priv->gscreen,
918
GTK_WINDOW(toplevel));
922
xfdesktop_file_icon_manager_desktop_properties(GtkWidget *widget,
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);
929
xfdesktop_file_utils_show_properties_dialog(file, fmanager->priv->gscreen,
934
xfdesktop_menu_item_from_app_info(XfdesktopFileIconManager *fmanager,
935
XfdesktopFileIcon *icon,
937
gboolean with_mnemonic,
938
gboolean with_title_prefix)
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));
950
title = g_strdup_printf(_("Open With \"%s\""),
951
g_app_info_get_name(app_info));
955
mi = gtk_image_menu_item_new_with_mnemonic(title);
957
mi = gtk_image_menu_item_new_with_label(title);
960
g_object_set_qdata_full(G_OBJECT(mi), xfdesktop_app_info_quark,
961
g_object_ref(app_info), g_object_unref);
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),
967
gtk_widget_show(img);
970
g_signal_connect(G_OBJECT(mi), "activate",
971
G_CALLBACK(xfdesktop_file_icon_menu_app_info_executed),
978
xfdesktop_file_icon_menu_free_icon_list_idled(gpointer user_data)
980
GList *icon_list = user_data;
982
g_list_foreach(icon_list, (GFunc)g_object_unref, NULL);
983
g_list_free(icon_list);
989
xfdesktop_file_icon_menu_free_icon_list(GtkMenu *menu,
992
g_idle_add(xfdesktop_file_icon_menu_free_icon_list_idled, user_data);
996
xfdesktop_file_icon_menu_create_launcher(GtkWidget *widget,
999
XfdesktopFileIconManager *fmanager = XFDESKTOP_FILE_ICON_MANAGER(user_data);
1001
gchar *cmd = NULL, *uri = NULL, *display_name;
1002
GError *error = NULL;
1004
display_name = gdk_screen_make_display_name(fmanager->priv->gscreen);
1006
file = g_object_get_data(G_OBJECT(widget), "file");
1009
uri = g_file_get_uri(file);
1010
cmd = g_strdup_printf("exo-desktop-item-edit \"--display=%s\" \"%s\"",
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);
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);
1031
g_free(display_name);
1037
xfdesktop_file_icon_menu_create_folder(GtkWidget *widget,
1040
XfdesktopFileIconManager *fmanager = XFDESKTOP_FILE_ICON_MANAGER(user_data);
1041
GtkWidget *toplevel;
1043
toplevel = gtk_widget_get_toplevel(GTK_WIDGET(fmanager->priv->icon_view));
1045
xfdesktop_file_utils_create_file(fmanager->priv->folder, "inode/directory",
1046
fmanager->priv->gscreen,
1047
GTK_WINDOW(toplevel));
1051
xfdesktop_file_icon_template_item_activated(GtkWidget *mi,
1054
XfdesktopFileIconManager *fmanager = XFDESKTOP_FILE_ICON_MANAGER(user_data);
1055
GtkWidget *toplevel;
1056
GFile *file = g_object_get_data(G_OBJECT(mi), "file");
1058
toplevel = gtk_widget_get_toplevel(GTK_WIDGET(fmanager->priv->icon_view));
1061
xfdesktop_file_utils_create_file_from_template(fmanager->priv->folder, file,
1062
fmanager->priv->gscreen,
1063
GTK_WINDOW(toplevel));
1065
xfdesktop_file_utils_create_file(fmanager->priv->folder, "text/plain",
1066
fmanager->priv->gscreen,
1067
GTK_WINDOW(toplevel));
1072
compare_template_files(gconstpointer a,
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);
1082
if(!info_a || !info_b)
1085
if(type_a == type_b) {
1086
return g_strcmp0(name_a, name_b);
1088
if(type_a == G_FILE_TYPE_DIRECTORY)
1096
xfdesktop_file_icon_menu_fill_template_menu(GtkWidget *menu,
1097
GFile *template_dir,
1098
XfdesktopFileIconManager *fmanager)
1100
GFileEnumerator *enumerator;
1101
GtkWidget *item, *image, *submenu;
1105
GList *files = NULL, *lp;
1107
gboolean have_templates = FALSE;
1109
g_return_val_if_fail(G_IS_FILE(template_dir), FALSE);
1111
enumerator = g_file_enumerate_children(template_dir,
1112
XFDESKTOP_FILE_INFO_NAMESPACE,
1113
G_FILE_QUERY_INFO_NONE,
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);
1123
g_object_unref(enumerator);
1126
files = g_list_sort(files, compare_template_files);
1128
for(lp = files; lp != NULL; lp = lp->next) {
1130
info = g_object_get_data(G_OBJECT(file), "info");
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));
1138
/* fill the submenu from the folder contents */
1139
have_templates = xfdesktop_file_icon_menu_fill_template_menu(submenu, file, fmanager)
1142
/* check if any items were added to the submenu */
1143
if (GTK_MENU_SHELL(submenu)->children)
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);
1156
g_object_unref (submenu);
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, '.');
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);
1172
g_object_set_data_full(G_OBJECT(item), "file",
1173
g_object_ref(file), g_object_unref);
1175
g_signal_connect (G_OBJECT(item), "activate",
1176
G_CALLBACK(xfdesktop_file_icon_template_item_activated),
1179
have_templates = TRUE;
1182
g_object_unref(file);
1187
return have_templates;
1189
dp = g_dir_open (absolute_path, 0, NULL);
1190
g_free (absolute_path);
1192
/* read the directory contents (if opened successfully) */
1193
if (G_LIKELY (dp != NULL))
1195
/* process all files within the directory */
1198
/* read the name of the next file */
1199
name = g_dir_read_name (dp);
1200
if (G_UNLIKELY (name == NULL))
1202
else if (name[0] == '.')
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);
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);
1215
/* close the directory handle */
1219
/* check if we have any infos */
1220
if (G_UNLIKELY (info_list == NULL))
1223
/* determine the icon theme for the menu */
1224
icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (menu));
1226
/* add menu items for all infos */
1227
for (lp = info_list; lp != NULL; lp = lp->next)
1229
/* determine the info */
1232
/* check if we have a regular file or a directory here */
1233
if (G_LIKELY (info->type == THUNAR_VFS_FILE_TYPE_REGULAR))
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))
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),
1247
gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
1248
gtk_widget_show (item);
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);
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);
1261
have_templates = TRUE;
1263
else if (info->type == THUNAR_VFS_FILE_TYPE_DIRECTORY)
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));
1270
/* fill the submenu from the folder contents */
1271
have_templates = xfdesktop_file_icon_menu_fill_template_menu(submenu,
1276
/* check if any items were added to the submenu */
1277
if (G_LIKELY (GTK_MENU_SHELL (submenu)->children != NULL))
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);
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);
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);
1295
g_object_unref (G_OBJECT (submenu));
1299
/* release the info list */
1300
thunar_vfs_info_list_free (info_list);
1303
return have_templates;
1308
xfdesktop_menu_shell_append_action_list(GtkMenuShell *menu_shell,
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);
1325
xfdesktop_settings_launch(GtkWidget *w,
1328
XfdesktopFileIconManager *fmanager = XFDESKTOP_FILE_ICON_MANAGER(user_data);
1330
GError *error = NULL;
1332
cmd = g_find_program_in_path("xfdesktop-settings");
1334
cmd = g_strdup(BINDIR "/xfdesktop-settings");
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);
1344
g_error_free(error);
1351
xfdesktop_file_icon_manager_populate_context_menu(XfceDesktop *desktop,
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;
1364
GtkWidget *toplevel = gtk_widget_get_toplevel(GTK_WIDGET(fmanager->priv->icon_view));
1369
selected = xfdesktop_icon_view_get_selected_items(fmanager->priv->icon_view);
1371
file_icon = selected->data;
1373
/* assume click on the desktop itself */
1374
selected = g_list_append(selected, fmanager->priv->desktop_icon);
1375
file_icon = fmanager->priv->desktop_icon;
1377
info = xfdesktop_file_icon_peek_file_info(file_icon);
1379
multi_sel = (g_list_length(selected) > 1);
1382
got_custom_menu = xfdesktop_icon_populate_context_menu(XFDESKTOP_ICON(selected->data),
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),
1393
if(!got_custom_menu) {
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),
1405
mi = gtk_separator_menu_item_new();
1406
gtk_widget_show(mi);
1407
gtk_menu_shell_append(GTK_MENU_SHELL(menu), mi);
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"));
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),
1425
mi = gtk_separator_menu_item_new();
1426
gtk_widget_show(mi);
1427
gtk_menu_shell_append(GTK_MENU_SHELL(menu), mi);
1429
if(file_icon == fmanager->priv->desktop_icon) {
1432
/* create launcher item */
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);
1439
g_signal_connect(G_OBJECT(mi), "activate",
1440
G_CALLBACK(xfdesktop_file_icon_menu_create_launcher),
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);
1448
/* create link item */
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);
1455
g_signal_connect(G_OBJECT(mi), "activate",
1456
G_CALLBACK(xfdesktop_file_icon_menu_create_launcher),
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);
1464
/* create folder item */
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);
1470
g_signal_connect(G_OBJECT(mi), "activate",
1471
G_CALLBACK(xfdesktop_file_icon_menu_create_folder),
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);
1479
/* create from template submenu */
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);
1485
tmpl_menu = gtk_menu_new();
1486
gtk_menu_item_set_submenu(GTK_MENU_ITEM(mi), tmpl_menu);
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);
1494
if(templates_dir && !g_file_equal(home_dir, templates_dir))
1496
xfdesktop_file_icon_menu_fill_template_menu(tmpl_menu,
1502
g_object_unref(templates_dir);
1503
g_object_unref(home_dir);
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),
1515
mi = gtk_separator_menu_item_new();
1516
gtk_widget_show(mi);
1517
gtk_menu_shell_append(GTK_MENU_SHELL(menu), mi);
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);
1528
g_signal_connect(G_OBJECT(mi), "activate",
1529
G_CALLBACK(xfdesktop_file_icon_menu_executed),
1532
mi = gtk_separator_menu_item_new();
1533
gtk_widget_show(mi);
1534
gtk_menu_shell_append(GTK_MENU_SHELL(menu), mi);
1536
if(g_content_type_equals(g_file_info_get_content_type(info),
1537
"application/x-desktop"))
1539
GFile *file = xfdesktop_file_icon_peek_file(file_icon);
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),
1555
app_infos = g_app_info_get_all_for_type(g_file_info_get_content_type(info));
1557
GAppInfo *app_info = G_APP_INFO(app_infos->data);
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);
1563
g_object_unref(app_info);
1565
if(app_infos->next) {
1566
GtkWidget *app_infos_menu;
1567
gint list_len = g_list_length(app_infos->next);
1569
if(!xfdesktop_file_utils_file_is_executable(info)
1572
mi = gtk_separator_menu_item_new();
1573
gtk_widget_show(mi);
1574
gtk_menu_shell_append(GTK_MENU_SHELL(menu), mi);
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);
1582
app_infos_menu = gtk_menu_new();
1583
gtk_menu_item_set_submenu(GTK_MENU_ITEM(mi),
1586
app_infos_menu = (GtkWidget *)menu;
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,
1593
gtk_menu_shell_append(GTK_MENU_SHELL(app_infos_menu), mi);
1594
g_object_unref(app_info);
1598
/* free the app info list */
1599
g_list_free(app_infos);
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),
1612
mi = gtk_separator_menu_item_new();
1613
gtk_widget_show(mi);
1614
gtk_menu_shell_append(GTK_MENU_SHELL(menu), mi);
1619
if(!multi_sel && fmanager->priv->thunarx_menu_providers) {
1620
GList *menu_actions = NULL;
1621
ThunarxMenuProvider *provider;
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,
1629
THUNARX_FILE_INFO(file_icon)));
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,
1642
xfdesktop_menu_shell_append_action_list(GTK_MENU_SHELL(menu),
1644
g_list_foreach(menu_actions, (GFunc)g_object_unref, NULL);
1645
g_list_free(menu_actions);
1647
mi = gtk_separator_menu_item_new();
1648
gtk_widget_show(mi);
1649
gtk_menu_shell_append(GTK_MENU_SHELL(menu), mi);
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),
1663
gtk_widget_set_sensitive(mi, FALSE);
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),
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),
1680
gtk_widget_set_sensitive(mi, FALSE);
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),
1690
gtk_widget_set_sensitive(mi, FALSE);
1692
mi = gtk_separator_menu_item_new();
1693
gtk_widget_show(mi);
1694
gtk_menu_shell_append(GTK_MENU_SHELL(menu), mi);
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),
1704
gtk_widget_set_sensitive(mi, FALSE);
1707
mi = gtk_separator_menu_item_new();
1708
gtk_widget_show(mi);
1709
gtk_menu_shell_append(GTK_MENU_SHELL(menu), mi);
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);
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);
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),
1739
/* don't free |selected|. the menu deactivated handler does that */
1743
file_icon_hash_write_icons(gpointer key,
1747
XfceRc *rcfile = data;
1748
XfdesktopIcon *icon = value;
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);
1759
xfdesktop_file_icon_manager_save_icons(gpointer user_data)
1761
XfdesktopFileIconManager *fmanager = XFDESKTOP_FILE_ICON_MANAGER(user_data);
1762
gchar relpath[PATH_MAX], *tmppath, *path;
1765
fmanager->priv->save_icons_id = 0;
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);
1773
tmppath = g_strconcat(path, ".new", NULL);
1775
rcfile = xfce_rc_simple_open(tmppath, FALSE);
1777
g_warning("Unable to determine location of icon position cache file. " \
1778
"Icon positions will not be saved.");
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);
1790
g_hash_table_foreach(fmanager->priv->special_icons,
1791
file_icon_hash_write_icons, rcfile);
1793
xfce_rc_flush(rcfile);
1794
xfce_rc_close(rcfile);
1796
if(rename(tmppath, path)) {
1797
g_warning("Unable to rename temp file to %s: %s", path,
1809
xfdesktop_file_icon_position_changed(XfdesktopFileIcon *icon,
1812
XfdesktopFileIconManager *fmanager = XFDESKTOP_FILE_ICON_MANAGER(user_data);
1814
if(fmanager->priv->save_icons_id)
1815
g_source_remove(fmanager->priv->save_icons_id);
1817
fmanager->priv->save_icons_id = g_timeout_add(SAVE_DELAY,
1818
xfdesktop_file_icon_manager_save_icons,
1826
xfdesktop_file_icon_manager_get_cached_icon_position(XfdesktopFileIconManager *fmanager,
1831
gchar relpath[PATH_MAX];
1833
gboolean ret = FALSE;
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);
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)
1846
xfce_rc_close(rcfile);
1853
#if defined(DEBUG) && DEBUG > 0
1854
static GList *_alive_icon_list = NULL;
1857
_icon_notify_destroy(gpointer data,
1860
g_assert(g_list_find(_alive_icon_list, obj));
1861
_alive_icon_list = g_list_remove(_alive_icon_list, obj);
1863
DBG("icon finalized: '%s'", xfdesktop_icon_peek_label(XFDESKTOP_ICON(obj)));
1868
xfdesktop_file_icon_manager_add_icon(XfdesktopFileIconManager *fmanager,
1869
XfdesktopFileIcon *icon,
1870
gboolean defer_if_missing)
1872
gint16 row = -1, col = -1;
1873
gboolean do_add = FALSE;
1877
file = xfdesktop_file_icon_peek_file(icon);
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));
1885
name = xfdesktop_icon_peek_label(XFDESKTOP_ICON(icon));
1886
if(xfdesktop_file_icon_manager_get_cached_icon_position(fmanager, name,
1889
DBG("attempting to set icon '%s' to position (%d,%d)", name, row, col);
1890
xfdesktop_icon_set_position(XFDESKTOP_ICON(icon), row, col);
1893
if(defer_if_missing) {
1894
fmanager->priv->deferred_icons = g_list_prepend(fmanager->priv->deferred_icons,
1895
g_object_ref(file));
1901
g_signal_connect(G_OBJECT(icon), "position-changed",
1902
G_CALLBACK(xfdesktop_file_icon_position_changed),
1904
xfdesktop_icon_view_add_item(fmanager->priv->icon_view,
1905
XFDESKTOP_ICON(icon));
1908
#if defined(DEBUG) && DEBUG > 0
1910
_alive_icon_list = g_list_prepend(_alive_icon_list, icon);
1911
g_object_weak_ref(G_OBJECT(icon), _icon_notify_destroy, NULL);
1918
static XfdesktopFileIcon *
1919
xfdesktop_file_icon_manager_add_regular_icon(XfdesktopFileIconManager *fmanager,
1922
gboolean defer_if_missing)
1924
XfdesktopRegularFileIcon *icon = NULL;
1925
gboolean is_desktop_file = FALSE;
1927
g_return_val_if_fail(fmanager && G_IS_FILE(file) && G_IS_FILE_INFO(info), NULL);
1929
if(g_content_type_equals(g_file_info_get_content_type(info),
1930
"application/x-desktop"))
1932
is_desktop_file = TRUE;
1936
gchar *uri = g_file_get_uri(file);
1937
if(g_str_has_suffix(uri, ".desktop"))
1938
is_desktop_file = TRUE;
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) */
1947
gchar *path = g_file_get_path(file);
1948
XfceRc *rcfile = xfce_rc_simple_open(path, TRUE);
1954
xfce_rc_set_group(rcfile, "Desktop Entry");
1955
if(xfce_rc_read_bool_entry(rcfile, "Hidden", FALSE)) {
1956
xfce_rc_close(rcfile);
1960
value = xfce_rc_read_entry(rcfile, "OnlyShowIn", NULL);
1961
if(value && strncmp(value, "XFCE;", 5) && !strstr(value, ";XFCE;")) {
1962
xfce_rc_close(rcfile);
1966
value = xfce_rc_read_entry(rcfile, "NotShowIn", NULL);
1967
if(value && (!strncmp(value, "XFCE;", 5) || strstr(value, ";XFCE;"))) {
1968
xfce_rc_close(rcfile);
1972
xfce_rc_close(rcfile);
1976
/* should never return NULL */
1977
icon = xfdesktop_regular_file_icon_new(file, info, fmanager->priv->gscreen);
1979
if(xfdesktop_file_icon_manager_add_icon(fmanager,
1980
XFDESKTOP_FILE_ICON(icon),
1983
g_hash_table_replace(fmanager->priv->icons, g_object_ref(file), icon);
1984
return XFDESKTOP_FILE_ICON(icon);
1986
g_object_unref(G_OBJECT(icon));
1991
static XfdesktopFileIcon *
1992
xfdesktop_file_icon_manager_add_volume_icon(XfdesktopFileIconManager *fmanager,
1995
XfdesktopVolumeIcon *icon;
1997
g_return_val_if_fail(fmanager && G_IS_VOLUME(volume), NULL);
1999
/* should never return NULL */
2000
icon = xfdesktop_volume_icon_new(volume, fmanager->priv->gscreen);
2002
if(xfdesktop_file_icon_manager_add_icon(fmanager,
2003
XFDESKTOP_FILE_ICON(icon),
2006
g_hash_table_replace(fmanager->priv->removable_icons,
2007
g_object_ref(G_OBJECT(volume)), icon);
2008
return XFDESKTOP_FILE_ICON(icon);
2010
g_object_unref(G_OBJECT(icon));
2015
static XfdesktopFileIcon *
2016
xfdesktop_file_icon_manager_add_special_file_icon(XfdesktopFileIconManager *fmanager,
2017
XfdesktopSpecialFileIconType type)
2019
XfdesktopSpecialFileIcon *icon;
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);
2026
if(xfdesktop_file_icon_manager_add_icon(fmanager,
2027
XFDESKTOP_FILE_ICON(icon),
2030
g_hash_table_replace(fmanager->priv->special_icons,
2031
GINT_TO_POINTER(type), icon);
2032
return XFDESKTOP_FILE_ICON(icon);
2034
g_object_unref(G_OBJECT(icon));
2040
xfdesktop_remove_icons_ht(gpointer key,
2044
xfdesktop_icon_view_remove_item(XFDESKTOP_ICON_VIEW(user_data),
2045
XFDESKTOP_ICON(value));
2050
xfdesktop_file_icon_manager_refresh_icons(XfdesktopFileIconManager *fmanager)
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);
2061
/* ditch removable media */
2062
if(fmanager->priv->show_removable_media)
2063
xfdesktop_file_icon_manager_remove_removable_media(fmanager);
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));
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));
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);
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);
2088
/* clear out anything left in the icon view */
2089
xfdesktop_icon_view_remove_all(fmanager->priv->icon_view);
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);
2097
/* add back removable media */
2098
if(fmanager->priv->show_removable_media)
2099
xfdesktop_file_icon_manager_load_removable_media(fmanager);
2101
/* reload and add ~/Desktop/ */
2102
xfdesktop_file_icon_manager_load_desktop_folder(fmanager);
2106
xfdesktop_file_icon_manager_key_press(GtkWidget *widget,
2110
XfdesktopFileIconManager *fmanager = XFDESKTOP_FILE_ICON_MANAGER(user_data);
2112
gboolean force_delete = FALSE;
2114
switch(evt->keyval) {
2117
if(evt->state & GDK_SHIFT_MASK)
2118
force_delete = TRUE;
2119
xfdesktop_file_icon_manager_delete_selected(fmanager, force_delete);
2124
if(!(evt->state & GDK_CONTROL_MASK)
2125
|| (evt->state & (GDK_SHIFT_MASK|GDK_MOD1_MASK|GDK_MOD4_MASK)))
2129
selected = xfdesktop_icon_view_get_selected_items(fmanager->priv->icon_view);
2131
xfdesktop_clipboard_manager_copy_files(clipboard_manager,
2133
g_list_free(selected);
2139
if(!(evt->state & GDK_CONTROL_MASK)
2140
|| (evt->state & (GDK_SHIFT_MASK|GDK_MOD1_MASK|GDK_MOD4_MASK)))
2144
selected = xfdesktop_icon_view_get_selected_items(fmanager->priv->icon_view);
2146
xfdesktop_clipboard_manager_cut_files(clipboard_manager,
2148
g_list_free(selected);
2154
if(!(evt->state & GDK_CONTROL_MASK)
2155
|| (evt->state & (GDK_SHIFT_MASK|GDK_MOD1_MASK|GDK_MOD4_MASK)))
2159
if(xfdesktop_clipboard_manager_get_can_paste(clipboard_manager)) {
2160
xfdesktop_clipboard_manager_paste_files(clipboard_manager, fmanager->priv->folder, widget, NULL);
2166
if(!(evt->state & GDK_CONTROL_MASK)
2167
|| (evt->state & (GDK_SHIFT_MASK|GDK_MOD1_MASK|GDK_MOD4_MASK)))
2173
xfdesktop_file_icon_manager_refresh_icons(fmanager);
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);
2186
g_list_free(selected);
2194
xfdesktop_file_icon_manager_file_changed(GFileMonitor *monitor,
2197
GFileMonitorEvent event,
2200
XfdesktopFileIconManager *fmanager = XFDESKTOP_FILE_ICON_MANAGER(user_data);
2201
XfdesktopFileIcon *icon;
2202
GFileInfo *file_info;
2205
case G_FILE_MONITOR_EVENT_CHANGED:
2206
DBG("got changed event: %s", g_file_get_path(file));
2208
icon = g_hash_table_lookup(fmanager->priv->icons, file);
2210
file_info = g_file_query_info(file, XFDESKTOP_FILE_INFO_NAMESPACE,
2211
G_FILE_QUERY_INFO_NONE, NULL, NULL);
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);
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);
2225
case G_FILE_MONITOR_EVENT_CREATED:
2226
DBG("got created event");
2228
/* make sure it's not the desktop folder itself */
2229
if(g_file_equal(fmanager->priv->folder, file))
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);
2236
xfdesktop_icon_view_remove_item(fmanager->priv->icon_view,
2237
XFDESKTOP_ICON(icon));
2238
g_hash_table_remove(fmanager->priv->icons, file);
2241
file_info = g_file_query_info(file, XFDESKTOP_FILE_INFO_NAMESPACE,
2242
G_FILE_QUERY_INFO_NONE, NULL, NULL);
2244
gboolean is_hidden = g_file_info_get_attribute_boolean(file_info,
2245
G_FILE_ATTRIBUTE_STANDARD_IS_HIDDEN);
2247
xfdesktop_file_icon_manager_add_regular_icon(fmanager,
2252
g_object_unref(file_info);
2256
case G_FILE_MONITOR_EVENT_DELETED:
2257
DBG("got deleted event");
2259
icon = g_hash_table_lookup(fmanager->priv->icons, file);
2261
/* Always try to remove thumbnail so it doesn't take up
2262
* space on the user's disk.
2264
xfdesktop_thumbnailer_delete_thumbnail(fmanager->priv->thumbnailer,
2265
g_file_get_path(file));
2266
xfdesktop_icon_delete_thumbnail(XFDESKTOP_ICON(icon));
2268
xfdesktop_icon_view_remove_item(fmanager->priv->icon_view,
2269
XFDESKTOP_ICON(icon));
2270
g_hash_table_remove(fmanager->priv->icons, file);
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);
2287
xfdesktop_file_icon_manager_files_ready(GFileEnumerator *enumerator,
2288
GAsyncResult *result,
2291
XfdesktopFileIconManager *fmanager = XFDESKTOP_FILE_ICON_MANAGER(user_data);
2292
GError *error = NULL;
2296
g_return_if_fail(enumerator == fmanager->priv->enumerator);
2298
files = g_file_enumerator_next_files_finish(enumerator, result, &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,
2306
xfce_message_dialog(GTK_WIDGET_TOPLEVEL(toplevel) ? GTK_WINDOW(toplevel) : NULL,
2309
GTK_STOCK_DIALOG_WARNING,
2310
_("Failed to load the desktop folder"), error->message,
2311
GTK_STOCK_CLOSE, GTK_RESPONSE_ACCEPT, NULL);
2314
g_object_unref(fmanager->priv->enumerator);
2315
fmanager->priv->enumerator = NULL;
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,
2325
xfdesktop_file_icon_manager_add_regular_icon(fmanager,
2328
g_object_unref(info);
2329
g_object_unref(file);
2331
g_list_free(fmanager->priv->deferred_icons);
2332
fmanager->priv->deferred_icons = NULL;
2336
if(!fmanager->priv->monitor) {
2337
fmanager->priv->monitor = g_file_monitor(fmanager->priv->folder,
2338
G_FILE_MONITOR_NONE,
2340
g_signal_connect(fmanager->priv->monitor, "changed",
2341
G_CALLBACK(xfdesktop_file_icon_manager_file_changed),
2345
for(l = files; l; l = l->next) {
2346
DBG("got a GFileInfo: %s", g_file_info_get_display_name(l->data));
2348
is_hidden = g_file_info_get_attribute_boolean(l->data,
2349
G_FILE_ATTRIBUTE_STANDARD_IS_HIDDEN);
2351
const gchar *name = g_file_info_get_name(l->data);
2352
GFile *file = g_file_get_child(fmanager->priv->folder, name);
2354
xfdesktop_file_icon_manager_add_regular_icon(fmanager,
2358
g_object_unref(file);
2361
g_object_unref(l->data);
2366
g_file_enumerator_next_files_async(fmanager->priv->enumerator,
2367
10, G_PRIORITY_DEFAULT, NULL,
2368
(GAsyncReadyCallback) xfdesktop_file_icon_manager_files_ready,
2374
xfdesktop_file_icon_manager_load_desktop_folder(XfdesktopFileIconManager *fmanager)
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;
2382
if(fmanager->priv->enumerator) {
2383
g_object_unref(fmanager->priv->enumerator);
2384
fmanager->priv->enumerator = NULL;
2387
fmanager->priv->enumerator = g_file_enumerate_children(fmanager->priv->folder,
2388
XFDESKTOP_FILE_INFO_NAMESPACE,
2389
G_FILE_QUERY_INFO_NONE,
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,
2402
xfdesktop_file_icon_manager_check_icons_opacity(gpointer key,
2406
XfdesktopRegularFileIcon *icon = XFDESKTOP_REGULAR_FILE_ICON(value);
2407
XfdesktopClipboardManager *cmanager = XFDESKTOP_CLIPBOARD_MANAGER(data);
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);
2412
xfdesktop_regular_file_icon_set_pixbuf_opacity(icon, 100);
2416
xfdesktop_file_icon_manager_clipboard_changed(XfdesktopClipboardManager *cmanager,
2419
XfdesktopFileIconManager *fmanager = XFDESKTOP_FILE_ICON_MANAGER(user_data);
2424
g_hash_table_foreach(fmanager->priv->icons,
2425
xfdesktop_file_icon_manager_check_icons_opacity,
2431
xfdesktop_file_icon_manager_volume_changed(GVolume *volume,
2434
XfdesktopFileIconManager *fmanager = XFDESKTOP_FILE_ICON_MANAGER(user_data);
2435
XfdesktopIcon *icon;
2436
gboolean is_present = xfdesktop_file_utils_volume_is_present(volume);
2438
icon = g_hash_table_lookup(fmanager->priv->removable_icons, volume);
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);
2449
xfdesktop_file_icon_manager_add_removable_volume(XfdesktopFileIconManager *fmanager,
2452
if(!xfdesktop_file_utils_volume_is_removable(volume))
2455
if(xfdesktop_file_utils_volume_is_present(volume))
2456
xfdesktop_file_icon_manager_add_volume_icon(fmanager, volume);
2458
g_signal_connect(G_OBJECT(volume), "changed",
2459
G_CALLBACK(xfdesktop_file_icon_manager_volume_changed),
2464
xfdesktop_file_icon_manager_volume_added(GVolumeMonitor *monitor,
2468
XfdesktopFileIconManager *fmanager = XFDESKTOP_FILE_ICON_MANAGER(user_data);
2470
xfdesktop_file_icon_manager_add_removable_volume(fmanager, volume);
2474
xfdesktop_file_icon_manager_volume_removed(GVolumeMonitor *monitor,
2478
XfdesktopFileIconManager *fmanager = XFDESKTOP_FILE_ICON_MANAGER(user_data);
2479
XfdesktopIcon *icon;
2481
icon = g_hash_table_lookup(fmanager->priv->removable_icons, volume);
2483
xfdesktop_icon_view_remove_item(fmanager->priv->icon_view, icon);
2484
g_hash_table_remove(fmanager->priv->removable_icons, volume);
2489
xfdesktop_file_icon_manager_load_removable_media(XfdesktopFileIconManager *fmanager)
2493
/* ensure we don't re-enter if we're already set up */
2494
if(fmanager->priv->removable_icons)
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);
2502
g_object_ref(G_OBJECT(fmanager->priv->volume_monitor));
2504
fmanager->priv->removable_icons = g_hash_table_new_full(g_direct_hash,
2506
(GDestroyNotify)g_object_unref,
2507
(GDestroyNotify)g_object_unref);
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);
2514
g_list_free(volumes);
2516
g_signal_connect(G_OBJECT(fmanager->priv->volume_monitor), "volume-added",
2517
G_CALLBACK(xfdesktop_file_icon_manager_volume_added),
2519
g_signal_connect(G_OBJECT(fmanager->priv->volume_monitor), "volume-removed",
2520
G_CALLBACK(xfdesktop_file_icon_manager_volume_removed),
2525
xfdesktop_file_icon_manager_ht_remove_removable_media(gpointer key,
2529
XfdesktopIcon *icon = XFDESKTOP_ICON(value);
2530
XfdesktopFileIconManager *fmanager = XFDESKTOP_FILE_ICON_MANAGER(user_data);
2533
volume = xfdesktop_volume_icon_peek_volume(XFDESKTOP_VOLUME_ICON(icon));
2535
g_signal_handlers_disconnect_by_func(volume,
2536
G_CALLBACK(xfdesktop_file_icon_manager_volume_changed),
2540
xfdesktop_icon_view_remove_item(fmanager->priv->icon_view, icon);
2544
xfdesktop_file_icon_manager_remove_removable_media(XfdesktopFileIconManager *fmanager)
2546
if(fmanager->priv->removable_icons) {
2547
g_hash_table_foreach(fmanager->priv->removable_icons,
2548
xfdesktop_file_icon_manager_ht_remove_removable_media,
2550
g_hash_table_destroy(fmanager->priv->removable_icons);
2551
fmanager->priv->removable_icons = NULL;
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),
2558
g_signal_handlers_disconnect_by_func(G_OBJECT(fmanager->priv->volume_monitor),
2559
G_CALLBACK(xfdesktop_file_icon_manager_volume_removed),
2562
g_object_unref(fmanager->priv->volume_monitor);
2567
/* virtual functions */
2570
xfdesktop_file_icon_manager_real_init(XfdesktopIconViewManager *manager,
2571
XfdesktopIconView *icon_view)
2573
XfdesktopFileIconManager *fmanager = XFDESKTOP_FILE_ICON_MANAGER(manager);
2574
GFileInfo *desktop_info;
2577
ThunarxProviderFactory *thunarx_pfac;
2580
if(fmanager->priv->inited) {
2581
g_warning("Initializing icon manager when already inited");
2585
fmanager->priv->icon_view = icon_view;
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),
2592
fmanager->priv->gscreen = gtk_widget_get_screen(GTK_WIDGET(icon_view));
2594
/* FIXME: remove for 4.4.0 */
2595
__migrate_old_icon_positions(fmanager);
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);
2603
g_object_ref(G_OBJECT(clipboard_manager));
2605
g_signal_connect(G_OBJECT(clipboard_manager), "changed",
2606
G_CALLBACK(xfdesktop_file_icon_manager_clipboard_changed),
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
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);
2619
g_signal_connect(G_OBJECT(xfdesktop_icon_view_get_window_widget(icon_view)),
2621
G_CALLBACK(xfdesktop_file_icon_manager_key_press),
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);
2629
fmanager->priv->special_icons = g_hash_table_new_full(g_direct_hash,
2632
(GDestroyNotify)g_object_unref);
2634
if(!xfdesktop_file_utils_dbus_init())
2635
g_warning("Unable to initialise D-Bus. Some xfdesktop features may be unavailable.");
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);
2647
thunarx_pfac = thunarx_provider_factory_get_default();
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);
2656
g_object_unref(G_OBJECT(thunarx_pfac));
2659
desktop_info = g_file_query_info(fmanager->priv->folder,
2660
XFDESKTOP_FILE_INFO_NAMESPACE,
2661
G_FILE_QUERY_INFO_NONE,
2664
fmanager->priv->desktop_icon = XFDESKTOP_FILE_ICON(xfdesktop_regular_file_icon_new(fmanager->priv->folder,
2666
fmanager->priv->gscreen));
2668
g_object_unref(desktop_info);
2670
fmanager->priv->inited = TRUE;
2676
xfdesktop_file_icon_manager_fini(XfdesktopIconViewManager *manager)
2678
XfdesktopFileIconManager *fmanager = XFDESKTOP_FILE_ICON_MANAGER(manager);
2681
if(!fmanager->priv->inited) {
2682
g_warning("Trying to de-init icon manager when it was never inited");
2686
fmanager->priv->inited = FALSE;
2688
if(fmanager->priv->enumerator) {
2689
g_object_unref(fmanager->priv->enumerator);
2690
fmanager->priv->enumerator = NULL;
2693
g_signal_handlers_disconnect_by_func(G_OBJECT(fmanager->priv->desktop),
2694
G_CALLBACK(xfdesktop_file_icon_manager_populate_context_menu),
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);
2703
g_signal_handlers_disconnect_by_func(G_OBJECT(clipboard_manager),
2704
G_CALLBACK(xfdesktop_file_icon_manager_clipboard_changed),
2707
g_object_unref(G_OBJECT(clipboard_manager));
2709
if(fmanager->priv->show_removable_media)
2710
xfdesktop_file_icon_manager_remove_removable_media(fmanager);
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));
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));
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);
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;
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),
2738
g_object_unref(fmanager->priv->monitor);
2739
fmanager->priv->monitor = NULL;
2741
g_object_unref(G_OBJECT(fmanager->priv->desktop_icon));
2742
fmanager->priv->desktop_icon = NULL;
2745
g_list_foreach(fmanager->priv->thunarx_menu_providers,
2746
(GFunc)g_object_unref, NULL);
2747
g_list_free(fmanager->priv->thunarx_menu_providers);
2749
g_list_foreach(fmanager->priv->thunarx_properties_providers,
2750
(GFunc)g_object_unref, NULL);
2751
g_list_free(fmanager->priv->thunarx_properties_providers);
2754
g_hash_table_destroy(fmanager->priv->special_icons);
2755
fmanager->priv->special_icons = NULL;
2757
g_hash_table_destroy(fmanager->priv->icons);
2758
fmanager->priv->icons = NULL;
2760
xfdesktop_file_utils_dbus_cleanup();
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),
2766
xfdesktop_icon_view_unset_drag_source(fmanager->priv->icon_view);
2767
xfdesktop_icon_view_unset_drag_dest(fmanager->priv->icon_view);
2771
xfdesktop_file_icon_manager_drag_drop(XfdesktopIconViewManager *manager,
2772
XfdesktopIcon *drop_icon,
2773
GdkDragContext *context,
2778
XfdesktopFileIconManager *fmanager = XFDESKTOP_FILE_ICON_MANAGER(manager);
2779
GtkWidget *widget = GTK_WIDGET(fmanager->priv->icon_view);
2784
target = gtk_drag_dest_find_target(widget, context,
2785
fmanager->priv->drop_targets);
2786
if(target == GDK_NONE)
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 */
2792
guchar *prop_text = NULL;
2793
GFile *source_file, *file;
2797
GFileInfo *info = xfdesktop_file_icon_peek_file_info(XFDESKTOP_FILE_ICON(drop_icon));
2801
if(g_file_info_get_file_type(info) != G_FILE_TYPE_DIRECTORY)
2804
source_file = xfdesktop_file_icon_peek_file(XFDESKTOP_FILE_ICON(drop_icon));
2807
source_file = fmanager->priv->folder;
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)
2815
prop_text = g_realloc(prop_text, prop_len + 1);
2816
prop_text[prop_len] = 0;
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);
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,
2834
} else if(target == gdk_atom_intern("_NETSCAPE_URL", FALSE)) {
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)
2844
TRACE("target good");
2846
gtk_drag_get_data(widget, context, target, time_);
2851
static void xfdesktop_dnd_item(GtkWidget *item, GdkDragAction *action)
2853
*action = GPOINTER_TO_UINT(g_object_get_data(G_OBJECT(item), "action"));
2856
static void xfdesktop_dnd_item_cancel(GtkWidget *item, GdkDragAction *action)
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>
2876
static void xfdesktop_dnd_menu (XfdesktopIconViewManager *manager,
2877
XfdesktopIcon *drop_icon,
2878
GdkDragContext *context,
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 };
2889
guint menu_item, signal_id;
2892
menu = gtk_menu_new();
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);
2907
gtk_widget_show(item);
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);
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);
2921
gtk_widget_show(menu);
2922
g_object_ref_sink(G_OBJECT(menu));
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);
2932
context->action = response;
2934
g_object_unref(G_OBJECT(menu));
2938
xfdesktop_file_icon_manager_drag_data_received(XfdesktopIconViewManager *manager,
2939
XfdesktopIcon *drop_icon,
2940
GdkDragContext *context,
2943
GtkSelectionData *data,
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;
2953
gboolean user_selected_action = FALSE;
2957
if(context->action == GDK_ACTION_ASK) {
2958
xfdesktop_dnd_menu(manager, drop_icon, context, row, col, time_);
2960
if(context->action == 0) {
2961
gtk_drag_finish(context, FALSE, FALSE, time_);
2964
/* The user picked whether to move or copy the files */
2965
user_selected_action = TRUE;
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
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])
2980
/* FIXME: do we really need to do anything here? xfdesktop should
2981
* detect when something changes on its own */
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");
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));
2995
source_file = fmanager->priv->folder;
2997
if(source_file && exo_desktop_item_edit) {
2998
gchar **parts = g_strsplit((const gchar *)data->data, "\n", -1);
3000
if(2 == g_strv_length(parts)) {
3001
gchar *cwd = g_file_get_uri(source_file);
3005
/* use the argv form so we don't have to worry about quoting
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";
3017
if(xfce_spawn_on_screen(fmanager->priv->gscreen, NULL, myargv,
3018
NULL, G_SPAWN_SEARCH_PATH, TRUE,
3019
gtk_get_current_event_time(),
3031
g_free(exo_desktop_item_edit);
3032
} else if(info == TARGET_TEXT_URI_LIST) {
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);
3039
copy_only = (context->action == GDK_ACTION_COPY);
3041
if(tfile && g_file_has_uri_scheme(tfile, "trash") && copy_only) {
3042
gtk_drag_finish(context, FALSE, FALSE, time_);
3046
file_list = xfdesktop_file_utils_file_list_from_string((const gchar *)data->data);
3048
GtkWidget *toplevel = gtk_widget_get_toplevel(GTK_WIDGET(fmanager->priv->icon_view));
3050
if(tinfo && xfdesktop_file_utils_file_is_executable(tinfo)) {
3051
drop_ok = xfdesktop_file_utils_execute(fmanager->priv->folder,
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));
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));
3066
/* if it's a volume, but we don't have |tinfo|, this just isn't
3068
if(!tinfo && dest_is_volume) {
3069
xfdesktop_file_utils_file_list_free(file_list);
3070
gtk_drag_finish(context, FALSE, FALSE, time_);
3074
if(tinfo && g_file_info_get_file_type(tinfo) == G_FILE_TYPE_DIRECTORY) {
3075
base_dest_file = g_object_ref(tfile);
3077
base_dest_file = g_object_ref(fmanager->priv->folder);
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.
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,
3092
src_info = g_file_query_info(file_list->data,
3093
G_FILE_ATTRIBUTE_ID_FILESYSTEM,
3094
G_FILE_QUERY_INFO_NONE,
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);
3104
if(g_strcmp0(src_name, dest_name) == 0) {
3106
context->action = GDK_ACTION_MOVE;
3110
if(dest_info != NULL)
3111
g_object_unref(dest_info);
3112
if(src_info != NULL)
3113
g_object_unref(src_info);
3116
for (l = file_list; l; l = l->next) {
3117
gchar *dest_basename = g_file_get_basename(l->data);
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
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);
3127
dest_file_list = g_list_prepend(dest_file_list, base_dest_file);
3131
g_free(dest_basename);
3134
g_object_unref(base_dest_file);
3136
if(dest_file_list) {
3137
dest_file_list = g_list_reverse(dest_file_list);
3139
drop_ok = xfdesktop_file_utils_transfer_files(context->action,
3142
fmanager->priv->gscreen);
3146
xfdesktop_file_utils_file_list_free(dest_file_list);
3148
g_list_free(dest_file_list);
3154
DBG("finishing drop on desktop from external source: drop_ok=%s, copy_only=%s",
3155
drop_ok?"TRUE":"FALSE", copy_only?"TRUE":"FALSE");
3157
gtk_drag_finish(context, drop_ok, !copy_only, time_);
3161
xfdesktop_file_icon_manager_drag_data_get(XfdesktopIconViewManager *manager,
3163
GdkDragContext *context,
3164
GtkSelectionData *data,
3173
g_return_if_fail(drag_icons);
3174
g_return_if_fail(info == TARGET_TEXT_URI_LIST);
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);
3179
gtk_selection_data_set(data, data->target, 8, (guchar *)str, strlen(str));
3182
xfdesktop_file_utils_file_list_free(file_list);
3188
XfdesktopIconViewManager *
3189
xfdesktop_file_icon_manager_new(GFile *folder,
3190
XfconfChannel *channel)
3192
XfdesktopFileIconManager *fmanager;
3194
g_return_val_if_fail(folder && channel, NULL);
3196
fmanager = g_object_new(XFDESKTOP_TYPE_FILE_ICON_MANAGER,
3199
fmanager->priv->channel = g_object_ref(G_OBJECT(channel));
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");
3212
return XFDESKTOP_ICON_VIEW_MANAGER(fmanager);
3216
xfdesktop_file_icon_manager_set_show_removable_media(XfdesktopFileIconManager *manager,
3217
gboolean show_removable_media)
3219
g_return_if_fail(XFDESKTOP_IS_FILE_ICON_MANAGER(manager));
3221
if(show_removable_media == manager->priv->show_removable_media)
3224
manager->priv->show_removable_media = show_removable_media;
3226
if(!manager->priv->inited)
3229
if(show_removable_media)
3230
xfdesktop_file_icon_manager_load_removable_media(manager);
3232
xfdesktop_file_icon_manager_remove_removable_media(manager);
3236
xfdesktop_file_icon_manager_get_show_removable_media(XfdesktopFileIconManager *manager)
3238
g_return_val_if_fail(XFDESKTOP_IS_FILE_ICON_MANAGER(manager), FALSE);
3239
return manager->priv->show_removable_media;
3243
xfdesktop_file_icon_manager_requeue_thumbnails(gpointer key,
3248
XfdesktopFileIconManager *fmanager = XFDESKTOP_FILE_ICON_MANAGER(data);
3250
xfdesktop_thumbnailer_queue_thumbnail(fmanager->priv->thumbnailer,
3251
g_file_get_path(file));
3255
xfdesktop_file_icon_manager_remove_thumbnails(gpointer key,
3259
XfdesktopRegularFileIcon *icon = XFDESKTOP_REGULAR_FILE_ICON(value);
3261
xfdesktop_icon_delete_thumbnail(XFDESKTOP_ICON(icon));
3265
xfdesktop_file_icon_manager_set_show_thumbnails(XfdesktopFileIconManager *manager,
3266
gboolean show_thumbnails)
3268
g_return_if_fail(XFDESKTOP_IS_FILE_ICON_MANAGER(manager));
3270
if(show_thumbnails == manager->priv->show_thumbnails)
3273
manager->priv->show_thumbnails = show_thumbnails;
3275
if(!manager->priv->inited)
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,
3284
/* We have to remove the thumbnails because the regular file
3285
* icons can't easily check if thumbnails are allowed.
3287
g_hash_table_foreach(manager->priv->icons,
3288
xfdesktop_file_icon_manager_remove_thumbnails,
3294
xfdesktop_file_icon_manager_get_show_thumbnails(XfdesktopFileIconManager *manager)
3296
g_return_val_if_fail(XFDESKTOP_IS_FILE_ICON_MANAGER(manager), FALSE);
3297
return manager->priv->show_thumbnails;
3301
xfdesktop_file_icon_manager_set_show_special_file(XfdesktopFileIconManager *manager,
3302
XfdesktopSpecialFileIconType type,
3303
gboolean show_special_file)
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);
3308
if(manager->priv->show_special[type] == show_special_file)
3311
manager->priv->show_special[type] = show_special_file;
3313
if(!manager->priv->inited)
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);
3321
XfdesktopIcon *icon = g_hash_table_lookup(manager->priv->special_icons,
3322
GINT_TO_POINTER(type));
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));
3332
xfdesktop_file_icon_manager_get_show_special_file(XfdesktopFileIconManager *manager,
3333
XfdesktopSpecialFileIconType type)
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,
3339
return manager->priv->show_special[type];
3343
xfdesktop_file_icon_manager_update_image(GtkWidget *widget,
3346
XfdesktopFileIconManager *manager)
3349
XfdesktopIcon *icon;
3351
g_return_if_fail(srcfile && thumbfile);
3352
g_return_if_fail(XFDESKTOP_FILE_ICON_MANAGER(manager));
3354
file = g_file_new_for_path(srcfile);
3356
icon = g_hash_table_lookup(manager->priv->icons, file);
3359
g_object_unref(file);
3360
file = g_file_new_for_path(thumbfile);
3361
xfdesktop_icon_set_thumbnail_file(icon, file);