diff options
author | zork@chromium.org <zork@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-11-18 19:23:25 +0000 |
---|---|---|
committer | zork@chromium.org <zork@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-11-18 19:23:25 +0000 |
commit | 918c632d257d5c87f82265991d7b3ae84b8c391f (patch) | |
tree | eb5752a10bf1fb6bbd42a80a6acec092fd50799c /chrome/browser | |
parent | daa4b0db3fdaf5493490b7a249f6d0b809a1b1ac (diff) | |
download | chromium_src-918c632d257d5c87f82265991d7b3ae84b8c391f.zip chromium_src-918c632d257d5c87f82265991d7b3ae84b8c391f.tar.gz chromium_src-918c632d257d5c87f82265991d7b3ae84b8c391f.tar.bz2 |
Add support for ShowHtmlDialog() to Linux. This is modeled off the MacOS and Windows versions, except that it uses a gtk dialog and TabContentsContainerGtk to create the window.
BUG=25260
TEST=Call ShowHTMLDialog() with a working dialog, such as the login dialog for Bookmark sync.
Review URL: http://codereview.chromium.org/394011
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@32363 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser')
-rw-r--r-- | chrome/browser/gtk/browser_window_gtk.cc | 3 | ||||
-rw-r--r-- | chrome/browser/gtk/html_dialog_gtk.cc | 205 | ||||
-rw-r--r-- | chrome/browser/gtk/html_dialog_gtk.h | 89 | ||||
-rw-r--r-- | chrome/browser/tab_contents/tab_contents_view_gtk.cc | 7 |
4 files changed, 301 insertions, 3 deletions
diff --git a/chrome/browser/gtk/browser_window_gtk.cc b/chrome/browser/gtk/browser_window_gtk.cc index 9a2bb4c..c136c0c 100644 --- a/chrome/browser/gtk/browser_window_gtk.cc +++ b/chrome/browser/gtk/browser_window_gtk.cc @@ -51,6 +51,7 @@ #include "chrome/browser/gtk/gtk_floating_container.h" #include "chrome/browser/gtk/go_button_gtk.h" #include "chrome/browser/gtk/gtk_theme_provider.h" +#include "chrome/browser/gtk/html_dialog_gtk.h" #include "chrome/browser/gtk/import_dialog_gtk.h" #include "chrome/browser/gtk/info_bubble_gtk.h" #include "chrome/browser/gtk/infobar_container_gtk.h" @@ -1165,7 +1166,7 @@ void BrowserWindowGtk::ShowThemeInstallBubble() { void BrowserWindowGtk::ShowHTMLDialog(HtmlDialogUIDelegate* delegate, gfx::NativeWindow parent_window) { - NOTIMPLEMENTED(); + HtmlDialogGtk::ShowHtmlDialogGtk(browser_.get(), delegate); } void BrowserWindowGtk::UserChangedTheme() { diff --git a/chrome/browser/gtk/html_dialog_gtk.cc b/chrome/browser/gtk/html_dialog_gtk.cc new file mode 100644 index 0000000..5eca0ec --- /dev/null +++ b/chrome/browser/gtk/html_dialog_gtk.cc @@ -0,0 +1,205 @@ +// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/gtk/html_dialog_gtk.h" + +#include <gtk/gtk.h> + +#include "chrome/browser/browser_window.h" +#include "chrome/browser/dom_ui/html_dialog_ui.h" +#include "chrome/browser/gtk/tab_contents_container_gtk.h" +#include "chrome/browser/tab_contents/tab_contents.h" +#include "chrome/common/gtk_util.h" + +// static +void HtmlDialogGtk::ShowHtmlDialogGtk(Browser* browser, + HtmlDialogUIDelegate* delegate) { + HtmlDialogGtk* html_dialog = new HtmlDialogGtk(browser, delegate); + html_dialog->InitDialog(); +} + +//////////////////////////////////////////////////////////////////////////////// +// HtmlDialogGtk, public: + +HtmlDialogGtk::HtmlDialogGtk(Browser* parent_browser, + HtmlDialogUIDelegate* delegate) + : parent_browser_(parent_browser), + delegate_(delegate), + dialog_(NULL) { +} + +HtmlDialogGtk::~HtmlDialogGtk() { +} + +//////////////////////////////////////////////////////////////////////////////// +// HtmlDialogUIDelegate implementation: + +bool HtmlDialogGtk::IsDialogModal() const { + return delegate_ ? delegate_->IsDialogModal() : false; +} + +std::wstring HtmlDialogGtk::GetDialogTitle() const { + return delegate_ ? delegate_->GetDialogTitle() : L""; +} + +GURL HtmlDialogGtk::GetDialogContentURL() const { + if (delegate_) + return delegate_->GetDialogContentURL(); + else + return GURL(); +} + +void HtmlDialogGtk::GetDOMMessageHandlers( + std::vector<DOMMessageHandler*>* handlers) const { + if (delegate_) + delegate_->GetDOMMessageHandlers(handlers); + else + handlers->clear(); +} + +void HtmlDialogGtk::GetDialogSize(gfx::Size* size) const { + if (delegate_) + delegate_->GetDialogSize(size); + else + *size = gfx::Size(); +} + +std::string HtmlDialogGtk::GetDialogArgs() const { + if (delegate_) + return delegate_->GetDialogArgs(); + else + return std::string(); +} + +void HtmlDialogGtk::OnDialogClosed(const std::string& json_retval) { + DCHECK(delegate_); + DCHECK(dialog_); + + HtmlDialogUIDelegate* dialog_delegate = delegate_; + delegate_ = NULL; // We will not communicate further with the delegate. + dialog_delegate->OnDialogClosed(json_retval); + gtk_widget_destroy(dialog_); + delete this; +} + +//////////////////////////////////////////////////////////////////////////////// +// TabContentsDelegate implementation: + +void HtmlDialogGtk::OpenURLFromTab(TabContents* source, + const GURL& url, + const GURL& referrer, + WindowOpenDisposition disposition, + PageTransition::Type transition) { + // Force all links to open in a new window, ignoring the incoming + // disposition. This is a tabless, modal dialog so we can't just + // open it in the current frame. + static_cast<TabContentsDelegate*>(parent_browser_)->OpenURLFromTab( + source, url, referrer, NEW_WINDOW, transition); +} + +void HtmlDialogGtk::NavigationStateChanged(const TabContents* source, + unsigned changed_flags) { + // We shouldn't receive any NavigationStateChanged except the first + // one, which we ignore because we're a dialog box. +} + +void HtmlDialogGtk::ReplaceContents(TabContents* source, + TabContents* new_contents) { +} + +void HtmlDialogGtk::AddNewContents(TabContents* source, + TabContents* new_contents, + WindowOpenDisposition disposition, + const gfx::Rect& initial_pos, + bool user_gesture) { + static_cast<TabContentsDelegate*>(parent_browser_)->AddNewContents( + source, new_contents, NEW_WINDOW, initial_pos, user_gesture); +} + +void HtmlDialogGtk::ActivateContents(TabContents* contents) { + // We don't do anything here because there's only one TabContents in + // this frame and we don't have a TabStripModel. +} + +void HtmlDialogGtk::LoadingStateChanged(TabContents* source) { + // We don't care about this notification. +} + +void HtmlDialogGtk::CloseContents(TabContents* source) { + // We receive this message but don't handle it because we really do the + // cleanup in OnDialogClosed(). +} + +void HtmlDialogGtk::MoveContents(TabContents* source, const gfx::Rect& pos) { + // The contained web page wishes to resize itself. We let it do this because + // if it's a dialog we know about, we trust it not to be mean to the user. +} + +bool HtmlDialogGtk::IsPopup(TabContents* source) { + // This needs to return true so that we are allowed to be resized by our + // contents. + return true; +} + +void HtmlDialogGtk::ToolbarSizeChanged(TabContents* source, + bool is_animating) { + // Ignored. +} + +void HtmlDialogGtk::URLStarredChanged(TabContents* source, bool starred) { + // We don't have a visible star to click in the window. + NOTREACHED(); +} + +void HtmlDialogGtk::UpdateTargetURL(TabContents* source, const GURL& url) { + // Ignored. +} + +//////////////////////////////////////////////////////////////////////////////// +// HtmlDialogGtk: + +void HtmlDialogGtk::InitDialog() { + Profile* profile = parent_browser_->profile(); + tab_contents_.reset(new TabContents(profile, NULL, MSG_ROUTING_NONE, NULL)); + tab_contents_->set_delegate(this); + + // This must be done before loading the page; see the comments in + // HtmlDialogUI. + HtmlDialogUI::GetPropertyAccessor().SetProperty(tab_contents_->property_bag(), + this); + + tab_contents_->controller().LoadURL(GetDialogContentURL(), + GURL(), PageTransition::START_PAGE); + GtkDialogFlags flags = GTK_DIALOG_NO_SEPARATOR; + if (delegate_->IsDialogModal()) + flags = static_cast<GtkDialogFlags>(flags | GTK_DIALOG_MODAL); + + dialog_ = gtk_dialog_new_with_buttons( + WideToUTF8(delegate_->GetDialogTitle()).c_str(), + parent_browser_->window()->GetNativeHandle(), + flags, + NULL); + + g_signal_connect(dialog_, "response", G_CALLBACK(OnResponse), this); + + tab_contents_container_.reset(new TabContentsContainerGtk(NULL)); + gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog_)->vbox), + tab_contents_container_->widget(), TRUE, TRUE, 0); + + tab_contents_container_->SetTabContents(tab_contents_.get()); + + gfx::Size dialog_size; + delegate_->GetDialogSize(&dialog_size); + + gtk_window_set_default_size(GTK_WINDOW(dialog_), + dialog_size.width(), + dialog_size.height()); + gtk_widget_show_all(dialog_); +} + +// static +void HtmlDialogGtk::OnResponse(GtkWidget* widget, int response, + HtmlDialogGtk* dialog) { + dialog->OnDialogClosed(std::string()); +} diff --git a/chrome/browser/gtk/html_dialog_gtk.h b/chrome/browser/gtk/html_dialog_gtk.h new file mode 100644 index 0000000..7ec5003 --- /dev/null +++ b/chrome/browser/gtk/html_dialog_gtk.h @@ -0,0 +1,89 @@ +// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_GTK_HTML_DIALOG_GTK_H_ +#define CHROME_BROWSER_GTK_HTML_DIALOG_GTK_H_ + +#include <string> +#include <vector> + +#include "base/gfx/size.h" +#include "base/scoped_ptr.h" +#include "chrome/browser/browser.h" +#include "chrome/browser/dom_ui/html_dialog_ui.h" +#include "chrome/browser/tab_contents/tab_contents_delegate.h" + +typedef struct _GtkWidget GtkWidget; + +class TabContents; +class TabContentsContainerGtk; + +class HtmlDialogGtk : public TabContentsDelegate, + public HtmlDialogUIDelegate { + public: + HtmlDialogGtk(Browser* parent_browser, HtmlDialogUIDelegate* delegate); + virtual ~HtmlDialogGtk(); + + static void ShowHtmlDialogGtk(Browser* browser, + HtmlDialogUIDelegate* delegate); + // Initializes the contents of the dialog (the DOMView and the callbacks). + void InitDialog(); + + // Overridden from HtmlDialogUI::Delegate: + virtual bool IsDialogModal() const; + virtual std::wstring GetDialogTitle() const; + virtual GURL GetDialogContentURL() const; + virtual void GetDOMMessageHandlers( + std::vector<DOMMessageHandler*>* handlers) const; + virtual void GetDialogSize(gfx::Size* size) const; + virtual std::string GetDialogArgs() const; + virtual void OnDialogClosed(const std::string& json_retval); + + // Overridden from TabContentsDelegate: + virtual void OpenURLFromTab(TabContents* source, + const GURL& url, + const GURL& referrer, + WindowOpenDisposition disposition, + PageTransition::Type transition); + virtual void NavigationStateChanged(const TabContents* source, + unsigned changed_flags); + virtual void ReplaceContents(TabContents* source, + TabContents* new_contents); + virtual void AddNewContents(TabContents* source, + TabContents* new_contents, + WindowOpenDisposition disposition, + const gfx::Rect& initial_pos, + bool user_gesture); + virtual void ActivateContents(TabContents* contents); + virtual void LoadingStateChanged(TabContents* source); + virtual void CloseContents(TabContents* source); + virtual void MoveContents(TabContents* source, const gfx::Rect& pos); + virtual bool IsPopup(TabContents* source); + virtual void ToolbarSizeChanged(TabContents* source, bool is_animating); + virtual void URLStarredChanged(TabContents* source, bool starred); + virtual void UpdateTargetURL(TabContents* source, const GURL& url); + + private: + static void OnResponse(GtkWidget* widget, int response, + HtmlDialogGtk* dialog); + + // The Browser object which created this html dialog; we send all + // window opening/navigations to this object. + Browser* parent_browser_; + + // This view is a delegate to the HTML content since it needs to get notified + // about when the dialog is closing. For all other actions (besides dialog + // closing) we delegate to the creator of this view, which we keep track of + // using this variable. + HtmlDialogUIDelegate* delegate_; + + GtkWidget* dialog_; + + scoped_ptr<TabContents> tab_contents_; + scoped_ptr<TabContentsContainerGtk> tab_contents_container_; + + DISALLOW_COPY_AND_ASSIGN(HtmlDialogGtk); +}; + +#endif // CHROME_BROWSER_GTK_HTML_DIALOG_GTK_H_ diff --git a/chrome/browser/tab_contents/tab_contents_view_gtk.cc b/chrome/browser/tab_contents/tab_contents_view_gtk.cc index 61c685e..3916640 100644 --- a/chrome/browser/tab_contents/tab_contents_view_gtk.cc +++ b/chrome/browser/tab_contents/tab_contents_view_gtk.cc @@ -345,8 +345,11 @@ bool TabContentsViewGtk::HandleKeyboardEvent( BrowserWindowGtk* browser_window = BrowserWindowGtk::GetBrowserWindowForNativeWindow(window); - DCHECK(browser_window); - return browser_window->HandleKeyboardEvent(event.os_event); + + // If this is a dialog, the top level window isn't a browser. In this case, + // we just return false. + return browser_window ? + browser_window->HandleKeyboardEvent(event.os_event) : false; } void TabContentsViewGtk::Observe(NotificationType type, |