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/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"
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_window_manager.h"
22 #include "chrome/browser/ui/browser_window.h"
23 #include "ui/base/l10n/l10n_util.h"
26 SystemMenuModelBuilder::SystemMenuModelBuilder(
27 ui::AcceleratorProvider* provider,
29 : menu_delegate_(provider, browser) {
32 SystemMenuModelBuilder::~SystemMenuModelBuilder() {
35 void SystemMenuModelBuilder::Init() {
36 ui::SimpleMenuModel* model = new ui::SimpleMenuModel(&menu_delegate_);
37 menu_model_.reset(model);
40 // On Windows with HOST_DESKTOP_TYPE_NATIVE we put the menu items in the
41 // system menu (not at the end). Doing this necessitates adding a trailing
43 if (browser()->host_desktop_type() == chrome::HOST_DESKTOP_TYPE_NATIVE)
44 model->AddSeparator(ui::NORMAL_SEPARATOR);
48 void SystemMenuModelBuilder::BuildMenu(ui::SimpleMenuModel* model) {
49 // We add the menu items in reverse order so that insertion_index never needs
51 if (browser()->is_type_tabbed())
52 BuildSystemMenuForBrowserWindow(model);
54 BuildSystemMenuForAppOrPopupWindow(model);
55 AddFrameToggleItems(model);
58 void SystemMenuModelBuilder::BuildSystemMenuForBrowserWindow(
59 ui::SimpleMenuModel* model) {
60 model->AddItemWithStringId(IDC_NEW_TAB, IDS_NEW_TAB);
61 model->AddItemWithStringId(IDC_RESTORE_TAB, IDS_RESTORE_TAB);
62 if (chrome::CanOpenTaskManager()) {
63 model->AddSeparator(ui::NORMAL_SEPARATOR);
64 model->AddItemWithStringId(IDC_TASK_MANAGER, IDS_TASK_MANAGER);
66 AppendTeleportMenu(model);
67 // If it's a regular browser window with tabs, we don't add any more items,
68 // since it already has menus (Page, Chrome).
71 void SystemMenuModelBuilder::BuildSystemMenuForAppOrPopupWindow(
72 ui::SimpleMenuModel* model) {
73 model->AddItemWithStringId(IDC_BACK, IDS_CONTENT_CONTEXT_BACK);
74 model->AddItemWithStringId(IDC_FORWARD, IDS_CONTENT_CONTEXT_FORWARD);
75 model->AddItemWithStringId(IDC_RELOAD, IDS_APP_MENU_RELOAD);
76 model->AddSeparator(ui::NORMAL_SEPARATOR);
77 if (browser()->is_app())
78 model->AddItemWithStringId(IDC_NEW_TAB, IDS_APP_MENU_NEW_WEB_PAGE);
80 model->AddItemWithStringId(IDC_SHOW_AS_TAB, IDS_SHOW_AS_TAB);
81 model->AddSeparator(ui::NORMAL_SEPARATOR);
82 model->AddItemWithStringId(IDC_CUT, IDS_CUT);
83 model->AddItemWithStringId(IDC_COPY, IDS_COPY);
84 model->AddItemWithStringId(IDC_PASTE, IDS_PASTE);
85 model->AddSeparator(ui::NORMAL_SEPARATOR);
86 model->AddItemWithStringId(IDC_FIND, IDS_FIND);
87 model->AddItemWithStringId(IDC_PRINT, IDS_PRINT);
88 zoom_menu_contents_.reset(new ZoomMenuModel(&menu_delegate_));
89 model->AddSubMenuWithStringId(IDC_ZOOM_MENU, IDS_ZOOM_MENU,
90 zoom_menu_contents_.get());
91 encoding_menu_contents_.reset(new EncodingMenuModel(browser()));
92 model->AddSubMenuWithStringId(IDC_ENCODING_MENU,
94 encoding_menu_contents_.get());
95 if (browser()->is_app() && chrome::CanOpenTaskManager()) {
96 model->AddSeparator(ui::NORMAL_SEPARATOR);
97 model->AddItemWithStringId(IDC_TASK_MANAGER, IDS_TASK_MANAGER);
100 AppendTeleportMenu(model);
103 void SystemMenuModelBuilder::AddFrameToggleItems(ui::SimpleMenuModel* model) {
104 if (CommandLine::ForCurrentProcess()->HasSwitch(
105 switches::kDebugEnableFrameToggle)) {
106 model->AddSeparator(ui::NORMAL_SEPARATOR);
107 model->AddItem(IDC_DEBUG_FRAME_TOGGLE, ASCIIToUTF16("Toggle Frame Type"));
111 void SystemMenuModelBuilder::AppendTeleportMenu(ui::SimpleMenuModel* model) {
112 #if defined(OS_CHROMEOS)
113 DCHECK(browser()->window());
114 chrome::MultiUserWindowManager* manager =
115 chrome::MultiUserWindowManager::GetInstance();
116 // If there is no manager, we are not in the proper multi user mode.
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)
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 const std::string user_id =
130 manager->GetUserIDFromProfile(browser()->profile());
131 aura::Window* window = browser()->window()->GetNativeWindow();
132 if (user_id.empty() || !window || manager->GetWindowOwner(window).empty())
135 model->AddSeparator(ui::NORMAL_SEPARATOR);
136 DCHECK(logged_in_users <= 3);
137 for (int user_index = 1; user_index < logged_in_users; ++user_index) {
139 user_index == 1 ? IDC_VISIT_DESKTOP_OF_LRU_USER_2 :
140 IDC_VISIT_DESKTOP_OF_LRU_USER_3,
141 l10n_util::GetStringFUTF16(IDC_VISIT_DESKTOP_OF_LRU_USER,
142 delegate->GetUserDisplayName(user_index)));