-/* -*- 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
*
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;
/* 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);
{
_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,
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);
}
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;
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,
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)
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);
}
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;
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:
{
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);
}
}
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);
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 */
{
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)
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)
{
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)
{
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)
g_signal_handler_block (priv->dialog,
priv->dialog_selection_changed_id);
- g_assert (priv->old_file == NULL);
- priv->old_file = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (priv->dialog));
+ restore_inactive_state (button);
priv->active = TRUE;
}
/* 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--;
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)
- {
- gtk_file_chooser_select_file (GTK_FILE_CHOOSER (dialog), priv->old_file, NULL);
- }
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)