blob: 383a8b475541aaf0d1ba256ad133a9e2b7a48395 [file] [log] [blame]
// 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