diff options
author | bauerb@chromium.org <bauerb@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-03-24 16:11:59 +0000 |
---|---|---|
committer | bauerb@chromium.org <bauerb@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-03-24 16:11:59 +0000 |
commit | 7e4d9746bd475b0f28c3ebf4c561693129137fd8 (patch) | |
tree | 181c261f8e7e7c852b0eb3799d04f1f5bdf54e80 | |
parent | e5e9dd07968a2811196b262e739633e373837acc (diff) | |
download | chromium_src-7e4d9746bd475b0f28c3ebf4c561693129137fd8.zip chromium_src-7e4d9746bd475b0f28c3ebf4c561693129137fd8.tar.gz chromium_src-7e4d9746bd475b0f28c3ebf4c561693129137fd8.tar.bz2 |
Make repost form warning tab-modal on Gtk.
This is the Gtk version of http://codereview.chromium.org/969003.
BUG=26271
TEST=Go to http://www.cs.unc.edu/~jbs/resources/perl/perl-cgi/programs/form1-POST.html, hit Submit, then refresh. The warning sheet should be tab-modal, not window-modal. Opening a login form (which is also tab-modal) while the warning is shown should not crash, neither should bringing up the warning while a login form is shown.
Review URL: http://codereview.chromium.org/660434
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@42474 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/browser/gtk/browser_window_gtk.cc | 2 | ||||
-rw-r--r-- | chrome/browser/gtk/repost_form_warning_gtk.cc | 117 | ||||
-rw-r--r-- | chrome/browser/gtk/repost_form_warning_gtk.h | 29 | ||||
-rw-r--r-- | chrome/browser/tab_contents/tab_contents.cc | 6 |
4 files changed, 104 insertions, 50 deletions
diff --git a/chrome/browser/gtk/browser_window_gtk.cc b/chrome/browser/gtk/browser_window_gtk.cc index 39e6348..59873fe 100644 --- a/chrome/browser/gtk/browser_window_gtk.cc +++ b/chrome/browser/gtk/browser_window_gtk.cc @@ -874,7 +874,7 @@ void BrowserWindowGtk::ShowNewProfileDialog() { void BrowserWindowGtk::ShowRepostFormWarningDialog( TabContents* tab_contents) { - new RepostFormWarningGtk(GetNativeHandle(), &tab_contents->controller()); + new RepostFormWarningGtk(GetNativeHandle(), tab_contents); } void BrowserWindowGtk::ShowContentSettingsWindow( diff --git a/chrome/browser/gtk/repost_form_warning_gtk.cc b/chrome/browser/gtk/repost_form_warning_gtk.cc index 53d1ca1..a3f4681 100644 --- a/chrome/browser/gtk/repost_form_warning_gtk.cc +++ b/chrome/browser/gtk/repost_form_warning_gtk.cc @@ -9,45 +9,75 @@ #include "base/message_loop.h" #include "chrome/browser/gtk/gtk_util.h" #include "chrome/browser/tab_contents/navigation_controller.h" +#include "chrome/browser/tab_contents/tab_contents.h" #include "chrome/common/notification_service.h" #include "grit/generated_resources.h" -RepostFormWarningGtk::RepostFormWarningGtk( - GtkWindow* parent, - NavigationController* navigation_controller) - : navigation_controller_(navigation_controller) { - dialog_ = gtk_message_dialog_new( - parent, - GTK_DIALOG_MODAL, - GTK_MESSAGE_QUESTION, - GTK_BUTTONS_NONE, - "%s", +RepostFormWarningGtk::RepostFormWarningGtk(GtkWindow* parent, + TabContents* tab_contents) + : navigation_controller_(&tab_contents->controller()) { + dialog_ = gtk_vbox_new(NULL, gtk_util::kContentAreaBorder); + gtk_box_set_spacing(GTK_BOX(dialog_), gtk_util::kContentAreaSpacing); + GtkWidget* label = gtk_label_new( l10n_util::GetStringUTF8(IDS_HTTP_POST_WARNING).c_str()); - gtk_util::ApplyMessageDialogQuirks(dialog_); - gtk_window_set_title(GTK_WINDOW(dialog_), - l10n_util::GetStringUTF8(IDS_HTTP_POST_WARNING_TITLE).c_str()); - gtk_util::AddButtonToDialog(dialog_, - l10n_util::GetStringUTF8(IDS_CANCEL).c_str(), - GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL); - gtk_util::AddButtonToDialog(dialog_, - l10n_util::GetStringUTF8(IDS_HTTP_POST_WARNING_RESEND).c_str(), - GTK_STOCK_REFRESH, GTK_RESPONSE_OK); - gtk_util::SetWindowIcon(GTK_WINDOW(dialog_)); - - g_signal_connect(dialog_, "response", G_CALLBACK(OnResponse), this); - g_signal_connect(dialog_, "destroy", G_CALLBACK(OnWindowDestroy), this); - - gtk_widget_show_all(dialog_); + GtkWidget* image = gtk_image_new_from_stock(GTK_STOCK_DIALOG_QUESTION, + GTK_ICON_SIZE_DIALOG); + gtk_misc_set_alignment(GTK_MISC(image), 0.5, 0.0); + + gtk_label_set_line_wrap(GTK_LABEL(label), TRUE); + gtk_label_set_selectable(GTK_LABEL(label), TRUE); + + GtkWidget *hbox = gtk_hbox_new(FALSE, gtk_util::kControlSpacing); + + gtk_box_pack_start(GTK_BOX(hbox), image, FALSE, FALSE, 0); + + gtk_box_pack_start(GTK_BOX(hbox), label, TRUE, TRUE, 0); + + gtk_box_pack_start(GTK_BOX(dialog_), hbox, FALSE, FALSE, 0); + + GtkWidget* buttonBox = gtk_hbutton_box_new(); + gtk_button_box_set_layout(GTK_BUTTON_BOX(buttonBox), GTK_BUTTONBOX_END); + gtk_box_set_spacing(GTK_BOX(buttonBox), gtk_util::kControlSpacing); + gtk_box_pack_end(GTK_BOX(dialog_), buttonBox, FALSE, TRUE, 0); + + cancel_ = gtk_button_new_from_stock(GTK_STOCK_CANCEL); + gtk_button_set_label(GTK_BUTTON(cancel_), + l10n_util::GetStringUTF8(IDS_CANCEL).c_str()); + g_signal_connect(cancel_, "clicked", G_CALLBACK(OnCancelThunk), this); + gtk_box_pack_end(GTK_BOX(buttonBox), cancel_, FALSE, TRUE, 0); + + ok_ = gtk_button_new_from_stock(GTK_STOCK_REFRESH); + gtk_button_set_label( + GTK_BUTTON(ok_), + l10n_util::GetStringUTF8(IDS_HTTP_POST_WARNING_RESEND).c_str()); + g_signal_connect(ok_, "clicked", G_CALLBACK(OnRefreshThunk), this); + gtk_box_pack_end(GTK_BOX(buttonBox), ok_, FALSE, TRUE, 0); + + g_signal_connect(cancel_, "hierarchy-changed", + G_CALLBACK(OnHierarchyChangedThunk), this); + + window_ = tab_contents->CreateConstrainedDialog(this); registrar_.Add(this, NotificationType::LOAD_START, Source<NavigationController>(navigation_controller_)); registrar_.Add(this, NotificationType::TAB_CLOSING, Source<NavigationController>(navigation_controller_)); + registrar_.Add(this, NotificationType::RELOADING, + Source<NavigationController>(navigation_controller_)); + } RepostFormWarningGtk::~RepostFormWarningGtk() { } +GtkWidget* RepostFormWarningGtk::GetWidgetRoot() { + return dialog_; +} + +void RepostFormWarningGtk::DeleteDelegate() { + MessageLoop::current()->DeleteSoon(FROM_HERE, this); +} + void RepostFormWarningGtk::Observe(NotificationType type, const NotificationSource& source, const NotificationDetails& details) { @@ -56,11 +86,11 @@ void RepostFormWarningGtk::Observe(NotificationType type, // a navigation controller anymore. if (dialog_ && navigation_controller_ && (type == NotificationType::LOAD_START || - type == NotificationType::TAB_CLOSING)) { + type == NotificationType::TAB_CLOSING || + type == NotificationType::RELOADING)) { DCHECK_EQ(Source<NavigationController>(source).ptr(), navigation_controller_); - navigation_controller_ = NULL; - Destroy(); + OnCancel(dialog_); } } @@ -69,20 +99,29 @@ void RepostFormWarningGtk::Destroy() { gtk_widget_destroy(dialog_); dialog_ = NULL; } + window_->CloseConstrainedWindow(); } -// static -void RepostFormWarningGtk::OnResponse(GtkWidget* widget, int response, - RepostFormWarningGtk* dialog) { - dialog->Destroy(); - if (response == GTK_RESPONSE_OK) { - if (dialog->navigation_controller_) - dialog->navigation_controller_->Reload(false); +void RepostFormWarningGtk::OnRefresh(GtkWidget* widget) { + if (navigation_controller_) { + navigation_controller_->ContinuePendingReload(); + // reloading the page will close the dialog. } } -// static -void RepostFormWarningGtk::OnWindowDestroy(GtkWidget* widget, - RepostFormWarningGtk* dialog) { - MessageLoop::current()->DeleteSoon(FROM_HERE, dialog); +void RepostFormWarningGtk::OnCancel(GtkWidget* widget) { + if (navigation_controller_) { + navigation_controller_->CancelPendingReload(); + } + Destroy(); } + +void RepostFormWarningGtk::OnHierarchyChanged(GtkWidget* root, + GtkWidget* previous_toplevel) { + DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); + if (!GTK_WIDGET_TOPLEVEL(gtk_widget_get_toplevel(cancel_))) { + return; + } + gtk_widget_grab_focus(cancel_); +} + diff --git a/chrome/browser/gtk/repost_form_warning_gtk.h b/chrome/browser/gtk/repost_form_warning_gtk.h index 268b98e..4382fbc 100644 --- a/chrome/browser/gtk/repost_form_warning_gtk.h +++ b/chrome/browser/gtk/repost_form_warning_gtk.h @@ -8,19 +8,26 @@ #include <gtk/gtk.h> #include "chrome/common/notification_registrar.h" +#include "chrome/browser/gtk/constrained_window_gtk.h" +#include "app/gtk_signal.h" class NavigationController; +class TabContents; // Displays a dialog that warns the user that they are about to resubmit a form. // To display the dialog, allocate this object on the heap. It will open the // dialog from its constructor and then delete itself when the user dismisses // the dialog. -class RepostFormWarningGtk : public NotificationObserver { +class RepostFormWarningGtk : public NotificationObserver, + ConstrainedWindowGtkDelegate { public: - RepostFormWarningGtk(GtkWindow* parent, - NavigationController* navigation_controller); + RepostFormWarningGtk(GtkWindow* parent, TabContents* tab_contents); virtual ~RepostFormWarningGtk(); + virtual GtkWidget* GetWidgetRoot(); + + virtual void DeleteDelegate(); + private: // NotificationObserver implementation. // Watch for a new load or a closed tab and dismiss the dialog if they occur. @@ -29,13 +36,15 @@ class RepostFormWarningGtk : public NotificationObserver { const NotificationDetails& details); // Tell Gtk to destroy the dialog window. This will only be done once, even - // if Destroy is called multiple times (eg, from both OnResponse and Observe.) + // if Destroy is called multiple times. void Destroy(); - static void OnResponse(GtkWidget* widget, - int response, - RepostFormWarningGtk* dialog); - static void OnWindowDestroy(GtkWidget* widget, RepostFormWarningGtk* dialog); + CHROMEGTK_CALLBACK_0(RepostFormWarningGtk, void, OnRefresh); + CHROMEGTK_CALLBACK_0(RepostFormWarningGtk, void, OnCancel); + CHROMEGTK_CALLBACK_1(RepostFormWarningGtk, + void, + OnHierarchyChanged, + GtkWidget*); NotificationRegistrar registrar_; @@ -43,6 +52,10 @@ class RepostFormWarningGtk : public NotificationObserver { NavigationController* navigation_controller_; GtkWidget* dialog_; + GtkWidget* ok_; + GtkWidget* cancel_; + + ConstrainedWindow* window_; DISALLOW_COPY_AND_ASSIGN(RepostFormWarningGtk); }; diff --git a/chrome/browser/tab_contents/tab_contents.cc b/chrome/browser/tab_contents/tab_contents.cc index c8d3e95..21f78da 100644 --- a/chrome/browser/tab_contents/tab_contents.cc +++ b/chrome/browser/tab_contents/tab_contents.cc @@ -1091,8 +1091,10 @@ void TabContents::WillClose(ConstrainedWindow* window) { bool removed_topmost_window = it == child_windows_.begin(); if (it != child_windows_.end()) child_windows_.erase(it); - if (removed_topmost_window && child_windows_.size() > 0) { - child_windows_[0]->ShowConstrainedWindow(); + if (child_windows_.size() > 0) { + if (removed_topmost_window) { + child_windows_[0]->ShowConstrainedWindow(); + } BlockTabContent(true); } else { BlockTabContent(false); |