X-Git-Url: http://pileus.org/git/?a=blobdiff_plain;f=gtk%2Fgtkfilechooserbutton.c;h=a14bd92e2ea74dee58ebf406e82c408412ef0938;hb=a89d420270d1a856e072ed87c365b0176f102e6c;hp=32f3c62ef59fa393a09942ff61439a7ec67db9e0;hpb=7df00df6b6bf7d97883b3dc3870e4a8ddf086bf2;p=~andy%2Fgtk diff --git a/gtk/gtkfilechooserbutton.c b/gtk/gtkfilechooserbutton.c index 32f3c62ef..a14bd92e2 100644 --- a/gtk/gtkfilechooserbutton.c +++ b/gtk/gtkfilechooserbutton.c @@ -1,4 +1,4 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 2 -*- */ +/* -*- Mode: C; c-file-style: "gnu"; tab-width: 8 -*- */ /* GTK+: gtkfilechooserbutton.c * @@ -178,7 +178,8 @@ struct _GtkFileChooserButtonPrivate GtkTreeModel *filter_model; GtkFileSystem *fs; - GFile *old_file; + GFile *selection_while_inactive; + GFile *current_folder_while_inactive; gulong combo_box_changed_id; gulong dialog_file_activated_id; @@ -226,6 +227,17 @@ enum /* 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); +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); +static void gtk_file_chooser_button_unselect_file (GtkFileChooser *chooser, + GFile *file); +static void gtk_file_chooser_button_unselect_all (GtkFileChooser *chooser); +static GSList *gtk_file_chooser_button_get_files (GtkFileChooser *chooser); static gboolean gtk_file_chooser_button_add_shortcut_folder (GtkFileChooser *chooser, GFile *file, GError **error); @@ -561,10 +573,170 @@ gtk_file_chooser_button_file_chooser_iface_init (GtkFileChooserIface *iface) { _gtk_file_chooser_delegate_iface_init (iface); + iface->set_current_folder = gtk_file_chooser_button_set_current_folder; + iface->get_current_folder = gtk_file_chooser_button_get_current_folder; + iface->select_file = gtk_file_chooser_button_select_file; + iface->unselect_file = gtk_file_chooser_button_unselect_file; + iface->unselect_all = gtk_file_chooser_button_unselect_all; + iface->get_files = gtk_file_chooser_button_get_files; iface->add_shortcut_folder = gtk_file_chooser_button_add_shortcut_folder; iface->remove_shortcut_folder = gtk_file_chooser_button_remove_shortcut_folder; } +static gboolean +gtk_file_chooser_button_set_current_folder (GtkFileChooser *chooser, + GFile *file, + GError **error) +{ + GtkFileChooserButton *button = GTK_FILE_CHOOSER_BUTTON (chooser); + GtkFileChooserButtonPrivate *priv = button->priv; + GtkFileChooser *delegate; + + delegate = g_object_get_qdata (G_OBJECT (chooser), + GTK_FILE_CHOOSER_DELEGATE_QUARK); + + if (priv->active) + return gtk_file_chooser_set_current_folder_file (delegate, file, error); + else + { + if (priv->current_folder_while_inactive) + g_object_unref (priv->current_folder_while_inactive); + + priv->current_folder_while_inactive = g_object_ref (file); + + g_signal_emit_by_name (button, "current-folder-changed"); + + return TRUE; + } +} + +static GFile * +gtk_file_chooser_button_get_current_folder (GtkFileChooser *chooser) +{ + GtkFileChooserButton *button = GTK_FILE_CHOOSER_BUTTON (chooser); + GtkFileChooserButtonPrivate *priv = button->priv; + GtkFileChooser *delegate; + + delegate = g_object_get_qdata (G_OBJECT (chooser), + GTK_FILE_CHOOSER_DELEGATE_QUARK); + + if (priv->active) + return gtk_file_chooser_get_current_folder_file (delegate); + else + { + if (priv->current_folder_while_inactive) + return g_object_ref (priv->current_folder_while_inactive); + else + return NULL; + } +} + +static gboolean +gtk_file_chooser_button_select_file (GtkFileChooser *chooser, + GFile *file, + GError **error) +{ + GtkFileChooserButton *button = GTK_FILE_CHOOSER_BUTTON (chooser); + GtkFileChooserButtonPrivate *priv = button->priv; + GtkFileChooser *delegate; + + delegate = g_object_get_qdata (G_OBJECT (chooser), + GTK_FILE_CHOOSER_DELEGATE_QUARK); + + if (priv->active) + return gtk_file_chooser_select_file (delegate, file, error); + else + { + if (priv->selection_while_inactive) + g_object_unref (priv->selection_while_inactive); + + priv->selection_while_inactive = g_object_ref (file); + + return TRUE; + } +} + +static void +gtk_file_chooser_button_unselect_file (GtkFileChooser *chooser, + GFile *file) +{ + GtkFileChooserButton *button = GTK_FILE_CHOOSER_BUTTON (chooser); + GtkFileChooserButtonPrivate *priv = button->priv; + GtkFileChooser *delegate; + + delegate = g_object_get_qdata (G_OBJECT (chooser), + GTK_FILE_CHOOSER_DELEGATE_QUARK); + + if (priv->active) + gtk_file_chooser_unselect_file (delegate, file); + else + { + if (g_file_equal (priv->selection_while_inactive, file)) + { + if (priv->selection_while_inactive) + { + g_object_unref (priv->selection_while_inactive); + priv->selection_while_inactive = NULL; + } + } + } +} + +static void +gtk_file_chooser_button_unselect_all (GtkFileChooser *chooser) +{ + GtkFileChooserButton *button = GTK_FILE_CHOOSER_BUTTON (chooser); + GtkFileChooserButtonPrivate *priv = button->priv; + GtkFileChooser *delegate; + + delegate = g_object_get_qdata (G_OBJECT (chooser), + GTK_FILE_CHOOSER_DELEGATE_QUARK); + + if (priv->active) + gtk_file_chooser_unselect_all (delegate); + else + { + if (priv->selection_while_inactive) + { + g_object_unref (priv->selection_while_inactive); + priv->selection_while_inactive = NULL; + } + } +} + +static GSList * +gtk_file_chooser_button_get_files (GtkFileChooser *chooser) +{ + GtkFileChooserButton *button = GTK_FILE_CHOOSER_BUTTON (chooser); + GtkFileChooserButtonPrivate *priv = button->priv; + GtkFileChooser *delegate; + + delegate = g_object_get_qdata (G_OBJECT (chooser), + GTK_FILE_CHOOSER_DELEGATE_QUARK); + + if (priv->active) + return gtk_file_chooser_get_files (delegate); + else + { + GSList *result; + + result = NULL; + + if (priv->selection_while_inactive) + result = g_slist_prepend (NULL, g_object_ref (priv->selection_while_inactive)); + else if (gtk_file_chooser_get_action (GTK_FILE_CHOOSER (priv->dialog)) == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER) + { + /* If there is no "real" selection in SELECT_FOLDER mode, then we'll just return + * the current folder, since that is what GtkFileChooserDefault would do. + */ + if (priv->current_folder_while_inactive) + result = g_slist_prepend (NULL, g_object_ref (priv->current_folder_while_inactive)); + } + + return result; + } +} + static gboolean gtk_file_chooser_button_add_shortcut_folder (GtkFileChooser *chooser, GFile *file, @@ -669,7 +841,6 @@ gtk_file_chooser_button_constructor (GType type, GtkFileChooserButton *button; GtkFileChooserButtonPrivate *priv; GSList *list; - char *current_folder; object = G_OBJECT_CLASS (gtk_file_chooser_button_parent_class)->constructor (type, n_params, @@ -904,8 +1075,11 @@ gtk_file_chooser_button_finalize (GObject *object) GtkFileChooserButton *button = GTK_FILE_CHOOSER_BUTTON (object); GtkFileChooserButtonPrivate *priv = button->priv; - if (priv->old_file) - g_object_unref (priv->old_file); + if (priv->selection_while_inactive) + g_object_unref (priv->selection_while_inactive); + + if (priv->current_folder_while_inactive) + g_object_unref (priv->current_folder_while_inactive); G_OBJECT_CLASS (gtk_file_chooser_button_parent_class)->finalize (object); } @@ -1161,8 +1335,6 @@ gtk_file_chooser_button_hide (GtkWidget *widget) static void gtk_file_chooser_button_map (GtkWidget *widget) { - GtkFileChooserButton *button = GTK_FILE_CHOOSER_BUTTON (widget); - GTK_WIDGET_CLASS (gtk_file_chooser_button_parent_class)->map (widget); } @@ -1782,7 +1954,7 @@ model_add_volumes (GtkFileChooserButton *button, base_file = _gtk_file_system_volume_get_root (volume); if (base_file != NULL) { - if (!g_file_is_native (base_file)) + if (!_gtk_file_has_native_path (base_file)) { g_object_unref (base_file); continue; @@ -1842,7 +2014,7 @@ model_add_bookmarks (GtkFileChooserButton *button, file = l->data; - if (g_file_is_native (file)) + if (_gtk_file_has_native_path (file)) { gtk_list_store_insert (store, &iter, pos); gtk_list_store_set (store, &iter, @@ -2064,7 +2236,7 @@ test_if_file_is_visible (GtkFileSystem *fs, if (!file) return FALSE; - if (local_only && !g_file_is_native (file)) + if (local_only && !_gtk_file_has_native_path (file)) return FALSE; if (!is_folder) @@ -2117,7 +2289,7 @@ filter_model_visible_func (GtkTreeModel *model, if (base_file) { - if (!g_file_is_native (base_file)) + if (!_gtk_file_has_native_path (base_file)) retval = FALSE; g_object_unref (base_file); } @@ -2174,13 +2346,13 @@ static void update_combo_box (GtkFileChooserButton *button) { GtkFileChooserButtonPrivate *priv = button->priv; - GSList *files; + GFile *file; GtkTreeIter iter; gboolean row_found; gtk_tree_model_get_iter_first (priv->filter_model, &iter); - files = gtk_file_chooser_get_files (GTK_FILE_CHOOSER (priv->dialog)); + file = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (priv->dialog)); row_found = FALSE; @@ -2203,9 +2375,7 @@ update_combo_box (GtkFileChooserButton *button) case ROW_TYPE_SHORTCUT: case ROW_TYPE_BOOKMARK: case ROW_TYPE_CURRENT_FOLDER: - row_found = (files && - files->data && - g_file_equal (data, files->data)); + row_found = (file && g_file_equal (data, file)); break; case ROW_TYPE_VOLUME: { @@ -2214,9 +2384,7 @@ update_combo_box (GtkFileChooserButton *button) base_file = _gtk_file_system_volume_get_root (data); if (base_file) { - row_found = (files && - files->data && - g_file_equal (base_file, files->data)); + row_found = (file && g_file_equal (base_file, file)); g_object_unref (base_file); } } @@ -2238,12 +2406,12 @@ update_combo_box (GtkFileChooserButton *button) while (!row_found && gtk_tree_model_iter_next (priv->filter_model, &iter)); /* If it hasn't been found already, update & select the current-folder row. */ - if (!row_found && files && files->data) + if (!row_found && file) { GtkTreeIter filter_iter; gint pos; - model_update_current_folder (button, files->data); + model_update_current_folder (button, file); gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (priv->filter_model)); pos = model_get_type_position (button, ROW_TYPE_CURRENT_FOLDER); @@ -2257,8 +2425,8 @@ update_combo_box (GtkFileChooserButton *button) g_signal_handler_unblock (priv->combo_box, priv->combo_box_changed_id); } - g_slist_foreach (files, (GFunc) g_object_unref, NULL); - g_slist_free (files); + if (file) + g_object_unref (file); } /* Button */ @@ -2304,9 +2472,9 @@ update_label_and_image (GtkFileChooserButton *button) { GtkFileChooserButtonPrivate *priv = button->priv; gchar *label_text; - GSList *files; + GFile *file; - files = gtk_file_chooser_get_files (GTK_FILE_CHOOSER (priv->dialog)); + file = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (priv->dialog)); label_text = NULL; if (priv->update_button_cancellable) @@ -2315,13 +2483,10 @@ update_label_and_image (GtkFileChooserButton *button) priv->update_button_cancellable = NULL; } - if (files && files->data) + if (file) { - GFile *file; GtkFileSystemVolume *volume = NULL; - file = files->data; - volume = _gtk_file_system_get_volume_for_file (priv->fs, file); if (volume) { @@ -2371,10 +2536,10 @@ update_label_and_image (GtkFileChooserButton *button) if (pixbuf) g_object_unref (pixbuf); } + + g_object_unref (file); } out: - g_slist_foreach (files, (GFunc) g_object_unref, NULL); - g_slist_free (files); if (label_text) { @@ -2443,6 +2608,35 @@ fs_bookmarks_changed_cb (GtkFileSystem *fs, update_combo_box (user_data); } +static void +save_inactive_state (GtkFileChooserButton *button) +{ + GtkFileChooserButtonPrivate *priv = button->priv; + + if (priv->current_folder_while_inactive) + g_object_unref (priv->current_folder_while_inactive); + + if (priv->selection_while_inactive) + g_object_unref (priv->selection_while_inactive); + + priv->current_folder_while_inactive = gtk_file_chooser_get_current_folder_file (GTK_FILE_CHOOSER (priv->dialog)); + priv->selection_while_inactive = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (priv->dialog)); +} + +static void +restore_inactive_state (GtkFileChooserButton *button) +{ + GtkFileChooserButtonPrivate *priv = button->priv; + + if (priv->current_folder_while_inactive) + gtk_file_chooser_set_current_folder_file (GTK_FILE_CHOOSER (priv->dialog), priv->current_folder_while_inactive, NULL); + + if (priv->selection_while_inactive) + gtk_file_chooser_select_file (GTK_FILE_CHOOSER (priv->dialog), priv->selection_while_inactive, NULL); + else + gtk_file_chooser_unselect_all (GTK_FILE_CHOOSER (priv->dialog)); +} + /* Dialog */ static void open_dialog (GtkFileChooserButton *button) @@ -2470,23 +2664,14 @@ open_dialog (GtkFileChooserButton *button) if (!priv->active) { - GSList *files; - g_signal_handler_block (priv->dialog, priv->dialog_folder_changed_id); g_signal_handler_block (priv->dialog, priv->dialog_file_activated_id); g_signal_handler_block (priv->dialog, priv->dialog_selection_changed_id); - files = gtk_file_chooser_get_files (GTK_FILE_CHOOSER (priv->dialog)); - if (files) - { - if (files->data) - priv->old_file = g_object_ref (files->data); - g_slist_foreach (files, (GFunc) g_object_unref, NULL); - g_slist_free (files); - } + restore_inactive_state (button); priv->active = TRUE; } @@ -2624,7 +2809,7 @@ dialog_notify_cb (GObject *dialog, /* If the path isn't local but we're in local-only mode now, remove * the custom-folder row */ - if (data && g_file_is_native (G_FILE (data)) && + if (data && _gtk_file_has_native_path (G_FILE (data)) && gtk_file_chooser_get_local_only (GTK_FILE_CHOOSER (priv->dialog))) { pos--; @@ -2658,36 +2843,17 @@ dialog_response_cb (GtkDialog *dialog, if (response == GTK_RESPONSE_ACCEPT || response == GTK_RESPONSE_OK) { + save_inactive_state (button); + g_signal_emit_by_name (button, "current-folder-changed"); g_signal_emit_by_name (button, "selection-changed"); update_label_and_image (button); update_combo_box (button); } - else if (priv->old_file) - { - switch (gtk_file_chooser_get_action (GTK_FILE_CHOOSER (dialog))) - { - case GTK_FILE_CHOOSER_ACTION_OPEN: - gtk_file_chooser_select_file (GTK_FILE_CHOOSER (dialog), priv->old_file, - NULL); - break; - case GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER: - gtk_file_chooser_set_current_folder_file (GTK_FILE_CHOOSER (dialog), - priv->old_file, NULL); - break; - default: - g_assert_not_reached (); - break; - } - } else - gtk_file_chooser_unselect_all (GTK_FILE_CHOOSER (dialog)); - - if (priv->old_file) { - g_object_unref (priv->old_file); - priv->old_file = NULL; + restore_inactive_state (button); } if (priv->active)