1
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
5
* Copyright (C) 1999, 2000 Free Software Foundation
6
* Copyright (C) 2000, 2001 Eazel, Inc.
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.
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.
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.
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>
32
#include "nautilus-view.h"
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"
43
#include <gdk/gdkkeysyms.h>
45
#include <glib/gi18n.h>
46
#include <glib/gstdio.h>
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>
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>
83
#define DEBUG_FLAG NAUTILUS_DEBUG_DIRECTORY_VIEW
84
#include <libnautilus-private/nautilus-debug.h>
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
97
#define SILENT_WINDOW_OPEN_LIMIT 5
99
#define DUPLICATE_HORIZONTAL_ICON_OFFSET 70
100
#define DUPLICATE_VERTICAL_ICON_OFFSET 30
102
#define MAX_QUEUED_UPDATES 500
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"
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"
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"
122
#define NAUTILUS_VIEW_POPUP_PATH_LOCATION "/location"
124
#define MAX_MENU_LEVELS 5
125
#define TEMPLATE_LIMIT 30
146
PROP_WINDOW_SLOT = 1,
147
PROP_SUPPORTS_ZOOMING,
151
static guint signals[LAST_SIGNAL];
152
static GParamSpec *properties[NUM_PROPERTIES] = { NULL, };
154
static GdkAtom copied_files_atom;
156
static char *scripts_directory_uri = NULL;
157
static int scripts_directory_uri_length;
159
struct NautilusViewDetails
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;
170
gboolean supports_zooming;
172
GList *scripts_directory_list;
173
GtkActionGroup *scripts_action_group;
174
guint scripts_merge_id;
176
GList *templates_directory_list;
177
GtkActionGroup *templates_action_group;
178
guint templates_merge_id;
180
GtkActionGroup *extensions_menu_action_group;
181
guint extensions_menu_merge_id;
183
guint display_selection_idle_id;
184
guint update_menus_timeout_id;
185
guint update_status_idle_id;
186
guint reveal_selection_idle_id;
188
guint display_pending_source_id;
189
guint changes_timeout_id;
191
guint update_interval;
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;
200
guint delayed_rename_file_id;
202
GList *new_added_files;
203
GList *new_changed_files;
205
GHashTable *non_ready_files;
207
GList *old_added_files;
208
GList *old_changed_files;
210
GList *pending_selection;
212
/* whether we are in the active slot */
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.
221
gboolean menu_states_untrustworthy;
222
gboolean scripts_invalid;
223
gboolean templates_invalid;
224
gboolean reported_load_error;
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.
230
gboolean updates_frozen;
231
guint updates_queued;
232
gboolean needs_reload;
234
gboolean sort_directories_first;
236
gboolean show_foreign_files;
237
gboolean show_hidden_files;
238
gboolean ignore_hidden_file_preferences;
240
gboolean batching_selection_level;
241
gboolean selection_changed_while_batched;
243
gboolean selection_was_removed;
245
gboolean metadata_for_directory_as_file_pending;
246
gboolean metadata_for_files_in_directory_pending;
248
gboolean selection_change_is_due_to_shell;
249
gboolean send_selection_change_to_shell;
251
GtkActionGroup *open_with_action_group;
252
guint open_with_merge_id;
254
GList *subdirectory_list;
256
GdkPoint context_menu_position;
261
NautilusDirectory *directory;
264
/* forward declarations */
266
static gboolean display_selection_info_idle_callback (gpointer data);
267
static void nautilus_view_duplicate_selection (NautilusView *view,
269
GArray *item_locations);
270
static void nautilus_view_create_links_for_files (NautilusView *view,
272
GArray *item_locations);
273
static void trash_or_delete_files (GtkWindow *parent_window,
275
gboolean delete_if_all_already_in_trash,
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,
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,
299
gpointer callback_data);
300
static void nautilus_view_trash_state_changed_callback (NautilusTrashMonitor *trash,
302
gpointer callback_data);
303
static void nautilus_view_select_file (NautilusView *view,
306
static void update_templates_directory (NautilusView *view);
307
static void user_dirs_changed (NautilusView *view);
309
static gboolean file_list_all_are_folders (GList *file_list);
311
static void unschedule_pop_up_location_context_menu (NautilusView *view);
313
G_DEFINE_TYPE (NautilusView, nautilus_view, GTK_TYPE_SCROLLED_WINDOW);
314
#define parent_class nautilus_view_parent_class
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)
334
/* virtual methods (public and non-public) */
337
* nautilus_view_merge_menus:
339
* Add this view's menus to the window's menu bar.
340
* @view: NautilusView in question.
343
nautilus_view_merge_menus (NautilusView *view)
345
g_return_if_fail (NAUTILUS_IS_VIEW (view));
348
(NAUTILUS_VIEW_CLASS, view,
349
merge_menus, (view));
353
nautilus_view_unmerge_menus (NautilusView *view)
355
g_return_if_fail (NAUTILUS_IS_VIEW (view));
358
(NAUTILUS_VIEW_CLASS, view,
359
unmerge_menus, (view));
363
real_get_backing_uri (NautilusView *view)
365
NautilusDirectory *directory;
368
g_return_val_if_fail (NAUTILUS_IS_VIEW (view), NULL);
370
if (view->details->model == NULL) {
374
directory = view->details->model;
376
if (NAUTILUS_IS_DESKTOP_DIRECTORY (directory)) {
377
directory = nautilus_desktop_directory_get_real_directory (NAUTILUS_DESKTOP_DIRECTORY (directory));
379
nautilus_directory_ref (directory);
382
uri = nautilus_directory_get_uri (directory);
384
nautilus_directory_unref (directory);
391
* nautilus_view_get_backing_uri:
393
* Returns the URI for the target location of new directory, new file, new
394
* link, new launcher, and paste operations.
398
nautilus_view_get_backing_uri (NautilusView *view)
400
g_return_val_if_fail (NAUTILUS_IS_VIEW (view), NULL);
402
return EEL_CALL_METHOD_WITH_RETURN_VALUE
403
(NAUTILUS_VIEW_CLASS, view,
404
get_backing_uri, (view));
408
* nautilus_view_select_all:
410
* select all the items in the view
414
nautilus_view_select_all (NautilusView *view)
416
g_return_if_fail (NAUTILUS_IS_VIEW (view));
419
(NAUTILUS_VIEW_CLASS, view,
424
nautilus_view_call_set_selection (NautilusView *view, GList *selection)
426
g_return_if_fail (NAUTILUS_IS_VIEW (view));
429
(NAUTILUS_VIEW_CLASS, view,
430
set_selection, (view, selection));
434
nautilus_view_get_selection_for_file_transfer (NautilusView *view)
436
g_return_val_if_fail (NAUTILUS_IS_VIEW (view), NULL);
438
return EEL_CALL_METHOD_WITH_RETURN_VALUE
439
(NAUTILUS_VIEW_CLASS, view,
440
get_selection_for_file_transfer, (view));
444
* nautilus_view_get_selected_icon_locations:
446
* return an array of locations of selected icons if available
447
* Return value: GArray of GdkPoints
451
nautilus_view_get_selected_icon_locations (NautilusView *view)
453
g_return_val_if_fail (NAUTILUS_IS_VIEW (view), NULL);
455
return EEL_CALL_METHOD_WITH_RETURN_VALUE
456
(NAUTILUS_VIEW_CLASS, view,
457
get_selected_icon_locations, (view));
461
nautilus_view_invert_selection (NautilusView *view)
463
g_return_if_fail (NAUTILUS_IS_VIEW (view));
466
(NAUTILUS_VIEW_CLASS, view,
467
invert_selection, (view));
471
* nautilus_view_reveal_selection:
473
* Scroll as necessary to reveal the selected items.
476
nautilus_view_reveal_selection (NautilusView *view)
478
g_return_if_fail (NAUTILUS_IS_VIEW (view));
481
(NAUTILUS_VIEW_CLASS, view,
482
reveal_selection, (view));
486
* nautilus_view_reset_to_defaults:
488
* set sorting order, zoom level, etc. to match defaults
492
nautilus_view_reset_to_defaults (NautilusView *view)
494
NautilusWindowShowHiddenFilesMode mode;
496
g_return_if_fail (NAUTILUS_IS_VIEW (view));
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);
509
nautilus_view_using_manual_layout (NautilusView *view)
511
g_return_val_if_fail (NAUTILUS_IS_VIEW (view), FALSE);
513
return EEL_CALL_METHOD_WITH_RETURN_VALUE
514
(NAUTILUS_VIEW_CLASS, view,
515
using_manual_layout, (view));
519
nautilus_view_get_item_count (NautilusView *view)
521
g_return_val_if_fail (NAUTILUS_IS_VIEW (view), 0);
523
return EEL_CALL_METHOD_WITH_RETURN_VALUE
524
(NAUTILUS_VIEW_CLASS, view,
525
get_item_count, (view));
529
* nautilus_view_can_rename_file
531
* Determine whether a file can be renamed.
532
* @file: A NautilusFile
534
* Return value: TRUE if @file can be renamed, FALSE otherwise.
538
nautilus_view_can_rename_file (NautilusView *view, NautilusFile *file)
540
return EEL_CALL_METHOD_WITH_RETURN_VALUE
541
(NAUTILUS_VIEW_CLASS, view,
542
can_rename_file, (view, file));
546
nautilus_view_is_read_only (NautilusView *view)
548
g_return_val_if_fail (NAUTILUS_IS_VIEW (view), FALSE);
550
return EEL_CALL_METHOD_WITH_RETURN_VALUE
551
(NAUTILUS_VIEW_CLASS, view,
552
is_read_only, (view));
556
showing_trash_directory (NautilusView *view)
560
file = nautilus_view_get_directory_as_file (view);
562
return nautilus_file_is_in_trash (file);
568
nautilus_view_supports_creating_files (NautilusView *view)
570
g_return_val_if_fail (NAUTILUS_IS_VIEW (view), FALSE);
572
return !nautilus_view_is_read_only (view) && !showing_trash_directory (view);
576
nautilus_view_is_empty (NautilusView *view)
578
g_return_val_if_fail (NAUTILUS_IS_VIEW (view), FALSE);
580
return EEL_CALL_METHOD_WITH_RETURN_VALUE
581
(NAUTILUS_VIEW_CLASS, view,
586
* nautilus_view_bump_zoom_level:
588
* bump the current zoom level by invoking the relevant subclass through the slot
592
nautilus_view_bump_zoom_level (NautilusView *view,
595
g_return_if_fail (NAUTILUS_IS_VIEW (view));
597
if (!nautilus_view_supports_zooming (view)) {
602
(NAUTILUS_VIEW_CLASS, view,
603
bump_zoom_level, (view, zoom_increment));
607
* nautilus_view_zoom_to_level:
609
* Set the current zoom level by invoking the relevant subclass through the slot
613
nautilus_view_zoom_to_level (NautilusView *view,
614
NautilusZoomLevel zoom_level)
616
g_return_if_fail (NAUTILUS_IS_VIEW (view));
618
if (!nautilus_view_supports_zooming (view)) {
623
(NAUTILUS_VIEW_CLASS, view,
624
zoom_to_level, (view, zoom_level));
628
nautilus_view_get_zoom_level (NautilusView *view)
630
g_return_val_if_fail (NAUTILUS_IS_VIEW (view), NAUTILUS_ZOOM_LEVEL_STANDARD);
632
if (!nautilus_view_supports_zooming (view)) {
633
return NAUTILUS_ZOOM_LEVEL_STANDARD;
636
return EEL_CALL_METHOD_WITH_RETURN_VALUE
637
(NAUTILUS_VIEW_CLASS, view,
638
get_zoom_level, (view));
642
* nautilus_view_can_zoom_in:
644
* Determine whether the view can be zoomed any closer.
645
* @view: The zoomable NautilusView.
647
* Return value: TRUE if @view can be zoomed any closer, FALSE otherwise.
651
nautilus_view_can_zoom_in (NautilusView *view)
653
g_return_val_if_fail (NAUTILUS_IS_VIEW (view), FALSE);
655
if (!nautilus_view_supports_zooming (view)) {
659
return EEL_CALL_METHOD_WITH_RETURN_VALUE
660
(NAUTILUS_VIEW_CLASS, view,
661
can_zoom_in, (view));
665
* nautilus_view_can_zoom_out:
667
* Determine whether the view can be zoomed any further away.
668
* @view: The zoomable NautilusView.
670
* Return value: TRUE if @view can be zoomed any further away, FALSE otherwise.
674
nautilus_view_can_zoom_out (NautilusView *view)
676
g_return_val_if_fail (NAUTILUS_IS_VIEW (view), FALSE);
678
if (!nautilus_view_supports_zooming (view)) {
682
return EEL_CALL_METHOD_WITH_RETURN_VALUE
683
(NAUTILUS_VIEW_CLASS, view,
684
can_zoom_out, (view));
688
nautilus_view_supports_zooming (NautilusView *view)
690
g_return_val_if_fail (NAUTILUS_IS_VIEW (view), FALSE);
692
return view->details->supports_zooming;
696
* nautilus_view_restore_default_zoom_level:
698
* restore to the default zoom level by invoking the relevant subclass through the slot
702
nautilus_view_restore_default_zoom_level (NautilusView *view)
704
g_return_if_fail (NAUTILUS_IS_VIEW (view));
706
if (!nautilus_view_supports_zooming (view)) {
711
(NAUTILUS_VIEW_CLASS, view,
712
restore_default_zoom_level, (view));
716
nautilus_view_get_view_id (NautilusView *view)
718
return EEL_CALL_METHOD_WITH_RETURN_VALUE
719
(NAUTILUS_VIEW_CLASS, view,
720
get_view_id, (view));
724
nautilus_view_get_first_visible_file (NautilusView *view)
726
return EEL_CALL_METHOD_WITH_RETURN_VALUE
727
(NAUTILUS_VIEW_CLASS, view,
728
get_first_visible_file, (view));
732
nautilus_view_scroll_to_file (NautilusView *view,
736
(NAUTILUS_VIEW_CLASS, view,
737
scroll_to_file, (view, uri));
741
nautilus_view_get_emblem_names_to_exclude (NautilusView *view)
746
g_assert (NAUTILUS_IS_VIEW (view));
748
excludes = g_new (char *, 3);
751
excludes[i++] = g_strdup (NAUTILUS_FILE_EMBLEM_NAME_TRASH);
753
if (!nautilus_file_can_write (view->details->directory_as_file)) {
754
excludes[i++] = g_strdup (NAUTILUS_FILE_EMBLEM_NAME_CANT_WRITE);
757
excludes[i++] = NULL;
763
nautilus_view_set_is_active (NautilusView *view,
766
g_return_if_fail (NAUTILUS_IS_VIEW (view));
768
EEL_CALL_METHOD (NAUTILUS_VIEW_CLASS, view,
769
set_is_active, (view, is_active));
773
* nautilus_view_get_selection:
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.
781
* Return value: GList of NautilusFile pointers representing the selection.
785
nautilus_view_get_selection (NautilusView *view)
787
g_return_val_if_fail (NAUTILUS_IS_VIEW (view), NULL);
789
return EEL_CALL_METHOD_WITH_RETURN_VALUE
790
(NAUTILUS_VIEW_CLASS, view,
791
get_selection, (view));
796
* nautilus_view_update_menus:
798
* Update the sensitivity and wording of dynamic menu items.
799
* @view: NautilusView in question.
802
nautilus_view_update_menus (NautilusView *view)
804
g_return_if_fail (NAUTILUS_IS_VIEW (view));
806
if (!view->details->active) {
812
(NAUTILUS_VIEW_CLASS, view,
813
update_menus, (view));
815
view->details->menu_states_untrustworthy = FALSE;
819
GAppInfo *application;
821
NautilusView *directory_view;
822
} ApplicationLaunchParameters;
826
NautilusView *directory_view;
827
} ScriptLaunchParameters;
831
NautilusView *directory_view;
832
} CreateTemplateParameters;
834
static ApplicationLaunchParameters *
835
application_launch_parameters_new (GAppInfo *application,
837
NautilusView *directory_view)
839
ApplicationLaunchParameters *result;
841
result = g_new0 (ApplicationLaunchParameters, 1);
842
result->application = g_object_ref (application);
843
result->files = nautilus_file_list_copy (files);
845
if (directory_view != NULL) {
846
g_object_ref (directory_view);
847
result->directory_view = directory_view;
854
application_launch_parameters_free (ApplicationLaunchParameters *parameters)
856
g_object_unref (parameters->application);
857
nautilus_file_list_free (parameters->files);
859
if (parameters->directory_view != NULL) {
860
g_object_unref (parameters->directory_view);
867
file_and_directory_list_to_files (GList *fad_list)
870
FileAndDirectory *fad;
873
for (l = fad_list; l != NULL; l = l->next) {
875
res = g_list_prepend (res, nautilus_file_ref (fad->file));
877
return g_list_reverse (res);
882
file_and_directory_list_from_files (NautilusDirectory *directory, GList *files)
885
FileAndDirectory *fad;
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);
894
return g_list_reverse (res);
898
file_and_directory_free (FileAndDirectory *fad)
900
nautilus_directory_unref (fad->directory);
901
nautilus_file_unref (fad->file);
907
file_and_directory_list_free (GList *list)
911
for (l = list; l != NULL; l = l->next) {
912
file_and_directory_free (l->data);
919
file_and_directory_equal (gconstpointer v1,
922
const FileAndDirectory *fad1, *fad2;
926
return (fad1->file == fad2->file &&
927
fad1->directory == fad2->directory);
931
file_and_directory_hash (gconstpointer v)
933
const FileAndDirectory *fad;
936
return GPOINTER_TO_UINT (fad->file) ^ GPOINTER_TO_UINT (fad->directory);
942
static ScriptLaunchParameters *
943
script_launch_parameters_new (NautilusFile *file,
944
NautilusView *directory_view)
946
ScriptLaunchParameters *result;
948
result = g_new0 (ScriptLaunchParameters, 1);
949
g_object_ref (directory_view);
950
result->directory_view = directory_view;
951
nautilus_file_ref (file);
958
script_launch_parameters_free (ScriptLaunchParameters *parameters)
960
g_object_unref (parameters->directory_view);
961
nautilus_file_unref (parameters->file);
965
static CreateTemplateParameters *
966
create_template_parameters_new (NautilusFile *file,
967
NautilusView *directory_view)
969
CreateTemplateParameters *result;
971
result = g_new0 (CreateTemplateParameters, 1);
972
g_object_ref (directory_view);
973
result->directory_view = directory_view;
974
nautilus_file_ref (file);
981
create_templates_parameters_free (CreateTemplateParameters *parameters)
983
g_object_unref (parameters->directory_view);
984
nautilus_file_unref (parameters->file);
989
nautilus_view_get_nautilus_window (NautilusView *view)
991
g_assert (view->details->window != NULL);
993
return view->details->window;
997
nautilus_view_get_nautilus_window_slot (NautilusView *view)
999
g_assert (view->details->slot != NULL);
1001
return view->details->slot;
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.
1009
nautilus_view_get_containing_window (NautilusView *view)
1013
g_assert (NAUTILUS_IS_VIEW (view));
1015
window = gtk_widget_get_ancestor (GTK_WIDGET (view), GTK_TYPE_WINDOW);
1016
if (window == NULL) {
1020
return GTK_WINDOW (window);
1024
nautilus_view_confirm_multiple (GtkWindow *parent_window,
1033
if (count <= SILENT_WINDOW_OPEN_LIMIT) {
1037
prompt = _("Are you sure you want to open all files?");
1039
detail = g_strdup_printf (ngettext("This will open %'d separate tab.",
1040
"This will open %'d separate tabs.", count), count);
1042
detail = g_strdup_printf (ngettext("This will open %'d separate window.",
1043
"This will open %'d separate windows.", count), count);
1045
dialog = eel_show_yes_no_dialog (prompt, detail,
1046
GTK_STOCK_OK, GTK_STOCK_CANCEL,
1050
response = gtk_dialog_run (dialog);
1051
gtk_widget_destroy (GTK_WIDGET (dialog));
1053
return response == GTK_RESPONSE_YES;
1057
selection_contains_one_item_in_menu_callback (NautilusView *view, GList *selection)
1059
if (eel_g_list_exactly_one_item (selection)) {
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.
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));
1076
selection_not_empty_in_menu_callback (NautilusView *view, GList *selection)
1078
if (selection != NULL) {
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.
1086
if (!view->details->menu_states_untrustworthy) {
1087
g_warning ("Empty selection found when selection was expected. No action will be performed.");
1094
get_view_directory (NautilusView *view)
1099
uri = nautilus_directory_get_uri (view->details->model);
1100
if (eel_uri_is_desktop (uri)) {
1102
uri = nautilus_get_desktop_directory_uri ();
1105
f = g_file_new_for_uri (uri);
1106
path = g_file_get_path (f);
1114
nautilus_view_preview_files (NautilusView *view,
1118
NautilusPreviewer *previewer;
1121
GtkWidget *toplevel;
1123
previewer = nautilus_previewer_get_singleton ();
1124
uri = nautilus_file_get_uri (files->data);
1125
toplevel = gtk_widget_get_toplevel (GTK_WIDGET (view));
1127
xid = gdk_x11_window_get_xid (gtk_widget_get_window (toplevel));
1128
nautilus_previewer_call_show_file (previewer, uri, xid, TRUE);
1132
nautilus_view_activate_files (NautilusView *view,
1134
NautilusWindowOpenFlags flags,
1135
gboolean confirm_multiple)
1139
path = get_view_directory (view);
1140
nautilus_mime_activate_files (nautilus_view_get_containing_window (view),
1141
view->details->slot,
1151
nautilus_view_activate_file (NautilusView *view,
1153
NautilusWindowOpenFlags flags)
1157
path = get_view_directory (view);
1158
nautilus_mime_activate_file (nautilus_view_get_containing_window (view),
1159
view->details->slot,
1168
action_open_callback (GtkAction *action,
1169
gpointer callback_data)
1174
view = NAUTILUS_VIEW (callback_data);
1176
selection = nautilus_view_get_selection (view);
1177
nautilus_view_activate_files (view,
1181
nautilus_file_list_free (selection);
1185
action_open_close_parent_callback (GtkAction *action,
1186
gpointer callback_data)
1191
view = NAUTILUS_VIEW (callback_data);
1193
selection = nautilus_view_get_selection (view);
1194
nautilus_view_activate_files (view,
1196
NAUTILUS_WINDOW_OPEN_FLAG_CLOSE_BEHIND,
1198
nautilus_file_list_free (selection);
1203
action_open_alternate_callback (GtkAction *action,
1204
gpointer callback_data)
1210
view = NAUTILUS_VIEW (callback_data);
1211
selection = nautilus_view_get_selection (view);
1213
window = nautilus_view_get_containing_window (view);
1215
if (nautilus_view_confirm_multiple (window, g_list_length (selection), FALSE)) {
1216
g_list_foreach (selection, open_one_in_new_window, view);
1219
nautilus_file_list_free (selection);
1223
action_open_new_tab_callback (GtkAction *action,
1224
gpointer callback_data)
1230
view = NAUTILUS_VIEW (callback_data);
1231
selection = nautilus_view_get_selection (view);
1233
window = nautilus_view_get_containing_window (view);
1235
if (nautilus_view_confirm_multiple (window, g_list_length (selection), TRUE)) {
1236
nautilus_view_activate_files (view,
1238
NAUTILUS_WINDOW_OPEN_FLAG_NEW_TAB,
1242
nautilus_file_list_free (selection);
1246
app_chooser_dialog_response_cb (GtkDialog *dialog,
1250
GtkWindow *parent_window;
1255
parent_window = user_data;
1257
if (response_id != GTK_RESPONSE_OK) {
1258
gtk_widget_destroy (GTK_WIDGET (dialog));
1262
info = gtk_app_chooser_get_app_info (GTK_APP_CHOOSER (dialog));
1263
file = g_object_get_data (G_OBJECT (dialog), "directory-view:file");
1265
g_signal_emit_by_name (nautilus_signaller_get_current (), "mime_data_changed");
1270
nautilus_launch_application (info, &files, parent_window);
1272
gtk_widget_destroy (GTK_WIDGET (dialog));
1273
g_object_unref (info);
1277
choose_program (NautilusView *view,
1282
GtkWindow *parent_window;
1284
g_assert (NAUTILUS_IS_VIEW (view));
1285
g_assert (NAUTILUS_IS_FILE (file));
1287
nautilus_file_ref (file);
1288
location = nautilus_file_get_location (file);
1289
parent_window = nautilus_view_get_containing_window (view);
1291
dialog = gtk_app_chooser_dialog_new (parent_window, 0,
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);
1299
g_signal_connect_object (dialog, "response",
1300
G_CALLBACK (app_chooser_dialog_response_cb),
1303
g_object_unref (location);
1304
nautilus_file_unref (file);
1308
open_with_other_program (NautilusView *view)
1312
g_assert (NAUTILUS_IS_VIEW (view));
1314
selection = nautilus_view_get_selection (view);
1316
if (selection_contains_one_item_in_menu_callback (view, selection)) {
1317
choose_program (view, NAUTILUS_FILE (selection->data));
1320
nautilus_file_list_free (selection);
1324
action_other_application_callback (GtkAction *action,
1325
gpointer callback_data)
1327
g_assert (NAUTILUS_IS_VIEW (callback_data));
1329
open_with_other_program (NAUTILUS_VIEW (callback_data));
1333
trash_or_delete_selected_files (NautilusView *view)
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).
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),
1346
nautilus_file_list_free (selection);
1347
view->details->selection_was_removed = TRUE;
1352
real_trash (NautilusView *view)
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);
1367
action_trash_callback (GtkAction *action,
1368
gpointer callback_data)
1370
trash_or_delete_selected_files (NAUTILUS_VIEW (callback_data));
1374
delete_selected_files (NautilusView *view)
1380
selection = nautilus_view_get_selection_for_file_transfer (view);
1381
if (selection == NULL) {
1386
for (node = selection; node != NULL; node = node->next) {
1387
locations = g_list_prepend (locations,
1388
nautilus_file_get_location ((NautilusFile *) node->data));
1390
locations = g_list_reverse (locations);
1392
nautilus_file_operations_delete (locations, nautilus_view_get_containing_window (view), NULL, NULL);
1394
g_list_free_full (locations, g_object_unref);
1395
nautilus_file_list_free (selection);
1399
action_delete_callback (GtkAction *action,
1400
gpointer callback_data)
1402
delete_selected_files (NAUTILUS_VIEW (callback_data));
1406
action_restore_from_trash_callback (GtkAction *action,
1407
gpointer callback_data)
1412
view = NAUTILUS_VIEW (callback_data);
1414
selection = nautilus_view_get_selection_for_file_transfer (view);
1415
nautilus_restore_files_from_trash (selection,
1416
nautilus_view_get_containing_window (view));
1418
nautilus_file_list_free (selection);
1423
real_delete (NautilusView *view)
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);
1438
action_duplicate_callback (GtkAction *action,
1439
gpointer callback_data)
1443
GArray *selected_item_locations;
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.
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);
1459
nautilus_file_list_free (selection);
1463
action_create_link_callback (GtkAction *action,
1464
gpointer callback_data)
1468
GArray *selected_item_locations;
1470
g_assert (NAUTILUS_IS_VIEW (callback_data));
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);
1480
nautilus_file_list_free (selection);
1484
action_select_all_callback (GtkAction *action,
1485
gpointer callback_data)
1487
g_assert (NAUTILUS_IS_VIEW (callback_data));
1489
nautilus_view_select_all (callback_data);
1493
action_invert_selection_callback (GtkAction *action,
1494
gpointer callback_data)
1496
g_assert (NAUTILUS_IS_VIEW (callback_data));
1498
nautilus_view_invert_selection (callback_data);
1502
pattern_select_response_cb (GtkWidget *dialog, int response, gpointer user_data)
1505
NautilusDirectory *directory;
1510
view = NAUTILUS_VIEW (user_data);
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)));
1520
nautilus_view_call_set_selection (view, selection);
1521
nautilus_file_list_free (selection);
1523
nautilus_view_reveal_selection(view);
1526
case GTK_RESPONSE_NONE :
1527
case GTK_RESPONSE_DELETE_EVENT :
1528
case GTK_RESPONSE_CANCEL :
1529
gtk_widget_destroy (GTK_WIDGET (dialog));
1531
case GTK_RESPONSE_HELP :
1533
gtk_show_uri (gtk_window_get_screen (GTK_WINDOW (dialog)),
1534
"ghelp:gnome-help#files-select",
1535
gtk_get_current_event_time (), &error);
1537
eel_show_error_dialog (_("There was an error displaying help."), error->message,
1538
GTK_WINDOW (dialog));
1539
g_error_free (error);
1543
g_assert_not_reached ();
1548
select_pattern (NautilusView *view)
1555
char *example_pattern;
1557
dialog = gtk_dialog_new_with_buttons (_("Select Items Matching"),
1558
nautilus_view_get_containing_window (view),
1559
GTK_DIALOG_DESTROY_WITH_PARENT,
1563
GTK_RESPONSE_CANCEL,
1567
gtk_dialog_set_default_response (GTK_DIALOG (dialog),
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);
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>",
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);
1583
table = gtk_table_new (2, 2, FALSE);
1585
gtk_table_attach (GTK_TABLE (table), label,
1591
gtk_table_attach (GTK_TABLE (table), entry,
1594
GTK_EXPAND | GTK_FILL, GTK_FILL,
1597
gtk_table_attach (GTK_TABLE (table), example,
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),
1610
gtk_widget_show_all (dialog);
1614
action_select_pattern_callback (GtkAction *action,
1615
gpointer callback_data)
1617
g_assert (NAUTILUS_IS_VIEW (callback_data));
1619
select_pattern(callback_data);
1623
action_reset_to_defaults_callback (GtkAction *action,
1624
gpointer callback_data)
1626
g_assert (NAUTILUS_IS_VIEW (callback_data));
1628
nautilus_view_reset_to_defaults (callback_data);
1633
hidden_files_mode_changed (NautilusWindow *window,
1634
gpointer callback_data)
1636
NautilusView *directory_view;
1638
directory_view = NAUTILUS_VIEW (callback_data);
1640
nautilus_view_init_show_hidden_files (directory_view);
1644
action_save_search_callback (GtkAction *action,
1645
gpointer callback_data)
1647
NautilusSearchDirectory *search;
1648
NautilusView *directory_view;
1650
directory_view = NAUTILUS_VIEW (callback_data);
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);
1657
/* Save search is disabled */
1658
schedule_update_menus (directory_view);
1663
query_name_entry_changed_cb (GtkWidget *entry, GtkWidget *button)
1668
text = gtk_entry_get_text (GTK_ENTRY (entry));
1670
sensitive = (text != NULL) && (*text != 0);
1672
gtk_widget_set_sensitive (button, sensitive);
1677
action_save_search_as_callback (GtkAction *action,
1678
gpointer callback_data)
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;
1687
directory_view = NAUTILUS_VIEW (callback_data);
1689
if (directory_view->details->model &&
1690
NAUTILUS_IS_SEARCH_DIRECTORY (directory_view->details->model)) {
1691
search = NAUTILUS_SEARCH_DIRECTORY (directory_view->details->model);
1693
dialog = gtk_dialog_new_with_buttons (_("Save Search as"),
1694
nautilus_view_get_containing_window (directory_view),
1696
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
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),
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);
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);
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);
1722
gtk_widget_set_sensitive (save_button, FALSE);
1723
g_signal_connect (entry, "changed",
1724
G_CALLBACK (query_name_entry_changed_cb), save_button);
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);
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);
1738
gtk_file_chooser_set_local_only (GTK_FILE_CHOOSER (chooser), TRUE);
1740
gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (chooser),
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);
1748
filename_utf8 = g_strconcat (entry_text, NAUTILUS_SAVED_SEARCH_EXTENSION, NULL);
1751
filename = g_filename_from_utf8 (filename_utf8, -1, NULL, NULL, NULL);
1752
g_free (filename_utf8);
1754
dirname = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (chooser));
1756
path = g_build_filename (dirname, filename, NULL);
1760
uri = g_filename_to_uri (path, NULL, NULL);
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);
1771
gtk_widget_destroy (dialog);
1777
action_empty_trash_callback (GtkAction *action,
1778
gpointer callback_data)
1780
g_assert (NAUTILUS_IS_VIEW (callback_data));
1782
nautilus_file_operations_empty_trash (GTK_WIDGET (callback_data));
1787
NautilusFile *new_file;
1791
delayed_rename_file_hack_callback (RenameData *data)
1794
NautilusFile *new_file;
1797
new_file = data->new_file;
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);
1809
delayed_rename_file_hack_removed (RenameData *data)
1811
g_object_unref (data->view);
1812
nautilus_file_unref (data->new_file);
1818
rename_file (NautilusView *view, NautilusFile *new_file)
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.
1832
if (NAUTILUS_IS_LIST_VIEW (view)) {
1833
nautilus_view_select_file (view, new_file);
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);
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);
1849
/* no need to select because start_renaming_file selects
1850
* nautilus_view_select_file (view, new_file);
1852
EEL_CALL_METHOD (NAUTILUS_VIEW_CLASS, view, start_renaming_file, (view, new_file, FALSE));
1853
nautilus_view_reveal_selection (view);
1857
reveal_newly_added_folder (NautilusView *view, NautilusFile *new_file,
1858
NautilusDirectory *directory, GFile *target_location)
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);
1869
g_object_unref (location);
1873
NautilusView *directory_view;
1874
GHashTable *added_locations;
1879
track_newly_added_locations (NautilusView *view, NautilusFile *new_file,
1880
NautilusDirectory *directory, gpointer user_data)
1882
NewFolderData *data;
1886
g_hash_table_insert (data->added_locations, nautilus_file_get_location (new_file), NULL);
1890
new_folder_done (GFile *new_folder, gpointer user_data)
1892
NautilusView *directory_view;
1894
char screen_string[32];
1896
NewFolderData *data;
1898
data = (NewFolderData *)user_data;
1900
directory_view = data->directory_view;
1902
if (directory_view == NULL) {
1906
g_signal_handlers_disconnect_by_func (directory_view,
1907
G_CALLBACK (track_newly_added_locations),
1910
if (new_folder == NULL) {
1914
screen = gtk_widget_get_screen (GTK_WIDGET (directory_view));
1915
g_snprintf (screen_string, sizeof (screen_string), "%d", gdk_screen_get_number (screen));
1918
file = nautilus_file_get (new_folder);
1919
nautilus_file_set_metadata
1920
(file, NAUTILUS_METADATA_KEY_SCREEN,
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);
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.
1932
g_signal_connect_data (directory_view,
1934
G_CALLBACK (reveal_newly_added_folder),
1935
g_object_ref (new_folder),
1936
(GClosureNotify)g_object_unref,
1939
nautilus_file_unref (file);
1942
g_hash_table_destroy (data->added_locations);
1943
eel_remove_weak_pointer (&data->directory_view);
1948
static NewFolderData *
1949
new_folder_data_new (NautilusView *directory_view)
1951
NewFolderData *data;
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);
1963
context_menu_to_file_operation_position (NautilusView *directory_view)
1965
g_return_val_if_fail (NAUTILUS_IS_VIEW (directory_view), NULL);
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;
1980
nautilus_view_new_folder (NautilusView *directory_view)
1983
NewFolderData *data;
1986
data = new_folder_data_new (directory_view);
1988
g_signal_connect_data (directory_view,
1990
G_CALLBACK (track_newly_added_locations),
1992
(GClosureNotify)NULL,
1995
pos = context_menu_to_file_operation_position (directory_view);
1997
parent_uri = nautilus_view_get_backing_uri (directory_view);
1998
nautilus_file_operations_new_folder (GTK_WIDGET (directory_view),
2000
new_folder_done, data);
2002
g_free (parent_uri);
2005
static NewFolderData *
2006
setup_new_folder_data (NautilusView *directory_view)
2008
NewFolderData *data;
2010
data = new_folder_data_new (directory_view);
2012
g_signal_connect_data (directory_view,
2014
G_CALLBACK (track_newly_added_locations),
2016
(GClosureNotify)NULL,
2023
nautilus_view_new_file_with_initial_contents (NautilusView *view,
2024
const char *parent_uri,
2025
const char *filename,
2026
const char *initial_contents,
2030
NewFolderData *data;
2032
g_assert (parent_uri != NULL);
2034
data = setup_new_folder_data (view);
2037
pos = context_menu_to_file_operation_position (view);
2040
nautilus_file_operations_new_file (GTK_WIDGET (view),
2041
pos, parent_uri, filename,
2042
initial_contents, length,
2043
new_folder_done, data);
2047
nautilus_view_new_file (NautilusView *directory_view,
2048
const char *parent_uri,
2049
NautilusFile *source)
2052
NewFolderData *data;
2054
char *container_uri;
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);
2062
if (source == NULL) {
2063
nautilus_view_new_file_with_initial_contents (directory_view,
2064
parent_uri != NULL ? parent_uri : container_uri,
2069
g_free (container_uri);
2073
g_return_if_fail (nautilus_file_is_local (source));
2075
pos = context_menu_to_file_operation_position (directory_view);
2077
data = setup_new_folder_data (directory_view);
2079
source_uri = nautilus_file_get_uri (source);
2081
nautilus_file_operations_new_file_from_template (GTK_WIDGET (directory_view),
2083
parent_uri != NULL ? parent_uri : container_uri,
2086
new_folder_done, data);
2088
g_free (source_uri);
2089
g_free (container_uri);
2093
action_new_folder_callback (GtkAction *action,
2094
gpointer callback_data)
2096
g_assert (NAUTILUS_IS_VIEW (callback_data));
2098
nautilus_view_new_folder (NAUTILUS_VIEW (callback_data));
2102
action_new_empty_file_callback (GtkAction *action,
2103
gpointer callback_data)
2105
g_assert (NAUTILUS_IS_VIEW (callback_data));
2107
nautilus_view_new_file (NAUTILUS_VIEW (callback_data), NULL, NULL);
2111
action_new_launcher_callback (GtkAction *action,
2112
gpointer callback_data)
2118
g_assert (NAUTILUS_IS_VIEW (callback_data));
2120
view = NAUTILUS_VIEW (callback_data);
2122
parent_uri = nautilus_view_get_backing_uri (view);
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",
2129
"--create-new", parent_uri, NULL);
2131
g_free (parent_uri);
2135
action_properties_callback (GtkAction *action,
2136
gpointer callback_data)
2142
g_assert (NAUTILUS_IS_VIEW (callback_data));
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));
2150
nautilus_properties_window_present (files, GTK_WIDGET (view));
2152
nautilus_file_list_free (files);
2155
nautilus_properties_window_present (selection, GTK_WIDGET (view));
2157
nautilus_file_list_free (selection);
2161
action_location_properties_callback (GtkAction *action,
2162
gpointer callback_data)
2167
g_assert (NAUTILUS_IS_VIEW (callback_data));
2169
view = NAUTILUS_VIEW (callback_data);
2170
g_assert (NAUTILUS_IS_FILE (view->details->location_popup_directory_as_file));
2172
files = g_list_append (NULL, nautilus_file_ref (view->details->location_popup_directory_as_file));
2174
nautilus_properties_window_present (files, GTK_WIDGET (view));
2176
nautilus_file_list_free (files);
2180
all_files_in_trash (GList *files)
2184
/* Result is ambiguous if called on NULL, so disallow. */
2185
g_return_val_if_fail (files != NULL, FALSE);
2187
for (node = files; node != NULL; node = node->next) {
2188
if (!nautilus_file_is_in_trash (NAUTILUS_FILE (node->data))) {
2197
all_selected_items_in_trash (NautilusView *view)
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.
2206
selection = nautilus_view_get_selection (view);
2207
result = (selection == NULL) ? FALSE : all_files_in_trash (selection);
2208
nautilus_file_list_free (selection);
2214
we_are_in_vfolder_desktop_dir (NautilusView *view)
2219
g_return_val_if_fail (NAUTILUS_IS_VIEW (view), FALSE);
2221
if (view->details->model == NULL) {
2225
file = nautilus_directory_get_corresponding_file (view->details->model);
2226
mime_type = nautilus_file_get_mime_type (file);
2227
nautilus_file_unref (file);
2229
if (mime_type != NULL
2230
&& strcmp (mime_type, "x-directory/vfolder-desktop") == 0) {
2240
click_policy_changed_callback (gpointer callback_data)
2244
view = NAUTILUS_VIEW (callback_data);
2247
(NAUTILUS_VIEW_CLASS, view,
2248
click_policy_changed, (view));
2252
nautilus_view_should_sort_directories_first (NautilusView *view)
2254
return view->details->sort_directories_first;
2258
sort_directories_first_changed_callback (gpointer callback_data)
2261
gboolean preference_value;
2263
view = NAUTILUS_VIEW (callback_data);
2266
g_settings_get_boolean (nautilus_preferences, NAUTILUS_PREFERENCES_SORT_DIRECTORIES_FIRST);
2268
if (preference_value != view->details->sort_directories_first) {
2269
view->details->sort_directories_first = preference_value;
2271
(NAUTILUS_VIEW_CLASS, view,
2272
sort_directories_first_changed, (view));
2277
set_up_scripts_directory_global (void)
2279
char *scripts_directory_path;
2280
const char *override;
2282
if (scripts_directory_uri != NULL) {
2286
override = g_getenv ("GNOME22_USER_DIR");
2289
scripts_directory_path = g_build_filename (override,
2293
scripts_directory_path = g_build_filename (g_get_home_dir (),
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);
2304
g_free (scripts_directory_path);
2306
return (scripts_directory_uri != NULL) ? TRUE : FALSE;
2310
scripts_added_or_changed_callback (NautilusDirectory *directory,
2312
gpointer callback_data)
2316
view = NAUTILUS_VIEW (callback_data);
2318
view->details->scripts_invalid = TRUE;
2319
if (view->details->active) {
2320
schedule_update_menus (view);
2325
templates_added_or_changed_callback (NautilusDirectory *directory,
2327
gpointer callback_data)
2331
view = NAUTILUS_VIEW (callback_data);
2333
view->details->templates_invalid = TRUE;
2334
if (view->details->active) {
2335
schedule_update_menus (view);
2340
add_directory_to_directory_list (NautilusView *view,
2341
NautilusDirectory *directory,
2342
GList **directory_list,
2343
GCallback changed_callback)
2345
NautilusFileAttributes attributes;
2347
if (g_list_find (*directory_list, directory) == NULL) {
2348
nautilus_directory_ref (directory);
2351
NAUTILUS_FILE_ATTRIBUTES_FOR_ICON |
2352
NAUTILUS_FILE_ATTRIBUTE_INFO |
2353
NAUTILUS_FILE_ATTRIBUTE_DIRECTORY_ITEM_COUNT;
2355
nautilus_directory_file_monitor_add (directory, directory_list,
2357
(NautilusDirectoryCallback)changed_callback, view);
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);
2364
*directory_list = g_list_append (*directory_list, directory);
2369
remove_directory_from_directory_list (NautilusView *view,
2370
NautilusDirectory *directory,
2371
GList **directory_list,
2372
GCallback changed_callback)
2374
*directory_list = g_list_remove (*directory_list, directory);
2376
g_signal_handlers_disconnect_by_func (directory,
2377
G_CALLBACK (changed_callback),
2380
nautilus_directory_file_monitor_remove (directory, directory_list);
2382
nautilus_directory_unref (directory);
2387
add_directory_to_scripts_directory_list (NautilusView *view,
2388
NautilusDirectory *directory)
2390
add_directory_to_directory_list (view, directory,
2391
&view->details->scripts_directory_list,
2392
G_CALLBACK (scripts_added_or_changed_callback));
2396
remove_directory_from_scripts_directory_list (NautilusView *view,
2397
NautilusDirectory *directory)
2399
remove_directory_from_directory_list (view, directory,
2400
&view->details->scripts_directory_list,
2401
G_CALLBACK (scripts_added_or_changed_callback));
2405
add_directory_to_templates_directory_list (NautilusView *view,
2406
NautilusDirectory *directory)
2408
add_directory_to_directory_list (view, directory,
2409
&view->details->templates_directory_list,
2410
G_CALLBACK (templates_added_or_changed_callback));
2414
remove_directory_from_templates_directory_list (NautilusView *view,
2415
NautilusDirectory *directory)
2417
remove_directory_from_directory_list (view, directory,
2418
&view->details->templates_directory_list,
2419
G_CALLBACK (templates_added_or_changed_callback));
2423
slot_active (NautilusWindowSlot *slot,
2426
g_assert (!view->details->active);
2427
view->details->active = TRUE;
2429
nautilus_view_merge_menus (view);
2430
schedule_update_menus (view);
2434
slot_inactive (NautilusWindowSlot *slot,
2437
g_assert (view->details->active ||
2438
gtk_widget_get_parent (GTK_WIDGET (view)) == NULL);
2439
view->details->active = FALSE;
2441
nautilus_view_unmerge_menus (view);
2442
remove_update_menus_timeout_callback (view);
2446
nautilus_view_grab_focus (NautilusView *view)
2448
/* focus the child of the scrolled window if it exists */
2450
child = gtk_bin_get_child (GTK_BIN (view));
2452
gtk_widget_grab_focus (GTK_WIDGET (child));
2457
nautilus_view_get_selection_count (NautilusView *view)
2459
/* FIXME: This could be faster if we special cased it in subclasses */
2463
files = nautilus_view_get_selection (NAUTILUS_VIEW (view));
2464
len = g_list_length (files);
2465
nautilus_file_list_free (files);
2471
nautilus_view_set_selection (NautilusView *nautilus_view,
2476
view = NAUTILUS_VIEW (nautilus_view);
2478
if (!view->details->loading) {
2479
/* If we aren't still loading, set the selection right now,
2480
* and reveal the new selection.
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);
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.
2490
g_list_free_full (view->details->pending_selection, g_object_unref);
2491
view->details->pending_selection =
2492
eel_g_object_list_copy (selection);
2497
get_bulk_rename_tool ()
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);
2505
have_bulk_rename_tool ()
2507
char *bulk_rename_tool;
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);
2517
nautilus_view_init (NautilusView *view)
2519
NautilusDirectory *scripts_directory;
2520
NautilusDirectory *templates_directory;
2521
char *templates_uri;
2523
view->details = g_new0 (NautilusViewDetails, 1);
2525
/* Default to true; desktop-icon-view sets to false */
2526
view->details->show_foreign_files = TRUE;
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,
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);
2541
gtk_style_context_set_junction_sides (gtk_widget_get_style_context (GTK_WIDGET (view)),
2542
GTK_JUNCTION_TOP | GTK_JUNCTION_LEFT);
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);
2549
g_warning ("Ignoring scripts directory, it may be a broken link\n");
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);
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);
2565
view->details->sort_directories_first =
2566
g_settings_get_boolean (nautilus_preferences, NAUTILUS_PREFERENCES_SORT_DIRECTORIES_FIRST);
2568
g_signal_connect_object (nautilus_trash_monitor_get (), "trash_state_changed",
2569
G_CALLBACK (nautilus_view_trash_state_changed_callback), view, 0);
2571
/* React to clipboard changes */
2572
g_signal_connect_object (nautilus_clipboard_monitor_get (), "clipboard_changed",
2573
G_CALLBACK (clipboard_changed_callback), view, 0);
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);
2579
gtk_widget_show (GTK_WIDGET (view));
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),
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);
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);
2601
real_unmerge_menus (NautilusView *view)
2603
GtkUIManager *ui_manager;
2605
if (view->details->window == NULL) {
2609
ui_manager = nautilus_window_get_ui_manager (view->details->window);
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);
2629
nautilus_view_destroy (GtkWidget *object)
2634
view = NAUTILUS_VIEW (object);
2636
disconnect_model_handlers (view);
2638
nautilus_view_unmerge_menus (view);
2640
/* We don't own the window, so no unref */
2641
view->details->slot = NULL;
2642
view->details->window = NULL;
2644
nautilus_view_stop_loading (view);
2646
for (node = view->details->scripts_directory_list; node != NULL; node = next) {
2648
remove_directory_from_scripts_directory_list (view, node->data);
2651
for (node = view->details->templates_directory_list; node != NULL; node = next) {
2653
remove_directory_from_templates_directory_list (view, node->data);
2656
while (view->details->subdirectory_list != NULL) {
2657
nautilus_view_remove_subdirectory (view,
2658
view->details->subdirectory_list->data);
2661
remove_update_menus_timeout_callback (view);
2662
remove_update_status_idle_callback (view);
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;
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;
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;
2679
if (view->details->model) {
2680
nautilus_directory_unref (view->details->model);
2681
view->details->model = NULL;
2684
if (view->details->directory_as_file) {
2685
nautilus_file_unref (view->details->directory_as_file);
2686
view->details->directory_as_file = NULL;
2689
EEL_CALL_PARENT (GTK_WIDGET_CLASS, destroy, (object));
2693
nautilus_view_finalize (GObject *object)
2697
view = NAUTILUS_VIEW (object);
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);
2708
g_signal_handlers_disconnect_by_func (gnome_lockdown_preferences,
2709
schedule_update_menus, view);
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);
2716
g_hash_table_destroy (view->details->non_ready_files);
2718
g_free (view->details);
2720
EEL_CALL_PARENT (G_OBJECT_CLASS, finalize, (object));
2724
* nautilus_view_display_selection_info:
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.
2731
nautilus_view_display_selection_info (NautilusView *view)
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;
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;
2750
g_return_if_fail (NAUTILUS_IS_VIEW (view));
2752
selection = nautilus_view_get_selection (view);
2754
folder_item_count_known = TRUE;
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;
2769
for (p = selection; p != NULL; p = p->next) {
2771
if (nautilus_file_is_directory (file)) {
2773
if (nautilus_file_get_directory_item_count (file, &file_item_count, NULL)) {
2774
folder_item_count += file_item_count;
2776
folder_item_count_known = FALSE;
2780
if (!nautilus_file_can_get_size (file)) {
2781
non_folder_size_known = TRUE;
2782
non_folder_size += nautilus_file_get_size (file);
2786
if (first_item_name == NULL) {
2787
first_item_name = nautilus_file_get_display_name (file);
2791
nautilus_file_list_free (selection);
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.
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);
2801
folder_count_str = g_strdup_printf (ngettext("%'d folder selected",
2802
"%'d folders selected",
2807
if (folder_count == 1) {
2808
if (!folder_item_count_known) {
2809
folder_item_count_str = g_strdup ("");
2811
folder_item_count_str = g_strdup_printf (ngettext(" (containing %'d item)",
2812
" (containing %'d items)",
2818
if (!folder_item_count_known) {
2819
folder_item_count_str = g_strdup ("");
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)",
2831
if (non_folder_count != 0) {
2834
if (folder_count == 0) {
2835
if (non_folder_count == 1) {
2836
items_string = g_strdup_printf (_("\"%s\" selected"),
2839
items_string = g_strdup_printf (ngettext("%'d item selected",
2840
"%'d items selected",
2845
/* Folders selected also, use "other" terminology */
2846
items_string = g_strdup_printf (ngettext("%'d other item selected",
2847
"%'d other items selected",
2852
if (non_folder_size_known) {
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.
2861
non_folder_str = g_strdup_printf (_("%s (%s)"),
2865
g_free (size_string);
2866
g_free (items_string);
2868
non_folder_str = items_string;
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);
2876
if (folder_count == 0 && non_folder_count == 0) {
2877
char *item_count_str;
2880
item_count = nautilus_view_get_item_count (view);
2882
item_count_str = g_strdup_printf (ngettext ("%'u item", "%'u items", item_count), item_count);
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);
2888
status_string = item_count_str;
2891
} else if (folder_count == 0) {
2892
view_status_string = g_strdup (non_folder_str);
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
2900
status_string = g_strdup_printf (_("%s, %s"),
2902
obj_selected_free_space_str);
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
2909
view_status_string = g_strdup_printf ("%s%s",
2911
folder_item_count_str);
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
2919
status_string = g_strdup_printf (_("%s%s, %s"),
2921
folder_item_count_str,
2922
obj_selected_free_space_str);
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.
2932
view_status_string = g_strdup_printf (_("%s%s, %s"),
2934
folder_item_count_str,
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.
2946
status_string = g_strdup_printf (_("%s%s, %s, %s"),
2948
folder_item_count_str,
2950
obj_selected_free_space_str);
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);
2961
if (status_string == NULL) {
2962
status_string = g_strdup (view_status_string);
2965
nautilus_window_slot_set_status (view->details->slot,
2967
view_status_string);
2969
g_free (status_string);
2970
g_free (view_status_string);
2974
nautilus_view_send_selection_change (NautilusView *view)
2976
g_signal_emit (view, signals[SELECTION_CHANGED], 0);
2978
view->details->send_selection_change_to_shell = FALSE;
2982
nautilus_view_load_location (NautilusView *nautilus_view,
2985
NautilusDirectory *directory;
2986
NautilusView *directory_view;
2988
directory_view = NAUTILUS_VIEW (nautilus_view);
2990
directory = nautilus_directory_get (location);
2991
load_directory (directory_view, directory);
2992
nautilus_directory_unref (directory);
2996
reveal_selection_idle_callback (gpointer data)
3000
view = NAUTILUS_VIEW (data);
3002
view->details->reveal_selection_idle_id = 0;
3003
nautilus_view_reveal_selection (view);
3009
done_loading (NautilusView *view,
3010
gboolean all_files_seen)
3014
if (!view->details->loading) {
3018
/* This can be called during destruction, in which case there
3019
* is no NautilusWindow any more.
3021
if (view->details->window != NULL) {
3022
if (all_files_seen) {
3023
nautilus_window_report_load_complete (view->details->window, NAUTILUS_VIEW (view));
3026
schedule_update_menus (view);
3027
schedule_update_status (view);
3028
reset_update_interval (view);
3030
selection = view->details->pending_selection;
3031
if (selection != NULL && all_files_seen) {
3032
view->details->pending_selection = NULL;
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;
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.
3046
if (view->details->reveal_selection_idle_id != 0) {
3047
g_source_remove (view->details->reveal_selection_idle_id);
3049
view->details->reveal_selection_idle_id =
3050
g_idle_add (reveal_selection_idle_callback, view);
3052
nautilus_view_reveal_selection (view);
3055
g_list_free_full (selection, g_object_unref);
3056
nautilus_view_display_selection_info (view);
3059
g_signal_emit (view, signals[END_LOADING], 0, all_files_seen);
3061
view->details->loading = FALSE;
3066
GHashTable *debuting_files;
3068
} DebutingFilesData;
3071
debuting_files_data_free (DebutingFilesData *data)
3073
g_hash_table_unref (data->debuting_files);
3074
nautilus_file_list_free (data->added_files);
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.
3083
debuting_files_add_file_callback (NautilusView *view,
3084
NautilusFile *new_file,
3085
NautilusDirectory *directory,
3086
DebutingFilesData *data)
3090
location = nautilus_file_get_location (new_file);
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);
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),
3105
g_object_unref (location);
3110
NautilusView *directory_view;
3114
copy_move_done_data_free (CopyMoveDoneData *data)
3116
g_assert (data != NULL);
3118
eel_remove_weak_pointer (&data->directory_view);
3119
nautilus_file_list_free (data->added_files);
3124
pre_copy_move_add_file_callback (NautilusView *view,
3125
NautilusFile *new_file,
3126
NautilusDirectory *directory,
3127
CopyMoveDoneData *data)
3129
nautilus_file_ref (new_file);
3130
data->added_files = g_list_prepend (data->added_files, new_file);
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.
3138
static CopyMoveDoneData *
3139
pre_copy_move (NautilusView *directory_view)
3141
CopyMoveDoneData *copy_move_done_data;
3143
copy_move_done_data = g_new0 (CopyMoveDoneData, 1);
3144
copy_move_done_data->directory_view = directory_view;
3146
eel_add_weak_pointer (©_move_done_data->directory_view);
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.
3152
g_signal_connect (directory_view, "add_file",
3153
G_CALLBACK (pre_copy_move_add_file_callback), copy_move_done_data);
3155
return copy_move_done_data;
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.
3162
copy_move_done_partition_func (gpointer data, gpointer callback_data)
3167
location = nautilus_file_get_location (NAUTILUS_FILE (data));
3168
result = g_hash_table_remove ((GHashTable *) callback_data, location);
3169
g_object_unref (location);
3175
remove_not_really_moved_files (gpointer key,
3177
gpointer callback_data)
3179
GList **added_files;
3184
if (GPOINTER_TO_INT (value)) {
3188
added_files = callback_data;
3189
*added_files = g_list_prepend (*added_files,
3190
nautilus_file_get (loc));
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.
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.
3203
copy_move_done_callback (GHashTable *debuting_files, gpointer data)
3205
NautilusView *directory_view;
3206
CopyMoveDoneData *copy_move_done_data;
3207
DebutingFilesData *debuting_files_data;
3209
copy_move_done_data = (CopyMoveDoneData *) data;
3210
directory_view = copy_move_done_data->directory_view;
3212
if (directory_view != NULL) {
3213
g_assert (NAUTILUS_IS_VIEW (directory_view));
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,
3221
©_move_done_data->added_files);
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.
3227
g_signal_handlers_disconnect_by_func (directory_view,
3228
G_CALLBACK (pre_copy_move_add_file_callback),
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.
3236
g_hash_table_foreach_remove (debuting_files,
3237
remove_not_really_moved_files,
3238
&debuting_files_data->added_files);
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);
3247
debuting_files_data_free (debuting_files_data);
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.
3253
g_signal_connect_data (directory_view,
3255
G_CALLBACK (debuting_files_add_file_callback),
3256
debuting_files_data,
3257
(GClosureNotify) debuting_files_data_free,
3262
copy_move_done_data_free (copy_move_done_data);
3266
view_file_still_belongs (NautilusView *view,
3268
NautilusDirectory *directory)
3270
if (view->details->model != directory &&
3271
g_list_find (view->details->subdirectory_list, directory) == NULL) {
3275
return nautilus_directory_contains_file (directory, file);
3279
still_should_show_file (NautilusView *view, NautilusFile *file, NautilusDirectory *directory)
3281
return nautilus_view_should_show_file (view, file) &&
3282
view_file_still_belongs (view, file, directory);
3286
ready_to_load (NautilusFile *file)
3288
return nautilus_file_check_if_ready (file,
3289
NAUTILUS_FILE_ATTRIBUTES_FOR_ICON);
3293
compare_files_cover (gconstpointer a, gconstpointer b, gpointer callback_data)
3295
const FileAndDirectory *fad1, *fad2;
3298
view = callback_data;
3301
if (fad1->directory < fad2->directory) {
3303
} else if (fad1->directory > fad2->directory) {
3306
return EEL_INVOKE_METHOD (NAUTILUS_VIEW_CLASS, view, compare_files,
3307
(view, fad1->file, fad2->file));
3311
sort_files (NautilusView *view, GList **list)
3313
*list = g_list_sort_with_data (*list, compare_files_cover, view);
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.
3323
process_new_files (NautilusView *view)
3325
GList *new_added_files, *new_changed_files, *old_added_files, *old_changed_files;
3326
GHashTable *non_ready_files;
3328
FileAndDirectory *pending;
3329
gboolean in_non_ready;
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;
3336
non_ready_files = view->details->non_ready_files;
3338
old_added_files = view->details->old_added_files;
3339
old_changed_files = view->details->old_changed_files;
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.
3344
for (node = new_added_files; node != NULL; 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)) {
3351
g_hash_table_remove (non_ready_files, pending);
3353
new_added_files = g_list_delete_link (new_added_files, node);
3354
old_added_files = g_list_prepend (old_added_files, pending);
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);
3363
file_and_directory_list_free (new_added_files);
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.
3370
for (node = new_changed_files; node != NULL; 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);
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);
3386
file_and_directory_list_free (new_changed_files);
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);
3394
/* Resort old_changed_files too, since file attributes
3395
* relevant to sorting could have changed.
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);
3405
process_old_files (NautilusView *view)
3407
GList *files_added, *files_changed, *node;
3408
FileAndDirectory *pending;
3409
GList *selection, *files;
3410
gboolean send_selection_change;
3412
files_added = view->details->old_added_files;
3413
files_changed = view->details->old_changed_files;
3415
send_selection_change = FALSE;
3417
if (files_added != NULL || files_changed != NULL) {
3418
g_signal_emit (view, signals[BEGIN_FILE_CHANGES], 0);
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);
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);
3434
g_signal_emit (view, signals[END_FILE_CHANGES], 0);
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);
3445
file_and_directory_list_free (view->details->old_added_files);
3446
view->details->old_added_files = NULL;
3448
file_and_directory_list_free (view->details->old_changed_files);
3449
view->details->old_changed_files = NULL;
3452
if (send_selection_change) {
3453
/* Send a selection change since some file names could
3456
nautilus_view_send_selection_change (view);
3461
display_pending_files (NautilusView *view)
3464
/* Don't dispatch any updates while the view is frozen. */
3465
if (view->details->updates_frozen) {
3469
process_new_files (view);
3470
process_old_files (view);
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);
3480
nautilus_view_freeze_updates (NautilusView *view)
3482
view->details->updates_frozen = TRUE;
3483
view->details->updates_queued = 0;
3484
view->details->needs_reload = FALSE;
3488
nautilus_view_unfreeze_updates (NautilusView *view)
3490
view->details->updates_frozen = FALSE;
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);
3498
schedule_idle_display_of_pending_files (view);
3503
display_selection_info_idle_callback (gpointer data)
3507
view = NAUTILUS_VIEW (data);
3509
g_object_ref (G_OBJECT (view));
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);
3517
g_object_unref (G_OBJECT (view));
3523
remove_update_menus_timeout_callback (NautilusView *view)
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;
3532
update_menus_if_pending (NautilusView *view)
3534
if (!view->details->menu_states_untrustworthy) {
3538
remove_update_menus_timeout_callback (view);
3539
nautilus_view_update_menus (view);
3543
update_menus_timeout_callback (gpointer data)
3547
view = NAUTILUS_VIEW (data);
3549
g_object_ref (G_OBJECT (view));
3551
view->details->update_menus_timeout_id = 0;
3552
nautilus_view_update_menus (view);
3554
g_object_unref (G_OBJECT (view));
3560
display_pending_callback (gpointer data)
3564
view = NAUTILUS_VIEW (data);
3566
g_object_ref (G_OBJECT (view));
3568
view->details->display_pending_source_id = 0;
3570
display_pending_files (view);
3572
g_object_unref (G_OBJECT (view));
3578
schedule_idle_display_of_pending_files (NautilusView *view)
3580
/* Get rid of a pending source as it might be a timeout */
3581
unschedule_display_of_pending_files (view);
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);
3592
schedule_timeout_display_of_pending_files (NautilusView *view, guint interval)
3594
/* No need to schedule an update if there's already one pending. */
3595
if (view->details->display_pending_source_id != 0) {
3599
view->details->display_pending_source_id =
3600
g_timeout_add (interval, display_pending_callback, view);
3604
unschedule_display_of_pending_files (NautilusView *view)
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;
3614
queue_pending_files (NautilusView *view,
3615
NautilusDirectory *directory,
3617
GList **pending_list)
3619
if (files == NULL) {
3623
/* Don't queue any more updates if we need to reload anyway */
3624
if (view->details->needs_reload) {
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.
3633
if (view->details->updates_queued > MAX_QUEUED_UPDATES) {
3634
view->details->needs_reload = TRUE;
3641
*pending_list = g_list_concat (file_and_directory_list_from_files (directory, files),
3644
if (! view->details->loading || nautilus_directory_are_all_files_seen (directory)) {
3645
schedule_timeout_display_of_pending_files (view, view->details->update_interval);
3650
remove_changes_timeout_callback (NautilusView *view)
3652
if (view->details->changes_timeout_id != 0) {
3653
g_source_remove (view->details->changes_timeout_id);
3654
view->details->changes_timeout_id = 0;
3659
reset_update_interval (NautilusView *view)
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);
3670
changes_timeout_callback (gpointer data)
3677
view = NAUTILUS_VIEW (data);
3679
g_object_ref (G_OBJECT (view));
3681
now = eel_get_system_time();
3682
time_delta = now - view->details->last_queued;
3684
if (time_delta < UPDATE_INTERVAL_RESET*1000) {
3685
if (view->details->update_interval < UPDATE_INTERVAL_MAX &&
3686
view->details->loading) {
3688
view->details->update_interval += UPDATE_INTERVAL_INC;
3693
reset_update_interval (view);
3697
g_object_unref (G_OBJECT (view));
3703
schedule_changes (NautilusView *view)
3705
/* Remember when the change was queued */
3706
view->details->last_queued = eel_get_system_time();
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) {
3714
view->details->changes_timeout_id =
3715
g_timeout_add (UPDATE_INTERVAL_TIMEOUT_INTERVAL, changes_timeout_callback, view);
3719
files_added_callback (NautilusDirectory *directory,
3721
gpointer callback_data)
3727
view = NAUTILUS_VIEW (callback_data);
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)");
3735
schedule_changes (view);
3737
queue_pending_files (view, directory, files, &view->details->new_added_files);
3739
/* The number of items could have changed */
3740
schedule_update_status (view);
3744
files_changed_callback (NautilusDirectory *directory,
3746
gpointer callback_data)
3752
view = NAUTILUS_VIEW (callback_data);
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)");
3760
schedule_changes (view);
3762
queue_pending_files (view, directory, files, &view->details->new_changed_files);
3764
/* The free space or the number of items could have changed */
3765
schedule_update_status (view);
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.
3770
schedule_update_menus (view);
3774
done_loading_callback (NautilusDirectory *directory,
3775
gpointer callback_data)
3779
view = NAUTILUS_VIEW (callback_data);
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.
3787
unschedule_display_of_pending_files (view);
3788
schedule_timeout_display_of_pending_files (view, UPDATE_INTERVAL_MIN);
3793
load_error_callback (NautilusDirectory *directory,
3795
gpointer callback_data)
3799
view = NAUTILUS_VIEW (callback_data);
3801
/* FIXME: By doing a stop, we discard some pending files. Is
3804
nautilus_view_stop_loading (view);
3806
/* Emit a signal to tell subclasses that a load error has
3807
* occurred, so they can handle it in the UI.
3809
g_signal_emit (view,
3810
signals[LOAD_ERROR], 0, error);
3814
real_load_error (NautilusView *view, GError *error)
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
3822
if (!view->details->reported_load_error) {
3823
nautilus_report_error_loading_directory
3824
(nautilus_view_get_directory_as_file (view),
3826
nautilus_view_get_containing_window (view));
3828
view->details->reported_load_error = TRUE;
3832
nautilus_view_add_subdirectory (NautilusView *view,
3833
NautilusDirectory*directory)
3835
NautilusFileAttributes attributes;
3837
g_assert (!g_list_find (view->details->subdirectory_list, directory));
3839
nautilus_directory_ref (directory);
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;
3849
nautilus_directory_file_monitor_add (directory,
3850
&view->details->model,
3851
view->details->show_hidden_files,
3853
files_added_callback, view);
3856
(directory, "files_added",
3857
G_CALLBACK (files_added_callback), view);
3859
(directory, "files_changed",
3860
G_CALLBACK (files_changed_callback), view);
3862
view->details->subdirectory_list = g_list_prepend (
3863
view->details->subdirectory_list, directory);
3867
nautilus_view_remove_subdirectory (NautilusView *view,
3868
NautilusDirectory*directory)
3870
g_assert (g_list_find (view->details->subdirectory_list, directory));
3872
view->details->subdirectory_list = g_list_remove (
3873
view->details->subdirectory_list, directory);
3875
g_signal_handlers_disconnect_by_func (directory,
3876
G_CALLBACK (files_added_callback),
3878
g_signal_handlers_disconnect_by_func (directory,
3879
G_CALLBACK (files_changed_callback),
3882
nautilus_directory_file_monitor_remove (directory, &view->details->model);
3884
nautilus_directory_unref (directory);
3888
* nautilus_view_get_loading:
3889
* @view: an #NautilusView.
3891
* Return value: #gboolean inicating whether @view is currently loaded.
3895
nautilus_view_get_loading (NautilusView *view)
3897
g_return_val_if_fail (NAUTILUS_IS_VIEW (view), FALSE);
3899
return view->details->loading;
3903
nautilus_view_get_ui_manager (NautilusView *view)
3905
if (view->details->window == NULL) {
3908
return nautilus_window_get_ui_manager (view->details->window);
3912
* nautilus_view_get_model:
3914
* Get the model for this NautilusView.
3915
* @view: NautilusView of interest.
3917
* Return value: NautilusDirectory for this view.
3921
nautilus_view_get_model (NautilusView *view)
3923
g_return_val_if_fail (NAUTILUS_IS_VIEW (view), NULL);
3925
return view->details->model;
3929
nautilus_view_get_copied_files_atom (NautilusView *view)
3931
g_return_val_if_fail (NAUTILUS_IS_VIEW (view), GDK_NONE);
3933
return copied_files_atom;
3937
prepend_uri_one (gpointer data, gpointer callback_data)
3942
g_assert (NAUTILUS_IS_FILE (data));
3943
g_assert (callback_data != NULL);
3945
result = (GList **) callback_data;
3946
file = (NautilusFile *) data;
3947
*result = g_list_prepend (*result, nautilus_file_get_uri (file));
3951
offset_drop_points (GArray *relative_item_points,
3952
int x_offset, int y_offset)
3956
if (relative_item_points == NULL) {
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;
3967
nautilus_view_create_links_for_files (NautilusView *view, GList *files,
3968
GArray *relative_item_points)
3972
CopyMoveDoneData *copy_move_done_data;
3973
g_assert (relative_item_points->len == 0
3974
|| g_list_length (files) == relative_item_points->len);
3976
g_assert (NAUTILUS_IS_VIEW (view));
3977
g_assert (files != NULL);
3979
/* create a list of URIs */
3981
g_list_foreach (files, prepend_uri_one, &uris);
3982
uris = g_list_reverse (uris);
3984
g_assert (g_list_length (uris) == g_list_length (files));
3986
/* offset the drop locations a bit so that we don't pile
3987
* up the icons on top of each other
3989
offset_drop_points (relative_item_points,
3990
DUPLICATE_HORIZONTAL_ICON_OFFSET,
3991
DUPLICATE_VERTICAL_ICON_OFFSET);
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);
3998
g_list_free_full (uris, g_free);
4002
nautilus_view_duplicate_selection (NautilusView *view, GList *files,
4003
GArray *relative_item_points)
4006
CopyMoveDoneData *copy_move_done_data;
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);
4013
/* create a list of URIs */
4015
g_list_foreach (files, prepend_uri_one, &uris);
4016
uris = g_list_reverse (uris);
4018
g_assert (g_list_length (uris) == g_list_length (files));
4020
/* offset the drop locations a bit so that we don't pile
4021
* up the icons on top of each other
4023
offset_drop_points (relative_item_points,
4024
DUPLICATE_HORIZONTAL_ICON_OFFSET,
4025
DUPLICATE_VERTICAL_ICON_OFFSET);
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);
4033
/* special_link_in_selection
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
4041
special_link_in_selection (NautilusView *view)
4044
GList *selection, *node;
4047
g_return_val_if_fail (NAUTILUS_IS_VIEW (view), FALSE);
4051
selection = nautilus_view_get_selection (NAUTILUS_VIEW (view));
4053
for (node = selection; node != NULL; node = node->next) {
4054
file = NAUTILUS_FILE (node->data);
4056
saw_link = NAUTILUS_IS_DESKTOP_ICON_FILE (file);
4063
nautilus_file_list_free (selection);
4068
/* desktop_or_home_dir_in_selection
4070
* Return TRUE if either the desktop or the home directory is in the selection.
4074
desktop_or_home_dir_in_selection (NautilusView *view)
4076
gboolean saw_desktop_or_home_dir;
4077
GList *selection, *node;
4080
g_return_val_if_fail (NAUTILUS_IS_VIEW (view), FALSE);
4082
saw_desktop_or_home_dir = FALSE;
4084
selection = nautilus_view_get_selection (NAUTILUS_VIEW (view));
4086
for (node = selection; node != NULL; node = node->next) {
4087
file = NAUTILUS_FILE (node->data);
4089
saw_desktop_or_home_dir =
4090
nautilus_file_is_home (file)
4091
|| nautilus_file_is_desktop_directory (file);
4093
if (saw_desktop_or_home_dir) {
4098
nautilus_file_list_free (selection);
4100
return saw_desktop_or_home_dir;
4104
trash_or_delete_done_cb (GHashTable *debuting_uris,
4105
gboolean user_cancel,
4109
view->details->selection_was_removed = FALSE;
4114
trash_or_delete_files (GtkWindow *parent_window,
4116
gboolean delete_if_all_already_in_trash,
4123
for (node = files; node != NULL; node = node->next) {
4124
locations = g_list_prepend (locations,
4125
nautilus_file_get_location ((NautilusFile *) node->data));
4128
locations = g_list_reverse (locations);
4130
nautilus_file_operations_trash_or_delete (locations,
4132
(NautilusDeleteCallback) trash_or_delete_done_cb,
4134
g_list_free_full (locations, g_object_unref);
4138
can_rename_file (NautilusView *view, NautilusFile *file)
4140
return nautilus_file_can_rename (file);
4144
start_renaming_file (NautilusView *view,
4146
gboolean select_all)
4149
nautilus_view_select_file (view, file);
4154
update_context_menu_position_from_event (NautilusView *view,
4155
GdkEventButton *event)
4157
g_return_if_fail (NAUTILUS_IS_VIEW (view));
4159
if (event != NULL) {
4160
view->details->context_menu_position.x = event->x;
4161
view->details->context_menu_position.y = event->y;
4163
view->details->context_menu_position.x = -1;
4164
view->details->context_menu_position.y = -1;
4168
/* handle the open command */
4171
open_one_in_new_window (gpointer data, gpointer callback_data)
4173
g_assert (NAUTILUS_IS_FILE (data));
4174
g_assert (NAUTILUS_IS_VIEW (callback_data));
4176
nautilus_view_activate_file (NAUTILUS_VIEW (callback_data),
4177
NAUTILUS_FILE (data),
4178
NAUTILUS_WINDOW_OPEN_FLAG_NEW_WINDOW);
4182
nautilus_view_get_directory_as_file (NautilusView *view)
4184
g_assert (NAUTILUS_IS_VIEW (view));
4186
return view->details->directory_as_file;
4190
open_with_launch_application_callback (GtkAction *action,
4191
gpointer callback_data)
4193
ApplicationLaunchParameters *launch_parameters;
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));
4203
escape_action_name (const char *action_name,
4208
if (action_name == NULL) {
4212
s = g_string_new (prefix);
4214
while (*action_name != 0) {
4215
switch (*action_name) {
4217
g_string_append (s, "\\\\");
4220
g_string_append (s, "\\s");
4223
g_string_append (s, "\\a");
4226
g_string_append (s, "\\q");
4229
g_string_append_c (s, *action_name);
4234
return g_string_free (s, FALSE);
4238
escape_action_path (const char *action_path)
4242
if (action_path == NULL) {
4246
s = g_string_sized_new (strlen (action_path) + 2);
4248
while (*action_path != 0) {
4249
switch (*action_path) {
4251
g_string_append (s, "\\\\");
4254
g_string_append (s, "\\a");
4257
g_string_append (s, "\\q");
4260
g_string_append_c (s, *action_path);
4265
return g_string_free (s, FALSE);
4270
add_submenu (GtkUIManager *ui_manager,
4271
GtkActionGroup *action_group,
4273
const char *parent_path,
4277
gboolean add_action)
4279
char *escaped_label;
4282
char *escaped_submenu_name;
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);
4292
action = gtk_action_new (action_name,
4296
if (pixbuf != NULL) {
4297
g_object_set_data_full (G_OBJECT (action), "menu-icon",
4298
g_object_ref (pixbuf),
4302
g_object_set (action, "hide-if-empty", FALSE, NULL);
4304
gtk_action_group_add_action (action_group,
4306
g_object_unref (action);
4309
gtk_ui_manager_add_ui (ui_manager,
4312
escaped_submenu_name,
4314
GTK_UI_MANAGER_MENU,
4316
g_free (action_name);
4317
g_free (escaped_label);
4318
g_free (submenu_name);
4319
g_free (escaped_submenu_name);
4324
add_application_to_open_with_menu (NautilusView *view,
4325
GAppInfo *application,
4328
const char *menu_placeholder,
4329
const char *popup_placeholder,
4330
const gboolean submenu)
4332
ApplicationLaunchParameters *launch_parameters;
4340
GtkWidget *menuitem;
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));
4346
label = g_strdup_printf ("%s", escaped_app);
4348
label = g_strdup_printf (_("Open With %s"), escaped_app);
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)),
4354
g_free (escaped_app);
4356
action_name = g_strdup_printf ("open_with_%d", index);
4358
action = gtk_action_new (action_name,
4363
app_icon = g_app_info_get_icon (application);
4364
if (app_icon != NULL) {
4365
g_object_ref (app_icon);
4367
app_icon = g_themed_icon_new ("application-x-executable");
4370
gtk_action_set_gicon (action, app_icon);
4371
g_object_unref (app_icon);
4373
g_signal_connect_data (action, "activate",
4374
G_CALLBACK (open_with_launch_application_callback),
4376
(GClosureNotify)application_launch_parameters_free, 0);
4378
gtk_action_group_add_action (view->details->open_with_action_group,
4380
g_object_unref (action);
4382
gtk_ui_manager_add_ui (nautilus_window_get_ui_manager (view->details->window),
4383
view->details->open_with_merge_id,
4387
GTK_UI_MANAGER_MENUITEM,
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),
4394
gtk_image_menu_item_set_always_show_image (GTK_IMAGE_MENU_ITEM (menuitem), TRUE);
4397
gtk_ui_manager_add_ui (nautilus_window_get_ui_manager (view->details->window),
4398
view->details->open_with_merge_id,
4402
GTK_UI_MANAGER_MENUITEM,
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),
4409
gtk_image_menu_item_set_always_show_image (GTK_IMAGE_MENU_ITEM (menuitem), TRUE);
4412
g_free (action_name);
4418
get_x_content_async_callback (const char **content,
4423
view = NAUTILUS_VIEW (user_data);
4425
if (view->details->window != NULL) {
4426
schedule_update_menus (view);
4428
g_object_unref (view);
4432
add_x_content_apps (NautilusView *view, NautilusFile *file, GList **applications)
4435
char **x_content_types;
4438
g_return_if_fail (applications != NULL);
4440
mount = nautilus_file_get_mount (file);
4442
if (mount == NULL) {
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;
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);
4455
g_strfreev (x_content_types);
4457
nautilus_get_x_content_types_for_mount_async (mount,
4458
get_x_content_async_callback,
4460
g_object_ref (view));
4464
g_object_unref (mount);
4468
reset_open_with_menu (NautilusView *view, GList *selection)
4470
GList *applications, *node;
4472
gboolean submenu_visible, filter_default;
4473
int num_applications;
4475
gboolean other_applications_visible;
4476
gboolean open_with_chooser_visible;
4477
GtkUIManager *ui_manager;
4479
GAppInfo *default_app;
4481
/* Clear any previous inserted items in the applications and viewers placeholders */
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);
4488
nautilus_ui_prepare_merge_ui (ui_manager,
4490
&view->details->open_with_merge_id,
4491
&view->details->open_with_action_group);
4493
num_applications = 0;
4495
other_applications_visible = (selection != NULL);
4496
filter_default = (selection != NULL);
4498
for (node = selection; node != NULL; node = node->next) {
4500
file = NAUTILUS_FILE (node->data);
4502
other_applications_visible &=
4503
(!nautilus_mime_file_opens_in_view (file) ||
4504
nautilus_file_is_directory (file));
4508
if (filter_default) {
4509
default_app = nautilus_mime_get_default_application_for_files (selection);
4512
applications = NULL;
4513
if (other_applications_visible) {
4514
applications = nautilus_mime_get_applications_for_files (selection);
4517
if (g_list_length (selection) == 1) {
4518
add_x_content_apps (view, NAUTILUS_FILE (selection->data), &applications);
4522
num_applications = g_list_length (applications);
4524
if (file_list_all_are_folders (selection)) {
4525
submenu_visible = (num_applications > 2);
4527
submenu_visible = (num_applications > 3);
4530
for (node = applications, index = 0; node != NULL; node = node->next, index++) {
4531
GAppInfo *application;
4535
application = node->data;
4537
if (default_app != NULL && g_app_info_equal (default_app, application)) {
4541
if (submenu_visible) {
4542
menu_path = NAUTILUS_VIEW_MENU_PATH_APPLICATIONS_SUBMENU_PLACEHOLDER;
4543
popup_path = NAUTILUS_VIEW_POPUP_PATH_APPLICATIONS_SUBMENU_PLACEHOLDER;
4545
menu_path = NAUTILUS_VIEW_MENU_PATH_APPLICATIONS_PLACEHOLDER;
4546
popup_path = NAUTILUS_VIEW_POPUP_PATH_APPLICATIONS_PLACEHOLDER;
4549
gtk_ui_manager_add_ui (nautilus_window_get_ui_manager (view->details->window),
4550
view->details->open_with_merge_id,
4554
GTK_UI_MANAGER_SEPARATOR,
4557
add_application_to_open_with_menu (view,
4561
menu_path, popup_path, submenu_visible);
4563
g_list_free_full (applications, g_object_unref);
4564
if (default_app != NULL) {
4565
g_object_unref (default_app);
4568
open_with_chooser_visible = other_applications_visible &&
4569
g_list_length (selection) == 1;
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);
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);
4589
get_all_extension_menu_items (GtkWidget *window,
4596
providers = nautilus_module_get_extensions_for_type (NAUTILUS_TYPE_MENU_PROVIDER);
4599
for (l = providers; l != NULL; l = l->next) {
4600
NautilusMenuProvider *provider;
4603
provider = NAUTILUS_MENU_PROVIDER (l->data);
4604
file_items = nautilus_menu_provider_get_file_items (provider,
4607
items = g_list_concat (items, file_items);
4610
nautilus_module_extension_list_free (providers);
4617
NautilusMenuItem *item;
4621
} ExtensionActionCallbackData;
4625
extension_action_callback_data_free (ExtensionActionCallbackData *data)
4627
g_object_unref (data->item);
4628
nautilus_file_list_free (data->selection);
4634
search_in_menu_items (GList* items, const char *item_name)
4638
for (list = items; list != NULL; list = list->next) {
4642
g_object_get (list->data, "name", &name, NULL);
4643
if (strcmp (name, item_name) == 0) {
4650
g_object_get (list->data, "menu", &menu, NULL);
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);
4668
extension_action_callback (GtkAction *action,
4669
gpointer callback_data)
4671
ExtensionActionCallbackData *data;
4677
data = callback_data;
4679
/* Make sure the selected menu item is valid for the final sniffed
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)),
4685
is_valid = search_in_menu_items (items, item_name);
4687
for (l = items; l != NULL; l = l->next) {
4688
g_object_unref (l->data);
4690
g_list_free (items);
4695
nautilus_menu_item_activate (data->item);
4700
get_menu_icon (const char *icon_name)
4702
NautilusIconInfo *info;
4706
size = nautilus_get_icon_size_for_stock_size (GTK_ICON_SIZE_MENU);
4708
if (g_path_is_absolute (icon_name)) {
4709
info = nautilus_icon_info_lookup_from_path (icon_name, size);
4711
info = nautilus_icon_info_lookup_from_name (icon_name, size);
4713
pixbuf = nautilus_icon_info_get_pixbuf_nodefault_at_size (info, size);
4714
g_object_unref (info);
4720
get_menu_icon_for_file (NautilusFile *file)
4722
NautilusIconInfo *info;
4726
size = nautilus_get_icon_size_for_stock_size (GTK_ICON_SIZE_MENU);
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);
4736
add_extension_action_for_files (NautilusView *view,
4737
NautilusMenuItem *item,
4740
char *name, *label, *tip, *icon;
4741
gboolean sensitive, priority;
4744
ExtensionActionCallbackData *data;
4746
g_object_get (G_OBJECT (item),
4747
"name", &name, "label", &label,
4748
"tip", &tip, "icon", &icon,
4749
"sensitive", &sensitive,
4750
"priority", &priority,
4753
action = gtk_action_new (name,
4759
pixbuf = get_menu_icon (icon);
4760
if (pixbuf != NULL) {
4761
g_object_set_data_full (G_OBJECT (action), "menu-icon",
4767
gtk_action_set_sensitive (action, sensitive);
4768
g_object_set (action, "is-important", priority, NULL);
4770
data = g_new0 (ExtensionActionCallbackData, 1);
4771
data->item = g_object_ref (item);
4773
data->selection = nautilus_file_list_copy (files);
4774
data->action = action;
4776
g_signal_connect_data (action, "activate",
4777
G_CALLBACK (extension_action_callback),
4779
(GClosureNotify)extension_action_callback_data_free, 0);
4781
gtk_action_group_add_action (view->details->extensions_menu_action_group,
4782
GTK_ACTION (action));
4783
g_object_unref (action);
4794
add_extension_menu_items (NautilusView *view,
4797
const char *subdirectory)
4799
GtkUIManager *ui_manager;
4802
ui_manager = nautilus_window_get_ui_manager (view->details->window);
4804
for (l = menu_items; l; l = l->next) {
4805
NautilusMenuItem *item;
4810
item = NAUTILUS_MENU_ITEM (l->data);
4812
g_object_get (item, "menu", &menu, NULL);
4814
action = add_extension_action_for_files (view, item, files);
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,
4820
gtk_action_get_name (action),
4821
gtk_action_get_name (action),
4822
(menu != NULL) ? GTK_UI_MANAGER_MENU : GTK_UI_MANAGER_MENUITEM,
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,
4830
gtk_action_get_name (action),
4831
gtk_action_get_name (action),
4832
(menu != NULL) ? GTK_UI_MANAGER_MENU : GTK_UI_MANAGER_MENUITEM,
4836
/* recursively fill the menu */
4841
children = nautilus_menu_get_items (menu);
4843
subdir = g_build_path ("/", subdirectory, gtk_action_get_name (action), NULL);
4844
add_extension_menu_items (view,
4849
nautilus_menu_item_list_free (children);
4856
reset_extension_actions_menu (NautilusView *view, GList *selection)
4859
GtkUIManager *ui_manager;
4861
/* Clear any previous inserted items in the extension actions placeholder */
4862
ui_manager = nautilus_window_get_ui_manager (view->details->window);
4864
nautilus_ui_unmerge_ui (ui_manager,
4865
&view->details->extensions_menu_merge_id,
4866
&view->details->extensions_menu_action_group);
4868
nautilus_ui_prepare_merge_ui (ui_manager,
4869
"DirExtensionsMenuGroup",
4870
&view->details->extensions_menu_merge_id,
4871
&view->details->extensions_menu_action_group);
4873
items = get_all_extension_menu_items (gtk_widget_get_toplevel (GTK_WIDGET (view)),
4875
if (items != NULL) {
4876
add_extension_menu_items (view, selection, items, "");
4878
g_list_foreach (items, (GFunc) g_object_unref, NULL);
4879
g_list_free (items);
4884
change_to_view_directory (NautilusView *view)
4889
old_path = g_get_current_dir ();
4891
path = get_view_directory (view);
4893
/* FIXME: What to do about non-local directories? */
4904
get_file_names_as_parameter_array (GList *selection,
4905
NautilusDirectory *model)
4910
GFile *file_location;
4911
GFile *model_location;
4914
if (model == NULL) {
4918
parameters = g_new (char *, g_list_length (selection) + 1);
4920
model_location = nautilus_directory_get_location (model);
4922
for (node = selection, i = 0; node != NULL; node = node->next, i++) {
4923
file = NAUTILUS_FILE (node->data);
4925
if (!nautilus_file_is_local (file)) {
4926
parameters[i] = NULL;
4927
g_strfreev (parameters);
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);
4936
g_object_unref (file_location);
4939
g_object_unref (model_location);
4941
parameters[i] = NULL;
4946
get_file_paths_or_uris_as_newline_delimited_string (GList *selection, gboolean get_paths)
4951
NautilusDesktopLink *link;
4952
GString *expanding_string;
4956
expanding_string = g_string_new ("");
4957
for (node = selection; node != NULL; node = node->next) {
4959
if (NAUTILUS_IS_DESKTOP_ICON_FILE (node->data)) {
4960
link = nautilus_desktop_icon_file_get_link (NAUTILUS_DESKTOP_ICON_FILE (node->data));
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));
4968
uri = nautilus_file_get_uri (NAUTILUS_FILE (node->data));
4975
path = g_filename_from_uri (uri, NULL, NULL);
4977
g_string_append (expanding_string, path);
4979
g_string_append (expanding_string, "\n");
4982
g_string_append (expanding_string, uri);
4983
g_string_append (expanding_string, "\n");
4988
result = expanding_string->str;
4989
g_string_free (expanding_string, FALSE);
4995
get_file_paths_as_newline_delimited_string (GList *selection)
4997
return get_file_paths_or_uris_as_newline_delimited_string (selection, TRUE);
5001
get_file_uris_as_newline_delimited_string (GList *selection)
5003
return get_file_paths_or_uris_as_newline_delimited_string (selection, FALSE);
5006
/* returns newly allocated strings for setting the environment variables */
5008
get_strings_for_environment_variables (NautilusView *view, GList *selected_files,
5009
char **file_paths, char **uris, char **uri)
5011
char *directory_uri;
5013
/* We need to check that the directory uri starts with "file:" since
5014
* nautilus_directory_is_local returns FALSE for nfs.
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);
5022
*file_paths = g_strdup ("");
5024
g_free (directory_uri);
5026
*uris = get_file_uris_as_newline_delimited_string (selected_files);
5028
*uri = nautilus_directory_get_uri (view->details->model);
5029
if (eel_uri_is_desktop (*uri)) {
5031
*uri = nautilus_get_desktop_directory_uri ();
5035
static NautilusView *
5036
get_directory_view_of_extra_pane (NautilusView *view)
5038
NautilusWindowSlot *slot;
5039
NautilusView *next_view;
5041
slot = nautilus_window_get_extra_slot (nautilus_view_get_nautilus_window (view));
5043
next_view = nautilus_window_slot_get_current_view (slot);
5045
if (NAUTILUS_IS_VIEW (next_view)) {
5046
return NAUTILUS_VIEW (next_view);
5053
* Set up some environment variables that scripts can use
5054
* to take advantage of the current Nautilus state.
5057
set_script_environment_variables (NautilusView *view, GList *selected_files)
5062
char *geometry_string;
5063
NautilusView *next_view;
5065
get_strings_for_environment_variables (view, selected_files,
5066
&file_paths, &uris, &uri);
5068
g_setenv ("NAUTILUS_SCRIPT_SELECTED_FILE_PATHS", file_paths, TRUE);
5069
g_free (file_paths);
5071
g_setenv ("NAUTILUS_SCRIPT_SELECTED_URIS", uris, TRUE);
5074
g_setenv ("NAUTILUS_SCRIPT_CURRENT_URI", uri, TRUE);
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);
5083
next_view = get_directory_view_of_extra_pane (view);
5085
GList *next_pane_selected_files;
5086
next_pane_selected_files = nautilus_view_get_selection (next_view);
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);
5092
file_paths = g_strdup("");
5093
uris = g_strdup("");
5097
g_setenv ("NAUTILUS_SCRIPT_NEXT_PANE_SELECTED_FILE_PATHS", file_paths, TRUE);
5098
g_free (file_paths);
5100
g_setenv ("NAUTILUS_SCRIPT_NEXT_PANE_SELECTED_URIS", uris, TRUE);
5103
g_setenv ("NAUTILUS_SCRIPT_NEXT_PANE_CURRENT_URI", uri, TRUE);
5107
/* Unset all the special script environment variables. */
5109
unset_script_environment_variables (void)
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");
5121
run_script_callback (GtkAction *action, gpointer callback_data)
5123
ScriptLaunchParameters *launch_parameters;
5125
GList *selected_files;
5127
char *local_file_path;
5129
char *old_working_dir;
5132
launch_parameters = (ScriptLaunchParameters *) callback_data;
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);
5139
quoted_path = g_shell_quote (local_file_path);
5140
g_free (local_file_path);
5142
old_working_dir = change_to_view_directory (launch_parameters->directory_view);
5144
selected_files = nautilus_view_get_selection (launch_parameters->directory_view);
5145
set_script_environment_variables (launch_parameters->directory_view, selected_files);
5147
parameters = get_file_names_as_parameter_array (selected_files,
5148
launch_parameters->directory_view->details->model);
5150
screen = gtk_widget_get_screen (GTK_WIDGET (launch_parameters->directory_view));
5152
DEBUG ("run_script_callback, script_path=\"%s\" (omitting script parameters)",
5155
nautilus_launch_application_from_command_array (screen, quoted_path, FALSE,
5156
(const char * const *) parameters);
5157
g_strfreev (parameters);
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);
5167
add_script_to_scripts_menus (NautilusView *directory_view,
5169
const char *menu_path,
5170
const char *popup_path,
5171
const char *popup_bg_path)
5173
ScriptLaunchParameters *launch_parameters;
5178
char *escaped_label;
5180
GtkUIManager *ui_manager;
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);
5187
launch_parameters = script_launch_parameters_new (file, directory_view);
5189
action_name = escape_action_name (uri, "script_");
5190
escaped_label = eel_str_double_underscores (name);
5192
action = gtk_action_new (action_name,
5197
pixbuf = get_menu_icon_for_file (file);
5198
if (pixbuf != NULL) {
5199
g_object_set_data_full (G_OBJECT (action), "menu-icon",
5204
g_signal_connect_data (action, "activate",
5205
G_CALLBACK (run_script_callback),
5207
(GClosureNotify)script_launch_parameters_free, 0);
5209
gtk_action_group_add_action_with_accel (directory_view->details->scripts_action_group,
5211
g_object_unref (action);
5213
ui_manager = nautilus_window_get_ui_manager (directory_view->details->window);
5215
gtk_ui_manager_add_ui (ui_manager,
5216
directory_view->details->scripts_merge_id,
5220
GTK_UI_MANAGER_MENUITEM,
5222
gtk_ui_manager_add_ui (ui_manager,
5223
directory_view->details->scripts_merge_id,
5227
GTK_UI_MANAGER_MENUITEM,
5229
gtk_ui_manager_add_ui (ui_manager,
5230
directory_view->details->scripts_merge_id,
5234
GTK_UI_MANAGER_MENUITEM,
5240
g_free (action_name);
5241
g_free (escaped_label);
5245
add_submenu_to_directory_menus (NautilusView *directory_view,
5246
GtkActionGroup *action_group,
5249
const char *menu_path,
5250
const char *popup_path,
5251
const char *popup_bg_path)
5256
GtkUIManager *ui_manager;
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);
5266
g_object_unref (pixbuf);
5273
directory_belongs_in_scripts_menu (const char *uri)
5278
if (!eel_str_has_prefix (uri, scripts_directory_uri)) {
5283
for (i = scripts_directory_uri_length; uri[i] != '\0'; i++) {
5284
if (uri[i] == '/') {
5289
if (num_levels > MAX_MENU_LEVELS) {
5297
update_directory_in_scripts_menu (NautilusView *view, NautilusDirectory *directory)
5299
char *menu_path, *popup_path, *popup_bg_path;
5300
GList *file_list, *filtered, *node;
5301
gboolean any_scripts;
5303
NautilusDirectory *dir;
5307
uri = nautilus_directory_get_uri (directory);
5308
escaped_path = escape_action_path (uri + scripts_directory_uri_length);
5310
menu_path = g_strconcat (NAUTILUS_VIEW_MENU_PATH_SCRIPTS_PLACEHOLDER,
5313
popup_path = g_strconcat (NAUTILUS_VIEW_POPUP_PATH_SCRIPTS_PLACEHOLDER,
5316
popup_bg_path = g_strconcat (NAUTILUS_VIEW_POPUP_PATH_BACKGROUND_SCRIPTS_PLACEHOLDER,
5319
g_free (escaped_path);
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);
5325
file_list = nautilus_file_list_sort_by_display_name (filtered);
5327
any_scripts = FALSE;
5328
for (node = file_list; node != NULL; node = node->next) {
5331
if (nautilus_file_is_launchable (file)) {
5332
add_script_to_scripts_menus (view, file, menu_path, popup_path, popup_bg_path);
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);
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);
5352
nautilus_file_list_free (file_list);
5354
g_free (popup_path);
5355
g_free (popup_bg_path);
5362
update_scripts_menu (NautilusView *view)
5364
gboolean any_scripts;
5365
GList *sorted_copy, *node;
5366
NautilusDirectory *directory;
5368
GtkUIManager *ui_manager;
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;
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);
5381
nautilus_ui_prepare_merge_ui (ui_manager,
5383
&view->details->scripts_merge_id,
5384
&view->details->scripts_action_group);
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;
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)) {
5401
nautilus_directory_list_free (sorted_copy);
5403
action = gtk_action_group_get_action (view->details->dir_action_group, NAUTILUS_ACTION_SCRIPTS);
5404
gtk_action_set_visible (action, any_scripts);
5408
create_template_callback (GtkAction *action, gpointer callback_data)
5410
CreateTemplateParameters *parameters;
5412
parameters = callback_data;
5414
nautilus_view_new_file (parameters->directory_view, NULL, parameters->file);
5418
add_template_to_templates_menus (NautilusView *directory_view,
5420
const char *menu_path,
5421
const char *popup_bg_path)
5423
char *tmp, *tip, *uri, *name;
5424
char *escaped_label;
5427
CreateTemplateParameters *parameters;
5428
GtkUIManager *ui_manager;
5431
tmp = nautilus_file_get_display_name (file);
5432
name = eel_filename_strip_extension (tmp);
5435
uri = nautilus_file_get_uri (file);
5436
tip = g_strdup_printf (_("Create a new document from template \"%s\""), name);
5438
action_name = escape_action_name (uri, "template_");
5439
escaped_label = eel_str_double_underscores (name);
5441
parameters = create_template_parameters_new (file, directory_view);
5443
action = gtk_action_new (action_name,
5448
pixbuf = get_menu_icon_for_file (file);
5449
if (pixbuf != NULL) {
5450
g_object_set_data_full (G_OBJECT (action), "menu-icon",
5455
g_signal_connect_data (action, "activate",
5456
G_CALLBACK (create_template_callback),
5458
(GClosureNotify)create_templates_parameters_free, 0);
5460
gtk_action_group_add_action (directory_view->details->templates_action_group,
5462
g_object_unref (action);
5464
ui_manager = nautilus_window_get_ui_manager (directory_view->details->window);
5466
gtk_ui_manager_add_ui (ui_manager,
5467
directory_view->details->templates_merge_id,
5471
GTK_UI_MANAGER_MENUITEM,
5474
gtk_ui_manager_add_ui (ui_manager,
5475
directory_view->details->templates_merge_id,
5479
GTK_UI_MANAGER_MENUITEM,
5482
g_free (escaped_label);
5486
g_free (action_name);
5490
update_templates_directory (NautilusView *view)
5492
NautilusDirectory *templates_directory;
5494
char *templates_uri;
5496
for (node = view->details->templates_directory_list; node != NULL; node = next) {
5498
remove_directory_from_templates_directory_list (view, node->data);
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);
5511
user_dirs_changed (NautilusView *view)
5513
update_templates_directory (view);
5514
view->details->templates_invalid = TRUE;
5515
schedule_update_menus (view);
5519
directory_belongs_in_templates_menu (const char *templates_directory_uri,
5525
if (templates_directory_uri == NULL) {
5529
if (!g_str_has_prefix (uri, templates_directory_uri)) {
5534
for (i = strlen (templates_directory_uri); uri[i] != '\0'; i++) {
5535
if (uri[i] == '/') {
5540
if (num_levels > MAX_MENU_LEVELS) {
5548
update_directory_in_templates_menu (NautilusView *view,
5549
const char *templates_directory_uri,
5550
NautilusDirectory *directory)
5552
char *menu_path, *popup_bg_path;
5553
GList *file_list, *filtered, *node;
5554
gboolean any_templates;
5556
NautilusDirectory *dir;
5561
/* We know this directory belongs to the template dir, so it must exist */
5562
g_assert (templates_directory_uri);
5564
uri = nautilus_directory_get_uri (directory);
5565
escaped_path = escape_action_path (uri + strlen (templates_directory_uri));
5567
menu_path = g_strconcat (NAUTILUS_VIEW_MENU_PATH_NEW_DOCUMENTS_PLACEHOLDER,
5570
popup_bg_path = g_strconcat (NAUTILUS_VIEW_POPUP_PATH_BACKGROUND_NEW_DOCUMENTS_PLACEHOLDER,
5573
g_free (escaped_path);
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);
5579
file_list = nautilus_file_list_sort_by_display_name (filtered);
5582
any_templates = FALSE;
5583
for (node = file_list; num < TEMPLATE_LIMIT && node != NULL; node = node->next, num++) {
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);
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);
5598
any_templates = TRUE;
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;
5607
nautilus_file_list_free (file_list);
5609
g_free (popup_bg_path);
5612
return any_templates;
5618
update_templates_menu (NautilusView *view)
5620
gboolean any_templates;
5621
GList *sorted_copy, *node;
5622
NautilusDirectory *directory;
5623
GtkUIManager *ui_manager;
5626
char *templates_directory_uri;
5628
if (nautilus_should_use_templates_directory ()) {
5629
templates_directory_uri = nautilus_get_templates_directory_uri ();
5631
templates_directory_uri = NULL;
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;
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);
5644
nautilus_ui_prepare_merge_ui (ui_manager,
5646
&view->details->templates_merge_id,
5647
&view->details->templates_action_group);
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;
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,
5662
any_templates = TRUE;
5666
nautilus_directory_list_free (sorted_copy);
5668
action = gtk_action_group_get_action (view->details->dir_action_group, NAUTILUS_ACTION_NO_TEMPLATES);
5669
gtk_action_set_visible (action, !any_templates);
5671
g_free (templates_directory_uri);
5676
action_open_scripts_folder_callback (GtkAction *action,
5677
gpointer callback_data)
5680
static GFile *location = NULL;
5682
if (location == NULL) {
5683
location = g_file_new_for_uri (scripts_directory_uri);
5686
view = NAUTILUS_VIEW (callback_data);
5687
nautilus_window_slot_go_to (view->details->slot, location, FALSE);
5689
eel_show_info_dialog_with_details
5690
(_("All executable files in this folder will appear in the "
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 "
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));
5714
create_popup_menu (NautilusView *view, const char *popup_path)
5718
menu = gtk_ui_manager_get_widget (nautilus_window_get_ui_manager (view->details->window),
5720
gtk_menu_set_screen (GTK_MENU (menu),
5721
gtk_widget_get_screen (GTK_WIDGET (view)));
5722
gtk_widget_show (GTK_WIDGET (menu));
5724
return GTK_MENU (menu);
5728
copy_or_cut_files (NautilusView *view,
5729
GList *clipboard_contents,
5733
char *status_string, *name;
5734
NautilusClipboardInfo info;
5735
GtkTargetList *target_list;
5736
GtkTargetEntry *targets;
5739
info.files = clipboard_contents;
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);
5747
targets = gtk_target_table_new_from_list (target_list, &n_targets);
5748
gtk_target_list_unref (target_list);
5750
gtk_clipboard_set_with_data (nautilus_clipboard_get (GTK_WIDGET (view)),
5752
nautilus_get_clipboard_callback, nautilus_clear_clipboard_callback,
5754
gtk_target_table_free (targets, n_targets);
5756
nautilus_clipboard_monitor_set_clipboard_info (nautilus_clipboard_monitor_get (), &info);
5758
count = g_list_length (clipboard_contents);
5760
name = nautilus_file_get_display_name (clipboard_contents->data);
5762
status_string = g_strdup_printf (_("\"%s\" will be moved "
5763
"if you select the Paste command"),
5766
status_string = g_strdup_printf (_("\"%s\" will be copied "
5767
"if you select the Paste command"),
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",
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",
5789
nautilus_window_slot_set_status (view->details->slot,
5790
status_string, NULL);
5791
g_free (status_string);
5795
action_copy_files_callback (GtkAction *action,
5796
gpointer callback_data)
5801
view = NAUTILUS_VIEW (callback_data);
5803
selection = nautilus_view_get_selection_for_file_transfer (view);
5804
copy_or_cut_files (view, selection, FALSE);
5805
nautilus_file_list_free (selection);
5809
move_copy_selection_to_location (NautilusView *view,
5813
GList *selection, *uris, *l;
5815
selection = nautilus_view_get_selection_for_file_transfer (view);
5816
if (selection == NULL) {
5821
for (l = selection; l != NULL; l = l->next) {
5822
uris = g_list_prepend (uris,
5823
nautilus_file_get_uri ((NautilusFile *) l->data));
5825
uris = g_list_reverse (uris);
5827
nautilus_view_move_copy_items (view, uris, NULL, target_uri,
5831
g_list_free_full (uris, g_free);
5832
nautilus_file_list_free (selection);
5836
move_copy_selection_to_next_pane (NautilusView *view,
5839
NautilusWindowSlot *slot;
5840
char *dest_location;
5842
slot = nautilus_window_get_extra_slot (nautilus_view_get_nautilus_window (view));
5843
g_return_if_fail (slot != NULL);
5845
dest_location = nautilus_window_slot_get_current_uri (slot);
5846
g_return_if_fail (dest_location != NULL);
5848
move_copy_selection_to_location (view, copy_action, dest_location);
5852
action_copy_to_next_pane_callback (GtkAction *action, gpointer callback_data)
5856
view = NAUTILUS_VIEW (callback_data);
5857
move_copy_selection_to_next_pane (view,
5862
action_move_to_next_pane_callback (GtkAction *action, gpointer callback_data)
5864
NautilusWindowSlot *slot;
5865
char *dest_location;
5868
view = NAUTILUS_VIEW (callback_data);
5870
slot = nautilus_window_get_extra_slot (nautilus_view_get_nautilus_window (view));
5871
g_return_if_fail (slot != NULL);
5873
dest_location = nautilus_window_slot_get_current_uri (slot);
5874
g_return_if_fail (dest_location != NULL);
5876
move_copy_selection_to_location (view, GDK_ACTION_MOVE, dest_location);
5880
action_copy_to_home_callback (GtkAction *action, gpointer callback_data)
5883
char *dest_location;
5885
view = NAUTILUS_VIEW (callback_data);
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);
5893
action_move_to_home_callback (GtkAction *action, gpointer callback_data)
5896
char *dest_location;
5898
view = NAUTILUS_VIEW (callback_data);
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);
5906
action_copy_to_desktop_callback (GtkAction *action, gpointer callback_data)
5909
char *dest_location;
5911
view = NAUTILUS_VIEW (callback_data);
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);
5919
action_move_to_desktop_callback (GtkAction *action, gpointer callback_data)
5922
char *dest_location;
5924
view = NAUTILUS_VIEW (callback_data);
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);
5932
action_cut_files_callback (GtkAction *action,
5933
gpointer callback_data)
5938
view = NAUTILUS_VIEW (callback_data);
5940
selection = nautilus_view_get_selection_for_file_transfer (view);
5941
copy_or_cut_files (view, selection, TRUE);
5942
nautilus_file_list_free (selection);
5946
paste_clipboard_data (NautilusView *view,
5947
GtkSelectionData *selection_data,
5948
char *destination_uri)
5954
item_uris = nautilus_clipboard_get_uri_list_from_selection_data (selection_data, &cut,
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."),
5962
nautilus_view_move_copy_items (view, item_uris, NULL, destination_uri,
5963
cut ? GDK_ACTION_MOVE : GDK_ACTION_COPY,
5966
/* If items are cut then remove from clipboard */
5968
gtk_clipboard_clear (nautilus_clipboard_get (GTK_WIDGET (view)));
5971
g_list_free_full (item_uris, g_free);
5976
paste_clipboard_received_callback (GtkClipboard *clipboard,
5977
GtkSelectionData *selection_data,
5983
view = NAUTILUS_VIEW (data);
5985
view_uri = nautilus_view_get_backing_uri (view);
5987
if (view->details->window != NULL) {
5988
paste_clipboard_data (view, selection_data, view_uri);
5993
g_object_unref (view);
5998
NautilusFile *target;
6002
paste_into_clipboard_received_callback (GtkClipboard *clipboard,
6003
GtkSelectionData *selection_data,
6004
gpointer callback_data)
6006
PasteIntoData *data;
6008
char *directory_uri;
6010
data = (PasteIntoData *) callback_data;
6012
view = NAUTILUS_VIEW (data->view);
6014
if (view->details->window != NULL) {
6015
directory_uri = nautilus_file_get_activation_uri (data->target);
6017
paste_clipboard_data (view, selection_data, directory_uri);
6019
g_free (directory_uri);
6022
g_object_unref (view);
6023
nautilus_file_unref (data->target);
6028
action_paste_files_callback (GtkAction *action,
6029
gpointer callback_data)
6033
view = NAUTILUS_VIEW (callback_data);
6035
g_object_ref (view);
6036
gtk_clipboard_request_contents (nautilus_clipboard_get (GTK_WIDGET (view)),
6038
paste_clipboard_received_callback,
6043
paste_into (NautilusView *view,
6044
NautilusFile *target)
6046
PasteIntoData *data;
6048
g_assert (NAUTILUS_IS_VIEW (view));
6049
g_assert (NAUTILUS_IS_FILE (target));
6051
data = g_new (PasteIntoData, 1);
6053
data->view = g_object_ref (view);
6054
data->target = nautilus_file_ref (target);
6056
gtk_clipboard_request_contents (nautilus_clipboard_get (GTK_WIDGET (view)),
6058
paste_into_clipboard_received_callback,
6063
action_paste_files_into_callback (GtkAction *action,
6064
gpointer callback_data)
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);
6079
invoke_external_bulk_rename_utility (NautilusView *view,
6084
char *quoted_parameter;
6085
char *bulk_rename_tool;
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) {
6095
parameter = nautilus_file_get_uri (file);
6096
quoted_parameter = g_shell_quote (parameter);
6098
cmd = g_string_append (cmd, " ");
6099
cmd = g_string_append (cmd, quoted_parameter);
6100
g_free (quoted_parameter);
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);
6110
real_action_rename (NautilusView *view,
6111
gboolean select_all)
6116
g_assert (NAUTILUS_IS_VIEW (view));
6118
selection = nautilus_view_get_selection (view);
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);
6127
file = NAUTILUS_FILE (selection->data);
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);
6133
EEL_CALL_METHOD (NAUTILUS_VIEW_CLASS, view, start_renaming_file, (view, file, select_all));
6137
nautilus_file_list_free (selection);
6141
action_rename_callback (GtkAction *action,
6142
gpointer callback_data)
6144
real_action_rename (NAUTILUS_VIEW (callback_data), FALSE);
6148
action_rename_select_all_callback (GtkAction *action,
6149
gpointer callback_data)
6151
real_action_rename (NAUTILUS_VIEW (callback_data), TRUE);
6155
file_mount_callback (NautilusFile *file,
6156
GFile *result_location,
6158
gpointer callback_data)
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);
6171
nautilus_view_set_initiated_unmount (NautilusView *view,
6172
gboolean initiated_unmount)
6174
if (view->details->window != NULL) {
6175
nautilus_window_set_initiated_unmount(view->details->window,
6181
file_unmount_callback (NautilusFile *file,
6182
GFile *result_location,
6184
gpointer callback_data)
6188
view = NAUTILUS_VIEW (callback_data);
6189
nautilus_view_set_initiated_unmount (view, FALSE);
6190
g_object_unref (view);
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);
6202
file_eject_callback (NautilusFile *file,
6203
GFile *result_location,
6205
gpointer callback_data)
6209
view = NAUTILUS_VIEW (callback_data);
6210
nautilus_view_set_initiated_unmount (view, FALSE);
6211
g_object_unref (view);
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);
6223
file_stop_callback (NautilusFile *file,
6224
GFile *result_location,
6226
gpointer callback_data)
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);
6238
action_mount_volume_callback (GtkAction *action,
6242
GList *selection, *l;
6244
GMountOperation *mount_op;
6246
view = NAUTILUS_VIEW (data);
6248
selection = nautilus_view_get_selection (view);
6249
for (l = selection; l != NULL; l = l->next) {
6250
file = NAUTILUS_FILE (l->data);
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);
6260
nautilus_file_list_free (selection);
6264
action_unmount_volume_callback (GtkAction *action,
6268
GList *selection, *l;
6271
view = NAUTILUS_VIEW (data);
6273
selection = nautilus_view_get_selection (view);
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);
6286
nautilus_file_list_free (selection);
6290
action_eject_volume_callback (GtkAction *action,
6294
GList *selection, *l;
6297
view = NAUTILUS_VIEW (data);
6299
selection = nautilus_view_get_selection (view);
6300
for (l = selection; l != NULL; l = l->next) {
6301
file = NAUTILUS_FILE (l->data);
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);
6312
nautilus_file_list_free (selection);
6316
file_start_callback (NautilusFile *file,
6317
GFile *result_location,
6319
gpointer callback_data)
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);
6332
action_start_volume_callback (GtkAction *action,
6336
GList *selection, *l;
6338
GMountOperation *mount_op;
6340
view = NAUTILUS_VIEW (data);
6342
selection = nautilus_view_get_selection (view);
6343
for (l = selection; l != NULL; l = l->next) {
6344
file = NAUTILUS_FILE (l->data);
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);
6353
nautilus_file_list_free (selection);
6357
action_stop_volume_callback (GtkAction *action,
6361
GList *selection, *l;
6364
view = NAUTILUS_VIEW (data);
6366
selection = nautilus_view_get_selection (view);
6367
for (l = selection; l != NULL; l = l->next) {
6368
file = NAUTILUS_FILE (l->data);
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);
6378
nautilus_file_list_free (selection);
6382
action_detect_media_callback (GtkAction *action,
6386
GList *selection, *l;
6389
view = NAUTILUS_VIEW (data);
6391
selection = nautilus_view_get_selection (view);
6392
for (l = selection; l != NULL; l = l->next) {
6393
file = NAUTILUS_FILE (l->data);
6395
if (nautilus_file_can_poll_for_media (file) && !nautilus_file_is_media_check_automatic (file)) {
6396
nautilus_file_poll_for_media (file);
6399
nautilus_file_list_free (selection);
6403
action_self_mount_volume_callback (GtkAction *action,
6408
GMountOperation *mount_op;
6410
view = NAUTILUS_VIEW (data);
6412
file = nautilus_view_get_directory_as_file (view);
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);
6424
action_self_unmount_volume_callback (GtkAction *action,
6429
GMountOperation *mount_op;
6431
view = NAUTILUS_VIEW (data);
6433
file = nautilus_view_get_directory_as_file (view);
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);
6445
action_self_eject_volume_callback (GtkAction *action,
6450
GMountOperation *mount_op;
6452
view = NAUTILUS_VIEW (data);
6454
file = nautilus_view_get_directory_as_file (view);
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);
6466
action_self_start_volume_callback (GtkAction *action,
6471
GMountOperation *mount_op;
6473
view = NAUTILUS_VIEW (data);
6475
file = nautilus_view_get_directory_as_file (view);
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);
6486
action_self_stop_volume_callback (GtkAction *action,
6491
GMountOperation *mount_op;
6493
view = NAUTILUS_VIEW (data);
6495
file = nautilus_view_get_directory_as_file (view);
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);
6507
action_self_detect_media_callback (GtkAction *action,
6513
view = NAUTILUS_VIEW (data);
6515
file = nautilus_view_get_directory_as_file (view);
6520
nautilus_file_poll_for_media (file);
6524
action_location_mount_volume_callback (GtkAction *action,
6529
GMountOperation *mount_op;
6531
view = NAUTILUS_VIEW (data);
6533
file = view->details->location_popup_directory_as_file;
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);
6545
action_location_unmount_volume_callback (GtkAction *action,
6550
GMountOperation *mount_op;
6552
view = NAUTILUS_VIEW (data);
6554
file = view->details->location_popup_directory_as_file;
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);
6567
action_location_eject_volume_callback (GtkAction *action,
6572
GMountOperation *mount_op;
6574
view = NAUTILUS_VIEW (data);
6576
file = view->details->location_popup_directory_as_file;
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);
6589
action_location_start_volume_callback (GtkAction *action,
6594
GMountOperation *mount_op;
6596
view = NAUTILUS_VIEW (data);
6598
file = view->details->location_popup_directory_as_file;
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);
6609
action_location_stop_volume_callback (GtkAction *action,
6614
GMountOperation *mount_op;
6616
view = NAUTILUS_VIEW (data);
6618
file = view->details->location_popup_directory_as_file;
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);
6630
action_location_detect_media_callback (GtkAction *action,
6636
view = NAUTILUS_VIEW (data);
6638
file = view->details->location_popup_directory_as_file;
6643
nautilus_file_poll_for_media (file);
6647
connect_to_server_response_callback (GtkDialog *dialog,
6651
#ifdef GIO_CONVERSION_DONE
6657
entry = GTK_ENTRY (data);
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));
6667
case GTK_RESPONSE_NONE:
6668
case GTK_RESPONSE_DELETE_EVENT:
6669
case GTK_RESPONSE_CANCEL:
6670
gtk_widget_destroy (GTK_WIDGET (dialog));
6673
g_assert_not_reached ();
6676
/* FIXME: the above code should make a server connection permanent */
6677
gtk_widget_destroy (GTK_WIDGET (dialog));
6681
entry_activate_callback (GtkEntry *entry,
6686
dialog = GTK_DIALOG (user_data);
6687
gtk_dialog_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
6691
action_connect_to_server_link_callback (GtkAction *action,
6698
NautilusIconInfo *icon;
6699
const char *icon_name;
6707
view = NAUTILUS_VIEW (data);
6709
selection = nautilus_view_get_selection (view);
6711
if (!eel_g_list_exactly_one_item (selection)) {
6712
nautilus_file_list_free (selection);
6716
file = NAUTILUS_FILE (selection->data);
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);
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),
6728
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
6729
_("_Connect"), GTK_RESPONSE_OK,
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);
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);
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);
6743
label = gtk_label_new_with_mnemonic (_("Link _name:"));
6744
gtk_widget_show (label);
6746
gtk_box_pack_start (GTK_BOX (box), label, TRUE, TRUE, 12);
6748
entry = gtk_entry_new ();
6750
gtk_entry_set_text (GTK_ENTRY (entry), name);
6752
g_signal_connect (entry,
6754
G_CALLBACK (entry_activate_callback),
6757
gtk_widget_show (entry);
6758
gtk_label_set_mnemonic_widget (GTK_LABEL (label), entry);
6760
gtk_box_pack_start (GTK_BOX (box), entry, TRUE, TRUE, 12);
6762
gtk_dialog_set_default_response (GTK_DIALOG (dialog),
6764
g_signal_connect (dialog, "response",
6765
G_CALLBACK (connect_to_server_response_callback),
6767
gtk_widget_show (dialog);
6771
g_object_unref (icon);
6776
action_location_open_alternate_callback (GtkAction *action,
6777
gpointer callback_data)
6782
view = NAUTILUS_VIEW (callback_data);
6784
file = view->details->location_popup_directory_as_file;
6788
nautilus_view_activate_file (view,
6790
NAUTILUS_WINDOW_OPEN_FLAG_NEW_WINDOW);
6794
action_location_open_in_new_tab_callback (GtkAction *action,
6795
gpointer callback_data)
6800
view = NAUTILUS_VIEW (callback_data);
6802
file = view->details->location_popup_directory_as_file;
6807
nautilus_view_activate_file (view,
6809
NAUTILUS_WINDOW_OPEN_FLAG_NEW_TAB);
6813
action_location_cut_callback (GtkAction *action,
6814
gpointer callback_data)
6820
view = NAUTILUS_VIEW (callback_data);
6822
file = view->details->location_popup_directory_as_file;
6823
g_return_if_fail (file != NULL);
6825
files = g_list_append (NULL, file);
6826
copy_or_cut_files (view, files, TRUE);
6827
g_list_free (files);
6831
action_location_copy_callback (GtkAction *action,
6832
gpointer callback_data)
6838
view = NAUTILUS_VIEW (callback_data);
6840
file = view->details->location_popup_directory_as_file;
6841
g_return_if_fail (file != NULL);
6843
files = g_list_append (NULL, file);
6844
copy_or_cut_files (view, files, FALSE);
6845
g_list_free (files);
6849
action_location_paste_files_into_callback (GtkAction *action,
6850
gpointer callback_data)
6855
view = NAUTILUS_VIEW (callback_data);
6857
file = view->details->location_popup_directory_as_file;
6858
g_return_if_fail (file != NULL);
6860
paste_into (view, file);
6864
action_location_trash_callback (GtkAction *action,
6865
gpointer callback_data)
6871
view = NAUTILUS_VIEW (callback_data);
6873
file = view->details->location_popup_directory_as_file;
6874
g_return_if_fail (file != NULL);
6876
files = g_list_append (NULL, file);
6877
trash_or_delete_files (nautilus_view_get_containing_window (view),
6880
g_list_free (files);
6884
action_location_delete_callback (GtkAction *action,
6885
gpointer callback_data)
6892
view = NAUTILUS_VIEW (callback_data);
6894
file = view->details->location_popup_directory_as_file;
6895
g_return_if_fail (file != NULL);
6897
location = nautilus_file_get_location (file);
6899
files = g_list_append (NULL, location);
6900
nautilus_file_operations_delete (files, nautilus_view_get_containing_window (view),
6903
g_list_free_full (files, g_object_unref);
6907
action_location_restore_from_trash_callback (GtkAction *action,
6908
gpointer callback_data)
6914
view = NAUTILUS_VIEW (callback_data);
6915
file = view->details->location_popup_directory_as_file;
6920
nautilus_restore_files_from_trash (&l,
6921
nautilus_view_get_containing_window (view));
6925
nautilus_view_init_show_hidden_files (NautilusView *view)
6927
NautilusWindowShowHiddenFilesMode mode;
6928
gboolean show_hidden_changed;
6929
gboolean show_hidden_default_setting;
6931
if (view->details->ignore_hidden_file_preferences) {
6935
show_hidden_changed = FALSE;
6936
mode = nautilus_window_get_hidden_files_mode (view->details->window);
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;
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;
6949
show_hidden_changed = view->details->show_hidden_files;
6950
view->details->show_hidden_files = FALSE;
6954
if (show_hidden_changed && (view->details->model != NULL)) {
6955
load_directory (view, view->details->model);
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",
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",
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",
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,
7077
G_CALLBACK (action_restore_from_trash_callback) },
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.
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",
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) },
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) },
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) },
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) },
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) },
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) },
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,
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,
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) },
7243
connect_proxy (NautilusView *view,
7246
GtkActionGroup *action_group)
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);
7258
g_object_unref (pixbuf);
7264
pre_activate (NautilusView *view,
7266
GtkActionGroup *action_group)
7270
gboolean activated_from_popup;
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;
7276
event = gtk_get_current_event ();
7277
proxy = gtk_get_event_widget (event);
7279
if (proxy != NULL) {
7280
GtkWidget *toplevel;
7281
GdkWindowTypeHint hint;
7283
toplevel = gtk_widget_get_toplevel (proxy);
7285
if (GTK_IS_WINDOW (toplevel)) {
7286
hint = gtk_window_get_type_hint (GTK_WINDOW (toplevel));
7288
if (hint == GDK_WINDOW_TYPE_HINT_POPUP_MENU) {
7289
activated_from_popup = TRUE;
7294
if (!activated_from_popup) {
7295
update_context_menu_position_from_event (view, NULL);
7300
real_merge_menus (NautilusView *view)
7302
GtkActionGroup *action_group;
7303
GtkUIManager *ui_manager;
7308
ui_manager = nautilus_window_get_ui_manager (view->details->window);
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),
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);
7325
action = gtk_action_group_get_action (action_group, NAUTILUS_ACTION_NO_TEMPLATES);
7326
gtk_action_set_sensitive (action, FALSE);
7328
g_signal_connect_object (action_group, "connect-proxy",
7329
G_CALLBACK (connect_proxy), G_OBJECT (view),
7331
g_signal_connect_object (action_group, "pre-activate",
7332
G_CALLBACK (pre_activate), G_OBJECT (view),
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 */
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);
7342
view->details->scripts_invalid = TRUE;
7343
view->details->templates_invalid = TRUE;
7348
can_paste_into_file (NautilusFile *file)
7350
if (nautilus_file_is_directory (file) &&
7351
nautilus_file_can_write (file)) {
7354
if (nautilus_file_has_activation_uri (file)) {
7356
NautilusFile *activation_file;
7359
location = nautilus_file_get_activation_location (file);
7360
activation_file = nautilus_file_get (location);
7361
g_object_unref (location);
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));
7370
nautilus_file_unref (activation_file);
7379
clipboard_targets_received (GtkClipboard *clipboard,
7391
view = NAUTILUS_VIEW (user_data);
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);
7402
for (i=0; i < n_targets; i++) {
7403
if (targets[i] == copied_files_atom) {
7410
selection = nautilus_view_get_selection (view);
7411
count = g_list_length (selection);
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));
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)));
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")));
7435
nautilus_file_list_free (selection);
7437
g_object_unref (view);
7441
should_show_empty_trash (NautilusView *view)
7443
return (showing_trash_directory (view));
7447
file_list_all_are_folders (GList *file_list)
7450
NautilusFile *file, *linked_file;
7451
char *activation_uri;
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)) {
7462
activation_uri = nautilus_file_get_activation_uri (file);
7464
if (activation_uri == NULL) {
7465
g_free (activation_uri);
7469
linked_file = nautilus_file_get_existing_by_uri (activation_uri);
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
7478
(linked_file != NULL &&
7479
nautilus_file_is_directory (linked_file)) ||
7480
(activation_uri != NULL &&
7481
activation_uri[strlen (activation_uri) - 1] == '/');
7483
nautilus_file_unref (linked_file);
7484
g_free (activation_uri);
7489
} else if (!(nautilus_file_is_directory (file) ||
7490
NAUTILUS_IS_DESKTOP_ICON_FILE (file))) {
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)
7510
*show_mount = FALSE;
7511
*show_unmount = FALSE;
7512
*show_eject = FALSE;
7513
*show_connect = FALSE;
7514
*show_start = FALSE;
7518
if (nautilus_file_can_eject (file)) {
7522
if (nautilus_file_can_mount (file)) {
7526
if (nautilus_file_can_start (file) || nautilus_file_can_start_degraded (file)) {
7530
if (nautilus_file_can_stop (file)) {
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;
7540
if (nautilus_file_can_poll_for_media (file) && !nautilus_file_is_media_check_automatic (file)) {
7544
*start_stop_type = nautilus_file_get_start_stop_type (file);
7546
if (nautilus_file_is_nautilus_link (file)) {
7547
uri = nautilus_file_get_activation_uri (file);
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;
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)
7570
*show_mount = FALSE;
7571
*show_unmount = FALSE;
7572
*show_eject = FALSE;
7573
*show_start = FALSE;
7581
if (nautilus_file_can_eject (file)) {
7585
if (nautilus_file_can_mount (file)) {
7589
if (nautilus_file_can_start (file) || nautilus_file_can_start_degraded (file)) {
7593
if (nautilus_file_can_stop (file)) {
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;
7603
if (nautilus_file_can_poll_for_media (file) && !nautilus_file_is_media_check_automatic (file)) {
7607
*start_stop_type = nautilus_file_get_start_stop_type (file);
7612
files_are_all_directories (GList *files)
7616
gboolean all_directories;
7618
all_directories = TRUE;
7620
for (l = files; l != NULL; l = l->next) {
7621
file = NAUTILUS_FILE (l->data);
7622
all_directories &= nautilus_file_is_directory (file);
7625
return all_directories;
7629
files_is_none_directory (GList *files)
7633
gboolean no_directory;
7635
no_directory = TRUE;
7637
for (l = files; l != NULL; l = l->next) {
7638
file = NAUTILUS_FILE (l->data);
7639
no_directory &= !nautilus_file_is_directory (file);
7642
return no_directory;
7646
update_restore_from_trash_action (GtkAction *action,
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;
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;
7664
if (files != NULL) {
7665
if (g_list_length (files) == 1) {
7666
original_file = nautilus_file_get_trash_original_file (files->data);
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));
7678
if (original_file != NULL || original_dirs != NULL) {
7679
gtk_action_set_visible (action, TRUE);
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);
7687
if (original_location != NULL) {
7688
original_name = g_file_get_parse_name (original_location);
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);
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)));
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);
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)));
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);
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)));
7726
g_free (original_name);
7728
g_object_set (action, "tooltip", tooltip, NULL);
7730
if (original_location != NULL) {
7731
g_object_unref (original_location);
7734
gtk_action_set_visible (action, FALSE);
7737
nautilus_file_unref (original_file);
7738
nautilus_file_unref (original_dir);
7739
g_list_free (original_dirs);
7741
if (original_dirs_hash != NULL) {
7742
g_hash_table_destroy (original_dirs_hash);
7747
real_update_menus_volumes (NautilusView *view,
7749
gint selection_count)
7753
gboolean show_mount;
7754
gboolean show_unmount;
7755
gboolean show_eject;
7756
gboolean show_connect;
7757
gboolean show_start;
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;
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;
7780
for (l = selection; l != NULL && (show_mount || show_unmount
7781
|| show_eject || show_connect
7782
|| show_start || show_stop
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;
7793
file = NAUTILUS_FILE (l->data);
7794
file_should_show_foreach (file,
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;
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);
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);
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);
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);
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);
7833
switch (start_stop_type) {
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"));
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"));
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"));
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"));
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"));
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);
7862
switch (start_stop_type) {
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"));
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"));
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"));
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"));
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"));
7887
action = gtk_action_group_get_action (view->details->dir_action_group,
7888
NAUTILUS_ACTION_POLL);
7889
gtk_action_set_visible (action, show_poll);
7891
show_self_mount = show_self_unmount = show_self_eject =
7892
show_self_start = show_self_stop = show_self_poll = FALSE;
7894
file = nautilus_view_get_directory_as_file (view);
7895
file_should_show_self (file,
7902
&self_start_stop_type);
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);
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);
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);
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) {
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"));
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"));
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"));
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"));
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"));
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) {
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"));
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"));
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"));
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"));
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"));
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);
7981
real_update_location_menu_volumes (NautilusView *view)
7985
gboolean show_mount;
7986
gboolean show_unmount;
7987
gboolean show_eject;
7988
gboolean show_connect;
7989
gboolean show_start;
7992
GDriveStartStopType start_stop_type;
7994
g_assert (NAUTILUS_IS_VIEW (view));
7995
g_assert (NAUTILUS_IS_FILE (view->details->location_popup_directory_as_file));
7997
file = NAUTILUS_FILE (view->details->location_popup_directory_as_file);
7998
file_should_show_foreach (file,
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);
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);
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);
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);
8024
switch (start_stop_type) {
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"));
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"));
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"));
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"));
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"));
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);
8053
switch (start_stop_type) {
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"));
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"));
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"));
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"));
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"));
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);
8083
/* TODO: we should split out this routine into two functions:
8084
* Update on clipboard changes
8085
* Update on selection changes
8088
real_update_paste_menu (NautilusView *view,
8090
gint selection_count)
8092
gboolean can_paste_files_into;
8093
gboolean selection_is_read_only;
8094
gboolean is_read_only;
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)));
8101
is_read_only = nautilus_view_is_read_only (view);
8103
can_paste_files_into = (selection_count == 1 &&
8104
can_paste_into_file (NAUTILUS_FILE (selection->data)));
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);
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);
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,
8123
real_update_location_menu (NautilusView *view)
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;
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);
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);
8144
label = _("Open in New _Window");
8145
g_object_set (action,
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);
8153
label = _("Open in New _Tab");
8154
g_object_set (action,
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));
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);
8169
nautilus_file_can_delete (file) &&
8171
!is_desktop_or_home_dir;
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);
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")));
8191
nautilus_file_is_in_trash (file)) {
8192
if (nautilus_file_is_self_owned (file)) {
8193
show_delete = FALSE;
8196
label = _("_Delete Permanently");
8197
tip = _("Delete the open folder permanently");
8198
show_separate_delete_command = FALSE;
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);
8205
action = gtk_action_group_get_action (view->details->dir_action_group,
8206
NAUTILUS_ACTION_LOCATION_TRASH);
8207
g_object_set (action,
8210
"icon-name", (file != NULL &&
8211
nautilus_file_is_in_trash (file)) ?
8212
NAUTILUS_ICON_DELETE : NAUTILUS_ICON_TRASH_FULL,
8214
gtk_action_set_sensitive (action, can_delete_file);
8215
gtk_action_set_visible (action, show_delete);
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,
8228
action = gtk_action_group_get_action (view->details->dir_action_group,
8229
NAUTILUS_ACTION_LOCATION_RESTORE_FROM_TRASH);
8233
update_restore_from_trash_action (action, &l, TRUE);
8235
real_update_location_menu_volumes (view);
8239
clipboard_changed_callback (NautilusClipboardMonitor *monitor, NautilusView *view)
8242
gint selection_count;
8244
if (!view->details->active) {
8248
selection = nautilus_view_get_selection (view);
8249
selection_count = g_list_length (selection);
8251
real_update_paste_menu (view, selection, selection_count);
8253
nautilus_file_list_free (selection);
8258
can_delete_all (GList *files)
8263
for (l = files; l != NULL; l = l->next) {
8265
if (!nautilus_file_can_delete (file)) {
8273
has_writable_extra_pane (NautilusView *view)
8275
NautilusView *other_view;
8277
other_view = get_directory_view_of_extra_pane (view);
8278
if (other_view != NULL) {
8279
return !nautilus_view_is_read_only (other_view);
8285
real_update_menus (NautilusView *view)
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;
8305
gboolean show_save_search;
8306
gboolean save_search_sensitive;
8307
gboolean show_save_search_as;
8308
gboolean show_desktop_target;
8312
GtkWidget *menuitem;
8313
gboolean next_pane_is_writable;
8314
gboolean show_properties;
8316
selection = nautilus_view_get_selection (view);
8317
selection_count = g_list_length (selection);
8319
selection_contains_special_link = special_link_in_selection (view);
8320
selection_contains_desktop_or_home_dir = desktop_or_home_dir_in_selection (view);
8322
can_create_files = nautilus_view_supports_creating_files (view);
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;
8331
can_duplicate_files = can_create_files && can_copy_files;
8332
can_link_files = can_create_files && can_copy_files;
8334
vfolder_directory = we_are_in_vfolder_desktop_dir (view);
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 ());
8343
gtk_action_set_sensitive (action,
8344
selection_count == 1 &&
8345
nautilus_view_can_rename_file (view, selection->data));
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);
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);
8356
can_open = show_app = selection_count != 0;
8358
for (l = selection; l != NULL; l = l->next) {
8361
file = NAUTILUS_FILE (selection->data);
8363
if (!nautilus_mime_file_opens_in_external_app (file)) {
8372
label_with_underscore = NULL;
8377
if (can_open && show_app) {
8378
app = nautilus_mime_get_default_application_for_files (selection);
8384
escaped_app = eel_str_double_underscores (g_app_info_get_display_name (app));
8385
label_with_underscore = g_strdup_printf (_("_Open With %s"),
8388
app_icon = g_app_info_get_icon (app);
8389
if (app_icon != NULL) {
8390
g_object_ref (app_icon);
8393
g_free (escaped_app);
8394
g_object_unref (app);
8397
g_object_set (action, "label",
8398
label_with_underscore ? label_with_underscore : _("_Open"),
8401
menuitem = gtk_ui_manager_get_widget (
8402
nautilus_window_get_ui_manager (view->details->window),
8403
NAUTILUS_VIEW_MENU_PATH_OPEN);
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);
8409
menuitem = gtk_ui_manager_get_widget (
8410
nautilus_window_get_ui_manager (view->details->window),
8411
NAUTILUS_VIEW_POPUP_PATH_OPEN);
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);
8417
if (app_icon == NULL) {
8418
app_icon = g_themed_icon_new (GTK_STOCK_OPEN);
8421
gtk_action_set_gicon (action, app_icon);
8422
g_object_unref (app_icon);
8424
gtk_action_set_visible (action, can_open);
8426
g_free (label_with_underscore);
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);
8433
action = gtk_action_group_get_action (view->details->dir_action_group,
8434
NAUTILUS_ACTION_OPEN_ALTERNATE);
8436
gtk_action_set_sensitive (action, selection_count != 0);
8437
gtk_action_set_visible (action, show_open_alternate);
8439
if (selection_count == 0 || selection_count == 1) {
8440
label_with_underscore = g_strdup (_("Open in New _Window"));
8442
label_with_underscore = g_strdup_printf (ngettext("Open in %'d New _Window",
8443
"Open in %'d New _Windows",
8448
g_object_set (action, "label",
8449
label_with_underscore,
8451
g_free (label_with_underscore);
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);
8459
if (selection_count == 0 || selection_count == 1) {
8460
label_with_underscore = g_strdup (_("Open in New _Tab"));
8462
label_with_underscore = g_strdup_printf (ngettext("Open in %'d New _Tab",
8463
"Open in %'d New _Tabs",
8468
g_object_set (action, "label",
8469
label_with_underscore,
8471
g_free (label_with_underscore);
8473
/* Broken into its own function just for convenience */
8474
reset_open_with_menu (view, selection);
8475
reset_extension_actions_menu (view, selection);
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;
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);
8487
action = gtk_action_group_get_action (view->details->dir_action_group,
8488
NAUTILUS_ACTION_TRASH);
8489
g_object_set (action,
8492
"icon-name", all_selected_items_in_trash (view) ?
8493
NAUTILUS_ICON_DELETE : NAUTILUS_ICON_TRASH_FULL,
8495
gtk_action_set_sensitive (action, can_delete_files);
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);
8501
if (show_separate_delete_command) {
8502
g_object_set (action,
8503
"label", _("_Delete"),
8504
"icon-name", NAUTILUS_ICON_DELETE,
8507
gtk_action_set_sensitive (action, can_delete_files);
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);
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);
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",
8527
show_properties = (!NAUTILUS_IS_DESKTOP_ICON_VIEW (view) || selection_count > 0);
8529
action = gtk_action_group_get_action (view->details->dir_action_group,
8530
NAUTILUS_ACTION_PROPERTIES);
8532
gtk_action_set_sensitive (action, show_properties);
8534
if (selection_count == 0) {
8535
gtk_action_set_tooltip (action, _("View or modify the properties of the open folder"));
8537
gtk_action_set_tooltip (action, _("View or modify the properties of each selected item"));
8540
gtk_action_set_visible (action, show_properties);
8542
action = gtk_action_group_get_action (view->details->dir_action_group,
8543
NAUTILUS_ACTION_PROPERTIES_ACCEL);
8545
gtk_action_set_sensitive (action, show_properties);
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"),
8552
gtk_action_set_sensitive (action, !nautilus_trash_monitor_is_empty ());
8553
gtk_action_set_visible (action, should_show_empty_trash (view));
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;
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);
8567
show_save_search_as = TRUE;
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);
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));
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));
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));
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);
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);
8599
real_update_paste_menu (view, selection, selection_count);
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);
8607
real_update_menus_volumes (view, selection, selection_count);
8609
nautilus_file_list_free (selection);
8611
if (view->details->scripts_invalid) {
8612
update_scripts_menu (view);
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);
8619
if (can_create_files && view->details->templates_invalid) {
8620
update_templates_menu (view);
8623
next_pane_is_writable = has_writable_extra_pane (view);
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);
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);
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);
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);
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);
8656
action = gtk_action_group_get_action (view->details->dir_action_group,
8658
gtk_action_set_sensitive (action, can_copy_files);
8659
action = gtk_action_group_get_action (view->details->dir_action_group,
8661
gtk_action_set_sensitive (action, can_delete_files);
8665
* nautilus_view_pop_up_selection_context_menu
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.
8671
* Return value: NautilusDirectory for this view.
8675
nautilus_view_pop_up_selection_context_menu (NautilusView *view,
8676
GdkEventButton *event)
8678
g_assert (NAUTILUS_IS_VIEW (view));
8680
/* Make the context menu items not flash as they update to proper disabled,
8681
* etc. states by forcing menus to update now.
8683
update_menus_if_pending (view);
8685
update_context_menu_position_from_event (view, event);
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,
8695
* nautilus_view_pop_up_background_context_menu
8697
* Pop up a context menu appropriate to the view globally at the last right click location.
8698
* @view: NautilusView of interest.
8700
* Return value: NautilusDirectory for this view.
8704
nautilus_view_pop_up_background_context_menu (NautilusView *view,
8705
GdkEventButton *event)
8707
g_assert (NAUTILUS_IS_VIEW (view));
8709
/* Make the context menu items not flash as they update to proper disabled,
8710
* etc. states by forcing menus to update now.
8712
update_menus_if_pending (view);
8714
update_context_menu_position_from_event (view, event);
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,
8725
real_pop_up_location_context_menu (NautilusView *view)
8727
/* always update the menu before showing it. Shouldn't be too expensive. */
8728
real_update_location_menu (view);
8730
update_context_menu_position_from_event (view, view->details->location_popup_event);
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);
8740
location_popup_file_attributes_ready (NautilusFile *file,
8745
view = NAUTILUS_VIEW (data);
8746
g_assert (NAUTILUS_IS_VIEW (view));
8748
g_assert (file == view->details->location_popup_directory_as_file);
8750
real_pop_up_location_context_menu (view);
8754
unschedule_pop_up_location_context_menu (NautilusView *view)
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,
8761
nautilus_file_unref (view->details->location_popup_directory_as_file);
8762
view->details->location_popup_directory_as_file = NULL;
8767
schedule_pop_up_location_context_menu (NautilusView *view,
8768
GdkEventButton *event,
8771
g_assert (NAUTILUS_IS_FILE (file));
8773
if (view->details->location_popup_event != NULL) {
8774
gdk_event_free ((GdkEvent *) view->details->location_popup_event);
8776
view->details->location_popup_event = (GdkEventButton *) gdk_event_copy ((GdkEvent *)event);
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);
8785
unschedule_pop_up_location_context_menu (view);
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,
8798
* nautilus_view_pop_up_location_context_menu
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.
8808
nautilus_view_pop_up_location_context_menu (NautilusView *view,
8809
GdkEventButton *event,
8810
const char *location)
8814
g_assert (NAUTILUS_IS_VIEW (view));
8816
if (location != NULL) {
8817
file = nautilus_file_get_by_uri (location);
8819
file = nautilus_file_ref (view->details->directory_as_file);
8823
schedule_pop_up_location_context_menu (view, event, file);
8824
nautilus_file_unref (file);
8829
schedule_update_menus (NautilusView *view)
8831
g_assert (NAUTILUS_IS_VIEW (view));
8833
/* Don't schedule updates after destroy (#349551),
8834
* or if we are not active.
8836
if (view->details->window == NULL ||
8837
!view->details->active) {
8841
view->details->menu_states_untrustworthy = TRUE;
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);
8851
remove_update_status_idle_callback (NautilusView *view)
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;
8860
update_status_idle_callback (gpointer data)
8864
view = NAUTILUS_VIEW (data);
8865
nautilus_view_display_selection_info (view);
8866
view->details->update_status_idle_id = 0;
8871
schedule_update_status (NautilusView *view)
8873
g_assert (NAUTILUS_IS_VIEW (view));
8875
/* Make sure we haven't already destroyed it */
8876
if (view->details->window == NULL) {
8880
if (view->details->loading) {
8881
/* Don't update status bar while loading the dir */
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);
8893
* nautilus_view_notify_selection_changed:
8895
* Notify this view that the selection has changed. This is normally
8896
* called only by subclasses.
8897
* @view: NautilusView whose selection has changed.
8901
nautilus_view_notify_selection_changed (NautilusView *view)
8906
g_return_if_fail (NAUTILUS_IS_VIEW (view));
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);
8913
view->details->selection_was_removed = FALSE;
8915
if (!view->details->selection_change_is_due_to_shell) {
8916
view->details->send_selection_change_to_shell = TRUE;
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,
8926
if (view->details->batching_selection_level != 0) {
8927
view->details->selection_changed_while_batched = TRUE;
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.
8935
/* Schedule an update of menu item states to match selection */
8936
schedule_update_menus (view);
8941
file_changed_callback (NautilusFile *file, gpointer callback_data)
8943
NautilusView *view = NAUTILUS_VIEW (callback_data);
8945
schedule_changes (view);
8947
schedule_update_menus (view);
8948
schedule_update_status (view);
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.
8961
load_directory (NautilusView *view,
8962
NautilusDirectory *directory)
8964
NautilusDirectory *old_directory;
8965
NautilusFile *old_file;
8966
NautilusFileAttributes attributes;
8968
g_assert (NAUTILUS_IS_VIEW (view));
8969
g_assert (NAUTILUS_IS_DIRECTORY (directory));
8971
nautilus_view_stop_loading (view);
8972
g_signal_emit (view, signals[CLEAR], 0);
8974
view->details->loading = TRUE;
8976
/* Update menus when directory is empty, before going to new
8977
* location, so they won't have any false lingering knowledge
8980
schedule_update_menus (view);
8982
while (view->details->subdirectory_list != NULL) {
8983
nautilus_view_remove_subdirectory (view,
8984
view->details->subdirectory_list->data);
8987
disconnect_model_handlers (view);
8989
old_directory = view->details->model;
8990
nautilus_directory_ref (directory);
8991
view->details->model = directory;
8992
nautilus_directory_unref (old_directory);
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);
8999
view->details->reported_load_error = FALSE;
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.
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,
9014
metadata_for_directory_as_file_ready_callback, view);
9015
nautilus_directory_call_when_ready
9016
(view->details->model,
9019
metadata_for_files_in_directory_ready_callback, view);
9021
/* If capabilities change, then we need to update the menus
9022
* because of New Folder, and relative emblems.
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,
9031
view->details->file_changed_handler_id = g_signal_connect
9032
(view->details->directory_as_file, "changed",
9033
G_CALLBACK (file_changed_callback), view);
9037
finish_loading (NautilusView *view)
9039
NautilusFileAttributes attributes;
9041
nautilus_window_report_load_underway (view->details->window,
9042
NAUTILUS_VIEW (view));
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.
9047
g_signal_emit (view, signals[BEGIN_LOADING], 0);
9049
/* Assume we have now all information to show window */
9050
nautilus_window_view_visible (view->details->window, NAUTILUS_VIEW (view));
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.
9057
unschedule_display_of_pending_files (view);
9058
schedule_timeout_display_of_pending_files (view, UPDATE_INTERVAL_MIN);
9061
/* Start loading. */
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);
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.
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;
9084
nautilus_directory_file_monitor_add (view->details->model,
9085
&view->details->model,
9086
view->details->show_hidden_files,
9088
files_added_callback, view);
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);
9099
finish_loading_if_all_metadata_loaded (NautilusView *view)
9101
if (!view->details->metadata_for_directory_as_file_pending &&
9102
!view->details->metadata_for_files_in_directory_pending) {
9103
finish_loading (view);
9108
metadata_for_directory_as_file_ready_callback (NautilusFile *file,
9109
gpointer callback_data)
9113
view = callback_data;
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);
9119
view->details->metadata_for_directory_as_file_pending = FALSE;
9121
finish_loading_if_all_metadata_loaded (view);
9125
metadata_for_files_in_directory_ready_callback (NautilusDirectory *directory,
9127
gpointer callback_data)
9131
view = callback_data;
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);
9137
view->details->metadata_for_files_in_directory_pending = FALSE;
9139
finish_loading_if_all_metadata_loaded (view);
9143
disconnect_handler (GObject *object, int *id)
9146
g_signal_handler_disconnect (object, *id);
9152
disconnect_directory_handler (NautilusView *view, int *id)
9154
disconnect_handler (G_OBJECT (view->details->model), id);
9158
disconnect_directory_as_file_handler (NautilusView *view, int *id)
9160
disconnect_handler (G_OBJECT (view->details->directory_as_file), id);
9164
disconnect_model_handlers (NautilusView *view)
9166
if (view->details->model == NULL) {
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,
9177
nautilus_directory_cancel_callback (view->details->model,
9178
metadata_for_files_in_directory_ready_callback,
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);
9187
nautilus_view_select_file (NautilusView *view, NautilusFile *file)
9191
file_list.data = file;
9192
file_list.next = NULL;
9193
file_list.prev = NULL;
9194
nautilus_view_call_set_selection (view, &file_list);
9198
remove_all (gpointer key, gpointer value, gpointer callback_data)
9204
* nautilus_view_stop_loading:
9206
* Stop the current ongoing process, such as switching to a new uri.
9207
* @view: NautilusView in question.
9211
nautilus_view_stop_loading (NautilusView *view)
9213
g_return_if_fail (NAUTILUS_IS_VIEW (view));
9215
unschedule_display_of_pending_files (view);
9216
reset_update_interval (view);
9218
/* Free extra undisplayed files */
9219
file_and_directory_list_free (view->details->new_added_files);
9220
view->details->new_added_files = NULL;
9222
file_and_directory_list_free (view->details->new_changed_files);
9223
view->details->new_changed_files = NULL;
9225
g_hash_table_foreach_remove (view->details->non_ready_files, remove_all, NULL);
9227
file_and_directory_list_free (view->details->old_added_files);
9228
view->details->old_added_files = NULL;
9230
file_and_directory_list_free (view->details->old_changed_files);
9231
view->details->old_changed_files = NULL;
9233
g_list_free_full (view->details->pending_selection, g_object_unref);
9234
view->details->pending_selection = NULL;
9236
if (view->details->model != NULL) {
9237
nautilus_directory_file_monitor_remove (view->details->model, view);
9239
done_loading (view, FALSE);
9243
nautilus_view_is_editable (NautilusView *view)
9245
NautilusDirectory *directory;
9247
directory = nautilus_view_get_model (view);
9249
if (directory != NULL) {
9250
return nautilus_directory_is_editable (directory);
9257
real_is_read_only (NautilusView *view)
9261
if (!nautilus_view_is_editable (view)) {
9265
file = nautilus_view_get_directory_as_file (view);
9267
return !nautilus_file_can_write (file);
9273
* nautilus_view_should_show_file
9275
* Returns whether or not this file should be displayed based on
9276
* current filtering options.
9279
nautilus_view_should_show_file (NautilusView *view, NautilusFile *file)
9281
return nautilus_file_should_show (file,
9282
view->details->show_hidden_files,
9283
view->details->show_foreign_files);
9287
real_using_manual_layout (NautilusView *view)
9289
g_return_val_if_fail (NAUTILUS_IS_VIEW (view), FALSE);
9295
schedule_update_menus_callback (gpointer callback_data)
9297
schedule_update_menus (NAUTILUS_VIEW (callback_data));
9301
nautilus_view_ignore_hidden_file_preferences (NautilusView *view)
9303
g_return_if_fail (view->details->model == NULL);
9305
if (view->details->ignore_hidden_file_preferences) {
9309
view->details->show_hidden_files = FALSE;
9310
view->details->ignore_hidden_file_preferences = TRUE;
9314
nautilus_view_set_show_foreign (NautilusView *view,
9315
gboolean show_foreign)
9317
view->details->show_foreign_files = show_foreign;
9321
nautilus_view_get_uri (NautilusView *view)
9323
g_return_val_if_fail (NAUTILUS_IS_VIEW (view), NULL);
9324
if (view->details->model == NULL) {
9327
return nautilus_directory_get_uri (view->details->model);
9331
nautilus_view_move_copy_items (NautilusView *view,
9332
const GList *item_uris,
9333
GArray *relative_item_points,
9334
const char *target_uri,
9338
NautilusFile *target_file;
9340
g_assert (relative_item_points == NULL
9341
|| relative_item_points->len == 0
9342
|| g_list_length ((GList *)item_uris) == relative_item_points->len);
9344
/* add the drop location to the icon offsets */
9345
offset_drop_points (relative_item_points, x, y);
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));
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;
9364
/* Handle dropping onto a file-roller archiver file, instead of starting a move/copy */
9366
nautilus_file_unref (target_file);
9368
quoted_uri = g_shell_quote (target_uri);
9369
command = g_strconcat ("file-roller -a ", quoted_uri, NULL);
9370
g_free (quoted_uri);
9372
for (l = item_uris; l != NULL; l = l->next) {
9373
quoted_uri = g_shell_quote ((char *) l->data);
9375
tmp = g_strconcat (command, " ", quoted_uri, NULL);
9379
g_free (quoted_uri);
9382
screen = gtk_widget_get_screen (GTK_WIDGET (view));
9383
if (screen == NULL) {
9384
screen = gdk_screen_get_default ();
9387
nautilus_launch_application_from_command (screen, command, FALSE, NULL);
9392
nautilus_file_unref (target_file);
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));
9401
nautilus_view_trash_state_changed_callback (NautilusTrashMonitor *trash_monitor,
9402
gboolean state, gpointer callback_data)
9406
view = (NautilusView *) callback_data;
9407
g_assert (NAUTILUS_IS_VIEW (view));
9409
schedule_update_menus (view);
9413
nautilus_view_start_batching_selection_changes (NautilusView *view)
9415
g_return_if_fail (NAUTILUS_IS_VIEW (view));
9417
++view->details->batching_selection_level;
9418
view->details->selection_changed_while_batched = FALSE;
9422
nautilus_view_stop_batching_selection_changes (NautilusView *view)
9424
g_return_if_fail (NAUTILUS_IS_VIEW (view));
9425
g_return_if_fail (view->details->batching_selection_level > 0);
9427
if (--view->details->batching_selection_level == 0) {
9428
if (view->details->selection_changed_while_batched) {
9429
nautilus_view_notify_selection_changed (view);
9435
nautilus_view_get_active (NautilusView *view)
9437
g_assert (NAUTILUS_IS_VIEW (view));
9438
return view->details->active;
9442
real_get_selected_icon_locations (NautilusView *view)
9444
/* By default, just return an empty list. */
9445
return g_array_new (FALSE, TRUE, sizeof (GdkPoint));
9449
nautilus_view_set_property (GObject *object,
9451
const GValue *value,
9454
NautilusView *directory_view;
9455
NautilusWindowSlot *slot;
9456
NautilusWindow *window;
9458
directory_view = NAUTILUS_VIEW (object);
9461
case PROP_WINDOW_SLOT:
9462
g_assert (directory_view->details->slot == NULL);
9464
slot = NAUTILUS_WINDOW_SLOT (g_value_get_object (value));
9465
window = nautilus_window_slot_get_window (slot);
9467
directory_view->details->slot = slot;
9468
directory_view->details->window = window;
9470
g_signal_connect_object (directory_view->details->slot,
9471
"active", G_CALLBACK (slot_active),
9473
g_signal_connect_object (directory_view->details->slot,
9474
"inactive", G_CALLBACK (slot_inactive),
9477
g_signal_connect_object (directory_view->details->window,
9478
"hidden-files-mode-changed", G_CALLBACK (hidden_files_mode_changed),
9480
nautilus_view_init_show_hidden_files (directory_view);
9482
case PROP_SUPPORTS_ZOOMING:
9483
directory_view->details->supports_zooming = g_value_get_boolean (value);
9486
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
9493
nautilus_view_handle_scroll_event (NautilusView *directory_view,
9494
GdkEventScroll *event)
9496
if (event->state & GDK_CONTROL_MASK) {
9497
switch (event->direction) {
9500
nautilus_view_bump_zoom_level (directory_view, 1);
9503
case GDK_SCROLL_DOWN:
9505
nautilus_view_bump_zoom_level (directory_view, -1);
9508
case GDK_SCROLL_LEFT:
9509
case GDK_SCROLL_RIGHT:
9513
g_assert_not_reached ();
9520
/* handle Shift+Scroll, which will cause a zoom-in/out */
9522
nautilus_view_scroll_event (GtkWidget *widget,
9523
GdkEventScroll *event)
9525
NautilusView *directory_view;
9527
directory_view = NAUTILUS_VIEW (widget);
9528
if (nautilus_view_handle_scroll_event (directory_view, event)) {
9532
return GTK_WIDGET_CLASS (parent_class)->scroll_event (widget, event);
9537
nautilus_view_parent_set (GtkWidget *widget,
9538
GtkWidget *old_parent)
9543
view = NAUTILUS_VIEW (widget);
9545
parent = gtk_widget_get_parent (widget);
9546
g_assert (parent == NULL || old_parent == NULL);
9548
if (GTK_WIDGET_CLASS (parent_class)->parent_set != NULL) {
9549
GTK_WIDGET_CLASS (parent_class)->parent_set (widget, old_parent);
9552
if (parent != NULL) {
9553
g_assert (old_parent == NULL);
9555
if (view->details->slot ==
9556
nautilus_window_get_active_slot (view->details->window)) {
9557
view->details->active = TRUE;
9559
nautilus_view_merge_menus (view);
9560
schedule_update_menus (view);
9563
nautilus_view_unmerge_menus (view);
9564
remove_update_menus_timeout_callback (view);
9569
nautilus_view_class_init (NautilusViewClass *klass)
9571
GObjectClass *oclass;
9572
GtkWidgetClass *widget_class;
9573
GtkScrolledWindowClass *scrolled_window_class;
9574
GtkBindingSet *binding_set;
9576
widget_class = GTK_WIDGET_CLASS (klass);
9577
scrolled_window_class = GTK_SCROLLED_WINDOW_CLASS (klass);
9578
oclass = G_OBJECT_CLASS (klass);
9580
oclass->finalize = nautilus_view_finalize;
9581
oclass->set_property = nautilus_view_set_property;
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;
9587
/* Get rid of the strange 3-pixel gap that GtkScrolledWindow
9588
* uses by default. It does us no good.
9590
scrolled_window_class->scrollbar_spacing = 0;
9593
g_signal_new ("add_file",
9594
G_TYPE_FROM_CLASS (klass),
9596
G_STRUCT_OFFSET (NautilusViewClass, add_file),
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),
9604
G_STRUCT_OFFSET (NautilusViewClass, begin_file_changes),
9606
g_cclosure_marshal_VOID__VOID,
9608
signals[BEGIN_LOADING] =
9609
g_signal_new ("begin_loading",
9610
G_TYPE_FROM_CLASS (klass),
9612
G_STRUCT_OFFSET (NautilusViewClass, begin_loading),
9614
g_cclosure_marshal_VOID__VOID,
9617
g_signal_new ("clear",
9618
G_TYPE_FROM_CLASS (klass),
9620
G_STRUCT_OFFSET (NautilusViewClass, clear),
9622
g_cclosure_marshal_VOID__VOID,
9624
signals[END_FILE_CHANGES] =
9625
g_signal_new ("end_file_changes",
9626
G_TYPE_FROM_CLASS (klass),
9628
G_STRUCT_OFFSET (NautilusViewClass, end_file_changes),
9630
g_cclosure_marshal_VOID__VOID,
9632
signals[END_LOADING] =
9633
g_signal_new ("end_loading",
9634
G_TYPE_FROM_CLASS (klass),
9636
G_STRUCT_OFFSET (NautilusViewClass, end_loading),
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),
9644
G_STRUCT_OFFSET (NautilusViewClass, file_changed),
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),
9652
G_STRUCT_OFFSET (NautilusViewClass, load_error),
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),
9660
G_STRUCT_OFFSET (NautilusViewClass, remove_file),
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),
9669
g_cclosure_marshal_VOID__VOID,
9671
signals[SELECTION_CHANGED] =
9672
g_signal_new ("selection-changed",
9673
G_TYPE_FROM_CLASS (klass),
9677
g_cclosure_marshal_VOID__VOID,
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,
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,
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;
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);
9728
copied_files_atom = gdk_atom_intern ("x-special/gnome-copied-files", FALSE);
9730
properties[PROP_WINDOW_SLOT] =
9731
g_param_spec_object ("window-slot",
9733
"The parent window slot reference",
9734
NAUTILUS_TYPE_WINDOW_SLOT,
9736
G_PARAM_CONSTRUCT_ONLY);
9737
properties[PROP_SUPPORTS_ZOOMING] =
9738
g_param_spec_boolean ("supports-zooming",
9740
"Whether the view supports zooming",
9742
G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY |
9743
G_PARAM_STATIC_STRINGS);
9745
g_object_class_install_properties (oclass, NUM_PROPERTIES, properties);
9747
binding_set = gtk_binding_set_by_class (klass);
9748
gtk_binding_entry_add_signal (binding_set, GDK_KEY_Delete, GDK_CONTROL_MASK,
9750
gtk_binding_entry_add_signal (binding_set, GDK_KEY_KP_Delete, GDK_CONTROL_MASK,
9752
gtk_binding_entry_add_signal (binding_set, GDK_KEY_KP_Delete, GDK_SHIFT_MASK,