2006-12-22 [colin] 2.6.1cvs64
authorColin Leroy <colin@colino.net>
Fri, 22 Dec 2006 09:55:44 +0000 (09:55 +0000)
committerColin Leroy <colin@colino.net>
Fri, 22 Dec 2006 09:55:44 +0000 (09:55 +0000)
* src/toolbar.c
* src/toolbar.h
Add a combo to the learn spam button
* src/plugins/bogofilter/bogofilter.c
* src/plugins/bogofilter/bogofilter_gtk.c
* src/plugins/bogofilter/bogofilter.h
Allow to store Unsure mails in a specific
folder to make better teaching easier

ChangeLog
PATCHSETS
configure.ac
src/plugins/bogofilter/bogofilter.c
src/plugins/bogofilter/bogofilter.h
src/plugins/bogofilter/bogofilter_gtk.c
src/toolbar.c
src/toolbar.h

index ba5eecf0d0113f13ad95202e63784ef727cd0241..271054846dde4503d84b2cd6c338a3dbf2ae8709 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2006-12-22 [colin]     2.6.1cvs64
+
+       * src/toolbar.c
+       * src/toolbar.h
+               Add a combo to the learn spam button
+       * src/plugins/bogofilter/bogofilter.c
+       * src/plugins/bogofilter/bogofilter_gtk.c
+       * src/plugins/bogofilter/bogofilter.h
+               Allow to store Unsure mails in a specific
+               folder to make better teaching easier
+
 2006-12-21 [wwp]       2.6.1cvs63
 
        * src/compose.c
index ca5ffa481fef0d174212f1ff9580a850c05ac052..b7d27485b1a5cdbd92f30387e702286ac850d023 100644 (file)
--- a/PATCHSETS
+++ b/PATCHSETS
 ( cvs diff -u -r 1.382.2.342 -r 1.382.2.343 src/compose.c;  cvs diff -u -r 1.2.2.5 -r 1.2.2.6 src/folder_item_prefs.h;  cvs diff -u -r 1.204.2.113 -r 1.204.2.114 src/prefs_common.c;  cvs diff -u -r 1.103.2.70 -r 1.103.2.71 src/prefs_common.h;  cvs diff -u -r 1.52.2.29 -r 1.52.2.30 src/prefs_folder_item.c;  cvs diff -u -r 1.5.2.27 -r 1.5.2.28 src/prefs_spelling.c;  cvs diff -u -r 1.9.2.44 -r 1.9.2.45 src/gtk/gtkaspell.c;  cvs diff -u -r 1.5.2.7 -r 1.5.2.8 src/gtk/gtkaspell.h;  ) > 2.6.1cvs61.patchset
 ( cvs diff -u -r 1.9.2.45 -r 1.9.2.46 src/gtk/gtkaspell.c;  ) > 2.6.1cvs62.patchset
 ( cvs diff -u -r 1.382.2.343 -r 1.382.2.344 src/compose.c;  cvs diff -u -r 1.204.2.114 -r 1.204.2.115 src/prefs_common.c;  cvs diff -u -r 1.103.2.71 -r 1.103.2.72 src/prefs_common.h;  cvs diff -u -r 1.5.2.28 -r 1.5.2.29 src/prefs_spelling.c;  cvs diff -u -r 1.9.2.46 -r 1.9.2.47 src/gtk/gtkaspell.c;  cvs diff -u -r 1.5.2.8 -r 1.5.2.9 src/gtk/gtkaspell.h;  ) > 2.6.1cvs63.patchset
+( cvs diff -u -r 1.43.2.57 -r 1.43.2.58 src/toolbar.c;  cvs diff -u -r 1.19.2.13 -r 1.19.2.14 src/toolbar.h;  cvs diff -u -r 1.1.2.21 -r 1.1.2.22 src/plugins/bogofilter/bogofilter.c;  cvs diff -u -r 1.1.2.13 -r 1.1.2.14 src/plugins/bogofilter/bogofilter_gtk.c;  cvs diff -u -r 1.1.2.7 -r 1.1.2.8 src/plugins/bogofilter/bogofilter.h;  ) > 2.6.1cvs64.patchset
index 070b13000126d9a8771d463288ac443c0366111d..6cfb53a3dc28a2b3ac8bfe457c807f7afd31c593 100644 (file)
@@ -11,7 +11,7 @@ MINOR_VERSION=6
 MICRO_VERSION=1
 INTERFACE_AGE=0
 BINARY_AGE=0
-EXTRA_VERSION=63
+EXTRA_VERSION=64
 EXTRA_RELEASE=
 EXTRA_GTK2_VERSION=
 
index 9060d13c8f7ca308028fa342e64634f5cbadec5b..7c32c22b86073de1c30859714142137d1249b989 100644 (file)
@@ -87,6 +87,10 @@ static PrefParam param[] = {
         NULL, NULL, NULL},
        {"save_folder", NULL, &config.save_folder, P_STRING,
         NULL, NULL, NULL},
+       {"save_unsure", "FALSE", &config.save_unsure, P_BOOL,
+        NULL, NULL, NULL},
+       {"save_unsure_folder", NULL, &config.save_unsure_folder, P_STRING,
+        NULL, NULL, NULL},
        {"max_size", "250", &config.max_size, P_INT,
         NULL, NULL, NULL},
        {"bogopath", "bogofilter", &config.bogopath, P_STRING,
@@ -133,6 +137,7 @@ typedef struct _BogoFilterData {
        gchar **bogo_args;
        GSList *msglist;
        GSList *new_hams;
+       GSList *new_unsure;
        GSList *new_spams;
        GSList *whitelisted_new_spams;
        gboolean done;
@@ -311,6 +316,14 @@ static void bogofilter_do_filter(BogoFilterData *data)
                                                 * it was not). */
                                                data->whitelisted_new_spams = g_slist_prepend(data->whitelisted_new_spams, msginfo);
 
+                                       } else if (config.save_unsure && parts && parts[0] && parts[1] && *parts[1] == 'U') {
+                                               
+                                               debug_print("message %d is unsure\n", msginfo->msgnum);
+                                               /* Spam will be filtered away */
+                                               data->mail_filtering_data->filtered = g_slist_prepend(
+                                                       data->mail_filtering_data->filtered, msginfo);
+                                               data->new_unsure = g_slist_prepend(data->new_unsure, msginfo);
+
                                        } else {
                                                
                                                debug_print("message %d is ham\n", msginfo->msgnum);
@@ -413,7 +426,8 @@ static gboolean mail_filtering_hook(gpointer source, gpointer data)
        static gboolean warned_error = FALSE;
        int status = 0;
        int total = 0, curnum = 0;
-       GSList *new_hams = NULL, *new_spams = NULL, *whitelisted_new_spams = NULL;
+       GSList *new_hams = NULL, *new_spams = NULL;
+       GSList *new_unsure, *whitelisted_new_spams = NULL;
        gchar *bogo_exec = (config.bogopath && *config.bogopath) ? config.bogopath:"bogofilter";
        gchar *bogo_args[4];
        gboolean ok_to_thread = TRUE;
@@ -461,6 +475,7 @@ static gboolean mail_filtering_hook(gpointer source, gpointer data)
        to_filter_data->msglist = msglist;
        to_filter_data->mail_filtering_data = mail_filtering_data;
        to_filter_data->new_hams = NULL;
+       to_filter_data->new_unsure = NULL;
        to_filter_data->new_spams = NULL;
        to_filter_data->whitelisted_new_spams = NULL;
        to_filter_data->done = FALSE;
@@ -499,6 +514,7 @@ static gboolean mail_filtering_hook(gpointer source, gpointer data)
 #endif
 
        new_hams = to_filter_data->new_hams;
+       new_unsure = to_filter_data->new_unsure;
        new_spams = to_filter_data->new_spams;
        whitelisted_new_spams = to_filter_data->whitelisted_new_spams;
        status = to_filter_data->status;
@@ -514,6 +530,11 @@ static gboolean mail_filtering_hook(gpointer source, gpointer data)
                MsgInfo *msginfo = (MsgInfo *)cur->data;
                procmsg_msginfo_unset_flags(msginfo, MSG_SPAM, 0);
        }
+       /* unflag unsure */
+       for (cur = new_unsure; cur; cur = cur->next) {
+               MsgInfo *msginfo = (MsgInfo *)cur->data;
+               procmsg_msginfo_unset_flags(msginfo, MSG_SPAM, 0);
+       }
        /* flag whitelisted spams */
        for (cur = whitelisted_new_spams; cur; cur = cur->next) {
                MsgInfo *msginfo = (MsgInfo *)cur->data;
@@ -561,22 +582,40 @@ static gboolean mail_filtering_hook(gpointer source, gpointer data)
                g_slist_free(mail_filtering_data->unfiltered);
                mail_filtering_data->filtered = NULL;
                mail_filtering_data->unfiltered = NULL;
-       } else if (config.receive_spam && new_spams) {
-               FolderItem *save_folder;
-
-               if ((!config.save_folder) ||
-                   (config.save_folder[0] == '\0') ||
-                   ((save_folder = folder_find_item_from_identifier(config.save_folder)) == NULL))
-                       save_folder = folder_get_default_trash();
-               if (save_folder) {
-                       for (cur = new_spams; cur; cur = cur->next) {
-                               msginfo = (MsgInfo *)cur->data;
-                               msginfo->is_move = TRUE;
-                               msginfo->to_filter_folder = save_folder;
+       } else {
+               if (config.receive_spam && new_spams) {
+                       FolderItem *save_folder;
+
+                       if ((!config.save_folder) ||
+                           (config.save_folder[0] == '\0') ||
+                           ((save_folder = folder_find_item_from_identifier(config.save_folder)) == NULL))
+                               save_folder = folder_get_default_trash();
+                       if (save_folder) {
+                               for (cur = new_spams; cur; cur = cur->next) {
+                                       msginfo = (MsgInfo *)cur->data;
+                                       msginfo->is_move = TRUE;
+                                       msginfo->to_filter_folder = save_folder;
+                               }
+                       }
+               }
+               if (config.save_unsure && new_unsure) {
+                       FolderItem *save_unsure_folder;
+
+                       if ((!config.save_unsure_folder) ||
+                           (config.save_unsure_folder[0] == '\0') ||
+                           ((save_unsure_folder = folder_find_item_from_identifier(config.save_unsure_folder)) == NULL))
+                               save_unsure_folder = folder_get_default_inbox();
+                       if (save_unsure_folder) {
+                               for (cur = new_unsure; cur; cur = cur->next) {
+                                       msginfo = (MsgInfo *)cur->data;
+                                       msginfo->is_move = TRUE;
+                                       msginfo->to_filter_folder = save_unsure_folder;
+                               }
                        }
                }
        } 
        g_slist_free(new_hams);
+       g_slist_free(new_unsure);
        g_slist_free(new_spams);
        g_slist_free(whitelisted_new_spams);
 
@@ -621,6 +660,8 @@ int bogofilter_learn(MsgInfo *msginfo, GSList *msglist, gboolean spam)
                        else 
                                /* learn as ham */
                                cmd = g_strdup_printf("%s -n -I '%s'", bogo_exec, file);
+                               
+                       debug_print("%s\n", cmd);
                        if ((status = execute_command_line(cmd, FALSE)) != 0)
                                log_error(_("Learning failed; `%s` returned with status %d."),
                                                cmd, status);
@@ -668,7 +709,8 @@ int bogofilter_learn(MsgInfo *msginfo, GSList *msglist, gboolean spam)
                                else 
                                        /* learn as ham */
                                        cmd = g_strdup_printf("%s -n -I '%s'", bogo_exec, file);
-
+                               
+                               debug_print("%s\n", cmd);
                                if ((status = execute_command_line(cmd, FALSE)) != 0)
                                        log_error(_("Learning failed; `%s` returned with status %d."),
                                                        cmd, status);
@@ -695,7 +737,7 @@ int bogofilter_learn(MsgInfo *msginfo, GSList *msglist, gboolean spam)
                                bogo_args[1] = spam ? "-s":"-n";
                        bogo_args[2] = "-b";
                        bogo_args[3] = NULL;
-
+                       debug_print("|%s %s %s ...\n", bogo_args[0], bogo_args[1], bogo_args[2]);
                        bogo_forked = g_spawn_async_with_pipes(
                                        NULL, bogo_args,NULL, G_SPAWN_SEARCH_PATH|G_SPAWN_DO_NOT_REAP_CHILD,
                                        NULL, NULL, &bogo_pid, &bogo_stdin,
index 56f816972ea585140269942a8f9a09d3880c411f..f270698a34f69c5e9557b18158fdd8d2d02ec07d 100644 (file)
@@ -36,6 +36,8 @@ struct _BogofilterConfig
        gboolean                 insert_header;
        gboolean                 whitelist_ab;
        gchar                   *whitelist_ab_folder;
+       gboolean                 save_unsure;
+       gchar                   *save_unsure_folder;
 };
 
 BogofilterConfig *bogofilter_get_config              (void);
index 18bb1f1ae6243ecc43530ec8c3f3aec3a3342387..cbc476bd8b931f912260c9714b44c129e0265c98 100644 (file)
@@ -50,6 +50,9 @@ struct BogofilterPage
        GtkWidget *receive_spam;
        GtkWidget *save_folder;
        GtkWidget *save_folder_select;
+       GtkWidget *save_unsure;
+       GtkWidget *save_unsure_folder;
+       GtkWidget *save_unsure_folder_select;
        GtkWidget *insert_header;
        GtkWidget *max_size;
        GtkWidget *bogopath;
@@ -66,15 +69,15 @@ static const gchar *whitelist_ab_folder_text [] = {
 
 static void foldersel_cb(GtkWidget *widget, gpointer data)
 {
-       struct BogofilterPage *page = (struct BogofilterPage *) data;
+       GtkWidget *entry = (GtkWidget *) data;
        FolderItem *item;
        gchar *item_id;
        gint newpos = 0;
        
        item = foldersel_folder_sel(NULL, FOLDER_SEL_MOVE, NULL);
        if (item && (item_id = folder_item_get_identifier(item)) != NULL) {
-               gtk_editable_delete_text(GTK_EDITABLE(page->save_folder), 0, -1);
-               gtk_editable_insert_text(GTK_EDITABLE(page->save_folder), item_id, strlen(item_id), &newpos);
+               gtk_editable_delete_text(GTK_EDITABLE(entry), 0, -1);
+               gtk_editable_insert_text(GTK_EDITABLE(entry), item_id, strlen(item_id), &newpos);
                g_free(item_id);
        }
 }
@@ -100,7 +103,8 @@ static void bogofilter_create_widget_func(PrefsPage * _page,
 
        GtkWidget *vbox1, *vbox2;
        GtkWidget *hbox_max_size;
-       GtkWidget *hbox_process_emails, *hbox_save_spam, *hbox_bogopath, *hbox_whitelist;
+       GtkWidget *hbox_process_emails, *hbox_save_spam, *hbox_save_unsure;
+       GtkWidget *hbox_bogopath, *hbox_whitelist;
 
        GtkWidget *max_size_label;
        GtkObject *max_size_spinbtn_adj;
@@ -113,6 +117,10 @@ static void bogofilter_create_widget_func(PrefsPage * _page,
        GtkWidget *save_spam_folder_entry;
        GtkWidget *save_spam_folder_select;
 
+       GtkWidget *save_unsure_checkbtn;
+       GtkWidget *save_unsure_folder_entry;
+       GtkWidget *save_unsure_folder_select;
+
        GtkWidget *insert_header_chkbtn;
        GtkWidget *whitelist_ab_chkbtn;
        GtkWidget *bogopath_label;
@@ -176,7 +184,7 @@ static void bogofilter_create_widget_func(PrefsPage * _page,
        gtk_widget_show (save_spam_folder_entry);
        gtk_box_pack_start (GTK_BOX (hbox_save_spam), save_spam_folder_entry, TRUE, TRUE, 0);
        gtk_tooltips_set_tip(tooltips, save_spam_folder_entry,
-                       _("Folder for storing identified spam. Leave empty to use the default trash folder"),
+                       _("Folder for storing identified spam. Leave empty to use the default trash folder."),
                        NULL);
 
        save_spam_folder_select = gtkut_get_browse_directory_btn(_("_Browse"));
@@ -186,6 +194,28 @@ static void bogofilter_create_widget_func(PrefsPage * _page,
                        _("Click this button to select a folder for storing spam"),
                        NULL);
 
+       hbox_save_unsure = gtk_hbox_new(FALSE, 8);
+       gtk_widget_show(hbox_save_unsure);
+       gtk_box_pack_start (GTK_BOX (vbox2), hbox_save_unsure, TRUE, TRUE, 0);
+
+       save_unsure_checkbtn = gtk_check_button_new_with_label(_("When unsure, move in"));
+       gtk_widget_show(save_unsure_checkbtn);
+       gtk_box_pack_start(GTK_BOX(hbox_save_unsure), save_unsure_checkbtn, FALSE, FALSE, 0);
+
+       save_unsure_folder_entry = gtk_entry_new();
+       gtk_widget_show (save_unsure_folder_entry);
+       gtk_box_pack_start (GTK_BOX (hbox_save_unsure), save_unsure_folder_entry, TRUE, TRUE, 0);
+       gtk_tooltips_set_tip(tooltips, save_unsure_folder_entry,
+                       _("Folder for storing mail for which spam status is Unsure. Leave empty to use the default inbox folder."),
+                       NULL);
+
+       save_unsure_folder_select = gtkut_get_browse_directory_btn(_("_Browse"));
+       gtk_widget_show (save_unsure_folder_select);
+       gtk_box_pack_start (GTK_BOX (hbox_save_unsure), save_unsure_folder_select, FALSE, FALSE, 0);
+       gtk_tooltips_set_tip(tooltips, save_unsure_folder_select,
+                       _("Click this button to select a folder for storing Unsure mails"),
+                       NULL);
+
        insert_header_chkbtn = gtk_check_button_new_with_label(_("Insert X-Bogosity header"));
        gtk_widget_show(insert_header_chkbtn);
        gtk_box_pack_start(GTK_BOX(vbox2), insert_header_chkbtn, FALSE, FALSE, 0);
@@ -244,19 +274,25 @@ static void bogofilter_create_widget_func(PrefsPage * _page,
        SET_TOGGLE_SENSITIVITY(save_spam_checkbtn, save_spam_folder_entry);
        SET_TOGGLE_SENSITIVITY(save_spam_checkbtn, save_spam_folder_select);
        SET_TOGGLE_SENSITIVITY(save_spam_checkbtn, insert_header_chkbtn);
+       SET_TOGGLE_SENSITIVITY(save_unsure_checkbtn, save_unsure_folder_entry);
+       SET_TOGGLE_SENSITIVITY(save_unsure_checkbtn, save_unsure_folder_select);
+       SET_TOGGLE_SENSITIVITY(save_unsure_checkbtn, insert_header_chkbtn);
        SET_TOGGLE_SENSITIVITY(whitelist_ab_chkbtn, whitelist_ab_folder_combo);
        SET_TOGGLE_SENSITIVITY(whitelist_ab_chkbtn, whitelist_ab_select_btn);
 
        config = bogofilter_get_config();
 
        g_signal_connect(G_OBJECT(save_spam_folder_select), "clicked",
-                       G_CALLBACK(foldersel_cb), page);
+                       G_CALLBACK(foldersel_cb), save_spam_folder_entry);
+       g_signal_connect(G_OBJECT(save_unsure_folder_select), "clicked",
+                       G_CALLBACK(foldersel_cb), save_unsure_folder_entry);
        g_signal_connect(G_OBJECT (whitelist_ab_select_btn), "clicked",
                         G_CALLBACK(bogofilter_whitelist_ab_select_cb), page);
 
        gtk_spin_button_set_value(GTK_SPIN_BUTTON(max_size_spinbtn), (float) config->max_size);
        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(process_emails_checkbtn), config->process_emails);
        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(save_spam_checkbtn), config->receive_spam);
+       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(save_unsure_checkbtn), config->save_unsure);
        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(insert_header_chkbtn), config->insert_header);
        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(whitelist_ab_chkbtn), config->whitelist_ab);
        if (config->whitelist_ab_folder != NULL)
@@ -264,17 +300,25 @@ static void bogofilter_create_widget_func(PrefsPage * _page,
                                config->whitelist_ab_folder);
        if (config->save_folder != NULL)
                gtk_entry_set_text(GTK_ENTRY(save_spam_folder_entry), config->save_folder);
+       if (config->save_unsure_folder != NULL)
+               gtk_entry_set_text(GTK_ENTRY(save_unsure_folder_entry), config->save_unsure_folder);
        if (config->bogopath != NULL)
                gtk_entry_set_text(GTK_ENTRY(bogopath_entry), config->bogopath);
 
        page->max_size = max_size_spinbtn;
        page->process_emails = process_emails_checkbtn;
+
        page->receive_spam = save_spam_checkbtn;
+       page->save_folder = save_spam_folder_entry;
+       page->save_folder_select = save_spam_folder_select;
+
+       page->save_unsure = save_unsure_checkbtn;
+       page->save_unsure_folder = save_unsure_folder_entry;
+       page->save_unsure_folder_select = save_unsure_folder_select;
+
        page->insert_header = insert_header_chkbtn;
        page->whitelist_ab = whitelist_ab_chkbtn;
        page->whitelist_ab_folder_combo = whitelist_ab_folder_combo;
-       page->save_folder = save_spam_folder_entry;
-       page->save_folder_select = save_spam_folder_select;
        page->bogopath = bogopath_entry;
 
        page->page.widget = vbox1;
@@ -304,6 +348,13 @@ static void bogofilter_save_func(PrefsPage *_page)
        g_free(config->save_folder);
        config->save_folder = gtk_editable_get_chars(GTK_EDITABLE(page->save_folder), 0, -1);
 
+       /* save_unsure */
+       config->save_unsure = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(page->save_unsure));
+
+       /* save_unsure_folder */
+       g_free(config->save_unsure_folder);
+       config->save_unsure_folder = gtk_editable_get_chars(GTK_EDITABLE(page->save_unsure_folder), 0, -1);
+
        /* insert_header */
        config->insert_header = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(page->insert_header));
 
index ce4b37c20ce536ce25f72ad6e66fa201646cbe75..7dda259185873c0bde6316bb0d5ded9ec277426e 100644 (file)
@@ -89,6 +89,8 @@ static void activate_compose_button           (Toolbar        *toolbar,
 /* toolbar callbacks */
 static void toolbar_reply                      (gpointer        data, 
                                                 guint           action);
+static void toolbar_learn                      (gpointer        data, 
+                                                guint           action);
 static void toolbar_delete_cb                  (GtkWidget      *widget,
                                                 gpointer        data);
 static void toolbar_trash_cb                   (GtkWidget      *widget,
@@ -238,6 +240,11 @@ static GtkItemFactoryEntry forward_entries[] =
        {N_("/For_ward as attachment"), "<shift>F", toolbar_reply, COMPOSE_FORWARD_AS_ATTACH, NULL},
        {N_("/Redirec_t"),              NULL,       toolbar_reply, COMPOSE_REDIRECT, NULL}
 };
+static GtkItemFactoryEntry learn_entries[] =
+{
+       {N_("/Learn as _Spam"),         NULL,   toolbar_learn, TRUE, NULL},
+       {N_("/Learn as _Ham"),          NULL,   toolbar_learn, FALSE, NULL}
+};
 
 
 gint toolbar_ret_val_from_descr(const gchar *descr)
@@ -1007,6 +1014,34 @@ static void toolbar_compose_cb(GtkWidget *widget, gpointer data)
        }
 }
 
+static void toolbar_learn(gpointer data, guint as_spam)
+{
+       ToolbarItem *toolbar_item = (ToolbarItem*)data;
+       MainWindow *mainwin;
+       MessageView *msgview;
+
+       g_return_if_fail(toolbar_item != NULL);
+
+       switch (toolbar_item->type) {
+       case TOOLBAR_MAIN:
+               mainwin = (MainWindow*)toolbar_item->parent;
+               if (as_spam) 
+                       mainwindow_learn(mainwin, TRUE);
+               else
+                       mainwindow_learn(mainwin, FALSE);
+               break;
+       case TOOLBAR_MSGVIEW:
+               msgview = (MessageView*)toolbar_item->parent;
+               if (as_spam) 
+                       messageview_learn(msgview, TRUE);
+               else
+                       messageview_learn(msgview, FALSE);
+               break;
+       default:
+               debug_print("toolbar event not supported\n");
+       }
+}
+
 static void toolbar_learn_cb(GtkWidget *widget, gpointer data)
 {
        ToolbarItem *toolbar_item = (ToolbarItem*)data;
@@ -1443,6 +1478,7 @@ Toolbar *toolbar_create(ToolbarType        type,
        ComboButton *replysender_combo;
        ComboButton *fwd_combo;
        ComboButton *compose_combo;
+       ComboButton *ham_combo;
 
        GtkTooltips *toolbar_tips;
        ToolbarSylpheedActions *action_item;
@@ -1559,6 +1595,17 @@ Toolbar *toolbar_create(ToolbarType       type,
                        gtk_tooltips_set_tip(GTK_TOOLTIPS(toolbar_tips), 
                                             toolbar_data->learn_ham_btn,
                                           _("Learn Ham"), NULL);                       
+                       n_menu_entries = sizeof(learn_entries) / 
+                               sizeof(learn_entries[0]);
+                       ham_combo = gtkut_combo_button_create(toolbar_data->learn_spam_btn,
+                                             learn_entries, n_menu_entries,
+                                             "<LearnSpam>", (gpointer)toolbar_item);
+                       gtk_button_set_relief(GTK_BUTTON(ham_combo->arrow),
+                                             GTK_RELIEF_NONE);
+                       gtk_toolbar_append_widget(GTK_TOOLBAR(toolbar),
+                                                 GTK_WIDGET_PTR(ham_combo),
+                                                 _("Learn as..."), "Learn");
+                       toolbar_data->ham_combo = ham_combo;
                        break;
                case A_REPLY_MESSAGE:
                        toolbar_data->reply_btn = item;
@@ -1969,6 +2016,10 @@ void toolbar_main_set_sensitive(gpointer data)
                SET_WIDGET_COND(toolbar->learn_spam_btn, 
                        M_TARGET_EXIST|M_CAN_LEARN_SPAM);
 
+       if (toolbar->ham_combo)
+               SET_WIDGET_COND(GTK_WIDGET_PTR(toolbar->ham_combo),
+                       M_TARGET_EXIST|M_CAN_LEARN_SPAM);
+
        if (toolbar->cancel_inc_btn)
                SET_WIDGET_COND(toolbar->cancel_inc_btn,
                                M_INC_ACTIVE);
index 8de1f1a7f78c7da08c39786c17a28e1680a2b134..6cff2626b551a9e517beb1e71dc7bc42695ae101 100644 (file)
@@ -79,6 +79,8 @@ struct _Toolbar {
        GtkWidget *separator;
        GtkWidget *learn_spam_btn;
        GtkWidget *learn_ham_btn;
+       ComboButton *ham_combo;
+       
        GtkWidget *cancel_inc_btn;
        
        ComposeButtonType compose_btn_type;