From: Paul Mangan Date: Sun, 17 Mar 2002 09:50:46 +0000 (+0000) Subject: mark crossposted messages as read X-Git-Tag: rel_0_7_5~120 X-Git-Url: http://git.claws-mail.org/?p=claws.git;a=commitdiff_plain;h=1ac2ee669cccf991cf7f6362e3d83eb706b70df7 mark crossposted messages as read --- diff --git a/AUTHORS b/AUTHORS index 4e4e768f8..dd8786687 100644 --- a/AUTHORS +++ b/AUTHORS @@ -135,3 +135,4 @@ contributors (beside the above; based on Changelog) Colin Leroy Wilbert Berendsen Bob Woodside + Stefaan Eeckels diff --git a/ChangeLog.claws b/ChangeLog.claws index 5c046abd3..4f89511ed 100644 --- a/ChangeLog.claws +++ b/ChangeLog.claws @@ -1,3 +1,16 @@ +2002-03-17 [paul] 0.7.4claws19 + + * src/defs.h + src/folder.h + src/news.c + src/prefs_account.[ch] + src/procmsg.[ch] + src/summaryview.c + automatically mark cross-posted messages as read + and (optionally) give them a colour label + Patch submitted by Stefaan Eeckels + + 2002-03-17 [paul] 0.7.4claws18 * sync with sylpheed 0.7.4cvs5 diff --git a/configure.in b/configure.in index 53dd4a0cf..d431a7a6a 100644 --- a/configure.in +++ b/configure.in @@ -8,7 +8,7 @@ MINOR_VERSION=7 MICRO_VERSION=4 INTERFACE_AGE=0 BINARY_AGE=0 -EXTRA_VERSION=claws18 +EXTRA_VERSION=claws19 VERSION=$MAJOR_VERSION.$MINOR_VERSION.$MICRO_VERSION$EXTRA_VERSION dnl set $target diff --git a/src/defs.h b/src/defs.h index 3ce749601..573fa913a 100644 --- a/src/defs.h +++ b/src/defs.h @@ -65,7 +65,7 @@ #define FOLDER_LIST "folderlist.xml" #define CACHE_FILE ".sylpheed_cache" #define MARK_FILE ".sylpheed_mark" -#define CACHE_VERSION 19 +#define CACHE_VERSION 20 #define MARK_VERSION 2 #define DEFAULT_SIGNATURE ".signature" diff --git a/src/folder.h b/src/folder.h index 7f0adfd9d..649b10dde 100644 --- a/src/folder.h +++ b/src/folder.h @@ -100,6 +100,8 @@ struct _Folder gpointer data; + GHashTable *newsart; + /* virtual functions */ GSList * (*get_msg_list) (Folder *folder, FolderItem *item, diff --git a/src/news.c b/src/news.c index 4ee9cfb5a..ee794421e 100644 --- a/src/news.c +++ b/src/news.c @@ -774,7 +774,7 @@ static MsgInfo *news_parse_xover(const gchar *xover_str) { MsgInfo *msginfo; gchar buf[NNTPBUFSIZE]; - gchar *subject, *sender, *size, *line, *date, *msgid, *ref, *tmp; + gchar *subject, *sender, *size, *line, *date, *msgid, *ref, *tmp, *xref; gchar *p; gint num, size_int, line_int; gchar *xover_buf; @@ -788,8 +788,9 @@ static MsgInfo *news_parse_xover(const gchar *xover_str) PARSE_ONE_PARAM(ref, msgid); PARSE_ONE_PARAM(size, ref); PARSE_ONE_PARAM(line, size); + PARSE_ONE_PARAM(xref, line); - tmp = strchr(line, '\t'); + tmp = strchr(xref, '\t'); if (!tmp) tmp = strchr(line, '\r'); if (!tmp) tmp = strchr(line, '\n'); if (tmp) *tmp = '\0'; @@ -827,6 +828,13 @@ static MsgInfo *news_parse_xover(const gchar *xover_str) msginfo->inreplyto = g_strdup(p); } + msginfo->xref = g_strdup(xref); + p = msginfo->xref+strlen(msginfo->xref) - 1; + while (*p == '\r' || *p == '\n') { + *p = '\0'; + p--; + } + return msginfo; } diff --git a/src/prefs_account.c b/src/prefs_account.c index 91f0021fb..be9a41d2d 100644 --- a/src/prefs_account.c +++ b/src/prefs_account.c @@ -46,6 +46,7 @@ #include "gtkutils.h" #include "utils.h" #include "alertpanel.h" +#include "colorlabel.h" static gboolean cancelled; @@ -163,6 +164,9 @@ static struct Advanced { GtkWidget *domain_entry; GtkWidget *tunnelcmd_chkbtn; GtkWidget *tunnelcmd_entry; + GtkWidget *crosspost_chkbtn; + GtkWidget *crosspost_colormenu; + } advanced; static void prefs_account_fix_size (void); @@ -176,6 +180,8 @@ static void prefs_account_enum_set_radiobtn (PrefParam *pparam); static void prefs_account_ascii_armored_warning(GtkWidget* widget, gpointer unused); #endif /* USE_GPGME || USE_SSL */ +static void prefs_account_crosspost_set_data_from_colormenu(PrefParam *pparam); +static void prefs_account_crosspost_set_colormenu(PrefParam *pparam); static void prefs_account_nntpauth_toggled(GtkToggleButton *button, gpointer user_data); @@ -402,6 +408,16 @@ static PrefParam param[] = { &advanced.tunnelcmd_entry, prefs_set_data_from_entry, prefs_set_entry}, + {"mark_crosspost_read", "FALSE", &tmp_ac_prefs.mark_crosspost_read, P_BOOL, + &advanced.crosspost_chkbtn, + prefs_set_data_from_toggle, prefs_set_toggle}, + + {"crosspost_color", NULL, &tmp_ac_prefs.crosspost_col, P_ENUM, + &advanced.crosspost_colormenu, + prefs_account_crosspost_set_data_from_colormenu, + prefs_account_crosspost_set_colormenu}, + + {NULL, NULL, NULL, P_OTHER, NULL, NULL, NULL} }; @@ -1502,6 +1518,40 @@ static void prefs_account_ssl_create(void) } #endif /* USE_SSL */ +static void crosspost_color_toggled(void) +{ + gboolean is_active; + + is_active = gtk_toggle_button_get_active + (GTK_TOGGLE_BUTTON(advanced.crosspost_chkbtn)); + gtk_widget_set_sensitive(advanced.crosspost_colormenu, is_active); +} + +static void prefs_account_crosspost_set_data_from_colormenu(PrefParam *pparam) +{ + GtkWidget *menu; + GtkWidget *menuitem; + + menu = gtk_option_menu_get_menu(GTK_OPTION_MENU(advanced.crosspost_colormenu)); + menuitem = gtk_menu_get_active(GTK_MENU(menu)); + *((gint *)pparam->data) = GPOINTER_TO_INT + (gtk_object_get_data(GTK_OBJECT(menuitem), "color")); +} + +static void prefs_account_crosspost_set_colormenu(PrefParam *pparam) +{ + gint colorlabel = *((gint *)pparam->data); + GtkOptionMenu *colormenu = GTK_OPTION_MENU(*pparam->widget); + GtkWidget *menu; + GtkWidget *menuitem; + + gtk_option_menu_set_history(colormenu, colorlabel); + menu = gtk_option_menu_get_menu(colormenu); + menuitem = gtk_menu_get_active(GTK_MENU(menu)); + gtk_menu_item_activate(GTK_MENU_ITEM(menuitem)); +} + + static void prefs_account_advanced_create(void) { GtkWidget *vbox1; @@ -1522,6 +1572,12 @@ static void prefs_account_advanced_create(void) GtkWidget *entry_domain; GtkWidget *checkbtn_tunnelcmd; GtkWidget *entry_tunnelcmd; + GtkWidget *checkbtn_crosspost; + GtkWidget *colormenu_crosspost; + GtkWidget *menu; + GtkWidget *menuitem; + GtkWidget *item; + gint i; #define PACK_HBOX(hbox) \ { \ @@ -1587,6 +1643,21 @@ static void prefs_account_advanced_create(void) gtk_box_pack_start (GTK_BOX (hbox1), entry_tunnelcmd, TRUE, TRUE, 0); SET_TOGGLE_SENSITIVITY (checkbtn_tunnelcmd, entry_tunnelcmd); + PACK_HBOX (hbox1); + PACK_CHECK_BUTTON (hbox1, checkbtn_crosspost, + _("Mark crossposted messages as read and color:")); + gtk_signal_connect (GTK_OBJECT (checkbtn_crosspost), "toggled", + GTK_SIGNAL_FUNC (crosspost_color_toggled), + NULL); + + colormenu_crosspost = gtk_option_menu_new(); + gtk_widget_show (colormenu_crosspost); + gtk_box_pack_start (GTK_BOX (hbox1), colormenu_crosspost, FALSE, FALSE, 0); + + menu = colorlabel_create_color_menu(); + gtk_option_menu_set_menu (GTK_OPTION_MENU(colormenu_crosspost), menu); + SET_TOGGLE_SENSITIVITY(checkbtn_crosspost, colormenu_crosspost); + #undef PACK_HBOX #undef PACK_PORT_ENTRY @@ -1605,6 +1676,8 @@ static void prefs_account_advanced_create(void) advanced.domain_entry = entry_domain; advanced.tunnelcmd_chkbtn = checkbtn_tunnelcmd; advanced.tunnelcmd_entry = entry_tunnelcmd; + advanced.crosspost_chkbtn = checkbtn_crosspost; + advanced.crosspost_colormenu = colormenu_crosspost; } static gint prefs_account_deleted(GtkWidget *widget, GdkEventAny *event, @@ -1870,6 +1943,8 @@ static void prefs_account_protocol_activated(GtkMenuItem *menuitem) gtk_widget_hide(advanced.popport_hbox); gtk_widget_hide(advanced.imapport_hbox); gtk_widget_show(advanced.nntpport_hbox); + gtk_widget_show(advanced.crosspost_chkbtn); + gtk_widget_show(advanced.crosspost_colormenu); break; case A_LOCAL: gtk_widget_hide(basic.nntpserv_label); @@ -1925,6 +2000,8 @@ static void prefs_account_protocol_activated(GtkMenuItem *menuitem) gtk_widget_hide(advanced.popport_hbox); gtk_widget_hide(advanced.imapport_hbox); gtk_widget_hide(advanced.nntpport_hbox); + gtk_widget_hide(advanced.crosspost_chkbtn); + gtk_widget_hide(advanced.crosspost_colormenu); break; case A_IMAP4: gtk_widget_hide(basic.nntpserv_label); @@ -1982,6 +2059,8 @@ static void prefs_account_protocol_activated(GtkMenuItem *menuitem) gtk_widget_hide(advanced.popport_hbox); gtk_widget_show(advanced.imapport_hbox); gtk_widget_hide(advanced.nntpport_hbox); + gtk_widget_hide(advanced.crosspost_chkbtn); + gtk_widget_hide(advanced.crosspost_colormenu); break; case A_POP3: default: @@ -2040,6 +2119,8 @@ static void prefs_account_protocol_activated(GtkMenuItem *menuitem) gtk_widget_show(advanced.popport_hbox); gtk_widget_hide(advanced.imapport_hbox); gtk_widget_hide(advanced.nntpport_hbox); + gtk_widget_hide(advanced.crosspost_chkbtn); + gtk_widget_hide(advanced.crosspost_colormenu); break; } diff --git a/src/prefs_account.h b/src/prefs_account.h index 35e8357d5..139f9bb80 100644 --- a/src/prefs_account.h +++ b/src/prefs_account.h @@ -159,6 +159,8 @@ struct _PrefsAccount gushort nntpport; gboolean set_domain; gchar *domain; + gboolean mark_crosspost_read; + gint crosspost_col; /* Use this command to open a socket, rather than doing so * directly. Good if you want to perhaps use a special socks diff --git a/src/procmsg.c b/src/procmsg.c index 138077ed5..72549223d 100644 --- a/src/procmsg.c +++ b/src/procmsg.c @@ -241,6 +241,8 @@ GSList *procmsg_read_cache(FolderItem *item, gboolean scan_file) READ_CACHE_DATA(msginfo->msgid, fp); READ_CACHE_DATA(msginfo->inreplyto, fp); READ_CACHE_DATA(msginfo->references, fp); + READ_CACHE_DATA(msginfo->xref, fp); + MSG_SET_PERM_FLAGS(msginfo->flags, default_flags.perm_flags); MSG_SET_TMP_FLAGS(msginfo->flags, default_flags.tmp_flags); @@ -385,6 +387,8 @@ void procmsg_write_cache(MsgInfo *msginfo, FILE *fp) WRITE_CACHE_DATA(msginfo->msgid, fp); WRITE_CACHE_DATA(msginfo->inreplyto, fp); WRITE_CACHE_DATA(msginfo->references, fp); + WRITE_CACHE_DATA(msginfo->xref, fp); + } void procmsg_write_flags(MsgInfo *msginfo, FILE *fp) @@ -942,6 +946,7 @@ MsgInfo *procmsg_msginfo_copy(MsgInfo *msginfo) MEMBDUP(subject); MEMBDUP(msgid); MEMBDUP(inreplyto); + MEMBDUP(xref); MEMBCOPY(folder); MEMBCOPY(to_folder); @@ -977,6 +982,7 @@ void procmsg_msginfo_free(MsgInfo *msginfo) g_free(msginfo->subject); g_free(msginfo->msgid); g_free(msginfo->inreplyto); + g_free(msginfo->xref); g_free(msginfo); } diff --git a/src/procmsg.h b/src/procmsg.h index eddd6a203..f2043a1fa 100644 --- a/src/procmsg.h +++ b/src/procmsg.h @@ -184,6 +184,7 @@ struct _MsgInfo gchar *subject; gchar *msgid; gchar *inreplyto; + gchar *xref; FolderItem *folder; FolderItem *to_folder; diff --git a/src/summaryview.c b/src/summaryview.c index 67e0b3ad5..b355a6832 100644 --- a/src/summaryview.c +++ b/src/summaryview.c @@ -380,6 +380,9 @@ static gint summary_cmp_by_label (GtkCList *clist, gconstpointer ptr1, gconstpointer ptr2); +static void news_process_crossposted (MsgInfo *msginfo); +static void news_flag_crosspost (MsgInfo *msginfo); + GtkTargetEntry summary_drag_types[1] = { {"text/plain", GTK_TARGET_SAME_APP, TARGET_DUMMY} @@ -1607,6 +1610,9 @@ static void summary_set_marks_func(GtkCTree *ctree, GtkCTreeNode *node, msginfo = gtk_ctree_node_get_row_data(ctree, node); + if (MSG_IS_NEWS(msginfo->flags)) + news_flag_crosspost(msginfo); + if (MSG_IS_NEW(msginfo->flags) && !MSG_IS_IGNORE_THREAD(msginfo->flags)) summaryview->newmsgs++; if (MSG_IS_UNREAD(msginfo->flags) && !MSG_IS_IGNORE_THREAD(msginfo->flags)) @@ -4833,6 +4839,69 @@ static gint summary_cmp_by_label(GtkCList *clist, return MSG_GET_COLORLABEL(msginfo1->flags) - MSG_GET_COLORLABEL(msginfo2->flags); } + +static void news_flag_crosspost(MsgInfo *msginfo) +{ + GString *line; + gpointer key; + gpointer value; + MsgPermFlags flags; + Folder *mff = msginfo->folder->folder; + + if (mff->account->mark_crosspost_read && MSG_IS_NEWS(msginfo->flags)) { + line = g_string_sized_new(128); + g_string_sprintf(line, "%s:%d", msginfo->folder->path, msginfo->msgnum); + debug_print(_("nfcp: checking <%s>"), line->str); + if (mff->newsart && + g_hash_table_lookup_extended(mff->newsart, line->str, &key, &value)) { + debug_print(_(" <%s>"), value); + if (MSG_IS_NEW(msginfo->flags) || MSG_IS_UNREAD(msginfo->flags)) { + MSG_UNSET_PERM_FLAGS(msginfo->flags, MSG_NEW | MSG_UNREAD); + MSG_SET_COLORLABEL_VALUE(msginfo->flags, mff->account->crosspost_col); + } + g_hash_table_remove(mff->newsart, key); + g_free(key); + } + g_string_free(line, TRUE); + debug_print(_("\n")); + } +} + +static void news_process_crossposted(MsgInfo *msginfo) +{ + gchar **crossref; + gchar **crp; + gchar *cp; + gint cnt; + static char *read = "read"; + Folder *mff = msginfo->folder->folder; + + /* Get the Xref: line */ + if (msginfo->xref) { + /* Retrieve the cross-posted groups and message ids */ + /* Format of Xref is Xref: server message:id message:id ... */ + crossref = g_strsplit(msginfo->xref, " ", 1024); + for (crp = crossref+2, cnt = 0; *crp; crp++, cnt++) { + if ((cp = strchr(*crp, ':'))) { + *cp = '\0'; + if (!strcmp(*crp, msginfo->folder->path)) continue; + *cp = ':'; + + /* On first pass, create a GHashTable to hold the list of + * article numbers per newsgroup that have been read. */ + if (!mff->newsart) { + mff->newsart = g_hash_table_new(g_str_hash, g_str_equal); + } + /* When a summary is selected, the articles for that + * newsgroup are marked based on this entry */ + g_hash_table_insert(mff->newsart, g_strdup(*crp), read); + debug_print(_("Cross-reference %d: Hash <%s>\n"), cnt, *crp); + } + } + g_strfreev(crossref); + } +} + static gint summary_cmp_by_score(GtkCList *clist, gconstpointer ptr1, gconstpointer ptr2) {