OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/chromeos/status/network_menu.h" | 5 #include "chrome/browser/chromeos/status/network_menu.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
11 #include "base/stringprintf.h" | 11 #include "base/stringprintf.h" |
12 #include "base/utf_string_conversions.h" | 12 #include "base/utf_string_conversions.h" |
13 #include "chrome/browser/chromeos/choose_mobile_network_dialog.h" | 13 #include "chrome/browser/chromeos/choose_mobile_network_dialog.h" |
14 #include "chrome/browser/chromeos/cros/cros_library.h" | 14 #include "chrome/browser/chromeos/cros/cros_library.h" |
15 #include "chrome/browser/chromeos/sim_dialog_delegate.h" | 15 #include "chrome/browser/chromeos/sim_dialog_delegate.h" |
16 #include "chrome/browser/ui/browser.h" | 16 #include "chrome/browser/ui/browser.h" |
17 #include "chrome/browser/ui/browser_list.h" | 17 #include "chrome/browser/ui/browser_list.h" |
18 #include "chrome/browser/ui/views/window.h" | 18 #include "chrome/browser/ui/views/window.h" |
19 #include "chrome/common/url_constants.h" | 19 #include "chrome/common/url_constants.h" |
20 #include "chrome/common/chrome_switches.h" | 20 #include "chrome/common/chrome_switches.h" |
21 #include "grit/generated_resources.h" | 21 #include "grit/generated_resources.h" |
22 #include "grit/theme_resources.h" | 22 #include "grit/theme_resources.h" |
23 #include "net/base/escape.h" | 23 #include "net/base/escape.h" |
24 #include "ui/base/l10n/l10n_util.h" | 24 #include "ui/base/l10n/l10n_util.h" |
25 #include "ui/base/resource/resource_bundle.h" | 25 #include "ui/base/resource/resource_bundle.h" |
26 #include "ui/gfx/canvas_skia.h" | 26 #include "ui/gfx/canvas_skia.h" |
27 #include "ui/gfx/skbitmap_operations.h" | 27 #include "ui/gfx/skbitmap_operations.h" |
28 #include "views/controls/menu/menu_2.h" | 28 #include "views/controls/button/menu_button.h" |
| 29 #include "views/controls/menu/menu_item_view.h" |
| 30 #include "views/controls/menu/submenu_view.h" |
| 31 #include "views/widget/widget.h" |
29 #include "views/window/window.h" | 32 #include "views/window/window.h" |
30 | 33 |
| 34 using views::MenuItemView; |
| 35 |
| 36 namespace { |
| 37 |
| 38 // Offset for VPN menu items. |
| 39 const int kVPNCommandIndexOffset = 10000; |
| 40 |
| 41 } // namespace |
| 42 |
31 namespace chromeos { | 43 namespace chromeos { |
32 | 44 |
| 45 class NetworkMenuModel : public views::MenuDelegate { |
| 46 public: |
| 47 struct NetworkInfo { |
| 48 NetworkInfo() : |
| 49 need_passphrase(false), remembered(true), auto_connect(true) {} |
| 50 // "ethernet" | "wifi" | "cellular" | "other". |
| 51 std::string network_type; |
| 52 // "connected" | "connecting" | "disconnected" | "error". |
| 53 std::string status; |
| 54 // status message or error message, empty if unknown status. |
| 55 std::string message; |
| 56 // IP address (if network is active, empty otherwise) |
| 57 std::string ip_address; |
| 58 // Remembered passphrase. |
| 59 std::string passphrase; |
| 60 // true if the network requires a passphrase. |
| 61 bool need_passphrase; |
| 62 // true if the network is currently remembered. |
| 63 bool remembered; |
| 64 // true if the network is auto connect (meaningful for Wifi only). |
| 65 bool auto_connect; |
| 66 }; |
| 67 |
| 68 explicit NetworkMenuModel(NetworkMenu* owner) : owner_(owner) {} |
| 69 virtual ~NetworkMenuModel() {} |
| 70 |
| 71 // views::MenuDelegate implementation ---------------------------------------- |
| 72 |
| 73 virtual const gfx::Font& GetLabelFont(int id) const OVERRIDE; |
| 74 virtual bool IsItemChecked(int id) const OVERRIDE; |
| 75 virtual bool IsCommandEnabled(int id) const OVERRIDE; |
| 76 virtual void ExecuteCommand(int id) OVERRIDE; |
| 77 |
| 78 // Connect or reconnect to the network at |index|. |
| 79 // If remember >= 0, set the favorite state of the network. |
| 80 // Returns true if a connect occurred (e.g. menu should be closed). |
| 81 bool ConnectToNetworkAt(int index, |
| 82 const std::string& passphrase, |
| 83 const std::string& ssid, |
| 84 int remember) const; |
| 85 |
| 86 // Called by NetworkMenu::RunMenu to initialize list of menu items. |
| 87 virtual void InitMenuItems(bool is_browser_mode, |
| 88 bool should_open_button_options) {} |
| 89 |
| 90 // PopulateMenu() clears and reinstalls the menu items defined in this |
| 91 // instance by calling PopulateMenuItem() on each one. Subclasses with |
| 92 // submenus should override PopulateMenuItem(), deferring to the base |
| 93 // class implementation for non-submenu items and calling PopulateMenu() |
| 94 // for the submenu after adding it. |
| 95 virtual void PopulateMenu(views::MenuItemView* menu); |
| 96 virtual void PopulateMenuItem( |
| 97 views::MenuItemView* menu, |
| 98 int index, |
| 99 int command_id); |
| 100 |
| 101 protected: |
| 102 enum MenuItemFlags { |
| 103 FLAG_DISABLED = 1 << 0, |
| 104 FLAG_TOGGLE_ETHERNET = 1 << 1, |
| 105 FLAG_TOGGLE_WIFI = 1 << 2, |
| 106 FLAG_TOGGLE_CELLULAR = 1 << 3, |
| 107 FLAG_TOGGLE_OFFLINE = 1 << 4, |
| 108 FLAG_ASSOCIATED = 1 << 5, |
| 109 FLAG_ETHERNET = 1 << 6, |
| 110 FLAG_WIFI = 1 << 7, |
| 111 FLAG_CELLULAR = 1 << 8, |
| 112 FLAG_PRIVATE_NETWORKS = 1 << 9, |
| 113 FLAG_OPTIONS = 1 << 10, |
| 114 FLAG_ADD_WIFI = 1 << 11, |
| 115 FLAG_ADD_CELLULAR = 1 << 12, |
| 116 FLAG_VPN = 1 << 13, |
| 117 FLAG_ADD_VPN = 1 << 14, |
| 118 FLAG_DISCONNECT_VPN = 1 << 15, |
| 119 }; |
| 120 |
| 121 struct MenuItem { |
| 122 MenuItem() |
| 123 : type(ui::MenuModel::TYPE_SEPARATOR), |
| 124 sub_menu_model(NULL), |
| 125 flags(0) {} |
| 126 MenuItem(ui::MenuModel::ItemType type, string16 label, SkBitmap icon, |
| 127 const std::string& service_path, int flags) |
| 128 : type(type), |
| 129 label(label), |
| 130 icon(icon), |
| 131 service_path(service_path), |
| 132 sub_menu_model(NULL), |
| 133 flags(flags) {} |
| 134 MenuItem(ui::MenuModel::ItemType type, string16 label, SkBitmap icon, |
| 135 NetworkMenuModel* sub_menu_model, int flags) |
| 136 : type(type), |
| 137 label(label), |
| 138 icon(icon), |
| 139 sub_menu_model(sub_menu_model), |
| 140 flags(flags) {} |
| 141 |
| 142 ui::MenuModel::ItemType type; |
| 143 string16 label; |
| 144 SkBitmap icon; |
| 145 std::string service_path; |
| 146 NetworkMenuModel* sub_menu_model; // Weak. |
| 147 int flags; |
| 148 }; |
| 149 typedef std::vector<MenuItem> MenuItemVector; |
| 150 |
| 151 // Our menu items. |
| 152 MenuItemVector menu_items_; |
| 153 |
| 154 NetworkMenu* owner_; // Weak pointer to NetworkMenu that owns this MenuModel. |
| 155 |
| 156 private: |
| 157 // Shows network details in Web UI options window. |
| 158 void ShowTabbedNetworkSettings(const Network* network) const; |
| 159 |
| 160 // Show a NetworkConfigView modal dialog instance. |
| 161 void ShowNetworkConfigView(NetworkConfigView* view) const; |
| 162 |
| 163 void ActivateCellular(const CellularNetwork* cellular) const; |
| 164 void ShowOther(ConnectionType type) const; |
| 165 void ShowOtherCellular() const; |
| 166 |
| 167 DISALLOW_COPY_AND_ASSIGN(NetworkMenuModel); |
| 168 }; |
| 169 |
33 class MainMenuModel : public NetworkMenuModel { | 170 class MainMenuModel : public NetworkMenuModel { |
34 public: | 171 public: |
35 explicit MainMenuModel(NetworkMenu* owner); | 172 explicit MainMenuModel(NetworkMenu* owner); |
36 virtual ~MainMenuModel() {} | 173 virtual ~MainMenuModel() {} |
37 | 174 |
38 // NetworkMenuModel implementation. | 175 // NetworkMenuModel implementation ------------------------------------------- |
39 virtual void InitMenuItems(bool is_browser_mode, | 176 virtual void InitMenuItems(bool is_browser_mode, |
40 bool should_open_button_options); | 177 bool should_open_button_options) OVERRIDE; |
| 178 virtual void PopulateMenuItem(views::MenuItemView* menu, |
| 179 int index, |
| 180 int command_id) OVERRIDE; |
| 181 |
| 182 // MenuDelegate implementaion ------------------------------------------------ |
| 183 virtual const gfx::Font& GetLabelFont(int id) const OVERRIDE; |
| 184 virtual bool IsItemChecked(int id) const OVERRIDE; |
| 185 virtual bool IsCommandEnabled(int id) const OVERRIDE; |
| 186 virtual void ExecuteCommand(int id) OVERRIDE; |
41 | 187 |
42 private: | 188 private: |
43 scoped_ptr<NetworkMenuModel> vpn_menu_model_; | 189 scoped_ptr<NetworkMenuModel> vpn_menu_model_; |
44 | 190 |
45 DISALLOW_COPY_AND_ASSIGN(MainMenuModel); | 191 DISALLOW_COPY_AND_ASSIGN(MainMenuModel); |
46 }; | 192 }; |
47 | 193 |
48 class VPNMenuModel : public NetworkMenuModel { | 194 class VPNMenuModel : public NetworkMenuModel { |
49 public: | 195 public: |
50 explicit VPNMenuModel(NetworkMenu* owner); | 196 explicit VPNMenuModel(NetworkMenu* owner); |
51 virtual ~VPNMenuModel() {} | 197 virtual ~VPNMenuModel() {} |
52 | 198 |
53 // NetworkMenuModel implementation. | 199 // NetworkMenuModel implementation. |
54 virtual void InitMenuItems(bool is_browser_mode, | 200 virtual void InitMenuItems(bool is_browser_mode, |
55 bool should_open_button_options); | 201 bool should_open_button_options); |
| 202 virtual void PopulateMenuItem( |
| 203 views::MenuItemView* menu, |
| 204 int index, |
| 205 int command_id) OVERRIDE; |
56 | 206 |
57 static SkBitmap IconForDisplay(const Network* network); | 207 static SkBitmap IconForDisplay(const Network* network); |
58 | 208 |
59 private: | 209 private: |
60 DISALLOW_COPY_AND_ASSIGN(VPNMenuModel); | 210 DISALLOW_COPY_AND_ASSIGN(VPNMenuModel); |
61 }; | 211 }; |
62 | 212 |
63 //////////////////////////////////////////////////////////////////////////////// | 213 // NetworkMenuModel, public methods: ------------------------------------------- |
64 // NetworkMenuModel, public methods: | |
65 | 214 |
66 bool NetworkMenuModel::ConnectToNetworkAt(int index, | 215 bool NetworkMenuModel::ConnectToNetworkAt(int index, |
67 const std::string& passphrase, | 216 const std::string& passphrase, |
68 const std::string& ssid, | 217 const std::string& ssid, |
69 int auto_connect) const { | 218 int auto_connect) const { |
70 int flags = menu_items_[index].flags; | 219 int flags = menu_items_[index].flags; |
71 NetworkLibrary* cros = CrosLibrary::Get()->GetNetworkLibrary(); | 220 NetworkLibrary* cros = CrosLibrary::Get()->GetNetworkLibrary(); |
72 const std::string& service_path = menu_items_[index].service_path; | 221 const std::string& service_path = menu_items_[index].service_path; |
73 if (flags & FLAG_WIFI) { | 222 if (flags & FLAG_WIFI) { |
74 WifiNetwork* wifi = cros->FindWifiNetworkByPath(service_path); | 223 WifiNetwork* wifi = cros->FindWifiNetworkByPath(service_path); |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
150 } else { | 299 } else { |
151 // If we are attempting to connect to a network that no longer exists, | 300 // If we are attempting to connect to a network that no longer exists, |
152 // display a notification. | 301 // display a notification. |
153 LOG(WARNING) << "VPN does not exist to connect to: " << service_path; | 302 LOG(WARNING) << "VPN does not exist to connect to: " << service_path; |
154 // TODO(stevenjb): Show notification. | 303 // TODO(stevenjb): Show notification. |
155 } | 304 } |
156 } | 305 } |
157 return true; | 306 return true; |
158 } | 307 } |
159 | 308 |
160 //////////////////////////////////////////////////////////////////////////////// | 309 // NetworkMenuModel, views::MenuDelegate implementation ------------------------ |
161 // NetworkMenuModel, ui::MenuModel implementation: | |
162 | 310 |
163 int NetworkMenuModel::GetItemCount() const { | 311 const gfx::Font& NetworkMenuModel::GetLabelFont(int id) const { |
164 return static_cast<int>(menu_items_.size()); | 312 DCHECK_LE(0, id); |
| 313 DCHECK_GT(static_cast<int>(menu_items_.size()), id); |
| 314 return (menu_items_[id].flags & FLAG_ASSOCIATED) ? |
| 315 ResourceBundle::GetSharedInstance().GetFont(ResourceBundle::BoldFont) : |
| 316 ResourceBundle::GetSharedInstance().GetFont(ResourceBundle::BaseFont); |
165 } | 317 } |
166 | 318 |
167 ui::MenuModel::ItemType NetworkMenuModel::GetTypeAt(int index) const { | 319 bool NetworkMenuModel::IsItemChecked(int id) const { |
168 return menu_items_[index].type; | |
169 } | |
170 | |
171 string16 NetworkMenuModel::GetLabelAt(int index) const { | |
172 return menu_items_[index].label; | |
173 } | |
174 | |
175 const gfx::Font* NetworkMenuModel::GetLabelFontAt(int index) const { | |
176 return (menu_items_[index].flags & FLAG_ASSOCIATED) ? | |
177 &ResourceBundle::GetSharedInstance().GetFont(ResourceBundle::BoldFont) : | |
178 NULL; | |
179 } | |
180 | |
181 bool NetworkMenuModel::IsItemCheckedAt(int index) const { | |
182 // All ui::MenuModel::TYPE_CHECK menu items are checked. | |
183 return true; | 320 return true; |
184 } | 321 } |
185 | 322 |
186 bool NetworkMenuModel::GetIconAt(int index, SkBitmap* icon) { | 323 bool NetworkMenuModel::IsCommandEnabled(int id) const { |
187 if (!menu_items_[index].icon.empty()) { | 324 if (id < static_cast<int>(menu_items_.size())) |
188 *icon = menu_items_[index].icon; | 325 return !(menu_items_[id].flags & FLAG_DISABLED); |
| 326 else |
189 return true; | 327 return true; |
190 } | |
191 return false; | |
192 } | 328 } |
193 | 329 |
194 bool NetworkMenuModel::IsEnabledAt(int index) const { | 330 void NetworkMenuModel::ExecuteCommand(int id) { |
195 return !(menu_items_[index].flags & FLAG_DISABLED); | 331 DCHECK_LE(0, id); |
196 } | 332 DCHECK_GT(static_cast<int>(menu_items_.size()), id); |
197 | |
198 ui::MenuModel* NetworkMenuModel::GetSubmenuModelAt(int index) const { | |
199 return menu_items_[index].sub_menu_model; | |
200 } | |
201 | |
202 void NetworkMenuModel::ActivatedAt(int index) { | |
203 // When we are refreshing the menu, ignore menu item activation. | 333 // When we are refreshing the menu, ignore menu item activation. |
204 if (owner_->refreshing_menu_) | 334 if (owner_->refreshing_menu_) |
205 return; | 335 return; |
206 | 336 |
207 NetworkLibrary* cros = CrosLibrary::Get()->GetNetworkLibrary(); | 337 NetworkLibrary* cros = CrosLibrary::Get()->GetNetworkLibrary(); |
208 int flags = menu_items_[index].flags; | 338 int flags = menu_items_[id].flags; |
209 if (flags & FLAG_OPTIONS) { | 339 if (flags & FLAG_OPTIONS) { |
210 owner_->OpenButtonOptions(); | 340 owner_->OpenButtonOptions(); |
211 } else if (flags & FLAG_TOGGLE_ETHERNET) { | 341 } else if (flags & FLAG_TOGGLE_ETHERNET) { |
212 cros->EnableEthernetNetworkDevice(!cros->ethernet_enabled()); | 342 cros->EnableEthernetNetworkDevice(!cros->ethernet_enabled()); |
213 } else if (flags & FLAG_TOGGLE_WIFI) { | 343 } else if (flags & FLAG_TOGGLE_WIFI) { |
214 cros->EnableWifiNetworkDevice(!cros->wifi_enabled()); | 344 cros->EnableWifiNetworkDevice(!cros->wifi_enabled()); |
215 } else if (flags & FLAG_TOGGLE_CELLULAR) { | 345 } else if (flags & FLAG_TOGGLE_CELLULAR) { |
216 const NetworkDevice* cellular = cros->FindCellularDevice(); | 346 const NetworkDevice* cellular = cros->FindCellularDevice(); |
217 if (!cellular) { | 347 if (!cellular) { |
218 LOG(ERROR) << "Not found cellular device, it should be available."; | 348 LOG(ERROR) << "Not found cellular device, it should be available."; |
219 cros->EnableCellularNetworkDevice(!cros->cellular_enabled()); | 349 cros->EnableCellularNetworkDevice(!cros->cellular_enabled()); |
220 } else { | 350 } else { |
221 if (cellular->sim_lock_state() == SIM_UNLOCKED || | 351 if (cellular->sim_lock_state() == SIM_UNLOCKED || |
222 cellular->sim_lock_state() == SIM_UNKNOWN) { | 352 cellular->sim_lock_state() == SIM_UNKNOWN) { |
223 cros->EnableCellularNetworkDevice(!cros->cellular_enabled()); | 353 cros->EnableCellularNetworkDevice(!cros->cellular_enabled()); |
224 } else { | 354 } else { |
225 SimDialogDelegate::ShowDialog(owner_->GetNativeWindow(), | 355 SimDialogDelegate::ShowDialog(owner_->GetNativeWindow(), |
226 SimDialogDelegate::SIM_DIALOG_UNLOCK); | 356 SimDialogDelegate::SIM_DIALOG_UNLOCK); |
227 } | 357 } |
228 } | 358 } |
229 } else if (flags & FLAG_TOGGLE_OFFLINE) { | 359 } else if (flags & FLAG_TOGGLE_OFFLINE) { |
230 cros->EnableOfflineMode(!cros->offline_mode()); | 360 cros->EnableOfflineMode(!cros->offline_mode()); |
231 } else if (flags & FLAG_ETHERNET) { | 361 } else if (flags & FLAG_ETHERNET) { |
232 if (cros->ethernet_connected()) { | 362 if (cros->ethernet_connected()) { |
233 ShowTabbedNetworkSettings(cros->ethernet_network()); | 363 ShowTabbedNetworkSettings(cros->ethernet_network()); |
234 } | 364 } |
235 } else if (flags & (FLAG_WIFI | FLAG_ADD_WIFI | | 365 } else if (flags & (FLAG_WIFI | FLAG_ADD_WIFI | |
236 FLAG_CELLULAR | FLAG_ADD_CELLULAR | | 366 FLAG_CELLULAR | FLAG_ADD_CELLULAR | |
237 FLAG_VPN | FLAG_ADD_VPN)) { | 367 FLAG_VPN | FLAG_ADD_VPN)) { |
238 ConnectToNetworkAt(index, std::string(), std::string(), -1); | 368 ConnectToNetworkAt(id, std::string(), std::string(), -1); |
239 } else if (flags & FLAG_DISCONNECT_VPN) { | 369 } else if (flags & FLAG_DISCONNECT_VPN) { |
240 const VirtualNetwork* active_vpn = cros->virtual_network(); | 370 const VirtualNetwork* active_vpn = cros->virtual_network(); |
241 if (active_vpn) | 371 if (active_vpn) |
242 cros->DisconnectFromNetwork(active_vpn); | 372 cros->DisconnectFromNetwork(active_vpn); |
243 } | 373 } |
244 } | 374 } |
245 | 375 |
246 //////////////////////////////////////////////////////////////////////////////// | 376 void NetworkMenuModel::PopulateMenu(views::MenuItemView* menu) { |
247 // NetworkMenuModel, private methods: | 377 menu->CreateSubmenu()->RemoveAllChildViews(true); |
| 378 const int menu_items_count = static_cast<int>(menu_items_.size()); |
| 379 for (int i = 0; i < menu_items_count; ++i) |
| 380 PopulateMenuItem(menu, i, i); |
| 381 |
| 382 menu->ChildrenChanged(); |
| 383 } |
| 384 |
| 385 void NetworkMenuModel::PopulateMenuItem( |
| 386 views::MenuItemView* menu, |
| 387 int index, |
| 388 int command_id) { |
| 389 DCHECK_GT(static_cast<int>(menu_items_.size()), index); |
| 390 const MenuItem& item = menu_items_[index]; |
| 391 switch (item.type) { |
| 392 case ui::MenuModel::TYPE_SEPARATOR: |
| 393 menu->AppendSeparator(); |
| 394 break; |
| 395 case ui::MenuModel::TYPE_COMMAND: |
| 396 if (item.icon.empty()) { |
| 397 menu->AppendMenuItemWithLabel(command_id, UTF16ToWide(item.label)); |
| 398 } else { |
| 399 menu->AppendMenuItemWithIcon( |
| 400 command_id, |
| 401 UTF16ToWide(item.label), |
| 402 item.icon); |
| 403 } |
| 404 break; |
| 405 default: |
| 406 // Submenus should be handled by subclasses. |
| 407 NOTREACHED(); |
| 408 } |
| 409 } |
| 410 |
| 411 // NetworkMenuModel, private methods: ------------------------------------------ |
248 | 412 |
249 void NetworkMenuModel::ShowTabbedNetworkSettings(const Network* network) const { | 413 void NetworkMenuModel::ShowTabbedNetworkSettings(const Network* network) const { |
250 DCHECK(network); | 414 DCHECK(network); |
251 Browser* browser = BrowserList::GetLastActive(); | 415 Browser* browser = BrowserList::GetLastActive(); |
252 if (!browser) | 416 if (!browser) |
253 return; | 417 return; |
254 std::string page = StringPrintf("%s?servicePath=%s&networkType=%d", | 418 std::string page = StringPrintf("%s?servicePath=%s&networkType=%d", |
255 chrome::kInternetOptionsSubPage, | 419 chrome::kInternetOptionsSubPage, |
256 EscapeUrlEncodedData(network->service_path()).c_str(), | 420 EscapeUrlEncodedData(network->service_path()).c_str(), |
257 network->type()); | 421 network->type()); |
(...skipping 21 matching lines...) Expand all Loading... |
279 } | 443 } |
280 | 444 |
281 void NetworkMenuModel::ShowOther(ConnectionType type) const { | 445 void NetworkMenuModel::ShowOther(ConnectionType type) const { |
282 ShowNetworkConfigView(new NetworkConfigView(type)); | 446 ShowNetworkConfigView(new NetworkConfigView(type)); |
283 } | 447 } |
284 | 448 |
285 void NetworkMenuModel::ShowOtherCellular() const { | 449 void NetworkMenuModel::ShowOtherCellular() const { |
286 ChooseMobileNetworkDialog::ShowDialog(owner_->GetNativeWindow()); | 450 ChooseMobileNetworkDialog::ShowDialog(owner_->GetNativeWindow()); |
287 } | 451 } |
288 | 452 |
289 //////////////////////////////////////////////////////////////////////////////// | 453 // MainMenuModel --------------------------------------------------------------- |
290 // MainMenuModel | |
291 | 454 |
292 MainMenuModel::MainMenuModel(NetworkMenu* owner) | 455 MainMenuModel::MainMenuModel(NetworkMenu* owner) |
293 : NetworkMenuModel(owner) { | 456 : NetworkMenuModel(owner) { |
294 vpn_menu_model_.reset(new VPNMenuModel(owner)); | 457 vpn_menu_model_.reset(new VPNMenuModel(owner)); |
295 } | 458 } |
296 | 459 |
| 460 // MainMenuModel, NetworkMenuModel implementation: ----------------------------- |
| 461 |
297 void MainMenuModel::InitMenuItems(bool is_browser_mode, | 462 void MainMenuModel::InitMenuItems(bool is_browser_mode, |
298 bool should_open_button_options) { | 463 bool should_open_button_options) { |
299 // This gets called on initialization, so any changes should be reflected | 464 // This gets called on initialization, so any changes should be reflected |
300 // in CrosMock::SetNetworkLibraryStatusAreaExpectations(). | 465 // in CrosMock::SetNetworkLibraryStatusAreaExpectations(). |
301 | 466 |
302 menu_items_.clear(); | 467 menu_items_.clear(); |
303 | 468 |
304 NetworkLibrary* cros = CrosLibrary::Get()->GetNetworkLibrary(); | 469 NetworkLibrary* cros = CrosLibrary::Get()->GetNetworkLibrary(); |
305 if (cros->IsLocked()) { | 470 if (cros->IsLocked()) { |
306 menu_items_.push_back( | 471 menu_items_.push_back( |
(...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
587 // Recursively call each submenu to populate its own menu items. | 752 // Recursively call each submenu to populate its own menu items. |
588 for (size_t i = 0; i < menu_items_.size(); ++i) { | 753 for (size_t i = 0; i < menu_items_.size(); ++i) { |
589 if (menu_items_[i].type == ui::MenuModel::TYPE_SUBMENU && | 754 if (menu_items_[i].type == ui::MenuModel::TYPE_SUBMENU && |
590 menu_items_[i].sub_menu_model) { | 755 menu_items_[i].sub_menu_model) { |
591 menu_items_[i].sub_menu_model->InitMenuItems(is_browser_mode, | 756 menu_items_[i].sub_menu_model->InitMenuItems(is_browser_mode, |
592 should_open_button_options); | 757 should_open_button_options); |
593 } | 758 } |
594 } | 759 } |
595 } | 760 } |
596 | 761 |
597 //////////////////////////////////////////////////////////////////////////////// | 762 // MainMenuModel, views::MenuDelegate implementation --------------------------- |
598 // VPNMenuModel | 763 |
| 764 const gfx::Font& MainMenuModel::GetLabelFont(int id) const { |
| 765 if (id >= kVPNCommandIndexOffset) |
| 766 return vpn_menu_model_->GetLabelFont(id - kVPNCommandIndexOffset); |
| 767 else |
| 768 return NetworkMenuModel::GetLabelFont(id); |
| 769 } |
| 770 |
| 771 bool MainMenuModel::IsItemChecked(int id) const { |
| 772 if (id >= kVPNCommandIndexOffset) |
| 773 return vpn_menu_model_->IsItemChecked(id - kVPNCommandIndexOffset); |
| 774 else |
| 775 return NetworkMenuModel::IsItemChecked(id); |
| 776 } |
| 777 |
| 778 bool MainMenuModel::IsCommandEnabled(int id) const { |
| 779 if (id >= kVPNCommandIndexOffset) |
| 780 return vpn_menu_model_->IsCommandEnabled(id - kVPNCommandIndexOffset); |
| 781 else |
| 782 return NetworkMenuModel::IsCommandEnabled(id); |
| 783 } |
| 784 |
| 785 void MainMenuModel::ExecuteCommand(int id) { |
| 786 if (id >= kVPNCommandIndexOffset) |
| 787 vpn_menu_model_->ExecuteCommand(id - kVPNCommandIndexOffset); |
| 788 else |
| 789 NetworkMenuModel::ExecuteCommand(id); |
| 790 } |
| 791 |
| 792 // MainMenuModel, NetworkMenuModel implementation: ----------------------------- |
| 793 |
| 794 void MainMenuModel::PopulateMenuItem( |
| 795 views::MenuItemView* menu, |
| 796 int index, |
| 797 int command_id) { |
| 798 DCHECK_GT(static_cast<int>(menu_items_.size()), index); |
| 799 const MenuItem& item = menu_items_[index]; |
| 800 if (item.type == ui::MenuModel::TYPE_SUBMENU) { |
| 801 views::MenuItemView* vpn_menu = NULL; |
| 802 if (item.icon.empty()) { |
| 803 vpn_menu = menu->AppendSubMenu(command_id, UTF16ToWide(item.label)); |
| 804 } else { |
| 805 vpn_menu = menu->AppendSubMenuWithIcon( |
| 806 command_id, |
| 807 UTF16ToWide(item.label), |
| 808 item.icon); |
| 809 } |
| 810 vpn_menu_model_->PopulateMenu(vpn_menu); |
| 811 } else { |
| 812 NetworkMenuModel::PopulateMenuItem(menu, index, command_id); |
| 813 } |
| 814 } |
| 815 |
| 816 // VPNMenuModel ---------------------------------------------------------------- |
599 | 817 |
600 VPNMenuModel::VPNMenuModel(NetworkMenu* owner) | 818 VPNMenuModel::VPNMenuModel(NetworkMenu* owner) |
601 : NetworkMenuModel(owner) { | 819 : NetworkMenuModel(owner) { |
602 } | 820 } |
603 | 821 |
| 822 // VPNMenuModel, NetworkMenuModel implementation: ------------------------------ |
| 823 |
604 void VPNMenuModel::InitMenuItems(bool is_browser_mode, | 824 void VPNMenuModel::InitMenuItems(bool is_browser_mode, |
605 bool should_open_button_options) { | 825 bool should_open_button_options) { |
606 // This gets called on initialization, so any changes should be reflected | 826 // This gets called on initialization, so any changes should be reflected |
607 // in CrosMock::SetNetworkLibraryStatusAreaExpectations(). | 827 // in CrosMock::SetNetworkLibraryStatusAreaExpectations(). |
608 | 828 |
609 menu_items_.clear(); | 829 menu_items_.clear(); |
610 | 830 |
611 // VPN only applies if there's a connected underlying network. | 831 // VPN only applies if there's a connected underlying network. |
612 NetworkLibrary* cros = CrosLibrary::Get()->GetNetworkLibrary(); | 832 NetworkLibrary* cros = CrosLibrary::Get()->GetNetworkLibrary(); |
613 const Network* connected_network = cros->connected_network(); | 833 const Network* connected_network = cros->connected_network(); |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
659 l10n_util::GetStringUTF16(IDS_STATUSBAR_NETWORK_ADD_VPN), | 879 l10n_util::GetStringUTF16(IDS_STATUSBAR_NETWORK_ADD_VPN), |
660 SkBitmap(), std::string(), FLAG_ADD_VPN)); | 880 SkBitmap(), std::string(), FLAG_ADD_VPN)); |
661 if (active_vpn) { | 881 if (active_vpn) { |
662 menu_items_.push_back(MenuItem( | 882 menu_items_.push_back(MenuItem( |
663 ui::MenuModel::TYPE_COMMAND, | 883 ui::MenuModel::TYPE_COMMAND, |
664 l10n_util::GetStringUTF16(IDS_STATUSBAR_NETWORK_DISCONNECT_VPN), | 884 l10n_util::GetStringUTF16(IDS_STATUSBAR_NETWORK_DISCONNECT_VPN), |
665 SkBitmap(), std::string(), FLAG_DISCONNECT_VPN)); | 885 SkBitmap(), std::string(), FLAG_DISCONNECT_VPN)); |
666 } | 886 } |
667 } | 887 } |
668 | 888 |
| 889 void VPNMenuModel::PopulateMenuItem( |
| 890 views::MenuItemView* menu, |
| 891 int index, |
| 892 int command_id) { |
| 893 NetworkMenuModel::PopulateMenuItem( |
| 894 menu, |
| 895 index, |
| 896 command_id + kVPNCommandIndexOffset); |
| 897 } |
| 898 |
669 // static | 899 // static |
670 SkBitmap VPNMenuModel::IconForDisplay(const Network* network) { | 900 SkBitmap VPNMenuModel::IconForDisplay(const Network* network) { |
671 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); | 901 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); |
672 const SkBitmap* icon = NULL; | 902 const SkBitmap* icon = NULL; |
673 const SkBitmap* bottom_right_badge = NULL; | 903 const SkBitmap* bottom_right_badge = NULL; |
674 const SkBitmap* top_left_badge = NULL; | 904 const SkBitmap* top_left_badge = NULL; |
675 // We know for sure |network| is the active network, so no more checking | 905 // We know for sure |network| is the active network, so no more checking |
676 // is needed by BadgeForPrivateNetworkStatus, hence pass in NULL. | 906 // is needed by BadgeForPrivateNetworkStatus, hence pass in NULL. |
677 const SkBitmap* bottom_left_badge = | 907 const SkBitmap* bottom_left_badge = |
678 NetworkMenu::BadgeForPrivateNetworkStatus(NULL); | 908 NetworkMenu::BadgeForPrivateNetworkStatus(NULL); |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
746 | 976 |
747 // static | 977 // static |
748 SkBitmap NetworkMenu::kAnimatingImages[kNumAnimatingImages]; | 978 SkBitmap NetworkMenu::kAnimatingImages[kNumAnimatingImages]; |
749 | 979 |
750 // static | 980 // static |
751 SkBitmap NetworkMenu::kAnimatingImagesBlack[kNumAnimatingImages]; | 981 SkBitmap NetworkMenu::kAnimatingImagesBlack[kNumAnimatingImages]; |
752 | 982 |
753 NetworkMenu::NetworkMenu() | 983 NetworkMenu::NetworkMenu() |
754 : min_width_(-1) { | 984 : min_width_(-1) { |
755 main_menu_model_.reset(new MainMenuModel(this)); | 985 main_menu_model_.reset(new MainMenuModel(this)); |
756 network_menu_.reset(new views::Menu2(main_menu_model_.get())); | 986 network_menu_.reset(new views::MenuItemView(main_menu_model_.get())); |
| 987 network_menu_->set_has_icons(true); |
757 } | 988 } |
758 | 989 |
759 NetworkMenu::~NetworkMenu() { | 990 NetworkMenu::~NetworkMenu() { |
760 } | 991 } |
761 | 992 |
762 void NetworkMenu::SetFirstLevelMenuWidth(int width) { | 993 void NetworkMenu::SetFirstLevelMenuWidth(int width) { |
763 min_width_ = width; | 994 min_width_ = width; |
764 // This actually has no effect since menu is rebuilt before showing. | |
765 network_menu_->SetMinimumWidth(width); | |
766 } | 995 } |
767 | 996 |
768 void NetworkMenu::CancelMenu() { | 997 void NetworkMenu::CancelMenu() { |
769 network_menu_->CancelMenu(); | 998 network_menu_->Cancel(); |
770 } | 999 } |
771 | 1000 |
772 void NetworkMenu::UpdateMenu() { | 1001 void NetworkMenu::UpdateMenu() { |
773 refreshing_menu_ = true; | 1002 refreshing_menu_ = true; |
774 main_menu_model_->InitMenuItems(IsBrowserMode(), ShouldOpenButtonOptions()); | 1003 main_menu_model_->InitMenuItems(IsBrowserMode(), ShouldOpenButtonOptions()); |
775 network_menu_->Rebuild(); | 1004 main_menu_model_->PopulateMenu(network_menu_.get()); |
776 refreshing_menu_ = false; | 1005 refreshing_menu_ = false; |
777 } | 1006 } |
778 | 1007 |
779 // static | 1008 // static |
780 const SkBitmap* NetworkMenu::IconForNetworkStrength(const WifiNetwork* wifi, | 1009 const SkBitmap* NetworkMenu::IconForNetworkStrength(const WifiNetwork* wifi, |
781 bool black) { | 1010 bool black) { |
782 DCHECK(wifi); | 1011 DCHECK(wifi); |
783 if (wifi->strength() == 0) { | 1012 if (wifi->strength() == 0) { |
784 return ResourceBundle::GetSharedInstance().GetBitmapNamed( | 1013 return ResourceBundle::GetSharedInstance().GetBitmapNamed( |
785 black ? IDR_STATUSBAR_NETWORK_BARS0_BLACK : | 1014 black ? IDR_STATUSBAR_NETWORK_BARS0_BLACK : |
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
964 kBottomRightBadgeX, | 1193 kBottomRightBadgeX, |
965 kBottomRightBadgeY); | 1194 kBottomRightBadgeY); |
966 if (top_left_badge != NULL) | 1195 if (top_left_badge != NULL) |
967 canvas.DrawBitmapInt(*top_left_badge, kTopLeftBadgeX, kTopLeftBadgeY); | 1196 canvas.DrawBitmapInt(*top_left_badge, kTopLeftBadgeX, kTopLeftBadgeY); |
968 if (bottom_left_badge != NULL) | 1197 if (bottom_left_badge != NULL) |
969 canvas.DrawBitmapInt(*bottom_left_badge, kBottomLeftBadgeX, | 1198 canvas.DrawBitmapInt(*bottom_left_badge, kBottomLeftBadgeX, |
970 kBottomLeftBadgeY); | 1199 kBottomLeftBadgeY); |
971 return canvas.ExtractBitmap(); | 1200 return canvas.ExtractBitmap(); |
972 } | 1201 } |
973 | 1202 |
974 //////////////////////////////////////////////////////////////////////////////// | 1203 // NetworkMenu, views::ViewMenuDelegate implementation: ------------------------ |
975 // NetworkMenu, views::ViewMenuDelegate implementation: | |
976 | 1204 |
977 void NetworkMenu::RunMenu(views::View* source, const gfx::Point& pt) { | 1205 void NetworkMenu::RunMenu(views::View* source, const gfx::Point& pt) { |
978 refreshing_menu_ = true; | 1206 DCHECK_EQ(GetMenuButton(), source); |
979 NetworkLibrary* cros = CrosLibrary::Get()->GetNetworkLibrary(); | 1207 NetworkLibrary* cros = CrosLibrary::Get()->GetNetworkLibrary(); |
980 cros->RequestNetworkScan(); | 1208 cros->RequestNetworkScan(); |
981 | 1209 |
982 // Build initial menu items. They will be updated when UpdateMenu is | 1210 UpdateMenu(); |
983 // called from NetworkChanged. | |
984 main_menu_model_->InitMenuItems(IsBrowserMode(), ShouldOpenButtonOptions()); | |
985 network_menu_->Rebuild(); | |
986 | 1211 |
987 // Restore menu width, if it was set up. | 1212 // TODO(rhashimoto): Remove this workaround when WebUI provides a |
988 // NOTE: width isn't checked for correctness here since all width-related | 1213 // top-level widget on the ChromeOS login screen that is a window. |
989 // logic implemented inside |network_menu_|. | 1214 // The current BackgroundView class for the ChromeOS login screen |
990 if (min_width_ != -1) | 1215 // creates a owning Widget that has a native GtkWindow but is not a |
991 network_menu_->SetMinimumWidth(min_width_); | 1216 // Window. This makes it impossible to get the NativeWindow via |
992 refreshing_menu_ = false; | 1217 // the views API. This workaround casts the top-level NativeWidget |
993 network_menu_->RunMenuAt(pt, views::Menu2::ALIGN_TOPRIGHT); | 1218 // to a NativeWindow that we can pass to MenuItemView::RunMenuAt(). |
| 1219 gfx::NativeWindow window = GTK_WINDOW(source->GetWidget()->GetNativeView()); |
| 1220 |
| 1221 gfx::Point screen_loc; |
| 1222 views::View::ConvertPointToScreen(source, &screen_loc); |
| 1223 gfx::Rect bounds(screen_loc, source->size()); |
| 1224 network_menu_->RunMenuAt( |
| 1225 window, |
| 1226 GetMenuButton(), |
| 1227 bounds, |
| 1228 base::i18n::IsRTL() ? MenuItemView::TOPLEFT : MenuItemView::TOPRIGHT, |
| 1229 true); |
994 } | 1230 } |
995 | 1231 |
996 } // namespace chromeos | 1232 } // namespace chromeos |
OLD | NEW |