mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2025-01-15 14:50:06 +00:00
filechooserbutton: Stop using GtkFileSystem
Just use gio directly.
This commit is contained in:
parent
0210850e86
commit
b41d380230
@ -192,11 +192,10 @@ struct _GtkFileChooserButton
|
||||
GtkTreeModel *model;
|
||||
GtkTreeModel *filter_model;
|
||||
|
||||
GtkFileSystem *fs;
|
||||
GFile *selection_while_inactive;
|
||||
GFile *current_folder_while_inactive;
|
||||
|
||||
gulong fs_volumes_changed_id;
|
||||
GVolumeMonitor *volume_monitor;
|
||||
|
||||
GCancellable *dnd_select_folder_cancellable;
|
||||
GCancellable *update_button_cancellable;
|
||||
@ -276,7 +275,7 @@ static void gtk_file_chooser_button_state_flags_changed (GtkWidget
|
||||
GtkStateFlags previous_state);
|
||||
|
||||
/* Utility Functions */
|
||||
static void set_info_for_file_at_iter (GtkFileChooserButton *fs,
|
||||
static void set_info_for_file_at_iter (GtkFileChooserButton *button,
|
||||
GFile *file,
|
||||
GtkTreeIter *iter);
|
||||
|
||||
@ -313,8 +312,6 @@ static void update_combo_box (GtkFileChooserButton *button)
|
||||
static void update_label_and_image (GtkFileChooserButton *button);
|
||||
|
||||
/* Child Object Callbacks */
|
||||
static void fs_volumes_changed_cb (GtkFileSystem *fs,
|
||||
gpointer user_data);
|
||||
static void bookmarks_changed_cb (gpointer user_data);
|
||||
|
||||
static void combo_box_changed_cb (GtkComboBox *combo_box,
|
||||
@ -329,6 +326,10 @@ static void dialog_response_cb (GtkDialog *dialog,
|
||||
static void native_response_cb (GtkFileChooserNative *native,
|
||||
gint response,
|
||||
gpointer user_data);
|
||||
static void volumes_changed (GVolumeMonitor *volume_monitor,
|
||||
gpointer volume,
|
||||
gpointer user_data);
|
||||
static GSList * get_volumes_list (GVolumeMonitor *volume_monitor);
|
||||
|
||||
static guint file_chooser_button_signals[LAST_SIGNAL] = { 0 };
|
||||
|
||||
@ -342,9 +343,9 @@ G_DEFINE_TYPE_WITH_CODE (GtkFileChooserButton, gtk_file_chooser_button, GTK_TYPE
|
||||
|
||||
struct DndSelectFolderData
|
||||
{
|
||||
GtkFileSystem *file_system;
|
||||
GtkFileChooserButton *button;
|
||||
GtkFileChooserAction action;
|
||||
GCancellable *cancellable;
|
||||
GFile *file;
|
||||
gchar **uris;
|
||||
guint i;
|
||||
@ -352,29 +353,29 @@ struct DndSelectFolderData
|
||||
};
|
||||
|
||||
static void
|
||||
dnd_select_folder_get_info_cb (GCancellable *cancellable,
|
||||
GFileInfo *info,
|
||||
const GError *error,
|
||||
dnd_select_folder_get_info_cb (GObject *object,
|
||||
GAsyncResult *result,
|
||||
gpointer user_data)
|
||||
{
|
||||
GFile *file = G_FILE (object);
|
||||
struct DndSelectFolderData *data = user_data;
|
||||
GFileInfo *info;
|
||||
GtkFileChooserButton *button = data->button;
|
||||
gboolean cancelled = g_cancellable_is_cancelled (cancellable);
|
||||
|
||||
if (cancellable != button->dnd_select_folder_cancellable)
|
||||
if (g_cancellable_is_cancelled (data->cancellable))
|
||||
{
|
||||
g_object_unref (data->button);
|
||||
g_object_unref (data->file);
|
||||
g_object_unref (data->cancellable);
|
||||
g_strfreev (data->uris);
|
||||
g_free (data);
|
||||
|
||||
g_object_unref (cancellable);
|
||||
return;
|
||||
}
|
||||
|
||||
button->dnd_select_folder_cancellable = NULL;
|
||||
|
||||
if (!cancelled && !error && info != NULL)
|
||||
info = g_file_query_info_finish (file, result, NULL);
|
||||
if (info)
|
||||
{
|
||||
gboolean is_folder;
|
||||
|
||||
@ -388,16 +389,18 @@ dnd_select_folder_get_info_cb (GCancellable *cancellable,
|
||||
else
|
||||
data->selected = FALSE;
|
||||
|
||||
g_clear_object (&info);
|
||||
|
||||
if (data->selected || data->uris[++data->i] == NULL)
|
||||
{
|
||||
g_signal_emit (data->button, file_chooser_button_signals[FILE_SET], 0);
|
||||
|
||||
g_object_unref (data->button);
|
||||
g_object_unref (data->file);
|
||||
g_object_unref (data->cancellable);
|
||||
g_strfreev (data->uris);
|
||||
g_free (data);
|
||||
|
||||
g_object_unref (cancellable);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -406,12 +409,17 @@ dnd_select_folder_get_info_cb (GCancellable *cancellable,
|
||||
|
||||
data->file = g_file_new_for_uri (data->uris[data->i]);
|
||||
|
||||
button->dnd_select_folder_cancellable =
|
||||
_gtk_file_system_get_info (data->file_system, data->file,
|
||||
"standard::type",
|
||||
dnd_select_folder_get_info_cb, user_data);
|
||||
g_clear_object (&data->cancellable);
|
||||
data->cancellable = g_cancellable_new ();
|
||||
button->dnd_select_folder_cancellable = data->cancellable;
|
||||
|
||||
g_object_unref (cancellable);
|
||||
g_file_query_info_async (data->file,
|
||||
"standard::type",
|
||||
G_FILE_QUERY_INFO_NONE,
|
||||
G_PRIORITY_DEFAULT,
|
||||
data->cancellable,
|
||||
dnd_select_folder_get_info_cb,
|
||||
user_data);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@ -431,18 +439,21 @@ gtk_file_chooser_button_drop (GtkDropTarget *target,
|
||||
info->i = 0;
|
||||
info->uris = g_new0 (char *, 2);
|
||||
info->selected = FALSE;
|
||||
info->file_system = button->fs;
|
||||
g_object_get (button->chooser, "action", &info->action, NULL);
|
||||
|
||||
info->file = g_object_ref (file);
|
||||
|
||||
if (button->dnd_select_folder_cancellable)
|
||||
g_cancellable_cancel (button->dnd_select_folder_cancellable);
|
||||
g_clear_pointer (&button->dnd_select_folder_cancellable, g_cancellable_cancel);
|
||||
|
||||
button->dnd_select_folder_cancellable =
|
||||
_gtk_file_system_get_info (button->fs, info->file,
|
||||
info->cancellable = g_cancellable_new ();
|
||||
button->dnd_select_folder_cancellable = info->cancellable;
|
||||
g_file_query_info_async (info->file,
|
||||
"standard::type",
|
||||
dnd_select_folder_get_info_cb, info);
|
||||
G_FILE_QUERY_INFO_NONE,
|
||||
G_PRIORITY_DEFAULT,
|
||||
info->cancellable,
|
||||
dnd_select_folder_get_info_cb,
|
||||
info);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@ -900,14 +911,31 @@ gtk_file_chooser_button_constructed (GObject *object)
|
||||
* delegated when the OK button is pressed. */
|
||||
g_object_set_qdata (object, GTK_FILE_CHOOSER_DELEGATE_QUARK, button->chooser);
|
||||
|
||||
button->fs =
|
||||
g_object_ref (_gtk_file_chooser_get_file_system (button->chooser));
|
||||
|
||||
model_add_special (button);
|
||||
|
||||
list = _gtk_file_system_list_volumes (button->fs);
|
||||
button->volume_monitor = g_volume_monitor_get ();
|
||||
g_signal_connect (button->volume_monitor, "mount-added",
|
||||
G_CALLBACK (volumes_changed), button);
|
||||
g_signal_connect (button->volume_monitor, "mount-removed",
|
||||
G_CALLBACK (volumes_changed), button);
|
||||
g_signal_connect (button->volume_monitor, "mount-changed",
|
||||
G_CALLBACK (volumes_changed), button);
|
||||
g_signal_connect (button->volume_monitor, "volume-added",
|
||||
G_CALLBACK (volumes_changed), button);
|
||||
g_signal_connect (button->volume_monitor, "volume-removed",
|
||||
G_CALLBACK (volumes_changed), button);
|
||||
g_signal_connect (button->volume_monitor, "volume-changed",
|
||||
G_CALLBACK (volumes_changed), button);
|
||||
g_signal_connect (button->volume_monitor, "drive-connected",
|
||||
G_CALLBACK (volumes_changed), button);
|
||||
g_signal_connect (button->volume_monitor, "drive-disconnected",
|
||||
G_CALLBACK (volumes_changed), button);
|
||||
g_signal_connect (button->volume_monitor, "drive-changed",
|
||||
G_CALLBACK (volumes_changed), button);
|
||||
|
||||
list = get_volumes_list (button->volume_monitor);
|
||||
model_add_volumes (button, list);
|
||||
g_slist_free (list);
|
||||
g_slist_free_full (list, g_object_unref);
|
||||
|
||||
list = _gtk_bookmarks_manager_list_bookmarks (button->bookmarks_manager);
|
||||
model_add_bookmarks (button, list);
|
||||
@ -932,10 +960,6 @@ gtk_file_chooser_button_constructed (GObject *object)
|
||||
"action", gtk_file_chooser_get_action (GTK_FILE_CHOOSER (button->chooser)),
|
||||
NULL);
|
||||
|
||||
button->fs_volumes_changed_id =
|
||||
g_signal_connect (button->fs, "volumes-changed",
|
||||
G_CALLBACK (fs_volumes_changed_cb), object);
|
||||
|
||||
update_label_and_image (button);
|
||||
update_combo_box (button);
|
||||
}
|
||||
@ -1091,7 +1115,6 @@ static void
|
||||
gtk_file_chooser_button_dispose (GObject *object)
|
||||
{
|
||||
GtkFileChooserButton *button = GTK_FILE_CHOOSER_BUTTON (object);
|
||||
GSList *l;
|
||||
|
||||
if (button->model)
|
||||
{
|
||||
@ -1110,24 +1133,14 @@ gtk_file_chooser_button_dispose (GObject *object)
|
||||
g_clear_pointer (&button->dnd_select_folder_cancellable, g_cancellable_cancel);
|
||||
g_clear_pointer (&button->update_button_cancellable, g_cancellable_cancel);
|
||||
|
||||
if (button->change_icon_theme_cancellables)
|
||||
{
|
||||
for (l = button->change_icon_theme_cancellables; l; l = l->next)
|
||||
{
|
||||
GCancellable *cancellable = G_CANCELLABLE (l->data);
|
||||
g_cancellable_cancel (cancellable);
|
||||
}
|
||||
g_slist_free (button->change_icon_theme_cancellables);
|
||||
g_slist_free_full (button->change_icon_theme_cancellables, (GDestroyNotify)g_cancellable_cancel);
|
||||
button->change_icon_theme_cancellables = NULL;
|
||||
}
|
||||
|
||||
g_clear_object (&button->filter_model);
|
||||
|
||||
if (button->fs)
|
||||
{
|
||||
g_signal_handler_disconnect (button->fs, button->fs_volumes_changed_id);
|
||||
g_clear_object (&button->fs);
|
||||
}
|
||||
if (button->volume_monitor)
|
||||
g_signal_handlers_disconnect_by_func (button->volume_monitor, volumes_changed, button);
|
||||
g_clear_object (&button->volume_monitor);
|
||||
|
||||
g_clear_pointer (&button->bookmarks_manager, _gtk_bookmarks_manager_free);
|
||||
|
||||
@ -1194,26 +1207,34 @@ struct ChangeIconThemeData
|
||||
{
|
||||
GtkFileChooserButton *button;
|
||||
GtkTreeRowReference *row_ref;
|
||||
GCancellable *cancellable;
|
||||
};
|
||||
|
||||
static void
|
||||
change_icon_theme_get_info_cb (GCancellable *cancellable,
|
||||
GFileInfo *info,
|
||||
const GError *error,
|
||||
change_icon_theme_get_info_cb (GObject *source,
|
||||
GAsyncResult *result,
|
||||
gpointer user_data)
|
||||
{
|
||||
gboolean cancelled = g_cancellable_is_cancelled (cancellable);
|
||||
GIcon *icon;
|
||||
GFile *file = G_FILE (source);
|
||||
struct ChangeIconThemeData *data = user_data;
|
||||
GFileInfo *info;
|
||||
GIcon *icon;
|
||||
GtkFileChooserButton *button = data->button;
|
||||
|
||||
if (!g_slist_find (button->change_icon_theme_cancellables, cancellable))
|
||||
goto out;
|
||||
if (g_cancellable_is_cancelled (data->cancellable))
|
||||
{
|
||||
g_object_unref (data->button);
|
||||
g_object_unref (data->cancellable);
|
||||
gtk_tree_row_reference_free (data->row_ref);
|
||||
g_free (data);
|
||||
return;
|
||||
}
|
||||
|
||||
button->change_icon_theme_cancellables =
|
||||
g_slist_remove (button->change_icon_theme_cancellables, cancellable);
|
||||
g_slist_remove (button->change_icon_theme_cancellables, data->cancellable);
|
||||
|
||||
if (cancelled || error)
|
||||
info = g_file_query_info_finish (file, result, NULL);
|
||||
if (!info)
|
||||
goto out;
|
||||
|
||||
icon = _gtk_file_info_get_icon (info, ICON_SIZE, gtk_widget_get_scale_factor (GTK_WIDGET (data->button)));
|
||||
@ -1244,25 +1265,20 @@ change_icon_theme_get_info_cb (GCancellable *cancellable,
|
||||
|
||||
out:
|
||||
g_object_unref (data->button);
|
||||
g_object_unref (data->cancellable);
|
||||
gtk_tree_row_reference_free (data->row_ref);
|
||||
g_free (data);
|
||||
|
||||
g_object_unref (cancellable);
|
||||
g_clear_object (&info);
|
||||
}
|
||||
|
||||
static void
|
||||
change_icon_theme (GtkFileChooserButton *button)
|
||||
{
|
||||
GtkTreeIter iter;
|
||||
GSList *l;
|
||||
gint width = 0;
|
||||
|
||||
for (l = button->change_icon_theme_cancellables; l; l = l->next)
|
||||
{
|
||||
GCancellable *cancellable = G_CANCELLABLE (l->data);
|
||||
g_cancellable_cancel (cancellable);
|
||||
}
|
||||
g_slist_free (button->change_icon_theme_cancellables);
|
||||
g_slist_free_full (button->change_icon_theme_cancellables, (GDestroyNotify)g_cancellable_cancel);
|
||||
button->change_icon_theme_cancellables = NULL;
|
||||
|
||||
update_label_and_image (button);
|
||||
@ -1292,7 +1308,6 @@ change_icon_theme (GtkFileChooserButton *button)
|
||||
if (g_file_is_native (G_FILE (data)))
|
||||
{
|
||||
GtkTreePath *path;
|
||||
GCancellable *cancellable;
|
||||
struct ChangeIconThemeData *info;
|
||||
|
||||
info = g_new0 (struct ChangeIconThemeData, 1);
|
||||
@ -1301,13 +1316,17 @@ change_icon_theme (GtkFileChooserButton *button)
|
||||
info->row_ref = gtk_tree_row_reference_new (button->model, path);
|
||||
gtk_tree_path_free (path);
|
||||
|
||||
cancellable =
|
||||
_gtk_file_system_get_info (button->fs, data,
|
||||
info->cancellable = g_cancellable_new ();
|
||||
g_file_query_info_async (data,
|
||||
"standard::icon",
|
||||
G_FILE_QUERY_INFO_NONE,
|
||||
G_PRIORITY_DEFAULT,
|
||||
info->cancellable,
|
||||
change_icon_theme_get_info_cb,
|
||||
info);
|
||||
|
||||
button->change_icon_theme_cancellables =
|
||||
g_slist_append (button->change_icon_theme_cancellables, cancellable);
|
||||
g_slist_append (button->change_icon_theme_cancellables, info->cancellable);
|
||||
icon = NULL;
|
||||
}
|
||||
else
|
||||
@ -1322,9 +1341,14 @@ change_icon_theme (GtkFileChooserButton *button)
|
||||
}
|
||||
break;
|
||||
case ROW_TYPE_VOLUME:
|
||||
if (data)
|
||||
icon = _gtk_file_system_volume_get_icon (data);
|
||||
|
||||
if (G_IS_DRIVE (data))
|
||||
icon = g_drive_get_icon (G_DRIVE (data));
|
||||
else if (G_IS_VOLUME (data))
|
||||
icon = g_volume_get_icon (G_VOLUME (data));
|
||||
else if (G_IS_MOUNT (data))
|
||||
icon = g_mount_get_icon (G_MOUNT (data));
|
||||
else
|
||||
icon = NULL;
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
@ -1370,17 +1394,17 @@ struct SetDisplayNameData
|
||||
};
|
||||
|
||||
static void
|
||||
set_info_get_info_cb (GCancellable *cancellable,
|
||||
GFileInfo *info,
|
||||
const GError *error,
|
||||
set_info_get_info_cb (GObject *source,
|
||||
GAsyncResult *result,
|
||||
gpointer callback_data)
|
||||
{
|
||||
gboolean cancelled = g_cancellable_is_cancelled (cancellable);
|
||||
GFile *file = G_FILE (source);
|
||||
struct SetDisplayNameData *data = callback_data;
|
||||
GFileInfo *info = NULL;
|
||||
GIcon *icon;
|
||||
GtkTreePath *path;
|
||||
GtkTreeIter iter;
|
||||
GCancellable *model_cancellable = NULL;
|
||||
struct SetDisplayNameData *data = callback_data;
|
||||
GtkFileChooserButton *button = data->button;
|
||||
gboolean is_folder;
|
||||
|
||||
@ -1400,15 +1424,13 @@ set_info_get_info_cb (GCancellable *cancellable,
|
||||
gtk_tree_model_get (button->model, &iter,
|
||||
CANCELLABLE_COLUMN, &model_cancellable,
|
||||
-1);
|
||||
if (cancellable != model_cancellable)
|
||||
goto out;
|
||||
|
||||
gtk_list_store_set (GTK_LIST_STORE (button->model), &iter,
|
||||
CANCELLABLE_COLUMN, NULL,
|
||||
-1);
|
||||
|
||||
if (cancelled || error)
|
||||
/* There was an error, leave the fallback name in there */
|
||||
info = g_file_query_info_finish (file, result, NULL);
|
||||
if (!info)
|
||||
goto out;
|
||||
|
||||
icon = _gtk_file_info_get_icon (info, ICON_SIZE, gtk_widget_get_scale_factor (GTK_WIDGET (data->button)));
|
||||
@ -1433,7 +1455,7 @@ out:
|
||||
gtk_tree_row_reference_free (data->row_ref);
|
||||
g_free (data);
|
||||
|
||||
g_object_unref (cancellable);
|
||||
g_clear_object (&info);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1453,9 +1475,14 @@ set_info_for_file_at_iter (GtkFileChooserButton *button,
|
||||
data->row_ref = gtk_tree_row_reference_new (button->model, tree_path);
|
||||
gtk_tree_path_free (tree_path);
|
||||
|
||||
cancellable = _gtk_file_system_get_info (button->fs, file,
|
||||
cancellable = g_cancellable_new ();
|
||||
g_file_query_info_async (file,
|
||||
"standard::type,standard::icon,standard::display-name",
|
||||
set_info_get_info_cb, data);
|
||||
G_FILE_QUERY_INFO_NONE,
|
||||
G_PRIORITY_DEFAULT,
|
||||
cancellable,
|
||||
set_info_get_info_cb,
|
||||
data);
|
||||
|
||||
gtk_list_store_set (GTK_LIST_STORE (button->model), iter,
|
||||
CANCELLABLE_COLUMN, cancellable,
|
||||
@ -1541,10 +1568,8 @@ model_free_row_data (GtkFileChooserButton *button,
|
||||
case ROW_TYPE_SHORTCUT:
|
||||
case ROW_TYPE_BOOKMARK:
|
||||
case ROW_TYPE_CURRENT_FOLDER:
|
||||
g_object_unref (data);
|
||||
break;
|
||||
case ROW_TYPE_VOLUME:
|
||||
_gtk_file_system_volume_unref (data);
|
||||
g_object_unref (data);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -1552,18 +1577,18 @@ model_free_row_data (GtkFileChooserButton *button,
|
||||
}
|
||||
|
||||
static void
|
||||
model_add_special_get_info_cb (GCancellable *cancellable,
|
||||
GFileInfo *info,
|
||||
const GError *error,
|
||||
model_add_special_get_info_cb (GObject *source,
|
||||
GAsyncResult *result,
|
||||
gpointer user_data)
|
||||
{
|
||||
gboolean cancelled = g_cancellable_is_cancelled (cancellable);
|
||||
GFile *file = G_FILE (source);
|
||||
struct ChangeIconThemeData *data = user_data;
|
||||
GtkTreeIter iter;
|
||||
GtkTreePath *path;
|
||||
GIcon *icon;
|
||||
GCancellable *model_cancellable = NULL;
|
||||
struct ChangeIconThemeData *data = user_data;
|
||||
GtkFileChooserButton *button = data->button;
|
||||
GFileInfo *info = NULL;
|
||||
gchar *name;
|
||||
|
||||
if (!button->model)
|
||||
@ -1581,15 +1606,13 @@ model_add_special_get_info_cb (GCancellable *cancellable,
|
||||
gtk_tree_model_get (button->model, &iter,
|
||||
CANCELLABLE_COLUMN, &model_cancellable,
|
||||
-1);
|
||||
if (cancellable != model_cancellable)
|
||||
|
||||
goto out;
|
||||
|
||||
gtk_list_store_set (GTK_LIST_STORE (button->model), &iter,
|
||||
CANCELLABLE_COLUMN, NULL,
|
||||
-1);
|
||||
|
||||
if (cancelled || error)
|
||||
info = g_file_query_info_finish (file, result, NULL);
|
||||
if (!info)
|
||||
goto out;
|
||||
|
||||
icon = _gtk_file_info_get_icon (info, ICON_SIZE, gtk_widget_get_scale_factor (GTK_WIDGET (data->button)));
|
||||
@ -1615,7 +1638,7 @@ out:
|
||||
gtk_tree_row_reference_free (data->row_ref);
|
||||
g_free (data);
|
||||
|
||||
g_object_unref (cancellable);
|
||||
g_clear_object (&info);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1650,9 +1673,14 @@ model_add_special (GtkFileChooserButton *button)
|
||||
tree_path);
|
||||
gtk_tree_path_free (tree_path);
|
||||
|
||||
cancellable = _gtk_file_system_get_info (button->fs, file,
|
||||
cancellable = g_cancellable_new ();
|
||||
g_file_query_info_async (file,
|
||||
"standard::icon,standard::display-name",
|
||||
model_add_special_get_info_cb, info);
|
||||
G_FILE_QUERY_INFO_NONE,
|
||||
G_PRIORITY_DEFAULT,
|
||||
cancellable,
|
||||
model_add_special_get_info_cb,
|
||||
info);
|
||||
|
||||
gtk_list_store_set (store, &iter,
|
||||
ICON_COLUMN, NULL,
|
||||
@ -1688,9 +1716,14 @@ model_add_special (GtkFileChooserButton *button)
|
||||
tree_path);
|
||||
gtk_tree_path_free (tree_path);
|
||||
|
||||
cancellable = _gtk_file_system_get_info (button->fs, file,
|
||||
cancellable = g_cancellable_new ();
|
||||
g_file_query_info_async (file,
|
||||
"standard::icon,standard::display-name",
|
||||
model_add_special_get_info_cb, info);
|
||||
G_FILE_QUERY_INFO_NONE,
|
||||
G_PRIORITY_DEFAULT,
|
||||
cancellable,
|
||||
model_add_special_get_info_cb,
|
||||
info);
|
||||
|
||||
gtk_list_store_set (store, &iter,
|
||||
TYPE_COLUMN, ROW_TYPE_SPECIAL,
|
||||
@ -1721,26 +1754,43 @@ model_add_volumes (GtkFileChooserButton *button,
|
||||
|
||||
for (l = volumes; l; l = l->next)
|
||||
{
|
||||
GtkFileSystemVolume *volume;
|
||||
gpointer *volume;
|
||||
GtkTreeIter iter;
|
||||
GIcon *icon;
|
||||
gchar *display_name;
|
||||
|
||||
volume = l->data;
|
||||
icon = _gtk_file_system_volume_get_icon (volume);
|
||||
display_name = _gtk_file_system_volume_get_display_name (volume);
|
||||
if (G_IS_DRIVE (volume))
|
||||
{
|
||||
icon = g_drive_get_icon (G_DRIVE (volume));
|
||||
display_name = g_drive_get_name (G_DRIVE (volume));
|
||||
}
|
||||
else if (G_IS_VOLUME (volume))
|
||||
{
|
||||
icon = g_volume_get_icon (G_VOLUME (volume));
|
||||
display_name = g_volume_get_name (G_VOLUME (volume));
|
||||
}
|
||||
else if (G_IS_MOUNT (volume))
|
||||
{
|
||||
icon = g_mount_get_icon (G_MOUNT (volume));
|
||||
display_name = g_mount_get_name (G_MOUNT (volume));
|
||||
}
|
||||
else
|
||||
{
|
||||
icon = NULL;
|
||||
display_name = NULL;
|
||||
}
|
||||
|
||||
gtk_list_store_insert (store, &iter, pos);
|
||||
gtk_list_store_set (store, &iter,
|
||||
ICON_COLUMN, icon,
|
||||
DISPLAY_NAME_COLUMN, display_name,
|
||||
TYPE_COLUMN, ROW_TYPE_VOLUME,
|
||||
DATA_COLUMN, _gtk_file_system_volume_ref (volume),
|
||||
DATA_COLUMN, g_object_ref (volume),
|
||||
IS_FOLDER_COLUMN, TRUE,
|
||||
-1);
|
||||
|
||||
if (icon)
|
||||
g_object_unref (icon);
|
||||
g_clear_object (&icon);
|
||||
g_free (display_name);
|
||||
|
||||
button->n_volumes++;
|
||||
@ -1978,8 +2028,7 @@ model_remove_rows (GtkFileChooserButton *button,
|
||||
|
||||
/* Filter Model */
|
||||
static gboolean
|
||||
test_if_file_is_visible (GtkFileSystem *fs,
|
||||
GFile *file,
|
||||
test_if_file_is_visible (GFile *file,
|
||||
gboolean is_folder)
|
||||
{
|
||||
if (!file)
|
||||
@ -1996,7 +2045,6 @@ filter_model_visible_func (GtkTreeModel *model,
|
||||
GtkTreeIter *iter,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkFileChooserButton *button = GTK_FILE_CHOOSER_BUTTON (user_data);
|
||||
gchar type;
|
||||
gpointer data;
|
||||
gboolean retval, is_folder;
|
||||
@ -2018,7 +2066,7 @@ filter_model_visible_func (GtkTreeModel *model,
|
||||
case ROW_TYPE_SPECIAL:
|
||||
case ROW_TYPE_SHORTCUT:
|
||||
case ROW_TYPE_BOOKMARK:
|
||||
retval = test_if_file_is_visible (button->fs, data, is_folder);
|
||||
retval = test_if_file_is_visible (data, is_folder);
|
||||
break;
|
||||
case ROW_TYPE_VOLUME:
|
||||
retval = TRUE;
|
||||
@ -2118,15 +2166,10 @@ update_combo_box (GtkFileChooserButton *button)
|
||||
break;
|
||||
case ROW_TYPE_VOLUME:
|
||||
{
|
||||
GFile *base_file;
|
||||
|
||||
base_file = _gtk_file_system_volume_get_root (data);
|
||||
if (base_file)
|
||||
{
|
||||
GFile *base_file = g_file_new_for_uri ("file:///");
|
||||
row_found = (file && g_file_equal (base_file, file));
|
||||
g_object_unref (base_file);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
row_found = FALSE;
|
||||
@ -2171,21 +2214,19 @@ update_combo_box (GtkFileChooserButton *button)
|
||||
|
||||
/* Button */
|
||||
static void
|
||||
update_label_get_info_cb (GCancellable *cancellable,
|
||||
GFileInfo *info,
|
||||
const GError *error,
|
||||
update_label_get_info_cb (GObject *source,
|
||||
GAsyncResult *result,
|
||||
gpointer data)
|
||||
{
|
||||
gboolean cancelled = g_cancellable_is_cancelled (cancellable);
|
||||
GIcon *icon;
|
||||
GFile *file = G_FILE (source);
|
||||
GtkFileChooserButton *button = data;
|
||||
GIcon *icon;
|
||||
GFileInfo *info;
|
||||
|
||||
if (cancellable != button->update_button_cancellable)
|
||||
goto out;
|
||||
g_clear_object (&button->update_button_cancellable);
|
||||
|
||||
button->update_button_cancellable = NULL;
|
||||
|
||||
if (cancelled || error)
|
||||
info = g_file_query_info_finish (file, result, NULL);
|
||||
if (!info)
|
||||
goto out;
|
||||
|
||||
gtk_label_set_text (GTK_LABEL (button->label), g_file_info_get_display_name (info));
|
||||
@ -2199,8 +2240,8 @@ update_label_get_info_cb (GCancellable *cancellable,
|
||||
out:
|
||||
emit_selection_changed_if_changing_selection (button);
|
||||
|
||||
g_clear_object (&info);
|
||||
g_object_unref (button);
|
||||
g_object_unref (cancellable);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -2223,44 +2264,46 @@ update_label_and_image (GtkFileChooserButton *button)
|
||||
|
||||
if (file)
|
||||
{
|
||||
GtkFileSystemVolume *volume = NULL;
|
||||
|
||||
volume = _gtk_file_system_get_volume_for_file (button->fs, file);
|
||||
if (volume)
|
||||
{
|
||||
GMount *mount;
|
||||
GFile *base_file;
|
||||
|
||||
base_file = _gtk_file_system_volume_get_root (volume);
|
||||
mount = g_file_find_enclosing_mount (file, NULL, NULL);
|
||||
if (!mount && g_file_is_native (file))
|
||||
base_file = g_file_new_for_uri ("file:///");
|
||||
else if (mount)
|
||||
base_file = g_mount_get_root (mount);
|
||||
else
|
||||
base_file = NULL;
|
||||
|
||||
if (base_file && g_file_equal (base_file, file))
|
||||
{
|
||||
GIcon *icon;
|
||||
|
||||
label_text = _gtk_file_system_volume_get_display_name (volume);
|
||||
icon = _gtk_file_system_volume_get_icon (volume);
|
||||
label_text = g_mount_get_name (mount);
|
||||
icon = g_mount_get_icon (mount);
|
||||
gtk_image_set_from_gicon (GTK_IMAGE (button->image), icon);
|
||||
gtk_image_set_pixel_size (GTK_IMAGE (button->image), ICON_SIZE);
|
||||
if (icon)
|
||||
g_object_unref (icon);
|
||||
g_clear_object (&icon);
|
||||
}
|
||||
|
||||
if (base_file)
|
||||
g_object_unref (base_file);
|
||||
|
||||
_gtk_file_system_volume_unref (volume);
|
||||
g_clear_object (&base_file);
|
||||
g_clear_object (&mount);
|
||||
|
||||
if (label_text)
|
||||
{
|
||||
done_changing_selection = TRUE;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
if (g_file_is_native (file) ||
|
||||
!_gtk_bookmarks_manager_has_bookmark (button->bookmarks_manager, file))
|
||||
{
|
||||
button->update_button_cancellable =
|
||||
_gtk_file_system_get_info (button->fs, file,
|
||||
button->update_button_cancellable = g_cancellable_new ();
|
||||
g_file_query_info_async (file,
|
||||
"standard::icon,standard::display-name",
|
||||
G_FILE_QUERY_INFO_NONE,
|
||||
G_PRIORITY_DEFAULT,
|
||||
button->update_button_cancellable,
|
||||
update_label_get_info_cb,
|
||||
g_object_ref (button));
|
||||
}
|
||||
@ -2286,8 +2329,7 @@ update_label_and_image (GtkFileChooserButton *button)
|
||||
|
||||
out:
|
||||
|
||||
if (file)
|
||||
g_object_unref (file);
|
||||
g_clear_object (&file);
|
||||
|
||||
if (label_text)
|
||||
{
|
||||
@ -2309,9 +2351,179 @@ out:
|
||||
* Child Object Callbacks *
|
||||
* ************************ */
|
||||
|
||||
/* File System */
|
||||
static gboolean
|
||||
mount_referenced_by_volume_activation_root (GList *volumes, GMount *mount)
|
||||
{
|
||||
GList *l;
|
||||
GFile *mount_root;
|
||||
gboolean ret;
|
||||
|
||||
ret = FALSE;
|
||||
|
||||
mount_root = g_mount_get_root (mount);
|
||||
|
||||
for (l = volumes; l != NULL; l = l->next)
|
||||
{
|
||||
GVolume *volume = G_VOLUME (l->data);
|
||||
GFile *volume_activation_root;
|
||||
|
||||
volume_activation_root = g_volume_get_activation_root (volume);
|
||||
if (volume_activation_root != NULL)
|
||||
{
|
||||
if (g_file_has_prefix (volume_activation_root, mount_root))
|
||||
{
|
||||
ret = TRUE;
|
||||
g_object_unref (volume_activation_root);
|
||||
break;
|
||||
}
|
||||
g_object_unref (volume_activation_root);
|
||||
}
|
||||
}
|
||||
|
||||
g_object_unref (mount_root);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static GSList *
|
||||
get_volumes_list (GVolumeMonitor *volume_monitor)
|
||||
{
|
||||
GSList *result;
|
||||
GList *l, *ll;
|
||||
GList *drives;
|
||||
GList *volumes;
|
||||
GList *mounts;
|
||||
GDrive *drive;
|
||||
GVolume *volume;
|
||||
GMount *mount;
|
||||
|
||||
result = NULL;
|
||||
|
||||
/* first go through all connected drives */
|
||||
drives = g_volume_monitor_get_connected_drives (volume_monitor);
|
||||
|
||||
for (l = drives; l != NULL; l = l->next)
|
||||
{
|
||||
drive = l->data;
|
||||
volumes = g_drive_get_volumes (drive);
|
||||
|
||||
if (volumes)
|
||||
{
|
||||
for (ll = volumes; ll != NULL; ll = ll->next)
|
||||
{
|
||||
volume = ll->data;
|
||||
mount = g_volume_get_mount (volume);
|
||||
|
||||
if (mount)
|
||||
{
|
||||
/* Show mounted volume */
|
||||
result = g_slist_prepend (result, g_object_ref (mount));
|
||||
g_object_unref (mount);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Do show the unmounted volumes in the sidebar;
|
||||
* this is so the user can mount it (in case automounting
|
||||
* is off).
|
||||
*
|
||||
* Also, even if automounting is enabled, this gives a visual
|
||||
* cue that the user should remember to yank out the media if
|
||||
* he just unmounted it.
|
||||
*/
|
||||
result = g_slist_prepend (result, g_object_ref (volume));
|
||||
}
|
||||
|
||||
g_object_unref (volume);
|
||||
}
|
||||
|
||||
g_list_free (volumes);
|
||||
}
|
||||
else if (g_drive_is_media_removable (drive) && !g_drive_is_media_check_automatic (drive))
|
||||
{
|
||||
/* If the drive has no mountable volumes and we cannot detect media change.. we
|
||||
* display the drive in the sidebar so the user can manually poll the drive by
|
||||
* right clicking and selecting "Rescan..."
|
||||
*
|
||||
* This is mainly for drives like floppies where media detection doesn't
|
||||
* work.. but it's also for human beings who like to turn off media detection
|
||||
* in the OS to save battery juice.
|
||||
*/
|
||||
|
||||
result = g_slist_prepend (result, g_object_ref (drive));
|
||||
}
|
||||
|
||||
g_object_unref (drive);
|
||||
}
|
||||
|
||||
g_list_free (drives);
|
||||
|
||||
/* add all volumes that is not associated with a drive */
|
||||
volumes = g_volume_monitor_get_volumes (volume_monitor);
|
||||
|
||||
for (l = volumes; l != NULL; l = l->next)
|
||||
{
|
||||
volume = l->data;
|
||||
drive = g_volume_get_drive (volume);
|
||||
|
||||
if (drive)
|
||||
{
|
||||
g_object_unref (drive);
|
||||
continue;
|
||||
}
|
||||
|
||||
mount = g_volume_get_mount (volume);
|
||||
|
||||
if (mount)
|
||||
{
|
||||
/* show this mount */
|
||||
result = g_slist_prepend (result, g_object_ref (mount));
|
||||
g_object_unref (mount);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* see comment above in why we add an icon for a volume */
|
||||
result = g_slist_prepend (result, g_object_ref (volume));
|
||||
}
|
||||
|
||||
g_object_unref (volume);
|
||||
}
|
||||
|
||||
/* add mounts that has no volume (/etc/mtab mounts, ftp, sftp,...) */
|
||||
mounts = g_volume_monitor_get_mounts (volume_monitor);
|
||||
|
||||
for (l = mounts; l != NULL; l = l->next)
|
||||
{
|
||||
mount = l->data;
|
||||
volume = g_mount_get_volume (mount);
|
||||
|
||||
if (volume)
|
||||
{
|
||||
g_object_unref (volume);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* if there's exists one or more volumes with an activation root
|
||||
* inside the mount, don't display the mount
|
||||
*/
|
||||
if (mount_referenced_by_volume_activation_root (volumes, mount))
|
||||
{
|
||||
g_object_unref (mount);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* show this mount */
|
||||
result = g_slist_prepend (result, g_object_ref (mount));
|
||||
g_object_unref (mount);
|
||||
}
|
||||
|
||||
g_list_free (volumes);
|
||||
g_list_free (mounts);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
fs_volumes_changed_cb (GtkFileSystem *fs,
|
||||
volumes_changed (GVolumeMonitor *volume_monitor,
|
||||
gpointer volume,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkFileChooserButton *button = GTK_FILE_CHOOSER_BUTTON (user_data);
|
||||
@ -2323,9 +2535,9 @@ fs_volumes_changed_cb (GtkFileSystem *fs,
|
||||
|
||||
button->n_volumes = 0;
|
||||
|
||||
volumes = _gtk_file_system_list_volumes (fs);
|
||||
volumes = get_volumes_list (volume_monitor);
|
||||
model_add_volumes (user_data, volumes);
|
||||
g_slist_free (volumes);
|
||||
g_slist_free_full (volumes, g_object_unref);
|
||||
|
||||
gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (button->filter_model));
|
||||
|
||||
@ -2474,16 +2686,11 @@ combo_box_changed_cb (GtkComboBox *combo_box,
|
||||
break;
|
||||
case ROW_TYPE_VOLUME:
|
||||
{
|
||||
GFile *base_file;
|
||||
|
||||
base_file = _gtk_file_system_volume_get_root (data);
|
||||
if (base_file)
|
||||
{
|
||||
GFile *base_file = g_file_new_for_uri ("file:///");
|
||||
gtk_file_chooser_button_select_file (GTK_FILE_CHOOSER (button), base_file, NULL);
|
||||
file_was_set = TRUE;
|
||||
g_object_unref (base_file);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ROW_TYPE_OTHER:
|
||||
open_dialog (user_data);
|
||||
|
Loading…
Reference in New Issue
Block a user