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 19namespace { 20 21// Pointer to singleton object (NULL if no bubble is open). 22ManagePasswordsBubbleGtk* 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. 26const int kBubbleAnchorWidth = 20; 27const int kBubbleAnchorHeight = 25; 28 29} // namespace 30 31// static 32void 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 48void ManagePasswordsBubbleGtk::CloseBubble() { 49 if (g_bubble) 50 g_bubble->Close(); 51} 52 53// static 54bool ManagePasswordsBubbleGtk::IsShowing() { 55 return g_bubble != NULL; 56} 57 58ManagePasswordsBubbleGtk::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 107ManagePasswordsBubbleGtk::~ManagePasswordsBubbleGtk() { 108 DCHECK_EQ(g_bubble, this); 109 // Set singleton pointer to NULL. 110 g_bubble = NULL; 111} 112 113void ManagePasswordsBubbleGtk::Close() { 114 DCHECK(bubble_); 115 bubble_->Close(); 116} 117 118void ManagePasswordsBubbleGtk::OnDestroy(GtkWidget* widget) { 119 // Listen to the destroy signal and delete this instance when it is caught. 120 delete this; 121} 122 123void ManagePasswordsBubbleGtk::OnSaveButtonClicked(GtkWidget* button) { 124 ManagePasswordsBubbleUIController::FromWebContents(web_contents_)-> 125 SavePassword(); 126 Close(); 127} 128 129void ManagePasswordsBubbleGtk::OnNotNowButtonClicked(GtkWidget* button) { 130 Close(); 131} 132