[gthumb] allow to mount unmounted volumes



commit 63fa3f441c9182945c9ff62e60f4a644c407e317
Author: Paolo Bacchilega <paobac src gnome org>
Date:   Sun May 30 10:37:32 2021 +0200

    allow to mount unmounted volumes

 gthumb/glib-utils.h          |   1 +
 gthumb/gth-browser.c         | 113 +++++++++++++++++++++++++++++++++++++++++--
 gthumb/gth-file-source-vfs.c |  85 +++++++++++++++++++++++++++++++-
 gthumb/gth-folder-tree.c     |   7 +--
 gthumb/gth-main.c            |  23 ++++-----
 gthumb/gth-main.h            |   2 +-
 gthumb/gth-vfs-tree.c        |   7 ++-
 7 files changed, 216 insertions(+), 22 deletions(-)
---
diff --git a/gthumb/glib-utils.h b/gthumb/glib-utils.h
index 6470f09d..8df99254 100644
--- a/gthumb/glib-utils.h
+++ b/gthumb/glib-utils.h
@@ -67,6 +67,7 @@ G_BEGIN_DECLS
 #define GFILE_STANDARD_ATTRIBUTES_WITH_CONTENT_TYPE 
DEFINE_STANDARD_ATTRIBUTES(",standard::fast-content-type,standard::content-type")
 #define GIO_ATTRIBUTES 
"standard::*,etag::*,id::*,access::*,mountable::*,time::*,unix::*,dos::*,owner::*,thumbnail::*,filesystem::*,gvfs::*,xattr::*,xattr-sys::*,selinux::*"
 #define GTH_FILE_ATTRIBUTE_EMBLEMS "gth::file::emblems"
+#define GTH_FILE_ATTRIBUTE_VOLUME "gth::volume"
 
 #define GNOME_COPIED_FILES gdk_atom_intern_static_string ("x-special/gnome-copied-files")
 #define IROUND(x) ((int)floor(((double)x) + 0.5))
diff --git a/gthumb/gth-browser.c b/gthumb/gth-browser.c
index cc920179..6dbebdd6 100644
--- a/gthumb/gth-browser.c
+++ b/gthumb/gth-browser.c
@@ -1716,6 +1716,88 @@ mount_volume_ready_cb (GObject      *source_object,
 }
 
 
+static void
+mount_mountable_ready_cb (GObject      *source_object,
+                         GAsyncResult *result,
+                         gpointer      user_data)
+{
+       LoadData *load_data = user_data;
+       GError   *error = NULL;
+
+       if (! g_file_start_mountable_finish (G_FILE (source_object),
+                                            result,
+                                            &error))
+       {
+               load_data_done (load_data, error);
+               load_data_free (load_data);
+               return;
+       }
+
+       gth_monitor_entry_points_changed (gth_main_get_default_monitor ());
+       _gth_browser_update_entry_point_list (load_data->browser);
+
+       /* try to load again */
+
+       if (! load_data_is_still_relevant (load_data)) {
+               load_data_cancelled (load_data);
+               return;
+       }
+
+       _gth_browser_remove_activity (load_data->browser);
+
+       _gth_browser_load (load_data->browser,
+                          load_data->requested_folder->file,
+                          load_data->file_to_select,
+                          NULL,
+                          0,
+                          load_data->action,
+                          load_data->automatic);
+
+       load_data_free (load_data);
+}
+
+
+static void
+volume_mount_ready_cb (GObject      *source_object,
+                      GAsyncResult *result,
+                      gpointer      user_data)
+{
+       LoadData *load_data = user_data;
+       GError   *error = NULL;
+
+       if (! g_volume_mount_finish (G_VOLUME (source_object),
+                                    result,
+                                    &error))
+       {
+               load_data_done (load_data, error);
+               load_data_free (load_data);
+               return;
+       }
+
+       gth_monitor_entry_points_changed (gth_main_get_default_monitor ());
+       _gth_browser_update_entry_point_list (load_data->browser);
+
+       /* try to load again */
+
+       if (! load_data_is_still_relevant (load_data)) {
+               load_data_cancelled (load_data);
+               return;
+       }
+
+       _gth_browser_remove_activity (load_data->browser);
+
+       _gth_browser_load (load_data->browser,
+                          load_data->requested_folder->file,
+                          load_data->file_to_select,
+                          NULL,
+                          0,
+                          load_data->action,
+                          load_data->automatic);
+
+       load_data_free (load_data);
+}
+
+
 static void
 _gth_browser_hide_infobar (GthBrowser *browser)
 {
@@ -1733,8 +1815,8 @@ _gth_browser_load (GthBrowser *browser,
                   GthAction   action,
                   gboolean    automatic)
 {
-       LoadData *load_data;
-       GFile    *entry_point;
+       LoadData    *load_data;
+       GthFileData *entry_point;
 
        if (! automatic)
                _gth_browser_hide_infobar (browser);
@@ -1752,7 +1834,7 @@ _gth_browser_load (GthBrowser *browser,
                                   vscroll,
                                   action,
                                   automatic,
-                                  entry_point);
+                                  entry_point->file);
 
        _gth_browser_add_activity (browser);
 
@@ -1773,6 +1855,31 @@ _gth_browser_load (GthBrowser *browser,
 
                return;
        }
+       else if (g_file_info_get_file_type (entry_point->info) == G_FILE_TYPE_MOUNTABLE) {
+               GMountOperation *mount_op;
+               GVolume         *volume;
+
+               mount_op = gtk_mount_operation_new (GTK_WINDOW (browser));
+               volume = (GVolume *) g_file_info_get_attribute_object (entry_point->info, 
GTH_FILE_ATTRIBUTE_VOLUME);
+               if (volume != NULL)
+                       g_volume_mount (volume,
+                                       0,
+                                       mount_op,
+                                       load_data->cancellable,
+                                       volume_mount_ready_cb,
+                                       load_data);
+               else
+                       g_file_mount_mountable (entry_point->file,
+                                               0,
+                                               mount_op,
+                                               load_data->cancellable,
+                                               mount_mountable_ready_cb,
+                                               load_data);
+
+               g_object_unref (mount_op);
+
+               return;
+       }
 
        if (gth_action_changes_folder (load_data->action))
                gth_hook_invoke ("gth-browser-load-location-before", browser, 
load_data->requested_folder->file);
diff --git a/gthumb/gth-file-source-vfs.c b/gthumb/gth-file-source-vfs.c
index 9207586f..6dfa36d6 100644
--- a/gthumb/gth-file-source-vfs.c
+++ b/gthumb/gth-file-source-vfs.c
@@ -59,6 +59,9 @@ struct _GthFileSourceVfsPrivate
 static guint mount_changed_event_id = 0;
 static guint mount_added_event_id = 0;
 static guint mount_removed_event_id = 0;
+static guint volume_changed_event_id = 0;
+static guint volume_added_event_id = 0;
+static guint volume_removed_event_id = 0;
 
 
 G_DEFINE_TYPE_WITH_CODE (GthFileSourceVfs,
@@ -121,6 +124,7 @@ gth_file_source_vfs_get_entry_points (GthFileSource *file_source)
        GList          *list;
        GVolumeMonitor *monitor;
        GList          *mounts;
+       GList          *volumes;
        GList          *scan;
 
        list = NULL;
@@ -185,8 +189,70 @@ gth_file_source_vfs_get_entry_points (GthFileSource *file_source)
                g_free (name);
                _g_object_unref (icon);
        }
-
        _g_object_list_unref (mounts);
+
+       /* Not mounted mountable volumes. */
+
+       volumes = g_volume_monitor_get_volumes (monitor);
+       for (scan = volumes; scan; scan = scan->next) {
+               GVolume   *volume = scan->data;
+               GMount    *mount;
+               GFile     *file;
+               GIcon     *icon;
+               char      *name;
+               GFileInfo *info;
+
+               if (! g_volume_can_mount (volume))
+                       continue;
+
+               mount = g_volume_get_mount (volume);
+               if (mount != NULL) {
+                       /* Already mounted, ignore. */
+                       g_object_unref (mount);
+                       continue;
+               }
+
+               file = g_volume_get_activation_root (volume);
+               if (file == NULL) {
+                       char *device;
+
+                       device = g_volume_get_identifier (volume, G_VOLUME_IDENTIFIER_KIND_UNIX_DEVICE);
+                       if (device == NULL)
+                               continue;
+                       file = g_file_new_for_path (device);
+
+                       g_free (device);
+               }
+
+               if (gth_file_data_list_find_file (list, file) != NULL) {
+                       /* Already mounted, ignore. */
+                       g_object_unref (file);
+                       continue;
+               }
+
+               icon = g_volume_get_symbolic_icon (volume);
+               name = g_volume_get_name (volume);
+
+               info = g_file_info_new ();
+               g_file_info_set_file_type (info, G_FILE_TYPE_MOUNTABLE);
+               g_file_info_set_attribute_object (info, GTH_FILE_ATTRIBUTE_VOLUME, G_OBJECT (volume));
+               g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_READ, TRUE);
+               g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE, FALSE);
+               g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_DELETE, FALSE);
+               g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_TRASH, FALSE);
+               g_file_info_set_symbolic_icon (info, icon);
+               g_file_info_set_display_name (info, name);
+               g_file_info_set_name (info, name);
+
+               list = g_list_append (list, gth_file_data_new (file, info));
+
+               g_object_unref (info);
+               g_object_unref (file);
+               g_free (name);
+               _g_object_unref (icon);
+       }
+       _g_object_list_unref (volumes);
+
        g_object_unref (monitor);
 
        return list;
@@ -406,7 +472,7 @@ gth_file_source_vfs_can_cut (GthFileSource *file_source)
 
 static void
 mount_monitor_mountpoints_changed_cb (GVolumeMonitor *volume_monitor,
-                                     GMount         *mount,
+                                     gpointer        mount_or_volume,
                                      gpointer        user_data)
 {
        call_when_idle ((DataFunc) gth_monitor_entry_points_changed, gth_main_get_default_monitor ());
@@ -436,6 +502,21 @@ gth_file_source_vfs_monitor_entry_points (GthFileSource *file_source)
                                                           "mount-removed",
                                                           G_CALLBACK (mount_monitor_mountpoints_changed_cb),
                                                           file_source_vfs);
+       if (volume_changed_event_id == 0)
+               volume_changed_event_id = g_signal_connect (file_source_vfs->priv->mount_monitor,
+                                                           "volume-changed",
+                                                           G_CALLBACK (mount_monitor_mountpoints_changed_cb),
+                                                           file_source_vfs);
+       if (volume_added_event_id == 0)
+               volume_added_event_id = g_signal_connect (file_source_vfs->priv->mount_monitor,
+                                                         "volume-added",
+                                                         G_CALLBACK (mount_monitor_mountpoints_changed_cb),
+                                                         file_source_vfs);
+       if (volume_removed_event_id == 0)
+               volume_removed_event_id = g_signal_connect (file_source_vfs->priv->mount_monitor,
+                                                           "volume-removed",
+                                                           G_CALLBACK (mount_monitor_mountpoints_changed_cb),
+                                                           file_source_vfs);
 }
 
 
diff --git a/gthumb/gth-folder-tree.c b/gthumb/gth-folder-tree.c
index 47735c82..3febc0e2 100644
--- a/gthumb/gth-folder-tree.c
+++ b/gthumb/gth-folder-tree.c
@@ -1307,7 +1307,8 @@ _gth_folder_tree_add_file (GthFolderTree *folder_tree,
 {
        GtkTreeIter iter;
 
-       if (g_file_info_get_file_type (fd->info) != G_FILE_TYPE_DIRECTORY)
+       if ((g_file_info_get_file_type (fd->info) != G_FILE_TYPE_DIRECTORY)
+           && (g_file_info_get_file_type (fd->info) != G_FILE_TYPE_MOUNTABLE))
                return FALSE;
 
        /* add the folder */
@@ -1660,13 +1661,13 @@ gth_folder_tree_set_children (GthFolderTree *folder_tree,
        file_hash = g_hash_table_new_full (g_file_hash, (GEqualFunc) g_file_equal, g_object_unref, NULL);
        for (scan = old_files; scan; scan = scan->next) {
                GthFileData *file_data = scan->data;
-               g_hash_table_insert (file_hash, g_object_ref (file_data->file), GINT_TO_POINTER (1));
+               g_hash_table_add (file_hash, g_object_ref (file_data->file));
        }
 
        for (scan = files; scan; scan = scan->next) {
                GthFileData *file_data = scan->data;
 
-               if (! g_hash_table_lookup (file_hash, file_data->file))
+               if (! g_hash_table_contains (file_hash, file_data->file))
                        _gth_folder_tree_add_file (folder_tree, p_parent_iter, file_data);
        }
 
diff --git a/gthumb/gth-main.c b/gthumb/gth-main.c
index 6b881294..5a205c74 100644
--- a/gthumb/gth-main.c
+++ b/gthumb/gth-main.c
@@ -327,17 +327,16 @@ gth_main_get_all_entry_points (void)
 }
 
 
-GFile *
+GthFileData *
 gth_main_get_nearest_entry_point (GFile *file)
 {
        GList *list;
        GList *scan;
        GList *entries;
-       char  *nearest_uri;
+       GthFileData *nearest;
        char  *uri;
        int    file_uri_len;
        int    min_diff;
-       GFile *nearest;
 
        entries = NULL;
        list = gth_main_get_all_entry_points ();
@@ -345,32 +344,34 @@ gth_main_get_nearest_entry_point (GFile *file)
                GthFileData *entry_point = scan->data;
 
                if (_g_file_is_parent (entry_point->file, file))
-                       entries = g_list_prepend (entries, g_file_get_uri (entry_point->file));
+                       entries = g_list_prepend (entries, g_object_ref (entry_point));
        }
 
-       nearest_uri = NULL;
+       nearest = NULL;
        uri = g_file_get_uri (file);
        file_uri_len = strlen (uri);
        min_diff = 0;
        for (scan = entries; scan; scan = scan->next) {
-               char *entry_uri = scan->data;
+               GthFileData *entry_point = scan->data;
+               char *entry_uri;
                int   entry_len;
                int   diff;
 
+               entry_uri = g_file_get_uri (entry_point->file);
                entry_len = strlen (entry_uri);
                diff = abs (entry_len - file_uri_len);
                if ((scan == entries) || (diff < min_diff)) {
                        min_diff = diff;
-                       nearest_uri = entry_uri;
+                       nearest = entry_point;
                }
+
+               g_free (entry_uri);
        }
        g_free (uri);
 
-       nearest = NULL;
-       if (nearest_uri != NULL)
-               nearest = g_file_new_for_uri (nearest_uri);
+       g_object_ref (nearest);
 
-       _g_string_list_free (entries);
+       _g_object_list_unref (entries);
        _g_object_list_unref (list);
 
        return nearest;
diff --git a/gthumb/gth-main.h b/gthumb/gth-main.h
index f329ea36..d2341f98 100644
--- a/gthumb/gth-main.h
+++ b/gthumb/gth-main.h
@@ -71,7 +71,7 @@ GthFileSource *        gth_main_get_file_source               (GFile
 char *                 gth_main_get_source_scheme             (const char           *uri);
 GList *                gth_main_get_all_file_sources          (void);
 GList *                gth_main_get_all_entry_points          (void);
-GFile *                gth_main_get_nearest_entry_point       (GFile                *file);
+GthFileData *          gth_main_get_nearest_entry_point       (GFile                *file);
 char *                 gth_main_get_gio_uri                   (const char           *uri);
 GFile *                gth_main_get_gio_file                  (GFile                *file);
 void                   gth_main_register_metadata_category    (GthMetadataCategory  *metadata_category);
diff --git a/gthumb/gth-vfs-tree.c b/gthumb/gth-vfs-tree.c
index 3f928140..2a03c86a 100644
--- a/gthumb/gth-vfs-tree.c
+++ b/gthumb/gth-vfs-tree.c
@@ -114,8 +114,11 @@ load_data_new (GthVfsTree *vfs_tree,
        load_data->vfs_tree = g_object_ref (vfs_tree);
        load_data->action = action;
        load_data->requested_folder = gth_file_data_new (location, NULL);
-       if (vfs_tree->priv->tree_root_is_vfs_root && ! g_file_equal (location, root))
-               load_data->entry_point = gth_main_get_nearest_entry_point (location);
+       if (vfs_tree->priv->tree_root_is_vfs_root && ! g_file_equal (location, root)) {
+               GthFileData *entry_point = gth_main_get_nearest_entry_point (location);
+               load_data->entry_point = _g_object_ref (entry_point->file);
+               g_object_unref (entry_point);
+       }
        else
                load_data->entry_point = _g_object_ref (root);
        load_data->file_source = gth_main_get_file_source (load_data->requested_folder->file);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]