diff options
author | Ross Burton <ross@openedhand.com> | 2008-01-10 11:06:09 +0000 |
---|---|---|
committer | Ross Burton <ross@openedhand.com> | 2008-01-10 11:06:09 +0000 |
commit | e84e87594633a0efd40b3a703c819d94b4b6b68c (patch) | |
tree | 9bff8cb3eaf25e8d379e560934037d79087b08f2 /meta/packages/gtk+ | |
parent | 305ca5dc9a27f91db1be64fec070a4e4f78fba19 (diff) | |
download | openembedded-core-e84e87594633a0efd40b3a703c819d94b4b6b68c.tar.gz openembedded-core-e84e87594633a0efd40b3a703c819d94b4b6b68c.tar.bz2 openembedded-core-e84e87594633a0efd40b3a703c819d94b4b6b68c.zip |
gtk: upgrade 2.15.3 to 2.15.5
git-svn-id: https://svn.o-hand.com/repos/poky/trunk@3447 311d38ba-8fff-0310-9ca6-ca027cbcb966
Diffstat (limited to 'meta/packages/gtk+')
-rw-r--r-- | meta/packages/gtk+/gtk+-2.12.5/cellrenderer-cairo.patch (renamed from meta/packages/gtk+/gtk+-2.12.3/cellrenderer-cairo.patch) | 0 | ||||
-rw-r--r-- | meta/packages/gtk+/gtk+-2.12.5/combo-arrow-size.patch (renamed from meta/packages/gtk+/gtk+-2.12.3/combo-arrow-size.patch) | 0 | ||||
-rw-r--r-- | meta/packages/gtk+/gtk+-2.12.5/disable-print.patch (renamed from meta/packages/gtk+/gtk+-2.12.3/disable-print.patch) | 0 | ||||
-rw-r--r-- | meta/packages/gtk+/gtk+-2.12.5/entry-cairo.patch (renamed from meta/packages/gtk+/gtk+-2.12.3/entry-cairo.patch) | 0 | ||||
-rw-r--r-- | meta/packages/gtk+/gtk+-2.12.5/filechooser-default.patch (renamed from meta/packages/gtk+/gtk+-2.12.3/filechooser-default.patch) | 8913 | ||||
-rw-r--r-- | meta/packages/gtk+/gtk+-2.12.5/filechooser-utils.patch (renamed from meta/packages/gtk+/gtk+-2.12.3/filechooser-utils.patch) | 0 | ||||
-rw-r--r-- | meta/packages/gtk+/gtk+-2.12.5/filechooser.patch (renamed from meta/packages/gtk+/gtk+-2.12.3/filechooser.patch) | 0 | ||||
-rw-r--r-- | meta/packages/gtk+/gtk+-2.12.5/filesystem-volumes.patch (renamed from meta/packages/gtk+/gtk+-2.12.3/filesystem-volumes.patch) | 0 | ||||
-rw-r--r-- | meta/packages/gtk+/gtk+-2.12.5/gtklabel-resize-patch (renamed from meta/packages/gtk+/gtk+-2.12.3/gtklabel-resize-patch) | 0 | ||||
-rw-r--r-- | meta/packages/gtk+/gtk+-2.12.5/hardcoded_libtool.patch (renamed from meta/packages/gtk+/gtk+-2.12.3/hardcoded_libtool.patch) | 0 | ||||
-rw-r--r-- | meta/packages/gtk+/gtk+-2.12.5/menu-deactivate.patch (renamed from meta/packages/gtk+/gtk+-2.12.3/menu-deactivate.patch) | 0 | ||||
-rw-r--r-- | meta/packages/gtk+/gtk+-2.12.5/no-demos.patch (renamed from meta/packages/gtk+/gtk+-2.12.3/no-demos.patch) | 0 | ||||
-rw-r--r-- | meta/packages/gtk+/gtk+-2.12.5/pangoxft2.10.6.diff (renamed from meta/packages/gtk+/gtk+-2.12.3/pangoxft2.10.6.diff) | 0 | ||||
-rw-r--r-- | meta/packages/gtk+/gtk+-2.12.5/range-no-redraw.patch (renamed from meta/packages/gtk+/gtk+-2.12.3/range-no-redraw.patch) | 0 | ||||
-rw-r--r-- | meta/packages/gtk+/gtk+-2.12.5/run-iconcache.patch (renamed from meta/packages/gtk+/gtk+-2.12.3/run-iconcache.patch) | 0 | ||||
-rw-r--r-- | meta/packages/gtk+/gtk+-2.12.5/scrolled-placement.patch (renamed from meta/packages/gtk+/gtk+-2.12.3/scrolled-placement.patch) | 0 | ||||
-rw-r--r-- | meta/packages/gtk+/gtk+-2.12.5/toggle-font.diff (renamed from meta/packages/gtk+/gtk+-2.12.3/toggle-font.diff) | 0 | ||||
-rw-r--r-- | meta/packages/gtk+/gtk+-2.12.5/xsettings.patch (renamed from meta/packages/gtk+/gtk+-2.12.3/xsettings.patch) | 0 | ||||
-rw-r--r-- | meta/packages/gtk+/gtk+_2.12.5.bb (renamed from meta/packages/gtk+/gtk+_2.12.3.bb) | 0 |
19 files changed, 2126 insertions, 6787 deletions
diff --git a/meta/packages/gtk+/gtk+-2.12.3/cellrenderer-cairo.patch b/meta/packages/gtk+/gtk+-2.12.5/cellrenderer-cairo.patch index 4439e69fb6..4439e69fb6 100644 --- a/meta/packages/gtk+/gtk+-2.12.3/cellrenderer-cairo.patch +++ b/meta/packages/gtk+/gtk+-2.12.5/cellrenderer-cairo.patch diff --git a/meta/packages/gtk+/gtk+-2.12.3/combo-arrow-size.patch b/meta/packages/gtk+/gtk+-2.12.5/combo-arrow-size.patch index d44c454ce3..d44c454ce3 100644 --- a/meta/packages/gtk+/gtk+-2.12.3/combo-arrow-size.patch +++ b/meta/packages/gtk+/gtk+-2.12.5/combo-arrow-size.patch diff --git a/meta/packages/gtk+/gtk+-2.12.3/disable-print.patch b/meta/packages/gtk+/gtk+-2.12.5/disable-print.patch index 13cbd91d77..13cbd91d77 100644 --- a/meta/packages/gtk+/gtk+-2.12.3/disable-print.patch +++ b/meta/packages/gtk+/gtk+-2.12.5/disable-print.patch diff --git a/meta/packages/gtk+/gtk+-2.12.3/entry-cairo.patch b/meta/packages/gtk+/gtk+-2.12.5/entry-cairo.patch index 3313e7f132..3313e7f132 100644 --- a/meta/packages/gtk+/gtk+-2.12.3/entry-cairo.patch +++ b/meta/packages/gtk+/gtk+-2.12.5/entry-cairo.patch diff --git a/meta/packages/gtk+/gtk+-2.12.3/filechooser-default.patch b/meta/packages/gtk+/gtk+-2.12.5/filechooser-default.patch index 17671db0d1..34a86b2bfb 100644 --- a/meta/packages/gtk+/gtk+-2.12.3/filechooser-default.patch +++ b/meta/packages/gtk+/gtk+-2.12.5/filechooser-default.patch @@ -1,7 +1,7 @@ -Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c -=================================================================== ---- gtk+-2.12.3.orig/gtk/gtkfilechooserdefault.c 2007-12-04 16:52:08.000000000 +0000 -+++ gtk+-2.12.3/gtk/gtkfilechooserdefault.c 2008-01-04 10:11:11.000000000 +0000 +Index: gtk+-2.12.5/gtk/gtkfilechooserdefault.c +================ =================================================== +--- gtk+-2.12.5/gtk/gtkfilechooserdefault.c (revision 19337) ++++ gtk+-2.12.5/gtk/gtkfilechooserdefault.c (working copy) @@ -27,12 +27,12 @@ #include "gtkcelllayout.h" #include "gtkcellrendererpixbuf.h" @@ -52,23 +52,6 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c /* Profiling stuff */ #undef PROFILE_FILE_CHOOSER #ifdef PROFILE_FILE_CHOOSER -@@ -102,6 +98,7 @@ - #endif - - #define PROFILE_INDENT 4 -+ - static int profile_indent; - - static void -@@ -141,8 +138,6 @@ - #define profile_msg(x, y) - #endif - -- -- - typedef struct _GtkFileChooserDefaultClass GtkFileChooserDefaultClass; - - #define GTK_FILE_CHOOSER_DEFAULT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_FILE_CHOOSER_DEFAULT, GtkFileChooserDefaultClass)) @@ -150,6 +145,7 @@ #define GTK_FILE_CHOOSER_DEFAULT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_FILE_CHOOSER_DEFAULT, GtkFileChooserDefaultClass)) @@ -219,14 +202,6 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c #define NUM_LINES 45 #define NUM_CHARS 60 -@@ -361,7 +241,6 @@ - const GtkFilePath *path, - GError **error); - static GSList * gtk_file_chooser_default_list_shortcut_folders (GtkFileChooser *chooser); -- - static void gtk_file_chooser_default_get_default_size (GtkFileChooserEmbed *chooser_embed, - gint *default_width, - gint *default_height); @@ -369,52 +248,17 @@ static gboolean gtk_file_chooser_default_should_respond (GtkFileChooserEmbed *chooser_embed); static void gtk_file_chooser_default_initial_focus (GtkFileChooserEmbed *chooser_embed); @@ -245,23 +220,23 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c -static void search_shortcut_handler (GtkFileChooserDefault *impl); -static void recent_shortcut_handler (GtkFileChooserDefault *impl); -static void update_appearance (GtkFileChooserDefault *impl); -- --static void set_current_filter (GtkFileChooserDefault *impl, -- GtkFileFilter *filter); --static void check_preview_change (GtkFileChooserDefault *impl); +static void up_folder_handler (GtkFileChooserDefault *impl); +static void down_folder_handler (GtkFileChooserDefault *impl); +static void home_folder_handler (GtkFileChooserDefault *impl); +static void show_hidden_handler (GtkFileChooserDefault *impl); +static void update_appearance (GtkFileChooserDefault *impl); +-static void set_current_filter (GtkFileChooserDefault *impl, +- GtkFileFilter *filter); +-static void check_preview_change (GtkFileChooserDefault *impl); +- static void filter_combo_changed (GtkComboBox *combo_box, GtkFileChooserDefault *impl); -static void shortcuts_row_activated_cb (GtkTreeView *tree_view, - GtkTreePath *path, - GtkTreeViewColumn *column, - GtkFileChooserDefault *impl); -- + -static gboolean shortcuts_key_press_event_cb (GtkWidget *widget, - GdkEventKey *event, - GtkFileChooserDefault *impl); @@ -281,7 +256,7 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - const GtkFilePath *path); - -static void bookmarks_check_add_sensitivity (GtkFileChooserDefault *impl); - +- +static void set_current_filter (GtkFileChooserDefault *impl, + GtkFileFilter *filter); static gboolean list_select_func (GtkTreeSelection *selection, @@ -307,12 +282,13 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c static void list_icon_data_func (GtkTreeViewColumn *tree_column, GtkCellRenderer *cell, GtkTreeModel *tree_model, -@@ -477,114 +308,7 @@ +@@ -477,115 +308,8 @@ static void location_button_toggled_cb (GtkToggleButton *toggle, GtkFileChooserDefault *impl); -static void location_switch_to_path_bar (GtkFileChooserDefault *impl); -- ++static void settings_load (GtkFileChooserDefault *impl); + -static void search_stop_searching (GtkFileChooserDefault *impl, - gboolean remove_query); -static void search_clear_model (GtkFileChooserDefault *impl, @@ -419,10 +395,10 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - GtkTreeModel *child_model); - - -+static void settings_load (GtkFileChooserDefault *impl); - +- G_DEFINE_TYPE_WITH_CODE (GtkFileChooserDefault, _gtk_file_chooser_default, GTK_TYPE_VBOX, G_IMPLEMENT_INTERFACE (GTK_TYPE_FILE_CHOOSER, + gtk_file_chooser_default_iface_init) @@ -595,13 +319,9 @@ static void _gtk_file_chooser_default_class_init (GtkFileChooserDefaultClass *class) @@ -446,23 +422,26 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c NULL, NULL, _gtk_marshal_VOID__STRING, G_TYPE_NONE, 1, G_TYPE_STRING); -@@ -629,15 +349,7 @@ +@@ -629,18 +349,10 @@ _gtk_binding_signal_new ("location-popup-on-paste", G_OBJECT_CLASS_TYPE (class), G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION, - G_CALLBACK (location_popup_on_paste_handler), -- NULL, NULL, -- _gtk_marshal_VOID__VOID, -- G_TYPE_NONE, 0); ++ NULL, + NULL, NULL, + _gtk_marshal_VOID__VOID, + G_TYPE_NONE, 0); - signals[LOCATION_TOGGLE_POPUP] = - _gtk_binding_signal_new (I_("location-toggle-popup"), - G_OBJECT_CLASS_TYPE (class), - G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION, - G_CALLBACK (location_toggle_popup_handler), -+ NULL, - NULL, NULL, - _gtk_marshal_VOID__VOID, - G_TYPE_NONE, 0); +- NULL, NULL, +- _gtk_marshal_VOID__VOID, +- G_TYPE_NONE, 0); + signals[UP_FOLDER] = + _gtk_binding_signal_new (I_("up-folder"), + G_OBJECT_CLASS_TYPE (class), @@ -665,22 +377,6 @@ NULL, NULL, _gtk_marshal_VOID__VOID, @@ -528,13 +507,13 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - GDK_r, GDK_MOD1_MASK, - "recent-shortcut", - 0); -- + - for (i = 0; i < 10; i++) - gtk_binding_entry_add_signal (binding_set, - quick_bookmark_keyvals[i], GDK_MOD1_MASK, - "quick-bookmark", - 1, G_TYPE_INT, i); - +- _gtk_file_chooser_install_properties (gobject_class); + + gtk_settings_install_property (g_param_spec_string ("gtk-file-chooser-backend", @@ -567,7 +546,7 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c } static void -@@ -827,85 +497,27 @@ +@@ -827,87 +497,29 @@ access ("MARK: *** CREATE FILE CHOOSER", F_OK); #endif impl->local_only = TRUE; @@ -591,9 +570,12 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c impl->tooltips = gtk_tooltips_new (); g_object_ref_sink (impl->tooltips); -- profile_end ("end", NULL); --} -- ++ if (!impl->root_folder) ++ impl->root_folder = g_strdup ("/"); ++ + profile_end ("end", NULL); + } + -/* Frees the data columns for the specified iter in the shortcuts model*/ -static void -shortcuts_free_row_data (GtkFileChooserDefault *impl, @@ -602,7 +584,7 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - gpointer col_data; - ShortcutType shortcut_type; - GtkFileSystemHandle *handle; -- + - gtk_tree_model_get (GTK_TREE_MODEL (impl->shortcuts_model), iter, - SHORTCUTS_COL_DATA, &col_data, - SHORTCUTS_COL_TYPE, &shortcut_type, @@ -629,17 +611,14 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - GtkFilePath *path; - - g_assert (shortcut_type == SHORTCUT_TYPE_PATH); -+ if (!impl->root_folder) -+ impl->root_folder = g_strdup ("/"); - +- - path = col_data; - gtk_file_path_free (path); - } -+ profile_end ("end", NULL); - } - +-} +- -/* Frees all the data columns in the shortcuts model */ --static void + static void -shortcuts_free (GtkFileChooserDefault *impl) -{ - GtkTreeIter iter; @@ -657,25 +636,12 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - g_object_unref (impl->shortcuts_model); - impl->shortcuts_model = NULL; -} - - static void +- +-static void pending_select_paths_free (GtkFileChooserDefault *impl) -@@ -924,12 +536,12 @@ - impl->pending_select_paths = NULL; - } - -+ - static void - pending_select_paths_add (GtkFileChooserDefault *impl, - const GtkFilePath *path) { -- impl->pending_select_paths = -- g_slist_prepend (impl->pending_select_paths, gtk_file_path_copy (path)); -+ impl->pending_select_paths = g_slist_prepend (impl->pending_select_paths, gtk_file_path_copy (path)); - } - - /* Used from gtk_tree_selection_selected_foreach() */ -@@ -964,18 +576,27 @@ + GSList *l; +@@ -964,19 +576,28 @@ } static void @@ -690,26 +656,27 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c + for (l = impl->path_history; l; l = l->next) + { + GtkFilePath *path; -+ + +- if (impl->shortcuts_combo_filter_model) +- g_object_unref (impl->shortcuts_combo_filter_model); + path = l->data; + gtk_file_path_free (path); + } -- if (impl->shortcuts_combo_filter_model) -- g_object_unref (impl->shortcuts_combo_filter_model); +- shortcuts_free (impl); + g_slist_free (impl->path_history); + impl->path_history = NULL; +} -- shortcuts_free (impl); +static void +gtk_file_chooser_default_finalize (GObject *object) +{ + GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (object); + GSList *l; - ++ g_object_unref (impl->file_system); + g_free (impl->browse_files_last_selected_name); @@ -999,8 +620,7 @@ if (impl->current_folder) gtk_file_path_free (impl->current_folder); @@ -726,14 +693,14 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - search_clear_model (impl, FALSE); - recent_clear_model (impl, FALSE); -- -- g_free (impl->preview_display_name); + if (impl->list_press_path) + { + gtk_tree_path_free (impl->list_press_path); + impl->list_press_path = NULL; + } +- g_free (impl->preview_display_name); +- g_free (impl->edited_new_text); g_object_unref (impl->tooltips); @@ -785,7 +752,7 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c path, error); } -@@ -1175,9378 +776,3705 @@ +@@ -1175,514 +776,108 @@ /* Changes folders, displaying an error dialog if this fails */ static gboolean @@ -803,9 +770,7 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c g_return_val_if_fail (path != NULL, FALSE); - profile_start ("start", (char *) path); -+ path_copy = gtk_file_path_copy (path); -+ file_name = gtk_file_system_path_to_filename (impl->file_system, path_copy); - +- - /* We copy the path because of this case: - * - * list_row_activated() @@ -814,19 +779,28 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - * calls _gtk_file_chooser_set_current_folder_path() - * changing folders fails, sets model to NULL, thus freeing the path in (*) - */ +- + path_copy = gtk_file_path_copy (path); ++ file_name = gtk_file_system_path_to_filename (impl->file_system, path_copy); + +- error = NULL; +- result = gtk_file_chooser_default_update_current_folder (GTK_FILE_CHOOSER (impl), path_copy, TRUE, clear_entry, &error); + if (!file_name) + { + gtk_file_path_free (path_copy); + return 0; + } -+ + +- if (!result) +- error_changing_folder_dialog (impl, path_copy, error); + if (impl->root_folder && file_name[0] == '/' && file_name[1] == 0) + { + /* If changing to / and we have root_folder, change into it instead */ + gtk_file_path_free (path_copy); + path_copy = gtk_file_system_filename_to_path (impl->file_system, + impl->root_folder); -+ + +- gtk_file_path_free (path_copy); + gtk_widget_set_sensitive (impl->up_button, FALSE); + } + else if (impl->root_folder && @@ -850,7 +824,8 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c + gchar *name = + gtk_file_system_path_to_filename (impl->file_system, + impl->current_folder); -+ + +- profile_end ("end", (char *) path); + if (name && !strncmp (name, "/media", 6)) + { + g_free (name); @@ -858,52 +833,13 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c + g_free (file_name); + return 0; + } -+ -+ gtk_widget_set_sensitive (impl->up_button, TRUE); -+ } -+ else if (!strncmp (file_name, "/media/", 7)) -+ { -+ /* Changing into a media child -- if it is an immediate child, disable -+ * the Up button -+ */ -+ gchar * p = file_name + 7; -+ gchar * q = strchr (p, '/'); -+ if (!q) -+ gtk_widget_set_sensitive (impl->up_button, FALSE); -+ else -+ gtk_widget_set_sensitive (impl->up_button, TRUE); -+ } -+ else -+ { -+ gtk_widget_set_sensitive (impl->up_button, TRUE); -+ } - -- path_copy = gtk_file_path_copy (path); - - error = NULL; -- result = gtk_file_chooser_default_update_current_folder (GTK_FILE_CHOOSER (impl), path_copy, TRUE, clear_entry, &error); -+ result = _gtk_file_chooser_set_current_folder_path (GTK_FILE_CHOOSER (impl), path_copy, &error); - -- if (!result) -+ if (errormsg && !result) - error_changing_folder_dialog (impl, path_copy, error); - -- gtk_file_path_free (path_copy); -+ gtk_label_set_text (GTK_LABEL (impl->location_label), file_name); - -- profile_end ("end", (char *) path); -+ gtk_file_path_free (path_copy); -+ g_free (file_name); - - return result; - } +- return result; +-} +- -static void -update_preview_widget_visibility (GtkFileChooserDefault *impl) -+static gboolean -+change_folder_and_display_error (GtkFileChooserDefault *impl, -+ const GtkFilePath *path) - { +-{ - if (impl->use_preview_label) - { - if (!impl->preview_label) @@ -915,7 +851,21 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - gtk_widget_show (impl->preview_label); - } - } -- else ++ gtk_widget_set_sensitive (impl->up_button, TRUE); ++ } ++ else if (!strncmp (file_name, "/media/", 7)) ++ { ++ /* Changing into a media child -- if it is an immediate child, disable ++ * the Up button ++ */ ++ gchar * p = file_name + 7; ++ gchar * q = strchr (p, '/'); ++ if (!q) ++ gtk_widget_set_sensitive (impl->up_button, FALSE); ++ else ++ gtk_widget_set_sensitive (impl->up_button, TRUE); ++ } + else - { - if (impl->preview_label) - { @@ -923,92 +873,72 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - impl->preview_label = NULL; - } - } -- ++ { ++ gtk_widget_set_sensitive (impl->up_button, TRUE); ++ } + - if (impl->preview_widget_active && impl->preview_widget) - gtk_widget_show (impl->preview_box); - else - gtk_widget_hide (impl->preview_box); -- + - g_signal_emit_by_name (impl, "default-size-changed"); -+ return change_folder (impl, path, TRUE); - } +-} ++ error = NULL; ++ result = _gtk_file_chooser_set_current_folder_path (GTK_FILE_CHOOSER (impl), path_copy, &error); -static void -set_preview_widget (GtkFileChooserDefault *impl, - GtkWidget *preview_widget) -+ -+/* FIXME: GtkFileSystem needs a function to split a remote path -+ * into hostname and path components, or maybe just have a -+ * gtk_file_system_path_get_display_name(). -+ * -+ * This function is also used in gtkfilechooserbutton.c -+ */ -+gchar * -+_gtk_file_chooser_label_for_uri (const gchar *uri) - { +-{ - if (preview_widget == impl->preview_widget) - return; -+ const gchar *path, *start, *end, *p; -+ gchar *host, *label; ++ if (errormsg && !result) ++ error_changing_folder_dialog (impl, path_copy, error); - if (impl->preview_widget) - gtk_container_remove (GTK_CONTAINER (impl->preview_box), - impl->preview_widget); -+ start = strstr (uri, "://"); -+ start += 3; -+ path = strchr (start, '/'); ++ gtk_label_set_text (GTK_LABEL (impl->location_label), file_name); - impl->preview_widget = preview_widget; - if (impl->preview_widget) -+ if (path) -+ end = path; -+ else - { +- { - gtk_widget_show (impl->preview_widget); - gtk_box_pack_start (GTK_BOX (impl->preview_box), impl->preview_widget, TRUE, TRUE, 0); - gtk_box_reorder_child (GTK_BOX (impl->preview_box), - impl->preview_widget, - (impl->use_preview_label && impl->preview_label) ? 1 : 0); -+ end = uri + strlen (uri); -+ path = "/"; - } +- } ++ gtk_file_path_free (path_copy); ++ g_free (file_name); - update_preview_widget_visibility (impl); --} -+ /* strip username */ -+ p = strchr (start, '@'); -+ if (p && p < end) -+ { -+ start = p + 1; -+ } ++ return result; + } -/* Renders a "Search" icon at an appropriate size for a tree view */ -static GdkPixbuf * -render_search_icon (GtkFileChooserDefault *impl) --{ ++static gboolean ++change_folder_and_display_error (GtkFileChooserDefault *impl, ++ const GtkFilePath *path) + { - return gtk_widget_render_icon (GTK_WIDGET (impl), GTK_STOCK_FIND, GTK_ICON_SIZE_MENU, NULL); --} -+ p = strchr (start, ':'); -+ if (p && p < end) -+ end = p; ++ return change_folder (impl, path, TRUE); + } -static GdkPixbuf * -render_recent_icon (GtkFileChooserDefault *impl) -{ - GtkIconTheme *theme; - GdkPixbuf *retval; -+ host = g_strndup (start, end - start); - if (gtk_widget_has_screen (GTK_WIDGET (impl))) - theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (GTK_WIDGET (impl))); - else - theme = gtk_icon_theme_get_default (); -+ /* Translators: the first string is a path and the second string -+ * is a hostname. Nautilus and the panel contain the same string -+ * to translate. -+ */ -+ label = g_strdup_printf (_("%1$s on %2$s"), path, host); - +- - retval = gtk_icon_theme_load_icon (theme, "document-open-recent", - impl->icon_size, 0, - NULL); @@ -1016,13 +946,11 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - /* fallback */ - if (!retval) - retval = gtk_widget_render_icon (GTK_WIDGET (impl), GTK_STOCK_FILE, GTK_ICON_SIZE_MENU, NULL); -+ g_free (host); - +- - return retval; -+ return label; - } - - +-} +- +- -/* Re-reads all the icons for the shortcuts, used when the theme changes */ -struct ReloadIconsData -{ @@ -1030,109 +958,58 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - GtkTreeRowReference *row_ref; -}; - -+/* Callback used when the "New Folder" button is clicked */ - static void +-static void -shortcuts_reload_icons_get_info_cb (GtkFileSystemHandle *handle, - const GtkFileInfo *info, - const GError *error, - gpointer user_data) -+new_folder_button_clicked (GtkButton *button, -+ GtkFileChooserDefault *impl) - { +-{ - GdkPixbuf *pixbuf; - GtkTreeIter iter; - GtkTreePath *path; +- GtkTreeIter iter; +- GtkTreePath *path; - gboolean cancelled = handle->cancelled; - struct ReloadIconsData *data = user_data; - +- - if (!g_slist_find (data->impl->reload_icon_handles, handle)) - goto out; -+ if (!impl->browse_files_model) -+ return; /* FIXME: this sucks. Disable the New Folder button or something. */ - +- - data->impl->reload_icon_handles = g_slist_remove (data->impl->reload_icon_handles, handle); -+ /* Prevent button from being clicked twice */ -+ gtk_widget_set_sensitive (impl->browse_new_folder_button, FALSE); - +- - if (cancelled || error) - goto out; -+ _gtk_file_system_model_add_editable (impl->browse_files_model, &iter); - +- - pixbuf = gtk_file_info_render_icon (info, GTK_WIDGET (data->impl), - data->impl->icon_size, NULL); -+ path = gtk_tree_model_get_path (GTK_TREE_MODEL (impl->browse_files_model), &iter); -+ gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (impl->browse_files_tree_view), -+ path, impl->list_name_column, -+ FALSE, 0.0, 0.0); -+ -+ g_object_set (impl->list_name_renderer, "editable", TRUE, NULL); -+ gtk_tree_view_set_cursor (GTK_TREE_VIEW (impl->browse_files_tree_view), -+ path, -+ impl->list_name_column, -+ TRUE); - +- - path = gtk_tree_row_reference_get_path (data->row_ref); - gtk_tree_model_get_iter (GTK_TREE_MODEL (data->impl->shortcuts_model), &iter, path); - gtk_list_store_set (data->impl->shortcuts_model, &iter, - SHORTCUTS_COL_PIXBUF, pixbuf, - -1); - gtk_tree_path_free (path); -+} - +- gtk_tree_path_free (path); +- - if (pixbuf) - g_object_unref (pixbuf); -+static void -+edited_idle_create_folder_cb (GtkFileSystemHandle *handle, -+ const GtkFilePath *path, -+ const GError *error, -+ gpointer data) -+{ -+ gboolean cancelled = handle->cancelled; -+ GtkFileChooserDefault *impl = data; - +- -out: - gtk_tree_row_reference_free (data->row_ref); - g_object_unref (data->impl); - g_free (data); -+ if (!g_slist_find (impl->pending_handles, handle)) -+ goto out; -+ -+ impl->pending_handles = g_slist_remove (impl->pending_handles, handle); -+ -+ if (cancelled) -+ goto out; -+ -+ if (!error) -+ change_folder_and_display_error (impl, path); -+ else -+ error_creating_folder_dialog (impl, path, g_error_copy (error)); - -+ out: -+ g_object_unref (impl); - g_object_unref (handle); - } - +- +- g_object_unref (handle); +-} +- -static void -shortcuts_reload_icons (GtkFileChooserDefault *impl) -+/* Idle handler for creating a new folder after editing its name cell, or for -+ * canceling the editing. -+ */ -+static gboolean -+edited_idle_cb (GtkFileChooserDefault *impl) - { +-{ - GSList *l; - GtkTreeIter iter; -+ GDK_THREADS_ENTER (); - +- - profile_start ("start", NULL); -+ g_source_destroy (impl->edited_idle); -+ impl->edited_idle = NULL; - +- - if (!gtk_tree_model_get_iter_first (GTK_TREE_MODEL (impl->shortcuts_model), &iter)) - goto out; -+ _gtk_file_system_model_remove_editable (impl->browse_files_model); -+ g_object_set (impl->list_name_renderer, "editable", FALSE, NULL); - +- - for (l = impl->reload_icon_handles; l; l = l->next) - { - GtkFileSystemHandle *handle = GTK_FILE_SYSTEM_HANDLE (l->data); @@ -1140,11 +1017,9 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - } - g_slist_free (impl->reload_icon_handles); - impl->reload_icon_handles = NULL; -+ gtk_widget_set_sensitive (impl->browse_new_folder_button, TRUE); - +- - do -+ if (impl->edited_new_text) /* not cancelled? */ - { +- { - gpointer data; - ShortcutType shortcut_type; - gboolean pixbuf_visible; @@ -1155,38 +1030,17 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - SHORTCUTS_COL_TYPE, &shortcut_type, - SHORTCUTS_COL_PIXBUF_VISIBLE, &pixbuf_visible, - -1); -+ GError *error; -+ GtkFilePath *file_path; - +- - pixbuf = NULL; - if (pixbuf_visible) - { - if (shortcut_type == SHORTCUT_TYPE_VOLUME) - { - GtkFileSystemVolume *volume; -+ error = NULL; -+ file_path = gtk_file_system_make_path (impl->file_system, -+ impl->current_folder, -+ impl->edited_new_text, -+ &error); -+ if (file_path) -+ { -+ GtkFileSystemHandle *handle; - +- - volume = data; - pixbuf = gtk_file_system_volume_render_icon (impl->file_system, volume, GTK_WIDGET (impl), - impl->icon_size, NULL); -- -- gtk_list_store_set (impl->shortcuts_model, &iter, -- SHORTCUTS_COL_PIXBUF, pixbuf, -- -1); -+ handle = gtk_file_system_create_folder (impl->file_system, file_path, -+ edited_idle_create_folder_cb, -+ g_object_ref (impl)); -+ impl->pending_handles = g_slist_append (impl->pending_handles, handle); - -- if (pixbuf) -- g_object_unref (pixbuf); - } - else if (shortcut_type == SHORTCUT_TYPE_PATH) - { @@ -1223,13 +1077,6 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (GTK_WIDGET (impl))); - pixbuf = gtk_icon_theme_load_icon (icon_theme, "gnome-fs-share", - impl->icon_size, 0, NULL); -- -- gtk_list_store_set (impl->shortcuts_model, &iter, -- SHORTCUTS_COL_PIXBUF, pixbuf, -- -1); -- -- if (pixbuf) -- g_object_unref (pixbuf); - } - } - else if (shortcut_type == SHORTCUT_TYPE_SEARCH) @@ -1240,87 +1087,59 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - { - pixbuf = render_recent_icon (impl); - } -+ gtk_file_path_free (file_path); - } -+ else -+ error_creating_folder_dialog (impl, file_path, error); -+ -+ g_free (impl->edited_new_text); -+ impl->edited_new_text = NULL; - } +- +- gtk_list_store_set (impl->shortcuts_model, &iter, +- SHORTCUTS_COL_PIXBUF, pixbuf, +- -1); +- +- if (pixbuf) +- g_object_unref (pixbuf); +- +- } +- } - while (gtk_tree_model_iter_next (GTK_TREE_MODEL (impl->shortcuts_model),&iter)); - +- - out: -+ GDK_THREADS_LEAVE (); - +- - profile_end ("end", NULL); -+ return FALSE; - } - +-} +- -static void -shortcuts_find_folder (GtkFileChooserDefault *impl, - GtkFilePath *folder) -+static void -+queue_edited_idle (GtkFileChooserDefault *impl, -+ const gchar *new_text) - { +-{ - GtkTreeSelection *selection; - int pos; - GtkTreePath *path; - - selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_shortcuts_tree_view)); -+ /* We create the folder in an idle handler so that we don't modify the tree -+ * just now. -+ */ - +- - g_assert (folder != NULL); - pos = shortcut_find_position (impl, folder); - if (pos == -1) -+ if (!impl->edited_idle) - { +- { - gtk_tree_selection_unselect_all (selection); - return; -+ impl->edited_idle = g_idle_source_new (); -+ g_source_set_closure (impl->edited_idle, -+ g_cclosure_new_object (G_CALLBACK (edited_idle_cb), -+ G_OBJECT (impl))); -+ g_source_attach (impl->edited_idle, NULL); - } - +- } +- - path = gtk_tree_path_new_from_indices (pos, -1); - gtk_tree_selection_select_path (selection, path); - gtk_tree_path_free (path); -+ g_free (impl->edited_new_text); -+ impl->edited_new_text = g_strdup (new_text); - } - +-} +- -/* If a shortcut corresponds to the current folder, selects it */ -+/* Callback used from the text cell renderer when the new folder is named */ - static void +-static void -shortcuts_find_current_folder (GtkFileChooserDefault *impl) -+renderer_edited_cb (GtkCellRendererText *cell_renderer_text, -+ const gchar *path, -+ const gchar *new_text, -+ GtkFileChooserDefault *impl) - { +-{ - shortcuts_find_folder (impl, impl->current_folder); -+ /* work around bug #154921 */ -+ g_object_set (cell_renderer_text, -+ "mode", GTK_CELL_RENDERER_MODE_INERT, NULL); -+ queue_edited_idle (impl, new_text); - } - +-} +- -/* Removes the specified number of rows from the shortcuts list */ -+/* Callback used from the text cell renderer when the new folder edition gets -+ * canceled. -+ */ - static void +-static void -shortcuts_remove_rows (GtkFileChooserDefault *impl, - int start_row, - int n_rows) -+renderer_editing_canceled_cb (GtkCellRendererText *cell_renderer_text, -+ GtkFileChooserDefault *impl) - { +-{ - GtkTreePath *path; - - path = gtk_tree_path_new_from_indices (start_row, -1); @@ -1331,27 +1150,14 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - - if (!gtk_tree_model_get_iter (GTK_TREE_MODEL (impl->shortcuts_model), &iter, path)) - g_assert_not_reached (); -+ /* work around bug #154921 */ -+ g_object_set (cell_renderer_text, -+ "mode", GTK_CELL_RENDERER_MODE_INERT, NULL); -+ queue_edited_idle (impl, NULL); -+} - +- - shortcuts_free_row_data (impl, &iter); - gtk_list_store_remove (impl->shortcuts_model, &iter); - } -+/* Creates the widgets for the filter combo box */ -+static GtkWidget * -+filter_create (GtkFileChooserDefault *impl) -+{ -+ impl->filter_combo = gtk_combo_box_new_text (); -+ gtk_combo_box_set_focus_on_click (GTK_COMBO_BOX (impl->filter_combo), FALSE); - +- - gtk_tree_path_free (path); -} -+ g_signal_connect (impl->filter_combo, "changed", -+ G_CALLBACK (filter_combo_changed), impl); - +- -static void -shortcuts_update_count (GtkFileChooserDefault *impl, - ShortcutsIndex type, @@ -1396,13 +1202,11 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - /* nothing */ - break; - } -+ return impl->filter_combo; - } - +-} +- -struct ShortcutsInsertRequest -{ -+struct selection_check_closure { - GtkFileChooserDefault *impl; +- GtkFileChooserDefault *impl; - GtkFilePath *parent_path; - GtkFilePath *path; - int pos; @@ -1411,22 +1215,14 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - ShortcutsIndex type; - gboolean name_only; - gboolean removable; -+ int num_selected; -+ gboolean all_files; -+ gboolean all_folders; - }; - -+/* Used from gtk_tree_selection_selected_foreach() */ - static void +-}; +- +-static void -get_file_info_finished (GtkFileSystemHandle *handle, - const GtkFileInfo *info, - const GError *error, - gpointer data) -+selection_check_foreach_cb (GtkTreeModel *model, -+ GtkTreePath *path, -+ GtkTreeIter *iter, -+ gpointer data) - { +-{ - gint pos = -1; - gboolean cancelled = handle->cancelled; - GdkPixbuf *pixbuf; @@ -1451,37 +1247,25 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - -1); - if (handle != model_handle) - goto out; -+ struct selection_check_closure *closure; -+ GtkTreeIter child_iter; -+ const GtkFileInfo *info; -+ gboolean is_folder; - +- - /* set the handle to NULL in the model (we unref later on) */ - gtk_list_store_set (request->impl->shortcuts_model, &iter, - SHORTCUTS_COL_HANDLE, NULL, - -1); -+ closure = data; -+ closure->num_selected++; - +- - if (cancelled) - goto out; -+ gtk_tree_model_sort_convert_iter_to_child_iter (closure->impl->sort_model, &child_iter, iter); - +- - if (!info) - { - gtk_list_store_remove (request->impl->shortcuts_model, &iter); - shortcuts_update_count (request->impl, request->type, -1); -+ info = _gtk_file_system_model_get_info (closure->impl->browse_files_model, &child_iter); -+ is_folder = info ? gtk_file_info_get_is_folder (info) : FALSE; - +- - if (request->type == SHORTCUTS_HOME) - { - const char *home = g_get_home_dir (); - GtkFilePath *home_path; -+ closure->all_folders = closure->all_folders && is_folder; -+ closure->all_files = closure->all_files && !is_folder; -+} - +- - home_path = gtk_file_system_filename_to_path (request->impl->file_system, home); - error_getting_info_dialog (request->impl, home_path, g_error_copy (error)); - gtk_file_path_free (home_path); @@ -1492,16 +1276,7 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - gint separator_pos = shortcuts_get_index (request->impl, SHORTCUTS_CURRENT_FOLDER_SEPARATOR); - shortcuts_remove_rows (request->impl, separator_pos, 1); - } -+/* Checks whether the selected items in the file list are all files or all folders */ -+static void -+selection_check (GtkFileChooserDefault *impl, -+ gint *num_selected, -+ gboolean *all_files, -+ gboolean *all_folders) -+{ -+ struct selection_check_closure closure; -+ GtkTreeSelection *selection; - +- - goto out; - } - @@ -1537,30 +1312,19 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - - if (request->impl->has_search) - pos -= 1; -+ closure.impl = impl; -+ closure.num_selected = 0; -+ closure.all_files = TRUE; -+ closure.all_folders = TRUE; - +- - if (request->impl->has_recent) - pos -= 2; -+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_files_tree_view)); -+ gtk_tree_selection_selected_foreach (selection, -+ selection_check_foreach_cb, -+ &closure); - +- - gtk_combo_box_set_active (GTK_COMBO_BOX (request->impl->save_folder_combo), pos); - g_signal_handlers_unblock_by_func (request->impl->save_folder_combo, - G_CALLBACK (save_folder_combo_changed_cb), - request->impl); - } -+ g_assert (closure.num_selected == 0 || !(closure.all_files && closure.all_folders)); - +- - if (pixbuf) - g_object_unref (pixbuf); -+ if (num_selected) -+ *num_selected = closure.num_selected; - +- -out: - g_object_unref (request->impl); - gtk_file_path_free (request->parent_path); @@ -1568,86 +1332,57 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - gtk_tree_row_reference_free (request->row_ref); - g_free (request->label_copy); - g_free (request); -+ if (all_files) -+ *all_files = closure.all_files; - +- - g_object_unref (handle); -+ if (all_folders) -+ *all_folders = closure.all_folders; - } - --/* FIXME: GtkFileSystem needs a function to split a remote path +-} +- + /* FIXME: GtkFileSystem needs a function to split a remote path - * into hostname and path components, or maybe just have a -- * gtk_file_system_path_get_display_name(). -- * -- * This function is also used in gtkfilechooserbutton.c -+struct get_selected_path_closure { -+ GtkFileChooserDefault *impl; -+ const GtkFilePath *path; -+}; -+ -+/* Handles key press events on the file list, so that we can trap Enter to -+ * activate the default button on our own. Also, checks to see if '/' has been -+ * pressed. See comment by tree_view_keybinding_cb() for more details. - */ --gchar * --_gtk_file_chooser_label_for_uri (const gchar *uri) -+static gboolean -+trap_activate_cb (GtkWidget *widget, -+ GdkEventKey *event, -+ gpointer data) ++ * into hostname and path components, or maybe just have a + * gtk_file_system_path_get_display_name(). + * + * This function is also used in gtkfilechooserbutton.c +@@ -1692,11 +887,11 @@ { -- const gchar *path, *start, *end, *p; -- gchar *host, *label; + const gchar *path, *start, *end, *p; + gchar *host, *label; - -- start = strstr (uri, "://"); -- start += 3; -- path = strchr (start, '/'); ++ + start = strstr (uri, "://"); + start += 3; + path = strchr (start, '/'); - -- if (path) -- end = path; -- else -- { -- end = uri + strlen (uri); -- path = "/"; -- } -+ GtkFileChooserDefault *impl; -+ int modifiers; - -- /* strip username */ -- p = strchr (start, '@'); -- if (p && p < end) -- { -- start = p + 1; -- } ++ + if (path) + end = path; + else +@@ -1711,719 +906,25 @@ + { + start = p + 1; + } - -- p = strchr (start, ':'); -- if (p && p < end) -- end = p; ++ + p = strchr (start, ':'); + if (p && p < end) + end = p; - -- host = g_strndup (start, end - start); -+ impl = (GtkFileChooserDefault *) data; ++ + host = g_strndup (start, end - start); - /* Translators: the first string is a path and the second string - * is a hostname. Nautilus and the panel contain the same string - * to translate. -- */ -- label = g_strdup_printf (_("%1$s on %2$s"), path, host); ++ /* Translators: the first string is a path and the second string ++ * is a hostname. Nautilus and the panel contain the same string ++ * to translate. + */ + label = g_strdup_printf (_("%1$s on %2$s"), path, host); - -- g_free (host); -+ modifiers = gtk_accelerator_get_default_mod_mask (); - -- return label; --} -+ if ((event->keyval == GDK_Return -+ || event->keyval == GDK_ISO_Enter -+ || event->keyval == GDK_KP_Enter -+ || event->keyval == GDK_space) -+ && ((event->state & modifiers) == 0) -+ && !(impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER || -+ impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)) -+ { -+ GtkWindow *window; ++ + g_free (host); + + return label; + } -/* Inserts a path in the shortcuts tree, making a copy of it; alternatively, - * inserts a volume. A position of -1 indicates the end of the tree. @@ -1667,40 +1402,17 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - gpointer data = NULL; - GtkTreeIter iter; - GtkIconTheme *icon_theme; -+ window = get_toplevel (widget); -+ if (window -+ && widget != window->default_widget -+ && !(widget == window->focus_widget && -+ (!window->default_widget || !GTK_WIDGET_SENSITIVE (window->default_widget)))) -+ { -+ gtk_window_activate_default (window); -+ return TRUE; -+ } -+ } -+ -+ return FALSE; -+} - profile_start ("start", (shortcut_type == SHORTCUT_TYPE_VOLUME) ? "volume" - : ((shortcut_type == SHORTCUT_TYPE_PATH) ? (char *) path : NULL)); -+static gboolean -+list_button_press (GtkWidget *widget, GdkEventButton *event, gpointer data) -+{ -+ GtkTreeView * tree = GTK_TREE_VIEW (widget); -+ GtkFileChooserDefault *impl = data; -+ GtkTreePath *path; - +- - if (shortcut_type == SHORTCUT_TYPE_VOLUME) -+ if (event->type != GDK_BUTTON_PRESS || -+ !gtk_tree_view_get_path_at_pos (tree, (gint)event->x, (gint)event->y, -+ &path, NULL, NULL, NULL)) - { +- { - data = volume; - label_copy = gtk_file_system_volume_get_display_name (impl->file_system, volume); - pixbuf = gtk_file_system_volume_render_icon (impl->file_system, volume, GTK_WIDGET (impl), - impl->icon_size, NULL); -+ return FALSE; - } +- } - else if (shortcut_type == SHORTCUT_TYPE_PATH) - { - if (gtk_file_system_path_is_local (impl->file_system, path)) @@ -1737,7 +1449,7 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - SHORTCUTS_COL_TYPE, SHORTCUT_TYPE_PATH, - SHORTCUTS_COL_HANDLE, handle, - -1); - +- - shortcuts_update_count (impl, type, 1); - - return; @@ -1753,22 +1465,11 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - else - { - gchar *uri; -+ impl->list_press_time = event->time; -+ impl->list_press_path = path; - +- - uri = gtk_file_system_path_to_uri (impl->file_system, path); -+ return FALSE; -+} - +- - label_copy = _gtk_file_chooser_label_for_uri (uri); -+static gboolean -+list_button_release (GtkWidget *widget, GdkEventButton *event, gpointer data) -+{ -+ GtkTreeView * tree = GTK_TREE_VIEW (widget); -+ GtkFileChooserDefault *impl = data; -+ GtkTreePath *path = NULL; -+ gboolean retval = FALSE; - +- - g_free (uri); - } - @@ -1781,35 +1482,19 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - } - } - else -+ if (!impl->list_press_time || -+ !impl->list_press_path || -+ event->type != GDK_BUTTON_RELEASE || -+ !gtk_tree_view_get_path_at_pos (tree, (gint)event->x, (gint)event->y, -+ &path, NULL, NULL, NULL)) - { +- { - g_assert_not_reached (); -+ goto done; -+ } - +- - return; -+ if (event->time - impl->list_press_time > LONG_CLICK_LENGTH && -+ !gtk_tree_path_compare (impl->list_press_path, path)) -+ { -+ retval = TRUE; -+ list_row_activated (tree, path, NULL, impl); - } - +- } +- - if (pos == -1) - gtk_list_store_append (impl->shortcuts_model, &iter); - else - gtk_list_store_insert (impl->shortcuts_model, &iter, pos); -+ done: -+ if (path) -+ gtk_tree_path_free (path); - +- - shortcuts_update_count (impl, type, 1); -+ impl->list_press_time = 0; - +- - gtk_list_store_set (impl->shortcuts_model, &iter, - SHORTCUTS_COL_PIXBUF, pixbuf, - SHORTCUTS_COL_PIXBUF_VISIBLE, TRUE, @@ -1833,17 +1518,10 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - * again. - */ - gint combo_pos = shortcuts_get_index (impl, SHORTCUTS_CURRENT_FOLDER); -+ if (impl->list_press_path) -+ { -+ gtk_tree_path_free (impl->list_press_path); -+ impl->list_press_path = NULL; -+ } - +- - if (impl->has_search) - combo_pos -= 1; -+ return FALSE; -+} - +- - if (impl->has_recent) - combo_pos -= 2; - @@ -1856,44 +1534,23 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - G_CALLBACK (save_folder_combo_changed_cb), - impl); - } - +- - g_free (label_copy); -+/* Creates the widgets for the file list */ -+static GtkWidget * -+create_file_list (GtkFileChooserDefault *impl) -+{ -+ GtkWidget *swin; -+ GtkTreeSelection *selection; -+ GtkTreeViewColumn *column; -+ GtkCellRenderer *renderer; - +- - if (pixbuf) - g_object_unref (pixbuf); -+ /* Scrolled window */ - +- - profile_end ("end", NULL); -} -+ swin = gtk_scrolled_window_new (NULL, NULL); -+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (swin), -+ GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); -+ gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (swin), -+ GTK_SHADOW_IN); - +- -static void -shortcuts_append_search (GtkFileChooserDefault *impl) -{ - GdkPixbuf *pixbuf; - GtkTreeIter iter; -+ /* Tree/list view */ - +- - pixbuf = render_search_icon (impl); -+ impl->browse_files_tree_view = gtk_tree_view_new (); -+#ifdef PROFILE_FILE_CHOOSER -+ g_object_set_data (G_OBJECT (impl->browse_files_tree_view), "fmq-name", "file_list"); -+#endif -+ g_object_set_data (G_OBJECT (impl->browse_files_tree_view), I_("GtkFileChooserDefault"), impl); -+ atk_object_set_name (gtk_widget_get_accessible (impl->browse_files_tree_view), _("Files")); - +- - gtk_list_store_append (impl->shortcuts_model, &iter); - gtk_list_store_set (impl->shortcuts_model, &iter, - SHORTCUTS_COL_PIXBUF, pixbuf, @@ -1903,38 +1560,21 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - SHORTCUTS_COL_TYPE, SHORTCUT_TYPE_SEARCH, - SHORTCUTS_COL_REMOVABLE, FALSE, - -1); -+ gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (impl->browse_files_tree_view), TRUE); -+ gtk_container_add (GTK_CONTAINER (swin), impl->browse_files_tree_view); - +- - if (pixbuf) - g_object_unref (pixbuf); -+ g_signal_connect (impl->browse_files_tree_view, "row_activated", -+ G_CALLBACK (list_row_activated), impl); -+ g_signal_connect (impl->browse_files_tree_view, "key_press_event", -+ G_CALLBACK (trap_activate_cb), impl); -+ g_signal_connect (impl->browse_files_tree_view, "button_press_event", -+ G_CALLBACK (list_button_press), impl); -+ g_signal_connect (impl->browse_files_tree_view, "button_release_event", -+ G_CALLBACK (list_button_release), impl); - +- - impl->has_search = TRUE; -} -+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_files_tree_view)); -+ gtk_tree_selection_set_select_function (selection, -+ list_select_func, -+ impl, NULL); - +- -static void -shortcuts_append_recent (GtkFileChooserDefault *impl) -{ - GdkPixbuf *pixbuf; - GtkTreeIter iter; -+ g_signal_connect (selection, "changed", -+ G_CALLBACK (list_selection_changed), impl); - +- - pixbuf = render_recent_icon (impl); -+ /* Filename column */ - +- - gtk_list_store_append (impl->shortcuts_model, &iter); - gtk_list_store_set (impl->shortcuts_model, &iter, - SHORTCUTS_COL_PIXBUF, pixbuf, @@ -1947,85 +1587,40 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - - if (pixbuf) - g_object_unref (pixbuf); -+ impl->list_name_column = gtk_tree_view_column_new (); -+ gtk_tree_view_column_set_expand (impl->list_name_column, TRUE); -+ gtk_tree_view_column_set_resizable (impl->list_name_column, TRUE); -+ gtk_tree_view_column_set_title (impl->list_name_column, _("Name")); -+ gtk_tree_view_column_set_sort_column_id (impl->list_name_column, FILE_LIST_COL_NAME); - +- - impl->has_recent = TRUE; -} -+ renderer = gtk_cell_renderer_pixbuf_new (); -+ gtk_tree_view_column_pack_start (impl->list_name_column, renderer, FALSE); -+ gtk_tree_view_column_set_cell_data_func (impl->list_name_column, renderer, -+ list_icon_data_func, impl, NULL); - +- -/* Appends an item for the user's home directory to the shortcuts model */ -static void -shortcuts_append_home (GtkFileChooserDefault *impl) -{ - const char *home; - GtkFilePath *home_path; -+ impl->list_name_renderer = gtk_cell_renderer_text_new (); -+ g_object_set (impl->list_name_renderer, -+ "ellipsize", PANGO_ELLIPSIZE_END, -+ NULL); -+ g_signal_connect (impl->list_name_renderer, "edited", -+ G_CALLBACK (renderer_edited_cb), impl); -+ g_signal_connect (impl->list_name_renderer, "editing_canceled", -+ G_CALLBACK (renderer_editing_canceled_cb), impl); -+ gtk_tree_view_column_pack_start (impl->list_name_column, impl->list_name_renderer, TRUE); -+ gtk_tree_view_column_set_cell_data_func (impl->list_name_column, impl->list_name_renderer, -+ list_name_data_func, impl, NULL); - +- - profile_start ("start", NULL); -+ gtk_tree_view_append_column (GTK_TREE_VIEW (impl->browse_files_tree_view), impl->list_name_column); -+#if 0 -+ /* Size column */ - +- - home = g_get_home_dir (); - if (home == NULL) - { - profile_end ("end - no home directory!?", NULL); - return; - } -+ column = gtk_tree_view_column_new (); -+ gtk_tree_view_column_set_title (column, _("Size")); - +- - home_path = gtk_file_system_filename_to_path (impl->file_system, home); -+ renderer = gtk_cell_renderer_text_new (); -+ gtk_tree_view_column_pack_start (column, renderer, TRUE); /* bug: it doesn't expand */ -+ gtk_tree_view_column_set_cell_data_func (column, renderer, -+ list_size_data_func, impl, NULL); -+ gtk_tree_view_column_set_sort_column_id (column, FILE_LIST_COL_SIZE); -+ gtk_tree_view_append_column (GTK_TREE_VIEW (impl->browse_files_tree_view), column); -+#endif -+ /* Modification time column */ - +- - shortcuts_insert_path (impl, -1, SHORTCUT_TYPE_PATH, NULL, home_path, NULL, FALSE, SHORTCUTS_HOME); - impl->has_home = TRUE; -+ column = gtk_tree_view_column_new (); -+ gtk_tree_view_column_set_resizable (column, TRUE); -+ gtk_tree_view_column_set_title (column, _("Modified")); - +- - gtk_file_path_free (home_path); -+ renderer = gtk_cell_renderer_text_new (); -+ gtk_tree_view_column_pack_start (column, renderer, TRUE); -+ gtk_tree_view_column_set_cell_data_func (column, renderer, -+ list_mtime_data_func, impl, NULL); -+ gtk_tree_view_column_set_sort_column_id (column, FILE_LIST_COL_MTIME); -+ gtk_tree_view_append_column (GTK_TREE_VIEW (impl->browse_files_tree_view), column); -+ gtk_widget_show_all (swin); - +- - profile_end ("end", NULL); -+ return swin; - } - +-} +- -/* Appends the ~/Desktop directory to the shortcuts model */ - static void +-static void -shortcuts_append_desktop (GtkFileChooserDefault *impl) -+up_button_clicked_cb (GtkButton *button, gpointer data) - { +-{ - const char *name; - GtkFilePath *path; - @@ -2039,21 +1634,12 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - /* We do not actually pop up an error dialog if there is no desktop directory - * because some people may really not want to have one. - */ -+ GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (data); -+ up_folder_handler (impl); -+} - +- - gtk_file_path_free (path); -+static void -+volume_button_clicked_cb (GtkButton *button, gpointer data) -+{ -+ GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (data); -+ GtkFilePath * path = g_object_get_data (G_OBJECT (button), "file-path"); - +- - profile_end ("end", NULL); -+ change_folder_and_display_error (impl, path); - } - +-} +- -/* Appends a list of GtkFilePath to the shortcuts model; returns how many were inserted */ -static int -shortcuts_append_paths (GtkFileChooserDefault *impl, @@ -2062,216 +1648,85 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - int start_row; - int num_inserted; - gchar *label; -+static GtkWidget * -+create_bar (GtkFileChooserDefault *impl) -+{ -+ GSList *list, *l; -+ int n; -+ GtkWidget *bar = gtk_hbox_new (FALSE, DEFAULT_SPACING); -+ GtkWidget *img; -+ GtkWidget *label; -+ -+ /* first the Up button */ -+ img = gtk_image_new_from_stock (GTK_STOCK_GO_UP, GTK_ICON_SIZE_BUTTON); -+ gtk_widget_show (img); -+ -+ impl->up_button = gtk_button_new (); -+ gtk_container_add (GTK_CONTAINER (impl->up_button), img); -+ gtk_widget_show (impl->up_button); -+ gtk_widget_set_sensitive (impl->up_button, FALSE); -+ gtk_button_set_focus_on_click (GTK_BUTTON (impl->up_button), FALSE); -+ -+ g_signal_connect (impl->up_button, "clicked", -+ G_CALLBACK (up_button_clicked_cb), impl); -+ gtk_box_pack_start (GTK_BOX(bar), impl->up_button, FALSE, FALSE, 0); - +- - profile_start ("start", NULL); -+ impl->num_volumes = 0; -+ list = gtk_file_system_list_volumes (impl->file_system); - +- - /* As there is no separator now, we want to start there. - */ - start_row = shortcuts_get_index (impl, SHORTCUTS_BOOKMARKS_SEPARATOR); - num_inserted = 0; -+ n = 0; - +- - for (; paths; paths = paths->next) -+ for (l = list; l; l = l->next, n++) - { +- { - GtkFilePath *path; - - path = paths->data; -+ GtkFileSystemVolume *volume; -+ GdkPixbuf *pixbuf; -+ GtkWidget *button; -+ GtkWidget *image; -+ GtkFilePath *base_path; -+ gchar * file_name = NULL; - +- - if (impl->local_only && - !gtk_file_system_path_is_local (impl->file_system, path)) - continue; -+ volume = l->data; -+ base_path = -+ gtk_file_system_volume_get_base_path (impl->file_system, volume); - +- - label = gtk_file_system_get_bookmark_label (impl->file_system, path); -+ if (impl->local_only) -+ { -+ gboolean is_local = -+ gtk_file_system_path_is_local (impl->file_system, base_path); - +- - /* NULL GError, but we don't really want to show error boxes here */ - shortcuts_insert_path (impl, start_row + num_inserted, SHORTCUT_TYPE_PATH, NULL, path, label, TRUE, SHORTCUTS_BOOKMARKS); - num_inserted++; -+ if (!is_local) -+ { -+ gtk_file_path_free (base_path); -+ gtk_file_system_volume_free (impl->file_system, volume); -+ continue; -+ } -+ } - +- - g_free (label); - } -+#if 0 -+ label_copy = -+ gtk_file_system_volume_get_display_name (impl->file_system, volume); -+#endif -+ pixbuf = -+ gtk_file_system_volume_render_icon (impl->file_system, volume, -+ GTK_WIDGET (impl), -+ impl->icon_size, NULL); -+ -+ button = gtk_button_new (); -+ image = gtk_image_new_from_pixbuf (pixbuf); -+ g_object_unref (G_OBJECT (pixbuf)); -+ gtk_container_add (GTK_CONTAINER (button), image); -+ gtk_button_set_focus_on_click (GTK_BUTTON (button), FALSE); -+ -+ file_name = -+ gtk_file_system_path_to_filename (impl->file_system, base_path); -+ -+ if (file_name && impl->root_folder && -+ strcmp (file_name, impl->root_folder) && -+ !strncmp (file_name, impl->root_folder, strlen (file_name))) -+ { -+ /* The base path is below the root folder; we replace it with -+ * the root folder -+ */ -+ gtk_file_path_free (base_path); -+ base_path = gtk_file_system_filename_to_path (impl->file_system, -+ impl->root_folder); -+ } - +- - profile_end ("end", NULL); -+ g_free (file_name); -+ gtk_widget_show_all (button); - +- - return num_inserted; -} -+ g_object_set_data (G_OBJECT (button), "file-path", base_path); - +- -/* Returns the index for the corresponding item in the shortcuts bar */ -static int -shortcuts_get_index (GtkFileChooserDefault *impl, - ShortcutsIndex where) -{ - int n; -+ g_signal_connect (button, "clicked", -+ G_CALLBACK (volume_button_clicked_cb), impl); - +- - n = 0; - - if (where == SHORTCUTS_SEARCH) - goto out; -+ gtk_box_pack_start (GTK_BOX(bar), button, FALSE, FALSE, 0); -+ } - +- - n += impl->has_search ? 1 : 0; -+ impl->num_volumes = n; -+ g_slist_free (list); - +- - if (where == SHORTCUTS_RECENT) - goto out; -+ label = impl->location_label = gtk_label_new (NULL); -+ gtk_label_set_ellipsize (GTK_LABEL (label), PANGO_ELLIPSIZE_START); -+ gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5); -+ gtk_label_set_text (GTK_LABEL (label), impl->root_folder); -+ gtk_widget_show (label); -+ gtk_box_pack_start (GTK_BOX(bar), label, TRUE, TRUE, 0); - +- - n += impl->has_recent ? 1 : 0; -+ gtk_widget_show (bar); - +- - if (where == SHORTCUTS_RECENT_SEPARATOR) - goto out; -+ return bar; -+} - +- - n += impl->has_recent ? 1 : 0; -+/* Creates the widgets for the files/folders pane */ -+static GtkWidget * -+file_pane_create (GtkFileChooserDefault *impl) -+{ -+ GtkWidget *vbox; -+ GtkWidget *hbox; -+ GtkWidget *widget; -+ vbox = gtk_vbox_new (FALSE, DEFAULT_SPACING); -+ gtk_widget_show (vbox); - +- - if (where == SHORTCUTS_HOME) - goto out; -+ /* The volume bar and 'Create Folder' button */ -+ hbox = gtk_hbox_new (FALSE, DEFAULT_SPACING); -+ gtk_widget_show (hbox); -+ impl->bar = create_bar (impl); -+ gtk_widget_show_all (impl->bar); -+ gtk_box_pack_start (GTK_BOX (hbox), impl->bar, TRUE, TRUE, 0); - +- - n += impl->has_home ? 1 : 0; -+ /* Create Folder */ -+ widget = gtk_image_new_from_icon_name ("folder-new", GTK_ICON_SIZE_BUTTON); -+ gtk_widget_show (widget); -+ impl->browse_new_folder_button = gtk_button_new (); -+ gtk_container_add (GTK_CONTAINER (impl->browse_new_folder_button), widget); -+ gtk_button_set_focus_on_click (GTK_BUTTON (impl->browse_new_folder_button), -+ FALSE); - +- - if (where == SHORTCUTS_DESKTOP) - goto out; -+ g_signal_connect (impl->browse_new_folder_button, "clicked", -+ G_CALLBACK (new_folder_button_clicked), impl); -+ gtk_box_pack_end (GTK_BOX (hbox), impl->browse_new_folder_button, FALSE, FALSE, 0); - +- - n += impl->has_desktop ? 1 : 0; -+ widget = filter_create (impl); -+ gtk_widget_hide (widget); -+ gtk_box_pack_end (GTK_BOX (hbox), widget, FALSE, FALSE, 0); - +- - if (where == SHORTCUTS_VOLUMES) - goto out; -+ gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0); - +- - n += impl->num_volumes; -+ /* Box for lists */ -+ hbox = gtk_hbox_new (FALSE, LIST_HBOX_SPACING); -+ gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 0); -+ gtk_widget_show (hbox); - +- - if (where == SHORTCUTS_SHORTCUTS) - goto out; -+ /* File list */ - +- - n += impl->num_shortcuts; -+ widget = create_file_list (impl); -+ gtk_box_pack_start (GTK_BOX (hbox), widget, TRUE, TRUE, 0); - +- - if (where == SHORTCUTS_BOOKMARKS_SEPARATOR) - goto out; -+ return vbox; -+} - +- - /* If there are no bookmarks there won't be a separator */ - n += (impl->num_bookmarks > 0) ? 1 : 0; - @@ -2279,53 +1734,26 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - goto out; - - n += impl->num_bookmarks; -+/* Creates the widgets specific to Save mode */ -+static GtkWidget * -+save_widgets_create (GtkFileChooserDefault *impl) -+{ -+ GtkWidget *vbox; -+ GtkWidget *hbox; -+ GtkWidget *widget; - +- - if (where == SHORTCUTS_CURRENT_FOLDER_SEPARATOR) - goto out; -+ vbox = gtk_vbox_new (FALSE, 0); -+ hbox = gtk_hbox_new (FALSE, DEFAULT_SPACING); - +- - n += 1; -+ widget = gtk_label_new (_("Name:")); -+ gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5); -+ gtk_box_pack_start (GTK_BOX (hbox), widget, FALSE, FALSE, 0); -+ gtk_widget_show (widget); - +- - if (where == SHORTCUTS_CURRENT_FOLDER) - goto out; -+ impl->location_entry = _gtk_file_chooser_entry_new (TRUE); -+ _gtk_file_chooser_entry_set_file_system (GTK_FILE_CHOOSER_ENTRY (impl->location_entry), -+ impl->file_system); -+/* gtk_entry_set_width_chars (GTK_ENTRY (impl->location_entry), 45); */ -+ gtk_entry_set_activates_default (GTK_ENTRY (impl->location_entry), TRUE); -+ gtk_box_pack_start (GTK_BOX (hbox), impl->location_entry, -+ TRUE, TRUE, 0); - +- - g_assert_not_reached (); -+ gtk_widget_show (impl->location_entry); - +- - out: -+ gtk_widget_show (hbox); -+ gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0); - +- - return n; -+ return vbox; - } - +-} +- -/* Adds all the file system volumes to the shortcuts model */ -+/* Destroys the widgets specific to Save mode */ -+/* ??? */ - static void +-static void -shortcuts_add_volumes (GtkFileChooserDefault *impl) -+save_widgets_destroy (GtkFileChooserDefault *impl) - { +-{ - int start_row; - GSList *list, *l; - int n; @@ -2336,49 +1764,27 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - - old_changing_folders = impl->changing_folder; - impl->changing_folder = TRUE; -+ if (impl->save_widgets == NULL) -+ return; - +- - start_row = shortcuts_get_index (impl, SHORTCUTS_VOLUMES); - shortcuts_remove_rows (impl, start_row, impl->num_volumes); - impl->num_volumes = 0; -+ gtk_widget_destroy (impl->save_widgets); -+ impl->save_widgets = NULL; -+ impl->location_entry = NULL; -+} - +- - list = gtk_file_system_list_volumes (impl->file_system); -+/* Creates the main hpaned with the widgets shared by Open and Save mode */ -+static GtkWidget * -+browse_widgets_create (GtkFileChooserDefault *impl) -+{ -+ GtkWidget *widget; - +- - n = 0; -+ widget = file_pane_create (impl); - +- - for (l = list; l; l = l->next) - { - GtkFileSystemVolume *volume; -+ return widget; -+} - +- - volume = l->data; -+static GObject* -+gtk_file_chooser_default_constructor (GType type, -+ guint n_construct_properties, -+ GObjectConstructParam *construct_params) -+{ -+ GtkFileChooserDefault *impl; -+ GObject *object; - +- - if (impl->local_only) - { - if (gtk_file_system_volume_get_is_mounted (impl->file_system, volume)) - { - GtkFilePath *base_path; -+ profile_start ("start", NULL); - +- - base_path = gtk_file_system_volume_get_base_path (impl->file_system, volume); - if (base_path != NULL) - { @@ -2393,37 +1799,23 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - } - } - } -+ object = G_OBJECT_CLASS (_gtk_file_chooser_default_parent_class)->constructor (type, -+ n_construct_properties, -+ construct_params); -+ impl = GTK_FILE_CHOOSER_DEFAULT (object); - +- - shortcuts_insert_path (impl, start_row + n, SHORTCUT_TYPE_VOLUME, volume, NULL, NULL, FALSE, SHORTCUTS_VOLUMES); - n++; - } -+ g_assert (impl->file_system); - +- - impl->num_volumes = n; - g_slist_free (list); -+ gtk_widget_push_composite_child (); - +- - if (impl->shortcuts_pane_filter_model) - gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (impl->shortcuts_pane_filter_model)); -+ /* Widgets for Save mode */ -+ impl->save_widgets = save_widgets_create (impl); -+ gtk_box_pack_start (GTK_BOX (impl), impl->save_widgets, FALSE, FALSE, 0); - +- - if (impl->shortcuts_combo_filter_model) - gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (impl->shortcuts_combo_filter_model)); -+ /* The browse widgets */ -+ impl->browse_widgets = browse_widgets_create (impl); -+ gtk_box_pack_start (GTK_BOX (impl), impl->browse_widgets, TRUE, TRUE, 0); - +- - impl->changing_folder = old_changing_folders; -+ gtk_widget_pop_composite_child (); -+ update_appearance (impl); - - profile_end ("end", NULL); +- +- profile_end ("end", NULL); -} - -/* Inserts a separator node in the shortcuts list */ @@ -2432,7 +1824,7 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - ShortcutsIndex where) -{ - GtkTreeIter iter; - +- - g_assert (where == SHORTCUTS_RECENT_SEPARATOR || - where == SHORTCUTS_BOOKMARKS_SEPARATOR || - where == SHORTCUTS_CURRENT_FOLDER_SEPARATOR); @@ -2446,15 +1838,12 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - SHORTCUTS_COL_DATA, NULL, - SHORTCUTS_COL_TYPE, SHORTCUT_TYPE_SEPARATOR, - -1); -+ return object; - } - +-} +- -/* Updates the list of bookmarks */ - static void +-static void -shortcuts_add_bookmarks (GtkFileChooserDefault *impl) -+set_local_only (GtkFileChooserDefault *impl, -+ gboolean local_only) - { +-{ - GSList *bookmarks; - gboolean old_changing_folders; - GtkTreeIter iter; @@ -2462,24 +1851,12 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - GtkFilePath *combo_selected = NULL; - ShortcutType shortcut_type; - gpointer col_data; -+ if (local_only != impl->local_only) -+ { -+ impl->local_only = local_only; - +- - profile_start ("start", NULL); - - old_changing_folders = impl->changing_folder; - impl->changing_folder = TRUE; -+ if (local_only && -+ !gtk_file_system_path_is_local (impl->file_system, impl->current_folder)) -+ { -+ /* If we are pointing to a non-local folder, make an effort to change -+ * back to a local folder, but it's really up to the app to not cause -+ * such a situation, so we ignore errors. -+ */ -+ const gchar *home = g_get_home_dir (); -+ GtkFilePath *home_path; - +- - if (shortcuts_get_selected (impl, &iter)) - { - gtk_tree_model_get (GTK_TREE_MODEL (impl->shortcuts_model), @@ -2487,21 +1864,17 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - SHORTCUTS_COL_DATA, &col_data, - SHORTCUTS_COL_TYPE, &shortcut_type, - -1); -+ if (home == NULL) -+ return; - +- - if (col_data && shortcut_type == SHORTCUT_TYPE_PATH) - list_selected = gtk_file_path_copy (col_data); - } -+ home_path = gtk_file_system_filename_to_path (impl->file_system, home); - +- - if (impl->save_folder_combo && - gtk_combo_box_get_active_iter (GTK_COMBO_BOX (impl->save_folder_combo), - &iter)) - { - GtkTreeIter child_iter; -+ _gtk_file_chooser_set_current_folder_path (GTK_FILE_CHOOSER (impl), home_path, NULL); - +- - gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER (impl->shortcuts_combo_filter_model), - &child_iter, - &iter); @@ -2513,75 +1886,36 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - - if (col_data && shortcut_type == SHORTCUT_TYPE_PATH) - combo_selected = gtk_file_path_copy (col_data); -+ gtk_file_path_free (home_path); -+ } - } -+} - +- } +- - if (impl->num_bookmarks > 0) - shortcuts_remove_rows (impl, - shortcuts_get_index (impl, SHORTCUTS_BOOKMARKS_SEPARATOR), - impl->num_bookmarks + 1); -+static void -+volumes_changed_cb (GtkFileSystem *file_system, -+ GtkFileChooserDefault *impl) -+{ -+ /* FIXME -- update the bar */ -+} -+ -+/* Sets the file chooser to multiple selection mode */ -+static void -+set_select_multiple (GtkFileChooserDefault *impl, -+ gboolean select_multiple, -+ gboolean property_notify) -+{ -+ GtkTreeSelection *selection; -+ GtkSelectionMode mode; - +- - impl->num_bookmarks = 0; -+ if (select_multiple == impl->select_multiple) -+ return; - +- - bookmarks = gtk_file_system_list_bookmarks (impl->file_system); - shortcuts_append_paths (impl, bookmarks); - gtk_file_paths_free (bookmarks); -+ mode = select_multiple ? GTK_SELECTION_MULTIPLE : GTK_SELECTION_BROWSE; - +- - if (impl->num_bookmarks > 0) - shortcuts_insert_separator (impl, SHORTCUTS_BOOKMARKS_SEPARATOR); -+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_files_tree_view)); -+ gtk_tree_selection_set_mode (selection, mode); - +- - if (impl->shortcuts_pane_filter_model) - gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (impl->shortcuts_pane_filter_model)); -+ impl->select_multiple = select_multiple; -+ g_object_notify (G_OBJECT (impl), "select-multiple"); -+} - +- - if (impl->shortcuts_combo_filter_model) - gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (impl->shortcuts_combo_filter_model)); -+static void -+set_file_system_backend (GtkFileChooserDefault *impl, -+ const char *backend) -+{ -+ profile_start ("start for backend", backend ? backend : "default"); - +- - if (list_selected) -+ if (impl->file_system) - { +- { - shortcuts_find_folder (impl, list_selected); - gtk_file_path_free (list_selected); -+ g_signal_handler_disconnect (impl->file_system, impl->volumes_changed_id); -+ impl->volumes_changed_id = 0; -+ g_object_unref (impl->file_system); - } - +- } +- - if (combo_selected) -+ impl->file_system = NULL; -+ if (backend) -+ impl->file_system = gtk_file_system_create (backend); -+ else - { +- { - gint pos; - - pos = shortcut_find_position (impl, combo_selected); @@ -2589,50 +1923,25 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - { - if (impl->has_search) - pos -= 1; -+ GtkSettings *settings = gtk_settings_get_default (); -+ gchar *default_backend = NULL; - +- - if (impl->has_recent) - pos -= 2; -+ g_object_get (settings, "gtk-file-chooser-backend", &default_backend, NULL); -+ if (default_backend) -+ { -+ impl->file_system = gtk_file_system_create (default_backend); -+ g_free (default_backend); -+ } -+ } - +- - gtk_combo_box_set_active (GTK_COMBO_BOX (impl->save_folder_combo), pos); - } -+ if (!impl->file_system) -+ { -+#if defined (G_OS_UNIX) -+ impl->file_system = gtk_file_system_unix_new (); -+#elif defined (G_OS_WIN32) -+ impl->file_system = gtk_file_system_win32_new (); -+#else -+#error "No default filesystem implementation on the platform" -+#endif -+ } - +- - gtk_file_path_free (combo_selected); -+ if (impl->file_system) -+ { -+ impl->volumes_changed_id = g_signal_connect (impl->file_system, "volumes-changed", -+ G_CALLBACK (volumes_changed_cb), -+ impl); - } +- } - - impl->changing_folder = old_changing_folders; - - profile_end ("end", NULL); - } - +- +- profile_end ("end", NULL); +-} +- -/* Appends a separator and a row to the shortcuts list for the current folder */ - static void +-static void -shortcuts_add_current_folder (GtkFileChooserDefault *impl) -+show_new_folder_button (GtkFileChooserDefault *impl) - { +-{ - int pos; - gboolean success; - @@ -2644,10 +1953,7 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - - pos = shortcut_find_position (impl, impl->current_folder); - if (pos == -1) -+ if ((impl->action == GTK_FILE_CHOOSER_ACTION_SAVE || -+ impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER) && -+ impl->show_create_folder) - { +- { - GtkFileSystemVolume *volume; - GtkFilePath *base_path; - @@ -2679,12 +1985,9 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - - if (base_path) - gtk_file_path_free (base_path); -+ gtk_widget_show (impl->browse_new_folder_button); -+ gtk_misc_set_alignment (GTK_MISC (impl->location_label), 0.5, 0.5); - } +- } - else if (impl->save_folder_combo != NULL) -+ else - { +- { - if (impl->has_search) - pos -= 1; - @@ -2692,47 +1995,23 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - pos -= 2; /* + separator */ - - gtk_combo_box_set_active (GTK_COMBO_BOX (impl->save_folder_combo), pos); -+ gtk_widget_hide (impl->browse_new_folder_button); -+ gtk_misc_set_alignment (GTK_MISC (impl->location_label), 1.0, 0.5); - } - } - +- } +-} +- -/* Updates the current folder row in the shortcuts model */ -+/* This function is basically a do_all function. -+ * -+ * It sets the visibility on all the widgets based on the current state, and -+ * moves the custom_widget if needed. -+ */ - static void +-static void -shortcuts_update_current_folder (GtkFileChooserDefault *impl) -+update_appearance (GtkFileChooserDefault *impl) - { +-{ - int pos; - - pos = shortcuts_get_index (impl, SHORTCUTS_CURRENT_FOLDER_SEPARATOR); -+ if (impl->action == GTK_FILE_CHOOSER_ACTION_SAVE || -+ impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER) -+ { -+ gtk_widget_show (impl->save_widgets); -+ gtk_widget_show (impl->browse_widgets); - +- - if (impl->shortcuts_current_folder_active) -+ if (impl->select_multiple) -+ { -+ g_warning ("Save mode cannot be set in conjunction with multiple selection mode. " -+ "Re-setting to single selection mode."); -+ set_select_multiple (impl, FALSE, TRUE); -+ } -+ } -+ else if (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN || -+ impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER) - { +- { - shortcuts_remove_rows (impl, pos, 2); - impl->shortcuts_current_folder_active = FALSE; -+ gtk_widget_hide (impl->save_widgets); -+ gtk_widget_show (impl->browse_widgets); - } - +- } +- - shortcuts_add_current_folder (impl); -} - @@ -2751,18 +2030,15 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - path = gtk_tree_model_get_path (model, iter); - if (!path) - return FALSE; -+ show_new_folder_button (impl); - +- - pos = *gtk_tree_path_get_indices (path); - gtk_tree_path_free (path); -+ gtk_widget_queue_draw (impl->browse_files_tree_view); - +- - return (pos < shortcuts_get_index (impl, SHORTCUTS_CURRENT_FOLDER_SEPARATOR)); -+ g_signal_emit_by_name (impl, "default-size-changed"); - } - +-} +- -/* Creates the list model for shortcuts */ - static void +-static void -shortcuts_model_create (GtkFileChooserDefault *impl) -{ - /* Keep this order in sync with the SHORCUTS_COL_* enum values */ @@ -2774,18 +2050,12 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - G_TYPE_BOOLEAN, /* removable */ - G_TYPE_BOOLEAN, /* pixbuf cell visibility */ - G_TYPE_POINTER); /* GtkFileSystemHandle */ -+gtk_file_chooser_default_set_property (GObject *object, -+ guint prop_id, -+ const GValue *value, -+ GParamSpec *pspec) - +- - if (search_is_possible (impl)) - { - shortcuts_append_search (impl); - } -+{ -+ GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (object); - +- - if (impl->recent_manager) - { - shortcuts_append_recent (impl); @@ -2793,8 +2063,7 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - } - - if (impl->file_system) -+ switch (prop_id) - { +- { - shortcuts_append_home (impl); - shortcuts_append_desktop (impl); - shortcuts_add_volumes (impl); @@ -2809,279 +2078,66 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - impl, - NULL); -} -+ case GTK_FILE_CHOOSER_PROP_ACTION: -+ { -+ GtkFileChooserAction action = g_value_get_enum (value); - --/* Callback used when the "New Folder" button is clicked */ --static void --new_folder_button_clicked (GtkButton *button, -- GtkFileChooserDefault *impl) --{ -- GtkTreeIter iter; -- GtkTreePath *path; -- -- if (!impl->browse_files_model) -- return; /* FIXME: this sucks. Disable the New Folder button or something. */ -- -- /* Prevent button from being clicked twice */ -- gtk_widget_set_sensitive (impl->browse_new_folder_button, FALSE); -- -- _gtk_file_system_model_add_editable (impl->browse_files_model, &iter); -- -- path = gtk_tree_model_get_path (GTK_TREE_MODEL (impl->browse_files_model), &iter); -- gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (impl->browse_files_tree_view), -- path, impl->list_name_column, -- FALSE, 0.0, 0.0); -- -- g_object_set (impl->list_name_renderer, "editable", TRUE, NULL); -- gtk_tree_view_set_cursor (GTK_TREE_VIEW (impl->browse_files_tree_view), -- path, -- impl->list_name_column, -- TRUE); -- -- gtk_tree_path_free (path); --} - --static void --edited_idle_create_folder_cb (GtkFileSystemHandle *handle, -- const GtkFilePath *path, -- const GError *error, -- gpointer data) --{ -- gboolean cancelled = handle->cancelled; -- GtkFileChooserDefault *impl = data; -- -- if (!g_slist_find (impl->pending_handles, handle)) -- goto out; -- -- impl->pending_handles = g_slist_remove (impl->pending_handles, handle); -+ if (action != impl->action) -+ { -+ gtk_file_chooser_default_unselect_all (GTK_FILE_CHOOSER (impl)); -+ -+ if ((action == GTK_FILE_CHOOSER_ACTION_SAVE || action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER) -+ && impl->select_multiple) -+ { -+ g_warning ("Tried to change the file chooser action to SAVE or CREATE_FOLDER, but " -+ "this is not allowed in multiple selection mode. Resetting the file chooser " -+ "to single selection mode."); -+ set_select_multiple (impl, FALSE, TRUE); -+ } -+ impl->action = action; -+ update_appearance (impl); -+ settings_load (impl); -+ } -+ } -+ break; - -- if (cancelled) -- goto out; -+ case GTK_FILE_CHOOSER_PROP_FILE_SYSTEM_BACKEND: -+ set_file_system_backend (impl, g_value_get_string (value)); -+ break; + /* Callback used when the "New Folder" button is clicked */ + static void + new_folder_button_clicked (GtkButton *button, +@@ -2472,7 +973,7 @@ + goto out; -- if (!error) + if (!error) - change_folder_and_display_error (impl, path, FALSE); -- else -- error_creating_folder_dialog (impl, path, g_error_copy (error)); -+ case GTK_FILE_CHOOSER_PROP_FILTER: -+ set_current_filter (impl, g_value_get_object (value)); -+ break; - -- out: -- g_object_unref (impl); -- g_object_unref (handle); --} -+ case GTK_FILE_CHOOSER_PROP_LOCAL_ONLY: -+ set_local_only (impl, g_value_get_boolean (value)); -+ break; ++ change_folder_and_display_error (impl, path); + else + error_creating_folder_dialog (impl, path, g_error_copy (error)); --/* Idle handler for creating a new folder after editing its name cell, or for -- * canceling the editing. -- */ --static gboolean --edited_idle_cb (GtkFileChooserDefault *impl) --{ -- GDK_THREADS_ENTER (); +@@ -2488,7 +989,7 @@ + edited_idle_cb (GtkFileChooserDefault *impl) + { + GDK_THREADS_ENTER (); - -- g_source_destroy (impl->edited_idle); -- impl->edited_idle = NULL; -+ case GTK_FILE_CHOOSER_PROP_SELECT_MULTIPLE: -+ { -+ gboolean select_multiple = g_value_get_boolean (value); -+ if ((impl->action == GTK_FILE_CHOOSER_ACTION_SAVE || impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER) -+ && select_multiple) -+ { -+ g_warning ("Tried to set the file chooser to multiple selection mode, but this is " -+ "not allowed in SAVE or CREATE_FOLDER modes. Ignoring the change and " -+ "leaving the file chooser in single selection mode."); -+ return; -+ } - -- _gtk_file_system_model_remove_editable (impl->browse_files_model); -- g_object_set (impl->list_name_renderer, "editable", FALSE, NULL); -+ set_select_multiple (impl, select_multiple, FALSE); -+ } -+ break; - -- gtk_widget_set_sensitive (impl->browse_new_folder_button, TRUE); -+ case GTK_FILE_CHOOSER_PROP_SHOW_HIDDEN: -+ { -+ gboolean show_hidden = g_value_get_boolean (value); -+ if (show_hidden != impl->show_hidden) -+ { -+ impl->show_hidden = show_hidden; - -- if (impl->edited_new_text) /* not cancelled? */ -- { -- GError *error; -- GtkFilePath *file_path; -+ if (impl->browse_files_model) -+ _gtk_file_system_model_set_show_hidden (impl->browse_files_model, show_hidden); -+ } -+ } -+ break; - -- error = NULL; -- file_path = gtk_file_system_make_path (impl->file_system, -- impl->current_folder, -- impl->edited_new_text, -- &error); -- if (file_path) -- { -- GtkFileSystemHandle *handle; -+ case GTK_FILE_CHOOSER_PROP_DO_OVERWRITE_CONFIRMATION: -+ { -+ gboolean do_overwrite_confirmation = g_value_get_boolean (value); -+ impl->do_overwrite_confirmation = do_overwrite_confirmation; -+ } -+ break; - -- handle = gtk_file_system_create_folder (impl->file_system, file_path, -- edited_idle_create_folder_cb, -- g_object_ref (impl)); -- impl->pending_handles = g_slist_append (impl->pending_handles, handle); -+ case GTK_FILE_CHOOSER_PROP_ROOT_FOLDER: -+ { -+ GtkFilePath * path; -+ gchar * new_root = g_strdup (g_value_get_string (value)); - -- gtk_file_path_free (file_path); -- } -- else -- error_creating_folder_dialog (impl, file_path, error); -+ if (!new_root) -+ { -+ new_root = g_strdup ("/"); -+ } - -- g_free (impl->edited_new_text); -- impl->edited_new_text = NULL; -- } -+ path = gtk_file_system_filename_to_path (impl->file_system, -+ new_root); -+ if (change_folder (impl, path, FALSE)) -+ { -+ g_free (impl->root_folder); -+ impl->root_folder = new_root; -+ } -+ else -+ { -+ g_warning ("Unable to set [%s] as root folder", new_root); -+ g_free (new_root); -+ } - -- GDK_THREADS_LEAVE (); -+ gtk_file_path_free (path); -+ } -+ break; - -- return FALSE; --} -+ case GTK_FILE_CHOOSER_PROP_SHOW_CREATE_FOLDER: -+ { -+ gboolean show = g_value_get_boolean (value); -+ if (show != impl->show_create_folder) -+ { -+ impl->show_create_folder = show; -+ show_new_folder_button (impl); -+ } -+ } -+ break; - --static void --queue_edited_idle (GtkFileChooserDefault *impl, -- const gchar *new_text) --{ -- /* We create the folder in an idle handler so that we don't modify the tree -- * just now. -- */ -+ /* These are not supported */ -+ case GTK_FILE_CHOOSER_PROP_PREVIEW_WIDGET: -+ case GTK_FILE_CHOOSER_PROP_PREVIEW_WIDGET_ACTIVE: -+ case GTK_FILE_CHOOSER_PROP_USE_PREVIEW_LABEL: -+ case GTK_FILE_CHOOSER_PROP_EXTRA_WIDGET: -+ break; ++ + g_source_destroy (impl->edited_idle); + impl->edited_idle = NULL; -- if (!impl->edited_idle) -- { -- impl->edited_idle = g_idle_source_new (); -- g_source_set_closure (impl->edited_idle, -- g_cclosure_new_object (G_CALLBACK (edited_idle_cb), -- G_OBJECT (impl))); -- g_source_attach (impl->edited_idle, NULL); -+ default: -+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); -+ break; - } -- -- g_free (impl->edited_new_text); -- impl->edited_new_text = g_strdup (new_text); --} -- --/* Callback used from the text cell renderer when the new folder is named */ --static void --renderer_edited_cb (GtkCellRendererText *cell_renderer_text, -- const gchar *path, -- const gchar *new_text, -- GtkFileChooserDefault *impl) --{ +@@ -2558,10 +1059,10 @@ + const gchar *new_text, + GtkFileChooserDefault *impl) + { - /* work around bug #154921 */ - g_object_set (cell_renderer_text, -- "mode", GTK_CELL_RENDERER_MODE_INERT, NULL); ++ /* work around bug #154921 */ ++ g_object_set (cell_renderer_text, + "mode", GTK_CELL_RENDERER_MODE_INERT, NULL); - queue_edited_idle (impl, new_text); ++ queue_edited_idle (impl, new_text); } --/* Callback used from the text cell renderer when the new folder edition gets -- * canceled. -- */ - static void --renderer_editing_canceled_cb (GtkCellRendererText *cell_renderer_text, -- GtkFileChooserDefault *impl) --{ + /* Callback used from the text cell renderer when the new folder edition gets +@@ -2571,10 +1072,10 @@ + renderer_editing_canceled_cb (GtkCellRendererText *cell_renderer_text, + GtkFileChooserDefault *impl) + { - /* work around bug #154921 */ - g_object_set (cell_renderer_text, -- "mode", GTK_CELL_RENDERER_MODE_INERT, NULL); ++ /* work around bug #154921 */ ++ g_object_set (cell_renderer_text, + "mode", GTK_CELL_RENDERER_MODE_INERT, NULL); - queue_edited_idle (impl, NULL); --} -- --/* Creates the widgets for the filter combo box */ --static GtkWidget * --filter_create (GtkFileChooserDefault *impl) --{ -- impl->filter_combo = gtk_combo_box_new_text (); -- gtk_combo_box_set_focus_on_click (GTK_COMBO_BOX (impl->filter_combo), FALSE); -- -- g_signal_connect (impl->filter_combo, "changed", -- G_CALLBACK (filter_combo_changed), impl); -- ++ queue_edited_idle (impl, NULL); + } + + /* Creates the widgets for the filter combo box */ +@@ -2587,253 +1088,9 @@ + g_signal_connect (impl->filter_combo, "changed", + G_CALLBACK (filter_combo_changed), impl); + - gtk_widget_set_tooltip_text (impl->filter_combo, - _("Select which types of files are shown")); - -- return impl->filter_combo; --} -- + return impl->filter_combo; + } + -static GtkWidget * -button_new (GtkFileChooserDefault *impl, - const char *text, @@ -3110,11 +2166,7 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c -static int -shortcut_find_position (GtkFileChooserDefault *impl, - const GtkFilePath *path) -+gtk_file_chooser_default_get_property (GObject *object, -+ guint prop_id, -+ GValue *value, -+ GParamSpec *pspec) - { +-{ - GtkTreeIter iter; - int i; - int current_folder_separator_idx; @@ -3129,11 +2181,9 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - if (current_folder_separator_idx >= impl->shortcuts_model->length) - return -1; -#endif -+ GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (object); - +- - for (i = 0; i < current_folder_separator_idx; i++) -+ switch (prop_id) - { +- { - gpointer col_data; - ShortcutType shortcut_type; - @@ -3170,10 +2220,7 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - return i; - } - } -+ case GTK_FILE_CHOOSER_PROP_ACTION: -+ g_value_set_enum (value, impl->action); -+ break; - +- - if (i < current_folder_separator_idx - 1) - { - if (!gtk_tree_model_iter_next (GTK_TREE_MODEL (impl->shortcuts_model), &iter)) @@ -3332,28 +2379,13 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - remove_selected_bookmarks (impl); -} - --struct selection_check_closure { -- GtkFileChooserDefault *impl; -- int num_selected; -- gboolean all_files; -- gboolean all_folders; --}; -- --/* Used from gtk_tree_selection_selected_foreach() */ --static void --selection_check_foreach_cb (GtkTreeModel *model, -- GtkTreePath *path, -- GtkTreeIter *iter, -- gpointer data) --{ -- struct selection_check_closure *closure; -- GtkTreeIter child_iter; -- const GtkFileInfo *info; -- gboolean is_folder; -- -- closure = data; -- closure->num_selected++; -- + struct selection_check_closure { + GtkFileChooserDefault *impl; + int num_selected; +@@ -2856,29 +1113,11 @@ + closure = data; + closure->num_selected++; + - switch (closure->impl->operation_mode) - { - case OPERATION_MODE_BROWSE: @@ -3361,14 +2393,17 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - info = _gtk_file_system_model_get_info (closure->impl->browse_files_model, &child_iter); - is_folder = info ? gtk_file_info_get_is_folder (info) : FALSE; - break; -- ++ gtk_tree_model_sort_convert_iter_to_child_iter (closure->impl->sort_model, &child_iter, iter); + - case OPERATION_MODE_SEARCH: - search_get_valid_child_iter (closure->impl, &child_iter, iter); - gtk_tree_model_get (GTK_TREE_MODEL (closure->impl->search_model), &child_iter, - SEARCH_MODEL_COL_IS_FOLDER, &is_folder, - -1); - break; -- ++ info = _gtk_file_system_model_get_info (closure->impl->browse_files_model, &child_iter); ++ is_folder = info ? gtk_file_info_get_is_folder (info) : FALSE; + - case OPERATION_MODE_RECENT: - recent_get_valid_child_iter (closure->impl, &child_iter, iter); - gtk_tree_model_get (GTK_TREE_MODEL (closure->impl->recent_model), &child_iter, @@ -3377,47 +2412,13 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - break; - } - -- closure->all_folders = closure->all_folders && is_folder; -- closure->all_files = closure->all_files && !is_folder; --} -- --/* Checks whether the selected items in the file list are all files or all folders */ --static void --selection_check (GtkFileChooserDefault *impl, -- gint *num_selected, -- gboolean *all_files, -- gboolean *all_folders) --{ -- struct selection_check_closure closure; -- GtkTreeSelection *selection; -- -- closure.impl = impl; -- closure.num_selected = 0; -- closure.all_files = TRUE; -- closure.all_folders = TRUE; -- -- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_files_tree_view)); -- gtk_tree_selection_selected_foreach (selection, -- selection_check_foreach_cb, -- &closure); -- -- g_assert (closure.num_selected == 0 || !(closure.all_files && closure.all_folders)); -- -- if (num_selected) -- *num_selected = closure.num_selected; -- -- if (all_files) -- *all_files = closure.all_files; -- -- if (all_folders) -- *all_folders = closure.all_folders; --} -- --struct get_selected_path_closure { -- GtkFileChooserDefault *impl; -- const GtkFilePath *path; --}; -- + closure->all_folders = closure->all_folders && is_folder; + closure->all_files = closure->all_files && !is_folder; + } +@@ -2920,1126 +1159,6 @@ + const GtkFilePath *path; + }; + -static void -get_selected_path_foreach_cb (GtkTreeModel *model, - GtkTreePath *path, @@ -4538,22 +3539,13 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - return vbox; -} - --/* Handles key press events on the file list, so that we can trap Enter to -- * activate the default button on our own. Also, checks to see if '/' has been -- * pressed. See comment by tree_view_keybinding_cb() for more details. -- */ --static gboolean --trap_activate_cb (GtkWidget *widget, -- GdkEventKey *event, -- gpointer data) --{ -- GtkFileChooserDefault *impl; -- int modifiers; -- -- impl = (GtkFileChooserDefault *) data; -- -- modifiers = gtk_accelerator_get_default_mod_mask (); -- + /* Handles key press events on the file list, so that we can trap Enter to + * activate the default button on our own. Also, checks to see if '/' has been + * pressed. See comment by tree_view_keybinding_cb() for more details. +@@ -4056,17 +1175,6 @@ + + modifiers = gtk_accelerator_get_default_mod_mask (); + - if ((event->keyval == GDK_slash - || event->keyval == GDK_KP_Divide -#ifdef G_OS_UNIX @@ -4565,37 +3557,25 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - return TRUE; - } - -- if ((event->keyval == GDK_Return -- || event->keyval == GDK_ISO_Enter -- || event->keyval == GDK_KP_Enter -- || event->keyval == GDK_space) -- && ((event->state & modifiers) == 0) -- && !(impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER || -- impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)) -- { -- GtkWindow *window; -- -- window = get_toplevel (widget); -- if (window -- && widget != window->default_widget -- && !(widget == window->focus_widget && -- (!window->default_widget || !GTK_WIDGET_SENSITIVE (window->default_widget)))) -- { -- gtk_window_activate_default (window); -- return TRUE; -- } -- } -- -- return FALSE; --} -- + if ((event->keyval == GDK_Return + || event->keyval == GDK_ISO_Enter + || event->keyval == GDK_KP_Enter +@@ -4091,474 +1199,66 @@ + return FALSE; + } + -/* Callback used when the file list's popup menu is detached */ -static void -popup_menu_detach_cb (GtkWidget *attach_widget, - GtkMenu *menu) --{ ++static gboolean ++list_button_press (GtkWidget *widget, GdkEventButton *event, gpointer data) + { - GtkFileChooserDefault *impl; -- ++ GtkTreeView * tree = GTK_TREE_VIEW (widget); ++ GtkFileChooserDefault *impl = data; ++ GtkTreePath *path; + - impl = g_object_get_data (G_OBJECT (attach_widget), "GtkFileChooserDefault"); - g_assert (GTK_IS_FILE_CHOOSER_DEFAULT (impl)); - @@ -4642,7 +3622,10 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - GtkFileChooser *chooser = GTK_FILE_CHOOSER (impl); - - for (i = 1; uris[i]; i++) -- { ++ if (event->type != GDK_BUTTON_PRESS || ++ !gtk_tree_view_get_path_at_pos (tree, (gint)event->x, (gint)event->y, ++ &path, NULL, NULL, NULL)) + { - GtkFilePath *path; - - uri = uris[i]; @@ -4658,16 +3641,19 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - - gtk_file_path_free (path); - } -- } ++ return FALSE; + } -} -- + -struct FileListDragData -{ - GtkFileChooserDefault *impl; - gchar **uris; - GtkFilePath *path; -}; -- ++ impl->list_press_time = event->time; ++ impl->list_press_path = path; + -static void -file_list_drag_data_received_get_info_cb (GtkFileSystemHandle *handle, - const GtkFileInfo *info, @@ -4713,8 +3699,9 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - g_free (data); - - g_object_unref (handle); --} -- ++ return FALSE; + } + -static void -file_list_drag_data_received_cb (GtkWidget *widget, - GdkDragContext *context, @@ -4783,18 +3770,23 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c -} - -/* Don't do anything with the drag_drop signal */ --static gboolean + static gboolean -file_list_drag_drop_cb (GtkWidget *widget, - GdkDragContext *context, - gint x, - gint y, - guint time_, - GtkFileChooserDefault *impl) --{ ++list_button_release (GtkWidget *widget, GdkEventButton *event, gpointer data) + { - g_signal_stop_emission_by_name (widget, "drag_drop"); - return TRUE; -} -- ++ GtkTreeView * tree = GTK_TREE_VIEW (widget); ++ GtkFileChooserDefault *impl = data; ++ GtkTreePath *path = NULL; ++ gboolean retval = FALSE; + -/* Disable the normal tree drag motion handler, it makes it look like you're - dropping the dragged item onto a tree item */ -static gboolean @@ -4907,15 +3899,21 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - NULL, NULL, NULL, NULL, - event->button, event->time); - else -- { ++ if (!impl->list_press_time || ++ !impl->list_press_path || ++ event->type != GDK_BUTTON_RELEASE || ++ !gtk_tree_view_get_path_at_pos (tree, (gint)event->x, (gint)event->y, ++ &path, NULL, NULL, NULL)) + { - gtk_menu_popup (GTK_MENU (impl->browse_files_popup_menu), - NULL, NULL, - popup_position_func, impl->browse_files_tree_view, - 0, GDK_CURRENT_TIME); - gtk_menu_shell_select_first (GTK_MENU_SHELL (impl->browse_files_popup_menu), - FALSE); -- } -- ++ goto done; + } + -} - -/* Callback used for the GtkWidget::popup-menu signal of the file list */ @@ -4961,7 +3959,9 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - name_id = mtime_id = 0; - - switch (impl->operation_mode) -- { ++ if (event->time - impl->list_press_time > LONG_CLICK_LENGTH && ++ !gtk_tree_path_compare (impl->list_press_path, path)) + { - case OPERATION_MODE_BROWSE: - name_id = FILE_LIST_COL_NAME; - mtime_id = FILE_LIST_COL_MTIME; @@ -4974,12 +3974,17 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - name_id = RECENT_MODEL_COL_PATH; - mtime_id = RECENT_MODEL_COL_INFO; - break; -- } -- ++ retval = TRUE; ++ list_row_activated (tree, path, NULL, impl); + } + - gtk_tree_view_column_set_sort_column_id (impl->list_name_column, name_id); - gtk_tree_view_column_set_sort_column_id (impl->list_mtime_column, mtime_id); -} -- ++ done: ++ if (path) ++ gtk_tree_path_free (path); + -static gboolean -file_list_query_tooltip_cb (GtkWidget *widget, - gint x, @@ -4993,7 +3998,8 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - GtkTreePath *path = NULL; - GtkFilePath *file_path = NULL; - gchar *filename; -- ++ impl->list_press_time = 0; + - if (impl->operation_mode == OPERATION_MODE_BROWSE) - return FALSE; - @@ -5007,7 +4013,8 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - return FALSE; - - switch (impl->operation_mode) -- { ++ if (impl->list_press_path) + { - case OPERATION_MODE_SEARCH: - if (!gtk_tree_model_get_iter (GTK_TREE_MODEL (impl->search_model_sort), &iter, path)) - { @@ -5037,8 +4044,10 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - case OPERATION_MODE_BROWSE: - g_assert_not_reached (); - return FALSE; -- } -- ++ gtk_tree_path_free (impl->list_press_path); ++ impl->list_press_path = NULL; + } + - if (!file_path) - { - gtk_tree_path_free (path); @@ -5055,52 +4064,44 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - gtk_tree_path_free (path); - - return TRUE; --} -- --/* Creates the widgets for the file list */ --static GtkWidget * --create_file_list (GtkFileChooserDefault *impl) --{ -- GtkWidget *swin; -- GtkTreeSelection *selection; -- GtkTreeViewColumn *column; -- GtkCellRenderer *renderer; -- -- /* Scrolled window */ -- -- swin = gtk_scrolled_window_new (NULL, NULL); -- gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (swin), ++ return FALSE; + } + ++ + /* Creates the widgets for the file list */ + static GtkWidget * + create_file_list (GtkFileChooserDefault *impl) +@@ -4572,7 +1272,7 @@ + + swin = gtk_scrolled_window_new (NULL, NULL); + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (swin), - GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS); -- gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (swin), -- GTK_SHADOW_IN); -- -- /* Tree/list view */ -- -- impl->browse_files_tree_view = gtk_tree_view_new (); --#ifdef PROFILE_FILE_CHOOSER -- g_object_set_data (G_OBJECT (impl->browse_files_tree_view), "fmq-name", "file_list"); --#endif -- g_object_set_data (G_OBJECT (impl->browse_files_tree_view), I_("GtkFileChooserDefault"), impl); -- atk_object_set_name (gtk_widget_get_accessible (impl->browse_files_tree_view), _("Files")); -- -- gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (impl->browse_files_tree_view), TRUE); -- gtk_container_add (GTK_CONTAINER (swin), impl->browse_files_tree_view); -- ++ GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); + gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (swin), + GTK_SHADOW_IN); + +@@ -4588,41 +1288,19 @@ + gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (impl->browse_files_tree_view), TRUE); + gtk_container_add (GTK_CONTAINER (swin), impl->browse_files_tree_view); + - gtk_drag_dest_set (impl->browse_files_tree_view, - GTK_DEST_DEFAULT_ALL, - file_list_dest_targets, - num_file_list_dest_targets, - GDK_ACTION_COPY | GDK_ACTION_MOVE); - -- g_signal_connect (impl->browse_files_tree_view, "row_activated", -- G_CALLBACK (list_row_activated), impl); -- g_signal_connect (impl->browse_files_tree_view, "key_press_event", -- G_CALLBACK (trap_activate_cb), impl); + g_signal_connect (impl->browse_files_tree_view, "row_activated", + G_CALLBACK (list_row_activated), impl); + g_signal_connect (impl->browse_files_tree_view, "key_press_event", + G_CALLBACK (trap_activate_cb), impl); - g_signal_connect (impl->browse_files_tree_view, "popup_menu", - G_CALLBACK (list_popup_menu_cb), impl); -- g_signal_connect (impl->browse_files_tree_view, "button_press_event", + g_signal_connect (impl->browse_files_tree_view, "button_press_event", - G_CALLBACK (list_button_press_event_cb), impl); -- ++ G_CALLBACK (list_button_press), impl); ++ g_signal_connect (impl->browse_files_tree_view, "button_release_event", ++ G_CALLBACK (list_button_release), impl); + - g_signal_connect (impl->browse_files_tree_view, "drag_data_received", - G_CALLBACK (file_list_drag_data_received_cb), impl); - g_signal_connect (impl->browse_files_tree_view, "drag_drop", @@ -5112,134 +4113,175 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - g_signal_connect (impl->browse_files_tree_view, "query-tooltip", - G_CALLBACK (file_list_query_tooltip_cb), impl); - -- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_files_tree_view)); -- gtk_tree_selection_set_select_function (selection, -- list_select_func, -- impl, NULL); + selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_files_tree_view)); + gtk_tree_selection_set_select_function (selection, + list_select_func, + impl, NULL); - gtk_tree_view_enable_model_drag_source (GTK_TREE_VIEW (impl->browse_files_tree_view), - GDK_BUTTON1_MASK, - file_list_source_targets, - num_file_list_source_targets, - GDK_ACTION_COPY); + + g_signal_connect (selection, "changed", + G_CALLBACK (list_selection_changed), impl); +@@ -4666,7 +1344,6 @@ + gtk_tree_view_column_set_sort_column_id (column, FILE_LIST_COL_SIZE); + gtk_tree_view_append_column (GTK_TREE_VIEW (impl->browse_files_tree_view), column); + #endif - -- g_signal_connect (selection, "changed", -- G_CALLBACK (list_selection_changed), impl); -- -- /* Filename column */ -- -- impl->list_name_column = gtk_tree_view_column_new (); -- gtk_tree_view_column_set_expand (impl->list_name_column, TRUE); -- gtk_tree_view_column_set_resizable (impl->list_name_column, TRUE); -- gtk_tree_view_column_set_title (impl->list_name_column, _("Name")); -- gtk_tree_view_column_set_sort_column_id (impl->list_name_column, FILE_LIST_COL_NAME); -- -- renderer = gtk_cell_renderer_pixbuf_new (); -- gtk_tree_view_column_pack_start (impl->list_name_column, renderer, FALSE); -- gtk_tree_view_column_set_cell_data_func (impl->list_name_column, renderer, -- list_icon_data_func, impl, NULL); -- -- impl->list_name_renderer = gtk_cell_renderer_text_new (); -- g_object_set (impl->list_name_renderer, -- "ellipsize", PANGO_ELLIPSIZE_END, -- NULL); -- g_signal_connect (impl->list_name_renderer, "edited", -- G_CALLBACK (renderer_edited_cb), impl); -- g_signal_connect (impl->list_name_renderer, "editing_canceled", -- G_CALLBACK (renderer_editing_canceled_cb), impl); -- gtk_tree_view_column_pack_start (impl->list_name_column, impl->list_name_renderer, TRUE); -- gtk_tree_view_column_set_cell_data_func (impl->list_name_column, impl->list_name_renderer, -- list_name_data_func, impl, NULL); -- -- gtk_tree_view_append_column (GTK_TREE_VIEW (impl->browse_files_tree_view), impl->list_name_column); --#if 0 -- /* Size column */ -- -- column = gtk_tree_view_column_new (); -- gtk_tree_view_column_set_title (column, _("Size")); -- -- renderer = gtk_cell_renderer_text_new (); -- gtk_tree_view_column_pack_start (column, renderer, TRUE); /* bug: it doesn't expand */ -- gtk_tree_view_column_set_cell_data_func (column, renderer, -- list_size_data_func, impl, NULL); -- gtk_tree_view_column_set_sort_column_id (column, FILE_LIST_COL_SIZE); -- gtk_tree_view_append_column (GTK_TREE_VIEW (impl->browse_files_tree_view), column); --#endif -- -- /* Modification time column */ -- -- column = gtk_tree_view_column_new (); -- gtk_tree_view_column_set_resizable (column, TRUE); -- gtk_tree_view_column_set_title (column, _("Modified")); -- -- renderer = gtk_cell_renderer_text_new (); -- gtk_tree_view_column_pack_start (column, renderer, TRUE); -- gtk_tree_view_column_set_cell_data_func (column, renderer, -- list_mtime_data_func, impl, NULL); -- gtk_tree_view_append_column (GTK_TREE_VIEW (impl->browse_files_tree_view), column); + /* Modification time column */ + + column = gtk_tree_view_column_new (); +@@ -4677,276 +1354,221 @@ + gtk_tree_view_column_pack_start (column, renderer, TRUE); + gtk_tree_view_column_set_cell_data_func (column, renderer, + list_mtime_data_func, impl, NULL); ++ gtk_tree_view_column_set_sort_column_id (column, FILE_LIST_COL_MTIME); + gtk_tree_view_append_column (GTK_TREE_VIEW (impl->browse_files_tree_view), column); - impl->list_mtime_column = column; - - file_list_set_sort_column_ids (impl); - -- gtk_widget_show_all (swin); -- -- return swin; --} -- + gtk_widget_show_all (swin); + + return swin; + } + -static GtkWidget * -create_path_bar (GtkFileChooserDefault *impl) --{ ++static void ++up_button_clicked_cb (GtkButton *button, gpointer data) + { - GtkWidget *path_bar; -- ++ GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (data); ++ up_folder_handler (impl); ++} + - path_bar = g_object_new (GTK_TYPE_PATH_BAR, NULL); - _gtk_path_bar_set_file_system (GTK_PATH_BAR (path_bar), impl->file_system); -- ++static void ++volume_button_clicked_cb (GtkButton *button, gpointer data) ++{ ++ GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (data); ++ GtkFilePath * path = g_object_get_data (G_OBJECT (button), "file-path"); + - return path_bar; --} -- ++ change_folder_and_display_error (impl, path); + } + -/* Creates the widgets for the files/folders pane */ --static GtkWidget * + static GtkWidget * -file_pane_create (GtkFileChooserDefault *impl, - GtkSizeGroup *size_group) --{ ++create_bar (GtkFileChooserDefault *impl) + { - GtkWidget *vbox; - GtkWidget *hbox; - GtkWidget *widget; -- ++ GSList *list, *l; ++ int n; ++ GtkWidget *bar = gtk_hbox_new (FALSE, DEFAULT_SPACING); ++ GtkWidget *img; ++ GtkWidget *label; + - vbox = gtk_vbox_new (FALSE, 6); - gtk_widget_show (vbox); -- ++ /* first the Up button */ ++ img = gtk_image_new_from_stock (GTK_STOCK_GO_UP, GTK_ICON_SIZE_BUTTON); ++ gtk_widget_show (img); + - /* Box for lists and preview */ -- ++ impl->up_button = gtk_button_new (); ++ gtk_container_add (GTK_CONTAINER (impl->up_button), img); ++ gtk_widget_show (impl->up_button); ++ gtk_widget_set_sensitive (impl->up_button, FALSE); ++ gtk_button_set_focus_on_click (GTK_BUTTON (impl->up_button), FALSE); + - hbox = gtk_hbox_new (FALSE, PREVIEW_HBOX_SPACING); - gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 0); - gtk_widget_show (hbox); -- ++ g_signal_connect (impl->up_button, "clicked", ++ G_CALLBACK (up_button_clicked_cb), impl); ++ gtk_box_pack_start (GTK_BOX(bar), impl->up_button, FALSE, FALSE, 0); + - /* File list */ -- ++ impl->num_volumes = 0; ++ list = gtk_file_system_list_volumes (impl->file_system); + - widget = create_file_list (impl); - gtk_box_pack_start (GTK_BOX (hbox), widget, TRUE, TRUE, 0); -- ++ n = 0; + - /* Preview */ -- ++ for (l = list; l; l = l->next, n++) ++ { ++ GtkFileSystemVolume *volume; ++ GdkPixbuf *pixbuf; ++ GtkWidget *button; ++ GtkWidget *image; ++ GtkFilePath *base_path; ++ gchar * file_name = NULL; + - impl->preview_box = gtk_vbox_new (FALSE, 12); - gtk_box_pack_start (GTK_BOX (hbox), impl->preview_box, FALSE, FALSE, 0); - /* Don't show preview box initially */ -- ++ volume = l->data; ++ base_path = ++ gtk_file_system_volume_get_base_path (impl->file_system, volume); + - /* Filter combo */ -- ++ if (impl->local_only) ++ { ++ gboolean is_local = ++ gtk_file_system_path_is_local (impl->file_system, base_path); + - impl->filter_combo_hbox = gtk_hbox_new (FALSE, 12); -- ++ if (!is_local) ++ { ++ gtk_file_path_free (base_path); ++ gtk_file_system_volume_free (impl->file_system, volume); ++ continue; ++ } ++ } + - widget = filter_create (impl); -- ++#if 0 ++ label_copy = ++ gtk_file_system_volume_get_display_name (impl->file_system, volume); ++#endif ++ pixbuf = ++ gtk_file_system_volume_render_icon (impl->file_system, volume, ++ GTK_WIDGET (impl), ++ impl->icon_size, NULL); + - gtk_widget_show (widget); - gtk_box_pack_end (GTK_BOX (impl->filter_combo_hbox), widget, FALSE, FALSE, 0); -- ++ button = gtk_button_new (); ++ image = gtk_image_new_from_pixbuf (pixbuf); ++ g_object_unref (G_OBJECT (pixbuf)); ++ gtk_container_add (GTK_CONTAINER (button), image); ++ gtk_button_set_focus_on_click (GTK_BUTTON (button), FALSE); + - gtk_size_group_add_widget (size_group, impl->filter_combo_hbox); - gtk_box_pack_end (GTK_BOX (vbox), impl->filter_combo_hbox, FALSE, FALSE, 0); -- ++ file_name = ++ gtk_file_system_path_to_filename (impl->file_system, base_path); + - return vbox; -} -- ++ if (file_name && impl->root_folder && ++ strcmp (file_name, impl->root_folder) && ++ !strncmp (file_name, impl->root_folder, strlen (file_name))) ++ { ++ /* The base path is below the root folder; we replace it with ++ * the root folder ++ */ ++ gtk_file_path_free (base_path); ++ base_path = gtk_file_system_filename_to_path (impl->file_system, ++ impl->root_folder); ++ } + -/* Callback used when the "Browse for more folders" expander is toggled */ -static void -expander_changed_cb (GtkExpander *expander, @@ -5249,17 +4291,22 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - impl->expand_folders = gtk_expander_get_expanded(GTK_EXPANDER (impl->save_expander)); - update_appearance (impl); -} -- ++ g_free (file_name); ++ gtk_widget_show_all (button); + -/* Callback used when the selection changes in the save folder combo box */ -static void -save_folder_combo_changed_cb (GtkComboBox *combo, - GtkFileChooserDefault *impl) -{ - GtkTreeIter iter; -- ++ g_object_set_data (G_OBJECT (button), "file-path", base_path); + - if (impl->changing_folder) - return; -- ++ g_signal_connect (button, "clicked", ++ G_CALLBACK (volume_button_clicked_cb), impl); + - if (gtk_combo_box_get_active_iter (combo, &iter)) - { - GtkTreeIter child_iter; @@ -5270,7 +4317,9 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - shortcuts_activate_iter (impl, &child_iter); - } -} -- ++ gtk_box_pack_start (GTK_BOX(bar), button, FALSE, FALSE, 0); ++ } + -/* Filter function used to filter out the Search item and its separator. - * Used for the "Save in folder" combo box, so that these items do not appear in it. - */ @@ -5284,14 +4333,25 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - gint *indices; - int idx; - gboolean retval; -- ++ impl->num_volumes = n; ++ g_slist_free (list); + - impl = GTK_FILE_CHOOSER_DEFAULT (data); -- ++ label = impl->location_label = gtk_label_new (NULL); ++ gtk_label_set_ellipsize (GTK_LABEL (label), PANGO_ELLIPSIZE_START); ++ gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5); ++ gtk_label_set_text (GTK_LABEL (label), impl->root_folder); ++ gtk_widget_show (label); ++ gtk_box_pack_start (GTK_BOX(bar), label, TRUE, TRUE, 0); + - g_assert (model == GTK_TREE_MODEL (impl->shortcuts_model)); -- ++ gtk_widget_show (bar); + - tree_path = gtk_tree_model_get_path (GTK_TREE_MODEL (impl->shortcuts_model), iter); - g_assert (tree_path != NULL); -- ++ return bar; ++} + - indices = gtk_tree_path_get_indices (tree_path); - - retval = TRUE; @@ -5322,24 +4382,44 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - } - -/* Creates the combo box with the save folders */ --static GtkWidget * ++/* Creates the widgets for the files/folders pane */ + static GtkWidget * -save_folder_combo_create (GtkFileChooserDefault *impl) --{ ++file_pane_create (GtkFileChooserDefault *impl) + { - GtkWidget *combo; - GtkCellRenderer *cell; -- ++ GtkWidget *vbox; ++ GtkWidget *hbox; ++ GtkWidget *widget; ++ vbox = gtk_vbox_new (FALSE, DEFAULT_SPACING); ++ gtk_widget_show (vbox); + - impl->shortcuts_combo_filter_model = gtk_tree_model_filter_new (GTK_TREE_MODEL (impl->shortcuts_model), NULL); - gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (impl->shortcuts_combo_filter_model), - shortcuts_combo_filter_func, - impl, - NULL); -- ++ /* The volume bar and 'Create Folder' button */ ++ hbox = gtk_hbox_new (FALSE, DEFAULT_SPACING); ++ gtk_widget_show (hbox); ++ impl->bar = create_bar (impl); ++ gtk_widget_show_all (impl->bar); ++ gtk_box_pack_start (GTK_BOX (hbox), impl->bar, TRUE, TRUE, 0); + - combo = g_object_new (GTK_TYPE_COMBO_BOX, - "model", impl->shortcuts_combo_filter_model, - "focus-on-click", FALSE, - NULL); - gtk_widget_show (combo); -- ++ /* Create Folder */ ++ widget = gtk_image_new_from_icon_name ("folder-new", GTK_ICON_SIZE_BUTTON); ++ gtk_widget_show (widget); ++ impl->browse_new_folder_button = gtk_button_new (); ++ gtk_container_add (GTK_CONTAINER (impl->browse_new_folder_button), widget); ++ gtk_button_set_focus_on_click (GTK_BUTTON (impl->browse_new_folder_button), ++ FALSE); + - cell = gtk_cell_renderer_pixbuf_new (); - gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo), cell, FALSE); - gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo), cell, @@ -5347,36 +4427,57 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - "visible", SHORTCUTS_COL_PIXBUF_VISIBLE, - "sensitive", SHORTCUTS_COL_PIXBUF_VISIBLE, - NULL); -- ++ g_signal_connect (impl->browse_new_folder_button, "clicked", ++ G_CALLBACK (new_folder_button_clicked), impl); ++ gtk_box_pack_end (GTK_BOX (hbox), impl->browse_new_folder_button, FALSE, FALSE, 0); + - cell = gtk_cell_renderer_text_new (); - gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo), cell, TRUE); - gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo), cell, - "text", SHORTCUTS_COL_NAME, - "sensitive", SHORTCUTS_COL_PIXBUF_VISIBLE, - NULL); -- ++ widget = filter_create (impl); ++ gtk_widget_hide (widget); ++ gtk_box_pack_end (GTK_BOX (hbox), widget, FALSE, FALSE, 0); + - gtk_combo_box_set_row_separator_func (GTK_COMBO_BOX (combo), - shortcuts_row_separator_func, - NULL, NULL); -- ++ gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0); + - g_signal_connect (combo, "changed", - G_CALLBACK (save_folder_combo_changed_cb), impl); -- ++ /* Box for lists */ ++ hbox = gtk_hbox_new (FALSE, LIST_HBOX_SPACING); ++ gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 0); ++ gtk_widget_show (hbox); + - return combo; --} -- --/* Creates the widgets specific to Save mode */ ++ /* File list */ ++ ++ widget = create_file_list (impl); ++ gtk_box_pack_start (GTK_BOX (hbox), widget, TRUE, TRUE, 0); ++ ++ return vbox; + } + + /* Creates the widgets specific to Save mode */ -static void --save_widgets_create (GtkFileChooserDefault *impl) --{ -- GtkWidget *vbox; ++static GtkWidget * + save_widgets_create (GtkFileChooserDefault *impl) + { + GtkWidget *vbox; - GtkWidget *table; -- GtkWidget *widget; ++ GtkWidget *hbox; + GtkWidget *widget; - GtkWidget *alignment; -- + - if (impl->save_widgets != NULL) - return; -- ++ vbox = gtk_vbox_new (FALSE, 0); ++ hbox = gtk_hbox_new (FALSE, DEFAULT_SPACING); + - location_switch_to_path_bar (impl); - - vbox = gtk_vbox_new (FALSE, 12); @@ -5390,27 +4491,33 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - /* Label */ - - widget = gtk_label_new_with_mnemonic (_("_Name:")); -- gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5); ++ widget = gtk_label_new (_("Name:")); + gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5); - gtk_table_attach (GTK_TABLE (table), widget, - 0, 1, 0, 1, - GTK_FILL, GTK_FILL, - 0, 0); -- gtk_widget_show (widget); -- ++ gtk_box_pack_start (GTK_BOX (hbox), widget, FALSE, FALSE, 0); + gtk_widget_show (widget); + - /* Location entry */ - -- impl->location_entry = _gtk_file_chooser_entry_new (TRUE); -- _gtk_file_chooser_entry_set_file_system (GTK_FILE_CHOOSER_ENTRY (impl->location_entry), -- impl->file_system); + impl->location_entry = _gtk_file_chooser_entry_new (TRUE); + _gtk_file_chooser_entry_set_file_system (GTK_FILE_CHOOSER_ENTRY (impl->location_entry), + impl->file_system); - gtk_entry_set_width_chars (GTK_ENTRY (impl->location_entry), 45); -- gtk_entry_set_activates_default (GTK_ENTRY (impl->location_entry), TRUE); ++/* gtk_entry_set_width_chars (GTK_ENTRY (impl->location_entry), 45); */ + gtk_entry_set_activates_default (GTK_ENTRY (impl->location_entry), TRUE); - gtk_table_attach (GTK_TABLE (table), impl->location_entry, - 1, 2, 0, 1, - GTK_EXPAND | GTK_FILL, 0, - 0, 0); -- gtk_widget_show (impl->location_entry); ++ gtk_box_pack_start (GTK_BOX (hbox), impl->location_entry, ++ TRUE, TRUE, 0); ++ + gtk_widget_show (impl->location_entry); - gtk_label_set_mnemonic_widget (GTK_LABEL (widget), impl->location_entry); -- + - /* Folder combo */ - impl->save_folder_label = gtk_label_new (NULL); - gtk_misc_set_alignment (GTK_MISC (impl->save_folder_label), 0.0, 0.5); @@ -5419,7 +4526,9 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - GTK_FILL, GTK_FILL, - 0, 0); - gtk_widget_show (impl->save_folder_label); -- ++ gtk_widget_show (hbox); ++ gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0); + - impl->save_folder_combo = save_folder_combo_create (impl); - gtk_table_attach (GTK_TABLE (table), impl->save_folder_combo, - 1, 2, 1, 2, @@ -5442,23 +4551,23 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - gtk_box_pack_start (GTK_BOX (impl), impl->save_widgets, FALSE, FALSE, 0); - gtk_box_reorder_child (GTK_BOX (impl), impl->save_widgets, 0); - gtk_widget_show (impl->save_widgets); --} -- --/* Destroys the widgets specific to Save mode */ --static void --save_widgets_destroy (GtkFileChooserDefault *impl) --{ -- if (impl->save_widgets == NULL) -- return; -- -- gtk_widget_destroy (impl->save_widgets); -- impl->save_widgets = NULL; -- impl->location_entry = NULL; ++ return vbox; + } + + /* Destroys the widgets specific to Save mode */ ++/* ??? */ + static void + save_widgets_destroy (GtkFileChooserDefault *impl) + { +@@ -4956,313 +1578,17 @@ + gtk_widget_destroy (impl->save_widgets); + impl->save_widgets = NULL; + impl->location_entry = NULL; - impl->save_folder_label = NULL; - impl->save_folder_combo = NULL; - impl->save_expander = NULL; --} -- + } + -/* Turns on the path bar widget. Can be called even if we are already in that - * mode. - */ @@ -5703,20 +4812,21 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - atk_object_set_name (gtk_widget_get_accessible (impl->location_button), str); -} - --/* Creates the main hpaned with the widgets shared by Open and Save mode */ --static GtkWidget * --browse_widgets_create (GtkFileChooserDefault *impl) --{ + /* Creates the main hpaned with the widgets shared by Open and Save mode */ + static GtkWidget * + browse_widgets_create (GtkFileChooserDefault *impl) + { - GtkWidget *vbox; - GtkWidget *hbox; - GtkWidget *hpaned; -- GtkWidget *widget; + GtkWidget *widget; - GtkSizeGroup *size_group; -- + - /* size group is used by the [+][-] buttons and the filter combo */ - size_group = gtk_size_group_new (GTK_SIZE_GROUP_VERTICAL); - vbox = gtk_vbox_new (FALSE, 12); -- ++ widget = file_pane_create (impl); + - /* Location widgets */ - hbox = gtk_hbox_new (FALSE, 12); - gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0); @@ -5761,51 +4871,40 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - g_object_unref (size_group); - - return vbox; --} -- --static GObject* --gtk_file_chooser_default_constructor (GType type, -- guint n_construct_properties, -- GObjectConstructParam *construct_params) --{ -- GtkFileChooserDefault *impl; -- GObject *object; -- -- profile_start ("start", NULL); -- -- object = G_OBJECT_CLASS (_gtk_file_chooser_default_parent_class)->constructor (type, -- n_construct_properties, -- construct_params); -- impl = GTK_FILE_CHOOSER_DEFAULT (object); -- -- g_assert (impl->file_system); -- -- gtk_widget_push_composite_child (); -- ++ return widget; + } + + static GObject* +@@ -5284,20 +1610,14 @@ + + gtk_widget_push_composite_child (); + - /* Recent files manager */ - recent_manager_update (impl); -- ++ /* Widgets for Save mode */ ++ impl->save_widgets = save_widgets_create (impl); ++ gtk_box_pack_start (GTK_BOX (impl), impl->save_widgets, FALSE, FALSE, 0); + - /* Shortcuts model */ - shortcuts_model_create (impl); - -- /* The browse widgets */ -- impl->browse_widgets = browse_widgets_create (impl); -- gtk_box_pack_start (GTK_BOX (impl), impl->browse_widgets, TRUE, TRUE, 0); -- + /* The browse widgets */ + impl->browse_widgets = browse_widgets_create (impl); + gtk_box_pack_start (GTK_BOX (impl), impl->browse_widgets, TRUE, TRUE, 0); + - /* Alignment to hold extra widget */ - impl->extra_align = gtk_alignment_new (0.0, 0.5, 1.0, 1.0); - gtk_box_pack_start (GTK_BOX (impl), impl->extra_align, FALSE, FALSE, 0); - -- gtk_widget_pop_composite_child (); -- update_appearance (impl); -- -- profile_end ("end", NULL); -- -- return object; --} -- + gtk_widget_pop_composite_child (); + update_appearance (impl); + +@@ -5306,35 +1626,7 @@ + return object; + } + -/* Sets the extra_widget by packing it in the appropriate place */ --static void + static void -set_extra_widget (GtkFileChooserDefault *impl, - GtkWidget *extra_widget) -{ @@ -5833,48 +4932,30 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c -} - -static void --set_local_only (GtkFileChooserDefault *impl, -- gboolean local_only) --{ -- if (local_only != impl->local_only) -- { -- impl->local_only = local_only; -- + set_local_only (GtkFileChooserDefault *impl, + gboolean local_only) + { +@@ -5342,12 +1634,6 @@ + { + impl->local_only = local_only; + - if (impl->shortcuts_model && impl->file_system) - { - shortcuts_add_volumes (impl); - shortcuts_add_bookmarks (impl); - } - -- if (local_only && -- !gtk_file_system_path_is_local (impl->file_system, impl->current_folder)) -- { -- /* If we are pointing to a non-local folder, make an effort to change -- * back to a local folder, but it's really up to the app to not cause -- * such a situation, so we ignore errors. -- */ -- const gchar *home = g_get_home_dir (); -- GtkFilePath *home_path; -- -- if (home == NULL) -- return; -- -- home_path = gtk_file_system_filename_to_path (impl->file_system, home); -- -- _gtk_file_chooser_set_current_folder_path (GTK_FILE_CHOOSER (impl), home_path, NULL); -- -- gtk_file_path_free (home_path); -- } -- } --} -- --static void --volumes_changed_cb (GtkFileSystem *file_system, -- GtkFileChooserDefault *impl) --{ + if (local_only && + !gtk_file_system_path_is_local (impl->file_system, impl->current_folder)) + { +@@ -5374,21 +1660,9 @@ + volumes_changed_cb (GtkFileSystem *file_system, + GtkFileChooserDefault *impl) + { - shortcuts_add_volumes (impl); --} -- ++ /* FIXME -- update the bar */ + } + -/* Callback used when the set of bookmarks changes in the file system */ -static void -bookmarks_changed_cb (GtkFileSystem *file_system, @@ -5887,97 +4968,67 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - shortcuts_check_popup_sensitivity (impl); -} - --/* Sets the file chooser to multiple selection mode */ --static void --set_select_multiple (GtkFileChooserDefault *impl, -- gboolean select_multiple, -- gboolean property_notify) --{ -- GtkTreeSelection *selection; -- GtkSelectionMode mode; -- -- if (select_multiple == impl->select_multiple) -- return; -- -- mode = select_multiple ? GTK_SELECTION_MULTIPLE : GTK_SELECTION_BROWSE; -- -- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_files_tree_view)); -- gtk_tree_selection_set_mode (selection, mode); -- -- impl->select_multiple = select_multiple; -- g_object_notify (G_OBJECT (impl), "select-multiple"); + /* Sets the file chooser to multiple selection mode */ + static void + set_select_multiple (GtkFileChooserDefault *impl, +@@ -5408,8 +1682,6 @@ + + impl->select_multiple = select_multiple; + g_object_notify (G_OBJECT (impl), "select-multiple"); - - check_preview_change (impl); --} -- --static void --set_file_system_backend (GtkFileChooserDefault *impl, -- const char *backend) --{ -- profile_start ("start for backend", backend ? backend : "default"); -- -- if (impl->file_system) -- { -- g_signal_handler_disconnect (impl->file_system, impl->volumes_changed_id); -- impl->volumes_changed_id = 0; + } + + static void +@@ -5422,8 +1694,6 @@ + { + g_signal_handler_disconnect (impl->file_system, impl->volumes_changed_id); + impl->volumes_changed_id = 0; - g_signal_handler_disconnect (impl->file_system, impl->bookmarks_changed_id); - impl->bookmarks_changed_id = 0; -- g_object_unref (impl->file_system); -- } -- -- impl->file_system = NULL; -- if (backend) -- impl->file_system = gtk_file_system_create (backend); -- else -- { -- GtkSettings *settings = gtk_settings_get_default (); -- gchar *default_backend = NULL; -- -- g_object_get (settings, "gtk-file-chooser-backend", &default_backend, NULL); -- if (default_backend) -- { -- impl->file_system = gtk_file_system_create (default_backend); -- g_free (default_backend); -- } -- } -- -- if (!impl->file_system) -- { --#if defined (G_OS_UNIX) -- impl->file_system = gtk_file_system_unix_new (); --#elif defined (G_OS_WIN32) -- impl->file_system = gtk_file_system_win32_new (); --#else --#error "No default filesystem implementation on the platform" --#endif -- } -- -- if (impl->file_system) -- { -- impl->volumes_changed_id = g_signal_connect (impl->file_system, "volumes-changed", -- G_CALLBACK (volumes_changed_cb), -- impl); + g_object_unref (impl->file_system); + } + +@@ -5459,14 +1729,28 @@ + impl->volumes_changed_id = g_signal_connect (impl->file_system, "volumes-changed", + G_CALLBACK (volumes_changed_cb), + impl); - impl->bookmarks_changed_id = g_signal_connect (impl->file_system, "bookmarks-changed", - G_CALLBACK (bookmarks_changed_cb), - impl); -- } -- -- profile_end ("end", NULL); --} -- --/* This function is basically a do_all function. -- * -- * It sets the visibility on all the widgets based on the current state, and -- * moves the custom_widget if needed. -- */ --static void --update_appearance (GtkFileChooserDefault *impl) --{ -- if (impl->action == GTK_FILE_CHOOSER_ACTION_SAVE || -- impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER) -- { + } + + profile_end ("end", NULL); + } + ++static void ++show_new_folder_button (GtkFileChooserDefault *impl) ++{ ++ if ((impl->action == GTK_FILE_CHOOSER_ACTION_SAVE || ++ impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER) && ++ impl->show_create_folder) ++ { ++ gtk_widget_show (impl->browse_new_folder_button); ++ gtk_misc_set_alignment (GTK_MISC (impl->location_label), 0.5, 0.5); ++ } ++ else ++ { ++ gtk_widget_hide (impl->browse_new_folder_button); ++ gtk_misc_set_alignment (GTK_MISC (impl->location_label), 1.0, 0.5); ++ } ++} ++ + /* This function is basically a do_all function. + * + * It sets the visibility on all the widgets based on the current state, and +@@ -5478,33 +1762,9 @@ + if (impl->action == GTK_FILE_CHOOSER_ACTION_SAVE || + impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER) + { - const char *text; -- ++ gtk_widget_show (impl->save_widgets); ++ gtk_widget_show (impl->browse_widgets); + - gtk_widget_hide (impl->location_button); - save_widgets_create (impl); - @@ -6003,25 +5054,24 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - - gtk_widget_show (impl->browse_new_folder_button); - -- if (impl->select_multiple) -- { -- g_warning ("Save mode cannot be set in conjunction with multiple selection mode. " -- "Re-setting to single selection mode."); -- set_select_multiple (impl, FALSE, TRUE); -- } -- } -- else if (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN || -- impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER) -- { + if (impl->select_multiple) + { + g_warning ("Save mode cannot be set in conjunction with multiple selection mode. " +@@ -5515,23 +1775,12 @@ + else if (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN || + impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER) + { - gtk_widget_show (impl->location_button); - save_widgets_destroy (impl); -- gtk_widget_show (impl->browse_widgets); ++ gtk_widget_hide (impl->save_widgets); + gtk_widget_show (impl->browse_widgets); - location_mode_set (impl, impl->location_mode, TRUE); -- } -- + } + - if (impl->location_entry) - _gtk_file_chooser_entry_set_action (GTK_FILE_CHOOSER_ENTRY (impl->location_entry), impl->action); -- ++ show_new_folder_button (impl); + - if (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN) - gtk_widget_hide (impl->browse_new_folder_button); - else @@ -6030,58 +5080,23 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - /* This *is* needed; we need to redraw the file list because the "sensitivity" - * of files may change depending whether we are in a file or folder-only mode. - */ -- gtk_widget_queue_draw (impl->browse_files_tree_view); -- -- g_signal_emit_by_name (impl, "default-size-changed"); --} -- --static void --gtk_file_chooser_default_set_property (GObject *object, -- guint prop_id, -- const GValue *value, -- GParamSpec *pspec) -- --{ -- GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (object); -- -- switch (prop_id) -- { -- case GTK_FILE_CHOOSER_PROP_ACTION: -- { -- GtkFileChooserAction action = g_value_get_enum (value); -- -- if (action != impl->action) -- { -- gtk_file_chooser_default_unselect_all (GTK_FILE_CHOOSER (impl)); -- + gtk_widget_queue_draw (impl->browse_files_tree_view); + + g_signal_emit_by_name (impl, "default-size-changed"); +@@ -5556,8 +1805,7 @@ + { + gtk_file_chooser_default_unselect_all (GTK_FILE_CHOOSER (impl)); + - if ((action == GTK_FILE_CHOOSER_ACTION_SAVE || - action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER) -- && impl->select_multiple) -- { -- g_warning ("Tried to change the file chooser action to SAVE or CREATE_FOLDER, but " -- "this is not allowed in multiple selection mode. Resetting the file chooser " -- "to single selection mode."); -- set_select_multiple (impl, FALSE, TRUE); -- } -- impl->action = action; -- update_appearance (impl); -- settings_load (impl); -- } -- } -- break; -- -- case GTK_FILE_CHOOSER_PROP_FILE_SYSTEM_BACKEND: -- set_file_system_backend (impl, g_value_get_string (value)); -- break; -- -- case GTK_FILE_CHOOSER_PROP_FILTER: -- set_current_filter (impl, g_value_get_object (value)); -- break; -- -- case GTK_FILE_CHOOSER_PROP_LOCAL_ONLY: -- set_local_only (impl, g_value_get_boolean (value)); -- break; -- ++ if ((action == GTK_FILE_CHOOSER_ACTION_SAVE || action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER) + && impl->select_multiple) + { + g_warning ("Tried to change the file chooser action to SAVE or CREATE_FOLDER, but " +@@ -5584,29 +1832,10 @@ + set_local_only (impl, g_value_get_boolean (value)); + break; + - case GTK_FILE_CHOOSER_PROP_PREVIEW_WIDGET: - set_preview_widget (impl, g_value_get_object (value)); - break; @@ -6100,170 +5115,143 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - set_extra_widget (impl, g_value_get_object (value)); - break; - -- case GTK_FILE_CHOOSER_PROP_SELECT_MULTIPLE: -- { -- gboolean select_multiple = g_value_get_boolean (value); + case GTK_FILE_CHOOSER_PROP_SELECT_MULTIPLE: + { + gboolean select_multiple = g_value_get_boolean (value); - if ((impl->action == GTK_FILE_CHOOSER_ACTION_SAVE || - impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER) -- && select_multiple) -- { -- g_warning ("Tried to set the file chooser to multiple selection mode, but this is " -- "not allowed in SAVE or CREATE_FOLDER modes. Ignoring the change and " -- "leaving the file chooser in single selection mode."); -- return; -- } -- -- set_select_multiple (impl, select_multiple, FALSE); -- } -- break; -- -- case GTK_FILE_CHOOSER_PROP_SHOW_HIDDEN: -- { -- gboolean show_hidden = g_value_get_boolean (value); -- if (show_hidden != impl->show_hidden) -- { -- impl->show_hidden = show_hidden; -- -- if (impl->browse_files_model) -- _gtk_file_system_model_set_show_hidden (impl->browse_files_model, show_hidden); -- } -- } -- break; -- -- case GTK_FILE_CHOOSER_PROP_DO_OVERWRITE_CONFIRMATION: -- { -- gboolean do_overwrite_confirmation = g_value_get_boolean (value); -- impl->do_overwrite_confirmation = do_overwrite_confirmation; -- } -- break; -- -- default: -- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); -- break; -- } --} -- --static void --gtk_file_chooser_default_get_property (GObject *object, -- guint prop_id, -- GValue *value, -- GParamSpec *pspec) --{ -- GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (object); -- -- switch (prop_id) -- { -- case GTK_FILE_CHOOSER_PROP_ACTION: -- g_value_set_enum (value, impl->action); -- break; -- -- case GTK_FILE_CHOOSER_PROP_FILTER: -- g_value_set_object (value, impl->current_filter); -- break; -- -- case GTK_FILE_CHOOSER_PROP_LOCAL_ONLY: -- g_value_set_boolean (value, impl->local_only); -- break; -- ++ if ((impl->action == GTK_FILE_CHOOSER_ACTION_SAVE || impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER) + && select_multiple) + { + g_warning ("Tried to set the file chooser to multiple selection mode, but this is " +@@ -5639,6 +1868,51 @@ + } + break; + ++ case GTK_FILE_CHOOSER_PROP_ROOT_FOLDER: ++ { ++ GtkFilePath * path; ++ gchar * new_root = g_strdup (g_value_get_string (value)); ++ ++ if (!new_root) ++ { ++ new_root = g_strdup ("/"); ++ } ++ ++ path = gtk_file_system_filename_to_path (impl->file_system, ++ new_root); ++ if (change_folder (impl, path, FALSE)) ++ { ++ g_free (impl->root_folder); ++ impl->root_folder = new_root; ++ } ++ else ++ { ++ g_warning ("Unable to set [%s] as root folder", new_root); ++ g_free (new_root); ++ } ++ ++ gtk_file_path_free (path); ++ } ++ break; ++ ++ case GTK_FILE_CHOOSER_PROP_SHOW_CREATE_FOLDER: ++ { ++ gboolean show = g_value_get_boolean (value); ++ if (show != impl->show_create_folder) ++ { ++ impl->show_create_folder = show; ++ show_new_folder_button (impl); ++ } ++ } ++ break; ++ ++ /* These are not supported */ ++ case GTK_FILE_CHOOSER_PROP_PREVIEW_WIDGET: ++ case GTK_FILE_CHOOSER_PROP_PREVIEW_WIDGET_ACTIVE: ++ case GTK_FILE_CHOOSER_PROP_USE_PREVIEW_LABEL: ++ case GTK_FILE_CHOOSER_PROP_EXTRA_WIDGET: ++ break; ++ + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; +@@ -5667,30 +1941,34 @@ + g_value_set_boolean (value, impl->local_only); + break; + - case GTK_FILE_CHOOSER_PROP_PREVIEW_WIDGET: - g_value_set_object (value, impl->preview_widget); -- break; -- ++ case GTK_FILE_CHOOSER_PROP_SELECT_MULTIPLE: ++ g_value_set_boolean (value, impl->select_multiple); + break; + - case GTK_FILE_CHOOSER_PROP_PREVIEW_WIDGET_ACTIVE: - g_value_set_boolean (value, impl->preview_widget_active); -- break; -- ++ case GTK_FILE_CHOOSER_PROP_SHOW_HIDDEN: ++ g_value_set_boolean (value, impl->show_hidden); + break; + - case GTK_FILE_CHOOSER_PROP_USE_PREVIEW_LABEL: - g_value_set_boolean (value, impl->use_preview_label); -- break; -- ++ case GTK_FILE_CHOOSER_PROP_ROOT_FOLDER: ++ g_value_set_string (value, impl->root_folder); + break; + - case GTK_FILE_CHOOSER_PROP_EXTRA_WIDGET: - g_value_set_object (value, impl->extra_widget); -- break; -- ++ case GTK_FILE_CHOOSER_PROP_SHOW_CREATE_FOLDER: ++ g_value_set_boolean (value, impl->show_create_folder); + break; + - case GTK_FILE_CHOOSER_PROP_SELECT_MULTIPLE: - g_value_set_boolean (value, impl->select_multiple); -- break; -- ++ case GTK_FILE_CHOOSER_PROP_PREVIEW_WIDGET: ++ g_value_set_object (value, NULL); + break; + - case GTK_FILE_CHOOSER_PROP_SHOW_HIDDEN: - g_value_set_boolean (value, impl->show_hidden); -- break; -- -- case GTK_FILE_CHOOSER_PROP_DO_OVERWRITE_CONFIRMATION: -- g_value_set_boolean (value, impl->do_overwrite_confirmation); -- break; -- -- default: -- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); -- break; -- } --} -- --/* Removes the settings signal handler. It's safe to call multiple times */ --static void --remove_settings_signal (GtkFileChooserDefault *impl, -- GdkScreen *screen) --{ -- if (impl->settings_signal_id) -- { -- GtkSettings *settings; -- -- settings = gtk_settings_get_for_screen (screen); -- g_signal_handler_disconnect (settings, -- impl->settings_signal_id); -- impl->settings_signal_id = 0; -- } --} -- --static void --gtk_file_chooser_default_dispose (GObject *object) --{ -- GSList *l; -- GtkFileChooserDefault *impl = (GtkFileChooserDefault *) object; -- ++ case GTK_FILE_CHOOSER_PROP_PREVIEW_WIDGET_ACTIVE: ++ g_value_set_boolean (value, FALSE); + break; + ++ case GTK_FILE_CHOOSER_PROP_USE_PREVIEW_LABEL: ++ g_value_set_boolean (value, FALSE); ++ break; ++ + case GTK_FILE_CHOOSER_PROP_DO_OVERWRITE_CONFIRMATION: + g_value_set_boolean (value, impl->do_overwrite_confirmation); + break; +@@ -5723,24 +2001,12 @@ + GSList *l; + GtkFileChooserDefault *impl = (GtkFileChooserDefault *) object; + - if (impl->extra_widget) - { - g_object_unref (impl->extra_widget); - impl->extra_widget = NULL; - } - -- if (impl->volumes_changed_id > 0) -- { -- g_signal_handler_disconnect (impl->file_system, impl->volumes_changed_id); -- impl->volumes_changed_id = 0; -- } -- + if (impl->volumes_changed_id > 0) + { + g_signal_handler_disconnect (impl->file_system, impl->volumes_changed_id); + impl->volumes_changed_id = 0; + } + - if (impl->bookmarks_changed_id > 0) - { - g_signal_handler_disconnect (impl->file_system, impl->bookmarks_changed_id); - impl->bookmarks_changed_id = 0; - } - -- pending_select_paths_free (impl); -- -- /* cancel all pending operations */ -- if (impl->pending_handles) -- { -- for (l = impl->pending_handles; l; l = l->next) -- { -- GtkFileSystemHandle *handle =l->data; -- gtk_file_system_cancel_operation (handle); -- } -- g_slist_free (impl->pending_handles); -- impl->pending_handles = NULL; -- } -- -- if (impl->reload_icon_handles) -- { -- for (l = impl->reload_icon_handles; l; l = l->next) -- { -- GtkFileSystemHandle *handle =l->data; -- gtk_file_system_cancel_operation (handle); -- } -- g_slist_free (impl->reload_icon_handles); -- impl->reload_icon_handles = NULL; -- } -- + pending_select_paths_free (impl); + + /* cancel all pending operations */ +@@ -5766,23 +2032,6 @@ + impl->reload_icon_handles = NULL; + } + - if (impl->loading_shortcuts) - { - for (l = impl->loading_shortcuts; l; l = l->next) @@ -6281,30 +5269,13 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - impl->file_list_drag_data_received_handle = NULL; - } - -- if (impl->update_current_folder_handle) -- { -- gtk_file_system_cancel_operation (impl->update_current_folder_handle); -- impl->update_current_folder_handle = NULL; -- } -- -- if (impl->show_and_select_paths_handle) -- { -- gtk_file_system_cancel_operation (impl->show_and_select_paths_handle); -- impl->show_and_select_paths_handle = NULL; -- } -- -- if (impl->should_respond_get_info_handle) -- { -- gtk_file_system_cancel_operation (impl->should_respond_get_info_handle); -- impl->should_respond_get_info_handle = NULL; -- } -- -- if (impl->update_from_entry_handle) -- { -- gtk_file_system_cancel_operation (impl->update_from_entry_handle); -- impl->update_from_entry_handle = NULL; -- } -- + if (impl->update_current_folder_handle) + { + gtk_file_system_cancel_operation (impl->update_current_folder_handle); +@@ -5807,15 +2056,6 @@ + impl->update_from_entry_handle = NULL; + } + - if (impl->shortcuts_activate_iter_handle) - { - gtk_file_system_cancel_operation (impl->shortcuts_activate_iter_handle); @@ -6314,138 +5285,45 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - search_stop_searching (impl, TRUE); - recent_stop_loading (impl); - -- remove_settings_signal (impl, gtk_widget_get_screen (GTK_WIDGET (impl))); -- -- G_OBJECT_CLASS (_gtk_file_chooser_default_parent_class)->dispose (object); --} -- --/* We override show-all since we have internal widgets that -- * shouldn't be shown when you call show_all(), like the filter -- * combo box. -- */ --static void --gtk_file_chooser_default_show_all (GtkWidget *widget) --{ + remove_settings_signal (impl, gtk_widget_get_screen (GTK_WIDGET (impl))); + + G_OBJECT_CLASS (_gtk_file_chooser_default_parent_class)->dispose (object); +@@ -5828,12 +2068,7 @@ + static void + gtk_file_chooser_default_show_all (GtkWidget *widget) + { - GtkFileChooserDefault *impl = (GtkFileChooserDefault *) widget; - -- gtk_widget_show (widget); + gtk_widget_show (widget); - - if (impl->extra_widget) - gtk_widget_show_all (impl->extra_widget); --} -- --/* Handler for GtkWindow::set-focus; this is where we save the last-focused -- * widget on our toplevel. See gtk_file_chooser_default_hierarchy_changed() -- */ --static void --toplevel_set_focus_cb (GtkWindow *window, -- GtkWidget *focus, -- GtkFileChooserDefault *impl) --{ -- impl->toplevel_last_focus_widget = gtk_window_get_focus (window); --} -- --/* We monitor the focus widget on our toplevel to be able to know which widget -- * was last focused at the time our "should_respond" method gets called. -- */ --static void --gtk_file_chooser_default_hierarchy_changed (GtkWidget *widget, -- GtkWidget *previous_toplevel) --{ -- GtkFileChooserDefault *impl; -- GtkWidget *toplevel; -- -- impl = GTK_FILE_CHOOSER_DEFAULT (widget); -- -- if (previous_toplevel) -- { -- g_assert (impl->toplevel_set_focus_id != 0); -- g_signal_handler_disconnect (previous_toplevel, impl->toplevel_set_focus_id); -- impl->toplevel_set_focus_id = 0; -- impl->toplevel_last_focus_widget = NULL; -- } -- else -- g_assert (impl->toplevel_set_focus_id == 0); -- -- toplevel = gtk_widget_get_toplevel (widget); -- if (GTK_IS_WINDOW (toplevel)) -- { -- impl->toplevel_set_focus_id = g_signal_connect (toplevel, "set_focus", -- G_CALLBACK (toplevel_set_focus_cb), impl); -- impl->toplevel_last_focus_widget = gtk_window_get_focus (GTK_WINDOW (toplevel)); -- } --} -- --/* Changes the icons wherever it is needed */ --static void --change_icon_theme (GtkFileChooserDefault *impl) --{ -- GtkSettings *settings; -- gint width, height; -- -- profile_start ("start", NULL); -- -- settings = gtk_settings_get_for_screen (gtk_widget_get_screen (GTK_WIDGET (impl))); -- -- if (gtk_icon_size_lookup_for_settings (settings, GTK_ICON_SIZE_MENU, &width, &height)) -- impl->icon_size = MAX (width, height); -- else -- impl->icon_size = FALLBACK_ICON_SIZE; -- + } + + /* Handler for GtkWindow::set-focus; this is where we save the last-focused +@@ -5894,7 +2129,6 @@ + else + impl->icon_size = FALLBACK_ICON_SIZE; + - shortcuts_reload_icons (impl); -- gtk_widget_queue_resize (impl->browse_files_tree_view); -- -- profile_end ("end", NULL); --} -- --/* Callback used when a GtkSettings value changes */ --static void --settings_notify_cb (GObject *object, -- GParamSpec *pspec, -- GtkFileChooserDefault *impl) --{ -- const char *name; -- -- profile_start ("start", NULL); -- -- name = g_param_spec_get_name (pspec); -- + gtk_widget_queue_resize (impl->browse_files_tree_view); + + profile_end ("end", NULL); +@@ -5912,8 +2146,8 @@ + + name = g_param_spec_get_name (pspec); + - if (strcmp (name, "gtk-icon-theme-name") == 0 || - strcmp (name, "gtk-icon-sizes") == 0) -- change_icon_theme (impl); -- -- profile_end ("end", NULL); --} -- --/* Installs a signal handler for GtkSettings so that we can monitor changes in -- * the icon theme. -- */ --static void --check_icon_theme (GtkFileChooserDefault *impl) --{ -- GtkSettings *settings; -- -- profile_start ("start", NULL); -- -- if (impl->settings_signal_id) -- { -- profile_end ("end", NULL); -- return; -- } -- -- if (gtk_widget_has_screen (GTK_WIDGET (impl))) -- { -- settings = gtk_settings_get_for_screen (gtk_widget_get_screen (GTK_WIDGET (impl))); -- impl->settings_signal_id = g_signal_connect (settings, "notify", -- G_CALLBACK (settings_notify_cb), impl); -- -- change_icon_theme (impl); -- } -- -- profile_end ("end", NULL); --} -- --static void ++ if (strcmp (name, "gtk-icon-theme-name") == 0 ++ || strcmp (name, "gtk-icon-sizes") == 0) + change_icon_theme (impl); + + profile_end ("end", NULL); +@@ -5948,24 +2182,6 @@ + } + + static void -recent_manager_update (GtkFileChooserDefault *impl) -{ - GtkRecentManager *manager; @@ -6464,72 +5342,21 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c -} - -static void --gtk_file_chooser_default_style_set (GtkWidget *widget, -- GtkStyle *previous_style) --{ -- GtkFileChooserDefault *impl; -- -- profile_start ("start", NULL); -- -- impl = GTK_FILE_CHOOSER_DEFAULT (widget); -- -- profile_msg (" parent class style_set start", NULL); -- if (GTK_WIDGET_CLASS (_gtk_file_chooser_default_parent_class)->style_set) -- GTK_WIDGET_CLASS (_gtk_file_chooser_default_parent_class)->style_set (widget, previous_style); -- profile_msg (" parent class style_set end", NULL); -- -- if (gtk_widget_has_screen (GTK_WIDGET (impl))) -- change_icon_theme (impl); -- -- profile_msg (" emit default-size-changed start", NULL); -- g_signal_emit_by_name (widget, "default-size-changed"); -- profile_msg (" emit default-size-changed end", NULL); -- -- profile_end ("end", NULL); --} -- --static void --gtk_file_chooser_default_screen_changed (GtkWidget *widget, -- GdkScreen *previous_screen) --{ -- GtkFileChooserDefault *impl; -- -- profile_start ("start", NULL); -- -- impl = GTK_FILE_CHOOSER_DEFAULT (widget); -- -- if (GTK_WIDGET_CLASS (_gtk_file_chooser_default_parent_class)->screen_changed) -- GTK_WIDGET_CLASS (_gtk_file_chooser_default_parent_class)->screen_changed (widget, previous_screen); -- -- remove_settings_signal (impl, previous_screen); -- check_icon_theme (impl); + gtk_file_chooser_default_style_set (GtkWidget *widget, + GtkStyle *previous_style) + { +@@ -6005,7 +2221,6 @@ + + remove_settings_signal (impl, previous_screen); + check_icon_theme (impl); - recent_manager_update (impl); -- -- g_signal_emit_by_name (widget, "default-size-changed"); -- -- profile_end ("end", NULL); --} -- --static void --gtk_file_chooser_default_size_allocate (GtkWidget *widget, -- GtkAllocation *allocation) --{ -- GtkFileChooserDefault *impl; -- -- impl = GTK_FILE_CHOOSER_DEFAULT (widget); -- -- GTK_WIDGET_CLASS (_gtk_file_chooser_default_parent_class)->size_allocate (widget, allocation); -- -- if (!gtk_file_chooser_default_get_resizable (GTK_FILE_CHOOSER_EMBED (impl))) -- { -- /* The dialog is not resizable, we shouldn't -- * trust in the size it has in this stage -- */ -- return; -- } -- -- impl->default_width = allocation->width; -- impl->default_height = allocation->height; + + g_signal_emit_by_name (widget, "default-size-changed"); + +@@ -6032,15 +2247,6 @@ + + impl->default_width = allocation->width; + impl->default_height = allocation->height; - - if (impl->preview_widget_active && - impl->preview_widget && @@ -6539,110 +5366,48 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - if (impl->extra_widget && - GTK_WIDGET_DRAWABLE (impl->extra_widget)) - impl->default_height -= GTK_BOX (widget)->spacing + impl->extra_widget->allocation.height; --} -- --static gboolean --get_is_file_filtered (GtkFileChooserDefault *impl, -- const GtkFilePath *path, -- GtkFileInfo *file_info) --{ -- GtkFileFilterInfo filter_info; -- GtkFileFilterFlags needed; -- gboolean result; -- -- if (!impl->current_filter) -- return FALSE; -- -- filter_info.contains = GTK_FILE_FILTER_DISPLAY_NAME | GTK_FILE_FILTER_MIME_TYPE; -- -- needed = gtk_file_filter_get_needed (impl->current_filter); -- -- filter_info.display_name = gtk_file_info_get_display_name (file_info); -- filter_info.mime_type = gtk_file_info_get_mime_type (file_info); -- -- if (needed & GTK_FILE_FILTER_FILENAME) -- { -- filter_info.filename = gtk_file_system_path_to_filename (impl->file_system, path); -- if (filter_info.filename) -- filter_info.contains |= GTK_FILE_FILTER_FILENAME; -- } -- else -- filter_info.filename = NULL; -- -- if (needed & GTK_FILE_FILTER_URI) -- { -- filter_info.uri = gtk_file_system_path_to_uri (impl->file_system, path); -- if (filter_info.uri) -- filter_info.contains |= GTK_FILE_FILTER_URI; -- } -- else -- filter_info.uri = NULL; -- -- result = gtk_file_filter_filter (impl->current_filter, &filter_info); -- -- if (filter_info.filename) -- g_free ((gchar *)filter_info.filename); -- if (filter_info.uri) -- g_free ((gchar *)filter_info.uri); -- -- return !result; --} -- --static void --settings_load (GtkFileChooserDefault *impl) --{ -- GtkFileChooserSettings *settings; + } + + static gboolean +@@ -6094,23 +2300,18 @@ + settings_load (GtkFileChooserDefault *impl) + { + GtkFileChooserSettings *settings; - LocationMode location_mode; -- gboolean show_hidden; -- gboolean expand_folders; -- -- settings = _gtk_file_chooser_settings_new (); -- + gboolean show_hidden; + gboolean expand_folders; + + settings = _gtk_file_chooser_settings_new (); + - location_mode = _gtk_file_chooser_settings_get_location_mode (settings); -- show_hidden = _gtk_file_chooser_settings_get_show_hidden (settings); -- expand_folders = _gtk_file_chooser_settings_get_expand_folders (settings); -- -- g_object_unref (settings); -- + show_hidden = _gtk_file_chooser_settings_get_show_hidden (settings); + expand_folders = _gtk_file_chooser_settings_get_expand_folders (settings); + + g_object_unref (settings); + - location_mode_set (impl, location_mode, TRUE); -- gtk_file_chooser_set_show_hidden (GTK_FILE_CHOOSER (impl), show_hidden); -- impl->expand_folders = expand_folders; + gtk_file_chooser_set_show_hidden (GTK_FILE_CHOOSER (impl), show_hidden); + impl->expand_folders = expand_folders; - if (impl->save_expander) - gtk_expander_set_expanded (GTK_EXPANDER (impl->save_expander), expand_folders); --} -- --static void --settings_save (GtkFileChooserDefault *impl) --{ -- GtkFileChooserSettings *settings; -- -- settings = _gtk_file_chooser_settings_new (); -- + } + + static void +@@ -6120,7 +2321,6 @@ + + settings = _gtk_file_chooser_settings_new (); + - _gtk_file_chooser_settings_set_location_mode (settings, impl->location_mode); -- _gtk_file_chooser_settings_set_show_hidden (settings, gtk_file_chooser_get_show_hidden (GTK_FILE_CHOOSER (impl))); -- _gtk_file_chooser_settings_set_expand_folders (settings, impl->expand_folders); -- -- /* NULL GError */ -- _gtk_file_chooser_settings_save (settings, NULL); -- -- g_object_unref (settings); --} -- --/* GtkWidget::map method */ --static void --gtk_file_chooser_default_map (GtkWidget *widget) --{ -- GtkFileChooserDefault *impl; -- char *current_working_dir; -- -- profile_start ("start", NULL); -- -- impl = GTK_FILE_CHOOSER_DEFAULT (widget); -- -- GTK_WIDGET_CLASS (_gtk_file_chooser_default_parent_class)->map (widget); -- + _gtk_file_chooser_settings_set_show_hidden (settings, gtk_file_chooser_get_show_hidden (GTK_FILE_CHOOSER (impl))); + _gtk_file_chooser_settings_set_expand_folders (settings, impl->expand_folders); + +@@ -6143,44 +2343,32 @@ + + GTK_WIDGET_CLASS (_gtk_file_chooser_default_parent_class)->map (widget); + - if (impl->operation_mode == OPERATION_MODE_BROWSE) -- { ++ switch (impl->reload_state) + { - switch (impl->reload_state) - { - case RELOAD_EMPTY: @@ -6660,7 +5425,13 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - * don't need to reload - */ - break; -- ++ 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_WAS_UNMAPPED: - /* Just reload the current folder; else continue - * the pending load. @@ -6671,543 +5442,148 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - change_folder_and_display_error (impl, impl->current_folder, FALSE); - } - break; -- ++ case RELOAD_HAS_FOLDER: ++ /* Nothing; we are already loading or loaded, so we don't need to reload */ ++ break; + - default: - g_assert_not_reached (); - } -- } -- ++ case RELOAD_WAS_UNMAPPED: ++ /* Just reload the current folder; else continue the pending load. */ ++ if (impl->current_folder) ++ { ++ 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); - -- settings_load (impl); -- -- profile_end ("end", NULL); --} -- --/* GtkWidget::unmap method */ --static void --gtk_file_chooser_default_unmap (GtkWidget *widget) --{ -- GtkFileChooserDefault *impl; -- -- impl = GTK_FILE_CHOOSER_DEFAULT (widget); -- -- settings_save (impl); -- -- GTK_WIDGET_CLASS (_gtk_file_chooser_default_parent_class)->unmap (widget); -- -- impl->reload_state = RELOAD_WAS_UNMAPPED; --} -- --static gboolean --list_model_filter_func (GtkFileSystemModel *model, -- GtkFilePath *path, -- const GtkFileInfo *file_info, -- gpointer user_data) --{ -- GtkFileChooserDefault *impl = user_data; -- -- if (!impl->current_filter) -- return TRUE; -- -- if (gtk_file_info_get_is_folder (file_info)) -- return TRUE; -- -- return !get_is_file_filtered (impl, path, (GtkFileInfo *) file_info); --} -- --static void --install_list_model_filter (GtkFileChooserDefault *impl) --{ -- GtkFileSystemModelFilter filter; -- gpointer data; -- -- g_assert (impl->browse_files_model != NULL); -- -- if (impl->current_filter) -- { -- filter = list_model_filter_func; -- data = impl; -- } -- else -- { -- filter = NULL; -- data = NULL; -- } -- -- _gtk_file_system_model_set_filter (impl->browse_files_model, -- filter, -- data); --} -- --#define COMPARE_DIRECTORIES \ -- GtkFileChooserDefault *impl = user_data; \ + settings_load (impl); + + profile_end ("end", NULL); +@@ -6244,8 +2432,8 @@ + + #define COMPARE_DIRECTORIES \ + GtkFileChooserDefault *impl = user_data; \ - const GtkFileInfo *info_a = _gtk_file_system_model_get_info (impl->browse_files_model, a); \ - const GtkFileInfo *info_b = _gtk_file_system_model_get_info (impl->browse_files_model, b); \ -- gboolean dir_a, dir_b; \ -- \ -- if (info_a) \ -- dir_a = gtk_file_info_get_is_folder (info_a); \ -- else \ -- return impl->list_sort_ascending ? -1 : 1; \ -- \ -- if (info_b) \ -- dir_b = gtk_file_info_get_is_folder (info_b); \ -- else \ -- return impl->list_sort_ascending ? 1 : -1; \ -- \ -- if (dir_a != dir_b) \ -- return impl->list_sort_ascending ? (dir_a ? -1 : 1) : (dir_a ? 1 : -1) /* Directories *always* go first */ -- --/* Sort callback for the filename column */ --static gint --name_sort_func (GtkTreeModel *model, -- GtkTreeIter *a, -- GtkTreeIter *b, -- gpointer user_data) --{ -- COMPARE_DIRECTORIES; -- else -- return strcmp (gtk_file_info_get_display_key (info_a), gtk_file_info_get_display_key (info_b)); --} -- --/* Sort callback for the size column */ --static gint --size_sort_func (GtkTreeModel *model, -- GtkTreeIter *a, -- GtkTreeIter *b, -- gpointer user_data) --{ -- COMPARE_DIRECTORIES; -- else -- { -- gint64 size_a = gtk_file_info_get_size (info_a); -- gint64 size_b = gtk_file_info_get_size (info_b); -- -- return size_a > size_b ? -1 : (size_a == size_b ? 0 : 1); -- } --} -- --/* Sort callback for the mtime column */ --static gint --mtime_sort_func (GtkTreeModel *model, -- GtkTreeIter *a, -- GtkTreeIter *b, -- gpointer user_data) --{ -- COMPARE_DIRECTORIES; -- else -- { -- GtkFileTime ta = gtk_file_info_get_modification_time (info_a); -- GtkFileTime tb = gtk_file_info_get_modification_time (info_b); -- -- return ta > tb ? -1 : (ta == tb ? 0 : 1); -- } --} -- --/* Callback used when the sort column changes. We cache the sort order for use -- * in name_sort_func(). -- */ --static void --list_sort_column_changed_cb (GtkTreeSortable *sortable, -- GtkFileChooserDefault *impl) --{ -- GtkSortType sort_type; -- -- if (gtk_tree_sortable_get_sort_column_id (sortable, NULL, &sort_type)) -- impl->list_sort_ascending = (sort_type == GTK_SORT_ASCENDING); --} -- --static void --set_busy_cursor (GtkFileChooserDefault *impl, -- gboolean busy) --{ -- GtkWindow *toplevel; -- GdkDisplay *display; -- GdkCursor *cursor; -- -- toplevel = get_toplevel (GTK_WIDGET (impl)); -- if (!toplevel || !GTK_WIDGET_REALIZED (toplevel)) -- return; -- -- display = gtk_widget_get_display (GTK_WIDGET (toplevel)); -- -- if (busy) -- cursor = gdk_cursor_new_for_display (display, GDK_WATCH); -- else -- cursor = NULL; -- -- gdk_window_set_cursor (GTK_WIDGET (toplevel)->window, cursor); -- gdk_display_flush (display); -- -- if (cursor) -- gdk_cursor_unref (cursor); --} -- --/* Creates a sort model to wrap the file system model and sets it on the tree view */ --static void --load_set_model (GtkFileChooserDefault *impl) --{ -- profile_start ("start", NULL); -- -- g_assert (impl->browse_files_model != NULL); -- g_assert (impl->sort_model == NULL); -- -- profile_msg (" gtk_tree_model_sort_new_with_model start", NULL); -- impl->sort_model = (GtkTreeModelSort *)gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (impl->browse_files_model)); -- gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (impl->sort_model), FILE_LIST_COL_NAME, name_sort_func, impl, NULL); -- gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (impl->sort_model), FILE_LIST_COL_SIZE, size_sort_func, impl, NULL); -- gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (impl->sort_model), FILE_LIST_COL_MTIME, mtime_sort_func, impl, NULL); -- gtk_tree_sortable_set_default_sort_func (GTK_TREE_SORTABLE (impl->sort_model), NULL, NULL, NULL); -- gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (impl->sort_model), FILE_LIST_COL_NAME, GTK_SORT_ASCENDING); -- impl->list_sort_ascending = TRUE; -- profile_msg (" gtk_tree_model_sort_new_with_model end", NULL); -- -- g_signal_connect (impl->sort_model, "sort_column_changed", -- G_CALLBACK (list_sort_column_changed_cb), impl); -- -- profile_msg (" gtk_tree_view_set_model start", NULL); -- gtk_tree_view_set_model (GTK_TREE_VIEW (impl->browse_files_tree_view), -- GTK_TREE_MODEL (impl->sort_model)); -- gtk_tree_view_columns_autosize (GTK_TREE_VIEW (impl->browse_files_tree_view)); -- gtk_tree_view_set_search_column (GTK_TREE_VIEW (impl->browse_files_tree_view), -- GTK_FILE_SYSTEM_MODEL_DISPLAY_NAME); -- profile_msg (" gtk_tree_view_set_model end", NULL); -- -- profile_end ("end", NULL); --} -- --/* Timeout callback used when the loading timer expires */ --static gboolean --load_timeout_cb (gpointer data) --{ -- GtkFileChooserDefault *impl; -- -- profile_start ("start", NULL); -- -- impl = GTK_FILE_CHOOSER_DEFAULT (data); -- g_assert (impl->load_state == LOAD_PRELOAD); -- g_assert (impl->load_timeout_id != 0); -- g_assert (impl->browse_files_model != NULL); -- -- impl->load_timeout_id = 0; -- impl->load_state = LOAD_LOADING; -- -- load_set_model (impl); -- -- profile_end ("end", NULL); -- -- return FALSE; --} -- --/* Sets up a new load timer for the model and switches to the LOAD_PRELOAD state */ --static void --load_setup_timer (GtkFileChooserDefault *impl) --{ -- g_assert (impl->load_timeout_id == 0); -- g_assert (impl->load_state != LOAD_PRELOAD); -- ++ const GtkFileInfo *info_a = _gtk_file_system_model_get_info (impl->browse_files_model, a); \ ++ const GtkFileInfo *info_b = _gtk_file_system_model_get_info (impl->browse_files_model, b); \ + gboolean dir_a, dir_b; \ + \ + if (info_a) \ +@@ -6387,6 +2575,8 @@ + + profile_start ("start", NULL); + ++ GDK_THREADS_ENTER (); ++ + impl = GTK_FILE_CHOOSER_DEFAULT (data); + g_assert (impl->load_state == LOAD_PRELOAD); + g_assert (impl->load_timeout_id != 0); +@@ -6397,6 +2587,8 @@ + + load_set_model (impl); + ++ GDK_THREADS_LEAVE (); ++ + profile_end ("end", NULL); + + return FALSE; +@@ -6409,7 +2601,7 @@ + g_assert (impl->load_timeout_id == 0); + g_assert (impl->load_state != LOAD_PRELOAD); + - impl->load_timeout_id = gdk_threads_add_timeout (MAX_LOADING_TIME, load_timeout_cb, impl); -- impl->load_state = LOAD_PRELOAD; --} -- --/* Removes the load timeout and switches to the LOAD_FINISHED state */ --static void --load_remove_timer (GtkFileChooserDefault *impl) --{ -- if (impl->load_timeout_id != 0) -- { -- g_assert (impl->load_state == LOAD_PRELOAD); -- -- g_source_remove (impl->load_timeout_id); -- impl->load_timeout_id = 0; -- impl->load_state = LOAD_EMPTY; -- } -- else -- g_assert (impl->load_state == LOAD_EMPTY || -- impl->load_state == LOAD_LOADING || -- impl->load_state == LOAD_FINISHED); --} -- --/* Selects the first row in the file list */ --static void --browse_files_select_first_row (GtkFileChooserDefault *impl) --{ -- GtkTreePath *path; -- -- if (!impl->sort_model) -- return; -- -- path = gtk_tree_path_new_from_indices (0, -1); -- gtk_tree_view_set_cursor (GTK_TREE_VIEW (impl->browse_files_tree_view), path, NULL, FALSE); -- gtk_tree_path_free (path); --} -- --struct center_selected_row_closure { -- GtkFileChooserDefault *impl; -- gboolean already_centered; --}; -- --/* Callback used from gtk_tree_selection_selected_foreach(); centers the -- * selected row in the tree view. -- */ --static void --center_selected_row_foreach_cb (GtkTreeModel *model, -- GtkTreePath *path, -- GtkTreeIter *iter, -- gpointer data) --{ -- struct center_selected_row_closure *closure; -- -- closure = data; -- if (closure->already_centered) -- return; -- -- gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (closure->impl->browse_files_tree_view), path, NULL, TRUE, 0.5, 0.0); -- closure->already_centered = TRUE; --} -- --/* Centers the selected row in the tree view */ --static void --browse_files_center_selected_row (GtkFileChooserDefault *impl) --{ -- struct center_selected_row_closure closure; -- GtkTreeSelection *selection; -- -- closure.impl = impl; -- closure.already_centered = FALSE; -- -- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_files_tree_view)); -- gtk_tree_selection_selected_foreach (selection, center_selected_row_foreach_cb, &closure); --} -- --struct ShowAndSelectPathsData --{ -- GtkFileChooserDefault *impl; -- GSList *paths; --}; -- --static void --show_and_select_paths_finished_loading (GtkFileFolder *folder, -- gpointer user_data) --{ -- gboolean have_hidden; ++ impl->load_timeout_id = g_timeout_add (MAX_LOADING_TIME, load_timeout_cb, impl); + impl->load_state = LOAD_PRELOAD; + } + +@@ -6494,12 +2686,10 @@ + gpointer user_data) + { + gboolean have_hidden; - gboolean have_filtered; -- GSList *l; -- struct ShowAndSelectPathsData *data = user_data; -- -- have_hidden = FALSE; + GSList *l; + struct ShowAndSelectPathsData *data = user_data; + + have_hidden = FALSE; - have_filtered = FALSE; -- -- for (l = data->paths; l; l = l->next) -- { -- const GtkFilePath *path; -- GtkFileInfo *info; -- -- path = l->data; -- -- /* NULL GError */ -- info = gtk_file_folder_get_info (folder, path, NULL); -- if (info) -- { -- if (!have_hidden) -- have_hidden = gtk_file_info_get_is_hidden (info); -- + + for (l = data->paths; l; l = l->next) + { +@@ -6515,12 +2705,9 @@ + if (!have_hidden) + have_hidden = gtk_file_info_get_is_hidden (info); + - if (!have_filtered) - have_filtered = !gtk_file_info_get_is_folder (info) && get_is_file_filtered (data->impl, path, info); - -- gtk_file_info_free (info); -- + gtk_file_info_free (info); + - if (have_hidden && have_filtered) -- break; /* we now have all the information we need */ -- } -- } -- -- g_signal_handlers_disconnect_by_func (folder, -- show_and_select_paths_finished_loading, -- user_data); -- -- g_object_unref (folder); -- -- if (have_hidden) -- g_object_set (data->impl, "show-hidden", TRUE, NULL); -- ++ if (have_hidden) + break; /* we now have all the information we need */ + } + } +@@ -6534,9 +2721,6 @@ + if (have_hidden) + g_object_set (data->impl, "show-hidden", TRUE, NULL); + - if (have_filtered) - set_current_filter (data->impl, NULL); - -- for (l = data->paths; l; l = l->next) -- { -- const GtkFilePath *path; -- -- path = l->data; -- _gtk_file_system_model_path_do (data->impl->browse_files_model, path, -- select_func, data->impl); -- } -- -- browse_files_center_selected_row (data->impl); -- -- g_object_unref (data->impl); -- gtk_file_paths_free (data->paths); -- g_free (data); --} -- --static void --show_and_select_paths_get_folder_cb (GtkFileSystemHandle *handle, -- GtkFileFolder *folder, -- const GError *error, -- gpointer user_data) --{ -- gboolean cancelled = handle->cancelled; -- struct ShowAndSelectPathsData *data = user_data; -- -- if (data->impl->show_and_select_paths_handle != handle) -- goto out; -- -- data->impl->show_and_select_paths_handle = NULL; -- -- if (cancelled || error) -- goto out; -- -- g_object_unref (handle); -- -- if (gtk_file_folder_is_finished_loading (folder)) -- show_and_select_paths_finished_loading (folder, user_data); -- else -- g_signal_connect (folder, "finished-loading", -- G_CALLBACK (show_and_select_paths_finished_loading), -- user_data); -- -- return; -- --out: -- g_object_unref (data->impl); -- gtk_file_paths_free (data->paths); -- g_free (data); -- -- g_object_unref (handle); --} -- --static gboolean --show_and_select_paths (GtkFileChooserDefault *impl, -- const GtkFilePath *parent_path, -- GSList *paths, -- GError **error) --{ -- struct ShowAndSelectPathsData *info; -- -- profile_start ("start", NULL); -- -- if (!paths) -- { -- profile_end ("end", NULL); -- return TRUE; -- } -- -- info = g_new (struct ShowAndSelectPathsData, 1); -- info->impl = g_object_ref (impl); -- info->paths = gtk_file_paths_copy (paths); -- -- if (impl->show_and_select_paths_handle) -- gtk_file_system_cancel_operation (impl->show_and_select_paths_handle); -- -- impl->show_and_select_paths_handle = -- gtk_file_system_get_folder (impl->file_system, parent_path, -- GTK_FILE_INFO_IS_FOLDER | GTK_FILE_INFO_IS_HIDDEN, -- show_and_select_paths_get_folder_cb, info); -- -- profile_end ("end", NULL); -- return TRUE; --} -- --/* Processes the pending operation when a folder is finished loading */ --static void --pending_select_paths_process (GtkFileChooserDefault *impl) --{ -- g_assert (impl->load_state == LOAD_FINISHED); -- g_assert (impl->browse_files_model != NULL); -- g_assert (impl->sort_model != NULL); -- -- if (impl->pending_select_paths) -- { -- /* NULL GError */ -- show_and_select_paths (impl, impl->current_folder, impl->pending_select_paths, NULL); -- pending_select_paths_free (impl); -- browse_files_center_selected_row (impl); -- } -- else -- { -- /* We only select the first row if the chooser is actually mapped --- -- * selecting the first row is to help the user when he is interacting with -- * the chooser, but sometimes a chooser works not on behalf of the user, -- * but rather on behalf of something else like GtkFileChooserButton. In -- * that case, the chooser's selection should be what the caller expects, -- * as the user can't see that something else got selected. See bug #165264. -- */ -- if (GTK_WIDGET_MAPPED (impl) && impl->action == GTK_FILE_CHOOSER_ACTION_OPEN) -- browse_files_select_first_row (impl); -- } -- -- g_assert (impl->pending_select_paths == NULL); --} -- --/* Callback used when the file system model finishes loading */ --static void --browse_files_model_finished_loading_cb (GtkFileSystemModel *model, -- GtkFileChooserDefault *impl) --{ -- profile_start ("start", NULL); -- -- if (impl->load_state == LOAD_PRELOAD) -- { -- load_remove_timer (impl); -- load_set_model (impl); -- } -- else if (impl->load_state == LOAD_LOADING) -- { -- /* Nothing */ -- } -- else -- { -- /* We can't g_assert_not_reached(), as something other than us may have -- * initiated a folder reload. See #165556. -- */ -- profile_end ("end", NULL); -- return; -- } -- -- g_assert (impl->load_timeout_id == 0); -- -- impl->load_state = LOAD_FINISHED; -- -- pending_select_paths_process (impl); -- set_busy_cursor (impl, FALSE); --#ifdef PROFILE_FILE_CHOOSER -- access ("MARK: *** FINISHED LOADING", F_OK); --#endif -- -- profile_end ("end", NULL); --} -- + for (l = data->paths; l; l = l->next) + { + const GtkFilePath *path; +@@ -6644,6 +2828,12 @@ + * but rather on behalf of something else like GtkFileChooserButton. In + * that case, the chooser's selection should be what the caller expects, + * as the user can't see that something else got selected. See bug #165264. ++ * ++ * Also, we don't select the first file if we are not in OPEN mode. Doing ++ * so would change the contents of the filename entry for SAVE or ++ * CREATE_FOLDER, which is undesired; in SELECT_FOLDER, we don't want to ++ * select a *different* folder from the one into which the user just ++ * navigated. + */ + if (GTK_WIDGET_MAPPED (impl) && impl->action == GTK_FILE_CHOOSER_ACTION_OPEN) + browse_files_select_first_row (impl); +@@ -6690,11 +2880,17 @@ + profile_end ("end", NULL); + } + -static void -stop_loading_and_clear_list_model (GtkFileChooserDefault *impl) --{ -- load_remove_timer (impl); /* This changes the state to LOAD_EMPTY */ ++/* Gets rid of the old list model and creates a new one for the current folder */ ++static gboolean ++set_list_model (GtkFileChooserDefault *impl, ++ GError **error) + { ++ g_assert (impl->current_folder != NULL); ++ ++ profile_start ("start", NULL); ++ + load_remove_timer (impl); /* This changes the state to LOAD_EMPTY */ - -- if (impl->browse_files_model) -- { -- g_object_unref (impl->browse_files_model); -- impl->browse_files_model = NULL; -- } -- -- if (impl->sort_model) -- { -- g_object_unref (impl->sort_model); -- impl->sort_model = NULL; -- } ++ + if (impl->browse_files_model) + { + g_object_unref (impl->browse_files_model); +@@ -6706,21 +2902,7 @@ + g_object_unref (impl->sort_model); + impl->sort_model = NULL; + } - - gtk_tree_view_set_model (GTK_TREE_VIEW (impl->browse_files_tree_view), NULL); -} -- + -/* Gets rid of the old list model and creates a new one for the current folder */ -static gboolean -set_list_model (GtkFileChooserDefault *impl, @@ -7219,296 +5595,121 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - - stop_loading_and_clear_list_model (impl); - -- set_busy_cursor (impl, TRUE); -- gtk_tree_view_set_model (GTK_TREE_VIEW (impl->browse_files_tree_view), NULL); -- -- impl->browse_files_model = _gtk_file_system_model_new (impl->file_system, -- impl->current_folder, 0, -- GTK_FILE_INFO_ALL, -- error); -- if (!impl->browse_files_model) -- { -- set_busy_cursor (impl, FALSE); -- profile_end ("end", NULL); -- return FALSE; -- } -- -- load_setup_timer (impl); /* This changes the state to LOAD_PRELOAD */ -- -- g_signal_connect (impl->browse_files_model, "finished-loading", -- G_CALLBACK (browse_files_model_finished_loading_cb), impl); -- -- _gtk_file_system_model_set_show_hidden (impl->browse_files_model, impl->show_hidden); -- -- install_list_model_filter (impl); -- -- profile_end ("end", NULL); -- -- return TRUE; --} -- --struct update_chooser_entry_selected_foreach_closure { -- int num_selected; -- GtkTreeIter first_selected_iter; --}; -- --static gint --compare_utf8_filenames (const gchar *a, -- const gchar *b) --{ -- gchar *a_folded, *b_folded; -- gint retval; -- -- a_folded = g_utf8_strdown (a, -1); -- b_folded = g_utf8_strdown (b, -1); -- -- retval = strcmp (a_folded, b_folded); -- -- g_free (a_folded); -- g_free (b_folded); -- -- return retval; --} -- --static void --update_chooser_entry_selected_foreach (GtkTreeModel *model, -- GtkTreePath *path, -- GtkTreeIter *iter, -- gpointer data) --{ -- struct update_chooser_entry_selected_foreach_closure *closure; -- -- closure = data; -- closure->num_selected++; -- -- if (closure->num_selected == 1) -- closure->first_selected_iter = *iter; --} -- --static void --update_chooser_entry (GtkFileChooserDefault *impl) --{ -- GtkTreeSelection *selection; -- struct update_chooser_entry_selected_foreach_closure closure; -- const char *file_part; -- + set_busy_cursor (impl, TRUE); + gtk_tree_view_set_model (GTK_TREE_VIEW (impl->browse_files_tree_view), NULL); + +@@ -6794,17 +2976,10 @@ + struct update_chooser_entry_selected_foreach_closure closure; + const char *file_part; + - /* no need to update the file chooser's entry if there's no entry */ - if (impl->operation_mode == OPERATION_MODE_SEARCH || - impl->operation_mode == OPERATION_MODE_RECENT || - !impl->location_entry) - return; - -- if (!(impl->action == GTK_FILE_CHOOSER_ACTION_SAVE -- || impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER + if (!(impl->action == GTK_FILE_CHOOSER_ACTION_SAVE + || impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER - || ((impl->action == GTK_FILE_CHOOSER_ACTION_OPEN - || impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER) - && impl->location_mode == LOCATION_MODE_FILENAME_ENTRY))) -- return; -- -- g_assert (impl->location_entry != NULL); -- -- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_files_tree_view)); -- closure.num_selected = 0; -- gtk_tree_selection_selected_foreach (selection, update_chooser_entry_selected_foreach, &closure); -- -- file_part = NULL; -- -- if (closure.num_selected == 0) -- { -- goto maybe_clear_entry; -- } -- else if (closure.num_selected == 1) -- { -- GtkTreeIter child_iter; ++ || impl->action == GTK_FILE_CHOOSER_ACTION_OPEN ++ || impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER)) + return; + + g_assert (impl->location_entry != NULL); +@@ -6822,45 +2997,39 @@ + else if (closure.num_selected == 1) + { + GtkTreeIter child_iter; - - if (impl->operation_mode == OPERATION_MODE_BROWSE) - { - const GtkFileInfo *info; - gboolean change_entry; -- ++ const GtkFileInfo *info; ++ gboolean change_entry; + - gtk_tree_model_sort_convert_iter_to_child_iter (impl->sort_model, - &child_iter, - &closure.first_selected_iter); -- ++ gtk_tree_model_sort_convert_iter_to_child_iter (impl->sort_model, ++ &child_iter, ++ &closure.first_selected_iter); + - info = _gtk_file_system_model_get_info (impl->browse_files_model, &child_iter); -- ++ info = _gtk_file_system_model_get_info (impl->browse_files_model, &child_iter); + - /* If the cursor moved to the row of the newly created folder, - * retrieving info will return NULL. - */ - if (!info) - return; -- ++ /* If the cursor moved to the row of the newly created folder, ++ * retrieving info will return NULL. ++ */ ++ if (!info) ++ return; + - g_free (impl->browse_files_last_selected_name); - impl->browse_files_last_selected_name = - g_strdup (gtk_file_info_get_display_name (info)); -- ++ g_free (impl->browse_files_last_selected_name); ++ impl->browse_files_last_selected_name = g_strdup (gtk_file_info_get_display_name (info)); + - if (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN || - impl->action == GTK_FILE_CHOOSER_ACTION_SAVE) - change_entry = !gtk_file_info_get_is_folder (info); /* We don't want the name to change when clicking on a folder... */ - else - change_entry = TRUE; /* ... unless we are in one of the folder modes */ -- ++ if (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN ++ || impl->action == GTK_FILE_CHOOSER_ACTION_SAVE) ++ change_entry = !gtk_file_info_get_is_folder (info); /* We don't want the name to change when clicking on a folder... */ ++ else ++ change_entry = TRUE; /* ... unless we are in one of the folder modes */ + - if (change_entry) - _gtk_file_chooser_entry_set_file_part (GTK_FILE_CHOOSER_ENTRY (impl->location_entry), - impl->browse_files_last_selected_name); -- ++ if (change_entry) ++ _gtk_file_chooser_entry_set_file_part (GTK_FILE_CHOOSER_ENTRY (impl->location_entry), impl->browse_files_last_selected_name); + - return; - } -- } -- else -- { ++ return; + } + else + { - g_assert (!(impl->action == GTK_FILE_CHOOSER_ACTION_SAVE || - impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)); -- -- /* Multiple selection, so just clear the entry. */ -- -- g_free (impl->browse_files_last_selected_name); -- impl->browse_files_last_selected_name = NULL; -- -- _gtk_file_chooser_entry_set_file_part (GTK_FILE_CHOOSER_ENTRY (impl->location_entry), ""); -- return; -- } -- -- maybe_clear_entry: -- -- if (impl->browse_files_last_selected_name) -- { -- const char *entry_text; -- int len; -- gboolean clear_entry; -- -- entry_text = gtk_entry_get_text (GTK_ENTRY (impl->location_entry)); -- len = strlen (entry_text); -- if (len != 0) -- { -- /* The file chooser entry may have appended a "/" to its text. So -- * take it out, and compare the result to the old selection. -- */ -- if (entry_text[len - 1] == G_DIR_SEPARATOR) -- { -- char *tmp; -- -- tmp = g_strndup (entry_text, len - 1); -- clear_entry = (compare_utf8_filenames (impl->browse_files_last_selected_name, tmp) == 0); -- g_free (tmp); -- } -- else -- clear_entry = (compare_utf8_filenames (impl->browse_files_last_selected_name, entry_text) == 0); -- } -- else -- clear_entry = FALSE; -- -- if (clear_entry) -- _gtk_file_chooser_entry_set_file_part (GTK_FILE_CHOOSER_ENTRY (impl->location_entry), ""); -- } --} -- --static gboolean --gtk_file_chooser_default_set_current_folder (GtkFileChooser *chooser, -- const GtkFilePath *path, -- GError **error) --{ -- return gtk_file_chooser_default_update_current_folder (chooser, path, FALSE, FALSE, error); --} -- -- --struct UpdateCurrentFolderData --{ -- GtkFileChooserDefault *impl; -- GtkFilePath *path; -- gboolean keep_trail; -- gboolean clear_entry; -- GtkFilePath *original_path; -- GError *original_error; --}; -- --static void --update_current_folder_get_info_cb (GtkFileSystemHandle *handle, -- const GtkFileInfo *info, -- const GError *error, -- gpointer user_data) --{ -- gboolean cancelled = handle->cancelled; -- struct UpdateCurrentFolderData *data = user_data; -- GtkFileChooserDefault *impl = data->impl; -- -- if (handle != impl->update_current_folder_handle) -- goto out; -- -- impl->update_current_folder_handle = NULL; -- impl->reload_state = RELOAD_EMPTY; -- -- set_busy_cursor (impl, FALSE); -- -- if (cancelled) -- goto out; -- -- if (error) -- { -- GtkFilePath *parent_path; -- -- if (!data->original_path) -- { -- data->original_path = gtk_file_path_copy (data->path); -- data->original_error = g_error_copy (error); -- } -- -- /* get parent path and try to change the folder to that */ -- if (gtk_file_system_get_parent (impl->file_system, data->path, &parent_path, NULL) && ++ g_assert (!(impl->action == GTK_FILE_CHOOSER_ACTION_SAVE ++ || impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)); + + /* Multiple selection, so just clear the entry. */ + +@@ -6957,7 +3126,7 @@ + + /* get parent path and try to change the folder to that */ + if (gtk_file_system_get_parent (impl->file_system, data->path, &parent_path, NULL) && - parent_path != NULL) -- { -- gtk_file_path_free (data->path); -- data->path = parent_path; -- -- g_object_unref (handle); -- -- /* restart the update current folder operation */ -- impl->reload_state = RELOAD_HAS_FOLDER; -- -- impl->update_current_folder_handle = -- gtk_file_system_get_info (impl->file_system, data->path, -- GTK_FILE_INFO_IS_FOLDER, -- update_current_folder_get_info_cb, -- data); -- -- set_busy_cursor (impl, TRUE); -- -- return; -- } -- else -- { -- /* error and bail out */ -- error_changing_folder_dialog (impl, data->original_path, data->original_error); -- -- gtk_file_path_free (data->original_path); -- -- goto out; -- } -- } -- -- if (data->original_path) -- { -- error_changing_folder_dialog (impl, data->original_path, data->original_error); -- -- gtk_file_path_free (data->original_path); -- } -- -- if (!gtk_file_info_get_is_folder (info)) -- goto out; -- ++ parent_path) + { + gtk_file_path_free (data->path); + data->path = parent_path; +@@ -6998,9 +3167,6 @@ + if (!gtk_file_info_get_is_folder (info)) + goto out; + - if (!_gtk_path_bar_set_path (GTK_PATH_BAR (impl->browse_path_bar), data->path, data->keep_trail, NULL)) - goto out; - -- if (impl->current_folder != data->path) -- { -- if (impl->current_folder) -- gtk_file_path_free (impl->current_folder); -- -- impl->current_folder = gtk_file_path_copy (data->path); -- -- impl->reload_state = RELOAD_HAS_FOLDER; -- } -- + if (impl->current_folder != data->path) + { + if (impl->current_folder) +@@ -7011,17 +3177,6 @@ + impl->reload_state = RELOAD_HAS_FOLDER; + } + - /* Update the widgets that may trigger a folder change themselves. */ - - if (!impl->changing_folder) @@ -7520,53 +5721,27 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - impl->changing_folder = FALSE; - } - -- /* Set the folder on the save entry */ -- -- if (impl->location_entry) -- { -- _gtk_file_chooser_entry_set_base_folder (GTK_FILE_CHOOSER_ENTRY (impl->location_entry), -- impl->current_folder); -- -- if (data->clear_entry) -- _gtk_file_chooser_entry_set_file_part (GTK_FILE_CHOOSER_ENTRY (impl->location_entry), ""); -- } -- -- /* Create a new list model. This is slightly evil; we store the result value -- * but perform more actions rather than returning immediately even if it -- * generates an error. -- */ -- set_list_model (impl, NULL); -- -- /* Refresh controls */ -- + /* Set the folder on the save entry */ + + if (impl->location_entry) +@@ -7041,13 +3196,7 @@ + + /* Refresh controls */ + - shortcuts_find_current_folder (impl); - -- g_signal_emit_by_name (impl, "current-folder-changed", 0); + g_signal_emit_by_name (impl, "current-folder-changed", 0); - - check_preview_change (impl); - bookmarks_check_add_sensitivity (impl); - -- g_signal_emit_by_name (impl, "selection-changed", 0); -- --out: -- gtk_file_path_free (data->path); -- g_free (data); -- -- g_object_unref (handle); --} -- --static gboolean --gtk_file_chooser_default_update_current_folder (GtkFileChooser *chooser, -- const GtkFilePath *path, -- gboolean keep_trail, -- gboolean clear_entry, -- GError **error) --{ -- GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (chooser); -- struct UpdateCurrentFolderData *data; -- -- profile_start ("start", (char *) path); -- + g_signal_emit_by_name (impl, "selection-changed", 0); + + out: +@@ -7069,18 +3218,6 @@ + + profile_start ("start", (char *) path); + - switch (impl->operation_mode) - { - case OPERATION_MODE_SEARCH: @@ -7579,214 +5754,53 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - break; - } - -- g_assert (path != NULL); -- -- if (impl->local_only && -- !gtk_file_system_path_is_local (impl->file_system, path)) -- { -- g_set_error (error, -- GTK_FILE_CHOOSER_ERROR, -- GTK_FILE_CHOOSER_ERROR_BAD_FILENAME, -- _("Cannot change to folder because it is not local")); -- -- profile_end ("end - not local", (char *) path); -- return FALSE; -- } -- -- if (impl->update_current_folder_handle) -- gtk_file_system_cancel_operation (impl->update_current_folder_handle); -- -- /* Test validity of path here. */ -- data = g_new0 (struct UpdateCurrentFolderData, 1); -- data->impl = impl; -- data->path = gtk_file_path_copy (path); -- data->keep_trail = keep_trail; -- data->clear_entry = clear_entry; -- -- impl->reload_state = RELOAD_HAS_FOLDER; -- -- impl->update_current_folder_handle = -- gtk_file_system_get_info (impl->file_system, path, GTK_FILE_INFO_IS_FOLDER, -- update_current_folder_get_info_cb, -- data); -- -- set_busy_cursor (impl, TRUE); -- -- profile_end ("end", NULL); -- return TRUE; --} -- --static GtkFilePath * --gtk_file_chooser_default_get_current_folder (GtkFileChooser *chooser) --{ -- GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (chooser); -- + g_assert (path != NULL); + + if (impl->local_only && +@@ -7123,10 +3260,6 @@ + { + GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (chooser); + - if (impl->operation_mode == OPERATION_MODE_SEARCH || - impl->operation_mode == OPERATION_MODE_RECENT) - return NULL; - -- if (impl->reload_state == RELOAD_EMPTY) -- { -- char *current_working_dir; -- GtkFilePath *path; -- -- /* We are unmapped, or we had an error while loading the last folder. We'll return -- * the $cwd since once we get (re)mapped, we'll load $cwd anyway unless the caller -- * explicitly calls set_current_folder() on us. -- */ -- current_working_dir = g_get_current_dir (); -- path = gtk_file_system_filename_to_path (impl->file_system, current_working_dir); -- g_free (current_working_dir); -- return path; -- } -- -- return gtk_file_path_copy (impl->current_folder); --} -- --static void --gtk_file_chooser_default_set_current_name (GtkFileChooser *chooser, -- const gchar *name) --{ -- GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (chooser); -- + if (impl->reload_state == RELOAD_EMPTY) + { + char *current_working_dir; +@@ -7151,8 +3284,8 @@ + { + GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (chooser); + - g_return_if_fail (impl->action == GTK_FILE_CHOOSER_ACTION_SAVE || - impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER); -- -- pending_select_paths_free (impl); -- _gtk_file_chooser_entry_set_file_part (GTK_FILE_CHOOSER_ENTRY (impl->location_entry), name); --} -- --static void --select_func (GtkFileSystemModel *model, -- GtkTreePath *path, -- GtkTreeIter *iter, -- gpointer user_data) --{ -- GtkFileChooserDefault *impl = user_data; -- GtkTreeSelection *selection; -- GtkTreeIter sorted_iter; -- -- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_files_tree_view)); -- -- gtk_tree_model_sort_convert_child_iter_to_iter (impl->sort_model, &sorted_iter, iter); -- gtk_tree_selection_select_iter (selection, &sorted_iter); --} -- --static gboolean --gtk_file_chooser_default_select_path (GtkFileChooser *chooser, -- const GtkFilePath *path, -- GError **error) --{ -- GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (chooser); -- GtkFilePath *parent_path; -- gboolean same_path; -- -- if (!gtk_file_system_get_parent (impl->file_system, path, &parent_path, error)) -- return FALSE; -- -- if (!parent_path) ++ g_return_if_fail (impl->action == GTK_FILE_CHOOSER_ACTION_SAVE ++ || impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER); + + pending_select_paths_free (impl); + _gtk_file_chooser_entry_set_file_part (GTK_FILE_CHOOSER_ENTRY (impl->location_entry), name); +@@ -7187,14 +3320,10 @@ + return FALSE; + + if (!parent_path) - return _gtk_file_chooser_set_current_folder_path (chooser, path, error); -- ++ return _gtk_file_chooser_set_current_folder_path (chooser, path, error); + - if (impl->operation_mode == OPERATION_MODE_SEARCH || - impl->operation_mode == OPERATION_MODE_RECENT || - impl->load_state == LOAD_EMPTY) - { - same_path = FALSE; - } -- else -- { -- g_assert (impl->current_folder != NULL); -- -- same_path = gtk_file_path_compare (parent_path, impl->current_folder) == 0; -- } -- -- if (same_path && impl->load_state == LOAD_FINISHED) -- { -- gboolean result; -- GSList paths; -- -- paths.data = (gpointer) path; -- paths.next = NULL; -- -- result = show_and_select_paths (impl, parent_path, &paths, error); -- gtk_file_path_free (parent_path); -- return result; -- } -- -- pending_select_paths_add (impl, path); -- -- if (!same_path) -- { -- gboolean result; -- -- result = _gtk_file_chooser_set_current_folder_path (chooser, parent_path, error); -- gtk_file_path_free (parent_path); -- return result; -- } -- -- gtk_file_path_free (parent_path); -- return TRUE; --} -- --static void --unselect_func (GtkFileSystemModel *model, -- GtkTreePath *path, -- GtkTreeIter *iter, -- gpointer user_data) --{ -- GtkFileChooserDefault *impl = user_data; -- GtkTreeView *tree_view = GTK_TREE_VIEW (impl->browse_files_tree_view); -- GtkTreePath *sorted_path; -- -- sorted_path = gtk_tree_model_sort_convert_child_path_to_path (impl->sort_model, -- path); -- gtk_tree_selection_unselect_path (gtk_tree_view_get_selection (tree_view), -- sorted_path); -- gtk_tree_path_free (sorted_path); --} -- --static void --gtk_file_chooser_default_unselect_path (GtkFileChooser *chooser, -- const GtkFilePath *path) --{ -- GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (chooser); -- -- if (!impl->browse_files_model) -- return; -- -- _gtk_file_system_model_path_do (impl->browse_files_model, path, -- unselect_func, impl); --} -- --static gboolean --maybe_select (GtkTreeModel *model, -- GtkTreePath *path, -- GtkTreeIter *iter, -- gpointer data) --{ -- GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (data); -- GtkTreeSelection *selection; -- const GtkFileInfo *info; -- gboolean is_folder; -- -- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_files_tree_view)); -- -- info = get_list_file_info (impl, iter); -- is_folder = gtk_file_info_get_is_folder (info); -- -- if ((is_folder && impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER) || -- (!is_folder && impl->action == GTK_FILE_CHOOSER_ACTION_OPEN)) -- gtk_tree_selection_select_iter (selection, iter); -- else -- gtk_tree_selection_unselect_iter (selection, iter); -- -- return FALSE; --} -- --static void --gtk_file_chooser_default_select_all (GtkFileChooser *chooser) --{ -- GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (chooser); ++ if (impl->load_state == LOAD_EMPTY) ++ same_path = FALSE; + else + { + g_assert (impl->current_folder != NULL); +@@ -7289,17 +3418,6 @@ + gtk_file_chooser_default_select_all (GtkFileChooser *chooser) + { + GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (chooser); - - if (impl->operation_mode == OPERATION_MODE_SEARCH || - impl->operation_mode == OPERATION_MODE_RECENT) @@ -7798,274 +5812,54 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - return; - } - -- if (impl->select_multiple) -- gtk_tree_model_foreach (GTK_TREE_MODEL (impl->sort_model), -- maybe_select, impl); --} -- --static void --gtk_file_chooser_default_unselect_all (GtkFileChooser *chooser) --{ -- GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (chooser); -- GtkTreeSelection *selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_files_tree_view)); -- -- gtk_tree_selection_unselect_all (selection); -- pending_select_paths_free (impl); --} -- --/* Checks whether the filename entry for the Save modes contains a well-formed filename. -- * -- * is_well_formed_ret - whether what the user typed passes gkt_file_system_make_path() -- * -- * is_empty_ret - whether the file entry is totally empty -- * -- * is_file_part_empty_ret - whether the file part is empty (will be if user types "foobar/", and -- * the path will be "$cwd/foobar") -- */ --static void --check_save_entry (GtkFileChooserDefault *impl, -- GtkFilePath **path_ret, -- gboolean *is_well_formed_ret, -- gboolean *is_empty_ret, -- gboolean *is_file_part_empty_ret, -- gboolean *is_folder) --{ -- GtkFileChooserEntry *chooser_entry; -- const GtkFilePath *current_folder; -- const char *file_part; -- GtkFilePath *path; -- GError *error; -- -- g_assert (impl->action == GTK_FILE_CHOOSER_ACTION_SAVE -- || impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER + if (impl->select_multiple) + gtk_tree_model_foreach (GTK_TREE_MODEL (impl->sort_model), + maybe_select, impl); +@@ -7340,9 +3458,8 @@ + + g_assert (impl->action == GTK_FILE_CHOOSER_ACTION_SAVE + || impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER - || ((impl->action == GTK_FILE_CHOOSER_ACTION_OPEN - || impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER) - && impl->location_mode == LOCATION_MODE_FILENAME_ENTRY)); -- -- chooser_entry = GTK_FILE_CHOOSER_ENTRY (impl->location_entry); -- -- if (strlen (gtk_entry_get_text (GTK_ENTRY (chooser_entry))) == 0) -- { -- *path_ret = NULL; -- *is_well_formed_ret = TRUE; -- *is_empty_ret = TRUE; -- *is_file_part_empty_ret = TRUE; -- *is_folder = FALSE; -- -- return; -- } -- -- *is_empty_ret = FALSE; -- -- current_folder = _gtk_file_chooser_entry_get_current_folder (chooser_entry); -- if (!current_folder) -- { -- *path_ret = NULL; -- *is_well_formed_ret = FALSE; -- *is_file_part_empty_ret = FALSE; -- *is_folder = FALSE; -- -- return; -- } -- -- file_part = _gtk_file_chooser_entry_get_file_part (chooser_entry); -- -- if (!file_part || file_part[0] == '\0') -- { -- *path_ret = gtk_file_path_copy (current_folder); -- *is_well_formed_ret = TRUE; -- *is_file_part_empty_ret = TRUE; -- *is_folder = TRUE; -- -- return; -- } -- -- *is_file_part_empty_ret = FALSE; -- -- error = NULL; -- path = gtk_file_system_make_path (impl->file_system, current_folder, file_part, &error); -- -- if (!path) -- { -- error_building_filename_dialog (impl, current_folder, file_part, error); -- *path_ret = NULL; -- *is_well_formed_ret = FALSE; -- *is_folder = FALSE; -- -- return; -- } -- -- *path_ret = path; -- *is_well_formed_ret = TRUE; -- *is_folder = _gtk_file_chooser_entry_get_is_folder (chooser_entry, path); --} -- --struct get_paths_closure { -- GtkFileChooserDefault *impl; -- GSList *result; -- GtkFilePath *path_from_entry; --}; -- --static void --get_paths_foreach (GtkTreeModel *model, -- GtkTreePath *path, -- GtkTreeIter *iter, -- gpointer data) --{ -- struct get_paths_closure *info; -- const GtkFilePath *file_path; -- GtkFileSystemModel *fs_model; -- GtkTreeIter sel_iter; -- -- info = data; -- fs_model = info->impl->browse_files_model; -- gtk_tree_model_sort_convert_iter_to_child_iter (info->impl->sort_model, &sel_iter, iter); -- -- file_path = _gtk_file_system_model_get_path (fs_model, &sel_iter); -- if (!file_path) -- return; /* We are on the editable row */ -+ case GTK_FILE_CHOOSER_PROP_FILTER: -+ g_value_set_object (value, impl->current_filter); -+ break; ++ || impl->action == GTK_FILE_CHOOSER_ACTION_OPEN ++ || impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER); -- if (!info->path_from_entry -- || gtk_file_path_compare (info->path_from_entry, file_path) != 0) -- info->result = g_slist_prepend (info->result, gtk_file_path_copy (file_path)); --} -+ case GTK_FILE_CHOOSER_PROP_LOCAL_ONLY: -+ g_value_set_boolean (value, impl->local_only); -+ break; + chooser_entry = GTK_FILE_CHOOSER_ENTRY (impl->location_entry); --static GSList * --gtk_file_chooser_default_get_paths (GtkFileChooser *chooser) --{ -- GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (chooser); -- struct get_paths_closure info; -- GtkWindow *toplevel; -- GtkWidget *current_focus; +@@ -7439,14 +3556,7 @@ + struct get_paths_closure info; + GtkWindow *toplevel; + GtkWidget *current_focus; - gboolean file_list_seen; -+ case GTK_FILE_CHOOSER_PROP_SELECT_MULTIPLE: -+ g_value_set_boolean (value, impl->select_multiple); -+ break; - if (impl->operation_mode == OPERATION_MODE_SEARCH) - return search_get_selected_paths (impl); -+ case GTK_FILE_CHOOSER_PROP_SHOW_HIDDEN: -+ g_value_set_boolean (value, impl->show_hidden); -+ break; - +- - if (impl->operation_mode == OPERATION_MODE_RECENT) - return recent_get_selected_paths (impl); -+ case GTK_FILE_CHOOSER_PROP_ROOT_FOLDER: -+ g_value_set_string (value, impl->root_folder); -+ break; - -- info.impl = impl; -- info.result = NULL; -- info.path_from_entry = NULL; -+ case GTK_FILE_CHOOSER_PROP_SHOW_CREATE_FOLDER: -+ g_value_set_boolean (value, impl->show_create_folder); -+ break; - -- toplevel = get_toplevel (GTK_WIDGET (impl)); -- if (toplevel) -- current_focus = gtk_window_get_focus (toplevel); -- else -- current_focus = NULL; -+ case GTK_FILE_CHOOSER_PROP_PREVIEW_WIDGET: -+ g_value_set_object (value, NULL); -+ break; +- + info.impl = impl; + info.result = NULL; + info.path_from_entry = NULL; +@@ -7457,14 +3567,12 @@ + else + current_focus = NULL; - file_list_seen = FALSE; -- if (current_focus == impl->browse_files_tree_view) -- { -- GtkTreeSelection *selection; -+ case GTK_FILE_CHOOSER_PROP_PREVIEW_WIDGET_ACTIVE: -+ g_value_set_boolean (value, FALSE); -+ break; - -- file_list: -+ case GTK_FILE_CHOOSER_PROP_USE_PREVIEW_LABEL: -+ g_value_set_boolean (value, FALSE); -+ break; - -- file_list_seen = TRUE; -- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_files_tree_view)); -- gtk_tree_selection_selected_foreach (selection, get_paths_foreach, &info); -+ case GTK_FILE_CHOOSER_PROP_DO_OVERWRITE_CONFIRMATION: -+ g_value_set_boolean (value, impl->do_overwrite_confirmation); -+ break; - -- /* If there is no selection in the file list, we probably have this situation: -- * -- * 1. The user typed a filename in the SAVE filename entry ("foo.txt"). -- * 2. He then double-clicked on a folder ("bar") in the file list -- * -- * So we want the selection to be "bar/foo.txt". Jump to the case for the -- * filename entry to see if that is the case. -- */ -- if (info.result == NULL && impl->location_entry) -- goto file_entry; -+ default: -+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); -+ break; - } -- else if (impl->location_entry && current_focus == impl->location_entry) -+} -+ -+/* Removes the settings signal handler. It's safe to call multiple times */ -+static void -+remove_settings_signal (GtkFileChooserDefault *impl, -+ GdkScreen *screen) -+{ -+ if (impl->settings_signal_id) + if (current_focus == impl->browse_files_tree_view) { -- gboolean is_well_formed, is_empty, is_file_part_empty, is_folder; -+ GtkSettings *settings; - -- file_entry: -+ settings = gtk_settings_get_for_screen (screen); -+ g_signal_handler_disconnect (settings, -+ impl->settings_signal_id); -+ impl->settings_signal_id = 0; -+ } -+} + GtkTreeSelection *selection; -- check_save_entry (impl, &info.path_from_entry, &is_well_formed, &is_empty, &is_file_part_empty, &is_folder); -+static void -+gtk_file_chooser_default_dispose (GObject *object) -+{ -+ GSList *l; -+ GtkFileChooserDefault *impl = (GtkFileChooserDefault *) object; - -- if (is_empty) -- goto out; -+ if (impl->volumes_changed_id > 0) -+ { -+ g_signal_handler_disconnect (impl->file_system, impl->volumes_changed_id); -+ impl->volumes_changed_id = 0; -+ } + file_list: -- if (!is_well_formed) -- return NULL; -+ pending_select_paths_free (impl); +- file_list_seen = TRUE; + selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_files_tree_view)); + gtk_tree_selection_selected_foreach (selection, get_paths_foreach, &info); -- if (is_file_part_empty && impl->action == GTK_FILE_CHOOSER_ACTION_SAVE) -- { -- gtk_file_path_free (info.path_from_entry); -- return NULL; -- } -+ /* cancel all pending operations */ -+ if (impl->pending_handles) -+ { -+ for (l = impl->pending_handles; l; l = l->next) -+ { -+ GtkFileSystemHandle *handle =l->data; -+ gtk_file_system_cancel_operation (handle); -+ } -+ g_slist_free (impl->pending_handles); -+ impl->pending_handles = NULL; -+ } +@@ -7499,12 +3607,8 @@ + return NULL; + } - if (info.path_from_entry) - info.result = g_slist_prepend (info.result, info.path_from_entry); @@ -8073,269 +5867,76 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - goto file_list; - else - return NULL; -+ if (impl->reload_icon_handles) -+ { -+ for (l = impl->reload_icon_handles; l; l = l->next) -+ { -+ GtkFileSystemHandle *handle =l->data; -+ gtk_file_system_cancel_operation (handle); -+ } -+ g_slist_free (impl->reload_icon_handles); -+ impl->reload_icon_handles = NULL; ++ g_assert (info.path_from_entry != NULL); ++ info.result = g_slist_prepend (info.result, info.path_from_entry); } -- else if (impl->toplevel_last_focus_widget == impl->browse_files_tree_view) -- goto file_list; -- else if (impl->location_entry && impl->toplevel_last_focus_widget == impl->location_entry) -- goto file_entry; -- else -+ -+ if (impl->update_current_folder_handle) + else if (impl->toplevel_last_focus_widget == impl->browse_files_tree_view) + goto file_list; +@@ -7512,9 +3616,9 @@ + goto file_entry; + else { - /* The focus is on a dialog's action area button or something else */ - if (impl->action == GTK_FILE_CHOOSER_ACTION_SAVE || - impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER) -- goto file_entry; -- else -- goto file_list; -+ gtk_file_system_cancel_operation (impl->update_current_folder_handle); -+ impl->update_current_folder_handle = NULL; - } - -- out: -+ if (impl->show_and_select_paths_handle) -+ { -+ gtk_file_system_cancel_operation (impl->show_and_select_paths_handle); -+ impl->show_and_select_paths_handle = NULL; -+ } - -- /* If there's no folder selected, and we're in SELECT_FOLDER mode, then we -- * fall back to the current directory */ -- if (impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER && -- info.result == NULL) -+ if (impl->should_respond_get_info_handle) - { -- info.result = g_slist_prepend (info.result, _gtk_file_chooser_get_current_folder_path (chooser)); -+ gtk_file_system_cancel_operation (impl->should_respond_get_info_handle); -+ impl->should_respond_get_info_handle = NULL; - } - -- return g_slist_reverse (info.result); --} -+ if (impl->update_from_entry_handle) -+ { -+ gtk_file_system_cancel_operation (impl->update_from_entry_handle); -+ impl->update_from_entry_handle = NULL; -+ } ++ /* The focus is on a dialog's action area button or something else */ ++ if (impl->action == GTK_FILE_CHOOSER_ACTION_SAVE ++ || impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER) + goto file_entry; + else + goto file_list; +@@ -7533,17 +3637,6 @@ + return g_slist_reverse (info.result); + } -static GtkFilePath * -gtk_file_chooser_default_get_preview_path (GtkFileChooser *chooser) -{ - GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (chooser); -+ remove_settings_signal (impl, gtk_widget_get_screen (GTK_WIDGET (impl))); - +- - if (impl->preview_path) - return gtk_file_path_copy (impl->preview_path); - else - return NULL; -+ G_OBJECT_CLASS (_gtk_file_chooser_default_parent_class)->dispose (object); - } - --static GtkFileSystem * --gtk_file_chooser_default_get_file_system (GtkFileChooser *chooser) -+/* We override show-all since we have internal widgets that -+ * shouldn't be shown when you call show_all(), like the filter -+ * combo box. -+ */ -+static void -+gtk_file_chooser_default_show_all (GtkWidget *widget) - { -- GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (chooser); +-} - -- return impl->file_system; -+ gtk_widget_show (widget); - } - --/* Shows or hides the filter widgets */ -+/* Handler for GtkWindow::set-focus; this is where we save the last-focused -+ * widget on our toplevel. See gtk_file_chooser_default_hierarchy_changed() -+ */ - static void --show_filters (GtkFileChooserDefault *impl, -- gboolean show) -+toplevel_set_focus_cb (GtkWindow *window, -+ GtkWidget *focus, -+ GtkFileChooserDefault *impl) + static GtkFileSystem * + gtk_file_chooser_default_get_file_system (GtkFileChooser *chooser) { -- if (show) +@@ -7558,9 +3651,9 @@ + gboolean show) + { + if (show) - gtk_widget_show (impl->filter_combo_hbox); -- else ++ gtk_widget_show (impl->filter_combo); + else - gtk_widget_hide (impl->filter_combo_hbox); -+ impl->toplevel_last_focus_widget = gtk_window_get_focus (window); ++ gtk_widget_hide (impl->filter_combo); } -+/* We monitor the focus widget on our toplevel to be able to know which widget -+ * was last focused at the time our "should_respond" method gets called. -+ */ static void --gtk_file_chooser_default_add_filter (GtkFileChooser *chooser, -- GtkFileFilter *filter) -+gtk_file_chooser_default_hierarchy_changed (GtkWidget *widget, -+ GtkWidget *previous_toplevel) - { -- GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (chooser); -- const gchar *name; -+ GtkFileChooserDefault *impl; -+ GtkWidget *toplevel; - -- if (g_slist_find (impl->filters, filter)) -+ impl = GTK_FILE_CHOOSER_DEFAULT (widget); -+ -+ if (previous_toplevel) - { -- g_warning ("gtk_file_chooser_add_filter() called on filter already in list\n"); -- return; -+ g_assert (impl->toplevel_set_focus_id != 0); -+ g_signal_handler_disconnect (previous_toplevel, impl->toplevel_set_focus_id); -+ impl->toplevel_set_focus_id = 0; -+ impl->toplevel_last_focus_widget = NULL; - } -+ else -+ g_assert (impl->toplevel_set_focus_id == 0); - -- g_object_ref_sink (filter); -- impl->filters = g_slist_append (impl->filters, filter); -+ toplevel = gtk_widget_get_toplevel (widget); -+ if (GTK_IS_WINDOW (toplevel)) -+ { -+ impl->toplevel_set_focus_id = g_signal_connect (toplevel, "set_focus", -+ G_CALLBACK (toplevel_set_focus_cb), impl); -+ impl->toplevel_last_focus_widget = gtk_window_get_focus (GTK_WINDOW (toplevel)); -+ } -+} - -- name = gtk_file_filter_get_name (filter); -- if (!name) -- name = "Untitled filter"; /* Place-holder, doesn't need to be marked for translation */ -+/* Changes the icons wherever it is needed */ -+static void -+change_icon_theme (GtkFileChooserDefault *impl) -+{ -+ GtkSettings *settings; -+ gint width, height; - -- gtk_combo_box_append_text (GTK_COMBO_BOX (impl->filter_combo), name); -+ profile_start ("start", NULL); - -- if (!g_slist_find (impl->filters, impl->current_filter)) -- set_current_filter (impl, filter); -+ settings = gtk_settings_get_for_screen (gtk_widget_get_screen (GTK_WIDGET (impl))); -+ -+ if (gtk_icon_size_lookup_for_settings (settings, GTK_ICON_SIZE_MENU, &width, &height)) -+ impl->icon_size = MAX (width, height); -+ else -+ impl->icon_size = FALLBACK_ICON_SIZE; -+ -+ gtk_widget_queue_resize (impl->browse_files_tree_view); -+ -+ profile_end ("end", NULL); -+} -+ -+/* Callback used when a GtkSettings value changes */ -+static void -+settings_notify_cb (GObject *object, -+ GParamSpec *pspec, -+ GtkFileChooserDefault *impl) -+{ -+ const char *name; -+ -+ profile_start ("start", NULL); -+ -+ name = g_param_spec_get_name (pspec); -+ -+ if (strcmp (name, "gtk-icon-theme-name") == 0 -+ || strcmp (name, "gtk-icon-sizes") == 0) -+ change_icon_theme (impl); +@@ -7588,7 +3683,7 @@ + if (!g_slist_find (impl->filters, impl->current_filter)) + set_current_filter (impl, filter); - show_filters (impl, TRUE); -+ profile_end ("end", NULL); ++ show_filters (impl, g_slist_length (impl->filters) > 1); } -+/* Installs a signal handler for GtkSettings so that we can monitor changes in -+ * the icon theme. -+ */ static void --gtk_file_chooser_default_remove_filter (GtkFileChooser *chooser, -- GtkFileFilter *filter) -+check_icon_theme (GtkFileChooserDefault *impl) - { -- GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (chooser); -- GtkTreeModel *model; -- GtkTreeIter iter; -- gint filter_index; -+ GtkSettings *settings; - -- filter_index = g_slist_index (impl->filters, filter); -+ profile_start ("start", NULL); - -- if (filter_index < 0) -+ if (impl->settings_signal_id) - { -- g_warning ("gtk_file_chooser_remove_filter() called on filter not in list\n"); -+ profile_end ("end", NULL); - return; - } - -- impl->filters = g_slist_remove (impl->filters, filter); -- -- if (filter == impl->current_filter) -+ if (gtk_widget_has_screen (GTK_WIDGET (impl))) - { -- if (impl->filters) -- set_current_filter (impl, impl->filters->data); -- else -- set_current_filter (impl, NULL); -+ settings = gtk_settings_get_for_screen (gtk_widget_get_screen (GTK_WIDGET (impl))); -+ impl->settings_signal_id = g_signal_connect (settings, "notify", -+ G_CALLBACK (settings_notify_cb), impl); -+ -+ change_icon_theme (impl); - } +@@ -7627,8 +3722,7 @@ -- /* Remove row from the combo box */ -- model = gtk_combo_box_get_model (GTK_COMBO_BOX (impl->filter_combo)); -- if (!gtk_tree_model_iter_nth_child (model, &iter, NULL, filter_index)) -- g_assert_not_reached (); -+ profile_end ("end", NULL); -+} - -- gtk_list_store_remove (GTK_LIST_STORE (model), &iter); -+static void -+gtk_file_chooser_default_style_set (GtkWidget *widget, -+ GtkStyle *previous_style) -+{ -+ GtkFileChooserDefault *impl; - -- g_object_unref (filter); -+ profile_start ("start", NULL); + g_object_unref (filter); - if (!impl->filters) - show_filters (impl, FALSE); --} -+ impl = GTK_FILE_CHOOSER_DEFAULT (widget); - --static GSList * --gtk_file_chooser_default_list_filters (GtkFileChooser *chooser) --{ -- GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (chooser); -+ profile_msg (" parent class style_set start", NULL); -+ if (GTK_WIDGET_CLASS (_gtk_file_chooser_default_parent_class)->style_set) -+ GTK_WIDGET_CLASS (_gtk_file_chooser_default_parent_class)->style_set (widget, previous_style); -+ profile_msg (" parent class style_set end", NULL); ++ show_filters (impl, g_slist_length (impl->filters) > 1); + } -- return g_slist_copy (impl->filters); --} -+ if (gtk_widget_has_screen (GTK_WIDGET (impl))) -+ change_icon_theme (impl); + static GSList * +@@ -7639,234 +3733,6 @@ + return g_slist_copy (impl->filters); + } -/* Returns the position in the shortcuts tree where the nth specified shortcut would appear */ -static int @@ -8344,67 +5945,48 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c -{ - return pos + shortcuts_get_index (impl, SHORTCUTS_SHORTCUTS); -} -+ profile_msg (" emit default-size-changed start", NULL); -+ g_signal_emit_by_name (widget, "default-size-changed"); -+ profile_msg (" emit default-size-changed end", NULL); - +- -struct AddShortcutData -{ - GtkFileChooserDefault *impl; - GtkFilePath *path; -}; -+ profile_end ("end", NULL); -+} - - static void +- +-static void -add_shortcut_get_info_cb (GtkFileSystemHandle *handle, - const GtkFileInfo *info, - const GError *error, - gpointer user_data) -+gtk_file_chooser_default_screen_changed (GtkWidget *widget, -+ GdkScreen *previous_screen) - { +-{ - int pos; - gboolean cancelled = handle->cancelled; - struct AddShortcutData *data = user_data; - - if (!g_slist_find (data->impl->loading_shortcuts, handle)) - goto out; -+ GtkFileChooserDefault *impl; - +- - data->impl->loading_shortcuts = g_slist_remove (data->impl->loading_shortcuts, handle); -+ profile_start ("start", NULL); - +- - if (cancelled || error || !gtk_file_info_get_is_folder (info)) - goto out; -+ impl = GTK_FILE_CHOOSER_DEFAULT (widget); - +- - pos = shortcuts_get_pos_for_shortcut_folder (data->impl, data->impl->num_shortcuts); -+ if (GTK_WIDGET_CLASS (_gtk_file_chooser_default_parent_class)->screen_changed) -+ GTK_WIDGET_CLASS (_gtk_file_chooser_default_parent_class)->screen_changed (widget, previous_screen); - +- - shortcuts_insert_path (data->impl, pos, SHORTCUT_TYPE_PATH, NULL, data->path, NULL, FALSE, SHORTCUTS_SHORTCUTS); -+ remove_settings_signal (impl, previous_screen); -+ check_icon_theme (impl); - +- -out: - g_object_unref (data->impl); - gtk_file_path_free (data->path); - g_free (data); -+ g_signal_emit_by_name (widget, "default-size-changed"); - +- - g_object_unref (handle); -+ profile_end ("end", NULL); - } - +-} +- -static gboolean -gtk_file_chooser_default_add_shortcut_folder (GtkFileChooser *chooser, - const GtkFilePath *path, - GError **error) -+static void -+gtk_file_chooser_default_size_allocate (GtkWidget *widget, -+ GtkAllocation *allocation) - { +-{ - GtkFileSystemHandle *handle; - GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (chooser); - struct AddShortcutData *data; @@ -8416,8 +5998,7 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - if (pos >= 0 && pos < shortcuts_get_index (impl, SHORTCUTS_BOOKMARKS_SEPARATOR)) - { - gchar *uri; -+ GtkFileChooserDefault *impl; - +- - uri = gtk_file_system_path_to_uri (impl->file_system, path); - /* translators, "Shortcut" means "Bookmark" here */ - g_set_error (error, @@ -8426,15 +6007,12 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - _("Shortcut %s already exists"), - uri); - g_free (uri); -+ impl = GTK_FILE_CHOOSER_DEFAULT (widget); - +- - return FALSE; - } -+ GTK_WIDGET_CLASS (_gtk_file_chooser_default_parent_class)->size_allocate (widget, allocation); - +- - for (l = impl->loading_shortcuts; l; l = l->next) -+ if (!gtk_file_chooser_default_get_resizable (GTK_FILE_CHOOSER_EMBED (impl))) - { +- { - GtkFileSystemHandle *h = l->data; - GtkFilePath *p; - @@ -8453,12 +6031,8 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - - return FALSE; - } -+ /* The dialog is not resizable, we shouldn't -+ * trust in the size it has in this stage -+ */ -+ return; - } - +- } +- - data = g_new0 (struct AddShortcutData, 1); - data->impl = g_object_ref (impl); - data->path = gtk_file_path_copy (path); @@ -8474,35 +6048,25 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - g_object_set_data (G_OBJECT (handle), "add-shortcut-path-key", data->path); - - return TRUE; -+ impl->default_width = allocation->width; -+ impl->default_height = allocation->height; - } - - static gboolean +-} +- +-static gboolean -gtk_file_chooser_default_remove_shortcut_folder (GtkFileChooser *chooser, - const GtkFilePath *path, - GError **error) -+get_is_file_filtered (GtkFileChooserDefault *impl, -+ const GtkFilePath *path, -+ GtkFileInfo *file_info) - { +-{ - GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (chooser); - int pos; - GtkTreeIter iter; - GSList *l; - char *uri; - int i; -+ GtkFileFilterInfo filter_info; -+ GtkFileFilterFlags needed; -+ gboolean result; - +- - for (l = impl->loading_shortcuts; l; l = l->next) - { - GtkFileSystemHandle *h = l->data; - GtkFilePath *p; -+ if (!impl->current_filter) -+ return FALSE; - +- - p = g_object_get_data (G_OBJECT (h), "add-shortcut-path-key"); - if (p && !gtk_file_path_compare (path, p)) - { @@ -8511,21 +6075,16 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - return TRUE; - } - } -+ filter_info.contains = GTK_FILE_FILTER_DISPLAY_NAME | GTK_FILE_FILTER_MIME_TYPE; - +- - if (impl->num_shortcuts == 0) - goto out; -+ needed = gtk_file_filter_get_needed (impl->current_filter); - +- - pos = shortcuts_get_pos_for_shortcut_folder (impl, 0); - if (!gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (impl->shortcuts_model), &iter, NULL, pos)) - g_assert_not_reached (); -+ filter_info.display_name = gtk_file_info_get_display_name (file_info); -+ filter_info.mime_type = gtk_file_info_get_mime_type (file_info); - +- - for (i = 0; i < impl->num_shortcuts; i++) -+ if (needed & GTK_FILE_FILTER_FILENAME) - { +- { - gpointer col_data; - ShortcutType shortcut_type; - GtkFilePath *shortcut; @@ -8544,27 +6103,13 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - impl->num_shortcuts--; - return TRUE; - } -+ filter_info.filename = gtk_file_system_path_to_filename (impl->file_system, path); -+ if (filter_info.filename) -+ filter_info.contains |= GTK_FILE_FILTER_FILENAME; -+ } -+ else -+ filter_info.filename = NULL; - +- - if (!gtk_tree_model_iter_next (GTK_TREE_MODEL (impl->shortcuts_model), &iter)) - g_assert_not_reached (); -+ if (needed & GTK_FILE_FILTER_URI) -+ { -+ filter_info.uri = gtk_file_system_path_to_uri (impl->file_system, path); -+ if (filter_info.uri) -+ filter_info.contains |= GTK_FILE_FILTER_URI; - } -+ else -+ filter_info.uri = NULL; - +- } +- - out: -+ result = gtk_file_filter_filter (impl->current_filter, &filter_info); - +- - uri = gtk_file_system_path_to_uri (impl->file_system, path); - /* translators, "Shortcut" means "Bookmark" here */ - g_set_error (error, @@ -8573,895 +6118,137 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - _("Shortcut %s does not exist"), - uri); - g_free (uri); -+ if (filter_info.filename) -+ g_free ((gchar *)filter_info.filename); -+ if (filter_info.uri) -+ g_free ((gchar *)filter_info.uri); - +- - return FALSE; -+ return !result; - } - +-} +- -static GSList * -gtk_file_chooser_default_list_shortcut_folders (GtkFileChooser *chooser) -+static void -+settings_load (GtkFileChooserDefault *impl) - { +-{ - GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (chooser); - int pos; - GtkTreeIter iter; - int i; - GSList *list; -+ GtkFileChooserSettings *settings; -+ gboolean show_hidden; -+ gboolean expand_folders; - +- - if (impl->num_shortcuts == 0) - return NULL; -+ settings = _gtk_file_chooser_settings_new (); - +- - pos = shortcuts_get_pos_for_shortcut_folder (impl, 0); - if (!gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (impl->shortcuts_model), &iter, NULL, pos)) - g_assert_not_reached (); -+ show_hidden = _gtk_file_chooser_settings_get_show_hidden (settings); -+ expand_folders = _gtk_file_chooser_settings_get_expand_folders (settings); - +- - list = NULL; -+ g_object_unref (settings); - +- - for (i = 0; i < impl->num_shortcuts; i++) - { - gpointer col_data; - ShortcutType shortcut_type; - GtkFilePath *shortcut; -+ gtk_file_chooser_set_show_hidden (GTK_FILE_CHOOSER (impl), show_hidden); -+ impl->expand_folders = expand_folders; -+} -+ -+static void -+settings_save (GtkFileChooserDefault *impl) -+{ -+ GtkFileChooserSettings *settings; - +- - gtk_tree_model_get (GTK_TREE_MODEL (impl->shortcuts_model), &iter, - SHORTCUTS_COL_DATA, &col_data, - SHORTCUTS_COL_TYPE, &shortcut_type, - -1); - g_assert (col_data != NULL); - g_assert (shortcut_type == SHORTCUT_TYPE_PATH); -+ settings = _gtk_file_chooser_settings_new (); - +- - shortcut = col_data; - list = g_slist_prepend (list, gtk_file_path_copy (shortcut)); -+ _gtk_file_chooser_settings_set_show_hidden (settings, gtk_file_chooser_get_show_hidden (GTK_FILE_CHOOSER (impl))); -+ _gtk_file_chooser_settings_set_expand_folders (settings, impl->expand_folders); - +- - if (i != impl->num_shortcuts - 1) - { - if (!gtk_tree_model_iter_next (GTK_TREE_MODEL (impl->shortcuts_model), &iter)) - g_assert_not_reached (); - } - } -+ /* NULL GError */ -+ _gtk_file_chooser_settings_save (settings, NULL); - +- - return g_slist_reverse (list); -+ g_object_unref (settings); - } - --/* Guesses a size based upon font sizes */ -+/* GtkWidget::map method */ +-} +- + /* Guesses a size based upon font sizes */ static void --find_good_size_from_style (GtkWidget *widget, -- gint *width, -- gint *height) -+gtk_file_chooser_default_map (GtkWidget *widget) + find_good_size_from_style (GtkWidget *widget, +@@ -7911,25 +3777,9 @@ + gint *default_height) { GtkFileChooserDefault *impl; -- int font_size; -- GdkScreen *screen; -- double resolution; -- -- g_assert (widget->style != NULL); -- impl = GTK_FILE_CHOOSER_DEFAULT (widget); -+ char *current_working_dir; - -- if (impl->default_width == 0 && -- impl->default_height == 0) -- { -- screen = gtk_widget_get_screen (widget); -- if (screen) -- { -- resolution = gdk_screen_get_resolution (screen); -- if (resolution < 0.0) /* will be -1 if the resolution is not defined in the GdkScreen */ -- resolution = 96.0; -- } -- else -- resolution = 96.0; /* wheeee */ -+ profile_start ("start", NULL); - -- font_size = pango_font_description_get_size (widget->style->font_desc); -- font_size = PANGO_PIXELS (font_size) * resolution / 72.0; -+ impl = GTK_FILE_CHOOSER_DEFAULT (widget); - -- impl->default_width = font_size * NUM_CHARS; -- impl->default_height = font_size * NUM_LINES; -- } -+ GTK_WIDGET_CLASS (_gtk_file_chooser_default_parent_class)->map (widget); - -- *width = impl->default_width; -- *height = impl->default_height; --} -+ 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; - --static void --gtk_file_chooser_default_get_default_size (GtkFileChooserEmbed *chooser_embed, -- gint *default_width, -- gint *default_height) --{ -- GtkFileChooserDefault *impl; - GtkRequisition req; -+ case RELOAD_HAS_FOLDER: -+ /* Nothing; we are already loading or loaded, so we don't need to reload */ -+ break; - -- impl = GTK_FILE_CHOOSER_DEFAULT (chooser_embed); -- find_good_size_from_style (GTK_WIDGET (chooser_embed), default_width, default_height); -+ case RELOAD_WAS_UNMAPPED: -+ /* Just reload the current folder; else continue the pending load. */ -+ if (impl->current_folder) -+ { -+ pending_select_paths_store_selection (impl); -+ change_folder_and_display_error (impl, impl->current_folder); -+ } -+ break; + impl = GTK_FILE_CHOOSER_DEFAULT (chooser_embed); + find_good_size_from_style (GTK_WIDGET (chooser_embed), default_width, default_height); +- - if (impl->preview_widget_active && - impl->preview_widget && - GTK_WIDGET_VISIBLE (impl->preview_widget)) - { - gtk_widget_size_request (impl->preview_box, &req); - *default_width += PREVIEW_HBOX_SPACING + req.width; -+ default: -+ g_assert_not_reached (); - } - +- } +- - if (impl->extra_widget && - GTK_WIDGET_VISIBLE (impl->extra_widget)) - { - gtk_widget_size_request (impl->extra_align, &req); - *default_height += GTK_BOX (chooser_embed)->spacing + req.height; - } -+ settings_load (impl); -+ -+ profile_end ("end", NULL); } --static gboolean --gtk_file_chooser_default_get_resizable (GtkFileChooserEmbed *chooser_embed) -+/* GtkWidget::unmap method */ -+static void -+gtk_file_chooser_default_unmap (GtkWidget *widget) - { - GtkFileChooserDefault *impl; - -- impl = GTK_FILE_CHOOSER_DEFAULT (chooser_embed); -+ impl = GTK_FILE_CHOOSER_DEFAULT (widget); + static gboolean +@@ -7940,8 +3790,7 @@ + impl = GTK_FILE_CHOOSER_DEFAULT (chooser_embed); -- return (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN || + return (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN || - impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER || - gtk_expander_get_expanded (GTK_EXPANDER (impl->save_expander))); --} -+ settings_save (impl); - --struct switch_folder_closure { -- GtkFileChooserDefault *impl; -- const GtkFilePath *path; -- int num_selected; --}; -+ GTK_WIDGET_CLASS (_gtk_file_chooser_default_parent_class)->unmap (widget); - --/* Used from gtk_tree_selection_selected_foreach() in switch_to_selected_folder() */ --static void --switch_folder_foreach_cb (GtkTreeModel *model, -- GtkTreePath *path, -- GtkTreeIter *iter, -- gpointer data) -+ impl->reload_state = RELOAD_WAS_UNMAPPED; -+} -+ -+static gboolean -+list_model_filter_func (GtkFileSystemModel *model, -+ GtkFilePath *path, -+ const GtkFileInfo *file_info, -+ gpointer user_data) - { -- struct switch_folder_closure *closure; -- GtkTreeIter child_iter; -+ GtkFileChooserDefault *impl = user_data; - -- closure = data; -+ if (!impl->current_filter) -+ return TRUE; - -- gtk_tree_model_sort_convert_iter_to_child_iter (closure->impl->sort_model, &child_iter, iter); -+ if (gtk_file_info_get_is_folder (file_info)) -+ return TRUE; - -- closure->path = _gtk_file_system_model_get_path (closure->impl->browse_files_model, &child_iter); -- closure->num_selected++; -+ return !get_is_file_filtered (impl, path, (GtkFileInfo *) file_info); ++ impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER); } --/* Changes to the selected folder in the list view */ - static void --switch_to_selected_folder (GtkFileChooserDefault *impl) -+install_list_model_filter (GtkFileChooserDefault *impl) - { -- GtkTreeSelection *selection; -- struct switch_folder_closure closure; -- -- /* We do this with foreach() rather than get_selected() as we may be in -- * multiple selection mode -- */ -+ GtkFileSystemModelFilter filter; -+ gpointer data; + struct switch_folder_closure { +@@ -7988,7 +3837,7 @@ -- closure.impl = impl; -- closure.path = NULL; -- closure.num_selected = 0; -+ g_assert (impl->browse_files_model != NULL); - -- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_files_tree_view)); -- gtk_tree_selection_selected_foreach (selection, switch_folder_foreach_cb, &closure); -+ if (impl->current_filter) -+ { -+ filter = list_model_filter_func; -+ data = impl; -+ } -+ else -+ { -+ filter = NULL; -+ data = NULL; -+ } -+ -+ _gtk_file_system_model_set_filter (impl->browse_files_model, -+ filter, -+ data); -+} - -- g_assert (closure.path && closure.num_selected == 1); -+#define COMPARE_DIRECTORIES \ -+ GtkFileChooserDefault *impl = user_data; \ -+ const GtkFileInfo *info_a = _gtk_file_system_model_get_info (impl->browse_files_model, a); \ -+ const GtkFileInfo *info_b = _gtk_file_system_model_get_info (impl->browse_files_model, b); \ -+ gboolean dir_a, dir_b; \ -+ \ -+ if (info_a) \ -+ dir_a = gtk_file_info_get_is_folder (info_a); \ -+ else \ -+ return impl->list_sort_ascending ? -1 : 1; \ -+ \ -+ if (info_b) \ -+ dir_b = gtk_file_info_get_is_folder (info_b); \ -+ else \ -+ return impl->list_sort_ascending ? 1 : -1; \ -+ \ -+ if (dir_a != dir_b) \ -+ return impl->list_sort_ascending ? (dir_a ? -1 : 1) : (dir_a ? 1 : -1) /* Directories *always* go first */ + g_assert (closure.path && closure.num_selected == 1); - change_folder_and_display_error (impl, closure.path, FALSE); -+/* Sort callback for the filename column */ -+static gint -+name_sort_func (GtkTreeModel *model, -+ GtkTreeIter *a, -+ GtkTreeIter *b, -+ gpointer user_data) -+{ -+ COMPARE_DIRECTORIES; -+ else -+ return strcmp (gtk_file_info_get_display_key (info_a), gtk_file_info_get_display_key (info_b)); - } - --/* Gets the GtkFileInfo for the selected row in the file list; assumes single -- * selection mode. -- */ --static const GtkFileInfo * --get_selected_file_info_from_file_list (GtkFileChooserDefault *impl, -- gboolean *had_selection) -+/* Sort callback for the size column */ -+static gint -+size_sort_func (GtkTreeModel *model, -+ GtkTreeIter *a, -+ GtkTreeIter *b, -+ gpointer user_data) - { -- GtkTreeSelection *selection; -- GtkTreeIter iter, child_iter; -- const GtkFileInfo *info; -- -- g_assert (!impl->select_multiple); -- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_files_tree_view)); -- if (!gtk_tree_selection_get_selected (selection, NULL, &iter)) -+ COMPARE_DIRECTORIES; -+ else - { -- *had_selection = FALSE; -- return NULL; -- } -- -- *had_selection = TRUE; -- -- gtk_tree_model_sort_convert_iter_to_child_iter (impl->sort_model, -- &child_iter, -- &iter); -+ gint64 size_a = gtk_file_info_get_size (info_a); -+ gint64 size_b = gtk_file_info_get_size (info_b); - -- info = _gtk_file_system_model_get_info (impl->browse_files_model, &child_iter); -- return info; -+ return size_a > size_b ? -1 : (size_a == size_b ? 0 : 1); -+ } - } - --/* Gets the display name of the selected file in the file list; assumes single -- * selection mode and that something is selected. -- */ --static const gchar * --get_display_name_from_file_list (GtkFileChooserDefault *impl) -+/* Sort callback for the mtime column */ -+static gint -+mtime_sort_func (GtkTreeModel *model, -+ GtkTreeIter *a, -+ GtkTreeIter *b, -+ gpointer user_data) - { -- const GtkFileInfo *info; -- gboolean had_selection; -- -- info = get_selected_file_info_from_file_list (impl, &had_selection); -- g_assert (had_selection); -- g_assert (info != NULL); -+ COMPARE_DIRECTORIES; -+ else -+ { -+ GtkFileTime ta = gtk_file_info_get_modification_time (info_a); -+ GtkFileTime tb = gtk_file_info_get_modification_time (info_b); - -- return gtk_file_info_get_display_name (info); -+ return ta > tb ? -1 : (ta == tb ? 0 : 1); -+ } - } - -+/* Callback used when the sort column changes. We cache the sort order for use -+ * in name_sort_func(). -+ */ - static void --add_custom_button_to_dialog (GtkDialog *dialog, -- const gchar *mnemonic_label, -- const gchar *stock_id, -- gint response_id) -+list_sort_column_changed_cb (GtkTreeSortable *sortable, -+ GtkFileChooserDefault *impl) - { -- GtkWidget *button; -- -- button = gtk_button_new_with_mnemonic (mnemonic_label); -- GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT); -- gtk_button_set_image (GTK_BUTTON (button), -- gtk_image_new_from_stock (stock_id, GTK_ICON_SIZE_BUTTON)); -- gtk_widget_show (button); -+ GtkSortType sort_type; - -- gtk_dialog_add_action_widget (GTK_DIALOG (dialog), button, response_id); -+ if (gtk_tree_sortable_get_sort_column_id (sortable, NULL, &sort_type)) -+ impl->list_sort_ascending = (sort_type == GTK_SORT_ASCENDING); - } - --/* Presents an overwrite confirmation dialog; returns whether we should accept -- * the filename. -- */ --static gboolean --confirm_dialog_should_accept_filename (GtkFileChooserDefault *impl, -- const gchar *file_part, -- const gchar *folder_display_name) -+static void -+set_busy_cursor (GtkFileChooserDefault *impl, -+ gboolean busy) - { - GtkWindow *toplevel; -- GtkWidget *dialog; -- int response; -+ GdkDisplay *display; -+ GdkCursor *cursor; - - toplevel = get_toplevel (GTK_WIDGET (impl)); -+ if (!toplevel || !GTK_WIDGET_REALIZED (toplevel)) -+ return; - -- dialog = gtk_message_dialog_new (toplevel, -- GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, -- GTK_MESSAGE_QUESTION, -- GTK_BUTTONS_NONE, -- _("A file named \"%s\" already exists. Do you want to replace it?"), -- file_part); -- gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), -- _("The file already exists in \"%s\". Replacing it will " -- "overwrite its contents."), -- folder_display_name); -- -- gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL); -- add_custom_button_to_dialog (GTK_DIALOG (dialog), _("_Replace"), GTK_STOCK_SAVE_AS, GTK_RESPONSE_ACCEPT); -- gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_ACCEPT); -- -- if (toplevel->group) -- gtk_window_group_add_window (toplevel->group, GTK_WINDOW (dialog)); -+ display = gtk_widget_get_display (GTK_WIDGET (toplevel)); - -- response = gtk_dialog_run (GTK_DIALOG (dialog)); -+ if (busy) -+ cursor = gdk_cursor_new_for_display (display, GDK_WATCH); -+ else -+ cursor = NULL; - -- gtk_widget_destroy (dialog); -+ gdk_window_set_cursor (GTK_WIDGET (toplevel)->window, cursor); -+ gdk_display_flush (display); - -- return (response == GTK_RESPONSE_ACCEPT); -+ if (cursor) -+ gdk_cursor_unref (cursor); - } - --struct GetDisplayNameData --{ -- GtkFileChooserDefault *impl; -- gchar *file_part; --}; -- -+/* Creates a sort model to wrap the file system model and sets it on the tree view */ - static void --confirmation_confirm_get_info_cb (GtkFileSystemHandle *handle, -- const GtkFileInfo *info, -- const GError *error, -- gpointer user_data) -+load_set_model (GtkFileChooserDefault *impl) - { -- gboolean cancelled = handle->cancelled; -- gboolean should_respond = FALSE; -- struct GetDisplayNameData *data = user_data; -- -- if (handle != data->impl->should_respond_get_info_handle) -- goto out; -- -- data->impl->should_respond_get_info_handle = NULL; -+ profile_start ("start", NULL); - -- if (cancelled) -- goto out; -+ g_assert (impl->browse_files_model != NULL); -+ g_assert (impl->sort_model == NULL); - -- if (error) -- /* Huh? Did the folder disappear? Let the caller deal with it */ -- should_respond = TRUE; -- else -- should_respond = confirm_dialog_should_accept_filename (data->impl, data->file_part, gtk_file_info_get_display_name (info)); -+ profile_msg (" gtk_tree_model_sort_new_with_model start", NULL); -+ impl->sort_model = (GtkTreeModelSort *)gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (impl->browse_files_model)); -+ gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (impl->sort_model), FILE_LIST_COL_NAME, name_sort_func, impl, NULL); -+ gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (impl->sort_model), FILE_LIST_COL_SIZE, size_sort_func, impl, NULL); -+ gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (impl->sort_model), FILE_LIST_COL_MTIME, mtime_sort_func, impl, NULL); -+ gtk_tree_sortable_set_default_sort_func (GTK_TREE_SORTABLE (impl->sort_model), NULL, NULL, NULL); -+ gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (impl->sort_model), FILE_LIST_COL_NAME, GTK_SORT_ASCENDING); -+ impl->list_sort_ascending = TRUE; -+ profile_msg (" gtk_tree_model_sort_new_with_model end", NULL); - -- set_busy_cursor (data->impl, FALSE); -- if (should_respond) -- g_signal_emit_by_name (data->impl, "response-requested"); -+ g_signal_connect (impl->sort_model, "sort_column_changed", -+ G_CALLBACK (list_sort_column_changed_cb), impl); - --out: -- g_object_unref (data->impl); -- g_free (data->file_part); -- g_free (data); -+ profile_msg (" gtk_tree_view_set_model start", NULL); -+ gtk_tree_view_set_model (GTK_TREE_VIEW (impl->browse_files_tree_view), -+ GTK_TREE_MODEL (impl->sort_model)); -+ gtk_tree_view_columns_autosize (GTK_TREE_VIEW (impl->browse_files_tree_view)); -+ gtk_tree_view_set_search_column (GTK_TREE_VIEW (impl->browse_files_tree_view), -+ GTK_FILE_SYSTEM_MODEL_DISPLAY_NAME); -+ profile_msg (" gtk_tree_view_set_model end", NULL); - -- g_object_unref (handle); -+ profile_end ("end", NULL); ++ change_folder_and_display_error (impl, closure.path); } --/* Does overwrite confirmation if appropriate, and returns whether the dialog -- * should respond. Can get the file part from the file list or the save entry. -- */ -+/* Timeout callback used when the loading timer expires */ - static gboolean --should_respond_after_confirm_overwrite (GtkFileChooserDefault *impl, -- const gchar *file_part, -- const GtkFilePath *parent_path) -+load_timeout_cb (gpointer data) - { -- GtkFileChooserConfirmation conf; -+ GtkFileChooserDefault *impl; - -- if (!impl->do_overwrite_confirmation) -- return TRUE; -+ profile_start ("start", NULL); - -- conf = GTK_FILE_CHOOSER_CONFIRMATION_CONFIRM; -+ GDK_THREADS_ENTER (); - -- g_signal_emit_by_name (impl, "confirm-overwrite", &conf); -+ impl = GTK_FILE_CHOOSER_DEFAULT (data); -+ g_assert (impl->load_state == LOAD_PRELOAD); -+ g_assert (impl->load_timeout_id != 0); -+ g_assert (impl->browse_files_model != NULL); - -- switch (conf) -- { -- case GTK_FILE_CHOOSER_CONFIRMATION_CONFIRM: -- { -- struct GetDisplayNameData *data; -+ impl->load_timeout_id = 0; -+ impl->load_state = LOAD_LOADING; - -- g_assert (file_part != NULL); -+ load_set_model (impl); - -- data = g_new0 (struct GetDisplayNameData, 1); -- data->impl = g_object_ref (impl); -- data->file_part = g_strdup (file_part); -+ GDK_THREADS_LEAVE (); - -- if (impl->should_respond_get_info_handle) -- gtk_file_system_cancel_operation (impl->should_respond_get_info_handle); -+ profile_end ("end", NULL); - -- impl->should_respond_get_info_handle = -- gtk_file_system_get_info (impl->file_system, parent_path, -- GTK_FILE_INFO_DISPLAY_NAME, -- confirmation_confirm_get_info_cb, -- data); -- set_busy_cursor (data->impl, TRUE); -- return FALSE; -- } -+ return FALSE; -+} - -- case GTK_FILE_CHOOSER_CONFIRMATION_ACCEPT_FILENAME: -- return TRUE; -+/* Sets up a new load timer for the model and switches to the LOAD_PRELOAD state */ -+static void -+load_setup_timer (GtkFileChooserDefault *impl) -+{ -+ g_assert (impl->load_timeout_id == 0); -+ g_assert (impl->load_state != LOAD_PRELOAD); - -- case GTK_FILE_CHOOSER_CONFIRMATION_SELECT_AGAIN: -- return FALSE; -+ impl->load_timeout_id = g_timeout_add (MAX_LOADING_TIME, load_timeout_cb, impl); -+ impl->load_state = LOAD_PRELOAD; -+} - -- default: -- g_assert_not_reached (); -- return FALSE; -+/* Removes the load timeout and switches to the LOAD_FINISHED state */ -+static void -+load_remove_timer (GtkFileChooserDefault *impl) -+{ -+ if (impl->load_timeout_id != 0) -+ { -+ g_assert (impl->load_state == LOAD_PRELOAD); -+ -+ g_source_remove (impl->load_timeout_id); -+ impl->load_timeout_id = 0; -+ impl->load_state = LOAD_EMPTY; + /* Gets the GtkFileInfo for the selected row in the file list; assumes single +@@ -8187,24 +4036,7 @@ } -+ else -+ g_assert (impl->load_state == LOAD_EMPTY || -+ impl->load_state == LOAD_LOADING || -+ impl->load_state == LOAD_FINISHED); } -/* Gives the focus to the browse tree view only if it is visible */ -+/* Selects the first row in the file list */ static void -focus_browse_tree_view_if_possible (GtkFileChooserDefault *impl) -+browse_files_select_first_row (GtkFileChooserDefault *impl) - { +-{ - gboolean do_focus; -+ GtkTreePath *path; - +- - if ((impl->action == GTK_FILE_CHOOSER_ACTION_SAVE || - impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER) - && !gtk_expander_get_expanded (GTK_EXPANDER (impl->save_expander))) - do_focus = FALSE; - else - do_focus = TRUE; -+ if (!impl->sort_model) -+ return; - +- - if (do_focus) - gtk_widget_grab_focus (impl->browse_files_tree_view); -+ path = gtk_tree_path_new_from_indices (0, -1); -+ gtk_tree_view_set_cursor (GTK_TREE_VIEW (impl->browse_files_tree_view), path, NULL, FALSE); -+ gtk_tree_path_free (path); - } - -+struct center_selected_row_closure { -+ GtkFileChooserDefault *impl; -+ gboolean already_centered; -+}; -+ -+/* Callback used from gtk_tree_selection_selected_foreach(); centers the -+ * selected row in the tree view. -+ */ - static void --action_create_folder_cb (GtkFileSystemHandle *handle, -- const GtkFilePath *path, -- const GError *error, -- gpointer user_data) -+center_selected_row_foreach_cb (GtkTreeModel *model, -+ GtkTreePath *path, -+ GtkTreeIter *iter, -+ gpointer data) - { -- gboolean cancelled = handle->cancelled; -- GtkFileChooserDefault *impl = user_data; +-} - -- if (!g_slist_find (impl->pending_handles, handle)) -- goto out; -+ struct center_selected_row_closure *closure; - -- impl->pending_handles = g_slist_remove (impl->pending_handles, handle); -+ closure = data; -+ if (closure->already_centered) -+ return; - -- set_busy_cursor (impl, FALSE); -+ gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (closure->impl->browse_files_tree_view), path, NULL, TRUE, 0.5, 0.0); -+ closure->already_centered = TRUE; -+} - -- if (cancelled) -- goto out; -+/* Centers the selected row in the tree view */ -+static void -+browse_files_center_selected_row (GtkFileChooserDefault *impl) -+{ -+ struct center_selected_row_closure closure; -+ GtkTreeSelection *selection; - -- if (error) -- error_creating_folder_dialog (impl, path, g_error_copy (error)); -- else -- g_signal_emit_by_name (impl, "response-requested"); -+ closure.impl = impl; -+ closure.already_centered = FALSE; - --out: -- g_object_unref (impl); -- g_object_unref (handle); -+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_files_tree_view)); -+ gtk_tree_selection_selected_foreach (selection, center_selected_row_foreach_cb, &closure); - } - --struct FileExistsData -+struct ShowAndSelectPathsData - { - GtkFileChooserDefault *impl; -- gboolean file_exists_and_is_not_folder; -- GtkFilePath *parent_path; -- GtkFilePath *path; -+ GSList *paths; - }; - - static void --save_entry_get_info_cb (GtkFileSystemHandle *handle, -- const GtkFileInfo *info, -- const GError *error, -- gpointer user_data) -+show_and_select_paths_finished_loading (GtkFileFolder *folder, -+ gpointer user_data) - { -- gboolean parent_is_folder; -- gboolean cancelled = handle->cancelled; -- struct FileExistsData *data = user_data; -+ gboolean have_hidden; -+ GSList *l; -+ struct ShowAndSelectPathsData *data = user_data; - -- if (handle != data->impl->should_respond_get_info_handle) -- goto out; -+ have_hidden = FALSE; - -- data->impl->should_respond_get_info_handle = NULL; -+ for (l = data->paths; l; l = l->next) -+ { -+ const GtkFilePath *path; -+ GtkFileInfo *info; - -- set_busy_cursor (data->impl, FALSE); -+ path = l->data; - -- if (cancelled) -- goto out; -+ /* NULL GError */ -+ info = gtk_file_folder_get_info (folder, path, NULL); -+ if (info) -+ { -+ if (!have_hidden) -+ have_hidden = gtk_file_info_get_is_hidden (info); - -- if (!info) -- parent_is_folder = FALSE; -- else -- parent_is_folder = gtk_file_info_get_is_folder (info); -+ gtk_file_info_free (info); - -- if (parent_is_folder) -- { -- if (data->impl->action == GTK_FILE_CHOOSER_ACTION_SAVE) -- { -- if (data->file_exists_and_is_not_folder) -- { -- gboolean retval; -- const char *file_part; -+ if (have_hidden) -+ break; /* we now have all the information we need */ -+ } -+ } - -- file_part = _gtk_file_chooser_entry_get_file_part (GTK_FILE_CHOOSER_ENTRY (data->impl->location_entry)); -- retval = should_respond_after_confirm_overwrite (data->impl, file_part, data->parent_path); -+ g_signal_handlers_disconnect_by_func (folder, -+ show_and_select_paths_finished_loading, -+ user_data); - -- if (retval) -- g_signal_emit_by_name (data->impl, "response-requested"); -- } -- else -- g_signal_emit_by_name (data->impl, "response-requested"); -- } -- else /* GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER */ -- { -- GtkFileSystemHandle *handle; -+ g_object_unref (folder); - -- g_object_ref (data->impl); -- handle = gtk_file_system_create_folder (data->impl->file_system, -- data->path, -- action_create_folder_cb, -- data->impl); -- data->impl->pending_handles = g_slist_append (data->impl->pending_handles, handle); -- set_busy_cursor (data->impl, TRUE); -- } -- } -- else -+ if (have_hidden) -+ g_object_set (data->impl, "show-hidden", TRUE, NULL); -+ -+ for (l = data->paths; l; l = l->next) +-static void + action_create_folder_cb (GtkFileSystemHandle *handle, + const GtkFilePath *path, + const GError *error, +@@ -8300,7 +4132,7 @@ + else { -- /* This will display an error, which is what we want */ + /* This will display an error, which is what we want */ - change_folder_and_display_error (data->impl, data->parent_path, FALSE); -+ const GtkFilePath *path; -+ -+ path = l->data; -+ _gtk_file_system_model_path_do (data->impl->browse_files_model, path, -+ select_func, data->impl); ++ change_folder_and_display_error (data->impl, data->parent_path); } --out: -+ browse_files_center_selected_row (data->impl); -+ - g_object_unref (data->impl); -- gtk_file_path_free (data->path); -- gtk_file_path_free (data->parent_path); -+ gtk_file_paths_free (data->paths); - g_free (data); -- -- g_object_unref (handle); - } - - static void --file_exists_get_info_cb (GtkFileSystemHandle *handle, -- const GtkFileInfo *info, -- const GError *error, -- gpointer user_data) -+show_and_select_paths_get_folder_cb (GtkFileSystemHandle *handle, -+ GtkFileFolder *folder, -+ const GError *error, -+ gpointer user_data) - { -- gboolean data_ownership_taken = FALSE; - gboolean cancelled = handle->cancelled; -- gboolean file_exists_and_is_not_folder; -- struct FileExistsData *data = user_data; -+ struct ShowAndSelectPathsData *data = user_data; - -- if (handle != data->impl->file_exists_get_info_handle) -+ if (data->impl->show_and_select_paths_handle != handle) - goto out; - -- data->impl->file_exists_get_info_handle = NULL; -- -- set_busy_cursor (data->impl, FALSE); -+ data->impl->show_and_select_paths_handle = NULL; - -- if (cancelled) -+ if (cancelled || error) - goto out; - -- file_exists_and_is_not_folder = info && !gtk_file_info_get_is_folder (info); -+ g_object_unref (handle); - -- if (data->impl->action == GTK_FILE_CHOOSER_ACTION_OPEN) -- /* user typed a filename; we are done */ -- g_signal_emit_by_name (data->impl, "response-requested"); -- else if (data->impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER -- && file_exists_and_is_not_folder) -- { -- /* Oops, the user typed the name of an existing path which is not -- * a folder -- */ -- error_creating_folder_over_existing_file_dialog (data->impl, data->path, -- g_error_copy (error)); -- } -+ if (gtk_file_folder_is_finished_loading (folder)) -+ show_and_select_paths_finished_loading (folder, user_data); - else -- { -- /* check that everything up to the last component exists */ -- -- data->file_exists_and_is_not_folder = file_exists_and_is_not_folder; -- data_ownership_taken = TRUE; -- -- if (data->impl->should_respond_get_info_handle) -- gtk_file_system_cancel_operation (data->impl->should_respond_get_info_handle); -+ g_signal_connect (folder, "finished-loading", -+ G_CALLBACK (show_and_select_paths_finished_loading), -+ user_data); - -- data->impl->should_respond_get_info_handle = -- gtk_file_system_get_info (data->impl->file_system, -- data->parent_path, -- GTK_FILE_INFO_IS_FOLDER, -- save_entry_get_info_cb, -- data); -- set_busy_cursor (data->impl, TRUE); -- } -+ return; - out: -- if (!data_ownership_taken) -- { -- g_object_unref (data->impl); -- gtk_file_path_free (data->path); -- gtk_file_path_free (data->parent_path); -- g_free (data); -- } -+ g_object_unref (data->impl); -+ gtk_file_paths_free (data->paths); -+ g_free (data); - +@@ -8378,51 +4210,7 @@ g_object_unref (handle); } @@ -9469,23 +6256,15 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c -paste_text_received (GtkClipboard *clipboard, - const gchar *text, - GtkFileChooserDefault *impl) -+static gboolean -+show_and_select_paths (GtkFileChooserDefault *impl, -+ const GtkFilePath *parent_path, -+ GSList *paths, -+ GError **error) - { +-{ - GtkFilePath *path; -+ struct ShowAndSelectPathsData *info; - if (!text) - return; -+ profile_start ("start", NULL); - +- - path = gtk_file_system_uri_to_path (impl->file_system, text); - if (!path) -+ if (!paths) - { +- { - if (!g_path_is_absolute (text)) - { - location_popup_handler (impl, text); @@ -9498,21 +6277,14 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - location_popup_handler (impl, text); - return; - } -+ profile_end ("end", NULL); -+ return TRUE; - } - +- } +- - if (!gtk_file_chooser_default_select_path (GTK_FILE_CHOOSER (impl), path, NULL)) - location_popup_handler (impl, text); -+ info = g_new (struct ShowAndSelectPathsData, 1); -+ info->impl = g_object_ref (impl); -+ info->paths = gtk_file_paths_copy (paths); - +- - gtk_file_path_free (path); -} -+ if (impl->show_and_select_paths_handle) -+ gtk_file_system_cancel_operation (impl->show_and_select_paths_handle); - +- -/* Handler for the "location-popup-on-paste" keybinding signal */ -static void -location_popup_on_paste_handler (GtkFileChooserDefault *impl) @@ -9523,326 +6295,60 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - (GtkClipboardTextReceivedFunc) paste_text_received, - impl); -} -+ impl->show_and_select_paths_handle = -+ gtk_file_system_get_folder (impl->file_system, parent_path, -+ GTK_FILE_INFO_IS_FOLDER | GTK_FILE_INFO_IS_HIDDEN, -+ show_and_select_paths_get_folder_cb, info); - -+ profile_end ("end", NULL); -+ return TRUE; -+} - --/* Implementation for GtkFileChooserEmbed::should_respond() */ --static gboolean --gtk_file_chooser_default_should_respond (GtkFileChooserEmbed *chooser_embed) -+/* Processes the pending operation when a folder is finished loading */ -+static void -+pending_select_paths_process (GtkFileChooserDefault *impl) - { -- GtkFileChooserDefault *impl; -- GtkWidget *toplevel; -- GtkWidget *current_focus; -+ g_assert (impl->load_state == LOAD_FINISHED); -+ g_assert (impl->browse_files_model != NULL); -+ g_assert (impl->sort_model != NULL); - -- impl = GTK_FILE_CHOOSER_DEFAULT (chooser_embed); -+ if (impl->pending_select_paths) -+ { -+ /* NULL GError */ -+ show_and_select_paths (impl, impl->current_folder, impl->pending_select_paths, NULL); -+ pending_select_paths_free (impl); -+ browse_files_center_selected_row (impl); -+ } -+ else -+ { -+ /* We only select the first row if the chooser is actually mapped --- -+ * selecting the first row is to help the user when he is interacting with -+ * the chooser, but sometimes a chooser works not on behalf of the user, -+ * but rather on behalf of something else like GtkFileChooserButton. In -+ * that case, the chooser's selection should be what the caller expects, -+ * as the user can't see that something else got selected. See bug #165264. -+ * -+ * Also, we don't select the first file if we are not in OPEN mode. Doing -+ * so would change the contents of the filename entry for SAVE or -+ * CREATE_FOLDER, which is undesired; in SELECT_FOLDER, we don't want to -+ * select a *different* folder from the one into which the user just -+ * navigated. -+ */ -+ if (GTK_WIDGET_MAPPED (impl) && impl->action == GTK_FILE_CHOOSER_ACTION_OPEN) -+ browse_files_select_first_row (impl); -+ } - -- toplevel = gtk_widget_get_toplevel (GTK_WIDGET (impl)); -- g_assert (GTK_IS_WINDOW (toplevel)); -+ g_assert (impl->pending_select_paths == NULL); -+} - -- current_focus = gtk_window_get_focus (GTK_WINDOW (toplevel)); -+/* Callback used when the file system model finishes loading */ -+static void -+browse_files_model_finished_loading_cb (GtkFileSystemModel *model, -+ GtkFileChooserDefault *impl) -+{ -+ profile_start ("start", NULL); - -- if (current_focus == impl->browse_files_tree_view) -+ if (impl->load_state == LOAD_PRELOAD) - { -- /* The following array encodes what we do based on the impl->action and the -- * number of files selected. -+ load_remove_timer (impl); -+ load_set_model (impl); -+ } -+ else if (impl->load_state == LOAD_LOADING) -+ { -+ /* Nothing */ -+ } -+ else -+ { -+ /* We can't g_assert_not_reached(), as something other than us may have -+ * initiated a folder reload. See #165556. - */ -- typedef enum { -- NOOP, /* Do nothing (don't respond) */ -- RESPOND, /* Respond immediately */ -- RESPOND_OR_SWITCH, /* Respond immediately if the selected item is a file; switch to it if it is a folder */ -- ALL_FILES, /* Respond only if everything selected is a file */ -- ALL_FOLDERS, /* Respond only if everything selected is a folder */ -- SAVE_ENTRY, /* Go to the code for handling the save entry */ -- NOT_REACHED /* Sanity check */ -- } ActionToTake; -- static const ActionToTake what_to_do[4][3] = { -- /* 0 selected 1 selected many selected */ -- /* ACTION_OPEN */ { NOOP, RESPOND_OR_SWITCH, ALL_FILES }, -- /* ACTION_SAVE */ { SAVE_ENTRY, RESPOND_OR_SWITCH, NOT_REACHED }, -- /* ACTION_SELECT_FOLDER */ { RESPOND, ALL_FOLDERS, ALL_FOLDERS }, -- /* ACTION_CREATE_FOLDER */ { SAVE_ENTRY, ALL_FOLDERS, NOT_REACHED } -- }; -- -- int num_selected; -- gboolean all_files, all_folders; -- int k; -- ActionToTake action; -+ profile_end ("end", NULL); -+ return; -+ } - -- file_list: -+ g_assert (impl->load_timeout_id == 0); +- +- + /* Implementation for GtkFileChooserEmbed::should_respond() */ + static gboolean + gtk_file_chooser_default_should_respond (GtkFileChooserEmbed *chooser_embed) +@@ -8469,12 +4257,6 @@ -- g_assert (impl->action >= GTK_FILE_CHOOSER_ACTION_OPEN && impl->action <= GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER); -+ impl->load_state = LOAD_FINISHED; + g_assert (impl->action >= GTK_FILE_CHOOSER_ACTION_OPEN && impl->action <= GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER); - if (impl->operation_mode == OPERATION_MODE_SEARCH) - return search_should_respond (impl); -+ pending_select_paths_process (impl); -+ set_busy_cursor (impl, FALSE); -+#ifdef PROFILE_FILE_CHOOSER -+ access ("MARK: *** FINISHED LOADING", F_OK); -+#endif - +- - if (impl->operation_mode == OPERATION_MODE_RECENT) - return recent_should_respond (impl); -+ profile_end ("end", NULL); -+} - -- selection_check (impl, &num_selected, &all_files, &all_folders); -+/* Gets rid of the old list model and creates a new one for the current folder */ -+static gboolean -+set_list_model (GtkFileChooserDefault *impl, -+ GError **error) -+{ -+ g_assert (impl->current_folder != NULL); - -- if (num_selected > 2) -- k = 2; -- else -- k = num_selected; -+ profile_start ("start", NULL); - -- action = what_to_do [impl->action] [k]; -+ load_remove_timer (impl); /* This changes the state to LOAD_EMPTY */ - -- switch (action) -- { -- case NOOP: -- return FALSE; -+ if (impl->browse_files_model) -+ { -+ g_object_unref (impl->browse_files_model); -+ impl->browse_files_model = NULL; -+ } - -- case RESPOND: -- return TRUE; -+ if (impl->sort_model) -+ { -+ g_object_unref (impl->sort_model); -+ impl->sort_model = NULL; -+ } - -- case RESPOND_OR_SWITCH: -- g_assert (num_selected == 1); -+ set_busy_cursor (impl, TRUE); -+ gtk_tree_view_set_model (GTK_TREE_VIEW (impl->browse_files_tree_view), NULL); - -- if (all_folders) -- { -- switch_to_selected_folder (impl); -- return FALSE; -- } -- else if (impl->action == GTK_FILE_CHOOSER_ACTION_SAVE) -- return should_respond_after_confirm_overwrite (impl, -- get_display_name_from_file_list (impl), -- impl->current_folder); -- else -- return TRUE; -+ impl->browse_files_model = _gtk_file_system_model_new (impl->file_system, -+ impl->current_folder, 0, -+ GTK_FILE_INFO_ALL, -+ error); -+ if (!impl->browse_files_model) -+ { -+ set_busy_cursor (impl, FALSE); -+ profile_end ("end", NULL); -+ return FALSE; -+ } - -- case ALL_FILES: -- return all_files; -+ load_setup_timer (impl); /* This changes the state to LOAD_PRELOAD */ - -- case ALL_FOLDERS: -- return all_folders; -+ g_signal_connect (impl->browse_files_model, "finished-loading", -+ G_CALLBACK (browse_files_model_finished_loading_cb), impl); - -- case SAVE_ENTRY: -- goto save_entry; -+ _gtk_file_system_model_set_show_hidden (impl->browse_files_model, impl->show_hidden); - -- default: -- g_assert_not_reached (); -- } -- } -- else if ((impl->location_entry != NULL) && (current_focus == impl->location_entry)) -- { -- GtkFilePath *path; -- gboolean is_well_formed, is_empty, is_file_part_empty; -- gboolean is_folder; -- gboolean retval; -- GtkFileChooserEntry *entry; -- GError *error; -+ install_list_model_filter (impl); +- + selection_check (impl, &num_selected, &all_files, &all_folders); -- save_entry: -+ profile_end ("end", NULL); + if (num_selected > 2) +@@ -8533,9 +4315,8 @@ -- g_assert (impl->action == GTK_FILE_CHOOSER_ACTION_SAVE -- || impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER + g_assert (impl->action == GTK_FILE_CHOOSER_ACTION_SAVE + || impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER - || ((impl->action == GTK_FILE_CHOOSER_ACTION_OPEN - || impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER) - && impl->location_mode == LOCATION_MODE_FILENAME_ENTRY)); -+ return TRUE; -+} - -- entry = GTK_FILE_CHOOSER_ENTRY (impl->location_entry); -- check_save_entry (impl, &path, &is_well_formed, &is_empty, &is_file_part_empty, &is_folder); -+struct update_chooser_entry_selected_foreach_closure { -+ int num_selected; -+ GtkTreeIter first_selected_iter; -+}; - -- if (is_empty || !is_well_formed) -- return FALSE; -+static gint -+compare_utf8_filenames (const gchar *a, -+ const gchar *b) -+{ -+ gchar *a_folded, *b_folded; -+ gint retval; - -- g_assert (path != NULL); -+ a_folded = g_utf8_strdown (a, -1); -+ b_folded = g_utf8_strdown (b, -1); ++ || impl->action == GTK_FILE_CHOOSER_ACTION_OPEN ++ || impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER); -- error = NULL; -- if (is_folder) -- { + entry = GTK_FILE_CHOOSER_ENTRY (impl->location_entry); + check_save_entry (impl, &path, &is_well_formed, &is_empty, &is_file_part_empty, &is_folder); +@@ -8548,14 +4329,14 @@ + error = NULL; + if (is_folder) + { - if (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN || - impl->action == GTK_FILE_CHOOSER_ACTION_SAVE) -- { ++ if (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN ++ || impl->action == GTK_FILE_CHOOSER_ACTION_SAVE) + { - change_folder_and_display_error (impl, path, TRUE); -- retval = FALSE; -- } ++ change_folder_and_display_error (impl, path); + retval = FALSE; + } - else if (impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER || - impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER) -- { -- /* The folder already exists, so we do not need to create it. -- * Just respond to terminate the dialog. -- */ -- retval = TRUE; -- } -- else -- { -- g_assert_not_reached (); -- retval = FALSE; -- } -- } -- else -- { -- struct FileExistsData *data; -+ retval = strcmp (a_folded, b_folded); - -- /* We need to check whether path exists and is not a folder */ -+ g_free (a_folded); -+ g_free (b_folded); - -- data = g_new0 (struct FileExistsData, 1); -- data->impl = g_object_ref (impl); -- data->path = gtk_file_path_copy (path); -- data->parent_path = gtk_file_path_copy (_gtk_file_chooser_entry_get_current_folder (entry)); -+ return retval; -+} - -- if (impl->file_exists_get_info_handle) -- gtk_file_system_cancel_operation (impl->file_exists_get_info_handle); -+static void -+update_chooser_entry_selected_foreach (GtkTreeModel *model, -+ GtkTreePath *path, -+ GtkTreeIter *iter, -+ gpointer data) -+{ -+ struct update_chooser_entry_selected_foreach_closure *closure; - -- impl->file_exists_get_info_handle = -- gtk_file_system_get_info (impl->file_system, path, -- GTK_FILE_INFO_IS_FOLDER, -- file_exists_get_info_cb, -- data); -+ closure = data; -+ closure->num_selected++; - -- set_busy_cursor (impl, TRUE); -- retval = FALSE; -+ if (closure->num_selected == 1) -+ closure->first_selected_iter = *iter; -+} - -- if (error != NULL) -- g_error_free (error); -- } -+static void -+update_chooser_entry (GtkFileChooserDefault *impl) -+{ -+ GtkTreeSelection *selection; -+ struct update_chooser_entry_selected_foreach_closure closure; -+ const char *file_part; - -- gtk_file_path_free (path); -- return retval; -- } ++ else if (impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER ++ || GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER) + { + /* The folder already exists, so we do not need to create it. + * Just respond to terminate the dialog. +@@ -8598,37 +4379,13 @@ + gtk_file_path_free (path); + return retval; + } - else if (impl->toplevel_last_focus_widget == impl->browse_shortcuts_tree_view) - { - /* The focus is on a dialog's action area button, *and* the widget that @@ -9850,12 +6356,7 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - * selected shortcut and tell the caller not to respond. - */ - GtkTreeIter iter; -+ if (!(impl->action == GTK_FILE_CHOOSER_ACTION_SAVE -+ || impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER -+ || impl->action == GTK_FILE_CHOOSER_ACTION_OPEN -+ || impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER)) -+ return; - +- - if (shortcuts_get_selected (impl, &iter)) - { - shortcuts_activate_iter (impl, &iter); @@ -9864,110 +6365,56 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - } - else - goto file_list; -+ g_assert (impl->location_entry != NULL); - +- - return FALSE; - } -- else if (impl->toplevel_last_focus_widget == impl->browse_files_tree_view) -- { -- /* The focus is on a dialog's action area button, *and* the widget that + else if (impl->toplevel_last_focus_widget == impl->browse_files_tree_view) + { + /* The focus is on a dialog's action area button, *and* the widget that - * was focused immediately before it is the file list. -- */ -- goto file_list; -- } ++ * was focused immediately before it is the file list. + */ + goto file_list; + } - else if (impl->operation_mode == OPERATION_MODE_SEARCH && impl->toplevel_last_focus_widget == impl->search_entry) -+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_files_tree_view)); -+ closure.num_selected = 0; -+ gtk_tree_selection_selected_foreach (selection, update_chooser_entry_selected_foreach, &closure); -+ -+ file_part = NULL; -+ -+ if (closure.num_selected == 0) - { +- { - search_entry_activate_cb (GTK_ENTRY (impl->search_entry), impl); - return FALSE; -+ goto maybe_clear_entry; - } -- else if (impl->location_entry && impl->toplevel_last_focus_widget == impl->location_entry) -+ else if (closure.num_selected == 1) - { -- /* The focus is on a dialog's action area button, *and* the widget that -- * was focused immediately before it is the location entry. -- */ -- goto save_entry; - } -- else -- /* The focus is on a dialog's action area button or something else */ -- if (impl->action == GTK_FILE_CHOOSER_ACTION_SAVE -- || impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER) -- goto save_entry; -- else -- goto file_list; -- -- g_assert_not_reached (); -- return FALSE; --} -+ GtkTreeIter child_iter; -+ const GtkFileInfo *info; -+ gboolean change_entry; - --/* Implementation for GtkFileChooserEmbed::initial_focus() */ --static void --gtk_file_chooser_default_initial_focus (GtkFileChooserEmbed *chooser_embed) --{ -- GtkFileChooserDefault *impl; -- GtkWidget *widget; -+ gtk_tree_model_sort_convert_iter_to_child_iter (impl->sort_model, -+ &child_iter, -+ &closure.first_selected_iter); + else if (impl->location_entry && impl->toplevel_last_focus_widget == impl->location_entry) + { + /* The focus is on a dialog's action area button, *and* the widget that +@@ -8657,17 +4414,16 @@ -- impl = GTK_FILE_CHOOSER_DEFAULT (chooser_embed); -+ info = _gtk_file_system_model_get_info (impl->browse_files_model, &child_iter); + impl = GTK_FILE_CHOOSER_DEFAULT (chooser_embed); - if (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN || - impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER) -- { ++ if (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN ++ || impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER) + { - if (impl->location_mode == LOCATION_MODE_PATH_BAR) -- widget = impl->browse_files_tree_view; -+ /* If the cursor moved to the row of the newly created folder, -+ * retrieving info will return NULL. -+ */ -+ if (!info) -+ return; -+ -+ g_free (impl->browse_files_last_selected_name); -+ impl->browse_files_last_selected_name = g_strdup (gtk_file_info_get_display_name (info)); -+ -+ if (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN -+ || impl->action == GTK_FILE_CHOOSER_ACTION_SAVE) -+ change_entry = !gtk_file_info_get_is_folder (info); /* We don't want the name to change when clicking on a folder... */ - else + widget = impl->browse_files_tree_view; +- else - widget = impl->location_entry; -+ change_entry = TRUE; /* ... unless we are in one of the folder modes */ -+ -+ if (change_entry) -+ _gtk_file_chooser_entry_set_file_part (GTK_FILE_CHOOSER_ENTRY (impl->location_entry), impl->browse_files_last_selected_name); -+ -+ return; } - else if (impl->action == GTK_FILE_CHOOSER_ACTION_SAVE || - impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER) - widget = impl->location_entry; ++ else if (impl->action == GTK_FILE_CHOOSER_ACTION_SAVE ++ || impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER) ++ { ++ widget = impl->location_entry; ++ } else { -- g_assert_not_reached (); -- widget = NULL; -- } -+ g_assert (!(impl->action == GTK_FILE_CHOOSER_ACTION_SAVE -+ || impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)); - -- g_assert (widget != NULL); -- gtk_widget_grab_focus (widget); --} -+ /* Multiple selection, so just clear the entry. */ + g_assert_not_reached (); +@@ -8678,1475 +4434,7 @@ + gtk_widget_grab_focus (widget); + } -/* Callback used from gtk_tree_selection_selected_foreach(); gets the selected GtkFilePaths */ --static void + static void -search_selected_foreach_get_path_cb (GtkTreeModel *model, - GtkTreePath *path, - GtkTreeIter *iter, @@ -9976,105 +6423,58 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - GSList **list; - const GtkFilePath *file_path; - GtkFilePath *file_path_copy; -+ g_free (impl->browse_files_last_selected_name); -+ impl->browse_files_last_selected_name = NULL; - +- - list = data; -+ _gtk_file_chooser_entry_set_file_part (GTK_FILE_CHOOSER_ENTRY (impl->location_entry), ""); -+ return; -+ } - +- - gtk_tree_model_get (model, iter, SEARCH_MODEL_COL_PATH, &file_path, -1); - file_path_copy = gtk_file_path_copy (file_path); - *list = g_slist_prepend (*list, file_path_copy); -} -+ maybe_clear_entry: - +- -/* Constructs a list of the selected paths in search mode */ -static GSList * -search_get_selected_paths (GtkFileChooserDefault *impl) -{ - GSList *result; - GtkTreeSelection *selection; -+ if (impl->browse_files_last_selected_name) -+ { -+ const char *entry_text; -+ int len; -+ gboolean clear_entry; - +- - result = NULL; -+ entry_text = gtk_entry_get_text (GTK_ENTRY (impl->location_entry)); -+ len = strlen (entry_text); -+ if (len != 0) -+ { -+ /* The file chooser entry may have appended a "/" to its text. So -+ * take it out, and compare the result to the old selection. -+ */ -+ if (entry_text[len - 1] == G_DIR_SEPARATOR) -+ { -+ char *tmp; - +- - selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_files_tree_view)); - gtk_tree_selection_selected_foreach (selection, search_selected_foreach_get_path_cb, &result); - result = g_slist_reverse (result); -+ tmp = g_strndup (entry_text, len - 1); -+ clear_entry = (compare_utf8_filenames (impl->browse_files_last_selected_name, tmp) == 0); -+ g_free (tmp); -+ } -+ else -+ clear_entry = (compare_utf8_filenames (impl->browse_files_last_selected_name, entry_text) == 0); -+ } -+ else -+ clear_entry = FALSE; - +- - return result; -+ if (clear_entry) -+ _gtk_file_chooser_entry_set_file_part (GTK_FILE_CHOOSER_ENTRY (impl->location_entry), ""); -+ } - } - +-} +- -/* Called from ::should_respond(). We return whether there are selected files - * in the search list. - */ - static gboolean +-static gboolean -search_should_respond (GtkFileChooserDefault *impl) -+gtk_file_chooser_default_set_current_folder (GtkFileChooser *chooser, -+ const GtkFilePath *path, -+ GError **error) - { +-{ - GtkTreeSelection *selection; - - g_assert (impl->operation_mode == OPERATION_MODE_SEARCH); - - selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_files_tree_view)); - return (gtk_tree_selection_count_selected_rows (selection) != 0); -+ return gtk_file_chooser_default_update_current_folder (chooser, path, FALSE, FALSE, error); - } - +-} +- -struct SearchHitInsertRequest -+ -+struct UpdateCurrentFolderData - { - GtkFileChooserDefault *impl; - GtkFilePath *path; +-{ +- GtkFileChooserDefault *impl; +- GtkFilePath *path; - GtkTreeRowReference *row_ref; -+ gboolean keep_trail; -+ gboolean clear_entry; -+ GtkFilePath *original_path; -+ GError *original_error; - }; - - static void +-}; +- +-static void -search_hit_get_info_cb (GtkFileSystemHandle *handle, - const GtkFileInfo *info, - const GError *error, - gpointer data) -+update_current_folder_get_info_cb (GtkFileSystemHandle *handle, -+ const GtkFileInfo *info, -+ const GError *error, -+ gpointer user_data) - { - gboolean cancelled = handle->cancelled; +-{ +- gboolean cancelled = handle->cancelled; - GdkPixbuf *pixbuf = NULL; - GtkTreePath *path; - GtkTreeIter iter; @@ -10086,14 +6486,11 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - - if (!request->impl->search_model) - goto out; -+ struct UpdateCurrentFolderData *data = user_data; -+ GtkFileChooserDefault *impl = data->impl; - +- - path = gtk_tree_row_reference_get_path (request->row_ref); - if (!path) -+ if (handle != impl->update_current_folder_handle) - goto out; - +- goto out; +- - gtk_tree_model_get_iter (GTK_TREE_MODEL (request->impl->search_model), - &iter, path); - gtk_tree_path_free (path); @@ -10103,70 +6500,46 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - -1); - if (handle != model_handle) - goto out; -+ impl->update_current_folder_handle = NULL; -+ impl->reload_state = RELOAD_EMPTY; - +- - /* set the handle to NULL in the model */ - gtk_list_store_set (request->impl->search_model, &iter, - SEARCH_MODEL_COL_HANDLE, NULL, - -1); -+ set_busy_cursor (impl, FALSE); - - if (cancelled) - goto out; - +- +- if (cancelled) +- goto out; +- - if (!info) -+ if (error) - { +- { - gtk_list_store_remove (request->impl->search_model, &iter); - goto out; - } -+ GtkFilePath *parent_path; - +- - display_name = g_strdup (gtk_file_info_get_display_name (info)); - mime_type = g_strdup (gtk_file_info_get_mime_type (info)); - is_folder = gtk_file_info_get_is_folder (info); - pixbuf = gtk_file_info_render_icon (info, GTK_WIDGET (request->impl), - request->impl->icon_size, NULL); -+ if (!data->original_path) -+ { -+ data->original_path = gtk_file_path_copy (data->path); -+ data->original_error = g_error_copy (error); -+ } - +- - gtk_list_store_set (request->impl->search_model, &iter, - SEARCH_MODEL_COL_PIXBUF, pixbuf, - SEARCH_MODEL_COL_DISPLAY_NAME, display_name, - SEARCH_MODEL_COL_MIME_TYPE, mime_type, - SEARCH_MODEL_COL_IS_FOLDER, is_folder, - -1); -+ /* get parent path and try to change the folder to that */ -+ if (gtk_file_system_get_parent (impl->file_system, data->path, &parent_path, NULL) && -+ parent_path) -+ { -+ gtk_file_path_free (data->path); -+ data->path = parent_path; - +- - if (pixbuf) - g_object_unref (pixbuf); -+ g_object_unref (handle); - +- -out: - g_object_unref (request->impl); - gtk_file_path_free (request->path); - gtk_tree_row_reference_free (request->row_ref); - g_free (request); -+ /* restart the update current folder operation */ -+ impl->reload_state = RELOAD_HAS_FOLDER; - +- - g_object_unref (handle); -} -+ impl->update_current_folder_handle = -+ gtk_file_system_get_info (impl->file_system, data->path, -+ GTK_FILE_INFO_IS_FOLDER, -+ update_current_folder_get_info_cb, -+ data); - +- -/* Adds one hit from the search engine to the search_model */ -static void -search_add_hit (GtkFileChooserDefault *impl, @@ -10182,50 +6555,28 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - GtkTreePath *p; - GtkFileSystemHandle *handle; - struct SearchHitInsertRequest *request; -+ set_busy_cursor (impl, TRUE); - +- - path = gtk_file_system_uri_to_path (impl->file_system, uri); - if (!path) - return; -+ return; -+ } -+ else -+ { -+ /* error and bail out */ -+ error_changing_folder_dialog (impl, data->original_path, data->original_error); - +- - filename = gtk_file_system_path_to_filename (impl->file_system, path); - if (!filename) - { - gtk_file_path_free (path); - return; -+ gtk_file_path_free (data->original_path); -+ -+ goto out; -+ } - } - +- } +- - if (stat (filename, &statbuf) != 0) -+ if (data->original_path) - { +- { - gtk_file_path_free (path); - g_free (filename); - return; -+ error_changing_folder_dialog (impl, data->original_path, data->original_error); -+ -+ gtk_file_path_free (data->original_path); - } - +- } +- - statbuf_copy = g_new (struct stat, 1); - *statbuf_copy = statbuf; -+ if (!gtk_file_info_get_is_folder (info)) -+ goto out; -+ -+ if (impl->current_folder != data->path) -+ { -+ if (impl->current_folder) -+ gtk_file_path_free (impl->current_folder); - +- - tmp = g_filename_display_name (filename); - collation_key = g_utf8_collate_key_for_filename (tmp, -1); - g_free (tmp); @@ -10233,16 +6584,13 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - request = g_new0 (struct SearchHitInsertRequest, 1); - request->impl = g_object_ref (impl); - request->path = gtk_file_path_copy (path); -+ impl->current_folder = gtk_file_path_copy (data->path); - +- - gtk_list_store_append (impl->search_model, &iter); - p = gtk_tree_model_get_path (GTK_TREE_MODEL (impl->search_model), &iter); - - request->row_ref = gtk_tree_row_reference_new (GTK_TREE_MODEL (impl->search_model), p); - gtk_tree_path_free (p); -+ impl->reload_state = RELOAD_HAS_FOLDER; -+ } - +- - handle = gtk_file_system_get_info (impl->file_system, path, - GTK_FILE_INFO_IS_FOLDER | GTK_FILE_INFO_ICON | GTK_FILE_INFO_MIME_TYPE | GTK_FILE_INFO_DISPLAY_NAME, - search_hit_get_info_cb, @@ -10266,16 +6614,11 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - GList *l; - - impl = GTK_FILE_CHOOSER_DEFAULT (data); -+ /* Set the folder on the save entry */ - +- - for (l = hits; l; l = l->next) - search_add_hit (impl, (gchar*)l->data); -} -+ if (impl->location_entry) -+ { -+ _gtk_file_chooser_entry_set_base_folder (GTK_FILE_CHOOSER_ENTRY (impl->location_entry), -+ impl->current_folder); - +- -/* Callback used from GtkSearchEngine when the query is done running */ -static void -search_engine_finished_cb (GtkSearchEngine *engine, @@ -10292,19 +6635,11 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - gtk_tree_view_set_model (GTK_TREE_VIEW (impl->browse_files_tree_view), - GTK_TREE_MODEL (impl->search_model_filter)); -#endif -+ if (data->clear_entry) -+ _gtk_file_chooser_entry_set_file_part (GTK_FILE_CHOOSER_ENTRY (impl->location_entry), ""); -+ } - +- - /* FMQ: if search was empty, say that we got no hits */ - set_busy_cursor (impl, FALSE); -} -+ /* Create a new list model. This is slightly evil; we store the result value -+ * but perform more actions rather than returning immediately even if it -+ * generates an error. -+ */ -+ set_list_model (impl, NULL); - +- -/* Displays a generic error when we cannot create a GtkSearchEngine. - * It would be better if _gtk_search_engine_new() gave us a GError - * with a better message, but it doesn't do that right now. @@ -10317,8 +6652,7 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - _("The program was not able to create a connection to the indexer " - "daemon. Please make sure it is running.")); -} -+ /* Refresh controls */ - +- -static void -search_engine_error_cb (GtkSearchEngine *engine, - const gchar *message, @@ -10327,30 +6661,18 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - GtkFileChooserDefault *impl; - - impl = GTK_FILE_CHOOSER_DEFAULT (data); -+ g_signal_emit_by_name (impl, "current-folder-changed", 0); -+ g_signal_emit_by_name (impl, "selection-changed", 0); - +- - search_stop_searching (impl, TRUE); - error_message (impl, _("Could not send the search request"), message); -+out: -+ gtk_file_path_free (data->path); -+ g_free (data); - +- - set_busy_cursor (impl, FALSE); -+ g_object_unref (handle); - } - +-} +- -/* Frees the data in the search_model */ -static void -search_clear_model (GtkFileChooserDefault *impl, - gboolean remove_from_treeview) -+static gboolean -+gtk_file_chooser_default_update_current_folder (GtkFileChooser *chooser, -+ const GtkFilePath *path, -+ gboolean keep_trail, -+ gboolean clear_entry, -+ GError **error) - { +-{ - GtkTreeModel *model; - GtkTreeIter iter; - @@ -10385,9 +6707,7 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - g_free (statbuf); - } - while (gtk_tree_model_iter_next (model, &iter)); -+ GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (chooser); -+ struct UpdateCurrentFolderData *data; - +- - g_object_unref (impl->search_model); - impl->search_model = NULL; - @@ -10396,13 +6716,11 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - - g_object_unref (impl->search_model_sort); - impl->search_model_sort = NULL; -+ profile_start ("start", (char *) path); - +- - if (remove_from_treeview) - gtk_tree_view_set_model (GTK_TREE_VIEW (impl->browse_files_tree_view), NULL); -} -+ g_assert (path != NULL); - +- -/* Stops any ongoing searches; does not touch the search_model */ -static void -search_stop_searching (GtkFileChooserDefault *impl, @@ -10415,9 +6733,7 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - } - - if (impl->search_engine) -+ if (impl->local_only && -+ !gtk_file_system_path_is_local (impl->file_system, path)) - { +- { - _gtk_search_engine_stop (impl->search_engine); - - g_object_unref (impl->search_engine); @@ -10430,76 +6746,46 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c -search_switch_to_browse_mode (GtkFileChooserDefault *impl) -{ - g_assert (impl->operation_mode != OPERATION_MODE_BROWSE); -+ g_set_error (error, -+ GTK_FILE_CHOOSER_ERROR, -+ GTK_FILE_CHOOSER_ERROR_BAD_FILENAME, -+ _("Cannot change to folder because it is not local")); - +- - search_stop_searching (impl, FALSE); - search_clear_model (impl, TRUE); -+ profile_end ("end - not local", (char *) path); -+ return FALSE; -+ } - +- - gtk_widget_destroy (impl->search_hbox); - impl->search_hbox = NULL; - impl->search_entry = NULL; -+ if (impl->update_current_folder_handle) -+ gtk_file_system_cancel_operation (impl->update_current_folder_handle); - +- - gtk_widget_show (impl->browse_path_bar); - gtk_widget_show (impl->browse_new_folder_button); -+ /* Test validity of path here. */ -+ data = g_new0 (struct UpdateCurrentFolderData, 1); -+ data->impl = impl; -+ data->path = gtk_file_path_copy (path); -+ data->keep_trail = keep_trail; -+ data->clear_entry = clear_entry; - +- - if (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN || - impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER) - { - gtk_widget_show (impl->location_button); -+ impl->reload_state = RELOAD_HAS_FOLDER; - +- - if (impl->location_mode == LOCATION_MODE_FILENAME_ENTRY) - gtk_widget_show (impl->location_entry_box); - } -+ impl->update_current_folder_handle = -+ gtk_file_system_get_info (impl->file_system, path, GTK_FILE_INFO_IS_FOLDER, -+ update_current_folder_get_info_cb, -+ data); - +- - impl->operation_mode = OPERATION_MODE_BROWSE; -+ set_busy_cursor (impl, TRUE); - +- - file_list_set_sort_column_ids (impl); -+ profile_end ("end", NULL); -+ return TRUE; - } - +-} +- -/* Sort callback from the path column */ -static gint -search_column_path_sort_func (GtkTreeModel *model, - GtkTreeIter *a, - GtkTreeIter *b, - gpointer user_data) -+static GtkFilePath * -+gtk_file_chooser_default_get_current_folder (GtkFileChooser *chooser) - { +-{ - GtkFileChooserDefault *impl = user_data; - GtkTreeIter child_a, child_b; - const char *collation_key_a, *collation_key_b; - gboolean is_folder_a, is_folder_b; -+ GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (chooser); - +- - gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER (model), &child_a, a); - gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER (model), &child_b, b); -+ if (impl->reload_state == RELOAD_EMPTY) -+ { -+ char *current_working_dir; -+ GtkFilePath *path; - +- - gtk_tree_model_get (GTK_TREE_MODEL (impl->search_model), &child_a, - SEARCH_MODEL_COL_IS_FOLDER, &is_folder_a, - SEARCH_MODEL_COL_COLLATION_KEY, &collation_key_a, @@ -10508,53 +6794,28 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - SEARCH_MODEL_COL_IS_FOLDER, &is_folder_b, - SEARCH_MODEL_COL_COLLATION_KEY, &collation_key_b, - -1); -+ /* We are unmapped, or we had an error while loading the last folder. We'll return -+ * the $cwd since once we get (re)mapped, we'll load $cwd anyway unless the caller -+ * explicitly calls set_current_folder() on us. -+ */ -+ current_working_dir = g_get_current_dir (); -+ path = gtk_file_system_filename_to_path (impl->file_system, current_working_dir); -+ g_free (current_working_dir); -+ return path; -+ } - +- - if (!collation_key_a) - return 1; -+ return gtk_file_path_copy (impl->current_folder); -+} - +- - if (!collation_key_b) - return -1; -+static void -+gtk_file_chooser_default_set_current_name (GtkFileChooser *chooser, -+ const gchar *name) -+{ -+ GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (chooser); - +- - /* always show folders first */ - if (is_folder_a != is_folder_b) - return is_folder_a ? 1 : -1; -+ g_return_if_fail (impl->action == GTK_FILE_CHOOSER_ACTION_SAVE -+ || impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER); - +- - return strcmp (collation_key_a, collation_key_b); -+ pending_select_paths_free (impl); -+ _gtk_file_chooser_entry_set_file_part (GTK_FILE_CHOOSER_ENTRY (impl->location_entry), name); - } - +-} +- -/* Sort callback from the modification time column */ -static gint -search_column_mtime_sort_func (GtkTreeModel *model, - GtkTreeIter *a, - GtkTreeIter *b, - gpointer user_data) -+static void -+select_func (GtkFileSystemModel *model, -+ GtkTreePath *path, -+ GtkTreeIter *iter, -+ gpointer user_data) - { - GtkFileChooserDefault *impl = user_data; +-{ +- GtkFileChooserDefault *impl = user_data; - GtkTreeIter child_a, child_b; - const struct stat *statbuf_a, *statbuf_b; - gboolean is_folder_a, is_folder_b; @@ -10581,167 +6842,100 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - - if (!statbuf_b) - return -1; -+ GtkTreeSelection *selection; -+ GtkTreeIter sorted_iter; - +- - if (is_folder_a != is_folder_b) - return is_folder_a ? 1 : -1; -+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_files_tree_view)); - +- - if (statbuf_a->st_mtime < statbuf_b->st_mtime) - return -1; - else if (statbuf_a->st_mtime > statbuf_b->st_mtime) - return 1; - else - return 0; -+ gtk_tree_model_sort_convert_child_iter_to_iter (impl->sort_model, &sorted_iter, iter); -+ gtk_tree_selection_select_iter (selection, &sorted_iter); - } - - static gboolean +-} +- +-static gboolean -search_get_is_filtered (GtkFileChooserDefault *impl, - const GtkFilePath *path, - const gchar *display_name, - const gchar *mime_type) -+gtk_file_chooser_default_select_path (GtkFileChooser *chooser, -+ const GtkFilePath *path, -+ GError **error) - { +-{ - GtkFileFilterInfo filter_info; - GtkFileFilterFlags needed; - gboolean result; -+ GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (chooser); -+ GtkFilePath *parent_path; -+ gboolean same_path; - +- - if (!impl->current_filter) -+ if (!gtk_file_system_get_parent (impl->file_system, path, &parent_path, error)) - return FALSE; - +- return FALSE; +- - filter_info.contains = GTK_FILE_FILTER_DISPLAY_NAME | GTK_FILE_FILTER_MIME_TYPE; - needed = gtk_file_filter_get_needed (impl->current_filter); - - filter_info.display_name = display_name; - filter_info.mime_type = mime_type; -+ if (!parent_path) -+ return _gtk_file_chooser_set_current_folder_path (chooser, path, error); - +- - if (needed & GTK_FILE_FILTER_FILENAME) -+ if (impl->load_state == LOAD_EMPTY) -+ same_path = FALSE; -+ else - { +- { - filter_info.filename = gtk_file_system_path_to_filename (impl->file_system, path); - if (filter_info.filename) - filter_info.contains |= GTK_FILE_FILTER_FILENAME; -+ g_assert (impl->current_folder != NULL); -+ -+ same_path = gtk_file_path_compare (parent_path, impl->current_folder) == 0; - } +- } - else - filter_info.filename = NULL; - +- - if (needed & GTK_FILE_FILTER_URI) -+ if (same_path && impl->load_state == LOAD_FINISHED) - { +- { - filter_info.uri = gtk_file_system_path_to_uri (impl->file_system, path); - if (filter_info.uri) - filter_info.contains |= GTK_FILE_FILTER_URI; -+ gboolean result; -+ GSList paths; -+ -+ paths.data = (gpointer) path; -+ paths.next = NULL; -+ -+ result = show_and_select_paths (impl, parent_path, &paths, error); -+ gtk_file_path_free (parent_path); -+ return result; - } +- } - else - filter_info.uri = NULL; - +- - result = gtk_file_filter_filter (impl->current_filter, &filter_info); -+ pending_select_paths_add (impl, path); - +- - if (filter_info.filename) - g_free ((gchar *) filter_info.filename); - if (filter_info.uri) - g_free ((gchar *) filter_info.uri); -+ if (!same_path) -+ { -+ gboolean result; - +- - return !result; -+ result = _gtk_file_chooser_set_current_folder_path (chooser, parent_path, error); -+ gtk_file_path_free (parent_path); -+ return result; -+ } - -+ gtk_file_path_free (parent_path); -+ return TRUE; - } - +- +-} +- -/* Visibility function for the recent filter model */ -static gboolean -search_model_visible_func (GtkTreeModel *model, - GtkTreeIter *iter, - gpointer user_data) -+static void -+unselect_func (GtkFileSystemModel *model, -+ GtkTreePath *path, -+ GtkTreeIter *iter, -+ gpointer user_data) - { - GtkFileChooserDefault *impl = user_data; +-{ +- GtkFileChooserDefault *impl = user_data; - GtkFilePath *file_path; - gchar *display_name, *mime_type; - gboolean is_folder; - - if (!impl->current_filter) - return TRUE; -+ GtkTreeView *tree_view = GTK_TREE_VIEW (impl->browse_files_tree_view); -+ GtkTreePath *sorted_path; - +- - gtk_tree_model_get (model, iter, - SEARCH_MODEL_COL_PATH, &file_path, - SEARCH_MODEL_COL_IS_FOLDER, &is_folder, - SEARCH_MODEL_COL_DISPLAY_NAME, &display_name, - SEARCH_MODEL_COL_MIME_TYPE, &mime_type, - -1); -+ sorted_path = gtk_tree_model_sort_convert_child_path_to_path (impl->sort_model, -+ path); -+ gtk_tree_selection_unselect_path (gtk_tree_view_get_selection (tree_view), -+ sorted_path); -+ gtk_tree_path_free (sorted_path); -+} - +- - if (!display_name) - return TRUE; -+static void -+gtk_file_chooser_default_unselect_path (GtkFileChooser *chooser, -+ const GtkFilePath *path) -+{ -+ GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (chooser); - +- - if (is_folder) - return TRUE; -+ if (!impl->browse_files_model) -+ return; - +- - return !search_get_is_filtered (impl, file_path, display_name, mime_type); -+ _gtk_file_system_model_path_do (impl->browse_files_model, path, -+ unselect_func, impl); - } - +-} +- -/* Creates the search_model and puts it in the tree view */ -static void -search_setup_model (GtkFileChooserDefault *impl) -+static gboolean -+maybe_select (GtkTreeModel *model, -+ GtkTreePath *path, -+ GtkTreeIter *iter, -+ gpointer data) - { +-{ - g_assert (impl->search_model == NULL); - g_assert (impl->search_model_filter == NULL); - g_assert (impl->search_model_sort == NULL); @@ -10772,11 +6966,7 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - GDK_TYPE_PIXBUF, - G_TYPE_POINTER, - G_TYPE_BOOLEAN); -+ GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (data); -+ GtkTreeSelection *selection; -+ const GtkFileInfo *info; -+ gboolean is_folder; - +- - impl->search_model_filter = - GTK_TREE_MODEL_FILTER (gtk_tree_model_filter_new (GTK_TREE_MODEL (impl->search_model), NULL)); - gtk_tree_model_filter_set_visible_func (impl->search_model_filter, @@ -10803,44 +6993,21 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - */ - gtk_tree_view_set_model (GTK_TREE_VIEW (impl->browse_files_tree_view), - GTK_TREE_MODEL (impl->search_model_sort)); -+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_files_tree_view)); -+ -+ info = get_list_file_info (impl, iter); -+ is_folder = gtk_file_info_get_is_folder (info); -+ -+ if ((is_folder && impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER) || -+ (!is_folder && impl->action == GTK_FILE_CHOOSER_ACTION_OPEN)) -+ gtk_tree_selection_select_iter (selection, iter); -+ else -+ gtk_tree_selection_unselect_iter (selection, iter); -+ -+ return FALSE; - } - - static void +-} +- +-static void -search_get_valid_child_iter (GtkFileChooserDefault *impl, - GtkTreeIter *child_iter, - GtkTreeIter *iter) -+gtk_file_chooser_default_select_all (GtkFileChooser *chooser) - { +-{ - GtkTreeIter middle; - - if (!impl->search_model) - return; -+ GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (chooser); -+ if (impl->select_multiple) -+ gtk_tree_model_foreach (GTK_TREE_MODEL (impl->sort_model), -+ maybe_select, impl); -+} - +- - if (!impl->search_model_filter || !impl->search_model_sort) - return; -+static void -+gtk_file_chooser_default_unselect_all (GtkFileChooser *chooser) -+{ -+ GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (chooser); -+ GtkTreeSelection *selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_files_tree_view)); - +- - /* pass 1: get the iterator in the filter model */ - gtk_tree_model_sort_convert_iter_to_child_iter (impl->search_model_sort, - &middle, iter); @@ -10848,98 +7015,46 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - /* pass 2: get the iterator in the real model */ - gtk_tree_model_filter_convert_iter_to_child_iter (impl->search_model_filter, - child_iter, &middle); -+ gtk_tree_selection_unselect_all (selection); -+ pending_select_paths_free (impl); - } - +-} +- -/* Creates a new query with the specified text and launches it */ -+/* Checks whether the filename entry for the Save modes contains a well-formed filename. -+ * -+ * is_well_formed_ret - whether what the user typed passes gkt_file_system_make_path() -+ * -+ * is_empty_ret - whether the file entry is totally empty -+ * -+ * is_file_part_empty_ret - whether the file part is empty (will be if user types "foobar/", and -+ * the path will be "$cwd/foobar") -+ */ - static void +-static void -search_start_query (GtkFileChooserDefault *impl, - const gchar *query_text) -+check_save_entry (GtkFileChooserDefault *impl, -+ GtkFilePath **path_ret, -+ gboolean *is_well_formed_ret, -+ gboolean *is_empty_ret, -+ gboolean *is_file_part_empty_ret, -+ gboolean *is_folder) - { +-{ - search_stop_searching (impl, FALSE); - search_clear_model (impl, TRUE); - search_setup_model (impl); - set_busy_cursor (impl, TRUE); -+ GtkFileChooserEntry *chooser_entry; -+ const GtkFilePath *current_folder; -+ const char *file_part; -+ GtkFilePath *path; -+ GError *error; - +- - if (impl->search_engine == NULL) - impl->search_engine = _gtk_search_engine_new (); -+ g_assert (impl->action == GTK_FILE_CHOOSER_ACTION_SAVE -+ || impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER -+ || impl->action == GTK_FILE_CHOOSER_ACTION_OPEN -+ || impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER); -+ -+ chooser_entry = GTK_FILE_CHOOSER_ENTRY (impl->location_entry); - +- - if (!impl->search_engine) -+ if (strlen (gtk_entry_get_text (GTK_ENTRY (chooser_entry))) == 0) - { +- { - set_busy_cursor (impl, FALSE); - search_error_could_not_create_client (impl); /* lame; we don't get an error code or anything */ -+ *path_ret = NULL; -+ *is_well_formed_ret = TRUE; -+ *is_empty_ret = TRUE; -+ *is_file_part_empty_ret = TRUE; -+ *is_folder = FALSE; -+ - return; - } - +- return; +- } +- - if (!impl->search_query) -+ *is_empty_ret = FALSE; -+ -+ current_folder = _gtk_file_chooser_entry_get_current_folder (chooser_entry); -+ if (!current_folder) - { +- { - impl->search_query = _gtk_query_new (); - _gtk_query_set_text (impl->search_query, query_text); -+ *path_ret = NULL; -+ *is_well_formed_ret = FALSE; -+ *is_file_part_empty_ret = FALSE; -+ *is_folder = FALSE; -+ -+ return; - } +- } - - _gtk_search_engine_set_query (impl->search_engine, impl->search_query); - +- - g_signal_connect (impl->search_engine, "hits-added", - G_CALLBACK (search_engine_hits_added_cb), impl); - g_signal_connect (impl->search_engine, "finished", - G_CALLBACK (search_engine_finished_cb), impl); - g_signal_connect (impl->search_engine, "error", - G_CALLBACK (search_engine_error_cb), impl); -+ file_part = _gtk_file_chooser_entry_get_file_part (chooser_entry); - +- - _gtk_search_engine_start (impl->search_engine); -} -+ if (!file_part || file_part[0] == '\0') -+ { -+ *path_ret = gtk_file_path_copy (current_folder); -+ *is_well_formed_ret = TRUE; -+ *is_file_part_empty_ret = TRUE; -+ *is_folder = TRUE; - +- -/* Callback used when the user presses Enter while typing on the search - * entry; starts the query - */ @@ -10949,113 +7064,55 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c -{ - GtkFileChooserDefault *impl; - const char *text; -+ return; -+ } - +- - impl = GTK_FILE_CHOOSER_DEFAULT (data); -+ *is_file_part_empty_ret = FALSE; - +- - text = gtk_entry_get_text (GTK_ENTRY (impl->search_entry)); - if (strlen (text) == 0) - return; -+ error = NULL; -+ path = gtk_file_system_make_path (impl->file_system, current_folder, file_part, &error); - +- - /* reset any existing query object */ - if (impl->search_query) -+ if (!path) - { +- { - g_object_unref (impl->search_query); - impl->search_query = NULL; -+ error_building_filename_dialog (impl, current_folder, file_part, error); -+ *path_ret = NULL; -+ *is_well_formed_ret = FALSE; -+ *is_folder = FALSE; -+ -+ return; - } - +- } +- - search_start_query (impl, text); -+ *path_ret = path; -+ *is_well_formed_ret = TRUE; -+ *is_folder = _gtk_file_chooser_entry_get_is_folder (chooser_entry, path); - } - +-} +- -/* Hides the path bar and creates the search entry */ -+struct get_paths_closure { -+ GtkFileChooserDefault *impl; -+ GSList *result; -+ GtkFilePath *path_from_entry; -+}; -+ - static void +-static void -search_setup_widgets (GtkFileChooserDefault *impl) -+get_paths_foreach (GtkTreeModel *model, -+ GtkTreePath *path, -+ GtkTreeIter *iter, -+ gpointer data) - { +-{ - GtkWidget *label; -+ struct get_paths_closure *info; -+ const GtkFilePath *file_path; -+ GtkFileSystemModel *fs_model; -+ GtkTreeIter sel_iter; -+ -+ info = data; -+ fs_model = info->impl->browse_files_model; -+ gtk_tree_model_sort_convert_iter_to_child_iter (info->impl->sort_model, &sel_iter, iter); - +- - impl->search_hbox = gtk_hbox_new (FALSE, 12); -+ file_path = _gtk_file_system_model_get_path (fs_model, &sel_iter); -+ if (!file_path) -+ return; /* We are on the editable row */ - +- - /* Label */ -+ if (!info->path_from_entry -+ || gtk_file_path_compare (info->path_from_entry, file_path) != 0) -+ info->result = g_slist_prepend (info->result, gtk_file_path_copy (file_path)); -+} - +- - label = gtk_label_new_with_mnemonic (_("_Search:")); - gtk_box_pack_start (GTK_BOX (impl->search_hbox), label, FALSE, FALSE, 0); -+static GSList * -+gtk_file_chooser_default_get_paths (GtkFileChooser *chooser) -+{ -+ GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (chooser); -+ struct get_paths_closure info; -+ GtkWindow *toplevel; -+ GtkWidget *current_focus; - +- - /* Entry */ -+ info.impl = impl; -+ info.result = NULL; -+ info.path_from_entry = NULL; - +- - impl->search_entry = gtk_entry_new (); - gtk_label_set_mnemonic_widget (GTK_LABEL (label), impl->search_entry); - g_signal_connect (impl->search_entry, "activate", - G_CALLBACK (search_entry_activate_cb), - impl); - gtk_box_pack_start (GTK_BOX (impl->search_hbox), impl->search_entry, TRUE, TRUE, 0); -+ toplevel = get_toplevel (GTK_WIDGET (impl)); -+ if (toplevel) -+ current_focus = gtk_window_get_focus (toplevel); -+ else -+ current_focus = NULL; - +- - /* if there already is a query, restart it */ - if (impl->search_query) -+ if (current_focus == impl->browse_files_tree_view) - { +- { - gchar *query = _gtk_query_get_text (impl->search_query); -+ GtkTreeSelection *selection; - +- - if (query) - { - gtk_entry_set_text (GTK_ENTRY (impl->search_entry), query); - search_start_query (impl, query); -+ file_list: - +- - g_free (query); - } - else @@ -11063,124 +7120,43 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - g_object_unref (impl->search_query); - impl->search_query = NULL; - } -+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_files_tree_view)); -+ gtk_tree_selection_selected_foreach (selection, get_paths_foreach, &info); -+ -+ /* If there is no selection in the file list, we probably have this situation: -+ * -+ * 1. The user typed a filename in the SAVE filename entry ("foo.txt"). -+ * 2. He then double-clicked on a folder ("bar") in the file list -+ * -+ * So we want the selection to be "bar/foo.txt". Jump to the case for the -+ * filename entry to see if that is the case. -+ */ -+ if (info.result == NULL && impl->location_entry) -+ goto file_entry; - } -+ else if (impl->location_entry && current_focus == impl->location_entry) -+ { -+ gboolean is_well_formed, is_empty, is_file_part_empty, is_folder; -+ -+ file_entry: -+ -+ check_save_entry (impl, &info.path_from_entry, &is_well_formed, &is_empty, &is_file_part_empty, &is_folder); -+ -+ if (is_empty) -+ goto out; - +- } +- - gtk_widget_hide (impl->browse_path_bar); - gtk_widget_hide (impl->browse_new_folder_button); -+ if (!is_well_formed) -+ return NULL; -+ -+ if (is_file_part_empty && impl->action == GTK_FILE_CHOOSER_ACTION_SAVE) -+ { -+ gtk_file_path_free (info.path_from_entry); -+ return NULL; -+ } - +- - /* Box for search widgets */ - gtk_box_pack_start (GTK_BOX (impl->browse_path_bar_hbox), impl->search_hbox, TRUE, TRUE, 0); - gtk_widget_show_all (impl->search_hbox); -+ g_assert (info.path_from_entry != NULL); -+ info.result = g_slist_prepend (info.result, info.path_from_entry); -+ } -+ else if (impl->toplevel_last_focus_widget == impl->browse_files_tree_view) -+ goto file_list; -+ else if (impl->location_entry && impl->toplevel_last_focus_widget == impl->location_entry) -+ goto file_entry; -+ else -+ { -+ /* The focus is on a dialog's action area button or something else */ -+ if (impl->action == GTK_FILE_CHOOSER_ACTION_SAVE -+ || impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER) -+ goto file_entry; -+ else -+ goto file_list; -+ } - +- - /* Hide the location widgets temporarily */ -+ out: - +- - if (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN || - impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER) -+ /* If there's no folder selected, and we're in SELECT_FOLDER mode, then we -+ * fall back to the current directory */ -+ if (impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER && -+ info.result == NULL) - { +- { - gtk_widget_hide (impl->location_button); - gtk_widget_hide (impl->location_entry_box); -+ info.result = g_slist_prepend (info.result, _gtk_file_chooser_get_current_folder_path (chooser)); - } - +- } +- - gtk_widget_grab_focus (impl->search_entry); -+ return g_slist_reverse (info.result); -+} -+ -+static GtkFileSystem * -+gtk_file_chooser_default_get_file_system (GtkFileChooser *chooser) -+{ -+ GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (chooser); - +- - /* FMQ: hide the filter combo? */ -+ return impl->file_system; - } - +-} +- -/* Main entry point to the searching functions; this gets called when the user - * activates the Search shortcut. - */ -+/* Shows or hides the filter widgets */ - static void +-static void -search_activate (GtkFileChooserDefault *impl) -+show_filters (GtkFileChooserDefault *impl, -+ gboolean show) - { +-{ - OperationMode previous_mode; - - if (impl->operation_mode == OPERATION_MODE_SEARCH) -+ if (show) -+ gtk_widget_show (impl->filter_combo); -+ else -+ gtk_widget_hide (impl->filter_combo); -+} -+ -+static void -+gtk_file_chooser_default_add_filter (GtkFileChooser *chooser, -+ GtkFileFilter *filter) -+{ -+ GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (chooser); -+ const gchar *name; -+ -+ g_debug ("adding filter"); -+ -+ if (g_slist_find (impl->filters, filter)) - { +- { - gtk_widget_grab_focus (impl->search_entry); -+ g_warning ("gtk_file_chooser_add_filter() called on filter already in list\n"); - return; - } - +- return; +- } +- - previous_mode = impl->operation_mode; - impl->operation_mode = OPERATION_MODE_SEARCH; - @@ -11190,50 +7166,37 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - recent_stop_loading (impl); - recent_clear_model (impl, TRUE); - break; -+ g_object_ref_sink (filter); -+ impl->filters = g_slist_append (impl->filters, filter); - +- - case OPERATION_MODE_BROWSE: - stop_loading_and_clear_list_model (impl); - break; -+ name = gtk_file_filter_get_name (filter); -+ if (!name) -+ name = "Untitled filter"; /* Place-holder, doesn't need to be marked for translation */ - +- - case OPERATION_MODE_SEARCH: - g_assert_not_reached (); - break; - } -+ gtk_combo_box_append_text (GTK_COMBO_BOX (impl->filter_combo), name); - +- - g_assert (impl->search_hbox == NULL); - g_assert (impl->search_entry == NULL); - g_assert (impl->search_model == NULL); - g_assert (impl->search_model_filter == NULL); -+ if (!g_slist_find (impl->filters, impl->current_filter)) -+ set_current_filter (impl, filter); - +- - search_setup_widgets (impl); - file_list_set_sort_column_ids (impl); -+ show_filters (impl, g_slist_length (impl->filters) > 1); - } - +-} +- -/* - * Recent files support - */ - -/* Frees the data in the recent_model */ - static void +-static void -recent_clear_model (GtkFileChooserDefault *impl, - gboolean remove_from_treeview) -+gtk_file_chooser_default_remove_filter (GtkFileChooser *chooser, -+ GtkFileFilter *filter) - { -+ GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (chooser); - GtkTreeModel *model; - GtkTreeIter iter; -+ gint filter_index; - +-{ +- GtkTreeModel *model; +- GtkTreeIter iter; +- - if (!impl->recent_model) - return; - @@ -11277,8 +7240,7 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - g_object_unref (impl->recent_model_sort); - impl->recent_model_sort = NULL; -} -+ filter_index = g_slist_index (impl->filters, filter); - +- -/* Stops any ongoing loading of the recent files list; does - * not touch the recent_model - */ @@ -11286,13 +7248,10 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c -recent_stop_loading (GtkFileChooserDefault *impl) -{ - if (impl->load_recent_id) -+ if (filter_index < 0) - { +- { - g_source_remove (impl->load_recent_id); - impl->load_recent_id = 0; -+ g_warning ("gtk_file_chooser_remove_filter() called on filter not in list\n"); -+ return; - } +- } -} - -/* Stops any pending load, clears the file list, and switches @@ -11305,34 +7264,24 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - - recent_stop_loading (impl); - recent_clear_model (impl, TRUE); - +- - gtk_widget_show (impl->browse_path_bar); - gtk_widget_show (impl->browse_new_folder_button); -+ impl->filters = g_slist_remove (impl->filters, filter); - +- - if (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN || - impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER) -+ if (filter == impl->current_filter) - { +- { - gtk_widget_show (impl->location_button); - - if (impl->location_mode == LOCATION_MODE_FILENAME_ENTRY) - gtk_widget_show (impl->location_entry_box); -+ if (impl->filters) -+ set_current_filter (impl, impl->filters->data); -+ else -+ set_current_filter (impl, NULL); - } - +- } +- - impl->operation_mode = OPERATION_MODE_BROWSE; - - file_list_set_sort_column_ids (impl); -} -+ /* Remove row from the combo box */ -+ model = gtk_combo_box_get_model (GTK_COMBO_BOX (impl->filter_combo)); -+ if (!gtk_tree_model_iter_nth_child (model, &iter, NULL, filter_index)) -+ g_assert_not_reached (); - +- -/* Sort callback from the modification time column */ -static gint -recent_column_mtime_sort_func (GtkTreeModel *model, @@ -11359,12 +7308,10 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - - if (!info_a) - return 1; -+ gtk_list_store_remove (GTK_LIST_STORE (model), &iter); - +- - if (!info_b) - return -1; -+ g_object_unref (filter); - +- - /* folders always go first */ - if (is_folder_a != is_folder_b) - return is_folder_a ? 1 : -1; @@ -11375,17 +7322,14 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - return 1; - else - return 0; -+ show_filters (impl, g_slist_length (impl->filters) > 1); - } - +-} +- -static gint -recent_column_path_sort_func (GtkTreeModel *model, - GtkTreeIter *a, - GtkTreeIter *b, - gpointer user_data) -+static GSList * -+gtk_file_chooser_default_list_filters (GtkFileChooser *chooser) - { +-{ - GtkFileChooserDefault *impl = user_data; - GtkTreeIter child_a, child_b; - gboolean is_folder_a, is_folder_b; @@ -11411,22 +7355,15 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - - if (is_folder_a != is_folder_b) - return is_folder_a ? 1 : -1; -+ GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (chooser); - +- - return strcmp (name_a, name_b); -+ return g_slist_copy (impl->filters); - } - +-} +- -static gboolean -recent_get_is_filtered (GtkFileChooserDefault *impl, - const GtkFilePath *path, - GtkRecentInfo *recent_info) -+/* Guesses a size based upon font sizes */ -+static void -+find_good_size_from_style (GtkWidget *widget, -+ gint *width, -+ gint *height) - { +-{ - GtkFileFilterInfo filter_info; - GtkFileFilterFlags needed; - gboolean result; @@ -11436,78 +7373,44 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - - filter_info.contains = GTK_FILE_FILTER_DISPLAY_NAME | GTK_FILE_FILTER_MIME_TYPE; - needed = gtk_file_filter_get_needed (impl->current_filter); -+ GtkFileChooserDefault *impl; -+ int font_size; -+ GdkScreen *screen; -+ double resolution; - +- - filter_info.display_name = gtk_recent_info_get_display_name (recent_info); - filter_info.mime_type = gtk_recent_info_get_mime_type (recent_info); -+ g_assert (widget->style != NULL); -+ impl = GTK_FILE_CHOOSER_DEFAULT (widget); - +- - if (needed & GTK_FILE_FILTER_FILENAME) -+ if (impl->default_width == 0 && -+ impl->default_height == 0) - { +- { - filter_info.filename = gtk_file_system_path_to_filename (impl->file_system, path); - if (filter_info.filename) - filter_info.contains |= GTK_FILE_FILTER_FILENAME; - } - else - filter_info.filename = NULL; -+ screen = gtk_widget_get_screen (widget); -+ if (screen) -+ { -+ resolution = gdk_screen_get_resolution (screen); -+ if (resolution < 0.0) /* will be -1 if the resolution is not defined in the GdkScreen */ -+ resolution = 96.0; -+ } -+ else -+ resolution = 96.0; /* wheeee */ - +- - if (needed & GTK_FILE_FILTER_URI) - { - filter_info.uri = gtk_file_system_path_to_uri (impl->file_system, path); - if (filter_info.uri) - filter_info.contains |= GTK_FILE_FILTER_URI; -+ font_size = pango_font_description_get_size (widget->style->font_desc); -+ font_size = PANGO_PIXELS (font_size) * resolution / 72.0; -+ -+ impl->default_width = font_size * NUM_CHARS; -+ impl->default_height = font_size * NUM_LINES; - } +- } - else - filter_info.uri = NULL; - +- - result = gtk_file_filter_filter (impl->current_filter, &filter_info); -+ *width = impl->default_width; -+ *height = impl->default_height; -+} - +- - if (filter_info.filename) - g_free ((gchar *) filter_info.filename); - if (filter_info.uri) - g_free ((gchar *) filter_info.uri); -+static void -+gtk_file_chooser_default_get_default_size (GtkFileChooserEmbed *chooser_embed, -+ gint *default_width, -+ gint *default_height) -+{ -+ GtkFileChooserDefault *impl; - +- - return !result; -+ impl = GTK_FILE_CHOOSER_DEFAULT (chooser_embed); -+ find_good_size_from_style (GTK_WIDGET (chooser_embed), default_width, default_height); - } - +-} +- -/* Visibility function for the recent filter model */ - static gboolean +-static gboolean -recent_model_visible_func (GtkTreeModel *model, - GtkTreeIter *iter, - gpointer user_data) -+gtk_file_chooser_default_get_resizable (GtkFileChooserEmbed *chooser_embed) - { +-{ - GtkFileChooserDefault *impl = user_data; - GtkFilePath *file_path; - GtkRecentInfo *recent_info; @@ -11527,12 +7430,10 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - - if (is_folder) - return TRUE; -+ GtkFileChooserDefault *impl; - +- - return !recent_get_is_filtered (impl, file_path, recent_info); -} -+ impl = GTK_FILE_CHOOSER_DEFAULT (chooser_embed); - +- -static void -recent_setup_model (GtkFileChooserDefault *impl) -{ @@ -11590,40 +7491,26 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (impl->recent_model_sort), - RECENT_MODEL_COL_INFO, - GTK_SORT_DESCENDING); -+ return (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN || -+ impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER); - } - +-} +- -typedef struct -{ -+struct switch_folder_closure { - GtkFileChooserDefault *impl; +- GtkFileChooserDefault *impl; - GList *items; - gint n_items; - gint n_loaded_items; - guint needs_sorting : 1; -} RecentLoadData; -+ const GtkFilePath *path; -+ int num_selected; -+}; - -+/* Used from gtk_tree_selection_selected_foreach() in switch_to_selected_folder() */ - static void +- +-static void -recent_idle_cleanup (gpointer data) -+switch_folder_foreach_cb (GtkTreeModel *model, -+ GtkTreePath *path, -+ GtkTreeIter *iter, -+ gpointer data) - { +-{ - RecentLoadData *load_data = data; - GtkFileChooserDefault *impl = load_data->impl; -+ struct switch_folder_closure *closure; -+ GtkTreeIter child_iter; - +- - gtk_tree_view_set_model (GTK_TREE_VIEW (impl->browse_files_tree_view), - GTK_TREE_MODEL (impl->recent_model_sort)); -+ closure = data; - +- - set_busy_cursor (impl, FALSE); - - impl->load_recent_id = 0; @@ -11633,13 +7520,10 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - g_list_foreach (load_data->items, (GFunc) gtk_recent_info_unref, NULL); - g_list_free (load_data->items); - } -+ gtk_tree_model_sort_convert_iter_to_child_iter (closure->impl->sort_model, &child_iter, iter); - +- - g_free (load_data); -+ closure->path = _gtk_file_system_model_get_path (closure->impl->browse_files_model, &child_iter); -+ closure->num_selected++; - } - +-} +- -struct RecentItemInsertRequest -{ - GtkFileChooserDefault *impl; @@ -11647,130 +7531,77 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - GtkTreeRowReference *row_ref; -}; - -+/* Changes to the selected folder in the list view */ - static void +-static void -recent_item_get_info_cb (GtkFileSystemHandle *handle, - const GtkFileInfo *info, - const GError *error, - gpointer data) -+switch_to_selected_folder (GtkFileChooserDefault *impl) - { +-{ - gboolean cancelled = handle->cancelled; - GtkTreePath *path; - GtkTreeIter iter; - GtkFileSystemHandle *model_handle; - gboolean is_folder = FALSE; - struct RecentItemInsertRequest *request = data; -+ GtkTreeSelection *selection; -+ struct switch_folder_closure closure; - +- - if (!request->impl->recent_model) - goto out; -+ /* We do this with foreach() rather than get_selected() as we may be in -+ * multiple selection mode -+ */ - +- - path = gtk_tree_row_reference_get_path (request->row_ref); - if (!path) - goto out; -+ closure.impl = impl; -+ closure.path = NULL; -+ closure.num_selected = 0; - +- - gtk_tree_model_get_iter (GTK_TREE_MODEL (request->impl->recent_model), - &iter, path); - gtk_tree_path_free (path); -+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_files_tree_view)); -+ gtk_tree_selection_selected_foreach (selection, switch_folder_foreach_cb, &closure); - +- - gtk_tree_model_get (GTK_TREE_MODEL (request->impl->recent_model), &iter, - RECENT_MODEL_COL_HANDLE, &model_handle, - -1); - if (handle != model_handle) - goto out; -+ g_assert (closure.path && closure.num_selected == 1); - +- - gtk_list_store_set (request->impl->recent_model, &iter, - RECENT_MODEL_COL_HANDLE, NULL, - -1); -+ change_folder_and_display_error (impl, closure.path); -+} - +- - if (cancelled) - goto out; -+/* Gets the GtkFileInfo for the selected row in the file list; assumes single -+ * selection mode. -+ */ -+static const GtkFileInfo * -+get_selected_file_info_from_file_list (GtkFileChooserDefault *impl, -+ gboolean *had_selection) -+{ -+ GtkTreeSelection *selection; -+ GtkTreeIter iter, child_iter; -+ const GtkFileInfo *info; - +- - if (!info) -+ g_assert (!impl->select_multiple); -+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_files_tree_view)); -+ if (!gtk_tree_selection_get_selected (selection, NULL, &iter)) - { +- { - gtk_list_store_remove (request->impl->recent_model, &iter); - goto out; -+ *had_selection = FALSE; -+ return NULL; - } - +- } +- - is_folder = gtk_file_info_get_is_folder (info); - - gtk_list_store_set (request->impl->recent_model, &iter, - RECENT_MODEL_COL_IS_FOLDER, is_folder, - -1); -+ *had_selection = TRUE; - +- -out: - g_object_unref (request->impl); - gtk_file_path_free (request->path); - gtk_tree_row_reference_free (request->row_ref); - g_free (request); -+ gtk_tree_model_sort_convert_iter_to_child_iter (impl->sort_model, -+ &child_iter, -+ &iter); - +- - g_object_unref (handle); -+ info = _gtk_file_system_model_get_info (impl->browse_files_model, &child_iter); -+ return info; - } - +-} +- -static gint -recent_sort_mru (gconstpointer a, - gconstpointer b) -+/* Gets the display name of the selected file in the file list; assumes single -+ * selection mode and that something is selected. -+ */ -+static const gchar * -+get_display_name_from_file_list (GtkFileChooserDefault *impl) - { +-{ - GtkRecentInfo *info_a = (GtkRecentInfo *) a; - GtkRecentInfo *info_b = (GtkRecentInfo *) b; -+ const GtkFileInfo *info; -+ gboolean had_selection; -+ -+ info = get_selected_file_info_from_file_list (impl, &had_selection); -+ g_assert (had_selection); -+ g_assert (info != NULL); - -- return (gtk_recent_info_get_modified (info_a) < gtk_recent_info_get_modified (info_b)); -+ return gtk_file_info_get_display_name (info); - } - +- +- return (gtk_recent_info_get_modified (info_b) - gtk_recent_info_get_modified (info_a)); +-} +- -static gint -get_recent_files_limit (GtkWidget *widget) -+static void -+add_custom_button_to_dialog (GtkDialog *dialog, -+ const gchar *mnemonic_label, -+ const gchar *stock_id, -+ gint response_id) - { +-{ - GtkSettings *settings; - gint limit; - @@ -11778,28 +7609,15 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - settings = gtk_settings_get_for_screen (gtk_widget_get_screen (widget)); - else - settings = gtk_settings_get_default (); -+ GtkWidget *button; - +- - g_object_get (G_OBJECT (settings), "gtk-recent-files-limit", &limit, NULL); -+ button = gtk_button_new_with_mnemonic (mnemonic_label); -+ GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT); -+ gtk_button_set_image (GTK_BUTTON (button), -+ gtk_image_new_from_stock (stock_id, GTK_ICON_SIZE_BUTTON)); -+ gtk_widget_show (button); - +- - return limit; -+ gtk_dialog_add_action_widget (GTK_DIALOG (dialog), button, response_id); - } - -+/* Presents an overwrite confirmation dialog; returns whether we should accept -+ * the filename. -+ */ - static gboolean +-} +- +-static gboolean -recent_idle_load (gpointer data) -+confirm_dialog_should_accept_filename (GtkFileChooserDefault *impl, -+ const gchar *file_part, -+ const gchar *folder_display_name) - { +-{ - RecentLoadData *load_data = data; - GtkFileChooserDefault *impl = load_data->impl; - GtkTreeIter iter; @@ -11812,36 +7630,19 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - - if (!impl->recent_manager) - return FALSE; -+ GtkWindow *toplevel; -+ GtkWidget *dialog; -+ int response; - +- - /* first iteration: load all the items */ - if (!load_data->items) - { - load_data->items = gtk_recent_manager_get_items (impl->recent_manager); - if (!load_data->items) - return FALSE; -+ toplevel = get_toplevel (GTK_WIDGET (impl)); - +- - load_data->needs_sorting = TRUE; -+ dialog = gtk_message_dialog_new (toplevel, -+ GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, -+ GTK_MESSAGE_QUESTION, -+ GTK_BUTTONS_NONE, -+ _("A file named \"%s\" already exists. Do you want to replace it?"), -+ file_part); -+ gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), -+ _("The file already exists in \"%s\". Replacing it will " -+ "overwrite its contents."), -+ folder_display_name); - +- - return TRUE; - } -+ gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL); -+ add_custom_button_to_dialog (GTK_DIALOG (dialog), _("_Replace"), GTK_STOCK_SAVE_AS, GTK_RESPONSE_ACCEPT); -+ gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_ACCEPT); - +- - /* second iteration: preliminary MRU sorting and clamping */ - if (load_data->needs_sorting) - { @@ -11886,9 +7687,7 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - - gtk_list_store_append (impl->recent_model, &iter); - p = gtk_tree_model_get_path (GTK_TREE_MODEL (impl->recent_model), &iter); -+ if (toplevel->group) -+ gtk_window_group_add_window (toplevel->group, GTK_WINDOW (dialog)); - +- - request = g_new0 (struct RecentItemInsertRequest, 1); - request->impl = g_object_ref (impl); - request->path = gtk_file_path_copy (path); @@ -11917,20 +7716,16 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - g_list_foreach (load_data->items, (GFunc) gtk_recent_info_unref, NULL); - g_list_free (load_data->items); - load_data->items = NULL; -+ response = gtk_dialog_run (GTK_DIALOG (dialog)); - +- - return FALSE; - } -+ gtk_widget_destroy (dialog); - +- - return TRUE; -+ return (response == GTK_RESPONSE_ACCEPT); - } - +-} +- -static void -recent_start_loading (GtkFileChooserDefault *impl) -+struct GetDisplayNameData - { +-{ - RecentLoadData *load_data; - - recent_stop_loading (impl); @@ -11956,92 +7751,54 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - load_data, - recent_idle_cleanup); -} -+ GtkFileChooserDefault *impl; -+ gchar *file_part; -+}; - - static void +- +-static void -recent_selected_foreach_get_path_cb (GtkTreeModel *model, - GtkTreePath *path, - GtkTreeIter *iter, - gpointer data) -+confirmation_confirm_get_info_cb (GtkFileSystemHandle *handle, -+ const GtkFileInfo *info, -+ const GError *error, -+ gpointer user_data) - { +-{ - GSList **list; - const GtkFilePath *file_path; - GtkFilePath *file_path_copy; -+ gboolean cancelled = handle->cancelled; -+ gboolean should_respond = FALSE; -+ struct GetDisplayNameData *data = user_data; - +- - list = data; -+ if (handle != data->impl->should_respond_get_info_handle) -+ goto out; - +- - gtk_tree_model_get (model, iter, RECENT_MODEL_COL_PATH, &file_path, -1); - file_path_copy = gtk_file_path_copy (file_path); - *list = g_slist_prepend (*list, file_path_copy); -} -+ data->impl->should_respond_get_info_handle = NULL; - +- -/* Constructs a list of the selected paths in recent files mode */ -static GSList * -recent_get_selected_paths (GtkFileChooserDefault *impl) -{ - GSList *result; - GtkTreeSelection *selection; -+ if (cancelled) -+ goto out; -+ -+ if (error) -+ /* Huh? Did the folder disappear? Let the caller deal with it */ -+ should_respond = TRUE; -+ else -+ should_respond = confirm_dialog_should_accept_filename (data->impl, data->file_part, gtk_file_info_get_display_name (info)); - +- - result = NULL; -+ set_busy_cursor (data->impl, FALSE); -+ if (should_respond) -+ g_signal_emit_by_name (data->impl, "response-requested"); - +- - selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_files_tree_view)); - gtk_tree_selection_selected_foreach (selection, recent_selected_foreach_get_path_cb, &result); - result = g_slist_reverse (result); -+out: -+ g_object_unref (data->impl); -+ g_free (data->file_part); -+ g_free (data); - +- - return result; -+ g_object_unref (handle); - } - +-} +- -/* Called from ::should_respond(). We return whether there are selected - * files in the recent files list. -+/* Does overwrite confirmation if appropriate, and returns whether the dialog -+ * should respond. Can get the file part from the file list or the save entry. - */ - static gboolean +- */ +-static gboolean -recent_should_respond (GtkFileChooserDefault *impl) -+should_respond_after_confirm_overwrite (GtkFileChooserDefault *impl, -+ const gchar *file_part, -+ const GtkFilePath *parent_path) - { +-{ - GtkTreeSelection *selection; -+ GtkFileChooserConfirmation conf; - +- - g_assert (impl->operation_mode == OPERATION_MODE_RECENT); -+ if (!impl->do_overwrite_confirmation) -+ return TRUE; - +- - selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_files_tree_view)); - return (gtk_tree_selection_count_selected_rows (selection) != 0); -} -+ conf = GTK_FILE_CHOOSER_CONFIRMATION_CONFIRM; - +- -/* Hide the location widgets temporarily */ -static void -recent_hide_entry (GtkFileChooserDefault *impl) @@ -12051,18 +7808,12 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - - if (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN || - impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER) -+ g_signal_emit_by_name (impl, "confirm-overwrite", &conf); -+ -+ switch (conf) - { +- { - gtk_widget_hide (impl->location_button); - gtk_widget_hide (impl->location_entry_box); - } -} -+ case GTK_FILE_CHOOSER_CONFIRMATION_CONFIRM: -+ { -+ struct GetDisplayNameData *data; - +- -/* Main entry point to the recent files functions; this gets called when - * the user activates the Recently Used shortcut. - */ @@ -12070,28 +7821,13 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c -recent_activate (GtkFileChooserDefault *impl) -{ - OperationMode previous_mode; -+ g_assert (file_part != NULL); - +- - if (impl->operation_mode == OPERATION_MODE_RECENT) - return; -+ data = g_new0 (struct GetDisplayNameData, 1); -+ data->impl = g_object_ref (impl); -+ data->file_part = g_strdup (file_part); -+ -+ if (impl->should_respond_get_info_handle) -+ gtk_file_system_cancel_operation (impl->should_respond_get_info_handle); - +- - previous_mode = impl->operation_mode; - impl->operation_mode = OPERATION_MODE_RECENT; -+ impl->should_respond_get_info_handle = -+ gtk_file_system_get_info (impl->file_system, parent_path, -+ GTK_FILE_INFO_DISPLAY_NAME, -+ confirmation_confirm_get_info_cb, -+ data); -+ set_busy_cursor (data->impl, TRUE); -+ return FALSE; -+ } - +- - switch (previous_mode) - { - case OPERATION_MODE_SEARCH: @@ -12102,52 +7838,38 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - impl->search_hbox = NULL; - impl->search_entry = NULL; - break; -+ case GTK_FILE_CHOOSER_CONFIRMATION_ACCEPT_FILENAME: -+ return TRUE; - +- - case OPERATION_MODE_BROWSE: - stop_loading_and_clear_list_model (impl); - break; -+ case GTK_FILE_CHOOSER_CONFIRMATION_SELECT_AGAIN: -+ return FALSE; - +- - case OPERATION_MODE_RECENT: -+ default: - g_assert_not_reached (); +- g_assert_not_reached (); - break; -+ return FALSE; - } +- } - - recent_hide_entry (impl); - file_list_set_sort_column_ids (impl); - recent_start_loading (impl); - } - +-} +- -/* convert an iterator coming from the model bound to - * browse_files_tree_view to an interator inside the - * real recent_model - */ - static void +-static void -recent_get_valid_child_iter (GtkFileChooserDefault *impl, - GtkTreeIter *child_iter, - GtkTreeIter *iter) -+action_create_folder_cb (GtkFileSystemHandle *handle, -+ const GtkFilePath *path, -+ const GError *error, -+ gpointer user_data) - { +-{ - GtkTreeIter middle; - - if (!impl->recent_model) - return; -+ gboolean cancelled = handle->cancelled; -+ GtkFileChooserDefault *impl = user_data; - +- - if (!impl->recent_model_filter || !impl->recent_model_sort) - return; -+ if (!g_slist_find (impl->pending_handles, handle)) -+ goto out; - +- - /* pass 1: get the iterator in the filter model */ - gtk_tree_model_sort_convert_iter_to_child_iter (impl->recent_model_sort, - &middle, iter); @@ -12157,94 +7879,28 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - child_iter, - &middle); -} -+ impl->pending_handles = g_slist_remove (impl->pending_handles, handle); - -+ set_busy_cursor (impl, FALSE); - +- +- -static void --set_current_filter (GtkFileChooserDefault *impl, -- GtkFileFilter *filter) --{ -- if (impl->current_filter != filter) -- { -- int filter_index; -+ if (cancelled) -+ goto out; - -- /* NULL filters are allowed to reset to non-filtered status -- */ -- filter_index = g_slist_index (impl->filters, filter); -- if (impl->filters && filter && filter_index < 0) -- return; -+ if (error) -+ error_creating_folder_dialog (impl, path, g_error_copy (error)); -+ else -+ g_signal_emit_by_name (impl, "response-requested"); - -- if (impl->current_filter) -- g_object_unref (impl->current_filter); -- impl->current_filter = filter; -- if (impl->current_filter) -- { -- g_object_ref_sink (impl->current_filter); -- } -+out: -+ g_object_unref (impl); -+ g_object_unref (handle); -+} - -- if (impl->filters) -- gtk_combo_box_set_active (GTK_COMBO_BOX (impl->filter_combo), -- filter_index); -+struct FileExistsData -+{ -+ GtkFileChooserDefault *impl; -+ gboolean file_exists_and_is_not_folder; -+ GtkFilePath *parent_path; -+ GtkFilePath *path; -+}; - -- if (impl->browse_files_model) -- install_list_model_filter (impl); -+static void -+save_entry_get_info_cb (GtkFileSystemHandle *handle, -+ const GtkFileInfo *info, -+ const GError *error, -+ gpointer user_data) -+{ -+ gboolean parent_is_folder; -+ gboolean cancelled = handle->cancelled; -+ struct FileExistsData *data = user_data; + set_current_filter (GtkFileChooserDefault *impl, + GtkFileFilter *filter) + { +@@ -10175,12 +4463,6 @@ + if (impl->browse_files_model) + install_list_model_filter (impl); - if (impl->search_model_filter) - gtk_tree_model_filter_refilter (impl->search_model_filter); -+ if (handle != data->impl->should_respond_get_info_handle) -+ goto out; - +- - if (impl->recent_model_filter) - gtk_tree_model_filter_refilter (impl->recent_model_filter); -+ data->impl->should_respond_get_info_handle = NULL; - -- g_object_notify (G_OBJECT (impl), "filter"); -- } --} -+ set_busy_cursor (data->impl, FALSE); - --static void --filter_combo_changed (GtkComboBox *combo_box, -- GtkFileChooserDefault *impl) --{ -- gint new_index = gtk_combo_box_get_active (combo_box); -- GtkFileFilter *new_filter = g_slist_nth_data (impl->filters, new_index); -+ if (cancelled) -+ goto out; - -- set_current_filter (impl, new_filter); --} -+ if (!info) -+ parent_is_folder = FALSE; -+ else -+ parent_is_folder = gtk_file_info_get_is_folder (info); +- + g_object_notify (G_OBJECT (impl), "filter"); + } + } +@@ -10195,355 +4477,7 @@ + set_current_filter (impl, new_filter); + } -static void -check_preview_change (GtkFileChooserDefault *impl) @@ -12257,39 +7913,27 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - new_path = NULL; - new_display_name = NULL; - if (cursor_path) -+ if (parent_is_folder) - { +- { - GtkTreeIter child_iter; - - if (impl->operation_mode == OPERATION_MODE_BROWSE) - { - if (impl->sort_model) -+ if (data->impl->action == GTK_FILE_CHOOSER_ACTION_SAVE) -+ { -+ if (data->file_exists_and_is_not_folder) - { +- { - GtkTreeIter iter; - const GtkFileInfo *new_info; - - gtk_tree_model_get_iter (GTK_TREE_MODEL (impl->sort_model), &iter, cursor_path); - gtk_tree_path_free (cursor_path); -+ gboolean retval; -+ const char *file_part; - +- - gtk_tree_model_sort_convert_iter_to_child_iter (impl->sort_model, &child_iter, &iter); -+ file_part = _gtk_file_chooser_entry_get_file_part (GTK_FILE_CHOOSER_ENTRY (data->impl->location_entry)); -+ retval = should_respond_after_confirm_overwrite (data->impl, file_part, data->parent_path); - +- - new_path = _gtk_file_system_model_get_path (impl->browse_files_model, &child_iter); - new_info = _gtk_file_system_model_get_info (impl->browse_files_model, &child_iter); - if (new_info) - new_display_name = gtk_file_info_get_display_name (new_info); -+ if (retval) -+ g_signal_emit_by_name (data->impl, "response-requested"); - } -+ else -+ g_signal_emit_by_name (data->impl, "response-requested"); - } +- } +- } - else if (impl->operation_mode == OPERATION_MODE_SEARCH) - { - GtkTreeIter iter; @@ -12305,11 +7949,9 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - -1); - } - else if (impl->operation_mode == OPERATION_MODE_RECENT) -+ else /* GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER */ - { +- { - GtkTreeIter iter; -+ GtkFileSystemHandle *handle; - +- - gtk_tree_model_get_iter (GTK_TREE_MODEL (impl->recent_model_sort), - &iter, cursor_path); - gtk_tree_path_free (cursor_path); @@ -12319,21 +7961,13 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - RECENT_MODEL_COL_PATH, &new_path, - RECENT_MODEL_COL_DISPLAY_NAME, &new_display_name, - -1); -+ g_object_ref (data->impl); -+ handle = gtk_file_system_create_folder (data->impl->file_system, -+ data->path, -+ action_create_folder_cb, -+ data->impl); -+ data->impl->pending_handles = g_slist_append (data->impl->pending_handles, handle); -+ set_busy_cursor (data->impl, TRUE); - } - } +- } +- } - - if (new_path != impl->preview_path && - !(new_path && impl->preview_path && - gtk_file_path_compare (new_path, impl->preview_path) == 0)) -+ else - { +- { - if (impl->preview_path) - { - gtk_file_path_free (impl->preview_path); @@ -12350,129 +7984,70 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - impl->preview_path = NULL; - impl->preview_display_name = NULL; - } -+ /* This will display an error, which is what we want */ -+ change_folder_and_display_error (data->impl, data->parent_path); -+ } - +- - if (impl->use_preview_label && impl->preview_label) - gtk_label_set_text (GTK_LABEL (impl->preview_label), impl->preview_display_name); -+out: -+ g_object_unref (data->impl); -+ gtk_file_path_free (data->path); -+ gtk_file_path_free (data->parent_path); -+ g_free (data); - +- - g_signal_emit_by_name (impl, "update-preview"); - } -+ g_object_unref (handle); - } - - static void +-} +- +-static void -shortcuts_activate_volume_mount_cb (GtkFileSystemHandle *handle, - GtkFileSystemVolume *volume, - const GError *error, - gpointer data) -+file_exists_get_info_cb (GtkFileSystemHandle *handle, -+ const GtkFileInfo *info, -+ const GError *error, -+ gpointer user_data) - { +-{ - GtkFilePath *path; -+ gboolean data_ownership_taken = FALSE; - gboolean cancelled = handle->cancelled; +- gboolean cancelled = handle->cancelled; - GtkFileChooserDefault *impl = data; -+ gboolean file_exists_and_is_not_folder; -+ struct FileExistsData *data = user_data; - +- - if (handle != impl->shortcuts_activate_iter_handle) -+ if (handle != data->impl->file_exists_get_info_handle) - goto out; - +- goto out; +- - impl->shortcuts_activate_iter_handle = NULL; -+ data->impl->file_exists_get_info_handle = NULL; - +- - set_busy_cursor (impl, FALSE); -+ set_busy_cursor (data->impl, FALSE); - - if (cancelled) - goto out; - +- +- if (cancelled) +- goto out; +- - if (error) -+ file_exists_and_is_not_folder = info && !gtk_file_info_get_is_folder (info); -+ -+ if (data->impl->action == GTK_FILE_CHOOSER_ACTION_OPEN) -+ /* user typed a filename; we are done */ -+ g_signal_emit_by_name (data->impl, "response-requested"); -+ else if (data->impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER -+ && file_exists_and_is_not_folder) -+ { -+ /* Oops, the user typed the name of an existing path which is not -+ * a folder -+ */ -+ error_creating_folder_over_existing_file_dialog (data->impl, data->path, -+ g_error_copy (error)); -+ } -+ else - { +- { - char *msg; -+ /* check that everything up to the last component exists */ -+ -+ data->file_exists_and_is_not_folder = file_exists_and_is_not_folder; -+ data_ownership_taken = TRUE; - +- - msg = g_strdup_printf (_("Could not mount %s"), - gtk_file_system_volume_get_display_name (impl->file_system, volume)); - error_message (impl, msg, error->message); - g_free (msg); -+ if (data->impl->should_respond_get_info_handle) -+ gtk_file_system_cancel_operation (data->impl->should_respond_get_info_handle); - +- - goto out; -+ data->impl->should_respond_get_info_handle = -+ gtk_file_system_get_info (data->impl->file_system, -+ data->parent_path, -+ GTK_FILE_INFO_IS_FOLDER, -+ save_entry_get_info_cb, -+ data); -+ set_busy_cursor (data->impl, TRUE); - } - +- } +- - path = gtk_file_system_volume_get_base_path (impl->file_system, volume); - if (path != NULL) -+out: -+ if (!data_ownership_taken) - { +- { - change_folder_and_display_error (impl, path, FALSE); - focus_browse_tree_view_if_possible (impl); - - gtk_file_path_free (path); -+ g_object_unref (data->impl); -+ gtk_file_path_free (data->path); -+ gtk_file_path_free (data->parent_path); -+ g_free (data); - } - +- } +- -out: - g_object_unref (impl); - g_object_unref (handle); - } - - +- g_object_unref (handle); +-} +- +- -/* Activates a volume by mounting it if necessary and then switching to its - * base path. - */ -static void -shortcuts_activate_volume (GtkFileChooserDefault *impl, - GtkFileSystemVolume *volume) -+/* Implementation for GtkFileChooserEmbed::should_respond() */ -+static gboolean -+gtk_file_chooser_default_should_respond (GtkFileChooserEmbed *chooser_embed) - { +-{ - GtkFilePath *path; -+ GtkFileChooserDefault *impl; -+ GtkWidget *toplevel; -+ GtkWidget *current_focus; - +- - switch (impl->operation_mode) - { - case OPERATION_MODE_BROWSE: @@ -12484,102 +8059,23 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - recent_switch_to_browse_mode (impl); - break; - } -+ impl = GTK_FILE_CHOOSER_DEFAULT (chooser_embed); - +- - /* We ref the file chooser since volume_mount() may run a main loop, and the - * user could close the file chooser window in the meantime. - */ - g_object_ref (impl); -+ toplevel = gtk_widget_get_toplevel (GTK_WIDGET (impl)); -+ g_assert (GTK_IS_WINDOW (toplevel)); -+ -+ current_focus = gtk_window_get_focus (GTK_WINDOW (toplevel)); - +- - if (!gtk_file_system_volume_get_is_mounted (impl->file_system, volume)) -+ if (current_focus == impl->browse_files_tree_view) - { +- { - set_busy_cursor (impl, TRUE); -+ /* The following array encodes what we do based on the impl->action and the -+ * number of files selected. -+ */ -+ typedef enum { -+ NOOP, /* Do nothing (don't respond) */ -+ RESPOND, /* Respond immediately */ -+ RESPOND_OR_SWITCH, /* Respond immediately if the selected item is a file; switch to it if it is a folder */ -+ ALL_FILES, /* Respond only if everything selected is a file */ -+ ALL_FOLDERS, /* Respond only if everything selected is a folder */ -+ SAVE_ENTRY, /* Go to the code for handling the save entry */ -+ NOT_REACHED /* Sanity check */ -+ } ActionToTake; -+ static const ActionToTake what_to_do[4][3] = { -+ /* 0 selected 1 selected many selected */ -+ /* ACTION_OPEN */ { NOOP, RESPOND_OR_SWITCH, ALL_FILES }, -+ /* ACTION_SAVE */ { SAVE_ENTRY, RESPOND_OR_SWITCH, NOT_REACHED }, -+ /* ACTION_SELECT_FOLDER */ { RESPOND, ALL_FOLDERS, ALL_FOLDERS }, -+ /* ACTION_CREATE_FOLDER */ { SAVE_ENTRY, ALL_FOLDERS, NOT_REACHED } -+ }; -+ -+ int num_selected; -+ gboolean all_files, all_folders; -+ int k; -+ ActionToTake action; -+ -+ file_list: -+ -+ g_assert (impl->action >= GTK_FILE_CHOOSER_ACTION_OPEN && impl->action <= GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER); -+ -+ selection_check (impl, &num_selected, &all_files, &all_folders); -+ -+ if (num_selected > 2) -+ k = 2; -+ else -+ k = num_selected; -+ -+ action = what_to_do [impl->action] [k]; -+ -+ switch (action) -+ { -+ case NOOP: -+ return FALSE; -+ -+ case RESPOND: -+ return TRUE; -+ -+ case RESPOND_OR_SWITCH: -+ g_assert (num_selected == 1); -+ -+ if (all_folders) -+ { -+ switch_to_selected_folder (impl); -+ return FALSE; -+ } -+ else if (impl->action == GTK_FILE_CHOOSER_ACTION_SAVE) -+ return should_respond_after_confirm_overwrite (impl, -+ get_display_name_from_file_list (impl), -+ impl->current_folder); -+ else -+ return TRUE; -+ -+ case ALL_FILES: -+ return all_files; -+ -+ case ALL_FOLDERS: -+ return all_folders; -+ -+ case SAVE_ENTRY: -+ goto save_entry; - +- - impl->shortcuts_activate_iter_handle = - gtk_file_system_volume_mount (impl->file_system, volume, - shortcuts_activate_volume_mount_cb, - g_object_ref (impl)); -+ default: -+ g_assert_not_reached (); -+ } - } +- } - else -+ else if ((impl->location_entry != NULL) && (current_focus == impl->location_entry)) - { +- { - path = gtk_file_system_volume_get_base_path (impl->file_system, volume); - if (path != NULL) - { @@ -12587,70 +8083,17 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - gtk_file_path_free (path); - } - } -+ GtkFilePath *path; -+ gboolean is_well_formed, is_empty, is_file_part_empty; -+ gboolean is_folder; -+ gboolean retval; -+ GtkFileChooserEntry *entry; -+ GError *error; -+ -+ save_entry: -+ -+ g_assert (impl->action == GTK_FILE_CHOOSER_ACTION_SAVE -+ || impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER -+ || impl->action == GTK_FILE_CHOOSER_ACTION_OPEN -+ || impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER); -+ -+ entry = GTK_FILE_CHOOSER_ENTRY (impl->location_entry); -+ check_save_entry (impl, &path, &is_well_formed, &is_empty, &is_file_part_empty, &is_folder); -+ -+ if (is_empty || !is_well_formed) -+ return FALSE; -+ -+ g_assert (path != NULL); -+ -+ error = NULL; -+ if (is_folder) -+ { -+ if (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN -+ || impl->action == GTK_FILE_CHOOSER_ACTION_SAVE) -+ { -+ change_folder_and_display_error (impl, path); -+ retval = FALSE; -+ } -+ else if (impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER -+ || GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER) -+ { -+ /* The folder already exists, so we do not need to create it. -+ * Just respond to terminate the dialog. -+ */ -+ retval = TRUE; -+ } -+ else -+ { -+ g_assert_not_reached (); -+ retval = FALSE; -+ } -+ } -+ else -+ { -+ struct FileExistsData *data; - +- - g_object_unref (impl); -} -+ /* We need to check whether path exists and is not a folder */ - +- -/* Opens the folder or volume at the specified iter in the shortcuts model */ -struct ShortcutsActivateData -{ - GtkFileChooserDefault *impl; - GtkFilePath *path; -}; -+ data = g_new0 (struct FileExistsData, 1); -+ data->impl = g_object_ref (impl); -+ data->path = gtk_file_path_copy (path); -+ data->parent_path = gtk_file_path_copy (_gtk_file_chooser_entry_get_current_folder (entry)); - +- -static void -shortcuts_activate_get_info_cb (GtkFileSystemHandle *handle, - const GtkFileInfo *info, @@ -12659,48 +8102,21 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c -{ - gboolean cancelled = handle->cancelled; - struct ShortcutsActivateData *data = user_data; -+ if (impl->file_exists_get_info_handle) -+ gtk_file_system_cancel_operation (impl->file_exists_get_info_handle); - +- - if (handle != data->impl->shortcuts_activate_iter_handle) - goto out; -+ impl->file_exists_get_info_handle = -+ gtk_file_system_get_info (impl->file_system, path, -+ GTK_FILE_INFO_IS_FOLDER, -+ file_exists_get_info_cb, -+ data); - +- - data->impl->shortcuts_activate_iter_handle = NULL; -+ set_busy_cursor (impl, TRUE); -+ retval = FALSE; - +- - if (cancelled) - goto out; -+ if (error != NULL) -+ g_error_free (error); -+ } - +- - if (!error && gtk_file_info_get_is_folder (info)) -+ gtk_file_path_free (path); -+ return retval; -+ } -+ else if (impl->toplevel_last_focus_widget == impl->browse_files_tree_view) -+ { -+ /* The focus is on a dialog's action area button, *and* the widget that -+ * was focused immediately before it is the file list. -+ */ -+ goto file_list; -+ } -+ else if (impl->location_entry && impl->toplevel_last_focus_widget == impl->location_entry) - { +- { - change_folder_and_display_error (data->impl, data->path, FALSE); - focus_browse_tree_view_if_possible (data->impl); -+ /* The focus is on a dialog's action area button, *and* the widget that -+ * was focused immediately before it is the location entry. -+ */ -+ goto save_entry; - } - else +- } +- else - gtk_file_chooser_default_select_path (GTK_FILE_CHOOSER (data->impl), - data->path, - NULL); @@ -12709,24 +8125,14 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - g_object_unref (data->impl); - gtk_file_path_free (data->path); - g_free (data); -+ /* The focus is on a dialog's action area button or something else */ -+ if (impl->action == GTK_FILE_CHOOSER_ACTION_SAVE -+ || impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER) -+ goto save_entry; -+ else -+ goto file_list; - +- - g_object_unref (handle); -+ g_assert_not_reached (); -+ return FALSE; - } - -+/* Implementation for GtkFileChooserEmbed::initial_focus() */ - static void +-} +- +-static void -shortcuts_activate_iter (GtkFileChooserDefault *impl, - GtkTreeIter *iter) -+gtk_file_chooser_default_initial_focus (GtkFileChooserEmbed *chooser_embed) - { +-{ - gpointer col_data; - ShortcutType shortcut_type; - @@ -12749,18 +8155,13 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - else if (shortcut_type == SHORTCUT_TYPE_VOLUME) - { - GtkFileSystemVolume *volume; -+ GtkFileChooserDefault *impl; -+ GtkWidget *widget; - +- - volume = col_data; -+ impl = GTK_FILE_CHOOSER_DEFAULT (chooser_embed); - +- - shortcuts_activate_volume (impl, volume); - } - else if (shortcut_type == SHORTCUT_TYPE_PATH) -+ if (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN -+ || impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER) - { +- { - struct ShortcutsActivateData *data; - - data = g_new0 (struct ShortcutsActivateData, 1); @@ -12771,76 +8172,46 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - gtk_file_system_get_info (impl->file_system, data->path, - GTK_FILE_INFO_IS_FOLDER, - shortcuts_activate_get_info_cb, data); -+ widget = impl->browse_files_tree_view; - } +- } - else if (shortcut_type == SHORTCUT_TYPE_SEARCH) -+ else if (impl->action == GTK_FILE_CHOOSER_ACTION_SAVE -+ || impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER) - { +- { - search_activate (impl); -+ widget = impl->location_entry; - } +- } - else if (shortcut_type == SHORTCUT_TYPE_RECENT) -+ else - { +- { - recent_activate (impl); -+ g_assert_not_reached (); -+ widget = NULL; - } -+ -+ g_assert (widget != NULL); -+ gtk_widget_grab_focus (widget); - } - +- } +-} +- -/* Callback used when a row in the shortcuts list is activated */ - static void +-static void -shortcuts_row_activated_cb (GtkTreeView *tree_view, - GtkTreePath *path, - GtkTreeViewColumn *column, - GtkFileChooserDefault *impl) -+set_current_filter (GtkFileChooserDefault *impl, -+ GtkFileFilter *filter) - { +-{ - GtkTreeIter iter; - GtkTreeIter child_iter; - - if (!gtk_tree_model_get_iter (impl->shortcuts_pane_filter_model, &iter, path)) - return; -+ if (impl->current_filter != filter) -+ { -+ int filter_index; - +- - gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER (impl->shortcuts_pane_filter_model), - &child_iter, - &iter); - shortcuts_activate_iter (impl, &child_iter); -} -+ /* NULL filters are allowed to reset to non-filtered status -+ */ -+ filter_index = g_slist_index (impl->filters, filter); -+ if (impl->filters && filter && filter_index < 0) -+ return; - +- -/* Handler for GtkWidget::key-press-event on the shortcuts list */ --static gboolean + static gboolean -shortcuts_key_press_event_cb (GtkWidget *widget, - GdkEventKey *event, - GtkFileChooserDefault *impl) -{ - guint modifiers; -+ if (impl->current_filter) -+ g_object_unref (impl->current_filter); -+ impl->current_filter = filter; -+ if (impl->current_filter) -+ { -+ g_object_ref_sink (impl->current_filter); -+ } - +- - modifiers = gtk_accelerator_get_default_mod_mask (); -+ if (impl->filters) -+ gtk_combo_box_set_active (GTK_COMBO_BOX (impl->filter_combo), -+ filter_index); - +- - if ((event->keyval == GDK_BackSpace - || event->keyval == GDK_Delete - || event->keyval == GDK_KP_Delete) @@ -12849,30 +8220,24 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - remove_selected_bookmarks (impl); - return TRUE; - } -+ if (impl->browse_files_model) -+ install_list_model_filter (impl); - +- - if ((event->keyval == GDK_F2) - && (event->state & modifiers) == 0) - { - rename_selected_bookmark (impl); - return TRUE; -+ g_object_notify (G_OBJECT (impl), "filter"); - } +- } - - return FALSE; - } - +-} +- -static gboolean -shortcuts_select_func (GtkTreeSelection *selection, - GtkTreeModel *model, - GtkTreePath *path, - gboolean path_currently_selected, - gpointer data) -+static void -+filter_combo_changed (GtkComboBox *combo_box, -+ GtkFileChooserDefault *impl) - { +-{ - GtkFileChooserDefault *impl = data; - GtkTreeIter filter_iter; - ShortcutType shortcut_type; @@ -12881,15 +8246,15 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - g_assert_not_reached (); - - gtk_tree_model_get (impl->shortcuts_pane_filter_model, &filter_iter, SHORTCUTS_COL_TYPE, &shortcut_type, -1); -+ gint new_index = gtk_combo_box_get_active (combo_box); -+ GtkFileFilter *new_filter = g_slist_nth_data (impl->filters, new_index); - +- - return shortcut_type != SHORTCUT_TYPE_SEPARATOR; -+ set_current_filter (impl, new_filter); - } - - static gboolean -@@ -10562,55 +4490,17 @@ +-} +- +-static gboolean + list_select_func (GtkTreeSelection *selection, + GtkTreeModel *model, + GtkTreePath *path, +@@ -10556,55 +4490,17 @@ impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER) { GtkTreeIter iter, child_iter; @@ -12900,10 +8265,15 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - case OPERATION_MODE_SEARCH: - { - gboolean is_folder; -- ++ if (!gtk_tree_model_get_iter (GTK_TREE_MODEL (impl->sort_model), &iter, path)) ++ return FALSE; ++ ++ gtk_tree_model_sort_convert_iter_to_child_iter (impl->sort_model, &child_iter, &iter); + - if (!gtk_tree_model_get_iter (GTK_TREE_MODEL (impl->search_model_sort), &iter, path)) - return FALSE; -- ++ info = _gtk_file_system_model_get_info (impl->browse_files_model, &child_iter); + - search_get_valid_child_iter (impl, &child_iter, &iter); - gtk_tree_model_get (GTK_TREE_MODEL (impl->search_model), &child_iter, - SEARCH_MODEL_COL_IS_FOLDER, &is_folder, @@ -12943,19 +8313,12 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - } - break; - } -+ if (!gtk_tree_model_get_iter (GTK_TREE_MODEL (impl->sort_model), &iter, path)) -+ return FALSE; -+ -+ gtk_tree_model_sort_convert_iter_to_child_iter (impl->sort_model, &child_iter, &iter); -+ -+ info = _gtk_file_system_model_get_info (impl->browse_files_model, &child_iter); -+ + if (info && !gtk_file_info_get_is_folder (info)) + return FALSE; } return TRUE; -@@ -10621,8 +4511,7 @@ +@@ -10615,8 +4511,7 @@ GtkFileChooserDefault *impl) { /* See if we are in the new folder editable row for Save mode */ @@ -12965,7 +8328,7 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c { const GtkFileInfo *info; gboolean had_selection; -@@ -10640,9 +4529,6 @@ +@@ -10634,9 +4529,6 @@ if (impl->location_entry) update_chooser_entry (impl); @@ -12975,7 +8338,7 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c g_signal_emit_by_name (impl, "selection-changed", 0); } -@@ -10653,107 +4539,30 @@ +@@ -10647,107 +4539,30 @@ GtkTreeViewColumn *column, GtkFileChooserDefault *impl) { @@ -13031,7 +8394,8 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - RECENT_MODEL_COL_PATH, &file_path, - RECENT_MODEL_COL_IS_FOLDER, &is_folder, - -1); -- ++ change_folder_and_display_error (impl, file_path); + - if (is_folder) - { - change_folder_and_display_error (impl, file_path, FALSE); @@ -13045,8 +8409,7 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - case OPERATION_MODE_BROWSE: - { - const GtkFileInfo *info; -+ change_folder_and_display_error (impl, file_path); - +- - if (!gtk_tree_model_get_iter (GTK_TREE_MODEL (impl->sort_model), &iter, path)) - return; - @@ -13072,7 +8435,7 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c + return; } -} -- + -static void -path_bar_clicked (GtkPathBar *path_bar, - GtkFilePath *file_path, @@ -13082,7 +8445,7 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c -{ - if (child_path) - pending_select_paths_add (impl, child_path); - +- - if (!change_folder_and_display_error (impl, file_path, FALSE)) - return; - @@ -13098,7 +8461,7 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c } static const GtkFileInfo * -@@ -10778,83 +4587,40 @@ +@@ -10772,83 +4587,40 @@ { GtkFileChooserDefault *impl = data; GtkTreeIter child_iter; @@ -13116,7 +8479,8 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - { - GtkTreeIter child_iter; - gboolean is_folder; -- ++ info = get_list_file_info (impl, iter); + - search_get_valid_child_iter (impl, &child_iter, iter); - gtk_tree_model_get (GTK_TREE_MODEL (impl->search_model), &child_iter, - SEARCH_MODEL_COL_PIXBUF, &pixbuf, @@ -13128,14 +8492,20 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - sensitive = is_folder; - } - break; -+ info = get_list_file_info (impl, iter); ++ gtk_tree_model_sort_convert_iter_to_child_iter (impl->sort_model, ++ &child_iter, ++ iter); ++ path = _gtk_file_system_model_get_path (impl->browse_files_model, &child_iter); - case OPERATION_MODE_RECENT: - { - GtkTreeIter child_iter; - GtkRecentInfo *info; - gboolean is_folder; -- ++ if (path) ++ { ++ pixbuf = NULL; + - recent_get_valid_child_iter (impl, &child_iter, iter); - gtk_tree_model_get (GTK_TREE_MODEL (impl->recent_model), &child_iter, - RECENT_MODEL_COL_INFO, &info, @@ -13154,16 +8524,9 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - { - const GtkFileInfo *info; - const GtkFilePath *path; -+ gtk_tree_model_sort_convert_iter_to_child_iter (impl->sort_model, -+ &child_iter, -+ iter); -+ path = _gtk_file_system_model_get_path (impl->browse_files_model, &child_iter); - +- - info = get_list_file_info (impl, iter); -+ if (path) -+ { -+ pixbuf = NULL; - +- - gtk_tree_model_sort_convert_iter_to_child_iter (impl->sort_model, - &child_iter, - iter); @@ -13195,12 +8558,12 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c + pixbuf = gtk_file_info_render_icon (info, GTK_WIDGET (impl), + impl->icon_size, NULL); + } -+ } + } + else + { + /* We are on the editable row */ + pixbuf = NULL; - } ++ } + + if (info && (impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER || + impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)) @@ -13208,24 +8571,14 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c g_object_set (cell, "pixbuf", pixbuf, -@@ -10864,96 +4630,32 @@ - if (pixbuf) - g_object_unref (pixbuf); - -- profile_end ("end", NULL); --} -- --static void --list_name_data_func (GtkTreeViewColumn *tree_column, -- GtkCellRenderer *cell, -- GtkTreeModel *tree_model, -- GtkTreeIter *iter, -- gpointer data) --{ -- GtkFileChooserDefault *impl = data; +@@ -10869,85 +4641,21 @@ + gpointer data) + { + GtkFileChooserDefault *impl = data; - const GtkFileInfo *info; -- gboolean sensitive = TRUE; -- ++ const GtkFileInfo *info = get_list_file_info (impl, iter); + gboolean sensitive = TRUE; + - if (impl->operation_mode == OPERATION_MODE_SEARCH) - { - GtkTreeIter child_iter; @@ -13287,20 +8640,7 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - - info = get_list_file_info (impl, iter); - sensitive = TRUE; -+ profile_end ("end", NULL); -+} -+ -+static void -+list_name_data_func (GtkTreeViewColumn *tree_column, -+ GtkCellRenderer *cell, -+ GtkTreeModel *tree_model, -+ GtkTreeIter *iter, -+ gpointer data) -+{ -+ GtkFileChooserDefault *impl = data; -+ const GtkFileInfo *info = get_list_file_info (impl, iter); -+ gboolean sensitive = TRUE; - +- if (!info) { g_object_set (cell, @@ -13320,7 +8660,7 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c { sensitive = gtk_file_info_get_is_folder (info); } -@@ -10961,7 +4663,6 @@ +@@ -10955,7 +4663,6 @@ g_object_set (cell, "text", gtk_file_info_get_display_name (info), "sensitive", sensitive, @@ -13328,7 +8668,7 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c NULL); } -@@ -11023,142 +4724,64 @@ +@@ -11017,142 +4724,64 @@ gpointer data) { GtkFileChooserDefault *impl; @@ -13344,7 +8684,9 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c impl = data; - if (impl->operation_mode == OPERATION_MODE_SEARCH) -- { ++ info = get_list_file_info (impl, iter); ++ if (!info) + { - GtkTreeIter child_iter; - struct stat *statbuf; - gboolean is_folder; @@ -13363,21 +8705,25 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - if (impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER || - impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER) - sensitive = is_folder; -- } ++ g_object_set (cell, ++ "text", "", ++ "sensitive", TRUE, ++ NULL); ++ return; + } - else if (impl->operation_mode == OPERATION_MODE_RECENT) -+ info = get_list_file_info (impl, iter); -+ if (!info) - { +- { - GtkTreeIter child_iter; - GtkRecentInfo *info; - gboolean is_folder; -- + - recent_get_valid_child_iter (impl, &child_iter, iter); - gtk_tree_model_get (GTK_TREE_MODEL (impl->recent_model), &child_iter, - RECENT_MODEL_COL_INFO, &info, - RECENT_MODEL_COL_IS_FOLDER, &is_folder, - -1); -- ++ time_mtime = gtk_file_info_get_modification_time (info); + - if (info) - time_mtime = gtk_recent_info_get_modified (info); - else @@ -13386,14 +8732,11 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - if (impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER || - impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER) - sensitive = is_folder; -+ g_object_set (cell, -+ "text", "", -+ "sensitive", TRUE, -+ NULL); -+ return; - } -- else -- { +- } ++ if (time_mtime == 0) ++ strcpy (buf, _("Unknown")); + else + { - const GtkFileInfo *info; - - info = get_list_file_info (impl, iter); @@ -13407,19 +8750,16 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - } - - time_mtime = (time_t) gtk_file_info_get_modification_time (info); - +- - if (impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER || - impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER) - sensitive = gtk_file_info_get_is_folder (info); - } -+ time_mtime = gtk_file_info_get_modification_time (info); - +- - if (G_UNLIKELY (time_mtime == 0)) - date_str = g_strdup (_("Unknown")); -+ if (time_mtime == 0) -+ strcpy (buf, _("Unknown")); - else - { +- else +- { - GDate mtime, now; - gint days_diff; - struct tm tm_mtime; @@ -13471,9 +8811,9 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c else format = "%x"; /* Any other date */ - } -- -- locale_format = g_locale_from_utf8 (format, -1, NULL, NULL, NULL); +- locale_format = g_locale_from_utf8 (format, -1, NULL, NULL, NULL); +- - if (strftime (buf, sizeof (buf), locale_format, &tm_mtime) != 0) - date_str = g_locale_to_utf8 (buf, -1, NULL, NULL, NULL); - else @@ -13498,18 +8838,22 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c } GtkWidget * -@@ -11169,437 +4792,73 @@ +@@ -11163,437 +4792,73 @@ NULL); } --static void ++/* Handler for the "up-folder" keybinding signal */ + static void -location_set_user_text (GtkFileChooserDefault *impl, - const gchar *path) --{ ++up_folder_handler (GtkFileChooserDefault *impl) + { - _gtk_file_chooser_entry_set_file_part (GTK_FILE_CHOOSER_ENTRY (impl->location_entry), path); - gtk_editable_set_position (GTK_EDITABLE (impl->location_entry), -1); -} -- ++ GtkFilePath * parent; ++ pending_select_paths_add (impl, impl->current_folder); + -static void -location_popup_handler (GtkFileChooserDefault *impl, - const gchar *path) @@ -13531,7 +8875,12 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - g_assert_not_reached (); - break; - } -- ++ if (gtk_file_system_get_parent (impl->file_system, impl->current_folder, ++ &parent, NULL) && parent) ++ { ++ impl->path_history = g_slist_prepend (impl->path_history, ++ gtk_file_path_copy (impl->current_folder)); + - if (impl->current_folder) - change_folder_and_display_error (impl, impl->current_folder, FALSE); - @@ -13585,34 +8934,28 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - } - else - g_assert_not_reached (); --} -- - /* Handler for the "up-folder" keybinding signal */ - static void - up_folder_handler (GtkFileChooserDefault *impl) - { -- _gtk_path_bar_up (GTK_PATH_BAR (impl->browse_path_bar)); -+ GtkFilePath * parent; -+ pending_select_paths_add (impl, impl->current_folder); -+ -+ if (gtk_file_system_get_parent (impl->file_system, impl->current_folder, -+ &parent, NULL) && parent) -+ { -+ impl->path_history = g_slist_prepend (impl->path_history, -+ gtk_file_path_copy (impl->current_folder)); -+ + change_folder_and_display_error (impl, parent); + gtk_file_path_free (parent); + } } +-/* Handler for the "up-folder" keybinding signal */ +-static void +-up_folder_handler (GtkFileChooserDefault *impl) +-{ +- _gtk_path_bar_up (GTK_PATH_BAR (impl->browse_path_bar)); +-} +- /* Handler for the "down-folder" keybinding signal */ static void down_folder_handler (GtkFileChooserDefault *impl) { - _gtk_path_bar_down (GTK_PATH_BAR (impl->browse_path_bar)); -} -- ++ if (impl->path_history) ++ { ++ GtkFilePath * path = impl->path_history->data; + -/* Switches to the shortcut in the specified index */ -static void -switch_to_shortcut (GtkFileChooserDefault *impl, @@ -13625,10 +8968,6 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - - shortcuts_activate_iter (impl, &iter); - focus_browse_tree_view_if_possible (impl); -+ if (impl->path_history) -+ { -+ GtkFilePath * path = impl->path_history->data; -+ + change_folder_and_display_error (impl, path); + impl->path_history = g_slist_remove (impl->path_history, path); + gtk_file_path_free (path); @@ -13641,10 +8980,10 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c { - if (impl->has_home) - switch_to_shortcut (impl, shortcuts_get_index (impl, SHORTCUTS_HOME)); --} -- + } + -/* Handler for the "desktop-folder" keybinding signal */ --static void + static void -desktop_folder_handler (GtkFileChooserDefault *impl) -{ - if (impl->has_desktop) @@ -13694,24 +9033,27 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - gtk_tree_path_free (path); - - switch_to_shortcut (impl, bookmark_pos); - } - - static void +-} +- +-static void show_hidden_handler (GtkFileChooserDefault *impl) { - g_object_set (impl, - "show-hidden", !impl->show_hidden, - NULL); --} -- + } + - -/* Drag and drop interfaces */ - -static void -_shortcuts_pane_model_filter_class_init (ShortcutsPaneModelFilterClass *class) --{ --} -- ++static GtkFilePath * ++gtk_file_chooser_default_get_preview_path (GtkFileChooser *chooser) + { ++ return NULL; + } + -static void -_shortcuts_pane_model_filter_init (ShortcutsPaneModelFilter *model) -{ @@ -13719,10 +9061,13 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c -} - -/* GtkTreeDragSource::row_draggable implementation for the shortcuts filter model */ --static gboolean + static gboolean -shortcuts_pane_model_filter_row_draggable (GtkTreeDragSource *drag_source, - GtkTreePath *path) --{ ++gtk_file_chooser_default_add_shortcut_folder (GtkFileChooser *chooser, ++ const GtkFilePath *path, ++ GError **error) + { - ShortcutsPaneModelFilter *model; - int pos; - int bookmarks_pos; @@ -13797,7 +9142,7 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - - model = RECENT_MODEL_SORT (drag_source); - if (!gtk_tree_model_get_iter (GTK_TREE_MODEL (model), &iter, path)) -- return FALSE; + return FALSE; - - recent_get_valid_child_iter (model->impl, &child_iter, &iter); - gtk_tree_model_get (GTK_TREE_MODEL (model->impl->recent_model), &child_iter, @@ -13805,13 +9150,16 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - -1); - - return is_folder; --} -- --static gboolean + } + + static gboolean -recent_model_sort_drag_data_get (GtkTreeDragSource *drag_source, - GtkTreePath *path, - GtkSelectionData *selection_data) --{ ++gtk_file_chooser_default_remove_shortcut_folder (GtkFileChooser *chooser, ++ const GtkFilePath *path, ++ GError **error) + { - RecentModelSort *model; - GtkTreeIter iter, child_iter; - GtkFilePath *file_path; @@ -13836,14 +9184,18 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - g_strfreev (uris); - - return TRUE; --} -- ++ return TRUE; + } + -static void -recent_model_sort_drag_source_iface_init (GtkTreeDragSourceIface *iface) --{ ++static GSList * ++gtk_file_chooser_default_list_shortcut_folders (GtkFileChooser *chooser) + { - iface->row_draggable = recent_model_sort_row_draggable; - iface->drag_data_get = recent_model_sort_drag_data_get; --} ++ return NULL; + } - -static void -_recent_model_sort_class_init (RecentModelSortClass *klass) @@ -13855,14 +9207,12 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c -_recent_model_sort_init (RecentModelSort *model) -{ - model->impl = NULL; - } - +-} +- -static GtkTreeModel * -recent_model_sort_new (GtkFileChooserDefault *impl, - GtkTreeModel *child_model) -+static GtkFilePath * -+gtk_file_chooser_default_get_preview_path (GtkFileChooser *chooser) - { +-{ - RecentModelSort *model; - - model = g_object_new (RECENT_MODEL_SORT_TYPE, @@ -13871,25 +9221,21 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - model->impl = impl; - - return GTK_TREE_MODEL (model); -+ return NULL; - } - +-} +- - - - static gboolean +-static gboolean -search_model_sort_row_draggable (GtkTreeDragSource *drag_source, - GtkTreePath *path) -+gtk_file_chooser_default_add_shortcut_folder (GtkFileChooser *chooser, -+ const GtkFilePath *path, -+ GError **error) - { +-{ - SearchModelSort *model; - GtkTreeIter iter, child_iter; - gboolean is_folder; - - model = SEARCH_MODEL_SORT (drag_source); - if (!gtk_tree_model_get_iter (GTK_TREE_MODEL (model), &iter, path)) - return FALSE; +- return FALSE; - - search_get_valid_child_iter (model->impl, &child_iter, &iter); - gtk_tree_model_get (GTK_TREE_MODEL (model->impl->search_model), &child_iter, @@ -13897,9 +9243,9 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - -1); - - return is_folder; - } - - static gboolean +-} +- +-static gboolean -search_model_sort_drag_data_get (GtkTreeDragSource *drag_source, - GtkTreePath *path, - GtkSelectionData *selection_data) @@ -13945,20 +9291,14 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - -static void -_search_model_sort_init (SearchModelSort *model) -+gtk_file_chooser_default_remove_shortcut_folder (GtkFileChooser *chooser, -+ const GtkFilePath *path, -+ GError **error) - { +-{ - model->impl = NULL; -+ return TRUE; - } - +-} +- -static GtkTreeModel * -search_model_sort_new (GtkFileChooserDefault *impl, - GtkTreeModel *child_model) -+static GSList * -+gtk_file_chooser_default_list_shortcut_folders (GtkFileChooser *chooser) - { +-{ - SearchModelSort *model; - - model = g_object_new (SEARCH_MODEL_SORT_TYPE, @@ -13967,12 +9307,11 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c - model->impl = impl; - - return GTK_TREE_MODEL (model); -+ return NULL; - } -Index: gtk+-2.12.3/gtk/gtkfilechooserprivate.h +-} +Index: gtk+-2.12.5/gtk/gtkfilechooserprivate.h =================================================================== ---- gtk+-2.12.3.orig/gtk/gtkfilechooserprivate.h 2007-12-04 16:52:08.000000000 +0000 -+++ gtk+-2.12.3/gtk/gtkfilechooserprivate.h 2008-01-04 10:11:20.000000000 +0000 +--- gtk+-2.12.5/gtk/gtkfilechooserprivate.h (revision 19337) ++++ gtk+-2.12.5/gtk/gtkfilechooserprivate.h (working copy) @@ -25,9 +25,6 @@ #include "gtkfilesystem.h" #include "gtkfilesystemmodel.h" @@ -14000,12 +9339,12 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserprivate.h /* Save mode widgets */ GtkWidget *save_widgets; -- ++ GtkWidget *save_file_name_entry; + - GtkWidget *save_folder_label; - GtkWidget *save_folder_combo; - GtkWidget *save_expander; -+ GtkWidget *save_file_name_entry; - +- /* The file browsing widgets */ GtkWidget *browse_widgets; - GtkWidget *browse_shortcuts_tree_view; @@ -14058,7 +9397,8 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserprivate.h LocationMode location_mode; GtkListStore *shortcuts_model; -- ++ GtkTreeModel *shortcuts_filter_model; + - /* Filter for the shortcuts pane. We filter out the "current folder" row and - * the separator that we use for the "Save in folder" combo. - */ @@ -14068,8 +9408,7 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserprivate.h - * its separator. - */ - GtkTreeModel *shortcuts_combo_filter_model; -+ GtkTreeModel *shortcuts_filter_model; - +- GtkTreeModelSort *sort_model; /* Handles */ @@ -14150,10 +9489,10 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserprivate.h }; -Index: gtk+-2.12.3/tests/autotestfilechooser.c +Index: gtk+-2.12.5/tests/autotestfilechooser.c =================================================================== ---- gtk+-2.12.3.orig/tests/autotestfilechooser.c 2007-12-04 16:52:18.000000000 +0000 -+++ gtk+-2.12.3/tests/autotestfilechooser.c 2008-01-02 13:26:09.000000000 +0000 +--- gtk+-2.12.5/tests/autotestfilechooser.c (revision 19337) ++++ gtk+-2.12.5/tests/autotestfilechooser.c (working copy) @@ -510,9 +510,6 @@ && (impl->location_mode == LOCATION_MODE_PATH_BAR ? impl->location_entry == NULL diff --git a/meta/packages/gtk+/gtk+-2.12.3/filechooser-utils.patch b/meta/packages/gtk+/gtk+-2.12.5/filechooser-utils.patch index 45cfd4fd60..45cfd4fd60 100644 --- a/meta/packages/gtk+/gtk+-2.12.3/filechooser-utils.patch +++ b/meta/packages/gtk+/gtk+-2.12.5/filechooser-utils.patch diff --git a/meta/packages/gtk+/gtk+-2.12.3/filechooser.patch b/meta/packages/gtk+/gtk+-2.12.5/filechooser.patch index c422f60d49..c422f60d49 100644 --- a/meta/packages/gtk+/gtk+-2.12.3/filechooser.patch +++ b/meta/packages/gtk+/gtk+-2.12.5/filechooser.patch diff --git a/meta/packages/gtk+/gtk+-2.12.3/filesystem-volumes.patch b/meta/packages/gtk+/gtk+-2.12.5/filesystem-volumes.patch index 826fd6bee0..826fd6bee0 100644 --- a/meta/packages/gtk+/gtk+-2.12.3/filesystem-volumes.patch +++ b/meta/packages/gtk+/gtk+-2.12.5/filesystem-volumes.patch diff --git a/meta/packages/gtk+/gtk+-2.12.3/gtklabel-resize-patch b/meta/packages/gtk+/gtk+-2.12.5/gtklabel-resize-patch index df29656343..df29656343 100644 --- a/meta/packages/gtk+/gtk+-2.12.3/gtklabel-resize-patch +++ b/meta/packages/gtk+/gtk+-2.12.5/gtklabel-resize-patch diff --git a/meta/packages/gtk+/gtk+-2.12.3/hardcoded_libtool.patch b/meta/packages/gtk+/gtk+-2.12.5/hardcoded_libtool.patch index 6adb0cfef6..6adb0cfef6 100644 --- a/meta/packages/gtk+/gtk+-2.12.3/hardcoded_libtool.patch +++ b/meta/packages/gtk+/gtk+-2.12.5/hardcoded_libtool.patch diff --git a/meta/packages/gtk+/gtk+-2.12.3/menu-deactivate.patch b/meta/packages/gtk+/gtk+-2.12.5/menu-deactivate.patch index cfb8849e9f..cfb8849e9f 100644 --- a/meta/packages/gtk+/gtk+-2.12.3/menu-deactivate.patch +++ b/meta/packages/gtk+/gtk+-2.12.5/menu-deactivate.patch diff --git a/meta/packages/gtk+/gtk+-2.12.3/no-demos.patch b/meta/packages/gtk+/gtk+-2.12.5/no-demos.patch index 0fc4c48d1a..0fc4c48d1a 100644 --- a/meta/packages/gtk+/gtk+-2.12.3/no-demos.patch +++ b/meta/packages/gtk+/gtk+-2.12.5/no-demos.patch diff --git a/meta/packages/gtk+/gtk+-2.12.3/pangoxft2.10.6.diff b/meta/packages/gtk+/gtk+-2.12.5/pangoxft2.10.6.diff index 63828cec63..63828cec63 100644 --- a/meta/packages/gtk+/gtk+-2.12.3/pangoxft2.10.6.diff +++ b/meta/packages/gtk+/gtk+-2.12.5/pangoxft2.10.6.diff diff --git a/meta/packages/gtk+/gtk+-2.12.3/range-no-redraw.patch b/meta/packages/gtk+/gtk+-2.12.5/range-no-redraw.patch index 14387b8a2e..14387b8a2e 100644 --- a/meta/packages/gtk+/gtk+-2.12.3/range-no-redraw.patch +++ b/meta/packages/gtk+/gtk+-2.12.5/range-no-redraw.patch diff --git a/meta/packages/gtk+/gtk+-2.12.3/run-iconcache.patch b/meta/packages/gtk+/gtk+-2.12.5/run-iconcache.patch index ac15e9ab24..ac15e9ab24 100644 --- a/meta/packages/gtk+/gtk+-2.12.3/run-iconcache.patch +++ b/meta/packages/gtk+/gtk+-2.12.5/run-iconcache.patch diff --git a/meta/packages/gtk+/gtk+-2.12.3/scrolled-placement.patch b/meta/packages/gtk+/gtk+-2.12.5/scrolled-placement.patch index a0b50c8cac..a0b50c8cac 100644 --- a/meta/packages/gtk+/gtk+-2.12.3/scrolled-placement.patch +++ b/meta/packages/gtk+/gtk+-2.12.5/scrolled-placement.patch diff --git a/meta/packages/gtk+/gtk+-2.12.3/toggle-font.diff b/meta/packages/gtk+/gtk+-2.12.5/toggle-font.diff index 59ad150b2f..59ad150b2f 100644 --- a/meta/packages/gtk+/gtk+-2.12.3/toggle-font.diff +++ b/meta/packages/gtk+/gtk+-2.12.5/toggle-font.diff diff --git a/meta/packages/gtk+/gtk+-2.12.3/xsettings.patch b/meta/packages/gtk+/gtk+-2.12.5/xsettings.patch index b63e262d34..b63e262d34 100644 --- a/meta/packages/gtk+/gtk+-2.12.3/xsettings.patch +++ b/meta/packages/gtk+/gtk+-2.12.5/xsettings.patch diff --git a/meta/packages/gtk+/gtk+_2.12.3.bb b/meta/packages/gtk+/gtk+_2.12.5.bb index 79784dd026..79784dd026 100644 --- a/meta/packages/gtk+/gtk+_2.12.3.bb +++ b/meta/packages/gtk+/gtk+_2.12.5.bb |