root/chrome/browser/ui/gtk/crypto_module_password_dialog_gtk.cc

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. Show
  2. OnResponse
  3. OnWindowDestroy
  4. ShowCryptoModulePasswordDialog

// Copyright (c) 2012 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/ui/crypto_module_password_dialog.h"

#include <gtk/gtk.h>

#include "base/basictypes.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/ui/gtk/gtk_util.h"
#include "grit/generated_resources.h"
#include "ui/base/gtk/gtk_hig_constants.h"
#include "ui/base/gtk/gtk_signal.h"
#include "ui/base/l10n/l10n_util.h"
#include "url/gurl.h"

namespace {

// TODO(mattm): change into a constrained dialog.
class CryptoModulePasswordDialog {
 public:
  CryptoModulePasswordDialog(
      const std::string& slot_name,
      bool retry,
      chrome::CryptoModulePasswordReason reason,
      const std::string& hostname,
      gfx::NativeWindow parent,
      const chrome::CryptoModulePasswordCallback& callback);

  ~CryptoModulePasswordDialog() {}

  void Show();

 private:
  CHROMEGTK_CALLBACK_1(CryptoModulePasswordDialog, void, OnResponse, int);
  CHROMEGTK_CALLBACK_0(CryptoModulePasswordDialog, void, OnWindowDestroy);

  chrome::CryptoModulePasswordCallback callback_;

  GtkWidget* dialog_;
  GtkWidget* password_entry_;

  DISALLOW_COPY_AND_ASSIGN(CryptoModulePasswordDialog);
};

CryptoModulePasswordDialog::CryptoModulePasswordDialog(
    const std::string& slot_name,
    bool retry,
    chrome::CryptoModulePasswordReason reason,
    const std::string& hostname,
    gfx::NativeWindow parent,
    const chrome::CryptoModulePasswordCallback& callback)
    : callback_(callback) {
  dialog_ = gtk_dialog_new_with_buttons(
      l10n_util::GetStringUTF8(IDS_CRYPTO_MODULE_AUTH_DIALOG_TITLE).c_str(),
      parent,
      GTK_DIALOG_NO_SEPARATOR,
      NULL);  // Populate the buttons later, for control over the OK button.
  gtk_dialog_add_button(GTK_DIALOG(dialog_),
                        GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT);
  GtkWidget* ok_button = gtk_util::AddButtonToDialog(
      dialog_,
      l10n_util::GetStringUTF8(
          IDS_CRYPTO_MODULE_AUTH_DIALOG_OK_BUTTON_LABEL).c_str(),
      GTK_STOCK_OK,
      GTK_RESPONSE_ACCEPT);
  gtk_widget_set_can_default(ok_button, TRUE);
  gtk_dialog_set_default_response(GTK_DIALOG(dialog_), GTK_RESPONSE_ACCEPT);

  // Select an appropriate text for the reason.
  std::string text;
  const base::string16& hostname16 = base::UTF8ToUTF16(hostname);
  const base::string16& slot16 = base::UTF8ToUTF16(slot_name);
  switch (reason) {
    case chrome::kCryptoModulePasswordKeygen:
      text = l10n_util::GetStringFUTF8(
          IDS_CRYPTO_MODULE_AUTH_DIALOG_TEXT_KEYGEN, slot16, hostname16);
      break;
    case chrome::kCryptoModulePasswordCertEnrollment:
      text = l10n_util::GetStringFUTF8(
          IDS_CRYPTO_MODULE_AUTH_DIALOG_TEXT_CERT_ENROLLMENT,
          slot16,
          hostname16);
      break;
    case chrome::kCryptoModulePasswordClientAuth:
      text = l10n_util::GetStringFUTF8(
          IDS_CRYPTO_MODULE_AUTH_DIALOG_TEXT_CLIENT_AUTH, slot16, hostname16);
      break;
    case chrome::kCryptoModulePasswordListCerts:
      text = l10n_util::GetStringFUTF8(
          IDS_CRYPTO_MODULE_AUTH_DIALOG_TEXT_LIST_CERTS, slot16);
      break;
    case chrome::kCryptoModulePasswordCertImport:
      text = l10n_util::GetStringFUTF8(
          IDS_CRYPTO_MODULE_AUTH_DIALOG_TEXT_CERT_IMPORT, slot16);
      break;
    case chrome::kCryptoModulePasswordCertExport:
      text = l10n_util::GetStringFUTF8(
          IDS_CRYPTO_MODULE_AUTH_DIALOG_TEXT_CERT_EXPORT, slot16);
      break;
    default:
      NOTREACHED();
  }
  GtkWidget* label = gtk_label_new(text.c_str());
  gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
  gtk_util::LeftAlignMisc(label);
  gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog_)->vbox), label,
                     FALSE, FALSE, 0);

  password_entry_ = gtk_entry_new();
  gtk_entry_set_activates_default(GTK_ENTRY(password_entry_), TRUE);
  gtk_entry_set_visibility(GTK_ENTRY(password_entry_), FALSE);

  GtkWidget* password_box = gtk_hbox_new(FALSE, ui::kLabelSpacing);
  gtk_box_pack_start(GTK_BOX(password_box),
                     gtk_label_new(l10n_util::GetStringUTF8(
                         IDS_CRYPTO_MODULE_AUTH_DIALOG_PASSWORD_FIELD).c_str()),
                     FALSE, FALSE, 0);
  gtk_box_pack_start(GTK_BOX(password_box), password_entry_,
                     TRUE, TRUE, 0);

  gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog_)->vbox), password_box,
                     FALSE, FALSE, 0);

  g_signal_connect(dialog_, "response",
                   G_CALLBACK(OnResponseThunk), this);
  g_signal_connect(dialog_, "destroy",
                   G_CALLBACK(OnWindowDestroyThunk), this);
}

void CryptoModulePasswordDialog::Show() {
  gtk_util::ShowDialog(dialog_);
}

void CryptoModulePasswordDialog::OnResponse(GtkWidget* dialog,
                                            int response_id) {
  if (response_id == GTK_RESPONSE_ACCEPT)
    callback_.Run(gtk_entry_get_text(GTK_ENTRY(password_entry_)));
  else
    callback_.Run(std::string());

  // This will cause gtk to zero out the buffer.  (see
  // gtk_entry_buffer_normal_delete_text:
  // http://git.gnome.org/browse/gtk+/tree/gtk/gtkentrybuffer.c#n187)
  gtk_editable_delete_text(GTK_EDITABLE(password_entry_), 0, -1);
  gtk_widget_destroy(dialog_);
}

void CryptoModulePasswordDialog::OnWindowDestroy(GtkWidget* widget) {
  delete this;
}

}  // namespace

namespace chrome {

void ShowCryptoModulePasswordDialog(
    const std::string& slot_name,
    bool retry,
    CryptoModulePasswordReason reason,
    const std::string& hostname,
    gfx::NativeWindow parent,
    const CryptoModulePasswordCallback& callback) {
  (new CryptoModulePasswordDialog(
       slot_name, retry, reason, hostname, parent, callback))->Show();
}

}  // namespace chrome

/* [<][>][^][v][top][bottom][index][help] */