diff options
author | Matthias Clasen <mclasen@redhat.com> | 2020-07-12 14:41:01 +0000 |
---|---|---|
committer | Matthias Clasen <mclasen@redhat.com> | 2020-07-12 14:41:01 +0000 |
commit | 7ddbbb50ff9da663bd6d1349e51bfb5e2eb08e10 (patch) | |
tree | 0ee3068fc17238372a412a465db320aa1398e6cc | |
parent | f2eb0361197de9aeb38b9babe8f1d9983d0c91f2 (diff) | |
parent | 8a8b96bf4b7d5d3e46a7f9563897768eb595d817 (diff) | |
download | gtk+-7ddbbb50ff9da663bd6d1349e51bfb5e2eb08e10.tar.gz |
Merge branch 'drop-file-system' into 'master'
Drop file system
See merge request GNOME/gtk!2229
-rw-r--r-- | gtk/gtkfilechooser.c | 18 | ||||
-rw-r--r-- | gtk/gtkfilechooserbutton.c | 1365 | ||||
-rw-r--r-- | gtk/gtkfilechooserdialog.c | 1 | ||||
-rw-r--r-- | gtk/gtkfilechooserentry.c | 2 | ||||
-rw-r--r-- | gtk/gtkfilechooserentry.h | 1 | ||||
-rw-r--r-- | gtk/gtkfilechoosernative.c | 1 | ||||
-rw-r--r-- | gtk/gtkfilechoosernativeportal.c | 1 | ||||
-rw-r--r-- | gtk/gtkfilechoosernativequartz.c | 1 | ||||
-rw-r--r-- | gtk/gtkfilechoosernativewin32.c | 1 | ||||
-rw-r--r-- | gtk/gtkfilechooserprivate.h | 4 | ||||
-rw-r--r-- | gtk/gtkfilechooserutils.c | 82 | ||||
-rw-r--r-- | gtk/gtkfilechooserutils.h | 7 | ||||
-rw-r--r-- | gtk/gtkfilechooserwidget.c | 309 | ||||
-rw-r--r-- | gtk/gtkfilesystem.c | 823 | ||||
-rw-r--r-- | gtk/gtkfilesystem.h | 116 | ||||
-rw-r--r-- | gtk/gtkfilesystemmodel.c | 2 | ||||
-rw-r--r-- | gtk/gtknativedialog.c | 1 | ||||
-rw-r--r-- | gtk/gtkpathbar.c | 524 | ||||
-rw-r--r-- | gtk/gtkpathbar.h | 35 | ||||
-rw-r--r-- | gtk/gtkplacessidebar.c | 2 | ||||
-rw-r--r-- | gtk/meson.build | 1 |
21 files changed, 1273 insertions, 2024 deletions
diff --git a/gtk/gtkfilechooser.c b/gtk/gtkfilechooser.c index a6c28424ad..259e55687d 100644 --- a/gtk/gtkfilechooser.c +++ b/gtk/gtkfilechooser.c @@ -540,24 +540,6 @@ gtk_file_chooser_get_file (GtkFileChooser *chooser) return result; } -/*< private > - * _gtk_file_chooser_get_file_system: - * @chooser: a #GtkFileChooser - * - * Gets the #GtkFileSystem of @chooser; this is an internal - * implementation detail, used for conversion between paths - * and filenames and URIs. - * - * Returns: the file system for @chooser. - **/ -GtkFileSystem * -_gtk_file_chooser_get_file_system (GtkFileChooser *chooser) -{ - g_return_val_if_fail (GTK_IS_FILE_CHOOSER (chooser), NULL); - - return GTK_FILE_CHOOSER_GET_IFACE (chooser)->get_file_system (chooser); -} - /** * gtk_file_chooser_add_shortcut_folder: * @chooser: a #GtkFileChooser diff --git a/gtk/gtkfilechooserbutton.c b/gtk/gtkfilechooserbutton.c index 3708da6588..1ffa9807e7 100644 --- a/gtk/gtkfilechooserbutton.c +++ b/gtk/gtkfilechooserbutton.c @@ -11,7 +11,7 @@ * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public @@ -109,9 +109,9 @@ * Private Macros * * **************** */ -#define ICON_SIZE 16 -#define DEFAULT_TITLE N_("Select a File") -#define DESKTOP_DISPLAY_NAME N_("Desktop") +#define ICON_SIZE 16 +#define DEFAULT_TITLE N_("Select a File") +#define DESKTOP_DISPLAY_NAME N_("Desktop") #define FALLBACK_DISPLAY_NAME N_("(None)") @@ -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; @@ -235,34 +234,34 @@ struct _GtkFileChooserButtonClass /* GtkFileChooserIface Functions */ static void gtk_file_chooser_button_file_chooser_iface_init (GtkFileChooserIface *iface); static gboolean gtk_file_chooser_button_set_current_folder (GtkFileChooser *chooser, - GFile *file, - GError **error); + GFile *file, + GError **error); static GFile *gtk_file_chooser_button_get_current_folder (GtkFileChooser *chooser); static gboolean gtk_file_chooser_button_select_file (GtkFileChooser *chooser, - GFile *file, - GError **error); + GFile *file, + GError **error); static void gtk_file_chooser_button_unselect_file (GtkFileChooser *chooser, - GFile *file); + GFile *file); static void gtk_file_chooser_button_unselect_all (GtkFileChooser *chooser); static GListModel *gtk_file_chooser_button_get_files (GtkFileChooser *chooser); static gboolean gtk_file_chooser_button_add_shortcut_folder (GtkFileChooser *chooser, - GFile *file, - GError **error); + GFile *file, + GError **error); static gboolean gtk_file_chooser_button_remove_shortcut_folder (GtkFileChooser *chooser, - GFile *file, - GError **error); + GFile *file, + GError **error); /* GObject Functions */ static void gtk_file_chooser_button_constructed (GObject *object); static void gtk_file_chooser_button_dispose (GObject *object); static void gtk_file_chooser_button_set_property (GObject *object, - guint param_id, - const GValue *value, - GParamSpec *pspec); + guint param_id, + const GValue *value, + GParamSpec *pspec); static void gtk_file_chooser_button_get_property (GObject *object, - guint param_id, - GValue *value, - GParamSpec *pspec); + guint param_id, + GValue *value, + GParamSpec *pspec); static void gtk_file_chooser_button_finalize (GObject *object); /* GtkWidget Functions */ @@ -271,64 +270,66 @@ static void gtk_file_chooser_button_hide (GtkWidget *wi static void gtk_file_chooser_button_root (GtkWidget *widget); static void gtk_file_chooser_button_map (GtkWidget *widget); static gboolean gtk_file_chooser_button_mnemonic_activate (GtkWidget *widget, - gboolean group_cycling); + gboolean group_cycling); static void gtk_file_chooser_button_state_flags_changed (GtkWidget *widget, GtkStateFlags previous_state); /* Utility Functions */ -static void set_info_for_file_at_iter (GtkFileChooserButton *fs, - GFile *file, - GtkTreeIter *iter); +static void set_info_for_file_at_iter (GtkFileChooserButton *button, + GFile *file, + GtkTreeIter *iter); static gint model_get_type_position (GtkFileChooserButton *button, - RowType row_type); + RowType row_type); static void model_free_row_data (GtkFileChooserButton *button, - GtkTreeIter *iter); + GtkTreeIter *iter); static void model_add_special (GtkFileChooserButton *button); static void model_add_other (GtkFileChooserButton *button); static void model_add_volumes (GtkFileChooserButton *button, - GSList *volumes); + GSList *volumes); static void model_add_bookmarks (GtkFileChooserButton *button, - GSList *bookmarks); + GSList *bookmarks); static void model_update_current_folder (GtkFileChooserButton *button, - GFile *file); + GFile *file); static void model_remove_rows (GtkFileChooserButton *button, - gint pos, - gint n_rows); + gint pos, + gint n_rows); static gboolean filter_model_visible_func (GtkTreeModel *model, - GtkTreeIter *iter, - gpointer user_data); + GtkTreeIter *iter, + gpointer user_data); static gboolean combo_box_row_separator_func (GtkTreeModel *model, - GtkTreeIter *iter, - gpointer user_data); + GtkTreeIter *iter, + gpointer user_data); static void name_cell_data_func (GtkCellLayout *layout, - GtkCellRenderer *cell, - GtkTreeModel *model, - GtkTreeIter *iter, - gpointer user_data); + GtkCellRenderer *cell, + GtkTreeModel *model, + GtkTreeIter *iter, + gpointer user_data); static void open_dialog (GtkFileChooserButton *button); 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, - gpointer user_data); + gpointer user_data); static void button_clicked_cb (GtkButton *real_button, - gpointer user_data); + gpointer user_data); static void dialog_response_cb (GtkDialog *dialog, - gint response, - gpointer user_data); + gint response, + gpointer user_data); 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,52 +353,54 @@ struct DndSelectFolderData }; static void -dnd_select_folder_get_info_cb (GCancellable *cancellable, - GFileInfo *info, - const GError *error, - gpointer user_data) +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; is_folder = _gtk_file_info_consider_as_directory (info); data->selected = - (((data->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER && is_folder) || - (data->action == GTK_FILE_CHOOSER_ACTION_OPEN && !is_folder)) && - gtk_file_chooser_select_file (GTK_FILE_CHOOSER (data->button), data->file, NULL)); + (((data->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER && is_folder) || + (data->action == GTK_FILE_CHOOSER_ACTION_OPEN && !is_folder)) && + gtk_file_chooser_select_file (GTK_FILE_CHOOSER (data->button), data->file, NULL)); } 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, - "standard::type", - dnd_select_folder_get_info_cb, info); + info->cancellable = g_cancellable_new (); + button->dnd_select_folder_cancellable = info->cancellable; + g_file_query_info_async (info->file, + "standard::type", + G_FILE_QUERY_INFO_NONE, + G_PRIORITY_DEFAULT, + info->cancellable, + dnd_select_folder_get_info_cb, + info); return TRUE; } @@ -482,12 +493,12 @@ gtk_file_chooser_button_class_init (GtkFileChooserButtonClass * class) */ file_chooser_button_signals[FILE_SET] = g_signal_new (I_("file-set"), - G_TYPE_FROM_CLASS (gobject_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (GtkFileChooserButtonClass, file_set), - NULL, NULL, - NULL, - G_TYPE_NONE, 0); + G_TYPE_FROM_CLASS (gobject_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (GtkFileChooserButtonClass, file_set), + NULL, NULL, + NULL, + G_TYPE_NONE, 0); /** * GtkFileChooserButton:dialog: @@ -495,12 +506,12 @@ gtk_file_chooser_button_class_init (GtkFileChooserButtonClass * class) * Instance of the #GtkFileChooserDialog associated with the button. */ g_object_class_install_property (gobject_class, PROP_DIALOG, - g_param_spec_object ("dialog", - P_("Dialog"), - P_("The file chooser dialog to use."), - GTK_TYPE_FILE_CHOOSER, - (GTK_PARAM_WRITABLE | - G_PARAM_CONSTRUCT_ONLY))); + g_param_spec_object ("dialog", + P_("Dialog"), + P_("The file chooser dialog to use."), + GTK_TYPE_FILE_CHOOSER, + (GTK_PARAM_WRITABLE | + G_PARAM_CONSTRUCT_ONLY))); /** * GtkFileChooserButton:title: @@ -508,11 +519,11 @@ gtk_file_chooser_button_class_init (GtkFileChooserButtonClass * class) * Title to put on the #GtkFileChooserDialog associated with the button. */ g_object_class_install_property (gobject_class, PROP_TITLE, - g_param_spec_string ("title", - P_("Title"), - P_("The title of the file chooser dialog."), - _(DEFAULT_TITLE), - GTK_PARAM_READWRITE)); + g_param_spec_string ("title", + P_("Title"), + P_("The title of the file chooser dialog."), + _(DEFAULT_TITLE), + GTK_PARAM_READWRITE)); /** * GtkFileChooserButton:width-chars: @@ -520,18 +531,18 @@ gtk_file_chooser_button_class_init (GtkFileChooserButtonClass * class) * The width of the entry and label inside the button, in characters. */ g_object_class_install_property (gobject_class, PROP_WIDTH_CHARS, - g_param_spec_int ("width-chars", - P_("Width In Characters"), - P_("The desired width of the button widget, in characters."), - -1, G_MAXINT, -1, - GTK_PARAM_READWRITE)); + g_param_spec_int ("width-chars", + P_("Width In Characters"), + P_("The desired width of the button widget, in characters."), + -1, G_MAXINT, -1, + GTK_PARAM_READWRITE)); g_object_class_install_property (gobject_class, PROP_MODAL, - g_param_spec_boolean ("modal", - P_("Modal"), - P_("Whether to make the dialog modal"), - TRUE, - GTK_PARAM_READWRITE)); + g_param_spec_boolean ("modal", + P_("Modal"), + P_("Whether to make the dialog modal"), + TRUE, + GTK_PARAM_READWRITE)); _gtk_file_chooser_install_properties (gobject_class); @@ -593,8 +604,8 @@ gtk_file_chooser_button_init (GtkFileChooserButton *button) /* Bookmarks manager */ button->bookmarks_manager = _gtk_bookmarks_manager_new (bookmarks_changed_cb, button); gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT (button->combo_box), - button->name_cell, name_cell_data_func, - NULL, NULL); + button->name_cell, name_cell_data_func, + NULL, NULL); /* DnD */ target = gtk_drop_target_new (G_TYPE_FILE, GDK_ACTION_COPY); @@ -632,8 +643,8 @@ emit_selection_changed_if_changing_selection (GtkFileChooserButton *button) static gboolean gtk_file_chooser_button_set_current_folder (GtkFileChooser *chooser, - GFile *file, - GError **error) + GFile *file, + GError **error) { GtkFileChooserButton *button = GTK_FILE_CHOOSER_BUTTON (chooser); @@ -663,8 +674,8 @@ gtk_file_chooser_button_get_current_folder (GtkFileChooser *chooser) static gboolean gtk_file_chooser_button_select_file (GtkFileChooser *chooser, - GFile *file, - GError **error) + GFile *file, + GError **error) { GtkFileChooserButton *button = GTK_FILE_CHOOSER_BUTTON (chooser); @@ -701,7 +712,7 @@ unselect_current_file (GtkFileChooserButton *button) static void gtk_file_chooser_button_unselect_file (GtkFileChooser *chooser, - GFile *file) + GFile *file) { GtkFileChooserButton *button = GTK_FILE_CHOOSER_BUTTON (chooser); @@ -738,7 +749,7 @@ get_selected_file (GtkFileChooserButton *button) * the current folder, since that is what GtkFileChooserWidget would do. */ if (button->current_folder_while_inactive) - retval = button->current_folder_while_inactive; + retval = button->current_folder_while_inactive; } if (retval) @@ -768,14 +779,14 @@ gtk_file_chooser_button_get_files (GtkFileChooser *chooser) static gboolean gtk_file_chooser_button_add_shortcut_folder (GtkFileChooser *chooser, - GFile *file, - GError **error) + GFile *file, + GError **error) { GtkFileChooser *delegate; gboolean retval; delegate = g_object_get_qdata (G_OBJECT (chooser), - GTK_FILE_CHOOSER_DELEGATE_QUARK); + GTK_FILE_CHOOSER_DELEGATE_QUARK); retval = gtk_file_chooser_add_shortcut_folder (delegate, file, error); if (retval) @@ -789,12 +800,12 @@ gtk_file_chooser_button_add_shortcut_folder (GtkFileChooser *chooser, gtk_list_store_insert (GTK_LIST_STORE (button->model), &iter, pos); gtk_list_store_set (GTK_LIST_STORE (button->model), &iter, - ICON_COLUMN, NULL, - DISPLAY_NAME_COLUMN, _(FALLBACK_DISPLAY_NAME), - TYPE_COLUMN, ROW_TYPE_SHORTCUT, - DATA_COLUMN, g_object_ref (file), - IS_FOLDER_COLUMN, FALSE, - -1); + ICON_COLUMN, NULL, + DISPLAY_NAME_COLUMN, _(FALLBACK_DISPLAY_NAME), + TYPE_COLUMN, ROW_TYPE_SHORTCUT, + DATA_COLUMN, g_object_ref (file), + IS_FOLDER_COLUMN, FALSE, + -1); set_info_for_file_at_iter (button, file, &iter); button->n_shortcuts++; @@ -806,14 +817,14 @@ gtk_file_chooser_button_add_shortcut_folder (GtkFileChooser *chooser, static gboolean gtk_file_chooser_button_remove_shortcut_folder (GtkFileChooser *chooser, - GFile *file, - GError **error) + GFile *file, + GError **error) { GtkFileChooser *delegate; gboolean retval; delegate = g_object_get_qdata (G_OBJECT (chooser), - GTK_FILE_CHOOSER_DELEGATE_QUARK); + GTK_FILE_CHOOSER_DELEGATE_QUARK); retval = gtk_file_chooser_remove_shortcut_folder (delegate, file, error); @@ -828,27 +839,27 @@ gtk_file_chooser_button_remove_shortcut_folder (GtkFileChooser *chooser, gtk_tree_model_iter_nth_child (button->model, &iter, NULL, pos); do - { - gpointer data; - - gtk_tree_model_get (button->model, &iter, - TYPE_COLUMN, &type, - DATA_COLUMN, &data, - -1); - - if (type == ROW_TYPE_SHORTCUT && - data && g_file_equal (data, file)) - { - model_free_row_data (GTK_FILE_CHOOSER_BUTTON (chooser), &iter); - gtk_list_store_remove (GTK_LIST_STORE (button->model), &iter); - button->n_shortcuts--; - gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (button->filter_model)); - update_combo_box (GTK_FILE_CHOOSER_BUTTON (chooser)); - break; - } - } + { + gpointer data; + + gtk_tree_model_get (button->model, &iter, + TYPE_COLUMN, &type, + DATA_COLUMN, &data, + -1); + + if (type == ROW_TYPE_SHORTCUT && + data && g_file_equal (data, file)) + { + model_free_row_data (GTK_FILE_CHOOSER_BUTTON (chooser), &iter); + gtk_list_store_remove (GTK_LIST_STORE (button->model), &iter); + button->n_shortcuts--; + gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (button->filter_model)); + update_combo_box (GTK_FILE_CHOOSER_BUTTON (chooser)); + break; + } + } while (type == ROW_TYPE_SHORTCUT && - gtk_tree_model_iter_next (button->model, &iter)); + gtk_tree_model_iter_next (button->model, &iter)); } return retval; @@ -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); @@ -917,24 +945,20 @@ gtk_file_chooser_button_constructed (GObject *object) button->filter_model = gtk_tree_model_filter_new (button->model, NULL); gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (button->filter_model), - filter_model_visible_func, - object, NULL); + filter_model_visible_func, + object, NULL); gtk_combo_box_set_model (GTK_COMBO_BOX (button->combo_box), button->filter_model); gtk_combo_box_set_row_separator_func (GTK_COMBO_BOX (button->combo_box), - combo_box_row_separator_func, - NULL, NULL); + combo_box_row_separator_func, + NULL, NULL); /* set up the action for a user-provided dialog, this also updates * the label, image and combobox */ g_object_set (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); + "action", gtk_file_chooser_get_action (GTK_FILE_CHOOSER (button->chooser)), + NULL); update_label_and_image (button); update_combo_box (button); @@ -942,9 +966,9 @@ gtk_file_chooser_button_constructed (GObject *object) static void gtk_file_chooser_button_set_property (GObject *object, - guint param_id, - const GValue *value, - GParamSpec *pspec) + guint param_id, + const GValue *value, + GParamSpec *pspec) { GtkFileChooserButton *button = GTK_FILE_CHOOSER_BUTTON (object); @@ -956,27 +980,27 @@ gtk_file_chooser_button_set_property (GObject *object, break; case PROP_WIDTH_CHARS: gtk_file_chooser_button_set_width_chars (GTK_FILE_CHOOSER_BUTTON (object), - g_value_get_int (value)); + g_value_get_int (value)); break; case GTK_FILE_CHOOSER_PROP_ACTION: switch (g_value_get_enum (value)) - { - case GTK_FILE_CHOOSER_ACTION_SAVE: - { - GEnumClass *eclass; - GEnumValue *eval; - - eclass = g_type_class_peek (GTK_TYPE_FILE_CHOOSER_ACTION); - eval = g_enum_get_value (eclass, g_value_get_enum (value)); - g_warning ("%s: Choosers of type '%s' do not support '%s'.", - G_STRFUNC, G_OBJECT_TYPE_NAME (object), eval->value_name); - - g_value_set_enum ((GValue *) value, GTK_FILE_CHOOSER_ACTION_OPEN); - } - break; + { + case GTK_FILE_CHOOSER_ACTION_SAVE: + { + GEnumClass *eclass; + GEnumValue *eval; + + eclass = g_type_class_peek (GTK_TYPE_FILE_CHOOSER_ACTION); + eval = g_enum_get_value (eclass, g_value_get_enum (value)); + g_warning ("%s: Choosers of type '%s' do not support '%s'.", + G_STRFUNC, G_OBJECT_TYPE_NAME (object), eval->value_name); + + g_value_set_enum ((GValue *) value, GTK_FILE_CHOOSER_ACTION_OPEN); + } + break; default: break; - } + } g_object_set_property (G_OBJECT (button->chooser), pspec->name, value); update_label_and_image (GTK_FILE_CHOOSER_BUTTON (object)); @@ -1009,7 +1033,7 @@ gtk_file_chooser_button_set_property (GObject *object, case GTK_FILE_CHOOSER_PROP_SELECT_MULTIPLE: g_warning ("%s: Choosers of type '%s' do not support selecting multiple files.", - G_STRFUNC, G_OBJECT_TYPE_NAME (object)); + G_STRFUNC, G_OBJECT_TYPE_NAME (object)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); @@ -1019,9 +1043,9 @@ gtk_file_chooser_button_set_property (GObject *object, static void gtk_file_chooser_button_get_property (GObject *object, - guint param_id, - GValue *value, - GParamSpec *pspec) + guint param_id, + GValue *value, + GParamSpec *pspec) { GtkFileChooserButton *button = GTK_FILE_CHOOSER_BUTTON (object); @@ -1029,7 +1053,7 @@ gtk_file_chooser_button_get_property (GObject *object, { case PROP_WIDTH_CHARS: g_value_set_int (value, - gtk_label_get_width_chars (GTK_LABEL (button->label))); + gtk_label_get_width_chars (GTK_LABEL (button->label))); break; case PROP_TITLE: @@ -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); - button->change_icon_theme_cancellables = NULL; - } + 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); @@ -1168,7 +1181,7 @@ gtk_file_chooser_button_map (GtkWidget *widget) static gboolean gtk_file_chooser_button_mnemonic_activate (GtkWidget *widget, - gboolean group_cycling) + gboolean group_cycling) { GtkFileChooserButton *button = GTK_FILE_CHOOSER_BUTTON (widget); @@ -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, - gpointer user_data) +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))); @@ -1232,37 +1253,32 @@ change_icon_theme_get_info_cb (GCancellable *cancellable, gtk_tree_path_free (path); gtk_list_store_set (GTK_LIST_STORE (button->model), &iter, - ICON_COLUMN, icon, - -1); + ICON_COLUMN, icon, + -1); g_object_set (button->icon_cell, - "width", width, - NULL); + "width", width, + NULL); } g_object_unref (icon); } 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); @@ -1277,40 +1293,43 @@ change_icon_theme (GtkFileChooserButton *button) type = ROW_TYPE_INVALID; gtk_tree_model_get (button->model, &iter, - TYPE_COLUMN, &type, - DATA_COLUMN, &data, - -1); + TYPE_COLUMN, &type, + DATA_COLUMN, &data, + -1); switch (type) - { - case ROW_TYPE_SPECIAL: - case ROW_TYPE_SHORTCUT: - case ROW_TYPE_BOOKMARK: - case ROW_TYPE_CURRENT_FOLDER: - if (data) - { - if (g_file_is_native (G_FILE (data))) - { - GtkTreePath *path; - GCancellable *cancellable; - struct ChangeIconThemeData *info; - - info = g_new0 (struct ChangeIconThemeData, 1); - info->button = g_object_ref (button); - path = gtk_tree_model_get_path (button->model, &iter); - 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, - "standard::icon", - change_icon_theme_get_info_cb, - info); + { + case ROW_TYPE_SPECIAL: + case ROW_TYPE_SHORTCUT: + case ROW_TYPE_BOOKMARK: + case ROW_TYPE_CURRENT_FOLDER: + if (data) + { + if (g_file_is_native (G_FILE (data))) + { + GtkTreePath *path; + struct ChangeIconThemeData *info; + + info = g_new0 (struct ChangeIconThemeData, 1); + info->button = g_object_ref (button); + path = gtk_tree_model_get_path (button->model, &iter); + info->row_ref = gtk_tree_row_reference_new (button->model, path); + gtk_tree_path_free (path); + + 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 + } + else { /* Don't call get_info for remote paths to avoid latency and * auth dialogs. @@ -1319,33 +1338,38 @@ change_icon_theme (GtkFileChooserButton *button) */ icon = g_themed_icon_new ("folder-remote"); } - } - break; - case ROW_TYPE_VOLUME: - if (data) - icon = _gtk_file_system_volume_get_icon (data); - - break; - default: - continue; - break; - } + } + break; + case ROW_TYPE_VOLUME: + 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; + break; + } if (icon) - width = MAX (width, ICON_SIZE); + width = MAX (width, ICON_SIZE); gtk_list_store_set (GTK_LIST_STORE (button->model), &iter, - ICON_COLUMN, icon, - -1); + ICON_COLUMN, icon, + -1); if (icon) - g_object_unref (icon); + g_object_unref (icon); } while (gtk_tree_model_iter_next (button->model, &iter)); g_object_set (button->icon_cell, - "width", width, - NULL); + "width", width, + NULL); } static void @@ -1370,17 +1394,17 @@ struct SetDisplayNameData }; static void -set_info_get_info_cb (GCancellable *cancellable, - GFileInfo *info, - const GError *error, - gpointer callback_data) +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; @@ -1398,17 +1422,15 @@ set_info_get_info_cb (GCancellable *cancellable, /* Validate the cancellable */ gtk_tree_model_get (button->model, &iter, - CANCELLABLE_COLUMN, &model_cancellable, - -1); - if (cancellable != model_cancellable) - goto out; + CANCELLABLE_COLUMN, &model_cancellable, + -1); gtk_list_store_set (GTK_LIST_STORE (button->model), &iter, - CANCELLABLE_COLUMN, NULL, - -1); + 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))); @@ -1419,10 +1441,10 @@ set_info_get_info_cb (GCancellable *cancellable, is_folder = _gtk_file_info_consider_as_directory (info); gtk_list_store_set (GTK_LIST_STORE (button->model), &iter, - ICON_COLUMN, icon, - DISPLAY_NAME_COLUMN, data->label, - IS_FOLDER_COLUMN, is_folder, - -1); + ICON_COLUMN, icon, + DISPLAY_NAME_COLUMN, data->label, + IS_FOLDER_COLUMN, is_folder, + -1); if (icon) g_object_unref (icon); @@ -1433,13 +1455,13 @@ out: gtk_tree_row_reference_free (data->row_ref); g_free (data); - g_object_unref (cancellable); + g_clear_object (&info); } static void set_info_for_file_at_iter (GtkFileChooserButton *button, - GFile *file, - GtkTreeIter *iter) + GFile *file, + GtkTreeIter *iter) { struct SetDisplayNameData *data; GtkTreePath *tree_path; @@ -1453,19 +1475,24 @@ 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, - "standard::type,standard::icon,standard::display-name", - set_info_get_info_cb, data); + cancellable = g_cancellable_new (); + g_file_query_info_async (file, + "standard::type,standard::icon,standard::display-name", + 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, - -1); + CANCELLABLE_COLUMN, cancellable, + -1); } /* Shortcuts Model */ static gint model_get_type_position (GtkFileChooserButton *button, - RowType row_type) + RowType row_type) { gint retval = 0; @@ -1520,17 +1547,17 @@ model_get_type_position (GtkFileChooserButton *button, static void model_free_row_data (GtkFileChooserButton *button, - GtkTreeIter *iter) + GtkTreeIter *iter) { gchar type; gpointer data; GCancellable *cancellable; gtk_tree_model_get (button->model, iter, - TYPE_COLUMN, &type, - DATA_COLUMN, &data, - CANCELLABLE_COLUMN, &cancellable, - -1); + TYPE_COLUMN, &type, + DATA_COLUMN, &data, + CANCELLABLE_COLUMN, &cancellable, + -1); if (cancellable) g_cancellable_cancel (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, - gpointer user_data) +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) @@ -1579,25 +1604,23 @@ model_add_special_get_info_cb (GCancellable *cancellable, gtk_tree_path_free (path); gtk_tree_model_get (button->model, &iter, - CANCELLABLE_COLUMN, &model_cancellable, - -1); - if (cancellable != model_cancellable) - - goto out; + CANCELLABLE_COLUMN, &model_cancellable, + -1); gtk_list_store_set (GTK_LIST_STORE (button->model), &iter, - CANCELLABLE_COLUMN, NULL, - -1); + 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))); if (icon) { gtk_list_store_set (GTK_LIST_STORE (button->model), &iter, - ICON_COLUMN, icon, - -1); + ICON_COLUMN, icon, + -1); g_object_unref (icon); } @@ -1606,8 +1629,8 @@ model_add_special_get_info_cb (GCancellable *cancellable, -1); if (!name) gtk_list_store_set (GTK_LIST_STORE (button->model), &iter, - DISPLAY_NAME_COLUMN, g_file_info_get_display_name (info), - -1); + DISPLAY_NAME_COLUMN, g_file_info_get_display_name (info), + -1); g_free (name); out: @@ -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 @@ -1647,21 +1670,26 @@ model_add_special (GtkFileChooserButton *button) info->button = g_object_ref (button); tree_path = gtk_tree_model_get_path (GTK_TREE_MODEL (store), &iter); info->row_ref = gtk_tree_row_reference_new (GTK_TREE_MODEL (store), - tree_path); + tree_path); gtk_tree_path_free (tree_path); - cancellable = _gtk_file_system_get_info (button->fs, file, - "standard::icon,standard::display-name", - model_add_special_get_info_cb, info); + cancellable = g_cancellable_new (); + g_file_query_info_async (file, + "standard::icon,standard::display-name", + 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, - DISPLAY_NAME_COLUMN, NULL, - TYPE_COLUMN, ROW_TYPE_SPECIAL, - DATA_COLUMN, file, - IS_FOLDER_COLUMN, TRUE, - CANCELLABLE_COLUMN, cancellable, - -1); + ICON_COLUMN, NULL, + DISPLAY_NAME_COLUMN, NULL, + TYPE_COLUMN, ROW_TYPE_SPECIAL, + DATA_COLUMN, file, + IS_FOLDER_COLUMN, TRUE, + CANCELLABLE_COLUMN, cancellable, + -1); button->n_special++; } @@ -1685,21 +1713,26 @@ model_add_special (GtkFileChooserButton *button) info->button = g_object_ref (button); tree_path = gtk_tree_model_get_path (GTK_TREE_MODEL (store), &iter); info->row_ref = gtk_tree_row_reference_new (GTK_TREE_MODEL (store), - tree_path); + tree_path); gtk_tree_path_free (tree_path); - cancellable = _gtk_file_system_get_info (button->fs, file, - "standard::icon,standard::display-name", - model_add_special_get_info_cb, info); + cancellable = g_cancellable_new (); + g_file_query_info_async (file, + "standard::icon,standard::display-name", + 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, - ICON_COLUMN, NULL, - DISPLAY_NAME_COLUMN, _(DESKTOP_DISPLAY_NAME), - DATA_COLUMN, file, - IS_FOLDER_COLUMN, TRUE, - CANCELLABLE_COLUMN, cancellable, - -1); + TYPE_COLUMN, ROW_TYPE_SPECIAL, + ICON_COLUMN, NULL, + DISPLAY_NAME_COLUMN, _(DESKTOP_DISPLAY_NAME), + DATA_COLUMN, file, + IS_FOLDER_COLUMN, TRUE, + CANCELLABLE_COLUMN, cancellable, + -1); button->n_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++; @@ -1750,7 +1800,7 @@ model_add_volumes (GtkFileChooserButton *button, static void model_add_bookmarks (GtkFileChooserButton *button, - GSList *bookmarks) + GSList *bookmarks) { GtkListStore *store; GtkTreeIter iter; @@ -1770,46 +1820,46 @@ model_add_bookmarks (GtkFileChooserButton *button, file = l->data; if (_gtk_file_has_native_path (file)) - { - gtk_list_store_insert (store, &iter, pos); - gtk_list_store_set (store, &iter, - ICON_COLUMN, NULL, - DISPLAY_NAME_COLUMN, _(FALLBACK_DISPLAY_NAME), - TYPE_COLUMN, ROW_TYPE_BOOKMARK, - DATA_COLUMN, g_object_ref (file), - IS_FOLDER_COLUMN, FALSE, - -1); - set_info_for_file_at_iter (button, file, &iter); - } + { + gtk_list_store_insert (store, &iter, pos); + gtk_list_store_set (store, &iter, + ICON_COLUMN, NULL, + DISPLAY_NAME_COLUMN, _(FALLBACK_DISPLAY_NAME), + TYPE_COLUMN, ROW_TYPE_BOOKMARK, + DATA_COLUMN, g_object_ref (file), + IS_FOLDER_COLUMN, FALSE, + -1); + set_info_for_file_at_iter (button, file, &iter); + } else - { - gchar *label; - GIcon *icon; - - /* Don't call get_info for remote paths to avoid latency and - * auth dialogs. - * If we switch to a better bookmarks file format (XBEL), we - * should use mime info to get a better icon. - */ - label = _gtk_bookmarks_manager_get_bookmark_label (button->bookmarks_manager, file); - if (!label) - label = _gtk_file_chooser_label_for_file (file); + { + gchar *label; + GIcon *icon; + + /* Don't call get_info for remote paths to avoid latency and + * auth dialogs. + * If we switch to a better bookmarks file format (XBEL), we + * should use mime info to get a better icon. + */ + label = _gtk_bookmarks_manager_get_bookmark_label (button->bookmarks_manager, file); + if (!label) + label = _gtk_file_chooser_label_for_file (file); icon = g_themed_icon_new ("folder-remote"); - gtk_list_store_insert (store, &iter, pos); - gtk_list_store_set (store, &iter, - ICON_COLUMN, icon, - DISPLAY_NAME_COLUMN, label, - TYPE_COLUMN, ROW_TYPE_BOOKMARK, - DATA_COLUMN, g_object_ref (file), - IS_FOLDER_COLUMN, TRUE, - -1); + gtk_list_store_insert (store, &iter, pos); + gtk_list_store_set (store, &iter, + ICON_COLUMN, icon, + DISPLAY_NAME_COLUMN, label, + TYPE_COLUMN, ROW_TYPE_BOOKMARK, + DATA_COLUMN, g_object_ref (file), + IS_FOLDER_COLUMN, TRUE, + -1); - g_free (label); - if (icon) - g_object_unref (icon); - } + g_free (label); + if (icon) + g_object_unref (icon); + } button->n_bookmarks++; pos++; @@ -1822,19 +1872,19 @@ model_add_bookmarks (GtkFileChooserButton *button, gtk_list_store_insert (store, &iter, pos); gtk_list_store_set (store, &iter, - ICON_COLUMN, NULL, - DISPLAY_NAME_COLUMN, NULL, - TYPE_COLUMN, ROW_TYPE_BOOKMARK_SEPARATOR, - DATA_COLUMN, NULL, - IS_FOLDER_COLUMN, FALSE, - -1); + ICON_COLUMN, NULL, + DISPLAY_NAME_COLUMN, NULL, + TYPE_COLUMN, ROW_TYPE_BOOKMARK_SEPARATOR, + DATA_COLUMN, NULL, + IS_FOLDER_COLUMN, FALSE, + -1); button->has_bookmark_separator = TRUE; } } static void model_update_current_folder (GtkFileChooserButton *button, - GFile *file) + GFile *file) { GtkListStore *store; GtkTreeIter iter; @@ -1850,12 +1900,12 @@ model_update_current_folder (GtkFileChooserButton *button, pos = model_get_type_position (button, ROW_TYPE_CURRENT_FOLDER_SEPARATOR); gtk_list_store_insert (store, &iter, pos); gtk_list_store_set (store, &iter, - ICON_COLUMN, NULL, - DISPLAY_NAME_COLUMN, NULL, - TYPE_COLUMN, ROW_TYPE_CURRENT_FOLDER_SEPARATOR, - DATA_COLUMN, NULL, - IS_FOLDER_COLUMN, FALSE, - -1); + ICON_COLUMN, NULL, + DISPLAY_NAME_COLUMN, NULL, + TYPE_COLUMN, ROW_TYPE_CURRENT_FOLDER_SEPARATOR, + DATA_COLUMN, NULL, + IS_FOLDER_COLUMN, FALSE, + -1); button->has_current_folder_separator = TRUE; } @@ -1874,12 +1924,12 @@ model_update_current_folder (GtkFileChooserButton *button, if (g_file_is_native (file)) { gtk_list_store_set (store, &iter, - ICON_COLUMN, NULL, - DISPLAY_NAME_COLUMN, _(FALLBACK_DISPLAY_NAME), - TYPE_COLUMN, ROW_TYPE_CURRENT_FOLDER, - DATA_COLUMN, g_object_ref (file), - IS_FOLDER_COLUMN, FALSE, - -1); + ICON_COLUMN, NULL, + DISPLAY_NAME_COLUMN, _(FALLBACK_DISPLAY_NAME), + TYPE_COLUMN, ROW_TYPE_CURRENT_FOLDER, + DATA_COLUMN, g_object_ref (file), + IS_FOLDER_COLUMN, FALSE, + -1); set_info_for_file_at_iter (button, file, &iter); } else @@ -1894,12 +1944,12 @@ model_update_current_folder (GtkFileChooserButton *button, */ label = _gtk_bookmarks_manager_get_bookmark_label (button->bookmarks_manager, file); if (!label) - label = _gtk_file_chooser_label_for_file (file); + label = _gtk_file_chooser_label_for_file (file); if (g_file_is_native (file)) - icon = g_themed_icon_new ("folder"); + icon = g_themed_icon_new ("folder"); else - icon = g_themed_icon_new ("folder-remote"); + icon = g_themed_icon_new ("folder-remote"); gtk_list_store_set (store, &iter, ICON_COLUMN, icon, @@ -1911,7 +1961,7 @@ model_update_current_folder (GtkFileChooserButton *button, g_free (label); if (icon) - g_object_unref (icon); + g_object_unref (icon); } } @@ -1940,20 +1990,20 @@ model_add_other (GtkFileChooserButton *button) gtk_list_store_insert (store, &iter, pos); gtk_list_store_set (store, &iter, - ICON_COLUMN, NULL, - DISPLAY_NAME_COLUMN, _("Other…"), - TYPE_COLUMN, ROW_TYPE_OTHER, - DATA_COLUMN, NULL, - IS_FOLDER_COLUMN, FALSE, - -1); + ICON_COLUMN, NULL, + DISPLAY_NAME_COLUMN, _("Other…"), + TYPE_COLUMN, ROW_TYPE_OTHER, + DATA_COLUMN, NULL, + IS_FOLDER_COLUMN, FALSE, + -1); g_object_unref (icon); } static void model_remove_rows (GtkFileChooserButton *button, - gint pos, - gint n_rows) + gint pos, + gint n_rows) { GtkListStore *store; @@ -1967,7 +2017,7 @@ model_remove_rows (GtkFileChooserButton *button, GtkTreeIter iter; if (!gtk_tree_model_iter_nth_child (button->model, &iter, NULL, pos)) - g_assert_not_reached (); + g_assert_not_reached (); model_free_row_data (button, &iter); gtk_list_store_remove (store, &iter); @@ -1978,9 +2028,8 @@ model_remove_rows (GtkFileChooserButton *button, /* Filter Model */ static gboolean -test_if_file_is_visible (GtkFileSystem *fs, - GFile *file, - gboolean is_folder) +test_if_file_is_visible (GFile *file, + gboolean is_folder) { if (!file) return FALSE; @@ -1993,10 +2042,9 @@ test_if_file_is_visible (GtkFileSystem *fs, static gboolean filter_model_visible_func (GtkTreeModel *model, - GtkTreeIter *iter, - gpointer user_data) + GtkTreeIter *iter, + gpointer user_data) { - GtkFileChooserButton *button = GTK_FILE_CHOOSER_BUTTON (user_data); gchar type; gpointer data; gboolean retval, is_folder; @@ -2005,10 +2053,10 @@ filter_model_visible_func (GtkTreeModel *model, data = NULL; gtk_tree_model_get (model, iter, - TYPE_COLUMN, &type, - DATA_COLUMN, &data, - IS_FOLDER_COLUMN, &is_folder, - -1); + TYPE_COLUMN, &type, + DATA_COLUMN, &data, + IS_FOLDER_COLUMN, &is_folder, + -1); switch (type) { @@ -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; @@ -2034,17 +2082,17 @@ filter_model_visible_func (GtkTreeModel *model, /* Combo Box */ static void name_cell_data_func (GtkCellLayout *layout, - GtkCellRenderer *cell, - GtkTreeModel *model, - GtkTreeIter *iter, - gpointer user_data) + GtkCellRenderer *cell, + GtkTreeModel *model, + GtkTreeIter *iter, + gpointer user_data) { gchar type; type = 0; gtk_tree_model_get (model, iter, - TYPE_COLUMN, &type, - -1); + TYPE_COLUMN, &type, + -1); if (type == ROW_TYPE_CURRENT_FOLDER) g_object_set (cell, "ellipsize", PANGO_ELLIPSIZE_END, NULL); @@ -2056,16 +2104,16 @@ name_cell_data_func (GtkCellLayout *layout, static gboolean combo_box_row_separator_func (GtkTreeModel *model, - GtkTreeIter *iter, - gpointer user_data) + GtkTreeIter *iter, + gpointer user_data) { gchar type = ROW_TYPE_INVALID; gtk_tree_model_get (model, iter, TYPE_COLUMN, &type, -1); return (type == ROW_TYPE_BOOKMARK_SEPARATOR || - type == ROW_TYPE_CURRENT_FOLDER_SEPARATOR || - type == ROW_TYPE_OTHER_SEPARATOR); + type == ROW_TYPE_CURRENT_FOLDER_SEPARATOR || + type == ROW_TYPE_OTHER_SEPARATOR); } static void @@ -2075,7 +2123,7 @@ select_combo_box_row_no_notify (GtkFileChooserButton *button, int pos) gtk_tree_model_iter_nth_child (button->model, &iter, NULL, pos); gtk_tree_model_filter_convert_child_iter_to_iter (GTK_TREE_MODEL_FILTER (button->filter_model), - &filter_iter, &iter); + &filter_iter, &iter); g_signal_handlers_block_by_func (button->combo_box, combo_box_changed_cb, button); gtk_combo_box_set_active_iter (GTK_COMBO_BOX (button->combo_box), &filter_iter); @@ -2104,42 +2152,37 @@ update_combo_box (GtkFileChooserButton *button) data = NULL; gtk_tree_model_get (button->filter_model, &iter, - TYPE_COLUMN, &type, - DATA_COLUMN, &data, - -1); + TYPE_COLUMN, &type, + DATA_COLUMN, &data, + -1); switch (type) - { - case ROW_TYPE_SPECIAL: - case ROW_TYPE_SHORTCUT: - case ROW_TYPE_BOOKMARK: - case ROW_TYPE_CURRENT_FOLDER: - row_found = (file && g_file_equal (data, file)); - break; - case ROW_TYPE_VOLUME: - { - GFile *base_file; - - base_file = _gtk_file_system_volume_get_root (data); - if (base_file) - { - row_found = (file && g_file_equal (base_file, file)); - g_object_unref (base_file); - } - } - break; - default: - row_found = FALSE; - break; - } + { + case ROW_TYPE_SPECIAL: + case ROW_TYPE_SHORTCUT: + case ROW_TYPE_BOOKMARK: + case ROW_TYPE_CURRENT_FOLDER: + row_found = (file && g_file_equal (data, file)); + break; + case ROW_TYPE_VOLUME: + { + 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; + break; + } if (row_found) - { - g_signal_handlers_block_by_func (button->combo_box, combo_box_changed_cb, button); - gtk_combo_box_set_active_iter (GTK_COMBO_BOX (button->combo_box), - &iter); - g_signal_handlers_unblock_by_func (button->combo_box, combo_box_changed_cb, button); - } + { + g_signal_handlers_block_by_func (button->combo_box, combo_box_changed_cb, button); + gtk_combo_box_set_active_iter (GTK_COMBO_BOX (button->combo_box), + &iter); + g_signal_handlers_unblock_by_func (button->combo_box, combo_box_changed_cb, button); + } } while (!row_found && gtk_tree_model_iter_next (button->filter_model, &iter)); @@ -2149,16 +2192,16 @@ update_combo_box (GtkFileChooserButton *button) /* If it hasn't been found already, update & select the current-folder row. */ if (file) - { - model_update_current_folder (button, file); - pos = model_get_type_position (button, ROW_TYPE_CURRENT_FOLDER); - } + { + model_update_current_folder (button, file); + pos = model_get_type_position (button, ROW_TYPE_CURRENT_FOLDER); + } else - { - /* No selection; switch to that row */ + { + /* No selection; switch to that row */ - pos = model_get_type_position (button, ROW_TYPE_OTHER_SEPARATOR); - } + pos = model_get_type_position (button, ROW_TYPE_OTHER_SEPARATOR); + } gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (button->filter_model)); @@ -2171,21 +2214,19 @@ update_combo_box (GtkFileChooserButton *button) /* Button */ static void -update_label_get_info_cb (GCancellable *cancellable, - GFileInfo *info, - const GError *error, - gpointer data) +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; - - button->update_button_cancellable = NULL; + g_clear_object (&button->update_button_cancellable); - 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,46 +2264,48 @@ update_label_and_image (GtkFileChooserButton *button) if (file) { - GtkFileSystemVolume *volume = NULL; + GMount *mount; + GFile *base_file; + + 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; - volume = _gtk_file_system_get_volume_for_file (button->fs, file); - if (volume) + if (base_file && g_file_equal (base_file, file)) { - GFile *base_file; - - base_file = _gtk_file_system_volume_get_root (volume); - 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); - 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); - } + GIcon *icon; - if (base_file) - g_object_unref (base_file); + 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); + g_clear_object (&icon); + } - _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 (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, - "standard::icon,standard::display-name", - update_label_get_info_cb, - g_object_ref (button)); + 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)); } else { @@ -2275,7 +2318,7 @@ update_label_and_image (GtkFileChooserButton *button) if (icon) g_object_unref (icon); - done_changing_selection = TRUE; + done_changing_selection = TRUE; } } else @@ -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,23 +2351,193 @@ 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, - gpointer user_data) +volumes_changed (GVolumeMonitor *volume_monitor, + gpointer volume, + gpointer user_data) { GtkFileChooserButton *button = GTK_FILE_CHOOSER_BUTTON (user_data); GSList *volumes; model_remove_rows (user_data, - model_get_type_position (user_data, ROW_TYPE_VOLUME), - button->n_volumes); + model_get_type_position (user_data, ROW_TYPE_VOLUME), + button->n_volumes); 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)); @@ -2341,8 +2553,8 @@ bookmarks_changed_cb (gpointer user_data) bookmarks = _gtk_bookmarks_manager_list_bookmarks (button->bookmarks_manager); model_remove_rows (user_data, - model_get_type_position (user_data, ROW_TYPE_BOOKMARK_SEPARATOR), - button->n_bookmarks + button->has_bookmark_separator); + model_get_type_position (user_data, ROW_TYPE_BOOKMARK_SEPARATOR), + button->n_bookmarks + button->has_bookmark_separator); button->has_bookmark_separator = FALSE; button->n_bookmarks = 0; model_add_bookmarks (user_data, bookmarks); @@ -2439,7 +2651,7 @@ open_dialog (GtkFileChooserButton *button) /* Combo Box */ static void combo_box_changed_cb (GtkComboBox *combo_box, - gpointer user_data) + gpointer user_data) { GtkFileChooserButton *button = GTK_FILE_CHOOSER_BUTTON (user_data); GtkTreeIter iter; @@ -2456,41 +2668,36 @@ combo_box_changed_cb (GtkComboBox *combo_box, data = NULL; gtk_tree_model_get (button->filter_model, &iter, - TYPE_COLUMN, &type, - DATA_COLUMN, &data, - -1); + TYPE_COLUMN, &type, + DATA_COLUMN, &data, + -1); switch (type) - { - case ROW_TYPE_SPECIAL: - case ROW_TYPE_SHORTCUT: - case ROW_TYPE_BOOKMARK: - case ROW_TYPE_CURRENT_FOLDER: - if (data) - { - gtk_file_chooser_button_select_file (GTK_FILE_CHOOSER (button), data, NULL); - file_was_set = TRUE; - } - break; - case ROW_TYPE_VOLUME: - { - GFile *base_file; - - base_file = _gtk_file_system_volume_get_root (data); - if (base_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); - break; - default: - break; - } + { + case ROW_TYPE_SPECIAL: + case ROW_TYPE_SHORTCUT: + case ROW_TYPE_BOOKMARK: + case ROW_TYPE_CURRENT_FOLDER: + if (data) + { + gtk_file_chooser_button_select_file (GTK_FILE_CHOOSER (button), data, NULL); + file_was_set = TRUE; + } + break; + case ROW_TYPE_VOLUME: + { + 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); + break; + default: + break; + } } if (file_was_set) @@ -2500,7 +2707,7 @@ combo_box_changed_cb (GtkComboBox *combo_box, /* Button */ static void button_clicked_cb (GtkButton *real_button, - gpointer user_data) + gpointer user_data) { open_dialog (user_data); } @@ -2509,7 +2716,7 @@ button_clicked_cb (GtkButton *real_button, static void common_response_cb (GtkFileChooserButton *button, - gint response) + gint response) { if (response == GTK_RESPONSE_ACCEPT || response == GTK_RESPONSE_OK) @@ -2533,8 +2740,8 @@ common_response_cb (GtkFileChooserButton *button, static void dialog_response_cb (GtkDialog *dialog, - gint response, - gpointer user_data) + gint response, + gpointer user_data) { GtkFileChooserButton *button = GTK_FILE_CHOOSER_BUTTON (user_data); @@ -2549,8 +2756,8 @@ dialog_response_cb (GtkDialog *dialog, static void native_response_cb (GtkFileChooserNative *native, - gint response, - gpointer user_data) + gint response, + gpointer user_data) { GtkFileChooserButton *button = GTK_FILE_CHOOSER_BUTTON (user_data); @@ -2579,15 +2786,15 @@ native_response_cb (GtkFileChooserNative *native, */ GtkWidget * gtk_file_chooser_button_new (const gchar *title, - GtkFileChooserAction action) + GtkFileChooserAction action) { g_return_val_if_fail (action == GTK_FILE_CHOOSER_ACTION_OPEN || - action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER, NULL); + action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER, NULL); return g_object_new (GTK_TYPE_FILE_CHOOSER_BUTTON, - "action", action, - "title", (title ? title : _(DEFAULT_TITLE)), - NULL); + "action", action, + "title", (title ? title : _(DEFAULT_TITLE)), + NULL); } /** @@ -2613,8 +2820,8 @@ gtk_file_chooser_button_new_with_dialog (GtkWidget *dialog) g_return_val_if_fail (GTK_IS_FILE_CHOOSER (dialog) && GTK_IS_DIALOG (dialog), NULL); return g_object_new (GTK_TYPE_FILE_CHOOSER_BUTTON, - "dialog", dialog, - NULL); + "dialog", dialog, + NULL); } /** @@ -2626,7 +2833,7 @@ gtk_file_chooser_button_new_with_dialog (GtkWidget *dialog) */ void gtk_file_chooser_button_set_title (GtkFileChooserButton *button, - const gchar *title) + const gchar *title) { g_return_if_fail (GTK_IS_FILE_CHOOSER_BUTTON (button)); @@ -2682,7 +2889,7 @@ gtk_file_chooser_button_get_width_chars (GtkFileChooserButton *button) */ void gtk_file_chooser_button_set_width_chars (GtkFileChooserButton *button, - gint n_chars) + gint n_chars) { g_return_if_fail (GTK_IS_FILE_CHOOSER_BUTTON (button)); diff --git a/gtk/gtkfilechooserdialog.c b/gtk/gtkfilechooserdialog.c index a7bc1dd15f..d27ba8e3c0 100644 --- a/gtk/gtkfilechooserdialog.c +++ b/gtk/gtkfilechooserdialog.c @@ -26,7 +26,6 @@ #include "gtkfilechooserwidgetprivate.h" #include "gtkfilechooserutils.h" #include "gtkfilechooserembed.h" -#include "gtkfilesystem.h" #include "gtksizerequest.h" #include "gtktypebuiltins.h" #include "gtkintl.h" diff --git a/gtk/gtkfilechooserentry.c b/gtk/gtkfilechooserentry.c index 695d3db352..97e36f0994 100644 --- a/gtk/gtkfilechooserentry.c +++ b/gtk/gtkfilechooserentry.c @@ -25,7 +25,7 @@ #include "gtkcelllayout.h" #include "gtkcellrenderertext.h" #include "gtkentryprivate.h" -#include "gtkfilesystemmodel.h" +#include "gtkfilechooserutils.h" #include "gtklabel.h" #include "gtkmain.h" #include "gtksizerequest.h" diff --git a/gtk/gtkfilechooserentry.h b/gtk/gtkfilechooserentry.h index fb6725e9c9..e1ed9f7304 100644 --- a/gtk/gtkfilechooserentry.h +++ b/gtk/gtkfilechooserentry.h @@ -19,7 +19,6 @@ #ifndef __GTK_FILE_CHOOSER_ENTRY_H__ #define __GTK_FILE_CHOOSER_ENTRY_H__ -#include "gtkfilesystem.h" #include "gtkfilechooser.h" G_BEGIN_DECLS diff --git a/gtk/gtkfilechoosernative.c b/gtk/gtkfilechoosernative.c index b6f7a9b01b..d157dfa002 100644 --- a/gtk/gtkfilechoosernative.c +++ b/gtk/gtkfilechoosernative.c @@ -29,7 +29,6 @@ #include "gtkfilechooserwidgetprivate.h" #include "gtkfilechooserutils.h" #include "gtkfilechooserembed.h" -#include "gtkfilesystem.h" #include "gtksizerequest.h" #include "gtktypebuiltins.h" #include "gtkintl.h" diff --git a/gtk/gtkfilechoosernativeportal.c b/gtk/gtkfilechoosernativeportal.c index d14a28cb34..1aafd3d9fc 100644 --- a/gtk/gtkfilechoosernativeportal.c +++ b/gtk/gtkfilechoosernativeportal.c @@ -29,7 +29,6 @@ #include "gtkfilechooserwidgetprivate.h" #include "gtkfilechooserutils.h" #include "gtkfilechooserembed.h" -#include "gtkfilesystem.h" #include "gtksizerequest.h" #include "gtktypebuiltins.h" #include "gtkintl.h" diff --git a/gtk/gtkfilechoosernativequartz.c b/gtk/gtkfilechoosernativequartz.c index d7cf4113a4..1726942b97 100644 --- a/gtk/gtkfilechoosernativequartz.c +++ b/gtk/gtkfilechoosernativequartz.c @@ -29,7 +29,6 @@ #include "gtkfilechooserwidgetprivate.h" #include "gtkfilechooserutils.h" #include "gtkfilechooserembed.h" -#include "gtkfilesystem.h" #include "gtksizerequest.h" #include "gtktypebuiltins.h" #include "gtkintl.h" diff --git a/gtk/gtkfilechoosernativewin32.c b/gtk/gtkfilechoosernativewin32.c index 66157ccd69..9b43506042 100644 --- a/gtk/gtkfilechoosernativewin32.c +++ b/gtk/gtkfilechoosernativewin32.c @@ -35,7 +35,6 @@ #include "gtkfilechooserwidgetprivate.h" #include "gtkfilechooserutils.h" #include "gtkfilechooserembed.h" -#include "gtkfilesystem.h" #include "gtksizerequest.h" #include "gtktypebuiltins.h" #include "gtkintl.h" diff --git a/gtk/gtkfilechooserprivate.h b/gtk/gtkfilechooserprivate.h index 092d785eb9..2e96ff66e9 100644 --- a/gtk/gtkfilechooserprivate.h +++ b/gtk/gtkfilechooserprivate.h @@ -20,7 +20,6 @@ #define __GTK_FILE_CHOOSER_PRIVATE_H__ #include "gtkfilechooser.h" -#include "gtkfilesystem.h" #include "gtkfilesystemmodel.h" #include "gtkliststore.h" #include "gtkrecentmanager.h" @@ -73,7 +72,6 @@ struct _GtkFileChooserIface void (*select_all) (GtkFileChooser *chooser); void (*unselect_all) (GtkFileChooser *chooser); GListModel * (*get_files) (GtkFileChooser *chooser); - GtkFileSystem *(*get_file_system) (GtkFileChooser *chooser); void (*add_filter) (GtkFileChooser *chooser, GtkFileFilter *filter); void (*remove_filter) (GtkFileChooser *chooser, @@ -109,8 +107,6 @@ struct _GtkFileChooserIface const char *id); }; -GtkFileSystem *_gtk_file_chooser_get_file_system (GtkFileChooser *chooser); - void gtk_file_chooser_select_all (GtkFileChooser *chooser); void gtk_file_chooser_unselect_all (GtkFileChooser *chooser); gboolean gtk_file_chooser_select_file (GtkFileChooser *chooser, diff --git a/gtk/gtkfilechooserutils.c b/gtk/gtkfilechooserutils.c index 0c62e8d590..d51e6f4051 100644 --- a/gtk/gtkfilechooserutils.c +++ b/gtk/gtkfilechooserutils.c @@ -20,7 +20,6 @@ #include "config.h" #include "gtkfilechooserutils.h" #include "gtkfilechooser.h" -#include "gtkfilesystem.h" #include "gtktypebuiltins.h" #include "gtkintl.h" @@ -40,7 +39,6 @@ static void delegate_unselect_file (GtkFileChooser *choose static void delegate_select_all (GtkFileChooser *chooser); static void delegate_unselect_all (GtkFileChooser *chooser); static GListModel * delegate_get_files (GtkFileChooser *chooser); -static GtkFileSystem *delegate_get_file_system (GtkFileChooser *chooser); static void delegate_add_filter (GtkFileChooser *chooser, GtkFileFilter *filter); static void delegate_remove_filter (GtkFileChooser *chooser, @@ -128,7 +126,6 @@ _gtk_file_chooser_delegate_iface_init (GtkFileChooserIface *iface) iface->select_all = delegate_select_all; iface->unselect_all = delegate_unselect_all; iface->get_files = delegate_get_files; - iface->get_file_system = delegate_get_file_system; iface->add_filter = delegate_add_filter; iface->remove_filter = delegate_remove_filter; iface->get_filters = delegate_get_filters; @@ -215,12 +212,6 @@ delegate_get_files (GtkFileChooser *chooser) return gtk_file_chooser_get_files (get_delegate (chooser)); } -static GtkFileSystem * -delegate_get_file_system (GtkFileChooser *chooser) -{ - return _gtk_file_chooser_get_file_system (get_delegate (chooser)); -} - static void delegate_add_filter (GtkFileChooser *chooser, GtkFileFilter *filter) @@ -411,3 +402,76 @@ delegate_get_choice (GtkFileChooser *chooser, { return gtk_file_chooser_get_choice (get_delegate (chooser), id); } + +gboolean +_gtk_file_info_consider_as_directory (GFileInfo *info) +{ + GFileType type = g_file_info_get_file_type (info); + + return (type == G_FILE_TYPE_DIRECTORY || + type == G_FILE_TYPE_MOUNTABLE || + type == G_FILE_TYPE_SHORTCUT); +} + +gboolean +_gtk_file_has_native_path (GFile *file) +{ + char *local_file_path; + gboolean has_native_path; + + /* Don't use g_file_is_native(), as we want to support FUSE paths if available */ + local_file_path = g_file_get_path (file); + has_native_path = (local_file_path != NULL); + g_free (local_file_path); + + return has_native_path; +} + +gboolean +_gtk_file_consider_as_remote (GFile *file) +{ + GFileInfo *info; + gboolean is_remote; + + info = g_file_query_filesystem_info (file, G_FILE_ATTRIBUTE_FILESYSTEM_REMOTE, NULL, NULL); + if (info) + { + is_remote = g_file_info_get_attribute_boolean (info, G_FILE_ATTRIBUTE_FILESYSTEM_REMOTE); + + g_object_unref (info); + } + else + is_remote = FALSE; + + return is_remote; +} + +GIcon * +_gtk_file_info_get_icon (GFileInfo *info, + int icon_size, + int scale) +{ + GIcon *icon; + GdkPixbuf *pixbuf; + const gchar *thumbnail_path; + + thumbnail_path = g_file_info_get_attribute_byte_string (info, G_FILE_ATTRIBUTE_THUMBNAIL_PATH); + + if (thumbnail_path) + { + pixbuf = gdk_pixbuf_new_from_file_at_size (thumbnail_path, + icon_size*scale, icon_size*scale, + NULL); + + if (pixbuf != NULL) + return G_ICON (pixbuf); + } + + icon = g_file_info_get_icon (info); + if (icon) + return g_object_ref (icon); + + /* Use general fallback for all files without icon */ + icon = g_themed_icon_new ("text-x-generic"); + return icon; +} diff --git a/gtk/gtkfilechooserutils.h b/gtk/gtkfilechooserutils.h index 3ca736c996..43041e2885 100644 --- a/gtk/gtkfilechooserutils.h +++ b/gtk/gtkfilechooserutils.h @@ -49,6 +49,13 @@ GSettings *_gtk_file_chooser_get_settings_for_widget (GtkWidget *widget); gchar * _gtk_file_chooser_label_for_file (GFile *file); +gboolean _gtk_file_info_consider_as_directory (GFileInfo *info); +gboolean _gtk_file_has_native_path (GFile *file); +gboolean _gtk_file_consider_as_remote (GFile *file); +GIcon * _gtk_file_info_get_icon (GFileInfo *info, + int icon_size, + int scale); + G_END_DECLS #endif /* __GTK_FILE_CHOOSER_UTILS_H__ */ diff --git a/gtk/gtkfilechooserwidget.c b/gtk/gtkfilechooserwidget.c index ac9e8721a1..b2500b790b 100644 --- a/gtk/gtkfilechooserwidget.c +++ b/gtk/gtkfilechooserwidget.c @@ -38,7 +38,6 @@ #include "gtkfilechooserentry.h" #include "gtkfilechooserutils.h" #include "gtkfilechooser.h" -#include "gtkfilesystem.h" #include "gtkfilesystemmodel.h" #include "gtkgrid.h" #include "gtkicontheme.h" @@ -227,8 +226,6 @@ struct _GtkFileChooserWidget GtkFileChooserAction action; - GtkFileSystem *file_system; - GtkWidget *box; GActionGroup *item_actions; @@ -480,7 +477,6 @@ static void gtk_file_chooser_widget_unselect_file (GtkF static void gtk_file_chooser_widget_select_all (GtkFileChooser *chooser); static void gtk_file_chooser_widget_unselect_all (GtkFileChooser *chooser); static GListModel * gtk_file_chooser_widget_get_files (GtkFileChooser *chooser); -static GtkFileSystem *gtk_file_chooser_widget_get_file_system (GtkFileChooser *chooser); static void gtk_file_chooser_widget_add_filter (GtkFileChooser *chooser, GtkFileFilter *filter); static void gtk_file_chooser_widget_remove_filter (GtkFileChooser *chooser, @@ -612,7 +608,6 @@ gtk_file_chooser_widget_iface_init (GtkFileChooserIface *iface) iface->select_all = gtk_file_chooser_widget_select_all; iface->unselect_all = gtk_file_chooser_widget_unselect_all; iface->get_files = gtk_file_chooser_widget_get_files; - iface->get_file_system = gtk_file_chooser_widget_get_file_system; iface->set_current_folder = gtk_file_chooser_widget_set_current_folder; iface->get_current_folder = gtk_file_chooser_widget_get_current_folder; iface->set_current_name = gtk_file_chooser_widget_set_current_name; @@ -663,8 +658,6 @@ gtk_file_chooser_widget_finalize (GObject *object) if (impl->location_changed_id > 0) g_source_remove (impl->location_changed_id); - g_clear_object (&impl->file_system); - g_free (impl->browse_files_last_selected_name); g_clear_object (&impl->filters); @@ -919,22 +912,18 @@ struct FileExistsData }; static void -name_exists_get_info_cb (GCancellable *cancellable, - GFileInfo *info, - const GError *error, +name_exists_get_info_cb (GObject *source, + GAsyncResult *result, gpointer user_data) { + GFile *file = G_FILE (source); struct FileExistsData *data = user_data; + GFileInfo *info; GtkFileChooserWidget *impl = data->impl; - if (cancellable != impl->file_exists_get_info_cancellable) - goto out; - - impl->file_exists_get_info_cancellable = NULL; - - if (g_cancellable_is_cancelled (cancellable)) - goto out; + g_clear_object (&impl->file_exists_get_info_cancellable); + info = g_file_query_info_finish (file, result, NULL); if (info != NULL) { gtk_widget_set_sensitive (data->button, FALSE); @@ -948,11 +937,10 @@ name_exists_get_info_cb (GCancellable *cancellable, /* Don't clear the label here, it may contain a warning */ } -out: g_object_unref (impl); g_object_unref (data->file); g_free (data); - g_object_unref (cancellable); + g_clear_object (&info); } static void @@ -1014,13 +1002,16 @@ check_valid_child_name (GtkFileChooserWidget *impl, if (impl->file_exists_get_info_cancellable) g_cancellable_cancel (impl->file_exists_get_info_cancellable); - - impl->file_exists_get_info_cancellable = - _gtk_file_system_get_info (impl->file_system, - file, - "standard::type", - name_exists_get_info_cb, - data); + g_clear_object (&impl->file_exists_get_info_cancellable); + + impl->file_exists_get_info_cancellable = g_cancellable_new (); + g_file_query_info_async (file, + "standard::type", + G_FILE_QUERY_INFO_NONE, + G_PRIORITY_DEFAULT, + impl->file_exists_get_info_cancellable, + name_exists_get_info_cb, + data); g_object_unref (file); } @@ -1694,27 +1685,25 @@ typedef struct } FileListDragData; static void -file_list_drag_data_received_get_info_cb (GCancellable *cancellable, - GFileInfo *info, - const GError *error, +file_list_drag_data_received_get_info_cb (GObject *source, + GAsyncResult *result, gpointer user_data) { - gboolean cancelled = g_cancellable_is_cancelled (cancellable); + GFile *file = G_FILE (source); FileListDragData *data = user_data; + GFileInfo *info; GtkFileChooserWidget *impl = data->impl; GtkFileChooser *chooser = GTK_FILE_CHOOSER (impl); - if (cancellable != impl->file_list_drag_data_received_cancellable) - goto out; + g_clear_object (&impl->file_list_drag_data_received_cancellable); - impl->file_list_drag_data_received_cancellable = NULL; - - if (cancelled || error) + info = g_file_query_info_finish (file, result, NULL); + if (!info) goto out; if ((impl->action == GTK_FILE_CHOOSER_ACTION_OPEN || impl->action == GTK_FILE_CHOOSER_ACTION_SAVE) && - data->files->next == NULL && !error && _gtk_file_info_consider_as_directory (info)) + data->files->next == NULL && _gtk_file_info_consider_as_directory (info)) change_folder_and_display_error (data->impl, data->files->data, FALSE); else { @@ -1736,7 +1725,7 @@ out: g_slist_free_full (data->files, g_object_unref); g_free (data); - g_object_unref (cancellable); + g_clear_object (&info); } static gboolean @@ -1757,12 +1746,16 @@ file_list_drag_drop_cb (GtkDropTarget *dest, if (impl->file_list_drag_data_received_cancellable) g_cancellable_cancel (impl->file_list_drag_data_received_cancellable); + g_clear_object (&impl->file_list_drag_data_received_cancellable); - impl->file_list_drag_data_received_cancellable = - _gtk_file_system_get_info (impl->file_system, data->files->data, - "standard::type", - file_list_drag_data_received_get_info_cb, - data); + impl->file_list_drag_data_received_cancellable = g_cancellable_new (); + g_file_query_info_async (data->files->data, + "standard::type", + G_FILE_QUERY_INFO_NONE, + G_PRIORITY_DEFAULT, + impl->file_list_drag_data_received_cancellable, + file_list_drag_data_received_get_info_cb, + data); return TRUE; } @@ -2593,8 +2586,6 @@ gtk_file_chooser_widget_constructed (GObject *object) G_OBJECT_CLASS (gtk_file_chooser_widget_parent_class)->constructed (object); - g_assert (impl->file_system); - update_appearance (impl); profile_end ("end", NULL); @@ -3144,10 +3135,18 @@ cancel_all_operations (GtkFileChooserWidget *impl) { pending_select_files_free (impl); - g_clear_pointer (&impl->file_list_drag_data_received_cancellable, g_cancellable_cancel); - g_clear_pointer (&impl->update_current_folder_cancellable, g_cancellable_cancel); - g_clear_pointer (&impl->should_respond_get_info_cancellable, g_cancellable_cancel); - g_clear_pointer (&impl->file_exists_get_info_cancellable, g_cancellable_cancel); + if (impl->file_list_drag_data_received_cancellable) + g_cancellable_cancel (impl->file_list_drag_data_received_cancellable); + g_clear_object (&impl->file_list_drag_data_received_cancellable); + if (impl->update_current_folder_cancellable) + g_cancellable_cancel (impl->update_current_folder_cancellable); + g_clear_object (&impl->update_current_folder_cancellable); + if (impl->should_respond_get_info_cancellable) + g_cancellable_cancel (impl->should_respond_get_info_cancellable); + g_clear_object (&impl->should_respond_get_info_cancellable); + if (impl->file_exists_get_info_cancellable) + g_cancellable_cancel (impl->file_exists_get_info_cancellable); + g_clear_object (&impl->file_exists_get_info_cancellable); search_stop_searching (impl, TRUE); } @@ -4959,24 +4958,19 @@ struct UpdateCurrentFolderData }; static void -update_current_folder_mount_enclosing_volume_cb (GCancellable *cancellable, - GtkFileSystemVolume *volume, - const GError *error, - gpointer user_data) +update_current_folder_mount_enclosing_volume_cb (GObject *source, + GAsyncResult *result, + gpointer user_data) { + GFile *file = G_FILE (source); struct UpdateCurrentFolderData *data = user_data; GtkFileChooserWidget *impl = data->impl; - gboolean cancelled = g_cancellable_is_cancelled (cancellable); - - if (cancellable != impl->update_current_folder_cancellable) - goto out; + GError *error = NULL; - impl->update_current_folder_cancellable = NULL; + g_clear_object (&impl->update_current_folder_cancellable); set_busy_cursor (impl, FALSE); - if (cancelled) - goto out; - + g_file_mount_enclosing_volume_finish (file, result, &error); if (error) { error_changing_folder_dialog (data->impl, data->file, g_error_copy (error)); @@ -4991,30 +4985,26 @@ out: g_object_unref (data->file); g_free (data); - g_object_unref (cancellable); + g_clear_error (&error); } static void -update_current_folder_get_info_cb (GCancellable *cancellable, - GFileInfo *info, - const GError *error, +update_current_folder_get_info_cb (GObject *source, + GAsyncResult *result, gpointer user_data) { - gboolean cancelled = g_cancellable_is_cancelled (cancellable); + GFile *file = G_FILE (source); struct UpdateCurrentFolderData *data = user_data; + GFileInfo *info; + GError *error = NULL; GtkFileChooserWidget *impl = data->impl; - if (cancellable != impl->update_current_folder_cancellable) - goto out; - - impl->update_current_folder_cancellable = NULL; + g_clear_object (&impl->update_current_folder_cancellable); impl->reload_state = RELOAD_EMPTY; set_busy_cursor (impl, FALSE); - if (cancelled) - goto out; - + info = g_file_query_info_finish (file, result, &error); if (error) { GFile *parent_file; @@ -5024,18 +5014,20 @@ update_current_folder_get_info_cb (GCancellable *cancellable, GMountOperation *mount_operation; GtkWidget *toplevel; - g_object_unref (cancellable); + g_clear_error (&error); toplevel = GTK_WIDGET (gtk_widget_get_root (GTK_WIDGET (impl))); mount_operation = gtk_mount_operation_new (GTK_WINDOW (toplevel)); set_busy_cursor (impl, TRUE); - impl->update_current_folder_cancellable = - _gtk_file_system_mount_enclosing_volume (impl->file_system, data->file, - mount_operation, - update_current_folder_mount_enclosing_volume_cb, - data); + impl->update_current_folder_cancellable = g_cancellable_new (); + g_file_mount_enclosing_volume (data->file, + G_MOUNT_MOUNT_NONE, + mount_operation, + impl->update_current_folder_cancellable, + update_current_folder_mount_enclosing_volume_cb, + data); return; } @@ -5054,16 +5046,19 @@ update_current_folder_get_info_cb (GCancellable *cancellable, g_object_unref (data->file); data->file = parent_file; - g_object_unref (cancellable); + g_clear_error (&error); /* restart the update current folder operation */ impl->reload_state = RELOAD_HAS_FOLDER; - impl->update_current_folder_cancellable = - _gtk_file_system_get_info (impl->file_system, data->file, - "standard::type", - update_current_folder_get_info_cb, - data); + impl->update_current_folder_cancellable = g_cancellable_new (); + g_file_query_info_async (data->file, + "standard::type", + G_FILE_QUERY_INFO_NONE, + G_PRIORITY_DEFAULT, + impl->update_current_folder_cancellable, + update_current_folder_get_info_cb, + data); set_busy_cursor (impl, TRUE); @@ -5079,6 +5074,7 @@ update_current_folder_get_info_cb (GCancellable *cancellable, else g_error_free (data->original_error); + g_clear_error (&error); g_object_unref (data->original_file); goto out; @@ -5143,7 +5139,7 @@ out: g_object_unref (data->file); g_free (data); - g_object_unref (cancellable); + g_clear_object (&info); } static gboolean @@ -5164,6 +5160,7 @@ gtk_file_chooser_widget_update_current_folder (GtkFileChooser *chooser, if (impl->update_current_folder_cancellable) g_cancellable_cancel (impl->update_current_folder_cancellable); + g_clear_object (&impl->update_current_folder_cancellable); /* Test validity of path here. */ data = g_new0 (struct UpdateCurrentFolderData, 1); @@ -5174,11 +5171,14 @@ gtk_file_chooser_widget_update_current_folder (GtkFileChooser *chooser, impl->reload_state = RELOAD_HAS_FOLDER; - impl->update_current_folder_cancellable = - _gtk_file_system_get_info (impl->file_system, file, - "standard::type", - update_current_folder_get_info_cb, - data); + impl->update_current_folder_cancellable = g_cancellable_new (); + g_file_query_info_async (file, + "standard::type", + G_FILE_QUERY_INFO_NONE, + G_PRIORITY_DEFAULT, + impl->update_current_folder_cancellable, + update_current_folder_get_info_cb, + data); set_busy_cursor (impl, TRUE); g_object_unref (file); @@ -5601,14 +5601,6 @@ gtk_file_chooser_widget_get_files (GtkFileChooser *chooser) return G_LIST_MODEL (info.result); } -static GtkFileSystem * -gtk_file_chooser_widget_get_file_system (GtkFileChooser *chooser) -{ - GtkFileChooserWidget *impl = GTK_FILE_CHOOSER_WIDGET (chooser); - - return impl->file_system; -} - /* Shows or hides the filter widgets */ static void show_filters (GtkFileChooserWidget *impl, @@ -5892,23 +5884,18 @@ struct GetDisplayNameData }; static void -confirmation_confirm_get_info_cb (GCancellable *cancellable, - GFileInfo *info, - const GError *error, +confirmation_confirm_get_info_cb (GObject *source, + GAsyncResult *result, gpointer user_data) { - gboolean cancelled = g_cancellable_is_cancelled (cancellable); + GFile *file = G_FILE (source); struct GetDisplayNameData *data = user_data; + GFileInfo *info; - if (cancellable != data->impl->should_respond_get_info_cancellable) - goto out; - - data->impl->should_respond_get_info_cancellable = NULL; - - if (cancelled) - goto out; + g_clear_object (&data->impl->should_respond_get_info_cancellable); - if (error) + info = g_file_query_info_finish (file, result, NULL); + if (!info) goto out; confirm_dialog_should_accept_filename (data->impl, data->file_part, @@ -5921,7 +5908,7 @@ out: g_free (data->file_part); g_free (data); - g_object_unref (cancellable); + g_clear_object (&info); } /* Does overwrite confirmation if appropriate, and returns whether the dialog @@ -5942,38 +5929,38 @@ should_respond_after_confirm_overwrite (GtkFileChooserWidget *impl, if (impl->should_respond_get_info_cancellable) g_cancellable_cancel (impl->should_respond_get_info_cancellable); - - impl->should_respond_get_info_cancellable = - _gtk_file_system_get_info (impl->file_system, parent_file, - "standard::display-name", - confirmation_confirm_get_info_cb, - data); + g_clear_object (&impl->should_respond_get_info_cancellable); + + impl->should_respond_get_info_cancellable = g_cancellable_new (); + g_file_query_info_async (parent_file, + "standard::display-name", + G_FILE_QUERY_INFO_NONE, + G_PRIORITY_DEFAULT, + impl->should_respond_get_info_cancellable, + confirmation_confirm_get_info_cb, + data); set_busy_cursor (data->impl, TRUE); return FALSE; } static void -name_entry_get_parent_info_cb (GCancellable *cancellable, - GFileInfo *info, - const GError *error, +name_entry_get_parent_info_cb (GObject *source, + GAsyncResult *result, gpointer user_data) { + GFile *file = G_FILE (source); + struct FileExistsData *data = user_data; + GFileInfo *info; gboolean parent_is_folder = FALSE; gboolean parent_is_accessible = FALSE; - gboolean cancelled = g_cancellable_is_cancelled (cancellable); - struct FileExistsData *data = user_data; GtkFileChooserWidget *impl = data->impl; + GError *error = NULL; - if (cancellable != impl->should_respond_get_info_cancellable) - goto out; - - impl->should_respond_get_info_cancellable = NULL; + g_clear_object (&impl->should_respond_get_info_cancellable); set_busy_cursor (impl, FALSE); - if (cancelled) - goto out; - + info = g_file_query_info_finish (file, result, &error); if (info) { parent_is_folder = _gtk_file_info_consider_as_directory (info); @@ -6059,39 +6046,35 @@ name_entry_get_parent_info_cb (GCancellable *cancellable, error_changing_folder_dialog (impl, data->parent_file, error_copy); } -out: g_object_unref (data->impl); g_object_unref (data->file); g_object_unref (data->parent_file); g_free (data); - g_object_unref (cancellable); + g_clear_error (&error); + g_clear_object (&info); } static void -file_exists_get_info_cb (GCancellable *cancellable, - GFileInfo *info, - const GError *error, +file_exists_get_info_cb (GObject *source, + GAsyncResult *result, gpointer user_data) { + GFile *file = G_FILE (source); + struct FileExistsData *data = user_data; + GFileInfo *info; gboolean data_ownership_taken = FALSE; - gboolean cancelled = g_cancellable_is_cancelled (cancellable); gboolean file_exists; gboolean is_folder; gboolean needs_parent_check = FALSE; - struct FileExistsData *data = user_data; GtkFileChooserWidget *impl = data->impl; + GError *error = NULL; - if (cancellable != impl->file_exists_get_info_cancellable) - goto out; - - impl->file_exists_get_info_cancellable = NULL; + g_clear_object (&impl->file_exists_get_info_cancellable); set_busy_cursor (impl, FALSE); - if (cancelled) - goto out; - + info = g_file_query_info_finish (file, result, &error); file_exists = (info != NULL); is_folder = (file_exists && _gtk_file_info_consider_as_directory (info)); @@ -6148,17 +6131,19 @@ file_exists_get_info_cb (GCancellable *cancellable, if (impl->should_respond_get_info_cancellable) g_cancellable_cancel (impl->should_respond_get_info_cancellable); - - impl->should_respond_get_info_cancellable = - _gtk_file_system_get_info (impl->file_system, - data->parent_file, - "standard::type,access::can-execute", - name_entry_get_parent_info_cb, - data); + g_clear_object (&impl->should_respond_get_info_cancellable); + + impl->should_respond_get_info_cancellable = g_cancellable_new (); + g_file_query_info_async (data->parent_file, + "standard::type,access::can-execute", + G_FILE_QUERY_INFO_NONE, + G_PRIORITY_DEFAULT, + impl->should_respond_get_info_cancellable, + name_entry_get_parent_info_cb, + data); set_busy_cursor (impl, TRUE); } -out: if (!data_ownership_taken) { g_object_unref (impl); @@ -6167,7 +6152,8 @@ out: g_free (data); } - g_object_unref (cancellable); + g_clear_error (&error); + g_clear_object (&info); } static void @@ -6434,12 +6420,16 @@ gtk_file_chooser_widget_should_respond (GtkFileChooserEmbed *chooser_embed) if (impl->file_exists_get_info_cancellable) g_cancellable_cancel (impl->file_exists_get_info_cancellable); - - impl->file_exists_get_info_cancellable = - _gtk_file_system_get_info (impl->file_system, file, - "standard::type", - file_exists_get_info_cb, - data); + g_clear_object (&impl->file_exists_get_info_cancellable); + + impl->file_exists_get_info_cancellable = g_cancellable_new (); + g_file_query_info_async (file, + "standard::type", + G_FILE_QUERY_INFO_NONE, + G_PRIORITY_DEFAULT, + impl->file_exists_get_info_cancellable, + file_exists_get_info_cb, + data); set_busy_cursor (impl, TRUE); } @@ -7863,8 +7853,6 @@ post_process_ui (GtkFileChooserWidget *impl) file_list_set_sort_column_ids (impl); update_cell_renderer_attributes (impl); - /* Set the GtkPathBar file system backend */ - _gtk_path_bar_set_file_system (GTK_PATH_BAR (impl->browse_path_bar), impl->file_system); file = g_file_new_for_path ("/"); _gtk_path_bar_set_file (GTK_PATH_BAR (impl->browse_path_bar), file, FALSE); g_object_unref (file); @@ -7994,7 +7982,6 @@ gtk_file_chooser_widget_init (GtkFileChooserWidget *impl) g_signal_connect (impl, "notify::display,", G_CALLBACK (display_changed_cb), impl); check_icon_theme (impl); - impl->file_system = _gtk_file_system_new (); impl->bookmarks_manager = _gtk_bookmarks_manager_new (NULL, NULL); impl->filters = g_list_store_new (GTK_TYPE_FILE_FILTER); diff --git a/gtk/gtkfilesystem.c b/gtk/gtkfilesystem.c deleted file mode 100644 index 4e71446d69..0000000000 --- a/gtk/gtkfilesystem.c +++ /dev/null @@ -1,823 +0,0 @@ -/* GTK - The GIMP Toolkit - * gtkfilesystem.c: Filesystem abstraction functions. - * Copyright (C) 2003, Red Hat, Inc. - * Copyright (C) 2007-2008 Carlos Garnacho - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see <http://www.gnu.org/licenses/>. - * - * Authors: Carlos Garnacho <carlos@imendio.com> - */ - -#include "config.h" - -#include "gtkfilesystem.h" - -#include <string.h> -#include <glib/gi18n-lib.h> - -#include "gtkfilechooser.h" -#include "gtkintl.h" -#include "gtkprivate.h" -#include "gtkstylecontextprivate.h" - -/* #define DEBUG_MODE */ -#ifdef DEBUG_MODE -#define DEBUG(x) g_debug (x); -#else -#define DEBUG(x) -#endif - -#define FILES_PER_QUERY 100 - -/* The pointers we return for a GtkFileSystemVolume are opaque tokens; they are - * really pointers to GDrive, GVolume or GMount objects. We need an extra - * token for the fake “File System” volume. So, we’ll return a pointer to - * this particular string. - */ -static const gchar *root_volume_token = N_("File System"); -#define IS_ROOT_VOLUME(volume) ((gpointer) (volume) == (gpointer) root_volume_token) - -enum { - PROP_0, - PROP_FILE, - PROP_ENUMERATOR, - PROP_ATTRIBUTES -}; - -enum { - VOLUMES_CHANGED, - FS_LAST_SIGNAL -}; - -enum { - FILES_ADDED, - FILES_REMOVED, - FILES_CHANGED, - FINISHED_LOADING, - DELETED, - FOLDER_LAST_SIGNAL -}; - -static guint fs_signals [FS_LAST_SIGNAL] = { 0, }; - -typedef struct AsyncFuncData AsyncFuncData; - -struct GtkFileSystemPrivate -{ - GVolumeMonitor *volume_monitor; - - /* This list contains elements that can be - * of type GDrive, GVolume and GMount - */ - GSList *volumes; -}; - -struct AsyncFuncData -{ - GtkFileSystem *file_system; - GFile *file; - GCancellable *cancellable; - - gpointer callback; - gpointer data; -}; - -G_DEFINE_TYPE_WITH_PRIVATE (GtkFileSystem, _gtk_file_system, G_TYPE_OBJECT) - - -/* GtkFileSystem methods */ -static void -volumes_changed (GVolumeMonitor *volume_monitor, - gpointer volume, - gpointer user_data) -{ - GtkFileSystem *file_system = user_data; - - g_signal_emit (file_system, fs_signals[VOLUMES_CHANGED], 0, volume); -} - -static void -gtk_file_system_dispose (GObject *object) -{ - GtkFileSystem *file_system = GTK_FILE_SYSTEM (object); - GtkFileSystemPrivate *priv = file_system->priv; - - DEBUG ("dispose"); - - if (priv->volumes) - { - g_slist_free_full (priv->volumes, g_object_unref); - priv->volumes = NULL; - } - - if (priv->volume_monitor) - { - g_signal_handlers_disconnect_by_func (priv->volume_monitor, volumes_changed, object); - g_object_unref (priv->volume_monitor); - priv->volume_monitor = NULL; - } - - G_OBJECT_CLASS (_gtk_file_system_parent_class)->dispose (object); -} - -static void -_gtk_file_system_class_init (GtkFileSystemClass *class) -{ - GObjectClass *object_class = G_OBJECT_CLASS (class); - - object_class->dispose = gtk_file_system_dispose; - - fs_signals[VOLUMES_CHANGED] = - g_signal_new (I_("volumes-changed"), - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (GtkFileSystemClass, volumes_changed), - NULL, NULL, - NULL, - G_TYPE_NONE, 0); -} - -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 void -get_volumes_list (GtkFileSystem *file_system) -{ - GtkFileSystemPrivate *priv = file_system->priv; - GList *l, *ll; - GList *drives; - GList *volumes; - GList *mounts; - GDrive *drive; - GVolume *volume; - GMount *mount; - - if (priv->volumes) - { - g_slist_free_full (priv->volumes, g_object_unref); - priv->volumes = NULL; - } - - /* first go through all connected drives */ - drives = g_volume_monitor_get_connected_drives (priv->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 */ - priv->volumes = g_slist_prepend (priv->volumes, 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. - */ - priv->volumes = g_slist_prepend (priv->volumes, 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. - */ - - priv->volumes = g_slist_prepend (priv->volumes, 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 (priv->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 */ - priv->volumes = g_slist_prepend (priv->volumes, g_object_ref (mount)); - g_object_unref (mount); - } - else - { - /* see comment above in why we add an icon for a volume */ - priv->volumes = g_slist_prepend (priv->volumes, 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 (priv->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 */ - priv->volumes = g_slist_prepend (priv->volumes, g_object_ref (mount)); - g_object_unref (mount); - } - - g_list_free (volumes); - - g_list_free (mounts); -} - -static void -_gtk_file_system_init (GtkFileSystem *file_system) -{ - GtkFileSystemPrivate *priv; - - DEBUG ("init"); - - file_system->priv = priv = _gtk_file_system_get_instance_private (file_system); - - /* Volumes */ - priv->volume_monitor = g_volume_monitor_get (); - - g_signal_connect (priv->volume_monitor, "mount-added", - G_CALLBACK (volumes_changed), file_system); - g_signal_connect (priv->volume_monitor, "mount-removed", - G_CALLBACK (volumes_changed), file_system); - g_signal_connect (priv->volume_monitor, "mount-changed", - G_CALLBACK (volumes_changed), file_system); - g_signal_connect (priv->volume_monitor, "volume-added", - G_CALLBACK (volumes_changed), file_system); - g_signal_connect (priv->volume_monitor, "volume-removed", - G_CALLBACK (volumes_changed), file_system); - g_signal_connect (priv->volume_monitor, "volume-changed", - G_CALLBACK (volumes_changed), file_system); - g_signal_connect (priv->volume_monitor, "drive-connected", - G_CALLBACK (volumes_changed), file_system); - g_signal_connect (priv->volume_monitor, "drive-disconnected", - G_CALLBACK (volumes_changed), file_system); - g_signal_connect (priv->volume_monitor, "drive-changed", - G_CALLBACK (volumes_changed), file_system); -} - -/* GtkFileSystem public methods */ -GtkFileSystem * -_gtk_file_system_new (void) -{ - return g_object_new (GTK_TYPE_FILE_SYSTEM, NULL); -} - -GSList * -_gtk_file_system_list_volumes (GtkFileSystem *file_system) -{ - GtkFileSystemPrivate *priv = file_system->priv; - GSList *list; - - DEBUG ("list_volumes"); - - get_volumes_list (file_system); - - list = g_slist_copy (priv->volumes); - -#ifndef G_OS_WIN32 - /* Prepend root volume */ - list = g_slist_prepend (list, (gpointer) root_volume_token); -#endif - - return list; -} - -static void -free_async_data (AsyncFuncData *async_data) -{ - g_object_unref (async_data->file_system); - g_object_unref (async_data->file); - g_object_unref (async_data->cancellable); - - g_free (async_data); -} - -static void -query_info_callback (GObject *source_object, - GAsyncResult *result, - gpointer user_data) -{ - AsyncFuncData *async_data; - GError *error = NULL; - GFileInfo *file_info; - GFile *file; - - DEBUG ("query_info_callback"); - - file = G_FILE (source_object); - async_data = (AsyncFuncData *) user_data; - file_info = g_file_query_info_finish (file, result, &error); - - if (async_data->callback) - { - ((GtkFileSystemGetInfoCallback) async_data->callback) (async_data->cancellable, - file_info, error, async_data->data); - } - - if (file_info) - g_object_unref (file_info); - - if (error) - g_error_free (error); - - free_async_data (async_data); -} - -GCancellable * -_gtk_file_system_get_info (GtkFileSystem *file_system, - GFile *file, - const gchar *attributes, - GtkFileSystemGetInfoCallback callback, - gpointer data) -{ - GCancellable *cancellable; - AsyncFuncData *async_data; - - g_return_val_if_fail (GTK_IS_FILE_SYSTEM (file_system), NULL); - g_return_val_if_fail (G_IS_FILE (file), NULL); - - cancellable = g_cancellable_new (); - - async_data = g_new0 (AsyncFuncData, 1); - async_data->file_system = g_object_ref (file_system); - async_data->file = g_object_ref (file); - async_data->cancellable = g_object_ref (cancellable); - - async_data->callback = callback; - async_data->data = data; - - g_file_query_info_async (file, - attributes, - G_FILE_QUERY_INFO_NONE, - G_PRIORITY_DEFAULT, - cancellable, - query_info_callback, - async_data); - - return cancellable; -} - -static void -drive_poll_for_media_cb (GObject *source_object, - GAsyncResult *result, - gpointer user_data) -{ - AsyncFuncData *async_data; - GError *error = NULL; - - g_drive_poll_for_media_finish (G_DRIVE (source_object), result, &error); - async_data = (AsyncFuncData *) user_data; - - ((GtkFileSystemVolumeMountCallback) async_data->callback) (async_data->cancellable, - (GtkFileSystemVolume *) source_object, - error, async_data->data); - - if (error) - g_error_free (error); -} - -static void -volume_mount_cb (GObject *source_object, - GAsyncResult *result, - gpointer user_data) -{ - AsyncFuncData *async_data; - GError *error = NULL; - - g_volume_mount_finish (G_VOLUME (source_object), result, &error); - async_data = (AsyncFuncData *) user_data; - - ((GtkFileSystemVolumeMountCallback) async_data->callback) (async_data->cancellable, - (GtkFileSystemVolume *) source_object, - error, async_data->data); - - if (error) - g_error_free (error); -} - -GCancellable * -_gtk_file_system_mount_volume (GtkFileSystem *file_system, - GtkFileSystemVolume *volume, - GMountOperation *mount_operation, - GtkFileSystemVolumeMountCallback callback, - gpointer data) -{ - GCancellable *cancellable; - AsyncFuncData *async_data; - gboolean handled = FALSE; - - DEBUG ("volume_mount"); - - cancellable = g_cancellable_new (); - - async_data = g_new0 (AsyncFuncData, 1); - async_data->file_system = g_object_ref (file_system); - async_data->cancellable = g_object_ref (cancellable); - - async_data->callback = callback; - async_data->data = data; - - if (G_IS_DRIVE (volume)) - { - /* this path happens for drives that are not polled by the OS and where the last media - * check indicated that no media was available. So the thing to do here is to - * invoke poll_for_media() on the drive - */ - g_drive_poll_for_media (G_DRIVE (volume), cancellable, drive_poll_for_media_cb, async_data); - handled = TRUE; - } - else if (G_IS_VOLUME (volume)) - { - g_volume_mount (G_VOLUME (volume), G_MOUNT_MOUNT_NONE, mount_operation, cancellable, volume_mount_cb, async_data); - handled = TRUE; - } - - if (!handled) - free_async_data (async_data); - - return cancellable; -} - -static void -enclosing_volume_mount_cb (GObject *source_object, - GAsyncResult *result, - gpointer user_data) -{ - GtkFileSystemVolume *volume; - AsyncFuncData *async_data; - GError *error = NULL; - - async_data = (AsyncFuncData *) user_data; - g_file_mount_enclosing_volume_finish (G_FILE (source_object), result, &error); - volume = _gtk_file_system_get_volume_for_file (async_data->file_system, G_FILE (source_object)); - - /* Silently drop G_IO_ERROR_ALREADY_MOUNTED error for gvfs backends without visible mounts. */ - /* Better than doing query_info with additional I/O every time. */ - if (error && g_error_matches (error, G_IO_ERROR, G_IO_ERROR_ALREADY_MOUNTED)) - g_clear_error (&error); - - ((GtkFileSystemVolumeMountCallback) async_data->callback) (async_data->cancellable, volume, - error, async_data->data); - - if (error) - g_error_free (error); - - _gtk_file_system_volume_unref (volume); -} - -GCancellable * -_gtk_file_system_mount_enclosing_volume (GtkFileSystem *file_system, - GFile *file, - GMountOperation *mount_operation, - GtkFileSystemVolumeMountCallback callback, - gpointer data) -{ - GCancellable *cancellable; - AsyncFuncData *async_data; - - g_return_val_if_fail (GTK_IS_FILE_SYSTEM (file_system), NULL); - g_return_val_if_fail (G_IS_FILE (file), NULL); - - DEBUG ("mount_enclosing_volume"); - - cancellable = g_cancellable_new (); - - async_data = g_new0 (AsyncFuncData, 1); - async_data->file_system = g_object_ref (file_system); - async_data->file = g_object_ref (file); - async_data->cancellable = g_object_ref (cancellable); - - async_data->callback = callback; - async_data->data = data; - - g_file_mount_enclosing_volume (file, - G_MOUNT_MOUNT_NONE, - mount_operation, - cancellable, - enclosing_volume_mount_cb, - async_data); - return cancellable; -} - -GtkFileSystemVolume * -_gtk_file_system_get_volume_for_file (GtkFileSystem *file_system, - GFile *file) -{ - GMount *mount; - - DEBUG ("get_volume_for_file"); - - mount = g_file_find_enclosing_mount (file, NULL, NULL); - - if (!mount && g_file_is_native (file)) - return (GtkFileSystemVolume *) root_volume_token; - - return (GtkFileSystemVolume *) mount; -} - -/* GtkFileSystemVolume public methods */ -gchar * -_gtk_file_system_volume_get_display_name (GtkFileSystemVolume *volume) -{ - DEBUG ("volume_get_display_name"); - - if (IS_ROOT_VOLUME (volume)) - return g_strdup (_(root_volume_token)); - if (G_IS_DRIVE (volume)) - return g_drive_get_name (G_DRIVE (volume)); - else if (G_IS_MOUNT (volume)) - return g_mount_get_name (G_MOUNT (volume)); - else if (G_IS_VOLUME (volume)) - return g_volume_get_name (G_VOLUME (volume)); - - return NULL; -} - -gboolean -_gtk_file_system_volume_is_mounted (GtkFileSystemVolume *volume) -{ - gboolean mounted; - - DEBUG ("volume_is_mounted"); - - if (IS_ROOT_VOLUME (volume)) - return TRUE; - - mounted = FALSE; - - if (G_IS_MOUNT (volume)) - mounted = TRUE; - else if (G_IS_VOLUME (volume)) - { - GMount *mount; - - mount = g_volume_get_mount (G_VOLUME (volume)); - - if (mount) - { - mounted = TRUE; - g_object_unref (mount); - } - } - - return mounted; -} - -GFile * -_gtk_file_system_volume_get_root (GtkFileSystemVolume *volume) -{ - GFile *file = NULL; - - DEBUG ("volume_get_base"); - - if (IS_ROOT_VOLUME (volume)) - return g_file_new_for_uri ("file:///"); - - if (G_IS_MOUNT (volume)) - file = g_mount_get_root (G_MOUNT (volume)); - else if (G_IS_VOLUME (volume)) - { - GMount *mount; - - mount = g_volume_get_mount (G_VOLUME (volume)); - - if (mount) - { - file = g_mount_get_root (mount); - g_object_unref (mount); - } - } - - return file; -} - -GIcon * -_gtk_file_system_volume_get_icon (GtkFileSystemVolume *volume) -{ - GIcon *icon = NULL; - - if (IS_ROOT_VOLUME (volume)) - icon = g_themed_icon_new ("drive-harddisk"); - else if (G_IS_DRIVE (volume)) - icon = g_drive_get_icon (G_DRIVE (volume)); - else if (G_IS_VOLUME (volume)) - icon = g_volume_get_icon (G_VOLUME (volume)); - else if (G_IS_MOUNT (volume)) - icon = g_mount_get_icon (G_MOUNT (volume)); - - return icon; -} - -GIcon * -_gtk_file_system_volume_get_symbolic_icon (GtkFileSystemVolume *volume) -{ - if (IS_ROOT_VOLUME (volume)) - return g_themed_icon_new ("drive-harddisk-symbolic"); - else if (G_IS_DRIVE (volume)) - return g_drive_get_symbolic_icon (G_DRIVE (volume)); - else if (G_IS_VOLUME (volume)) - return g_volume_get_symbolic_icon (G_VOLUME (volume)); - else if (G_IS_MOUNT (volume)) - return g_mount_get_symbolic_icon (G_MOUNT (volume)); - else - return NULL; -} - -GtkFileSystemVolume * -_gtk_file_system_volume_ref (GtkFileSystemVolume *volume) -{ - if (IS_ROOT_VOLUME (volume)) - return volume; - - if (G_IS_MOUNT (volume) || - G_IS_VOLUME (volume) || - G_IS_DRIVE (volume)) - g_object_ref (volume); - - return volume; -} - -void -_gtk_file_system_volume_unref (GtkFileSystemVolume *volume) -{ - /* Root volume doesn't need to be freed */ - if (IS_ROOT_VOLUME (volume)) - return; - - if (G_IS_MOUNT (volume) || - G_IS_VOLUME (volume) || - G_IS_DRIVE (volume)) - g_object_unref (volume); -} - -/* GFileInfo helper functions */ -GIcon * -_gtk_file_info_get_icon (GFileInfo *info, - int icon_size, - int scale) -{ - GIcon *icon; - GdkPixbuf *pixbuf; - const gchar *thumbnail_path; - - thumbnail_path = g_file_info_get_attribute_byte_string (info, G_FILE_ATTRIBUTE_THUMBNAIL_PATH); - - if (thumbnail_path) - { - pixbuf = gdk_pixbuf_new_from_file_at_size (thumbnail_path, - icon_size*scale, icon_size*scale, - NULL); - - if (pixbuf != NULL) - return G_ICON (pixbuf); - } - - icon = g_file_info_get_icon (info); - if (icon) - return g_object_ref (icon); - - /* Use general fallback for all files without icon */ - icon = g_themed_icon_new ("text-x-generic"); - return icon; -} - -gboolean -_gtk_file_info_consider_as_directory (GFileInfo *info) -{ - GFileType type = g_file_info_get_file_type (info); - - return (type == G_FILE_TYPE_DIRECTORY || - type == G_FILE_TYPE_MOUNTABLE || - type == G_FILE_TYPE_SHORTCUT); -} - -gboolean -_gtk_file_has_native_path (GFile *file) -{ - char *local_file_path; - gboolean has_native_path; - - /* Don't use g_file_is_native(), as we want to support FUSE paths if available */ - local_file_path = g_file_get_path (file); - has_native_path = (local_file_path != NULL); - g_free (local_file_path); - - return has_native_path; -} - -gboolean -_gtk_file_consider_as_remote (GFile *file) -{ - GFileInfo *info; - gboolean is_remote; - - info = g_file_query_filesystem_info (file, G_FILE_ATTRIBUTE_FILESYSTEM_REMOTE, NULL, NULL); - if (info) - { - is_remote = g_file_info_get_attribute_boolean (info, G_FILE_ATTRIBUTE_FILESYSTEM_REMOTE); - - g_object_unref (info); - } - else - is_remote = FALSE; - - return is_remote; -} diff --git a/gtk/gtkfilesystem.h b/gtk/gtkfilesystem.h deleted file mode 100644 index c734dfcede..0000000000 --- a/gtk/gtkfilesystem.h +++ /dev/null @@ -1,116 +0,0 @@ -/* GTK - The GIMP Toolkit - * gtkfilesystem.h: Filesystem abstraction functions. - * Copyright (C) 2003, Red Hat, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see <http://www.gnu.org/licenses/>. - */ - -#ifndef __GTK_FILE_SYSTEM_H__ -#define __GTK_FILE_SYSTEM_H__ - -#include <gio/gio.h> -#include <gtk/gtkwidget.h> /* For icon handling */ - -G_BEGIN_DECLS - -#define GTK_TYPE_FILE_SYSTEM (_gtk_file_system_get_type ()) -#define GTK_FILE_SYSTEM(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GTK_TYPE_FILE_SYSTEM, GtkFileSystem)) -#define GTK_FILE_SYSTEM_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), GTK_TYPE_FILE_SYSTEM, GtkFileSystemClass)) -#define GTK_IS_FILE_SYSTEM(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GTK_TYPE_FILE_SYSTEM)) -#define GTK_IS_FILE_SYSTEM_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), GTK_TYPE_FILE_SYSTEM)) -#define GTK_FILE_SYSTEM_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GTK_TYPE_FILE_SYSTEM, GtkFileSystemClass)) - -typedef struct GtkFileSystem GtkFileSystem; -typedef struct GtkFileSystemPrivate GtkFileSystemPrivate; -typedef struct GtkFileSystemClass GtkFileSystemClass; - - -typedef struct GtkFileSystemVolume GtkFileSystemVolume; /* opaque struct */ - - -struct GtkFileSystem -{ - GObject parent_object; - - GtkFileSystemPrivate *priv; -}; - -struct GtkFileSystemClass -{ - GObjectClass parent_class; - - void (*volumes_changed) (GtkFileSystem *file_system); -}; - - -typedef void (* GtkFileSystemGetInfoCallback) (GCancellable *cancellable, - GFileInfo *file_info, - const GError *error, - gpointer data); -typedef void (* GtkFileSystemVolumeMountCallback) (GCancellable *cancellable, - GtkFileSystemVolume *volume, - const GError *error, - gpointer data); - -/* GtkFileSystem methods */ -GType _gtk_file_system_get_type (void) G_GNUC_CONST; - -GtkFileSystem * _gtk_file_system_new (void); - -GSList * _gtk_file_system_list_volumes (GtkFileSystem *file_system); - -GCancellable * _gtk_file_system_get_info (GtkFileSystem *file_system, - GFile *file, - const gchar *attributes, - GtkFileSystemGetInfoCallback callback, - gpointer data); -GCancellable * _gtk_file_system_mount_volume (GtkFileSystem *file_system, - GtkFileSystemVolume *volume, - GMountOperation *mount_operation, - GtkFileSystemVolumeMountCallback callback, - gpointer data); -GCancellable * _gtk_file_system_mount_enclosing_volume (GtkFileSystem *file_system, - GFile *file, - GMountOperation *mount_operation, - GtkFileSystemVolumeMountCallback callback, - gpointer data); - -GtkFileSystemVolume * _gtk_file_system_get_volume_for_file (GtkFileSystem *file_system, - GFile *file); - -/* GtkFileSystemVolume methods */ -gchar * _gtk_file_system_volume_get_display_name (GtkFileSystemVolume *volume); -gboolean _gtk_file_system_volume_is_mounted (GtkFileSystemVolume *volume); -GFile * _gtk_file_system_volume_get_root (GtkFileSystemVolume *volume); -GIcon * _gtk_file_system_volume_get_symbolic_icon (GtkFileSystemVolume *volume); -GIcon * _gtk_file_system_volume_get_icon (GtkFileSystemVolume *volume); - -GtkFileSystemVolume *_gtk_file_system_volume_ref (GtkFileSystemVolume *volume); -void _gtk_file_system_volume_unref (GtkFileSystemVolume *volume); - -/* GFileInfo helper functions */ -GIcon * _gtk_file_info_get_icon (GFileInfo *info, - int icon_size, - int scale); - -gboolean _gtk_file_info_consider_as_directory (GFileInfo *info); - -/* GFile helper functions */ -gboolean _gtk_file_has_native_path (GFile *file); - -gboolean _gtk_file_consider_as_remote (GFile *file); - -G_END_DECLS - -#endif /* __GTK_FILE_SYSTEM_H__ */ diff --git a/gtk/gtkfilesystemmodel.c b/gtk/gtkfilesystemmodel.c index 006cb1252b..a541b88ba9 100644 --- a/gtk/gtkfilesystemmodel.c +++ b/gtk/gtkfilesystemmodel.c @@ -23,7 +23,7 @@ #include <stdlib.h> #include <string.h> -#include "gtkfilesystem.h" +#include "gtkfilechooserutils.h" #include "gtkintl.h" #include "gtkmarshalers.h" #include "gtktreedatalist.h" diff --git a/gtk/gtknativedialog.c b/gtk/gtknativedialog.c index 784455e118..1ba13798c5 100644 --- a/gtk/gtknativedialog.c +++ b/gtk/gtknativedialog.c @@ -28,7 +28,6 @@ #include "gtkfilechooserwidgetprivate.h" #include "gtkfilechooserutils.h" #include "gtkfilechooserembed.h" -#include "gtkfilesystem.h" #include "gtksizerequest.h" #include "gtktypebuiltins.h" #include "gtkintl.h" diff --git a/gtk/gtkpathbar.c b/gtk/gtkpathbar.c index ce7ac14e2d..cdaf541ef5 100644 --- a/gtk/gtkpathbar.c +++ b/gtk/gtkpathbar.c @@ -37,9 +37,10 @@ #include "gtkeventcontrollerscroll.h" #include "gtkdragsource.h" -typedef struct +struct _GtkPathBar { - GtkFileSystem *file_system; + GtkWidget parent_instance; + GFile *root_file; GFile *home_file; GFile *desktop_file; @@ -80,7 +81,19 @@ typedef struct GtkWidget *up_slider_button; GtkWidget *down_slider_button; gint16 slider_width; -} GtkPathBarPrivate; +}; + +typedef struct _GtkPathBarClass GtkPathBarClass; + +struct _GtkPathBarClass +{ + GtkWidgetClass parent_class; + + void (* path_clicked) (GtkPathBar *path_bar, + GFile *file, + GFile *child_file, + gboolean child_is_hidden); +}; enum { PATH_CLICKED, @@ -118,7 +131,7 @@ struct _ButtonData */ #define BUTTON_IS_FAKE_ROOT(button) ((button)->type == HOME_BUTTON) -G_DEFINE_TYPE_WITH_PRIVATE (GtkPathBar, gtk_path_bar, GTK_TYPE_WIDGET) +G_DEFINE_TYPE (GtkPathBar, gtk_path_bar, GTK_TYPE_WIDGET) static void gtk_path_bar_finalize (GObject *object); static void gtk_path_bar_dispose (GObject *object); @@ -146,30 +159,27 @@ static gboolean gtk_path_bar_scroll_controller_scroll (GtkEventControllerScroll static void add_cancellable (GtkPathBar *path_bar, - GCancellable *cancellable) + GCancellable *cancellable) { - GtkPathBarPrivate *priv = gtk_path_bar_get_instance_private (path_bar); - - g_assert (g_list_find (priv->cancellables, cancellable) == NULL); - priv->cancellables = g_list_prepend (priv->cancellables, cancellable); + g_assert (g_list_find (path_bar->cancellables, cancellable) == NULL); + path_bar->cancellables = g_list_prepend (path_bar->cancellables, cancellable); } static void drop_node_for_cancellable (GtkPathBar *path_bar, - GCancellable *cancellable) + GCancellable *cancellable) { - GtkPathBarPrivate *priv = gtk_path_bar_get_instance_private (path_bar); GList *node; - node = g_list_find (priv->cancellables, cancellable); + node = g_list_find (path_bar->cancellables, cancellable); g_assert (node != NULL); node->data = NULL; - priv->cancellables = g_list_delete_link (priv->cancellables, node); + path_bar->cancellables = g_list_delete_link (path_bar->cancellables, node); } static void cancel_cancellable (GtkPathBar *path_bar, - GCancellable *cancellable) + GCancellable *cancellable) { drop_node_for_cancellable (path_bar, cancellable); g_cancellable_cancel (cancellable); @@ -177,7 +187,7 @@ cancel_cancellable (GtkPathBar *path_bar, static void cancellable_async_done (GtkPathBar *path_bar, - GCancellable *cancellable) + GCancellable *cancellable) { drop_node_for_cancellable (path_bar, cancellable); g_object_unref (cancellable); @@ -186,11 +196,9 @@ cancellable_async_done (GtkPathBar *path_bar, static void cancel_all_cancellables (GtkPathBar *path_bar) { - GtkPathBarPrivate *priv = gtk_path_bar_get_instance_private (path_bar); - - while (priv->cancellables) + while (path_bar->cancellables) { - GCancellable *cancellable = priv->cancellables->data; + GCancellable *cancellable = path_bar->cancellables->data; cancel_cancellable (path_bar, cancellable); } } @@ -198,27 +206,27 @@ cancel_all_cancellables (GtkPathBar *path_bar) static void gtk_path_bar_init (GtkPathBar *path_bar) { - GtkPathBarPrivate *priv = gtk_path_bar_get_instance_private (path_bar); GtkEventController *controller; + const char *home; - priv->up_slider_button = gtk_button_new_from_icon_name ("pan-start-symbolic"); - gtk_widget_set_parent (priv->up_slider_button, GTK_WIDGET (path_bar)); + path_bar->up_slider_button = gtk_button_new_from_icon_name ("pan-start-symbolic"); + gtk_widget_set_parent (path_bar->up_slider_button, GTK_WIDGET (path_bar)); - priv->down_slider_button = gtk_button_new_from_icon_name ("pan-end-symbolic"); - gtk_widget_set_parent (priv->down_slider_button, GTK_WIDGET (path_bar)); + path_bar->down_slider_button = gtk_button_new_from_icon_name ("pan-end-symbolic"); + gtk_widget_set_parent (path_bar->down_slider_button, GTK_WIDGET (path_bar)); /* GtkBuilder wont let us connect 'swapped' without specifying the signal's * user data in the .ui file */ - g_signal_connect_swapped (priv->up_slider_button, "clicked", + g_signal_connect_swapped (path_bar->up_slider_button, "clicked", G_CALLBACK (gtk_path_bar_scroll_up), path_bar); - g_signal_connect_swapped (priv->down_slider_button, "clicked", + g_signal_connect_swapped (path_bar->down_slider_button, "clicked", G_CALLBACK (gtk_path_bar_scroll_down), path_bar); gtk_widget_add_css_class (GTK_WIDGET (path_bar), GTK_STYLE_CLASS_LINKED); - priv->get_info_cancellable = NULL; - priv->cancellables = NULL; + path_bar->get_info_cancellable = NULL; + path_bar->cancellables = NULL; controller = gtk_event_controller_scroll_new (GTK_EVENT_CONTROLLER_SCROLL_VERTICAL | GTK_EVENT_CONTROLLER_SCROLL_DISCRETE); @@ -226,6 +234,28 @@ gtk_path_bar_init (GtkPathBar *path_bar) G_CALLBACK (gtk_path_bar_scroll_controller_scroll), path_bar); gtk_widget_add_controller (GTK_WIDGET (path_bar), controller); + + home = g_get_home_dir (); + if (home != NULL) + { + const gchar *desktop; + + path_bar->home_file = g_file_new_for_path (home); + /* FIXME: Need file system backend specific way of getting the + * Desktop path. + */ + desktop = g_get_user_special_dir (G_USER_DIRECTORY_DESKTOP); + if (desktop != NULL) + path_bar->desktop_file = g_file_new_for_path (desktop); + else + path_bar->desktop_file = NULL; + } + else + { + path_bar->home_file = NULL; + path_bar->desktop_file = NULL; + } + path_bar->root_file = g_file_new_for_path ("/"); } static void @@ -262,20 +292,17 @@ static void gtk_path_bar_finalize (GObject *object) { GtkPathBar *path_bar = GTK_PATH_BAR (object); - GtkPathBarPrivate *priv = gtk_path_bar_get_instance_private (path_bar); cancel_all_cancellables (path_bar); - g_list_free (priv->button_list); - g_clear_object (&priv->root_file); - g_clear_object (&priv->home_file); - g_clear_object (&priv->desktop_file); + g_list_free (path_bar->button_list); + g_clear_object (&path_bar->root_file); + g_clear_object (&path_bar->home_file); + g_clear_object (&path_bar->desktop_file); - g_clear_object (&priv->root_icon); - g_clear_object (&priv->home_icon); - g_clear_object (&priv->desktop_icon); - - g_clear_object (&priv->file_system); + g_clear_object (&path_bar->root_icon); + g_clear_object (&path_bar->home_icon); + g_clear_object (&path_bar->desktop_icon); G_OBJECT_CLASS (gtk_path_bar_parent_class)->finalize (object); } @@ -284,13 +311,12 @@ static void gtk_path_bar_dispose (GObject *object) { GtkPathBar *path_bar = GTK_PATH_BAR (object); - GtkPathBarPrivate *priv = gtk_path_bar_get_instance_private (path_bar); GtkWidget *w; while ((w = gtk_widget_get_first_child (GTK_WIDGET (path_bar))) != NULL) gtk_widget_unparent (w); - priv->get_info_cancellable = NULL; + path_bar->get_info_cancellable = NULL; cancel_all_cancellables (path_bar); G_OBJECT_CLASS (gtk_path_bar_parent_class)->dispose (object); @@ -306,7 +332,6 @@ gtk_path_bar_measure (GtkWidget *widget, int *natural_baseline) { GtkPathBar *path_bar = GTK_PATH_BAR (widget); - GtkPathBarPrivate *priv = gtk_path_bar_get_instance_private (path_bar); ButtonData *button_data; GList *list; int child_size; @@ -318,7 +343,7 @@ gtk_path_bar_measure (GtkWidget *widget, if (orientation == GTK_ORIENTATION_HORIZONTAL) { - for (list = priv->button_list; list; list = list->next) + for (list = path_bar->button_list; list; list = list->next) { button_data = BUTTON_DATA (list->data); gtk_widget_measure (button_data->button, GTK_ORIENTATION_HORIZONTAL, -1, @@ -342,30 +367,30 @@ gtk_path_bar_measure (GtkWidget *widget, /* Theoretically, the slider could be bigger than the other button. But we're * not going to worry about that now. */ - priv->slider_width = 0; + path_bar->slider_width = 0; - gtk_widget_measure (priv->up_slider_button, GTK_ORIENTATION_HORIZONTAL, -1, + gtk_widget_measure (path_bar->up_slider_button, GTK_ORIENTATION_HORIZONTAL, -1, &child_min, &child_nat, NULL, NULL); - if (priv->button_list && priv->button_list->next != NULL) + if (path_bar->button_list && path_bar->button_list->next != NULL) { *minimum += child_min; *natural += child_nat; } - priv->slider_width = MAX (priv->slider_width, child_min); + path_bar->slider_width = MAX (path_bar->slider_width, child_min); - gtk_widget_measure (priv->down_slider_button, GTK_ORIENTATION_HORIZONTAL, -1, + gtk_widget_measure (path_bar->down_slider_button, GTK_ORIENTATION_HORIZONTAL, -1, &child_min, &child_nat, NULL, NULL); - if (priv->button_list && priv->button_list->next != NULL) + if (path_bar->button_list && path_bar->button_list->next != NULL) { *minimum += child_min; *natural += child_nat; } - priv->slider_width = MAX (priv->slider_width, child_min); + path_bar->slider_width = MAX (path_bar->slider_width, child_min); } else /* VERTICAL */ { - for (list = priv->button_list; list; list = list->next) + for (list = path_bar->button_list; list; list = list->next) { button_data = BUTTON_DATA (list->data); gtk_widget_measure (button_data->button, GTK_ORIENTATION_VERTICAL, -1, @@ -375,12 +400,12 @@ gtk_path_bar_measure (GtkWidget *widget, *natural = MAX (*natural, child_nat); } - gtk_widget_measure (priv->up_slider_button, GTK_ORIENTATION_VERTICAL, -1, + gtk_widget_measure (path_bar->up_slider_button, GTK_ORIENTATION_VERTICAL, -1, &child_min, &child_nat, NULL, NULL); *minimum = MAX (*minimum, child_min); *natural = MAX (*natural, child_nat); - gtk_widget_measure (priv->up_slider_button, GTK_ORIENTATION_VERTICAL, -1, + gtk_widget_measure (path_bar->up_slider_button, GTK_ORIENTATION_VERTICAL, -1, &child_min, &child_nat, NULL, NULL); *minimum = MAX (*minimum, child_min); *natural = MAX (*natural, child_nat); @@ -390,23 +415,21 @@ gtk_path_bar_measure (GtkWidget *widget, static void gtk_path_bar_update_slider_buttons (GtkPathBar *path_bar) { - GtkPathBarPrivate *priv = gtk_path_bar_get_instance_private (path_bar); - - if (priv->button_list) + if (path_bar->button_list) { GtkWidget *button; - button = BUTTON_DATA (priv->button_list->data)->button; + button = BUTTON_DATA (path_bar->button_list->data)->button; if (gtk_widget_get_child_visible (button)) - gtk_widget_set_sensitive (priv->down_slider_button, FALSE); + gtk_widget_set_sensitive (path_bar->down_slider_button, FALSE); else - gtk_widget_set_sensitive (priv->down_slider_button, TRUE); + gtk_widget_set_sensitive (path_bar->down_slider_button, TRUE); - button = BUTTON_DATA (g_list_last (priv->button_list)->data)->button; + button = BUTTON_DATA (g_list_last (path_bar->button_list)->data)->button; if (gtk_widget_get_child_visible (button)) - gtk_widget_set_sensitive (priv->up_slider_button, FALSE); + gtk_widget_set_sensitive (path_bar->up_slider_button, FALSE); else - gtk_widget_set_sensitive (priv->up_slider_button, TRUE); + gtk_widget_set_sensitive (path_bar->up_slider_button, TRUE); } } @@ -419,7 +442,6 @@ gtk_path_bar_size_allocate (GtkWidget *widget, int baseline) { GtkPathBar *path_bar = GTK_PATH_BAR (widget); - GtkPathBarPrivate *priv = gtk_path_bar_get_instance_private (path_bar); GtkWidget *child; GtkTextDirection direction; GtkAllocation child_allocation; @@ -432,45 +454,45 @@ gtk_path_bar_size_allocate (GtkWidget *widget, GtkRequisition child_requisition; /* No path is set; we don't have to allocate anything. */ - if (priv->button_list == NULL) + if (path_bar->button_list == NULL) return; direction = gtk_widget_get_direction (widget); allocation_width = widget_width; /* First, we check to see if we need the scrollbars. */ - if (priv->fake_root) - width = priv->slider_width; + if (path_bar->fake_root) + width = path_bar->slider_width; else width = 0; - for (list = priv->button_list; list; list = list->next) + for (list = path_bar->button_list; list; list = list->next) { child = BUTTON_DATA (list->data)->button; gtk_widget_get_preferred_size (child, &child_requisition, NULL); width += child_requisition.width; - if (list == priv->fake_root) + if (list == path_bar->fake_root) break; } if (width <= allocation_width) { - if (priv->fake_root) - first_button = priv->fake_root; + if (path_bar->fake_root) + first_button = path_bar->fake_root; else - first_button = g_list_last (priv->button_list); + first_button = g_list_last (path_bar->button_list); } else { gboolean reached_end = FALSE; - gint slider_space = 2 * priv->slider_width; + gint slider_space = 2 * path_bar->slider_width; - if (priv->first_scrolled_button) - first_button = priv->first_scrolled_button; + if (path_bar->first_scrolled_button) + first_button = path_bar->first_scrolled_button; else - first_button = priv->button_list; + first_button = path_bar->button_list; need_sliders = TRUE; /* To see how much space we have, and how many buttons we can display. @@ -491,7 +513,7 @@ gtk_path_bar_size_allocate (GtkWidget *widget, if (width + child_requisition.width + slider_space > allocation_width) reached_end = TRUE; - else if (list == priv->fake_root) + else if (list == path_bar->fake_root) break; else width += child_requisition.width; @@ -514,7 +536,7 @@ gtk_path_bar_size_allocate (GtkWidget *widget, else { width += child_requisition.width; - if (first_button == priv->fake_root) + if (first_button == path_bar->fake_root) break; first_button = first_button->next; } @@ -528,19 +550,19 @@ gtk_path_bar_size_allocate (GtkWidget *widget, if (direction == GTK_TEXT_DIR_RTL) { child_allocation.x = widget_width; - if (need_sliders || priv->fake_root) + if (need_sliders || path_bar->fake_root) { - child_allocation.x -= priv->slider_width; - up_slider_offset = widget_width - priv->slider_width; + child_allocation.x -= path_bar->slider_width; + up_slider_offset = widget_width - path_bar->slider_width; } } else { child_allocation.x = 0; - if (need_sliders || priv->fake_root) + if (need_sliders || path_bar->fake_root) { up_slider_offset = 0; - child_allocation.x += priv->slider_width; + child_allocation.x += path_bar->slider_width; } } @@ -555,7 +577,7 @@ gtk_path_bar_size_allocate (GtkWidget *widget, gtk_widget_get_preferred_size (child, &child_requisition, NULL); child_allocation.width = MIN (child_requisition.width, - allocation_width - 2 * priv->slider_width); + allocation_width - 2 * path_bar->slider_width); if (direction == GTK_TEXT_DIR_RTL) child_allocation.x -= child_allocation.width; @@ -564,13 +586,13 @@ gtk_path_bar_size_allocate (GtkWidget *widget, if (need_sliders && direction == GTK_TEXT_DIR_RTL) { gtk_widget_get_allocation (widget, &widget_allocation); - if (child_allocation.x - priv->slider_width < widget_allocation.x) + if (child_allocation.x - path_bar->slider_width < widget_allocation.x) break; } else if (need_sliders && direction == GTK_TEXT_DIR_LTR) { gtk_widget_get_allocation (widget, &widget_allocation); - if (child_allocation.x + child_allocation.width + priv->slider_width > + if (child_allocation.x + child_allocation.width + path_bar->slider_width > widget_allocation.x + allocation_width) break; } @@ -588,7 +610,7 @@ gtk_path_bar_size_allocate (GtkWidget *widget, if (direction == GTK_TEXT_DIR_RTL) { - down_slider_offset = child_allocation.x - priv->slider_width; + down_slider_offset = child_allocation.x - path_bar->slider_width; } else { @@ -609,41 +631,41 @@ gtk_path_bar_size_allocate (GtkWidget *widget, gtk_widget_set_child_visible (child, FALSE); } - if (need_sliders || priv->fake_root) + if (need_sliders || path_bar->fake_root) { - child_allocation.width = priv->slider_width; + child_allocation.width = path_bar->slider_width; child_allocation.x = up_slider_offset; - gtk_widget_size_allocate (priv->up_slider_button, + gtk_widget_size_allocate (path_bar->up_slider_button, &child_allocation, -1); - gtk_widget_set_child_visible (priv->up_slider_button, TRUE); - gtk_widget_show (priv->up_slider_button); + gtk_widget_set_child_visible (path_bar->up_slider_button, TRUE); + gtk_widget_show (path_bar->up_slider_button); if (direction == GTK_TEXT_DIR_LTR) - down_slider_offset += priv->slider_width; + down_slider_offset += path_bar->slider_width; } else { - gtk_widget_set_child_visible (priv->up_slider_button, FALSE); + gtk_widget_set_child_visible (path_bar->up_slider_button, FALSE); } if (need_sliders) { - child_allocation.width = priv->slider_width; + child_allocation.width = path_bar->slider_width; child_allocation.x = down_slider_offset; - gtk_widget_size_allocate (priv->down_slider_button, + gtk_widget_size_allocate (path_bar->down_slider_button, &child_allocation, -1); - gtk_widget_set_child_visible (priv->down_slider_button, TRUE); - gtk_widget_show (priv->down_slider_button); + gtk_widget_set_child_visible (path_bar->down_slider_button, TRUE); + gtk_widget_show (path_bar->down_slider_button); gtk_path_bar_update_slider_buttons (path_bar); } else { - gtk_widget_set_child_visible (priv->down_slider_button, FALSE); + gtk_widget_set_child_visible (path_bar->down_slider_button, FALSE); } } @@ -664,13 +686,12 @@ gtk_path_bar_scroll_controller_scroll (GtkEventControllerScroll *scroll, static void gtk_path_bar_scroll_down (GtkPathBar *path_bar) { - GtkPathBarPrivate *priv = gtk_path_bar_get_instance_private (path_bar); GtkAllocation allocation, button_allocation; GList *list; GList *down_button = NULL; gint space_available; - if (gtk_widget_get_child_visible (BUTTON_DATA (priv->button_list->data)->button)) + if (gtk_widget_get_child_visible (BUTTON_DATA (path_bar->button_list->data)->button)) { /* Return if the last button is already visible */ return; @@ -680,7 +701,7 @@ gtk_path_bar_scroll_down (GtkPathBar *path_bar) /* We find the button at the 'down' end that we have to make * visible */ - for (list = priv->button_list; list; list = list->next) + for (list = path_bar->button_list; list; list = list->next) { if (list->next && gtk_widget_get_child_visible (BUTTON_DATA (list->next->data)->button)) { @@ -694,16 +715,16 @@ gtk_path_bar_scroll_down (GtkPathBar *path_bar) gtk_widget_get_allocation (BUTTON_DATA (down_button->data)->button, &button_allocation); space_available = (allocation.width - - 2 * priv->slider_width + - 2 * path_bar->slider_width - button_allocation.width); - priv->first_scrolled_button = down_button; + path_bar->first_scrolled_button = down_button; /* We have space_available free space that's not being used. * So we walk down from the end, adding buttons until we use all free space. */ while (space_available > 0) { - priv->first_scrolled_button = down_button; + path_bar->first_scrolled_button = down_button; down_button = down_button->next; if (!down_button) break; @@ -714,10 +735,9 @@ gtk_path_bar_scroll_down (GtkPathBar *path_bar) static void gtk_path_bar_scroll_up (GtkPathBar *path_bar) { - GtkPathBarPrivate *priv = gtk_path_bar_get_instance_private (path_bar); GList *list; - list = g_list_last (priv->button_list); + list = g_list_last (path_bar->button_list); if (gtk_widget_get_child_visible (BUTTON_DATA (list->data)->button)) { @@ -731,26 +751,25 @@ gtk_path_bar_scroll_up (GtkPathBar *path_bar) { if (list->prev && gtk_widget_get_child_visible (BUTTON_DATA (list->prev->data)->button)) { - if (list->prev == priv->fake_root) - priv->fake_root = NULL; - priv->first_scrolled_button = list; + if (list->prev == path_bar->fake_root) + path_bar->fake_root = NULL; + path_bar->first_scrolled_button = list; return; } } } static void -gtk_path_bar_clear_buttons (GtkPathBar *self) +gtk_path_bar_clear_buttons (GtkPathBar *path_bar) { - GtkPathBarPrivate *priv = gtk_path_bar_get_instance_private (self); GtkWidget *w; - w = gtk_widget_get_first_child (GTK_WIDGET (self)); + w = gtk_widget_get_first_child (GTK_WIDGET (path_bar)); while (w) { GtkWidget *next = gtk_widget_get_next_sibling (w); - if (w != priv->up_slider_button && w != priv->down_slider_button) + if (w != path_bar->up_slider_button && w != path_bar->down_slider_button) { gtk_widget_unparent (w); } @@ -758,8 +777,8 @@ gtk_path_bar_clear_buttons (GtkPathBar *self) w = next; } - priv->first_scrolled_button = NULL; - priv->fake_root = NULL; + path_bar->first_scrolled_button = NULL; + path_bar->fake_root = NULL; } static void @@ -767,7 +786,6 @@ button_clicked_cb (GtkWidget *button, gpointer data) { GtkPathBar *path_bar; - GtkPathBarPrivate *priv; ButtonData *button_data; GList *button_list; gboolean child_is_hidden; @@ -778,9 +796,8 @@ button_clicked_cb (GtkWidget *button, return; path_bar = GTK_PATH_BAR (gtk_widget_get_parent (button)); - priv = gtk_path_bar_get_instance_private (path_bar); - button_list = g_list_find (priv->button_list, button_data); + button_list = g_list_find (path_bar->button_list, button_data); g_assert (button_list != NULL); g_signal_handlers_block_by_func (button, @@ -814,50 +831,42 @@ struct SetButtonImageData }; static void -set_button_image_get_info_cb (GCancellable *cancellable, - GFileInfo *info, - const GError *error, - gpointer user_data) +set_button_image_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 SetButtonImageData *data = user_data; - GtkPathBarPrivate *priv = gtk_path_bar_get_instance_private (data->path_bar); + GFileInfo *info; + GIcon *icon; - if (cancelled) - { - g_free (data); - g_object_unref (cancellable); - return; - } + info = g_file_query_info_finish (file, result, NULL); + if (!info) + goto out; g_assert (GTK_IS_PATH_BAR (data->path_bar)); g_assert (G_OBJECT (data->path_bar)->ref_count > 0); - g_assert (cancellable == data->button_data->cancellable); - cancellable_async_done (data->path_bar, cancellable); + cancellable_async_done (data->path_bar, data->button_data->cancellable); data->button_data->cancellable = NULL; - if (error) - goto out; - icon = g_file_info_get_symbolic_icon (info); gtk_image_set_from_gicon (GTK_IMAGE (data->button_data->image), icon); switch (data->button_data->type) { case HOME_BUTTON: - g_set_object (&priv->home_icon, icon); - break; + g_set_object (&data->path_bar->home_icon, icon); + break; case DESKTOP_BUTTON: - g_set_object (&priv->desktop_icon, icon); - break; + g_set_object (&data->path_bar->desktop_icon, icon); + break; case NORMAL_BUTTON: case ROOT_BUTTON: default: - break; + break; }; out: @@ -866,36 +875,40 @@ out: static void set_button_image (GtkPathBar *path_bar, - ButtonData *button_data) + ButtonData *button_data) { - GtkPathBarPrivate *priv = gtk_path_bar_get_instance_private (path_bar); - GtkFileSystemVolume *volume; struct SetButtonImageData *data; + GMount *mount; switch (button_data->type) { case ROOT_BUTTON: - if (priv->root_icon != NULL) + if (path_bar->root_icon != NULL) { - gtk_image_set_from_gicon (GTK_IMAGE (button_data->image), priv->root_icon); + gtk_image_set_from_gicon (GTK_IMAGE (button_data->image), path_bar->root_icon); break; } - volume = _gtk_file_system_get_volume_for_file (priv->file_system, priv->root_file); - if (volume == NULL) - return; + mount = g_file_find_enclosing_mount (button_data->file, NULL, NULL); - priv->root_icon = _gtk_file_system_volume_get_symbolic_icon (volume); - _gtk_file_system_volume_unref (volume); - gtk_image_set_from_gicon (GTK_IMAGE (button_data->image), priv->root_icon); + if (!mount && g_file_is_native (button_data->file)) + path_bar->root_icon = g_themed_icon_new ("drive-harddisk-symbolic"); + else if (mount) + path_bar->root_icon = g_mount_get_symbolic_icon (mount); + else + path_bar->root_icon = NULL; + + g_clear_object (&mount); + + gtk_image_set_from_gicon (GTK_IMAGE (button_data->image), path_bar->root_icon); break; case HOME_BUTTON: - if (priv->home_icon != NULL) + if (path_bar->home_icon != NULL) { - gtk_image_set_from_gicon (GTK_IMAGE (button_data->image), priv->home_icon); + gtk_image_set_from_gicon (GTK_IMAGE (button_data->image), path_bar->home_icon); break; } @@ -904,23 +917,26 @@ set_button_image (GtkPathBar *path_bar, data->button_data = button_data; if (button_data->cancellable) - { - cancel_cancellable (path_bar, button_data->cancellable); - } + { + cancel_cancellable (path_bar, button_data->cancellable); + g_clear_object (&button_data->cancellable); + } - button_data->cancellable = - _gtk_file_system_get_info (priv->file_system, - priv->home_file, - "standard::symbolic-icon", - set_button_image_get_info_cb, - data); + button_data->cancellable = g_cancellable_new (); + g_file_query_info_async (path_bar->home_file, + "standard::symbolic-icon", + G_FILE_QUERY_INFO_NONE, + G_PRIORITY_DEFAULT, + button_data->cancellable, + set_button_image_get_info_cb, + data); add_cancellable (path_bar, button_data->cancellable); break; case DESKTOP_BUTTON: - if (priv->desktop_icon != NULL) + if (path_bar->desktop_icon != NULL) { - gtk_image_set_from_gicon (GTK_IMAGE (button_data->image), priv->desktop_icon); + gtk_image_set_from_gicon (GTK_IMAGE (button_data->image), path_bar->desktop_icon); break; } @@ -929,16 +945,19 @@ set_button_image (GtkPathBar *path_bar, data->button_data = button_data; if (button_data->cancellable) - { - cancel_cancellable (path_bar, button_data->cancellable); - } + { + cancel_cancellable (path_bar, button_data->cancellable); + g_clear_object (&button_data->cancellable); + } - button_data->cancellable = - _gtk_file_system_get_info (priv->file_system, - priv->desktop_file, - "standard::symbolic-icon", - set_button_image_get_info_cb, - data); + button_data->cancellable = g_cancellable_new (); + g_file_query_info_async (path_bar->desktop_file, + "standard::symbolic-icon", + G_FILE_QUERY_INFO_NONE, + G_PRIORITY_DEFAULT, + button_data->cancellable, + set_button_image_get_info_cb, + data); add_cancellable (path_bar, button_data->cancellable); break; @@ -998,16 +1017,14 @@ static ButtonType find_button_type (GtkPathBar *path_bar, GFile *file) { - GtkPathBarPrivate *priv = gtk_path_bar_get_instance_private (path_bar); - - if (priv->root_file != NULL && - g_file_equal (file, priv->root_file)) + if (path_bar->root_file != NULL && + g_file_equal (file, path_bar->root_file)) return ROOT_BUTTON; - if (priv->home_file != NULL && - g_file_equal (file, priv->home_file)) + if (path_bar->home_file != NULL && + g_file_equal (file, path_bar->home_file)) return HOME_BUTTON; - if (priv->desktop_file != NULL && - g_file_equal (file, priv->desktop_file)) + if (path_bar->desktop_file != NULL && + g_file_equal (file, path_bar->desktop_file)) return DESKTOP_BUTTON; return NORMAL_BUTTON; @@ -1084,12 +1101,11 @@ static gboolean gtk_path_bar_check_parent_path (GtkPathBar *path_bar, GFile *file) { - GtkPathBarPrivate *priv = gtk_path_bar_get_instance_private (path_bar); GList *list; GList *current_path = NULL; gboolean need_new_fake_root = FALSE; - for (list = priv->button_list; list; list = list->next) + for (list = path_bar->button_list; list; list = list->next) { ButtonData *button_data; @@ -1099,7 +1115,7 @@ gtk_path_bar_check_parent_path (GtkPathBar *path_bar, current_path = list; break; } - if (list == priv->fake_root) + if (list == path_bar->fake_root) need_new_fake_root = TRUE; } @@ -1107,7 +1123,7 @@ gtk_path_bar_check_parent_path (GtkPathBar *path_bar, { if (need_new_fake_root) { - priv->fake_root = NULL; + path_bar->fake_root = NULL; for (list = current_path; list; list = list->next) { ButtonData *button_data; @@ -1115,13 +1131,13 @@ gtk_path_bar_check_parent_path (GtkPathBar *path_bar, button_data = list->data; if (BUTTON_IS_FAKE_ROOT (button_data)) { - priv->fake_root = list; + path_bar->fake_root = list; break; } } } - for (list = priv->button_list; list; list = list->next) + for (list = path_bar->button_list; list; list = list->next) { gtk_path_bar_update_button_appearance (path_bar, BUTTON_DATA (list->data), @@ -1130,7 +1146,7 @@ gtk_path_bar_check_parent_path (GtkPathBar *path_bar, if (!gtk_widget_get_child_visible (BUTTON_DATA (current_path->data)->button)) { - priv->first_scrolled_button = current_path; + path_bar->first_scrolled_button = current_path; gtk_widget_queue_resize (GTK_WIDGET (path_bar)); } @@ -1147,6 +1163,7 @@ struct SetFileInfo GtkPathBar *path_bar; GList *new_buttons; GList *fake_root; + GCancellable *cancellable; gboolean first_directory; }; @@ -1154,21 +1171,19 @@ static void gtk_path_bar_set_file_finish (struct SetFileInfo *info, gboolean result) { - GtkPathBarPrivate *priv = gtk_path_bar_get_instance_private (info->path_bar); - if (result) { GList *l; gtk_path_bar_clear_buttons (info->path_bar); - priv->button_list = g_list_reverse (info->new_buttons); - priv->fake_root = info->fake_root; + info->path_bar->button_list = g_list_reverse (info->new_buttons); + info->path_bar->fake_root = info->fake_root; - for (l = priv->button_list; l; l = l->next) + for (l = info->path_bar->button_list; l; l = l->next) { GtkWidget *button = BUTTON_DATA (l->data)->button; - gtk_widget_insert_after (button, GTK_WIDGET (info->path_bar), priv->up_slider_button); + gtk_widget_insert_after (button, GTK_WIDGET (info->path_bar), info->path_bar->up_slider_button); } } else @@ -1194,44 +1209,38 @@ gtk_path_bar_set_file_finish (struct SetFileInfo *info, } static void -gtk_path_bar_get_info_callback (GCancellable *cancellable, - GFileInfo *info, - const GError *error, - gpointer data) +gtk_path_bar_get_info_callback (GObject *source, + GAsyncResult *result, + gpointer data) { - gboolean cancelled = g_cancellable_is_cancelled (cancellable); + GFile *file = G_FILE (source); struct SetFileInfo *file_info = data; - GtkPathBarPrivate *priv = gtk_path_bar_get_instance_private (file_info->path_bar); + GFileInfo *info; ButtonData *button_data; const gchar *display_name; gboolean is_hidden; - if (cancelled) + info = g_file_query_info_finish (file, result, NULL); + if (!info) { gtk_path_bar_set_file_finish (file_info, FALSE); - g_object_unref (cancellable); return; } g_assert (GTK_IS_PATH_BAR (file_info->path_bar)); g_assert (G_OBJECT (file_info->path_bar)->ref_count > 0); - g_assert (cancellable == priv->get_info_cancellable); - cancellable_async_done (file_info->path_bar, cancellable); - priv->get_info_cancellable = NULL; - - if (!info) - { - gtk_path_bar_set_file_finish (file_info, FALSE); - return; - } + cancellable_async_done (file_info->path_bar, file_info->cancellable); + if (file_info->path_bar->get_info_cancellable == file_info->cancellable) + file_info->path_bar->get_info_cancellable = NULL; + file_info->cancellable = NULL; display_name = g_file_info_get_display_name (info); is_hidden = g_file_info_get_is_hidden (info) || g_file_info_get_is_backup (info); button_data = make_directory_button (file_info->path_bar, display_name, file_info->file, - file_info->first_directory, is_hidden); + file_info->first_directory, is_hidden); g_clear_object (&file_info->file); file_info->new_buttons = g_list_prepend (file_info->new_buttons, button_data); @@ -1256,14 +1265,18 @@ gtk_path_bar_get_info_callback (GCancellable *cancellable, file_info->parent_file = g_file_get_parent (file_info->file); /* Recurse asynchronously */ - priv->get_info_cancellable = _gtk_file_system_get_info (priv->file_system, - file_info->file, - "standard::display-name," - "standard::is-hidden," - "standard::is-backup", - gtk_path_bar_get_info_callback, - file_info); - add_cancellable (file_info->path_bar, priv->get_info_cancellable); + file_info->cancellable = g_cancellable_new (); + file_info->path_bar->get_info_cancellable = file_info->cancellable; + g_file_query_info_async (file_info->file, + "standard::display-name," + "standard::is-hidden," + "standard::is-backup", + G_FILE_QUERY_INFO_NONE, + G_PRIORITY_DEFAULT, + file_info->cancellable, + gtk_path_bar_get_info_callback, + file_info); + add_cancellable (file_info->path_bar, file_info->cancellable); } void @@ -1271,7 +1284,6 @@ _gtk_path_bar_set_file (GtkPathBar *path_bar, GFile *file, gboolean keep_trail) { - GtkPathBarPrivate *priv = gtk_path_bar_get_instance_private (path_bar); struct SetFileInfo *info; g_return_if_fail (GTK_IS_PATH_BAR (path_bar)); @@ -1289,55 +1301,21 @@ _gtk_path_bar_set_file (GtkPathBar *path_bar, info->first_directory = TRUE; info->parent_file = g_file_get_parent (info->file); - if (priv->get_info_cancellable) - { - cancel_cancellable (path_bar, priv->get_info_cancellable); - } - - priv->get_info_cancellable = - _gtk_file_system_get_info (priv->file_system, - info->file, - "standard::display-name,standard::is-hidden,standard::is-backup", - gtk_path_bar_get_info_callback, - info); - add_cancellable (path_bar, priv->get_info_cancellable); -} - -/* FIXME: This should be a construct-only property */ -void -_gtk_path_bar_set_file_system (GtkPathBar *path_bar, - GtkFileSystem *file_system) -{ - GtkPathBarPrivate *priv = gtk_path_bar_get_instance_private (path_bar); - const char *home; - - g_return_if_fail (GTK_IS_PATH_BAR (path_bar)); - - g_assert (priv->file_system == NULL); - - priv->file_system = g_object_ref (file_system); - - home = g_get_home_dir (); - if (home != NULL) - { - const gchar *desktop; - - priv->home_file = g_file_new_for_path (home); - /* FIXME: Need file system backend specific way of getting the - * Desktop path. - */ - desktop = g_get_user_special_dir (G_USER_DIRECTORY_DESKTOP); - if (desktop != NULL) - priv->desktop_file = g_file_new_for_path (desktop); - else - priv->desktop_file = NULL; - } - else - { - priv->home_file = NULL; - priv->desktop_file = NULL; - } - priv->root_file = g_file_new_for_path ("/"); + if (path_bar->get_info_cancellable) + cancel_cancellable (path_bar, path_bar->get_info_cancellable); + + info->cancellable = g_cancellable_new (); + path_bar->get_info_cancellable = info->cancellable; + g_file_query_info_async (info->file, + "standard::display-name," + "standard::is-hidden," + "standard::is-backup", + G_FILE_QUERY_INFO_NONE, + G_PRIORITY_DEFAULT, + info->cancellable, + gtk_path_bar_get_info_callback, + info); + add_cancellable (path_bar, info->cancellable); } /** @@ -1350,10 +1328,9 @@ _gtk_path_bar_set_file_system (GtkPathBar *path_bar, void _gtk_path_bar_up (GtkPathBar *path_bar) { - GtkPathBarPrivate *priv = gtk_path_bar_get_instance_private (path_bar); GList *l; - for (l = priv->button_list; l; l = l->next) + for (l = path_bar->button_list; l; l = l->next) { GtkWidget *button = BUTTON_DATA (l->data)->button; if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button))) @@ -1378,10 +1355,9 @@ _gtk_path_bar_up (GtkPathBar *path_bar) void _gtk_path_bar_down (GtkPathBar *path_bar) { - GtkPathBarPrivate *priv = gtk_path_bar_get_instance_private (path_bar); GList *l; - for (l = priv->button_list; l; l = l->next) + for (l = path_bar->button_list; l; l = l->next) { GtkWidget *button = BUTTON_DATA (l->data)->button; if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button))) diff --git a/gtk/gtkpathbar.h b/gtk/gtkpathbar.h index 1e9c0f1e6c..11ed72455d 100644 --- a/gtk/gtkpathbar.h +++ b/gtk/gtkpathbar.h @@ -19,43 +19,20 @@ #define __GTK_PATH_BAR_H__ #include "gtkwidget.h" -#include "gtkfilesystem.h" G_BEGIN_DECLS -typedef struct _GtkPathBar GtkPathBar; -typedef struct _GtkPathBarClass GtkPathBarClass; +#define GTK_TYPE_PATH_BAR (gtk_path_bar_get_type ()) +#define GTK_PATH_BAR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_PATH_BAR, GtkPathBar)) +#define GTK_IS_PATH_BAR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_PATH_BAR)) - -#define GTK_TYPE_PATH_BAR (gtk_path_bar_get_type ()) -#define GTK_PATH_BAR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_PATH_BAR, GtkPathBar)) -#define GTK_PATH_BAR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_PATH_BAR, GtkPathBarClass)) -#define GTK_IS_PATH_BAR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_PATH_BAR)) -#define GTK_IS_PATH_BAR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_PATH_BAR)) -#define GTK_PATH_BAR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_PATH_BAR, GtkPathBarClass)) - -struct _GtkPathBar -{ - GtkWidget parent_instance; -}; - -struct _GtkPathBarClass -{ - GtkWidgetClass parent_class; - - void (* path_clicked) (GtkPathBar *path_bar, - GFile *file, - GFile *child_file, - gboolean child_is_hidden); -}; +typedef struct _GtkPathBar GtkPathBar; GDK_AVAILABLE_IN_ALL GType gtk_path_bar_get_type (void) G_GNUC_CONST; -void _gtk_path_bar_set_file_system (GtkPathBar *path_bar, - GtkFileSystem *file_system); void _gtk_path_bar_set_file (GtkPathBar *path_bar, - GFile *file, - gboolean keep_trail); + GFile *file, + gboolean keep_trail); void _gtk_path_bar_up (GtkPathBar *path_bar); void _gtk_path_bar_down (GtkPathBar *path_bar); diff --git a/gtk/gtkplacessidebar.c b/gtk/gtkplacessidebar.c index 1131668f58..7c528252e2 100644 --- a/gtk/gtkplacessidebar.c +++ b/gtk/gtkplacessidebar.c @@ -33,7 +33,7 @@ #include "gdk/gdkkeysyms.h" #include "gtkbookmarksmanagerprivate.h" #include "gtkcelllayout.h" -#include "gtkfilesystem.h" +#include "gtkfilechooserutils.h" #include "gtkicontheme.h" #include "gtkintl.h" #include "gtkmain.h" diff --git a/gtk/meson.build b/gtk/meson.build index 02ba60a842..96f626aef3 100644 --- a/gtk/meson.build +++ b/gtk/meson.build @@ -105,7 +105,6 @@ gtk_private_sources = files([ 'gtkfilechoosererrorstack.c', 'gtkfilechoosernativeportal.c', 'gtkfilechooserutils.c', - 'gtkfilesystem.c', 'gtkfilesystemmodel.c', 'gtkgizmo.c', 'gtkgladecatalog.c', |