2 * Claws Mail -- a GTK based, lightweight, and fast e-mail client
3 * Copyright (C) 1999-2009 Colin Leroy <colin@colino.net> and
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU 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, see <http://www.gnu.org/licenses/>.
23 #include "claws-features.h"
27 #include <glib/gi18n.h>
32 #include "gtk/gtkutils.h"
34 #include "common/claws.h"
35 #include "common/version.h"
37 #include "common/utils.h"
40 #include "prefs_gtk.h"
41 #include "foldersel.h"
42 #include "statusbar.h"
45 #include "addressbook.h"
52 GtkWidget
*process_emails
;
53 GtkWidget
*receive_spam
;
54 GtkWidget
*save_folder
;
55 GtkWidget
*save_folder_select
;
58 GtkWidget
*whitelist_ab
;
59 GtkWidget
*whitelist_ab_folder_combo
;
60 GtkWidget
*learn_from_whitelist_chkbtn
;
61 GtkWidget
*mark_as_read
;
64 static void foldersel_cb(GtkWidget
*widget
, gpointer data
)
66 GtkWidget
*entry
= (GtkWidget
*) data
;
71 item
= foldersel_folder_sel(NULL
, FOLDER_SEL_MOVE
, NULL
, FALSE
, NULL
);
72 if (item
&& (item_id
= folder_item_get_identifier(item
)) != NULL
) {
73 gtk_editable_delete_text(GTK_EDITABLE(entry
), 0, -1);
74 gtk_editable_insert_text(GTK_EDITABLE(entry
), item_id
, strlen(item_id
), &newpos
);
79 #ifndef USE_ALT_ADDRBOOK
80 static void bsfilter_whitelist_ab_select_cb(GtkWidget
*widget
, gpointer data
)
82 struct BsfilterPage
*page
= (struct BsfilterPage
*) data
;
83 const gchar
*folderpath
= NULL
;
84 gchar
*new_path
= NULL
;
86 folderpath
= gtk_entry_get_text(GTK_ENTRY(gtk_bin_get_child(GTK_BIN((page
->whitelist_ab_folder_combo
)))));
87 new_path
= addressbook_folder_selection(folderpath
);
89 gtk_entry_set_text(GTK_ENTRY(gtk_bin_get_child(GTK_BIN((page
->whitelist_ab_folder_combo
)))), new_path
);
95 static void bsfilter_create_widget_func(PrefsPage
* _page
,
99 struct BsfilterPage
*page
= (struct BsfilterPage
*) _page
;
100 BsfilterConfig
*config
;
102 GtkWidget
*vbox1
, *vbox2
;
103 GtkWidget
*hbox_max_size
;
104 GtkWidget
*hbox_process_emails
, *hbox_save_spam
;
105 GtkWidget
*hbox_bspath
, *hbox_whitelist
;
106 GtkWidget
*hbox_mark_as_read
;
108 GtkWidget
*max_size_label
;
109 GtkAdjustment
*max_size_spinbtn_adj
;
110 GtkWidget
*max_size_spinbtn
;
111 GtkWidget
*max_size_kb_label
;
113 GtkWidget
*process_emails_checkbtn
;
115 GtkWidget
*save_spam_checkbtn
;
116 GtkWidget
*save_spam_folder_entry
;
117 GtkWidget
*save_spam_folder_select
;
119 GtkWidget
*whitelist_ab_checkbtn
;
120 GtkWidget
*learn_from_whitelist_chkbtn
;
121 GtkWidget
*bspath_label
;
122 GtkWidget
*bspath_entry
;
124 GtkWidget
*mark_as_read_checkbtn
;
126 GtkWidget
*whitelist_ab_folder_combo
;
127 GtkWidget
*whitelist_ab_select_btn
;
129 vbox1
= gtk_box_new(GTK_ORIENTATION_VERTICAL
, VSPACING
);
130 gtk_widget_show (vbox1
);
131 gtk_container_set_border_width (GTK_CONTAINER (vbox1
), VBOX_BORDER
);
133 vbox2
= gtk_box_new(GTK_ORIENTATION_VERTICAL
, 4);
134 gtk_widget_show (vbox2
);
135 gtk_box_pack_start (GTK_BOX (vbox1
), vbox2
, FALSE
, FALSE
, 0);
137 hbox_process_emails
= gtk_box_new(GTK_ORIENTATION_HORIZONTAL
, 8);
138 gtk_widget_show(hbox_process_emails
);
139 gtk_box_pack_start (GTK_BOX (vbox2
), hbox_process_emails
, TRUE
, TRUE
, 0);
141 process_emails_checkbtn
= gtk_check_button_new_with_label(
142 _("Process messages on receiving"));
143 gtk_widget_show(process_emails_checkbtn
);
144 gtk_box_pack_start(GTK_BOX(hbox_process_emails
), process_emails_checkbtn
, TRUE
, TRUE
, 0);
146 hbox_max_size
= gtk_box_new(GTK_ORIENTATION_HORIZONTAL
, 8);
147 gtk_widget_show(hbox_max_size
);
148 gtk_box_pack_start (GTK_BOX (vbox2
), hbox_max_size
, TRUE
, TRUE
, 0);
150 max_size_label
= gtk_label_new(_("Maximum size"));
151 gtk_widget_show(max_size_label
);
152 gtk_box_pack_start(GTK_BOX(hbox_max_size
), max_size_label
, FALSE
, FALSE
, 0);
154 max_size_spinbtn_adj
= gtk_adjustment_new(250, 0, 10000, 10, 10, 0);
155 max_size_spinbtn
= gtk_spin_button_new(GTK_ADJUSTMENT(max_size_spinbtn_adj
), 1, 0);
156 gtk_widget_show(max_size_spinbtn
);
157 gtk_box_pack_start(GTK_BOX(hbox_max_size
), max_size_spinbtn
, FALSE
, FALSE
, 0);
158 CLAWS_SET_TIP(max_size_spinbtn
,
159 _("Messages larger than this will not be checked"));
160 gtk_spin_button_set_numeric(GTK_SPIN_BUTTON(max_size_spinbtn
), TRUE
);
162 max_size_kb_label
= gtk_label_new(_("KiB"));
163 gtk_widget_show(max_size_kb_label
);
164 gtk_box_pack_start(GTK_BOX(hbox_max_size
), max_size_kb_label
, FALSE
, FALSE
, 0);
166 hbox_save_spam
= gtk_box_new(GTK_ORIENTATION_HORIZONTAL
, 8);
167 gtk_widget_show(hbox_save_spam
);
168 gtk_box_pack_start (GTK_BOX (vbox2
), hbox_save_spam
, TRUE
, TRUE
, 0);
170 save_spam_checkbtn
= gtk_check_button_new_with_label(_("Save spam in"));
171 gtk_widget_show(save_spam_checkbtn
);
172 gtk_box_pack_start(GTK_BOX(hbox_save_spam
), save_spam_checkbtn
, FALSE
, FALSE
, 0);
174 save_spam_folder_entry
= gtk_entry_new();
175 gtk_widget_show (save_spam_folder_entry
);
176 gtk_box_pack_start (GTK_BOX (hbox_save_spam
), save_spam_folder_entry
, TRUE
, TRUE
, 0);
177 CLAWS_SET_TIP(save_spam_folder_entry
,
178 _("Folder for storing identified spam. Leave empty to use the trash folder."));
180 save_spam_folder_select
= gtkut_get_browse_directory_btn(_("_Browse"));
181 gtk_widget_show (save_spam_folder_select
);
182 gtk_box_pack_start (GTK_BOX (hbox_save_spam
), save_spam_folder_select
, FALSE
, FALSE
, 0);
183 CLAWS_SET_TIP(save_spam_folder_select
,
184 _("Click this button to select a folder for storing spam"));
186 hbox_whitelist
= gtk_box_new(GTK_ORIENTATION_HORIZONTAL
, 8);
187 gtk_widget_show(hbox_whitelist
);
188 gtk_box_pack_start (GTK_BOX (vbox2
), hbox_whitelist
, TRUE
, TRUE
, 0);
190 whitelist_ab_checkbtn
= gtk_check_button_new_with_label(_("Whitelist senders found in address book/folder"));
191 gtk_widget_show(whitelist_ab_checkbtn
);
192 gtk_box_pack_start(GTK_BOX(hbox_whitelist
), whitelist_ab_checkbtn
, FALSE
, FALSE
, 0);
193 CLAWS_SET_TIP(whitelist_ab_checkbtn
,
194 _("Messages coming from your address book contacts will be received in the normal folder even if detected as spam"));
196 whitelist_ab_folder_combo
= combobox_text_new(TRUE
, _("Any"), NULL
);
197 gtk_widget_set_size_request(whitelist_ab_folder_combo
, 100, -1);
198 gtk_box_pack_start (GTK_BOX (hbox_whitelist
), whitelist_ab_folder_combo
, TRUE
, TRUE
, 0);
200 whitelist_ab_select_btn
= gtk_button_new_with_label(_("Select..."));
201 gtk_widget_show (whitelist_ab_select_btn
);
202 gtk_box_pack_start (GTK_BOX (hbox_whitelist
), whitelist_ab_select_btn
, FALSE
, FALSE
, 0);
203 CLAWS_SET_TIP(whitelist_ab_select_btn
,
204 _("Click this button to select a book or folder in the address book"));
206 learn_from_whitelist_chkbtn
= gtk_check_button_new_with_label(_("Learn whitelisted emails as ham"));
207 CLAWS_SET_TIP(learn_from_whitelist_chkbtn
,
208 _("If Bsfilter thought an email was spam or unsure, but it was whitelisted, "
209 "learn it as ham."));
210 gtk_widget_show(learn_from_whitelist_chkbtn
);
211 gtk_box_pack_start (GTK_BOX (vbox2
), learn_from_whitelist_chkbtn
, TRUE
, TRUE
, 0);
213 hbox_bspath
= gtk_box_new(GTK_ORIENTATION_HORIZONTAL
, 8);
214 gtk_widget_show(hbox_bspath
);
215 gtk_box_pack_start (GTK_BOX (vbox2
), hbox_bspath
, FALSE
, FALSE
, 0);
217 bspath_label
= gtk_label_new(_("Bsfilter call"));
218 gtk_widget_show(bspath_label
);
219 gtk_box_pack_start(GTK_BOX(hbox_bspath
), bspath_label
, FALSE
, FALSE
, 0);
221 bspath_entry
= gtk_entry_new();
222 gtk_widget_show(bspath_entry
);
223 gtk_box_pack_start(GTK_BOX(hbox_bspath
), bspath_entry
, FALSE
, FALSE
, 0);
224 CLAWS_SET_TIP(bspath_entry
,
225 _("Path to bsfilter executable"));
227 hbox_mark_as_read
= gtk_box_new(GTK_ORIENTATION_HORIZONTAL
, 8);
228 gtk_widget_show(hbox_mark_as_read
);
229 gtk_box_pack_start (GTK_BOX (vbox2
), hbox_mark_as_read
, TRUE
, TRUE
, 0);
231 mark_as_read_checkbtn
= gtk_check_button_new_with_label(_("Mark spam as read"));
232 gtk_widget_show(mark_as_read_checkbtn
);
233 gtk_box_pack_start(GTK_BOX(hbox_mark_as_read
), mark_as_read_checkbtn
, FALSE
, FALSE
, 0);
235 SET_TOGGLE_SENSITIVITY(save_spam_checkbtn
, save_spam_folder_entry
);
236 SET_TOGGLE_SENSITIVITY(save_spam_checkbtn
, save_spam_folder_select
);
237 SET_TOGGLE_SENSITIVITY(whitelist_ab_checkbtn
, whitelist_ab_folder_combo
);
238 SET_TOGGLE_SENSITIVITY(whitelist_ab_checkbtn
, whitelist_ab_select_btn
);
239 SET_TOGGLE_SENSITIVITY(whitelist_ab_checkbtn
, learn_from_whitelist_chkbtn
);
240 SET_TOGGLE_SENSITIVITY(save_spam_checkbtn
, mark_as_read_checkbtn
);
242 config
= bsfilter_get_config();
244 g_signal_connect(G_OBJECT(save_spam_folder_select
), "clicked",
245 G_CALLBACK(foldersel_cb
), save_spam_folder_entry
);
246 #ifndef USE_ALT_ADDRBOOK
247 g_signal_connect(G_OBJECT (whitelist_ab_select_btn
), "clicked",
248 G_CALLBACK(bsfilter_whitelist_ab_select_cb
), page
);
250 gtk_widget_set_sensitive(whitelist_ab_select_btn
, FALSE
);
253 gtk_spin_button_set_value(GTK_SPIN_BUTTON(max_size_spinbtn
), (float) config
->max_size
);
254 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(process_emails_checkbtn
), config
->process_emails
);
255 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(save_spam_checkbtn
), config
->receive_spam
);
256 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(whitelist_ab_checkbtn
), config
->whitelist_ab
);
257 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(learn_from_whitelist_chkbtn
), config
->learn_from_whitelist
);
258 if (config
->whitelist_ab_folder
!= NULL
) {
259 /* translate "Any" (stored UNtranslated) */
260 if (strcasecmp(config
->whitelist_ab_folder
, "Any") == 0)
261 gtk_entry_set_text(GTK_ENTRY(gtk_bin_get_child(GTK_BIN((whitelist_ab_folder_combo
)))),
262 config
->whitelist_ab_folder
);
264 /* backward compatibility (when translated "Any" was stored) */
265 if (g_utf8_collate(config
->whitelist_ab_folder
, _("Any")) == 0)
266 gtk_entry_set_text(GTK_ENTRY(gtk_bin_get_child(GTK_BIN((whitelist_ab_folder_combo
)))),
267 config
->whitelist_ab_folder
);
269 gtk_entry_set_text(GTK_ENTRY(gtk_bin_get_child(GTK_BIN((whitelist_ab_folder_combo
)))),
270 config
->whitelist_ab_folder
);
272 if (config
->save_folder
!= NULL
)
273 gtk_entry_set_text(GTK_ENTRY(save_spam_folder_entry
), config
->save_folder
);
274 if (config
->bspath
!= NULL
)
275 gtk_entry_set_text(GTK_ENTRY(bspath_entry
), config
->bspath
);
276 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(mark_as_read_checkbtn
), config
->mark_as_read
);
278 page
->max_size
= max_size_spinbtn
;
279 page
->process_emails
= process_emails_checkbtn
;
281 page
->receive_spam
= save_spam_checkbtn
;
282 page
->save_folder
= save_spam_folder_entry
;
283 page
->save_folder_select
= save_spam_folder_select
;
285 page
->whitelist_ab
= whitelist_ab_checkbtn
;
286 page
->whitelist_ab_folder_combo
= whitelist_ab_folder_combo
;
287 page
->learn_from_whitelist_chkbtn
= learn_from_whitelist_chkbtn
;
288 page
->bspath
= bspath_entry
;
290 page
->mark_as_read
= mark_as_read_checkbtn
;
292 page
->page
.widget
= vbox1
;
295 static void bsfilter_destroy_widget_func(PrefsPage
*_page
)
297 debug_print("Destroying Bsfilter widget\n");
300 static void bsfilter_save_func(PrefsPage
*_page
)
302 struct BsfilterPage
*page
= (struct BsfilterPage
*) _page
;
303 BsfilterConfig
*config
;
305 debug_print("Saving Bsfilter Page\n");
307 config
= bsfilter_get_config();
310 config
->process_emails
= gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(page
->process_emails
));
313 config
->receive_spam
= gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(page
->receive_spam
));
316 g_free(config
->save_folder
);
317 config
->save_folder
= gtk_editable_get_chars(GTK_EDITABLE(page
->save_folder
), 0, -1);
320 config
->whitelist_ab
= gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(page
->whitelist_ab
));
321 g_free(config
->whitelist_ab_folder
);
322 config
->whitelist_ab_folder
= gtk_editable_get_chars(
323 GTK_EDITABLE(gtk_bin_get_child(GTK_BIN((page
->whitelist_ab_folder_combo
)))), 0, -1);
324 /* store UNtranslated "Any" */
325 if (g_utf8_collate(config
->whitelist_ab_folder
, _("Any")) == 0) {
326 g_free(config
->whitelist_ab_folder
);
327 config
->whitelist_ab_folder
= g_strdup("Any");
330 /* learn_from_whitelist_chkbtn */
331 config
->learn_from_whitelist
= gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(page
->learn_from_whitelist_chkbtn
));
334 g_free(config
->bspath
);
335 config
->bspath
= gtk_editable_get_chars(GTK_EDITABLE(page
->bspath
), 0, -1);
338 config
->max_size
= gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(page
->max_size
));
341 config
->mark_as_read
= gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(page
->mark_as_read
));
343 if (config
->process_emails
) {
344 bsfilter_register_hook();
346 bsfilter_unregister_hook();
349 procmsg_register_spam_learner(bsfilter_learn
);
350 procmsg_spam_set_folder(config
->save_folder
, bsfilter_get_spam_folder
);
352 bsfilter_save_config();
355 typedef struct _BsCbData
{
361 static gboolean
gtk_message_callback(gpointer data
)
363 BsCbData
*cbdata
= (BsCbData
*)data
;
366 statusbar_print_all("%s", cbdata
->message
);
367 else if (cbdata
->total
== 0) {
370 if (cbdata
->total
&& cbdata
->done
)
371 statusbar_progress_all(cbdata
->done
, cbdata
->total
, 10);
373 statusbar_progress_all(0,0,0);
374 g_free(cbdata
->message
);
380 static void gtk_safe_message_callback(gchar
*message
, gint total
, gint done
, gboolean thread_safe
)
382 BsCbData
*cbdata
= g_new0(BsCbData
, 1);
384 cbdata
->message
= g_strdup(message
);
385 cbdata
->total
= total
;
388 g_timeout_add(0, gtk_message_callback
, cbdata
);
390 gtk_message_callback(cbdata
);
393 static struct BsfilterPage bsfilter_page
;
395 gint
bsfilter_gtk_init(void)
397 static gchar
*path
[3];
399 path
[0] = _("Plugins");
400 path
[1] = _("Bsfilter");
403 bsfilter_page
.page
.path
= path
;
404 bsfilter_page
.page
.create_widget
= bsfilter_create_widget_func
;
405 bsfilter_page
.page
.destroy_widget
= bsfilter_destroy_widget_func
;
406 bsfilter_page
.page
.save_page
= bsfilter_save_func
;
407 bsfilter_page
.page
.weight
= 35.0;
409 prefs_gtk_register_page((PrefsPage
*) &bsfilter_page
);
410 bsfilter_set_message_callback(gtk_safe_message_callback
);
412 debug_print("Bsfilter GTK plugin loaded\n");
416 void bsfilter_gtk_done(void)
418 prefs_gtk_unregister_page((PrefsPage
*) &bsfilter_page
);