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 "chrome/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/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 "components/user_manager/user_info.h"
25 #include "ui/base/l10n/l10n_util.h"
28 SystemMenuModelBuilder::SystemMenuModelBuilder(
29 ui::AcceleratorProvider
* provider
,
31 : menu_delegate_(provider
, browser
) {
34 SystemMenuModelBuilder::~SystemMenuModelBuilder() {
37 void SystemMenuModelBuilder::Init() {
38 ui::SimpleMenuModel
* model
= new ui::SimpleMenuModel(&menu_delegate_
);
39 menu_model_
.reset(model
);
42 // On Windows with HOST_DESKTOP_TYPE_NATIVE we put the menu items in the
43 // system menu (not at the end). Doing this necessitates adding a trailing
45 if (browser()->host_desktop_type() == chrome::HOST_DESKTOP_TYPE_NATIVE
)
46 model
->AddSeparator(ui::NORMAL_SEPARATOR
);
50 void SystemMenuModelBuilder::BuildMenu(ui::SimpleMenuModel
* model
) {
51 // We add the menu items in reverse order so that insertion_index never needs
53 if (browser()->is_type_tabbed())
54 BuildSystemMenuForBrowserWindow(model
);
56 BuildSystemMenuForAppOrPopupWindow(model
);
57 AddFrameToggleItems(model
);
60 void SystemMenuModelBuilder::BuildSystemMenuForBrowserWindow(
61 ui::SimpleMenuModel
* model
) {
62 model
->AddItemWithStringId(IDC_NEW_TAB
, IDS_NEW_TAB
);
63 model
->AddItemWithStringId(IDC_RESTORE_TAB
, IDS_RESTORE_TAB
);
64 if (chrome::CanOpenTaskManager()) {
65 model
->AddSeparator(ui::NORMAL_SEPARATOR
);
66 model
->AddItemWithStringId(IDC_TASK_MANAGER
, IDS_TASK_MANAGER
);
68 #if defined(OS_LINUX) && !defined(OS_CHROMEOS)
69 model
->AddSeparator(ui::NORMAL_SEPARATOR
);
70 model
->AddCheckItemWithStringId(IDC_USE_SYSTEM_TITLE_BAR
,
71 IDS_SHOW_WINDOW_DECORATIONS_MENU
);
73 AppendTeleportMenu(model
);
74 // If it's a regular browser window with tabs, we don't add any more items,
75 // since it already has menus (Page, Chrome).
78 void SystemMenuModelBuilder::BuildSystemMenuForAppOrPopupWindow(
79 ui::SimpleMenuModel
* model
) {
80 model
->AddItemWithStringId(IDC_BACK
, IDS_CONTENT_CONTEXT_BACK
);
81 model
->AddItemWithStringId(IDC_FORWARD
, IDS_CONTENT_CONTEXT_FORWARD
);
82 model
->AddItemWithStringId(IDC_RELOAD
, IDS_APP_MENU_RELOAD
);
83 model
->AddSeparator(ui::NORMAL_SEPARATOR
);
84 if (browser()->is_app())
85 model
->AddItemWithStringId(IDC_NEW_TAB
, IDS_APP_MENU_NEW_WEB_PAGE
);
87 model
->AddItemWithStringId(IDC_SHOW_AS_TAB
, IDS_SHOW_AS_TAB
);
88 model
->AddSeparator(ui::NORMAL_SEPARATOR
);
89 model
->AddItemWithStringId(IDC_CUT
, IDS_CUT
);
90 model
->AddItemWithStringId(IDC_COPY
, IDS_COPY
);
91 model
->AddItemWithStringId(IDC_PASTE
, IDS_PASTE
);
92 model
->AddSeparator(ui::NORMAL_SEPARATOR
);
93 model
->AddItemWithStringId(IDC_FIND
, IDS_FIND
);
94 model
->AddItemWithStringId(IDC_PRINT
, IDS_PRINT
);
95 zoom_menu_contents_
.reset(new ZoomMenuModel(&menu_delegate_
));
96 model
->AddSubMenuWithStringId(IDC_ZOOM_MENU
, IDS_ZOOM_MENU
,
97 zoom_menu_contents_
.get());
98 encoding_menu_contents_
.reset(new EncodingMenuModel(browser()));
99 model
->AddSubMenuWithStringId(IDC_ENCODING_MENU
,
101 encoding_menu_contents_
.get());
102 if (browser()->is_app() && chrome::CanOpenTaskManager()) {
103 model
->AddSeparator(ui::NORMAL_SEPARATOR
);
104 model
->AddItemWithStringId(IDC_TASK_MANAGER
, IDS_TASK_MANAGER
);
106 #if defined(OS_LINUX) && !defined(OS_CHROMEOS)
107 model
->AddSeparator(ui::NORMAL_SEPARATOR
);
108 model
->AddItemWithStringId(IDC_CLOSE_WINDOW
, IDS_CLOSE
);
111 AppendTeleportMenu(model
);
114 void SystemMenuModelBuilder::AddFrameToggleItems(ui::SimpleMenuModel
* model
) {
115 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
116 switches::kDebugEnableFrameToggle
)) {
117 model
->AddSeparator(ui::NORMAL_SEPARATOR
);
118 model
->AddItem(IDC_DEBUG_FRAME_TOGGLE
,
119 base::ASCIIToUTF16("Toggle Frame Type"));
123 void SystemMenuModelBuilder::AppendTeleportMenu(ui::SimpleMenuModel
* model
) {
124 #if defined(OS_CHROMEOS)
125 DCHECK(browser()->window());
126 // If there is no manager, we are not in the proper multi user mode.
127 if (chrome::MultiUserWindowManager::GetMultiProfileMode() !=
128 chrome::MultiUserWindowManager::MULTI_PROFILE_MODE_SEPARATED
)
131 // Don't show the menu for incognito windows.
132 if (browser()->profile()->IsOffTheRecord())
135 // To show the menu we need at least two logged in users.
136 ash::SessionStateDelegate
* delegate
=
137 ash::Shell::GetInstance()->session_state_delegate();
138 int logged_in_users
= delegate
->NumberOfLoggedInUsers();
139 if (logged_in_users
<= 1)
142 // If this does not belong to a profile or there is no window, or the window
143 // is not owned by anyone, we don't show the menu addition.
144 chrome::MultiUserWindowManager
* manager
=
145 chrome::MultiUserWindowManager::GetInstance();
146 const std::string user_id
=
147 multi_user_util::GetUserIDFromProfile(browser()->profile());
148 aura::Window
* window
= browser()->window()->GetNativeWindow();
149 if (user_id
.empty() || !window
|| manager
->GetWindowOwner(window
).empty())
152 model
->AddSeparator(ui::NORMAL_SEPARATOR
);
153 DCHECK(logged_in_users
<= 3);
154 for (int user_index
= 1; user_index
< logged_in_users
; ++user_index
) {
155 const user_manager::UserInfo
* user_info
= delegate
->GetUserInfo(user_index
);
157 user_index
== 1 ? IDC_VISIT_DESKTOP_OF_LRU_USER_2
158 : IDC_VISIT_DESKTOP_OF_LRU_USER_3
,
159 l10n_util::GetStringFUTF16(IDS_VISIT_DESKTOP_OF_LRU_USER
,
160 user_info
->GetDisplayName(),
161 base::ASCIIToUTF16(user_info
->GetEmail())));