OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 2012 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/search/other_device_menu.h" | |
6 | |
7 #include "base/string16.h" | |
8 #include "chrome/browser/ui/browser.h" | |
9 #include "chrome/browser/ui/browser_finder.h" | |
10 #include "chrome/browser/ui/browser_window.h" | |
11 #include "chrome/browser/ui/webui/ntp/foreign_session_handler.h" | |
12 #include "content/public/browser/web_contents.h" | |
13 #include "content/public/browser/web_ui.h" | |
14 #include "chrome/browser/sync/glue/session_model_associator.h" | |
15 #include "grit/generated_resources.h" | |
16 #include "ui/base/l10n/l10n_util.h" | |
17 #include "ui/base/text/text_elider.h" | |
18 #include "ui/views/controls/menu/menu_model_adapter.h" | |
19 #include "ui/views/controls/menu/menu_runner.h" | |
20 #include "ui/views/widget/widget.h" | |
21 #include "webkit/glue/window_open_disposition.h" | |
22 | |
23 using browser_sync::ForeignSessionHandler; | |
24 using browser_sync::SessionModelAssociator; | |
25 | |
26 // The max number of tabs that will be added to the menu. | |
27 // TODO(jeremycho): Discuss details with UX, e.g. is it prefereable to show only | |
28 // some of the tabs for a window or none at all? | |
29 static const size_t kMaxTabsToShow = 256; | |
30 | |
31 // The max width of a menu. Menu text exceeding this will be elided. | |
32 static const int kMaxWidth = 375; | |
33 | |
34 OtherDeviceMenu::OtherDeviceMenu(content::WebUI* web_ui, | |
35 const std::string& session_id, | |
36 const gfx::Point& location) : | |
37 web_ui_(web_ui), session_id_(session_id), location_(location), | |
38 ALLOW_THIS_IN_INITIALIZER_LIST(menu_model_(this)) { | |
39 AddDeviceTabs(); | |
40 | |
41 // Add a "Open all" menu item if there is more than one tab. | |
42 if (tab_data_.size() > 1) { | |
43 linked_ptr<DictionaryValue> show_all_tab_value = | |
44 linked_ptr<DictionaryValue>(new DictionaryValue()); | |
45 // kInvalidId signifies that the entire session should be opened. | |
46 show_all_tab_value->SetInteger( | |
47 "sessionId", | |
48 ForeignSessionHandler::kInvalidId); | |
49 show_all_tab_value->SetInteger( | |
50 "windowId", | |
51 ForeignSessionHandler::kInvalidId); | |
52 menu_model_.AddSeparator(ui::NORMAL_SEPARATOR); | |
53 menu_model_.AddItem( | |
54 tab_data_.size(), | |
55 l10n_util::GetStringUTF16(IDS_NEW_TAB_OTHER_SESSIONS_OPEN_ALL)); | |
56 tab_data_.push_back(show_all_tab_value); | |
57 } | |
58 } | |
59 | |
60 OtherDeviceMenu::~OtherDeviceMenu() { | |
61 } | |
62 | |
63 void OtherDeviceMenu::ShowMenu() { | |
64 content::WebContents* web_contents = web_ui_->GetWebContents(); | |
65 Browser* browser = browser::FindBrowserWithWebContents(web_contents); | |
66 if (browser) { | |
dhollowa
2012/10/02 00:02:08
nit: you can avoid nesting with pattern:
if (!br
jeremycho
2012/10/02 04:49:00
Done.
| |
67 views::Widget* widget = views::Widget::GetWidgetForNativeWindow( | |
68 browser->window()->GetNativeWindow()); | |
69 if (widget) { | |
70 views::MenuModelAdapter menu_model_adapter(&menu_model_); | |
71 menu_runner_.reset( | |
72 new views::MenuRunner(menu_model_adapter.CreateMenu())); | |
73 | |
74 if (menu_runner_->RunMenuAt(widget, NULL, | |
75 gfx::Rect(location_, gfx::Size()), | |
76 views::MenuItemView::TOPLEFT, 0) == | |
77 views::MenuRunner::MENU_DELETED) | |
78 return; | |
79 } | |
80 } | |
81 } | |
82 | |
83 bool OtherDeviceMenu::IsCommandIdChecked(int command_id) const { | |
84 return false; | |
85 } | |
86 | |
87 bool OtherDeviceMenu::IsCommandIdEnabled(int command_id) const { | |
88 return true; | |
89 } | |
90 | |
91 void OtherDeviceMenu::ExecuteCommand(int command_id) { | |
92 ExecuteCommand(command_id, 0); | |
93 } | |
94 | |
95 // TODO(jeremycho): Figure out why mouse wheel clicks don't trigger this. | |
96 void OtherDeviceMenu::ExecuteCommand(int command_id, int event_flags) { | |
97 DCHECK_GT(tab_data_.size(), static_cast<size_t>(command_id)) << | |
98 "Invalid command_id from other device menu."; | |
99 | |
100 linked_ptr<DictionaryValue> tab_data = tab_data_[command_id]; | |
101 // This is not a mistake - sessionId actually refers to the tab id. | |
102 // See ForeignSessionHandler::SessionTabToValue. | |
103 int tab_id = ForeignSessionHandler::kInvalidId; | |
104 tab_data->GetInteger("sessionId", &tab_id); | |
105 | |
106 int window_id = ForeignSessionHandler::kInvalidId; | |
107 tab_data->GetInteger("windowId", &window_id); | |
108 | |
109 WindowOpenDisposition disposition = | |
110 chrome::DispositionFromEventFlags(event_flags); | |
111 ForeignSessionHandler::OpenForeignSession( | |
112 web_ui_, session_id_, window_id, tab_id, disposition); | |
113 // TODO(jeremycho): Figure out what to log. | |
114 } | |
115 | |
116 bool OtherDeviceMenu::GetAcceleratorForCommandId( | |
117 int command_id, | |
118 ui::Accelerator* accelerator) { | |
119 return false; | |
120 } | |
121 | |
122 void OtherDeviceMenu::AddDeviceTabs() { | |
123 SessionModelAssociator* associator = | |
124 ForeignSessionHandler::GetModelAssociator(web_ui_); | |
125 std::vector<const SessionWindow*> windows; | |
126 | |
127 // Populate the menu with the device's tabs, using separators between windows. | |
128 if (associator && associator->GetForeignSession(session_id_, &windows)) { | |
129 bool last_window_has_tabs = false; | |
130 for (std::vector<const SessionWindow*>::const_iterator it = | |
131 windows.begin(); it != windows.end(); ++it) { | |
132 if (last_window_has_tabs) | |
133 menu_model_.AddSeparator(ui::NORMAL_SEPARATOR); | |
134 last_window_has_tabs = false; | |
135 | |
136 const SessionWindow* window = *it; | |
137 for (size_t i = 0; i < window->tabs.size(); ++i) { | |
138 linked_ptr<DictionaryValue> tab_value = | |
139 linked_ptr<DictionaryValue>(new DictionaryValue()); | |
140 if (ForeignSessionHandler::SessionTabToValue( | |
141 *window->tabs[i], tab_value.get())) { | |
142 last_window_has_tabs = true; | |
143 tab_value->SetInteger("windowId", window->window_id.id()); | |
144 string16 title; | |
145 tab_value->GetString("title", &title); | |
146 title = ui::ElideText( | |
147 title, gfx::Font(), kMaxWidth, ui::ELIDE_AT_END); | |
148 menu_model_.AddItem(tab_data_.size(), title); | |
149 // TODO(jeremycho): Use tab_value.GetString("url", &url) to | |
150 // request favicons. http://crbug.com/153410. | |
151 tab_data_.push_back(tab_value); | |
152 if (tab_data_.size() >= kMaxTabsToShow) | |
153 return; | |
154 } | |
155 } | |
156 } | |
157 } | |
158 } | |
OLD | NEW |