2008-04-30 Cosimo Cecchi <cosimoc@gnome.org>
[nautilus.git] / src / nautilus-navigation-window-menus.c
blob3d9e445fc908272e4c6d4aaa596348b7f6a30c39
1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
3 /*
4 * Nautilus
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.
28 #include <config.h>
30 #include <locale.h>
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);
68 static void
69 action_close_all_windows_callback (GtkAction *action,
70 gpointer user_data)
72 nautilus_application_close_all_navigation_windows ();
75 static void
76 action_back_callback (GtkAction *action,
77 gpointer user_data)
79 nautilus_navigation_window_go_back (NAUTILUS_NAVIGATION_WINDOW (user_data));
82 static void
83 action_forward_callback (GtkAction *action,
84 gpointer user_data)
86 nautilus_navigation_window_go_forward (NAUTILUS_NAVIGATION_WINDOW (user_data));
89 static void
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));
98 static void
99 forget_history_if_confirmed (NautilusWindow *window)
101 GtkDialog *dialog;
102 char *prompt;
103 char *detail;
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.");
116 } else {
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,
124 detail,
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);
137 static void
138 action_clear_history_callback (GtkAction *action,
139 gpointer user_data)
141 forget_history_if_confirmed (NAUTILUS_WINDOW (user_data));
144 static void
145 action_show_hide_toolbar_callback (GtkAction *action,
146 gpointer user_data)
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);
154 } else {
155 nautilus_navigation_window_hide_toolbar (window);
161 static void
162 action_show_hide_sidebar_callback (GtkAction *action,
163 gpointer user_data)
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);
171 } else {
172 nautilus_navigation_window_hide_sidebar (window);
176 static void
177 action_show_hide_location_bar_callback (GtkAction *action,
178 gpointer user_data)
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);
186 } else {
187 nautilus_navigation_window_hide_location_bar (window, TRUE);
191 static void
192 action_show_hide_statusbar_callback (GtkAction *action,
193 gpointer user_data)
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);
201 } else {
202 nautilus_navigation_window_hide_status_bar (window);
206 void
207 nautilus_navigation_window_update_show_hide_menu_items (NautilusNavigationWindow *window)
209 GtkAction *action;
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));
234 void
235 nautilus_navigation_window_update_spatial_menu_item (NautilusNavigationWindow *window)
237 GtkAction *action;
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));
247 static void
248 action_add_bookmark_callback (GtkAction *action,
249 gpointer user_data)
251 nautilus_window_add_bookmark_for_current_location (NAUTILUS_WINDOW (user_data));
254 static void
255 action_edit_bookmarks_callback (GtkAction *action,
256 gpointer user_data)
258 nautilus_window_edit_bookmarks (NAUTILUS_WINDOW (user_data));
261 void
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;
270 void
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;
288 static void
289 show_bogus_history_window (NautilusWindow *window,
290 NautilusBookmark *bookmark)
292 GFile *file;
293 char *uri_for_display;
294 char *detail;
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."),
302 detail,
303 GTK_WINDOW (window));
305 g_object_unref (file);
306 g_free (uri_for_display);
307 g_free (detail);
310 static void
311 connect_proxy_cb (GtkActionGroup *action_group,
312 GtkAction *action,
313 GtkWidget *proxy,
314 gpointer dummy)
316 GtkLabel *label;
318 if (!GTK_IS_MENU_ITEM (proxy))
319 return;
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);
329 * refresh_go_menu:
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.
334 static void
335 refresh_go_menu (NautilusNavigationWindow *window)
337 GtkUIManager *ui_manager;
338 GList *node;
339 int index;
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,
358 -1);
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,
369 "history",
370 index,
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);
378 static gboolean
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) */
386 return FALSE;
389 static void
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,
397 window);
402 * nautilus_navigation_window_initialize_go_menu
404 * Wire up signals so we'll be notified when history list changes.
406 static void
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);
415 static void
416 action_new_window_callback (GtkAction *action,
417 gpointer user_data)
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,
425 NULL,
426 gtk_window_get_screen (GTK_WINDOW (current_window)));
427 nautilus_window_go_home (new_window);
430 static void
431 action_folder_window_callback (GtkAction *action,
432 gpointer user_data)
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,
441 current_window,
442 NULL,
443 current_location,
444 gtk_window_get_screen (GTK_WINDOW (current_window)));
445 if (current_location != NULL) {
446 g_object_unref (current_location);
450 static void
451 action_go_to_location_callback (GtkAction *action,
452 gpointer user_data)
454 NautilusWindow *window;
456 window = NAUTILUS_WINDOW (user_data);
458 nautilus_window_prompt_for_location (window, NULL);
461 static void
462 action_search_callback (GtkAction *action,
463 gpointer user_data)
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 },
525 void
526 nautilus_navigation_window_initialize_actions (NautilusNavigationWindow *window)
528 GtkActionGroup *action_group;
529 GtkUIManager *ui_manager;
530 GtkAction *action;
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),
537 window);
538 gtk_action_group_add_toggle_actions (action_group,
539 navigation_toggle_entries, G_N_ELEMENTS (navigation_toggle_entries),
540 window);
542 action = g_object_new (NAUTILUS_TYPE_NAVIGATION_ACTION,
543 "name", "Back",
544 "label", _("_Back"),
545 "stock_id", GTK_STOCK_GO_BACK,
546 "tooltip", _("Go to the previous visited location"),
547 "arrow-tooltip", _("Back history"),
548 "window", window,
549 "direction", NAUTILUS_NAVIGATION_DIRECTION_BACK,
550 "is_important", TRUE,
551 NULL);
552 g_signal_connect (action, "activate",
553 G_CALLBACK (action_back_callback), window);
554 gtk_action_group_add_action_with_accel (action_group,
555 action,
556 "<alt>Left");
557 g_object_unref (action);
559 action = g_object_new (NAUTILUS_TYPE_NAVIGATION_ACTION,
560 "name", "Forward",
561 "label", _("_Forward"),
562 "stock_id", GTK_STOCK_GO_FORWARD,
563 "tooltip", _("Go to the next visited location"),
564 "arrow-tooltip", _("Forward history"),
565 "window", window,
566 "direction", NAUTILUS_NAVIGATION_DIRECTION_FORWARD,
567 "is_important", TRUE,
568 NULL);
569 g_signal_connect (action, "activate",
570 G_CALLBACK (action_forward_callback), window);
571 gtk_action_group_add_action_with_accel (action_group,
572 action,
573 "<alt>Right");
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.
593 void
594 nautilus_navigation_window_initialize_menus (NautilusNavigationWindow *window)
596 GtkUIManager *ui_manager;
597 const char *ui;
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);