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