1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*-
3 nautilus-desktop-link-monitor.c: singleton thatn manages the links
5 Copyright (C) 2003 Red Hat, Inc.
7 This program is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public License as
9 published by the Free Software Foundation; either version 2 of the
10 License, or (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License for more details.
17 You should have received a copy of the GNU General Public
18 License along with this program; if not, write to the
19 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA.
22 Author: Alexander Larsson <alexl@redhat.com>
26 #include "nautilus-desktop-link-monitor.h"
27 #include "nautilus-desktop-link.h"
28 #include "nautilus-desktop-icon-file.h"
29 #include "nautilus-directory.h"
30 #include "nautilus-desktop-directory.h"
31 #include "nautilus-global-preferences.h"
33 #include <eel/eel-debug.h>
34 #include <eel/eel-gtk-macros.h>
35 #include <eel/eel-glib-extensions.h>
36 #include <eel/eel-vfs-extensions.h>
37 #include <eel/eel-stock-dialogs.h>
38 #include <gtk/gtkmessagedialog.h>
39 #include <gtk/gtksignal.h>
40 #include <gtk/gtkstock.h>
41 #include <glib/gi18n.h>
43 #include <libnautilus-private/nautilus-trash-monitor.h>
46 struct NautilusDesktopLinkMonitorDetails
{
47 GVolumeMonitor
*volume_monitor
;
48 NautilusDirectory
*desktop_dir
;
50 NautilusDesktopLink
*home_link
;
51 NautilusDesktopLink
*computer_link
;
52 NautilusDesktopLink
*trash_link
;
53 NautilusDesktopLink
*network_link
;
63 static void nautilus_desktop_link_monitor_init (gpointer object
,
65 static void nautilus_desktop_link_monitor_class_init (gpointer klass
);
67 EEL_CLASS_BOILERPLATE (NautilusDesktopLinkMonitor
,
68 nautilus_desktop_link_monitor
,
71 static NautilusDesktopLinkMonitor
*the_link_monitor
= NULL
;
74 destroy_desktop_link_monitor (void)
76 if (the_link_monitor
!= NULL
) {
77 g_object_unref (the_link_monitor
);
81 NautilusDesktopLinkMonitor
*
82 nautilus_desktop_link_monitor_get (void)
84 if (the_link_monitor
== NULL
) {
85 g_object_new (NAUTILUS_TYPE_DESKTOP_LINK_MONITOR
, NULL
);
86 eel_debug_call_at_shutdown (destroy_desktop_link_monitor
);
88 return the_link_monitor
;
92 volume_delete_dialog (GtkWidget
*parent_view
,
93 NautilusDesktopLink
*link
)
99 mount
= nautilus_desktop_link_get_mount (link
);
102 display_name
= nautilus_desktop_link_get_display_name (link
);
103 dialog_str
= g_strdup_printf (_("You cannot move the volume \"%s\" to the trash."),
105 g_free (display_name
);
107 if (g_mount_can_eject (mount
)) {
108 eel_run_simple_dialog
113 _("If you want to eject the volume, please use \"Eject\" in the "
114 "popup menu of the volume."),
117 eel_run_simple_dialog
122 _("If you want to unmount the volume, please use \"Unmount Volume\" in the "
123 "popup menu of the volume."),
127 g_object_unref (mount
);
133 nautilus_desktop_link_monitor_delete_link (NautilusDesktopLinkMonitor
*monitor
,
134 NautilusDesktopLink
*link
,
135 GtkWidget
*parent_view
)
137 switch (nautilus_desktop_link_get_link_type (link
)) {
138 case NAUTILUS_DESKTOP_LINK_HOME
:
139 case NAUTILUS_DESKTOP_LINK_COMPUTER
:
140 case NAUTILUS_DESKTOP_LINK_TRASH
:
141 case NAUTILUS_DESKTOP_LINK_NETWORK
:
142 /* just ignore. We don't allow you to delete these */
145 volume_delete_dialog (parent_view
, link
);
151 volume_file_name_used (NautilusDesktopLinkMonitor
*monitor
,
158 for (l
= monitor
->details
->mount_links
; l
!= NULL
; l
= l
->next
) {
159 other_name
= nautilus_desktop_link_get_file_name (l
->data
);
160 same
= strcmp (name
, other_name
) == 0;
172 nautilus_desktop_link_monitor_make_filename_unique (NautilusDesktopLinkMonitor
*monitor
,
173 const char *filename
)
179 unique_name
= g_strdup (filename
);
180 while (volume_file_name_used (monitor
, unique_name
)) {
181 g_free (unique_name
);
182 unique_name
= g_strdup_printf ("%s.%d", filename
, i
++);
188 create_mount_link (NautilusDesktopLinkMonitor
*monitor
,
191 NautilusDesktopLink
*link
;
195 if (eel_preferences_get_boolean (NAUTILUS_PREFERENCES_DESKTOP_VOLUMES_VISIBLE
)) {
196 link
= nautilus_desktop_link_new_from_mount (mount
);
197 monitor
->details
->mount_links
= g_list_prepend (monitor
->details
->mount_links
, link
);
204 mount_added_callback (GVolumeMonitor
*volume_monitor
,
206 NautilusDesktopLinkMonitor
*monitor
)
208 create_mount_link (monitor
, mount
);
213 mount_removed_callback (GVolumeMonitor
*volume_monitor
,
215 NautilusDesktopLinkMonitor
*monitor
)
218 NautilusDesktopLink
*link
;
222 for (l
= monitor
->details
->mount_links
; l
!= NULL
; l
= l
->next
) {
223 other_mount
= nautilus_desktop_link_get_mount (l
->data
);
224 if (mount
== other_mount
) {
225 g_object_unref (other_mount
);
229 g_object_unref (other_mount
);
233 monitor
->details
->mount_links
= g_list_remove (monitor
->details
->mount_links
, link
);
234 g_object_unref (link
);
239 mount_changed_callback (GVolumeMonitor
*volume_monitor
,
241 NautilusDesktopLinkMonitor
*monitor
)
243 /* TODO: update the mount */
247 update_link_visibility (NautilusDesktopLinkMonitor
*monitor
,
248 NautilusDesktopLink
**link_ref
,
249 NautilusDesktopLinkType link_type
,
250 const char *preference_key
)
252 if (eel_preferences_get_boolean (preference_key
)) {
253 if (*link_ref
== NULL
) {
254 *link_ref
= nautilus_desktop_link_new (link_type
);
257 if (*link_ref
!= NULL
) {
258 g_object_unref (*link_ref
);
265 desktop_home_visible_changed (gpointer callback_data
)
267 NautilusDesktopLinkMonitor
*monitor
;
269 monitor
= NAUTILUS_DESKTOP_LINK_MONITOR (callback_data
);
271 update_link_visibility (NAUTILUS_DESKTOP_LINK_MONITOR (monitor
),
272 &monitor
->details
->home_link
,
273 NAUTILUS_DESKTOP_LINK_HOME
,
274 NAUTILUS_PREFERENCES_DESKTOP_HOME_VISIBLE
);
278 desktop_computer_visible_changed (gpointer callback_data
)
280 NautilusDesktopLinkMonitor
*monitor
;
282 monitor
= NAUTILUS_DESKTOP_LINK_MONITOR (callback_data
);
284 update_link_visibility (NAUTILUS_DESKTOP_LINK_MONITOR (callback_data
),
285 &monitor
->details
->computer_link
,
286 NAUTILUS_DESKTOP_LINK_COMPUTER
,
287 NAUTILUS_PREFERENCES_DESKTOP_COMPUTER_VISIBLE
);
291 desktop_trash_visible_changed (gpointer callback_data
)
293 NautilusDesktopLinkMonitor
*monitor
;
295 monitor
= NAUTILUS_DESKTOP_LINK_MONITOR (callback_data
);
297 update_link_visibility (NAUTILUS_DESKTOP_LINK_MONITOR (callback_data
),
298 &monitor
->details
->trash_link
,
299 NAUTILUS_DESKTOP_LINK_TRASH
,
300 NAUTILUS_PREFERENCES_DESKTOP_TRASH_VISIBLE
);
304 desktop_network_visible_changed (gpointer callback_data
)
306 NautilusDesktopLinkMonitor
*monitor
;
308 monitor
= NAUTILUS_DESKTOP_LINK_MONITOR (callback_data
);
310 update_link_visibility (NAUTILUS_DESKTOP_LINK_MONITOR (callback_data
),
311 &monitor
->details
->network_link
,
312 NAUTILUS_DESKTOP_LINK_NETWORK
,
313 NAUTILUS_PREFERENCES_DESKTOP_NETWORK_VISIBLE
);
317 desktop_volumes_visible_changed (gpointer callback_data
)
319 NautilusDesktopLinkMonitor
*monitor
;
322 monitor
= NAUTILUS_DESKTOP_LINK_MONITOR (callback_data
);
324 if (eel_preferences_get_boolean (NAUTILUS_PREFERENCES_DESKTOP_VOLUMES_VISIBLE
)) {
325 if (monitor
->details
->mount_links
== NULL
) {
326 mounts
= g_volume_monitor_get_mounts (monitor
->details
->volume_monitor
);
327 for (l
= mounts
; l
!= NULL
; l
= l
->next
) {
328 create_mount_link (monitor
, l
->data
);
329 g_object_unref (l
->data
);
331 g_list_free (mounts
);
334 g_list_foreach (monitor
->details
->mount_links
, (GFunc
)g_object_unref
, NULL
);
335 g_list_free (monitor
->details
->mount_links
);
336 monitor
->details
->mount_links
= NULL
;
341 create_link_and_add_preference (NautilusDesktopLink
**link_ref
,
342 NautilusDesktopLinkType link_type
,
343 const char *preference_key
,
344 EelPreferencesCallback callback
,
345 gpointer callback_data
)
347 if (eel_preferences_get_boolean (preference_key
)) {
348 *link_ref
= nautilus_desktop_link_new (link_type
);
351 eel_preferences_add_callback (preference_key
, callback
, callback_data
);
355 nautilus_desktop_link_monitor_init (gpointer object
, gpointer klass
)
357 NautilusDesktopLinkMonitor
*monitor
;
361 monitor
= NAUTILUS_DESKTOP_LINK_MONITOR (object
);
363 the_link_monitor
= monitor
;
365 monitor
->details
= g_new0 (NautilusDesktopLinkMonitorDetails
, 1);
367 monitor
->details
->volume_monitor
= g_volume_monitor_get ();
369 /* We keep around a ref to the desktop dir */
370 monitor
->details
->desktop_dir
= nautilus_directory_get_by_uri (EEL_DESKTOP_URI
);
374 create_link_and_add_preference (&monitor
->details
->home_link
,
375 NAUTILUS_DESKTOP_LINK_HOME
,
376 NAUTILUS_PREFERENCES_DESKTOP_HOME_VISIBLE
,
377 desktop_home_visible_changed
,
380 create_link_and_add_preference (&monitor
->details
->computer_link
,
381 NAUTILUS_DESKTOP_LINK_COMPUTER
,
382 NAUTILUS_PREFERENCES_DESKTOP_COMPUTER_VISIBLE
,
383 desktop_computer_visible_changed
,
386 create_link_and_add_preference (&monitor
->details
->trash_link
,
387 NAUTILUS_DESKTOP_LINK_TRASH
,
388 NAUTILUS_PREFERENCES_DESKTOP_TRASH_VISIBLE
,
389 desktop_trash_visible_changed
,
392 create_link_and_add_preference (&monitor
->details
->network_link
,
393 NAUTILUS_DESKTOP_LINK_NETWORK
,
394 NAUTILUS_PREFERENCES_DESKTOP_NETWORK_VISIBLE
,
395 desktop_network_visible_changed
,
400 mounts
= g_volume_monitor_get_mounts (monitor
->details
->volume_monitor
);
401 for (l
= mounts
; l
!= NULL
; l
= l
->next
) {
403 create_mount_link (monitor
, mount
);
404 g_object_unref (mount
);
406 g_list_free (mounts
);
408 eel_preferences_add_callback (NAUTILUS_PREFERENCES_DESKTOP_VOLUMES_VISIBLE
,
409 desktop_volumes_visible_changed
,
412 monitor
->details
->mount_id
=
413 g_signal_connect_object (monitor
->details
->volume_monitor
, "mount_added",
414 G_CALLBACK (mount_added_callback
), monitor
, 0);
415 monitor
->details
->unmount_id
=
416 g_signal_connect_object (monitor
->details
->volume_monitor
, "mount_removed",
417 G_CALLBACK (mount_removed_callback
), monitor
, 0);
418 monitor
->details
->changed_id
=
419 g_signal_connect_object (monitor
->details
->volume_monitor
, "mount_changed",
420 G_CALLBACK (mount_changed_callback
), monitor
, 0);
425 remove_link_and_preference (NautilusDesktopLink
**link_ref
,
426 const char *preference_key
,
427 EelPreferencesCallback callback
,
428 gpointer callback_data
)
430 if (*link_ref
!= NULL
) {
431 g_object_unref (*link_ref
);
435 eel_preferences_remove_callback (preference_key
, callback
, callback_data
);
439 desktop_link_monitor_finalize (GObject
*object
)
441 NautilusDesktopLinkMonitor
*monitor
;
443 monitor
= NAUTILUS_DESKTOP_LINK_MONITOR (object
);
445 g_object_unref (monitor
->details
->volume_monitor
);
449 remove_link_and_preference (&monitor
->details
->home_link
,
450 NAUTILUS_PREFERENCES_DESKTOP_HOME_VISIBLE
,
451 desktop_home_visible_changed
,
454 remove_link_and_preference (&monitor
->details
->computer_link
,
455 NAUTILUS_PREFERENCES_DESKTOP_COMPUTER_VISIBLE
,
456 desktop_computer_visible_changed
,
459 remove_link_and_preference (&monitor
->details
->trash_link
,
460 NAUTILUS_PREFERENCES_DESKTOP_TRASH_VISIBLE
,
461 desktop_trash_visible_changed
,
464 remove_link_and_preference (&monitor
->details
->network_link
,
465 NAUTILUS_PREFERENCES_DESKTOP_NETWORK_VISIBLE
,
466 desktop_network_visible_changed
,
471 g_list_foreach (monitor
->details
->mount_links
, (GFunc
)g_object_unref
, NULL
);
472 g_list_free (monitor
->details
->mount_links
);
473 monitor
->details
->mount_links
= NULL
;
475 nautilus_directory_unref (monitor
->details
->desktop_dir
);
476 monitor
->details
->desktop_dir
= NULL
;
478 eel_preferences_remove_callback (NAUTILUS_PREFERENCES_DESKTOP_VOLUMES_VISIBLE
,
479 desktop_volumes_visible_changed
,
482 if (monitor
->details
->mount_id
!= 0) {
483 g_source_remove (monitor
->details
->mount_id
);
485 if (monitor
->details
->unmount_id
!= 0) {
486 g_source_remove (monitor
->details
->unmount_id
);
488 if (monitor
->details
->changed_id
!= 0) {
489 g_source_remove (monitor
->details
->changed_id
);
492 g_free (monitor
->details
);
494 EEL_CALL_PARENT (G_OBJECT_CLASS
, finalize
, (object
));
498 nautilus_desktop_link_monitor_class_init (gpointer klass
)
500 GObjectClass
*object_class
;
502 object_class
= G_OBJECT_CLASS (klass
);
504 object_class
->finalize
= desktop_link_monitor_finalize
;