| // Copyright (c) 2009 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "chrome/browser/chromeos/options/internet_page_view.h" |
| |
| #include <string> |
| |
| #include "app/combobox_model.h" |
| #include "chrome/browser/chromeos/cros/cros_library.h" |
| #include "chrome/browser/chromeos/options/network_config_view.h" |
| #include "chrome/browser/chromeos/options/options_window_view.h" |
| #include "chrome/browser/chromeos/status/network_menu_button.h" |
| #include "grit/generated_resources.h" |
| #include "grit/theme_resources.h" |
| #include "views/controls/button/native_button.h" |
| #include "views/controls/combobox/combobox.h" |
| #include "views/controls/image_view.h" |
| #include "views/widget/widget.h" |
| #include "views/window/window.h" |
| |
| namespace chromeos { |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| // NetworkSection |
| |
| class NetworkSection : public SettingsPageSection, |
| public views::ButtonListener { |
| public: |
| NetworkSection(InternetPageView* parent, Profile* profile, int title_msg_id); |
| virtual ~NetworkSection() {} |
| |
| // Overriden from views::Button::ButtonListener: |
| virtual void ButtonPressed(views::Button* sender, const views::Event& event); |
| |
| protected: |
| enum ButtonFlags { |
| OPTIONS_BUTTON = 1 << 0, |
| CONNECT_BUTTON = 1 << 1, |
| DISCONNECT_BUTTON = 1 << 2, |
| FORGET_BUTTON = 1 << 3, |
| }; |
| |
| // SettingsPageSection overrides: |
| virtual void InitContents(GridLayout* layout); |
| |
| // Subclasses will initialize themselves in this method. |
| virtual void InitSection() = 0; |
| |
| // This adds a row for a network. |
| // |id| is passed back in the ButtonClicked method. |
| // |icon|, |name|, |bold_name|, and |status| are displayed in the row. |
| // |button_flags| is an OR of ButtonFlags that should be displayed. |
| void AddNetwork(int id, const SkBitmap& icon, const std::wstring& name, |
| bool bold_name, const std::wstring& status, int button_flags, |
| int connection_type); |
| |
| // Creates a modal popup with |view|. |
| void CreateModalPopup(views::WindowDelegate* view); |
| |
| // This method is called when the user click on the |button| for |id|. |
| virtual void ButtonClicked(int button, int connection_type, int id) = 0; |
| |
| private: |
| // This constant determines the button tag offset for the different buttons. |
| // The ButtonFlag is multiplied by this offset to determine the button tag. |
| // For example, for disconnect buttons (DISCONNECT_BUTTON = 4), the button tag |
| // will be offset by 4000. |
| static const int kButtonIdOffset = 1000; |
| // This constant determines the button tag offset for the connection types. |
| // The ConnectionType is multiplied by this to determine the button tag. |
| // For example, for wifi buttons (TYPE_WIFI = 2), the button tag |
| // will be offset by 200. |
| static const int kConnectionTypeOffset = 100; |
| |
| InternetPageView* parent_; |
| |
| int quad_column_view_set_id_; |
| |
| GridLayout* layout_; |
| |
| DISALLOW_COPY_AND_ASSIGN(NetworkSection); |
| }; |
| |
| NetworkSection::NetworkSection(InternetPageView* parent, Profile* profile, |
| int title_msg_id) |
| : SettingsPageSection(profile, title_msg_id), |
| parent_(parent), |
| quad_column_view_set_id_(1) { |
| } |
| |
| void NetworkSection::ButtonPressed(views::Button* sender, |
| const views::Event& event) { |
| int id = sender->tag(); |
| // Determine the button from the id (div by kButtonIdOffset). |
| int button = id / kButtonIdOffset; |
| id %= kButtonIdOffset; |
| // Determine the connection type from the id (div by kConnectionTypeOffset). |
| int connection_type = id / kConnectionTypeOffset; |
| id %= kConnectionTypeOffset; |
| |
| ButtonClicked(button, connection_type, id); |
| } |
| |
| void NetworkSection::InitContents(GridLayout* layout) { |
| layout_ = layout; |
| |
| ColumnSet* column_set = layout_->AddColumnSet(quad_column_view_set_id_); |
| // icon |
| column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, 1, |
| GridLayout::USE_PREF, 0, 0); |
| // network name |
| column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, 1, |
| GridLayout::USE_PREF, 0, 0); |
| // fill padding |
| column_set->AddPaddingColumn(10, 0); |
| // first button |
| column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, 1, |
| GridLayout::USE_PREF, 0, 0); |
| // padding |
| column_set->AddPaddingColumn(0, 10); |
| // second button |
| column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, 1, |
| GridLayout::USE_PREF, 0, 0); |
| |
| InitSection(); |
| } |
| |
| void NetworkSection::AddNetwork(int id, const SkBitmap& icon, |
| const std::wstring& name, bool bold_name, |
| const std::wstring& status, int button_flags, |
| int connection_type) { |
| ResourceBundle& rb = ResourceBundle::GetSharedInstance(); |
| |
| // Offset id by connection type. |
| id += kConnectionTypeOffset * connection_type; |
| |
| layout_->StartRow(0, quad_column_view_set_id_); |
| views::ImageView* icon_view = new views::ImageView(); |
| icon_view->SetImage(icon); |
| layout_->AddView(icon_view, 1, 2); |
| |
| views::Label* name_view = new views::Label(name); |
| if (bold_name) |
| name_view->SetFont(rb.GetFont(ResourceBundle::BoldFont)); |
| name_view->SetHorizontalAlignment(views::Label::ALIGN_LEFT); |
| layout_->AddView(name_view); |
| |
| int num_buttons = 0; |
| if (button_flags & OPTIONS_BUTTON) |
| num_buttons++; |
| if (button_flags & CONNECT_BUTTON) |
| num_buttons++; |
| if (button_flags & DISCONNECT_BUTTON) |
| num_buttons++; |
| if (button_flags & FORGET_BUTTON) |
| num_buttons++; |
| |
| if (num_buttons > 0) { |
| // We only support 2 buttons. |
| DCHECK_LE(num_buttons, 2); |
| |
| if (num_buttons == 1) |
| layout_->SkipColumns(1); |
| |
| if (button_flags & FORGET_BUTTON) { |
| views::NativeButton* button = new views::NativeButton(this, |
| l10n_util::GetString(IDS_OPTIONS_SETTINGS_FORGET)); |
| button->set_tag(id + kButtonIdOffset * FORGET_BUTTON); |
| layout_->AddView(button, 1, 2); |
| } |
| |
| if (button_flags & DISCONNECT_BUTTON) { |
| views::NativeButton* button = new views::NativeButton(this, |
| l10n_util::GetString(IDS_OPTIONS_SETTINGS_DISCONNECT)); |
| button->set_tag(id + kButtonIdOffset * DISCONNECT_BUTTON); |
| layout_->AddView(button, 1, 2); |
| } |
| |
| if (button_flags & CONNECT_BUTTON) { |
| views::NativeButton* button = new views::NativeButton(this, |
| l10n_util::GetString(IDS_OPTIONS_SETTINGS_CONNECT)); |
| button->set_tag(id + kButtonIdOffset * CONNECT_BUTTON); |
| layout_->AddView(button, 1, 2); |
| } |
| |
| if (button_flags & OPTIONS_BUTTON) { |
| views::NativeButton* button = new views::NativeButton(this, |
| l10n_util::GetString(IDS_OPTIONS_SETTINGS_OPTIONS)); |
| button->set_tag(id + kButtonIdOffset * OPTIONS_BUTTON); |
| layout_->AddView(button, 1, 2); |
| } |
| } |
| |
| layout_->StartRow(0, quad_column_view_set_id_); |
| layout_->SkipColumns(1); |
| views::Label* status_label = new views::Label(status); |
| status_label->SetFont(rb.GetFont(ResourceBundle::SmallFont)); |
| status_label->SetColor(SK_ColorLTGRAY); |
| status_label->SetHorizontalAlignment(views::Label::ALIGN_LEFT); |
| layout_->AddView(status_label); |
| layout_->AddPaddingRow(0, kRelatedControlVerticalSpacing); |
| } |
| |
| void NetworkSection::CreateModalPopup(views::WindowDelegate* view) { |
| views::Window* window = views::Window::CreateChromeWindow( |
| GetOptionsViewParent(), gfx::Rect(), view); |
| window->SetIsAlwaysOnTop(true); |
| window->Show(); |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| // WiredSection |
| |
| class WiredSection : public NetworkSection { |
| public: |
| WiredSection(InternetPageView* parent, Profile* profile); |
| virtual ~WiredSection() {} |
| |
| protected: |
| // NetworkSection overrides: |
| virtual void InitSection(); |
| virtual void ButtonClicked(int button, int connection_type, int id); |
| |
| DISALLOW_COPY_AND_ASSIGN(WiredSection); |
| }; |
| |
| WiredSection::WiredSection(InternetPageView* parent, Profile* profile) |
| : NetworkSection(parent, profile, |
| IDS_OPTIONS_SETTINGS_SECTION_TITLE_WIRED_NETWORK) { |
| } |
| |
| void WiredSection::InitSection() { |
| NetworkLibrary* cros = CrosLibrary::Get()->GetNetworkLibrary(); |
| ResourceBundle& rb = ResourceBundle::GetSharedInstance(); |
| |
| SkBitmap icon = *rb.GetBitmapNamed(IDR_STATUSBAR_WIRED_BLACK); |
| if (!cros->ethernet_connecting() && !cros->ethernet_connected()) { |
| icon = NetworkMenuButton::IconForDisplay(icon, |
| *rb.GetBitmapNamed(IDR_STATUSBAR_NETWORK_DISCONNECTED)); |
| } |
| |
| std::wstring name = |
| l10n_util::GetString(IDS_STATUSBAR_NETWORK_DEVICE_ETHERNET); |
| |
| int s = IDS_STATUSBAR_NETWORK_DEVICE_DISABLED; |
| if (cros->ethernet_connecting()) |
| s = IDS_STATUSBAR_NETWORK_DEVICE_CONNECTING; |
| else if (cros->ethernet_connected()) |
| s = IDS_STATUSBAR_NETWORK_DEVICE_CONNECTED; |
| else if (cros->ethernet_enabled()) |
| s = IDS_STATUSBAR_NETWORK_DEVICE_DISCONNECTED; |
| std::wstring status = l10n_util::GetString(s); |
| |
| int flags = cros->ethernet_connected() ? OPTIONS_BUTTON : 0; |
| bool bold = cros->ethernet_connected() ? true : false; |
| AddNetwork(0, icon, name, bold, status, flags, TYPE_ETHERNET); |
| } |
| |
| void WiredSection::ButtonClicked(int button, int connection_type, int id) { |
| CreateModalPopup(new NetworkConfigView( |
| CrosLibrary::Get()->GetNetworkLibrary()->ethernet_network())); |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| // WirelessSection |
| |
| class WirelessSection : public NetworkSection { |
| public: |
| WirelessSection(InternetPageView* parent, Profile* profile); |
| virtual ~WirelessSection() {} |
| |
| protected: |
| // NetworkSection overrides: |
| virtual void InitSection(); |
| virtual void ButtonClicked(int button, int connection_type, int id); |
| |
| private: |
| // This calls NetworkSection::AddNetwork . |
| // For |connecting| or |connected| networks, the name is bold. |
| // The status is "Connecting" if |connecting|, "Connected" if |connected|, |
| // or "Disconnected". |
| // For connected networks, we show the disconnect and options buttons. |
| // For !connected and !connecting networks, we show the connect button. |
| void AddWirelessNetwork(int id, const SkBitmap& icon, |
| const std::wstring& name, bool connecting, |
| bool connected, int connection_type); |
| |
| WifiNetworkVector wifi_networks_; |
| CellularNetworkVector celluar_networks_; |
| |
| DISALLOW_COPY_AND_ASSIGN(WirelessSection); |
| }; |
| |
| WirelessSection::WirelessSection(InternetPageView* parent, Profile* profile) |
| : NetworkSection(parent, profile, |
| IDS_OPTIONS_SETTINGS_SECTION_TITLE_WIRELESS_NETWORK) { |
| } |
| |
| void WirelessSection::InitSection() { |
| NetworkLibrary* cros = CrosLibrary::Get()->GetNetworkLibrary(); |
| ResourceBundle& rb = ResourceBundle::GetSharedInstance(); |
| |
| // Wifi |
| wifi_networks_ = cros->wifi_networks(); |
| for (size_t i = 0; i < wifi_networks_.size(); ++i) { |
| std::wstring name = ASCIIToWide(wifi_networks_[i].ssid); |
| |
| SkBitmap icon = NetworkMenuButton::IconForNetworkStrength( |
| wifi_networks_[i].strength, true); |
| if (wifi_networks_[i].encrypted) { |
| icon = NetworkMenuButton::IconForDisplay(icon, |
| *rb.GetBitmapNamed(IDR_STATUSBAR_NETWORK_SECURE)); |
| } |
| |
| bool connecting = wifi_networks_[i].connecting; |
| bool connected = wifi_networks_[i].connected; |
| AddWirelessNetwork(i, icon, name, connecting, connected, TYPE_WIFI); |
| } |
| |
| // Cellular |
| celluar_networks_ = cros->cellular_networks(); |
| // Cellular networks ssids. |
| for (size_t i = 0; i < celluar_networks_.size(); ++i) { |
| std::wstring name = ASCIIToWide(celluar_networks_[i].name); |
| |
| SkBitmap icon = NetworkMenuButton::IconForNetworkStrength( |
| celluar_networks_[i].strength, true); |
| // TODO(chocobo): Check cellular network 3g/edge. |
| SkBitmap badge = *rb.GetBitmapNamed(IDR_STATUSBAR_NETWORK_3G); |
| // SkBitmap badge = *rb.GetBitmapNamed(IDR_STATUSBAR_NETWORK_EDGE); |
| icon = NetworkMenuButton::IconForDisplay(icon, badge); |
| |
| bool connecting = celluar_networks_[i].connecting; |
| bool connected = celluar_networks_[i].connected; |
| AddWirelessNetwork(i, icon, name, connecting, connected, TYPE_CELLULAR); |
| } |
| } |
| |
| void WirelessSection::ButtonClicked(int button, int connection_type, int id) { |
| if (connection_type == TYPE_CELLULAR) { |
| if (static_cast<int>(celluar_networks_.size()) > id) { |
| if (button == CONNECT_BUTTON) { |
| // Connect to cellular network. |
| CrosLibrary::Get()->GetNetworkLibrary()->ConnectToCellularNetwork( |
| celluar_networks_[id]); |
| } else if (button == DISCONNECT_BUTTON) { |
| CrosLibrary::Get()->GetNetworkLibrary()->DisconnectFromCellularNetwork( |
| celluar_networks_[id]); |
| } else { |
| CreateModalPopup(new NetworkConfigView(celluar_networks_[id])); |
| } |
| } |
| } else if (connection_type == TYPE_WIFI) { |
| if (static_cast<int>(wifi_networks_.size()) > id) { |
| if (button == CONNECT_BUTTON) { |
| // Connect to wifi here. Open password page if appropriate. |
| if (wifi_networks_[id].encrypted) { |
| NetworkConfigView* view = |
| new NetworkConfigView(wifi_networks_[id], true); |
| CreateModalPopup(view); |
| view->SetLoginTextfieldFocus(); |
| } else { |
| CrosLibrary::Get()->GetNetworkLibrary()->ConnectToWifiNetwork( |
| wifi_networks_[id], string16(), string16(), string16()); |
| } |
| } else if (button == DISCONNECT_BUTTON) { |
| CrosLibrary::Get()->GetNetworkLibrary()->DisconnectFromWifiNetwork( |
| wifi_networks_[id]); |
| } else { |
| CreateModalPopup(new NetworkConfigView(wifi_networks_[id], false)); |
| } |
| } |
| } else { |
| NOTREACHED(); |
| } |
| } |
| |
| void WirelessSection::AddWirelessNetwork(int id, const SkBitmap& icon, |
| const std::wstring& name, bool connecting, bool connected, |
| int connection_type) { |
| bool bold = connecting || connected; |
| |
| int s = IDS_STATUSBAR_NETWORK_DEVICE_DISCONNECTED; |
| if (connecting) |
| s = IDS_STATUSBAR_NETWORK_DEVICE_CONNECTING; |
| else if (connected) |
| s = IDS_STATUSBAR_NETWORK_DEVICE_CONNECTED; |
| std::wstring status = l10n_util::GetString(s); |
| |
| int flags = 0; |
| if (connected) { |
| flags |= DISCONNECT_BUTTON | OPTIONS_BUTTON; |
| } else if (!connecting) { |
| flags |= CONNECT_BUTTON; |
| } |
| |
| AddNetwork(id, icon, name, bold, status, flags, connection_type); |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| // RememberedSection |
| |
| class RememberedSection : public NetworkSection { |
| public: |
| RememberedSection(InternetPageView* parent, Profile* profile); |
| virtual ~RememberedSection() {} |
| |
| protected: |
| // NetworkSection overrides: |
| virtual void InitSection(); |
| virtual void ButtonClicked(int button, int connection_type, int id); |
| |
| private: |
| WifiNetworkVector wifi_networks_; |
| CellularNetworkVector celluar_networks_; |
| |
| DISALLOW_COPY_AND_ASSIGN(RememberedSection); |
| }; |
| |
| RememberedSection::RememberedSection(InternetPageView* parent, Profile* profile) |
| : NetworkSection(parent, profile, |
| IDS_OPTIONS_SETTINGS_SECTION_TITLE_REMEMBERED_NETWORK) { |
| } |
| |
| void RememberedSection::InitSection() { |
| NetworkLibrary* cros = CrosLibrary::Get()->GetNetworkLibrary(); |
| ResourceBundle& rb = ResourceBundle::GetSharedInstance(); |
| |
| // Wifi |
| wifi_networks_ = cros->remembered_wifi_networks(); |
| for (size_t i = 0; i < wifi_networks_.size(); ++i) { |
| std::wstring name = ASCIIToWide(wifi_networks_[i].ssid); |
| |
| SkBitmap icon = *rb.GetBitmapNamed(IDR_STATUSBAR_NETWORK_BARS0); |
| if (wifi_networks_[i].encrypted) { |
| icon = NetworkMenuButton::IconForDisplay(icon, |
| *rb.GetBitmapNamed(IDR_STATUSBAR_NETWORK_SECURE)); |
| } |
| |
| AddNetwork(i, icon, name, false, std::wstring(), FORGET_BUTTON, TYPE_WIFI); |
| } |
| |
| // Cellular |
| celluar_networks_ = cros->remembered_cellular_networks(); |
| // Cellular networks ssids. |
| for (size_t i = 0; i < celluar_networks_.size(); ++i) { |
| std::wstring name = ASCIIToWide(celluar_networks_[i].name); |
| |
| SkBitmap icon = *rb.GetBitmapNamed(IDR_STATUSBAR_NETWORK_BARS0); |
| // TODO(chocobo): Check cellular network 3g/edge. |
| SkBitmap badge = *rb.GetBitmapNamed(IDR_STATUSBAR_NETWORK_3G); |
| // SkBitmap badge = *rb.GetBitmapNamed(IDR_STATUSBAR_NETWORK_EDGE); |
| icon = NetworkMenuButton::IconForDisplay(icon, badge); |
| |
| AddNetwork(i, icon, name, false, std::wstring(), FORGET_BUTTON, |
| TYPE_CELLULAR); |
| } |
| } |
| |
| void RememberedSection::ButtonClicked(int button, int connection_type, int id) { |
| if (connection_type == TYPE_CELLULAR) { |
| if (static_cast<int>(celluar_networks_.size()) > id) { |
| CrosLibrary::Get()->GetNetworkLibrary()->ForgetCellularNetwork( |
| celluar_networks_[id]); |
| } |
| } else if (connection_type == TYPE_WIFI) { |
| if (static_cast<int>(wifi_networks_.size()) > id) { |
| CrosLibrary::Get()->GetNetworkLibrary()->ForgetWifiNetwork( |
| wifi_networks_[id]); |
| } |
| } else { |
| NOTREACHED(); |
| } |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| // InternetPageView |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| // InternetPageView, SettingsPageView implementation: |
| |
| InternetPageView::InternetPageView(Profile* profile) |
| : SettingsPageView(profile) { |
| CrosLibrary::Get()->GetNetworkLibrary()->AddObserver(this); |
| } |
| |
| InternetPageView::~InternetPageView() { |
| CrosLibrary::Get()->GetNetworkLibrary()->RemoveObserver(this); |
| } |
| |
| void InternetPageView::NetworkChanged(NetworkLibrary* obj) { |
| InitControlLayout(); |
| } |
| |
| void InternetPageView::InitControlLayout() { |
| RemoveAllChildViews(true); |
| |
| GridLayout* layout = CreatePanelGridLayout(this); |
| SetLayoutManager(layout); |
| |
| int single_column_view_set_id = 0; |
| ColumnSet* column_set = layout->AddColumnSet(single_column_view_set_id); |
| column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, 1, |
| GridLayout::USE_PREF, 0, 0); |
| |
| layout->StartRow(0, single_column_view_set_id); |
| layout->AddView(new WiredSection(this, profile())); |
| layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); |
| |
| layout->StartRow(0, single_column_view_set_id); |
| layout->AddView(new WirelessSection(this, profile())); |
| layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); |
| |
| layout->StartRow(0, single_column_view_set_id); |
| layout->AddView(new RememberedSection(this, profile())); |
| layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); |
| |
| Layout(); |
| } |
| |
| } // namespace chromeos |