1
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
3
* Copyright (C) 2005 Vincent Untz
5
* This program is free software; you can redistribute it and/or
6
* modify it under the terms of the GNU General Public License as
7
* published by the Free Software Foundation; either version 2 of the
8
* License, or (at your option) any later version.
10
* This program is distributed in the hope that it will be useful, but
11
* WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
* General Public License for more details.
15
* You should have received a copy of the GNU General Public License
16
* along with this program; if not, write to the Free Software
17
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
21
* Vincent Untz <vincent@vuntz.net>
23
* Based on code from panel-menu-bar.c
28
* + drag and drop loses icon for URIs
29
* + drag and drop of bookmarks/network places/removable media should create
31
* + if a menu is open and gets updated, it should reappear and not just
37
#include "panel-menu-items.h"
40
#include <glib/gi18n.h>
43
#include <libpanel-util/panel-error.h>
44
#include <libpanel-util/panel-glib.h>
45
#include <libpanel-util/panel-keyfile.h>
46
#include <libpanel-util/panel-launch.h>
47
#include <libpanel-util/panel-show.h>
50
#include "panel-action-button.h"
51
#include "panel-globals.h"
52
#include "panel-icon-names.h"
53
#include "panel-lockdown.h"
54
#include "panel-recent.h"
55
#include "panel-stock-icons.h"
56
#include "panel-util.h"
58
#define BOOKMARKS_FILENAME ".gtk-bookmarks"
59
#define DESKTOP_IS_HOME_DIR_DIR "/apps/nautilus/preferences"
60
#define DESKTOP_IS_HOME_DIR_KEY "/apps/nautilus/preferences/desktop_is_home_dir"
61
#define NAMES_DIR "/apps/nautilus/desktop"
62
#define HOME_NAME_KEY "/apps/nautilus/desktop/home_icon_name"
63
#define COMPUTER_NAME_KEY "/apps/nautilus/desktop/computer_icon_name"
64
#define MAX_ITEMS_OR_SUBMENU 5
65
#define MAX_BOOKMARK_ITEMS 100
67
G_DEFINE_TYPE (PanelPlaceMenuItem, panel_place_menu_item, GTK_TYPE_IMAGE_MENU_ITEM)
68
G_DEFINE_TYPE (PanelDesktopMenuItem, panel_desktop_menu_item, GTK_TYPE_IMAGE_MENU_ITEM)
70
#define PANEL_PLACE_MENU_ITEM_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), PANEL_TYPE_PLACE_MENU_ITEM, PanelPlaceMenuItemPrivate))
71
#define PANEL_DESKTOP_MENU_ITEM_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), PANEL_TYPE_DESKTOP_MENU_ITEM, PanelDesktopMenuItemPrivate))
73
struct _PanelPlaceMenuItemPrivate {
77
GtkRecentManager *recent_manager;
79
GFileMonitor *bookmarks_monitor;
81
GVolumeMonitor *volume_monitor;
82
gulong drive_changed_id;
83
gulong drive_connected_id;
84
gulong drive_disconnected_id;
85
gulong volume_added_id;
86
gulong volume_changed_id;
87
gulong volume_removed_id;
88
gulong mount_added_id;
89
gulong mount_changed_id;
90
gulong mount_removed_id;
95
struct _PanelDesktopMenuItemPrivate {
100
guint append_lock_logout : 1;
104
activate_uri_on_screen (const char *uri,
107
panel_show_uri (screen, uri, gtk_get_current_event_time (), NULL);
111
activate_uri (GtkWidget *menuitem,
114
activate_uri_on_screen (uri, menuitem_to_screen (menuitem));
118
activate_path (GtkWidget *menuitem,
123
uri = g_filename_to_uri (path, NULL, NULL);
124
activate_uri_on_screen (uri, menuitem_to_screen (menuitem));
129
activate_home_uri (GtkWidget *menuitem,
132
activate_path (menuitem, g_get_home_dir ());
136
activate_desktop_uri (GtkWidget *menuitem,
139
activate_path (menuitem,
140
g_get_user_special_dir (G_USER_DIRECTORY_DESKTOP));
144
panel_menu_items_append_from_desktop (GtkWidget *menu,
156
gboolean is_application;
164
key_file = g_key_file_new ();
166
if (g_path_is_absolute (path)) {
167
loaded = g_key_file_load_from_file (key_file, path,
168
G_KEY_FILE_NONE, NULL);
174
if (!g_str_has_suffix (path, ".desktop")) {
175
desktop_path = g_strconcat (path, ".desktop", NULL);
180
lookup_file = g_strconcat ("applications", G_DIR_SEPARATOR_S,
182
loaded = g_key_file_load_from_data_dirs (key_file, lookup_file,
186
full_path = path_freeme;
187
g_free (lookup_file);
189
if (desktop_path != path)
190
g_free (desktop_path);
194
g_key_file_free (key_file);
196
g_free (path_freeme);
200
/* For Application desktop files, respect TryExec */
201
type = panel_key_file_get_string (key_file, "Type");
203
g_key_file_free (key_file);
205
g_free (path_freeme);
208
is_application = (strcmp (type, "Application") == 0);
211
if (is_application) {
212
tryexec = panel_key_file_get_string (key_file, "TryExec");
216
prog = g_find_program_in_path (tryexec);
220
/* FIXME: we could add some file monitor magic,
221
* so that the menu items appears when the
222
* program appears, but that's really complex
223
* for not a huge benefit */
224
g_key_file_free (key_file);
226
g_free (path_freeme);
234
/* Now, simply build the menu item */
235
icon = panel_key_file_get_locale_string (key_file, "Icon");
236
comment = panel_key_file_get_locale_string (key_file, "Comment");
238
if (PANEL_GLIB_STR_EMPTY (force_name))
239
name = panel_key_file_get_locale_string (key_file, "Name");
241
name = g_strdup (force_name);
244
item = panel_image_menu_item_new ();
246
item = gtk_image_menu_item_new ();
249
setup_menu_item_with_icon (item, panel_menu_icon_get_size (),
250
icon, NULL, NULL, name);
252
panel_util_set_tooltip_text (item, comment);
254
gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
255
g_signal_connect_data (item, "activate",
256
G_CALLBACK (panel_menu_item_activate_desktop_file),
257
g_strdup (full_path),
258
(GClosureNotify) g_free, 0);
259
g_signal_connect (G_OBJECT (item), "button_press_event",
260
G_CALLBACK (menu_dummy_button_press_event), NULL);
262
uri = g_filename_to_uri (full_path, NULL, NULL);
264
setup_uri_drag (item, uri, icon);
267
g_key_file_free (key_file);
279
g_free (path_freeme);
283
panel_menu_items_append_place_item (const char *icon_name,
294
item = panel_image_menu_item_new ();
295
setup_menu_item_with_icon (item,
296
panel_menu_icon_get_size (),
297
icon_name, NULL, gicon,
300
panel_util_set_tooltip_text (item, tooltip);
302
gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
304
user_data = g_strdup (uri);
305
g_signal_connect_data (item, "activate", callback, user_data,
306
(GClosureNotify) g_free, 0);
308
g_signal_connect (G_OBJECT (item), "button_press_event",
309
G_CALLBACK (menu_dummy_button_press_event), NULL);
311
setup_uri_drag (item, uri, icon_name);
315
panel_menu_items_create_action_item_full (PanelActionButtonType action_type,
321
if (panel_action_get_is_disabled (action_type))
324
item = gtk_image_menu_item_new ();
325
setup_menu_item_with_icon (item,
326
panel_menu_icon_get_size (),
327
panel_action_get_icon_name (action_type),
329
label ? label : panel_action_get_text (action_type));
331
panel_util_set_tooltip_text (item,
334
panel_action_get_tooltip (action_type));
336
g_signal_connect (item, "activate",
337
panel_action_get_invoke (action_type), NULL);
338
g_signal_connect (G_OBJECT (item), "button_press_event",
339
G_CALLBACK (menu_dummy_button_press_event), NULL);
340
setup_internal_applet_drag (item, action_type);
346
panel_menu_items_create_action_item (PanelActionButtonType action_type)
348
return panel_menu_items_create_action_item_full (action_type,
353
panel_place_menu_item_append_gtk_bookmarks (GtkWidget *menu)
362
GIOChannel *io_channel;
365
GSList *lines = NULL;
366
GSList *add_bookmarks, *l;
367
PanelBookmark *bookmark;
369
filename = g_build_filename (g_get_home_dir (),
370
BOOKMARKS_FILENAME, NULL);
372
io_channel = g_io_channel_new_file (filename, "r", NULL);
378
/* We use a hard limit to avoid having users shooting their
379
* own feet, and to avoid crashing the system if a misbehaving
380
* application creates a big bookmars file.
382
for (i = 0; i < MAX_BOOKMARK_ITEMS; i++) {
385
gsize terminator_pos;
388
status = g_io_channel_read_line (io_channel, &contents, &length, &terminator_pos, NULL);
390
if (status != G_IO_STATUS_NORMAL)
396
/* Clear the line terminator (\n), if any */
397
if (terminator_pos > 0)
398
contents[terminator_pos] = '\0';
400
lines = g_slist_prepend (lines, contents);
403
g_io_channel_shutdown (io_channel, FALSE, NULL);
404
g_io_channel_unref (io_channel);
409
lines = g_slist_reverse (lines);
411
table = g_hash_table_new (g_str_hash, g_str_equal);
412
add_bookmarks = NULL;
414
for (l = lines; l; l = l->next) {
415
char *line = (char*) l->data;
417
if (line[0] && !g_hash_table_lookup (table, line)) {
423
g_hash_table_insert (table, line, line);
425
space = strchr (line, ' ');
428
label = g_strdup (space + 1);
435
if (g_str_has_prefix (line, "x-nautilus-search:"))
439
file = g_file_new_for_uri (line);
440
keep = !g_file_is_native (file) ||
441
g_file_query_exists (file, NULL);
442
g_object_unref (file);
451
bookmark = g_malloc (sizeof (PanelBookmark));
452
bookmark->full_uri = g_strdup (line);
453
bookmark->label = label;
454
add_bookmarks = g_slist_prepend (add_bookmarks, bookmark);
458
g_hash_table_destroy (table);
459
g_slist_foreach (lines, (GFunc) g_free, NULL);
460
g_slist_free (lines);
462
add_bookmarks = g_slist_reverse (add_bookmarks);
464
if (g_slist_length (add_bookmarks) <= MAX_ITEMS_OR_SUBMENU) {
469
item = gtk_image_menu_item_new ();
470
setup_menu_item_with_icon (item, panel_menu_icon_get_size (),
471
PANEL_ICON_BOOKMARKS, NULL, NULL,
474
gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
475
gtk_widget_show (item);
477
add_menu = create_empty_menu ();
478
gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), add_menu);
481
for (l = add_bookmarks; l; l = l->next) {
491
file = g_file_new_for_uri (bookmark->full_uri);
492
display_name = g_file_get_parse_name (file);
493
g_object_unref (file);
494
/* Translators: %s is a URI */
495
tooltip = g_strdup_printf (_("Open '%s'"), display_name);
496
g_free (display_name);
499
if (bookmark->label) {
500
label = g_strdup (g_strstrip (bookmark->label));
508
label = panel_util_get_label_for_uri (bookmark->full_uri);
512
g_free (bookmark->full_uri);
514
g_free (bookmark->label);
520
icon = panel_util_get_icon_for_uri (bookmark->full_uri);
521
/*FIXME: we should probably get a GIcon if possible, so that we
522
* have customized icons for cd-rom, eg */
524
icon = g_strdup (PANEL_ICON_FOLDER);
526
gicon = g_themed_icon_new_with_default_fallbacks (icon);
528
//FIXME: drag and drop will be broken for x-nautilus-search uris
529
panel_menu_items_append_place_item (icon, gicon,
533
G_CALLBACK (activate_uri),
537
g_object_unref (gicon);
540
g_free (bookmark->full_uri);
542
g_free (bookmark->label);
546
g_slist_free (add_bookmarks);
550
drive_poll_for_media_cb (GObject *source_object,
560
if (!g_drive_poll_for_media_finish (G_DRIVE (source_object),
562
if (error->code != G_IO_ERROR_FAILED_HANDLED) {
563
screen = GDK_SCREEN (user_data);
565
name = g_drive_get_name (G_DRIVE (source_object));
566
primary = g_strdup_printf (_("Unable to scan %s for media changes"),
569
panel_error_dialog (NULL, screen,
570
"cannot_scan_drive", TRUE,
571
primary, error->message);
574
g_error_free (error);
577
//FIXME: should we mount the volume and activate the root of the new
582
panel_menu_item_rescan_drive (GtkWidget *menuitem,
585
g_drive_poll_for_media (drive, NULL,
586
drive_poll_for_media_cb,
587
menuitem_to_screen (menuitem));
591
panel_menu_item_append_drive (GtkWidget *menu,
599
icon = g_drive_get_icon (drive);
600
title = g_drive_get_name (drive);
602
item = panel_image_menu_item_new ();
603
setup_menu_item_with_icon (item,
604
panel_menu_icon_get_size (),
607
g_object_unref (icon);
609
tooltip = g_strdup_printf (_("Rescan %s"), title);
610
panel_util_set_tooltip_text (item, tooltip);
615
gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
617
g_signal_connect_data (item, "activate",
618
G_CALLBACK (panel_menu_item_rescan_drive),
619
g_object_ref (drive),
620
(GClosureNotify) g_object_unref, 0);
622
g_signal_connect (G_OBJECT (item), "button_press_event",
623
G_CALLBACK (menu_dummy_button_press_event), NULL);
628
GMountOperation *mount_op;
629
} PanelVolumeMountData;
632
volume_mount_cb (GObject *source_object,
636
PanelVolumeMountData *mount_data = user_data;
640
if (!g_volume_mount_finish (G_VOLUME (source_object), res, &error)) {
644
if (error->code != G_IO_ERROR_FAILED_HANDLED) {
645
name = g_volume_get_name (G_VOLUME (source_object));
646
primary = g_strdup_printf (_("Unable to mount %s"),
650
panel_error_dialog (NULL, mount_data->screen,
651
"cannot_mount_volume", TRUE,
652
primary, error->message);
655
g_error_free (error);
661
mount = g_volume_get_mount (G_VOLUME (source_object));
662
root = g_mount_get_root (mount);
663
rooturi = g_file_get_uri (root);
664
activate_uri_on_screen (rooturi, mount_data->screen);
665
g_object_unref (mount);
666
g_object_unref (root);
670
g_object_unref (mount_data->mount_op);
671
g_slice_free (PanelVolumeMountData, mount_data);
675
panel_menu_item_mount_volume (GtkWidget *menuitem,
678
PanelVolumeMountData *mount_data;
680
mount_data = g_slice_new (PanelVolumeMountData);
681
mount_data->screen = menuitem_to_screen (menuitem);
682
mount_data->mount_op = gtk_mount_operation_new (NULL);
683
gtk_mount_operation_set_screen (GTK_MOUNT_OPERATION (mount_data->mount_op),
686
g_volume_mount (volume, G_MOUNT_MOUNT_NONE, mount_data->mount_op, NULL,
687
volume_mount_cb, mount_data);
691
panel_menu_item_append_volume (GtkWidget *menu,
699
icon = g_volume_get_icon (volume);
700
title = g_volume_get_name (volume);
702
item = panel_image_menu_item_new ();
703
setup_menu_item_with_icon (item,
704
panel_menu_icon_get_size (),
707
g_object_unref (icon);
709
tooltip = g_strdup_printf (_("Mount %s"), title);
710
panel_util_set_tooltip_text (item, tooltip);
715
gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
717
g_signal_connect_data (item, "activate",
718
G_CALLBACK (panel_menu_item_mount_volume),
719
g_object_ref (volume),
720
(GClosureNotify) g_object_unref, 0);
722
g_signal_connect (G_OBJECT (item), "button_press_event",
723
G_CALLBACK (menu_dummy_button_press_event), NULL);
727
panel_menu_item_append_mount (GtkWidget *menu,
733
char *activation_uri;
735
icon = g_mount_get_icon (mount);
736
display_name = g_mount_get_name (mount);
738
root = g_mount_get_root (mount);
739
activation_uri = g_file_get_uri (root);
740
g_object_unref (root);
742
panel_menu_items_append_place_item (NULL, icon,
744
display_name, //FIXME tooltip
746
G_CALLBACK (activate_uri),
749
g_object_unref (icon);
750
g_free (display_name);
751
g_free (activation_uri);
761
PanelGioItemType type;
769
/* this is loosely based on update_places() from nautilus-places-sidebar.c */
771
panel_place_menu_item_append_local_gio (PanelPlaceMenuItem *place_item,
789
/* first go through all connected drives */
790
drives = g_volume_monitor_get_connected_drives (place_item->priv->volume_monitor);
791
for (l = drives; l != NULL; l = l->next) {
794
volumes = g_drive_get_volumes (drive);
795
if (volumes != NULL) {
796
for (ll = volumes; ll != NULL; ll = ll->next) {
798
mount = g_volume_get_mount (volume);
799
item = g_slice_new (PanelGioItem);
801
item->type = PANEL_GIO_MOUNT;
802
item->u.mount = mount;
804
/* Do show the unmounted volumes; this
805
* is so the user can mount it (in case
806
* automounting is off).
808
* Also, even if automounting is
809
* enabled, this gives a visual cue
810
* that the user should remember to
811
* yank out the media if he just
814
item->type = PANEL_GIO_VOLUME;
815
item->u.volume = g_object_ref (volume);
817
items = g_slist_prepend (items, item);
818
g_object_unref (volume);
820
g_list_free (volumes);
822
if (g_drive_is_media_removable (drive) &&
823
!g_drive_is_media_check_automatic (drive)) {
824
/* If the drive has no mountable volumes and we
825
* cannot detect media change.. we display the
826
* drive so the user can manually poll the
827
* drive by clicking on it..."
829
* This is mainly for drives like floppies
830
* where media detection doesn't work.. but
831
* it's also for human beings who like to turn
832
* off media detection in the OS to save
835
item = g_slice_new (PanelGioItem);
836
item->type = PANEL_GIO_DRIVE;
837
item->u.drive = g_object_ref (drive);
838
items = g_slist_prepend (items, item);
841
g_object_unref (drive);
843
g_list_free (drives);
845
/* add all volumes that is not associated with a drive */
846
volumes = g_volume_monitor_get_volumes (place_item->priv->volume_monitor);
847
for (l = volumes; l != NULL; l = l->next) {
849
drive = g_volume_get_drive (volume);
851
g_object_unref (volume);
852
g_object_unref (drive);
855
mount = g_volume_get_mount (volume);
856
item = g_slice_new (PanelGioItem);
858
item->type = PANEL_GIO_MOUNT;
859
item->u.mount = mount;
861
/* see comment above in why we add an icon for an
862
* unmounted mountable volume */
863
item->type = PANEL_GIO_VOLUME;
864
item->u.volume = g_object_ref (volume);
866
items = g_slist_prepend (items, item);
867
g_object_unref (volume);
869
g_list_free (volumes);
871
/* add mounts that has no volume (/etc/mtab mounts, ftp, sftp,...) */
872
mounts = g_volume_monitor_get_mounts (place_item->priv->volume_monitor);
873
for (l = mounts; l != NULL; l = l->next) {
878
if (g_mount_is_shadowed (mount)) {
879
g_object_unref (mount);
883
volume = g_mount_get_volume (mount);
884
if (volume != NULL) {
885
g_object_unref (volume);
886
g_object_unref (mount);
890
root = g_mount_get_root (mount);
891
if (!g_file_is_native (root)) {
892
g_object_unref (root);
893
g_object_unref (mount);
896
g_object_unref (root);
898
item = g_slice_new (PanelGioItem);
899
item->type = PANEL_GIO_MOUNT;
900
item->u.mount = mount;
901
items = g_slist_prepend (items, item);
903
g_list_free (mounts);
905
/* now that we have everything, add the items inline or in a submenu */
906
items = g_slist_reverse (items);
908
if (g_slist_length (items) <= MAX_ITEMS_OR_SUBMENU) {
913
item = gtk_image_menu_item_new ();
914
setup_menu_item_with_icon (item, panel_menu_icon_get_size (),
915
PANEL_ICON_REMOVABLE_MEDIA,
917
_("Removable Media"));
919
gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
920
gtk_widget_show (item);
922
add_menu = create_empty_menu ();
923
gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), add_menu);
926
for (sl = items; sl; sl = sl->next) {
928
switch (item->type) {
929
case PANEL_GIO_DRIVE:
930
panel_menu_item_append_drive (add_menu, item->u.drive);
931
g_object_unref (item->u.drive);
933
case PANEL_GIO_VOLUME:
934
panel_menu_item_append_volume (add_menu, item->u.volume);
935
g_object_unref (item->u.volume);
937
case PANEL_GIO_MOUNT:
938
panel_menu_item_append_mount (add_menu, item->u.mount);
939
g_object_unref (item->u.mount);
942
g_assert_not_reached ();
944
g_slice_free (PanelGioItem, item);
947
g_slist_free (items);
950
/* this is loosely based on update_places() from nautilus-places-sidebar.c */
952
panel_place_menu_item_append_remote_gio (PanelPlaceMenuItem *place_item,
958
GSList *add_mounts, *sl;
960
/* add mounts that has no volume (/etc/mtab mounts, ftp, sftp,...) */
961
mounts = g_volume_monitor_get_mounts (place_item->priv->volume_monitor);
964
for (l = mounts; l; l = l->next) {
970
if (g_mount_is_shadowed (mount)) {
971
g_object_unref (mount);
975
volume = g_mount_get_volume (mount);
976
if (volume != NULL) {
977
g_object_unref (volume);
978
g_object_unref (mount);
982
root = g_mount_get_root (mount);
983
if (g_file_is_native (root)) {
984
g_object_unref (root);
985
g_object_unref (mount);
988
g_object_unref (root);
991
add_mounts = g_slist_prepend (add_mounts, mount);
993
add_mounts = g_slist_reverse (add_mounts);
995
if (g_slist_length (add_mounts) <= MAX_ITEMS_OR_SUBMENU) {
1000
item = panel_image_menu_item_new ();
1001
setup_menu_item_with_icon (item, panel_menu_icon_get_size (),
1002
PANEL_ICON_NETWORK_SERVER,
1004
_("Network Places"));
1006
gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
1007
gtk_widget_show (item);
1009
add_menu = create_empty_menu ();
1010
gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), add_menu);
1013
for (sl = add_mounts; sl; sl = sl->next) {
1015
panel_menu_item_append_mount (add_menu, mount);
1016
g_object_unref (mount);
1019
g_slist_free (add_mounts);
1020
g_list_free (mounts);
1025
panel_place_menu_item_create_menu (PanelPlaceMenuItem *place_item)
1027
GtkWidget *places_menu;
1034
places_menu = panel_create_menu ();
1036
file = g_file_new_for_path (g_get_home_dir ());
1037
uri = g_file_get_uri (file);
1038
name = panel_util_get_label_for_uri (uri);
1039
g_object_unref (file);
1041
panel_menu_items_append_place_item (PANEL_ICON_HOME, NULL,
1043
_("Open your personal folder"),
1045
G_CALLBACK (activate_home_uri),
1050
if (!gconf_client_get_bool (panel_gconf_get_client (),
1051
DESKTOP_IS_HOME_DIR_KEY,
1053
file = g_file_new_for_path (g_get_user_special_dir (G_USER_DIRECTORY_DESKTOP));
1054
uri = g_file_get_uri (file);
1055
g_object_unref (file);
1057
panel_menu_items_append_place_item (
1058
PANEL_ICON_DESKTOP, NULL,
1059
/* Translators: Desktop is used here as in
1060
* "Desktop Folder" (this is not the Desktop
1062
C_("Desktop Folder", "Desktop"),
1063
_("Open the contents of your desktop in a folder"),
1065
G_CALLBACK (activate_desktop_uri),
1066
/* FIXME: if the dir changes, we'd need to update the drag data since the uri is not the same */
1071
panel_place_menu_item_append_gtk_bookmarks (places_menu);
1072
add_menu_separator (places_menu);
1074
gconf_name = gconf_client_get_string (panel_gconf_get_client (),
1077
panel_menu_items_append_from_desktop (places_menu,
1078
"nautilus-computer.desktop",
1082
g_free (gconf_name);
1084
panel_place_menu_item_append_local_gio (place_item, places_menu);
1085
add_menu_separator (places_menu);
1087
panel_menu_items_append_from_desktop (places_menu,
1088
"network-scheme.desktop",
1091
panel_place_menu_item_append_remote_gio (place_item, places_menu);
1093
if (panel_is_program_in_path ("nautilus-connect-server")) {
1094
item = panel_menu_items_create_action_item (PANEL_ACTION_CONNECT_SERVER);
1096
gtk_menu_shell_append (GTK_MENU_SHELL (places_menu),
1100
add_menu_separator (places_menu);
1102
panel_menu_items_append_from_desktop (places_menu,
1103
"gnome-search-tool.desktop",
1107
panel_recent_append_documents_menu (places_menu,
1108
place_item->priv->recent_manager);
1114
panel_place_menu_item_recreate_menu (GtkWidget *widget)
1116
PanelPlaceMenuItem *place_item;
1118
place_item = PANEL_PLACE_MENU_ITEM (widget);
1120
if (place_item->priv->menu) {
1121
gtk_widget_destroy (place_item->priv->menu);
1122
place_item->priv->menu = panel_place_menu_item_create_menu (place_item);
1123
gtk_menu_item_set_submenu (GTK_MENU_ITEM (place_item),
1124
place_item->priv->menu);
1125
panel_applet_menu_set_recurse (GTK_MENU (place_item->priv->menu),
1127
place_item->priv->panel);
1132
panel_place_menu_item_key_changed (GConfClient *client,
1135
GtkWidget *place_item)
1137
panel_place_menu_item_recreate_menu (place_item);
1141
panel_place_menu_item_gtk_bookmarks_changed (GFileMonitor *handle,
1144
GFileMonitorEvent event,
1147
panel_place_menu_item_recreate_menu (GTK_WIDGET (user_data));
1151
panel_place_menu_item_drives_changed (GVolumeMonitor *monitor,
1153
GtkWidget *place_menu)
1155
panel_place_menu_item_recreate_menu (place_menu);
1159
panel_place_menu_item_volumes_changed (GVolumeMonitor *monitor,
1161
GtkWidget *place_menu)
1163
panel_place_menu_item_recreate_menu (place_menu);
1167
panel_place_menu_item_mounts_changed (GVolumeMonitor *monitor,
1169
GtkWidget *place_menu)
1171
panel_place_menu_item_recreate_menu (place_menu);
1175
panel_desktop_menu_item_append_menu (GtkWidget *menu,
1178
PanelDesktopMenuItem *parent;
1179
gboolean add_separator;
1183
parent = PANEL_DESKTOP_MENU_ITEM (data);
1185
add_separator = FALSE;
1186
children = gtk_container_get_children (GTK_CONTAINER (menu));
1187
last = g_list_last (children);
1190
add_separator = !GTK_IS_SEPARATOR (GTK_WIDGET (last->data));
1192
g_list_free (children);
1195
add_menu_separator (menu);
1197
panel_menu_items_append_from_desktop (menu, "yelp.desktop", NULL, FALSE);
1198
panel_menu_items_append_from_desktop (menu, "gnome-about.desktop", NULL, FALSE);
1200
if (parent->priv->append_lock_logout)
1201
panel_menu_items_append_lock_logout (menu);
1205
panel_desktop_menu_item_create_menu (PanelDesktopMenuItem *desktop_item)
1207
GtkWidget *desktop_menu;
1209
desktop_menu = create_applications_menu ("settings.menu", NULL, FALSE);
1211
g_object_set_data (G_OBJECT (desktop_menu),
1212
"panel-menu-append-callback",
1213
panel_desktop_menu_item_append_menu);
1214
g_object_set_data (G_OBJECT (desktop_menu),
1215
"panel-menu-append-callback-data",
1218
return desktop_menu;
1222
panel_desktop_menu_item_recreate_menu (PanelDesktopMenuItem *desktop_item)
1224
if (desktop_item->priv->menu) {
1225
gtk_widget_destroy (desktop_item->priv->menu);
1226
desktop_item->priv->menu = panel_desktop_menu_item_create_menu (desktop_item);
1227
gtk_menu_item_set_submenu (GTK_MENU_ITEM (desktop_item),
1228
desktop_item->priv->menu);
1229
panel_applet_menu_set_recurse (GTK_MENU (desktop_item->priv->menu),
1231
desktop_item->priv->panel);
1236
panel_place_menu_item_finalize (GObject *object)
1238
PanelPlaceMenuItem *menuitem = (PanelPlaceMenuItem *) object;
1240
gconf_client_remove_dir (panel_gconf_get_client (),
1241
DESKTOP_IS_HOME_DIR_DIR,
1243
gconf_client_remove_dir (panel_gconf_get_client (),
1247
if (menuitem->priv->bookmarks_monitor != NULL) {
1248
g_file_monitor_cancel (menuitem->priv->bookmarks_monitor);
1249
g_object_unref (menuitem->priv->bookmarks_monitor);
1251
menuitem->priv->bookmarks_monitor = NULL;
1253
if (menuitem->priv->drive_changed_id)
1254
g_signal_handler_disconnect (menuitem->priv->volume_monitor,
1255
menuitem->priv->drive_changed_id);
1256
menuitem->priv->drive_changed_id = 0;
1258
if (menuitem->priv->drive_connected_id)
1259
g_signal_handler_disconnect (menuitem->priv->volume_monitor,
1260
menuitem->priv->drive_connected_id);
1261
menuitem->priv->drive_connected_id = 0;
1263
if (menuitem->priv->drive_disconnected_id)
1264
g_signal_handler_disconnect (menuitem->priv->volume_monitor,
1265
menuitem->priv->drive_disconnected_id);
1266
menuitem->priv->drive_disconnected_id = 0;
1268
if (menuitem->priv->volume_added_id)
1269
g_signal_handler_disconnect (menuitem->priv->volume_monitor,
1270
menuitem->priv->volume_added_id);
1271
menuitem->priv->volume_added_id = 0;
1273
if (menuitem->priv->volume_changed_id)
1274
g_signal_handler_disconnect (menuitem->priv->volume_monitor,
1275
menuitem->priv->volume_changed_id);
1276
menuitem->priv->volume_changed_id = 0;
1278
if (menuitem->priv->volume_removed_id)
1279
g_signal_handler_disconnect (menuitem->priv->volume_monitor,
1280
menuitem->priv->volume_removed_id);
1281
menuitem->priv->volume_removed_id = 0;
1283
if (menuitem->priv->mount_added_id)
1284
g_signal_handler_disconnect (menuitem->priv->volume_monitor,
1285
menuitem->priv->mount_added_id);
1286
menuitem->priv->mount_added_id = 0;
1288
if (menuitem->priv->mount_changed_id)
1289
g_signal_handler_disconnect (menuitem->priv->volume_monitor,
1290
menuitem->priv->mount_changed_id);
1291
menuitem->priv->mount_changed_id = 0;
1293
if (menuitem->priv->mount_removed_id)
1294
g_signal_handler_disconnect (menuitem->priv->volume_monitor,
1295
menuitem->priv->mount_removed_id);
1296
menuitem->priv->mount_removed_id = 0;
1298
if (menuitem->priv->volume_monitor != NULL)
1299
g_object_unref (menuitem->priv->volume_monitor);
1300
menuitem->priv->volume_monitor = NULL;
1302
G_OBJECT_CLASS (panel_place_menu_item_parent_class)->finalize (object);
1306
panel_desktop_menu_item_finalize (GObject *object)
1308
PanelDesktopMenuItem *menuitem = (PanelDesktopMenuItem *) object;
1310
if (menuitem->priv->append_lock_logout)
1311
panel_lockdown_notify_remove (G_CALLBACK (panel_desktop_menu_item_recreate_menu),
1313
G_OBJECT_CLASS (panel_desktop_menu_item_parent_class)->finalize (object);
1317
panel_place_menu_item_init (PanelPlaceMenuItem *menuitem)
1320
char *bookmarks_filename;
1323
menuitem->priv = PANEL_PLACE_MENU_ITEM_GET_PRIVATE (menuitem);
1325
gconf_client_add_dir (panel_gconf_get_client (),
1326
DESKTOP_IS_HOME_DIR_DIR,
1327
GCONF_CLIENT_PRELOAD_NONE,
1329
gconf_client_add_dir (panel_gconf_get_client (),
1331
GCONF_CLIENT_PRELOAD_NONE,
1334
panel_gconf_notify_add_while_alive (HOME_NAME_KEY,
1335
(GConfClientNotifyFunc) panel_place_menu_item_key_changed,
1336
G_OBJECT (menuitem));
1337
panel_gconf_notify_add_while_alive (DESKTOP_IS_HOME_DIR_KEY,
1338
(GConfClientNotifyFunc) panel_place_menu_item_key_changed,
1339
G_OBJECT (menuitem));
1340
panel_gconf_notify_add_while_alive (COMPUTER_NAME_KEY,
1341
(GConfClientNotifyFunc) panel_place_menu_item_key_changed,
1342
G_OBJECT (menuitem));
1344
menuitem->priv->recent_manager = gtk_recent_manager_get_default ();
1346
bookmarks_filename = g_build_filename (g_get_home_dir (),
1347
BOOKMARKS_FILENAME, NULL);
1348
bookmark = g_file_new_for_path (bookmarks_filename);
1351
menuitem->priv->bookmarks_monitor = g_file_monitor_file
1353
G_FILE_MONITOR_NONE,
1357
g_warning ("Failed to add file monitor for %s: %s\n",
1358
bookmarks_filename, error->message);
1359
g_error_free (error);
1361
g_signal_connect (G_OBJECT (menuitem->priv->bookmarks_monitor),
1363
(GCallback) panel_place_menu_item_gtk_bookmarks_changed,
1367
g_object_unref (bookmark);
1368
g_free (bookmarks_filename);
1370
menuitem->priv->volume_monitor = g_volume_monitor_get ();
1372
menuitem->priv->drive_changed_id = g_signal_connect (menuitem->priv->volume_monitor,
1374
G_CALLBACK (panel_place_menu_item_drives_changed),
1376
menuitem->priv->drive_connected_id = g_signal_connect (menuitem->priv->volume_monitor,
1378
G_CALLBACK (panel_place_menu_item_drives_changed),
1380
menuitem->priv->drive_disconnected_id = g_signal_connect (menuitem->priv->volume_monitor,
1381
"drive-disconnected",
1382
G_CALLBACK (panel_place_menu_item_drives_changed),
1384
menuitem->priv->volume_added_id = g_signal_connect (menuitem->priv->volume_monitor,
1386
G_CALLBACK (panel_place_menu_item_volumes_changed),
1388
menuitem->priv->volume_changed_id = g_signal_connect (menuitem->priv->volume_monitor,
1390
G_CALLBACK (panel_place_menu_item_volumes_changed),
1392
menuitem->priv->volume_removed_id = g_signal_connect (menuitem->priv->volume_monitor,
1394
G_CALLBACK (panel_place_menu_item_volumes_changed),
1396
menuitem->priv->mount_added_id = g_signal_connect (menuitem->priv->volume_monitor,
1398
G_CALLBACK (panel_place_menu_item_mounts_changed),
1400
menuitem->priv->mount_changed_id = g_signal_connect (menuitem->priv->volume_monitor,
1402
G_CALLBACK (panel_place_menu_item_mounts_changed),
1404
menuitem->priv->mount_removed_id = g_signal_connect (menuitem->priv->volume_monitor,
1406
G_CALLBACK (panel_place_menu_item_mounts_changed),
1412
panel_desktop_menu_item_init (PanelDesktopMenuItem *menuitem)
1414
menuitem->priv = PANEL_DESKTOP_MENU_ITEM_GET_PRIVATE (menuitem);
1418
panel_place_menu_item_class_init (PanelPlaceMenuItemClass *klass)
1420
GObjectClass *gobject_class = (GObjectClass *) klass;
1422
gobject_class->finalize = panel_place_menu_item_finalize;
1424
g_type_class_add_private (klass, sizeof (PanelPlaceMenuItemPrivate));
1428
panel_desktop_menu_item_class_init (PanelDesktopMenuItemClass *klass)
1430
GObjectClass *gobject_class = (GObjectClass *) klass;
1432
gobject_class->finalize = panel_desktop_menu_item_finalize;
1434
g_type_class_add_private (klass, sizeof (PanelDesktopMenuItemPrivate));
1438
panel_place_menu_item_new (gboolean use_image)
1440
PanelPlaceMenuItem *menuitem;
1443
menuitem = g_object_new (PANEL_TYPE_PLACE_MENU_ITEM, NULL);
1446
image = gtk_image_new_from_icon_name (PANEL_ICON_FOLDER,
1447
panel_menu_icon_get_size ());
1451
setup_menuitem (GTK_WIDGET (menuitem),
1452
image ? panel_menu_icon_get_size () : GTK_ICON_SIZE_INVALID,
1456
menuitem->priv->use_image = use_image;
1458
menuitem->priv->menu = panel_place_menu_item_create_menu (menuitem);
1459
gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem),
1460
menuitem->priv->menu);
1462
return GTK_WIDGET (menuitem);
1466
panel_desktop_menu_item_new (gboolean use_image,
1467
gboolean append_lock_logout)
1469
PanelDesktopMenuItem *menuitem;
1472
menuitem = g_object_new (PANEL_TYPE_DESKTOP_MENU_ITEM, NULL);
1475
image = gtk_image_new_from_icon_name ("computer",
1476
panel_menu_icon_get_size ());
1480
setup_menuitem (GTK_WIDGET (menuitem),
1481
image ? panel_menu_icon_get_size () : GTK_ICON_SIZE_INVALID,
1485
menuitem->priv->use_image = use_image;
1487
menuitem->priv->append_lock_logout = append_lock_logout;
1488
if (append_lock_logout)
1489
panel_lockdown_notify_add (G_CALLBACK (panel_desktop_menu_item_recreate_menu),
1492
menuitem->priv->menu = panel_desktop_menu_item_create_menu (menuitem);
1493
gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem),
1494
menuitem->priv->menu);
1496
return GTK_WIDGET (menuitem);
1500
panel_place_menu_item_set_panel (GtkWidget *item,
1503
PanelPlaceMenuItem *place_item;
1505
place_item = PANEL_PLACE_MENU_ITEM (item);
1507
place_item->priv->panel = panel;
1508
panel_applet_menu_set_recurse (GTK_MENU (place_item->priv->menu),
1509
"menu_panel", panel);
1513
panel_desktop_menu_item_set_panel (GtkWidget *item,
1516
PanelDesktopMenuItem *desktop_item;
1518
desktop_item = PANEL_DESKTOP_MENU_ITEM (item);
1520
desktop_item->priv->panel = panel;
1521
panel_applet_menu_set_recurse (GTK_MENU (desktop_item->priv->menu),
1522
"menu_panel", panel);
1526
panel_menu_items_append_lock_logout (GtkWidget *menu)
1528
gboolean separator_inserted;
1532
const char *translate;
1536
separator_inserted = FALSE;
1537
children = gtk_container_get_children (GTK_CONTAINER (menu));
1538
last = g_list_last (children);
1540
separator_inserted = GTK_IS_SEPARATOR (GTK_WIDGET (last->data));
1542
g_list_free (children);
1544
if (panel_lock_screen_action_available ("lock")) {
1545
item = panel_menu_items_create_action_item (PANEL_ACTION_LOCK);
1547
if (!separator_inserted) {
1548
add_menu_separator (menu);
1549
separator_inserted = TRUE;
1552
gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
1556
if (panel_lockdown_get_disable_log_out ())
1558
/* Below this, we only have log out/shutdown items */
1560
/* Translators: translate "1" (msgctxt: "panel:showusername") to anything
1561
* but "1" if "Log Out %s" doesn't make any sense in your
1562
* language (where %s is a username).
1564
translate = C_("panel:showusername", "1");
1565
if (strcmp (translate, "1") == 0) {
1566
const char *user_name;
1568
user_name = g_get_real_name ();
1569
if (!user_name || !user_name [0])
1570
user_name = g_get_user_name ();
1572
/* keep those strings in sync with the ones in
1573
* panel-action-button.c */
1574
/* Translators: this string is used ONLY if you translated
1575
* "1" (msgctxt: "panel:showusername") to "1" */
1576
label = g_strdup_printf (_("Log Out %s..."),
1577
g_get_user_name ());
1578
/* Translators: this string is used ONLY if you translated
1579
* "1" (msgctxt: "panel:showusername") to "1" */
1580
tooltip = g_strdup_printf (_("Log out %s of this session to "
1581
"log in as a different user"),
1588
item = panel_menu_items_create_action_item_full (PANEL_ACTION_LOGOUT,
1594
if (!separator_inserted) {
1595
add_menu_separator (menu);
1596
separator_inserted = TRUE;
1599
gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
1602
item = panel_menu_items_create_action_item (PANEL_ACTION_SHUTDOWN);
1604
if (!separator_inserted)
1605
add_menu_separator (menu);
1607
gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
1612
panel_menu_item_activate_desktop_file (GtkWidget *menuitem,
1615
panel_launch_desktop_file (path, menuitem_to_screen (menuitem), NULL);