system_menu_model_builder.cc revision f2477e01787aa58f445919b809d89e252beef54f
1// Copyright (c) 2013 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "chrome/browser/ui/views/frame/system_menu_model_builder.h" 6 7#include "base/command_line.h" 8#include "base/strings/utf_string_conversions.h" 9#include "chrome/app/chrome_command_ids.h" 10#include "chrome/browser/ui/browser_commands.h" 11#include "chrome/browser/ui/host_desktop.h" 12#include "chrome/browser/ui/toolbar/wrench_menu_model.h" 13#include "chrome/common/chrome_switches.h" 14#include "grit/generated_resources.h" 15#include "ui/base/accelerators/accelerator.h" 16#include "ui/base/models/simple_menu_model.h" 17 18#if defined(OS_CHROMEOS) 19#include "ash/session_state_delegate.h" 20#include "ash/shell.h" 21#include "chrome/browser/ui/ash/multi_user/multi_user_util.h" 22#include "chrome/browser/ui/ash/multi_user/multi_user_window_manager.h" 23#include "chrome/browser/ui/browser_window.h" 24#include "ui/base/l10n/l10n_util.h" 25#endif 26 27SystemMenuModelBuilder::SystemMenuModelBuilder( 28 ui::AcceleratorProvider* provider, 29 Browser* browser) 30 : menu_delegate_(provider, browser) { 31} 32 33SystemMenuModelBuilder::~SystemMenuModelBuilder() { 34} 35 36void SystemMenuModelBuilder::Init() { 37 ui::SimpleMenuModel* model = new ui::SimpleMenuModel(&menu_delegate_); 38 menu_model_.reset(model); 39 BuildMenu(model); 40#if defined(OS_WIN) 41 // On Windows with HOST_DESKTOP_TYPE_NATIVE we put the menu items in the 42 // system menu (not at the end). Doing this necessitates adding a trailing 43 // separator. 44 if (browser()->host_desktop_type() == chrome::HOST_DESKTOP_TYPE_NATIVE) 45 model->AddSeparator(ui::NORMAL_SEPARATOR); 46#endif 47} 48 49void SystemMenuModelBuilder::BuildMenu(ui::SimpleMenuModel* model) { 50 // We add the menu items in reverse order so that insertion_index never needs 51 // to change. 52 if (browser()->is_type_tabbed()) 53 BuildSystemMenuForBrowserWindow(model); 54 else 55 BuildSystemMenuForAppOrPopupWindow(model); 56 AddFrameToggleItems(model); 57} 58 59void SystemMenuModelBuilder::BuildSystemMenuForBrowserWindow( 60 ui::SimpleMenuModel* model) { 61 model->AddItemWithStringId(IDC_NEW_TAB, IDS_NEW_TAB); 62 model->AddItemWithStringId(IDC_RESTORE_TAB, IDS_RESTORE_TAB); 63 if (chrome::CanOpenTaskManager()) { 64 model->AddSeparator(ui::NORMAL_SEPARATOR); 65 model->AddItemWithStringId(IDC_TASK_MANAGER, IDS_TASK_MANAGER); 66 } 67 AppendTeleportMenu(model); 68 // If it's a regular browser window with tabs, we don't add any more items, 69 // since it already has menus (Page, Chrome). 70} 71 72void SystemMenuModelBuilder::BuildSystemMenuForAppOrPopupWindow( 73 ui::SimpleMenuModel* model) { 74 model->AddItemWithStringId(IDC_BACK, IDS_CONTENT_CONTEXT_BACK); 75 model->AddItemWithStringId(IDC_FORWARD, IDS_CONTENT_CONTEXT_FORWARD); 76 model->AddItemWithStringId(IDC_RELOAD, IDS_APP_MENU_RELOAD); 77 model->AddSeparator(ui::NORMAL_SEPARATOR); 78 if (browser()->is_app()) 79 model->AddItemWithStringId(IDC_NEW_TAB, IDS_APP_MENU_NEW_WEB_PAGE); 80 else 81 model->AddItemWithStringId(IDC_SHOW_AS_TAB, IDS_SHOW_AS_TAB); 82 model->AddSeparator(ui::NORMAL_SEPARATOR); 83 model->AddItemWithStringId(IDC_CUT, IDS_CUT); 84 model->AddItemWithStringId(IDC_COPY, IDS_COPY); 85 model->AddItemWithStringId(IDC_PASTE, IDS_PASTE); 86 model->AddSeparator(ui::NORMAL_SEPARATOR); 87 model->AddItemWithStringId(IDC_FIND, IDS_FIND); 88 model->AddItemWithStringId(IDC_PRINT, IDS_PRINT); 89 zoom_menu_contents_.reset(new ZoomMenuModel(&menu_delegate_)); 90 model->AddSubMenuWithStringId(IDC_ZOOM_MENU, IDS_ZOOM_MENU, 91 zoom_menu_contents_.get()); 92 encoding_menu_contents_.reset(new EncodingMenuModel(browser())); 93 model->AddSubMenuWithStringId(IDC_ENCODING_MENU, 94 IDS_ENCODING_MENU, 95 encoding_menu_contents_.get()); 96 if (browser()->is_app() && chrome::CanOpenTaskManager()) { 97 model->AddSeparator(ui::NORMAL_SEPARATOR); 98 model->AddItemWithStringId(IDC_TASK_MANAGER, IDS_TASK_MANAGER); 99 } 100 101 AppendTeleportMenu(model); 102} 103 104void SystemMenuModelBuilder::AddFrameToggleItems(ui::SimpleMenuModel* model) { 105 if (CommandLine::ForCurrentProcess()->HasSwitch( 106 switches::kDebugEnableFrameToggle)) { 107 model->AddSeparator(ui::NORMAL_SEPARATOR); 108 model->AddItem(IDC_DEBUG_FRAME_TOGGLE, ASCIIToUTF16("Toggle Frame Type")); 109 } 110} 111 112void SystemMenuModelBuilder::AppendTeleportMenu(ui::SimpleMenuModel* model) { 113#if defined(OS_CHROMEOS) 114 DCHECK(browser()->window()); 115 // If there is no manager, we are not in the proper multi user mode. 116 if (chrome::MultiUserWindowManager::GetMultiProfileMode() != 117 chrome::MultiUserWindowManager::MULTI_PROFILE_MODE_SEPARATED) 118 return; 119 120 // To show the menu we need at least two logged in users. 121 ash::SessionStateDelegate* delegate = 122 ash::Shell::GetInstance()->session_state_delegate(); 123 int logged_in_users = delegate->NumberOfLoggedInUsers(); 124 if (logged_in_users <= 1) 125 return; 126 127 // If this does not belong to a profile or there is no window, or the window 128 // is not owned by anyone, we don't show the menu addition. 129 chrome::MultiUserWindowManager* manager = 130 chrome::MultiUserWindowManager::GetInstance(); 131 const std::string user_id = 132 multi_user_util::GetUserIDFromProfile(browser()->profile()); 133 aura::Window* window = browser()->window()->GetNativeWindow(); 134 if (user_id.empty() || !window || manager->GetWindowOwner(window).empty()) 135 return; 136 137 model->AddSeparator(ui::NORMAL_SEPARATOR); 138 DCHECK(logged_in_users <= 3); 139 for (int user_index = 1; user_index < logged_in_users; ++user_index) { 140 model->AddItem( 141 user_index == 1 ? IDC_VISIT_DESKTOP_OF_LRU_USER_2 : 142 IDC_VISIT_DESKTOP_OF_LRU_USER_3, 143 l10n_util::GetStringFUTF16(IDC_VISIT_DESKTOP_OF_LRU_USER, 144 delegate->GetUserDisplayName(user_index))); 145 } 146#endif 147} 148