Home | History | Annotate | Download | only in views
      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