#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
static GdkBitmap *markxpmmask;
static GdkPixmap *deletedxpm;
static GdkBitmap *deletedxpmmask;
+static GdkPixmap *movedxpm;
+static GdkBitmap *movedxpmmask;
+static GdkPixmap *copiedxpm;
+static GdkBitmap *copiedxpmmask;
static GdkPixmap *newxpm;
static GdkBitmap *newxpmmask;
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,
#define START_LONG_OPERATION(summaryview) { \
summary_lock(summaryview); \
main_window_cursor_wait(summaryview->mainwin); \
- gtk_clist_freeze(GTK_CLIST(summaryview->ctree)); \
+ if (sc_g_list_bigger(GTK_CLIST(summaryview->ctree)->selection, 1)) {\
+ froze = TRUE; \
+ gtk_clist_freeze(GTK_CLIST(summaryview->ctree)); \
+ } \
folder_item_update_freeze(); \
inc_lock(); \
+ hooks_unregister_hook(MSGINFO_UPDATE_HOOKLIST, \
+ summaryview->msginfo_update_callback_id); \
}
#define END_LONG_OPERATION(summaryview) { \
inc_unlock(); \
folder_item_update_thaw(); \
- gtk_clist_thaw(GTK_CLIST(summaryview->ctree)); \
+ if (froze) \
+ gtk_clist_thaw(GTK_CLIST(summaryview->ctree)); \
main_window_cursor_normal(summaryview->mainwin); \
summary_unlock(summaryview); \
+ summaryview->msginfo_update_callback_id = \
+ hooks_register_hook(MSGINFO_UPDATE_HOOKLIST, \
+ summary_update_msg, (gpointer) summaryview); \
}
SummaryView *summary_create(void)
&clipgpgsignedxpm, &clipgpgsignedxpmmask);
stock_pixmap_gdk(summaryview->ctree, STOCK_PIXMAP_SPAM,
&spamxpm, &spamxpmmask);
+ stock_pixmap_gdk(summaryview->ctree, STOCK_PIXMAP_MOVED,
+ &movedxpm, &movedxpmmask);
+ stock_pixmap_gdk(summaryview->ctree, STOCK_PIXMAP_COPIED,
+ &copiedxpm, &copiedxpmmask);
summary_set_fonts(summaryview);
summary_set_column_titles(summaryview);
}
+static gboolean summaryview_quicksearch_recurse(gpointer data)
+{
+ SummaryView *summaryview = (SummaryView *)data;
+ main_window_cursor_wait(summaryview->mainwin);
+ quicksearch_reset_cur_folder_item(summaryview->quicksearch);
+ quicksearch_search_subfolders(summaryview->quicksearch,
+ summaryview->folderview,
+ summaryview->folder_item);
+ main_window_cursor_normal(summaryview->mainwin);
+ return FALSE;
+}
gboolean summary_show(SummaryView *summaryview, FolderItem *item)
{
GtkCTree *ctree = GTK_CTREE(summaryview->ctree);
if (!summaryview->mainwin)
return FALSE;
-
+START_TIMING("--------- summary_show");
+ summaryview->last_displayed = NULL;
summary_switch_from_to(summaryview, item);
inc_lock();
} else {
summary_unlock(summaryview);
inc_unlock();
+ END_TIMING();
return FALSE;
}
if (changed || !quicksearch_is_active(summaryview->quicksearch))
buf = NULL;
if (!item || !item->path || !folder_item_parent(item) || item->no_select) {
g_free(buf);
- debug_print("empty folder\n\n");
+ debug_print("empty folder (%p %s %p %d)\n\n",
+ item,
+ item?item->path:"NULL",
+ item?folder_item_parent(item):0x0,
+ item?item->no_select:FALSE);
summary_set_hide_read_msgs_menu(summaryview, FALSE);
summary_clear_all(summaryview);
summaryview->folder_item = item;
summaryview->folderview,
summaryview->folder_item);
main_window_cursor_normal(summaryview->mainwin);
- }
+ }
+ END_TIMING();
return TRUE;
}
g_free(buf);
statusbar_pop_all();
hidden_removed = TRUE;
- if (quicksearch_is_running(summaryview->quicksearch)) {
- /* only scan subfolders when quicksearch changed,
- * not when search is the same and folder changed */
- main_window_cursor_wait(summaryview->mainwin);
- quicksearch_reset_cur_folder_item(summaryview->quicksearch);
- quicksearch_search_subfolders(summaryview->quicksearch,
- summaryview->folderview,
- summaryview->folder_item);
- main_window_cursor_normal(summaryview->mainwin);
- }
-
if (!quicksearch_is_active(summaryview->quicksearch)) {
debug_print("search cancelled!\n");
gtk_clist_thaw(GTK_CLIST(ctree));
summary_unlock(summaryview);
inc_unlock();
summary_show(summaryview, summaryview->folder_item);
+ END_TIMING();
return FALSE;
}
g_slist_free(mlist);
}
if (!hidden_removed) {
+ START_TIMING("removing hidden");
not_killed = NULL;
for(cur = mlist ; cur != NULL && cur->data != NULL ; cur = g_slist_next(cur)) {
MsgInfo * msginfo = (MsgInfo *) cur->data;
}
g_slist_free(mlist);
mlist = not_killed;
+ END_TIMING();
}
STATUSBAR_POP(summaryview->mainwin);
g_slist_free(mlist);
+ if (quicksearch_is_active(summaryview->quicksearch) &&
+ quicksearch_is_running(summaryview->quicksearch)) {
+ /* only scan subfolders when quicksearch changed,
+ * not when search is the same and folder changed */
+ g_timeout_add(100, summaryview_quicksearch_recurse, summaryview);
+ }
+
if (is_refresh) {
+ summaryview->last_displayed = summaryview->displayed;
summaryview->displayed =
summary_find_msg_by_msgnum(summaryview,
displayed_msgnum);
main_window_cursor_normal(summaryview->mainwin);
summary_unlock(summaryview);
inc_unlock();
-
+ END_TIMING();
return TRUE;
}
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;
gboolean display_msg, gboolean do_refresh)
{
GtkCTree *ctree = GTK_CTREE(summaryview->ctree);
-
if (summary_is_locked(summaryview))
return;
if (!summaryview->folder_item)
GTK_EVENTS_FLUSH();
summary_unlock(summaryview);
gtk_widget_grab_focus(GTK_WIDGET(ctree));
- if (GTK_CTREE_ROW(node) == NULL) {
- g_warning("crash avoidance hack 1\n");
- return;
- }
- if (((GtkCListRow *)(GTK_CTREE_ROW(node)))->state < GTK_STATE_NORMAL
- || ((GtkCListRow *)(GTK_CTREE_ROW(node)))->state > GTK_STATE_INSENSITIVE) {
- g_warning("crash avoidance hack 2\n");
- return;
- }
gtk_ctree_node_moveto(ctree, node, 0, 0.5, 0);
}
- summary_unselect_all(summaryview);
if (display_msg && summaryview->displayed == node)
summaryview->displayed = NULL;
summaryview->display_msg = display_msg;
for (; node != NULL; node = gtkut_ctree_node_next(ctree, node)) {
msginfo = gtk_ctree_node_get_row_data(ctree, node);
- if (msginfo && !MSG_IS_DELETED(msginfo->flags)) break;
+ if (msginfo && !MSG_IS_DELETED(msginfo->flags)
+ && !MSG_IS_MOVE(msginfo->flags)) break;
}
return 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;
}
msginfo = gtk_ctree_node_get_row_data
(GTK_CTREE(summaryview->ctree),
GTK_CTREE_NODE(cur->data));
- if (!msginfo)
- g_warning("summary_status_show(): msginfo == NULL\n");
- else {
+ if (msginfo) {
sel_size += msginfo->size;
n_selected++;
-
}
}
msginfo = gtk_ctree_node_get_row_data
(GTK_CTREE(summaryview->ctree),
GTK_CTREE_NODE(cur));
- if (!msginfo)
- g_warning("summary_status_show(): msginfo == NULL\n");
- else {
+ if (msginfo) {
n_size += msginfo->size;
n_total++;
if (MSG_IS_NEW(msginfo->flags))
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)
GtkCTree *ctree = GTK_CTREE(summaryview->ctree);
GtkCList *clist = GTK_CLIST(summaryview->ctree);
GtkCListCompareFunc cmp_func = NULL;
+ START_TIMING("summary_sort");
g_signal_handlers_block_by_func(G_OBJECT(summaryview->ctree),
G_CALLBACK(summary_tree_expanded), summaryview);
gtk_clist_freeze(GTK_CLIST(summaryview->ctree));
gtk_clist_set_compare_func(clist, cmp_func);
gtk_clist_set_sort_type(clist, (GtkSortType)sort_type);
-
gtk_sctree_sort_recursive(ctree, NULL);
gtk_ctree_node_moveto(ctree, summaryview->selected, 0, 0.5, 0);
gtk_clist_thaw(GTK_CLIST(summaryview->ctree));
g_signal_handlers_unblock_by_func(G_OBJECT(summaryview->ctree),
G_CALLBACK(summary_tree_expanded), summaryview);
+ END_TIMING();
}
gboolean summary_insert_gnode_func(GtkCTree *ctree, guint depth, GNode *gnode,
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,
- gnode->parent->parent ? TRUE : FALSE);
-#define SET_TEXT(col) \
- gtk_ctree_node_set_text(ctree, cnode, col_pos[col], \
- text[col_pos[col]])
-
- SET_TEXT(S_COL_NUMBER);
- SET_TEXT(S_COL_SCORE);
- SET_TEXT(S_COL_SIZE);
- SET_TEXT(S_COL_DATE);
- SET_TEXT(S_COL_FROM);
- SET_TEXT(S_COL_TO);
- /* SET_TEXT(S_COL_SUBJECT); already set by node info */
-
- if (free_from) {
- g_free(text[col_pos[S_COL_FROM]]);
- text[col_pos[S_COL_FROM]] = NULL;
- }
+ NULL, NULL, NULL, NULL, FALSE, summaryview->threaded && !summaryview->thread_collapsed);
+#define SET_TEXT(col) { \
+ gtk_ctree_node_set_text(ctree, cnode, col_pos[col], \
+ text[col_pos[col]]); \
+}
+
+ if (summaryview->col_state[summaryview->col_pos[S_COL_NUMBER]].visible)
+ SET_TEXT(S_COL_NUMBER);
+ if (summaryview->col_state[summaryview->col_pos[S_COL_SCORE]].visible)
+ SET_TEXT(S_COL_SCORE);
+ if (summaryview->col_state[summaryview->col_pos[S_COL_SIZE]].visible)
+ SET_TEXT(S_COL_SIZE);
+ if (summaryview->col_state[summaryview->col_pos[S_COL_DATE]].visible)
+ SET_TEXT(S_COL_DATE);
+ if (summaryview->col_state[summaryview->col_pos[S_COL_FROM]].visible)
+ SET_TEXT(S_COL_FROM);
+ if (summaryview->col_state[summaryview->col_pos[S_COL_TO]].visible)
+ SET_TEXT(S_COL_TO);
#undef SET_TEXT
summaryview->subject_table = subject_table;
if (prefs_common.use_addr_book)
- start_address_completion();
+ start_address_completion(NULL);
if (summaryview->threaded) {
GNode *root, *gnode;
-
+ START_TIMING("summaryview_set_ctree_from_list(1)");
root = procmsg_get_thread_tree(mlist);
for (gnode = root->children; gnode != NULL;
gnode = gnode->next) {
- node = gtk_ctree_insert_gnode
+ node = gtk_sctree_insert_gnode
(ctree, NULL, node, gnode,
summary_insert_gnode_func, summaryview);
}
g_node_destroy(root);
- summary_thread_init(summaryview);
+ 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);
node);
}
mlist = cur;
+ END_TIMING();
}
if (prefs_common.enable_hscrollbar &&
node = GTK_CTREE_NODE(GTK_CLIST(ctree)->row_list);
if (prefs_common.bold_unread) {
+ START_TIMING("summaryview_set_ctree_from_list(3)");
while (node) {
GtkCTreeNode *next = GTK_CTREE_NODE_NEXT(node);
if (GTK_CTREE_ROW(node)->children)
summary_set_row_marks(summaryview, node);
node = next;
}
+ END_TIMING();
}
g_signal_handlers_unblock_by_func(G_OBJECT(ctree),
}
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_MIME]] = "";
text[col_pos[S_COL_LOCKED]] = "";
text[col_pos[S_COL_DATE]] = "";
- text[col_pos[S_COL_NUMBER]] = itos(msginfo->msgnum);
- text[col_pos[S_COL_SIZE]] = to_human_readable(msginfo->size);
- text[col_pos[S_COL_SCORE]] = itos_buf(col_score, msginfo->score);
-
- if (msginfo->date_t) {
- procheader_date_get_localtime(date_modified,
- sizeof(date_modified),
- msginfo->date_t);
- text[col_pos[S_COL_DATE]] = date_modified;
- } else if (msginfo->date)
- text[col_pos[S_COL_DATE]] = msginfo->date;
+ if (summaryview->col_state[summaryview->col_pos[S_COL_NUMBER]].visible)
+ text[col_pos[S_COL_NUMBER]] = itos(msginfo->msgnum);
else
- text[col_pos[S_COL_DATE]] = _("(No Date)");
+ text[col_pos[S_COL_NUMBER]] = "";
+ /* slow! */
+ if (summaryview->col_state[summaryview->col_pos[S_COL_SIZE]].visible)
+ text[col_pos[S_COL_SIZE]] = to_human_readable(msginfo->size);
+ else
+ text[col_pos[S_COL_SIZE]] = "";
+
+ if (summaryview->col_state[summaryview->col_pos[S_COL_SCORE]].visible)
+ text[col_pos[S_COL_SCORE]] = itos_buf(col_score, msginfo->score);
+ else
+ text[col_pos[S_COL_SCORE]] = "";
+
+ /* slow! */
+ if (summaryview->col_state[summaryview->col_pos[S_COL_DATE]].visible) {
+ if (msginfo->date_t) {
+ procheader_date_get_localtime(date_modified,
+ sizeof(date_modified),
+ msginfo->date_t);
+ text[col_pos[S_COL_DATE]] = date_modified;
+ } else if (msginfo->date)
+ text[col_pos[S_COL_DATE]] = msginfo->date;
+ else
+ text[col_pos[S_COL_DATE]] = _("(No Date)");
+ }
+
if (prefs_common.swap_from && msginfo->from && msginfo->to
&& !summaryview->col_state[summaryview->col_pos[S_COL_TO]].visible) {
gchar *addr = NULL;
msginfo->fromname :
_("(No From)");
} else {
+ gchar buf[BUFFSIZE];
gchar *tmp = summary_complete_address(msginfo->from);
- from_text = tmp ? tmp : (msginfo->fromname ?
- msginfo->fromname:
- _("(No From)"));
+ if (tmp) {
+ strncpy2(buf, tmp, sizeof(buf));
+ g_free(tmp);
+ from_text = buf;
+ } else {
+ from_text = (msginfo->fromname) ?
+ msginfo->fromname:
+ _("(No From)");
+ }
}
to_text = msginfo->to ? msginfo->to :
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)
summary_msginfo_unset_flags
(msginfo, MSG_NEW | MSG_UNREAD, 0);
summary_set_row_marks(summaryview, row);
- gtk_clist_thaw(GTK_CLIST(summaryview->ctree));
summary_status_show(summaryview);
}
}
GtkCTree *ctree = GTK_CTREE(summaryview->ctree);
MsgInfo *msginfo;
gint val;
-
+ START_TIMING("summary_display_msg_full");
if (!new_window) {
if (summaryview->displayed == row)
return;
else
summaryview->messageview->filtered = FALSE;
}
-
g_return_if_fail(row != NULL);
if (summary_is_locked(summaryview)) return;
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);
val = messageview_show(msgview, msginfo, all_headers);
if (GTK_CLIST(msgview->mimeview->ctree)->row_list == NULL)
gtk_widget_grab_focus(summaryview->ctree);
- gtkut_ctree_node_move_if_on_the_edge(ctree, row);
+ gtkut_ctree_node_move_if_on_the_edge(ctree, row,
+ GTK_CLIST(summaryview->ctree)->focus_row);
}
if (val == 0 && MSG_IS_UNREAD(msginfo->flags)) {
messageview_set_menu_sensitive(summaryview->messageview);
summary_unlock(summaryview);
+ END_TIMING();
}
void summary_display_msg_selected(SummaryView *summaryview,
summaryview->selected);
if (!msginfo) return;
- compose_reedit(msginfo);
+ compose_reedit(msginfo, FALSE);
}
gboolean summary_step(SummaryView *summaryview, GtkScrollType type)
gtk_ctree_node_set_pixmap(ctree, row, col_pos[S_COL_MARK],
markxpm, markxpmmask);
} else if (MSG_IS_MOVE(flags)) {
- gtk_ctree_node_set_text(ctree, row, col_pos[S_COL_MARK], "o");
+ gtk_ctree_node_set_pixmap(ctree, row, col_pos[S_COL_MARK],
+ movedxpm, movedxpmmask);
if (style)
style = bold_marked_style;
else {
gtk_ctree_node_set_foreground
(ctree, row, &summaryview->color_marked);
} else if (MSG_IS_COPY(flags)) {
- gtk_ctree_node_set_text(ctree, row, col_pos[S_COL_MARK], "O");
+ gtk_ctree_node_set_pixmap(ctree, row, col_pos[S_COL_MARK],
+ copiedxpm, copiedxpmmask);
if (style)
style = bold_marked_style;
else {
{
GtkCTree *ctree = GTK_CTREE(summaryview->ctree);
GList *cur;
+ gboolean froze = FALSE;
START_LONG_OPERATION(summaryview);
folder_item_set_batch(summaryview->folder_item, TRUE);
msginfo->msgnum);
}
-void summary_mark_as_read(SummaryView *summaryview)
+void summary_mark_as_read
+(SummaryView *summaryview)
{
GtkCTree *ctree = GTK_CTREE(summaryview->ctree);
GList *cur;
+ gboolean froze = FALSE;
START_LONG_OPERATION(summaryview);
folder_item_set_batch(summaryview->folder_item, TRUE);
{
GtkCTree *ctree = GTK_CTREE(summaryview->ctree);
GList *cur;
+ gboolean froze = FALSE;
START_LONG_OPERATION(summaryview);
for (cur = GTK_CLIST(ctree)->selection; cur != NULL && cur->data != NULL; cur = cur->next)
{
GtkCTree *ctree = GTK_CTREE(summaryview->ctree);
GList *cur;
+ gboolean froze = FALSE;
START_LONG_OPERATION(summaryview);
for (cur = GTK_CLIST(ctree)->selection; cur != NULL && cur->data != NULL; cur = cur->next)
GtkCTree *ctree = GTK_CTREE(summaryview->ctree);
GtkCTreeNode *node;
AlertValue val;
+ gboolean froze = FALSE;
if (prefs_common.ask_mark_all_read) {
val = alertpanel_full(_("Mark all as read"),
_("Do you really want to mark all mails in this "
"folder as read ?"), GTK_STOCK_NO, GTK_STOCK_YES, NULL,
- TRUE, NULL, ALERT_QUESTION, G_ALERTALTERNATE);
+ TRUE, NULL, ALERT_QUESTION, G_ALERTDEFAULT);
- if (val == G_ALERTDEFAULT ||
- val == (G_ALERTDEFAULT|G_ALERTDISABLE))
+ if ((val & ~G_ALERTDISABLE) != G_ALERTALTERNATE)
return;
- else if (val == (G_ALERTALTERNATE|G_ALERTDISABLE))
+ else if (val & G_ALERTDISABLE)
prefs_common.ask_mark_all_read = FALSE;
}
GSList *msgs = NULL;
gboolean immediate_exec = prefs_common.immediate_exec;
gboolean moved = FALSE;
+ gboolean froze = FALSE;
+
prefs_common.immediate_exec = FALSE;
START_LONG_OPERATION(summaryview);
} else {
summary_msginfo_unset_flags(msginfo, MSG_SPAM, 0);
}
+ summary_set_row_marks(summaryview, row);
}
} else {
log_error(_("An error happened while learning.\n"));
{
GtkCTree *ctree = GTK_CTREE(summaryview->ctree);
GList *cur;
+ gboolean froze = FALSE;
START_LONG_OPERATION(summaryview);
folder_item_set_batch(summaryview->folder_item, TRUE);
GtkCTreeNode *node;
AlertValue aval;
MsgInfo *msginfo;
+ gboolean froze = FALSE;
if (!item) return;
if (!summaryview->folder_item) return;
- aval = alertpanel(_("Delete message(s)"),
- _("Do you really want to delete selected message(s)?"),
- GTK_STOCK_CANCEL, "+"GTK_STOCK_DELETE, NULL);
- if (aval != G_ALERTALTERNATE) return;
+ if (!prefs_common.live_dangerously) {
+ aval = alertpanel(_("Delete message(s)"),
+ _("Do you really want to delete selected message(s)?"),
+ GTK_STOCK_CANCEL, "+"GTK_STOCK_DELETE, NULL);
+ if (aval != G_ALERTALTERNATE) return;
+ }
for (cur = GTK_CLIST(ctree)->selection; cur != NULL && cur->data != NULL;
cur = cur->next) {
{
GtkCTree *ctree = GTK_CTREE(summaryview->ctree);
GList *cur;
+ gboolean froze = FALSE;
START_LONG_OPERATION(summaryview);
folder_item_set_batch(summaryview->folder_item, TRUE);
void summary_move_selected_to(SummaryView *summaryview, FolderItem *to_folder)
{
GList *cur;
+ GtkCTreeNode *sel_last = NULL;
+ gboolean froze = FALSE;
if (!to_folder) return;
if (!summaryview->folder_item ||
return;
}
- START_LONG_OPERATION(summaryview);
+ START_LONG_OPERATION(summaryview);
for (cur = GTK_CLIST(summaryview->ctree)->selection;
- cur != NULL && cur->data != NULL; cur = cur->next)
+ cur != NULL && cur->data != NULL; cur = cur->next) {
+ sel_last = GTK_CTREE_NODE(cur->data);
summary_move_row_to
(summaryview, GTK_CTREE_NODE(cur->data), to_folder);
-
+ }
END_LONG_OPERATION(summaryview);
summaryview->display_msg = prefs_common.always_show_msg;
if (prefs_common.immediate_exec) {
summary_execute(summaryview);
} else {
+ GtkCTreeNode *node = summary_find_next_msg(summaryview, sel_last);
+ if (!node)
+ node = summary_find_prev_msg(summaryview, sel_last);
+ summary_select_node(summaryview, node, prefs_common.always_show_msg, TRUE);
summary_status_show(summaryview);
}
void summary_copy_selected_to(SummaryView *summaryview, FolderItem *to_folder)
{
GList *cur;
+ gboolean froze = FALSE;
if (!to_folder) return;
if (!summaryview->folder_item) return;
summaryview->displayed = NULL;
}
if (GTK_CTREE_ROW(node)->children != NULL) {
- g_warning("summary_execute(): children != NULL\n");
- continue;
+ next = NULL;
+ if (GTK_CTREE_ROW(node)->sibling) {
+ next = GTK_CTREE_ROW(node)->sibling;
+ } else {
+ GtkCTreeNode *parent = NULL;
+ for (parent = GTK_CTREE_ROW(node)->parent; parent != NULL;
+ parent = GTK_CTREE_ROW(parent)->parent) {
+ if (GTK_CTREE_ROW(parent)->sibling) {
+ next = GTK_CTREE_ROW(parent)->sibling;
+ }
+ }
+ }
}
if (!new_selected &&
}
folder_item_update_thaw();
- gtk_clist_thaw(GTK_CLIST(summaryview->ctree));
if (new_selected) {
summary_unlock(summaryview);
gtk_sctree_select
- (GTK_SCTREE(ctree),
- new_selected);
+ (GTK_SCTREE(ctree), new_selected);
summary_lock(summaryview);
}
if (summaryview->threaded) {
- gtk_clist_freeze(GTK_CLIST(summaryview->ctree));
summary_thread_build(summaryview);
summary_thread_init(summaryview);
- gtk_clist_thaw(GTK_CLIST(summaryview->ctree));
}
+ gtk_clist_thaw(GTK_CLIST(summaryview->ctree));
+
summaryview->selected = clist->selection ?
GTK_CTREE_NODE(clist->selection->data) : NULL;
summaryview);
if (summaryview->mlist) {
+ hooks_unregister_hook(MSGINFO_UPDATE_HOOKLIST,
+ summaryview->msginfo_update_callback_id);
val = procmsg_move_messages(summaryview->mlist);
+ summaryview->msginfo_update_callback_id =
+ hooks_register_hook(MSGINFO_UPDATE_HOOKLIST,
+ summary_update_msg, (gpointer) summaryview);
for (cur = summaryview->mlist; cur != NULL && cur->data != NULL; cur = cur->next)
procmsg_msginfo_free((MsgInfo *)cur->data);
msginfo->msgid))
g_hash_table_remove(summaryview->msgid_table,
msginfo->msgid);
+ if (msginfo->subject && *msginfo->subject &&
+ node == subject_table_lookup(summaryview->subject_table,
+ msginfo->subject)) {
+ subject_table_remove(summaryview->subject_table,
+ msginfo->subject);
+ }
}
}
GtkCTree *ctree = GTK_CTREE(summaryview->ctree);
/* search copying messages and execute */
+ hooks_unregister_hook(MSGINFO_UPDATE_HOOKLIST,
+ summaryview->msginfo_update_callback_id);
gtk_ctree_pre_recursive(ctree, NULL, summary_execute_copy_func,
summaryview);
g_slist_free(summaryview->mlist);
summaryview->mlist = NULL;
}
+ summaryview->msginfo_update_callback_id =
+ hooks_register_hook(MSGINFO_UPDATE_HOOKLIST,
+ summary_update_msg, (gpointer) summaryview);
}
static void summary_execute_copy_func(GtkCTree *ctree, GtkCTreeNode *node,
if (!summaryview->mlist) return;
+ hooks_unregister_hook(MSGINFO_UPDATE_HOOKLIST,
+ summaryview->msginfo_update_callback_id);
+
folder_item_remove_msgs(summaryview->folder_item,
summaryview->mlist);
+ summaryview->msginfo_update_callback_id =
+ hooks_register_hook(MSGINFO_UPDATE_HOOKLIST,
+ summary_update_msg, (gpointer) summaryview);
for (cur = summaryview->mlist; cur != NULL && cur->data != NULL; cur = cur->next)
procmsg_msginfo_free((MsgInfo *)cur->data);
if (msginfo && MSG_IS_DELETED(msginfo->flags)) {
summaryview->mlist =
- g_slist_append(summaryview->mlist, msginfo);
+ g_slist_prepend(summaryview->mlist, msginfo);
gtk_ctree_node_set_row_data(ctree, node, NULL);
if (msginfo->msgid && *msginfo->msgid &&
msginfo->subject);
}
- if (parent && parent != node) {
+ if (parent && parent != node && parent != GTK_CTREE_ROW(node)->parent) {
gtk_ctree_move(ctree, node, parent, NULL);
}
GtkCTree *ctree = GTK_CTREE(summaryview->ctree);
GtkCTreeNode *node = GTK_CTREE_NODE(GTK_CLIST(ctree)->row_list);
GtkCTreeNode *next;
-
+ START_TIMING("summary_thread_init");
if (!summaryview->thread_collapsed) {
g_signal_handlers_block_by_func(G_OBJECT(ctree),
G_CALLBACK(summary_tree_expanded), summaryview);
g_signal_handlers_unblock_by_func(G_OBJECT(ctree),
G_CALLBACK(summary_tree_expanded), summaryview);
}
+ END_TIMING();
}
static void summary_unthread_for_exec(SummaryView *summaryview)
{
GtkCTreeNode *node;
GtkCTree *ctree = GTK_CTREE(summaryview->ctree);
+ gboolean froze = FALSE;
debug_print("Unthreading for execution...");
for (node = GTK_CTREE_NODE(GTK_CLIST(ctree)->row_list);
node != NULL; node = GTK_CTREE_NODE_NEXT(node)) {
- summary_unthread_for_exec_func(ctree, node, NULL);
+ summary_unthread_for_exec_func(ctree, node, summaryview);
}
END_LONG_OPERATION(summaryview);
GtkCTreeNode *top_parent;
GtkCTreeNode *child;
GtkCTreeNode *sibling;
-
+ SummaryView * summaryview = (SummaryView *)data;
msginfo = GTKUT_CTREE_NODE_GET_ROW_DATA(node);
if (!msginfo ||
child = GTK_CTREE_ROW(node)->children;
if (!child) return;
+ if (node == summaryview->selected)
+ summaryview->selected = NULL;
+ if (node == summaryview->displayed)
+ summaryview->displayed = NULL;
+
for (top_parent = node;
GTK_CTREE_ROW(top_parent)->parent != NULL;
top_parent = GTK_CTREE_ROW(top_parent)->parent)
;
sibling = GTK_CTREE_ROW(top_parent)->sibling;
+ GTK_SCTREE(ctree)->sorting = TRUE;
while (child != NULL) {
GtkCTreeNode *next_child;
-
+ MsgInfo *cinfo = GTKUT_CTREE_NODE_GET_ROW_DATA(child);
+
next_child = GTK_CTREE_ROW(child)->sibling;
- gtk_ctree_move(ctree, child, NULL, sibling);
+
+ if (!MSG_IS_MOVE(cinfo->flags) && !MSG_IS_DELETED(cinfo->flags)) {
+ gtk_ctree_move(ctree, child,
+ NULL,
+ sibling);
+ } else {
+ if (child == summaryview->displayed) {
+ messageview_clear(summaryview->messageview);
+ summaryview->displayed = NULL;
+ }
+ if (child == summaryview->selected) {
+ messageview_clear(summaryview->messageview);
+ summaryview->selected = NULL;
+ }
+ }
child = next_child;
}
+ GTK_SCTREE(ctree)->sorting = FALSE;
}
void summary_expand_threads(SummaryView *summaryview)
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);
}
gtk_ctree_node_set_row_style(ctree, node, style);
+ gtk_style_unref(style);
}
static void summary_set_row_colorlabel(SummaryView *summaryview, GtkCTreeNode *row, guint labelcolor)
summary_msginfo_change_flags(msginfo, MSG_COLORLABEL_TO_FLAGS(labelcolor), 0,
MSG_CLABEL_FLAG_MASK, 0);
+ summary_set_row_marks(summaryview, row);
}
void summary_set_colorlabel(SummaryView *summaryview, guint labelcolor,
{
GtkCTree *ctree = GTK_CTREE(summaryview->ctree);
GList *cur;
+ gboolean froze = FALSE;
START_LONG_OPERATION(summaryview);
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
for ( ; sel != NULL; sel = sel->next)
msginfo_list =
- g_slist_append(msginfo_list,
+ g_slist_prepend(msginfo_list,
gtk_ctree_node_get_row_data(GTK_CTREE(summaryview->ctree),
GTK_CTREE_NODE(sel->data)));
- return msginfo_list;
+ return g_slist_reverse(msginfo_list);
}
static void summary_reply_cb(SummaryView *summaryview, guint action,
node = GTK_CTREE_NODE(GTK_CLIST(summaryview->ctree)->row_list);
+ gtk_clist_freeze(GTK_CLIST(summaryview->ctree));
if (prefs_common.bold_unread) {
while (node) {
GtkCTreeNode *next = GTK_CTREE_NODE_NEXT(node);
node = next;
}
}
+ gtk_clist_thaw(GTK_CLIST(summaryview->ctree));
END_TIMING();
}
{ \
MsgInfo *msginfo1 = ((GtkCListRow *)ptr1)->data; \
MsgInfo *msginfo2 = ((GtkCListRow *)ptr2)->data; \
- \
if (!msginfo1 || !msginfo2) \
return -1; \
\
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;
{
GtkCTree *ctree = GTK_CTREE(summaryview->ctree);
GList *cur;
+ gboolean froze = FALSE;
START_LONG_OPERATION(summaryview);
for (cur = GTK_CLIST(ctree)->selection; cur != NULL && cur->data != NULL; cur = cur->next)
{
GtkCTree *ctree = GTK_CTREE(summaryview->ctree);
GList *cur;
+ gboolean froze = FALSE;
START_LONG_OPERATION(summaryview);
for (cur = GTK_CLIST(ctree)->selection; cur != NULL && cur->data != NULL; cur = cur->next)
stock_pixmap_gdk(ctree, STOCK_PIXMAP_GPG_SIGNED, &gpgsignedxpm, &gpgsignedxpmmask);
stock_pixmap_gdk(ctree, STOCK_PIXMAP_CLIP_GPG_SIGNED, &clipgpgsignedxpm, &clipgpgsignedxpmmask);
stock_pixmap_gdk(ctree, STOCK_PIXMAP_SPAM, &spamxpm, &spamxpmmask);
+ stock_pixmap_gdk(ctree, STOCK_PIXMAP_MOVED, &movedxpm, &movedxpmmask);
+ stock_pixmap_gdk(ctree, STOCK_PIXMAP_COPIED, &copiedxpm, &copiedxpmmask);
pixmap = stock_pixmap_widget(summaryview->hbox, STOCK_PIXMAP_DIR_OPEN);
gtk_box_pack_start(GTK_BOX(summaryview->hbox), pixmap, FALSE, FALSE, 4);
g_return_val_if_fail(msginfo_update != NULL, TRUE);
g_return_val_if_fail(summaryview != NULL, FALSE);
+ if (msginfo_update->msginfo->folder != summaryview->folder_item)
+ return FALSE;
+
if (msginfo_update->flags & MSGINFO_UPDATE_FLAGS) {
node = gtk_ctree_find_by_row_data(
GTK_CTREE(summaryview->ctree), NULL,