1 // Copyright 2013 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/gtk/manage_passwords_bubble_gtk.h" 6 7 #include "chrome/browser/chrome_notification_types.h" 8 #include "chrome/browser/profiles/profile.h" 9 #include "chrome/browser/ui/browser.h" 10 #include "chrome/browser/ui/browser_finder.h" 11 #include "chrome/browser/ui/browser_window.h" 12 #include "chrome/browser/ui/gtk/gtk_theme_service.h" 13 #include "chrome/browser/ui/gtk/location_bar_view_gtk.h" 14 #include "chrome/browser/ui/passwords/manage_passwords_bubble_ui_controller.h" 15 #include "grit/generated_resources.h" 16 #include "ui/base/gtk/gtk_hig_constants.h" 17 #include "ui/base/l10n/l10n_util.h" 18 19 namespace { 20 21 // Pointer to singleton object (NULL if no bubble is open). 22 ManagePasswordsBubbleGtk* g_bubble = NULL; 23 24 // Need to manually set anchor width and height to ensure that the bubble shows 25 // in the correct spot the first time it is displayed when no icon is present. 26 const int kBubbleAnchorWidth = 20; 27 const int kBubbleAnchorHeight = 25; 28 29 } // namespace 30 31 // static 32 void ManagePasswordsBubbleGtk::ShowBubble(content::WebContents* web_contents) { 33 Browser* browser = chrome::FindBrowserWithWebContents(web_contents); 34 DCHECK(browser && browser->window() && browser->fullscreen_controller()); 35 36 LocationBar* location_bar = browser->window()->GetLocationBar(); 37 GtkWidget* anchor = browser->window()->IsFullscreen() ? 38 GTK_WIDGET(browser->window()->GetNativeWindow()) : 39 static_cast<LocationBarViewGtk*>(location_bar)-> 40 manage_passwords_icon_widget(); 41 42 g_bubble = new ManagePasswordsBubbleGtk(anchor, 43 web_contents, 44 browser->fullscreen_controller()); 45 } 46 47 // static 48 void ManagePasswordsBubbleGtk::CloseBubble() { 49 if (g_bubble) 50 g_bubble->Close(); 51 } 52 53 // static 54 bool ManagePasswordsBubbleGtk::IsShowing() { 55 return g_bubble != NULL; 56 } 57 58 ManagePasswordsBubbleGtk::ManagePasswordsBubbleGtk( 59 GtkWidget* anchor, 60 content::WebContents* web_contents, 61 FullscreenController* fullscreen_controller) 62 : web_contents_(web_contents) { 63 GtkThemeService* theme_service = GtkThemeService::GetFrom( 64 Profile::FromBrowserContext(web_contents_->GetBrowserContext())); 65 66 GtkWidget* bubble_contents_ = gtk_vbox_new(FALSE, ui::kControlSpacing); 67 gtk_container_set_border_width(GTK_CONTAINER(bubble_contents_), 68 ui::kContentAreaBorder); 69 GtkWidget* label = theme_service->BuildLabel( 70 l10n_util::GetStringUTF8(IDS_SAVE_PASSWORD), ui::kGdkBlack); 71 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); 72 gtk_box_pack_start(GTK_BOX(bubble_contents_), label, FALSE, FALSE, 0); 73 74 GtkWidget* button_container = gtk_hbox_new(FALSE, 0); 75 GtkWidget* nope_button = gtk_button_new_with_label(l10n_util::GetStringUTF8( 76 IDS_PASSWORD_MANAGER_CANCEL_BUTTON).c_str()); 77 g_signal_connect(nope_button, "clicked", 78 G_CALLBACK(OnNotNowButtonClickedThunk), this); 79 GtkWidget* save_button = gtk_button_new_with_label( 80 l10n_util::GetStringUTF8(IDS_PASSWORD_MANAGER_SAVE_BUTTON).c_str()); 81 g_signal_connect(save_button, "clicked", 82 G_CALLBACK(OnSaveButtonClickedThunk), this); 83 84 gtk_box_pack_end(GTK_BOX(button_container), save_button, FALSE, FALSE, 4); 85 gtk_box_pack_end(GTK_BOX(button_container), nope_button, FALSE, FALSE, 0); 86 gtk_box_pack_start(GTK_BOX(bubble_contents_), button_container, FALSE, FALSE, 87 0); 88 gtk_widget_grab_focus(save_button); 89 90 gfx::Rect rect = gfx::Rect(kBubbleAnchorWidth, kBubbleAnchorHeight); 91 BubbleGtk::FrameStyle frame_style = gtk_widget_is_toplevel(anchor) ? 92 BubbleGtk::FIXED_TOP_RIGHT : BubbleGtk::ANCHOR_TOP_RIGHT; 93 bubble_ = BubbleGtk::Show(anchor, 94 &rect, 95 bubble_contents_, 96 frame_style, 97 BubbleGtk::MATCH_SYSTEM_THEME | 98 BubbleGtk::POPUP_WINDOW | 99 BubbleGtk::GRAB_INPUT, 100 theme_service, 101 NULL); 102 103 g_signal_connect(bubble_contents_, "destroy", 104 G_CALLBACK(&OnDestroyThunk), this); 105 } 106 107 ManagePasswordsBubbleGtk::~ManagePasswordsBubbleGtk() { 108 DCHECK_EQ(g_bubble, this); 109 // Set singleton pointer to NULL. 110 g_bubble = NULL; 111 } 112 113 void ManagePasswordsBubbleGtk::Close() { 114 DCHECK(bubble_); 115 bubble_->Close(); 116 } 117 118 void ManagePasswordsBubbleGtk::OnDestroy(GtkWidget* widget) { 119 // Listen to the destroy signal and delete this instance when it is caught. 120 delete this; 121 } 122 123 void ManagePasswordsBubbleGtk::OnSaveButtonClicked(GtkWidget* button) { 124 ManagePasswordsBubbleUIController::FromWebContents(web_contents_)-> 125 SavePassword(); 126 Close(); 127 } 128 129 void ManagePasswordsBubbleGtk::OnNotNowButtonClicked(GtkWidget* button) { 130 Close(); 131 } 132