[sylpheed-jp:10638] 新しいfeatureのパッチ:受け た日付で整えり

Phil Vandry <[email protected]>
Newsgroups gmane.mail.sylpheed.general.japanese
Message-ID <[email protected]>
こんいちは、

メールの受けた日付の順番に整える時もあるけど Sylpheed はそれが出来ない。
受けた日付はメッセージに入れた日付と違います。

このパッチはその能力をたす。新しい「受日付」という円柱を作りました。

IMAP を使う時、受けた日付の事項のダウンロードされていないから、その能力も
含めました。

このパッチは Sylpheed に受け取られると頼みます。

-Phil

_______________________________________________
Sylpheed-jp mailing list
[email protected]
http://www.sraoss.jp/mailman/listinfo/sylpheed-jp
sylpheed.received_date.patch (text/x-diff, 13.3 KB)
Index: libsylph/enums.h
===================================================================
--- libsylph/enums.h	(revision 2029)
+++ libsylph/enums.h	(working copy)
@@ -49,6 +49,7 @@
 	S_COL_SIZE,
 	S_COL_NUMBER,
 	S_COL_TO,
+	S_COL_RECVDATE,
 
 	S_COL_MSG_INFO,
 
Index: libsylph/folder.h
===================================================================
--- libsylph/folder.h	(revision 2029)
+++ libsylph/folder.h	(working copy)
@@ -103,7 +103,8 @@
 	SORT_BY_MARK,
 	SORT_BY_UNREAD,
 	SORT_BY_MIME,
-	SORT_BY_TO
+	SORT_BY_TO,
+	SORT_BY_RECVDATE
 } FolderSortKey;
 
 typedef enum
Index: libsylph/prefs_common.c
===================================================================
--- libsylph/prefs_common.c	(revision 2029)
+++ libsylph/prefs_common.c	(working copy)
@@ -163,6 +163,8 @@
 	 &prefs_common.summary_col_visible[S_COL_NUMBER], P_BOOL},
 	{"summary_col_show_to", "FALSE",
 	 &prefs_common.summary_col_visible[S_COL_TO], P_BOOL},
+	{"summary_col_show_recvdate", "FALSE",
+	 &prefs_common.summary_col_visible[S_COL_RECVDATE], P_BOOL},
 
 	{"summary_col_pos_mark", "0",
 	  &prefs_common.summary_col_pos[S_COL_MARK], P_INT},
@@ -182,6 +184,8 @@
 	  &prefs_common.summary_col_pos[S_COL_NUMBER], P_INT},
 	{"summary_col_pos_to", "8",
 	  &prefs_common.summary_col_pos[S_COL_TO], P_INT},
+	{"summary_col_pos_recvdate", "9",
+	  &prefs_common.summary_col_pos[S_COL_RECVDATE], P_INT},
 
 	{"summary_sent_col_show_mark", "TRUE",
 	 &prefs_common.summary_sent_col_visible[S_COL_MARK], P_BOOL},
@@ -201,6 +205,8 @@
 	 &prefs_common.summary_sent_col_visible[S_COL_NUMBER], P_BOOL},
 	{"summary_sent_col_show_to", "TRUE",
 	 &prefs_common.summary_sent_col_visible[S_COL_TO], P_BOOL},
+	{"summary_sent_col_show_recvdate", "FALSE",
+	 &prefs_common.summary_sent_col_visible[S_COL_RECVDATE], P_BOOL},
 
 	{"summary_sent_col_pos_mark", "0",
 	  &prefs_common.summary_sent_col_pos[S_COL_MARK], P_INT},
@@ -220,6 +226,8 @@
 	  &prefs_common.summary_sent_col_pos[S_COL_NUMBER], P_INT},
 	{"summary_sent_col_pos_to", "4",
 	  &prefs_common.summary_sent_col_pos[S_COL_TO], P_INT},
+	{"summary_send_col_pos_recvdate", "9",
+	  &prefs_common.summary_sent_col_pos[S_COL_RECVDATE], P_INT},
 
 	{"summary_col_size_mark", "10",
 	 &prefs_common.summary_col_size[S_COL_MARK], P_INT},
@@ -239,6 +247,8 @@
 	 &prefs_common.summary_col_size[S_COL_NUMBER], P_INT},
 	{"summary_col_size_to", "120",
 	 &prefs_common.summary_col_size[S_COL_TO], P_INT},
+	{"summary_col_size_recvdate", "118",
+	 &prefs_common.summary_col_size[S_COL_RECVDATE], P_INT},
 
 	/* Widget size */
 	{"folderwin_x", "16", &prefs_common.folderwin_x, P_INT},
Index: libsylph/imap.c
===================================================================
--- libsylph/imap.c	(revision 2029)
+++ libsylph/imap.c	(working copy)
@@ -3069,6 +3069,126 @@
 	return flags;
 }
 
+static gchar *imap_get_date(gchar *cur_pos, time_t *resultp)
+{
+	gchar *end_pos, *p;
+	static const gchar monthstr[] = "JanFebMarAprMayJunJulAugSepOctNovDec";
+	gchar buf[32]; /* dd-mmm-yyyy hh:mm:ss -zzzz = 26 */
+	gchar smallbuf[4];
+	guint32 mday, mon, year, hour, minute, second, zone_h, zone_m;
+	int zonesign;
+#if GLIB_CHECK_VERSION(2,12,0)
+#define HAVE_GTIMEVAL_CONVERSIONS
+	GTimeVal tv;
+#else
+	struct tm tms;
+#endif
+
+	if (resultp) *resultp = 0;
+
+	if (((*cur_pos) != '"') || (!(end_pos = strchr(cur_pos+1, '"')))) {
+		g_warning("invalid IMAP date: %s\n", cur_pos);
+		return cur_pos;
+	}
+	if ((end_pos - cur_pos) > 31) {
+		/* The format is very rigid as defined in the RFC. We need
+		   not tolerate things like extra space characters */
+		g_warning("invalid IMAP date (too long): %s\n", cur_pos);
+		return end_pos + 1;
+	}
+	memcpy(buf, cur_pos+1, end_pos-cur_pos-1);
+	buf[end_pos-cur_pos-1] = 0;
+	end_pos++; /* skip final quote */
+
+	cur_pos = buf;
+
+	if ((*cur_pos) == ' ') cur_pos++;
+	mday = strtoul(cur_pos, &p, 10);
+	if ((p == cur_pos) || (mday < 1) || (mday > 31) || ((*p) != '-')) goto baddate;
+	cur_pos = p+1;
+
+	if ((cur_pos[0] == 0) || (cur_pos[1] == 0) || (cur_pos[2] == 0) || (cur_pos[3] != '-'))
+		goto baddate;
+	smallbuf[0] = cur_pos[0];
+	smallbuf[1] = cur_pos[1];
+	smallbuf[2] = cur_pos[2];
+	smallbuf[3] = 0;
+	cur_pos += 4;
+	if (!(p = strstr(monthstr, smallbuf))) goto baddate;
+	if (((p - monthstr) % 3) > 0) goto baddate;
+	mon = (p-monthstr)/3 + 1;
+
+	year = strtoul(cur_pos, &p, 10);
+	if ((p == cur_pos) || ((*p) != ' ')) goto baddate;
+	cur_pos = p+1;
+
+	hour = strtoul(cur_pos, &p, 10);
+	if ((p == cur_pos) || (hour > 23) || ((*p) != ':')) goto baddate;
+	cur_pos = p+1;
+
+	minute = strtoul(cur_pos, &p, 10);
+	if ((p == cur_pos) || (minute > 59) || ((*p) != ':')) goto baddate;
+	cur_pos = p+1;
+
+	second = strtoul(cur_pos, &p, 10);
+	if ((p == cur_pos) || (second > 59) || ((*p) != ' ')) goto baddate;
+	cur_pos = p+1;
+
+	if ((*cur_pos) == '+') {
+		zonesign = 1;
+	} else if ((*cur_pos) == '-') {
+		zonesign = -1;
+	} else {
+		goto baddate;
+	}
+
+	if (strlen(++cur_pos) != 4) goto baddate;
+	smallbuf[0] = *(cur_pos++);
+	smallbuf[1] = *(cur_pos++);
+	smallbuf[2] = 0;
+	zone_h = strtoul(smallbuf, &p, 10);
+	if (*p) goto baddate;
+
+	smallbuf[0] = *(cur_pos++);
+	smallbuf[1] = *(cur_pos++);
+	zone_m = strtoul(smallbuf, &p, 10);
+	if (*p) goto baddate;
+
+#ifdef HAVE_GTIMEVAL_CONVERSIONS
+	sprintf(buf, "%u-%02u-%02uT%02u:%02u:%02uZ", year, mon, mday, hour, minute, second);
+	g_time_val_from_iso8601(buf, &tv); /* should always work */
+	tv.tv_sec -= zonesign * (zone_h * 3600 + zone_m * 60);
+
+	if (resultp) *resultp = tv.tv_sec;
+#else
+	tms.tm_year = year-1900;
+	tms.tm_mon = mon-1;
+	tms.tm_mday = mday;
+	tms.tm_hour = hour - zonesign * zone_h;
+	tms.tm_min = minute - zonesign * zone_m;
+	tms.tm_sec = second;
+	tms.tm_isdst = 0;
+
+#ifdef __GLIBC__
+	/* timegm is a GNU extension */
+	if (resultp) *resultp = timegm(&tms);
+#else
+	/* There is no way to convert a UTC time to a time_t.
+	   This is an unsupported configuration. However, we will use
+	   mktime anyway. All times obtained this way will be wrong
+	   by some offset. At least the results are still usable for
+	   sorting, since the ordering of times will not be affected */
+	if (resultp) *resultp = mktime(&tms);
+#endif
+#endif
+
+	return end_pos;
+
+baddate:
+	g_warning("invalid IMAP date: %s\n", buf);
+	return end_pos;
+}
+
 static MsgInfo *imap_parse_envelope(IMAPSession *session, FolderItem *item,
 				    GString *line_str)
 {
@@ -3078,6 +3198,7 @@
 	gint msgnum;
 	guint32 uid = 0;
 	size_t size = 0;
+	time_t internaldate;
 	MsgFlags flags = {0, 0}, imap_flags = {0, 0};
 
 	g_return_val_if_fail(line_str != NULL, NULL);
@@ -3139,6 +3260,9 @@
 						  line_str);
 			msginfo = procheader_parse_str(headers, flags, FALSE);
 			g_free(headers);
+		} else if (!strncmp(cur_pos, "INTERNALDATE ", 13)) {
+			cur_pos += 13;
+			cur_pos = imap_get_date(cur_pos, &internaldate);
 		} else {
 			g_warning("invalid FETCH response: %s\n", cur_pos);
 			break;
@@ -3152,6 +3276,7 @@
 		msginfo->size = size;
 		msginfo->flags.tmp_flags |= imap_flags.tmp_flags;
 		msginfo->flags.perm_flags = imap_flags.perm_flags;
+		msginfo->mtime = internaldate;
 	}
 
 	return msginfo;
@@ -3968,7 +4093,7 @@
 gint imap_cmd_envelope(IMAPSession *session, const gchar *seq_set)
 {
 	imap_cmd_gen_send
-		(session, "UID FETCH %s (UID FLAGS RFC822.SIZE RFC822.HEADER)",
+		(session, "UID FETCH %s (UID FLAGS RFC822.SIZE RFC822.HEADER INTERNALDATE)",
 		 seq_set);
 
 	return IMAP_SUCCESS;
Index: src/summaryview.c
===================================================================
--- src/summaryview.c	(revision 2029)
+++ src/summaryview.c	(working copy)
@@ -342,6 +342,10 @@
 					 GtkTreeIter		*a,
 					 GtkTreeIter		*b,
 					 gpointer		 data);
+static gint summary_cmp_by_recvdate	(GtkTreeModel		*model,
+					 GtkTreeIter		*a,
+					 GtkTreeIter		*b,
+					 gpointer		 data);
 static gint summary_cmp_by_thread_date	(GtkTreeModel		*model,
 					 GtkTreeIter		*a,
 					 GtkTreeIter		*b,
@@ -378,7 +382,8 @@
 	S_COL_MARK,
 	S_COL_UNREAD,
 	S_COL_MIME,
-	S_COL_TO
+	S_COL_TO,
+	S_COL_RECVDATE
 };
 
 /* must be synched with SummaryColumnType */
@@ -391,7 +396,8 @@
 	SORT_BY_DATE,
 	SORT_BY_SIZE,
 	SORT_BY_NUMBER,
-	SORT_BY_TO
+	SORT_BY_TO,
+	SORT_BY_RECVDATE
 };
 
 enum
@@ -2080,7 +2086,7 @@
 	SummaryColumnType col_type, prev_col_type;
 	GtkTreeViewColumn *column;
 
-	g_return_if_fail(sort_key >= SORT_BY_NONE && sort_key <= SORT_BY_TO);
+	g_return_if_fail(sort_key >= SORT_BY_NONE && sort_key <= SORT_BY_RECVDATE);
 
 	if (!item || !item->path || !item->parent || item->no_select) return;
 
@@ -2167,7 +2173,9 @@
 {
 	GtkTreeStore *store = GTK_TREE_STORE(summaryview->store);
 	gchar date_modified[80];
+	gchar recvdate_buf[80];
 	const gchar *date_s;
+	const gchar *recvdate_s;
 	gchar *sw_from_s = NULL;
 	gchar *subject_s = NULL;
 	gchar *to_s = NULL;
@@ -2193,6 +2201,13 @@
 		date_s = msginfo->date;
 	else
 		date_s = _("(No Date)");
+	if (msginfo->mtime) {
+		procheader_date_get_localtime(recvdate_buf,
+					      sizeof(recvdate_buf),
+					      msginfo->mtime);
+		recvdate_s = recvdate_buf;
+	} else
+		recvdate_s = _("(No Date)");
 	if (prefs_common.swap_from && msginfo->from && msginfo->to) {
 		gchar *from;
 
@@ -2273,6 +2288,7 @@
 			   	       msginfo->fromname ? msginfo->fromname :
 				       _("(No From)"),
 			   S_COL_DATE, date_s,
+			   S_COL_RECVDATE, recvdate_s,
 			   S_COL_SIZE, to_human_readable(msginfo->size),
 			   S_COL_NUMBER, msginfo->msgnum,
 			   S_COL_TO, to_s ? to_s : "",
@@ -4988,6 +5004,7 @@
 				   G_TYPE_STRING,
 				   G_TYPE_UINT,
 				   G_TYPE_STRING,
+				   G_TYPE_STRING,
 
 				   G_TYPE_POINTER,
 
@@ -5007,6 +5024,7 @@
 	SET_SORT(S_COL_SUBJECT, summary_cmp_by_subject);
 	SET_SORT(S_COL_FROM, summary_cmp_by_from);
 	SET_SORT(S_COL_DATE, summary_cmp_by_date);
+	SET_SORT(S_COL_RECVDATE, summary_cmp_by_recvdate);
 	SET_SORT(S_COL_SIZE, summary_cmp_by_size);
 	SET_SORT(S_COL_NUMBER, summary_cmp_by_num);
 	SET_SORT(S_COL_TO, summary_cmp_by_to);
@@ -5092,6 +5110,8 @@
 		   prefs_common.summary_col_size[S_COL_NUMBER], 1.0);
 	ADD_COLUMN(_("To"), text, S_COL_TO, TRUE,
 		   prefs_common.summary_col_size[S_COL_TO], 0.0);
+	ADD_COLUMN(_("Received date"), text, S_COL_RECVDATE, TRUE,
+		   prefs_common.summary_col_size[S_COL_RECVDATE], 0.0);
 
 #undef ADD_COLUMN
 
@@ -5968,6 +5988,7 @@
 
 CMP_FUNC_DEF(summary_cmp_by_num, msginfo_a->msgnum - msginfo_b->msgnum)
 CMP_FUNC_DEF(summary_cmp_by_date, msginfo_a->date_t - msginfo_b->date_t)
+CMP_FUNC_DEF(summary_cmp_by_recvdate, msginfo_a->mtime - msginfo_b->mtime)
 
 #undef CMP_FUNC_DEF
 
Index: src/prefs_summary_column.c
===================================================================
--- src/prefs_summary_column.c	(revision 2029)
+++ src/prefs_summary_column.c	(working copy)
@@ -69,39 +69,42 @@
 } summary_col;
 
 static const gchar *const col_name[N_SUMMARY_VISIBLE_COLS] = {
-	N_("Mark"),		/* S_COL_MARK    */
-	N_("Unread"),		/* S_COL_UNREAD  */
-	N_("Attachment"),	/* S_COL_MIME    */
-	N_("Subject"),		/* S_COL_SUBJECT */
-	N_("From"),		/* S_COL_FROM    */
-	N_("Date"),		/* S_COL_DATE    */
-	N_("Size"),		/* S_COL_SIZE    */
-	N_("Number"),		/* S_COL_NUMBER  */
-	N_("To")		/* S_COL_TO      */
+	N_("Mark"),		/* S_COL_MARK     */
+	N_("Unread"),		/* S_COL_UNREAD   */
+	N_("Attachment"),	/* S_COL_MIME     */
+	N_("Subject"),		/* S_COL_SUBJECT  */
+	N_("From"),		/* S_COL_FROM     */
+	N_("Date"),		/* S_COL_DATE     */
+	N_("Size"),		/* S_COL_SIZE     */
+	N_("Number"),		/* S_COL_NUMBER   */
+	N_("To"),		/* S_COL_TO       */
+	N_("Received date")	/* S_COL_RECVDATE */
 };
 
 static SummaryColumnState default_state[N_SUMMARY_VISIBLE_COLS] = {
-	{ S_COL_MARK   , TRUE  },
-	{ S_COL_UNREAD , TRUE  },
-	{ S_COL_MIME   , TRUE  },
-	{ S_COL_SUBJECT, TRUE  },
-	{ S_COL_FROM   , TRUE  },
-	{ S_COL_DATE   , TRUE  },
-	{ S_COL_SIZE   , TRUE  },
-	{ S_COL_NUMBER , FALSE },
-	{ S_COL_TO     , FALSE }
+	{ S_COL_MARK    , TRUE  },
+	{ S_COL_UNREAD  , TRUE  },
+	{ S_COL_MIME    , TRUE  },
+	{ S_COL_SUBJECT , TRUE  },
+	{ S_COL_FROM    , TRUE  },
+	{ S_COL_DATE    , TRUE  },
+	{ S_COL_SIZE    , TRUE  },
+	{ S_COL_NUMBER  , FALSE },
+	{ S_COL_TO      , FALSE },
+	{ S_COL_RECVDATE, FALSE }
 };
 
 static SummaryColumnState default_sent_state[N_SUMMARY_VISIBLE_COLS] = {
-	{ S_COL_MARK   , TRUE  },
-	{ S_COL_UNREAD , TRUE  },
-	{ S_COL_MIME   , TRUE  },
-	{ S_COL_SUBJECT, TRUE  },
-	{ S_COL_TO     , TRUE  },
-	{ S_COL_DATE   , TRUE  },
-	{ S_COL_SIZE   , TRUE  },
-	{ S_COL_NUMBER , FALSE },
-	{ S_COL_FROM   , FALSE }
+	{ S_COL_MARK    , TRUE  },
+	{ S_COL_UNREAD  , TRUE  },
+	{ S_COL_MIME    , TRUE  },
+	{ S_COL_SUBJECT , TRUE  },
+	{ S_COL_TO      , TRUE  },
+	{ S_COL_DATE    , TRUE  },
+	{ S_COL_SIZE    , TRUE  },
+	{ S_COL_NUMBER  , FALSE },
+	{ S_COL_FROM    , FALSE },
+	{ S_COL_RECVDATE, FALSE }
 };
 
 static void prefs_summary_column_create	(void);
Index: po/fr.po
===================================================================
--- po/fr.po	(revision 2029)
+++ po/fr.po	(working copy)
@@ -5992,6 +5992,11 @@
 msgid "Date"
 msgstr "Date"
 
+#. S_COL_RECVDATE
+#: src/prefs_summary_column.c:81
+msgid "Received date"
+msgstr "Date de réception"
+
 #. S_COL_SIZE
 #: src/prefs_summary_column.c:79
 msgid "Number"
Index: po/ja.po
===================================================================
--- po/ja.po	(revision 2029)
+++ po/ja.po	(working copy)
@@ -5929,6 +5929,11 @@
 msgid "Date"
 msgstr "日付"
 
+#. S_COL_RECVDATE
+#: src/prefs_summary_column.c:81
+msgid "Received date"
+msgstr "受日付"
+
 #. S_COL_SIZE
 #: src/prefs_summary_column.c:79
 msgid "Number"
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.