network_config_view.cc revision 90dce4d38c5ff5333bea97d859d4e484e27edf0c
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/chromeos/options/network_config_view.h" 6 7#include <algorithm> 8 9#include "ash/shell.h" 10#include "base/string_util.h" 11#include "base/utf_string_conversions.h" 12#include "chrome/browser/chromeos/cros/network_property_ui_data.h" 13#include "chrome/browser/chromeos/login/login_display_host_impl.h" 14#include "chrome/browser/chromeos/options/vpn_config_view.h" 15#include "chrome/browser/chromeos/options/wifi_config_view.h" 16#include "chrome/browser/chromeos/options/wimax_config_view.h" 17#include "chrome/browser/profiles/profile_manager.h" 18#include "chrome/browser/ui/browser.h" 19#include "chrome/browser/ui/browser_finder.h" 20#include "chrome/browser/ui/browser_window.h" 21#include "chrome/browser/ui/host_desktop.h" 22#include "grit/chromium_strings.h" 23#include "grit/generated_resources.h" 24#include "grit/locale_settings.h" 25#include "grit/theme_resources.h" 26#include "ui/aura/root_window.h" 27#include "ui/base/accessibility/accessible_view_state.h" 28#include "ui/base/l10n/l10n_util.h" 29#include "ui/base/resource/resource_bundle.h" 30#include "ui/gfx/image/image.h" 31#include "ui/gfx/rect.h" 32#include "ui/views/controls/button/label_button.h" 33#include "ui/views/controls/image_view.h" 34#include "ui/views/layout/layout_constants.h" 35#include "ui/views/widget/widget.h" 36 37using views::Widget; 38 39namespace { 40 41gfx::NativeWindow GetDialogParent() { 42 if (chromeos::LoginDisplayHostImpl::default_host()) { 43 return chromeos::LoginDisplayHostImpl::default_host()->GetNativeWindow(); 44 } else { 45 Browser* browser = chrome::FindTabbedBrowser( 46 ProfileManager::GetDefaultProfileOrOffTheRecord(), 47 true, 48 chrome::HOST_DESKTOP_TYPE_ASH); 49 if (browser) 50 return browser->window()->GetNativeWindow(); 51 } 52 return NULL; 53} 54 55// Avoid global static initializer. 56chromeos::NetworkConfigView** GetActiveDialogPointer() { 57 static chromeos::NetworkConfigView* active_dialog = NULL; 58 return &active_dialog; 59} 60 61chromeos::NetworkConfigView* GetActiveDialog() { 62 return *(GetActiveDialogPointer()); 63} 64 65void SetActiveDialog(chromeos::NetworkConfigView* dialog) { 66 *(GetActiveDialogPointer()) = dialog; 67} 68 69} // namespace 70 71namespace chromeos { 72 73// static 74const int ChildNetworkConfigView::kInputFieldMinWidth = 270; 75 76NetworkConfigView::NetworkConfigView(Network* network) 77 : child_config_view_(NULL), 78 delegate_(NULL), 79 advanced_button_(NULL) { 80 DCHECK(GetActiveDialog() == NULL); 81 SetActiveDialog(this); 82 if (network->type() == TYPE_WIFI) { 83 child_config_view_ = 84 new WifiConfigView(this, static_cast<WifiNetwork*>(network)); 85 } else if (network->type() == TYPE_WIMAX) { 86 child_config_view_ = 87 new WimaxConfigView(this, static_cast<WimaxNetwork*>(network)); 88 } else if (network->type() == TYPE_VPN) { 89 child_config_view_ = 90 new VPNConfigView(this, static_cast<VirtualNetwork*>(network)); 91 } else { 92 NOTREACHED(); 93 } 94} 95 96NetworkConfigView::NetworkConfigView(ConnectionType type) 97 : child_config_view_(NULL), 98 delegate_(NULL), 99 advanced_button_(NULL) { 100 DCHECK(GetActiveDialog() == NULL); 101 SetActiveDialog(this); 102 if (type == TYPE_WIFI) { 103 child_config_view_ = new WifiConfigView(this, false /* show_8021x */); 104 advanced_button_ = new views::LabelButton(this, l10n_util::GetStringUTF16( 105 IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_ADVANCED_BUTTON)); 106 advanced_button_->SetStyle(views::Button::STYLE_NATIVE_TEXTBUTTON); 107 } else if (type == TYPE_VPN) { 108 child_config_view_ = new VPNConfigView(this); 109 } else { 110 NOTREACHED(); 111 } 112} 113 114NetworkConfigView::~NetworkConfigView() { 115 DCHECK(GetActiveDialog() == this); 116 SetActiveDialog(NULL); 117} 118 119// static 120bool NetworkConfigView::Show(Network* network, gfx::NativeWindow parent) { 121 if (GetActiveDialog() != NULL) 122 return false; 123 NetworkConfigView* view = new NetworkConfigView(network); 124 view->ShowDialog(parent); 125 return true; 126} 127 128// static 129bool NetworkConfigView::ShowForType(ConnectionType type, 130 gfx::NativeWindow parent) { 131 if (GetActiveDialog() != NULL) 132 return false; 133 NetworkConfigView* view = new NetworkConfigView(type); 134 view->ShowDialog(parent); 135 return true; 136} 137 138gfx::NativeWindow NetworkConfigView::GetNativeWindow() const { 139 return GetWidget()->GetNativeWindow(); 140} 141 142string16 NetworkConfigView::GetDialogButtonLabel( 143 ui::DialogButton button) const { 144 if (button == ui::DIALOG_BUTTON_OK) 145 return l10n_util::GetStringUTF16(IDS_OPTIONS_SETTINGS_CONNECT); 146 return views::DialogDelegateView::GetDialogButtonLabel(button); 147} 148 149bool NetworkConfigView::IsDialogButtonEnabled(ui::DialogButton button) const { 150 // Disable connect button if cannot login. 151 if (button == ui::DIALOG_BUTTON_OK) 152 return child_config_view_->CanLogin(); 153 return true; 154} 155 156bool NetworkConfigView::Cancel() { 157 if (delegate_) 158 delegate_->OnDialogCancelled(); 159 child_config_view_->Cancel(); 160 return true; 161} 162 163bool NetworkConfigView::Accept() { 164 // Do not attempt login if it is guaranteed to fail, keep the dialog open. 165 if (!child_config_view_->CanLogin()) 166 return false; 167 bool result = child_config_view_->Login(); 168 if (result && delegate_) 169 delegate_->OnDialogAccepted(); 170 return result; 171} 172 173views::View* NetworkConfigView::CreateExtraView() { 174 return advanced_button_; 175} 176 177views::View* NetworkConfigView::GetInitiallyFocusedView() { 178 return child_config_view_->GetInitiallyFocusedView(); 179} 180 181string16 NetworkConfigView::GetWindowTitle() const { 182 DCHECK(!child_config_view_->GetTitle().empty()); 183 return child_config_view_->GetTitle(); 184} 185 186ui::ModalType NetworkConfigView::GetModalType() const { 187 return ui::MODAL_TYPE_SYSTEM; 188} 189 190void NetworkConfigView::GetAccessibleState(ui::AccessibleViewState* state) { 191 state->name = 192 l10n_util::GetStringUTF16(IDS_OPTIONS_SETTINGS_OTHER_WIFI_NETWORKS); 193 state->role = ui::AccessibilityTypes::ROLE_DIALOG; 194} 195 196void NetworkConfigView::ButtonPressed(views::Button* sender, 197 const ui::Event& event) { 198 if (advanced_button_ && sender == advanced_button_) { 199 advanced_button_->SetVisible(false); 200 ShowAdvancedView(); 201 } 202} 203 204void NetworkConfigView::ShowAdvancedView() { 205 // Clear out the old widgets and build new ones. 206 RemoveChildView(child_config_view_); 207 delete child_config_view_; 208 // For now, there is only an advanced view for Wi-Fi 802.1X. 209 child_config_view_ = new WifiConfigView(this, true /* show_8021x */); 210 AddChildView(child_config_view_); 211 // Resize the window to be able to hold the new widgets. 212 gfx::Size size = views::Widget::GetLocalizedContentsSize( 213 IDS_JOIN_WIFI_NETWORK_DIALOG_ADVANCED_WIDTH_CHARS, 214 IDS_JOIN_WIFI_NETWORK_DIALOG_ADVANCED_MINIMUM_HEIGHT_LINES); 215 // Get the new bounds with desired size at the same center point. 216 gfx::Rect bounds = GetWidget()->GetWindowBoundsInScreen(); 217 int horiz_padding = bounds.width() - size.width(); 218 int vert_padding = bounds.height() - size.height(); 219 bounds.Inset(horiz_padding / 2, vert_padding / 2, 220 horiz_padding / 2, vert_padding / 2); 221 GetWidget()->SetBoundsConstrained(bounds); 222 Layout(); 223 child_config_view_->InitFocus(); 224} 225 226void NetworkConfigView::Layout() { 227 child_config_view_->SetBounds(0, 0, width(), height()); 228} 229 230gfx::Size NetworkConfigView::GetPreferredSize() { 231 gfx::Size result(views::Widget::GetLocalizedContentsSize( 232 IDS_JOIN_WIFI_NETWORK_DIALOG_WIDTH_CHARS, 233 IDS_JOIN_WIFI_NETWORK_DIALOG_MINIMUM_HEIGHT_LINES)); 234 gfx::Size size = child_config_view_->GetPreferredSize(); 235 result.set_height(size.height()); 236 if (size.width() > result.width()) 237 result.set_width(size.width()); 238 return result; 239} 240 241void NetworkConfigView::ViewHierarchyChanged( 242 const ViewHierarchyChangedDetails& details) { 243 // Can't init before we're inserted into a Container, because we require 244 // a HWND to parent native child controls to. 245 if (details.is_add && details.child == this) { 246 AddChildView(child_config_view_); 247 } 248} 249 250void NetworkConfigView::ShowDialog(gfx::NativeWindow parent) { 251 if (parent == NULL) 252 parent = GetDialogParent(); 253 // Failed connections may result in a pop-up with no natural parent window, 254 // so provide a fallback context on the active display. 255 gfx::NativeWindow context = parent ? NULL : ash::Shell::GetActiveRootWindow(); 256 Widget* window = DialogDelegate::CreateDialogWidget(this, context, parent); 257 window->SetAlwaysOnTop(true); 258 window->Show(); 259} 260 261ControlledSettingIndicatorView::ControlledSettingIndicatorView() 262 : managed_(false), 263 image_view_(NULL) { 264 Init(); 265} 266 267ControlledSettingIndicatorView::ControlledSettingIndicatorView( 268 const NetworkPropertyUIData& ui_data) 269 : managed_(false), 270 image_view_(NULL) { 271 Init(); 272 Update(ui_data); 273} 274 275ControlledSettingIndicatorView::~ControlledSettingIndicatorView() {} 276 277void ControlledSettingIndicatorView::Update( 278 const NetworkPropertyUIData& ui_data) { 279 if (managed_ == ui_data.IsManaged()) 280 return; 281 282 managed_ = ui_data.IsManaged(); 283 PreferredSizeChanged(); 284} 285 286gfx::Size ControlledSettingIndicatorView::GetPreferredSize() { 287 return (managed_ && visible()) ? image_view_->GetPreferredSize() 288 : gfx::Size(); 289} 290 291void ControlledSettingIndicatorView::Layout() { 292 image_view_->SetBounds(0, 0, width(), height()); 293} 294 295void ControlledSettingIndicatorView::OnMouseEntered( 296 const ui::MouseEvent& event) { 297 image_view_->SetImage(color_image_); 298} 299 300void ControlledSettingIndicatorView::OnMouseExited( 301 const ui::MouseEvent& event) { 302 image_view_->SetImage(gray_image_); 303} 304 305void ControlledSettingIndicatorView::Init() { 306 color_image_ = ResourceBundle::GetSharedInstance().GetImageNamed( 307 IDR_CONTROLLED_SETTING_MANDATORY).ToImageSkia(); 308 gray_image_ = ResourceBundle::GetSharedInstance().GetImageNamed( 309 IDR_CONTROLLED_SETTING_MANDATORY_GRAY).ToImageSkia(); 310 image_view_ = new views::ImageView(); 311 // Disable |image_view_| so mouse events propagate to the parent. 312 image_view_->SetEnabled(false); 313 image_view_->SetImage(gray_image_); 314 image_view_->SetTooltipText( 315 l10n_util::GetStringUTF16(IDS_OPTIONS_CONTROLLED_SETTING_POLICY)); 316 AddChildView(image_view_); 317} 318 319} // namespace chromeos 320