Don't reload the current folder unnecessarily on ::map().

2005-09-27  Federico Mena Quintero  <federico@ximian.com>

	Don't reload the current folder unnecessarily on ::map().

	* gtk/gtkfilechooserprivate.h (ReloadState): New enum to represent
	the reloading state.
	(struct _GtkFileChooserDefault): Added a "reload_state" field.

	* gtk/gtkfilechooserdefault.c (gtk_file_chooser_default_init):
	Initialize impl->reload_state.
	(gtk_file_chooser_default_map): Check the impl->reload_state; load
	a default folder if no folder has been set, or reload the current
	one only if we had been unmapped first.
	(gtk_file_chooser_default_update_current_folder): Set the
	reload_state to RELOAD_HAS_FOLDER.
	(gtk_file_chooser_default_unmap): Implement, and set the
	reload_state to RELOAD_WAS_UNMAPPED.
	(shortcuts_model_create): Don't call shortcuts_add_bookmarks()
	here; they'll get (re)loaded on ::map() anyway.

	* gtk/gtkfilechooserwidget.c
	(gtk_file_chooser_widget_constructor): Don't set a default folder here.

	* tests/autotestfilechooser.c (test_action_widgets): Don't take in
	a dialog; build it ourselves.
	(test_reload): New test to ensure that we don't load the default
	folder more than once, and that we reload it when
	unmapping/remapping.
	(get_impl_from_dialog): New utility function.
	(test_widgets_for_current_action): Use get_impl_from_dialog().
This commit is contained in:
Federico Mena Quintero 2005-09-27 23:57:09 +00:00 committed by Federico Mena Quintero
parent 58a2a79682
commit 72851a22cd
5 changed files with 254 additions and 39 deletions

View File

@ -1,3 +1,34 @@
2005-09-27 Federico Mena Quintero <federico@ximian.com>
Don't reload the current folder unnecessarily on ::map().
* gtk/gtkfilechooserprivate.h (ReloadState): New enum to represent
the reloading state.
(struct _GtkFileChooserDefault): Added a "reload_state" field.
* gtk/gtkfilechooserdefault.c (gtk_file_chooser_default_init):
Initialize impl->reload_state.
(gtk_file_chooser_default_map): Check the impl->reload_state; load
a default folder if no folder has been set, or reload the current
one only if we had been unmapped first.
(gtk_file_chooser_default_update_current_folder): Set the
reload_state to RELOAD_HAS_FOLDER.
(gtk_file_chooser_default_unmap): Implement, and set the
reload_state to RELOAD_WAS_UNMAPPED.
(shortcuts_model_create): Don't call shortcuts_add_bookmarks()
here; they'll get (re)loaded on ::map() anyway.
* gtk/gtkfilechooserwidget.c
(gtk_file_chooser_widget_constructor): Don't set a default folder here.
* tests/autotestfilechooser.c (test_action_widgets): Don't take in
a dialog; build it ourselves.
(test_reload): New test to ensure that we don't load the default
folder more than once, and that we reload it when
unmapping/remapping.
(get_impl_from_dialog): New utility function.
(test_widgets_for_current_action): Use get_impl_from_dialog().
2005-09-27 Federico Mena Quintero <federico@ximian.com>
* gtk/gtkfilechooserdefault.c

View File

@ -1,3 +1,34 @@
2005-09-27 Federico Mena Quintero <federico@ximian.com>
Don't reload the current folder unnecessarily on ::map().
* gtk/gtkfilechooserprivate.h (ReloadState): New enum to represent
the reloading state.
(struct _GtkFileChooserDefault): Added a "reload_state" field.
* gtk/gtkfilechooserdefault.c (gtk_file_chooser_default_init):
Initialize impl->reload_state.
(gtk_file_chooser_default_map): Check the impl->reload_state; load
a default folder if no folder has been set, or reload the current
one only if we had been unmapped first.
(gtk_file_chooser_default_update_current_folder): Set the
reload_state to RELOAD_HAS_FOLDER.
(gtk_file_chooser_default_unmap): Implement, and set the
reload_state to RELOAD_WAS_UNMAPPED.
(shortcuts_model_create): Don't call shortcuts_add_bookmarks()
here; they'll get (re)loaded on ::map() anyway.
* gtk/gtkfilechooserwidget.c
(gtk_file_chooser_widget_constructor): Don't set a default folder here.
* tests/autotestfilechooser.c (test_action_widgets): Don't take in
a dialog; build it ourselves.
(test_reload): New test to ensure that we don't load the default
folder more than once, and that we reload it when
unmapping/remapping.
(get_impl_from_dialog): New utility function.
(test_widgets_for_current_action): Use get_impl_from_dialog().
2005-09-27 Federico Mena Quintero <federico@ximian.com>
* gtk/gtkfilechooserdefault.c

View File

@ -258,6 +258,7 @@ static void gtk_file_chooser_default_get_property (GObject *ob
static void gtk_file_chooser_default_dispose (GObject *object);
static void gtk_file_chooser_default_show_all (GtkWidget *widget);
static void gtk_file_chooser_default_map (GtkWidget *widget);
static void gtk_file_chooser_default_unmap (GtkWidget *widget);
static void gtk_file_chooser_default_hierarchy_changed (GtkWidget *widget,
GtkWidget *previous_toplevel);
static void gtk_file_chooser_default_style_set (GtkWidget *widget,
@ -500,6 +501,7 @@ gtk_file_chooser_default_class_init (GtkFileChooserDefaultClass *class)
widget_class->show_all = gtk_file_chooser_default_show_all;
widget_class->map = gtk_file_chooser_default_map;
widget_class->unmap = gtk_file_chooser_default_unmap;
widget_class->hierarchy_changed = gtk_file_chooser_default_hierarchy_changed;
widget_class->style_set = gtk_file_chooser_default_style_set;
widget_class->screen_changed = gtk_file_chooser_default_screen_changed;
@ -634,6 +636,7 @@ gtk_file_chooser_default_init (GtkFileChooserDefault *impl)
impl->show_hidden = FALSE;
impl->icon_size = FALLBACK_ICON_SIZE;
impl->load_state = LOAD_EMPTY;
impl->reload_state = RELOAD_EMPTY;
impl->pending_select_paths = NULL;
gtk_box_set_spacing (GTK_BOX (impl), 12);
@ -1749,7 +1752,6 @@ shortcuts_model_create (GtkFileChooserDefault *impl)
shortcuts_append_home (impl);
shortcuts_append_desktop (impl);
shortcuts_add_volumes (impl);
shortcuts_add_bookmarks (impl);
}
impl->shortcuts_filter_model = shortcuts_model_filter_new (impl,
@ -4656,6 +4658,7 @@ static void
gtk_file_chooser_default_map (GtkWidget *widget)
{
GtkFileChooserDefault *impl;
char *current_working_dir;
profile_start ("start", NULL);
@ -4663,10 +4666,29 @@ gtk_file_chooser_default_map (GtkWidget *widget)
GTK_WIDGET_CLASS (parent_class)->map (widget);
if (impl->current_folder)
switch (impl->reload_state)
{
case RELOAD_EMPTY:
/* The user didn't explicitly give us a folder to display, so we'll use the cwd */
current_working_dir = g_get_current_dir ();
gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (impl), current_working_dir);
g_free (current_working_dir);
break;
case RELOAD_HAS_FOLDER:
/* Nothing; we are already loading or loaded, so we don't need to reload */
break;
case RELOAD_WAS_UNMAPPED:
/* Just reload the current folder */
g_assert (impl->current_folder != NULL);
pending_select_paths_store_selection (impl);
change_folder_and_display_error (impl, impl->current_folder);
break;
default:
g_assert_not_reached ();
}
bookmarks_changed_cb (impl->file_system, impl);
@ -4674,6 +4696,19 @@ gtk_file_chooser_default_map (GtkWidget *widget)
profile_end ("end", NULL);
}
/* GtkWidget::unmap method */
static void
gtk_file_chooser_default_unmap (GtkWidget *widget)
{
GtkFileChooserDefault *impl;
impl = GTK_FILE_CHOOSER_DEFAULT (widget);
GTK_WIDGET_CLASS (parent_class)->unmap (widget);
impl->reload_state = RELOAD_WAS_UNMAPPED;
}
static gboolean
list_model_filter_func (GtkFileSystemModel *model,
GtkFilePath *path,
@ -5283,6 +5318,8 @@ gtk_file_chooser_default_update_current_folder (GtkFileChooser *chooser,
gtk_file_path_free (impl->current_folder);
impl->current_folder = gtk_file_path_copy (path);
impl->reload_state = RELOAD_HAS_FOLDER;
}
/* Update the widgets that may trigger a folder change themselves. */

View File

@ -139,7 +139,6 @@ gtk_file_chooser_widget_constructor (GType type,
{
GtkFileChooserWidgetPrivate *priv;
GObject *object;
gchar *current_folder;
object = parent_class->constructor (type,
n_construct_properties,
@ -153,10 +152,6 @@ gtk_file_chooser_widget_constructor (GType type,
gtk_box_pack_start (GTK_BOX (object), priv->impl, TRUE, TRUE, 0);
gtk_widget_show (priv->impl);
current_folder = g_get_current_dir ();
gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (priv->impl), current_folder);
g_free (current_folder);
_gtk_file_chooser_set_delegate (GTK_FILE_CHOOSER (object),
GTK_FILE_CHOOSER (priv->impl));

View File

@ -63,20 +63,17 @@ get_action_name (GtkFileChooserAction action)
return enum_value->value_name;
}
static gboolean
test_widgets_for_current_action (GtkFileChooserDialog *dialog,
GtkFileChooserAction expected_action)
static GtkFileChooserDefault *
get_impl_from_dialog (GtkWidget *dialog)
{
GtkFileChooserDialog *d;
GtkFileChooserDialogPrivate *dialog_priv;
GtkFileChooserWidget *chooser_widget;
GtkFileChooserWidgetPrivate *widget_priv;
GtkFileChooserDefault *impl;
gboolean passed;
if (gtk_file_chooser_get_action (GTK_FILE_CHOOSER (dialog)) != expected_action)
return FALSE;
dialog_priv = dialog->priv;
d = GTK_FILE_CHOOSER_DIALOG (dialog);
dialog_priv = d->priv;
chooser_widget = GTK_FILE_CHOOSER_WIDGET (dialog_priv->widget);
if (!chooser_widget)
g_error ("BUG: dialog_priv->widget is not a GtkFileChooserWidget");
@ -86,6 +83,21 @@ test_widgets_for_current_action (GtkFileChooserDialog *dialog,
if (!impl)
g_error ("BUG: widget_priv->impl is not a GtkFileChooserDefault");
return impl;
}
static gboolean
test_widgets_for_current_action (GtkFileChooserDialog *dialog,
GtkFileChooserAction expected_action)
{
GtkFileChooserDefault *impl;
gboolean passed;
if (gtk_file_chooser_get_action (GTK_FILE_CHOOSER (dialog)) != expected_action)
return FALSE;
impl = get_impl_from_dialog (GTK_WIDGET (dialog));
g_assert (impl->action == expected_action);
passed = TRUE;
@ -208,31 +220,11 @@ switch_from_action_cb (GtkFileChooserDialog *dialog,
}
static gboolean
test_action_widgets (GtkFileChooserDialog *dialog)
{
GtkFileChooserAction action;
gboolean passed;
action = gtk_file_chooser_get_action (GTK_FILE_CHOOSER (dialog));
passed = test_widgets_for_current_action (dialog, action);
log_test (passed, "test_action_widgets(): widgets for initial action %s", get_action_name (action));
if (!passed)
return FALSE;
passed = foreach_action (dialog, switch_from_action_cb, NULL);
log_test (passed, "test_action_widgets(): all transitions through property change");
return passed;
}
int
main (int argc, char **argv)
test_action_widgets (void)
{
GtkWidget *dialog;
gtk_init (&argc, &argv);
GtkFileChooserAction action;
gboolean passed;
dialog = gtk_file_chooser_dialog_new ("Test file chooser",
NULL,
@ -244,9 +236,138 @@ main (int argc, char **argv)
NULL);
gtk_widget_show (dialog);
test_action_widgets (GTK_FILE_CHOOSER_DIALOG (dialog));
action = gtk_file_chooser_get_action (GTK_FILE_CHOOSER (dialog));
passed = test_widgets_for_current_action (GTK_FILE_CHOOSER_DIALOG (dialog), action);
log_test (passed, "test_action_widgets(): widgets for initial action %s", get_action_name (action));
if (!passed)
return FALSE;
passed = foreach_action (GTK_FILE_CHOOSER_DIALOG (dialog), switch_from_action_cb, NULL);
log_test (passed, "test_action_widgets(): all transitions through property change");
gtk_widget_destroy (dialog);
return passed;
}
static gboolean
test_reload_sequence (gboolean set_folder_before_map)
{
GtkWidget *dialog;
GtkFileChooserDefault *impl;
gboolean passed;
passed = TRUE;
dialog = gtk_file_chooser_dialog_new ("Test file chooser",
NULL,
GTK_FILE_CHOOSER_ACTION_OPEN,
GTK_STOCK_CANCEL,
GTK_RESPONSE_CANCEL,
GTK_STOCK_OK,
GTK_RESPONSE_ACCEPT,
NULL);
impl = get_impl_from_dialog (dialog);
if (set_folder_before_map)
{
gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), g_get_home_dir ());
passed = (impl->current_folder != NULL
&& impl->browse_files_model != NULL
&& (impl->load_state == LOAD_PRELOAD || impl->load_state == LOAD_LOADING || impl->load_state == LOAD_FINISHED)
&& impl->reload_state == RELOAD_HAS_FOLDER
&& (impl->load_state == LOAD_PRELOAD ? (impl->load_timeout_id != 0) : TRUE)
&& ((impl->load_state == LOAD_LOADING || impl->load_state == LOAD_FINISHED)
? (impl->load_timeout_id == 0 && impl->sort_model != NULL)
: TRUE));
}
else
{
/* Initially, no folder is not loaded or pending */
passed = passed && (impl->current_folder == NULL
&& impl->sort_model == NULL
&& impl->browse_files_model == NULL
&& impl->load_state == LOAD_EMPTY
&& impl->reload_state == RELOAD_EMPTY
&& impl->load_timeout_id == 0);
}
if (!passed)
return FALSE;
/* After mapping, it is loading some folder, either the one that was explicitly set or the default one */
gtk_widget_show (dialog);
passed = (impl->current_folder != NULL
&& impl->browse_files_model != NULL
&& (impl->load_state == LOAD_PRELOAD || impl->load_state == LOAD_LOADING || impl->load_state == LOAD_FINISHED)
&& impl->reload_state == RELOAD_HAS_FOLDER
&& (impl->load_state == LOAD_PRELOAD ? (impl->load_timeout_id != 0) : TRUE)
&& ((impl->load_state == LOAD_LOADING || impl->load_state == LOAD_FINISHED)
? (impl->load_timeout_id == 0 && impl->sort_model != NULL)
: TRUE));
if (!passed)
return FALSE;
/* Unmap it; we should still have a folder */
gtk_widget_hide (dialog);
passed = (impl->current_folder != NULL
&& impl->browse_files_model != NULL
&& (impl->load_state == LOAD_PRELOAD || impl->load_state == LOAD_LOADING || impl->load_state == LOAD_FINISHED)
&& impl->reload_state == RELOAD_WAS_UNMAPPED
&& (impl->load_state == LOAD_PRELOAD ? (impl->load_timeout_id != 0) : TRUE)
&& ((impl->load_state == LOAD_LOADING || impl->load_state == LOAD_FINISHED)
? (impl->load_timeout_id == 0 && impl->sort_model != NULL)
: TRUE));
/* Map it again! */
gtk_widget_show (dialog);
passed = (impl->current_folder != NULL
&& impl->browse_files_model != NULL
&& (impl->load_state == LOAD_PRELOAD || impl->load_state == LOAD_LOADING || impl->load_state == LOAD_FINISHED)
&& impl->reload_state == RELOAD_HAS_FOLDER
&& (impl->load_state == LOAD_PRELOAD ? (impl->load_timeout_id != 0) : TRUE)
&& ((impl->load_state == LOAD_LOADING || impl->load_state == LOAD_FINISHED)
? (impl->load_timeout_id == 0 && impl->sort_model != NULL)
: TRUE));
if (!passed)
return FALSE;
gtk_widget_destroy (dialog);
return passed;
}
static gboolean
test_reload (void)
{
gboolean passed;
passed = test_reload_sequence (FALSE);
log_test (passed, "test_reload(): create and use the default folder");
if (!passed)
return FALSE;
passed = test_reload_sequence (TRUE);
log_test (passed, "test_reload(): set a folder explicitly before mapping");
return passed;
}
int
main (int argc, char **argv)
{
gtk_init (&argc, &argv);
test_action_widgets ();
test_reload ();
return 0;
}