1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140
|
// Copyright (c) 2012 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/ui/views/external_protocol_dialog.h"
#include "base/metrics/histogram.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/external_protocol/external_protocol_handler.h"
#include "chrome/browser/tab_contents/tab_util.h"
#include "chrome/browser/ui/external_protocol_dialog_delegate.h"
#include "chrome/grit/generated_resources.h"
#include "components/constrained_window/constrained_window_views.h"
#include "content/public/browser/web_contents.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/gfx/text_elider.h"
#include "ui/views/controls/message_box_view.h"
#include "ui/views/widget/widget.h"
using content::WebContents;
namespace {
const int kMessageWidth = 400;
} // namespace
///////////////////////////////////////////////////////////////////////////////
// ExternalProtocolHandler
// static
void ExternalProtocolHandler::RunExternalProtocolDialog(
const GURL& url, int render_process_host_id, int routing_id) {
scoped_ptr<ExternalProtocolDialogDelegate> delegate(
new ExternalProtocolDialogDelegate(url,
render_process_host_id,
routing_id));
if (delegate->program_name().empty()) {
// ShellExecute won't do anything. Don't bother warning the user.
return;
}
// Windowing system takes ownership.
new ExternalProtocolDialog(
delegate.Pass(), render_process_host_id, routing_id);
}
///////////////////////////////////////////////////////////////////////////////
// ExternalProtocolDialog
ExternalProtocolDialog::~ExternalProtocolDialog() {
}
//////////////////////////////////////////////////////////////////////////////
// ExternalProtocolDialog, views::DialogDelegate implementation:
int ExternalProtocolDialog::GetDefaultDialogButton() const {
return ui::DIALOG_BUTTON_CANCEL;
}
base::string16 ExternalProtocolDialog::GetDialogButtonLabel(
ui::DialogButton button) const {
if (button == ui::DIALOG_BUTTON_OK)
return l10n_util::GetStringUTF16(IDS_EXTERNAL_PROTOCOL_OK_BUTTON_TEXT);
else
return l10n_util::GetStringUTF16(IDS_EXTERNAL_PROTOCOL_CANCEL_BUTTON_TEXT);
}
base::string16 ExternalProtocolDialog::GetWindowTitle() const {
return delegate_->GetTitleText();
}
void ExternalProtocolDialog::DeleteDelegate() {
delete this;
}
bool ExternalProtocolDialog::Cancel() {
// We also get called back here if the user closes the dialog or presses
// escape. In these cases it would be preferable to ignore the state of the
// check box but MessageBox doesn't distinguish this from pressing the cancel
// button.
delegate_->DoCancel(delegate_->url(),
message_box_view_->IsCheckBoxSelected());
// Returning true closes the dialog.
return true;
}
bool ExternalProtocolDialog::Accept() {
// We record how long it takes the user to accept an external protocol. If
// users start accepting these dialogs too quickly, we should worry about
// clickjacking.
UMA_HISTOGRAM_LONG_TIMES("clickjacking.launch_url",
base::TimeTicks::Now() - creation_time_);
delegate_->DoAccept(delegate_->url(),
message_box_view_->IsCheckBoxSelected());
// Returning true closes the dialog.
return true;
}
views::View* ExternalProtocolDialog::GetContentsView() {
return message_box_view_;
}
views::Widget* ExternalProtocolDialog::GetWidget() {
return message_box_view_->GetWidget();
}
const views::Widget* ExternalProtocolDialog::GetWidget() const {
return message_box_view_->GetWidget();
}
///////////////////////////////////////////////////////////////////////////////
// ExternalProtocolDialog, private:
ExternalProtocolDialog::ExternalProtocolDialog(
scoped_ptr<const ProtocolDialogDelegate> delegate,
int render_process_host_id,
int routing_id)
: delegate_(delegate.Pass()),
render_process_host_id_(render_process_host_id),
routing_id_(routing_id),
creation_time_(base::TimeTicks::Now()) {
views::MessageBoxView::InitParams params(delegate_->GetMessageText());
params.message_width = kMessageWidth;
message_box_view_ = new views::MessageBoxView(params);
message_box_view_->SetCheckBoxLabel(delegate_->GetCheckboxText());
// Dialog is top level if we don't have a web_contents associated with us.
WebContents* web_contents = tab_util::GetWebContentsByID(
render_process_host_id_, routing_id_);
gfx::NativeWindow parent_window = NULL;
if (web_contents)
parent_window = web_contents->GetTopLevelNativeWindow();
constrained_window::CreateBrowserModalDialogViews(this,
parent_window)->Show();
}
|