1 // Copyright (c) 2011 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 "chrome/browser/ui/browser_dialogs.h"
10 #include "chrome/browser/ui/views/window.h"
11 #include "content/browser/tab_contents/tab_contents.h"
12 #include "content/common/native_web_keyboard_event.h"
13 #include "ui/base/keycodes/keyboard_codes.h"
14 #include "views/events/event.h"
15 #include "views/widget/root_view.h"
16 #include "views/widget/widget.h"
17 #include "views/window/window.h"
18
19 #if defined(OS_LINUX)
20 #include "views/window/window_gtk.h"
21 #endif
22
23 namespace browser {
24
25 // Declared in browser_dialogs.h so that others don't need to depend on our .h.
ShowHtmlDialog(gfx::NativeWindow parent,Profile * profile,HtmlDialogUIDelegate * delegate)26 gfx::NativeWindow ShowHtmlDialog(gfx::NativeWindow parent, Profile* profile,
27 HtmlDialogUIDelegate* delegate) {
28 HtmlDialogView* html_view =
29 new HtmlDialogView(profile, delegate);
30 browser::CreateViewsWindow(parent, gfx::Rect(), html_view);
31 html_view->InitDialog();
32 html_view->window()->Show();
33 return html_view->window()->GetNativeWindow();
34 }
35
36 } // namespace browser
37
38 ////////////////////////////////////////////////////////////////////////////////
39 // HtmlDialogView, public:
40
HtmlDialogView(Profile * profile,HtmlDialogUIDelegate * delegate)41 HtmlDialogView::HtmlDialogView(Profile* profile,
42 HtmlDialogUIDelegate* delegate)
43 : DOMView(),
44 HtmlDialogTabContentsDelegate(profile),
45 delegate_(delegate) {
46 }
47
~HtmlDialogView()48 HtmlDialogView::~HtmlDialogView() {
49 }
50
51 ////////////////////////////////////////////////////////////////////////////////
52 // HtmlDialogView, views::View implementation:
53
GetPreferredSize()54 gfx::Size HtmlDialogView::GetPreferredSize() {
55 gfx::Size out;
56 if (delegate_)
57 delegate_->GetDialogSize(&out);
58 return out;
59 }
60
AcceleratorPressed(const views::Accelerator & accelerator)61 bool HtmlDialogView::AcceleratorPressed(const views::Accelerator& accelerator) {
62 // Pressing ESC closes the dialog.
63 DCHECK_EQ(ui::VKEY_ESCAPE, accelerator.GetKeyCode());
64 OnWindowClosed();
65 OnDialogClosed(std::string());
66 return true;
67 }
68
69 ////////////////////////////////////////////////////////////////////////////////
70 // HtmlDialogView, views::WindowDelegate implementation:
71
CanResize() const72 bool HtmlDialogView::CanResize() const {
73 return true;
74 }
75
IsModal() const76 bool HtmlDialogView::IsModal() const {
77 if (delegate_)
78 return delegate_->IsDialogModal();
79 return false;
80 }
81
GetWindowTitle() const82 std::wstring HtmlDialogView::GetWindowTitle() const {
83 if (delegate_)
84 return delegate_->GetDialogTitle();
85 return std::wstring();
86 }
87
WindowClosing()88 void HtmlDialogView::WindowClosing() {
89 // If we still have a delegate that means we haven't notified it of the
90 // dialog closing. This happens if the user clicks the Close button on the
91 // dialog.
92 if (delegate_) {
93 OnWindowClosed();
94 OnDialogClosed("");
95 }
96 }
97
GetContentsView()98 views::View* HtmlDialogView::GetContentsView() {
99 return this;
100 }
101
GetInitiallyFocusedView()102 views::View* HtmlDialogView::GetInitiallyFocusedView() {
103 return this;
104 }
105
ShouldShowWindowTitle() const106 bool HtmlDialogView::ShouldShowWindowTitle() const {
107 return ShouldShowDialogTitle();
108 }
109
110 ////////////////////////////////////////////////////////////////////////////////
111 // HtmlDialogUIDelegate implementation:
112
IsDialogModal() const113 bool HtmlDialogView::IsDialogModal() const {
114 return IsModal();
115 }
116
GetDialogTitle() const117 std::wstring HtmlDialogView::GetDialogTitle() const {
118 return GetWindowTitle();
119 }
120
GetDialogContentURL() const121 GURL HtmlDialogView::GetDialogContentURL() const {
122 if (delegate_)
123 return delegate_->GetDialogContentURL();
124 return GURL();
125 }
126
GetWebUIMessageHandlers(std::vector<WebUIMessageHandler * > * handlers) const127 void HtmlDialogView::GetWebUIMessageHandlers(
128 std::vector<WebUIMessageHandler*>* handlers) const {
129 if (delegate_)
130 delegate_->GetWebUIMessageHandlers(handlers);
131 }
132
GetDialogSize(gfx::Size * size) const133 void HtmlDialogView::GetDialogSize(gfx::Size* size) const {
134 if (delegate_)
135 delegate_->GetDialogSize(size);
136 }
137
GetDialogArgs() const138 std::string HtmlDialogView::GetDialogArgs() const {
139 if (delegate_)
140 return delegate_->GetDialogArgs();
141 return std::string();
142 }
143
OnDialogClosed(const std::string & json_retval)144 void HtmlDialogView::OnDialogClosed(const std::string& json_retval) {
145 HtmlDialogTabContentsDelegate::Detach();
146 if (delegate_) {
147 HtmlDialogUIDelegate* dialog_delegate = delegate_;
148 delegate_ = NULL; // We will not communicate further with the delegate.
149 dialog_delegate->OnDialogClosed(json_retval);
150 }
151 window()->CloseWindow();
152 }
153
OnWindowClosed()154 void HtmlDialogView::OnWindowClosed() {
155 if (delegate_)
156 delegate_->OnWindowClosed();
157 }
158
OnCloseContents(TabContents * source,bool * out_close_dialog)159 void HtmlDialogView::OnCloseContents(TabContents* source,
160 bool* out_close_dialog) {
161 if (delegate_)
162 delegate_->OnCloseContents(source, out_close_dialog);
163 }
164
ShouldShowDialogTitle() const165 bool HtmlDialogView::ShouldShowDialogTitle() const {
166 if (delegate_)
167 return delegate_->ShouldShowDialogTitle();
168 return true;
169 }
170
HandleContextMenu(const ContextMenuParams & params)171 bool HtmlDialogView::HandleContextMenu(const ContextMenuParams& params) {
172 if (delegate_)
173 return delegate_->HandleContextMenu(params);
174 return HtmlDialogTabContentsDelegate::HandleContextMenu(params);
175 }
176
177 ////////////////////////////////////////////////////////////////////////////////
178 // TabContentsDelegate implementation:
179
MoveContents(TabContents * source,const gfx::Rect & pos)180 void HtmlDialogView::MoveContents(TabContents* source, const gfx::Rect& pos) {
181 // The contained web page wishes to resize itself. We let it do this because
182 // if it's a dialog we know about, we trust it not to be mean to the user.
183 GetWidget()->SetBounds(pos);
184 }
185
186 // A simplified version of BrowserView::HandleKeyboardEvent().
187 // We don't handle global keyboard shortcuts here, but that's fine since
188 // they're all browser-specific. (This may change in the future.)
HandleKeyboardEvent(const NativeWebKeyboardEvent & event)189 void HtmlDialogView::HandleKeyboardEvent(const NativeWebKeyboardEvent& event) {
190 #if defined(OS_WIN)
191 // Any unhandled keyboard/character messages should be defproced.
192 // This allows stuff like F10, etc to work correctly.
193 DefWindowProc(event.os_event.hwnd, event.os_event.message,
194 event.os_event.wParam, event.os_event.lParam);
195 #elif defined(OS_LINUX)
196 views::WindowGtk* window_gtk = static_cast<views::WindowGtk*>(window());
197 if (event.os_event && !event.skip_in_browser) {
198 views::KeyEvent views_event(reinterpret_cast<GdkEvent*>(event.os_event));
199 window_gtk->HandleKeyboardEvent(views_event);
200 }
201 #endif
202 }
203
CloseContents(TabContents * source)204 void HtmlDialogView::CloseContents(TabContents* source) {
205 bool close_dialog = false;
206 OnCloseContents(source, &close_dialog);
207 if (close_dialog)
208 OnDialogClosed(std::string());
209 }
210
211 ////////////////////////////////////////////////////////////////////////////////
212 // HtmlDialogView:
213
InitDialog()214 void HtmlDialogView::InitDialog() {
215 // Now Init the DOMView. This view runs in its own process to render the html.
216 DOMView::Init(profile(), NULL);
217
218 tab_contents_->set_delegate(this);
219
220 // Set the delegate. This must be done before loading the page. See
221 // the comment above HtmlDialogUI in its header file for why.
222 HtmlDialogUI::GetPropertyAccessor().SetProperty(tab_contents_->property_bag(),
223 this);
224
225 // Pressing the ESC key will close the dialog.
226 AddAccelerator(views::Accelerator(ui::VKEY_ESCAPE, false, false, false));
227
228 DOMView::LoadURL(GetDialogContentURL());
229 }
230