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>
27 #include <glade/glade.h>
30 #include <gnome-keyring.h>
32 #define gnome_keyring_is_available() FALSE
35 #include "ev-password.h"
42 struct _EvPasswordDialogPrivate {
49 GtkWidget *check_default;
50 GtkWidget *check_session;
53 #define EV_PASSWORD_DIALOG_GET_PRIVATE(object) \
54 (G_TYPE_INSTANCE_GET_PRIVATE ((object), EV_TYPE_PASSWORD_DIALOG, EvPasswordDialogPrivate));
56 G_DEFINE_TYPE (EvPasswordDialog, ev_password_dialog, GTK_TYPE_DIALOG)
59 static void ev_password_dialog_entry_changed_cb (GtkEditable *editable,
60 EvPasswordDialog *dialog);
61 static void ev_password_dialog_entry_activated_cb (GtkEntry *entry,
62 EvPasswordDialog *dialog);
63 static void ev_password_set_bad_password_label (EvPasswordDialog *dialog,
65 static void ev_password_search_in_keyring (EvPasswordDialog *dialog,
69 ev_password_dialog_set_property (GObject *object,
74 EvPasswordDialog *dialog = EV_PASSWORD_DIALOG (object);
82 dialog->priv->uri = g_strdup (g_value_get_string (value));
84 file = g_file_new_for_uri (dialog->priv->uri);
86 base_name = g_file_get_basename (file);
87 format = g_strdup_printf ("<span size=\"larger\" weight=\"bold\">%s</span>\n\n%s",
88 _("Password required"),
89 _("The document ā%sā is locked and requires a password before it can be opened."));
90 markup = g_markup_printf_escaped (format, base_name);
92 gtk_label_set_markup (GTK_LABEL (dialog->priv->label), markup);
97 g_object_unref (file);
99 ev_password_search_in_keyring (dialog, dialog->priv->uri);
102 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
108 ev_password_dialog_finalize (GObject *object)
110 EvPasswordDialog *dialog = EV_PASSWORD_DIALOG (object);
112 if (dialog->priv->uri) {
113 g_free (dialog->priv->uri);
114 dialog->priv->uri = NULL;
117 G_OBJECT_CLASS (ev_password_dialog_parent_class)->finalize (object);
122 ev_password_dialog_class_init (EvPasswordDialogClass *class)
124 GObjectClass *g_object_class;
125 GtkWidgetClass *widget_class;
127 g_object_class = G_OBJECT_CLASS (class);
128 widget_class = GTK_WIDGET_CLASS (class);
130 g_type_class_add_private (g_object_class, sizeof (EvPasswordDialogPrivate));
132 g_object_class->set_property = ev_password_dialog_set_property;
133 g_object_class->finalize = ev_password_dialog_finalize;
135 g_object_class_install_property (g_object_class,
137 g_param_spec_string ("uri",
139 "Encrypted document URI",
141 G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
146 ev_password_dialog_init (EvPasswordDialog *dialog)
149 const char *glade_file = DATADIR "/evince-password.glade";
152 dialog->priv = EV_PASSWORD_DIALOG_GET_PRIVATE (dialog);
154 gtk_window_set_title (GTK_WINDOW (dialog), _("Enter password"));
155 gtk_window_set_destroy_with_parent (GTK_WINDOW (dialog), TRUE);
156 gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE);
157 gtk_container_set_border_width (GTK_CONTAINER (dialog), 5);
158 gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (dialog)->vbox), 12);
160 gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_CANCEL,
161 GTK_RESPONSE_CANCEL);
162 gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_OK,
165 xml = glade_xml_new (glade_file, "hbox-contents", NULL);
168 hbox = glade_xml_get_widget (xml, "hbox-contents");
169 gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), hbox);
171 dialog->priv->bad_label = glade_xml_get_widget (xml, "bad_password_label");
172 dialog->priv->check_default = glade_xml_get_widget (xml, "savesession_checkbutton");
173 dialog->priv->check_session = glade_xml_get_widget (xml, "savekeyring_checkbutton");
174 dialog->priv->entry = glade_xml_get_widget (xml, "password_entry");
175 dialog->priv->label = glade_xml_get_widget (xml, "password_label");
177 g_signal_connect (dialog->priv->entry, "changed", G_CALLBACK (ev_password_dialog_entry_changed_cb), dialog);
178 g_signal_connect (dialog->priv->entry, "activate", G_CALLBACK (ev_password_dialog_entry_activated_cb), dialog);
180 ev_password_set_bad_password_label (dialog, " ");
182 if (!gnome_keyring_is_available ()) {
183 gtk_widget_hide (dialog->priv->check_default);
184 gtk_widget_hide (dialog->priv->check_session);
187 g_object_unref (xml);
191 ev_password_set_bad_password_label (EvPasswordDialog *dialog,
196 markup = g_strdup_printf ("<span color=\"red\" size=\"smaller\">%s</span>",
198 gtk_label_set_markup (GTK_LABEL (dialog->priv->bad_label), markup);
203 ev_password_dialog_entry_changed_cb (GtkEditable *editable,
204 EvPasswordDialog *dialog)
208 text = gtk_entry_get_text (GTK_ENTRY (editable));
210 if (text == NULL || *text == '\0')
211 gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog),
212 GTK_RESPONSE_OK, FALSE);
214 gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog),
215 GTK_RESPONSE_OK, TRUE);
217 ev_password_set_bad_password_label (dialog, " ");
221 ev_password_dialog_entry_activated_cb (GtkEntry *entry,
222 EvPasswordDialog *dialog)
224 gtk_dialog_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
229 ev_password_item_created_callback (GnomeKeyringResult result,
239 ev_password_dialog_save_password (EvPasswordDialog *dialog)
242 GnomeKeyringAttributeList *attributes;
243 GnomeKeyringAttribute attribute;
245 gchar *unescaped_uri;
247 attributes = gnome_keyring_attribute_list_new ();
249 attribute.name = g_strdup ("type");
250 attribute.type = GNOME_KEYRING_ATTRIBUTE_TYPE_STRING;
251 attribute.value.string = g_strdup ("document_password");
252 g_array_append_val (attributes, attribute);
254 attribute.name = g_strdup ("uri");
255 attribute.type = GNOME_KEYRING_ATTRIBUTE_TYPE_STRING;
256 attribute.value.string = g_strdup (dialog->priv->uri);
257 g_array_append_val (attributes, attribute);
259 unescaped_uri = g_uri_unescape_string (dialog->priv->uri, NULL);
260 name = g_strdup_printf (_("Password for document %s"), unescaped_uri);
262 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dialog->priv->check_default))) {
263 gnome_keyring_item_create (NULL,
264 GNOME_KEYRING_ITEM_GENERIC_SECRET,
267 ev_password_dialog_get_password (dialog),
268 TRUE, ev_password_item_created_callback,
272 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dialog->priv->check_session))) {
273 gnome_keyring_item_create ("session",
274 GNOME_KEYRING_ITEM_GENERIC_SECRET,
277 ev_password_dialog_get_password (dialog),
278 TRUE, ev_password_item_created_callback,
282 gnome_keyring_attribute_list_free (attributes);
284 g_free (unescaped_uri);
286 #endif /* WITH_KEYRING */
292 ev_password_keyring_found_cb (GnomeKeyringResult result,
297 GnomeKeyringFound *found;
298 EvPasswordDialog *dialog = EV_PASSWORD_DIALOG (data);
300 if (result != GNOME_KEYRING_RESULT_OK || list == NULL)
304 gtk_entry_set_text (GTK_ENTRY (dialog->priv->entry), found->secret);
306 #endif /* WITH_KEYRING */
309 ev_password_search_in_keyring (EvPasswordDialog *dialog, const gchar *uri)
312 GnomeKeyringAttributeList *attributes;
313 GnomeKeyringAttribute attribute;
315 attributes = gnome_keyring_attribute_list_new ();
317 attribute.name = g_strdup ("type");
318 attribute.type = GNOME_KEYRING_ATTRIBUTE_TYPE_STRING;
319 attribute.value.string = g_strdup ("document_password");
320 g_array_append_val (attributes, attribute);
322 attribute.name = g_strdup ("uri");
323 attribute.type = GNOME_KEYRING_ATTRIBUTE_TYPE_STRING;
324 attribute.value.string = g_strdup (uri);
325 g_array_append_val (attributes, attribute);
327 gnome_keyring_find_items (GNOME_KEYRING_ITEM_GENERIC_SECRET,
329 ev_password_keyring_found_cb,
330 g_object_ref (dialog),
332 gnome_keyring_attribute_list_free (attributes);
333 #endif /* WITH_KEYRING */
338 ev_password_dialog_get_password (EvPasswordDialog *dialog)
340 return gtk_entry_get_text (GTK_ENTRY (dialog->priv->entry));
344 ev_password_dialog_set_bad_pass (EvPasswordDialog *dialog)
346 gtk_entry_set_text (GTK_ENTRY (dialog->priv->entry), "");
347 ev_password_set_bad_password_label (dialog, _("Incorrect password"));