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.
5 #include "chrome/browser/chromeos/options/network_config_view.h"
10 #include "base/strings/string_util.h"
11 #include "base/strings/utf_string_conversions.h"
12 #include "chrome/browser/chromeos/login/ui/login_display_host_impl.h"
13 #include "chrome/browser/chromeos/options/network_property_ui_data.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 "chrome/grit/generated_resources.h"
23 #include "chrome/grit/locale_settings.h"
24 #include "chrome/grit/theme_resources.h"
25 #include "chromeos/login/login_state.h"
26 #include "chromeos/network/network_state.h"
27 #include "chromeos/network/network_state_handler.h"
28 #include "components/user_manager/user.h"
29 #include "ui/accessibility/ax_view_state.h"
30 #include "ui/aura/window_event_dispatcher.h"
31 #include "ui/base/l10n/l10n_util.h"
32 #include "ui/base/resource/resource_bundle.h"
33 #include "ui/gfx/geometry/rect.h"
34 #include "ui/gfx/image/image.h"
35 #include "ui/views/controls/button/label_button.h"
36 #include "ui/views/controls/image_view.h"
37 #include "ui/views/layout/layout_constants.h"
38 #include "ui/views/widget/widget.h"
44 gfx::NativeWindow
GetParentForUnhostedDialog() {
45 if (chromeos::LoginDisplayHostImpl::default_host()) {
46 return chromeos::LoginDisplayHostImpl::default_host()->GetNativeWindow();
48 Browser
* browser
= chrome::FindTabbedBrowser(
49 ProfileManager::GetPrimaryUserProfile(),
51 chrome::HOST_DESKTOP_TYPE_ASH
);
53 return browser
->window()->GetNativeWindow();
58 // Avoid global static initializer.
59 chromeos::NetworkConfigView
** GetActiveDialogPointer() {
60 static chromeos::NetworkConfigView
* active_dialog
= NULL
;
61 return &active_dialog
;
64 chromeos::NetworkConfigView
* GetActiveDialog() {
65 return *(GetActiveDialogPointer());
68 void SetActiveDialog(chromeos::NetworkConfigView
* dialog
) {
69 *(GetActiveDialogPointer()) = dialog
;
77 const int ChildNetworkConfigView::kInputFieldMinWidth
= 270;
79 NetworkConfigView::NetworkConfigView()
80 : child_config_view_(NULL
),
82 advanced_button_(NULL
) {
83 DCHECK(GetActiveDialog() == NULL
);
84 SetActiveDialog(this);
87 bool NetworkConfigView::InitWithNetworkState(const NetworkState
* network
) {
89 std::string service_path
= network
->path();
90 if (network
->type() == shill::kTypeWifi
||
91 network
->type() == shill::kTypeEthernet
) {
92 child_config_view_
= new WifiConfigView(this, service_path
, false);
93 } else if (network
->type() == shill::kTypeWimax
) {
94 child_config_view_
= new WimaxConfigView(this, service_path
);
95 } else if (network
->type() == shill::kTypeVPN
) {
96 child_config_view_
= new VPNConfigView(this, service_path
);
98 return child_config_view_
!= NULL
;
101 bool NetworkConfigView::InitWithType(const std::string
& type
) {
102 if (type
== shill::kTypeWifi
) {
103 child_config_view_
= new WifiConfigView(this,
104 "" /* service_path */,
105 false /* show_8021x */);
106 advanced_button_
= new views::LabelButton(this, l10n_util::GetStringUTF16(
107 IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_ADVANCED_BUTTON
));
108 advanced_button_
->SetStyle(views::Button::STYLE_BUTTON
);
109 } else if (type
== shill::kTypeVPN
) {
110 child_config_view_
= new VPNConfigView(this,
111 "" /* service_path */);
113 return child_config_view_
!= NULL
;
116 NetworkConfigView::~NetworkConfigView() {
117 DCHECK(GetActiveDialog() == this);
118 SetActiveDialog(NULL
);
122 void NetworkConfigView::Show(const std::string
& service_path
,
123 gfx::NativeWindow parent
) {
124 if (GetActiveDialog() != NULL
)
126 NetworkConfigView
* view
= new NetworkConfigView();
127 const NetworkState
* network
= NetworkHandler::Get()->network_state_handler()->
128 GetNetworkState(service_path
);
130 LOG(ERROR
) << "NetworkConfigView::Show called with invalid service_path";
133 if (!view
->InitWithNetworkState(network
)) {
134 LOG(ERROR
) << "NetworkConfigView::Show called with invalid network type: "
139 view
->ShowDialog(parent
);
143 void NetworkConfigView::ShowForType(const std::string
& type
,
144 gfx::NativeWindow parent
) {
145 if (GetActiveDialog() != NULL
)
147 NetworkConfigView
* view
= new NetworkConfigView();
148 if (!view
->InitWithType(type
)) {
149 LOG(ERROR
) << "NetworkConfigView::ShowForType called with invalid type: "
154 view
->ShowDialog(parent
);
157 gfx::NativeWindow
NetworkConfigView::GetNativeWindow() const {
158 return GetWidget()->GetNativeWindow();
161 base::string16
NetworkConfigView::GetDialogButtonLabel(
162 ui::DialogButton button
) const {
163 if (button
== ui::DIALOG_BUTTON_OK
) {
164 if (child_config_view_
->IsConfigureDialog())
165 return l10n_util::GetStringUTF16(IDS_OPTIONS_SETTINGS_CONFIGURE
);
166 return l10n_util::GetStringUTF16(IDS_OPTIONS_SETTINGS_CONNECT
);
168 return views::DialogDelegateView::GetDialogButtonLabel(button
);
171 bool NetworkConfigView::IsDialogButtonEnabled(ui::DialogButton button
) const {
172 // Disable connect button if cannot login.
173 if (button
== ui::DIALOG_BUTTON_OK
)
174 return child_config_view_
->CanLogin();
178 bool NetworkConfigView::Cancel() {
180 delegate_
->OnDialogCancelled();
181 child_config_view_
->Cancel();
185 bool NetworkConfigView::Accept() {
186 // Do not attempt login if it is guaranteed to fail, keep the dialog open.
187 if (!child_config_view_
->CanLogin())
189 bool result
= child_config_view_
->Login();
190 if (result
&& delegate_
)
191 delegate_
->OnDialogAccepted();
195 views::View
* NetworkConfigView::CreateExtraView() {
196 return advanced_button_
;
199 views::View
* NetworkConfigView::GetInitiallyFocusedView() {
200 return child_config_view_
->GetInitiallyFocusedView();
203 base::string16
NetworkConfigView::GetWindowTitle() const {
204 DCHECK(!child_config_view_
->GetTitle().empty());
205 return child_config_view_
->GetTitle();
208 ui::ModalType
NetworkConfigView::GetModalType() const {
209 return ui::MODAL_TYPE_SYSTEM
;
212 void NetworkConfigView::GetAccessibleState(ui::AXViewState
* state
) {
213 views::DialogDelegateView::GetAccessibleState(state
);
215 l10n_util::GetStringUTF16(IDS_OPTIONS_SETTINGS_OTHER_WIFI_NETWORKS
);
218 void NetworkConfigView::ButtonPressed(views::Button
* sender
,
219 const ui::Event
& event
) {
220 if (advanced_button_
&& sender
== advanced_button_
) {
221 advanced_button_
->SetVisible(false);
226 void NetworkConfigView::ShowAdvancedView() {
227 // Clear out the old widgets and build new ones.
228 RemoveChildView(child_config_view_
);
229 delete child_config_view_
;
230 // For now, there is only an advanced view for Wi-Fi 802.1X.
231 child_config_view_
= new WifiConfigView(this,
232 "" /* service_path */,
233 true /* show_8021x */);
234 AddChildView(child_config_view_
);
235 // Resize the window to be able to hold the new widgets.
236 gfx::Size size
= views::Widget::GetLocalizedContentsSize(
237 IDS_JOIN_WIFI_NETWORK_DIALOG_ADVANCED_WIDTH_CHARS
,
238 IDS_JOIN_WIFI_NETWORK_DIALOG_ADVANCED_MINIMUM_HEIGHT_LINES
);
239 // Get the new bounds with desired size at the same center point.
240 gfx::Rect bounds
= GetWidget()->GetWindowBoundsInScreen();
241 int horiz_padding
= bounds
.width() - size
.width();
242 int vert_padding
= bounds
.height() - size
.height();
243 bounds
.Inset(horiz_padding
/ 2, vert_padding
/ 2,
244 horiz_padding
/ 2, vert_padding
/ 2);
245 GetWidget()->SetBoundsConstrained(bounds
);
247 child_config_view_
->InitFocus();
250 void NetworkConfigView::Layout() {
251 child_config_view_
->SetBounds(0, 0, width(), height());
254 gfx::Size
NetworkConfigView::GetPreferredSize() const {
255 gfx::Size
result(views::Widget::GetLocalizedContentsSize(
256 IDS_JOIN_WIFI_NETWORK_DIALOG_WIDTH_CHARS
,
257 IDS_JOIN_WIFI_NETWORK_DIALOG_MINIMUM_HEIGHT_LINES
));
258 gfx::Size size
= child_config_view_
->GetPreferredSize();
259 result
.set_height(size
.height());
260 if (size
.width() > result
.width())
261 result
.set_width(size
.width());
265 void NetworkConfigView::ViewHierarchyChanged(
266 const ViewHierarchyChangedDetails
& details
) {
267 // Can't init before we're inserted into a Container, because we require
268 // a HWND to parent native child controls to.
269 views::DialogDelegateView::ViewHierarchyChanged(details
);
270 if (details
.is_add
&& details
.child
== this) {
271 AddChildView(child_config_view_
);
275 void NetworkConfigView::ShowDialog(gfx::NativeWindow parent
) {
277 parent
= GetParentForUnhostedDialog();
278 // Failed connections may result in a pop-up with no natural parent window,
279 // so provide a fallback context on the primary display. This is necessary
280 // becase one of parent or context must be non NULL.
281 gfx::NativeWindow context
=
282 parent
? NULL
: ash::Shell::GetPrimaryRootWindow();
283 Widget
* window
= DialogDelegate::CreateDialogWidget(this, context
, parent
);
284 window
->SetAlwaysOnTop(true);
288 // ChildNetworkConfigView
290 ChildNetworkConfigView::ChildNetworkConfigView(
291 NetworkConfigView
* parent
,
292 const std::string
& service_path
)
294 service_path_(service_path
) {
297 ChildNetworkConfigView::~ChildNetworkConfigView() {
300 bool ChildNetworkConfigView::IsConfigureDialog() {
305 void ChildNetworkConfigView::GetShareStateForLoginState(bool* default_value
,
307 *default_value
= !LoginState::Get()->UserHasNetworkProfile();
308 // Allow only authenticated user to change the share state.
309 *modifiable
= LoginState::Get()->IsUserAuthenticated();
312 // ControlledSettingIndicatorView
314 ControlledSettingIndicatorView::ControlledSettingIndicatorView()
320 ControlledSettingIndicatorView::ControlledSettingIndicatorView(
321 const NetworkPropertyUIData
& ui_data
)
328 ControlledSettingIndicatorView::~ControlledSettingIndicatorView() {}
330 void ControlledSettingIndicatorView::Update(
331 const NetworkPropertyUIData
& ui_data
) {
332 if (managed_
== ui_data
.IsManaged())
335 managed_
= ui_data
.IsManaged();
336 PreferredSizeChanged();
339 gfx::Size
ControlledSettingIndicatorView::GetPreferredSize() const {
340 return (managed_
&& visible()) ? image_view_
->GetPreferredSize()
344 void ControlledSettingIndicatorView::Layout() {
345 image_view_
->SetBounds(0, 0, width(), height());
348 void ControlledSettingIndicatorView::Init() {
349 image_
= ResourceBundle::GetSharedInstance().GetImageNamed(
350 IDR_CONTROLLED_SETTING_MANDATORY
).ToImageSkia();
351 image_view_
= new views::ImageView();
352 // Disable |image_view_| so mouse events propagate to the parent.
353 image_view_
->SetEnabled(false);
354 image_view_
->SetImage(image_
);
355 image_view_
->SetTooltipText(
356 l10n_util::GetStringUTF16(IDS_OPTIONS_CONTROLLED_SETTING_POLICY
));
357 AddChildView(image_view_
);
360 } // namespace chromeos