Added a check button for NNTP authentication to account preferences.
[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
44 struct gpgmegtk_sig_status_s {
45         GtkWidget *mainwindow;
46         GtkWidget *label;
47         int running;
48         int destroy_pending;
49         guint timeout_id;
50         int timeout_id_valid;
51 };
52
53
54 static void do_destroy(GpgmegtkSigStatus hd)
55 {
56         if (!hd->running ) {
57                 if (hd->mainwindow) {
58                         gtk_widget_destroy ( hd->mainwindow );
59                         hd->mainwindow = NULL;
60                 }
61                 if (hd->timeout_id_valid) {
62                         gtk_timeout_remove(hd->timeout_id);
63                         hd->timeout_id_valid = 0;
64                 }
65                 if(hd->destroy_pending) 
66                         g_free(hd);
67         }
68 }
69
70
71 static void okay_cb(GtkWidget *widget, gpointer data)
72 {
73         GpgmegtkSigStatus hd = data;
74
75         hd->running = 0;
76         do_destroy(hd);
77 }
78
79
80 static void key_pressed(GtkWidget *widget, GdkEventKey *event, gpointer data)
81 {
82         GpgmegtkSigStatus hd = data;
83
84         if (event && event->keyval == GDK_Escape) {
85                 hd->running = 0;
86                 do_destroy(hd);
87         }
88 }
89
90
91 GpgmegtkSigStatus gpgmegtk_sig_status_create()
92 {
93         GtkWidget *window;
94         GtkWidget *vbox;
95         GtkWidget *hbox;
96         GtkWidget *label;
97         GtkWidget *okay_btn;
98         GtkWidget *okay_area;
99         GpgmegtkSigStatus hd;
100
101         hd = g_malloc0(sizeof *hd);
102         hd->running = 1;
103
104         window = gtk_window_new(GTK_WINDOW_DIALOG);
105         hd->mainwindow = window;
106         gtk_widget_set_usize(window, 400, -1);
107         gtk_container_set_border_width(GTK_CONTAINER(window), 8);
108         gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
109         gtk_window_set_policy(GTK_WINDOW(window), FALSE, FALSE, FALSE);
110         gtk_signal_connect(GTK_OBJECT(window), "delete_event",
111                            GTK_SIGNAL_FUNC(okay_cb), hd);
112         gtk_signal_connect(GTK_OBJECT(window), "key_press_event",
113                            GTK_SIGNAL_FUNC(key_pressed), hd);
114
115         vbox = gtk_vbox_new(FALSE, 8);
116         gtk_container_add(GTK_CONTAINER(window), vbox);
117         gtk_widget_show(vbox);
118
119         hbox = gtk_hbox_new(FALSE, 0);
120         gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 8);
121         gtk_widget_show(hbox);
122
123         label = gtk_label_new(_("Checking signature"));
124         hd->label = label;
125         gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 8);
126         gtk_widget_show(label);
127
128         gtkut_button_set_create(&okay_area, &okay_btn, _("Okay"),
129                                 NULL, NULL, NULL, NULL);
130         gtk_box_pack_end(GTK_BOX(vbox), okay_area, FALSE, FALSE, 0);
131         gtk_widget_grab_default(okay_btn);
132         gtk_signal_connect(GTK_OBJECT(okay_btn), "clicked",
133                            GTK_SIGNAL_FUNC(okay_cb), hd);
134
135         gtk_widget_show_all(window);
136
137         while (gtk_events_pending())
138             gtk_main_iteration();
139
140         return hd;
141 }
142
143 static gint timeout_cb(gpointer data)
144 {
145     GpgmegtkSigStatus hd = data;
146
147     hd->running = 0;
148     hd->timeout_id_valid = 0;
149     do_destroy(hd);
150     return FALSE;
151 }
152
153 void gpgmegtk_sig_status_destroy(GpgmegtkSigStatus hd)
154 {
155         if( hd ) {
156                 hd->destroy_pending = 1;
157                 if (hd->running && !hd->timeout_id_valid) {
158                     hd->timeout_id = gtk_timeout_add(MY_TIMEOUT,
159                                                      timeout_cb, hd);
160                     hd->timeout_id_valid = 1;
161                 }
162                 do_destroy(hd);
163         }
164 }
165
166
167 /* Fixme: remove status and get it from the context */
168 void gpgmegtk_sig_status_update(GpgmegtkSigStatus hd, GpgmeCtx ctx)
169 {
170     int idx;
171     time_t created;
172     GpgmeSigStat status;
173     char *text = NULL;
174
175     if (!hd || !hd->running || !ctx)
176         return;
177
178     for (idx=0; gpgme_get_sig_status(ctx, idx, &status, &created); idx++ ) {
179         char *tmp;
180         const char *userid;
181         GpgmeKey key = NULL;
182
183         if ( !gpgme_get_sig_key (ctx, idx, &key) ) {
184             userid = gpgme_key_get_string_attr (key, GPGME_ATTR_USERID,
185                                                 NULL, 0);
186         }
187         else
188             userid = "[?]";
189
190         tmp = g_strdup_printf ( "%s%s%s from \"%s\"",
191                                 text? text:"",
192                                 text? "\n":"",
193                                 gpgmegtk_sig_status_to_string(status),
194                                 userid );
195         g_free (text);
196         text = tmp;
197         gpgme_key_unref (key);
198     }
199
200     gtk_label_set_text(GTK_LABEL(hd->label), text ); 
201     g_free (text);
202
203     while (gtk_events_pending())
204         gtk_main_iteration();
205 }
206
207
208 const char *gpgmegtk_sig_status_to_string(GpgmeSigStat status)
209 {
210         const char *result = "?";
211
212         switch ( status ) {
213             case GPGME_SIG_STAT_NONE:
214                 result = _("Oops: Signature not verified");
215                 break;
216             case GPGME_SIG_STAT_NOSIG:
217                 result = _("No signature found");
218                 break;
219             case GPGME_SIG_STAT_GOOD:
220                 result = _("Good signature");
221                 break;
222             case GPGME_SIG_STAT_BAD:
223                 result = _("BAD signature");
224                 break;
225             case GPGME_SIG_STAT_NOKEY:
226                 result = _("No public key to verify the signature");
227                 break;
228             case GPGME_SIG_STAT_ERROR:
229                 result = _("Error verifying the signature");
230                 break;
231         }
232
233         return result;
234 }
235
236 #endif /* USE_GPGME */