OLD | NEW |
| (Empty) |
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/web_dialog_view.h" | |
6 | |
7 #include <vector> | |
8 | |
9 #include "base/property_bag.h" | |
10 #include "base/utf_string_conversions.h" | |
11 #include "content/public/browser/browser_context.h" | |
12 #include "content/public/browser/native_web_keyboard_event.h" | |
13 #include "content/public/browser/notification_details.h" | |
14 #include "content/public/browser/notification_source.h" | |
15 #include "content/public/browser/notification_types.h" | |
16 #include "content/public/browser/web_contents.h" | |
17 #include "ui/base/keycodes/keyboard_codes.h" | |
18 #include "ui/views/controls/webview/webview.h" | |
19 #include "ui/views/events/event.h" | |
20 #include "ui/views/layout/fill_layout.h" | |
21 #include "ui/views/widget/root_view.h" | |
22 #include "ui/views/widget/widget.h" | |
23 #include "ui/web_dialogs/web_dialog_delegate.h" | |
24 #include "ui/web_dialogs/web_dialog_ui.h" | |
25 | |
26 #if defined(USE_AURA) | |
27 #include "ui/aura/event.h" | |
28 #include "ui/views/widget/native_widget_aura.h" | |
29 #endif | |
30 | |
31 using content::NativeWebKeyboardEvent; | |
32 using content::WebContents; | |
33 using content::WebUIMessageHandler; | |
34 using ui::WebDialogDelegate; | |
35 using ui::WebDialogUI; | |
36 using ui::WebDialogWebContentsDelegate; | |
37 | |
38 //////////////////////////////////////////////////////////////////////////////// | |
39 // WebDialogView, public: | |
40 | |
41 WebDialogView::WebDialogView( | |
42 content::BrowserContext* context, | |
43 WebDialogDelegate* delegate, | |
44 WebContentsHandler* handler) | |
45 : ClientView(NULL, NULL), | |
46 WebDialogWebContentsDelegate(context, handler), | |
47 initialized_(false), | |
48 delegate_(delegate), | |
49 web_view_(new views::WebView(context)) { | |
50 web_view_->set_allow_accelerators(true); | |
51 AddChildView(web_view_); | |
52 set_contents_view(web_view_); | |
53 SetLayoutManager(new views::FillLayout); | |
54 // Pressing the ESC key will close the dialog. | |
55 AddAccelerator(ui::Accelerator(ui::VKEY_ESCAPE, ui::EF_NONE)); | |
56 } | |
57 | |
58 WebDialogView::~WebDialogView() { | |
59 } | |
60 | |
61 content::WebContents* WebDialogView::web_contents() { | |
62 return web_view_->web_contents(); | |
63 } | |
64 | |
65 //////////////////////////////////////////////////////////////////////////////// | |
66 // WebDialogView, views::View implementation: | |
67 | |
68 gfx::Size WebDialogView::GetPreferredSize() { | |
69 gfx::Size out; | |
70 if (delegate_) | |
71 delegate_->GetMinimumDialogSize(&out); | |
72 return out; | |
73 } | |
74 | |
75 bool WebDialogView::AcceleratorPressed(const ui::Accelerator& accelerator) { | |
76 // Pressing ESC closes the dialog. | |
77 DCHECK_EQ(ui::VKEY_ESCAPE, accelerator.key_code()); | |
78 OnDialogClosed(std::string()); | |
79 return true; | |
80 } | |
81 | |
82 void WebDialogView::ViewHierarchyChanged(bool is_add, | |
83 views::View* parent, | |
84 views::View* child) { | |
85 if (is_add && GetWidget()) | |
86 InitDialog(); | |
87 } | |
88 | |
89 bool WebDialogView::CanClose() { | |
90 bool close_dialog = true; | |
91 if (delegate_) | |
92 delegate_->OnCloseContents(web_view_->web_contents(), | |
93 &close_dialog); | |
94 | |
95 return close_dialog; | |
96 } | |
97 | |
98 //////////////////////////////////////////////////////////////////////////////// | |
99 // WebDialogView, views::WidgetDelegate implementation: | |
100 | |
101 bool WebDialogView::CanResize() const { | |
102 return true; | |
103 } | |
104 | |
105 ui::ModalType WebDialogView::GetModalType() const { | |
106 return GetDialogModalType(); | |
107 } | |
108 | |
109 string16 WebDialogView::GetWindowTitle() const { | |
110 if (delegate_) | |
111 return delegate_->GetDialogTitle(); | |
112 return string16(); | |
113 } | |
114 | |
115 std::string WebDialogView::GetWindowName() const { | |
116 if (delegate_) | |
117 return delegate_->GetDialogName(); | |
118 return std::string(); | |
119 } | |
120 | |
121 void WebDialogView::WindowClosing() { | |
122 // If we still have a delegate that means we haven't notified it of the | |
123 // dialog closing. This happens if the user clicks the Close button on the | |
124 // dialog. | |
125 if (delegate_) | |
126 OnDialogClosed(""); | |
127 } | |
128 | |
129 views::View* WebDialogView::GetContentsView() { | |
130 return this; | |
131 } | |
132 | |
133 views::ClientView* WebDialogView::CreateClientView(views::Widget* widget) { | |
134 return this; | |
135 } | |
136 | |
137 views::View* WebDialogView::GetInitiallyFocusedView() { | |
138 return web_view_; | |
139 } | |
140 | |
141 bool WebDialogView::ShouldShowWindowTitle() const { | |
142 return ShouldShowDialogTitle(); | |
143 } | |
144 | |
145 views::Widget* WebDialogView::GetWidget() { | |
146 return View::GetWidget(); | |
147 } | |
148 | |
149 const views::Widget* WebDialogView::GetWidget() const { | |
150 return View::GetWidget(); | |
151 } | |
152 | |
153 //////////////////////////////////////////////////////////////////////////////// | |
154 // WebDialogDelegate implementation: | |
155 | |
156 ui::ModalType WebDialogView::GetDialogModalType() const { | |
157 if (delegate_) | |
158 return delegate_->GetDialogModalType(); | |
159 return ui::MODAL_TYPE_NONE; | |
160 } | |
161 | |
162 string16 WebDialogView::GetDialogTitle() const { | |
163 return GetWindowTitle(); | |
164 } | |
165 | |
166 GURL WebDialogView::GetDialogContentURL() const { | |
167 if (delegate_) | |
168 return delegate_->GetDialogContentURL(); | |
169 return GURL(); | |
170 } | |
171 | |
172 void WebDialogView::GetWebUIMessageHandlers( | |
173 std::vector<WebUIMessageHandler*>* handlers) const { | |
174 if (delegate_) | |
175 delegate_->GetWebUIMessageHandlers(handlers); | |
176 } | |
177 | |
178 void WebDialogView::GetDialogSize(gfx::Size* size) const { | |
179 if (delegate_) | |
180 delegate_->GetDialogSize(size); | |
181 } | |
182 | |
183 void WebDialogView::GetMinimumDialogSize(gfx::Size* size) const { | |
184 if (delegate_) | |
185 delegate_->GetMinimumDialogSize(size); | |
186 } | |
187 | |
188 std::string WebDialogView::GetDialogArgs() const { | |
189 if (delegate_) | |
190 return delegate_->GetDialogArgs(); | |
191 return std::string(); | |
192 } | |
193 | |
194 void WebDialogView::OnDialogShown(content::WebUI* webui, | |
195 content::RenderViewHost* render_view_host) { | |
196 if (delegate_) | |
197 delegate_->OnDialogShown(webui, render_view_host); | |
198 } | |
199 | |
200 void WebDialogView::OnDialogClosed(const std::string& json_retval) { | |
201 Detach(); | |
202 if (delegate_) { | |
203 // Store the dialog content area size. | |
204 delegate_->StoreDialogSize(GetContentsBounds().size()); | |
205 } | |
206 | |
207 if (GetWidget()) | |
208 GetWidget()->Close(); | |
209 | |
210 if (delegate_) { | |
211 delegate_->OnDialogClosed(json_retval); | |
212 delegate_ = NULL; // We will not communicate further with the delegate. | |
213 } | |
214 } | |
215 | |
216 void WebDialogView::OnCloseContents(WebContents* source, | |
217 bool* out_close_dialog) { | |
218 if (delegate_) | |
219 delegate_->OnCloseContents(source, out_close_dialog); | |
220 } | |
221 | |
222 bool WebDialogView::ShouldShowDialogTitle() const { | |
223 if (delegate_) | |
224 return delegate_->ShouldShowDialogTitle(); | |
225 return true; | |
226 } | |
227 | |
228 bool WebDialogView::HandleContextMenu( | |
229 const content::ContextMenuParams& params) { | |
230 if (delegate_) | |
231 return delegate_->HandleContextMenu(params); | |
232 return WebDialogWebContentsDelegate::HandleContextMenu(params); | |
233 } | |
234 | |
235 //////////////////////////////////////////////////////////////////////////////// | |
236 // content::WebContentsDelegate implementation: | |
237 | |
238 void WebDialogView::MoveContents(WebContents* source, const gfx::Rect& pos) { | |
239 // The contained web page wishes to resize itself. We let it do this because | |
240 // if it's a dialog we know about, we trust it not to be mean to the user. | |
241 GetWidget()->SetBounds(pos); | |
242 } | |
243 | |
244 // A simplified version of BrowserView::HandleKeyboardEvent(). | |
245 // We don't handle global keyboard shortcuts here, but that's fine since | |
246 // they're all browser-specific. (This may change in the future.) | |
247 void WebDialogView::HandleKeyboardEvent(const NativeWebKeyboardEvent& event) { | |
248 #if defined(USE_AURA) | |
249 aura::KeyEvent aura_event(event.os_event->native_event(), false); | |
250 views::NativeWidgetAura* aura_widget = | |
251 static_cast<views::NativeWidgetAura*>(GetWidget()->native_widget()); | |
252 aura_widget->OnKeyEvent(&aura_event); | |
253 #elif defined(OS_WIN) | |
254 // Any unhandled keyboard/character messages should be defproced. | |
255 // This allows stuff like F10, etc to work correctly. | |
256 DefWindowProc(event.os_event.hwnd, event.os_event.message, | |
257 event.os_event.wParam, event.os_event.lParam); | |
258 #endif | |
259 } | |
260 | |
261 void WebDialogView::CloseContents(WebContents* source) { | |
262 bool close_dialog = false; | |
263 OnCloseContents(source, &close_dialog); | |
264 if (close_dialog) | |
265 OnDialogClosed(std::string()); | |
266 } | |
267 | |
268 content::WebContents* WebDialogView::OpenURLFromTab( | |
269 content::WebContents* source, | |
270 const content::OpenURLParams& params) { | |
271 content::WebContents* new_contents = NULL; | |
272 if (delegate_ && | |
273 delegate_->HandleOpenURLFromTab(source, params, &new_contents)) { | |
274 return new_contents; | |
275 } | |
276 return WebDialogWebContentsDelegate::OpenURLFromTab(source, params); | |
277 } | |
278 | |
279 void WebDialogView::AddNewContents(content::WebContents* source, | |
280 content::WebContents* new_contents, | |
281 WindowOpenDisposition disposition, | |
282 const gfx::Rect& initial_pos, | |
283 bool user_gesture) { | |
284 if (delegate_ && delegate_->HandleAddNewContents( | |
285 source, new_contents, disposition, initial_pos, user_gesture)) { | |
286 return; | |
287 } | |
288 WebDialogWebContentsDelegate::AddNewContents( | |
289 source, new_contents, disposition, initial_pos, user_gesture); | |
290 } | |
291 | |
292 void WebDialogView::LoadingStateChanged(content::WebContents* source) { | |
293 if (delegate_) | |
294 delegate_->OnLoadingStateChanged(source); | |
295 } | |
296 | |
297 //////////////////////////////////////////////////////////////////////////////// | |
298 // WebDialogView, private: | |
299 | |
300 void WebDialogView::InitDialog() { | |
301 content::WebContents* web_contents = web_view_->GetWebContents(); | |
302 if (web_contents->GetDelegate() == this) | |
303 return; | |
304 | |
305 web_contents->SetDelegate(this); | |
306 | |
307 // Set the delegate. This must be done before loading the page. See | |
308 // the comment above WebDialogUI in its header file for why. | |
309 WebDialogUI::GetPropertyAccessor().SetProperty( | |
310 web_contents->GetPropertyBag(), this); | |
311 | |
312 if (delegate_) { | |
313 gfx::Size out; | |
314 delegate_->GetDialogSize(&out); | |
315 if (!out.IsEmpty() && GetWidget()) | |
316 GetWidget()->CenterWindow(out); | |
317 } | |
318 | |
319 web_view_->LoadInitialURL(GetDialogContentURL()); | |
320 } | |
OLD | NEW |