[Xfce4-commits] <xfdesktop:master> Port XfdesktopVolumeIcon to GIO. A few other refactorings included.

Jannis Pohlmann noreply at xfce.org
Tue Nov 2 01:14:44 CET 2010


Updating branch refs/heads/master
         to f5d4f6d41fb5e9717446688d7e14d43b03296389 (commit)
       from dac08811c7e623655a5de0920a1c9f912f516b10 (commit)

commit f5d4f6d41fb5e9717446688d7e14d43b03296389
Author: Jannis Pohlmann <jannis at xfce.org>
Date:   Fri Oct 29 21:33:57 2010 +0200

    Port XfdesktopVolumeIcon to GIO. A few other refactorings included.
    
    What doesn't work at the moment is mounting + opening removable volumes
    by activating their icons. This will only mount them, not open them. It
    is easy to fix however.

 src/xfdesktop-file-icon-manager.c |  132 ++++----
 src/xfdesktop-file-utils.c        |  109 +++++--
 src/xfdesktop-file-utils.h        |   13 +-
 src/xfdesktop-regular-file-icon.c |   23 +-
 src/xfdesktop-special-file-icon.c |    9 +-
 src/xfdesktop-volume-icon.c       |  661 +++++++++++++++++++++----------------
 src/xfdesktop-volume-icon.h       |    8 +-
 7 files changed, 550 insertions(+), 405 deletions(-)

diff --git a/src/xfdesktop-file-icon-manager.c b/src/xfdesktop-file-icon-manager.c
index 2f0c981..c59bf03 100644
--- a/src/xfdesktop-file-icon-manager.c
+++ b/src/xfdesktop-file-icon-manager.c
@@ -108,6 +108,8 @@ struct _XfdesktopFileIconManagerPrivate
     XfdesktopFileIcon *desktop_icon;
     GFileMonitor *monitor;
     GFileEnumerator *enumerator;
+
+    GVolumeMonitor *volume_monitor;
     
     GHashTable *icons;
     GHashTable *removable_icons;
@@ -208,7 +210,6 @@ static const GtkTargetEntry drop_targets[] = {
 static const gint n_drop_targets = (sizeof(drop_targets)/sizeof(drop_targets[0]));
 
 static XfdesktopClipboardManager *clipboard_manager = NULL;
-static ThunarVfsVolumeManager *thunar_volume_manager = NULL;
 
 static GQuark xfdesktop_app_info_quark = 0;
 
@@ -1963,11 +1964,11 @@ xfdesktop_file_icon_manager_add_regular_icon(XfdesktopFileIconManager *fmanager,
 
 static XfdesktopFileIcon *
 xfdesktop_file_icon_manager_add_volume_icon(XfdesktopFileIconManager *fmanager,
-                                            ThunarVfsVolume *volume)
+                                            GVolume *volume)
 {
     XfdesktopVolumeIcon *icon;
     
-    g_return_val_if_fail(fmanager && volume, NULL);
+    g_return_val_if_fail(fmanager && G_IS_VOLUME(volume), NULL);
     
     /* should never return NULL */
     icon = xfdesktop_volume_icon_new(volume, fmanager->priv->gscreen);
@@ -2321,8 +2322,7 @@ static void
 xfdesktop_file_icon_manager_load_desktop_folder(XfdesktopFileIconManager *fmanager)
 {
     if(fmanager->priv->deferred_icons) {
-        g_list_foreach(fmanager->priv->deferred_icons,
-                       (GFunc)thunar_vfs_info_unref, NULL);
+        g_list_foreach(fmanager->priv->deferred_icons, (GFunc)g_object_unref, NULL);
         g_list_free(fmanager->priv->deferred_icons);
         fmanager->priv->deferred_icons = NULL;
     }
@@ -2376,12 +2376,12 @@ xfdesktop_file_icon_manager_clipboard_changed(XfdesktopClipboardManager *cmanage
 
 
 static void
-xfdesktop_file_icon_manager_volume_changed(ThunarVfsVolume *volume,
+xfdesktop_file_icon_manager_volume_changed(GVolume *volume,
                                            gpointer user_data)
 {
     XfdesktopFileIconManager *fmanager = XFDESKTOP_FILE_ICON_MANAGER(user_data);
     XfdesktopIcon *icon;
-    gboolean is_present = thunar_vfs_volume_is_present(volume);
+    gboolean is_present = xfdesktop_file_utils_volume_is_present(volume);
     
     icon = g_hash_table_lookup(fmanager->priv->removable_icons, volume);
 
@@ -2395,12 +2395,12 @@ xfdesktop_file_icon_manager_volume_changed(ThunarVfsVolume *volume,
 
 static void
 xfdesktop_file_icon_manager_add_removable_volume(XfdesktopFileIconManager *fmanager,
-                                                 ThunarVfsVolume *volume)
+                                                 GVolume *volume)
 {
-    if(!thunar_vfs_volume_is_removable(volume))
+    if(!xfdesktop_file_utils_volume_is_removable(volume))
         return;
     
-    if(thunar_vfs_volume_is_present(volume))
+    if(xfdesktop_file_utils_volume_is_present(volume))
         xfdesktop_file_icon_manager_add_volume_icon(fmanager, volume);
     
     g_signal_connect(G_OBJECT(volume), "changed",
@@ -2409,37 +2409,27 @@ xfdesktop_file_icon_manager_add_removable_volume(XfdesktopFileIconManager *fmana
 }
 
 static void
-xfdesktop_file_icon_manager_volumes_added(ThunarVfsVolumeManager *vmanager,
-                                          GList *volumes,
-                                          gpointer user_data)
+xfdesktop_file_icon_manager_volume_added(GVolumeMonitor *monitor,
+                                         GVolume *volume,
+                                         gpointer user_data)
 {
     XfdesktopFileIconManager *fmanager = XFDESKTOP_FILE_ICON_MANAGER(user_data);
-    GList *l;
-    ThunarVfsVolume *volume;
-    
-    for(l = volumes; l; l = l->next) {
-        volume = THUNAR_VFS_VOLUME(l->data);
-        xfdesktop_file_icon_manager_add_removable_volume(fmanager, volume);
-    }
+
+    xfdesktop_file_icon_manager_add_removable_volume(fmanager, volume);
 }
 
 static void
-xfdesktop_file_icon_manager_volumes_removed(ThunarVfsVolumeManager *vmanager,
-                                            GList *volumes,
-                                            gpointer user_data)
+xfdesktop_file_icon_manager_volume_removed(GVolumeMonitor *monitor,
+                                           GVolume *volume,
+                                           gpointer user_data)
 {
     XfdesktopFileIconManager *fmanager = XFDESKTOP_FILE_ICON_MANAGER(user_data);
-    GList *l;
-    ThunarVfsVolume *volume;
     XfdesktopIcon *icon;
     
-    for(l = volumes; l; l = l->next) {
-        volume = THUNAR_VFS_VOLUME(l->data);
-        icon = g_hash_table_lookup(fmanager->priv->removable_icons, volume);
-        if(icon) {
-            xfdesktop_icon_view_remove_item(fmanager->priv->icon_view, icon);
-            g_hash_table_remove(fmanager->priv->removable_icons, volume);
-        }
+    icon = g_hash_table_lookup(fmanager->priv->removable_icons, volume);
+    if(icon) {
+        xfdesktop_icon_view_remove_item(fmanager->priv->icon_view, icon);
+        g_hash_table_remove(fmanager->priv->removable_icons, volume);
     }
 }
 
@@ -2447,37 +2437,35 @@ static void
 xfdesktop_file_icon_manager_load_removable_media(XfdesktopFileIconManager *fmanager)
 {
     GList *volumes, *l;
-    ThunarVfsVolume *volume;
     
     /* ensure we don't re-enter if we're already set up */
     if(fmanager->priv->removable_icons)
         return;
     
-    if(!thunar_volume_manager) {
-        thunar_volume_manager = thunar_vfs_volume_manager_get_default();
-        g_object_add_weak_pointer(G_OBJECT(thunar_volume_manager),
-                                  (gpointer)&thunar_volume_manager);
+    if(!fmanager->priv->volume_monitor) {
+        fmanager->priv->volume_monitor = g_volume_monitor_get();
+        g_object_add_weak_pointer(G_OBJECT(fmanager->priv->volume_monitor),
+                                  (gpointer)&fmanager->priv->volume_monitor);
     } else
-       g_object_ref(G_OBJECT(thunar_volume_manager));
+       g_object_ref(G_OBJECT(fmanager->priv->volume_monitor));
     
     fmanager->priv->removable_icons = g_hash_table_new_full(g_direct_hash,
                                                             g_direct_equal,
                                                             (GDestroyNotify)g_object_unref,
                                                             (GDestroyNotify)g_object_unref);
     
-    volumes = thunar_vfs_volume_manager_get_volumes(thunar_volume_manager);
-    
+    volumes = g_volume_monitor_get_volumes(fmanager->priv->volume_monitor);
     for(l = volumes; l; l = l->next) {
-        volume = THUNAR_VFS_VOLUME(l->data);
-        xfdesktop_file_icon_manager_add_removable_volume(fmanager,
-                                                         volume);
+        xfdesktop_file_icon_manager_add_removable_volume(fmanager, l->data);
+        g_object_unref(l->data);
     }
+    g_list_free(volumes);
     
-    g_signal_connect(G_OBJECT(thunar_volume_manager), "volumes-added",
-                     G_CALLBACK(xfdesktop_file_icon_manager_volumes_added),
+    g_signal_connect(G_OBJECT(fmanager->priv->volume_monitor), "volume-added",
+                     G_CALLBACK(xfdesktop_file_icon_manager_volume_added),
                      fmanager);
-    g_signal_connect(G_OBJECT(thunar_volume_manager), "volumes-removed",
-                     G_CALLBACK(xfdesktop_file_icon_manager_volumes_removed),
+    g_signal_connect(G_OBJECT(fmanager->priv->volume_monitor), "volume-removed",
+                     G_CALLBACK(xfdesktop_file_icon_manager_volume_removed),
                      fmanager);
 }
 
@@ -2488,6 +2476,14 @@ xfdesktop_file_icon_manager_ht_remove_removable_media(gpointer key,
 {
     XfdesktopIcon *icon = XFDESKTOP_ICON(value);
     XfdesktopFileIconManager *fmanager = XFDESKTOP_FILE_ICON_MANAGER(user_data);
+    GVolume *volume;
+
+    volume = xfdesktop_volume_icon_peek_volume(XFDESKTOP_VOLUME_ICON(icon));
+    if(volume) {
+        g_signal_handlers_disconnect_by_func(volume,
+                                             G_CALLBACK(xfdesktop_file_icon_manager_volume_changed),
+                                             fmanager);
+    }
     
     xfdesktop_icon_view_remove_item(fmanager->priv->icon_view, icon);
 }
@@ -2495,33 +2491,24 @@ xfdesktop_file_icon_manager_ht_remove_removable_media(gpointer key,
 static void
 xfdesktop_file_icon_manager_remove_removable_media(XfdesktopFileIconManager *fmanager)
 {
-    GList *volumes, *l;
-    
-    if(!fmanager->priv->removable_icons)
-        return;
-    
-    volumes = thunar_vfs_volume_manager_get_volumes(thunar_volume_manager);
-    for(l = volumes; l; l = l->next) {
-        g_signal_handlers_disconnect_by_func(G_OBJECT(l->data),
-                                             G_CALLBACK(xfdesktop_file_icon_manager_volume_changed),
-                                             fmanager);
+    if(fmanager->priv->removable_icons) {
+        g_hash_table_foreach(fmanager->priv->removable_icons,
+                             xfdesktop_file_icon_manager_ht_remove_removable_media,
+                             fmanager);
+        g_hash_table_destroy(fmanager->priv->removable_icons);
+        fmanager->priv->removable_icons = NULL;
     }
     
-    g_hash_table_foreach(fmanager->priv->removable_icons,
-                         xfdesktop_file_icon_manager_ht_remove_removable_media,
-                         fmanager);
-    g_hash_table_destroy(fmanager->priv->removable_icons);
-    fmanager->priv->removable_icons = NULL;
-    
-    g_signal_handlers_disconnect_by_func(G_OBJECT(thunar_volume_manager),
-                                         G_CALLBACK(xfdesktop_file_icon_manager_volumes_added),
-                                         fmanager);
-    g_signal_handlers_disconnect_by_func(G_OBJECT(thunar_volume_manager),
-                                         G_CALLBACK(xfdesktop_file_icon_manager_volumes_removed),
-                                         fmanager);
+    if(fmanager->priv->volume_monitor) {
+        g_signal_handlers_disconnect_by_func(G_OBJECT(fmanager->priv->volume_monitor),
+                                             G_CALLBACK(xfdesktop_file_icon_manager_volume_added),
+                                             fmanager);
+        g_signal_handlers_disconnect_by_func(G_OBJECT(fmanager->priv->volume_monitor),
+                                             G_CALLBACK(xfdesktop_file_icon_manager_volume_removed),
+                                             fmanager);
     
-    DBG("refcnt of volmanager: %d", G_OBJECT(thunar_volume_manager)->ref_count);
-    g_object_unref(G_OBJECT(thunar_volume_manager));
+        g_object_unref(fmanager->priv->volume_monitor);
+    }
 }
 
 
@@ -2687,8 +2674,7 @@ xfdesktop_file_icon_manager_fini(XfdesktopIconViewManager *manager)
     }
     
     if(fmanager->priv->deferred_icons) {
-        g_list_foreach(fmanager->priv->deferred_icons,
-                       (GFunc)g_object_unref, NULL);
+        g_list_foreach(fmanager->priv->deferred_icons, (GFunc)g_object_unref, NULL);
         g_list_free(fmanager->priv->deferred_icons);
         fmanager->priv->deferred_icons = NULL;
     }
diff --git a/src/xfdesktop-file-utils.c b/src/xfdesktop-file-utils.c
index a803002..6622d97 100644
--- a/src/xfdesktop-file-utils.c
+++ b/src/xfdesktop-file-utils.c
@@ -260,6 +260,72 @@ xfdesktop_file_utils_format_time_for_display(guint64 file_time)
   return g_strdup(_("Unknown"));
 }
 
+gboolean
+xfdesktop_file_utils_volume_is_present(GVolume *volume)
+{
+  gboolean has_media = FALSE;
+  gboolean is_shadowed = FALSE;
+  GDrive *drive;
+  GMount *mount;
+
+  g_return_val_if_fail(G_IS_VOLUME(volume), FALSE);
+
+  drive = g_volume_get_drive (volume);
+  if(drive) {
+      has_media = g_drive_has_media(drive);
+      g_object_unref(drive);
+  }
+
+  mount = g_volume_get_mount(volume);
+  if(mount) {
+      is_shadowed = g_mount_is_shadowed(mount);
+      g_object_unref(mount);
+  }
+
+  return has_media && !is_shadowed;
+}
+
+gboolean
+xfdesktop_file_utils_volume_is_removable(GVolume *volume)
+{
+  gboolean can_eject = FALSE;
+  gboolean can_mount = FALSE;
+  gboolean can_unmount = FALSE;
+  gboolean is_removable = FALSE;
+  GDrive *drive;
+  GMount *mount;
+
+  g_return_val_if_fail(G_IS_VOLUME(volume), FALSE);
+  
+  /* check if the volume can be ejected */
+  can_eject = g_volume_can_eject(volume);
+
+  /* determine the drive for the volume */
+  drive = g_volume_get_drive(volume);
+  if(drive) {
+      /*check if the drive media can be removed */
+      is_removable = g_drive_is_media_removable(drive);
+
+      /* release the drive */
+      g_object_unref(drive);
+  }
+
+  /* determine the mount for the volume (if it is mounted at all) */
+  mount = g_volume_get_mount(volume);
+  if(mount) {
+      /* check if the volume can be unmounted */
+      can_unmount = g_mount_can_unmount(mount);
+
+      /* release the mount */
+      g_object_unref(mount);
+  }
+
+  /* determine whether the device can be mounted */
+  can_mount = g_volume_can_mount(volume);
+
+  return can_eject || can_unmount || is_removable || can_mount;
+}
+
 GList *
 xfdesktop_file_utils_file_icon_list_to_file_list(GList *icon_list)
 {
@@ -350,11 +416,11 @@ xfdesktop_file_utils_get_fallback_icon(gint size)
 }
 
 GdkPixbuf *
-xfdesktop_file_utils_get_file_icon(const gchar *custom_icon_name,
-                                   GFileInfo *info,
-                                   gint size,
-                                   const GdkPixbuf *emblem,
-                                   guint opacity)
+xfdesktop_file_utils_get_icon(const gchar *custom_icon_name,
+                              GIcon *icon,
+                              gint size,
+                              const GdkPixbuf *emblem,
+                              guint opacity)
 {
     GtkIconTheme *itheme = gtk_icon_theme_get_default();
     GdkPixbuf *pix_theme = NULL, *pix = NULL;
@@ -364,24 +430,21 @@ xfdesktop_file_utils_get_file_icon(const gchar *custom_icon_name,
                                              ITHEME_FLAGS, NULL);
     }
     
-    if(!pix_theme && info) {
-        GIcon *icon = g_file_info_get_icon(info);
-        if(icon) {
-            if(G_IS_THEMED_ICON(icon)) {
-              GtkIconInfo *icon_info = gtk_icon_theme_lookup_by_gicon(itheme,
-                                                                      icon, size,
-                                                                      ITHEME_FLAGS);
-              if(icon_info) {
-                  pix_theme = gtk_icon_info_load_icon(icon_info, NULL);
-                  gtk_icon_info_free(icon_info);
-              }
-            } else if(G_IS_LOADABLE_ICON(icon)) {
-                GInputStream *stream = g_loadable_icon_load(G_LOADABLE_ICON(icon), 
-                                                            size, NULL, NULL, NULL);
-                if(stream) {
-                    pix = gdk_pixbuf_new_from_stream(stream, NULL, NULL);
-                    g_object_unref(stream);
-                }
+    if(!pix_theme && icon) {
+        if(G_IS_THEMED_ICON(icon)) {
+          GtkIconInfo *icon_info = gtk_icon_theme_lookup_by_gicon(itheme,
+                                                                  icon, size,
+                                                                  ITHEME_FLAGS);
+          if(icon_info) {
+              pix_theme = gtk_icon_info_load_icon(icon_info, NULL);
+              gtk_icon_info_free(icon_info);
+          }
+        } else if(G_IS_LOADABLE_ICON(icon)) {
+            GInputStream *stream = g_loadable_icon_load(G_LOADABLE_ICON(icon), 
+                                                        size, NULL, NULL, NULL);
+            if(stream) {
+                pix = gdk_pixbuf_new_from_stream(stream, NULL, NULL);
+                g_object_unref(stream);
             }
         }
     }
diff --git a/src/xfdesktop-file-utils.h b/src/xfdesktop-file-utils.h
index 603dfbf..200f30e 100644
--- a/src/xfdesktop-file-utils.h
+++ b/src/xfdesktop-file-utils.h
@@ -61,17 +61,20 @@ gboolean xfdesktop_file_utils_is_desktop_file(GFileInfo *info);
 gboolean xfdesktop_file_utils_file_is_executable(GFileInfo *info);
 gchar *xfdesktop_file_utils_format_time_for_display(guint64 file_time);
 
+gboolean xfdesktop_file_utils_volume_is_present(GVolume *volume);
+gboolean xfdesktop_file_utils_volume_is_removable(GVolume *volume);
+
 GList *xfdesktop_file_utils_file_icon_list_to_file_list(GList *icon_list);
 gchar *xfdesktop_file_utils_file_list_to_string(GList *file_list);
 void xfdesktop_file_utils_file_list_free(GList *file_list);
 
 GdkPixbuf *xfdesktop_file_utils_get_fallback_icon(gint size);
 
-GdkPixbuf *xfdesktop_file_utils_get_file_icon(const gchar *custom_icon_name,
-                                              GFileInfo *info,
-                                              gint size,
-                                              const GdkPixbuf *emblem,
-                                              guint opacity);
+GdkPixbuf *xfdesktop_file_utils_get_icon(const gchar *custom_icon_name,
+                                         GIcon *icon,
+                                         gint size,
+                                         const GdkPixbuf *emblem,
+                                         guint opacity);
 
 void xfdesktop_file_utils_set_window_cursor(GtkWindow *window,
                                             GdkCursorType cursor_type);
diff --git a/src/xfdesktop-regular-file-icon.c b/src/xfdesktop-regular-file-icon.c
index 2b23c3b..05afe76 100644
--- a/src/xfdesktop-regular-file-icon.c
+++ b/src/xfdesktop-regular-file-icon.c
@@ -219,6 +219,8 @@ xfdesktop_regular_file_icon_peek_pixbuf(XfdesktopIcon *icon,
         xfdesktop_regular_file_icon_invalidate_pixbuf(file_icon);
 
     if(!file_icon->priv->pix) {
+        GIcon *gicon = NULL;
+
         /* create a GFile for the $HOME/.thumbnails/ directory */
         gchar *thumbnail_dir_path = g_build_filename(xfce_get_homedir(), 
                                                      ".thumbnails", NULL);
@@ -280,11 +282,13 @@ xfdesktop_regular_file_icon_peek_pixbuf(XfdesktopIcon *icon,
                 }
             }
         }
+
+        if(file_icon->priv->file_info)
+            gicon = g_file_info_get_icon(file_icon->priv->file_info);
         
-        file_icon->priv->pix = xfdesktop_file_utils_get_file_icon(icon_name, 
-                                                                  file_icon->priv->file_info, 
-                                                                  size, emblem_pix,
-                                                                  file_icon->priv->pix_opacity);
+        file_icon->priv->pix = xfdesktop_file_utils_get_icon(icon_name, gicon, 
+                                                             size, emblem_pix,
+                                                             file_icon->priv->pix_opacity);
         
         file_icon->priv->cur_pix_size = size;
 
@@ -400,7 +404,7 @@ xfdesktop_regular_file_icon_do_drop_dest(XfdesktopIcon *icon,
 
         result = TRUE;
     } else {
-        GFile *parent, *dest_file;
+        GFile *parent, *dest_file = NULL;
         gchar *name;
         
         parent = g_file_get_parent(src_file);
@@ -430,10 +434,11 @@ xfdesktop_regular_file_icon_do_drop_dest(XfdesktopIcon *icon,
             xfdesktop_file_utils_transfer_file(action, src_file, dest_file,
                                                regular_file_icon->priv->gscreen);
 
+            g_object_unref(dest_file);
+
             result = TRUE;
         }
 
-        g_object_unref(dest_file);
         g_free(name);
     }
     
@@ -588,6 +593,12 @@ xfdesktop_regular_file_icon_update_file_info(XfdesktopFileIcon *icon,
 
     regular_file_icon->priv->file_info = g_object_ref(info);
 
+    if(regular_file_icon->priv->filesystem_info)
+        g_object_unref(regular_file_icon->priv->filesystem_info);
+    regular_file_icon->priv->filesystem_info = g_file_query_filesystem_info(regular_file_icon->priv->file,
+                                                                            XFDESKTOP_FILESYSTEM_INFO_NAMESPACE,
+                                                                            NULL, NULL);
+
     uri = g_file_get_uri(regular_file_icon->priv->file);
     path = thunar_vfs_path_new(uri, NULL);
     regular_file_icon->priv->info = thunar_vfs_info_new_for_path(path, NULL);
diff --git a/src/xfdesktop-special-file-icon.c b/src/xfdesktop-special-file-icon.c
index 828b806..d15e615 100644
--- a/src/xfdesktop-special-file-icon.c
+++ b/src/xfdesktop-special-file-icon.c
@@ -221,6 +221,7 @@ xfdesktop_special_file_icon_peek_pixbuf(XfdesktopIcon *icon,
         xfdesktop_special_file_icon_invalidate_pixbuf(file_icon);
     
     if(!file_icon->priv->pix) {
+        GIcon *gicon = NULL;
         const gchar *custom_icon_name = NULL;
 
         /* use a custom icon name for the local filesystem root */
@@ -229,10 +230,12 @@ xfdesktop_special_file_icon_peek_pixbuf(XfdesktopIcon *icon,
             custom_icon_name = "drive-harddisk";
         if(parent)
             g_object_unref(parent);
+
+        if(file_icon->priv->file_info)
+            gicon = g_file_info_get_icon(file_icon->priv->file_info);
         
-        file_icon->priv->pix = xfdesktop_file_utils_get_file_icon(custom_icon_name,
-                                                                  file_icon->priv->file_info,
-                                                                  size, NULL, 100);
+        file_icon->priv->pix = xfdesktop_file_utils_get_icon(custom_icon_name, gicon,
+                                                             size, NULL, 100);
         
         file_icon->priv->cur_pix_size = size;
     }
diff --git a/src/xfdesktop-volume-icon.c b/src/xfdesktop-volume-icon.c
index 87283dc..5c96f2d 100644
--- a/src/xfdesktop-volume-icon.c
+++ b/src/xfdesktop-volume-icon.c
@@ -36,10 +36,6 @@
 #include <time.h>
 #endif
 
-#ifdef HAVE_SYS_STATVFS_H
-#include <sys/statvfs.h>
-#endif
-
 #ifndef PATH_MAX
 #define PATH_MAX 4096
 #endif
@@ -52,6 +48,7 @@
 #include <thunarx/thunarx.h>
 #endif
 
+#include "xfdesktop-common.h"
 #include "xfdesktop-file-utils.h"
 #include "xfdesktop-volume-icon.h"
 
@@ -60,7 +57,8 @@ struct _XfdesktopVolumeIconPrivate
     GdkPixbuf *pix;
     gchar *tooltip;
     gint cur_pix_size;
-    ThunarVfsVolume *volume;
+    gchar *label;
+    GVolume *volume;
     ThunarVfsInfo *info;
     GFileInfo *file_info;
     GFileInfo *filesystem_info;
@@ -86,16 +84,14 @@ static G_CONST_RETURN ThunarVfsInfo *xfdesktop_volume_icon_peek_info(XfdesktopFi
 static GFileInfo *xfdesktop_volume_icon_peek_file_info(XfdesktopFileIcon *icon);
 static GFileInfo *xfdesktop_volume_icon_peek_filesystem_info(XfdesktopFileIcon *icon);
 static GFile *xfdesktop_volume_icon_peek_file(XfdesktopFileIcon *icon);
-static void xfdesktop_volume_icon_update_info(XfdesktopFileIcon *icon,
-                                              ThunarVfsInfo *info);
+static void xfdesktop_volume_icon_update_file_info(XfdesktopFileIcon *icon,
+                                                   GFileInfo *info);
 static gboolean xfdesktop_volume_icon_activated(XfdesktopIcon *icon);
 
 #ifdef HAVE_THUNARX
 static void xfdesktop_volume_icon_tfi_init(ThunarxFileInfoIface *iface);
 #endif
 
-static void xfdesktop_volume_icon_volume_changed_cb(ThunarVfsVolume *volume,
-                                                    gpointer user_data);
 static inline void xfdesktop_volume_icon_invalidate_pixbuf(XfdesktopVolumeIcon *icon);
 
 
@@ -136,7 +132,7 @@ xfdesktop_volume_icon_class_init(XfdesktopVolumeIconClass *klass)
     file_icon_class->peek_file_info = xfdesktop_volume_icon_peek_file_info;
     file_icon_class->peek_filesystem_info = xfdesktop_volume_icon_peek_filesystem_info;
     file_icon_class->peek_file = xfdesktop_volume_icon_peek_file;
-    file_icon_class->update_info = xfdesktop_volume_icon_update_info;
+    file_icon_class->update_file_info = xfdesktop_volume_icon_update_file_info;
     file_icon_class->can_rename_file = (gboolean (*)(XfdesktopFileIcon *))gtk_false;
     file_icon_class->can_delete_file = (gboolean (*)(XfdesktopFileIcon *))gtk_false;
 }
@@ -158,16 +154,26 @@ xfdesktop_volume_icon_finalize(GObject *obj)
                                          G_CALLBACK(xfdesktop_volume_icon_invalidate_pixbuf),
                                          icon);
     
-    g_signal_handlers_disconnect_by_func(G_OBJECT(icon->priv->volume),
-                                         G_CALLBACK(xfdesktop_volume_icon_volume_changed_cb),
-                                         icon);
+    if(icon->priv->label) {
+        g_free(icon->priv->label);
+        icon->priv->label = NULL;
+    }
     
     if(icon->priv->pix)
         g_object_unref(G_OBJECT(icon->priv->pix));
     
     if(icon->priv->info)
         thunar_vfs_info_unref(icon->priv->info);
-    
+
+    if(icon->priv->file_info)
+        g_object_unref(icon->priv->file_info);
+
+    if(icon->priv->filesystem_info)
+        g_object_unref(icon->priv->filesystem_info);
+
+    if(icon->priv->file)
+        g_object_unref(icon->priv->file);
+
     if(icon->priv->volume)
         g_object_unref(G_OBJECT(icon->priv->volume));
     
@@ -195,30 +201,6 @@ xfdesktop_volume_icon_tfi_init(ThunarxFileInfoIface *iface)
 #endif  /* HAVE_THUNARX */
 
 
-static void
-xfdesktop_volume_icon_volume_changed_cb(ThunarVfsVolume *volume,
-                                        gpointer user_data)
-{
-    XfdesktopFileIcon *file_icon = XFDESKTOP_FILE_ICON(user_data);
-    ThunarVfsPath *new_path;
-    
-    new_path = thunar_vfs_volume_get_mount_point(volume);
-    if(new_path) {
-        ThunarVfsInfo *new_info = thunar_vfs_info_new_for_path(new_path, NULL);
-        
-        if(new_info) {
-            xfdesktop_file_icon_update_info(file_icon, new_info);
-            thunar_vfs_info_unref(new_info);
-            return;
-        }
-        
-        /* |new_path| is owned by |volume| */
-    }
-    
-    /* both new and old info is NULL or stale */
-    xfdesktop_file_icon_update_info(file_icon, NULL);
-}
-
 static inline void
 xfdesktop_volume_icon_invalidate_pixbuf(XfdesktopVolumeIcon *icon)
 {
@@ -234,7 +216,6 @@ xfdesktop_volume_icon_peek_pixbuf(XfdesktopIcon *icon,
                                   gint size)
 {
     XfdesktopVolumeIcon *file_icon = XFDESKTOP_VOLUME_ICON(icon);
-    const gchar *icon_name;
     
     g_return_val_if_fail(XFDESKTOP_IS_VOLUME_ICON(icon), NULL);
     
@@ -242,12 +223,13 @@ xfdesktop_volume_icon_peek_pixbuf(XfdesktopIcon *icon,
         xfdesktop_volume_icon_invalidate_pixbuf(file_icon);
 
     if(!file_icon->priv->pix) {
-        icon_name = thunar_vfs_volume_lookup_icon_name(file_icon->priv->volume,
-                                                       gtk_icon_theme_get_default());
-        
-        file_icon->priv->pix = xfdesktop_file_utils_get_file_icon(icon_name, 
-                                                                  file_icon->priv->file_info,
-                                                                  size, NULL, 100);
+        GIcon *gicon = NULL;
+
+        if(file_icon->priv->volume)
+            gicon = g_volume_get_icon(file_icon->priv->volume);
+
+        file_icon->priv->pix = xfdesktop_file_utils_get_icon(NULL, gicon, size, 
+                                                             NULL, 100);
         
         file_icon->priv->cur_pix_size = size;
     }
@@ -258,14 +240,23 @@ xfdesktop_volume_icon_peek_pixbuf(XfdesktopIcon *icon,
 G_CONST_RETURN gchar *
 xfdesktop_volume_icon_peek_label(XfdesktopIcon *icon)
 {
+    XfdesktopVolumeIcon *volume_icon = XFDESKTOP_VOLUME_ICON(icon);
+
     g_return_val_if_fail(XFDESKTOP_IS_VOLUME_ICON(icon), NULL);
-    return thunar_vfs_volume_get_name(XFDESKTOP_VOLUME_ICON(icon)->priv->volume);
+    
+    if(!volume_icon->priv->label) {
+            volume_icon->priv->label = g_volume_get_name(volume_icon->priv->volume);
+    }
+
+    return volume_icon->priv->label;
 }
 
 static GdkDragAction
 xfdesktop_volume_icon_get_allowed_drag_actions(XfdesktopIcon *icon)
 {
     XfdesktopVolumeIcon *volume_icon = XFDESKTOP_VOLUME_ICON(icon);
+    GVolume *volume;
+    GMount *mount;
     
     /* volume icons more or less represent the volume's mount point, usually
      * (hopefully) a local path.  so when it's mounted, we certainly can't move
@@ -276,14 +267,19 @@ xfdesktop_volume_icon_get_allowed_drag_actions(XfdesktopIcon *icon)
     /* FIXME: should i allow all actions if not mounted as well, and try to
      * mount and resolve on drop? */
     
-    if(thunar_vfs_volume_is_mounted(volume_icon->priv->volume)) {
-        const ThunarVfsInfo *info = xfdesktop_file_icon_peek_info(XFDESKTOP_FILE_ICON(icon));
+    volume = xfdesktop_volume_icon_peek_volume(volume_icon);
+
+    mount = g_volume_get_mount(volume);
+    if(mount) {
+        GFileInfo *info = xfdesktop_file_icon_peek_file_info(XFDESKTOP_FILE_ICON(icon));
         if(info) {
-            if(info->flags & THUNAR_VFS_FILE_FLAGS_READABLE)
+            if(g_file_info_get_attribute_boolean(info, G_FILE_ATTRIBUTE_ACCESS_CAN_READ))
                 return GDK_ACTION_COPY | GDK_ACTION_LINK;
             else
                 return GDK_ACTION_LINK;
         }
+
+        g_object_unref(mount);
     }
     
     return 0;
@@ -293,74 +289,28 @@ static GdkDragAction
 xfdesktop_volume_icon_get_allowed_drop_actions(XfdesktopIcon *icon)
 {
     XfdesktopVolumeIcon *volume_icon = XFDESKTOP_VOLUME_ICON(icon);
+    GVolume *volume;
+    GMount *mount;
     
     /* if not mounted, it doesn't really make sense to allow any operations
      * here.  if mounted, we should allow everything if it's writable. */
     
     /* FIXME: should i allow all actions if not mounted as well, and try to
      * mount and resolve on drop? */
-    
-    if(thunar_vfs_volume_is_mounted(volume_icon->priv->volume)) {
-        const ThunarVfsInfo *info = xfdesktop_file_icon_peek_info(XFDESKTOP_FILE_ICON(icon));
-        if(info && info->flags & THUNAR_VFS_FILE_FLAGS_WRITABLE)
-            return GDK_ACTION_MOVE | GDK_ACTION_COPY | GDK_ACTION_LINK;
-    }
-    
-    return 0;
-}
 
-static void
-xfdesktop_volume_icon_drag_job_error(ThunarVfsJob *job,
-                                     GError *error,
-                                     gpointer user_data)
-{
-    XfdesktopVolumeIcon *volume_icon = XFDESKTOP_VOLUME_ICON(user_data);
-    XfdesktopFileIcon *src_file_icon = g_object_get_data(G_OBJECT(job),
-                                                         "--xfdesktop-src-file-icon");
-    XfdesktopFileUtilsFileop fileop = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(job),
-                                                                        "--xfdesktop-file-icon-action"));
-    const ThunarVfsInfo *src_info = xfdesktop_file_icon_peek_info(src_file_icon);
-    
-    g_return_if_fail(volume_icon);
-    
-    if(!src_file_icon)
-        return;
-    
-    xfdesktop_file_utils_handle_fileop_error(NULL, src_info,
-                                             volume_icon->priv->info,
-                                             fileop, error);
-}
-
-static ThunarVfsInteractiveJobResponse
-xfdesktop_volume_icon_interactive_job_ask(ThunarVfsJob *job,
-                                          const gchar *message,
-                                          ThunarVfsInteractiveJobResponse choices,
-                                          gpointer user_data)
-{
-    GtkWidget *icon_view = xfdesktop_icon_peek_icon_view(XFDESKTOP_ICON(user_data));
-    GtkWidget *toplevel = gtk_widget_get_toplevel(icon_view);
-    return xfdesktop_file_utils_interactive_job_ask(GTK_WINDOW(toplevel),
-                                                    message, choices);
-}
+    volume = xfdesktop_volume_icon_peek_volume(volume_icon);
 
-static void
-xfdesktop_volume_icon_drag_job_finished(ThunarVfsJob *job,
-                                        gpointer user_data)
-{
-    XfdesktopVolumeIcon *volume_icon = XFDESKTOP_VOLUME_ICON(user_data);
-    XfdesktopFileIcon *src_file_icon = g_object_get_data(G_OBJECT(job),
-                                                         "--xfdesktop-src-file-icon");
-    
-    if(!xfdesktop_file_icon_remove_active_job(XFDESKTOP_FILE_ICON(volume_icon), job))
-        g_critical("ThunarVfsJob 0x%p not found in active jobs list", job);
-    
-    if(!xfdesktop_file_icon_remove_active_job(src_file_icon, job))
-        g_critical("ThunarVfsJob 0x%p not found in active jobs list", job);
-    
-    g_object_unref(G_OBJECT(job));
+    mount = g_volume_get_mount(volume);
+    if(mount) {
+        GFileInfo *info = xfdesktop_file_icon_peek_file_info(XFDESKTOP_FILE_ICON(icon));
+        if(info) {
+            if(g_file_info_get_attribute_boolean(info, G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE))
+                return GDK_ACTION_MOVE | GDK_ACTION_COPY | GDK_ACTION_LINK;
+        }
+        g_object_unref(mount);
+    }
     
-    g_object_unref(G_OBJECT(src_file_icon));
-    g_object_unref(G_OBJECT(volume_icon));
+    return 0;
 }
 
 static gboolean
@@ -370,10 +320,10 @@ xfdesktop_volume_icon_do_drop_dest(XfdesktopIcon *icon,
 {
     XfdesktopVolumeIcon *volume_icon = XFDESKTOP_VOLUME_ICON(icon);
     XfdesktopFileIcon *src_file_icon = XFDESKTOP_FILE_ICON(src_icon);
-    const ThunarVfsInfo *src_info;
-    ThunarVfsJob *job = NULL;
-    const gchar *name;
-    ThunarVfsPath *dest_path;
+    GFileInfo *src_info;
+    GFile *src_file, *parent, *dest_file;
+    gboolean result = FALSE;
+    gchar *name;
     
     DBG("entering");
     
@@ -381,176 +331,293 @@ xfdesktop_volume_icon_do_drop_dest(XfdesktopIcon *icon,
     g_return_val_if_fail(xfdesktop_volume_icon_get_allowed_drop_actions(icon),
                          FALSE);
     
-    src_info = xfdesktop_file_icon_peek_info(src_file_icon);
+    src_file = xfdesktop_file_icon_peek_file(src_file_icon);
+
+    src_info = xfdesktop_file_icon_peek_file_info(src_file_icon);
     if(!src_info)
         return FALSE;
-    
-    if(thunar_vfs_path_is_root(src_info->path))
+
+    if(!volume_icon->priv->file_info)
         return FALSE;
-    
-    name = thunar_vfs_path_get_name(src_info->path);
-    if(!name)
+   
+    parent = g_file_get_parent(src_file);
+    if(!parent)
         return FALSE;
+    g_object_unref(parent);
         
-    dest_path = thunar_vfs_path_relative(volume_icon->priv->info->path,
-                                         name);
-    if(!dest_path)
+    name = g_file_get_basename(src_file);
+    if(!name)
         return FALSE;
     
     switch(action) {
         case GDK_ACTION_MOVE:
             DBG("doing move");
-            job = thunar_vfs_move_file(src_info->path, dest_path, NULL);
+            dest_file = g_object_ref(volume_icon->priv->file);
             break;
         
         case GDK_ACTION_COPY:
             DBG("doing copy");
-            job = thunar_vfs_copy_file(src_info->path, dest_path, NULL);
-                break;
+            dest_file = g_file_get_child(volume_icon->priv->file, name);
+            break;
         
         case GDK_ACTION_LINK:
             DBG("doing link");
-            job = thunar_vfs_link_file(src_info->path, dest_path, NULL);
+            dest_file = g_object_ref(volume_icon->priv->file);
             break;
         
         default:
             g_warning("Unsupported drag action: %d", action);
     }
-        
-    thunar_vfs_path_unref(dest_path);
+
+    if(dest_file) {
+        xfdesktop_file_utils_transfer_file(action, src_file, dest_file,
+                                           volume_icon->priv->gscreen);
     
-    if(job) {
-        DBG("got job, action initiated");
-        
-        /* ensure they aren't destroyed until the job is finished */
-        g_object_ref(G_OBJECT(src_file_icon));
-        g_object_ref(G_OBJECT(volume_icon));
-        
-        g_object_set_data(G_OBJECT(job), "--xfdesktop-file-icon-callback",
-                          G_CALLBACK(xfdesktop_volume_icon_drag_job_finished));
-        g_object_set_data(G_OBJECT(job), "--xfdesktop-file-icon-data", icon);
-        xfdesktop_file_icon_add_active_job(XFDESKTOP_FILE_ICON(volume_icon),
-                                           job);
-        xfdesktop_file_icon_add_active_job(src_file_icon, job);
-        
-        g_object_set_data(G_OBJECT(job), "--xfdesktop-src-file-icon",
-                          src_file_icon);
-        g_object_set_data(G_OBJECT(job), "--xfdesktop-file-icon-action",
-                          GINT_TO_POINTER(action == GDK_ACTION_MOVE
-                                          ? XFDESKTOP_FILE_UTILS_FILEOP_MOVE
-                                          : (action == GDK_ACTION_COPY
-                                             ? XFDESKTOP_FILE_UTILS_FILEOP_COPY
-                                             : XFDESKTOP_FILE_UTILS_FILEOP_LINK)));
-        g_signal_connect(G_OBJECT(job), "error",
-                         G_CALLBACK(xfdesktop_volume_icon_drag_job_error),
-                         volume_icon);
-        g_signal_connect(G_OBJECT(job), "ask",
-                         G_CALLBACK(xfdesktop_volume_icon_interactive_job_ask),
-                         volume_icon);
-        g_signal_connect(G_OBJECT(job), "finished",
-                         G_CALLBACK(xfdesktop_volume_icon_drag_job_finished),
-                         volume_icon);
-        
-        g_object_ref(G_OBJECT(job));
+        g_object_unref(dest_file);
+
+        result = TRUE;
+    }
+
+    g_free(name);
         
-        return TRUE;
-    } else
-        return FALSE;
-    
-    return FALSE;
+    return result;
 }
 
 static G_CONST_RETURN gchar *
 xfdesktop_volume_icon_peek_tooltip(XfdesktopIcon *icon)
 {
     XfdesktopVolumeIcon *volume_icon = XFDESKTOP_VOLUME_ICON(icon);
-    
-    if(!volume_icon->priv->info)
-        return NULL;
-    
-    /* FIXME: something different? */
+    GFileInfo *fs_info = xfdesktop_file_icon_peek_filesystem_info(XFDESKTOP_FILE_ICON(icon));
+    GFile *file = xfdesktop_file_icon_peek_file(XFDESKTOP_FILE_ICON(icon));
     
     if(!volume_icon->priv->tooltip) {
-        gchar freebuf[128], totbuf[128], *space;
-        ThunarVfsPath *path;
-        gchar mntpnt[THUNAR_VFS_PATH_MAXSTRLEN] = { 0, };
-        ThunarVfsFileSize size;
-        struct statvfs stfs;
-        
-        path = thunar_vfs_volume_get_mount_point(volume_icon->priv->volume);
-        if(path
-           && thunar_vfs_path_to_string(path, mntpnt, sizeof(mntpnt), NULL) > 0
-           && thunar_vfs_info_get_free_space(volume_icon->priv->info, &size)
-           && !statvfs(mntpnt, &stfs))
-        {
-            thunar_vfs_humanize_size(size, freebuf, sizeof(freebuf));
-            thunar_vfs_humanize_size((ThunarVfsFileSize)(stfs.f_blocks * stfs.f_bsize),
-                                     totbuf, sizeof(totbuf));
-            space = g_strdup_printf(_("%s (%s total)"), freebuf, totbuf);
-        } else
-            space = g_strdup(_("(unknown)"));
-        
-        volume_icon->priv->tooltip = g_strdup_printf(_("Kind: Removable Volume\n"
-                                                       "Mount Point: %s\n"
-                                                       "Free Space: %s"),
-                                                     *mntpnt ? mntpnt
-                                                             : _("(unknown)"),
-                                                     space);
-        
-        g_free(space);
-    }
+        guint64 size, free_space;
+        gchar *mount_point = NULL, *size_string = NULL, *free_space_string = NULL;
+
+        if(file && fs_info) {
+            mount_point = g_file_get_parse_name(file);
+
+            size = g_file_info_get_attribute_uint64(fs_info,
+                                                    G_FILE_ATTRIBUTE_FILESYSTEM_SIZE);
+            size_string = g_format_size_for_display(size);
+
+            free_space = g_file_info_get_attribute_uint64(fs_info,
+                                                          G_FILE_ATTRIBUTE_FILESYSTEM_FREE);
+            free_space_string = g_format_size_for_display(free_space);
+
+            volume_icon->priv->tooltip =
+                g_strdup_printf(_("Removable Volume\nMounted in \"%s\"\n%s left (%s total)"),
+                                mount_point, free_space_string, size_string);
     
+            g_free(free_space_string);
+            g_free(size_string);
+            g_free(mount_point);
+        } else {
+            volume_icon->priv->tooltip = g_strdup(_("Removable Volume\nNot mounted yet"));
+        }
+    }
+
     return volume_icon->priv->tooltip;
 }
 
 static void
-xfdesktop_volume_icon_menu_toggle_mount(GtkWidget *widget,
-                                        gpointer user_data)
+xfdesktop_volume_icon_eject_finish(GObject *object,
+                                   GAsyncResult *result,
+                                   gpointer user_data)
 {
     XfdesktopVolumeIcon *icon = XFDESKTOP_VOLUME_ICON(user_data);
     GtkWidget *icon_view = xfdesktop_icon_peek_icon_view(XFDESKTOP_ICON(icon));
-    GtkWidget *toplevel = gtk_widget_get_toplevel(icon_view);
+    GtkWidget *toplevel = icon_view ? gtk_widget_get_toplevel(icon_view) : NULL;
+    GVolume *volume = G_VOLUME(object);
     GError *error = NULL;
-    gboolean is_mount;
-    
-    is_mount = !thunar_vfs_volume_is_mounted(icon->priv->volume);
-    
-    if(!is_mount)
-        thunar_vfs_volume_unmount(icon->priv->volume, toplevel, &error);
-    else
-        thunar_vfs_volume_mount(icon->priv->volume, toplevel, &error);
-    
-    if(error) {
-        gchar *primary = g_markup_printf_escaped(is_mount ? _("Unable to mount \"%s\":")
-                                                          : _("Unable to unmount \"%s\":"),
-                                                 thunar_vfs_volume_get_name(icon->priv->volume));
-        xfce_message_dialog(toplevel ? GTK_WINDOW(toplevel) : NULL,
-                            is_mount ? _("Mount Failed") : _("Unmount Failed"),
-                            GTK_STOCK_DIALOG_ERROR, primary, error->message,
-                            GTK_STOCK_CLOSE, GTK_RESPONSE_ACCEPT, NULL);
-        g_free(primary);
+      
+    g_return_if_fail(G_IS_VOLUME(object));
+    g_return_if_fail(G_IS_ASYNC_RESULT(result));
+    g_return_if_fail(XFDESKTOP_IS_VOLUME_ICON(icon));
+
+    if(!g_volume_eject_finish(volume, result, &error)) {
+        /* ignore GIO errors handled internally */
+        if(error->domain != G_IO_ERROR || error->code != G_IO_ERROR_FAILED_HANDLED) {
+            gchar *volume_name = g_volume_get_name(volume);
+            gchar *primary = g_markup_printf_escaped(_("Failed to eject \"%s\""), 
+                                                     volume_name);
+
+            /* display an error dialog to inform the user */
+            xfce_message_dialog(toplevel ? GTK_WINDOW(toplevel) : NULL,
+                                _("Eject Failed"), GTK_STOCK_DIALOG_ERROR, 
+                                primary, error->message,
+                                GTK_STOCK_CLOSE, GTK_RESPONSE_ACCEPT, NULL);
+
+            g_free(primary);
+            g_free(volume_name);
+        }
+
         g_error_free(error);
     }
+
+#ifdef HAVE_LIBNOTIFY
+#if 0
+    xfdesktop_notify_eject_finish(mount);
+#endif
+#endif
+
+    g_object_unref(icon);
 }
 
 static void
-xfdesktop_volume_icon_menu_eject(GtkWidget *widget,
-                                 gpointer user_data)
+xfdesktop_volume_icon_unmount_finish(GObject *object,
+                                     GAsyncResult *result,
+                                     gpointer user_data)
 {
     XfdesktopVolumeIcon *icon = XFDESKTOP_VOLUME_ICON(user_data);
+    GtkWidget *icon_view = xfdesktop_icon_peek_icon_view(XFDESKTOP_ICON(icon));
+    GtkWidget *toplevel = gtk_widget_get_toplevel(icon_view);
+    GMount *mount = G_MOUNT(object);
     GError *error = NULL;
+      
+    g_return_if_fail(G_IS_MOUNT(object));
+    g_return_if_fail(G_IS_ASYNC_RESULT(result));
+    g_return_if_fail(XFDESKTOP_IS_VOLUME_ICON(icon));
+
+    if(!g_mount_unmount_finish(mount, result, &error)) {
+        /* ignore GIO errors handled internally */
+        if(error->domain != G_IO_ERROR || error->code != G_IO_ERROR_FAILED_HANDLED) {
+            gchar *mount_name = g_mount_get_name(mount);
+            gchar *primary = g_markup_printf_escaped(_("Failed to eject \"%s\""), 
+                                                     mount_name);
+
+            /* display an error dialog to inform the user */
+            xfce_message_dialog(toplevel ? GTK_WINDOW(toplevel) : NULL,
+                                _("Eject Failed"), GTK_STOCK_DIALOG_ERROR, 
+                                primary, error->message,
+                                GTK_STOCK_CLOSE, GTK_RESPONSE_ACCEPT, NULL);
+
+            g_free(primary);
+            g_free(mount_name);
+        }
+
+        g_error_free(error);
+    }
+
+#ifdef HAVE_LIBNOTIFY
+#if 0
+    xfdesktop_notify_unmount_finish(mount);
+#endif
+#endif
+
+    g_object_unref(icon);
+}
+
+static void
+xfdesktop_volume_icon_mount_finish(GObject *object,
+                                   GAsyncResult *result,
+                                   gpointer user_data)
+{
+    XfdesktopVolumeIcon *icon = XFDESKTOP_VOLUME_ICON(user_data);
     GtkWidget *icon_view = xfdesktop_icon_peek_icon_view(XFDESKTOP_ICON(icon));
     GtkWidget *toplevel = gtk_widget_get_toplevel(icon_view);
-    
-    if(!thunar_vfs_volume_eject(icon->priv->volume, toplevel, &error)) {
-        gchar *primary = g_markup_printf_escaped(_("Unable to eject \"%s\":"),
-                                                 thunar_vfs_volume_get_name(icon->priv->volume));
-        xfce_message_dialog(GTK_WINDOW(toplevel),
-                            _("Eject Failed"), GTK_STOCK_DIALOG_ERROR,
-                            primary, error->message,
-                            GTK_STOCK_CLOSE, GTK_RESPONSE_ACCEPT, NULL);
-        g_free(primary);
+    GVolume *volume = G_VOLUME(object);
+    GError *error = NULL;
+
+    if(!g_volume_mount_finish(volume, result, &error)) {
+        if(error->domain != G_IO_ERROR || error->code != G_IO_ERROR_FAILED_HANDLED) {
+            gchar *volume_name = g_volume_get_name(volume);
+            gchar *primary = g_markup_printf_escaped(_("Failed to mount \"%s\""),
+                                                     volume_name);
+            xfce_message_dialog(toplevel ? GTK_WINDOW(toplevel) : NULL,
+                                _("Mount Failed"), GTK_STOCK_DIALOG_ERROR, 
+                                primary, error->message,
+                                GTK_STOCK_CLOSE, GTK_RESPONSE_ACCEPT, NULL);
+            g_free(primary);
+            g_free(volume_name);
+        }
+        
         g_error_free(error);
+    } else {
+        GMount *mount = g_volume_get_mount(volume);
+        GFile *file = NULL;
+        GFileInfo *info = NULL;
+
+        if(mount) {
+            file = g_mount_get_root(mount);
+            info = g_file_query_info(file,
+                                     XFDESKTOP_FILE_INFO_NAMESPACE,
+                                     G_FILE_QUERY_INFO_NONE,
+                                     NULL, NULL);
+            g_object_unref(mount);
+        }
+
+        if(file && info) {
+            if(icon->priv->file)
+                g_object_unref(icon->priv->file);
+            icon->priv->file = g_object_ref(file);
+
+            xfdesktop_file_icon_update_file_info(XFDESKTOP_FILE_ICON(icon), info);
+        } else {
+            if(icon->priv->file)
+                g_object_unref(icon->priv->file);
+            icon->priv->file = NULL;
+
+            xfdesktop_file_icon_update_file_info(XFDESKTOP_FILE_ICON(icon), NULL);
+        }
+            
+        if(file)
+            g_object_unref(file);
+
+        if(info)
+            g_object_unref(info);
+    }
+}
+
+static void
+xfdesktop_volume_icon_menu_toggle_mount(GtkWidget *widget,
+                                        gpointer user_data)
+{
+    XfdesktopVolumeIcon *icon = XFDESKTOP_VOLUME_ICON(user_data);
+    GtkWidget *icon_view = xfdesktop_icon_peek_icon_view(XFDESKTOP_ICON(icon));
+    GtkWidget *toplevel = gtk_widget_get_toplevel(icon_view);
+    GVolume *volume;
+    GMount *mount;
+    
+    volume = xfdesktop_volume_icon_peek_volume(icon);
+    mount = g_volume_get_mount(volume);
+    
+    if(mount) {
+        if(g_volume_can_eject(volume)) {
+#ifdef HAVE_LIBNOTIFY
+#if 0
+            /* TODO */
+            xfdesktop_notify_eject(volume);
+#endif
+#endif
+
+            g_volume_eject(volume, G_MOUNT_UNMOUNT_NONE, NULL,
+                           xfdesktop_volume_icon_eject_finish,
+                           g_object_ref(icon));
+        } else {
+#ifdef HAVE_LIBNOTIFY
+#if 0
+            /* TODO */
+            xfdesktop_notify_unmount(mount);
+#endif
+#endif
+
+            g_mount_unmount(mount, G_MOUNT_UNMOUNT_NONE, NULL,
+                            xfdesktop_volume_icon_unmount_finish, 
+                            g_object_ref(icon));
+        }
+    } else {
+        GMountOperation *operation;
+
+        operation = gtk_mount_operation_new(toplevel ? GTK_WINDOW(toplevel) : NULL);
+        gtk_mount_operation_set_screen(GTK_MOUNT_OPERATION(operation),
+                                       icon->priv->gscreen);
+
+        g_volume_mount(volume, G_MOUNT_MOUNT_NONE, operation, NULL,
+                       xfdesktop_volume_icon_mount_finish, 
+                       g_object_ref(icon));
+
+        g_object_unref(operation);
     }
 }
 
@@ -572,9 +639,10 @@ xfdesktop_volume_icon_populate_context_menu(XfdesktopIcon *icon,
                                             GtkWidget *menu)
 {
     XfdesktopVolumeIcon *volume_icon = XFDESKTOP_VOLUME_ICON(icon);
-    ThunarVfsVolume *volume = volume_icon->priv->volume;
+    GVolume *volume = volume_icon->priv->volume;
     GtkWidget *mi, *img;
-    gboolean mounted, ejectable;
+    GMount *mount;
+    const gchar *icon_name, *icon_label;
     
     img = gtk_image_new_from_stock(GTK_STOCK_OPEN, GTK_ICON_SIZE_MENU);
     gtk_widget_show(img);
@@ -589,35 +657,34 @@ xfdesktop_volume_icon_populate_context_menu(XfdesktopIcon *icon,
     gtk_widget_show(mi);
     gtk_menu_shell_append(GTK_MENU_SHELL(menu), mi);
     
-    mounted = thunar_vfs_volume_is_mounted(volume);
-    ejectable = thunar_vfs_volume_is_ejectable(volume);
+    mount = g_volume_get_mount(volume);
 
-    if(!mounted || (mounted && !ejectable)) {
-        if(mounted) {
-            img = gtk_image_new_from_stock(GTK_STOCK_DISCONNECT, GTK_ICON_SIZE_MENU);
-            mi = gtk_image_menu_item_new_with_mnemonic(_("_Unmount Volume"));
-        } else {
-            img = gtk_image_new_from_stock(GTK_STOCK_CONNECT, GTK_ICON_SIZE_MENU);
-            mi = gtk_image_menu_item_new_with_mnemonic(_("_Mount Volume"));
+    if(mount) {
+        if(g_volume_can_eject(volume)) {
+            icon_name = "media-eject";
+            icon_label = _("E_ject Volume");
+        } else if(g_mount_can_unmount(mount)) {
+            icon_name = "media-eject";
+            icon_label = _("E_ject Volume");
+        }
+
+        g_object_unref(mount);
+    } else {
+        if(g_volume_can_mount(volume)) {
+            icon_name = NULL;
+            icon_label = _("_Mount Volume");
         }
-        gtk_widget_show(img);
-        gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(mi), img);
-        gtk_widget_show(mi);
-        gtk_menu_shell_append(GTK_MENU_SHELL(menu), mi);
-        g_signal_connect(G_OBJECT(mi), "activate",
-                         G_CALLBACK(xfdesktop_volume_icon_menu_toggle_mount),
-                         icon);
     }
 
-    if(ejectable) {
-        img = gtk_image_new_from_icon_name("media-eject", GTK_ICON_SIZE_MENU);
+    if(xfdesktop_file_utils_volume_is_removable(volume) && icon_label) {
+        img = gtk_image_new_from_icon_name(icon_name, GTK_ICON_SIZE_MENU);
         gtk_widget_show(img);
-        mi = gtk_image_menu_item_new_with_mnemonic(_("E_ject Volume"));
+        mi = gtk_image_menu_item_new_with_mnemonic(icon_label);
         gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(mi), img);
         gtk_widget_show(mi);
         gtk_menu_shell_append(GTK_MENU_SHELL(menu), mi);
         g_signal_connect(G_OBJECT(mi), "activate",
-                         G_CALLBACK(xfdesktop_volume_icon_menu_eject),
+                         G_CALLBACK(xfdesktop_volume_icon_menu_toggle_mount),
                          icon);
     }
 
@@ -672,29 +739,35 @@ xfdesktop_volume_icon_peek_file(XfdesktopFileIcon *icon)
 }
 
 static void
-xfdesktop_volume_icon_update_info(XfdesktopFileIcon *icon,
-                                  ThunarVfsInfo *info)
+xfdesktop_volume_icon_update_file_info(XfdesktopFileIcon *icon,
+                                       GFileInfo *info)
 {
     XfdesktopVolumeIcon *volume_icon = XFDESKTOP_VOLUME_ICON(icon);
-    gboolean label_changed = TRUE;
-    
+
     g_return_if_fail(XFDESKTOP_IS_VOLUME_ICON(icon));
-    
-    if(volume_icon->priv->info) {
-        if(info && !strcmp(volume_icon->priv->info->display_name,
-                           info->display_name))
-        {
-            label_changed = FALSE;
-        }
-    
-        thunar_vfs_info_unref(volume_icon->priv->info);
+
+    DBG("entering");
+
+    /* just replace the file info here */
+    if(volume_icon->priv->file_info)
+        g_object_unref(volume_icon->priv->file_info);
+    volume_icon->priv->file_info = info ? g_object_ref(info) : NULL;
+
+    /* update the filesystem info as well */
+    if(volume_icon->priv->filesystem_info)
+        g_object_unref(volume_icon->priv->filesystem_info);
+    if(volume_icon->priv->file) {
+        volume_icon->priv->filesystem_info = g_file_query_filesystem_info(volume_icon->priv->file,
+                                                                          XFDESKTOP_FILE_INFO_NAMESPACE,
+                                                                          NULL, NULL);
     }
-    
-    volume_icon->priv->info = info ? thunar_vfs_info_ref(info) : NULL;
-    
-    if(label_changed)
-        xfdesktop_icon_label_changed(XFDESKTOP_ICON(icon));
-    
+
+    /* invalidate the tooltip */
+    if(volume_icon->priv->tooltip) {
+        g_free(volume_icon->priv->tooltip);
+        volume_icon->priv->tooltip = NULL;
+    }
+
     /* not really easy to check if this changed or not, so just invalidate it */
     xfdesktop_volume_icon_invalidate_pixbuf(volume_icon);
     xfdesktop_icon_pixbuf_changed(XFDESKTOP_ICON(icon));
@@ -704,49 +777,57 @@ static gboolean
 xfdesktop_volume_icon_activated(XfdesktopIcon *icon_p)
 {
     XfdesktopVolumeIcon *icon = XFDESKTOP_VOLUME_ICON(icon_p);
-    ThunarVfsVolume *volume = (ThunarVfsVolume *)xfdesktop_volume_icon_peek_volume(icon);
+    GVolume *volume = xfdesktop_volume_icon_peek_volume(icon);
+    GMount *mount;
     
     TRACE("entering");
+
+    mount = g_volume_get_mount(volume);
     
-    if(!thunar_vfs_volume_is_mounted(volume)) {
+    if(!mount) {
+        /* TODO we need to call the parent classes activated handler
+         * in the mount callback in order to open the mount point in
+         * the file manager */
         xfdesktop_volume_icon_menu_toggle_mount(NULL, icon);
-        if(!thunar_vfs_volume_is_mounted(volume))
-            return TRUE;  /* mount failed; halt signal emission */
+        return TRUE;
+    } else {
+        g_object_unref(mount);
     }
     
     /* chain up */
     return XFDESKTOP_ICON_CLASS(xfdesktop_volume_icon_parent_class)->activated(icon_p);
 }
 
-
-
 XfdesktopVolumeIcon *
-xfdesktop_volume_icon_new(ThunarVfsVolume *volume,
+xfdesktop_volume_icon_new(GVolume *volume,
                           GdkScreen *screen)
 {
     XfdesktopVolumeIcon *volume_icon;
-    ThunarVfsPath *path;
+    GMount *mount;
     
-    g_return_val_if_fail(THUNAR_VFS_IS_VOLUME(volume), NULL);
+    g_return_val_if_fail(G_IS_VOLUME(volume), NULL);
     
     volume_icon = g_object_new(XFDESKTOP_TYPE_VOLUME_ICON, NULL);
     volume_icon->priv->volume = g_object_ref(G_OBJECT(volume));
     volume_icon->priv->gscreen = screen;
-    
-    path = thunar_vfs_volume_get_mount_point(volume);
-    if(path) {
-        volume_icon->priv->info = thunar_vfs_info_new_for_path(path, NULL);
-        /* |path| is owned by |volume|, do not free */
+
+    mount = g_volume_get_mount(volume);
+    if(mount) {
+        volume_icon->priv->file = g_mount_get_root(mount);
+        volume_icon->priv->file_info = g_file_query_info(volume_icon->priv->file,
+                                                         XFDESKTOP_FILE_INFO_NAMESPACE,
+                                                         G_FILE_QUERY_INFO_NONE,
+                                                         NULL, NULL);
+        volume_icon->priv->filesystem_info = g_file_query_filesystem_info(volume_icon->priv->file,
+                                                                          XFDESKTOP_FILESYSTEM_INFO_NAMESPACE,
+                                                                          NULL, NULL);
+        g_object_unref(mount);
     }
     
-    g_signal_connect(G_OBJECT(volume), "changed",
-                     G_CALLBACK(xfdesktop_volume_icon_volume_changed_cb),
-                     volume_icon);
-    
     return volume_icon;
 }
 
-G_CONST_RETURN ThunarVfsVolume *
+GVolume *
 xfdesktop_volume_icon_peek_volume(XfdesktopVolumeIcon *icon)
 {
     g_return_val_if_fail(XFDESKTOP_IS_VOLUME_ICON(icon), NULL);
diff --git a/src/xfdesktop-volume-icon.h b/src/xfdesktop-volume-icon.h
index 5ff0fd2..506c54a 100644
--- a/src/xfdesktop-volume-icon.h
+++ b/src/xfdesktop-volume-icon.h
@@ -21,9 +21,7 @@
 #ifndef __XFDESKTOP_VOLUME_ICON_H__
 #define __XFDESKTOP_VOLUME_ICON_H__
 
-#include <glib-object.h>
-
-#include <thunar-vfs/thunar-vfs.h>
+#include <gio/gio.h>
 
 #include "xfdesktop-file-icon.h"
 
@@ -52,10 +50,10 @@ struct _XfdesktopVolumeIconClass
 
 GType xfdesktop_volume_icon_get_type(void) G_GNUC_CONST;
 
-XfdesktopVolumeIcon *xfdesktop_volume_icon_new(ThunarVfsVolume *volume,
+XfdesktopVolumeIcon *xfdesktop_volume_icon_new(GVolume *volume,
                                                GdkScreen *screen);
 
-G_CONST_RETURN ThunarVfsVolume *xfdesktop_volume_icon_peek_volume(XfdesktopVolumeIcon *icon);
+GVolume *xfdesktop_volume_icon_peek_volume(XfdesktopVolumeIcon *icon);
 
 
 G_END_DECLS



More information about the Xfce4-commits mailing list