]> Pileus Git - ~andy/gtk/commitdiff
Fixes bug #317999:
authorFederico Mena Quintero <federico@ximian.com>
Fri, 7 Oct 2005 19:54:32 +0000 (19:54 +0000)
committerFederico Mena Quintero <federico@src.gnome.org>
Fri, 7 Oct 2005 19:54:32 +0000 (19:54 +0000)
2005-10-07  Federico Mena Quintero  <federico@ximian.com>

Fixes bug #317999:

* tests/autotestfilechooser.c (test_reload_sequence): Ensure that
the the result of gtk_file_chooser_get_folder() is NULL or
non-NULL at the right times.  Log the tests.
(test_button_folder_states): New test for the initial states of
the current folder in GtkFileChooserButton.
(main): Test that the number of warnings/errors/critical errors is
zero.

* gtk/gtkfilechooser.c (gtk_file_chooser_get_current_folder):
Clarify the documentation on when this can return NULL.
(gtk_file_chooser_get_current_folder_uri): Likewise.

* gtk/gtkfilechooserbutton.c (struct
_GtkFileChooserButtonPrivate): Added a folder_has_been_set flag;
we use it to keep track of whether a folder has been set.
(gtk_file_chooser_button_map):  Implement.  If no folder has been
loaded before, we at least try to load $cwd here.
(gtk_file_chooser_button_constructor): If the construct-time
dialog already has a folder set, turn on our folder_has_been_set
flag.
(dialog_current_folder_changed_cb): Turn on our
folder_has_been_set flag.

ChangeLog
ChangeLog.pre-2-10
gtk/gtkfilechooser.c
gtk/gtkfilechooserbutton.c
tests/autotestfilechooser.c

index 2e2a2b08d535a35ed2bb3cbe716cc6876426852d..2246644158994ae81b775a7a4e2a49bb8d362a82 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,30 @@
+2005-10-07  Federico Mena Quintero  <federico@ximian.com>
+
+       Fixes bug #317999:
+
+       * tests/autotestfilechooser.c (test_reload_sequence): Ensure that
+       the the result of gtk_file_chooser_get_folder() is NULL or
+       non-NULL at the right times.  Log the tests.
+       (test_button_folder_states): New test for the initial states of
+       the current folder in GtkFileChooserButton.
+       (main): Test that the number of warnings/errors/critical errors is
+       zero.
+
+       * gtk/gtkfilechooser.c (gtk_file_chooser_get_current_folder):
+       Clarify the documentation on when this can return NULL.
+       (gtk_file_chooser_get_current_folder_uri): Likewise.
+
+       * gtk/gtkfilechooserbutton.c (struct
+       _GtkFileChooserButtonPrivate): Added a folder_has_been_set flag;
+       we use it to keep track of whether a folder has been set.
+       (gtk_file_chooser_button_map):  Implement.  If no folder has been
+       loaded before, we at least try to load $cwd here.
+       (gtk_file_chooser_button_constructor): If the construct-time
+       dialog already has a folder set, turn on our folder_has_been_set
+       flag.
+       (dialog_current_folder_changed_cb): Turn on our
+       folder_has_been_set flag.
+
 2005-10-07  Michael Natterer  <mitch@gimp.org>
 
        * gtk/gtkfilechooserdefault.c: remove some explicit #defines of
index 2e2a2b08d535a35ed2bb3cbe716cc6876426852d..2246644158994ae81b775a7a4e2a49bb8d362a82 100644 (file)
@@ -1,3 +1,30 @@
+2005-10-07  Federico Mena Quintero  <federico@ximian.com>
+
+       Fixes bug #317999:
+
+       * tests/autotestfilechooser.c (test_reload_sequence): Ensure that
+       the the result of gtk_file_chooser_get_folder() is NULL or
+       non-NULL at the right times.  Log the tests.
+       (test_button_folder_states): New test for the initial states of
+       the current folder in GtkFileChooserButton.
+       (main): Test that the number of warnings/errors/critical errors is
+       zero.
+
+       * gtk/gtkfilechooser.c (gtk_file_chooser_get_current_folder):
+       Clarify the documentation on when this can return NULL.
+       (gtk_file_chooser_get_current_folder_uri): Likewise.
+
+       * gtk/gtkfilechooserbutton.c (struct
+       _GtkFileChooserButtonPrivate): Added a folder_has_been_set flag;
+       we use it to keep track of whether a folder has been set.
+       (gtk_file_chooser_button_map):  Implement.  If no folder has been
+       loaded before, we at least try to load $cwd here.
+       (gtk_file_chooser_button_constructor): If the construct-time
+       dialog already has a folder set, turn on our folder_has_been_set
+       flag.
+       (dialog_current_folder_changed_cb): Turn on our
+       folder_has_been_set flag.
+
 2005-10-07  Michael Natterer  <mitch@gimp.org>
 
        * gtk/gtkfilechooserdefault.c: remove some explicit #defines of
index 005d56032e8b1058bd2c2a55a30ea2bb738d2423..a55ef8b90b25f46ca02bcc67a96237eb361dde6f 100644 (file)
@@ -700,9 +700,11 @@ gtk_file_chooser_set_current_folder (GtkFileChooser *chooser,
  * Gets the current folder of @chooser as a local filename.
  * See gtk_file_chooser_set_current_folder().
  * 
- * Return value: the full path of the current folder, or %NULL
- *  if the current path cannot be represented as a local filename.
- *  Free with g_free().
+ * Return value: the full path of the current folder, or %NULL if the current
+ * path cannot be represented as a local filename.  Free with g_free().  This
+ * function will also return %NULL if the file chooser was unable to load the
+ * last folder that was requested from it; for example, as would be for calling
+ * gtk_file_chooser_set_current_folder() on a nonexistent folder.
  *
  * Since: 2.4
  **/
@@ -1019,8 +1021,10 @@ gtk_file_chooser_set_current_folder_uri (GtkFileChooser *chooser,
  * Gets the current folder of @chooser as an URI.
  * See gtk_file_chooser_set_current_folder_uri().
  * 
- * Return value: the URI for the current folder.
- *  Free with g_free().
+ * Return value: the URI for the current folder.  Free with g_free().  This
+ * function will also return %NULL if the file chooser was unable to load the
+ * last folder that was requested from it; for example, as would be for calling
+ * gtk_file_chooser_set_current_folder_uri() on a nonexistent folder.
  *
  * Since: 2.4
  */
index e9117f932820049188c7c14da8e5ce4077e9c8aa..94458b9a62b1f6427636559dce3cc6ce62aff3ef 100644 (file)
@@ -155,6 +155,9 @@ struct _GtkFileChooserButtonPrivate
 
   /* Used for hiding/showing the dialog when the button is hidden */
   guint8 active                       : 1;
+
+  /* Used to track whether we need to set a default current folder on ::map() */
+  guint8 folder_has_been_set          : 1;
 };
 
 
@@ -211,6 +214,7 @@ static void     gtk_file_chooser_button_show_all           (GtkWidget        *wi
 static void     gtk_file_chooser_button_hide_all           (GtkWidget        *widget);
 static void     gtk_file_chooser_button_show               (GtkWidget        *widget);
 static void     gtk_file_chooser_button_hide               (GtkWidget        *widget);
+static void     gtk_file_chooser_button_map                (GtkWidget        *widget);
 static gboolean gtk_file_chooser_button_mnemonic_activate  (GtkWidget        *widget,
                                                            gboolean          group_cycling);
 static void     gtk_file_chooser_button_style_set          (GtkWidget        *widget,
@@ -322,6 +326,7 @@ gtk_file_chooser_button_class_init (GtkFileChooserButtonClass * class)
   widget_class->hide_all = gtk_file_chooser_button_hide_all;
   widget_class->show = gtk_file_chooser_button_show;
   widget_class->hide = gtk_file_chooser_button_hide;
+  widget_class->map = gtk_file_chooser_button_map;
   widget_class->style_set = gtk_file_chooser_button_style_set;
   widget_class->screen_changed = gtk_file_chooser_button_screen_changed;
   widget_class->mnemonic_activate = gtk_file_chooser_button_mnemonic_activate;
@@ -593,6 +598,7 @@ gtk_file_chooser_button_constructor (GType                  type,
   GObject *object;
   GtkFileChooserButtonPrivate *priv;
   GSList *list;
+  char *current_folder;
 
   object = (*G_OBJECT_CLASS (gtk_file_chooser_button_parent_class)->constructor) (type,
                                                                                  n_params,
@@ -627,6 +633,13 @@ gtk_file_chooser_button_constructor (GType                  type,
                                               -1);
     }
 
+  current_folder = gtk_file_chooser_get_current_folder_uri (GTK_FILE_CHOOSER (priv->dialog));
+  if (current_folder != NULL)
+    {
+      priv->folder_has_been_set = TRUE;
+      g_free (current_folder);
+    }
+
   g_free (priv->backend);
   priv->backend = NULL;
 
@@ -1013,6 +1026,28 @@ gtk_file_chooser_button_hide (GtkWidget *widget)
     (*GTK_WIDGET_CLASS (gtk_file_chooser_button_parent_class)->hide) (widget);
 }
 
+static void
+gtk_file_chooser_button_map (GtkWidget *widget)
+{
+  GtkFileChooserButtonPrivate *priv;
+
+  priv = GTK_FILE_CHOOSER_BUTTON_GET_PRIVATE (widget);
+
+  if (!priv->folder_has_been_set)
+    {
+      char *current_working_dir;
+
+      current_working_dir = g_get_current_dir ();
+      gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (widget), current_working_dir);
+      g_free (current_working_dir);
+
+      priv->folder_has_been_set = TRUE;
+    }
+
+  if (GTK_WIDGET_CLASS (gtk_file_chooser_button_parent_class)->map)
+    (*GTK_WIDGET_CLASS (gtk_file_chooser_button_parent_class)->map) (widget);
+}
+
 static gboolean
 gtk_file_chooser_button_mnemonic_activate (GtkWidget *widget,
                                           gboolean   group_cycling)
@@ -2060,7 +2095,15 @@ static void
 dialog_current_folder_changed_cb (GtkFileChooser *dialog,
                                  gpointer        user_data)
 {
-  g_signal_emit_by_name (user_data, "current-folder-changed");
+  GtkFileChooserButton *button;
+  GtkFileChooserButtonPrivate *priv;
+
+  button = GTK_FILE_CHOOSER_BUTTON (user_data);
+  priv = GTK_FILE_CHOOSER_BUTTON_GET_PRIVATE (button);
+
+  priv->folder_has_been_set = TRUE;
+
+  g_signal_emit_by_name (button, "current-folder-changed");
 }
 
 static void
index 7597bf52a5f8c45e39e83369815407bf6f933eca..0dadc1a18f12f0065abaefa4c81145107cefae3a 100644 (file)
@@ -24,6 +24,7 @@
 #define GTK_FILE_SYSTEM_ENABLE_UNSUPPORTED
 
 #include <config.h>
+#include <string.h>
 #include <glib/gprintf.h>
 #include <gtk/gtk.h>
 #include "gtk/gtkfilechooserprivate.h"
@@ -280,6 +281,7 @@ test_reload_sequence (gboolean set_folder_before_map)
   GtkWidget *dialog;
   GtkFileChooserDefault *impl;
   gboolean passed;
+  char *folder;
 
   passed = TRUE;
 
@@ -305,6 +307,10 @@ test_reload_sequence (gboolean set_folder_before_map)
                && ((impl->load_state == LOAD_LOADING || impl->load_state == LOAD_FINISHED)
                    ? (impl->load_timeout_id == 0 && impl->sort_model != NULL)
                    : TRUE));
+
+      folder = gtk_file_chooser_get_current_folder (GTK_FILE_CHOOSER (dialog));
+      passed = passed && (folder != NULL && strcmp (folder, g_get_home_dir()) == 0);
+      g_free (folder);
     }
   else
     {
@@ -315,8 +321,12 @@ test_reload_sequence (gboolean set_folder_before_map)
                          && impl->load_state == LOAD_EMPTY
                          && impl->reload_state == RELOAD_EMPTY
                          && impl->load_timeout_id == 0);
+
+      folder = gtk_file_chooser_get_current_folder (GTK_FILE_CHOOSER (dialog));
+      passed = passed && (folder == NULL);
     }
 
+  log_test (passed, "test_reload_sequence(): initial status");
   if (!passed)
     return FALSE;
 
@@ -332,6 +342,12 @@ test_reload_sequence (gboolean set_folder_before_map)
            && ((impl->load_state == LOAD_LOADING || impl->load_state == LOAD_FINISHED)
                ? (impl->load_timeout_id == 0 && impl->sort_model != NULL)
                : TRUE));
+
+  folder = gtk_file_chooser_get_current_folder (GTK_FILE_CHOOSER (dialog));
+  passed = passed && (folder != NULL);
+  g_free (folder);
+
+  log_test (passed, "test_reload_sequence(): status after map");
   if (!passed)
     return FALSE;
 
@@ -350,6 +366,14 @@ test_reload_sequence (gboolean set_folder_before_map)
   if (!passed)
     return FALSE;
 
+  folder = gtk_file_chooser_get_current_folder (GTK_FILE_CHOOSER (dialog));
+  passed = passed && (folder != NULL);
+  g_free (folder);
+
+  log_test (passed, "test_reload_sequence(): status after unmap");
+  if (!passed)
+    return FALSE;
+
   /* Map it again! */
 
   gtk_widget_show_now (dialog);
@@ -365,8 +389,13 @@ test_reload_sequence (gboolean set_folder_before_map)
   if (!passed)
     return FALSE;
 
-  gtk_widget_destroy (dialog);
+  folder = gtk_file_chooser_get_current_folder (GTK_FILE_CHOOSER (dialog));
+  passed = passed && (folder != NULL);
+  g_free (folder);
+
+  log_test (passed, "test_reload_sequence(): status after re-map");
 
+  gtk_widget_destroy (dialog);
   return passed;
 }
 
@@ -386,13 +415,177 @@ test_reload (void)
   return passed;
 }
 
+static gboolean
+test_button_folder_states_for_action (GtkFileChooserAction action, gboolean use_dialog, gboolean set_folder_on_dialog)
+{
+  gboolean passed;
+  GtkWidget *window;
+  GtkWidget *button;
+  char *folder;
+  gboolean must_have_folder_initially;
+  GtkWidget *dialog;
+
+  passed = TRUE;
+
+  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+
+  must_have_folder_initially = (use_dialog && set_folder_on_dialog);
+
+  if (use_dialog)
+    {
+      dialog = gtk_file_chooser_dialog_new ("Test", NULL, action,
+                                           GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+                                           GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
+                                           NULL);
+      button = gtk_file_chooser_button_new_with_dialog (dialog);
+
+      if (set_folder_on_dialog)
+       gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), g_get_home_dir ());
+    }
+  else
+    {
+      button = gtk_file_chooser_button_new ("Test", action);
+      dialog = NULL; /* keep gcc happy */
+    }
+
+  gtk_container_add (GTK_CONTAINER (window), button);
+
+  /* Pre-map; no folder is set */
+
+  folder = gtk_file_chooser_get_current_folder (GTK_FILE_CHOOSER (button));
+  if (must_have_folder_initially)
+    passed = passed && (folder != NULL);
+  else
+    passed = passed && (folder == NULL);
+
+  log_test (passed, "test_button_folder_states_for_action(): %s, use_dialog=%d, set_folder_on_dialog=%d, pre-map, %s",
+           get_action_name (action),
+           use_dialog,
+           set_folder_on_dialog,
+           must_have_folder_initially ? "must have folder" : "folder must not be set");
+
+  /* Map; folder should be set */
+
+  gtk_widget_show_all (window);
+  gtk_widget_show_now (window);
+  folder = gtk_file_chooser_get_current_folder (GTK_FILE_CHOOSER (button));
+  passed = passed && (folder != NULL);
+  log_test (passed, "test_button_folder_states_for_action(): %s, use_dialog=%d, set_folder_on_dialog=%d, mapped, must have folder",
+           get_action_name (action),
+           use_dialog,
+           set_folder_on_dialog);
+  g_free (folder);
+
+  /* Unmap; folder should be set */
+
+  gtk_widget_hide (window);
+  folder = gtk_file_chooser_get_current_folder (GTK_FILE_CHOOSER (button));
+  passed = passed && (folder != NULL);
+  log_test (passed, "test_button_folder_states_for_action(): %s, use_dialog=%d, set_folder_on_dialog=%d, unmapped, must have folder",
+           get_action_name (action),
+           use_dialog,
+           set_folder_on_dialog);
+  g_free (folder);
+
+  /* Re-map; folder should be set */
+
+  gtk_widget_show_now (window);
+  folder = gtk_file_chooser_get_current_folder (GTK_FILE_CHOOSER (button));
+  passed = passed && (folder != NULL);
+  log_test (passed, "test_button_folder_states_for_action(): %s, use_dialog=%d, set_folder_on_dialog=%d, re-mapped, must have folder",
+           get_action_name (action),
+           use_dialog,
+           set_folder_on_dialog);
+  g_free (folder);
+
+  gtk_widget_destroy (window);
+
+  return passed;
+}
+
+static gboolean
+test_button_folder_states (void)
+{
+  /* GtkFileChooserButton only supports OPEN and SELECT_FOLDER */
+  static const GtkFileChooserAction actions_to_test[] = {
+    GTK_FILE_CHOOSER_ACTION_OPEN,
+    GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER
+  };
+  gboolean passed;
+  int i;
+
+  passed = TRUE;
+
+  for (i = 0; i < G_N_ELEMENTS (actions_to_test); i++)
+    {
+      passed = passed && test_button_folder_states_for_action (actions_to_test[i], FALSE, FALSE);
+      passed = passed && test_button_folder_states_for_action (actions_to_test[i], TRUE, FALSE);
+      passed = passed && test_button_folder_states_for_action (actions_to_test[i], TRUE, TRUE);
+      log_test (passed, "test_button_folder_states(): action %s", get_action_name (actions_to_test[i]));
+    }
+
+  log_test (passed, "test_button_folder_states(): all supported actions");
+  return passed;
+}
+
+static int num_warnings;
+static int num_errors;
+static int num_critical_errors;
+
+static void
+log_override_cb (const gchar   *log_domain,
+                GLogLevelFlags log_level,
+                const gchar   *message,
+                gpointer       user_data)
+{
+  if (log_level & G_LOG_LEVEL_WARNING)
+    num_warnings++;
+
+  if (log_level & G_LOG_LEVEL_ERROR)
+    num_errors++;
+
+  if (log_level & G_LOG_LEVEL_CRITICAL)
+    num_critical_errors++;
+
+  g_log_default_handler (log_domain, log_level, message, user_data);
+}
+
 int
 main (int argc, char **argv)
 {
+  static const char *domains[] = {
+    "Glib", "GLib-GObject", "GModule", "GThread", "Pango", "Gdk", "GdkPixbuf", "Gtk", "libgnomevfs"
+  };
+
+  gboolean passed;
+  gboolean zero_warnings;
+  gboolean zero_errors;
+  gboolean zero_critical_errors;
+  int i;
+
+  for (i = 0; i < G_N_ELEMENTS (domains); i++)
+    g_log_set_handler (domains[i],
+                      G_LOG_FLAG_RECURSION | G_LOG_FLAG_FATAL | G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_WARNING,
+                      log_override_cb, NULL);
+
   gtk_init (&argc, &argv);
 
-  test_action_widgets ();
-  test_reload ();
+  passed = test_action_widgets ();
+  passed = passed && test_reload ();
+  passed = passed && test_button_folder_states ();
+  log_test (passed, "main(): main tests");
+
+  zero_warnings = num_warnings == 0;
+  zero_errors = num_errors == 0;
+  zero_critical_errors = num_critical_errors == 0;
+
+  log_test (zero_warnings, "main(): zero warnings (actual number %d)", num_warnings);
+  log_test (zero_errors, "main(): zero errors (actual number %d)", num_errors);
+  log_test (zero_critical_errors, "main(): zero critical errors (actual number %d)", num_critical_errors);
+
+  passed = passed && zero_warnings && zero_errors && zero_critical_errors;
+
+  log_test (passed, "main(): ALL TESTS");
 
   return 0;
 }