~ubuntu-branches/ubuntu/oneiric/nautilus/oneiric-updates

« back to all changes in this revision

Viewing changes to .pc/12_remove_create_launcher_on_desktop.patch/src/nautilus-view.c

  • Committer: Bazaar Package Importer
  • Author(s): Didier Roche
  • Date: 2011-07-25 11:44:24 UTC
  • Revision ID: james.westby@ubuntu.com-20110725114424-thpvep0hbdv8d4kj
Tags: 1:3.1.3-0ubuntu3
* debian/patches/12_remove_create_launcher_on_desktop.patch:
  - remove the "create launcher" entry from desktop right-click. It's depending
    on a gnome-panel binary, confusing the user when unity is running and
    default upstream sessions don't have even nautilus drawing the icons on
    the desktop. Do the same for other places as well. (LP: #723861)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
 
2
 
 
3
/* nautilus-view.c
 
4
 *
 
5
 * Copyright (C) 1999, 2000  Free Software Foundation
 
6
 * Copyright (C) 2000, 2001  Eazel, Inc.
 
7
 *
 
8
 * This program is free software; you can redistribute it and/or
 
9
 * modify it under the terms of the GNU General Public License as
 
10
 * published by the Free Software Foundation; either version 2 of the
 
11
 * License, or (at your option) any later version.
 
12
 *
 
13
 * This program is distributed in the hope that it will be useful,
 
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
16
 * General Public License for more details.
 
17
 *
 
18
 * You should have received a copy of the GNU General Public
 
19
 * License along with this program; if not, write to the
 
20
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 
21
 * Boston, MA 02111-1307, USA.
 
22
 *
 
23
 * Authors: Ettore Perazzoli,
 
24
 *          John Sullivan <sullivan@eazel.com>,
 
25
 *          Darin Adler <darin@bentspoon.com>,
 
26
 *          Pavel Cisler <pavel@eazel.com>,
 
27
 *          David Emory Watson <dwatson@cs.ucr.edu>
 
28
 */
 
29
 
 
30
#include <config.h>
 
31
 
 
32
#include "nautilus-view.h"
 
33
 
 
34
#include "nautilus-actions.h"
 
35
#include "nautilus-desktop-icon-view.h"
 
36
#include "nautilus-error-reporting.h"
 
37
#include "nautilus-list-view.h"
 
38
#include "nautilus-mime-actions.h"
 
39
#include "nautilus-previewer.h"
 
40
#include "nautilus-properties-window.h"
 
41
 
 
42
#include <gdk/gdkx.h>
 
43
#include <gdk/gdkkeysyms.h>
 
44
#include <gtk/gtk.h>
 
45
#include <glib/gi18n.h>
 
46
#include <glib/gstdio.h>
 
47
#include <gio/gio.h>
 
48
#include <math.h>
 
49
 
 
50
#include <eel/eel-glib-extensions.h>
 
51
#include <eel/eel-gnome-extensions.h>
 
52
#include <eel/eel-gtk-extensions.h>
 
53
#include <eel/eel-gtk-macros.h>
 
54
#include <eel/eel-stock-dialogs.h>
 
55
#include <eel/eel-string.h>
 
56
#include <eel/eel-vfs-extensions.h>
 
57
 
 
58
#include <libnautilus-extension/nautilus-menu-provider.h>
 
59
#include <libnautilus-private/nautilus-clipboard.h>
 
60
#include <libnautilus-private/nautilus-clipboard-monitor.h>
 
61
#include <libnautilus-private/nautilus-desktop-icon-file.h>
 
62
#include <libnautilus-private/nautilus-desktop-directory.h>
 
63
#include <libnautilus-private/nautilus-search-directory.h>
 
64
#include <libnautilus-private/nautilus-directory.h>
 
65
#include <libnautilus-private/nautilus-dnd.h>
 
66
#include <libnautilus-private/nautilus-file-attributes.h>
 
67
#include <libnautilus-private/nautilus-file-changes-queue.h>
 
68
#include <libnautilus-private/nautilus-file-dnd.h>
 
69
#include <libnautilus-private/nautilus-file-operations.h>
 
70
#include <libnautilus-private/nautilus-file-utilities.h>
 
71
#include <libnautilus-private/nautilus-file-private.h>
 
72
#include <libnautilus-private/nautilus-global-preferences.h>
 
73
#include <libnautilus-private/nautilus-link.h>
 
74
#include <libnautilus-private/nautilus-metadata.h>
 
75
#include <libnautilus-private/nautilus-recent.h>
 
76
#include <libnautilus-private/nautilus-module.h>
 
77
#include <libnautilus-private/nautilus-program-choosing.h>
 
78
#include <libnautilus-private/nautilus-trash-monitor.h>
 
79
#include <libnautilus-private/nautilus-ui-utilities.h>
 
80
#include <libnautilus-private/nautilus-signaller.h>
 
81
#include <libnautilus-private/nautilus-icon-names.h>
 
82
 
 
83
#define DEBUG_FLAG NAUTILUS_DEBUG_DIRECTORY_VIEW
 
84
#include <libnautilus-private/nautilus-debug.h>
 
85
 
 
86
/* Minimum starting update inverval */
 
87
#define UPDATE_INTERVAL_MIN 100
 
88
/* Maximum update interval */
 
89
#define UPDATE_INTERVAL_MAX 2000
 
90
/* Amount of miliseconds the update interval is increased */
 
91
#define UPDATE_INTERVAL_INC 250
 
92
/* Interval at which the update interval is increased */
 
93
#define UPDATE_INTERVAL_TIMEOUT_INTERVAL 250
 
94
/* Milliseconds that have to pass without a change to reset the update interval */
 
95
#define UPDATE_INTERVAL_RESET 1000
 
96
 
 
97
#define SILENT_WINDOW_OPEN_LIMIT 5
 
98
 
 
99
#define DUPLICATE_HORIZONTAL_ICON_OFFSET 70
 
100
#define DUPLICATE_VERTICAL_ICON_OFFSET   30
 
101
 
 
102
#define MAX_QUEUED_UPDATES 500
 
103
 
 
104
#define NAUTILUS_VIEW_MENU_PATH_APPLICATIONS_SUBMENU_PLACEHOLDER  "/MenuBar/File/Open Placeholder/Open With/Applications Placeholder"
 
105
#define NAUTILUS_VIEW_MENU_PATH_APPLICATIONS_PLACEHOLDER          "/MenuBar/File/Open Placeholder/Applications Placeholder"
 
106
#define NAUTILUS_VIEW_MENU_PATH_SCRIPTS_PLACEHOLDER               "/MenuBar/File/Open Placeholder/Scripts/Scripts Placeholder"
 
107
#define NAUTILUS_VIEW_MENU_PATH_EXTENSION_ACTIONS_PLACEHOLDER     "/MenuBar/Edit/Extension Actions"
 
108
#define NAUTILUS_VIEW_MENU_PATH_NEW_DOCUMENTS_PLACEHOLDER         "/MenuBar/File/New Items Placeholder/New Documents/New Documents Placeholder"
 
109
#define NAUTILUS_VIEW_MENU_PATH_OPEN                              "/MenuBar/File/Open Placeholder/Open"
 
110
 
 
111
#define NAUTILUS_VIEW_POPUP_PATH_SELECTION                        "/selection"
 
112
#define NAUTILUS_VIEW_POPUP_PATH_APPLICATIONS_SUBMENU_PLACEHOLDER "/selection/Open Placeholder/Open With/Applications Placeholder"
 
113
#define NAUTILUS_VIEW_POPUP_PATH_APPLICATIONS_PLACEHOLDER         "/selection/Open Placeholder/Applications Placeholder"
 
114
#define NAUTILUS_VIEW_POPUP_PATH_SCRIPTS_PLACEHOLDER              "/selection/Open Placeholder/Scripts/Scripts Placeholder"
 
115
#define NAUTILUS_VIEW_POPUP_PATH_EXTENSION_ACTIONS                "/selection/Extension Actions"
 
116
#define NAUTILUS_VIEW_POPUP_PATH_OPEN                             "/selection/Open Placeholder/Open"
 
117
 
 
118
#define NAUTILUS_VIEW_POPUP_PATH_BACKGROUND                       "/background"
 
119
#define NAUTILUS_VIEW_POPUP_PATH_BACKGROUND_SCRIPTS_PLACEHOLDER   "/background/Before Zoom Items/New Object Items/Scripts/Scripts Placeholder"
 
120
#define NAUTILUS_VIEW_POPUP_PATH_BACKGROUND_NEW_DOCUMENTS_PLACEHOLDER "/background/Before Zoom Items/New Object Items/New Documents/New Documents Placeholder"
 
121
 
 
122
#define NAUTILUS_VIEW_POPUP_PATH_LOCATION                         "/location"
 
123
 
 
124
#define MAX_MENU_LEVELS 5
 
125
#define TEMPLATE_LIMIT 30
 
126
 
 
127
enum {
 
128
        ADD_FILE,
 
129
        BEGIN_FILE_CHANGES,
 
130
        BEGIN_LOADING,
 
131
        CLEAR,
 
132
        END_FILE_CHANGES,
 
133
        END_LOADING,
 
134
        FILE_CHANGED,
 
135
        LOAD_ERROR,
 
136
        MOVE_COPY_ITEMS,
 
137
        REMOVE_FILE,
 
138
        ZOOM_LEVEL_CHANGED,
 
139
        SELECTION_CHANGED,
 
140
        TRASH,
 
141
        DELETE,
 
142
        LAST_SIGNAL
 
143
};
 
144
 
 
145
enum {
 
146
        PROP_WINDOW_SLOT = 1,
 
147
        PROP_SUPPORTS_ZOOMING,
 
148
        NUM_PROPERTIES
 
149
};
 
150
 
 
151
static guint signals[LAST_SIGNAL];
 
152
static GParamSpec *properties[NUM_PROPERTIES] = { NULL, };
 
153
 
 
154
static GdkAtom copied_files_atom;
 
155
 
 
156
static char *scripts_directory_uri = NULL;
 
157
static int scripts_directory_uri_length;
 
158
 
 
159
struct NautilusViewDetails
 
160
{
 
161
        NautilusWindow *window;
 
162
        NautilusWindowSlot *slot;
 
163
        NautilusDirectory *model;
 
164
        NautilusFile *directory_as_file;
 
165
        NautilusFile *location_popup_directory_as_file;
 
166
        GdkEventButton *location_popup_event;
 
167
        GtkActionGroup *dir_action_group;
 
168
        guint dir_merge_id;
 
169
 
 
170
        gboolean supports_zooming;
 
171
 
 
172
        GList *scripts_directory_list;
 
173
        GtkActionGroup *scripts_action_group;
 
174
        guint scripts_merge_id;
 
175
        
 
176
        GList *templates_directory_list;
 
177
        GtkActionGroup *templates_action_group;
 
178
        guint templates_merge_id;
 
179
 
 
180
        GtkActionGroup *extensions_menu_action_group;
 
181
        guint extensions_menu_merge_id;
 
182
        
 
183
        guint display_selection_idle_id;
 
184
        guint update_menus_timeout_id;
 
185
        guint update_status_idle_id;
 
186
        guint reveal_selection_idle_id;
 
187
 
 
188
        guint display_pending_source_id;
 
189
        guint changes_timeout_id;
 
190
 
 
191
        guint update_interval;
 
192
        guint64 last_queued;
 
193
        
 
194
        guint files_added_handler_id;
 
195
        guint files_changed_handler_id;
 
196
        guint load_error_handler_id;
 
197
        guint done_loading_handler_id;
 
198
        guint file_changed_handler_id;
 
199
 
 
200
        guint delayed_rename_file_id;
 
201
 
 
202
        GList *new_added_files;
 
203
        GList *new_changed_files;
 
204
 
 
205
        GHashTable *non_ready_files;
 
206
 
 
207
        GList *old_added_files;
 
208
        GList *old_changed_files;
 
209
 
 
210
        GList *pending_selection;
 
211
 
 
212
        /* whether we are in the active slot */
 
213
        gboolean active;
 
214
 
 
215
        /* loading indicates whether this view has begun loading a directory.
 
216
         * This flag should need not be set inside subclasses. NautilusView automatically
 
217
         * sets 'loading' to TRUE before it begins loading a directory's contents and to FALSE
 
218
         * after it finishes loading the directory and its view.
 
219
         */
 
220
        gboolean loading;
 
221
        gboolean menu_states_untrustworthy;
 
222
        gboolean scripts_invalid;
 
223
        gboolean templates_invalid;
 
224
        gboolean reported_load_error;
 
225
 
 
226
        /* flag to indicate that no file updates should be dispatched to subclasses.
 
227
         * This is a workaround for bug #87701 that prevents the list view from
 
228
         * losing focus when the underlying GtkTreeView is updated.
 
229
         */
 
230
        gboolean updates_frozen;
 
231
        guint    updates_queued;
 
232
        gboolean needs_reload;
 
233
 
 
234
        gboolean sort_directories_first;
 
235
 
 
236
        gboolean show_foreign_files;
 
237
        gboolean show_hidden_files;
 
238
        gboolean ignore_hidden_file_preferences;
 
239
 
 
240
        gboolean batching_selection_level;
 
241
        gboolean selection_changed_while_batched;
 
242
 
 
243
        gboolean selection_was_removed;
 
244
 
 
245
        gboolean metadata_for_directory_as_file_pending;
 
246
        gboolean metadata_for_files_in_directory_pending;
 
247
 
 
248
        gboolean selection_change_is_due_to_shell;
 
249
        gboolean send_selection_change_to_shell;
 
250
 
 
251
        GtkActionGroup *open_with_action_group;
 
252
        guint open_with_merge_id;
 
253
 
 
254
        GList *subdirectory_list;
 
255
 
 
256
        GdkPoint context_menu_position;
 
257
};
 
258
 
 
259
typedef struct {
 
260
        NautilusFile *file;
 
261
        NautilusDirectory *directory;
 
262
} FileAndDirectory;
 
263
 
 
264
/* forward declarations */
 
265
 
 
266
static gboolean display_selection_info_idle_callback           (gpointer              data);
 
267
static void     nautilus_view_duplicate_selection              (NautilusView      *view,
 
268
                                                                GList                *files,
 
269
                                                                GArray               *item_locations);
 
270
static void     nautilus_view_create_links_for_files           (NautilusView      *view,
 
271
                                                                GList                *files,
 
272
                                                                GArray               *item_locations);
 
273
static void     trash_or_delete_files                          (GtkWindow            *parent_window,
 
274
                                                                const GList          *files,
 
275
                                                                gboolean              delete_if_all_already_in_trash,
 
276
                                                                NautilusView      *view);
 
277
static void     load_directory                                 (NautilusView      *view,
 
278
                                                                NautilusDirectory    *directory);
 
279
static void     nautilus_view_merge_menus                      (NautilusView      *view);
 
280
static void     nautilus_view_unmerge_menus                    (NautilusView      *view);
 
281
static void     nautilus_view_init_show_hidden_files           (NautilusView      *view);
 
282
static void     clipboard_changed_callback                     (NautilusClipboardMonitor *monitor,
 
283
                                                                NautilusView      *view);
 
284
static void     open_one_in_new_window                         (gpointer              data,
 
285
                                                                gpointer              callback_data);
 
286
static void     schedule_update_menus                          (NautilusView      *view);
 
287
static void     schedule_update_menus_callback                 (gpointer              callback_data);
 
288
static void     remove_update_menus_timeout_callback           (NautilusView      *view);
 
289
static void     schedule_update_status                          (NautilusView      *view);
 
290
static void     remove_update_status_idle_callback             (NautilusView *view); 
 
291
static void     reset_update_interval                          (NautilusView      *view);
 
292
static void     schedule_idle_display_of_pending_files         (NautilusView      *view);
 
293
static void     unschedule_display_of_pending_files            (NautilusView      *view);
 
294
static void     disconnect_model_handlers                      (NautilusView      *view);
 
295
static void     metadata_for_directory_as_file_ready_callback  (NautilusFile         *file,
 
296
                                                                gpointer              callback_data);
 
297
static void     metadata_for_files_in_directory_ready_callback (NautilusDirectory    *directory,
 
298
                                                                GList                *files,
 
299
                                                                gpointer              callback_data);
 
300
static void     nautilus_view_trash_state_changed_callback     (NautilusTrashMonitor *trash,
 
301
                                                                gboolean              state,
 
302
                                                                gpointer              callback_data);
 
303
static void     nautilus_view_select_file                      (NautilusView      *view,
 
304
                                                                NautilusFile         *file);
 
305
 
 
306
static void     update_templates_directory                     (NautilusView *view);
 
307
static void     user_dirs_changed                              (NautilusView *view);
 
308
 
 
309
static gboolean file_list_all_are_folders                      (GList *file_list);
 
310
 
 
311
static void unschedule_pop_up_location_context_menu (NautilusView *view);
 
312
 
 
313
G_DEFINE_TYPE (NautilusView, nautilus_view, GTK_TYPE_SCROLLED_WINDOW);
 
314
#define parent_class nautilus_view_parent_class
 
315
 
 
316
EEL_IMPLEMENT_MUST_OVERRIDE_SIGNAL (nautilus_view, add_file)
 
317
EEL_IMPLEMENT_MUST_OVERRIDE_SIGNAL (nautilus_view, bump_zoom_level)
 
318
EEL_IMPLEMENT_MUST_OVERRIDE_SIGNAL (nautilus_view, can_zoom_in)
 
319
EEL_IMPLEMENT_MUST_OVERRIDE_SIGNAL (nautilus_view, can_zoom_out)
 
320
EEL_IMPLEMENT_MUST_OVERRIDE_SIGNAL (nautilus_view, clear)
 
321
EEL_IMPLEMENT_MUST_OVERRIDE_SIGNAL (nautilus_view, file_changed)
 
322
EEL_IMPLEMENT_MUST_OVERRIDE_SIGNAL (nautilus_view, get_selection)
 
323
EEL_IMPLEMENT_MUST_OVERRIDE_SIGNAL (nautilus_view, get_selection_for_file_transfer)
 
324
EEL_IMPLEMENT_MUST_OVERRIDE_SIGNAL (nautilus_view, get_item_count)
 
325
EEL_IMPLEMENT_MUST_OVERRIDE_SIGNAL (nautilus_view, is_empty)
 
326
EEL_IMPLEMENT_MUST_OVERRIDE_SIGNAL (nautilus_view, reset_to_defaults)
 
327
EEL_IMPLEMENT_MUST_OVERRIDE_SIGNAL (nautilus_view, restore_default_zoom_level)
 
328
EEL_IMPLEMENT_MUST_OVERRIDE_SIGNAL (nautilus_view, select_all)
 
329
EEL_IMPLEMENT_MUST_OVERRIDE_SIGNAL (nautilus_view, set_selection)
 
330
EEL_IMPLEMENT_MUST_OVERRIDE_SIGNAL (nautilus_view, zoom_to_level)
 
331
EEL_IMPLEMENT_MUST_OVERRIDE_SIGNAL (nautilus_view, get_zoom_level)
 
332
EEL_IMPLEMENT_MUST_OVERRIDE_SIGNAL (nautilus_view, invert_selection)
 
333
 
 
334
/* virtual methods (public and non-public) */
 
335
 
 
336
/**
 
337
 * nautilus_view_merge_menus:
 
338
 * 
 
339
 * Add this view's menus to the window's menu bar.
 
340
 * @view: NautilusView in question.
 
341
 */
 
342
static void
 
343
nautilus_view_merge_menus (NautilusView *view)
 
344
{
 
345
        g_return_if_fail (NAUTILUS_IS_VIEW (view));
 
346
 
 
347
        EEL_CALL_METHOD
 
348
                (NAUTILUS_VIEW_CLASS, view,
 
349
                 merge_menus, (view));
 
350
}
 
351
 
 
352
static void
 
353
nautilus_view_unmerge_menus (NautilusView *view)
 
354
{
 
355
        g_return_if_fail (NAUTILUS_IS_VIEW (view));
 
356
 
 
357
        EEL_CALL_METHOD
 
358
                (NAUTILUS_VIEW_CLASS, view,
 
359
                 unmerge_menus, (view));
 
360
}
 
361
 
 
362
static char *
 
363
real_get_backing_uri (NautilusView *view)
 
364
{
 
365
        NautilusDirectory *directory;
 
366
        char *uri;
 
367
       
 
368
        g_return_val_if_fail (NAUTILUS_IS_VIEW (view), NULL);
 
369
 
 
370
        if (view->details->model == NULL) {
 
371
                return NULL;
 
372
        }
 
373
       
 
374
        directory = view->details->model;
 
375
       
 
376
        if (NAUTILUS_IS_DESKTOP_DIRECTORY (directory)) {
 
377
                directory = nautilus_desktop_directory_get_real_directory (NAUTILUS_DESKTOP_DIRECTORY (directory));
 
378
        } else {
 
379
                nautilus_directory_ref (directory);
 
380
        }
 
381
       
 
382
        uri = nautilus_directory_get_uri (directory);
 
383
 
 
384
        nautilus_directory_unref (directory);
 
385
 
 
386
        return uri;
 
387
}
 
388
 
 
389
/**
 
390
 *
 
391
 * nautilus_view_get_backing_uri:
 
392
 *
 
393
 * Returns the URI for the target location of new directory, new file, new
 
394
 * link, new launcher, and paste operations.
 
395
 */
 
396
 
 
397
char *
 
398
nautilus_view_get_backing_uri (NautilusView *view)
 
399
{
 
400
        g_return_val_if_fail (NAUTILUS_IS_VIEW (view), NULL);
 
401
 
 
402
        return EEL_CALL_METHOD_WITH_RETURN_VALUE
 
403
                (NAUTILUS_VIEW_CLASS, view,
 
404
                 get_backing_uri, (view));
 
405
}
 
406
 
 
407
/**
 
408
 * nautilus_view_select_all:
 
409
 *
 
410
 * select all the items in the view
 
411
 * 
 
412
 **/
 
413
static void
 
414
nautilus_view_select_all (NautilusView *view)
 
415
{
 
416
        g_return_if_fail (NAUTILUS_IS_VIEW (view));
 
417
 
 
418
        EEL_CALL_METHOD
 
419
                (NAUTILUS_VIEW_CLASS, view,
 
420
                 select_all, (view));
 
421
}
 
422
 
 
423
static void
 
424
nautilus_view_call_set_selection (NautilusView *view, GList *selection)
 
425
{
 
426
        g_return_if_fail (NAUTILUS_IS_VIEW (view));
 
427
 
 
428
        EEL_CALL_METHOD
 
429
                (NAUTILUS_VIEW_CLASS, view,
 
430
                 set_selection, (view, selection));
 
431
}
 
432
 
 
433
static GList *
 
434
nautilus_view_get_selection_for_file_transfer (NautilusView *view)
 
435
{
 
436
        g_return_val_if_fail (NAUTILUS_IS_VIEW (view), NULL);
 
437
 
 
438
        return EEL_CALL_METHOD_WITH_RETURN_VALUE
 
439
                (NAUTILUS_VIEW_CLASS, view,
 
440
                 get_selection_for_file_transfer, (view));
 
441
}
 
442
 
 
443
/**
 
444
 * nautilus_view_get_selected_icon_locations:
 
445
 *
 
446
 * return an array of locations of selected icons if available
 
447
 * Return value: GArray of GdkPoints
 
448
 * 
 
449
 **/
 
450
static GArray *
 
451
nautilus_view_get_selected_icon_locations (NautilusView *view)
 
452
{
 
453
        g_return_val_if_fail (NAUTILUS_IS_VIEW (view), NULL);
 
454
 
 
455
        return EEL_CALL_METHOD_WITH_RETURN_VALUE
 
456
                (NAUTILUS_VIEW_CLASS, view,
 
457
                 get_selected_icon_locations, (view));
 
458
}
 
459
 
 
460
static void
 
461
nautilus_view_invert_selection (NautilusView *view)
 
462
{
 
463
        g_return_if_fail (NAUTILUS_IS_VIEW (view));
 
464
 
 
465
        EEL_CALL_METHOD
 
466
                (NAUTILUS_VIEW_CLASS, view,
 
467
                 invert_selection, (view));
 
468
}
 
469
 
 
470
/**
 
471
 * nautilus_view_reveal_selection:
 
472
 *
 
473
 * Scroll as necessary to reveal the selected items.
 
474
 **/
 
475
static void
 
476
nautilus_view_reveal_selection (NautilusView *view)
 
477
{
 
478
        g_return_if_fail (NAUTILUS_IS_VIEW (view));
 
479
 
 
480
        EEL_CALL_METHOD
 
481
                (NAUTILUS_VIEW_CLASS, view,
 
482
                 reveal_selection, (view));
 
483
}
 
484
 
 
485
/**
 
486
 * nautilus_view_reset_to_defaults:
 
487
 *
 
488
 * set sorting order, zoom level, etc. to match defaults
 
489
 * 
 
490
 **/
 
491
static void
 
492
nautilus_view_reset_to_defaults (NautilusView *view)
 
493
{
 
494
        NautilusWindowShowHiddenFilesMode mode;
 
495
 
 
496
        g_return_if_fail (NAUTILUS_IS_VIEW (view));
 
497
        
 
498
        EEL_CALL_METHOD
 
499
                (NAUTILUS_VIEW_CLASS, view,
 
500
                 reset_to_defaults, (view));
 
501
        mode = nautilus_window_get_hidden_files_mode (view->details->window);
 
502
        if (mode != NAUTILUS_WINDOW_SHOW_HIDDEN_FILES_DEFAULT) {
 
503
                nautilus_window_set_hidden_files_mode (view->details->window,
 
504
                                                       NAUTILUS_WINDOW_SHOW_HIDDEN_FILES_DEFAULT);
 
505
        }
 
506
}
 
507
 
 
508
static gboolean
 
509
nautilus_view_using_manual_layout (NautilusView  *view)
 
510
{
 
511
        g_return_val_if_fail (NAUTILUS_IS_VIEW (view), FALSE);
 
512
 
 
513
        return EEL_CALL_METHOD_WITH_RETURN_VALUE
 
514
                (NAUTILUS_VIEW_CLASS, view,
 
515
                 using_manual_layout, (view));
 
516
}
 
517
 
 
518
static guint
 
519
nautilus_view_get_item_count (NautilusView *view)
 
520
{
 
521
        g_return_val_if_fail (NAUTILUS_IS_VIEW (view), 0);
 
522
 
 
523
        return EEL_CALL_METHOD_WITH_RETURN_VALUE
 
524
                (NAUTILUS_VIEW_CLASS, view,
 
525
                 get_item_count, (view));
 
526
}
 
527
 
 
528
/**
 
529
 * nautilus_view_can_rename_file
 
530
 *
 
531
 * Determine whether a file can be renamed.
 
532
 * @file: A NautilusFile
 
533
 * 
 
534
 * Return value: TRUE if @file can be renamed, FALSE otherwise.
 
535
 * 
 
536
 **/
 
537
static gboolean
 
538
nautilus_view_can_rename_file (NautilusView *view, NautilusFile *file)
 
539
{
 
540
        return EEL_CALL_METHOD_WITH_RETURN_VALUE
 
541
                (NAUTILUS_VIEW_CLASS, view,
 
542
                 can_rename_file, (view, file));
 
543
}
 
544
 
 
545
static gboolean
 
546
nautilus_view_is_read_only (NautilusView *view)
 
547
{
 
548
        g_return_val_if_fail (NAUTILUS_IS_VIEW (view), FALSE);
 
549
 
 
550
        return EEL_CALL_METHOD_WITH_RETURN_VALUE
 
551
                (NAUTILUS_VIEW_CLASS, view,
 
552
                 is_read_only, (view));
 
553
}
 
554
 
 
555
static gboolean
 
556
showing_trash_directory (NautilusView *view)
 
557
{
 
558
        NautilusFile *file;
 
559
 
 
560
        file = nautilus_view_get_directory_as_file (view);
 
561
        if (file != NULL) {
 
562
                return nautilus_file_is_in_trash (file);
 
563
        }
 
564
        return FALSE;
 
565
}
 
566
 
 
567
static gboolean
 
568
nautilus_view_supports_creating_files (NautilusView *view)
 
569
{
 
570
        g_return_val_if_fail (NAUTILUS_IS_VIEW (view), FALSE);
 
571
 
 
572
        return !nautilus_view_is_read_only (view) && !showing_trash_directory (view);
 
573
}
 
574
 
 
575
static gboolean
 
576
nautilus_view_is_empty (NautilusView *view)
 
577
{
 
578
        g_return_val_if_fail (NAUTILUS_IS_VIEW (view), FALSE);
 
579
 
 
580
        return EEL_CALL_METHOD_WITH_RETURN_VALUE
 
581
                (NAUTILUS_VIEW_CLASS, view,
 
582
                 is_empty, (view));
 
583
}
 
584
 
 
585
/**
 
586
 * nautilus_view_bump_zoom_level:
 
587
 *
 
588
 * bump the current zoom level by invoking the relevant subclass through the slot
 
589
 * 
 
590
 **/
 
591
void
 
592
nautilus_view_bump_zoom_level (NautilusView *view,
 
593
                               int zoom_increment)
 
594
{
 
595
        g_return_if_fail (NAUTILUS_IS_VIEW (view));
 
596
 
 
597
        if (!nautilus_view_supports_zooming (view)) {
 
598
                return;
 
599
        }
 
600
 
 
601
        EEL_CALL_METHOD
 
602
                (NAUTILUS_VIEW_CLASS, view,
 
603
                 bump_zoom_level, (view, zoom_increment));
 
604
}
 
605
 
 
606
/**
 
607
 * nautilus_view_zoom_to_level:
 
608
 *
 
609
 * Set the current zoom level by invoking the relevant subclass through the slot
 
610
 * 
 
611
 **/
 
612
void
 
613
nautilus_view_zoom_to_level (NautilusView *view,
 
614
                             NautilusZoomLevel zoom_level)
 
615
{
 
616
        g_return_if_fail (NAUTILUS_IS_VIEW (view));
 
617
 
 
618
        if (!nautilus_view_supports_zooming (view)) {
 
619
                return;
 
620
        }
 
621
 
 
622
        EEL_CALL_METHOD
 
623
                (NAUTILUS_VIEW_CLASS, view,
 
624
                 zoom_to_level, (view, zoom_level));
 
625
}
 
626
 
 
627
NautilusZoomLevel
 
628
nautilus_view_get_zoom_level (NautilusView *view)
 
629
{
 
630
        g_return_val_if_fail (NAUTILUS_IS_VIEW (view), NAUTILUS_ZOOM_LEVEL_STANDARD);
 
631
 
 
632
        if (!nautilus_view_supports_zooming (view)) {
 
633
                return NAUTILUS_ZOOM_LEVEL_STANDARD;
 
634
        }
 
635
 
 
636
        return EEL_CALL_METHOD_WITH_RETURN_VALUE
 
637
                (NAUTILUS_VIEW_CLASS, view,
 
638
                 get_zoom_level, (view));
 
639
}
 
640
 
 
641
/**
 
642
 * nautilus_view_can_zoom_in:
 
643
 *
 
644
 * Determine whether the view can be zoomed any closer.
 
645
 * @view: The zoomable NautilusView.
 
646
 * 
 
647
 * Return value: TRUE if @view can be zoomed any closer, FALSE otherwise.
 
648
 * 
 
649
 **/
 
650
gboolean
 
651
nautilus_view_can_zoom_in (NautilusView *view)
 
652
{
 
653
        g_return_val_if_fail (NAUTILUS_IS_VIEW (view), FALSE);
 
654
 
 
655
        if (!nautilus_view_supports_zooming (view)) {
 
656
                return FALSE;
 
657
        }
 
658
 
 
659
        return EEL_CALL_METHOD_WITH_RETURN_VALUE
 
660
                (NAUTILUS_VIEW_CLASS, view,
 
661
                 can_zoom_in, (view));
 
662
}
 
663
 
 
664
/**
 
665
 * nautilus_view_can_zoom_out:
 
666
 *
 
667
 * Determine whether the view can be zoomed any further away.
 
668
 * @view: The zoomable NautilusView.
 
669
 * 
 
670
 * Return value: TRUE if @view can be zoomed any further away, FALSE otherwise.
 
671
 * 
 
672
 **/
 
673
gboolean
 
674
nautilus_view_can_zoom_out (NautilusView *view)
 
675
{
 
676
        g_return_val_if_fail (NAUTILUS_IS_VIEW (view), FALSE);
 
677
 
 
678
        if (!nautilus_view_supports_zooming (view)) {
 
679
                return FALSE;
 
680
        }
 
681
 
 
682
        return EEL_CALL_METHOD_WITH_RETURN_VALUE
 
683
                (NAUTILUS_VIEW_CLASS, view,
 
684
                 can_zoom_out, (view));
 
685
}
 
686
 
 
687
gboolean
 
688
nautilus_view_supports_zooming (NautilusView *view)
 
689
{
 
690
        g_return_val_if_fail (NAUTILUS_IS_VIEW (view), FALSE);
 
691
 
 
692
        return view->details->supports_zooming;
 
693
}
 
694
 
 
695
/**
 
696
 * nautilus_view_restore_default_zoom_level:
 
697
 *
 
698
 * restore to the default zoom level by invoking the relevant subclass through the slot
 
699
 * 
 
700
 **/
 
701
void
 
702
nautilus_view_restore_default_zoom_level (NautilusView *view)
 
703
{
 
704
        g_return_if_fail (NAUTILUS_IS_VIEW (view));
 
705
 
 
706
        if (!nautilus_view_supports_zooming (view)) {
 
707
                return;
 
708
        }
 
709
 
 
710
        EEL_CALL_METHOD
 
711
                (NAUTILUS_VIEW_CLASS, view,
 
712
                 restore_default_zoom_level, (view));
 
713
}
 
714
 
 
715
const char *
 
716
nautilus_view_get_view_id (NautilusView *view)
 
717
{
 
718
        return EEL_CALL_METHOD_WITH_RETURN_VALUE
 
719
                (NAUTILUS_VIEW_CLASS, view,
 
720
                 get_view_id, (view));
 
721
}
 
722
 
 
723
char *
 
724
nautilus_view_get_first_visible_file (NautilusView *view)
 
725
{
 
726
        return EEL_CALL_METHOD_WITH_RETURN_VALUE
 
727
                (NAUTILUS_VIEW_CLASS, view,
 
728
                 get_first_visible_file, (view));
 
729
}
 
730
 
 
731
void
 
732
nautilus_view_scroll_to_file (NautilusView *view,
 
733
                              const char *uri)
 
734
{
 
735
        EEL_CALL_METHOD
 
736
                (NAUTILUS_VIEW_CLASS, view,
 
737
                 scroll_to_file, (view, uri));
 
738
}
 
739
 
 
740
char **
 
741
nautilus_view_get_emblem_names_to_exclude (NautilusView *view)
 
742
{
 
743
        char **excludes;
 
744
        int i;
 
745
        
 
746
        g_assert (NAUTILUS_IS_VIEW (view));
 
747
 
 
748
        excludes = g_new (char *, 3);
 
749
        
 
750
        i = 0;
 
751
        excludes[i++] = g_strdup (NAUTILUS_FILE_EMBLEM_NAME_TRASH);
 
752
 
 
753
        if (!nautilus_file_can_write (view->details->directory_as_file)) {
 
754
                excludes[i++] = g_strdup (NAUTILUS_FILE_EMBLEM_NAME_CANT_WRITE);
 
755
        }
 
756
 
 
757
        excludes[i++] = NULL;
 
758
 
 
759
        return excludes;
 
760
}
 
761
 
 
762
void
 
763
nautilus_view_set_is_active (NautilusView *view,
 
764
                             gboolean is_active)
 
765
{
 
766
        g_return_if_fail (NAUTILUS_IS_VIEW (view));
 
767
 
 
768
        EEL_CALL_METHOD (NAUTILUS_VIEW_CLASS, view,
 
769
                         set_is_active, (view, is_active));
 
770
}
 
771
 
 
772
/**
 
773
 * nautilus_view_get_selection:
 
774
 *
 
775
 * Get a list of NautilusFile pointers that represents the
 
776
 * currently-selected items in this view. Subclasses must override
 
777
 * the signal handler for the 'get_selection' signal. Callers are
 
778
 * responsible for g_free-ing the list (but not its data).
 
779
 * @view: NautilusView whose selected items are of interest.
 
780
 * 
 
781
 * Return value: GList of NautilusFile pointers representing the selection.
 
782
 * 
 
783
 **/
 
784
GList *
 
785
nautilus_view_get_selection (NautilusView *view)
 
786
{
 
787
        g_return_val_if_fail (NAUTILUS_IS_VIEW (view), NULL);
 
788
 
 
789
        return EEL_CALL_METHOD_WITH_RETURN_VALUE
 
790
                (NAUTILUS_VIEW_CLASS, view,
 
791
                 get_selection, (view));
 
792
}
 
793
 
 
794
 
 
795
/**
 
796
 * nautilus_view_update_menus:
 
797
 * 
 
798
 * Update the sensitivity and wording of dynamic menu items.
 
799
 * @view: NautilusView in question.
 
800
 */
 
801
void
 
802
nautilus_view_update_menus (NautilusView *view)
 
803
{
 
804
        g_return_if_fail (NAUTILUS_IS_VIEW (view));
 
805
 
 
806
        if (!view->details->active) {
 
807
                return;
 
808
        }
 
809
 
 
810
 
 
811
        EEL_CALL_METHOD
 
812
                (NAUTILUS_VIEW_CLASS, view,
 
813
                 update_menus, (view));
 
814
 
 
815
        view->details->menu_states_untrustworthy = FALSE;
 
816
}
 
817
 
 
818
typedef struct {
 
819
        GAppInfo *application;
 
820
        GList *files;
 
821
        NautilusView *directory_view;
 
822
} ApplicationLaunchParameters;
 
823
 
 
824
typedef struct {
 
825
        NautilusFile *file;
 
826
        NautilusView *directory_view;
 
827
} ScriptLaunchParameters;
 
828
 
 
829
typedef struct {
 
830
        NautilusFile *file;
 
831
        NautilusView *directory_view;
 
832
} CreateTemplateParameters;
 
833
 
 
834
static ApplicationLaunchParameters *
 
835
application_launch_parameters_new (GAppInfo *application,
 
836
                                   GList *files,
 
837
                                   NautilusView *directory_view)
 
838
{
 
839
        ApplicationLaunchParameters *result;
 
840
 
 
841
        result = g_new0 (ApplicationLaunchParameters, 1);
 
842
        result->application = g_object_ref (application);
 
843
        result->files = nautilus_file_list_copy (files);
 
844
 
 
845
        if (directory_view != NULL) {
 
846
                g_object_ref (directory_view);
 
847
                result->directory_view = directory_view;
 
848
        }
 
849
 
 
850
        return result;
 
851
}
 
852
 
 
853
static void
 
854
application_launch_parameters_free (ApplicationLaunchParameters *parameters)
 
855
{
 
856
        g_object_unref (parameters->application);
 
857
        nautilus_file_list_free (parameters->files);
 
858
 
 
859
        if (parameters->directory_view != NULL) {
 
860
                g_object_unref (parameters->directory_view);
 
861
        }
 
862
 
 
863
        g_free (parameters);
 
864
}                             
 
865
 
 
866
static GList *
 
867
file_and_directory_list_to_files (GList *fad_list)
 
868
{
 
869
        GList *res, *l;
 
870
        FileAndDirectory *fad;
 
871
 
 
872
        res = NULL;
 
873
        for (l = fad_list; l != NULL; l = l->next) {
 
874
                fad = l->data;
 
875
                res = g_list_prepend (res, nautilus_file_ref (fad->file));
 
876
        }
 
877
        return g_list_reverse (res);
 
878
}
 
879
 
 
880
 
 
881
static GList *
 
882
file_and_directory_list_from_files (NautilusDirectory *directory, GList *files)
 
883
{
 
884
        GList *res, *l;
 
885
        FileAndDirectory *fad;
 
886
 
 
887
        res = NULL;
 
888
        for (l = files; l != NULL; l = l->next) {
 
889
                fad = g_new0 (FileAndDirectory, 1);
 
890
                fad->directory = nautilus_directory_ref (directory);
 
891
                fad->file = nautilus_file_ref (l->data);
 
892
                res = g_list_prepend (res, fad);
 
893
        }
 
894
        return g_list_reverse (res);
 
895
}
 
896
 
 
897
static void
 
898
file_and_directory_free (FileAndDirectory *fad)
 
899
{
 
900
        nautilus_directory_unref (fad->directory);
 
901
        nautilus_file_unref (fad->file);
 
902
        g_free (fad);
 
903
}
 
904
 
 
905
 
 
906
static void
 
907
file_and_directory_list_free (GList *list)
 
908
{
 
909
        GList *l;
 
910
 
 
911
        for (l = list; l != NULL; l = l->next) {
 
912
                file_and_directory_free (l->data);
 
913
        }
 
914
 
 
915
        g_list_free (list);
 
916
}
 
917
 
 
918
static gboolean
 
919
file_and_directory_equal (gconstpointer  v1,
 
920
                          gconstpointer  v2)
 
921
{
 
922
        const FileAndDirectory *fad1, *fad2;
 
923
        fad1 = v1;
 
924
        fad2 = v2;
 
925
 
 
926
        return (fad1->file == fad2->file &&
 
927
                fad1->directory == fad2->directory);
 
928
}
 
929
 
 
930
static guint
 
931
file_and_directory_hash  (gconstpointer  v)
 
932
{
 
933
        const FileAndDirectory *fad;
 
934
 
 
935
        fad = v;
 
936
        return GPOINTER_TO_UINT (fad->file) ^ GPOINTER_TO_UINT (fad->directory);
 
937
}
 
938
 
 
939
 
 
940
 
 
941
 
 
942
static ScriptLaunchParameters *
 
943
script_launch_parameters_new (NautilusFile *file,
 
944
                              NautilusView *directory_view)
 
945
{
 
946
        ScriptLaunchParameters *result;
 
947
 
 
948
        result = g_new0 (ScriptLaunchParameters, 1);
 
949
        g_object_ref (directory_view);
 
950
        result->directory_view = directory_view;
 
951
        nautilus_file_ref (file);
 
952
        result->file = file;
 
953
 
 
954
        return result;
 
955
}
 
956
 
 
957
static void
 
958
script_launch_parameters_free (ScriptLaunchParameters *parameters)
 
959
{
 
960
        g_object_unref (parameters->directory_view);
 
961
        nautilus_file_unref (parameters->file);
 
962
        g_free (parameters);
 
963
}                             
 
964
 
 
965
static CreateTemplateParameters *
 
966
create_template_parameters_new (NautilusFile *file,
 
967
                                NautilusView *directory_view)
 
968
{
 
969
        CreateTemplateParameters *result;
 
970
 
 
971
        result = g_new0 (CreateTemplateParameters, 1);
 
972
        g_object_ref (directory_view);
 
973
        result->directory_view = directory_view;
 
974
        nautilus_file_ref (file);
 
975
        result->file = file;
 
976
 
 
977
        return result;
 
978
}
 
979
 
 
980
static void
 
981
create_templates_parameters_free (CreateTemplateParameters *parameters)
 
982
{
 
983
        g_object_unref (parameters->directory_view);
 
984
        nautilus_file_unref (parameters->file);
 
985
        g_free (parameters);
 
986
}                             
 
987
 
 
988
NautilusWindow *
 
989
nautilus_view_get_nautilus_window (NautilusView  *view)
 
990
{
 
991
        g_assert (view->details->window != NULL);
 
992
 
 
993
        return view->details->window;
 
994
}
 
995
 
 
996
NautilusWindowSlot *
 
997
nautilus_view_get_nautilus_window_slot (NautilusView  *view)
 
998
{
 
999
        g_assert (view->details->slot != NULL);
 
1000
 
 
1001
        return view->details->slot;
 
1002
}
 
1003
 
 
1004
/* Returns the GtkWindow that this directory view occupies, or NULL
 
1005
 * if at the moment this directory view is not in a GtkWindow or the
 
1006
 * GtkWindow cannot be determined. Primarily used for parenting dialogs.
 
1007
 */
 
1008
static GtkWindow *
 
1009
nautilus_view_get_containing_window (NautilusView *view)
 
1010
{
 
1011
        GtkWidget *window;
 
1012
 
 
1013
        g_assert (NAUTILUS_IS_VIEW (view));
 
1014
        
 
1015
        window = gtk_widget_get_ancestor (GTK_WIDGET (view), GTK_TYPE_WINDOW);
 
1016
        if (window == NULL) {
 
1017
                return NULL;
 
1018
        }
 
1019
 
 
1020
        return GTK_WINDOW (window);
 
1021
}
 
1022
 
 
1023
static gboolean
 
1024
nautilus_view_confirm_multiple (GtkWindow *parent_window,
 
1025
                                int count,
 
1026
                                gboolean tabs)
 
1027
{
 
1028
        GtkDialog *dialog;
 
1029
        char *prompt;
 
1030
        char *detail;
 
1031
        int response;
 
1032
 
 
1033
        if (count <= SILENT_WINDOW_OPEN_LIMIT) {
 
1034
                return TRUE;
 
1035
        }
 
1036
 
 
1037
        prompt = _("Are you sure you want to open all files?");
 
1038
        if (tabs) {
 
1039
                detail = g_strdup_printf (ngettext("This will open %'d separate tab.",
 
1040
                                                   "This will open %'d separate tabs.", count), count);
 
1041
        } else {
 
1042
                detail = g_strdup_printf (ngettext("This will open %'d separate window.",
 
1043
                                                   "This will open %'d separate windows.", count), count);
 
1044
        }
 
1045
        dialog = eel_show_yes_no_dialog (prompt, detail, 
 
1046
                                         GTK_STOCK_OK, GTK_STOCK_CANCEL,
 
1047
                                         parent_window);
 
1048
        g_free (detail);
 
1049
 
 
1050
        response = gtk_dialog_run (dialog);
 
1051
        gtk_widget_destroy (GTK_WIDGET (dialog));
 
1052
 
 
1053
        return response == GTK_RESPONSE_YES;
 
1054
}
 
1055
 
 
1056
static gboolean
 
1057
selection_contains_one_item_in_menu_callback (NautilusView *view, GList *selection)
 
1058
{
 
1059
        if (eel_g_list_exactly_one_item (selection)) {
 
1060
                return TRUE;
 
1061
        }
 
1062
 
 
1063
        /* If we've requested a menu update that hasn't yet occurred, then
 
1064
         * the mismatch here doesn't surprise us, and we won't complain.
 
1065
         * Otherwise, we will complain.
 
1066
         */
 
1067
        if (!view->details->menu_states_untrustworthy) {
 
1068
                g_warning ("Expected one selected item, found %'d. No action will be performed.",       
 
1069
                           g_list_length (selection));
 
1070
        }
 
1071
 
 
1072
        return FALSE;
 
1073
}
 
1074
 
 
1075
static gboolean
 
1076
selection_not_empty_in_menu_callback (NautilusView *view, GList *selection)
 
1077
{
 
1078
        if (selection != NULL) {
 
1079
                return TRUE;
 
1080
        }
 
1081
 
 
1082
        /* If we've requested a menu update that hasn't yet occurred, then
 
1083
         * the mismatch here doesn't surprise us, and we won't complain.
 
1084
         * Otherwise, we will complain.
 
1085
         */
 
1086
        if (!view->details->menu_states_untrustworthy) {
 
1087
                g_warning ("Empty selection found when selection was expected. No action will be performed.");
 
1088
        }
 
1089
 
 
1090
        return FALSE;
 
1091
}
 
1092
 
 
1093
static char *
 
1094
get_view_directory (NautilusView *view)
 
1095
{
 
1096
        char *uri, *path;
 
1097
        GFile *f;
 
1098
        
 
1099
        uri = nautilus_directory_get_uri (view->details->model);
 
1100
        if (eel_uri_is_desktop (uri)) {
 
1101
                g_free (uri);
 
1102
                uri = nautilus_get_desktop_directory_uri ();
 
1103
                
 
1104
        }
 
1105
        f = g_file_new_for_uri (uri);
 
1106
        path = g_file_get_path (f);
 
1107
        g_object_unref (f);
 
1108
        g_free (uri);
 
1109
        
 
1110
        return path;
 
1111
}
 
1112
 
 
1113
void
 
1114
nautilus_view_preview_files (NautilusView *view,
 
1115
                             GList *files,
 
1116
                             GArray *locations)
 
1117
{
 
1118
        NautilusPreviewer *previewer;
 
1119
        gchar *uri;
 
1120
        guint xid;
 
1121
        GtkWidget *toplevel;
 
1122
 
 
1123
        previewer = nautilus_previewer_get_singleton ();
 
1124
        uri = nautilus_file_get_uri (files->data);
 
1125
        toplevel = gtk_widget_get_toplevel (GTK_WIDGET (view));
 
1126
 
 
1127
        xid = gdk_x11_window_get_xid (gtk_widget_get_window (toplevel));
 
1128
        nautilus_previewer_call_show_file (previewer, uri, xid, TRUE);
 
1129
}
 
1130
 
 
1131
void
 
1132
nautilus_view_activate_files (NautilusView *view,
 
1133
                              GList *files,
 
1134
                              NautilusWindowOpenFlags flags,
 
1135
                              gboolean confirm_multiple)
 
1136
{
 
1137
        char *path;
 
1138
 
 
1139
        path = get_view_directory (view);
 
1140
        nautilus_mime_activate_files (nautilus_view_get_containing_window (view),
 
1141
                                      view->details->slot,
 
1142
                                      files,
 
1143
                                      path,
 
1144
                                      flags,
 
1145
                                      confirm_multiple);
 
1146
 
 
1147
        g_free (path);
 
1148
}
 
1149
 
 
1150
static void
 
1151
nautilus_view_activate_file (NautilusView *view,
 
1152
                             NautilusFile *file,
 
1153
                             NautilusWindowOpenFlags flags)
 
1154
{
 
1155
        char *path;
 
1156
 
 
1157
        path = get_view_directory (view);
 
1158
        nautilus_mime_activate_file (nautilus_view_get_containing_window (view),
 
1159
                                     view->details->slot,
 
1160
                                     file,
 
1161
                                     path,
 
1162
                                     flags);
 
1163
 
 
1164
        g_free (path);
 
1165
}
 
1166
 
 
1167
static void
 
1168
action_open_callback (GtkAction *action,
 
1169
                      gpointer callback_data)
 
1170
{
 
1171
        GList *selection;
 
1172
        NautilusView *view;
 
1173
 
 
1174
        view = NAUTILUS_VIEW (callback_data);
 
1175
 
 
1176
        selection = nautilus_view_get_selection (view);
 
1177
        nautilus_view_activate_files (view,
 
1178
                                      selection,
 
1179
                                      0,
 
1180
                                      TRUE);
 
1181
        nautilus_file_list_free (selection);
 
1182
}
 
1183
 
 
1184
static void
 
1185
action_open_close_parent_callback (GtkAction *action,
 
1186
                                   gpointer callback_data)
 
1187
{
 
1188
        GList *selection;
 
1189
        NautilusView *view;
 
1190
 
 
1191
        view = NAUTILUS_VIEW (callback_data);
 
1192
 
 
1193
        selection = nautilus_view_get_selection (view);
 
1194
        nautilus_view_activate_files (view,
 
1195
                                      selection,
 
1196
                                      NAUTILUS_WINDOW_OPEN_FLAG_CLOSE_BEHIND,
 
1197
                                      TRUE);
 
1198
        nautilus_file_list_free (selection);
 
1199
}
 
1200
 
 
1201
 
 
1202
static void
 
1203
action_open_alternate_callback (GtkAction *action,
 
1204
                                gpointer callback_data)
 
1205
{
 
1206
        NautilusView *view;
 
1207
        GList *selection;
 
1208
        GtkWindow *window;
 
1209
 
 
1210
        view = NAUTILUS_VIEW (callback_data);
 
1211
        selection = nautilus_view_get_selection (view);
 
1212
 
 
1213
        window = nautilus_view_get_containing_window (view);
 
1214
 
 
1215
        if (nautilus_view_confirm_multiple (window, g_list_length (selection), FALSE)) {
 
1216
                g_list_foreach (selection, open_one_in_new_window, view);
 
1217
        }
 
1218
 
 
1219
        nautilus_file_list_free (selection);
 
1220
}
 
1221
 
 
1222
static void
 
1223
action_open_new_tab_callback (GtkAction *action,
 
1224
                              gpointer callback_data)
 
1225
{
 
1226
        NautilusView *view;
 
1227
        GList *selection;
 
1228
        GtkWindow *window;
 
1229
 
 
1230
        view = NAUTILUS_VIEW (callback_data);
 
1231
        selection = nautilus_view_get_selection (view);
 
1232
 
 
1233
        window = nautilus_view_get_containing_window (view);
 
1234
 
 
1235
        if (nautilus_view_confirm_multiple (window, g_list_length (selection), TRUE)) {
 
1236
                nautilus_view_activate_files (view,
 
1237
                                              selection,
 
1238
                                              NAUTILUS_WINDOW_OPEN_FLAG_NEW_TAB,
 
1239
                                              FALSE);
 
1240
        }
 
1241
 
 
1242
        nautilus_file_list_free (selection);
 
1243
}
 
1244
 
 
1245
static void
 
1246
app_chooser_dialog_response_cb (GtkDialog *dialog,
 
1247
                                gint response_id,
 
1248
                                gpointer user_data)
 
1249
{
 
1250
        GtkWindow *parent_window;
 
1251
        NautilusFile *file;
 
1252
        GAppInfo *info;
 
1253
        GList files;
 
1254
 
 
1255
        parent_window = user_data;
 
1256
 
 
1257
        if (response_id != GTK_RESPONSE_OK) {
 
1258
                gtk_widget_destroy (GTK_WIDGET (dialog));
 
1259
                return;
 
1260
        }
 
1261
 
 
1262
        info = gtk_app_chooser_get_app_info (GTK_APP_CHOOSER (dialog));
 
1263
        file = g_object_get_data (G_OBJECT (dialog), "directory-view:file");
 
1264
 
 
1265
        g_signal_emit_by_name (nautilus_signaller_get_current (), "mime_data_changed");
 
1266
 
 
1267
        files.next = NULL;
 
1268
        files.prev = NULL;
 
1269
        files.data = file;
 
1270
        nautilus_launch_application (info, &files, parent_window);
 
1271
 
 
1272
        gtk_widget_destroy (GTK_WIDGET (dialog));
 
1273
        g_object_unref (info);
 
1274
}
 
1275
 
 
1276
static void
 
1277
choose_program (NautilusView *view,
 
1278
                NautilusFile *file)
 
1279
{
 
1280
        GtkWidget *dialog;
 
1281
        GFile *location;
 
1282
        GtkWindow *parent_window;
 
1283
 
 
1284
        g_assert (NAUTILUS_IS_VIEW (view));
 
1285
        g_assert (NAUTILUS_IS_FILE (file));
 
1286
 
 
1287
        nautilus_file_ref (file);
 
1288
        location = nautilus_file_get_location (file);
 
1289
        parent_window = nautilus_view_get_containing_window (view);
 
1290
 
 
1291
        dialog = gtk_app_chooser_dialog_new (parent_window, 0,
 
1292
                                             location);
 
1293
        g_object_set_data_full (G_OBJECT (dialog), 
 
1294
                                "directory-view:file",
 
1295
                                g_object_ref (file),
 
1296
                                (GDestroyNotify)g_object_unref);
 
1297
        gtk_widget_show (dialog);
 
1298
 
 
1299
        g_signal_connect_object (dialog, "response", 
 
1300
                                 G_CALLBACK (app_chooser_dialog_response_cb),
 
1301
                                 parent_window, 0);
 
1302
 
 
1303
        g_object_unref (location);
 
1304
        nautilus_file_unref (file);     
 
1305
}
 
1306
 
 
1307
static void
 
1308
open_with_other_program (NautilusView *view)
 
1309
{
 
1310
        GList *selection;
 
1311
 
 
1312
        g_assert (NAUTILUS_IS_VIEW (view));
 
1313
 
 
1314
        selection = nautilus_view_get_selection (view);
 
1315
 
 
1316
        if (selection_contains_one_item_in_menu_callback (view, selection)) {
 
1317
                choose_program (view, NAUTILUS_FILE (selection->data));
 
1318
        }
 
1319
 
 
1320
        nautilus_file_list_free (selection);
 
1321
}
 
1322
 
 
1323
static void
 
1324
action_other_application_callback (GtkAction *action,
 
1325
                                   gpointer callback_data)
 
1326
{
 
1327
        g_assert (NAUTILUS_IS_VIEW (callback_data));
 
1328
 
 
1329
        open_with_other_program (NAUTILUS_VIEW (callback_data));
 
1330
}
 
1331
 
 
1332
static void
 
1333
trash_or_delete_selected_files (NautilusView *view)
 
1334
{
 
1335
        GList *selection;
 
1336
 
 
1337
        /* This might be rapidly called multiple times for the same selection
 
1338
         * when using keybindings. So we remember if the current selection
 
1339
         * was already removed (but the view doesn't know about it yet).
 
1340
         */
 
1341
        if (!view->details->selection_was_removed) {
 
1342
                selection = nautilus_view_get_selection_for_file_transfer (view);
 
1343
                trash_or_delete_files (nautilus_view_get_containing_window (view),
 
1344
                                       selection, TRUE,
 
1345
                                       view);
 
1346
                nautilus_file_list_free (selection);
 
1347
                view->details->selection_was_removed = TRUE;
 
1348
        }
 
1349
}
 
1350
 
 
1351
static gboolean
 
1352
real_trash (NautilusView *view)
 
1353
{
 
1354
        GtkAction *action;
 
1355
 
 
1356
        action = gtk_action_group_get_action (view->details->dir_action_group,
 
1357
                                              NAUTILUS_ACTION_TRASH);
 
1358
        if (gtk_action_get_sensitive (action) &&
 
1359
            gtk_action_get_visible (action)) {
 
1360
                trash_or_delete_selected_files (view);
 
1361
                return TRUE;
 
1362
        }
 
1363
        return FALSE;
 
1364
}
 
1365
 
 
1366
static void
 
1367
action_trash_callback (GtkAction *action,
 
1368
                       gpointer callback_data)
 
1369
{
 
1370
        trash_or_delete_selected_files (NAUTILUS_VIEW (callback_data));
 
1371
}
 
1372
 
 
1373
static void
 
1374
delete_selected_files (NautilusView *view)
 
1375
{
 
1376
        GList *selection;
 
1377
        GList *node;
 
1378
        GList *locations;
 
1379
 
 
1380
        selection = nautilus_view_get_selection_for_file_transfer (view);
 
1381
        if (selection == NULL) {
 
1382
                return;
 
1383
        }
 
1384
 
 
1385
        locations = NULL;
 
1386
        for (node = selection; node != NULL; node = node->next) {
 
1387
                locations = g_list_prepend (locations,
 
1388
                                            nautilus_file_get_location ((NautilusFile *) node->data));
 
1389
        }
 
1390
        locations = g_list_reverse (locations);
 
1391
 
 
1392
        nautilus_file_operations_delete (locations, nautilus_view_get_containing_window (view), NULL, NULL);
 
1393
 
 
1394
        g_list_free_full (locations, g_object_unref);
 
1395
        nautilus_file_list_free (selection);
 
1396
}
 
1397
 
 
1398
static void
 
1399
action_delete_callback (GtkAction *action,
 
1400
                        gpointer callback_data)
 
1401
{
 
1402
        delete_selected_files (NAUTILUS_VIEW (callback_data));
 
1403
}
 
1404
 
 
1405
static void
 
1406
action_restore_from_trash_callback (GtkAction *action,
 
1407
                                    gpointer callback_data)
 
1408
{
 
1409
        NautilusView *view;
 
1410
        GList *selection;
 
1411
 
 
1412
        view = NAUTILUS_VIEW (callback_data);
 
1413
 
 
1414
        selection = nautilus_view_get_selection_for_file_transfer (view);
 
1415
        nautilus_restore_files_from_trash (selection,
 
1416
                                           nautilus_view_get_containing_window (view));
 
1417
 
 
1418
        nautilus_file_list_free (selection);
 
1419
 
 
1420
}
 
1421
 
 
1422
static gboolean
 
1423
real_delete (NautilusView *view)
 
1424
{
 
1425
        GtkAction *action;
 
1426
 
 
1427
        action = gtk_action_group_get_action (view->details->dir_action_group,
 
1428
                                              NAUTILUS_ACTION_DELETE);
 
1429
        if (gtk_action_get_sensitive (action) &&
 
1430
            gtk_action_get_visible (action)) {
 
1431
                delete_selected_files (view);
 
1432
                return TRUE;
 
1433
        }
 
1434
        return FALSE;
 
1435
}
 
1436
 
 
1437
static void
 
1438
action_duplicate_callback (GtkAction *action,
 
1439
                           gpointer callback_data)
 
1440
{
 
1441
        NautilusView *view;
 
1442
        GList *selection;
 
1443
        GArray *selected_item_locations;
 
1444
 
 
1445
        view = NAUTILUS_VIEW (callback_data);
 
1446
        selection = nautilus_view_get_selection_for_file_transfer (view);
 
1447
        if (selection_not_empty_in_menu_callback (view, selection)) {
 
1448
                /* FIXME bugzilla.gnome.org 45061:
 
1449
                 * should change things here so that we use a get_icon_locations (view, selection).
 
1450
                 * Not a problem in this case but in other places the selection may change by
 
1451
                 * the time we go and retrieve the icon positions, relying on the selection
 
1452
                 * staying intact to ensure the right sequence and count of positions is fragile.
 
1453
                 */
 
1454
                selected_item_locations = nautilus_view_get_selected_icon_locations (view);
 
1455
                nautilus_view_duplicate_selection (view, selection, selected_item_locations);
 
1456
                g_array_free (selected_item_locations, TRUE);
 
1457
        }
 
1458
 
 
1459
        nautilus_file_list_free (selection);
 
1460
}
 
1461
 
 
1462
static void
 
1463
action_create_link_callback (GtkAction *action,
 
1464
                             gpointer callback_data)
 
1465
{
 
1466
        NautilusView *view;
 
1467
        GList *selection;
 
1468
        GArray *selected_item_locations;
 
1469
        
 
1470
        g_assert (NAUTILUS_IS_VIEW (callback_data));
 
1471
 
 
1472
        view = NAUTILUS_VIEW (callback_data);
 
1473
        selection = nautilus_view_get_selection (view);
 
1474
        if (selection_not_empty_in_menu_callback (view, selection)) {
 
1475
                selected_item_locations = nautilus_view_get_selected_icon_locations (view);
 
1476
                nautilus_view_create_links_for_files (view, selection, selected_item_locations);
 
1477
                g_array_free (selected_item_locations, TRUE);
 
1478
        }
 
1479
 
 
1480
        nautilus_file_list_free (selection);
 
1481
}
 
1482
 
 
1483
static void
 
1484
action_select_all_callback (GtkAction *action, 
 
1485
                            gpointer callback_data)
 
1486
{
 
1487
        g_assert (NAUTILUS_IS_VIEW (callback_data));
 
1488
 
 
1489
        nautilus_view_select_all (callback_data);
 
1490
}
 
1491
 
 
1492
static void
 
1493
action_invert_selection_callback (GtkAction *action,
 
1494
                                  gpointer callback_data)
 
1495
{
 
1496
        g_assert (NAUTILUS_IS_VIEW (callback_data));
 
1497
 
 
1498
        nautilus_view_invert_selection (callback_data);
 
1499
}
 
1500
 
 
1501
static void
 
1502
pattern_select_response_cb (GtkWidget *dialog, int response, gpointer user_data)
 
1503
{
 
1504
        NautilusView *view;
 
1505
        NautilusDirectory *directory;
 
1506
        GtkWidget *entry;
 
1507
        GList *selection;
 
1508
        GError *error;
 
1509
 
 
1510
        view = NAUTILUS_VIEW (user_data);
 
1511
 
 
1512
        switch (response) {
 
1513
        case GTK_RESPONSE_OK :
 
1514
                entry = g_object_get_data (G_OBJECT (dialog), "entry");
 
1515
                directory = nautilus_view_get_model (view);
 
1516
                selection = nautilus_directory_match_pattern (directory,
 
1517
                                                              gtk_entry_get_text (GTK_ENTRY (entry)));
 
1518
                        
 
1519
                if (selection) {
 
1520
                        nautilus_view_call_set_selection (view, selection);
 
1521
                        nautilus_file_list_free (selection);
 
1522
 
 
1523
                        nautilus_view_reveal_selection(view);
 
1524
                }
 
1525
                /* fall through */
 
1526
        case GTK_RESPONSE_NONE :
 
1527
        case GTK_RESPONSE_DELETE_EVENT :
 
1528
        case GTK_RESPONSE_CANCEL :
 
1529
                gtk_widget_destroy (GTK_WIDGET (dialog));
 
1530
                break;
 
1531
        case GTK_RESPONSE_HELP :
 
1532
                error = NULL;
 
1533
                gtk_show_uri (gtk_window_get_screen (GTK_WINDOW (dialog)),
 
1534
                              "ghelp:gnome-help#files-select",
 
1535
                              gtk_get_current_event_time (), &error);
 
1536
                if (error) {
 
1537
                        eel_show_error_dialog (_("There was an error displaying help."), error->message,
 
1538
                                               GTK_WINDOW (dialog));
 
1539
                        g_error_free (error);
 
1540
                }
 
1541
                break;
 
1542
        default :
 
1543
                g_assert_not_reached ();
 
1544
        }
 
1545
}
 
1546
 
 
1547
static void
 
1548
select_pattern (NautilusView *view)
 
1549
{
 
1550
        GtkWidget *dialog;
 
1551
        GtkWidget *label;
 
1552
        GtkWidget *example;
 
1553
        GtkWidget *table;
 
1554
        GtkWidget *entry;
 
1555
        char *example_pattern;
 
1556
 
 
1557
        dialog = gtk_dialog_new_with_buttons (_("Select Items Matching"),
 
1558
                                              nautilus_view_get_containing_window (view),
 
1559
                                              GTK_DIALOG_DESTROY_WITH_PARENT,
 
1560
                                              GTK_STOCK_HELP,
 
1561
                                              GTK_RESPONSE_HELP,
 
1562
                                              GTK_STOCK_CANCEL,
 
1563
                                              GTK_RESPONSE_CANCEL,
 
1564
                                              GTK_STOCK_OK,
 
1565
                                              GTK_RESPONSE_OK,
 
1566
                                              NULL);
 
1567
        gtk_dialog_set_default_response (GTK_DIALOG (dialog),
 
1568
                                         GTK_RESPONSE_OK);
 
1569
        gtk_container_set_border_width (GTK_CONTAINER (dialog), 5);
 
1570
        gtk_box_set_spacing (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))), 2);
 
1571
 
 
1572
        label = gtk_label_new_with_mnemonic (_("_Pattern:"));
 
1573
        example = gtk_label_new (NULL);
 
1574
        example_pattern = g_strdup_printf ("<b>%s</b><i>%s</i>", 
 
1575
                                           _("Examples: "),
 
1576
                                           "*.png, file\?\?.txt, pict*.\?\?\?");
 
1577
        gtk_label_set_markup (GTK_LABEL (example), example_pattern);
 
1578
        g_free (example_pattern);
 
1579
        gtk_misc_set_alignment (GTK_MISC (example), 0.0, 0.5);
 
1580
        entry = gtk_entry_new ();
 
1581
        gtk_entry_set_activates_default (GTK_ENTRY (entry), TRUE);
 
1582
 
 
1583
        table = gtk_table_new (2, 2, FALSE);
 
1584
        
 
1585
        gtk_table_attach (GTK_TABLE (table), label,
 
1586
                          0, 1,
 
1587
                          0, 1,
 
1588
                          GTK_FILL, GTK_FILL,
 
1589
                          5, 5);
 
1590
 
 
1591
        gtk_table_attach (GTK_TABLE (table), entry,
 
1592
                          1, 2,
 
1593
                          0, 1,
 
1594
                          GTK_EXPAND | GTK_FILL, GTK_FILL,
 
1595
                          5, 5);
 
1596
 
 
1597
        gtk_table_attach (GTK_TABLE (table), example,
 
1598
                          1, 2,
 
1599
                          1, 2,
 
1600
                          GTK_FILL, GTK_FILL,
 
1601
                          5, 0);
 
1602
 
 
1603
        gtk_label_set_mnemonic_widget (GTK_LABEL (label), entry);
 
1604
        gtk_widget_show_all (table);
 
1605
        gtk_container_add (GTK_CONTAINER (gtk_dialog_get_content_area (GTK_DIALOG (dialog))), table);
 
1606
        g_object_set_data (G_OBJECT (dialog), "entry", entry);
 
1607
        g_signal_connect (dialog, "response",
 
1608
                          G_CALLBACK (pattern_select_response_cb),
 
1609
                          view);
 
1610
        gtk_widget_show_all (dialog);
 
1611
}
 
1612
 
 
1613
static void
 
1614
action_select_pattern_callback (GtkAction *action, 
 
1615
                                gpointer callback_data)
 
1616
{
 
1617
        g_assert (NAUTILUS_IS_VIEW (callback_data));
 
1618
 
 
1619
        select_pattern(callback_data);
 
1620
}
 
1621
 
 
1622
static void
 
1623
action_reset_to_defaults_callback (GtkAction *action, 
 
1624
                                   gpointer callback_data)
 
1625
{
 
1626
        g_assert (NAUTILUS_IS_VIEW (callback_data));
 
1627
 
 
1628
        nautilus_view_reset_to_defaults (callback_data);
 
1629
}
 
1630
 
 
1631
 
 
1632
static void
 
1633
hidden_files_mode_changed (NautilusWindow *window,
 
1634
                           gpointer callback_data)
 
1635
{
 
1636
        NautilusView *directory_view;
 
1637
 
 
1638
        directory_view = NAUTILUS_VIEW (callback_data);
 
1639
 
 
1640
        nautilus_view_init_show_hidden_files (directory_view);
 
1641
}
 
1642
 
 
1643
static void
 
1644
action_save_search_callback (GtkAction *action,
 
1645
                             gpointer callback_data)
 
1646
{                
 
1647
        NautilusSearchDirectory *search;
 
1648
        NautilusView    *directory_view;
 
1649
        
 
1650
        directory_view = NAUTILUS_VIEW (callback_data);
 
1651
 
 
1652
        if (directory_view->details->model &&
 
1653
            NAUTILUS_IS_SEARCH_DIRECTORY (directory_view->details->model)) {
 
1654
                search = NAUTILUS_SEARCH_DIRECTORY (directory_view->details->model);
 
1655
                nautilus_search_directory_save_search (search);
 
1656
 
 
1657
                /* Save search is disabled */
 
1658
                schedule_update_menus (directory_view);
 
1659
        }
 
1660
}
 
1661
 
 
1662
static void
 
1663
query_name_entry_changed_cb  (GtkWidget *entry, GtkWidget *button)
 
1664
{
 
1665
        const char *text;
 
1666
        gboolean sensitive;
 
1667
        
 
1668
        text = gtk_entry_get_text (GTK_ENTRY (entry));
 
1669
 
 
1670
        sensitive = (text != NULL) && (*text != 0);
 
1671
 
 
1672
        gtk_widget_set_sensitive (button, sensitive);
 
1673
}
 
1674
 
 
1675
 
 
1676
static void
 
1677
action_save_search_as_callback (GtkAction *action,
 
1678
                                gpointer callback_data)
 
1679
{
 
1680
        NautilusView    *directory_view;
 
1681
        NautilusSearchDirectory *search;
 
1682
        GtkWidget *dialog, *table, *label, *entry, *chooser, *save_button;
 
1683
        const char *entry_text;
 
1684
        char *filename, *filename_utf8, *dirname, *path, *uri;
 
1685
        GFile *location;
 
1686
        
 
1687
        directory_view = NAUTILUS_VIEW (callback_data);
 
1688
 
 
1689
        if (directory_view->details->model &&
 
1690
            NAUTILUS_IS_SEARCH_DIRECTORY (directory_view->details->model)) {
 
1691
                search = NAUTILUS_SEARCH_DIRECTORY (directory_view->details->model);
 
1692
                
 
1693
                dialog = gtk_dialog_new_with_buttons (_("Save Search as"),
 
1694
                                                      nautilus_view_get_containing_window (directory_view),
 
1695
                                                      0,
 
1696
                                                      GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
 
1697
                                                      NULL);
 
1698
                save_button = gtk_dialog_add_button (GTK_DIALOG (dialog),
 
1699
                                                     GTK_STOCK_SAVE, GTK_RESPONSE_OK);
 
1700
                gtk_dialog_set_default_response (GTK_DIALOG (dialog),
 
1701
                                                 GTK_RESPONSE_OK);
 
1702
                gtk_container_set_border_width (GTK_CONTAINER (dialog), 5);
 
1703
                gtk_box_set_spacing (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))), 2);
 
1704
                gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE);
 
1705
 
 
1706
                table = gtk_table_new (2, 2, FALSE);
 
1707
                gtk_container_set_border_width (GTK_CONTAINER (table), 5);
 
1708
                gtk_table_set_row_spacings (GTK_TABLE (table), 6);
 
1709
                gtk_table_set_col_spacings (GTK_TABLE (table), 12);
 
1710
                gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))), table, TRUE, TRUE, 0);
 
1711
                gtk_widget_show (table);
 
1712
                
 
1713
                label = gtk_label_new_with_mnemonic (_("Search _name:"));
 
1714
                gtk_misc_set_alignment (GTK_MISC(label), 0.0, 0.5);
 
1715
                gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1, GTK_FILL, 0, 0, 0);
 
1716
                gtk_widget_show (label);
 
1717
                entry = gtk_entry_new ();
 
1718
                gtk_table_attach (GTK_TABLE (table), entry, 1, 2, 0, 1, GTK_FILL | GTK_EXPAND, 0, 0, 0);
 
1719
                gtk_entry_set_activates_default (GTK_ENTRY (entry), TRUE);
 
1720
                gtk_label_set_mnemonic_widget (GTK_LABEL (label), entry);
 
1721
                
 
1722
                gtk_widget_set_sensitive (save_button, FALSE);
 
1723
                g_signal_connect (entry, "changed",
 
1724
                                  G_CALLBACK (query_name_entry_changed_cb), save_button);
 
1725
                
 
1726
                gtk_widget_show (entry);
 
1727
                label = gtk_label_new_with_mnemonic (_("_Folder:"));
 
1728
                gtk_misc_set_alignment (GTK_MISC(label), 0.0, 0.5);
 
1729
                gtk_table_attach (GTK_TABLE (table), label, 0, 1, 1, 2, GTK_FILL, 0, 0, 0);
 
1730
                gtk_widget_show (label);
 
1731
 
 
1732
                chooser = gtk_file_chooser_button_new (_("Select Folder to Save Search In"),
 
1733
                                                       GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER);
 
1734
                gtk_table_attach (GTK_TABLE (table), chooser, 1, 2, 1, 2, GTK_FILL | GTK_EXPAND, 0, 0, 0);
 
1735
                gtk_label_set_mnemonic_widget (GTK_LABEL (label), chooser);
 
1736
                gtk_widget_show (chooser);
 
1737
 
 
1738
                gtk_file_chooser_set_local_only (GTK_FILE_CHOOSER (chooser), TRUE);
 
1739
 
 
1740
                gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (chooser),
 
1741
                                                     g_get_home_dir ());
 
1742
                
 
1743
                if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK) {
 
1744
                        entry_text = gtk_entry_get_text (GTK_ENTRY (entry));
 
1745
                        if (g_str_has_suffix (entry_text, NAUTILUS_SAVED_SEARCH_EXTENSION)) {
 
1746
                                filename_utf8 = g_strdup (entry_text);
 
1747
                        } else {
 
1748
                                filename_utf8 = g_strconcat (entry_text, NAUTILUS_SAVED_SEARCH_EXTENSION, NULL);
 
1749
                        }
 
1750
 
 
1751
                        filename = g_filename_from_utf8 (filename_utf8, -1, NULL, NULL, NULL);
 
1752
                        g_free (filename_utf8);
 
1753
 
 
1754
                        dirname = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (chooser));
 
1755
                        
 
1756
                        path = g_build_filename (dirname, filename, NULL);
 
1757
                        g_free (filename);
 
1758
                        g_free (dirname);
 
1759
 
 
1760
                        uri = g_filename_to_uri (path, NULL, NULL);
 
1761
                        g_free (path);
 
1762
                        
 
1763
                        nautilus_search_directory_save_to_file (search, uri);
 
1764
                        location = g_file_new_for_uri (uri);
 
1765
                        nautilus_file_changes_queue_file_added (location);
 
1766
                        g_object_unref (location);
 
1767
                        nautilus_file_changes_consume_changes (TRUE);
 
1768
                        g_free (uri);
 
1769
                }
 
1770
                
 
1771
                gtk_widget_destroy (dialog);
 
1772
        }
 
1773
}
 
1774
 
 
1775
 
 
1776
static void
 
1777
action_empty_trash_callback (GtkAction *action,
 
1778
                             gpointer callback_data)
 
1779
{                
 
1780
        g_assert (NAUTILUS_IS_VIEW (callback_data));
 
1781
 
 
1782
        nautilus_file_operations_empty_trash (GTK_WIDGET (callback_data));
 
1783
}
 
1784
 
 
1785
typedef struct {
 
1786
        NautilusView *view;
 
1787
        NautilusFile *new_file;
 
1788
} RenameData;
 
1789
 
 
1790
static gboolean
 
1791
delayed_rename_file_hack_callback (RenameData *data)
 
1792
{
 
1793
        NautilusView *view;
 
1794
        NautilusFile *new_file;
 
1795
 
 
1796
        view = data->view;
 
1797
        new_file = data->new_file;
 
1798
 
 
1799
        if (view->details->window != NULL &&
 
1800
            view->details->active) {
 
1801
                EEL_CALL_METHOD (NAUTILUS_VIEW_CLASS, view, start_renaming_file, (view, new_file, FALSE));
 
1802
                nautilus_view_reveal_selection (view);
 
1803
        }
 
1804
 
 
1805
        return FALSE;
 
1806
}
 
1807
 
 
1808
static void
 
1809
delayed_rename_file_hack_removed (RenameData *data)
 
1810
{
 
1811
        g_object_unref (data->view);
 
1812
        nautilus_file_unref (data->new_file);
 
1813
        g_free (data);
 
1814
}
 
1815
 
 
1816
 
 
1817
static void
 
1818
rename_file (NautilusView *view, NautilusFile *new_file)
 
1819
{
 
1820
        RenameData *data;
 
1821
 
 
1822
        /* HACK!!!!
 
1823
           This is a work around bug in listview. After the rename is
 
1824
           enabled we will get file changes due to info about the new
 
1825
           file being read, which will cause the model to change. When
 
1826
           the model changes GtkTreeView clears the editing. This hack just
 
1827
           delays editing for some time to try to avoid this problem.
 
1828
           A major problem is that the selection of the row causes us
 
1829
           to load the slow mimetype for the file, which leads to a
 
1830
           file_changed. So, before we delay we select the row.
 
1831
        */
 
1832
        if (NAUTILUS_IS_LIST_VIEW (view)) {
 
1833
                nautilus_view_select_file (view, new_file);
 
1834
                
 
1835
                data = g_new (RenameData, 1);
 
1836
                data->view = g_object_ref (view);
 
1837
                data->new_file = nautilus_file_ref (new_file);
 
1838
                if (view->details->delayed_rename_file_id != 0) {
 
1839
                        g_source_remove (view->details->delayed_rename_file_id);
 
1840
                }
 
1841
                view->details->delayed_rename_file_id = 
 
1842
                        g_timeout_add_full (G_PRIORITY_DEFAULT,
 
1843
                                            100, (GSourceFunc)delayed_rename_file_hack_callback,
 
1844
                                            data, (GDestroyNotify) delayed_rename_file_hack_removed);
 
1845
                
 
1846
                return;
 
1847
        }
 
1848
 
 
1849
        /* no need to select because start_renaming_file selects
 
1850
         * nautilus_view_select_file (view, new_file);
 
1851
         */
 
1852
        EEL_CALL_METHOD (NAUTILUS_VIEW_CLASS, view, start_renaming_file, (view, new_file, FALSE));
 
1853
        nautilus_view_reveal_selection (view);
 
1854
}
 
1855
 
 
1856
static void
 
1857
reveal_newly_added_folder (NautilusView *view, NautilusFile *new_file,
 
1858
                           NautilusDirectory *directory, GFile *target_location)
 
1859
{
 
1860
        GFile *location;
 
1861
 
 
1862
        location = nautilus_file_get_location (new_file);
 
1863
        if (g_file_equal (location, target_location)) {
 
1864
                g_signal_handlers_disconnect_by_func (view,
 
1865
                                                      G_CALLBACK (reveal_newly_added_folder),
 
1866
                                                      (void *) target_location);
 
1867
                rename_file (view, new_file);
 
1868
        }
 
1869
        g_object_unref (location);
 
1870
}
 
1871
 
 
1872
typedef struct {
 
1873
        NautilusView *directory_view;
 
1874
        GHashTable *added_locations;
 
1875
} NewFolderData;
 
1876
 
 
1877
 
 
1878
static void
 
1879
track_newly_added_locations (NautilusView *view, NautilusFile *new_file,
 
1880
                             NautilusDirectory *directory, gpointer user_data)
 
1881
{
 
1882
        NewFolderData *data;
 
1883
 
 
1884
        data = user_data;
 
1885
 
 
1886
        g_hash_table_insert (data->added_locations, nautilus_file_get_location (new_file), NULL);
 
1887
}
 
1888
 
 
1889
static void
 
1890
new_folder_done (GFile *new_folder, gpointer user_data)
 
1891
{
 
1892
        NautilusView *directory_view;
 
1893
        NautilusFile *file;
 
1894
        char screen_string[32];
 
1895
        GdkScreen *screen;
 
1896
        NewFolderData *data;
 
1897
 
 
1898
        data = (NewFolderData *)user_data;
 
1899
 
 
1900
        directory_view = data->directory_view;
 
1901
 
 
1902
        if (directory_view == NULL) {
 
1903
                goto fail;
 
1904
        }
 
1905
 
 
1906
        g_signal_handlers_disconnect_by_func (directory_view,
 
1907
                                              G_CALLBACK (track_newly_added_locations),
 
1908
                                              (void *) data);
 
1909
 
 
1910
        if (new_folder == NULL) {
 
1911
                goto fail;
 
1912
        }
 
1913
        
 
1914
        screen = gtk_widget_get_screen (GTK_WIDGET (directory_view));
 
1915
        g_snprintf (screen_string, sizeof (screen_string), "%d", gdk_screen_get_number (screen));
 
1916
 
 
1917
        
 
1918
        file = nautilus_file_get (new_folder);
 
1919
        nautilus_file_set_metadata
 
1920
                (file, NAUTILUS_METADATA_KEY_SCREEN,
 
1921
                 NULL,
 
1922
                 screen_string);
 
1923
 
 
1924
        if (g_hash_table_lookup_extended (data->added_locations, new_folder, NULL, NULL)) {
 
1925
                /* The file was already added */
 
1926
                rename_file (directory_view, file);
 
1927
        } else {
 
1928
                /* We need to run after the default handler adds the folder we want to
 
1929
                 * operate on. The ADD_FILE signal is registered as G_SIGNAL_RUN_LAST, so we
 
1930
                 * must use connect_after.
 
1931
                 */
 
1932
                g_signal_connect_data (directory_view,
 
1933
                                       "add_file",
 
1934
                                       G_CALLBACK (reveal_newly_added_folder),
 
1935
                                       g_object_ref (new_folder),
 
1936
                                       (GClosureNotify)g_object_unref,
 
1937
                                       G_CONNECT_AFTER);
 
1938
        }
 
1939
        nautilus_file_unref (file);
 
1940
 
 
1941
 fail:
 
1942
        g_hash_table_destroy (data->added_locations);
 
1943
        eel_remove_weak_pointer (&data->directory_view);
 
1944
        g_free (data);
 
1945
}
 
1946
 
 
1947
 
 
1948
static NewFolderData *
 
1949
new_folder_data_new (NautilusView *directory_view)
 
1950
{
 
1951
        NewFolderData *data;
 
1952
 
 
1953
        data = g_new (NewFolderData, 1);
 
1954
        data->directory_view = directory_view;
 
1955
        data->added_locations = g_hash_table_new_full (g_file_hash, (GEqualFunc)g_file_equal,
 
1956
                                                       g_object_unref, NULL);
 
1957
        eel_add_weak_pointer (&data->directory_view);
 
1958
 
 
1959
        return data;
 
1960
}
 
1961
 
 
1962
static GdkPoint *
 
1963
context_menu_to_file_operation_position (NautilusView *directory_view)
 
1964
{
 
1965
        g_return_val_if_fail (NAUTILUS_IS_VIEW (directory_view), NULL);
 
1966
 
 
1967
        if (nautilus_view_using_manual_layout (directory_view)
 
1968
            && directory_view->details->context_menu_position.x >= 0
 
1969
            && directory_view->details->context_menu_position.y >= 0) {
 
1970
                EEL_CALL_METHOD (NAUTILUS_VIEW_CLASS, directory_view,
 
1971
                                 widget_to_file_operation_position,
 
1972
                                 (directory_view, &directory_view->details->context_menu_position));
 
1973
                return &directory_view->details->context_menu_position;
 
1974
        } else {
 
1975
                return NULL;
 
1976
        }
 
1977
}
 
1978
 
 
1979
static void
 
1980
nautilus_view_new_folder (NautilusView *directory_view)
 
1981
{
 
1982
        char *parent_uri;
 
1983
        NewFolderData *data;
 
1984
        GdkPoint *pos;
 
1985
 
 
1986
        data = new_folder_data_new (directory_view);
 
1987
 
 
1988
        g_signal_connect_data (directory_view,
 
1989
                               "add_file",
 
1990
                               G_CALLBACK (track_newly_added_locations),
 
1991
                               data,
 
1992
                               (GClosureNotify)NULL,
 
1993
                               G_CONNECT_AFTER);
 
1994
 
 
1995
        pos = context_menu_to_file_operation_position (directory_view);
 
1996
 
 
1997
        parent_uri = nautilus_view_get_backing_uri (directory_view);
 
1998
        nautilus_file_operations_new_folder (GTK_WIDGET (directory_view),
 
1999
                                             pos, parent_uri,
 
2000
                                             new_folder_done, data);
 
2001
 
 
2002
        g_free (parent_uri);
 
2003
}
 
2004
 
 
2005
static NewFolderData *
 
2006
setup_new_folder_data (NautilusView *directory_view)
 
2007
{
 
2008
        NewFolderData *data;
 
2009
 
 
2010
        data = new_folder_data_new (directory_view);
 
2011
 
 
2012
        g_signal_connect_data (directory_view,
 
2013
                               "add_file",
 
2014
                               G_CALLBACK (track_newly_added_locations),
 
2015
                               data,
 
2016
                               (GClosureNotify)NULL,
 
2017
                               G_CONNECT_AFTER);
 
2018
 
 
2019
        return data;
 
2020
}
 
2021
 
 
2022
void
 
2023
nautilus_view_new_file_with_initial_contents (NautilusView *view,
 
2024
                                              const char *parent_uri,
 
2025
                                              const char *filename,
 
2026
                                              const char *initial_contents,
 
2027
                                              int length,
 
2028
                                              GdkPoint *pos)
 
2029
{
 
2030
        NewFolderData *data;
 
2031
 
 
2032
        g_assert (parent_uri != NULL);
 
2033
 
 
2034
        data = setup_new_folder_data (view);
 
2035
 
 
2036
        if (pos == NULL) {
 
2037
                pos = context_menu_to_file_operation_position (view);
 
2038
        }
 
2039
 
 
2040
        nautilus_file_operations_new_file (GTK_WIDGET (view),
 
2041
                                           pos, parent_uri, filename,
 
2042
                                           initial_contents, length,
 
2043
                                           new_folder_done, data);
 
2044
}
 
2045
 
 
2046
static void
 
2047
nautilus_view_new_file (NautilusView *directory_view,
 
2048
                        const char *parent_uri,
 
2049
                        NautilusFile *source)
 
2050
{
 
2051
        GdkPoint *pos;
 
2052
        NewFolderData *data;
 
2053
        char *source_uri;
 
2054
        char *container_uri;
 
2055
 
 
2056
        container_uri = NULL;
 
2057
        if (parent_uri == NULL) {
 
2058
                container_uri = nautilus_view_get_backing_uri (directory_view);
 
2059
                g_assert (container_uri != NULL);
 
2060
        }
 
2061
 
 
2062
        if (source == NULL) {
 
2063
                nautilus_view_new_file_with_initial_contents (directory_view,
 
2064
                                                              parent_uri != NULL ? parent_uri : container_uri,
 
2065
                                                              NULL,
 
2066
                                                              NULL,
 
2067
                                                              0,
 
2068
                                                              NULL);
 
2069
                g_free (container_uri);
 
2070
                return;
 
2071
        }
 
2072
 
 
2073
        g_return_if_fail (nautilus_file_is_local (source));
 
2074
 
 
2075
        pos = context_menu_to_file_operation_position (directory_view);
 
2076
 
 
2077
        data = setup_new_folder_data (directory_view);
 
2078
 
 
2079
        source_uri = nautilus_file_get_uri (source);
 
2080
 
 
2081
        nautilus_file_operations_new_file_from_template (GTK_WIDGET (directory_view),
 
2082
                                                         pos,
 
2083
                                                         parent_uri != NULL ? parent_uri : container_uri,
 
2084
                                                         NULL,
 
2085
                                                         source_uri,
 
2086
                                                         new_folder_done, data);
 
2087
 
 
2088
        g_free (source_uri);
 
2089
        g_free (container_uri);
 
2090
}
 
2091
 
 
2092
static void
 
2093
action_new_folder_callback (GtkAction *action,
 
2094
                            gpointer callback_data)
 
2095
{                
 
2096
        g_assert (NAUTILUS_IS_VIEW (callback_data));
 
2097
 
 
2098
        nautilus_view_new_folder (NAUTILUS_VIEW (callback_data));
 
2099
}
 
2100
 
 
2101
static void
 
2102
action_new_empty_file_callback (GtkAction *action,
 
2103
                                gpointer callback_data)
 
2104
{                
 
2105
        g_assert (NAUTILUS_IS_VIEW (callback_data));
 
2106
 
 
2107
        nautilus_view_new_file (NAUTILUS_VIEW (callback_data), NULL, NULL);
 
2108
}
 
2109
 
 
2110
static void
 
2111
action_new_launcher_callback (GtkAction *action,
 
2112
                              gpointer callback_data)
 
2113
{
 
2114
        char *parent_uri;
 
2115
        NautilusView *view;
 
2116
        GtkWindow *window;
 
2117
 
 
2118
        g_assert (NAUTILUS_IS_VIEW (callback_data));
 
2119
 
 
2120
        view = NAUTILUS_VIEW (callback_data);
 
2121
 
 
2122
        parent_uri = nautilus_view_get_backing_uri (view);
 
2123
 
 
2124
        window = nautilus_view_get_containing_window (view);
 
2125
        DEBUG ("Create new launcher in window=%p: %s", window, parent_uri);
 
2126
        nautilus_launch_application_from_command (gtk_widget_get_screen (GTK_WIDGET (view)),
 
2127
                                                  "gnome-desktop-item-edit",
 
2128
                                                  FALSE,
 
2129
                                                  "--create-new", parent_uri, NULL);
 
2130
 
 
2131
        g_free (parent_uri);
 
2132
}
 
2133
 
 
2134
static void
 
2135
action_properties_callback (GtkAction *action,
 
2136
                            gpointer callback_data)
 
2137
{
 
2138
        NautilusView *view;
 
2139
        GList *selection;
 
2140
        GList *files;
 
2141
        
 
2142
        g_assert (NAUTILUS_IS_VIEW (callback_data));
 
2143
 
 
2144
        view = NAUTILUS_VIEW (callback_data);
 
2145
        selection = nautilus_view_get_selection (view);
 
2146
        if (g_list_length (selection) == 0) {
 
2147
                if (view->details->directory_as_file != NULL) {
 
2148
                        files = g_list_append (NULL, nautilus_file_ref (view->details->directory_as_file));
 
2149
 
 
2150
                        nautilus_properties_window_present (files, GTK_WIDGET (view));
 
2151
 
 
2152
                        nautilus_file_list_free (files);
 
2153
                }
 
2154
        } else {
 
2155
                nautilus_properties_window_present (selection, GTK_WIDGET (view));
 
2156
        }
 
2157
        nautilus_file_list_free (selection);
 
2158
}
 
2159
 
 
2160
static void
 
2161
action_location_properties_callback (GtkAction *action,
 
2162
                                     gpointer   callback_data)
 
2163
{
 
2164
        NautilusView *view;
 
2165
        GList           *files;
 
2166
 
 
2167
        g_assert (NAUTILUS_IS_VIEW (callback_data));
 
2168
 
 
2169
        view = NAUTILUS_VIEW (callback_data);
 
2170
        g_assert (NAUTILUS_IS_FILE (view->details->location_popup_directory_as_file));
 
2171
 
 
2172
        files = g_list_append (NULL, nautilus_file_ref (view->details->location_popup_directory_as_file));
 
2173
 
 
2174
        nautilus_properties_window_present (files, GTK_WIDGET (view));
 
2175
 
 
2176
        nautilus_file_list_free (files);
 
2177
}
 
2178
 
 
2179
static gboolean
 
2180
all_files_in_trash (GList *files)
 
2181
{
 
2182
        GList *node;
 
2183
 
 
2184
        /* Result is ambiguous if called on NULL, so disallow. */
 
2185
        g_return_val_if_fail (files != NULL, FALSE);
 
2186
 
 
2187
        for (node = files; node != NULL; node = node->next) {
 
2188
                if (!nautilus_file_is_in_trash (NAUTILUS_FILE (node->data))) {
 
2189
                        return FALSE;
 
2190
                }
 
2191
        }
 
2192
 
 
2193
        return TRUE;
 
2194
}
 
2195
 
 
2196
static gboolean
 
2197
all_selected_items_in_trash (NautilusView *view)
 
2198
{
 
2199
        GList *selection;
 
2200
        gboolean result;
 
2201
 
 
2202
        /* If the contents share a parent directory, we need only
 
2203
         * check that parent directory. Otherwise we have to inspect
 
2204
         * each selected item.
 
2205
         */
 
2206
        selection = nautilus_view_get_selection (view);
 
2207
        result = (selection == NULL) ? FALSE : all_files_in_trash (selection);
 
2208
        nautilus_file_list_free (selection);
 
2209
 
 
2210
        return result;
 
2211
}
 
2212
 
 
2213
static gboolean
 
2214
we_are_in_vfolder_desktop_dir (NautilusView *view)
 
2215
{
 
2216
        NautilusFile *file;
 
2217
        char *mime_type;
 
2218
 
 
2219
        g_return_val_if_fail (NAUTILUS_IS_VIEW (view), FALSE);
 
2220
 
 
2221
        if (view->details->model == NULL) {
 
2222
                return FALSE;
 
2223
        }
 
2224
 
 
2225
        file = nautilus_directory_get_corresponding_file (view->details->model);
 
2226
        mime_type = nautilus_file_get_mime_type (file);
 
2227
        nautilus_file_unref (file);
 
2228
 
 
2229
        if (mime_type != NULL
 
2230
            && strcmp (mime_type, "x-directory/vfolder-desktop") == 0) {
 
2231
                g_free (mime_type);
 
2232
                return TRUE;
 
2233
        } else {
 
2234
                g_free (mime_type);
 
2235
                return FALSE;
 
2236
        }
 
2237
}
 
2238
 
 
2239
static void
 
2240
click_policy_changed_callback (gpointer callback_data)
 
2241
{
 
2242
        NautilusView *view;
 
2243
 
 
2244
        view = NAUTILUS_VIEW (callback_data);
 
2245
 
 
2246
        EEL_CALL_METHOD
 
2247
                (NAUTILUS_VIEW_CLASS, view,
 
2248
                 click_policy_changed, (view));
 
2249
}
 
2250
 
 
2251
gboolean
 
2252
nautilus_view_should_sort_directories_first (NautilusView *view)
 
2253
{
 
2254
        return view->details->sort_directories_first;
 
2255
}
 
2256
 
 
2257
static void
 
2258
sort_directories_first_changed_callback (gpointer callback_data)
 
2259
{
 
2260
        NautilusView *view;
 
2261
        gboolean preference_value;
 
2262
 
 
2263
        view = NAUTILUS_VIEW (callback_data);
 
2264
 
 
2265
        preference_value =
 
2266
                g_settings_get_boolean (nautilus_preferences, NAUTILUS_PREFERENCES_SORT_DIRECTORIES_FIRST);
 
2267
 
 
2268
        if (preference_value != view->details->sort_directories_first) {
 
2269
                view->details->sort_directories_first = preference_value;
 
2270
                EEL_CALL_METHOD
 
2271
                        (NAUTILUS_VIEW_CLASS, view,
 
2272
                         sort_directories_first_changed, (view));
 
2273
        }
 
2274
}
 
2275
 
 
2276
static gboolean
 
2277
set_up_scripts_directory_global (void)
 
2278
{
 
2279
        char *scripts_directory_path;
 
2280
        const char *override;
 
2281
 
 
2282
        if (scripts_directory_uri != NULL) {
 
2283
                return TRUE;
 
2284
        }
 
2285
 
 
2286
        override = g_getenv ("GNOME22_USER_DIR");
 
2287
 
 
2288
        if (override) {
 
2289
                scripts_directory_path = g_build_filename (override,
 
2290
                                                           "nautilus-scripts",
 
2291
                                                           NULL);
 
2292
        } else {
 
2293
                scripts_directory_path = g_build_filename (g_get_home_dir (),
 
2294
                                                           ".gnome2",
 
2295
                                                           "nautilus-scripts",
 
2296
                                                           NULL);
 
2297
        }
 
2298
 
 
2299
        if (g_mkdir_with_parents (scripts_directory_path, 0755) == 0) {
 
2300
                scripts_directory_uri = g_filename_to_uri (scripts_directory_path, NULL, NULL);
 
2301
                scripts_directory_uri_length = strlen (scripts_directory_uri);
 
2302
        }
 
2303
 
 
2304
        g_free (scripts_directory_path);
 
2305
 
 
2306
        return (scripts_directory_uri != NULL) ? TRUE : FALSE;
 
2307
}
 
2308
 
 
2309
static void
 
2310
scripts_added_or_changed_callback (NautilusDirectory *directory,
 
2311
                                   GList *files,
 
2312
                                   gpointer callback_data)
 
2313
{
 
2314
        NautilusView *view;
 
2315
 
 
2316
        view = NAUTILUS_VIEW (callback_data);
 
2317
 
 
2318
        view->details->scripts_invalid = TRUE;
 
2319
        if (view->details->active) {
 
2320
                schedule_update_menus (view);
 
2321
        }
 
2322
}
 
2323
 
 
2324
static void
 
2325
templates_added_or_changed_callback (NautilusDirectory *directory,
 
2326
                                     GList *files,
 
2327
                                     gpointer callback_data)
 
2328
{
 
2329
        NautilusView *view;
 
2330
 
 
2331
        view = NAUTILUS_VIEW (callback_data);
 
2332
 
 
2333
        view->details->templates_invalid = TRUE;
 
2334
        if (view->details->active) {
 
2335
                schedule_update_menus (view);
 
2336
        }
 
2337
}
 
2338
 
 
2339
static void
 
2340
add_directory_to_directory_list (NautilusView *view,
 
2341
                                 NautilusDirectory *directory,
 
2342
                                 GList **directory_list,
 
2343
                                 GCallback changed_callback)
 
2344
{
 
2345
        NautilusFileAttributes attributes;
 
2346
 
 
2347
        if (g_list_find (*directory_list, directory) == NULL) {
 
2348
                nautilus_directory_ref (directory);
 
2349
 
 
2350
                attributes =
 
2351
                        NAUTILUS_FILE_ATTRIBUTES_FOR_ICON |
 
2352
                        NAUTILUS_FILE_ATTRIBUTE_INFO |
 
2353
                        NAUTILUS_FILE_ATTRIBUTE_DIRECTORY_ITEM_COUNT;
 
2354
 
 
2355
                nautilus_directory_file_monitor_add (directory, directory_list,
 
2356
                                                     FALSE, attributes,
 
2357
                                                     (NautilusDirectoryCallback)changed_callback, view);
 
2358
 
 
2359
                g_signal_connect_object (directory, "files_added",
 
2360
                                         G_CALLBACK (changed_callback), view, 0);
 
2361
                g_signal_connect_object (directory, "files_changed",
 
2362
                                         G_CALLBACK (changed_callback), view, 0);
 
2363
 
 
2364
                *directory_list = g_list_append (*directory_list, directory);
 
2365
        }
 
2366
}
 
2367
 
 
2368
static void
 
2369
remove_directory_from_directory_list (NautilusView *view,
 
2370
                                      NautilusDirectory *directory,
 
2371
                                      GList **directory_list,
 
2372
                                      GCallback changed_callback)
 
2373
{
 
2374
        *directory_list = g_list_remove (*directory_list, directory);
 
2375
 
 
2376
        g_signal_handlers_disconnect_by_func (directory,
 
2377
                                              G_CALLBACK (changed_callback),
 
2378
                                              view);
 
2379
 
 
2380
        nautilus_directory_file_monitor_remove (directory, directory_list);
 
2381
 
 
2382
        nautilus_directory_unref (directory);
 
2383
}
 
2384
 
 
2385
 
 
2386
static void
 
2387
add_directory_to_scripts_directory_list (NautilusView *view,
 
2388
                                         NautilusDirectory *directory)
 
2389
{
 
2390
        add_directory_to_directory_list (view, directory,
 
2391
                                         &view->details->scripts_directory_list,
 
2392
                                         G_CALLBACK (scripts_added_or_changed_callback));
 
2393
}
 
2394
 
 
2395
static void
 
2396
remove_directory_from_scripts_directory_list (NautilusView *view,
 
2397
                                              NautilusDirectory *directory)
 
2398
{
 
2399
        remove_directory_from_directory_list (view, directory,
 
2400
                                              &view->details->scripts_directory_list,
 
2401
                                              G_CALLBACK (scripts_added_or_changed_callback));
 
2402
}
 
2403
 
 
2404
static void
 
2405
add_directory_to_templates_directory_list (NautilusView *view,
 
2406
                                           NautilusDirectory *directory)
 
2407
{
 
2408
        add_directory_to_directory_list (view, directory,
 
2409
                                         &view->details->templates_directory_list,
 
2410
                                         G_CALLBACK (templates_added_or_changed_callback));
 
2411
}
 
2412
 
 
2413
static void
 
2414
remove_directory_from_templates_directory_list (NautilusView *view,
 
2415
                                                NautilusDirectory *directory)
 
2416
{
 
2417
        remove_directory_from_directory_list (view, directory,
 
2418
                                              &view->details->templates_directory_list,
 
2419
                                              G_CALLBACK (templates_added_or_changed_callback));
 
2420
}
 
2421
 
 
2422
static void
 
2423
slot_active (NautilusWindowSlot *slot,
 
2424
             NautilusView *view)
 
2425
{
 
2426
        g_assert (!view->details->active);
 
2427
        view->details->active = TRUE;
 
2428
 
 
2429
        nautilus_view_merge_menus (view);
 
2430
        schedule_update_menus (view);
 
2431
}
 
2432
 
 
2433
static void
 
2434
slot_inactive (NautilusWindowSlot *slot,
 
2435
               NautilusView *view)
 
2436
{
 
2437
        g_assert (view->details->active ||
 
2438
                  gtk_widget_get_parent (GTK_WIDGET (view)) == NULL);
 
2439
        view->details->active = FALSE;
 
2440
 
 
2441
        nautilus_view_unmerge_menus (view);
 
2442
        remove_update_menus_timeout_callback (view);
 
2443
}
 
2444
 
 
2445
void
 
2446
nautilus_view_grab_focus (NautilusView *view)
 
2447
{
 
2448
        /* focus the child of the scrolled window if it exists */
 
2449
        GtkWidget *child;
 
2450
        child = gtk_bin_get_child (GTK_BIN (view));
 
2451
        if (child) {
 
2452
                gtk_widget_grab_focus (GTK_WIDGET (child));
 
2453
        }
 
2454
}
 
2455
 
 
2456
int
 
2457
nautilus_view_get_selection_count (NautilusView *view)
 
2458
{
 
2459
        /* FIXME: This could be faster if we special cased it in subclasses */
 
2460
        GList *files;
 
2461
        int len;
 
2462
 
 
2463
        files = nautilus_view_get_selection (NAUTILUS_VIEW (view));
 
2464
        len = g_list_length (files);
 
2465
        nautilus_file_list_free (files);
 
2466
        
 
2467
        return len;
 
2468
}
 
2469
 
 
2470
void
 
2471
nautilus_view_set_selection (NautilusView *nautilus_view,
 
2472
                             GList *selection)
 
2473
{
 
2474
        NautilusView *view;
 
2475
 
 
2476
        view = NAUTILUS_VIEW (nautilus_view);
 
2477
 
 
2478
        if (!view->details->loading) {
 
2479
                /* If we aren't still loading, set the selection right now,
 
2480
                 * and reveal the new selection.
 
2481
                 */
 
2482
                view->details->selection_change_is_due_to_shell = TRUE;
 
2483
                nautilus_view_call_set_selection (view, selection);
 
2484
                view->details->selection_change_is_due_to_shell = FALSE;
 
2485
                nautilus_view_reveal_selection (view);
 
2486
        } else {
 
2487
                /* If we are still loading, set the list of pending URIs instead.
 
2488
                 * done_loading() will eventually select the pending URIs and reveal them.
 
2489
                 */
 
2490
                g_list_free_full (view->details->pending_selection, g_object_unref);
 
2491
                view->details->pending_selection =
 
2492
                        eel_g_object_list_copy (selection);
 
2493
        }
 
2494
}
 
2495
 
 
2496
static char *
 
2497
get_bulk_rename_tool ()
 
2498
{
 
2499
        char *bulk_rename_tool;
 
2500
        g_settings_get (nautilus_preferences, NAUTILUS_PREFERENCES_BULK_RENAME_TOOL, "^ay", &bulk_rename_tool);
 
2501
        return g_strstrip (bulk_rename_tool);
 
2502
}
 
2503
 
 
2504
static gboolean
 
2505
have_bulk_rename_tool ()
 
2506
{
 
2507
        char *bulk_rename_tool;
 
2508
        gboolean have_tool;
 
2509
 
 
2510
        bulk_rename_tool = get_bulk_rename_tool ();
 
2511
        have_tool = ((bulk_rename_tool != NULL) && (*bulk_rename_tool != '\0'));
 
2512
        g_free (bulk_rename_tool);
 
2513
        return have_tool;
 
2514
}
 
2515
 
 
2516
static void
 
2517
nautilus_view_init (NautilusView *view)
 
2518
{
 
2519
        NautilusDirectory *scripts_directory;
 
2520
        NautilusDirectory *templates_directory;
 
2521
        char *templates_uri;
 
2522
 
 
2523
        view->details = g_new0 (NautilusViewDetails, 1);
 
2524
 
 
2525
        /* Default to true; desktop-icon-view sets to false */
 
2526
        view->details->show_foreign_files = TRUE;
 
2527
 
 
2528
        view->details->non_ready_files =
 
2529
                g_hash_table_new_full (file_and_directory_hash,
 
2530
                                       file_and_directory_equal,
 
2531
                                       (GDestroyNotify)file_and_directory_free,
 
2532
                                       NULL);
 
2533
 
 
2534
        gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (view),
 
2535
                                        GTK_POLICY_AUTOMATIC,
 
2536
                                        GTK_POLICY_AUTOMATIC);
 
2537
        gtk_scrolled_window_set_hadjustment (GTK_SCROLLED_WINDOW (view), NULL);
 
2538
        gtk_scrolled_window_set_vadjustment (GTK_SCROLLED_WINDOW (view), NULL);
 
2539
        gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (view), GTK_SHADOW_NONE);
 
2540
 
 
2541
        gtk_style_context_set_junction_sides (gtk_widget_get_style_context (GTK_WIDGET (view)),
 
2542
                                              GTK_JUNCTION_TOP | GTK_JUNCTION_LEFT);
 
2543
 
 
2544
        if (set_up_scripts_directory_global ()) {
 
2545
                scripts_directory = nautilus_directory_get_by_uri (scripts_directory_uri);
 
2546
                add_directory_to_scripts_directory_list (view, scripts_directory);
 
2547
                nautilus_directory_unref (scripts_directory);
 
2548
        } else {
 
2549
                g_warning ("Ignoring scripts directory, it may be a broken link\n");
 
2550
        }
 
2551
 
 
2552
        if (nautilus_should_use_templates_directory ()) {
 
2553
                templates_uri = nautilus_get_templates_directory_uri ();
 
2554
                templates_directory = nautilus_directory_get_by_uri (templates_uri);
 
2555
                g_free (templates_uri);
 
2556
                add_directory_to_templates_directory_list (view, templates_directory);
 
2557
                nautilus_directory_unref (templates_directory);
 
2558
        }
 
2559
        update_templates_directory (view);
 
2560
        g_signal_connect_object (nautilus_signaller_get_current (),
 
2561
                                 "user_dirs_changed",
 
2562
                                 G_CALLBACK (user_dirs_changed),
 
2563
                                 view, G_CONNECT_SWAPPED);
 
2564
 
 
2565
        view->details->sort_directories_first =
 
2566
                g_settings_get_boolean (nautilus_preferences, NAUTILUS_PREFERENCES_SORT_DIRECTORIES_FIRST);
 
2567
 
 
2568
        g_signal_connect_object (nautilus_trash_monitor_get (), "trash_state_changed",
 
2569
                                 G_CALLBACK (nautilus_view_trash_state_changed_callback), view, 0);
 
2570
 
 
2571
        /* React to clipboard changes */
 
2572
        g_signal_connect_object (nautilus_clipboard_monitor_get (), "clipboard_changed",
 
2573
                                 G_CALLBACK (clipboard_changed_callback), view, 0);
 
2574
 
 
2575
        /* Register to menu provider extension signal managing menu updates */
 
2576
        g_signal_connect_object (nautilus_signaller_get_current (), "popup_menu_changed",
 
2577
                                 G_CALLBACK (nautilus_view_update_menus), view, G_CONNECT_SWAPPED);
 
2578
 
 
2579
        gtk_widget_show (GTK_WIDGET (view));
 
2580
 
 
2581
        g_signal_connect_swapped (nautilus_preferences,
 
2582
                                  "changed::" NAUTILUS_PREFERENCES_ENABLE_DELETE,
 
2583
                                  G_CALLBACK (schedule_update_menus_callback), view);
 
2584
        g_signal_connect_swapped (nautilus_preferences,
 
2585
                                  "changed::" NAUTILUS_PREFERENCES_CLICK_POLICY,
 
2586
                                  G_CALLBACK(click_policy_changed_callback),
 
2587
                                  view);
 
2588
        g_signal_connect_swapped (nautilus_preferences,
 
2589
                                  "changed::" NAUTILUS_PREFERENCES_SORT_DIRECTORIES_FIRST, 
 
2590
                                  G_CALLBACK(sort_directories_first_changed_callback), view);
 
2591
        g_signal_connect_swapped (gnome_lockdown_preferences,
 
2592
                                  "changed::" NAUTILUS_PREFERENCES_LOCKDOWN_COMMAND_LINE,
 
2593
                                  G_CALLBACK (schedule_update_menus), view);
 
2594
 
 
2595
        g_signal_connect_swapped (nautilus_window_state,
 
2596
                                  "changed::" NAUTILUS_WINDOW_STATE_START_WITH_STATUS_BAR,
 
2597
                                  G_CALLBACK (nautilus_view_display_selection_info), view);
 
2598
}
 
2599
 
 
2600
static void
 
2601
real_unmerge_menus (NautilusView *view)
 
2602
{
 
2603
        GtkUIManager *ui_manager;
 
2604
 
 
2605
        if (view->details->window == NULL) {
 
2606
                return;
 
2607
        }
 
2608
 
 
2609
        ui_manager = nautilus_window_get_ui_manager (view->details->window);
 
2610
 
 
2611
        nautilus_ui_unmerge_ui (ui_manager,
 
2612
                                &view->details->dir_merge_id,
 
2613
                                &view->details->dir_action_group);
 
2614
        nautilus_ui_unmerge_ui (ui_manager,
 
2615
                                &view->details->extensions_menu_merge_id,
 
2616
                                &view->details->extensions_menu_action_group);
 
2617
        nautilus_ui_unmerge_ui (ui_manager,
 
2618
                                &view->details->open_with_merge_id,
 
2619
                                &view->details->open_with_action_group);
 
2620
        nautilus_ui_unmerge_ui (ui_manager,
 
2621
                                &view->details->scripts_merge_id,
 
2622
                                &view->details->scripts_action_group);
 
2623
        nautilus_ui_unmerge_ui (ui_manager,
 
2624
                                &view->details->templates_merge_id,
 
2625
                                &view->details->templates_action_group);
 
2626
}
 
2627
 
 
2628
static void
 
2629
nautilus_view_destroy (GtkWidget *object)
 
2630
{
 
2631
        NautilusView *view;
 
2632
        GList *node, *next;
 
2633
 
 
2634
        view = NAUTILUS_VIEW (object);
 
2635
 
 
2636
        disconnect_model_handlers (view);
 
2637
 
 
2638
        nautilus_view_unmerge_menus (view);
 
2639
        
 
2640
        /* We don't own the window, so no unref */
 
2641
        view->details->slot = NULL;
 
2642
        view->details->window = NULL;
 
2643
        
 
2644
        nautilus_view_stop_loading (view);
 
2645
 
 
2646
        for (node = view->details->scripts_directory_list; node != NULL; node = next) {
 
2647
                next = node->next;
 
2648
                remove_directory_from_scripts_directory_list (view, node->data);
 
2649
        }
 
2650
 
 
2651
        for (node = view->details->templates_directory_list; node != NULL; node = next) {
 
2652
                next = node->next;
 
2653
                remove_directory_from_templates_directory_list (view, node->data);
 
2654
        }
 
2655
 
 
2656
        while (view->details->subdirectory_list != NULL) {
 
2657
                nautilus_view_remove_subdirectory (view,
 
2658
                                                   view->details->subdirectory_list->data);
 
2659
        }
 
2660
 
 
2661
        remove_update_menus_timeout_callback (view);
 
2662
        remove_update_status_idle_callback (view);
 
2663
 
 
2664
        if (view->details->display_selection_idle_id != 0) {
 
2665
                g_source_remove (view->details->display_selection_idle_id);
 
2666
                view->details->display_selection_idle_id = 0;
 
2667
        }
 
2668
 
 
2669
        if (view->details->reveal_selection_idle_id != 0) {
 
2670
                g_source_remove (view->details->reveal_selection_idle_id);
 
2671
                view->details->reveal_selection_idle_id = 0;
 
2672
        }
 
2673
 
 
2674
        if (view->details->delayed_rename_file_id != 0) {
 
2675
                g_source_remove (view->details->delayed_rename_file_id);
 
2676
                view->details->delayed_rename_file_id = 0;
 
2677
        }
 
2678
 
 
2679
        if (view->details->model) {
 
2680
                nautilus_directory_unref (view->details->model);
 
2681
                view->details->model = NULL;
 
2682
        }
 
2683
        
 
2684
        if (view->details->directory_as_file) {
 
2685
                nautilus_file_unref (view->details->directory_as_file);
 
2686
                view->details->directory_as_file = NULL;
 
2687
        }
 
2688
 
 
2689
        EEL_CALL_PARENT (GTK_WIDGET_CLASS, destroy, (object));
 
2690
}
 
2691
 
 
2692
static void
 
2693
nautilus_view_finalize (GObject *object)
 
2694
{
 
2695
        NautilusView *view;
 
2696
 
 
2697
        view = NAUTILUS_VIEW (object);
 
2698
 
 
2699
        g_signal_handlers_disconnect_by_func (nautilus_preferences,
 
2700
                                              schedule_update_menus_callback, view);
 
2701
        g_signal_handlers_disconnect_by_func (nautilus_preferences,
 
2702
                                              click_policy_changed_callback, view);
 
2703
        g_signal_handlers_disconnect_by_func (nautilus_preferences,
 
2704
                                              sort_directories_first_changed_callback, view);
 
2705
        g_signal_handlers_disconnect_by_func (nautilus_window_state,
 
2706
                                              nautilus_view_display_selection_info, view);
 
2707
 
 
2708
        g_signal_handlers_disconnect_by_func (gnome_lockdown_preferences,
 
2709
                                              schedule_update_menus, view);
 
2710
 
 
2711
        unschedule_pop_up_location_context_menu (view);
 
2712
        if (view->details->location_popup_event != NULL) {
 
2713
                gdk_event_free ((GdkEvent *) view->details->location_popup_event);
 
2714
        }
 
2715
 
 
2716
        g_hash_table_destroy (view->details->non_ready_files);
 
2717
 
 
2718
        g_free (view->details);
 
2719
 
 
2720
        EEL_CALL_PARENT (G_OBJECT_CLASS, finalize, (object));
 
2721
}
 
2722
 
 
2723
/**
 
2724
 * nautilus_view_display_selection_info:
 
2725
 *
 
2726
 * Display information about the current selection, and notify the view frame of the changed selection.
 
2727
 * @view: NautilusView for which to display selection info.
 
2728
 *
 
2729
 **/
 
2730
void
 
2731
nautilus_view_display_selection_info (NautilusView *view)
 
2732
{
 
2733
        GList *selection;
 
2734
        goffset non_folder_size;
 
2735
        gboolean non_folder_size_known;
 
2736
        guint non_folder_count, folder_count, folder_item_count;
 
2737
        gboolean folder_item_count_known;
 
2738
        guint file_item_count;
 
2739
        GList *p;
 
2740
        char *first_item_name;
 
2741
        char *non_folder_str;
 
2742
        char *folder_count_str;
 
2743
        char *folder_item_count_str;
 
2744
        char *status_string;
 
2745
        char *view_status_string;
 
2746
        char *free_space_str;
 
2747
        char *obj_selected_free_space_str;
 
2748
        NautilusFile *file;
 
2749
 
 
2750
        g_return_if_fail (NAUTILUS_IS_VIEW (view));
 
2751
 
 
2752
        selection = nautilus_view_get_selection (view);
 
2753
        
 
2754
        folder_item_count_known = TRUE;
 
2755
        folder_count = 0;
 
2756
        folder_item_count = 0;
 
2757
        non_folder_count = 0;
 
2758
        non_folder_size_known = FALSE;
 
2759
        non_folder_size = 0;
 
2760
        first_item_name = NULL;
 
2761
        folder_count_str = NULL;
 
2762
        non_folder_str = NULL;
 
2763
        folder_item_count_str = NULL;
 
2764
        free_space_str = NULL;
 
2765
        obj_selected_free_space_str = NULL;
 
2766
        status_string = NULL;
 
2767
        view_status_string = NULL;
 
2768
        
 
2769
        for (p = selection; p != NULL; p = p->next) {
 
2770
                file = p->data;
 
2771
                if (nautilus_file_is_directory (file)) {
 
2772
                        folder_count++;
 
2773
                        if (nautilus_file_get_directory_item_count (file, &file_item_count, NULL)) {
 
2774
                                folder_item_count += file_item_count;
 
2775
                        } else {
 
2776
                                folder_item_count_known = FALSE;
 
2777
                        }
 
2778
                } else {
 
2779
                        non_folder_count++;
 
2780
                        if (!nautilus_file_can_get_size (file)) {
 
2781
                                non_folder_size_known = TRUE;
 
2782
                                non_folder_size += nautilus_file_get_size (file);
 
2783
                        }
 
2784
                }
 
2785
 
 
2786
                if (first_item_name == NULL) {
 
2787
                        first_item_name = nautilus_file_get_display_name (file);
 
2788
                }
 
2789
        }
 
2790
        
 
2791
        nautilus_file_list_free (selection);
 
2792
        
 
2793
        /* Break out cases for localization's sake. But note that there are still pieces
 
2794
         * being assembled in a particular order, which may be a problem for some localizers.
 
2795
         */
 
2796
 
 
2797
        if (folder_count != 0) {
 
2798
                if (folder_count == 1 && non_folder_count == 0) {
 
2799
                        folder_count_str = g_strdup_printf (_("\"%s\" selected"), first_item_name);
 
2800
                } else {
 
2801
                        folder_count_str = g_strdup_printf (ngettext("%'d folder selected", 
 
2802
                                                                     "%'d folders selected", 
 
2803
                                                                     folder_count), 
 
2804
                                                            folder_count);
 
2805
                }
 
2806
 
 
2807
                if (folder_count == 1) {
 
2808
                        if (!folder_item_count_known) {
 
2809
                                folder_item_count_str = g_strdup ("");
 
2810
                        } else {
 
2811
                                folder_item_count_str = g_strdup_printf (ngettext(" (containing %'d item)",
 
2812
                                                                                  " (containing %'d items)",
 
2813
                                                                                  folder_item_count), 
 
2814
                                                                         folder_item_count);
 
2815
                        }
 
2816
                }
 
2817
                else {
 
2818
                        if (!folder_item_count_known) {
 
2819
                                folder_item_count_str = g_strdup ("");
 
2820
                        } else {
 
2821
                                /* translators: this is preceded with a string of form 'N folders' (N more than 1) */
 
2822
                                folder_item_count_str = g_strdup_printf (ngettext(" (containing a total of %'d item)",
 
2823
                                                                                  " (containing a total of %'d items)",
 
2824
                                                                                  folder_item_count), 
 
2825
                                                                         folder_item_count);
 
2826
                        }
 
2827
                        
 
2828
                }
 
2829
        }
 
2830
 
 
2831
        if (non_folder_count != 0) {
 
2832
                char *items_string;
 
2833
 
 
2834
                if (folder_count == 0) {
 
2835
                        if (non_folder_count == 1) {
 
2836
                                items_string = g_strdup_printf (_("\"%s\" selected"), 
 
2837
                                                                first_item_name);
 
2838
                        } else {
 
2839
                                items_string = g_strdup_printf (ngettext("%'d item selected",
 
2840
                                                                         "%'d items selected",
 
2841
                                                                         non_folder_count), 
 
2842
                                                                non_folder_count);
 
2843
                        }
 
2844
                } else {
 
2845
                        /* Folders selected also, use "other" terminology */
 
2846
                        items_string = g_strdup_printf (ngettext("%'d other item selected",
 
2847
                                                                 "%'d other items selected",
 
2848
                                                                 non_folder_count), 
 
2849
                                                        non_folder_count);
 
2850
                }
 
2851
 
 
2852
                if (non_folder_size_known) {
 
2853
                        char *size_string;
 
2854
 
 
2855
                        size_string = g_format_size_for_display (non_folder_size);
 
2856
                        /* This is marked for translation in case a localiser
 
2857
                         * needs to use something other than parentheses. The
 
2858
                         * first message gives the number of items selected;
 
2859
                         * the message in parentheses the size of those items.
 
2860
                         */
 
2861
                        non_folder_str = g_strdup_printf (_("%s (%s)"), 
 
2862
                                                          items_string, 
 
2863
                                                          size_string);
 
2864
 
 
2865
                        g_free (size_string);
 
2866
                        g_free (items_string);
 
2867
                } else {
 
2868
                        non_folder_str = items_string;
 
2869
                }
 
2870
        }
 
2871
 
 
2872
        free_space_str = nautilus_file_get_volume_free_space (view->details->directory_as_file);
 
2873
        if (free_space_str != NULL) {
 
2874
                obj_selected_free_space_str = g_strdup_printf (_("Free space: %s"), free_space_str);
 
2875
        }
 
2876
        if (folder_count == 0 && non_folder_count == 0) {
 
2877
                char *item_count_str;
 
2878
                guint item_count;
 
2879
 
 
2880
                item_count = nautilus_view_get_item_count (view);
 
2881
                
 
2882
                item_count_str = g_strdup_printf (ngettext ("%'u item", "%'u items", item_count), item_count);
 
2883
 
 
2884
                if (free_space_str != NULL) {
 
2885
                        status_string = g_strdup_printf (_("%s, Free space: %s"), item_count_str, free_space_str);
 
2886
                        g_free (item_count_str);
 
2887
                } else {
 
2888
                        status_string = item_count_str;
 
2889
                }
 
2890
 
 
2891
        } else if (folder_count == 0) {
 
2892
                view_status_string = g_strdup (non_folder_str);
 
2893
 
 
2894
                if (free_space_str != NULL) {
 
2895
                        /* Marking this for translation, since you
 
2896
                         * might want to change "," to something else.
 
2897
                         * After the comma the amount of free space will
 
2898
                         * be shown.
 
2899
                         */
 
2900
                        status_string = g_strdup_printf (_("%s, %s"),
 
2901
                                                         non_folder_str,
 
2902
                                                         obj_selected_free_space_str);
 
2903
                }
 
2904
        } else if (non_folder_count == 0) {
 
2905
                /* No use marking this for translation, since you
 
2906
                 * can't reorder the strings, which is the main thing
 
2907
                 * you'd want to do.
 
2908
                 */
 
2909
                view_status_string = g_strdup_printf ("%s%s",
 
2910
                                                      folder_count_str,
 
2911
                                                      folder_item_count_str);
 
2912
 
 
2913
                if (free_space_str != NULL) {
 
2914
                        /* Marking this for translation, since you
 
2915
                         * might want to change "," to something else.
 
2916
                         * After the comma the amount of free space will
 
2917
                         * be shown.
 
2918
                         */
 
2919
                        status_string = g_strdup_printf (_("%s%s, %s"),
 
2920
                                                         folder_count_str,
 
2921
                                                         folder_item_count_str,
 
2922
                                                         obj_selected_free_space_str);
 
2923
                }
 
2924
        } else {
 
2925
                /* This is marked for translation in case a localizer
 
2926
                 * needs to change ", " to something else. The comma
 
2927
                 * is between the message about the number of folders
 
2928
                 * and the number of items in those folders and the
 
2929
                 * message about the number of other items and the
 
2930
                 * total size of those items.
 
2931
                 */
 
2932
                view_status_string = g_strdup_printf (_("%s%s, %s"),
 
2933
                                                      folder_count_str,
 
2934
                                                      folder_item_count_str,
 
2935
                                                      non_folder_str);
 
2936
 
 
2937
                if (obj_selected_free_space_str != NULL) {
 
2938
                        /* This is marked for translation in case a localizer
 
2939
                         * needs to change ", " to something else. The first comma
 
2940
                         * is between the message about the number of folders
 
2941
                         * and the number of items in those folders and the
 
2942
                         * message about the number of other items and the
 
2943
                         * total size of those items. After the second comma
 
2944
                         * the free space is written.
 
2945
                         */
 
2946
                        status_string = g_strdup_printf (_("%s%s, %s, %s"),
 
2947
                                                         folder_count_str,
 
2948
                                                         folder_item_count_str,
 
2949
                                                         non_folder_str,
 
2950
                                                         obj_selected_free_space_str);
 
2951
                }
 
2952
        }
 
2953
 
 
2954
        g_free (free_space_str);
 
2955
        g_free (obj_selected_free_space_str);
 
2956
        g_free (first_item_name);
 
2957
        g_free (folder_count_str);
 
2958
        g_free (folder_item_count_str);
 
2959
        g_free (non_folder_str);
 
2960
 
 
2961
        if (status_string == NULL) {
 
2962
                status_string = g_strdup (view_status_string);
 
2963
        }
 
2964
 
 
2965
        nautilus_window_slot_set_status (view->details->slot,
 
2966
                                         status_string,
 
2967
                                         view_status_string);
 
2968
 
 
2969
        g_free (status_string);
 
2970
        g_free (view_status_string);
 
2971
}
 
2972
 
 
2973
static void
 
2974
nautilus_view_send_selection_change (NautilusView *view)
 
2975
{
 
2976
        g_signal_emit (view, signals[SELECTION_CHANGED], 0);
 
2977
 
 
2978
        view->details->send_selection_change_to_shell = FALSE;
 
2979
}
 
2980
 
 
2981
void
 
2982
nautilus_view_load_location (NautilusView *nautilus_view,
 
2983
                             GFile        *location)
 
2984
{
 
2985
        NautilusDirectory *directory;
 
2986
        NautilusView *directory_view;
 
2987
 
 
2988
        directory_view = NAUTILUS_VIEW (nautilus_view);
 
2989
 
 
2990
        directory = nautilus_directory_get (location);
 
2991
        load_directory (directory_view, directory);
 
2992
        nautilus_directory_unref (directory);
 
2993
}
 
2994
 
 
2995
static gboolean
 
2996
reveal_selection_idle_callback (gpointer data)
 
2997
{
 
2998
        NautilusView *view;
 
2999
        
 
3000
        view = NAUTILUS_VIEW (data);
 
3001
 
 
3002
        view->details->reveal_selection_idle_id = 0;
 
3003
        nautilus_view_reveal_selection (view);
 
3004
 
 
3005
        return FALSE;
 
3006
}
 
3007
 
 
3008
static void
 
3009
done_loading (NautilusView *view,
 
3010
              gboolean all_files_seen)
 
3011
{
 
3012
        GList *selection;
 
3013
 
 
3014
        if (!view->details->loading) {
 
3015
                return;
 
3016
        }
 
3017
 
 
3018
        /* This can be called during destruction, in which case there
 
3019
         * is no NautilusWindow any more.
 
3020
         */
 
3021
        if (view->details->window != NULL) {
 
3022
                if (all_files_seen) {
 
3023
                        nautilus_window_report_load_complete (view->details->window, NAUTILUS_VIEW (view));
 
3024
                }
 
3025
 
 
3026
                schedule_update_menus (view);
 
3027
                schedule_update_status (view);
 
3028
                reset_update_interval (view);
 
3029
 
 
3030
                selection = view->details->pending_selection;
 
3031
                if (selection != NULL && all_files_seen) {
 
3032
                        view->details->pending_selection = NULL;
 
3033
 
 
3034
                        view->details->selection_change_is_due_to_shell = TRUE;
 
3035
                        nautilus_view_call_set_selection (view, selection);
 
3036
                        view->details->selection_change_is_due_to_shell = FALSE;
 
3037
 
 
3038
                        if (NAUTILUS_IS_LIST_VIEW (view)) {
 
3039
                                /* HACK: We should be able to directly call reveal_selection here,
 
3040
                                 * but at this point the GtkTreeView hasn't allocated the new nodes
 
3041
                                 * yet, and it has a bug in the scroll calculation dealing with this
 
3042
                                 * special case. It would always make the selection the top row, even
 
3043
                                 * if no scrolling would be neccessary to reveal it. So we let it
 
3044
                                 * allocate before revealing.
 
3045
                                 */
 
3046
                                if (view->details->reveal_selection_idle_id != 0) {
 
3047
                                        g_source_remove (view->details->reveal_selection_idle_id);
 
3048
                                }
 
3049
                                view->details->reveal_selection_idle_id = 
 
3050
                                        g_idle_add (reveal_selection_idle_callback, view);
 
3051
                        } else {
 
3052
                                nautilus_view_reveal_selection (view);
 
3053
                        }
 
3054
                }
 
3055
                g_list_free_full (selection, g_object_unref);
 
3056
                nautilus_view_display_selection_info (view);
 
3057
        }
 
3058
 
 
3059
        g_signal_emit (view, signals[END_LOADING], 0, all_files_seen);
 
3060
 
 
3061
        view->details->loading = FALSE;
 
3062
}
 
3063
 
 
3064
 
 
3065
typedef struct {
 
3066
        GHashTable *debuting_files;
 
3067
        GList      *added_files;
 
3068
} DebutingFilesData;
 
3069
 
 
3070
static void
 
3071
debuting_files_data_free (DebutingFilesData *data)
 
3072
{
 
3073
        g_hash_table_unref (data->debuting_files);
 
3074
        nautilus_file_list_free (data->added_files);
 
3075
        g_free (data);
 
3076
}
 
3077
 
 
3078
/* This signal handler watch for the arrival of the icons created
 
3079
 * as the result of a file operation. Once the last one is detected
 
3080
 * it selects and reveals them all.
 
3081
 */
 
3082
static void
 
3083
debuting_files_add_file_callback (NautilusView *view,
 
3084
                                  NautilusFile *new_file,
 
3085
                                  NautilusDirectory *directory,
 
3086
                                  DebutingFilesData *data)
 
3087
{
 
3088
        GFile *location;
 
3089
 
 
3090
        location = nautilus_file_get_location (new_file);
 
3091
 
 
3092
        if (g_hash_table_remove (data->debuting_files, location)) {
 
3093
                nautilus_file_ref (new_file);
 
3094
                data->added_files = g_list_prepend (data->added_files, new_file);
 
3095
 
 
3096
                if (g_hash_table_size (data->debuting_files) == 0) {
 
3097
                        nautilus_view_call_set_selection (view, data->added_files);
 
3098
                        nautilus_view_reveal_selection (view);
 
3099
                        g_signal_handlers_disconnect_by_func (view,
 
3100
                                                              G_CALLBACK (debuting_files_add_file_callback),
 
3101
                                                              data);
 
3102
                }
 
3103
        }
 
3104
        
 
3105
        g_object_unref (location);
 
3106
}
 
3107
 
 
3108
typedef struct {
 
3109
        GList           *added_files;
 
3110
        NautilusView *directory_view;
 
3111
} CopyMoveDoneData;
 
3112
 
 
3113
static void
 
3114
copy_move_done_data_free (CopyMoveDoneData *data)
 
3115
{
 
3116
        g_assert (data != NULL);
 
3117
        
 
3118
        eel_remove_weak_pointer (&data->directory_view);
 
3119
        nautilus_file_list_free (data->added_files);
 
3120
        g_free (data);
 
3121
}
 
3122
 
 
3123
static void
 
3124
pre_copy_move_add_file_callback (NautilusView *view,
 
3125
                                 NautilusFile *new_file,
 
3126
                                 NautilusDirectory *directory,
 
3127
                                 CopyMoveDoneData *data)
 
3128
{
 
3129
        nautilus_file_ref (new_file);
 
3130
        data->added_files = g_list_prepend (data->added_files, new_file);
 
3131
}
 
3132
 
 
3133
/* This needs to be called prior to nautilus_file_operations_copy_move.
 
3134
 * It hooks up a signal handler to catch any icons that get added before
 
3135
 * the copy_done_callback is invoked. The return value should  be passed
 
3136
 * as the data for uri_copy_move_done_callback.
 
3137
 */
 
3138
static CopyMoveDoneData *
 
3139
pre_copy_move (NautilusView *directory_view)
 
3140
{
 
3141
        CopyMoveDoneData *copy_move_done_data;
 
3142
 
 
3143
        copy_move_done_data = g_new0 (CopyMoveDoneData, 1);
 
3144
        copy_move_done_data->directory_view = directory_view;
 
3145
 
 
3146
        eel_add_weak_pointer (&copy_move_done_data->directory_view);
 
3147
 
 
3148
        /* We need to run after the default handler adds the folder we want to
 
3149
         * operate on. The ADD_FILE signal is registered as G_SIGNAL_RUN_LAST, so we
 
3150
         * must use connect_after.
 
3151
         */
 
3152
        g_signal_connect (directory_view, "add_file",
 
3153
                          G_CALLBACK (pre_copy_move_add_file_callback), copy_move_done_data);
 
3154
 
 
3155
        return copy_move_done_data;
 
3156
}
 
3157
 
 
3158
/* This function is used to pull out any debuting uris that were added
 
3159
 * and (as a side effect) remove them from the debuting uri hash table.
 
3160
 */
 
3161
static gboolean
 
3162
copy_move_done_partition_func (gpointer data, gpointer callback_data)
 
3163
{
 
3164
        GFile *location;
 
3165
        gboolean result;
 
3166
        
 
3167
        location = nautilus_file_get_location (NAUTILUS_FILE (data));
 
3168
        result = g_hash_table_remove ((GHashTable *) callback_data, location);
 
3169
        g_object_unref (location);
 
3170
 
 
3171
        return result;
 
3172
}
 
3173
 
 
3174
static gboolean
 
3175
remove_not_really_moved_files (gpointer key,
 
3176
                               gpointer value,
 
3177
                               gpointer callback_data)
 
3178
{
 
3179
        GList **added_files;
 
3180
        GFile *loc;
 
3181
 
 
3182
        loc = key;
 
3183
 
 
3184
        if (GPOINTER_TO_INT (value)) {
 
3185
                return FALSE;
 
3186
        }
 
3187
        
 
3188
        added_files = callback_data;
 
3189
        *added_files = g_list_prepend (*added_files,
 
3190
                                       nautilus_file_get (loc));
 
3191
        return TRUE;
 
3192
}
 
3193
 
 
3194
 
 
3195
/* When this function is invoked, the file operation is over, but all
 
3196
 * the icons may not have been added to the directory view yet, so
 
3197
 * we can't select them yet.
 
3198
 * 
 
3199
 * We're passed a hash table of the uri's to look out for, we hook
 
3200
 * up a signal handler to await their arrival.
 
3201
 */
 
3202
static void
 
3203
copy_move_done_callback (GHashTable *debuting_files, gpointer data)
 
3204
{
 
3205
        NautilusView  *directory_view;
 
3206
        CopyMoveDoneData *copy_move_done_data;
 
3207
        DebutingFilesData  *debuting_files_data;
 
3208
 
 
3209
        copy_move_done_data = (CopyMoveDoneData *) data;
 
3210
        directory_view = copy_move_done_data->directory_view;
 
3211
 
 
3212
        if (directory_view != NULL) {
 
3213
                g_assert (NAUTILUS_IS_VIEW (directory_view));
 
3214
        
 
3215
                debuting_files_data = g_new (DebutingFilesData, 1);
 
3216
                debuting_files_data->debuting_files = g_hash_table_ref (debuting_files);
 
3217
                debuting_files_data->added_files = eel_g_list_partition
 
3218
                        (copy_move_done_data->added_files,
 
3219
                         copy_move_done_partition_func,
 
3220
                         debuting_files,
 
3221
                         &copy_move_done_data->added_files);
 
3222
 
 
3223
                /* We're passed the same data used by pre_copy_move_add_file_callback, so disconnecting
 
3224
                 * it will free data. We've already siphoned off the added_files we need, and stashed the
 
3225
                 * directory_view pointer.
 
3226
                 */
 
3227
                g_signal_handlers_disconnect_by_func (directory_view,
 
3228
                                                      G_CALLBACK (pre_copy_move_add_file_callback),
 
3229
                                                      data);
 
3230
        
 
3231
                /* Any items in the debuting_files hash table that have
 
3232
                 * "FALSE" as their value aren't really being copied
 
3233
                 * or moved, so we can't wait for an add_file signal
 
3234
                 * to come in for those.
 
3235
                 */
 
3236
                g_hash_table_foreach_remove (debuting_files,
 
3237
                                             remove_not_really_moved_files,
 
3238
                                             &debuting_files_data->added_files);
 
3239
                
 
3240
                if (g_hash_table_size (debuting_files) == 0) {
 
3241
                        /* on the off-chance that all the icons have already been added */
 
3242
                        if (debuting_files_data->added_files != NULL) {
 
3243
                                nautilus_view_call_set_selection (directory_view,
 
3244
                                                                  debuting_files_data->added_files);
 
3245
                                nautilus_view_reveal_selection (directory_view);
 
3246
                        }
 
3247
                        debuting_files_data_free (debuting_files_data);
 
3248
                } else {
 
3249
                        /* We need to run after the default handler adds the folder we want to
 
3250
                         * operate on. The ADD_FILE signal is registered as G_SIGNAL_RUN_LAST, so we
 
3251
                         * must use connect_after.
 
3252
                         */
 
3253
                        g_signal_connect_data (directory_view,
 
3254
                                               "add_file",
 
3255
                                               G_CALLBACK (debuting_files_add_file_callback),
 
3256
                                               debuting_files_data,
 
3257
                                               (GClosureNotify) debuting_files_data_free,
 
3258
                                               G_CONNECT_AFTER);
 
3259
                }
 
3260
        }
 
3261
 
 
3262
        copy_move_done_data_free (copy_move_done_data);
 
3263
}
 
3264
 
 
3265
static gboolean
 
3266
view_file_still_belongs (NautilusView *view,
 
3267
                         NautilusFile *file,
 
3268
                         NautilusDirectory *directory)
 
3269
{
 
3270
        if (view->details->model != directory &&
 
3271
            g_list_find (view->details->subdirectory_list, directory) == NULL) {
 
3272
                return FALSE;
 
3273
        }
 
3274
        
 
3275
        return nautilus_directory_contains_file (directory, file);
 
3276
}
 
3277
 
 
3278
static gboolean
 
3279
still_should_show_file (NautilusView *view, NautilusFile *file, NautilusDirectory *directory)
 
3280
{
 
3281
        return nautilus_view_should_show_file (view, file) &&
 
3282
                view_file_still_belongs (view, file, directory);
 
3283
}
 
3284
 
 
3285
static gboolean
 
3286
ready_to_load (NautilusFile *file)
 
3287
{
 
3288
        return nautilus_file_check_if_ready (file,
 
3289
                                             NAUTILUS_FILE_ATTRIBUTES_FOR_ICON);
 
3290
}
 
3291
 
 
3292
static int
 
3293
compare_files_cover (gconstpointer a, gconstpointer b, gpointer callback_data)
 
3294
{
 
3295
        const FileAndDirectory *fad1, *fad2;
 
3296
        NautilusView *view;
 
3297
        
 
3298
        view = callback_data;
 
3299
        fad1 = a; fad2 = b;
 
3300
 
 
3301
        if (fad1->directory < fad2->directory) {
 
3302
                return -1;
 
3303
        } else if (fad1->directory > fad2->directory) {
 
3304
                return 1;
 
3305
        } else {
 
3306
                return EEL_INVOKE_METHOD (NAUTILUS_VIEW_CLASS, view, compare_files,
 
3307
                                          (view, fad1->file, fad2->file));
 
3308
        }
 
3309
}
 
3310
static void
 
3311
sort_files (NautilusView *view, GList **list)
 
3312
{
 
3313
        *list = g_list_sort_with_data (*list, compare_files_cover, view);
 
3314
        
 
3315
}
 
3316
 
 
3317
/* Go through all the new added and changed files.
 
3318
 * Put any that are not ready to load in the non_ready_files hash table.
 
3319
 * Add all the rest to the old_added_files and old_changed_files lists.
 
3320
 * Sort the old_*_files lists if anything was added to them.
 
3321
 */
 
3322
static void
 
3323
process_new_files (NautilusView *view)
 
3324
{
 
3325
        GList *new_added_files, *new_changed_files, *old_added_files, *old_changed_files;
 
3326
        GHashTable *non_ready_files;
 
3327
        GList *node, *next;
 
3328
        FileAndDirectory *pending;
 
3329
        gboolean in_non_ready;
 
3330
 
 
3331
        new_added_files = view->details->new_added_files;
 
3332
        view->details->new_added_files = NULL;
 
3333
        new_changed_files = view->details->new_changed_files;
 
3334
        view->details->new_changed_files = NULL;
 
3335
 
 
3336
        non_ready_files = view->details->non_ready_files;
 
3337
 
 
3338
        old_added_files = view->details->old_added_files;
 
3339
        old_changed_files = view->details->old_changed_files;
 
3340
 
 
3341
        /* Newly added files go into the old_added_files list if they're
 
3342
         * ready, and into the hash table if they're not.
 
3343
         */
 
3344
        for (node = new_added_files; node != NULL; node = next) {
 
3345
                next = node->next;
 
3346
                pending = (FileAndDirectory *)node->data;
 
3347
                in_non_ready = g_hash_table_lookup (non_ready_files, pending) != NULL;
 
3348
                if (nautilus_view_should_show_file (view, pending->file)) {
 
3349
                        if (ready_to_load (pending->file)) {
 
3350
                                if (in_non_ready) {
 
3351
                                        g_hash_table_remove (non_ready_files, pending);
 
3352
                                }
 
3353
                                new_added_files = g_list_delete_link (new_added_files, node);
 
3354
                                old_added_files = g_list_prepend (old_added_files, pending);
 
3355
                        } else {
 
3356
                                if (!in_non_ready) {
 
3357
                                        new_added_files = g_list_delete_link (new_added_files, node);
 
3358
                                        g_hash_table_insert (non_ready_files, pending, pending);
 
3359
                                }
 
3360
                        }
 
3361
                }
 
3362
        }
 
3363
        file_and_directory_list_free (new_added_files);
 
3364
 
 
3365
        /* Newly changed files go into the old_added_files list if they're ready
 
3366
         * and were seen non-ready in the past, into the old_changed_files list
 
3367
         * if they are read and were not seen non-ready in the past, and into
 
3368
         * the hash table if they're not ready.
 
3369
         */
 
3370
        for (node = new_changed_files; node != NULL; node = next) {
 
3371
                next = node->next;
 
3372
                pending = (FileAndDirectory *)node->data;
 
3373
                if (!still_should_show_file (view, pending->file, pending->directory) || ready_to_load (pending->file)) {
 
3374
                        if (g_hash_table_lookup (non_ready_files, pending) != NULL) {
 
3375
                                g_hash_table_remove (non_ready_files, pending);
 
3376
                                if (still_should_show_file (view, pending->file, pending->directory)) {
 
3377
                                        new_changed_files = g_list_delete_link (new_changed_files, node);
 
3378
                                        old_added_files = g_list_prepend (old_added_files, pending);
 
3379
                                }
 
3380
                        } else if (nautilus_view_should_show_file (view, pending->file)) {
 
3381
                                new_changed_files = g_list_delete_link (new_changed_files, node);
 
3382
                                old_changed_files = g_list_prepend (old_changed_files, pending);
 
3383
                        }
 
3384
                }
 
3385
        }
 
3386
        file_and_directory_list_free (new_changed_files);
 
3387
 
 
3388
        /* If any files were added to old_added_files, then resort it. */
 
3389
        if (old_added_files != view->details->old_added_files) {
 
3390
                view->details->old_added_files = old_added_files;
 
3391
                sort_files (view, &view->details->old_added_files);
 
3392
        }
 
3393
 
 
3394
        /* Resort old_changed_files too, since file attributes
 
3395
         * relevant to sorting could have changed.
 
3396
         */
 
3397
        if (old_changed_files != view->details->old_changed_files) {
 
3398
                view->details->old_changed_files = old_changed_files;
 
3399
                sort_files (view, &view->details->old_changed_files);
 
3400
        }
 
3401
 
 
3402
}
 
3403
 
 
3404
static void
 
3405
process_old_files (NautilusView *view)
 
3406
{
 
3407
        GList *files_added, *files_changed, *node;
 
3408
        FileAndDirectory *pending;
 
3409
        GList *selection, *files;
 
3410
        gboolean send_selection_change;
 
3411
 
 
3412
        files_added = view->details->old_added_files;
 
3413
        files_changed = view->details->old_changed_files;
 
3414
        
 
3415
        send_selection_change = FALSE;
 
3416
 
 
3417
        if (files_added != NULL || files_changed != NULL) {
 
3418
                g_signal_emit (view, signals[BEGIN_FILE_CHANGES], 0);
 
3419
 
 
3420
                for (node = files_added; node != NULL; node = node->next) {
 
3421
                        pending = node->data;
 
3422
                        g_signal_emit (view,
 
3423
                                       signals[ADD_FILE], 0, pending->file, pending->directory);
 
3424
                }
 
3425
 
 
3426
                for (node = files_changed; node != NULL; node = node->next) {
 
3427
                        pending = node->data;
 
3428
                        g_signal_emit (view,
 
3429
                                       signals[still_should_show_file (view, pending->file, pending->directory)
 
3430
                                               ? FILE_CHANGED : REMOVE_FILE], 0,
 
3431
                                       pending->file, pending->directory);
 
3432
                }
 
3433
 
 
3434
                g_signal_emit (view, signals[END_FILE_CHANGES], 0);
 
3435
 
 
3436
                if (files_changed != NULL) {
 
3437
                        selection = nautilus_view_get_selection (view);
 
3438
                        files = file_and_directory_list_to_files (files_changed);
 
3439
                        send_selection_change = eel_g_lists_sort_and_check_for_intersection
 
3440
                                (&files, &selection);
 
3441
                        nautilus_file_list_free (files);
 
3442
                        nautilus_file_list_free (selection);
 
3443
                }
 
3444
                
 
3445
                file_and_directory_list_free (view->details->old_added_files);
 
3446
                view->details->old_added_files = NULL;
 
3447
 
 
3448
                file_and_directory_list_free (view->details->old_changed_files);
 
3449
                view->details->old_changed_files = NULL;
 
3450
        }
 
3451
 
 
3452
        if (send_selection_change) {
 
3453
                /* Send a selection change since some file names could
 
3454
                 * have changed.
 
3455
                 */
 
3456
                nautilus_view_send_selection_change (view);
 
3457
        }
 
3458
}
 
3459
 
 
3460
static void
 
3461
display_pending_files (NautilusView *view)
 
3462
{
 
3463
 
 
3464
        /* Don't dispatch any updates while the view is frozen. */
 
3465
        if (view->details->updates_frozen) {
 
3466
                return;
 
3467
        }
 
3468
 
 
3469
        process_new_files (view);
 
3470
        process_old_files (view);
 
3471
 
 
3472
        if (view->details->model != NULL
 
3473
            && nautilus_directory_are_all_files_seen (view->details->model)
 
3474
            && g_hash_table_size (view->details->non_ready_files) == 0) {
 
3475
                done_loading (view, TRUE);
 
3476
        }
 
3477
}
 
3478
 
 
3479
void
 
3480
nautilus_view_freeze_updates (NautilusView *view)
 
3481
{
 
3482
        view->details->updates_frozen = TRUE;
 
3483
        view->details->updates_queued = 0;
 
3484
        view->details->needs_reload = FALSE;
 
3485
}
 
3486
 
 
3487
void
 
3488
nautilus_view_unfreeze_updates (NautilusView *view)
 
3489
{
 
3490
        view->details->updates_frozen = FALSE;
 
3491
 
 
3492
        if (view->details->needs_reload) {
 
3493
                view->details->needs_reload = FALSE;
 
3494
                if (view->details->model != NULL) {
 
3495
                        load_directory (view, view->details->model);
 
3496
                }
 
3497
        } else {
 
3498
                schedule_idle_display_of_pending_files (view);
 
3499
        }
 
3500
}
 
3501
 
 
3502
static gboolean
 
3503
display_selection_info_idle_callback (gpointer data)
 
3504
{
 
3505
        NautilusView *view;
 
3506
        
 
3507
        view = NAUTILUS_VIEW (data);
 
3508
 
 
3509
        g_object_ref (G_OBJECT (view));
 
3510
 
 
3511
        view->details->display_selection_idle_id = 0;
 
3512
        nautilus_view_display_selection_info (view);
 
3513
        if (view->details->send_selection_change_to_shell) {
 
3514
                nautilus_view_send_selection_change (view);
 
3515
        }
 
3516
 
 
3517
        g_object_unref (G_OBJECT (view));
 
3518
 
 
3519
        return FALSE;
 
3520
}
 
3521
 
 
3522
static void
 
3523
remove_update_menus_timeout_callback (NautilusView *view) 
 
3524
{
 
3525
        if (view->details->update_menus_timeout_id != 0) {
 
3526
                g_source_remove (view->details->update_menus_timeout_id);
 
3527
                view->details->update_menus_timeout_id = 0;
 
3528
        }
 
3529
}
 
3530
 
 
3531
static void
 
3532
update_menus_if_pending (NautilusView *view)
 
3533
{
 
3534
        if (!view->details->menu_states_untrustworthy) {
 
3535
                return;
 
3536
        }
 
3537
 
 
3538
        remove_update_menus_timeout_callback (view);
 
3539
        nautilus_view_update_menus (view);
 
3540
}
 
3541
 
 
3542
static gboolean
 
3543
update_menus_timeout_callback (gpointer data)
 
3544
{
 
3545
        NautilusView *view;
 
3546
 
 
3547
        view = NAUTILUS_VIEW (data);
 
3548
 
 
3549
        g_object_ref (G_OBJECT (view));
 
3550
 
 
3551
        view->details->update_menus_timeout_id = 0;
 
3552
        nautilus_view_update_menus (view);
 
3553
 
 
3554
        g_object_unref (G_OBJECT (view));
 
3555
 
 
3556
        return FALSE;
 
3557
}
 
3558
 
 
3559
static gboolean
 
3560
display_pending_callback (gpointer data)
 
3561
{
 
3562
        NautilusView *view;
 
3563
 
 
3564
        view = NAUTILUS_VIEW (data);
 
3565
 
 
3566
        g_object_ref (G_OBJECT (view));
 
3567
 
 
3568
        view->details->display_pending_source_id = 0;
 
3569
 
 
3570
        display_pending_files (view);
 
3571
 
 
3572
        g_object_unref (G_OBJECT (view));
 
3573
 
 
3574
        return FALSE;
 
3575
}
 
3576
 
 
3577
static void
 
3578
schedule_idle_display_of_pending_files (NautilusView *view)
 
3579
{
 
3580
        /* Get rid of a pending source as it might be a timeout */
 
3581
        unschedule_display_of_pending_files (view);
 
3582
 
 
3583
        /* We want higher priority than the idle that handles the relayout
 
3584
           to avoid a resort on each add. But we still want to allow repaints
 
3585
           and other hight prio events while we have pending files to show. */
 
3586
        view->details->display_pending_source_id =
 
3587
                g_idle_add_full (G_PRIORITY_DEFAULT_IDLE - 20,
 
3588
                                 display_pending_callback, view, NULL);
 
3589
}
 
3590
 
 
3591
static void
 
3592
schedule_timeout_display_of_pending_files (NautilusView *view, guint interval)
 
3593
{
 
3594
        /* No need to schedule an update if there's already one pending. */
 
3595
        if (view->details->display_pending_source_id != 0) {
 
3596
                return;
 
3597
        }
 
3598
 
 
3599
        view->details->display_pending_source_id =
 
3600
                g_timeout_add (interval, display_pending_callback, view);
 
3601
}
 
3602
 
 
3603
static void
 
3604
unschedule_display_of_pending_files (NautilusView *view)
 
3605
{
 
3606
        /* Get rid of source if it's active. */
 
3607
        if (view->details->display_pending_source_id != 0) {
 
3608
                g_source_remove (view->details->display_pending_source_id);
 
3609
                view->details->display_pending_source_id = 0;
 
3610
        }
 
3611
}
 
3612
 
 
3613
static void
 
3614
queue_pending_files (NautilusView *view,
 
3615
                     NautilusDirectory *directory,
 
3616
                     GList *files,
 
3617
                     GList **pending_list)
 
3618
{
 
3619
        if (files == NULL) {
 
3620
                return;
 
3621
        }
 
3622
 
 
3623
        /* Don't queue any more updates if we need to reload anyway */
 
3624
        if (view->details->needs_reload) {
 
3625
                return;
 
3626
        }
 
3627
 
 
3628
        if (view->details->updates_frozen) {
 
3629
                view->details->updates_queued += g_list_length (files);
 
3630
                /* Mark the directory for reload when there are too much queued
 
3631
                 * changes to prevent the pending list from growing infinitely.
 
3632
                 */
 
3633
                if (view->details->updates_queued > MAX_QUEUED_UPDATES) {
 
3634
                        view->details->needs_reload = TRUE;
 
3635
                        return;
 
3636
                }
 
3637
        }
 
3638
 
 
3639
        
 
3640
 
 
3641
        *pending_list = g_list_concat (file_and_directory_list_from_files (directory, files),
 
3642
                                       *pending_list);
 
3643
 
 
3644
        if (! view->details->loading || nautilus_directory_are_all_files_seen (directory)) {
 
3645
                schedule_timeout_display_of_pending_files (view, view->details->update_interval);
 
3646
        }
 
3647
}
 
3648
 
 
3649
static void
 
3650
remove_changes_timeout_callback (NautilusView *view) 
 
3651
{
 
3652
        if (view->details->changes_timeout_id != 0) {
 
3653
                g_source_remove (view->details->changes_timeout_id);
 
3654
                view->details->changes_timeout_id = 0;
 
3655
        }
 
3656
}
 
3657
 
 
3658
static void
 
3659
reset_update_interval (NautilusView *view)
 
3660
{
 
3661
        view->details->update_interval = UPDATE_INTERVAL_MIN;
 
3662
        remove_changes_timeout_callback (view);
 
3663
        /* Reschedule a pending timeout to idle */
 
3664
        if (view->details->display_pending_source_id != 0) {
 
3665
                schedule_idle_display_of_pending_files (view);
 
3666
        }
 
3667
}
 
3668
 
 
3669
static gboolean
 
3670
changes_timeout_callback (gpointer data)
 
3671
{
 
3672
        gint64 now;
 
3673
        gint64 time_delta;
 
3674
        gboolean ret;
 
3675
        NautilusView *view;
 
3676
 
 
3677
        view = NAUTILUS_VIEW (data);
 
3678
 
 
3679
        g_object_ref (G_OBJECT (view));
 
3680
 
 
3681
        now = eel_get_system_time();
 
3682
        time_delta = now - view->details->last_queued;
 
3683
 
 
3684
        if (time_delta < UPDATE_INTERVAL_RESET*1000) {
 
3685
                if (view->details->update_interval < UPDATE_INTERVAL_MAX &&
 
3686
                    view->details->loading) {
 
3687
                        /* Increase */
 
3688
                        view->details->update_interval += UPDATE_INTERVAL_INC;
 
3689
                }
 
3690
                ret = TRUE;
 
3691
        } else {
 
3692
                /* Reset */
 
3693
                reset_update_interval (view);
 
3694
                ret = FALSE;
 
3695
        }
 
3696
 
 
3697
        g_object_unref (G_OBJECT (view));
 
3698
 
 
3699
        return ret;
 
3700
}
 
3701
 
 
3702
static void
 
3703
schedule_changes (NautilusView *view)
 
3704
{
 
3705
        /* Remember when the change was queued */
 
3706
        view->details->last_queued = eel_get_system_time();
 
3707
 
 
3708
        /* No need to schedule if there are already changes pending or during loading */
 
3709
        if (view->details->changes_timeout_id != 0 ||
 
3710
            view->details->loading) {
 
3711
                return;
 
3712
        }
 
3713
 
 
3714
        view->details->changes_timeout_id = 
 
3715
                g_timeout_add (UPDATE_INTERVAL_TIMEOUT_INTERVAL, changes_timeout_callback, view);
 
3716
}
 
3717
 
 
3718
static void
 
3719
files_added_callback (NautilusDirectory *directory,
 
3720
                      GList *files,
 
3721
                      gpointer callback_data)
 
3722
{
 
3723
        NautilusView *view;
 
3724
        GtkWindow *window;
 
3725
        char *uri;
 
3726
 
 
3727
        view = NAUTILUS_VIEW (callback_data);
 
3728
 
 
3729
        window = nautilus_view_get_containing_window (view);
 
3730
        uri = nautilus_view_get_uri (view);
 
3731
        DEBUG_FILES (files, "Files added in window %p: %s",
 
3732
                     window, uri ? uri : "(no directory)");
 
3733
        g_free (uri);
 
3734
 
 
3735
        schedule_changes (view);
 
3736
 
 
3737
        queue_pending_files (view, directory, files, &view->details->new_added_files);
 
3738
 
 
3739
        /* The number of items could have changed */
 
3740
        schedule_update_status (view);
 
3741
}
 
3742
 
 
3743
static void
 
3744
files_changed_callback (NautilusDirectory *directory,
 
3745
                        GList *files,
 
3746
                        gpointer callback_data)
 
3747
{
 
3748
        NautilusView *view;
 
3749
        GtkWindow *window;
 
3750
        char *uri;
 
3751
        
 
3752
        view = NAUTILUS_VIEW (callback_data);
 
3753
 
 
3754
        window = nautilus_view_get_containing_window (view);
 
3755
        uri = nautilus_view_get_uri (view);
 
3756
        DEBUG_FILES (files, "Files changed in window %p: %s",
 
3757
                     window, uri ? uri : "(no directory)");
 
3758
        g_free (uri);
 
3759
 
 
3760
        schedule_changes (view);
 
3761
 
 
3762
        queue_pending_files (view, directory, files, &view->details->new_changed_files);
 
3763
        
 
3764
        /* The free space or the number of items could have changed */
 
3765
        schedule_update_status (view);
 
3766
 
 
3767
        /* A change in MIME type could affect the Open with menu, for
 
3768
         * one thing, so we need to update menus when files change.
 
3769
         */
 
3770
        schedule_update_menus (view);
 
3771
}
 
3772
 
 
3773
static void
 
3774
done_loading_callback (NautilusDirectory *directory,
 
3775
                       gpointer callback_data)
 
3776
{
 
3777
        NautilusView *view;
 
3778
 
 
3779
        view = NAUTILUS_VIEW (callback_data);
 
3780
        
 
3781
        process_new_files (view);
 
3782
        if (g_hash_table_size (view->details->non_ready_files) == 0) {
 
3783
                /* Unschedule a pending update and schedule a new one with the minimal
 
3784
                 * update interval. This gives the view a short chance at gathering the
 
3785
                 * (cached) deep counts.
 
3786
                 */
 
3787
                unschedule_display_of_pending_files (view);
 
3788
                schedule_timeout_display_of_pending_files (view, UPDATE_INTERVAL_MIN);
 
3789
        }
 
3790
}
 
3791
 
 
3792
static void
 
3793
load_error_callback (NautilusDirectory *directory,
 
3794
                     GError *error,
 
3795
                     gpointer callback_data)
 
3796
{
 
3797
        NautilusView *view;
 
3798
 
 
3799
        view = NAUTILUS_VIEW (callback_data);
 
3800
 
 
3801
        /* FIXME: By doing a stop, we discard some pending files. Is
 
3802
         * that OK?
 
3803
         */
 
3804
        nautilus_view_stop_loading (view);
 
3805
 
 
3806
        /* Emit a signal to tell subclasses that a load error has
 
3807
         * occurred, so they can handle it in the UI.
 
3808
         */
 
3809
        g_signal_emit (view,
 
3810
                       signals[LOAD_ERROR], 0, error);
 
3811
}
 
3812
 
 
3813
static void
 
3814
real_load_error (NautilusView *view, GError *error)
 
3815
{
 
3816
        /* Report only one error per failed directory load (from the UI
 
3817
         * point of view, not from the NautilusDirectory point of view).
 
3818
         * Otherwise you can get multiple identical errors caused by 
 
3819
         * unrelated code that just happens to try to iterate this
 
3820
         * directory.
 
3821
         */
 
3822
        if (!view->details->reported_load_error) {
 
3823
                nautilus_report_error_loading_directory 
 
3824
                        (nautilus_view_get_directory_as_file (view),
 
3825
                         error,
 
3826
                         nautilus_view_get_containing_window (view));
 
3827
        }
 
3828
        view->details->reported_load_error = TRUE;
 
3829
}
 
3830
 
 
3831
void
 
3832
nautilus_view_add_subdirectory (NautilusView  *view,
 
3833
                                NautilusDirectory*directory)
 
3834
{
 
3835
        NautilusFileAttributes attributes;
 
3836
 
 
3837
        g_assert (!g_list_find (view->details->subdirectory_list, directory));
 
3838
        
 
3839
        nautilus_directory_ref (directory);
 
3840
 
 
3841
        attributes =
 
3842
                NAUTILUS_FILE_ATTRIBUTES_FOR_ICON |
 
3843
                NAUTILUS_FILE_ATTRIBUTE_DIRECTORY_ITEM_COUNT |
 
3844
                NAUTILUS_FILE_ATTRIBUTE_INFO |
 
3845
                NAUTILUS_FILE_ATTRIBUTE_LINK_INFO |
 
3846
                NAUTILUS_FILE_ATTRIBUTE_MOUNT |
 
3847
                NAUTILUS_FILE_ATTRIBUTE_EXTENSION_INFO;
 
3848
 
 
3849
        nautilus_directory_file_monitor_add (directory,
 
3850
                                             &view->details->model,
 
3851
                                             view->details->show_hidden_files,
 
3852
                                             attributes,
 
3853
                                             files_added_callback, view);
 
3854
        
 
3855
        g_signal_connect
 
3856
                (directory, "files_added",
 
3857
                 G_CALLBACK (files_added_callback), view);
 
3858
        g_signal_connect
 
3859
                (directory, "files_changed",
 
3860
                 G_CALLBACK (files_changed_callback), view);
 
3861
        
 
3862
        view->details->subdirectory_list = g_list_prepend (
 
3863
                                                           view->details->subdirectory_list, directory);
 
3864
}
 
3865
 
 
3866
void
 
3867
nautilus_view_remove_subdirectory (NautilusView  *view,
 
3868
                                   NautilusDirectory*directory)
 
3869
{
 
3870
        g_assert (g_list_find (view->details->subdirectory_list, directory));
 
3871
        
 
3872
        view->details->subdirectory_list = g_list_remove (
 
3873
                                                          view->details->subdirectory_list, directory);
 
3874
 
 
3875
        g_signal_handlers_disconnect_by_func (directory,
 
3876
                                              G_CALLBACK (files_added_callback),
 
3877
                                              view);
 
3878
        g_signal_handlers_disconnect_by_func (directory,
 
3879
                                              G_CALLBACK (files_changed_callback),
 
3880
                                              view);
 
3881
 
 
3882
        nautilus_directory_file_monitor_remove (directory, &view->details->model);
 
3883
 
 
3884
        nautilus_directory_unref (directory);
 
3885
}
 
3886
 
 
3887
/**
 
3888
 * nautilus_view_get_loading:
 
3889
 * @view: an #NautilusView.
 
3890
 *
 
3891
 * Return value: #gboolean inicating whether @view is currently loaded.
 
3892
 * 
 
3893
 **/
 
3894
gboolean
 
3895
nautilus_view_get_loading (NautilusView *view)
 
3896
{
 
3897
        g_return_val_if_fail (NAUTILUS_IS_VIEW (view), FALSE);
 
3898
 
 
3899
        return view->details->loading;
 
3900
}
 
3901
 
 
3902
GtkUIManager *
 
3903
nautilus_view_get_ui_manager (NautilusView  *view)
 
3904
{
 
3905
        if (view->details->window == NULL) {
 
3906
                return NULL;
 
3907
        }
 
3908
        return nautilus_window_get_ui_manager (view->details->window);  
 
3909
}
 
3910
 
 
3911
/**
 
3912
 * nautilus_view_get_model:
 
3913
 *
 
3914
 * Get the model for this NautilusView.
 
3915
 * @view: NautilusView of interest.
 
3916
 * 
 
3917
 * Return value: NautilusDirectory for this view.
 
3918
 * 
 
3919
 **/
 
3920
NautilusDirectory *
 
3921
nautilus_view_get_model (NautilusView *view)
 
3922
{
 
3923
        g_return_val_if_fail (NAUTILUS_IS_VIEW (view), NULL);
 
3924
 
 
3925
        return view->details->model;
 
3926
}
 
3927
 
 
3928
GdkAtom
 
3929
nautilus_view_get_copied_files_atom (NautilusView *view)
 
3930
{
 
3931
        g_return_val_if_fail (NAUTILUS_IS_VIEW (view), GDK_NONE);
 
3932
        
 
3933
        return copied_files_atom;
 
3934
}
 
3935
 
 
3936
static void
 
3937
prepend_uri_one (gpointer data, gpointer callback_data)
 
3938
{
 
3939
        NautilusFile *file;
 
3940
        GList **result;
 
3941
        
 
3942
        g_assert (NAUTILUS_IS_FILE (data));
 
3943
        g_assert (callback_data != NULL);
 
3944
 
 
3945
        result = (GList **) callback_data;
 
3946
        file = (NautilusFile *) data;
 
3947
        *result = g_list_prepend (*result, nautilus_file_get_uri (file));
 
3948
}
 
3949
 
 
3950
static void
 
3951
offset_drop_points (GArray *relative_item_points,
 
3952
                    int x_offset, int y_offset)
 
3953
{
 
3954
        guint index;
 
3955
 
 
3956
        if (relative_item_points == NULL) {
 
3957
                return;
 
3958
        }
 
3959
 
 
3960
        for (index = 0; index < relative_item_points->len; index++) {
 
3961
                g_array_index (relative_item_points, GdkPoint, index).x += x_offset;
 
3962
                g_array_index (relative_item_points, GdkPoint, index).y += y_offset;
 
3963
        }
 
3964
}
 
3965
 
 
3966
static void
 
3967
nautilus_view_create_links_for_files (NautilusView *view, GList *files,
 
3968
                                      GArray *relative_item_points)
 
3969
{
 
3970
        GList *uris;
 
3971
        char *dir_uri;
 
3972
        CopyMoveDoneData *copy_move_done_data;
 
3973
        g_assert (relative_item_points->len == 0
 
3974
                  || g_list_length (files) == relative_item_points->len);
 
3975
        
 
3976
        g_assert (NAUTILUS_IS_VIEW (view));
 
3977
        g_assert (files != NULL);
 
3978
 
 
3979
        /* create a list of URIs */
 
3980
        uris = NULL;
 
3981
        g_list_foreach (files, prepend_uri_one, &uris);
 
3982
        uris = g_list_reverse (uris);
 
3983
 
 
3984
        g_assert (g_list_length (uris) == g_list_length (files));
 
3985
 
 
3986
        /* offset the drop locations a bit so that we don't pile
 
3987
         * up the icons on top of each other
 
3988
         */
 
3989
        offset_drop_points (relative_item_points,
 
3990
                            DUPLICATE_HORIZONTAL_ICON_OFFSET,
 
3991
                            DUPLICATE_VERTICAL_ICON_OFFSET);
 
3992
 
 
3993
        copy_move_done_data = pre_copy_move (view);
 
3994
        dir_uri = nautilus_view_get_backing_uri (view);
 
3995
        nautilus_file_operations_copy_move (uris, relative_item_points, dir_uri, GDK_ACTION_LINK, 
 
3996
                                            GTK_WIDGET (view), copy_move_done_callback, copy_move_done_data);
 
3997
        g_free (dir_uri);
 
3998
        g_list_free_full (uris, g_free);
 
3999
}
 
4000
 
 
4001
static void
 
4002
nautilus_view_duplicate_selection (NautilusView *view, GList *files,
 
4003
                                   GArray *relative_item_points)
 
4004
{
 
4005
        GList *uris;
 
4006
        CopyMoveDoneData *copy_move_done_data;
 
4007
 
 
4008
        g_assert (NAUTILUS_IS_VIEW (view));
 
4009
        g_assert (files != NULL);
 
4010
        g_assert (g_list_length (files) == relative_item_points->len
 
4011
                  || relative_item_points->len == 0);
 
4012
 
 
4013
        /* create a list of URIs */
 
4014
        uris = NULL;
 
4015
        g_list_foreach (files, prepend_uri_one, &uris);
 
4016
        uris = g_list_reverse (uris);
 
4017
 
 
4018
        g_assert (g_list_length (uris) == g_list_length (files));
 
4019
        
 
4020
        /* offset the drop locations a bit so that we don't pile
 
4021
         * up the icons on top of each other
 
4022
         */
 
4023
        offset_drop_points (relative_item_points,
 
4024
                            DUPLICATE_HORIZONTAL_ICON_OFFSET,
 
4025
                            DUPLICATE_VERTICAL_ICON_OFFSET);
 
4026
 
 
4027
        copy_move_done_data = pre_copy_move (view);
 
4028
        nautilus_file_operations_copy_move (uris, relative_item_points, NULL, GDK_ACTION_COPY,
 
4029
                                            GTK_WIDGET (view), copy_move_done_callback, copy_move_done_data);
 
4030
        g_list_free_full (uris, g_free);
 
4031
}
 
4032
 
 
4033
/* special_link_in_selection
 
4034
 * 
 
4035
 * Return TRUE if one of our special links is in the selection.
 
4036
 * Special links include the following: 
 
4037
 *       NAUTILUS_DESKTOP_LINK_TRASH, NAUTILUS_DESKTOP_LINK_HOME, NAUTILUS_DESKTOP_LINK_MOUNT
 
4038
 */
 
4039
 
 
4040
static gboolean
 
4041
special_link_in_selection (NautilusView *view)
 
4042
{
 
4043
        gboolean saw_link;
 
4044
        GList *selection, *node;
 
4045
        NautilusFile *file;
 
4046
 
 
4047
        g_return_val_if_fail (NAUTILUS_IS_VIEW (view), FALSE);
 
4048
 
 
4049
        saw_link = FALSE;
 
4050
 
 
4051
        selection = nautilus_view_get_selection (NAUTILUS_VIEW (view));
 
4052
 
 
4053
        for (node = selection; node != NULL; node = node->next) {
 
4054
                file = NAUTILUS_FILE (node->data);
 
4055
 
 
4056
                saw_link = NAUTILUS_IS_DESKTOP_ICON_FILE (file);
 
4057
                
 
4058
                if (saw_link) {
 
4059
                        break;
 
4060
                }
 
4061
        }
 
4062
        
 
4063
        nautilus_file_list_free (selection);
 
4064
        
 
4065
        return saw_link;
 
4066
}
 
4067
 
 
4068
/* desktop_or_home_dir_in_selection
 
4069
 * 
 
4070
 * Return TRUE if either the desktop or the home directory is in the selection.
 
4071
 */
 
4072
 
 
4073
static gboolean
 
4074
desktop_or_home_dir_in_selection (NautilusView *view)
 
4075
{
 
4076
        gboolean saw_desktop_or_home_dir;
 
4077
        GList *selection, *node;
 
4078
        NautilusFile *file;
 
4079
 
 
4080
        g_return_val_if_fail (NAUTILUS_IS_VIEW (view), FALSE);
 
4081
 
 
4082
        saw_desktop_or_home_dir = FALSE;
 
4083
 
 
4084
        selection = nautilus_view_get_selection (NAUTILUS_VIEW (view));
 
4085
 
 
4086
        for (node = selection; node != NULL; node = node->next) {
 
4087
                file = NAUTILUS_FILE (node->data);
 
4088
 
 
4089
                saw_desktop_or_home_dir =
 
4090
                        nautilus_file_is_home (file)
 
4091
                        || nautilus_file_is_desktop_directory (file);
 
4092
                
 
4093
                if (saw_desktop_or_home_dir) {
 
4094
                        break;
 
4095
                }
 
4096
        }
 
4097
        
 
4098
        nautilus_file_list_free (selection);
 
4099
        
 
4100
        return saw_desktop_or_home_dir;
 
4101
}
 
4102
 
 
4103
static void
 
4104
trash_or_delete_done_cb (GHashTable *debuting_uris,
 
4105
                         gboolean user_cancel,
 
4106
                         NautilusView *view)
 
4107
{
 
4108
        if (user_cancel) {
 
4109
                view->details->selection_was_removed = FALSE;
 
4110
        }
 
4111
}
 
4112
 
 
4113
static void
 
4114
trash_or_delete_files (GtkWindow *parent_window,
 
4115
                       const GList *files,
 
4116
                       gboolean delete_if_all_already_in_trash,
 
4117
                       NautilusView *view)
 
4118
{
 
4119
        GList *locations;
 
4120
        const GList *node;
 
4121
        
 
4122
        locations = NULL;
 
4123
        for (node = files; node != NULL; node = node->next) {
 
4124
                locations = g_list_prepend (locations,
 
4125
                                            nautilus_file_get_location ((NautilusFile *) node->data));
 
4126
        }
 
4127
        
 
4128
        locations = g_list_reverse (locations);
 
4129
 
 
4130
        nautilus_file_operations_trash_or_delete (locations,
 
4131
                                                  parent_window,
 
4132
                                                  (NautilusDeleteCallback) trash_or_delete_done_cb,
 
4133
                                                  view);
 
4134
        g_list_free_full (locations, g_object_unref);
 
4135
}
 
4136
 
 
4137
static gboolean
 
4138
can_rename_file (NautilusView *view, NautilusFile *file)
 
4139
{
 
4140
        return nautilus_file_can_rename (file);
 
4141
}
 
4142
 
 
4143
static void
 
4144
start_renaming_file (NautilusView *view,
 
4145
                     NautilusFile *file,
 
4146
                     gboolean select_all)
 
4147
{
 
4148
        if (file !=  NULL) {
 
4149
                nautilus_view_select_file (view, file);
 
4150
        }
 
4151
}
 
4152
 
 
4153
static void
 
4154
update_context_menu_position_from_event (NautilusView *view,
 
4155
                                         GdkEventButton  *event)
 
4156
{
 
4157
        g_return_if_fail (NAUTILUS_IS_VIEW (view));
 
4158
 
 
4159
        if (event != NULL) {
 
4160
                view->details->context_menu_position.x = event->x;
 
4161
                view->details->context_menu_position.y = event->y;
 
4162
        } else {
 
4163
                view->details->context_menu_position.x = -1;
 
4164
                view->details->context_menu_position.y = -1;
 
4165
        }
 
4166
}
 
4167
 
 
4168
/* handle the open command */
 
4169
 
 
4170
static void
 
4171
open_one_in_new_window (gpointer data, gpointer callback_data)
 
4172
{
 
4173
        g_assert (NAUTILUS_IS_FILE (data));
 
4174
        g_assert (NAUTILUS_IS_VIEW (callback_data));
 
4175
 
 
4176
        nautilus_view_activate_file (NAUTILUS_VIEW (callback_data),
 
4177
                                     NAUTILUS_FILE (data),
 
4178
                                     NAUTILUS_WINDOW_OPEN_FLAG_NEW_WINDOW);
 
4179
}
 
4180
 
 
4181
NautilusFile *
 
4182
nautilus_view_get_directory_as_file (NautilusView *view)
 
4183
{
 
4184
        g_assert (NAUTILUS_IS_VIEW (view));
 
4185
 
 
4186
        return view->details->directory_as_file; 
 
4187
}
 
4188
 
 
4189
static void
 
4190
open_with_launch_application_callback (GtkAction *action,
 
4191
                                       gpointer callback_data)
 
4192
{
 
4193
        ApplicationLaunchParameters *launch_parameters;
 
4194
        
 
4195
        launch_parameters = (ApplicationLaunchParameters *) callback_data;
 
4196
        nautilus_launch_application 
 
4197
                (launch_parameters->application,
 
4198
                 launch_parameters->files,
 
4199
                 nautilus_view_get_containing_window (launch_parameters->directory_view));
 
4200
}
 
4201
 
 
4202
static char *
 
4203
escape_action_name (const char *action_name,
 
4204
                    const char *prefix)
 
4205
{
 
4206
        GString *s;
 
4207
 
 
4208
        if (action_name == NULL) {
 
4209
                return NULL;
 
4210
        }
 
4211
        
 
4212
        s = g_string_new (prefix);
 
4213
 
 
4214
        while (*action_name != 0) {
 
4215
                switch (*action_name) {
 
4216
                case '\\':
 
4217
                        g_string_append (s, "\\\\");
 
4218
                        break;
 
4219
                case '/':
 
4220
                        g_string_append (s, "\\s");
 
4221
                        break;
 
4222
                case '&':
 
4223
                        g_string_append (s, "\\a");
 
4224
                        break;
 
4225
                case '"':
 
4226
                        g_string_append (s, "\\q");
 
4227
                        break;
 
4228
                default:
 
4229
                        g_string_append_c (s, *action_name);
 
4230
                }
 
4231
 
 
4232
                action_name ++;
 
4233
        }
 
4234
        return g_string_free (s, FALSE);
 
4235
}
 
4236
 
 
4237
static char *
 
4238
escape_action_path (const char *action_path)
 
4239
{
 
4240
        GString *s;
 
4241
 
 
4242
        if (action_path == NULL) {
 
4243
                return NULL;
 
4244
        }
 
4245
        
 
4246
        s = g_string_sized_new (strlen (action_path) + 2);
 
4247
 
 
4248
        while (*action_path != 0) {
 
4249
                switch (*action_path) {
 
4250
                case '\\':
 
4251
                        g_string_append (s, "\\\\");
 
4252
                        break;
 
4253
                case '&':
 
4254
                        g_string_append (s, "\\a");
 
4255
                        break;
 
4256
                case '"':
 
4257
                        g_string_append (s, "\\q");
 
4258
                        break;
 
4259
                default:
 
4260
                        g_string_append_c (s, *action_path);
 
4261
                }
 
4262
 
 
4263
                action_path ++;
 
4264
        }
 
4265
        return g_string_free (s, FALSE);
 
4266
}
 
4267
 
 
4268
 
 
4269
static void
 
4270
add_submenu (GtkUIManager *ui_manager,
 
4271
             GtkActionGroup *action_group,
 
4272
             guint merge_id,
 
4273
             const char *parent_path,
 
4274
             const char *uri,
 
4275
             const char *label,
 
4276
             GdkPixbuf *pixbuf,
 
4277
             gboolean add_action)
 
4278
{
 
4279
        char *escaped_label;
 
4280
        char *action_name;
 
4281
        char *submenu_name;
 
4282
        char *escaped_submenu_name;
 
4283
        GtkAction *action;
 
4284
        
 
4285
        if (parent_path != NULL) {
 
4286
                action_name = escape_action_name (uri, "submenu_");
 
4287
                submenu_name = g_path_get_basename (uri);
 
4288
                escaped_submenu_name = escape_action_path (submenu_name);
 
4289
                escaped_label = eel_str_double_underscores (label);
 
4290
 
 
4291
                if (add_action) {
 
4292
                        action = gtk_action_new (action_name,
 
4293
                                                 escaped_label,
 
4294
                                                 NULL,
 
4295
                                                 NULL);
 
4296
                        if (pixbuf != NULL) {
 
4297
                                g_object_set_data_full (G_OBJECT (action), "menu-icon",
 
4298
                                                        g_object_ref (pixbuf),
 
4299
                                                        g_object_unref);
 
4300
                        }
 
4301
                        
 
4302
                        g_object_set (action, "hide-if-empty", FALSE, NULL);
 
4303
                        
 
4304
                        gtk_action_group_add_action (action_group,
 
4305
                                                     action);
 
4306
                        g_object_unref (action);
 
4307
                }
 
4308
 
 
4309
                gtk_ui_manager_add_ui (ui_manager,
 
4310
                                       merge_id,
 
4311
                                       parent_path,
 
4312
                                       escaped_submenu_name,
 
4313
                                       action_name,
 
4314
                                       GTK_UI_MANAGER_MENU,
 
4315
                                       FALSE);
 
4316
                g_free (action_name);
 
4317
                g_free (escaped_label);
 
4318
                g_free (submenu_name);
 
4319
                g_free (escaped_submenu_name);
 
4320
        }
 
4321
}
 
4322
 
 
4323
static void
 
4324
add_application_to_open_with_menu (NautilusView *view,
 
4325
                                   GAppInfo *application, 
 
4326
                                   GList *files,
 
4327
                                   int index,
 
4328
                                   const char *menu_placeholder,
 
4329
                                   const char *popup_placeholder,
 
4330
                                   const gboolean submenu)
 
4331
{
 
4332
        ApplicationLaunchParameters *launch_parameters;
 
4333
        char *tip;
 
4334
        char *label;
 
4335
        char *action_name;
 
4336
        char *escaped_app;
 
4337
        char *path;
 
4338
        GtkAction *action;
 
4339
        GIcon *app_icon;
 
4340
        GtkWidget *menuitem;
 
4341
 
 
4342
        launch_parameters = application_launch_parameters_new 
 
4343
                (application, files, view);
 
4344
        escaped_app = eel_str_double_underscores (g_app_info_get_display_name (application));
 
4345
        if (submenu)
 
4346
                label = g_strdup_printf ("%s", escaped_app);
 
4347
        else
 
4348
                label = g_strdup_printf (_("Open With %s"), escaped_app);
 
4349
 
 
4350
        tip = g_strdup_printf (ngettext ("Use \"%s\" to open the selected item",
 
4351
                                         "Use \"%s\" to open the selected items",
 
4352
                                         g_list_length (files)),
 
4353
                               escaped_app);
 
4354
        g_free (escaped_app);
 
4355
 
 
4356
        action_name = g_strdup_printf ("open_with_%d", index);
 
4357
        
 
4358
        action = gtk_action_new (action_name,
 
4359
                                 label,
 
4360
                                 tip,
 
4361
                                 NULL);
 
4362
 
 
4363
        app_icon = g_app_info_get_icon (application);
 
4364
        if (app_icon != NULL) {
 
4365
                g_object_ref (app_icon);
 
4366
        } else {
 
4367
                app_icon = g_themed_icon_new ("application-x-executable");
 
4368
        }
 
4369
 
 
4370
        gtk_action_set_gicon (action, app_icon);
 
4371
        g_object_unref (app_icon);
 
4372
 
 
4373
        g_signal_connect_data (action, "activate",
 
4374
                               G_CALLBACK (open_with_launch_application_callback),
 
4375
                               launch_parameters, 
 
4376
                               (GClosureNotify)application_launch_parameters_free, 0);
 
4377
 
 
4378
        gtk_action_group_add_action (view->details->open_with_action_group,
 
4379
                                     action);
 
4380
        g_object_unref (action);
 
4381
        
 
4382
        gtk_ui_manager_add_ui (nautilus_window_get_ui_manager (view->details->window),
 
4383
                               view->details->open_with_merge_id,
 
4384
                               menu_placeholder,
 
4385
                               action_name,
 
4386
                               action_name,
 
4387
                               GTK_UI_MANAGER_MENUITEM,
 
4388
                               FALSE);
 
4389
 
 
4390
        path = g_strdup_printf ("%s/%s", menu_placeholder, action_name);
 
4391
        menuitem = gtk_ui_manager_get_widget (
 
4392
                                              nautilus_window_get_ui_manager (view->details->window),
 
4393
                                              path);
 
4394
        gtk_image_menu_item_set_always_show_image (GTK_IMAGE_MENU_ITEM (menuitem), TRUE);
 
4395
        g_free (path);
 
4396
 
 
4397
        gtk_ui_manager_add_ui (nautilus_window_get_ui_manager (view->details->window),
 
4398
                               view->details->open_with_merge_id,
 
4399
                               popup_placeholder,
 
4400
                               action_name,
 
4401
                               action_name,
 
4402
                               GTK_UI_MANAGER_MENUITEM,
 
4403
                               FALSE);
 
4404
 
 
4405
        path = g_strdup_printf ("%s/%s", popup_placeholder, action_name);
 
4406
        menuitem = gtk_ui_manager_get_widget (
 
4407
                                              nautilus_window_get_ui_manager (view->details->window),
 
4408
                                              path);
 
4409
        gtk_image_menu_item_set_always_show_image (GTK_IMAGE_MENU_ITEM (menuitem), TRUE);
 
4410
 
 
4411
        g_free (path);
 
4412
        g_free (action_name);
 
4413
        g_free (label);
 
4414
        g_free (tip);
 
4415
}
 
4416
 
 
4417
static void
 
4418
get_x_content_async_callback (const char **content,
 
4419
                              gpointer user_data)
 
4420
{
 
4421
        NautilusView *view;
 
4422
 
 
4423
        view = NAUTILUS_VIEW (user_data);
 
4424
 
 
4425
        if (view->details->window != NULL) {
 
4426
                schedule_update_menus (view);
 
4427
        }
 
4428
        g_object_unref (view);
 
4429
}
 
4430
 
 
4431
static void
 
4432
add_x_content_apps (NautilusView *view, NautilusFile *file, GList **applications)
 
4433
{
 
4434
        GMount *mount;
 
4435
        char **x_content_types;
 
4436
        unsigned int n;
 
4437
 
 
4438
        g_return_if_fail (applications != NULL);
 
4439
 
 
4440
        mount = nautilus_file_get_mount (file);
 
4441
 
 
4442
        if (mount == NULL) {
 
4443
                return;
 
4444
        }
 
4445
        
 
4446
        x_content_types = nautilus_get_cached_x_content_types_for_mount (mount);
 
4447
        if (x_content_types != NULL) {
 
4448
                for (n = 0; x_content_types[n] != NULL; n++) {
 
4449
                        char *x_content_type = x_content_types[n];
 
4450
                        GList *app_info_for_x_content_type;
 
4451
                        
 
4452
                        app_info_for_x_content_type = g_app_info_get_all_for_type (x_content_type);
 
4453
                        *applications = g_list_concat (*applications, app_info_for_x_content_type);
 
4454
                }
 
4455
                g_strfreev (x_content_types);
 
4456
        } else {
 
4457
                nautilus_get_x_content_types_for_mount_async (mount,
 
4458
                                                              get_x_content_async_callback,
 
4459
                                                              NULL,
 
4460
                                                              g_object_ref (view));
 
4461
                
 
4462
        }
 
4463
 
 
4464
        g_object_unref (mount);
 
4465
}
 
4466
 
 
4467
static void
 
4468
reset_open_with_menu (NautilusView *view, GList *selection)
 
4469
{
 
4470
        GList *applications, *node;
 
4471
        NautilusFile *file;
 
4472
        gboolean submenu_visible, filter_default;
 
4473
        int num_applications;
 
4474
        int index;
 
4475
        gboolean other_applications_visible;
 
4476
        gboolean open_with_chooser_visible;
 
4477
        GtkUIManager *ui_manager;
 
4478
        GtkAction *action;
 
4479
        GAppInfo *default_app;
 
4480
 
 
4481
        /* Clear any previous inserted items in the applications and viewers placeholders */
 
4482
 
 
4483
        ui_manager = nautilus_window_get_ui_manager (view->details->window);
 
4484
        nautilus_ui_unmerge_ui (ui_manager,
 
4485
                                &view->details->open_with_merge_id,
 
4486
                                &view->details->open_with_action_group);
 
4487
        
 
4488
        nautilus_ui_prepare_merge_ui (ui_manager,
 
4489
                                      "OpenWithGroup",
 
4490
                                      &view->details->open_with_merge_id,
 
4491
                                      &view->details->open_with_action_group);
 
4492
        
 
4493
        num_applications = 0;
 
4494
 
 
4495
        other_applications_visible = (selection != NULL);
 
4496
        filter_default = (selection != NULL);
 
4497
 
 
4498
        for (node = selection; node != NULL; node = node->next) {
 
4499
 
 
4500
                file = NAUTILUS_FILE (node->data);
 
4501
 
 
4502
                other_applications_visible &=
 
4503
                        (!nautilus_mime_file_opens_in_view (file) ||
 
4504
                         nautilus_file_is_directory (file));
 
4505
        }
 
4506
 
 
4507
        default_app = NULL;
 
4508
        if (filter_default) {
 
4509
                default_app = nautilus_mime_get_default_application_for_files (selection);
 
4510
        }
 
4511
 
 
4512
        applications = NULL;
 
4513
        if (other_applications_visible) {
 
4514
                applications = nautilus_mime_get_applications_for_files (selection);
 
4515
        }
 
4516
 
 
4517
        if (g_list_length (selection) == 1) {
 
4518
                add_x_content_apps (view, NAUTILUS_FILE (selection->data), &applications);
 
4519
        }
 
4520
 
 
4521
 
 
4522
        num_applications = g_list_length (applications);
 
4523
 
 
4524
        if (file_list_all_are_folders (selection)) {
 
4525
                submenu_visible = (num_applications > 2);
 
4526
        } else {
 
4527
                submenu_visible = (num_applications > 3);
 
4528
        }
 
4529
        
 
4530
        for (node = applications, index = 0; node != NULL; node = node->next, index++) {
 
4531
                GAppInfo *application;
 
4532
                char *menu_path;
 
4533
                char *popup_path;
 
4534
                
 
4535
                application = node->data;
 
4536
 
 
4537
                if (default_app != NULL && g_app_info_equal (default_app, application)) {
 
4538
                        continue;
 
4539
                }
 
4540
 
 
4541
                if (submenu_visible) {
 
4542
                        menu_path = NAUTILUS_VIEW_MENU_PATH_APPLICATIONS_SUBMENU_PLACEHOLDER;
 
4543
                        popup_path = NAUTILUS_VIEW_POPUP_PATH_APPLICATIONS_SUBMENU_PLACEHOLDER;
 
4544
                } else {
 
4545
                        menu_path = NAUTILUS_VIEW_MENU_PATH_APPLICATIONS_PLACEHOLDER;
 
4546
                        popup_path = NAUTILUS_VIEW_POPUP_PATH_APPLICATIONS_PLACEHOLDER;
 
4547
                }
 
4548
 
 
4549
                gtk_ui_manager_add_ui (nautilus_window_get_ui_manager (view->details->window),
 
4550
                                       view->details->open_with_merge_id,
 
4551
                                       menu_path,
 
4552
                                       "separator",
 
4553
                                       NULL,
 
4554
                                       GTK_UI_MANAGER_SEPARATOR,
 
4555
                                       FALSE);
 
4556
                                       
 
4557
                add_application_to_open_with_menu (view, 
 
4558
                                                   node->data, 
 
4559
                                                   selection, 
 
4560
                                                   index, 
 
4561
                                                   menu_path, popup_path, submenu_visible);
 
4562
        }
 
4563
        g_list_free_full (applications, g_object_unref);
 
4564
        if (default_app != NULL) {
 
4565
                g_object_unref (default_app);
 
4566
        }
 
4567
 
 
4568
        open_with_chooser_visible = other_applications_visible &&
 
4569
                g_list_length (selection) == 1;
 
4570
 
 
4571
        if (submenu_visible) {
 
4572
                action = gtk_action_group_get_action (view->details->dir_action_group,
 
4573
                                                      NAUTILUS_ACTION_OTHER_APPLICATION1);
 
4574
                gtk_action_set_visible (action, open_with_chooser_visible);
 
4575
                action = gtk_action_group_get_action (view->details->dir_action_group,
 
4576
                                                      NAUTILUS_ACTION_OTHER_APPLICATION2);
 
4577
                gtk_action_set_visible (action, FALSE);
 
4578
        } else {
 
4579
                action = gtk_action_group_get_action (view->details->dir_action_group,
 
4580
                                                      NAUTILUS_ACTION_OTHER_APPLICATION1);
 
4581
                gtk_action_set_visible (action, FALSE);
 
4582
                action = gtk_action_group_get_action (view->details->dir_action_group,
 
4583
                                                      NAUTILUS_ACTION_OTHER_APPLICATION2);
 
4584
                gtk_action_set_visible (action, open_with_chooser_visible);
 
4585
        }
 
4586
}
 
4587
 
 
4588
static GList *
 
4589
get_all_extension_menu_items (GtkWidget *window,
 
4590
                              GList *selection)
 
4591
{
 
4592
        GList *items;
 
4593
        GList *providers;
 
4594
        GList *l;
 
4595
        
 
4596
        providers = nautilus_module_get_extensions_for_type (NAUTILUS_TYPE_MENU_PROVIDER);
 
4597
        items = NULL;
 
4598
 
 
4599
        for (l = providers; l != NULL; l = l->next) {
 
4600
                NautilusMenuProvider *provider;
 
4601
                GList *file_items;
 
4602
                
 
4603
                provider = NAUTILUS_MENU_PROVIDER (l->data);
 
4604
                file_items = nautilus_menu_provider_get_file_items (provider,
 
4605
                                                                    window,
 
4606
                                                                    selection);
 
4607
                items = g_list_concat (items, file_items);              
 
4608
        }
 
4609
 
 
4610
        nautilus_module_extension_list_free (providers);
 
4611
 
 
4612
        return items;
 
4613
}
 
4614
 
 
4615
typedef struct 
 
4616
{
 
4617
        NautilusMenuItem *item;
 
4618
        NautilusView *view;
 
4619
        GList *selection;
 
4620
        GtkAction *action;
 
4621
} ExtensionActionCallbackData;
 
4622
 
 
4623
 
 
4624
static void
 
4625
extension_action_callback_data_free (ExtensionActionCallbackData *data)
 
4626
{
 
4627
        g_object_unref (data->item);
 
4628
        nautilus_file_list_free (data->selection);
 
4629
        
 
4630
        g_free (data);
 
4631
}
 
4632
 
 
4633
static gboolean
 
4634
search_in_menu_items (GList* items, const char *item_name)
 
4635
{
 
4636
        GList* list;
 
4637
        
 
4638
        for (list = items; list != NULL; list = list->next) {
 
4639
                NautilusMenu* menu;
 
4640
                char *name;
 
4641
                
 
4642
                g_object_get (list->data, "name", &name, NULL);
 
4643
                if (strcmp (name, item_name) == 0) {
 
4644
                        g_free (name);
 
4645
                        return TRUE;
 
4646
                }
 
4647
                g_free (name);
 
4648
 
 
4649
                menu = NULL;
 
4650
                g_object_get (list->data, "menu", &menu, NULL);
 
4651
                if (menu != NULL) {
 
4652
                        gboolean ret;
 
4653
                        GList* submenus;
 
4654
 
 
4655
                        submenus = nautilus_menu_get_items (menu);
 
4656
                        ret = search_in_menu_items (submenus, item_name);
 
4657
                        nautilus_menu_item_list_free (submenus);
 
4658
                        g_object_unref (menu);
 
4659
                        if (ret) {
 
4660
                                return TRUE;
 
4661
                        }
 
4662
                }
 
4663
        }
 
4664
        return FALSE;
 
4665
}
 
4666
 
 
4667
static void
 
4668
extension_action_callback (GtkAction *action,
 
4669
                           gpointer callback_data)
 
4670
{
 
4671
        ExtensionActionCallbackData *data;
 
4672
        char *item_name;
 
4673
        gboolean is_valid;
 
4674
        GList *l;
 
4675
        GList *items;
 
4676
 
 
4677
        data = callback_data;
 
4678
 
 
4679
        /* Make sure the selected menu item is valid for the final sniffed
 
4680
         * mime type */
 
4681
        g_object_get (data->item, "name", &item_name, NULL);
 
4682
        items = get_all_extension_menu_items (gtk_widget_get_toplevel (GTK_WIDGET (data->view)), 
 
4683
                                              data->selection);
 
4684
        
 
4685
        is_valid = search_in_menu_items (items, item_name);
 
4686
 
 
4687
        for (l = items; l != NULL; l = l->next) {
 
4688
                g_object_unref (l->data);
 
4689
        }
 
4690
        g_list_free (items);
 
4691
        
 
4692
        g_free (item_name);
 
4693
 
 
4694
        if (is_valid) {
 
4695
                nautilus_menu_item_activate (data->item);
 
4696
        }
 
4697
}
 
4698
 
 
4699
static GdkPixbuf *
 
4700
get_menu_icon (const char *icon_name)
 
4701
{
 
4702
        NautilusIconInfo *info;
 
4703
        GdkPixbuf *pixbuf;
 
4704
        int size;
 
4705
 
 
4706
        size = nautilus_get_icon_size_for_stock_size (GTK_ICON_SIZE_MENU);
 
4707
 
 
4708
        if (g_path_is_absolute (icon_name)) {
 
4709
                info = nautilus_icon_info_lookup_from_path (icon_name, size);
 
4710
        } else {
 
4711
                info = nautilus_icon_info_lookup_from_name (icon_name, size);
 
4712
        }
 
4713
        pixbuf = nautilus_icon_info_get_pixbuf_nodefault_at_size (info, size);
 
4714
        g_object_unref (info);
 
4715
 
 
4716
        return pixbuf;
 
4717
}
 
4718
 
 
4719
static GdkPixbuf *
 
4720
get_menu_icon_for_file (NautilusFile *file)
 
4721
{
 
4722
        NautilusIconInfo *info;
 
4723
        GdkPixbuf *pixbuf;
 
4724
        int size;
 
4725
 
 
4726
        size = nautilus_get_icon_size_for_stock_size (GTK_ICON_SIZE_MENU);
 
4727
        
 
4728
        info = nautilus_file_get_icon (file, size, 0);
 
4729
        pixbuf = nautilus_icon_info_get_pixbuf_nodefault_at_size (info, size);
 
4730
        g_object_unref (info);
 
4731
        
 
4732
        return pixbuf;
 
4733
}
 
4734
 
 
4735
static GtkAction *
 
4736
add_extension_action_for_files (NautilusView *view, 
 
4737
                                NautilusMenuItem *item,
 
4738
                                GList *files)
 
4739
{
 
4740
        char *name, *label, *tip, *icon;
 
4741
        gboolean sensitive, priority;
 
4742
        GtkAction *action;
 
4743
        GdkPixbuf *pixbuf;
 
4744
        ExtensionActionCallbackData *data;
 
4745
        
 
4746
        g_object_get (G_OBJECT (item), 
 
4747
                      "name", &name, "label", &label, 
 
4748
                      "tip", &tip, "icon", &icon,
 
4749
                      "sensitive", &sensitive,
 
4750
                      "priority", &priority,
 
4751
                      NULL);
 
4752
 
 
4753
        action = gtk_action_new (name,
 
4754
                                 label,
 
4755
                                 tip,
 
4756
                                 icon);
 
4757
 
 
4758
        if (icon != NULL) {
 
4759
                pixbuf = get_menu_icon (icon);
 
4760
                if (pixbuf != NULL) {
 
4761
                        g_object_set_data_full (G_OBJECT (action), "menu-icon",
 
4762
                                                pixbuf,
 
4763
                                                g_object_unref);
 
4764
                }
 
4765
        }
 
4766
 
 
4767
        gtk_action_set_sensitive (action, sensitive);
 
4768
        g_object_set (action, "is-important", priority, NULL);
 
4769
 
 
4770
        data = g_new0 (ExtensionActionCallbackData, 1);
 
4771
        data->item = g_object_ref (item);
 
4772
        data->view = view;
 
4773
        data->selection = nautilus_file_list_copy (files);
 
4774
        data->action = action;
 
4775
 
 
4776
        g_signal_connect_data (action, "activate",
 
4777
                               G_CALLBACK (extension_action_callback),
 
4778
                               data,
 
4779
                               (GClosureNotify)extension_action_callback_data_free, 0);
 
4780
                
 
4781
        gtk_action_group_add_action (view->details->extensions_menu_action_group,
 
4782
                                     GTK_ACTION (action));
 
4783
        g_object_unref (action);
 
4784
        
 
4785
        g_free (name);
 
4786
        g_free (label);
 
4787
        g_free (tip);
 
4788
        g_free (icon);
 
4789
 
 
4790
        return action;
 
4791
}
 
4792
 
 
4793
static void
 
4794
add_extension_menu_items (NautilusView *view,
 
4795
                          GList *files,
 
4796
                          GList *menu_items,
 
4797
                          const char *subdirectory)
 
4798
{
 
4799
        GtkUIManager *ui_manager;
 
4800
        GList *l;
 
4801
 
 
4802
        ui_manager = nautilus_window_get_ui_manager (view->details->window);
 
4803
        
 
4804
        for (l = menu_items; l; l = l->next) {
 
4805
                NautilusMenuItem *item;
 
4806
                NautilusMenu *menu;
 
4807
                GtkAction *action;
 
4808
                char *path;
 
4809
                
 
4810
                item = NAUTILUS_MENU_ITEM (l->data);
 
4811
                
 
4812
                g_object_get (item, "menu", &menu, NULL);
 
4813
                
 
4814
                action = add_extension_action_for_files (view, item, files);
 
4815
                
 
4816
                path = g_build_path ("/", NAUTILUS_VIEW_POPUP_PATH_EXTENSION_ACTIONS, subdirectory, NULL);
 
4817
                gtk_ui_manager_add_ui (ui_manager,
 
4818
                                       view->details->extensions_menu_merge_id,
 
4819
                                       path,
 
4820
                                       gtk_action_get_name (action),
 
4821
                                       gtk_action_get_name (action),
 
4822
                                       (menu != NULL) ? GTK_UI_MANAGER_MENU : GTK_UI_MANAGER_MENUITEM,
 
4823
                                       FALSE);
 
4824
                g_free (path);
 
4825
 
 
4826
                path = g_build_path ("/", NAUTILUS_VIEW_MENU_PATH_EXTENSION_ACTIONS_PLACEHOLDER, subdirectory, NULL);
 
4827
                gtk_ui_manager_add_ui (ui_manager,
 
4828
                                       view->details->extensions_menu_merge_id,
 
4829
                                       path,
 
4830
                                       gtk_action_get_name (action),
 
4831
                                       gtk_action_get_name (action),
 
4832
                                       (menu != NULL) ? GTK_UI_MANAGER_MENU : GTK_UI_MANAGER_MENUITEM,
 
4833
                                       FALSE);
 
4834
                g_free (path);
 
4835
 
 
4836
                /* recursively fill the menu */                
 
4837
                if (menu != NULL) {
 
4838
                        char *subdir;
 
4839
                        GList *children;
 
4840
                        
 
4841
                        children = nautilus_menu_get_items (menu);
 
4842
                        
 
4843
                        subdir = g_build_path ("/", subdirectory, gtk_action_get_name (action), NULL);
 
4844
                        add_extension_menu_items (view,
 
4845
                                                  files,
 
4846
                                                  children,
 
4847
                                                  subdir);
 
4848
 
 
4849
                        nautilus_menu_item_list_free (children);
 
4850
                        g_free (subdir);
 
4851
                }                       
 
4852
        }
 
4853
}
 
4854
 
 
4855
static void
 
4856
reset_extension_actions_menu (NautilusView *view, GList *selection)
 
4857
{
 
4858
        GList *items;
 
4859
        GtkUIManager *ui_manager;
 
4860
        
 
4861
        /* Clear any previous inserted items in the extension actions placeholder */
 
4862
        ui_manager = nautilus_window_get_ui_manager (view->details->window);
 
4863
 
 
4864
        nautilus_ui_unmerge_ui (ui_manager,
 
4865
                                &view->details->extensions_menu_merge_id,
 
4866
                                &view->details->extensions_menu_action_group);
 
4867
        
 
4868
        nautilus_ui_prepare_merge_ui (ui_manager,
 
4869
                                      "DirExtensionsMenuGroup",
 
4870
                                      &view->details->extensions_menu_merge_id,
 
4871
                                      &view->details->extensions_menu_action_group);
 
4872
 
 
4873
        items = get_all_extension_menu_items (gtk_widget_get_toplevel (GTK_WIDGET (view)), 
 
4874
                                              selection);
 
4875
        if (items != NULL) {
 
4876
                add_extension_menu_items (view, selection, items, "");
 
4877
 
 
4878
                g_list_foreach (items, (GFunc) g_object_unref, NULL);
 
4879
                g_list_free (items);
 
4880
        }
 
4881
}
 
4882
 
 
4883
static char *
 
4884
change_to_view_directory (NautilusView *view)
 
4885
{
 
4886
        char *path;
 
4887
        char *old_path;
 
4888
 
 
4889
        old_path = g_get_current_dir ();
 
4890
 
 
4891
        path = get_view_directory (view);
 
4892
 
 
4893
        /* FIXME: What to do about non-local directories? */
 
4894
        if (path != NULL) {
 
4895
                g_chdir (path);
 
4896
        }
 
4897
 
 
4898
        g_free (path);
 
4899
 
 
4900
        return old_path;
 
4901
}
 
4902
 
 
4903
static char **
 
4904
get_file_names_as_parameter_array (GList *selection,
 
4905
                                   NautilusDirectory *model)
 
4906
{
 
4907
        NautilusFile *file;
 
4908
        char **parameters;
 
4909
        GList *node;
 
4910
        GFile *file_location;
 
4911
        GFile *model_location;
 
4912
        int i;
 
4913
 
 
4914
        if (model == NULL) {
 
4915
                return NULL;
 
4916
        }
 
4917
 
 
4918
        parameters = g_new (char *, g_list_length (selection) + 1);
 
4919
 
 
4920
        model_location = nautilus_directory_get_location (model);
 
4921
 
 
4922
        for (node = selection, i = 0; node != NULL; node = node->next, i++) {
 
4923
                file = NAUTILUS_FILE (node->data);
 
4924
 
 
4925
                if (!nautilus_file_is_local (file)) {
 
4926
                        parameters[i] = NULL;
 
4927
                        g_strfreev (parameters);
 
4928
                        return NULL;
 
4929
                }
 
4930
 
 
4931
                file_location = nautilus_file_get_location (NAUTILUS_FILE (node->data));
 
4932
                parameters[i] = g_file_get_relative_path (model_location, file_location);
 
4933
                if (parameters[i] == NULL) {
 
4934
                        parameters[i] = g_file_get_path (file_location);
 
4935
                }
 
4936
                g_object_unref (file_location);
 
4937
        }
 
4938
 
 
4939
        g_object_unref (model_location);
 
4940
 
 
4941
        parameters[i] = NULL;
 
4942
        return parameters;
 
4943
}
 
4944
 
 
4945
static char *
 
4946
get_file_paths_or_uris_as_newline_delimited_string (GList *selection, gboolean get_paths)
 
4947
{
 
4948
        char *path;
 
4949
        char *uri;
 
4950
        char *result;
 
4951
        NautilusDesktopLink *link;
 
4952
        GString *expanding_string;
 
4953
        GList *node;
 
4954
        GFile *location;
 
4955
 
 
4956
        expanding_string = g_string_new ("");
 
4957
        for (node = selection; node != NULL; node = node->next) {
 
4958
                uri = NULL;
 
4959
                if (NAUTILUS_IS_DESKTOP_ICON_FILE (node->data)) {
 
4960
                        link = nautilus_desktop_icon_file_get_link (NAUTILUS_DESKTOP_ICON_FILE (node->data));
 
4961
                        if (link != NULL) {
 
4962
                                location = nautilus_desktop_link_get_activation_location (link);
 
4963
                                uri = g_file_get_uri (location);
 
4964
                                g_object_unref (location);
 
4965
                                g_object_unref (G_OBJECT (link));
 
4966
                        }
 
4967
                } else {
 
4968
                        uri = nautilus_file_get_uri (NAUTILUS_FILE (node->data));
 
4969
                }
 
4970
                if (uri == NULL) {
 
4971
                        continue;
 
4972
                }
 
4973
 
 
4974
                if (get_paths) {
 
4975
                        path = g_filename_from_uri (uri, NULL, NULL);
 
4976
                        if (path != NULL) {
 
4977
                                g_string_append (expanding_string, path);
 
4978
                                g_free (path);
 
4979
                                g_string_append (expanding_string, "\n");
 
4980
                        }
 
4981
                } else {
 
4982
                        g_string_append (expanding_string, uri);
 
4983
                        g_string_append (expanding_string, "\n");
 
4984
                }
 
4985
                g_free (uri);
 
4986
        }
 
4987
 
 
4988
        result = expanding_string->str;
 
4989
        g_string_free (expanding_string, FALSE);
 
4990
 
 
4991
        return result;
 
4992
}
 
4993
 
 
4994
static char *
 
4995
get_file_paths_as_newline_delimited_string (GList *selection)
 
4996
{
 
4997
        return get_file_paths_or_uris_as_newline_delimited_string (selection, TRUE);
 
4998
}
 
4999
 
 
5000
static char *
 
5001
get_file_uris_as_newline_delimited_string (GList *selection)
 
5002
{
 
5003
        return get_file_paths_or_uris_as_newline_delimited_string (selection, FALSE);
 
5004
}
 
5005
 
 
5006
/* returns newly allocated strings for setting the environment variables */
 
5007
static void
 
5008
get_strings_for_environment_variables (NautilusView *view, GList *selected_files,
 
5009
                                       char **file_paths, char **uris, char **uri)
 
5010
{
 
5011
        char *directory_uri;
 
5012
 
 
5013
        /* We need to check that the directory uri starts with "file:" since
 
5014
         * nautilus_directory_is_local returns FALSE for nfs.
 
5015
         */
 
5016
        directory_uri = nautilus_directory_get_uri (view->details->model);
 
5017
        if (eel_str_has_prefix (directory_uri, "file:") ||
 
5018
            eel_uri_is_desktop (directory_uri) ||
 
5019
            eel_uri_is_trash (directory_uri)) {
 
5020
                *file_paths = get_file_paths_as_newline_delimited_string (selected_files);
 
5021
        } else {
 
5022
                *file_paths = g_strdup ("");
 
5023
        }
 
5024
        g_free (directory_uri);
 
5025
 
 
5026
        *uris = get_file_uris_as_newline_delimited_string (selected_files);
 
5027
 
 
5028
        *uri = nautilus_directory_get_uri (view->details->model);
 
5029
        if (eel_uri_is_desktop (*uri)) {
 
5030
                g_free (*uri);
 
5031
                *uri = nautilus_get_desktop_directory_uri ();
 
5032
        }
 
5033
}
 
5034
 
 
5035
static NautilusView *
 
5036
get_directory_view_of_extra_pane (NautilusView *view)
 
5037
{
 
5038
        NautilusWindowSlot *slot;
 
5039
        NautilusView *next_view;
 
5040
 
 
5041
        slot = nautilus_window_get_extra_slot (nautilus_view_get_nautilus_window (view));
 
5042
        if (slot != NULL) {
 
5043
                next_view = nautilus_window_slot_get_current_view (slot);
 
5044
 
 
5045
                if (NAUTILUS_IS_VIEW (next_view)) {
 
5046
                        return NAUTILUS_VIEW (next_view);
 
5047
                }
 
5048
        }
 
5049
        return NULL;
 
5050
}
 
5051
 
 
5052
/*
 
5053
 * Set up some environment variables that scripts can use
 
5054
 * to take advantage of the current Nautilus state.
 
5055
 */
 
5056
static void
 
5057
set_script_environment_variables (NautilusView *view, GList *selected_files)
 
5058
{
 
5059
        char *file_paths;
 
5060
        char *uris;
 
5061
        char *uri;
 
5062
        char *geometry_string;
 
5063
        NautilusView *next_view;
 
5064
 
 
5065
        get_strings_for_environment_variables (view, selected_files,
 
5066
                                               &file_paths, &uris, &uri);
 
5067
 
 
5068
        g_setenv ("NAUTILUS_SCRIPT_SELECTED_FILE_PATHS", file_paths, TRUE);
 
5069
        g_free (file_paths);
 
5070
 
 
5071
        g_setenv ("NAUTILUS_SCRIPT_SELECTED_URIS", uris, TRUE);
 
5072
        g_free (uris);
 
5073
 
 
5074
        g_setenv ("NAUTILUS_SCRIPT_CURRENT_URI", uri, TRUE);
 
5075
        g_free (uri);
 
5076
 
 
5077
        geometry_string = eel_gtk_window_get_geometry_string
 
5078
                (GTK_WINDOW (nautilus_view_get_containing_window (view)));
 
5079
        g_setenv ("NAUTILUS_SCRIPT_WINDOW_GEOMETRY", geometry_string, TRUE);
 
5080
        g_free (geometry_string);
 
5081
 
 
5082
        /* next pane */
 
5083
        next_view = get_directory_view_of_extra_pane (view);
 
5084
        if (next_view) {
 
5085
                GList *next_pane_selected_files;
 
5086
                next_pane_selected_files = nautilus_view_get_selection (next_view);
 
5087
 
 
5088
                get_strings_for_environment_variables (next_view, next_pane_selected_files,
 
5089
                                                       &file_paths, &uris, &uri);
 
5090
                nautilus_file_list_free (next_pane_selected_files);
 
5091
        } else {
 
5092
                file_paths = g_strdup("");
 
5093
                uris = g_strdup("");
 
5094
                uri = g_strdup("");
 
5095
        }
 
5096
 
 
5097
        g_setenv ("NAUTILUS_SCRIPT_NEXT_PANE_SELECTED_FILE_PATHS", file_paths, TRUE);
 
5098
        g_free (file_paths);
 
5099
 
 
5100
        g_setenv ("NAUTILUS_SCRIPT_NEXT_PANE_SELECTED_URIS", uris, TRUE);
 
5101
        g_free (uris);
 
5102
 
 
5103
        g_setenv ("NAUTILUS_SCRIPT_NEXT_PANE_CURRENT_URI", uri, TRUE);
 
5104
        g_free (uri);
 
5105
}
 
5106
 
 
5107
/* Unset all the special script environment variables. */
 
5108
static void
 
5109
unset_script_environment_variables (void)
 
5110
{
 
5111
        g_unsetenv ("NAUTILUS_SCRIPT_SELECTED_FILE_PATHS");
 
5112
        g_unsetenv ("NAUTILUS_SCRIPT_SELECTED_URIS");
 
5113
        g_unsetenv ("NAUTILUS_SCRIPT_CURRENT_URI");
 
5114
        g_unsetenv ("NAUTILUS_SCRIPT_WINDOW_GEOMETRY");
 
5115
        g_unsetenv ("NAUTILUS_SCRIPT_NEXT_PANE_SELECTED_FILE_PATHS");
 
5116
        g_unsetenv ("NAUTILUS_SCRIPT_NEXT_PANE_SELECTED_URIS");
 
5117
        g_unsetenv ("NAUTILUS_SCRIPT_NEXT_PANE_CURRENT_URI");
 
5118
}
 
5119
 
 
5120
static void
 
5121
run_script_callback (GtkAction *action, gpointer callback_data)
 
5122
{
 
5123
        ScriptLaunchParameters *launch_parameters;
 
5124
        GdkScreen *screen;
 
5125
        GList *selected_files;
 
5126
        char *file_uri;
 
5127
        char *local_file_path;
 
5128
        char *quoted_path;
 
5129
        char *old_working_dir;
 
5130
        char **parameters;
 
5131
        
 
5132
        launch_parameters = (ScriptLaunchParameters *) callback_data;
 
5133
 
 
5134
        file_uri = nautilus_file_get_uri (launch_parameters->file);
 
5135
        local_file_path = g_filename_from_uri (file_uri, NULL, NULL);
 
5136
        g_assert (local_file_path != NULL);
 
5137
        g_free (file_uri);
 
5138
 
 
5139
        quoted_path = g_shell_quote (local_file_path);
 
5140
        g_free (local_file_path);
 
5141
 
 
5142
        old_working_dir = change_to_view_directory (launch_parameters->directory_view);
 
5143
 
 
5144
        selected_files = nautilus_view_get_selection (launch_parameters->directory_view);
 
5145
        set_script_environment_variables (launch_parameters->directory_view, selected_files);
 
5146
         
 
5147
        parameters = get_file_names_as_parameter_array (selected_files,
 
5148
                                                        launch_parameters->directory_view->details->model);
 
5149
 
 
5150
        screen = gtk_widget_get_screen (GTK_WIDGET (launch_parameters->directory_view));
 
5151
 
 
5152
        DEBUG ("run_script_callback, script_path=\"%s\" (omitting script parameters)",
 
5153
               local_file_path);
 
5154
 
 
5155
        nautilus_launch_application_from_command_array (screen, quoted_path, FALSE,
 
5156
                                                        (const char * const *) parameters);
 
5157
        g_strfreev (parameters);
 
5158
 
 
5159
        nautilus_file_list_free (selected_files);
 
5160
        unset_script_environment_variables ();
 
5161
        g_chdir (old_working_dir);              
 
5162
        g_free (old_working_dir);
 
5163
        g_free (quoted_path);
 
5164
}
 
5165
 
 
5166
static void
 
5167
add_script_to_scripts_menus (NautilusView *directory_view,
 
5168
                             NautilusFile *file,
 
5169
                             const char *menu_path,
 
5170
                             const char *popup_path, 
 
5171
                             const char *popup_bg_path)
 
5172
{
 
5173
        ScriptLaunchParameters *launch_parameters;
 
5174
        char *tip;
 
5175
        char *name;
 
5176
        char *uri;
 
5177
        char *action_name;
 
5178
        char *escaped_label;
 
5179
        GdkPixbuf *pixbuf;
 
5180
        GtkUIManager *ui_manager;
 
5181
        GtkAction *action;
 
5182
 
 
5183
        name = nautilus_file_get_display_name (file);
 
5184
        uri = nautilus_file_get_uri (file);
 
5185
        tip = g_strdup_printf (_("Run \"%s\" on any selected items"), name);
 
5186
 
 
5187
        launch_parameters = script_launch_parameters_new (file, directory_view);
 
5188
 
 
5189
        action_name = escape_action_name (uri, "script_");
 
5190
        escaped_label = eel_str_double_underscores (name);
 
5191
 
 
5192
        action = gtk_action_new (action_name,
 
5193
                                 escaped_label,
 
5194
                                 tip,
 
5195
                                 NULL);
 
5196
 
 
5197
        pixbuf = get_menu_icon_for_file (file);
 
5198
        if (pixbuf != NULL) {
 
5199
                g_object_set_data_full (G_OBJECT (action), "menu-icon",
 
5200
                                        pixbuf,
 
5201
                                        g_object_unref);
 
5202
        }
 
5203
 
 
5204
        g_signal_connect_data (action, "activate",
 
5205
                               G_CALLBACK (run_script_callback),
 
5206
                               launch_parameters,
 
5207
                               (GClosureNotify)script_launch_parameters_free, 0);
 
5208
 
 
5209
        gtk_action_group_add_action_with_accel (directory_view->details->scripts_action_group,
 
5210
                                                action, NULL);
 
5211
        g_object_unref (action);
 
5212
 
 
5213
        ui_manager = nautilus_window_get_ui_manager (directory_view->details->window);
 
5214
 
 
5215
        gtk_ui_manager_add_ui (ui_manager,
 
5216
                               directory_view->details->scripts_merge_id,
 
5217
                               menu_path,
 
5218
                               action_name,
 
5219
                               action_name,
 
5220
                               GTK_UI_MANAGER_MENUITEM,
 
5221
                               FALSE);
 
5222
        gtk_ui_manager_add_ui (ui_manager,
 
5223
                               directory_view->details->scripts_merge_id,
 
5224
                               popup_path,
 
5225
                               action_name,
 
5226
                               action_name,
 
5227
                               GTK_UI_MANAGER_MENUITEM,
 
5228
                               FALSE);
 
5229
        gtk_ui_manager_add_ui (ui_manager,
 
5230
                               directory_view->details->scripts_merge_id,
 
5231
                               popup_bg_path,
 
5232
                               action_name,
 
5233
                               action_name,
 
5234
                               GTK_UI_MANAGER_MENUITEM,
 
5235
                               FALSE);
 
5236
 
 
5237
        g_free (name);
 
5238
        g_free (uri);
 
5239
        g_free (tip);
 
5240
        g_free (action_name);
 
5241
        g_free (escaped_label);
 
5242
}
 
5243
 
 
5244
static void
 
5245
add_submenu_to_directory_menus (NautilusView *directory_view,
 
5246
                                GtkActionGroup *action_group,
 
5247
                                guint merge_id,
 
5248
                                NautilusFile *file,
 
5249
                                const char *menu_path,
 
5250
                                const char *popup_path,
 
5251
                                const char *popup_bg_path)
 
5252
{
 
5253
        char *name;
 
5254
        GdkPixbuf *pixbuf;
 
5255
        char *uri;
 
5256
        GtkUIManager *ui_manager;
 
5257
 
 
5258
        ui_manager = nautilus_window_get_ui_manager (directory_view->details->window);
 
5259
        uri = nautilus_file_get_uri (file);
 
5260
        name = nautilus_file_get_display_name (file);
 
5261
        pixbuf = get_menu_icon_for_file (file);
 
5262
        add_submenu (ui_manager, action_group, merge_id, menu_path, uri, name, pixbuf, TRUE);
 
5263
        add_submenu (ui_manager, action_group, merge_id, popup_path, uri, name, pixbuf, FALSE);
 
5264
        add_submenu (ui_manager, action_group, merge_id, popup_bg_path, uri, name, pixbuf, FALSE);
 
5265
        if (pixbuf) {
 
5266
                g_object_unref (pixbuf);
 
5267
        }
 
5268
        g_free (name);
 
5269
        g_free (uri);
 
5270
}
 
5271
 
 
5272
static gboolean
 
5273
directory_belongs_in_scripts_menu (const char *uri)
 
5274
{
 
5275
        int num_levels;
 
5276
        int i;
 
5277
 
 
5278
        if (!eel_str_has_prefix (uri, scripts_directory_uri)) {
 
5279
                return FALSE;
 
5280
        }
 
5281
 
 
5282
        num_levels = 0;
 
5283
        for (i = scripts_directory_uri_length; uri[i] != '\0'; i++) {
 
5284
                if (uri[i] == '/') {
 
5285
                        num_levels++;
 
5286
                }
 
5287
        }
 
5288
 
 
5289
        if (num_levels > MAX_MENU_LEVELS) {
 
5290
                return FALSE;
 
5291
        }
 
5292
 
 
5293
        return TRUE;
 
5294
}
 
5295
 
 
5296
static gboolean
 
5297
update_directory_in_scripts_menu (NautilusView *view, NautilusDirectory *directory)
 
5298
{
 
5299
        char *menu_path, *popup_path, *popup_bg_path;
 
5300
        GList *file_list, *filtered, *node;
 
5301
        gboolean any_scripts;
 
5302
        NautilusFile *file;
 
5303
        NautilusDirectory *dir;
 
5304
        char *uri;
 
5305
        char *escaped_path;
 
5306
        
 
5307
        uri = nautilus_directory_get_uri (directory);
 
5308
        escaped_path = escape_action_path (uri + scripts_directory_uri_length);
 
5309
        g_free (uri);
 
5310
        menu_path = g_strconcat (NAUTILUS_VIEW_MENU_PATH_SCRIPTS_PLACEHOLDER,
 
5311
                                 escaped_path,
 
5312
                                 NULL);
 
5313
        popup_path = g_strconcat (NAUTILUS_VIEW_POPUP_PATH_SCRIPTS_PLACEHOLDER,
 
5314
                                  escaped_path,
 
5315
                                  NULL);
 
5316
        popup_bg_path = g_strconcat (NAUTILUS_VIEW_POPUP_PATH_BACKGROUND_SCRIPTS_PLACEHOLDER,
 
5317
                                     escaped_path,
 
5318
                                     NULL);
 
5319
        g_free (escaped_path);
 
5320
 
 
5321
        file_list = nautilus_directory_get_file_list (directory);
 
5322
        filtered = nautilus_file_list_filter_hidden (file_list, FALSE);
 
5323
        nautilus_file_list_free (file_list);
 
5324
 
 
5325
        file_list = nautilus_file_list_sort_by_display_name (filtered);
 
5326
 
 
5327
        any_scripts = FALSE;
 
5328
        for (node = file_list; node != NULL; node = node->next) {
 
5329
                file = node->data;
 
5330
 
 
5331
                if (nautilus_file_is_launchable (file)) {
 
5332
                        add_script_to_scripts_menus (view, file, menu_path, popup_path, popup_bg_path);
 
5333
                        any_scripts = TRUE;
 
5334
                } else if (nautilus_file_is_directory (file)) {
 
5335
                        uri = nautilus_file_get_uri (file);
 
5336
                        if (directory_belongs_in_scripts_menu (uri)) {
 
5337
                                dir = nautilus_directory_get_by_uri (uri);
 
5338
                                add_directory_to_scripts_directory_list (view, dir);
 
5339
                                nautilus_directory_unref (dir);
 
5340
 
 
5341
                                add_submenu_to_directory_menus (view,
 
5342
                                                                view->details->scripts_action_group,
 
5343
                                                                view->details->scripts_merge_id,
 
5344
                                                                file, menu_path, popup_path, popup_bg_path);
 
5345
 
 
5346
                                any_scripts = TRUE;
 
5347
                        }
 
5348
                        g_free (uri);
 
5349
                }
 
5350
        }
 
5351
 
 
5352
        nautilus_file_list_free (file_list);
 
5353
 
 
5354
        g_free (popup_path);
 
5355
        g_free (popup_bg_path);
 
5356
        g_free (menu_path);
 
5357
 
 
5358
        return any_scripts;
 
5359
}
 
5360
 
 
5361
static void
 
5362
update_scripts_menu (NautilusView *view)
 
5363
{
 
5364
        gboolean any_scripts;
 
5365
        GList *sorted_copy, *node;
 
5366
        NautilusDirectory *directory;
 
5367
        char *uri;
 
5368
        GtkUIManager *ui_manager;
 
5369
        GtkAction *action;
 
5370
 
 
5371
        /* There is a race condition here.  If we don't mark the scripts menu as
 
5372
           valid before we begin our task then we can lose script menu updates that
 
5373
           occur before we finish. */
 
5374
        view->details->scripts_invalid = FALSE;
 
5375
 
 
5376
        ui_manager = nautilus_window_get_ui_manager (view->details->window);
 
5377
        nautilus_ui_unmerge_ui (ui_manager,
 
5378
                                &view->details->scripts_merge_id,
 
5379
                                &view->details->scripts_action_group);
 
5380
        
 
5381
        nautilus_ui_prepare_merge_ui (ui_manager,
 
5382
                                      "ScriptsGroup",
 
5383
                                      &view->details->scripts_merge_id,
 
5384
                                      &view->details->scripts_action_group);
 
5385
 
 
5386
        /* As we walk through the directories, remove any that no longer belong. */
 
5387
        any_scripts = FALSE;
 
5388
        sorted_copy = nautilus_directory_list_sort_by_uri
 
5389
                (nautilus_directory_list_copy (view->details->scripts_directory_list));
 
5390
        for (node = sorted_copy; node != NULL; node = node->next) {
 
5391
                directory = node->data;
 
5392
 
 
5393
                uri = nautilus_directory_get_uri (directory);
 
5394
                if (!directory_belongs_in_scripts_menu (uri)) {
 
5395
                        remove_directory_from_scripts_directory_list (view, directory);
 
5396
                } else if (update_directory_in_scripts_menu (view, directory)) {
 
5397
                        any_scripts = TRUE;
 
5398
                }
 
5399
                g_free (uri);
 
5400
        }
 
5401
        nautilus_directory_list_free (sorted_copy);
 
5402
 
 
5403
        action = gtk_action_group_get_action (view->details->dir_action_group, NAUTILUS_ACTION_SCRIPTS);
 
5404
        gtk_action_set_visible (action, any_scripts);
 
5405
}
 
5406
 
 
5407
static void
 
5408
create_template_callback (GtkAction *action, gpointer callback_data)
 
5409
{
 
5410
        CreateTemplateParameters *parameters;
 
5411
 
 
5412
        parameters = callback_data;
 
5413
        
 
5414
        nautilus_view_new_file (parameters->directory_view, NULL, parameters->file);
 
5415
}
 
5416
 
 
5417
static void
 
5418
add_template_to_templates_menus (NautilusView *directory_view,
 
5419
                                 NautilusFile *file,
 
5420
                                 const char *menu_path,
 
5421
                                 const char *popup_bg_path)
 
5422
{
 
5423
        char *tmp, *tip, *uri, *name;
 
5424
        char *escaped_label;
 
5425
        GdkPixbuf *pixbuf;
 
5426
        char *action_name;
 
5427
        CreateTemplateParameters *parameters;
 
5428
        GtkUIManager *ui_manager;
 
5429
        GtkAction *action;
 
5430
 
 
5431
        tmp = nautilus_file_get_display_name (file);
 
5432
        name = eel_filename_strip_extension (tmp);
 
5433
        g_free (tmp);
 
5434
 
 
5435
        uri = nautilus_file_get_uri (file);
 
5436
        tip = g_strdup_printf (_("Create a new document from template \"%s\""), name);
 
5437
 
 
5438
        action_name = escape_action_name (uri, "template_");
 
5439
        escaped_label = eel_str_double_underscores (name);
 
5440
        
 
5441
        parameters = create_template_parameters_new (file, directory_view);
 
5442
 
 
5443
        action = gtk_action_new (action_name,
 
5444
                                 escaped_label,
 
5445
                                 tip,
 
5446
                                 NULL);
 
5447
        
 
5448
        pixbuf = get_menu_icon_for_file (file);
 
5449
        if (pixbuf != NULL) {
 
5450
                g_object_set_data_full (G_OBJECT (action), "menu-icon",
 
5451
                                        pixbuf,
 
5452
                                        g_object_unref);
 
5453
        }
 
5454
 
 
5455
        g_signal_connect_data (action, "activate",
 
5456
                               G_CALLBACK (create_template_callback),
 
5457
                               parameters, 
 
5458
                               (GClosureNotify)create_templates_parameters_free, 0);
 
5459
        
 
5460
        gtk_action_group_add_action (directory_view->details->templates_action_group,
 
5461
                                     action);
 
5462
        g_object_unref (action);
 
5463
 
 
5464
        ui_manager = nautilus_window_get_ui_manager (directory_view->details->window);
 
5465
 
 
5466
        gtk_ui_manager_add_ui (ui_manager,
 
5467
                               directory_view->details->templates_merge_id,
 
5468
                               menu_path,
 
5469
                               action_name,
 
5470
                               action_name,
 
5471
                               GTK_UI_MANAGER_MENUITEM,
 
5472
                               FALSE);
 
5473
        
 
5474
        gtk_ui_manager_add_ui (ui_manager,
 
5475
                               directory_view->details->templates_merge_id,
 
5476
                               popup_bg_path,
 
5477
                               action_name,
 
5478
                               action_name,
 
5479
                               GTK_UI_MANAGER_MENUITEM,
 
5480
                               FALSE);
 
5481
        
 
5482
        g_free (escaped_label);
 
5483
        g_free (name);
 
5484
        g_free (tip);
 
5485
        g_free (uri);
 
5486
        g_free (action_name);
 
5487
}
 
5488
 
 
5489
static void
 
5490
update_templates_directory (NautilusView *view)
 
5491
{
 
5492
        NautilusDirectory *templates_directory;
 
5493
        GList *node, *next;
 
5494
        char *templates_uri;
 
5495
 
 
5496
        for (node = view->details->templates_directory_list; node != NULL; node = next) {
 
5497
                next = node->next;
 
5498
                remove_directory_from_templates_directory_list (view, node->data);
 
5499
        }
 
5500
        
 
5501
        if (nautilus_should_use_templates_directory ()) {
 
5502
                templates_uri = nautilus_get_templates_directory_uri ();
 
5503
                templates_directory = nautilus_directory_get_by_uri (templates_uri);
 
5504
                g_free (templates_uri);
 
5505
                add_directory_to_templates_directory_list (view, templates_directory);
 
5506
                nautilus_directory_unref (templates_directory);
 
5507
        }
 
5508
}
 
5509
 
 
5510
static void
 
5511
user_dirs_changed (NautilusView *view)
 
5512
{
 
5513
        update_templates_directory (view);
 
5514
        view->details->templates_invalid = TRUE;
 
5515
        schedule_update_menus (view);
 
5516
}
 
5517
 
 
5518
static gboolean
 
5519
directory_belongs_in_templates_menu (const char *templates_directory_uri,
 
5520
                                     const char *uri)
 
5521
{
 
5522
        int num_levels;
 
5523
        int i;
 
5524
 
 
5525
        if (templates_directory_uri == NULL) {
 
5526
                return FALSE;
 
5527
        }
 
5528
        
 
5529
        if (!g_str_has_prefix (uri, templates_directory_uri)) {
 
5530
                return FALSE;
 
5531
        }
 
5532
 
 
5533
        num_levels = 0;
 
5534
        for (i = strlen (templates_directory_uri); uri[i] != '\0'; i++) {
 
5535
                if (uri[i] == '/') {
 
5536
                        num_levels++;
 
5537
                }
 
5538
        }
 
5539
 
 
5540
        if (num_levels > MAX_MENU_LEVELS) {
 
5541
                return FALSE;
 
5542
        }
 
5543
 
 
5544
        return TRUE;
 
5545
}
 
5546
 
 
5547
static gboolean
 
5548
update_directory_in_templates_menu (NautilusView *view,
 
5549
                                    const char *templates_directory_uri,
 
5550
                                    NautilusDirectory *directory)
 
5551
{
 
5552
        char *menu_path, *popup_bg_path;
 
5553
        GList *file_list, *filtered, *node;
 
5554
        gboolean any_templates;
 
5555
        NautilusFile *file;
 
5556
        NautilusDirectory *dir;
 
5557
        char *escaped_path;
 
5558
        char *uri;
 
5559
        int num;
 
5560
 
 
5561
        /* We know this directory belongs to the template dir, so it must exist */
 
5562
        g_assert (templates_directory_uri);
 
5563
        
 
5564
        uri = nautilus_directory_get_uri (directory);
 
5565
        escaped_path = escape_action_path (uri + strlen (templates_directory_uri));
 
5566
        g_free (uri);
 
5567
        menu_path = g_strconcat (NAUTILUS_VIEW_MENU_PATH_NEW_DOCUMENTS_PLACEHOLDER,
 
5568
                                 escaped_path,
 
5569
                                 NULL);
 
5570
        popup_bg_path = g_strconcat (NAUTILUS_VIEW_POPUP_PATH_BACKGROUND_NEW_DOCUMENTS_PLACEHOLDER,
 
5571
                                     escaped_path,
 
5572
                                     NULL);
 
5573
        g_free (escaped_path);
 
5574
 
 
5575
        file_list = nautilus_directory_get_file_list (directory);
 
5576
        filtered = nautilus_file_list_filter_hidden (file_list, FALSE);
 
5577
        nautilus_file_list_free (file_list);
 
5578
 
 
5579
        file_list = nautilus_file_list_sort_by_display_name (filtered);
 
5580
 
 
5581
        num = 0;
 
5582
        any_templates = FALSE;
 
5583
        for (node = file_list; num < TEMPLATE_LIMIT && node != NULL; node = node->next, num++) {
 
5584
                file = node->data;
 
5585
 
 
5586
                if (nautilus_file_is_directory (file)) {
 
5587
                        uri = nautilus_file_get_uri (file);
 
5588
                        if (directory_belongs_in_templates_menu (templates_directory_uri, uri)) {
 
5589
                                dir = nautilus_directory_get_by_uri (uri);
 
5590
                                add_directory_to_templates_directory_list (view, dir);
 
5591
                                nautilus_directory_unref (dir);
 
5592
 
 
5593
                                add_submenu_to_directory_menus (view,
 
5594
                                                                view->details->templates_action_group,
 
5595
                                                                view->details->templates_merge_id,
 
5596
                                                                file, menu_path, NULL, popup_bg_path);
 
5597
 
 
5598
                                any_templates = TRUE;
 
5599
                        }
 
5600
                        g_free (uri);
 
5601
                } else if (nautilus_file_can_read (file)) {
 
5602
                        add_template_to_templates_menus (view, file, menu_path, popup_bg_path);
 
5603
                        any_templates = TRUE;
 
5604
                }
 
5605
        }
 
5606
 
 
5607
        nautilus_file_list_free (file_list);
 
5608
 
 
5609
        g_free (popup_bg_path);
 
5610
        g_free (menu_path);
 
5611
 
 
5612
        return any_templates;
 
5613
}
 
5614
 
 
5615
 
 
5616
 
 
5617
static void
 
5618
update_templates_menu (NautilusView *view)
 
5619
{
 
5620
        gboolean any_templates;
 
5621
        GList *sorted_copy, *node;
 
5622
        NautilusDirectory *directory;
 
5623
        GtkUIManager *ui_manager;
 
5624
        char *uri;
 
5625
        GtkAction *action;
 
5626
        char *templates_directory_uri;
 
5627
 
 
5628
        if (nautilus_should_use_templates_directory ()) {
 
5629
                templates_directory_uri = nautilus_get_templates_directory_uri ();
 
5630
        } else {
 
5631
                templates_directory_uri = NULL;
 
5632
        }
 
5633
 
 
5634
        /* There is a race condition here.  If we don't mark the scripts menu as
 
5635
           valid before we begin our task then we can lose template menu updates that
 
5636
           occur before we finish. */
 
5637
        view->details->templates_invalid = FALSE;
 
5638
 
 
5639
        ui_manager = nautilus_window_get_ui_manager (view->details->window);
 
5640
        nautilus_ui_unmerge_ui (ui_manager,
 
5641
                                &view->details->templates_merge_id,
 
5642
                                &view->details->templates_action_group);
 
5643
 
 
5644
        nautilus_ui_prepare_merge_ui (ui_manager,
 
5645
                                      "TemplatesGroup",
 
5646
                                      &view->details->templates_merge_id,
 
5647
                                      &view->details->templates_action_group);
 
5648
 
 
5649
        /* As we walk through the directories, remove any that no longer belong. */
 
5650
        any_templates = FALSE;
 
5651
        sorted_copy = nautilus_directory_list_sort_by_uri
 
5652
                (nautilus_directory_list_copy (view->details->templates_directory_list));
 
5653
        for (node = sorted_copy; node != NULL; node = node->next) {
 
5654
                directory = node->data;
 
5655
 
 
5656
                uri = nautilus_directory_get_uri (directory);
 
5657
                if (!directory_belongs_in_templates_menu (templates_directory_uri, uri)) {
 
5658
                        remove_directory_from_templates_directory_list (view, directory);
 
5659
                } else if (update_directory_in_templates_menu (view,
 
5660
                                                               templates_directory_uri,
 
5661
                                                               directory)) {
 
5662
                        any_templates = TRUE;
 
5663
                }
 
5664
                g_free (uri);
 
5665
        }
 
5666
        nautilus_directory_list_free (sorted_copy);
 
5667
 
 
5668
        action = gtk_action_group_get_action (view->details->dir_action_group, NAUTILUS_ACTION_NO_TEMPLATES);
 
5669
        gtk_action_set_visible (action, !any_templates);
 
5670
 
 
5671
        g_free (templates_directory_uri);
 
5672
}
 
5673
 
 
5674
 
 
5675
static void
 
5676
action_open_scripts_folder_callback (GtkAction *action, 
 
5677
                                     gpointer callback_data)
 
5678
{      
 
5679
        NautilusView *view;
 
5680
        static GFile *location = NULL;
 
5681
 
 
5682
        if (location == NULL) {
 
5683
                location = g_file_new_for_uri (scripts_directory_uri);
 
5684
        }
 
5685
 
 
5686
        view = NAUTILUS_VIEW (callback_data);
 
5687
        nautilus_window_slot_go_to (view->details->slot, location, FALSE);
 
5688
 
 
5689
        eel_show_info_dialog_with_details 
 
5690
                (_("All executable files in this folder will appear in the "
 
5691
                   "Scripts menu."),
 
5692
                 _("Choosing a script from the menu will run "
 
5693
                   "that script with any selected items as input."), 
 
5694
                 _("All executable files in this folder will appear in the "
 
5695
                   "Scripts menu. Choosing a script from the menu will run "
 
5696
                   "that script.\n\n"
 
5697
                   "When executed from a local folder, scripts will be passed "
 
5698
                   "the selected file names. When executed from a remote folder "
 
5699
                   "(e.g. a folder showing web or ftp content), scripts will "
 
5700
                   "be passed no parameters.\n\n"
 
5701
                   "In all cases, the following environment variables will be "
 
5702
                   "set by Nautilus, which the scripts may use:\n\n"
 
5703
                   "NAUTILUS_SCRIPT_SELECTED_FILE_PATHS: newline-delimited paths for selected files (only if local)\n\n"
 
5704
                   "NAUTILUS_SCRIPT_SELECTED_URIS: newline-delimited URIs for selected files\n\n"
 
5705
                   "NAUTILUS_SCRIPT_CURRENT_URI: URI for current location\n\n"
 
5706
                   "NAUTILUS_SCRIPT_WINDOW_GEOMETRY: position and size of current window\n\n"
 
5707
                   "NAUTILUS_SCRIPT_NEXT_PANE_SELECTED_FILE_PATHS: newline-delimited paths for selected files in the inactive pane of a split-view window (only if local)\n\n"
 
5708
                   "NAUTILUS_SCRIPT_NEXT_PANE_SELECTED_URIS: newline-delimited URIs for selected files in the inactive pane of a split-view window\n\n"
 
5709
                   "NAUTILUS_SCRIPT_NEXT_PANE_CURRENT_URI: URI for current location in the inactive pane of a split-view window"),
 
5710
                 nautilus_view_get_containing_window (view));
 
5711
}
 
5712
 
 
5713
static GtkMenu *
 
5714
create_popup_menu (NautilusView *view, const char *popup_path)
 
5715
{
 
5716
        GtkWidget *menu;
 
5717
        
 
5718
        menu = gtk_ui_manager_get_widget (nautilus_window_get_ui_manager (view->details->window),
 
5719
                                          popup_path);
 
5720
        gtk_menu_set_screen (GTK_MENU (menu),
 
5721
                             gtk_widget_get_screen (GTK_WIDGET (view)));
 
5722
        gtk_widget_show (GTK_WIDGET (menu));
 
5723
 
 
5724
        return GTK_MENU (menu);
 
5725
}
 
5726
        
 
5727
static void
 
5728
copy_or_cut_files (NautilusView *view,
 
5729
                   GList           *clipboard_contents,
 
5730
                   gboolean         cut)
 
5731
{
 
5732
        int count;
 
5733
        char *status_string, *name;
 
5734
        NautilusClipboardInfo info;
 
5735
        GtkTargetList *target_list;
 
5736
        GtkTargetEntry *targets;
 
5737
        int n_targets;
 
5738
 
 
5739
        info.files = clipboard_contents;
 
5740
        info.cut = cut;
 
5741
 
 
5742
        target_list = gtk_target_list_new (NULL, 0);
 
5743
        gtk_target_list_add (target_list, copied_files_atom, 0, 0);
 
5744
        gtk_target_list_add_uri_targets (target_list, 0);
 
5745
        gtk_target_list_add_text_targets (target_list, 0);
 
5746
 
 
5747
        targets = gtk_target_table_new_from_list (target_list, &n_targets);
 
5748
        gtk_target_list_unref (target_list);
 
5749
 
 
5750
        gtk_clipboard_set_with_data (nautilus_clipboard_get (GTK_WIDGET (view)),
 
5751
                                     targets, n_targets,
 
5752
                                     nautilus_get_clipboard_callback, nautilus_clear_clipboard_callback,
 
5753
                                     NULL);
 
5754
        gtk_target_table_free (targets, n_targets);
 
5755
 
 
5756
        nautilus_clipboard_monitor_set_clipboard_info (nautilus_clipboard_monitor_get (), &info);
 
5757
 
 
5758
        count = g_list_length (clipboard_contents);
 
5759
        if (count == 1) {
 
5760
                name = nautilus_file_get_display_name (clipboard_contents->data);
 
5761
                if (cut) {
 
5762
                        status_string = g_strdup_printf (_("\"%s\" will be moved "
 
5763
                                                           "if you select the Paste command"),
 
5764
                                                         name);
 
5765
                } else {
 
5766
                        status_string = g_strdup_printf (_("\"%s\" will be copied "
 
5767
                                                           "if you select the Paste command"),
 
5768
                                                         name);
 
5769
                }
 
5770
                g_free (name);
 
5771
        } else {
 
5772
                if (cut) {
 
5773
                        status_string = g_strdup_printf (ngettext("The %'d selected item will be moved "
 
5774
                                                                  "if you select the Paste command",
 
5775
                                                                  "The %'d selected items will be moved "
 
5776
                                                                  "if you select the Paste command",
 
5777
                                                                  count),
 
5778
                                                         count);
 
5779
                } else {
 
5780
                        status_string = g_strdup_printf (ngettext("The %'d selected item will be copied "
 
5781
                                                                  "if you select the Paste command",
 
5782
                                                                  "The %'d selected items will be copied "
 
5783
                                                                  "if you select the Paste command",
 
5784
                                                                  count),
 
5785
                                                         count);
 
5786
                }
 
5787
        }
 
5788
 
 
5789
        nautilus_window_slot_set_status (view->details->slot,
 
5790
                                         status_string, NULL);
 
5791
        g_free (status_string);
 
5792
}
 
5793
 
 
5794
static void
 
5795
action_copy_files_callback (GtkAction *action,
 
5796
                            gpointer callback_data)
 
5797
{
 
5798
        NautilusView *view;
 
5799
        GList *selection;
 
5800
 
 
5801
        view = NAUTILUS_VIEW (callback_data);
 
5802
 
 
5803
        selection = nautilus_view_get_selection_for_file_transfer (view);
 
5804
        copy_or_cut_files (view, selection, FALSE);
 
5805
        nautilus_file_list_free (selection);
 
5806
}
 
5807
 
 
5808
static void
 
5809
move_copy_selection_to_location (NautilusView *view,
 
5810
                                 int copy_action,
 
5811
                                 char *target_uri)
 
5812
{
 
5813
        GList *selection, *uris, *l;
 
5814
 
 
5815
        selection = nautilus_view_get_selection_for_file_transfer (view);
 
5816
        if (selection == NULL) {
 
5817
                return;
 
5818
        }
 
5819
 
 
5820
        uris = NULL;
 
5821
        for (l = selection; l != NULL; l = l->next) {
 
5822
                uris = g_list_prepend (uris,
 
5823
                                       nautilus_file_get_uri ((NautilusFile *) l->data));
 
5824
        }
 
5825
        uris = g_list_reverse (uris);
 
5826
 
 
5827
        nautilus_view_move_copy_items (view, uris, NULL, target_uri,
 
5828
                                       copy_action,
 
5829
                                       0, 0);
 
5830
 
 
5831
        g_list_free_full (uris, g_free);
 
5832
        nautilus_file_list_free (selection);
 
5833
}
 
5834
 
 
5835
static void
 
5836
move_copy_selection_to_next_pane (NautilusView *view,
 
5837
                                  int copy_action)
 
5838
{
 
5839
        NautilusWindowSlot *slot;
 
5840
        char *dest_location;
 
5841
 
 
5842
        slot = nautilus_window_get_extra_slot (nautilus_view_get_nautilus_window (view));
 
5843
        g_return_if_fail (slot != NULL);
 
5844
 
 
5845
        dest_location = nautilus_window_slot_get_current_uri (slot);
 
5846
        g_return_if_fail (dest_location != NULL);
 
5847
 
 
5848
        move_copy_selection_to_location (view, copy_action, dest_location);
 
5849
}
 
5850
 
 
5851
static void
 
5852
action_copy_to_next_pane_callback (GtkAction *action, gpointer callback_data)
 
5853
{
 
5854
        NautilusView *view;
 
5855
 
 
5856
        view = NAUTILUS_VIEW (callback_data);
 
5857
        move_copy_selection_to_next_pane (view,
 
5858
                                          GDK_ACTION_COPY);
 
5859
}
 
5860
 
 
5861
static void
 
5862
action_move_to_next_pane_callback (GtkAction *action, gpointer callback_data)
 
5863
{
 
5864
        NautilusWindowSlot *slot;
 
5865
        char *dest_location;
 
5866
        NautilusView *view;
 
5867
 
 
5868
        view = NAUTILUS_VIEW (callback_data);
 
5869
 
 
5870
        slot = nautilus_window_get_extra_slot (nautilus_view_get_nautilus_window (view));
 
5871
        g_return_if_fail (slot != NULL);
 
5872
 
 
5873
        dest_location = nautilus_window_slot_get_current_uri (slot);
 
5874
        g_return_if_fail (dest_location != NULL);
 
5875
 
 
5876
        move_copy_selection_to_location (view, GDK_ACTION_MOVE, dest_location);
 
5877
}
 
5878
 
 
5879
static void
 
5880
action_copy_to_home_callback (GtkAction *action, gpointer callback_data)
 
5881
{
 
5882
        NautilusView *view;
 
5883
        char *dest_location;
 
5884
 
 
5885
        view = NAUTILUS_VIEW (callback_data);
 
5886
 
 
5887
        dest_location = nautilus_get_home_directory_uri ();
 
5888
        move_copy_selection_to_location (view, GDK_ACTION_COPY, dest_location);
 
5889
        g_free (dest_location);
 
5890
}
 
5891
 
 
5892
static void
 
5893
action_move_to_home_callback (GtkAction *action, gpointer callback_data)
 
5894
{
 
5895
        NautilusView *view;
 
5896
        char *dest_location;
 
5897
 
 
5898
        view = NAUTILUS_VIEW (callback_data);
 
5899
 
 
5900
        dest_location = nautilus_get_home_directory_uri ();
 
5901
        move_copy_selection_to_location (view, GDK_ACTION_MOVE, dest_location);
 
5902
        g_free (dest_location);
 
5903
}
 
5904
 
 
5905
static void
 
5906
action_copy_to_desktop_callback (GtkAction *action, gpointer callback_data)
 
5907
{
 
5908
        NautilusView *view;
 
5909
        char *dest_location;
 
5910
 
 
5911
        view = NAUTILUS_VIEW (callback_data);
 
5912
 
 
5913
        dest_location = nautilus_get_desktop_directory_uri ();
 
5914
        move_copy_selection_to_location (view, GDK_ACTION_COPY, dest_location);
 
5915
        g_free (dest_location);
 
5916
}
 
5917
 
 
5918
static void
 
5919
action_move_to_desktop_callback (GtkAction *action, gpointer callback_data)
 
5920
{
 
5921
        NautilusView *view;
 
5922
        char *dest_location;
 
5923
 
 
5924
        view = NAUTILUS_VIEW (callback_data);
 
5925
 
 
5926
        dest_location = nautilus_get_desktop_directory_uri ();
 
5927
        move_copy_selection_to_location (view, GDK_ACTION_MOVE, dest_location);
 
5928
        g_free (dest_location);
 
5929
}
 
5930
 
 
5931
static void
 
5932
action_cut_files_callback (GtkAction *action,
 
5933
                           gpointer callback_data)
 
5934
{
 
5935
        NautilusView *view;
 
5936
        GList *selection;
 
5937
 
 
5938
        view = NAUTILUS_VIEW (callback_data);
 
5939
 
 
5940
        selection = nautilus_view_get_selection_for_file_transfer (view);
 
5941
        copy_or_cut_files (view, selection, TRUE);
 
5942
        nautilus_file_list_free (selection);
 
5943
}
 
5944
 
 
5945
static void
 
5946
paste_clipboard_data (NautilusView *view,
 
5947
                      GtkSelectionData *selection_data,
 
5948
                      char *destination_uri)
 
5949
{
 
5950
        gboolean cut;
 
5951
        GList *item_uris;
 
5952
 
 
5953
        cut = FALSE;
 
5954
        item_uris = nautilus_clipboard_get_uri_list_from_selection_data (selection_data, &cut,
 
5955
                                                                         copied_files_atom);
 
5956
 
 
5957
        if (item_uris == NULL|| destination_uri == NULL) {
 
5958
                nautilus_window_slot_set_status (view->details->slot,
 
5959
                                                 _("There is nothing on the clipboard to paste."),
 
5960
                                                 NULL);
 
5961
        } else {
 
5962
                nautilus_view_move_copy_items (view, item_uris, NULL, destination_uri,
 
5963
                                               cut ? GDK_ACTION_MOVE : GDK_ACTION_COPY,
 
5964
                                               0, 0);
 
5965
 
 
5966
                /* If items are cut then remove from clipboard */
 
5967
                if (cut) {
 
5968
                        gtk_clipboard_clear (nautilus_clipboard_get (GTK_WIDGET (view)));
 
5969
                }
 
5970
 
 
5971
                g_list_free_full (item_uris, g_free);
 
5972
        }
 
5973
}
 
5974
 
 
5975
static void
 
5976
paste_clipboard_received_callback (GtkClipboard     *clipboard,
 
5977
                                   GtkSelectionData *selection_data,
 
5978
                                   gpointer          data)
 
5979
{
 
5980
        NautilusView *view;
 
5981
        char *view_uri;
 
5982
 
 
5983
        view = NAUTILUS_VIEW (data);
 
5984
 
 
5985
        view_uri = nautilus_view_get_backing_uri (view);
 
5986
 
 
5987
        if (view->details->window != NULL) {
 
5988
                paste_clipboard_data (view, selection_data, view_uri);
 
5989
        }
 
5990
 
 
5991
        g_free (view_uri);
 
5992
 
 
5993
        g_object_unref (view);
 
5994
}
 
5995
 
 
5996
typedef struct {
 
5997
        NautilusView *view;
 
5998
        NautilusFile *target;
 
5999
} PasteIntoData;
 
6000
 
 
6001
static void
 
6002
paste_into_clipboard_received_callback (GtkClipboard     *clipboard,
 
6003
                                        GtkSelectionData *selection_data,
 
6004
                                        gpointer          callback_data)
 
6005
{
 
6006
        PasteIntoData *data;
 
6007
        NautilusView *view;
 
6008
        char *directory_uri;
 
6009
 
 
6010
        data = (PasteIntoData *) callback_data;
 
6011
 
 
6012
        view = NAUTILUS_VIEW (data->view);
 
6013
 
 
6014
        if (view->details->window != NULL) {
 
6015
                directory_uri = nautilus_file_get_activation_uri (data->target);
 
6016
 
 
6017
                paste_clipboard_data (view, selection_data, directory_uri);
 
6018
 
 
6019
                g_free (directory_uri);
 
6020
        }
 
6021
 
 
6022
        g_object_unref (view);
 
6023
        nautilus_file_unref (data->target);
 
6024
        g_free (data);
 
6025
}
 
6026
 
 
6027
static void
 
6028
action_paste_files_callback (GtkAction *action,
 
6029
                             gpointer callback_data)
 
6030
{
 
6031
        NautilusView *view;
 
6032
 
 
6033
        view = NAUTILUS_VIEW (callback_data);
 
6034
 
 
6035
        g_object_ref (view);
 
6036
        gtk_clipboard_request_contents (nautilus_clipboard_get (GTK_WIDGET (view)),
 
6037
                                        copied_files_atom,
 
6038
                                        paste_clipboard_received_callback,
 
6039
                                        view);
 
6040
}
 
6041
 
 
6042
static void
 
6043
paste_into (NautilusView *view,
 
6044
            NautilusFile *target)
 
6045
{
 
6046
        PasteIntoData *data;
 
6047
 
 
6048
        g_assert (NAUTILUS_IS_VIEW (view));
 
6049
        g_assert (NAUTILUS_IS_FILE (target));
 
6050
 
 
6051
        data = g_new (PasteIntoData, 1);
 
6052
 
 
6053
        data->view = g_object_ref (view);
 
6054
        data->target = nautilus_file_ref (target);
 
6055
 
 
6056
        gtk_clipboard_request_contents (nautilus_clipboard_get (GTK_WIDGET (view)),
 
6057
                                        copied_files_atom,
 
6058
                                        paste_into_clipboard_received_callback,
 
6059
                                        data);
 
6060
}
 
6061
 
 
6062
static void
 
6063
action_paste_files_into_callback (GtkAction *action,
 
6064
                                  gpointer callback_data)
 
6065
{
 
6066
        NautilusView *view;
 
6067
        GList *selection;
 
6068
 
 
6069
        view = NAUTILUS_VIEW (callback_data);
 
6070
        selection = nautilus_view_get_selection (view);
 
6071
        if (selection != NULL) {
 
6072
                paste_into (view, NAUTILUS_FILE (selection->data));
 
6073
                nautilus_file_list_free (selection);
 
6074
        }
 
6075
 
 
6076
}
 
6077
 
 
6078
static void
 
6079
invoke_external_bulk_rename_utility (NautilusView *view,
 
6080
                                     GList *selection)
 
6081
{
 
6082
        GString *cmd;
 
6083
        char *parameter;
 
6084
        char *quoted_parameter;
 
6085
        char *bulk_rename_tool;
 
6086
        GList *walk;
 
6087
        NautilusFile *file;
 
6088
 
 
6089
        /* assemble command line */
 
6090
        bulk_rename_tool = get_bulk_rename_tool ();
 
6091
        cmd = g_string_new (bulk_rename_tool);
 
6092
        g_free (bulk_rename_tool);
 
6093
        for (walk = selection; walk; walk = walk->next) {
 
6094
                file = walk->data;
 
6095
                parameter = nautilus_file_get_uri (file);
 
6096
                quoted_parameter = g_shell_quote (parameter);
 
6097
                g_free (parameter);
 
6098
                cmd = g_string_append (cmd, " ");
 
6099
                cmd = g_string_append (cmd, quoted_parameter);
 
6100
                g_free (quoted_parameter);
 
6101
        }
 
6102
 
 
6103
        /* spawning and error handling */
 
6104
        nautilus_launch_application_from_command (gtk_widget_get_screen (GTK_WIDGET (view)),
 
6105
                                                  cmd->str, FALSE, NULL);
 
6106
        g_string_free (cmd, TRUE);
 
6107
}
 
6108
 
 
6109
static void
 
6110
real_action_rename (NautilusView *view,
 
6111
                    gboolean select_all)
 
6112
{
 
6113
        NautilusFile *file;
 
6114
        GList *selection;
 
6115
 
 
6116
        g_assert (NAUTILUS_IS_VIEW (view));
 
6117
 
 
6118
        selection = nautilus_view_get_selection (view);
 
6119
 
 
6120
        if (selection_not_empty_in_menu_callback (view, selection)) {
 
6121
                /* If there is more than one file selected, invoke a batch renamer */
 
6122
                if (selection->next != NULL) {
 
6123
                        if (have_bulk_rename_tool ()) {
 
6124
                                invoke_external_bulk_rename_utility (view, selection);
 
6125
                        }
 
6126
                } else {
 
6127
                        file = NAUTILUS_FILE (selection->data);
 
6128
                        if (!select_all) {
 
6129
                                /* directories don't have a file extension, so
 
6130
                                 * they are always pre-selected as a whole */
 
6131
                                select_all = nautilus_file_is_directory (file);
 
6132
                        }
 
6133
                        EEL_CALL_METHOD (NAUTILUS_VIEW_CLASS, view, start_renaming_file, (view, file, select_all));
 
6134
                }
 
6135
        }
 
6136
 
 
6137
        nautilus_file_list_free (selection);
 
6138
}
 
6139
 
 
6140
static void
 
6141
action_rename_callback (GtkAction *action,
 
6142
                        gpointer callback_data)
 
6143
{
 
6144
        real_action_rename (NAUTILUS_VIEW (callback_data), FALSE);
 
6145
}
 
6146
 
 
6147
static void
 
6148
action_rename_select_all_callback (GtkAction *action,
 
6149
                                   gpointer callback_data)
 
6150
{
 
6151
        real_action_rename (NAUTILUS_VIEW (callback_data), TRUE);
 
6152
}
 
6153
 
 
6154
static void
 
6155
file_mount_callback (NautilusFile  *file,
 
6156
                     GFile         *result_location,
 
6157
                     GError        *error,
 
6158
                     gpointer       callback_data)
 
6159
{
 
6160
        if (error != NULL &&
 
6161
            (error->domain != G_IO_ERROR ||
 
6162
             (error->code != G_IO_ERROR_CANCELLED &&
 
6163
              error->code != G_IO_ERROR_FAILED_HANDLED &&
 
6164
              error->code != G_IO_ERROR_ALREADY_MOUNTED))) {
 
6165
                eel_show_error_dialog (_("Unable to mount location"),
 
6166
                                       error->message, NULL);
 
6167
        }
 
6168
}
 
6169
 
 
6170
static void
 
6171
nautilus_view_set_initiated_unmount (NautilusView *view,
 
6172
                                     gboolean initiated_unmount)
 
6173
{
 
6174
        if (view->details->window != NULL) {
 
6175
                nautilus_window_set_initiated_unmount(view->details->window,
 
6176
                                                      initiated_unmount);
 
6177
        }
 
6178
}
 
6179
 
 
6180
static void
 
6181
file_unmount_callback (NautilusFile  *file,
 
6182
                       GFile         *result_location,
 
6183
                       GError        *error,
 
6184
                       gpointer       callback_data)
 
6185
{
 
6186
        NautilusView *view;
 
6187
 
 
6188
        view = NAUTILUS_VIEW (callback_data);
 
6189
        nautilus_view_set_initiated_unmount (view, FALSE);
 
6190
        g_object_unref (view);
 
6191
 
 
6192
        if (error != NULL &&
 
6193
            (error->domain != G_IO_ERROR ||
 
6194
             (error->code != G_IO_ERROR_CANCELLED &&
 
6195
              error->code != G_IO_ERROR_FAILED_HANDLED))) {
 
6196
                eel_show_error_dialog (_("Unable to unmount location"),
 
6197
                                       error->message, NULL);
 
6198
        }
 
6199
}
 
6200
 
 
6201
static void
 
6202
file_eject_callback (NautilusFile  *file,
 
6203
                     GFile         *result_location,
 
6204
                     GError        *error,
 
6205
                     gpointer       callback_data)
 
6206
{
 
6207
        NautilusView *view;
 
6208
 
 
6209
        view = NAUTILUS_VIEW (callback_data);
 
6210
        nautilus_view_set_initiated_unmount (view, FALSE);
 
6211
        g_object_unref (view);
 
6212
 
 
6213
        if (error != NULL &&
 
6214
            (error->domain != G_IO_ERROR ||
 
6215
             (error->code != G_IO_ERROR_CANCELLED &&
 
6216
              error->code != G_IO_ERROR_FAILED_HANDLED))) {
 
6217
                eel_show_error_dialog (_("Unable to eject location"),
 
6218
                                       error->message, NULL);
 
6219
        }
 
6220
}
 
6221
 
 
6222
static void
 
6223
file_stop_callback (NautilusFile  *file,
 
6224
                    GFile         *result_location,
 
6225
                    GError        *error,
 
6226
                    gpointer       callback_data)
 
6227
{
 
6228
        if (error != NULL &&
 
6229
            (error->domain != G_IO_ERROR ||
 
6230
             (error->code != G_IO_ERROR_CANCELLED &&
 
6231
              error->code != G_IO_ERROR_FAILED_HANDLED))) {
 
6232
                eel_show_error_dialog (_("Unable to stop drive"),
 
6233
                                       error->message, NULL);
 
6234
        }
 
6235
}
 
6236
 
 
6237
static void
 
6238
action_mount_volume_callback (GtkAction *action,
 
6239
                              gpointer data)
 
6240
{
 
6241
        NautilusFile *file;
 
6242
        GList *selection, *l;
 
6243
        NautilusView *view;
 
6244
        GMountOperation *mount_op;
 
6245
 
 
6246
        view = NAUTILUS_VIEW (data);
 
6247
        
 
6248
        selection = nautilus_view_get_selection (view);
 
6249
        for (l = selection; l != NULL; l = l->next) {
 
6250
                file = NAUTILUS_FILE (l->data);
 
6251
                
 
6252
                if (nautilus_file_can_mount (file)) {
 
6253
                        mount_op = gtk_mount_operation_new (nautilus_view_get_containing_window (view));
 
6254
                        g_mount_operation_set_password_save (mount_op, G_PASSWORD_SAVE_FOR_SESSION);
 
6255
                        nautilus_file_mount (file, mount_op, NULL,
 
6256
                                             file_mount_callback, NULL);
 
6257
                        g_object_unref (mount_op);
 
6258
                }
 
6259
        }
 
6260
        nautilus_file_list_free (selection);
 
6261
}
 
6262
 
 
6263
static void
 
6264
action_unmount_volume_callback (GtkAction *action,
 
6265
                                gpointer data)
 
6266
{
 
6267
        NautilusFile *file;
 
6268
        GList *selection, *l;
 
6269
        NautilusView *view;
 
6270
 
 
6271
        view = NAUTILUS_VIEW (data);
 
6272
        
 
6273
        selection = nautilus_view_get_selection (view);
 
6274
 
 
6275
        for (l = selection; l != NULL; l = l->next) {
 
6276
                file = NAUTILUS_FILE (l->data);
 
6277
                if (nautilus_file_can_unmount (file)) {
 
6278
                        GMountOperation *mount_op;
 
6279
                        mount_op = gtk_mount_operation_new (nautilus_view_get_containing_window (view));
 
6280
                        nautilus_view_set_initiated_unmount (view, TRUE);
 
6281
                        nautilus_file_unmount (file, mount_op, NULL,
 
6282
                                               file_unmount_callback, g_object_ref (view));
 
6283
                        g_object_unref (mount_op);
 
6284
                }
 
6285
        }
 
6286
        nautilus_file_list_free (selection);
 
6287
}
 
6288
 
 
6289
static void
 
6290
action_eject_volume_callback (GtkAction *action,
 
6291
                              gpointer data)
 
6292
{
 
6293
        NautilusFile *file;
 
6294
        GList *selection, *l;
 
6295
        NautilusView *view;
 
6296
 
 
6297
        view = NAUTILUS_VIEW (data);
 
6298
        
 
6299
        selection = nautilus_view_get_selection (view);
 
6300
        for (l = selection; l != NULL; l = l->next) {
 
6301
                file = NAUTILUS_FILE (l->data);
 
6302
                
 
6303
                if (nautilus_file_can_eject (file)) {
 
6304
                        GMountOperation *mount_op;
 
6305
                        mount_op = gtk_mount_operation_new (nautilus_view_get_containing_window (view));
 
6306
                        nautilus_view_set_initiated_unmount (view, TRUE);
 
6307
                        nautilus_file_eject (file, mount_op, NULL,
 
6308
                                             file_eject_callback, g_object_ref (view));
 
6309
                        g_object_unref (mount_op);
 
6310
                }
 
6311
        }       
 
6312
        nautilus_file_list_free (selection);
 
6313
}
 
6314
 
 
6315
static void
 
6316
file_start_callback (NautilusFile  *file,
 
6317
                     GFile         *result_location,
 
6318
                     GError        *error,
 
6319
                     gpointer       callback_data)
 
6320
{
 
6321
        if (error != NULL &&
 
6322
            (error->domain != G_IO_ERROR ||
 
6323
             (error->code != G_IO_ERROR_CANCELLED &&
 
6324
              error->code != G_IO_ERROR_FAILED_HANDLED &&
 
6325
              error->code != G_IO_ERROR_ALREADY_MOUNTED))) {
 
6326
                eel_show_error_dialog (_("Unable to start location"),
 
6327
                                       error->message, NULL);
 
6328
        }
 
6329
}
 
6330
 
 
6331
static void
 
6332
action_start_volume_callback (GtkAction *action,
 
6333
                              gpointer   data)
 
6334
{
 
6335
        NautilusFile *file;
 
6336
        GList *selection, *l;
 
6337
        NautilusView *view;
 
6338
        GMountOperation *mount_op;
 
6339
 
 
6340
        view = NAUTILUS_VIEW (data);
 
6341
 
 
6342
        selection = nautilus_view_get_selection (view);
 
6343
        for (l = selection; l != NULL; l = l->next) {
 
6344
                file = NAUTILUS_FILE (l->data);
 
6345
 
 
6346
                if (nautilus_file_can_start (file) || nautilus_file_can_start_degraded (file)) {
 
6347
                        mount_op = gtk_mount_operation_new (nautilus_view_get_containing_window (view));
 
6348
                        nautilus_file_start (file, mount_op, NULL,
 
6349
                                             file_start_callback, NULL);
 
6350
                        g_object_unref (mount_op);
 
6351
                }
 
6352
        }
 
6353
        nautilus_file_list_free (selection);
 
6354
}
 
6355
 
 
6356
static void
 
6357
action_stop_volume_callback (GtkAction *action,
 
6358
                             gpointer   data)
 
6359
{
 
6360
        NautilusFile *file;
 
6361
        GList *selection, *l;
 
6362
        NautilusView *view;
 
6363
 
 
6364
        view = NAUTILUS_VIEW (data);
 
6365
 
 
6366
        selection = nautilus_view_get_selection (view);
 
6367
        for (l = selection; l != NULL; l = l->next) {
 
6368
                file = NAUTILUS_FILE (l->data);
 
6369
 
 
6370
                if (nautilus_file_can_stop (file)) {
 
6371
                        GMountOperation *mount_op;
 
6372
                        mount_op = gtk_mount_operation_new (nautilus_view_get_containing_window (view));
 
6373
                        nautilus_file_stop (file, mount_op, NULL,
 
6374
                                            file_stop_callback, NULL);
 
6375
                        g_object_unref (mount_op);
 
6376
                }
 
6377
        }
 
6378
        nautilus_file_list_free (selection);
 
6379
}
 
6380
 
 
6381
static void
 
6382
action_detect_media_callback (GtkAction *action,
 
6383
                              gpointer   data)
 
6384
{
 
6385
        NautilusFile *file;
 
6386
        GList *selection, *l;
 
6387
        NautilusView *view;
 
6388
 
 
6389
        view = NAUTILUS_VIEW (data);
 
6390
 
 
6391
        selection = nautilus_view_get_selection (view);
 
6392
        for (l = selection; l != NULL; l = l->next) {
 
6393
                file = NAUTILUS_FILE (l->data);
 
6394
 
 
6395
                if (nautilus_file_can_poll_for_media (file) && !nautilus_file_is_media_check_automatic (file)) {
 
6396
                        nautilus_file_poll_for_media (file);
 
6397
                }
 
6398
        }
 
6399
        nautilus_file_list_free (selection);
 
6400
}
 
6401
 
 
6402
static void
 
6403
action_self_mount_volume_callback (GtkAction *action,
 
6404
                                   gpointer data)
 
6405
{
 
6406
        NautilusFile *file;
 
6407
        NautilusView *view;
 
6408
        GMountOperation *mount_op;
 
6409
 
 
6410
        view = NAUTILUS_VIEW (data);
 
6411
 
 
6412
        file = nautilus_view_get_directory_as_file (view);
 
6413
        if (file == NULL) {
 
6414
                return;
 
6415
        }
 
6416
 
 
6417
        mount_op = gtk_mount_operation_new (nautilus_view_get_containing_window (view));
 
6418
        g_mount_operation_set_password_save (mount_op, G_PASSWORD_SAVE_FOR_SESSION);
 
6419
        nautilus_file_mount (file, mount_op, NULL, file_mount_callback, NULL);
 
6420
        g_object_unref (mount_op);
 
6421
}
 
6422
 
 
6423
static void
 
6424
action_self_unmount_volume_callback (GtkAction *action,
 
6425
                                     gpointer data)
 
6426
{
 
6427
        NautilusFile *file;
 
6428
        NautilusView *view;
 
6429
        GMountOperation *mount_op;
 
6430
 
 
6431
        view = NAUTILUS_VIEW (data);
 
6432
 
 
6433
        file = nautilus_view_get_directory_as_file (view);
 
6434
        if (file == NULL) {
 
6435
                return;
 
6436
        }
 
6437
 
 
6438
        mount_op = gtk_mount_operation_new (nautilus_view_get_containing_window (view));
 
6439
        nautilus_view_set_initiated_unmount (view, TRUE);
 
6440
        nautilus_file_unmount (file, mount_op, NULL, file_unmount_callback, g_object_ref (view));
 
6441
        g_object_unref (mount_op);
 
6442
}
 
6443
 
 
6444
static void
 
6445
action_self_eject_volume_callback (GtkAction *action,
 
6446
                                   gpointer data)
 
6447
{
 
6448
        NautilusFile *file;
 
6449
        NautilusView *view;
 
6450
        GMountOperation *mount_op;
 
6451
 
 
6452
        view = NAUTILUS_VIEW (data);
 
6453
 
 
6454
        file = nautilus_view_get_directory_as_file (view);
 
6455
        if (file == NULL) {
 
6456
                return;
 
6457
        }
 
6458
        
 
6459
        mount_op = gtk_mount_operation_new (nautilus_view_get_containing_window (view));
 
6460
        nautilus_view_set_initiated_unmount (view, TRUE);
 
6461
        nautilus_file_eject (file, mount_op, NULL, file_eject_callback, g_object_ref (view));
 
6462
        g_object_unref (mount_op);
 
6463
}
 
6464
 
 
6465
static void
 
6466
action_self_start_volume_callback (GtkAction *action,
 
6467
                                   gpointer   data)
 
6468
{
 
6469
        NautilusFile *file;
 
6470
        NautilusView *view;
 
6471
        GMountOperation *mount_op;
 
6472
 
 
6473
        view = NAUTILUS_VIEW (data);
 
6474
 
 
6475
        file = nautilus_view_get_directory_as_file (view);
 
6476
        if (file == NULL) {
 
6477
                return;
 
6478
        }
 
6479
 
 
6480
        mount_op = gtk_mount_operation_new (nautilus_view_get_containing_window (view));
 
6481
        nautilus_file_start (file, mount_op, NULL, file_start_callback, NULL);
 
6482
        g_object_unref (mount_op);
 
6483
}
 
6484
 
 
6485
static void
 
6486
action_self_stop_volume_callback (GtkAction *action,
 
6487
                                  gpointer   data)
 
6488
{
 
6489
        NautilusFile *file;
 
6490
        NautilusView *view;
 
6491
        GMountOperation *mount_op;
 
6492
 
 
6493
        view = NAUTILUS_VIEW (data);
 
6494
 
 
6495
        file = nautilus_view_get_directory_as_file (view);
 
6496
        if (file == NULL) {
 
6497
                return;
 
6498
        }
 
6499
 
 
6500
        mount_op = gtk_mount_operation_new (nautilus_view_get_containing_window (view));
 
6501
        nautilus_file_stop (file, mount_op, NULL,
 
6502
                            file_stop_callback, NULL);
 
6503
        g_object_unref (mount_op);
 
6504
}
 
6505
 
 
6506
static void
 
6507
action_self_detect_media_callback (GtkAction *action,
 
6508
                                   gpointer   data)
 
6509
{
 
6510
        NautilusFile *file;
 
6511
        NautilusView *view;
 
6512
 
 
6513
        view = NAUTILUS_VIEW (data);
 
6514
 
 
6515
        file = nautilus_view_get_directory_as_file (view);
 
6516
        if (file == NULL) {
 
6517
                return;
 
6518
        }
 
6519
 
 
6520
        nautilus_file_poll_for_media (file);
 
6521
}
 
6522
 
 
6523
static void
 
6524
action_location_mount_volume_callback (GtkAction *action,
 
6525
                                       gpointer data)
 
6526
{
 
6527
        NautilusFile *file;
 
6528
        NautilusView *view;
 
6529
        GMountOperation *mount_op;
 
6530
 
 
6531
        view = NAUTILUS_VIEW (data);
 
6532
 
 
6533
        file = view->details->location_popup_directory_as_file;
 
6534
        if (file == NULL) {
 
6535
                return;
 
6536
        }
 
6537
 
 
6538
        mount_op = gtk_mount_operation_new (nautilus_view_get_containing_window (view));
 
6539
        g_mount_operation_set_password_save (mount_op, G_PASSWORD_SAVE_FOR_SESSION);
 
6540
        nautilus_file_mount (file, mount_op, NULL, file_mount_callback, NULL);
 
6541
        g_object_unref (mount_op);
 
6542
}
 
6543
 
 
6544
static void
 
6545
action_location_unmount_volume_callback (GtkAction *action,
 
6546
                                         gpointer data)
 
6547
{
 
6548
        NautilusFile *file;
 
6549
        NautilusView *view;
 
6550
        GMountOperation *mount_op;
 
6551
 
 
6552
        view = NAUTILUS_VIEW (data);
 
6553
 
 
6554
        file = view->details->location_popup_directory_as_file;
 
6555
        if (file == NULL) {
 
6556
                return;
 
6557
        }
 
6558
 
 
6559
        mount_op = gtk_mount_operation_new (nautilus_view_get_containing_window (view));
 
6560
        nautilus_view_set_initiated_unmount (view, TRUE);
 
6561
        nautilus_file_unmount (file, mount_op, NULL,
 
6562
                               file_unmount_callback, g_object_ref (view));
 
6563
        g_object_unref (mount_op);
 
6564
}
 
6565
 
 
6566
static void
 
6567
action_location_eject_volume_callback (GtkAction *action,
 
6568
                                       gpointer data)
 
6569
{
 
6570
        NautilusFile *file;
 
6571
        NautilusView *view;
 
6572
        GMountOperation *mount_op;
 
6573
 
 
6574
        view = NAUTILUS_VIEW (data);
 
6575
 
 
6576
        file = view->details->location_popup_directory_as_file;
 
6577
        if (file == NULL) {
 
6578
                return;
 
6579
        }
 
6580
        
 
6581
        mount_op = gtk_mount_operation_new (nautilus_view_get_containing_window (view));
 
6582
        nautilus_view_set_initiated_unmount (view, TRUE);
 
6583
        nautilus_file_eject (file, mount_op, NULL,
 
6584
                             file_eject_callback, g_object_ref (view));
 
6585
        g_object_unref (mount_op);
 
6586
}
 
6587
 
 
6588
static void
 
6589
action_location_start_volume_callback (GtkAction *action,
 
6590
                                       gpointer   data)
 
6591
{
 
6592
        NautilusFile *file;
 
6593
        NautilusView *view;
 
6594
        GMountOperation *mount_op;
 
6595
 
 
6596
        view = NAUTILUS_VIEW (data);
 
6597
 
 
6598
        file = view->details->location_popup_directory_as_file;
 
6599
        if (file == NULL) {
 
6600
                return;
 
6601
        }
 
6602
 
 
6603
        mount_op = gtk_mount_operation_new (nautilus_view_get_containing_window (view));
 
6604
        nautilus_file_start (file, mount_op, NULL, file_start_callback, NULL);
 
6605
        g_object_unref (mount_op);
 
6606
}
 
6607
 
 
6608
static void
 
6609
action_location_stop_volume_callback (GtkAction *action,
 
6610
                                      gpointer   data)
 
6611
{
 
6612
        NautilusFile *file;
 
6613
        NautilusView *view;
 
6614
        GMountOperation *mount_op;
 
6615
 
 
6616
        view = NAUTILUS_VIEW (data);
 
6617
 
 
6618
        file = view->details->location_popup_directory_as_file;
 
6619
        if (file == NULL) {
 
6620
                return;
 
6621
        }
 
6622
 
 
6623
        mount_op = gtk_mount_operation_new (nautilus_view_get_containing_window (view));
 
6624
        nautilus_file_stop (file, mount_op, NULL,
 
6625
                            file_stop_callback, NULL);
 
6626
        g_object_unref (mount_op);
 
6627
}
 
6628
 
 
6629
static void
 
6630
action_location_detect_media_callback (GtkAction *action,
 
6631
                                       gpointer   data)
 
6632
{
 
6633
        NautilusFile *file;
 
6634
        NautilusView *view;
 
6635
 
 
6636
        view = NAUTILUS_VIEW (data);
 
6637
 
 
6638
        file = view->details->location_popup_directory_as_file;
 
6639
        if (file == NULL) {
 
6640
                return;
 
6641
        }
 
6642
 
 
6643
        nautilus_file_poll_for_media (file);
 
6644
}
 
6645
 
 
6646
static void
 
6647
connect_to_server_response_callback (GtkDialog *dialog,
 
6648
                                     int response_id,
 
6649
                                     gpointer data)
 
6650
{
 
6651
#ifdef GIO_CONVERSION_DONE
 
6652
        GtkEntry *entry;
 
6653
        char *uri;
 
6654
        const char *name;
 
6655
        char *icon;
 
6656
 
 
6657
        entry = GTK_ENTRY (data);
 
6658
        
 
6659
        switch (response_id) {
 
6660
        case GTK_RESPONSE_OK:
 
6661
                uri = g_object_get_data (G_OBJECT (dialog), "link-uri");
 
6662
                icon = g_object_get_data (G_OBJECT (dialog), "link-icon");
 
6663
                name = gtk_entry_get_text (entry);
 
6664
                gnome_vfs_connect_to_server (uri, (char *)name, icon);
 
6665
                gtk_widget_destroy (GTK_WIDGET (dialog));
 
6666
                break;
 
6667
        case GTK_RESPONSE_NONE:
 
6668
        case GTK_RESPONSE_DELETE_EVENT:
 
6669
        case GTK_RESPONSE_CANCEL:
 
6670
                gtk_widget_destroy (GTK_WIDGET (dialog));
 
6671
                break;
 
6672
        default :
 
6673
                g_assert_not_reached ();
 
6674
        }
 
6675
#endif
 
6676
        /* FIXME: the above code should make a server connection permanent */
 
6677
        gtk_widget_destroy (GTK_WIDGET (dialog));
 
6678
}
 
6679
 
 
6680
static void
 
6681
entry_activate_callback (GtkEntry *entry,
 
6682
                         gpointer user_data)
 
6683
{
 
6684
        GtkDialog *dialog;
 
6685
        
 
6686
        dialog = GTK_DIALOG (user_data);
 
6687
        gtk_dialog_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
 
6688
}
 
6689
 
 
6690
static void
 
6691
action_connect_to_server_link_callback (GtkAction *action,
 
6692
                                        gpointer data)
 
6693
{
 
6694
        NautilusFile *file;
 
6695
        GList *selection;
 
6696
        NautilusView *view;
 
6697
        char *uri;
 
6698
        NautilusIconInfo *icon;
 
6699
        const char *icon_name;
 
6700
        char *name;
 
6701
        GtkWidget *dialog;
 
6702
        GtkWidget *label;
 
6703
        GtkWidget *entry;
 
6704
        GtkWidget *box;
 
6705
        char *title;
 
6706
 
 
6707
        view = NAUTILUS_VIEW (data);
 
6708
        
 
6709
        selection = nautilus_view_get_selection (view);
 
6710
 
 
6711
        if (!eel_g_list_exactly_one_item (selection)) {
 
6712
                nautilus_file_list_free (selection);
 
6713
                return;
 
6714
        }
 
6715
 
 
6716
        file = NAUTILUS_FILE (selection->data);
 
6717
 
 
6718
        uri = nautilus_file_get_activation_uri (file);
 
6719
        icon = nautilus_file_get_icon (file, NAUTILUS_ICON_SIZE_STANDARD, 0);
 
6720
        icon_name = nautilus_icon_info_get_used_name (icon);
 
6721
        name = nautilus_file_get_display_name (file);
 
6722
 
 
6723
        if (uri != NULL) {
 
6724
                title = g_strdup_printf (_("Connect to Server %s"), name);
 
6725
                dialog = gtk_dialog_new_with_buttons (title,
 
6726
                                                      nautilus_view_get_containing_window (view),
 
6727
                                                      0,
 
6728
                                                      GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
 
6729
                                                      _("_Connect"), GTK_RESPONSE_OK,
 
6730
                                                      NULL);
 
6731
 
 
6732
                g_object_set_data_full (G_OBJECT (dialog), "link-uri", g_strdup (uri), g_free);
 
6733
                g_object_set_data_full (G_OBJECT (dialog), "link-icon", g_strdup (icon_name), g_free);
 
6734
                
 
6735
                gtk_container_set_border_width (GTK_CONTAINER (dialog), 5);
 
6736
                gtk_box_set_spacing (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))), 2);
 
6737
 
 
6738
                box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12);
 
6739
                gtk_widget_show (box);
 
6740
                gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))),
 
6741
                                    box, TRUE, TRUE, 0);
 
6742
                
 
6743
                label = gtk_label_new_with_mnemonic (_("Link _name:"));
 
6744
                gtk_widget_show (label);
 
6745
 
 
6746
                gtk_box_pack_start (GTK_BOX (box), label, TRUE, TRUE, 12);
 
6747
                
 
6748
                entry = gtk_entry_new ();
 
6749
                if (name) {
 
6750
                        gtk_entry_set_text (GTK_ENTRY (entry), name);
 
6751
                }
 
6752
                g_signal_connect (entry,
 
6753
                                  "activate", 
 
6754
                                  G_CALLBACK (entry_activate_callback),
 
6755
                                  dialog);
 
6756
                
 
6757
                gtk_widget_show (entry);
 
6758
                gtk_label_set_mnemonic_widget (GTK_LABEL (label), entry);
 
6759
                
 
6760
                gtk_box_pack_start (GTK_BOX (box), entry, TRUE, TRUE, 12);
 
6761
                
 
6762
                gtk_dialog_set_default_response (GTK_DIALOG (dialog),
 
6763
                                                 GTK_RESPONSE_OK);
 
6764
                g_signal_connect (dialog, "response",
 
6765
                                  G_CALLBACK (connect_to_server_response_callback),
 
6766
                                  entry);
 
6767
                gtk_widget_show (dialog);
 
6768
        }
 
6769
        
 
6770
        g_free (uri);
 
6771
        g_object_unref (icon);
 
6772
        g_free (name);
 
6773
}
 
6774
 
 
6775
static void
 
6776
action_location_open_alternate_callback (GtkAction *action,
 
6777
                                         gpointer   callback_data)
 
6778
{
 
6779
        NautilusView *view;
 
6780
        NautilusFile *file;
 
6781
 
 
6782
        view = NAUTILUS_VIEW (callback_data);
 
6783
 
 
6784
        file = view->details->location_popup_directory_as_file;
 
6785
        if (file == NULL) {
 
6786
                return;
 
6787
        }
 
6788
        nautilus_view_activate_file (view,
 
6789
                                     file,
 
6790
                                     NAUTILUS_WINDOW_OPEN_FLAG_NEW_WINDOW);
 
6791
}
 
6792
 
 
6793
static void
 
6794
action_location_open_in_new_tab_callback (GtkAction *action,
 
6795
                                          gpointer   callback_data)
 
6796
{
 
6797
        NautilusView *view;
 
6798
        NautilusFile *file;
 
6799
 
 
6800
        view = NAUTILUS_VIEW (callback_data);
 
6801
 
 
6802
        file = view->details->location_popup_directory_as_file;
 
6803
        if (file == NULL) {
 
6804
                return;
 
6805
        }
 
6806
 
 
6807
        nautilus_view_activate_file (view,
 
6808
                                     file,
 
6809
                                     NAUTILUS_WINDOW_OPEN_FLAG_NEW_TAB);
 
6810
}
 
6811
 
 
6812
static void
 
6813
action_location_cut_callback (GtkAction *action,
 
6814
                              gpointer   callback_data)
 
6815
{
 
6816
        NautilusView *view;
 
6817
        NautilusFile *file;
 
6818
        GList *files;
 
6819
 
 
6820
        view = NAUTILUS_VIEW (callback_data);
 
6821
 
 
6822
        file = view->details->location_popup_directory_as_file;
 
6823
        g_return_if_fail (file != NULL);
 
6824
 
 
6825
        files = g_list_append (NULL, file);
 
6826
        copy_or_cut_files (view, files, TRUE);
 
6827
        g_list_free (files);
 
6828
}
 
6829
 
 
6830
static void
 
6831
action_location_copy_callback (GtkAction *action,
 
6832
                               gpointer   callback_data)
 
6833
{
 
6834
        NautilusView *view;
 
6835
        NautilusFile *file;
 
6836
        GList *files;
 
6837
 
 
6838
        view = NAUTILUS_VIEW (callback_data);
 
6839
 
 
6840
        file = view->details->location_popup_directory_as_file;
 
6841
        g_return_if_fail (file != NULL);
 
6842
 
 
6843
        files = g_list_append (NULL, file);
 
6844
        copy_or_cut_files (view, files, FALSE);
 
6845
        g_list_free (files);
 
6846
}
 
6847
 
 
6848
static void
 
6849
action_location_paste_files_into_callback (GtkAction *action,
 
6850
                                           gpointer callback_data)
 
6851
{
 
6852
        NautilusView *view;
 
6853
        NautilusFile *file;
 
6854
 
 
6855
        view = NAUTILUS_VIEW (callback_data);
 
6856
 
 
6857
        file = view->details->location_popup_directory_as_file;
 
6858
        g_return_if_fail (file != NULL);
 
6859
 
 
6860
        paste_into (view, file);
 
6861
}
 
6862
 
 
6863
static void
 
6864
action_location_trash_callback (GtkAction *action,
 
6865
                                gpointer   callback_data)
 
6866
{
 
6867
        NautilusView *view;
 
6868
        NautilusFile *file;
 
6869
        GList *files;
 
6870
 
 
6871
        view = NAUTILUS_VIEW (callback_data);
 
6872
 
 
6873
        file = view->details->location_popup_directory_as_file;
 
6874
        g_return_if_fail (file != NULL);
 
6875
 
 
6876
        files = g_list_append (NULL, file);
 
6877
        trash_or_delete_files (nautilus_view_get_containing_window (view),
 
6878
                               files, TRUE,
 
6879
                               view);
 
6880
        g_list_free (files);
 
6881
}
 
6882
 
 
6883
static void
 
6884
action_location_delete_callback (GtkAction *action,
 
6885
                                 gpointer   callback_data)
 
6886
{
 
6887
        NautilusView *view;
 
6888
        NautilusFile *file;
 
6889
        GFile *location;
 
6890
        GList *files;
 
6891
 
 
6892
        view = NAUTILUS_VIEW (callback_data);
 
6893
 
 
6894
        file = view->details->location_popup_directory_as_file;
 
6895
        g_return_if_fail (file != NULL);
 
6896
 
 
6897
        location = nautilus_file_get_location (file);
 
6898
 
 
6899
        files = g_list_append (NULL, location);
 
6900
        nautilus_file_operations_delete (files, nautilus_view_get_containing_window (view),
 
6901
                                         NULL, NULL);
 
6902
 
 
6903
        g_list_free_full (files, g_object_unref);
 
6904
}
 
6905
 
 
6906
static void
 
6907
action_location_restore_from_trash_callback (GtkAction *action,
 
6908
                                             gpointer callback_data)
 
6909
{
 
6910
        NautilusView *view;
 
6911
        NautilusFile *file;
 
6912
        GList l;
 
6913
 
 
6914
        view = NAUTILUS_VIEW (callback_data);
 
6915
        file = view->details->location_popup_directory_as_file;
 
6916
 
 
6917
        l.prev = NULL;
 
6918
        l.next = NULL;
 
6919
        l.data = file;
 
6920
        nautilus_restore_files_from_trash (&l,
 
6921
                                           nautilus_view_get_containing_window (view));
 
6922
}
 
6923
 
 
6924
static void
 
6925
nautilus_view_init_show_hidden_files (NautilusView *view)
 
6926
{
 
6927
        NautilusWindowShowHiddenFilesMode mode;
 
6928
        gboolean show_hidden_changed;
 
6929
        gboolean show_hidden_default_setting;
 
6930
 
 
6931
        if (view->details->ignore_hidden_file_preferences) {
 
6932
                return;
 
6933
        }
 
6934
 
 
6935
        show_hidden_changed = FALSE;
 
6936
        mode = nautilus_window_get_hidden_files_mode (view->details->window);
 
6937
 
 
6938
        if (mode == NAUTILUS_WINDOW_SHOW_HIDDEN_FILES_DEFAULT) {
 
6939
                show_hidden_default_setting = g_settings_get_boolean (nautilus_preferences, NAUTILUS_PREFERENCES_SHOW_HIDDEN_FILES);
 
6940
                if (show_hidden_default_setting != view->details->show_hidden_files) {
 
6941
                        view->details->show_hidden_files = show_hidden_default_setting;
 
6942
                        show_hidden_changed = TRUE;
 
6943
                }
 
6944
        } else {
 
6945
                if (mode == NAUTILUS_WINDOW_SHOW_HIDDEN_FILES_ENABLE) {
 
6946
                        show_hidden_changed = !view->details->show_hidden_files;
 
6947
                        view->details->show_hidden_files = TRUE;
 
6948
                } else {
 
6949
                        show_hidden_changed = view->details->show_hidden_files;
 
6950
                        view->details->show_hidden_files = FALSE;
 
6951
                }
 
6952
        }
 
6953
 
 
6954
        if (show_hidden_changed && (view->details->model != NULL)) {
 
6955
                load_directory (view, view->details->model);    
 
6956
        }
 
6957
 
 
6958
}
 
6959
 
 
6960
static const GtkActionEntry directory_view_entries[] = {
 
6961
  /* name, stock id, label */  { "New Documents", "document-new", N_("Create New _Document") },
 
6962
  /* name, stock id, label */  { "Open With", NULL, N_("Open Wit_h"),
 
6963
                                 NULL, N_("Choose a program with which to open the selected item") },
 
6964
  /* name, stock id */         { "Properties", GTK_STOCK_PROPERTIES,
 
6965
  /* label, accelerator */       N_("_Properties"), "<alt>Return",
 
6966
  /* tooltip */                  N_("View or modify the properties of each selected item"),
 
6967
                                 G_CALLBACK (action_properties_callback) },
 
6968
  /* name, stock id */         { "PropertiesAccel", NULL,
 
6969
  /* label, accelerator */       "PropertiesAccel", "<control>I",
 
6970
  /* tooltip */                  NULL,
 
6971
                                 G_CALLBACK (action_properties_callback) },
 
6972
  /* name, stock id */         { "New Folder", "folder-new",
 
6973
  /* label, accelerator */       N_("Create New _Folder"), "<control><shift>N",
 
6974
  /* tooltip */                  N_("Create a new empty folder inside this folder"),
 
6975
                                 G_CALLBACK (action_new_folder_callback) },
 
6976
  /* name, stock id, label */  { "No Templates", NULL, N_("No templates installed") },
 
6977
  /* name, stock id */         { "New Empty Document", NULL,
 
6978
    /* translators: this is used to indicate that a document doesn't contain anything */
 
6979
  /* label, accelerator */       N_("_Empty Document"), NULL,
 
6980
  /* tooltip */                  N_("Create a new empty document inside this folder"),
 
6981
                                 G_CALLBACK (action_new_empty_file_callback) },
 
6982
  /* name, stock id */         { "New Launcher", NULL,
 
6983
  /* label, accelerator */       N_("Create L_auncher..."), NULL,
 
6984
  /* tooltip */                  N_("Create a new launcher"),
 
6985
                                 G_CALLBACK (action_new_launcher_callback) },
 
6986
  /* name, stock id */         { "Open", NULL,
 
6987
  /* label, accelerator */       N_("_Open"), "<control>o",
 
6988
  /* tooltip */                  N_("Open the selected item in this window"),
 
6989
                                 G_CALLBACK (action_open_callback) },
 
6990
  /* name, stock id */         { "OpenAccel", NULL,
 
6991
  /* label, accelerator */       "OpenAccel", "<alt>Down",
 
6992
  /* tooltip */                  NULL,
 
6993
                                 G_CALLBACK (action_open_callback) },
 
6994
  /* name, stock id */         { "OpenAlternate", NULL,
 
6995
  /* label, accelerator */       N_("Open in Navigation Window"), "<control><shift>o",
 
6996
  /* tooltip */                  N_("Open each selected item in a navigation window"),
 
6997
                                 G_CALLBACK (action_open_alternate_callback) },
 
6998
  /* name, stock id */         { "OpenInNewTab", NULL,
 
6999
  /* label, accelerator */       N_("Open in New _Tab"), "<control><shift>o",
 
7000
  /* tooltip */                  N_("Open each selected item in a new tab"),
 
7001
                                 G_CALLBACK (action_open_new_tab_callback) },
 
7002
  /* name, stock id */         { "OtherApplication1", NULL,
 
7003
  /* label, accelerator */       N_("Other _Application..."), NULL,
 
7004
  /* tooltip */                  N_("Choose another application with which to open the selected item"),
 
7005
                                 G_CALLBACK (action_other_application_callback) },
 
7006
  /* name, stock id */         { "OtherApplication2", NULL,
 
7007
  /* label, accelerator */       N_("Open With Other _Application..."), NULL,
 
7008
  /* tooltip */                  N_("Choose another application with which to open the selected item"),
 
7009
                                 G_CALLBACK (action_other_application_callback) },
 
7010
  /* name, stock id */         { "Open Scripts Folder", NULL,
 
7011
  /* label, accelerator */       N_("_Open Scripts Folder"), NULL,
 
7012
  /* tooltip */                 N_("Show the folder containing the scripts that appear in this menu"),
 
7013
                                 G_CALLBACK (action_open_scripts_folder_callback) },
 
7014
  /* name, stock id */         { "Empty Trash", NULL,
 
7015
  /* label, accelerator */       N_("E_mpty Trash"), NULL,
 
7016
  /* tooltip */                  N_("Delete all items in the Trash"),
 
7017
                                 G_CALLBACK (action_empty_trash_callback) },
 
7018
  /* name, stock id */         { "Cut", GTK_STOCK_CUT,
 
7019
  /* label, accelerator */       NULL, NULL,
 
7020
  /* tooltip */                  N_("Prepare the selected files to be moved with a Paste command"),
 
7021
                                 G_CALLBACK (action_cut_files_callback) },
 
7022
  /* name, stock id */         { "Copy", GTK_STOCK_COPY,
 
7023
  /* label, accelerator */       NULL, NULL,
 
7024
  /* tooltip */                  N_("Prepare the selected files to be copied with a Paste command"),
 
7025
                                 G_CALLBACK (action_copy_files_callback) },
 
7026
  /* name, stock id */         { "Paste", GTK_STOCK_PASTE,
 
7027
  /* label, accelerator */       NULL, NULL,
 
7028
  /* tooltip */                  N_("Move or copy files previously selected by a Cut or Copy command"),
 
7029
                                 G_CALLBACK (action_paste_files_callback) },
 
7030
  /* We make accelerator "" instead of null here to not inherit the stock
 
7031
     accelerator for paste */
 
7032
  /* name, stock id */         { "Paste Files Into", GTK_STOCK_PASTE,
 
7033
  /* label, accelerator */       N_("_Paste Into Folder"), "",
 
7034
  /* tooltip */                  N_("Move or copy files previously selected by a Cut or Copy command into the selected folder"),
 
7035
                                 G_CALLBACK (action_paste_files_into_callback) },
 
7036
  /* name, stock id, label */  { "CopyToMenu", NULL, N_("Cop_y to") },
 
7037
  /* name, stock id, label */  { "MoveToMenu", NULL, N_("M_ove to") },                      
 
7038
  /* name, stock id */         { "Select All", NULL,
 
7039
  /* label, accelerator */       N_("Select _All"), "<control>A",
 
7040
  /* tooltip */                  N_("Select all items in this window"),
 
7041
                                 G_CALLBACK (action_select_all_callback) },
 
7042
  /* name, stock id */         { "Select Pattern", NULL,
 
7043
  /* label, accelerator */       N_("Select I_tems Matching..."), "<control>S",
 
7044
  /* tooltip */                  N_("Select items in this window matching a given pattern"),
 
7045
                                 G_CALLBACK (action_select_pattern_callback) },
 
7046
  /* name, stock id */         { "Invert Selection", NULL,
 
7047
  /* label, accelerator */       N_("_Invert Selection"), "<control><shift>I",
 
7048
  /* tooltip */                  N_("Select all and only the items that are not currently selected"),
 
7049
                                 G_CALLBACK (action_invert_selection_callback) }, 
 
7050
  /* name, stock id */         { "Duplicate", NULL,
 
7051
  /* label, accelerator */       N_("D_uplicate"), NULL,
 
7052
  /* tooltip */                  N_("Duplicate each selected item"),
 
7053
                                 G_CALLBACK (action_duplicate_callback) },
 
7054
  /* name, stock id */         { "Create Link", NULL,
 
7055
  /* label, accelerator */       N_("Ma_ke Link"), "<control>M",
 
7056
  /* tooltip */                  N_("Create a symbolic link for each selected item"),
 
7057
                                 G_CALLBACK (action_create_link_callback) },
 
7058
  /* name, stock id */         { "Rename", NULL,
 
7059
  /* label, accelerator */       N_("_Rename..."), "F2",
 
7060
  /* tooltip */                  N_("Rename selected item"),
 
7061
                                 G_CALLBACK (action_rename_callback) },
 
7062
  /* name, stock id */         { "RenameSelectAll", NULL,
 
7063
  /* label, accelerator */       "RenameSelectAll", "<shift>F2",
 
7064
  /* tooltip */                  NULL,
 
7065
                                 G_CALLBACK (action_rename_select_all_callback) },
 
7066
  /* name, stock id */         { "Trash", NULL,
 
7067
  /* label, accelerator */       N_("Mo_ve to Trash"), "<control>Delete",
 
7068
  /* tooltip */                  N_("Move each selected item to the Trash"),
 
7069
                                 G_CALLBACK (action_trash_callback) },
 
7070
  /* name, stock id */         { "Delete", NULL,
 
7071
  /* label, accelerator */       N_("_Delete"), "<shift>Delete",
 
7072
  /* tooltip */                  N_("Delete each selected item, without moving to the Trash"),
 
7073
                                 G_CALLBACK (action_delete_callback) },
 
7074
  /* name, stock id */         { "Restore From Trash", NULL,
 
7075
  /* label, accelerator */       N_("_Restore"), NULL,
 
7076
                                 NULL,
 
7077
                                 G_CALLBACK (action_restore_from_trash_callback) },
 
7078
  /*
 
7079
   * multiview-TODO: decide whether "Reset to Defaults" should
 
7080
   * be window-wide, and not just view-wide.
 
7081
   * Since this also resets the "Show hidden files" mode,
 
7082
   * it is a mixture of both ATM.
 
7083
   */
 
7084
  /* name, stock id */         { "Reset to Defaults", NULL,
 
7085
  /* label, accelerator */       N_("Reset View to _Defaults"), NULL,
 
7086
  /* tooltip */                  N_("Reset sorting order and zoom level to match preferences for this view"),
 
7087
                                 G_CALLBACK (action_reset_to_defaults_callback) },
 
7088
  /* name, stock id */         { "Connect To Server Link", NULL,
 
7089
  /* label, accelerator */       N_("Connect To This Server"), NULL,
 
7090
  /* tooltip */                  N_("Make a permanent connection to this server"),
 
7091
                                 G_CALLBACK (action_connect_to_server_link_callback) },
 
7092
  /* name, stock id */         { "Mount Volume", NULL,
 
7093
  /* label, accelerator */       N_("_Mount"), NULL,
 
7094
  /* tooltip */                  N_("Mount the selected volume"),
 
7095
                                 G_CALLBACK (action_mount_volume_callback) },
 
7096
  /* name, stock id */         { "Unmount Volume", NULL,
 
7097
  /* label, accelerator */       N_("_Unmount"), NULL,
 
7098
  /* tooltip */                  N_("Unmount the selected volume"),
 
7099
                                 G_CALLBACK (action_unmount_volume_callback) },
 
7100
  /* name, stock id */         { "Eject Volume", NULL,
 
7101
  /* label, accelerator */       N_("_Eject"), NULL,
 
7102
  /* tooltip */                  N_("Eject the selected volume"),
 
7103
                                 G_CALLBACK (action_eject_volume_callback) },
 
7104
  /* name, stock id */         { "Start Volume", NULL,
 
7105
  /* label, accelerator */       N_("_Start"), NULL,
 
7106
  /* tooltip */                  N_("Start the selected volume"),
 
7107
                                 G_CALLBACK (action_start_volume_callback) },
 
7108
  /* name, stock id */         { "Stop Volume", NULL,
 
7109
  /* label, accelerator */       N_("_Stop"), NULL,
 
7110
  /* tooltip */                  N_("Stop the selected volume"),
 
7111
                                 G_CALLBACK (action_stop_volume_callback) },
 
7112
  /* name, stock id */         { "Poll", NULL,
 
7113
  /* label, accelerator */       N_("_Detect Media"), NULL,
 
7114
  /* tooltip */                  N_("Detect media in the selected drive"),
 
7115
                                 G_CALLBACK (action_detect_media_callback) },
 
7116
  /* name, stock id */         { "Self Mount Volume", NULL,
 
7117
  /* label, accelerator */       N_("_Mount"), NULL,
 
7118
  /* tooltip */                  N_("Mount the volume associated with the open folder"),
 
7119
                                 G_CALLBACK (action_self_mount_volume_callback) },
 
7120
  /* name, stock id */         { "Self Unmount Volume", NULL,
 
7121
  /* label, accelerator */       N_("_Unmount"), NULL,
 
7122
  /* tooltip */                  N_("Unmount the volume associated with the open folder"),
 
7123
                                 G_CALLBACK (action_self_unmount_volume_callback) },
 
7124
  /* name, stock id */         { "Self Eject Volume", NULL,
 
7125
  /* label, accelerator */       N_("_Eject"), NULL,
 
7126
  /* tooltip */                  N_("Eject the volume associated with the open folder"),
 
7127
                                 G_CALLBACK (action_self_eject_volume_callback) },
 
7128
  /* name, stock id */         { "Self Start Volume", NULL,
 
7129
  /* label, accelerator */       N_("_Start"), NULL,
 
7130
  /* tooltip */                  N_("Start the volume associated with the open folder"),
 
7131
                                 G_CALLBACK (action_self_start_volume_callback) },
 
7132
  /* name, stock id */         { "Self Stop Volume", NULL,
 
7133
  /* label, accelerator */       N_("_Stop"), NULL,
 
7134
  /* tooltip */                  N_("Stop the volume associated with the open folder"),
 
7135
                                 G_CALLBACK (action_self_stop_volume_callback) },
 
7136
  /* name, stock id */         { "Self Poll", NULL,
 
7137
  /* label, accelerator */       N_("_Detect Media"), NULL,
 
7138
  /* tooltip */                  N_("Detect media in the selected drive"),
 
7139
                                 G_CALLBACK (action_self_detect_media_callback) },
 
7140
  /* name, stock id */         { "OpenCloseParent", NULL,
 
7141
  /* label, accelerator */       N_("Open File and Close window"), "<alt><shift>Down",
 
7142
  /* tooltip */                  NULL,
 
7143
                                 G_CALLBACK (action_open_close_parent_callback) },
 
7144
  /* name, stock id */         { "Save Search", NULL,
 
7145
  /* label, accelerator */       N_("Sa_ve Search"), NULL,
 
7146
  /* tooltip */                  N_("Save the edited search"),
 
7147
                                 G_CALLBACK (action_save_search_callback) },
 
7148
  /* name, stock id */         { "Save Search As", NULL,
 
7149
  /* label, accelerator */       N_("Sa_ve Search As..."), NULL,
 
7150
  /* tooltip */                  N_("Save the current search as a file"),
 
7151
                                 G_CALLBACK (action_save_search_as_callback) },
 
7152
 
 
7153
  /* Location-specific actions */
 
7154
  /* name, stock id */         { NAUTILUS_ACTION_LOCATION_OPEN_ALTERNATE, NULL,
 
7155
  /* label, accelerator */       N_("Open in Navigation Window"), "",
 
7156
  /* tooltip */                  N_("Open this folder in a navigation window"),
 
7157
                                 G_CALLBACK (action_location_open_alternate_callback) },
 
7158
  /* name, stock id */         { NAUTILUS_ACTION_LOCATION_OPEN_IN_NEW_TAB, NULL,
 
7159
  /* label, accelerator */       N_("Open in New _Tab"), "",
 
7160
  /* tooltip */                  N_("Open this folder in a new tab"),
 
7161
                                 G_CALLBACK (action_location_open_in_new_tab_callback) },
 
7162
 
 
7163
  /* name, stock id */         { NAUTILUS_ACTION_LOCATION_CUT, GTK_STOCK_CUT,
 
7164
  /* label, accelerator */       NULL, "",
 
7165
  /* tooltip */                  N_("Prepare this folder to be moved with a Paste command"),
 
7166
                                 G_CALLBACK (action_location_cut_callback) },
 
7167
  /* name, stock id */         { NAUTILUS_ACTION_LOCATION_COPY, GTK_STOCK_COPY,
 
7168
  /* label, accelerator */       NULL, "",
 
7169
  /* tooltip */                  N_("Prepare this folder to be copied with a Paste command"),
 
7170
                                 G_CALLBACK (action_location_copy_callback) },
 
7171
  /* name, stock id */         { NAUTILUS_ACTION_LOCATION_PASTE_FILES_INTO, GTK_STOCK_PASTE,
 
7172
  /* label, accelerator */       N_("_Paste Into Folder"), "",
 
7173
  /* tooltip */                  N_("Move or copy files previously selected by a Cut or Copy command into this folder"),
 
7174
                                 G_CALLBACK (action_location_paste_files_into_callback) },
 
7175
 
 
7176
  /* name, stock id */         { NAUTILUS_ACTION_LOCATION_TRASH, NULL,
 
7177
  /* label, accelerator */       N_("Mo_ve to Trash"), "",
 
7178
  /* tooltip */                  N_("Move this folder to the Trash"),
 
7179
                                 G_CALLBACK (action_location_trash_callback) },
 
7180
  /* name, stock id */         { NAUTILUS_ACTION_LOCATION_DELETE, NAUTILUS_ICON_DELETE,
 
7181
  /* label, accelerator */       N_("_Delete"), "",
 
7182
  /* tooltip */                  N_("Delete this folder, without moving to the Trash"),
 
7183
                                 G_CALLBACK (action_location_delete_callback) },
 
7184
  /* name, stock id */         { NAUTILUS_ACTION_LOCATION_RESTORE_FROM_TRASH, NULL,
 
7185
  /* label, accelerator */       N_("_Restore"), NULL, NULL,
 
7186
                                 G_CALLBACK (action_location_restore_from_trash_callback) },
 
7187
 
 
7188
  /* name, stock id */         { "Location Mount Volume", NULL,
 
7189
  /* label, accelerator */       N_("_Mount"), NULL,
 
7190
  /* tooltip */                  N_("Mount the volume associated with this folder"),
 
7191
                                 G_CALLBACK (action_location_mount_volume_callback) },
 
7192
  /* name, stock id */         { "Location Unmount Volume", NULL,
 
7193
  /* label, accelerator */       N_("_Unmount"), NULL,
 
7194
  /* tooltip */                  N_("Unmount the volume associated with this folder"),
 
7195
                                 G_CALLBACK (action_location_unmount_volume_callback) },
 
7196
  /* name, stock id */         { "Location Eject Volume", NULL,
 
7197
  /* label, accelerator */       N_("_Eject"), NULL,
 
7198
  /* tooltip */                  N_("Eject the volume associated with this folder"),
 
7199
                                 G_CALLBACK (action_location_eject_volume_callback) },
 
7200
  /* name, stock id */         { "Location Start Volume", NULL,
 
7201
  /* label, accelerator */       N_("_Start"), NULL,
 
7202
  /* tooltip */                  N_("Start the volume associated with this folder"),
 
7203
                                 G_CALLBACK (action_location_start_volume_callback) },
 
7204
  /* name, stock id */         { "Location Stop Volume", NULL,
 
7205
  /* label, accelerator */       N_("_Stop"), NULL,
 
7206
  /* tooltip */                  N_("Stop the volume associated with this folder"),
 
7207
                                 G_CALLBACK (action_location_stop_volume_callback) },
 
7208
  /* name, stock id */         { "Location Poll", NULL,
 
7209
  /* label, accelerator */       N_("_Detect Media"), NULL,
 
7210
  /* tooltip */                  N_("Detect media in the selected drive"),
 
7211
                                 G_CALLBACK (action_location_detect_media_callback) },
 
7212
 
 
7213
  /* name, stock id */         { "LocationProperties", GTK_STOCK_PROPERTIES,
 
7214
  /* label, accelerator */       N_("_Properties"), NULL,
 
7215
  /* tooltip */                  N_("View or modify the properties of this folder"),
 
7216
                                 G_CALLBACK (action_location_properties_callback) },
 
7217
 
 
7218
  /* name, stock id, label */  {NAUTILUS_ACTION_COPY_TO_NEXT_PANE, NULL, N_("_Other pane"),
 
7219
                                NULL, N_("Copy the current selection to the other pane in the window"),
 
7220
                                G_CALLBACK (action_copy_to_next_pane_callback) },
 
7221
  /* name, stock id, label */  {NAUTILUS_ACTION_MOVE_TO_NEXT_PANE, NULL, N_("_Other pane"),
 
7222
                                NULL, N_("Move the current selection to the other pane in the window"),
 
7223
                                G_CALLBACK (action_move_to_next_pane_callback) },
 
7224
  /* name, stock id, label */  {NAUTILUS_ACTION_COPY_TO_HOME, NAUTILUS_ICON_HOME,
 
7225
                                N_("_Home"), NULL,
 
7226
                                N_("Copy the current selection to the home folder"),
 
7227
                                G_CALLBACK (action_copy_to_home_callback) },
 
7228
  /* name, stock id, label */  {NAUTILUS_ACTION_MOVE_TO_HOME, NAUTILUS_ICON_HOME,
 
7229
                                N_("_Home"), NULL,
 
7230
                                N_("Move the current selection to the home folder"),
 
7231
                                G_CALLBACK (action_move_to_home_callback) },
 
7232
  /* name, stock id, label */  {NAUTILUS_ACTION_COPY_TO_DESKTOP, NAUTILUS_ICON_DESKTOP,
 
7233
                                N_("_Desktop"), NULL,
 
7234
                                N_("Copy the current selection to the desktop"),
 
7235
                                G_CALLBACK (action_copy_to_desktop_callback) },
 
7236
  /* name, stock id, label */  {NAUTILUS_ACTION_MOVE_TO_DESKTOP, NAUTILUS_ICON_DESKTOP,
 
7237
                                N_("_Desktop"), NULL,
 
7238
                                N_("Move the current selection to the desktop"),
 
7239
                                G_CALLBACK (action_move_to_desktop_callback) },
 
7240
};
 
7241
 
 
7242
static void
 
7243
connect_proxy (NautilusView *view,
 
7244
               GtkAction *action,
 
7245
               GtkWidget *proxy,
 
7246
               GtkActionGroup *action_group)
 
7247
{
 
7248
        GdkPixbuf *pixbuf;
 
7249
        GtkWidget *image;
 
7250
 
 
7251
        if (strcmp (gtk_action_get_name (action), NAUTILUS_ACTION_NEW_EMPTY_DOCUMENT) == 0 &&
 
7252
            GTK_IS_IMAGE_MENU_ITEM (proxy)) {
 
7253
                pixbuf = get_menu_icon ("text-x-generic");
 
7254
                if (pixbuf != NULL) {
 
7255
                        image = gtk_image_new_from_pixbuf (pixbuf);
 
7256
                        gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (proxy), image);
 
7257
 
 
7258
                        g_object_unref (pixbuf);
 
7259
                }
 
7260
        }
 
7261
}
 
7262
 
 
7263
static void
 
7264
pre_activate (NautilusView *view,
 
7265
              GtkAction *action,
 
7266
              GtkActionGroup *action_group)
 
7267
{
 
7268
        GdkEvent *event;
 
7269
        GtkWidget *proxy;
 
7270
        gboolean activated_from_popup;
 
7271
 
 
7272
        /* check whether action was activated through a popup menu.
 
7273
         * If not, unset the last stored context menu popup position */
 
7274
        activated_from_popup = FALSE;
 
7275
 
 
7276
        event = gtk_get_current_event ();
 
7277
        proxy = gtk_get_event_widget (event);
 
7278
 
 
7279
        if (proxy != NULL) {
 
7280
                GtkWidget *toplevel;
 
7281
                GdkWindowTypeHint hint;
 
7282
 
 
7283
                toplevel = gtk_widget_get_toplevel (proxy);
 
7284
 
 
7285
                if (GTK_IS_WINDOW (toplevel)) {
 
7286
                        hint = gtk_window_get_type_hint (GTK_WINDOW (toplevel));
 
7287
 
 
7288
                        if (hint == GDK_WINDOW_TYPE_HINT_POPUP_MENU) {
 
7289
                                activated_from_popup = TRUE;
 
7290
                        }
 
7291
                }
 
7292
        }
 
7293
 
 
7294
        if (!activated_from_popup) {
 
7295
                update_context_menu_position_from_event (view, NULL);
 
7296
        }
 
7297
}
 
7298
 
 
7299
static void
 
7300
real_merge_menus (NautilusView *view)
 
7301
{
 
7302
        GtkActionGroup *action_group;
 
7303
        GtkUIManager *ui_manager;
 
7304
        GtkAction *action;
 
7305
        const char *ui;
 
7306
        char *tooltip;
 
7307
 
 
7308
        ui_manager = nautilus_window_get_ui_manager (view->details->window);
 
7309
 
 
7310
        action_group = gtk_action_group_new ("DirViewActions");
 
7311
        gtk_action_group_set_translation_domain (action_group, GETTEXT_PACKAGE);
 
7312
        view->details->dir_action_group = action_group;
 
7313
        gtk_action_group_add_actions (action_group, 
 
7314
                                      directory_view_entries, G_N_ELEMENTS (directory_view_entries),
 
7315
                                      view);
 
7316
 
 
7317
        /* Translators: %s is a directory */
 
7318
        tooltip = g_strdup_printf (_("Run or manage scripts from %s"), "~/.gnome2/nautilus-scripts");
 
7319
        /* Create a script action here specially because its tooltip is dynamic */
 
7320
        action = gtk_action_new ("Scripts", _("_Scripts"), tooltip, NULL);
 
7321
        gtk_action_group_add_action (action_group, action);
 
7322
        g_object_unref (action);
 
7323
        g_free (tooltip);
 
7324
 
 
7325
        action = gtk_action_group_get_action (action_group, NAUTILUS_ACTION_NO_TEMPLATES);
 
7326
        gtk_action_set_sensitive (action, FALSE);
 
7327
 
 
7328
        g_signal_connect_object (action_group, "connect-proxy",
 
7329
                                 G_CALLBACK (connect_proxy), G_OBJECT (view),
 
7330
                                 G_CONNECT_SWAPPED);
 
7331
        g_signal_connect_object (action_group, "pre-activate",
 
7332
                                 G_CALLBACK (pre_activate), G_OBJECT (view),
 
7333
                                 G_CONNECT_SWAPPED);
 
7334
 
 
7335
        /* Insert action group at end so clipboard action group ends up before it */
 
7336
        gtk_ui_manager_insert_action_group (ui_manager, action_group, -1);
 
7337
        g_object_unref (action_group); /* owned by ui manager */
 
7338
 
 
7339
        ui = nautilus_ui_string_get ("nautilus-directory-view-ui.xml");
 
7340
        view->details->dir_merge_id = gtk_ui_manager_add_ui_from_string (ui_manager, ui, -1, NULL);
 
7341
        
 
7342
        view->details->scripts_invalid = TRUE;
 
7343
        view->details->templates_invalid = TRUE;
 
7344
}
 
7345
 
 
7346
 
 
7347
static gboolean
 
7348
can_paste_into_file (NautilusFile *file)
 
7349
{
 
7350
        if (nautilus_file_is_directory (file) &&
 
7351
            nautilus_file_can_write (file)) {
 
7352
                return TRUE;
 
7353
        }
 
7354
        if (nautilus_file_has_activation_uri (file)) {
 
7355
                GFile *location;
 
7356
                NautilusFile *activation_file;
 
7357
                gboolean res;
 
7358
                
 
7359
                location = nautilus_file_get_activation_location (file);
 
7360
                activation_file = nautilus_file_get (location);
 
7361
                g_object_unref (location);
 
7362
        
 
7363
                /* The target location might not have data for it read yet,
 
7364
                   and we can't want to do sync I/O, so treat the unknown
 
7365
                   case as can-write */
 
7366
                res = (nautilus_file_get_file_type (activation_file) == G_FILE_TYPE_UNKNOWN) ||
 
7367
                        (nautilus_file_get_file_type (activation_file) == G_FILE_TYPE_DIRECTORY &&
 
7368
                         nautilus_file_can_write (activation_file));
 
7369
 
 
7370
                nautilus_file_unref (activation_file);
 
7371
                
 
7372
                return res;
 
7373
        }
 
7374
        
 
7375
        return FALSE;
 
7376
}
 
7377
 
 
7378
static void
 
7379
clipboard_targets_received (GtkClipboard     *clipboard,
 
7380
                            GdkAtom          *targets,
 
7381
                            int               n_targets,
 
7382
                            gpointer          user_data)
 
7383
{
 
7384
        NautilusView *view;
 
7385
        gboolean can_paste;
 
7386
        int i;
 
7387
        GList *selection;
 
7388
        int count;
 
7389
        GtkAction *action;
 
7390
 
 
7391
        view = NAUTILUS_VIEW (user_data);
 
7392
        can_paste = FALSE;
 
7393
 
 
7394
        if (view->details->window == NULL ||
 
7395
            !view->details->active) {
 
7396
                /* We've been destroyed or became inactive since call */
 
7397
                g_object_unref (view);
 
7398
                return;
 
7399
        }
 
7400
 
 
7401
        if (targets) {
 
7402
                for (i=0; i < n_targets; i++) {
 
7403
                        if (targets[i] == copied_files_atom) {
 
7404
                                can_paste = TRUE;
 
7405
                        }
 
7406
                }
 
7407
        }
 
7408
        
 
7409
        
 
7410
        selection = nautilus_view_get_selection (view);
 
7411
        count = g_list_length (selection);
 
7412
        
 
7413
        action = gtk_action_group_get_action (view->details->dir_action_group,
 
7414
                                              NAUTILUS_ACTION_PASTE);
 
7415
        gtk_action_set_sensitive (action,
 
7416
                                  can_paste && !nautilus_view_is_read_only (view));
 
7417
 
 
7418
        action = gtk_action_group_get_action (view->details->dir_action_group,
 
7419
                                              NAUTILUS_ACTION_PASTE_FILES_INTO);
 
7420
        gtk_action_set_sensitive (action,
 
7421
                                  can_paste && count == 1 &&
 
7422
                                  can_paste_into_file (NAUTILUS_FILE (selection->data)));
 
7423
 
 
7424
        action = gtk_action_group_get_action (view->details->dir_action_group,
 
7425
                                              NAUTILUS_ACTION_LOCATION_PASTE_FILES_INTO);
 
7426
        g_object_set_data (G_OBJECT (action),
 
7427
                           "can-paste-according-to-clipboard",
 
7428
                           GINT_TO_POINTER (can_paste));
 
7429
        gtk_action_set_sensitive (action,
 
7430
                                  GPOINTER_TO_INT (g_object_get_data (G_OBJECT (action),
 
7431
                                                                      "can-paste-according-to-clipboard")) &&
 
7432
                                  GPOINTER_TO_INT (g_object_get_data (G_OBJECT (action),
 
7433
                                                                      "can-paste-according-to-destination")));
 
7434
 
 
7435
        nautilus_file_list_free (selection);
 
7436
        
 
7437
        g_object_unref (view);
 
7438
}
 
7439
 
 
7440
static gboolean
 
7441
should_show_empty_trash (NautilusView *view)
 
7442
{
 
7443
        return (showing_trash_directory (view));
 
7444
}
 
7445
 
 
7446
static gboolean
 
7447
file_list_all_are_folders (GList *file_list)
 
7448
{
 
7449
        GList *l;
 
7450
        NautilusFile *file, *linked_file;
 
7451
        char *activation_uri;
 
7452
        gboolean is_dir;
 
7453
        
 
7454
        for (l = file_list; l != NULL; l = l->next) {
 
7455
                file = NAUTILUS_FILE (l->data);
 
7456
                if (nautilus_file_is_nautilus_link (file) &&
 
7457
                    !NAUTILUS_IS_DESKTOP_ICON_FILE (file)) {
 
7458
                        if (nautilus_file_is_launcher (file)) {
 
7459
                                return FALSE;
 
7460
                        }
 
7461
                                
 
7462
                        activation_uri = nautilus_file_get_activation_uri (file);
 
7463
                        
 
7464
                        if (activation_uri == NULL) {
 
7465
                                g_free (activation_uri);
 
7466
                                return FALSE;
 
7467
                        }
 
7468
 
 
7469
                        linked_file = nautilus_file_get_existing_by_uri (activation_uri);
 
7470
 
 
7471
                        /* We might not actually know the type of the linked file yet,
 
7472
                         * however we don't want to schedule a read, since that might do things
 
7473
                         * like ask for password etc. This is a bit unfortunate, but I don't
 
7474
                         * know any way around it, so we do various heuristics here
 
7475
                         * to get things mostly right 
 
7476
                         */
 
7477
                        is_dir =
 
7478
                                (linked_file != NULL &&
 
7479
                                 nautilus_file_is_directory (linked_file)) ||
 
7480
                                (activation_uri != NULL &&
 
7481
                                 activation_uri[strlen (activation_uri) - 1] == '/');
 
7482
                        
 
7483
                        nautilus_file_unref (linked_file);
 
7484
                        g_free (activation_uri);
 
7485
                        
 
7486
                        if (!is_dir) {
 
7487
                                return FALSE;
 
7488
                        }
 
7489
                } else if (!(nautilus_file_is_directory (file) ||
 
7490
                             NAUTILUS_IS_DESKTOP_ICON_FILE (file))) {
 
7491
                        return FALSE;
 
7492
                }
 
7493
        }
 
7494
        return TRUE;
 
7495
}
 
7496
 
 
7497
static void
 
7498
file_should_show_foreach (NautilusFile        *file,
 
7499
                          gboolean            *show_mount,
 
7500
                          gboolean            *show_unmount,
 
7501
                          gboolean            *show_eject,
 
7502
                          gboolean            *show_connect,
 
7503
                          gboolean            *show_start,
 
7504
                          gboolean            *show_stop,
 
7505
                          gboolean            *show_poll,
 
7506
                          GDriveStartStopType *start_stop_type)
 
7507
{
 
7508
        char *uri;
 
7509
 
 
7510
        *show_mount = FALSE;
 
7511
        *show_unmount = FALSE;
 
7512
        *show_eject = FALSE;
 
7513
        *show_connect = FALSE;
 
7514
        *show_start = FALSE;
 
7515
        *show_stop = FALSE;
 
7516
        *show_poll = FALSE;
 
7517
 
 
7518
        if (nautilus_file_can_eject (file)) {
 
7519
                *show_eject = TRUE;
 
7520
        }
 
7521
 
 
7522
        if (nautilus_file_can_mount (file)) {
 
7523
                *show_mount = TRUE;
 
7524
        }
 
7525
 
 
7526
        if (nautilus_file_can_start (file) || nautilus_file_can_start_degraded (file)) {
 
7527
                *show_start = TRUE;
 
7528
        }
 
7529
 
 
7530
        if (nautilus_file_can_stop (file)) {
 
7531
                *show_stop = TRUE;
 
7532
        }
 
7533
 
 
7534
        /* Dot not show both Unmount and Eject/Safe Removal; too confusing to
 
7535
         * have too many menu entries */
 
7536
        if (nautilus_file_can_unmount (file) && !*show_eject && !*show_stop) {
 
7537
                *show_unmount = TRUE;
 
7538
        }
 
7539
 
 
7540
        if (nautilus_file_can_poll_for_media (file) && !nautilus_file_is_media_check_automatic (file)) {
 
7541
                *show_poll = TRUE;
 
7542
        }
 
7543
 
 
7544
        *start_stop_type = nautilus_file_get_start_stop_type (file);
 
7545
 
 
7546
        if (nautilus_file_is_nautilus_link (file)) {
 
7547
                uri = nautilus_file_get_activation_uri (file);
 
7548
                if (uri != NULL &&
 
7549
                    (eel_istr_has_prefix (uri, "ftp:") ||
 
7550
                     eel_istr_has_prefix (uri, "ssh:") ||
 
7551
                     eel_istr_has_prefix (uri, "sftp:") ||
 
7552
                     eel_istr_has_prefix (uri, "dav:") ||
 
7553
                     eel_istr_has_prefix (uri, "davs:"))) {
 
7554
                        *show_connect = TRUE;
 
7555
                }
 
7556
                g_free (uri);
 
7557
        }
 
7558
}
 
7559
 
 
7560
static void
 
7561
file_should_show_self (NautilusFile        *file,
 
7562
                       gboolean            *show_mount,
 
7563
                       gboolean            *show_unmount,
 
7564
                       gboolean            *show_eject,
 
7565
                       gboolean            *show_start,
 
7566
                       gboolean            *show_stop,
 
7567
                       gboolean            *show_poll,
 
7568
                       GDriveStartStopType *start_stop_type)
 
7569
{
 
7570
        *show_mount = FALSE;
 
7571
        *show_unmount = FALSE;
 
7572
        *show_eject = FALSE;
 
7573
        *show_start = FALSE;
 
7574
        *show_stop = FALSE;
 
7575
        *show_poll = FALSE;
 
7576
 
 
7577
        if (file == NULL) {
 
7578
                return;
 
7579
        }
 
7580
 
 
7581
        if (nautilus_file_can_eject (file)) {
 
7582
                *show_eject = TRUE;
 
7583
        }
 
7584
 
 
7585
        if (nautilus_file_can_mount (file)) {
 
7586
                *show_mount = TRUE;
 
7587
        }
 
7588
 
 
7589
        if (nautilus_file_can_start (file) || nautilus_file_can_start_degraded (file)) {
 
7590
                *show_start = TRUE;
 
7591
        }
 
7592
 
 
7593
        if (nautilus_file_can_stop (file)) {
 
7594
                *show_stop = TRUE;
 
7595
        }
 
7596
 
 
7597
        /* Dot not show both Unmount and Eject/Safe Removal; too confusing to
 
7598
         * have too many menu entries */
 
7599
        if (nautilus_file_can_unmount (file) && !*show_eject && !*show_stop) {
 
7600
                *show_unmount = TRUE;
 
7601
        }
 
7602
 
 
7603
        if (nautilus_file_can_poll_for_media (file) && !nautilus_file_is_media_check_automatic (file)) {
 
7604
                *show_poll = TRUE;
 
7605
        }
 
7606
 
 
7607
        *start_stop_type = nautilus_file_get_start_stop_type (file);
 
7608
 
 
7609
}
 
7610
 
 
7611
static gboolean
 
7612
files_are_all_directories (GList *files)
 
7613
{
 
7614
        NautilusFile *file;
 
7615
        GList *l;
 
7616
        gboolean all_directories;
 
7617
 
 
7618
        all_directories = TRUE;
 
7619
 
 
7620
        for (l = files; l != NULL; l = l->next) {
 
7621
                file = NAUTILUS_FILE (l->data);
 
7622
                all_directories &= nautilus_file_is_directory (file);
 
7623
        }
 
7624
 
 
7625
        return all_directories;
 
7626
}
 
7627
 
 
7628
static gboolean
 
7629
files_is_none_directory (GList *files)
 
7630
{
 
7631
        NautilusFile *file;
 
7632
        GList *l;
 
7633
        gboolean no_directory;
 
7634
 
 
7635
        no_directory = TRUE;
 
7636
 
 
7637
        for (l = files; l != NULL; l = l->next) {
 
7638
                file = NAUTILUS_FILE (l->data);
 
7639
                no_directory &= !nautilus_file_is_directory (file);
 
7640
        }
 
7641
 
 
7642
        return no_directory;
 
7643
}
 
7644
 
 
7645
static void
 
7646
update_restore_from_trash_action (GtkAction *action,
 
7647
                                  GList *files,
 
7648
                                  gboolean is_self)
 
7649
{
 
7650
        NautilusFile *original_file;
 
7651
        NautilusFile *original_dir;
 
7652
        GHashTable *original_dirs_hash;
 
7653
        GList *original_dirs;
 
7654
        GFile *original_location;
 
7655
        char *tooltip, *original_name;
 
7656
 
 
7657
        original_file = NULL;
 
7658
        original_dir = NULL;
 
7659
        original_dirs = NULL;
 
7660
        original_dirs_hash = NULL;
 
7661
        original_location = NULL;
 
7662
        original_name = NULL;
 
7663
 
 
7664
        if (files != NULL) {
 
7665
                if (g_list_length (files) == 1) {
 
7666
                        original_file = nautilus_file_get_trash_original_file (files->data);
 
7667
                } else {
 
7668
                        original_dirs_hash = nautilus_trashed_files_get_original_directories (files, NULL);
 
7669
                        if (original_dirs_hash != NULL) {
 
7670
                                original_dirs = g_hash_table_get_keys (original_dirs_hash);
 
7671
                                if (g_list_length (original_dirs) == 1) {
 
7672
                                        original_dir = nautilus_file_ref (NAUTILUS_FILE (original_dirs->data));
 
7673
                                }
 
7674
                        }
 
7675
                }
 
7676
        }
 
7677
 
 
7678
        if (original_file != NULL || original_dirs != NULL) {
 
7679
                gtk_action_set_visible (action, TRUE);
 
7680
 
 
7681
                if (original_file != NULL) {
 
7682
                        original_location = nautilus_file_get_location (original_file);
 
7683
                } else if (original_dir != NULL) {
 
7684
                        original_location = nautilus_file_get_location (original_dir);
 
7685
                }
 
7686
 
 
7687
                if (original_location != NULL) {
 
7688
                        original_name = g_file_get_parse_name (original_location);
 
7689
                }
 
7690
 
 
7691
                if (is_self) {
 
7692
                        g_assert (g_list_length (files) == 1);
 
7693
                        g_assert (original_location != NULL);
 
7694
                        tooltip = g_strdup_printf (_("Move the open folder out of the trash to \"%s\""), original_name);
 
7695
                } else if (files_are_all_directories (files)) {
 
7696
                        if (original_name != NULL) {
 
7697
                                tooltip = g_strdup_printf (ngettext ("Move the selected folder out of the trash to \"%s\"",
 
7698
                                                                     "Move the selected folders out of the trash to \"%s\"",
 
7699
                                                                     g_list_length (files)), original_name);
 
7700
                        } else {
 
7701
                                tooltip = g_strdup_printf (ngettext ("Move the selected folder out of the trash",
 
7702
                                                                     "Move the selected folders out of the trash",
 
7703
                                                                     g_list_length (files)));
 
7704
                        }
 
7705
                } else if (files_is_none_directory (files)) {
 
7706
                        if (original_name != NULL) {
 
7707
                                tooltip = g_strdup_printf (ngettext ("Move the selected file out of the trash to \"%s\"",
 
7708
                                                                     "Move the selected files out of the trash to \"%s\"",
 
7709
                                                                     g_list_length (files)), original_name);
 
7710
                        } else {
 
7711
                                tooltip = g_strdup_printf (ngettext ("Move the selected file out of the trash",
 
7712
                                                                     "Move the selected files out of the trash",
 
7713
                                                                     g_list_length (files)));
 
7714
                        }
 
7715
                } else {
 
7716
                        if (original_name != NULL) {
 
7717
                                tooltip = g_strdup_printf (ngettext ("Move the selected item out of the trash to \"%s\"",
 
7718
                                                                     "Move the selected items out of the trash to \"%s\"",
 
7719
                                                                     g_list_length (files)), original_name);
 
7720
                        } else {
 
7721
                                tooltip = g_strdup_printf (ngettext ("Move the selected item out of the trash",
 
7722
                                                                     "Move the selected items out of the trash",
 
7723
                                                                     g_list_length (files)));
 
7724
                        }
 
7725
                }
 
7726
                g_free (original_name);
 
7727
 
 
7728
                g_object_set (action, "tooltip", tooltip, NULL);
 
7729
 
 
7730
                if (original_location != NULL) {
 
7731
                        g_object_unref (original_location);
 
7732
                }
 
7733
        } else {
 
7734
                gtk_action_set_visible (action, FALSE);
 
7735
        }
 
7736
 
 
7737
        nautilus_file_unref (original_file);
 
7738
        nautilus_file_unref (original_dir);
 
7739
        g_list_free (original_dirs);
 
7740
 
 
7741
        if (original_dirs_hash != NULL) {
 
7742
                g_hash_table_destroy (original_dirs_hash);
 
7743
        }
 
7744
}
 
7745
 
 
7746
static void
 
7747
real_update_menus_volumes (NautilusView *view,
 
7748
                           GList *selection,
 
7749
                           gint selection_count)
 
7750
{
 
7751
        GList *l;
 
7752
        NautilusFile *file;
 
7753
        gboolean show_mount;
 
7754
        gboolean show_unmount;
 
7755
        gboolean show_eject;
 
7756
        gboolean show_connect;
 
7757
        gboolean show_start;
 
7758
        gboolean show_stop;
 
7759
        gboolean show_poll;
 
7760
        GDriveStartStopType start_stop_type;
 
7761
        gboolean show_self_mount;
 
7762
        gboolean show_self_unmount;
 
7763
        gboolean show_self_eject;
 
7764
        gboolean show_self_start;
 
7765
        gboolean show_self_stop;
 
7766
        gboolean show_self_poll;
 
7767
        GDriveStartStopType self_start_stop_type;
 
7768
        GtkAction *action;
 
7769
 
 
7770
        show_mount = (selection != NULL);
 
7771
        show_unmount = (selection != NULL);
 
7772
        show_eject = (selection != NULL);
 
7773
        show_connect = (selection != NULL && selection_count == 1);
 
7774
        show_start = (selection != NULL && selection_count == 1);
 
7775
        show_stop = (selection != NULL && selection_count == 1);
 
7776
        show_poll = (selection != NULL && selection_count == 1);
 
7777
        start_stop_type = G_DRIVE_START_STOP_TYPE_UNKNOWN;
 
7778
        self_start_stop_type = G_DRIVE_START_STOP_TYPE_UNKNOWN;
 
7779
 
 
7780
        for (l = selection; l != NULL && (show_mount || show_unmount
 
7781
                                          || show_eject || show_connect
 
7782
                                          || show_start || show_stop
 
7783
                                          || show_poll);
 
7784
             l = l->next) {
 
7785
                gboolean show_mount_one;
 
7786
                gboolean show_unmount_one;
 
7787
                gboolean show_eject_one;
 
7788
                gboolean show_connect_one;
 
7789
                gboolean show_start_one;
 
7790
                gboolean show_stop_one;
 
7791
                gboolean show_poll_one;
 
7792
 
 
7793
                file = NAUTILUS_FILE (l->data);
 
7794
                file_should_show_foreach (file,
 
7795
                                          &show_mount_one,
 
7796
                                          &show_unmount_one,
 
7797
                                          &show_eject_one,
 
7798
                                          &show_connect_one,
 
7799
                                          &show_start_one,
 
7800
                                          &show_stop_one,
 
7801
                                          &show_poll_one,
 
7802
                                          &start_stop_type);
 
7803
 
 
7804
                show_mount &= show_mount_one;
 
7805
                show_unmount &= show_unmount_one;
 
7806
                show_eject &= show_eject_one;
 
7807
                show_connect &= show_connect_one;
 
7808
                show_start &= show_start_one;
 
7809
                show_stop &= show_stop_one;
 
7810
                show_poll &= show_poll_one;
 
7811
        }
 
7812
 
 
7813
        action = gtk_action_group_get_action (view->details->dir_action_group,
 
7814
                                              NAUTILUS_ACTION_CONNECT_TO_SERVER_LINK);
 
7815
        gtk_action_set_visible (action, show_connect);
 
7816
        
 
7817
        action = gtk_action_group_get_action (view->details->dir_action_group,
 
7818
                                              NAUTILUS_ACTION_MOUNT_VOLUME);
 
7819
        gtk_action_set_visible (action, show_mount);
 
7820
        
 
7821
        action = gtk_action_group_get_action (view->details->dir_action_group,
 
7822
                                              NAUTILUS_ACTION_UNMOUNT_VOLUME);
 
7823
        gtk_action_set_visible (action, show_unmount);
 
7824
        
 
7825
        action = gtk_action_group_get_action (view->details->dir_action_group,
 
7826
                                              NAUTILUS_ACTION_EJECT_VOLUME);
 
7827
        gtk_action_set_visible (action, show_eject);
 
7828
        
 
7829
        action = gtk_action_group_get_action (view->details->dir_action_group,
 
7830
                                              NAUTILUS_ACTION_START_VOLUME);
 
7831
        gtk_action_set_visible (action, show_start);
 
7832
        if (show_start) {
 
7833
                switch (start_stop_type) {
 
7834
                default:
 
7835
                case G_DRIVE_START_STOP_TYPE_UNKNOWN:
 
7836
                        gtk_action_set_label (action, _("_Start"));
 
7837
                        gtk_action_set_tooltip (action, _("Start the selected drive"));
 
7838
                        break;
 
7839
                case G_DRIVE_START_STOP_TYPE_SHUTDOWN:
 
7840
                        gtk_action_set_label (action, _("_Start"));
 
7841
                        gtk_action_set_tooltip (action, _("Start the selected drive"));
 
7842
                        break;
 
7843
                case G_DRIVE_START_STOP_TYPE_NETWORK:
 
7844
                        gtk_action_set_label (action, _("_Connect"));
 
7845
                        gtk_action_set_tooltip (action, _("Connect to the selected drive"));
 
7846
                        break;
 
7847
                case G_DRIVE_START_STOP_TYPE_MULTIDISK:
 
7848
                        gtk_action_set_label (action, _("_Start Multi-disk Drive"));
 
7849
                        gtk_action_set_tooltip (action, _("Start the selected multi-disk drive"));
 
7850
                        break;
 
7851
                case G_DRIVE_START_STOP_TYPE_PASSWORD:
 
7852
                        gtk_action_set_label (action, _("U_nlock Drive"));
 
7853
                        gtk_action_set_tooltip (action, _("Unlock the selected drive"));
 
7854
                        break;
 
7855
                }
 
7856
        }
 
7857
 
 
7858
        action = gtk_action_group_get_action (view->details->dir_action_group,
 
7859
                                              NAUTILUS_ACTION_STOP_VOLUME);
 
7860
        gtk_action_set_visible (action, show_stop);
 
7861
        if (show_stop) {
 
7862
                switch (start_stop_type) {
 
7863
                default:
 
7864
                case G_DRIVE_START_STOP_TYPE_UNKNOWN:
 
7865
                        gtk_action_set_label (action, _("_Stop"));
 
7866
                        gtk_action_set_tooltip (action, _("Stop the selected drive"));
 
7867
                        break;
 
7868
                case G_DRIVE_START_STOP_TYPE_SHUTDOWN:
 
7869
                        gtk_action_set_label (action, _("_Safely Remove Drive"));
 
7870
                        gtk_action_set_tooltip (action, _("Safely remove the selected drive"));
 
7871
                        break;
 
7872
                case G_DRIVE_START_STOP_TYPE_NETWORK:
 
7873
                        gtk_action_set_label (action, _("_Disconnect"));
 
7874
                        gtk_action_set_tooltip (action, _("Disconnect the selected drive"));
 
7875
                        break;
 
7876
                case G_DRIVE_START_STOP_TYPE_MULTIDISK:
 
7877
                        gtk_action_set_label (action, _("_Stop Multi-disk Drive"));
 
7878
                        gtk_action_set_tooltip (action, _("Stop the selected multi-disk drive"));
 
7879
                        break;
 
7880
                case G_DRIVE_START_STOP_TYPE_PASSWORD:
 
7881
                        gtk_action_set_label (action, _("_Lock Drive"));
 
7882
                        gtk_action_set_tooltip (action, _("Lock the selected drive"));
 
7883
                        break;
 
7884
                }
 
7885
        }
 
7886
 
 
7887
        action = gtk_action_group_get_action (view->details->dir_action_group,
 
7888
                                              NAUTILUS_ACTION_POLL);
 
7889
        gtk_action_set_visible (action, show_poll);
 
7890
 
 
7891
        show_self_mount = show_self_unmount = show_self_eject =
 
7892
                show_self_start = show_self_stop = show_self_poll = FALSE;
 
7893
 
 
7894
        file = nautilus_view_get_directory_as_file (view);
 
7895
        file_should_show_self (file,
 
7896
                               &show_self_mount,
 
7897
                               &show_self_unmount,
 
7898
                               &show_self_eject,
 
7899
                               &show_self_start,
 
7900
                               &show_self_stop,
 
7901
                               &show_self_poll,
 
7902
                               &self_start_stop_type);
 
7903
 
 
7904
        action = gtk_action_group_get_action (view->details->dir_action_group,
 
7905
                                              NAUTILUS_ACTION_SELF_MOUNT_VOLUME);
 
7906
        gtk_action_set_visible (action, show_self_mount);
 
7907
 
 
7908
        action = gtk_action_group_get_action (view->details->dir_action_group,
 
7909
                                              NAUTILUS_ACTION_SELF_UNMOUNT_VOLUME);
 
7910
        gtk_action_set_visible (action, show_self_unmount);
 
7911
 
 
7912
        action = gtk_action_group_get_action (view->details->dir_action_group,
 
7913
                                              NAUTILUS_ACTION_SELF_EJECT_VOLUME);
 
7914
        gtk_action_set_visible (action, show_self_eject);
 
7915
 
 
7916
        action = gtk_action_group_get_action (view->details->dir_action_group,
 
7917
                                              NAUTILUS_ACTION_SELF_START_VOLUME);
 
7918
        gtk_action_set_visible (action, show_self_start);
 
7919
        if (show_self_start) {
 
7920
                switch (self_start_stop_type) {
 
7921
                default:
 
7922
                case G_DRIVE_START_STOP_TYPE_UNKNOWN:
 
7923
                        gtk_action_set_label (action, _("_Start"));
 
7924
                        gtk_action_set_tooltip (action, _("Start the drive associated with the open folder"));
 
7925
                        break;
 
7926
                case G_DRIVE_START_STOP_TYPE_SHUTDOWN:
 
7927
                        gtk_action_set_label (action, _("_Start"));
 
7928
                        gtk_action_set_tooltip (action, _("Start the drive associated with the open folder"));
 
7929
                        break;
 
7930
                case G_DRIVE_START_STOP_TYPE_NETWORK:
 
7931
                        gtk_action_set_label (action, _("_Connect"));
 
7932
                        gtk_action_set_tooltip (action, _("Connect to the drive associated with the open folder"));
 
7933
                        break;
 
7934
                case G_DRIVE_START_STOP_TYPE_MULTIDISK:
 
7935
                        gtk_action_set_label (action, _("_Start Multi-disk Drive"));
 
7936
                        gtk_action_set_tooltip (action, _("Start the multi-disk drive associated with the open folder"));
 
7937
                        break;
 
7938
                case G_DRIVE_START_STOP_TYPE_PASSWORD:
 
7939
                        gtk_action_set_label (action, _("_Unlock Drive"));
 
7940
                        gtk_action_set_tooltip (action, _("Unlock the drive associated with the open folder"));
 
7941
                        break;
 
7942
                }
 
7943
        }
 
7944
 
 
7945
        action = gtk_action_group_get_action (view->details->dir_action_group,
 
7946
                                              NAUTILUS_ACTION_SELF_STOP_VOLUME);
 
7947
        gtk_action_set_visible (action, show_self_stop);
 
7948
        if (show_self_stop) {
 
7949
                switch (self_start_stop_type) {
 
7950
                default:
 
7951
                case G_DRIVE_START_STOP_TYPE_UNKNOWN:
 
7952
                        gtk_action_set_label (action, _("_Stop"));
 
7953
                        gtk_action_set_tooltip (action, _("_Stop the drive associated with the open folder"));
 
7954
                        break;
 
7955
                case G_DRIVE_START_STOP_TYPE_SHUTDOWN:
 
7956
                        gtk_action_set_label (action, _("_Safely Remove Drive"));
 
7957
                        gtk_action_set_tooltip (action, _("Safely remove the drive associated with the open folder"));
 
7958
                        break;
 
7959
                case G_DRIVE_START_STOP_TYPE_NETWORK:
 
7960
                        gtk_action_set_label (action, _("_Disconnect"));
 
7961
                        gtk_action_set_tooltip (action, _("Disconnect the drive associated with the open folder"));
 
7962
                        break;
 
7963
                case G_DRIVE_START_STOP_TYPE_MULTIDISK:
 
7964
                        gtk_action_set_label (action, _("_Stop Multi-disk Drive"));
 
7965
                        gtk_action_set_tooltip (action, _("Stop the multi-disk drive associated with the open folder"));
 
7966
                        break;
 
7967
                case G_DRIVE_START_STOP_TYPE_PASSWORD:
 
7968
                        gtk_action_set_label (action, _("_Lock Drive"));
 
7969
                        gtk_action_set_tooltip (action, _("Lock the drive associated with the open folder"));
 
7970
                        break;
 
7971
                }
 
7972
        }
 
7973
 
 
7974
        action = gtk_action_group_get_action (view->details->dir_action_group,
 
7975
                                              NAUTILUS_ACTION_SELF_POLL);
 
7976
        gtk_action_set_visible (action, show_self_poll);
 
7977
 
 
7978
}
 
7979
 
 
7980
static void
 
7981
real_update_location_menu_volumes (NautilusView *view)
 
7982
{
 
7983
        GtkAction *action;
 
7984
        NautilusFile *file;
 
7985
        gboolean show_mount;
 
7986
        gboolean show_unmount;
 
7987
        gboolean show_eject;
 
7988
        gboolean show_connect;
 
7989
        gboolean show_start;
 
7990
        gboolean show_stop;
 
7991
        gboolean show_poll;
 
7992
        GDriveStartStopType start_stop_type;
 
7993
 
 
7994
        g_assert (NAUTILUS_IS_VIEW (view));
 
7995
        g_assert (NAUTILUS_IS_FILE (view->details->location_popup_directory_as_file));
 
7996
 
 
7997
        file = NAUTILUS_FILE (view->details->location_popup_directory_as_file);
 
7998
        file_should_show_foreach (file,
 
7999
                                  &show_mount,
 
8000
                                  &show_unmount,
 
8001
                                  &show_eject,
 
8002
                                  &show_connect,
 
8003
                                  &show_start,
 
8004
                                  &show_stop,
 
8005
                                  &show_poll,
 
8006
                                  &start_stop_type);
 
8007
 
 
8008
        action = gtk_action_group_get_action (view->details->dir_action_group,
 
8009
                                              NAUTILUS_ACTION_LOCATION_MOUNT_VOLUME);
 
8010
        gtk_action_set_visible (action, show_mount);
 
8011
 
 
8012
        action = gtk_action_group_get_action (view->details->dir_action_group,
 
8013
                                              NAUTILUS_ACTION_LOCATION_UNMOUNT_VOLUME);
 
8014
        gtk_action_set_visible (action, show_unmount);
 
8015
 
 
8016
        action = gtk_action_group_get_action (view->details->dir_action_group,
 
8017
                                              NAUTILUS_ACTION_LOCATION_EJECT_VOLUME);
 
8018
        gtk_action_set_visible (action, show_eject);
 
8019
 
 
8020
        action = gtk_action_group_get_action (view->details->dir_action_group,
 
8021
                                              NAUTILUS_ACTION_LOCATION_START_VOLUME);
 
8022
        gtk_action_set_visible (action, show_start);
 
8023
        if (show_start) {
 
8024
                switch (start_stop_type) {
 
8025
                default:
 
8026
                case G_DRIVE_START_STOP_TYPE_UNKNOWN:
 
8027
                        gtk_action_set_label (action, _("_Start"));
 
8028
                        gtk_action_set_tooltip (action, _("Start the selected drive"));
 
8029
                        break;
 
8030
                case G_DRIVE_START_STOP_TYPE_SHUTDOWN:
 
8031
                        gtk_action_set_label (action, _("_Start"));
 
8032
                        gtk_action_set_tooltip (action, _("Start the selected drive"));
 
8033
                        break;
 
8034
                case G_DRIVE_START_STOP_TYPE_NETWORK:
 
8035
                        gtk_action_set_label (action, _("_Connect"));
 
8036
                        gtk_action_set_tooltip (action, _("Connect to the selected drive"));
 
8037
                        break;
 
8038
                case G_DRIVE_START_STOP_TYPE_MULTIDISK:
 
8039
                        gtk_action_set_label (action, _("_Start Multi-disk Drive"));
 
8040
                        gtk_action_set_tooltip (action, _("Start the selected multi-disk drive"));
 
8041
                        break;
 
8042
                case G_DRIVE_START_STOP_TYPE_PASSWORD:
 
8043
                        gtk_action_set_label (action, _("_Unlock Drive"));
 
8044
                        gtk_action_set_tooltip (action, _("Unlock the selected drive"));
 
8045
                        break;
 
8046
                }
 
8047
        }
 
8048
 
 
8049
        action = gtk_action_group_get_action (view->details->dir_action_group,
 
8050
                                              NAUTILUS_ACTION_LOCATION_STOP_VOLUME);
 
8051
        gtk_action_set_visible (action, show_stop);
 
8052
        if (show_stop) {
 
8053
                switch (start_stop_type) {
 
8054
                default:
 
8055
                case G_DRIVE_START_STOP_TYPE_UNKNOWN:
 
8056
                        gtk_action_set_label (action, _("_Stop"));
 
8057
                        gtk_action_set_tooltip (action, _("Stop the selected volume"));
 
8058
                        break;
 
8059
                case G_DRIVE_START_STOP_TYPE_SHUTDOWN:
 
8060
                        gtk_action_set_label (action, _("_Safely Remove Drive"));
 
8061
                        gtk_action_set_tooltip (action, _("Safely remove the selected drive"));
 
8062
                        break;
 
8063
                case G_DRIVE_START_STOP_TYPE_NETWORK:
 
8064
                        gtk_action_set_label (action, _("_Disconnect"));
 
8065
                        gtk_action_set_tooltip (action, _("Disconnect the selected drive"));
 
8066
                        break;
 
8067
                case G_DRIVE_START_STOP_TYPE_MULTIDISK:
 
8068
                        gtk_action_set_label (action, _("_Stop Multi-disk Drive"));
 
8069
                        gtk_action_set_tooltip (action, _("Stop the selected multi-disk drive"));
 
8070
                        break;
 
8071
                case G_DRIVE_START_STOP_TYPE_PASSWORD:
 
8072
                        gtk_action_set_label (action, _("_Lock Drive"));
 
8073
                        gtk_action_set_tooltip (action, _("Lock the selected drive"));
 
8074
                        break;
 
8075
                }
 
8076
        }
 
8077
 
 
8078
        action = gtk_action_group_get_action (view->details->dir_action_group,
 
8079
                                              NAUTILUS_ACTION_LOCATION_POLL);
 
8080
        gtk_action_set_visible (action, show_poll);
 
8081
}
 
8082
 
 
8083
/* TODO: we should split out this routine into two functions:
 
8084
 * Update on clipboard changes
 
8085
 * Update on selection changes
 
8086
 */
 
8087
static void
 
8088
real_update_paste_menu (NautilusView *view,
 
8089
                        GList *selection,
 
8090
                        gint selection_count)
 
8091
{
 
8092
        gboolean can_paste_files_into;
 
8093
        gboolean selection_is_read_only;
 
8094
        gboolean is_read_only;
 
8095
        GtkAction *action;
 
8096
 
 
8097
        selection_is_read_only = selection_count == 1 &&
 
8098
                (!nautilus_file_can_write (NAUTILUS_FILE (selection->data)) &&
 
8099
                 !nautilus_file_has_activation_uri (NAUTILUS_FILE (selection->data)));
 
8100
                 
 
8101
        is_read_only = nautilus_view_is_read_only (view);
 
8102
        
 
8103
        can_paste_files_into = (selection_count == 1 && 
 
8104
                                can_paste_into_file (NAUTILUS_FILE (selection->data)));
 
8105
 
 
8106
        action = gtk_action_group_get_action (view->details->dir_action_group,
 
8107
                                              NAUTILUS_ACTION_PASTE);
 
8108
        gtk_action_set_sensitive (action, !is_read_only);
 
8109
        
 
8110
        action = gtk_action_group_get_action (view->details->dir_action_group,
 
8111
                                              NAUTILUS_ACTION_PASTE_FILES_INTO);
 
8112
        gtk_action_set_visible (action, can_paste_files_into);
 
8113
        gtk_action_set_sensitive (action, !selection_is_read_only);
 
8114
 
 
8115
        /* Ask the clipboard */
 
8116
        g_object_ref (view); /* Need to keep the object alive until we get the reply */
 
8117
        gtk_clipboard_request_targets (nautilus_clipboard_get (GTK_WIDGET (view)),
 
8118
                                       clipboard_targets_received,
 
8119
                                       view);
 
8120
}
 
8121
 
 
8122
static void
 
8123
real_update_location_menu (NautilusView *view)
 
8124
{
 
8125
        GtkAction *action;
 
8126
        NautilusFile *file;
 
8127
        gboolean is_special_link;
 
8128
        gboolean is_desktop_or_home_dir;
 
8129
        gboolean can_delete_file, show_delete;
 
8130
        gboolean show_separate_delete_command;
 
8131
        gboolean show_open_in_new_tab;
 
8132
        gboolean show_open_alternate;
 
8133
        GList l;
 
8134
        char *label;
 
8135
        char *tip;
 
8136
 
 
8137
        show_open_in_new_tab = g_settings_get_boolean (nautilus_preferences, NAUTILUS_PREFERENCES_ALWAYS_USE_BROWSER);
 
8138
        show_open_alternate = g_settings_get_boolean (nautilus_preferences, NAUTILUS_PREFERENCES_ALWAYS_USE_BROWSER);
 
8139
 
 
8140
        action = gtk_action_group_get_action (view->details->dir_action_group,
 
8141
                                              NAUTILUS_ACTION_LOCATION_OPEN_ALTERNATE);
 
8142
        gtk_action_set_visible (action, show_open_alternate);
 
8143
 
 
8144
        label = _("Open in New _Window");
 
8145
        g_object_set (action,
 
8146
                      "label", label,
 
8147
                      NULL);
 
8148
 
 
8149
        action = gtk_action_group_get_action (view->details->dir_action_group,
 
8150
                                              NAUTILUS_ACTION_LOCATION_OPEN_IN_NEW_TAB);
 
8151
        gtk_action_set_visible (action, show_open_in_new_tab);
 
8152
 
 
8153
        label = _("Open in New _Tab");
 
8154
        g_object_set (action,
 
8155
                      "label", label,
 
8156
                      NULL);
 
8157
 
 
8158
        file = view->details->location_popup_directory_as_file;
 
8159
        g_assert (NAUTILUS_IS_FILE (file));
 
8160
        g_assert (nautilus_file_check_if_ready (file, NAUTILUS_FILE_ATTRIBUTE_INFO |
 
8161
                                                NAUTILUS_FILE_ATTRIBUTE_MOUNT |
 
8162
                                                NAUTILUS_FILE_ATTRIBUTE_FILESYSTEM_INFO));
 
8163
 
 
8164
        is_special_link = NAUTILUS_IS_DESKTOP_ICON_FILE (file);
 
8165
        is_desktop_or_home_dir = nautilus_file_is_home (file)
 
8166
                || nautilus_file_is_desktop_directory (file);
 
8167
 
 
8168
        can_delete_file =
 
8169
                nautilus_file_can_delete (file) &&
 
8170
                !is_special_link &&
 
8171
                !is_desktop_or_home_dir;
 
8172
 
 
8173
        action = gtk_action_group_get_action (view->details->dir_action_group,
 
8174
                                              NAUTILUS_ACTION_LOCATION_CUT);
 
8175
        gtk_action_set_sensitive (action, can_delete_file);
 
8176
 
 
8177
        action = gtk_action_group_get_action (view->details->dir_action_group,
 
8178
                                              NAUTILUS_ACTION_LOCATION_PASTE_FILES_INTO);
 
8179
        g_object_set_data (G_OBJECT (action),
 
8180
                           "can-paste-according-to-destination",
 
8181
                           GINT_TO_POINTER (can_paste_into_file (file)));
 
8182
        gtk_action_set_sensitive (action,
 
8183
                                  GPOINTER_TO_INT (g_object_get_data (G_OBJECT (action),
 
8184
                                                                      "can-paste-according-to-clipboard")) &&
 
8185
                                  GPOINTER_TO_INT (g_object_get_data (G_OBJECT (action),
 
8186
                                                                      "can-paste-according-to-destination")));
 
8187
 
 
8188
        show_delete = TRUE;
 
8189
 
 
8190
        if (file != NULL &&
 
8191
            nautilus_file_is_in_trash (file)) {
 
8192
                if (nautilus_file_is_self_owned (file)) {
 
8193
                        show_delete = FALSE;
 
8194
                }
 
8195
 
 
8196
                label = _("_Delete Permanently");
 
8197
                tip = _("Delete the open folder permanently");
 
8198
                show_separate_delete_command = FALSE;
 
8199
        } else {
 
8200
                label = _("Mo_ve to Trash");
 
8201
                tip = _("Move the open folder to the Trash");
 
8202
                show_separate_delete_command = g_settings_get_boolean (nautilus_preferences, NAUTILUS_PREFERENCES_ENABLE_DELETE);
 
8203
        }
 
8204
 
 
8205
        action = gtk_action_group_get_action (view->details->dir_action_group,
 
8206
                                              NAUTILUS_ACTION_LOCATION_TRASH);
 
8207
        g_object_set (action,
 
8208
                      "label", label,
 
8209
                      "tooltip", tip,
 
8210
                      "icon-name", (file != NULL &&
 
8211
                                    nautilus_file_is_in_trash (file)) ?
 
8212
                      NAUTILUS_ICON_DELETE : NAUTILUS_ICON_TRASH_FULL,
 
8213
                      NULL);
 
8214
        gtk_action_set_sensitive (action, can_delete_file);
 
8215
        gtk_action_set_visible (action, show_delete);
 
8216
 
 
8217
        action = gtk_action_group_get_action (view->details->dir_action_group,
 
8218
                                              NAUTILUS_ACTION_LOCATION_DELETE);
 
8219
        gtk_action_set_visible (action, show_separate_delete_command);
 
8220
        if (show_separate_delete_command) {
 
8221
                gtk_action_set_sensitive (action, can_delete_file);
 
8222
                g_object_set (action,
 
8223
                              "icon-name", NAUTILUS_ICON_DELETE,
 
8224
                              "sensitive", can_delete_file,
 
8225
                              NULL);
 
8226
        }
 
8227
 
 
8228
        action = gtk_action_group_get_action (view->details->dir_action_group,
 
8229
                                              NAUTILUS_ACTION_LOCATION_RESTORE_FROM_TRASH);
 
8230
        l.prev = NULL;
 
8231
        l.next = NULL;
 
8232
        l.data = file;
 
8233
        update_restore_from_trash_action (action, &l, TRUE);
 
8234
 
 
8235
        real_update_location_menu_volumes (view);
 
8236
}
 
8237
 
 
8238
static void
 
8239
clipboard_changed_callback (NautilusClipboardMonitor *monitor, NautilusView *view)
 
8240
{
 
8241
        GList *selection;
 
8242
        gint selection_count;
 
8243
 
 
8244
        if (!view->details->active) {
 
8245
                return;
 
8246
        }
 
8247
 
 
8248
        selection = nautilus_view_get_selection (view);
 
8249
        selection_count = g_list_length (selection);
 
8250
 
 
8251
        real_update_paste_menu (view, selection, selection_count);
 
8252
 
 
8253
        nautilus_file_list_free (selection);
 
8254
        
 
8255
}
 
8256
 
 
8257
static gboolean
 
8258
can_delete_all (GList *files)
 
8259
{
 
8260
        NautilusFile *file;
 
8261
        GList *l;
 
8262
 
 
8263
        for (l = files; l != NULL; l = l->next) {
 
8264
                file = l->data;
 
8265
                if (!nautilus_file_can_delete (file)) {
 
8266
                        return FALSE;
 
8267
                }
 
8268
        }
 
8269
        return TRUE;
 
8270
}
 
8271
 
 
8272
static gboolean
 
8273
has_writable_extra_pane (NautilusView *view)
 
8274
{
 
8275
        NautilusView *other_view;
 
8276
 
 
8277
        other_view = get_directory_view_of_extra_pane (view);
 
8278
        if (other_view != NULL) {
 
8279
                return !nautilus_view_is_read_only (other_view);
 
8280
        }
 
8281
        return FALSE;
 
8282
}
 
8283
 
 
8284
static void
 
8285
real_update_menus (NautilusView *view)
 
8286
{
 
8287
        GList *selection, *l;
 
8288
        gint selection_count;
 
8289
        const char *tip, *label;
 
8290
        char *label_with_underscore;
 
8291
        gboolean selection_contains_special_link;
 
8292
        gboolean selection_contains_desktop_or_home_dir;
 
8293
        gboolean can_create_files;
 
8294
        gboolean can_delete_files;
 
8295
        gboolean can_copy_files;
 
8296
        gboolean can_link_files;
 
8297
        gboolean can_duplicate_files;
 
8298
        gboolean show_separate_delete_command;
 
8299
        gboolean vfolder_directory;
 
8300
        gboolean disable_command_line;
 
8301
        gboolean show_open_alternate;
 
8302
        gboolean show_open_in_new_tab;
 
8303
        gboolean can_open;
 
8304
        gboolean show_app;
 
8305
        gboolean show_save_search;
 
8306
        gboolean save_search_sensitive;
 
8307
        gboolean show_save_search_as;
 
8308
        gboolean show_desktop_target;
 
8309
        GtkAction *action;
 
8310
        GAppInfo *app;
 
8311
        GIcon *app_icon;
 
8312
        GtkWidget *menuitem;
 
8313
        gboolean next_pane_is_writable;
 
8314
        gboolean show_properties;
 
8315
 
 
8316
        selection = nautilus_view_get_selection (view);
 
8317
        selection_count = g_list_length (selection);
 
8318
 
 
8319
        selection_contains_special_link = special_link_in_selection (view);
 
8320
        selection_contains_desktop_or_home_dir = desktop_or_home_dir_in_selection (view);
 
8321
 
 
8322
        can_create_files = nautilus_view_supports_creating_files (view);
 
8323
        can_delete_files =
 
8324
                can_delete_all (selection) &&
 
8325
                selection_count != 0 &&
 
8326
                !selection_contains_special_link &&
 
8327
                !selection_contains_desktop_or_home_dir;
 
8328
        can_copy_files = selection_count != 0
 
8329
                && !selection_contains_special_link;    
 
8330
 
 
8331
        can_duplicate_files = can_create_files && can_copy_files;
 
8332
        can_link_files = can_create_files && can_copy_files;
 
8333
        
 
8334
        vfolder_directory = we_are_in_vfolder_desktop_dir (view);
 
8335
 
 
8336
        action = gtk_action_group_get_action (view->details->dir_action_group,
 
8337
                                              NAUTILUS_ACTION_RENAME);
 
8338
        /* rename sensitivity depending on selection */
 
8339
        if (selection_count > 1) {
 
8340
                /* If multiple files are selected, sensitivity depends on whether a bulk renamer is registered. */
 
8341
                gtk_action_set_sensitive (action, have_bulk_rename_tool ());
 
8342
        } else {
 
8343
                gtk_action_set_sensitive (action,
 
8344
                                          selection_count == 1 &&
 
8345
                                          nautilus_view_can_rename_file (view, selection->data));
 
8346
        }
 
8347
 
 
8348
        action = gtk_action_group_get_action (view->details->dir_action_group,
 
8349
                                              NAUTILUS_ACTION_NEW_FOLDER);
 
8350
        gtk_action_set_sensitive (action, can_create_files);
 
8351
 
 
8352
        action = gtk_action_group_get_action (view->details->dir_action_group,
 
8353
                                              NAUTILUS_ACTION_OPEN);
 
8354
        gtk_action_set_sensitive (action, selection_count != 0);
 
8355
        
 
8356
        can_open = show_app = selection_count != 0;
 
8357
 
 
8358
        for (l = selection; l != NULL; l = l->next) {
 
8359
                NautilusFile *file;
 
8360
 
 
8361
                file = NAUTILUS_FILE (selection->data);
 
8362
 
 
8363
                if (!nautilus_mime_file_opens_in_external_app (file)) {
 
8364
                        show_app = FALSE;
 
8365
                }
 
8366
 
 
8367
                if (!show_app) {
 
8368
                        break;
 
8369
                }
 
8370
        } 
 
8371
 
 
8372
        label_with_underscore = NULL;
 
8373
 
 
8374
        app = NULL;
 
8375
        app_icon = NULL;
 
8376
 
 
8377
        if (can_open && show_app) {
 
8378
                app = nautilus_mime_get_default_application_for_files (selection);
 
8379
        }
 
8380
 
 
8381
        if (app != NULL) {
 
8382
                char *escaped_app;
 
8383
 
 
8384
                escaped_app = eel_str_double_underscores (g_app_info_get_display_name (app));
 
8385
                label_with_underscore = g_strdup_printf (_("_Open With %s"),
 
8386
                                                         escaped_app);
 
8387
 
 
8388
                app_icon = g_app_info_get_icon (app);
 
8389
                if (app_icon != NULL) {
 
8390
                        g_object_ref (app_icon);
 
8391
                }
 
8392
 
 
8393
                g_free (escaped_app);
 
8394
                g_object_unref (app);
 
8395
        }
 
8396
 
 
8397
        g_object_set (action, "label", 
 
8398
                      label_with_underscore ? label_with_underscore : _("_Open"),
 
8399
                      NULL);
 
8400
 
 
8401
        menuitem = gtk_ui_manager_get_widget (
 
8402
                                              nautilus_window_get_ui_manager (view->details->window),
 
8403
                                              NAUTILUS_VIEW_MENU_PATH_OPEN);
 
8404
 
 
8405
        /* Only force displaying the icon if it is an application icon */
 
8406
        gtk_image_menu_item_set_always_show_image (
 
8407
                                                   GTK_IMAGE_MENU_ITEM (menuitem), app_icon != NULL);
 
8408
 
 
8409
        menuitem = gtk_ui_manager_get_widget (
 
8410
                                              nautilus_window_get_ui_manager (view->details->window),
 
8411
                                              NAUTILUS_VIEW_POPUP_PATH_OPEN);
 
8412
 
 
8413
        /* Only force displaying the icon if it is an application icon */
 
8414
        gtk_image_menu_item_set_always_show_image (
 
8415
                                                   GTK_IMAGE_MENU_ITEM (menuitem), app_icon != NULL);
 
8416
 
 
8417
        if (app_icon == NULL) {
 
8418
                app_icon = g_themed_icon_new (GTK_STOCK_OPEN);
 
8419
        }
 
8420
 
 
8421
        gtk_action_set_gicon (action, app_icon);
 
8422
        g_object_unref (app_icon);
 
8423
 
 
8424
        gtk_action_set_visible (action, can_open);
 
8425
        
 
8426
        g_free (label_with_underscore);
 
8427
 
 
8428
        show_open_alternate = file_list_all_are_folders (selection) &&
 
8429
                selection_count > 0 &&
 
8430
                g_settings_get_boolean (nautilus_preferences, NAUTILUS_PREFERENCES_ALWAYS_USE_BROWSER) &&
 
8431
                !(nautilus_window_get_window_type (view->details->window) == NAUTILUS_WINDOW_DESKTOP);
 
8432
 
 
8433
        action = gtk_action_group_get_action (view->details->dir_action_group,
 
8434
                                              NAUTILUS_ACTION_OPEN_ALTERNATE);
 
8435
 
 
8436
        gtk_action_set_sensitive (action,  selection_count != 0);
 
8437
        gtk_action_set_visible (action, show_open_alternate);
 
8438
 
 
8439
        if (selection_count == 0 || selection_count == 1) {
 
8440
                label_with_underscore = g_strdup (_("Open in New _Window"));
 
8441
        } else {
 
8442
                label_with_underscore = g_strdup_printf (ngettext("Open in %'d New _Window",
 
8443
                                                                  "Open in %'d New _Windows",
 
8444
                                                                  selection_count), 
 
8445
                                                         selection_count);
 
8446
        }
 
8447
 
 
8448
        g_object_set (action, "label", 
 
8449
                      label_with_underscore,
 
8450
                      NULL);
 
8451
        g_free (label_with_underscore);
 
8452
 
 
8453
        show_open_in_new_tab = show_open_alternate;
 
8454
        action = gtk_action_group_get_action (view->details->dir_action_group,
 
8455
                                              NAUTILUS_ACTION_OPEN_IN_NEW_TAB);
 
8456
        gtk_action_set_sensitive (action, selection_count != 0);
 
8457
        gtk_action_set_visible (action, show_open_in_new_tab);
 
8458
 
 
8459
        if (selection_count == 0 || selection_count == 1) {
 
8460
                label_with_underscore = g_strdup (_("Open in New _Tab"));
 
8461
        } else {
 
8462
                label_with_underscore = g_strdup_printf (ngettext("Open in %'d New _Tab",
 
8463
                                                                  "Open in %'d New _Tabs",
 
8464
                                                                  selection_count), 
 
8465
                                                         selection_count);
 
8466
        }
 
8467
 
 
8468
        g_object_set (action, "label", 
 
8469
                      label_with_underscore,
 
8470
                      NULL);
 
8471
        g_free (label_with_underscore);
 
8472
 
 
8473
        /* Broken into its own function just for convenience */
 
8474
        reset_open_with_menu (view, selection);
 
8475
        reset_extension_actions_menu (view, selection);
 
8476
 
 
8477
        if (all_selected_items_in_trash (view)) {
 
8478
                label = _("_Delete Permanently");
 
8479
                tip = _("Delete all selected items permanently");
 
8480
                show_separate_delete_command = FALSE;
 
8481
        } else {
 
8482
                label = _("Mo_ve to Trash");
 
8483
                tip = _("Move each selected item to the Trash");
 
8484
                show_separate_delete_command = g_settings_get_boolean (nautilus_preferences, NAUTILUS_PREFERENCES_ENABLE_DELETE);
 
8485
        }
 
8486
        
 
8487
        action = gtk_action_group_get_action (view->details->dir_action_group,
 
8488
                                              NAUTILUS_ACTION_TRASH);
 
8489
        g_object_set (action,
 
8490
                      "label", label,
 
8491
                      "tooltip", tip,
 
8492
                      "icon-name", all_selected_items_in_trash (view) ?
 
8493
                      NAUTILUS_ICON_DELETE : NAUTILUS_ICON_TRASH_FULL,
 
8494
                      NULL);
 
8495
        gtk_action_set_sensitive (action, can_delete_files);
 
8496
 
 
8497
        action = gtk_action_group_get_action (view->details->dir_action_group,
 
8498
                                              NAUTILUS_ACTION_DELETE);
 
8499
        gtk_action_set_visible (action, show_separate_delete_command);
 
8500
        
 
8501
        if (show_separate_delete_command) {
 
8502
                g_object_set (action,
 
8503
                              "label", _("_Delete"),
 
8504
                              "icon-name", NAUTILUS_ICON_DELETE,
 
8505
                              NULL);
 
8506
        }
 
8507
        gtk_action_set_sensitive (action, can_delete_files);
 
8508
 
 
8509
 
 
8510
        action = gtk_action_group_get_action (view->details->dir_action_group,
 
8511
                                              NAUTILUS_ACTION_RESTORE_FROM_TRASH);
 
8512
        update_restore_from_trash_action (action, selection, FALSE);
 
8513
        
 
8514
        action = gtk_action_group_get_action (view->details->dir_action_group,
 
8515
                                              NAUTILUS_ACTION_DUPLICATE);
 
8516
        gtk_action_set_sensitive (action, can_duplicate_files);
 
8517
 
 
8518
        action = gtk_action_group_get_action (view->details->dir_action_group,
 
8519
                                              NAUTILUS_ACTION_CREATE_LINK);
 
8520
        gtk_action_set_sensitive (action, can_link_files);
 
8521
        g_object_set (action, "label",
 
8522
                      ngettext ("Ma_ke Link",
 
8523
                                "Ma_ke Links",
 
8524
                                selection_count),
 
8525
                      NULL);
 
8526
        
 
8527
        show_properties = (!NAUTILUS_IS_DESKTOP_ICON_VIEW (view) || selection_count > 0);
 
8528
 
 
8529
        action = gtk_action_group_get_action (view->details->dir_action_group,
 
8530
                                              NAUTILUS_ACTION_PROPERTIES);
 
8531
 
 
8532
        gtk_action_set_sensitive (action, show_properties);
 
8533
 
 
8534
        if (selection_count == 0) {
 
8535
                gtk_action_set_tooltip (action, _("View or modify the properties of the open folder"));
 
8536
        } else {
 
8537
                gtk_action_set_tooltip (action, _("View or modify the properties of each selected item"));
 
8538
        }
 
8539
 
 
8540
        gtk_action_set_visible (action, show_properties);
 
8541
 
 
8542
        action = gtk_action_group_get_action (view->details->dir_action_group,
 
8543
                                              NAUTILUS_ACTION_PROPERTIES_ACCEL);
 
8544
 
 
8545
        gtk_action_set_sensitive (action, show_properties);
 
8546
 
 
8547
        action = gtk_action_group_get_action (view->details->dir_action_group,
 
8548
                                              NAUTILUS_ACTION_EMPTY_TRASH);
 
8549
        g_object_set (action,
 
8550
                      "label", _("E_mpty Trash"),
 
8551
                      NULL);
 
8552
        gtk_action_set_sensitive (action, !nautilus_trash_monitor_is_empty ());
 
8553
        gtk_action_set_visible (action, should_show_empty_trash (view));
 
8554
 
 
8555
        show_save_search = FALSE;
 
8556
        save_search_sensitive = FALSE;
 
8557
        show_save_search_as = FALSE;
 
8558
        if (view->details->model &&
 
8559
            NAUTILUS_IS_SEARCH_DIRECTORY (view->details->model)) {
 
8560
                NautilusSearchDirectory *search;
 
8561
 
 
8562
                search = NAUTILUS_SEARCH_DIRECTORY (view->details->model);
 
8563
                if (nautilus_search_directory_is_saved_search (search)) {
 
8564
                        show_save_search = TRUE;
 
8565
                        save_search_sensitive = nautilus_search_directory_is_modified (search);
 
8566
                } else {
 
8567
                        show_save_search_as = TRUE;
 
8568
                }
 
8569
        } 
 
8570
        action = gtk_action_group_get_action (view->details->dir_action_group,
 
8571
                                              NAUTILUS_ACTION_SAVE_SEARCH);
 
8572
        gtk_action_set_visible (action, show_save_search);
 
8573
        gtk_action_set_sensitive (action, save_search_sensitive);
 
8574
        action = gtk_action_group_get_action (view->details->dir_action_group,
 
8575
                                              NAUTILUS_ACTION_SAVE_SEARCH_AS);
 
8576
        gtk_action_set_visible (action, show_save_search_as);
 
8577
 
 
8578
 
 
8579
        action = gtk_action_group_get_action (view->details->dir_action_group,
 
8580
                                              NAUTILUS_ACTION_SELECT_ALL);
 
8581
        gtk_action_set_sensitive (action, !nautilus_view_is_empty (view));
 
8582
 
 
8583
        action = gtk_action_group_get_action (view->details->dir_action_group,
 
8584
                                              NAUTILUS_ACTION_SELECT_PATTERN);
 
8585
        gtk_action_set_sensitive (action, !nautilus_view_is_empty (view));
 
8586
 
 
8587
        action = gtk_action_group_get_action (view->details->dir_action_group,
 
8588
                                              NAUTILUS_ACTION_INVERT_SELECTION);
 
8589
        gtk_action_set_sensitive (action, !nautilus_view_is_empty (view));
 
8590
 
 
8591
        action = gtk_action_group_get_action (view->details->dir_action_group,
 
8592
                                              NAUTILUS_ACTION_CUT);
 
8593
        gtk_action_set_sensitive (action, can_delete_files);
 
8594
 
 
8595
        action = gtk_action_group_get_action (view->details->dir_action_group,
 
8596
                                              NAUTILUS_ACTION_COPY);
 
8597
        gtk_action_set_sensitive (action, can_copy_files);
 
8598
 
 
8599
        real_update_paste_menu (view, selection, selection_count);
 
8600
 
 
8601
        disable_command_line = g_settings_get_boolean (gnome_lockdown_preferences, NAUTILUS_PREFERENCES_LOCKDOWN_COMMAND_LINE);
 
8602
        action = gtk_action_group_get_action (view->details->dir_action_group,
 
8603
                                              NAUTILUS_ACTION_NEW_LAUNCHER);
 
8604
        gtk_action_set_visible (action, vfolder_directory && !disable_command_line);
 
8605
        gtk_action_set_sensitive (action, can_create_files);
 
8606
 
 
8607
        real_update_menus_volumes (view, selection, selection_count);
 
8608
 
 
8609
        nautilus_file_list_free (selection);
 
8610
 
 
8611
        if (view->details->scripts_invalid) {
 
8612
                update_scripts_menu (view);
 
8613
        }
 
8614
 
 
8615
        action = gtk_action_group_get_action (view->details->dir_action_group,
 
8616
                                              NAUTILUS_ACTION_NEW_DOCUMENTS);
 
8617
        gtk_action_set_sensitive (action, can_create_files);
 
8618
 
 
8619
        if (can_create_files && view->details->templates_invalid) {
 
8620
                update_templates_menu (view);
 
8621
        }
 
8622
 
 
8623
        next_pane_is_writable = has_writable_extra_pane (view);
 
8624
 
 
8625
        /* next pane: works if file is copyable, and next pane is writable */
 
8626
        action = gtk_action_group_get_action (view->details->dir_action_group,
 
8627
                                              NAUTILUS_ACTION_COPY_TO_NEXT_PANE);
 
8628
        gtk_action_set_sensitive (action, can_copy_files && next_pane_is_writable);
 
8629
 
 
8630
        /* move to next pane: works if file is cuttable, and next pane is writable */
 
8631
        action = gtk_action_group_get_action (view->details->dir_action_group,
 
8632
                                              NAUTILUS_ACTION_MOVE_TO_NEXT_PANE);
 
8633
        gtk_action_set_sensitive (action, can_delete_files && next_pane_is_writable);
 
8634
 
 
8635
 
 
8636
        show_desktop_target =
 
8637
                g_settings_get_boolean (gnome_background_preferences, NAUTILUS_PREFERENCES_SHOW_DESKTOP) &&
 
8638
                !g_settings_get_boolean (nautilus_preferences, NAUTILUS_PREFERENCES_DESKTOP_IS_HOME_DIR);
 
8639
 
 
8640
        action = gtk_action_group_get_action (view->details->dir_action_group,
 
8641
                                              NAUTILUS_ACTION_COPY_TO_HOME);
 
8642
        gtk_action_set_sensitive (action, can_copy_files);
 
8643
        action = gtk_action_group_get_action (view->details->dir_action_group,
 
8644
                                              NAUTILUS_ACTION_COPY_TO_DESKTOP);
 
8645
        gtk_action_set_sensitive (action, can_copy_files);
 
8646
        gtk_action_set_visible (action, show_desktop_target);
 
8647
 
 
8648
        action = gtk_action_group_get_action (view->details->dir_action_group,
 
8649
                                              NAUTILUS_ACTION_MOVE_TO_HOME);
 
8650
        gtk_action_set_sensitive (action, can_delete_files);
 
8651
        action = gtk_action_group_get_action (view->details->dir_action_group,
 
8652
                                              NAUTILUS_ACTION_MOVE_TO_DESKTOP);
 
8653
        gtk_action_set_sensitive (action, can_delete_files);
 
8654
        gtk_action_set_visible (action, show_desktop_target);
 
8655
 
 
8656
        action = gtk_action_group_get_action (view->details->dir_action_group,
 
8657
                                              "CopyToMenu");
 
8658
        gtk_action_set_sensitive (action, can_copy_files);
 
8659
        action = gtk_action_group_get_action (view->details->dir_action_group,
 
8660
                                              "MoveToMenu");
 
8661
        gtk_action_set_sensitive (action, can_delete_files);
 
8662
}
 
8663
 
 
8664
/**
 
8665
 * nautilus_view_pop_up_selection_context_menu
 
8666
 *
 
8667
 * Pop up a context menu appropriate to the selected items.
 
8668
 * @view: NautilusView of interest.
 
8669
 * @event: The event that triggered this context menu.
 
8670
 * 
 
8671
 * Return value: NautilusDirectory for this view.
 
8672
 * 
 
8673
 **/
 
8674
void 
 
8675
nautilus_view_pop_up_selection_context_menu  (NautilusView *view, 
 
8676
                                              GdkEventButton  *event)
 
8677
{
 
8678
        g_assert (NAUTILUS_IS_VIEW (view));
 
8679
 
 
8680
        /* Make the context menu items not flash as they update to proper disabled,
 
8681
         * etc. states by forcing menus to update now.
 
8682
         */
 
8683
        update_menus_if_pending (view);
 
8684
 
 
8685
        update_context_menu_position_from_event (view, event);
 
8686
 
 
8687
        eel_pop_up_context_menu (create_popup_menu 
 
8688
                                 (view, NAUTILUS_VIEW_POPUP_PATH_SELECTION),
 
8689
                                 EEL_DEFAULT_POPUP_MENU_DISPLACEMENT,
 
8690
                                 EEL_DEFAULT_POPUP_MENU_DISPLACEMENT,
 
8691
                                 event);
 
8692
}
 
8693
 
 
8694
/**
 
8695
 * nautilus_view_pop_up_background_context_menu
 
8696
 *
 
8697
 * Pop up a context menu appropriate to the view globally at the last right click location.
 
8698
 * @view: NautilusView of interest.
 
8699
 * 
 
8700
 * Return value: NautilusDirectory for this view.
 
8701
 * 
 
8702
 **/
 
8703
void 
 
8704
nautilus_view_pop_up_background_context_menu (NautilusView *view, 
 
8705
                                              GdkEventButton  *event)
 
8706
{
 
8707
        g_assert (NAUTILUS_IS_VIEW (view));
 
8708
 
 
8709
        /* Make the context menu items not flash as they update to proper disabled,
 
8710
         * etc. states by forcing menus to update now.
 
8711
         */
 
8712
        update_menus_if_pending (view);
 
8713
 
 
8714
        update_context_menu_position_from_event (view, event);
 
8715
 
 
8716
 
 
8717
        eel_pop_up_context_menu (create_popup_menu 
 
8718
                                 (view, NAUTILUS_VIEW_POPUP_PATH_BACKGROUND),
 
8719
                                 EEL_DEFAULT_POPUP_MENU_DISPLACEMENT,
 
8720
                                 EEL_DEFAULT_POPUP_MENU_DISPLACEMENT,
 
8721
                                 event);
 
8722
}
 
8723
 
 
8724
static void
 
8725
real_pop_up_location_context_menu (NautilusView *view)
 
8726
{
 
8727
        /* always update the menu before showing it. Shouldn't be too expensive. */
 
8728
        real_update_location_menu (view);
 
8729
 
 
8730
        update_context_menu_position_from_event (view, view->details->location_popup_event);
 
8731
 
 
8732
        eel_pop_up_context_menu (create_popup_menu 
 
8733
                                 (view, NAUTILUS_VIEW_POPUP_PATH_LOCATION),
 
8734
                                 EEL_DEFAULT_POPUP_MENU_DISPLACEMENT,
 
8735
                                 EEL_DEFAULT_POPUP_MENU_DISPLACEMENT,
 
8736
                                 view->details->location_popup_event);
 
8737
}
 
8738
 
 
8739
static void
 
8740
location_popup_file_attributes_ready (NautilusFile *file,
 
8741
                                      gpointer      data)
 
8742
{
 
8743
        NautilusView *view;
 
8744
 
 
8745
        view = NAUTILUS_VIEW (data);
 
8746
        g_assert (NAUTILUS_IS_VIEW (view));
 
8747
 
 
8748
        g_assert (file == view->details->location_popup_directory_as_file);
 
8749
 
 
8750
        real_pop_up_location_context_menu (view);
 
8751
}
 
8752
 
 
8753
static void
 
8754
unschedule_pop_up_location_context_menu (NautilusView *view)
 
8755
{
 
8756
        if (view->details->location_popup_directory_as_file != NULL) {
 
8757
                g_assert (NAUTILUS_IS_FILE (view->details->location_popup_directory_as_file));
 
8758
                nautilus_file_cancel_call_when_ready (view->details->location_popup_directory_as_file,
 
8759
                                                      location_popup_file_attributes_ready,
 
8760
                                                      view);
 
8761
                nautilus_file_unref (view->details->location_popup_directory_as_file);
 
8762
                view->details->location_popup_directory_as_file = NULL;
 
8763
        }
 
8764
}
 
8765
 
 
8766
static void
 
8767
schedule_pop_up_location_context_menu (NautilusView *view,
 
8768
                                       GdkEventButton  *event,
 
8769
                                       NautilusFile    *file)
 
8770
{
 
8771
        g_assert (NAUTILUS_IS_FILE (file));
 
8772
 
 
8773
        if (view->details->location_popup_event != NULL) {
 
8774
                gdk_event_free ((GdkEvent *) view->details->location_popup_event);
 
8775
        }
 
8776
        view->details->location_popup_event = (GdkEventButton *) gdk_event_copy ((GdkEvent *)event);
 
8777
 
 
8778
        if (file == view->details->location_popup_directory_as_file) {
 
8779
                if (nautilus_file_check_if_ready (file, NAUTILUS_FILE_ATTRIBUTE_INFO |
 
8780
                                                  NAUTILUS_FILE_ATTRIBUTE_MOUNT |
 
8781
                                                  NAUTILUS_FILE_ATTRIBUTE_FILESYSTEM_INFO)) {
 
8782
                        real_pop_up_location_context_menu (view);
 
8783
                }
 
8784
        } else {
 
8785
                unschedule_pop_up_location_context_menu (view);
 
8786
 
 
8787
                view->details->location_popup_directory_as_file = nautilus_file_ref (file);
 
8788
                nautilus_file_call_when_ready (view->details->location_popup_directory_as_file,
 
8789
                                               NAUTILUS_FILE_ATTRIBUTE_INFO |
 
8790
                                               NAUTILUS_FILE_ATTRIBUTE_MOUNT |
 
8791
                                               NAUTILUS_FILE_ATTRIBUTE_FILESYSTEM_INFO,
 
8792
                                               location_popup_file_attributes_ready,
 
8793
                                               view);
 
8794
        }
 
8795
}
 
8796
 
 
8797
/**
 
8798
 * nautilus_view_pop_up_location_context_menu
 
8799
 *
 
8800
 * Pop up a context menu appropriate to the view globally.
 
8801
 * @view: NautilusView of interest.
 
8802
 * @event: GdkEventButton triggering the popup.
 
8803
 * @location: The location the popup-menu should be created for,
 
8804
 * or NULL for the currently displayed location.
 
8805
 *
 
8806
 **/
 
8807
void 
 
8808
nautilus_view_pop_up_location_context_menu (NautilusView *view, 
 
8809
                                            GdkEventButton  *event,
 
8810
                                            const char      *location)
 
8811
{
 
8812
        NautilusFile *file;
 
8813
 
 
8814
        g_assert (NAUTILUS_IS_VIEW (view));
 
8815
 
 
8816
        if (location != NULL) {
 
8817
                file = nautilus_file_get_by_uri (location);
 
8818
        } else {
 
8819
                file = nautilus_file_ref (view->details->directory_as_file);
 
8820
        }
 
8821
 
 
8822
        if (file != NULL) {
 
8823
                schedule_pop_up_location_context_menu (view, event, file);
 
8824
                nautilus_file_unref (file);
 
8825
        }
 
8826
}
 
8827
 
 
8828
static void
 
8829
schedule_update_menus (NautilusView *view) 
 
8830
{
 
8831
        g_assert (NAUTILUS_IS_VIEW (view));
 
8832
 
 
8833
        /* Don't schedule updates after destroy (#349551),
 
8834
         * or if we are not active.
 
8835
         */
 
8836
        if (view->details->window == NULL ||
 
8837
            !view->details->active) {
 
8838
                return;
 
8839
        }
 
8840
        
 
8841
        view->details->menu_states_untrustworthy = TRUE;
 
8842
 
 
8843
        /* Schedule a menu update with the current update interval */
 
8844
        if (view->details->update_menus_timeout_id == 0) {
 
8845
                view->details->update_menus_timeout_id
 
8846
                        = g_timeout_add (view->details->update_interval, update_menus_timeout_callback, view);
 
8847
        }
 
8848
}
 
8849
 
 
8850
static void
 
8851
remove_update_status_idle_callback (NautilusView *view) 
 
8852
{
 
8853
        if (view->details->update_status_idle_id != 0) {
 
8854
                g_source_remove (view->details->update_status_idle_id);
 
8855
                view->details->update_status_idle_id = 0;
 
8856
        }
 
8857
}
 
8858
 
 
8859
static gboolean
 
8860
update_status_idle_callback (gpointer data)
 
8861
{
 
8862
        NautilusView *view;
 
8863
 
 
8864
        view = NAUTILUS_VIEW (data);
 
8865
        nautilus_view_display_selection_info (view);
 
8866
        view->details->update_status_idle_id = 0;
 
8867
        return FALSE;
 
8868
}
 
8869
 
 
8870
static void
 
8871
schedule_update_status (NautilusView *view) 
 
8872
{
 
8873
        g_assert (NAUTILUS_IS_VIEW (view));
 
8874
 
 
8875
        /* Make sure we haven't already destroyed it */
 
8876
        if (view->details->window == NULL) {
 
8877
                return;
 
8878
        }
 
8879
 
 
8880
        if (view->details->loading) {
 
8881
                /* Don't update status bar while loading the dir */
 
8882
                return;
 
8883
        }
 
8884
 
 
8885
        if (view->details->update_status_idle_id == 0) {
 
8886
                view->details->update_status_idle_id =
 
8887
                        g_idle_add_full (G_PRIORITY_DEFAULT_IDLE - 20,
 
8888
                                         update_status_idle_callback, view, NULL);
 
8889
        }
 
8890
}
 
8891
 
 
8892
/**
 
8893
 * nautilus_view_notify_selection_changed:
 
8894
 * 
 
8895
 * Notify this view that the selection has changed. This is normally
 
8896
 * called only by subclasses.
 
8897
 * @view: NautilusView whose selection has changed.
 
8898
 * 
 
8899
 **/
 
8900
void
 
8901
nautilus_view_notify_selection_changed (NautilusView *view)
 
8902
{
 
8903
        GtkWindow *window;
 
8904
        GList *selection;
 
8905
        
 
8906
        g_return_if_fail (NAUTILUS_IS_VIEW (view));
 
8907
 
 
8908
        selection = nautilus_view_get_selection (view);
 
8909
        window = nautilus_view_get_containing_window (view);
 
8910
        DEBUG_FILES (selection, "Selection changed in window %p", window);
 
8911
        nautilus_file_list_free (selection);
 
8912
 
 
8913
        view->details->selection_was_removed = FALSE;
 
8914
 
 
8915
        if (!view->details->selection_change_is_due_to_shell) {
 
8916
                view->details->send_selection_change_to_shell = TRUE;
 
8917
        }
 
8918
 
 
8919
        /* Schedule a display of the new selection. */
 
8920
        if (view->details->display_selection_idle_id == 0) {
 
8921
                view->details->display_selection_idle_id
 
8922
                        = g_idle_add (display_selection_info_idle_callback,
 
8923
                                      view);
 
8924
        }
 
8925
 
 
8926
        if (view->details->batching_selection_level != 0) {
 
8927
                view->details->selection_changed_while_batched = TRUE;
 
8928
        } else {
 
8929
                /* Here is the work we do only when we're not
 
8930
                 * batching selection changes. In other words, it's the slower
 
8931
                 * stuff that we don't want to slow down selection techniques
 
8932
                 * such as rubberband-selecting in icon view.
 
8933
                 */
 
8934
 
 
8935
                /* Schedule an update of menu item states to match selection */
 
8936
                schedule_update_menus (view);
 
8937
        }
 
8938
}
 
8939
 
 
8940
static void
 
8941
file_changed_callback (NautilusFile *file, gpointer callback_data)
 
8942
{
 
8943
        NautilusView *view = NAUTILUS_VIEW (callback_data);
 
8944
 
 
8945
        schedule_changes (view);
 
8946
 
 
8947
        schedule_update_menus (view);
 
8948
        schedule_update_status (view);
 
8949
}
 
8950
 
 
8951
/**
 
8952
 * load_directory:
 
8953
 * 
 
8954
 * Switch the displayed location to a new uri. If the uri is not valid,
 
8955
 * the location will not be switched; user feedback will be provided instead.
 
8956
 * @view: NautilusView whose location will be changed.
 
8957
 * @uri: A string representing the uri to switch to.
 
8958
 * 
 
8959
 **/
 
8960
static void
 
8961
load_directory (NautilusView *view,
 
8962
                NautilusDirectory *directory)
 
8963
{
 
8964
        NautilusDirectory *old_directory;
 
8965
        NautilusFile *old_file;
 
8966
        NautilusFileAttributes attributes;
 
8967
 
 
8968
        g_assert (NAUTILUS_IS_VIEW (view));
 
8969
        g_assert (NAUTILUS_IS_DIRECTORY (directory));
 
8970
 
 
8971
        nautilus_view_stop_loading (view);
 
8972
        g_signal_emit (view, signals[CLEAR], 0);
 
8973
 
 
8974
        view->details->loading = TRUE;
 
8975
 
 
8976
        /* Update menus when directory is empty, before going to new
 
8977
         * location, so they won't have any false lingering knowledge
 
8978
         * of old selection.
 
8979
         */
 
8980
        schedule_update_menus (view);
 
8981
        
 
8982
        while (view->details->subdirectory_list != NULL) {
 
8983
                nautilus_view_remove_subdirectory (view,
 
8984
                                                   view->details->subdirectory_list->data);
 
8985
        }
 
8986
 
 
8987
        disconnect_model_handlers (view);
 
8988
 
 
8989
        old_directory = view->details->model;
 
8990
        nautilus_directory_ref (directory);
 
8991
        view->details->model = directory;
 
8992
        nautilus_directory_unref (old_directory);
 
8993
 
 
8994
        old_file = view->details->directory_as_file;
 
8995
        view->details->directory_as_file =
 
8996
                nautilus_directory_get_corresponding_file (directory);
 
8997
        nautilus_file_unref (old_file);
 
8998
 
 
8999
        view->details->reported_load_error = FALSE;
 
9000
 
 
9001
        /* FIXME bugzilla.gnome.org 45062: In theory, we also need to monitor metadata here (as
 
9002
         * well as doing a call when ready), in case external forces
 
9003
         * change the directory's file metadata.
 
9004
         */
 
9005
        attributes = 
 
9006
                NAUTILUS_FILE_ATTRIBUTE_INFO |
 
9007
                NAUTILUS_FILE_ATTRIBUTE_MOUNT |
 
9008
                NAUTILUS_FILE_ATTRIBUTE_FILESYSTEM_INFO;
 
9009
        view->details->metadata_for_directory_as_file_pending = TRUE;
 
9010
        view->details->metadata_for_files_in_directory_pending = TRUE;
 
9011
        nautilus_file_call_when_ready
 
9012
                (view->details->directory_as_file,
 
9013
                 attributes,
 
9014
                 metadata_for_directory_as_file_ready_callback, view);
 
9015
        nautilus_directory_call_when_ready
 
9016
                (view->details->model,
 
9017
                 attributes,
 
9018
                 FALSE,
 
9019
                 metadata_for_files_in_directory_ready_callback, view);
 
9020
 
 
9021
        /* If capabilities change, then we need to update the menus
 
9022
         * because of New Folder, and relative emblems.
 
9023
         */
 
9024
        attributes = 
 
9025
                NAUTILUS_FILE_ATTRIBUTE_INFO |
 
9026
                NAUTILUS_FILE_ATTRIBUTE_FILESYSTEM_INFO;
 
9027
        nautilus_file_monitor_add (view->details->directory_as_file,
 
9028
                                   &view->details->directory_as_file,
 
9029
                                   attributes);
 
9030
 
 
9031
        view->details->file_changed_handler_id = g_signal_connect
 
9032
                (view->details->directory_as_file, "changed",
 
9033
                 G_CALLBACK (file_changed_callback), view);
 
9034
}
 
9035
 
 
9036
static void
 
9037
finish_loading (NautilusView *view)
 
9038
{
 
9039
        NautilusFileAttributes attributes;
 
9040
 
 
9041
        nautilus_window_report_load_underway (view->details->window,
 
9042
                                              NAUTILUS_VIEW (view));
 
9043
 
 
9044
        /* Tell interested parties that we've begun loading this directory now.
 
9045
         * Subclasses use this to know that the new metadata is now available.
 
9046
         */
 
9047
        g_signal_emit (view, signals[BEGIN_LOADING], 0);
 
9048
 
 
9049
        /* Assume we have now all information to show window */
 
9050
        nautilus_window_view_visible  (view->details->window, NAUTILUS_VIEW (view));
 
9051
 
 
9052
        if (nautilus_directory_are_all_files_seen (view->details->model)) {
 
9053
                /* Unschedule a pending update and schedule a new one with the minimal
 
9054
                 * update interval. This gives the view a short chance at gathering the
 
9055
                 * (cached) deep counts.
 
9056
                 */
 
9057
                unschedule_display_of_pending_files (view);
 
9058
                schedule_timeout_display_of_pending_files (view, UPDATE_INTERVAL_MIN);
 
9059
        }
 
9060
        
 
9061
        /* Start loading. */
 
9062
 
 
9063
        /* Connect handlers to learn about loading progress. */
 
9064
        view->details->done_loading_handler_id = g_signal_connect
 
9065
                (view->details->model, "done_loading",
 
9066
                 G_CALLBACK (done_loading_callback), view);
 
9067
        view->details->load_error_handler_id = g_signal_connect
 
9068
                (view->details->model, "load_error",
 
9069
                 G_CALLBACK (load_error_callback), view);
 
9070
 
 
9071
        /* Monitor the things needed to get the right icon. Also
 
9072
         * monitor a directory's item count because the "size"
 
9073
         * attribute is based on that, and the file's metadata
 
9074
         * and possible custom name.
 
9075
         */
 
9076
        attributes =
 
9077
                NAUTILUS_FILE_ATTRIBUTES_FOR_ICON |
 
9078
                NAUTILUS_FILE_ATTRIBUTE_DIRECTORY_ITEM_COUNT |
 
9079
                NAUTILUS_FILE_ATTRIBUTE_INFO |
 
9080
                NAUTILUS_FILE_ATTRIBUTE_LINK_INFO |
 
9081
                NAUTILUS_FILE_ATTRIBUTE_MOUNT |
 
9082
                NAUTILUS_FILE_ATTRIBUTE_EXTENSION_INFO;
 
9083
 
 
9084
        nautilus_directory_file_monitor_add (view->details->model,
 
9085
                                             &view->details->model,
 
9086
                                             view->details->show_hidden_files,
 
9087
                                             attributes,
 
9088
                                             files_added_callback, view);
 
9089
 
 
9090
        view->details->files_added_handler_id = g_signal_connect
 
9091
                (view->details->model, "files_added",
 
9092
                 G_CALLBACK (files_added_callback), view);
 
9093
        view->details->files_changed_handler_id = g_signal_connect
 
9094
                (view->details->model, "files_changed",
 
9095
                 G_CALLBACK (files_changed_callback), view);
 
9096
}
 
9097
 
 
9098
static void
 
9099
finish_loading_if_all_metadata_loaded (NautilusView *view)
 
9100
{
 
9101
        if (!view->details->metadata_for_directory_as_file_pending &&
 
9102
            !view->details->metadata_for_files_in_directory_pending) {
 
9103
                finish_loading (view);
 
9104
        }
 
9105
}
 
9106
 
 
9107
static void
 
9108
metadata_for_directory_as_file_ready_callback (NautilusFile *file,
 
9109
                                               gpointer callback_data)
 
9110
{
 
9111
        NautilusView *view;
 
9112
 
 
9113
        view = callback_data;
 
9114
 
 
9115
        g_assert (NAUTILUS_IS_VIEW (view));
 
9116
        g_assert (view->details->directory_as_file == file);
 
9117
        g_assert (view->details->metadata_for_directory_as_file_pending);
 
9118
 
 
9119
        view->details->metadata_for_directory_as_file_pending = FALSE;
 
9120
        
 
9121
        finish_loading_if_all_metadata_loaded (view);
 
9122
}
 
9123
 
 
9124
static void
 
9125
metadata_for_files_in_directory_ready_callback (NautilusDirectory *directory,
 
9126
                                                GList *files,
 
9127
                                                gpointer callback_data)
 
9128
{
 
9129
        NautilusView *view;
 
9130
 
 
9131
        view = callback_data;
 
9132
 
 
9133
        g_assert (NAUTILUS_IS_VIEW (view));
 
9134
        g_assert (view->details->model == directory);
 
9135
        g_assert (view->details->metadata_for_files_in_directory_pending);
 
9136
 
 
9137
        view->details->metadata_for_files_in_directory_pending = FALSE;
 
9138
        
 
9139
        finish_loading_if_all_metadata_loaded (view);
 
9140
}
 
9141
 
 
9142
static void
 
9143
disconnect_handler (GObject *object, int *id)
 
9144
{
 
9145
        if (*id != 0) {
 
9146
                g_signal_handler_disconnect (object, *id);
 
9147
                *id = 0;
 
9148
        }
 
9149
}
 
9150
 
 
9151
static void
 
9152
disconnect_directory_handler (NautilusView *view, int *id)
 
9153
{
 
9154
        disconnect_handler (G_OBJECT (view->details->model), id);
 
9155
}
 
9156
 
 
9157
static void
 
9158
disconnect_directory_as_file_handler (NautilusView *view, int *id)
 
9159
{
 
9160
        disconnect_handler (G_OBJECT (view->details->directory_as_file), id);
 
9161
}
 
9162
 
 
9163
static void
 
9164
disconnect_model_handlers (NautilusView *view)
 
9165
{
 
9166
        if (view->details->model == NULL) {
 
9167
                return;
 
9168
        }
 
9169
        disconnect_directory_handler (view, &view->details->files_added_handler_id);
 
9170
        disconnect_directory_handler (view, &view->details->files_changed_handler_id);
 
9171
        disconnect_directory_handler (view, &view->details->done_loading_handler_id);
 
9172
        disconnect_directory_handler (view, &view->details->load_error_handler_id);
 
9173
        disconnect_directory_as_file_handler (view, &view->details->file_changed_handler_id);
 
9174
        nautilus_file_cancel_call_when_ready (view->details->directory_as_file,
 
9175
                                              metadata_for_directory_as_file_ready_callback,
 
9176
                                              view);
 
9177
        nautilus_directory_cancel_callback (view->details->model,
 
9178
                                            metadata_for_files_in_directory_ready_callback,
 
9179
                                            view);
 
9180
        nautilus_directory_file_monitor_remove (view->details->model,
 
9181
                                                &view->details->model);
 
9182
        nautilus_file_monitor_remove (view->details->directory_as_file,
 
9183
                                      &view->details->directory_as_file);
 
9184
}
 
9185
 
 
9186
static void
 
9187
nautilus_view_select_file (NautilusView *view, NautilusFile *file)
 
9188
{
 
9189
        GList file_list;
 
9190
 
 
9191
        file_list.data = file;
 
9192
        file_list.next = NULL;
 
9193
        file_list.prev = NULL;
 
9194
        nautilus_view_call_set_selection (view, &file_list);
 
9195
}
 
9196
 
 
9197
static gboolean
 
9198
remove_all (gpointer key, gpointer value, gpointer callback_data)
 
9199
{
 
9200
        return TRUE;
 
9201
}
 
9202
 
 
9203
/**
 
9204
 * nautilus_view_stop_loading:
 
9205
 * 
 
9206
 * Stop the current ongoing process, such as switching to a new uri.
 
9207
 * @view: NautilusView in question.
 
9208
 * 
 
9209
 **/
 
9210
void
 
9211
nautilus_view_stop_loading (NautilusView *view)
 
9212
{
 
9213
        g_return_if_fail (NAUTILUS_IS_VIEW (view));
 
9214
 
 
9215
        unschedule_display_of_pending_files (view);
 
9216
        reset_update_interval (view);
 
9217
 
 
9218
        /* Free extra undisplayed files */
 
9219
        file_and_directory_list_free (view->details->new_added_files);
 
9220
        view->details->new_added_files = NULL;
 
9221
 
 
9222
        file_and_directory_list_free (view->details->new_changed_files);
 
9223
        view->details->new_changed_files = NULL;
 
9224
 
 
9225
        g_hash_table_foreach_remove (view->details->non_ready_files, remove_all, NULL);
 
9226
 
 
9227
        file_and_directory_list_free (view->details->old_added_files);
 
9228
        view->details->old_added_files = NULL;
 
9229
 
 
9230
        file_and_directory_list_free (view->details->old_changed_files);
 
9231
        view->details->old_changed_files = NULL;
 
9232
 
 
9233
        g_list_free_full (view->details->pending_selection, g_object_unref);
 
9234
        view->details->pending_selection = NULL;
 
9235
 
 
9236
        if (view->details->model != NULL) {
 
9237
                nautilus_directory_file_monitor_remove (view->details->model, view);
 
9238
        }
 
9239
        done_loading (view, FALSE);
 
9240
}
 
9241
 
 
9242
gboolean
 
9243
nautilus_view_is_editable (NautilusView *view)
 
9244
{
 
9245
        NautilusDirectory *directory;
 
9246
 
 
9247
        directory = nautilus_view_get_model (view);
 
9248
 
 
9249
        if (directory != NULL) {
 
9250
                return nautilus_directory_is_editable (directory);
 
9251
        }
 
9252
 
 
9253
        return TRUE;
 
9254
}
 
9255
 
 
9256
static gboolean
 
9257
real_is_read_only (NautilusView *view)
 
9258
{
 
9259
        NautilusFile *file;
 
9260
        
 
9261
        if (!nautilus_view_is_editable (view)) {
 
9262
                return TRUE;
 
9263
        }
 
9264
        
 
9265
        file = nautilus_view_get_directory_as_file (view);
 
9266
        if (file != NULL) {
 
9267
                return !nautilus_file_can_write (file);
 
9268
        }
 
9269
        return FALSE;
 
9270
}
 
9271
 
 
9272
/**
 
9273
 * nautilus_view_should_show_file
 
9274
 * 
 
9275
 * Returns whether or not this file should be displayed based on
 
9276
 * current filtering options.
 
9277
 */
 
9278
gboolean
 
9279
nautilus_view_should_show_file (NautilusView *view, NautilusFile *file)
 
9280
{
 
9281
        return nautilus_file_should_show (file,
 
9282
                                          view->details->show_hidden_files,
 
9283
                                          view->details->show_foreign_files);
 
9284
}
 
9285
 
 
9286
static gboolean
 
9287
real_using_manual_layout (NautilusView *view)
 
9288
{
 
9289
        g_return_val_if_fail (NAUTILUS_IS_VIEW (view), FALSE);
 
9290
 
 
9291
        return FALSE;
 
9292
}
 
9293
 
 
9294
static void
 
9295
schedule_update_menus_callback (gpointer callback_data)
 
9296
{
 
9297
        schedule_update_menus (NAUTILUS_VIEW (callback_data));
 
9298
}
 
9299
 
 
9300
void
 
9301
nautilus_view_ignore_hidden_file_preferences (NautilusView *view)
 
9302
{
 
9303
        g_return_if_fail (view->details->model == NULL);
 
9304
 
 
9305
        if (view->details->ignore_hidden_file_preferences) {
 
9306
                return;
 
9307
        }
 
9308
 
 
9309
        view->details->show_hidden_files = FALSE;
 
9310
        view->details->ignore_hidden_file_preferences = TRUE;
 
9311
}
 
9312
 
 
9313
void
 
9314
nautilus_view_set_show_foreign (NautilusView *view,
 
9315
                                gboolean show_foreign)
 
9316
{
 
9317
        view->details->show_foreign_files = show_foreign;
 
9318
}
 
9319
 
 
9320
char *
 
9321
nautilus_view_get_uri (NautilusView *view)
 
9322
{
 
9323
        g_return_val_if_fail (NAUTILUS_IS_VIEW (view), NULL);
 
9324
        if (view->details->model == NULL) {
 
9325
                return NULL;
 
9326
        }
 
9327
        return nautilus_directory_get_uri (view->details->model);
 
9328
}
 
9329
 
 
9330
void
 
9331
nautilus_view_move_copy_items (NautilusView *view,
 
9332
                               const GList *item_uris,
 
9333
                               GArray *relative_item_points,
 
9334
                               const char *target_uri,
 
9335
                               int copy_action,
 
9336
                               int x, int y)
 
9337
{
 
9338
        NautilusFile *target_file;
 
9339
        
 
9340
        g_assert (relative_item_points == NULL
 
9341
                  || relative_item_points->len == 0 
 
9342
                  || g_list_length ((GList *)item_uris) == relative_item_points->len);
 
9343
 
 
9344
        /* add the drop location to the icon offsets */
 
9345
        offset_drop_points (relative_item_points, x, y);
 
9346
 
 
9347
        target_file = nautilus_file_get_existing_by_uri (target_uri);
 
9348
        /* special-case "command:" here instead of starting a move/copy */
 
9349
        if (target_file != NULL && nautilus_file_is_launcher (target_file)) {
 
9350
                nautilus_file_unref (target_file);
 
9351
                nautilus_launch_desktop_file (
 
9352
                                              gtk_widget_get_screen (GTK_WIDGET (view)),
 
9353
                                              target_uri, item_uris,
 
9354
                                              nautilus_view_get_containing_window (view));
 
9355
                return;
 
9356
        } else if (copy_action == GDK_ACTION_COPY &&
 
9357
                   nautilus_is_file_roller_installed () &&
 
9358
                   target_file != NULL &&
 
9359
                   nautilus_file_is_archive (target_file)) {
 
9360
                char *command, *quoted_uri, *tmp;
 
9361
                const GList *l;
 
9362
                GdkScreen  *screen;
 
9363
 
 
9364
                /* Handle dropping onto a file-roller archiver file, instead of starting a move/copy */
 
9365
 
 
9366
                nautilus_file_unref (target_file);
 
9367
 
 
9368
                quoted_uri = g_shell_quote (target_uri);
 
9369
                command = g_strconcat ("file-roller -a ", quoted_uri, NULL);
 
9370
                g_free (quoted_uri);
 
9371
 
 
9372
                for (l = item_uris; l != NULL; l = l->next) {
 
9373
                        quoted_uri = g_shell_quote ((char *) l->data);
 
9374
 
 
9375
                        tmp = g_strconcat (command, " ", quoted_uri, NULL);
 
9376
                        g_free (command);
 
9377
                        command = tmp;
 
9378
 
 
9379
                        g_free (quoted_uri);
 
9380
                } 
 
9381
 
 
9382
                screen = gtk_widget_get_screen (GTK_WIDGET (view));
 
9383
                if (screen == NULL) {
 
9384
                        screen = gdk_screen_get_default ();
 
9385
                }
 
9386
 
 
9387
                nautilus_launch_application_from_command (screen, command, FALSE, NULL);
 
9388
                g_free (command);
 
9389
 
 
9390
                return;
 
9391
        }
 
9392
        nautilus_file_unref (target_file);
 
9393
 
 
9394
        nautilus_file_operations_copy_move
 
9395
                (item_uris, relative_item_points, 
 
9396
                 target_uri, copy_action, GTK_WIDGET (view),
 
9397
                 copy_move_done_callback, pre_copy_move (view));
 
9398
}
 
9399
 
 
9400
static void
 
9401
nautilus_view_trash_state_changed_callback (NautilusTrashMonitor *trash_monitor,
 
9402
                                            gboolean state, gpointer callback_data)
 
9403
{
 
9404
        NautilusView *view;
 
9405
 
 
9406
        view = (NautilusView *) callback_data;
 
9407
        g_assert (NAUTILUS_IS_VIEW (view));
 
9408
        
 
9409
        schedule_update_menus (view);
 
9410
}
 
9411
 
 
9412
void
 
9413
nautilus_view_start_batching_selection_changes (NautilusView *view)
 
9414
{
 
9415
        g_return_if_fail (NAUTILUS_IS_VIEW (view));
 
9416
 
 
9417
        ++view->details->batching_selection_level;
 
9418
        view->details->selection_changed_while_batched = FALSE;
 
9419
}
 
9420
 
 
9421
void
 
9422
nautilus_view_stop_batching_selection_changes (NautilusView *view)
 
9423
{
 
9424
        g_return_if_fail (NAUTILUS_IS_VIEW (view));
 
9425
        g_return_if_fail (view->details->batching_selection_level > 0);
 
9426
 
 
9427
        if (--view->details->batching_selection_level == 0) {
 
9428
                if (view->details->selection_changed_while_batched) {
 
9429
                        nautilus_view_notify_selection_changed (view);
 
9430
                }
 
9431
        }
 
9432
}
 
9433
 
 
9434
gboolean
 
9435
nautilus_view_get_active (NautilusView *view)
 
9436
{
 
9437
        g_assert (NAUTILUS_IS_VIEW (view));
 
9438
        return view->details->active;
 
9439
}
 
9440
 
 
9441
static GArray *
 
9442
real_get_selected_icon_locations (NautilusView *view)
 
9443
{
 
9444
        /* By default, just return an empty list. */
 
9445
        return g_array_new (FALSE, TRUE, sizeof (GdkPoint));
 
9446
}
 
9447
 
 
9448
static void
 
9449
nautilus_view_set_property (GObject         *object,
 
9450
                            guint            prop_id,
 
9451
                            const GValue    *value,
 
9452
                            GParamSpec      *pspec)
 
9453
{
 
9454
        NautilusView *directory_view;
 
9455
        NautilusWindowSlot *slot;
 
9456
        NautilusWindow *window;
 
9457
  
 
9458
        directory_view = NAUTILUS_VIEW (object);
 
9459
 
 
9460
        switch (prop_id)  {
 
9461
        case PROP_WINDOW_SLOT:
 
9462
                g_assert (directory_view->details->slot == NULL);
 
9463
 
 
9464
                slot = NAUTILUS_WINDOW_SLOT (g_value_get_object (value));
 
9465
                window = nautilus_window_slot_get_window (slot);
 
9466
 
 
9467
                directory_view->details->slot = slot;
 
9468
                directory_view->details->window = window;
 
9469
 
 
9470
                g_signal_connect_object (directory_view->details->slot,
 
9471
                                         "active", G_CALLBACK (slot_active),
 
9472
                                         directory_view, 0);
 
9473
                g_signal_connect_object (directory_view->details->slot,
 
9474
                                         "inactive", G_CALLBACK (slot_inactive),
 
9475
                                         directory_view, 0);
 
9476
 
 
9477
                g_signal_connect_object (directory_view->details->window,
 
9478
                                         "hidden-files-mode-changed", G_CALLBACK (hidden_files_mode_changed),
 
9479
                                         directory_view, 0);
 
9480
                nautilus_view_init_show_hidden_files (directory_view);
 
9481
                break;
 
9482
        case PROP_SUPPORTS_ZOOMING:
 
9483
                directory_view->details->supports_zooming = g_value_get_boolean (value);
 
9484
                break;
 
9485
        default:
 
9486
                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 
9487
                break;
 
9488
        }
 
9489
}
 
9490
 
 
9491
 
 
9492
gboolean
 
9493
nautilus_view_handle_scroll_event (NautilusView *directory_view,
 
9494
                                   GdkEventScroll *event)
 
9495
{
 
9496
        if (event->state & GDK_CONTROL_MASK) {
 
9497
                switch (event->direction) {
 
9498
                case GDK_SCROLL_UP:
 
9499
                        /* Zoom In */
 
9500
                        nautilus_view_bump_zoom_level (directory_view, 1);
 
9501
                        return TRUE;
 
9502
 
 
9503
                case GDK_SCROLL_DOWN:
 
9504
                        /* Zoom Out */
 
9505
                        nautilus_view_bump_zoom_level (directory_view, -1);
 
9506
                        return TRUE;
 
9507
 
 
9508
                case GDK_SCROLL_LEFT:
 
9509
                case GDK_SCROLL_RIGHT:
 
9510
                        break;
 
9511
 
 
9512
                default:
 
9513
                        g_assert_not_reached ();
 
9514
                }
 
9515
        }
 
9516
 
 
9517
        return FALSE;
 
9518
}
 
9519
 
 
9520
/* handle Shift+Scroll, which will cause a zoom-in/out */
 
9521
static gboolean
 
9522
nautilus_view_scroll_event (GtkWidget *widget,
 
9523
                            GdkEventScroll *event)
 
9524
{
 
9525
        NautilusView *directory_view;
 
9526
 
 
9527
        directory_view = NAUTILUS_VIEW (widget);
 
9528
        if (nautilus_view_handle_scroll_event (directory_view, event)) {
 
9529
                return TRUE;
 
9530
        }
 
9531
 
 
9532
        return GTK_WIDGET_CLASS (parent_class)->scroll_event (widget, event);
 
9533
}
 
9534
 
 
9535
 
 
9536
static void
 
9537
nautilus_view_parent_set (GtkWidget *widget,
 
9538
                          GtkWidget *old_parent)
 
9539
{
 
9540
        NautilusView *view;
 
9541
        GtkWidget *parent;
 
9542
 
 
9543
        view = NAUTILUS_VIEW (widget);
 
9544
 
 
9545
        parent = gtk_widget_get_parent (widget);
 
9546
        g_assert (parent == NULL || old_parent == NULL);
 
9547
 
 
9548
        if (GTK_WIDGET_CLASS (parent_class)->parent_set != NULL) {
 
9549
                GTK_WIDGET_CLASS (parent_class)->parent_set (widget, old_parent);
 
9550
        }
 
9551
 
 
9552
        if (parent != NULL) {
 
9553
                g_assert (old_parent == NULL);
 
9554
 
 
9555
                if (view->details->slot == 
 
9556
                    nautilus_window_get_active_slot (view->details->window)) {
 
9557
                        view->details->active = TRUE;
 
9558
 
 
9559
                        nautilus_view_merge_menus (view);
 
9560
                        schedule_update_menus (view);
 
9561
                }
 
9562
        } else {
 
9563
                nautilus_view_unmerge_menus (view);
 
9564
                remove_update_menus_timeout_callback (view);
 
9565
        }
 
9566
}
 
9567
 
 
9568
static void
 
9569
nautilus_view_class_init (NautilusViewClass *klass)
 
9570
{
 
9571
        GObjectClass *oclass;
 
9572
        GtkWidgetClass *widget_class;
 
9573
        GtkScrolledWindowClass *scrolled_window_class;
 
9574
        GtkBindingSet *binding_set;
 
9575
 
 
9576
        widget_class = GTK_WIDGET_CLASS (klass);
 
9577
        scrolled_window_class = GTK_SCROLLED_WINDOW_CLASS (klass);
 
9578
        oclass = G_OBJECT_CLASS (klass);
 
9579
 
 
9580
        oclass->finalize = nautilus_view_finalize;
 
9581
        oclass->set_property = nautilus_view_set_property;
 
9582
 
 
9583
        widget_class->destroy = nautilus_view_destroy;
 
9584
        widget_class->scroll_event = nautilus_view_scroll_event;
 
9585
        widget_class->parent_set = nautilus_view_parent_set;
 
9586
 
 
9587
        /* Get rid of the strange 3-pixel gap that GtkScrolledWindow
 
9588
         * uses by default. It does us no good.
 
9589
         */
 
9590
        scrolled_window_class->scrollbar_spacing = 0;
 
9591
 
 
9592
        signals[ADD_FILE] =
 
9593
                g_signal_new ("add_file",
 
9594
                              G_TYPE_FROM_CLASS (klass),
 
9595
                              G_SIGNAL_RUN_LAST,
 
9596
                              G_STRUCT_OFFSET (NautilusViewClass, add_file),
 
9597
                              NULL, NULL,
 
9598
                              g_cclosure_marshal_generic,
 
9599
                              G_TYPE_NONE, 2, NAUTILUS_TYPE_FILE, NAUTILUS_TYPE_DIRECTORY);
 
9600
        signals[BEGIN_FILE_CHANGES] =
 
9601
                g_signal_new ("begin_file_changes",
 
9602
                              G_TYPE_FROM_CLASS (klass),
 
9603
                              G_SIGNAL_RUN_LAST,
 
9604
                              G_STRUCT_OFFSET (NautilusViewClass, begin_file_changes),
 
9605
                              NULL, NULL,
 
9606
                              g_cclosure_marshal_VOID__VOID,
 
9607
                              G_TYPE_NONE, 0);
 
9608
        signals[BEGIN_LOADING] =
 
9609
                g_signal_new ("begin_loading",
 
9610
                              G_TYPE_FROM_CLASS (klass),
 
9611
                              G_SIGNAL_RUN_LAST,
 
9612
                              G_STRUCT_OFFSET (NautilusViewClass, begin_loading),
 
9613
                              NULL, NULL,
 
9614
                              g_cclosure_marshal_VOID__VOID,
 
9615
                              G_TYPE_NONE, 0);
 
9616
        signals[CLEAR] =
 
9617
                g_signal_new ("clear",
 
9618
                              G_TYPE_FROM_CLASS (klass),
 
9619
                              G_SIGNAL_RUN_LAST,
 
9620
                              G_STRUCT_OFFSET (NautilusViewClass, clear),
 
9621
                              NULL, NULL,
 
9622
                              g_cclosure_marshal_VOID__VOID,
 
9623
                              G_TYPE_NONE, 0);
 
9624
        signals[END_FILE_CHANGES] =
 
9625
                g_signal_new ("end_file_changes",
 
9626
                              G_TYPE_FROM_CLASS (klass),
 
9627
                              G_SIGNAL_RUN_LAST,
 
9628
                              G_STRUCT_OFFSET (NautilusViewClass, end_file_changes),
 
9629
                              NULL, NULL,
 
9630
                              g_cclosure_marshal_VOID__VOID,
 
9631
                              G_TYPE_NONE, 0);
 
9632
        signals[END_LOADING] =
 
9633
                g_signal_new ("end_loading",
 
9634
                              G_TYPE_FROM_CLASS (klass),
 
9635
                              G_SIGNAL_RUN_LAST,
 
9636
                              G_STRUCT_OFFSET (NautilusViewClass, end_loading),
 
9637
                              NULL, NULL,
 
9638
                              g_cclosure_marshal_VOID__BOOLEAN,
 
9639
                              G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
 
9640
        signals[FILE_CHANGED] =
 
9641
                g_signal_new ("file_changed",
 
9642
                              G_TYPE_FROM_CLASS (klass),
 
9643
                              G_SIGNAL_RUN_LAST,
 
9644
                              G_STRUCT_OFFSET (NautilusViewClass, file_changed),
 
9645
                              NULL, NULL,
 
9646
                              g_cclosure_marshal_generic,
 
9647
                              G_TYPE_NONE, 2, NAUTILUS_TYPE_FILE, NAUTILUS_TYPE_DIRECTORY);
 
9648
        signals[LOAD_ERROR] =
 
9649
                g_signal_new ("load_error",
 
9650
                              G_TYPE_FROM_CLASS (klass),
 
9651
                              G_SIGNAL_RUN_LAST,
 
9652
                              G_STRUCT_OFFSET (NautilusViewClass, load_error),
 
9653
                              NULL, NULL,
 
9654
                              g_cclosure_marshal_VOID__POINTER,
 
9655
                              G_TYPE_NONE, 1, G_TYPE_POINTER);
 
9656
        signals[REMOVE_FILE] =
 
9657
                g_signal_new ("remove_file",
 
9658
                              G_TYPE_FROM_CLASS (klass),
 
9659
                              G_SIGNAL_RUN_LAST,
 
9660
                              G_STRUCT_OFFSET (NautilusViewClass, remove_file),
 
9661
                              NULL, NULL,
 
9662
                              g_cclosure_marshal_generic,
 
9663
                              G_TYPE_NONE, 2, NAUTILUS_TYPE_FILE, NAUTILUS_TYPE_DIRECTORY);
 
9664
        signals[ZOOM_LEVEL_CHANGED] =
 
9665
                g_signal_new ("zoom-level-changed",
 
9666
                              G_TYPE_FROM_CLASS (klass),
 
9667
                              G_SIGNAL_RUN_LAST,
 
9668
                              0, NULL, NULL,
 
9669
                              g_cclosure_marshal_VOID__VOID,
 
9670
                              G_TYPE_NONE, 0);
 
9671
        signals[SELECTION_CHANGED] =
 
9672
                g_signal_new ("selection-changed",
 
9673
                              G_TYPE_FROM_CLASS (klass),
 
9674
                              G_SIGNAL_RUN_LAST,
 
9675
                              0,
 
9676
                              NULL, NULL,
 
9677
                              g_cclosure_marshal_VOID__VOID,
 
9678
                              G_TYPE_NONE, 0);
 
9679
        signals[TRASH] =
 
9680
                g_signal_new ("trash",
 
9681
                              G_TYPE_FROM_CLASS (klass),
 
9682
                              G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
 
9683
                              G_STRUCT_OFFSET (NautilusViewClass, trash),
 
9684
                              g_signal_accumulator_true_handled, NULL,
 
9685
                              g_cclosure_marshal_generic,
 
9686
                              G_TYPE_BOOLEAN, 0);
 
9687
        signals[DELETE] =
 
9688
                g_signal_new ("delete",
 
9689
                              G_TYPE_FROM_CLASS (klass),
 
9690
                              G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
 
9691
                              G_STRUCT_OFFSET (NautilusViewClass, delete),
 
9692
                              g_signal_accumulator_true_handled, NULL,
 
9693
                              g_cclosure_marshal_generic,
 
9694
                              G_TYPE_BOOLEAN, 0);
 
9695
 
 
9696
        klass->get_selected_icon_locations = real_get_selected_icon_locations;
 
9697
        klass->is_read_only = real_is_read_only;
 
9698
        klass->load_error = real_load_error;
 
9699
        klass->can_rename_file = can_rename_file;
 
9700
        klass->start_renaming_file = start_renaming_file;
 
9701
        klass->get_backing_uri = real_get_backing_uri;
 
9702
        klass->using_manual_layout = real_using_manual_layout;
 
9703
        klass->merge_menus = real_merge_menus;
 
9704
        klass->unmerge_menus = real_unmerge_menus;
 
9705
        klass->update_menus = real_update_menus;
 
9706
        klass->trash = real_trash;
 
9707
        klass->delete = real_delete;
 
9708
 
 
9709
        /* Function pointers that subclasses must override */
 
9710
        EEL_ASSIGN_MUST_OVERRIDE_SIGNAL (klass, nautilus_view, add_file);
 
9711
        EEL_ASSIGN_MUST_OVERRIDE_SIGNAL (klass, nautilus_view, bump_zoom_level);
 
9712
        EEL_ASSIGN_MUST_OVERRIDE_SIGNAL (klass, nautilus_view, can_zoom_in);
 
9713
        EEL_ASSIGN_MUST_OVERRIDE_SIGNAL (klass, nautilus_view, can_zoom_out);
 
9714
        EEL_ASSIGN_MUST_OVERRIDE_SIGNAL (klass, nautilus_view, clear);
 
9715
        EEL_ASSIGN_MUST_OVERRIDE_SIGNAL (klass, nautilus_view, file_changed);
 
9716
        EEL_ASSIGN_MUST_OVERRIDE_SIGNAL (klass, nautilus_view, get_selection);
 
9717
        EEL_ASSIGN_MUST_OVERRIDE_SIGNAL (klass, nautilus_view, get_selection_for_file_transfer);
 
9718
        EEL_ASSIGN_MUST_OVERRIDE_SIGNAL (klass, nautilus_view, get_item_count);
 
9719
        EEL_ASSIGN_MUST_OVERRIDE_SIGNAL (klass, nautilus_view, is_empty);
 
9720
        EEL_ASSIGN_MUST_OVERRIDE_SIGNAL (klass, nautilus_view, reset_to_defaults);
 
9721
        EEL_ASSIGN_MUST_OVERRIDE_SIGNAL (klass, nautilus_view, restore_default_zoom_level);
 
9722
        EEL_ASSIGN_MUST_OVERRIDE_SIGNAL (klass, nautilus_view, select_all);
 
9723
        EEL_ASSIGN_MUST_OVERRIDE_SIGNAL (klass, nautilus_view, set_selection);
 
9724
        EEL_ASSIGN_MUST_OVERRIDE_SIGNAL (klass, nautilus_view, invert_selection);
 
9725
        EEL_ASSIGN_MUST_OVERRIDE_SIGNAL (klass, nautilus_view, zoom_to_level);
 
9726
        EEL_ASSIGN_MUST_OVERRIDE_SIGNAL (klass, nautilus_view, get_zoom_level);
 
9727
 
 
9728
        copied_files_atom = gdk_atom_intern ("x-special/gnome-copied-files", FALSE);
 
9729
 
 
9730
        properties[PROP_WINDOW_SLOT] =
 
9731
                g_param_spec_object ("window-slot",
 
9732
                                     "Window Slot",
 
9733
                                     "The parent window slot reference",
 
9734
                                     NAUTILUS_TYPE_WINDOW_SLOT,
 
9735
                                     G_PARAM_WRITABLE |
 
9736
                                     G_PARAM_CONSTRUCT_ONLY);
 
9737
        properties[PROP_SUPPORTS_ZOOMING] =
 
9738
                g_param_spec_boolean ("supports-zooming",
 
9739
                                      "Supports zooming",
 
9740
                                      "Whether the view supports zooming",
 
9741
                                      TRUE,
 
9742
                                      G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY |
 
9743
                                      G_PARAM_STATIC_STRINGS);
 
9744
 
 
9745
        g_object_class_install_properties (oclass, NUM_PROPERTIES, properties);
 
9746
 
 
9747
        binding_set = gtk_binding_set_by_class (klass);
 
9748
        gtk_binding_entry_add_signal (binding_set, GDK_KEY_Delete, GDK_CONTROL_MASK,
 
9749
                                      "trash", 0);
 
9750
        gtk_binding_entry_add_signal (binding_set, GDK_KEY_KP_Delete, GDK_CONTROL_MASK,
 
9751
                                      "trash", 0);
 
9752
        gtk_binding_entry_add_signal (binding_set, GDK_KEY_KP_Delete, GDK_SHIFT_MASK,
 
9753
                                      "delete", 0);
 
9754
}
 
9755