2008-05-05 Paolo Borelli <pborelli@katamail.com>
[nautilus.git] / libnautilus-private / nautilus-desktop-link-monitor.c
blob1151e7bdb6773011b832791ef29ae5ed8f6aa537
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>
25 #include <config.h>
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>
42 #include <gio/gio.h>
43 #include <libnautilus-private/nautilus-trash-monitor.h>
44 #include <string.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;
55 gulong mount_id;
56 gulong unmount_id;
57 gulong changed_id;
59 GList *mount_links;
63 static void nautilus_desktop_link_monitor_init (gpointer object,
64 gpointer klass);
65 static void nautilus_desktop_link_monitor_class_init (gpointer klass);
67 EEL_CLASS_BOILERPLATE (NautilusDesktopLinkMonitor,
68 nautilus_desktop_link_monitor,
69 G_TYPE_OBJECT)
71 static NautilusDesktopLinkMonitor *the_link_monitor = NULL;
73 static void
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;
91 static void
92 volume_delete_dialog (GtkWidget *parent_view,
93 NautilusDesktopLink *link)
95 GMount *mount;
96 char *dialog_str;
97 char *display_name;
99 mount = nautilus_desktop_link_get_mount (link);
101 if (mount != NULL) {
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."),
104 display_name);
105 g_free (display_name);
107 if (g_mount_can_eject (mount)) {
108 eel_run_simple_dialog
109 (parent_view,
110 FALSE,
111 GTK_MESSAGE_ERROR,
112 dialog_str,
113 _("If you want to eject the volume, please use \"Eject\" in the "
114 "popup menu of the volume."),
115 GTK_STOCK_OK, NULL);
116 } else {
117 eel_run_simple_dialog
118 (parent_view,
119 FALSE,
120 GTK_MESSAGE_ERROR,
121 dialog_str,
122 _("If you want to unmount the volume, please use \"Unmount Volume\" in the "
123 "popup menu of the volume."),
124 GTK_STOCK_OK, NULL);
127 g_object_unref (mount);
128 g_free (dialog_str);
132 void
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 */
143 break;
144 default:
145 volume_delete_dialog (parent_view, link);
146 break;
150 static gboolean
151 volume_file_name_used (NautilusDesktopLinkMonitor *monitor,
152 const char *name)
154 GList *l;
155 char *other_name;
156 gboolean same;
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;
161 g_free (other_name);
163 if (same) {
164 return TRUE;
168 return FALSE;
171 char *
172 nautilus_desktop_link_monitor_make_filename_unique (NautilusDesktopLinkMonitor *monitor,
173 const char *filename)
175 char *unique_name;
176 int i;
178 i = 2;
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++);
184 return unique_name;
187 static void
188 create_mount_link (NautilusDesktopLinkMonitor *monitor,
189 GMount *mount)
191 NautilusDesktopLink *link;
193 link = NULL;
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);
203 static void
204 mount_added_callback (GVolumeMonitor *volume_monitor,
205 GMount *mount,
206 NautilusDesktopLinkMonitor *monitor)
208 create_mount_link (monitor, mount);
212 static void
213 mount_removed_callback (GVolumeMonitor *volume_monitor,
214 GMount *mount,
215 NautilusDesktopLinkMonitor *monitor)
217 GList *l;
218 NautilusDesktopLink *link;
219 GMount *other_mount;
221 link = NULL;
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);
226 link = l->data;
227 break;
229 g_object_unref (other_mount);
232 if (link) {
233 monitor->details->mount_links = g_list_remove (monitor->details->mount_links, link);
234 g_object_unref (link);
238 static void
239 mount_changed_callback (GVolumeMonitor *volume_monitor,
240 GMount *mount,
241 NautilusDesktopLinkMonitor *monitor)
243 /* TODO: update the mount */
246 static void
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);
256 } else {
257 if (*link_ref != NULL) {
258 g_object_unref (*link_ref);
259 *link_ref = NULL;
264 static void
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);
277 static void
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);
290 static void
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);
303 static void
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);
316 static void
317 desktop_volumes_visible_changed (gpointer callback_data)
319 NautilusDesktopLinkMonitor *monitor;
320 GList *l, *mounts;
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);
333 } else {
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;
340 static void
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);
354 static void
355 nautilus_desktop_link_monitor_init (gpointer object, gpointer klass)
357 NautilusDesktopLinkMonitor *monitor;
358 GList *l, *mounts;
359 GMount *mount;
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);
372 /* Default links */
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,
378 monitor);
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,
384 monitor);
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,
390 monitor);
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,
396 monitor);
398 /* Mount links */
400 mounts = g_volume_monitor_get_mounts (monitor->details->volume_monitor);
401 for (l = mounts; l != NULL; l = l->next) {
402 mount = l->data;
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,
410 monitor);
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);
424 static void
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);
432 *link_ref = NULL;
435 eel_preferences_remove_callback (preference_key, callback, callback_data);
438 static void
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);
447 /* Default links */
449 remove_link_and_preference (&monitor->details->home_link,
450 NAUTILUS_PREFERENCES_DESKTOP_HOME_VISIBLE,
451 desktop_home_visible_changed,
452 monitor);
454 remove_link_and_preference (&monitor->details->computer_link,
455 NAUTILUS_PREFERENCES_DESKTOP_COMPUTER_VISIBLE,
456 desktop_computer_visible_changed,
457 monitor);
459 remove_link_and_preference (&monitor->details->trash_link,
460 NAUTILUS_PREFERENCES_DESKTOP_TRASH_VISIBLE,
461 desktop_trash_visible_changed,
462 monitor);
464 remove_link_and_preference (&monitor->details->network_link,
465 NAUTILUS_PREFERENCES_DESKTOP_NETWORK_VISIBLE,
466 desktop_network_visible_changed,
467 monitor);
469 /* Mounts */
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,
480 monitor);
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));
497 static void
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;