diff options
author | Carlos Soriano <csoriano@gnome.org> | 2016-04-15 10:35:34 +0200 |
---|---|---|
committer | Carlos Soriano <csoriano@gnome.org> | 2016-04-15 20:12:01 +0200 |
commit | 73e10fadc922e75a0858bf29e23e524cb9681851 (patch) | |
tree | b574237d706815d67f46ca9e59d4b6768d6026b0 /nautilus-desktop/nautilus-desktop-link-monitor.c | |
parent | d1a1c798e62571f14d64c22334ae7043203e4a13 (diff) | |
download | nautilus-73e10fadc922e75a0858bf29e23e524cb9681851.tar.gz |
desktop: move to a different folder
For a better structured hierarchy.
https://bugzilla.gnome.org/show_bug.cgi?id=712620
Diffstat (limited to 'nautilus-desktop/nautilus-desktop-link-monitor.c')
-rw-r--r-- | nautilus-desktop/nautilus-desktop-link-monitor.c | 432 |
1 files changed, 432 insertions, 0 deletions
diff --git a/nautilus-desktop/nautilus-desktop-link-monitor.c b/nautilus-desktop/nautilus-desktop-link-monitor.c new file mode 100644 index 000000000..54ce6daf9 --- /dev/null +++ b/nautilus-desktop/nautilus-desktop-link-monitor.c @@ -0,0 +1,432 @@ +/* + nautilus-desktop-link-monitor.c: singleton thatn manages the links + + Copyright (C) 2003 Red Hat, Inc. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public + License along with this program; if not, see <http://www.gnu.org/licenses/>. + + Author: Alexander Larsson <alexl@redhat.com> +*/ + +#include <config.h> +#include "nautilus-desktop-link-monitor.h" +#include "nautilus-desktop-link.h" +#include "nautilus-desktop-icon-file.h" +#include "nautilus-desktop-directory.h" + +#include <eel/eel-debug.h> +#include <eel/eel-vfs-extensions.h> +#include <eel/eel-stock-dialogs.h> +#include <gtk/gtk.h> +#include <glib/gi18n.h> +#include <gio/gio.h> + +#include <libnautilus-private/nautilus-trash-monitor.h> +#include <libnautilus-private/nautilus-global-preferences.h> +#include <libnautilus-private/nautilus-directory.h> + +#include <string.h> + +struct NautilusDesktopLinkMonitorDetails { + GVolumeMonitor *volume_monitor; + NautilusDirectory *desktop_dir; + + NautilusDesktopLink *home_link; + NautilusDesktopLink *trash_link; + NautilusDesktopLink *network_link; + + GList *mount_links; +}; + +G_DEFINE_TYPE (NautilusDesktopLinkMonitor, nautilus_desktop_link_monitor, G_TYPE_OBJECT); + +static NautilusDesktopLinkMonitor *the_link_monitor = NULL; + +void +nautilus_desktop_link_monitor_shutdown (void) +{ + g_clear_object (&the_link_monitor); +} + +NautilusDesktopLinkMonitor * +nautilus_desktop_link_monitor_get (void) +{ + if (the_link_monitor == NULL) { + g_object_new (NAUTILUS_TYPE_DESKTOP_LINK_MONITOR, NULL); + eel_debug_call_at_shutdown (nautilus_desktop_link_monitor_shutdown); + } + return the_link_monitor; +} + +static gboolean +volume_file_name_used (NautilusDesktopLinkMonitor *monitor, + const char *name) +{ + GList *l; + char *other_name; + gboolean same; + + for (l = monitor->details->mount_links; l != NULL; l = l->next) { + other_name = nautilus_desktop_link_get_file_name (l->data); + same = strcmp (name, other_name) == 0; + g_free (other_name); + + if (same) { + return TRUE; + } + } + + return FALSE; +} + +char * +nautilus_desktop_link_monitor_make_filename_unique (NautilusDesktopLinkMonitor *monitor, + const char *filename) +{ + char *unique_name; + int i; + + i = 2; + unique_name = g_strdup (filename); + while (volume_file_name_used (monitor, unique_name)) { + g_free (unique_name); + unique_name = g_strdup_printf ("%s.%d", filename, i++); + } + return unique_name; +} + +static gboolean +has_mount (NautilusDesktopLinkMonitor *monitor, + GMount *mount) +{ + gboolean ret; + GMount *other_mount; + GList *l; + + ret = FALSE; + + for (l = monitor->details->mount_links; l != NULL; l = l->next) { + other_mount = nautilus_desktop_link_get_mount (l->data); + if (mount == other_mount) { + g_object_unref (other_mount); + ret = TRUE; + break; + } + g_object_unref (other_mount); + } + + return ret; +} + +static void +create_mount_link (NautilusDesktopLinkMonitor *monitor, + GMount *mount) +{ + NautilusDesktopLink *link; + + if (has_mount (monitor, mount)) + return; + + if ((!g_mount_is_shadowed (mount)) && + g_settings_get_boolean (nautilus_desktop_preferences, + NAUTILUS_PREFERENCES_DESKTOP_VOLUMES_VISIBLE)) { + link = nautilus_desktop_link_new_from_mount (mount); + monitor->details->mount_links = g_list_prepend (monitor->details->mount_links, link); + } +} + +static void +remove_mount_link (NautilusDesktopLinkMonitor *monitor, + GMount *mount) +{ + GList *l; + NautilusDesktopLink *link; + GMount *other_mount; + + link = NULL; + for (l = monitor->details->mount_links; l != NULL; l = l->next) { + other_mount = nautilus_desktop_link_get_mount (l->data); + if (mount == other_mount) { + g_object_unref (other_mount); + link = l->data; + break; + } + g_object_unref (other_mount); + } + + if (link) { + monitor->details->mount_links = g_list_remove (monitor->details->mount_links, link); + g_object_unref (link); + } +} + + + +static void +mount_added_callback (GVolumeMonitor *volume_monitor, + GMount *mount, + NautilusDesktopLinkMonitor *monitor) +{ + create_mount_link (monitor, mount); +} + + +static void +mount_removed_callback (GVolumeMonitor *volume_monitor, + GMount *mount, + NautilusDesktopLinkMonitor *monitor) +{ + remove_mount_link (monitor, mount); +} + +static void +mount_changed_callback (GVolumeMonitor *volume_monitor, + GMount *mount, + NautilusDesktopLinkMonitor *monitor) +{ + /* TODO: update the mount with other details */ + + /* remove a mount if it goes into the shadows */ + if (g_mount_is_shadowed (mount) && has_mount (monitor, mount)) { + remove_mount_link (monitor, mount); + }} + +static void +update_link_visibility (NautilusDesktopLinkMonitor *monitor, + NautilusDesktopLink **link_ref, + NautilusDesktopLinkType link_type, + const char *preference_key) +{ + if (g_settings_get_boolean (nautilus_desktop_preferences, preference_key)) { + if (*link_ref == NULL) { + *link_ref = nautilus_desktop_link_new (link_type); + } + } else { + if (*link_ref != NULL) { + g_object_unref (*link_ref); + *link_ref = NULL; + } + } +} + +static void +desktop_home_visible_changed (gpointer callback_data) +{ + NautilusDesktopLinkMonitor *monitor; + + monitor = NAUTILUS_DESKTOP_LINK_MONITOR (callback_data); + + update_link_visibility (NAUTILUS_DESKTOP_LINK_MONITOR (monitor), + &monitor->details->home_link, + NAUTILUS_DESKTOP_LINK_HOME, + NAUTILUS_PREFERENCES_DESKTOP_HOME_VISIBLE); +} + +static void +desktop_trash_visible_changed (gpointer callback_data) +{ + NautilusDesktopLinkMonitor *monitor; + + monitor = NAUTILUS_DESKTOP_LINK_MONITOR (callback_data); + + update_link_visibility (NAUTILUS_DESKTOP_LINK_MONITOR (callback_data), + &monitor->details->trash_link, + NAUTILUS_DESKTOP_LINK_TRASH, + NAUTILUS_PREFERENCES_DESKTOP_TRASH_VISIBLE); +} + +static void +desktop_network_visible_changed (gpointer callback_data) +{ + NautilusDesktopLinkMonitor *monitor; + + monitor = NAUTILUS_DESKTOP_LINK_MONITOR (callback_data); + + update_link_visibility (NAUTILUS_DESKTOP_LINK_MONITOR (callback_data), + &monitor->details->network_link, + NAUTILUS_DESKTOP_LINK_NETWORK, + NAUTILUS_PREFERENCES_DESKTOP_NETWORK_VISIBLE); +} + +static void +desktop_volumes_visible_changed (gpointer callback_data) +{ + NautilusDesktopLinkMonitor *monitor; + GList *l, *mounts; + + monitor = NAUTILUS_DESKTOP_LINK_MONITOR (callback_data); + + if (g_settings_get_boolean (nautilus_desktop_preferences, + NAUTILUS_PREFERENCES_DESKTOP_VOLUMES_VISIBLE)) { + if (monitor->details->mount_links == NULL) { + mounts = g_volume_monitor_get_mounts (monitor->details->volume_monitor); + for (l = mounts; l != NULL; l = l->next) { + create_mount_link (monitor, l->data); + g_object_unref (l->data); + } + g_list_free (mounts); + } + } else { + g_list_foreach (monitor->details->mount_links, (GFunc)g_object_unref, NULL); + g_list_free (monitor->details->mount_links); + monitor->details->mount_links = NULL; + } +} + +static void +create_link_and_add_preference (NautilusDesktopLink **link_ref, + NautilusDesktopLinkType link_type, + const char *preference_key, + GCallback callback, + gpointer callback_data) +{ + char *detailed_signal; + + if (g_settings_get_boolean (nautilus_desktop_preferences, preference_key)) { + *link_ref = nautilus_desktop_link_new (link_type); + } + + detailed_signal = g_strconcat ("changed::", preference_key, NULL); + g_signal_connect_swapped (nautilus_desktop_preferences, + detailed_signal, + callback, callback_data); + + g_free (detailed_signal); +} + +static void +nautilus_desktop_link_monitor_init (NautilusDesktopLinkMonitor *monitor) +{ + GList *l, *mounts; + GMount *mount; + + monitor->details = G_TYPE_INSTANCE_GET_PRIVATE (monitor, NAUTILUS_TYPE_DESKTOP_LINK_MONITOR, + NautilusDesktopLinkMonitorDetails); + + the_link_monitor = monitor; + monitor->details->volume_monitor = g_volume_monitor_get (); + + /* We keep around a ref to the desktop dir */ + monitor->details->desktop_dir = nautilus_directory_get_by_uri (EEL_DESKTOP_URI); + + /* Default links */ + + create_link_and_add_preference (&monitor->details->home_link, + NAUTILUS_DESKTOP_LINK_HOME, + NAUTILUS_PREFERENCES_DESKTOP_HOME_VISIBLE, + G_CALLBACK (desktop_home_visible_changed), + monitor); + + create_link_and_add_preference (&monitor->details->trash_link, + NAUTILUS_DESKTOP_LINK_TRASH, + NAUTILUS_PREFERENCES_DESKTOP_TRASH_VISIBLE, + G_CALLBACK (desktop_trash_visible_changed), + monitor); + + create_link_and_add_preference (&monitor->details->network_link, + NAUTILUS_DESKTOP_LINK_NETWORK, + NAUTILUS_PREFERENCES_DESKTOP_NETWORK_VISIBLE, + G_CALLBACK (desktop_network_visible_changed), + monitor); + + /* Mount links */ + + mounts = g_volume_monitor_get_mounts (monitor->details->volume_monitor); + for (l = mounts; l != NULL; l = l->next) { + mount = l->data; + create_mount_link (monitor, mount); + g_object_unref (mount); + } + g_list_free (mounts); + + g_signal_connect_swapped (nautilus_desktop_preferences, + "changed::" NAUTILUS_PREFERENCES_DESKTOP_VOLUMES_VISIBLE, + G_CALLBACK (desktop_volumes_visible_changed), + monitor); + + g_signal_connect_object (monitor->details->volume_monitor, "mount-added", + G_CALLBACK (mount_added_callback), monitor, 0); + g_signal_connect_object (monitor->details->volume_monitor, "mount-removed", + G_CALLBACK (mount_removed_callback), monitor, 0); + g_signal_connect_object (monitor->details->volume_monitor, "mount-changed", + G_CALLBACK (mount_changed_callback), monitor, 0); +} + +static void +remove_link_and_preference (NautilusDesktopLink **link_ref, + const char *preference_key, + GCallback callback, + gpointer callback_data) +{ + if (*link_ref != NULL) { + g_object_unref (*link_ref); + *link_ref = NULL; + } + + g_signal_handlers_disconnect_by_func (nautilus_desktop_preferences, + callback, callback_data); +} + +static void +desktop_link_monitor_finalize (GObject *object) +{ + NautilusDesktopLinkMonitor *monitor; + + monitor = NAUTILUS_DESKTOP_LINK_MONITOR (object); + + /* Default links */ + + remove_link_and_preference (&monitor->details->home_link, + NAUTILUS_PREFERENCES_DESKTOP_HOME_VISIBLE, + G_CALLBACK (desktop_home_visible_changed), + monitor); + + remove_link_and_preference (&monitor->details->trash_link, + NAUTILUS_PREFERENCES_DESKTOP_TRASH_VISIBLE, + G_CALLBACK (desktop_trash_visible_changed), + monitor); + + remove_link_and_preference (&monitor->details->network_link, + NAUTILUS_PREFERENCES_DESKTOP_NETWORK_VISIBLE, + G_CALLBACK (desktop_network_visible_changed), + monitor); + + /* Mounts */ + + g_list_foreach (monitor->details->mount_links, (GFunc)g_object_unref, NULL); + g_list_free (monitor->details->mount_links); + monitor->details->mount_links = NULL; + + nautilus_directory_unref (monitor->details->desktop_dir); + monitor->details->desktop_dir = NULL; + + g_signal_handlers_disconnect_by_func (nautilus_desktop_preferences, + desktop_volumes_visible_changed, + monitor); + + g_object_unref (monitor->details->volume_monitor); + + G_OBJECT_CLASS (nautilus_desktop_link_monitor_parent_class)->finalize (object); +} + +static void +nautilus_desktop_link_monitor_class_init (NautilusDesktopLinkMonitorClass *klass) +{ + GObjectClass *object_class; + + object_class = G_OBJECT_CLASS (klass); + object_class->finalize = desktop_link_monitor_finalize; + + g_type_class_add_private (klass, sizeof (NautilusDesktopLinkMonitorDetails)); +} |