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/webui/constrained_web_dialog_delegate_base.h" 6 7 #include "base/strings/utf_string_conversions.h" 8 #include "chrome/browser/ui/views/constrained_window_views.h" 9 #include "content/public/browser/native_web_keyboard_event.h" 10 #include "content/public/browser/web_contents.h" 11 #include "ui/views/controls/webview/unhandled_keyboard_event_handler.h" 12 #include "ui/views/controls/webview/webview.h" 13 #include "ui/views/widget/widget.h" 14 #include "ui/views/window/dialog_delegate.h" 15 #include "ui/web_dialogs/web_dialog_delegate.h" 16 #include "ui/web_dialogs/web_dialog_ui.h" 17 18 using ui::WebDialogDelegate; 19 using ui::WebDialogWebContentsDelegate; 20 21 namespace { 22 23 class ConstrainedWebDialogDelegateViews 24 : public ConstrainedWebDialogDelegateBase { 25 public: 26 ConstrainedWebDialogDelegateViews(content::BrowserContext* context, 27 WebDialogDelegate* delegate, 28 WebDialogWebContentsDelegate* tab_delegate, 29 views::WebView* view) 30 : ConstrainedWebDialogDelegateBase(context, delegate, tab_delegate), 31 view_(view) {} 32 33 virtual ~ConstrainedWebDialogDelegateViews() {} 34 35 // WebDialogWebContentsDelegate: 36 virtual void CloseContents(content::WebContents* source) OVERRIDE { 37 view_->GetWidget()->Close(); 38 } 39 40 // contents::WebContentsDelegate: 41 virtual void HandleKeyboardEvent( 42 content::WebContents* source, 43 const content::NativeWebKeyboardEvent& event) OVERRIDE { 44 unhandled_keyboard_event_handler_.HandleKeyboardEvent( 45 event, view_->GetFocusManager()); 46 } 47 48 // ConstrainedWebDialogDelegate: 49 virtual web_modal::NativeWebContentsModalDialog GetNativeDialog() OVERRIDE { 50 return view_->GetWidget()->GetNativeView(); 51 } 52 53 private: 54 // Converts keyboard events on the WebContents to accelerators. 55 views::UnhandledKeyboardEventHandler unhandled_keyboard_event_handler_; 56 57 views::WebView* view_; 58 59 DISALLOW_COPY_AND_ASSIGN(ConstrainedWebDialogDelegateViews); 60 }; 61 62 class ConstrainedWebDialogDelegateViewViews 63 : public views::WebView, 64 public ConstrainedWebDialogDelegate, 65 public views::WidgetDelegate { 66 public: 67 ConstrainedWebDialogDelegateViewViews( 68 content::BrowserContext* browser_context, 69 WebDialogDelegate* delegate, 70 WebDialogWebContentsDelegate* tab_delegate) 71 : views::WebView(browser_context), 72 impl_(new ConstrainedWebDialogDelegateViews(browser_context, delegate, 73 tab_delegate, this)) { 74 SetWebContents(GetWebContents()); 75 AddAccelerator(ui::Accelerator(ui::VKEY_ESCAPE, ui::EF_NONE)); 76 } 77 virtual ~ConstrainedWebDialogDelegateViewViews() {} 78 79 // ConstrainedWebDialogDelegate: 80 virtual const WebDialogDelegate* GetWebDialogDelegate() const OVERRIDE { 81 return impl_->GetWebDialogDelegate(); 82 } 83 virtual WebDialogDelegate* GetWebDialogDelegate() OVERRIDE { 84 return impl_->GetWebDialogDelegate(); 85 } 86 virtual void OnDialogCloseFromWebUI() OVERRIDE { 87 return impl_->OnDialogCloseFromWebUI(); 88 } 89 virtual void ReleaseWebContentsOnDialogClose() OVERRIDE { 90 return impl_->ReleaseWebContentsOnDialogClose(); 91 } 92 virtual web_modal::NativeWebContentsModalDialog GetNativeDialog() OVERRIDE { 93 return impl_->GetNativeDialog(); 94 } 95 virtual content::WebContents* GetWebContents() OVERRIDE { 96 return impl_->GetWebContents(); 97 } 98 99 // views::WidgetDelegate: 100 virtual views::View* GetInitiallyFocusedView() OVERRIDE { 101 return this; 102 } 103 virtual void WindowClosing() OVERRIDE { 104 if (!impl_->closed_via_webui()) 105 GetWebDialogDelegate()->OnDialogClosed(std::string()); 106 } 107 virtual views::Widget* GetWidget() OVERRIDE { 108 return View::GetWidget(); 109 } 110 virtual const views::Widget* GetWidget() const OVERRIDE { 111 return View::GetWidget(); 112 } 113 virtual base::string16 GetWindowTitle() const OVERRIDE { 114 return impl_->closed_via_webui() ? base::string16() : 115 GetWebDialogDelegate()->GetDialogTitle(); 116 } 117 virtual views::View* GetContentsView() OVERRIDE { 118 return this; 119 } 120 virtual views::NonClientFrameView* CreateNonClientFrameView( 121 views::Widget* widget) OVERRIDE { 122 return views::DialogDelegate::CreateDialogFrameView(widget); 123 } 124 virtual bool ShouldShowCloseButton() const OVERRIDE { 125 // No close button if the dialog doesn't want a title bar. 126 return impl_->GetWebDialogDelegate()->ShouldShowDialogTitle(); 127 } 128 virtual ui::ModalType GetModalType() const OVERRIDE { 129 return ui::MODAL_TYPE_CHILD; 130 } 131 132 // views::WebView: 133 virtual bool AcceleratorPressed(const ui::Accelerator& accelerator) OVERRIDE { 134 // Pressing ESC closes the dialog. 135 DCHECK_EQ(ui::VKEY_ESCAPE, accelerator.key_code()); 136 GetWidget()->Close(); 137 return true; 138 } 139 virtual gfx::Size GetPreferredSize() const OVERRIDE { 140 gfx::Size size; 141 if (!impl_->closed_via_webui()) 142 GetWebDialogDelegate()->GetDialogSize(&size); 143 return size; 144 } 145 virtual gfx::Size GetMinimumSize() const OVERRIDE { 146 // Return an empty size so that we can be made smaller. 147 return gfx::Size(); 148 } 149 150 private: 151 scoped_ptr<ConstrainedWebDialogDelegateViews> impl_; 152 153 DISALLOW_COPY_AND_ASSIGN(ConstrainedWebDialogDelegateViewViews); 154 }; 155 156 } // namespace 157 158 ConstrainedWebDialogDelegate* CreateConstrainedWebDialog( 159 content::BrowserContext* browser_context, 160 WebDialogDelegate* delegate, 161 WebDialogWebContentsDelegate* tab_delegate, 162 content::WebContents* web_contents) { 163 ConstrainedWebDialogDelegateViewViews* dialog = 164 new ConstrainedWebDialogDelegateViewViews( 165 browser_context, delegate, tab_delegate); 166 ShowWebModalDialogViews(dialog, web_contents); 167 return dialog; 168 } 169