1 /* select-keys.c - GTK+ based key selection
2 * Copyright (C) 2001 Werner Koch (dd9jn)
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
28 #include <gdk/gdkkeysyms.h>
29 #include <gtk/gtkmain.h>
30 #include <gtk/gtkwidget.h>
31 #include <gtk/gtkwindow.h>
32 #include <gtk/gtkscrolledwindow.h>
33 #include <gtk/gtkvbox.h>
34 #include <gtk/gtkhbox.h>
35 #include <gtk/gtkclist.h>
36 #include <gtk/gtklabel.h>
37 #include <gtk/gtkentry.h>
38 #include <gtk/gtkhbbox.h>
39 #include <gtk/gtkbutton.h>
40 #include <gtk/gtkprogressbar.h>
41 #include <gtk/gtksignal.h>
44 #include "select-keys.h"
63 GtkProgress *progress;
69 static void set_row (GtkCList *clist, GpgmeKey key );
70 static void fill_clist (GtkCList *clist, const char *pattern );
71 static void create_dialog (void);
72 static void open_dialog (void);
73 static void close_dialog (void);
74 static void key_pressed_cb (GtkWidget *widget,
75 GdkEventKey *event, gpointer data);
76 static void select_btn_cb (GtkWidget *widget, gpointer data);
77 static void cancel_btn_cb (GtkWidget *widget, gpointer data);
81 update_progress (void)
83 if (select_keys.progress) {
84 gfloat val = gtk_progress_get_value (select_keys.progress);
87 gtk_progress_set_value (select_keys.progress, val);
88 if ( !GTK_WIDGET_VISIBLE (select_keys.progress) )
89 gtk_widget_show (GTK_WIDGET (select_keys.progress));
95 * select_keys_get_recipients:
96 * @recp_names: A list of email addresses
98 * Select a list of recipients from a given list of email addresses.
99 * This may pop up a window to present the user a choice, it will also
100 * check that the recipients key are all valid.
102 * Return value: NULL on error or a list of list of recipients.
105 gpgmegtk_recipient_selection (GSList *recp_names)
109 err = gpgme_recipients_new (&select_keys.rset);
111 g_message ("** failed to allocate recipients set: %s",
112 gpgme_strerror (err) );
119 select_keys.pattern = recp_names? recp_names->data:NULL;
120 gtk_label_set_text (select_keys.toplabel, select_keys.pattern );
121 gtk_clist_clear (select_keys.clist);
122 fill_clist (select_keys.clist, select_keys.pattern);
125 recp_names = recp_names->next;
126 } while (select_keys.okay && recp_names );
131 GpgmeRecipients rset = select_keys.rset;
132 select_keys.rset = NULL;
134 gpgme_recipients_release (rset);
142 destroy_key (gpointer data)
145 gpgme_key_release (key);
149 set_row (GtkCList *clist, GpgmeKey key )
152 const char *text[N_COL_TITLES];
156 algo_buf = g_strdup_printf ("%lu/%s",
157 gpgme_key_get_ulong_attr (key, GPGME_ATTR_LEN, NULL, 0 ),
158 gpgme_key_get_string_attr (key, GPGME_ATTR_ALGO, NULL, 0 ) );
159 text[COL_ALGO] = algo_buf;
161 s = gpgme_key_get_string_attr (key, GPGME_ATTR_KEYID, NULL, 0 );
162 if ( strlen (s) == 16 )
163 s += 8; /* show only the short keyID */
166 s = gpgme_key_get_string_attr (key, GPGME_ATTR_NAME, NULL, 0 );
169 s = gpgme_key_get_string_attr (key, GPGME_ATTR_EMAIL, NULL, 0 );
172 s = gpgme_key_get_string_attr (key, GPGME_ATTR_VALIDITY, NULL, 0 );
173 text[COL_VALIDITY] = s;
175 row = gtk_clist_append (clist, (gchar**)text);
178 gtk_clist_set_row_data_full (clist, row, key, destroy_key);
183 fill_clist (GtkCList *clist, const char *pattern )
189 debug_print ("select_keys:fill_clist: pattern `%s'\n", pattern );
191 /*gtk_clist_freeze (select_keys.clist);*/
192 err = gpgme_new (&ctx);
195 while (gtk_events_pending ())
196 gtk_main_iteration ();
198 err = gpgme_op_keylist_start (ctx, pattern, 0 );
200 g_message ("** gpgme_op_keylist_start(%s) failed: %s",
201 pattern, gpgme_strerror (err));
205 while ( !(err = gpgme_op_keylist_next ( ctx, &key )) ) {
206 debug_print ("%% %s:%d: insert\n", __FILE__ ,__LINE__ );
207 set_row (clist, key ); key = NULL;
209 while (gtk_events_pending ())
210 gtk_main_iteration ();
212 debug_print ("%% %s:%d: ready\n", __FILE__ ,__LINE__ );
213 gtk_widget_hide (GTK_WIDGET (select_keys.progress));
214 if ( err != GPGME_EOF )
215 g_message ("** gpgme_op_keylist_next failed: %s",
216 gpgme_strerror (err));
218 /*gtk_clist_thaw (select_keys.clist);*/
228 GtkWidget *vbox, *vbox2, *hbox;
230 GtkWidget *scrolledwin;
234 GtkWidget *select_btn, *cancel_btn;
235 gchar *titles[N_COL_TITLES];
237 g_assert (!select_keys.window);
238 window = gtk_window_new (GTK_WINDOW_DIALOG);
239 gtk_widget_set_usize (window, 500, 320);
240 gtk_container_set_border_width (GTK_CONTAINER (window), 8);
241 gtk_window_set_title (GTK_WINDOW (window), _("Select Keys"));
242 gtk_window_set_modal (GTK_WINDOW (window), TRUE);
243 gtk_signal_connect (GTK_OBJECT (window), "delete_event",
244 GTK_SIGNAL_FUNC (close_dialog), NULL);
245 gtk_signal_connect (GTK_OBJECT (window), "key_press_event",
246 GTK_SIGNAL_FUNC (key_pressed_cb), NULL);
248 vbox = gtk_vbox_new (FALSE, 8);
249 gtk_container_add (GTK_CONTAINER (window), vbox);
251 hbox = gtk_hbox_new(FALSE, 4);
252 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
253 label = gtk_label_new ( _("Select key for: ") );
254 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
255 label = gtk_label_new ( "" );
256 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
259 hbox = gtk_hbox_new (FALSE, 8);
260 gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 0);
261 gtk_container_set_border_width (GTK_CONTAINER (hbox), 2);
264 scrolledwin = gtk_scrolled_window_new (NULL, NULL);
265 gtk_box_pack_start (GTK_BOX (hbox), scrolledwin, TRUE, TRUE, 0);
266 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwin),
267 GTK_POLICY_AUTOMATIC,
268 GTK_POLICY_AUTOMATIC);
270 titles[COL_ALGO] = _("Size");
271 titles[COL_KEYID] = _("Key ID");
272 titles[COL_NAME] = _("Name");
273 titles[COL_EMAIL] = _("Address");
274 titles[COL_VALIDITY] = _("Val");
276 clist = gtk_clist_new_with_titles (N_COL_TITLES, titles);
277 gtk_container_add (GTK_CONTAINER (scrolledwin), clist);
278 gtk_clist_set_column_width (GTK_CLIST(clist), COL_ALGO, 40);
279 gtk_clist_set_column_width (GTK_CLIST(clist), COL_KEYID, 60);
280 gtk_clist_set_column_width (GTK_CLIST(clist), COL_NAME, 100);
281 gtk_clist_set_column_width (GTK_CLIST(clist), COL_EMAIL, 100);
282 gtk_clist_set_column_width (GTK_CLIST(clist), COL_VALIDITY, 20);
283 gtk_clist_set_selection_mode (GTK_CLIST(clist), GTK_SELECTION_BROWSE);
285 hbox = gtk_hbox_new (FALSE, 8);
286 gtk_box_pack_end (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
288 gtkut_button_set_create (&bbox, &select_btn, _("Select"),
289 &cancel_btn, _("Cancel"), NULL, NULL);
290 gtk_box_pack_end (GTK_BOX (hbox), bbox, FALSE, FALSE, 0);
291 gtk_widget_grab_default (select_btn);
293 gtk_signal_connect (GTK_OBJECT (select_btn), "clicked",
294 GTK_SIGNAL_FUNC (select_btn_cb), clist);
295 gtk_signal_connect (GTK_OBJECT(cancel_btn), "clicked",
296 GTK_SIGNAL_FUNC (cancel_btn_cb), NULL);
298 vbox2 = gtk_vbox_new (FALSE, 4);
299 gtk_box_pack_start (GTK_BOX (hbox), vbox2, FALSE, FALSE, 0);
301 progress = gtk_progress_bar_new ();
302 gtk_box_pack_start (GTK_BOX (vbox2), progress, FALSE, FALSE, 4);
303 gtk_progress_set_activity_mode (GTK_PROGRESS (progress), 1);
305 gtk_widget_show_all (window);
306 select_keys.window = window;
307 select_keys.toplabel = GTK_LABEL (label);
308 select_keys.clist = GTK_CLIST (clist);
309 select_keys.progress = GTK_PROGRESS (progress);
316 if ( !select_keys.window )
318 select_keys.okay = 0;
319 gtk_widget_show (select_keys.window);
326 gtk_widget_destroy (select_keys.window);
327 select_keys.window = NULL;
332 key_pressed_cb (GtkWidget *widget, GdkEventKey *event, gpointer data)
334 if (event && event->keyval == GDK_Escape) {
335 select_keys.okay = 0;
342 select_btn_cb (GtkWidget *widget, gpointer data)
344 GtkCList *clist = GTK_CLIST (data);
348 if (!clist->selection) {
349 g_message ("** nothing selected");
352 row = GPOINTER_TO_INT(clist->selection->data);
353 key = gtk_clist_get_row_data(clist, row);
355 const char *s = gpgme_key_get_string_attr (key,
358 g_message ("** FIXME: we are faking the trust calculation");
359 if (!gpgme_recipients_add_name_with_validity (select_keys.rset, s,
360 GPGME_VALIDITY_FULL) ) {
361 select_keys.okay = 1;
369 cancel_btn_cb (GtkWidget *widget, gpointer data)
371 select_keys.okay = 0;