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