inital gtk2 patch
[claws.git] / src / sigstatus.c
1 /* sigstatus.h - GTK+ based signature status display
2  *      Copyright (C) 2001 Werner Koch (dd9jn)
3  *
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.
8  *
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.
13  *
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.
17  */
18
19 #ifdef HAVE_CONFIG_H
20 #  include "config.h"
21 #endif
22
23 #if USE_GPGME
24
25 #include <glib.h>
26 #include <gtk/gtkwindow.h>
27 #include <gtk/gtkvbox.h>
28 #include <gtk/gtkhbox.h>
29 #include <gtk/gtklabel.h>
30 #include <gtk/gtkbutton.h>
31 #include <gdk/gdkkeysyms.h>
32 #include <gpgme.h>
33
34 #include "intl.h"
35 #include "gtkutils.h"
36 #include "utils.h"
37 #include "sigstatus.h"
38
39 /* remove the window after 30 seconds to avoid cluttering the deskop 
40  * with too many of them */
41 #define MY_TIMEOUT (30*1000)
42
43 struct gpgmegtk_sig_status_s {
44         GtkWidget *mainwindow;
45         GtkWidget *label;
46         gint running;
47         gint destroy_pending;
48         guint timeout_id;
49         gint timeout_id_valid;
50 };
51
52
53 static void do_destroy(GpgmegtkSigStatus hd)
54 {
55         if (!hd->running) {
56                 if (hd->mainwindow) {
57                         gtk_widget_destroy ( hd->mainwindow );
58                         hd->mainwindow = NULL;
59                 }
60                 if (hd->timeout_id_valid) {
61                         gtk_timeout_remove(hd->timeout_id);
62                         hd->timeout_id_valid = 0;
63                 }
64                 if (hd->destroy_pending) 
65                 g_free(hd);
66         }
67 }
68
69 static void okay_cb(GtkWidget *widget, gpointer data)
70 {
71         GpgmegtkSigStatus hd = data;
72
73         hd->running = 0;
74         do_destroy(hd);
75 }
76
77 static gint delete_event(GtkWidget *widget, GdkEventAny *event, gpointer data)
78 {
79         GpgmegtkSigStatus hd = data;
80
81         hd->running = 0;
82         do_destroy(hd);
83
84         return TRUE;
85 }
86
87 static gboolean key_pressed(GtkWidget *widget, GdkEventKey *event, gpointer data)
88 {
89         GpgmegtkSigStatus hd = data;
90
91         if (event && event->keyval == GDK_Escape) {
92                 hd->running = 0;
93                 do_destroy(hd);
94         }
95         return FALSE;
96 }
97
98 GpgmegtkSigStatus gpgmegtk_sig_status_create(void)
99 {
100         GtkWidget *window;
101         GtkWidget *vbox;
102         GtkWidget *hbox;
103         GtkWidget *label;
104         GtkWidget *okay_btn;
105         GtkWidget *okay_area;
106         GpgmegtkSigStatus hd;
107
108         hd = g_malloc0(sizeof *hd);
109         hd->running = 1;
110
111         window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
112         hd->mainwindow = window;
113         gtk_widget_set_size_request(window, 400, -1);
114         gtk_container_set_border_width(GTK_CONTAINER(window), 8);
115         gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
116         gtk_window_set_policy(GTK_WINDOW(window), FALSE, TRUE, FALSE);
117         g_signal_connect(G_OBJECT(window), "delete_event",
118                                 G_CALLBACK(delete_event), hd);
119         g_signal_connect(G_OBJECT(window), "key_press_event",
120                          G_CALLBACK(key_pressed), hd);
121
122         vbox = gtk_vbox_new(FALSE, 8);
123         gtk_container_add(GTK_CONTAINER(window), vbox);
124         gtk_widget_show(vbox);
125
126         hbox = gtk_hbox_new(FALSE, 0);
127         gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 8);
128         gtk_widget_show(hbox);
129
130         label = gtk_label_new(_("Checking signature"));
131         hd->label = label;
132         gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 8);
133         gtk_widget_show(label);
134
135         gtkut_button_set_create(&okay_area, &okay_btn, _("OK"),
136                                 NULL, NULL, NULL, NULL);
137         gtk_box_pack_end(GTK_BOX(vbox), okay_area, FALSE, FALSE, 0);
138         gtk_widget_grab_default(okay_btn);
139         g_signal_connect(G_OBJECT(okay_btn), "clicked",
140                          G_CALLBACK(okay_cb), hd);
141
142         gtk_widget_show_all(window);
143
144         while (gtk_events_pending())
145                 gtk_main_iteration();
146
147         return hd;
148 }
149
150 static gint timeout_cb(gpointer data)
151 {
152         GpgmegtkSigStatus hd = data;
153
154         hd->running = 0;
155         hd->timeout_id_valid = 0;
156         do_destroy(hd);
157
158         return FALSE;
159 }
160
161 void gpgmegtk_sig_status_destroy(GpgmegtkSigStatus hd)
162 {
163         if (hd) {
164                 hd->destroy_pending = 1;
165                 if (hd->running && !hd->timeout_id_valid) {
166                         hd->timeout_id = gtk_timeout_add(MY_TIMEOUT,
167                                                          timeout_cb, hd);
168                         hd->timeout_id_valid = 1;
169                 }
170                 do_destroy(hd);
171         }
172 }
173
174 /* Fixme: remove status and get it from the context */
175 void gpgmegtk_sig_status_update(GpgmegtkSigStatus hd, GpgmeCtx ctx)
176 {
177         gint idx;
178         time_t created;
179         GpgmeSigStat status;
180         gchar *text = NULL;
181
182         if (!hd || !hd->running || !ctx)
183                 return;
184
185         for (idx = 0; gpgme_get_sig_status(ctx, idx, &status, &created);
186              idx++) {
187                 gchar *tmp;
188                 const gchar *userid;
189                 GpgmeKey key = NULL;
190
191                 if (!gpgme_get_sig_key (ctx, idx, &key)) {
192                         userid = gpgme_key_get_string_attr
193                                 (key, GPGME_ATTR_USERID, NULL, 0);
194                 } else
195                         userid = "[?]";
196
197                 tmp = g_strdup_printf(_("%s%s%s from \"%s\""),
198                                       text ? text : "",
199                                       text ? "\n" : "",
200                                       gpgmegtk_sig_status_to_string(status),
201                                       userid);
202                 g_free (text);
203                 text = tmp;
204                 gpgme_key_unref (key);
205         }
206
207         gtk_label_set_text(GTK_LABEL(hd->label), text); 
208         g_free(text);
209
210         while (gtk_events_pending())
211                 gtk_main_iteration();
212 }
213
214 const char *gpgmegtk_sig_status_to_string(GpgmeSigStat status)
215 {
216         const char *result = "?";
217
218         switch (status) {
219         case GPGME_SIG_STAT_NONE:
220                 result = _("Oops: Signature not verified");
221                 break;
222         case GPGME_SIG_STAT_NOSIG:
223                 result = _("No signature found");
224                 break;
225         case GPGME_SIG_STAT_GOOD:
226                 result = _("Good signature");
227                 break;
228         case GPGME_SIG_STAT_GOOD_EXP:   
229                 result = _("Good signature but it has expired");
230                 break;
231         case GPGME_SIG_STAT_GOOD_EXPKEY:
232                 result = _("Good signature but the key has expired");
233                 break;
234         case GPGME_SIG_STAT_BAD:
235                 result = _("BAD signature");
236                 break;
237         case GPGME_SIG_STAT_NOKEY:
238                 result = _("No public key to verify the signature");
239                 break;
240         case GPGME_SIG_STAT_ERROR:
241                 result = _("Error verifying the signature");
242                 break;
243         default:
244                 break;
245         }
246
247         return result;
248 }
249
250 #endif /* USE_GPGME */