evince r3281 - in trunk: . shell



Author: carlosgc
Date: Mon Dec  1 11:16:43 2008
New Revision: 3281
URL: http://svn.gnome.org/viewvc/evince?rev=3281&view=rev

Log:
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.

Added:
   trunk/shell/ev-keyring.c
   trunk/shell/ev-keyring.h
Removed:
   trunk/shell/ev-password.c
   trunk/shell/ev-password.h
Modified:
   trunk/ChangeLog
   trunk/configure.ac
   trunk/shell/Makefile.am
   trunk/shell/ev-password-view.c
   trunk/shell/ev-password-view.h
   trunk/shell/ev-window.c

Modified: trunk/configure.ac
==============================================================================
--- trunk/configure.ac	(original)
+++ trunk/configure.ac	Mon Dec  1 11:16:43 2008
@@ -47,7 +47,7 @@
 DBUS_GLIB_REQUIRED=0.70
 GTK_REQUIRED=2.12.0
 GLIB_REQUIRED=2.15.6
-KEYRING_REQUIRED=0.4.0
+KEYRING_REQUIRED=2.22.0
 
 GNOME_ICON_THEME_REQUIRED=2.17.1
 LIBXML_REQUIRED=2.5.0

Modified: trunk/shell/Makefile.am
==============================================================================
--- trunk/shell/Makefile.am	(original)
+++ trunk/shell/Makefile.am	Mon Dec  1 11:16:43 2008
@@ -38,6 +38,8 @@
 	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 @@
 	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		\

Added: trunk/shell/ev-keyring.c
==============================================================================
--- (empty file)
+++ trunk/shell/ev-keyring.c	Mon Dec  1 11:16:43 2008
@@ -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 */
+}

Added: trunk/shell/ev-keyring.h
==============================================================================
--- (empty file)
+++ trunk/shell/ev-keyring.h	Mon Dec  1 11:16:43 2008
@@ -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__ */

Modified: trunk/shell/ev-password-view.c
==============================================================================
--- trunk/shell/ev-password-view.c	(original)
+++ trunk/shell/ev-password-view.c	Mon Dec  1 11:16:43 2008
@@ -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 @@
 	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 @@
 
 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 @@
 	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 @@
 	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 @@
 	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);
+	g_return_if_fail (uri != NULL);
 
-	markup = g_markup_printf_escaped ("<span size=\"x-large\" weight=\"bold\">%s</span>", file_name);
+	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);
 }
+

Modified: trunk/shell/ev-password-view.h
==============================================================================
--- trunk/shell/ev-password-view.h	(original)
+++ trunk/shell/ev-password-view.h	Mon Dec  1 11:16:43 2008
@@ -21,6 +21,7 @@
 #define __EV_PASSWORD_VIEW_H__
 
 #include <gtk/gtk.h>
+#include <gio/gio.h>
 
 G_BEGIN_DECLS
 
@@ -34,6 +35,7 @@
 
 struct _EvPasswordView {
 	GtkViewport parent_instance;
+	
 	EvPasswordViewPrivate *priv;
 };
 
@@ -44,11 +46,13 @@
 	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
 

Modified: trunk/shell/ev-window.c
==============================================================================
--- trunk/shell/ev-window.c	(original)
+++ trunk/shell/ev-window.c	Mon Dec  1 11:16:43 2008
@@ -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 @@
 	/* Dialogs */
 	GtkWidget *properties;
 	GtkWidget *print_dialog;
-	GtkWidget *password_dialog;
 
 	/* UI Builders */
 	GtkActionGroup   *action_group;
@@ -1256,57 +1255,15 @@
 }
 
 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_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 @@
 
 	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 @@
 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->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),



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]