1 /* this file is part of evince, a gnome document viewer
3 * Copyright (C) 2005 Red Hat, Inc
5 * Evince is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * Evince is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
24 #include <glib/gi18n.h>
26 #include <glade/glade.h>
27 #include <gnome-keyring.h>
28 #include <libgnomevfs/gnome-vfs-utils.h>
30 #include "ev-password.h"
37 struct _EvPasswordDialogPrivate {
44 GtkWidget *check_default;
45 GtkWidget *check_session;
48 #define EV_PASSWORD_DIALOG_GET_PRIVATE(object) \
49 (G_TYPE_INSTANCE_GET_PRIVATE ((object), EV_TYPE_PASSWORD_DIALOG, EvPasswordDialogPrivate));
51 G_DEFINE_TYPE (EvPasswordDialog, ev_password_dialog, GTK_TYPE_DIALOG)
54 static void ev_password_dialog_entry_changed_cb (GtkEditable *editable,
55 EvPasswordDialog *dialog);
56 static void ev_password_dialog_entry_activated_cb (GtkEntry *entry,
57 EvPasswordDialog *dialog);
58 static void ev_password_set_bad_password_label (EvPasswordDialog *dialog,
60 static void ev_password_search_in_keyring (EvPasswordDialog *dialog,
64 ev_password_dialog_set_property (GObject *object,
69 EvPasswordDialog *dialog = EV_PASSWORD_DIALOG (object);
78 dialog->priv->uri = g_strdup (g_value_get_string (value));
80 file_name = gnome_vfs_format_uri_for_display (dialog->priv->uri);
81 base_name = g_path_get_basename (file_name);
82 format = g_strdup_printf ("<span size=\"larger\" weight=\"bold\">%s</span>\n\n%s",
83 _("Password required"),
84 _("The document ā%sā is locked and requires a password before it can be opened."));
85 markup = g_markup_printf_escaped (format, base_name);
87 gtk_label_set_markup (GTK_LABEL (dialog->priv->label), markup);
94 ev_password_search_in_keyring (dialog, dialog->priv->uri);
97 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
103 ev_password_dialog_finalize (GObject *object)
105 EvPasswordDialog *dialog = EV_PASSWORD_DIALOG (object);
107 if (dialog->priv->uri) {
108 g_free (dialog->priv->uri);
109 dialog->priv->uri = NULL;
112 G_OBJECT_CLASS (ev_password_dialog_parent_class)->finalize (object);
117 ev_password_dialog_class_init (EvPasswordDialogClass *class)
119 GObjectClass *g_object_class;
120 GtkWidgetClass *widget_class;
122 g_object_class = G_OBJECT_CLASS (class);
123 widget_class = GTK_WIDGET_CLASS (class);
125 g_type_class_add_private (g_object_class, sizeof (EvPasswordDialogPrivate));
127 g_object_class->set_property = ev_password_dialog_set_property;
128 g_object_class->finalize = ev_password_dialog_finalize;
130 g_object_class_install_property (g_object_class,
132 g_param_spec_string ("uri",
134 "Encrypted document URI",
136 G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
141 ev_password_dialog_init (EvPasswordDialog *dialog)
144 const char *glade_file = DATADIR "/evince-password.glade";
147 dialog->priv = EV_PASSWORD_DIALOG_GET_PRIVATE (dialog);
149 gtk_window_set_title (GTK_WINDOW (dialog), _("Enter password"));
150 gtk_window_set_destroy_with_parent (GTK_WINDOW (dialog), TRUE);
151 gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE);
152 gtk_container_set_border_width (GTK_CONTAINER (dialog), 5);
153 gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (dialog)->vbox), 12);
155 gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_CANCEL,
156 GTK_RESPONSE_CANCEL);
157 gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_OK,
160 xml = glade_xml_new (glade_file, "hbox-contents", NULL);
163 hbox = glade_xml_get_widget (xml, "hbox-contents");
164 gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), hbox);
166 dialog->priv->bad_label = glade_xml_get_widget (xml, "bad_password_label");
167 dialog->priv->check_default = glade_xml_get_widget (xml, "savesession_checkbutton");
168 dialog->priv->check_session = glade_xml_get_widget (xml, "savekeyring_checkbutton");
169 dialog->priv->entry = glade_xml_get_widget (xml, "password_entry");
170 dialog->priv->label = glade_xml_get_widget (xml, "password_label");
172 g_signal_connect (dialog->priv->entry, "changed", G_CALLBACK (ev_password_dialog_entry_changed_cb), dialog);
173 g_signal_connect (dialog->priv->entry, "activate", G_CALLBACK (ev_password_dialog_entry_activated_cb), dialog);
175 ev_password_set_bad_password_label (dialog, " ");
177 if (!gnome_keyring_is_available ()) {
178 gtk_widget_hide (dialog->priv->check_default);
179 gtk_widget_hide (dialog->priv->check_session);
182 g_object_unref (xml);
186 ev_password_set_bad_password_label (EvPasswordDialog *dialog,
191 markup = g_strdup_printf ("<span color=\"red\" size=\"smaller\">%s</span>",
193 gtk_label_set_markup (GTK_LABEL (dialog->priv->bad_label), markup);
198 ev_password_dialog_entry_changed_cb (GtkEditable *editable,
199 EvPasswordDialog *dialog)
203 text = gtk_entry_get_text (GTK_ENTRY (editable));
205 if (text == NULL || *text == '\0')
206 gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog),
207 GTK_RESPONSE_OK, FALSE);
209 gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog),
210 GTK_RESPONSE_OK, TRUE);
212 ev_password_set_bad_password_label (dialog, " ");
216 ev_password_dialog_entry_activated_cb (GtkEntry *entry,
217 EvPasswordDialog *dialog)
219 gtk_dialog_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
223 ev_password_item_created_callback (GnomeKeyringResult result,
232 ev_password_dialog_save_password (EvPasswordDialog *dialog)
234 GnomeKeyringAttributeList *attributes;
235 GnomeKeyringAttribute attribute;
237 gchar *unescaped_uri;
239 attributes = gnome_keyring_attribute_list_new ();
241 attribute.name = g_strdup ("type");
242 attribute.type = GNOME_KEYRING_ATTRIBUTE_TYPE_STRING;
243 attribute.value.string = g_strdup ("document_password");
244 g_array_append_val (attributes, attribute);
246 attribute.name = g_strdup ("uri");
247 attribute.type = GNOME_KEYRING_ATTRIBUTE_TYPE_STRING;
248 attribute.value.string = g_strdup (dialog->priv->uri);
249 g_array_append_val (attributes, attribute);
251 unescaped_uri = gnome_vfs_unescape_string_for_display (dialog->priv->uri);
252 name = g_strdup_printf (_("Password for document %s"), unescaped_uri);
254 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dialog->priv->check_default))) {
255 gnome_keyring_item_create (NULL,
256 GNOME_KEYRING_ITEM_GENERIC_SECRET,
259 ev_password_dialog_get_password (dialog),
260 TRUE, ev_password_item_created_callback,
264 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dialog->priv->check_session))) {
265 gnome_keyring_item_create ("session",
266 GNOME_KEYRING_ITEM_GENERIC_SECRET,
269 ev_password_dialog_get_password (dialog),
270 TRUE, ev_password_item_created_callback,
274 gnome_keyring_attribute_list_free (attributes);
276 g_free (unescaped_uri);
282 ev_password_keyring_found_cb (GnomeKeyringResult result,
287 GnomeKeyringFound *found;
288 EvPasswordDialog *dialog = EV_PASSWORD_DIALOG (data);
290 if (result != GNOME_KEYRING_RESULT_OK || list == NULL)
294 gtk_entry_set_text (GTK_ENTRY (dialog->priv->entry), found->secret);
298 ev_password_search_in_keyring (EvPasswordDialog *dialog, const gchar *uri)
300 GnomeKeyringAttributeList *attributes;
301 GnomeKeyringAttribute attribute;
303 attributes = gnome_keyring_attribute_list_new ();
305 attribute.name = g_strdup ("type");
306 attribute.type = GNOME_KEYRING_ATTRIBUTE_TYPE_STRING;
307 attribute.value.string = g_strdup ("document_password");
308 g_array_append_val (attributes, attribute);
310 attribute.name = g_strdup ("uri");
311 attribute.type = GNOME_KEYRING_ATTRIBUTE_TYPE_STRING;
312 attribute.value.string = g_strdup (uri);
313 g_array_append_val (attributes, attribute);
315 gnome_keyring_find_items (GNOME_KEYRING_ITEM_GENERIC_SECRET,
317 ev_password_keyring_found_cb,
318 g_object_ref (dialog),
320 gnome_keyring_attribute_list_free (attributes);
325 ev_password_dialog_get_password (EvPasswordDialog *dialog)
327 return g_strdup (gtk_entry_get_text (GTK_ENTRY (dialog->priv->entry)));
331 ev_password_dialog_set_bad_pass (EvPasswordDialog *dialog)
333 gtk_entry_set_text (GTK_ENTRY (dialog->priv->entry), "");
334 ev_password_set_bad_password_label (dialog, _("Incorrect password"));