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