]> Pileus Git - ~andy/gtk/commitdiff
filechooserbutton: Fix preserving the selection after cancelling the dialog
authorFederico Mena Quintero <federico@gnome.org>
Tue, 12 Feb 2013 05:03:26 +0000 (23:03 -0600)
committerFederico Mena Quintero <federico@gnome.org>
Thu, 14 Feb 2013 00:01:39 +0000 (18:01 -0600)
The button's underlying file chooser dialog should not be used to store the file selection
while the dialog is unmapped.  Instead, the file chooser button now stores the
selection itself.

Signed-off-by: Federico Mena Quintero <federico@gnome.org>
gtk/gtkfilechooserbutton.c

index a0933c86786f0c9a30002d0634f0c374209a5917..ba2a445e6a91f7782f0d8f8b0029e6c7f6f9552c 100644 (file)
@@ -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,7 @@ struct _GtkFileChooserButtonPrivate
   GtkTreeModel *filter_model;
 
   GtkFileSystem *fs;
-  GFile *old_file;
+  GFile *selection_while_inactive;
 
   gulong combo_box_changed_id;
   gulong dialog_file_activated_id;
@@ -226,6 +226,13 @@ enum
 
 /* GtkFileChooserIface Functions */
 static void     gtk_file_chooser_button_file_chooser_iface_init (GtkFileChooserIface *iface);
+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 +568,118 @@ gtk_file_chooser_button_file_chooser_iface_init (GtkFileChooserIface *iface)
 {
   _gtk_file_chooser_delegate_iface_init (iface);
 
+  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_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);
+
+      g_signal_emit (button, file_chooser_button_signals[FILE_SET], 0);
+
+      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;
+           }
+
+         g_signal_emit (button, file_chooser_button_signals[FILE_SET], 0);
+       }
+    }
+}
+
+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;
+       }
+
+      g_signal_emit (button, file_chooser_button_signals[FILE_SET], 0);
+    }
+}
+
+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;
+
+      if (priv->selection_while_inactive)
+       result = g_slist_prepend (NULL, g_object_ref (priv->selection_while_inactive));
+      else
+       result = NULL;
+
+      return result;
+    }
+}
+
 static gboolean
 gtk_file_chooser_button_add_shortcut_folder (GtkFileChooser  *chooser,
                                             GFile           *file,
@@ -903,8 +1018,8 @@ 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);
 
   G_OBJECT_CLASS (gtk_file_chooser_button_parent_class)->finalize (object);
 }
@@ -2474,8 +2589,7 @@ 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));
+      gtk_file_chooser_select_file (GTK_FILE_CHOOSER (priv->dialog), priv->selection_while_inactive, NULL);
 
       priv->active = TRUE;
     }
@@ -2647,25 +2761,24 @@ dialog_response_cb (GtkDialog *dialog,
   if (response == GTK_RESPONSE_ACCEPT ||
       response == GTK_RESPONSE_OK)
     {
+      if (priv->selection_while_inactive)
+       g_object_unref (priv->selection_while_inactive);
+
+      priv->selection_while_inactive = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (priv->dialog));
+
       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)
+  else if (priv->selection_while_inactive)
     {
-      gtk_file_chooser_select_file (GTK_FILE_CHOOSER (dialog), priv->old_file, NULL);
+      gtk_file_chooser_select_file (GTK_FILE_CHOOSER (dialog), priv->selection_while_inactive, 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;
-    }
-
   if (priv->active)
     {
       g_signal_handler_unblock (priv->dialog,