Colin Leroy
Wilbert Berendsen
Bob Woodside
+ Stefaan Eeckels
+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 <Stefaan.Eeckels@eec.lu>
+
+
2002-03-17 [paul] 0.7.4claws18
* sync with sylpheed 0.7.4cvs5
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
#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"
gpointer data;
+ GHashTable *newsart;
+
/* virtual functions */
GSList * (*get_msg_list) (Folder *folder,
FolderItem *item,
{
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;
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';
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;
}
#include "gtkutils.h"
#include "utils.h"
#include "alertpanel.h"
+#include "colorlabel.h"
static gboolean cancelled;
GtkWidget *domain_entry;
GtkWidget *tunnelcmd_chkbtn;
GtkWidget *tunnelcmd_entry;
+ GtkWidget *crosspost_chkbtn;
+ GtkWidget *crosspost_colormenu;
+
} advanced;
static void prefs_account_fix_size (void);
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);
&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}
};
}
#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;
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) \
{ \
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
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,
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);
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);
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:
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;
}
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
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);
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)
MEMBDUP(subject);
MEMBDUP(msgid);
MEMBDUP(inreplyto);
+ MEMBDUP(xref);
MEMBCOPY(folder);
MEMBCOPY(to_folder);
g_free(msginfo->subject);
g_free(msginfo->msgid);
g_free(msginfo->inreplyto);
+ g_free(msginfo->xref);
g_free(msginfo);
}
gchar *subject;
gchar *msgid;
gchar *inreplyto;
+ gchar *xref;
FolderItem *folder;
FolderItem *to_folder;
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}
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))
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)
{