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. 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 41 HtmlDialogView::HtmlDialogView(Profile* profile, 42 HtmlDialogUIDelegate* delegate) 43 : DOMView(), 44 HtmlDialogTabContentsDelegate(profile), 45 delegate_(delegate) { 46 } 47 48 HtmlDialogView::~HtmlDialogView() { 49 } 50 51 //////////////////////////////////////////////////////////////////////////////// 52 // HtmlDialogView, views::View implementation: 53 54 gfx::Size HtmlDialogView::GetPreferredSize() { 55 gfx::Size out; 56 if (delegate_) 57 delegate_->GetDialogSize(&out); 58 return out; 59 } 60 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 72 bool HtmlDialogView::CanResize() const { 73 return true; 74 } 75 76 bool HtmlDialogView::IsModal() const { 77 if (delegate_) 78 return delegate_->IsDialogModal(); 79 return false; 80 } 81 82 std::wstring HtmlDialogView::GetWindowTitle() const { 83 if (delegate_) 84 return delegate_->GetDialogTitle(); 85 return std::wstring(); 86 } 87 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 98 views::View* HtmlDialogView::GetContentsView() { 99 return this; 100 } 101 102 views::View* HtmlDialogView::GetInitiallyFocusedView() { 103 return this; 104 } 105 106 bool HtmlDialogView::ShouldShowWindowTitle() const { 107 return ShouldShowDialogTitle(); 108 } 109 110 //////////////////////////////////////////////////////////////////////////////// 111 // HtmlDialogUIDelegate implementation: 112 113 bool HtmlDialogView::IsDialogModal() const { 114 return IsModal(); 115 } 116 117 std::wstring HtmlDialogView::GetDialogTitle() const { 118 return GetWindowTitle(); 119 } 120 121 GURL HtmlDialogView::GetDialogContentURL() const { 122 if (delegate_) 123 return delegate_->GetDialogContentURL(); 124 return GURL(); 125 } 126 127 void HtmlDialogView::GetWebUIMessageHandlers( 128 std::vector<WebUIMessageHandler*>* handlers) const { 129 if (delegate_) 130 delegate_->GetWebUIMessageHandlers(handlers); 131 } 132 133 void HtmlDialogView::GetDialogSize(gfx::Size* size) const { 134 if (delegate_) 135 delegate_->GetDialogSize(size); 136 } 137 138 std::string HtmlDialogView::GetDialogArgs() const { 139 if (delegate_) 140 return delegate_->GetDialogArgs(); 141 return std::string(); 142 } 143 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 154 void HtmlDialogView::OnWindowClosed() { 155 if (delegate_) 156 delegate_->OnWindowClosed(); 157 } 158 159 void HtmlDialogView::OnCloseContents(TabContents* source, 160 bool* out_close_dialog) { 161 if (delegate_) 162 delegate_->OnCloseContents(source, out_close_dialog); 163 } 164 165 bool HtmlDialogView::ShouldShowDialogTitle() const { 166 if (delegate_) 167 return delegate_->ShouldShowDialogTitle(); 168 return true; 169 } 170 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 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.) 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 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 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