1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
6 * Copyright (C) 2000, 2001 Eazel, Inc.
8 * Nautilus 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 * Nautilus 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 License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 * Author: John Sullivan <sullivan@eazel.com>
25 /* nautilus-window-menus.h - implementation of nautilus window menu operations,
26 * split into separate file just for convenience.
32 #include "nautilus-actions.h"
33 #include "nautilus-navigation-action.h"
34 #include "nautilus-application.h"
35 #include "nautilus-bookmark-list.h"
36 #include "nautilus-bookmarks-window.h"
37 #include "nautilus-file-management-properties.h"
38 #include "nautilus-property-browser.h"
39 #include "nautilus-window-manage-views.h"
40 #include "nautilus-window-private.h"
41 #include "nautilus-window-bookmarks.h"
42 #include <eel/eel-glib-extensions.h>
43 #include <eel/eel-gnome-extensions.h>
44 #include <eel/eel-stock-dialogs.h>
45 #include <eel/eel-string.h>
46 #include <eel/eel-xml-extensions.h>
47 #include <libxml/parser.h>
48 #include <gtk/gtkmain.h>
49 #include <libgnome/gnome-help.h>
50 #include <glib/gi18n.h>
51 #include <libgnome/gnome-util.h>
52 #include <libgnomeui/gnome-about.h>
53 #include <libgnomeui/gnome-uidefs.h>
54 #include <libnautilus-private/nautilus-file-utilities.h>
55 #include <libnautilus-private/nautilus-global-preferences.h>
56 #include <libnautilus-private/nautilus-ui-utilities.h>
57 #include <libnautilus-private/nautilus-undo-manager.h>
58 #include <libnautilus-private/nautilus-search-engine.h>
59 #include <libnautilus-private/nautilus-signaller.h>
61 #define MENU_PATH_HISTORY_PLACEHOLDER "/MenuBar/Other Menus/Go/History Placeholder"
63 #define RESPONSE_FORGET 1000
64 #define MENU_ITEM_MAX_WIDTH_CHARS 32
66 static void schedule_refresh_go_menu (NautilusNavigationWindow
*window
);
69 action_close_all_windows_callback (GtkAction
*action
,
72 nautilus_application_close_all_navigation_windows ();
76 action_back_callback (GtkAction
*action
,
79 nautilus_navigation_window_go_back (NAUTILUS_NAVIGATION_WINDOW (user_data
));
83 action_forward_callback (GtkAction
*action
,
86 nautilus_navigation_window_go_forward (NAUTILUS_NAVIGATION_WINDOW (user_data
));
90 forget_history_if_yes (GtkDialog
*dialog
, int response
, gpointer callback_data
)
92 if (response
== RESPONSE_FORGET
) {
93 nautilus_forget_history ();
95 gtk_object_destroy (GTK_OBJECT (dialog
));
99 forget_history_if_confirmed (NautilusWindow
*window
)
105 /* Confirm before forgetting history because it's a rare operation that
106 * is hard to recover from. We don't want people doing it accidentally
107 * when they intended to choose another Go menu item.
109 if ((rand() % 10) == 0) {
110 /* This is a little joke, shows up occasionally. I only
111 * implemented this feature so I could use this joke.
113 prompt
= _("Are you sure you want to forget history?");
114 /* Translators: This is part of a joke and is paired with "Are you sure you want to forget history?" */
115 detail
= _("If you do, you will be doomed to repeat it.");
117 prompt
= _("Are you sure you want to clear the list "
118 "of locations you have visited?");
119 detail
= _("If you clear the list of locations,"
120 " they will be permanently deleted.");
123 dialog
= eel_create_question_dialog (prompt
,
125 GTK_STOCK_CANCEL
, GTK_RESPONSE_CANCEL
,
126 GTK_STOCK_CLEAR
, RESPONSE_FORGET
,
127 GTK_WINDOW (window
));
129 gtk_widget_show (GTK_WIDGET (dialog
));
131 g_signal_connect (dialog
, "response",
132 G_CALLBACK (forget_history_if_yes
), NULL
);
134 gtk_dialog_set_default_response (dialog
, GTK_RESPONSE_CANCEL
);
138 action_clear_history_callback (GtkAction
*action
,
141 forget_history_if_confirmed (NAUTILUS_WINDOW (user_data
));
145 action_show_hide_toolbar_callback (GtkAction
*action
,
148 NautilusNavigationWindow
*window
;
150 window
= NAUTILUS_NAVIGATION_WINDOW (user_data
);
152 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action
))) {
153 nautilus_navigation_window_show_toolbar (window
);
155 nautilus_navigation_window_hide_toolbar (window
);
162 action_show_hide_sidebar_callback (GtkAction
*action
,
165 NautilusNavigationWindow
*window
;
167 window
= NAUTILUS_NAVIGATION_WINDOW (user_data
);
169 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action
))) {
170 nautilus_navigation_window_show_sidebar (window
);
172 nautilus_navigation_window_hide_sidebar (window
);
177 action_show_hide_location_bar_callback (GtkAction
*action
,
180 NautilusNavigationWindow
*window
;
182 window
= NAUTILUS_NAVIGATION_WINDOW (user_data
);
184 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action
))) {
185 nautilus_navigation_window_show_location_bar (window
, TRUE
);
187 nautilus_navigation_window_hide_location_bar (window
, TRUE
);
192 action_show_hide_statusbar_callback (GtkAction
*action
,
195 NautilusNavigationWindow
*window
;
197 window
= NAUTILUS_NAVIGATION_WINDOW (user_data
);
199 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action
))) {
200 nautilus_navigation_window_show_status_bar (window
);
202 nautilus_navigation_window_hide_status_bar (window
);
207 nautilus_navigation_window_update_show_hide_menu_items (NautilusNavigationWindow
*window
)
211 g_assert (NAUTILUS_IS_NAVIGATION_WINDOW (window
));
213 action
= gtk_action_group_get_action (window
->details
->navigation_action_group
,
214 NAUTILUS_ACTION_SHOW_HIDE_TOOLBAR
);
215 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action
),
216 nautilus_navigation_window_toolbar_showing (window
));
218 action
= gtk_action_group_get_action (window
->details
->navigation_action_group
,
219 NAUTILUS_ACTION_SHOW_HIDE_SIDEBAR
);
220 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action
),
221 nautilus_navigation_window_sidebar_showing (window
));
223 action
= gtk_action_group_get_action (window
->details
->navigation_action_group
,
224 NAUTILUS_ACTION_SHOW_HIDE_LOCATION_BAR
);
225 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action
),
226 nautilus_navigation_window_location_bar_showing (window
));
228 action
= gtk_action_group_get_action (window
->details
->navigation_action_group
,
229 NAUTILUS_ACTION_SHOW_HIDE_STATUSBAR
);
230 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action
),
231 nautilus_navigation_window_status_bar_showing (window
));
235 nautilus_navigation_window_update_spatial_menu_item (NautilusNavigationWindow
*window
)
239 g_assert (NAUTILUS_IS_NAVIGATION_WINDOW (window
));
241 action
= gtk_action_group_get_action (window
->details
->navigation_action_group
,
242 NAUTILUS_ACTION_FOLDER_WINDOW
);
243 gtk_action_set_visible (action
,
244 !eel_preferences_get_boolean (NAUTILUS_PREFERENCES_ALWAYS_USE_BROWSER
));
248 action_add_bookmark_callback (GtkAction
*action
,
251 nautilus_window_add_bookmark_for_current_location (NAUTILUS_WINDOW (user_data
));
255 action_edit_bookmarks_callback (GtkAction
*action
,
258 nautilus_window_edit_bookmarks (NAUTILUS_WINDOW (user_data
));
262 nautilus_navigation_window_remove_go_menu_callback (NautilusNavigationWindow
*window
)
264 if (window
->details
->refresh_go_menu_idle_id
!= 0) {
265 g_source_remove (window
->details
->refresh_go_menu_idle_id
);
266 window
->details
->refresh_go_menu_idle_id
= 0;
271 nautilus_navigation_window_remove_go_menu_items (NautilusNavigationWindow
*window
)
273 GtkUIManager
*ui_manager
;
275 ui_manager
= nautilus_window_get_ui_manager (NAUTILUS_WINDOW (window
));
276 if (window
->details
->go_menu_merge_id
!= 0) {
277 gtk_ui_manager_remove_ui (ui_manager
,
278 window
->details
->go_menu_merge_id
);
279 window
->details
->go_menu_merge_id
= 0;
281 if (window
->details
->go_menu_action_group
!= NULL
) {
282 gtk_ui_manager_remove_action_group (ui_manager
,
283 window
->details
->go_menu_action_group
);
284 window
->details
->go_menu_action_group
= NULL
;
289 show_bogus_history_window (NautilusWindow
*window
,
290 NautilusBookmark
*bookmark
)
293 char *uri_for_display
;
296 file
= nautilus_bookmark_get_location (bookmark
);
297 uri_for_display
= g_file_get_parse_name (file
);
299 detail
= g_strdup_printf (_("The location \"%s\" does not exist."), uri_for_display
);
301 eel_show_warning_dialog (_("The history location doesn't exist."),
303 GTK_WINDOW (window
));
305 g_object_unref (file
);
306 g_free (uri_for_display
);
311 connect_proxy_cb (GtkActionGroup
*action_group
,
318 if (!GTK_IS_MENU_ITEM (proxy
))
321 label
= GTK_LABEL (GTK_BIN (proxy
)->child
);
323 gtk_label_set_use_underline (label
, FALSE
);
324 gtk_label_set_ellipsize (label
, PANGO_ELLIPSIZE_END
);
325 gtk_label_set_max_width_chars (label
, MENU_ITEM_MAX_WIDTH_CHARS
);
331 * Refresh list of bookmarks at end of Go menu to match centralized history list.
332 * @window: The NautilusWindow whose Go menu will be refreshed.
335 refresh_go_menu (NautilusNavigationWindow
*window
)
337 GtkUIManager
*ui_manager
;
341 g_assert (NAUTILUS_IS_NAVIGATION_WINDOW (window
));
343 /* Unregister any pending call to this function. */
344 nautilus_navigation_window_remove_go_menu_callback (window
);
346 /* Remove old set of history items. */
347 nautilus_navigation_window_remove_go_menu_items (window
);
349 ui_manager
= nautilus_window_get_ui_manager (NAUTILUS_WINDOW (window
));
351 window
->details
->go_menu_merge_id
= gtk_ui_manager_new_merge_id (ui_manager
);
352 window
->details
->go_menu_action_group
= gtk_action_group_new ("GoMenuGroup");
353 g_signal_connect (window
->details
->go_menu_action_group
, "connect-proxy",
354 G_CALLBACK (connect_proxy_cb
), NULL
);
356 gtk_ui_manager_insert_action_group (ui_manager
,
357 window
->details
->go_menu_action_group
,
359 g_object_unref (window
->details
->go_menu_action_group
);
361 /* Add in a new set of history items. */
362 for (node
= nautilus_get_history_list (), index
= 0;
363 node
!= NULL
&& index
< 10;
364 node
= node
->next
, index
++) {
365 nautilus_menus_append_bookmark_to_menu
366 (NAUTILUS_WINDOW (window
),
367 NAUTILUS_BOOKMARK (node
->data
),
368 MENU_PATH_HISTORY_PLACEHOLDER
,
371 window
->details
->go_menu_action_group
,
372 window
->details
->go_menu_merge_id
,
373 G_CALLBACK (schedule_refresh_go_menu
),
374 show_bogus_history_window
);
379 refresh_go_menu_idle_callback (gpointer data
)
381 g_assert (NAUTILUS_IS_NAVIGATION_WINDOW (data
));
383 refresh_go_menu (NAUTILUS_NAVIGATION_WINDOW (data
));
385 /* Don't call this again (unless rescheduled) */
390 schedule_refresh_go_menu (NautilusNavigationWindow
*window
)
392 g_assert (NAUTILUS_IS_NAVIGATION_WINDOW (window
));
394 if (window
->details
->refresh_go_menu_idle_id
== 0) {
395 window
->details
->refresh_go_menu_idle_id
396 = g_idle_add (refresh_go_menu_idle_callback
,
402 * nautilus_navigation_window_initialize_go_menu
404 * Wire up signals so we'll be notified when history list changes.
407 nautilus_navigation_window_initialize_go_menu (NautilusNavigationWindow
*window
)
409 /* Recreate bookmarks part of menu if history list changes
411 g_signal_connect_object (nautilus_signaller_get_current (), "history_list_changed",
412 G_CALLBACK (schedule_refresh_go_menu
), window
, G_CONNECT_SWAPPED
);
416 action_new_window_callback (GtkAction
*action
,
419 NautilusWindow
*current_window
;
420 NautilusWindow
*new_window
;
422 current_window
= NAUTILUS_WINDOW (user_data
);
423 new_window
= nautilus_application_create_navigation_window (
424 current_window
->application
,
426 gtk_window_get_screen (GTK_WINDOW (current_window
)));
427 nautilus_window_go_home (new_window
);
431 action_folder_window_callback (GtkAction
*action
,
434 NautilusWindow
*current_window
;
435 GFile
*current_location
;
437 current_window
= NAUTILUS_WINDOW (user_data
);
438 current_location
= nautilus_window_get_location (current_window
);
439 nautilus_application_present_spatial_window (
440 current_window
->application
,
444 gtk_window_get_screen (GTK_WINDOW (current_window
)));
445 if (current_location
!= NULL
) {
446 g_object_unref (current_location
);
451 action_go_to_location_callback (GtkAction
*action
,
454 NautilusWindow
*window
;
456 window
= NAUTILUS_WINDOW (user_data
);
458 nautilus_window_prompt_for_location (window
, NULL
);
462 action_search_callback (GtkAction
*action
,
465 NautilusNavigationWindow
*window
;
467 window
= NAUTILUS_NAVIGATION_WINDOW (user_data
);
469 nautilus_navigation_window_show_search (window
);
472 static const GtkActionEntry navigation_entries
[] = {
473 /* name, stock id, label */ { "Go", NULL
, N_("_Go") },
474 /* name, stock id, label */ { "Bookmarks", NULL
, N_("_Bookmarks") },
475 /* name, stock id, label */ { "New Window", "window-new", N_("New _Window"),
476 "<control>N", N_("Open another Nautilus window for the displayed location"),
477 G_CALLBACK (action_new_window_callback
) },
478 /* name, stock id, label */ { "Folder Window", "folder", N_("Open Folder W_indow"),
479 NULL
, N_("Open a folder window for the displayed location"),
480 G_CALLBACK (action_folder_window_callback
) },
481 /* name, stock id, label */ { "Close All Windows", NULL
, N_("Close _All Windows"),
482 "<control><shift>W", N_("Close all Navigation windows"),
483 G_CALLBACK (action_close_all_windows_callback
) },
484 /* name, stock id, label */ { "Go to Location", NULL
, N_("_Location..."),
485 "<control>L", N_("Specify a location to open"),
486 G_CALLBACK (action_go_to_location_callback
) },
487 /* name, stock id, label */ { "Clear History", NULL
, N_("Clea_r History"),
488 NULL
, N_("Clear contents of Go menu and Back/Forward lists"),
489 G_CALLBACK (action_clear_history_callback
) },
490 /* name, stock id, label */ { "Add Bookmark", GTK_STOCK_ADD
, N_("_Add Bookmark"),
491 "<control>d", N_("Add a bookmark for the current location to this menu"),
492 G_CALLBACK (action_add_bookmark_callback
) },
493 /* name, stock id, label */ { "Edit Bookmarks", NULL
, N_("_Edit Bookmarks"),
494 "<control>b", N_("Display a window that allows editing the bookmarks in this menu"),
495 G_CALLBACK (action_edit_bookmarks_callback
) },
496 /* name, stock id, label */ { "Search", "gtk-find", N_("_Search for Files..."),
497 "<control>F", N_("Locate documents and folders on this computer by name or content"),
498 G_CALLBACK (action_search_callback
) },
502 static const GtkToggleActionEntry navigation_toggle_entries
[] = {
503 /* name, stock id */ { "Show Hide Toolbar", NULL
,
504 /* label, accelerator */ N_("_Main Toolbar"), NULL
,
505 /* tooltip */ N_("Change the visibility of this window's main toolbar"),
506 G_CALLBACK (action_show_hide_toolbar_callback
),
507 /* is_active */ TRUE
},
508 /* name, stock id */ { "Show Hide Sidebar", NULL
,
509 /* label, accelerator */ N_("_Side Pane"), "F9",
510 /* tooltip */ N_("Change the visibility of this window's side pane"),
511 G_CALLBACK (action_show_hide_sidebar_callback
),
512 /* is_active */ TRUE
},
513 /* name, stock id */ { "Show Hide Location Bar", NULL
,
514 /* label, accelerator */ N_("Location _Bar"), NULL
,
515 /* tooltip */ N_("Change the visibility of this window's location bar"),
516 G_CALLBACK (action_show_hide_location_bar_callback
),
517 /* is_active */ TRUE
},
518 /* name, stock id */ { "Show Hide Statusbar", NULL
,
519 /* label, accelerator */ N_("St_atusbar"), NULL
,
520 /* tooltip */ N_("Change the visibility of this window's statusbar"),
521 G_CALLBACK (action_show_hide_statusbar_callback
),
522 /* is_active */ TRUE
},
526 nautilus_navigation_window_initialize_actions (NautilusNavigationWindow
*window
)
528 GtkActionGroup
*action_group
;
529 GtkUIManager
*ui_manager
;
532 action_group
= gtk_action_group_new ("NavigationActions");
533 gtk_action_group_set_translation_domain (action_group
, GETTEXT_PACKAGE
);
534 window
->details
->navigation_action_group
= action_group
;
535 gtk_action_group_add_actions (action_group
,
536 navigation_entries
, G_N_ELEMENTS (navigation_entries
),
538 gtk_action_group_add_toggle_actions (action_group
,
539 navigation_toggle_entries
, G_N_ELEMENTS (navigation_toggle_entries
),
542 action
= g_object_new (NAUTILUS_TYPE_NAVIGATION_ACTION
,
545 "stock_id", GTK_STOCK_GO_BACK
,
546 "tooltip", _("Go to the previous visited location"),
547 "arrow-tooltip", _("Back history"),
549 "direction", NAUTILUS_NAVIGATION_DIRECTION_BACK
,
550 "is_important", TRUE
,
552 g_signal_connect (action
, "activate",
553 G_CALLBACK (action_back_callback
), window
);
554 gtk_action_group_add_action_with_accel (action_group
,
557 g_object_unref (action
);
559 action
= g_object_new (NAUTILUS_TYPE_NAVIGATION_ACTION
,
561 "label", _("_Forward"),
562 "stock_id", GTK_STOCK_GO_FORWARD
,
563 "tooltip", _("Go to the next visited location"),
564 "arrow-tooltip", _("Forward history"),
566 "direction", NAUTILUS_NAVIGATION_DIRECTION_FORWARD
,
567 "is_important", TRUE
,
569 g_signal_connect (action
, "activate",
570 G_CALLBACK (action_forward_callback
), window
);
571 gtk_action_group_add_action_with_accel (action_group
,
575 g_object_unref (action
);
577 action
= gtk_action_group_get_action (action_group
, NAUTILUS_ACTION_SEARCH
);
578 g_object_set (action
, "short_label", _("_Search"), NULL
);
580 ui_manager
= nautilus_window_get_ui_manager (NAUTILUS_WINDOW (window
));
582 gtk_ui_manager_insert_action_group (ui_manager
, action_group
, 0);
583 g_object_unref (action_group
); /* owned by ui_manager */
588 * nautilus_window_initialize_menus
590 * Create and install the set of menus for this window.
591 * @window: A recently-created NautilusWindow.
594 nautilus_navigation_window_initialize_menus (NautilusNavigationWindow
*window
)
596 GtkUIManager
*ui_manager
;
599 ui_manager
= nautilus_window_get_ui_manager (NAUTILUS_WINDOW (window
));
601 ui
= nautilus_ui_string_get ("nautilus-navigation-window-ui.xml");
602 gtk_ui_manager_add_ui_from_string (ui_manager
, ui
, -1, NULL
);
604 nautilus_navigation_window_update_show_hide_menu_items (window
);
605 nautilus_navigation_window_update_spatial_menu_item (window
);
607 nautilus_navigation_window_initialize_go_menu (window
);