summaryrefslogtreecommitdiffstats
path: root/meta/recipes-gnome/gtk+/gtk+-2.12.7/filechooser-default.patch
diff options
context:
space:
mode:
authorRichard Purdie <rpurdie@linux.intel.com>2010-08-27 15:14:24 +0100
committerRichard Purdie <rpurdie@linux.intel.com>2010-08-27 15:29:45 +0100
commit29d6678fd546377459ef75cf54abeef5b969b5cf (patch)
tree8edd65790e37a00d01c3f203f773fe4b5012db18 /meta/recipes-gnome/gtk+/gtk+-2.12.7/filechooser-default.patch
parentda49de6885ee1bc424e70bc02f21f6ab920efb55 (diff)
downloadpoky-29d6678fd546377459ef75cf54abeef5b969b5cf.tar.gz
Major layout change to the packages directory
Having one monolithic packages directory makes it hard to find things and is generally overwhelming. This commit splits it into several logical sections roughly based on function, recipes.txt gives more information about the classifications used. The opportunity is also used to switch from "packages" to "recipes" as used in OpenEmbedded as the term "packages" can be confusing to people and has many different meanings. Not all recipes have been classified yet, this is just a first pass at separating things out. Some packages are moved to meta-extras as they're no longer actively used or maintained. Signed-off-by: Richard Purdie <rpurdie@linux.intel.com>
Diffstat (limited to 'meta/recipes-gnome/gtk+/gtk+-2.12.7/filechooser-default.patch')
-rw-r--r--meta/recipes-gnome/gtk+/gtk+-2.12.7/filechooser-default.patch9521
1 files changed, 9521 insertions, 0 deletions
diff --git a/meta/recipes-gnome/gtk+/gtk+-2.12.7/filechooser-default.patch b/meta/recipes-gnome/gtk+/gtk+-2.12.7/filechooser-default.patch
new file mode 100644
index 0000000000..146316c9c1
--- /dev/null
+++ b/meta/recipes-gnome/gtk+/gtk+-2.12.7/filechooser-default.patch
@@ -0,0 +1,9521 @@
1Index: gtk+-2.12.5/gtk/gtkfilechooserdefault.c
2================ ===================================================
3--- gtk+-2.12.5/gtk/gtkfilechooserdefault.c (revision 19337)
4+++ gtk+-2.12.5/gtk/gtkfilechooserdefault.c (working copy)
5@@ -27,12 +27,12 @@
6 #include "gtkcelllayout.h"
7 #include "gtkcellrendererpixbuf.h"
8 #include "gtkcellrenderertext.h"
9+#include "gtkcellrenderertext.h"
10 #include "gtkcheckmenuitem.h"
11 #include "gtkclipboard.h"
12 #include "gtkcombobox.h"
13 #include "gtkentry.h"
14 #include "gtkeventbox.h"
15-#include "gtkexpander.h"
16 #include "gtkfilechooserprivate.h"
17 #include "gtkfilechooserdefault.h"
18 #include "gtkfilechooserembed.h"
19@@ -53,17 +53,13 @@
20 #include "gtkmarshalers.h"
21 #include "gtkmenuitem.h"
22 #include "gtkmessagedialog.h"
23-#include "gtkpathbar.h"
24 #include "gtkprivate.h"
25 #include "gtkradiobutton.h"
26-#include "gtkrecentfilter.h"
27-#include "gtkrecentmanager.h"
28 #include "gtkscrolledwindow.h"
29 #include "gtkseparatormenuitem.h"
30 #include "gtksizegroup.h"
31 #include "gtkstock.h"
32 #include "gtktable.h"
33-#include "gtktooltip.h"
34 #include "gtktreednd.h"
35 #include "gtktreeprivate.h"
36 #include "gtktreeselection.h"
37@@ -81,8 +77,6 @@
38 #include <errno.h>
39 #include <string.h>
40 #include <time.h>
41-#include <sys/stat.h>
42-#include <sys/types.h>
43
44
45 #ifdef HAVE_UNISTD_H
46@@ -92,6 +86,8 @@
47 #include <io.h>
48 #endif
49
50+#define DEFAULT_SPACING 5
51+
52 /* Profiling stuff */
53 #undef PROFILE_FILE_CHOOSER
54 #ifdef PROFILE_FILE_CHOOSER
55@@ -150,6 +145,7 @@
56 #define GTK_FILE_CHOOSER_DEFAULT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_FILE_CHOOSER_DEFAULT, GtkFileChooserDefaultClass))
57
58 #define MAX_LOADING_TIME 500
59+#define LONG_CLICK_LENGTH 500
60
61 struct _GtkFileChooserDefaultClass
62 {
63@@ -163,38 +159,12 @@
64 UP_FOLDER,
65 DOWN_FOLDER,
66 HOME_FOLDER,
67- DESKTOP_FOLDER,
68- QUICK_BOOKMARK,
69- LOCATION_TOGGLE_POPUP,
70 SHOW_HIDDEN,
71- SEARCH_SHORTCUT,
72- RECENT_SHORTCUT,
73-
74 LAST_SIGNAL
75 };
76
77 static guint signals[LAST_SIGNAL] = { 0 };
78
79-/* Column numbers for the shortcuts tree. Keep these in sync with shortcuts_model_create() */
80-enum {
81- SHORTCUTS_COL_PIXBUF,
82- SHORTCUTS_COL_NAME,
83- SHORTCUTS_COL_DATA,
84- SHORTCUTS_COL_TYPE,
85- SHORTCUTS_COL_REMOVABLE,
86- SHORTCUTS_COL_PIXBUF_VISIBLE,
87- SHORTCUTS_COL_HANDLE,
88- SHORTCUTS_COL_NUM_COLUMNS
89-};
90-
91-typedef enum {
92- SHORTCUT_TYPE_PATH,
93- SHORTCUT_TYPE_VOLUME,
94- SHORTCUT_TYPE_SEPARATOR,
95- SHORTCUT_TYPE_SEARCH,
96- SHORTCUT_TYPE_RECENT
97-} ShortcutType;
98-
99 /* Column numbers for the file list */
100 enum {
101 FILE_LIST_COL_NAME,
102@@ -203,100 +173,10 @@
103 FILE_LIST_COL_NUM_COLUMNS
104 };
105
106-/* Column numbers for the search model.
107- * Keep this in sync with search_setup_model()
108- */
109-enum {
110- SEARCH_MODEL_COL_PATH,
111- SEARCH_MODEL_COL_DISPLAY_NAME,
112- SEARCH_MODEL_COL_COLLATION_KEY,
113- SEARCH_MODEL_COL_STAT,
114- SEARCH_MODEL_COL_HANDLE,
115- SEARCH_MODEL_COL_PIXBUF,
116- SEARCH_MODEL_COL_MIME_TYPE,
117- SEARCH_MODEL_COL_IS_FOLDER,
118- SEARCH_MODEL_COL_NUM_COLUMNS
119-};
120-
121-enum {
122- RECENT_MODEL_COL_PATH,
123- RECENT_MODEL_COL_DISPLAY_NAME,
124- RECENT_MODEL_COL_INFO,
125- RECENT_MODEL_COL_IS_FOLDER,
126- RECENT_MODEL_COL_HANDLE,
127- RECENT_MODEL_COL_NUM_COLUMNS
128-};
129-
130-/* Identifiers for target types */
131-enum {
132- GTK_TREE_MODEL_ROW,
133- TEXT_URI_LIST
134-};
135-
136-/* Target types for dragging from the shortcuts list */
137-static const GtkTargetEntry shortcuts_source_targets[] = {
138- { "GTK_TREE_MODEL_ROW", GTK_TARGET_SAME_WIDGET, GTK_TREE_MODEL_ROW }
139-};
140-
141-static const int num_shortcuts_source_targets = G_N_ELEMENTS (shortcuts_source_targets);
142-
143-/* Target types for dropping into the shortcuts list */
144-static const GtkTargetEntry shortcuts_dest_targets[] = {
145- { "GTK_TREE_MODEL_ROW", GTK_TARGET_SAME_WIDGET, GTK_TREE_MODEL_ROW },
146- { "text/uri-list", 0, TEXT_URI_LIST }
147-};
148-
149-static const int num_shortcuts_dest_targets = G_N_ELEMENTS (shortcuts_dest_targets);
150-
151-/* Target types for DnD from the file list */
152-static const GtkTargetEntry file_list_source_targets[] = {
153- { "text/uri-list", 0, TEXT_URI_LIST }
154-};
155-
156-static const int num_file_list_source_targets = G_N_ELEMENTS (file_list_source_targets);
157-
158-/* Target types for dropping into the file list */
159-static const GtkTargetEntry file_list_dest_targets[] = {
160- { "text/uri-list", 0, TEXT_URI_LIST }
161-};
162-
163-static const int num_file_list_dest_targets = G_N_ELEMENTS (file_list_dest_targets);
164-
165-/* Target types for dragging from the recent files list */
166-static const GtkTargetEntry recent_list_source_targets[] = {
167- { "text/uri-list", 0, TEXT_URI_LIST }
168-};
169-
170-static const int num_recent_list_source_targets = G_N_ELEMENTS (recent_list_source_targets);
171-
172-static gboolean
173-search_is_possible (GtkFileChooserDefault *impl)
174-{
175- if (impl->search_engine == NULL)
176- impl->search_engine = _gtk_search_engine_new ();
177-
178- return impl->search_engine != NULL;
179-}
180-
181-/* Interesting places in the shortcuts bar */
182-typedef enum {
183- SHORTCUTS_SEARCH,
184- SHORTCUTS_RECENT,
185- SHORTCUTS_RECENT_SEPARATOR,
186- SHORTCUTS_HOME,
187- SHORTCUTS_DESKTOP,
188- SHORTCUTS_VOLUMES,
189- SHORTCUTS_SHORTCUTS,
190- SHORTCUTS_BOOKMARKS_SEPARATOR,
191- SHORTCUTS_BOOKMARKS,
192- SHORTCUTS_CURRENT_FOLDER_SEPARATOR,
193- SHORTCUTS_CURRENT_FOLDER
194-} ShortcutsIndex;
195-
196 /* Icon size for if we can't get it from the theme */
197-#define FALLBACK_ICON_SIZE 16
198+#define FALLBACK_ICON_SIZE 24
199
200-#define PREVIEW_HBOX_SPACING 12
201+#define LIST_HBOX_SPACING DEFAULT_SPACING
202 #define NUM_LINES 45
203 #define NUM_CHARS 60
204
205@@ -369,52 +248,17 @@
206 static gboolean gtk_file_chooser_default_should_respond (GtkFileChooserEmbed *chooser_embed);
207 static void gtk_file_chooser_default_initial_focus (GtkFileChooserEmbed *chooser_embed);
208
209-static void location_popup_handler (GtkFileChooserDefault *impl,
210- const gchar *path);
211-static void location_popup_on_paste_handler (GtkFileChooserDefault *impl);
212-static void location_toggle_popup_handler (GtkFileChooserDefault *impl);
213-static void up_folder_handler (GtkFileChooserDefault *impl);
214-static void down_folder_handler (GtkFileChooserDefault *impl);
215-static void home_folder_handler (GtkFileChooserDefault *impl);
216-static void desktop_folder_handler (GtkFileChooserDefault *impl);
217-static void quick_bookmark_handler (GtkFileChooserDefault *impl,
218- gint bookmark_index);
219-static void show_hidden_handler (GtkFileChooserDefault *impl);
220-static void search_shortcut_handler (GtkFileChooserDefault *impl);
221-static void recent_shortcut_handler (GtkFileChooserDefault *impl);
222-static void update_appearance (GtkFileChooserDefault *impl);
223+static void up_folder_handler (GtkFileChooserDefault *impl);
224+static void down_folder_handler (GtkFileChooserDefault *impl);
225+static void home_folder_handler (GtkFileChooserDefault *impl);
226+static void show_hidden_handler (GtkFileChooserDefault *impl);
227+static void update_appearance (GtkFileChooserDefault *impl);
228
229-static void set_current_filter (GtkFileChooserDefault *impl,
230- GtkFileFilter *filter);
231-static void check_preview_change (GtkFileChooserDefault *impl);
232-
233 static void filter_combo_changed (GtkComboBox *combo_box,
234 GtkFileChooserDefault *impl);
235-static void shortcuts_row_activated_cb (GtkTreeView *tree_view,
236- GtkTreePath *path,
237- GtkTreeViewColumn *column,
238- GtkFileChooserDefault *impl);
239
240-static gboolean shortcuts_key_press_event_cb (GtkWidget *widget,
241- GdkEventKey *event,
242- GtkFileChooserDefault *impl);
243-
244-static gboolean shortcuts_select_func (GtkTreeSelection *selection,
245- GtkTreeModel *model,
246- GtkTreePath *path,
247- gboolean path_currently_selected,
248- gpointer data);
249-static gboolean shortcuts_get_selected (GtkFileChooserDefault *impl,
250- GtkTreeIter *iter);
251-static void shortcuts_activate_iter (GtkFileChooserDefault *impl,
252- GtkTreeIter *iter);
253-static int shortcuts_get_index (GtkFileChooserDefault *impl,
254- ShortcutsIndex where);
255-static int shortcut_find_position (GtkFileChooserDefault *impl,
256- const GtkFilePath *path);
257-
258-static void bookmarks_check_add_sensitivity (GtkFileChooserDefault *impl);
259-
260+static void set_current_filter (GtkFileChooserDefault *impl,
261+ GtkFileFilter *filter);
262 static gboolean list_select_func (GtkTreeSelection *selection,
263 GtkTreeModel *model,
264 GtkTreePath *path,
265@@ -433,19 +277,6 @@
266 GtkTreeIter *iter,
267 gpointer user_data);
268
269-static void path_bar_clicked (GtkPathBar *path_bar,
270- GtkFilePath *file_path,
271- GtkFilePath *child_path,
272- gboolean child_is_hidden,
273- GtkFileChooserDefault *impl);
274-
275-static void add_bookmark_button_clicked_cb (GtkButton *button,
276- GtkFileChooserDefault *impl);
277-static void remove_bookmark_button_clicked_cb (GtkButton *button,
278- GtkFileChooserDefault *impl);
279-static void save_folder_combo_changed_cb (GtkComboBox *combo,
280- GtkFileChooserDefault *impl);
281-
282 static void list_icon_data_func (GtkTreeViewColumn *tree_column,
283 GtkCellRenderer *cell,
284 GtkTreeModel *tree_model,
285@@ -477,115 +308,8 @@
286
287 static void location_button_toggled_cb (GtkToggleButton *toggle,
288 GtkFileChooserDefault *impl);
289-static void location_switch_to_path_bar (GtkFileChooserDefault *impl);
290+static void settings_load (GtkFileChooserDefault *impl);
291
292-static void search_stop_searching (GtkFileChooserDefault *impl,
293- gboolean remove_query);
294-static void search_clear_model (GtkFileChooserDefault *impl,
295- gboolean remove_from_treeview);
296-static gboolean search_should_respond (GtkFileChooserDefault *impl);
297-static void search_switch_to_browse_mode (GtkFileChooserDefault *impl);
298-static GSList *search_get_selected_paths (GtkFileChooserDefault *impl);
299-static void search_entry_activate_cb (GtkEntry *entry,
300- gpointer data);
301-static void settings_load (GtkFileChooserDefault *impl);
302-static void search_get_valid_child_iter (GtkFileChooserDefault *impl,
303- GtkTreeIter *child_iter,
304- GtkTreeIter *iter);
305-
306-static void recent_manager_update (GtkFileChooserDefault *impl);
307-static void recent_stop_loading (GtkFileChooserDefault *impl);
308-static void recent_clear_model (GtkFileChooserDefault *impl,
309- gboolean remove_from_treeview);
310-static gboolean recent_should_respond (GtkFileChooserDefault *impl);
311-static void recent_switch_to_browse_mode (GtkFileChooserDefault *impl);
312-static GSList * recent_get_selected_paths (GtkFileChooserDefault *impl);
313-static void recent_get_valid_child_iter (GtkFileChooserDefault *impl,
314- GtkTreeIter *child_iter,
315- GtkTreeIter *iter);
316-
317-
318-
319-
320-/* Drag and drop interface declarations */
321-
322-typedef struct {
323- GtkTreeModelFilter parent;
324-
325- GtkFileChooserDefault *impl;
326-} ShortcutsPaneModelFilter;
327-
328-typedef struct {
329- GtkTreeModelFilterClass parent_class;
330-} ShortcutsPaneModelFilterClass;
331-
332-#define SHORTCUTS_PANE_MODEL_FILTER_TYPE (_shortcuts_pane_model_filter_get_type ())
333-#define SHORTCUTS_PANE_MODEL_FILTER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SHORTCUTS_PANE_MODEL_FILTER_TYPE, ShortcutsPaneModelFilter))
334-
335-static void shortcuts_pane_model_filter_drag_source_iface_init (GtkTreeDragSourceIface *iface);
336-
337-G_DEFINE_TYPE_WITH_CODE (ShortcutsPaneModelFilter,
338- _shortcuts_pane_model_filter,
339- GTK_TYPE_TREE_MODEL_FILTER,
340- G_IMPLEMENT_INTERFACE (GTK_TYPE_TREE_DRAG_SOURCE,
341- shortcuts_pane_model_filter_drag_source_iface_init))
342-
343-static GtkTreeModel *shortcuts_pane_model_filter_new (GtkFileChooserDefault *impl,
344- GtkTreeModel *child_model,
345- GtkTreePath *root);
346-
347-
348-typedef struct {
349- GtkTreeModelSort parent;
350-
351- GtkFileChooserDefault *impl;
352-} RecentModelSort;
353-
354-typedef struct {
355- GtkTreeModelSortClass parent_class;
356-} RecentModelSortClass;
357-
358-#define RECENT_MODEL_SORT_TYPE (_recent_model_sort_get_type ())
359-#define RECENT_MODEL_SORT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RECENT_MODEL_SORT_TYPE, RecentModelSort))
360-
361-static void recent_model_sort_drag_source_iface_init (GtkTreeDragSourceIface *iface);
362-
363-G_DEFINE_TYPE_WITH_CODE (RecentModelSort,
364- _recent_model_sort,
365- GTK_TYPE_TREE_MODEL_SORT,
366- G_IMPLEMENT_INTERFACE (GTK_TYPE_TREE_DRAG_SOURCE,
367- recent_model_sort_drag_source_iface_init));
368-
369-static GtkTreeModel *recent_model_sort_new (GtkFileChooserDefault *impl,
370- GtkTreeModel *child_model);
371-
372-
373-typedef struct {
374- GtkTreeModelSort parent;
375-
376- GtkFileChooserDefault *impl;
377-} SearchModelSort;
378-
379-typedef struct {
380- GtkTreeModelSortClass parent_class;
381-} SearchModelSortClass;
382-
383-#define SEARCH_MODEL_SORT_TYPE (_search_model_sort_get_type ())
384-#define SEARCH_MODEL_SORT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SEARCH_MODEL_SORT_TYPE, SearchModelSort))
385-
386-static void search_model_sort_drag_source_iface_init (GtkTreeDragSourceIface *iface);
387-
388-G_DEFINE_TYPE_WITH_CODE (SearchModelSort,
389- _search_model_sort,
390- GTK_TYPE_TREE_MODEL_SORT,
391- G_IMPLEMENT_INTERFACE (GTK_TYPE_TREE_DRAG_SOURCE,
392- search_model_sort_drag_source_iface_init));
393-
394-static GtkTreeModel *search_model_sort_new (GtkFileChooserDefault *impl,
395- GtkTreeModel *child_model);
396-
397-
398-
399 G_DEFINE_TYPE_WITH_CODE (GtkFileChooserDefault, _gtk_file_chooser_default, GTK_TYPE_VBOX,
400 G_IMPLEMENT_INTERFACE (GTK_TYPE_FILE_CHOOSER,
401 gtk_file_chooser_default_iface_init)
402@@ -595,13 +319,9 @@
403 static void
404 _gtk_file_chooser_default_class_init (GtkFileChooserDefaultClass *class)
405 {
406- static const guint quick_bookmark_keyvals[10] = {
407- GDK_1, GDK_2, GDK_3, GDK_4, GDK_5, GDK_6, GDK_7, GDK_8, GDK_9, GDK_0
408- };
409 GObjectClass *gobject_class = G_OBJECT_CLASS (class);
410 GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
411 GtkBindingSet *binding_set;
412- int i;
413
414 gobject_class->finalize = gtk_file_chooser_default_finalize;
415 gobject_class->constructor = gtk_file_chooser_default_constructor;
416@@ -621,7 +341,7 @@
417 _gtk_binding_signal_new (I_("location-popup"),
418 G_OBJECT_CLASS_TYPE (class),
419 G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
420- G_CALLBACK (location_popup_handler),
421+ NULL,
422 NULL, NULL,
423 _gtk_marshal_VOID__STRING,
424 G_TYPE_NONE, 1, G_TYPE_STRING);
425@@ -629,18 +349,10 @@
426 _gtk_binding_signal_new ("location-popup-on-paste",
427 G_OBJECT_CLASS_TYPE (class),
428 G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
429- G_CALLBACK (location_popup_on_paste_handler),
430+ NULL,
431 NULL, NULL,
432 _gtk_marshal_VOID__VOID,
433 G_TYPE_NONE, 0);
434- signals[LOCATION_TOGGLE_POPUP] =
435- _gtk_binding_signal_new (I_("location-toggle-popup"),
436- G_OBJECT_CLASS_TYPE (class),
437- G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
438- G_CALLBACK (location_toggle_popup_handler),
439- NULL, NULL,
440- _gtk_marshal_VOID__VOID,
441- G_TYPE_NONE, 0);
442 signals[UP_FOLDER] =
443 _gtk_binding_signal_new (I_("up-folder"),
444 G_OBJECT_CLASS_TYPE (class),
445@@ -665,22 +377,6 @@
446 NULL, NULL,
447 _gtk_marshal_VOID__VOID,
448 G_TYPE_NONE, 0);
449- signals[DESKTOP_FOLDER] =
450- _gtk_binding_signal_new (I_("desktop-folder"),
451- G_OBJECT_CLASS_TYPE (class),
452- G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
453- G_CALLBACK (desktop_folder_handler),
454- NULL, NULL,
455- _gtk_marshal_VOID__VOID,
456- G_TYPE_NONE, 0);
457- signals[QUICK_BOOKMARK] =
458- _gtk_binding_signal_new (I_("quick-bookmark"),
459- G_OBJECT_CLASS_TYPE (class),
460- G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
461- G_CALLBACK (quick_bookmark_handler),
462- NULL, NULL,
463- _gtk_marshal_VOID__INT,
464- G_TYPE_NONE, 1, G_TYPE_INT);
465 signals[SHOW_HIDDEN] =
466 _gtk_binding_signal_new ("show-hidden",
467 G_OBJECT_CLASS_TYPE (class),
468@@ -689,22 +385,6 @@
469 NULL, NULL,
470 _gtk_marshal_VOID__VOID,
471 G_TYPE_NONE, 0);
472- signals[SEARCH_SHORTCUT] =
473- _gtk_binding_signal_new ("search-shortcut",
474- G_OBJECT_CLASS_TYPE (class),
475- G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
476- G_CALLBACK (search_shortcut_handler),
477- NULL, NULL,
478- _gtk_marshal_VOID__VOID,
479- G_TYPE_NONE, 0);
480- signals[RECENT_SHORTCUT] =
481- _gtk_binding_signal_new ("recent-shortcut",
482- G_OBJECT_CLASS_TYPE (class),
483- G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
484- G_CALLBACK (recent_shortcut_handler),
485- NULL, NULL,
486- _gtk_marshal_VOID__VOID,
487- G_TYPE_NONE, 0);
488
489 binding_set = gtk_binding_set_by_class (class);
490
491@@ -764,29 +444,11 @@
492 "home-folder",
493 0);
494 gtk_binding_entry_add_signal (binding_set,
495- GDK_d, GDK_MOD1_MASK,
496- "desktop-folder",
497- 0);
498- gtk_binding_entry_add_signal (binding_set,
499 GDK_h, GDK_CONTROL_MASK,
500 "show-hidden",
501 0);
502- gtk_binding_entry_add_signal (binding_set,
503- GDK_s, GDK_MOD1_MASK,
504- "search-shortcut",
505- 0);
506- gtk_binding_entry_add_signal (binding_set,
507- GDK_r, GDK_MOD1_MASK,
508- "recent-shortcut",
509- 0);
510
511- for (i = 0; i < 10; i++)
512- gtk_binding_entry_add_signal (binding_set,
513- quick_bookmark_keyvals[i], GDK_MOD1_MASK,
514- "quick-bookmark",
515- 1, G_TYPE_INT, i);
516-
517 _gtk_file_chooser_install_properties (gobject_class);
518 }
519
520 static void
521@@ -797,7 +465,6 @@
522 iface->select_all = gtk_file_chooser_default_select_all;
523 iface->unselect_all = gtk_file_chooser_default_unselect_all;
524 iface->get_paths = gtk_file_chooser_default_get_paths;
525- iface->get_preview_path = gtk_file_chooser_default_get_preview_path;
526 iface->get_file_system = gtk_file_chooser_default_get_file_system;
527 iface->set_current_folder = gtk_file_chooser_default_set_current_folder;
528 iface->get_current_folder = gtk_file_chooser_default_get_current_folder;
529@@ -805,9 +472,12 @@
530 iface->add_filter = gtk_file_chooser_default_add_filter;
531 iface->remove_filter = gtk_file_chooser_default_remove_filter;
532 iface->list_filters = gtk_file_chooser_default_list_filters;
533+
534+ /* these are only stubs */
535+ iface->get_preview_path = gtk_file_chooser_default_get_preview_path;
536 iface->add_shortcut_folder = gtk_file_chooser_default_add_shortcut_folder;
537 iface->remove_shortcut_folder = gtk_file_chooser_default_remove_shortcut_folder;
538- iface->list_shortcut_folders = gtk_file_chooser_default_list_shortcut_folders;
539+
540 }
541
542 static void
543@@ -827,87 +497,29 @@
544 access ("MARK: *** CREATE FILE CHOOSER", F_OK);
545 #endif
546 impl->local_only = TRUE;
547- impl->preview_widget_active = TRUE;
548- impl->use_preview_label = TRUE;
549 impl->select_multiple = FALSE;
550 impl->show_hidden = FALSE;
551+ impl->show_create_folder = TRUE;
552 impl->icon_size = FALLBACK_ICON_SIZE;
553 impl->load_state = LOAD_EMPTY;
554 impl->reload_state = RELOAD_EMPTY;
555 impl->pending_select_paths = NULL;
556- impl->location_mode = LOCATION_MODE_PATH_BAR;
557- impl->operation_mode = OPERATION_MODE_BROWSE;
558+ impl->location_mode = LOCATION_MODE_FILENAME_ENTRY;
559+ impl->path_history = NULL;
560
561- gtk_box_set_spacing (GTK_BOX (impl), 12);
562+ gtk_box_set_spacing (GTK_BOX (impl), DEFAULT_SPACING);
563
564 impl->tooltips = gtk_tooltips_new ();
565 g_object_ref_sink (impl->tooltips);
566
567+ if (!impl->root_folder)
568+ impl->root_folder = g_strdup ("/");
569+
570 profile_end ("end", NULL);
571 }
572
573-/* Frees the data columns for the specified iter in the shortcuts model*/
574-static void
575-shortcuts_free_row_data (GtkFileChooserDefault *impl,
576- GtkTreeIter *iter)
577-{
578- gpointer col_data;
579- ShortcutType shortcut_type;
580- GtkFileSystemHandle *handle;
581
582- gtk_tree_model_get (GTK_TREE_MODEL (impl->shortcuts_model), iter,
583- SHORTCUTS_COL_DATA, &col_data,
584- SHORTCUTS_COL_TYPE, &shortcut_type,
585- SHORTCUTS_COL_HANDLE, &handle,
586- -1);
587-
588- if (handle)
589- gtk_file_system_cancel_operation (handle);
590-
591- if (!(shortcut_type == SHORTCUT_TYPE_PATH ||
592- shortcut_type == SHORTCUT_TYPE_VOLUME) ||
593- !col_data)
594- return;
595-
596- if (shortcut_type == SHORTCUT_TYPE_VOLUME)
597- {
598- GtkFileSystemVolume *volume;
599-
600- volume = col_data;
601- gtk_file_system_volume_free (impl->file_system, volume);
602- }
603- else
604- {
605- GtkFilePath *path;
606-
607- g_assert (shortcut_type == SHORTCUT_TYPE_PATH);
608-
609- path = col_data;
610- gtk_file_path_free (path);
611- }
612-}
613-
614-/* Frees all the data columns in the shortcuts model */
615 static void
616-shortcuts_free (GtkFileChooserDefault *impl)
617-{
618- GtkTreeIter iter;
619-
620- if (!impl->shortcuts_model)
621- return;
622-
623- if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (impl->shortcuts_model), &iter))
624- do
625- {
626- shortcuts_free_row_data (impl, &iter);
627- }
628- while (gtk_tree_model_iter_next (GTK_TREE_MODEL (impl->shortcuts_model), &iter));
629-
630- g_object_unref (impl->shortcuts_model);
631- impl->shortcuts_model = NULL;
632-}
633-
634-static void
635 pending_select_paths_free (GtkFileChooserDefault *impl)
636 {
637 GSList *l;
638@@ -964,19 +576,28 @@
639 }
640
641 static void
642-gtk_file_chooser_default_finalize (GObject *object)
643+path_history_free (GtkFileChooserDefault *impl)
644 {
645- GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (object);
646 GSList *l;
647
648- if (impl->shortcuts_pane_filter_model)
649- g_object_unref (impl->shortcuts_pane_filter_model);
650+ for (l = impl->path_history; l; l = l->next)
651+ {
652+ GtkFilePath *path;
653
654- if (impl->shortcuts_combo_filter_model)
655- g_object_unref (impl->shortcuts_combo_filter_model);
656+ path = l->data;
657+ gtk_file_path_free (path);
658+ }
659
660- shortcuts_free (impl);
661+ g_slist_free (impl->path_history);
662+ impl->path_history = NULL;
663+}
664
665+static void
666+gtk_file_chooser_default_finalize (GObject *object)
667+{
668+ GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (object);
669+ GSList *l;
670+
671 g_object_unref (impl->file_system);
672
673 g_free (impl->browse_files_last_selected_name);
674@@ -999,8 +620,7 @@
675 if (impl->current_folder)
676 gtk_file_path_free (impl->current_folder);
677
678- if (impl->preview_path)
679- gtk_file_path_free (impl->preview_path);
680+ path_history_free (impl);
681
682 load_remove_timer (impl);
683
684@@ -1011,15 +631,18 @@
685 if (impl->sort_model)
686 g_object_unref (impl->sort_model);
687
688- search_clear_model (impl, FALSE);
689- recent_clear_model (impl, FALSE);
690+ if (impl->list_press_path)
691+ {
692+ gtk_tree_path_free (impl->list_press_path);
693+ impl->list_press_path = NULL;
694+ }
695
696- g_free (impl->preview_display_name);
697-
698 g_free (impl->edited_new_text);
699
700 g_object_unref (impl->tooltips);
701
702+ g_free (impl->root_folder);
703+
704 G_OBJECT_CLASS (_gtk_file_chooser_default_parent_class)->finalize (object);
705 }
706
707@@ -1104,28 +727,6 @@
708 path, error);
709 }
710
711-/* Shows an error dialog about not being able to add a bookmark */
712-static void
713-error_adding_bookmark_dialog (GtkFileChooserDefault *impl,
714- const GtkFilePath *path,
715- GError *error)
716-{
717- error_dialog (impl,
718- _("Could not add a bookmark"),
719- path, error);
720-}
721-
722-/* Shows an error dialog about not being able to remove a bookmark */
723-static void
724-error_removing_bookmark_dialog (GtkFileChooserDefault *impl,
725- const GtkFilePath *path,
726- GError *error)
727-{
728- error_dialog (impl,
729- _("Could not remove bookmark"),
730- path, error);
731-}
732-
733 /* Shows an error dialog about not being able to create a folder */
734 static void
735 error_creating_folder_dialog (GtkFileChooserDefault *impl,
736@@ -1146,9 +747,9 @@
737 GError *error)
738 {
739 error_dialog (impl,
740- _("The folder could not be created, as a file with the same "
741- "name already exists. Try using a different name for the "
742- "folder, or rename the file first."),
743+ _("The folder could not be created, as a file with the same name "
744+ "already exists. Try using a different name for the folder, "
745+ "or rename the file first."),
746 path, error);
747 }
748
749@@ -1175,514 +776,108 @@
750
751 /* Changes folders, displaying an error dialog if this fails */
752 static gboolean
753-change_folder_and_display_error (GtkFileChooserDefault *impl,
754- const GtkFilePath *path,
755- gboolean clear_entry)
756+change_folder (GtkFileChooserDefault *impl, const GtkFilePath *path,
757+ gboolean errormsg)
758 {
759 GError *error;
760 gboolean result;
761 GtkFilePath *path_copy;
762+ gchar * file_name;
763
764 g_return_val_if_fail (path != NULL, FALSE);
765
766- profile_start ("start", (char *) path);
767-
768- /* We copy the path because of this case:
769- *
770- * list_row_activated()
771- * fetches path from model; path belongs to the model (*)
772- * calls change_folder_and_display_error()
773- * calls _gtk_file_chooser_set_current_folder_path()
774- * changing folders fails, sets model to NULL, thus freeing the path in (*)
775- */
776-
777 path_copy = gtk_file_path_copy (path);
778+ file_name = gtk_file_system_path_to_filename (impl->file_system, path_copy);
779
780- error = NULL;
781- result = gtk_file_chooser_default_update_current_folder (GTK_FILE_CHOOSER (impl), path_copy, TRUE, clear_entry, &error);
782+ if (!file_name)
783+ {
784+ gtk_file_path_free (path_copy);
785+ return 0;
786+ }
787
788- if (!result)
789- error_changing_folder_dialog (impl, path_copy, error);
790+ if (impl->root_folder && file_name[0] == '/' && file_name[1] == 0)
791+ {
792+ /* If changing to / and we have root_folder, change into it instead */
793+ gtk_file_path_free (path_copy);
794+ path_copy = gtk_file_system_filename_to_path (impl->file_system,
795+ impl->root_folder);
796
797- gtk_file_path_free (path_copy);
798+ gtk_widget_set_sensitive (impl->up_button, FALSE);
799+ }
800+ else if (impl->root_folder &&
801+ strcmp (file_name, impl->root_folder) &&
802+ !strncmp (file_name, impl->root_folder, strlen (file_name)))
803+ {
804+ /* refuse to change below the root */
805+ gtk_file_path_free (path_copy);
806+ g_free (file_name);
807+ return 0;
808+ }
809+ else if (!strcmp (file_name, impl->root_folder))
810+ {
811+ gtk_widget_set_sensitive (impl->up_button, FALSE);
812+ }
813+ else if (impl->current_folder && !strcmp (file_name, "/media"))
814+ {
815+ /* Asked to changed into /media -- if we are already in a media
816+ * child folder, we refuse, but if we are in the root, we permit this
817+ */
818+ gchar *name =
819+ gtk_file_system_path_to_filename (impl->file_system,
820+ impl->current_folder);
821
822- profile_end ("end", (char *) path);
823+ if (name && !strncmp (name, "/media", 6))
824+ {
825+ g_free (name);
826+ gtk_file_path_free (path_copy);
827+ g_free (file_name);
828+ return 0;
829+ }
830
831- return result;
832-}
833-
834-static void
835-update_preview_widget_visibility (GtkFileChooserDefault *impl)
836-{
837- if (impl->use_preview_label)
838- {
839- if (!impl->preview_label)
840- {
841- impl->preview_label = gtk_label_new (impl->preview_display_name);
842- gtk_box_pack_start (GTK_BOX (impl->preview_box), impl->preview_label, FALSE, FALSE, 0);
843- gtk_box_reorder_child (GTK_BOX (impl->preview_box), impl->preview_label, 0);
844- gtk_label_set_ellipsize (GTK_LABEL (impl->preview_label), PANGO_ELLIPSIZE_MIDDLE);
845- gtk_widget_show (impl->preview_label);
846- }
847- }
848+ gtk_widget_set_sensitive (impl->up_button, TRUE);
849+ }
850+ else if (!strncmp (file_name, "/media/", 7))
851+ {
852+ /* Changing into a media child -- if it is an immediate child, disable
853+ * the Up button
854+ */
855+ gchar * p = file_name + 7;
856+ gchar * q = strchr (p, '/');
857+ if (!q)
858+ gtk_widget_set_sensitive (impl->up_button, FALSE);
859+ else
860+ gtk_widget_set_sensitive (impl->up_button, TRUE);
861+ }
862 else
863- {
864- if (impl->preview_label)
865- {
866- gtk_widget_destroy (impl->preview_label);
867- impl->preview_label = NULL;
868- }
869- }
870+ {
871+ gtk_widget_set_sensitive (impl->up_button, TRUE);
872+ }
873
874- if (impl->preview_widget_active && impl->preview_widget)
875- gtk_widget_show (impl->preview_box);
876- else
877- gtk_widget_hide (impl->preview_box);
878
879- g_signal_emit_by_name (impl, "default-size-changed");
880-}
881+ error = NULL;
882+ result = _gtk_file_chooser_set_current_folder_path (GTK_FILE_CHOOSER (impl), path_copy, &error);
883
884-static void
885-set_preview_widget (GtkFileChooserDefault *impl,
886- GtkWidget *preview_widget)
887-{
888- if (preview_widget == impl->preview_widget)
889- return;
890+ if (errormsg && !result)
891+ error_changing_folder_dialog (impl, path_copy, error);
892
893- if (impl->preview_widget)
894- gtk_container_remove (GTK_CONTAINER (impl->preview_box),
895- impl->preview_widget);
896+ gtk_label_set_text (GTK_LABEL (impl->location_label), file_name);
897
898- impl->preview_widget = preview_widget;
899- if (impl->preview_widget)
900- {
901- gtk_widget_show (impl->preview_widget);
902- gtk_box_pack_start (GTK_BOX (impl->preview_box), impl->preview_widget, TRUE, TRUE, 0);
903- gtk_box_reorder_child (GTK_BOX (impl->preview_box),
904- impl->preview_widget,
905- (impl->use_preview_label && impl->preview_label) ? 1 : 0);
906- }
907+ gtk_file_path_free (path_copy);
908+ g_free (file_name);
909
910- update_preview_widget_visibility (impl);
911+ return result;
912 }
913
914-/* Renders a "Search" icon at an appropriate size for a tree view */
915-static GdkPixbuf *
916-render_search_icon (GtkFileChooserDefault *impl)
917+static gboolean
918+change_folder_and_display_error (GtkFileChooserDefault *impl,
919+ const GtkFilePath *path)
920 {
921- return gtk_widget_render_icon (GTK_WIDGET (impl), GTK_STOCK_FIND, GTK_ICON_SIZE_MENU, NULL);
922+ return change_folder (impl, path, TRUE);
923 }
924
925-static GdkPixbuf *
926-render_recent_icon (GtkFileChooserDefault *impl)
927-{
928- GtkIconTheme *theme;
929- GdkPixbuf *retval;
930
931- if (gtk_widget_has_screen (GTK_WIDGET (impl)))
932- theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (GTK_WIDGET (impl)));
933- else
934- theme = gtk_icon_theme_get_default ();
935-
936- retval = gtk_icon_theme_load_icon (theme, "document-open-recent",
937- impl->icon_size, 0,
938- NULL);
939-
940- /* fallback */
941- if (!retval)
942- retval = gtk_widget_render_icon (GTK_WIDGET (impl), GTK_STOCK_FILE, GTK_ICON_SIZE_MENU, NULL);
943-
944- return retval;
945-}
946-
947-
948-/* Re-reads all the icons for the shortcuts, used when the theme changes */
949-struct ReloadIconsData
950-{
951- GtkFileChooserDefault *impl;
952- GtkTreeRowReference *row_ref;
953-};
954-
955-static void
956-shortcuts_reload_icons_get_info_cb (GtkFileSystemHandle *handle,
957- const GtkFileInfo *info,
958- const GError *error,
959- gpointer user_data)
960-{
961- GdkPixbuf *pixbuf;
962- GtkTreeIter iter;
963- GtkTreePath *path;
964- gboolean cancelled = handle->cancelled;
965- struct ReloadIconsData *data = user_data;
966-
967- if (!g_slist_find (data->impl->reload_icon_handles, handle))
968- goto out;
969-
970- data->impl->reload_icon_handles = g_slist_remove (data->impl->reload_icon_handles, handle);
971-
972- if (cancelled || error)
973- goto out;
974-
975- pixbuf = gtk_file_info_render_icon (info, GTK_WIDGET (data->impl),
976- data->impl->icon_size, NULL);
977-
978- path = gtk_tree_row_reference_get_path (data->row_ref);
979- gtk_tree_model_get_iter (GTK_TREE_MODEL (data->impl->shortcuts_model), &iter, path);
980- gtk_list_store_set (data->impl->shortcuts_model, &iter,
981- SHORTCUTS_COL_PIXBUF, pixbuf,
982- -1);
983- gtk_tree_path_free (path);
984-
985- if (pixbuf)
986- g_object_unref (pixbuf);
987-
988-out:
989- gtk_tree_row_reference_free (data->row_ref);
990- g_object_unref (data->impl);
991- g_free (data);
992-
993- g_object_unref (handle);
994-}
995-
996-static void
997-shortcuts_reload_icons (GtkFileChooserDefault *impl)
998-{
999- GSList *l;
1000- GtkTreeIter iter;
1001-
1002- profile_start ("start", NULL);
1003-
1004- if (!gtk_tree_model_get_iter_first (GTK_TREE_MODEL (impl->shortcuts_model), &iter))
1005- goto out;
1006-
1007- for (l = impl->reload_icon_handles; l; l = l->next)
1008- {
1009- GtkFileSystemHandle *handle = GTK_FILE_SYSTEM_HANDLE (l->data);
1010- gtk_file_system_cancel_operation (handle);
1011- }
1012- g_slist_free (impl->reload_icon_handles);
1013- impl->reload_icon_handles = NULL;
1014-
1015- do
1016- {
1017- gpointer data;
1018- ShortcutType shortcut_type;
1019- gboolean pixbuf_visible;
1020- GdkPixbuf *pixbuf;
1021-
1022- gtk_tree_model_get (GTK_TREE_MODEL (impl->shortcuts_model), &iter,
1023- SHORTCUTS_COL_DATA, &data,
1024- SHORTCUTS_COL_TYPE, &shortcut_type,
1025- SHORTCUTS_COL_PIXBUF_VISIBLE, &pixbuf_visible,
1026- -1);
1027-
1028- pixbuf = NULL;
1029- if (pixbuf_visible)
1030- {
1031- if (shortcut_type == SHORTCUT_TYPE_VOLUME)
1032- {
1033- GtkFileSystemVolume *volume;
1034-
1035- volume = data;
1036- pixbuf = gtk_file_system_volume_render_icon (impl->file_system, volume, GTK_WIDGET (impl),
1037- impl->icon_size, NULL);
1038- }
1039- else if (shortcut_type == SHORTCUT_TYPE_PATH)
1040- {
1041- if (gtk_file_system_path_is_local (impl->file_system, (GtkFilePath *)data))
1042- {
1043- const GtkFilePath *path;
1044- struct ReloadIconsData *info;
1045- GtkTreePath *tree_path;
1046- GtkFileSystemHandle *handle;
1047-
1048- path = data;
1049-
1050- info = g_new0 (struct ReloadIconsData, 1);
1051- info->impl = g_object_ref (impl);
1052- tree_path = gtk_tree_model_get_path (GTK_TREE_MODEL (impl->shortcuts_model), &iter);
1053- info->row_ref = gtk_tree_row_reference_new (GTK_TREE_MODEL (impl->shortcuts_model), tree_path);
1054- gtk_tree_path_free (tree_path);
1055-
1056- handle = gtk_file_system_get_info (impl->file_system, path,
1057- GTK_FILE_INFO_ICON,
1058- shortcuts_reload_icons_get_info_cb,
1059- info);
1060- impl->reload_icon_handles = g_slist_append (impl->reload_icon_handles, handle);
1061- }
1062- else
1063- {
1064- GtkIconTheme *icon_theme;
1065-
1066- /* Don't call get_info for remote paths to avoid latency and
1067- * auth dialogs.
1068- * If we switch to a better bookmarks file format (XBEL), we
1069- * should use mime info to get a better icon.
1070- */
1071- icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (GTK_WIDGET (impl)));
1072- pixbuf = gtk_icon_theme_load_icon (icon_theme, "gnome-fs-share",
1073- impl->icon_size, 0, NULL);
1074- }
1075- }
1076- else if (shortcut_type == SHORTCUT_TYPE_SEARCH)
1077- {
1078- pixbuf = render_search_icon (impl);
1079- }
1080- else if (shortcut_type == SHORTCUT_TYPE_RECENT)
1081- {
1082- pixbuf = render_recent_icon (impl);
1083- }
1084-
1085- gtk_list_store_set (impl->shortcuts_model, &iter,
1086- SHORTCUTS_COL_PIXBUF, pixbuf,
1087- -1);
1088-
1089- if (pixbuf)
1090- g_object_unref (pixbuf);
1091-
1092- }
1093- }
1094- while (gtk_tree_model_iter_next (GTK_TREE_MODEL (impl->shortcuts_model),&iter));
1095-
1096- out:
1097-
1098- profile_end ("end", NULL);
1099-}
1100-
1101-static void
1102-shortcuts_find_folder (GtkFileChooserDefault *impl,
1103- GtkFilePath *folder)
1104-{
1105- GtkTreeSelection *selection;
1106- int pos;
1107- GtkTreePath *path;
1108-
1109- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_shortcuts_tree_view));
1110-
1111- g_assert (folder != NULL);
1112- pos = shortcut_find_position (impl, folder);
1113- if (pos == -1)
1114- {
1115- gtk_tree_selection_unselect_all (selection);
1116- return;
1117- }
1118-
1119- path = gtk_tree_path_new_from_indices (pos, -1);
1120- gtk_tree_selection_select_path (selection, path);
1121- gtk_tree_path_free (path);
1122-}
1123-
1124-/* If a shortcut corresponds to the current folder, selects it */
1125-static void
1126-shortcuts_find_current_folder (GtkFileChooserDefault *impl)
1127-{
1128- shortcuts_find_folder (impl, impl->current_folder);
1129-}
1130-
1131-/* Removes the specified number of rows from the shortcuts list */
1132-static void
1133-shortcuts_remove_rows (GtkFileChooserDefault *impl,
1134- int start_row,
1135- int n_rows)
1136-{
1137- GtkTreePath *path;
1138-
1139- path = gtk_tree_path_new_from_indices (start_row, -1);
1140-
1141- for (; n_rows; n_rows--)
1142- {
1143- GtkTreeIter iter;
1144-
1145- if (!gtk_tree_model_get_iter (GTK_TREE_MODEL (impl->shortcuts_model), &iter, path))
1146- g_assert_not_reached ();
1147-
1148- shortcuts_free_row_data (impl, &iter);
1149- gtk_list_store_remove (impl->shortcuts_model, &iter);
1150- }
1151-
1152- gtk_tree_path_free (path);
1153-}
1154-
1155-static void
1156-shortcuts_update_count (GtkFileChooserDefault *impl,
1157- ShortcutsIndex type,
1158- gint value)
1159-{
1160- switch (type)
1161- {
1162- case SHORTCUTS_HOME:
1163- if (value < 0)
1164- impl->has_home = FALSE;
1165- else
1166- impl->has_home = TRUE;
1167- break;
1168-
1169- case SHORTCUTS_DESKTOP:
1170- if (value < 0)
1171- impl->has_desktop = FALSE;
1172- else
1173- impl->has_desktop = TRUE;
1174- break;
1175-
1176- case SHORTCUTS_VOLUMES:
1177- impl->num_volumes += value;
1178- break;
1179-
1180- case SHORTCUTS_SHORTCUTS:
1181- impl->num_shortcuts += value;
1182- break;
1183-
1184- case SHORTCUTS_BOOKMARKS:
1185- impl->num_bookmarks += value;
1186- break;
1187-
1188- case SHORTCUTS_CURRENT_FOLDER:
1189- if (value < 0)
1190- impl->shortcuts_current_folder_active = FALSE;
1191- else
1192- impl->shortcuts_current_folder_active = TRUE;
1193- break;
1194-
1195- default:
1196- /* nothing */
1197- break;
1198- }
1199-}
1200-
1201-struct ShortcutsInsertRequest
1202-{
1203- GtkFileChooserDefault *impl;
1204- GtkFilePath *parent_path;
1205- GtkFilePath *path;
1206- int pos;
1207- char *label_copy;
1208- GtkTreeRowReference *row_ref;
1209- ShortcutsIndex type;
1210- gboolean name_only;
1211- gboolean removable;
1212-};
1213-
1214-static void
1215-get_file_info_finished (GtkFileSystemHandle *handle,
1216- const GtkFileInfo *info,
1217- const GError *error,
1218- gpointer data)
1219-{
1220- gint pos = -1;
1221- gboolean cancelled = handle->cancelled;
1222- GdkPixbuf *pixbuf;
1223- GtkTreePath *path;
1224- GtkTreeIter iter;
1225- GtkFileSystemHandle *model_handle;
1226- struct ShortcutsInsertRequest *request = data;
1227-
1228- path = gtk_tree_row_reference_get_path (request->row_ref);
1229- if (!path)
1230- /* Handle doesn't exist anymore in the model */
1231- goto out;
1232-
1233- pos = gtk_tree_path_get_indices (path)[0];
1234- gtk_tree_model_get_iter (GTK_TREE_MODEL (request->impl->shortcuts_model),
1235- &iter, path);
1236- gtk_tree_path_free (path);
1237-
1238- /* validate handle, else goto out */
1239- gtk_tree_model_get (GTK_TREE_MODEL (request->impl->shortcuts_model), &iter,
1240- SHORTCUTS_COL_HANDLE, &model_handle,
1241- -1);
1242- if (handle != model_handle)
1243- goto out;
1244-
1245- /* set the handle to NULL in the model (we unref later on) */
1246- gtk_list_store_set (request->impl->shortcuts_model, &iter,
1247- SHORTCUTS_COL_HANDLE, NULL,
1248- -1);
1249-
1250- if (cancelled)
1251- goto out;
1252-
1253- if (!info)
1254- {
1255- gtk_list_store_remove (request->impl->shortcuts_model, &iter);
1256- shortcuts_update_count (request->impl, request->type, -1);
1257-
1258- if (request->type == SHORTCUTS_HOME)
1259- {
1260- const char *home = g_get_home_dir ();
1261- GtkFilePath *home_path;
1262-
1263- home_path = gtk_file_system_filename_to_path (request->impl->file_system, home);
1264- error_getting_info_dialog (request->impl, home_path, g_error_copy (error));
1265- gtk_file_path_free (home_path);
1266- }
1267- else if (request->type == SHORTCUTS_CURRENT_FOLDER)
1268- {
1269- /* Remove the current folder separator */
1270- gint separator_pos = shortcuts_get_index (request->impl, SHORTCUTS_CURRENT_FOLDER_SEPARATOR);
1271- shortcuts_remove_rows (request->impl, separator_pos, 1);
1272- }
1273-
1274- goto out;
1275- }
1276-
1277- if (!request->label_copy)
1278- request->label_copy = g_strdup (gtk_file_info_get_display_name (info));
1279- pixbuf = gtk_file_info_render_icon (info, GTK_WIDGET (request->impl),
1280- request->impl->icon_size, NULL);
1281-
1282- gtk_list_store_set (request->impl->shortcuts_model, &iter,
1283- SHORTCUTS_COL_PIXBUF, pixbuf,
1284- SHORTCUTS_COL_PIXBUF_VISIBLE, TRUE,
1285- SHORTCUTS_COL_NAME, request->label_copy,
1286- SHORTCUTS_COL_TYPE, SHORTCUT_TYPE_PATH,
1287- SHORTCUTS_COL_REMOVABLE, request->removable,
1288- -1);
1289-
1290- if (request->impl->shortcuts_pane_filter_model)
1291- gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (request->impl->shortcuts_pane_filter_model));
1292-
1293- if (request->impl->shortcuts_combo_filter_model)
1294- gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (request->impl->shortcuts_combo_filter_model));
1295-
1296- if (request->type == SHORTCUTS_CURRENT_FOLDER &&
1297- request->impl->save_folder_combo != NULL)
1298- {
1299- /* The current folder is updated via _activate_iter(), don't
1300- * have save_folder_combo_changed_cb() call _activate_iter()
1301- * again.
1302- */
1303- g_signal_handlers_block_by_func (request->impl->save_folder_combo,
1304- G_CALLBACK (save_folder_combo_changed_cb),
1305- request->impl);
1306-
1307- if (request->impl->has_search)
1308- pos -= 1;
1309-
1310- if (request->impl->has_recent)
1311- pos -= 2;
1312-
1313- gtk_combo_box_set_active (GTK_COMBO_BOX (request->impl->save_folder_combo), pos);
1314- g_signal_handlers_unblock_by_func (request->impl->save_folder_combo,
1315- G_CALLBACK (save_folder_combo_changed_cb),
1316- request->impl);
1317- }
1318-
1319- if (pixbuf)
1320- g_object_unref (pixbuf);
1321-
1322-out:
1323- g_object_unref (request->impl);
1324- gtk_file_path_free (request->parent_path);
1325- gtk_file_path_free (request->path);
1326- gtk_tree_row_reference_free (request->row_ref);
1327- g_free (request->label_copy);
1328- g_free (request);
1329-
1330- g_object_unref (handle);
1331-}
1332-
1333 /* FIXME: GtkFileSystem needs a function to split a remote path
1334- * into hostname and path components, or maybe just have a
1335+ * into hostname and path components, or maybe just have a
1336 * gtk_file_system_path_get_display_name().
1337 *
1338 * This function is also used in gtkfilechooserbutton.c
1339@@ -1692,11 +887,11 @@
1340 {
1341 const gchar *path, *start, *end, *p;
1342 gchar *host, *label;
1343-
1344+
1345 start = strstr (uri, "://");
1346 start += 3;
1347 path = strchr (start, '/');
1348-
1349+
1350 if (path)
1351 end = path;
1352 else
1353@@ -1711,719 +906,25 @@
1354 {
1355 start = p + 1;
1356 }
1357-
1358+
1359 p = strchr (start, ':');
1360 if (p && p < end)
1361 end = p;
1362-
1363+
1364 host = g_strndup (start, end - start);
1365
1366- /* Translators: the first string is a path and the second string
1367- * is a hostname. Nautilus and the panel contain the same string
1368- * to translate.
1369+ /* Translators: the first string is a path and the second string
1370+ * is a hostname. Nautilus and the panel contain the same string
1371+ * to translate.
1372 */
1373 label = g_strdup_printf (_("%1$s on %2$s"), path, host);
1374-
1375+
1376 g_free (host);
1377
1378 return label;
1379 }
1380
1381-/* Inserts a path in the shortcuts tree, making a copy of it; alternatively,
1382- * inserts a volume. A position of -1 indicates the end of the tree.
1383- */
1384-static void
1385-shortcuts_insert_path (GtkFileChooserDefault *impl,
1386- int pos,
1387- ShortcutType shortcut_type,
1388- GtkFileSystemVolume *volume,
1389- const GtkFilePath *path,
1390- const char *label,
1391- gboolean removable,
1392- ShortcutsIndex type)
1393-{
1394- char *label_copy;
1395- GdkPixbuf *pixbuf = NULL;
1396- gpointer data = NULL;
1397- GtkTreeIter iter;
1398- GtkIconTheme *icon_theme;
1399
1400- profile_start ("start", (shortcut_type == SHORTCUT_TYPE_VOLUME) ? "volume"
1401- : ((shortcut_type == SHORTCUT_TYPE_PATH) ? (char *) path : NULL));
1402-
1403- if (shortcut_type == SHORTCUT_TYPE_VOLUME)
1404- {
1405- data = volume;
1406- label_copy = gtk_file_system_volume_get_display_name (impl->file_system, volume);
1407- pixbuf = gtk_file_system_volume_render_icon (impl->file_system, volume, GTK_WIDGET (impl),
1408- impl->icon_size, NULL);
1409- }
1410- else if (shortcut_type == SHORTCUT_TYPE_PATH)
1411- {
1412- if (gtk_file_system_path_is_local (impl->file_system, path))
1413- {
1414- struct ShortcutsInsertRequest *request;
1415- GtkFileSystemHandle *handle;
1416- GtkTreePath *p;
1417-
1418- request = g_new0 (struct ShortcutsInsertRequest, 1);
1419- request->impl = g_object_ref (impl);
1420- request->path = gtk_file_path_copy (path);
1421- request->name_only = TRUE;
1422- request->removable = removable;
1423- request->pos = pos;
1424- request->type = type;
1425- if (label)
1426- request->label_copy = g_strdup (label);
1427-
1428- if (pos == -1)
1429- gtk_list_store_append (impl->shortcuts_model, &iter);
1430- else
1431- gtk_list_store_insert (impl->shortcuts_model, &iter, pos);
1432-
1433- p = gtk_tree_model_get_path (GTK_TREE_MODEL (impl->shortcuts_model), &iter);
1434- request->row_ref = gtk_tree_row_reference_new (GTK_TREE_MODEL (impl->shortcuts_model), p);
1435- gtk_tree_path_free (p);
1436-
1437- handle = gtk_file_system_get_info (request->impl->file_system, request->path,
1438- GTK_FILE_INFO_DISPLAY_NAME | GTK_FILE_INFO_IS_HIDDEN | GTK_FILE_INFO_ICON,
1439- get_file_info_finished, request);
1440-
1441- gtk_list_store_set (impl->shortcuts_model, &iter,
1442- SHORTCUTS_COL_DATA, gtk_file_path_copy (path),
1443- SHORTCUTS_COL_TYPE, SHORTCUT_TYPE_PATH,
1444- SHORTCUTS_COL_HANDLE, handle,
1445- -1);
1446-
1447- shortcuts_update_count (impl, type, 1);
1448-
1449- return;
1450- }
1451- else
1452- {
1453- /* Don't call get_info for remote paths to avoid latency and
1454- * auth dialogs.
1455- */
1456- data = gtk_file_path_copy (path);
1457- if (label)
1458- label_copy = g_strdup (label);
1459- else
1460- {
1461- gchar *uri;
1462-
1463- uri = gtk_file_system_path_to_uri (impl->file_system, path);
1464-
1465- label_copy = _gtk_file_chooser_label_for_uri (uri);
1466-
1467- g_free (uri);
1468- }
1469-
1470- /* If we switch to a better bookmarks file format (XBEL), we
1471- * should use mime info to get a better icon.
1472- */
1473- icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (GTK_WIDGET (impl)));
1474- pixbuf = gtk_icon_theme_load_icon (icon_theme, "gnome-fs-share",
1475- impl->icon_size, 0, NULL);
1476- }
1477- }
1478- else
1479- {
1480- g_assert_not_reached ();
1481-
1482- return;
1483- }
1484-
1485- if (pos == -1)
1486- gtk_list_store_append (impl->shortcuts_model, &iter);
1487- else
1488- gtk_list_store_insert (impl->shortcuts_model, &iter, pos);
1489-
1490- shortcuts_update_count (impl, type, 1);
1491-
1492- gtk_list_store_set (impl->shortcuts_model, &iter,
1493- SHORTCUTS_COL_PIXBUF, pixbuf,
1494- SHORTCUTS_COL_PIXBUF_VISIBLE, TRUE,
1495- SHORTCUTS_COL_NAME, label_copy,
1496- SHORTCUTS_COL_DATA, data,
1497- SHORTCUTS_COL_TYPE, shortcut_type,
1498- SHORTCUTS_COL_REMOVABLE, removable,
1499- SHORTCUTS_COL_HANDLE, NULL,
1500- -1);
1501-
1502- if (impl->shortcuts_pane_filter_model)
1503- gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (impl->shortcuts_pane_filter_model));
1504-
1505- if (impl->shortcuts_combo_filter_model)
1506- gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (impl->shortcuts_combo_filter_model));
1507-
1508- if (type == SHORTCUTS_CURRENT_FOLDER && impl->save_folder_combo != NULL)
1509- {
1510- /* The current folder is updated via _activate_iter(), don't
1511- * have save_folder_combo_changed_cb() call _activate_iter()
1512- * again.
1513- */
1514- gint combo_pos = shortcuts_get_index (impl, SHORTCUTS_CURRENT_FOLDER);
1515-
1516- if (impl->has_search)
1517- combo_pos -= 1;
1518-
1519- if (impl->has_recent)
1520- combo_pos -= 2;
1521-
1522- g_signal_handlers_block_by_func (impl->save_folder_combo,
1523- G_CALLBACK (save_folder_combo_changed_cb),
1524- impl);
1525-
1526- gtk_combo_box_set_active (GTK_COMBO_BOX (impl->save_folder_combo), combo_pos);
1527- g_signal_handlers_unblock_by_func (impl->save_folder_combo,
1528- G_CALLBACK (save_folder_combo_changed_cb),
1529- impl);
1530- }
1531-
1532- g_free (label_copy);
1533-
1534- if (pixbuf)
1535- g_object_unref (pixbuf);
1536-
1537- profile_end ("end", NULL);
1538-}
1539-
1540-static void
1541-shortcuts_append_search (GtkFileChooserDefault *impl)
1542-{
1543- GdkPixbuf *pixbuf;
1544- GtkTreeIter iter;
1545-
1546- pixbuf = render_search_icon (impl);
1547-
1548- gtk_list_store_append (impl->shortcuts_model, &iter);
1549- gtk_list_store_set (impl->shortcuts_model, &iter,
1550- SHORTCUTS_COL_PIXBUF, pixbuf,
1551- SHORTCUTS_COL_PIXBUF_VISIBLE, TRUE,
1552- SHORTCUTS_COL_NAME, _("Search"),
1553- SHORTCUTS_COL_DATA, NULL,
1554- SHORTCUTS_COL_TYPE, SHORTCUT_TYPE_SEARCH,
1555- SHORTCUTS_COL_REMOVABLE, FALSE,
1556- -1);
1557-
1558- if (pixbuf)
1559- g_object_unref (pixbuf);
1560-
1561- impl->has_search = TRUE;
1562-}
1563-
1564-static void
1565-shortcuts_append_recent (GtkFileChooserDefault *impl)
1566-{
1567- GdkPixbuf *pixbuf;
1568- GtkTreeIter iter;
1569-
1570- pixbuf = render_recent_icon (impl);
1571-
1572- gtk_list_store_append (impl->shortcuts_model, &iter);
1573- gtk_list_store_set (impl->shortcuts_model, &iter,
1574- SHORTCUTS_COL_PIXBUF, pixbuf,
1575- SHORTCUTS_COL_PIXBUF_VISIBLE, TRUE,
1576- SHORTCUTS_COL_NAME, _("Recently Used"),
1577- SHORTCUTS_COL_DATA, NULL,
1578- SHORTCUTS_COL_TYPE, SHORTCUT_TYPE_RECENT,
1579- SHORTCUTS_COL_REMOVABLE, FALSE,
1580- -1);
1581-
1582- if (pixbuf)
1583- g_object_unref (pixbuf);
1584-
1585- impl->has_recent = TRUE;
1586-}
1587-
1588-/* Appends an item for the user's home directory to the shortcuts model */
1589-static void
1590-shortcuts_append_home (GtkFileChooserDefault *impl)
1591-{
1592- const char *home;
1593- GtkFilePath *home_path;
1594-
1595- profile_start ("start", NULL);
1596-
1597- home = g_get_home_dir ();
1598- if (home == NULL)
1599- {
1600- profile_end ("end - no home directory!?", NULL);
1601- return;
1602- }
1603-
1604- home_path = gtk_file_system_filename_to_path (impl->file_system, home);
1605-
1606- shortcuts_insert_path (impl, -1, SHORTCUT_TYPE_PATH, NULL, home_path, NULL, FALSE, SHORTCUTS_HOME);
1607- impl->has_home = TRUE;
1608-
1609- gtk_file_path_free (home_path);
1610-
1611- profile_end ("end", NULL);
1612-}
1613-
1614-/* Appends the ~/Desktop directory to the shortcuts model */
1615-static void
1616-shortcuts_append_desktop (GtkFileChooserDefault *impl)
1617-{
1618- const char *name;
1619- GtkFilePath *path;
1620-
1621- profile_start ("start", NULL);
1622-
1623- name = g_get_user_special_dir (G_USER_DIRECTORY_DESKTOP);
1624- path = gtk_file_system_filename_to_path (impl->file_system, name);
1625- shortcuts_insert_path (impl, -1, SHORTCUT_TYPE_PATH, NULL, path, _("Desktop"), FALSE, SHORTCUTS_DESKTOP);
1626- impl->has_desktop = TRUE;
1627-
1628- /* We do not actually pop up an error dialog if there is no desktop directory
1629- * because some people may really not want to have one.
1630- */
1631-
1632- gtk_file_path_free (path);
1633-
1634- profile_end ("end", NULL);
1635-}
1636-
1637-/* Appends a list of GtkFilePath to the shortcuts model; returns how many were inserted */
1638-static int
1639-shortcuts_append_paths (GtkFileChooserDefault *impl,
1640- GSList *paths)
1641-{
1642- int start_row;
1643- int num_inserted;
1644- gchar *label;
1645-
1646- profile_start ("start", NULL);
1647-
1648- /* As there is no separator now, we want to start there.
1649- */
1650- start_row = shortcuts_get_index (impl, SHORTCUTS_BOOKMARKS_SEPARATOR);
1651- num_inserted = 0;
1652-
1653- for (; paths; paths = paths->next)
1654- {
1655- GtkFilePath *path;
1656-
1657- path = paths->data;
1658-
1659- if (impl->local_only &&
1660- !gtk_file_system_path_is_local (impl->file_system, path))
1661- continue;
1662-
1663- label = gtk_file_system_get_bookmark_label (impl->file_system, path);
1664-
1665- /* NULL GError, but we don't really want to show error boxes here */
1666- shortcuts_insert_path (impl, start_row + num_inserted, SHORTCUT_TYPE_PATH, NULL, path, label, TRUE, SHORTCUTS_BOOKMARKS);
1667- num_inserted++;
1668-
1669- g_free (label);
1670- }
1671-
1672- profile_end ("end", NULL);
1673-
1674- return num_inserted;
1675-}
1676-
1677-/* Returns the index for the corresponding item in the shortcuts bar */
1678-static int
1679-shortcuts_get_index (GtkFileChooserDefault *impl,
1680- ShortcutsIndex where)
1681-{
1682- int n;
1683-
1684- n = 0;
1685-
1686- if (where == SHORTCUTS_SEARCH)
1687- goto out;
1688-
1689- n += impl->has_search ? 1 : 0;
1690-
1691- if (where == SHORTCUTS_RECENT)
1692- goto out;
1693-
1694- n += impl->has_recent ? 1 : 0;
1695-
1696- if (where == SHORTCUTS_RECENT_SEPARATOR)
1697- goto out;
1698-
1699- n += impl->has_recent ? 1 : 0;
1700-
1701- if (where == SHORTCUTS_HOME)
1702- goto out;
1703-
1704- n += impl->has_home ? 1 : 0;
1705-
1706- if (where == SHORTCUTS_DESKTOP)
1707- goto out;
1708-
1709- n += impl->has_desktop ? 1 : 0;
1710-
1711- if (where == SHORTCUTS_VOLUMES)
1712- goto out;
1713-
1714- n += impl->num_volumes;
1715-
1716- if (where == SHORTCUTS_SHORTCUTS)
1717- goto out;
1718-
1719- n += impl->num_shortcuts;
1720-
1721- if (where == SHORTCUTS_BOOKMARKS_SEPARATOR)
1722- goto out;
1723-
1724- /* If there are no bookmarks there won't be a separator */
1725- n += (impl->num_bookmarks > 0) ? 1 : 0;
1726-
1727- if (where == SHORTCUTS_BOOKMARKS)
1728- goto out;
1729-
1730- n += impl->num_bookmarks;
1731-
1732- if (where == SHORTCUTS_CURRENT_FOLDER_SEPARATOR)
1733- goto out;
1734-
1735- n += 1;
1736-
1737- if (where == SHORTCUTS_CURRENT_FOLDER)
1738- goto out;
1739-
1740- g_assert_not_reached ();
1741-
1742- out:
1743-
1744- return n;
1745-}
1746-
1747-/* Adds all the file system volumes to the shortcuts model */
1748-static void
1749-shortcuts_add_volumes (GtkFileChooserDefault *impl)
1750-{
1751- int start_row;
1752- GSList *list, *l;
1753- int n;
1754- gboolean old_changing_folders;
1755-
1756- profile_start ("start", NULL);
1757-
1758-
1759- old_changing_folders = impl->changing_folder;
1760- impl->changing_folder = TRUE;
1761-
1762- start_row = shortcuts_get_index (impl, SHORTCUTS_VOLUMES);
1763- shortcuts_remove_rows (impl, start_row, impl->num_volumes);
1764- impl->num_volumes = 0;
1765-
1766- list = gtk_file_system_list_volumes (impl->file_system);
1767-
1768- n = 0;
1769-
1770- for (l = list; l; l = l->next)
1771- {
1772- GtkFileSystemVolume *volume;
1773-
1774- volume = l->data;
1775-
1776- if (impl->local_only)
1777- {
1778- if (gtk_file_system_volume_get_is_mounted (impl->file_system, volume))
1779- {
1780- GtkFilePath *base_path;
1781-
1782- base_path = gtk_file_system_volume_get_base_path (impl->file_system, volume);
1783- if (base_path != NULL)
1784- {
1785- gboolean is_local = gtk_file_system_path_is_local (impl->file_system, base_path);
1786- gtk_file_path_free (base_path);
1787-
1788- if (!is_local)
1789- {
1790- gtk_file_system_volume_free (impl->file_system, volume);
1791- continue;
1792- }
1793- }
1794- }
1795- }
1796-
1797- shortcuts_insert_path (impl, start_row + n, SHORTCUT_TYPE_VOLUME, volume, NULL, NULL, FALSE, SHORTCUTS_VOLUMES);
1798- n++;
1799- }
1800-
1801- impl->num_volumes = n;
1802- g_slist_free (list);
1803-
1804- if (impl->shortcuts_pane_filter_model)
1805- gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (impl->shortcuts_pane_filter_model));
1806-
1807- if (impl->shortcuts_combo_filter_model)
1808- gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (impl->shortcuts_combo_filter_model));
1809-
1810- impl->changing_folder = old_changing_folders;
1811-
1812- profile_end ("end", NULL);
1813-}
1814-
1815-/* Inserts a separator node in the shortcuts list */
1816-static void
1817-shortcuts_insert_separator (GtkFileChooserDefault *impl,
1818- ShortcutsIndex where)
1819-{
1820- GtkTreeIter iter;
1821-
1822- g_assert (where == SHORTCUTS_RECENT_SEPARATOR ||
1823- where == SHORTCUTS_BOOKMARKS_SEPARATOR ||
1824- where == SHORTCUTS_CURRENT_FOLDER_SEPARATOR);
1825-
1826- gtk_list_store_insert (impl->shortcuts_model, &iter,
1827- shortcuts_get_index (impl, where));
1828- gtk_list_store_set (impl->shortcuts_model, &iter,
1829- SHORTCUTS_COL_PIXBUF, NULL,
1830- SHORTCUTS_COL_PIXBUF_VISIBLE, FALSE,
1831- SHORTCUTS_COL_NAME, NULL,
1832- SHORTCUTS_COL_DATA, NULL,
1833- SHORTCUTS_COL_TYPE, SHORTCUT_TYPE_SEPARATOR,
1834- -1);
1835-}
1836-
1837-/* Updates the list of bookmarks */
1838-static void
1839-shortcuts_add_bookmarks (GtkFileChooserDefault *impl)
1840-{
1841- GSList *bookmarks;
1842- gboolean old_changing_folders;
1843- GtkTreeIter iter;
1844- GtkFilePath *list_selected = NULL;
1845- GtkFilePath *combo_selected = NULL;
1846- ShortcutType shortcut_type;
1847- gpointer col_data;
1848-
1849- profile_start ("start", NULL);
1850-
1851- old_changing_folders = impl->changing_folder;
1852- impl->changing_folder = TRUE;
1853-
1854- if (shortcuts_get_selected (impl, &iter))
1855- {
1856- gtk_tree_model_get (GTK_TREE_MODEL (impl->shortcuts_model),
1857- &iter,
1858- SHORTCUTS_COL_DATA, &col_data,
1859- SHORTCUTS_COL_TYPE, &shortcut_type,
1860- -1);
1861-
1862- if (col_data && shortcut_type == SHORTCUT_TYPE_PATH)
1863- list_selected = gtk_file_path_copy (col_data);
1864- }
1865-
1866- if (impl->save_folder_combo &&
1867- gtk_combo_box_get_active_iter (GTK_COMBO_BOX (impl->save_folder_combo),
1868- &iter))
1869- {
1870- GtkTreeIter child_iter;
1871-
1872- gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER (impl->shortcuts_combo_filter_model),
1873- &child_iter,
1874- &iter);
1875- gtk_tree_model_get (GTK_TREE_MODEL (impl->shortcuts_model),
1876- &child_iter,
1877- SHORTCUTS_COL_DATA, &col_data,
1878- SHORTCUTS_COL_TYPE, &shortcut_type,
1879- -1);
1880-
1881- if (col_data && shortcut_type == SHORTCUT_TYPE_PATH)
1882- combo_selected = gtk_file_path_copy (col_data);
1883- }
1884-
1885- if (impl->num_bookmarks > 0)
1886- shortcuts_remove_rows (impl,
1887- shortcuts_get_index (impl, SHORTCUTS_BOOKMARKS_SEPARATOR),
1888- impl->num_bookmarks + 1);
1889-
1890- impl->num_bookmarks = 0;
1891-
1892- bookmarks = gtk_file_system_list_bookmarks (impl->file_system);
1893- shortcuts_append_paths (impl, bookmarks);
1894- gtk_file_paths_free (bookmarks);
1895-
1896- if (impl->num_bookmarks > 0)
1897- shortcuts_insert_separator (impl, SHORTCUTS_BOOKMARKS_SEPARATOR);
1898-
1899- if (impl->shortcuts_pane_filter_model)
1900- gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (impl->shortcuts_pane_filter_model));
1901-
1902- if (impl->shortcuts_combo_filter_model)
1903- gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (impl->shortcuts_combo_filter_model));
1904-
1905- if (list_selected)
1906- {
1907- shortcuts_find_folder (impl, list_selected);
1908- gtk_file_path_free (list_selected);
1909- }
1910-
1911- if (combo_selected)
1912- {
1913- gint pos;
1914-
1915- pos = shortcut_find_position (impl, combo_selected);
1916- if (pos != -1)
1917- {
1918- if (impl->has_search)
1919- pos -= 1;
1920-
1921- if (impl->has_recent)
1922- pos -= 2;
1923-
1924- gtk_combo_box_set_active (GTK_COMBO_BOX (impl->save_folder_combo), pos);
1925- }
1926-
1927- gtk_file_path_free (combo_selected);
1928- }
1929-
1930- impl->changing_folder = old_changing_folders;
1931-
1932- profile_end ("end", NULL);
1933-}
1934-
1935-/* Appends a separator and a row to the shortcuts list for the current folder */
1936-static void
1937-shortcuts_add_current_folder (GtkFileChooserDefault *impl)
1938-{
1939- int pos;
1940- gboolean success;
1941-
1942- g_assert (!impl->shortcuts_current_folder_active);
1943-
1944- success = TRUE;
1945-
1946- g_assert (impl->current_folder != NULL);
1947-
1948- pos = shortcut_find_position (impl, impl->current_folder);
1949- if (pos == -1)
1950- {
1951- GtkFileSystemVolume *volume;
1952- GtkFilePath *base_path;
1953-
1954- /* Separator */
1955-
1956- shortcuts_insert_separator (impl, SHORTCUTS_CURRENT_FOLDER_SEPARATOR);
1957-
1958- /* Item */
1959-
1960- pos = shortcuts_get_index (impl, SHORTCUTS_CURRENT_FOLDER);
1961-
1962- volume = gtk_file_system_get_volume_for_path (impl->file_system, impl->current_folder);
1963- if (volume)
1964- base_path = gtk_file_system_volume_get_base_path (impl->file_system, volume);
1965- else
1966- base_path = NULL;
1967-
1968- if (base_path &&
1969- strcmp (gtk_file_path_get_string (base_path), gtk_file_path_get_string (impl->current_folder)) == 0)
1970- {
1971- shortcuts_insert_path (impl, pos, SHORTCUT_TYPE_VOLUME, volume, NULL, NULL, FALSE, SHORTCUTS_CURRENT_FOLDER);
1972- }
1973- else
1974- {
1975- shortcuts_insert_path (impl, pos, SHORTCUT_TYPE_PATH, NULL, impl->current_folder, NULL, FALSE, SHORTCUTS_CURRENT_FOLDER);
1976- if (volume)
1977- gtk_file_system_volume_free (impl->file_system, volume);
1978- }
1979-
1980- if (base_path)
1981- gtk_file_path_free (base_path);
1982- }
1983- else if (impl->save_folder_combo != NULL)
1984- {
1985- if (impl->has_search)
1986- pos -= 1;
1987-
1988- if (impl->has_recent)
1989- pos -= 2; /* + separator */
1990-
1991- gtk_combo_box_set_active (GTK_COMBO_BOX (impl->save_folder_combo), pos);
1992- }
1993-}
1994-
1995-/* Updates the current folder row in the shortcuts model */
1996-static void
1997-shortcuts_update_current_folder (GtkFileChooserDefault *impl)
1998-{
1999- int pos;
2000-
2001- pos = shortcuts_get_index (impl, SHORTCUTS_CURRENT_FOLDER_SEPARATOR);
2002-
2003- if (impl->shortcuts_current_folder_active)
2004- {
2005- shortcuts_remove_rows (impl, pos, 2);
2006- impl->shortcuts_current_folder_active = FALSE;
2007- }
2008-
2009- shortcuts_add_current_folder (impl);
2010-}
2011-
2012-/* Filter function used for the shortcuts filter model */
2013-static gboolean
2014-shortcuts_pane_filter_cb (GtkTreeModel *model,
2015- GtkTreeIter *iter,
2016- gpointer data)
2017-{
2018- GtkFileChooserDefault *impl;
2019- GtkTreePath *path;
2020- int pos;
2021-
2022- impl = GTK_FILE_CHOOSER_DEFAULT (data);
2023-
2024- path = gtk_tree_model_get_path (model, iter);
2025- if (!path)
2026- return FALSE;
2027-
2028- pos = *gtk_tree_path_get_indices (path);
2029- gtk_tree_path_free (path);
2030-
2031- return (pos < shortcuts_get_index (impl, SHORTCUTS_CURRENT_FOLDER_SEPARATOR));
2032-}
2033-
2034-/* Creates the list model for shortcuts */
2035-static void
2036-shortcuts_model_create (GtkFileChooserDefault *impl)
2037-{
2038- /* Keep this order in sync with the SHORCUTS_COL_* enum values */
2039- impl->shortcuts_model = gtk_list_store_new (SHORTCUTS_COL_NUM_COLUMNS,
2040- GDK_TYPE_PIXBUF, /* pixbuf */
2041- G_TYPE_STRING, /* name */
2042- G_TYPE_POINTER, /* path or volume */
2043- G_TYPE_INT, /* ShortcutType */
2044- G_TYPE_BOOLEAN, /* removable */
2045- G_TYPE_BOOLEAN, /* pixbuf cell visibility */
2046- G_TYPE_POINTER); /* GtkFileSystemHandle */
2047-
2048- if (search_is_possible (impl))
2049- {
2050- shortcuts_append_search (impl);
2051- }
2052-
2053- if (impl->recent_manager)
2054- {
2055- shortcuts_append_recent (impl);
2056- shortcuts_insert_separator (impl, SHORTCUTS_RECENT_SEPARATOR);
2057- }
2058-
2059- if (impl->file_system)
2060- {
2061- shortcuts_append_home (impl);
2062- shortcuts_append_desktop (impl);
2063- shortcuts_add_volumes (impl);
2064- }
2065-
2066- impl->shortcuts_pane_filter_model = shortcuts_pane_model_filter_new (impl,
2067- GTK_TREE_MODEL (impl->shortcuts_model),
2068- NULL);
2069-
2070- gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (impl->shortcuts_pane_filter_model),
2071- shortcuts_pane_filter_cb,
2072- impl,
2073- NULL);
2074-}
2075-
2076 /* Callback used when the "New Folder" button is clicked */
2077 static void
2078 new_folder_button_clicked (GtkButton *button,
2079@@ -2472,7 +973,7 @@
2080 goto out;
2081
2082 if (!error)
2083- change_folder_and_display_error (impl, path, FALSE);
2084+ change_folder_and_display_error (impl, path);
2085 else
2086 error_creating_folder_dialog (impl, path, g_error_copy (error));
2087
2088@@ -2488,7 +989,7 @@
2089 edited_idle_cb (GtkFileChooserDefault *impl)
2090 {
2091 GDK_THREADS_ENTER ();
2092-
2093+
2094 g_source_destroy (impl->edited_idle);
2095 impl->edited_idle = NULL;
2096
2097@@ -2558,10 +1059,10 @@
2098 const gchar *new_text,
2099 GtkFileChooserDefault *impl)
2100 {
2101- /* work around bug #154921 */
2102- g_object_set (cell_renderer_text,
2103+ /* work around bug #154921 */
2104+ g_object_set (cell_renderer_text,
2105 "mode", GTK_CELL_RENDERER_MODE_INERT, NULL);
2106- queue_edited_idle (impl, new_text);
2107+ queue_edited_idle (impl, new_text);
2108 }
2109
2110 /* Callback used from the text cell renderer when the new folder edition gets
2111@@ -2571,10 +1072,10 @@
2112 renderer_editing_canceled_cb (GtkCellRendererText *cell_renderer_text,
2113 GtkFileChooserDefault *impl)
2114 {
2115- /* work around bug #154921 */
2116- g_object_set (cell_renderer_text,
2117+ /* work around bug #154921 */
2118+ g_object_set (cell_renderer_text,
2119 "mode", GTK_CELL_RENDERER_MODE_INERT, NULL);
2120- queue_edited_idle (impl, NULL);
2121+ queue_edited_idle (impl, NULL);
2122 }
2123
2124 /* Creates the widgets for the filter combo box */
2125@@ -2587,253 +1088,9 @@
2126 g_signal_connect (impl->filter_combo, "changed",
2127 G_CALLBACK (filter_combo_changed), impl);
2128
2129- gtk_widget_set_tooltip_text (impl->filter_combo,
2130- _("Select which types of files are shown"));
2131-
2132 return impl->filter_combo;
2133 }
2134
2135-static GtkWidget *
2136-button_new (GtkFileChooserDefault *impl,
2137- const char *text,
2138- const char *stock_id,
2139- gboolean sensitive,
2140- gboolean show,
2141- GCallback callback)
2142-{
2143- GtkWidget *button;
2144- GtkWidget *image;
2145-
2146- button = gtk_button_new_with_mnemonic (text);
2147- image = gtk_image_new_from_stock (stock_id, GTK_ICON_SIZE_BUTTON);
2148- gtk_button_set_image (GTK_BUTTON (button), image);
2149-
2150- gtk_widget_set_sensitive (button, sensitive);
2151- g_signal_connect (button, "clicked", callback, impl);
2152-
2153- if (show)
2154- gtk_widget_show (button);
2155-
2156- return button;
2157-}
2158-
2159-/* Looks for a path among the shortcuts; returns its index or -1 if it doesn't exist */
2160-static int
2161-shortcut_find_position (GtkFileChooserDefault *impl,
2162- const GtkFilePath *path)
2163-{
2164- GtkTreeIter iter;
2165- int i;
2166- int current_folder_separator_idx;
2167-
2168- if (!gtk_tree_model_get_iter_first (GTK_TREE_MODEL (impl->shortcuts_model), &iter))
2169- return -1;
2170-
2171- current_folder_separator_idx = shortcuts_get_index (impl, SHORTCUTS_CURRENT_FOLDER_SEPARATOR);
2172-
2173-#if 0
2174- /* FIXME: is this still needed? */
2175- if (current_folder_separator_idx >= impl->shortcuts_model->length)
2176- return -1;
2177-#endif
2178-
2179- for (i = 0; i < current_folder_separator_idx; i++)
2180- {
2181- gpointer col_data;
2182- ShortcutType shortcut_type;
2183-
2184- gtk_tree_model_get (GTK_TREE_MODEL (impl->shortcuts_model), &iter,
2185- SHORTCUTS_COL_DATA, &col_data,
2186- SHORTCUTS_COL_TYPE, &shortcut_type,
2187- -1);
2188-
2189- if (col_data)
2190- {
2191- if (shortcut_type == SHORTCUT_TYPE_VOLUME)
2192- {
2193- GtkFileSystemVolume *volume;
2194- GtkFilePath *base_path;
2195- gboolean exists;
2196-
2197- volume = col_data;
2198- base_path = gtk_file_system_volume_get_base_path (impl->file_system, volume);
2199-
2200- exists = base_path && strcmp (gtk_file_path_get_string (path),
2201- gtk_file_path_get_string (base_path)) == 0;
2202- g_free (base_path);
2203-
2204- if (exists)
2205- return i;
2206- }
2207- else if (shortcut_type == SHORTCUT_TYPE_PATH)
2208- {
2209- GtkFilePath *model_path;
2210-
2211- model_path = col_data;
2212-
2213- if (model_path && gtk_file_path_compare (model_path, path) == 0)
2214- return i;
2215- }
2216- }
2217-
2218- if (i < current_folder_separator_idx - 1)
2219- {
2220- if (!gtk_tree_model_iter_next (GTK_TREE_MODEL (impl->shortcuts_model), &iter))
2221- g_assert_not_reached ();
2222- }
2223- }
2224-
2225- return -1;
2226-}
2227-
2228-/* Tries to add a bookmark from a path name */
2229-static gboolean
2230-shortcuts_add_bookmark_from_path (GtkFileChooserDefault *impl,
2231- const GtkFilePath *path,
2232- int pos)
2233-{
2234- GError *error;
2235-
2236- g_return_val_if_fail (path != NULL, FALSE);
2237-
2238- if (shortcut_find_position (impl, path) != -1)
2239- return FALSE;
2240-
2241- error = NULL;
2242- if (!gtk_file_system_insert_bookmark (impl->file_system, path, pos, &error))
2243- {
2244- error_adding_bookmark_dialog (impl, path, error);
2245- return FALSE;
2246- }
2247-
2248- return TRUE;
2249-}
2250-
2251-static void
2252-add_bookmark_foreach_cb (GtkTreeModel *model,
2253- GtkTreePath *path,
2254- GtkTreeIter *iter,
2255- gpointer data)
2256-{
2257- GtkFileChooserDefault *impl;
2258- GtkFileSystemModel *fs_model;
2259- GtkTreeIter child_iter;
2260- const GtkFilePath *file_path;
2261-
2262- impl = (GtkFileChooserDefault *) data;
2263-
2264- switch (impl->operation_mode)
2265- {
2266- case OPERATION_MODE_BROWSE:
2267- fs_model = impl->browse_files_model;
2268- gtk_tree_model_sort_convert_iter_to_child_iter (impl->sort_model, &child_iter, iter);
2269- file_path = _gtk_file_system_model_get_path (fs_model, &child_iter);
2270- break;
2271-
2272- case OPERATION_MODE_SEARCH:
2273- search_get_valid_child_iter (impl, &child_iter, iter);
2274- gtk_tree_model_get (GTK_TREE_MODEL (impl->search_model), &child_iter,
2275- SEARCH_MODEL_COL_PATH, &file_path,
2276- -1);
2277- break;
2278-
2279- case OPERATION_MODE_RECENT:
2280- recent_get_valid_child_iter (impl, &child_iter, iter);
2281- gtk_tree_model_get (GTK_TREE_MODEL (impl->recent_model), &child_iter,
2282- RECENT_MODEL_COL_PATH, &file_path,
2283- -1);
2284- break;
2285- }
2286-
2287- shortcuts_add_bookmark_from_path (impl, file_path, -1);
2288-}
2289-
2290-/* Adds a bookmark from the currently selected item in the file list */
2291-static void
2292-bookmarks_add_selected_folder (GtkFileChooserDefault *impl)
2293-{
2294- GtkTreeSelection *selection;
2295-
2296- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_files_tree_view));
2297-
2298- if (gtk_tree_selection_count_selected_rows (selection) == 0)
2299- shortcuts_add_bookmark_from_path (impl, impl->current_folder, -1);
2300- else
2301- gtk_tree_selection_selected_foreach (selection,
2302- add_bookmark_foreach_cb,
2303- impl);
2304-}
2305-
2306-/* Callback used when the "Add bookmark" button is clicked */
2307-static void
2308-add_bookmark_button_clicked_cb (GtkButton *button,
2309- GtkFileChooserDefault *impl)
2310-{
2311- bookmarks_add_selected_folder (impl);
2312-}
2313-
2314-/* Returns TRUE plus an iter in the shortcuts_model if a row is selected;
2315- * returns FALSE if no shortcut is selected.
2316- */
2317-static gboolean
2318-shortcuts_get_selected (GtkFileChooserDefault *impl,
2319- GtkTreeIter *iter)
2320-{
2321- GtkTreeSelection *selection;
2322- GtkTreeIter parent_iter;
2323-
2324- if (!impl->browse_shortcuts_tree_view)
2325- return FALSE;
2326-
2327- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_shortcuts_tree_view));
2328-
2329- if (!gtk_tree_selection_get_selected (selection, NULL, &parent_iter))
2330- return FALSE;
2331-
2332- gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER (impl->shortcuts_pane_filter_model),
2333- iter,
2334- &parent_iter);
2335- return TRUE;
2336-}
2337-
2338-/* Removes the selected bookmarks */
2339-static void
2340-remove_selected_bookmarks (GtkFileChooserDefault *impl)
2341-{
2342- GtkTreeIter iter;
2343- gpointer col_data;
2344- GtkFilePath *path;
2345- gboolean removable;
2346- GError *error;
2347-
2348- if (!shortcuts_get_selected (impl, &iter))
2349- return;
2350-
2351- gtk_tree_model_get (GTK_TREE_MODEL (impl->shortcuts_model), &iter,
2352- SHORTCUTS_COL_DATA, &col_data,
2353- SHORTCUTS_COL_REMOVABLE, &removable,
2354- -1);
2355-
2356- if (!removable)
2357- return;
2358-
2359- g_assert (col_data != NULL);
2360-
2361- path = col_data;
2362-
2363- error = NULL;
2364- if (!gtk_file_system_remove_bookmark (impl->file_system, path, &error))
2365- error_removing_bookmark_dialog (impl, path, error);
2366-}
2367-
2368-/* Callback used when the "Remove bookmark" button is clicked */
2369-static void
2370-remove_bookmark_button_clicked_cb (GtkButton *button,
2371- GtkFileChooserDefault *impl)
2372-{
2373- remove_selected_bookmarks (impl);
2374-}
2375-
2376 struct selection_check_closure {
2377 GtkFileChooserDefault *impl;
2378 int num_selected;
2379@@ -2856,29 +1113,11 @@
2380 closure = data;
2381 closure->num_selected++;
2382
2383- switch (closure->impl->operation_mode)
2384- {
2385- case OPERATION_MODE_BROWSE:
2386- gtk_tree_model_sort_convert_iter_to_child_iter (closure->impl->sort_model, &child_iter, iter);
2387- info = _gtk_file_system_model_get_info (closure->impl->browse_files_model, &child_iter);
2388- is_folder = info ? gtk_file_info_get_is_folder (info) : FALSE;
2389- break;
2390+ gtk_tree_model_sort_convert_iter_to_child_iter (closure->impl->sort_model, &child_iter, iter);
2391
2392- case OPERATION_MODE_SEARCH:
2393- search_get_valid_child_iter (closure->impl, &child_iter, iter);
2394- gtk_tree_model_get (GTK_TREE_MODEL (closure->impl->search_model), &child_iter,
2395- SEARCH_MODEL_COL_IS_FOLDER, &is_folder,
2396- -1);
2397- break;
2398+ info = _gtk_file_system_model_get_info (closure->impl->browse_files_model, &child_iter);
2399+ is_folder = info ? gtk_file_info_get_is_folder (info) : FALSE;
2400
2401- case OPERATION_MODE_RECENT:
2402- recent_get_valid_child_iter (closure->impl, &child_iter, iter);
2403- gtk_tree_model_get (GTK_TREE_MODEL (closure->impl->recent_model), &child_iter,
2404- RECENT_MODEL_COL_IS_FOLDER, &is_folder,
2405- -1);
2406- break;
2407- }
2408-
2409 closure->all_folders = closure->all_folders && is_folder;
2410 closure->all_files = closure->all_files && !is_folder;
2411 }
2412@@ -2920,1126 +1159,6 @@
2413 const GtkFilePath *path;
2414 };
2415
2416-static void
2417-get_selected_path_foreach_cb (GtkTreeModel *model,
2418- GtkTreePath *path,
2419- GtkTreeIter *iter,
2420- gpointer data)
2421-{
2422- struct get_selected_path_closure *closure;
2423- GtkTreeIter child_iter;
2424-
2425- closure = data;
2426-
2427- switch (closure->impl->operation_mode)
2428- {
2429- case OPERATION_MODE_BROWSE:
2430- gtk_tree_model_sort_convert_iter_to_child_iter (closure->impl->sort_model, &child_iter, iter);
2431- closure->path = _gtk_file_system_model_get_path (closure->impl->browse_files_model, &child_iter);
2432- break;
2433-
2434- case OPERATION_MODE_SEARCH:
2435- search_get_valid_child_iter (closure->impl, &child_iter, iter);
2436- gtk_tree_model_get (GTK_TREE_MODEL (closure->impl->search_model), &child_iter,
2437- SEARCH_MODEL_COL_PATH, &closure->path,
2438- -1);
2439- break;
2440-
2441- case OPERATION_MODE_RECENT:
2442- recent_get_valid_child_iter (closure->impl, &child_iter, iter);
2443- gtk_tree_model_get (GTK_TREE_MODEL (closure->impl->recent_model), &child_iter,
2444- RECENT_MODEL_COL_PATH, &closure->path,
2445- -1);
2446- break;
2447- }
2448-}
2449-
2450-/* Returns a selected path from the file list */
2451-static const GtkFilePath *
2452-get_selected_path (GtkFileChooserDefault *impl)
2453-{
2454- struct get_selected_path_closure closure;
2455- GtkTreeSelection *selection;
2456-
2457- closure.impl = impl;
2458- closure.path = NULL;
2459-
2460- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_files_tree_view));
2461- gtk_tree_selection_selected_foreach (selection,
2462- get_selected_path_foreach_cb,
2463- &closure);
2464-
2465- return closure.path;
2466-}
2467-
2468-typedef struct {
2469- GtkFileChooserDefault *impl;
2470- gchar *tip;
2471-} UpdateTooltipData;
2472-
2473-static void
2474-update_tooltip (GtkTreeModel *model,
2475- GtkTreePath *path,
2476- GtkTreeIter *iter,
2477- gpointer data)
2478-{
2479- UpdateTooltipData *udata = data;
2480- GtkTreeIter child_iter;
2481- const GtkFileInfo *info;
2482-
2483- if (udata->tip == NULL)
2484- {
2485- const gchar *display_name;
2486-
2487- switch (udata->impl->operation_mode)
2488- {
2489- case OPERATION_MODE_BROWSE:
2490- gtk_tree_model_sort_convert_iter_to_child_iter (udata->impl->sort_model,
2491- &child_iter,
2492- iter);
2493- info = _gtk_file_system_model_get_info (udata->impl->browse_files_model, &child_iter);
2494- display_name = gtk_file_info_get_display_name (info);
2495- break;
2496-
2497- case OPERATION_MODE_SEARCH:
2498- search_get_valid_child_iter (udata->impl, &child_iter, iter);
2499- gtk_tree_model_get (GTK_TREE_MODEL (udata->impl->search_model), &child_iter,
2500- SEARCH_MODEL_COL_DISPLAY_NAME, &display_name,
2501- -1);
2502- break;
2503-
2504- case OPERATION_MODE_RECENT:
2505- recent_get_valid_child_iter (udata->impl, &child_iter, iter);
2506- gtk_tree_model_get (GTK_TREE_MODEL (udata->impl->recent_model), &child_iter,
2507- RECENT_MODEL_COL_DISPLAY_NAME, &display_name,
2508- -1);
2509- break;
2510- }
2511-
2512- udata->tip = g_strdup_printf (_("Add the folder '%s' to the bookmarks"),
2513- display_name);
2514- }
2515-}
2516-
2517-
2518-/* Sensitize the "add bookmark" button if all the selected items are folders, or
2519- * if there are no selected items *and* the current folder is not in the
2520- * bookmarks list. De-sensitize the button otherwise.
2521- */
2522-static void
2523-bookmarks_check_add_sensitivity (GtkFileChooserDefault *impl)
2524-{
2525- gint num_selected;
2526- gboolean all_folders;
2527- gboolean active;
2528- gchar *tip;
2529-
2530- selection_check (impl, &num_selected, NULL, &all_folders);
2531-
2532- if (num_selected == 0)
2533- active = (impl->current_folder != NULL) && (shortcut_find_position (impl, impl->current_folder) == -1);
2534- else if (num_selected == 1)
2535- {
2536- const GtkFilePath *path;
2537-
2538- path = get_selected_path (impl);
2539- active = all_folders && (shortcut_find_position (impl, path) == -1);
2540- }
2541- else
2542- active = all_folders;
2543-
2544- gtk_widget_set_sensitive (impl->browse_shortcuts_add_button, active);
2545-
2546- if (impl->browse_files_popup_menu_add_shortcut_item)
2547- gtk_widget_set_sensitive (impl->browse_files_popup_menu_add_shortcut_item,
2548- (num_selected == 0) ? FALSE : active);
2549-
2550- if (active)
2551- {
2552- if (num_selected == 0)
2553- tip = g_strdup_printf (_("Add the current folder to the bookmarks"));
2554- else if (num_selected > 1)
2555- tip = g_strdup_printf (_("Add the selected folders to the bookmarks"));
2556- else
2557- {
2558- GtkTreeSelection *selection;
2559- UpdateTooltipData data;
2560-
2561- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_files_tree_view));
2562- data.impl = impl;
2563- data.tip = NULL;
2564- gtk_tree_selection_selected_foreach (selection, update_tooltip, &data);
2565- tip = data.tip;
2566- }
2567-
2568- gtk_widget_set_tooltip_text (impl->browse_shortcuts_add_button, tip);
2569- g_free (tip);
2570- }
2571-}
2572-
2573-/* Sets the sensitivity of the "remove bookmark" button depending on whether a
2574- * bookmark row is selected in the shortcuts tree.
2575- */
2576-static void
2577-bookmarks_check_remove_sensitivity (GtkFileChooserDefault *impl)
2578-{
2579- GtkTreeIter iter;
2580- gboolean removable = FALSE;
2581- gchar *name = NULL;
2582-
2583- if (shortcuts_get_selected (impl, &iter))
2584- gtk_tree_model_get (GTK_TREE_MODEL (impl->shortcuts_model), &iter,
2585- SHORTCUTS_COL_REMOVABLE, &removable,
2586- SHORTCUTS_COL_NAME, &name,
2587- -1);
2588-
2589- gtk_widget_set_sensitive (impl->browse_shortcuts_remove_button, removable);
2590-
2591- if (removable)
2592- {
2593- gchar *tip;
2594-
2595- tip = g_strdup_printf (_("Remove the bookmark '%s'"), name);
2596- gtk_widget_set_tooltip_text (impl->browse_shortcuts_remove_button, tip);
2597- g_free (tip);
2598- }
2599-
2600- g_free (name);
2601-}
2602-
2603-static void
2604-shortcuts_check_popup_sensitivity (GtkFileChooserDefault *impl)
2605-{
2606- GtkTreeIter iter;
2607- gboolean removable = FALSE;
2608-
2609- if (impl->browse_shortcuts_popup_menu == NULL)
2610- return;
2611-
2612- if (shortcuts_get_selected (impl, &iter))
2613- gtk_tree_model_get (GTK_TREE_MODEL (impl->shortcuts_model), &iter,
2614- SHORTCUTS_COL_REMOVABLE, &removable,
2615- -1);
2616-
2617- gtk_widget_set_sensitive (impl->browse_shortcuts_popup_menu_remove_item, removable);
2618- gtk_widget_set_sensitive (impl->browse_shortcuts_popup_menu_rename_item, removable);
2619-}
2620-
2621-/* GtkWidget::drag-begin handler for the shortcuts list. */
2622-static void
2623-shortcuts_drag_begin_cb (GtkWidget *widget,
2624- GdkDragContext *context,
2625- GtkFileChooserDefault *impl)
2626-{
2627-#if 0
2628- impl->shortcuts_drag_context = g_object_ref (context);
2629-#endif
2630-}
2631-
2632-#if 0
2633-/* Removes the idle handler for outside drags */
2634-static void
2635-shortcuts_cancel_drag_outside_idle (GtkFileChooserDefault *impl)
2636-{
2637- if (!impl->shortcuts_drag_outside_idle)
2638- return;
2639-
2640- g_source_destroy (impl->shortcuts_drag_outside_idle);
2641- impl->shortcuts_drag_outside_idle = NULL;
2642-}
2643-#endif
2644-
2645-/* GtkWidget::drag-end handler for the shortcuts list. */
2646-static void
2647-shortcuts_drag_end_cb (GtkWidget *widget,
2648- GdkDragContext *context,
2649- GtkFileChooserDefault *impl)
2650-{
2651-#if 0
2652- g_object_unref (impl->shortcuts_drag_context);
2653-
2654- shortcuts_cancel_drag_outside_idle (impl);
2655-
2656- if (!impl->shortcuts_drag_outside)
2657- return;
2658-
2659- gtk_button_clicked (GTK_BUTTON (impl->browse_shortcuts_remove_button));
2660-
2661- impl->shortcuts_drag_outside = FALSE;
2662-#endif
2663-}
2664-
2665-/* GtkWidget::drag-data-delete handler for the shortcuts list. */
2666-static void
2667-shortcuts_drag_data_delete_cb (GtkWidget *widget,
2668- GdkDragContext *context,
2669- GtkFileChooserDefault *impl)
2670-{
2671- g_signal_stop_emission_by_name (widget, "drag_data_delete");
2672-}
2673-
2674-#if 0
2675-/* Creates a suitable drag cursor to indicate that the selected bookmark will be
2676- * deleted or not.
2677- */
2678-static void
2679-shortcuts_drag_set_delete_cursor (GtkFileChooserDefault *impl,
2680- gboolean delete)
2681-{
2682- GtkTreeView *tree_view;
2683- GtkTreeIter iter;
2684- GtkTreePath *path;
2685- GdkPixmap *row_pixmap;
2686- GdkBitmap *mask;
2687- int row_pixmap_y;
2688- int cell_y;
2689-
2690- tree_view = GTK_TREE_VIEW (impl->browse_shortcuts_tree_view);
2691-
2692- /* Find the selected path and get its drag pixmap */
2693-
2694- if (!shortcuts_get_selected (impl, &iter))
2695- g_assert_not_reached ();
2696-
2697- path = gtk_tree_model_get_path (GTK_TREE_MODEL (impl->shortcuts_model), &iter);
2698-
2699- row_pixmap = gtk_tree_view_create_row_drag_icon (tree_view, path);
2700- gtk_tree_path_free (path);
2701-
2702- mask = NULL;
2703- row_pixmap_y = 0;
2704-
2705- if (delete)
2706- {
2707- GdkPixbuf *pixbuf;
2708-
2709- pixbuf = gtk_widget_render_icon (impl->browse_shortcuts_tree_view,
2710- GTK_STOCK_DELETE,
2711- GTK_ICON_SIZE_DND,
2712- NULL);
2713- if (pixbuf)
2714- {
2715- GdkPixmap *composite;
2716- int row_pixmap_width, row_pixmap_height;
2717- int pixbuf_width, pixbuf_height;
2718- int composite_width, composite_height;
2719- int pixbuf_x, pixbuf_y;
2720- GdkGC *gc, *mask_gc;
2721- GdkColor color;
2722- GdkBitmap *pixbuf_mask;
2723-
2724- /* Create pixmap and mask for composite image */
2725-
2726- gdk_drawable_get_size (row_pixmap, &row_pixmap_width, &row_pixmap_height);
2727- pixbuf_width = gdk_pixbuf_get_width (pixbuf);
2728- pixbuf_height = gdk_pixbuf_get_height (pixbuf);
2729-
2730- composite_width = MAX (row_pixmap_width, pixbuf_width);
2731- composite_height = MAX (row_pixmap_height, pixbuf_height);
2732-
2733- row_pixmap_y = (composite_height - row_pixmap_height) / 2;
2734-
2735- if (gtk_widget_get_direction (impl->browse_shortcuts_tree_view) == GTK_TEXT_DIR_RTL)
2736- pixbuf_x = 0;
2737- else
2738- pixbuf_x = composite_width - pixbuf_width;
2739-
2740- pixbuf_y = (composite_height - pixbuf_height) / 2;
2741-
2742- composite = gdk_pixmap_new (row_pixmap, composite_width, composite_height, -1);
2743- gc = gdk_gc_new (composite);
2744-
2745- mask = gdk_pixmap_new (row_pixmap, composite_width, composite_height, 1);
2746- mask_gc = gdk_gc_new (mask);
2747- color.pixel = 0;
2748- gdk_gc_set_foreground (mask_gc, &color);
2749- gdk_draw_rectangle (mask, mask_gc, TRUE, 0, 0, composite_width, composite_height);
2750-
2751- color.red = 0xffff;
2752- color.green = 0xffff;
2753- color.blue = 0xffff;
2754- gdk_gc_set_rgb_fg_color (gc, &color);
2755- gdk_draw_rectangle (composite, gc, TRUE, 0, 0, composite_width, composite_height);
2756-
2757- /* Composite the row pixmap and the pixbuf */
2758-
2759- gdk_pixbuf_render_pixmap_and_mask_for_colormap
2760- (pixbuf,
2761- gtk_widget_get_colormap (impl->browse_shortcuts_tree_view),
2762- NULL, &pixbuf_mask, 128);
2763- gdk_draw_drawable (mask, mask_gc, pixbuf_mask,
2764- 0, 0,
2765- pixbuf_x, pixbuf_y,
2766- pixbuf_width, pixbuf_height);
2767- g_object_unref (pixbuf_mask);
2768-
2769- gdk_draw_drawable (composite, gc, row_pixmap,
2770- 0, 0,
2771- 0, row_pixmap_y,
2772- row_pixmap_width, row_pixmap_height);
2773- color.pixel = 1;
2774- gdk_gc_set_foreground (mask_gc, &color);
2775- gdk_draw_rectangle (mask, mask_gc, TRUE, 0, row_pixmap_y, row_pixmap_width, row_pixmap_height);
2776-
2777- gdk_draw_pixbuf (composite, gc, pixbuf,
2778- 0, 0,
2779- pixbuf_x, pixbuf_y,
2780- pixbuf_width, pixbuf_height,
2781- GDK_RGB_DITHER_MAX,
2782- 0, 0);
2783-
2784- g_object_unref (pixbuf);
2785- g_object_unref (row_pixmap);
2786-
2787- row_pixmap = composite;
2788- }
2789- }
2790-
2791- /* The hotspot offsets here are copied from gtk_tree_view_drag_begin(), ugh */
2792-
2793- gtk_tree_view_get_path_at_pos (tree_view,
2794- tree_view->priv->press_start_x,
2795- tree_view->priv->press_start_y,
2796- NULL,
2797- NULL,
2798- NULL,
2799- &cell_y);
2800-
2801- gtk_drag_set_icon_pixmap (impl->shortcuts_drag_context,
2802- gdk_drawable_get_colormap (row_pixmap),
2803- row_pixmap,
2804- mask,
2805- tree_view->priv->press_start_x + 1,
2806- row_pixmap_y + cell_y + 1);
2807-
2808- g_object_unref (row_pixmap);
2809- if (mask)
2810- g_object_unref (mask);
2811-}
2812-
2813-/* We set the delete cursor and the shortcuts_drag_outside flag in an idle
2814- * handler so that we can tell apart the drag_leave event that comes right
2815- * before a drag_drop, from a normal drag_leave. We don't want to set the
2816- * cursor nor the flag in the latter case.
2817- */
2818-static gboolean
2819-shortcuts_drag_outside_idle_cb (GtkFileChooserDefault *impl)
2820-{
2821- GDK_THREADS_ENTER ();
2822-
2823- shortcuts_drag_set_delete_cursor (impl, TRUE);
2824- impl->shortcuts_drag_outside = TRUE;
2825-
2826- shortcuts_cancel_drag_outside_idle (impl);
2827-
2828- GDK_THREADS_LEAVE ();
2829-
2830- return FALSE;
2831-}
2832-#endif
2833-
2834-/* GtkWidget::drag-leave handler for the shortcuts list. We unhighlight the
2835- * drop position.
2836- */
2837-static void
2838-shortcuts_drag_leave_cb (GtkWidget *widget,
2839- GdkDragContext *context,
2840- guint time_,
2841- GtkFileChooserDefault *impl)
2842-{
2843-#if 0
2844- if (gtk_drag_get_source_widget (context) == widget && !impl->shortcuts_drag_outside_idle)
2845- {
2846- impl->shortcuts_drag_outside_idle = g_idle_source_new ();
2847- g_source_set_closure (impl->shortcuts_drag_outside_idle,
2848- g_cclosure_new_object (G_CALLBACK (shortcuts_drag_outside_idle_cb),
2849- G_OBJECT (impl)));
2850- g_source_attach (impl->shortcuts_drag_outside_idle, NULL);
2851- }
2852-#endif
2853-
2854- gtk_tree_view_set_drag_dest_row (GTK_TREE_VIEW (impl->browse_shortcuts_tree_view),
2855- NULL,
2856- GTK_TREE_VIEW_DROP_BEFORE);
2857-
2858- g_signal_stop_emission_by_name (widget, "drag_leave");
2859-}
2860-
2861-/* Computes the appropriate row and position for dropping */
2862-static void
2863-shortcuts_compute_drop_position (GtkFileChooserDefault *impl,
2864- int x,
2865- int y,
2866- GtkTreePath **path,
2867- GtkTreeViewDropPosition *pos)
2868-{
2869- GtkTreeView *tree_view;
2870- GtkTreeViewColumn *column;
2871- int cell_y;
2872- GdkRectangle cell;
2873- int row;
2874- int bookmarks_index;
2875-
2876- tree_view = GTK_TREE_VIEW (impl->browse_shortcuts_tree_view);
2877-
2878- bookmarks_index = shortcuts_get_index (impl, SHORTCUTS_BOOKMARKS);
2879-
2880- if (!gtk_tree_view_get_path_at_pos (tree_view,
2881- x,
2882- y - TREE_VIEW_HEADER_HEIGHT (tree_view),
2883- path,
2884- &column,
2885- NULL,
2886- &cell_y))
2887- {
2888- row = bookmarks_index + impl->num_bookmarks - 1;
2889- *path = gtk_tree_path_new_from_indices (row, -1);
2890- *pos = GTK_TREE_VIEW_DROP_AFTER;
2891- return;
2892- }
2893-
2894- row = *gtk_tree_path_get_indices (*path);
2895- gtk_tree_view_get_background_area (tree_view, *path, column, &cell);
2896- gtk_tree_path_free (*path);
2897-
2898- if (row < bookmarks_index)
2899- {
2900- row = bookmarks_index;
2901- *pos = GTK_TREE_VIEW_DROP_BEFORE;
2902- }
2903- else if (row > bookmarks_index + impl->num_bookmarks - 1)
2904- {
2905- row = bookmarks_index + impl->num_bookmarks - 1;
2906- *pos = GTK_TREE_VIEW_DROP_AFTER;
2907- }
2908- else
2909- {
2910- if (cell_y < cell.height / 2)
2911- *pos = GTK_TREE_VIEW_DROP_BEFORE;
2912- else
2913- *pos = GTK_TREE_VIEW_DROP_AFTER;
2914- }
2915-
2916- *path = gtk_tree_path_new_from_indices (row, -1);
2917-}
2918-
2919-/* GtkWidget::drag-motion handler for the shortcuts list. We basically
2920- * implement the destination side of DnD by hand, due to limitations in
2921- * GtkTreeView's DnD API.
2922- */
2923-static gboolean
2924-shortcuts_drag_motion_cb (GtkWidget *widget,
2925- GdkDragContext *context,
2926- gint x,
2927- gint y,
2928- guint time_,
2929- GtkFileChooserDefault *impl)
2930-{
2931- GtkTreePath *path;
2932- GtkTreeViewDropPosition pos;
2933- GdkDragAction action;
2934-
2935-#if 0
2936- if (gtk_drag_get_source_widget (context) == widget)
2937- {
2938- shortcuts_cancel_drag_outside_idle (impl);
2939-
2940- if (impl->shortcuts_drag_outside)
2941- {
2942- shortcuts_drag_set_delete_cursor (impl, FALSE);
2943- impl->shortcuts_drag_outside = FALSE;
2944- }
2945- }
2946-#endif
2947-
2948- if (context->suggested_action == GDK_ACTION_COPY ||
2949- (context->actions & GDK_ACTION_COPY) != 0)
2950- action = GDK_ACTION_COPY;
2951- else if (context->suggested_action == GDK_ACTION_MOVE ||
2952- (context->actions & GDK_ACTION_MOVE) != 0)
2953- action = GDK_ACTION_MOVE;
2954- else
2955- {
2956- action = 0;
2957- goto out;
2958- }
2959-
2960- shortcuts_compute_drop_position (impl, x, y, &path, &pos);
2961- gtk_tree_view_set_drag_dest_row (GTK_TREE_VIEW (impl->browse_shortcuts_tree_view), path, pos);
2962- gtk_tree_path_free (path);
2963-
2964- out:
2965-
2966- g_signal_stop_emission_by_name (widget, "drag_motion");
2967-
2968- if (action != 0)
2969- {
2970- gdk_drag_status (context, action, time_);
2971- return TRUE;
2972- }
2973- else
2974- return FALSE;
2975-}
2976-
2977-/* GtkWidget::drag-drop handler for the shortcuts list. */
2978-static gboolean
2979-shortcuts_drag_drop_cb (GtkWidget *widget,
2980- GdkDragContext *context,
2981- gint x,
2982- gint y,
2983- guint time_,
2984- GtkFileChooserDefault *impl)
2985-{
2986-#if 0
2987- shortcuts_cancel_drag_outside_idle (impl);
2988-#endif
2989-
2990- g_signal_stop_emission_by_name (widget, "drag_drop");
2991- return TRUE;
2992-}
2993-
2994-/* Parses a "text/uri-list" string and inserts its URIs as bookmarks */
2995-static void
2996-shortcuts_drop_uris (GtkFileChooserDefault *impl,
2997- const char *data,
2998- int position)
2999-{
3000- gchar **uris;
3001- gint i;
3002-
3003- uris = g_uri_list_extract_uris (data);
3004-
3005- for (i = 0; uris[i]; i++)
3006- {
3007- char *uri;
3008- GtkFilePath *path;
3009-
3010- uri = uris[i];
3011- path = gtk_file_system_uri_to_path (impl->file_system, uri);
3012-
3013- if (path)
3014- {
3015- if (shortcuts_add_bookmark_from_path (impl, path, position))
3016- position++;
3017-
3018- gtk_file_path_free (path);
3019- }
3020- else
3021- {
3022- GError *error = NULL;
3023-
3024- g_set_error (&error,
3025- GTK_FILE_CHOOSER_ERROR,
3026- GTK_FILE_CHOOSER_ERROR_BAD_FILENAME,
3027- _("Could not add a bookmark for '%s' "
3028- "because it is an invalid path name."),
3029- uri);
3030- error_adding_bookmark_dialog (impl, path, error);
3031- }
3032- }
3033-
3034- g_strfreev (uris);
3035-}
3036-
3037-/* Reorders the selected bookmark to the specified position */
3038-static void
3039-shortcuts_reorder (GtkFileChooserDefault *impl,
3040- int new_position)
3041-{
3042- GtkTreeIter iter;
3043- gpointer col_data;
3044- ShortcutType shortcut_type;
3045- GtkTreePath *path;
3046- int old_position;
3047- int bookmarks_index;
3048- const GtkFilePath *file_path;
3049- GtkFilePath *file_path_copy;
3050- GError *error;
3051- gchar *name;
3052-
3053- /* Get the selected path */
3054-
3055- if (!shortcuts_get_selected (impl, &iter))
3056- g_assert_not_reached ();
3057-
3058- path = gtk_tree_model_get_path (GTK_TREE_MODEL (impl->shortcuts_model), &iter);
3059- old_position = *gtk_tree_path_get_indices (path);
3060- gtk_tree_path_free (path);
3061-
3062- bookmarks_index = shortcuts_get_index (impl, SHORTCUTS_BOOKMARKS);
3063- old_position -= bookmarks_index;
3064- g_assert (old_position >= 0 && old_position < impl->num_bookmarks);
3065-
3066- gtk_tree_model_get (GTK_TREE_MODEL (impl->shortcuts_model), &iter,
3067- SHORTCUTS_COL_NAME, &name,
3068- SHORTCUTS_COL_DATA, &col_data,
3069- SHORTCUTS_COL_TYPE, &shortcut_type,
3070- -1);
3071- g_assert (col_data != NULL);
3072- g_assert (shortcut_type == SHORTCUT_TYPE_PATH);
3073-
3074- file_path = col_data;
3075- file_path_copy = gtk_file_path_copy (file_path); /* removal below will free file_path, so we need a copy */
3076-
3077- /* Remove the path from the old position and insert it in the new one */
3078-
3079- if (new_position > old_position)
3080- new_position--;
3081-
3082- if (old_position == new_position)
3083- goto out;
3084-
3085- error = NULL;
3086- if (gtk_file_system_remove_bookmark (impl->file_system, file_path_copy, &error))
3087- {
3088- shortcuts_add_bookmark_from_path (impl, file_path_copy, new_position);
3089- gtk_file_system_set_bookmark_label (impl->file_system, file_path_copy, name);
3090- }
3091- else
3092- error_adding_bookmark_dialog (impl, file_path_copy, error);
3093-
3094- out:
3095-
3096- gtk_file_path_free (file_path_copy);
3097-}
3098-
3099-/* Callback used when we get the drag data for the bookmarks list. We add the
3100- * received URIs as bookmarks if they are folders.
3101- */
3102-static void
3103-shortcuts_drag_data_received_cb (GtkWidget *widget,
3104- GdkDragContext *context,
3105- gint x,
3106- gint y,
3107- GtkSelectionData *selection_data,
3108- guint info,
3109- guint time_,
3110- gpointer data)
3111-{
3112- GtkFileChooserDefault *impl;
3113- GtkTreePath *tree_path;
3114- GtkTreeViewDropPosition tree_pos;
3115- int position;
3116- int bookmarks_index;
3117-
3118- impl = GTK_FILE_CHOOSER_DEFAULT (data);
3119-
3120- /* Compute position */
3121-
3122- bookmarks_index = shortcuts_get_index (impl, SHORTCUTS_BOOKMARKS);
3123-
3124- shortcuts_compute_drop_position (impl, x, y, &tree_path, &tree_pos);
3125- position = *gtk_tree_path_get_indices (tree_path);
3126- gtk_tree_path_free (tree_path);
3127-
3128- if (tree_pos == GTK_TREE_VIEW_DROP_AFTER)
3129- position++;
3130-
3131- g_assert (position >= bookmarks_index);
3132- position -= bookmarks_index;
3133-
3134- if (selection_data->target == gdk_atom_intern_static_string ("text/uri-list"))
3135- shortcuts_drop_uris (impl, (const char *) selection_data->data, position);
3136- else if (selection_data->target == gdk_atom_intern_static_string ("GTK_TREE_MODEL_ROW"))
3137- shortcuts_reorder (impl, position);
3138-
3139- g_signal_stop_emission_by_name (widget, "drag_data_received");
3140-}
3141-
3142-/* Callback used when the selection in the shortcuts tree changes */
3143-static void
3144-shortcuts_selection_changed_cb (GtkTreeSelection *selection,
3145- GtkFileChooserDefault *impl)
3146-{
3147- bookmarks_check_remove_sensitivity (impl);
3148- shortcuts_check_popup_sensitivity (impl);
3149-}
3150-
3151-static gboolean
3152-shortcuts_row_separator_func (GtkTreeModel *model,
3153- GtkTreeIter *iter,
3154- gpointer data)
3155-{
3156- ShortcutType shortcut_type;
3157-
3158- gtk_tree_model_get (model, iter, SHORTCUTS_COL_TYPE, &shortcut_type, -1);
3159-
3160- return shortcut_type == SHORTCUT_TYPE_SEPARATOR;
3161-}
3162-
3163-/* Since GtkTreeView has a keybinding attached to '/', we need to catch
3164- * keypresses before the TreeView gets them.
3165- */
3166-static gboolean
3167-tree_view_keybinding_cb (GtkWidget *tree_view,
3168- GdkEventKey *event,
3169- GtkFileChooserDefault *impl)
3170-{
3171- if ((event->keyval == GDK_slash
3172- || event->keyval == GDK_KP_Divide
3173-#ifdef G_OS_UNIX
3174- || event->keyval == GDK_asciitilde
3175-#endif
3176- ) && ! (event->state & (~GDK_SHIFT_MASK & gtk_accelerator_get_default_mod_mask ())))
3177- {
3178- location_popup_handler (impl, event->string);
3179- return TRUE;
3180- }
3181-
3182- return FALSE;
3183-}
3184-
3185-/* Callback used when the file list's popup menu is detached */
3186-static void
3187-shortcuts_popup_menu_detach_cb (GtkWidget *attach_widget,
3188- GtkMenu *menu)
3189-{
3190- GtkFileChooserDefault *impl;
3191-
3192- impl = g_object_get_data (G_OBJECT (attach_widget), "GtkFileChooserDefault");
3193- g_assert (GTK_IS_FILE_CHOOSER_DEFAULT (impl));
3194-
3195- impl->browse_shortcuts_popup_menu = NULL;
3196- impl->browse_shortcuts_popup_menu_remove_item = NULL;
3197- impl->browse_shortcuts_popup_menu_rename_item = NULL;
3198-}
3199-
3200-static void
3201-remove_shortcut_cb (GtkMenuItem *item,
3202- GtkFileChooserDefault *impl)
3203-{
3204- remove_selected_bookmarks (impl);
3205-}
3206-
3207-/* Rename the selected bookmark */
3208-static void
3209-rename_selected_bookmark (GtkFileChooserDefault *impl)
3210-{
3211- GtkTreeIter iter;
3212- GtkTreePath *path;
3213- GtkTreeViewColumn *column;
3214- GtkCellRenderer *cell;
3215- GList *renderers;
3216-
3217- if (shortcuts_get_selected (impl, &iter))
3218- {
3219- path = gtk_tree_model_get_path (GTK_TREE_MODEL (impl->shortcuts_model), &iter);
3220- column = gtk_tree_view_get_column (GTK_TREE_VIEW (impl->browse_shortcuts_tree_view), 0);
3221- renderers = gtk_tree_view_column_get_cell_renderers (column);
3222- cell = g_list_nth_data (renderers, 1);
3223- g_list_free (renderers);
3224- g_object_set (cell, "editable", TRUE, NULL);
3225- gtk_tree_view_set_cursor_on_cell (GTK_TREE_VIEW (impl->browse_shortcuts_tree_view),
3226- path, column, cell, TRUE);
3227- gtk_tree_path_free (path);
3228- }
3229-}
3230-
3231-static void
3232-rename_shortcut_cb (GtkMenuItem *item,
3233- GtkFileChooserDefault *impl)
3234-{
3235- rename_selected_bookmark (impl);
3236-}
3237-
3238-/* Constructs the popup menu for the file list if needed */
3239-static void
3240-shortcuts_build_popup_menu (GtkFileChooserDefault *impl)
3241-{
3242- GtkWidget *item;
3243-
3244- if (impl->browse_shortcuts_popup_menu)
3245- return;
3246-
3247- impl->browse_shortcuts_popup_menu = gtk_menu_new ();
3248- gtk_menu_attach_to_widget (GTK_MENU (impl->browse_shortcuts_popup_menu),
3249- impl->browse_shortcuts_tree_view,
3250- shortcuts_popup_menu_detach_cb);
3251-
3252- item = gtk_image_menu_item_new_with_label (_("Remove"));
3253- impl->browse_shortcuts_popup_menu_remove_item = item;
3254- gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item),
3255- gtk_image_new_from_stock (GTK_STOCK_REMOVE, GTK_ICON_SIZE_MENU));
3256- g_signal_connect (item, "activate",
3257- G_CALLBACK (remove_shortcut_cb), impl);
3258- gtk_widget_show (item);
3259- gtk_menu_shell_append (GTK_MENU_SHELL (impl->browse_shortcuts_popup_menu), item);
3260-
3261- item = gtk_menu_item_new_with_label (_("Rename..."));
3262- impl->browse_shortcuts_popup_menu_rename_item = item;
3263- g_signal_connect (item, "activate",
3264- G_CALLBACK (rename_shortcut_cb), impl);
3265- gtk_widget_show (item);
3266- gtk_menu_shell_append (GTK_MENU_SHELL (impl->browse_shortcuts_popup_menu), item);
3267-
3268- shortcuts_check_popup_sensitivity (impl);
3269-}
3270-
3271-static void
3272-shortcuts_update_popup_menu (GtkFileChooserDefault *impl)
3273-{
3274- shortcuts_build_popup_menu (impl);
3275-}
3276-
3277-static void
3278-popup_position_func (GtkMenu *menu,
3279- gint *x,
3280- gint *y,
3281- gboolean *push_in,
3282- gpointer user_data);
3283-
3284-static void
3285-shortcuts_popup_menu (GtkFileChooserDefault *impl,
3286- GdkEventButton *event)
3287-{
3288- shortcuts_update_popup_menu (impl);
3289- if (event)
3290- gtk_menu_popup (GTK_MENU (impl->browse_shortcuts_popup_menu),
3291- NULL, NULL, NULL, NULL,
3292- event->button, event->time);
3293- else
3294- {
3295- gtk_menu_popup (GTK_MENU (impl->browse_shortcuts_popup_menu),
3296- NULL, NULL,
3297- popup_position_func, impl->browse_shortcuts_tree_view,
3298- 0, GDK_CURRENT_TIME);
3299- gtk_menu_shell_select_first (GTK_MENU_SHELL (impl->browse_shortcuts_popup_menu),
3300- FALSE);
3301- }
3302-}
3303-
3304-/* Callback used for the GtkWidget::popup-menu signal of the shortcuts list */
3305-static gboolean
3306-shortcuts_popup_menu_cb (GtkWidget *widget,
3307- GtkFileChooserDefault *impl)
3308-{
3309- shortcuts_popup_menu (impl, NULL);
3310- return TRUE;
3311-}
3312-
3313-/* Callback used when a button is pressed on the shortcuts list.
3314- * We trap button 3 to bring up a popup menu.
3315- */
3316-static gboolean
3317-shortcuts_button_press_event_cb (GtkWidget *widget,
3318- GdkEventButton *event,
3319- GtkFileChooserDefault *impl)
3320-{
3321- static gboolean in_press = FALSE;
3322- gboolean handled;
3323-
3324- if (in_press)
3325- return FALSE;
3326-
3327- if (event->button != 3)
3328- return FALSE;
3329-
3330- in_press = TRUE;
3331- handled = gtk_widget_event (impl->browse_shortcuts_tree_view, (GdkEvent *) event);
3332- in_press = FALSE;
3333-
3334- if (!handled)
3335- return FALSE;
3336-
3337- shortcuts_popup_menu (impl, event);
3338- return TRUE;
3339-}
3340-
3341-static void
3342-shortcuts_edited (GtkCellRenderer *cell,
3343- gchar *path_string,
3344- gchar *new_text,
3345- GtkFileChooserDefault *impl)
3346-{
3347- GtkTreePath *path;
3348- GtkTreeIter iter;
3349- GtkFilePath *shortcut;
3350-
3351- g_object_set (cell, "editable", FALSE, NULL);
3352-
3353- path = gtk_tree_path_new_from_string (path_string);
3354- if (!gtk_tree_model_get_iter (GTK_TREE_MODEL (impl->shortcuts_model), &iter, path))
3355- g_assert_not_reached ();
3356-
3357- gtk_tree_model_get (GTK_TREE_MODEL (impl->shortcuts_model), &iter,
3358- SHORTCUTS_COL_DATA, &shortcut,
3359- -1);
3360- gtk_tree_path_free (path);
3361-
3362- gtk_file_system_set_bookmark_label (impl->file_system, shortcut, new_text);
3363-}
3364-
3365-static void
3366-shortcuts_editing_canceled (GtkCellRenderer *cell,
3367- GtkFileChooserDefault *impl)
3368-{
3369- g_object_set (cell, "editable", FALSE, NULL);
3370-}
3371-
3372-/* Creates the widgets for the shortcuts and bookmarks tree */
3373-static GtkWidget *
3374-shortcuts_list_create (GtkFileChooserDefault *impl)
3375-{
3376- GtkWidget *swin;
3377- GtkTreeSelection *selection;
3378- GtkTreeViewColumn *column;
3379- GtkCellRenderer *renderer;
3380-
3381- /* Scrolled window */
3382-
3383- swin = gtk_scrolled_window_new (NULL, NULL);
3384- gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (swin),
3385- GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
3386- gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (swin),
3387- GTK_SHADOW_IN);
3388- gtk_widget_show (swin);
3389-
3390- /* Tree */
3391-
3392- impl->browse_shortcuts_tree_view = gtk_tree_view_new ();
3393-#ifdef PROFILE_FILE_CHOOSER
3394- g_object_set_data (G_OBJECT (impl->browse_shortcuts_tree_view), "fmq-name", "shortcuts");
3395-#endif
3396- g_signal_connect (impl->browse_shortcuts_tree_view, "key_press_event",
3397- G_CALLBACK (tree_view_keybinding_cb), impl);
3398- g_signal_connect (impl->browse_shortcuts_tree_view, "popup_menu",
3399- G_CALLBACK (shortcuts_popup_menu_cb), impl);
3400- g_signal_connect (impl->browse_shortcuts_tree_view, "button_press_event",
3401- G_CALLBACK (shortcuts_button_press_event_cb), impl);
3402- /* Accessible object name for the file chooser's shortcuts pane */
3403- atk_object_set_name (gtk_widget_get_accessible (impl->browse_shortcuts_tree_view), _("Places"));
3404-
3405- gtk_tree_view_set_model (GTK_TREE_VIEW (impl->browse_shortcuts_tree_view), impl->shortcuts_pane_filter_model);
3406-
3407- gtk_tree_view_enable_model_drag_source (GTK_TREE_VIEW (impl->browse_shortcuts_tree_view),
3408- GDK_BUTTON1_MASK,
3409- shortcuts_source_targets,
3410- num_shortcuts_source_targets,
3411- GDK_ACTION_MOVE);
3412-
3413- gtk_drag_dest_set (impl->browse_shortcuts_tree_view,
3414- GTK_DEST_DEFAULT_ALL,
3415- shortcuts_dest_targets,
3416- num_shortcuts_dest_targets,
3417- GDK_ACTION_COPY | GDK_ACTION_MOVE);
3418-
3419- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_shortcuts_tree_view));
3420- gtk_tree_selection_set_mode (selection, GTK_SELECTION_BROWSE);
3421- gtk_tree_selection_set_select_function (selection,
3422- shortcuts_select_func,
3423- impl, NULL);
3424-
3425- g_signal_connect (selection, "changed",
3426- G_CALLBACK (shortcuts_selection_changed_cb), impl);
3427-
3428- g_signal_connect (impl->browse_shortcuts_tree_view, "row_activated",
3429- G_CALLBACK (shortcuts_row_activated_cb), impl);
3430-
3431- g_signal_connect (impl->browse_shortcuts_tree_view, "key_press_event",
3432- G_CALLBACK (shortcuts_key_press_event_cb), impl);
3433-
3434- g_signal_connect (impl->browse_shortcuts_tree_view, "drag_begin",
3435- G_CALLBACK (shortcuts_drag_begin_cb), impl);
3436- g_signal_connect (impl->browse_shortcuts_tree_view, "drag_end",
3437- G_CALLBACK (shortcuts_drag_end_cb), impl);
3438- g_signal_connect (impl->browse_shortcuts_tree_view, "drag_data_delete",
3439- G_CALLBACK (shortcuts_drag_data_delete_cb), impl);
3440-
3441- g_signal_connect (impl->browse_shortcuts_tree_view, "drag_leave",
3442- G_CALLBACK (shortcuts_drag_leave_cb), impl);
3443- g_signal_connect (impl->browse_shortcuts_tree_view, "drag_motion",
3444- G_CALLBACK (shortcuts_drag_motion_cb), impl);
3445- g_signal_connect (impl->browse_shortcuts_tree_view, "drag_drop",
3446- G_CALLBACK (shortcuts_drag_drop_cb), impl);
3447- g_signal_connect (impl->browse_shortcuts_tree_view, "drag_data_received",
3448- G_CALLBACK (shortcuts_drag_data_received_cb), impl);
3449-
3450- gtk_container_add (GTK_CONTAINER (swin), impl->browse_shortcuts_tree_view);
3451- gtk_widget_show (impl->browse_shortcuts_tree_view);
3452-
3453- /* Column */
3454-
3455- column = gtk_tree_view_column_new ();
3456- /* Column header for the file chooser's shortcuts pane */
3457- gtk_tree_view_column_set_title (column, _("_Places"));
3458-
3459- renderer = gtk_cell_renderer_pixbuf_new ();
3460- gtk_tree_view_column_pack_start (column, renderer, FALSE);
3461- gtk_tree_view_column_set_attributes (column, renderer,
3462- "pixbuf", SHORTCUTS_COL_PIXBUF,
3463- "visible", SHORTCUTS_COL_PIXBUF_VISIBLE,
3464- NULL);
3465-
3466- renderer = gtk_cell_renderer_text_new ();
3467- g_signal_connect (renderer, "edited",
3468- G_CALLBACK (shortcuts_edited), impl);
3469- g_signal_connect (renderer, "editing-canceled",
3470- G_CALLBACK (shortcuts_editing_canceled), impl);
3471- gtk_tree_view_column_pack_start (column, renderer, TRUE);
3472- gtk_tree_view_column_set_attributes (column, renderer,
3473- "text", SHORTCUTS_COL_NAME,
3474- NULL);
3475-
3476- gtk_tree_view_set_row_separator_func (GTK_TREE_VIEW (impl->browse_shortcuts_tree_view),
3477- shortcuts_row_separator_func,
3478- NULL, NULL);
3479-
3480- gtk_tree_view_append_column (GTK_TREE_VIEW (impl->browse_shortcuts_tree_view), column);
3481-
3482- return swin;
3483-}
3484-
3485-/* Creates the widgets for the shortcuts/bookmarks pane */
3486-static GtkWidget *
3487-shortcuts_pane_create (GtkFileChooserDefault *impl,
3488- GtkSizeGroup *size_group)
3489-{
3490- GtkWidget *vbox;
3491- GtkWidget *hbox;
3492- GtkWidget *widget;
3493-
3494- vbox = gtk_vbox_new (FALSE, 6);
3495- gtk_widget_show (vbox);
3496-
3497- /* Shortcuts tree */
3498-
3499- widget = shortcuts_list_create (impl);
3500- gtk_box_pack_start (GTK_BOX (vbox), widget, TRUE, TRUE, 0);
3501-
3502- /* Box for buttons */
3503-
3504- hbox = gtk_hbox_new (TRUE, 6);
3505- gtk_size_group_add_widget (size_group, hbox);
3506- gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
3507- gtk_widget_show (hbox);
3508-
3509- /* Add bookmark button */
3510-
3511- impl->browse_shortcuts_add_button = button_new (impl,
3512- _("_Add"),
3513- GTK_STOCK_ADD,
3514- FALSE,
3515- TRUE,
3516- G_CALLBACK (add_bookmark_button_clicked_cb));
3517- gtk_box_pack_start (GTK_BOX (hbox), impl->browse_shortcuts_add_button, TRUE, TRUE, 0);
3518- gtk_widget_set_tooltip_text (impl->browse_shortcuts_add_button,
3519- _("Add the selected folder to the Bookmarks"));
3520-
3521- /* Remove bookmark button */
3522-
3523- impl->browse_shortcuts_remove_button = button_new (impl,
3524- _("_Remove"),
3525- GTK_STOCK_REMOVE,
3526- FALSE,
3527- TRUE,
3528- G_CALLBACK (remove_bookmark_button_clicked_cb));
3529- gtk_box_pack_start (GTK_BOX (hbox), impl->browse_shortcuts_remove_button, TRUE, TRUE, 0);
3530- gtk_widget_set_tooltip_text (impl->browse_shortcuts_remove_button,
3531- _("Remove the selected bookmark"));
3532-
3533- return vbox;
3534-}
3535-
3536 /* Handles key press events on the file list, so that we can trap Enter to
3537 * activate the default button on our own. Also, checks to see if '/' has been
3538 * pressed. See comment by tree_view_keybinding_cb() for more details.
3539@@ -4056,17 +1175,6 @@
3540
3541 modifiers = gtk_accelerator_get_default_mod_mask ();
3542
3543- if ((event->keyval == GDK_slash
3544- || event->keyval == GDK_KP_Divide
3545-#ifdef G_OS_UNIX
3546- || event->keyval == GDK_asciitilde
3547-#endif
3548- ) && ! (event->state & (~GDK_SHIFT_MASK & modifiers)))
3549- {
3550- location_popup_handler (impl, event->string);
3551- return TRUE;
3552- }
3553-
3554 if ((event->keyval == GDK_Return
3555 || event->keyval == GDK_ISO_Enter
3556 || event->keyval == GDK_KP_Enter
3557@@ -4091,474 +1199,66 @@
3558 return FALSE;
3559 }
3560
3561-/* Callback used when the file list's popup menu is detached */
3562-static void
3563-popup_menu_detach_cb (GtkWidget *attach_widget,
3564- GtkMenu *menu)
3565+static gboolean
3566+list_button_press (GtkWidget *widget, GdkEventButton *event, gpointer data)
3567 {
3568- GtkFileChooserDefault *impl;
3569+ GtkTreeView * tree = GTK_TREE_VIEW (widget);
3570+ GtkFileChooserDefault *impl = data;
3571+ GtkTreePath *path;
3572
3573- impl = g_object_get_data (G_OBJECT (attach_widget), "GtkFileChooserDefault");
3574- g_assert (GTK_IS_FILE_CHOOSER_DEFAULT (impl));
3575-
3576- impl->browse_files_popup_menu = NULL;
3577- impl->browse_files_popup_menu_add_shortcut_item = NULL;
3578- impl->browse_files_popup_menu_hidden_files_item = NULL;
3579-}
3580-
3581-/* Callback used when the "Add to Bookmarks" menu item is activated */
3582-static void
3583-add_to_shortcuts_cb (GtkMenuItem *item,
3584- GtkFileChooserDefault *impl)
3585-{
3586- bookmarks_add_selected_folder (impl);
3587-}
3588-
3589-/* Callback used when the "Show Hidden Files" menu item is toggled */
3590-static void
3591-show_hidden_toggled_cb (GtkCheckMenuItem *item,
3592- GtkFileChooserDefault *impl)
3593-{
3594- g_object_set (impl,
3595- "show-hidden", gtk_check_menu_item_get_active (item),
3596- NULL);
3597-}
3598-
3599-/* Shows an error dialog about not being able to select a dragged file */
3600-static void
3601-error_selecting_dragged_file_dialog (GtkFileChooserDefault *impl,
3602- const GtkFilePath *path,
3603- GError *error)
3604-{
3605- error_dialog (impl,
3606- _("Could not select file"),
3607- path, error);
3608-}
3609-
3610-static void
3611-file_list_drag_data_select_uris (GtkFileChooserDefault *impl,
3612- gchar **uris)
3613-{
3614- int i;
3615- char *uri;
3616- GtkFileChooser *chooser = GTK_FILE_CHOOSER (impl);
3617-
3618- for (i = 1; uris[i]; i++)
3619+ if (event->type != GDK_BUTTON_PRESS ||
3620+ !gtk_tree_view_get_path_at_pos (tree, (gint)event->x, (gint)event->y,
3621+ &path, NULL, NULL, NULL))
3622 {
3623- GtkFilePath *path;
3624-
3625- uri = uris[i];
3626- path = gtk_file_system_uri_to_path (impl->file_system, uri);
3627-
3628- if (path)
3629- {
3630- GError *error = NULL;
3631-
3632- gtk_file_chooser_default_select_path (chooser, path, &error);
3633- if (error)
3634- error_selecting_dragged_file_dialog (impl, path, error);
3635-
3636- gtk_file_path_free (path);
3637- }
3638+ return FALSE;
3639 }
3640-}
3641
3642-struct FileListDragData
3643-{
3644- GtkFileChooserDefault *impl;
3645- gchar **uris;
3646- GtkFilePath *path;
3647-};
3648+ impl->list_press_time = event->time;
3649+ impl->list_press_path = path;
3650
3651-static void
3652-file_list_drag_data_received_get_info_cb (GtkFileSystemHandle *handle,
3653- const GtkFileInfo *info,
3654- const GError *error,
3655- gpointer user_data)
3656-{
3657- gboolean cancelled = handle->cancelled;
3658- struct FileListDragData *data = user_data;
3659- GtkFileChooser *chooser = GTK_FILE_CHOOSER (data->impl);
3660-
3661- if (handle != data->impl->file_list_drag_data_received_handle)
3662- goto out;
3663-
3664- data->impl->file_list_drag_data_received_handle = NULL;
3665-
3666- if (cancelled || error)
3667- goto out;
3668-
3669- if ((data->impl->action == GTK_FILE_CHOOSER_ACTION_OPEN ||
3670- data->impl->action == GTK_FILE_CHOOSER_ACTION_SAVE) &&
3671- data->uris[1] == 0 && !error &&
3672- gtk_file_info_get_is_folder (info))
3673- change_folder_and_display_error (data->impl, data->path, FALSE);
3674- else
3675- {
3676- GError *error = NULL;
3677-
3678- gtk_file_chooser_default_unselect_all (chooser);
3679- gtk_file_chooser_default_select_path (chooser, data->path, &error);
3680- if (error)
3681- error_selecting_dragged_file_dialog (data->impl, data->path, error);
3682- else
3683- browse_files_center_selected_row (data->impl);
3684- }
3685-
3686- if (data->impl->select_multiple)
3687- file_list_drag_data_select_uris (data->impl, data->uris);
3688-
3689-out:
3690- g_object_unref (data->impl);
3691- g_strfreev (data->uris);
3692- gtk_file_path_free (data->path);
3693- g_free (data);
3694-
3695- g_object_unref (handle);
3696+ return FALSE;
3697 }
3698
3699-static void
3700-file_list_drag_data_received_cb (GtkWidget *widget,
3701- GdkDragContext *context,
3702- gint x,
3703- gint y,
3704- GtkSelectionData *selection_data,
3705- guint info,
3706- guint time_,
3707- gpointer data)
3708-{
3709- GtkFileChooserDefault *impl;
3710- GtkFileChooser *chooser;
3711- gchar **uris;
3712- char *uri;
3713- GtkFilePath *path;
3714- GError *error = NULL;
3715-
3716- impl = GTK_FILE_CHOOSER_DEFAULT (data);
3717- chooser = GTK_FILE_CHOOSER (data);
3718-
3719- /* Parse the text/uri-list string, navigate to the first one */
3720- uris = g_uri_list_extract_uris ((const char *) selection_data->data);
3721- if (uris[0])
3722- {
3723- uri = uris[0];
3724- path = gtk_file_system_uri_to_path (impl->file_system, uri);
3725-
3726- if (path)
3727- {
3728- struct FileListDragData *data;
3729-
3730- data = g_new0 (struct FileListDragData, 1);
3731- data->impl = g_object_ref (impl);
3732- data->uris = uris;
3733- data->path = path;
3734-
3735- if (impl->file_list_drag_data_received_handle)
3736- gtk_file_system_cancel_operation (impl->file_list_drag_data_received_handle);
3737-
3738- impl->file_list_drag_data_received_handle =
3739- gtk_file_system_get_info (impl->file_system, path,
3740- GTK_FILE_INFO_IS_FOLDER,
3741- file_list_drag_data_received_get_info_cb,
3742- data);
3743- goto out;
3744- }
3745- else
3746- {
3747- g_set_error (&error,
3748- GTK_FILE_CHOOSER_ERROR,
3749- GTK_FILE_CHOOSER_ERROR_BAD_FILENAME,
3750- _("Could not select file '%s' "
3751- "because it is an invalid path name."),
3752- uri);
3753- error_selecting_dragged_file_dialog (impl, NULL, error);
3754- }
3755-
3756- if (impl->select_multiple)
3757- file_list_drag_data_select_uris (impl, uris);
3758- }
3759-
3760- g_strfreev (uris);
3761-
3762-out:
3763- g_signal_stop_emission_by_name (widget, "drag_data_received");
3764-}
3765-
3766-/* Don't do anything with the drag_drop signal */
3767 static gboolean
3768-file_list_drag_drop_cb (GtkWidget *widget,
3769- GdkDragContext *context,
3770- gint x,
3771- gint y,
3772- guint time_,
3773- GtkFileChooserDefault *impl)
3774+list_button_release (GtkWidget *widget, GdkEventButton *event, gpointer data)
3775 {
3776- g_signal_stop_emission_by_name (widget, "drag_drop");
3777- return TRUE;
3778-}
3779+ GtkTreeView * tree = GTK_TREE_VIEW (widget);
3780+ GtkFileChooserDefault *impl = data;
3781+ GtkTreePath *path = NULL;
3782+ gboolean retval = FALSE;
3783
3784-/* Disable the normal tree drag motion handler, it makes it look like you're
3785- dropping the dragged item onto a tree item */
3786-static gboolean
3787-file_list_drag_motion_cb (GtkWidget *widget,
3788- GdkDragContext *context,
3789- gint x,
3790- gint y,
3791- guint time_,
3792- GtkFileChooserDefault *impl)
3793-{
3794- g_signal_stop_emission_by_name (widget, "drag_motion");
3795- return TRUE;
3796-}
3797-
3798-/* Constructs the popup menu for the file list if needed */
3799-static void
3800-file_list_build_popup_menu (GtkFileChooserDefault *impl)
3801-{
3802- GtkWidget *item;
3803-
3804- if (impl->browse_files_popup_menu)
3805- return;
3806-
3807- impl->browse_files_popup_menu = gtk_menu_new ();
3808- gtk_menu_attach_to_widget (GTK_MENU (impl->browse_files_popup_menu),
3809- impl->browse_files_tree_view,
3810- popup_menu_detach_cb);
3811-
3812- item = gtk_image_menu_item_new_with_mnemonic (_("_Add to Bookmarks"));
3813- impl->browse_files_popup_menu_add_shortcut_item = item;
3814- gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item),
3815- gtk_image_new_from_stock (GTK_STOCK_ADD, GTK_ICON_SIZE_MENU));
3816- gtk_widget_set_sensitive (item, FALSE);
3817- g_signal_connect (item, "activate",
3818- G_CALLBACK (add_to_shortcuts_cb), impl);
3819- gtk_widget_show (item);
3820- gtk_menu_shell_append (GTK_MENU_SHELL (impl->browse_files_popup_menu), item);
3821-
3822- item = gtk_separator_menu_item_new ();
3823- gtk_widget_show (item);
3824- gtk_menu_shell_append (GTK_MENU_SHELL (impl->browse_files_popup_menu), item);
3825-
3826- item = gtk_check_menu_item_new_with_mnemonic (_("Show _Hidden Files"));
3827- impl->browse_files_popup_menu_hidden_files_item = item;
3828- g_signal_connect (item, "toggled",
3829- G_CALLBACK (show_hidden_toggled_cb), impl);
3830- gtk_widget_show (item);
3831- gtk_menu_shell_append (GTK_MENU_SHELL (impl->browse_files_popup_menu), item);
3832-}
3833-
3834-/* Updates the popup menu for the file list, creating it if necessary */
3835-static void
3836-file_list_update_popup_menu (GtkFileChooserDefault *impl)
3837-{
3838- file_list_build_popup_menu (impl);
3839-
3840- /* FIXME - handle OPERATION_MODE_SEARCH and OPERATION_MODE_RECENT */
3841-
3842- /* The sensitivity of the Add to Bookmarks item is set in
3843- * bookmarks_check_add_sensitivity()
3844- */
3845-
3846- g_signal_handlers_block_by_func (impl->browse_files_popup_menu_hidden_files_item,
3847- G_CALLBACK (show_hidden_toggled_cb), impl);
3848- gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (impl->browse_files_popup_menu_hidden_files_item),
3849- impl->show_hidden);
3850- g_signal_handlers_unblock_by_func (impl->browse_files_popup_menu_hidden_files_item,
3851- G_CALLBACK (show_hidden_toggled_cb), impl);
3852-}
3853-
3854-static void
3855-popup_position_func (GtkMenu *menu,
3856- gint *x,
3857- gint *y,
3858- gboolean *push_in,
3859- gpointer user_data)
3860-{
3861- GtkWidget *widget = GTK_WIDGET (user_data);
3862- GdkScreen *screen = gtk_widget_get_screen (widget);
3863- GtkRequisition req;
3864- gint monitor_num;
3865- GdkRectangle monitor;
3866-
3867- g_return_if_fail (GTK_WIDGET_REALIZED (widget));
3868-
3869- gdk_window_get_origin (widget->window, x, y);
3870-
3871- gtk_widget_size_request (GTK_WIDGET (menu), &req);
3872-
3873- *x += (widget->allocation.width - req.width) / 2;
3874- *y += (widget->allocation.height - req.height) / 2;
3875-
3876- monitor_num = gdk_screen_get_monitor_at_point (screen, *x, *y);
3877- gtk_menu_set_monitor (menu, monitor_num);
3878- gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor);
3879-
3880- *x = CLAMP (*x, monitor.x, monitor.x + MAX (0, monitor.width - req.width));
3881- *y = CLAMP (*y, monitor.y, monitor.y + MAX (0, monitor.height - req.height));
3882-
3883- *push_in = FALSE;
3884-}
3885-
3886-static void
3887-file_list_popup_menu (GtkFileChooserDefault *impl,
3888- GdkEventButton *event)
3889-{
3890- file_list_update_popup_menu (impl);
3891- if (event)
3892- gtk_menu_popup (GTK_MENU (impl->browse_files_popup_menu),
3893- NULL, NULL, NULL, NULL,
3894- event->button, event->time);
3895- else
3896+ if (!impl->list_press_time ||
3897+ !impl->list_press_path ||
3898+ event->type != GDK_BUTTON_RELEASE ||
3899+ !gtk_tree_view_get_path_at_pos (tree, (gint)event->x, (gint)event->y,
3900+ &path, NULL, NULL, NULL))
3901 {
3902- gtk_menu_popup (GTK_MENU (impl->browse_files_popup_menu),
3903- NULL, NULL,
3904- popup_position_func, impl->browse_files_tree_view,
3905- 0, GDK_CURRENT_TIME);
3906- gtk_menu_shell_select_first (GTK_MENU_SHELL (impl->browse_files_popup_menu),
3907- FALSE);
3908+ goto done;
3909 }
3910
3911-}
3912-
3913-/* Callback used for the GtkWidget::popup-menu signal of the file list */
3914-static gboolean
3915-list_popup_menu_cb (GtkWidget *widget,
3916- GtkFileChooserDefault *impl)
3917-{
3918- file_list_popup_menu (impl, NULL);
3919- return TRUE;
3920-}
3921-
3922-/* Callback used when a button is pressed on the file list. We trap button 3 to
3923- * bring up a popup menu.
3924- */
3925-static gboolean
3926-list_button_press_event_cb (GtkWidget *widget,
3927- GdkEventButton *event,
3928- GtkFileChooserDefault *impl)
3929-{
3930- static gboolean in_press = FALSE;
3931- gboolean handled;
3932-
3933- if (in_press)
3934- return FALSE;
3935-
3936- if (event->button != 3)
3937- return FALSE;
3938-
3939- in_press = TRUE;
3940- handled = gtk_widget_event (impl->browse_files_tree_view, (GdkEvent *) event);
3941- in_press = FALSE;
3942-
3943- file_list_popup_menu (impl, event);
3944- return TRUE;
3945-}
3946-
3947-/* Sets the sort column IDs for the file list based on the operation mode */
3948-static void
3949-file_list_set_sort_column_ids (GtkFileChooserDefault *impl)
3950-{
3951- int name_id, mtime_id;
3952-
3953- name_id = mtime_id = 0;
3954-
3955- switch (impl->operation_mode)
3956+ if (event->time - impl->list_press_time > LONG_CLICK_LENGTH &&
3957+ !gtk_tree_path_compare (impl->list_press_path, path))
3958 {
3959- case OPERATION_MODE_BROWSE:
3960- name_id = FILE_LIST_COL_NAME;
3961- mtime_id = FILE_LIST_COL_MTIME;
3962- break;
3963- case OPERATION_MODE_SEARCH:
3964- name_id = SEARCH_MODEL_COL_PATH;
3965- mtime_id = SEARCH_MODEL_COL_STAT;
3966- break;
3967- case OPERATION_MODE_RECENT:
3968- name_id = RECENT_MODEL_COL_PATH;
3969- mtime_id = RECENT_MODEL_COL_INFO;
3970- break;
3971+ retval = TRUE;
3972+ list_row_activated (tree, path, NULL, impl);
3973 }
3974
3975- gtk_tree_view_column_set_sort_column_id (impl->list_name_column, name_id);
3976- gtk_tree_view_column_set_sort_column_id (impl->list_mtime_column, mtime_id);
3977-}
3978+ done:
3979+ if (path)
3980+ gtk_tree_path_free (path);
3981
3982-static gboolean
3983-file_list_query_tooltip_cb (GtkWidget *widget,
3984- gint x,
3985- gint y,
3986- gboolean keyboard_tip,
3987- GtkTooltip *tooltip,
3988- gpointer user_data)
3989-{
3990- GtkFileChooserDefault *impl = user_data;
3991- GtkTreeIter iter, child_iter;
3992- GtkTreePath *path = NULL;
3993- GtkFilePath *file_path = NULL;
3994- gchar *filename;
3995+ impl->list_press_time = 0;
3996
3997- if (impl->operation_mode == OPERATION_MODE_BROWSE)
3998- return FALSE;
3999-
4000-
4001- gtk_tree_view_get_tooltip_context (GTK_TREE_VIEW (impl->browse_files_tree_view),
4002- &x, &y,
4003- keyboard_tip,
4004- NULL, &path, NULL);
4005-
4006- if (!path)
4007- return FALSE;
4008-
4009- switch (impl->operation_mode)
4010+ if (impl->list_press_path)
4011 {
4012- case OPERATION_MODE_SEARCH:
4013- if (!gtk_tree_model_get_iter (GTK_TREE_MODEL (impl->search_model_sort), &iter, path))
4014- {
4015- gtk_tree_path_free (path);
4016- return FALSE;
4017- }
4018-
4019- search_get_valid_child_iter (impl, &child_iter, &iter);
4020- gtk_tree_model_get (GTK_TREE_MODEL (impl->search_model), &child_iter,
4021- SEARCH_MODEL_COL_PATH, &file_path,
4022- -1);
4023- break;
4024-
4025- case OPERATION_MODE_RECENT:
4026- if (!gtk_tree_model_get_iter (GTK_TREE_MODEL (impl->recent_model_sort), &iter, path))
4027- {
4028- gtk_tree_path_free (path);
4029- return FALSE;
4030- }
4031-
4032- recent_get_valid_child_iter (impl, &child_iter, &iter);
4033- gtk_tree_model_get (GTK_TREE_MODEL (impl->recent_model), &child_iter,
4034- RECENT_MODEL_COL_PATH, &file_path,
4035- -1);
4036- break;
4037-
4038- case OPERATION_MODE_BROWSE:
4039- g_assert_not_reached ();
4040- return FALSE;
4041+ gtk_tree_path_free (impl->list_press_path);
4042+ impl->list_press_path = NULL;
4043 }
4044
4045- if (!file_path)
4046- {
4047- gtk_tree_path_free (path);
4048- return FALSE;
4049- }
4050-
4051- filename = gtk_file_system_path_to_filename (impl->file_system, file_path);
4052- gtk_tooltip_set_text (tooltip, filename);
4053- gtk_tree_view_set_tooltip_row (GTK_TREE_VIEW (impl->browse_files_tree_view),
4054- tooltip,
4055- path);
4056-
4057- g_free (filename);
4058- gtk_tree_path_free (path);
4059-
4060- return TRUE;
4061+ return FALSE;
4062 }
4063
4064+
4065 /* Creates the widgets for the file list */
4066 static GtkWidget *
4067 create_file_list (GtkFileChooserDefault *impl)
4068@@ -4572,7 +1272,7 @@
4069
4070 swin = gtk_scrolled_window_new (NULL, NULL);
4071 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (swin),
4072- GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
4073+ GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
4074 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (swin),
4075 GTK_SHADOW_IN);
4076
4077@@ -4588,41 +1288,19 @@
4078 gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (impl->browse_files_tree_view), TRUE);
4079 gtk_container_add (GTK_CONTAINER (swin), impl->browse_files_tree_view);
4080
4081- gtk_drag_dest_set (impl->browse_files_tree_view,
4082- GTK_DEST_DEFAULT_ALL,
4083- file_list_dest_targets,
4084- num_file_list_dest_targets,
4085- GDK_ACTION_COPY | GDK_ACTION_MOVE);
4086-
4087 g_signal_connect (impl->browse_files_tree_view, "row_activated",
4088 G_CALLBACK (list_row_activated), impl);
4089 g_signal_connect (impl->browse_files_tree_view, "key_press_event",
4090 G_CALLBACK (trap_activate_cb), impl);
4091- g_signal_connect (impl->browse_files_tree_view, "popup_menu",
4092- G_CALLBACK (list_popup_menu_cb), impl);
4093 g_signal_connect (impl->browse_files_tree_view, "button_press_event",
4094- G_CALLBACK (list_button_press_event_cb), impl);
4095+ G_CALLBACK (list_button_press), impl);
4096+ g_signal_connect (impl->browse_files_tree_view, "button_release_event",
4097+ G_CALLBACK (list_button_release), impl);
4098
4099- g_signal_connect (impl->browse_files_tree_view, "drag_data_received",
4100- G_CALLBACK (file_list_drag_data_received_cb), impl);
4101- g_signal_connect (impl->browse_files_tree_view, "drag_drop",
4102- G_CALLBACK (file_list_drag_drop_cb), impl);
4103- g_signal_connect (impl->browse_files_tree_view, "drag_motion",
4104- G_CALLBACK (file_list_drag_motion_cb), impl);
4105-
4106- g_object_set (impl->browse_files_tree_view, "has-tooltip", TRUE, NULL);
4107- g_signal_connect (impl->browse_files_tree_view, "query-tooltip",
4108- G_CALLBACK (file_list_query_tooltip_cb), impl);
4109-
4110 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_files_tree_view));
4111 gtk_tree_selection_set_select_function (selection,
4112 list_select_func,
4113 impl, NULL);
4114- gtk_tree_view_enable_model_drag_source (GTK_TREE_VIEW (impl->browse_files_tree_view),
4115- GDK_BUTTON1_MASK,
4116- file_list_source_targets,
4117- num_file_list_source_targets,
4118- GDK_ACTION_COPY);
4119
4120 g_signal_connect (selection, "changed",
4121 G_CALLBACK (list_selection_changed), impl);
4122@@ -4666,7 +1344,6 @@
4123 gtk_tree_view_column_set_sort_column_id (column, FILE_LIST_COL_SIZE);
4124 gtk_tree_view_append_column (GTK_TREE_VIEW (impl->browse_files_tree_view), column);
4125 #endif
4126-
4127 /* Modification time column */
4128
4129 column = gtk_tree_view_column_new ();
4130@@ -4677,276 +1354,221 @@
4131 gtk_tree_view_column_pack_start (column, renderer, TRUE);
4132 gtk_tree_view_column_set_cell_data_func (column, renderer,
4133 list_mtime_data_func, impl, NULL);
4134+ gtk_tree_view_column_set_sort_column_id (column, FILE_LIST_COL_MTIME);
4135 gtk_tree_view_append_column (GTK_TREE_VIEW (impl->browse_files_tree_view), column);
4136- impl->list_mtime_column = column;
4137-
4138- file_list_set_sort_column_ids (impl);
4139-
4140 gtk_widget_show_all (swin);
4141
4142 return swin;
4143 }
4144
4145-static GtkWidget *
4146-create_path_bar (GtkFileChooserDefault *impl)
4147+static void
4148+up_button_clicked_cb (GtkButton *button, gpointer data)
4149 {
4150- GtkWidget *path_bar;
4151+ GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (data);
4152+ up_folder_handler (impl);
4153+}
4154
4155- path_bar = g_object_new (GTK_TYPE_PATH_BAR, NULL);
4156- _gtk_path_bar_set_file_system (GTK_PATH_BAR (path_bar), impl->file_system);
4157+static void
4158+volume_button_clicked_cb (GtkButton *button, gpointer data)
4159+{
4160+ GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (data);
4161+ GtkFilePath * path = g_object_get_data (G_OBJECT (button), "file-path");
4162
4163- return path_bar;
4164+ change_folder_and_display_error (impl, path);
4165 }
4166
4167-/* Creates the widgets for the files/folders pane */
4168 static GtkWidget *
4169-file_pane_create (GtkFileChooserDefault *impl,
4170- GtkSizeGroup *size_group)
4171+create_bar (GtkFileChooserDefault *impl)
4172 {
4173- GtkWidget *vbox;
4174- GtkWidget *hbox;
4175- GtkWidget *widget;
4176+ GSList *list, *l;
4177+ int n;
4178+ GtkWidget *bar = gtk_hbox_new (FALSE, DEFAULT_SPACING);
4179+ GtkWidget *img;
4180+ GtkWidget *label;
4181
4182- vbox = gtk_vbox_new (FALSE, 6);
4183- gtk_widget_show (vbox);
4184+ /* first the Up button */
4185+ img = gtk_image_new_from_stock (GTK_STOCK_GO_UP, GTK_ICON_SIZE_BUTTON);
4186+ gtk_widget_show (img);
4187
4188- /* Box for lists and preview */
4189+ impl->up_button = gtk_button_new ();
4190+ gtk_container_add (GTK_CONTAINER (impl->up_button), img);
4191+ gtk_widget_show (impl->up_button);
4192+ gtk_widget_set_sensitive (impl->up_button, FALSE);
4193+ gtk_button_set_focus_on_click (GTK_BUTTON (impl->up_button), FALSE);
4194
4195- hbox = gtk_hbox_new (FALSE, PREVIEW_HBOX_SPACING);
4196- gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 0);
4197- gtk_widget_show (hbox);
4198+ g_signal_connect (impl->up_button, "clicked",
4199+ G_CALLBACK (up_button_clicked_cb), impl);
4200+ gtk_box_pack_start (GTK_BOX(bar), impl->up_button, FALSE, FALSE, 0);
4201
4202- /* File list */
4203+ impl->num_volumes = 0;
4204+ list = gtk_file_system_list_volumes (impl->file_system);
4205
4206- widget = create_file_list (impl);
4207- gtk_box_pack_start (GTK_BOX (hbox), widget, TRUE, TRUE, 0);
4208+ n = 0;
4209
4210- /* Preview */
4211+ for (l = list; l; l = l->next, n++)
4212+ {
4213+ GtkFileSystemVolume *volume;
4214+ GdkPixbuf *pixbuf;
4215+ GtkWidget *button;
4216+ GtkWidget *image;
4217+ GtkFilePath *base_path;
4218+ gchar * file_name = NULL;
4219
4220- impl->preview_box = gtk_vbox_new (FALSE, 12);
4221- gtk_box_pack_start (GTK_BOX (hbox), impl->preview_box, FALSE, FALSE, 0);
4222- /* Don't show preview box initially */
4223+ volume = l->data;
4224+ base_path =
4225+ gtk_file_system_volume_get_base_path (impl->file_system, volume);
4226
4227- /* Filter combo */
4228+ if (impl->local_only)
4229+ {
4230+ gboolean is_local =
4231+ gtk_file_system_path_is_local (impl->file_system, base_path);
4232
4233- impl->filter_combo_hbox = gtk_hbox_new (FALSE, 12);
4234+ if (!is_local)
4235+ {
4236+ gtk_file_path_free (base_path);
4237+ gtk_file_system_volume_free (impl->file_system, volume);
4238+ continue;
4239+ }
4240+ }
4241
4242- widget = filter_create (impl);
4243+#if 0
4244+ label_copy =
4245+ gtk_file_system_volume_get_display_name (impl->file_system, volume);
4246+#endif
4247+ pixbuf =
4248+ gtk_file_system_volume_render_icon (impl->file_system, volume,
4249+ GTK_WIDGET (impl),
4250+ impl->icon_size, NULL);
4251
4252- gtk_widget_show (widget);
4253- gtk_box_pack_end (GTK_BOX (impl->filter_combo_hbox), widget, FALSE, FALSE, 0);
4254+ button = gtk_button_new ();
4255+ image = gtk_image_new_from_pixbuf (pixbuf);
4256+ g_object_unref (G_OBJECT (pixbuf));
4257+ gtk_container_add (GTK_CONTAINER (button), image);
4258+ gtk_button_set_focus_on_click (GTK_BUTTON (button), FALSE);
4259
4260- gtk_size_group_add_widget (size_group, impl->filter_combo_hbox);
4261- gtk_box_pack_end (GTK_BOX (vbox), impl->filter_combo_hbox, FALSE, FALSE, 0);
4262+ file_name =
4263+ gtk_file_system_path_to_filename (impl->file_system, base_path);
4264
4265- return vbox;
4266-}
4267+ if (file_name && impl->root_folder &&
4268+ strcmp (file_name, impl->root_folder) &&
4269+ !strncmp (file_name, impl->root_folder, strlen (file_name)))
4270+ {
4271+ /* The base path is below the root folder; we replace it with
4272+ * the root folder
4273+ */
4274+ gtk_file_path_free (base_path);
4275+ base_path = gtk_file_system_filename_to_path (impl->file_system,
4276+ impl->root_folder);
4277+ }
4278
4279-/* Callback used when the "Browse for more folders" expander is toggled */
4280-static void
4281-expander_changed_cb (GtkExpander *expander,
4282- GParamSpec *pspec,
4283- GtkFileChooserDefault *impl)
4284-{
4285- impl->expand_folders = gtk_expander_get_expanded(GTK_EXPANDER (impl->save_expander));
4286- update_appearance (impl);
4287-}
4288+ g_free (file_name);
4289+ gtk_widget_show_all (button);
4290
4291-/* Callback used when the selection changes in the save folder combo box */
4292-static void
4293-save_folder_combo_changed_cb (GtkComboBox *combo,
4294- GtkFileChooserDefault *impl)
4295-{
4296- GtkTreeIter iter;
4297+ g_object_set_data (G_OBJECT (button), "file-path", base_path);
4298
4299- if (impl->changing_folder)
4300- return;
4301+ g_signal_connect (button, "clicked",
4302+ G_CALLBACK (volume_button_clicked_cb), impl);
4303
4304- if (gtk_combo_box_get_active_iter (combo, &iter))
4305- {
4306- GtkTreeIter child_iter;
4307-
4308- gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER (impl->shortcuts_combo_filter_model),
4309- &child_iter,
4310- &iter);
4311- shortcuts_activate_iter (impl, &child_iter);
4312- }
4313-}
4314+ gtk_box_pack_start (GTK_BOX(bar), button, FALSE, FALSE, 0);
4315+ }
4316
4317-/* Filter function used to filter out the Search item and its separator.
4318- * Used for the "Save in folder" combo box, so that these items do not appear in it.
4319- */
4320-static gboolean
4321-shortcuts_combo_filter_func (GtkTreeModel *model,
4322- GtkTreeIter *iter,
4323- gpointer data)
4324-{
4325- GtkFileChooserDefault *impl;
4326- GtkTreePath *tree_path;
4327- gint *indices;
4328- int idx;
4329- gboolean retval;
4330+ impl->num_volumes = n;
4331+ g_slist_free (list);
4332
4333- impl = GTK_FILE_CHOOSER_DEFAULT (data);
4334+ label = impl->location_label = gtk_label_new (NULL);
4335+ gtk_label_set_ellipsize (GTK_LABEL (label), PANGO_ELLIPSIZE_START);
4336+ gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5);
4337+ gtk_label_set_text (GTK_LABEL (label), impl->root_folder);
4338+ gtk_widget_show (label);
4339+ gtk_box_pack_start (GTK_BOX(bar), label, TRUE, TRUE, 0);
4340
4341- g_assert (model == GTK_TREE_MODEL (impl->shortcuts_model));
4342+ gtk_widget_show (bar);
4343
4344- tree_path = gtk_tree_model_get_path (GTK_TREE_MODEL (impl->shortcuts_model), iter);
4345- g_assert (tree_path != NULL);
4346+ return bar;
4347+}
4348
4349- indices = gtk_tree_path_get_indices (tree_path);
4350-
4351- retval = TRUE;
4352-
4353- if (impl->has_search)
4354- {
4355- idx = shortcuts_get_index (impl, SHORTCUTS_SEARCH);
4356- if (idx == indices[0])
4357- retval = FALSE;
4358- }
4359-
4360- if (impl->has_recent)
4361- {
4362- idx = shortcuts_get_index (impl, SHORTCUTS_RECENT);
4363- if (idx == indices[0])
4364- retval = FALSE;
4365- else
4366- {
4367- idx = shortcuts_get_index (impl, SHORTCUTS_RECENT_SEPARATOR);
4368- if (idx == indices[0])
4369- retval = FALSE;
4370- }
4371- }
4372-
4373- gtk_tree_path_free (tree_path);
4374-
4375- return retval;
4376- }
4377-
4378-/* Creates the combo box with the save folders */
4379+/* Creates the widgets for the files/folders pane */
4380 static GtkWidget *
4381-save_folder_combo_create (GtkFileChooserDefault *impl)
4382+file_pane_create (GtkFileChooserDefault *impl)
4383 {
4384- GtkWidget *combo;
4385- GtkCellRenderer *cell;
4386+ GtkWidget *vbox;
4387+ GtkWidget *hbox;
4388+ GtkWidget *widget;
4389+ vbox = gtk_vbox_new (FALSE, DEFAULT_SPACING);
4390+ gtk_widget_show (vbox);
4391
4392- impl->shortcuts_combo_filter_model = gtk_tree_model_filter_new (GTK_TREE_MODEL (impl->shortcuts_model), NULL);
4393- gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (impl->shortcuts_combo_filter_model),
4394- shortcuts_combo_filter_func,
4395- impl,
4396- NULL);
4397+ /* The volume bar and 'Create Folder' button */
4398+ hbox = gtk_hbox_new (FALSE, DEFAULT_SPACING);
4399+ gtk_widget_show (hbox);
4400+ impl->bar = create_bar (impl);
4401+ gtk_widget_show_all (impl->bar);
4402+ gtk_box_pack_start (GTK_BOX (hbox), impl->bar, TRUE, TRUE, 0);
4403
4404- combo = g_object_new (GTK_TYPE_COMBO_BOX,
4405- "model", impl->shortcuts_combo_filter_model,
4406- "focus-on-click", FALSE,
4407- NULL);
4408- gtk_widget_show (combo);
4409+ /* Create Folder */
4410+ widget = gtk_image_new_from_icon_name ("folder-new", GTK_ICON_SIZE_BUTTON);
4411+ gtk_widget_show (widget);
4412+ impl->browse_new_folder_button = gtk_button_new ();
4413+ gtk_container_add (GTK_CONTAINER (impl->browse_new_folder_button), widget);
4414+ gtk_button_set_focus_on_click (GTK_BUTTON (impl->browse_new_folder_button),
4415+ FALSE);
4416
4417- cell = gtk_cell_renderer_pixbuf_new ();
4418- gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo), cell, FALSE);
4419- gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo), cell,
4420- "pixbuf", SHORTCUTS_COL_PIXBUF,
4421- "visible", SHORTCUTS_COL_PIXBUF_VISIBLE,
4422- "sensitive", SHORTCUTS_COL_PIXBUF_VISIBLE,
4423- NULL);
4424+ g_signal_connect (impl->browse_new_folder_button, "clicked",
4425+ G_CALLBACK (new_folder_button_clicked), impl);
4426+ gtk_box_pack_end (GTK_BOX (hbox), impl->browse_new_folder_button, FALSE, FALSE, 0);
4427
4428- cell = gtk_cell_renderer_text_new ();
4429- gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo), cell, TRUE);
4430- gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo), cell,
4431- "text", SHORTCUTS_COL_NAME,
4432- "sensitive", SHORTCUTS_COL_PIXBUF_VISIBLE,
4433- NULL);
4434+ widget = filter_create (impl);
4435+ gtk_widget_hide (widget);
4436+ gtk_box_pack_end (GTK_BOX (hbox), widget, FALSE, FALSE, 0);
4437
4438- gtk_combo_box_set_row_separator_func (GTK_COMBO_BOX (combo),
4439- shortcuts_row_separator_func,
4440- NULL, NULL);
4441+ gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
4442
4443- g_signal_connect (combo, "changed",
4444- G_CALLBACK (save_folder_combo_changed_cb), impl);
4445+ /* Box for lists */
4446+ hbox = gtk_hbox_new (FALSE, LIST_HBOX_SPACING);
4447+ gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 0);
4448+ gtk_widget_show (hbox);
4449
4450- return combo;
4451+ /* File list */
4452+
4453+ widget = create_file_list (impl);
4454+ gtk_box_pack_start (GTK_BOX (hbox), widget, TRUE, TRUE, 0);
4455+
4456+ return vbox;
4457 }
4458
4459 /* Creates the widgets specific to Save mode */
4460-static void
4461+static GtkWidget *
4462 save_widgets_create (GtkFileChooserDefault *impl)
4463 {
4464 GtkWidget *vbox;
4465- GtkWidget *table;
4466+ GtkWidget *hbox;
4467 GtkWidget *widget;
4468- GtkWidget *alignment;
4469
4470- if (impl->save_widgets != NULL)
4471- return;
4472+ vbox = gtk_vbox_new (FALSE, 0);
4473+ hbox = gtk_hbox_new (FALSE, DEFAULT_SPACING);
4474
4475- location_switch_to_path_bar (impl);
4476-
4477- vbox = gtk_vbox_new (FALSE, 12);
4478-
4479- table = gtk_table_new (2, 2, FALSE);
4480- gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0);
4481- gtk_widget_show (table);
4482- gtk_table_set_row_spacings (GTK_TABLE (table), 12);
4483- gtk_table_set_col_spacings (GTK_TABLE (table), 12);
4484-
4485- /* Label */
4486-
4487- widget = gtk_label_new_with_mnemonic (_("_Name:"));
4488+ widget = gtk_label_new (_("Name:"));
4489 gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5);
4490- gtk_table_attach (GTK_TABLE (table), widget,
4491- 0, 1, 0, 1,
4492- GTK_FILL, GTK_FILL,
4493- 0, 0);
4494+ gtk_box_pack_start (GTK_BOX (hbox), widget, FALSE, FALSE, 0);
4495 gtk_widget_show (widget);
4496
4497- /* Location entry */
4498-
4499 impl->location_entry = _gtk_file_chooser_entry_new (TRUE);
4500 _gtk_file_chooser_entry_set_file_system (GTK_FILE_CHOOSER_ENTRY (impl->location_entry),
4501 impl->file_system);
4502- gtk_entry_set_width_chars (GTK_ENTRY (impl->location_entry), 45);
4503+/* gtk_entry_set_width_chars (GTK_ENTRY (impl->location_entry), 45); */
4504 gtk_entry_set_activates_default (GTK_ENTRY (impl->location_entry), TRUE);
4505- gtk_table_attach (GTK_TABLE (table), impl->location_entry,
4506- 1, 2, 0, 1,
4507- GTK_EXPAND | GTK_FILL, 0,
4508- 0, 0);
4509+ gtk_box_pack_start (GTK_BOX (hbox), impl->location_entry,
4510+ TRUE, TRUE, 0);
4511+
4512 gtk_widget_show (impl->location_entry);
4513- gtk_label_set_mnemonic_widget (GTK_LABEL (widget), impl->location_entry);
4514
4515- /* Folder combo */
4516- impl->save_folder_label = gtk_label_new (NULL);
4517- gtk_misc_set_alignment (GTK_MISC (impl->save_folder_label), 0.0, 0.5);
4518- gtk_table_attach (GTK_TABLE (table), impl->save_folder_label,
4519- 0, 1, 1, 2,
4520- GTK_FILL, GTK_FILL,
4521- 0, 0);
4522- gtk_widget_show (impl->save_folder_label);
4523+ gtk_widget_show (hbox);
4524+ gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
4525
4526- impl->save_folder_combo = save_folder_combo_create (impl);
4527- gtk_table_attach (GTK_TABLE (table), impl->save_folder_combo,
4528- 1, 2, 1, 2,
4529- GTK_EXPAND | GTK_FILL, GTK_FILL,
4530- 0, 0);
4531- gtk_label_set_mnemonic_widget (GTK_LABEL (impl->save_folder_label), impl->save_folder_combo);
4532-
4533- /* Expander */
4534- alignment = gtk_alignment_new (0.0, 0.5, 1.0, 1.0);
4535- gtk_box_pack_start (GTK_BOX (vbox), alignment, FALSE, FALSE, 0);
4536-
4537- impl->save_expander = gtk_expander_new_with_mnemonic (_("_Browse for other folders"));
4538- gtk_container_add (GTK_CONTAINER (alignment), impl->save_expander);
4539- g_signal_connect (impl->save_expander, "notify::expanded",
4540- G_CALLBACK (expander_changed_cb),
4541- impl);
4542- gtk_widget_show_all (alignment);
4543-
4544- impl->save_widgets = vbox;
4545- gtk_box_pack_start (GTK_BOX (impl), impl->save_widgets, FALSE, FALSE, 0);
4546- gtk_box_reorder_child (GTK_BOX (impl), impl->save_widgets, 0);
4547- gtk_widget_show (impl->save_widgets);
4548+ return vbox;
4549 }
4550
4551 /* Destroys the widgets specific to Save mode */
4552+/* ??? */
4553 static void
4554 save_widgets_destroy (GtkFileChooserDefault *impl)
4555 {
4556@@ -4956,313 +1578,17 @@
4557 gtk_widget_destroy (impl->save_widgets);
4558 impl->save_widgets = NULL;
4559 impl->location_entry = NULL;
4560- impl->save_folder_label = NULL;
4561- impl->save_folder_combo = NULL;
4562- impl->save_expander = NULL;
4563 }
4564
4565-/* Turns on the path bar widget. Can be called even if we are already in that
4566- * mode.
4567- */
4568-static void
4569-location_switch_to_path_bar (GtkFileChooserDefault *impl)
4570-{
4571- if (impl->location_entry)
4572- {
4573- gtk_widget_destroy (impl->location_entry);
4574- impl->location_entry = NULL;
4575- }
4576-
4577- gtk_widget_hide (impl->location_entry_box);
4578-}
4579-
4580-/* Sets the full path of the current folder as the text in the location entry. */
4581-static void
4582-location_entry_set_initial_text (GtkFileChooserDefault *impl)
4583-{
4584- char *text;
4585-
4586- if (!impl->current_folder)
4587- return;
4588-
4589- if (gtk_file_system_path_is_local (impl->file_system, impl->current_folder))
4590- {
4591- char *filename;
4592-
4593- filename = gtk_file_system_path_to_filename (impl->file_system, impl->current_folder);
4594- if (filename)
4595- {
4596- text = g_filename_to_utf8 (filename, -1, NULL, NULL, NULL);
4597- g_free (filename);
4598- }
4599- else
4600- text = NULL;
4601- }
4602- else
4603- text = gtk_file_system_path_to_uri (impl->file_system, impl->current_folder);
4604-
4605- if (text)
4606- {
4607- gboolean need_slash;
4608- int len;
4609-
4610- len = strlen (text);
4611- need_slash = (text[len - 1] != G_DIR_SEPARATOR);
4612-
4613- if (need_slash)
4614- {
4615- char *slash_text;
4616-
4617- slash_text = g_new (char, len + 2);
4618- strcpy (slash_text, text);
4619- slash_text[len] = G_DIR_SEPARATOR;
4620- slash_text[len + 1] = 0;
4621-
4622- g_free (text);
4623- text = slash_text;
4624- }
4625-
4626- _gtk_file_chooser_entry_set_file_part (GTK_FILE_CHOOSER_ENTRY (impl->location_entry), text);
4627- g_free (text);
4628- }
4629-}
4630-
4631-/* Turns on the location entry. Can be called even if we are already in that
4632- * mode.
4633- */
4634-static void
4635-location_switch_to_filename_entry (GtkFileChooserDefault *impl)
4636-{
4637- /* when in search or recent files mode, we are not showing the
4638- * location_entry_box container, so there's no point in switching
4639- * to it.
4640- */
4641- if (impl->operation_mode == OPERATION_MODE_SEARCH ||
4642- impl->operation_mode == OPERATION_MODE_RECENT)
4643- return;
4644-
4645- if (impl->location_entry)
4646- gtk_widget_destroy (impl->location_entry);
4647-
4648- /* Box */
4649-
4650- gtk_widget_show (impl->location_entry_box);
4651-
4652- /* Entry */
4653-
4654- impl->location_entry = _gtk_file_chooser_entry_new (TRUE);
4655- _gtk_file_chooser_entry_set_file_system (GTK_FILE_CHOOSER_ENTRY (impl->location_entry),
4656- impl->file_system);
4657- gtk_entry_set_activates_default (GTK_ENTRY (impl->location_entry), TRUE);
4658- _gtk_file_chooser_entry_set_action (GTK_FILE_CHOOSER_ENTRY (impl->location_entry), impl->action);
4659-
4660- gtk_box_pack_start (GTK_BOX (impl->location_entry_box), impl->location_entry, TRUE, TRUE, 0);
4661- gtk_label_set_mnemonic_widget (GTK_LABEL (impl->location_label), impl->location_entry);
4662-
4663- /* Configure the entry */
4664-
4665- _gtk_file_chooser_entry_set_base_folder (GTK_FILE_CHOOSER_ENTRY (impl->location_entry), impl->current_folder);
4666-
4667- /* Done */
4668-
4669- gtk_widget_show (impl->location_entry);
4670- gtk_widget_grab_focus (impl->location_entry);
4671-}
4672-
4673-/* Sets a new location mode. set_buttons determines whether the toggle button
4674- * for the mode will also be changed.
4675- */
4676-static void
4677-location_mode_set (GtkFileChooserDefault *impl,
4678- LocationMode new_mode,
4679- gboolean set_button)
4680-{
4681- if (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN ||
4682- impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER)
4683- {
4684- GtkWindow *toplevel;
4685- GtkWidget *current_focus;
4686- gboolean button_active;
4687- gboolean switch_to_file_list;
4688-
4689- switch (new_mode)
4690- {
4691- case LOCATION_MODE_PATH_BAR:
4692- button_active = FALSE;
4693-
4694- /* The location_entry will disappear when we switch to path bar mode. So,
4695- * we'll focus the file list in that case, to avoid having a window with
4696- * no focused widget.
4697- */
4698- toplevel = get_toplevel (GTK_WIDGET (impl));
4699- switch_to_file_list = FALSE;
4700- if (toplevel)
4701- {
4702- current_focus = gtk_window_get_focus (toplevel);
4703- if (!current_focus || current_focus == impl->location_entry)
4704- switch_to_file_list = TRUE;
4705- }
4706-
4707- location_switch_to_path_bar (impl);
4708-
4709- if (switch_to_file_list)
4710- gtk_widget_grab_focus (impl->browse_files_tree_view);
4711-
4712- break;
4713-
4714- case LOCATION_MODE_FILENAME_ENTRY:
4715- button_active = TRUE;
4716- location_switch_to_filename_entry (impl);
4717- break;
4718-
4719- default:
4720- g_assert_not_reached ();
4721- return;
4722- }
4723-
4724- if (set_button)
4725- {
4726- g_signal_handlers_block_by_func (impl->location_button,
4727- G_CALLBACK (location_button_toggled_cb), impl);
4728-
4729- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (impl->location_button), button_active);
4730-
4731- g_signal_handlers_unblock_by_func (impl->location_button,
4732- G_CALLBACK (location_button_toggled_cb), impl);
4733- }
4734- }
4735-
4736- impl->location_mode = new_mode;
4737-}
4738-
4739-static void
4740-location_toggle_popup_handler (GtkFileChooserDefault *impl)
4741-{
4742- /* If the file entry is not visible, show it.
4743- * If it is visible, turn it off only if it is focused. Otherwise, switch to the entry.
4744- */
4745- if (impl->location_mode == LOCATION_MODE_PATH_BAR)
4746- {
4747- location_mode_set (impl, LOCATION_MODE_FILENAME_ENTRY, TRUE);
4748- }
4749- else if (impl->location_mode == LOCATION_MODE_FILENAME_ENTRY)
4750- {
4751- if (GTK_WIDGET_HAS_FOCUS (impl->location_entry))
4752- {
4753- location_mode_set (impl, LOCATION_MODE_PATH_BAR, TRUE);
4754- }
4755- else
4756- {
4757- gtk_widget_grab_focus (impl->location_entry);
4758- }
4759- }
4760-}
4761-
4762-/* Callback used when one of the location mode buttons is toggled */
4763-static void
4764-location_button_toggled_cb (GtkToggleButton *toggle,
4765- GtkFileChooserDefault *impl)
4766-{
4767- gboolean is_active;
4768- LocationMode new_mode;
4769-
4770- is_active = gtk_toggle_button_get_active (toggle);
4771-
4772- if (is_active)
4773- {
4774- g_assert (impl->location_mode == LOCATION_MODE_PATH_BAR);
4775- new_mode = LOCATION_MODE_FILENAME_ENTRY;
4776- }
4777- else
4778- {
4779- g_assert (impl->location_mode == LOCATION_MODE_FILENAME_ENTRY);
4780- new_mode = LOCATION_MODE_PATH_BAR;
4781- }
4782-
4783- location_mode_set (impl, new_mode, FALSE);
4784-}
4785-
4786-/* Creates a toggle button for the location entry. */
4787-static void
4788-location_button_create (GtkFileChooserDefault *impl)
4789-{
4790- GtkWidget *image;
4791- const char *str;
4792-
4793- image = gtk_image_new_from_stock (GTK_STOCK_EDIT, GTK_ICON_SIZE_BUTTON);
4794- gtk_widget_show (image);
4795-
4796- impl->location_button = g_object_new (GTK_TYPE_TOGGLE_BUTTON,
4797- "image", image,
4798- NULL);
4799-
4800- g_signal_connect (impl->location_button, "toggled",
4801- G_CALLBACK (location_button_toggled_cb), impl);
4802-
4803- str = _("Type a file name");
4804-
4805- gtk_widget_set_tooltip_text (impl->location_button, str);
4806- atk_object_set_name (gtk_widget_get_accessible (impl->location_button), str);
4807-}
4808-
4809 /* Creates the main hpaned with the widgets shared by Open and Save mode */
4810 static GtkWidget *
4811 browse_widgets_create (GtkFileChooserDefault *impl)
4812 {
4813- GtkWidget *vbox;
4814- GtkWidget *hbox;
4815- GtkWidget *hpaned;
4816 GtkWidget *widget;
4817- GtkSizeGroup *size_group;
4818
4819- /* size group is used by the [+][-] buttons and the filter combo */
4820- size_group = gtk_size_group_new (GTK_SIZE_GROUP_VERTICAL);
4821- vbox = gtk_vbox_new (FALSE, 12);
4822+ widget = file_pane_create (impl);
4823
4824- /* Location widgets */
4825- hbox = gtk_hbox_new (FALSE, 12);
4826- gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
4827- gtk_widget_show (hbox);
4828- impl->browse_path_bar_hbox = hbox;
4829-
4830- location_button_create (impl);
4831- gtk_box_pack_start (GTK_BOX (hbox), impl->location_button, FALSE, FALSE, 0);
4832-
4833- /* Path bar */
4834-
4835- impl->browse_path_bar = create_path_bar (impl);
4836- g_signal_connect (impl->browse_path_bar, "path-clicked", G_CALLBACK (path_bar_clicked), impl);
4837- gtk_widget_show_all (impl->browse_path_bar);
4838- gtk_box_pack_start (GTK_BOX (hbox), impl->browse_path_bar, TRUE, TRUE, 0);
4839-
4840- /* Create Folder */
4841- impl->browse_new_folder_button = gtk_button_new_with_mnemonic (_("Create Fo_lder"));
4842- g_signal_connect (impl->browse_new_folder_button, "clicked",
4843- G_CALLBACK (new_folder_button_clicked), impl);
4844- gtk_box_pack_end (GTK_BOX (hbox), impl->browse_new_folder_button, FALSE, FALSE, 0);
4845-
4846- /* Box for the location label and entry */
4847-
4848- impl->location_entry_box = gtk_hbox_new (FALSE, 12);
4849- gtk_box_pack_start (GTK_BOX (vbox), impl->location_entry_box, FALSE, FALSE, 0);
4850-
4851- impl->location_label = gtk_label_new_with_mnemonic (_("_Location:"));
4852- gtk_widget_show (impl->location_label);
4853- gtk_box_pack_start (GTK_BOX (impl->location_entry_box), impl->location_label, FALSE, FALSE, 0);
4854-
4855- /* Paned widget */
4856- hpaned = gtk_hpaned_new ();
4857- gtk_widget_show (hpaned);
4858- gtk_box_pack_start (GTK_BOX (vbox), hpaned, TRUE, TRUE, 0);
4859-
4860- widget = shortcuts_pane_create (impl, size_group);
4861- gtk_paned_pack1 (GTK_PANED (hpaned), widget, FALSE, FALSE);
4862- widget = file_pane_create (impl, size_group);
4863- gtk_paned_pack2 (GTK_PANED (hpaned), widget, TRUE, FALSE);
4864-
4865- g_object_unref (size_group);
4866-
4867- return vbox;
4868+ return widget;
4869 }
4870
4871 static GObject*
4872@@ -5284,20 +1610,14 @@
4873
4874 gtk_widget_push_composite_child ();
4875
4876- /* Recent files manager */
4877- recent_manager_update (impl);
4878+ /* Widgets for Save mode */
4879+ impl->save_widgets = save_widgets_create (impl);
4880+ gtk_box_pack_start (GTK_BOX (impl), impl->save_widgets, FALSE, FALSE, 0);
4881
4882- /* Shortcuts model */
4883- shortcuts_model_create (impl);
4884-
4885 /* The browse widgets */
4886 impl->browse_widgets = browse_widgets_create (impl);
4887 gtk_box_pack_start (GTK_BOX (impl), impl->browse_widgets, TRUE, TRUE, 0);
4888
4889- /* Alignment to hold extra widget */
4890- impl->extra_align = gtk_alignment_new (0.0, 0.5, 1.0, 1.0);
4891- gtk_box_pack_start (GTK_BOX (impl), impl->extra_align, FALSE, FALSE, 0);
4892-
4893 gtk_widget_pop_composite_child ();
4894 update_appearance (impl);
4895
4896@@ -5306,35 +1626,7 @@
4897 return object;
4898 }
4899
4900-/* Sets the extra_widget by packing it in the appropriate place */
4901 static void
4902-set_extra_widget (GtkFileChooserDefault *impl,
4903- GtkWidget *extra_widget)
4904-{
4905- if (extra_widget)
4906- {
4907- g_object_ref (extra_widget);
4908- /* FIXME: is this right ? */
4909- gtk_widget_show (extra_widget);
4910- }
4911-
4912- if (impl->extra_widget)
4913- {
4914- gtk_container_remove (GTK_CONTAINER (impl->extra_align), impl->extra_widget);
4915- g_object_unref (impl->extra_widget);
4916- }
4917-
4918- impl->extra_widget = extra_widget;
4919- if (impl->extra_widget)
4920- {
4921- gtk_container_add (GTK_CONTAINER (impl->extra_align), impl->extra_widget);
4922- gtk_widget_show (impl->extra_align);
4923- }
4924- else
4925- gtk_widget_hide (impl->extra_align);
4926-}
4927-
4928-static void
4929 set_local_only (GtkFileChooserDefault *impl,
4930 gboolean local_only)
4931 {
4932@@ -5342,12 +1634,6 @@
4933 {
4934 impl->local_only = local_only;
4935
4936- if (impl->shortcuts_model && impl->file_system)
4937- {
4938- shortcuts_add_volumes (impl);
4939- shortcuts_add_bookmarks (impl);
4940- }
4941-
4942 if (local_only &&
4943 !gtk_file_system_path_is_local (impl->file_system, impl->current_folder))
4944 {
4945@@ -5374,21 +1660,9 @@
4946 volumes_changed_cb (GtkFileSystem *file_system,
4947 GtkFileChooserDefault *impl)
4948 {
4949- shortcuts_add_volumes (impl);
4950+ /* FIXME -- update the bar */
4951 }
4952
4953-/* Callback used when the set of bookmarks changes in the file system */
4954-static void
4955-bookmarks_changed_cb (GtkFileSystem *file_system,
4956- GtkFileChooserDefault *impl)
4957-{
4958- shortcuts_add_bookmarks (impl);
4959-
4960- bookmarks_check_add_sensitivity (impl);
4961- bookmarks_check_remove_sensitivity (impl);
4962- shortcuts_check_popup_sensitivity (impl);
4963-}
4964-
4965 /* Sets the file chooser to multiple selection mode */
4966 static void
4967 set_select_multiple (GtkFileChooserDefault *impl,
4968@@ -5408,8 +1682,6 @@
4969
4970 impl->select_multiple = select_multiple;
4971 g_object_notify (G_OBJECT (impl), "select-multiple");
4972-
4973- check_preview_change (impl);
4974 }
4975
4976 static void
4977@@ -5422,8 +1694,6 @@
4978 {
4979 g_signal_handler_disconnect (impl->file_system, impl->volumes_changed_id);
4980 impl->volumes_changed_id = 0;
4981- g_signal_handler_disconnect (impl->file_system, impl->bookmarks_changed_id);
4982- impl->bookmarks_changed_id = 0;
4983 g_object_unref (impl->file_system);
4984 }
4985
4986@@ -5459,14 +1729,28 @@
4987 impl->volumes_changed_id = g_signal_connect (impl->file_system, "volumes-changed",
4988 G_CALLBACK (volumes_changed_cb),
4989 impl);
4990- impl->bookmarks_changed_id = g_signal_connect (impl->file_system, "bookmarks-changed",
4991- G_CALLBACK (bookmarks_changed_cb),
4992- impl);
4993 }
4994
4995 profile_end ("end", NULL);
4996 }
4997
4998+static void
4999+show_new_folder_button (GtkFileChooserDefault *impl)
5000+{
5001+ if ((impl->action == GTK_FILE_CHOOSER_ACTION_SAVE ||
5002+ impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER) &&
5003+ impl->show_create_folder)
5004+ {
5005+ gtk_widget_show (impl->browse_new_folder_button);
5006+ gtk_misc_set_alignment (GTK_MISC (impl->location_label), 0.5, 0.5);
5007+ }
5008+ else
5009+ {
5010+ gtk_widget_hide (impl->browse_new_folder_button);
5011+ gtk_misc_set_alignment (GTK_MISC (impl->location_label), 1.0, 0.5);
5012+ }
5013+}
5014+
5015 /* This function is basically a do_all function.
5016 *
5017 * It sets the visibility on all the widgets based on the current state, and
5018@@ -5478,33 +1762,9 @@
5019 if (impl->action == GTK_FILE_CHOOSER_ACTION_SAVE ||
5020 impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)
5021 {
5022- const char *text;
5023+ gtk_widget_show (impl->save_widgets);
5024+ gtk_widget_show (impl->browse_widgets);
5025
5026- gtk_widget_hide (impl->location_button);
5027- save_widgets_create (impl);
5028-
5029- if (impl->action == GTK_FILE_CHOOSER_ACTION_SAVE)
5030- text = _("Save in _folder:");
5031- else
5032- text = _("Create in _folder:");
5033-
5034- gtk_label_set_text_with_mnemonic (GTK_LABEL (impl->save_folder_label), text);
5035-
5036- if (gtk_expander_get_expanded (GTK_EXPANDER (impl->save_expander)))
5037- {
5038- gtk_widget_set_sensitive (impl->save_folder_label, FALSE);
5039- gtk_widget_set_sensitive (impl->save_folder_combo, FALSE);
5040- gtk_widget_show (impl->browse_widgets);
5041- }
5042- else
5043- {
5044- gtk_widget_set_sensitive (impl->save_folder_label, TRUE);
5045- gtk_widget_set_sensitive (impl->save_folder_combo, TRUE);
5046- gtk_widget_hide (impl->browse_widgets);
5047- }
5048-
5049- gtk_widget_show (impl->browse_new_folder_button);
5050-
5051 if (impl->select_multiple)
5052 {
5053 g_warning ("Save mode cannot be set in conjunction with multiple selection mode. "
5054@@ -5515,23 +1775,12 @@
5055 else if (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN ||
5056 impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER)
5057 {
5058- gtk_widget_show (impl->location_button);
5059- save_widgets_destroy (impl);
5060+ gtk_widget_hide (impl->save_widgets);
5061 gtk_widget_show (impl->browse_widgets);
5062- location_mode_set (impl, impl->location_mode, TRUE);
5063 }
5064
5065- if (impl->location_entry)
5066- _gtk_file_chooser_entry_set_action (GTK_FILE_CHOOSER_ENTRY (impl->location_entry), impl->action);
5067+ show_new_folder_button (impl);
5068
5069- if (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN)
5070- gtk_widget_hide (impl->browse_new_folder_button);
5071- else
5072- gtk_widget_show (impl->browse_new_folder_button);
5073-
5074- /* This *is* needed; we need to redraw the file list because the "sensitivity"
5075- * of files may change depending whether we are in a file or folder-only mode.
5076- */
5077 gtk_widget_queue_draw (impl->browse_files_tree_view);
5078
5079 g_signal_emit_by_name (impl, "default-size-changed");
5080@@ -5556,8 +1805,7 @@
5081 {
5082 gtk_file_chooser_default_unselect_all (GTK_FILE_CHOOSER (impl));
5083
5084- if ((action == GTK_FILE_CHOOSER_ACTION_SAVE ||
5085- action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)
5086+ if ((action == GTK_FILE_CHOOSER_ACTION_SAVE || action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)
5087 && impl->select_multiple)
5088 {
5089 g_warning ("Tried to change the file chooser action to SAVE or CREATE_FOLDER, but "
5090@@ -5584,29 +1832,10 @@
5091 set_local_only (impl, g_value_get_boolean (value));
5092 break;
5093
5094- case GTK_FILE_CHOOSER_PROP_PREVIEW_WIDGET:
5095- set_preview_widget (impl, g_value_get_object (value));
5096- break;
5097-
5098- case GTK_FILE_CHOOSER_PROP_PREVIEW_WIDGET_ACTIVE:
5099- impl->preview_widget_active = g_value_get_boolean (value);
5100- update_preview_widget_visibility (impl);
5101- break;
5102-
5103- case GTK_FILE_CHOOSER_PROP_USE_PREVIEW_LABEL:
5104- impl->use_preview_label = g_value_get_boolean (value);
5105- update_preview_widget_visibility (impl);
5106- break;
5107-
5108- case GTK_FILE_CHOOSER_PROP_EXTRA_WIDGET:
5109- set_extra_widget (impl, g_value_get_object (value));
5110- break;
5111-
5112 case GTK_FILE_CHOOSER_PROP_SELECT_MULTIPLE:
5113 {
5114 gboolean select_multiple = g_value_get_boolean (value);
5115- if ((impl->action == GTK_FILE_CHOOSER_ACTION_SAVE ||
5116- impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)
5117+ if ((impl->action == GTK_FILE_CHOOSER_ACTION_SAVE || impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)
5118 && select_multiple)
5119 {
5120 g_warning ("Tried to set the file chooser to multiple selection mode, but this is "
5121@@ -5639,6 +1868,51 @@
5122 }
5123 break;
5124
5125+ case GTK_FILE_CHOOSER_PROP_ROOT_FOLDER:
5126+ {
5127+ GtkFilePath * path;
5128+ gchar * new_root = g_strdup (g_value_get_string (value));
5129+
5130+ if (!new_root)
5131+ {
5132+ new_root = g_strdup ("/");
5133+ }
5134+
5135+ path = gtk_file_system_filename_to_path (impl->file_system,
5136+ new_root);
5137+ if (change_folder (impl, path, FALSE))
5138+ {
5139+ g_free (impl->root_folder);
5140+ impl->root_folder = new_root;
5141+ }
5142+ else
5143+ {
5144+ g_warning ("Unable to set [%s] as root folder", new_root);
5145+ g_free (new_root);
5146+ }
5147+
5148+ gtk_file_path_free (path);
5149+ }
5150+ break;
5151+
5152+ case GTK_FILE_CHOOSER_PROP_SHOW_CREATE_FOLDER:
5153+ {
5154+ gboolean show = g_value_get_boolean (value);
5155+ if (show != impl->show_create_folder)
5156+ {
5157+ impl->show_create_folder = show;
5158+ show_new_folder_button (impl);
5159+ }
5160+ }
5161+ break;
5162+
5163+ /* These are not supported */
5164+ case GTK_FILE_CHOOSER_PROP_PREVIEW_WIDGET:
5165+ case GTK_FILE_CHOOSER_PROP_PREVIEW_WIDGET_ACTIVE:
5166+ case GTK_FILE_CHOOSER_PROP_USE_PREVIEW_LABEL:
5167+ case GTK_FILE_CHOOSER_PROP_EXTRA_WIDGET:
5168+ break;
5169+
5170 default:
5171 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
5172 break;
5173@@ -5667,30 +1941,34 @@
5174 g_value_set_boolean (value, impl->local_only);
5175 break;
5176
5177- case GTK_FILE_CHOOSER_PROP_PREVIEW_WIDGET:
5178- g_value_set_object (value, impl->preview_widget);
5179+ case GTK_FILE_CHOOSER_PROP_SELECT_MULTIPLE:
5180+ g_value_set_boolean (value, impl->select_multiple);
5181 break;
5182
5183- case GTK_FILE_CHOOSER_PROP_PREVIEW_WIDGET_ACTIVE:
5184- g_value_set_boolean (value, impl->preview_widget_active);
5185+ case GTK_FILE_CHOOSER_PROP_SHOW_HIDDEN:
5186+ g_value_set_boolean (value, impl->show_hidden);
5187 break;
5188
5189- case GTK_FILE_CHOOSER_PROP_USE_PREVIEW_LABEL:
5190- g_value_set_boolean (value, impl->use_preview_label);
5191+ case GTK_FILE_CHOOSER_PROP_ROOT_FOLDER:
5192+ g_value_set_string (value, impl->root_folder);
5193 break;
5194
5195- case GTK_FILE_CHOOSER_PROP_EXTRA_WIDGET:
5196- g_value_set_object (value, impl->extra_widget);
5197+ case GTK_FILE_CHOOSER_PROP_SHOW_CREATE_FOLDER:
5198+ g_value_set_boolean (value, impl->show_create_folder);
5199 break;
5200
5201- case GTK_FILE_CHOOSER_PROP_SELECT_MULTIPLE:
5202- g_value_set_boolean (value, impl->select_multiple);
5203+ case GTK_FILE_CHOOSER_PROP_PREVIEW_WIDGET:
5204+ g_value_set_object (value, NULL);
5205 break;
5206
5207- case GTK_FILE_CHOOSER_PROP_SHOW_HIDDEN:
5208- g_value_set_boolean (value, impl->show_hidden);
5209+ case GTK_FILE_CHOOSER_PROP_PREVIEW_WIDGET_ACTIVE:
5210+ g_value_set_boolean (value, FALSE);
5211 break;
5212
5213+ case GTK_FILE_CHOOSER_PROP_USE_PREVIEW_LABEL:
5214+ g_value_set_boolean (value, FALSE);
5215+ break;
5216+
5217 case GTK_FILE_CHOOSER_PROP_DO_OVERWRITE_CONFIRMATION:
5218 g_value_set_boolean (value, impl->do_overwrite_confirmation);
5219 break;
5220@@ -5723,24 +2001,12 @@
5221 GSList *l;
5222 GtkFileChooserDefault *impl = (GtkFileChooserDefault *) object;
5223
5224- if (impl->extra_widget)
5225- {
5226- g_object_unref (impl->extra_widget);
5227- impl->extra_widget = NULL;
5228- }
5229-
5230 if (impl->volumes_changed_id > 0)
5231 {
5232 g_signal_handler_disconnect (impl->file_system, impl->volumes_changed_id);
5233 impl->volumes_changed_id = 0;
5234 }
5235
5236- if (impl->bookmarks_changed_id > 0)
5237- {
5238- g_signal_handler_disconnect (impl->file_system, impl->bookmarks_changed_id);
5239- impl->bookmarks_changed_id = 0;
5240- }
5241-
5242 pending_select_paths_free (impl);
5243
5244 /* cancel all pending operations */
5245@@ -5766,23 +2032,6 @@
5246 impl->reload_icon_handles = NULL;
5247 }
5248
5249- if (impl->loading_shortcuts)
5250- {
5251- for (l = impl->loading_shortcuts; l; l = l->next)
5252- {
5253- GtkFileSystemHandle *handle =l->data;
5254- gtk_file_system_cancel_operation (handle);
5255- }
5256- g_slist_free (impl->loading_shortcuts);
5257- impl->loading_shortcuts = NULL;
5258- }
5259-
5260- if (impl->file_list_drag_data_received_handle)
5261- {
5262- gtk_file_system_cancel_operation (impl->file_list_drag_data_received_handle);
5263- impl->file_list_drag_data_received_handle = NULL;
5264- }
5265-
5266 if (impl->update_current_folder_handle)
5267 {
5268 gtk_file_system_cancel_operation (impl->update_current_folder_handle);
5269@@ -5807,15 +2056,6 @@
5270 impl->update_from_entry_handle = NULL;
5271 }
5272
5273- if (impl->shortcuts_activate_iter_handle)
5274- {
5275- gtk_file_system_cancel_operation (impl->shortcuts_activate_iter_handle);
5276- impl->shortcuts_activate_iter_handle = NULL;
5277- }
5278-
5279- search_stop_searching (impl, TRUE);
5280- recent_stop_loading (impl);
5281-
5282 remove_settings_signal (impl, gtk_widget_get_screen (GTK_WIDGET (impl)));
5283
5284 G_OBJECT_CLASS (_gtk_file_chooser_default_parent_class)->dispose (object);
5285@@ -5828,12 +2068,7 @@
5286 static void
5287 gtk_file_chooser_default_show_all (GtkWidget *widget)
5288 {
5289- GtkFileChooserDefault *impl = (GtkFileChooserDefault *) widget;
5290-
5291 gtk_widget_show (widget);
5292-
5293- if (impl->extra_widget)
5294- gtk_widget_show_all (impl->extra_widget);
5295 }
5296
5297 /* Handler for GtkWindow::set-focus; this is where we save the last-focused
5298@@ -5894,7 +2129,6 @@
5299 else
5300 impl->icon_size = FALLBACK_ICON_SIZE;
5301
5302- shortcuts_reload_icons (impl);
5303 gtk_widget_queue_resize (impl->browse_files_tree_view);
5304
5305 profile_end ("end", NULL);
5306@@ -5912,8 +2146,8 @@
5307
5308 name = g_param_spec_get_name (pspec);
5309
5310- if (strcmp (name, "gtk-icon-theme-name") == 0 ||
5311- strcmp (name, "gtk-icon-sizes") == 0)
5312+ if (strcmp (name, "gtk-icon-theme-name") == 0
5313+ || strcmp (name, "gtk-icon-sizes") == 0)
5314 change_icon_theme (impl);
5315
5316 profile_end ("end", NULL);
5317@@ -5948,24 +2182,6 @@
5318 }
5319
5320 static void
5321-recent_manager_update (GtkFileChooserDefault *impl)
5322-{
5323- GtkRecentManager *manager;
5324-
5325- profile_start ("start", NULL);
5326-
5327- if (gtk_widget_has_screen (GTK_WIDGET (impl)))
5328- manager = gtk_recent_manager_get_for_screen (gtk_widget_get_screen (GTK_WIDGET (impl)));
5329- else
5330- manager = gtk_recent_manager_get_default ();
5331-
5332- if (impl->recent_manager != manager)
5333- impl->recent_manager = manager;
5334-
5335- profile_end ("end", NULL);
5336-}
5337-
5338-static void
5339 gtk_file_chooser_default_style_set (GtkWidget *widget,
5340 GtkStyle *previous_style)
5341 {
5342@@ -6005,7 +2221,6 @@
5343
5344 remove_settings_signal (impl, previous_screen);
5345 check_icon_theme (impl);
5346- recent_manager_update (impl);
5347
5348 g_signal_emit_by_name (widget, "default-size-changed");
5349
5350@@ -6032,15 +2247,6 @@
5351
5352 impl->default_width = allocation->width;
5353 impl->default_height = allocation->height;
5354-
5355- if (impl->preview_widget_active &&
5356- impl->preview_widget &&
5357- GTK_WIDGET_DRAWABLE (impl->preview_widget))
5358- impl->default_width -= impl->preview_widget->allocation.width + PREVIEW_HBOX_SPACING;
5359-
5360- if (impl->extra_widget &&
5361- GTK_WIDGET_DRAWABLE (impl->extra_widget))
5362- impl->default_height -= GTK_BOX (widget)->spacing + impl->extra_widget->allocation.height;
5363 }
5364
5365 static gboolean
5366@@ -6094,23 +2300,18 @@
5367 settings_load (GtkFileChooserDefault *impl)
5368 {
5369 GtkFileChooserSettings *settings;
5370- LocationMode location_mode;
5371 gboolean show_hidden;
5372 gboolean expand_folders;
5373
5374 settings = _gtk_file_chooser_settings_new ();
5375
5376- location_mode = _gtk_file_chooser_settings_get_location_mode (settings);
5377 show_hidden = _gtk_file_chooser_settings_get_show_hidden (settings);
5378 expand_folders = _gtk_file_chooser_settings_get_expand_folders (settings);
5379
5380 g_object_unref (settings);
5381
5382- location_mode_set (impl, location_mode, TRUE);
5383 gtk_file_chooser_set_show_hidden (GTK_FILE_CHOOSER (impl), show_hidden);
5384 impl->expand_folders = expand_folders;
5385- if (impl->save_expander)
5386- gtk_expander_set_expanded (GTK_EXPANDER (impl->save_expander), expand_folders);
5387 }
5388
5389 static void
5390@@ -6120,7 +2321,6 @@
5391
5392 settings = _gtk_file_chooser_settings_new ();
5393
5394- _gtk_file_chooser_settings_set_location_mode (settings, impl->location_mode);
5395 _gtk_file_chooser_settings_set_show_hidden (settings, gtk_file_chooser_get_show_hidden (GTK_FILE_CHOOSER (impl)));
5396 _gtk_file_chooser_settings_set_expand_folders (settings, impl->expand_folders);
5397
5398@@ -6143,44 +2343,32 @@
5399
5400 GTK_WIDGET_CLASS (_gtk_file_chooser_default_parent_class)->map (widget);
5401
5402- if (impl->operation_mode == OPERATION_MODE_BROWSE)
5403+ switch (impl->reload_state)
5404 {
5405- switch (impl->reload_state)
5406- {
5407- case RELOAD_EMPTY:
5408- /* The user didn't explicitly give us a folder to
5409- * display, so we'll use the cwd
5410- */
5411- current_working_dir = g_get_current_dir ();
5412- gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (impl),
5413- current_working_dir);
5414- g_free (current_working_dir);
5415- break;
5416-
5417- case RELOAD_HAS_FOLDER:
5418- /* Nothing; we are already loading or loaded, so we
5419- * don't need to reload
5420- */
5421- break;
5422+ case RELOAD_EMPTY:
5423+ /* The user didn't explicitly give us a folder to display, so we'll use the cwd */
5424+ current_working_dir = g_get_current_dir ();
5425+ gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (impl), current_working_dir);
5426+ g_free (current_working_dir);
5427+ break;
5428
5429- case RELOAD_WAS_UNMAPPED:
5430- /* Just reload the current folder; else continue
5431- * the pending load.
5432- */
5433- if (impl->current_folder)
5434- {
5435- pending_select_paths_store_selection (impl);
5436- change_folder_and_display_error (impl, impl->current_folder, FALSE);
5437- }
5438- break;
5439+ case RELOAD_HAS_FOLDER:
5440+ /* Nothing; we are already loading or loaded, so we don't need to reload */
5441+ break;
5442
5443- default:
5444- g_assert_not_reached ();
5445- }
5446+ case RELOAD_WAS_UNMAPPED:
5447+ /* Just reload the current folder; else continue the pending load. */
5448+ if (impl->current_folder)
5449+ {
5450+ pending_select_paths_store_selection (impl);
5451+ change_folder_and_display_error (impl, impl->current_folder);
5452+ }
5453+ break;
5454+
5455+ default:
5456+ g_assert_not_reached ();
5457 }
5458
5459- bookmarks_changed_cb (impl->file_system, impl);
5460-
5461 settings_load (impl);
5462
5463 profile_end ("end", NULL);
5464@@ -6244,8 +2432,8 @@
5465
5466 #define COMPARE_DIRECTORIES \
5467 GtkFileChooserDefault *impl = user_data; \
5468- const GtkFileInfo *info_a = _gtk_file_system_model_get_info (impl->browse_files_model, a); \
5469- const GtkFileInfo *info_b = _gtk_file_system_model_get_info (impl->browse_files_model, b); \
5470+ const GtkFileInfo *info_a = _gtk_file_system_model_get_info (impl->browse_files_model, a); \
5471+ const GtkFileInfo *info_b = _gtk_file_system_model_get_info (impl->browse_files_model, b); \
5472 gboolean dir_a, dir_b; \
5473 \
5474 if (info_a) \
5475@@ -6387,6 +2575,8 @@
5476
5477 profile_start ("start", NULL);
5478
5479+ GDK_THREADS_ENTER ();
5480+
5481 impl = GTK_FILE_CHOOSER_DEFAULT (data);
5482 g_assert (impl->load_state == LOAD_PRELOAD);
5483 g_assert (impl->load_timeout_id != 0);
5484@@ -6397,6 +2587,8 @@
5485
5486 load_set_model (impl);
5487
5488+ GDK_THREADS_LEAVE ();
5489+
5490 profile_end ("end", NULL);
5491
5492 return FALSE;
5493@@ -6409,7 +2601,7 @@
5494 g_assert (impl->load_timeout_id == 0);
5495 g_assert (impl->load_state != LOAD_PRELOAD);
5496
5497- impl->load_timeout_id = gdk_threads_add_timeout (MAX_LOADING_TIME, load_timeout_cb, impl);
5498+ impl->load_timeout_id = g_timeout_add (MAX_LOADING_TIME, load_timeout_cb, impl);
5499 impl->load_state = LOAD_PRELOAD;
5500 }
5501
5502@@ -6494,12 +2686,10 @@
5503 gpointer user_data)
5504 {
5505 gboolean have_hidden;
5506- gboolean have_filtered;
5507 GSList *l;
5508 struct ShowAndSelectPathsData *data = user_data;
5509
5510 have_hidden = FALSE;
5511- have_filtered = FALSE;
5512
5513 for (l = data->paths; l; l = l->next)
5514 {
5515@@ -6515,12 +2705,9 @@
5516 if (!have_hidden)
5517 have_hidden = gtk_file_info_get_is_hidden (info);
5518
5519- if (!have_filtered)
5520- have_filtered = !gtk_file_info_get_is_folder (info) && get_is_file_filtered (data->impl, path, info);
5521-
5522 gtk_file_info_free (info);
5523
5524- if (have_hidden && have_filtered)
5525+ if (have_hidden)
5526 break; /* we now have all the information we need */
5527 }
5528 }
5529@@ -6534,9 +2721,6 @@
5530 if (have_hidden)
5531 g_object_set (data->impl, "show-hidden", TRUE, NULL);
5532
5533- if (have_filtered)
5534- set_current_filter (data->impl, NULL);
5535-
5536 for (l = data->paths; l; l = l->next)
5537 {
5538 const GtkFilePath *path;
5539@@ -6644,6 +2828,12 @@
5540 * but rather on behalf of something else like GtkFileChooserButton. In
5541 * that case, the chooser's selection should be what the caller expects,
5542 * as the user can't see that something else got selected. See bug #165264.
5543+ *
5544+ * Also, we don't select the first file if we are not in OPEN mode. Doing
5545+ * so would change the contents of the filename entry for SAVE or
5546+ * CREATE_FOLDER, which is undesired; in SELECT_FOLDER, we don't want to
5547+ * select a *different* folder from the one into which the user just
5548+ * navigated.
5549 */
5550 if (GTK_WIDGET_MAPPED (impl) && impl->action == GTK_FILE_CHOOSER_ACTION_OPEN)
5551 browse_files_select_first_row (impl);
5552@@ -6690,11 +2880,17 @@
5553 profile_end ("end", NULL);
5554 }
5555
5556-static void
5557-stop_loading_and_clear_list_model (GtkFileChooserDefault *impl)
5558+/* Gets rid of the old list model and creates a new one for the current folder */
5559+static gboolean
5560+set_list_model (GtkFileChooserDefault *impl,
5561+ GError **error)
5562 {
5563+ g_assert (impl->current_folder != NULL);
5564+
5565+ profile_start ("start", NULL);
5566+
5567 load_remove_timer (impl); /* This changes the state to LOAD_EMPTY */
5568-
5569+
5570 if (impl->browse_files_model)
5571 {
5572 g_object_unref (impl->browse_files_model);
5573@@ -6706,21 +2902,7 @@
5574 g_object_unref (impl->sort_model);
5575 impl->sort_model = NULL;
5576 }
5577-
5578- gtk_tree_view_set_model (GTK_TREE_VIEW (impl->browse_files_tree_view), NULL);
5579-}
5580
5581-/* Gets rid of the old list model and creates a new one for the current folder */
5582-static gboolean
5583-set_list_model (GtkFileChooserDefault *impl,
5584- GError **error)
5585-{
5586- g_assert (impl->current_folder != NULL);
5587-
5588- profile_start ("start", NULL);
5589-
5590- stop_loading_and_clear_list_model (impl);
5591-
5592 set_busy_cursor (impl, TRUE);
5593 gtk_tree_view_set_model (GTK_TREE_VIEW (impl->browse_files_tree_view), NULL);
5594
5595@@ -6794,17 +2976,10 @@
5596 struct update_chooser_entry_selected_foreach_closure closure;
5597 const char *file_part;
5598
5599- /* no need to update the file chooser's entry if there's no entry */
5600- if (impl->operation_mode == OPERATION_MODE_SEARCH ||
5601- impl->operation_mode == OPERATION_MODE_RECENT ||
5602- !impl->location_entry)
5603- return;
5604-
5605 if (!(impl->action == GTK_FILE_CHOOSER_ACTION_SAVE
5606 || impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER
5607- || ((impl->action == GTK_FILE_CHOOSER_ACTION_OPEN
5608- || impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER)
5609- && impl->location_mode == LOCATION_MODE_FILENAME_ENTRY)))
5610+ || impl->action == GTK_FILE_CHOOSER_ACTION_OPEN
5611+ || impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER))
5612 return;
5613
5614 g_assert (impl->location_entry != NULL);
5615@@ -6822,45 +2997,39 @@
5616 else if (closure.num_selected == 1)
5617 {
5618 GtkTreeIter child_iter;
5619-
5620- if (impl->operation_mode == OPERATION_MODE_BROWSE)
5621- {
5622- const GtkFileInfo *info;
5623- gboolean change_entry;
5624+ const GtkFileInfo *info;
5625+ gboolean change_entry;
5626
5627- gtk_tree_model_sort_convert_iter_to_child_iter (impl->sort_model,
5628- &child_iter,
5629- &closure.first_selected_iter);
5630+ gtk_tree_model_sort_convert_iter_to_child_iter (impl->sort_model,
5631+ &child_iter,
5632+ &closure.first_selected_iter);
5633
5634- info = _gtk_file_system_model_get_info (impl->browse_files_model, &child_iter);
5635+ info = _gtk_file_system_model_get_info (impl->browse_files_model, &child_iter);
5636
5637- /* If the cursor moved to the row of the newly created folder,
5638- * retrieving info will return NULL.
5639- */
5640- if (!info)
5641- return;
5642+ /* If the cursor moved to the row of the newly created folder,
5643+ * retrieving info will return NULL.
5644+ */
5645+ if (!info)
5646+ return;
5647
5648- g_free (impl->browse_files_last_selected_name);
5649- impl->browse_files_last_selected_name =
5650- g_strdup (gtk_file_info_get_display_name (info));
5651+ g_free (impl->browse_files_last_selected_name);
5652+ impl->browse_files_last_selected_name = g_strdup (gtk_file_info_get_display_name (info));
5653
5654- if (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN ||
5655- impl->action == GTK_FILE_CHOOSER_ACTION_SAVE)
5656- change_entry = !gtk_file_info_get_is_folder (info); /* We don't want the name to change when clicking on a folder... */
5657- else
5658- change_entry = TRUE; /* ... unless we are in one of the folder modes */
5659+ if (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN
5660+ || impl->action == GTK_FILE_CHOOSER_ACTION_SAVE)
5661+ change_entry = !gtk_file_info_get_is_folder (info); /* We don't want the name to change when clicking on a folder... */
5662+ else
5663+ change_entry = TRUE; /* ... unless we are in one of the folder modes */
5664
5665- if (change_entry)
5666- _gtk_file_chooser_entry_set_file_part (GTK_FILE_CHOOSER_ENTRY (impl->location_entry),
5667- impl->browse_files_last_selected_name);
5668+ if (change_entry)
5669+ _gtk_file_chooser_entry_set_file_part (GTK_FILE_CHOOSER_ENTRY (impl->location_entry), impl->browse_files_last_selected_name);
5670
5671- return;
5672- }
5673+ return;
5674 }
5675 else
5676 {
5677- g_assert (!(impl->action == GTK_FILE_CHOOSER_ACTION_SAVE ||
5678- impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER));
5679+ g_assert (!(impl->action == GTK_FILE_CHOOSER_ACTION_SAVE
5680+ || impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER));
5681
5682 /* Multiple selection, so just clear the entry. */
5683
5684@@ -6957,7 +3126,7 @@
5685
5686 /* get parent path and try to change the folder to that */
5687 if (gtk_file_system_get_parent (impl->file_system, data->path, &parent_path, NULL) &&
5688- parent_path != NULL)
5689+ parent_path)
5690 {
5691 gtk_file_path_free (data->path);
5692 data->path = parent_path;
5693@@ -6998,9 +3167,6 @@
5694 if (!gtk_file_info_get_is_folder (info))
5695 goto out;
5696
5697- if (!_gtk_path_bar_set_path (GTK_PATH_BAR (impl->browse_path_bar), data->path, data->keep_trail, NULL))
5698- goto out;
5699-
5700 if (impl->current_folder != data->path)
5701 {
5702 if (impl->current_folder)
5703@@ -7011,17 +3177,6 @@
5704 impl->reload_state = RELOAD_HAS_FOLDER;
5705 }
5706
5707- /* Update the widgets that may trigger a folder change themselves. */
5708-
5709- if (!impl->changing_folder)
5710- {
5711- impl->changing_folder = TRUE;
5712-
5713- shortcuts_update_current_folder (impl);
5714-
5715- impl->changing_folder = FALSE;
5716- }
5717-
5718 /* Set the folder on the save entry */
5719
5720 if (impl->location_entry)
5721@@ -7041,13 +3196,7 @@
5722
5723 /* Refresh controls */
5724
5725- shortcuts_find_current_folder (impl);
5726-
5727 g_signal_emit_by_name (impl, "current-folder-changed", 0);
5728-
5729- check_preview_change (impl);
5730- bookmarks_check_add_sensitivity (impl);
5731-
5732 g_signal_emit_by_name (impl, "selection-changed", 0);
5733
5734 out:
5735@@ -7069,18 +3218,6 @@
5736
5737 profile_start ("start", (char *) path);
5738
5739- switch (impl->operation_mode)
5740- {
5741- case OPERATION_MODE_SEARCH:
5742- search_switch_to_browse_mode (impl);
5743- break;
5744- case OPERATION_MODE_RECENT:
5745- recent_switch_to_browse_mode (impl);
5746- break;
5747- case OPERATION_MODE_BROWSE:
5748- break;
5749- }
5750-
5751 g_assert (path != NULL);
5752
5753 if (impl->local_only &&
5754@@ -7123,10 +3260,6 @@
5755 {
5756 GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (chooser);
5757
5758- if (impl->operation_mode == OPERATION_MODE_SEARCH ||
5759- impl->operation_mode == OPERATION_MODE_RECENT)
5760- return NULL;
5761-
5762 if (impl->reload_state == RELOAD_EMPTY)
5763 {
5764 char *current_working_dir;
5765@@ -7151,8 +3284,8 @@
5766 {
5767 GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (chooser);
5768
5769- g_return_if_fail (impl->action == GTK_FILE_CHOOSER_ACTION_SAVE ||
5770- impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER);
5771+ g_return_if_fail (impl->action == GTK_FILE_CHOOSER_ACTION_SAVE
5772+ || impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER);
5773
5774 pending_select_paths_free (impl);
5775 _gtk_file_chooser_entry_set_file_part (GTK_FILE_CHOOSER_ENTRY (impl->location_entry), name);
5776@@ -7187,14 +3320,10 @@
5777 return FALSE;
5778
5779 if (!parent_path)
5780- return _gtk_file_chooser_set_current_folder_path (chooser, path, error);
5781+ return _gtk_file_chooser_set_current_folder_path (chooser, path, error);
5782
5783- if (impl->operation_mode == OPERATION_MODE_SEARCH ||
5784- impl->operation_mode == OPERATION_MODE_RECENT ||
5785- impl->load_state == LOAD_EMPTY)
5786- {
5787- same_path = FALSE;
5788- }
5789+ if (impl->load_state == LOAD_EMPTY)
5790+ same_path = FALSE;
5791 else
5792 {
5793 g_assert (impl->current_folder != NULL);
5794@@ -7289,17 +3418,6 @@
5795 gtk_file_chooser_default_select_all (GtkFileChooser *chooser)
5796 {
5797 GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (chooser);
5798-
5799- if (impl->operation_mode == OPERATION_MODE_SEARCH ||
5800- impl->operation_mode == OPERATION_MODE_RECENT)
5801- {
5802- GtkTreeSelection *selection;
5803-
5804- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_files_tree_view));
5805- gtk_tree_selection_select_all (selection);
5806- return;
5807- }
5808-
5809 if (impl->select_multiple)
5810 gtk_tree_model_foreach (GTK_TREE_MODEL (impl->sort_model),
5811 maybe_select, impl);
5812@@ -7340,9 +3458,8 @@
5813
5814 g_assert (impl->action == GTK_FILE_CHOOSER_ACTION_SAVE
5815 || impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER
5816- || ((impl->action == GTK_FILE_CHOOSER_ACTION_OPEN
5817- || impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER)
5818- && impl->location_mode == LOCATION_MODE_FILENAME_ENTRY));
5819+ || impl->action == GTK_FILE_CHOOSER_ACTION_OPEN
5820+ || impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER);
5821
5822 chooser_entry = GTK_FILE_CHOOSER_ENTRY (impl->location_entry);
5823
5824@@ -7439,14 +3556,7 @@
5825 struct get_paths_closure info;
5826 GtkWindow *toplevel;
5827 GtkWidget *current_focus;
5828- gboolean file_list_seen;
5829
5830- if (impl->operation_mode == OPERATION_MODE_SEARCH)
5831- return search_get_selected_paths (impl);
5832-
5833- if (impl->operation_mode == OPERATION_MODE_RECENT)
5834- return recent_get_selected_paths (impl);
5835-
5836 info.impl = impl;
5837 info.result = NULL;
5838 info.path_from_entry = NULL;
5839@@ -7457,14 +3567,12 @@
5840 else
5841 current_focus = NULL;
5842
5843- file_list_seen = FALSE;
5844 if (current_focus == impl->browse_files_tree_view)
5845 {
5846 GtkTreeSelection *selection;
5847
5848 file_list:
5849
5850- file_list_seen = TRUE;
5851 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_files_tree_view));
5852 gtk_tree_selection_selected_foreach (selection, get_paths_foreach, &info);
5853
5854@@ -7499,12 +3607,8 @@
5855 return NULL;
5856 }
5857
5858- if (info.path_from_entry)
5859- info.result = g_slist_prepend (info.result, info.path_from_entry);
5860- else if (!file_list_seen)
5861- goto file_list;
5862- else
5863- return NULL;
5864+ g_assert (info.path_from_entry != NULL);
5865+ info.result = g_slist_prepend (info.result, info.path_from_entry);
5866 }
5867 else if (impl->toplevel_last_focus_widget == impl->browse_files_tree_view)
5868 goto file_list;
5869@@ -7512,9 +3616,9 @@
5870 goto file_entry;
5871 else
5872 {
5873- /* The focus is on a dialog's action area button or something else */
5874- if (impl->action == GTK_FILE_CHOOSER_ACTION_SAVE ||
5875- impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)
5876+ /* The focus is on a dialog's action area button or something else */
5877+ if (impl->action == GTK_FILE_CHOOSER_ACTION_SAVE
5878+ || impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)
5879 goto file_entry;
5880 else
5881 goto file_list;
5882@@ -7533,17 +3637,6 @@
5883 return g_slist_reverse (info.result);
5884 }
5885
5886-static GtkFilePath *
5887-gtk_file_chooser_default_get_preview_path (GtkFileChooser *chooser)
5888-{
5889- GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (chooser);
5890-
5891- if (impl->preview_path)
5892- return gtk_file_path_copy (impl->preview_path);
5893- else
5894- return NULL;
5895-}
5896-
5897 static GtkFileSystem *
5898 gtk_file_chooser_default_get_file_system (GtkFileChooser *chooser)
5899 {
5900@@ -7558,9 +3651,9 @@
5901 gboolean show)
5902 {
5903 if (show)
5904- gtk_widget_show (impl->filter_combo_hbox);
5905+ gtk_widget_show (impl->filter_combo);
5906 else
5907- gtk_widget_hide (impl->filter_combo_hbox);
5908+ gtk_widget_hide (impl->filter_combo);
5909 }
5910
5911 static void
5912@@ -7588,7 +3683,7 @@
5913 if (!g_slist_find (impl->filters, impl->current_filter))
5914 set_current_filter (impl, filter);
5915
5916- show_filters (impl, TRUE);
5917+ show_filters (impl, g_slist_length (impl->filters) > 1);
5918 }
5919
5920 static void
5921@@ -7627,8 +3722,7 @@
5922
5923 g_object_unref (filter);
5924
5925- if (!impl->filters)
5926- show_filters (impl, FALSE);
5927+ show_filters (impl, g_slist_length (impl->filters) > 1);
5928 }
5929
5930 static GSList *
5931@@ -7639,234 +3733,6 @@
5932 return g_slist_copy (impl->filters);
5933 }
5934
5935-/* Returns the position in the shortcuts tree where the nth specified shortcut would appear */
5936-static int
5937-shortcuts_get_pos_for_shortcut_folder (GtkFileChooserDefault *impl,
5938- int pos)
5939-{
5940- return pos + shortcuts_get_index (impl, SHORTCUTS_SHORTCUTS);
5941-}
5942-
5943-struct AddShortcutData
5944-{
5945- GtkFileChooserDefault *impl;
5946- GtkFilePath *path;
5947-};
5948-
5949-static void
5950-add_shortcut_get_info_cb (GtkFileSystemHandle *handle,
5951- const GtkFileInfo *info,
5952- const GError *error,
5953- gpointer user_data)
5954-{
5955- int pos;
5956- gboolean cancelled = handle->cancelled;
5957- struct AddShortcutData *data = user_data;
5958-
5959- if (!g_slist_find (data->impl->loading_shortcuts, handle))
5960- goto out;
5961-
5962- data->impl->loading_shortcuts = g_slist_remove (data->impl->loading_shortcuts, handle);
5963-
5964- if (cancelled || error || !gtk_file_info_get_is_folder (info))
5965- goto out;
5966-
5967- pos = shortcuts_get_pos_for_shortcut_folder (data->impl, data->impl->num_shortcuts);
5968-
5969- shortcuts_insert_path (data->impl, pos, SHORTCUT_TYPE_PATH, NULL, data->path, NULL, FALSE, SHORTCUTS_SHORTCUTS);
5970-
5971-out:
5972- g_object_unref (data->impl);
5973- gtk_file_path_free (data->path);
5974- g_free (data);
5975-
5976- g_object_unref (handle);
5977-}
5978-
5979-static gboolean
5980-gtk_file_chooser_default_add_shortcut_folder (GtkFileChooser *chooser,
5981- const GtkFilePath *path,
5982- GError **error)
5983-{
5984- GtkFileSystemHandle *handle;
5985- GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (chooser);
5986- struct AddShortcutData *data;
5987- GSList *l;
5988- int pos;
5989-
5990- /* Avoid adding duplicates */
5991- pos = shortcut_find_position (impl, path);
5992- if (pos >= 0 && pos < shortcuts_get_index (impl, SHORTCUTS_BOOKMARKS_SEPARATOR))
5993- {
5994- gchar *uri;
5995-
5996- uri = gtk_file_system_path_to_uri (impl->file_system, path);
5997- /* translators, "Shortcut" means "Bookmark" here */
5998- g_set_error (error,
5999- GTK_FILE_CHOOSER_ERROR,
6000- GTK_FILE_CHOOSER_ERROR_ALREADY_EXISTS,
6001- _("Shortcut %s already exists"),
6002- uri);
6003- g_free (uri);
6004-
6005- return FALSE;
6006- }
6007-
6008- for (l = impl->loading_shortcuts; l; l = l->next)
6009- {
6010- GtkFileSystemHandle *h = l->data;
6011- GtkFilePath *p;
6012-
6013- p = g_object_get_data (G_OBJECT (h), "add-shortcut-path-key");
6014- if (p && !gtk_file_path_compare (path, p))
6015- {
6016- gchar *uri;
6017-
6018- uri = gtk_file_system_path_to_uri (impl->file_system, path);
6019- g_set_error (error,
6020- GTK_FILE_CHOOSER_ERROR,
6021- GTK_FILE_CHOOSER_ERROR_ALREADY_EXISTS,
6022- _("Shortcut %s already exists"),
6023- uri);
6024- g_free (uri);
6025-
6026- return FALSE;
6027- }
6028- }
6029-
6030- data = g_new0 (struct AddShortcutData, 1);
6031- data->impl = g_object_ref (impl);
6032- data->path = gtk_file_path_copy (path);
6033-
6034- handle = gtk_file_system_get_info (impl->file_system, path,
6035- GTK_FILE_INFO_IS_FOLDER,
6036- add_shortcut_get_info_cb, data);
6037-
6038- if (!handle)
6039- return FALSE;
6040-
6041- impl->loading_shortcuts = g_slist_append (impl->loading_shortcuts, handle);
6042- g_object_set_data (G_OBJECT (handle), "add-shortcut-path-key", data->path);
6043-
6044- return TRUE;
6045-}
6046-
6047-static gboolean
6048-gtk_file_chooser_default_remove_shortcut_folder (GtkFileChooser *chooser,
6049- const GtkFilePath *path,
6050- GError **error)
6051-{
6052- GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (chooser);
6053- int pos;
6054- GtkTreeIter iter;
6055- GSList *l;
6056- char *uri;
6057- int i;
6058-
6059- for (l = impl->loading_shortcuts; l; l = l->next)
6060- {
6061- GtkFileSystemHandle *h = l->data;
6062- GtkFilePath *p;
6063-
6064- p = g_object_get_data (G_OBJECT (h), "add-shortcut-path-key");
6065- if (p && !gtk_file_path_compare (path, p))
6066- {
6067- impl->loading_shortcuts = g_slist_remove (impl->loading_shortcuts, h);
6068- gtk_file_system_cancel_operation (h);
6069- return TRUE;
6070- }
6071- }
6072-
6073- if (impl->num_shortcuts == 0)
6074- goto out;
6075-
6076- pos = shortcuts_get_pos_for_shortcut_folder (impl, 0);
6077- if (!gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (impl->shortcuts_model), &iter, NULL, pos))
6078- g_assert_not_reached ();
6079-
6080- for (i = 0; i < impl->num_shortcuts; i++)
6081- {
6082- gpointer col_data;
6083- ShortcutType shortcut_type;
6084- GtkFilePath *shortcut;
6085-
6086- gtk_tree_model_get (GTK_TREE_MODEL (impl->shortcuts_model), &iter,
6087- SHORTCUTS_COL_DATA, &col_data,
6088- SHORTCUTS_COL_TYPE, &shortcut_type,
6089- -1);
6090- g_assert (col_data != NULL);
6091- g_assert (shortcut_type == SHORTCUT_TYPE_PATH);
6092-
6093- shortcut = col_data;
6094- if (gtk_file_path_compare (shortcut, path) == 0)
6095- {
6096- shortcuts_remove_rows (impl, pos + i, 1);
6097- impl->num_shortcuts--;
6098- return TRUE;
6099- }
6100-
6101- if (!gtk_tree_model_iter_next (GTK_TREE_MODEL (impl->shortcuts_model), &iter))
6102- g_assert_not_reached ();
6103- }
6104-
6105- out:
6106-
6107- uri = gtk_file_system_path_to_uri (impl->file_system, path);
6108- /* translators, "Shortcut" means "Bookmark" here */
6109- g_set_error (error,
6110- GTK_FILE_CHOOSER_ERROR,
6111- GTK_FILE_CHOOSER_ERROR_NONEXISTENT,
6112- _("Shortcut %s does not exist"),
6113- uri);
6114- g_free (uri);
6115-
6116- return FALSE;
6117-}
6118-
6119-static GSList *
6120-gtk_file_chooser_default_list_shortcut_folders (GtkFileChooser *chooser)
6121-{
6122- GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (chooser);
6123- int pos;
6124- GtkTreeIter iter;
6125- int i;
6126- GSList *list;
6127-
6128- if (impl->num_shortcuts == 0)
6129- return NULL;
6130-
6131- pos = shortcuts_get_pos_for_shortcut_folder (impl, 0);
6132- if (!gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (impl->shortcuts_model), &iter, NULL, pos))
6133- g_assert_not_reached ();
6134-
6135- list = NULL;
6136-
6137- for (i = 0; i < impl->num_shortcuts; i++)
6138- {
6139- gpointer col_data;
6140- ShortcutType shortcut_type;
6141- GtkFilePath *shortcut;
6142-
6143- gtk_tree_model_get (GTK_TREE_MODEL (impl->shortcuts_model), &iter,
6144- SHORTCUTS_COL_DATA, &col_data,
6145- SHORTCUTS_COL_TYPE, &shortcut_type,
6146- -1);
6147- g_assert (col_data != NULL);
6148- g_assert (shortcut_type == SHORTCUT_TYPE_PATH);
6149-
6150- shortcut = col_data;
6151- list = g_slist_prepend (list, gtk_file_path_copy (shortcut));
6152-
6153- if (i != impl->num_shortcuts - 1)
6154- {
6155- if (!gtk_tree_model_iter_next (GTK_TREE_MODEL (impl->shortcuts_model), &iter))
6156- g_assert_not_reached ();
6157- }
6158- }
6159-
6160- return g_slist_reverse (list);
6161-}
6162-
6163 /* Guesses a size based upon font sizes */
6164 static void
6165 find_good_size_from_style (GtkWidget *widget,
6166@@ -7911,25 +3777,9 @@
6167 gint *default_height)
6168 {
6169 GtkFileChooserDefault *impl;
6170- GtkRequisition req;
6171
6172 impl = GTK_FILE_CHOOSER_DEFAULT (chooser_embed);
6173 find_good_size_from_style (GTK_WIDGET (chooser_embed), default_width, default_height);
6174-
6175- if (impl->preview_widget_active &&
6176- impl->preview_widget &&
6177- GTK_WIDGET_VISIBLE (impl->preview_widget))
6178- {
6179- gtk_widget_size_request (impl->preview_box, &req);
6180- *default_width += PREVIEW_HBOX_SPACING + req.width;
6181- }
6182-
6183- if (impl->extra_widget &&
6184- GTK_WIDGET_VISIBLE (impl->extra_widget))
6185- {
6186- gtk_widget_size_request (impl->extra_align, &req);
6187- *default_height += GTK_BOX (chooser_embed)->spacing + req.height;
6188- }
6189 }
6190
6191 static gboolean
6192@@ -7940,8 +3790,7 @@
6193 impl = GTK_FILE_CHOOSER_DEFAULT (chooser_embed);
6194
6195 return (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN ||
6196- impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER ||
6197- gtk_expander_get_expanded (GTK_EXPANDER (impl->save_expander)));
6198+ impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER);
6199 }
6200
6201 struct switch_folder_closure {
6202@@ -7988,7 +3837,7 @@
6203
6204 g_assert (closure.path && closure.num_selected == 1);
6205
6206- change_folder_and_display_error (impl, closure.path, FALSE);
6207+ change_folder_and_display_error (impl, closure.path);
6208 }
6209
6210 /* Gets the GtkFileInfo for the selected row in the file list; assumes single
6211@@ -8187,24 +4036,7 @@
6212 }
6213 }
6214
6215-/* Gives the focus to the browse tree view only if it is visible */
6216 static void
6217-focus_browse_tree_view_if_possible (GtkFileChooserDefault *impl)
6218-{
6219- gboolean do_focus;
6220-
6221- if ((impl->action == GTK_FILE_CHOOSER_ACTION_SAVE ||
6222- impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)
6223- && !gtk_expander_get_expanded (GTK_EXPANDER (impl->save_expander)))
6224- do_focus = FALSE;
6225- else
6226- do_focus = TRUE;
6227-
6228- if (do_focus)
6229- gtk_widget_grab_focus (impl->browse_files_tree_view);
6230-}
6231-
6232-static void
6233 action_create_folder_cb (GtkFileSystemHandle *handle,
6234 const GtkFilePath *path,
6235 const GError *error,
6236@@ -8300,7 +4132,7 @@
6237 else
6238 {
6239 /* This will display an error, which is what we want */
6240- change_folder_and_display_error (data->impl, data->parent_path, FALSE);
6241+ change_folder_and_display_error (data->impl, data->parent_path);
6242 }
6243
6244 out:
6245@@ -8378,51 +4210,7 @@
6246 g_object_unref (handle);
6247 }
6248
6249-static void
6250-paste_text_received (GtkClipboard *clipboard,
6251- const gchar *text,
6252- GtkFileChooserDefault *impl)
6253-{
6254- GtkFilePath *path;
6255
6256- if (!text)
6257- return;
6258-
6259- path = gtk_file_system_uri_to_path (impl->file_system, text);
6260- if (!path)
6261- {
6262- if (!g_path_is_absolute (text))
6263- {
6264- location_popup_handler (impl, text);
6265- return;
6266- }
6267-
6268- path = gtk_file_system_filename_to_path (impl->file_system, text);
6269- if (!path)
6270- {
6271- location_popup_handler (impl, text);
6272- return;
6273- }
6274- }
6275-
6276- if (!gtk_file_chooser_default_select_path (GTK_FILE_CHOOSER (impl), path, NULL))
6277- location_popup_handler (impl, text);
6278-
6279- gtk_file_path_free (path);
6280-}
6281-
6282-/* Handler for the "location-popup-on-paste" keybinding signal */
6283-static void
6284-location_popup_on_paste_handler (GtkFileChooserDefault *impl)
6285-{
6286- GtkClipboard *clipboard = gtk_widget_get_clipboard (GTK_WIDGET (impl),
6287- GDK_SELECTION_CLIPBOARD);
6288- gtk_clipboard_request_text (clipboard,
6289- (GtkClipboardTextReceivedFunc) paste_text_received,
6290- impl);
6291-}
6292-
6293-
6294 /* Implementation for GtkFileChooserEmbed::should_respond() */
6295 static gboolean
6296 gtk_file_chooser_default_should_respond (GtkFileChooserEmbed *chooser_embed)
6297@@ -8469,12 +4257,6 @@
6298
6299 g_assert (impl->action >= GTK_FILE_CHOOSER_ACTION_OPEN && impl->action <= GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER);
6300
6301- if (impl->operation_mode == OPERATION_MODE_SEARCH)
6302- return search_should_respond (impl);
6303-
6304- if (impl->operation_mode == OPERATION_MODE_RECENT)
6305- return recent_should_respond (impl);
6306-
6307 selection_check (impl, &num_selected, &all_files, &all_folders);
6308
6309 if (num_selected > 2)
6310@@ -8533,9 +4315,8 @@
6311
6312 g_assert (impl->action == GTK_FILE_CHOOSER_ACTION_SAVE
6313 || impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER
6314- || ((impl->action == GTK_FILE_CHOOSER_ACTION_OPEN
6315- || impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER)
6316- && impl->location_mode == LOCATION_MODE_FILENAME_ENTRY));
6317+ || impl->action == GTK_FILE_CHOOSER_ACTION_OPEN
6318+ || impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER);
6319
6320 entry = GTK_FILE_CHOOSER_ENTRY (impl->location_entry);
6321 check_save_entry (impl, &path, &is_well_formed, &is_empty, &is_file_part_empty, &is_folder);
6322@@ -8548,14 +4329,14 @@
6323 error = NULL;
6324 if (is_folder)
6325 {
6326- if (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN ||
6327- impl->action == GTK_FILE_CHOOSER_ACTION_SAVE)
6328+ if (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN
6329+ || impl->action == GTK_FILE_CHOOSER_ACTION_SAVE)
6330 {
6331- change_folder_and_display_error (impl, path, TRUE);
6332+ change_folder_and_display_error (impl, path);
6333 retval = FALSE;
6334 }
6335- else if (impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER ||
6336- impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)
6337+ else if (impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER
6338+ || GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)
6339 {
6340 /* The folder already exists, so we do not need to create it.
6341 * Just respond to terminate the dialog.
6342@@ -8598,37 +4379,13 @@
6343 gtk_file_path_free (path);
6344 return retval;
6345 }
6346- else if (impl->toplevel_last_focus_widget == impl->browse_shortcuts_tree_view)
6347- {
6348- /* The focus is on a dialog's action area button, *and* the widget that
6349- * was focused immediately before it is the shortcuts list. Switch to the
6350- * selected shortcut and tell the caller not to respond.
6351- */
6352- GtkTreeIter iter;
6353-
6354- if (shortcuts_get_selected (impl, &iter))
6355- {
6356- shortcuts_activate_iter (impl, &iter);
6357-
6358- focus_browse_tree_view_if_possible (impl);
6359- }
6360- else
6361- goto file_list;
6362-
6363- return FALSE;
6364- }
6365 else if (impl->toplevel_last_focus_widget == impl->browse_files_tree_view)
6366 {
6367 /* The focus is on a dialog's action area button, *and* the widget that
6368- * was focused immediately before it is the file list.
6369+ * was focused immediately before it is the file list.
6370 */
6371 goto file_list;
6372 }
6373- else if (impl->operation_mode == OPERATION_MODE_SEARCH && impl->toplevel_last_focus_widget == impl->search_entry)
6374- {
6375- search_entry_activate_cb (GTK_ENTRY (impl->search_entry), impl);
6376- return FALSE;
6377- }
6378 else if (impl->location_entry && impl->toplevel_last_focus_widget == impl->location_entry)
6379 {
6380 /* The focus is on a dialog's action area button, *and* the widget that
6381@@ -8657,17 +4414,16 @@
6382
6383 impl = GTK_FILE_CHOOSER_DEFAULT (chooser_embed);
6384
6385- if (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN ||
6386- impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER)
6387+ if (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN
6388+ || impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER)
6389 {
6390- if (impl->location_mode == LOCATION_MODE_PATH_BAR)
6391 widget = impl->browse_files_tree_view;
6392- else
6393- widget = impl->location_entry;
6394 }
6395- else if (impl->action == GTK_FILE_CHOOSER_ACTION_SAVE ||
6396- impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)
6397- widget = impl->location_entry;
6398+ else if (impl->action == GTK_FILE_CHOOSER_ACTION_SAVE
6399+ || impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)
6400+ {
6401+ widget = impl->location_entry;
6402+ }
6403 else
6404 {
6405 g_assert_not_reached ();
6406@@ -8678,1475 +4434,7 @@
6407 gtk_widget_grab_focus (widget);
6408 }
6409
6410-/* Callback used from gtk_tree_selection_selected_foreach(); gets the selected GtkFilePaths */
6411 static void
6412-search_selected_foreach_get_path_cb (GtkTreeModel *model,
6413- GtkTreePath *path,
6414- GtkTreeIter *iter,
6415- gpointer data)
6416-{
6417- GSList **list;
6418- const GtkFilePath *file_path;
6419- GtkFilePath *file_path_copy;
6420-
6421- list = data;
6422-
6423- gtk_tree_model_get (model, iter, SEARCH_MODEL_COL_PATH, &file_path, -1);
6424- file_path_copy = gtk_file_path_copy (file_path);
6425- *list = g_slist_prepend (*list, file_path_copy);
6426-}
6427-
6428-/* Constructs a list of the selected paths in search mode */
6429-static GSList *
6430-search_get_selected_paths (GtkFileChooserDefault *impl)
6431-{
6432- GSList *result;
6433- GtkTreeSelection *selection;
6434-
6435- result = NULL;
6436-
6437- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_files_tree_view));
6438- gtk_tree_selection_selected_foreach (selection, search_selected_foreach_get_path_cb, &result);
6439- result = g_slist_reverse (result);
6440-
6441- return result;
6442-}
6443-
6444-/* Called from ::should_respond(). We return whether there are selected files
6445- * in the search list.
6446- */
6447-static gboolean
6448-search_should_respond (GtkFileChooserDefault *impl)
6449-{
6450- GtkTreeSelection *selection;
6451-
6452- g_assert (impl->operation_mode == OPERATION_MODE_SEARCH);
6453-
6454- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_files_tree_view));
6455- return (gtk_tree_selection_count_selected_rows (selection) != 0);
6456-}
6457-
6458-struct SearchHitInsertRequest
6459-{
6460- GtkFileChooserDefault *impl;
6461- GtkFilePath *path;
6462- GtkTreeRowReference *row_ref;
6463-};
6464-
6465-static void
6466-search_hit_get_info_cb (GtkFileSystemHandle *handle,
6467- const GtkFileInfo *info,
6468- const GError *error,
6469- gpointer data)
6470-{
6471- gboolean cancelled = handle->cancelled;
6472- GdkPixbuf *pixbuf = NULL;
6473- GtkTreePath *path;
6474- GtkTreeIter iter;
6475- GtkFileSystemHandle *model_handle;
6476- gboolean is_folder = FALSE;
6477- char *mime_type;
6478- char *display_name;
6479- struct SearchHitInsertRequest *request = data;
6480-
6481- if (!request->impl->search_model)
6482- goto out;
6483-
6484- path = gtk_tree_row_reference_get_path (request->row_ref);
6485- if (!path)
6486- goto out;
6487-
6488- gtk_tree_model_get_iter (GTK_TREE_MODEL (request->impl->search_model),
6489- &iter, path);
6490- gtk_tree_path_free (path);
6491-
6492- gtk_tree_model_get (GTK_TREE_MODEL (request->impl->search_model), &iter,
6493- SEARCH_MODEL_COL_HANDLE, &model_handle,
6494- -1);
6495- if (handle != model_handle)
6496- goto out;
6497-
6498- /* set the handle to NULL in the model */
6499- gtk_list_store_set (request->impl->search_model, &iter,
6500- SEARCH_MODEL_COL_HANDLE, NULL,
6501- -1);
6502-
6503- if (cancelled)
6504- goto out;
6505-
6506- if (!info)
6507- {
6508- gtk_list_store_remove (request->impl->search_model, &iter);
6509- goto out;
6510- }
6511-
6512- display_name = g_strdup (gtk_file_info_get_display_name (info));
6513- mime_type = g_strdup (gtk_file_info_get_mime_type (info));
6514- is_folder = gtk_file_info_get_is_folder (info);
6515- pixbuf = gtk_file_info_render_icon (info, GTK_WIDGET (request->impl),
6516- request->impl->icon_size, NULL);
6517-
6518- gtk_list_store_set (request->impl->search_model, &iter,
6519- SEARCH_MODEL_COL_PIXBUF, pixbuf,
6520- SEARCH_MODEL_COL_DISPLAY_NAME, display_name,
6521- SEARCH_MODEL_COL_MIME_TYPE, mime_type,
6522- SEARCH_MODEL_COL_IS_FOLDER, is_folder,
6523- -1);
6524-
6525- if (pixbuf)
6526- g_object_unref (pixbuf);
6527-
6528-out:
6529- g_object_unref (request->impl);
6530- gtk_file_path_free (request->path);
6531- gtk_tree_row_reference_free (request->row_ref);
6532- g_free (request);
6533-
6534- g_object_unref (handle);
6535-}
6536-
6537-/* Adds one hit from the search engine to the search_model */
6538-static void
6539-search_add_hit (GtkFileChooserDefault *impl,
6540- gchar *uri)
6541-{
6542- GtkFilePath *path;
6543- char *filename;
6544- char *tmp;
6545- char *collation_key;
6546- struct stat statbuf;
6547- struct stat *statbuf_copy;
6548- GtkTreeIter iter;
6549- GtkTreePath *p;
6550- GtkFileSystemHandle *handle;
6551- struct SearchHitInsertRequest *request;
6552-
6553- path = gtk_file_system_uri_to_path (impl->file_system, uri);
6554- if (!path)
6555- return;
6556-
6557- filename = gtk_file_system_path_to_filename (impl->file_system, path);
6558- if (!filename)
6559- {
6560- gtk_file_path_free (path);
6561- return;
6562- }
6563-
6564- if (stat (filename, &statbuf) != 0)
6565- {
6566- gtk_file_path_free (path);
6567- g_free (filename);
6568- return;
6569- }
6570-
6571- statbuf_copy = g_new (struct stat, 1);
6572- *statbuf_copy = statbuf;
6573-
6574- tmp = g_filename_display_name (filename);
6575- collation_key = g_utf8_collate_key_for_filename (tmp, -1);
6576- g_free (tmp);
6577-
6578- request = g_new0 (struct SearchHitInsertRequest, 1);
6579- request->impl = g_object_ref (impl);
6580- request->path = gtk_file_path_copy (path);
6581-
6582- gtk_list_store_append (impl->search_model, &iter);
6583- p = gtk_tree_model_get_path (GTK_TREE_MODEL (impl->search_model), &iter);
6584-
6585- request->row_ref = gtk_tree_row_reference_new (GTK_TREE_MODEL (impl->search_model), p);
6586- gtk_tree_path_free (p);
6587-
6588- handle = gtk_file_system_get_info (impl->file_system, path,
6589- GTK_FILE_INFO_IS_FOLDER | GTK_FILE_INFO_ICON | GTK_FILE_INFO_MIME_TYPE | GTK_FILE_INFO_DISPLAY_NAME,
6590- search_hit_get_info_cb,
6591- request);
6592-
6593- gtk_list_store_set (impl->search_model, &iter,
6594- SEARCH_MODEL_COL_PATH, path,
6595- SEARCH_MODEL_COL_COLLATION_KEY, collation_key,
6596- SEARCH_MODEL_COL_STAT, statbuf_copy,
6597- SEARCH_MODEL_COL_HANDLE, handle,
6598- -1);
6599-}
6600-
6601-/* Callback used from GtkSearchEngine when we get new hits */
6602-static void
6603-search_engine_hits_added_cb (GtkSearchEngine *engine,
6604- GList *hits,
6605- gpointer data)
6606-{
6607- GtkFileChooserDefault *impl;
6608- GList *l;
6609-
6610- impl = GTK_FILE_CHOOSER_DEFAULT (data);
6611-
6612- for (l = hits; l; l = l->next)
6613- search_add_hit (impl, (gchar*)l->data);
6614-}
6615-
6616-/* Callback used from GtkSearchEngine when the query is done running */
6617-static void
6618-search_engine_finished_cb (GtkSearchEngine *engine,
6619- gpointer data)
6620-{
6621- GtkFileChooserDefault *impl;
6622-
6623- impl = GTK_FILE_CHOOSER_DEFAULT (data);
6624-
6625-#if 0
6626- /* EB: setting the model here will avoid loads of row events,
6627- * but it'll make the search look like blocked.
6628- */
6629- gtk_tree_view_set_model (GTK_TREE_VIEW (impl->browse_files_tree_view),
6630- GTK_TREE_MODEL (impl->search_model_filter));
6631-#endif
6632-
6633- /* FMQ: if search was empty, say that we got no hits */
6634- set_busy_cursor (impl, FALSE);
6635-}
6636-
6637-/* Displays a generic error when we cannot create a GtkSearchEngine.
6638- * It would be better if _gtk_search_engine_new() gave us a GError
6639- * with a better message, but it doesn't do that right now.
6640- */
6641-static void
6642-search_error_could_not_create_client (GtkFileChooserDefault *impl)
6643-{
6644- error_message (impl,
6645- _("Could not start the search process"),
6646- _("The program was not able to create a connection to the indexer "
6647- "daemon. Please make sure it is running."));
6648-}
6649-
6650-static void
6651-search_engine_error_cb (GtkSearchEngine *engine,
6652- const gchar *message,
6653- gpointer data)
6654-{
6655- GtkFileChooserDefault *impl;
6656-
6657- impl = GTK_FILE_CHOOSER_DEFAULT (data);
6658-
6659- search_stop_searching (impl, TRUE);
6660- error_message (impl, _("Could not send the search request"), message);
6661-
6662- set_busy_cursor (impl, FALSE);
6663-}
6664-
6665-/* Frees the data in the search_model */
6666-static void
6667-search_clear_model (GtkFileChooserDefault *impl,
6668- gboolean remove_from_treeview)
6669-{
6670- GtkTreeModel *model;
6671- GtkTreeIter iter;
6672-
6673- if (!impl->search_model)
6674- return;
6675-
6676- model = GTK_TREE_MODEL (impl->search_model);
6677-
6678- if (gtk_tree_model_get_iter_first (model, &iter))
6679- do
6680- {
6681- GtkFilePath *path;
6682- gchar *display_name;
6683- gchar *collation_key;
6684- struct stat *statbuf;
6685- GtkFileSystemHandle *handle;
6686-
6687- gtk_tree_model_get (model, &iter,
6688- SEARCH_MODEL_COL_PATH, &path,
6689- SEARCH_MODEL_COL_DISPLAY_NAME, &display_name,
6690- SEARCH_MODEL_COL_COLLATION_KEY, &collation_key,
6691- SEARCH_MODEL_COL_STAT, &statbuf,
6692- SEARCH_MODEL_COL_HANDLE, &handle,
6693- -1);
6694-
6695- if (handle)
6696- gtk_file_system_cancel_operation (handle);
6697-
6698- gtk_file_path_free (path);
6699- g_free (display_name);
6700- g_free (collation_key);
6701- g_free (statbuf);
6702- }
6703- while (gtk_tree_model_iter_next (model, &iter));
6704-
6705- g_object_unref (impl->search_model);
6706- impl->search_model = NULL;
6707-
6708- g_object_unref (impl->search_model_filter);
6709- impl->search_model_filter = NULL;
6710-
6711- g_object_unref (impl->search_model_sort);
6712- impl->search_model_sort = NULL;
6713-
6714- if (remove_from_treeview)
6715- gtk_tree_view_set_model (GTK_TREE_VIEW (impl->browse_files_tree_view), NULL);
6716-}
6717-
6718-/* Stops any ongoing searches; does not touch the search_model */
6719-static void
6720-search_stop_searching (GtkFileChooserDefault *impl,
6721- gboolean remove_query)
6722-{
6723- if (remove_query && impl->search_query)
6724- {
6725- g_object_unref (impl->search_query);
6726- impl->search_query = NULL;
6727- }
6728-
6729- if (impl->search_engine)
6730- {
6731- _gtk_search_engine_stop (impl->search_engine);
6732-
6733- g_object_unref (impl->search_engine);
6734- impl->search_engine = NULL;
6735- }
6736-}
6737-
6738-/* Stops any pending searches, clears the file list, and switches back to OPERATION_MODE_BROWSE */
6739-static void
6740-search_switch_to_browse_mode (GtkFileChooserDefault *impl)
6741-{
6742- g_assert (impl->operation_mode != OPERATION_MODE_BROWSE);
6743-
6744- search_stop_searching (impl, FALSE);
6745- search_clear_model (impl, TRUE);
6746-
6747- gtk_widget_destroy (impl->search_hbox);
6748- impl->search_hbox = NULL;
6749- impl->search_entry = NULL;
6750-
6751- gtk_widget_show (impl->browse_path_bar);
6752- gtk_widget_show (impl->browse_new_folder_button);
6753-
6754- if (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN ||
6755- impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER)
6756- {
6757- gtk_widget_show (impl->location_button);
6758-
6759- if (impl->location_mode == LOCATION_MODE_FILENAME_ENTRY)
6760- gtk_widget_show (impl->location_entry_box);
6761- }
6762-
6763- impl->operation_mode = OPERATION_MODE_BROWSE;
6764-
6765- file_list_set_sort_column_ids (impl);
6766-}
6767-
6768-/* Sort callback from the path column */
6769-static gint
6770-search_column_path_sort_func (GtkTreeModel *model,
6771- GtkTreeIter *a,
6772- GtkTreeIter *b,
6773- gpointer user_data)
6774-{
6775- GtkFileChooserDefault *impl = user_data;
6776- GtkTreeIter child_a, child_b;
6777- const char *collation_key_a, *collation_key_b;
6778- gboolean is_folder_a, is_folder_b;
6779-
6780- gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER (model), &child_a, a);
6781- gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER (model), &child_b, b);
6782-
6783- gtk_tree_model_get (GTK_TREE_MODEL (impl->search_model), &child_a,
6784- SEARCH_MODEL_COL_IS_FOLDER, &is_folder_a,
6785- SEARCH_MODEL_COL_COLLATION_KEY, &collation_key_a,
6786- -1);
6787- gtk_tree_model_get (GTK_TREE_MODEL (impl->search_model), &child_b,
6788- SEARCH_MODEL_COL_IS_FOLDER, &is_folder_b,
6789- SEARCH_MODEL_COL_COLLATION_KEY, &collation_key_b,
6790- -1);
6791-
6792- if (!collation_key_a)
6793- return 1;
6794-
6795- if (!collation_key_b)
6796- return -1;
6797-
6798- /* always show folders first */
6799- if (is_folder_a != is_folder_b)
6800- return is_folder_a ? 1 : -1;
6801-
6802- return strcmp (collation_key_a, collation_key_b);
6803-}
6804-
6805-/* Sort callback from the modification time column */
6806-static gint
6807-search_column_mtime_sort_func (GtkTreeModel *model,
6808- GtkTreeIter *a,
6809- GtkTreeIter *b,
6810- gpointer user_data)
6811-{
6812- GtkFileChooserDefault *impl = user_data;
6813- GtkTreeIter child_a, child_b;
6814- const struct stat *statbuf_a, *statbuf_b;
6815- gboolean is_folder_a, is_folder_b;
6816-
6817- gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER (model), &child_a, a);
6818- gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER (model), &child_b, b);
6819-
6820- /* Note that although we store a whole struct stat in the model, we only
6821- * compare the mtime here. If we add another column relative to a struct stat
6822- * (e.g. a file size column), we'll want another sort callback similar to this
6823- * one as well.
6824- */
6825- gtk_tree_model_get (GTK_TREE_MODEL (impl->search_model), &child_a,
6826- SEARCH_MODEL_COL_IS_FOLDER, &is_folder_a,
6827- SEARCH_MODEL_COL_STAT, &statbuf_a,
6828- -1);
6829- gtk_tree_model_get (GTK_TREE_MODEL (impl->search_model), &child_b,
6830- SEARCH_MODEL_COL_IS_FOLDER, &is_folder_b,
6831- SEARCH_MODEL_COL_STAT, &statbuf_b,
6832- -1);
6833-
6834- if (!statbuf_a)
6835- return 1;
6836-
6837- if (!statbuf_b)
6838- return -1;
6839-
6840- if (is_folder_a != is_folder_b)
6841- return is_folder_a ? 1 : -1;
6842-
6843- if (statbuf_a->st_mtime < statbuf_b->st_mtime)
6844- return -1;
6845- else if (statbuf_a->st_mtime > statbuf_b->st_mtime)
6846- return 1;
6847- else
6848- return 0;
6849-}
6850-
6851-static gboolean
6852-search_get_is_filtered (GtkFileChooserDefault *impl,
6853- const GtkFilePath *path,
6854- const gchar *display_name,
6855- const gchar *mime_type)
6856-{
6857- GtkFileFilterInfo filter_info;
6858- GtkFileFilterFlags needed;
6859- gboolean result;
6860-
6861- if (!impl->current_filter)
6862- return FALSE;
6863-
6864- filter_info.contains = GTK_FILE_FILTER_DISPLAY_NAME | GTK_FILE_FILTER_MIME_TYPE;
6865- needed = gtk_file_filter_get_needed (impl->current_filter);
6866-
6867- filter_info.display_name = display_name;
6868- filter_info.mime_type = mime_type;
6869-
6870- if (needed & GTK_FILE_FILTER_FILENAME)
6871- {
6872- filter_info.filename = gtk_file_system_path_to_filename (impl->file_system, path);
6873- if (filter_info.filename)
6874- filter_info.contains |= GTK_FILE_FILTER_FILENAME;
6875- }
6876- else
6877- filter_info.filename = NULL;
6878-
6879- if (needed & GTK_FILE_FILTER_URI)
6880- {
6881- filter_info.uri = gtk_file_system_path_to_uri (impl->file_system, path);
6882- if (filter_info.uri)
6883- filter_info.contains |= GTK_FILE_FILTER_URI;
6884- }
6885- else
6886- filter_info.uri = NULL;
6887-
6888- result = gtk_file_filter_filter (impl->current_filter, &filter_info);
6889-
6890- if (filter_info.filename)
6891- g_free ((gchar *) filter_info.filename);
6892- if (filter_info.uri)
6893- g_free ((gchar *) filter_info.uri);
6894-
6895- return !result;
6896-
6897-}
6898-
6899-/* Visibility function for the recent filter model */
6900-static gboolean
6901-search_model_visible_func (GtkTreeModel *model,
6902- GtkTreeIter *iter,
6903- gpointer user_data)
6904-{
6905- GtkFileChooserDefault *impl = user_data;
6906- GtkFilePath *file_path;
6907- gchar *display_name, *mime_type;
6908- gboolean is_folder;
6909-
6910- if (!impl->current_filter)
6911- return TRUE;
6912-
6913- gtk_tree_model_get (model, iter,
6914- SEARCH_MODEL_COL_PATH, &file_path,
6915- SEARCH_MODEL_COL_IS_FOLDER, &is_folder,
6916- SEARCH_MODEL_COL_DISPLAY_NAME, &display_name,
6917- SEARCH_MODEL_COL_MIME_TYPE, &mime_type,
6918- -1);
6919-
6920- if (!display_name)
6921- return TRUE;
6922-
6923- if (is_folder)
6924- return TRUE;
6925-
6926- return !search_get_is_filtered (impl, file_path, display_name, mime_type);
6927-}
6928-
6929-/* Creates the search_model and puts it in the tree view */
6930-static void
6931-search_setup_model (GtkFileChooserDefault *impl)
6932-{
6933- g_assert (impl->search_model == NULL);
6934- g_assert (impl->search_model_filter == NULL);
6935- g_assert (impl->search_model_sort == NULL);
6936-
6937- /* We store these columns in the search model:
6938- *
6939- * SEARCH_MODEL_COL_PATH - a GtkFilePath for the hit's URI, stored as a
6940- * pointer not as a GTK_TYPE_FILE_PATH
6941- * SEARCH_MODEL_COL_DISPLAY_NAME - a string with the display name, stored
6942- * as a pointer not as a G_TYPE_STRING
6943- * SEARCH_MODEL_COL_COLLATION_KEY - collation key for the filename, stored
6944- * as a pointer not as a G_TYPE_STRING
6945- * SEARCH_MODEL_COL_STAT - pointer to a struct stat
6946- * SEARCH_MODEL_COL_HANDLE - handle used when getting the hit's info
6947- * SEARCH_MODEL_COL_PIXBUF - GdkPixbuf for the hit's icon
6948- * SEARCH_MODEL_COL_MIME_TYPE - a string with the hit's MIME type
6949- * SEARCH_MODEL_COL_IS_FOLDER - a boolean flag for folders
6950- *
6951- * Keep this in sync with the enumeration defined near the beginning
6952- * of this file.
6953- */
6954- impl->search_model = gtk_list_store_new (SEARCH_MODEL_COL_NUM_COLUMNS,
6955- G_TYPE_POINTER,
6956- G_TYPE_POINTER,
6957- G_TYPE_POINTER,
6958- G_TYPE_POINTER,
6959- G_TYPE_POINTER,
6960- GDK_TYPE_PIXBUF,
6961- G_TYPE_POINTER,
6962- G_TYPE_BOOLEAN);
6963-
6964- impl->search_model_filter =
6965- GTK_TREE_MODEL_FILTER (gtk_tree_model_filter_new (GTK_TREE_MODEL (impl->search_model), NULL));
6966- gtk_tree_model_filter_set_visible_func (impl->search_model_filter,
6967- search_model_visible_func,
6968- impl, NULL);
6969-
6970- impl->search_model_sort =
6971- GTK_TREE_MODEL_SORT (search_model_sort_new (impl, GTK_TREE_MODEL (impl->search_model_filter)));
6972- gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (impl->search_model_sort),
6973- SEARCH_MODEL_COL_PATH,
6974- search_column_path_sort_func,
6975- impl, NULL);
6976- gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (impl->search_model_sort),
6977- SEARCH_MODEL_COL_STAT,
6978- search_column_mtime_sort_func,
6979- impl, NULL);
6980- gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (impl->search_model_sort),
6981- SEARCH_MODEL_COL_STAT,
6982- GTK_SORT_DESCENDING);
6983-
6984- /* EB: setting the model here will make the hits list update feel
6985- * more "alive" than setting the model at the end of the search
6986- * run
6987- */
6988- gtk_tree_view_set_model (GTK_TREE_VIEW (impl->browse_files_tree_view),
6989- GTK_TREE_MODEL (impl->search_model_sort));
6990-}
6991-
6992-static void
6993-search_get_valid_child_iter (GtkFileChooserDefault *impl,
6994- GtkTreeIter *child_iter,
6995- GtkTreeIter *iter)
6996-{
6997- GtkTreeIter middle;
6998-
6999- if (!impl->search_model)
7000- return;
7001-
7002- if (!impl->search_model_filter || !impl->search_model_sort)
7003- return;
7004-
7005- /* pass 1: get the iterator in the filter model */
7006- gtk_tree_model_sort_convert_iter_to_child_iter (impl->search_model_sort,
7007- &middle, iter);
7008-
7009- /* pass 2: get the iterator in the real model */
7010- gtk_tree_model_filter_convert_iter_to_child_iter (impl->search_model_filter,
7011- child_iter, &middle);
7012-}
7013-
7014-/* Creates a new query with the specified text and launches it */
7015-static void
7016-search_start_query (GtkFileChooserDefault *impl,
7017- const gchar *query_text)
7018-{
7019- search_stop_searching (impl, FALSE);
7020- search_clear_model (impl, TRUE);
7021- search_setup_model (impl);
7022- set_busy_cursor (impl, TRUE);
7023-
7024- if (impl->search_engine == NULL)
7025- impl->search_engine = _gtk_search_engine_new ();
7026-
7027- if (!impl->search_engine)
7028- {
7029- set_busy_cursor (impl, FALSE);
7030- search_error_could_not_create_client (impl); /* lame; we don't get an error code or anything */
7031- return;
7032- }
7033-
7034- if (!impl->search_query)
7035- {
7036- impl->search_query = _gtk_query_new ();
7037- _gtk_query_set_text (impl->search_query, query_text);
7038- }
7039-
7040- _gtk_search_engine_set_query (impl->search_engine, impl->search_query);
7041-
7042- g_signal_connect (impl->search_engine, "hits-added",
7043- G_CALLBACK (search_engine_hits_added_cb), impl);
7044- g_signal_connect (impl->search_engine, "finished",
7045- G_CALLBACK (search_engine_finished_cb), impl);
7046- g_signal_connect (impl->search_engine, "error",
7047- G_CALLBACK (search_engine_error_cb), impl);
7048-
7049- _gtk_search_engine_start (impl->search_engine);
7050-}
7051-
7052-/* Callback used when the user presses Enter while typing on the search
7053- * entry; starts the query
7054- */
7055-static void
7056-search_entry_activate_cb (GtkEntry *entry,
7057- gpointer data)
7058-{
7059- GtkFileChooserDefault *impl;
7060- const char *text;
7061-
7062- impl = GTK_FILE_CHOOSER_DEFAULT (data);
7063-
7064- text = gtk_entry_get_text (GTK_ENTRY (impl->search_entry));
7065- if (strlen (text) == 0)
7066- return;
7067-
7068- /* reset any existing query object */
7069- if (impl->search_query)
7070- {
7071- g_object_unref (impl->search_query);
7072- impl->search_query = NULL;
7073- }
7074-
7075- search_start_query (impl, text);
7076-}
7077-
7078-/* Hides the path bar and creates the search entry */
7079-static void
7080-search_setup_widgets (GtkFileChooserDefault *impl)
7081-{
7082- GtkWidget *label;
7083-
7084- impl->search_hbox = gtk_hbox_new (FALSE, 12);
7085-
7086- /* Label */
7087-
7088- label = gtk_label_new_with_mnemonic (_("_Search:"));
7089- gtk_box_pack_start (GTK_BOX (impl->search_hbox), label, FALSE, FALSE, 0);
7090-
7091- /* Entry */
7092-
7093- impl->search_entry = gtk_entry_new ();
7094- gtk_label_set_mnemonic_widget (GTK_LABEL (label), impl->search_entry);
7095- g_signal_connect (impl->search_entry, "activate",
7096- G_CALLBACK (search_entry_activate_cb),
7097- impl);
7098- gtk_box_pack_start (GTK_BOX (impl->search_hbox), impl->search_entry, TRUE, TRUE, 0);
7099-
7100- /* if there already is a query, restart it */
7101- if (impl->search_query)
7102- {
7103- gchar *query = _gtk_query_get_text (impl->search_query);
7104-
7105- if (query)
7106- {
7107- gtk_entry_set_text (GTK_ENTRY (impl->search_entry), query);
7108- search_start_query (impl, query);
7109-
7110- g_free (query);
7111- }
7112- else
7113- {
7114- g_object_unref (impl->search_query);
7115- impl->search_query = NULL;
7116- }
7117- }
7118-
7119- gtk_widget_hide (impl->browse_path_bar);
7120- gtk_widget_hide (impl->browse_new_folder_button);
7121-
7122- /* Box for search widgets */
7123- gtk_box_pack_start (GTK_BOX (impl->browse_path_bar_hbox), impl->search_hbox, TRUE, TRUE, 0);
7124- gtk_widget_show_all (impl->search_hbox);
7125-
7126- /* Hide the location widgets temporarily */
7127-
7128- if (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN ||
7129- impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER)
7130- {
7131- gtk_widget_hide (impl->location_button);
7132- gtk_widget_hide (impl->location_entry_box);
7133- }
7134-
7135- gtk_widget_grab_focus (impl->search_entry);
7136-
7137- /* FMQ: hide the filter combo? */
7138-}
7139-
7140-/* Main entry point to the searching functions; this gets called when the user
7141- * activates the Search shortcut.
7142- */
7143-static void
7144-search_activate (GtkFileChooserDefault *impl)
7145-{
7146- OperationMode previous_mode;
7147-
7148- if (impl->operation_mode == OPERATION_MODE_SEARCH)
7149- {
7150- gtk_widget_grab_focus (impl->search_entry);
7151- return;
7152- }
7153-
7154- previous_mode = impl->operation_mode;
7155- impl->operation_mode = OPERATION_MODE_SEARCH;
7156-
7157- switch (previous_mode)
7158- {
7159- case OPERATION_MODE_RECENT:
7160- recent_stop_loading (impl);
7161- recent_clear_model (impl, TRUE);
7162- break;
7163-
7164- case OPERATION_MODE_BROWSE:
7165- stop_loading_and_clear_list_model (impl);
7166- break;
7167-
7168- case OPERATION_MODE_SEARCH:
7169- g_assert_not_reached ();
7170- break;
7171- }
7172-
7173- g_assert (impl->search_hbox == NULL);
7174- g_assert (impl->search_entry == NULL);
7175- g_assert (impl->search_model == NULL);
7176- g_assert (impl->search_model_filter == NULL);
7177-
7178- search_setup_widgets (impl);
7179- file_list_set_sort_column_ids (impl);
7180-}
7181-
7182-/*
7183- * Recent files support
7184- */
7185-
7186-/* Frees the data in the recent_model */
7187-static void
7188-recent_clear_model (GtkFileChooserDefault *impl,
7189- gboolean remove_from_treeview)
7190-{
7191- GtkTreeModel *model;
7192- GtkTreeIter iter;
7193-
7194- if (!impl->recent_model)
7195- return;
7196-
7197- model = GTK_TREE_MODEL (impl->recent_model);
7198-
7199- if (remove_from_treeview)
7200- gtk_tree_view_set_model (GTK_TREE_VIEW (impl->browse_files_tree_view), NULL);
7201-
7202- if (gtk_tree_model_get_iter_first (model, &iter))
7203- {
7204- do
7205- {
7206- GtkFilePath *file_path;
7207- GtkFileSystemHandle *handle;
7208- GtkRecentInfo *recent_info;
7209- gchar *display_name;
7210-
7211- gtk_tree_model_get (model, &iter,
7212- RECENT_MODEL_COL_DISPLAY_NAME, &display_name,
7213- RECENT_MODEL_COL_PATH, &file_path,
7214- RECENT_MODEL_COL_HANDLE, &handle,
7215- RECENT_MODEL_COL_INFO, &recent_info,
7216- -1);
7217-
7218- if (handle)
7219- gtk_file_system_cancel_operation (handle);
7220-
7221- gtk_file_path_free (file_path);
7222- gtk_recent_info_unref (recent_info);
7223- g_free (display_name);
7224- }
7225- while (gtk_tree_model_iter_next (model, &iter));
7226- }
7227-
7228- g_object_unref (impl->recent_model);
7229- impl->recent_model = NULL;
7230-
7231- g_object_unref (impl->recent_model_filter);
7232- impl->recent_model_filter = NULL;
7233-
7234- g_object_unref (impl->recent_model_sort);
7235- impl->recent_model_sort = NULL;
7236-}
7237-
7238-/* Stops any ongoing loading of the recent files list; does
7239- * not touch the recent_model
7240- */
7241-static void
7242-recent_stop_loading (GtkFileChooserDefault *impl)
7243-{
7244- if (impl->load_recent_id)
7245- {
7246- g_source_remove (impl->load_recent_id);
7247- impl->load_recent_id = 0;
7248- }
7249-}
7250-
7251-/* Stops any pending load, clears the file list, and switches
7252- * back to OPERATION_MODE_BROWSE
7253- */
7254-static void
7255-recent_switch_to_browse_mode (GtkFileChooserDefault *impl)
7256-{
7257- g_assert (impl->operation_mode != OPERATION_MODE_BROWSE);
7258-
7259- recent_stop_loading (impl);
7260- recent_clear_model (impl, TRUE);
7261-
7262- gtk_widget_show (impl->browse_path_bar);
7263- gtk_widget_show (impl->browse_new_folder_button);
7264-
7265- if (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN ||
7266- impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER)
7267- {
7268- gtk_widget_show (impl->location_button);
7269-
7270- if (impl->location_mode == LOCATION_MODE_FILENAME_ENTRY)
7271- gtk_widget_show (impl->location_entry_box);
7272- }
7273-
7274- impl->operation_mode = OPERATION_MODE_BROWSE;
7275-
7276- file_list_set_sort_column_ids (impl);
7277-}
7278-
7279-/* Sort callback from the modification time column */
7280-static gint
7281-recent_column_mtime_sort_func (GtkTreeModel *model,
7282- GtkTreeIter *a,
7283- GtkTreeIter *b,
7284- gpointer user_data)
7285-{
7286- GtkFileChooserDefault *impl = user_data;
7287- GtkTreeIter child_a, child_b;
7288- GtkRecentInfo *info_a, *info_b;
7289- gboolean is_folder_a, is_folder_b;
7290-
7291- gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER (model), &child_a, a);
7292- gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER (model), &child_b, b);
7293-
7294- gtk_tree_model_get (GTK_TREE_MODEL (impl->recent_model), &child_a,
7295- RECENT_MODEL_COL_IS_FOLDER, &is_folder_a,
7296- RECENT_MODEL_COL_INFO, &info_a,
7297- -1);
7298- gtk_tree_model_get (GTK_TREE_MODEL (impl->recent_model), &child_b,
7299- RECENT_MODEL_COL_IS_FOLDER, &is_folder_b,
7300- RECENT_MODEL_COL_INFO, &info_b,
7301- -1);
7302-
7303- if (!info_a)
7304- return 1;
7305-
7306- if (!info_b)
7307- return -1;
7308-
7309- /* folders always go first */
7310- if (is_folder_a != is_folder_b)
7311- return is_folder_a ? 1 : -1;
7312-
7313- if (gtk_recent_info_get_modified (info_a) < gtk_recent_info_get_modified (info_b))
7314- return -1;
7315- else if (gtk_recent_info_get_modified (info_a) > gtk_recent_info_get_modified (info_b))
7316- return 1;
7317- else
7318- return 0;
7319-}
7320-
7321-static gint
7322-recent_column_path_sort_func (GtkTreeModel *model,
7323- GtkTreeIter *a,
7324- GtkTreeIter *b,
7325- gpointer user_data)
7326-{
7327- GtkFileChooserDefault *impl = user_data;
7328- GtkTreeIter child_a, child_b;
7329- gboolean is_folder_a, is_folder_b;
7330- gchar *name_a, *name_b;
7331-
7332- gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER (model), &child_a, a);
7333- gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER (model), &child_b, b);
7334-
7335- gtk_tree_model_get (GTK_TREE_MODEL (impl->recent_model), &child_a,
7336- RECENT_MODEL_COL_IS_FOLDER, &is_folder_a,
7337- RECENT_MODEL_COL_DISPLAY_NAME, &name_a,
7338- -1);
7339- gtk_tree_model_get (GTK_TREE_MODEL (impl->recent_model), &child_b,
7340- RECENT_MODEL_COL_IS_FOLDER, &is_folder_b,
7341- RECENT_MODEL_COL_DISPLAY_NAME, &name_b,
7342- -1);
7343-
7344- if (!name_a)
7345- return 1;
7346-
7347- if (!name_b)
7348- return -1;
7349-
7350- if (is_folder_a != is_folder_b)
7351- return is_folder_a ? 1 : -1;
7352-
7353- return strcmp (name_a, name_b);
7354-}
7355-
7356-static gboolean
7357-recent_get_is_filtered (GtkFileChooserDefault *impl,
7358- const GtkFilePath *path,
7359- GtkRecentInfo *recent_info)
7360-{
7361- GtkFileFilterInfo filter_info;
7362- GtkFileFilterFlags needed;
7363- gboolean result;
7364-
7365- if (!impl->current_filter)
7366- return FALSE;
7367-
7368- filter_info.contains = GTK_FILE_FILTER_DISPLAY_NAME | GTK_FILE_FILTER_MIME_TYPE;
7369- needed = gtk_file_filter_get_needed (impl->current_filter);
7370-
7371- filter_info.display_name = gtk_recent_info_get_display_name (recent_info);
7372- filter_info.mime_type = gtk_recent_info_get_mime_type (recent_info);
7373-
7374- if (needed & GTK_FILE_FILTER_FILENAME)
7375- {
7376- filter_info.filename = gtk_file_system_path_to_filename (impl->file_system, path);
7377- if (filter_info.filename)
7378- filter_info.contains |= GTK_FILE_FILTER_FILENAME;
7379- }
7380- else
7381- filter_info.filename = NULL;
7382-
7383- if (needed & GTK_FILE_FILTER_URI)
7384- {
7385- filter_info.uri = gtk_file_system_path_to_uri (impl->file_system, path);
7386- if (filter_info.uri)
7387- filter_info.contains |= GTK_FILE_FILTER_URI;
7388- }
7389- else
7390- filter_info.uri = NULL;
7391-
7392- result = gtk_file_filter_filter (impl->current_filter, &filter_info);
7393-
7394- if (filter_info.filename)
7395- g_free ((gchar *) filter_info.filename);
7396- if (filter_info.uri)
7397- g_free ((gchar *) filter_info.uri);
7398-
7399- return !result;
7400-}
7401-
7402-/* Visibility function for the recent filter model */
7403-static gboolean
7404-recent_model_visible_func (GtkTreeModel *model,
7405- GtkTreeIter *iter,
7406- gpointer user_data)
7407-{
7408- GtkFileChooserDefault *impl = user_data;
7409- GtkFilePath *file_path;
7410- GtkRecentInfo *recent_info;
7411- gboolean is_folder;
7412-
7413- if (!impl->current_filter)
7414- return TRUE;
7415-
7416- gtk_tree_model_get (model, iter,
7417- RECENT_MODEL_COL_INFO, &recent_info,
7418- RECENT_MODEL_COL_PATH, &file_path,
7419- RECENT_MODEL_COL_IS_FOLDER, &is_folder,
7420- -1);
7421-
7422- if (!recent_info)
7423- return TRUE;
7424-
7425- if (is_folder)
7426- return TRUE;
7427-
7428- return !recent_get_is_filtered (impl, file_path, recent_info);
7429-}
7430-
7431-static void
7432-recent_setup_model (GtkFileChooserDefault *impl)
7433-{
7434- g_assert (impl->recent_model == NULL);
7435- g_assert (impl->recent_model_filter == NULL);
7436- g_assert (impl->recent_model_sort == NULL);
7437-
7438- /* We store these columns in the search model:
7439- *
7440- * RECENT_MODEL_COL_PATH - a pointer to GtkFilePath for the hit's URI,
7441- * stored as a pointer and not as a GTK_TYPE_FILE_PATH;
7442- * RECENT_MODEL_COL_DISPLAY_NAME - a string with the display name,
7443- * stored as a pointer and not as a G_TYPE_STRING;
7444- * RECENT_MODEL_COL_INFO - GtkRecentInfo, stored as a pointer and not
7445- * as a GTK_TYPE_RECENT_INFO;
7446- * RECENT_MODEL_COL_IS_FOLDER - boolean flag;
7447- * RECENT_MODEL_COL_HANDLE - GtkFileSystemHandle, stored as a pointer
7448- * and not as a GTK_TYPE_FILE_SYSTEM_HANDLE;
7449- *
7450- * Keep this in sync with the enumeration defined near the beginning of
7451- * this file.
7452- */
7453- impl->recent_model = gtk_list_store_new (RECENT_MODEL_COL_NUM_COLUMNS,
7454- G_TYPE_POINTER,
7455- G_TYPE_POINTER,
7456- G_TYPE_POINTER,
7457- G_TYPE_BOOLEAN,
7458- G_TYPE_POINTER);
7459-
7460- impl->recent_model_filter =
7461- GTK_TREE_MODEL_FILTER (gtk_tree_model_filter_new (GTK_TREE_MODEL (impl->recent_model), NULL));
7462- gtk_tree_model_filter_set_visible_func (impl->recent_model_filter,
7463- recent_model_visible_func,
7464- impl,
7465- NULL);
7466-
7467- /* this is the model that will actually be added to
7468- * the browse_files_tree_view widget; remember: we are
7469- * stuffing the real model into a filter model and then
7470- * into a sort model; this means we'll have to translate
7471- * the child iterator *twice* to get from a path or an
7472- * iterator coming from the tree view widget to the
7473- * real data inside the model.
7474- */
7475- impl->recent_model_sort =
7476- GTK_TREE_MODEL_SORT (recent_model_sort_new (impl, GTK_TREE_MODEL (impl->recent_model_filter)));
7477- gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (impl->recent_model_sort),
7478- RECENT_MODEL_COL_PATH,
7479- recent_column_path_sort_func,
7480- impl, NULL);
7481- gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (impl->recent_model_sort),
7482- RECENT_MODEL_COL_INFO,
7483- recent_column_mtime_sort_func,
7484- impl, NULL);
7485- gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (impl->recent_model_sort),
7486- RECENT_MODEL_COL_INFO,
7487- GTK_SORT_DESCENDING);
7488-}
7489-
7490-typedef struct
7491-{
7492- GtkFileChooserDefault *impl;
7493- GList *items;
7494- gint n_items;
7495- gint n_loaded_items;
7496- guint needs_sorting : 1;
7497-} RecentLoadData;
7498-
7499-static void
7500-recent_idle_cleanup (gpointer data)
7501-{
7502- RecentLoadData *load_data = data;
7503- GtkFileChooserDefault *impl = load_data->impl;
7504-
7505- gtk_tree_view_set_model (GTK_TREE_VIEW (impl->browse_files_tree_view),
7506- GTK_TREE_MODEL (impl->recent_model_sort));
7507-
7508- set_busy_cursor (impl, FALSE);
7509-
7510- impl->load_recent_id = 0;
7511-
7512- if (load_data->items)
7513- {
7514- g_list_foreach (load_data->items, (GFunc) gtk_recent_info_unref, NULL);
7515- g_list_free (load_data->items);
7516- }
7517-
7518- g_free (load_data);
7519-}
7520-
7521-struct RecentItemInsertRequest
7522-{
7523- GtkFileChooserDefault *impl;
7524- GtkFilePath *path;
7525- GtkTreeRowReference *row_ref;
7526-};
7527-
7528-static void
7529-recent_item_get_info_cb (GtkFileSystemHandle *handle,
7530- const GtkFileInfo *info,
7531- const GError *error,
7532- gpointer data)
7533-{
7534- gboolean cancelled = handle->cancelled;
7535- GtkTreePath *path;
7536- GtkTreeIter iter;
7537- GtkFileSystemHandle *model_handle;
7538- gboolean is_folder = FALSE;
7539- struct RecentItemInsertRequest *request = data;
7540-
7541- if (!request->impl->recent_model)
7542- goto out;
7543-
7544- path = gtk_tree_row_reference_get_path (request->row_ref);
7545- if (!path)
7546- goto out;
7547-
7548- gtk_tree_model_get_iter (GTK_TREE_MODEL (request->impl->recent_model),
7549- &iter, path);
7550- gtk_tree_path_free (path);
7551-
7552- gtk_tree_model_get (GTK_TREE_MODEL (request->impl->recent_model), &iter,
7553- RECENT_MODEL_COL_HANDLE, &model_handle,
7554- -1);
7555- if (handle != model_handle)
7556- goto out;
7557-
7558- gtk_list_store_set (request->impl->recent_model, &iter,
7559- RECENT_MODEL_COL_HANDLE, NULL,
7560- -1);
7561-
7562- if (cancelled)
7563- goto out;
7564-
7565- if (!info)
7566- {
7567- gtk_list_store_remove (request->impl->recent_model, &iter);
7568- goto out;
7569- }
7570-
7571- is_folder = gtk_file_info_get_is_folder (info);
7572-
7573- gtk_list_store_set (request->impl->recent_model, &iter,
7574- RECENT_MODEL_COL_IS_FOLDER, is_folder,
7575- -1);
7576-
7577-out:
7578- g_object_unref (request->impl);
7579- gtk_file_path_free (request->path);
7580- gtk_tree_row_reference_free (request->row_ref);
7581- g_free (request);
7582-
7583- g_object_unref (handle);
7584-}
7585-
7586-static gint
7587-recent_sort_mru (gconstpointer a,
7588- gconstpointer b)
7589-{
7590- GtkRecentInfo *info_a = (GtkRecentInfo *) a;
7591- GtkRecentInfo *info_b = (GtkRecentInfo *) b;
7592-
7593- return (gtk_recent_info_get_modified (info_b) - gtk_recent_info_get_modified (info_a));
7594-}
7595-
7596-static gint
7597-get_recent_files_limit (GtkWidget *widget)
7598-{
7599- GtkSettings *settings;
7600- gint limit;
7601-
7602- if (gtk_widget_has_screen (widget))
7603- settings = gtk_settings_get_for_screen (gtk_widget_get_screen (widget));
7604- else
7605- settings = gtk_settings_get_default ();
7606-
7607- g_object_get (G_OBJECT (settings), "gtk-recent-files-limit", &limit, NULL);
7608-
7609- return limit;
7610-}
7611-
7612-static gboolean
7613-recent_idle_load (gpointer data)
7614-{
7615- RecentLoadData *load_data = data;
7616- GtkFileChooserDefault *impl = load_data->impl;
7617- GtkTreeIter iter;
7618- GtkTreePath *p;
7619- GtkRecentInfo *info;
7620- const gchar *uri, *display_name;
7621- GtkFilePath *path;
7622- GtkFileSystemHandle *handle;
7623- struct RecentItemInsertRequest *request;
7624-
7625- if (!impl->recent_manager)
7626- return FALSE;
7627-
7628- /* first iteration: load all the items */
7629- if (!load_data->items)
7630- {
7631- load_data->items = gtk_recent_manager_get_items (impl->recent_manager);
7632- if (!load_data->items)
7633- return FALSE;
7634-
7635- load_data->needs_sorting = TRUE;
7636-
7637- return TRUE;
7638- }
7639-
7640- /* second iteration: preliminary MRU sorting and clamping */
7641- if (load_data->needs_sorting)
7642- {
7643- gint limit;
7644-
7645- load_data->items = g_list_sort (load_data->items, recent_sort_mru);
7646- load_data->n_items = g_list_length (load_data->items);
7647-
7648- limit = get_recent_files_limit (GTK_WIDGET (impl));
7649-
7650- if (limit != -1 && (load_data->n_items > limit))
7651- {
7652- GList *clamp, *l;
7653-
7654- clamp = g_list_nth (load_data->items, limit - 1);
7655- if (G_LIKELY (clamp))
7656- {
7657- l = clamp->next;
7658- clamp->next = NULL;
7659-
7660- g_list_foreach (l, (GFunc) gtk_recent_info_unref, NULL);
7661- g_list_free (l);
7662-
7663- load_data->n_items = limit;
7664- }
7665- }
7666-
7667- load_data->n_loaded_items = 0;
7668- load_data->needs_sorting = FALSE;
7669-
7670- return TRUE;
7671- }
7672-
7673- info = g_list_nth_data (load_data->items, load_data->n_loaded_items);
7674- g_assert (info != NULL);
7675-
7676- uri = gtk_recent_info_get_uri (info);
7677- display_name = gtk_recent_info_get_display_name (info);
7678- path = gtk_file_system_uri_to_path (impl->file_system, uri);
7679- if (!path)
7680- goto load_next;
7681-
7682- gtk_list_store_append (impl->recent_model, &iter);
7683- p = gtk_tree_model_get_path (GTK_TREE_MODEL (impl->recent_model), &iter);
7684-
7685- request = g_new0 (struct RecentItemInsertRequest, 1);
7686- request->impl = g_object_ref (impl);
7687- request->path = gtk_file_path_copy (path);
7688- request->row_ref = gtk_tree_row_reference_new (GTK_TREE_MODEL (impl->recent_model), p);
7689- gtk_tree_path_free (p);
7690-
7691- handle = gtk_file_system_get_info (impl->file_system, path,
7692- GTK_FILE_INFO_IS_FOLDER,
7693- recent_item_get_info_cb,
7694- request);
7695-
7696- gtk_list_store_set (impl->recent_model, &iter,
7697- RECENT_MODEL_COL_PATH, path,
7698- RECENT_MODEL_COL_DISPLAY_NAME, g_strdup (display_name),
7699- RECENT_MODEL_COL_INFO, gtk_recent_info_ref (info),
7700- RECENT_MODEL_COL_HANDLE, handle,
7701- -1);
7702-
7703-load_next:
7704-
7705- load_data->n_loaded_items += 1;
7706-
7707- /* finished loading items */
7708- if (load_data->n_loaded_items == load_data->n_items)
7709- {
7710- g_list_foreach (load_data->items, (GFunc) gtk_recent_info_unref, NULL);
7711- g_list_free (load_data->items);
7712- load_data->items = NULL;
7713-
7714- return FALSE;
7715- }
7716-
7717- return TRUE;
7718-}
7719-
7720-static void
7721-recent_start_loading (GtkFileChooserDefault *impl)
7722-{
7723- RecentLoadData *load_data;
7724-
7725- recent_stop_loading (impl);
7726- recent_clear_model (impl, TRUE);
7727- recent_setup_model (impl);
7728- set_busy_cursor (impl, TRUE);
7729-
7730- if (!impl->recent_manager)
7731- recent_manager_update (impl);
7732-
7733- g_assert (impl->load_recent_id == 0);
7734-
7735- load_data = g_new (RecentLoadData, 1);
7736- load_data->impl = impl;
7737- load_data->items = NULL;
7738- load_data->n_items = 0;
7739- load_data->n_loaded_items = 0;
7740- load_data->needs_sorting = TRUE;
7741-
7742- /* begin lazy loading the recent files into the model */
7743- impl->load_recent_id = gdk_threads_add_idle_full (G_PRIORITY_HIGH_IDLE + 30,
7744- recent_idle_load,
7745- load_data,
7746- recent_idle_cleanup);
7747-}
7748-
7749-static void
7750-recent_selected_foreach_get_path_cb (GtkTreeModel *model,
7751- GtkTreePath *path,
7752- GtkTreeIter *iter,
7753- gpointer data)
7754-{
7755- GSList **list;
7756- const GtkFilePath *file_path;
7757- GtkFilePath *file_path_copy;
7758-
7759- list = data;
7760-
7761- gtk_tree_model_get (model, iter, RECENT_MODEL_COL_PATH, &file_path, -1);
7762- file_path_copy = gtk_file_path_copy (file_path);
7763- *list = g_slist_prepend (*list, file_path_copy);
7764-}
7765-
7766-/* Constructs a list of the selected paths in recent files mode */
7767-static GSList *
7768-recent_get_selected_paths (GtkFileChooserDefault *impl)
7769-{
7770- GSList *result;
7771- GtkTreeSelection *selection;
7772-
7773- result = NULL;
7774-
7775- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_files_tree_view));
7776- gtk_tree_selection_selected_foreach (selection, recent_selected_foreach_get_path_cb, &result);
7777- result = g_slist_reverse (result);
7778-
7779- return result;
7780-}
7781-
7782-/* Called from ::should_respond(). We return whether there are selected
7783- * files in the recent files list.
7784- */
7785-static gboolean
7786-recent_should_respond (GtkFileChooserDefault *impl)
7787-{
7788- GtkTreeSelection *selection;
7789-
7790- g_assert (impl->operation_mode == OPERATION_MODE_RECENT);
7791-
7792- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_files_tree_view));
7793- return (gtk_tree_selection_count_selected_rows (selection) != 0);
7794-}
7795-
7796-/* Hide the location widgets temporarily */
7797-static void
7798-recent_hide_entry (GtkFileChooserDefault *impl)
7799-{
7800- gtk_widget_hide (impl->browse_path_bar);
7801- gtk_widget_hide (impl->browse_new_folder_button);
7802-
7803- if (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN ||
7804- impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER)
7805- {
7806- gtk_widget_hide (impl->location_button);
7807- gtk_widget_hide (impl->location_entry_box);
7808- }
7809-}
7810-
7811-/* Main entry point to the recent files functions; this gets called when
7812- * the user activates the Recently Used shortcut.
7813- */
7814-static void
7815-recent_activate (GtkFileChooserDefault *impl)
7816-{
7817- OperationMode previous_mode;
7818-
7819- if (impl->operation_mode == OPERATION_MODE_RECENT)
7820- return;
7821-
7822- previous_mode = impl->operation_mode;
7823- impl->operation_mode = OPERATION_MODE_RECENT;
7824-
7825- switch (previous_mode)
7826- {
7827- case OPERATION_MODE_SEARCH:
7828- search_stop_searching (impl, FALSE);
7829- search_clear_model (impl, TRUE);
7830-
7831- gtk_widget_destroy (impl->search_hbox);
7832- impl->search_hbox = NULL;
7833- impl->search_entry = NULL;
7834- break;
7835-
7836- case OPERATION_MODE_BROWSE:
7837- stop_loading_and_clear_list_model (impl);
7838- break;
7839-
7840- case OPERATION_MODE_RECENT:
7841- g_assert_not_reached ();
7842- break;
7843- }
7844-
7845- recent_hide_entry (impl);
7846- file_list_set_sort_column_ids (impl);
7847- recent_start_loading (impl);
7848-}
7849-
7850-/* convert an iterator coming from the model bound to
7851- * browse_files_tree_view to an interator inside the
7852- * real recent_model
7853- */
7854-static void
7855-recent_get_valid_child_iter (GtkFileChooserDefault *impl,
7856- GtkTreeIter *child_iter,
7857- GtkTreeIter *iter)
7858-{
7859- GtkTreeIter middle;
7860-
7861- if (!impl->recent_model)
7862- return;
7863-
7864- if (!impl->recent_model_filter || !impl->recent_model_sort)
7865- return;
7866-
7867- /* pass 1: get the iterator in the filter model */
7868- gtk_tree_model_sort_convert_iter_to_child_iter (impl->recent_model_sort,
7869- &middle, iter);
7870-
7871- /* pass 2: get the iterator in the real model */
7872- gtk_tree_model_filter_convert_iter_to_child_iter (impl->recent_model_filter,
7873- child_iter,
7874- &middle);
7875-}
7876-
7877-
7878-static void
7879 set_current_filter (GtkFileChooserDefault *impl,
7880 GtkFileFilter *filter)
7881 {
7882@@ -10175,12 +4463,6 @@
7883 if (impl->browse_files_model)
7884 install_list_model_filter (impl);
7885
7886- if (impl->search_model_filter)
7887- gtk_tree_model_filter_refilter (impl->search_model_filter);
7888-
7889- if (impl->recent_model_filter)
7890- gtk_tree_model_filter_refilter (impl->recent_model_filter);
7891-
7892 g_object_notify (G_OBJECT (impl), "filter");
7893 }
7894 }
7895@@ -10195,355 +4477,7 @@
7896 set_current_filter (impl, new_filter);
7897 }
7898
7899-static void
7900-check_preview_change (GtkFileChooserDefault *impl)
7901-{
7902- GtkTreePath *cursor_path;
7903- const GtkFilePath *new_path;
7904- const char *new_display_name;
7905-
7906- gtk_tree_view_get_cursor (GTK_TREE_VIEW (impl->browse_files_tree_view), &cursor_path, NULL);
7907- new_path = NULL;
7908- new_display_name = NULL;
7909- if (cursor_path)
7910- {
7911- GtkTreeIter child_iter;
7912-
7913- if (impl->operation_mode == OPERATION_MODE_BROWSE)
7914- {
7915- if (impl->sort_model)
7916- {
7917- GtkTreeIter iter;
7918- const GtkFileInfo *new_info;
7919-
7920- gtk_tree_model_get_iter (GTK_TREE_MODEL (impl->sort_model), &iter, cursor_path);
7921- gtk_tree_path_free (cursor_path);
7922-
7923- gtk_tree_model_sort_convert_iter_to_child_iter (impl->sort_model, &child_iter, &iter);
7924-
7925- new_path = _gtk_file_system_model_get_path (impl->browse_files_model, &child_iter);
7926- new_info = _gtk_file_system_model_get_info (impl->browse_files_model, &child_iter);
7927- if (new_info)
7928- new_display_name = gtk_file_info_get_display_name (new_info);
7929- }
7930- }
7931- else if (impl->operation_mode == OPERATION_MODE_SEARCH)
7932- {
7933- GtkTreeIter iter;
7934-
7935- gtk_tree_model_get_iter (GTK_TREE_MODEL (impl->search_model_sort),
7936- &iter, cursor_path);
7937- gtk_tree_path_free (cursor_path);
7938-
7939- search_get_valid_child_iter (impl, &child_iter, &iter);
7940- gtk_tree_model_get (GTK_TREE_MODEL (impl->search_model), &child_iter,
7941- SEARCH_MODEL_COL_PATH, &new_path,
7942- SEARCH_MODEL_COL_DISPLAY_NAME, &new_display_name,
7943- -1);
7944- }
7945- else if (impl->operation_mode == OPERATION_MODE_RECENT)
7946- {
7947- GtkTreeIter iter;
7948-
7949- gtk_tree_model_get_iter (GTK_TREE_MODEL (impl->recent_model_sort),
7950- &iter, cursor_path);
7951- gtk_tree_path_free (cursor_path);
7952-
7953- recent_get_valid_child_iter (impl, &child_iter, &iter);
7954- gtk_tree_model_get (GTK_TREE_MODEL (impl->recent_model), &child_iter,
7955- RECENT_MODEL_COL_PATH, &new_path,
7956- RECENT_MODEL_COL_DISPLAY_NAME, &new_display_name,
7957- -1);
7958- }
7959- }
7960-
7961- if (new_path != impl->preview_path &&
7962- !(new_path && impl->preview_path &&
7963- gtk_file_path_compare (new_path, impl->preview_path) == 0))
7964- {
7965- if (impl->preview_path)
7966- {
7967- gtk_file_path_free (impl->preview_path);
7968- g_free (impl->preview_display_name);
7969- }
7970-
7971- if (new_path)
7972- {
7973- impl->preview_path = gtk_file_path_copy (new_path);
7974- impl->preview_display_name = g_strdup (new_display_name);
7975- }
7976- else
7977- {
7978- impl->preview_path = NULL;
7979- impl->preview_display_name = NULL;
7980- }
7981-
7982- if (impl->use_preview_label && impl->preview_label)
7983- gtk_label_set_text (GTK_LABEL (impl->preview_label), impl->preview_display_name);
7984-
7985- g_signal_emit_by_name (impl, "update-preview");
7986- }
7987-}
7988-
7989-static void
7990-shortcuts_activate_volume_mount_cb (GtkFileSystemHandle *handle,
7991- GtkFileSystemVolume *volume,
7992- const GError *error,
7993- gpointer data)
7994-{
7995- GtkFilePath *path;
7996- gboolean cancelled = handle->cancelled;
7997- GtkFileChooserDefault *impl = data;
7998-
7999- if (handle != impl->shortcuts_activate_iter_handle)
8000- goto out;
8001-
8002- impl->shortcuts_activate_iter_handle = NULL;
8003-
8004- set_busy_cursor (impl, FALSE);
8005-
8006- if (cancelled)
8007- goto out;
8008-
8009- if (error)
8010- {
8011- char *msg;
8012-
8013- msg = g_strdup_printf (_("Could not mount %s"),
8014- gtk_file_system_volume_get_display_name (impl->file_system, volume));
8015- error_message (impl, msg, error->message);
8016- g_free (msg);
8017-
8018- goto out;
8019- }
8020-
8021- path = gtk_file_system_volume_get_base_path (impl->file_system, volume);
8022- if (path != NULL)
8023- {
8024- change_folder_and_display_error (impl, path, FALSE);
8025- focus_browse_tree_view_if_possible (impl);
8026-
8027- gtk_file_path_free (path);
8028- }
8029-
8030-out:
8031- g_object_unref (impl);
8032- g_object_unref (handle);
8033-}
8034-
8035-
8036-/* Activates a volume by mounting it if necessary and then switching to its
8037- * base path.
8038- */
8039-static void
8040-shortcuts_activate_volume (GtkFileChooserDefault *impl,
8041- GtkFileSystemVolume *volume)
8042-{
8043- GtkFilePath *path;
8044-
8045- switch (impl->operation_mode)
8046- {
8047- case OPERATION_MODE_BROWSE:
8048- break;
8049- case OPERATION_MODE_SEARCH:
8050- search_switch_to_browse_mode (impl);
8051- break;
8052- case OPERATION_MODE_RECENT:
8053- recent_switch_to_browse_mode (impl);
8054- break;
8055- }
8056-
8057- /* We ref the file chooser since volume_mount() may run a main loop, and the
8058- * user could close the file chooser window in the meantime.
8059- */
8060- g_object_ref (impl);
8061-
8062- if (!gtk_file_system_volume_get_is_mounted (impl->file_system, volume))
8063- {
8064- set_busy_cursor (impl, TRUE);
8065-
8066- impl->shortcuts_activate_iter_handle =
8067- gtk_file_system_volume_mount (impl->file_system, volume,
8068- shortcuts_activate_volume_mount_cb,
8069- g_object_ref (impl));
8070- }
8071- else
8072- {
8073- path = gtk_file_system_volume_get_base_path (impl->file_system, volume);
8074- if (path != NULL)
8075- {
8076- change_folder_and_display_error (impl, path, FALSE);
8077- gtk_file_path_free (path);
8078- }
8079- }
8080-
8081- g_object_unref (impl);
8082-}
8083-
8084-/* Opens the folder or volume at the specified iter in the shortcuts model */
8085-struct ShortcutsActivateData
8086-{
8087- GtkFileChooserDefault *impl;
8088- GtkFilePath *path;
8089-};
8090-
8091-static void
8092-shortcuts_activate_get_info_cb (GtkFileSystemHandle *handle,
8093- const GtkFileInfo *info,
8094- const GError *error,
8095- gpointer user_data)
8096-{
8097- gboolean cancelled = handle->cancelled;
8098- struct ShortcutsActivateData *data = user_data;
8099-
8100- if (handle != data->impl->shortcuts_activate_iter_handle)
8101- goto out;
8102-
8103- data->impl->shortcuts_activate_iter_handle = NULL;
8104-
8105- if (cancelled)
8106- goto out;
8107-
8108- if (!error && gtk_file_info_get_is_folder (info))
8109- {
8110- change_folder_and_display_error (data->impl, data->path, FALSE);
8111- focus_browse_tree_view_if_possible (data->impl);
8112- }
8113- else
8114- gtk_file_chooser_default_select_path (GTK_FILE_CHOOSER (data->impl),
8115- data->path,
8116- NULL);
8117-
8118-out:
8119- g_object_unref (data->impl);
8120- gtk_file_path_free (data->path);
8121- g_free (data);
8122-
8123- g_object_unref (handle);
8124-}
8125-
8126-static void
8127-shortcuts_activate_iter (GtkFileChooserDefault *impl,
8128- GtkTreeIter *iter)
8129-{
8130- gpointer col_data;
8131- ShortcutType shortcut_type;
8132-
8133- if (impl->location_mode == LOCATION_MODE_FILENAME_ENTRY && impl->action != GTK_FILE_CHOOSER_ACTION_SAVE)
8134- _gtk_file_chooser_entry_set_file_part (GTK_FILE_CHOOSER_ENTRY (impl->location_entry), "");
8135-
8136- gtk_tree_model_get (GTK_TREE_MODEL (impl->shortcuts_model), iter,
8137- SHORTCUTS_COL_DATA, &col_data,
8138- SHORTCUTS_COL_TYPE, &shortcut_type,
8139- -1);
8140-
8141- if (impl->shortcuts_activate_iter_handle)
8142- {
8143- gtk_file_system_cancel_operation (impl->shortcuts_activate_iter_handle);
8144- impl->shortcuts_activate_iter_handle = NULL;
8145- }
8146-
8147- if (shortcut_type == SHORTCUT_TYPE_SEPARATOR)
8148- return;
8149- else if (shortcut_type == SHORTCUT_TYPE_VOLUME)
8150- {
8151- GtkFileSystemVolume *volume;
8152-
8153- volume = col_data;
8154-
8155- shortcuts_activate_volume (impl, volume);
8156- }
8157- else if (shortcut_type == SHORTCUT_TYPE_PATH)
8158- {
8159- struct ShortcutsActivateData *data;
8160-
8161- data = g_new0 (struct ShortcutsActivateData, 1);
8162- data->impl = g_object_ref (impl);
8163- data->path = gtk_file_path_copy (col_data);
8164-
8165- impl->shortcuts_activate_iter_handle =
8166- gtk_file_system_get_info (impl->file_system, data->path,
8167- GTK_FILE_INFO_IS_FOLDER,
8168- shortcuts_activate_get_info_cb, data);
8169- }
8170- else if (shortcut_type == SHORTCUT_TYPE_SEARCH)
8171- {
8172- search_activate (impl);
8173- }
8174- else if (shortcut_type == SHORTCUT_TYPE_RECENT)
8175- {
8176- recent_activate (impl);
8177- }
8178-}
8179-
8180-/* Callback used when a row in the shortcuts list is activated */
8181-static void
8182-shortcuts_row_activated_cb (GtkTreeView *tree_view,
8183- GtkTreePath *path,
8184- GtkTreeViewColumn *column,
8185- GtkFileChooserDefault *impl)
8186-{
8187- GtkTreeIter iter;
8188- GtkTreeIter child_iter;
8189-
8190- if (!gtk_tree_model_get_iter (impl->shortcuts_pane_filter_model, &iter, path))
8191- return;
8192-
8193- gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER (impl->shortcuts_pane_filter_model),
8194- &child_iter,
8195- &iter);
8196- shortcuts_activate_iter (impl, &child_iter);
8197-}
8198-
8199-/* Handler for GtkWidget::key-press-event on the shortcuts list */
8200 static gboolean
8201-shortcuts_key_press_event_cb (GtkWidget *widget,
8202- GdkEventKey *event,
8203- GtkFileChooserDefault *impl)
8204-{
8205- guint modifiers;
8206-
8207- modifiers = gtk_accelerator_get_default_mod_mask ();
8208-
8209- if ((event->keyval == GDK_BackSpace
8210- || event->keyval == GDK_Delete
8211- || event->keyval == GDK_KP_Delete)
8212- && (event->state & modifiers) == 0)
8213- {
8214- remove_selected_bookmarks (impl);
8215- return TRUE;
8216- }
8217-
8218- if ((event->keyval == GDK_F2)
8219- && (event->state & modifiers) == 0)
8220- {
8221- rename_selected_bookmark (impl);
8222- return TRUE;
8223- }
8224-
8225- return FALSE;
8226-}
8227-
8228-static gboolean
8229-shortcuts_select_func (GtkTreeSelection *selection,
8230- GtkTreeModel *model,
8231- GtkTreePath *path,
8232- gboolean path_currently_selected,
8233- gpointer data)
8234-{
8235- GtkFileChooserDefault *impl = data;
8236- GtkTreeIter filter_iter;
8237- ShortcutType shortcut_type;
8238-
8239- if (!gtk_tree_model_get_iter (impl->shortcuts_pane_filter_model, &filter_iter, path))
8240- g_assert_not_reached ();
8241-
8242- gtk_tree_model_get (impl->shortcuts_pane_filter_model, &filter_iter, SHORTCUTS_COL_TYPE, &shortcut_type, -1);
8243-
8244- return shortcut_type != SHORTCUT_TYPE_SEPARATOR;
8245-}
8246-
8247-static gboolean
8248 list_select_func (GtkTreeSelection *selection,
8249 GtkTreeModel *model,
8250 GtkTreePath *path,
8251@@ -10556,55 +4490,17 @@
8252 impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)
8253 {
8254 GtkTreeIter iter, child_iter;
8255+ const GtkFileInfo *info;
8256
8257- switch (impl->operation_mode)
8258- {
8259- case OPERATION_MODE_SEARCH:
8260- {
8261- gboolean is_folder;
8262+ if (!gtk_tree_model_get_iter (GTK_TREE_MODEL (impl->sort_model), &iter, path))
8263+ return FALSE;
8264+
8265+ gtk_tree_model_sort_convert_iter_to_child_iter (impl->sort_model, &child_iter, &iter);
8266
8267- if (!gtk_tree_model_get_iter (GTK_TREE_MODEL (impl->search_model_sort), &iter, path))
8268- return FALSE;
8269+ info = _gtk_file_system_model_get_info (impl->browse_files_model, &child_iter);
8270
8271- search_get_valid_child_iter (impl, &child_iter, &iter);
8272- gtk_tree_model_get (GTK_TREE_MODEL (impl->search_model), &child_iter,
8273- SEARCH_MODEL_COL_IS_FOLDER, &is_folder,
8274- -1);
8275- if (!is_folder)
8276- return FALSE;
8277- }
8278- break;
8279-
8280- case OPERATION_MODE_RECENT:
8281- {
8282- gboolean is_folder;
8283-
8284- if (!gtk_tree_model_get_iter (GTK_TREE_MODEL (impl->recent_model_sort), &iter, path))
8285- return FALSE;
8286-
8287- recent_get_valid_child_iter (impl, &child_iter, &iter);
8288- gtk_tree_model_get (GTK_TREE_MODEL (impl->recent_model), &child_iter,
8289- RECENT_MODEL_COL_IS_FOLDER, &is_folder,
8290- -1);
8291- if (!is_folder)
8292- return FALSE;
8293- }
8294- break;
8295-
8296- case OPERATION_MODE_BROWSE:
8297- {
8298- const GtkFileInfo *info;
8299-
8300- if (!gtk_tree_model_get_iter (GTK_TREE_MODEL (impl->sort_model), &iter, path))
8301- return FALSE;
8302-
8303- gtk_tree_model_sort_convert_iter_to_child_iter (impl->sort_model, &child_iter, &iter);
8304- info = _gtk_file_system_model_get_info (impl->browse_files_model, &child_iter);
8305- if (info && !gtk_file_info_get_is_folder (info))
8306- return FALSE;
8307- }
8308- break;
8309- }
8310+ if (info && !gtk_file_info_get_is_folder (info))
8311+ return FALSE;
8312 }
8313
8314 return TRUE;
8315@@ -10615,8 +4511,7 @@
8316 GtkFileChooserDefault *impl)
8317 {
8318 /* See if we are in the new folder editable row for Save mode */
8319- if (impl->operation_mode == OPERATION_MODE_BROWSE &&
8320- impl->action == GTK_FILE_CHOOSER_ACTION_SAVE)
8321+ if (impl->action == GTK_FILE_CHOOSER_ACTION_SAVE)
8322 {
8323 const GtkFileInfo *info;
8324 gboolean had_selection;
8325@@ -10634,9 +4529,6 @@
8326 if (impl->location_entry)
8327 update_chooser_entry (impl);
8328
8329- check_preview_change (impl);
8330- bookmarks_check_add_sensitivity (impl);
8331-
8332 g_signal_emit_by_name (impl, "selection-changed", 0);
8333 }
8334
8335@@ -10647,107 +4539,30 @@
8336 GtkTreeViewColumn *column,
8337 GtkFileChooserDefault *impl)
8338 {
8339- GtkTreeIter iter;
8340- GtkTreeIter child_iter;
8341+ GtkTreeIter iter, child_iter;
8342+ const GtkFileInfo *info;
8343
8344- switch (impl->operation_mode)
8345- {
8346- case OPERATION_MODE_SEARCH:
8347- {
8348- GtkFilePath *file_path;
8349- gboolean is_folder;
8350+ if (!gtk_tree_model_get_iter (GTK_TREE_MODEL (impl->sort_model), &iter, path))
8351+ return;
8352
8353- if (!gtk_tree_model_get_iter (GTK_TREE_MODEL (impl->search_model_sort), &iter, path))
8354- return;
8355+ gtk_tree_model_sort_convert_iter_to_child_iter (impl->sort_model, &child_iter, &iter);
8356
8357- search_get_valid_child_iter (impl, &child_iter, &iter);
8358- gtk_tree_model_get (GTK_TREE_MODEL (impl->search_model), &child_iter,
8359- SEARCH_MODEL_COL_PATH, &file_path,
8360- SEARCH_MODEL_COL_IS_FOLDER, &is_folder,
8361- -1);
8362-
8363- if (is_folder)
8364- {
8365- change_folder_and_display_error (impl, file_path, FALSE);
8366- return;
8367- }
8368+ info = _gtk_file_system_model_get_info (impl->browse_files_model, &child_iter);
8369
8370- g_signal_emit_by_name (impl, "file-activated");
8371- }
8372- break;
8373+ if (gtk_file_info_get_is_folder (info))
8374+ {
8375+ const GtkFilePath *file_path;
8376
8377- case OPERATION_MODE_RECENT:
8378- {
8379- GtkFilePath *file_path;
8380- gboolean is_folder;
8381+ file_path = _gtk_file_system_model_get_path (impl->browse_files_model, &child_iter);
8382
8383- if (!gtk_tree_model_get_iter (GTK_TREE_MODEL (impl->recent_model_sort), &iter, path))
8384- return;
8385-
8386- recent_get_valid_child_iter (impl, &child_iter, &iter);
8387- gtk_tree_model_get (GTK_TREE_MODEL (impl->recent_model), &child_iter,
8388- RECENT_MODEL_COL_PATH, &file_path,
8389- RECENT_MODEL_COL_IS_FOLDER, &is_folder,
8390- -1);
8391+ change_folder_and_display_error (impl, file_path);
8392
8393- if (is_folder)
8394- {
8395- change_folder_and_display_error (impl, file_path, FALSE);
8396- return;
8397- }
8398-
8399- g_signal_emit_by_name (impl, "file-activated");
8400- }
8401- break;
8402-
8403- case OPERATION_MODE_BROWSE:
8404- {
8405- const GtkFileInfo *info;
8406-
8407- if (!gtk_tree_model_get_iter (GTK_TREE_MODEL (impl->sort_model), &iter, path))
8408- return;
8409-
8410- gtk_tree_model_sort_convert_iter_to_child_iter (impl->sort_model,
8411- &child_iter, &iter);
8412- info = _gtk_file_system_model_get_info (impl->browse_files_model,
8413- &child_iter);
8414-
8415- if (gtk_file_info_get_is_folder (info))
8416- {
8417- const GtkFilePath *file_path;
8418-
8419- file_path = _gtk_file_system_model_get_path (impl->browse_files_model, &child_iter);
8420- change_folder_and_display_error (impl, file_path, FALSE);
8421- return;
8422- }
8423-
8424- if (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN ||
8425- impl->action == GTK_FILE_CHOOSER_ACTION_SAVE)
8426- g_signal_emit_by_name (impl, "file-activated");
8427- }
8428- break;
8429+ return;
8430 }
8431-}
8432
8433-static void
8434-path_bar_clicked (GtkPathBar *path_bar,
8435- GtkFilePath *file_path,
8436- GtkFilePath *child_path,
8437- gboolean child_is_hidden,
8438- GtkFileChooserDefault *impl)
8439-{
8440- if (child_path)
8441- pending_select_paths_add (impl, child_path);
8442-
8443- if (!change_folder_and_display_error (impl, file_path, FALSE))
8444- return;
8445-
8446- /* Say we have "/foo/bar/[.baz]" and the user clicks on "bar". We should then
8447- * show hidden files so that ".baz" appears in the file list, as it will still
8448- * be shown in the path bar: "/foo/[bar]/.baz"
8449- */
8450- if (child_is_hidden)
8451- g_object_set (impl, "show-hidden", TRUE, NULL);
8452+ if (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN ||
8453+ impl->action == GTK_FILE_CHOOSER_ACTION_SAVE)
8454+ g_signal_emit_by_name (impl, "file-activated");
8455 }
8456
8457 static const GtkFileInfo *
8458@@ -10772,83 +4587,40 @@
8459 {
8460 GtkFileChooserDefault *impl = data;
8461 GtkTreeIter child_iter;
8462- GdkPixbuf *pixbuf = NULL;
8463+ const GtkFilePath *path;
8464+ GdkPixbuf *pixbuf;
8465+ const GtkFileInfo *info;
8466 gboolean sensitive = TRUE;
8467
8468 profile_start ("start", NULL);
8469
8470- switch (impl->operation_mode)
8471- {
8472- case OPERATION_MODE_SEARCH:
8473- {
8474- GtkTreeIter child_iter;
8475- gboolean is_folder;
8476+ info = get_list_file_info (impl, iter);
8477
8478- search_get_valid_child_iter (impl, &child_iter, iter);
8479- gtk_tree_model_get (GTK_TREE_MODEL (impl->search_model), &child_iter,
8480- SEARCH_MODEL_COL_PIXBUF, &pixbuf,
8481- SEARCH_MODEL_COL_IS_FOLDER, &is_folder,
8482- -1);
8483-
8484- if (impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER ||
8485- impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)
8486- sensitive = is_folder;
8487- }
8488- break;
8489+ gtk_tree_model_sort_convert_iter_to_child_iter (impl->sort_model,
8490+ &child_iter,
8491+ iter);
8492+ path = _gtk_file_system_model_get_path (impl->browse_files_model, &child_iter);
8493
8494- case OPERATION_MODE_RECENT:
8495- {
8496- GtkTreeIter child_iter;
8497- GtkRecentInfo *info;
8498- gboolean is_folder;
8499+ if (path)
8500+ {
8501+ pixbuf = NULL;
8502
8503- recent_get_valid_child_iter (impl, &child_iter, iter);
8504- gtk_tree_model_get (GTK_TREE_MODEL (impl->recent_model), &child_iter,
8505- RECENT_MODEL_COL_INFO, &info,
8506- RECENT_MODEL_COL_IS_FOLDER, &is_folder,
8507- -1);
8508-
8509- pixbuf = gtk_recent_info_get_icon (info, impl->icon_size);
8510-
8511- if (impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER ||
8512- impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)
8513- sensitive = is_folder;
8514- }
8515- break;
8516-
8517- case OPERATION_MODE_BROWSE:
8518- {
8519- const GtkFileInfo *info;
8520- const GtkFilePath *path;
8521-
8522- info = get_list_file_info (impl, iter);
8523-
8524- gtk_tree_model_sort_convert_iter_to_child_iter (impl->sort_model,
8525- &child_iter,
8526- iter);
8527- path = _gtk_file_system_model_get_path (impl->browse_files_model, &child_iter);
8528- if (path)
8529- {
8530- if (info)
8531- {
8532- /* FIXME: NULL GError */
8533- pixbuf = gtk_file_info_render_icon (info, GTK_WIDGET (impl),
8534- impl->icon_size, NULL);
8535- }
8536- }
8537- else
8538- {
8539- /* We are on the editable row */
8540- pixbuf = NULL;
8541- }
8542-
8543- if (info &&
8544- (impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER ||
8545- impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER))
8546- sensitive = gtk_file_info_get_is_folder (info);
8547- }
8548- break;
8549+ if (info)
8550+ {
8551+ /* FIXME: NULL GError */
8552+ pixbuf = gtk_file_info_render_icon (info, GTK_WIDGET (impl),
8553+ impl->icon_size, NULL);
8554+ }
8555 }
8556+ else
8557+ {
8558+ /* We are on the editable row */
8559+ pixbuf = NULL;
8560+ }
8561+
8562+ if (info && (impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER ||
8563+ impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER))
8564+ sensitive = gtk_file_info_get_is_folder (info);
8565
8566 g_object_set (cell,
8567 "pixbuf", pixbuf,
8568@@ -10869,85 +4641,21 @@
8569 gpointer data)
8570 {
8571 GtkFileChooserDefault *impl = data;
8572- const GtkFileInfo *info;
8573+ const GtkFileInfo *info = get_list_file_info (impl, iter);
8574 gboolean sensitive = TRUE;
8575
8576- if (impl->operation_mode == OPERATION_MODE_SEARCH)
8577- {
8578- GtkTreeIter child_iter;
8579- gchar *display_name;
8580- gboolean is_folder;
8581-
8582- search_get_valid_child_iter (impl, &child_iter, iter);
8583- gtk_tree_model_get (GTK_TREE_MODEL (impl->search_model), &child_iter,
8584- SEARCH_MODEL_COL_DISPLAY_NAME, &display_name,
8585- SEARCH_MODEL_COL_IS_FOLDER, &is_folder,
8586- -1);
8587-
8588- if (impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER ||
8589- impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)
8590- {
8591- sensitive = is_folder;
8592- }
8593-
8594- g_object_set (cell,
8595- "text", display_name,
8596- "sensitive", sensitive,
8597- "ellipsize", PANGO_ELLIPSIZE_END,
8598- NULL);
8599-
8600- return;
8601- }
8602-
8603- if (impl->operation_mode == OPERATION_MODE_RECENT)
8604- {
8605- GtkTreeIter child_iter;
8606- GtkRecentInfo *recent_info;
8607- gchar *display_name;
8608- gboolean is_folder;
8609-
8610- recent_get_valid_child_iter (impl, &child_iter, iter);
8611- gtk_tree_model_get (GTK_TREE_MODEL (impl->recent_model), &child_iter,
8612- RECENT_MODEL_COL_INFO, &recent_info,
8613- RECENT_MODEL_COL_IS_FOLDER, &is_folder,
8614- -1);
8615-
8616- display_name = gtk_recent_info_get_short_name (recent_info);
8617-
8618- if (impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER ||
8619- impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)
8620- {
8621- sensitive = is_folder;
8622- }
8623-
8624- g_object_set (cell,
8625- "text", display_name,
8626- "sensitive", sensitive,
8627- "ellipsize", PANGO_ELLIPSIZE_END,
8628- NULL);
8629-
8630- g_free (display_name);
8631-
8632- return;
8633- }
8634-
8635- info = get_list_file_info (impl, iter);
8636- sensitive = TRUE;
8637-
8638 if (!info)
8639 {
8640 g_object_set (cell,
8641 "text", _("Type name of new folder"),
8642- "sensitive", TRUE,
8643- "ellipsize", PANGO_ELLIPSIZE_NONE,
8644 NULL);
8645
8646 return;
8647 }
8648
8649
8650- if (impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER ||
8651- impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)
8652+ if (impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER
8653+ || impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)
8654 {
8655 sensitive = gtk_file_info_get_is_folder (info);
8656 }
8657@@ -10955,7 +4663,6 @@
8658 g_object_set (cell,
8659 "text", gtk_file_info_get_display_name (info),
8660 "sensitive", sensitive,
8661- "ellipsize", PANGO_ELLIPSIZE_END,
8662 NULL);
8663 }
8664
8665@@ -11017,142 +4724,64 @@
8666 gpointer data)
8667 {
8668 GtkFileChooserDefault *impl;
8669- time_t time_mtime;
8670- gchar *date_str = NULL;
8671+ const GtkFileInfo *info;
8672+ GtkFileTime time_mtime;
8673+ GDate mtime, now;
8674+ int days_diff;
8675+ char buf[256];
8676 gboolean sensitive = TRUE;
8677
8678 impl = data;
8679
8680- if (impl->operation_mode == OPERATION_MODE_SEARCH)
8681+ info = get_list_file_info (impl, iter);
8682+ if (!info)
8683 {
8684- GtkTreeIter child_iter;
8685- struct stat *statbuf;
8686- gboolean is_folder;
8687-
8688- search_get_valid_child_iter (impl, &child_iter, iter);
8689- gtk_tree_model_get (GTK_TREE_MODEL (impl->search_model), &child_iter,
8690- SEARCH_MODEL_COL_STAT, &statbuf,
8691- SEARCH_MODEL_COL_IS_FOLDER, &is_folder,
8692- -1);
8693- if (statbuf)
8694- time_mtime = statbuf->st_mtime;
8695- else
8696- time_mtime = 0;
8697-
8698-
8699- if (impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER ||
8700- impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)
8701- sensitive = is_folder;
8702+ g_object_set (cell,
8703+ "text", "",
8704+ "sensitive", TRUE,
8705+ NULL);
8706+ return;
8707 }
8708- else if (impl->operation_mode == OPERATION_MODE_RECENT)
8709- {
8710- GtkTreeIter child_iter;
8711- GtkRecentInfo *info;
8712- gboolean is_folder;
8713
8714- recent_get_valid_child_iter (impl, &child_iter, iter);
8715- gtk_tree_model_get (GTK_TREE_MODEL (impl->recent_model), &child_iter,
8716- RECENT_MODEL_COL_INFO, &info,
8717- RECENT_MODEL_COL_IS_FOLDER, &is_folder,
8718- -1);
8719+ time_mtime = gtk_file_info_get_modification_time (info);
8720
8721- if (info)
8722- time_mtime = gtk_recent_info_get_modified (info);
8723- else
8724- time_mtime = 0;
8725-
8726- if (impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER ||
8727- impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)
8728- sensitive = is_folder;
8729- }
8730+ if (time_mtime == 0)
8731+ strcpy (buf, _("Unknown"));
8732 else
8733 {
8734- const GtkFileInfo *info;
8735-
8736- info = get_list_file_info (impl, iter);
8737- if (!info)
8738- {
8739- g_object_set (cell,
8740- "text", "",
8741- "sensitive", TRUE,
8742- NULL);
8743- return;
8744- }
8745-
8746- time_mtime = (time_t) gtk_file_info_get_modification_time (info);
8747-
8748- if (impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER ||
8749- impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)
8750- sensitive = gtk_file_info_get_is_folder (info);
8751- }
8752-
8753- if (G_UNLIKELY (time_mtime == 0))
8754- date_str = g_strdup (_("Unknown"));
8755- else
8756- {
8757- GDate mtime, now;
8758- gint days_diff;
8759- struct tm tm_mtime;
8760 time_t time_now;
8761- const gchar *format;
8762- gchar *locale_format = NULL;
8763- gchar buf[256];
8764-
8765-#ifdef HAVE_LOCALTIME_R
8766- localtime_r ((time_t *) &time_mtime, &tm_mtime);
8767-#else
8768- {
8769- struct tm *ptm = localtime ((time_t *) &time_mtime);
8770-
8771- if (!ptm)
8772- {
8773- g_warning ("ptm != NULL failed");
8774-
8775- g_object_set (cell,
8776- "text", _("Unknown"),
8777- "sensitive", sensitive,
8778- NULL);
8779- return;
8780- }
8781- else
8782- memcpy ((void *) &tm_mtime, (void *) ptm, sizeof (struct tm));
8783- }
8784-#endif /* HAVE_LOCALTIME_R */
8785-
8786 g_date_set_time_t (&mtime, time_mtime);
8787 time_now = time (NULL);
8788 g_date_set_time_t (&now, time_now);
8789
8790 days_diff = g_date_get_julian (&now) - g_date_get_julian (&mtime);
8791
8792- /* Translators: %H means "hours" and %M means "minutes" */
8793 if (days_diff == 0)
8794- format = _("Today at %H:%M");
8795+ strcpy (buf, _("Today"));
8796 else if (days_diff == 1)
8797- format = _("Yesterday at %H:%M");
8798+ strcpy (buf, _("Yesterday"));
8799 else
8800 {
8801+ char *format;
8802+
8803 if (days_diff > 1 && days_diff < 7)
8804 format = "%A"; /* Days from last week */
8805 else
8806 format = "%x"; /* Any other date */
8807- }
8808
8809- locale_format = g_locale_from_utf8 (format, -1, NULL, NULL, NULL);
8810-
8811- if (strftime (buf, sizeof (buf), locale_format, &tm_mtime) != 0)
8812- date_str = g_locale_to_utf8 (buf, -1, NULL, NULL, NULL);
8813- else
8814- date_str = g_strdup (_("Unknown"));
8815-
8816- g_free (locale_format);
8817+ if (g_date_strftime (buf, sizeof (buf), format, &mtime) == 0)
8818+ strcpy (buf, _("Unknown"));
8819+ }
8820 }
8821
8822+ if (impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER ||
8823+ impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)
8824+ sensitive = gtk_file_info_get_is_folder (info);
8825+
8826 g_object_set (cell,
8827- "text", date_str,
8828+ "text", buf,
8829 "sensitive", sensitive,
8830 NULL);
8831- g_free (date_str);
8832 }
8833
8834 GtkWidget *
8835@@ -11163,437 +4792,73 @@
8836 NULL);
8837 }
8838
8839+/* Handler for the "up-folder" keybinding signal */
8840 static void
8841-location_set_user_text (GtkFileChooserDefault *impl,
8842- const gchar *path)
8843+up_folder_handler (GtkFileChooserDefault *impl)
8844 {
8845- _gtk_file_chooser_entry_set_file_part (GTK_FILE_CHOOSER_ENTRY (impl->location_entry), path);
8846- gtk_editable_set_position (GTK_EDITABLE (impl->location_entry), -1);
8847-}
8848+ GtkFilePath * parent;
8849+ pending_select_paths_add (impl, impl->current_folder);
8850
8851-static void
8852-location_popup_handler (GtkFileChooserDefault *impl,
8853- const gchar *path)
8854-{
8855- if (impl->operation_mode != OPERATION_MODE_BROWSE)
8856- {
8857- GtkWidget *widget_to_focus;
8858-
8859- /* This will give us the location widgets back */
8860- switch (impl->operation_mode)
8861- {
8862- case OPERATION_MODE_SEARCH:
8863- search_switch_to_browse_mode (impl);
8864- break;
8865- case OPERATION_MODE_RECENT:
8866- recent_switch_to_browse_mode (impl);
8867- break;
8868- case OPERATION_MODE_BROWSE:
8869- g_assert_not_reached ();
8870- break;
8871- }
8872+ if (gtk_file_system_get_parent (impl->file_system, impl->current_folder,
8873+ &parent, NULL) && parent)
8874+ {
8875+ impl->path_history = g_slist_prepend (impl->path_history,
8876+ gtk_file_path_copy (impl->current_folder));
8877
8878- if (impl->current_folder)
8879- change_folder_and_display_error (impl, impl->current_folder, FALSE);
8880-
8881- if (impl->location_mode == LOCATION_MODE_PATH_BAR)
8882- widget_to_focus = impl->browse_files_tree_view;
8883- else
8884- widget_to_focus = impl->location_entry;
8885-
8886- gtk_widget_grab_focus (widget_to_focus);
8887- return;
8888- }
8889-
8890- if (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN ||
8891- impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER)
8892- {
8893- LocationMode new_mode;
8894-
8895- if (path != NULL)
8896- {
8897- /* since the user typed something, we unconditionally want to turn on the entry */
8898- new_mode = LOCATION_MODE_FILENAME_ENTRY;
8899- }
8900- else if (impl->location_mode == LOCATION_MODE_PATH_BAR)
8901- new_mode = LOCATION_MODE_FILENAME_ENTRY;
8902- else if (impl->location_mode == LOCATION_MODE_FILENAME_ENTRY)
8903- new_mode = LOCATION_MODE_PATH_BAR;
8904- else
8905- {
8906- g_assert_not_reached ();
8907- return;
8908- }
8909-
8910- location_mode_set (impl, new_mode, TRUE);
8911- if (new_mode == LOCATION_MODE_FILENAME_ENTRY)
8912- {
8913- if (path != NULL)
8914- location_set_user_text (impl, path);
8915- else
8916- {
8917- location_entry_set_initial_text (impl);
8918- gtk_editable_select_region (GTK_EDITABLE (impl->location_entry), 0, -1);
8919- }
8920- }
8921- }
8922- else if (impl->action == GTK_FILE_CHOOSER_ACTION_SAVE ||
8923- impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)
8924- {
8925- gtk_widget_grab_focus (impl->location_entry);
8926- if (path != NULL)
8927- location_set_user_text (impl, path);
8928- }
8929- else
8930- g_assert_not_reached ();
8931+ change_folder_and_display_error (impl, parent);
8932+ gtk_file_path_free (parent);
8933+ }
8934 }
8935
8936-/* Handler for the "up-folder" keybinding signal */
8937-static void
8938-up_folder_handler (GtkFileChooserDefault *impl)
8939-{
8940- _gtk_path_bar_up (GTK_PATH_BAR (impl->browse_path_bar));
8941-}
8942-
8943 /* Handler for the "down-folder" keybinding signal */
8944 static void
8945 down_folder_handler (GtkFileChooserDefault *impl)
8946 {
8947- _gtk_path_bar_down (GTK_PATH_BAR (impl->browse_path_bar));
8948-}
8949+ if (impl->path_history)
8950+ {
8951+ GtkFilePath * path = impl->path_history->data;
8952
8953-/* Switches to the shortcut in the specified index */
8954-static void
8955-switch_to_shortcut (GtkFileChooserDefault *impl,
8956- int pos)
8957-{
8958- GtkTreeIter iter;
8959-
8960- if (!gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (impl->shortcuts_model), &iter, NULL, pos))
8961- g_assert_not_reached ();
8962-
8963- shortcuts_activate_iter (impl, &iter);
8964- focus_browse_tree_view_if_possible (impl);
8965+ change_folder_and_display_error (impl, path);
8966+ impl->path_history = g_slist_remove (impl->path_history, path);
8967+ gtk_file_path_free (path);
8968+ }
8969 }
8970
8971 /* Handler for the "home-folder" keybinding signal */
8972 static void
8973 home_folder_handler (GtkFileChooserDefault *impl)
8974 {
8975- if (impl->has_home)
8976- switch_to_shortcut (impl, shortcuts_get_index (impl, SHORTCUTS_HOME));
8977 }
8978
8979-/* Handler for the "desktop-folder" keybinding signal */
8980 static void
8981-desktop_folder_handler (GtkFileChooserDefault *impl)
8982-{
8983- if (impl->has_desktop)
8984- switch_to_shortcut (impl, shortcuts_get_index (impl, SHORTCUTS_DESKTOP));
8985-}
8986-
8987-/* Handler for the "search-shortcut" keybinding signal */
8988-static void
8989-search_shortcut_handler (GtkFileChooserDefault *impl)
8990-{
8991- if (impl->has_search)
8992- {
8993- switch_to_shortcut (impl, shortcuts_get_index (impl, SHORTCUTS_SEARCH));
8994-
8995- /* we want the entry widget to grab the focus the first
8996- * time, not the browse_files_tree_view widget.
8997- */
8998- if (impl->search_entry)
8999- gtk_widget_grab_focus (impl->search_entry);
9000- }
9001-}
9002-
9003-/* Handler for the "recent-shortcut" keybinding signal */
9004-static void
9005-recent_shortcut_handler (GtkFileChooserDefault *impl)
9006-{
9007- if (impl->has_recent)
9008- switch_to_shortcut (impl, shortcuts_get_index (impl, SHORTCUTS_RECENT));
9009-}
9010-
9011-static void
9012-quick_bookmark_handler (GtkFileChooserDefault *impl,
9013- gint bookmark_index)
9014-{
9015- int bookmark_pos;
9016- GtkTreePath *path;
9017-
9018- if (bookmark_index < 0 || bookmark_index >= impl->num_bookmarks)
9019- return;
9020-
9021- bookmark_pos = shortcuts_get_index (impl, SHORTCUTS_BOOKMARKS) + bookmark_index;
9022-
9023- path = gtk_tree_path_new_from_indices (bookmark_pos, -1);
9024- gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (impl->browse_shortcuts_tree_view),
9025- path, NULL,
9026- FALSE, 0.0, 0.0);
9027- gtk_tree_path_free (path);
9028-
9029- switch_to_shortcut (impl, bookmark_pos);
9030-}
9031-
9032-static void
9033 show_hidden_handler (GtkFileChooserDefault *impl)
9034 {
9035- g_object_set (impl,
9036- "show-hidden", !impl->show_hidden,
9037- NULL);
9038 }
9039
9040-
9041-/* Drag and drop interfaces */
9042-
9043-static void
9044-_shortcuts_pane_model_filter_class_init (ShortcutsPaneModelFilterClass *class)
9045+static GtkFilePath *
9046+gtk_file_chooser_default_get_preview_path (GtkFileChooser *chooser)
9047 {
9048+ return NULL;
9049 }
9050
9051-static void
9052-_shortcuts_pane_model_filter_init (ShortcutsPaneModelFilter *model)
9053-{
9054- model->impl = NULL;
9055-}
9056-
9057-/* GtkTreeDragSource::row_draggable implementation for the shortcuts filter model */
9058 static gboolean
9059-shortcuts_pane_model_filter_row_draggable (GtkTreeDragSource *drag_source,
9060- GtkTreePath *path)
9061+gtk_file_chooser_default_add_shortcut_folder (GtkFileChooser *chooser,
9062+ const GtkFilePath *path,
9063+ GError **error)
9064 {
9065- ShortcutsPaneModelFilter *model;
9066- int pos;
9067- int bookmarks_pos;
9068-
9069- model = SHORTCUTS_PANE_MODEL_FILTER (drag_source);
9070-
9071- pos = *gtk_tree_path_get_indices (path);
9072- bookmarks_pos = shortcuts_get_index (model->impl, SHORTCUTS_BOOKMARKS);
9073-
9074- return (pos >= bookmarks_pos && pos < bookmarks_pos + model->impl->num_bookmarks);
9075-}
9076-
9077-/* GtkTreeDragSource::drag_data_get implementation for the shortcuts filter model */
9078-static gboolean
9079-shortcuts_pane_model_filter_drag_data_get (GtkTreeDragSource *drag_source,
9080- GtkTreePath *path,
9081- GtkSelectionData *selection_data)
9082-{
9083- ShortcutsPaneModelFilter *model;
9084-
9085- model = SHORTCUTS_PANE_MODEL_FILTER (drag_source);
9086-
9087- /* FIXME */
9088-
9089- return FALSE;
9090-}
9091-
9092-/* Fill the GtkTreeDragSourceIface vtable */
9093-static void
9094-shortcuts_pane_model_filter_drag_source_iface_init (GtkTreeDragSourceIface *iface)
9095-{
9096- iface->row_draggable = shortcuts_pane_model_filter_row_draggable;
9097- iface->drag_data_get = shortcuts_pane_model_filter_drag_data_get;
9098-}
9099-
9100-#if 0
9101-/* Fill the GtkTreeDragDestIface vtable */
9102-static void
9103-shortcuts_pane_model_filter_drag_dest_iface_init (GtkTreeDragDestIface *iface)
9104-{
9105- iface->drag_data_received = shortcuts_pane_model_filter_drag_data_received;
9106- iface->row_drop_possible = shortcuts_pane_model_filter_row_drop_possible;
9107-}
9108-#endif
9109-
9110-static GtkTreeModel *
9111-shortcuts_pane_model_filter_new (GtkFileChooserDefault *impl,
9112- GtkTreeModel *child_model,
9113- GtkTreePath *root)
9114-{
9115- ShortcutsPaneModelFilter *model;
9116-
9117- model = g_object_new (SHORTCUTS_PANE_MODEL_FILTER_TYPE,
9118- "child-model", child_model,
9119- "virtual-root", root,
9120- NULL);
9121-
9122- model->impl = impl;
9123-
9124- return GTK_TREE_MODEL (model);
9125-}
9126-
9127-
9128-
9129-static gboolean
9130-recent_model_sort_row_draggable (GtkTreeDragSource *drag_source,
9131- GtkTreePath *path)
9132-{
9133- RecentModelSort *model;
9134- GtkTreeIter iter, child_iter;
9135- gboolean is_folder;
9136-
9137- model = RECENT_MODEL_SORT (drag_source);
9138- if (!gtk_tree_model_get_iter (GTK_TREE_MODEL (model), &iter, path))
9139 return FALSE;
9140-
9141- recent_get_valid_child_iter (model->impl, &child_iter, &iter);
9142- gtk_tree_model_get (GTK_TREE_MODEL (model->impl->recent_model), &child_iter,
9143- RECENT_MODEL_COL_IS_FOLDER, &is_folder,
9144- -1);
9145-
9146- return is_folder;
9147 }
9148
9149 static gboolean
9150-recent_model_sort_drag_data_get (GtkTreeDragSource *drag_source,
9151- GtkTreePath *path,
9152- GtkSelectionData *selection_data)
9153+gtk_file_chooser_default_remove_shortcut_folder (GtkFileChooser *chooser,
9154+ const GtkFilePath *path,
9155+ GError **error)
9156 {
9157- RecentModelSort *model;
9158- GtkTreeIter iter, child_iter;
9159- GtkFilePath *file_path;
9160- gchar **uris;
9161-
9162- model = RECENT_MODEL_SORT (drag_source);
9163- if (!gtk_tree_model_get_iter (GTK_TREE_MODEL (model), &iter, path))
9164- return FALSE;
9165-
9166- recent_get_valid_child_iter (model->impl, &child_iter, &iter);
9167- gtk_tree_model_get (GTK_TREE_MODEL (model->impl->recent_model), &child_iter,
9168- RECENT_MODEL_COL_PATH, &file_path,
9169- -1);
9170- g_assert (file_path != NULL);
9171-
9172- uris = g_new (gchar *, 2);
9173- uris[0] = gtk_file_system_path_to_uri (model->impl->file_system, file_path);
9174- uris[1] = NULL;
9175-
9176- gtk_selection_data_set_uris (selection_data, uris);
9177-
9178- g_strfreev (uris);
9179-
9180- return TRUE;
9181+ return TRUE;
9182 }
9183
9184-static void
9185-recent_model_sort_drag_source_iface_init (GtkTreeDragSourceIface *iface)
9186+static GSList *
9187+gtk_file_chooser_default_list_shortcut_folders (GtkFileChooser *chooser)
9188 {
9189- iface->row_draggable = recent_model_sort_row_draggable;
9190- iface->drag_data_get = recent_model_sort_drag_data_get;
9191+ return NULL;
9192 }
9193-
9194-static void
9195-_recent_model_sort_class_init (RecentModelSortClass *klass)
9196-{
9197-
9198-}
9199-
9200-static void
9201-_recent_model_sort_init (RecentModelSort *model)
9202-{
9203- model->impl = NULL;
9204-}
9205-
9206-static GtkTreeModel *
9207-recent_model_sort_new (GtkFileChooserDefault *impl,
9208- GtkTreeModel *child_model)
9209-{
9210- RecentModelSort *model;
9211-
9212- model = g_object_new (RECENT_MODEL_SORT_TYPE,
9213- "model", child_model,
9214- NULL);
9215- model->impl = impl;
9216-
9217- return GTK_TREE_MODEL (model);
9218-}
9219-
9220-
9221-
9222-static gboolean
9223-search_model_sort_row_draggable (GtkTreeDragSource *drag_source,
9224- GtkTreePath *path)
9225-{
9226- SearchModelSort *model;
9227- GtkTreeIter iter, child_iter;
9228- gboolean is_folder;
9229-
9230- model = SEARCH_MODEL_SORT (drag_source);
9231- if (!gtk_tree_model_get_iter (GTK_TREE_MODEL (model), &iter, path))
9232- return FALSE;
9233-
9234- search_get_valid_child_iter (model->impl, &child_iter, &iter);
9235- gtk_tree_model_get (GTK_TREE_MODEL (model->impl->search_model), &child_iter,
9236- SEARCH_MODEL_COL_IS_FOLDER, &is_folder,
9237- -1);
9238-
9239- return is_folder;
9240-}
9241-
9242-static gboolean
9243-search_model_sort_drag_data_get (GtkTreeDragSource *drag_source,
9244- GtkTreePath *path,
9245- GtkSelectionData *selection_data)
9246-{
9247- SearchModelSort *model;
9248- GtkTreeIter iter, child_iter;
9249- GtkFilePath *file_path;
9250- gchar **uris;
9251-
9252- model = SEARCH_MODEL_SORT (drag_source);
9253- if (!gtk_tree_model_get_iter (GTK_TREE_MODEL (model), &iter, path))
9254- return FALSE;
9255-
9256- search_get_valid_child_iter (model->impl, &child_iter, &iter);
9257- gtk_tree_model_get (GTK_TREE_MODEL (model->impl->search_model), &child_iter,
9258- RECENT_MODEL_COL_PATH, &file_path,
9259- -1);
9260- g_assert (file_path != NULL);
9261-
9262- uris = g_new (gchar *, 2);
9263- uris[0] = gtk_file_system_path_to_uri (model->impl->file_system, file_path);
9264- uris[1] = NULL;
9265-
9266- gtk_selection_data_set_uris (selection_data, uris);
9267-
9268- g_strfreev (uris);
9269-
9270- return TRUE;
9271-}
9272-
9273-static void
9274-search_model_sort_drag_source_iface_init (GtkTreeDragSourceIface *iface)
9275-{
9276- iface->row_draggable = search_model_sort_row_draggable;
9277- iface->drag_data_get = search_model_sort_drag_data_get;
9278-}
9279-
9280-static void
9281-_search_model_sort_class_init (SearchModelSortClass *klass)
9282-{
9283-
9284-}
9285-
9286-static void
9287-_search_model_sort_init (SearchModelSort *model)
9288-{
9289- model->impl = NULL;
9290-}
9291-
9292-static GtkTreeModel *
9293-search_model_sort_new (GtkFileChooserDefault *impl,
9294- GtkTreeModel *child_model)
9295-{
9296- SearchModelSort *model;
9297-
9298- model = g_object_new (SEARCH_MODEL_SORT_TYPE,
9299- "model", child_model,
9300- NULL);
9301- model->impl = impl;
9302-
9303- return GTK_TREE_MODEL (model);
9304-}
9305Index: gtk+-2.12.5/gtk/gtkfilechooserprivate.h
9306===================================================================
9307--- gtk+-2.12.5/gtk/gtkfilechooserprivate.h (revision 19337)
9308+++ gtk+-2.12.5/gtk/gtkfilechooserprivate.h (working copy)
9309@@ -25,9 +25,6 @@
9310 #include "gtkfilesystem.h"
9311 #include "gtkfilesystemmodel.h"
9312 #include "gtkliststore.h"
9313-#include "gtkrecentmanager.h"
9314-#include "gtksearchengine.h"
9315-#include "gtkquery.h"
9316 #include "gtktooltips.h"
9317 #include "gtktreemodelsort.h"
9318 #include "gtktreestore.h"
9319@@ -146,12 +143,6 @@
9320 LOCATION_MODE_FILENAME_ENTRY
9321 } LocationMode;
9322
9323-typedef enum {
9324- OPERATION_MODE_BROWSE,
9325- OPERATION_MODE_SEARCH,
9326- OPERATION_MODE_RECENT
9327-} OperationMode;
9328-
9329 struct _GtkFileChooserDefault
9330 {
9331 GtkVBox parent_instance;
9332@@ -162,53 +153,19 @@
9333
9334 /* Save mode widgets */
9335 GtkWidget *save_widgets;
9336+ GtkWidget *save_file_name_entry;
9337
9338- GtkWidget *save_folder_label;
9339- GtkWidget *save_folder_combo;
9340- GtkWidget *save_expander;
9341-
9342 /* The file browsing widgets */
9343 GtkWidget *browse_widgets;
9344- GtkWidget *browse_shortcuts_tree_view;
9345- GtkWidget *browse_shortcuts_add_button;
9346- GtkWidget *browse_shortcuts_remove_button;
9347- GtkWidget *browse_shortcuts_popup_menu;
9348- GtkWidget *browse_shortcuts_popup_menu_remove_item;
9349- GtkWidget *browse_shortcuts_popup_menu_rename_item;
9350 GtkWidget *browse_files_tree_view;
9351- GtkWidget *browse_files_popup_menu;
9352- GtkWidget *browse_files_popup_menu_add_shortcut_item;
9353- GtkWidget *browse_files_popup_menu_hidden_files_item;
9354 GtkWidget *browse_new_folder_button;
9355- GtkWidget *browse_path_bar_hbox;
9356- GtkWidget *browse_path_bar;
9357+ GtkWidget *bar;
9358+ GtkWidget *up_button;
9359
9360 GtkFileSystemModel *browse_files_model;
9361- char *browse_files_last_selected_name;
9362+ char *browse_files_last_selected_name; /* ??? */
9363
9364- /* OPERATION_MODE_SEARCH */
9365- GtkWidget *search_hbox;
9366- GtkWidget *search_entry;
9367- GtkSearchEngine *search_engine;
9368- GtkQuery *search_query;
9369- GtkListStore *search_model;
9370- GtkTreeModelFilter *search_model_filter;
9371- GtkTreeModelSort *search_model_sort;
9372-
9373- /* OPERATION_MODE_RECENT */
9374- GtkRecentManager *recent_manager;
9375- GtkListStore *recent_model;
9376- guint load_recent_id;
9377- GtkTreeModelFilter *recent_model_filter;
9378- GtkTreeModelSort *recent_model_sort;
9379-
9380- GtkWidget *filter_combo_hbox;
9381 GtkWidget *filter_combo;
9382- GtkWidget *preview_box;
9383- GtkWidget *preview_label;
9384- GtkWidget *preview_widget;
9385- GtkWidget *extra_align;
9386- GtkWidget *extra_widget;
9387
9388 GtkWidget *location_button;
9389 GtkWidget *location_entry_box;
9390@@ -217,23 +174,13 @@
9391 LocationMode location_mode;
9392
9393 GtkListStore *shortcuts_model;
9394+ GtkTreeModel *shortcuts_filter_model;
9395
9396- /* Filter for the shortcuts pane. We filter out the "current folder" row and
9397- * the separator that we use for the "Save in folder" combo.
9398- */
9399- GtkTreeModel *shortcuts_pane_filter_model;
9400-
9401- /* Filter for the "Save in folder" combo. We filter out the Search row and
9402- * its separator.
9403- */
9404- GtkTreeModel *shortcuts_combo_filter_model;
9405-
9406 GtkTreeModelSort *sort_model;
9407
9408 /* Handles */
9409 GSList *loading_shortcuts;
9410 GSList *reload_icon_handles;
9411- GtkFileSystemHandle *file_list_drag_data_received_handle;
9412 GtkFileSystemHandle *update_current_folder_handle;
9413 GtkFileSystemHandle *show_and_select_paths_handle;
9414 GtkFileSystemHandle *should_respond_get_info_handle;
9415@@ -246,9 +193,8 @@
9416 ReloadState reload_state;
9417 guint load_timeout_id;
9418
9419- OperationMode operation_mode;
9420-
9421 GSList *pending_select_paths;
9422+ GSList *path_history;
9423
9424 GtkFileFilter *current_filter;
9425 GSList *filters;
9426@@ -256,20 +202,16 @@
9427 GtkTooltips *tooltips;
9428
9429 int num_volumes;
9430- int num_shortcuts;
9431- int num_bookmarks;
9432
9433 gulong volumes_changed_id;
9434- gulong bookmarks_changed_id;
9435
9436 GtkFilePath *current_volume_path;
9437 GtkFilePath *current_folder;
9438- GtkFilePath *preview_path;
9439- char *preview_display_name;
9440
9441 GtkTreeViewColumn *list_name_column;
9442 GtkCellRenderer *list_name_renderer;
9443- GtkTreeViewColumn *list_mtime_column;
9444+ guint32 list_press_time;
9445+ GtkTreePath *list_press_path;
9446
9447 GSource *edited_idle;
9448 char *edited_new_text;
9449@@ -280,10 +222,7 @@
9450 gulong toplevel_set_focus_id;
9451 GtkWidget *toplevel_last_focus_widget;
9452
9453-#if 0
9454- GdkDragContext *shortcuts_drag_context;
9455- GSource *shortcuts_drag_outside_idle;
9456-#endif
9457+ gchar * root_folder;
9458
9459 gint default_width;
9460 gint default_height;
9461@@ -291,23 +230,13 @@
9462 /* Flags */
9463
9464 guint local_only : 1;
9465- guint preview_widget_active : 1;
9466- guint use_preview_label : 1;
9467 guint select_multiple : 1;
9468 guint show_hidden : 1;
9469+ guint show_create_folder : 1;
9470 guint do_overwrite_confirmation : 1;
9471 guint list_sort_ascending : 1;
9472 guint changing_folder : 1;
9473- guint shortcuts_current_folder_active : 1;
9474 guint expand_folders : 1;
9475- guint has_home : 1;
9476- guint has_desktop : 1;
9477- guint has_search : 1;
9478- guint has_recent : 1;
9479-
9480-#if 0
9481- guint shortcuts_drag_outside : 1;
9482-#endif
9483 };
9484
9485
9486Index: gtk+-2.12.5/tests/autotestfilechooser.c
9487===================================================================
9488--- gtk+-2.12.5/tests/autotestfilechooser.c (revision 19337)
9489+++ gtk+-2.12.5/tests/autotestfilechooser.c (working copy)
9490@@ -510,9 +510,6 @@
9491 && (impl->location_mode == LOCATION_MODE_PATH_BAR
9492 ? impl->location_entry == NULL
9493 : impl->location_entry != NULL)
9494- && impl->save_folder_label == NULL
9495- && impl->save_folder_combo == NULL
9496- && impl->save_expander == NULL
9497 && GTK_IS_CONTAINER (impl->browse_widgets) && GTK_WIDGET_DRAWABLE (impl->browse_widgets));
9498 }
9499 else if (has_action (save_actions, G_N_ELEMENTS (save_actions), impl->action))
9500@@ -523,9 +520,6 @@
9501 */
9502 passed = passed && (GTK_IS_CONTAINER (impl->save_widgets) && GTK_WIDGET_DRAWABLE (impl->save_widgets)
9503 && impl->location_entry != NULL && GTK_WIDGET_DRAWABLE (impl->location_entry)
9504- && GTK_IS_LABEL (impl->save_folder_label) && GTK_WIDGET_DRAWABLE (impl->save_folder_label)
9505- && GTK_IS_COMBO_BOX (impl->save_folder_combo) && GTK_WIDGET_DRAWABLE (impl->save_folder_combo)
9506- && GTK_IS_EXPANDER (impl->save_expander) && GTK_WIDGET_DRAWABLE (impl->save_expander)
9507 && GTK_IS_CONTAINER (impl->browse_widgets));
9508
9509 /* FIXME: we are in a SAVE mode; test the visibility and sensitivity of
9510@@ -1026,11 +1020,6 @@
9511 gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), base_dir);
9512 sleep_in_main_loop (500);
9513
9514- g_signal_emit_by_name (impl->browse_path_bar, "path-clicked",
9515- (GtkFilePath *) cwd_path,
9516- (GtkFilePath *) base_dir_path,
9517- FALSE);
9518- sleep_in_main_loop (500);
9519 passed = passed && (gtk_file_chooser_get_filter (GTK_FILE_CHOOSER (dialog)) == txt_filter);
9520
9521 log_test (passed, "test_folder_switch_and_filters(): filter after changing folder");