From 07cf7db47fd5fae64201f1cff73e39fd8aed2f54 Mon Sep 17 00:00:00 2001 From: Christian Neumair Date: Tue, 8 Jul 2008 21:05:55 +0000 Subject: Merge "multiview" tab branch. Fixes #48034. 2008-07-08 Christian Neumair * libnautilus-private/*.c: * src/*.c: Merge "multiview" tab branch. Fixes #48034. svn path=/trunk/; revision=14328 --- src/nautilus-navigation-window-menus.c | 344 ++++++++++++++++++++++++++++++++- 1 file changed, 340 insertions(+), 4 deletions(-) (limited to 'src/nautilus-navigation-window-menus.c') diff --git a/src/nautilus-navigation-window-menus.c b/src/nautilus-navigation-window-menus.c index 78600d57d..d2ec55052 100644 --- a/src/nautilus-navigation-window-menus.c +++ b/src/nautilus-navigation-window-menus.c @@ -30,6 +30,7 @@ #include #include "nautilus-actions.h" +#include "nautilus-notebook.h" #include "nautilus-navigation-action.h" #include "nautilus-application.h" #include "nautilus-bookmark-list.h" @@ -59,6 +60,7 @@ #include #define MENU_PATH_HISTORY_PLACEHOLDER "/MenuBar/Other Menus/Go/History Placeholder" +#define MENU_PATH_TABS_PLACEHOLDER "/MenuBar/Other Menus/Tabs/TabsOpen" #define RESPONSE_FORGET 1000 #define MENU_ITEM_MAX_WIDTH_CHARS 32 @@ -72,18 +74,36 @@ action_close_all_windows_callback (GtkAction *action, nautilus_application_close_all_navigation_windows (); } +static gboolean +should_open_in_new_tab (void) +{ + /* FIXME this is duplicated */ + GdkEvent *event; + + event = gtk_get_current_event (); + if (event->type == GDK_BUTTON_PRESS || event->type == GDK_BUTTON_RELEASE) { + return event->button.button == 2; + } + + gdk_event_free (event); + + return FALSE; +} + static void action_back_callback (GtkAction *action, gpointer user_data) { - nautilus_navigation_window_go_back (NAUTILUS_NAVIGATION_WINDOW (user_data)); + nautilus_navigation_window_back_or_forward (NAUTILUS_NAVIGATION_WINDOW (user_data), + TRUE, 0, should_open_in_new_tab ()); } static void action_forward_callback (GtkAction *action, gpointer user_data) { - nautilus_navigation_window_go_forward (NAUTILUS_NAVIGATION_WINDOW (user_data)); + nautilus_navigation_window_back_or_forward (NAUTILUS_NAVIGATION_WINDOW (user_data), + TRUE, 0, should_open_in_new_tab ()); } static void @@ -244,6 +264,23 @@ nautilus_navigation_window_update_spatial_menu_item (NautilusNavigationWindow *w !eel_preferences_get_boolean (NAUTILUS_PREFERENCES_ALWAYS_USE_BROWSER)); } +void +nautilus_navigation_window_update_tab_menu_item_visibility (NautilusNavigationWindow *window) +{ + GtkAction *action; + + action = gtk_action_group_get_action (window->details->navigation_action_group, + NAUTILUS_ACTION_TABS); + gtk_action_set_visible (action, + eel_preferences_get_boolean (NAUTILUS_PREFERENCES_ENABLE_TABS)); + + action = gtk_action_group_get_action (window->details->navigation_action_group, + NAUTILUS_ACTION_NEW_TAB); + gtk_action_set_visible (action, + eel_preferences_get_boolean (NAUTILUS_PREFERENCES_ENABLE_TABS)); + +} + static void action_add_bookmark_callback (GtkAction *action, gpointer user_data) @@ -412,6 +449,200 @@ nautilus_navigation_window_initialize_go_menu (NautilusNavigationWindow *window) G_CALLBACK (schedule_refresh_go_menu), window, G_CONNECT_SWAPPED); } +static void +update_tab_action_sensitivity (NautilusNavigationWindow *window) +{ + GtkActionGroup *action_group; + GtkAction *action; + NautilusNotebook *notebook; + gboolean sensitive; + int tab_num; + + g_assert (NAUTILUS_IS_NAVIGATION_WINDOW (window)); + + notebook = NAUTILUS_NOTEBOOK (window->notebook); + action_group = window->details->navigation_action_group; + + action = gtk_action_group_get_action (action_group, "TabsPrevious"); + sensitive = nautilus_notebook_can_set_current_page_relative (notebook, -1); + g_object_set (action, "sensitive", sensitive, NULL); + + action = gtk_action_group_get_action (action_group, "TabsNext"); + sensitive = nautilus_notebook_can_set_current_page_relative (notebook, 1); + g_object_set (action, "sensitive", sensitive, NULL); + + action = gtk_action_group_get_action (action_group, "TabsMoveLeft"); + sensitive = nautilus_notebook_can_reorder_current_child_relative (notebook, -1); + g_object_set (action, "sensitive", sensitive, NULL); + + action = gtk_action_group_get_action (action_group, "TabsMoveRight"); + sensitive = nautilus_notebook_can_reorder_current_child_relative (notebook, 1); + g_object_set (action, "sensitive", sensitive, NULL); + + action_group = window->details->tabs_menu_action_group; + tab_num = gtk_notebook_get_current_page (GTK_NOTEBOOK (notebook)); + action = gtk_action_group_get_action (action_group, "Tab0"); + if (tab_num >= 0 && action != NULL) { + gtk_radio_action_set_current_value (GTK_RADIO_ACTION (action), tab_num); + } +} + +static void +tab_menu_action_activate_callback (GtkAction *action, + gpointer user_data) +{ + int num; + GtkWidget *notebook; + NautilusNavigationWindow *window; + + window = NAUTILUS_NAVIGATION_WINDOW (user_data); + notebook = window->notebook; + + num = gtk_radio_action_get_current_value (GTK_RADIO_ACTION (action)); + + gtk_notebook_set_current_page (GTK_NOTEBOOK (notebook), num); +} + +static void +reload_tab_menu (NautilusNavigationWindow *window) +{ + GtkRadioAction *action; + GtkUIManager *ui_manager; + int i; + gchar action_name[80]; + gchar *action_label; + gchar accelerator[80]; + GSList *radio_group; + NautilusWindowSlot *slot; + GtkNotebook *notebook; + + g_assert (NAUTILUS_IS_NAVIGATION_WINDOW (window)); + + /* Remove old tab menu items */ + ui_manager = nautilus_window_get_ui_manager (NAUTILUS_WINDOW (window)); + if (window->details->tabs_menu_merge_id != 0) { + gtk_ui_manager_remove_ui (ui_manager, + window->details->tabs_menu_merge_id); + window->details->tabs_menu_merge_id = 0; + } + if (window->details->tabs_menu_action_group != NULL) { + gtk_ui_manager_remove_action_group (ui_manager, + window->details->tabs_menu_action_group); + window->details->tabs_menu_action_group = NULL; + } + + /* Add new tab menu items */ + window->details->tabs_menu_merge_id = gtk_ui_manager_new_merge_id (ui_manager); + window->details->tabs_menu_action_group = gtk_action_group_new ("TabsMenuGroup"); + + gtk_ui_manager_insert_action_group (ui_manager, + window->details->tabs_menu_action_group, + -1); + g_object_unref (window->details->tabs_menu_action_group); + + notebook = GTK_NOTEBOOK (window->notebook); + radio_group = NULL; + for (i = 0; i < gtk_notebook_get_n_pages (notebook); i++) { + + snprintf(action_name, sizeof (action_name), "Tab%d", i); + + slot = nautilus_window_get_slot_for_content_box (NAUTILUS_WINDOW (window), + gtk_notebook_get_nth_page (notebook, i)); + if (slot) { + action_label = g_strdup (slot->title); + } else { + /* Give the action a generic label. This should only happen when the tab is created + * and the slot has not yet be created, so if all goes to plan then the action label + * will be updated when the slot is created. */ + action_label = g_strdup_printf ("Tab %d", i); + } + + action = gtk_radio_action_new (action_name, action_label, NULL, NULL, i); + + g_free (action_label); + action_label = NULL; + + gtk_radio_action_set_group (action, radio_group); + radio_group = gtk_radio_action_get_group (action); + + g_signal_connect (action, "activate", + G_CALLBACK (tab_menu_action_activate_callback), + window); + + /* Use Alt+(Number) keyboard accelerators for first 10 tabs */ + if (i < 10) { + snprintf(accelerator, sizeof (accelerator), "%d", (i+1)%10); + } else { + accelerator[0] = '\0'; + } + gtk_action_group_add_action_with_accel (window->details->tabs_menu_action_group, + GTK_ACTION (action), + accelerator); + + g_object_unref (action); + + gtk_ui_manager_add_ui (ui_manager, + window->details->tabs_menu_merge_id, + MENU_PATH_TABS_PLACEHOLDER, + action_name, + action_name, + GTK_UI_MANAGER_MENUITEM, + FALSE); + } + + update_tab_action_sensitivity (window); +} + +static void +nautilus_navigation_window_initialize_tabs_menu (NautilusNavigationWindow *window) +{ + g_signal_connect_object (window->notebook, "page-added", + G_CALLBACK (reload_tab_menu), window, G_CONNECT_SWAPPED); + g_signal_connect_object (window->notebook, "page-removed", + G_CALLBACK (reload_tab_menu), window, G_CONNECT_SWAPPED); + g_signal_connect_object (window->notebook, "page-reordered", + G_CALLBACK (reload_tab_menu), window, G_CONNECT_SWAPPED); + g_signal_connect_object (window->notebook, "switch-page", + G_CALLBACK (update_tab_action_sensitivity), window, + G_CONNECT_SWAPPED | G_CONNECT_AFTER); + + reload_tab_menu (window); +} + +/* Update the label displayed in the "Tabs" menu. This is called when the title of + * a slot changes. */ +void +nautilus_navigation_window_sync_tab_menu_title (NautilusNavigationWindow *window, + NautilusWindowSlot *slot) +{ + int tab_num; + GtkNotebook *notebook; + GtkAction *action; + GtkActionGroup *action_group; + char action_name[80]; + + notebook = GTK_NOTEBOOK (window->notebook); + + /* Find the tab number for that slot. It should (almost?) always be the current + * tab, so check that first in order to avoid searching through the entire tab + * list. */ + tab_num = gtk_notebook_get_current_page (notebook); + if (slot->content_box != gtk_notebook_get_nth_page (notebook, tab_num)) { + tab_num = gtk_notebook_page_num (notebook, slot->content_box); + } + + g_return_if_fail (tab_num >= 0); + + /* Find the action associated with that tab */ + action_group = window->details->tabs_menu_action_group; + snprintf (action_name, sizeof (action_name), "Tab%d", tab_num); + action = gtk_action_group_get_action (action_group, action_name); + + /* Update the label */ + g_return_if_fail (action); + g_object_set (action, "label", slot->title, NULL); +} + static void action_new_window_callback (GtkAction *action, gpointer user_data) @@ -427,15 +658,61 @@ action_new_window_callback (GtkAction *action, nautilus_window_go_home (new_window); } +static void +action_new_tab_callback (GtkAction *action, + gpointer user_data) +{ + NautilusWindow *window; + NautilusWindowSlot *current_slot; + NautilusWindowSlot *new_slot; + NautilusWindowOpenFlags flags; + GFile *location; + int new_slot_position; + char *scheme; + + if (!eel_preferences_get_boolean (NAUTILUS_PREFERENCES_ENABLE_TABS)) { + return; + } + + window = NAUTILUS_WINDOW (user_data); + current_slot = window->details->active_slot; + location = nautilus_window_slot_get_location (current_slot); + + window = NAUTILUS_WINDOW (current_slot->window); + + if (location != NULL) { + flags = 0; + + new_slot_position = eel_preferences_get_enum (NAUTILUS_PREFERENCES_NEW_TAB_POSITION); + if (new_slot_position == NAUTILUS_NEW_TAB_POSITION_END) { + flags = NAUTILUS_WINDOW_OPEN_SLOT_APPEND; + } + + scheme = g_file_get_uri_scheme (location); + if (!strcmp (scheme, "x-nautilus-search")) { + g_object_unref (location); + location = g_file_new_for_path (g_get_home_dir ()); + } + g_free (scheme); + + new_slot = nautilus_window_open_slot (window, flags); + nautilus_window_set_active_slot (window, new_slot); + nautilus_window_slot_go_to (new_slot, location, FALSE); + g_object_unref (location); + } +} + static void action_folder_window_callback (GtkAction *action, gpointer user_data) { NautilusWindow *current_window; + NautilusWindowSlot *slot; GFile *current_location; current_window = NAUTILUS_WINDOW (user_data); - current_location = nautilus_window_get_location (current_window); + slot = current_window->details->active_slot; + current_location = nautilus_window_slot_get_location (slot); nautilus_application_present_spatial_window ( current_window->application, current_window, @@ -469,12 +746,56 @@ action_search_callback (GtkAction *action, nautilus_navigation_window_show_search (window); } +static void +action_tabs_previous_callback (GtkAction *action, + gpointer user_data) +{ + NautilusNavigationWindow *window; + + window = NAUTILUS_NAVIGATION_WINDOW (user_data); + nautilus_notebook_set_current_page_relative (NAUTILUS_NOTEBOOK (window->notebook), -1); +} + +static void +action_tabs_next_callback (GtkAction *action, + gpointer user_data) +{ + NautilusNavigationWindow *window; + + window = NAUTILUS_NAVIGATION_WINDOW (user_data); + nautilus_notebook_set_current_page_relative (NAUTILUS_NOTEBOOK (window->notebook), 1); +} + +static void +action_tabs_move_left_callback (GtkAction *action, + gpointer user_data) +{ + NautilusNavigationWindow *window; + + window = NAUTILUS_NAVIGATION_WINDOW (user_data); + nautilus_notebook_reorder_current_child_relative (NAUTILUS_NOTEBOOK (window->notebook), -1); +} + +static void +action_tabs_move_right_callback (GtkAction *action, + gpointer user_data) +{ + NautilusNavigationWindow *window; + + window = NAUTILUS_NAVIGATION_WINDOW (user_data); + nautilus_notebook_reorder_current_child_relative (NAUTILUS_NOTEBOOK (window->notebook), 1); +} + static const GtkActionEntry navigation_entries[] = { /* name, stock id, label */ { "Go", NULL, N_("_Go") }, /* name, stock id, label */ { "Bookmarks", NULL, N_("_Bookmarks") }, + /* name, stock id, label */ { "Tabs", NULL, N_("_Tabs") }, /* name, stock id, label */ { "New Window", "window-new", N_("New _Window"), "N", N_("Open another Nautilus window for the displayed location"), G_CALLBACK (action_new_window_callback) }, + /* name, stock id, label */ { "New Tab", "tab-new", N_("New _Tab"), + "T", N_("Open another tab for the displayed location"), + G_CALLBACK (action_new_tab_callback) }, /* name, stock id, label */ { "Folder Window", "folder", N_("Open Folder W_indow"), NULL, N_("Open a folder window for the displayed location"), G_CALLBACK (action_folder_window_callback) }, @@ -496,7 +817,20 @@ static const GtkActionEntry navigation_entries[] = { /* name, stock id, label */ { "Search", "gtk-find", N_("_Search for Files..."), "F", N_("Locate documents and folders on this computer by name or content"), G_CALLBACK (action_search_callback) }, - + + { "TabsPrevious", NULL, N_("_Previous Tab"), "Page_Up", + N_("Activate previous tab"), + G_CALLBACK (action_tabs_previous_callback) }, + { "TabsNext", NULL, N_("_Next Tab"), "Page_Down", + N_("Activate next tab"), + G_CALLBACK (action_tabs_next_callback) }, + { "TabsMoveLeft", NULL, N_("Move Tab _Left"), "Page_Up", + N_("Move current tab to left"), + G_CALLBACK (action_tabs_move_left_callback) }, + { "TabsMoveRight", NULL, N_("Move Tab _Right"), "Page_Down", + N_("Move current tab to right"), + G_CALLBACK (action_tabs_move_right_callback) }, + }; static const GtkToggleActionEntry navigation_toggle_entries[] = { @@ -603,7 +937,9 @@ nautilus_navigation_window_initialize_menus (NautilusNavigationWindow *window) nautilus_navigation_window_update_show_hide_menu_items (window); nautilus_navigation_window_update_spatial_menu_item (window); + nautilus_navigation_window_update_tab_menu_item_visibility (window); nautilus_navigation_window_initialize_go_menu (window); + nautilus_navigation_window_initialize_tabs_menu (window); } -- cgit v1.2.1