blob: da98e43382b3282a5b4b7a1f5cbda6d1c1f6b2b0 [file] [log] [blame]
Torne (Richard Coles)58218062012-11-14 11:43:16 +00001// 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/webui/constrained_web_dialog_delegate_base.h"
6
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +01007#include "base/strings/utf_string_conversions.h"
Torne (Richard Coles)58218062012-11-14 11:43:16 +00008#include "chrome/browser/ui/views/constrained_window_views.h"
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +01009#include "components/web_modal/web_contents_modal_dialog_manager.h"
10#include "components/web_modal/web_contents_modal_dialog_manager_delegate.h"
Torne (Richard Coles)58218062012-11-14 11:43:16 +000011#include "content/public/browser/native_web_keyboard_event.h"
12#include "content/public/browser/web_contents.h"
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000013#include "content/public/browser/web_contents_view.h"
Torne (Richard Coles)58218062012-11-14 11:43:16 +000014#include "ui/gfx/size.h"
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +010015#include "ui/views/controls/webview/unhandled_keyboard_event_handler.h"
Torne (Richard Coles)58218062012-11-14 11:43:16 +000016#include "ui/views/controls/webview/webview.h"
17#include "ui/views/view.h"
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000018#include "ui/views/widget/widget.h"
Torne (Richard Coles)58218062012-11-14 11:43:16 +000019#include "ui/views/widget/widget_delegate.h"
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +010020#include "ui/views/window/dialog_delegate.h"
Torne (Richard Coles)58218062012-11-14 11:43:16 +000021#include "ui/web_dialogs/web_dialog_delegate.h"
22#include "ui/web_dialogs/web_dialog_ui.h"
23
24using content::WebContents;
25using ui::WebDialogDelegate;
26using ui::WebDialogWebContentsDelegate;
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +010027using web_modal::NativeWebContentsModalDialog;
28using web_modal::WebContentsModalDialogManager;
Torne (Richard Coles)58218062012-11-14 11:43:16 +000029
30namespace {
31
32class ConstrainedWebDialogDelegateViews
33 : public ConstrainedWebDialogDelegateBase {
34 public:
35 ConstrainedWebDialogDelegateViews(
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000036 content::BrowserContext* browser_context,
Torne (Richard Coles)58218062012-11-14 11:43:16 +000037 WebDialogDelegate* delegate,
38 WebDialogWebContentsDelegate* tab_delegate,
39 views::WebView* view)
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000040 : ConstrainedWebDialogDelegateBase(
41 browser_context, delegate, tab_delegate),
Ben Murdochbb1529c2013-08-08 10:24:53 +010042 view_(view),
43 window_(NULL) {}
Torne (Richard Coles)58218062012-11-14 11:43:16 +000044
45 virtual ~ConstrainedWebDialogDelegateViews() {}
46
47 // WebDialogWebContentsDelegate interface.
48 virtual void CloseContents(WebContents* source) OVERRIDE {
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000049 window_->Close();
Torne (Richard Coles)58218062012-11-14 11:43:16 +000050 }
51
52 // contents::WebContentsDelegate
53 virtual void HandleKeyboardEvent(
54 content::WebContents* source,
55 const content::NativeWebKeyboardEvent& event) OVERRIDE {
56 unhandled_keyboard_event_handler_.HandleKeyboardEvent(
57 event, view_->GetFocusManager());
58 }
59
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000060 // ConstrainedWebDialogDelegate
61 virtual NativeWebContentsModalDialog GetNativeDialog() OVERRIDE {
62 return window_->GetNativeView();
63 }
64
65 void set_window(views::Widget* window) { window_ = window; }
66 views::Widget* window() const { return window_; }
67
Torne (Richard Coles)58218062012-11-14 11:43:16 +000068 private:
69 // Converts keyboard events on the WebContents to accelerators.
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +010070 views::UnhandledKeyboardEventHandler unhandled_keyboard_event_handler_;
Torne (Richard Coles)58218062012-11-14 11:43:16 +000071
72 views::WebView* view_;
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000073 views::Widget* window_;
Torne (Richard Coles)58218062012-11-14 11:43:16 +000074
75 DISALLOW_COPY_AND_ASSIGN(ConstrainedWebDialogDelegateViews);
76};
77
78} // namespace
79
80class ConstrainedWebDialogDelegateViewViews
81 : public views::WebView,
82 public ConstrainedWebDialogDelegate,
83 public views::WidgetDelegate {
84 public:
85 ConstrainedWebDialogDelegateViewViews(
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000086 content::BrowserContext* browser_context,
Torne (Richard Coles)58218062012-11-14 11:43:16 +000087 WebDialogDelegate* delegate,
88 WebDialogWebContentsDelegate* tab_delegate);
89 virtual ~ConstrainedWebDialogDelegateViewViews();
90
Torne (Richard Coles)58218062012-11-14 11:43:16 +000091 // ConstrainedWebDialogDelegate interface
92 virtual const WebDialogDelegate*
93 GetWebDialogDelegate() const OVERRIDE {
94 return impl_->GetWebDialogDelegate();
95 }
96 virtual WebDialogDelegate* GetWebDialogDelegate() OVERRIDE {
97 return impl_->GetWebDialogDelegate();
98 }
99 virtual void OnDialogCloseFromWebUI() OVERRIDE {
100 return impl_->OnDialogCloseFromWebUI();
101 }
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000102 virtual void ReleaseWebContentsOnDialogClose() OVERRIDE {
103 return impl_->ReleaseWebContentsOnDialogClose();
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000104 }
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000105 virtual NativeWebContentsModalDialog GetNativeDialog() OVERRIDE {
106 return impl_->window()->GetNativeView();
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000107 }
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000108 virtual WebContents* GetWebContents() OVERRIDE {
109 return impl_->GetWebContents();
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000110 }
111
112 // views::WidgetDelegate interface.
113 virtual views::View* GetInitiallyFocusedView() OVERRIDE {
114 return this;
115 }
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000116 virtual void WindowClosing() OVERRIDE {
117 if (!impl_->closed_via_webui())
118 GetWebDialogDelegate()->OnDialogClosed(std::string());
119 }
120 virtual views::Widget* GetWidget() OVERRIDE {
121 return View::GetWidget();
122 }
123 virtual const views::Widget* GetWidget() const OVERRIDE {
124 return View::GetWidget();
125 }
126 virtual string16 GetWindowTitle() const OVERRIDE {
127 return impl_->closed_via_webui() ? string16() :
128 GetWebDialogDelegate()->GetDialogTitle();
129 }
130 virtual views::View* GetContentsView() OVERRIDE {
131 return this;
132 }
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000133 // TODO(wittman): Remove this override once we move to the new style frame
134 // view on all dialogs.
135 virtual views::NonClientFrameView* CreateNonClientFrameView(
136 views::Widget* widget) OVERRIDE {
137 return CreateConstrainedStyleNonClientFrameView(
138 widget,
139 GetWebContents()->GetBrowserContext());
140 }
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +0100141 virtual bool ShouldShowCloseButton() const OVERRIDE {
142 // No close button if the dialog doesn't want a title bar.
143 return impl_->GetWebDialogDelegate()->ShouldShowDialogTitle();
144 }
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000145
146 virtual ui::ModalType GetModalType() const OVERRIDE {
147#if defined(USE_ASH)
148 return ui::MODAL_TYPE_CHILD;
149#else
150 return views::WidgetDelegate::GetModalType();
151#endif
152 }
153
154 virtual void OnWidgetMove() OVERRIDE {
155 // We need to check the existence of the widget because when running on
156 // WinXP this could get executed before the widget is entirely created.
157 if (!GetWidget())
158 return;
159
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +0100160 if (!views::DialogDelegate::UseNewStyle()) {
161 GetWidget()->CenterWindow(
162 GetWidget()->non_client_view()->GetPreferredSize());
163 }
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000164 views::WidgetDelegate::OnWidgetMove();
165 }
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000166
167 // views::WebView overrides.
168 virtual bool AcceleratorPressed(
169 const ui::Accelerator& accelerator) OVERRIDE {
170 // Pressing ESC closes the dialog.
171 DCHECK_EQ(ui::VKEY_ESCAPE, accelerator.key_code());
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000172 impl_->window()->Close();
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000173 return true;
174 }
175 virtual gfx::Size GetPreferredSize() OVERRIDE {
176 gfx::Size size;
177 if (!impl_->closed_via_webui())
178 GetWebDialogDelegate()->GetDialogSize(&size);
179 return size;
180 }
181 virtual gfx::Size GetMinimumSize() OVERRIDE {
182 // Return an empty size so that we can be made smaller.
183 return gfx::Size();
184 }
185
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000186 void SetWindow(views::Widget* window) {
187 impl_->set_window(window);
188 }
189
190 views::Widget* GetWindow() {
191 return impl_->window();
192 }
193
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100194 private:
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000195 scoped_ptr<ConstrainedWebDialogDelegateViews> impl_;
196
197 DISALLOW_COPY_AND_ASSIGN(ConstrainedWebDialogDelegateViewViews);
198};
199
200ConstrainedWebDialogDelegateViewViews::ConstrainedWebDialogDelegateViewViews(
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000201 content::BrowserContext* browser_context,
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000202 WebDialogDelegate* delegate,
203 WebDialogWebContentsDelegate* tab_delegate)
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000204 : views::WebView(browser_context),
205 impl_(new ConstrainedWebDialogDelegateViews(browser_context,
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000206 delegate,
207 tab_delegate,
208 this)) {
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000209 SetWebContents(GetWebContents());
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000210
211 // Pressing ESC closes the dialog.
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000212 AddAccelerator(ui::Accelerator(ui::VKEY_ESCAPE, ui::EF_NONE));
213}
214
215ConstrainedWebDialogDelegateViewViews::~ConstrainedWebDialogDelegateViewViews() {
216}
217
218ConstrainedWebDialogDelegate* CreateConstrainedWebDialog(
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000219 content::BrowserContext* browser_context,
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000220 WebDialogDelegate* delegate,
221 WebDialogWebContentsDelegate* tab_delegate,
222 content::WebContents* web_contents) {
223 ConstrainedWebDialogDelegateViewViews* constrained_delegate =
224 new ConstrainedWebDialogDelegateViewViews(
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000225 browser_context, delegate, tab_delegate);
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000226 WebContentsModalDialogManager* web_contents_modal_dialog_manager =
227 WebContentsModalDialogManager::FromWebContents(web_contents);
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100228 views::Widget* window = CreateWebContentsModalDialogViews(
229 constrained_delegate,
230 web_contents->GetView()->GetNativeView(),
231 web_contents_modal_dialog_manager->delegate()->
232 GetWebContentsModalDialogHost());
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000233 web_contents_modal_dialog_manager->ShowDialog(window->GetNativeView());
234 constrained_delegate->SetWindow(window);
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000235 return constrained_delegate;
236}