12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved. 22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file. 42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/views/frame/system_menu_model_builder.h" 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/command_line.h" 8868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h" 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/app/chrome_command_ids.h" 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/browser_commands.h" 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/host_desktop.h" 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/toolbar/wrench_menu_model.h" 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/common/chrome_switches.h" 146e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "chrome/grit/generated_resources.h" 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/base/accelerators/accelerator.h" 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/base/models/simple_menu_model.h" 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 188bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#if defined(OS_CHROMEOS) 195c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "ash/session/session_state_delegate.h" 208bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "ash/shell.h" 21f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chrome/browser/ui/ash/multi_user/multi_user_util.h" 22f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chrome/browser/ui/ash/multi_user/multi_user_window_manager.h" 238bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "chrome/browser/ui/browser_window.h" 24116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "components/user_manager/user_info.h" 258bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "ui/base/l10n/l10n_util.h" 268bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#endif 278bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)SystemMenuModelBuilder::SystemMenuModelBuilder( 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ui::AcceleratorProvider* provider, 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Browser* browser) 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : menu_delegate_(provider, browser) { 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)SystemMenuModelBuilder::~SystemMenuModelBuilder() { 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SystemMenuModelBuilder::Init() { 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ui::SimpleMenuModel* model = new ui::SimpleMenuModel(&menu_delegate_); 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) menu_model_.reset(model); 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BuildMenu(model); 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_WIN) 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // On Windows with HOST_DESKTOP_TYPE_NATIVE we put the menu items in the 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // system menu (not at the end). Doing this necessitates adding a trailing 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // separator. 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (browser()->host_desktop_type() == chrome::HOST_DESKTOP_TYPE_NATIVE) 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) model->AddSeparator(ui::NORMAL_SEPARATOR); 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SystemMenuModelBuilder::BuildMenu(ui::SimpleMenuModel* model) { 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // We add the menu items in reverse order so that insertion_index never needs 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // to change. 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (browser()->is_type_tabbed()) 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BuildSystemMenuForBrowserWindow(model); 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BuildSystemMenuForAppOrPopupWindow(model); 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AddFrameToggleItems(model); 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SystemMenuModelBuilder::BuildSystemMenuForBrowserWindow( 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ui::SimpleMenuModel* model) { 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) model->AddItemWithStringId(IDC_NEW_TAB, IDS_NEW_TAB); 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) model->AddItemWithStringId(IDC_RESTORE_TAB, IDS_RESTORE_TAB); 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (chrome::CanOpenTaskManager()) { 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) model->AddSeparator(ui::NORMAL_SEPARATOR); 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) model->AddItemWithStringId(IDC_TASK_MANAGER, IDS_TASK_MANAGER); 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if defined(OS_LINUX) && !defined(OS_CHROMEOS) 695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) model->AddSeparator(ui::NORMAL_SEPARATOR); 705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) model->AddCheckItemWithStringId(IDC_USE_SYSTEM_TITLE_BAR, 715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) IDS_SHOW_WINDOW_DECORATIONS_MENU); 725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif 738bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) AppendTeleportMenu(model); 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If it's a regular browser window with tabs, we don't add any more items, 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // since it already has menus (Page, Chrome). 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SystemMenuModelBuilder::BuildSystemMenuForAppOrPopupWindow( 792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ui::SimpleMenuModel* model) { 802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) model->AddItemWithStringId(IDC_BACK, IDS_CONTENT_CONTEXT_BACK); 812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) model->AddItemWithStringId(IDC_FORWARD, IDS_CONTENT_CONTEXT_FORWARD); 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) model->AddItemWithStringId(IDC_RELOAD, IDS_APP_MENU_RELOAD); 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) model->AddSeparator(ui::NORMAL_SEPARATOR); 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (browser()->is_app()) 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) model->AddItemWithStringId(IDC_NEW_TAB, IDS_APP_MENU_NEW_WEB_PAGE); 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) model->AddItemWithStringId(IDC_SHOW_AS_TAB, IDS_SHOW_AS_TAB); 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) model->AddSeparator(ui::NORMAL_SEPARATOR); 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) model->AddItemWithStringId(IDC_CUT, IDS_CUT); 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) model->AddItemWithStringId(IDC_COPY, IDS_COPY); 912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) model->AddItemWithStringId(IDC_PASTE, IDS_PASTE); 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) model->AddSeparator(ui::NORMAL_SEPARATOR); 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) model->AddItemWithStringId(IDC_FIND, IDS_FIND); 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) model->AddItemWithStringId(IDC_PRINT, IDS_PRINT); 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) zoom_menu_contents_.reset(new ZoomMenuModel(&menu_delegate_)); 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) model->AddSubMenuWithStringId(IDC_ZOOM_MENU, IDS_ZOOM_MENU, 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) zoom_menu_contents_.get()); 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) encoding_menu_contents_.reset(new EncodingMenuModel(browser())); 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) model->AddSubMenuWithStringId(IDC_ENCODING_MENU, 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) IDS_ENCODING_MENU, 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) encoding_menu_contents_.get()); 1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (browser()->is_app() && chrome::CanOpenTaskManager()) { 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) model->AddSeparator(ui::NORMAL_SEPARATOR); 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) model->AddItemWithStringId(IDC_TASK_MANAGER, IDS_TASK_MANAGER); 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if defined(OS_LINUX) && !defined(OS_CHROMEOS) 1075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) model->AddSeparator(ui::NORMAL_SEPARATOR); 1085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) model->AddItemWithStringId(IDC_CLOSE_WINDOW, IDS_CLOSE); 1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif 1108bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 1118bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) AppendTeleportMenu(model); 1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SystemMenuModelBuilder::AddFrameToggleItems(ui::SimpleMenuModel* model) { 1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (CommandLine::ForCurrentProcess()->HasSwitch( 1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) switches::kDebugEnableFrameToggle)) { 1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) model->AddSeparator(ui::NORMAL_SEPARATOR); 1185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) model->AddItem(IDC_DEBUG_FRAME_TOGGLE, 1195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::ASCIIToUTF16("Toggle Frame Type")); 1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1238bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void SystemMenuModelBuilder::AppendTeleportMenu(ui::SimpleMenuModel* model) { 1248bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#if defined(OS_CHROMEOS) 1258bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) DCHECK(browser()->window()); 1268bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // If there is no manager, we are not in the proper multi user mode. 127f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (chrome::MultiUserWindowManager::GetMultiProfileMode() != 128f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) chrome::MultiUserWindowManager::MULTI_PROFILE_MODE_SEPARATED) 1298bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return; 1308bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 131a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Don't show the menu for incognito windows. 132a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (browser()->profile()->IsOffTheRecord()) 133a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return; 134a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 1358bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // To show the menu we need at least two logged in users. 1368bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) ash::SessionStateDelegate* delegate = 1378bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) ash::Shell::GetInstance()->session_state_delegate(); 1388bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) int logged_in_users = delegate->NumberOfLoggedInUsers(); 1398bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (logged_in_users <= 1) 1408bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return; 1418bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 1428bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // If this does not belong to a profile or there is no window, or the window 1438bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // is not owned by anyone, we don't show the menu addition. 144f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) chrome::MultiUserWindowManager* manager = 145f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) chrome::MultiUserWindowManager::GetInstance(); 1468bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) const std::string user_id = 147f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) multi_user_util::GetUserIDFromProfile(browser()->profile()); 1488bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) aura::Window* window = browser()->window()->GetNativeWindow(); 1498bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (user_id.empty() || !window || manager->GetWindowOwner(window).empty()) 1508bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return; 1518bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 1528bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) model->AddSeparator(ui::NORMAL_SEPARATOR); 1538bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) DCHECK(logged_in_users <= 3); 1548bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) for (int user_index = 1; user_index < logged_in_users; ++user_index) { 155116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const user_manager::UserInfo* user_info = delegate->GetUserInfo(user_index); 1568bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) model->AddItem( 1575c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu user_index == 1 ? IDC_VISIT_DESKTOP_OF_LRU_USER_2 1585c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu : IDC_VISIT_DESKTOP_OF_LRU_USER_3, 1595c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu l10n_util::GetStringFUTF16(IDS_VISIT_DESKTOP_OF_LRU_USER, 1605c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu user_info->GetDisplayName(), 1615c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu base::ASCIIToUTF16(user_info->GetEmail()))); 1628bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 1638bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#endif 1648bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 165