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