[gthumb] allow to mount unmounted volumes
- From: Paolo Bacchilega <paobac src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gthumb] allow to mount unmounted volumes
- Date: Sat, 19 Jun 2021 18:10:42 +0000 (UTC)
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]