+static void
+emit_selection_changed_if_changing_selection (GtkFileChooserButton *button)
+{
+ GtkFileChooserButtonPrivate *priv = button->priv;
+
+ if (priv->is_changing_selection)
+ {
+ priv->is_changing_selection = FALSE;
+ g_signal_emit_by_name (button, "selection-changed");
+ }
+}
+
+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;
+
+ if (priv->current_folder_while_inactive)
+ g_object_unref (priv->current_folder_while_inactive);
+
+ priv->current_folder_while_inactive = g_object_ref (file);
+
+ update_combo_box (button);
+
+ g_signal_emit_by_name (button, "current-folder-changed");
+
+ if (priv->active)
+ gtk_file_chooser_set_current_folder_file (GTK_FILE_CHOOSER (priv->dialog), file, NULL);
+
+ return TRUE;
+}
+
+static GFile *
+gtk_file_chooser_button_get_current_folder (GtkFileChooser *chooser)
+{
+ GtkFileChooserButton *button = GTK_FILE_CHOOSER_BUTTON (chooser);
+ GtkFileChooserButtonPrivate *priv = button->priv;
+
+ 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;
+
+ if (priv->selection_while_inactive)
+ g_object_unref (priv->selection_while_inactive);
+
+ priv->selection_while_inactive = g_object_ref (file);
+
+ priv->is_changing_selection = TRUE;
+
+ update_label_and_image (button);
+ update_combo_box (button);
+
+ if (priv->active)
+ gtk_file_chooser_select_file (GTK_FILE_CHOOSER (priv->dialog), file, NULL);
+
+ return TRUE;
+}
+
+static void
+unselect_current_file (GtkFileChooserButton *button)
+{
+ GtkFileChooserButtonPrivate *priv = button->priv;
+
+ if (priv->selection_while_inactive)
+ {
+ g_object_unref (priv->selection_while_inactive);
+ priv->selection_while_inactive = NULL;
+ }
+
+ priv->is_changing_selection = TRUE;
+
+ update_label_and_image (button);
+ update_combo_box (button);
+}
+
+static void
+gtk_file_chooser_button_unselect_file (GtkFileChooser *chooser,
+ GFile *file)
+{
+ GtkFileChooserButton *button = GTK_FILE_CHOOSER_BUTTON (chooser);
+ GtkFileChooserButtonPrivate *priv = button->priv;
+
+ if (g_file_equal (priv->selection_while_inactive, file))
+ unselect_current_file (button);
+
+ if (priv->active)
+ gtk_file_chooser_unselect_file (GTK_FILE_CHOOSER (priv->dialog), file);
+}
+
+static void
+gtk_file_chooser_button_unselect_all (GtkFileChooser *chooser)
+{
+ GtkFileChooserButton *button = GTK_FILE_CHOOSER_BUTTON (chooser);
+ GtkFileChooserButtonPrivate *priv = button->priv;
+
+ unselect_current_file (button);
+
+ if (priv->active)
+ gtk_file_chooser_unselect_all (GTK_FILE_CHOOSER (priv->dialog));
+}
+
+static GFile *
+get_selected_file (GtkFileChooserButton *button)
+{
+ GtkFileChooserButtonPrivate *priv = button->priv;
+ GFile *retval;
+
+ retval = NULL;
+
+ if (priv->selection_while_inactive)
+ retval = 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)
+ retval = priv->current_folder_while_inactive;
+ }
+
+ if (retval)
+ return g_object_ref (retval);
+ else
+ return NULL;
+}
+
+static GSList *
+gtk_file_chooser_button_get_files (GtkFileChooser *chooser)
+{
+ GtkFileChooserButton *button = GTK_FILE_CHOOSER_BUTTON (chooser);
+ GFile *file;
+
+ file = get_selected_file (button);
+ if (file)
+ return g_slist_prepend (NULL, file);
+ else
+ return NULL;
+}
+