15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/views/javascript_app_modal_dialog_views.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/app_modal_dialogs/javascript_app_modal_dialog.h"
97d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "chrome/browser/ui/views/constrained_window_views.h"
106e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "chrome/grit/generated_resources.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/l10n/l10n_util.h"
12d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "ui/events/keycodes/keyboard_codes.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/controls/message_box_view.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/controls/textfield/textfield.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/widget/widget.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/window/dialog_client_view.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#if defined(USE_X11) && !defined(OS_CHROMEOS)
19e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "chrome/browser/ui/views/javascript_app_modal_event_blocker_x11.h"
20e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#endif
21e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// JavaScriptAppModalDialogViews, public:
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)JavaScriptAppModalDialogViews::JavaScriptAppModalDialogViews(
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    JavaScriptAppModalDialog* parent)
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : parent_(parent) {
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int options = views::MessageBoxView::DETECT_DIRECTIONALITY;
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (parent->javascript_message_type() ==
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          content::JAVASCRIPT_MESSAGE_TYPE_PROMPT)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    options |= views::MessageBoxView::HAS_PROMPT_FIELD;
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  views::MessageBoxView::InitParams params(parent->message_text());
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.options = options;
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.default_prompt = parent->default_prompt_text();
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  message_box_view_ = new views::MessageBoxView(params);
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(message_box_view_);
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  message_box_view_->AddAccelerator(
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ui::Accelerator(ui::VKEY_C, ui::EF_CONTROL_DOWN));
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (parent->display_suppress_checkbox()) {
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    message_box_view_->SetCheckBoxLabel(
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        l10n_util::GetStringUTF16(IDS_JAVASCRIPT_MESSAGEBOX_SUPPRESS_OPTION));
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)JavaScriptAppModalDialogViews::~JavaScriptAppModalDialogViews() {
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// JavaScriptAppModalDialogViews, NativeAppModalDialog implementation:
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int JavaScriptAppModalDialogViews::GetAppModalDialogButtons() const {
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return GetDialogButtons();
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void JavaScriptAppModalDialogViews::ShowAppModalDialog() {
58e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#if defined(USE_X11) && !defined(OS_CHROMEOS)
59e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  // BrowserView::CanActivate() ensures that other browser windows cannot be
60e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  // activated for long while the dialog is visible. Block events to other
61e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  // browser windows so that the user cannot interact with other browser windows
62e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  // in the short time that the other browser windows are active. This hack is
63e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  // unnecessary on Windows and Chrome OS.
64e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  // TODO(pkotwicz): Find a better way of doing this and remove this hack.
65e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  if (!event_blocker_x11_.get()) {
66e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    event_blocker_x11_.reset(
67e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch        new JavascriptAppModalEventBlockerX11(GetWidget()->GetNativeView()));
68e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  }
69e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#endif
70e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetWidget()->Show();
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void JavaScriptAppModalDialogViews::ActivateAppModalDialog() {
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetWidget()->Show();
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetWidget()->Activate();
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void JavaScriptAppModalDialogViews::CloseAppModalDialog() {
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetWidget()->Close();
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void JavaScriptAppModalDialogViews::AcceptAppModalDialog() {
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetDialogClientView()->AcceptWindow();
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void JavaScriptAppModalDialogViews::CancelAppModalDialog() {
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetDialogClientView()->CancelWindow();
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//////////////////////////////////////////////////////////////////////////////
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// JavaScriptAppModalDialogViews, views::DialogDelegate implementation:
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int JavaScriptAppModalDialogViews::GetDefaultDialogButton() const {
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return ui::DIALOG_BUTTON_OK;
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int JavaScriptAppModalDialogViews::GetDialogButtons() const {
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (parent_->javascript_message_type() ==
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          content::JAVASCRIPT_MESSAGE_TYPE_ALERT)
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return ui::DIALOG_BUTTON_OK;
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return ui::DIALOG_BUTTON_OK | ui::DIALOG_BUTTON_CANCEL;
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::string16 JavaScriptAppModalDialogViews::GetWindowTitle() const {
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return parent_->title();
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void JavaScriptAppModalDialogViews::WindowClosing() {
111e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#if defined(USE_X11) && !defined(OS_CHROMEOS)
112e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  event_blocker_x11_.reset();
113e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#endif
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void JavaScriptAppModalDialogViews::DeleteDelegate() {
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delete this;
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool JavaScriptAppModalDialogViews::Cancel() {
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  parent_->OnCancel(message_box_view_->IsCheckBoxSelected());
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool JavaScriptAppModalDialogViews::Accept() {
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  parent_->OnAccept(message_box_view_->GetInputText(),
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    message_box_view_->IsCheckBoxSelected());
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
131a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void JavaScriptAppModalDialogViews::OnClosed() {
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  parent_->OnClose();
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)views::Widget* JavaScriptAppModalDialogViews::GetWidget() {
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return message_box_view_->GetWidget();
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const views::Widget* JavaScriptAppModalDialogViews::GetWidget() const {
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return message_box_view_->GetWidget();
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::string16 JavaScriptAppModalDialogViews::GetDialogButtonLabel(
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ui::DialogButton button) const {
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (parent_->is_before_unload_dialog()) {
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (button == ui::DIALOG_BUTTON_OK) {
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return l10n_util::GetStringUTF16(
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          parent_->is_reload() ?
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          IDS_BEFORERELOAD_MESSAGEBOX_OK_BUTTON_LABEL :
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          IDS_BEFOREUNLOAD_MESSAGEBOX_OK_BUTTON_LABEL);
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else if (button == ui::DIALOG_BUTTON_CANCEL) {
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return l10n_util::GetStringUTF16(
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          parent_->is_reload() ?
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          IDS_BEFORERELOAD_MESSAGEBOX_CANCEL_BUTTON_LABEL :
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          IDS_BEFOREUNLOAD_MESSAGEBOX_CANCEL_BUTTON_LABEL);
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return DialogDelegate::GetDialogButtonLabel(button);
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)///////////////////////////////////////////////////////////////////////////////
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// JavaScriptAppModalDialogViews, views::WidgetDelegate implementation:
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ui::ModalType JavaScriptAppModalDialogViews::GetModalType() const {
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return ui::MODAL_TYPE_SYSTEM;
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)views::View* JavaScriptAppModalDialogViews::GetContentsView() {
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return message_box_view_;
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)views::View* JavaScriptAppModalDialogViews::GetInitiallyFocusedView() {
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (message_box_view_->text_box())
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return message_box_view_->text_box();
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return views::DialogDelegate::GetInitiallyFocusedView();
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// NativeAppModalDialog, public:
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NativeAppModalDialog* NativeAppModalDialog::CreateNativeJavaScriptPrompt(
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    JavaScriptAppModalDialog* dialog,
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gfx::NativeWindow parent_window) {
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  JavaScriptAppModalDialogViews* d = new JavaScriptAppModalDialogViews(dialog);
1867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  CreateBrowserModalDialogViews(d, parent_window);
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return d;
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
189