diff --git a/ChangeLog b/ChangeLog index 0a54245216..e30404f080 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,26 @@ +2005-09-15 Federico Mena Quintero + + * tests/autotestfilechooser.c: Start a set of automated tests for + the file chooser. The only test in there right now doesn't pass + yet. It specifies the intended behavior of the first optimization + of a series which I'll do on the file chooser (see + http://primates.ximian.com/~federico/news-2005-09.html#14 for the + details of this optimization). + + * tests/Makefile.am: Added autotestfilechooser.c. + + * gtk/gtkfilechooserprivate.h (struct + _GtkFileChooserDialogPrivate): Move all the file chooser's private + structures to here, so that they can be accessed by + tests/autotestfilechooser.c: _GtkFileChooserDialogPrivate, + _GtkFileChooserWidgetPrivate, LoadState, _GtkFileChooserDefault. + + * gtk/gtkfilechooserdialog.c: See above. + + * gtk/gtkfilechooserwidget.c: See above. + + * gtk/gtkfilechooserdefault.c: See above. + Thu Sep 15 15:27:55 2005 Tim Janik * gtk/gtkwindow.c: diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10 index 0a54245216..e30404f080 100644 --- a/ChangeLog.pre-2-10 +++ b/ChangeLog.pre-2-10 @@ -1,3 +1,26 @@ +2005-09-15 Federico Mena Quintero + + * tests/autotestfilechooser.c: Start a set of automated tests for + the file chooser. The only test in there right now doesn't pass + yet. It specifies the intended behavior of the first optimization + of a series which I'll do on the file chooser (see + http://primates.ximian.com/~federico/news-2005-09.html#14 for the + details of this optimization). + + * tests/Makefile.am: Added autotestfilechooser.c. + + * gtk/gtkfilechooserprivate.h (struct + _GtkFileChooserDialogPrivate): Move all the file chooser's private + structures to here, so that they can be accessed by + tests/autotestfilechooser.c: _GtkFileChooserDialogPrivate, + _GtkFileChooserWidgetPrivate, LoadState, _GtkFileChooserDefault. + + * gtk/gtkfilechooserdialog.c: See above. + + * gtk/gtkfilechooserwidget.c: See above. + + * gtk/gtkfilechooserdefault.c: See above. + Thu Sep 15 15:27:55 2005 Tim Janik * gtk/gtkwindow.c: diff --git a/gtk/gtkfilechooserdefault.c b/gtk/gtkfilechooserdefault.c index 3a79c8b1d3..99974b014f 100644 --- a/gtk/gtkfilechooserdefault.c +++ b/gtk/gtkfilechooserdefault.c @@ -32,6 +32,7 @@ #include "gtkentry.h" #include "gtkeventbox.h" #include "gtkexpander.h" +#include "gtkfilechooserprivate.h" #include "gtkfilechooserdefault.h" #include "gtkfilechooserembed.h" #include "gtkfilechooserentry.h" @@ -59,11 +60,7 @@ #include "gtktable.h" #include "gtktreednd.h" #include "gtktreeprivate.h" -#include "gtktreeview.h" -#include "gtktreemodelsort.h" #include "gtktreeselection.h" -#include "gtktreestore.h" -#include "gtktooltips.h" #include "gtktypebuiltins.h" #include "gtkvbox.h" @@ -145,13 +142,6 @@ typedef struct _GtkFileChooserDefaultClass GtkFileChooserDefaultClass; #define GTK_IS_FILE_CHOOSER_DEFAULT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_FILE_CHOOSER_DEFAULT)) #define GTK_FILE_CHOOSER_DEFAULT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_FILE_CHOOSER_DEFAULT, GtkFileChooserDefaultClass)) -typedef enum { - LOAD_EMPTY, /* There is no model */ - LOAD_PRELOAD, /* Model is loading and a timer is running; model isn't inserted into the tree yet */ - LOAD_LOADING, /* Timeout expired, model is inserted into the tree, but not fully loaded yet */ - LOAD_FINISHED /* Model is fully loaded and inserted into the tree */ -} LoadState; - #define MAX_LOADING_TIME 500 struct _GtkFileChooserDefaultClass @@ -159,111 +149,6 @@ struct _GtkFileChooserDefaultClass GtkVBoxClass parent_class; }; -struct _GtkFileChooserDefault -{ - GtkVBox parent_instance; - - GtkFileChooserAction action; - - GtkFileSystem *file_system; - - /* Save mode widgets */ - GtkWidget *save_widgets; - - GtkWidget *save_file_name_entry; - GtkWidget *save_folder_label; - GtkWidget *save_folder_combo; - GtkWidget *save_expander; - - /* The file browsing widgets */ - GtkWidget *browse_widgets; - GtkWidget *browse_shortcuts_tree_view; - GtkWidget *browse_shortcuts_add_button; - GtkWidget *browse_shortcuts_remove_button; - GtkWidget *browse_shortcuts_popup_menu; - GtkWidget *browse_shortcuts_popup_menu_remove_item; - GtkWidget *browse_shortcuts_popup_menu_rename_item; - GtkWidget *browse_files_tree_view; - GtkWidget *browse_files_popup_menu; - GtkWidget *browse_files_popup_menu_add_shortcut_item; - GtkWidget *browse_files_popup_menu_hidden_files_item; - GtkWidget *browse_new_folder_button; - GtkWidget *browse_path_bar; - - GtkFileSystemModel *browse_files_model; - - GtkWidget *filter_combo_hbox; - GtkWidget *filter_combo; - GtkWidget *preview_box; - GtkWidget *preview_label; - GtkWidget *preview_widget; - GtkWidget *extra_align; - GtkWidget *extra_widget; - - GtkListStore *shortcuts_model; - GtkTreeModel *shortcuts_filter_model; - - GtkTreeModelSort *sort_model; - - LoadState load_state; - guint load_timeout_id; - - GSList *pending_select_paths; - - GtkFileFilter *current_filter; - GSList *filters; - - GtkTooltips *tooltips; - - gboolean has_home; - gboolean has_desktop; - - int num_volumes; - int num_shortcuts; - int num_bookmarks; - - gulong volumes_changed_id; - gulong bookmarks_changed_id; - - GtkFilePath *current_volume_path; - GtkFilePath *current_folder; - GtkFilePath *preview_path; - char *preview_display_name; - - GtkTreeViewColumn *list_name_column; - GtkCellRenderer *list_name_renderer; - - GSource *edited_idle; - char *edited_new_text; - - gulong settings_signal_id; - int icon_size; - - gulong toplevel_set_focus_id; - GtkWidget *toplevel_last_focus_widget; - -#if 0 - GdkDragContext *shortcuts_drag_context; - GSource *shortcuts_drag_outside_idle; -#endif - - /* Flags */ - - guint local_only : 1; - guint preview_widget_active : 1; - guint use_preview_label : 1; - guint select_multiple : 1; - guint show_hidden : 1; - guint do_overwrite_confirmation : 1; - guint list_sort_ascending : 1; - guint changing_folder : 1; - guint shortcuts_current_folder_active : 1; - -#if 0 - guint shortcuts_drag_outside : 1; -#endif -}; - /* Signal IDs */ enum { LOCATION_POPUP, diff --git a/gtk/gtkfilechooserdialog.c b/gtk/gtkfilechooserdialog.c index d84f0ba3e3..db1e574410 100644 --- a/gtk/gtkfilechooserdialog.c +++ b/gtk/gtkfilechooserdialog.c @@ -19,6 +19,7 @@ */ #include +#include "gtkfilechooserprivate.h" #include "gtkfilechooserdialog.h" #include "gtkfilechooserwidget.h" #include "gtkfilechooserutils.h" @@ -30,19 +31,6 @@ #include -struct _GtkFileChooserDialogPrivate -{ - GtkWidget *widget; - - char *file_system; - - /* for use with GtkFileChooserEmbed */ - gint default_width; - gint default_height; - gboolean resize_horizontally; - gboolean resize_vertically; -}; - #define GTK_FILE_CHOOSER_DIALOG_GET_PRIVATE(o) (GTK_FILE_CHOOSER_DIALOG (o)->priv) static void gtk_file_chooser_dialog_class_init (GtkFileChooserDialogClass *class); diff --git a/gtk/gtkfilechooserprivate.h b/gtk/gtkfilechooserprivate.h index 45ec0b9146..0efc915ef1 100644 --- a/gtk/gtkfilechooserprivate.h +++ b/gtk/gtkfilechooserprivate.h @@ -23,6 +23,13 @@ #include "gtkfilechooser.h" #include "gtkfilesystem.h" +#include "gtkfilesystemmodel.h" +#include "gtkliststore.h" +#include "gtktooltips.h" +#include "gtktreemodelsort.h" +#include "gtktreestore.h" +#include "gtktreeview.h" +#include "gtkvbox.h" G_BEGIN_DECLS @@ -93,6 +100,202 @@ gboolean _gtk_file_chooser_remove_shortcut_folder (GtkFileChooser *cho const GtkFilePath *path, GError **error); +/* GtkFileChooserDialog private */ + +struct _GtkFileChooserDialogPrivate +{ + GtkWidget *widget; + + char *file_system; + + /* for use with GtkFileChooserEmbed */ + gint default_width; + gint default_height; + gboolean resize_horizontally; + gboolean resize_vertically; +}; + + +/* GtkFileChooserWidget private */ + +struct _GtkFileChooserWidgetPrivate +{ + GtkWidget *impl; + + char *file_system; +}; + + +/* GtkFileChooserDefault private */ + +typedef enum { + LOAD_EMPTY, /* There is no model */ + LOAD_PRELOAD, /* Model is loading and a timer is running; model isn't inserted into the tree yet */ + LOAD_LOADING, /* Timeout expired, model is inserted into the tree, but not fully loaded yet */ + LOAD_FINISHED /* Model is fully loaded and inserted into the tree */ +} LoadState; + +struct _GtkFileChooserDefault +{ + GtkVBox parent_instance; + + GtkFileChooserAction action; + + GtkFileSystem *file_system; + + /* Save mode widgets */ + GtkWidget *save_widgets; + + GtkWidget *save_file_name_entry; + GtkWidget *save_folder_label; + GtkWidget *save_folder_combo; + GtkWidget *save_expander; + + /* The file browsing widgets */ + GtkWidget *browse_widgets; + GtkWidget *browse_shortcuts_tree_view; + GtkWidget *browse_shortcuts_add_button; + GtkWidget *browse_shortcuts_remove_button; + GtkWidget *browse_shortcuts_popup_menu; + GtkWidget *browse_shortcuts_popup_menu_remove_item; + GtkWidget *browse_shortcuts_popup_menu_rename_item; + GtkWidget *browse_files_tree_view; + GtkWidget *browse_files_popup_menu; + GtkWidget *browse_files_popup_menu_add_shortcut_item; + GtkWidget *browse_files_popup_menu_hidden_files_item; + GtkWidget *browse_new_folder_button; + GtkWidget *browse_path_bar; + + GtkFileSystemModel *browse_files_model; + + GtkWidget *filter_combo_hbox; + GtkWidget *filter_combo; + GtkWidget *preview_box; + GtkWidget *preview_label; + GtkWidget *preview_widget; + GtkWidget *extra_align; + GtkWidget *extra_widget; + + GtkListStore *shortcuts_model; + GtkTreeModel *shortcuts_filter_model; + + GtkTreeModelSort *sort_model; + + LoadState load_state; + guint load_timeout_id; + + GSList *pending_select_paths; + + GtkFileFilter *current_filter; + GSList *filters; + + GtkTooltips *tooltips; + + gboolean has_home; + gboolean has_desktop; + + int num_volumes; + int num_shortcuts; + int num_bookmarks; + + gulong volumes_changed_id; + gulong bookmarks_changed_id; + + GtkFilePath *current_volume_path; + GtkFilePath *current_folder; + GtkFilePath *preview_path; + char *preview_display_name; + + GtkTreeViewColumn *list_name_column; + GtkCellRenderer *list_name_renderer; + + GSource *edited_idle; + char *edited_new_text; + + gulong settings_signal_id; + int icon_size; + + gulong toplevel_set_focus_id; + GtkWidget *toplevel_last_focus_widget; + +#if 0 + GdkDragContext *shortcuts_drag_context; + GSource *shortcuts_drag_outside_idle; +#endif + + /* Flags */ + + guint local_only : 1; + guint preview_widget_active : 1; + guint use_preview_label : 1; + guint select_multiple : 1; + guint show_hidden : 1; + guint do_overwrite_confirmation : 1; + guint list_sort_ascending : 1; + guint changing_folder : 1; + guint shortcuts_current_folder_active : 1; + +#if 0 + guint shortcuts_drag_outside : 1; +#endif +}; + + +/* GtkFileSystemModel private */ + +typedef struct _FileModelNode FileModelNode; + +struct _GtkFileSystemModel +{ + GObject parent_instance; + + GtkFileSystem *file_system; + GtkFileInfoType types; + FileModelNode *roots; + GtkFileFolder *root_folder; + GtkFilePath *root_path; + + GtkFileSystemModelFilter filter_func; + gpointer filter_data; + + GSList *idle_clears; + GSource *idle_clear_source; + GSource *idle_finished_loading_source; + + gushort max_depth; + + guint show_hidden : 1; + guint show_folders : 1; + guint show_files : 1; + guint folders_only : 1; + guint has_editable : 1; +}; + +struct _FileModelNode +{ + GtkFilePath *path; + FileModelNode *next; + + GtkFileInfo *info; + GtkFileFolder *folder; + + FileModelNode *children; + FileModelNode *parent; + GtkFileSystemModel *model; + + guint ref_count; + guint n_referenced_children; + + gushort depth; + + guint has_dummy : 1; + guint is_dummy : 1; + guint is_visible : 1; + guint loaded : 1; + guint idle_clear : 1; +}; + + G_END_DECLS #endif /* __GTK_FILE_CHOOSER_PRIVATE_H__ */ diff --git a/gtk/gtkfilechooserwidget.c b/gtk/gtkfilechooserwidget.c index 645b0b0d57..c065f67f65 100644 --- a/gtk/gtkfilechooserwidget.c +++ b/gtk/gtkfilechooserwidget.c @@ -19,6 +19,7 @@ */ #include +#include "gtkfilechooserprivate.h" #include "gtkfilechooserwidget.h" #include "gtkfilechooserdefault.h" #include "gtkfilechooserutils.h" @@ -27,13 +28,6 @@ #include "gtkintl.h" #include "gtkalias.h" -struct _GtkFileChooserWidgetPrivate -{ - GtkWidget *impl; - - char *file_system; -}; - #define GTK_FILE_CHOOSER_WIDGET_GET_PRIVATE(o) (GTK_FILE_CHOOSER_WIDGET (o)->priv) static void gtk_file_chooser_widget_class_init (GtkFileChooserWidgetClass *class); diff --git a/gtk/gtkfilesystemmodel.c b/gtk/gtkfilesystemmodel.c index 9c2dd30607..b2ad218ea9 100644 --- a/gtk/gtkfilesystemmodel.c +++ b/gtk/gtkfilesystemmodel.c @@ -21,6 +21,7 @@ #include #include +#include "gtkfilechooserprivate.h" #include "gtkfilesystemmodel.h" #include "gtkfilesystem.h" #include "gtkintl.h" @@ -30,7 +31,6 @@ #include "gtkalias.h" typedef struct _GtkFileSystemModelClass GtkFileSystemModelClass; -typedef struct _FileModelNode FileModelNode; #define GTK_FILE_SYSTEM_MODEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_FILE_SYSTEM_MODEL, GtkFileSystemModelClass)) #define GTK_IS_FILE_SYSTEM_MODEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_FILE_SYSTEM_MODEL)) @@ -45,55 +45,6 @@ struct _GtkFileSystemModelClass void (*finished_loading) (GtkFileSystemModel *model); }; -struct _GtkFileSystemModel -{ - GObject parent_instance; - - GtkFileSystem *file_system; - GtkFileInfoType types; - FileModelNode *roots; - GtkFileFolder *root_folder; - GtkFilePath *root_path; - - GtkFileSystemModelFilter filter_func; - gpointer filter_data; - - GSList *idle_clears; - GSource *idle_clear_source; - GSource *idle_finished_loading_source; - - gushort max_depth; - - guint show_hidden : 1; - guint show_folders : 1; - guint show_files : 1; - guint folders_only : 1; - guint has_editable : 1; -}; - -struct _FileModelNode -{ - GtkFilePath *path; - FileModelNode *next; - - GtkFileInfo *info; - GtkFileFolder *folder; - - FileModelNode *children; - FileModelNode *parent; - GtkFileSystemModel *model; - - guint ref_count; - guint n_referenced_children; - - gushort depth; - - guint has_dummy : 1; - guint is_dummy : 1; - guint is_visible : 1; - guint loaded : 1; - guint idle_clear : 1; -}; static void gtk_file_system_model_class_init (GtkFileSystemModelClass *class); static void gtk_file_system_model_iface_init (GtkTreeModelIface *iface); diff --git a/tests/Makefile.am b/tests/Makefile.am index a2bc7e7935..58fdf41be7 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -27,6 +27,7 @@ endif noinst_PROGRAMS = \ + autotestfilechooser \ simple \ testcairo \ testcalendar \ @@ -73,6 +74,7 @@ noinst_PROGRAMS = \ testmerge \ testactions +autotestfilechooser_DEPENDENCIES = $(TEST_DEPS) simple_DEPENDENCIES = $(TEST_DEPS) testicontheme_DEPENDENCIES = $(TEST_DEPS) testiconview_DEPENDENCIES = $(TEST_DEPS) @@ -113,6 +115,7 @@ testxinerama_DEPENDENCIES = $(TEST_DEPS) testmerge_DEPENDENCIES = $(TEST_DEPS) testactions_DEPENDENCIES = $(TEST_DEPS) +autotestfilechooser_LDADD = $(LDADDS) simple_LDADD = $(LDADDS) testcairo_LDADD = $(LDADDS) testcalendar_LDADD = $(LDADDS) @@ -160,6 +163,9 @@ pixbuf_threads_LDADD = $(LDADDS) $(GLIB_LIBS) testmerge_LDADD = $(LDADDS) testactions_LDADD = $(LDADDS) +autotestfilechooser_SOURCES = \ + autotestfilechooser.c + testfilechooser_SOURCES = \ prop-editor.c \ testfilechooser.c diff --git a/tests/autotestfilechooser.c b/tests/autotestfilechooser.c new file mode 100644 index 0000000000..0ba2683333 --- /dev/null +++ b/tests/autotestfilechooser.c @@ -0,0 +1,252 @@ +#define GTK_FILE_SYSTEM_ENABLE_UNSUPPORTED + +#include +#include +#include +#include "gtk/gtkfilechooserprivate.h" +#include "gtk/gtkfilechooserdefault.h" +#include "gtk/gtkfilechooserentry.h" + +static void +log_test (gboolean passed, const char *test_name, ...) +{ + va_list args; + char *str; + + va_start (args, test_name); + str = g_strdup_vprintf (test_name, args); + va_end (args); + + g_printf ("%s: %s\n", passed ? "PASSED" : "FAILED", str); + g_free (str); +} + +static const GtkFileChooserAction open_actions[] = { + GTK_FILE_CHOOSER_ACTION_OPEN, + GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER +}; + +static const GtkFileChooserAction save_actions[] = { + GTK_FILE_CHOOSER_ACTION_SAVE, + GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER +}; + + +static gboolean +has_action (const GtkFileChooserAction *actions, + int n_actions, + GtkFileChooserAction sought_action) +{ + int i; + + for (i = 0; i < n_actions; i++) + if (actions[i] == sought_action) + return TRUE; + + return FALSE; +} + +static const char * +get_action_name (GtkFileChooserAction action) +{ + GEnumClass *enum_class; + GEnumValue *enum_value; + + enum_class = g_type_class_peek (GTK_TYPE_FILE_CHOOSER_ACTION); + if (!enum_class) + g_error ("BUG: get_action_name(): no GEnumClass for GTK_TYPE_FILE_CHOOSER_ACTION"); + + enum_value = g_enum_get_value (enum_class, (int) action); + if (!enum_value) + g_error ("BUG: get_action_name(): no GEnumValue for GtkFileChooserAction %d", (int) action); + + return enum_value->value_name; +} + +static gboolean +test_widgets_for_current_action (GtkFileChooserDialog *dialog, + GtkFileChooserAction expected_action) +{ + 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; + chooser_widget = GTK_FILE_CHOOSER_WIDGET (dialog_priv->widget); + if (!chooser_widget) + g_error ("BUG: dialog_priv->widget is not a GtkFileChooserWidget"); + + widget_priv = chooser_widget->priv; + impl = (GtkFileChooserDefault *) (widget_priv->impl); + if (!impl) + g_error ("BUG: widget_priv->impl is not a GtkFileChooserDefault"); + + g_assert (impl->action == expected_action); + + passed = TRUE; + + /* OPEN implies that the "new folder" button is hidden; otherwise it is shown */ + if (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN) + passed = passed && !GTK_WIDGET_VISIBLE (impl->browse_new_folder_button); + else + passed = passed && GTK_WIDGET_VISIBLE (impl->browse_new_folder_button); + + /* Check that the widgets are present/visible or not */ + if (has_action (open_actions, G_N_ELEMENTS (open_actions), impl->action)) + { + passed = passed && (impl->save_widgets == NULL + && impl->save_file_name_entry == NULL + && impl->save_folder_label == NULL + && impl->save_folder_combo == NULL + && impl->save_expander == NULL + && GTK_IS_CONTAINER (impl->browse_widgets) && GTK_WIDGET_DRAWABLE (impl->browse_widgets)); + } + else if (has_action (save_actions, G_N_ELEMENTS (save_actions), impl->action)) + { + /* FIXME: we can't use GTK_IS_FILE_CHOOSER_ENTRY() because it uses + * _gtk_file_chooser_entry_get_type(), which is a non-exported symbol. + * So, we just test impl->save_file_name_entry for being non-NULL + */ + passed = passed && (GTK_IS_CONTAINER (impl->save_widgets) && GTK_WIDGET_DRAWABLE (impl->save_widgets) + && impl->save_file_name_entry != NULL && GTK_WIDGET_DRAWABLE (impl->save_file_name_entry) + && GTK_IS_LABEL (impl->save_folder_label) && GTK_WIDGET_DRAWABLE (impl->save_folder_label) + && GTK_IS_COMBO_BOX (impl->save_folder_combo) && GTK_WIDGET_DRAWABLE (impl->save_folder_combo) + && GTK_IS_EXPANDER (impl->save_expander) && GTK_WIDGET_DRAWABLE (impl->save_expander) + && GTK_IS_CONTAINER (impl->browse_widgets)); + + /* FIXME: we are in a SAVE mode; test the visibility and sensitivity of + * the children that change depending on the state of the expander. + */ + } + else + { + g_error ("BAD TEST: test_widgets_for_current_action() doesn't know about %s", get_action_name (impl->action)); + passed = FALSE; + } + + return passed; +} + +typedef gboolean (* ForeachActionCallback) (GtkFileChooserDialog *dialog, + GtkFileChooserAction action, + gpointer user_data); + +static gboolean +foreach_action (GtkFileChooserDialog *dialog, + ForeachActionCallback callback, + gpointer user_data) +{ + GEnumClass *enum_class; + int i; + + enum_class = g_type_class_peek (GTK_TYPE_FILE_CHOOSER_ACTION); + if (!enum_class) + g_error ("BUG: get_action_name(): no GEnumClass for GTK_TYPE_FILE_CHOOSER_ACTION"); + + for (i = 0; i < enum_class->n_values; i++) + { + GEnumValue *enum_value; + GtkFileChooserAction action; + gboolean passed; + + enum_value = enum_class->values + i; + action = enum_value->value; + + passed = (* callback) (dialog, action, user_data); + if (!passed) + return FALSE; + } + + return TRUE; +} + +struct action_closure { + GtkFileChooserAction from_action; +}; + +static gboolean +switch_from_to_action_cb (GtkFileChooserDialog *dialog, + GtkFileChooserAction action, + gpointer user_data) +{ + struct action_closure *closure; + gboolean passed; + + closure = user_data; + + gtk_file_chooser_set_action (GTK_FILE_CHOOSER (dialog), closure->from_action); + + passed = test_widgets_for_current_action (dialog, closure->from_action); + log_test (passed, "switch_from_to_action_cb(): reset to action %s", get_action_name (closure->from_action)); + if (!passed) + return FALSE; + + gtk_file_chooser_set_action (GTK_FILE_CHOOSER (dialog), action); + + passed = test_widgets_for_current_action (dialog, action); + log_test (passed, "switch_from_to_action_cb(): transition from %s to %s", + get_action_name (closure->from_action), + get_action_name (action)); + return passed; +} + +static gboolean +switch_from_action_cb (GtkFileChooserDialog *dialog, + GtkFileChooserAction action, + gpointer user_data) +{ + struct action_closure closure; + + closure.from_action = action; + + return foreach_action (dialog, switch_from_to_action_cb, &closure); +} + +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) +{ + GtkWidget *dialog; + + gtk_init (&argc, &argv); + + 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); + gtk_widget_show (dialog); + + test_action_widgets (GTK_FILE_CHOOSER_DIALOG (dialog)); + + gtk_widget_destroy (dialog); + + return 0; +}