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/ui/views/javascript_app_modal_dialog_views.h"
6
7#include "base/strings/utf_string_conversions.h"
8#include "chrome/browser/ui/app_modal_dialogs/javascript_app_modal_dialog.h"
9#include "chrome/browser/ui/views/constrained_window_views.h"
10#include "chrome/grit/generated_resources.h"
11#include "ui/base/l10n/l10n_util.h"
12#include "ui/events/keycodes/keyboard_codes.h"
13#include "ui/views/controls/message_box_view.h"
14#include "ui/views/controls/textfield/textfield.h"
15#include "ui/views/widget/widget.h"
16#include "ui/views/window/dialog_client_view.h"
17
18#if defined(USE_X11) && !defined(OS_CHROMEOS)
19#include "chrome/browser/ui/views/javascript_app_modal_event_blocker_x11.h"
20#endif
21
22////////////////////////////////////////////////////////////////////////////////
23// JavaScriptAppModalDialogViews, public:
24
25JavaScriptAppModalDialogViews::JavaScriptAppModalDialogViews(
26    JavaScriptAppModalDialog* parent)
27    : parent_(parent) {
28  int options = views::MessageBoxView::DETECT_DIRECTIONALITY;
29  if (parent->javascript_message_type() ==
30          content::JAVASCRIPT_MESSAGE_TYPE_PROMPT)
31    options |= views::MessageBoxView::HAS_PROMPT_FIELD;
32
33  views::MessageBoxView::InitParams params(parent->message_text());
34  params.options = options;
35  params.default_prompt = parent->default_prompt_text();
36  message_box_view_ = new views::MessageBoxView(params);
37  DCHECK(message_box_view_);
38
39  message_box_view_->AddAccelerator(
40      ui::Accelerator(ui::VKEY_C, ui::EF_CONTROL_DOWN));
41  if (parent->display_suppress_checkbox()) {
42    message_box_view_->SetCheckBoxLabel(
43        l10n_util::GetStringUTF16(IDS_JAVASCRIPT_MESSAGEBOX_SUPPRESS_OPTION));
44  }
45}
46
47JavaScriptAppModalDialogViews::~JavaScriptAppModalDialogViews() {
48}
49
50////////////////////////////////////////////////////////////////////////////////
51// JavaScriptAppModalDialogViews, NativeAppModalDialog implementation:
52
53int JavaScriptAppModalDialogViews::GetAppModalDialogButtons() const {
54  return GetDialogButtons();
55}
56
57void JavaScriptAppModalDialogViews::ShowAppModalDialog() {
58#if defined(USE_X11) && !defined(OS_CHROMEOS)
59  // BrowserView::CanActivate() ensures that other browser windows cannot be
60  // activated for long while the dialog is visible. Block events to other
61  // browser windows so that the user cannot interact with other browser windows
62  // in the short time that the other browser windows are active. This hack is
63  // unnecessary on Windows and Chrome OS.
64  // TODO(pkotwicz): Find a better way of doing this and remove this hack.
65  if (!event_blocker_x11_.get()) {
66    event_blocker_x11_.reset(
67        new JavascriptAppModalEventBlockerX11(GetWidget()->GetNativeView()));
68  }
69#endif
70
71  GetWidget()->Show();
72}
73
74void JavaScriptAppModalDialogViews::ActivateAppModalDialog() {
75  GetWidget()->Show();
76  GetWidget()->Activate();
77}
78
79void JavaScriptAppModalDialogViews::CloseAppModalDialog() {
80  GetWidget()->Close();
81}
82
83void JavaScriptAppModalDialogViews::AcceptAppModalDialog() {
84  GetDialogClientView()->AcceptWindow();
85}
86
87void JavaScriptAppModalDialogViews::CancelAppModalDialog() {
88  GetDialogClientView()->CancelWindow();
89}
90
91//////////////////////////////////////////////////////////////////////////////
92// JavaScriptAppModalDialogViews, views::DialogDelegate implementation:
93
94int JavaScriptAppModalDialogViews::GetDefaultDialogButton() const {
95  return ui::DIALOG_BUTTON_OK;
96}
97
98int JavaScriptAppModalDialogViews::GetDialogButtons() const {
99  if (parent_->javascript_message_type() ==
100          content::JAVASCRIPT_MESSAGE_TYPE_ALERT)
101    return ui::DIALOG_BUTTON_OK;
102
103  return ui::DIALOG_BUTTON_OK | ui::DIALOG_BUTTON_CANCEL;
104}
105
106base::string16 JavaScriptAppModalDialogViews::GetWindowTitle() const {
107  return parent_->title();
108}
109
110void JavaScriptAppModalDialogViews::WindowClosing() {
111#if defined(USE_X11) && !defined(OS_CHROMEOS)
112  event_blocker_x11_.reset();
113#endif
114}
115
116void JavaScriptAppModalDialogViews::DeleteDelegate() {
117  delete this;
118}
119
120bool JavaScriptAppModalDialogViews::Cancel() {
121  parent_->OnCancel(message_box_view_->IsCheckBoxSelected());
122  return true;
123}
124
125bool JavaScriptAppModalDialogViews::Accept() {
126  parent_->OnAccept(message_box_view_->GetInputText(),
127                    message_box_view_->IsCheckBoxSelected());
128  return true;
129}
130
131void JavaScriptAppModalDialogViews::OnClosed() {
132  parent_->OnClose();
133}
134
135views::Widget* JavaScriptAppModalDialogViews::GetWidget() {
136  return message_box_view_->GetWidget();
137}
138
139const views::Widget* JavaScriptAppModalDialogViews::GetWidget() const {
140  return message_box_view_->GetWidget();
141}
142
143base::string16 JavaScriptAppModalDialogViews::GetDialogButtonLabel(
144    ui::DialogButton button) const {
145  if (parent_->is_before_unload_dialog()) {
146    if (button == ui::DIALOG_BUTTON_OK) {
147      return l10n_util::GetStringUTF16(
148          parent_->is_reload() ?
149          IDS_BEFORERELOAD_MESSAGEBOX_OK_BUTTON_LABEL :
150          IDS_BEFOREUNLOAD_MESSAGEBOX_OK_BUTTON_LABEL);
151    } else if (button == ui::DIALOG_BUTTON_CANCEL) {
152      return l10n_util::GetStringUTF16(
153          parent_->is_reload() ?
154          IDS_BEFORERELOAD_MESSAGEBOX_CANCEL_BUTTON_LABEL :
155          IDS_BEFOREUNLOAD_MESSAGEBOX_CANCEL_BUTTON_LABEL);
156    }
157  }
158  return DialogDelegate::GetDialogButtonLabel(button);
159}
160
161///////////////////////////////////////////////////////////////////////////////
162// JavaScriptAppModalDialogViews, views::WidgetDelegate implementation:
163
164ui::ModalType JavaScriptAppModalDialogViews::GetModalType() const {
165  return ui::MODAL_TYPE_SYSTEM;
166}
167
168views::View* JavaScriptAppModalDialogViews::GetContentsView() {
169  return message_box_view_;
170}
171
172views::View* JavaScriptAppModalDialogViews::GetInitiallyFocusedView() {
173  if (message_box_view_->text_box())
174    return message_box_view_->text_box();
175  return views::DialogDelegate::GetInitiallyFocusedView();
176}
177
178////////////////////////////////////////////////////////////////////////////////
179// NativeAppModalDialog, public:
180
181// static
182NativeAppModalDialog* NativeAppModalDialog::CreateNativeJavaScriptPrompt(
183    JavaScriptAppModalDialog* dialog,
184    gfx::NativeWindow parent_window) {
185  JavaScriptAppModalDialogViews* d = new JavaScriptAppModalDialogViews(dialog);
186  CreateBrowserModalDialogViews(d, parent_window);
187  return d;
188}
189