diff options
author | Federico Mena Quintero <federico@ximian.com> | 2005-10-07 19:54:32 +0000 |
---|---|---|
committer | Federico Mena Quintero <federico@src.gnome.org> | 2005-10-07 19:54:32 +0000 |
commit | cca93029274bc39591f1d844ada3564c73c232da (patch) | |
tree | 58cedd63ca142670c4518994457b081394d91088 | |
parent | cab26ded6f1bc150f83178c68f058608534901d9 (diff) | |
download | gtk+-cca93029274bc39591f1d844ada3564c73c232da.tar.gz |
Fixes bug #317999:
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.
-rw-r--r-- | ChangeLog | 27 | ||||
-rw-r--r-- | ChangeLog.pre-2-10 | 27 | ||||
-rw-r--r-- | gtk/gtkfilechooser.c | 14 | ||||
-rw-r--r-- | gtk/gtkfilechooserbutton.c | 45 | ||||
-rw-r--r-- | tests/autotestfilechooser.c | 199 |
5 files changed, 303 insertions, 9 deletions
@@ -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 diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10 index 2e2a2b08d5..2246644158 100644 --- a/ChangeLog.pre-2-10 +++ b/ChangeLog.pre-2-10 @@ -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 diff --git a/gtk/gtkfilechooser.c b/gtk/gtkfilechooser.c index 005d56032e..a55ef8b90b 100644 --- a/gtk/gtkfilechooser.c +++ b/gtk/gtkfilechooser.c @@ -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 */ diff --git a/gtk/gtkfilechooserbutton.c b/gtk/gtkfilechooserbutton.c index e9117f9328..94458b9a62 100644 --- a/gtk/gtkfilechooserbutton.c +++ b/gtk/gtkfilechooserbutton.c @@ -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 diff --git a/tests/autotestfilechooser.c b/tests/autotestfilechooser.c index 7597bf52a5..0dadc1a18f 100644 --- a/tests/autotestfilechooser.c +++ b/tests/autotestfilechooser.c @@ -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; } |