1 /* this file is part of evince, a gnome document viewer
3 * Copyright (C) 2008 Carlos Garcia Campos <carlosgc@gnome.org>
4 * Copyright (C) 2005 Red Hat, Inc
6 * Evince is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * Evince is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
26 #include <glib/gi18n.h>
30 #include "ev-keyring.h"
31 #include "ev-password-view.h"
37 struct _EvPasswordViewPrivate {
38 GtkWindow *parent_window;
40 GtkWidget *password_entry;
43 GPasswordSave password_save;
48 #define EV_PASSWORD_VIEW_GET_PRIVATE(object) \
49 (G_TYPE_INSTANCE_GET_PRIVATE ((object), EV_TYPE_PASSWORD_VIEW, EvPasswordViewPrivate));
51 static guint password_view_signals [LAST_SIGNAL] = { 0 };
54 G_DEFINE_TYPE (EvPasswordView, ev_password_view, GTK_TYPE_VIEWPORT)
57 ev_password_view_finalize (GObject *object)
59 EvPasswordView *password_view = EV_PASSWORD_VIEW (object);
61 if (password_view->priv->password) {
62 g_free (password_view->priv->password);
63 password_view->priv->password = NULL;
66 password_view->priv->parent_window = NULL;
68 if (password_view->priv->uri_file) {
69 g_object_unref (password_view->priv->uri_file);
70 password_view->priv->uri_file = NULL;
73 G_OBJECT_CLASS (ev_password_view_parent_class)->finalize (object);
77 ev_password_view_class_init (EvPasswordViewClass *class)
79 GObjectClass *g_object_class;
80 GtkWidgetClass *widget_class;
82 g_object_class = G_OBJECT_CLASS (class);
83 widget_class = GTK_WIDGET_CLASS (class);
85 password_view_signals[UNLOCK] =
86 g_signal_new ("unlock",
87 G_TYPE_FROM_CLASS (g_object_class),
88 G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
89 G_STRUCT_OFFSET (EvPasswordViewClass, unlock),
91 g_cclosure_marshal_VOID__VOID,
94 g_type_class_add_private (g_object_class, sizeof (EvPasswordViewPrivate));
96 g_object_class->finalize = ev_password_view_finalize;
100 ev_password_view_clicked_cb (GtkWidget *button,
101 EvPasswordView *password_view)
103 ev_password_view_ask_password (password_view);
107 ev_password_view_init (EvPasswordView *password_view)
117 password_view->priv = EV_PASSWORD_VIEW_GET_PRIVATE (password_view);
119 password_view->priv->password_save = G_PASSWORD_SAVE_NEVER;
121 gtk_widget_push_composite_child ();
123 /* set ourselves up */
124 align = gtk_alignment_new (0.5, 0.5, 0.0, 0.0);
125 vbox = gtk_vbox_new (FALSE, 24);
126 gtk_container_set_border_width (GTK_CONTAINER (vbox), 24);
127 gtk_container_add (GTK_CONTAINER (password_view), align);
128 gtk_container_add (GTK_CONTAINER (align), vbox);
130 password_view->priv->label =
131 (GtkWidget *) g_object_new (GTK_TYPE_LABEL,
135 gtk_box_pack_start (GTK_BOX (vbox), password_view->priv->label, FALSE, FALSE, 0);
137 image = gtk_image_new_from_stock (GTK_STOCK_DIALOG_AUTHENTICATION,
138 GTK_ICON_SIZE_DIALOG);
139 gtk_box_pack_start (GTK_BOX (vbox), image, FALSE, FALSE, 0);
141 label = gtk_label_new (NULL);
142 gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
143 markup = g_strdup_printf ("<span size=\"x-large\">%s</span>",
144 _("This document is locked and can only be read by entering the correct password."));
145 gtk_label_set_markup (GTK_LABEL (label), markup);
148 gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
150 hbox = gtk_hbox_new (FALSE, 0);
151 gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
153 button = gtk_button_new_with_mnemonic (_("_Unlock Document"));
154 g_signal_connect (button, "clicked", G_CALLBACK (ev_password_view_clicked_cb), password_view);
155 gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, FALSE, 0);
157 gtk_widget_show_all (align);
158 gtk_widget_pop_composite_child ();
161 /* Public functions */
163 ev_password_view_set_uri (EvPasswordView *password_view,
166 gchar *markup, *file_name;
169 g_return_if_fail (EV_IS_PASSWORD_VIEW (password_view));
170 g_return_if_fail (uri != NULL);
172 file = g_file_new_for_uri (uri);
173 if (password_view->priv->uri_file &&
174 g_file_equal (file, password_view->priv->uri_file)) {
175 g_object_unref (file);
178 if (password_view->priv->uri_file)
179 g_object_unref (password_view->priv->uri_file);
180 password_view->priv->uri_file = file;
182 file_name = g_file_get_basename (password_view->priv->uri_file);
183 markup = g_markup_printf_escaped ("<span size=\"x-large\" weight=\"bold\">%s</span>",
187 gtk_label_set_markup (GTK_LABEL (password_view->priv->label), markup);
192 ev_password_dialog_got_response (GtkDialog *dialog,
194 EvPasswordView *password_view)
196 gtk_widget_set_sensitive (GTK_WIDGET (password_view), TRUE);
198 if (response_id == GTK_RESPONSE_OK) {
199 g_free (password_view->priv->password);
200 password_view->priv->password =
201 g_strdup (gtk_entry_get_text (GTK_ENTRY (password_view->priv->password_entry)));
203 g_signal_emit (password_view, password_view_signals[UNLOCK], 0);
206 gtk_widget_destroy (GTK_WIDGET (dialog));
210 ev_password_dialog_remember_button_toggled (GtkToggleButton *button,
211 EvPasswordView *password_view)
213 if (gtk_toggle_button_get_active (button)) {
216 data = g_object_get_data (G_OBJECT (button), "password-save");
217 password_view->priv->password_save = GPOINTER_TO_INT (data);
222 ev_password_dialog_entry_changed_cb (GtkEditable *editable,
227 text = gtk_entry_get_text (GTK_ENTRY (editable));
229 gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), GTK_RESPONSE_OK,
230 (text != NULL && *text != '\0'));
234 ev_password_dialog_entry_activated_cb (GtkEntry *entry,
237 gtk_dialog_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
241 ev_password_view_ask_password (EvPasswordView *password_view)
244 GtkWidget *content_area, *action_area;
245 GtkWidget *entry_container;
246 GtkWidget *hbox, *main_vbox, *vbox, *icon;
249 gchar *format, *markup, *file_name;
251 gtk_widget_set_sensitive (GTK_WIDGET (password_view), FALSE);
253 dialog = GTK_DIALOG (gtk_dialog_new ());
254 content_area = gtk_dialog_get_content_area (dialog);
255 action_area = gtk_dialog_get_action_area (dialog);
257 /* Set the dialog up with HIG properties */
258 gtk_dialog_set_has_separator (dialog, FALSE);
259 gtk_container_set_border_width (GTK_CONTAINER (dialog), 5);
260 gtk_box_set_spacing (GTK_BOX (content_area), 2); /* 2 * 5 + 2 = 12 */
261 gtk_container_set_border_width (GTK_CONTAINER (action_area), 5);
262 gtk_box_set_spacing (GTK_BOX (action_area), 6);
264 gtk_window_set_title (GTK_WINDOW (dialog), _("Enter password"));
265 gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE);
266 gtk_window_set_icon_name (GTK_WINDOW (dialog), GTK_STOCK_DIALOG_AUTHENTICATION);
267 gtk_window_set_transient_for (GTK_WINDOW (dialog), password_view->priv->parent_window);
268 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
270 gtk_dialog_add_buttons (dialog,
271 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
272 _("_Unlock Document"), GTK_RESPONSE_OK,
274 gtk_dialog_set_default_response (dialog, GTK_RESPONSE_OK);
275 gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog),
276 GTK_RESPONSE_OK, FALSE);
277 gtk_dialog_set_alternative_button_order (dialog,
283 hbox = gtk_hbox_new (FALSE, 12);
284 gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
285 gtk_box_pack_start (GTK_BOX (content_area), hbox, TRUE, TRUE, 0);
286 gtk_widget_show (hbox);
288 icon = gtk_image_new_from_stock (GTK_STOCK_DIALOG_AUTHENTICATION,
289 GTK_ICON_SIZE_DIALOG);
291 gtk_misc_set_alignment (GTK_MISC (icon), 0.5, 0.0);
292 gtk_box_pack_start (GTK_BOX (hbox), icon, FALSE, FALSE, 0);
293 gtk_widget_show (icon);
295 main_vbox = gtk_vbox_new (FALSE, 18);
296 gtk_box_pack_start (GTK_BOX (hbox), main_vbox, TRUE, TRUE, 0);
297 gtk_widget_show (main_vbox);
299 label = gtk_label_new (NULL);
300 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
301 gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
302 file_name = g_file_get_basename (password_view->priv->uri_file);
303 format = g_strdup_printf ("<span size=\"larger\" weight=\"bold\">%s</span>\n\n%s",
304 _("Password required"),
305 _("The document ā%sā is locked and requires a password before it can be opened."));
306 markup = g_markup_printf_escaped (format, file_name);
307 gtk_label_set_markup (GTK_LABEL (label), markup);
311 gtk_box_pack_start (GTK_BOX (main_vbox), label,
313 gtk_widget_show (label);
315 vbox = gtk_vbox_new (FALSE, 6);
316 gtk_box_pack_start (GTK_BOX (main_vbox), vbox, FALSE, FALSE, 0);
317 gtk_widget_show (vbox);
319 /* The table that holds the entries */
320 entry_container = gtk_alignment_new (0.0, 0.0, 1.0, 1.0);
322 gtk_alignment_set_padding (GTK_ALIGNMENT (entry_container),
325 gtk_box_pack_start (GTK_BOX (vbox), entry_container,
327 gtk_widget_show (entry_container);
329 table = gtk_table_new (1, 2, FALSE);
330 gtk_table_set_col_spacings (GTK_TABLE (table), 12);
331 gtk_table_set_row_spacings (GTK_TABLE (table), 6);
332 gtk_container_add (GTK_CONTAINER (entry_container), table);
333 gtk_widget_show (table);
335 label = gtk_label_new_with_mnemonic (_("_Password:"));
336 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
338 password_view->priv->password_entry = gtk_entry_new ();
339 gtk_entry_set_visibility (GTK_ENTRY (password_view->priv->password_entry), FALSE);
340 g_signal_connect (password_view->priv->password_entry, "changed",
341 G_CALLBACK (ev_password_dialog_entry_changed_cb),
343 g_signal_connect (password_view->priv->password_entry, "activate",
344 G_CALLBACK (ev_password_dialog_entry_activated_cb),
346 gtk_table_attach (GTK_TABLE (table), label,
348 GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
349 gtk_widget_show (label);
351 gtk_table_attach_defaults (GTK_TABLE (table), password_view->priv->password_entry,
353 gtk_widget_show (password_view->priv->password_entry);
355 gtk_label_set_mnemonic_widget (GTK_LABEL (label),
356 password_view->priv->password_entry);
358 if (ev_keyring_is_available ()) {
360 GtkWidget *remember_box;
363 remember_box = gtk_vbox_new (FALSE, 6);
364 gtk_box_pack_start (GTK_BOX (vbox), remember_box,
366 gtk_widget_show (remember_box);
368 choice = gtk_radio_button_new_with_mnemonic (NULL, _("Forget password _immediately"));
369 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (choice),
370 password_view->priv->password_save == G_PASSWORD_SAVE_NEVER);
371 g_object_set_data (G_OBJECT (choice), "password-save",
372 GINT_TO_POINTER (G_PASSWORD_SAVE_NEVER));
373 g_signal_connect (choice, "toggled",
374 G_CALLBACK (ev_password_dialog_remember_button_toggled),
376 gtk_box_pack_start (GTK_BOX (remember_box), choice, FALSE, FALSE, 0);
377 gtk_widget_show (choice);
379 group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (choice));
380 choice = gtk_radio_button_new_with_mnemonic (group, _("Remember password until you _log out"));
381 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (choice),
382 password_view->priv->password_save == G_PASSWORD_SAVE_FOR_SESSION);
383 g_object_set_data (G_OBJECT (choice), "password-save",
384 GINT_TO_POINTER (G_PASSWORD_SAVE_FOR_SESSION));
385 g_signal_connect (choice, "toggled",
386 G_CALLBACK (ev_password_dialog_remember_button_toggled),
388 gtk_box_pack_start (GTK_BOX (remember_box), choice, FALSE, FALSE, 0);
389 gtk_widget_show (choice);
391 group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (choice));
392 choice = gtk_radio_button_new_with_mnemonic (group, _("Remember _forever"));
393 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (choice),
394 password_view->priv->password_save == G_PASSWORD_SAVE_PERMANENTLY);
395 g_object_set_data (G_OBJECT (choice), "password-save",
396 GINT_TO_POINTER (G_PASSWORD_SAVE_PERMANENTLY));
397 g_signal_connect (choice, "toggled",
398 G_CALLBACK (ev_password_dialog_remember_button_toggled),
400 gtk_box_pack_start (GTK_BOX (remember_box), choice, FALSE, FALSE, 0);
401 gtk_widget_show (choice);
404 g_signal_connect (dialog, "response",
405 G_CALLBACK (ev_password_dialog_got_response),
408 gtk_widget_show (GTK_WIDGET (dialog));
412 ev_password_view_get_password (EvPasswordView *password_view)
414 return password_view->priv->password;
418 ev_password_view_get_password_save_flags (EvPasswordView *password_view)
420 return password_view->priv->password_save;
424 ev_password_view_new (GtkWindow *parent)
426 EvPasswordView *retval;
428 retval = EV_PASSWORD_VIEW (g_object_new (EV_TYPE_PASSWORD_VIEW, NULL));
430 retval->priv->parent_window = parent;
432 return GTK_WIDGET (retval);