summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--meta/conf/distro/poky.conf2
-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
20 files changed, 2127 insertions, 6788 deletions
diff --git a/meta/conf/distro/poky.conf b/meta/conf/distro/poky.conf
index 0454281924..93bd1e734f 100644
--- a/meta/conf/distro/poky.conf
+++ b/meta/conf/distro/poky.conf
@@ -196,7 +196,7 @@ PREFERRED_VERSION_glib-2.0-native ?= "2.12.4"
196PREFERRED_VERSION_atk ?= "1.20.0" 196PREFERRED_VERSION_atk ?= "1.20.0"
197PREFERRED_VERSION_cairo ?= "1.4.10" 197PREFERRED_VERSION_cairo ?= "1.4.10"
198PREFERRED_VERSION_pango ?= "1.18.3" 198PREFERRED_VERSION_pango ?= "1.18.3"
199PREFERRED_VERSION_gtk+ ?= "2.12.3" 199PREFERRED_VERSION_gtk+ ?= "2.12.5"
200 200
201PREFERRED_VERSION_dbus ?= "1.0.2" 201PREFERRED_VERSION_dbus ?= "1.0.2"
202PREFERRED_VERSION_dbus-native ?= "1.0.2" 202PREFERRED_VERSION_dbus-native ?= "1.0.2"
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 @@
1Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c 1Index: gtk+-2.12.5/gtk/gtkfilechooserdefault.c
2=================================================================== 2================ ===================================================
3--- gtk+-2.12.3.orig/gtk/gtkfilechooserdefault.c 2007-12-04 16:52:08.000000000 +0000 3--- gtk+-2.12.5/gtk/gtkfilechooserdefault.c (revision 19337)
4+++ gtk+-2.12.3/gtk/gtkfilechooserdefault.c 2008-01-04 10:11:11.000000000 +0000 4+++ gtk+-2.12.5/gtk/gtkfilechooserdefault.c (working copy)
5@@ -27,12 +27,12 @@ 5@@ -27,12 +27,12 @@
6 #include "gtkcelllayout.h" 6 #include "gtkcelllayout.h"
7 #include "gtkcellrendererpixbuf.h" 7 #include "gtkcellrendererpixbuf.h"
@@ -52,23 +52,6 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
52 /* Profiling stuff */ 52 /* Profiling stuff */
53 #undef PROFILE_FILE_CHOOSER 53 #undef PROFILE_FILE_CHOOSER
54 #ifdef PROFILE_FILE_CHOOSER 54 #ifdef PROFILE_FILE_CHOOSER
55@@ -102,6 +98,7 @@
56 #endif
57
58 #define PROFILE_INDENT 4
59+
60 static int profile_indent;
61
62 static void
63@@ -141,8 +138,6 @@
64 #define profile_msg(x, y)
65 #endif
66
67-
68-
69 typedef struct _GtkFileChooserDefaultClass GtkFileChooserDefaultClass;
70
71 #define GTK_FILE_CHOOSER_DEFAULT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_FILE_CHOOSER_DEFAULT, GtkFileChooserDefaultClass))
72@@ -150,6 +145,7 @@ 55@@ -150,6 +145,7 @@
73 #define GTK_FILE_CHOOSER_DEFAULT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_FILE_CHOOSER_DEFAULT, GtkFileChooserDefaultClass)) 56 #define GTK_FILE_CHOOSER_DEFAULT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_FILE_CHOOSER_DEFAULT, GtkFileChooserDefaultClass))
74 57
@@ -219,14 +202,6 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
219 #define NUM_LINES 45 202 #define NUM_LINES 45
220 #define NUM_CHARS 60 203 #define NUM_CHARS 60
221 204
222@@ -361,7 +241,6 @@
223 const GtkFilePath *path,
224 GError **error);
225 static GSList * gtk_file_chooser_default_list_shortcut_folders (GtkFileChooser *chooser);
226-
227 static void gtk_file_chooser_default_get_default_size (GtkFileChooserEmbed *chooser_embed,
228 gint *default_width,
229 gint *default_height);
230@@ -369,52 +248,17 @@ 205@@ -369,52 +248,17 @@
231 static gboolean gtk_file_chooser_default_should_respond (GtkFileChooserEmbed *chooser_embed); 206 static gboolean gtk_file_chooser_default_should_respond (GtkFileChooserEmbed *chooser_embed);
232 static void gtk_file_chooser_default_initial_focus (GtkFileChooserEmbed *chooser_embed); 207 static void gtk_file_chooser_default_initial_focus (GtkFileChooserEmbed *chooser_embed);
@@ -245,23 +220,23 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
245-static void search_shortcut_handler (GtkFileChooserDefault *impl); 220-static void search_shortcut_handler (GtkFileChooserDefault *impl);
246-static void recent_shortcut_handler (GtkFileChooserDefault *impl); 221-static void recent_shortcut_handler (GtkFileChooserDefault *impl);
247-static void update_appearance (GtkFileChooserDefault *impl); 222-static void update_appearance (GtkFileChooserDefault *impl);
248-
249-static void set_current_filter (GtkFileChooserDefault *impl,
250- GtkFileFilter *filter);
251-static void check_preview_change (GtkFileChooserDefault *impl);
252+static void up_folder_handler (GtkFileChooserDefault *impl); 223+static void up_folder_handler (GtkFileChooserDefault *impl);
253+static void down_folder_handler (GtkFileChooserDefault *impl); 224+static void down_folder_handler (GtkFileChooserDefault *impl);
254+static void home_folder_handler (GtkFileChooserDefault *impl); 225+static void home_folder_handler (GtkFileChooserDefault *impl);
255+static void show_hidden_handler (GtkFileChooserDefault *impl); 226+static void show_hidden_handler (GtkFileChooserDefault *impl);
256+static void update_appearance (GtkFileChooserDefault *impl); 227+static void update_appearance (GtkFileChooserDefault *impl);
257 228
229-static void set_current_filter (GtkFileChooserDefault *impl,
230- GtkFileFilter *filter);
231-static void check_preview_change (GtkFileChooserDefault *impl);
232-
258 static void filter_combo_changed (GtkComboBox *combo_box, 233 static void filter_combo_changed (GtkComboBox *combo_box,
259 GtkFileChooserDefault *impl); 234 GtkFileChooserDefault *impl);
260-static void shortcuts_row_activated_cb (GtkTreeView *tree_view, 235-static void shortcuts_row_activated_cb (GtkTreeView *tree_view,
261- GtkTreePath *path, 236- GtkTreePath *path,
262- GtkTreeViewColumn *column, 237- GtkTreeViewColumn *column,
263- GtkFileChooserDefault *impl); 238- GtkFileChooserDefault *impl);
264- 239
265-static gboolean shortcuts_key_press_event_cb (GtkWidget *widget, 240-static gboolean shortcuts_key_press_event_cb (GtkWidget *widget,
266- GdkEventKey *event, 241- GdkEventKey *event,
267- GtkFileChooserDefault *impl); 242- GtkFileChooserDefault *impl);
@@ -281,7 +256,7 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
281- const GtkFilePath *path); 256- const GtkFilePath *path);
282- 257-
283-static void bookmarks_check_add_sensitivity (GtkFileChooserDefault *impl); 258-static void bookmarks_check_add_sensitivity (GtkFileChooserDefault *impl);
284 259-
285+static void set_current_filter (GtkFileChooserDefault *impl, 260+static void set_current_filter (GtkFileChooserDefault *impl,
286+ GtkFileFilter *filter); 261+ GtkFileFilter *filter);
287 static gboolean list_select_func (GtkTreeSelection *selection, 262 static gboolean list_select_func (GtkTreeSelection *selection,
@@ -307,12 +282,13 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
307 static void list_icon_data_func (GtkTreeViewColumn *tree_column, 282 static void list_icon_data_func (GtkTreeViewColumn *tree_column,
308 GtkCellRenderer *cell, 283 GtkCellRenderer *cell,
309 GtkTreeModel *tree_model, 284 GtkTreeModel *tree_model,
310@@ -477,114 +308,7 @@ 285@@ -477,115 +308,8 @@
311 286
312 static void location_button_toggled_cb (GtkToggleButton *toggle, 287 static void location_button_toggled_cb (GtkToggleButton *toggle,
313 GtkFileChooserDefault *impl); 288 GtkFileChooserDefault *impl);
314-static void location_switch_to_path_bar (GtkFileChooserDefault *impl); 289-static void location_switch_to_path_bar (GtkFileChooserDefault *impl);
315- 290+static void settings_load (GtkFileChooserDefault *impl);
291
316-static void search_stop_searching (GtkFileChooserDefault *impl, 292-static void search_stop_searching (GtkFileChooserDefault *impl,
317- gboolean remove_query); 293- gboolean remove_query);
318-static void search_clear_model (GtkFileChooserDefault *impl, 294-static void search_clear_model (GtkFileChooserDefault *impl,
@@ -419,10 +395,10 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
419- GtkTreeModel *child_model); 395- GtkTreeModel *child_model);
420- 396-
421- 397-
422+static void settings_load (GtkFileChooserDefault *impl); 398-
423
424 G_DEFINE_TYPE_WITH_CODE (GtkFileChooserDefault, _gtk_file_chooser_default, GTK_TYPE_VBOX, 399 G_DEFINE_TYPE_WITH_CODE (GtkFileChooserDefault, _gtk_file_chooser_default, GTK_TYPE_VBOX,
425 G_IMPLEMENT_INTERFACE (GTK_TYPE_FILE_CHOOSER, 400 G_IMPLEMENT_INTERFACE (GTK_TYPE_FILE_CHOOSER,
401 gtk_file_chooser_default_iface_init)
426@@ -595,13 +319,9 @@ 402@@ -595,13 +319,9 @@
427 static void 403 static void
428 _gtk_file_chooser_default_class_init (GtkFileChooserDefaultClass *class) 404 _gtk_file_chooser_default_class_init (GtkFileChooserDefaultClass *class)
@@ -446,23 +422,26 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
446 NULL, NULL, 422 NULL, NULL,
447 _gtk_marshal_VOID__STRING, 423 _gtk_marshal_VOID__STRING,
448 G_TYPE_NONE, 1, G_TYPE_STRING); 424 G_TYPE_NONE, 1, G_TYPE_STRING);
449@@ -629,15 +349,7 @@ 425@@ -629,18 +349,10 @@
450 _gtk_binding_signal_new ("location-popup-on-paste", 426 _gtk_binding_signal_new ("location-popup-on-paste",
451 G_OBJECT_CLASS_TYPE (class), 427 G_OBJECT_CLASS_TYPE (class),
452 G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION, 428 G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
453- G_CALLBACK (location_popup_on_paste_handler), 429- G_CALLBACK (location_popup_on_paste_handler),
454- NULL, NULL, 430+ NULL,
455- _gtk_marshal_VOID__VOID, 431 NULL, NULL,
456- G_TYPE_NONE, 0); 432 _gtk_marshal_VOID__VOID,
433 G_TYPE_NONE, 0);
457- signals[LOCATION_TOGGLE_POPUP] = 434- signals[LOCATION_TOGGLE_POPUP] =
458- _gtk_binding_signal_new (I_("location-toggle-popup"), 435- _gtk_binding_signal_new (I_("location-toggle-popup"),
459- G_OBJECT_CLASS_TYPE (class), 436- G_OBJECT_CLASS_TYPE (class),
460- G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION, 437- G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
461- G_CALLBACK (location_toggle_popup_handler), 438- G_CALLBACK (location_toggle_popup_handler),
462+ NULL, 439- NULL, NULL,
463 NULL, NULL, 440- _gtk_marshal_VOID__VOID,
464 _gtk_marshal_VOID__VOID, 441- G_TYPE_NONE, 0);
465 G_TYPE_NONE, 0); 442 signals[UP_FOLDER] =
443 _gtk_binding_signal_new (I_("up-folder"),
444 G_OBJECT_CLASS_TYPE (class),
466@@ -665,22 +377,6 @@ 445@@ -665,22 +377,6 @@
467 NULL, NULL, 446 NULL, NULL,
468 _gtk_marshal_VOID__VOID, 447 _gtk_marshal_VOID__VOID,
@@ -528,13 +507,13 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
528- GDK_r, GDK_MOD1_MASK, 507- GDK_r, GDK_MOD1_MASK,
529- "recent-shortcut", 508- "recent-shortcut",
530- 0); 509- 0);
531- 510
532- for (i = 0; i < 10; i++) 511- for (i = 0; i < 10; i++)
533- gtk_binding_entry_add_signal (binding_set, 512- gtk_binding_entry_add_signal (binding_set,
534- quick_bookmark_keyvals[i], GDK_MOD1_MASK, 513- quick_bookmark_keyvals[i], GDK_MOD1_MASK,
535- "quick-bookmark", 514- "quick-bookmark",
536- 1, G_TYPE_INT, i); 515- 1, G_TYPE_INT, i);
537 516-
538 _gtk_file_chooser_install_properties (gobject_class); 517 _gtk_file_chooser_install_properties (gobject_class);
539+ 518+
540+ gtk_settings_install_property (g_param_spec_string ("gtk-file-chooser-backend", 519+ gtk_settings_install_property (g_param_spec_string ("gtk-file-chooser-backend",
@@ -567,7 +546,7 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
567 } 546 }
568 547
569 static void 548 static void
570@@ -827,85 +497,27 @@ 549@@ -827,87 +497,29 @@
571 access ("MARK: *** CREATE FILE CHOOSER", F_OK); 550 access ("MARK: *** CREATE FILE CHOOSER", F_OK);
572 #endif 551 #endif
573 impl->local_only = TRUE; 552 impl->local_only = TRUE;
@@ -591,9 +570,12 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
591 impl->tooltips = gtk_tooltips_new (); 570 impl->tooltips = gtk_tooltips_new ();
592 g_object_ref_sink (impl->tooltips); 571 g_object_ref_sink (impl->tooltips);
593 572
594- profile_end ("end", NULL); 573+ if (!impl->root_folder)
595-} 574+ impl->root_folder = g_strdup ("/");
596- 575+
576 profile_end ("end", NULL);
577 }
578
597-/* Frees the data columns for the specified iter in the shortcuts model*/ 579-/* Frees the data columns for the specified iter in the shortcuts model*/
598-static void 580-static void
599-shortcuts_free_row_data (GtkFileChooserDefault *impl, 581-shortcuts_free_row_data (GtkFileChooserDefault *impl,
@@ -602,7 +584,7 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
602- gpointer col_data; 584- gpointer col_data;
603- ShortcutType shortcut_type; 585- ShortcutType shortcut_type;
604- GtkFileSystemHandle *handle; 586- GtkFileSystemHandle *handle;
605- 587
606- gtk_tree_model_get (GTK_TREE_MODEL (impl->shortcuts_model), iter, 588- gtk_tree_model_get (GTK_TREE_MODEL (impl->shortcuts_model), iter,
607- SHORTCUTS_COL_DATA, &col_data, 589- SHORTCUTS_COL_DATA, &col_data,
608- SHORTCUTS_COL_TYPE, &shortcut_type, 590- SHORTCUTS_COL_TYPE, &shortcut_type,
@@ -629,17 +611,14 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
629- GtkFilePath *path; 611- GtkFilePath *path;
630- 612-
631- g_assert (shortcut_type == SHORTCUT_TYPE_PATH); 613- g_assert (shortcut_type == SHORTCUT_TYPE_PATH);
632+ if (!impl->root_folder) 614-
633+ impl->root_folder = g_strdup ("/");
634
635- path = col_data; 615- path = col_data;
636- gtk_file_path_free (path); 616- gtk_file_path_free (path);
637- } 617- }
638+ profile_end ("end", NULL); 618-}
639 } 619-
640
641-/* Frees all the data columns in the shortcuts model */ 620-/* Frees all the data columns in the shortcuts model */
642-static void 621 static void
643-shortcuts_free (GtkFileChooserDefault *impl) 622-shortcuts_free (GtkFileChooserDefault *impl)
644-{ 623-{
645- GtkTreeIter iter; 624- GtkTreeIter iter;
@@ -657,25 +636,12 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
657- g_object_unref (impl->shortcuts_model); 636- g_object_unref (impl->shortcuts_model);
658- impl->shortcuts_model = NULL; 637- impl->shortcuts_model = NULL;
659-} 638-}
660 639-
661 static void 640-static void
662 pending_select_paths_free (GtkFileChooserDefault *impl) 641 pending_select_paths_free (GtkFileChooserDefault *impl)
663@@ -924,12 +536,12 @@
664 impl->pending_select_paths = NULL;
665 }
666
667+
668 static void
669 pending_select_paths_add (GtkFileChooserDefault *impl,
670 const GtkFilePath *path)
671 { 642 {
672- impl->pending_select_paths = 643 GSList *l;
673- g_slist_prepend (impl->pending_select_paths, gtk_file_path_copy (path)); 644@@ -964,19 +576,28 @@
674+ impl->pending_select_paths = g_slist_prepend (impl->pending_select_paths, gtk_file_path_copy (path));
675 }
676
677 /* Used from gtk_tree_selection_selected_foreach() */
678@@ -964,18 +576,27 @@
679 } 645 }
680 646
681 static void 647 static void
@@ -690,26 +656,27 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
690+ for (l = impl->path_history; l; l = l->next) 656+ for (l = impl->path_history; l; l = l->next)
691+ { 657+ {
692+ GtkFilePath *path; 658+ GtkFilePath *path;
693+ 659
660- if (impl->shortcuts_combo_filter_model)
661- g_object_unref (impl->shortcuts_combo_filter_model);
694+ path = l->data; 662+ path = l->data;
695+ gtk_file_path_free (path); 663+ gtk_file_path_free (path);
696+ } 664+ }
697 665
698- if (impl->shortcuts_combo_filter_model) 666- shortcuts_free (impl);
699- g_object_unref (impl->shortcuts_combo_filter_model);
700+ g_slist_free (impl->path_history); 667+ g_slist_free (impl->path_history);
701+ impl->path_history = NULL; 668+ impl->path_history = NULL;
702+} 669+}
703 670
704- shortcuts_free (impl);
705+static void 671+static void
706+gtk_file_chooser_default_finalize (GObject *object) 672+gtk_file_chooser_default_finalize (GObject *object)
707+{ 673+{
708+ GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (object); 674+ GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (object);
709+ GSList *l; 675+ GSList *l;
710 676+
711 g_object_unref (impl->file_system); 677 g_object_unref (impl->file_system);
712 678
679 g_free (impl->browse_files_last_selected_name);
713@@ -999,8 +620,7 @@ 680@@ -999,8 +620,7 @@
714 if (impl->current_folder) 681 if (impl->current_folder)
715 gtk_file_path_free (impl->current_folder); 682 gtk_file_path_free (impl->current_folder);
@@ -726,14 +693,14 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
726 693
727- search_clear_model (impl, FALSE); 694- search_clear_model (impl, FALSE);
728- recent_clear_model (impl, FALSE); 695- recent_clear_model (impl, FALSE);
729-
730- g_free (impl->preview_display_name);
731+ if (impl->list_press_path) 696+ if (impl->list_press_path)
732+ { 697+ {
733+ gtk_tree_path_free (impl->list_press_path); 698+ gtk_tree_path_free (impl->list_press_path);
734+ impl->list_press_path = NULL; 699+ impl->list_press_path = NULL;
735+ } 700+ }
736 701
702- g_free (impl->preview_display_name);
703-
737 g_free (impl->edited_new_text); 704 g_free (impl->edited_new_text);
738 705
739 g_object_unref (impl->tooltips); 706 g_object_unref (impl->tooltips);
@@ -785,7 +752,7 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
785 path, error); 752 path, error);
786 } 753 }
787 754
788@@ -1175,9378 +776,3705 @@ 755@@ -1175,514 +776,108 @@
789 756
790 /* Changes folders, displaying an error dialog if this fails */ 757 /* Changes folders, displaying an error dialog if this fails */
791 static gboolean 758 static gboolean
@@ -803,9 +770,7 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
803 g_return_val_if_fail (path != NULL, FALSE); 770 g_return_val_if_fail (path != NULL, FALSE);
804 771
805- profile_start ("start", (char *) path); 772- profile_start ("start", (char *) path);
806+ path_copy = gtk_file_path_copy (path); 773-
807+ file_name = gtk_file_system_path_to_filename (impl->file_system, path_copy);
808
809- /* We copy the path because of this case: 774- /* We copy the path because of this case:
810- * 775- *
811- * list_row_activated() 776- * list_row_activated()
@@ -814,19 +779,28 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
814- * calls _gtk_file_chooser_set_current_folder_path() 779- * calls _gtk_file_chooser_set_current_folder_path()
815- * changing folders fails, sets model to NULL, thus freeing the path in (*) 780- * changing folders fails, sets model to NULL, thus freeing the path in (*)
816- */ 781- */
782-
783 path_copy = gtk_file_path_copy (path);
784+ file_name = gtk_file_system_path_to_filename (impl->file_system, path_copy);
785
786- error = NULL;
787- result = gtk_file_chooser_default_update_current_folder (GTK_FILE_CHOOSER (impl), path_copy, TRUE, clear_entry, &error);
817+ if (!file_name) 788+ if (!file_name)
818+ { 789+ {
819+ gtk_file_path_free (path_copy); 790+ gtk_file_path_free (path_copy);
820+ return 0; 791+ return 0;
821+ } 792+ }
822+ 793
794- if (!result)
795- error_changing_folder_dialog (impl, path_copy, error);
823+ if (impl->root_folder && file_name[0] == '/' && file_name[1] == 0) 796+ if (impl->root_folder && file_name[0] == '/' && file_name[1] == 0)
824+ { 797+ {
825+ /* If changing to / and we have root_folder, change into it instead */ 798+ /* If changing to / and we have root_folder, change into it instead */
826+ gtk_file_path_free (path_copy); 799+ gtk_file_path_free (path_copy);
827+ path_copy = gtk_file_system_filename_to_path (impl->file_system, 800+ path_copy = gtk_file_system_filename_to_path (impl->file_system,
828+ impl->root_folder); 801+ impl->root_folder);
829+ 802
803- gtk_file_path_free (path_copy);
830+ gtk_widget_set_sensitive (impl->up_button, FALSE); 804+ gtk_widget_set_sensitive (impl->up_button, FALSE);
831+ } 805+ }
832+ else if (impl->root_folder && 806+ else if (impl->root_folder &&
@@ -850,7 +824,8 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
850+ gchar *name = 824+ gchar *name =
851+ gtk_file_system_path_to_filename (impl->file_system, 825+ gtk_file_system_path_to_filename (impl->file_system,
852+ impl->current_folder); 826+ impl->current_folder);
853+ 827
828- profile_end ("end", (char *) path);
854+ if (name && !strncmp (name, "/media", 6)) 829+ if (name && !strncmp (name, "/media", 6))
855+ { 830+ {
856+ g_free (name); 831+ g_free (name);
@@ -858,52 +833,13 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
858+ g_free (file_name); 833+ g_free (file_name);
859+ return 0; 834+ return 0;
860+ } 835+ }
861+
862+ gtk_widget_set_sensitive (impl->up_button, TRUE);
863+ }
864+ else if (!strncmp (file_name, "/media/", 7))
865+ {
866+ /* Changing into a media child -- if it is an immediate child, disable
867+ * the Up button
868+ */
869+ gchar * p = file_name + 7;
870+ gchar * q = strchr (p, '/');
871+ if (!q)
872+ gtk_widget_set_sensitive (impl->up_button, FALSE);
873+ else
874+ gtk_widget_set_sensitive (impl->up_button, TRUE);
875+ }
876+ else
877+ {
878+ gtk_widget_set_sensitive (impl->up_button, TRUE);
879+ }
880
881- path_copy = gtk_file_path_copy (path);
882
883 error = NULL;
884- result = gtk_file_chooser_default_update_current_folder (GTK_FILE_CHOOSER (impl), path_copy, TRUE, clear_entry, &error);
885+ result = _gtk_file_chooser_set_current_folder_path (GTK_FILE_CHOOSER (impl), path_copy, &error);
886
887- if (!result)
888+ if (errormsg && !result)
889 error_changing_folder_dialog (impl, path_copy, error);
890
891- gtk_file_path_free (path_copy);
892+ gtk_label_set_text (GTK_LABEL (impl->location_label), file_name);
893
894- profile_end ("end", (char *) path);
895+ gtk_file_path_free (path_copy);
896+ g_free (file_name);
897
898 return result;
899 }
900 836
837- return result;
838-}
839-
901-static void 840-static void
902-update_preview_widget_visibility (GtkFileChooserDefault *impl) 841-update_preview_widget_visibility (GtkFileChooserDefault *impl)
903+static gboolean 842-{
904+change_folder_and_display_error (GtkFileChooserDefault *impl,
905+ const GtkFilePath *path)
906 {
907- if (impl->use_preview_label) 843- if (impl->use_preview_label)
908- { 844- {
909- if (!impl->preview_label) 845- if (!impl->preview_label)
@@ -915,7 +851,21 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
915- gtk_widget_show (impl->preview_label); 851- gtk_widget_show (impl->preview_label);
916- } 852- }
917- } 853- }
918- else 854+ gtk_widget_set_sensitive (impl->up_button, TRUE);
855+ }
856+ else if (!strncmp (file_name, "/media/", 7))
857+ {
858+ /* Changing into a media child -- if it is an immediate child, disable
859+ * the Up button
860+ */
861+ gchar * p = file_name + 7;
862+ gchar * q = strchr (p, '/');
863+ if (!q)
864+ gtk_widget_set_sensitive (impl->up_button, FALSE);
865+ else
866+ gtk_widget_set_sensitive (impl->up_button, TRUE);
867+ }
868 else
919- { 869- {
920- if (impl->preview_label) 870- if (impl->preview_label)
921- { 871- {
@@ -923,92 +873,72 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
923- impl->preview_label = NULL; 873- impl->preview_label = NULL;
924- } 874- }
925- } 875- }
926- 876+ {
877+ gtk_widget_set_sensitive (impl->up_button, TRUE);
878+ }
879
927- if (impl->preview_widget_active && impl->preview_widget) 880- if (impl->preview_widget_active && impl->preview_widget)
928- gtk_widget_show (impl->preview_box); 881- gtk_widget_show (impl->preview_box);
929- else 882- else
930- gtk_widget_hide (impl->preview_box); 883- gtk_widget_hide (impl->preview_box);
931- 884
932- g_signal_emit_by_name (impl, "default-size-changed"); 885- g_signal_emit_by_name (impl, "default-size-changed");
933+ return change_folder (impl, path, TRUE); 886-}
934 } 887+ error = NULL;
888+ result = _gtk_file_chooser_set_current_folder_path (GTK_FILE_CHOOSER (impl), path_copy, &error);
935 889
936-static void 890-static void
937-set_preview_widget (GtkFileChooserDefault *impl, 891-set_preview_widget (GtkFileChooserDefault *impl,
938- GtkWidget *preview_widget) 892- GtkWidget *preview_widget)
939+ 893-{
940+/* FIXME: GtkFileSystem needs a function to split a remote path
941+ * into hostname and path components, or maybe just have a
942+ * gtk_file_system_path_get_display_name().
943+ *
944+ * This function is also used in gtkfilechooserbutton.c
945+ */
946+gchar *
947+_gtk_file_chooser_label_for_uri (const gchar *uri)
948 {
949- if (preview_widget == impl->preview_widget) 894- if (preview_widget == impl->preview_widget)
950- return; 895- return;
951+ const gchar *path, *start, *end, *p; 896+ if (errormsg && !result)
952+ gchar *host, *label; 897+ error_changing_folder_dialog (impl, path_copy, error);
953 898
954- if (impl->preview_widget) 899- if (impl->preview_widget)
955- gtk_container_remove (GTK_CONTAINER (impl->preview_box), 900- gtk_container_remove (GTK_CONTAINER (impl->preview_box),
956- impl->preview_widget); 901- impl->preview_widget);
957+ start = strstr (uri, "://"); 902+ gtk_label_set_text (GTK_LABEL (impl->location_label), file_name);
958+ start += 3;
959+ path = strchr (start, '/');
960 903
961- impl->preview_widget = preview_widget; 904- impl->preview_widget = preview_widget;
962- if (impl->preview_widget) 905- if (impl->preview_widget)
963+ if (path) 906- {
964+ end = path;
965+ else
966 {
967- gtk_widget_show (impl->preview_widget); 907- gtk_widget_show (impl->preview_widget);
968- gtk_box_pack_start (GTK_BOX (impl->preview_box), impl->preview_widget, TRUE, TRUE, 0); 908- gtk_box_pack_start (GTK_BOX (impl->preview_box), impl->preview_widget, TRUE, TRUE, 0);
969- gtk_box_reorder_child (GTK_BOX (impl->preview_box), 909- gtk_box_reorder_child (GTK_BOX (impl->preview_box),
970- impl->preview_widget, 910- impl->preview_widget,
971- (impl->use_preview_label && impl->preview_label) ? 1 : 0); 911- (impl->use_preview_label && impl->preview_label) ? 1 : 0);
972+ end = uri + strlen (uri); 912- }
973+ path = "/"; 913+ gtk_file_path_free (path_copy);
974 } 914+ g_free (file_name);
975 915
976- update_preview_widget_visibility (impl); 916- update_preview_widget_visibility (impl);
977-} 917+ return result;
978+ /* strip username */ 918 }
979+ p = strchr (start, '@');
980+ if (p && p < end)
981+ {
982+ start = p + 1;
983+ }
984 919
985-/* Renders a "Search" icon at an appropriate size for a tree view */ 920-/* Renders a "Search" icon at an appropriate size for a tree view */
986-static GdkPixbuf * 921-static GdkPixbuf *
987-render_search_icon (GtkFileChooserDefault *impl) 922-render_search_icon (GtkFileChooserDefault *impl)
988-{ 923+static gboolean
924+change_folder_and_display_error (GtkFileChooserDefault *impl,
925+ const GtkFilePath *path)
926 {
989- return gtk_widget_render_icon (GTK_WIDGET (impl), GTK_STOCK_FIND, GTK_ICON_SIZE_MENU, NULL); 927- return gtk_widget_render_icon (GTK_WIDGET (impl), GTK_STOCK_FIND, GTK_ICON_SIZE_MENU, NULL);
990-} 928+ return change_folder (impl, path, TRUE);
991+ p = strchr (start, ':'); 929 }
992+ if (p && p < end)
993+ end = p;
994 930
995-static GdkPixbuf * 931-static GdkPixbuf *
996-render_recent_icon (GtkFileChooserDefault *impl) 932-render_recent_icon (GtkFileChooserDefault *impl)
997-{ 933-{
998- GtkIconTheme *theme; 934- GtkIconTheme *theme;
999- GdkPixbuf *retval; 935- GdkPixbuf *retval;
1000+ host = g_strndup (start, end - start);
1001 936
1002- if (gtk_widget_has_screen (GTK_WIDGET (impl))) 937- if (gtk_widget_has_screen (GTK_WIDGET (impl)))
1003- theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (GTK_WIDGET (impl))); 938- theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (GTK_WIDGET (impl)));
1004- else 939- else
1005- theme = gtk_icon_theme_get_default (); 940- theme = gtk_icon_theme_get_default ();
1006+ /* Translators: the first string is a path and the second string 941-
1007+ * is a hostname. Nautilus and the panel contain the same string
1008+ * to translate.
1009+ */
1010+ label = g_strdup_printf (_("%1$s on %2$s"), path, host);
1011
1012- retval = gtk_icon_theme_load_icon (theme, "document-open-recent", 942- retval = gtk_icon_theme_load_icon (theme, "document-open-recent",
1013- impl->icon_size, 0, 943- impl->icon_size, 0,
1014- NULL); 944- NULL);
@@ -1016,13 +946,11 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
1016- /* fallback */ 946- /* fallback */
1017- if (!retval) 947- if (!retval)
1018- retval = gtk_widget_render_icon (GTK_WIDGET (impl), GTK_STOCK_FILE, GTK_ICON_SIZE_MENU, NULL); 948- retval = gtk_widget_render_icon (GTK_WIDGET (impl), GTK_STOCK_FILE, GTK_ICON_SIZE_MENU, NULL);
1019+ g_free (host); 949-
1020
1021- return retval; 950- return retval;
1022+ return label; 951-}
1023 } 952-
1024 953-
1025
1026-/* Re-reads all the icons for the shortcuts, used when the theme changes */ 954-/* Re-reads all the icons for the shortcuts, used when the theme changes */
1027-struct ReloadIconsData 955-struct ReloadIconsData
1028-{ 956-{
@@ -1030,109 +958,58 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
1030- GtkTreeRowReference *row_ref; 958- GtkTreeRowReference *row_ref;
1031-}; 959-};
1032- 960-
1033+/* Callback used when the "New Folder" button is clicked */ 961-static void
1034 static void
1035-shortcuts_reload_icons_get_info_cb (GtkFileSystemHandle *handle, 962-shortcuts_reload_icons_get_info_cb (GtkFileSystemHandle *handle,
1036- const GtkFileInfo *info, 963- const GtkFileInfo *info,
1037- const GError *error, 964- const GError *error,
1038- gpointer user_data) 965- gpointer user_data)
1039+new_folder_button_clicked (GtkButton *button, 966-{
1040+ GtkFileChooserDefault *impl)
1041 {
1042- GdkPixbuf *pixbuf; 967- GdkPixbuf *pixbuf;
1043 GtkTreeIter iter; 968- GtkTreeIter iter;
1044 GtkTreePath *path; 969- GtkTreePath *path;
1045- gboolean cancelled = handle->cancelled; 970- gboolean cancelled = handle->cancelled;
1046- struct ReloadIconsData *data = user_data; 971- struct ReloadIconsData *data = user_data;
1047 972-
1048- if (!g_slist_find (data->impl->reload_icon_handles, handle)) 973- if (!g_slist_find (data->impl->reload_icon_handles, handle))
1049- goto out; 974- goto out;
1050+ if (!impl->browse_files_model) 975-
1051+ return; /* FIXME: this sucks. Disable the New Folder button or something. */
1052
1053- data->impl->reload_icon_handles = g_slist_remove (data->impl->reload_icon_handles, handle); 976- data->impl->reload_icon_handles = g_slist_remove (data->impl->reload_icon_handles, handle);
1054+ /* Prevent button from being clicked twice */ 977-
1055+ gtk_widget_set_sensitive (impl->browse_new_folder_button, FALSE);
1056
1057- if (cancelled || error) 978- if (cancelled || error)
1058- goto out; 979- goto out;
1059+ _gtk_file_system_model_add_editable (impl->browse_files_model, &iter); 980-
1060
1061- pixbuf = gtk_file_info_render_icon (info, GTK_WIDGET (data->impl), 981- pixbuf = gtk_file_info_render_icon (info, GTK_WIDGET (data->impl),
1062- data->impl->icon_size, NULL); 982- data->impl->icon_size, NULL);
1063+ path = gtk_tree_model_get_path (GTK_TREE_MODEL (impl->browse_files_model), &iter); 983-
1064+ gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (impl->browse_files_tree_view),
1065+ path, impl->list_name_column,
1066+ FALSE, 0.0, 0.0);
1067+
1068+ g_object_set (impl->list_name_renderer, "editable", TRUE, NULL);
1069+ gtk_tree_view_set_cursor (GTK_TREE_VIEW (impl->browse_files_tree_view),
1070+ path,
1071+ impl->list_name_column,
1072+ TRUE);
1073
1074- path = gtk_tree_row_reference_get_path (data->row_ref); 984- path = gtk_tree_row_reference_get_path (data->row_ref);
1075- gtk_tree_model_get_iter (GTK_TREE_MODEL (data->impl->shortcuts_model), &iter, path); 985- gtk_tree_model_get_iter (GTK_TREE_MODEL (data->impl->shortcuts_model), &iter, path);
1076- gtk_list_store_set (data->impl->shortcuts_model, &iter, 986- gtk_list_store_set (data->impl->shortcuts_model, &iter,
1077- SHORTCUTS_COL_PIXBUF, pixbuf, 987- SHORTCUTS_COL_PIXBUF, pixbuf,
1078- -1); 988- -1);
1079 gtk_tree_path_free (path); 989- gtk_tree_path_free (path);
1080+} 990-
1081
1082- if (pixbuf) 991- if (pixbuf)
1083- g_object_unref (pixbuf); 992- g_object_unref (pixbuf);
1084+static void 993-
1085+edited_idle_create_folder_cb (GtkFileSystemHandle *handle,
1086+ const GtkFilePath *path,
1087+ const GError *error,
1088+ gpointer data)
1089+{
1090+ gboolean cancelled = handle->cancelled;
1091+ GtkFileChooserDefault *impl = data;
1092
1093-out: 994-out:
1094- gtk_tree_row_reference_free (data->row_ref); 995- gtk_tree_row_reference_free (data->row_ref);
1095- g_object_unref (data->impl); 996- g_object_unref (data->impl);
1096- g_free (data); 997- g_free (data);
1097+ if (!g_slist_find (impl->pending_handles, handle)) 998-
1098+ goto out; 999- g_object_unref (handle);
1099+ 1000-}
1100+ impl->pending_handles = g_slist_remove (impl->pending_handles, handle); 1001-
1101+
1102+ if (cancelled)
1103+ goto out;
1104+
1105+ if (!error)
1106+ change_folder_and_display_error (impl, path);
1107+ else
1108+ error_creating_folder_dialog (impl, path, g_error_copy (error));
1109
1110+ out:
1111+ g_object_unref (impl);
1112 g_object_unref (handle);
1113 }
1114
1115-static void 1002-static void
1116-shortcuts_reload_icons (GtkFileChooserDefault *impl) 1003-shortcuts_reload_icons (GtkFileChooserDefault *impl)
1117+/* Idle handler for creating a new folder after editing its name cell, or for 1004-{
1118+ * canceling the editing.
1119+ */
1120+static gboolean
1121+edited_idle_cb (GtkFileChooserDefault *impl)
1122 {
1123- GSList *l; 1005- GSList *l;
1124- GtkTreeIter iter; 1006- GtkTreeIter iter;
1125+ GDK_THREADS_ENTER (); 1007-
1126
1127- profile_start ("start", NULL); 1008- profile_start ("start", NULL);
1128+ g_source_destroy (impl->edited_idle); 1009-
1129+ impl->edited_idle = NULL;
1130
1131- if (!gtk_tree_model_get_iter_first (GTK_TREE_MODEL (impl->shortcuts_model), &iter)) 1010- if (!gtk_tree_model_get_iter_first (GTK_TREE_MODEL (impl->shortcuts_model), &iter))
1132- goto out; 1011- goto out;
1133+ _gtk_file_system_model_remove_editable (impl->browse_files_model); 1012-
1134+ g_object_set (impl->list_name_renderer, "editable", FALSE, NULL);
1135
1136- for (l = impl->reload_icon_handles; l; l = l->next) 1013- for (l = impl->reload_icon_handles; l; l = l->next)
1137- { 1014- {
1138- GtkFileSystemHandle *handle = GTK_FILE_SYSTEM_HANDLE (l->data); 1015- GtkFileSystemHandle *handle = GTK_FILE_SYSTEM_HANDLE (l->data);
@@ -1140,11 +1017,9 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
1140- } 1017- }
1141- g_slist_free (impl->reload_icon_handles); 1018- g_slist_free (impl->reload_icon_handles);
1142- impl->reload_icon_handles = NULL; 1019- impl->reload_icon_handles = NULL;
1143+ gtk_widget_set_sensitive (impl->browse_new_folder_button, TRUE); 1020-
1144
1145- do 1021- do
1146+ if (impl->edited_new_text) /* not cancelled? */ 1022- {
1147 {
1148- gpointer data; 1023- gpointer data;
1149- ShortcutType shortcut_type; 1024- ShortcutType shortcut_type;
1150- gboolean pixbuf_visible; 1025- gboolean pixbuf_visible;
@@ -1155,38 +1030,17 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
1155- SHORTCUTS_COL_TYPE, &shortcut_type, 1030- SHORTCUTS_COL_TYPE, &shortcut_type,
1156- SHORTCUTS_COL_PIXBUF_VISIBLE, &pixbuf_visible, 1031- SHORTCUTS_COL_PIXBUF_VISIBLE, &pixbuf_visible,
1157- -1); 1032- -1);
1158+ GError *error; 1033-
1159+ GtkFilePath *file_path;
1160
1161- pixbuf = NULL; 1034- pixbuf = NULL;
1162- if (pixbuf_visible) 1035- if (pixbuf_visible)
1163- { 1036- {
1164- if (shortcut_type == SHORTCUT_TYPE_VOLUME) 1037- if (shortcut_type == SHORTCUT_TYPE_VOLUME)
1165- { 1038- {
1166- GtkFileSystemVolume *volume; 1039- GtkFileSystemVolume *volume;
1167+ error = NULL; 1040-
1168+ file_path = gtk_file_system_make_path (impl->file_system,
1169+ impl->current_folder,
1170+ impl->edited_new_text,
1171+ &error);
1172+ if (file_path)
1173+ {
1174+ GtkFileSystemHandle *handle;
1175
1176- volume = data; 1041- volume = data;
1177- pixbuf = gtk_file_system_volume_render_icon (impl->file_system, volume, GTK_WIDGET (impl), 1042- pixbuf = gtk_file_system_volume_render_icon (impl->file_system, volume, GTK_WIDGET (impl),
1178- impl->icon_size, NULL); 1043- impl->icon_size, NULL);
1179-
1180- gtk_list_store_set (impl->shortcuts_model, &iter,
1181- SHORTCUTS_COL_PIXBUF, pixbuf,
1182- -1);
1183+ handle = gtk_file_system_create_folder (impl->file_system, file_path,
1184+ edited_idle_create_folder_cb,
1185+ g_object_ref (impl));
1186+ impl->pending_handles = g_slist_append (impl->pending_handles, handle);
1187
1188- if (pixbuf)
1189- g_object_unref (pixbuf);
1190- } 1044- }
1191- else if (shortcut_type == SHORTCUT_TYPE_PATH) 1045- else if (shortcut_type == SHORTCUT_TYPE_PATH)
1192- { 1046- {
@@ -1223,13 +1077,6 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
1223- icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (GTK_WIDGET (impl))); 1077- icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (GTK_WIDGET (impl)));
1224- pixbuf = gtk_icon_theme_load_icon (icon_theme, "gnome-fs-share", 1078- pixbuf = gtk_icon_theme_load_icon (icon_theme, "gnome-fs-share",
1225- impl->icon_size, 0, NULL); 1079- impl->icon_size, 0, NULL);
1226-
1227- gtk_list_store_set (impl->shortcuts_model, &iter,
1228- SHORTCUTS_COL_PIXBUF, pixbuf,
1229- -1);
1230-
1231- if (pixbuf)
1232- g_object_unref (pixbuf);
1233- } 1080- }
1234- } 1081- }
1235- else if (shortcut_type == SHORTCUT_TYPE_SEARCH) 1082- else if (shortcut_type == SHORTCUT_TYPE_SEARCH)
@@ -1240,87 +1087,59 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
1240- { 1087- {
1241- pixbuf = render_recent_icon (impl); 1088- pixbuf = render_recent_icon (impl);
1242- } 1089- }
1243+ gtk_file_path_free (file_path); 1090-
1244 } 1091- gtk_list_store_set (impl->shortcuts_model, &iter,
1245+ else 1092- SHORTCUTS_COL_PIXBUF, pixbuf,
1246+ error_creating_folder_dialog (impl, file_path, error); 1093- -1);
1247+ 1094-
1248+ g_free (impl->edited_new_text); 1095- if (pixbuf)
1249+ impl->edited_new_text = NULL; 1096- g_object_unref (pixbuf);
1250 } 1097-
1098- }
1099- }
1251- while (gtk_tree_model_iter_next (GTK_TREE_MODEL (impl->shortcuts_model),&iter)); 1100- while (gtk_tree_model_iter_next (GTK_TREE_MODEL (impl->shortcuts_model),&iter));
1252 1101-
1253- out: 1102- out:
1254+ GDK_THREADS_LEAVE (); 1103-
1255
1256- profile_end ("end", NULL); 1104- profile_end ("end", NULL);
1257+ return FALSE; 1105-}
1258 } 1106-
1259
1260-static void 1107-static void
1261-shortcuts_find_folder (GtkFileChooserDefault *impl, 1108-shortcuts_find_folder (GtkFileChooserDefault *impl,
1262- GtkFilePath *folder) 1109- GtkFilePath *folder)
1263+static void 1110-{
1264+queue_edited_idle (GtkFileChooserDefault *impl,
1265+ const gchar *new_text)
1266 {
1267- GtkTreeSelection *selection; 1111- GtkTreeSelection *selection;
1268- int pos; 1112- int pos;
1269- GtkTreePath *path; 1113- GtkTreePath *path;
1270- 1114-
1271- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_shortcuts_tree_view)); 1115- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_shortcuts_tree_view));
1272+ /* We create the folder in an idle handler so that we don't modify the tree 1116-
1273+ * just now.
1274+ */
1275
1276- g_assert (folder != NULL); 1117- g_assert (folder != NULL);
1277- pos = shortcut_find_position (impl, folder); 1118- pos = shortcut_find_position (impl, folder);
1278- if (pos == -1) 1119- if (pos == -1)
1279+ if (!impl->edited_idle) 1120- {
1280 {
1281- gtk_tree_selection_unselect_all (selection); 1121- gtk_tree_selection_unselect_all (selection);
1282- return; 1122- return;
1283+ impl->edited_idle = g_idle_source_new (); 1123- }
1284+ g_source_set_closure (impl->edited_idle, 1124-
1285+ g_cclosure_new_object (G_CALLBACK (edited_idle_cb),
1286+ G_OBJECT (impl)));
1287+ g_source_attach (impl->edited_idle, NULL);
1288 }
1289
1290- path = gtk_tree_path_new_from_indices (pos, -1); 1125- path = gtk_tree_path_new_from_indices (pos, -1);
1291- gtk_tree_selection_select_path (selection, path); 1126- gtk_tree_selection_select_path (selection, path);
1292- gtk_tree_path_free (path); 1127- gtk_tree_path_free (path);
1293+ g_free (impl->edited_new_text); 1128-}
1294+ impl->edited_new_text = g_strdup (new_text); 1129-
1295 }
1296
1297-/* If a shortcut corresponds to the current folder, selects it */ 1130-/* If a shortcut corresponds to the current folder, selects it */
1298+/* Callback used from the text cell renderer when the new folder is named */ 1131-static void
1299 static void
1300-shortcuts_find_current_folder (GtkFileChooserDefault *impl) 1132-shortcuts_find_current_folder (GtkFileChooserDefault *impl)
1301+renderer_edited_cb (GtkCellRendererText *cell_renderer_text, 1133-{
1302+ const gchar *path,
1303+ const gchar *new_text,
1304+ GtkFileChooserDefault *impl)
1305 {
1306- shortcuts_find_folder (impl, impl->current_folder); 1134- shortcuts_find_folder (impl, impl->current_folder);
1307+ /* work around bug #154921 */ 1135-}
1308+ g_object_set (cell_renderer_text, 1136-
1309+ "mode", GTK_CELL_RENDERER_MODE_INERT, NULL);
1310+ queue_edited_idle (impl, new_text);
1311 }
1312
1313-/* Removes the specified number of rows from the shortcuts list */ 1137-/* Removes the specified number of rows from the shortcuts list */
1314+/* Callback used from the text cell renderer when the new folder edition gets 1138-static void
1315+ * canceled.
1316+ */
1317 static void
1318-shortcuts_remove_rows (GtkFileChooserDefault *impl, 1139-shortcuts_remove_rows (GtkFileChooserDefault *impl,
1319- int start_row, 1140- int start_row,
1320- int n_rows) 1141- int n_rows)
1321+renderer_editing_canceled_cb (GtkCellRendererText *cell_renderer_text, 1142-{
1322+ GtkFileChooserDefault *impl)
1323 {
1324- GtkTreePath *path; 1143- GtkTreePath *path;
1325- 1144-
1326- path = gtk_tree_path_new_from_indices (start_row, -1); 1145- path = gtk_tree_path_new_from_indices (start_row, -1);
@@ -1331,27 +1150,14 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
1331- 1150-
1332- if (!gtk_tree_model_get_iter (GTK_TREE_MODEL (impl->shortcuts_model), &iter, path)) 1151- if (!gtk_tree_model_get_iter (GTK_TREE_MODEL (impl->shortcuts_model), &iter, path))
1333- g_assert_not_reached (); 1152- g_assert_not_reached ();
1334+ /* work around bug #154921 */ 1153-
1335+ g_object_set (cell_renderer_text,
1336+ "mode", GTK_CELL_RENDERER_MODE_INERT, NULL);
1337+ queue_edited_idle (impl, NULL);
1338+}
1339
1340- shortcuts_free_row_data (impl, &iter); 1154- shortcuts_free_row_data (impl, &iter);
1341- gtk_list_store_remove (impl->shortcuts_model, &iter); 1155- gtk_list_store_remove (impl->shortcuts_model, &iter);
1342- } 1156- }
1343+/* Creates the widgets for the filter combo box */ 1157-
1344+static GtkWidget *
1345+filter_create (GtkFileChooserDefault *impl)
1346+{
1347+ impl->filter_combo = gtk_combo_box_new_text ();
1348+ gtk_combo_box_set_focus_on_click (GTK_COMBO_BOX (impl->filter_combo), FALSE);
1349
1350- gtk_tree_path_free (path); 1158- gtk_tree_path_free (path);
1351-} 1159-}
1352+ g_signal_connect (impl->filter_combo, "changed", 1160-
1353+ G_CALLBACK (filter_combo_changed), impl);
1354
1355-static void 1161-static void
1356-shortcuts_update_count (GtkFileChooserDefault *impl, 1162-shortcuts_update_count (GtkFileChooserDefault *impl,
1357- ShortcutsIndex type, 1163- ShortcutsIndex type,
@@ -1396,13 +1202,11 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
1396- /* nothing */ 1202- /* nothing */
1397- break; 1203- break;
1398- } 1204- }
1399+ return impl->filter_combo; 1205-}
1400 } 1206-
1401
1402-struct ShortcutsInsertRequest 1207-struct ShortcutsInsertRequest
1403-{ 1208-{
1404+struct selection_check_closure { 1209- GtkFileChooserDefault *impl;
1405 GtkFileChooserDefault *impl;
1406- GtkFilePath *parent_path; 1210- GtkFilePath *parent_path;
1407- GtkFilePath *path; 1211- GtkFilePath *path;
1408- int pos; 1212- int pos;
@@ -1411,22 +1215,14 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
1411- ShortcutsIndex type; 1215- ShortcutsIndex type;
1412- gboolean name_only; 1216- gboolean name_only;
1413- gboolean removable; 1217- gboolean removable;
1414+ int num_selected; 1218-};
1415+ gboolean all_files; 1219-
1416+ gboolean all_folders; 1220-static void
1417 };
1418
1419+/* Used from gtk_tree_selection_selected_foreach() */
1420 static void
1421-get_file_info_finished (GtkFileSystemHandle *handle, 1221-get_file_info_finished (GtkFileSystemHandle *handle,
1422- const GtkFileInfo *info, 1222- const GtkFileInfo *info,
1423- const GError *error, 1223- const GError *error,
1424- gpointer data) 1224- gpointer data)
1425+selection_check_foreach_cb (GtkTreeModel *model, 1225-{
1426+ GtkTreePath *path,
1427+ GtkTreeIter *iter,
1428+ gpointer data)
1429 {
1430- gint pos = -1; 1226- gint pos = -1;
1431- gboolean cancelled = handle->cancelled; 1227- gboolean cancelled = handle->cancelled;
1432- GdkPixbuf *pixbuf; 1228- GdkPixbuf *pixbuf;
@@ -1451,37 +1247,25 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
1451- -1); 1247- -1);
1452- if (handle != model_handle) 1248- if (handle != model_handle)
1453- goto out; 1249- goto out;
1454+ struct selection_check_closure *closure; 1250-
1455+ GtkTreeIter child_iter;
1456+ const GtkFileInfo *info;
1457+ gboolean is_folder;
1458
1459- /* set the handle to NULL in the model (we unref later on) */ 1251- /* set the handle to NULL in the model (we unref later on) */
1460- gtk_list_store_set (request->impl->shortcuts_model, &iter, 1252- gtk_list_store_set (request->impl->shortcuts_model, &iter,
1461- SHORTCUTS_COL_HANDLE, NULL, 1253- SHORTCUTS_COL_HANDLE, NULL,
1462- -1); 1254- -1);
1463+ closure = data; 1255-
1464+ closure->num_selected++;
1465
1466- if (cancelled) 1256- if (cancelled)
1467- goto out; 1257- goto out;
1468+ gtk_tree_model_sort_convert_iter_to_child_iter (closure->impl->sort_model, &child_iter, iter); 1258-
1469
1470- if (!info) 1259- if (!info)
1471- { 1260- {
1472- gtk_list_store_remove (request->impl->shortcuts_model, &iter); 1261- gtk_list_store_remove (request->impl->shortcuts_model, &iter);
1473- shortcuts_update_count (request->impl, request->type, -1); 1262- shortcuts_update_count (request->impl, request->type, -1);
1474+ info = _gtk_file_system_model_get_info (closure->impl->browse_files_model, &child_iter); 1263-
1475+ is_folder = info ? gtk_file_info_get_is_folder (info) : FALSE;
1476
1477- if (request->type == SHORTCUTS_HOME) 1264- if (request->type == SHORTCUTS_HOME)
1478- { 1265- {
1479- const char *home = g_get_home_dir (); 1266- const char *home = g_get_home_dir ();
1480- GtkFilePath *home_path; 1267- GtkFilePath *home_path;
1481+ closure->all_folders = closure->all_folders && is_folder; 1268-
1482+ closure->all_files = closure->all_files && !is_folder;
1483+}
1484
1485- home_path = gtk_file_system_filename_to_path (request->impl->file_system, home); 1269- home_path = gtk_file_system_filename_to_path (request->impl->file_system, home);
1486- error_getting_info_dialog (request->impl, home_path, g_error_copy (error)); 1270- error_getting_info_dialog (request->impl, home_path, g_error_copy (error));
1487- gtk_file_path_free (home_path); 1271- gtk_file_path_free (home_path);
@@ -1492,16 +1276,7 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
1492- gint separator_pos = shortcuts_get_index (request->impl, SHORTCUTS_CURRENT_FOLDER_SEPARATOR); 1276- gint separator_pos = shortcuts_get_index (request->impl, SHORTCUTS_CURRENT_FOLDER_SEPARATOR);
1493- shortcuts_remove_rows (request->impl, separator_pos, 1); 1277- shortcuts_remove_rows (request->impl, separator_pos, 1);
1494- } 1278- }
1495+/* Checks whether the selected items in the file list are all files or all folders */ 1279-
1496+static void
1497+selection_check (GtkFileChooserDefault *impl,
1498+ gint *num_selected,
1499+ gboolean *all_files,
1500+ gboolean *all_folders)
1501+{
1502+ struct selection_check_closure closure;
1503+ GtkTreeSelection *selection;
1504
1505- goto out; 1280- goto out;
1506- } 1281- }
1507- 1282-
@@ -1537,30 +1312,19 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
1537- 1312-
1538- if (request->impl->has_search) 1313- if (request->impl->has_search)
1539- pos -= 1; 1314- pos -= 1;
1540+ closure.impl = impl; 1315-
1541+ closure.num_selected = 0;
1542+ closure.all_files = TRUE;
1543+ closure.all_folders = TRUE;
1544
1545- if (request->impl->has_recent) 1316- if (request->impl->has_recent)
1546- pos -= 2; 1317- pos -= 2;
1547+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_files_tree_view)); 1318-
1548+ gtk_tree_selection_selected_foreach (selection,
1549+ selection_check_foreach_cb,
1550+ &closure);
1551
1552- gtk_combo_box_set_active (GTK_COMBO_BOX (request->impl->save_folder_combo), pos); 1319- gtk_combo_box_set_active (GTK_COMBO_BOX (request->impl->save_folder_combo), pos);
1553- g_signal_handlers_unblock_by_func (request->impl->save_folder_combo, 1320- g_signal_handlers_unblock_by_func (request->impl->save_folder_combo,
1554- G_CALLBACK (save_folder_combo_changed_cb), 1321- G_CALLBACK (save_folder_combo_changed_cb),
1555- request->impl); 1322- request->impl);
1556- } 1323- }
1557+ g_assert (closure.num_selected == 0 || !(closure.all_files && closure.all_folders)); 1324-
1558
1559- if (pixbuf) 1325- if (pixbuf)
1560- g_object_unref (pixbuf); 1326- g_object_unref (pixbuf);
1561+ if (num_selected) 1327-
1562+ *num_selected = closure.num_selected;
1563
1564-out: 1328-out:
1565- g_object_unref (request->impl); 1329- g_object_unref (request->impl);
1566- gtk_file_path_free (request->parent_path); 1330- gtk_file_path_free (request->parent_path);
@@ -1568,86 +1332,57 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
1568- gtk_tree_row_reference_free (request->row_ref); 1332- gtk_tree_row_reference_free (request->row_ref);
1569- g_free (request->label_copy); 1333- g_free (request->label_copy);
1570- g_free (request); 1334- g_free (request);
1571+ if (all_files) 1335-
1572+ *all_files = closure.all_files;
1573
1574- g_object_unref (handle); 1336- g_object_unref (handle);
1575+ if (all_folders) 1337-}
1576+ *all_folders = closure.all_folders; 1338-
1577 } 1339 /* FIXME: GtkFileSystem needs a function to split a remote path
1578
1579-/* FIXME: GtkFileSystem needs a function to split a remote path
1580- * into hostname and path components, or maybe just have a 1340- * into hostname and path components, or maybe just have a
1581- * gtk_file_system_path_get_display_name(). 1341+ * into hostname and path components, or maybe just have a
1582- * 1342 * gtk_file_system_path_get_display_name().
1583- * This function is also used in gtkfilechooserbutton.c 1343 *
1584+struct get_selected_path_closure { 1344 * This function is also used in gtkfilechooserbutton.c
1585+ GtkFileChooserDefault *impl; 1345@@ -1692,11 +887,11 @@
1586+ const GtkFilePath *path;
1587+};
1588+
1589+/* Handles key press events on the file list, so that we can trap Enter to
1590+ * activate the default button on our own. Also, checks to see if '/' has been
1591+ * pressed. See comment by tree_view_keybinding_cb() for more details.
1592 */
1593-gchar *
1594-_gtk_file_chooser_label_for_uri (const gchar *uri)
1595+static gboolean
1596+trap_activate_cb (GtkWidget *widget,
1597+ GdkEventKey *event,
1598+ gpointer data)
1599 { 1346 {
1600- const gchar *path, *start, *end, *p; 1347 const gchar *path, *start, *end, *p;
1601- gchar *host, *label; 1348 gchar *host, *label;
1602- 1349-
1603- start = strstr (uri, "://"); 1350+
1604- start += 3; 1351 start = strstr (uri, "://");
1605- path = strchr (start, '/'); 1352 start += 3;
1353 path = strchr (start, '/');
1606- 1354-
1607- if (path) 1355+
1608- end = path; 1356 if (path)
1609- else 1357 end = path;
1610- { 1358 else
1611- end = uri + strlen (uri); 1359@@ -1711,719 +906,25 @@
1612- path = "/"; 1360 {
1613- } 1361 start = p + 1;
1614+ GtkFileChooserDefault *impl; 1362 }
1615+ int modifiers;
1616
1617- /* strip username */
1618- p = strchr (start, '@');
1619- if (p && p < end)
1620- {
1621- start = p + 1;
1622- }
1623- 1363-
1624- p = strchr (start, ':'); 1364+
1625- if (p && p < end) 1365 p = strchr (start, ':');
1626- end = p; 1366 if (p && p < end)
1367 end = p;
1627- 1368-
1628- host = g_strndup (start, end - start); 1369+
1629+ impl = (GtkFileChooserDefault *) data; 1370 host = g_strndup (start, end - start);
1630 1371
1631- /* Translators: the first string is a path and the second string 1372- /* Translators: the first string is a path and the second string
1632- * is a hostname. Nautilus and the panel contain the same string 1373- * is a hostname. Nautilus and the panel contain the same string
1633- * to translate. 1374- * to translate.
1634- */ 1375+ /* Translators: the first string is a path and the second string
1635- label = g_strdup_printf (_("%1$s on %2$s"), path, host); 1376+ * is a hostname. Nautilus and the panel contain the same string
1377+ * to translate.
1378 */
1379 label = g_strdup_printf (_("%1$s on %2$s"), path, host);
1636- 1380-
1637- g_free (host); 1381+
1638+ modifiers = gtk_accelerator_get_default_mod_mask (); 1382 g_free (host);
1639 1383
1640- return label; 1384 return label;
1641-} 1385 }
1642+ if ((event->keyval == GDK_Return
1643+ || event->keyval == GDK_ISO_Enter
1644+ || event->keyval == GDK_KP_Enter
1645+ || event->keyval == GDK_space)
1646+ && ((event->state & modifiers) == 0)
1647+ && !(impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER ||
1648+ impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER))
1649+ {
1650+ GtkWindow *window;
1651 1386
1652-/* Inserts a path in the shortcuts tree, making a copy of it; alternatively, 1387-/* Inserts a path in the shortcuts tree, making a copy of it; alternatively,
1653- * inserts a volume. A position of -1 indicates the end of the tree. 1388- * 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
1667- gpointer data = NULL; 1402- gpointer data = NULL;
1668- GtkTreeIter iter; 1403- GtkTreeIter iter;
1669- GtkIconTheme *icon_theme; 1404- GtkIconTheme *icon_theme;
1670+ window = get_toplevel (widget);
1671+ if (window
1672+ && widget != window->default_widget
1673+ && !(widget == window->focus_widget &&
1674+ (!window->default_widget || !GTK_WIDGET_SENSITIVE (window->default_widget))))
1675+ {
1676+ gtk_window_activate_default (window);
1677+ return TRUE;
1678+ }
1679+ }
1680+
1681+ return FALSE;
1682+}
1683 1405
1684- profile_start ("start", (shortcut_type == SHORTCUT_TYPE_VOLUME) ? "volume" 1406- profile_start ("start", (shortcut_type == SHORTCUT_TYPE_VOLUME) ? "volume"
1685- : ((shortcut_type == SHORTCUT_TYPE_PATH) ? (char *) path : NULL)); 1407- : ((shortcut_type == SHORTCUT_TYPE_PATH) ? (char *) path : NULL));
1686+static gboolean 1408-
1687+list_button_press (GtkWidget *widget, GdkEventButton *event, gpointer data)
1688+{
1689+ GtkTreeView * tree = GTK_TREE_VIEW (widget);
1690+ GtkFileChooserDefault *impl = data;
1691+ GtkTreePath *path;
1692
1693- if (shortcut_type == SHORTCUT_TYPE_VOLUME) 1409- if (shortcut_type == SHORTCUT_TYPE_VOLUME)
1694+ if (event->type != GDK_BUTTON_PRESS || 1410- {
1695+ !gtk_tree_view_get_path_at_pos (tree, (gint)event->x, (gint)event->y,
1696+ &path, NULL, NULL, NULL))
1697 {
1698- data = volume; 1411- data = volume;
1699- label_copy = gtk_file_system_volume_get_display_name (impl->file_system, volume); 1412- label_copy = gtk_file_system_volume_get_display_name (impl->file_system, volume);
1700- pixbuf = gtk_file_system_volume_render_icon (impl->file_system, volume, GTK_WIDGET (impl), 1413- pixbuf = gtk_file_system_volume_render_icon (impl->file_system, volume, GTK_WIDGET (impl),
1701- impl->icon_size, NULL); 1414- impl->icon_size, NULL);
1702+ return FALSE; 1415- }
1703 }
1704- else if (shortcut_type == SHORTCUT_TYPE_PATH) 1416- else if (shortcut_type == SHORTCUT_TYPE_PATH)
1705- { 1417- {
1706- if (gtk_file_system_path_is_local (impl->file_system, path)) 1418- if (gtk_file_system_path_is_local (impl->file_system, path))
@@ -1737,7 +1449,7 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
1737- SHORTCUTS_COL_TYPE, SHORTCUT_TYPE_PATH, 1449- SHORTCUTS_COL_TYPE, SHORTCUT_TYPE_PATH,
1738- SHORTCUTS_COL_HANDLE, handle, 1450- SHORTCUTS_COL_HANDLE, handle,
1739- -1); 1451- -1);
1740 1452-
1741- shortcuts_update_count (impl, type, 1); 1453- shortcuts_update_count (impl, type, 1);
1742- 1454-
1743- return; 1455- return;
@@ -1753,22 +1465,11 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
1753- else 1465- else
1754- { 1466- {
1755- gchar *uri; 1467- gchar *uri;
1756+ impl->list_press_time = event->time; 1468-
1757+ impl->list_press_path = path;
1758
1759- uri = gtk_file_system_path_to_uri (impl->file_system, path); 1469- uri = gtk_file_system_path_to_uri (impl->file_system, path);
1760+ return FALSE; 1470-
1761+}
1762
1763- label_copy = _gtk_file_chooser_label_for_uri (uri); 1471- label_copy = _gtk_file_chooser_label_for_uri (uri);
1764+static gboolean 1472-
1765+list_button_release (GtkWidget *widget, GdkEventButton *event, gpointer data)
1766+{
1767+ GtkTreeView * tree = GTK_TREE_VIEW (widget);
1768+ GtkFileChooserDefault *impl = data;
1769+ GtkTreePath *path = NULL;
1770+ gboolean retval = FALSE;
1771
1772- g_free (uri); 1473- g_free (uri);
1773- } 1474- }
1774- 1475-
@@ -1781,35 +1482,19 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
1781- } 1482- }
1782- } 1483- }
1783- else 1484- else
1784+ if (!impl->list_press_time || 1485- {
1785+ !impl->list_press_path ||
1786+ event->type != GDK_BUTTON_RELEASE ||
1787+ !gtk_tree_view_get_path_at_pos (tree, (gint)event->x, (gint)event->y,
1788+ &path, NULL, NULL, NULL))
1789 {
1790- g_assert_not_reached (); 1486- g_assert_not_reached ();
1791+ goto done; 1487-
1792+ }
1793
1794- return; 1488- return;
1795+ if (event->time - impl->list_press_time > LONG_CLICK_LENGTH && 1489- }
1796+ !gtk_tree_path_compare (impl->list_press_path, path)) 1490-
1797+ {
1798+ retval = TRUE;
1799+ list_row_activated (tree, path, NULL, impl);
1800 }
1801
1802- if (pos == -1) 1491- if (pos == -1)
1803- gtk_list_store_append (impl->shortcuts_model, &iter); 1492- gtk_list_store_append (impl->shortcuts_model, &iter);
1804- else 1493- else
1805- gtk_list_store_insert (impl->shortcuts_model, &iter, pos); 1494- gtk_list_store_insert (impl->shortcuts_model, &iter, pos);
1806+ done: 1495-
1807+ if (path)
1808+ gtk_tree_path_free (path);
1809
1810- shortcuts_update_count (impl, type, 1); 1496- shortcuts_update_count (impl, type, 1);
1811+ impl->list_press_time = 0; 1497-
1812
1813- gtk_list_store_set (impl->shortcuts_model, &iter, 1498- gtk_list_store_set (impl->shortcuts_model, &iter,
1814- SHORTCUTS_COL_PIXBUF, pixbuf, 1499- SHORTCUTS_COL_PIXBUF, pixbuf,
1815- SHORTCUTS_COL_PIXBUF_VISIBLE, TRUE, 1500- SHORTCUTS_COL_PIXBUF_VISIBLE, TRUE,
@@ -1833,17 +1518,10 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
1833- * again. 1518- * again.
1834- */ 1519- */
1835- gint combo_pos = shortcuts_get_index (impl, SHORTCUTS_CURRENT_FOLDER); 1520- gint combo_pos = shortcuts_get_index (impl, SHORTCUTS_CURRENT_FOLDER);
1836+ if (impl->list_press_path) 1521-
1837+ {
1838+ gtk_tree_path_free (impl->list_press_path);
1839+ impl->list_press_path = NULL;
1840+ }
1841
1842- if (impl->has_search) 1522- if (impl->has_search)
1843- combo_pos -= 1; 1523- combo_pos -= 1;
1844+ return FALSE; 1524-
1845+}
1846
1847- if (impl->has_recent) 1525- if (impl->has_recent)
1848- combo_pos -= 2; 1526- combo_pos -= 2;
1849- 1527-
@@ -1856,44 +1534,23 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
1856- G_CALLBACK (save_folder_combo_changed_cb), 1534- G_CALLBACK (save_folder_combo_changed_cb),
1857- impl); 1535- impl);
1858- } 1536- }
1859 1537-
1860- g_free (label_copy); 1538- g_free (label_copy);
1861+/* Creates the widgets for the file list */ 1539-
1862+static GtkWidget *
1863+create_file_list (GtkFileChooserDefault *impl)
1864+{
1865+ GtkWidget *swin;
1866+ GtkTreeSelection *selection;
1867+ GtkTreeViewColumn *column;
1868+ GtkCellRenderer *renderer;
1869
1870- if (pixbuf) 1540- if (pixbuf)
1871- g_object_unref (pixbuf); 1541- g_object_unref (pixbuf);
1872+ /* Scrolled window */ 1542-
1873
1874- profile_end ("end", NULL); 1543- profile_end ("end", NULL);
1875-} 1544-}
1876+ swin = gtk_scrolled_window_new (NULL, NULL); 1545-
1877+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (swin),
1878+ GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
1879+ gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (swin),
1880+ GTK_SHADOW_IN);
1881
1882-static void 1546-static void
1883-shortcuts_append_search (GtkFileChooserDefault *impl) 1547-shortcuts_append_search (GtkFileChooserDefault *impl)
1884-{ 1548-{
1885- GdkPixbuf *pixbuf; 1549- GdkPixbuf *pixbuf;
1886- GtkTreeIter iter; 1550- GtkTreeIter iter;
1887+ /* Tree/list view */ 1551-
1888
1889- pixbuf = render_search_icon (impl); 1552- pixbuf = render_search_icon (impl);
1890+ impl->browse_files_tree_view = gtk_tree_view_new (); 1553-
1891+#ifdef PROFILE_FILE_CHOOSER
1892+ g_object_set_data (G_OBJECT (impl->browse_files_tree_view), "fmq-name", "file_list");
1893+#endif
1894+ g_object_set_data (G_OBJECT (impl->browse_files_tree_view), I_("GtkFileChooserDefault"), impl);
1895+ atk_object_set_name (gtk_widget_get_accessible (impl->browse_files_tree_view), _("Files"));
1896
1897- gtk_list_store_append (impl->shortcuts_model, &iter); 1554- gtk_list_store_append (impl->shortcuts_model, &iter);
1898- gtk_list_store_set (impl->shortcuts_model, &iter, 1555- gtk_list_store_set (impl->shortcuts_model, &iter,
1899- SHORTCUTS_COL_PIXBUF, pixbuf, 1556- SHORTCUTS_COL_PIXBUF, pixbuf,
@@ -1903,38 +1560,21 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
1903- SHORTCUTS_COL_TYPE, SHORTCUT_TYPE_SEARCH, 1560- SHORTCUTS_COL_TYPE, SHORTCUT_TYPE_SEARCH,
1904- SHORTCUTS_COL_REMOVABLE, FALSE, 1561- SHORTCUTS_COL_REMOVABLE, FALSE,
1905- -1); 1562- -1);
1906+ gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (impl->browse_files_tree_view), TRUE); 1563-
1907+ gtk_container_add (GTK_CONTAINER (swin), impl->browse_files_tree_view);
1908
1909- if (pixbuf) 1564- if (pixbuf)
1910- g_object_unref (pixbuf); 1565- g_object_unref (pixbuf);
1911+ g_signal_connect (impl->browse_files_tree_view, "row_activated", 1566-
1912+ G_CALLBACK (list_row_activated), impl);
1913+ g_signal_connect (impl->browse_files_tree_view, "key_press_event",
1914+ G_CALLBACK (trap_activate_cb), impl);
1915+ g_signal_connect (impl->browse_files_tree_view, "button_press_event",
1916+ G_CALLBACK (list_button_press), impl);
1917+ g_signal_connect (impl->browse_files_tree_view, "button_release_event",
1918+ G_CALLBACK (list_button_release), impl);
1919
1920- impl->has_search = TRUE; 1567- impl->has_search = TRUE;
1921-} 1568-}
1922+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_files_tree_view)); 1569-
1923+ gtk_tree_selection_set_select_function (selection,
1924+ list_select_func,
1925+ impl, NULL);
1926
1927-static void 1570-static void
1928-shortcuts_append_recent (GtkFileChooserDefault *impl) 1571-shortcuts_append_recent (GtkFileChooserDefault *impl)
1929-{ 1572-{
1930- GdkPixbuf *pixbuf; 1573- GdkPixbuf *pixbuf;
1931- GtkTreeIter iter; 1574- GtkTreeIter iter;
1932+ g_signal_connect (selection, "changed", 1575-
1933+ G_CALLBACK (list_selection_changed), impl);
1934
1935- pixbuf = render_recent_icon (impl); 1576- pixbuf = render_recent_icon (impl);
1936+ /* Filename column */ 1577-
1937
1938- gtk_list_store_append (impl->shortcuts_model, &iter); 1578- gtk_list_store_append (impl->shortcuts_model, &iter);
1939- gtk_list_store_set (impl->shortcuts_model, &iter, 1579- gtk_list_store_set (impl->shortcuts_model, &iter,
1940- SHORTCUTS_COL_PIXBUF, pixbuf, 1580- SHORTCUTS_COL_PIXBUF, pixbuf,
@@ -1947,85 +1587,40 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
1947- 1587-
1948- if (pixbuf) 1588- if (pixbuf)
1949- g_object_unref (pixbuf); 1589- g_object_unref (pixbuf);
1950+ impl->list_name_column = gtk_tree_view_column_new (); 1590-
1951+ gtk_tree_view_column_set_expand (impl->list_name_column, TRUE);
1952+ gtk_tree_view_column_set_resizable (impl->list_name_column, TRUE);
1953+ gtk_tree_view_column_set_title (impl->list_name_column, _("Name"));
1954+ gtk_tree_view_column_set_sort_column_id (impl->list_name_column, FILE_LIST_COL_NAME);
1955
1956- impl->has_recent = TRUE; 1591- impl->has_recent = TRUE;
1957-} 1592-}
1958+ renderer = gtk_cell_renderer_pixbuf_new (); 1593-
1959+ gtk_tree_view_column_pack_start (impl->list_name_column, renderer, FALSE);
1960+ gtk_tree_view_column_set_cell_data_func (impl->list_name_column, renderer,
1961+ list_icon_data_func, impl, NULL);
1962
1963-/* Appends an item for the user's home directory to the shortcuts model */ 1594-/* Appends an item for the user's home directory to the shortcuts model */
1964-static void 1595-static void
1965-shortcuts_append_home (GtkFileChooserDefault *impl) 1596-shortcuts_append_home (GtkFileChooserDefault *impl)
1966-{ 1597-{
1967- const char *home; 1598- const char *home;
1968- GtkFilePath *home_path; 1599- GtkFilePath *home_path;
1969+ impl->list_name_renderer = gtk_cell_renderer_text_new (); 1600-
1970+ g_object_set (impl->list_name_renderer,
1971+ "ellipsize", PANGO_ELLIPSIZE_END,
1972+ NULL);
1973+ g_signal_connect (impl->list_name_renderer, "edited",
1974+ G_CALLBACK (renderer_edited_cb), impl);
1975+ g_signal_connect (impl->list_name_renderer, "editing_canceled",
1976+ G_CALLBACK (renderer_editing_canceled_cb), impl);
1977+ gtk_tree_view_column_pack_start (impl->list_name_column, impl->list_name_renderer, TRUE);
1978+ gtk_tree_view_column_set_cell_data_func (impl->list_name_column, impl->list_name_renderer,
1979+ list_name_data_func, impl, NULL);
1980
1981- profile_start ("start", NULL); 1601- profile_start ("start", NULL);
1982+ gtk_tree_view_append_column (GTK_TREE_VIEW (impl->browse_files_tree_view), impl->list_name_column); 1602-
1983+#if 0
1984+ /* Size column */
1985
1986- home = g_get_home_dir (); 1603- home = g_get_home_dir ();
1987- if (home == NULL) 1604- if (home == NULL)
1988- { 1605- {
1989- profile_end ("end - no home directory!?", NULL); 1606- profile_end ("end - no home directory!?", NULL);
1990- return; 1607- return;
1991- } 1608- }
1992+ column = gtk_tree_view_column_new (); 1609-
1993+ gtk_tree_view_column_set_title (column, _("Size"));
1994
1995- home_path = gtk_file_system_filename_to_path (impl->file_system, home); 1610- home_path = gtk_file_system_filename_to_path (impl->file_system, home);
1996+ renderer = gtk_cell_renderer_text_new (); 1611-
1997+ gtk_tree_view_column_pack_start (column, renderer, TRUE); /* bug: it doesn't expand */
1998+ gtk_tree_view_column_set_cell_data_func (column, renderer,
1999+ list_size_data_func, impl, NULL);
2000+ gtk_tree_view_column_set_sort_column_id (column, FILE_LIST_COL_SIZE);
2001+ gtk_tree_view_append_column (GTK_TREE_VIEW (impl->browse_files_tree_view), column);
2002+#endif
2003+ /* Modification time column */
2004
2005- shortcuts_insert_path (impl, -1, SHORTCUT_TYPE_PATH, NULL, home_path, NULL, FALSE, SHORTCUTS_HOME); 1612- shortcuts_insert_path (impl, -1, SHORTCUT_TYPE_PATH, NULL, home_path, NULL, FALSE, SHORTCUTS_HOME);
2006- impl->has_home = TRUE; 1613- impl->has_home = TRUE;
2007+ column = gtk_tree_view_column_new (); 1614-
2008+ gtk_tree_view_column_set_resizable (column, TRUE);
2009+ gtk_tree_view_column_set_title (column, _("Modified"));
2010
2011- gtk_file_path_free (home_path); 1615- gtk_file_path_free (home_path);
2012+ renderer = gtk_cell_renderer_text_new (); 1616-
2013+ gtk_tree_view_column_pack_start (column, renderer, TRUE);
2014+ gtk_tree_view_column_set_cell_data_func (column, renderer,
2015+ list_mtime_data_func, impl, NULL);
2016+ gtk_tree_view_column_set_sort_column_id (column, FILE_LIST_COL_MTIME);
2017+ gtk_tree_view_append_column (GTK_TREE_VIEW (impl->browse_files_tree_view), column);
2018+ gtk_widget_show_all (swin);
2019
2020- profile_end ("end", NULL); 1617- profile_end ("end", NULL);
2021+ return swin; 1618-}
2022 } 1619-
2023
2024-/* Appends the ~/Desktop directory to the shortcuts model */ 1620-/* Appends the ~/Desktop directory to the shortcuts model */
2025 static void 1621-static void
2026-shortcuts_append_desktop (GtkFileChooserDefault *impl) 1622-shortcuts_append_desktop (GtkFileChooserDefault *impl)
2027+up_button_clicked_cb (GtkButton *button, gpointer data) 1623-{
2028 {
2029- const char *name; 1624- const char *name;
2030- GtkFilePath *path; 1625- GtkFilePath *path;
2031- 1626-
@@ -2039,21 +1634,12 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
2039- /* We do not actually pop up an error dialog if there is no desktop directory 1634- /* We do not actually pop up an error dialog if there is no desktop directory
2040- * because some people may really not want to have one. 1635- * because some people may really not want to have one.
2041- */ 1636- */
2042+ GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (data); 1637-
2043+ up_folder_handler (impl);
2044+}
2045
2046- gtk_file_path_free (path); 1638- gtk_file_path_free (path);
2047+static void 1639-
2048+volume_button_clicked_cb (GtkButton *button, gpointer data)
2049+{
2050+ GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (data);
2051+ GtkFilePath * path = g_object_get_data (G_OBJECT (button), "file-path");
2052
2053- profile_end ("end", NULL); 1640- profile_end ("end", NULL);
2054+ change_folder_and_display_error (impl, path); 1641-}
2055 } 1642-
2056
2057-/* Appends a list of GtkFilePath to the shortcuts model; returns how many were inserted */ 1643-/* Appends a list of GtkFilePath to the shortcuts model; returns how many were inserted */
2058-static int 1644-static int
2059-shortcuts_append_paths (GtkFileChooserDefault *impl, 1645-shortcuts_append_paths (GtkFileChooserDefault *impl,
@@ -2062,216 +1648,85 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
2062- int start_row; 1648- int start_row;
2063- int num_inserted; 1649- int num_inserted;
2064- gchar *label; 1650- gchar *label;
2065+static GtkWidget * 1651-
2066+create_bar (GtkFileChooserDefault *impl)
2067+{
2068+ GSList *list, *l;
2069+ int n;
2070+ GtkWidget *bar = gtk_hbox_new (FALSE, DEFAULT_SPACING);
2071+ GtkWidget *img;
2072+ GtkWidget *label;
2073+
2074+ /* first the Up button */
2075+ img = gtk_image_new_from_stock (GTK_STOCK_GO_UP, GTK_ICON_SIZE_BUTTON);
2076+ gtk_widget_show (img);
2077+
2078+ impl->up_button = gtk_button_new ();
2079+ gtk_container_add (GTK_CONTAINER (impl->up_button), img);
2080+ gtk_widget_show (impl->up_button);
2081+ gtk_widget_set_sensitive (impl->up_button, FALSE);
2082+ gtk_button_set_focus_on_click (GTK_BUTTON (impl->up_button), FALSE);
2083+
2084+ g_signal_connect (impl->up_button, "clicked",
2085+ G_CALLBACK (up_button_clicked_cb), impl);
2086+ gtk_box_pack_start (GTK_BOX(bar), impl->up_button, FALSE, FALSE, 0);
2087
2088- profile_start ("start", NULL); 1652- profile_start ("start", NULL);
2089+ impl->num_volumes = 0; 1653-
2090+ list = gtk_file_system_list_volumes (impl->file_system);
2091
2092- /* As there is no separator now, we want to start there. 1654- /* As there is no separator now, we want to start there.
2093- */ 1655- */
2094- start_row = shortcuts_get_index (impl, SHORTCUTS_BOOKMARKS_SEPARATOR); 1656- start_row = shortcuts_get_index (impl, SHORTCUTS_BOOKMARKS_SEPARATOR);
2095- num_inserted = 0; 1657- num_inserted = 0;
2096+ n = 0; 1658-
2097
2098- for (; paths; paths = paths->next) 1659- for (; paths; paths = paths->next)
2099+ for (l = list; l; l = l->next, n++) 1660- {
2100 {
2101- GtkFilePath *path; 1661- GtkFilePath *path;
2102- 1662-
2103- path = paths->data; 1663- path = paths->data;
2104+ GtkFileSystemVolume *volume; 1664-
2105+ GdkPixbuf *pixbuf;
2106+ GtkWidget *button;
2107+ GtkWidget *image;
2108+ GtkFilePath *base_path;
2109+ gchar * file_name = NULL;
2110
2111- if (impl->local_only && 1665- if (impl->local_only &&
2112- !gtk_file_system_path_is_local (impl->file_system, path)) 1666- !gtk_file_system_path_is_local (impl->file_system, path))
2113- continue; 1667- continue;
2114+ volume = l->data; 1668-
2115+ base_path =
2116+ gtk_file_system_volume_get_base_path (impl->file_system, volume);
2117
2118- label = gtk_file_system_get_bookmark_label (impl->file_system, path); 1669- label = gtk_file_system_get_bookmark_label (impl->file_system, path);
2119+ if (impl->local_only) 1670-
2120+ {
2121+ gboolean is_local =
2122+ gtk_file_system_path_is_local (impl->file_system, base_path);
2123
2124- /* NULL GError, but we don't really want to show error boxes here */ 1671- /* NULL GError, but we don't really want to show error boxes here */
2125- shortcuts_insert_path (impl, start_row + num_inserted, SHORTCUT_TYPE_PATH, NULL, path, label, TRUE, SHORTCUTS_BOOKMARKS); 1672- shortcuts_insert_path (impl, start_row + num_inserted, SHORTCUT_TYPE_PATH, NULL, path, label, TRUE, SHORTCUTS_BOOKMARKS);
2126- num_inserted++; 1673- num_inserted++;
2127+ if (!is_local) 1674-
2128+ {
2129+ gtk_file_path_free (base_path);
2130+ gtk_file_system_volume_free (impl->file_system, volume);
2131+ continue;
2132+ }
2133+ }
2134
2135- g_free (label); 1675- g_free (label);
2136- } 1676- }
2137+#if 0 1677-
2138+ label_copy =
2139+ gtk_file_system_volume_get_display_name (impl->file_system, volume);
2140+#endif
2141+ pixbuf =
2142+ gtk_file_system_volume_render_icon (impl->file_system, volume,
2143+ GTK_WIDGET (impl),
2144+ impl->icon_size, NULL);
2145+
2146+ button = gtk_button_new ();
2147+ image = gtk_image_new_from_pixbuf (pixbuf);
2148+ g_object_unref (G_OBJECT (pixbuf));
2149+ gtk_container_add (GTK_CONTAINER (button), image);
2150+ gtk_button_set_focus_on_click (GTK_BUTTON (button), FALSE);
2151+
2152+ file_name =
2153+ gtk_file_system_path_to_filename (impl->file_system, base_path);
2154+
2155+ if (file_name && impl->root_folder &&
2156+ strcmp (file_name, impl->root_folder) &&
2157+ !strncmp (file_name, impl->root_folder, strlen (file_name)))
2158+ {
2159+ /* The base path is below the root folder; we replace it with
2160+ * the root folder
2161+ */
2162+ gtk_file_path_free (base_path);
2163+ base_path = gtk_file_system_filename_to_path (impl->file_system,
2164+ impl->root_folder);
2165+ }
2166
2167- profile_end ("end", NULL); 1678- profile_end ("end", NULL);
2168+ g_free (file_name); 1679-
2169+ gtk_widget_show_all (button);
2170
2171- return num_inserted; 1680- return num_inserted;
2172-} 1681-}
2173+ g_object_set_data (G_OBJECT (button), "file-path", base_path); 1682-
2174
2175-/* Returns the index for the corresponding item in the shortcuts bar */ 1683-/* Returns the index for the corresponding item in the shortcuts bar */
2176-static int 1684-static int
2177-shortcuts_get_index (GtkFileChooserDefault *impl, 1685-shortcuts_get_index (GtkFileChooserDefault *impl,
2178- ShortcutsIndex where) 1686- ShortcutsIndex where)
2179-{ 1687-{
2180- int n; 1688- int n;
2181+ g_signal_connect (button, "clicked", 1689-
2182+ G_CALLBACK (volume_button_clicked_cb), impl);
2183
2184- n = 0; 1690- n = 0;
2185- 1691-
2186- if (where == SHORTCUTS_SEARCH) 1692- if (where == SHORTCUTS_SEARCH)
2187- goto out; 1693- goto out;
2188+ gtk_box_pack_start (GTK_BOX(bar), button, FALSE, FALSE, 0); 1694-
2189+ }
2190
2191- n += impl->has_search ? 1 : 0; 1695- n += impl->has_search ? 1 : 0;
2192+ impl->num_volumes = n; 1696-
2193+ g_slist_free (list);
2194
2195- if (where == SHORTCUTS_RECENT) 1697- if (where == SHORTCUTS_RECENT)
2196- goto out; 1698- goto out;
2197+ label = impl->location_label = gtk_label_new (NULL); 1699-
2198+ gtk_label_set_ellipsize (GTK_LABEL (label), PANGO_ELLIPSIZE_START);
2199+ gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5);
2200+ gtk_label_set_text (GTK_LABEL (label), impl->root_folder);
2201+ gtk_widget_show (label);
2202+ gtk_box_pack_start (GTK_BOX(bar), label, TRUE, TRUE, 0);
2203
2204- n += impl->has_recent ? 1 : 0; 1700- n += impl->has_recent ? 1 : 0;
2205+ gtk_widget_show (bar); 1701-
2206
2207- if (where == SHORTCUTS_RECENT_SEPARATOR) 1702- if (where == SHORTCUTS_RECENT_SEPARATOR)
2208- goto out; 1703- goto out;
2209+ return bar; 1704-
2210+}
2211
2212- n += impl->has_recent ? 1 : 0; 1705- n += impl->has_recent ? 1 : 0;
2213+/* Creates the widgets for the files/folders pane */ 1706-
2214+static GtkWidget *
2215+file_pane_create (GtkFileChooserDefault *impl)
2216+{
2217+ GtkWidget *vbox;
2218+ GtkWidget *hbox;
2219+ GtkWidget *widget;
2220+ vbox = gtk_vbox_new (FALSE, DEFAULT_SPACING);
2221+ gtk_widget_show (vbox);
2222
2223- if (where == SHORTCUTS_HOME) 1707- if (where == SHORTCUTS_HOME)
2224- goto out; 1708- goto out;
2225+ /* The volume bar and 'Create Folder' button */ 1709-
2226+ hbox = gtk_hbox_new (FALSE, DEFAULT_SPACING);
2227+ gtk_widget_show (hbox);
2228+ impl->bar = create_bar (impl);
2229+ gtk_widget_show_all (impl->bar);
2230+ gtk_box_pack_start (GTK_BOX (hbox), impl->bar, TRUE, TRUE, 0);
2231
2232- n += impl->has_home ? 1 : 0; 1710- n += impl->has_home ? 1 : 0;
2233+ /* Create Folder */ 1711-
2234+ widget = gtk_image_new_from_icon_name ("folder-new", GTK_ICON_SIZE_BUTTON);
2235+ gtk_widget_show (widget);
2236+ impl->browse_new_folder_button = gtk_button_new ();
2237+ gtk_container_add (GTK_CONTAINER (impl->browse_new_folder_button), widget);
2238+ gtk_button_set_focus_on_click (GTK_BUTTON (impl->browse_new_folder_button),
2239+ FALSE);
2240
2241- if (where == SHORTCUTS_DESKTOP) 1712- if (where == SHORTCUTS_DESKTOP)
2242- goto out; 1713- goto out;
2243+ g_signal_connect (impl->browse_new_folder_button, "clicked", 1714-
2244+ G_CALLBACK (new_folder_button_clicked), impl);
2245+ gtk_box_pack_end (GTK_BOX (hbox), impl->browse_new_folder_button, FALSE, FALSE, 0);
2246
2247- n += impl->has_desktop ? 1 : 0; 1715- n += impl->has_desktop ? 1 : 0;
2248+ widget = filter_create (impl); 1716-
2249+ gtk_widget_hide (widget);
2250+ gtk_box_pack_end (GTK_BOX (hbox), widget, FALSE, FALSE, 0);
2251
2252- if (where == SHORTCUTS_VOLUMES) 1717- if (where == SHORTCUTS_VOLUMES)
2253- goto out; 1718- goto out;
2254+ gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0); 1719-
2255
2256- n += impl->num_volumes; 1720- n += impl->num_volumes;
2257+ /* Box for lists */ 1721-
2258+ hbox = gtk_hbox_new (FALSE, LIST_HBOX_SPACING);
2259+ gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 0);
2260+ gtk_widget_show (hbox);
2261
2262- if (where == SHORTCUTS_SHORTCUTS) 1722- if (where == SHORTCUTS_SHORTCUTS)
2263- goto out; 1723- goto out;
2264+ /* File list */ 1724-
2265
2266- n += impl->num_shortcuts; 1725- n += impl->num_shortcuts;
2267+ widget = create_file_list (impl); 1726-
2268+ gtk_box_pack_start (GTK_BOX (hbox), widget, TRUE, TRUE, 0);
2269
2270- if (where == SHORTCUTS_BOOKMARKS_SEPARATOR) 1727- if (where == SHORTCUTS_BOOKMARKS_SEPARATOR)
2271- goto out; 1728- goto out;
2272+ return vbox; 1729-
2273+}
2274
2275- /* If there are no bookmarks there won't be a separator */ 1730- /* If there are no bookmarks there won't be a separator */
2276- n += (impl->num_bookmarks > 0) ? 1 : 0; 1731- n += (impl->num_bookmarks > 0) ? 1 : 0;
2277- 1732-
@@ -2279,53 +1734,26 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
2279- goto out; 1734- goto out;
2280- 1735-
2281- n += impl->num_bookmarks; 1736- n += impl->num_bookmarks;
2282+/* Creates the widgets specific to Save mode */ 1737-
2283+static GtkWidget *
2284+save_widgets_create (GtkFileChooserDefault *impl)
2285+{
2286+ GtkWidget *vbox;
2287+ GtkWidget *hbox;
2288+ GtkWidget *widget;
2289
2290- if (where == SHORTCUTS_CURRENT_FOLDER_SEPARATOR) 1738- if (where == SHORTCUTS_CURRENT_FOLDER_SEPARATOR)
2291- goto out; 1739- goto out;
2292+ vbox = gtk_vbox_new (FALSE, 0); 1740-
2293+ hbox = gtk_hbox_new (FALSE, DEFAULT_SPACING);
2294
2295- n += 1; 1741- n += 1;
2296+ widget = gtk_label_new (_("Name:")); 1742-
2297+ gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5);
2298+ gtk_box_pack_start (GTK_BOX (hbox), widget, FALSE, FALSE, 0);
2299+ gtk_widget_show (widget);
2300
2301- if (where == SHORTCUTS_CURRENT_FOLDER) 1743- if (where == SHORTCUTS_CURRENT_FOLDER)
2302- goto out; 1744- goto out;
2303+ impl->location_entry = _gtk_file_chooser_entry_new (TRUE); 1745-
2304+ _gtk_file_chooser_entry_set_file_system (GTK_FILE_CHOOSER_ENTRY (impl->location_entry),
2305+ impl->file_system);
2306+/* gtk_entry_set_width_chars (GTK_ENTRY (impl->location_entry), 45); */
2307+ gtk_entry_set_activates_default (GTK_ENTRY (impl->location_entry), TRUE);
2308+ gtk_box_pack_start (GTK_BOX (hbox), impl->location_entry,
2309+ TRUE, TRUE, 0);
2310
2311- g_assert_not_reached (); 1746- g_assert_not_reached ();
2312+ gtk_widget_show (impl->location_entry); 1747-
2313
2314- out: 1748- out:
2315+ gtk_widget_show (hbox); 1749-
2316+ gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
2317
2318- return n; 1750- return n;
2319+ return vbox; 1751-}
2320 } 1752-
2321
2322-/* Adds all the file system volumes to the shortcuts model */ 1753-/* Adds all the file system volumes to the shortcuts model */
2323+/* Destroys the widgets specific to Save mode */ 1754-static void
2324+/* ??? */
2325 static void
2326-shortcuts_add_volumes (GtkFileChooserDefault *impl) 1755-shortcuts_add_volumes (GtkFileChooserDefault *impl)
2327+save_widgets_destroy (GtkFileChooserDefault *impl) 1756-{
2328 {
2329- int start_row; 1757- int start_row;
2330- GSList *list, *l; 1758- GSList *list, *l;
2331- int n; 1759- int n;
@@ -2336,49 +1764,27 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
2336- 1764-
2337- old_changing_folders = impl->changing_folder; 1765- old_changing_folders = impl->changing_folder;
2338- impl->changing_folder = TRUE; 1766- impl->changing_folder = TRUE;
2339+ if (impl->save_widgets == NULL) 1767-
2340+ return;
2341
2342- start_row = shortcuts_get_index (impl, SHORTCUTS_VOLUMES); 1768- start_row = shortcuts_get_index (impl, SHORTCUTS_VOLUMES);
2343- shortcuts_remove_rows (impl, start_row, impl->num_volumes); 1769- shortcuts_remove_rows (impl, start_row, impl->num_volumes);
2344- impl->num_volumes = 0; 1770- impl->num_volumes = 0;
2345+ gtk_widget_destroy (impl->save_widgets); 1771-
2346+ impl->save_widgets = NULL;
2347+ impl->location_entry = NULL;
2348+}
2349
2350- list = gtk_file_system_list_volumes (impl->file_system); 1772- list = gtk_file_system_list_volumes (impl->file_system);
2351+/* Creates the main hpaned with the widgets shared by Open and Save mode */ 1773-
2352+static GtkWidget *
2353+browse_widgets_create (GtkFileChooserDefault *impl)
2354+{
2355+ GtkWidget *widget;
2356
2357- n = 0; 1774- n = 0;
2358+ widget = file_pane_create (impl); 1775-
2359
2360- for (l = list; l; l = l->next) 1776- for (l = list; l; l = l->next)
2361- { 1777- {
2362- GtkFileSystemVolume *volume; 1778- GtkFileSystemVolume *volume;
2363+ return widget; 1779-
2364+}
2365
2366- volume = l->data; 1780- volume = l->data;
2367+static GObject* 1781-
2368+gtk_file_chooser_default_constructor (GType type,
2369+ guint n_construct_properties,
2370+ GObjectConstructParam *construct_params)
2371+{
2372+ GtkFileChooserDefault *impl;
2373+ GObject *object;
2374
2375- if (impl->local_only) 1782- if (impl->local_only)
2376- { 1783- {
2377- if (gtk_file_system_volume_get_is_mounted (impl->file_system, volume)) 1784- if (gtk_file_system_volume_get_is_mounted (impl->file_system, volume))
2378- { 1785- {
2379- GtkFilePath *base_path; 1786- GtkFilePath *base_path;
2380+ profile_start ("start", NULL); 1787-
2381
2382- base_path = gtk_file_system_volume_get_base_path (impl->file_system, volume); 1788- base_path = gtk_file_system_volume_get_base_path (impl->file_system, volume);
2383- if (base_path != NULL) 1789- if (base_path != NULL)
2384- { 1790- {
@@ -2393,37 +1799,23 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
2393- } 1799- }
2394- } 1800- }
2395- } 1801- }
2396+ object = G_OBJECT_CLASS (_gtk_file_chooser_default_parent_class)->constructor (type, 1802-
2397+ n_construct_properties,
2398+ construct_params);
2399+ impl = GTK_FILE_CHOOSER_DEFAULT (object);
2400
2401- shortcuts_insert_path (impl, start_row + n, SHORTCUT_TYPE_VOLUME, volume, NULL, NULL, FALSE, SHORTCUTS_VOLUMES); 1803- shortcuts_insert_path (impl, start_row + n, SHORTCUT_TYPE_VOLUME, volume, NULL, NULL, FALSE, SHORTCUTS_VOLUMES);
2402- n++; 1804- n++;
2403- } 1805- }
2404+ g_assert (impl->file_system); 1806-
2405
2406- impl->num_volumes = n; 1807- impl->num_volumes = n;
2407- g_slist_free (list); 1808- g_slist_free (list);
2408+ gtk_widget_push_composite_child (); 1809-
2409
2410- if (impl->shortcuts_pane_filter_model) 1810- if (impl->shortcuts_pane_filter_model)
2411- gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (impl->shortcuts_pane_filter_model)); 1811- gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (impl->shortcuts_pane_filter_model));
2412+ /* Widgets for Save mode */ 1812-
2413+ impl->save_widgets = save_widgets_create (impl);
2414+ gtk_box_pack_start (GTK_BOX (impl), impl->save_widgets, FALSE, FALSE, 0);
2415
2416- if (impl->shortcuts_combo_filter_model) 1813- if (impl->shortcuts_combo_filter_model)
2417- gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (impl->shortcuts_combo_filter_model)); 1814- gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (impl->shortcuts_combo_filter_model));
2418+ /* The browse widgets */ 1815-
2419+ impl->browse_widgets = browse_widgets_create (impl);
2420+ gtk_box_pack_start (GTK_BOX (impl), impl->browse_widgets, TRUE, TRUE, 0);
2421
2422- impl->changing_folder = old_changing_folders; 1816- impl->changing_folder = old_changing_folders;
2423+ gtk_widget_pop_composite_child (); 1817-
2424+ update_appearance (impl); 1818- profile_end ("end", NULL);
2425
2426 profile_end ("end", NULL);
2427-} 1819-}
2428- 1820-
2429-/* Inserts a separator node in the shortcuts list */ 1821-/* Inserts a separator node in the shortcuts list */
@@ -2432,7 +1824,7 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
2432- ShortcutsIndex where) 1824- ShortcutsIndex where)
2433-{ 1825-{
2434- GtkTreeIter iter; 1826- GtkTreeIter iter;
2435 1827-
2436- g_assert (where == SHORTCUTS_RECENT_SEPARATOR || 1828- g_assert (where == SHORTCUTS_RECENT_SEPARATOR ||
2437- where == SHORTCUTS_BOOKMARKS_SEPARATOR || 1829- where == SHORTCUTS_BOOKMARKS_SEPARATOR ||
2438- where == SHORTCUTS_CURRENT_FOLDER_SEPARATOR); 1830- where == SHORTCUTS_CURRENT_FOLDER_SEPARATOR);
@@ -2446,15 +1838,12 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
2446- SHORTCUTS_COL_DATA, NULL, 1838- SHORTCUTS_COL_DATA, NULL,
2447- SHORTCUTS_COL_TYPE, SHORTCUT_TYPE_SEPARATOR, 1839- SHORTCUTS_COL_TYPE, SHORTCUT_TYPE_SEPARATOR,
2448- -1); 1840- -1);
2449+ return object; 1841-}
2450 } 1842-
2451
2452-/* Updates the list of bookmarks */ 1843-/* Updates the list of bookmarks */
2453 static void 1844-static void
2454-shortcuts_add_bookmarks (GtkFileChooserDefault *impl) 1845-shortcuts_add_bookmarks (GtkFileChooserDefault *impl)
2455+set_local_only (GtkFileChooserDefault *impl, 1846-{
2456+ gboolean local_only)
2457 {
2458- GSList *bookmarks; 1847- GSList *bookmarks;
2459- gboolean old_changing_folders; 1848- gboolean old_changing_folders;
2460- GtkTreeIter iter; 1849- GtkTreeIter iter;
@@ -2462,24 +1851,12 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
2462- GtkFilePath *combo_selected = NULL; 1851- GtkFilePath *combo_selected = NULL;
2463- ShortcutType shortcut_type; 1852- ShortcutType shortcut_type;
2464- gpointer col_data; 1853- gpointer col_data;
2465+ if (local_only != impl->local_only) 1854-
2466+ {
2467+ impl->local_only = local_only;
2468
2469- profile_start ("start", NULL); 1855- profile_start ("start", NULL);
2470- 1856-
2471- old_changing_folders = impl->changing_folder; 1857- old_changing_folders = impl->changing_folder;
2472- impl->changing_folder = TRUE; 1858- impl->changing_folder = TRUE;
2473+ if (local_only && 1859-
2474+ !gtk_file_system_path_is_local (impl->file_system, impl->current_folder))
2475+ {
2476+ /* If we are pointing to a non-local folder, make an effort to change
2477+ * back to a local folder, but it's really up to the app to not cause
2478+ * such a situation, so we ignore errors.
2479+ */
2480+ const gchar *home = g_get_home_dir ();
2481+ GtkFilePath *home_path;
2482
2483- if (shortcuts_get_selected (impl, &iter)) 1860- if (shortcuts_get_selected (impl, &iter))
2484- { 1861- {
2485- gtk_tree_model_get (GTK_TREE_MODEL (impl->shortcuts_model), 1862- gtk_tree_model_get (GTK_TREE_MODEL (impl->shortcuts_model),
@@ -2487,21 +1864,17 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
2487- SHORTCUTS_COL_DATA, &col_data, 1864- SHORTCUTS_COL_DATA, &col_data,
2488- SHORTCUTS_COL_TYPE, &shortcut_type, 1865- SHORTCUTS_COL_TYPE, &shortcut_type,
2489- -1); 1866- -1);
2490+ if (home == NULL) 1867-
2491+ return;
2492
2493- if (col_data && shortcut_type == SHORTCUT_TYPE_PATH) 1868- if (col_data && shortcut_type == SHORTCUT_TYPE_PATH)
2494- list_selected = gtk_file_path_copy (col_data); 1869- list_selected = gtk_file_path_copy (col_data);
2495- } 1870- }
2496+ home_path = gtk_file_system_filename_to_path (impl->file_system, home); 1871-
2497
2498- if (impl->save_folder_combo && 1872- if (impl->save_folder_combo &&
2499- gtk_combo_box_get_active_iter (GTK_COMBO_BOX (impl->save_folder_combo), 1873- gtk_combo_box_get_active_iter (GTK_COMBO_BOX (impl->save_folder_combo),
2500- &iter)) 1874- &iter))
2501- { 1875- {
2502- GtkTreeIter child_iter; 1876- GtkTreeIter child_iter;
2503+ _gtk_file_chooser_set_current_folder_path (GTK_FILE_CHOOSER (impl), home_path, NULL); 1877-
2504
2505- gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER (impl->shortcuts_combo_filter_model), 1878- gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER (impl->shortcuts_combo_filter_model),
2506- &child_iter, 1879- &child_iter,
2507- &iter); 1880- &iter);
@@ -2513,75 +1886,36 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
2513- 1886-
2514- if (col_data && shortcut_type == SHORTCUT_TYPE_PATH) 1887- if (col_data && shortcut_type == SHORTCUT_TYPE_PATH)
2515- combo_selected = gtk_file_path_copy (col_data); 1888- combo_selected = gtk_file_path_copy (col_data);
2516+ gtk_file_path_free (home_path); 1889- }
2517+ } 1890-
2518 }
2519+}
2520
2521- if (impl->num_bookmarks > 0) 1891- if (impl->num_bookmarks > 0)
2522- shortcuts_remove_rows (impl, 1892- shortcuts_remove_rows (impl,
2523- shortcuts_get_index (impl, SHORTCUTS_BOOKMARKS_SEPARATOR), 1893- shortcuts_get_index (impl, SHORTCUTS_BOOKMARKS_SEPARATOR),
2524- impl->num_bookmarks + 1); 1894- impl->num_bookmarks + 1);
2525+static void 1895-
2526+volumes_changed_cb (GtkFileSystem *file_system,
2527+ GtkFileChooserDefault *impl)
2528+{
2529+ /* FIXME -- update the bar */
2530+}
2531+
2532+/* Sets the file chooser to multiple selection mode */
2533+static void
2534+set_select_multiple (GtkFileChooserDefault *impl,
2535+ gboolean select_multiple,
2536+ gboolean property_notify)
2537+{
2538+ GtkTreeSelection *selection;
2539+ GtkSelectionMode mode;
2540
2541- impl->num_bookmarks = 0; 1896- impl->num_bookmarks = 0;
2542+ if (select_multiple == impl->select_multiple) 1897-
2543+ return;
2544
2545- bookmarks = gtk_file_system_list_bookmarks (impl->file_system); 1898- bookmarks = gtk_file_system_list_bookmarks (impl->file_system);
2546- shortcuts_append_paths (impl, bookmarks); 1899- shortcuts_append_paths (impl, bookmarks);
2547- gtk_file_paths_free (bookmarks); 1900- gtk_file_paths_free (bookmarks);
2548+ mode = select_multiple ? GTK_SELECTION_MULTIPLE : GTK_SELECTION_BROWSE; 1901-
2549
2550- if (impl->num_bookmarks > 0) 1902- if (impl->num_bookmarks > 0)
2551- shortcuts_insert_separator (impl, SHORTCUTS_BOOKMARKS_SEPARATOR); 1903- shortcuts_insert_separator (impl, SHORTCUTS_BOOKMARKS_SEPARATOR);
2552+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_files_tree_view)); 1904-
2553+ gtk_tree_selection_set_mode (selection, mode);
2554
2555- if (impl->shortcuts_pane_filter_model) 1905- if (impl->shortcuts_pane_filter_model)
2556- gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (impl->shortcuts_pane_filter_model)); 1906- gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (impl->shortcuts_pane_filter_model));
2557+ impl->select_multiple = select_multiple; 1907-
2558+ g_object_notify (G_OBJECT (impl), "select-multiple");
2559+}
2560
2561- if (impl->shortcuts_combo_filter_model) 1908- if (impl->shortcuts_combo_filter_model)
2562- gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (impl->shortcuts_combo_filter_model)); 1909- gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (impl->shortcuts_combo_filter_model));
2563+static void 1910-
2564+set_file_system_backend (GtkFileChooserDefault *impl,
2565+ const char *backend)
2566+{
2567+ profile_start ("start for backend", backend ? backend : "default");
2568
2569- if (list_selected) 1911- if (list_selected)
2570+ if (impl->file_system) 1912- {
2571 {
2572- shortcuts_find_folder (impl, list_selected); 1913- shortcuts_find_folder (impl, list_selected);
2573- gtk_file_path_free (list_selected); 1914- gtk_file_path_free (list_selected);
2574+ g_signal_handler_disconnect (impl->file_system, impl->volumes_changed_id); 1915- }
2575+ impl->volumes_changed_id = 0; 1916-
2576+ g_object_unref (impl->file_system);
2577 }
2578
2579- if (combo_selected) 1917- if (combo_selected)
2580+ impl->file_system = NULL; 1918- {
2581+ if (backend)
2582+ impl->file_system = gtk_file_system_create (backend);
2583+ else
2584 {
2585- gint pos; 1919- gint pos;
2586- 1920-
2587- pos = shortcut_find_position (impl, combo_selected); 1921- pos = shortcut_find_position (impl, combo_selected);
@@ -2589,50 +1923,25 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
2589- { 1923- {
2590- if (impl->has_search) 1924- if (impl->has_search)
2591- pos -= 1; 1925- pos -= 1;
2592+ GtkSettings *settings = gtk_settings_get_default (); 1926-
2593+ gchar *default_backend = NULL;
2594
2595- if (impl->has_recent) 1927- if (impl->has_recent)
2596- pos -= 2; 1928- pos -= 2;
2597+ g_object_get (settings, "gtk-file-chooser-backend", &default_backend, NULL); 1929-
2598+ if (default_backend)
2599+ {
2600+ impl->file_system = gtk_file_system_create (default_backend);
2601+ g_free (default_backend);
2602+ }
2603+ }
2604
2605- gtk_combo_box_set_active (GTK_COMBO_BOX (impl->save_folder_combo), pos); 1930- gtk_combo_box_set_active (GTK_COMBO_BOX (impl->save_folder_combo), pos);
2606- } 1931- }
2607+ if (!impl->file_system) 1932-
2608+ {
2609+#if defined (G_OS_UNIX)
2610+ impl->file_system = gtk_file_system_unix_new ();
2611+#elif defined (G_OS_WIN32)
2612+ impl->file_system = gtk_file_system_win32_new ();
2613+#else
2614+#error "No default filesystem implementation on the platform"
2615+#endif
2616+ }
2617
2618- gtk_file_path_free (combo_selected); 1933- gtk_file_path_free (combo_selected);
2619+ if (impl->file_system) 1934- }
2620+ {
2621+ impl->volumes_changed_id = g_signal_connect (impl->file_system, "volumes-changed",
2622+ G_CALLBACK (volumes_changed_cb),
2623+ impl);
2624 }
2625- 1935-
2626- impl->changing_folder = old_changing_folders; 1936- impl->changing_folder = old_changing_folders;
2627 1937-
2628 profile_end ("end", NULL); 1938- profile_end ("end", NULL);
2629 } 1939-}
2630 1940-
2631-/* Appends a separator and a row to the shortcuts list for the current folder */ 1941-/* Appends a separator and a row to the shortcuts list for the current folder */
2632 static void 1942-static void
2633-shortcuts_add_current_folder (GtkFileChooserDefault *impl) 1943-shortcuts_add_current_folder (GtkFileChooserDefault *impl)
2634+show_new_folder_button (GtkFileChooserDefault *impl) 1944-{
2635 {
2636- int pos; 1945- int pos;
2637- gboolean success; 1946- gboolean success;
2638- 1947-
@@ -2644,10 +1953,7 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
2644- 1953-
2645- pos = shortcut_find_position (impl, impl->current_folder); 1954- pos = shortcut_find_position (impl, impl->current_folder);
2646- if (pos == -1) 1955- if (pos == -1)
2647+ if ((impl->action == GTK_FILE_CHOOSER_ACTION_SAVE || 1956- {
2648+ impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER) &&
2649+ impl->show_create_folder)
2650 {
2651- GtkFileSystemVolume *volume; 1957- GtkFileSystemVolume *volume;
2652- GtkFilePath *base_path; 1958- GtkFilePath *base_path;
2653- 1959-
@@ -2679,12 +1985,9 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
2679- 1985-
2680- if (base_path) 1986- if (base_path)
2681- gtk_file_path_free (base_path); 1987- gtk_file_path_free (base_path);
2682+ gtk_widget_show (impl->browse_new_folder_button); 1988- }
2683+ gtk_misc_set_alignment (GTK_MISC (impl->location_label), 0.5, 0.5);
2684 }
2685- else if (impl->save_folder_combo != NULL) 1989- else if (impl->save_folder_combo != NULL)
2686+ else 1990- {
2687 {
2688- if (impl->has_search) 1991- if (impl->has_search)
2689- pos -= 1; 1992- pos -= 1;
2690- 1993-
@@ -2692,47 +1995,23 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
2692- pos -= 2; /* + separator */ 1995- pos -= 2; /* + separator */
2693- 1996-
2694- gtk_combo_box_set_active (GTK_COMBO_BOX (impl->save_folder_combo), pos); 1997- gtk_combo_box_set_active (GTK_COMBO_BOX (impl->save_folder_combo), pos);
2695+ gtk_widget_hide (impl->browse_new_folder_button); 1998- }
2696+ gtk_misc_set_alignment (GTK_MISC (impl->location_label), 1.0, 0.5); 1999-}
2697 } 2000-
2698 }
2699
2700-/* Updates the current folder row in the shortcuts model */ 2001-/* Updates the current folder row in the shortcuts model */
2701+/* This function is basically a do_all function. 2002-static void
2702+ *
2703+ * It sets the visibility on all the widgets based on the current state, and
2704+ * moves the custom_widget if needed.
2705+ */
2706 static void
2707-shortcuts_update_current_folder (GtkFileChooserDefault *impl) 2003-shortcuts_update_current_folder (GtkFileChooserDefault *impl)
2708+update_appearance (GtkFileChooserDefault *impl) 2004-{
2709 {
2710- int pos; 2005- int pos;
2711- 2006-
2712- pos = shortcuts_get_index (impl, SHORTCUTS_CURRENT_FOLDER_SEPARATOR); 2007- pos = shortcuts_get_index (impl, SHORTCUTS_CURRENT_FOLDER_SEPARATOR);
2713+ if (impl->action == GTK_FILE_CHOOSER_ACTION_SAVE || 2008-
2714+ impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)
2715+ {
2716+ gtk_widget_show (impl->save_widgets);
2717+ gtk_widget_show (impl->browse_widgets);
2718
2719- if (impl->shortcuts_current_folder_active) 2009- if (impl->shortcuts_current_folder_active)
2720+ if (impl->select_multiple) 2010- {
2721+ {
2722+ g_warning ("Save mode cannot be set in conjunction with multiple selection mode. "
2723+ "Re-setting to single selection mode.");
2724+ set_select_multiple (impl, FALSE, TRUE);
2725+ }
2726+ }
2727+ else if (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN ||
2728+ impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER)
2729 {
2730- shortcuts_remove_rows (impl, pos, 2); 2011- shortcuts_remove_rows (impl, pos, 2);
2731- impl->shortcuts_current_folder_active = FALSE; 2012- impl->shortcuts_current_folder_active = FALSE;
2732+ gtk_widget_hide (impl->save_widgets); 2013- }
2733+ gtk_widget_show (impl->browse_widgets); 2014-
2734 }
2735
2736- shortcuts_add_current_folder (impl); 2015- shortcuts_add_current_folder (impl);
2737-} 2016-}
2738- 2017-
@@ -2751,18 +2030,15 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
2751- path = gtk_tree_model_get_path (model, iter); 2030- path = gtk_tree_model_get_path (model, iter);
2752- if (!path) 2031- if (!path)
2753- return FALSE; 2032- return FALSE;
2754+ show_new_folder_button (impl); 2033-
2755
2756- pos = *gtk_tree_path_get_indices (path); 2034- pos = *gtk_tree_path_get_indices (path);
2757- gtk_tree_path_free (path); 2035- gtk_tree_path_free (path);
2758+ gtk_widget_queue_draw (impl->browse_files_tree_view); 2036-
2759
2760- return (pos < shortcuts_get_index (impl, SHORTCUTS_CURRENT_FOLDER_SEPARATOR)); 2037- return (pos < shortcuts_get_index (impl, SHORTCUTS_CURRENT_FOLDER_SEPARATOR));
2761+ g_signal_emit_by_name (impl, "default-size-changed"); 2038-}
2762 } 2039-
2763
2764-/* Creates the list model for shortcuts */ 2040-/* Creates the list model for shortcuts */
2765 static void 2041-static void
2766-shortcuts_model_create (GtkFileChooserDefault *impl) 2042-shortcuts_model_create (GtkFileChooserDefault *impl)
2767-{ 2043-{
2768- /* Keep this order in sync with the SHORCUTS_COL_* enum values */ 2044- /* Keep this order in sync with the SHORCUTS_COL_* enum values */
@@ -2774,18 +2050,12 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
2774- G_TYPE_BOOLEAN, /* removable */ 2050- G_TYPE_BOOLEAN, /* removable */
2775- G_TYPE_BOOLEAN, /* pixbuf cell visibility */ 2051- G_TYPE_BOOLEAN, /* pixbuf cell visibility */
2776- G_TYPE_POINTER); /* GtkFileSystemHandle */ 2052- G_TYPE_POINTER); /* GtkFileSystemHandle */
2777+gtk_file_chooser_default_set_property (GObject *object, 2053-
2778+ guint prop_id,
2779+ const GValue *value,
2780+ GParamSpec *pspec)
2781
2782- if (search_is_possible (impl)) 2054- if (search_is_possible (impl))
2783- { 2055- {
2784- shortcuts_append_search (impl); 2056- shortcuts_append_search (impl);
2785- } 2057- }
2786+{ 2058-
2787+ GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (object);
2788
2789- if (impl->recent_manager) 2059- if (impl->recent_manager)
2790- { 2060- {
2791- shortcuts_append_recent (impl); 2061- shortcuts_append_recent (impl);
@@ -2793,8 +2063,7 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
2793- } 2063- }
2794- 2064-
2795- if (impl->file_system) 2065- if (impl->file_system)
2796+ switch (prop_id) 2066- {
2797 {
2798- shortcuts_append_home (impl); 2067- shortcuts_append_home (impl);
2799- shortcuts_append_desktop (impl); 2068- shortcuts_append_desktop (impl);
2800- shortcuts_add_volumes (impl); 2069- shortcuts_add_volumes (impl);
@@ -2809,279 +2078,66 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
2809- impl, 2078- impl,
2810- NULL); 2079- NULL);
2811-} 2080-}
2812+ case GTK_FILE_CHOOSER_PROP_ACTION:
2813+ {
2814+ GtkFileChooserAction action = g_value_get_enum (value);
2815
2816-/* Callback used when the "New Folder" button is clicked */
2817-static void
2818-new_folder_button_clicked (GtkButton *button,
2819- GtkFileChooserDefault *impl)
2820-{
2821- GtkTreeIter iter;
2822- GtkTreePath *path;
2823-
2824- if (!impl->browse_files_model)
2825- return; /* FIXME: this sucks. Disable the New Folder button or something. */
2826-
2827- /* Prevent button from being clicked twice */
2828- gtk_widget_set_sensitive (impl->browse_new_folder_button, FALSE);
2829-
2830- _gtk_file_system_model_add_editable (impl->browse_files_model, &iter);
2831-
2832- path = gtk_tree_model_get_path (GTK_TREE_MODEL (impl->browse_files_model), &iter);
2833- gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (impl->browse_files_tree_view),
2834- path, impl->list_name_column,
2835- FALSE, 0.0, 0.0);
2836-
2837- g_object_set (impl->list_name_renderer, "editable", TRUE, NULL);
2838- gtk_tree_view_set_cursor (GTK_TREE_VIEW (impl->browse_files_tree_view),
2839- path,
2840- impl->list_name_column,
2841- TRUE);
2842-
2843- gtk_tree_path_free (path);
2844-}
2845- 2081-
2846-static void 2082 /* Callback used when the "New Folder" button is clicked */
2847-edited_idle_create_folder_cb (GtkFileSystemHandle *handle, 2083 static void
2848- const GtkFilePath *path, 2084 new_folder_button_clicked (GtkButton *button,
2849- const GError *error, 2085@@ -2472,7 +973,7 @@
2850- gpointer data) 2086 goto out;
2851-{
2852- gboolean cancelled = handle->cancelled;
2853- GtkFileChooserDefault *impl = data;
2854-
2855- if (!g_slist_find (impl->pending_handles, handle))
2856- goto out;
2857-
2858- impl->pending_handles = g_slist_remove (impl->pending_handles, handle);
2859+ if (action != impl->action)
2860+ {
2861+ gtk_file_chooser_default_unselect_all (GTK_FILE_CHOOSER (impl));
2862+
2863+ if ((action == GTK_FILE_CHOOSER_ACTION_SAVE || action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)
2864+ && impl->select_multiple)
2865+ {
2866+ g_warning ("Tried to change the file chooser action to SAVE or CREATE_FOLDER, but "
2867+ "this is not allowed in multiple selection mode. Resetting the file chooser "
2868+ "to single selection mode.");
2869+ set_select_multiple (impl, FALSE, TRUE);
2870+ }
2871+ impl->action = action;
2872+ update_appearance (impl);
2873+ settings_load (impl);
2874+ }
2875+ }
2876+ break;
2877
2878- if (cancelled)
2879- goto out;
2880+ case GTK_FILE_CHOOSER_PROP_FILE_SYSTEM_BACKEND:
2881+ set_file_system_backend (impl, g_value_get_string (value));
2882+ break;
2883 2087
2884- if (!error) 2088 if (!error)
2885- change_folder_and_display_error (impl, path, FALSE); 2089- change_folder_and_display_error (impl, path, FALSE);
2886- else 2090+ change_folder_and_display_error (impl, path);
2887- error_creating_folder_dialog (impl, path, g_error_copy (error)); 2091 else
2888+ case GTK_FILE_CHOOSER_PROP_FILTER: 2092 error_creating_folder_dialog (impl, path, g_error_copy (error));
2889+ set_current_filter (impl, g_value_get_object (value));
2890+ break;
2891
2892- out:
2893- g_object_unref (impl);
2894- g_object_unref (handle);
2895-}
2896+ case GTK_FILE_CHOOSER_PROP_LOCAL_ONLY:
2897+ set_local_only (impl, g_value_get_boolean (value));
2898+ break;
2899 2093
2900-/* Idle handler for creating a new folder after editing its name cell, or for 2094@@ -2488,7 +989,7 @@
2901- * canceling the editing. 2095 edited_idle_cb (GtkFileChooserDefault *impl)
2902- */ 2096 {
2903-static gboolean 2097 GDK_THREADS_ENTER ();
2904-edited_idle_cb (GtkFileChooserDefault *impl)
2905-{
2906- GDK_THREADS_ENTER ();
2907- 2098-
2908- g_source_destroy (impl->edited_idle); 2099+
2909- impl->edited_idle = NULL; 2100 g_source_destroy (impl->edited_idle);
2910+ case GTK_FILE_CHOOSER_PROP_SELECT_MULTIPLE: 2101 impl->edited_idle = NULL;
2911+ {
2912+ gboolean select_multiple = g_value_get_boolean (value);
2913+ if ((impl->action == GTK_FILE_CHOOSER_ACTION_SAVE || impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)
2914+ && select_multiple)
2915+ {
2916+ g_warning ("Tried to set the file chooser to multiple selection mode, but this is "
2917+ "not allowed in SAVE or CREATE_FOLDER modes. Ignoring the change and "
2918+ "leaving the file chooser in single selection mode.");
2919+ return;
2920+ }
2921
2922- _gtk_file_system_model_remove_editable (impl->browse_files_model);
2923- g_object_set (impl->list_name_renderer, "editable", FALSE, NULL);
2924+ set_select_multiple (impl, select_multiple, FALSE);
2925+ }
2926+ break;
2927
2928- gtk_widget_set_sensitive (impl->browse_new_folder_button, TRUE);
2929+ case GTK_FILE_CHOOSER_PROP_SHOW_HIDDEN:
2930+ {
2931+ gboolean show_hidden = g_value_get_boolean (value);
2932+ if (show_hidden != impl->show_hidden)
2933+ {
2934+ impl->show_hidden = show_hidden;
2935
2936- if (impl->edited_new_text) /* not cancelled? */
2937- {
2938- GError *error;
2939- GtkFilePath *file_path;
2940+ if (impl->browse_files_model)
2941+ _gtk_file_system_model_set_show_hidden (impl->browse_files_model, show_hidden);
2942+ }
2943+ }
2944+ break;
2945
2946- error = NULL;
2947- file_path = gtk_file_system_make_path (impl->file_system,
2948- impl->current_folder,
2949- impl->edited_new_text,
2950- &error);
2951- if (file_path)
2952- {
2953- GtkFileSystemHandle *handle;
2954+ case GTK_FILE_CHOOSER_PROP_DO_OVERWRITE_CONFIRMATION:
2955+ {
2956+ gboolean do_overwrite_confirmation = g_value_get_boolean (value);
2957+ impl->do_overwrite_confirmation = do_overwrite_confirmation;
2958+ }
2959+ break;
2960
2961- handle = gtk_file_system_create_folder (impl->file_system, file_path,
2962- edited_idle_create_folder_cb,
2963- g_object_ref (impl));
2964- impl->pending_handles = g_slist_append (impl->pending_handles, handle);
2965+ case GTK_FILE_CHOOSER_PROP_ROOT_FOLDER:
2966+ {
2967+ GtkFilePath * path;
2968+ gchar * new_root = g_strdup (g_value_get_string (value));
2969
2970- gtk_file_path_free (file_path);
2971- }
2972- else
2973- error_creating_folder_dialog (impl, file_path, error);
2974+ if (!new_root)
2975+ {
2976+ new_root = g_strdup ("/");
2977+ }
2978
2979- g_free (impl->edited_new_text);
2980- impl->edited_new_text = NULL;
2981- }
2982+ path = gtk_file_system_filename_to_path (impl->file_system,
2983+ new_root);
2984+ if (change_folder (impl, path, FALSE))
2985+ {
2986+ g_free (impl->root_folder);
2987+ impl->root_folder = new_root;
2988+ }
2989+ else
2990+ {
2991+ g_warning ("Unable to set [%s] as root folder", new_root);
2992+ g_free (new_root);
2993+ }
2994
2995- GDK_THREADS_LEAVE ();
2996+ gtk_file_path_free (path);
2997+ }
2998+ break;
2999
3000- return FALSE;
3001-}
3002+ case GTK_FILE_CHOOSER_PROP_SHOW_CREATE_FOLDER:
3003+ {
3004+ gboolean show = g_value_get_boolean (value);
3005+ if (show != impl->show_create_folder)
3006+ {
3007+ impl->show_create_folder = show;
3008+ show_new_folder_button (impl);
3009+ }
3010+ }
3011+ break;
3012
3013-static void
3014-queue_edited_idle (GtkFileChooserDefault *impl,
3015- const gchar *new_text)
3016-{
3017- /* We create the folder in an idle handler so that we don't modify the tree
3018- * just now.
3019- */
3020+ /* These are not supported */
3021+ case GTK_FILE_CHOOSER_PROP_PREVIEW_WIDGET:
3022+ case GTK_FILE_CHOOSER_PROP_PREVIEW_WIDGET_ACTIVE:
3023+ case GTK_FILE_CHOOSER_PROP_USE_PREVIEW_LABEL:
3024+ case GTK_FILE_CHOOSER_PROP_EXTRA_WIDGET:
3025+ break;
3026 2102
3027- if (!impl->edited_idle) 2103@@ -2558,10 +1059,10 @@
3028- { 2104 const gchar *new_text,
3029- impl->edited_idle = g_idle_source_new (); 2105 GtkFileChooserDefault *impl)
3030- g_source_set_closure (impl->edited_idle, 2106 {
3031- g_cclosure_new_object (G_CALLBACK (edited_idle_cb),
3032- G_OBJECT (impl)));
3033- g_source_attach (impl->edited_idle, NULL);
3034+ default:
3035+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
3036+ break;
3037 }
3038-
3039- g_free (impl->edited_new_text);
3040- impl->edited_new_text = g_strdup (new_text);
3041-}
3042-
3043-/* Callback used from the text cell renderer when the new folder is named */
3044-static void
3045-renderer_edited_cb (GtkCellRendererText *cell_renderer_text,
3046- const gchar *path,
3047- const gchar *new_text,
3048- GtkFileChooserDefault *impl)
3049-{
3050- /* work around bug #154921 */ 2107- /* work around bug #154921 */
3051- g_object_set (cell_renderer_text, 2108- g_object_set (cell_renderer_text,
3052- "mode", GTK_CELL_RENDERER_MODE_INERT, NULL); 2109+ /* work around bug #154921 */
2110+ g_object_set (cell_renderer_text,
2111 "mode", GTK_CELL_RENDERER_MODE_INERT, NULL);
3053- queue_edited_idle (impl, new_text); 2112- queue_edited_idle (impl, new_text);
2113+ queue_edited_idle (impl, new_text);
3054 } 2114 }
3055 2115
3056-/* Callback used from the text cell renderer when the new folder edition gets 2116 /* Callback used from the text cell renderer when the new folder edition gets
3057- * canceled. 2117@@ -2571,10 +1072,10 @@
3058- */ 2118 renderer_editing_canceled_cb (GtkCellRendererText *cell_renderer_text,
3059 static void 2119 GtkFileChooserDefault *impl)
3060-renderer_editing_canceled_cb (GtkCellRendererText *cell_renderer_text, 2120 {
3061- GtkFileChooserDefault *impl)
3062-{
3063- /* work around bug #154921 */ 2121- /* work around bug #154921 */
3064- g_object_set (cell_renderer_text, 2122- g_object_set (cell_renderer_text,
3065- "mode", GTK_CELL_RENDERER_MODE_INERT, NULL); 2123+ /* work around bug #154921 */
2124+ g_object_set (cell_renderer_text,
2125 "mode", GTK_CELL_RENDERER_MODE_INERT, NULL);
3066- queue_edited_idle (impl, NULL); 2126- queue_edited_idle (impl, NULL);
3067-} 2127+ queue_edited_idle (impl, NULL);
3068- 2128 }
3069-/* Creates the widgets for the filter combo box */ 2129
3070-static GtkWidget * 2130 /* Creates the widgets for the filter combo box */
3071-filter_create (GtkFileChooserDefault *impl) 2131@@ -2587,253 +1088,9 @@
3072-{ 2132 g_signal_connect (impl->filter_combo, "changed",
3073- impl->filter_combo = gtk_combo_box_new_text (); 2133 G_CALLBACK (filter_combo_changed), impl);
3074- gtk_combo_box_set_focus_on_click (GTK_COMBO_BOX (impl->filter_combo), FALSE); 2134
3075-
3076- g_signal_connect (impl->filter_combo, "changed",
3077- G_CALLBACK (filter_combo_changed), impl);
3078-
3079- gtk_widget_set_tooltip_text (impl->filter_combo, 2135- gtk_widget_set_tooltip_text (impl->filter_combo,
3080- _("Select which types of files are shown")); 2136- _("Select which types of files are shown"));
3081- 2137-
3082- return impl->filter_combo; 2138 return impl->filter_combo;
3083-} 2139 }
3084- 2140
3085-static GtkWidget * 2141-static GtkWidget *
3086-button_new (GtkFileChooserDefault *impl, 2142-button_new (GtkFileChooserDefault *impl,
3087- const char *text, 2143- const char *text,
@@ -3110,11 +2166,7 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
3110-static int 2166-static int
3111-shortcut_find_position (GtkFileChooserDefault *impl, 2167-shortcut_find_position (GtkFileChooserDefault *impl,
3112- const GtkFilePath *path) 2168- const GtkFilePath *path)
3113+gtk_file_chooser_default_get_property (GObject *object, 2169-{
3114+ guint prop_id,
3115+ GValue *value,
3116+ GParamSpec *pspec)
3117 {
3118- GtkTreeIter iter; 2170- GtkTreeIter iter;
3119- int i; 2171- int i;
3120- int current_folder_separator_idx; 2172- int current_folder_separator_idx;
@@ -3129,11 +2181,9 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
3129- if (current_folder_separator_idx >= impl->shortcuts_model->length) 2181- if (current_folder_separator_idx >= impl->shortcuts_model->length)
3130- return -1; 2182- return -1;
3131-#endif 2183-#endif
3132+ GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (object); 2184-
3133
3134- for (i = 0; i < current_folder_separator_idx; i++) 2185- for (i = 0; i < current_folder_separator_idx; i++)
3135+ switch (prop_id) 2186- {
3136 {
3137- gpointer col_data; 2187- gpointer col_data;
3138- ShortcutType shortcut_type; 2188- ShortcutType shortcut_type;
3139- 2189-
@@ -3170,10 +2220,7 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
3170- return i; 2220- return i;
3171- } 2221- }
3172- } 2222- }
3173+ case GTK_FILE_CHOOSER_PROP_ACTION: 2223-
3174+ g_value_set_enum (value, impl->action);
3175+ break;
3176
3177- if (i < current_folder_separator_idx - 1) 2224- if (i < current_folder_separator_idx - 1)
3178- { 2225- {
3179- if (!gtk_tree_model_iter_next (GTK_TREE_MODEL (impl->shortcuts_model), &iter)) 2226- 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
3332- remove_selected_bookmarks (impl); 2379- remove_selected_bookmarks (impl);
3333-} 2380-}
3334- 2381-
3335-struct selection_check_closure { 2382 struct selection_check_closure {
3336- GtkFileChooserDefault *impl; 2383 GtkFileChooserDefault *impl;
3337- int num_selected; 2384 int num_selected;
3338- gboolean all_files; 2385@@ -2856,29 +1113,11 @@
3339- gboolean all_folders; 2386 closure = data;
3340-}; 2387 closure->num_selected++;
3341- 2388
3342-/* Used from gtk_tree_selection_selected_foreach() */
3343-static void
3344-selection_check_foreach_cb (GtkTreeModel *model,
3345- GtkTreePath *path,
3346- GtkTreeIter *iter,
3347- gpointer data)
3348-{
3349- struct selection_check_closure *closure;
3350- GtkTreeIter child_iter;
3351- const GtkFileInfo *info;
3352- gboolean is_folder;
3353-
3354- closure = data;
3355- closure->num_selected++;
3356-
3357- switch (closure->impl->operation_mode) 2389- switch (closure->impl->operation_mode)
3358- { 2390- {
3359- case OPERATION_MODE_BROWSE: 2391- case OPERATION_MODE_BROWSE:
@@ -3361,14 +2393,17 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
3361- info = _gtk_file_system_model_get_info (closure->impl->browse_files_model, &child_iter); 2393- info = _gtk_file_system_model_get_info (closure->impl->browse_files_model, &child_iter);
3362- is_folder = info ? gtk_file_info_get_is_folder (info) : FALSE; 2394- is_folder = info ? gtk_file_info_get_is_folder (info) : FALSE;
3363- break; 2395- break;
3364- 2396+ gtk_tree_model_sort_convert_iter_to_child_iter (closure->impl->sort_model, &child_iter, iter);
2397
3365- case OPERATION_MODE_SEARCH: 2398- case OPERATION_MODE_SEARCH:
3366- search_get_valid_child_iter (closure->impl, &child_iter, iter); 2399- search_get_valid_child_iter (closure->impl, &child_iter, iter);
3367- gtk_tree_model_get (GTK_TREE_MODEL (closure->impl->search_model), &child_iter, 2400- gtk_tree_model_get (GTK_TREE_MODEL (closure->impl->search_model), &child_iter,
3368- SEARCH_MODEL_COL_IS_FOLDER, &is_folder, 2401- SEARCH_MODEL_COL_IS_FOLDER, &is_folder,
3369- -1); 2402- -1);
3370- break; 2403- break;
3371- 2404+ info = _gtk_file_system_model_get_info (closure->impl->browse_files_model, &child_iter);
2405+ is_folder = info ? gtk_file_info_get_is_folder (info) : FALSE;
2406
3372- case OPERATION_MODE_RECENT: 2407- case OPERATION_MODE_RECENT:
3373- recent_get_valid_child_iter (closure->impl, &child_iter, iter); 2408- recent_get_valid_child_iter (closure->impl, &child_iter, iter);
3374- gtk_tree_model_get (GTK_TREE_MODEL (closure->impl->recent_model), &child_iter, 2409- 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
3377- break; 2412- break;
3378- } 2413- }
3379- 2414-
3380- closure->all_folders = closure->all_folders && is_folder; 2415 closure->all_folders = closure->all_folders && is_folder;
3381- closure->all_files = closure->all_files && !is_folder; 2416 closure->all_files = closure->all_files && !is_folder;
3382-} 2417 }
3383- 2418@@ -2920,1126 +1159,6 @@
3384-/* Checks whether the selected items in the file list are all files or all folders */ 2419 const GtkFilePath *path;
3385-static void 2420 };
3386-selection_check (GtkFileChooserDefault *impl, 2421
3387- gint *num_selected,
3388- gboolean *all_files,
3389- gboolean *all_folders)
3390-{
3391- struct selection_check_closure closure;
3392- GtkTreeSelection *selection;
3393-
3394- closure.impl = impl;
3395- closure.num_selected = 0;
3396- closure.all_files = TRUE;
3397- closure.all_folders = TRUE;
3398-
3399- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_files_tree_view));
3400- gtk_tree_selection_selected_foreach (selection,
3401- selection_check_foreach_cb,
3402- &closure);
3403-
3404- g_assert (closure.num_selected == 0 || !(closure.all_files && closure.all_folders));
3405-
3406- if (num_selected)
3407- *num_selected = closure.num_selected;
3408-
3409- if (all_files)
3410- *all_files = closure.all_files;
3411-
3412- if (all_folders)
3413- *all_folders = closure.all_folders;
3414-}
3415-
3416-struct get_selected_path_closure {
3417- GtkFileChooserDefault *impl;
3418- const GtkFilePath *path;
3419-};
3420-
3421-static void 2422-static void
3422-get_selected_path_foreach_cb (GtkTreeModel *model, 2423-get_selected_path_foreach_cb (GtkTreeModel *model,
3423- GtkTreePath *path, 2424- GtkTreePath *path,
@@ -4538,22 +3539,13 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
4538- return vbox; 3539- return vbox;
4539-} 3540-}
4540- 3541-
4541-/* Handles key press events on the file list, so that we can trap Enter to 3542 /* Handles key press events on the file list, so that we can trap Enter to
4542- * activate the default button on our own. Also, checks to see if '/' has been 3543 * activate the default button on our own. Also, checks to see if '/' has been
4543- * pressed. See comment by tree_view_keybinding_cb() for more details. 3544 * pressed. See comment by tree_view_keybinding_cb() for more details.
4544- */ 3545@@ -4056,17 +1175,6 @@
4545-static gboolean 3546
4546-trap_activate_cb (GtkWidget *widget, 3547 modifiers = gtk_accelerator_get_default_mod_mask ();
4547- GdkEventKey *event, 3548
4548- gpointer data)
4549-{
4550- GtkFileChooserDefault *impl;
4551- int modifiers;
4552-
4553- impl = (GtkFileChooserDefault *) data;
4554-
4555- modifiers = gtk_accelerator_get_default_mod_mask ();
4556-
4557- if ((event->keyval == GDK_slash 3549- if ((event->keyval == GDK_slash
4558- || event->keyval == GDK_KP_Divide 3550- || event->keyval == GDK_KP_Divide
4559-#ifdef G_OS_UNIX 3551-#ifdef G_OS_UNIX
@@ -4565,37 +3557,25 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
4565- return TRUE; 3557- return TRUE;
4566- } 3558- }
4567- 3559-
4568- if ((event->keyval == GDK_Return 3560 if ((event->keyval == GDK_Return
4569- || event->keyval == GDK_ISO_Enter 3561 || event->keyval == GDK_ISO_Enter
4570- || event->keyval == GDK_KP_Enter 3562 || event->keyval == GDK_KP_Enter
4571- || event->keyval == GDK_space) 3563@@ -4091,474 +1199,66 @@
4572- && ((event->state & modifiers) == 0) 3564 return FALSE;
4573- && !(impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER || 3565 }
4574- impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)) 3566
4575- {
4576- GtkWindow *window;
4577-
4578- window = get_toplevel (widget);
4579- if (window
4580- && widget != window->default_widget
4581- && !(widget == window->focus_widget &&
4582- (!window->default_widget || !GTK_WIDGET_SENSITIVE (window->default_widget))))
4583- {
4584- gtk_window_activate_default (window);
4585- return TRUE;
4586- }
4587- }
4588-
4589- return FALSE;
4590-}
4591-
4592-/* Callback used when the file list's popup menu is detached */ 3567-/* Callback used when the file list's popup menu is detached */
4593-static void 3568-static void
4594-popup_menu_detach_cb (GtkWidget *attach_widget, 3569-popup_menu_detach_cb (GtkWidget *attach_widget,
4595- GtkMenu *menu) 3570- GtkMenu *menu)
4596-{ 3571+static gboolean
3572+list_button_press (GtkWidget *widget, GdkEventButton *event, gpointer data)
3573 {
4597- GtkFileChooserDefault *impl; 3574- GtkFileChooserDefault *impl;
4598- 3575+ GtkTreeView * tree = GTK_TREE_VIEW (widget);
3576+ GtkFileChooserDefault *impl = data;
3577+ GtkTreePath *path;
3578
4599- impl = g_object_get_data (G_OBJECT (attach_widget), "GtkFileChooserDefault"); 3579- impl = g_object_get_data (G_OBJECT (attach_widget), "GtkFileChooserDefault");
4600- g_assert (GTK_IS_FILE_CHOOSER_DEFAULT (impl)); 3580- g_assert (GTK_IS_FILE_CHOOSER_DEFAULT (impl));
4601- 3581-
@@ -4642,7 +3622,10 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
4642- GtkFileChooser *chooser = GTK_FILE_CHOOSER (impl); 3622- GtkFileChooser *chooser = GTK_FILE_CHOOSER (impl);
4643- 3623-
4644- for (i = 1; uris[i]; i++) 3624- for (i = 1; uris[i]; i++)
4645- { 3625+ if (event->type != GDK_BUTTON_PRESS ||
3626+ !gtk_tree_view_get_path_at_pos (tree, (gint)event->x, (gint)event->y,
3627+ &path, NULL, NULL, NULL))
3628 {
4646- GtkFilePath *path; 3629- GtkFilePath *path;
4647- 3630-
4648- uri = uris[i]; 3631- uri = uris[i];
@@ -4658,16 +3641,19 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
4658- 3641-
4659- gtk_file_path_free (path); 3642- gtk_file_path_free (path);
4660- } 3643- }
4661- } 3644+ return FALSE;
3645 }
4662-} 3646-}
4663- 3647
4664-struct FileListDragData 3648-struct FileListDragData
4665-{ 3649-{
4666- GtkFileChooserDefault *impl; 3650- GtkFileChooserDefault *impl;
4667- gchar **uris; 3651- gchar **uris;
4668- GtkFilePath *path; 3652- GtkFilePath *path;
4669-}; 3653-};
4670- 3654+ impl->list_press_time = event->time;
3655+ impl->list_press_path = path;
3656
4671-static void 3657-static void
4672-file_list_drag_data_received_get_info_cb (GtkFileSystemHandle *handle, 3658-file_list_drag_data_received_get_info_cb (GtkFileSystemHandle *handle,
4673- const GtkFileInfo *info, 3659- const GtkFileInfo *info,
@@ -4713,8 +3699,9 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
4713- g_free (data); 3699- g_free (data);
4714- 3700-
4715- g_object_unref (handle); 3701- g_object_unref (handle);
4716-} 3702+ return FALSE;
4717- 3703 }
3704
4718-static void 3705-static void
4719-file_list_drag_data_received_cb (GtkWidget *widget, 3706-file_list_drag_data_received_cb (GtkWidget *widget,
4720- GdkDragContext *context, 3707- GdkDragContext *context,
@@ -4783,18 +3770,23 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
4783-} 3770-}
4784- 3771-
4785-/* Don't do anything with the drag_drop signal */ 3772-/* Don't do anything with the drag_drop signal */
4786-static gboolean 3773 static gboolean
4787-file_list_drag_drop_cb (GtkWidget *widget, 3774-file_list_drag_drop_cb (GtkWidget *widget,
4788- GdkDragContext *context, 3775- GdkDragContext *context,
4789- gint x, 3776- gint x,
4790- gint y, 3777- gint y,
4791- guint time_, 3778- guint time_,
4792- GtkFileChooserDefault *impl) 3779- GtkFileChooserDefault *impl)
4793-{ 3780+list_button_release (GtkWidget *widget, GdkEventButton *event, gpointer data)
3781 {
4794- g_signal_stop_emission_by_name (widget, "drag_drop"); 3782- g_signal_stop_emission_by_name (widget, "drag_drop");
4795- return TRUE; 3783- return TRUE;
4796-} 3784-}
4797- 3785+ GtkTreeView * tree = GTK_TREE_VIEW (widget);
3786+ GtkFileChooserDefault *impl = data;
3787+ GtkTreePath *path = NULL;
3788+ gboolean retval = FALSE;
3789
4798-/* Disable the normal tree drag motion handler, it makes it look like you're 3790-/* Disable the normal tree drag motion handler, it makes it look like you're
4799- dropping the dragged item onto a tree item */ 3791- dropping the dragged item onto a tree item */
4800-static gboolean 3792-static gboolean
@@ -4907,15 +3899,21 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
4907- NULL, NULL, NULL, NULL, 3899- NULL, NULL, NULL, NULL,
4908- event->button, event->time); 3900- event->button, event->time);
4909- else 3901- else
4910- { 3902+ if (!impl->list_press_time ||
3903+ !impl->list_press_path ||
3904+ event->type != GDK_BUTTON_RELEASE ||
3905+ !gtk_tree_view_get_path_at_pos (tree, (gint)event->x, (gint)event->y,
3906+ &path, NULL, NULL, NULL))
3907 {
4911- gtk_menu_popup (GTK_MENU (impl->browse_files_popup_menu), 3908- gtk_menu_popup (GTK_MENU (impl->browse_files_popup_menu),
4912- NULL, NULL, 3909- NULL, NULL,
4913- popup_position_func, impl->browse_files_tree_view, 3910- popup_position_func, impl->browse_files_tree_view,
4914- 0, GDK_CURRENT_TIME); 3911- 0, GDK_CURRENT_TIME);
4915- gtk_menu_shell_select_first (GTK_MENU_SHELL (impl->browse_files_popup_menu), 3912- gtk_menu_shell_select_first (GTK_MENU_SHELL (impl->browse_files_popup_menu),
4916- FALSE); 3913- FALSE);
4917- } 3914+ goto done;
4918- 3915 }
3916
4919-} 3917-}
4920- 3918-
4921-/* Callback used for the GtkWidget::popup-menu signal of the file list */ 3919-/* Callback used for the GtkWidget::popup-menu signal of the file list */
@@ -4961,7 +3959,9 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
4961- name_id = mtime_id = 0; 3959- name_id = mtime_id = 0;
4962- 3960-
4963- switch (impl->operation_mode) 3961- switch (impl->operation_mode)
4964- { 3962+ if (event->time - impl->list_press_time > LONG_CLICK_LENGTH &&
3963+ !gtk_tree_path_compare (impl->list_press_path, path))
3964 {
4965- case OPERATION_MODE_BROWSE: 3965- case OPERATION_MODE_BROWSE:
4966- name_id = FILE_LIST_COL_NAME; 3966- name_id = FILE_LIST_COL_NAME;
4967- mtime_id = FILE_LIST_COL_MTIME; 3967- mtime_id = FILE_LIST_COL_MTIME;
@@ -4974,12 +3974,17 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
4974- name_id = RECENT_MODEL_COL_PATH; 3974- name_id = RECENT_MODEL_COL_PATH;
4975- mtime_id = RECENT_MODEL_COL_INFO; 3975- mtime_id = RECENT_MODEL_COL_INFO;
4976- break; 3976- break;
4977- } 3977+ retval = TRUE;
4978- 3978+ list_row_activated (tree, path, NULL, impl);
3979 }
3980
4979- gtk_tree_view_column_set_sort_column_id (impl->list_name_column, name_id); 3981- gtk_tree_view_column_set_sort_column_id (impl->list_name_column, name_id);
4980- gtk_tree_view_column_set_sort_column_id (impl->list_mtime_column, mtime_id); 3982- gtk_tree_view_column_set_sort_column_id (impl->list_mtime_column, mtime_id);
4981-} 3983-}
4982- 3984+ done:
3985+ if (path)
3986+ gtk_tree_path_free (path);
3987
4983-static gboolean 3988-static gboolean
4984-file_list_query_tooltip_cb (GtkWidget *widget, 3989-file_list_query_tooltip_cb (GtkWidget *widget,
4985- gint x, 3990- gint x,
@@ -4993,7 +3998,8 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
4993- GtkTreePath *path = NULL; 3998- GtkTreePath *path = NULL;
4994- GtkFilePath *file_path = NULL; 3999- GtkFilePath *file_path = NULL;
4995- gchar *filename; 4000- gchar *filename;
4996- 4001+ impl->list_press_time = 0;
4002
4997- if (impl->operation_mode == OPERATION_MODE_BROWSE) 4003- if (impl->operation_mode == OPERATION_MODE_BROWSE)
4998- return FALSE; 4004- return FALSE;
4999- 4005-
@@ -5007,7 +4013,8 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
5007- return FALSE; 4013- return FALSE;
5008- 4014-
5009- switch (impl->operation_mode) 4015- switch (impl->operation_mode)
5010- { 4016+ if (impl->list_press_path)
4017 {
5011- case OPERATION_MODE_SEARCH: 4018- case OPERATION_MODE_SEARCH:
5012- if (!gtk_tree_model_get_iter (GTK_TREE_MODEL (impl->search_model_sort), &iter, path)) 4019- if (!gtk_tree_model_get_iter (GTK_TREE_MODEL (impl->search_model_sort), &iter, path))
5013- { 4020- {
@@ -5037,8 +4044,10 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
5037- case OPERATION_MODE_BROWSE: 4044- case OPERATION_MODE_BROWSE:
5038- g_assert_not_reached (); 4045- g_assert_not_reached ();
5039- return FALSE; 4046- return FALSE;
5040- } 4047+ gtk_tree_path_free (impl->list_press_path);
5041- 4048+ impl->list_press_path = NULL;
4049 }
4050
5042- if (!file_path) 4051- if (!file_path)
5043- { 4052- {
5044- gtk_tree_path_free (path); 4053- gtk_tree_path_free (path);
@@ -5055,52 +4064,44 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
5055- gtk_tree_path_free (path); 4064- gtk_tree_path_free (path);
5056- 4065-
5057- return TRUE; 4066- return TRUE;
5058-} 4067+ return FALSE;
5059- 4068 }
5060-/* Creates the widgets for the file list */ 4069
5061-static GtkWidget * 4070+
5062-create_file_list (GtkFileChooserDefault *impl) 4071 /* Creates the widgets for the file list */
5063-{ 4072 static GtkWidget *
5064- GtkWidget *swin; 4073 create_file_list (GtkFileChooserDefault *impl)
5065- GtkTreeSelection *selection; 4074@@ -4572,7 +1272,7 @@
5066- GtkTreeViewColumn *column; 4075
5067- GtkCellRenderer *renderer; 4076 swin = gtk_scrolled_window_new (NULL, NULL);
5068- 4077 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (swin),
5069- /* Scrolled window */
5070-
5071- swin = gtk_scrolled_window_new (NULL, NULL);
5072- gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (swin),
5073- GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS); 4078- GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
5074- gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (swin), 4079+ GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
5075- GTK_SHADOW_IN); 4080 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (swin),
5076- 4081 GTK_SHADOW_IN);
5077- /* Tree/list view */ 4082
5078- 4083@@ -4588,41 +1288,19 @@
5079- impl->browse_files_tree_view = gtk_tree_view_new (); 4084 gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (impl->browse_files_tree_view), TRUE);
5080-#ifdef PROFILE_FILE_CHOOSER 4085 gtk_container_add (GTK_CONTAINER (swin), impl->browse_files_tree_view);
5081- g_object_set_data (G_OBJECT (impl->browse_files_tree_view), "fmq-name", "file_list"); 4086
5082-#endif
5083- g_object_set_data (G_OBJECT (impl->browse_files_tree_view), I_("GtkFileChooserDefault"), impl);
5084- atk_object_set_name (gtk_widget_get_accessible (impl->browse_files_tree_view), _("Files"));
5085-
5086- gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (impl->browse_files_tree_view), TRUE);
5087- gtk_container_add (GTK_CONTAINER (swin), impl->browse_files_tree_view);
5088-
5089- gtk_drag_dest_set (impl->browse_files_tree_view, 4087- gtk_drag_dest_set (impl->browse_files_tree_view,
5090- GTK_DEST_DEFAULT_ALL, 4088- GTK_DEST_DEFAULT_ALL,
5091- file_list_dest_targets, 4089- file_list_dest_targets,
5092- num_file_list_dest_targets, 4090- num_file_list_dest_targets,
5093- GDK_ACTION_COPY | GDK_ACTION_MOVE); 4091- GDK_ACTION_COPY | GDK_ACTION_MOVE);
5094- 4092-
5095- g_signal_connect (impl->browse_files_tree_view, "row_activated", 4093 g_signal_connect (impl->browse_files_tree_view, "row_activated",
5096- G_CALLBACK (list_row_activated), impl); 4094 G_CALLBACK (list_row_activated), impl);
5097- g_signal_connect (impl->browse_files_tree_view, "key_press_event", 4095 g_signal_connect (impl->browse_files_tree_view, "key_press_event",
5098- G_CALLBACK (trap_activate_cb), impl); 4096 G_CALLBACK (trap_activate_cb), impl);
5099- g_signal_connect (impl->browse_files_tree_view, "popup_menu", 4097- g_signal_connect (impl->browse_files_tree_view, "popup_menu",
5100- G_CALLBACK (list_popup_menu_cb), impl); 4098- G_CALLBACK (list_popup_menu_cb), impl);
5101- g_signal_connect (impl->browse_files_tree_view, "button_press_event", 4099 g_signal_connect (impl->browse_files_tree_view, "button_press_event",
5102- G_CALLBACK (list_button_press_event_cb), impl); 4100- G_CALLBACK (list_button_press_event_cb), impl);
5103- 4101+ G_CALLBACK (list_button_press), impl);
4102+ g_signal_connect (impl->browse_files_tree_view, "button_release_event",
4103+ G_CALLBACK (list_button_release), impl);
4104
5104- g_signal_connect (impl->browse_files_tree_view, "drag_data_received", 4105- g_signal_connect (impl->browse_files_tree_view, "drag_data_received",
5105- G_CALLBACK (file_list_drag_data_received_cb), impl); 4106- G_CALLBACK (file_list_drag_data_received_cb), impl);
5106- g_signal_connect (impl->browse_files_tree_view, "drag_drop", 4107- g_signal_connect (impl->browse_files_tree_view, "drag_drop",
@@ -5112,134 +4113,175 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
5112- g_signal_connect (impl->browse_files_tree_view, "query-tooltip", 4113- g_signal_connect (impl->browse_files_tree_view, "query-tooltip",
5113- G_CALLBACK (file_list_query_tooltip_cb), impl); 4114- G_CALLBACK (file_list_query_tooltip_cb), impl);
5114- 4115-
5115- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_files_tree_view)); 4116 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_files_tree_view));
5116- gtk_tree_selection_set_select_function (selection, 4117 gtk_tree_selection_set_select_function (selection,
5117- list_select_func, 4118 list_select_func,
5118- impl, NULL); 4119 impl, NULL);
5119- gtk_tree_view_enable_model_drag_source (GTK_TREE_VIEW (impl->browse_files_tree_view), 4120- gtk_tree_view_enable_model_drag_source (GTK_TREE_VIEW (impl->browse_files_tree_view),
5120- GDK_BUTTON1_MASK, 4121- GDK_BUTTON1_MASK,
5121- file_list_source_targets, 4122- file_list_source_targets,
5122- num_file_list_source_targets, 4123- num_file_list_source_targets,
5123- GDK_ACTION_COPY); 4124- GDK_ACTION_COPY);
4125
4126 g_signal_connect (selection, "changed",
4127 G_CALLBACK (list_selection_changed), impl);
4128@@ -4666,7 +1344,6 @@
4129 gtk_tree_view_column_set_sort_column_id (column, FILE_LIST_COL_SIZE);
4130 gtk_tree_view_append_column (GTK_TREE_VIEW (impl->browse_files_tree_view), column);
4131 #endif
5124- 4132-
5125- g_signal_connect (selection, "changed", 4133 /* Modification time column */
5126- G_CALLBACK (list_selection_changed), impl); 4134
5127- 4135 column = gtk_tree_view_column_new ();
5128- /* Filename column */ 4136@@ -4677,276 +1354,221 @@
5129- 4137 gtk_tree_view_column_pack_start (column, renderer, TRUE);
5130- impl->list_name_column = gtk_tree_view_column_new (); 4138 gtk_tree_view_column_set_cell_data_func (column, renderer,
5131- gtk_tree_view_column_set_expand (impl->list_name_column, TRUE); 4139 list_mtime_data_func, impl, NULL);
5132- gtk_tree_view_column_set_resizable (impl->list_name_column, TRUE); 4140+ gtk_tree_view_column_set_sort_column_id (column, FILE_LIST_COL_MTIME);
5133- gtk_tree_view_column_set_title (impl->list_name_column, _("Name")); 4141 gtk_tree_view_append_column (GTK_TREE_VIEW (impl->browse_files_tree_view), column);
5134- gtk_tree_view_column_set_sort_column_id (impl->list_name_column, FILE_LIST_COL_NAME);
5135-
5136- renderer = gtk_cell_renderer_pixbuf_new ();
5137- gtk_tree_view_column_pack_start (impl->list_name_column, renderer, FALSE);
5138- gtk_tree_view_column_set_cell_data_func (impl->list_name_column, renderer,
5139- list_icon_data_func, impl, NULL);
5140-
5141- impl->list_name_renderer = gtk_cell_renderer_text_new ();
5142- g_object_set (impl->list_name_renderer,
5143- "ellipsize", PANGO_ELLIPSIZE_END,
5144- NULL);
5145- g_signal_connect (impl->list_name_renderer, "edited",
5146- G_CALLBACK (renderer_edited_cb), impl);
5147- g_signal_connect (impl->list_name_renderer, "editing_canceled",
5148- G_CALLBACK (renderer_editing_canceled_cb), impl);
5149- gtk_tree_view_column_pack_start (impl->list_name_column, impl->list_name_renderer, TRUE);
5150- gtk_tree_view_column_set_cell_data_func (impl->list_name_column, impl->list_name_renderer,
5151- list_name_data_func, impl, NULL);
5152-
5153- gtk_tree_view_append_column (GTK_TREE_VIEW (impl->browse_files_tree_view), impl->list_name_column);
5154-#if 0
5155- /* Size column */
5156-
5157- column = gtk_tree_view_column_new ();
5158- gtk_tree_view_column_set_title (column, _("Size"));
5159-
5160- renderer = gtk_cell_renderer_text_new ();
5161- gtk_tree_view_column_pack_start (column, renderer, TRUE); /* bug: it doesn't expand */
5162- gtk_tree_view_column_set_cell_data_func (column, renderer,
5163- list_size_data_func, impl, NULL);
5164- gtk_tree_view_column_set_sort_column_id (column, FILE_LIST_COL_SIZE);
5165- gtk_tree_view_append_column (GTK_TREE_VIEW (impl->browse_files_tree_view), column);
5166-#endif
5167-
5168- /* Modification time column */
5169-
5170- column = gtk_tree_view_column_new ();
5171- gtk_tree_view_column_set_resizable (column, TRUE);
5172- gtk_tree_view_column_set_title (column, _("Modified"));
5173-
5174- renderer = gtk_cell_renderer_text_new ();
5175- gtk_tree_view_column_pack_start (column, renderer, TRUE);
5176- gtk_tree_view_column_set_cell_data_func (column, renderer,
5177- list_mtime_data_func, impl, NULL);
5178- gtk_tree_view_append_column (GTK_TREE_VIEW (impl->browse_files_tree_view), column);
5179- impl->list_mtime_column = column; 4142- impl->list_mtime_column = column;
5180- 4143-
5181- file_list_set_sort_column_ids (impl); 4144- file_list_set_sort_column_ids (impl);
5182- 4145-
5183- gtk_widget_show_all (swin); 4146 gtk_widget_show_all (swin);
5184- 4147
5185- return swin; 4148 return swin;
5186-} 4149 }
5187- 4150
5188-static GtkWidget * 4151-static GtkWidget *
5189-create_path_bar (GtkFileChooserDefault *impl) 4152-create_path_bar (GtkFileChooserDefault *impl)
5190-{ 4153+static void
4154+up_button_clicked_cb (GtkButton *button, gpointer data)
4155 {
5191- GtkWidget *path_bar; 4156- GtkWidget *path_bar;
5192- 4157+ GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (data);
4158+ up_folder_handler (impl);
4159+}
4160
5193- path_bar = g_object_new (GTK_TYPE_PATH_BAR, NULL); 4161- path_bar = g_object_new (GTK_TYPE_PATH_BAR, NULL);
5194- _gtk_path_bar_set_file_system (GTK_PATH_BAR (path_bar), impl->file_system); 4162- _gtk_path_bar_set_file_system (GTK_PATH_BAR (path_bar), impl->file_system);
5195- 4163+static void
4164+volume_button_clicked_cb (GtkButton *button, gpointer data)
4165+{
4166+ GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (data);
4167+ GtkFilePath * path = g_object_get_data (G_OBJECT (button), "file-path");
4168
5196- return path_bar; 4169- return path_bar;
5197-} 4170+ change_folder_and_display_error (impl, path);
5198- 4171 }
4172
5199-/* Creates the widgets for the files/folders pane */ 4173-/* Creates the widgets for the files/folders pane */
5200-static GtkWidget * 4174 static GtkWidget *
5201-file_pane_create (GtkFileChooserDefault *impl, 4175-file_pane_create (GtkFileChooserDefault *impl,
5202- GtkSizeGroup *size_group) 4176- GtkSizeGroup *size_group)
5203-{ 4177+create_bar (GtkFileChooserDefault *impl)
4178 {
5204- GtkWidget *vbox; 4179- GtkWidget *vbox;
5205- GtkWidget *hbox; 4180- GtkWidget *hbox;
5206- GtkWidget *widget; 4181- GtkWidget *widget;
5207- 4182+ GSList *list, *l;
4183+ int n;
4184+ GtkWidget *bar = gtk_hbox_new (FALSE, DEFAULT_SPACING);
4185+ GtkWidget *img;
4186+ GtkWidget *label;
4187
5208- vbox = gtk_vbox_new (FALSE, 6); 4188- vbox = gtk_vbox_new (FALSE, 6);
5209- gtk_widget_show (vbox); 4189- gtk_widget_show (vbox);
5210- 4190+ /* first the Up button */
4191+ img = gtk_image_new_from_stock (GTK_STOCK_GO_UP, GTK_ICON_SIZE_BUTTON);
4192+ gtk_widget_show (img);
4193
5211- /* Box for lists and preview */ 4194- /* Box for lists and preview */
5212- 4195+ impl->up_button = gtk_button_new ();
4196+ gtk_container_add (GTK_CONTAINER (impl->up_button), img);
4197+ gtk_widget_show (impl->up_button);
4198+ gtk_widget_set_sensitive (impl->up_button, FALSE);
4199+ gtk_button_set_focus_on_click (GTK_BUTTON (impl->up_button), FALSE);
4200
5213- hbox = gtk_hbox_new (FALSE, PREVIEW_HBOX_SPACING); 4201- hbox = gtk_hbox_new (FALSE, PREVIEW_HBOX_SPACING);
5214- gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 0); 4202- gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 0);
5215- gtk_widget_show (hbox); 4203- gtk_widget_show (hbox);
5216- 4204+ g_signal_connect (impl->up_button, "clicked",
4205+ G_CALLBACK (up_button_clicked_cb), impl);
4206+ gtk_box_pack_start (GTK_BOX(bar), impl->up_button, FALSE, FALSE, 0);
4207
5217- /* File list */ 4208- /* File list */
5218- 4209+ impl->num_volumes = 0;
4210+ list = gtk_file_system_list_volumes (impl->file_system);
4211
5219- widget = create_file_list (impl); 4212- widget = create_file_list (impl);
5220- gtk_box_pack_start (GTK_BOX (hbox), widget, TRUE, TRUE, 0); 4213- gtk_box_pack_start (GTK_BOX (hbox), widget, TRUE, TRUE, 0);
5221- 4214+ n = 0;
4215
5222- /* Preview */ 4216- /* Preview */
5223- 4217+ for (l = list; l; l = l->next, n++)
4218+ {
4219+ GtkFileSystemVolume *volume;
4220+ GdkPixbuf *pixbuf;
4221+ GtkWidget *button;
4222+ GtkWidget *image;
4223+ GtkFilePath *base_path;
4224+ gchar * file_name = NULL;
4225
5224- impl->preview_box = gtk_vbox_new (FALSE, 12); 4226- impl->preview_box = gtk_vbox_new (FALSE, 12);
5225- gtk_box_pack_start (GTK_BOX (hbox), impl->preview_box, FALSE, FALSE, 0); 4227- gtk_box_pack_start (GTK_BOX (hbox), impl->preview_box, FALSE, FALSE, 0);
5226- /* Don't show preview box initially */ 4228- /* Don't show preview box initially */
5227- 4229+ volume = l->data;
4230+ base_path =
4231+ gtk_file_system_volume_get_base_path (impl->file_system, volume);
4232
5228- /* Filter combo */ 4233- /* Filter combo */
5229- 4234+ if (impl->local_only)
4235+ {
4236+ gboolean is_local =
4237+ gtk_file_system_path_is_local (impl->file_system, base_path);
4238
5230- impl->filter_combo_hbox = gtk_hbox_new (FALSE, 12); 4239- impl->filter_combo_hbox = gtk_hbox_new (FALSE, 12);
5231- 4240+ if (!is_local)
4241+ {
4242+ gtk_file_path_free (base_path);
4243+ gtk_file_system_volume_free (impl->file_system, volume);
4244+ continue;
4245+ }
4246+ }
4247
5232- widget = filter_create (impl); 4248- widget = filter_create (impl);
5233- 4249+#if 0
4250+ label_copy =
4251+ gtk_file_system_volume_get_display_name (impl->file_system, volume);
4252+#endif
4253+ pixbuf =
4254+ gtk_file_system_volume_render_icon (impl->file_system, volume,
4255+ GTK_WIDGET (impl),
4256+ impl->icon_size, NULL);
4257
5234- gtk_widget_show (widget); 4258- gtk_widget_show (widget);
5235- gtk_box_pack_end (GTK_BOX (impl->filter_combo_hbox), widget, FALSE, FALSE, 0); 4259- gtk_box_pack_end (GTK_BOX (impl->filter_combo_hbox), widget, FALSE, FALSE, 0);
5236- 4260+ button = gtk_button_new ();
4261+ image = gtk_image_new_from_pixbuf (pixbuf);
4262+ g_object_unref (G_OBJECT (pixbuf));
4263+ gtk_container_add (GTK_CONTAINER (button), image);
4264+ gtk_button_set_focus_on_click (GTK_BUTTON (button), FALSE);
4265
5237- gtk_size_group_add_widget (size_group, impl->filter_combo_hbox); 4266- gtk_size_group_add_widget (size_group, impl->filter_combo_hbox);
5238- gtk_box_pack_end (GTK_BOX (vbox), impl->filter_combo_hbox, FALSE, FALSE, 0); 4267- gtk_box_pack_end (GTK_BOX (vbox), impl->filter_combo_hbox, FALSE, FALSE, 0);
5239- 4268+ file_name =
4269+ gtk_file_system_path_to_filename (impl->file_system, base_path);
4270
5240- return vbox; 4271- return vbox;
5241-} 4272-}
5242- 4273+ if (file_name && impl->root_folder &&
4274+ strcmp (file_name, impl->root_folder) &&
4275+ !strncmp (file_name, impl->root_folder, strlen (file_name)))
4276+ {
4277+ /* The base path is below the root folder; we replace it with
4278+ * the root folder
4279+ */
4280+ gtk_file_path_free (base_path);
4281+ base_path = gtk_file_system_filename_to_path (impl->file_system,
4282+ impl->root_folder);
4283+ }
4284
5243-/* Callback used when the "Browse for more folders" expander is toggled */ 4285-/* Callback used when the "Browse for more folders" expander is toggled */
5244-static void 4286-static void
5245-expander_changed_cb (GtkExpander *expander, 4287-expander_changed_cb (GtkExpander *expander,
@@ -5249,17 +4291,22 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
5249- impl->expand_folders = gtk_expander_get_expanded(GTK_EXPANDER (impl->save_expander)); 4291- impl->expand_folders = gtk_expander_get_expanded(GTK_EXPANDER (impl->save_expander));
5250- update_appearance (impl); 4292- update_appearance (impl);
5251-} 4293-}
5252- 4294+ g_free (file_name);
4295+ gtk_widget_show_all (button);
4296
5253-/* Callback used when the selection changes in the save folder combo box */ 4297-/* Callback used when the selection changes in the save folder combo box */
5254-static void 4298-static void
5255-save_folder_combo_changed_cb (GtkComboBox *combo, 4299-save_folder_combo_changed_cb (GtkComboBox *combo,
5256- GtkFileChooserDefault *impl) 4300- GtkFileChooserDefault *impl)
5257-{ 4301-{
5258- GtkTreeIter iter; 4302- GtkTreeIter iter;
5259- 4303+ g_object_set_data (G_OBJECT (button), "file-path", base_path);
4304
5260- if (impl->changing_folder) 4305- if (impl->changing_folder)
5261- return; 4306- return;
5262- 4307+ g_signal_connect (button, "clicked",
4308+ G_CALLBACK (volume_button_clicked_cb), impl);
4309
5263- if (gtk_combo_box_get_active_iter (combo, &iter)) 4310- if (gtk_combo_box_get_active_iter (combo, &iter))
5264- { 4311- {
5265- GtkTreeIter child_iter; 4312- GtkTreeIter child_iter;
@@ -5270,7 +4317,9 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
5270- shortcuts_activate_iter (impl, &child_iter); 4317- shortcuts_activate_iter (impl, &child_iter);
5271- } 4318- }
5272-} 4319-}
5273- 4320+ gtk_box_pack_start (GTK_BOX(bar), button, FALSE, FALSE, 0);
4321+ }
4322
5274-/* Filter function used to filter out the Search item and its separator. 4323-/* Filter function used to filter out the Search item and its separator.
5275- * Used for the "Save in folder" combo box, so that these items do not appear in it. 4324- * Used for the "Save in folder" combo box, so that these items do not appear in it.
5276- */ 4325- */
@@ -5284,14 +4333,25 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
5284- gint *indices; 4333- gint *indices;
5285- int idx; 4334- int idx;
5286- gboolean retval; 4335- gboolean retval;
5287- 4336+ impl->num_volumes = n;
4337+ g_slist_free (list);
4338
5288- impl = GTK_FILE_CHOOSER_DEFAULT (data); 4339- impl = GTK_FILE_CHOOSER_DEFAULT (data);
5289- 4340+ label = impl->location_label = gtk_label_new (NULL);
4341+ gtk_label_set_ellipsize (GTK_LABEL (label), PANGO_ELLIPSIZE_START);
4342+ gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5);
4343+ gtk_label_set_text (GTK_LABEL (label), impl->root_folder);
4344+ gtk_widget_show (label);
4345+ gtk_box_pack_start (GTK_BOX(bar), label, TRUE, TRUE, 0);
4346
5290- g_assert (model == GTK_TREE_MODEL (impl->shortcuts_model)); 4347- g_assert (model == GTK_TREE_MODEL (impl->shortcuts_model));
5291- 4348+ gtk_widget_show (bar);
4349
5292- tree_path = gtk_tree_model_get_path (GTK_TREE_MODEL (impl->shortcuts_model), iter); 4350- tree_path = gtk_tree_model_get_path (GTK_TREE_MODEL (impl->shortcuts_model), iter);
5293- g_assert (tree_path != NULL); 4351- g_assert (tree_path != NULL);
5294- 4352+ return bar;
4353+}
4354
5295- indices = gtk_tree_path_get_indices (tree_path); 4355- indices = gtk_tree_path_get_indices (tree_path);
5296- 4356-
5297- retval = TRUE; 4357- retval = TRUE;
@@ -5322,24 +4382,44 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
5322- } 4382- }
5323- 4383-
5324-/* Creates the combo box with the save folders */ 4384-/* Creates the combo box with the save folders */
5325-static GtkWidget * 4385+/* Creates the widgets for the files/folders pane */
4386 static GtkWidget *
5326-save_folder_combo_create (GtkFileChooserDefault *impl) 4387-save_folder_combo_create (GtkFileChooserDefault *impl)
5327-{ 4388+file_pane_create (GtkFileChooserDefault *impl)
4389 {
5328- GtkWidget *combo; 4390- GtkWidget *combo;
5329- GtkCellRenderer *cell; 4391- GtkCellRenderer *cell;
5330- 4392+ GtkWidget *vbox;
4393+ GtkWidget *hbox;
4394+ GtkWidget *widget;
4395+ vbox = gtk_vbox_new (FALSE, DEFAULT_SPACING);
4396+ gtk_widget_show (vbox);
4397
5331- impl->shortcuts_combo_filter_model = gtk_tree_model_filter_new (GTK_TREE_MODEL (impl->shortcuts_model), NULL); 4398- impl->shortcuts_combo_filter_model = gtk_tree_model_filter_new (GTK_TREE_MODEL (impl->shortcuts_model), NULL);
5332- gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (impl->shortcuts_combo_filter_model), 4399- gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (impl->shortcuts_combo_filter_model),
5333- shortcuts_combo_filter_func, 4400- shortcuts_combo_filter_func,
5334- impl, 4401- impl,
5335- NULL); 4402- NULL);
5336- 4403+ /* The volume bar and 'Create Folder' button */
4404+ hbox = gtk_hbox_new (FALSE, DEFAULT_SPACING);
4405+ gtk_widget_show (hbox);
4406+ impl->bar = create_bar (impl);
4407+ gtk_widget_show_all (impl->bar);
4408+ gtk_box_pack_start (GTK_BOX (hbox), impl->bar, TRUE, TRUE, 0);
4409
5337- combo = g_object_new (GTK_TYPE_COMBO_BOX, 4410- combo = g_object_new (GTK_TYPE_COMBO_BOX,
5338- "model", impl->shortcuts_combo_filter_model, 4411- "model", impl->shortcuts_combo_filter_model,
5339- "focus-on-click", FALSE, 4412- "focus-on-click", FALSE,
5340- NULL); 4413- NULL);
5341- gtk_widget_show (combo); 4414- gtk_widget_show (combo);
5342- 4415+ /* Create Folder */
4416+ widget = gtk_image_new_from_icon_name ("folder-new", GTK_ICON_SIZE_BUTTON);
4417+ gtk_widget_show (widget);
4418+ impl->browse_new_folder_button = gtk_button_new ();
4419+ gtk_container_add (GTK_CONTAINER (impl->browse_new_folder_button), widget);
4420+ gtk_button_set_focus_on_click (GTK_BUTTON (impl->browse_new_folder_button),
4421+ FALSE);
4422
5343- cell = gtk_cell_renderer_pixbuf_new (); 4423- cell = gtk_cell_renderer_pixbuf_new ();
5344- gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo), cell, FALSE); 4424- gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo), cell, FALSE);
5345- gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo), cell, 4425- gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo), cell,
@@ -5347,36 +4427,57 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
5347- "visible", SHORTCUTS_COL_PIXBUF_VISIBLE, 4427- "visible", SHORTCUTS_COL_PIXBUF_VISIBLE,
5348- "sensitive", SHORTCUTS_COL_PIXBUF_VISIBLE, 4428- "sensitive", SHORTCUTS_COL_PIXBUF_VISIBLE,
5349- NULL); 4429- NULL);
5350- 4430+ g_signal_connect (impl->browse_new_folder_button, "clicked",
4431+ G_CALLBACK (new_folder_button_clicked), impl);
4432+ gtk_box_pack_end (GTK_BOX (hbox), impl->browse_new_folder_button, FALSE, FALSE, 0);
4433
5351- cell = gtk_cell_renderer_text_new (); 4434- cell = gtk_cell_renderer_text_new ();
5352- gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo), cell, TRUE); 4435- gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo), cell, TRUE);
5353- gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo), cell, 4436- gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo), cell,
5354- "text", SHORTCUTS_COL_NAME, 4437- "text", SHORTCUTS_COL_NAME,
5355- "sensitive", SHORTCUTS_COL_PIXBUF_VISIBLE, 4438- "sensitive", SHORTCUTS_COL_PIXBUF_VISIBLE,
5356- NULL); 4439- NULL);
5357- 4440+ widget = filter_create (impl);
4441+ gtk_widget_hide (widget);
4442+ gtk_box_pack_end (GTK_BOX (hbox), widget, FALSE, FALSE, 0);
4443
5358- gtk_combo_box_set_row_separator_func (GTK_COMBO_BOX (combo), 4444- gtk_combo_box_set_row_separator_func (GTK_COMBO_BOX (combo),
5359- shortcuts_row_separator_func, 4445- shortcuts_row_separator_func,
5360- NULL, NULL); 4446- NULL, NULL);
5361- 4447+ gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
4448
5362- g_signal_connect (combo, "changed", 4449- g_signal_connect (combo, "changed",
5363- G_CALLBACK (save_folder_combo_changed_cb), impl); 4450- G_CALLBACK (save_folder_combo_changed_cb), impl);
5364- 4451+ /* Box for lists */
4452+ hbox = gtk_hbox_new (FALSE, LIST_HBOX_SPACING);
4453+ gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 0);
4454+ gtk_widget_show (hbox);
4455
5365- return combo; 4456- return combo;
5366-} 4457+ /* File list */
5367- 4458+
5368-/* Creates the widgets specific to Save mode */ 4459+ widget = create_file_list (impl);
4460+ gtk_box_pack_start (GTK_BOX (hbox), widget, TRUE, TRUE, 0);
4461+
4462+ return vbox;
4463 }
4464
4465 /* Creates the widgets specific to Save mode */
5369-static void 4466-static void
5370-save_widgets_create (GtkFileChooserDefault *impl) 4467+static GtkWidget *
5371-{ 4468 save_widgets_create (GtkFileChooserDefault *impl)
5372- GtkWidget *vbox; 4469 {
4470 GtkWidget *vbox;
5373- GtkWidget *table; 4471- GtkWidget *table;
5374- GtkWidget *widget; 4472+ GtkWidget *hbox;
4473 GtkWidget *widget;
5375- GtkWidget *alignment; 4474- GtkWidget *alignment;
5376- 4475
5377- if (impl->save_widgets != NULL) 4476- if (impl->save_widgets != NULL)
5378- return; 4477- return;
5379- 4478+ vbox = gtk_vbox_new (FALSE, 0);
4479+ hbox = gtk_hbox_new (FALSE, DEFAULT_SPACING);
4480
5380- location_switch_to_path_bar (impl); 4481- location_switch_to_path_bar (impl);
5381- 4482-
5382- vbox = gtk_vbox_new (FALSE, 12); 4483- vbox = gtk_vbox_new (FALSE, 12);
@@ -5390,27 +4491,33 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
5390- /* Label */ 4491- /* Label */
5391- 4492-
5392- widget = gtk_label_new_with_mnemonic (_("_Name:")); 4493- widget = gtk_label_new_with_mnemonic (_("_Name:"));
5393- gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5); 4494+ widget = gtk_label_new (_("Name:"));
4495 gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5);
5394- gtk_table_attach (GTK_TABLE (table), widget, 4496- gtk_table_attach (GTK_TABLE (table), widget,
5395- 0, 1, 0, 1, 4497- 0, 1, 0, 1,
5396- GTK_FILL, GTK_FILL, 4498- GTK_FILL, GTK_FILL,
5397- 0, 0); 4499- 0, 0);
5398- gtk_widget_show (widget); 4500+ gtk_box_pack_start (GTK_BOX (hbox), widget, FALSE, FALSE, 0);
5399- 4501 gtk_widget_show (widget);
4502
5400- /* Location entry */ 4503- /* Location entry */
5401- 4504-
5402- impl->location_entry = _gtk_file_chooser_entry_new (TRUE); 4505 impl->location_entry = _gtk_file_chooser_entry_new (TRUE);
5403- _gtk_file_chooser_entry_set_file_system (GTK_FILE_CHOOSER_ENTRY (impl->location_entry), 4506 _gtk_file_chooser_entry_set_file_system (GTK_FILE_CHOOSER_ENTRY (impl->location_entry),
5404- impl->file_system); 4507 impl->file_system);
5405- gtk_entry_set_width_chars (GTK_ENTRY (impl->location_entry), 45); 4508- gtk_entry_set_width_chars (GTK_ENTRY (impl->location_entry), 45);
5406- gtk_entry_set_activates_default (GTK_ENTRY (impl->location_entry), TRUE); 4509+/* gtk_entry_set_width_chars (GTK_ENTRY (impl->location_entry), 45); */
4510 gtk_entry_set_activates_default (GTK_ENTRY (impl->location_entry), TRUE);
5407- gtk_table_attach (GTK_TABLE (table), impl->location_entry, 4511- gtk_table_attach (GTK_TABLE (table), impl->location_entry,
5408- 1, 2, 0, 1, 4512- 1, 2, 0, 1,
5409- GTK_EXPAND | GTK_FILL, 0, 4513- GTK_EXPAND | GTK_FILL, 0,
5410- 0, 0); 4514- 0, 0);
5411- gtk_widget_show (impl->location_entry); 4515+ gtk_box_pack_start (GTK_BOX (hbox), impl->location_entry,
4516+ TRUE, TRUE, 0);
4517+
4518 gtk_widget_show (impl->location_entry);
5412- gtk_label_set_mnemonic_widget (GTK_LABEL (widget), impl->location_entry); 4519- gtk_label_set_mnemonic_widget (GTK_LABEL (widget), impl->location_entry);
5413- 4520
5414- /* Folder combo */ 4521- /* Folder combo */
5415- impl->save_folder_label = gtk_label_new (NULL); 4522- impl->save_folder_label = gtk_label_new (NULL);
5416- gtk_misc_set_alignment (GTK_MISC (impl->save_folder_label), 0.0, 0.5); 4523- 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
5419- GTK_FILL, GTK_FILL, 4526- GTK_FILL, GTK_FILL,
5420- 0, 0); 4527- 0, 0);
5421- gtk_widget_show (impl->save_folder_label); 4528- gtk_widget_show (impl->save_folder_label);
5422- 4529+ gtk_widget_show (hbox);
4530+ gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
4531
5423- impl->save_folder_combo = save_folder_combo_create (impl); 4532- impl->save_folder_combo = save_folder_combo_create (impl);
5424- gtk_table_attach (GTK_TABLE (table), impl->save_folder_combo, 4533- gtk_table_attach (GTK_TABLE (table), impl->save_folder_combo,
5425- 1, 2, 1, 2, 4534- 1, 2, 1, 2,
@@ -5442,23 +4551,23 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
5442- gtk_box_pack_start (GTK_BOX (impl), impl->save_widgets, FALSE, FALSE, 0); 4551- gtk_box_pack_start (GTK_BOX (impl), impl->save_widgets, FALSE, FALSE, 0);
5443- gtk_box_reorder_child (GTK_BOX (impl), impl->save_widgets, 0); 4552- gtk_box_reorder_child (GTK_BOX (impl), impl->save_widgets, 0);
5444- gtk_widget_show (impl->save_widgets); 4553- gtk_widget_show (impl->save_widgets);
5445-} 4554+ return vbox;
5446- 4555 }
5447-/* Destroys the widgets specific to Save mode */ 4556
5448-static void 4557 /* Destroys the widgets specific to Save mode */
5449-save_widgets_destroy (GtkFileChooserDefault *impl) 4558+/* ??? */
5450-{ 4559 static void
5451- if (impl->save_widgets == NULL) 4560 save_widgets_destroy (GtkFileChooserDefault *impl)
5452- return; 4561 {
5453- 4562@@ -4956,313 +1578,17 @@
5454- gtk_widget_destroy (impl->save_widgets); 4563 gtk_widget_destroy (impl->save_widgets);
5455- impl->save_widgets = NULL; 4564 impl->save_widgets = NULL;
5456- impl->location_entry = NULL; 4565 impl->location_entry = NULL;
5457- impl->save_folder_label = NULL; 4566- impl->save_folder_label = NULL;
5458- impl->save_folder_combo = NULL; 4567- impl->save_folder_combo = NULL;
5459- impl->save_expander = NULL; 4568- impl->save_expander = NULL;
5460-} 4569 }
5461- 4570
5462-/* Turns on the path bar widget. Can be called even if we are already in that 4571-/* Turns on the path bar widget. Can be called even if we are already in that
5463- * mode. 4572- * mode.
5464- */ 4573- */
@@ -5703,20 +4812,21 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
5703- atk_object_set_name (gtk_widget_get_accessible (impl->location_button), str); 4812- atk_object_set_name (gtk_widget_get_accessible (impl->location_button), str);
5704-} 4813-}
5705- 4814-
5706-/* Creates the main hpaned with the widgets shared by Open and Save mode */ 4815 /* Creates the main hpaned with the widgets shared by Open and Save mode */
5707-static GtkWidget * 4816 static GtkWidget *
5708-browse_widgets_create (GtkFileChooserDefault *impl) 4817 browse_widgets_create (GtkFileChooserDefault *impl)
5709-{ 4818 {
5710- GtkWidget *vbox; 4819- GtkWidget *vbox;
5711- GtkWidget *hbox; 4820- GtkWidget *hbox;
5712- GtkWidget *hpaned; 4821- GtkWidget *hpaned;
5713- GtkWidget *widget; 4822 GtkWidget *widget;
5714- GtkSizeGroup *size_group; 4823- GtkSizeGroup *size_group;
5715- 4824
5716- /* size group is used by the [+][-] buttons and the filter combo */ 4825- /* size group is used by the [+][-] buttons and the filter combo */
5717- size_group = gtk_size_group_new (GTK_SIZE_GROUP_VERTICAL); 4826- size_group = gtk_size_group_new (GTK_SIZE_GROUP_VERTICAL);
5718- vbox = gtk_vbox_new (FALSE, 12); 4827- vbox = gtk_vbox_new (FALSE, 12);
5719- 4828+ widget = file_pane_create (impl);
4829
5720- /* Location widgets */ 4830- /* Location widgets */
5721- hbox = gtk_hbox_new (FALSE, 12); 4831- hbox = gtk_hbox_new (FALSE, 12);
5722- gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0); 4832- gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
@@ -5761,51 +4871,40 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
5761- g_object_unref (size_group); 4871- g_object_unref (size_group);
5762- 4872-
5763- return vbox; 4873- return vbox;
5764-} 4874+ return widget;
5765- 4875 }
5766-static GObject* 4876
5767-gtk_file_chooser_default_constructor (GType type, 4877 static GObject*
5768- guint n_construct_properties, 4878@@ -5284,20 +1610,14 @@
5769- GObjectConstructParam *construct_params) 4879
5770-{ 4880 gtk_widget_push_composite_child ();
5771- GtkFileChooserDefault *impl; 4881
5772- GObject *object;
5773-
5774- profile_start ("start", NULL);
5775-
5776- object = G_OBJECT_CLASS (_gtk_file_chooser_default_parent_class)->constructor (type,
5777- n_construct_properties,
5778- construct_params);
5779- impl = GTK_FILE_CHOOSER_DEFAULT (object);
5780-
5781- g_assert (impl->file_system);
5782-
5783- gtk_widget_push_composite_child ();
5784-
5785- /* Recent files manager */ 4882- /* Recent files manager */
5786- recent_manager_update (impl); 4883- recent_manager_update (impl);
5787- 4884+ /* Widgets for Save mode */
4885+ impl->save_widgets = save_widgets_create (impl);
4886+ gtk_box_pack_start (GTK_BOX (impl), impl->save_widgets, FALSE, FALSE, 0);
4887
5788- /* Shortcuts model */ 4888- /* Shortcuts model */
5789- shortcuts_model_create (impl); 4889- shortcuts_model_create (impl);
5790- 4890-
5791- /* The browse widgets */ 4891 /* The browse widgets */
5792- impl->browse_widgets = browse_widgets_create (impl); 4892 impl->browse_widgets = browse_widgets_create (impl);
5793- gtk_box_pack_start (GTK_BOX (impl), impl->browse_widgets, TRUE, TRUE, 0); 4893 gtk_box_pack_start (GTK_BOX (impl), impl->browse_widgets, TRUE, TRUE, 0);
5794- 4894
5795- /* Alignment to hold extra widget */ 4895- /* Alignment to hold extra widget */
5796- impl->extra_align = gtk_alignment_new (0.0, 0.5, 1.0, 1.0); 4896- impl->extra_align = gtk_alignment_new (0.0, 0.5, 1.0, 1.0);
5797- gtk_box_pack_start (GTK_BOX (impl), impl->extra_align, FALSE, FALSE, 0); 4897- gtk_box_pack_start (GTK_BOX (impl), impl->extra_align, FALSE, FALSE, 0);
5798- 4898-
5799- gtk_widget_pop_composite_child (); 4899 gtk_widget_pop_composite_child ();
5800- update_appearance (impl); 4900 update_appearance (impl);
5801- 4901
5802- profile_end ("end", NULL); 4902@@ -5306,35 +1626,7 @@
5803- 4903 return object;
5804- return object; 4904 }
5805-} 4905
5806-
5807-/* Sets the extra_widget by packing it in the appropriate place */ 4906-/* Sets the extra_widget by packing it in the appropriate place */
5808-static void 4907 static void
5809-set_extra_widget (GtkFileChooserDefault *impl, 4908-set_extra_widget (GtkFileChooserDefault *impl,
5810- GtkWidget *extra_widget) 4909- GtkWidget *extra_widget)
5811-{ 4910-{
@@ -5833,48 +4932,30 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
5833-} 4932-}
5834- 4933-
5835-static void 4934-static void
5836-set_local_only (GtkFileChooserDefault *impl, 4935 set_local_only (GtkFileChooserDefault *impl,
5837- gboolean local_only) 4936 gboolean local_only)
5838-{ 4937 {
5839- if (local_only != impl->local_only) 4938@@ -5342,12 +1634,6 @@
5840- { 4939 {
5841- impl->local_only = local_only; 4940 impl->local_only = local_only;
5842- 4941
5843- if (impl->shortcuts_model && impl->file_system) 4942- if (impl->shortcuts_model && impl->file_system)
5844- { 4943- {
5845- shortcuts_add_volumes (impl); 4944- shortcuts_add_volumes (impl);
5846- shortcuts_add_bookmarks (impl); 4945- shortcuts_add_bookmarks (impl);
5847- } 4946- }
5848- 4947-
5849- if (local_only && 4948 if (local_only &&
5850- !gtk_file_system_path_is_local (impl->file_system, impl->current_folder)) 4949 !gtk_file_system_path_is_local (impl->file_system, impl->current_folder))
5851- { 4950 {
5852- /* If we are pointing to a non-local folder, make an effort to change 4951@@ -5374,21 +1660,9 @@
5853- * back to a local folder, but it's really up to the app to not cause 4952 volumes_changed_cb (GtkFileSystem *file_system,
5854- * such a situation, so we ignore errors. 4953 GtkFileChooserDefault *impl)
5855- */ 4954 {
5856- const gchar *home = g_get_home_dir ();
5857- GtkFilePath *home_path;
5858-
5859- if (home == NULL)
5860- return;
5861-
5862- home_path = gtk_file_system_filename_to_path (impl->file_system, home);
5863-
5864- _gtk_file_chooser_set_current_folder_path (GTK_FILE_CHOOSER (impl), home_path, NULL);
5865-
5866- gtk_file_path_free (home_path);
5867- }
5868- }
5869-}
5870-
5871-static void
5872-volumes_changed_cb (GtkFileSystem *file_system,
5873- GtkFileChooserDefault *impl)
5874-{
5875- shortcuts_add_volumes (impl); 4955- shortcuts_add_volumes (impl);
5876-} 4956+ /* FIXME -- update the bar */
5877- 4957 }
4958
5878-/* Callback used when the set of bookmarks changes in the file system */ 4959-/* Callback used when the set of bookmarks changes in the file system */
5879-static void 4960-static void
5880-bookmarks_changed_cb (GtkFileSystem *file_system, 4961-bookmarks_changed_cb (GtkFileSystem *file_system,
@@ -5887,97 +4968,67 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
5887- shortcuts_check_popup_sensitivity (impl); 4968- shortcuts_check_popup_sensitivity (impl);
5888-} 4969-}
5889- 4970-
5890-/* Sets the file chooser to multiple selection mode */ 4971 /* Sets the file chooser to multiple selection mode */
5891-static void 4972 static void
5892-set_select_multiple (GtkFileChooserDefault *impl, 4973 set_select_multiple (GtkFileChooserDefault *impl,
5893- gboolean select_multiple, 4974@@ -5408,8 +1682,6 @@
5894- gboolean property_notify) 4975
5895-{ 4976 impl->select_multiple = select_multiple;
5896- GtkTreeSelection *selection; 4977 g_object_notify (G_OBJECT (impl), "select-multiple");
5897- GtkSelectionMode mode;
5898-
5899- if (select_multiple == impl->select_multiple)
5900- return;
5901-
5902- mode = select_multiple ? GTK_SELECTION_MULTIPLE : GTK_SELECTION_BROWSE;
5903-
5904- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_files_tree_view));
5905- gtk_tree_selection_set_mode (selection, mode);
5906-
5907- impl->select_multiple = select_multiple;
5908- g_object_notify (G_OBJECT (impl), "select-multiple");
5909- 4978-
5910- check_preview_change (impl); 4979- check_preview_change (impl);
5911-} 4980 }
5912- 4981
5913-static void 4982 static void
5914-set_file_system_backend (GtkFileChooserDefault *impl, 4983@@ -5422,8 +1694,6 @@
5915- const char *backend) 4984 {
5916-{ 4985 g_signal_handler_disconnect (impl->file_system, impl->volumes_changed_id);
5917- profile_start ("start for backend", backend ? backend : "default"); 4986 impl->volumes_changed_id = 0;
5918-
5919- if (impl->file_system)
5920- {
5921- g_signal_handler_disconnect (impl->file_system, impl->volumes_changed_id);
5922- impl->volumes_changed_id = 0;
5923- g_signal_handler_disconnect (impl->file_system, impl->bookmarks_changed_id); 4987- g_signal_handler_disconnect (impl->file_system, impl->bookmarks_changed_id);
5924- impl->bookmarks_changed_id = 0; 4988- impl->bookmarks_changed_id = 0;
5925- g_object_unref (impl->file_system); 4989 g_object_unref (impl->file_system);
5926- } 4990 }
5927- 4991
5928- impl->file_system = NULL; 4992@@ -5459,14 +1729,28 @@
5929- if (backend) 4993 impl->volumes_changed_id = g_signal_connect (impl->file_system, "volumes-changed",
5930- impl->file_system = gtk_file_system_create (backend); 4994 G_CALLBACK (volumes_changed_cb),
5931- else 4995 impl);
5932- {
5933- GtkSettings *settings = gtk_settings_get_default ();
5934- gchar *default_backend = NULL;
5935-
5936- g_object_get (settings, "gtk-file-chooser-backend", &default_backend, NULL);
5937- if (default_backend)
5938- {
5939- impl->file_system = gtk_file_system_create (default_backend);
5940- g_free (default_backend);
5941- }
5942- }
5943-
5944- if (!impl->file_system)
5945- {
5946-#if defined (G_OS_UNIX)
5947- impl->file_system = gtk_file_system_unix_new ();
5948-#elif defined (G_OS_WIN32)
5949- impl->file_system = gtk_file_system_win32_new ();
5950-#else
5951-#error "No default filesystem implementation on the platform"
5952-#endif
5953- }
5954-
5955- if (impl->file_system)
5956- {
5957- impl->volumes_changed_id = g_signal_connect (impl->file_system, "volumes-changed",
5958- G_CALLBACK (volumes_changed_cb),
5959- impl);
5960- impl->bookmarks_changed_id = g_signal_connect (impl->file_system, "bookmarks-changed", 4996- impl->bookmarks_changed_id = g_signal_connect (impl->file_system, "bookmarks-changed",
5961- G_CALLBACK (bookmarks_changed_cb), 4997- G_CALLBACK (bookmarks_changed_cb),
5962- impl); 4998- impl);
5963- } 4999 }
5964- 5000
5965- profile_end ("end", NULL); 5001 profile_end ("end", NULL);
5966-} 5002 }
5967- 5003
5968-/* This function is basically a do_all function. 5004+static void
5969- * 5005+show_new_folder_button (GtkFileChooserDefault *impl)
5970- * It sets the visibility on all the widgets based on the current state, and 5006+{
5971- * moves the custom_widget if needed. 5007+ if ((impl->action == GTK_FILE_CHOOSER_ACTION_SAVE ||
5972- */ 5008+ impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER) &&
5973-static void 5009+ impl->show_create_folder)
5974-update_appearance (GtkFileChooserDefault *impl) 5010+ {
5975-{ 5011+ gtk_widget_show (impl->browse_new_folder_button);
5976- if (impl->action == GTK_FILE_CHOOSER_ACTION_SAVE || 5012+ gtk_misc_set_alignment (GTK_MISC (impl->location_label), 0.5, 0.5);
5977- impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER) 5013+ }
5978- { 5014+ else
5015+ {
5016+ gtk_widget_hide (impl->browse_new_folder_button);
5017+ gtk_misc_set_alignment (GTK_MISC (impl->location_label), 1.0, 0.5);
5018+ }
5019+}
5020+
5021 /* This function is basically a do_all function.
5022 *
5023 * It sets the visibility on all the widgets based on the current state, and
5024@@ -5478,33 +1762,9 @@
5025 if (impl->action == GTK_FILE_CHOOSER_ACTION_SAVE ||
5026 impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)
5027 {
5979- const char *text; 5028- const char *text;
5980- 5029+ gtk_widget_show (impl->save_widgets);
5030+ gtk_widget_show (impl->browse_widgets);
5031
5981- gtk_widget_hide (impl->location_button); 5032- gtk_widget_hide (impl->location_button);
5982- save_widgets_create (impl); 5033- save_widgets_create (impl);
5983- 5034-
@@ -6003,25 +5054,24 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
6003- 5054-
6004- gtk_widget_show (impl->browse_new_folder_button); 5055- gtk_widget_show (impl->browse_new_folder_button);
6005- 5056-
6006- if (impl->select_multiple) 5057 if (impl->select_multiple)
6007- { 5058 {
6008- g_warning ("Save mode cannot be set in conjunction with multiple selection mode. " 5059 g_warning ("Save mode cannot be set in conjunction with multiple selection mode. "
6009- "Re-setting to single selection mode."); 5060@@ -5515,23 +1775,12 @@
6010- set_select_multiple (impl, FALSE, TRUE); 5061 else if (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN ||
6011- } 5062 impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER)
6012- } 5063 {
6013- else if (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN ||
6014- impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER)
6015- {
6016- gtk_widget_show (impl->location_button); 5064- gtk_widget_show (impl->location_button);
6017- save_widgets_destroy (impl); 5065- save_widgets_destroy (impl);
6018- gtk_widget_show (impl->browse_widgets); 5066+ gtk_widget_hide (impl->save_widgets);
5067 gtk_widget_show (impl->browse_widgets);
6019- location_mode_set (impl, impl->location_mode, TRUE); 5068- location_mode_set (impl, impl->location_mode, TRUE);
6020- } 5069 }
6021- 5070
6022- if (impl->location_entry) 5071- if (impl->location_entry)
6023- _gtk_file_chooser_entry_set_action (GTK_FILE_CHOOSER_ENTRY (impl->location_entry), impl->action); 5072- _gtk_file_chooser_entry_set_action (GTK_FILE_CHOOSER_ENTRY (impl->location_entry), impl->action);
6024- 5073+ show_new_folder_button (impl);
5074
6025- if (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN) 5075- if (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN)
6026- gtk_widget_hide (impl->browse_new_folder_button); 5076- gtk_widget_hide (impl->browse_new_folder_button);
6027- else 5077- else
@@ -6030,58 +5080,23 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
6030- /* This *is* needed; we need to redraw the file list because the "sensitivity" 5080- /* This *is* needed; we need to redraw the file list because the "sensitivity"
6031- * of files may change depending whether we are in a file or folder-only mode. 5081- * of files may change depending whether we are in a file or folder-only mode.
6032- */ 5082- */
6033- gtk_widget_queue_draw (impl->browse_files_tree_view); 5083 gtk_widget_queue_draw (impl->browse_files_tree_view);
6034- 5084
6035- g_signal_emit_by_name (impl, "default-size-changed"); 5085 g_signal_emit_by_name (impl, "default-size-changed");
6036-} 5086@@ -5556,8 +1805,7 @@
6037- 5087 {
6038-static void 5088 gtk_file_chooser_default_unselect_all (GTK_FILE_CHOOSER (impl));
6039-gtk_file_chooser_default_set_property (GObject *object, 5089
6040- guint prop_id,
6041- const GValue *value,
6042- GParamSpec *pspec)
6043-
6044-{
6045- GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (object);
6046-
6047- switch (prop_id)
6048- {
6049- case GTK_FILE_CHOOSER_PROP_ACTION:
6050- {
6051- GtkFileChooserAction action = g_value_get_enum (value);
6052-
6053- if (action != impl->action)
6054- {
6055- gtk_file_chooser_default_unselect_all (GTK_FILE_CHOOSER (impl));
6056-
6057- if ((action == GTK_FILE_CHOOSER_ACTION_SAVE || 5090- if ((action == GTK_FILE_CHOOSER_ACTION_SAVE ||
6058- action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER) 5091- action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)
6059- && impl->select_multiple) 5092+ if ((action == GTK_FILE_CHOOSER_ACTION_SAVE || action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)
6060- { 5093 && impl->select_multiple)
6061- g_warning ("Tried to change the file chooser action to SAVE or CREATE_FOLDER, but " 5094 {
6062- "this is not allowed in multiple selection mode. Resetting the file chooser " 5095 g_warning ("Tried to change the file chooser action to SAVE or CREATE_FOLDER, but "
6063- "to single selection mode."); 5096@@ -5584,29 +1832,10 @@
6064- set_select_multiple (impl, FALSE, TRUE); 5097 set_local_only (impl, g_value_get_boolean (value));
6065- } 5098 break;
6066- impl->action = action; 5099
6067- update_appearance (impl);
6068- settings_load (impl);
6069- }
6070- }
6071- break;
6072-
6073- case GTK_FILE_CHOOSER_PROP_FILE_SYSTEM_BACKEND:
6074- set_file_system_backend (impl, g_value_get_string (value));
6075- break;
6076-
6077- case GTK_FILE_CHOOSER_PROP_FILTER:
6078- set_current_filter (impl, g_value_get_object (value));
6079- break;
6080-
6081- case GTK_FILE_CHOOSER_PROP_LOCAL_ONLY:
6082- set_local_only (impl, g_value_get_boolean (value));
6083- break;
6084-
6085- case GTK_FILE_CHOOSER_PROP_PREVIEW_WIDGET: 5100- case GTK_FILE_CHOOSER_PROP_PREVIEW_WIDGET:
6086- set_preview_widget (impl, g_value_get_object (value)); 5101- set_preview_widget (impl, g_value_get_object (value));
6087- break; 5102- break;
@@ -6100,170 +5115,143 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
6100- set_extra_widget (impl, g_value_get_object (value)); 5115- set_extra_widget (impl, g_value_get_object (value));
6101- break; 5116- break;
6102- 5117-
6103- case GTK_FILE_CHOOSER_PROP_SELECT_MULTIPLE: 5118 case GTK_FILE_CHOOSER_PROP_SELECT_MULTIPLE:
6104- { 5119 {
6105- gboolean select_multiple = g_value_get_boolean (value); 5120 gboolean select_multiple = g_value_get_boolean (value);
6106- if ((impl->action == GTK_FILE_CHOOSER_ACTION_SAVE || 5121- if ((impl->action == GTK_FILE_CHOOSER_ACTION_SAVE ||
6107- impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER) 5122- impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)
6108- && select_multiple) 5123+ if ((impl->action == GTK_FILE_CHOOSER_ACTION_SAVE || impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)
6109- { 5124 && select_multiple)
6110- g_warning ("Tried to set the file chooser to multiple selection mode, but this is " 5125 {
6111- "not allowed in SAVE or CREATE_FOLDER modes. Ignoring the change and " 5126 g_warning ("Tried to set the file chooser to multiple selection mode, but this is "
6112- "leaving the file chooser in single selection mode."); 5127@@ -5639,6 +1868,51 @@
6113- return; 5128 }
6114- } 5129 break;
6115- 5130
6116- set_select_multiple (impl, select_multiple, FALSE); 5131+ case GTK_FILE_CHOOSER_PROP_ROOT_FOLDER:
6117- } 5132+ {
6118- break; 5133+ GtkFilePath * path;
6119- 5134+ gchar * new_root = g_strdup (g_value_get_string (value));
6120- case GTK_FILE_CHOOSER_PROP_SHOW_HIDDEN: 5135+
6121- { 5136+ if (!new_root)
6122- gboolean show_hidden = g_value_get_boolean (value); 5137+ {
6123- if (show_hidden != impl->show_hidden) 5138+ new_root = g_strdup ("/");
6124- { 5139+ }
6125- impl->show_hidden = show_hidden; 5140+
6126- 5141+ path = gtk_file_system_filename_to_path (impl->file_system,
6127- if (impl->browse_files_model) 5142+ new_root);
6128- _gtk_file_system_model_set_show_hidden (impl->browse_files_model, show_hidden); 5143+ if (change_folder (impl, path, FALSE))
6129- } 5144+ {
6130- } 5145+ g_free (impl->root_folder);
6131- break; 5146+ impl->root_folder = new_root;
6132- 5147+ }
6133- case GTK_FILE_CHOOSER_PROP_DO_OVERWRITE_CONFIRMATION: 5148+ else
6134- { 5149+ {
6135- gboolean do_overwrite_confirmation = g_value_get_boolean (value); 5150+ g_warning ("Unable to set [%s] as root folder", new_root);
6136- impl->do_overwrite_confirmation = do_overwrite_confirmation; 5151+ g_free (new_root);
6137- } 5152+ }
6138- break; 5153+
6139- 5154+ gtk_file_path_free (path);
6140- default: 5155+ }
6141- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); 5156+ break;
6142- break; 5157+
6143- } 5158+ case GTK_FILE_CHOOSER_PROP_SHOW_CREATE_FOLDER:
6144-} 5159+ {
6145- 5160+ gboolean show = g_value_get_boolean (value);
6146-static void 5161+ if (show != impl->show_create_folder)
6147-gtk_file_chooser_default_get_property (GObject *object, 5162+ {
6148- guint prop_id, 5163+ impl->show_create_folder = show;
6149- GValue *value, 5164+ show_new_folder_button (impl);
6150- GParamSpec *pspec) 5165+ }
6151-{ 5166+ }
6152- GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (object); 5167+ break;
6153- 5168+
6154- switch (prop_id) 5169+ /* These are not supported */
6155- { 5170+ case GTK_FILE_CHOOSER_PROP_PREVIEW_WIDGET:
6156- case GTK_FILE_CHOOSER_PROP_ACTION: 5171+ case GTK_FILE_CHOOSER_PROP_PREVIEW_WIDGET_ACTIVE:
6157- g_value_set_enum (value, impl->action); 5172+ case GTK_FILE_CHOOSER_PROP_USE_PREVIEW_LABEL:
6158- break; 5173+ case GTK_FILE_CHOOSER_PROP_EXTRA_WIDGET:
6159- 5174+ break;
6160- case GTK_FILE_CHOOSER_PROP_FILTER: 5175+
6161- g_value_set_object (value, impl->current_filter); 5176 default:
6162- break; 5177 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
6163- 5178 break;
6164- case GTK_FILE_CHOOSER_PROP_LOCAL_ONLY: 5179@@ -5667,30 +1941,34 @@
6165- g_value_set_boolean (value, impl->local_only); 5180 g_value_set_boolean (value, impl->local_only);
6166- break; 5181 break;
6167- 5182
6168- case GTK_FILE_CHOOSER_PROP_PREVIEW_WIDGET: 5183- case GTK_FILE_CHOOSER_PROP_PREVIEW_WIDGET:
6169- g_value_set_object (value, impl->preview_widget); 5184- g_value_set_object (value, impl->preview_widget);
6170- break; 5185+ case GTK_FILE_CHOOSER_PROP_SELECT_MULTIPLE:
6171- 5186+ g_value_set_boolean (value, impl->select_multiple);
5187 break;
5188
6172- case GTK_FILE_CHOOSER_PROP_PREVIEW_WIDGET_ACTIVE: 5189- case GTK_FILE_CHOOSER_PROP_PREVIEW_WIDGET_ACTIVE:
6173- g_value_set_boolean (value, impl->preview_widget_active); 5190- g_value_set_boolean (value, impl->preview_widget_active);
6174- break; 5191+ case GTK_FILE_CHOOSER_PROP_SHOW_HIDDEN:
6175- 5192+ g_value_set_boolean (value, impl->show_hidden);
5193 break;
5194
6176- case GTK_FILE_CHOOSER_PROP_USE_PREVIEW_LABEL: 5195- case GTK_FILE_CHOOSER_PROP_USE_PREVIEW_LABEL:
6177- g_value_set_boolean (value, impl->use_preview_label); 5196- g_value_set_boolean (value, impl->use_preview_label);
6178- break; 5197+ case GTK_FILE_CHOOSER_PROP_ROOT_FOLDER:
6179- 5198+ g_value_set_string (value, impl->root_folder);
5199 break;
5200
6180- case GTK_FILE_CHOOSER_PROP_EXTRA_WIDGET: 5201- case GTK_FILE_CHOOSER_PROP_EXTRA_WIDGET:
6181- g_value_set_object (value, impl->extra_widget); 5202- g_value_set_object (value, impl->extra_widget);
6182- break; 5203+ case GTK_FILE_CHOOSER_PROP_SHOW_CREATE_FOLDER:
6183- 5204+ g_value_set_boolean (value, impl->show_create_folder);
5205 break;
5206
6184- case GTK_FILE_CHOOSER_PROP_SELECT_MULTIPLE: 5207- case GTK_FILE_CHOOSER_PROP_SELECT_MULTIPLE:
6185- g_value_set_boolean (value, impl->select_multiple); 5208- g_value_set_boolean (value, impl->select_multiple);
6186- break; 5209+ case GTK_FILE_CHOOSER_PROP_PREVIEW_WIDGET:
6187- 5210+ g_value_set_object (value, NULL);
5211 break;
5212
6188- case GTK_FILE_CHOOSER_PROP_SHOW_HIDDEN: 5213- case GTK_FILE_CHOOSER_PROP_SHOW_HIDDEN:
6189- g_value_set_boolean (value, impl->show_hidden); 5214- g_value_set_boolean (value, impl->show_hidden);
6190- break; 5215+ case GTK_FILE_CHOOSER_PROP_PREVIEW_WIDGET_ACTIVE:
6191- 5216+ g_value_set_boolean (value, FALSE);
6192- case GTK_FILE_CHOOSER_PROP_DO_OVERWRITE_CONFIRMATION: 5217 break;
6193- g_value_set_boolean (value, impl->do_overwrite_confirmation); 5218
6194- break; 5219+ case GTK_FILE_CHOOSER_PROP_USE_PREVIEW_LABEL:
6195- 5220+ g_value_set_boolean (value, FALSE);
6196- default: 5221+ break;
6197- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); 5222+
6198- break; 5223 case GTK_FILE_CHOOSER_PROP_DO_OVERWRITE_CONFIRMATION:
6199- } 5224 g_value_set_boolean (value, impl->do_overwrite_confirmation);
6200-} 5225 break;
6201- 5226@@ -5723,24 +2001,12 @@
6202-/* Removes the settings signal handler. It's safe to call multiple times */ 5227 GSList *l;
6203-static void 5228 GtkFileChooserDefault *impl = (GtkFileChooserDefault *) object;
6204-remove_settings_signal (GtkFileChooserDefault *impl, 5229
6205- GdkScreen *screen)
6206-{
6207- if (impl->settings_signal_id)
6208- {
6209- GtkSettings *settings;
6210-
6211- settings = gtk_settings_get_for_screen (screen);
6212- g_signal_handler_disconnect (settings,
6213- impl->settings_signal_id);
6214- impl->settings_signal_id = 0;
6215- }
6216-}
6217-
6218-static void
6219-gtk_file_chooser_default_dispose (GObject *object)
6220-{
6221- GSList *l;
6222- GtkFileChooserDefault *impl = (GtkFileChooserDefault *) object;
6223-
6224- if (impl->extra_widget) 5230- if (impl->extra_widget)
6225- { 5231- {
6226- g_object_unref (impl->extra_widget); 5232- g_object_unref (impl->extra_widget);
6227- impl->extra_widget = NULL; 5233- impl->extra_widget = NULL;
6228- } 5234- }
6229- 5235-
6230- if (impl->volumes_changed_id > 0) 5236 if (impl->volumes_changed_id > 0)
6231- { 5237 {
6232- g_signal_handler_disconnect (impl->file_system, impl->volumes_changed_id); 5238 g_signal_handler_disconnect (impl->file_system, impl->volumes_changed_id);
6233- impl->volumes_changed_id = 0; 5239 impl->volumes_changed_id = 0;
6234- } 5240 }
6235- 5241
6236- if (impl->bookmarks_changed_id > 0) 5242- if (impl->bookmarks_changed_id > 0)
6237- { 5243- {
6238- g_signal_handler_disconnect (impl->file_system, impl->bookmarks_changed_id); 5244- g_signal_handler_disconnect (impl->file_system, impl->bookmarks_changed_id);
6239- impl->bookmarks_changed_id = 0; 5245- impl->bookmarks_changed_id = 0;
6240- } 5246- }
6241- 5247-
6242- pending_select_paths_free (impl); 5248 pending_select_paths_free (impl);
6243- 5249
6244- /* cancel all pending operations */ 5250 /* cancel all pending operations */
6245- if (impl->pending_handles) 5251@@ -5766,23 +2032,6 @@
6246- { 5252 impl->reload_icon_handles = NULL;
6247- for (l = impl->pending_handles; l; l = l->next) 5253 }
6248- { 5254
6249- GtkFileSystemHandle *handle =l->data;
6250- gtk_file_system_cancel_operation (handle);
6251- }
6252- g_slist_free (impl->pending_handles);
6253- impl->pending_handles = NULL;
6254- }
6255-
6256- if (impl->reload_icon_handles)
6257- {
6258- for (l = impl->reload_icon_handles; l; l = l->next)
6259- {
6260- GtkFileSystemHandle *handle =l->data;
6261- gtk_file_system_cancel_operation (handle);
6262- }
6263- g_slist_free (impl->reload_icon_handles);
6264- impl->reload_icon_handles = NULL;
6265- }
6266-
6267- if (impl->loading_shortcuts) 5255- if (impl->loading_shortcuts)
6268- { 5256- {
6269- for (l = impl->loading_shortcuts; l; l = l->next) 5257- for (l = impl->loading_shortcuts; l; l = l->next)
@@ -6281,30 +5269,13 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
6281- impl->file_list_drag_data_received_handle = NULL; 5269- impl->file_list_drag_data_received_handle = NULL;
6282- } 5270- }
6283- 5271-
6284- if (impl->update_current_folder_handle) 5272 if (impl->update_current_folder_handle)
6285- { 5273 {
6286- gtk_file_system_cancel_operation (impl->update_current_folder_handle); 5274 gtk_file_system_cancel_operation (impl->update_current_folder_handle);
6287- impl->update_current_folder_handle = NULL; 5275@@ -5807,15 +2056,6 @@
6288- } 5276 impl->update_from_entry_handle = NULL;
6289- 5277 }
6290- if (impl->show_and_select_paths_handle) 5278
6291- {
6292- gtk_file_system_cancel_operation (impl->show_and_select_paths_handle);
6293- impl->show_and_select_paths_handle = NULL;
6294- }
6295-
6296- if (impl->should_respond_get_info_handle)
6297- {
6298- gtk_file_system_cancel_operation (impl->should_respond_get_info_handle);
6299- impl->should_respond_get_info_handle = NULL;
6300- }
6301-
6302- if (impl->update_from_entry_handle)
6303- {
6304- gtk_file_system_cancel_operation (impl->update_from_entry_handle);
6305- impl->update_from_entry_handle = NULL;
6306- }
6307-
6308- if (impl->shortcuts_activate_iter_handle) 5279- if (impl->shortcuts_activate_iter_handle)
6309- { 5280- {
6310- gtk_file_system_cancel_operation (impl->shortcuts_activate_iter_handle); 5281- gtk_file_system_cancel_operation (impl->shortcuts_activate_iter_handle);
@@ -6314,138 +5285,45 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
6314- search_stop_searching (impl, TRUE); 5285- search_stop_searching (impl, TRUE);
6315- recent_stop_loading (impl); 5286- recent_stop_loading (impl);
6316- 5287-
6317- remove_settings_signal (impl, gtk_widget_get_screen (GTK_WIDGET (impl))); 5288 remove_settings_signal (impl, gtk_widget_get_screen (GTK_WIDGET (impl)));
6318- 5289
6319- G_OBJECT_CLASS (_gtk_file_chooser_default_parent_class)->dispose (object); 5290 G_OBJECT_CLASS (_gtk_file_chooser_default_parent_class)->dispose (object);
6320-} 5291@@ -5828,12 +2068,7 @@
6321- 5292 static void
6322-/* We override show-all since we have internal widgets that 5293 gtk_file_chooser_default_show_all (GtkWidget *widget)
6323- * shouldn't be shown when you call show_all(), like the filter 5294 {
6324- * combo box.
6325- */
6326-static void
6327-gtk_file_chooser_default_show_all (GtkWidget *widget)
6328-{
6329- GtkFileChooserDefault *impl = (GtkFileChooserDefault *) widget; 5295- GtkFileChooserDefault *impl = (GtkFileChooserDefault *) widget;
6330- 5296-
6331- gtk_widget_show (widget); 5297 gtk_widget_show (widget);
6332- 5298-
6333- if (impl->extra_widget) 5299- if (impl->extra_widget)
6334- gtk_widget_show_all (impl->extra_widget); 5300- gtk_widget_show_all (impl->extra_widget);
6335-} 5301 }
6336- 5302
6337-/* Handler for GtkWindow::set-focus; this is where we save the last-focused 5303 /* Handler for GtkWindow::set-focus; this is where we save the last-focused
6338- * widget on our toplevel. See gtk_file_chooser_default_hierarchy_changed() 5304@@ -5894,7 +2129,6 @@
6339- */ 5305 else
6340-static void 5306 impl->icon_size = FALLBACK_ICON_SIZE;
6341-toplevel_set_focus_cb (GtkWindow *window, 5307
6342- GtkWidget *focus,
6343- GtkFileChooserDefault *impl)
6344-{
6345- impl->toplevel_last_focus_widget = gtk_window_get_focus (window);
6346-}
6347-
6348-/* We monitor the focus widget on our toplevel to be able to know which widget
6349- * was last focused at the time our "should_respond" method gets called.
6350- */
6351-static void
6352-gtk_file_chooser_default_hierarchy_changed (GtkWidget *widget,
6353- GtkWidget *previous_toplevel)
6354-{
6355- GtkFileChooserDefault *impl;
6356- GtkWidget *toplevel;
6357-
6358- impl = GTK_FILE_CHOOSER_DEFAULT (widget);
6359-
6360- if (previous_toplevel)
6361- {
6362- g_assert (impl->toplevel_set_focus_id != 0);
6363- g_signal_handler_disconnect (previous_toplevel, impl->toplevel_set_focus_id);
6364- impl->toplevel_set_focus_id = 0;
6365- impl->toplevel_last_focus_widget = NULL;
6366- }
6367- else
6368- g_assert (impl->toplevel_set_focus_id == 0);
6369-
6370- toplevel = gtk_widget_get_toplevel (widget);
6371- if (GTK_IS_WINDOW (toplevel))
6372- {
6373- impl->toplevel_set_focus_id = g_signal_connect (toplevel, "set_focus",
6374- G_CALLBACK (toplevel_set_focus_cb), impl);
6375- impl->toplevel_last_focus_widget = gtk_window_get_focus (GTK_WINDOW (toplevel));
6376- }
6377-}
6378-
6379-/* Changes the icons wherever it is needed */
6380-static void
6381-change_icon_theme (GtkFileChooserDefault *impl)
6382-{
6383- GtkSettings *settings;
6384- gint width, height;
6385-
6386- profile_start ("start", NULL);
6387-
6388- settings = gtk_settings_get_for_screen (gtk_widget_get_screen (GTK_WIDGET (impl)));
6389-
6390- if (gtk_icon_size_lookup_for_settings (settings, GTK_ICON_SIZE_MENU, &width, &height))
6391- impl->icon_size = MAX (width, height);
6392- else
6393- impl->icon_size = FALLBACK_ICON_SIZE;
6394-
6395- shortcuts_reload_icons (impl); 5308- shortcuts_reload_icons (impl);
6396- gtk_widget_queue_resize (impl->browse_files_tree_view); 5309 gtk_widget_queue_resize (impl->browse_files_tree_view);
6397- 5310
6398- profile_end ("end", NULL); 5311 profile_end ("end", NULL);
6399-} 5312@@ -5912,8 +2146,8 @@
6400- 5313
6401-/* Callback used when a GtkSettings value changes */ 5314 name = g_param_spec_get_name (pspec);
6402-static void 5315
6403-settings_notify_cb (GObject *object,
6404- GParamSpec *pspec,
6405- GtkFileChooserDefault *impl)
6406-{
6407- const char *name;
6408-
6409- profile_start ("start", NULL);
6410-
6411- name = g_param_spec_get_name (pspec);
6412-
6413- if (strcmp (name, "gtk-icon-theme-name") == 0 || 5316- if (strcmp (name, "gtk-icon-theme-name") == 0 ||
6414- strcmp (name, "gtk-icon-sizes") == 0) 5317- strcmp (name, "gtk-icon-sizes") == 0)
6415- change_icon_theme (impl); 5318+ if (strcmp (name, "gtk-icon-theme-name") == 0
6416- 5319+ || strcmp (name, "gtk-icon-sizes") == 0)
6417- profile_end ("end", NULL); 5320 change_icon_theme (impl);
6418-} 5321
6419- 5322 profile_end ("end", NULL);
6420-/* Installs a signal handler for GtkSettings so that we can monitor changes in 5323@@ -5948,24 +2182,6 @@
6421- * the icon theme. 5324 }
6422- */ 5325
6423-static void 5326 static void
6424-check_icon_theme (GtkFileChooserDefault *impl)
6425-{
6426- GtkSettings *settings;
6427-
6428- profile_start ("start", NULL);
6429-
6430- if (impl->settings_signal_id)
6431- {
6432- profile_end ("end", NULL);
6433- return;
6434- }
6435-
6436- if (gtk_widget_has_screen (GTK_WIDGET (impl)))
6437- {
6438- settings = gtk_settings_get_for_screen (gtk_widget_get_screen (GTK_WIDGET (impl)));
6439- impl->settings_signal_id = g_signal_connect (settings, "notify",
6440- G_CALLBACK (settings_notify_cb), impl);
6441-
6442- change_icon_theme (impl);
6443- }
6444-
6445- profile_end ("end", NULL);
6446-}
6447-
6448-static void
6449-recent_manager_update (GtkFileChooserDefault *impl) 5327-recent_manager_update (GtkFileChooserDefault *impl)
6450-{ 5328-{
6451- GtkRecentManager *manager; 5329- GtkRecentManager *manager;
@@ -6464,72 +5342,21 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
6464-} 5342-}
6465- 5343-
6466-static void 5344-static void
6467-gtk_file_chooser_default_style_set (GtkWidget *widget, 5345 gtk_file_chooser_default_style_set (GtkWidget *widget,
6468- GtkStyle *previous_style) 5346 GtkStyle *previous_style)
6469-{ 5347 {
6470- GtkFileChooserDefault *impl; 5348@@ -6005,7 +2221,6 @@
6471- 5349
6472- profile_start ("start", NULL); 5350 remove_settings_signal (impl, previous_screen);
6473- 5351 check_icon_theme (impl);
6474- impl = GTK_FILE_CHOOSER_DEFAULT (widget);
6475-
6476- profile_msg (" parent class style_set start", NULL);
6477- if (GTK_WIDGET_CLASS (_gtk_file_chooser_default_parent_class)->style_set)
6478- GTK_WIDGET_CLASS (_gtk_file_chooser_default_parent_class)->style_set (widget, previous_style);
6479- profile_msg (" parent class style_set end", NULL);
6480-
6481- if (gtk_widget_has_screen (GTK_WIDGET (impl)))
6482- change_icon_theme (impl);
6483-
6484- profile_msg (" emit default-size-changed start", NULL);
6485- g_signal_emit_by_name (widget, "default-size-changed");
6486- profile_msg (" emit default-size-changed end", NULL);
6487-
6488- profile_end ("end", NULL);
6489-}
6490-
6491-static void
6492-gtk_file_chooser_default_screen_changed (GtkWidget *widget,
6493- GdkScreen *previous_screen)
6494-{
6495- GtkFileChooserDefault *impl;
6496-
6497- profile_start ("start", NULL);
6498-
6499- impl = GTK_FILE_CHOOSER_DEFAULT (widget);
6500-
6501- if (GTK_WIDGET_CLASS (_gtk_file_chooser_default_parent_class)->screen_changed)
6502- GTK_WIDGET_CLASS (_gtk_file_chooser_default_parent_class)->screen_changed (widget, previous_screen);
6503-
6504- remove_settings_signal (impl, previous_screen);
6505- check_icon_theme (impl);
6506- recent_manager_update (impl); 5352- recent_manager_update (impl);
6507- 5353
6508- g_signal_emit_by_name (widget, "default-size-changed"); 5354 g_signal_emit_by_name (widget, "default-size-changed");
6509- 5355
6510- profile_end ("end", NULL); 5356@@ -6032,15 +2247,6 @@
6511-} 5357
6512- 5358 impl->default_width = allocation->width;
6513-static void 5359 impl->default_height = allocation->height;
6514-gtk_file_chooser_default_size_allocate (GtkWidget *widget,
6515- GtkAllocation *allocation)
6516-{
6517- GtkFileChooserDefault *impl;
6518-
6519- impl = GTK_FILE_CHOOSER_DEFAULT (widget);
6520-
6521- GTK_WIDGET_CLASS (_gtk_file_chooser_default_parent_class)->size_allocate (widget, allocation);
6522-
6523- if (!gtk_file_chooser_default_get_resizable (GTK_FILE_CHOOSER_EMBED (impl)))
6524- {
6525- /* The dialog is not resizable, we shouldn't
6526- * trust in the size it has in this stage
6527- */
6528- return;
6529- }
6530-
6531- impl->default_width = allocation->width;
6532- impl->default_height = allocation->height;
6533- 5360-
6534- if (impl->preview_widget_active && 5361- if (impl->preview_widget_active &&
6535- impl->preview_widget && 5362- impl->preview_widget &&
@@ -6539,110 +5366,48 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
6539- if (impl->extra_widget && 5366- if (impl->extra_widget &&
6540- GTK_WIDGET_DRAWABLE (impl->extra_widget)) 5367- GTK_WIDGET_DRAWABLE (impl->extra_widget))
6541- impl->default_height -= GTK_BOX (widget)->spacing + impl->extra_widget->allocation.height; 5368- impl->default_height -= GTK_BOX (widget)->spacing + impl->extra_widget->allocation.height;
6542-} 5369 }
6543- 5370
6544-static gboolean 5371 static gboolean
6545-get_is_file_filtered (GtkFileChooserDefault *impl, 5372@@ -6094,23 +2300,18 @@
6546- const GtkFilePath *path, 5373 settings_load (GtkFileChooserDefault *impl)
6547- GtkFileInfo *file_info) 5374 {
6548-{ 5375 GtkFileChooserSettings *settings;
6549- GtkFileFilterInfo filter_info;
6550- GtkFileFilterFlags needed;
6551- gboolean result;
6552-
6553- if (!impl->current_filter)
6554- return FALSE;
6555-
6556- filter_info.contains = GTK_FILE_FILTER_DISPLAY_NAME | GTK_FILE_FILTER_MIME_TYPE;
6557-
6558- needed = gtk_file_filter_get_needed (impl->current_filter);
6559-
6560- filter_info.display_name = gtk_file_info_get_display_name (file_info);
6561- filter_info.mime_type = gtk_file_info_get_mime_type (file_info);
6562-
6563- if (needed & GTK_FILE_FILTER_FILENAME)
6564- {
6565- filter_info.filename = gtk_file_system_path_to_filename (impl->file_system, path);
6566- if (filter_info.filename)
6567- filter_info.contains |= GTK_FILE_FILTER_FILENAME;
6568- }
6569- else
6570- filter_info.filename = NULL;
6571-
6572- if (needed & GTK_FILE_FILTER_URI)
6573- {
6574- filter_info.uri = gtk_file_system_path_to_uri (impl->file_system, path);
6575- if (filter_info.uri)
6576- filter_info.contains |= GTK_FILE_FILTER_URI;
6577- }
6578- else
6579- filter_info.uri = NULL;
6580-
6581- result = gtk_file_filter_filter (impl->current_filter, &filter_info);
6582-
6583- if (filter_info.filename)
6584- g_free ((gchar *)filter_info.filename);
6585- if (filter_info.uri)
6586- g_free ((gchar *)filter_info.uri);
6587-
6588- return !result;
6589-}
6590-
6591-static void
6592-settings_load (GtkFileChooserDefault *impl)
6593-{
6594- GtkFileChooserSettings *settings;
6595- LocationMode location_mode; 5376- LocationMode location_mode;
6596- gboolean show_hidden; 5377 gboolean show_hidden;
6597- gboolean expand_folders; 5378 gboolean expand_folders;
6598- 5379
6599- settings = _gtk_file_chooser_settings_new (); 5380 settings = _gtk_file_chooser_settings_new ();
6600- 5381
6601- location_mode = _gtk_file_chooser_settings_get_location_mode (settings); 5382- location_mode = _gtk_file_chooser_settings_get_location_mode (settings);
6602- show_hidden = _gtk_file_chooser_settings_get_show_hidden (settings); 5383 show_hidden = _gtk_file_chooser_settings_get_show_hidden (settings);
6603- expand_folders = _gtk_file_chooser_settings_get_expand_folders (settings); 5384 expand_folders = _gtk_file_chooser_settings_get_expand_folders (settings);
6604- 5385
6605- g_object_unref (settings); 5386 g_object_unref (settings);
6606- 5387
6607- location_mode_set (impl, location_mode, TRUE); 5388- location_mode_set (impl, location_mode, TRUE);
6608- gtk_file_chooser_set_show_hidden (GTK_FILE_CHOOSER (impl), show_hidden); 5389 gtk_file_chooser_set_show_hidden (GTK_FILE_CHOOSER (impl), show_hidden);
6609- impl->expand_folders = expand_folders; 5390 impl->expand_folders = expand_folders;
6610- if (impl->save_expander) 5391- if (impl->save_expander)
6611- gtk_expander_set_expanded (GTK_EXPANDER (impl->save_expander), expand_folders); 5392- gtk_expander_set_expanded (GTK_EXPANDER (impl->save_expander), expand_folders);
6612-} 5393 }
6613- 5394
6614-static void 5395 static void
6615-settings_save (GtkFileChooserDefault *impl) 5396@@ -6120,7 +2321,6 @@
6616-{ 5397
6617- GtkFileChooserSettings *settings; 5398 settings = _gtk_file_chooser_settings_new ();
6618- 5399
6619- settings = _gtk_file_chooser_settings_new ();
6620-
6621- _gtk_file_chooser_settings_set_location_mode (settings, impl->location_mode); 5400- _gtk_file_chooser_settings_set_location_mode (settings, impl->location_mode);
6622- _gtk_file_chooser_settings_set_show_hidden (settings, gtk_file_chooser_get_show_hidden (GTK_FILE_CHOOSER (impl))); 5401 _gtk_file_chooser_settings_set_show_hidden (settings, gtk_file_chooser_get_show_hidden (GTK_FILE_CHOOSER (impl)));
6623- _gtk_file_chooser_settings_set_expand_folders (settings, impl->expand_folders); 5402 _gtk_file_chooser_settings_set_expand_folders (settings, impl->expand_folders);
6624- 5403
6625- /* NULL GError */ 5404@@ -6143,44 +2343,32 @@
6626- _gtk_file_chooser_settings_save (settings, NULL); 5405
6627- 5406 GTK_WIDGET_CLASS (_gtk_file_chooser_default_parent_class)->map (widget);
6628- g_object_unref (settings); 5407
6629-}
6630-
6631-/* GtkWidget::map method */
6632-static void
6633-gtk_file_chooser_default_map (GtkWidget *widget)
6634-{
6635- GtkFileChooserDefault *impl;
6636- char *current_working_dir;
6637-
6638- profile_start ("start", NULL);
6639-
6640- impl = GTK_FILE_CHOOSER_DEFAULT (widget);
6641-
6642- GTK_WIDGET_CLASS (_gtk_file_chooser_default_parent_class)->map (widget);
6643-
6644- if (impl->operation_mode == OPERATION_MODE_BROWSE) 5408- if (impl->operation_mode == OPERATION_MODE_BROWSE)
6645- { 5409+ switch (impl->reload_state)
5410 {
6646- switch (impl->reload_state) 5411- switch (impl->reload_state)
6647- { 5412- {
6648- case RELOAD_EMPTY: 5413- case RELOAD_EMPTY:
@@ -6660,7 +5425,13 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
6660- * don't need to reload 5425- * don't need to reload
6661- */ 5426- */
6662- break; 5427- break;
6663- 5428+ case RELOAD_EMPTY:
5429+ /* The user didn't explicitly give us a folder to display, so we'll use the cwd */
5430+ current_working_dir = g_get_current_dir ();
5431+ gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (impl), current_working_dir);
5432+ g_free (current_working_dir);
5433+ break;
5434
6664- case RELOAD_WAS_UNMAPPED: 5435- case RELOAD_WAS_UNMAPPED:
6665- /* Just reload the current folder; else continue 5436- /* Just reload the current folder; else continue
6666- * the pending load. 5437- * the pending load.
@@ -6671,543 +5442,148 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
6671- change_folder_and_display_error (impl, impl->current_folder, FALSE); 5442- change_folder_and_display_error (impl, impl->current_folder, FALSE);
6672- } 5443- }
6673- break; 5444- break;
6674- 5445+ case RELOAD_HAS_FOLDER:
5446+ /* Nothing; we are already loading or loaded, so we don't need to reload */
5447+ break;
5448
6675- default: 5449- default:
6676- g_assert_not_reached (); 5450- g_assert_not_reached ();
6677- } 5451- }
6678- } 5452+ case RELOAD_WAS_UNMAPPED:
6679- 5453+ /* Just reload the current folder; else continue the pending load. */
5454+ if (impl->current_folder)
5455+ {
5456+ pending_select_paths_store_selection (impl);
5457+ change_folder_and_display_error (impl, impl->current_folder);
5458+ }
5459+ break;
5460+
5461+ default:
5462+ g_assert_not_reached ();
5463 }
5464
6680- bookmarks_changed_cb (impl->file_system, impl); 5465- bookmarks_changed_cb (impl->file_system, impl);
6681- 5466-
6682- settings_load (impl); 5467 settings_load (impl);
6683- 5468
6684- profile_end ("end", NULL); 5469 profile_end ("end", NULL);
6685-} 5470@@ -6244,8 +2432,8 @@
6686- 5471
6687-/* GtkWidget::unmap method */ 5472 #define COMPARE_DIRECTORIES \
6688-static void 5473 GtkFileChooserDefault *impl = user_data; \
6689-gtk_file_chooser_default_unmap (GtkWidget *widget)
6690-{
6691- GtkFileChooserDefault *impl;
6692-
6693- impl = GTK_FILE_CHOOSER_DEFAULT (widget);
6694-
6695- settings_save (impl);
6696-
6697- GTK_WIDGET_CLASS (_gtk_file_chooser_default_parent_class)->unmap (widget);
6698-
6699- impl->reload_state = RELOAD_WAS_UNMAPPED;
6700-}
6701-
6702-static gboolean
6703-list_model_filter_func (GtkFileSystemModel *model,
6704- GtkFilePath *path,
6705- const GtkFileInfo *file_info,
6706- gpointer user_data)
6707-{
6708- GtkFileChooserDefault *impl = user_data;
6709-
6710- if (!impl->current_filter)
6711- return TRUE;
6712-
6713- if (gtk_file_info_get_is_folder (file_info))
6714- return TRUE;
6715-
6716- return !get_is_file_filtered (impl, path, (GtkFileInfo *) file_info);
6717-}
6718-
6719-static void
6720-install_list_model_filter (GtkFileChooserDefault *impl)
6721-{
6722- GtkFileSystemModelFilter filter;
6723- gpointer data;
6724-
6725- g_assert (impl->browse_files_model != NULL);
6726-
6727- if (impl->current_filter)
6728- {
6729- filter = list_model_filter_func;
6730- data = impl;
6731- }
6732- else
6733- {
6734- filter = NULL;
6735- data = NULL;
6736- }
6737-
6738- _gtk_file_system_model_set_filter (impl->browse_files_model,
6739- filter,
6740- data);
6741-}
6742-
6743-#define COMPARE_DIRECTORIES \
6744- GtkFileChooserDefault *impl = user_data; \
6745- const GtkFileInfo *info_a = _gtk_file_system_model_get_info (impl->browse_files_model, a); \ 5474- const GtkFileInfo *info_a = _gtk_file_system_model_get_info (impl->browse_files_model, a); \
6746- const GtkFileInfo *info_b = _gtk_file_system_model_get_info (impl->browse_files_model, b); \ 5475- const GtkFileInfo *info_b = _gtk_file_system_model_get_info (impl->browse_files_model, b); \
6747- gboolean dir_a, dir_b; \ 5476+ const GtkFileInfo *info_a = _gtk_file_system_model_get_info (impl->browse_files_model, a); \
6748- \ 5477+ const GtkFileInfo *info_b = _gtk_file_system_model_get_info (impl->browse_files_model, b); \
6749- if (info_a) \ 5478 gboolean dir_a, dir_b; \
6750- dir_a = gtk_file_info_get_is_folder (info_a); \ 5479 \
6751- else \ 5480 if (info_a) \
6752- return impl->list_sort_ascending ? -1 : 1; \ 5481@@ -6387,6 +2575,8 @@
6753- \ 5482
6754- if (info_b) \ 5483 profile_start ("start", NULL);
6755- dir_b = gtk_file_info_get_is_folder (info_b); \ 5484
6756- else \ 5485+ GDK_THREADS_ENTER ();
6757- return impl->list_sort_ascending ? 1 : -1; \ 5486+
6758- \ 5487 impl = GTK_FILE_CHOOSER_DEFAULT (data);
6759- if (dir_a != dir_b) \ 5488 g_assert (impl->load_state == LOAD_PRELOAD);
6760- return impl->list_sort_ascending ? (dir_a ? -1 : 1) : (dir_a ? 1 : -1) /* Directories *always* go first */ 5489 g_assert (impl->load_timeout_id != 0);
6761- 5490@@ -6397,6 +2587,8 @@
6762-/* Sort callback for the filename column */ 5491
6763-static gint 5492 load_set_model (impl);
6764-name_sort_func (GtkTreeModel *model, 5493
6765- GtkTreeIter *a, 5494+ GDK_THREADS_LEAVE ();
6766- GtkTreeIter *b, 5495+
6767- gpointer user_data) 5496 profile_end ("end", NULL);
6768-{ 5497
6769- COMPARE_DIRECTORIES; 5498 return FALSE;
6770- else 5499@@ -6409,7 +2601,7 @@
6771- return strcmp (gtk_file_info_get_display_key (info_a), gtk_file_info_get_display_key (info_b)); 5500 g_assert (impl->load_timeout_id == 0);
6772-} 5501 g_assert (impl->load_state != LOAD_PRELOAD);
6773- 5502
6774-/* Sort callback for the size column */
6775-static gint
6776-size_sort_func (GtkTreeModel *model,
6777- GtkTreeIter *a,
6778- GtkTreeIter *b,
6779- gpointer user_data)
6780-{
6781- COMPARE_DIRECTORIES;
6782- else
6783- {
6784- gint64 size_a = gtk_file_info_get_size (info_a);
6785- gint64 size_b = gtk_file_info_get_size (info_b);
6786-
6787- return size_a > size_b ? -1 : (size_a == size_b ? 0 : 1);
6788- }
6789-}
6790-
6791-/* Sort callback for the mtime column */
6792-static gint
6793-mtime_sort_func (GtkTreeModel *model,
6794- GtkTreeIter *a,
6795- GtkTreeIter *b,
6796- gpointer user_data)
6797-{
6798- COMPARE_DIRECTORIES;
6799- else
6800- {
6801- GtkFileTime ta = gtk_file_info_get_modification_time (info_a);
6802- GtkFileTime tb = gtk_file_info_get_modification_time (info_b);
6803-
6804- return ta > tb ? -1 : (ta == tb ? 0 : 1);
6805- }
6806-}
6807-
6808-/* Callback used when the sort column changes. We cache the sort order for use
6809- * in name_sort_func().
6810- */
6811-static void
6812-list_sort_column_changed_cb (GtkTreeSortable *sortable,
6813- GtkFileChooserDefault *impl)
6814-{
6815- GtkSortType sort_type;
6816-
6817- if (gtk_tree_sortable_get_sort_column_id (sortable, NULL, &sort_type))
6818- impl->list_sort_ascending = (sort_type == GTK_SORT_ASCENDING);
6819-}
6820-
6821-static void
6822-set_busy_cursor (GtkFileChooserDefault *impl,
6823- gboolean busy)
6824-{
6825- GtkWindow *toplevel;
6826- GdkDisplay *display;
6827- GdkCursor *cursor;
6828-
6829- toplevel = get_toplevel (GTK_WIDGET (impl));
6830- if (!toplevel || !GTK_WIDGET_REALIZED (toplevel))
6831- return;
6832-
6833- display = gtk_widget_get_display (GTK_WIDGET (toplevel));
6834-
6835- if (busy)
6836- cursor = gdk_cursor_new_for_display (display, GDK_WATCH);
6837- else
6838- cursor = NULL;
6839-
6840- gdk_window_set_cursor (GTK_WIDGET (toplevel)->window, cursor);
6841- gdk_display_flush (display);
6842-
6843- if (cursor)
6844- gdk_cursor_unref (cursor);
6845-}
6846-
6847-/* Creates a sort model to wrap the file system model and sets it on the tree view */
6848-static void
6849-load_set_model (GtkFileChooserDefault *impl)
6850-{
6851- profile_start ("start", NULL);
6852-
6853- g_assert (impl->browse_files_model != NULL);
6854- g_assert (impl->sort_model == NULL);
6855-
6856- profile_msg (" gtk_tree_model_sort_new_with_model start", NULL);
6857- impl->sort_model = (GtkTreeModelSort *)gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (impl->browse_files_model));
6858- gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (impl->sort_model), FILE_LIST_COL_NAME, name_sort_func, impl, NULL);
6859- gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (impl->sort_model), FILE_LIST_COL_SIZE, size_sort_func, impl, NULL);
6860- gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (impl->sort_model), FILE_LIST_COL_MTIME, mtime_sort_func, impl, NULL);
6861- gtk_tree_sortable_set_default_sort_func (GTK_TREE_SORTABLE (impl->sort_model), NULL, NULL, NULL);
6862- gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (impl->sort_model), FILE_LIST_COL_NAME, GTK_SORT_ASCENDING);
6863- impl->list_sort_ascending = TRUE;
6864- profile_msg (" gtk_tree_model_sort_new_with_model end", NULL);
6865-
6866- g_signal_connect (impl->sort_model, "sort_column_changed",
6867- G_CALLBACK (list_sort_column_changed_cb), impl);
6868-
6869- profile_msg (" gtk_tree_view_set_model start", NULL);
6870- gtk_tree_view_set_model (GTK_TREE_VIEW (impl->browse_files_tree_view),
6871- GTK_TREE_MODEL (impl->sort_model));
6872- gtk_tree_view_columns_autosize (GTK_TREE_VIEW (impl->browse_files_tree_view));
6873- gtk_tree_view_set_search_column (GTK_TREE_VIEW (impl->browse_files_tree_view),
6874- GTK_FILE_SYSTEM_MODEL_DISPLAY_NAME);
6875- profile_msg (" gtk_tree_view_set_model end", NULL);
6876-
6877- profile_end ("end", NULL);
6878-}
6879-
6880-/* Timeout callback used when the loading timer expires */
6881-static gboolean
6882-load_timeout_cb (gpointer data)
6883-{
6884- GtkFileChooserDefault *impl;
6885-
6886- profile_start ("start", NULL);
6887-
6888- impl = GTK_FILE_CHOOSER_DEFAULT (data);
6889- g_assert (impl->load_state == LOAD_PRELOAD);
6890- g_assert (impl->load_timeout_id != 0);
6891- g_assert (impl->browse_files_model != NULL);
6892-
6893- impl->load_timeout_id = 0;
6894- impl->load_state = LOAD_LOADING;
6895-
6896- load_set_model (impl);
6897-
6898- profile_end ("end", NULL);
6899-
6900- return FALSE;
6901-}
6902-
6903-/* Sets up a new load timer for the model and switches to the LOAD_PRELOAD state */
6904-static void
6905-load_setup_timer (GtkFileChooserDefault *impl)
6906-{
6907- g_assert (impl->load_timeout_id == 0);
6908- g_assert (impl->load_state != LOAD_PRELOAD);
6909-
6910- impl->load_timeout_id = gdk_threads_add_timeout (MAX_LOADING_TIME, load_timeout_cb, impl); 5503- impl->load_timeout_id = gdk_threads_add_timeout (MAX_LOADING_TIME, load_timeout_cb, impl);
6911- impl->load_state = LOAD_PRELOAD; 5504+ impl->load_timeout_id = g_timeout_add (MAX_LOADING_TIME, load_timeout_cb, impl);
6912-} 5505 impl->load_state = LOAD_PRELOAD;
6913- 5506 }
6914-/* Removes the load timeout and switches to the LOAD_FINISHED state */ 5507
6915-static void 5508@@ -6494,12 +2686,10 @@
6916-load_remove_timer (GtkFileChooserDefault *impl) 5509 gpointer user_data)
6917-{ 5510 {
6918- if (impl->load_timeout_id != 0) 5511 gboolean have_hidden;
6919- {
6920- g_assert (impl->load_state == LOAD_PRELOAD);
6921-
6922- g_source_remove (impl->load_timeout_id);
6923- impl->load_timeout_id = 0;
6924- impl->load_state = LOAD_EMPTY;
6925- }
6926- else
6927- g_assert (impl->load_state == LOAD_EMPTY ||
6928- impl->load_state == LOAD_LOADING ||
6929- impl->load_state == LOAD_FINISHED);
6930-}
6931-
6932-/* Selects the first row in the file list */
6933-static void
6934-browse_files_select_first_row (GtkFileChooserDefault *impl)
6935-{
6936- GtkTreePath *path;
6937-
6938- if (!impl->sort_model)
6939- return;
6940-
6941- path = gtk_tree_path_new_from_indices (0, -1);
6942- gtk_tree_view_set_cursor (GTK_TREE_VIEW (impl->browse_files_tree_view), path, NULL, FALSE);
6943- gtk_tree_path_free (path);
6944-}
6945-
6946-struct center_selected_row_closure {
6947- GtkFileChooserDefault *impl;
6948- gboolean already_centered;
6949-};
6950-
6951-/* Callback used from gtk_tree_selection_selected_foreach(); centers the
6952- * selected row in the tree view.
6953- */
6954-static void
6955-center_selected_row_foreach_cb (GtkTreeModel *model,
6956- GtkTreePath *path,
6957- GtkTreeIter *iter,
6958- gpointer data)
6959-{
6960- struct center_selected_row_closure *closure;
6961-
6962- closure = data;
6963- if (closure->already_centered)
6964- return;
6965-
6966- gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (closure->impl->browse_files_tree_view), path, NULL, TRUE, 0.5, 0.0);
6967- closure->already_centered = TRUE;
6968-}
6969-
6970-/* Centers the selected row in the tree view */
6971-static void
6972-browse_files_center_selected_row (GtkFileChooserDefault *impl)
6973-{
6974- struct center_selected_row_closure closure;
6975- GtkTreeSelection *selection;
6976-
6977- closure.impl = impl;
6978- closure.already_centered = FALSE;
6979-
6980- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_files_tree_view));
6981- gtk_tree_selection_selected_foreach (selection, center_selected_row_foreach_cb, &closure);
6982-}
6983-
6984-struct ShowAndSelectPathsData
6985-{
6986- GtkFileChooserDefault *impl;
6987- GSList *paths;
6988-};
6989-
6990-static void
6991-show_and_select_paths_finished_loading (GtkFileFolder *folder,
6992- gpointer user_data)
6993-{
6994- gboolean have_hidden;
6995- gboolean have_filtered; 5512- gboolean have_filtered;
6996- GSList *l; 5513 GSList *l;
6997- struct ShowAndSelectPathsData *data = user_data; 5514 struct ShowAndSelectPathsData *data = user_data;
6998- 5515
6999- have_hidden = FALSE; 5516 have_hidden = FALSE;
7000- have_filtered = FALSE; 5517- have_filtered = FALSE;
7001- 5518
7002- for (l = data->paths; l; l = l->next) 5519 for (l = data->paths; l; l = l->next)
7003- { 5520 {
7004- const GtkFilePath *path; 5521@@ -6515,12 +2705,9 @@
7005- GtkFileInfo *info; 5522 if (!have_hidden)
7006- 5523 have_hidden = gtk_file_info_get_is_hidden (info);
7007- path = l->data; 5524
7008-
7009- /* NULL GError */
7010- info = gtk_file_folder_get_info (folder, path, NULL);
7011- if (info)
7012- {
7013- if (!have_hidden)
7014- have_hidden = gtk_file_info_get_is_hidden (info);
7015-
7016- if (!have_filtered) 5525- if (!have_filtered)
7017- have_filtered = !gtk_file_info_get_is_folder (info) && get_is_file_filtered (data->impl, path, info); 5526- have_filtered = !gtk_file_info_get_is_folder (info) && get_is_file_filtered (data->impl, path, info);
7018- 5527-
7019- gtk_file_info_free (info); 5528 gtk_file_info_free (info);
7020- 5529
7021- if (have_hidden && have_filtered) 5530- if (have_hidden && have_filtered)
7022- break; /* we now have all the information we need */ 5531+ if (have_hidden)
7023- } 5532 break; /* we now have all the information we need */
7024- } 5533 }
7025- 5534 }
7026- g_signal_handlers_disconnect_by_func (folder, 5535@@ -6534,9 +2721,6 @@
7027- show_and_select_paths_finished_loading, 5536 if (have_hidden)
7028- user_data); 5537 g_object_set (data->impl, "show-hidden", TRUE, NULL);
7029- 5538
7030- g_object_unref (folder);
7031-
7032- if (have_hidden)
7033- g_object_set (data->impl, "show-hidden", TRUE, NULL);
7034-
7035- if (have_filtered) 5539- if (have_filtered)
7036- set_current_filter (data->impl, NULL); 5540- set_current_filter (data->impl, NULL);
7037- 5541-
7038- for (l = data->paths; l; l = l->next) 5542 for (l = data->paths; l; l = l->next)
7039- { 5543 {
7040- const GtkFilePath *path; 5544 const GtkFilePath *path;
7041- 5545@@ -6644,6 +2828,12 @@
7042- path = l->data; 5546 * but rather on behalf of something else like GtkFileChooserButton. In
7043- _gtk_file_system_model_path_do (data->impl->browse_files_model, path, 5547 * that case, the chooser's selection should be what the caller expects,
7044- select_func, data->impl); 5548 * as the user can't see that something else got selected. See bug #165264.
7045- } 5549+ *
7046- 5550+ * Also, we don't select the first file if we are not in OPEN mode. Doing
7047- browse_files_center_selected_row (data->impl); 5551+ * so would change the contents of the filename entry for SAVE or
7048- 5552+ * CREATE_FOLDER, which is undesired; in SELECT_FOLDER, we don't want to
7049- g_object_unref (data->impl); 5553+ * select a *different* folder from the one into which the user just
7050- gtk_file_paths_free (data->paths); 5554+ * navigated.
7051- g_free (data); 5555 */
7052-} 5556 if (GTK_WIDGET_MAPPED (impl) && impl->action == GTK_FILE_CHOOSER_ACTION_OPEN)
7053- 5557 browse_files_select_first_row (impl);
7054-static void 5558@@ -6690,11 +2880,17 @@
7055-show_and_select_paths_get_folder_cb (GtkFileSystemHandle *handle, 5559 profile_end ("end", NULL);
7056- GtkFileFolder *folder, 5560 }
7057- const GError *error, 5561
7058- gpointer user_data)
7059-{
7060- gboolean cancelled = handle->cancelled;
7061- struct ShowAndSelectPathsData *data = user_data;
7062-
7063- if (data->impl->show_and_select_paths_handle != handle)
7064- goto out;
7065-
7066- data->impl->show_and_select_paths_handle = NULL;
7067-
7068- if (cancelled || error)
7069- goto out;
7070-
7071- g_object_unref (handle);
7072-
7073- if (gtk_file_folder_is_finished_loading (folder))
7074- show_and_select_paths_finished_loading (folder, user_data);
7075- else
7076- g_signal_connect (folder, "finished-loading",
7077- G_CALLBACK (show_and_select_paths_finished_loading),
7078- user_data);
7079-
7080- return;
7081-
7082-out:
7083- g_object_unref (data->impl);
7084- gtk_file_paths_free (data->paths);
7085- g_free (data);
7086-
7087- g_object_unref (handle);
7088-}
7089-
7090-static gboolean
7091-show_and_select_paths (GtkFileChooserDefault *impl,
7092- const GtkFilePath *parent_path,
7093- GSList *paths,
7094- GError **error)
7095-{
7096- struct ShowAndSelectPathsData *info;
7097-
7098- profile_start ("start", NULL);
7099-
7100- if (!paths)
7101- {
7102- profile_end ("end", NULL);
7103- return TRUE;
7104- }
7105-
7106- info = g_new (struct ShowAndSelectPathsData, 1);
7107- info->impl = g_object_ref (impl);
7108- info->paths = gtk_file_paths_copy (paths);
7109-
7110- if (impl->show_and_select_paths_handle)
7111- gtk_file_system_cancel_operation (impl->show_and_select_paths_handle);
7112-
7113- impl->show_and_select_paths_handle =
7114- gtk_file_system_get_folder (impl->file_system, parent_path,
7115- GTK_FILE_INFO_IS_FOLDER | GTK_FILE_INFO_IS_HIDDEN,
7116- show_and_select_paths_get_folder_cb, info);
7117-
7118- profile_end ("end", NULL);
7119- return TRUE;
7120-}
7121-
7122-/* Processes the pending operation when a folder is finished loading */
7123-static void
7124-pending_select_paths_process (GtkFileChooserDefault *impl)
7125-{
7126- g_assert (impl->load_state == LOAD_FINISHED);
7127- g_assert (impl->browse_files_model != NULL);
7128- g_assert (impl->sort_model != NULL);
7129-
7130- if (impl->pending_select_paths)
7131- {
7132- /* NULL GError */
7133- show_and_select_paths (impl, impl->current_folder, impl->pending_select_paths, NULL);
7134- pending_select_paths_free (impl);
7135- browse_files_center_selected_row (impl);
7136- }
7137- else
7138- {
7139- /* We only select the first row if the chooser is actually mapped ---
7140- * selecting the first row is to help the user when he is interacting with
7141- * the chooser, but sometimes a chooser works not on behalf of the user,
7142- * but rather on behalf of something else like GtkFileChooserButton. In
7143- * that case, the chooser's selection should be what the caller expects,
7144- * as the user can't see that something else got selected. See bug #165264.
7145- */
7146- if (GTK_WIDGET_MAPPED (impl) && impl->action == GTK_FILE_CHOOSER_ACTION_OPEN)
7147- browse_files_select_first_row (impl);
7148- }
7149-
7150- g_assert (impl->pending_select_paths == NULL);
7151-}
7152-
7153-/* Callback used when the file system model finishes loading */
7154-static void
7155-browse_files_model_finished_loading_cb (GtkFileSystemModel *model,
7156- GtkFileChooserDefault *impl)
7157-{
7158- profile_start ("start", NULL);
7159-
7160- if (impl->load_state == LOAD_PRELOAD)
7161- {
7162- load_remove_timer (impl);
7163- load_set_model (impl);
7164- }
7165- else if (impl->load_state == LOAD_LOADING)
7166- {
7167- /* Nothing */
7168- }
7169- else
7170- {
7171- /* We can't g_assert_not_reached(), as something other than us may have
7172- * initiated a folder reload. See #165556.
7173- */
7174- profile_end ("end", NULL);
7175- return;
7176- }
7177-
7178- g_assert (impl->load_timeout_id == 0);
7179-
7180- impl->load_state = LOAD_FINISHED;
7181-
7182- pending_select_paths_process (impl);
7183- set_busy_cursor (impl, FALSE);
7184-#ifdef PROFILE_FILE_CHOOSER
7185- access ("MARK: *** FINISHED LOADING", F_OK);
7186-#endif
7187-
7188- profile_end ("end", NULL);
7189-}
7190-
7191-static void 5562-static void
7192-stop_loading_and_clear_list_model (GtkFileChooserDefault *impl) 5563-stop_loading_and_clear_list_model (GtkFileChooserDefault *impl)
7193-{ 5564+/* Gets rid of the old list model and creates a new one for the current folder */
7194- load_remove_timer (impl); /* This changes the state to LOAD_EMPTY */ 5565+static gboolean
5566+set_list_model (GtkFileChooserDefault *impl,
5567+ GError **error)
5568 {
5569+ g_assert (impl->current_folder != NULL);
5570+
5571+ profile_start ("start", NULL);
5572+
5573 load_remove_timer (impl); /* This changes the state to LOAD_EMPTY */
7195- 5574-
7196- if (impl->browse_files_model) 5575+
7197- { 5576 if (impl->browse_files_model)
7198- g_object_unref (impl->browse_files_model); 5577 {
7199- impl->browse_files_model = NULL; 5578 g_object_unref (impl->browse_files_model);
7200- } 5579@@ -6706,21 +2902,7 @@
7201- 5580 g_object_unref (impl->sort_model);
7202- if (impl->sort_model) 5581 impl->sort_model = NULL;
7203- { 5582 }
7204- g_object_unref (impl->sort_model);
7205- impl->sort_model = NULL;
7206- }
7207- 5583-
7208- gtk_tree_view_set_model (GTK_TREE_VIEW (impl->browse_files_tree_view), NULL); 5584- gtk_tree_view_set_model (GTK_TREE_VIEW (impl->browse_files_tree_view), NULL);
7209-} 5585-}
7210- 5586
7211-/* Gets rid of the old list model and creates a new one for the current folder */ 5587-/* Gets rid of the old list model and creates a new one for the current folder */
7212-static gboolean 5588-static gboolean
7213-set_list_model (GtkFileChooserDefault *impl, 5589-set_list_model (GtkFileChooserDefault *impl,
@@ -7219,296 +5595,121 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
7219- 5595-
7220- stop_loading_and_clear_list_model (impl); 5596- stop_loading_and_clear_list_model (impl);
7221- 5597-
7222- set_busy_cursor (impl, TRUE); 5598 set_busy_cursor (impl, TRUE);
7223- gtk_tree_view_set_model (GTK_TREE_VIEW (impl->browse_files_tree_view), NULL); 5599 gtk_tree_view_set_model (GTK_TREE_VIEW (impl->browse_files_tree_view), NULL);
7224- 5600
7225- impl->browse_files_model = _gtk_file_system_model_new (impl->file_system, 5601@@ -6794,17 +2976,10 @@
7226- impl->current_folder, 0, 5602 struct update_chooser_entry_selected_foreach_closure closure;
7227- GTK_FILE_INFO_ALL, 5603 const char *file_part;
7228- error); 5604
7229- if (!impl->browse_files_model)
7230- {
7231- set_busy_cursor (impl, FALSE);
7232- profile_end ("end", NULL);
7233- return FALSE;
7234- }
7235-
7236- load_setup_timer (impl); /* This changes the state to LOAD_PRELOAD */
7237-
7238- g_signal_connect (impl->browse_files_model, "finished-loading",
7239- G_CALLBACK (browse_files_model_finished_loading_cb), impl);
7240-
7241- _gtk_file_system_model_set_show_hidden (impl->browse_files_model, impl->show_hidden);
7242-
7243- install_list_model_filter (impl);
7244-
7245- profile_end ("end", NULL);
7246-
7247- return TRUE;
7248-}
7249-
7250-struct update_chooser_entry_selected_foreach_closure {
7251- int num_selected;
7252- GtkTreeIter first_selected_iter;
7253-};
7254-
7255-static gint
7256-compare_utf8_filenames (const gchar *a,
7257- const gchar *b)
7258-{
7259- gchar *a_folded, *b_folded;
7260- gint retval;
7261-
7262- a_folded = g_utf8_strdown (a, -1);
7263- b_folded = g_utf8_strdown (b, -1);
7264-
7265- retval = strcmp (a_folded, b_folded);
7266-
7267- g_free (a_folded);
7268- g_free (b_folded);
7269-
7270- return retval;
7271-}
7272-
7273-static void
7274-update_chooser_entry_selected_foreach (GtkTreeModel *model,
7275- GtkTreePath *path,
7276- GtkTreeIter *iter,
7277- gpointer data)
7278-{
7279- struct update_chooser_entry_selected_foreach_closure *closure;
7280-
7281- closure = data;
7282- closure->num_selected++;
7283-
7284- if (closure->num_selected == 1)
7285- closure->first_selected_iter = *iter;
7286-}
7287-
7288-static void
7289-update_chooser_entry (GtkFileChooserDefault *impl)
7290-{
7291- GtkTreeSelection *selection;
7292- struct update_chooser_entry_selected_foreach_closure closure;
7293- const char *file_part;
7294-
7295- /* no need to update the file chooser's entry if there's no entry */ 5605- /* no need to update the file chooser's entry if there's no entry */
7296- if (impl->operation_mode == OPERATION_MODE_SEARCH || 5606- if (impl->operation_mode == OPERATION_MODE_SEARCH ||
7297- impl->operation_mode == OPERATION_MODE_RECENT || 5607- impl->operation_mode == OPERATION_MODE_RECENT ||
7298- !impl->location_entry) 5608- !impl->location_entry)
7299- return; 5609- return;
7300- 5610-
7301- if (!(impl->action == GTK_FILE_CHOOSER_ACTION_SAVE 5611 if (!(impl->action == GTK_FILE_CHOOSER_ACTION_SAVE
7302- || impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER 5612 || impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER
7303- || ((impl->action == GTK_FILE_CHOOSER_ACTION_OPEN 5613- || ((impl->action == GTK_FILE_CHOOSER_ACTION_OPEN
7304- || impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER) 5614- || impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER)
7305- && impl->location_mode == LOCATION_MODE_FILENAME_ENTRY))) 5615- && impl->location_mode == LOCATION_MODE_FILENAME_ENTRY)))
7306- return; 5616+ || impl->action == GTK_FILE_CHOOSER_ACTION_OPEN
7307- 5617+ || impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER))
7308- g_assert (impl->location_entry != NULL); 5618 return;
7309- 5619
7310- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_files_tree_view)); 5620 g_assert (impl->location_entry != NULL);
7311- closure.num_selected = 0; 5621@@ -6822,45 +2997,39 @@
7312- gtk_tree_selection_selected_foreach (selection, update_chooser_entry_selected_foreach, &closure); 5622 else if (closure.num_selected == 1)
7313- 5623 {
7314- file_part = NULL; 5624 GtkTreeIter child_iter;
7315-
7316- if (closure.num_selected == 0)
7317- {
7318- goto maybe_clear_entry;
7319- }
7320- else if (closure.num_selected == 1)
7321- {
7322- GtkTreeIter child_iter;
7323- 5625-
7324- if (impl->operation_mode == OPERATION_MODE_BROWSE) 5626- if (impl->operation_mode == OPERATION_MODE_BROWSE)
7325- { 5627- {
7326- const GtkFileInfo *info; 5628- const GtkFileInfo *info;
7327- gboolean change_entry; 5629- gboolean change_entry;
7328- 5630+ const GtkFileInfo *info;
5631+ gboolean change_entry;
5632
7329- gtk_tree_model_sort_convert_iter_to_child_iter (impl->sort_model, 5633- gtk_tree_model_sort_convert_iter_to_child_iter (impl->sort_model,
7330- &child_iter, 5634- &child_iter,
7331- &closure.first_selected_iter); 5635- &closure.first_selected_iter);
7332- 5636+ gtk_tree_model_sort_convert_iter_to_child_iter (impl->sort_model,
5637+ &child_iter,
5638+ &closure.first_selected_iter);
5639
7333- info = _gtk_file_system_model_get_info (impl->browse_files_model, &child_iter); 5640- info = _gtk_file_system_model_get_info (impl->browse_files_model, &child_iter);
7334- 5641+ info = _gtk_file_system_model_get_info (impl->browse_files_model, &child_iter);
5642
7335- /* If the cursor moved to the row of the newly created folder, 5643- /* If the cursor moved to the row of the newly created folder,
7336- * retrieving info will return NULL. 5644- * retrieving info will return NULL.
7337- */ 5645- */
7338- if (!info) 5646- if (!info)
7339- return; 5647- return;
7340- 5648+ /* If the cursor moved to the row of the newly created folder,
5649+ * retrieving info will return NULL.
5650+ */
5651+ if (!info)
5652+ return;
5653
7341- g_free (impl->browse_files_last_selected_name); 5654- g_free (impl->browse_files_last_selected_name);
7342- impl->browse_files_last_selected_name = 5655- impl->browse_files_last_selected_name =
7343- g_strdup (gtk_file_info_get_display_name (info)); 5656- g_strdup (gtk_file_info_get_display_name (info));
7344- 5657+ g_free (impl->browse_files_last_selected_name);
5658+ impl->browse_files_last_selected_name = g_strdup (gtk_file_info_get_display_name (info));
5659
7345- if (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN || 5660- if (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN ||
7346- impl->action == GTK_FILE_CHOOSER_ACTION_SAVE) 5661- impl->action == GTK_FILE_CHOOSER_ACTION_SAVE)
7347- change_entry = !gtk_file_info_get_is_folder (info); /* We don't want the name to change when clicking on a folder... */ 5662- change_entry = !gtk_file_info_get_is_folder (info); /* We don't want the name to change when clicking on a folder... */
7348- else 5663- else
7349- change_entry = TRUE; /* ... unless we are in one of the folder modes */ 5664- change_entry = TRUE; /* ... unless we are in one of the folder modes */
7350- 5665+ if (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN
5666+ || impl->action == GTK_FILE_CHOOSER_ACTION_SAVE)
5667+ change_entry = !gtk_file_info_get_is_folder (info); /* We don't want the name to change when clicking on a folder... */
5668+ else
5669+ change_entry = TRUE; /* ... unless we are in one of the folder modes */
5670
7351- if (change_entry) 5671- if (change_entry)
7352- _gtk_file_chooser_entry_set_file_part (GTK_FILE_CHOOSER_ENTRY (impl->location_entry), 5672- _gtk_file_chooser_entry_set_file_part (GTK_FILE_CHOOSER_ENTRY (impl->location_entry),
7353- impl->browse_files_last_selected_name); 5673- impl->browse_files_last_selected_name);
7354- 5674+ if (change_entry)
5675+ _gtk_file_chooser_entry_set_file_part (GTK_FILE_CHOOSER_ENTRY (impl->location_entry), impl->browse_files_last_selected_name);
5676
7355- return; 5677- return;
7356- } 5678- }
7357- } 5679+ return;
7358- else 5680 }
7359- { 5681 else
5682 {
7360- g_assert (!(impl->action == GTK_FILE_CHOOSER_ACTION_SAVE || 5683- g_assert (!(impl->action == GTK_FILE_CHOOSER_ACTION_SAVE ||
7361- impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)); 5684- impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER));
7362- 5685+ g_assert (!(impl->action == GTK_FILE_CHOOSER_ACTION_SAVE
7363- /* Multiple selection, so just clear the entry. */ 5686+ || impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER));
7364- 5687
7365- g_free (impl->browse_files_last_selected_name); 5688 /* Multiple selection, so just clear the entry. */
7366- impl->browse_files_last_selected_name = NULL; 5689
7367- 5690@@ -6957,7 +3126,7 @@
7368- _gtk_file_chooser_entry_set_file_part (GTK_FILE_CHOOSER_ENTRY (impl->location_entry), ""); 5691
7369- return; 5692 /* get parent path and try to change the folder to that */
7370- } 5693 if (gtk_file_system_get_parent (impl->file_system, data->path, &parent_path, NULL) &&
7371-
7372- maybe_clear_entry:
7373-
7374- if (impl->browse_files_last_selected_name)
7375- {
7376- const char *entry_text;
7377- int len;
7378- gboolean clear_entry;
7379-
7380- entry_text = gtk_entry_get_text (GTK_ENTRY (impl->location_entry));
7381- len = strlen (entry_text);
7382- if (len != 0)
7383- {
7384- /* The file chooser entry may have appended a "/" to its text. So
7385- * take it out, and compare the result to the old selection.
7386- */
7387- if (entry_text[len - 1] == G_DIR_SEPARATOR)
7388- {
7389- char *tmp;
7390-
7391- tmp = g_strndup (entry_text, len - 1);
7392- clear_entry = (compare_utf8_filenames (impl->browse_files_last_selected_name, tmp) == 0);
7393- g_free (tmp);
7394- }
7395- else
7396- clear_entry = (compare_utf8_filenames (impl->browse_files_last_selected_name, entry_text) == 0);
7397- }
7398- else
7399- clear_entry = FALSE;
7400-
7401- if (clear_entry)
7402- _gtk_file_chooser_entry_set_file_part (GTK_FILE_CHOOSER_ENTRY (impl->location_entry), "");
7403- }
7404-}
7405-
7406-static gboolean
7407-gtk_file_chooser_default_set_current_folder (GtkFileChooser *chooser,
7408- const GtkFilePath *path,
7409- GError **error)
7410-{
7411- return gtk_file_chooser_default_update_current_folder (chooser, path, FALSE, FALSE, error);
7412-}
7413-
7414-
7415-struct UpdateCurrentFolderData
7416-{
7417- GtkFileChooserDefault *impl;
7418- GtkFilePath *path;
7419- gboolean keep_trail;
7420- gboolean clear_entry;
7421- GtkFilePath *original_path;
7422- GError *original_error;
7423-};
7424-
7425-static void
7426-update_current_folder_get_info_cb (GtkFileSystemHandle *handle,
7427- const GtkFileInfo *info,
7428- const GError *error,
7429- gpointer user_data)
7430-{
7431- gboolean cancelled = handle->cancelled;
7432- struct UpdateCurrentFolderData *data = user_data;
7433- GtkFileChooserDefault *impl = data->impl;
7434-
7435- if (handle != impl->update_current_folder_handle)
7436- goto out;
7437-
7438- impl->update_current_folder_handle = NULL;
7439- impl->reload_state = RELOAD_EMPTY;
7440-
7441- set_busy_cursor (impl, FALSE);
7442-
7443- if (cancelled)
7444- goto out;
7445-
7446- if (error)
7447- {
7448- GtkFilePath *parent_path;
7449-
7450- if (!data->original_path)
7451- {
7452- data->original_path = gtk_file_path_copy (data->path);
7453- data->original_error = g_error_copy (error);
7454- }
7455-
7456- /* get parent path and try to change the folder to that */
7457- if (gtk_file_system_get_parent (impl->file_system, data->path, &parent_path, NULL) &&
7458- parent_path != NULL) 5694- parent_path != NULL)
7459- { 5695+ parent_path)
7460- gtk_file_path_free (data->path); 5696 {
7461- data->path = parent_path; 5697 gtk_file_path_free (data->path);
7462- 5698 data->path = parent_path;
7463- g_object_unref (handle); 5699@@ -6998,9 +3167,6 @@
7464- 5700 if (!gtk_file_info_get_is_folder (info))
7465- /* restart the update current folder operation */ 5701 goto out;
7466- impl->reload_state = RELOAD_HAS_FOLDER; 5702
7467-
7468- impl->update_current_folder_handle =
7469- gtk_file_system_get_info (impl->file_system, data->path,
7470- GTK_FILE_INFO_IS_FOLDER,
7471- update_current_folder_get_info_cb,
7472- data);
7473-
7474- set_busy_cursor (impl, TRUE);
7475-
7476- return;
7477- }
7478- else
7479- {
7480- /* error and bail out */
7481- error_changing_folder_dialog (impl, data->original_path, data->original_error);
7482-
7483- gtk_file_path_free (data->original_path);
7484-
7485- goto out;
7486- }
7487- }
7488-
7489- if (data->original_path)
7490- {
7491- error_changing_folder_dialog (impl, data->original_path, data->original_error);
7492-
7493- gtk_file_path_free (data->original_path);
7494- }
7495-
7496- if (!gtk_file_info_get_is_folder (info))
7497- goto out;
7498-
7499- if (!_gtk_path_bar_set_path (GTK_PATH_BAR (impl->browse_path_bar), data->path, data->keep_trail, NULL)) 5703- if (!_gtk_path_bar_set_path (GTK_PATH_BAR (impl->browse_path_bar), data->path, data->keep_trail, NULL))
7500- goto out; 5704- goto out;
7501- 5705-
7502- if (impl->current_folder != data->path) 5706 if (impl->current_folder != data->path)
7503- { 5707 {
7504- if (impl->current_folder) 5708 if (impl->current_folder)
7505- gtk_file_path_free (impl->current_folder); 5709@@ -7011,17 +3177,6 @@
7506- 5710 impl->reload_state = RELOAD_HAS_FOLDER;
7507- impl->current_folder = gtk_file_path_copy (data->path); 5711 }
7508- 5712
7509- impl->reload_state = RELOAD_HAS_FOLDER;
7510- }
7511-
7512- /* Update the widgets that may trigger a folder change themselves. */ 5713- /* Update the widgets that may trigger a folder change themselves. */
7513- 5714-
7514- if (!impl->changing_folder) 5715- if (!impl->changing_folder)
@@ -7520,53 +5721,27 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
7520- impl->changing_folder = FALSE; 5721- impl->changing_folder = FALSE;
7521- } 5722- }
7522- 5723-
7523- /* Set the folder on the save entry */ 5724 /* Set the folder on the save entry */
7524- 5725
7525- if (impl->location_entry) 5726 if (impl->location_entry)
7526- { 5727@@ -7041,13 +3196,7 @@
7527- _gtk_file_chooser_entry_set_base_folder (GTK_FILE_CHOOSER_ENTRY (impl->location_entry), 5728
7528- impl->current_folder); 5729 /* Refresh controls */
7529- 5730
7530- if (data->clear_entry)
7531- _gtk_file_chooser_entry_set_file_part (GTK_FILE_CHOOSER_ENTRY (impl->location_entry), "");
7532- }
7533-
7534- /* Create a new list model. This is slightly evil; we store the result value
7535- * but perform more actions rather than returning immediately even if it
7536- * generates an error.
7537- */
7538- set_list_model (impl, NULL);
7539-
7540- /* Refresh controls */
7541-
7542- shortcuts_find_current_folder (impl); 5731- shortcuts_find_current_folder (impl);
7543- 5732-
7544- g_signal_emit_by_name (impl, "current-folder-changed", 0); 5733 g_signal_emit_by_name (impl, "current-folder-changed", 0);
7545- 5734-
7546- check_preview_change (impl); 5735- check_preview_change (impl);
7547- bookmarks_check_add_sensitivity (impl); 5736- bookmarks_check_add_sensitivity (impl);
7548- 5737-
7549- g_signal_emit_by_name (impl, "selection-changed", 0); 5738 g_signal_emit_by_name (impl, "selection-changed", 0);
7550- 5739
7551-out: 5740 out:
7552- gtk_file_path_free (data->path); 5741@@ -7069,18 +3218,6 @@
7553- g_free (data); 5742
7554- 5743 profile_start ("start", (char *) path);
7555- g_object_unref (handle); 5744
7556-}
7557-
7558-static gboolean
7559-gtk_file_chooser_default_update_current_folder (GtkFileChooser *chooser,
7560- const GtkFilePath *path,
7561- gboolean keep_trail,
7562- gboolean clear_entry,
7563- GError **error)
7564-{
7565- GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (chooser);
7566- struct UpdateCurrentFolderData *data;
7567-
7568- profile_start ("start", (char *) path);
7569-
7570- switch (impl->operation_mode) 5745- switch (impl->operation_mode)
7571- { 5746- {
7572- case OPERATION_MODE_SEARCH: 5747- case OPERATION_MODE_SEARCH:
@@ -7579,214 +5754,53 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
7579- break; 5754- break;
7580- } 5755- }
7581- 5756-
7582- g_assert (path != NULL); 5757 g_assert (path != NULL);
7583- 5758
7584- if (impl->local_only && 5759 if (impl->local_only &&
7585- !gtk_file_system_path_is_local (impl->file_system, path)) 5760@@ -7123,10 +3260,6 @@
7586- { 5761 {
7587- g_set_error (error, 5762 GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (chooser);
7588- GTK_FILE_CHOOSER_ERROR, 5763
7589- GTK_FILE_CHOOSER_ERROR_BAD_FILENAME,
7590- _("Cannot change to folder because it is not local"));
7591-
7592- profile_end ("end - not local", (char *) path);
7593- return FALSE;
7594- }
7595-
7596- if (impl->update_current_folder_handle)
7597- gtk_file_system_cancel_operation (impl->update_current_folder_handle);
7598-
7599- /* Test validity of path here. */
7600- data = g_new0 (struct UpdateCurrentFolderData, 1);
7601- data->impl = impl;
7602- data->path = gtk_file_path_copy (path);
7603- data->keep_trail = keep_trail;
7604- data->clear_entry = clear_entry;
7605-
7606- impl->reload_state = RELOAD_HAS_FOLDER;
7607-
7608- impl->update_current_folder_handle =
7609- gtk_file_system_get_info (impl->file_system, path, GTK_FILE_INFO_IS_FOLDER,
7610- update_current_folder_get_info_cb,
7611- data);
7612-
7613- set_busy_cursor (impl, TRUE);
7614-
7615- profile_end ("end", NULL);
7616- return TRUE;
7617-}
7618-
7619-static GtkFilePath *
7620-gtk_file_chooser_default_get_current_folder (GtkFileChooser *chooser)
7621-{
7622- GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (chooser);
7623-
7624- if (impl->operation_mode == OPERATION_MODE_SEARCH || 5764- if (impl->operation_mode == OPERATION_MODE_SEARCH ||
7625- impl->operation_mode == OPERATION_MODE_RECENT) 5765- impl->operation_mode == OPERATION_MODE_RECENT)
7626- return NULL; 5766- return NULL;
7627- 5767-
7628- if (impl->reload_state == RELOAD_EMPTY) 5768 if (impl->reload_state == RELOAD_EMPTY)
7629- { 5769 {
7630- char *current_working_dir; 5770 char *current_working_dir;
7631- GtkFilePath *path; 5771@@ -7151,8 +3284,8 @@
7632- 5772 {
7633- /* We are unmapped, or we had an error while loading the last folder. We'll return 5773 GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (chooser);
7634- * the $cwd since once we get (re)mapped, we'll load $cwd anyway unless the caller 5774
7635- * explicitly calls set_current_folder() on us.
7636- */
7637- current_working_dir = g_get_current_dir ();
7638- path = gtk_file_system_filename_to_path (impl->file_system, current_working_dir);
7639- g_free (current_working_dir);
7640- return path;
7641- }
7642-
7643- return gtk_file_path_copy (impl->current_folder);
7644-}
7645-
7646-static void
7647-gtk_file_chooser_default_set_current_name (GtkFileChooser *chooser,
7648- const gchar *name)
7649-{
7650- GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (chooser);
7651-
7652- g_return_if_fail (impl->action == GTK_FILE_CHOOSER_ACTION_SAVE || 5775- g_return_if_fail (impl->action == GTK_FILE_CHOOSER_ACTION_SAVE ||
7653- impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER); 5776- impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER);
7654- 5777+ g_return_if_fail (impl->action == GTK_FILE_CHOOSER_ACTION_SAVE
7655- pending_select_paths_free (impl); 5778+ || impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER);
7656- _gtk_file_chooser_entry_set_file_part (GTK_FILE_CHOOSER_ENTRY (impl->location_entry), name); 5779
7657-} 5780 pending_select_paths_free (impl);
7658- 5781 _gtk_file_chooser_entry_set_file_part (GTK_FILE_CHOOSER_ENTRY (impl->location_entry), name);
7659-static void 5782@@ -7187,14 +3320,10 @@
7660-select_func (GtkFileSystemModel *model, 5783 return FALSE;
7661- GtkTreePath *path, 5784
7662- GtkTreeIter *iter, 5785 if (!parent_path)
7663- gpointer user_data)
7664-{
7665- GtkFileChooserDefault *impl = user_data;
7666- GtkTreeSelection *selection;
7667- GtkTreeIter sorted_iter;
7668-
7669- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_files_tree_view));
7670-
7671- gtk_tree_model_sort_convert_child_iter_to_iter (impl->sort_model, &sorted_iter, iter);
7672- gtk_tree_selection_select_iter (selection, &sorted_iter);
7673-}
7674-
7675-static gboolean
7676-gtk_file_chooser_default_select_path (GtkFileChooser *chooser,
7677- const GtkFilePath *path,
7678- GError **error)
7679-{
7680- GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (chooser);
7681- GtkFilePath *parent_path;
7682- gboolean same_path;
7683-
7684- if (!gtk_file_system_get_parent (impl->file_system, path, &parent_path, error))
7685- return FALSE;
7686-
7687- if (!parent_path)
7688- return _gtk_file_chooser_set_current_folder_path (chooser, path, error); 5786- return _gtk_file_chooser_set_current_folder_path (chooser, path, error);
7689- 5787+ return _gtk_file_chooser_set_current_folder_path (chooser, path, error);
5788
7690- if (impl->operation_mode == OPERATION_MODE_SEARCH || 5789- if (impl->operation_mode == OPERATION_MODE_SEARCH ||
7691- impl->operation_mode == OPERATION_MODE_RECENT || 5790- impl->operation_mode == OPERATION_MODE_RECENT ||
7692- impl->load_state == LOAD_EMPTY) 5791- impl->load_state == LOAD_EMPTY)
7693- { 5792- {
7694- same_path = FALSE; 5793- same_path = FALSE;
7695- } 5794- }
7696- else 5795+ if (impl->load_state == LOAD_EMPTY)
7697- { 5796+ same_path = FALSE;
7698- g_assert (impl->current_folder != NULL); 5797 else
7699- 5798 {
7700- same_path = gtk_file_path_compare (parent_path, impl->current_folder) == 0; 5799 g_assert (impl->current_folder != NULL);
7701- } 5800@@ -7289,17 +3418,6 @@
7702- 5801 gtk_file_chooser_default_select_all (GtkFileChooser *chooser)
7703- if (same_path && impl->load_state == LOAD_FINISHED) 5802 {
7704- { 5803 GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (chooser);
7705- gboolean result;
7706- GSList paths;
7707-
7708- paths.data = (gpointer) path;
7709- paths.next = NULL;
7710-
7711- result = show_and_select_paths (impl, parent_path, &paths, error);
7712- gtk_file_path_free (parent_path);
7713- return result;
7714- }
7715-
7716- pending_select_paths_add (impl, path);
7717-
7718- if (!same_path)
7719- {
7720- gboolean result;
7721-
7722- result = _gtk_file_chooser_set_current_folder_path (chooser, parent_path, error);
7723- gtk_file_path_free (parent_path);
7724- return result;
7725- }
7726-
7727- gtk_file_path_free (parent_path);
7728- return TRUE;
7729-}
7730-
7731-static void
7732-unselect_func (GtkFileSystemModel *model,
7733- GtkTreePath *path,
7734- GtkTreeIter *iter,
7735- gpointer user_data)
7736-{
7737- GtkFileChooserDefault *impl = user_data;
7738- GtkTreeView *tree_view = GTK_TREE_VIEW (impl->browse_files_tree_view);
7739- GtkTreePath *sorted_path;
7740-
7741- sorted_path = gtk_tree_model_sort_convert_child_path_to_path (impl->sort_model,
7742- path);
7743- gtk_tree_selection_unselect_path (gtk_tree_view_get_selection (tree_view),
7744- sorted_path);
7745- gtk_tree_path_free (sorted_path);
7746-}
7747-
7748-static void
7749-gtk_file_chooser_default_unselect_path (GtkFileChooser *chooser,
7750- const GtkFilePath *path)
7751-{
7752- GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (chooser);
7753-
7754- if (!impl->browse_files_model)
7755- return;
7756-
7757- _gtk_file_system_model_path_do (impl->browse_files_model, path,
7758- unselect_func, impl);
7759-}
7760-
7761-static gboolean
7762-maybe_select (GtkTreeModel *model,
7763- GtkTreePath *path,
7764- GtkTreeIter *iter,
7765- gpointer data)
7766-{
7767- GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (data);
7768- GtkTreeSelection *selection;
7769- const GtkFileInfo *info;
7770- gboolean is_folder;
7771-
7772- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_files_tree_view));
7773-
7774- info = get_list_file_info (impl, iter);
7775- is_folder = gtk_file_info_get_is_folder (info);
7776-
7777- if ((is_folder && impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER) ||
7778- (!is_folder && impl->action == GTK_FILE_CHOOSER_ACTION_OPEN))
7779- gtk_tree_selection_select_iter (selection, iter);
7780- else
7781- gtk_tree_selection_unselect_iter (selection, iter);
7782-
7783- return FALSE;
7784-}
7785-
7786-static void
7787-gtk_file_chooser_default_select_all (GtkFileChooser *chooser)
7788-{
7789- GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (chooser);
7790- 5804-
7791- if (impl->operation_mode == OPERATION_MODE_SEARCH || 5805- if (impl->operation_mode == OPERATION_MODE_SEARCH ||
7792- impl->operation_mode == OPERATION_MODE_RECENT) 5806- impl->operation_mode == OPERATION_MODE_RECENT)
@@ -7798,274 +5812,54 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
7798- return; 5812- return;
7799- } 5813- }
7800- 5814-
7801- if (impl->select_multiple) 5815 if (impl->select_multiple)
7802- gtk_tree_model_foreach (GTK_TREE_MODEL (impl->sort_model), 5816 gtk_tree_model_foreach (GTK_TREE_MODEL (impl->sort_model),
7803- maybe_select, impl); 5817 maybe_select, impl);
7804-} 5818@@ -7340,9 +3458,8 @@
7805- 5819
7806-static void 5820 g_assert (impl->action == GTK_FILE_CHOOSER_ACTION_SAVE
7807-gtk_file_chooser_default_unselect_all (GtkFileChooser *chooser) 5821 || impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER
7808-{
7809- GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (chooser);
7810- GtkTreeSelection *selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_files_tree_view));
7811-
7812- gtk_tree_selection_unselect_all (selection);
7813- pending_select_paths_free (impl);
7814-}
7815-
7816-/* Checks whether the filename entry for the Save modes contains a well-formed filename.
7817- *
7818- * is_well_formed_ret - whether what the user typed passes gkt_file_system_make_path()
7819- *
7820- * is_empty_ret - whether the file entry is totally empty
7821- *
7822- * is_file_part_empty_ret - whether the file part is empty (will be if user types "foobar/", and
7823- * the path will be "$cwd/foobar")
7824- */
7825-static void
7826-check_save_entry (GtkFileChooserDefault *impl,
7827- GtkFilePath **path_ret,
7828- gboolean *is_well_formed_ret,
7829- gboolean *is_empty_ret,
7830- gboolean *is_file_part_empty_ret,
7831- gboolean *is_folder)
7832-{
7833- GtkFileChooserEntry *chooser_entry;
7834- const GtkFilePath *current_folder;
7835- const char *file_part;
7836- GtkFilePath *path;
7837- GError *error;
7838-
7839- g_assert (impl->action == GTK_FILE_CHOOSER_ACTION_SAVE
7840- || impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER
7841- || ((impl->action == GTK_FILE_CHOOSER_ACTION_OPEN 5822- || ((impl->action == GTK_FILE_CHOOSER_ACTION_OPEN
7842- || impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER) 5823- || impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER)
7843- && impl->location_mode == LOCATION_MODE_FILENAME_ENTRY)); 5824- && impl->location_mode == LOCATION_MODE_FILENAME_ENTRY));
7844- 5825+ || impl->action == GTK_FILE_CHOOSER_ACTION_OPEN
7845- chooser_entry = GTK_FILE_CHOOSER_ENTRY (impl->location_entry); 5826+ || impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER);
7846-
7847- if (strlen (gtk_entry_get_text (GTK_ENTRY (chooser_entry))) == 0)
7848- {
7849- *path_ret = NULL;
7850- *is_well_formed_ret = TRUE;
7851- *is_empty_ret = TRUE;
7852- *is_file_part_empty_ret = TRUE;
7853- *is_folder = FALSE;
7854-
7855- return;
7856- }
7857-
7858- *is_empty_ret = FALSE;
7859-
7860- current_folder = _gtk_file_chooser_entry_get_current_folder (chooser_entry);
7861- if (!current_folder)
7862- {
7863- *path_ret = NULL;
7864- *is_well_formed_ret = FALSE;
7865- *is_file_part_empty_ret = FALSE;
7866- *is_folder = FALSE;
7867-
7868- return;
7869- }
7870-
7871- file_part = _gtk_file_chooser_entry_get_file_part (chooser_entry);
7872-
7873- if (!file_part || file_part[0] == '\0')
7874- {
7875- *path_ret = gtk_file_path_copy (current_folder);
7876- *is_well_formed_ret = TRUE;
7877- *is_file_part_empty_ret = TRUE;
7878- *is_folder = TRUE;
7879-
7880- return;
7881- }
7882-
7883- *is_file_part_empty_ret = FALSE;
7884-
7885- error = NULL;
7886- path = gtk_file_system_make_path (impl->file_system, current_folder, file_part, &error);
7887-
7888- if (!path)
7889- {
7890- error_building_filename_dialog (impl, current_folder, file_part, error);
7891- *path_ret = NULL;
7892- *is_well_formed_ret = FALSE;
7893- *is_folder = FALSE;
7894-
7895- return;
7896- }
7897-
7898- *path_ret = path;
7899- *is_well_formed_ret = TRUE;
7900- *is_folder = _gtk_file_chooser_entry_get_is_folder (chooser_entry, path);
7901-}
7902-
7903-struct get_paths_closure {
7904- GtkFileChooserDefault *impl;
7905- GSList *result;
7906- GtkFilePath *path_from_entry;
7907-};
7908-
7909-static void
7910-get_paths_foreach (GtkTreeModel *model,
7911- GtkTreePath *path,
7912- GtkTreeIter *iter,
7913- gpointer data)
7914-{
7915- struct get_paths_closure *info;
7916- const GtkFilePath *file_path;
7917- GtkFileSystemModel *fs_model;
7918- GtkTreeIter sel_iter;
7919-
7920- info = data;
7921- fs_model = info->impl->browse_files_model;
7922- gtk_tree_model_sort_convert_iter_to_child_iter (info->impl->sort_model, &sel_iter, iter);
7923-
7924- file_path = _gtk_file_system_model_get_path (fs_model, &sel_iter);
7925- if (!file_path)
7926- return; /* We are on the editable row */
7927+ case GTK_FILE_CHOOSER_PROP_FILTER:
7928+ g_value_set_object (value, impl->current_filter);
7929+ break;
7930 5827
7931- if (!info->path_from_entry 5828 chooser_entry = GTK_FILE_CHOOSER_ENTRY (impl->location_entry);
7932- || gtk_file_path_compare (info->path_from_entry, file_path) != 0)
7933- info->result = g_slist_prepend (info->result, gtk_file_path_copy (file_path));
7934-}
7935+ case GTK_FILE_CHOOSER_PROP_LOCAL_ONLY:
7936+ g_value_set_boolean (value, impl->local_only);
7937+ break;
7938 5829
7939-static GSList * 5830@@ -7439,14 +3556,7 @@
7940-gtk_file_chooser_default_get_paths (GtkFileChooser *chooser) 5831 struct get_paths_closure info;
7941-{ 5832 GtkWindow *toplevel;
7942- GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (chooser); 5833 GtkWidget *current_focus;
7943- struct get_paths_closure info;
7944- GtkWindow *toplevel;
7945- GtkWidget *current_focus;
7946- gboolean file_list_seen; 5834- gboolean file_list_seen;
7947+ case GTK_FILE_CHOOSER_PROP_SELECT_MULTIPLE:
7948+ g_value_set_boolean (value, impl->select_multiple);
7949+ break;
7950 5835
7951- if (impl->operation_mode == OPERATION_MODE_SEARCH) 5836- if (impl->operation_mode == OPERATION_MODE_SEARCH)
7952- return search_get_selected_paths (impl); 5837- return search_get_selected_paths (impl);
7953+ case GTK_FILE_CHOOSER_PROP_SHOW_HIDDEN: 5838-
7954+ g_value_set_boolean (value, impl->show_hidden);
7955+ break;
7956
7957- if (impl->operation_mode == OPERATION_MODE_RECENT) 5839- if (impl->operation_mode == OPERATION_MODE_RECENT)
7958- return recent_get_selected_paths (impl); 5840- return recent_get_selected_paths (impl);
7959+ case GTK_FILE_CHOOSER_PROP_ROOT_FOLDER: 5841-
7960+ g_value_set_string (value, impl->root_folder); 5842 info.impl = impl;
7961+ break; 5843 info.result = NULL;
7962 5844 info.path_from_entry = NULL;
7963- info.impl = impl; 5845@@ -7457,14 +3567,12 @@
7964- info.result = NULL; 5846 else
7965- info.path_from_entry = NULL; 5847 current_focus = NULL;
7966+ case GTK_FILE_CHOOSER_PROP_SHOW_CREATE_FOLDER:
7967+ g_value_set_boolean (value, impl->show_create_folder);
7968+ break;
7969
7970- toplevel = get_toplevel (GTK_WIDGET (impl));
7971- if (toplevel)
7972- current_focus = gtk_window_get_focus (toplevel);
7973- else
7974- current_focus = NULL;
7975+ case GTK_FILE_CHOOSER_PROP_PREVIEW_WIDGET:
7976+ g_value_set_object (value, NULL);
7977+ break;
7978 5848
7979- file_list_seen = FALSE; 5849- file_list_seen = FALSE;
7980- if (current_focus == impl->browse_files_tree_view) 5850 if (current_focus == impl->browse_files_tree_view)
7981- {
7982- GtkTreeSelection *selection;
7983+ case GTK_FILE_CHOOSER_PROP_PREVIEW_WIDGET_ACTIVE:
7984+ g_value_set_boolean (value, FALSE);
7985+ break;
7986
7987- file_list:
7988+ case GTK_FILE_CHOOSER_PROP_USE_PREVIEW_LABEL:
7989+ g_value_set_boolean (value, FALSE);
7990+ break;
7991
7992- file_list_seen = TRUE;
7993- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_files_tree_view));
7994- gtk_tree_selection_selected_foreach (selection, get_paths_foreach, &info);
7995+ case GTK_FILE_CHOOSER_PROP_DO_OVERWRITE_CONFIRMATION:
7996+ g_value_set_boolean (value, impl->do_overwrite_confirmation);
7997+ break;
7998
7999- /* If there is no selection in the file list, we probably have this situation:
8000- *
8001- * 1. The user typed a filename in the SAVE filename entry ("foo.txt").
8002- * 2. He then double-clicked on a folder ("bar") in the file list
8003- *
8004- * So we want the selection to be "bar/foo.txt". Jump to the case for the
8005- * filename entry to see if that is the case.
8006- */
8007- if (info.result == NULL && impl->location_entry)
8008- goto file_entry;
8009+ default:
8010+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
8011+ break;
8012 }
8013- else if (impl->location_entry && current_focus == impl->location_entry)
8014+}
8015+
8016+/* Removes the settings signal handler. It's safe to call multiple times */
8017+static void
8018+remove_settings_signal (GtkFileChooserDefault *impl,
8019+ GdkScreen *screen)
8020+{
8021+ if (impl->settings_signal_id)
8022 { 5851 {
8023- gboolean is_well_formed, is_empty, is_file_part_empty, is_folder; 5852 GtkTreeSelection *selection;
8024+ GtkSettings *settings;
8025
8026- file_entry:
8027+ settings = gtk_settings_get_for_screen (screen);
8028+ g_signal_handler_disconnect (settings,
8029+ impl->settings_signal_id);
8030+ impl->settings_signal_id = 0;
8031+ }
8032+}
8033 5853
8034- check_save_entry (impl, &info.path_from_entry, &is_well_formed, &is_empty, &is_file_part_empty, &is_folder); 5854 file_list:
8035+static void
8036+gtk_file_chooser_default_dispose (GObject *object)
8037+{
8038+ GSList *l;
8039+ GtkFileChooserDefault *impl = (GtkFileChooserDefault *) object;
8040
8041- if (is_empty)
8042- goto out;
8043+ if (impl->volumes_changed_id > 0)
8044+ {
8045+ g_signal_handler_disconnect (impl->file_system, impl->volumes_changed_id);
8046+ impl->volumes_changed_id = 0;
8047+ }
8048 5855
8049- if (!is_well_formed) 5856- file_list_seen = TRUE;
8050- return NULL; 5857 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_files_tree_view));
8051+ pending_select_paths_free (impl); 5858 gtk_tree_selection_selected_foreach (selection, get_paths_foreach, &info);
8052 5859
8053- if (is_file_part_empty && impl->action == GTK_FILE_CHOOSER_ACTION_SAVE) 5860@@ -7499,12 +3607,8 @@
8054- { 5861 return NULL;
8055- gtk_file_path_free (info.path_from_entry); 5862 }
8056- return NULL;
8057- }
8058+ /* cancel all pending operations */
8059+ if (impl->pending_handles)
8060+ {
8061+ for (l = impl->pending_handles; l; l = l->next)
8062+ {
8063+ GtkFileSystemHandle *handle =l->data;
8064+ gtk_file_system_cancel_operation (handle);
8065+ }
8066+ g_slist_free (impl->pending_handles);
8067+ impl->pending_handles = NULL;
8068+ }
8069 5863
8070- if (info.path_from_entry) 5864- if (info.path_from_entry)
8071- info.result = g_slist_prepend (info.result, info.path_from_entry); 5865- info.result = g_slist_prepend (info.result, info.path_from_entry);
@@ -8073,269 +5867,76 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
8073- goto file_list; 5867- goto file_list;
8074- else 5868- else
8075- return NULL; 5869- return NULL;
8076+ if (impl->reload_icon_handles) 5870+ g_assert (info.path_from_entry != NULL);
8077+ { 5871+ info.result = g_slist_prepend (info.result, info.path_from_entry);
8078+ for (l = impl->reload_icon_handles; l; l = l->next)
8079+ {
8080+ GtkFileSystemHandle *handle =l->data;
8081+ gtk_file_system_cancel_operation (handle);
8082+ }
8083+ g_slist_free (impl->reload_icon_handles);
8084+ impl->reload_icon_handles = NULL;
8085 } 5872 }
8086- else if (impl->toplevel_last_focus_widget == impl->browse_files_tree_view) 5873 else if (impl->toplevel_last_focus_widget == impl->browse_files_tree_view)
8087- goto file_list; 5874 goto file_list;
8088- else if (impl->location_entry && impl->toplevel_last_focus_widget == impl->location_entry) 5875@@ -7512,9 +3616,9 @@
8089- goto file_entry; 5876 goto file_entry;
8090- else 5877 else
8091+
8092+ if (impl->update_current_folder_handle)
8093 { 5878 {
8094- /* The focus is on a dialog's action area button or something else */ 5879- /* The focus is on a dialog's action area button or something else */
8095- if (impl->action == GTK_FILE_CHOOSER_ACTION_SAVE || 5880- if (impl->action == GTK_FILE_CHOOSER_ACTION_SAVE ||
8096- impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER) 5881- impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)
8097- goto file_entry; 5882+ /* The focus is on a dialog's action area button or something else */
8098- else 5883+ if (impl->action == GTK_FILE_CHOOSER_ACTION_SAVE
8099- goto file_list; 5884+ || impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)
8100+ gtk_file_system_cancel_operation (impl->update_current_folder_handle); 5885 goto file_entry;
8101+ impl->update_current_folder_handle = NULL; 5886 else
8102 } 5887 goto file_list;
8103 5888@@ -7533,17 +3637,6 @@
8104- out: 5889 return g_slist_reverse (info.result);
8105+ if (impl->show_and_select_paths_handle) 5890 }
8106+ {
8107+ gtk_file_system_cancel_operation (impl->show_and_select_paths_handle);
8108+ impl->show_and_select_paths_handle = NULL;
8109+ }
8110
8111- /* If there's no folder selected, and we're in SELECT_FOLDER mode, then we
8112- * fall back to the current directory */
8113- if (impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER &&
8114- info.result == NULL)
8115+ if (impl->should_respond_get_info_handle)
8116 {
8117- info.result = g_slist_prepend (info.result, _gtk_file_chooser_get_current_folder_path (chooser));
8118+ gtk_file_system_cancel_operation (impl->should_respond_get_info_handle);
8119+ impl->should_respond_get_info_handle = NULL;
8120 }
8121
8122- return g_slist_reverse (info.result);
8123-}
8124+ if (impl->update_from_entry_handle)
8125+ {
8126+ gtk_file_system_cancel_operation (impl->update_from_entry_handle);
8127+ impl->update_from_entry_handle = NULL;
8128+ }
8129 5891
8130-static GtkFilePath * 5892-static GtkFilePath *
8131-gtk_file_chooser_default_get_preview_path (GtkFileChooser *chooser) 5893-gtk_file_chooser_default_get_preview_path (GtkFileChooser *chooser)
8132-{ 5894-{
8133- GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (chooser); 5895- GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (chooser);
8134+ remove_settings_signal (impl, gtk_widget_get_screen (GTK_WIDGET (impl))); 5896-
8135
8136- if (impl->preview_path) 5897- if (impl->preview_path)
8137- return gtk_file_path_copy (impl->preview_path); 5898- return gtk_file_path_copy (impl->preview_path);
8138- else 5899- else
8139- return NULL; 5900- return NULL;
8140+ G_OBJECT_CLASS (_gtk_file_chooser_default_parent_class)->dispose (object); 5901-}
8141 }
8142
8143-static GtkFileSystem *
8144-gtk_file_chooser_default_get_file_system (GtkFileChooser *chooser)
8145+/* We override show-all since we have internal widgets that
8146+ * shouldn't be shown when you call show_all(), like the filter
8147+ * combo box.
8148+ */
8149+static void
8150+gtk_file_chooser_default_show_all (GtkWidget *widget)
8151 {
8152- GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (chooser);
8153- 5902-
8154- return impl->file_system; 5903 static GtkFileSystem *
8155+ gtk_widget_show (widget); 5904 gtk_file_chooser_default_get_file_system (GtkFileChooser *chooser)
8156 }
8157
8158-/* Shows or hides the filter widgets */
8159+/* Handler for GtkWindow::set-focus; this is where we save the last-focused
8160+ * widget on our toplevel. See gtk_file_chooser_default_hierarchy_changed()
8161+ */
8162 static void
8163-show_filters (GtkFileChooserDefault *impl,
8164- gboolean show)
8165+toplevel_set_focus_cb (GtkWindow *window,
8166+ GtkWidget *focus,
8167+ GtkFileChooserDefault *impl)
8168 { 5905 {
8169- if (show) 5906@@ -7558,9 +3651,9 @@
5907 gboolean show)
5908 {
5909 if (show)
8170- gtk_widget_show (impl->filter_combo_hbox); 5910- gtk_widget_show (impl->filter_combo_hbox);
8171- else 5911+ gtk_widget_show (impl->filter_combo);
5912 else
8172- gtk_widget_hide (impl->filter_combo_hbox); 5913- gtk_widget_hide (impl->filter_combo_hbox);
8173+ impl->toplevel_last_focus_widget = gtk_window_get_focus (window); 5914+ gtk_widget_hide (impl->filter_combo);
8174 } 5915 }
8175 5916
8176+/* We monitor the focus widget on our toplevel to be able to know which widget
8177+ * was last focused at the time our "should_respond" method gets called.
8178+ */
8179 static void 5917 static void
8180-gtk_file_chooser_default_add_filter (GtkFileChooser *chooser, 5918@@ -7588,7 +3683,7 @@
8181- GtkFileFilter *filter) 5919 if (!g_slist_find (impl->filters, impl->current_filter))
8182+gtk_file_chooser_default_hierarchy_changed (GtkWidget *widget, 5920 set_current_filter (impl, filter);
8183+ GtkWidget *previous_toplevel)
8184 {
8185- GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (chooser);
8186- const gchar *name;
8187+ GtkFileChooserDefault *impl;
8188+ GtkWidget *toplevel;
8189
8190- if (g_slist_find (impl->filters, filter))
8191+ impl = GTK_FILE_CHOOSER_DEFAULT (widget);
8192+
8193+ if (previous_toplevel)
8194 {
8195- g_warning ("gtk_file_chooser_add_filter() called on filter already in list\n");
8196- return;
8197+ g_assert (impl->toplevel_set_focus_id != 0);
8198+ g_signal_handler_disconnect (previous_toplevel, impl->toplevel_set_focus_id);
8199+ impl->toplevel_set_focus_id = 0;
8200+ impl->toplevel_last_focus_widget = NULL;
8201 }
8202+ else
8203+ g_assert (impl->toplevel_set_focus_id == 0);
8204
8205- g_object_ref_sink (filter);
8206- impl->filters = g_slist_append (impl->filters, filter);
8207+ toplevel = gtk_widget_get_toplevel (widget);
8208+ if (GTK_IS_WINDOW (toplevel))
8209+ {
8210+ impl->toplevel_set_focus_id = g_signal_connect (toplevel, "set_focus",
8211+ G_CALLBACK (toplevel_set_focus_cb), impl);
8212+ impl->toplevel_last_focus_widget = gtk_window_get_focus (GTK_WINDOW (toplevel));
8213+ }
8214+}
8215
8216- name = gtk_file_filter_get_name (filter);
8217- if (!name)
8218- name = "Untitled filter"; /* Place-holder, doesn't need to be marked for translation */
8219+/* Changes the icons wherever it is needed */
8220+static void
8221+change_icon_theme (GtkFileChooserDefault *impl)
8222+{
8223+ GtkSettings *settings;
8224+ gint width, height;
8225
8226- gtk_combo_box_append_text (GTK_COMBO_BOX (impl->filter_combo), name);
8227+ profile_start ("start", NULL);
8228
8229- if (!g_slist_find (impl->filters, impl->current_filter))
8230- set_current_filter (impl, filter);
8231+ settings = gtk_settings_get_for_screen (gtk_widget_get_screen (GTK_WIDGET (impl)));
8232+
8233+ if (gtk_icon_size_lookup_for_settings (settings, GTK_ICON_SIZE_MENU, &width, &height))
8234+ impl->icon_size = MAX (width, height);
8235+ else
8236+ impl->icon_size = FALLBACK_ICON_SIZE;
8237+
8238+ gtk_widget_queue_resize (impl->browse_files_tree_view);
8239+
8240+ profile_end ("end", NULL);
8241+}
8242+
8243+/* Callback used when a GtkSettings value changes */
8244+static void
8245+settings_notify_cb (GObject *object,
8246+ GParamSpec *pspec,
8247+ GtkFileChooserDefault *impl)
8248+{
8249+ const char *name;
8250+
8251+ profile_start ("start", NULL);
8252+
8253+ name = g_param_spec_get_name (pspec);
8254+
8255+ if (strcmp (name, "gtk-icon-theme-name") == 0
8256+ || strcmp (name, "gtk-icon-sizes") == 0)
8257+ change_icon_theme (impl);
8258 5921
8259- show_filters (impl, TRUE); 5922- show_filters (impl, TRUE);
8260+ profile_end ("end", NULL); 5923+ show_filters (impl, g_slist_length (impl->filters) > 1);
8261 } 5924 }
8262 5925
8263+/* Installs a signal handler for GtkSettings so that we can monitor changes in
8264+ * the icon theme.
8265+ */
8266 static void 5926 static void
8267-gtk_file_chooser_default_remove_filter (GtkFileChooser *chooser, 5927@@ -7627,8 +3722,7 @@
8268- GtkFileFilter *filter)
8269+check_icon_theme (GtkFileChooserDefault *impl)
8270 {
8271- GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (chooser);
8272- GtkTreeModel *model;
8273- GtkTreeIter iter;
8274- gint filter_index;
8275+ GtkSettings *settings;
8276
8277- filter_index = g_slist_index (impl->filters, filter);
8278+ profile_start ("start", NULL);
8279
8280- if (filter_index < 0)
8281+ if (impl->settings_signal_id)
8282 {
8283- g_warning ("gtk_file_chooser_remove_filter() called on filter not in list\n");
8284+ profile_end ("end", NULL);
8285 return;
8286 }
8287
8288- impl->filters = g_slist_remove (impl->filters, filter);
8289-
8290- if (filter == impl->current_filter)
8291+ if (gtk_widget_has_screen (GTK_WIDGET (impl)))
8292 {
8293- if (impl->filters)
8294- set_current_filter (impl, impl->filters->data);
8295- else
8296- set_current_filter (impl, NULL);
8297+ settings = gtk_settings_get_for_screen (gtk_widget_get_screen (GTK_WIDGET (impl)));
8298+ impl->settings_signal_id = g_signal_connect (settings, "notify",
8299+ G_CALLBACK (settings_notify_cb), impl);
8300+
8301+ change_icon_theme (impl);
8302 }
8303 5928
8304- /* Remove row from the combo box */ 5929 g_object_unref (filter);
8305- model = gtk_combo_box_get_model (GTK_COMBO_BOX (impl->filter_combo));
8306- if (!gtk_tree_model_iter_nth_child (model, &iter, NULL, filter_index))
8307- g_assert_not_reached ();
8308+ profile_end ("end", NULL);
8309+}
8310
8311- gtk_list_store_remove (GTK_LIST_STORE (model), &iter);
8312+static void
8313+gtk_file_chooser_default_style_set (GtkWidget *widget,
8314+ GtkStyle *previous_style)
8315+{
8316+ GtkFileChooserDefault *impl;
8317
8318- g_object_unref (filter);
8319+ profile_start ("start", NULL);
8320 5930
8321- if (!impl->filters) 5931- if (!impl->filters)
8322- show_filters (impl, FALSE); 5932- show_filters (impl, FALSE);
8323-} 5933+ show_filters (impl, g_slist_length (impl->filters) > 1);
8324+ impl = GTK_FILE_CHOOSER_DEFAULT (widget); 5934 }
8325
8326-static GSList *
8327-gtk_file_chooser_default_list_filters (GtkFileChooser *chooser)
8328-{
8329- GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (chooser);
8330+ profile_msg (" parent class style_set start", NULL);
8331+ if (GTK_WIDGET_CLASS (_gtk_file_chooser_default_parent_class)->style_set)
8332+ GTK_WIDGET_CLASS (_gtk_file_chooser_default_parent_class)->style_set (widget, previous_style);
8333+ profile_msg (" parent class style_set end", NULL);
8334 5935
8335- return g_slist_copy (impl->filters); 5936 static GSList *
8336-} 5937@@ -7639,234 +3733,6 @@
8337+ if (gtk_widget_has_screen (GTK_WIDGET (impl))) 5938 return g_slist_copy (impl->filters);
8338+ change_icon_theme (impl); 5939 }
8339 5940
8340-/* Returns the position in the shortcuts tree where the nth specified shortcut would appear */ 5941-/* Returns the position in the shortcuts tree where the nth specified shortcut would appear */
8341-static int 5942-static int
@@ -8344,67 +5945,48 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
8344-{ 5945-{
8345- return pos + shortcuts_get_index (impl, SHORTCUTS_SHORTCUTS); 5946- return pos + shortcuts_get_index (impl, SHORTCUTS_SHORTCUTS);
8346-} 5947-}
8347+ profile_msg (" emit default-size-changed start", NULL); 5948-
8348+ g_signal_emit_by_name (widget, "default-size-changed");
8349+ profile_msg (" emit default-size-changed end", NULL);
8350
8351-struct AddShortcutData 5949-struct AddShortcutData
8352-{ 5950-{
8353- GtkFileChooserDefault *impl; 5951- GtkFileChooserDefault *impl;
8354- GtkFilePath *path; 5952- GtkFilePath *path;
8355-}; 5953-};
8356+ profile_end ("end", NULL); 5954-
8357+} 5955-static void
8358
8359 static void
8360-add_shortcut_get_info_cb (GtkFileSystemHandle *handle, 5956-add_shortcut_get_info_cb (GtkFileSystemHandle *handle,
8361- const GtkFileInfo *info, 5957- const GtkFileInfo *info,
8362- const GError *error, 5958- const GError *error,
8363- gpointer user_data) 5959- gpointer user_data)
8364+gtk_file_chooser_default_screen_changed (GtkWidget *widget, 5960-{
8365+ GdkScreen *previous_screen)
8366 {
8367- int pos; 5961- int pos;
8368- gboolean cancelled = handle->cancelled; 5962- gboolean cancelled = handle->cancelled;
8369- struct AddShortcutData *data = user_data; 5963- struct AddShortcutData *data = user_data;
8370- 5964-
8371- if (!g_slist_find (data->impl->loading_shortcuts, handle)) 5965- if (!g_slist_find (data->impl->loading_shortcuts, handle))
8372- goto out; 5966- goto out;
8373+ GtkFileChooserDefault *impl; 5967-
8374
8375- data->impl->loading_shortcuts = g_slist_remove (data->impl->loading_shortcuts, handle); 5968- data->impl->loading_shortcuts = g_slist_remove (data->impl->loading_shortcuts, handle);
8376+ profile_start ("start", NULL); 5969-
8377
8378- if (cancelled || error || !gtk_file_info_get_is_folder (info)) 5970- if (cancelled || error || !gtk_file_info_get_is_folder (info))
8379- goto out; 5971- goto out;
8380+ impl = GTK_FILE_CHOOSER_DEFAULT (widget); 5972-
8381
8382- pos = shortcuts_get_pos_for_shortcut_folder (data->impl, data->impl->num_shortcuts); 5973- pos = shortcuts_get_pos_for_shortcut_folder (data->impl, data->impl->num_shortcuts);
8383+ if (GTK_WIDGET_CLASS (_gtk_file_chooser_default_parent_class)->screen_changed) 5974-
8384+ GTK_WIDGET_CLASS (_gtk_file_chooser_default_parent_class)->screen_changed (widget, previous_screen);
8385
8386- shortcuts_insert_path (data->impl, pos, SHORTCUT_TYPE_PATH, NULL, data->path, NULL, FALSE, SHORTCUTS_SHORTCUTS); 5975- shortcuts_insert_path (data->impl, pos, SHORTCUT_TYPE_PATH, NULL, data->path, NULL, FALSE, SHORTCUTS_SHORTCUTS);
8387+ remove_settings_signal (impl, previous_screen); 5976-
8388+ check_icon_theme (impl);
8389
8390-out: 5977-out:
8391- g_object_unref (data->impl); 5978- g_object_unref (data->impl);
8392- gtk_file_path_free (data->path); 5979- gtk_file_path_free (data->path);
8393- g_free (data); 5980- g_free (data);
8394+ g_signal_emit_by_name (widget, "default-size-changed"); 5981-
8395
8396- g_object_unref (handle); 5982- g_object_unref (handle);
8397+ profile_end ("end", NULL); 5983-}
8398 } 5984-
8399
8400-static gboolean 5985-static gboolean
8401-gtk_file_chooser_default_add_shortcut_folder (GtkFileChooser *chooser, 5986-gtk_file_chooser_default_add_shortcut_folder (GtkFileChooser *chooser,
8402- const GtkFilePath *path, 5987- const GtkFilePath *path,
8403- GError **error) 5988- GError **error)
8404+static void 5989-{
8405+gtk_file_chooser_default_size_allocate (GtkWidget *widget,
8406+ GtkAllocation *allocation)
8407 {
8408- GtkFileSystemHandle *handle; 5990- GtkFileSystemHandle *handle;
8409- GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (chooser); 5991- GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (chooser);
8410- struct AddShortcutData *data; 5992- struct AddShortcutData *data;
@@ -8416,8 +5998,7 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
8416- if (pos >= 0 && pos < shortcuts_get_index (impl, SHORTCUTS_BOOKMARKS_SEPARATOR)) 5998- if (pos >= 0 && pos < shortcuts_get_index (impl, SHORTCUTS_BOOKMARKS_SEPARATOR))
8417- { 5999- {
8418- gchar *uri; 6000- gchar *uri;
8419+ GtkFileChooserDefault *impl; 6001-
8420
8421- uri = gtk_file_system_path_to_uri (impl->file_system, path); 6002- uri = gtk_file_system_path_to_uri (impl->file_system, path);
8422- /* translators, "Shortcut" means "Bookmark" here */ 6003- /* translators, "Shortcut" means "Bookmark" here */
8423- g_set_error (error, 6004- g_set_error (error,
@@ -8426,15 +6007,12 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
8426- _("Shortcut %s already exists"), 6007- _("Shortcut %s already exists"),
8427- uri); 6008- uri);
8428- g_free (uri); 6009- g_free (uri);
8429+ impl = GTK_FILE_CHOOSER_DEFAULT (widget); 6010-
8430
8431- return FALSE; 6011- return FALSE;
8432- } 6012- }
8433+ GTK_WIDGET_CLASS (_gtk_file_chooser_default_parent_class)->size_allocate (widget, allocation); 6013-
8434
8435- for (l = impl->loading_shortcuts; l; l = l->next) 6014- for (l = impl->loading_shortcuts; l; l = l->next)
8436+ if (!gtk_file_chooser_default_get_resizable (GTK_FILE_CHOOSER_EMBED (impl))) 6015- {
8437 {
8438- GtkFileSystemHandle *h = l->data; 6016- GtkFileSystemHandle *h = l->data;
8439- GtkFilePath *p; 6017- GtkFilePath *p;
8440- 6018-
@@ -8453,12 +6031,8 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
8453- 6031-
8454- return FALSE; 6032- return FALSE;
8455- } 6033- }
8456+ /* The dialog is not resizable, we shouldn't 6034- }
8457+ * trust in the size it has in this stage 6035-
8458+ */
8459+ return;
8460 }
8461
8462- data = g_new0 (struct AddShortcutData, 1); 6036- data = g_new0 (struct AddShortcutData, 1);
8463- data->impl = g_object_ref (impl); 6037- data->impl = g_object_ref (impl);
8464- data->path = gtk_file_path_copy (path); 6038- data->path = gtk_file_path_copy (path);
@@ -8474,35 +6048,25 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
8474- g_object_set_data (G_OBJECT (handle), "add-shortcut-path-key", data->path); 6048- g_object_set_data (G_OBJECT (handle), "add-shortcut-path-key", data->path);
8475- 6049-
8476- return TRUE; 6050- return TRUE;
8477+ impl->default_width = allocation->width; 6051-}
8478+ impl->default_height = allocation->height; 6052-
8479 } 6053-static gboolean
8480
8481 static gboolean
8482-gtk_file_chooser_default_remove_shortcut_folder (GtkFileChooser *chooser, 6054-gtk_file_chooser_default_remove_shortcut_folder (GtkFileChooser *chooser,
8483- const GtkFilePath *path, 6055- const GtkFilePath *path,
8484- GError **error) 6056- GError **error)
8485+get_is_file_filtered (GtkFileChooserDefault *impl, 6057-{
8486+ const GtkFilePath *path,
8487+ GtkFileInfo *file_info)
8488 {
8489- GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (chooser); 6058- GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (chooser);
8490- int pos; 6059- int pos;
8491- GtkTreeIter iter; 6060- GtkTreeIter iter;
8492- GSList *l; 6061- GSList *l;
8493- char *uri; 6062- char *uri;
8494- int i; 6063- int i;
8495+ GtkFileFilterInfo filter_info; 6064-
8496+ GtkFileFilterFlags needed;
8497+ gboolean result;
8498
8499- for (l = impl->loading_shortcuts; l; l = l->next) 6065- for (l = impl->loading_shortcuts; l; l = l->next)
8500- { 6066- {
8501- GtkFileSystemHandle *h = l->data; 6067- GtkFileSystemHandle *h = l->data;
8502- GtkFilePath *p; 6068- GtkFilePath *p;
8503+ if (!impl->current_filter) 6069-
8504+ return FALSE;
8505
8506- p = g_object_get_data (G_OBJECT (h), "add-shortcut-path-key"); 6070- p = g_object_get_data (G_OBJECT (h), "add-shortcut-path-key");
8507- if (p && !gtk_file_path_compare (path, p)) 6071- if (p && !gtk_file_path_compare (path, p))
8508- { 6072- {
@@ -8511,21 +6075,16 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
8511- return TRUE; 6075- return TRUE;
8512- } 6076- }
8513- } 6077- }
8514+ filter_info.contains = GTK_FILE_FILTER_DISPLAY_NAME | GTK_FILE_FILTER_MIME_TYPE; 6078-
8515
8516- if (impl->num_shortcuts == 0) 6079- if (impl->num_shortcuts == 0)
8517- goto out; 6080- goto out;
8518+ needed = gtk_file_filter_get_needed (impl->current_filter); 6081-
8519
8520- pos = shortcuts_get_pos_for_shortcut_folder (impl, 0); 6082- pos = shortcuts_get_pos_for_shortcut_folder (impl, 0);
8521- if (!gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (impl->shortcuts_model), &iter, NULL, pos)) 6083- if (!gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (impl->shortcuts_model), &iter, NULL, pos))
8522- g_assert_not_reached (); 6084- g_assert_not_reached ();
8523+ filter_info.display_name = gtk_file_info_get_display_name (file_info); 6085-
8524+ filter_info.mime_type = gtk_file_info_get_mime_type (file_info);
8525
8526- for (i = 0; i < impl->num_shortcuts; i++) 6086- for (i = 0; i < impl->num_shortcuts; i++)
8527+ if (needed & GTK_FILE_FILTER_FILENAME) 6087- {
8528 {
8529- gpointer col_data; 6088- gpointer col_data;
8530- ShortcutType shortcut_type; 6089- ShortcutType shortcut_type;
8531- GtkFilePath *shortcut; 6090- GtkFilePath *shortcut;
@@ -8544,27 +6103,13 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
8544- impl->num_shortcuts--; 6103- impl->num_shortcuts--;
8545- return TRUE; 6104- return TRUE;
8546- } 6105- }
8547+ filter_info.filename = gtk_file_system_path_to_filename (impl->file_system, path); 6106-
8548+ if (filter_info.filename)
8549+ filter_info.contains |= GTK_FILE_FILTER_FILENAME;
8550+ }
8551+ else
8552+ filter_info.filename = NULL;
8553
8554- if (!gtk_tree_model_iter_next (GTK_TREE_MODEL (impl->shortcuts_model), &iter)) 6107- if (!gtk_tree_model_iter_next (GTK_TREE_MODEL (impl->shortcuts_model), &iter))
8555- g_assert_not_reached (); 6108- g_assert_not_reached ();
8556+ if (needed & GTK_FILE_FILTER_URI) 6109- }
8557+ { 6110-
8558+ filter_info.uri = gtk_file_system_path_to_uri (impl->file_system, path);
8559+ if (filter_info.uri)
8560+ filter_info.contains |= GTK_FILE_FILTER_URI;
8561 }
8562+ else
8563+ filter_info.uri = NULL;
8564
8565- out: 6111- out:
8566+ result = gtk_file_filter_filter (impl->current_filter, &filter_info); 6112-
8567
8568- uri = gtk_file_system_path_to_uri (impl->file_system, path); 6113- uri = gtk_file_system_path_to_uri (impl->file_system, path);
8569- /* translators, "Shortcut" means "Bookmark" here */ 6114- /* translators, "Shortcut" means "Bookmark" here */
8570- g_set_error (error, 6115- g_set_error (error,
@@ -8573,895 +6118,137 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
8573- _("Shortcut %s does not exist"), 6118- _("Shortcut %s does not exist"),
8574- uri); 6119- uri);
8575- g_free (uri); 6120- g_free (uri);
8576+ if (filter_info.filename) 6121-
8577+ g_free ((gchar *)filter_info.filename);
8578+ if (filter_info.uri)
8579+ g_free ((gchar *)filter_info.uri);
8580
8581- return FALSE; 6122- return FALSE;
8582+ return !result; 6123-}
8583 } 6124-
8584
8585-static GSList * 6125-static GSList *
8586-gtk_file_chooser_default_list_shortcut_folders (GtkFileChooser *chooser) 6126-gtk_file_chooser_default_list_shortcut_folders (GtkFileChooser *chooser)
8587+static void 6127-{
8588+settings_load (GtkFileChooserDefault *impl)
8589 {
8590- GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (chooser); 6128- GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (chooser);
8591- int pos; 6129- int pos;
8592- GtkTreeIter iter; 6130- GtkTreeIter iter;
8593- int i; 6131- int i;
8594- GSList *list; 6132- GSList *list;
8595+ GtkFileChooserSettings *settings; 6133-
8596+ gboolean show_hidden;
8597+ gboolean expand_folders;
8598
8599- if (impl->num_shortcuts == 0) 6134- if (impl->num_shortcuts == 0)
8600- return NULL; 6135- return NULL;
8601+ settings = _gtk_file_chooser_settings_new (); 6136-
8602
8603- pos = shortcuts_get_pos_for_shortcut_folder (impl, 0); 6137- pos = shortcuts_get_pos_for_shortcut_folder (impl, 0);
8604- if (!gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (impl->shortcuts_model), &iter, NULL, pos)) 6138- if (!gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (impl->shortcuts_model), &iter, NULL, pos))
8605- g_assert_not_reached (); 6139- g_assert_not_reached ();
8606+ show_hidden = _gtk_file_chooser_settings_get_show_hidden (settings); 6140-
8607+ expand_folders = _gtk_file_chooser_settings_get_expand_folders (settings);
8608
8609- list = NULL; 6141- list = NULL;
8610+ g_object_unref (settings); 6142-
8611
8612- for (i = 0; i < impl->num_shortcuts; i++) 6143- for (i = 0; i < impl->num_shortcuts; i++)
8613- { 6144- {
8614- gpointer col_data; 6145- gpointer col_data;
8615- ShortcutType shortcut_type; 6146- ShortcutType shortcut_type;
8616- GtkFilePath *shortcut; 6147- GtkFilePath *shortcut;
8617+ gtk_file_chooser_set_show_hidden (GTK_FILE_CHOOSER (impl), show_hidden); 6148-
8618+ impl->expand_folders = expand_folders;
8619+}
8620+
8621+static void
8622+settings_save (GtkFileChooserDefault *impl)
8623+{
8624+ GtkFileChooserSettings *settings;
8625
8626- gtk_tree_model_get (GTK_TREE_MODEL (impl->shortcuts_model), &iter, 6149- gtk_tree_model_get (GTK_TREE_MODEL (impl->shortcuts_model), &iter,
8627- SHORTCUTS_COL_DATA, &col_data, 6150- SHORTCUTS_COL_DATA, &col_data,
8628- SHORTCUTS_COL_TYPE, &shortcut_type, 6151- SHORTCUTS_COL_TYPE, &shortcut_type,
8629- -1); 6152- -1);
8630- g_assert (col_data != NULL); 6153- g_assert (col_data != NULL);
8631- g_assert (shortcut_type == SHORTCUT_TYPE_PATH); 6154- g_assert (shortcut_type == SHORTCUT_TYPE_PATH);
8632+ settings = _gtk_file_chooser_settings_new (); 6155-
8633
8634- shortcut = col_data; 6156- shortcut = col_data;
8635- list = g_slist_prepend (list, gtk_file_path_copy (shortcut)); 6157- list = g_slist_prepend (list, gtk_file_path_copy (shortcut));
8636+ _gtk_file_chooser_settings_set_show_hidden (settings, gtk_file_chooser_get_show_hidden (GTK_FILE_CHOOSER (impl))); 6158-
8637+ _gtk_file_chooser_settings_set_expand_folders (settings, impl->expand_folders);
8638
8639- if (i != impl->num_shortcuts - 1) 6159- if (i != impl->num_shortcuts - 1)
8640- { 6160- {
8641- if (!gtk_tree_model_iter_next (GTK_TREE_MODEL (impl->shortcuts_model), &iter)) 6161- if (!gtk_tree_model_iter_next (GTK_TREE_MODEL (impl->shortcuts_model), &iter))
8642- g_assert_not_reached (); 6162- g_assert_not_reached ();
8643- } 6163- }
8644- } 6164- }
8645+ /* NULL GError */ 6165-
8646+ _gtk_file_chooser_settings_save (settings, NULL);
8647
8648- return g_slist_reverse (list); 6166- return g_slist_reverse (list);
8649+ g_object_unref (settings); 6167-}
8650 } 6168-
8651 6169 /* Guesses a size based upon font sizes */
8652-/* Guesses a size based upon font sizes */
8653+/* GtkWidget::map method */
8654 static void 6170 static void
8655-find_good_size_from_style (GtkWidget *widget, 6171 find_good_size_from_style (GtkWidget *widget,
8656- gint *width, 6172@@ -7911,25 +3777,9 @@
8657- gint *height) 6173 gint *default_height)
8658+gtk_file_chooser_default_map (GtkWidget *widget)
8659 { 6174 {
8660 GtkFileChooserDefault *impl; 6175 GtkFileChooserDefault *impl;
8661- int font_size;
8662- GdkScreen *screen;
8663- double resolution;
8664-
8665- g_assert (widget->style != NULL);
8666- impl = GTK_FILE_CHOOSER_DEFAULT (widget);
8667+ char *current_working_dir;
8668
8669- if (impl->default_width == 0 &&
8670- impl->default_height == 0)
8671- {
8672- screen = gtk_widget_get_screen (widget);
8673- if (screen)
8674- {
8675- resolution = gdk_screen_get_resolution (screen);
8676- if (resolution < 0.0) /* will be -1 if the resolution is not defined in the GdkScreen */
8677- resolution = 96.0;
8678- }
8679- else
8680- resolution = 96.0; /* wheeee */
8681+ profile_start ("start", NULL);
8682
8683- font_size = pango_font_description_get_size (widget->style->font_desc);
8684- font_size = PANGO_PIXELS (font_size) * resolution / 72.0;
8685+ impl = GTK_FILE_CHOOSER_DEFAULT (widget);
8686
8687- impl->default_width = font_size * NUM_CHARS;
8688- impl->default_height = font_size * NUM_LINES;
8689- }
8690+ GTK_WIDGET_CLASS (_gtk_file_chooser_default_parent_class)->map (widget);
8691
8692- *width = impl->default_width;
8693- *height = impl->default_height;
8694-}
8695+ switch (impl->reload_state)
8696+ {
8697+ case RELOAD_EMPTY:
8698+ /* The user didn't explicitly give us a folder to display, so we'll use the cwd */
8699+ current_working_dir = g_get_current_dir ();
8700+ gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (impl), current_working_dir);
8701+ g_free (current_working_dir);
8702+ break;
8703
8704-static void
8705-gtk_file_chooser_default_get_default_size (GtkFileChooserEmbed *chooser_embed,
8706- gint *default_width,
8707- gint *default_height)
8708-{
8709- GtkFileChooserDefault *impl;
8710- GtkRequisition req; 6176- GtkRequisition req;
8711+ case RELOAD_HAS_FOLDER:
8712+ /* Nothing; we are already loading or loaded, so we don't need to reload */
8713+ break;
8714
8715- impl = GTK_FILE_CHOOSER_DEFAULT (chooser_embed);
8716- find_good_size_from_style (GTK_WIDGET (chooser_embed), default_width, default_height);
8717+ case RELOAD_WAS_UNMAPPED:
8718+ /* Just reload the current folder; else continue the pending load. */
8719+ if (impl->current_folder)
8720+ {
8721+ pending_select_paths_store_selection (impl);
8722+ change_folder_and_display_error (impl, impl->current_folder);
8723+ }
8724+ break;
8725 6177
6178 impl = GTK_FILE_CHOOSER_DEFAULT (chooser_embed);
6179 find_good_size_from_style (GTK_WIDGET (chooser_embed), default_width, default_height);
6180-
8726- if (impl->preview_widget_active && 6181- if (impl->preview_widget_active &&
8727- impl->preview_widget && 6182- impl->preview_widget &&
8728- GTK_WIDGET_VISIBLE (impl->preview_widget)) 6183- GTK_WIDGET_VISIBLE (impl->preview_widget))
8729- { 6184- {
8730- gtk_widget_size_request (impl->preview_box, &req); 6185- gtk_widget_size_request (impl->preview_box, &req);
8731- *default_width += PREVIEW_HBOX_SPACING + req.width; 6186- *default_width += PREVIEW_HBOX_SPACING + req.width;
8732+ default: 6187- }
8733+ g_assert_not_reached (); 6188-
8734 }
8735
8736- if (impl->extra_widget && 6189- if (impl->extra_widget &&
8737- GTK_WIDGET_VISIBLE (impl->extra_widget)) 6190- GTK_WIDGET_VISIBLE (impl->extra_widget))
8738- { 6191- {
8739- gtk_widget_size_request (impl->extra_align, &req); 6192- gtk_widget_size_request (impl->extra_align, &req);
8740- *default_height += GTK_BOX (chooser_embed)->spacing + req.height; 6193- *default_height += GTK_BOX (chooser_embed)->spacing + req.height;
8741- } 6194- }
8742+ settings_load (impl);
8743+
8744+ profile_end ("end", NULL);
8745 } 6195 }
8746 6196
8747-static gboolean 6197 static gboolean
8748-gtk_file_chooser_default_get_resizable (GtkFileChooserEmbed *chooser_embed) 6198@@ -7940,8 +3790,7 @@
8749+/* GtkWidget::unmap method */ 6199 impl = GTK_FILE_CHOOSER_DEFAULT (chooser_embed);
8750+static void
8751+gtk_file_chooser_default_unmap (GtkWidget *widget)
8752 {
8753 GtkFileChooserDefault *impl;
8754
8755- impl = GTK_FILE_CHOOSER_DEFAULT (chooser_embed);
8756+ impl = GTK_FILE_CHOOSER_DEFAULT (widget);
8757 6200
8758- return (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN || 6201 return (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN ||
8759- impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER || 6202- impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER ||
8760- gtk_expander_get_expanded (GTK_EXPANDER (impl->save_expander))); 6203- gtk_expander_get_expanded (GTK_EXPANDER (impl->save_expander)));
8761-} 6204+ impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER);
8762+ settings_save (impl);
8763
8764-struct switch_folder_closure {
8765- GtkFileChooserDefault *impl;
8766- const GtkFilePath *path;
8767- int num_selected;
8768-};
8769+ GTK_WIDGET_CLASS (_gtk_file_chooser_default_parent_class)->unmap (widget);
8770
8771-/* Used from gtk_tree_selection_selected_foreach() in switch_to_selected_folder() */
8772-static void
8773-switch_folder_foreach_cb (GtkTreeModel *model,
8774- GtkTreePath *path,
8775- GtkTreeIter *iter,
8776- gpointer data)
8777+ impl->reload_state = RELOAD_WAS_UNMAPPED;
8778+}
8779+
8780+static gboolean
8781+list_model_filter_func (GtkFileSystemModel *model,
8782+ GtkFilePath *path,
8783+ const GtkFileInfo *file_info,
8784+ gpointer user_data)
8785 {
8786- struct switch_folder_closure *closure;
8787- GtkTreeIter child_iter;
8788+ GtkFileChooserDefault *impl = user_data;
8789
8790- closure = data;
8791+ if (!impl->current_filter)
8792+ return TRUE;
8793
8794- gtk_tree_model_sort_convert_iter_to_child_iter (closure->impl->sort_model, &child_iter, iter);
8795+ if (gtk_file_info_get_is_folder (file_info))
8796+ return TRUE;
8797
8798- closure->path = _gtk_file_system_model_get_path (closure->impl->browse_files_model, &child_iter);
8799- closure->num_selected++;
8800+ return !get_is_file_filtered (impl, path, (GtkFileInfo *) file_info);
8801 } 6205 }
8802 6206
8803-/* Changes to the selected folder in the list view */ 6207 struct switch_folder_closure {
8804 static void 6208@@ -7988,7 +3837,7 @@
8805-switch_to_selected_folder (GtkFileChooserDefault *impl)
8806+install_list_model_filter (GtkFileChooserDefault *impl)
8807 {
8808- GtkTreeSelection *selection;
8809- struct switch_folder_closure closure;
8810-
8811- /* We do this with foreach() rather than get_selected() as we may be in
8812- * multiple selection mode
8813- */
8814+ GtkFileSystemModelFilter filter;
8815+ gpointer data;
8816 6209
8817- closure.impl = impl; 6210 g_assert (closure.path && closure.num_selected == 1);
8818- closure.path = NULL;
8819- closure.num_selected = 0;
8820+ g_assert (impl->browse_files_model != NULL);
8821
8822- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_files_tree_view));
8823- gtk_tree_selection_selected_foreach (selection, switch_folder_foreach_cb, &closure);
8824+ if (impl->current_filter)
8825+ {
8826+ filter = list_model_filter_func;
8827+ data = impl;
8828+ }
8829+ else
8830+ {
8831+ filter = NULL;
8832+ data = NULL;
8833+ }
8834+
8835+ _gtk_file_system_model_set_filter (impl->browse_files_model,
8836+ filter,
8837+ data);
8838+}
8839
8840- g_assert (closure.path && closure.num_selected == 1);
8841+#define COMPARE_DIRECTORIES \
8842+ GtkFileChooserDefault *impl = user_data; \
8843+ const GtkFileInfo *info_a = _gtk_file_system_model_get_info (impl->browse_files_model, a); \
8844+ const GtkFileInfo *info_b = _gtk_file_system_model_get_info (impl->browse_files_model, b); \
8845+ gboolean dir_a, dir_b; \
8846+ \
8847+ if (info_a) \
8848+ dir_a = gtk_file_info_get_is_folder (info_a); \
8849+ else \
8850+ return impl->list_sort_ascending ? -1 : 1; \
8851+ \
8852+ if (info_b) \
8853+ dir_b = gtk_file_info_get_is_folder (info_b); \
8854+ else \
8855+ return impl->list_sort_ascending ? 1 : -1; \
8856+ \
8857+ if (dir_a != dir_b) \
8858+ return impl->list_sort_ascending ? (dir_a ? -1 : 1) : (dir_a ? 1 : -1) /* Directories *always* go first */
8859 6211
8860- change_folder_and_display_error (impl, closure.path, FALSE); 6212- change_folder_and_display_error (impl, closure.path, FALSE);
8861+/* Sort callback for the filename column */ 6213+ change_folder_and_display_error (impl, closure.path);
8862+static gint
8863+name_sort_func (GtkTreeModel *model,
8864+ GtkTreeIter *a,
8865+ GtkTreeIter *b,
8866+ gpointer user_data)
8867+{
8868+ COMPARE_DIRECTORIES;
8869+ else
8870+ return strcmp (gtk_file_info_get_display_key (info_a), gtk_file_info_get_display_key (info_b));
8871 }
8872
8873-/* Gets the GtkFileInfo for the selected row in the file list; assumes single
8874- * selection mode.
8875- */
8876-static const GtkFileInfo *
8877-get_selected_file_info_from_file_list (GtkFileChooserDefault *impl,
8878- gboolean *had_selection)
8879+/* Sort callback for the size column */
8880+static gint
8881+size_sort_func (GtkTreeModel *model,
8882+ GtkTreeIter *a,
8883+ GtkTreeIter *b,
8884+ gpointer user_data)
8885 {
8886- GtkTreeSelection *selection;
8887- GtkTreeIter iter, child_iter;
8888- const GtkFileInfo *info;
8889-
8890- g_assert (!impl->select_multiple);
8891- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_files_tree_view));
8892- if (!gtk_tree_selection_get_selected (selection, NULL, &iter))
8893+ COMPARE_DIRECTORIES;
8894+ else
8895 {
8896- *had_selection = FALSE;
8897- return NULL;
8898- }
8899-
8900- *had_selection = TRUE;
8901-
8902- gtk_tree_model_sort_convert_iter_to_child_iter (impl->sort_model,
8903- &child_iter,
8904- &iter);
8905+ gint64 size_a = gtk_file_info_get_size (info_a);
8906+ gint64 size_b = gtk_file_info_get_size (info_b);
8907
8908- info = _gtk_file_system_model_get_info (impl->browse_files_model, &child_iter);
8909- return info;
8910+ return size_a > size_b ? -1 : (size_a == size_b ? 0 : 1);
8911+ }
8912 }
8913
8914-/* Gets the display name of the selected file in the file list; assumes single
8915- * selection mode and that something is selected.
8916- */
8917-static const gchar *
8918-get_display_name_from_file_list (GtkFileChooserDefault *impl)
8919+/* Sort callback for the mtime column */
8920+static gint
8921+mtime_sort_func (GtkTreeModel *model,
8922+ GtkTreeIter *a,
8923+ GtkTreeIter *b,
8924+ gpointer user_data)
8925 {
8926- const GtkFileInfo *info;
8927- gboolean had_selection;
8928-
8929- info = get_selected_file_info_from_file_list (impl, &had_selection);
8930- g_assert (had_selection);
8931- g_assert (info != NULL);
8932+ COMPARE_DIRECTORIES;
8933+ else
8934+ {
8935+ GtkFileTime ta = gtk_file_info_get_modification_time (info_a);
8936+ GtkFileTime tb = gtk_file_info_get_modification_time (info_b);
8937
8938- return gtk_file_info_get_display_name (info);
8939+ return ta > tb ? -1 : (ta == tb ? 0 : 1);
8940+ }
8941 }
8942
8943+/* Callback used when the sort column changes. We cache the sort order for use
8944+ * in name_sort_func().
8945+ */
8946 static void
8947-add_custom_button_to_dialog (GtkDialog *dialog,
8948- const gchar *mnemonic_label,
8949- const gchar *stock_id,
8950- gint response_id)
8951+list_sort_column_changed_cb (GtkTreeSortable *sortable,
8952+ GtkFileChooserDefault *impl)
8953 {
8954- GtkWidget *button;
8955-
8956- button = gtk_button_new_with_mnemonic (mnemonic_label);
8957- GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
8958- gtk_button_set_image (GTK_BUTTON (button),
8959- gtk_image_new_from_stock (stock_id, GTK_ICON_SIZE_BUTTON));
8960- gtk_widget_show (button);
8961+ GtkSortType sort_type;
8962
8963- gtk_dialog_add_action_widget (GTK_DIALOG (dialog), button, response_id);
8964+ if (gtk_tree_sortable_get_sort_column_id (sortable, NULL, &sort_type))
8965+ impl->list_sort_ascending = (sort_type == GTK_SORT_ASCENDING);
8966 }
8967
8968-/* Presents an overwrite confirmation dialog; returns whether we should accept
8969- * the filename.
8970- */
8971-static gboolean
8972-confirm_dialog_should_accept_filename (GtkFileChooserDefault *impl,
8973- const gchar *file_part,
8974- const gchar *folder_display_name)
8975+static void
8976+set_busy_cursor (GtkFileChooserDefault *impl,
8977+ gboolean busy)
8978 {
8979 GtkWindow *toplevel;
8980- GtkWidget *dialog;
8981- int response;
8982+ GdkDisplay *display;
8983+ GdkCursor *cursor;
8984
8985 toplevel = get_toplevel (GTK_WIDGET (impl));
8986+ if (!toplevel || !GTK_WIDGET_REALIZED (toplevel))
8987+ return;
8988
8989- dialog = gtk_message_dialog_new (toplevel,
8990- GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
8991- GTK_MESSAGE_QUESTION,
8992- GTK_BUTTONS_NONE,
8993- _("A file named \"%s\" already exists. Do you want to replace it?"),
8994- file_part);
8995- gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
8996- _("The file already exists in \"%s\". Replacing it will "
8997- "overwrite its contents."),
8998- folder_display_name);
8999-
9000- gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL);
9001- add_custom_button_to_dialog (GTK_DIALOG (dialog), _("_Replace"), GTK_STOCK_SAVE_AS, GTK_RESPONSE_ACCEPT);
9002- gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_ACCEPT);
9003-
9004- if (toplevel->group)
9005- gtk_window_group_add_window (toplevel->group, GTK_WINDOW (dialog));
9006+ display = gtk_widget_get_display (GTK_WIDGET (toplevel));
9007
9008- response = gtk_dialog_run (GTK_DIALOG (dialog));
9009+ if (busy)
9010+ cursor = gdk_cursor_new_for_display (display, GDK_WATCH);
9011+ else
9012+ cursor = NULL;
9013
9014- gtk_widget_destroy (dialog);
9015+ gdk_window_set_cursor (GTK_WIDGET (toplevel)->window, cursor);
9016+ gdk_display_flush (display);
9017
9018- return (response == GTK_RESPONSE_ACCEPT);
9019+ if (cursor)
9020+ gdk_cursor_unref (cursor);
9021 }
9022
9023-struct GetDisplayNameData
9024-{
9025- GtkFileChooserDefault *impl;
9026- gchar *file_part;
9027-};
9028-
9029+/* Creates a sort model to wrap the file system model and sets it on the tree view */
9030 static void
9031-confirmation_confirm_get_info_cb (GtkFileSystemHandle *handle,
9032- const GtkFileInfo *info,
9033- const GError *error,
9034- gpointer user_data)
9035+load_set_model (GtkFileChooserDefault *impl)
9036 {
9037- gboolean cancelled = handle->cancelled;
9038- gboolean should_respond = FALSE;
9039- struct GetDisplayNameData *data = user_data;
9040-
9041- if (handle != data->impl->should_respond_get_info_handle)
9042- goto out;
9043-
9044- data->impl->should_respond_get_info_handle = NULL;
9045+ profile_start ("start", NULL);
9046
9047- if (cancelled)
9048- goto out;
9049+ g_assert (impl->browse_files_model != NULL);
9050+ g_assert (impl->sort_model == NULL);
9051
9052- if (error)
9053- /* Huh? Did the folder disappear? Let the caller deal with it */
9054- should_respond = TRUE;
9055- else
9056- should_respond = confirm_dialog_should_accept_filename (data->impl, data->file_part, gtk_file_info_get_display_name (info));
9057+ profile_msg (" gtk_tree_model_sort_new_with_model start", NULL);
9058+ impl->sort_model = (GtkTreeModelSort *)gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (impl->browse_files_model));
9059+ gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (impl->sort_model), FILE_LIST_COL_NAME, name_sort_func, impl, NULL);
9060+ gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (impl->sort_model), FILE_LIST_COL_SIZE, size_sort_func, impl, NULL);
9061+ gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (impl->sort_model), FILE_LIST_COL_MTIME, mtime_sort_func, impl, NULL);
9062+ gtk_tree_sortable_set_default_sort_func (GTK_TREE_SORTABLE (impl->sort_model), NULL, NULL, NULL);
9063+ gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (impl->sort_model), FILE_LIST_COL_NAME, GTK_SORT_ASCENDING);
9064+ impl->list_sort_ascending = TRUE;
9065+ profile_msg (" gtk_tree_model_sort_new_with_model end", NULL);
9066
9067- set_busy_cursor (data->impl, FALSE);
9068- if (should_respond)
9069- g_signal_emit_by_name (data->impl, "response-requested");
9070+ g_signal_connect (impl->sort_model, "sort_column_changed",
9071+ G_CALLBACK (list_sort_column_changed_cb), impl);
9072
9073-out:
9074- g_object_unref (data->impl);
9075- g_free (data->file_part);
9076- g_free (data);
9077+ profile_msg (" gtk_tree_view_set_model start", NULL);
9078+ gtk_tree_view_set_model (GTK_TREE_VIEW (impl->browse_files_tree_view),
9079+ GTK_TREE_MODEL (impl->sort_model));
9080+ gtk_tree_view_columns_autosize (GTK_TREE_VIEW (impl->browse_files_tree_view));
9081+ gtk_tree_view_set_search_column (GTK_TREE_VIEW (impl->browse_files_tree_view),
9082+ GTK_FILE_SYSTEM_MODEL_DISPLAY_NAME);
9083+ profile_msg (" gtk_tree_view_set_model end", NULL);
9084
9085- g_object_unref (handle);
9086+ profile_end ("end", NULL);
9087 } 6214 }
9088 6215
9089-/* Does overwrite confirmation if appropriate, and returns whether the dialog 6216 /* Gets the GtkFileInfo for the selected row in the file list; assumes single
9090- * should respond. Can get the file part from the file list or the save entry. 6217@@ -8187,24 +4036,7 @@
9091- */
9092+/* Timeout callback used when the loading timer expires */
9093 static gboolean
9094-should_respond_after_confirm_overwrite (GtkFileChooserDefault *impl,
9095- const gchar *file_part,
9096- const GtkFilePath *parent_path)
9097+load_timeout_cb (gpointer data)
9098 {
9099- GtkFileChooserConfirmation conf;
9100+ GtkFileChooserDefault *impl;
9101
9102- if (!impl->do_overwrite_confirmation)
9103- return TRUE;
9104+ profile_start ("start", NULL);
9105
9106- conf = GTK_FILE_CHOOSER_CONFIRMATION_CONFIRM;
9107+ GDK_THREADS_ENTER ();
9108
9109- g_signal_emit_by_name (impl, "confirm-overwrite", &conf);
9110+ impl = GTK_FILE_CHOOSER_DEFAULT (data);
9111+ g_assert (impl->load_state == LOAD_PRELOAD);
9112+ g_assert (impl->load_timeout_id != 0);
9113+ g_assert (impl->browse_files_model != NULL);
9114
9115- switch (conf)
9116- {
9117- case GTK_FILE_CHOOSER_CONFIRMATION_CONFIRM:
9118- {
9119- struct GetDisplayNameData *data;
9120+ impl->load_timeout_id = 0;
9121+ impl->load_state = LOAD_LOADING;
9122
9123- g_assert (file_part != NULL);
9124+ load_set_model (impl);
9125
9126- data = g_new0 (struct GetDisplayNameData, 1);
9127- data->impl = g_object_ref (impl);
9128- data->file_part = g_strdup (file_part);
9129+ GDK_THREADS_LEAVE ();
9130
9131- if (impl->should_respond_get_info_handle)
9132- gtk_file_system_cancel_operation (impl->should_respond_get_info_handle);
9133+ profile_end ("end", NULL);
9134
9135- impl->should_respond_get_info_handle =
9136- gtk_file_system_get_info (impl->file_system, parent_path,
9137- GTK_FILE_INFO_DISPLAY_NAME,
9138- confirmation_confirm_get_info_cb,
9139- data);
9140- set_busy_cursor (data->impl, TRUE);
9141- return FALSE;
9142- }
9143+ return FALSE;
9144+}
9145
9146- case GTK_FILE_CHOOSER_CONFIRMATION_ACCEPT_FILENAME:
9147- return TRUE;
9148+/* Sets up a new load timer for the model and switches to the LOAD_PRELOAD state */
9149+static void
9150+load_setup_timer (GtkFileChooserDefault *impl)
9151+{
9152+ g_assert (impl->load_timeout_id == 0);
9153+ g_assert (impl->load_state != LOAD_PRELOAD);
9154
9155- case GTK_FILE_CHOOSER_CONFIRMATION_SELECT_AGAIN:
9156- return FALSE;
9157+ impl->load_timeout_id = g_timeout_add (MAX_LOADING_TIME, load_timeout_cb, impl);
9158+ impl->load_state = LOAD_PRELOAD;
9159+}
9160
9161- default:
9162- g_assert_not_reached ();
9163- return FALSE;
9164+/* Removes the load timeout and switches to the LOAD_FINISHED state */
9165+static void
9166+load_remove_timer (GtkFileChooserDefault *impl)
9167+{
9168+ if (impl->load_timeout_id != 0)
9169+ {
9170+ g_assert (impl->load_state == LOAD_PRELOAD);
9171+
9172+ g_source_remove (impl->load_timeout_id);
9173+ impl->load_timeout_id = 0;
9174+ impl->load_state = LOAD_EMPTY;
9175 } 6218 }
9176+ else
9177+ g_assert (impl->load_state == LOAD_EMPTY ||
9178+ impl->load_state == LOAD_LOADING ||
9179+ impl->load_state == LOAD_FINISHED);
9180 } 6219 }
9181 6220
9182-/* Gives the focus to the browse tree view only if it is visible */ 6221-/* Gives the focus to the browse tree view only if it is visible */
9183+/* Selects the first row in the file list */
9184 static void 6222 static void
9185-focus_browse_tree_view_if_possible (GtkFileChooserDefault *impl) 6223-focus_browse_tree_view_if_possible (GtkFileChooserDefault *impl)
9186+browse_files_select_first_row (GtkFileChooserDefault *impl) 6224-{
9187 {
9188- gboolean do_focus; 6225- gboolean do_focus;
9189+ GtkTreePath *path; 6226-
9190
9191- if ((impl->action == GTK_FILE_CHOOSER_ACTION_SAVE || 6227- if ((impl->action == GTK_FILE_CHOOSER_ACTION_SAVE ||
9192- impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER) 6228- impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)
9193- && !gtk_expander_get_expanded (GTK_EXPANDER (impl->save_expander))) 6229- && !gtk_expander_get_expanded (GTK_EXPANDER (impl->save_expander)))
9194- do_focus = FALSE; 6230- do_focus = FALSE;
9195- else 6231- else
9196- do_focus = TRUE; 6232- do_focus = TRUE;
9197+ if (!impl->sort_model) 6233-
9198+ return;
9199
9200- if (do_focus) 6234- if (do_focus)
9201- gtk_widget_grab_focus (impl->browse_files_tree_view); 6235- gtk_widget_grab_focus (impl->browse_files_tree_view);
9202+ path = gtk_tree_path_new_from_indices (0, -1); 6236-}
9203+ gtk_tree_view_set_cursor (GTK_TREE_VIEW (impl->browse_files_tree_view), path, NULL, FALSE);
9204+ gtk_tree_path_free (path);
9205 }
9206
9207+struct center_selected_row_closure {
9208+ GtkFileChooserDefault *impl;
9209+ gboolean already_centered;
9210+};
9211+
9212+/* Callback used from gtk_tree_selection_selected_foreach(); centers the
9213+ * selected row in the tree view.
9214+ */
9215 static void
9216-action_create_folder_cb (GtkFileSystemHandle *handle,
9217- const GtkFilePath *path,
9218- const GError *error,
9219- gpointer user_data)
9220+center_selected_row_foreach_cb (GtkTreeModel *model,
9221+ GtkTreePath *path,
9222+ GtkTreeIter *iter,
9223+ gpointer data)
9224 {
9225- gboolean cancelled = handle->cancelled;
9226- GtkFileChooserDefault *impl = user_data;
9227- 6237-
9228- if (!g_slist_find (impl->pending_handles, handle)) 6238-static void
9229- goto out; 6239 action_create_folder_cb (GtkFileSystemHandle *handle,
9230+ struct center_selected_row_closure *closure; 6240 const GtkFilePath *path,
9231 6241 const GError *error,
9232- impl->pending_handles = g_slist_remove (impl->pending_handles, handle); 6242@@ -8300,7 +4132,7 @@
9233+ closure = data; 6243 else
9234+ if (closure->already_centered)
9235+ return;
9236
9237- set_busy_cursor (impl, FALSE);
9238+ gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (closure->impl->browse_files_tree_view), path, NULL, TRUE, 0.5, 0.0);
9239+ closure->already_centered = TRUE;
9240+}
9241
9242- if (cancelled)
9243- goto out;
9244+/* Centers the selected row in the tree view */
9245+static void
9246+browse_files_center_selected_row (GtkFileChooserDefault *impl)
9247+{
9248+ struct center_selected_row_closure closure;
9249+ GtkTreeSelection *selection;
9250
9251- if (error)
9252- error_creating_folder_dialog (impl, path, g_error_copy (error));
9253- else
9254- g_signal_emit_by_name (impl, "response-requested");
9255+ closure.impl = impl;
9256+ closure.already_centered = FALSE;
9257
9258-out:
9259- g_object_unref (impl);
9260- g_object_unref (handle);
9261+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_files_tree_view));
9262+ gtk_tree_selection_selected_foreach (selection, center_selected_row_foreach_cb, &closure);
9263 }
9264
9265-struct FileExistsData
9266+struct ShowAndSelectPathsData
9267 {
9268 GtkFileChooserDefault *impl;
9269- gboolean file_exists_and_is_not_folder;
9270- GtkFilePath *parent_path;
9271- GtkFilePath *path;
9272+ GSList *paths;
9273 };
9274
9275 static void
9276-save_entry_get_info_cb (GtkFileSystemHandle *handle,
9277- const GtkFileInfo *info,
9278- const GError *error,
9279- gpointer user_data)
9280+show_and_select_paths_finished_loading (GtkFileFolder *folder,
9281+ gpointer user_data)
9282 {
9283- gboolean parent_is_folder;
9284- gboolean cancelled = handle->cancelled;
9285- struct FileExistsData *data = user_data;
9286+ gboolean have_hidden;
9287+ GSList *l;
9288+ struct ShowAndSelectPathsData *data = user_data;
9289
9290- if (handle != data->impl->should_respond_get_info_handle)
9291- goto out;
9292+ have_hidden = FALSE;
9293
9294- data->impl->should_respond_get_info_handle = NULL;
9295+ for (l = data->paths; l; l = l->next)
9296+ {
9297+ const GtkFilePath *path;
9298+ GtkFileInfo *info;
9299
9300- set_busy_cursor (data->impl, FALSE);
9301+ path = l->data;
9302
9303- if (cancelled)
9304- goto out;
9305+ /* NULL GError */
9306+ info = gtk_file_folder_get_info (folder, path, NULL);
9307+ if (info)
9308+ {
9309+ if (!have_hidden)
9310+ have_hidden = gtk_file_info_get_is_hidden (info);
9311
9312- if (!info)
9313- parent_is_folder = FALSE;
9314- else
9315- parent_is_folder = gtk_file_info_get_is_folder (info);
9316+ gtk_file_info_free (info);
9317
9318- if (parent_is_folder)
9319- {
9320- if (data->impl->action == GTK_FILE_CHOOSER_ACTION_SAVE)
9321- {
9322- if (data->file_exists_and_is_not_folder)
9323- {
9324- gboolean retval;
9325- const char *file_part;
9326+ if (have_hidden)
9327+ break; /* we now have all the information we need */
9328+ }
9329+ }
9330
9331- file_part = _gtk_file_chooser_entry_get_file_part (GTK_FILE_CHOOSER_ENTRY (data->impl->location_entry));
9332- retval = should_respond_after_confirm_overwrite (data->impl, file_part, data->parent_path);
9333+ g_signal_handlers_disconnect_by_func (folder,
9334+ show_and_select_paths_finished_loading,
9335+ user_data);
9336
9337- if (retval)
9338- g_signal_emit_by_name (data->impl, "response-requested");
9339- }
9340- else
9341- g_signal_emit_by_name (data->impl, "response-requested");
9342- }
9343- else /* GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER */
9344- {
9345- GtkFileSystemHandle *handle;
9346+ g_object_unref (folder);
9347
9348- g_object_ref (data->impl);
9349- handle = gtk_file_system_create_folder (data->impl->file_system,
9350- data->path,
9351- action_create_folder_cb,
9352- data->impl);
9353- data->impl->pending_handles = g_slist_append (data->impl->pending_handles, handle);
9354- set_busy_cursor (data->impl, TRUE);
9355- }
9356- }
9357- else
9358+ if (have_hidden)
9359+ g_object_set (data->impl, "show-hidden", TRUE, NULL);
9360+
9361+ for (l = data->paths; l; l = l->next)
9362 { 6244 {
9363- /* This will display an error, which is what we want */ 6245 /* This will display an error, which is what we want */
9364- change_folder_and_display_error (data->impl, data->parent_path, FALSE); 6246- change_folder_and_display_error (data->impl, data->parent_path, FALSE);
9365+ const GtkFilePath *path; 6247+ change_folder_and_display_error (data->impl, data->parent_path);
9366+
9367+ path = l->data;
9368+ _gtk_file_system_model_path_do (data->impl->browse_files_model, path,
9369+ select_func, data->impl);
9370 } 6248 }
9371 6249
9372-out:
9373+ browse_files_center_selected_row (data->impl);
9374+
9375 g_object_unref (data->impl);
9376- gtk_file_path_free (data->path);
9377- gtk_file_path_free (data->parent_path);
9378+ gtk_file_paths_free (data->paths);
9379 g_free (data);
9380-
9381- g_object_unref (handle);
9382 }
9383
9384 static void
9385-file_exists_get_info_cb (GtkFileSystemHandle *handle,
9386- const GtkFileInfo *info,
9387- const GError *error,
9388- gpointer user_data)
9389+show_and_select_paths_get_folder_cb (GtkFileSystemHandle *handle,
9390+ GtkFileFolder *folder,
9391+ const GError *error,
9392+ gpointer user_data)
9393 {
9394- gboolean data_ownership_taken = FALSE;
9395 gboolean cancelled = handle->cancelled;
9396- gboolean file_exists_and_is_not_folder;
9397- struct FileExistsData *data = user_data;
9398+ struct ShowAndSelectPathsData *data = user_data;
9399
9400- if (handle != data->impl->file_exists_get_info_handle)
9401+ if (data->impl->show_and_select_paths_handle != handle)
9402 goto out;
9403
9404- data->impl->file_exists_get_info_handle = NULL;
9405-
9406- set_busy_cursor (data->impl, FALSE);
9407+ data->impl->show_and_select_paths_handle = NULL;
9408
9409- if (cancelled)
9410+ if (cancelled || error)
9411 goto out;
9412
9413- file_exists_and_is_not_folder = info && !gtk_file_info_get_is_folder (info);
9414+ g_object_unref (handle);
9415
9416- if (data->impl->action == GTK_FILE_CHOOSER_ACTION_OPEN)
9417- /* user typed a filename; we are done */
9418- g_signal_emit_by_name (data->impl, "response-requested");
9419- else if (data->impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER
9420- && file_exists_and_is_not_folder)
9421- {
9422- /* Oops, the user typed the name of an existing path which is not
9423- * a folder
9424- */
9425- error_creating_folder_over_existing_file_dialog (data->impl, data->path,
9426- g_error_copy (error));
9427- }
9428+ if (gtk_file_folder_is_finished_loading (folder))
9429+ show_and_select_paths_finished_loading (folder, user_data);
9430 else
9431- {
9432- /* check that everything up to the last component exists */
9433-
9434- data->file_exists_and_is_not_folder = file_exists_and_is_not_folder;
9435- data_ownership_taken = TRUE;
9436-
9437- if (data->impl->should_respond_get_info_handle)
9438- gtk_file_system_cancel_operation (data->impl->should_respond_get_info_handle);
9439+ g_signal_connect (folder, "finished-loading",
9440+ G_CALLBACK (show_and_select_paths_finished_loading),
9441+ user_data);
9442
9443- data->impl->should_respond_get_info_handle =
9444- gtk_file_system_get_info (data->impl->file_system,
9445- data->parent_path,
9446- GTK_FILE_INFO_IS_FOLDER,
9447- save_entry_get_info_cb,
9448- data);
9449- set_busy_cursor (data->impl, TRUE);
9450- }
9451+ return;
9452
9453 out: 6250 out:
9454- if (!data_ownership_taken) 6251@@ -8378,51 +4210,7 @@
9455- {
9456- g_object_unref (data->impl);
9457- gtk_file_path_free (data->path);
9458- gtk_file_path_free (data->parent_path);
9459- g_free (data);
9460- }
9461+ g_object_unref (data->impl);
9462+ gtk_file_paths_free (data->paths);
9463+ g_free (data);
9464
9465 g_object_unref (handle); 6252 g_object_unref (handle);
9466 } 6253 }
9467 6254
@@ -9469,23 +6256,15 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
9469-paste_text_received (GtkClipboard *clipboard, 6256-paste_text_received (GtkClipboard *clipboard,
9470- const gchar *text, 6257- const gchar *text,
9471- GtkFileChooserDefault *impl) 6258- GtkFileChooserDefault *impl)
9472+static gboolean 6259-{
9473+show_and_select_paths (GtkFileChooserDefault *impl,
9474+ const GtkFilePath *parent_path,
9475+ GSList *paths,
9476+ GError **error)
9477 {
9478- GtkFilePath *path; 6260- GtkFilePath *path;
9479+ struct ShowAndSelectPathsData *info;
9480 6261
9481- if (!text) 6262- if (!text)
9482- return; 6263- return;
9483+ profile_start ("start", NULL); 6264-
9484
9485- path = gtk_file_system_uri_to_path (impl->file_system, text); 6265- path = gtk_file_system_uri_to_path (impl->file_system, text);
9486- if (!path) 6266- if (!path)
9487+ if (!paths) 6267- {
9488 {
9489- if (!g_path_is_absolute (text)) 6268- if (!g_path_is_absolute (text))
9490- { 6269- {
9491- location_popup_handler (impl, text); 6270- location_popup_handler (impl, text);
@@ -9498,21 +6277,14 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
9498- location_popup_handler (impl, text); 6277- location_popup_handler (impl, text);
9499- return; 6278- return;
9500- } 6279- }
9501+ profile_end ("end", NULL); 6280- }
9502+ return TRUE; 6281-
9503 }
9504
9505- if (!gtk_file_chooser_default_select_path (GTK_FILE_CHOOSER (impl), path, NULL)) 6282- if (!gtk_file_chooser_default_select_path (GTK_FILE_CHOOSER (impl), path, NULL))
9506- location_popup_handler (impl, text); 6283- location_popup_handler (impl, text);
9507+ info = g_new (struct ShowAndSelectPathsData, 1); 6284-
9508+ info->impl = g_object_ref (impl);
9509+ info->paths = gtk_file_paths_copy (paths);
9510
9511- gtk_file_path_free (path); 6285- gtk_file_path_free (path);
9512-} 6286-}
9513+ if (impl->show_and_select_paths_handle) 6287-
9514+ gtk_file_system_cancel_operation (impl->show_and_select_paths_handle);
9515
9516-/* Handler for the "location-popup-on-paste" keybinding signal */ 6288-/* Handler for the "location-popup-on-paste" keybinding signal */
9517-static void 6289-static void
9518-location_popup_on_paste_handler (GtkFileChooserDefault *impl) 6290-location_popup_on_paste_handler (GtkFileChooserDefault *impl)
@@ -9523,326 +6295,60 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
9523- (GtkClipboardTextReceivedFunc) paste_text_received, 6295- (GtkClipboardTextReceivedFunc) paste_text_received,
9524- impl); 6296- impl);
9525-} 6297-}
9526+ impl->show_and_select_paths_handle = 6298-
9527+ gtk_file_system_get_folder (impl->file_system, parent_path, 6299-
9528+ GTK_FILE_INFO_IS_FOLDER | GTK_FILE_INFO_IS_HIDDEN, 6300 /* Implementation for GtkFileChooserEmbed::should_respond() */
9529+ show_and_select_paths_get_folder_cb, info); 6301 static gboolean
9530 6302 gtk_file_chooser_default_should_respond (GtkFileChooserEmbed *chooser_embed)
9531+ profile_end ("end", NULL); 6303@@ -8469,12 +4257,6 @@
9532+ return TRUE;
9533+}
9534
9535-/* Implementation for GtkFileChooserEmbed::should_respond() */
9536-static gboolean
9537-gtk_file_chooser_default_should_respond (GtkFileChooserEmbed *chooser_embed)
9538+/* Processes the pending operation when a folder is finished loading */
9539+static void
9540+pending_select_paths_process (GtkFileChooserDefault *impl)
9541 {
9542- GtkFileChooserDefault *impl;
9543- GtkWidget *toplevel;
9544- GtkWidget *current_focus;
9545+ g_assert (impl->load_state == LOAD_FINISHED);
9546+ g_assert (impl->browse_files_model != NULL);
9547+ g_assert (impl->sort_model != NULL);
9548
9549- impl = GTK_FILE_CHOOSER_DEFAULT (chooser_embed);
9550+ if (impl->pending_select_paths)
9551+ {
9552+ /* NULL GError */
9553+ show_and_select_paths (impl, impl->current_folder, impl->pending_select_paths, NULL);
9554+ pending_select_paths_free (impl);
9555+ browse_files_center_selected_row (impl);
9556+ }
9557+ else
9558+ {
9559+ /* We only select the first row if the chooser is actually mapped ---
9560+ * selecting the first row is to help the user when he is interacting with
9561+ * the chooser, but sometimes a chooser works not on behalf of the user,
9562+ * but rather on behalf of something else like GtkFileChooserButton. In
9563+ * that case, the chooser's selection should be what the caller expects,
9564+ * as the user can't see that something else got selected. See bug #165264.
9565+ *
9566+ * Also, we don't select the first file if we are not in OPEN mode. Doing
9567+ * so would change the contents of the filename entry for SAVE or
9568+ * CREATE_FOLDER, which is undesired; in SELECT_FOLDER, we don't want to
9569+ * select a *different* folder from the one into which the user just
9570+ * navigated.
9571+ */
9572+ if (GTK_WIDGET_MAPPED (impl) && impl->action == GTK_FILE_CHOOSER_ACTION_OPEN)
9573+ browse_files_select_first_row (impl);
9574+ }
9575
9576- toplevel = gtk_widget_get_toplevel (GTK_WIDGET (impl));
9577- g_assert (GTK_IS_WINDOW (toplevel));
9578+ g_assert (impl->pending_select_paths == NULL);
9579+}
9580
9581- current_focus = gtk_window_get_focus (GTK_WINDOW (toplevel));
9582+/* Callback used when the file system model finishes loading */
9583+static void
9584+browse_files_model_finished_loading_cb (GtkFileSystemModel *model,
9585+ GtkFileChooserDefault *impl)
9586+{
9587+ profile_start ("start", NULL);
9588
9589- if (current_focus == impl->browse_files_tree_view)
9590+ if (impl->load_state == LOAD_PRELOAD)
9591 {
9592- /* The following array encodes what we do based on the impl->action and the
9593- * number of files selected.
9594+ load_remove_timer (impl);
9595+ load_set_model (impl);
9596+ }
9597+ else if (impl->load_state == LOAD_LOADING)
9598+ {
9599+ /* Nothing */
9600+ }
9601+ else
9602+ {
9603+ /* We can't g_assert_not_reached(), as something other than us may have
9604+ * initiated a folder reload. See #165556.
9605 */
9606- typedef enum {
9607- NOOP, /* Do nothing (don't respond) */
9608- RESPOND, /* Respond immediately */
9609- RESPOND_OR_SWITCH, /* Respond immediately if the selected item is a file; switch to it if it is a folder */
9610- ALL_FILES, /* Respond only if everything selected is a file */
9611- ALL_FOLDERS, /* Respond only if everything selected is a folder */
9612- SAVE_ENTRY, /* Go to the code for handling the save entry */
9613- NOT_REACHED /* Sanity check */
9614- } ActionToTake;
9615- static const ActionToTake what_to_do[4][3] = {
9616- /* 0 selected 1 selected many selected */
9617- /* ACTION_OPEN */ { NOOP, RESPOND_OR_SWITCH, ALL_FILES },
9618- /* ACTION_SAVE */ { SAVE_ENTRY, RESPOND_OR_SWITCH, NOT_REACHED },
9619- /* ACTION_SELECT_FOLDER */ { RESPOND, ALL_FOLDERS, ALL_FOLDERS },
9620- /* ACTION_CREATE_FOLDER */ { SAVE_ENTRY, ALL_FOLDERS, NOT_REACHED }
9621- };
9622-
9623- int num_selected;
9624- gboolean all_files, all_folders;
9625- int k;
9626- ActionToTake action;
9627+ profile_end ("end", NULL);
9628+ return;
9629+ }
9630
9631- file_list:
9632+ g_assert (impl->load_timeout_id == 0);
9633 6304
9634- g_assert (impl->action >= GTK_FILE_CHOOSER_ACTION_OPEN && impl->action <= GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER); 6305 g_assert (impl->action >= GTK_FILE_CHOOSER_ACTION_OPEN && impl->action <= GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER);
9635+ impl->load_state = LOAD_FINISHED;
9636 6306
9637- if (impl->operation_mode == OPERATION_MODE_SEARCH) 6307- if (impl->operation_mode == OPERATION_MODE_SEARCH)
9638- return search_should_respond (impl); 6308- return search_should_respond (impl);
9639+ pending_select_paths_process (impl); 6309-
9640+ set_busy_cursor (impl, FALSE);
9641+#ifdef PROFILE_FILE_CHOOSER
9642+ access ("MARK: *** FINISHED LOADING", F_OK);
9643+#endif
9644
9645- if (impl->operation_mode == OPERATION_MODE_RECENT) 6310- if (impl->operation_mode == OPERATION_MODE_RECENT)
9646- return recent_should_respond (impl); 6311- return recent_should_respond (impl);
9647+ profile_end ("end", NULL); 6312-
9648+} 6313 selection_check (impl, &num_selected, &all_files, &all_folders);
9649
9650- selection_check (impl, &num_selected, &all_files, &all_folders);
9651+/* Gets rid of the old list model and creates a new one for the current folder */
9652+static gboolean
9653+set_list_model (GtkFileChooserDefault *impl,
9654+ GError **error)
9655+{
9656+ g_assert (impl->current_folder != NULL);
9657
9658- if (num_selected > 2)
9659- k = 2;
9660- else
9661- k = num_selected;
9662+ profile_start ("start", NULL);
9663
9664- action = what_to_do [impl->action] [k];
9665+ load_remove_timer (impl); /* This changes the state to LOAD_EMPTY */
9666
9667- switch (action)
9668- {
9669- case NOOP:
9670- return FALSE;
9671+ if (impl->browse_files_model)
9672+ {
9673+ g_object_unref (impl->browse_files_model);
9674+ impl->browse_files_model = NULL;
9675+ }
9676
9677- case RESPOND:
9678- return TRUE;
9679+ if (impl->sort_model)
9680+ {
9681+ g_object_unref (impl->sort_model);
9682+ impl->sort_model = NULL;
9683+ }
9684
9685- case RESPOND_OR_SWITCH:
9686- g_assert (num_selected == 1);
9687+ set_busy_cursor (impl, TRUE);
9688+ gtk_tree_view_set_model (GTK_TREE_VIEW (impl->browse_files_tree_view), NULL);
9689
9690- if (all_folders)
9691- {
9692- switch_to_selected_folder (impl);
9693- return FALSE;
9694- }
9695- else if (impl->action == GTK_FILE_CHOOSER_ACTION_SAVE)
9696- return should_respond_after_confirm_overwrite (impl,
9697- get_display_name_from_file_list (impl),
9698- impl->current_folder);
9699- else
9700- return TRUE;
9701+ impl->browse_files_model = _gtk_file_system_model_new (impl->file_system,
9702+ impl->current_folder, 0,
9703+ GTK_FILE_INFO_ALL,
9704+ error);
9705+ if (!impl->browse_files_model)
9706+ {
9707+ set_busy_cursor (impl, FALSE);
9708+ profile_end ("end", NULL);
9709+ return FALSE;
9710+ }
9711
9712- case ALL_FILES:
9713- return all_files;
9714+ load_setup_timer (impl); /* This changes the state to LOAD_PRELOAD */
9715
9716- case ALL_FOLDERS:
9717- return all_folders;
9718+ g_signal_connect (impl->browse_files_model, "finished-loading",
9719+ G_CALLBACK (browse_files_model_finished_loading_cb), impl);
9720
9721- case SAVE_ENTRY:
9722- goto save_entry;
9723+ _gtk_file_system_model_set_show_hidden (impl->browse_files_model, impl->show_hidden);
9724
9725- default:
9726- g_assert_not_reached ();
9727- }
9728- }
9729- else if ((impl->location_entry != NULL) && (current_focus == impl->location_entry))
9730- {
9731- GtkFilePath *path;
9732- gboolean is_well_formed, is_empty, is_file_part_empty;
9733- gboolean is_folder;
9734- gboolean retval;
9735- GtkFileChooserEntry *entry;
9736- GError *error;
9737+ install_list_model_filter (impl);
9738 6314
9739- save_entry: 6315 if (num_selected > 2)
9740+ profile_end ("end", NULL); 6316@@ -8533,9 +4315,8 @@
9741 6317
9742- g_assert (impl->action == GTK_FILE_CHOOSER_ACTION_SAVE 6318 g_assert (impl->action == GTK_FILE_CHOOSER_ACTION_SAVE
9743- || impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER 6319 || impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER
9744- || ((impl->action == GTK_FILE_CHOOSER_ACTION_OPEN 6320- || ((impl->action == GTK_FILE_CHOOSER_ACTION_OPEN
9745- || impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER) 6321- || impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER)
9746- && impl->location_mode == LOCATION_MODE_FILENAME_ENTRY)); 6322- && impl->location_mode == LOCATION_MODE_FILENAME_ENTRY));
9747+ return TRUE; 6323+ || impl->action == GTK_FILE_CHOOSER_ACTION_OPEN
9748+} 6324+ || impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER);
9749
9750- entry = GTK_FILE_CHOOSER_ENTRY (impl->location_entry);
9751- check_save_entry (impl, &path, &is_well_formed, &is_empty, &is_file_part_empty, &is_folder);
9752+struct update_chooser_entry_selected_foreach_closure {
9753+ int num_selected;
9754+ GtkTreeIter first_selected_iter;
9755+};
9756
9757- if (is_empty || !is_well_formed)
9758- return FALSE;
9759+static gint
9760+compare_utf8_filenames (const gchar *a,
9761+ const gchar *b)
9762+{
9763+ gchar *a_folded, *b_folded;
9764+ gint retval;
9765
9766- g_assert (path != NULL);
9767+ a_folded = g_utf8_strdown (a, -1);
9768+ b_folded = g_utf8_strdown (b, -1);
9769 6325
9770- error = NULL; 6326 entry = GTK_FILE_CHOOSER_ENTRY (impl->location_entry);
9771- if (is_folder) 6327 check_save_entry (impl, &path, &is_well_formed, &is_empty, &is_file_part_empty, &is_folder);
9772- { 6328@@ -8548,14 +4329,14 @@
6329 error = NULL;
6330 if (is_folder)
6331 {
9773- if (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN || 6332- if (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN ||
9774- impl->action == GTK_FILE_CHOOSER_ACTION_SAVE) 6333- impl->action == GTK_FILE_CHOOSER_ACTION_SAVE)
9775- { 6334+ if (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN
6335+ || impl->action == GTK_FILE_CHOOSER_ACTION_SAVE)
6336 {
9776- change_folder_and_display_error (impl, path, TRUE); 6337- change_folder_and_display_error (impl, path, TRUE);
9777- retval = FALSE; 6338+ change_folder_and_display_error (impl, path);
9778- } 6339 retval = FALSE;
6340 }
9779- else if (impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER || 6341- else if (impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER ||
9780- impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER) 6342- impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)
9781- { 6343+ else if (impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER
9782- /* The folder already exists, so we do not need to create it. 6344+ || GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)
9783- * Just respond to terminate the dialog. 6345 {
9784- */ 6346 /* The folder already exists, so we do not need to create it.
9785- retval = TRUE; 6347 * Just respond to terminate the dialog.
9786- } 6348@@ -8598,37 +4379,13 @@
9787- else 6349 gtk_file_path_free (path);
9788- { 6350 return retval;
9789- g_assert_not_reached (); 6351 }
9790- retval = FALSE;
9791- }
9792- }
9793- else
9794- {
9795- struct FileExistsData *data;
9796+ retval = strcmp (a_folded, b_folded);
9797
9798- /* We need to check whether path exists and is not a folder */
9799+ g_free (a_folded);
9800+ g_free (b_folded);
9801
9802- data = g_new0 (struct FileExistsData, 1);
9803- data->impl = g_object_ref (impl);
9804- data->path = gtk_file_path_copy (path);
9805- data->parent_path = gtk_file_path_copy (_gtk_file_chooser_entry_get_current_folder (entry));
9806+ return retval;
9807+}
9808
9809- if (impl->file_exists_get_info_handle)
9810- gtk_file_system_cancel_operation (impl->file_exists_get_info_handle);
9811+static void
9812+update_chooser_entry_selected_foreach (GtkTreeModel *model,
9813+ GtkTreePath *path,
9814+ GtkTreeIter *iter,
9815+ gpointer data)
9816+{
9817+ struct update_chooser_entry_selected_foreach_closure *closure;
9818
9819- impl->file_exists_get_info_handle =
9820- gtk_file_system_get_info (impl->file_system, path,
9821- GTK_FILE_INFO_IS_FOLDER,
9822- file_exists_get_info_cb,
9823- data);
9824+ closure = data;
9825+ closure->num_selected++;
9826
9827- set_busy_cursor (impl, TRUE);
9828- retval = FALSE;
9829+ if (closure->num_selected == 1)
9830+ closure->first_selected_iter = *iter;
9831+}
9832
9833- if (error != NULL)
9834- g_error_free (error);
9835- }
9836+static void
9837+update_chooser_entry (GtkFileChooserDefault *impl)
9838+{
9839+ GtkTreeSelection *selection;
9840+ struct update_chooser_entry_selected_foreach_closure closure;
9841+ const char *file_part;
9842
9843- gtk_file_path_free (path);
9844- return retval;
9845- }
9846- else if (impl->toplevel_last_focus_widget == impl->browse_shortcuts_tree_view) 6352- else if (impl->toplevel_last_focus_widget == impl->browse_shortcuts_tree_view)
9847- { 6353- {
9848- /* The focus is on a dialog's action area button, *and* the widget that 6354- /* 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
9850- * selected shortcut and tell the caller not to respond. 6356- * selected shortcut and tell the caller not to respond.
9851- */ 6357- */
9852- GtkTreeIter iter; 6358- GtkTreeIter iter;
9853+ if (!(impl->action == GTK_FILE_CHOOSER_ACTION_SAVE 6359-
9854+ || impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER
9855+ || impl->action == GTK_FILE_CHOOSER_ACTION_OPEN
9856+ || impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER))
9857+ return;
9858
9859- if (shortcuts_get_selected (impl, &iter)) 6360- if (shortcuts_get_selected (impl, &iter))
9860- { 6361- {
9861- shortcuts_activate_iter (impl, &iter); 6362- shortcuts_activate_iter (impl, &iter);
@@ -9864,110 +6365,56 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
9864- } 6365- }
9865- else 6366- else
9866- goto file_list; 6367- goto file_list;
9867+ g_assert (impl->location_entry != NULL); 6368-
9868
9869- return FALSE; 6369- return FALSE;
9870- } 6370- }
9871- else if (impl->toplevel_last_focus_widget == impl->browse_files_tree_view) 6371 else if (impl->toplevel_last_focus_widget == impl->browse_files_tree_view)
9872- { 6372 {
9873- /* The focus is on a dialog's action area button, *and* the widget that 6373 /* The focus is on a dialog's action area button, *and* the widget that
9874- * was focused immediately before it is the file list. 6374- * was focused immediately before it is the file list.
9875- */ 6375+ * was focused immediately before it is the file list.
9876- goto file_list; 6376 */
9877- } 6377 goto file_list;
6378 }
9878- else if (impl->operation_mode == OPERATION_MODE_SEARCH && impl->toplevel_last_focus_widget == impl->search_entry) 6379- else if (impl->operation_mode == OPERATION_MODE_SEARCH && impl->toplevel_last_focus_widget == impl->search_entry)
9879+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_files_tree_view)); 6380- {
9880+ closure.num_selected = 0;
9881+ gtk_tree_selection_selected_foreach (selection, update_chooser_entry_selected_foreach, &closure);
9882+
9883+ file_part = NULL;
9884+
9885+ if (closure.num_selected == 0)
9886 {
9887- search_entry_activate_cb (GTK_ENTRY (impl->search_entry), impl); 6381- search_entry_activate_cb (GTK_ENTRY (impl->search_entry), impl);
9888- return FALSE; 6382- return FALSE;
9889+ goto maybe_clear_entry;
9890 }
9891- else if (impl->location_entry && impl->toplevel_last_focus_widget == impl->location_entry)
9892+ else if (closure.num_selected == 1)
9893 {
9894- /* The focus is on a dialog's action area button, *and* the widget that
9895- * was focused immediately before it is the location entry.
9896- */
9897- goto save_entry;
9898- } 6383- }
9899- else 6384 else if (impl->location_entry && impl->toplevel_last_focus_widget == impl->location_entry)
9900- /* The focus is on a dialog's action area button or something else */ 6385 {
9901- if (impl->action == GTK_FILE_CHOOSER_ACTION_SAVE 6386 /* The focus is on a dialog's action area button, *and* the widget that
9902- || impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER) 6387@@ -8657,17 +4414,16 @@
9903- goto save_entry;
9904- else
9905- goto file_list;
9906-
9907- g_assert_not_reached ();
9908- return FALSE;
9909-}
9910+ GtkTreeIter child_iter;
9911+ const GtkFileInfo *info;
9912+ gboolean change_entry;
9913
9914-/* Implementation for GtkFileChooserEmbed::initial_focus() */
9915-static void
9916-gtk_file_chooser_default_initial_focus (GtkFileChooserEmbed *chooser_embed)
9917-{
9918- GtkFileChooserDefault *impl;
9919- GtkWidget *widget;
9920+ gtk_tree_model_sort_convert_iter_to_child_iter (impl->sort_model,
9921+ &child_iter,
9922+ &closure.first_selected_iter);
9923 6388
9924- impl = GTK_FILE_CHOOSER_DEFAULT (chooser_embed); 6389 impl = GTK_FILE_CHOOSER_DEFAULT (chooser_embed);
9925+ info = _gtk_file_system_model_get_info (impl->browse_files_model, &child_iter);
9926 6390
9927- if (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN || 6391- if (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN ||
9928- impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER) 6392- impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER)
9929- { 6393+ if (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN
6394+ || impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER)
6395 {
9930- if (impl->location_mode == LOCATION_MODE_PATH_BAR) 6396- if (impl->location_mode == LOCATION_MODE_PATH_BAR)
9931- widget = impl->browse_files_tree_view; 6397 widget = impl->browse_files_tree_view;
9932+ /* If the cursor moved to the row of the newly created folder, 6398- else
9933+ * retrieving info will return NULL.
9934+ */
9935+ if (!info)
9936+ return;
9937+
9938+ g_free (impl->browse_files_last_selected_name);
9939+ impl->browse_files_last_selected_name = g_strdup (gtk_file_info_get_display_name (info));
9940+
9941+ if (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN
9942+ || impl->action == GTK_FILE_CHOOSER_ACTION_SAVE)
9943+ change_entry = !gtk_file_info_get_is_folder (info); /* We don't want the name to change when clicking on a folder... */
9944 else
9945- widget = impl->location_entry; 6399- widget = impl->location_entry;
9946+ change_entry = TRUE; /* ... unless we are in one of the folder modes */
9947+
9948+ if (change_entry)
9949+ _gtk_file_chooser_entry_set_file_part (GTK_FILE_CHOOSER_ENTRY (impl->location_entry), impl->browse_files_last_selected_name);
9950+
9951+ return;
9952 } 6400 }
9953- else if (impl->action == GTK_FILE_CHOOSER_ACTION_SAVE || 6401- else if (impl->action == GTK_FILE_CHOOSER_ACTION_SAVE ||
9954- impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER) 6402- impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)
9955- widget = impl->location_entry; 6403- widget = impl->location_entry;
6404+ else if (impl->action == GTK_FILE_CHOOSER_ACTION_SAVE
6405+ || impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)
6406+ {
6407+ widget = impl->location_entry;
6408+ }
9956 else 6409 else
9957 { 6410 {
9958- g_assert_not_reached (); 6411 g_assert_not_reached ();
9959- widget = NULL; 6412@@ -8678,1475 +4434,7 @@
9960- } 6413 gtk_widget_grab_focus (widget);
9961+ g_assert (!(impl->action == GTK_FILE_CHOOSER_ACTION_SAVE 6414 }
9962+ || impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER));
9963
9964- g_assert (widget != NULL);
9965- gtk_widget_grab_focus (widget);
9966-}
9967+ /* Multiple selection, so just clear the entry. */
9968 6415
9969-/* Callback used from gtk_tree_selection_selected_foreach(); gets the selected GtkFilePaths */ 6416-/* Callback used from gtk_tree_selection_selected_foreach(); gets the selected GtkFilePaths */
9970-static void 6417 static void
9971-search_selected_foreach_get_path_cb (GtkTreeModel *model, 6418-search_selected_foreach_get_path_cb (GtkTreeModel *model,
9972- GtkTreePath *path, 6419- GtkTreePath *path,
9973- GtkTreeIter *iter, 6420- GtkTreeIter *iter,
@@ -9976,105 +6423,58 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
9976- GSList **list; 6423- GSList **list;
9977- const GtkFilePath *file_path; 6424- const GtkFilePath *file_path;
9978- GtkFilePath *file_path_copy; 6425- GtkFilePath *file_path_copy;
9979+ g_free (impl->browse_files_last_selected_name); 6426-
9980+ impl->browse_files_last_selected_name = NULL;
9981
9982- list = data; 6427- list = data;
9983+ _gtk_file_chooser_entry_set_file_part (GTK_FILE_CHOOSER_ENTRY (impl->location_entry), ""); 6428-
9984+ return;
9985+ }
9986
9987- gtk_tree_model_get (model, iter, SEARCH_MODEL_COL_PATH, &file_path, -1); 6429- gtk_tree_model_get (model, iter, SEARCH_MODEL_COL_PATH, &file_path, -1);
9988- file_path_copy = gtk_file_path_copy (file_path); 6430- file_path_copy = gtk_file_path_copy (file_path);
9989- *list = g_slist_prepend (*list, file_path_copy); 6431- *list = g_slist_prepend (*list, file_path_copy);
9990-} 6432-}
9991+ maybe_clear_entry: 6433-
9992
9993-/* Constructs a list of the selected paths in search mode */ 6434-/* Constructs a list of the selected paths in search mode */
9994-static GSList * 6435-static GSList *
9995-search_get_selected_paths (GtkFileChooserDefault *impl) 6436-search_get_selected_paths (GtkFileChooserDefault *impl)
9996-{ 6437-{
9997- GSList *result; 6438- GSList *result;
9998- GtkTreeSelection *selection; 6439- GtkTreeSelection *selection;
9999+ if (impl->browse_files_last_selected_name) 6440-
10000+ {
10001+ const char *entry_text;
10002+ int len;
10003+ gboolean clear_entry;
10004
10005- result = NULL; 6441- result = NULL;
10006+ entry_text = gtk_entry_get_text (GTK_ENTRY (impl->location_entry)); 6442-
10007+ len = strlen (entry_text);
10008+ if (len != 0)
10009+ {
10010+ /* The file chooser entry may have appended a "/" to its text. So
10011+ * take it out, and compare the result to the old selection.
10012+ */
10013+ if (entry_text[len - 1] == G_DIR_SEPARATOR)
10014+ {
10015+ char *tmp;
10016
10017- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_files_tree_view)); 6443- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_files_tree_view));
10018- gtk_tree_selection_selected_foreach (selection, search_selected_foreach_get_path_cb, &result); 6444- gtk_tree_selection_selected_foreach (selection, search_selected_foreach_get_path_cb, &result);
10019- result = g_slist_reverse (result); 6445- result = g_slist_reverse (result);
10020+ tmp = g_strndup (entry_text, len - 1); 6446-
10021+ clear_entry = (compare_utf8_filenames (impl->browse_files_last_selected_name, tmp) == 0);
10022+ g_free (tmp);
10023+ }
10024+ else
10025+ clear_entry = (compare_utf8_filenames (impl->browse_files_last_selected_name, entry_text) == 0);
10026+ }
10027+ else
10028+ clear_entry = FALSE;
10029
10030- return result; 6447- return result;
10031+ if (clear_entry) 6448-}
10032+ _gtk_file_chooser_entry_set_file_part (GTK_FILE_CHOOSER_ENTRY (impl->location_entry), ""); 6449-
10033+ }
10034 }
10035
10036-/* Called from ::should_respond(). We return whether there are selected files 6450-/* Called from ::should_respond(). We return whether there are selected files
10037- * in the search list. 6451- * in the search list.
10038- */ 6452- */
10039 static gboolean 6453-static gboolean
10040-search_should_respond (GtkFileChooserDefault *impl) 6454-search_should_respond (GtkFileChooserDefault *impl)
10041+gtk_file_chooser_default_set_current_folder (GtkFileChooser *chooser, 6455-{
10042+ const GtkFilePath *path,
10043+ GError **error)
10044 {
10045- GtkTreeSelection *selection; 6456- GtkTreeSelection *selection;
10046- 6457-
10047- g_assert (impl->operation_mode == OPERATION_MODE_SEARCH); 6458- g_assert (impl->operation_mode == OPERATION_MODE_SEARCH);
10048- 6459-
10049- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_files_tree_view)); 6460- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_files_tree_view));
10050- return (gtk_tree_selection_count_selected_rows (selection) != 0); 6461- return (gtk_tree_selection_count_selected_rows (selection) != 0);
10051+ return gtk_file_chooser_default_update_current_folder (chooser, path, FALSE, FALSE, error); 6462-}
10052 } 6463-
10053
10054-struct SearchHitInsertRequest 6464-struct SearchHitInsertRequest
10055+ 6465-{
10056+struct UpdateCurrentFolderData 6466- GtkFileChooserDefault *impl;
10057 { 6467- GtkFilePath *path;
10058 GtkFileChooserDefault *impl;
10059 GtkFilePath *path;
10060- GtkTreeRowReference *row_ref; 6468- GtkTreeRowReference *row_ref;
10061+ gboolean keep_trail; 6469-};
10062+ gboolean clear_entry; 6470-
10063+ GtkFilePath *original_path; 6471-static void
10064+ GError *original_error;
10065 };
10066
10067 static void
10068-search_hit_get_info_cb (GtkFileSystemHandle *handle, 6472-search_hit_get_info_cb (GtkFileSystemHandle *handle,
10069- const GtkFileInfo *info, 6473- const GtkFileInfo *info,
10070- const GError *error, 6474- const GError *error,
10071- gpointer data) 6475- gpointer data)
10072+update_current_folder_get_info_cb (GtkFileSystemHandle *handle, 6476-{
10073+ const GtkFileInfo *info, 6477- gboolean cancelled = handle->cancelled;
10074+ const GError *error,
10075+ gpointer user_data)
10076 {
10077 gboolean cancelled = handle->cancelled;
10078- GdkPixbuf *pixbuf = NULL; 6478- GdkPixbuf *pixbuf = NULL;
10079- GtkTreePath *path; 6479- GtkTreePath *path;
10080- GtkTreeIter iter; 6480- GtkTreeIter iter;
@@ -10086,14 +6486,11 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
10086- 6486-
10087- if (!request->impl->search_model) 6487- if (!request->impl->search_model)
10088- goto out; 6488- goto out;
10089+ struct UpdateCurrentFolderData *data = user_data; 6489-
10090+ GtkFileChooserDefault *impl = data->impl;
10091
10092- path = gtk_tree_row_reference_get_path (request->row_ref); 6490- path = gtk_tree_row_reference_get_path (request->row_ref);
10093- if (!path) 6491- if (!path)
10094+ if (handle != impl->update_current_folder_handle) 6492- goto out;
10095 goto out; 6493-
10096
10097- gtk_tree_model_get_iter (GTK_TREE_MODEL (request->impl->search_model), 6494- gtk_tree_model_get_iter (GTK_TREE_MODEL (request->impl->search_model),
10098- &iter, path); 6495- &iter, path);
10099- gtk_tree_path_free (path); 6496- gtk_tree_path_free (path);
@@ -10103,70 +6500,46 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
10103- -1); 6500- -1);
10104- if (handle != model_handle) 6501- if (handle != model_handle)
10105- goto out; 6502- goto out;
10106+ impl->update_current_folder_handle = NULL; 6503-
10107+ impl->reload_state = RELOAD_EMPTY;
10108
10109- /* set the handle to NULL in the model */ 6504- /* set the handle to NULL in the model */
10110- gtk_list_store_set (request->impl->search_model, &iter, 6505- gtk_list_store_set (request->impl->search_model, &iter,
10111- SEARCH_MODEL_COL_HANDLE, NULL, 6506- SEARCH_MODEL_COL_HANDLE, NULL,
10112- -1); 6507- -1);
10113+ set_busy_cursor (impl, FALSE); 6508-
10114 6509- if (cancelled)
10115 if (cancelled) 6510- goto out;
10116 goto out; 6511-
10117
10118- if (!info) 6512- if (!info)
10119+ if (error) 6513- {
10120 {
10121- gtk_list_store_remove (request->impl->search_model, &iter); 6514- gtk_list_store_remove (request->impl->search_model, &iter);
10122- goto out; 6515- goto out;
10123- } 6516- }
10124+ GtkFilePath *parent_path; 6517-
10125
10126- display_name = g_strdup (gtk_file_info_get_display_name (info)); 6518- display_name = g_strdup (gtk_file_info_get_display_name (info));
10127- mime_type = g_strdup (gtk_file_info_get_mime_type (info)); 6519- mime_type = g_strdup (gtk_file_info_get_mime_type (info));
10128- is_folder = gtk_file_info_get_is_folder (info); 6520- is_folder = gtk_file_info_get_is_folder (info);
10129- pixbuf = gtk_file_info_render_icon (info, GTK_WIDGET (request->impl), 6521- pixbuf = gtk_file_info_render_icon (info, GTK_WIDGET (request->impl),
10130- request->impl->icon_size, NULL); 6522- request->impl->icon_size, NULL);
10131+ if (!data->original_path) 6523-
10132+ {
10133+ data->original_path = gtk_file_path_copy (data->path);
10134+ data->original_error = g_error_copy (error);
10135+ }
10136
10137- gtk_list_store_set (request->impl->search_model, &iter, 6524- gtk_list_store_set (request->impl->search_model, &iter,
10138- SEARCH_MODEL_COL_PIXBUF, pixbuf, 6525- SEARCH_MODEL_COL_PIXBUF, pixbuf,
10139- SEARCH_MODEL_COL_DISPLAY_NAME, display_name, 6526- SEARCH_MODEL_COL_DISPLAY_NAME, display_name,
10140- SEARCH_MODEL_COL_MIME_TYPE, mime_type, 6527- SEARCH_MODEL_COL_MIME_TYPE, mime_type,
10141- SEARCH_MODEL_COL_IS_FOLDER, is_folder, 6528- SEARCH_MODEL_COL_IS_FOLDER, is_folder,
10142- -1); 6529- -1);
10143+ /* get parent path and try to change the folder to that */ 6530-
10144+ if (gtk_file_system_get_parent (impl->file_system, data->path, &parent_path, NULL) &&
10145+ parent_path)
10146+ {
10147+ gtk_file_path_free (data->path);
10148+ data->path = parent_path;
10149
10150- if (pixbuf) 6531- if (pixbuf)
10151- g_object_unref (pixbuf); 6532- g_object_unref (pixbuf);
10152+ g_object_unref (handle); 6533-
10153
10154-out: 6534-out:
10155- g_object_unref (request->impl); 6535- g_object_unref (request->impl);
10156- gtk_file_path_free (request->path); 6536- gtk_file_path_free (request->path);
10157- gtk_tree_row_reference_free (request->row_ref); 6537- gtk_tree_row_reference_free (request->row_ref);
10158- g_free (request); 6538- g_free (request);
10159+ /* restart the update current folder operation */ 6539-
10160+ impl->reload_state = RELOAD_HAS_FOLDER;
10161
10162- g_object_unref (handle); 6540- g_object_unref (handle);
10163-} 6541-}
10164+ impl->update_current_folder_handle = 6542-
10165+ gtk_file_system_get_info (impl->file_system, data->path,
10166+ GTK_FILE_INFO_IS_FOLDER,
10167+ update_current_folder_get_info_cb,
10168+ data);
10169
10170-/* Adds one hit from the search engine to the search_model */ 6543-/* Adds one hit from the search engine to the search_model */
10171-static void 6544-static void
10172-search_add_hit (GtkFileChooserDefault *impl, 6545-search_add_hit (GtkFileChooserDefault *impl,
@@ -10182,50 +6555,28 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
10182- GtkTreePath *p; 6555- GtkTreePath *p;
10183- GtkFileSystemHandle *handle; 6556- GtkFileSystemHandle *handle;
10184- struct SearchHitInsertRequest *request; 6557- struct SearchHitInsertRequest *request;
10185+ set_busy_cursor (impl, TRUE); 6558-
10186
10187- path = gtk_file_system_uri_to_path (impl->file_system, uri); 6559- path = gtk_file_system_uri_to_path (impl->file_system, uri);
10188- if (!path) 6560- if (!path)
10189- return; 6561- return;
10190+ return; 6562-
10191+ }
10192+ else
10193+ {
10194+ /* error and bail out */
10195+ error_changing_folder_dialog (impl, data->original_path, data->original_error);
10196
10197- filename = gtk_file_system_path_to_filename (impl->file_system, path); 6563- filename = gtk_file_system_path_to_filename (impl->file_system, path);
10198- if (!filename) 6564- if (!filename)
10199- { 6565- {
10200- gtk_file_path_free (path); 6566- gtk_file_path_free (path);
10201- return; 6567- return;
10202+ gtk_file_path_free (data->original_path); 6568- }
10203+ 6569-
10204+ goto out;
10205+ }
10206 }
10207
10208- if (stat (filename, &statbuf) != 0) 6570- if (stat (filename, &statbuf) != 0)
10209+ if (data->original_path) 6571- {
10210 {
10211- gtk_file_path_free (path); 6572- gtk_file_path_free (path);
10212- g_free (filename); 6573- g_free (filename);
10213- return; 6574- return;
10214+ error_changing_folder_dialog (impl, data->original_path, data->original_error); 6575- }
10215+ 6576-
10216+ gtk_file_path_free (data->original_path);
10217 }
10218
10219- statbuf_copy = g_new (struct stat, 1); 6577- statbuf_copy = g_new (struct stat, 1);
10220- *statbuf_copy = statbuf; 6578- *statbuf_copy = statbuf;
10221+ if (!gtk_file_info_get_is_folder (info)) 6579-
10222+ goto out;
10223+
10224+ if (impl->current_folder != data->path)
10225+ {
10226+ if (impl->current_folder)
10227+ gtk_file_path_free (impl->current_folder);
10228
10229- tmp = g_filename_display_name (filename); 6580- tmp = g_filename_display_name (filename);
10230- collation_key = g_utf8_collate_key_for_filename (tmp, -1); 6581- collation_key = g_utf8_collate_key_for_filename (tmp, -1);
10231- g_free (tmp); 6582- g_free (tmp);
@@ -10233,16 +6584,13 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
10233- request = g_new0 (struct SearchHitInsertRequest, 1); 6584- request = g_new0 (struct SearchHitInsertRequest, 1);
10234- request->impl = g_object_ref (impl); 6585- request->impl = g_object_ref (impl);
10235- request->path = gtk_file_path_copy (path); 6586- request->path = gtk_file_path_copy (path);
10236+ impl->current_folder = gtk_file_path_copy (data->path); 6587-
10237
10238- gtk_list_store_append (impl->search_model, &iter); 6588- gtk_list_store_append (impl->search_model, &iter);
10239- p = gtk_tree_model_get_path (GTK_TREE_MODEL (impl->search_model), &iter); 6589- p = gtk_tree_model_get_path (GTK_TREE_MODEL (impl->search_model), &iter);
10240- 6590-
10241- request->row_ref = gtk_tree_row_reference_new (GTK_TREE_MODEL (impl->search_model), p); 6591- request->row_ref = gtk_tree_row_reference_new (GTK_TREE_MODEL (impl->search_model), p);
10242- gtk_tree_path_free (p); 6592- gtk_tree_path_free (p);
10243+ impl->reload_state = RELOAD_HAS_FOLDER; 6593-
10244+ }
10245
10246- handle = gtk_file_system_get_info (impl->file_system, path, 6594- handle = gtk_file_system_get_info (impl->file_system, path,
10247- GTK_FILE_INFO_IS_FOLDER | GTK_FILE_INFO_ICON | GTK_FILE_INFO_MIME_TYPE | GTK_FILE_INFO_DISPLAY_NAME, 6595- GTK_FILE_INFO_IS_FOLDER | GTK_FILE_INFO_ICON | GTK_FILE_INFO_MIME_TYPE | GTK_FILE_INFO_DISPLAY_NAME,
10248- search_hit_get_info_cb, 6596- search_hit_get_info_cb,
@@ -10266,16 +6614,11 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
10266- GList *l; 6614- GList *l;
10267- 6615-
10268- impl = GTK_FILE_CHOOSER_DEFAULT (data); 6616- impl = GTK_FILE_CHOOSER_DEFAULT (data);
10269+ /* Set the folder on the save entry */ 6617-
10270
10271- for (l = hits; l; l = l->next) 6618- for (l = hits; l; l = l->next)
10272- search_add_hit (impl, (gchar*)l->data); 6619- search_add_hit (impl, (gchar*)l->data);
10273-} 6620-}
10274+ if (impl->location_entry) 6621-
10275+ {
10276+ _gtk_file_chooser_entry_set_base_folder (GTK_FILE_CHOOSER_ENTRY (impl->location_entry),
10277+ impl->current_folder);
10278
10279-/* Callback used from GtkSearchEngine when the query is done running */ 6622-/* Callback used from GtkSearchEngine when the query is done running */
10280-static void 6623-static void
10281-search_engine_finished_cb (GtkSearchEngine *engine, 6624-search_engine_finished_cb (GtkSearchEngine *engine,
@@ -10292,19 +6635,11 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
10292- gtk_tree_view_set_model (GTK_TREE_VIEW (impl->browse_files_tree_view), 6635- gtk_tree_view_set_model (GTK_TREE_VIEW (impl->browse_files_tree_view),
10293- GTK_TREE_MODEL (impl->search_model_filter)); 6636- GTK_TREE_MODEL (impl->search_model_filter));
10294-#endif 6637-#endif
10295+ if (data->clear_entry) 6638-
10296+ _gtk_file_chooser_entry_set_file_part (GTK_FILE_CHOOSER_ENTRY (impl->location_entry), "");
10297+ }
10298
10299- /* FMQ: if search was empty, say that we got no hits */ 6639- /* FMQ: if search was empty, say that we got no hits */
10300- set_busy_cursor (impl, FALSE); 6640- set_busy_cursor (impl, FALSE);
10301-} 6641-}
10302+ /* Create a new list model. This is slightly evil; we store the result value 6642-
10303+ * but perform more actions rather than returning immediately even if it
10304+ * generates an error.
10305+ */
10306+ set_list_model (impl, NULL);
10307
10308-/* Displays a generic error when we cannot create a GtkSearchEngine. 6643-/* Displays a generic error when we cannot create a GtkSearchEngine.
10309- * It would be better if _gtk_search_engine_new() gave us a GError 6644- * It would be better if _gtk_search_engine_new() gave us a GError
10310- * with a better message, but it doesn't do that right now. 6645- * with a better message, but it doesn't do that right now.
@@ -10317,8 +6652,7 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
10317- _("The program was not able to create a connection to the indexer " 6652- _("The program was not able to create a connection to the indexer "
10318- "daemon. Please make sure it is running.")); 6653- "daemon. Please make sure it is running."));
10319-} 6654-}
10320+ /* Refresh controls */ 6655-
10321
10322-static void 6656-static void
10323-search_engine_error_cb (GtkSearchEngine *engine, 6657-search_engine_error_cb (GtkSearchEngine *engine,
10324- const gchar *message, 6658- const gchar *message,
@@ -10327,30 +6661,18 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
10327- GtkFileChooserDefault *impl; 6661- GtkFileChooserDefault *impl;
10328- 6662-
10329- impl = GTK_FILE_CHOOSER_DEFAULT (data); 6663- impl = GTK_FILE_CHOOSER_DEFAULT (data);
10330+ g_signal_emit_by_name (impl, "current-folder-changed", 0); 6664-
10331+ g_signal_emit_by_name (impl, "selection-changed", 0);
10332
10333- search_stop_searching (impl, TRUE); 6665- search_stop_searching (impl, TRUE);
10334- error_message (impl, _("Could not send the search request"), message); 6666- error_message (impl, _("Could not send the search request"), message);
10335+out: 6667-
10336+ gtk_file_path_free (data->path);
10337+ g_free (data);
10338
10339- set_busy_cursor (impl, FALSE); 6668- set_busy_cursor (impl, FALSE);
10340+ g_object_unref (handle); 6669-}
10341 } 6670-
10342
10343-/* Frees the data in the search_model */ 6671-/* Frees the data in the search_model */
10344-static void 6672-static void
10345-search_clear_model (GtkFileChooserDefault *impl, 6673-search_clear_model (GtkFileChooserDefault *impl,
10346- gboolean remove_from_treeview) 6674- gboolean remove_from_treeview)
10347+static gboolean 6675-{
10348+gtk_file_chooser_default_update_current_folder (GtkFileChooser *chooser,
10349+ const GtkFilePath *path,
10350+ gboolean keep_trail,
10351+ gboolean clear_entry,
10352+ GError **error)
10353 {
10354- GtkTreeModel *model; 6676- GtkTreeModel *model;
10355- GtkTreeIter iter; 6677- GtkTreeIter iter;
10356- 6678-
@@ -10385,9 +6707,7 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
10385- g_free (statbuf); 6707- g_free (statbuf);
10386- } 6708- }
10387- while (gtk_tree_model_iter_next (model, &iter)); 6709- while (gtk_tree_model_iter_next (model, &iter));
10388+ GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (chooser); 6710-
10389+ struct UpdateCurrentFolderData *data;
10390
10391- g_object_unref (impl->search_model); 6711- g_object_unref (impl->search_model);
10392- impl->search_model = NULL; 6712- impl->search_model = NULL;
10393- 6713-
@@ -10396,13 +6716,11 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
10396- 6716-
10397- g_object_unref (impl->search_model_sort); 6717- g_object_unref (impl->search_model_sort);
10398- impl->search_model_sort = NULL; 6718- impl->search_model_sort = NULL;
10399+ profile_start ("start", (char *) path); 6719-
10400
10401- if (remove_from_treeview) 6720- if (remove_from_treeview)
10402- gtk_tree_view_set_model (GTK_TREE_VIEW (impl->browse_files_tree_view), NULL); 6721- gtk_tree_view_set_model (GTK_TREE_VIEW (impl->browse_files_tree_view), NULL);
10403-} 6722-}
10404+ g_assert (path != NULL); 6723-
10405
10406-/* Stops any ongoing searches; does not touch the search_model */ 6724-/* Stops any ongoing searches; does not touch the search_model */
10407-static void 6725-static void
10408-search_stop_searching (GtkFileChooserDefault *impl, 6726-search_stop_searching (GtkFileChooserDefault *impl,
@@ -10415,9 +6733,7 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
10415- } 6733- }
10416- 6734-
10417- if (impl->search_engine) 6735- if (impl->search_engine)
10418+ if (impl->local_only && 6736- {
10419+ !gtk_file_system_path_is_local (impl->file_system, path))
10420 {
10421- _gtk_search_engine_stop (impl->search_engine); 6737- _gtk_search_engine_stop (impl->search_engine);
10422- 6738-
10423- g_object_unref (impl->search_engine); 6739- g_object_unref (impl->search_engine);
@@ -10430,76 +6746,46 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
10430-search_switch_to_browse_mode (GtkFileChooserDefault *impl) 6746-search_switch_to_browse_mode (GtkFileChooserDefault *impl)
10431-{ 6747-{
10432- g_assert (impl->operation_mode != OPERATION_MODE_BROWSE); 6748- g_assert (impl->operation_mode != OPERATION_MODE_BROWSE);
10433+ g_set_error (error, 6749-
10434+ GTK_FILE_CHOOSER_ERROR,
10435+ GTK_FILE_CHOOSER_ERROR_BAD_FILENAME,
10436+ _("Cannot change to folder because it is not local"));
10437
10438- search_stop_searching (impl, FALSE); 6750- search_stop_searching (impl, FALSE);
10439- search_clear_model (impl, TRUE); 6751- search_clear_model (impl, TRUE);
10440+ profile_end ("end - not local", (char *) path); 6752-
10441+ return FALSE;
10442+ }
10443
10444- gtk_widget_destroy (impl->search_hbox); 6753- gtk_widget_destroy (impl->search_hbox);
10445- impl->search_hbox = NULL; 6754- impl->search_hbox = NULL;
10446- impl->search_entry = NULL; 6755- impl->search_entry = NULL;
10447+ if (impl->update_current_folder_handle) 6756-
10448+ gtk_file_system_cancel_operation (impl->update_current_folder_handle);
10449
10450- gtk_widget_show (impl->browse_path_bar); 6757- gtk_widget_show (impl->browse_path_bar);
10451- gtk_widget_show (impl->browse_new_folder_button); 6758- gtk_widget_show (impl->browse_new_folder_button);
10452+ /* Test validity of path here. */ 6759-
10453+ data = g_new0 (struct UpdateCurrentFolderData, 1);
10454+ data->impl = impl;
10455+ data->path = gtk_file_path_copy (path);
10456+ data->keep_trail = keep_trail;
10457+ data->clear_entry = clear_entry;
10458
10459- if (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN || 6760- if (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN ||
10460- impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER) 6761- impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER)
10461- { 6762- {
10462- gtk_widget_show (impl->location_button); 6763- gtk_widget_show (impl->location_button);
10463+ impl->reload_state = RELOAD_HAS_FOLDER; 6764-
10464
10465- if (impl->location_mode == LOCATION_MODE_FILENAME_ENTRY) 6765- if (impl->location_mode == LOCATION_MODE_FILENAME_ENTRY)
10466- gtk_widget_show (impl->location_entry_box); 6766- gtk_widget_show (impl->location_entry_box);
10467- } 6767- }
10468+ impl->update_current_folder_handle = 6768-
10469+ gtk_file_system_get_info (impl->file_system, path, GTK_FILE_INFO_IS_FOLDER,
10470+ update_current_folder_get_info_cb,
10471+ data);
10472
10473- impl->operation_mode = OPERATION_MODE_BROWSE; 6769- impl->operation_mode = OPERATION_MODE_BROWSE;
10474+ set_busy_cursor (impl, TRUE); 6770-
10475
10476- file_list_set_sort_column_ids (impl); 6771- file_list_set_sort_column_ids (impl);
10477+ profile_end ("end", NULL); 6772-}
10478+ return TRUE; 6773-
10479 }
10480
10481-/* Sort callback from the path column */ 6774-/* Sort callback from the path column */
10482-static gint 6775-static gint
10483-search_column_path_sort_func (GtkTreeModel *model, 6776-search_column_path_sort_func (GtkTreeModel *model,
10484- GtkTreeIter *a, 6777- GtkTreeIter *a,
10485- GtkTreeIter *b, 6778- GtkTreeIter *b,
10486- gpointer user_data) 6779- gpointer user_data)
10487+static GtkFilePath * 6780-{
10488+gtk_file_chooser_default_get_current_folder (GtkFileChooser *chooser)
10489 {
10490- GtkFileChooserDefault *impl = user_data; 6781- GtkFileChooserDefault *impl = user_data;
10491- GtkTreeIter child_a, child_b; 6782- GtkTreeIter child_a, child_b;
10492- const char *collation_key_a, *collation_key_b; 6783- const char *collation_key_a, *collation_key_b;
10493- gboolean is_folder_a, is_folder_b; 6784- gboolean is_folder_a, is_folder_b;
10494+ GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (chooser); 6785-
10495
10496- gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER (model), &child_a, a); 6786- gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER (model), &child_a, a);
10497- gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER (model), &child_b, b); 6787- gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER (model), &child_b, b);
10498+ if (impl->reload_state == RELOAD_EMPTY) 6788-
10499+ {
10500+ char *current_working_dir;
10501+ GtkFilePath *path;
10502
10503- gtk_tree_model_get (GTK_TREE_MODEL (impl->search_model), &child_a, 6789- gtk_tree_model_get (GTK_TREE_MODEL (impl->search_model), &child_a,
10504- SEARCH_MODEL_COL_IS_FOLDER, &is_folder_a, 6790- SEARCH_MODEL_COL_IS_FOLDER, &is_folder_a,
10505- SEARCH_MODEL_COL_COLLATION_KEY, &collation_key_a, 6791- SEARCH_MODEL_COL_COLLATION_KEY, &collation_key_a,
@@ -10508,53 +6794,28 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
10508- SEARCH_MODEL_COL_IS_FOLDER, &is_folder_b, 6794- SEARCH_MODEL_COL_IS_FOLDER, &is_folder_b,
10509- SEARCH_MODEL_COL_COLLATION_KEY, &collation_key_b, 6795- SEARCH_MODEL_COL_COLLATION_KEY, &collation_key_b,
10510- -1); 6796- -1);
10511+ /* We are unmapped, or we had an error while loading the last folder. We'll return 6797-
10512+ * the $cwd since once we get (re)mapped, we'll load $cwd anyway unless the caller
10513+ * explicitly calls set_current_folder() on us.
10514+ */
10515+ current_working_dir = g_get_current_dir ();
10516+ path = gtk_file_system_filename_to_path (impl->file_system, current_working_dir);
10517+ g_free (current_working_dir);
10518+ return path;
10519+ }
10520
10521- if (!collation_key_a) 6798- if (!collation_key_a)
10522- return 1; 6799- return 1;
10523+ return gtk_file_path_copy (impl->current_folder); 6800-
10524+}
10525
10526- if (!collation_key_b) 6801- if (!collation_key_b)
10527- return -1; 6802- return -1;
10528+static void 6803-
10529+gtk_file_chooser_default_set_current_name (GtkFileChooser *chooser,
10530+ const gchar *name)
10531+{
10532+ GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (chooser);
10533
10534- /* always show folders first */ 6804- /* always show folders first */
10535- if (is_folder_a != is_folder_b) 6805- if (is_folder_a != is_folder_b)
10536- return is_folder_a ? 1 : -1; 6806- return is_folder_a ? 1 : -1;
10537+ g_return_if_fail (impl->action == GTK_FILE_CHOOSER_ACTION_SAVE 6807-
10538+ || impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER);
10539
10540- return strcmp (collation_key_a, collation_key_b); 6808- return strcmp (collation_key_a, collation_key_b);
10541+ pending_select_paths_free (impl); 6809-}
10542+ _gtk_file_chooser_entry_set_file_part (GTK_FILE_CHOOSER_ENTRY (impl->location_entry), name); 6810-
10543 }
10544
10545-/* Sort callback from the modification time column */ 6811-/* Sort callback from the modification time column */
10546-static gint 6812-static gint
10547-search_column_mtime_sort_func (GtkTreeModel *model, 6813-search_column_mtime_sort_func (GtkTreeModel *model,
10548- GtkTreeIter *a, 6814- GtkTreeIter *a,
10549- GtkTreeIter *b, 6815- GtkTreeIter *b,
10550- gpointer user_data) 6816- gpointer user_data)
10551+static void 6817-{
10552+select_func (GtkFileSystemModel *model, 6818- GtkFileChooserDefault *impl = user_data;
10553+ GtkTreePath *path,
10554+ GtkTreeIter *iter,
10555+ gpointer user_data)
10556 {
10557 GtkFileChooserDefault *impl = user_data;
10558- GtkTreeIter child_a, child_b; 6819- GtkTreeIter child_a, child_b;
10559- const struct stat *statbuf_a, *statbuf_b; 6820- const struct stat *statbuf_a, *statbuf_b;
10560- gboolean is_folder_a, is_folder_b; 6821- gboolean is_folder_a, is_folder_b;
@@ -10581,167 +6842,100 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
10581- 6842-
10582- if (!statbuf_b) 6843- if (!statbuf_b)
10583- return -1; 6844- return -1;
10584+ GtkTreeSelection *selection; 6845-
10585+ GtkTreeIter sorted_iter;
10586
10587- if (is_folder_a != is_folder_b) 6846- if (is_folder_a != is_folder_b)
10588- return is_folder_a ? 1 : -1; 6847- return is_folder_a ? 1 : -1;
10589+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_files_tree_view)); 6848-
10590
10591- if (statbuf_a->st_mtime < statbuf_b->st_mtime) 6849- if (statbuf_a->st_mtime < statbuf_b->st_mtime)
10592- return -1; 6850- return -1;
10593- else if (statbuf_a->st_mtime > statbuf_b->st_mtime) 6851- else if (statbuf_a->st_mtime > statbuf_b->st_mtime)
10594- return 1; 6852- return 1;
10595- else 6853- else
10596- return 0; 6854- return 0;
10597+ gtk_tree_model_sort_convert_child_iter_to_iter (impl->sort_model, &sorted_iter, iter); 6855-}
10598+ gtk_tree_selection_select_iter (selection, &sorted_iter); 6856-
10599 } 6857-static gboolean
10600
10601 static gboolean
10602-search_get_is_filtered (GtkFileChooserDefault *impl, 6858-search_get_is_filtered (GtkFileChooserDefault *impl,
10603- const GtkFilePath *path, 6859- const GtkFilePath *path,
10604- const gchar *display_name, 6860- const gchar *display_name,
10605- const gchar *mime_type) 6861- const gchar *mime_type)
10606+gtk_file_chooser_default_select_path (GtkFileChooser *chooser, 6862-{
10607+ const GtkFilePath *path,
10608+ GError **error)
10609 {
10610- GtkFileFilterInfo filter_info; 6863- GtkFileFilterInfo filter_info;
10611- GtkFileFilterFlags needed; 6864- GtkFileFilterFlags needed;
10612- gboolean result; 6865- gboolean result;
10613+ GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (chooser); 6866-
10614+ GtkFilePath *parent_path;
10615+ gboolean same_path;
10616
10617- if (!impl->current_filter) 6867- if (!impl->current_filter)
10618+ if (!gtk_file_system_get_parent (impl->file_system, path, &parent_path, error)) 6868- return FALSE;
10619 return FALSE; 6869-
10620
10621- filter_info.contains = GTK_FILE_FILTER_DISPLAY_NAME | GTK_FILE_FILTER_MIME_TYPE; 6870- filter_info.contains = GTK_FILE_FILTER_DISPLAY_NAME | GTK_FILE_FILTER_MIME_TYPE;
10622- needed = gtk_file_filter_get_needed (impl->current_filter); 6871- needed = gtk_file_filter_get_needed (impl->current_filter);
10623- 6872-
10624- filter_info.display_name = display_name; 6873- filter_info.display_name = display_name;
10625- filter_info.mime_type = mime_type; 6874- filter_info.mime_type = mime_type;
10626+ if (!parent_path) 6875-
10627+ return _gtk_file_chooser_set_current_folder_path (chooser, path, error);
10628
10629- if (needed & GTK_FILE_FILTER_FILENAME) 6876- if (needed & GTK_FILE_FILTER_FILENAME)
10630+ if (impl->load_state == LOAD_EMPTY) 6877- {
10631+ same_path = FALSE;
10632+ else
10633 {
10634- filter_info.filename = gtk_file_system_path_to_filename (impl->file_system, path); 6878- filter_info.filename = gtk_file_system_path_to_filename (impl->file_system, path);
10635- if (filter_info.filename) 6879- if (filter_info.filename)
10636- filter_info.contains |= GTK_FILE_FILTER_FILENAME; 6880- filter_info.contains |= GTK_FILE_FILTER_FILENAME;
10637+ g_assert (impl->current_folder != NULL); 6881- }
10638+
10639+ same_path = gtk_file_path_compare (parent_path, impl->current_folder) == 0;
10640 }
10641- else 6882- else
10642- filter_info.filename = NULL; 6883- filter_info.filename = NULL;
10643 6884-
10644- if (needed & GTK_FILE_FILTER_URI) 6885- if (needed & GTK_FILE_FILTER_URI)
10645+ if (same_path && impl->load_state == LOAD_FINISHED) 6886- {
10646 {
10647- filter_info.uri = gtk_file_system_path_to_uri (impl->file_system, path); 6887- filter_info.uri = gtk_file_system_path_to_uri (impl->file_system, path);
10648- if (filter_info.uri) 6888- if (filter_info.uri)
10649- filter_info.contains |= GTK_FILE_FILTER_URI; 6889- filter_info.contains |= GTK_FILE_FILTER_URI;
10650+ gboolean result; 6890- }
10651+ GSList paths;
10652+
10653+ paths.data = (gpointer) path;
10654+ paths.next = NULL;
10655+
10656+ result = show_and_select_paths (impl, parent_path, &paths, error);
10657+ gtk_file_path_free (parent_path);
10658+ return result;
10659 }
10660- else 6891- else
10661- filter_info.uri = NULL; 6892- filter_info.uri = NULL;
10662 6893-
10663- result = gtk_file_filter_filter (impl->current_filter, &filter_info); 6894- result = gtk_file_filter_filter (impl->current_filter, &filter_info);
10664+ pending_select_paths_add (impl, path); 6895-
10665
10666- if (filter_info.filename) 6896- if (filter_info.filename)
10667- g_free ((gchar *) filter_info.filename); 6897- g_free ((gchar *) filter_info.filename);
10668- if (filter_info.uri) 6898- if (filter_info.uri)
10669- g_free ((gchar *) filter_info.uri); 6899- g_free ((gchar *) filter_info.uri);
10670+ if (!same_path) 6900-
10671+ {
10672+ gboolean result;
10673
10674- return !result; 6901- return !result;
10675+ result = _gtk_file_chooser_set_current_folder_path (chooser, parent_path, error); 6902-
10676+ gtk_file_path_free (parent_path); 6903-}
10677+ return result; 6904-
10678+ }
10679
10680+ gtk_file_path_free (parent_path);
10681+ return TRUE;
10682 }
10683
10684-/* Visibility function for the recent filter model */ 6905-/* Visibility function for the recent filter model */
10685-static gboolean 6906-static gboolean
10686-search_model_visible_func (GtkTreeModel *model, 6907-search_model_visible_func (GtkTreeModel *model,
10687- GtkTreeIter *iter, 6908- GtkTreeIter *iter,
10688- gpointer user_data) 6909- gpointer user_data)
10689+static void 6910-{
10690+unselect_func (GtkFileSystemModel *model, 6911- GtkFileChooserDefault *impl = user_data;
10691+ GtkTreePath *path,
10692+ GtkTreeIter *iter,
10693+ gpointer user_data)
10694 {
10695 GtkFileChooserDefault *impl = user_data;
10696- GtkFilePath *file_path; 6912- GtkFilePath *file_path;
10697- gchar *display_name, *mime_type; 6913- gchar *display_name, *mime_type;
10698- gboolean is_folder; 6914- gboolean is_folder;
10699- 6915-
10700- if (!impl->current_filter) 6916- if (!impl->current_filter)
10701- return TRUE; 6917- return TRUE;
10702+ GtkTreeView *tree_view = GTK_TREE_VIEW (impl->browse_files_tree_view); 6918-
10703+ GtkTreePath *sorted_path;
10704
10705- gtk_tree_model_get (model, iter, 6919- gtk_tree_model_get (model, iter,
10706- SEARCH_MODEL_COL_PATH, &file_path, 6920- SEARCH_MODEL_COL_PATH, &file_path,
10707- SEARCH_MODEL_COL_IS_FOLDER, &is_folder, 6921- SEARCH_MODEL_COL_IS_FOLDER, &is_folder,
10708- SEARCH_MODEL_COL_DISPLAY_NAME, &display_name, 6922- SEARCH_MODEL_COL_DISPLAY_NAME, &display_name,
10709- SEARCH_MODEL_COL_MIME_TYPE, &mime_type, 6923- SEARCH_MODEL_COL_MIME_TYPE, &mime_type,
10710- -1); 6924- -1);
10711+ sorted_path = gtk_tree_model_sort_convert_child_path_to_path (impl->sort_model, 6925-
10712+ path);
10713+ gtk_tree_selection_unselect_path (gtk_tree_view_get_selection (tree_view),
10714+ sorted_path);
10715+ gtk_tree_path_free (sorted_path);
10716+}
10717
10718- if (!display_name) 6926- if (!display_name)
10719- return TRUE; 6927- return TRUE;
10720+static void 6928-
10721+gtk_file_chooser_default_unselect_path (GtkFileChooser *chooser,
10722+ const GtkFilePath *path)
10723+{
10724+ GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (chooser);
10725
10726- if (is_folder) 6929- if (is_folder)
10727- return TRUE; 6930- return TRUE;
10728+ if (!impl->browse_files_model) 6931-
10729+ return;
10730
10731- return !search_get_is_filtered (impl, file_path, display_name, mime_type); 6932- return !search_get_is_filtered (impl, file_path, display_name, mime_type);
10732+ _gtk_file_system_model_path_do (impl->browse_files_model, path, 6933-}
10733+ unselect_func, impl); 6934-
10734 }
10735
10736-/* Creates the search_model and puts it in the tree view */ 6935-/* Creates the search_model and puts it in the tree view */
10737-static void 6936-static void
10738-search_setup_model (GtkFileChooserDefault *impl) 6937-search_setup_model (GtkFileChooserDefault *impl)
10739+static gboolean 6938-{
10740+maybe_select (GtkTreeModel *model,
10741+ GtkTreePath *path,
10742+ GtkTreeIter *iter,
10743+ gpointer data)
10744 {
10745- g_assert (impl->search_model == NULL); 6939- g_assert (impl->search_model == NULL);
10746- g_assert (impl->search_model_filter == NULL); 6940- g_assert (impl->search_model_filter == NULL);
10747- g_assert (impl->search_model_sort == NULL); 6941- g_assert (impl->search_model_sort == NULL);
@@ -10772,11 +6966,7 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
10772- GDK_TYPE_PIXBUF, 6966- GDK_TYPE_PIXBUF,
10773- G_TYPE_POINTER, 6967- G_TYPE_POINTER,
10774- G_TYPE_BOOLEAN); 6968- G_TYPE_BOOLEAN);
10775+ GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (data); 6969-
10776+ GtkTreeSelection *selection;
10777+ const GtkFileInfo *info;
10778+ gboolean is_folder;
10779
10780- impl->search_model_filter = 6970- impl->search_model_filter =
10781- GTK_TREE_MODEL_FILTER (gtk_tree_model_filter_new (GTK_TREE_MODEL (impl->search_model), NULL)); 6971- GTK_TREE_MODEL_FILTER (gtk_tree_model_filter_new (GTK_TREE_MODEL (impl->search_model), NULL));
10782- gtk_tree_model_filter_set_visible_func (impl->search_model_filter, 6972- gtk_tree_model_filter_set_visible_func (impl->search_model_filter,
@@ -10803,44 +6993,21 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
10803- */ 6993- */
10804- gtk_tree_view_set_model (GTK_TREE_VIEW (impl->browse_files_tree_view), 6994- gtk_tree_view_set_model (GTK_TREE_VIEW (impl->browse_files_tree_view),
10805- GTK_TREE_MODEL (impl->search_model_sort)); 6995- GTK_TREE_MODEL (impl->search_model_sort));
10806+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_files_tree_view)); 6996-}
10807+ 6997-
10808+ info = get_list_file_info (impl, iter); 6998-static void
10809+ is_folder = gtk_file_info_get_is_folder (info);
10810+
10811+ if ((is_folder && impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER) ||
10812+ (!is_folder && impl->action == GTK_FILE_CHOOSER_ACTION_OPEN))
10813+ gtk_tree_selection_select_iter (selection, iter);
10814+ else
10815+ gtk_tree_selection_unselect_iter (selection, iter);
10816+
10817+ return FALSE;
10818 }
10819
10820 static void
10821-search_get_valid_child_iter (GtkFileChooserDefault *impl, 6999-search_get_valid_child_iter (GtkFileChooserDefault *impl,
10822- GtkTreeIter *child_iter, 7000- GtkTreeIter *child_iter,
10823- GtkTreeIter *iter) 7001- GtkTreeIter *iter)
10824+gtk_file_chooser_default_select_all (GtkFileChooser *chooser) 7002-{
10825 {
10826- GtkTreeIter middle; 7003- GtkTreeIter middle;
10827- 7004-
10828- if (!impl->search_model) 7005- if (!impl->search_model)
10829- return; 7006- return;
10830+ GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (chooser); 7007-
10831+ if (impl->select_multiple)
10832+ gtk_tree_model_foreach (GTK_TREE_MODEL (impl->sort_model),
10833+ maybe_select, impl);
10834+}
10835
10836- if (!impl->search_model_filter || !impl->search_model_sort) 7008- if (!impl->search_model_filter || !impl->search_model_sort)
10837- return; 7009- return;
10838+static void 7010-
10839+gtk_file_chooser_default_unselect_all (GtkFileChooser *chooser)
10840+{
10841+ GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (chooser);
10842+ GtkTreeSelection *selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_files_tree_view));
10843
10844- /* pass 1: get the iterator in the filter model */ 7011- /* pass 1: get the iterator in the filter model */
10845- gtk_tree_model_sort_convert_iter_to_child_iter (impl->search_model_sort, 7012- gtk_tree_model_sort_convert_iter_to_child_iter (impl->search_model_sort,
10846- &middle, iter); 7013- &middle, iter);
@@ -10848,98 +7015,46 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
10848- /* pass 2: get the iterator in the real model */ 7015- /* pass 2: get the iterator in the real model */
10849- gtk_tree_model_filter_convert_iter_to_child_iter (impl->search_model_filter, 7016- gtk_tree_model_filter_convert_iter_to_child_iter (impl->search_model_filter,
10850- child_iter, &middle); 7017- child_iter, &middle);
10851+ gtk_tree_selection_unselect_all (selection); 7018-}
10852+ pending_select_paths_free (impl); 7019-
10853 }
10854
10855-/* Creates a new query with the specified text and launches it */ 7020-/* Creates a new query with the specified text and launches it */
10856+/* Checks whether the filename entry for the Save modes contains a well-formed filename. 7021-static void
10857+ *
10858+ * is_well_formed_ret - whether what the user typed passes gkt_file_system_make_path()
10859+ *
10860+ * is_empty_ret - whether the file entry is totally empty
10861+ *
10862+ * is_file_part_empty_ret - whether the file part is empty (will be if user types "foobar/", and
10863+ * the path will be "$cwd/foobar")
10864+ */
10865 static void
10866-search_start_query (GtkFileChooserDefault *impl, 7022-search_start_query (GtkFileChooserDefault *impl,
10867- const gchar *query_text) 7023- const gchar *query_text)
10868+check_save_entry (GtkFileChooserDefault *impl, 7024-{
10869+ GtkFilePath **path_ret,
10870+ gboolean *is_well_formed_ret,
10871+ gboolean *is_empty_ret,
10872+ gboolean *is_file_part_empty_ret,
10873+ gboolean *is_folder)
10874 {
10875- search_stop_searching (impl, FALSE); 7025- search_stop_searching (impl, FALSE);
10876- search_clear_model (impl, TRUE); 7026- search_clear_model (impl, TRUE);
10877- search_setup_model (impl); 7027- search_setup_model (impl);
10878- set_busy_cursor (impl, TRUE); 7028- set_busy_cursor (impl, TRUE);
10879+ GtkFileChooserEntry *chooser_entry; 7029-
10880+ const GtkFilePath *current_folder;
10881+ const char *file_part;
10882+ GtkFilePath *path;
10883+ GError *error;
10884
10885- if (impl->search_engine == NULL) 7030- if (impl->search_engine == NULL)
10886- impl->search_engine = _gtk_search_engine_new (); 7031- impl->search_engine = _gtk_search_engine_new ();
10887+ g_assert (impl->action == GTK_FILE_CHOOSER_ACTION_SAVE 7032-
10888+ || impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER
10889+ || impl->action == GTK_FILE_CHOOSER_ACTION_OPEN
10890+ || impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER);
10891+
10892+ chooser_entry = GTK_FILE_CHOOSER_ENTRY (impl->location_entry);
10893
10894- if (!impl->search_engine) 7033- if (!impl->search_engine)
10895+ if (strlen (gtk_entry_get_text (GTK_ENTRY (chooser_entry))) == 0) 7034- {
10896 {
10897- set_busy_cursor (impl, FALSE); 7035- set_busy_cursor (impl, FALSE);
10898- search_error_could_not_create_client (impl); /* lame; we don't get an error code or anything */ 7036- search_error_could_not_create_client (impl); /* lame; we don't get an error code or anything */
10899+ *path_ret = NULL; 7037- return;
10900+ *is_well_formed_ret = TRUE; 7038- }
10901+ *is_empty_ret = TRUE; 7039-
10902+ *is_file_part_empty_ret = TRUE;
10903+ *is_folder = FALSE;
10904+
10905 return;
10906 }
10907
10908- if (!impl->search_query) 7040- if (!impl->search_query)
10909+ *is_empty_ret = FALSE; 7041- {
10910+
10911+ current_folder = _gtk_file_chooser_entry_get_current_folder (chooser_entry);
10912+ if (!current_folder)
10913 {
10914- impl->search_query = _gtk_query_new (); 7042- impl->search_query = _gtk_query_new ();
10915- _gtk_query_set_text (impl->search_query, query_text); 7043- _gtk_query_set_text (impl->search_query, query_text);
10916+ *path_ret = NULL; 7044- }
10917+ *is_well_formed_ret = FALSE;
10918+ *is_file_part_empty_ret = FALSE;
10919+ *is_folder = FALSE;
10920+
10921+ return;
10922 }
10923- 7045-
10924- _gtk_search_engine_set_query (impl->search_engine, impl->search_query); 7046- _gtk_search_engine_set_query (impl->search_engine, impl->search_query);
10925 7047-
10926- g_signal_connect (impl->search_engine, "hits-added", 7048- g_signal_connect (impl->search_engine, "hits-added",
10927- G_CALLBACK (search_engine_hits_added_cb), impl); 7049- G_CALLBACK (search_engine_hits_added_cb), impl);
10928- g_signal_connect (impl->search_engine, "finished", 7050- g_signal_connect (impl->search_engine, "finished",
10929- G_CALLBACK (search_engine_finished_cb), impl); 7051- G_CALLBACK (search_engine_finished_cb), impl);
10930- g_signal_connect (impl->search_engine, "error", 7052- g_signal_connect (impl->search_engine, "error",
10931- G_CALLBACK (search_engine_error_cb), impl); 7053- G_CALLBACK (search_engine_error_cb), impl);
10932+ file_part = _gtk_file_chooser_entry_get_file_part (chooser_entry); 7054-
10933
10934- _gtk_search_engine_start (impl->search_engine); 7055- _gtk_search_engine_start (impl->search_engine);
10935-} 7056-}
10936+ if (!file_part || file_part[0] == '\0') 7057-
10937+ {
10938+ *path_ret = gtk_file_path_copy (current_folder);
10939+ *is_well_formed_ret = TRUE;
10940+ *is_file_part_empty_ret = TRUE;
10941+ *is_folder = TRUE;
10942
10943-/* Callback used when the user presses Enter while typing on the search 7058-/* Callback used when the user presses Enter while typing on the search
10944- * entry; starts the query 7059- * entry; starts the query
10945- */ 7060- */
@@ -10949,113 +7064,55 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
10949-{ 7064-{
10950- GtkFileChooserDefault *impl; 7065- GtkFileChooserDefault *impl;
10951- const char *text; 7066- const char *text;
10952+ return; 7067-
10953+ }
10954
10955- impl = GTK_FILE_CHOOSER_DEFAULT (data); 7068- impl = GTK_FILE_CHOOSER_DEFAULT (data);
10956+ *is_file_part_empty_ret = FALSE; 7069-
10957
10958- text = gtk_entry_get_text (GTK_ENTRY (impl->search_entry)); 7070- text = gtk_entry_get_text (GTK_ENTRY (impl->search_entry));
10959- if (strlen (text) == 0) 7071- if (strlen (text) == 0)
10960- return; 7072- return;
10961+ error = NULL; 7073-
10962+ path = gtk_file_system_make_path (impl->file_system, current_folder, file_part, &error);
10963
10964- /* reset any existing query object */ 7074- /* reset any existing query object */
10965- if (impl->search_query) 7075- if (impl->search_query)
10966+ if (!path) 7076- {
10967 {
10968- g_object_unref (impl->search_query); 7077- g_object_unref (impl->search_query);
10969- impl->search_query = NULL; 7078- impl->search_query = NULL;
10970+ error_building_filename_dialog (impl, current_folder, file_part, error); 7079- }
10971+ *path_ret = NULL; 7080-
10972+ *is_well_formed_ret = FALSE;
10973+ *is_folder = FALSE;
10974+
10975+ return;
10976 }
10977
10978- search_start_query (impl, text); 7081- search_start_query (impl, text);
10979+ *path_ret = path; 7082-}
10980+ *is_well_formed_ret = TRUE; 7083-
10981+ *is_folder = _gtk_file_chooser_entry_get_is_folder (chooser_entry, path);
10982 }
10983
10984-/* Hides the path bar and creates the search entry */ 7084-/* Hides the path bar and creates the search entry */
10985+struct get_paths_closure { 7085-static void
10986+ GtkFileChooserDefault *impl;
10987+ GSList *result;
10988+ GtkFilePath *path_from_entry;
10989+};
10990+
10991 static void
10992-search_setup_widgets (GtkFileChooserDefault *impl) 7086-search_setup_widgets (GtkFileChooserDefault *impl)
10993+get_paths_foreach (GtkTreeModel *model, 7087-{
10994+ GtkTreePath *path,
10995+ GtkTreeIter *iter,
10996+ gpointer data)
10997 {
10998- GtkWidget *label; 7088- GtkWidget *label;
10999+ struct get_paths_closure *info; 7089-
11000+ const GtkFilePath *file_path;
11001+ GtkFileSystemModel *fs_model;
11002+ GtkTreeIter sel_iter;
11003+
11004+ info = data;
11005+ fs_model = info->impl->browse_files_model;
11006+ gtk_tree_model_sort_convert_iter_to_child_iter (info->impl->sort_model, &sel_iter, iter);
11007
11008- impl->search_hbox = gtk_hbox_new (FALSE, 12); 7090- impl->search_hbox = gtk_hbox_new (FALSE, 12);
11009+ file_path = _gtk_file_system_model_get_path (fs_model, &sel_iter); 7091-
11010+ if (!file_path)
11011+ return; /* We are on the editable row */
11012
11013- /* Label */ 7092- /* Label */
11014+ if (!info->path_from_entry 7093-
11015+ || gtk_file_path_compare (info->path_from_entry, file_path) != 0)
11016+ info->result = g_slist_prepend (info->result, gtk_file_path_copy (file_path));
11017+}
11018
11019- label = gtk_label_new_with_mnemonic (_("_Search:")); 7094- label = gtk_label_new_with_mnemonic (_("_Search:"));
11020- gtk_box_pack_start (GTK_BOX (impl->search_hbox), label, FALSE, FALSE, 0); 7095- gtk_box_pack_start (GTK_BOX (impl->search_hbox), label, FALSE, FALSE, 0);
11021+static GSList * 7096-
11022+gtk_file_chooser_default_get_paths (GtkFileChooser *chooser)
11023+{
11024+ GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (chooser);
11025+ struct get_paths_closure info;
11026+ GtkWindow *toplevel;
11027+ GtkWidget *current_focus;
11028
11029- /* Entry */ 7097- /* Entry */
11030+ info.impl = impl; 7098-
11031+ info.result = NULL;
11032+ info.path_from_entry = NULL;
11033
11034- impl->search_entry = gtk_entry_new (); 7099- impl->search_entry = gtk_entry_new ();
11035- gtk_label_set_mnemonic_widget (GTK_LABEL (label), impl->search_entry); 7100- gtk_label_set_mnemonic_widget (GTK_LABEL (label), impl->search_entry);
11036- g_signal_connect (impl->search_entry, "activate", 7101- g_signal_connect (impl->search_entry, "activate",
11037- G_CALLBACK (search_entry_activate_cb), 7102- G_CALLBACK (search_entry_activate_cb),
11038- impl); 7103- impl);
11039- gtk_box_pack_start (GTK_BOX (impl->search_hbox), impl->search_entry, TRUE, TRUE, 0); 7104- gtk_box_pack_start (GTK_BOX (impl->search_hbox), impl->search_entry, TRUE, TRUE, 0);
11040+ toplevel = get_toplevel (GTK_WIDGET (impl)); 7105-
11041+ if (toplevel)
11042+ current_focus = gtk_window_get_focus (toplevel);
11043+ else
11044+ current_focus = NULL;
11045
11046- /* if there already is a query, restart it */ 7106- /* if there already is a query, restart it */
11047- if (impl->search_query) 7107- if (impl->search_query)
11048+ if (current_focus == impl->browse_files_tree_view) 7108- {
11049 {
11050- gchar *query = _gtk_query_get_text (impl->search_query); 7109- gchar *query = _gtk_query_get_text (impl->search_query);
11051+ GtkTreeSelection *selection; 7110-
11052
11053- if (query) 7111- if (query)
11054- { 7112- {
11055- gtk_entry_set_text (GTK_ENTRY (impl->search_entry), query); 7113- gtk_entry_set_text (GTK_ENTRY (impl->search_entry), query);
11056- search_start_query (impl, query); 7114- search_start_query (impl, query);
11057+ file_list: 7115-
11058
11059- g_free (query); 7116- g_free (query);
11060- } 7117- }
11061- else 7118- else
@@ -11063,124 +7120,43 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
11063- g_object_unref (impl->search_query); 7120- g_object_unref (impl->search_query);
11064- impl->search_query = NULL; 7121- impl->search_query = NULL;
11065- } 7122- }
11066+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_files_tree_view)); 7123- }
11067+ gtk_tree_selection_selected_foreach (selection, get_paths_foreach, &info); 7124-
11068+
11069+ /* If there is no selection in the file list, we probably have this situation:
11070+ *
11071+ * 1. The user typed a filename in the SAVE filename entry ("foo.txt").
11072+ * 2. He then double-clicked on a folder ("bar") in the file list
11073+ *
11074+ * So we want the selection to be "bar/foo.txt". Jump to the case for the
11075+ * filename entry to see if that is the case.
11076+ */
11077+ if (info.result == NULL && impl->location_entry)
11078+ goto file_entry;
11079 }
11080+ else if (impl->location_entry && current_focus == impl->location_entry)
11081+ {
11082+ gboolean is_well_formed, is_empty, is_file_part_empty, is_folder;
11083+
11084+ file_entry:
11085+
11086+ check_save_entry (impl, &info.path_from_entry, &is_well_formed, &is_empty, &is_file_part_empty, &is_folder);
11087+
11088+ if (is_empty)
11089+ goto out;
11090
11091- gtk_widget_hide (impl->browse_path_bar); 7125- gtk_widget_hide (impl->browse_path_bar);
11092- gtk_widget_hide (impl->browse_new_folder_button); 7126- gtk_widget_hide (impl->browse_new_folder_button);
11093+ if (!is_well_formed) 7127-
11094+ return NULL;
11095+
11096+ if (is_file_part_empty && impl->action == GTK_FILE_CHOOSER_ACTION_SAVE)
11097+ {
11098+ gtk_file_path_free (info.path_from_entry);
11099+ return NULL;
11100+ }
11101
11102- /* Box for search widgets */ 7128- /* Box for search widgets */
11103- gtk_box_pack_start (GTK_BOX (impl->browse_path_bar_hbox), impl->search_hbox, TRUE, TRUE, 0); 7129- gtk_box_pack_start (GTK_BOX (impl->browse_path_bar_hbox), impl->search_hbox, TRUE, TRUE, 0);
11104- gtk_widget_show_all (impl->search_hbox); 7130- gtk_widget_show_all (impl->search_hbox);
11105+ g_assert (info.path_from_entry != NULL); 7131-
11106+ info.result = g_slist_prepend (info.result, info.path_from_entry);
11107+ }
11108+ else if (impl->toplevel_last_focus_widget == impl->browse_files_tree_view)
11109+ goto file_list;
11110+ else if (impl->location_entry && impl->toplevel_last_focus_widget == impl->location_entry)
11111+ goto file_entry;
11112+ else
11113+ {
11114+ /* The focus is on a dialog's action area button or something else */
11115+ if (impl->action == GTK_FILE_CHOOSER_ACTION_SAVE
11116+ || impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)
11117+ goto file_entry;
11118+ else
11119+ goto file_list;
11120+ }
11121
11122- /* Hide the location widgets temporarily */ 7132- /* Hide the location widgets temporarily */
11123+ out: 7133-
11124
11125- if (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN || 7134- if (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN ||
11126- impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER) 7135- impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER)
11127+ /* If there's no folder selected, and we're in SELECT_FOLDER mode, then we 7136- {
11128+ * fall back to the current directory */
11129+ if (impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER &&
11130+ info.result == NULL)
11131 {
11132- gtk_widget_hide (impl->location_button); 7137- gtk_widget_hide (impl->location_button);
11133- gtk_widget_hide (impl->location_entry_box); 7138- gtk_widget_hide (impl->location_entry_box);
11134+ info.result = g_slist_prepend (info.result, _gtk_file_chooser_get_current_folder_path (chooser)); 7139- }
11135 } 7140-
11136
11137- gtk_widget_grab_focus (impl->search_entry); 7141- gtk_widget_grab_focus (impl->search_entry);
11138+ return g_slist_reverse (info.result); 7142-
11139+}
11140+
11141+static GtkFileSystem *
11142+gtk_file_chooser_default_get_file_system (GtkFileChooser *chooser)
11143+{
11144+ GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (chooser);
11145
11146- /* FMQ: hide the filter combo? */ 7143- /* FMQ: hide the filter combo? */
11147+ return impl->file_system; 7144-}
11148 } 7145-
11149
11150-/* Main entry point to the searching functions; this gets called when the user 7146-/* Main entry point to the searching functions; this gets called when the user
11151- * activates the Search shortcut. 7147- * activates the Search shortcut.
11152- */ 7148- */
11153+/* Shows or hides the filter widgets */ 7149-static void
11154 static void
11155-search_activate (GtkFileChooserDefault *impl) 7150-search_activate (GtkFileChooserDefault *impl)
11156+show_filters (GtkFileChooserDefault *impl, 7151-{
11157+ gboolean show)
11158 {
11159- OperationMode previous_mode; 7152- OperationMode previous_mode;
11160- 7153-
11161- if (impl->operation_mode == OPERATION_MODE_SEARCH) 7154- if (impl->operation_mode == OPERATION_MODE_SEARCH)
11162+ if (show) 7155- {
11163+ gtk_widget_show (impl->filter_combo);
11164+ else
11165+ gtk_widget_hide (impl->filter_combo);
11166+}
11167+
11168+static void
11169+gtk_file_chooser_default_add_filter (GtkFileChooser *chooser,
11170+ GtkFileFilter *filter)
11171+{
11172+ GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (chooser);
11173+ const gchar *name;
11174+
11175+ g_debug ("adding filter");
11176+
11177+ if (g_slist_find (impl->filters, filter))
11178 {
11179- gtk_widget_grab_focus (impl->search_entry); 7156- gtk_widget_grab_focus (impl->search_entry);
11180+ g_warning ("gtk_file_chooser_add_filter() called on filter already in list\n"); 7157- return;
11181 return; 7158- }
11182 } 7159-
11183
11184- previous_mode = impl->operation_mode; 7160- previous_mode = impl->operation_mode;
11185- impl->operation_mode = OPERATION_MODE_SEARCH; 7161- impl->operation_mode = OPERATION_MODE_SEARCH;
11186- 7162-
@@ -11190,50 +7166,37 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
11190- recent_stop_loading (impl); 7166- recent_stop_loading (impl);
11191- recent_clear_model (impl, TRUE); 7167- recent_clear_model (impl, TRUE);
11192- break; 7168- break;
11193+ g_object_ref_sink (filter); 7169-
11194+ impl->filters = g_slist_append (impl->filters, filter);
11195
11196- case OPERATION_MODE_BROWSE: 7170- case OPERATION_MODE_BROWSE:
11197- stop_loading_and_clear_list_model (impl); 7171- stop_loading_and_clear_list_model (impl);
11198- break; 7172- break;
11199+ name = gtk_file_filter_get_name (filter); 7173-
11200+ if (!name)
11201+ name = "Untitled filter"; /* Place-holder, doesn't need to be marked for translation */
11202
11203- case OPERATION_MODE_SEARCH: 7174- case OPERATION_MODE_SEARCH:
11204- g_assert_not_reached (); 7175- g_assert_not_reached ();
11205- break; 7176- break;
11206- } 7177- }
11207+ gtk_combo_box_append_text (GTK_COMBO_BOX (impl->filter_combo), name); 7178-
11208
11209- g_assert (impl->search_hbox == NULL); 7179- g_assert (impl->search_hbox == NULL);
11210- g_assert (impl->search_entry == NULL); 7180- g_assert (impl->search_entry == NULL);
11211- g_assert (impl->search_model == NULL); 7181- g_assert (impl->search_model == NULL);
11212- g_assert (impl->search_model_filter == NULL); 7182- g_assert (impl->search_model_filter == NULL);
11213+ if (!g_slist_find (impl->filters, impl->current_filter)) 7183-
11214+ set_current_filter (impl, filter);
11215
11216- search_setup_widgets (impl); 7184- search_setup_widgets (impl);
11217- file_list_set_sort_column_ids (impl); 7185- file_list_set_sort_column_ids (impl);
11218+ show_filters (impl, g_slist_length (impl->filters) > 1); 7186-}
11219 } 7187-
11220
11221-/* 7188-/*
11222- * Recent files support 7189- * Recent files support
11223- */ 7190- */
11224- 7191-
11225-/* Frees the data in the recent_model */ 7192-/* Frees the data in the recent_model */
11226 static void 7193-static void
11227-recent_clear_model (GtkFileChooserDefault *impl, 7194-recent_clear_model (GtkFileChooserDefault *impl,
11228- gboolean remove_from_treeview) 7195- gboolean remove_from_treeview)
11229+gtk_file_chooser_default_remove_filter (GtkFileChooser *chooser, 7196-{
11230+ GtkFileFilter *filter) 7197- GtkTreeModel *model;
11231 { 7198- GtkTreeIter iter;
11232+ GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (chooser); 7199-
11233 GtkTreeModel *model;
11234 GtkTreeIter iter;
11235+ gint filter_index;
11236
11237- if (!impl->recent_model) 7200- if (!impl->recent_model)
11238- return; 7201- return;
11239- 7202-
@@ -11277,8 +7240,7 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
11277- g_object_unref (impl->recent_model_sort); 7240- g_object_unref (impl->recent_model_sort);
11278- impl->recent_model_sort = NULL; 7241- impl->recent_model_sort = NULL;
11279-} 7242-}
11280+ filter_index = g_slist_index (impl->filters, filter); 7243-
11281
11282-/* Stops any ongoing loading of the recent files list; does 7244-/* Stops any ongoing loading of the recent files list; does
11283- * not touch the recent_model 7245- * not touch the recent_model
11284- */ 7246- */
@@ -11286,13 +7248,10 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
11286-recent_stop_loading (GtkFileChooserDefault *impl) 7248-recent_stop_loading (GtkFileChooserDefault *impl)
11287-{ 7249-{
11288- if (impl->load_recent_id) 7250- if (impl->load_recent_id)
11289+ if (filter_index < 0) 7251- {
11290 {
11291- g_source_remove (impl->load_recent_id); 7252- g_source_remove (impl->load_recent_id);
11292- impl->load_recent_id = 0; 7253- impl->load_recent_id = 0;
11293+ g_warning ("gtk_file_chooser_remove_filter() called on filter not in list\n"); 7254- }
11294+ return;
11295 }
11296-} 7255-}
11297- 7256-
11298-/* Stops any pending load, clears the file list, and switches 7257-/* Stops any pending load, clears the file list, and switches
@@ -11305,34 +7264,24 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
11305- 7264-
11306- recent_stop_loading (impl); 7265- recent_stop_loading (impl);
11307- recent_clear_model (impl, TRUE); 7266- recent_clear_model (impl, TRUE);
11308 7267-
11309- gtk_widget_show (impl->browse_path_bar); 7268- gtk_widget_show (impl->browse_path_bar);
11310- gtk_widget_show (impl->browse_new_folder_button); 7269- gtk_widget_show (impl->browse_new_folder_button);
11311+ impl->filters = g_slist_remove (impl->filters, filter); 7270-
11312
11313- if (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN || 7271- if (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN ||
11314- impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER) 7272- impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER)
11315+ if (filter == impl->current_filter) 7273- {
11316 {
11317- gtk_widget_show (impl->location_button); 7274- gtk_widget_show (impl->location_button);
11318- 7275-
11319- if (impl->location_mode == LOCATION_MODE_FILENAME_ENTRY) 7276- if (impl->location_mode == LOCATION_MODE_FILENAME_ENTRY)
11320- gtk_widget_show (impl->location_entry_box); 7277- gtk_widget_show (impl->location_entry_box);
11321+ if (impl->filters) 7278- }
11322+ set_current_filter (impl, impl->filters->data); 7279-
11323+ else
11324+ set_current_filter (impl, NULL);
11325 }
11326
11327- impl->operation_mode = OPERATION_MODE_BROWSE; 7280- impl->operation_mode = OPERATION_MODE_BROWSE;
11328- 7281-
11329- file_list_set_sort_column_ids (impl); 7282- file_list_set_sort_column_ids (impl);
11330-} 7283-}
11331+ /* Remove row from the combo box */ 7284-
11332+ model = gtk_combo_box_get_model (GTK_COMBO_BOX (impl->filter_combo));
11333+ if (!gtk_tree_model_iter_nth_child (model, &iter, NULL, filter_index))
11334+ g_assert_not_reached ();
11335
11336-/* Sort callback from the modification time column */ 7285-/* Sort callback from the modification time column */
11337-static gint 7286-static gint
11338-recent_column_mtime_sort_func (GtkTreeModel *model, 7287-recent_column_mtime_sort_func (GtkTreeModel *model,
@@ -11359,12 +7308,10 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
11359- 7308-
11360- if (!info_a) 7309- if (!info_a)
11361- return 1; 7310- return 1;
11362+ gtk_list_store_remove (GTK_LIST_STORE (model), &iter); 7311-
11363
11364- if (!info_b) 7312- if (!info_b)
11365- return -1; 7313- return -1;
11366+ g_object_unref (filter); 7314-
11367
11368- /* folders always go first */ 7315- /* folders always go first */
11369- if (is_folder_a != is_folder_b) 7316- if (is_folder_a != is_folder_b)
11370- return is_folder_a ? 1 : -1; 7317- return is_folder_a ? 1 : -1;
@@ -11375,17 +7322,14 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
11375- return 1; 7322- return 1;
11376- else 7323- else
11377- return 0; 7324- return 0;
11378+ show_filters (impl, g_slist_length (impl->filters) > 1); 7325-}
11379 } 7326-
11380
11381-static gint 7327-static gint
11382-recent_column_path_sort_func (GtkTreeModel *model, 7328-recent_column_path_sort_func (GtkTreeModel *model,
11383- GtkTreeIter *a, 7329- GtkTreeIter *a,
11384- GtkTreeIter *b, 7330- GtkTreeIter *b,
11385- gpointer user_data) 7331- gpointer user_data)
11386+static GSList * 7332-{
11387+gtk_file_chooser_default_list_filters (GtkFileChooser *chooser)
11388 {
11389- GtkFileChooserDefault *impl = user_data; 7333- GtkFileChooserDefault *impl = user_data;
11390- GtkTreeIter child_a, child_b; 7334- GtkTreeIter child_a, child_b;
11391- gboolean is_folder_a, is_folder_b; 7335- gboolean is_folder_a, is_folder_b;
@@ -11411,22 +7355,15 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
11411- 7355-
11412- if (is_folder_a != is_folder_b) 7356- if (is_folder_a != is_folder_b)
11413- return is_folder_a ? 1 : -1; 7357- return is_folder_a ? 1 : -1;
11414+ GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (chooser); 7358-
11415
11416- return strcmp (name_a, name_b); 7359- return strcmp (name_a, name_b);
11417+ return g_slist_copy (impl->filters); 7360-}
11418 } 7361-
11419
11420-static gboolean 7362-static gboolean
11421-recent_get_is_filtered (GtkFileChooserDefault *impl, 7363-recent_get_is_filtered (GtkFileChooserDefault *impl,
11422- const GtkFilePath *path, 7364- const GtkFilePath *path,
11423- GtkRecentInfo *recent_info) 7365- GtkRecentInfo *recent_info)
11424+/* Guesses a size based upon font sizes */ 7366-{
11425+static void
11426+find_good_size_from_style (GtkWidget *widget,
11427+ gint *width,
11428+ gint *height)
11429 {
11430- GtkFileFilterInfo filter_info; 7367- GtkFileFilterInfo filter_info;
11431- GtkFileFilterFlags needed; 7368- GtkFileFilterFlags needed;
11432- gboolean result; 7369- gboolean result;
@@ -11436,78 +7373,44 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
11436- 7373-
11437- filter_info.contains = GTK_FILE_FILTER_DISPLAY_NAME | GTK_FILE_FILTER_MIME_TYPE; 7374- filter_info.contains = GTK_FILE_FILTER_DISPLAY_NAME | GTK_FILE_FILTER_MIME_TYPE;
11438- needed = gtk_file_filter_get_needed (impl->current_filter); 7375- needed = gtk_file_filter_get_needed (impl->current_filter);
11439+ GtkFileChooserDefault *impl; 7376-
11440+ int font_size;
11441+ GdkScreen *screen;
11442+ double resolution;
11443
11444- filter_info.display_name = gtk_recent_info_get_display_name (recent_info); 7377- filter_info.display_name = gtk_recent_info_get_display_name (recent_info);
11445- filter_info.mime_type = gtk_recent_info_get_mime_type (recent_info); 7378- filter_info.mime_type = gtk_recent_info_get_mime_type (recent_info);
11446+ g_assert (widget->style != NULL); 7379-
11447+ impl = GTK_FILE_CHOOSER_DEFAULT (widget);
11448
11449- if (needed & GTK_FILE_FILTER_FILENAME) 7380- if (needed & GTK_FILE_FILTER_FILENAME)
11450+ if (impl->default_width == 0 && 7381- {
11451+ impl->default_height == 0)
11452 {
11453- filter_info.filename = gtk_file_system_path_to_filename (impl->file_system, path); 7382- filter_info.filename = gtk_file_system_path_to_filename (impl->file_system, path);
11454- if (filter_info.filename) 7383- if (filter_info.filename)
11455- filter_info.contains |= GTK_FILE_FILTER_FILENAME; 7384- filter_info.contains |= GTK_FILE_FILTER_FILENAME;
11456- } 7385- }
11457- else 7386- else
11458- filter_info.filename = NULL; 7387- filter_info.filename = NULL;
11459+ screen = gtk_widget_get_screen (widget); 7388-
11460+ if (screen)
11461+ {
11462+ resolution = gdk_screen_get_resolution (screen);
11463+ if (resolution < 0.0) /* will be -1 if the resolution is not defined in the GdkScreen */
11464+ resolution = 96.0;
11465+ }
11466+ else
11467+ resolution = 96.0; /* wheeee */
11468
11469- if (needed & GTK_FILE_FILTER_URI) 7389- if (needed & GTK_FILE_FILTER_URI)
11470- { 7390- {
11471- filter_info.uri = gtk_file_system_path_to_uri (impl->file_system, path); 7391- filter_info.uri = gtk_file_system_path_to_uri (impl->file_system, path);
11472- if (filter_info.uri) 7392- if (filter_info.uri)
11473- filter_info.contains |= GTK_FILE_FILTER_URI; 7393- filter_info.contains |= GTK_FILE_FILTER_URI;
11474+ font_size = pango_font_description_get_size (widget->style->font_desc); 7394- }
11475+ font_size = PANGO_PIXELS (font_size) * resolution / 72.0;
11476+
11477+ impl->default_width = font_size * NUM_CHARS;
11478+ impl->default_height = font_size * NUM_LINES;
11479 }
11480- else 7395- else
11481- filter_info.uri = NULL; 7396- filter_info.uri = NULL;
11482 7397-
11483- result = gtk_file_filter_filter (impl->current_filter, &filter_info); 7398- result = gtk_file_filter_filter (impl->current_filter, &filter_info);
11484+ *width = impl->default_width; 7399-
11485+ *height = impl->default_height;
11486+}
11487
11488- if (filter_info.filename) 7400- if (filter_info.filename)
11489- g_free ((gchar *) filter_info.filename); 7401- g_free ((gchar *) filter_info.filename);
11490- if (filter_info.uri) 7402- if (filter_info.uri)
11491- g_free ((gchar *) filter_info.uri); 7403- g_free ((gchar *) filter_info.uri);
11492+static void 7404-
11493+gtk_file_chooser_default_get_default_size (GtkFileChooserEmbed *chooser_embed,
11494+ gint *default_width,
11495+ gint *default_height)
11496+{
11497+ GtkFileChooserDefault *impl;
11498
11499- return !result; 7405- return !result;
11500+ impl = GTK_FILE_CHOOSER_DEFAULT (chooser_embed); 7406-}
11501+ find_good_size_from_style (GTK_WIDGET (chooser_embed), default_width, default_height); 7407-
11502 }
11503
11504-/* Visibility function for the recent filter model */ 7408-/* Visibility function for the recent filter model */
11505 static gboolean 7409-static gboolean
11506-recent_model_visible_func (GtkTreeModel *model, 7410-recent_model_visible_func (GtkTreeModel *model,
11507- GtkTreeIter *iter, 7411- GtkTreeIter *iter,
11508- gpointer user_data) 7412- gpointer user_data)
11509+gtk_file_chooser_default_get_resizable (GtkFileChooserEmbed *chooser_embed) 7413-{
11510 {
11511- GtkFileChooserDefault *impl = user_data; 7414- GtkFileChooserDefault *impl = user_data;
11512- GtkFilePath *file_path; 7415- GtkFilePath *file_path;
11513- GtkRecentInfo *recent_info; 7416- GtkRecentInfo *recent_info;
@@ -11527,12 +7430,10 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
11527- 7430-
11528- if (is_folder) 7431- if (is_folder)
11529- return TRUE; 7432- return TRUE;
11530+ GtkFileChooserDefault *impl; 7433-
11531
11532- return !recent_get_is_filtered (impl, file_path, recent_info); 7434- return !recent_get_is_filtered (impl, file_path, recent_info);
11533-} 7435-}
11534+ impl = GTK_FILE_CHOOSER_DEFAULT (chooser_embed); 7436-
11535
11536-static void 7437-static void
11537-recent_setup_model (GtkFileChooserDefault *impl) 7438-recent_setup_model (GtkFileChooserDefault *impl)
11538-{ 7439-{
@@ -11590,40 +7491,26 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
11590- gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (impl->recent_model_sort), 7491- gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (impl->recent_model_sort),
11591- RECENT_MODEL_COL_INFO, 7492- RECENT_MODEL_COL_INFO,
11592- GTK_SORT_DESCENDING); 7493- GTK_SORT_DESCENDING);
11593+ return (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN || 7494-}
11594+ impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER); 7495-
11595 }
11596
11597-typedef struct 7496-typedef struct
11598-{ 7497-{
11599+struct switch_folder_closure { 7498- GtkFileChooserDefault *impl;
11600 GtkFileChooserDefault *impl;
11601- GList *items; 7499- GList *items;
11602- gint n_items; 7500- gint n_items;
11603- gint n_loaded_items; 7501- gint n_loaded_items;
11604- guint needs_sorting : 1; 7502- guint needs_sorting : 1;
11605-} RecentLoadData; 7503-} RecentLoadData;
11606+ const GtkFilePath *path; 7504-
11607+ int num_selected; 7505-static void
11608+};
11609
11610+/* Used from gtk_tree_selection_selected_foreach() in switch_to_selected_folder() */
11611 static void
11612-recent_idle_cleanup (gpointer data) 7506-recent_idle_cleanup (gpointer data)
11613+switch_folder_foreach_cb (GtkTreeModel *model, 7507-{
11614+ GtkTreePath *path,
11615+ GtkTreeIter *iter,
11616+ gpointer data)
11617 {
11618- RecentLoadData *load_data = data; 7508- RecentLoadData *load_data = data;
11619- GtkFileChooserDefault *impl = load_data->impl; 7509- GtkFileChooserDefault *impl = load_data->impl;
11620+ struct switch_folder_closure *closure; 7510-
11621+ GtkTreeIter child_iter;
11622
11623- gtk_tree_view_set_model (GTK_TREE_VIEW (impl->browse_files_tree_view), 7511- gtk_tree_view_set_model (GTK_TREE_VIEW (impl->browse_files_tree_view),
11624- GTK_TREE_MODEL (impl->recent_model_sort)); 7512- GTK_TREE_MODEL (impl->recent_model_sort));
11625+ closure = data; 7513-
11626
11627- set_busy_cursor (impl, FALSE); 7514- set_busy_cursor (impl, FALSE);
11628- 7515-
11629- impl->load_recent_id = 0; 7516- impl->load_recent_id = 0;
@@ -11633,13 +7520,10 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
11633- g_list_foreach (load_data->items, (GFunc) gtk_recent_info_unref, NULL); 7520- g_list_foreach (load_data->items, (GFunc) gtk_recent_info_unref, NULL);
11634- g_list_free (load_data->items); 7521- g_list_free (load_data->items);
11635- } 7522- }
11636+ gtk_tree_model_sort_convert_iter_to_child_iter (closure->impl->sort_model, &child_iter, iter); 7523-
11637
11638- g_free (load_data); 7524- g_free (load_data);
11639+ closure->path = _gtk_file_system_model_get_path (closure->impl->browse_files_model, &child_iter); 7525-}
11640+ closure->num_selected++; 7526-
11641 }
11642
11643-struct RecentItemInsertRequest 7527-struct RecentItemInsertRequest
11644-{ 7528-{
11645- GtkFileChooserDefault *impl; 7529- GtkFileChooserDefault *impl;
@@ -11647,130 +7531,77 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
11647- GtkTreeRowReference *row_ref; 7531- GtkTreeRowReference *row_ref;
11648-}; 7532-};
11649- 7533-
11650+/* Changes to the selected folder in the list view */ 7534-static void
11651 static void
11652-recent_item_get_info_cb (GtkFileSystemHandle *handle, 7535-recent_item_get_info_cb (GtkFileSystemHandle *handle,
11653- const GtkFileInfo *info, 7536- const GtkFileInfo *info,
11654- const GError *error, 7537- const GError *error,
11655- gpointer data) 7538- gpointer data)
11656+switch_to_selected_folder (GtkFileChooserDefault *impl) 7539-{
11657 {
11658- gboolean cancelled = handle->cancelled; 7540- gboolean cancelled = handle->cancelled;
11659- GtkTreePath *path; 7541- GtkTreePath *path;
11660- GtkTreeIter iter; 7542- GtkTreeIter iter;
11661- GtkFileSystemHandle *model_handle; 7543- GtkFileSystemHandle *model_handle;
11662- gboolean is_folder = FALSE; 7544- gboolean is_folder = FALSE;
11663- struct RecentItemInsertRequest *request = data; 7545- struct RecentItemInsertRequest *request = data;
11664+ GtkTreeSelection *selection; 7546-
11665+ struct switch_folder_closure closure;
11666
11667- if (!request->impl->recent_model) 7547- if (!request->impl->recent_model)
11668- goto out; 7548- goto out;
11669+ /* We do this with foreach() rather than get_selected() as we may be in 7549-
11670+ * multiple selection mode
11671+ */
11672
11673- path = gtk_tree_row_reference_get_path (request->row_ref); 7550- path = gtk_tree_row_reference_get_path (request->row_ref);
11674- if (!path) 7551- if (!path)
11675- goto out; 7552- goto out;
11676+ closure.impl = impl; 7553-
11677+ closure.path = NULL;
11678+ closure.num_selected = 0;
11679
11680- gtk_tree_model_get_iter (GTK_TREE_MODEL (request->impl->recent_model), 7554- gtk_tree_model_get_iter (GTK_TREE_MODEL (request->impl->recent_model),
11681- &iter, path); 7555- &iter, path);
11682- gtk_tree_path_free (path); 7556- gtk_tree_path_free (path);
11683+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_files_tree_view)); 7557-
11684+ gtk_tree_selection_selected_foreach (selection, switch_folder_foreach_cb, &closure);
11685
11686- gtk_tree_model_get (GTK_TREE_MODEL (request->impl->recent_model), &iter, 7558- gtk_tree_model_get (GTK_TREE_MODEL (request->impl->recent_model), &iter,
11687- RECENT_MODEL_COL_HANDLE, &model_handle, 7559- RECENT_MODEL_COL_HANDLE, &model_handle,
11688- -1); 7560- -1);
11689- if (handle != model_handle) 7561- if (handle != model_handle)
11690- goto out; 7562- goto out;
11691+ g_assert (closure.path && closure.num_selected == 1); 7563-
11692
11693- gtk_list_store_set (request->impl->recent_model, &iter, 7564- gtk_list_store_set (request->impl->recent_model, &iter,
11694- RECENT_MODEL_COL_HANDLE, NULL, 7565- RECENT_MODEL_COL_HANDLE, NULL,
11695- -1); 7566- -1);
11696+ change_folder_and_display_error (impl, closure.path); 7567-
11697+}
11698
11699- if (cancelled) 7568- if (cancelled)
11700- goto out; 7569- goto out;
11701+/* Gets the GtkFileInfo for the selected row in the file list; assumes single 7570-
11702+ * selection mode.
11703+ */
11704+static const GtkFileInfo *
11705+get_selected_file_info_from_file_list (GtkFileChooserDefault *impl,
11706+ gboolean *had_selection)
11707+{
11708+ GtkTreeSelection *selection;
11709+ GtkTreeIter iter, child_iter;
11710+ const GtkFileInfo *info;
11711
11712- if (!info) 7571- if (!info)
11713+ g_assert (!impl->select_multiple); 7572- {
11714+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_files_tree_view));
11715+ if (!gtk_tree_selection_get_selected (selection, NULL, &iter))
11716 {
11717- gtk_list_store_remove (request->impl->recent_model, &iter); 7573- gtk_list_store_remove (request->impl->recent_model, &iter);
11718- goto out; 7574- goto out;
11719+ *had_selection = FALSE; 7575- }
11720+ return NULL; 7576-
11721 }
11722
11723- is_folder = gtk_file_info_get_is_folder (info); 7577- is_folder = gtk_file_info_get_is_folder (info);
11724- 7578-
11725- gtk_list_store_set (request->impl->recent_model, &iter, 7579- gtk_list_store_set (request->impl->recent_model, &iter,
11726- RECENT_MODEL_COL_IS_FOLDER, is_folder, 7580- RECENT_MODEL_COL_IS_FOLDER, is_folder,
11727- -1); 7581- -1);
11728+ *had_selection = TRUE; 7582-
11729
11730-out: 7583-out:
11731- g_object_unref (request->impl); 7584- g_object_unref (request->impl);
11732- gtk_file_path_free (request->path); 7585- gtk_file_path_free (request->path);
11733- gtk_tree_row_reference_free (request->row_ref); 7586- gtk_tree_row_reference_free (request->row_ref);
11734- g_free (request); 7587- g_free (request);
11735+ gtk_tree_model_sort_convert_iter_to_child_iter (impl->sort_model, 7588-
11736+ &child_iter,
11737+ &iter);
11738
11739- g_object_unref (handle); 7589- g_object_unref (handle);
11740+ info = _gtk_file_system_model_get_info (impl->browse_files_model, &child_iter); 7590-}
11741+ return info; 7591-
11742 }
11743
11744-static gint 7592-static gint
11745-recent_sort_mru (gconstpointer a, 7593-recent_sort_mru (gconstpointer a,
11746- gconstpointer b) 7594- gconstpointer b)
11747+/* Gets the display name of the selected file in the file list; assumes single 7595-{
11748+ * selection mode and that something is selected.
11749+ */
11750+static const gchar *
11751+get_display_name_from_file_list (GtkFileChooserDefault *impl)
11752 {
11753- GtkRecentInfo *info_a = (GtkRecentInfo *) a; 7596- GtkRecentInfo *info_a = (GtkRecentInfo *) a;
11754- GtkRecentInfo *info_b = (GtkRecentInfo *) b; 7597- GtkRecentInfo *info_b = (GtkRecentInfo *) b;
11755+ const GtkFileInfo *info; 7598-
11756+ gboolean had_selection; 7599- return (gtk_recent_info_get_modified (info_b) - gtk_recent_info_get_modified (info_a));
11757+ 7600-}
11758+ info = get_selected_file_info_from_file_list (impl, &had_selection); 7601-
11759+ g_assert (had_selection);
11760+ g_assert (info != NULL);
11761
11762- return (gtk_recent_info_get_modified (info_a) < gtk_recent_info_get_modified (info_b));
11763+ return gtk_file_info_get_display_name (info);
11764 }
11765
11766-static gint 7602-static gint
11767-get_recent_files_limit (GtkWidget *widget) 7603-get_recent_files_limit (GtkWidget *widget)
11768+static void 7604-{
11769+add_custom_button_to_dialog (GtkDialog *dialog,
11770+ const gchar *mnemonic_label,
11771+ const gchar *stock_id,
11772+ gint response_id)
11773 {
11774- GtkSettings *settings; 7605- GtkSettings *settings;
11775- gint limit; 7606- gint limit;
11776- 7607-
@@ -11778,28 +7609,15 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
11778- settings = gtk_settings_get_for_screen (gtk_widget_get_screen (widget)); 7609- settings = gtk_settings_get_for_screen (gtk_widget_get_screen (widget));
11779- else 7610- else
11780- settings = gtk_settings_get_default (); 7611- settings = gtk_settings_get_default ();
11781+ GtkWidget *button; 7612-
11782
11783- g_object_get (G_OBJECT (settings), "gtk-recent-files-limit", &limit, NULL); 7613- g_object_get (G_OBJECT (settings), "gtk-recent-files-limit", &limit, NULL);
11784+ button = gtk_button_new_with_mnemonic (mnemonic_label); 7614-
11785+ GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
11786+ gtk_button_set_image (GTK_BUTTON (button),
11787+ gtk_image_new_from_stock (stock_id, GTK_ICON_SIZE_BUTTON));
11788+ gtk_widget_show (button);
11789
11790- return limit; 7615- return limit;
11791+ gtk_dialog_add_action_widget (GTK_DIALOG (dialog), button, response_id); 7616-}
11792 } 7617-
11793 7618-static gboolean
11794+/* Presents an overwrite confirmation dialog; returns whether we should accept
11795+ * the filename.
11796+ */
11797 static gboolean
11798-recent_idle_load (gpointer data) 7619-recent_idle_load (gpointer data)
11799+confirm_dialog_should_accept_filename (GtkFileChooserDefault *impl, 7620-{
11800+ const gchar *file_part,
11801+ const gchar *folder_display_name)
11802 {
11803- RecentLoadData *load_data = data; 7621- RecentLoadData *load_data = data;
11804- GtkFileChooserDefault *impl = load_data->impl; 7622- GtkFileChooserDefault *impl = load_data->impl;
11805- GtkTreeIter iter; 7623- GtkTreeIter iter;
@@ -11812,36 +7630,19 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
11812- 7630-
11813- if (!impl->recent_manager) 7631- if (!impl->recent_manager)
11814- return FALSE; 7632- return FALSE;
11815+ GtkWindow *toplevel; 7633-
11816+ GtkWidget *dialog;
11817+ int response;
11818
11819- /* first iteration: load all the items */ 7634- /* first iteration: load all the items */
11820- if (!load_data->items) 7635- if (!load_data->items)
11821- { 7636- {
11822- load_data->items = gtk_recent_manager_get_items (impl->recent_manager); 7637- load_data->items = gtk_recent_manager_get_items (impl->recent_manager);
11823- if (!load_data->items) 7638- if (!load_data->items)
11824- return FALSE; 7639- return FALSE;
11825+ toplevel = get_toplevel (GTK_WIDGET (impl)); 7640-
11826
11827- load_data->needs_sorting = TRUE; 7641- load_data->needs_sorting = TRUE;
11828+ dialog = gtk_message_dialog_new (toplevel, 7642-
11829+ GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
11830+ GTK_MESSAGE_QUESTION,
11831+ GTK_BUTTONS_NONE,
11832+ _("A file named \"%s\" already exists. Do you want to replace it?"),
11833+ file_part);
11834+ gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
11835+ _("The file already exists in \"%s\". Replacing it will "
11836+ "overwrite its contents."),
11837+ folder_display_name);
11838
11839- return TRUE; 7643- return TRUE;
11840- } 7644- }
11841+ gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL); 7645-
11842+ add_custom_button_to_dialog (GTK_DIALOG (dialog), _("_Replace"), GTK_STOCK_SAVE_AS, GTK_RESPONSE_ACCEPT);
11843+ gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_ACCEPT);
11844
11845- /* second iteration: preliminary MRU sorting and clamping */ 7646- /* second iteration: preliminary MRU sorting and clamping */
11846- if (load_data->needs_sorting) 7647- if (load_data->needs_sorting)
11847- { 7648- {
@@ -11886,9 +7687,7 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
11886- 7687-
11887- gtk_list_store_append (impl->recent_model, &iter); 7688- gtk_list_store_append (impl->recent_model, &iter);
11888- p = gtk_tree_model_get_path (GTK_TREE_MODEL (impl->recent_model), &iter); 7689- p = gtk_tree_model_get_path (GTK_TREE_MODEL (impl->recent_model), &iter);
11889+ if (toplevel->group) 7690-
11890+ gtk_window_group_add_window (toplevel->group, GTK_WINDOW (dialog));
11891
11892- request = g_new0 (struct RecentItemInsertRequest, 1); 7691- request = g_new0 (struct RecentItemInsertRequest, 1);
11893- request->impl = g_object_ref (impl); 7692- request->impl = g_object_ref (impl);
11894- request->path = gtk_file_path_copy (path); 7693- request->path = gtk_file_path_copy (path);
@@ -11917,20 +7716,16 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
11917- g_list_foreach (load_data->items, (GFunc) gtk_recent_info_unref, NULL); 7716- g_list_foreach (load_data->items, (GFunc) gtk_recent_info_unref, NULL);
11918- g_list_free (load_data->items); 7717- g_list_free (load_data->items);
11919- load_data->items = NULL; 7718- load_data->items = NULL;
11920+ response = gtk_dialog_run (GTK_DIALOG (dialog)); 7719-
11921
11922- return FALSE; 7720- return FALSE;
11923- } 7721- }
11924+ gtk_widget_destroy (dialog); 7722-
11925
11926- return TRUE; 7723- return TRUE;
11927+ return (response == GTK_RESPONSE_ACCEPT); 7724-}
11928 } 7725-
11929
11930-static void 7726-static void
11931-recent_start_loading (GtkFileChooserDefault *impl) 7727-recent_start_loading (GtkFileChooserDefault *impl)
11932+struct GetDisplayNameData 7728-{
11933 {
11934- RecentLoadData *load_data; 7729- RecentLoadData *load_data;
11935- 7730-
11936- recent_stop_loading (impl); 7731- recent_stop_loading (impl);
@@ -11956,92 +7751,54 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
11956- load_data, 7751- load_data,
11957- recent_idle_cleanup); 7752- recent_idle_cleanup);
11958-} 7753-}
11959+ GtkFileChooserDefault *impl; 7754-
11960+ gchar *file_part; 7755-static void
11961+};
11962
11963 static void
11964-recent_selected_foreach_get_path_cb (GtkTreeModel *model, 7756-recent_selected_foreach_get_path_cb (GtkTreeModel *model,
11965- GtkTreePath *path, 7757- GtkTreePath *path,
11966- GtkTreeIter *iter, 7758- GtkTreeIter *iter,
11967- gpointer data) 7759- gpointer data)
11968+confirmation_confirm_get_info_cb (GtkFileSystemHandle *handle, 7760-{
11969+ const GtkFileInfo *info,
11970+ const GError *error,
11971+ gpointer user_data)
11972 {
11973- GSList **list; 7761- GSList **list;
11974- const GtkFilePath *file_path; 7762- const GtkFilePath *file_path;
11975- GtkFilePath *file_path_copy; 7763- GtkFilePath *file_path_copy;
11976+ gboolean cancelled = handle->cancelled; 7764-
11977+ gboolean should_respond = FALSE;
11978+ struct GetDisplayNameData *data = user_data;
11979
11980- list = data; 7765- list = data;
11981+ if (handle != data->impl->should_respond_get_info_handle) 7766-
11982+ goto out;
11983
11984- gtk_tree_model_get (model, iter, RECENT_MODEL_COL_PATH, &file_path, -1); 7767- gtk_tree_model_get (model, iter, RECENT_MODEL_COL_PATH, &file_path, -1);
11985- file_path_copy = gtk_file_path_copy (file_path); 7768- file_path_copy = gtk_file_path_copy (file_path);
11986- *list = g_slist_prepend (*list, file_path_copy); 7769- *list = g_slist_prepend (*list, file_path_copy);
11987-} 7770-}
11988+ data->impl->should_respond_get_info_handle = NULL; 7771-
11989
11990-/* Constructs a list of the selected paths in recent files mode */ 7772-/* Constructs a list of the selected paths in recent files mode */
11991-static GSList * 7773-static GSList *
11992-recent_get_selected_paths (GtkFileChooserDefault *impl) 7774-recent_get_selected_paths (GtkFileChooserDefault *impl)
11993-{ 7775-{
11994- GSList *result; 7776- GSList *result;
11995- GtkTreeSelection *selection; 7777- GtkTreeSelection *selection;
11996+ if (cancelled) 7778-
11997+ goto out;
11998+
11999+ if (error)
12000+ /* Huh? Did the folder disappear? Let the caller deal with it */
12001+ should_respond = TRUE;
12002+ else
12003+ should_respond = confirm_dialog_should_accept_filename (data->impl, data->file_part, gtk_file_info_get_display_name (info));
12004
12005- result = NULL; 7779- result = NULL;
12006+ set_busy_cursor (data->impl, FALSE); 7780-
12007+ if (should_respond)
12008+ g_signal_emit_by_name (data->impl, "response-requested");
12009
12010- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_files_tree_view)); 7781- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_files_tree_view));
12011- gtk_tree_selection_selected_foreach (selection, recent_selected_foreach_get_path_cb, &result); 7782- gtk_tree_selection_selected_foreach (selection, recent_selected_foreach_get_path_cb, &result);
12012- result = g_slist_reverse (result); 7783- result = g_slist_reverse (result);
12013+out: 7784-
12014+ g_object_unref (data->impl);
12015+ g_free (data->file_part);
12016+ g_free (data);
12017
12018- return result; 7785- return result;
12019+ g_object_unref (handle); 7786-}
12020 } 7787-
12021
12022-/* Called from ::should_respond(). We return whether there are selected 7788-/* Called from ::should_respond(). We return whether there are selected
12023- * files in the recent files list. 7789- * files in the recent files list.
12024+/* Does overwrite confirmation if appropriate, and returns whether the dialog 7790- */
12025+ * should respond. Can get the file part from the file list or the save entry. 7791-static gboolean
12026 */
12027 static gboolean
12028-recent_should_respond (GtkFileChooserDefault *impl) 7792-recent_should_respond (GtkFileChooserDefault *impl)
12029+should_respond_after_confirm_overwrite (GtkFileChooserDefault *impl, 7793-{
12030+ const gchar *file_part,
12031+ const GtkFilePath *parent_path)
12032 {
12033- GtkTreeSelection *selection; 7794- GtkTreeSelection *selection;
12034+ GtkFileChooserConfirmation conf; 7795-
12035
12036- g_assert (impl->operation_mode == OPERATION_MODE_RECENT); 7796- g_assert (impl->operation_mode == OPERATION_MODE_RECENT);
12037+ if (!impl->do_overwrite_confirmation) 7797-
12038+ return TRUE;
12039
12040- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_files_tree_view)); 7798- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_files_tree_view));
12041- return (gtk_tree_selection_count_selected_rows (selection) != 0); 7799- return (gtk_tree_selection_count_selected_rows (selection) != 0);
12042-} 7800-}
12043+ conf = GTK_FILE_CHOOSER_CONFIRMATION_CONFIRM; 7801-
12044
12045-/* Hide the location widgets temporarily */ 7802-/* Hide the location widgets temporarily */
12046-static void 7803-static void
12047-recent_hide_entry (GtkFileChooserDefault *impl) 7804-recent_hide_entry (GtkFileChooserDefault *impl)
@@ -12051,18 +7808,12 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
12051- 7808-
12052- if (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN || 7809- if (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN ||
12053- impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER) 7810- impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER)
12054+ g_signal_emit_by_name (impl, "confirm-overwrite", &conf); 7811- {
12055+
12056+ switch (conf)
12057 {
12058- gtk_widget_hide (impl->location_button); 7812- gtk_widget_hide (impl->location_button);
12059- gtk_widget_hide (impl->location_entry_box); 7813- gtk_widget_hide (impl->location_entry_box);
12060- } 7814- }
12061-} 7815-}
12062+ case GTK_FILE_CHOOSER_CONFIRMATION_CONFIRM: 7816-
12063+ {
12064+ struct GetDisplayNameData *data;
12065
12066-/* Main entry point to the recent files functions; this gets called when 7817-/* Main entry point to the recent files functions; this gets called when
12067- * the user activates the Recently Used shortcut. 7818- * the user activates the Recently Used shortcut.
12068- */ 7819- */
@@ -12070,28 +7821,13 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
12070-recent_activate (GtkFileChooserDefault *impl) 7821-recent_activate (GtkFileChooserDefault *impl)
12071-{ 7822-{
12072- OperationMode previous_mode; 7823- OperationMode previous_mode;
12073+ g_assert (file_part != NULL); 7824-
12074
12075- if (impl->operation_mode == OPERATION_MODE_RECENT) 7825- if (impl->operation_mode == OPERATION_MODE_RECENT)
12076- return; 7826- return;
12077+ data = g_new0 (struct GetDisplayNameData, 1); 7827-
12078+ data->impl = g_object_ref (impl);
12079+ data->file_part = g_strdup (file_part);
12080+
12081+ if (impl->should_respond_get_info_handle)
12082+ gtk_file_system_cancel_operation (impl->should_respond_get_info_handle);
12083
12084- previous_mode = impl->operation_mode; 7828- previous_mode = impl->operation_mode;
12085- impl->operation_mode = OPERATION_MODE_RECENT; 7829- impl->operation_mode = OPERATION_MODE_RECENT;
12086+ impl->should_respond_get_info_handle = 7830-
12087+ gtk_file_system_get_info (impl->file_system, parent_path,
12088+ GTK_FILE_INFO_DISPLAY_NAME,
12089+ confirmation_confirm_get_info_cb,
12090+ data);
12091+ set_busy_cursor (data->impl, TRUE);
12092+ return FALSE;
12093+ }
12094
12095- switch (previous_mode) 7831- switch (previous_mode)
12096- { 7832- {
12097- case OPERATION_MODE_SEARCH: 7833- case OPERATION_MODE_SEARCH:
@@ -12102,52 +7838,38 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
12102- impl->search_hbox = NULL; 7838- impl->search_hbox = NULL;
12103- impl->search_entry = NULL; 7839- impl->search_entry = NULL;
12104- break; 7840- break;
12105+ case GTK_FILE_CHOOSER_CONFIRMATION_ACCEPT_FILENAME: 7841-
12106+ return TRUE;
12107
12108- case OPERATION_MODE_BROWSE: 7842- case OPERATION_MODE_BROWSE:
12109- stop_loading_and_clear_list_model (impl); 7843- stop_loading_and_clear_list_model (impl);
12110- break; 7844- break;
12111+ case GTK_FILE_CHOOSER_CONFIRMATION_SELECT_AGAIN: 7845-
12112+ return FALSE;
12113
12114- case OPERATION_MODE_RECENT: 7846- case OPERATION_MODE_RECENT:
12115+ default: 7847- g_assert_not_reached ();
12116 g_assert_not_reached ();
12117- break; 7848- break;
12118+ return FALSE; 7849- }
12119 }
12120- 7850-
12121- recent_hide_entry (impl); 7851- recent_hide_entry (impl);
12122- file_list_set_sort_column_ids (impl); 7852- file_list_set_sort_column_ids (impl);
12123- recent_start_loading (impl); 7853- recent_start_loading (impl);
12124 } 7854-}
12125 7855-
12126-/* convert an iterator coming from the model bound to 7856-/* convert an iterator coming from the model bound to
12127- * browse_files_tree_view to an interator inside the 7857- * browse_files_tree_view to an interator inside the
12128- * real recent_model 7858- * real recent_model
12129- */ 7859- */
12130 static void 7860-static void
12131-recent_get_valid_child_iter (GtkFileChooserDefault *impl, 7861-recent_get_valid_child_iter (GtkFileChooserDefault *impl,
12132- GtkTreeIter *child_iter, 7862- GtkTreeIter *child_iter,
12133- GtkTreeIter *iter) 7863- GtkTreeIter *iter)
12134+action_create_folder_cb (GtkFileSystemHandle *handle, 7864-{
12135+ const GtkFilePath *path,
12136+ const GError *error,
12137+ gpointer user_data)
12138 {
12139- GtkTreeIter middle; 7865- GtkTreeIter middle;
12140- 7866-
12141- if (!impl->recent_model) 7867- if (!impl->recent_model)
12142- return; 7868- return;
12143+ gboolean cancelled = handle->cancelled; 7869-
12144+ GtkFileChooserDefault *impl = user_data;
12145
12146- if (!impl->recent_model_filter || !impl->recent_model_sort) 7870- if (!impl->recent_model_filter || !impl->recent_model_sort)
12147- return; 7871- return;
12148+ if (!g_slist_find (impl->pending_handles, handle)) 7872-
12149+ goto out;
12150
12151- /* pass 1: get the iterator in the filter model */ 7873- /* pass 1: get the iterator in the filter model */
12152- gtk_tree_model_sort_convert_iter_to_child_iter (impl->recent_model_sort, 7874- gtk_tree_model_sort_convert_iter_to_child_iter (impl->recent_model_sort,
12153- &middle, iter); 7875- &middle, iter);
@@ -12157,94 +7879,28 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
12157- child_iter, 7879- child_iter,
12158- &middle); 7880- &middle);
12159-} 7881-}
12160+ impl->pending_handles = g_slist_remove (impl->pending_handles, handle); 7882-
12161 7883-
12162+ set_busy_cursor (impl, FALSE);
12163
12164-static void 7884-static void
12165-set_current_filter (GtkFileChooserDefault *impl, 7885 set_current_filter (GtkFileChooserDefault *impl,
12166- GtkFileFilter *filter) 7886 GtkFileFilter *filter)
12167-{ 7887 {
12168- if (impl->current_filter != filter) 7888@@ -10175,12 +4463,6 @@
12169- { 7889 if (impl->browse_files_model)
12170- int filter_index; 7890 install_list_model_filter (impl);
12171+ if (cancelled)
12172+ goto out;
12173
12174- /* NULL filters are allowed to reset to non-filtered status
12175- */
12176- filter_index = g_slist_index (impl->filters, filter);
12177- if (impl->filters && filter && filter_index < 0)
12178- return;
12179+ if (error)
12180+ error_creating_folder_dialog (impl, path, g_error_copy (error));
12181+ else
12182+ g_signal_emit_by_name (impl, "response-requested");
12183
12184- if (impl->current_filter)
12185- g_object_unref (impl->current_filter);
12186- impl->current_filter = filter;
12187- if (impl->current_filter)
12188- {
12189- g_object_ref_sink (impl->current_filter);
12190- }
12191+out:
12192+ g_object_unref (impl);
12193+ g_object_unref (handle);
12194+}
12195
12196- if (impl->filters)
12197- gtk_combo_box_set_active (GTK_COMBO_BOX (impl->filter_combo),
12198- filter_index);
12199+struct FileExistsData
12200+{
12201+ GtkFileChooserDefault *impl;
12202+ gboolean file_exists_and_is_not_folder;
12203+ GtkFilePath *parent_path;
12204+ GtkFilePath *path;
12205+};
12206
12207- if (impl->browse_files_model)
12208- install_list_model_filter (impl);
12209+static void
12210+save_entry_get_info_cb (GtkFileSystemHandle *handle,
12211+ const GtkFileInfo *info,
12212+ const GError *error,
12213+ gpointer user_data)
12214+{
12215+ gboolean parent_is_folder;
12216+ gboolean cancelled = handle->cancelled;
12217+ struct FileExistsData *data = user_data;
12218 7891
12219- if (impl->search_model_filter) 7892- if (impl->search_model_filter)
12220- gtk_tree_model_filter_refilter (impl->search_model_filter); 7893- gtk_tree_model_filter_refilter (impl->search_model_filter);
12221+ if (handle != data->impl->should_respond_get_info_handle) 7894-
12222+ goto out;
12223
12224- if (impl->recent_model_filter) 7895- if (impl->recent_model_filter)
12225- gtk_tree_model_filter_refilter (impl->recent_model_filter); 7896- gtk_tree_model_filter_refilter (impl->recent_model_filter);
12226+ data->impl->should_respond_get_info_handle = NULL; 7897-
12227 7898 g_object_notify (G_OBJECT (impl), "filter");
12228- g_object_notify (G_OBJECT (impl), "filter"); 7899 }
12229- } 7900 }
12230-} 7901@@ -10195,355 +4477,7 @@
12231+ set_busy_cursor (data->impl, FALSE); 7902 set_current_filter (impl, new_filter);
12232 7903 }
12233-static void
12234-filter_combo_changed (GtkComboBox *combo_box,
12235- GtkFileChooserDefault *impl)
12236-{
12237- gint new_index = gtk_combo_box_get_active (combo_box);
12238- GtkFileFilter *new_filter = g_slist_nth_data (impl->filters, new_index);
12239+ if (cancelled)
12240+ goto out;
12241
12242- set_current_filter (impl, new_filter);
12243-}
12244+ if (!info)
12245+ parent_is_folder = FALSE;
12246+ else
12247+ parent_is_folder = gtk_file_info_get_is_folder (info);
12248 7904
12249-static void 7905-static void
12250-check_preview_change (GtkFileChooserDefault *impl) 7906-check_preview_change (GtkFileChooserDefault *impl)
@@ -12257,39 +7913,27 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
12257- new_path = NULL; 7913- new_path = NULL;
12258- new_display_name = NULL; 7914- new_display_name = NULL;
12259- if (cursor_path) 7915- if (cursor_path)
12260+ if (parent_is_folder) 7916- {
12261 {
12262- GtkTreeIter child_iter; 7917- GtkTreeIter child_iter;
12263- 7918-
12264- if (impl->operation_mode == OPERATION_MODE_BROWSE) 7919- if (impl->operation_mode == OPERATION_MODE_BROWSE)
12265- { 7920- {
12266- if (impl->sort_model) 7921- if (impl->sort_model)
12267+ if (data->impl->action == GTK_FILE_CHOOSER_ACTION_SAVE) 7922- {
12268+ {
12269+ if (data->file_exists_and_is_not_folder)
12270 {
12271- GtkTreeIter iter; 7923- GtkTreeIter iter;
12272- const GtkFileInfo *new_info; 7924- const GtkFileInfo *new_info;
12273- 7925-
12274- gtk_tree_model_get_iter (GTK_TREE_MODEL (impl->sort_model), &iter, cursor_path); 7926- gtk_tree_model_get_iter (GTK_TREE_MODEL (impl->sort_model), &iter, cursor_path);
12275- gtk_tree_path_free (cursor_path); 7927- gtk_tree_path_free (cursor_path);
12276+ gboolean retval; 7928-
12277+ const char *file_part;
12278
12279- gtk_tree_model_sort_convert_iter_to_child_iter (impl->sort_model, &child_iter, &iter); 7929- gtk_tree_model_sort_convert_iter_to_child_iter (impl->sort_model, &child_iter, &iter);
12280+ file_part = _gtk_file_chooser_entry_get_file_part (GTK_FILE_CHOOSER_ENTRY (data->impl->location_entry)); 7930-
12281+ retval = should_respond_after_confirm_overwrite (data->impl, file_part, data->parent_path);
12282
12283- new_path = _gtk_file_system_model_get_path (impl->browse_files_model, &child_iter); 7931- new_path = _gtk_file_system_model_get_path (impl->browse_files_model, &child_iter);
12284- new_info = _gtk_file_system_model_get_info (impl->browse_files_model, &child_iter); 7932- new_info = _gtk_file_system_model_get_info (impl->browse_files_model, &child_iter);
12285- if (new_info) 7933- if (new_info)
12286- new_display_name = gtk_file_info_get_display_name (new_info); 7934- new_display_name = gtk_file_info_get_display_name (new_info);
12287+ if (retval) 7935- }
12288+ g_signal_emit_by_name (data->impl, "response-requested"); 7936- }
12289 }
12290+ else
12291+ g_signal_emit_by_name (data->impl, "response-requested");
12292 }
12293- else if (impl->operation_mode == OPERATION_MODE_SEARCH) 7937- else if (impl->operation_mode == OPERATION_MODE_SEARCH)
12294- { 7938- {
12295- GtkTreeIter iter; 7939- GtkTreeIter iter;
@@ -12305,11 +7949,9 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
12305- -1); 7949- -1);
12306- } 7950- }
12307- else if (impl->operation_mode == OPERATION_MODE_RECENT) 7951- else if (impl->operation_mode == OPERATION_MODE_RECENT)
12308+ else /* GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER */ 7952- {
12309 {
12310- GtkTreeIter iter; 7953- GtkTreeIter iter;
12311+ GtkFileSystemHandle *handle; 7954-
12312
12313- gtk_tree_model_get_iter (GTK_TREE_MODEL (impl->recent_model_sort), 7955- gtk_tree_model_get_iter (GTK_TREE_MODEL (impl->recent_model_sort),
12314- &iter, cursor_path); 7956- &iter, cursor_path);
12315- gtk_tree_path_free (cursor_path); 7957- gtk_tree_path_free (cursor_path);
@@ -12319,21 +7961,13 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
12319- RECENT_MODEL_COL_PATH, &new_path, 7961- RECENT_MODEL_COL_PATH, &new_path,
12320- RECENT_MODEL_COL_DISPLAY_NAME, &new_display_name, 7962- RECENT_MODEL_COL_DISPLAY_NAME, &new_display_name,
12321- -1); 7963- -1);
12322+ g_object_ref (data->impl); 7964- }
12323+ handle = gtk_file_system_create_folder (data->impl->file_system, 7965- }
12324+ data->path,
12325+ action_create_folder_cb,
12326+ data->impl);
12327+ data->impl->pending_handles = g_slist_append (data->impl->pending_handles, handle);
12328+ set_busy_cursor (data->impl, TRUE);
12329 }
12330 }
12331- 7966-
12332- if (new_path != impl->preview_path && 7967- if (new_path != impl->preview_path &&
12333- !(new_path && impl->preview_path && 7968- !(new_path && impl->preview_path &&
12334- gtk_file_path_compare (new_path, impl->preview_path) == 0)) 7969- gtk_file_path_compare (new_path, impl->preview_path) == 0))
12335+ else 7970- {
12336 {
12337- if (impl->preview_path) 7971- if (impl->preview_path)
12338- { 7972- {
12339- gtk_file_path_free (impl->preview_path); 7973- gtk_file_path_free (impl->preview_path);
@@ -12350,129 +7984,70 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
12350- impl->preview_path = NULL; 7984- impl->preview_path = NULL;
12351- impl->preview_display_name = NULL; 7985- impl->preview_display_name = NULL;
12352- } 7986- }
12353+ /* This will display an error, which is what we want */ 7987-
12354+ change_folder_and_display_error (data->impl, data->parent_path);
12355+ }
12356
12357- if (impl->use_preview_label && impl->preview_label) 7988- if (impl->use_preview_label && impl->preview_label)
12358- gtk_label_set_text (GTK_LABEL (impl->preview_label), impl->preview_display_name); 7989- gtk_label_set_text (GTK_LABEL (impl->preview_label), impl->preview_display_name);
12359+out: 7990-
12360+ g_object_unref (data->impl);
12361+ gtk_file_path_free (data->path);
12362+ gtk_file_path_free (data->parent_path);
12363+ g_free (data);
12364
12365- g_signal_emit_by_name (impl, "update-preview"); 7991- g_signal_emit_by_name (impl, "update-preview");
12366- } 7992- }
12367+ g_object_unref (handle); 7993-}
12368 } 7994-
12369 7995-static void
12370 static void
12371-shortcuts_activate_volume_mount_cb (GtkFileSystemHandle *handle, 7996-shortcuts_activate_volume_mount_cb (GtkFileSystemHandle *handle,
12372- GtkFileSystemVolume *volume, 7997- GtkFileSystemVolume *volume,
12373- const GError *error, 7998- const GError *error,
12374- gpointer data) 7999- gpointer data)
12375+file_exists_get_info_cb (GtkFileSystemHandle *handle, 8000-{
12376+ const GtkFileInfo *info,
12377+ const GError *error,
12378+ gpointer user_data)
12379 {
12380- GtkFilePath *path; 8001- GtkFilePath *path;
12381+ gboolean data_ownership_taken = FALSE; 8002- gboolean cancelled = handle->cancelled;
12382 gboolean cancelled = handle->cancelled;
12383- GtkFileChooserDefault *impl = data; 8003- GtkFileChooserDefault *impl = data;
12384+ gboolean file_exists_and_is_not_folder; 8004-
12385+ struct FileExistsData *data = user_data;
12386
12387- if (handle != impl->shortcuts_activate_iter_handle) 8005- if (handle != impl->shortcuts_activate_iter_handle)
12388+ if (handle != data->impl->file_exists_get_info_handle) 8006- goto out;
12389 goto out; 8007-
12390
12391- impl->shortcuts_activate_iter_handle = NULL; 8008- impl->shortcuts_activate_iter_handle = NULL;
12392+ data->impl->file_exists_get_info_handle = NULL; 8009-
12393
12394- set_busy_cursor (impl, FALSE); 8010- set_busy_cursor (impl, FALSE);
12395+ set_busy_cursor (data->impl, FALSE); 8011-
12396 8012- if (cancelled)
12397 if (cancelled) 8013- goto out;
12398 goto out; 8014-
12399
12400- if (error) 8015- if (error)
12401+ file_exists_and_is_not_folder = info && !gtk_file_info_get_is_folder (info); 8016- {
12402+
12403+ if (data->impl->action == GTK_FILE_CHOOSER_ACTION_OPEN)
12404+ /* user typed a filename; we are done */
12405+ g_signal_emit_by_name (data->impl, "response-requested");
12406+ else if (data->impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER
12407+ && file_exists_and_is_not_folder)
12408+ {
12409+ /* Oops, the user typed the name of an existing path which is not
12410+ * a folder
12411+ */
12412+ error_creating_folder_over_existing_file_dialog (data->impl, data->path,
12413+ g_error_copy (error));
12414+ }
12415+ else
12416 {
12417- char *msg; 8017- char *msg;
12418+ /* check that everything up to the last component exists */ 8018-
12419+
12420+ data->file_exists_and_is_not_folder = file_exists_and_is_not_folder;
12421+ data_ownership_taken = TRUE;
12422
12423- msg = g_strdup_printf (_("Could not mount %s"), 8019- msg = g_strdup_printf (_("Could not mount %s"),
12424- gtk_file_system_volume_get_display_name (impl->file_system, volume)); 8020- gtk_file_system_volume_get_display_name (impl->file_system, volume));
12425- error_message (impl, msg, error->message); 8021- error_message (impl, msg, error->message);
12426- g_free (msg); 8022- g_free (msg);
12427+ if (data->impl->should_respond_get_info_handle) 8023-
12428+ gtk_file_system_cancel_operation (data->impl->should_respond_get_info_handle);
12429
12430- goto out; 8024- goto out;
12431+ data->impl->should_respond_get_info_handle = 8025- }
12432+ gtk_file_system_get_info (data->impl->file_system, 8026-
12433+ data->parent_path,
12434+ GTK_FILE_INFO_IS_FOLDER,
12435+ save_entry_get_info_cb,
12436+ data);
12437+ set_busy_cursor (data->impl, TRUE);
12438 }
12439
12440- path = gtk_file_system_volume_get_base_path (impl->file_system, volume); 8027- path = gtk_file_system_volume_get_base_path (impl->file_system, volume);
12441- if (path != NULL) 8028- if (path != NULL)
12442+out: 8029- {
12443+ if (!data_ownership_taken)
12444 {
12445- change_folder_and_display_error (impl, path, FALSE); 8030- change_folder_and_display_error (impl, path, FALSE);
12446- focus_browse_tree_view_if_possible (impl); 8031- focus_browse_tree_view_if_possible (impl);
12447- 8032-
12448- gtk_file_path_free (path); 8033- gtk_file_path_free (path);
12449+ g_object_unref (data->impl); 8034- }
12450+ gtk_file_path_free (data->path); 8035-
12451+ gtk_file_path_free (data->parent_path);
12452+ g_free (data);
12453 }
12454
12455-out: 8036-out:
12456- g_object_unref (impl); 8037- g_object_unref (impl);
12457 g_object_unref (handle); 8038- g_object_unref (handle);
12458 } 8039-}
12459 8040-
12460 8041-
12461-/* Activates a volume by mounting it if necessary and then switching to its 8042-/* Activates a volume by mounting it if necessary and then switching to its
12462- * base path. 8043- * base path.
12463- */ 8044- */
12464-static void 8045-static void
12465-shortcuts_activate_volume (GtkFileChooserDefault *impl, 8046-shortcuts_activate_volume (GtkFileChooserDefault *impl,
12466- GtkFileSystemVolume *volume) 8047- GtkFileSystemVolume *volume)
12467+/* Implementation for GtkFileChooserEmbed::should_respond() */ 8048-{
12468+static gboolean
12469+gtk_file_chooser_default_should_respond (GtkFileChooserEmbed *chooser_embed)
12470 {
12471- GtkFilePath *path; 8049- GtkFilePath *path;
12472+ GtkFileChooserDefault *impl; 8050-
12473+ GtkWidget *toplevel;
12474+ GtkWidget *current_focus;
12475
12476- switch (impl->operation_mode) 8051- switch (impl->operation_mode)
12477- { 8052- {
12478- case OPERATION_MODE_BROWSE: 8053- case OPERATION_MODE_BROWSE:
@@ -12484,102 +8059,23 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
12484- recent_switch_to_browse_mode (impl); 8059- recent_switch_to_browse_mode (impl);
12485- break; 8060- break;
12486- } 8061- }
12487+ impl = GTK_FILE_CHOOSER_DEFAULT (chooser_embed); 8062-
12488
12489- /* We ref the file chooser since volume_mount() may run a main loop, and the 8063- /* We ref the file chooser since volume_mount() may run a main loop, and the
12490- * user could close the file chooser window in the meantime. 8064- * user could close the file chooser window in the meantime.
12491- */ 8065- */
12492- g_object_ref (impl); 8066- g_object_ref (impl);
12493+ toplevel = gtk_widget_get_toplevel (GTK_WIDGET (impl)); 8067-
12494+ g_assert (GTK_IS_WINDOW (toplevel));
12495+
12496+ current_focus = gtk_window_get_focus (GTK_WINDOW (toplevel));
12497
12498- if (!gtk_file_system_volume_get_is_mounted (impl->file_system, volume)) 8068- if (!gtk_file_system_volume_get_is_mounted (impl->file_system, volume))
12499+ if (current_focus == impl->browse_files_tree_view) 8069- {
12500 {
12501- set_busy_cursor (impl, TRUE); 8070- set_busy_cursor (impl, TRUE);
12502+ /* The following array encodes what we do based on the impl->action and the 8071-
12503+ * number of files selected.
12504+ */
12505+ typedef enum {
12506+ NOOP, /* Do nothing (don't respond) */
12507+ RESPOND, /* Respond immediately */
12508+ RESPOND_OR_SWITCH, /* Respond immediately if the selected item is a file; switch to it if it is a folder */
12509+ ALL_FILES, /* Respond only if everything selected is a file */
12510+ ALL_FOLDERS, /* Respond only if everything selected is a folder */
12511+ SAVE_ENTRY, /* Go to the code for handling the save entry */
12512+ NOT_REACHED /* Sanity check */
12513+ } ActionToTake;
12514+ static const ActionToTake what_to_do[4][3] = {
12515+ /* 0 selected 1 selected many selected */
12516+ /* ACTION_OPEN */ { NOOP, RESPOND_OR_SWITCH, ALL_FILES },
12517+ /* ACTION_SAVE */ { SAVE_ENTRY, RESPOND_OR_SWITCH, NOT_REACHED },
12518+ /* ACTION_SELECT_FOLDER */ { RESPOND, ALL_FOLDERS, ALL_FOLDERS },
12519+ /* ACTION_CREATE_FOLDER */ { SAVE_ENTRY, ALL_FOLDERS, NOT_REACHED }
12520+ };
12521+
12522+ int num_selected;
12523+ gboolean all_files, all_folders;
12524+ int k;
12525+ ActionToTake action;
12526+
12527+ file_list:
12528+
12529+ g_assert (impl->action >= GTK_FILE_CHOOSER_ACTION_OPEN && impl->action <= GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER);
12530+
12531+ selection_check (impl, &num_selected, &all_files, &all_folders);
12532+
12533+ if (num_selected > 2)
12534+ k = 2;
12535+ else
12536+ k = num_selected;
12537+
12538+ action = what_to_do [impl->action] [k];
12539+
12540+ switch (action)
12541+ {
12542+ case NOOP:
12543+ return FALSE;
12544+
12545+ case RESPOND:
12546+ return TRUE;
12547+
12548+ case RESPOND_OR_SWITCH:
12549+ g_assert (num_selected == 1);
12550+
12551+ if (all_folders)
12552+ {
12553+ switch_to_selected_folder (impl);
12554+ return FALSE;
12555+ }
12556+ else if (impl->action == GTK_FILE_CHOOSER_ACTION_SAVE)
12557+ return should_respond_after_confirm_overwrite (impl,
12558+ get_display_name_from_file_list (impl),
12559+ impl->current_folder);
12560+ else
12561+ return TRUE;
12562+
12563+ case ALL_FILES:
12564+ return all_files;
12565+
12566+ case ALL_FOLDERS:
12567+ return all_folders;
12568+
12569+ case SAVE_ENTRY:
12570+ goto save_entry;
12571
12572- impl->shortcuts_activate_iter_handle = 8072- impl->shortcuts_activate_iter_handle =
12573- gtk_file_system_volume_mount (impl->file_system, volume, 8073- gtk_file_system_volume_mount (impl->file_system, volume,
12574- shortcuts_activate_volume_mount_cb, 8074- shortcuts_activate_volume_mount_cb,
12575- g_object_ref (impl)); 8075- g_object_ref (impl));
12576+ default: 8076- }
12577+ g_assert_not_reached ();
12578+ }
12579 }
12580- else 8077- else
12581+ else if ((impl->location_entry != NULL) && (current_focus == impl->location_entry)) 8078- {
12582 {
12583- path = gtk_file_system_volume_get_base_path (impl->file_system, volume); 8079- path = gtk_file_system_volume_get_base_path (impl->file_system, volume);
12584- if (path != NULL) 8080- if (path != NULL)
12585- { 8081- {
@@ -12587,70 +8083,17 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
12587- gtk_file_path_free (path); 8083- gtk_file_path_free (path);
12588- } 8084- }
12589- } 8085- }
12590+ GtkFilePath *path; 8086-
12591+ gboolean is_well_formed, is_empty, is_file_part_empty;
12592+ gboolean is_folder;
12593+ gboolean retval;
12594+ GtkFileChooserEntry *entry;
12595+ GError *error;
12596+
12597+ save_entry:
12598+
12599+ g_assert (impl->action == GTK_FILE_CHOOSER_ACTION_SAVE
12600+ || impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER
12601+ || impl->action == GTK_FILE_CHOOSER_ACTION_OPEN
12602+ || impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER);
12603+
12604+ entry = GTK_FILE_CHOOSER_ENTRY (impl->location_entry);
12605+ check_save_entry (impl, &path, &is_well_formed, &is_empty, &is_file_part_empty, &is_folder);
12606+
12607+ if (is_empty || !is_well_formed)
12608+ return FALSE;
12609+
12610+ g_assert (path != NULL);
12611+
12612+ error = NULL;
12613+ if (is_folder)
12614+ {
12615+ if (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN
12616+ || impl->action == GTK_FILE_CHOOSER_ACTION_SAVE)
12617+ {
12618+ change_folder_and_display_error (impl, path);
12619+ retval = FALSE;
12620+ }
12621+ else if (impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER
12622+ || GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)
12623+ {
12624+ /* The folder already exists, so we do not need to create it.
12625+ * Just respond to terminate the dialog.
12626+ */
12627+ retval = TRUE;
12628+ }
12629+ else
12630+ {
12631+ g_assert_not_reached ();
12632+ retval = FALSE;
12633+ }
12634+ }
12635+ else
12636+ {
12637+ struct FileExistsData *data;
12638
12639- g_object_unref (impl); 8087- g_object_unref (impl);
12640-} 8088-}
12641+ /* We need to check whether path exists and is not a folder */ 8089-
12642
12643-/* Opens the folder or volume at the specified iter in the shortcuts model */ 8090-/* Opens the folder or volume at the specified iter in the shortcuts model */
12644-struct ShortcutsActivateData 8091-struct ShortcutsActivateData
12645-{ 8092-{
12646- GtkFileChooserDefault *impl; 8093- GtkFileChooserDefault *impl;
12647- GtkFilePath *path; 8094- GtkFilePath *path;
12648-}; 8095-};
12649+ data = g_new0 (struct FileExistsData, 1); 8096-
12650+ data->impl = g_object_ref (impl);
12651+ data->path = gtk_file_path_copy (path);
12652+ data->parent_path = gtk_file_path_copy (_gtk_file_chooser_entry_get_current_folder (entry));
12653
12654-static void 8097-static void
12655-shortcuts_activate_get_info_cb (GtkFileSystemHandle *handle, 8098-shortcuts_activate_get_info_cb (GtkFileSystemHandle *handle,
12656- const GtkFileInfo *info, 8099- const GtkFileInfo *info,
@@ -12659,48 +8102,21 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
12659-{ 8102-{
12660- gboolean cancelled = handle->cancelled; 8103- gboolean cancelled = handle->cancelled;
12661- struct ShortcutsActivateData *data = user_data; 8104- struct ShortcutsActivateData *data = user_data;
12662+ if (impl->file_exists_get_info_handle) 8105-
12663+ gtk_file_system_cancel_operation (impl->file_exists_get_info_handle);
12664
12665- if (handle != data->impl->shortcuts_activate_iter_handle) 8106- if (handle != data->impl->shortcuts_activate_iter_handle)
12666- goto out; 8107- goto out;
12667+ impl->file_exists_get_info_handle = 8108-
12668+ gtk_file_system_get_info (impl->file_system, path,
12669+ GTK_FILE_INFO_IS_FOLDER,
12670+ file_exists_get_info_cb,
12671+ data);
12672
12673- data->impl->shortcuts_activate_iter_handle = NULL; 8109- data->impl->shortcuts_activate_iter_handle = NULL;
12674+ set_busy_cursor (impl, TRUE); 8110-
12675+ retval = FALSE;
12676
12677- if (cancelled) 8111- if (cancelled)
12678- goto out; 8112- goto out;
12679+ if (error != NULL) 8113-
12680+ g_error_free (error);
12681+ }
12682
12683- if (!error && gtk_file_info_get_is_folder (info)) 8114- if (!error && gtk_file_info_get_is_folder (info))
12684+ gtk_file_path_free (path); 8115- {
12685+ return retval;
12686+ }
12687+ else if (impl->toplevel_last_focus_widget == impl->browse_files_tree_view)
12688+ {
12689+ /* The focus is on a dialog's action area button, *and* the widget that
12690+ * was focused immediately before it is the file list.
12691+ */
12692+ goto file_list;
12693+ }
12694+ else if (impl->location_entry && impl->toplevel_last_focus_widget == impl->location_entry)
12695 {
12696- change_folder_and_display_error (data->impl, data->path, FALSE); 8116- change_folder_and_display_error (data->impl, data->path, FALSE);
12697- focus_browse_tree_view_if_possible (data->impl); 8117- focus_browse_tree_view_if_possible (data->impl);
12698+ /* The focus is on a dialog's action area button, *and* the widget that 8118- }
12699+ * was focused immediately before it is the location entry. 8119- else
12700+ */
12701+ goto save_entry;
12702 }
12703 else
12704- gtk_file_chooser_default_select_path (GTK_FILE_CHOOSER (data->impl), 8120- gtk_file_chooser_default_select_path (GTK_FILE_CHOOSER (data->impl),
12705- data->path, 8121- data->path,
12706- NULL); 8122- NULL);
@@ -12709,24 +8125,14 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
12709- g_object_unref (data->impl); 8125- g_object_unref (data->impl);
12710- gtk_file_path_free (data->path); 8126- gtk_file_path_free (data->path);
12711- g_free (data); 8127- g_free (data);
12712+ /* The focus is on a dialog's action area button or something else */ 8128-
12713+ if (impl->action == GTK_FILE_CHOOSER_ACTION_SAVE
12714+ || impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)
12715+ goto save_entry;
12716+ else
12717+ goto file_list;
12718
12719- g_object_unref (handle); 8129- g_object_unref (handle);
12720+ g_assert_not_reached (); 8130-}
12721+ return FALSE; 8131-
12722 } 8132-static void
12723
12724+/* Implementation for GtkFileChooserEmbed::initial_focus() */
12725 static void
12726-shortcuts_activate_iter (GtkFileChooserDefault *impl, 8133-shortcuts_activate_iter (GtkFileChooserDefault *impl,
12727- GtkTreeIter *iter) 8134- GtkTreeIter *iter)
12728+gtk_file_chooser_default_initial_focus (GtkFileChooserEmbed *chooser_embed) 8135-{
12729 {
12730- gpointer col_data; 8136- gpointer col_data;
12731- ShortcutType shortcut_type; 8137- ShortcutType shortcut_type;
12732- 8138-
@@ -12749,18 +8155,13 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
12749- else if (shortcut_type == SHORTCUT_TYPE_VOLUME) 8155- else if (shortcut_type == SHORTCUT_TYPE_VOLUME)
12750- { 8156- {
12751- GtkFileSystemVolume *volume; 8157- GtkFileSystemVolume *volume;
12752+ GtkFileChooserDefault *impl; 8158-
12753+ GtkWidget *widget;
12754
12755- volume = col_data; 8159- volume = col_data;
12756+ impl = GTK_FILE_CHOOSER_DEFAULT (chooser_embed); 8160-
12757
12758- shortcuts_activate_volume (impl, volume); 8161- shortcuts_activate_volume (impl, volume);
12759- } 8162- }
12760- else if (shortcut_type == SHORTCUT_TYPE_PATH) 8163- else if (shortcut_type == SHORTCUT_TYPE_PATH)
12761+ if (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN 8164- {
12762+ || impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER)
12763 {
12764- struct ShortcutsActivateData *data; 8165- struct ShortcutsActivateData *data;
12765- 8166-
12766- data = g_new0 (struct ShortcutsActivateData, 1); 8167- data = g_new0 (struct ShortcutsActivateData, 1);
@@ -12771,76 +8172,46 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
12771- gtk_file_system_get_info (impl->file_system, data->path, 8172- gtk_file_system_get_info (impl->file_system, data->path,
12772- GTK_FILE_INFO_IS_FOLDER, 8173- GTK_FILE_INFO_IS_FOLDER,
12773- shortcuts_activate_get_info_cb, data); 8174- shortcuts_activate_get_info_cb, data);
12774+ widget = impl->browse_files_tree_view; 8175- }
12775 }
12776- else if (shortcut_type == SHORTCUT_TYPE_SEARCH) 8176- else if (shortcut_type == SHORTCUT_TYPE_SEARCH)
12777+ else if (impl->action == GTK_FILE_CHOOSER_ACTION_SAVE 8177- {
12778+ || impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)
12779 {
12780- search_activate (impl); 8178- search_activate (impl);
12781+ widget = impl->location_entry; 8179- }
12782 }
12783- else if (shortcut_type == SHORTCUT_TYPE_RECENT) 8180- else if (shortcut_type == SHORTCUT_TYPE_RECENT)
12784+ else 8181- {
12785 {
12786- recent_activate (impl); 8182- recent_activate (impl);
12787+ g_assert_not_reached (); 8183- }
12788+ widget = NULL; 8184-}
12789 } 8185-
12790+
12791+ g_assert (widget != NULL);
12792+ gtk_widget_grab_focus (widget);
12793 }
12794
12795-/* Callback used when a row in the shortcuts list is activated */ 8186-/* Callback used when a row in the shortcuts list is activated */
12796 static void 8187-static void
12797-shortcuts_row_activated_cb (GtkTreeView *tree_view, 8188-shortcuts_row_activated_cb (GtkTreeView *tree_view,
12798- GtkTreePath *path, 8189- GtkTreePath *path,
12799- GtkTreeViewColumn *column, 8190- GtkTreeViewColumn *column,
12800- GtkFileChooserDefault *impl) 8191- GtkFileChooserDefault *impl)
12801+set_current_filter (GtkFileChooserDefault *impl, 8192-{
12802+ GtkFileFilter *filter)
12803 {
12804- GtkTreeIter iter; 8193- GtkTreeIter iter;
12805- GtkTreeIter child_iter; 8194- GtkTreeIter child_iter;
12806- 8195-
12807- if (!gtk_tree_model_get_iter (impl->shortcuts_pane_filter_model, &iter, path)) 8196- if (!gtk_tree_model_get_iter (impl->shortcuts_pane_filter_model, &iter, path))
12808- return; 8197- return;
12809+ if (impl->current_filter != filter) 8198-
12810+ {
12811+ int filter_index;
12812
12813- gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER (impl->shortcuts_pane_filter_model), 8199- gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER (impl->shortcuts_pane_filter_model),
12814- &child_iter, 8200- &child_iter,
12815- &iter); 8201- &iter);
12816- shortcuts_activate_iter (impl, &child_iter); 8202- shortcuts_activate_iter (impl, &child_iter);
12817-} 8203-}
12818+ /* NULL filters are allowed to reset to non-filtered status 8204-
12819+ */
12820+ filter_index = g_slist_index (impl->filters, filter);
12821+ if (impl->filters && filter && filter_index < 0)
12822+ return;
12823
12824-/* Handler for GtkWidget::key-press-event on the shortcuts list */ 8205-/* Handler for GtkWidget::key-press-event on the shortcuts list */
12825-static gboolean 8206 static gboolean
12826-shortcuts_key_press_event_cb (GtkWidget *widget, 8207-shortcuts_key_press_event_cb (GtkWidget *widget,
12827- GdkEventKey *event, 8208- GdkEventKey *event,
12828- GtkFileChooserDefault *impl) 8209- GtkFileChooserDefault *impl)
12829-{ 8210-{
12830- guint modifiers; 8211- guint modifiers;
12831+ if (impl->current_filter) 8212-
12832+ g_object_unref (impl->current_filter);
12833+ impl->current_filter = filter;
12834+ if (impl->current_filter)
12835+ {
12836+ g_object_ref_sink (impl->current_filter);
12837+ }
12838
12839- modifiers = gtk_accelerator_get_default_mod_mask (); 8213- modifiers = gtk_accelerator_get_default_mod_mask ();
12840+ if (impl->filters) 8214-
12841+ gtk_combo_box_set_active (GTK_COMBO_BOX (impl->filter_combo),
12842+ filter_index);
12843
12844- if ((event->keyval == GDK_BackSpace 8215- if ((event->keyval == GDK_BackSpace
12845- || event->keyval == GDK_Delete 8216- || event->keyval == GDK_Delete
12846- || event->keyval == GDK_KP_Delete) 8217- || event->keyval == GDK_KP_Delete)
@@ -12849,30 +8220,24 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
12849- remove_selected_bookmarks (impl); 8220- remove_selected_bookmarks (impl);
12850- return TRUE; 8221- return TRUE;
12851- } 8222- }
12852+ if (impl->browse_files_model) 8223-
12853+ install_list_model_filter (impl);
12854
12855- if ((event->keyval == GDK_F2) 8224- if ((event->keyval == GDK_F2)
12856- && (event->state & modifiers) == 0) 8225- && (event->state & modifiers) == 0)
12857- { 8226- {
12858- rename_selected_bookmark (impl); 8227- rename_selected_bookmark (impl);
12859- return TRUE; 8228- return TRUE;
12860+ g_object_notify (G_OBJECT (impl), "filter"); 8229- }
12861 }
12862- 8230-
12863- return FALSE; 8231- return FALSE;
12864 } 8232-}
12865 8233-
12866-static gboolean 8234-static gboolean
12867-shortcuts_select_func (GtkTreeSelection *selection, 8235-shortcuts_select_func (GtkTreeSelection *selection,
12868- GtkTreeModel *model, 8236- GtkTreeModel *model,
12869- GtkTreePath *path, 8237- GtkTreePath *path,
12870- gboolean path_currently_selected, 8238- gboolean path_currently_selected,
12871- gpointer data) 8239- gpointer data)
12872+static void 8240-{
12873+filter_combo_changed (GtkComboBox *combo_box,
12874+ GtkFileChooserDefault *impl)
12875 {
12876- GtkFileChooserDefault *impl = data; 8241- GtkFileChooserDefault *impl = data;
12877- GtkTreeIter filter_iter; 8242- GtkTreeIter filter_iter;
12878- ShortcutType shortcut_type; 8243- ShortcutType shortcut_type;
@@ -12881,15 +8246,15 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
12881- g_assert_not_reached (); 8246- g_assert_not_reached ();
12882- 8247-
12883- gtk_tree_model_get (impl->shortcuts_pane_filter_model, &filter_iter, SHORTCUTS_COL_TYPE, &shortcut_type, -1); 8248- gtk_tree_model_get (impl->shortcuts_pane_filter_model, &filter_iter, SHORTCUTS_COL_TYPE, &shortcut_type, -1);
12884+ gint new_index = gtk_combo_box_get_active (combo_box); 8249-
12885+ GtkFileFilter *new_filter = g_slist_nth_data (impl->filters, new_index);
12886
12887- return shortcut_type != SHORTCUT_TYPE_SEPARATOR; 8250- return shortcut_type != SHORTCUT_TYPE_SEPARATOR;
12888+ set_current_filter (impl, new_filter); 8251-}
12889 } 8252-
12890 8253-static gboolean
12891 static gboolean 8254 list_select_func (GtkTreeSelection *selection,
12892@@ -10562,55 +4490,17 @@ 8255 GtkTreeModel *model,
8256 GtkTreePath *path,
8257@@ -10556,55 +4490,17 @@
12893 impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER) 8258 impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)
12894 { 8259 {
12895 GtkTreeIter iter, child_iter; 8260 GtkTreeIter iter, child_iter;
@@ -12900,10 +8265,15 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
12900- case OPERATION_MODE_SEARCH: 8265- case OPERATION_MODE_SEARCH:
12901- { 8266- {
12902- gboolean is_folder; 8267- gboolean is_folder;
12903- 8268+ if (!gtk_tree_model_get_iter (GTK_TREE_MODEL (impl->sort_model), &iter, path))
8269+ return FALSE;
8270+
8271+ gtk_tree_model_sort_convert_iter_to_child_iter (impl->sort_model, &child_iter, &iter);
8272
12904- if (!gtk_tree_model_get_iter (GTK_TREE_MODEL (impl->search_model_sort), &iter, path)) 8273- if (!gtk_tree_model_get_iter (GTK_TREE_MODEL (impl->search_model_sort), &iter, path))
12905- return FALSE; 8274- return FALSE;
12906- 8275+ info = _gtk_file_system_model_get_info (impl->browse_files_model, &child_iter);
8276
12907- search_get_valid_child_iter (impl, &child_iter, &iter); 8277- search_get_valid_child_iter (impl, &child_iter, &iter);
12908- gtk_tree_model_get (GTK_TREE_MODEL (impl->search_model), &child_iter, 8278- gtk_tree_model_get (GTK_TREE_MODEL (impl->search_model), &child_iter,
12909- SEARCH_MODEL_COL_IS_FOLDER, &is_folder, 8279- SEARCH_MODEL_COL_IS_FOLDER, &is_folder,
@@ -12943,19 +8313,12 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
12943- } 8313- }
12944- break; 8314- break;
12945- } 8315- }
12946+ if (!gtk_tree_model_get_iter (GTK_TREE_MODEL (impl->sort_model), &iter, path))
12947+ return FALSE;
12948+
12949+ gtk_tree_model_sort_convert_iter_to_child_iter (impl->sort_model, &child_iter, &iter);
12950+
12951+ info = _gtk_file_system_model_get_info (impl->browse_files_model, &child_iter);
12952+
12953+ if (info && !gtk_file_info_get_is_folder (info)) 8316+ if (info && !gtk_file_info_get_is_folder (info))
12954+ return FALSE; 8317+ return FALSE;
12955 } 8318 }
12956 8319
12957 return TRUE; 8320 return TRUE;
12958@@ -10621,8 +4511,7 @@ 8321@@ -10615,8 +4511,7 @@
12959 GtkFileChooserDefault *impl) 8322 GtkFileChooserDefault *impl)
12960 { 8323 {
12961 /* See if we are in the new folder editable row for Save mode */ 8324 /* 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
12965 { 8328 {
12966 const GtkFileInfo *info; 8329 const GtkFileInfo *info;
12967 gboolean had_selection; 8330 gboolean had_selection;
12968@@ -10640,9 +4529,6 @@ 8331@@ -10634,9 +4529,6 @@
12969 if (impl->location_entry) 8332 if (impl->location_entry)
12970 update_chooser_entry (impl); 8333 update_chooser_entry (impl);
12971 8334
@@ -12975,7 +8338,7 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
12975 g_signal_emit_by_name (impl, "selection-changed", 0); 8338 g_signal_emit_by_name (impl, "selection-changed", 0);
12976 } 8339 }
12977 8340
12978@@ -10653,107 +4539,30 @@ 8341@@ -10647,107 +4539,30 @@
12979 GtkTreeViewColumn *column, 8342 GtkTreeViewColumn *column,
12980 GtkFileChooserDefault *impl) 8343 GtkFileChooserDefault *impl)
12981 { 8344 {
@@ -13031,7 +8394,8 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
13031- RECENT_MODEL_COL_PATH, &file_path, 8394- RECENT_MODEL_COL_PATH, &file_path,
13032- RECENT_MODEL_COL_IS_FOLDER, &is_folder, 8395- RECENT_MODEL_COL_IS_FOLDER, &is_folder,
13033- -1); 8396- -1);
13034- 8397+ change_folder_and_display_error (impl, file_path);
8398
13035- if (is_folder) 8399- if (is_folder)
13036- { 8400- {
13037- change_folder_and_display_error (impl, file_path, FALSE); 8401- change_folder_and_display_error (impl, file_path, FALSE);
@@ -13045,8 +8409,7 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
13045- case OPERATION_MODE_BROWSE: 8409- case OPERATION_MODE_BROWSE:
13046- { 8410- {
13047- const GtkFileInfo *info; 8411- const GtkFileInfo *info;
13048+ change_folder_and_display_error (impl, file_path); 8412-
13049
13050- if (!gtk_tree_model_get_iter (GTK_TREE_MODEL (impl->sort_model), &iter, path)) 8413- if (!gtk_tree_model_get_iter (GTK_TREE_MODEL (impl->sort_model), &iter, path))
13051- return; 8414- return;
13052- 8415-
@@ -13072,7 +8435,7 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
13072+ return; 8435+ return;
13073 } 8436 }
13074-} 8437-}
13075- 8438
13076-static void 8439-static void
13077-path_bar_clicked (GtkPathBar *path_bar, 8440-path_bar_clicked (GtkPathBar *path_bar,
13078- GtkFilePath *file_path, 8441- GtkFilePath *file_path,
@@ -13082,7 +8445,7 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
13082-{ 8445-{
13083- if (child_path) 8446- if (child_path)
13084- pending_select_paths_add (impl, child_path); 8447- pending_select_paths_add (impl, child_path);
13085 8448-
13086- if (!change_folder_and_display_error (impl, file_path, FALSE)) 8449- if (!change_folder_and_display_error (impl, file_path, FALSE))
13087- return; 8450- return;
13088- 8451-
@@ -13098,7 +8461,7 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
13098 } 8461 }
13099 8462
13100 static const GtkFileInfo * 8463 static const GtkFileInfo *
13101@@ -10778,83 +4587,40 @@ 8464@@ -10772,83 +4587,40 @@
13102 { 8465 {
13103 GtkFileChooserDefault *impl = data; 8466 GtkFileChooserDefault *impl = data;
13104 GtkTreeIter child_iter; 8467 GtkTreeIter child_iter;
@@ -13116,7 +8479,8 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
13116- { 8479- {
13117- GtkTreeIter child_iter; 8480- GtkTreeIter child_iter;
13118- gboolean is_folder; 8481- gboolean is_folder;
13119- 8482+ info = get_list_file_info (impl, iter);
8483
13120- search_get_valid_child_iter (impl, &child_iter, iter); 8484- search_get_valid_child_iter (impl, &child_iter, iter);
13121- gtk_tree_model_get (GTK_TREE_MODEL (impl->search_model), &child_iter, 8485- gtk_tree_model_get (GTK_TREE_MODEL (impl->search_model), &child_iter,
13122- SEARCH_MODEL_COL_PIXBUF, &pixbuf, 8486- SEARCH_MODEL_COL_PIXBUF, &pixbuf,
@@ -13128,14 +8492,20 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
13128- sensitive = is_folder; 8492- sensitive = is_folder;
13129- } 8493- }
13130- break; 8494- break;
13131+ info = get_list_file_info (impl, iter); 8495+ gtk_tree_model_sort_convert_iter_to_child_iter (impl->sort_model,
8496+ &child_iter,
8497+ iter);
8498+ path = _gtk_file_system_model_get_path (impl->browse_files_model, &child_iter);
13132 8499
13133- case OPERATION_MODE_RECENT: 8500- case OPERATION_MODE_RECENT:
13134- { 8501- {
13135- GtkTreeIter child_iter; 8502- GtkTreeIter child_iter;
13136- GtkRecentInfo *info; 8503- GtkRecentInfo *info;
13137- gboolean is_folder; 8504- gboolean is_folder;
13138- 8505+ if (path)
8506+ {
8507+ pixbuf = NULL;
8508
13139- recent_get_valid_child_iter (impl, &child_iter, iter); 8509- recent_get_valid_child_iter (impl, &child_iter, iter);
13140- gtk_tree_model_get (GTK_TREE_MODEL (impl->recent_model), &child_iter, 8510- gtk_tree_model_get (GTK_TREE_MODEL (impl->recent_model), &child_iter,
13141- RECENT_MODEL_COL_INFO, &info, 8511- RECENT_MODEL_COL_INFO, &info,
@@ -13154,16 +8524,9 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
13154- { 8524- {
13155- const GtkFileInfo *info; 8525- const GtkFileInfo *info;
13156- const GtkFilePath *path; 8526- const GtkFilePath *path;
13157+ gtk_tree_model_sort_convert_iter_to_child_iter (impl->sort_model, 8527-
13158+ &child_iter,
13159+ iter);
13160+ path = _gtk_file_system_model_get_path (impl->browse_files_model, &child_iter);
13161
13162- info = get_list_file_info (impl, iter); 8528- info = get_list_file_info (impl, iter);
13163+ if (path) 8529-
13164+ {
13165+ pixbuf = NULL;
13166
13167- gtk_tree_model_sort_convert_iter_to_child_iter (impl->sort_model, 8530- gtk_tree_model_sort_convert_iter_to_child_iter (impl->sort_model,
13168- &child_iter, 8531- &child_iter,
13169- iter); 8532- iter);
@@ -13195,12 +8558,12 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
13195+ pixbuf = gtk_file_info_render_icon (info, GTK_WIDGET (impl), 8558+ pixbuf = gtk_file_info_render_icon (info, GTK_WIDGET (impl),
13196+ impl->icon_size, NULL); 8559+ impl->icon_size, NULL);
13197+ } 8560+ }
13198+ } 8561 }
13199+ else 8562+ else
13200+ { 8563+ {
13201+ /* We are on the editable row */ 8564+ /* We are on the editable row */
13202+ pixbuf = NULL; 8565+ pixbuf = NULL;
13203 } 8566+ }
13204+ 8567+
13205+ if (info && (impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER || 8568+ if (info && (impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER ||
13206+ impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)) 8569+ impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER))
@@ -13208,24 +8571,14 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
13208 8571
13209 g_object_set (cell, 8572 g_object_set (cell,
13210 "pixbuf", pixbuf, 8573 "pixbuf", pixbuf,
13211@@ -10864,96 +4630,32 @@ 8574@@ -10869,85 +4641,21 @@
13212 if (pixbuf) 8575 gpointer data)
13213 g_object_unref (pixbuf); 8576 {
13214 8577 GtkFileChooserDefault *impl = data;
13215- profile_end ("end", NULL);
13216-}
13217-
13218-static void
13219-list_name_data_func (GtkTreeViewColumn *tree_column,
13220- GtkCellRenderer *cell,
13221- GtkTreeModel *tree_model,
13222- GtkTreeIter *iter,
13223- gpointer data)
13224-{
13225- GtkFileChooserDefault *impl = data;
13226- const GtkFileInfo *info; 8578- const GtkFileInfo *info;
13227- gboolean sensitive = TRUE; 8579+ const GtkFileInfo *info = get_list_file_info (impl, iter);
13228- 8580 gboolean sensitive = TRUE;
8581
13229- if (impl->operation_mode == OPERATION_MODE_SEARCH) 8582- if (impl->operation_mode == OPERATION_MODE_SEARCH)
13230- { 8583- {
13231- GtkTreeIter child_iter; 8584- GtkTreeIter child_iter;
@@ -13287,20 +8640,7 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
13287- 8640-
13288- info = get_list_file_info (impl, iter); 8641- info = get_list_file_info (impl, iter);
13289- sensitive = TRUE; 8642- sensitive = TRUE;
13290+ profile_end ("end", NULL); 8643-
13291+}
13292+
13293+static void
13294+list_name_data_func (GtkTreeViewColumn *tree_column,
13295+ GtkCellRenderer *cell,
13296+ GtkTreeModel *tree_model,
13297+ GtkTreeIter *iter,
13298+ gpointer data)
13299+{
13300+ GtkFileChooserDefault *impl = data;
13301+ const GtkFileInfo *info = get_list_file_info (impl, iter);
13302+ gboolean sensitive = TRUE;
13303
13304 if (!info) 8644 if (!info)
13305 { 8645 {
13306 g_object_set (cell, 8646 g_object_set (cell,
@@ -13320,7 +8660,7 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
13320 { 8660 {
13321 sensitive = gtk_file_info_get_is_folder (info); 8661 sensitive = gtk_file_info_get_is_folder (info);
13322 } 8662 }
13323@@ -10961,7 +4663,6 @@ 8663@@ -10955,7 +4663,6 @@
13324 g_object_set (cell, 8664 g_object_set (cell,
13325 "text", gtk_file_info_get_display_name (info), 8665 "text", gtk_file_info_get_display_name (info),
13326 "sensitive", sensitive, 8666 "sensitive", sensitive,
@@ -13328,7 +8668,7 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
13328 NULL); 8668 NULL);
13329 } 8669 }
13330 8670
13331@@ -11023,142 +4724,64 @@ 8671@@ -11017,142 +4724,64 @@
13332 gpointer data) 8672 gpointer data)
13333 { 8673 {
13334 GtkFileChooserDefault *impl; 8674 GtkFileChooserDefault *impl;
@@ -13344,7 +8684,9 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
13344 impl = data; 8684 impl = data;
13345 8685
13346- if (impl->operation_mode == OPERATION_MODE_SEARCH) 8686- if (impl->operation_mode == OPERATION_MODE_SEARCH)
13347- { 8687+ info = get_list_file_info (impl, iter);
8688+ if (!info)
8689 {
13348- GtkTreeIter child_iter; 8690- GtkTreeIter child_iter;
13349- struct stat *statbuf; 8691- struct stat *statbuf;
13350- gboolean is_folder; 8692- gboolean is_folder;
@@ -13363,21 +8705,25 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
13363- if (impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER || 8705- if (impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER ||
13364- impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER) 8706- impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)
13365- sensitive = is_folder; 8707- sensitive = is_folder;
13366- } 8708+ g_object_set (cell,
8709+ "text", "",
8710+ "sensitive", TRUE,
8711+ NULL);
8712+ return;
8713 }
13367- else if (impl->operation_mode == OPERATION_MODE_RECENT) 8714- else if (impl->operation_mode == OPERATION_MODE_RECENT)
13368+ info = get_list_file_info (impl, iter); 8715- {
13369+ if (!info)
13370 {
13371- GtkTreeIter child_iter; 8716- GtkTreeIter child_iter;
13372- GtkRecentInfo *info; 8717- GtkRecentInfo *info;
13373- gboolean is_folder; 8718- gboolean is_folder;
13374- 8719
13375- recent_get_valid_child_iter (impl, &child_iter, iter); 8720- recent_get_valid_child_iter (impl, &child_iter, iter);
13376- gtk_tree_model_get (GTK_TREE_MODEL (impl->recent_model), &child_iter, 8721- gtk_tree_model_get (GTK_TREE_MODEL (impl->recent_model), &child_iter,
13377- RECENT_MODEL_COL_INFO, &info, 8722- RECENT_MODEL_COL_INFO, &info,
13378- RECENT_MODEL_COL_IS_FOLDER, &is_folder, 8723- RECENT_MODEL_COL_IS_FOLDER, &is_folder,
13379- -1); 8724- -1);
13380- 8725+ time_mtime = gtk_file_info_get_modification_time (info);
8726
13381- if (info) 8727- if (info)
13382- time_mtime = gtk_recent_info_get_modified (info); 8728- time_mtime = gtk_recent_info_get_modified (info);
13383- else 8729- else
@@ -13386,14 +8732,11 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
13386- if (impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER || 8732- if (impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER ||
13387- impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER) 8733- impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)
13388- sensitive = is_folder; 8734- sensitive = is_folder;
13389+ g_object_set (cell, 8735- }
13390+ "text", "", 8736+ if (time_mtime == 0)
13391+ "sensitive", TRUE, 8737+ strcpy (buf, _("Unknown"));
13392+ NULL); 8738 else
13393+ return; 8739 {
13394 }
13395- else
13396- {
13397- const GtkFileInfo *info; 8740- const GtkFileInfo *info;
13398- 8741-
13399- info = get_list_file_info (impl, iter); 8742- info = get_list_file_info (impl, iter);
@@ -13407,19 +8750,16 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
13407- } 8750- }
13408- 8751-
13409- time_mtime = (time_t) gtk_file_info_get_modification_time (info); 8752- time_mtime = (time_t) gtk_file_info_get_modification_time (info);
13410 8753-
13411- if (impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER || 8754- if (impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER ||
13412- impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER) 8755- impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)
13413- sensitive = gtk_file_info_get_is_folder (info); 8756- sensitive = gtk_file_info_get_is_folder (info);
13414- } 8757- }
13415+ time_mtime = gtk_file_info_get_modification_time (info); 8758-
13416
13417- if (G_UNLIKELY (time_mtime == 0)) 8759- if (G_UNLIKELY (time_mtime == 0))
13418- date_str = g_strdup (_("Unknown")); 8760- date_str = g_strdup (_("Unknown"));
13419+ if (time_mtime == 0) 8761- else
13420+ strcpy (buf, _("Unknown")); 8762- {
13421 else
13422 {
13423- GDate mtime, now; 8763- GDate mtime, now;
13424- gint days_diff; 8764- gint days_diff;
13425- struct tm tm_mtime; 8765- struct tm tm_mtime;
@@ -13471,9 +8811,9 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
13471 else 8811 else
13472 format = "%x"; /* Any other date */ 8812 format = "%x"; /* Any other date */
13473- } 8813- }
13474-
13475- locale_format = g_locale_from_utf8 (format, -1, NULL, NULL, NULL);
13476 8814
8815- locale_format = g_locale_from_utf8 (format, -1, NULL, NULL, NULL);
8816-
13477- if (strftime (buf, sizeof (buf), locale_format, &tm_mtime) != 0) 8817- if (strftime (buf, sizeof (buf), locale_format, &tm_mtime) != 0)
13478- date_str = g_locale_to_utf8 (buf, -1, NULL, NULL, NULL); 8818- date_str = g_locale_to_utf8 (buf, -1, NULL, NULL, NULL);
13479- else 8819- else
@@ -13498,18 +8838,22 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
13498 } 8838 }
13499 8839
13500 GtkWidget * 8840 GtkWidget *
13501@@ -11169,437 +4792,73 @@ 8841@@ -11163,437 +4792,73 @@
13502 NULL); 8842 NULL);
13503 } 8843 }
13504 8844
13505-static void 8845+/* Handler for the "up-folder" keybinding signal */
8846 static void
13506-location_set_user_text (GtkFileChooserDefault *impl, 8847-location_set_user_text (GtkFileChooserDefault *impl,
13507- const gchar *path) 8848- const gchar *path)
13508-{ 8849+up_folder_handler (GtkFileChooserDefault *impl)
8850 {
13509- _gtk_file_chooser_entry_set_file_part (GTK_FILE_CHOOSER_ENTRY (impl->location_entry), path); 8851- _gtk_file_chooser_entry_set_file_part (GTK_FILE_CHOOSER_ENTRY (impl->location_entry), path);
13510- gtk_editable_set_position (GTK_EDITABLE (impl->location_entry), -1); 8852- gtk_editable_set_position (GTK_EDITABLE (impl->location_entry), -1);
13511-} 8853-}
13512- 8854+ GtkFilePath * parent;
8855+ pending_select_paths_add (impl, impl->current_folder);
8856
13513-static void 8857-static void
13514-location_popup_handler (GtkFileChooserDefault *impl, 8858-location_popup_handler (GtkFileChooserDefault *impl,
13515- const gchar *path) 8859- const gchar *path)
@@ -13531,7 +8875,12 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
13531- g_assert_not_reached (); 8875- g_assert_not_reached ();
13532- break; 8876- break;
13533- } 8877- }
13534- 8878+ if (gtk_file_system_get_parent (impl->file_system, impl->current_folder,
8879+ &parent, NULL) && parent)
8880+ {
8881+ impl->path_history = g_slist_prepend (impl->path_history,
8882+ gtk_file_path_copy (impl->current_folder));
8883
13535- if (impl->current_folder) 8884- if (impl->current_folder)
13536- change_folder_and_display_error (impl, impl->current_folder, FALSE); 8885- change_folder_and_display_error (impl, impl->current_folder, FALSE);
13537- 8886-
@@ -13585,34 +8934,28 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
13585- } 8934- }
13586- else 8935- else
13587- g_assert_not_reached (); 8936- g_assert_not_reached ();
13588-}
13589-
13590 /* Handler for the "up-folder" keybinding signal */
13591 static void
13592 up_folder_handler (GtkFileChooserDefault *impl)
13593 {
13594- _gtk_path_bar_up (GTK_PATH_BAR (impl->browse_path_bar));
13595+ GtkFilePath * parent;
13596+ pending_select_paths_add (impl, impl->current_folder);
13597+
13598+ if (gtk_file_system_get_parent (impl->file_system, impl->current_folder,
13599+ &parent, NULL) && parent)
13600+ {
13601+ impl->path_history = g_slist_prepend (impl->path_history,
13602+ gtk_file_path_copy (impl->current_folder));
13603+
13604+ change_folder_and_display_error (impl, parent); 8937+ change_folder_and_display_error (impl, parent);
13605+ gtk_file_path_free (parent); 8938+ gtk_file_path_free (parent);
13606+ } 8939+ }
13607 } 8940 }
13608 8941
8942-/* Handler for the "up-folder" keybinding signal */
8943-static void
8944-up_folder_handler (GtkFileChooserDefault *impl)
8945-{
8946- _gtk_path_bar_up (GTK_PATH_BAR (impl->browse_path_bar));
8947-}
8948-
13609 /* Handler for the "down-folder" keybinding signal */ 8949 /* Handler for the "down-folder" keybinding signal */
13610 static void 8950 static void
13611 down_folder_handler (GtkFileChooserDefault *impl) 8951 down_folder_handler (GtkFileChooserDefault *impl)
13612 { 8952 {
13613- _gtk_path_bar_down (GTK_PATH_BAR (impl->browse_path_bar)); 8953- _gtk_path_bar_down (GTK_PATH_BAR (impl->browse_path_bar));
13614-} 8954-}
13615- 8955+ if (impl->path_history)
8956+ {
8957+ GtkFilePath * path = impl->path_history->data;
8958
13616-/* Switches to the shortcut in the specified index */ 8959-/* Switches to the shortcut in the specified index */
13617-static void 8960-static void
13618-switch_to_shortcut (GtkFileChooserDefault *impl, 8961-switch_to_shortcut (GtkFileChooserDefault *impl,
@@ -13625,10 +8968,6 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
13625- 8968-
13626- shortcuts_activate_iter (impl, &iter); 8969- shortcuts_activate_iter (impl, &iter);
13627- focus_browse_tree_view_if_possible (impl); 8970- focus_browse_tree_view_if_possible (impl);
13628+ if (impl->path_history)
13629+ {
13630+ GtkFilePath * path = impl->path_history->data;
13631+
13632+ change_folder_and_display_error (impl, path); 8971+ change_folder_and_display_error (impl, path);
13633+ impl->path_history = g_slist_remove (impl->path_history, path); 8972+ impl->path_history = g_slist_remove (impl->path_history, path);
13634+ gtk_file_path_free (path); 8973+ gtk_file_path_free (path);
@@ -13641,10 +8980,10 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
13641 { 8980 {
13642- if (impl->has_home) 8981- if (impl->has_home)
13643- switch_to_shortcut (impl, shortcuts_get_index (impl, SHORTCUTS_HOME)); 8982- switch_to_shortcut (impl, shortcuts_get_index (impl, SHORTCUTS_HOME));
13644-} 8983 }
13645- 8984
13646-/* Handler for the "desktop-folder" keybinding signal */ 8985-/* Handler for the "desktop-folder" keybinding signal */
13647-static void 8986 static void
13648-desktop_folder_handler (GtkFileChooserDefault *impl) 8987-desktop_folder_handler (GtkFileChooserDefault *impl)
13649-{ 8988-{
13650- if (impl->has_desktop) 8989- if (impl->has_desktop)
@@ -13694,24 +9033,27 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
13694- gtk_tree_path_free (path); 9033- gtk_tree_path_free (path);
13695- 9034-
13696- switch_to_shortcut (impl, bookmark_pos); 9035- switch_to_shortcut (impl, bookmark_pos);
13697 } 9036-}
13698 9037-
13699 static void 9038-static void
13700 show_hidden_handler (GtkFileChooserDefault *impl) 9039 show_hidden_handler (GtkFileChooserDefault *impl)
13701 { 9040 {
13702- g_object_set (impl, 9041- g_object_set (impl,
13703- "show-hidden", !impl->show_hidden, 9042- "show-hidden", !impl->show_hidden,
13704- NULL); 9043- NULL);
13705-} 9044 }
13706- 9045
13707- 9046-
13708-/* Drag and drop interfaces */ 9047-/* Drag and drop interfaces */
13709- 9048-
13710-static void 9049-static void
13711-_shortcuts_pane_model_filter_class_init (ShortcutsPaneModelFilterClass *class) 9050-_shortcuts_pane_model_filter_class_init (ShortcutsPaneModelFilterClass *class)
13712-{ 9051+static GtkFilePath *
13713-} 9052+gtk_file_chooser_default_get_preview_path (GtkFileChooser *chooser)
13714- 9053 {
9054+ return NULL;
9055 }
9056
13715-static void 9057-static void
13716-_shortcuts_pane_model_filter_init (ShortcutsPaneModelFilter *model) 9058-_shortcuts_pane_model_filter_init (ShortcutsPaneModelFilter *model)
13717-{ 9059-{
@@ -13719,10 +9061,13 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
13719-} 9061-}
13720- 9062-
13721-/* GtkTreeDragSource::row_draggable implementation for the shortcuts filter model */ 9063-/* GtkTreeDragSource::row_draggable implementation for the shortcuts filter model */
13722-static gboolean 9064 static gboolean
13723-shortcuts_pane_model_filter_row_draggable (GtkTreeDragSource *drag_source, 9065-shortcuts_pane_model_filter_row_draggable (GtkTreeDragSource *drag_source,
13724- GtkTreePath *path) 9066- GtkTreePath *path)
13725-{ 9067+gtk_file_chooser_default_add_shortcut_folder (GtkFileChooser *chooser,
9068+ const GtkFilePath *path,
9069+ GError **error)
9070 {
13726- ShortcutsPaneModelFilter *model; 9071- ShortcutsPaneModelFilter *model;
13727- int pos; 9072- int pos;
13728- int bookmarks_pos; 9073- int bookmarks_pos;
@@ -13797,7 +9142,7 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
13797- 9142-
13798- model = RECENT_MODEL_SORT (drag_source); 9143- model = RECENT_MODEL_SORT (drag_source);
13799- if (!gtk_tree_model_get_iter (GTK_TREE_MODEL (model), &iter, path)) 9144- if (!gtk_tree_model_get_iter (GTK_TREE_MODEL (model), &iter, path))
13800- return FALSE; 9145 return FALSE;
13801- 9146-
13802- recent_get_valid_child_iter (model->impl, &child_iter, &iter); 9147- recent_get_valid_child_iter (model->impl, &child_iter, &iter);
13803- gtk_tree_model_get (GTK_TREE_MODEL (model->impl->recent_model), &child_iter, 9148- 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
13805- -1); 9150- -1);
13806- 9151-
13807- return is_folder; 9152- return is_folder;
13808-} 9153 }
13809- 9154
13810-static gboolean 9155 static gboolean
13811-recent_model_sort_drag_data_get (GtkTreeDragSource *drag_source, 9156-recent_model_sort_drag_data_get (GtkTreeDragSource *drag_source,
13812- GtkTreePath *path, 9157- GtkTreePath *path,
13813- GtkSelectionData *selection_data) 9158- GtkSelectionData *selection_data)
13814-{ 9159+gtk_file_chooser_default_remove_shortcut_folder (GtkFileChooser *chooser,
9160+ const GtkFilePath *path,
9161+ GError **error)
9162 {
13815- RecentModelSort *model; 9163- RecentModelSort *model;
13816- GtkTreeIter iter, child_iter; 9164- GtkTreeIter iter, child_iter;
13817- GtkFilePath *file_path; 9165- GtkFilePath *file_path;
@@ -13836,14 +9184,18 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
13836- g_strfreev (uris); 9184- g_strfreev (uris);
13837- 9185-
13838- return TRUE; 9186- return TRUE;
13839-} 9187+ return TRUE;
13840- 9188 }
9189
13841-static void 9190-static void
13842-recent_model_sort_drag_source_iface_init (GtkTreeDragSourceIface *iface) 9191-recent_model_sort_drag_source_iface_init (GtkTreeDragSourceIface *iface)
13843-{ 9192+static GSList *
9193+gtk_file_chooser_default_list_shortcut_folders (GtkFileChooser *chooser)
9194 {
13844- iface->row_draggable = recent_model_sort_row_draggable; 9195- iface->row_draggable = recent_model_sort_row_draggable;
13845- iface->drag_data_get = recent_model_sort_drag_data_get; 9196- iface->drag_data_get = recent_model_sort_drag_data_get;
13846-} 9197+ return NULL;
9198 }
13847- 9199-
13848-static void 9200-static void
13849-_recent_model_sort_class_init (RecentModelSortClass *klass) 9201-_recent_model_sort_class_init (RecentModelSortClass *klass)
@@ -13855,14 +9207,12 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
13855-_recent_model_sort_init (RecentModelSort *model) 9207-_recent_model_sort_init (RecentModelSort *model)
13856-{ 9208-{
13857- model->impl = NULL; 9209- model->impl = NULL;
13858 } 9210-}
13859 9211-
13860-static GtkTreeModel * 9212-static GtkTreeModel *
13861-recent_model_sort_new (GtkFileChooserDefault *impl, 9213-recent_model_sort_new (GtkFileChooserDefault *impl,
13862- GtkTreeModel *child_model) 9214- GtkTreeModel *child_model)
13863+static GtkFilePath * 9215-{
13864+gtk_file_chooser_default_get_preview_path (GtkFileChooser *chooser)
13865 {
13866- RecentModelSort *model; 9216- RecentModelSort *model;
13867- 9217-
13868- model = g_object_new (RECENT_MODEL_SORT_TYPE, 9218- model = g_object_new (RECENT_MODEL_SORT_TYPE,
@@ -13871,25 +9221,21 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
13871- model->impl = impl; 9221- model->impl = impl;
13872- 9222-
13873- return GTK_TREE_MODEL (model); 9223- return GTK_TREE_MODEL (model);
13874+ return NULL; 9224-}
13875 } 9225-
13876
13877- 9226-
13878- 9227-
13879 static gboolean 9228-static gboolean
13880-search_model_sort_row_draggable (GtkTreeDragSource *drag_source, 9229-search_model_sort_row_draggable (GtkTreeDragSource *drag_source,
13881- GtkTreePath *path) 9230- GtkTreePath *path)
13882+gtk_file_chooser_default_add_shortcut_folder (GtkFileChooser *chooser, 9231-{
13883+ const GtkFilePath *path,
13884+ GError **error)
13885 {
13886- SearchModelSort *model; 9232- SearchModelSort *model;
13887- GtkTreeIter iter, child_iter; 9233- GtkTreeIter iter, child_iter;
13888- gboolean is_folder; 9234- gboolean is_folder;
13889- 9235-
13890- model = SEARCH_MODEL_SORT (drag_source); 9236- model = SEARCH_MODEL_SORT (drag_source);
13891- if (!gtk_tree_model_get_iter (GTK_TREE_MODEL (model), &iter, path)) 9237- if (!gtk_tree_model_get_iter (GTK_TREE_MODEL (model), &iter, path))
13892 return FALSE; 9238- return FALSE;
13893- 9239-
13894- search_get_valid_child_iter (model->impl, &child_iter, &iter); 9240- search_get_valid_child_iter (model->impl, &child_iter, &iter);
13895- gtk_tree_model_get (GTK_TREE_MODEL (model->impl->search_model), &child_iter, 9241- 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
13897- -1); 9243- -1);
13898- 9244-
13899- return is_folder; 9245- return is_folder;
13900 } 9246-}
13901 9247-
13902 static gboolean 9248-static gboolean
13903-search_model_sort_drag_data_get (GtkTreeDragSource *drag_source, 9249-search_model_sort_drag_data_get (GtkTreeDragSource *drag_source,
13904- GtkTreePath *path, 9250- GtkTreePath *path,
13905- GtkSelectionData *selection_data) 9251- GtkSelectionData *selection_data)
@@ -13945,20 +9291,14 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
13945- 9291-
13946-static void 9292-static void
13947-_search_model_sort_init (SearchModelSort *model) 9293-_search_model_sort_init (SearchModelSort *model)
13948+gtk_file_chooser_default_remove_shortcut_folder (GtkFileChooser *chooser, 9294-{
13949+ const GtkFilePath *path,
13950+ GError **error)
13951 {
13952- model->impl = NULL; 9295- model->impl = NULL;
13953+ return TRUE; 9296-}
13954 } 9297-
13955
13956-static GtkTreeModel * 9298-static GtkTreeModel *
13957-search_model_sort_new (GtkFileChooserDefault *impl, 9299-search_model_sort_new (GtkFileChooserDefault *impl,
13958- GtkTreeModel *child_model) 9300- GtkTreeModel *child_model)
13959+static GSList * 9301-{
13960+gtk_file_chooser_default_list_shortcut_folders (GtkFileChooser *chooser)
13961 {
13962- SearchModelSort *model; 9302- SearchModelSort *model;
13963- 9303-
13964- model = g_object_new (SEARCH_MODEL_SORT_TYPE, 9304- model = g_object_new (SEARCH_MODEL_SORT_TYPE,
@@ -13967,12 +9307,11 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserdefault.c
13967- model->impl = impl; 9307- model->impl = impl;
13968- 9308-
13969- return GTK_TREE_MODEL (model); 9309- return GTK_TREE_MODEL (model);
13970+ return NULL; 9310-}
13971 } 9311Index: gtk+-2.12.5/gtk/gtkfilechooserprivate.h
13972Index: gtk+-2.12.3/gtk/gtkfilechooserprivate.h
13973=================================================================== 9312===================================================================
13974--- gtk+-2.12.3.orig/gtk/gtkfilechooserprivate.h 2007-12-04 16:52:08.000000000 +0000 9313--- gtk+-2.12.5/gtk/gtkfilechooserprivate.h (revision 19337)
13975+++ gtk+-2.12.3/gtk/gtkfilechooserprivate.h 2008-01-04 10:11:20.000000000 +0000 9314+++ gtk+-2.12.5/gtk/gtkfilechooserprivate.h (working copy)
13976@@ -25,9 +25,6 @@ 9315@@ -25,9 +25,6 @@
13977 #include "gtkfilesystem.h" 9316 #include "gtkfilesystem.h"
13978 #include "gtkfilesystemmodel.h" 9317 #include "gtkfilesystemmodel.h"
@@ -14000,12 +9339,12 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserprivate.h
14000 9339
14001 /* Save mode widgets */ 9340 /* Save mode widgets */
14002 GtkWidget *save_widgets; 9341 GtkWidget *save_widgets;
14003- 9342+ GtkWidget *save_file_name_entry;
9343
14004- GtkWidget *save_folder_label; 9344- GtkWidget *save_folder_label;
14005- GtkWidget *save_folder_combo; 9345- GtkWidget *save_folder_combo;
14006- GtkWidget *save_expander; 9346- GtkWidget *save_expander;
14007+ GtkWidget *save_file_name_entry; 9347-
14008
14009 /* The file browsing widgets */ 9348 /* The file browsing widgets */
14010 GtkWidget *browse_widgets; 9349 GtkWidget *browse_widgets;
14011- GtkWidget *browse_shortcuts_tree_view; 9350- GtkWidget *browse_shortcuts_tree_view;
@@ -14058,7 +9397,8 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserprivate.h
14058 LocationMode location_mode; 9397 LocationMode location_mode;
14059 9398
14060 GtkListStore *shortcuts_model; 9399 GtkListStore *shortcuts_model;
14061- 9400+ GtkTreeModel *shortcuts_filter_model;
9401
14062- /* Filter for the shortcuts pane. We filter out the "current folder" row and 9402- /* Filter for the shortcuts pane. We filter out the "current folder" row and
14063- * the separator that we use for the "Save in folder" combo. 9403- * the separator that we use for the "Save in folder" combo.
14064- */ 9404- */
@@ -14068,8 +9408,7 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserprivate.h
14068- * its separator. 9408- * its separator.
14069- */ 9409- */
14070- GtkTreeModel *shortcuts_combo_filter_model; 9410- GtkTreeModel *shortcuts_combo_filter_model;
14071+ GtkTreeModel *shortcuts_filter_model; 9411-
14072
14073 GtkTreeModelSort *sort_model; 9412 GtkTreeModelSort *sort_model;
14074 9413
14075 /* Handles */ 9414 /* Handles */
@@ -14150,10 +9489,10 @@ Index: gtk+-2.12.3/gtk/gtkfilechooserprivate.h
14150 }; 9489 };
14151 9490
14152 9491
14153Index: gtk+-2.12.3/tests/autotestfilechooser.c 9492Index: gtk+-2.12.5/tests/autotestfilechooser.c
14154=================================================================== 9493===================================================================
14155--- gtk+-2.12.3.orig/tests/autotestfilechooser.c 2007-12-04 16:52:18.000000000 +0000 9494--- gtk+-2.12.5/tests/autotestfilechooser.c (revision 19337)
14156+++ gtk+-2.12.3/tests/autotestfilechooser.c 2008-01-02 13:26:09.000000000 +0000 9495+++ gtk+-2.12.5/tests/autotestfilechooser.c (working copy)
14157@@ -510,9 +510,6 @@ 9496@@ -510,9 +510,6 @@
14158 && (impl->location_mode == LOCATION_MODE_PATH_BAR 9497 && (impl->location_mode == LOCATION_MODE_PATH_BAR
14159 ? impl->location_entry == NULL 9498 ? 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