Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/shell
diff options
context:
space:
mode:
authorCarlos Garcia Campos <carlosgc@gnome.org>2008-12-01 11:16:43 (GMT)
committer Carlos Garcia Campos <carlosgc@src.gnome.org>2008-12-01 11:16:43 (GMT)
commitdc3a49f93a0798b5c0c8d2fd6283f39294945045 (patch)
tree68c16d20d561b645fde10246bd166f85f6a864f4 /shell
parentfeeec13cf60423b15059f5e30cf3fb5763cd3922 (diff)
Removed
2008-12-01 Carlos Garcia Campos <carlosgc@gnome.org> * configure.ac: * shell/Makefile.am: * shell/ev-keyring.[ch]: * shell/ev-password.[ch]: Removed * shell/ev-password-view.[ch]: (ev_password_view_finalize), (ev_password_view_class_init), (ev_password_view_clicked_cb), (ev_password_view_init), (ev_password_view_set_uri), (ev_password_dialog_got_response), (ev_password_dialog_remember_button_toggled), (ev_password_dialog_entry_changed_cb), (ev_password_dialog_entry_activated_cb), (ev_password_view_ask_password), (ev_password_view_get_password), (ev_password_view_get_password_save_flags), (ev_password_view_new): * shell/ev-window.c: (ev_window_password_view_unlock), (ev_window_load_job_cb), (ev_window_close_dialogs), (ev_window_init): Rework the password view. When the password is in the keyring it's used automatically without showing the password dialog and it's only stored in the keyring when we are sure it's correct. The password dialog has been reworked too, in order to make it more hig compliant and consistent with the GTK+ dialog used in gtkmountoperation. Fixes bug #562496. svn path=/trunk/; revision=3281
Diffstat (limited to 'shell')
-rw-r--r--shell/Makefile.am4
-rw-r--r--shell/ev-keyring.c116
-rw-r--r--shell/ev-keyring.h37
-rw-r--r--shell/ev-password-view.c310
-rw-r--r--shell/ev-password-view.h14
-rw-r--r--shell/ev-password.c350
-rw-r--r--shell/ev-password.h58
-rw-r--r--shell/ev-window.c119
8 files changed, 509 insertions, 499 deletions
diff --git a/shell/Makefile.am b/shell/Makefile.am
index b1dafd7..1a15494 100644
--- a/shell/Makefile.am
+++ b/shell/Makefile.am
@@ -38,6 +38,8 @@ evince_SOURCES= \
ev-file-monitor.c \
ev-history.c \
ev-history.h \
+ ev-keyring.h \
+ ev-keyring.c \
ev-marshal.c \
ev-marshal.h \
$(DBUS_SOURCES) \
@@ -55,8 +57,6 @@ evince_SOURCES= \
ev-page-action-widget.h \
ev-page-cache.h \
ev-page-cache.c \
- ev-password.h \
- ev-password.c \
ev-password-view.h \
ev-password-view.c \
ev-pixbuf-cache.c \
diff --git a/shell/ev-keyring.c b/shell/ev-keyring.c
new file mode 100644
index 0000000..0199863
--- /dev/null
+++ b/shell/ev-keyring.c
@@ -0,0 +1,116 @@
+/* ev-keyring.c
+ * this file is part of evince, a gnome document viewer
+ *
+ * Copyright (C) 2008 Carlos Garcia Campos <carlosgc@gnome.org>
+ *
+ * Evince is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Evince is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include <glib/gi18n.h>
+
+#include "ev-keyring.h"
+
+#ifdef WITH_KEYRING
+#include <gnome-keyring.h>
+
+static const GnomeKeyringPasswordSchema doc_password_schema = {
+ GNOME_KEYRING_ITEM_GENERIC_SECRET,
+ {
+ { "type", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING },
+ { "uri", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING },
+ { NULL, 0 }
+ }
+};
+const GnomeKeyringPasswordSchema *EV_DOCUMENT_PASSWORD_SCHEMA = &doc_password_schema;
+#endif /* WITH_KEYRING */
+
+gboolean
+ev_keyring_is_available (void)
+{
+#ifdef WITH_KEYRING
+ return gnome_keyring_is_available ();
+#else
+ return FALSE;
+#endif
+}
+
+gchar *
+ev_keyring_lookup_password (const gchar *uri)
+{
+ gchar *retval = NULL;
+#ifdef WITH_KEYRING
+ GnomeKeyringResult result;
+ gchar *password = NULL;
+
+ g_return_val_if_fail (uri != NULL, NULL);
+
+ if (!gnome_keyring_is_available ())
+ return NULL;
+
+ result = gnome_keyring_find_password_sync (EV_DOCUMENT_PASSWORD_SCHEMA,
+ &password,
+ "type", "document_password",
+ "uri", uri,
+ NULL);
+ if (result != GNOME_KEYRING_RESULT_OK || !password) {
+ if (password)
+ gnome_keyring_free_password (password);
+ return NULL;
+ }
+
+ retval = g_strdup (password);
+ gnome_keyring_free_password (password);
+#endif /* WITH_KEYRING */
+ return retval;
+}
+
+gboolean
+ev_keyring_save_password (const gchar *uri,
+ const gchar *password,
+ GPasswordSave flags)
+{
+#ifdef WITH_KEYRING
+ GnomeKeyringResult result;
+ const gchar *keyring;
+ gchar *name;
+ gchar *unescaped_uri;
+
+ g_return_val_if_fail (uri != NULL, FALSE);
+
+ if (!gnome_keyring_is_available ())
+ return FALSE;
+
+ if (flags == G_PASSWORD_SAVE_NEVER)
+ return FALSE;
+
+ keyring = (flags == G_PASSWORD_SAVE_FOR_SESSION) ? "session" : NULL;
+ unescaped_uri = g_uri_unescape_string (uri, NULL);
+ name = g_strdup_printf (_("Password for document %s"), unescaped_uri);
+ g_free (unescaped_uri);
+
+ result = gnome_keyring_store_password_sync (EV_DOCUMENT_PASSWORD_SCHEMA,
+ keyring, name, password,
+ "type", "document_password",
+ "uri", uri,
+ NULL);
+ g_free (name);
+
+ return (result == GNOME_KEYRING_RESULT_OK);
+#else
+ return FALSE;
+#endif /* WITH_KEYRING */
+}
diff --git a/shell/ev-keyring.h b/shell/ev-keyring.h
new file mode 100644
index 0000000..f51410e
--- /dev/null
+++ b/shell/ev-keyring.h
@@ -0,0 +1,37 @@
+/* ev-keyring.h
+ * this file is part of evince, a gnome document viewer
+ *
+ * Copyright (C) 2008 Carlos Garcia Campos <carlosgc@gnome.org>
+ *
+ * Evince is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Evince is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __EV_KEYRING_H__
+#define __EV_KEYRING_H__
+
+#include <glib.h>
+#include <gio/gio.h>
+
+G_BEGIN_DECLS
+
+gboolean ev_keyring_is_available (void);
+gchar *ev_keyring_lookup_password (const gchar *uri);
+gboolean ev_keyring_save_password (const gchar *uri,
+ const gchar *password,
+ GPasswordSave flags);
+
+G_END_DECLS
+
+#endif /* __EV_KEYRING_H__ */
diff --git a/shell/ev-password-view.c b/shell/ev-password-view.c
index b53300d..f7d0ca3 100644
--- a/shell/ev-password-view.c
+++ b/shell/ev-password-view.c
@@ -1,5 +1,6 @@
/* this file is part of evince, a gnome document viewer
*
+ * Copyright (C) 2008 Carlos Garcia Campos <carlosgc@gnome.org>
* Copyright (C) 2005 Red Hat, Inc
*
* Evince is free software; you can redistribute it and/or modify it
@@ -24,8 +25,9 @@
#include <glib/gi18n.h>
#include <gtk/gtk.h>
+#include <gio/gio.h>
-#include "ev-marshal.h"
+#include "ev-keyring.h"
#include "ev-password-view.h"
enum {
@@ -33,7 +35,14 @@ enum {
LAST_SIGNAL
};
struct _EvPasswordViewPrivate {
- GtkWidget *label;
+ GtkWindow *parent_window;
+ GtkWidget *label;
+ GtkWidget *password_entry;
+
+ gchar *password;
+ GPasswordSave password_save;
+
+ GFile *uri_file;
};
#define EV_PASSWORD_VIEW_GET_PRIVATE(object) \
@@ -44,6 +53,25 @@ static guint password_view_signals [LAST_SIGNAL] = { 0 };
G_DEFINE_TYPE (EvPasswordView, ev_password_view, GTK_TYPE_VIEWPORT)
+static void
+ev_password_view_finalize (GObject *object)
+{
+ EvPasswordView *password_view = EV_PASSWORD_VIEW (object);
+
+ if (password_view->priv->password) {
+ g_free (password_view->priv->password);
+ password_view->priv->password = NULL;
+ }
+
+ password_view->priv->parent_window = NULL;
+
+ if (password_view->priv->uri_file) {
+ g_object_unref (password_view->priv->uri_file);
+ password_view->priv->uri_file = NULL;
+ }
+
+ G_OBJECT_CLASS (ev_password_view_parent_class)->finalize (object);
+}
static void
ev_password_view_class_init (EvPasswordViewClass *class)
@@ -54,23 +82,25 @@ ev_password_view_class_init (EvPasswordViewClass *class)
g_object_class = G_OBJECT_CLASS (class);
widget_class = GTK_WIDGET_CLASS (class);
- password_view_signals [UNLOCK] =
+ password_view_signals[UNLOCK] =
g_signal_new ("unlock",
G_TYPE_FROM_CLASS (g_object_class),
G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
G_STRUCT_OFFSET (EvPasswordViewClass, unlock),
NULL, NULL,
- ev_marshal_VOID__VOID,
+ g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
g_type_class_add_private (g_object_class, sizeof (EvPasswordViewPrivate));
+
+ g_object_class->finalize = ev_password_view_finalize;
}
static void
ev_password_view_clicked_cb (GtkWidget *button,
EvPasswordView *password_view)
{
- g_signal_emit (password_view, password_view_signals [UNLOCK], 0);
+ ev_password_view_ask_password (password_view);
}
static void
@@ -82,10 +112,12 @@ ev_password_view_init (EvPasswordView *password_view)
GtkWidget *image;
GtkWidget *button;
GtkWidget *label;
- gchar *markup;
+ gchar *markup;
password_view->priv = EV_PASSWORD_VIEW_GET_PRIVATE (password_view);
+ password_view->priv->password_save = G_PASSWORD_SAVE_NEVER;
+
gtk_widget_push_composite_child ();
/* set ourselves up */
@@ -126,30 +158,274 @@ ev_password_view_init (EvPasswordView *password_view)
gtk_widget_pop_composite_child ();
}
-
/* Public functions */
void
-ev_password_view_set_file_name (EvPasswordView *password_view,
- const char *file_name)
+ev_password_view_set_uri (EvPasswordView *password_view,
+ const char *uri)
{
- gchar *markup;
+ gchar *markup, *file_name;
+ GFile *file;
g_return_if_fail (EV_IS_PASSWORD_VIEW (password_view));
- g_return_if_fail (file_name != NULL);
-
- markup = g_markup_printf_escaped ("<span size=\"x-large\" weight=\"bold\">%s</span>", file_name);
+ g_return_if_fail (uri != NULL);
+
+ file = g_file_new_for_uri (uri);
+ if (password_view->priv->uri_file &&
+ g_file_equal (file, password_view->priv->uri_file)) {
+ g_object_unref (file);
+ return;
+ }
+ if (password_view->priv->uri_file)
+ g_object_unref (password_view->priv->uri_file);
+ password_view->priv->uri_file = file;
+
+ file_name = g_file_get_basename (password_view->priv->uri_file);
+ markup = g_markup_printf_escaped ("<span size=\"x-large\" weight=\"bold\">%s</span>",
+ file_name);
+ g_free (file_name);
gtk_label_set_markup (GTK_LABEL (password_view->priv->label), markup);
+ g_free (markup);
+}
+
+static void
+ev_password_dialog_got_response (GtkDialog *dialog,
+ gint response_id,
+ EvPasswordView *password_view)
+{
+ gtk_widget_set_sensitive (GTK_WIDGET (password_view), TRUE);
+
+ if (response_id == GTK_RESPONSE_OK) {
+ g_free (password_view->priv->password);
+ password_view->priv->password =
+ g_strdup (gtk_entry_get_text (GTK_ENTRY (password_view->priv->password_entry)));
+
+ g_signal_emit (password_view, password_view_signals[UNLOCK], 0);
+ }
+
+ gtk_widget_destroy (GTK_WIDGET (dialog));
+}
+
+static void
+ev_password_dialog_remember_button_toggled (GtkToggleButton *button,
+ EvPasswordView *password_view)
+{
+ if (gtk_toggle_button_get_active (button)) {
+ gpointer data;
+
+ data = g_object_get_data (G_OBJECT (button), "password-save");
+ password_view->priv->password_save = GPOINTER_TO_INT (data);
+ }
+}
+
+static void
+ev_password_dialog_entry_changed_cb (GtkEditable *editable,
+ GtkDialog *dialog)
+{
+ const char *text;
+
+ text = gtk_entry_get_text (GTK_ENTRY (editable));
+
+ gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), GTK_RESPONSE_OK,
+ (text != NULL && *text != '\0'));
+}
+
+static void
+ev_password_dialog_entry_activated_cb (GtkEntry *entry,
+ GtkDialog *dialog)
+{
+ gtk_dialog_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
+}
+
+void
+ev_password_view_ask_password (EvPasswordView *password_view)
+{
+ GtkDialog *dialog;
+ GtkWidget *entry_container;
+ GtkWidget *hbox, *main_vbox, *vbox, *icon;
+ GtkWidget *table;
+ GtkWidget *label;
+ gchar *format, *markup, *file_name;
+
+ gtk_widget_set_sensitive (GTK_WIDGET (password_view), FALSE);
+
+ dialog = GTK_DIALOG (gtk_dialog_new ());
+
+ /* Set the dialog up with HIG properties */
+ gtk_dialog_set_has_separator (dialog, FALSE);
+ gtk_container_set_border_width (GTK_CONTAINER (dialog), 5);
+ gtk_box_set_spacing (GTK_BOX (dialog->vbox), 2); /* 2 * 5 + 2 = 12 */
+ gtk_container_set_border_width (GTK_CONTAINER (dialog->action_area), 5);
+ gtk_box_set_spacing (GTK_BOX (dialog->action_area), 6);
+
+ gtk_window_set_title (GTK_WINDOW (dialog), _("Enter password"));
+ gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE);
+ gtk_window_set_icon_name (GTK_WINDOW (dialog), GTK_STOCK_DIALOG_AUTHENTICATION);
+ gtk_window_set_transient_for (GTK_WINDOW (dialog), password_view->priv->parent_window);
+ gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
+
+ gtk_dialog_add_buttons (dialog,
+ GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+ _("_Unlock Document"), GTK_RESPONSE_OK,
+ NULL);
+ gtk_dialog_set_default_response (dialog, GTK_RESPONSE_OK);
+ gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog),
+ GTK_RESPONSE_OK, FALSE);
+ gtk_dialog_set_alternative_button_order (dialog,
+ GTK_RESPONSE_OK,
+ GTK_RESPONSE_CANCEL,
+ -1);
+
+ /* Build contents */
+ hbox = gtk_hbox_new (FALSE, 12);
+ gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
+ gtk_box_pack_start (GTK_BOX (dialog->vbox), hbox, TRUE, TRUE, 0);
+ gtk_widget_show (hbox);
+
+ icon = gtk_image_new_from_stock (GTK_STOCK_DIALOG_AUTHENTICATION,
+ GTK_ICON_SIZE_DIALOG);
+
+ gtk_misc_set_alignment (GTK_MISC (icon), 0.5, 0.0);
+ gtk_box_pack_start (GTK_BOX (hbox), icon, FALSE, FALSE, 0);
+ gtk_widget_show (icon);
+
+ main_vbox = gtk_vbox_new (FALSE, 18);
+ gtk_box_pack_start (GTK_BOX (hbox), main_vbox, TRUE, TRUE, 0);
+ gtk_widget_show (main_vbox);
+ label = gtk_label_new (NULL);
+ gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+ gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
+ file_name = g_file_get_basename (password_view->priv->uri_file);
+ format = g_strdup_printf ("<span size=\"larger\" weight=\"bold\">%s</span>\n\n%s",
+ _("Password required"),
+ _("The document ā€œ%sā€ is locked and requires a password before it can be opened."));
+ markup = g_markup_printf_escaped (format, file_name);
+ gtk_label_set_markup (GTK_LABEL (label), markup);
+ g_free (format);
g_free (markup);
+ g_free (file_name);
+ gtk_box_pack_start (GTK_BOX (main_vbox), label,
+ FALSE, FALSE, 0);
+ gtk_widget_show (label);
+
+ vbox = gtk_vbox_new (FALSE, 6);
+ gtk_box_pack_start (GTK_BOX (main_vbox), vbox, FALSE, FALSE, 0);
+ gtk_widget_show (vbox);
+
+ /* The table that holds the entries */
+ entry_container = gtk_alignment_new (0.0, 0.0, 1.0, 1.0);
+
+ gtk_alignment_set_padding (GTK_ALIGNMENT (entry_container),
+ 0, 0, 0, 0);
+
+ gtk_box_pack_start (GTK_BOX (vbox), entry_container,
+ FALSE, FALSE, 0);
+ gtk_widget_show (entry_container);
+
+ table = gtk_table_new (1, 2, FALSE);
+ gtk_table_set_col_spacings (GTK_TABLE (table), 12);
+ gtk_table_set_row_spacings (GTK_TABLE (table), 6);
+ gtk_container_add (GTK_CONTAINER (entry_container), table);
+ gtk_widget_show (table);
+
+ label = gtk_label_new_with_mnemonic (_("_Password:"));
+ gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+
+ password_view->priv->password_entry = gtk_entry_new ();
+ gtk_entry_set_visibility (GTK_ENTRY (password_view->priv->password_entry), FALSE);
+ g_signal_connect (password_view->priv->password_entry, "changed",
+ G_CALLBACK (ev_password_dialog_entry_changed_cb),
+ dialog);
+ g_signal_connect (password_view->priv->password_entry, "activate",
+ G_CALLBACK (ev_password_dialog_entry_activated_cb),
+ dialog);
+ gtk_table_attach (GTK_TABLE (table), label,
+ 0, 1, 0, 1,
+ GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
+ gtk_widget_show (label);
+
+ gtk_table_attach_defaults (GTK_TABLE (table), password_view->priv->password_entry,
+ 1, 2, 0, 1);
+ gtk_widget_show (password_view->priv->password_entry);
+
+ gtk_label_set_mnemonic_widget (GTK_LABEL (label),
+ password_view->priv->password_entry);
+
+ if (ev_keyring_is_available ()) {
+ GtkWidget *choice;
+ GtkWidget *remember_box;
+ GSList *group;
+
+ remember_box = gtk_vbox_new (FALSE, 6);
+ gtk_box_pack_start (GTK_BOX (vbox), remember_box,
+ FALSE, FALSE, 0);
+ gtk_widget_show (remember_box);
+
+ choice = gtk_radio_button_new_with_mnemonic (NULL, _("Forget password _immediately"));
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (choice),
+ password_view->priv->password_save == G_PASSWORD_SAVE_NEVER);
+ g_object_set_data (G_OBJECT (choice), "password-save",
+ GINT_TO_POINTER (G_PASSWORD_SAVE_NEVER));
+ g_signal_connect (choice, "toggled",
+ G_CALLBACK (ev_password_dialog_remember_button_toggled),
+ password_view);
+ gtk_box_pack_start (GTK_BOX (remember_box), choice, FALSE, FALSE, 0);
+ gtk_widget_show (choice);
+
+ group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (choice));
+ choice = gtk_radio_button_new_with_mnemonic (group, _("Remember password until you _logout"));
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (choice),
+ password_view->priv->password_save == G_PASSWORD_SAVE_FOR_SESSION);
+ g_object_set_data (G_OBJECT (choice), "password-save",
+ GINT_TO_POINTER (G_PASSWORD_SAVE_FOR_SESSION));
+ g_signal_connect (choice, "toggled",
+ G_CALLBACK (ev_password_dialog_remember_button_toggled),
+ password_view);
+ gtk_box_pack_start (GTK_BOX (remember_box), choice, FALSE, FALSE, 0);
+ gtk_widget_show (choice);
+
+ group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (choice));
+ choice = gtk_radio_button_new_with_mnemonic (group, _("Remember _forever"));
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (choice),
+ password_view->priv->password_save == G_PASSWORD_SAVE_PERMANENTLY);
+ g_object_set_data (G_OBJECT (choice), "password-save",
+ GINT_TO_POINTER (G_PASSWORD_SAVE_PERMANENTLY));
+ g_signal_connect (choice, "toggled",
+ G_CALLBACK (ev_password_dialog_remember_button_toggled),
+ password_view);
+ gtk_box_pack_start (GTK_BOX (remember_box), choice, FALSE, FALSE, 0);
+ gtk_widget_show (choice);
+ }
+
+ g_signal_connect (G_OBJECT (dialog), "response",
+ G_CALLBACK (ev_password_dialog_got_response),
+ password_view);
+
+ gtk_widget_show (GTK_WIDGET (dialog));
+}
+
+const gchar *
+ev_password_view_get_password (EvPasswordView *password_view)
+{
+ return password_view->priv->password;
+}
+
+GPasswordSave
+ev_password_view_get_password_save_flags (EvPasswordView *password_view)
+{
+ return password_view->priv->password_save;
}
GtkWidget *
-ev_password_view_new (void)
+ev_password_view_new (GtkWindow *parent)
{
- GtkWidget *retval;
+ EvPasswordView *retval;
+
+ retval = EV_PASSWORD_VIEW (g_object_new (EV_TYPE_PASSWORD_VIEW, NULL));
- retval = (GtkWidget *) g_object_new (EV_TYPE_PASSWORD_VIEW, NULL);
+ retval->priv->parent_window = parent;
- return retval;
+ return GTK_WIDGET (retval);
}
+
diff --git a/shell/ev-password-view.h b/shell/ev-password-view.h
index d59d62b..7f2670b 100644
--- a/shell/ev-password-view.h
+++ b/shell/ev-password-view.h
@@ -21,6 +21,7 @@
#define __EV_PASSWORD_VIEW_H__
#include <gtk/gtk.h>
+#include <gio/gio.h>
G_BEGIN_DECLS
@@ -34,6 +35,7 @@ typedef struct _EvPasswordViewPrivate EvPasswordViewPrivate;
struct _EvPasswordView {
GtkViewport parent_instance;
+
EvPasswordViewPrivate *priv;
};
@@ -44,11 +46,13 @@ struct _EvPasswordViewClass {
void (*unlock) (EvPasswordView *self);
};
-GType ev_password_view_get_type (void) G_GNUC_CONST;
-GtkWidget *ev_password_view_new (void);
-void ev_password_view_set_file_name (EvPasswordView *password_view,
- const char *file_name);
-
+GType ev_password_view_get_type (void) G_GNUC_CONST;
+GtkWidget *ev_password_view_new (GtkWindow *parent);
+void ev_password_view_set_uri (EvPasswordView *password_view,
+ const char *uri);
+void ev_password_view_ask_password (EvPasswordView *password_view);
+const gchar *ev_password_view_get_password (EvPasswordView *password_view);
+GPasswordSave ev_password_view_get_password_save_flags (EvPasswordView *password_view);
G_END_DECLS
diff --git a/shell/ev-password.c b/shell/ev-password.c
deleted file mode 100644
index a191b9f..0000000
--- a/shell/ev-password.c
+++ /dev/null
@@ -1,350 +0,0 @@
-/* this file is part of evince, a gnome document viewer
- *
- * Copyright (C) 2005 Red Hat, Inc
- *
- * Evince is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * Evince is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <glib/gi18n.h>
-#include <gio/gio.h>
-#include <gtk/gtk.h>
-#include <glade/glade.h>
-
-#ifdef WITH_KEYRING
-#include <gnome-keyring.h>
-#else
-#define gnome_keyring_is_available() FALSE
-#endif
-
-#include "ev-password.h"
-
-enum {
- PROP_0,
- PROP_URI,
-};
-
-struct _EvPasswordDialogPrivate {
-
- gchar *uri;
-
- GtkWidget *bad_label;
- GtkWidget *label;
- GtkWidget *entry;
- GtkWidget *check_default;
- GtkWidget *check_session;
-};
-
-#define EV_PASSWORD_DIALOG_GET_PRIVATE(object) \
- (G_TYPE_INSTANCE_GET_PRIVATE ((object), EV_TYPE_PASSWORD_DIALOG, EvPasswordDialogPrivate));
-
-G_DEFINE_TYPE (EvPasswordDialog, ev_password_dialog, GTK_TYPE_DIALOG)
-
-
-static void ev_password_dialog_entry_changed_cb (GtkEditable *editable,
- EvPasswordDialog *dialog);
-static void ev_password_dialog_entry_activated_cb (GtkEntry *entry,
- EvPasswordDialog *dialog);
-static void ev_password_set_bad_password_label (EvPasswordDialog *dialog,
- gchar *message);
-static void ev_password_search_in_keyring (EvPasswordDialog *dialog,
- const gchar *uri);
-
-static void
-ev_password_dialog_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- EvPasswordDialog *dialog = EV_PASSWORD_DIALOG (object);
- char *format;
- char *markup;
- char *base_name;
- GFile *file;
-
- switch (prop_id) {
- case PROP_URI:
- dialog->priv->uri = g_strdup (g_value_get_string (value));
-
- file = g_file_new_for_uri (dialog->priv->uri);
-
- base_name = g_file_get_basename (file);
- format = g_strdup_printf ("<span size=\"larger\" weight=\"bold\">%s</span>\n\n%s",
- _("Password required"),
- _("The document ā€œ%sā€ is locked and requires a password before it can be opened."));
- markup = g_markup_printf_escaped (format, base_name);
-
- gtk_label_set_markup (GTK_LABEL (dialog->priv->label), markup);
-
- g_free (base_name);
- g_free (format);
- g_free (markup);
- g_object_unref (file);
-
- ev_password_search_in_keyring (dialog, dialog->priv->uri);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-ev_password_dialog_finalize (GObject *object)
-{
- EvPasswordDialog *dialog = EV_PASSWORD_DIALOG (object);
-
- if (dialog->priv->uri) {
- g_free (dialog->priv->uri);
- dialog->priv->uri = NULL;
- }
-
- G_OBJECT_CLASS (ev_password_dialog_parent_class)->finalize (object);
-}
-
-
-static void
-ev_password_dialog_class_init (EvPasswordDialogClass *class)
-{
- GObjectClass *g_object_class;
- GtkWidgetClass *widget_class;
-
- g_object_class = G_OBJECT_CLASS (class);
- widget_class = GTK_WIDGET_CLASS (class);
-
- g_type_class_add_private (g_object_class, sizeof (EvPasswordDialogPrivate));
-
- g_object_class->set_property = ev_password_dialog_set_property;
- g_object_class->finalize = ev_password_dialog_finalize;
-
- g_object_class_install_property (g_object_class,
- PROP_URI,
- g_param_spec_string ("uri",
- "Document URI",
- "Encrypted document URI",
- NULL,
- G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
-}
-
-
-static void
-ev_password_dialog_init (EvPasswordDialog *dialog)
-{
- GtkWidget *hbox;
- const char *glade_file = DATADIR "/evince-password.glade";
- GladeXML *xml;
-
- dialog->priv = EV_PASSWORD_DIALOG_GET_PRIVATE (dialog);
-
- gtk_window_set_title (GTK_WINDOW (dialog), _("Enter password"));
- gtk_window_set_destroy_with_parent (GTK_WINDOW (dialog), TRUE);
- gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE);
- gtk_container_set_border_width (GTK_CONTAINER (dialog), 5);
- gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (dialog)->vbox), 12);
-
- gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_CANCEL,
- GTK_RESPONSE_CANCEL);
- gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_OK,
- GTK_RESPONSE_OK);
-
- xml = glade_xml_new (glade_file, "hbox-contents", NULL);
- g_assert (xml);
-
- hbox = glade_xml_get_widget (xml, "hbox-contents");
- gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), hbox);
-
- dialog->priv->bad_label = glade_xml_get_widget (xml, "bad_password_label");
- dialog->priv->check_default = glade_xml_get_widget (xml, "savesession_checkbutton");
- dialog->priv->check_session = glade_xml_get_widget (xml, "savekeyring_checkbutton");
- dialog->priv->entry = glade_xml_get_widget (xml, "password_entry");
- dialog->priv->label = glade_xml_get_widget (xml, "password_label");
-
- g_signal_connect (dialog->priv->entry, "changed", G_CALLBACK (ev_password_dialog_entry_changed_cb), dialog);
- g_signal_connect (dialog->priv->entry, "activate", G_CALLBACK (ev_password_dialog_entry_activated_cb), dialog);
-
- ev_password_set_bad_password_label (dialog, " ");
-
- if (!gnome_keyring_is_available ()) {
- gtk_widget_hide (dialog->priv->check_default);
- gtk_widget_hide (dialog->priv->check_session);
- }
-
- g_object_unref (xml);
-}
-
-static void
-ev_password_set_bad_password_label (EvPasswordDialog *dialog,
- gchar *message)
-{
- gchar *markup;
-
- markup = g_strdup_printf ("<span color=\"red\" size=\"smaller\">%s</span>",
- message);
- gtk_label_set_markup (GTK_LABEL (dialog->priv->bad_label), markup);
- g_free (markup);
-}
-
-static void
-ev_password_dialog_entry_changed_cb (GtkEditable *editable,
- EvPasswordDialog *dialog)
-{
- const char *text;
-
- text = gtk_entry_get_text (GTK_ENTRY (editable));
-
- if (text == NULL || *text == '\0')
- gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog),
- GTK_RESPONSE_OK, FALSE);
- else
- gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog),
- GTK_RESPONSE_OK, TRUE);
-
- ev_password_set_bad_password_label (dialog, " ");
-}
-
-static void
-ev_password_dialog_entry_activated_cb (GtkEntry *entry,
- EvPasswordDialog *dialog)
-{
- gtk_dialog_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
-}
-
-#ifdef WITH_KEYRING
-static void
-ev_password_item_created_callback (GnomeKeyringResult result,
- guint32 val,
- gpointer data)
-{
- /* Nothing yet */
- return;
-}
-#endif
-
-void
-ev_password_dialog_save_password (EvPasswordDialog *dialog)
-{
-#ifdef WITH_KEYRING
- GnomeKeyringAttributeList *attributes;
- GnomeKeyringAttribute attribute;
- gchar *name;
- gchar *unescaped_uri;
-
- attributes = gnome_keyring_attribute_list_new ();
-
- attribute.name = g_strdup ("type");
- attribute.type = GNOME_KEYRING_ATTRIBUTE_TYPE_STRING;
- attribute.value.string = g_strdup ("document_password");
- g_array_append_val (attributes, attribute);
-
- attribute.name = g_strdup ("uri");
- attribute.type = GNOME_KEYRING_ATTRIBUTE_TYPE_STRING;
- attribute.value.string = g_strdup (dialog->priv->uri);
- g_array_append_val (attributes, attribute);
-
- unescaped_uri = g_uri_unescape_string (dialog->priv->uri, NULL);
- name = g_strdup_printf (_("Password for document %s"), unescaped_uri);
-
- if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dialog->priv->check_default))) {
- gnome_keyring_item_create (NULL,
- GNOME_KEYRING_ITEM_GENERIC_SECRET,
- name,
- attributes,
- ev_password_dialog_get_password (dialog),
- TRUE, ev_password_item_created_callback,
- NULL, NULL);
- }
-
- if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dialog->priv->check_session))) {
- gnome_keyring_item_create ("session",
- GNOME_KEYRING_ITEM_GENERIC_SECRET,
- name,
- attributes,
- ev_password_dialog_get_password (dialog),
- TRUE, ev_password_item_created_callback,
- NULL, NULL);
- }
-
- gnome_keyring_attribute_list_free (attributes);
- g_free (name);
- g_free (unescaped_uri);
-
-#endif /* WITH_KEYRING */
- return;
-}
-
-#ifdef WITH_KEYRING
-static void
-ev_password_keyring_found_cb (GnomeKeyringResult result,
- GList *list,
- gpointer data)
-
-{
- GnomeKeyringFound *found;
- EvPasswordDialog *dialog = EV_PASSWORD_DIALOG (data);
-
- if (result != GNOME_KEYRING_RESULT_OK || list == NULL)
- return;
-
- found = list->data;
- gtk_entry_set_text (GTK_ENTRY (dialog->priv->entry), found->secret);
-}
-#endif /* WITH_KEYRING */
-
-static void
-ev_password_search_in_keyring (EvPasswordDialog *dialog, const gchar *uri)
-{
-#ifdef WITH_KEYRING
- GnomeKeyringAttributeList *attributes;
- GnomeKeyringAttribute attribute;
-
- attributes = gnome_keyring_attribute_list_new ();
-
- attribute.name = g_strdup ("type");
- attribute.type = GNOME_KEYRING_ATTRIBUTE_TYPE_STRING;
- attribute.value.string = g_strdup ("document_password");
- g_array_append_val (attributes, attribute);
-
- attribute.name = g_strdup ("uri");
- attribute.type = GNOME_KEYRING_ATTRIBUTE_TYPE_STRING;
- attribute.value.string = g_strdup (uri);
- g_array_append_val (attributes, attribute);
-
- gnome_keyring_find_items (GNOME_KEYRING_ITEM_GENERIC_SECRET,
- attributes,
- ev_password_keyring_found_cb,
- g_object_ref (dialog),
- g_object_unref);
- gnome_keyring_attribute_list_free (attributes);
-#endif /* WITH_KEYRING */
- return;
-}
-
-const char *
-ev_password_dialog_get_password (EvPasswordDialog *dialog)
-{
- return gtk_entry_get_text (GTK_ENTRY (dialog->priv->entry));
-}
-
-void
-ev_password_dialog_set_bad_pass (EvPasswordDialog *dialog)
-{
- gtk_entry_set_text (GTK_ENTRY (dialog->priv->entry), "");
- ev_password_set_bad_password_label (dialog, _("Incorrect password"));
-}
-
-
diff --git a/shell/ev-password.h b/shell/ev-password.h
deleted file mode 100644
index d092cca..0000000
--- a/shell/ev-password.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/* this file is part of evince, a gnome document viewer
- *
- * Copyright (C) 2005 Red Hat, Inc
- *
- * Evince is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * Evince is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#ifndef __EV_PASSWORD_H__
-#define __EV_PASSWORD_H__
-
-#include <gtk/gtk.h>
-
-G_BEGIN_DECLS
-
-#define EV_TYPE_PASSWORD_DIALOG (ev_password_dialog_get_type ())
-#define EV_PASSWORD_DIALOG(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), EV_TYPE_PASSWORD_DIALOG, EvPasswordDialog))
-#define EV_PASSWORD_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EV_TYPE_PASSWORD_DIALOG, EvPasswordDialogClass))
-#define EV_IS_PASSWORD_DIALOG(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), EV_TYPE_PASSWORD_DIALOG))
-#define EV_IS_PASSWORD_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EV_TYPE_PASSWORD_DIALOG))
-#define EV_PASSWORD_DIALOG_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EV_TYPE_PASSWORD_DIALOG, EvPasswordDialogClass))
-
-typedef struct _EvPasswordDialog EvPasswordDialog;
-typedef struct _EvPasswordDialogClass EvPasswordDialogClass;
-typedef struct _EvPasswordDialogPrivate EvPasswordDialogPrivate;
-
-struct _EvPasswordDialog
-{
- GtkDialog parent_instance;
-
- EvPasswordDialogPrivate* priv;
-};
-
-struct _EvPasswordDialogClass
-{
- GtkDialogClass parent_class;
-};
-
-GType ev_password_dialog_get_type (void) G_GNUC_CONST;
-
-const char *ev_password_dialog_get_password (EvPasswordDialog *dialog);
-void ev_password_dialog_set_bad_pass (EvPasswordDialog *dialog);
-void ev_password_dialog_save_password (EvPasswordDialog *dialog);
-
-G_END_DECLS
-
-#endif /* __EV_PASSWORD_H__ */
diff --git a/shell/ev-window.c b/shell/ev-window.c
index 47ce4c7..c570de7 100644
--- a/shell/ev-window.c
+++ b/shell/ev-window.c
@@ -73,7 +73,6 @@
#include "ev-navigation-action.h"
#include "ev-open-recent-action.h"
#include "ev-page-action.h"
-#include "ev-password.h"
#include "ev-password-view.h"
#include "ev-properties-dialog.h"
#include "ev-sidebar-attachments.h"
@@ -84,6 +83,7 @@
#include "ev-sidebar-layers.h"
#include "ev-stock-icons.h"
#include "ev-utils.h"
+#include "ev-keyring.h"
#include "ev-view.h"
#include "ev-window.h"
#include "ev-window-title.h"
@@ -135,7 +135,6 @@ struct _EvWindowPrivate {
/* Dialogs */
GtkWidget *properties;
GtkWidget *print_dialog;
- GtkWidget *password_dialog;
/* UI Builders */
GtkActionGroup *action_group;
@@ -1256,57 +1255,15 @@ ev_window_document_changed (EvWindow *ev_window,
}
static void
-password_dialog_response (GtkWidget *password_dialog,
- gint response_id,
- EvWindow *ev_window)
-{
- if (response_id == GTK_RESPONSE_OK) {
- ev_job_load_set_password (EV_JOB_LOAD (ev_window->priv->load_job),
- ev_password_dialog_get_password (EV_PASSWORD_DIALOG (password_dialog)));
-
- ev_password_dialog_save_password (EV_PASSWORD_DIALOG (password_dialog));
-
- ev_window_title_set_type (ev_window->priv->title, EV_WINDOW_TITLE_DOCUMENT);
- ev_job_scheduler_push_job (ev_window->priv->load_job, EV_JOB_PRIORITY_NONE);
-
- gtk_widget_destroy (password_dialog);
-
- return;
- }
-
- gtk_widget_set_sensitive (ev_window->priv->password_view, TRUE);
- gtk_widget_destroy (password_dialog);
-}
-
-/* Called either by ev_window_load_job_cb or by the "unlock" callback on the
- * password_view page. It assumes that ev_window->priv->password_* has been set
- * correctly. These are cleared by password_dialog_response() */
-
-static void
-ev_window_popup_password_dialog (EvWindow *ev_window)
+ev_window_password_view_unlock (EvWindow *ev_window)
{
+ const gchar *password;
+
g_assert (ev_window->priv->load_job);
- gtk_widget_set_sensitive (ev_window->priv->password_view, FALSE);
-
- ev_window_title_set_uri (ev_window->priv->title, ev_window->priv->uri);
- ev_window_title_set_type (ev_window->priv->title, EV_WINDOW_TITLE_PASSWORD);
-
- if (ev_window->priv->password_dialog == NULL) {
- ev_window->priv->password_dialog =
- g_object_new (EV_TYPE_PASSWORD_DIALOG, "uri", ev_window->priv->uri, NULL);
- gtk_window_set_transient_for (GTK_WINDOW (ev_window->priv->password_dialog), GTK_WINDOW (ev_window));
-
- g_object_add_weak_pointer (G_OBJECT (ev_window->priv->password_dialog),
- (gpointer) &(ev_window->priv->password_dialog));
- g_signal_connect (ev_window->priv->password_dialog,
- "response",
- G_CALLBACK (password_dialog_response),
- ev_window);
- gtk_widget_show (ev_window->priv->password_dialog);
- } else {
- ev_password_dialog_set_bad_pass (EV_PASSWORD_DIALOG (ev_window->priv->password_dialog));
- }
+ password = ev_password_view_get_password (EV_PASSWORD_VIEW (ev_window->priv->password_view));
+ ev_job_load_set_password (EV_JOB_LOAD (ev_window->priv->load_job), password);
+ ev_job_scheduler_push_job (ev_window->priv->load_job, EV_JOB_PRIORITY_NONE);
}
static void
@@ -1406,6 +1363,18 @@ ev_window_load_job_cb (EvJob *job,
ev_window_add_recent (ev_window, ev_window->priv->uri);
}
+ ev_window_title_set_type (ev_window->priv->title,
+ EV_WINDOW_TITLE_DOCUMENT);
+ if (job_load->password) {
+ GPasswordSave flags;
+
+ flags = ev_password_view_get_password_save_flags (
+ EV_PASSWORD_VIEW (ev_window->priv->password_view));
+ ev_keyring_save_password (ev_window->priv->uri,
+ job_load->password,
+ flags);
+ }
+
if (job_load->dest) {
EvLink *link;
EvLinkAction *link_action;
@@ -1448,20 +1417,40 @@ ev_window_load_job_cb (EvJob *job,
if (job->error->domain == EV_DOCUMENT_ERROR &&
job->error->code == EV_DOCUMENT_ERROR_ENCRYPTED) {
- GFile *file;
- gchar *base_name;
-
+ gchar *password;
+
setup_view_from_metadata (ev_window);
+
+ /* First look whether password is in keyring */
+ password = ev_keyring_lookup_password (ev_window->priv->uri);
+ if (password) {
+ if (job_load->password && strcmp (password, job_load->password) == 0) {
+ /* Password in kering is wrong */
+ ev_job_load_set_password (job_load, NULL);
+ /* FIXME: delete password from keyring? */
+ } else {
+ ev_job_load_set_password (job_load, password);
+ ev_job_scheduler_push_job (job, EV_JOB_PRIORITY_NONE);
+ g_free (password);
+ return;
+ }
+
+ g_free (password);
+ }
+
+ /* We need to ask the user for a password */
+ ev_window_title_set_uri (ev_window->priv->title,
+ ev_window->priv->uri);
+ ev_window_title_set_type (ev_window->priv->title,
+ EV_WINDOW_TITLE_PASSWORD);
+
+ ev_password_view_set_uri (EV_PASSWORD_VIEW (ev_window->priv->password_view),
+ job_load->uri);
- file = g_file_new_for_uri (job_load->uri);
- base_name = g_file_get_basename (file);
- ev_password_view_set_file_name (EV_PASSWORD_VIEW (ev_window->priv->password_view),
- base_name);
- g_object_unref (file);
- g_free (base_name);
ev_window_set_page_mode (ev_window, PAGE_MODE_PASSWORD);
-
- ev_window_popup_password_dialog (ev_window);
+
+ ev_job_load_set_password (job_load, NULL);
+ ev_password_view_ask_password (EV_PASSWORD_VIEW (ev_window->priv->password_view));
} else {
ev_window_error_message (ev_window, job->error,
"%s", _("Unable to open document"));
@@ -1518,10 +1507,6 @@ ev_window_get_uri (EvWindow *ev_window)
static void
ev_window_close_dialogs (EvWindow *ev_window)
{
- if (ev_window->priv->password_dialog)
- gtk_widget_destroy (ev_window->priv->password_dialog);
- ev_window->priv->password_dialog = NULL;
-
if (ev_window->priv->print_dialog)
gtk_widget_destroy (ev_window->priv->print_dialog);
ev_window->priv->print_dialog = NULL;
@@ -5650,10 +5635,10 @@ ev_window_init (EvWindow *ev_window)
ev_window->priv->view = ev_view_new ();
ev_view_set_screen_dpi (EV_VIEW (ev_window->priv->view),
get_screen_dpi (GTK_WINDOW (ev_window)));
- ev_window->priv->password_view = ev_password_view_new ();
+ ev_window->priv->password_view = ev_password_view_new (GTK_WINDOW (ev_window));
g_signal_connect_swapped (ev_window->priv->password_view,
"unlock",
- G_CALLBACK (ev_window_popup_password_dialog),
+ G_CALLBACK (ev_window_password_view_unlock),
ev_window);
g_signal_connect_object (ev_window->priv->view, "focus_in_event",
G_CALLBACK (view_actions_focus_in_cb),