Add new certificateProvider extension API.
[chromium-blink-merge.git] / chrome / browser / ui / views / frame / system_menu_model_builder.cc
blob0e5d48fb30939ff9f0b6900653728431ef8f3462
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.
5 #include "chrome/browser/ui/views/frame/system_menu_model_builder.h"
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/tabs/tab_strip_model.h"
13 #include "chrome/browser/ui/toolbar/wrench_menu_model.h"
14 #include "chrome/common/chrome_switches.h"
15 #include "chrome/common/url_constants.h"
16 #include "chrome/grit/generated_resources.h"
17 #include "ui/base/accelerators/accelerator.h"
18 #include "ui/base/models/simple_menu_model.h"
20 #if defined(OS_CHROMEOS)
21 #include "ash/session/session_state_delegate.h"
22 #include "ash/shell.h"
23 #include "chrome/browser/ui/ash/multi_user/multi_user_util.h"
24 #include "chrome/browser/ui/ash/multi_user/multi_user_window_manager.h"
25 #include "chrome/browser/ui/browser_window.h"
26 #include "components/user_manager/user_info.h"
27 #include "ui/base/l10n/l10n_util.h"
28 #endif
30 namespace {
32 // Given a |browser| that's an app or popup window, checks if it's hosting the
33 // settings page.
34 bool IsChromeSettingsAppOrPopupWindow(Browser* browser) {
35 DCHECK(browser);
36 TabStripModel* tab_strip = browser->tab_strip_model();
37 DCHECK_EQ(1, tab_strip->count());
38 const GURL gurl(tab_strip->GetWebContentsAt(0)->GetURL());
39 if (gurl.SchemeIs(content::kChromeUIScheme) &&
40 gurl.host().find(chrome::kChromeUISettingsHost) != std::string::npos) {
41 return true;
43 return false;
46 } // namespace
48 SystemMenuModelBuilder::SystemMenuModelBuilder(
49 ui::AcceleratorProvider* provider,
50 Browser* browser)
51 : menu_delegate_(provider, browser) {
54 SystemMenuModelBuilder::~SystemMenuModelBuilder() {
57 void SystemMenuModelBuilder::Init() {
58 ui::SimpleMenuModel* model = new ui::SimpleMenuModel(&menu_delegate_);
59 menu_model_.reset(model);
60 BuildMenu(model);
61 #if defined(OS_WIN)
62 // On Windows with HOST_DESKTOP_TYPE_NATIVE we put the menu items in the
63 // system menu (not at the end). Doing this necessitates adding a trailing
64 // separator.
65 if (browser()->host_desktop_type() == chrome::HOST_DESKTOP_TYPE_NATIVE)
66 model->AddSeparator(ui::NORMAL_SEPARATOR);
67 #endif
70 void SystemMenuModelBuilder::BuildMenu(ui::SimpleMenuModel* model) {
71 // We add the menu items in reverse order so that insertion_index never needs
72 // to change.
73 if (browser()->is_type_tabbed())
74 BuildSystemMenuForBrowserWindow(model);
75 else
76 BuildSystemMenuForAppOrPopupWindow(model);
77 AddFrameToggleItems(model);
80 void SystemMenuModelBuilder::BuildSystemMenuForBrowserWindow(
81 ui::SimpleMenuModel* model) {
82 model->AddItemWithStringId(IDC_NEW_TAB, IDS_NEW_TAB);
83 model->AddItemWithStringId(IDC_RESTORE_TAB, IDS_RESTORE_TAB);
84 if (chrome::CanOpenTaskManager()) {
85 model->AddSeparator(ui::NORMAL_SEPARATOR);
86 model->AddItemWithStringId(IDC_TASK_MANAGER, IDS_TASK_MANAGER);
88 #if defined(OS_LINUX) && !defined(OS_CHROMEOS)
89 model->AddSeparator(ui::NORMAL_SEPARATOR);
90 model->AddCheckItemWithStringId(IDC_USE_SYSTEM_TITLE_BAR,
91 IDS_SHOW_WINDOW_DECORATIONS_MENU);
92 #endif
93 AppendTeleportMenu(model);
94 // If it's a regular browser window with tabs, we don't add any more items,
95 // since it already has menus (Page, Chrome).
98 void SystemMenuModelBuilder::BuildSystemMenuForAppOrPopupWindow(
99 ui::SimpleMenuModel* model) {
100 model->AddItemWithStringId(IDC_BACK, IDS_CONTENT_CONTEXT_BACK);
101 model->AddItemWithStringId(IDC_FORWARD, IDS_CONTENT_CONTEXT_FORWARD);
102 model->AddItemWithStringId(IDC_RELOAD, IDS_APP_MENU_RELOAD);
103 model->AddSeparator(ui::NORMAL_SEPARATOR);
104 if (browser()->is_app())
105 model->AddItemWithStringId(IDC_NEW_TAB, IDS_APP_MENU_NEW_WEB_PAGE);
106 else
107 model->AddItemWithStringId(IDC_SHOW_AS_TAB, IDS_SHOW_AS_TAB);
108 model->AddSeparator(ui::NORMAL_SEPARATOR);
109 model->AddItemWithStringId(IDC_CUT, IDS_CUT);
110 model->AddItemWithStringId(IDC_COPY, IDS_COPY);
111 model->AddItemWithStringId(IDC_PASTE, IDS_PASTE);
112 model->AddSeparator(ui::NORMAL_SEPARATOR);
113 model->AddItemWithStringId(IDC_FIND, IDS_FIND);
114 model->AddItemWithStringId(IDC_PRINT, IDS_PRINT);
115 zoom_menu_contents_.reset(new ZoomMenuModel(&menu_delegate_));
116 model->AddSubMenuWithStringId(IDC_ZOOM_MENU, IDS_ZOOM_MENU,
117 zoom_menu_contents_.get());
118 encoding_menu_contents_.reset(new EncodingMenuModel(browser()));
119 model->AddSubMenuWithStringId(IDC_ENCODING_MENU,
120 IDS_ENCODING_MENU,
121 encoding_menu_contents_.get());
122 if (browser()->is_app() && chrome::CanOpenTaskManager()) {
123 model->AddSeparator(ui::NORMAL_SEPARATOR);
124 model->AddItemWithStringId(IDC_TASK_MANAGER, IDS_TASK_MANAGER);
126 #if defined(OS_LINUX) && !defined(OS_CHROMEOS)
127 model->AddSeparator(ui::NORMAL_SEPARATOR);
128 model->AddItemWithStringId(IDC_CLOSE_WINDOW, IDS_CLOSE);
129 #endif
131 // Avoid appending the teleport menu for the settings window. This window's
132 // presentation is unique: it's a normal browser window with an app-like
133 // frame, which doesn't have a user icon badge. Thus if teleported it's not
134 // clear what user it applies to. Rather than bother to implement badging just
135 // for this rare case, simply prevent the user from teleporting the window.
136 if (!IsChromeSettingsAppOrPopupWindow(browser()))
137 AppendTeleportMenu(model);
140 void SystemMenuModelBuilder::AddFrameToggleItems(ui::SimpleMenuModel* model) {
141 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
142 switches::kDebugEnableFrameToggle)) {
143 model->AddSeparator(ui::NORMAL_SEPARATOR);
144 model->AddItem(IDC_DEBUG_FRAME_TOGGLE,
145 base::ASCIIToUTF16("Toggle Frame Type"));
149 void SystemMenuModelBuilder::AppendTeleportMenu(ui::SimpleMenuModel* model) {
150 #if defined(OS_CHROMEOS)
151 DCHECK(browser()->window());
152 // If there is no manager, we are not in the proper multi user mode.
153 if (chrome::MultiUserWindowManager::GetMultiProfileMode() !=
154 chrome::MultiUserWindowManager::MULTI_PROFILE_MODE_SEPARATED)
155 return;
157 // Don't show the menu for incognito windows.
158 if (browser()->profile()->IsOffTheRecord())
159 return;
161 // To show the menu we need at least two logged in users.
162 ash::SessionStateDelegate* delegate =
163 ash::Shell::GetInstance()->session_state_delegate();
164 int logged_in_users = delegate->NumberOfLoggedInUsers();
165 if (logged_in_users <= 1)
166 return;
168 // If this does not belong to a profile or there is no window, or the window
169 // is not owned by anyone, we don't show the menu addition.
170 chrome::MultiUserWindowManager* manager =
171 chrome::MultiUserWindowManager::GetInstance();
172 const std::string user_id =
173 multi_user_util::GetUserIDFromProfile(browser()->profile());
174 aura::Window* window = browser()->window()->GetNativeWindow();
175 if (user_id.empty() || !window || manager->GetWindowOwner(window).empty())
176 return;
178 model->AddSeparator(ui::NORMAL_SEPARATOR);
179 DCHECK(logged_in_users <= 3);
180 for (int user_index = 1; user_index < logged_in_users; ++user_index) {
181 const user_manager::UserInfo* user_info = delegate->GetUserInfo(user_index);
182 model->AddItem(
183 user_index == 1 ? IDC_VISIT_DESKTOP_OF_LRU_USER_2
184 : IDC_VISIT_DESKTOP_OF_LRU_USER_3,
185 l10n_util::GetStringFUTF16(IDS_VISIT_DESKTOP_OF_LRU_USER,
186 user_info->GetDisplayName(),
187 base::ASCIIToUTF16(user_info->GetEmail())));
189 #endif