summaryrefslogtreecommitdiffstats
path: root/meta/recipes-gnome/gtk+/gtk+-2.12.7/filechooser-default.patch
diff options
context:
space:
mode:
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");