[prev in list] [next in list] [prev in thread] [next in thread] 

List:       sylpheed
Subject:    [sylpheed:24959] Patch to mark crossposted articles read
From:       Stefaan A Eeckels <Stefaan.Eeckels () ecc ! lu>
Date:       2005-05-22 21:47:18
Message-ID: 20050522234718.659aef56.Stefaan.Eeckels () ecc ! lu
[Download RAW message or body]

Hi list,

I've adapted my crosspost patch for the current svn revision
(274). It's not too big so I take the liberty to attach it
here.

What it does is to mark read (and color) crossposted messages
that have been read in another newsgroup. It checks crosspost
upon entering a group, not when the crossposted message is
read, and it doesn't save the list of read messages across 
program restarts (something I don't need much as I hardly ever
restart either sylpheed or my workstation), but I could add
that if there's interest.

Take care,

-- 
Stefaan
-- 
As complexity rises, precise statements lose meaning,
and meaningful statements lose precision. -- Lotfi Zadeh 

["read_crossposted.diff" (application/octet-stream)]

diff -u src/defs.h src.sae/defs.h
--- src/defs.h	Fri May 13 14:43:10 2005
+++ src.sae/defs.h	Sat May 21 16:10:51 2005
@@ -63,7 +63,8 @@
 #define FOLDER_LIST		"folderlist.xml"
 #define CACHE_FILE		".sylpheed_cache"
 #define MARK_FILE		".sylpheed_mark"
-#define CACHE_VERSION		0x21
+/* #define CACHE_VERSION		0x21 */
+#define CACHE_VERSION		0x22
 #define MARK_VERSION		2
 
 #define DEFAULT_SIGNATURE	".signature"
diff -u src/folder.h src.sae/folder.h
--- src/folder.h	Fri Apr  8 18:17:00 2005
+++ src.sae/folder.h	Sat May 21 16:04:50 2005
@@ -132,6 +132,8 @@
 	GNode *node;
 
 	gpointer data;
+
+	GHashTable *newsart;	/*sae*/
 };
 
 struct _FolderClass
diff -u src/news.c src.sae/news.c
--- src/news.c	Fri Mar  4 11:02:26 2005
+++ src.sae/news.c	Sat May 21 16:17:09 2005
@@ -911,7 +911,7 @@
 static MsgInfo *news_parse_xover(const gchar *xover_str)
 {
 	MsgInfo *msginfo;
-	gchar *subject, *sender, *size, *line, *date, *msgid, *ref, *tmp;
+	gchar *subject, *sender, *size, *line, *date, *msgid, *ref, *tmp, *xref; /*sae*/
 	gchar *p;
 	gint num, size_int, line_int;
 	gchar *xover_buf;
@@ -925,8 +925,10 @@
 	PARSE_ONE_PARAM(ref, msgid);
 	PARSE_ONE_PARAM(size, ref);
 	PARSE_ONE_PARAM(line, size);
+	PARSE_ONE_PARAM(xref, line);	/*sae*/
 
-	tmp = strchr(line, '\t');
+	tmp = strchr(xref, '\t');
+	if (!tmp) tmp = strchr(line, '\t');
 	if (!tmp) tmp = strchr(line, '\r');
 	if (!tmp) tmp = strchr(line, '\n');
 	if (tmp) *tmp = '\0';
@@ -961,6 +963,13 @@
 			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 -u src/prefs_account.c src.sae/prefs_account.c
--- src/prefs_account.c	Tue Mar 15 09:34:20 2005
+++ src.sae/prefs_account.c	Sun May 22 02:19:16 2005
@@ -47,6 +47,7 @@
 #include "gtkutils.h"
 #include "utils.h"
 #include "alertpanel.h"
+#include "colorlabel.h"
 #include "smtp.h"
 #include "imap.h"
 
@@ -176,6 +177,8 @@
 	GtkWidget *nntpport_entry;
 	GtkWidget *domain_chkbtn;
 	GtkWidget *domain_entry;
+	GtkWidget *crosspost_chkbtn;
+	GtkWidget *crosspost_colormenu;
 
 	GtkWidget *imap_frame;
 	GtkWidget *imapdir_entry;
@@ -188,6 +191,8 @@
 	GtkWidget *trash_folder_entry;
 } advanced;
 
+static GtkWidget *color_dialog;
+
 static void prefs_account_protocol_set_data_from_optmenu(PrefParam *pparam);
 static void prefs_account_protocol_set_optmenu		(PrefParam *pparam);
 static void prefs_account_protocol_activated		(GtkMenuItem *menuitem);
@@ -205,6 +210,8 @@
 #if USE_GPGME
 static void prefs_account_ascii_armored_warning		(GtkWidget *widget);
 #endif /* USE_GPGME */
+static void prefs_account_crosspost_set_data_from_colormenu(PrefParam *pparam);
+static void prefs_account_crosspost_set_colormenu(PrefParam *pparam);
 
 static PrefParam param[] = {
 	/* Basic */
@@ -443,6 +450,15 @@
 	 &advanced.domain_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},
+
 	{"imap_directory", NULL, &tmp_ac_prefs.imap_dir, P_STRING,
 	 &advanced.imapdir_entry, prefs_set_data_from_entry, prefs_set_entry},
 
@@ -1710,11 +1726,45 @@
 
 #endif /* USE_SSL */
 
+/* Added by sae 2005-05-22 */
+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));
+	*((gint *)pparam->data) = colorlabel_get_color_menu_active_item(menu);
+}
+
+static void prefs_account_crosspost_set_colormenu(PrefParam *pparam)
+{
+	gint colorlabel = *((gint *)pparam->data) - 1;
+	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;
 	GtkWidget *vbox2;
 	GtkWidget *hbox1;
+	GtkWidget *hbox_cp;
 	GtkWidget *checkbtn_smtpport;
 	GtkWidget *entry_smtpport;
 	GtkWidget *hbox_popport;
@@ -1740,6 +1790,13 @@
 	GtkWidget *draft_folder_entry;
 	GtkWidget *trash_folder_chkbtn;
 	GtkWidget *trash_folder_entry;
+	GtkWidget *checkbtn_crosspost;
+	GtkWidget *colormenu_crosspost;
+	GtkWidget *menu;
+	GtkWidget *menu_cp;
+	GtkWidget *menuitem;
+	GtkWidget *item;
+	gint i;
 
 #define PACK_HBOX(hbox) \
 { \
@@ -1797,6 +1854,21 @@
 	gtk_box_pack_start (GTK_BOX (hbox1), entry_domain, TRUE, TRUE, 0);
 	SET_TOGGLE_SENSITIVITY (checkbtn_domain, entry_domain);
 
+	/* sae 2005-05-22 */
+	PACK_HBOX (hbox_cp);
+	PACK_CHECK_BUTTON (hbox_cp, checkbtn_crosspost, _("Color crossposted read messages:"));
+	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 (hbox_cp), colormenu_crosspost, FALSE, FALSE, 0);
+
+	menu_cp = colorlabel_create_color_menu();
+	gtk_option_menu_set_menu (GTK_OPTION_MENU(colormenu_crosspost), menu_cp);
+	SET_TOGGLE_SENSITIVITY(checkbtn_crosspost, colormenu_crosspost);
+	/* end sae */
+
 	PACK_FRAME (vbox1, imap_frame, _("IMAP4"));
 
 	vbox3 = gtk_vbox_new (FALSE, VSPACING_NARROW);
@@ -1882,6 +1954,8 @@
 	advanced.nntpport_entry		= entry_nntpport;
 	advanced.domain_chkbtn		= checkbtn_domain;
 	advanced.domain_entry		= entry_domain;
+	advanced.crosspost_chkbtn	= checkbtn_crosspost;
+	advanced.crosspost_colormenu	= colormenu_crosspost;
 
 	advanced.imap_frame             = imap_frame;
 	advanced.imapdir_entry          = imapdir_entry;
@@ -2196,6 +2270,8 @@
 		gtk_widget_hide(advanced.imapport_hbox);
 		gtk_widget_show(advanced.nntpport_hbox);
 		gtk_widget_hide(advanced.imap_frame);
+		gtk_widget_show(advanced.crosspost_chkbtn);
+		gtk_widget_show(advanced.crosspost_colormenu);
 		break;
 	case A_LOCAL:
 		gtk_widget_hide(basic.nntpserv_label);
@@ -2231,6 +2307,8 @@
 		gtk_widget_hide(advanced.imapport_hbox);
 		gtk_widget_hide(advanced.nntpport_hbox);
 		gtk_widget_hide(advanced.imap_frame);
+		gtk_widget_hide(advanced.crosspost_chkbtn);
+		gtk_widget_hide(advanced.crosspost_colormenu);
 		break;
 	case A_IMAP4:
 		gtk_widget_hide(basic.nntpserv_label);
@@ -2266,6 +2344,8 @@
 		gtk_widget_show(advanced.imapport_hbox);
 		gtk_widget_hide(advanced.nntpport_hbox);
 		gtk_widget_show(advanced.imap_frame);
+		gtk_widget_hide(advanced.crosspost_chkbtn);
+		gtk_widget_hide(advanced.crosspost_colormenu);
 		break;
 	case A_POP3:
 	default:
@@ -2302,6 +2382,8 @@
 		gtk_widget_hide(advanced.imapport_hbox);
 		gtk_widget_hide(advanced.nntpport_hbox);
 		gtk_widget_hide(advanced.imap_frame);
+		gtk_widget_hide(advanced.crosspost_chkbtn);
+		gtk_widget_hide(advanced.crosspost_colormenu);
 		break;
 	}
 
diff -u src/prefs_account.h src.sae/prefs_account.h
--- src/prefs_account.h	Wed Jan 19 20:50:51 2005
+++ src.sae/prefs_account.h	Sat May 21 16:18:30 2005
@@ -144,6 +144,9 @@
 	gushort   nntpport;
 	gboolean  set_domain;
 	gchar    *domain;
+	/* (sae) Crosspost handling */
+	gboolean   mark_crosspost_read;
+	gint	   crosspost_col;
 
 	gchar *imap_dir;
 
diff -u src/procmsg.c src.sae/procmsg.c
--- src/procmsg.c	Tue Mar 29 10:39:04 2005
+++ src.sae/procmsg.c	Sun May 22 15:15:48 2005
@@ -41,6 +41,9 @@
 #  include "rfc2015.h"
 #endif
 
+int news_flag_crosspost(MsgInfo *msginfo);		/*sae */
+
+
 static void mark_sum_func			(gpointer	 key,
 						 gpointer	 value,
 						 gpointer	 data);
@@ -258,6 +261,7 @@
 		READ_CACHE_DATA(msginfo->subject, fp);
 		READ_CACHE_DATA(msginfo->msgid, fp);
 		READ_CACHE_DATA(msginfo->inreplyto, fp);
+		READ_CACHE_DATA(msginfo->xref, fp);		/* sae */
 
 		READ_CACHE_DATA_INT(refnum, fp);
 		for (; refnum != 0; refnum--) {
@@ -371,6 +375,15 @@
 			++unread;
 		}
 
+		/* sae 2005-05-21 */
+		if (MSG_IS_NEWS(msginfo->flags) &&
+		    (MSG_IS_NEW(msginfo->flags) || MSG_IS_UNREAD(msginfo->flags))) {
+			if (news_flag_crosspost(msginfo)) {
+				if (--new < 0) new = 0;
+				if (--unread < 0) unread = 0;
+			}
+		}
+
 		++total;
 	}
 
@@ -474,6 +487,7 @@
 	WRITE_CACHE_DATA(msginfo->subject, fp);
 	WRITE_CACHE_DATA(msginfo->msgid, fp);
 	WRITE_CACHE_DATA(msginfo->inreplyto, fp);
+	WRITE_CACHE_DATA(msginfo->xref, fp);	/* sae */
 
 	WRITE_CACHE_DATA_INT(g_slist_length(msginfo->references), fp);
 	for (cur = msginfo->references; cur != NULL; cur = cur->next) {
@@ -1417,6 +1431,7 @@
 	MEMBDUP(subject);
 	MEMBDUP(msgid);
 	MEMBDUP(inreplyto);
+	MEMBDUP(xref);		/*sae*/
 
 	MEMBCOPY(folder);
 	MEMBCOPY(to_folder);
@@ -1480,6 +1495,7 @@
 	g_free(msginfo->subject);
 	g_free(msginfo->msgid);
 	g_free(msginfo->inreplyto);
+	g_free(msginfo->xref);		/*sae*/
 
 	slist_free_strings(msginfo->references);
 	g_slist_free(msginfo->references);
diff -u src/procmsg.h src.sae/procmsg.h
--- src/procmsg.h	Tue Mar 29 10:39:04 2005
+++ src.sae/procmsg.h	Sat May 21 16:05:25 2005
@@ -180,6 +180,7 @@
 	gchar *subject;
 	gchar *msgid;
 	gchar *inreplyto;
+	gchar *xref;		/*sae*/
 
 	GSList *references;
 
diff -u src/summaryview.c src.sae/summaryview.c
--- src/summaryview.c	Fri May 20 10:22:23 2005
+++ src.sae/summaryview.c	Sun May 22 22:47:15 2005
@@ -48,6 +48,7 @@
 #include <string.h>
 #include <ctype.h>
 #include <unistd.h>
+#include <errno.h>
 
 #include "main.h"
 #include "menu.h"
@@ -309,7 +310,11 @@
 					 GtkTreeIter		*b,
 					 gpointer		 data);
 
+/* Cross-posted messages elimination support */
+static void news_process_crossposted(MsgInfo *msginfo);	/*sae */
+int news_flag_crosspost(MsgInfo *msginfo);		/*sae */
 
+
 /* must be synched with FolderSortKey */
 static SummaryColumnType sort_key_to_col[] = {
 	-1,
@@ -1373,7 +1378,7 @@
 
 	for (; valid == TRUE; valid = gtkut_tree_model_next(model, &iter_)) {
 		GET_MSG_INFO(msginfo, &iter_);
-		if (msginfo && (msginfo->flags.perm_flags & flags) != 0) {
+		if (msginfo && ((msginfo->flags.perm_flags & flags) != 0)) {
 			*next = iter_;
 			return TRUE;
 		}
@@ -2101,6 +2106,9 @@
 			if (MSG_IS_IMAP(msginfo->flags))
 				imap_msg_unset_perm_flags
 					(msginfo, MSG_NEW | MSG_UNREAD);
+			/* Enter crossposted messages in hash (sae 2005-05-22) */
+			if (MSG_IS_NEWS(msginfo->flags))
+				news_process_crossposted(msginfo);
 			summary_set_row(summaryview, iter, msginfo);
 			summary_status_show(summaryview);
 		}
@@ -2323,6 +2331,9 @@
 		summaryview->folder_item->unread--;
 	if (MSG_IS_NEW(msginfo->flags) || MSG_IS_UNREAD(msginfo->flags)) {
 		MSG_UNSET_PERM_FLAGS(msginfo->flags, MSG_NEW | MSG_UNREAD);
+		/* Enter crossposted messages in hash (sae 2005-05-22) */
+		if (MSG_IS_NEWS(msginfo->flags))
+			news_process_crossposted(msginfo);
 		summary_set_row(summaryview, iter, msginfo);
 		debug_print(_("Message %d is marked as being read\n"),
 			    msginfo->msgnum);
@@ -4472,6 +4483,78 @@
 					       "Dummy", 6);
 	}
 }
+
+/* Stuff below added by sae 2005-05-22 */
+
+/* Check a message against the messages in the "newsart" hash.
+ * If it's found, the message has been read somewhere else and
+ * can be marked read in this newsgroup. If a color has been
+ * chosen in the Advanced options, apply it to the message */
+int news_flag_crosspost(MsgInfo *msginfo)
+{
+	GString *line;
+	gpointer key;
+	gpointer value;
+	MsgPermFlags flags;
+	Folder *mff = msginfo->folder->folder;
+	int rv = 0;
+
+	if (mff->account->mark_crosspost_read) {
+		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);
+			MSG_UNSET_PERM_FLAGS(msginfo->flags, MSG_NEW | MSG_UNREAD);
+			MSG_SET_COLORLABEL_VALUE(msginfo->flags, mff->account->crosspost_col);
+			rv = 1;
+			g_hash_table_remove(mff->newsart, key);
+			g_free(key);	/* must free */
+		}
+		g_string_free(line, TRUE);
+		debug_print(_("\n"));
+	}
+	return rv;
+}
+
+/* Determine the cross-posted messages and make an entry in the
+ * "newsart" hash so that upon entry of another summary we can
+ * mark the messages in that group read */
+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);
+	}
+}
 
 
 /* custom compare functions for sorting */


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic