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