#include "timing.h"
#include "gedit-print.h"
#include "log.h"
+#include "manual.h"
#define SUMMARY_COL_MARK_WIDTH 10
#define SUMMARY_COL_STATUS_WIDTH 13
GSList *mlist);
static void summary_set_header (SummaryView *summaryview,
gchar *text[],
- MsgInfo *msginfo,
- gboolean *free_from);
+ MsgInfo *msginfo);
static void summary_display_msg (SummaryView *summaryview,
GtkCTreeNode *row);
static void summary_display_msg_full (SummaryView *summaryview,
gconstpointer ptr1,
gconstpointer ptr2);
-static void news_flag_crosspost (MsgInfo *msginfo);
-
static void quicksearch_execute_cb (QuickSearch *quicksearch,
gpointer data);
static void tog_searchbar_cb (GtkWidget *w,
if (!summaryview->mainwin)
return FALSE;
+ summaryview->last_displayed = NULL;
summary_switch_from_to(summaryview, item);
inc_lock();
}
if (is_refresh) {
+ summaryview->last_displayed = summaryview->displayed;
summaryview->displayed =
summary_find_msg_by_msgnum(summaryview,
displayed_msgnum);
void summary_select_next_marked(SummaryView *summaryview)
{
- GtkCTreeNode *node;
+ GtkCTreeNode *node = summaryview->selected;
+ gboolean skip_cur = FALSE;
+
+ if (summaryview->displayed
+ && summaryview->selected == summaryview->displayed) {
+ debug_print("skipping cur (%p %p)\n",
+ summaryview->displayed, summaryview->selected);
+ skip_cur = TRUE;
+ }
+
node = summary_find_next_flagged_msg
- (summaryview, summaryview->selected, MSG_MARKED, TRUE);
+ (summaryview, node, MSG_MARKED, skip_cur);
+
+ if (node)
+ summary_select_node(summaryview, node, TRUE, FALSE);
+ else {
+ node = summary_find_next_flagged_msg
+ (summaryview, NULL, MSG_MARKED, FALSE);
+ if (node == NULL || node == summaryview->selected) {
+ AlertValue val = 0;
- if (!node) {
- AlertValue val;
+ switch (prefs_common.next_unread_msg_dialog) {
+ case NEXTUNREADMSGDIALOG_ALWAYS:
+ val = alertpanel(_("No more marked messages"),
+ _("No marked message found. "
+ "Go to next folder?"),
+ GTK_STOCK_NO, "+"GTK_STOCK_YES, NULL);
+ break;
+ case NEXTUNREADMSGDIALOG_ASSUME_YES:
+ val = G_ALERTALTERNATE;
+ break;
+ case NEXTUNREADMSGDIALOG_ASSUME_NO:
+ val = G_ALERTOTHER;
+ break;
+ default:
+ debug_print(
+ _("Internal error: unexpected value for prefs_common.next_unread_msg_dialog\n"));
+ }
- val = alertpanel(_("No more marked messages"),
- _("No marked message found. "
- "Search from the beginning?"),
- GTK_STOCK_NO, "+"GTK_STOCK_YES, NULL);
- if (val != G_ALERTALTERNATE) return;
- node = summary_find_next_flagged_msg(summaryview, NULL,
- MSG_MARKED, TRUE);
- }
+ if (val == G_ALERTALTERNATE) {
+ folderview_select_next_marked(summaryview->folderview);
+ return;
+ }
+ else
+ return;
+ } else
+ summary_select_node(summaryview, node, TRUE, FALSE);
- if (!node)
- alertpanel_notice(_("No marked messages."));
- else
- summary_select_node(summaryview, node, TRUE, FALSE);
+ }
}
void summary_select_prev_labeled(SummaryView *summaryview)
summary_select_node(summaryview, node, TRUE, FALSE);
}
+void summary_select_last_read(SummaryView *summaryview)
+{
+ if (summaryview->last_displayed)
+ summary_select_node(summaryview, summaryview->last_displayed, TRUE, FALSE);
+}
+
+void summary_select_parent(SummaryView *summaryview)
+{
+ GtkCTreeNode *node = NULL;
+
+ if (summaryview->selected)
+ node = GTK_CTREE_ROW(summaryview->selected)->parent;
+ if (node)
+ summary_select_node(summaryview, node, TRUE, FALSE);
+}
+
void summary_select_by_msgnum(SummaryView *summaryview, guint msgnum)
{
GtkCTreeNode *node;
msginfo = gtk_ctree_node_get_row_data(ctree, node);
- if (msginfo && msginfo->folder && msginfo->folder->folder &&
- msginfo->folder->folder->klass->type == F_NEWS)
- news_flag_crosspost(msginfo);
-
if (MSG_IS_DELETED(msginfo->flags))
summaryview->deleted++;
gtk_label_set_text(GTK_LABEL(summaryview->statlabel_folder), "");
gtk_label_set_text(GTK_LABEL(summaryview->statlabel_select), "");
gtk_label_set_text(GTK_LABEL(summaryview->statlabel_msgs), "");
+ toolbar_main_set_sensitive(summaryview->mainwin);
return;
}
to_human_readable(n_size));
gtk_label_set_text(GTK_LABEL(summaryview->statlabel_msgs), str);
g_free(str);
+ toolbar_main_set_sensitive(summaryview->mainwin);
}
static void summary_set_column_titles(SummaryView *summaryview)
gint *col_pos = summaryview->col_pos;
const gchar *msgid = msginfo->msgid;
GHashTable *msgid_table = summaryview->msgid_table;
- gboolean free_from = FALSE;
- summary_set_header(summaryview, text, msginfo, &free_from);
+ summary_set_header(summaryview, text, msginfo);
gtk_sctree_set_node_info(ctree, cnode, text[col_pos[S_COL_SUBJECT]], 2,
NULL, NULL, NULL, NULL, FALSE, summaryview->threaded && !summaryview->thread_collapsed);
if (summaryview->col_state[summaryview->col_pos[S_COL_TO]].visible)
SET_TEXT(S_COL_TO);
- if (free_from) {
- g_free(text[col_pos[S_COL_FROM]]);
- text[col_pos[S_COL_FROM]] = NULL;
- }
-
#undef SET_TEXT
GTKUT_CTREE_NODE_SET_ROW_DATA(cnode, msginfo);
summaryview->subject_table = subject_table;
if (prefs_common.use_addr_book)
- start_address_completion();
+ start_address_completion(NULL);
if (summaryview->threaded) {
GNode *root, *gnode;
END_TIMING();
} else {
gchar *text[N_SUMMARY_COLS];
- gboolean free_from = FALSE;
gint *col_pos = summaryview->col_pos;
START_TIMING("summaryview_set_ctree_from_list(2)");
cur = mlist;
for (; mlist != NULL; mlist = mlist->next) {
msginfo = (MsgInfo *)mlist->data;
- summary_set_header(summaryview, text, msginfo, &free_from);
+ summary_set_header(summaryview, text, msginfo);
node = gtk_sctree_insert_node
(ctree, NULL, node, text, 2,
NULL, NULL, NULL, NULL,
FALSE, FALSE);
- if (free_from) {
- g_free(text[col_pos[S_COL_FROM]]);
- text[col_pos[S_COL_FROM]] = NULL;
- }
+
GTKUT_CTREE_NODE_SET_ROW_DATA(node, msginfo);
summary_set_marks_func(ctree, node, summaryview);
}
static void summary_set_header(SummaryView *summaryview, gchar *text[],
- MsgInfo *msginfo, gboolean *free_from)
+ MsgInfo *msginfo)
{
static gchar date_modified[80];
static gchar col_score[11];
text[col_pos[S_COL_TO]] = to_text;
if (!should_swap) {
text[col_pos[S_COL_FROM]] = from_text;
- *free_from = FALSE;
} else {
- gchar *tmp = NULL;
- tmp = g_strconcat("-->", to_text, NULL);
+ gchar tmp[BUFFSIZE];
+ snprintf(tmp, BUFFSIZE-1, "--> %s", to_text);
+ tmp[BUFFSIZE-1]='\0';
text[col_pos[S_COL_FROM]] = tmp;
- *free_from = TRUE;
}
if (summaryview->simplify_subject_preg != NULL)
MessageView *msgview;
msgview = summaryview->messageview;
-
+ summaryview->last_displayed = summaryview->displayed;
summaryview->displayed = row;
if (!messageview_is_visible(msgview)) {
main_window_toggle_message_view(summaryview->mainwin);
gtk_ctree_node_moveto(ctree, summaryview->selected, 0, 0.5, 0);
}
+void account_rules_radio_button_toggled_cb(GtkToggleButton *btn, gpointer data)
+{
+ prefs_common.apply_per_account_filtering_rules = GPOINTER_TO_INT(data);
+}
+
+gboolean summary_filter_get_mode(void)
+/* ask what to do w/ them: skip them, apply them regardless to the account,
+ use the current account */
+{
+ /* TODO: eventually also propose to use the current folder's default account,
+ if it is set */
+ /* TODO: eventually allow to select the account to use from a optmenu */
+
+ GtkWidget *vbox;
+ GtkWidget *account_rules_skip;
+ GtkWidget *account_rules_force;
+ GtkWidget *account_rules_user_current;
+ AlertValue val;
+
+ vbox = gtk_vbox_new (FALSE, 0);
+
+ account_rules_skip = gtk_radio_button_new_with_label
+ (NULL, _("Skip these rules"));
+ account_rules_force = gtk_radio_button_new_with_label_from_widget
+ (GTK_RADIO_BUTTON(account_rules_skip),
+ _("Apply these rules regardless of the account they belong to"));
+ account_rules_user_current = gtk_radio_button_new_with_label_from_widget
+ (GTK_RADIO_BUTTON(account_rules_skip),
+ _("Use current account for these rules"));
+ gtk_box_pack_start (GTK_BOX (vbox), account_rules_skip, FALSE, FALSE, 0);
+ gtk_box_pack_start (GTK_BOX (vbox), account_rules_force, FALSE, FALSE, 0);
+ gtk_box_pack_start (GTK_BOX (vbox), account_rules_user_current, FALSE, FALSE, 0);
+ g_signal_connect(G_OBJECT(account_rules_skip), "toggled",
+ G_CALLBACK(account_rules_radio_button_toggled_cb),
+ GINT_TO_POINTER(FILTERING_ACCOUNT_RULES_SKIP));
+ g_signal_connect(G_OBJECT(account_rules_force), "toggled",
+ G_CALLBACK(account_rules_radio_button_toggled_cb),
+ GINT_TO_POINTER(FILTERING_ACCOUNT_RULES_FORCE));
+ g_signal_connect(G_OBJECT(account_rules_user_current), "toggled",
+ G_CALLBACK(account_rules_radio_button_toggled_cb),
+ GINT_TO_POINTER(FILTERING_ACCOUNT_RULES_USE_CURRENT));
+ switch (prefs_common.apply_per_account_filtering_rules) {
+ case FILTERING_ACCOUNT_RULES_SKIP:
+ gtk_toggle_button_set_active(
+ GTK_TOGGLE_BUTTON(account_rules_skip), TRUE);
+ break;
+ case FILTERING_ACCOUNT_RULES_FORCE:
+ gtk_toggle_button_set_active(
+ GTK_TOGGLE_BUTTON(account_rules_force), TRUE);
+ break;
+ case FILTERING_ACCOUNT_RULES_USE_CURRENT:
+ gtk_toggle_button_set_active(
+ GTK_TOGGLE_BUTTON(account_rules_user_current), TRUE);
+ break;
+ }
+
+ val = alertpanel_with_widget(
+ _("Filtering"),
+ _("There are some filtering rules that belong to an account.\n"
+ "Please choose what to do with these rules:"),
+ _("_Filter"), _("_Cancel"), NULL, TRUE, vbox);
+ if ((val & ~G_ALERTDISABLE) != G_ALERTDEFAULT) {
+ return FALSE;
+ } else if (val & G_ALERTDISABLE)
+ prefs_common.ask_apply_per_account_filtering_rules = FALSE;
+
+ return TRUE;
+}
+
void summary_filter(SummaryView *summaryview, gboolean selected_only)
{
GSList *mlist = NULL, *cur_list;
summary_lock(summaryview);
+ /* are there any per-account filtering rules? */
+ if (prefs_common.ask_apply_per_account_filtering_rules == TRUE &&
+ filtering_peek_per_account_rules(filtering_rules)) {
+
+ if (summary_filter_get_mode() == FALSE) {
+ summary_unlock(summaryview);
+ return;
+ }
+ }
+
folder_item_update_freeze();
debug_print("filtering...");
if (hooks_invoke(MAIL_MANUAL_FILTERING_HOOKLIST, &mail_filtering_data))
return;
- filter_message_by_msginfo(filtering_rules, msginfo);
+ filter_message_by_msginfo(filtering_rules, msginfo, NULL);
}
void summary_msginfo_filter_open(FolderItem * item, MsgInfo *msginfo,
if (item == NULL)
prefs_filtering_open(&pre_global_processing,
_("Processing rules to apply before folder rules"),
- header, key);
+ MANUAL_ANCHOR_PROCESSING,
+ header, key, FALSE);
else
prefs_filtering_open(&item->prefs->processing,
_("Processing configuration"),
- header, key);
+ MANUAL_ANCHOR_PROCESSING,
+ header, key, FALSE);
}
else {
prefs_filtering_open(&filtering_rules,
- _("Filtering configuration"),
- header, key);
+ _("Filtering configuration"),
+ MANUAL_ANCHOR_FILTERING,
+ header, key, TRUE);
}
g_free(header);
summary_select_by_msgnum(summaryview, selected_msgnum);
summaryview->displayed = summary_find_msg_by_msgnum(summaryview, displayed_msgnum);
+ summaryview->last_displayed = summaryview->displayed;
if (!summaryview->displayed)
messageview_clear(summaryview->messageview);
else
return summary_cmp_by_date(clist, ptr1, ptr2);
}
-static void news_flag_crosspost(MsgInfo *msginfo)
-{
- GString *line;
- gpointer key;
- gpointer value;
- Folder *mff;
-
- g_return_if_fail(msginfo != NULL);
- g_return_if_fail(msginfo->folder != NULL);
- g_return_if_fail(msginfo->folder->folder != NULL);
- mff = msginfo->folder->folder;
- g_return_if_fail(mff->klass->type == F_NEWS);
-
- if (mff->account->mark_crosspost_read) {
- line = g_string_sized_new(128);
- g_string_printf(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>", (gchar *)value);
- if (MSG_IS_NEW(msginfo->flags) || MSG_IS_UNREAD(msginfo->flags)) {
- summary_msginfo_change_flags(msginfo,
- mff->account->crosspost_col, 0, MSG_NEW | MSG_UNREAD, 0);
- }
- g_hash_table_remove(mff->newsart, key);
- g_free(key);
- }
- g_string_free(line, TRUE);
- debug_print("\n");
- }
-}
-
static void summary_ignore_thread_func(GtkCTree *ctree, GtkCTreeNode *row, gpointer data)
{
SummaryView *summaryview = (SummaryView *) data;