follow-up and reply to / build threads with subjects
authorHoà Viêt Dinh <dinh.viet.hoa@free.fr>
Mon, 18 Jun 2001 00:50:21 +0000 (00:50 +0000)
committerHoà Viêt Dinh <dinh.viet.hoa@free.fr>
Mon, 18 Jun 2001 00:50:21 +0000 (00:50 +0000)
ChangeLog.claws
src/compose.c
src/compose.h
src/mainwindow.c
src/summaryview.c
src/summaryview.h

index db40386..f23cd4f 100644 (file)
@@ -1,3 +1,12 @@
+2001-06-18 [hoa]
+
+       * src/compose.[ch]
+       * src/mainwindow.c
+               Follow-up and reply to
+
+       * src/summaryview.[ch]
+               Build threads also with subjects
+
 2001-06-17 [hoa]
 
        * src/compose.c
index e319ac5..76343d6 100644 (file)
@@ -143,7 +143,9 @@ static gchar *compose_quote_parse_fmt               (Compose        *compose,
 static void compose_reply_set_entry            (Compose        *compose,
                                                 MsgInfo        *msginfo,
                                                 gboolean        to_all,
-                                                gboolean        to_sender);
+                                                gboolean        to_sender,
+                                                gboolean
+                                                followup_and_reply_to);
 static void compose_reedit_set_entry           (Compose        *compose,
                                                 MsgInfo        *msginfo);
 static void compose_insert_sig                 (Compose        *compose);
@@ -381,6 +383,11 @@ static gchar *compose_quote_fmt            (Compose        *compose,
                                         const gchar    *fmt,
                                         const gchar    * qmark);
 
+static void compose_generic_reply(MsgInfo *msginfo, gboolean quote,
+                                 gboolean to_all,
+                                 gboolean ignore_replyto,
+                                 gboolean followup_and_reply_to);
+
 static GtkItemFactoryEntry compose_popup_entries[] =
 {
        {N_("/_Add..."),        NULL, compose_attach_cb, 0, NULL},
@@ -491,8 +498,49 @@ msginfo->folder->folder->change_flags(msginfo->folder->folder, \
                                      msginfo); \
 }
 
+/*
+Compose * compose_new_followup_and_replyto(PrefsAccount *account,
+                                          const gchar *followupto, gchar * to)
+{
+       Compose *compose;
+
+       if (!account) account = cur_account;
+       g_return_val_if_fail(account != NULL, NULL);
+       g_return_val_if_fail(account->protocol != A_NNTP, NULL);
+
+       compose = compose_create(account);
+       compose->mode = COMPOSE_NEW;
+
+       if (prefs_common.auto_sig)
+               compose_insert_sig(compose);
+       gtk_editable_set_position(GTK_EDITABLE(compose->text), 0);
+       gtk_stext_set_point(GTK_STEXT(compose->text), 0);
+
+       compose_entry_append(compose, to, COMPOSE_TO);
+       compose_entry_append(compose, followupto, COMPOSE_NEWSGROUPS);
+       gtk_widget_grab_focus(compose->subject_entry);
+
+       return compose;
+}
+*/
+
 void compose_reply(MsgInfo *msginfo, gboolean quote, gboolean to_all,
                   gboolean ignore_replyto)
+{
+       compose_generic_reply(msginfo, quote, to_all, ignore_replyto, FALSE);
+}
+
+void compose_followup_and_reply_to(MsgInfo *msginfo, gboolean quote,
+                                  gboolean to_all,
+                                  gboolean ignore_replyto)
+{
+       compose_generic_reply(msginfo, quote, to_all, ignore_replyto, TRUE);
+}
+
+static void compose_generic_reply(MsgInfo *msginfo, gboolean quote,
+                                 gboolean to_all,
+                                 gboolean ignore_replyto,
+                                 gboolean followup_and_reply_to)
 {
        Compose *compose;
        PrefsAccount *account;
@@ -506,7 +554,8 @@ void compose_reply(MsgInfo *msginfo, gboolean quote, gboolean to_all,
        if (!account) account = cur_account;
        g_return_if_fail(account != NULL);
 
-       if (ignore_replyto && account->protocol == A_NNTP) {
+       if (ignore_replyto && account->protocol == A_NNTP &&
+           !followup_and_reply_to) {
                reply_account =
                        account_find_mail_from_address(account->address);
                if (!reply_account)
@@ -524,8 +573,17 @@ void compose_reply(MsgInfo *msginfo, gboolean quote, gboolean to_all,
        compose = compose_create(reply_account);
        compose->mode = COMPOSE_REPLY;
 
+
+       if (followup_and_reply_to) {
+               gtk_widget_show(compose->to_hbox);
+               gtk_widget_show(compose->to_entry);
+               gtk_table_set_row_spacing(GTK_TABLE(compose->table), 1, 4);
+               compose->use_to = TRUE;
+       }
+
        if (compose_parse_header(compose, msginfo) < 0) return;
-       compose_reply_set_entry(compose, msginfo, to_all, ignore_replyto);
+       compose_reply_set_entry(compose, msginfo, to_all, ignore_replyto,
+                               followup_and_reply_to);
 
        text = GTK_STEXT(compose->text);
        gtk_stext_freeze(text);
@@ -1360,7 +1418,8 @@ static gchar *compose_quote_parse_fmt(Compose *compose, MsgInfo *msginfo,
 */
 
 static void compose_reply_set_entry(Compose *compose, MsgInfo *msginfo,
-                                   gboolean to_all, gboolean ignore_replyto)
+                                   gboolean to_all, gboolean ignore_replyto,
+                                   gboolean followup_and_reply_to)
 {
        GSList *cc_list;
        GSList *cur;
@@ -1370,7 +1429,7 @@ static void compose_reply_set_entry(Compose *compose, MsgInfo *msginfo,
        g_return_if_fail(compose->account != NULL);
        g_return_if_fail(msginfo != NULL);
 
-       if (compose->account->protocol != A_NNTP)
+       if ((compose->account->protocol != A_NNTP) || followup_and_reply_to)
                gtk_entry_set_text(GTK_ENTRY(compose->to_entry),
                                   ( (compose->replyto && !ignore_replyto) 
                                     ? compose->replyto
index 9e85cb0..f60b47c 100644 (file)
@@ -52,6 +52,7 @@ typedef enum
        COMPOSE_REPLY_WITH_QUOTE,
        COMPOSE_REPLY_WITHOUT_QUOTE,
        COMPOSE_REPLY_TO_SENDER,
+       COMPOSE_FOLLOWUP_AND_REPLY_TO,
        COMPOSE_REPLY_TO_SENDER_WITH_QUOTE,
        COMPOSE_REPLY_TO_SENDER_WITHOUT_QUOTE,
        COMPOSE_REPLY_TO_ALL,
@@ -173,6 +174,10 @@ Compose * compose_new              (PrefsAccount   *account);
 Compose * compose_new_with_recipient   (PrefsAccount   *account,
                                         const gchar    *to);
 
+void compose_followup_and_reply_to (MsgInfo    *msginfo,
+                                   gboolean     quote,
+                                   gboolean     to_all,
+                                   gboolean     ignore_replyto);
 void compose_reply             (MsgInfo        *msginfo,
                                 gboolean        quote,
                                 gboolean        to_all,
index 1e2a861..b46419b 100644 (file)
@@ -484,6 +484,7 @@ static GtkItemFactoryEntry mainwin_entries[] =
        {N_("/_Message/Compose a news message"),        NULL,   compose_news_cb, 0, NULL},
        {N_("/_Message/_Reply"),                "<alt>R",       reply_cb, COMPOSE_REPLY, NULL},
        {N_("/_Message/Repl_y to sender"),      "<control><alt>R", reply_cb, COMPOSE_REPLY_TO_SENDER, NULL},
+       {N_("/_Message/Follow-up and reply to"), NULL, reply_cb, COMPOSE_FOLLOWUP_AND_REPLY_TO, NULL},
        {N_("/_Message/Reply to a_ll"),         "<shift><alt>R", reply_cb, COMPOSE_REPLY_TO_ALL, NULL},
        {N_("/_Message/_Forward"),              "<control>F", reply_cb, COMPOSE_FORWARD, NULL},
        {N_("/_Message/Forward as a_ttachment"),
@@ -1191,6 +1192,13 @@ void main_window_set_menu_sensitive(MainWindow *mainwin, gint selection)
        menu_set_sensitive(ifactory, "/Summary/Next message", sens);
        menu_set_sensitive(ifactory, "/Summary/Next unread message", sens);
        menu_set_sensitive(ifactory, "/Summary/Sort", sens);
+
+       if (mainwin->summaryview->folder_item &&
+           mainwin->summaryview->folder_item->folder->account)
+               sens = mainwin->summaryview->folder_item->folder->account->protocol == A_NNTP;
+       else
+               sens = FALSE;
+       menu_set_sensitive(ifactory, "/Message/Follow-up and reply to", sens);
 }
 
 void main_window_popup(MainWindow *mainwin)
@@ -2063,6 +2071,11 @@ static void reply_cb(MainWindow *mainwin, guint action, GtkWidget *widget)
                compose_reply(msginfo, prefs_common.reply_with_quote,
                              FALSE, TRUE);
                break;
+       case COMPOSE_FOLLOWUP_AND_REPLY_TO:
+               compose_followup_and_reply_to(msginfo,
+                                             prefs_common.reply_with_quote,
+                                             FALSE, TRUE);
+               break;
        case COMPOSE_REPLY_TO_ALL:
                compose_reply(msginfo, prefs_common.reply_with_quote,
                              TRUE, FALSE);
index 06cc602..8fc4e6e 100644 (file)
@@ -320,6 +320,7 @@ static GtkItemFactoryEntry summary_popup_entries[] =
        {N_("/---"),                    NULL, NULL,             0, "<Separator>"},
        {N_("/_Reply"),                 NULL, summary_reply_cb, COMPOSE_REPLY, NULL},
        {N_("/Repl_y to sender"),       NULL, summary_reply_cb, COMPOSE_REPLY_TO_SENDER, NULL},
+       {N_("/Follow-up and reply to"), NULL, summary_reply_cb, COMPOSE_FOLLOWUP_AND_REPLY_TO, NULL},
        {N_("/Reply to a_ll"),          NULL, summary_reply_cb, COMPOSE_REPLY_TO_ALL, NULL},
        {N_("/_Forward"),               NULL, summary_reply_cb, COMPOSE_FORWARD, NULL},
        {N_("/Forward as a_ttachment"),
@@ -867,6 +868,10 @@ void summary_clear_list(SummaryView *summaryview)
                g_hash_table_destroy(summaryview->msgid_table);
                summaryview->msgid_table = NULL;
        }
+       if (summaryview->subject_table) {
+               g_hash_table_destroy(summaryview->subject_table);
+               summaryview->subject_table = NULL;
+       }
        summaryview->mlist = NULL;
        if (summaryview->folder_table) {
                g_hash_table_destroy(summaryview->folder_table);
@@ -954,6 +959,13 @@ static void summary_set_menu_sensitive(SummaryView *summaryview)
        menu_set_sensitive(ifactory, "/Mark/Mark as read",          TRUE);
 
        menu_set_sensitive(ifactory, "/Select all", TRUE);
+
+       if (summaryview->folder_item->folder->account)
+               sens = summaryview->folder_item->folder->account->protocol
+                       == A_NNTP;
+       else
+               sens = FALSE;
+       menu_set_sensitive(ifactory, "/Follow-up and reply to", sens);
 }
 
 void summary_select_next_unread(SummaryView *summaryview)
@@ -1479,6 +1491,24 @@ void summary_sort(SummaryView *summaryview, SummarySortType type)
        main_window_cursor_normal(summaryview->mainwin);
 }
 
+static GtkCTreeNode * subject_table_lookup(GHashTable *subject_table,
+                                          gchar * subject)
+{
+       if (g_strncasecmp(subject, "Re: ", 4) == 0)
+               return g_hash_table_lookup(subject_table, subject + 4);
+       else
+               return g_hash_table_lookup(subject_table, subject);
+}
+
+static void subject_table_insert(GHashTable *subject_table, gchar * subject,
+                                GtkCTreeNode * node)
+{
+       if (g_strncasecmp(subject, "Re: ", 4) == 0)
+               g_hash_table_insert(subject_table, subject + 4, node);
+       else
+               g_hash_table_insert(subject_table, subject, node);
+}
+
 static void summary_set_ctree_from_list(SummaryView *summaryview,
                                        GSList *mlist)
 {
@@ -1489,6 +1519,7 @@ static void summary_set_ctree_from_list(SummaryView *summaryview,
        GtkCTreeNode *node, *parent;
        gchar *text[N_SUMMARY_COLS];
        GHashTable *msgid_table;
+       GHashTable *subject_table;
        GSList * cur;
        GtkCTreeNode *cur_parent;
 
@@ -1500,6 +1531,8 @@ static void summary_set_ctree_from_list(SummaryView *summaryview,
 
        msgid_table = g_hash_table_new(g_str_hash, g_str_equal);
        summaryview->msgid_table = msgid_table;
+       subject_table = g_hash_table_new(g_str_hash, g_str_equal);
+       summaryview->subject_table = subject_table;
 
        if (prefs_common.use_addr_book)
                start_address_completion();
@@ -1530,6 +1563,10 @@ static void summary_set_ctree_from_list(SummaryView *summaryview,
                                parent = g_hash_table_lookup
                                        (msgid_table, msginfo->inreplyto);
                        }
+                       if (msginfo->subject) {
+                               parent = subject_table_lookup
+                                       (subject_table, msginfo->subject);
+                       }
 
                        summary_set_header(text, msginfo);
 
@@ -1547,6 +1584,12 @@ static void summary_set_ctree_from_list(SummaryView *summaryview,
                            == NULL)
                                g_hash_table_insert(msgid_table,
                                                    msginfo->msgid, node);
+                       if (msginfo->subject &&
+                           subject_table_lookup(subject_table,
+                                                msginfo->subject) == NULL) {
+                               subject_table_insert(subject_table,
+                                                    msginfo->subject, node);
+                       }
 
                        cur_parent = parent;
                        cur_msginfo = msginfo;
@@ -1573,6 +1616,9 @@ static void summary_set_ctree_from_list(SummaryView *summaryview,
                                    *cur_msginfo->inreplyto) {
                                        cur_parent = g_hash_table_lookup(msgid_table, cur_msginfo->inreplyto);
                                }
+                               if (cur_parent == NULL && cur_msginfo->subject) {
+                                       cur_parent = subject_table_lookup(subject_table, cur_msginfo->subject);
+                               }
                        }
                }
 
@@ -1595,6 +1641,12 @@ static void summary_set_ctree_from_list(SummaryView *summaryview,
                            == NULL)
                                g_hash_table_insert(msgid_table,
                                                    msginfo->msgid, node);
+
+                       if (msginfo->subject &&
+                           subject_table_lookup(subject_table,
+                                                msginfo->subject) == NULL)
+                               subject_table_insert(subject_table,
+                                                    msginfo->subject, node);
                }
        }
 
@@ -1612,9 +1664,12 @@ static void summary_set_ctree_from_list(SummaryView *summaryview,
 
        debug_print(_("done.\n"));
        STATUSBAR_POP(summaryview->mainwin);
-       if (debug_mode)
+       if (debug_mode) {
                debug_print("\tmsgid hash table size = %d\n",
                            g_hash_table_size(msgid_table));
+               debug_print("\tsubject hash table size = %d\n",
+                           g_hash_table_size(subject_table));
+       }
 }
 
 struct wcachefp
@@ -2690,7 +2745,7 @@ void summary_thread_build(SummaryView *summaryview)
        gtk_ctree_pre_recursive_to_depth
                (GTK_CTREE(summaryview->ctree), NULL, 1,
                 GTK_CTREE_FUNC(summary_thread_func),
-                summaryview->msgid_table);
+                summaryview);
 
        gtk_clist_thaw(GTK_CLIST(summaryview->ctree));
 
@@ -2746,13 +2801,19 @@ static void summary_thread_func(GtkCTree *ctree, GtkCTreeNode *node,
 {
        MsgInfo *msginfo;
        GtkCTreeNode *parent;
-       GHashTable *msgid_table = (GHashTable *)data;
+       
+       SummaryView * summaryview = (SummaryView *) data;
+       GHashTable *msgid_table = summaryview->msgid_table;
+       GHashTable *subject_table = summaryview->subject_table;
 
        msginfo = GTKUT_CTREE_NODE_GET_ROW_DATA(node);
 
        if (!msginfo || !msginfo->inreplyto) return;
 
        parent = g_hash_table_lookup(msgid_table, msginfo->inreplyto);
+       if (parent == NULL && msginfo->subject) {
+               parent = subject_table_lookup(subject_table, msginfo->subject);
+       }
 
        if (parent && parent != node) {
                gtk_ctree_move(ctree, node, parent, NULL);
@@ -3208,6 +3269,11 @@ static void summary_reply_cb(SummaryView *summaryview, guint action,
                compose_reply(msginfo, prefs_common.reply_with_quote,
                              FALSE, TRUE);
                break;
+       case COMPOSE_FOLLOWUP_AND_REPLY_TO:
+               compose_followup_and_reply_to(msginfo,
+                                             prefs_common.reply_with_quote,
+                                             FALSE, TRUE);
+               break;
        case COMPOSE_REPLY_TO_SENDER_WITH_QUOTE:
                compose_reply(msginfo, TRUE, FALSE, TRUE);
                break;
index afd3b79..72cfa2f 100644 (file)
@@ -132,6 +132,7 @@ private:
 */
        /* table for looking up message-id */
        GHashTable *msgid_table;
+       GHashTable *subject_table;
 
        /* list for moving/deleting messages */
        GSList *mlist;