#include "prefs_filtering.h"
#include "account.h"
#include "compose.h"
+#include "file-utils.h"
#include "utils.h"
#include "gtkutils.h"
#include "stock_pixmap.h"
static void summary_status_show (SummaryView *summaryview);
static void summary_set_column_titles (SummaryView *summaryview);
static void summary_set_ctree_from_list (SummaryView *summaryview,
- GSList *mlist);
+ GSList *mlist,
+ guint selected_msgnum);
static inline void summary_set_header (SummaryView *summaryview,
gchar *text[],
MsgInfo *msginfo);
GtkCMCTreeNode *row);
static void summary_mark_row_as_unread (SummaryView *summaryview,
GtkCMCTreeNode *row);
+static gboolean summary_mark_all_read_confirm(gboolean ask_if_needed);
+static gboolean summary_mark_all_unread_confirm(gboolean ask_if_needed);
static void summary_delete_row (SummaryView *summaryview,
GtkCMCTreeNode *row);
static void summary_unmark_row (SummaryView *summaryview,
void summary_simplify_subject(SummaryView *summaryview, gchar * rexp,
GSList * mlist);
-static void summary_filter_func (MsgInfo *msginfo);
+static void summary_filter_func (MsgInfo *msginfo,
+ PrefsAccount *ac_prefs);
static void summary_colorlabel_menu_item_activate_cb
(GtkWidget *widget,
static void summary_drag_end(GtkWidget *widget,
GdkDragContext *drag_context,
SummaryView *summaryview);
-/* custom compare functions for sorting */
+/* custom compare functions for sorting */
static gint summary_cmp_by_mark (GtkCMCList *clist,
gconstpointer ptr1,
gconstpointer ptr2);
{"claws-mail/msg-path-list", 0, TARGET_MAIL_CM_PATH_LIST},
};
-#define DO_ACTION(name, act) { \
- if(!strcmp(name, a_name)) { \
- act; \
- } \
-}
+static void summary_reedit_cb(GtkAction *gaction, gpointer data);
+static void summary_reply_cb(GtkAction *gaction, gpointer data);
+/* Only submenus and specifically-handled menu entries here */
static GtkActionEntry summary_popup_entries[] =
{
- {"SummaryViewPopup", NULL, "SummaryViewPopup" },
- {"SummaryViewPopup/ReplyTo", NULL, N_("Repl_y to") },
- {"SummaryViewPopup/Mark", NULL, N_("_Mark") },
- {"SummaryViewPopup/ColorLabel", NULL, N_("Color la_bel") },
- {"SummaryViewPopup/Tags", NULL, N_("Ta_gs") },
- {"SummaryViewPopup/CreateFilterRule", NULL, N_("Create _filter rule") },
+ {"SummaryViewPopup", NULL, "SummaryViewPopup", NULL, NULL, NULL },
+ {"SummaryViewPopup/Reedit", NULL, N_("Re-edit"), NULL, NULL, G_CALLBACK(summary_reedit_cb) },
+ {"SummaryViewPopup/Reply", NULL, N_("_Reply"), NULL, NULL, G_CALLBACK(summary_reply_cb) }, /* COMPOSE_REPLY */
+ {"SummaryViewPopup/ReplyTo", NULL, N_("Repl_y to"), NULL, NULL, NULL },
+ {"SummaryViewPopup/ReplyTo/All", NULL, N_("_All"), NULL, NULL, G_CALLBACK(summary_reply_cb) }, /* COMPOSE_REPLY_TO_ALL */
+ {"SummaryViewPopup/ReplyTo/Sender", NULL, N_("_Sender"), NULL, NULL, G_CALLBACK(summary_reply_cb) }, /* COMPOSE_REPLY_TO_SENDER */
+ {"SummaryViewPopup/ReplyTo/List", NULL, N_("Mailing _list"), NULL, NULL, G_CALLBACK(summary_reply_cb) }, /* COMPOSE_REPLY_TO_LIST */
+
+ {"SummaryViewPopup/Forward", NULL, N_("_Forward"), NULL, NULL, G_CALLBACK(summary_reply_cb) }, /* COMPOSE_FORWARD_INLINE */
+ {"SummaryViewPopup/ForwardAtt", NULL, N_("For_ward as attachment"), NULL, NULL, G_CALLBACK(summary_reply_cb) }, /* COMPOSE_FORWARD_AS_ATTACH */
+ {"SummaryViewPopup/Redirect", NULL, N_("Redirec_t"), NULL, NULL, G_CALLBACK(summary_reply_cb) }, /* COMPOSE_REDIRECT */
+ {"SummaryViewPopup/Mark", NULL, N_("_Mark"), NULL, NULL, NULL },
+ {"SummaryViewPopup/ColorLabel", NULL, N_("Color la_bel"), NULL, NULL, NULL },
+ {"SummaryViewPopup/Tags", NULL, N_("Ta_gs"), NULL, NULL, NULL },
+ {"SummaryViewPopup/CreateFilterRule", NULL, N_("Create _filter rule"), NULL, NULL, NULL },
#ifndef GENERIC_UMPC
- {"SummaryViewPopup/CreateProcessingRule", NULL, N_("Create processing rule") },
+ {"SummaryViewPopup/CreateProcessingRule", NULL, N_("Create processing rule"), NULL, NULL, NULL },
#endif
- {"SummaryViewPopup/View", NULL, N_("_View") },
+ {"SummaryViewPopup/View", NULL, N_("_View"), NULL, NULL, NULL },
+};
+
+static void summary_header_lock_sorting_cb(GtkAction *gaction, gpointer data);
+static void summary_header_set_displayed_columns_cb(GtkAction *gaction, gpointer data);
+
+static GtkActionEntry summary_header_popup_entries[] =
+{
+ {"SummaryViewHeaderPopup", NULL, "SummaryViewHeaderPopup", NULL, NULL, NULL },
+ {"SummaryViewHeaderPopup/SetDisplayedColumns", NULL, N_("_Set displayed columns"), NULL, NULL, G_CALLBACK(summary_header_set_displayed_columns_cb) }
+};
+
+static GtkToggleActionEntry summary_header_popup_toggle_entries[] =
+{
+ {"SummaryViewHeaderPopup/LockColumnHeaders", NULL, N_("_Lock column headers"), NULL, NULL, G_CALLBACK(summary_header_lock_sorting_cb), FALSE }
};
static const gchar *const col_label[N_SUMMARY_COLS] = {
- "", /* S_COL_MARK */
- N_("S"), /* S_COL_STATUS */
- "", /* S_COL_MIME */
- N_("Subject"), /* S_COL_SUBJECT */
- N_("From"), /* S_COL_FROM */
- N_("To"), /* S_COL_TO */
- N_("Date"), /* S_COL_DATE */
- N_("Size"), /* S_COL_SIZE */
- N_("#"), /* S_COL_NUMBER */
- N_("Score"), /* S_COL_SCORE */
- "", /* S_COL_LOCKED */
- N_("Tags"), /* S_COL_TAGS */
+ "", /* S_COL_MARK */
+ N_("S"), /* S_COL_STATUS */
+ "", /* S_COL_MIME */
+ N_("Subject"), /* S_COL_SUBJECT */
+ N_("From"), /* S_COL_FROM */
+ N_("To"), /* S_COL_TO */
+ N_("Date"), /* S_COL_DATE */
+ N_("Size"), /* S_COL_SIZE */
+ N_("#"), /* S_COL_NUMBER */
+ N_("Score"), /* S_COL_SCORE */
+ "", /* S_COL_LOCKED */
+ N_("Tags"), /* S_COL_TAGS */
};
void summary_freeze(SummaryView *summaryview)
summary_update_msg, (gpointer) summaryview); \
}
+static void popup_menu_selection_done(GtkMenuShell *shell, gpointer user_data)
+{
+ SummaryView *summaryview = (SummaryView *)user_data;
+
+ cm_return_if_fail(summaryview != NULL);
+
+ /* If a message is displayed, place cursor back on the message. */
+ if (summaryview->displayed != NULL &&
+ summaryview->displayed != summaryview->selected) {
+ gtk_sctree_select(GTK_SCTREE(summaryview->ctree), summaryview->displayed);
+ }
+}
+
SummaryView *summary_create(MainWindow *mainwin)
{
SummaryView *summaryview;
toggle_search = gtk_toggle_button_new();
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(toggle_search),
prefs_common.show_searchbar);
- gtkut_widget_set_can_focus(toggle_search, FALSE);
+ gtk_widget_set_can_focus(toggle_search, FALSE);
gtk_widget_show(toggle_search);
CLAWS_SET_TIP(toggle_search, _("Toggle quick search bar"));
/* create popup menu */
- gtk_action_group_add_actions(mainwin->action_group, summary_popup_entries,
+ gtk_action_group_add_actions(mainwin->action_group,
+ summary_popup_entries,
+ G_N_ELEMENTS(summary_popup_entries),
+ (gpointer)summaryview);
+
+ gtk_action_group_add_actions(mainwin->action_group,
+ summary_header_popup_entries,
+ G_N_ELEMENTS(summary_header_popup_entries),
+ (gpointer)summaryview);
+
+ gtk_action_group_add_toggle_actions(mainwin->action_group,
+ summary_header_popup_toggle_entries,
+ G_N_ELEMENTS(summary_header_popup_toggle_entries),
+ (gpointer)summaryview);
+
+ summaryview->ui_manager = gtk_ui_manager_new();
+ summaryview->action_group = cm_menu_create_action_group_full(summaryview->ui_manager,"Menu", summary_popup_entries,
G_N_ELEMENTS(summary_popup_entries), (gpointer)summaryview);
- MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/", "Menus", "Menus", GTK_UI_MANAGER_MENUBAR)
MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menus", "SummaryViewPopup", "SummaryViewPopup", GTK_UI_MANAGER_MENU)
- MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menus/SummaryViewPopup", "Reply", "Message/Reply", GTK_UI_MANAGER_MENUITEM)
+ MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menus/SummaryViewPopup", "Reedit", "SummaryViewPopup/Reedit", GTK_UI_MANAGER_MENUITEM)
+ MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menus/SummaryViewPopup", "Reply", "SummaryViewPopup/Reply", GTK_UI_MANAGER_MENUITEM)
#ifndef GENERIC_UMPC
MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menus/SummaryViewPopup", "ReplyTo", "SummaryViewPopup/ReplyTo", GTK_UI_MANAGER_MENU)
MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menus/SummaryViewPopup", "Separator1", "Message/---", GTK_UI_MANAGER_SEPARATOR)
#endif
- MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menus/SummaryViewPopup", "Forward", "Message/Forward", GTK_UI_MANAGER_MENUITEM)
+ MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menus/SummaryViewPopup", "Forward", "SummaryViewPopup/Forward", GTK_UI_MANAGER_MENUITEM)
#ifndef GENERIC_UMPC
- MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menus/SummaryViewPopup", "ForwardAtt", "Message/ForwardAtt", GTK_UI_MANAGER_MENUITEM)
- MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menus/SummaryViewPopup", "Redirect", "Message/Redirect", GTK_UI_MANAGER_MENUITEM)
+ MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menus/SummaryViewPopup", "ForwardAtt", "SummaryViewPopup/ForwardAtt", GTK_UI_MANAGER_MENUITEM)
+ MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menus/SummaryViewPopup", "Redirect", "SummaryViewPopup/Redirect", GTK_UI_MANAGER_MENUITEM)
#endif
MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menus/SummaryViewPopup", "Separator2", "Message/---", GTK_UI_MANAGER_SEPARATOR)
MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menus/SummaryViewPopup", "Move", "Message/Move", GTK_UI_MANAGER_MENUITEM)
MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menus/SummaryViewPopup", "Separator6", "File/---", GTK_UI_MANAGER_SEPARATOR)
/* submenus - replyto */
- MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menus/SummaryViewPopup/ReplyTo", "All", "Message/ReplyTo/All", GTK_UI_MANAGER_MENUITEM)
- MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menus/SummaryViewPopup/ReplyTo", "Sender", "Message/ReplyTo/Sender", GTK_UI_MANAGER_MENUITEM)
- MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menus/SummaryViewPopup/ReplyTo", "MailingList", "Message/ReplyTo/List", GTK_UI_MANAGER_MENUITEM)
+ MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menus/SummaryViewPopup/ReplyTo", "All", "SummaryViewPopup/ReplyTo/All", GTK_UI_MANAGER_MENUITEM)
+ MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menus/SummaryViewPopup/ReplyTo", "Sender", "SummaryViewPopup/ReplyTo/Sender", GTK_UI_MANAGER_MENUITEM)
+ MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menus/SummaryViewPopup/ReplyTo", "MailingList", "SummaryViewPopup/ReplyTo/List", GTK_UI_MANAGER_MENUITEM)
/* submenus - mark */
MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menus/SummaryViewPopup/Mark", "Mark", "Message/Mark/Mark", GTK_UI_MANAGER_MENUITEM)
MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menus/SummaryViewPopup/Mark", "Unmark", "Message/Mark/Unmark", GTK_UI_MANAGER_MENUITEM)
MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menus/SummaryViewPopup/Mark", "Separator1", "Message/Mark/---", GTK_UI_MANAGER_SEPARATOR)
- MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menus/SummaryViewPopup/Mark", "MarkUnread", "Message/Mark/MarkUnread", GTK_UI_MANAGER_MENUITEM)
MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menus/SummaryViewPopup/Mark", "MarkRead", "Message/Mark/MarkRead", GTK_UI_MANAGER_MENUITEM)
+ MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menus/SummaryViewPopup/Mark", "MarkUnread", "Message/Mark/MarkUnread", GTK_UI_MANAGER_MENUITEM)
MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menus/SummaryViewPopup/Mark", "Separator2", "Message/Mark/---", GTK_UI_MANAGER_SEPARATOR)
MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menus/SummaryViewPopup/Mark", "MarkAllRead", "Message/Mark/MarkAllRead", GTK_UI_MANAGER_MENUITEM)
+ MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menus/SummaryViewPopup/Mark", "MarkAllUnread", "Message/Mark/MarkAllUnread", GTK_UI_MANAGER_MENUITEM)
MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menus/SummaryViewPopup/Mark", "Separator3", "Message/Mark/---", GTK_UI_MANAGER_SEPARATOR)
MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menus/SummaryViewPopup/Mark", "IgnoreThread", "Message/Mark/IgnoreThread", GTK_UI_MANAGER_MENUITEM)
MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menus/SummaryViewPopup/Mark", "UnignoreThread", "Message/Mark/UnignoreThread", GTK_UI_MANAGER_MENUITEM)
#ifndef GENERIC_UMPC
MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menus/SummaryViewPopup/View", "AllHeaders", "View/AllHeaders", GTK_UI_MANAGER_MENUITEM)
#endif
+
+ MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menus", "SummaryViewHeaderPopup", "SummaryViewHeaderPopup", GTK_UI_MANAGER_MENU)
+ MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menus/SummaryViewHeaderPopup", "LockColumnHeaders", "SummaryViewHeaderPopup/LockColumnHeaders", GTK_UI_MANAGER_MENUITEM)
+ MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menus/SummaryViewHeaderPopup", "SetDisplayedColumns", "SummaryViewHeaderPopup/SetDisplayedColumns", GTK_UI_MANAGER_MENUITEM)
+
summaryview->popupmenu = gtk_menu_item_get_submenu(GTK_MENU_ITEM(
gtk_ui_manager_get_widget(mainwin->ui_manager, "/Menus/SummaryViewPopup")) );
-
+ summaryview->headerpopupmenu = gtk_menu_item_get_submenu(GTK_MENU_ITEM(
+ gtk_ui_manager_get_widget(mainwin->ui_manager, "/Menus/SummaryViewHeaderPopup")) );
summaryview->vbox = vbox;
summaryview->scrolledwin = scrolledwin;
}
}
bold_marked_style = gtk_style_copy(bold_style);
- bold_marked_style->fg[GTK_STATE_NORMAL] =
+ bold_marked_style->text[GTK_STATE_NORMAL] =
summaryview->color_marked;
bold_deleted_style = gtk_style_copy(bold_style);
- bold_deleted_style->fg[GTK_STATE_NORMAL] =
+ bold_deleted_style->text[GTK_STATE_NORMAL] =
summaryview->color_dim;
}
main_create_mailing_list_menu (summaryview->mainwin, NULL);
summary_set_menu_sensitive(summaryview);
+ summaryview->header_menu_lock = FALSE;
}
#define CURRENTLY_DISPLAYED(m) \
|| summaryview->folder_item == NULL) {
return;
}
-
+ START_TIMING("");
main_window_cursor_wait(summaryview->mainwin);
summaryview_reset_recursive_folder_match(summaryview);
summaryview_quicksearch_search_subfolders(summaryview, summaryview->folder_item);
main_window_cursor_normal(summaryview->mainwin);
+ END_TIMING();
}
static gboolean summary_check_consistency(FolderItem *item, GSList *mlist)
val = alertpanel(_("Process mark"),
_("Some marks are left. Process them?"),
- GTK_STOCK_NO, GTK_STOCK_YES, GTK_STOCK_CANCEL);
+ GTK_STOCK_NO, GTK_STOCK_YES, GTK_STOCK_CANCEL, ALERTFOCUS_FIRST);
if (G_ALERTALTERNATE == val) {
summary_unlock(summaryview);
summary_execute(summaryview);
/* set ctree and hash table from the msginfo list, and
create the thread */
- summary_set_ctree_from_list(summaryview, mlist);
+ summary_set_ctree_from_list(summaryview, mlist, selected_msgnum);
g_slist_free(mlist);
- if (is_refresh) {
- if (!quicksearch_is_in_typing(summaryview->quicksearch)) {
- summaryview->displayed =
- summary_find_msg_by_msgnum(summaryview,
- displayed_msgnum);
- if (!summaryview->displayed)
- messageview_clear(summaryview->messageview);
- summary_unlock(summaryview);
- summary_select_by_msgnum(summaryview, selected_msgnum);
- summary_lock(summaryview);
- if (!summaryview->selected) {
- /* no selected message - select first unread
- message, but do not display it */
- node = summary_find_next_flagged_msg(summaryview, NULL,
- MSG_UNREAD, FALSE);
- if (node == NULL && GTK_CMCLIST(ctree)->row_list != NULL)
- node = gtk_cmctree_node_nth
- (ctree,
- item->sort_type == SORT_DESCENDING
- ? 0 : GTK_CMCLIST(ctree)->rows - 1);
- summary_unlock(summaryview);
- summary_select_node(summaryview, node, 0);
- summary_lock(summaryview);
- }
- } else {
- /* just select first/last */
- if (GTK_CMCLIST(ctree)->row_list != NULL)
+ if (quicksearch_is_in_typing(summaryview->quicksearch) ||
+ quicksearch_is_running(summaryview->quicksearch)) {
+ summaryview->displayed =
+ summary_find_msg_by_msgnum(summaryview,
+ displayed_msgnum);
+ if (!summaryview->displayed)
+ messageview_clear(summaryview->messageview);
+ summary_unlock(summaryview);
+
+ if (quicksearch_is_running(summaryview->quicksearch))
+ summary_select_by_msgnum(summaryview, selected_msgnum,
+ OPEN_SELECTED_ON_SEARCH_RESULTS);
+ else
+ summary_select_by_msgnum(summaryview, selected_msgnum,
+ FALSE);
+
+ summary_lock(summaryview);
+ if (!summaryview->selected) {
+ /* no selected message - select first unread
+ message, but do not display it */
+ node = summary_find_next_flagged_msg(summaryview, NULL,
+ MSG_UNREAD, FALSE);
+ if (node == NULL && GTK_CMCLIST(ctree)->row_list != NULL)
node = gtk_cmctree_node_nth
(ctree,
item->sort_type == SORT_DESCENDING
? 0 : GTK_CMCLIST(ctree)->rows - 1);
- gtk_sctree_select(GTK_SCTREE(ctree), node);
- summaryview->selected = node;
- gtk_cmctree_node_moveto(ctree, node, 0, 0.5, 0);
+ summary_unlock(summaryview);
+
+ if (quicksearch_is_running(summaryview->quicksearch))
+ summary_select_node(summaryview, node,
+ OPEN_SELECTED_ON_SEARCH_RESULTS);
+ else
+ summary_select_node(summaryview, node,
+ OPEN_SELECTED_ON_FOLDER_OPEN);
+
+ summary_lock(summaryview);
}
} else {
/* backward compat */
EntryAction act = prefs_common.summary_select_prio[i];
switch(act) {
- case ACTION_MARKED:
- node = summary_find_next_flagged_msg(summaryview, NULL,
+ case ACTION_OLDEST_MARKED:
+ if (summaryview->sort_type == SORT_ASCENDING)
+ node = summary_find_next_flagged_msg(summaryview, NULL,
+ MSG_MARKED, FALSE);
+ else
+ node = summary_find_prev_flagged_msg(summaryview, NULL,
MSG_MARKED, FALSE);
break;
- case ACTION_NEW:
- node = summary_find_next_flagged_msg(summaryview, NULL,
+ case ACTION_NEWEST_MARKED:
+ if (summaryview->sort_type == SORT_ASCENDING)
+ node = summary_find_prev_flagged_msg(summaryview, NULL,
+ MSG_MARKED, FALSE);
+ else
+ node = summary_find_next_flagged_msg(summaryview, NULL,
+ MSG_MARKED, FALSE);
+ break;
+ case ACTION_OLDEST_NEW:
+ if (summaryview->sort_type == SORT_ASCENDING)
+ node = summary_find_next_flagged_msg(summaryview, NULL,
+ MSG_NEW, FALSE);
+ else
+ node = summary_find_prev_flagged_msg(summaryview, NULL,
MSG_NEW, FALSE);
break;
- case ACTION_UNREAD:
- node = summary_find_next_flagged_msg(summaryview, NULL,
+ case ACTION_NEWEST_NEW:
+ if (summaryview->sort_type == SORT_ASCENDING)
+ node = summary_find_prev_flagged_msg(summaryview, NULL,
+ MSG_NEW, FALSE);
+ else
+ node = summary_find_next_flagged_msg(summaryview, NULL,
+ MSG_NEW, FALSE);
+ break;
+ case ACTION_OLDEST_UNREAD:
+ if (summaryview->sort_type == SORT_ASCENDING)
+ node = summary_find_next_flagged_msg(summaryview, NULL,
+ MSG_UNREAD, FALSE);
+ else
+ node = summary_find_prev_flagged_msg(summaryview, NULL,
+ MSG_UNREAD, FALSE);
+ break;
+ case ACTION_NEWEST_UNREAD:
+ if (summaryview->sort_type == SORT_ASCENDING)
+ node = summary_find_prev_flagged_msg(summaryview, NULL,
+ MSG_UNREAD, FALSE);
+ else
+ node = summary_find_next_flagged_msg(summaryview, NULL,
MSG_UNREAD, FALSE);
break;
case ACTION_LAST_OPENED:
summaryview->folder_item->last_seen);
}
break;
- case ACTION_LAST_LIST:
+ case ACTION_NEWEST_LIST:
if (GTK_CMCLIST(ctree)->row_list != NULL) {
node = gtk_cmctree_node_nth
(ctree,
? 0 : GTK_CMCLIST(ctree)->rows - 1);
}
break;
- case ACTION_FIRST_LIST:
+ case ACTION_OLDEST_LIST:
if (GTK_CMCLIST(ctree)->row_list != NULL) {
node = gtk_cmctree_node_nth
(ctree,
if (node) {
gint open_selected = -1;
- if (!is_refresh) {
- if (prefs_common.open_selected_on_folder_open)
- open_selected = 1;
- else
- open_selected = 0;
- }
+ if (OPEN_SELECTED_ON_FOLDER_OPEN)
+ open_selected = 1;
+ else
+ open_selected = 0;
summary_select_node(summaryview, node, open_selected);
}
for (cur = GTK_CMCLIST(summaryview->ctree)->selection; cur != NULL && cur->data != NULL;
cur = cur->next) {
msginfo = GTKUT_CTREE_NODE_GET_ROW_DATA(cur->data);
- mlist = g_slist_prepend(mlist, msginfo);
+ mlist = g_slist_prepend(mlist,
+ procmsg_msginfo_new_ref(msginfo));
}
mlist = g_slist_reverse(mlist);
gboolean sensitive;
gint i;
-#define N_ENTRIES 38
+#ifndef GENERIC_UMPC
+#define N_ENTRIES 40
+#else
+#define N_ENTRIES 29
+#endif
static struct {
const gchar *entry;
SensitiveCondMask cond;
entry[i].entry = (const gchar *) entry_str; entry[i++].cond = main_window_get_mask(__VA_ARGS__, -1); \
} while (0)
+ FILL_TABLE("Menus/SummaryViewPopup/Reedit", M_TARGET_EXIST, M_DRAFT);
FILL_TABLE("Menus/SummaryViewPopup/Reply", M_HAVE_ACCOUNT, M_TARGET_EXIST);
#ifndef GENERIC_UMPC
FILL_TABLE("Menus/SummaryViewPopup/ReplyTo", M_HAVE_ACCOUNT, M_TARGET_EXIST);
FILL_TABLE("Menus/SummaryViewPopup/Mark", M_TARGET_EXIST);
FILL_TABLE("Menus/SummaryViewPopup/Mark/Mark", M_TARGET_EXIST);
FILL_TABLE("Menus/SummaryViewPopup/Mark/Unmark", M_TARGET_EXIST);
- FILL_TABLE("Menus/SummaryViewPopup/Mark/MarkUnread", M_TARGET_EXIST);
FILL_TABLE("Menus/SummaryViewPopup/Mark/MarkRead", M_TARGET_EXIST);
+ FILL_TABLE("Menus/SummaryViewPopup/Mark/MarkUnread", M_TARGET_EXIST);
FILL_TABLE("Menus/SummaryViewPopup/Mark/MarkAllRead", M_TARGET_EXIST);
+ FILL_TABLE("Menus/SummaryViewPopup/Mark/MarkAllUnread", M_TARGET_EXIST);
FILL_TABLE("Menus/SummaryViewPopup/Mark/IgnoreThread", M_TARGET_EXIST);
FILL_TABLE("Menus/SummaryViewPopup/Mark/UnignoreThread", M_TARGET_EXIST);
FILL_TABLE("Menus/SummaryViewPopup/Mark/WatchThread", M_TARGET_EXIST);
FILL_TABLE("Menus/SummaryViewPopup/Mark/UnwatchThread", M_TARGET_EXIST);
- FILL_TABLE("Menus/SummaryViewPopup/Mark/Unlock", M_TARGET_EXIST);
FILL_TABLE("Menus/SummaryViewPopup/Mark/Lock", M_TARGET_EXIST);
+ FILL_TABLE("Menus/SummaryViewPopup/Mark/Unlock", M_TARGET_EXIST);
FILL_TABLE("Menus/SummaryViewPopup/Mark/MarkSpam", M_TARGET_EXIST, M_CAN_LEARN_SPAM);
FILL_TABLE("Menus/SummaryViewPopup/Mark/MarkHam", M_TARGET_EXIST, M_CAN_LEARN_SPAM);
FILL_TABLE("Menus/SummaryViewPopup/ColorLabel", M_TARGET_EXIST);
GtkCMCTreeNode *node = summaryview->selected;
GtkCMCTree *ctree = GTK_CMCTREE(summaryview->ctree);
- node = gtkut_ctree_node_prev(ctree, node);
+ if (summaryview->sort_type == SORT_ASCENDING)
+ node = gtkut_ctree_node_prev(ctree, node);
+ else
+ node = gtkut_ctree_node_next(ctree, node);
if (node && node != summaryview->selected)
- summary_select_node(summaryview, node, -1);
+ summary_select_node(summaryview, node, OPEN_SELECTED_ON_PREVNEXT);
}
void summary_select_next(SummaryView *summaryview)
GtkCMCTreeNode *node = summaryview->selected;
GtkCMCTree *ctree = GTK_CMCTREE(summaryview->ctree);
- node = gtkut_ctree_node_next(ctree, node);
+ if (summaryview->sort_type == SORT_ASCENDING)
+ node = gtkut_ctree_node_next(ctree, node);
+ else
+ node = gtkut_ctree_node_prev(ctree, node);
if (node && node != summaryview->selected)
- summary_select_node(summaryview, node, -1);
+ summary_select_node(summaryview, node, OPEN_SELECTED_ON_PREVNEXT);
}
void summary_select_prev_unread(SummaryView *summaryview)
{
GtkCMCTreeNode *node;
- gboolean skip_cur = FALSE;
-
- if (summaryview->displayed
- && summaryview->selected == summaryview->displayed) {
- debug_print("skipping current\n");
- skip_cur = TRUE;
- }
- node = summary_find_prev_flagged_msg
- (summaryview, summaryview->selected, MSG_UNREAD, skip_cur);
+ if (summaryview->sort_type == SORT_ASCENDING)
+ node = summary_find_prev_flagged_msg
+ (summaryview, summaryview->selected, MSG_UNREAD, TRUE);
+ else
+ node = summary_find_next_flagged_msg
+ (summaryview, summaryview->selected, MSG_UNREAD, TRUE);
if (!node || node == summaryview->selected) {
AlertValue val = 0;
val = alertpanel(_("No more unread messages"),
_("No unread message found. "
"Search from the end?"),
- GTK_STOCK_NO, "+"GTK_STOCK_YES, NULL);
+ GTK_STOCK_NO, GTK_STOCK_YES, NULL, ALERTFOCUS_SECOND);
break;
case NEXTUNREADMSGDIALOG_ASSUME_YES:
val = G_ALERTALTERNATE;
_("Internal error: unexpected value for prefs_common.next_unread_msg_dialog\n"));
}
if (val != G_ALERTALTERNATE) return;
- node = summary_find_prev_flagged_msg(summaryview, NULL,
- MSG_UNREAD, FALSE);
+ if (summaryview->sort_type == SORT_ASCENDING)
+ node = summary_find_prev_flagged_msg(summaryview, NULL,
+ MSG_UNREAD, FALSE);
+ else
+ node = summary_find_next_flagged_msg(summaryview, NULL,
+ MSG_UNREAD, FALSE);
}
if (!node)
alertpanel_notice(_("No unread messages."));
else
- summary_select_node(summaryview, node, -1);
+ summary_select_node(summaryview, node, OPEN_SELECTED_ON_PREVNEXT);
}
void summary_select_next_unread(SummaryView *summaryview)
{
GtkCMCTreeNode *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, node, MSG_UNREAD, skip_cur);
+ if (summaryview->sort_type == SORT_ASCENDING)
+ node = summary_find_next_flagged_msg
+ (summaryview, node, MSG_UNREAD, TRUE);
+ else
+ node = summary_find_prev_flagged_msg
+ (summaryview, node, MSG_UNREAD, TRUE);
if (node)
- summary_select_node(summaryview, node, -1);
+ summary_select_node(summaryview, node, OPEN_SELECTED_ON_PREVNEXT);
else {
- node = summary_find_next_flagged_msg
- (summaryview, NULL, MSG_UNREAD, FALSE);
- if (node == NULL || node == summaryview->selected) {
- AlertValue val = 0;
-
- switch (prefs_common.next_unread_msg_dialog) {
- case NEXTUNREADMSGDIALOG_ALWAYS:
- val = alertpanel(_("No more unread messages"),
- _("No unread 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"));
- }
-
- if (val == G_ALERTALTERNATE)
- folderview_select_next_with_flag(summaryview->folderview, MSG_UNREAD);
- } else {
- summary_select_node(summaryview, node, -1);
- }
+ AlertValue val = 0;
+
+ switch (prefs_common.next_unread_msg_dialog) {
+ case NEXTUNREADMSGDIALOG_ALWAYS:
+ val = alertpanel(_("No more unread messages"),
+ _("No unread message found. "
+ "Go to next folder?"),
+ GTK_STOCK_NO, GTK_STOCK_YES, NULL, ALERTFOCUS_SECOND);
+ 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"));
+ }
+
+ if (val == G_ALERTALTERNATE)
+ folderview_select_next_with_flag(summaryview->folderview, MSG_UNREAD);
}
}
void summary_select_prev_new(SummaryView *summaryview)
{
GtkCMCTreeNode *node;
- gboolean skip_cur = FALSE;
- if (summaryview->displayed
- && summaryview->selected == summaryview->displayed) {
- debug_print("skipping current\n");
- skip_cur = TRUE;
- }
-
- node = summary_find_prev_flagged_msg
- (summaryview, summaryview->selected, MSG_NEW, skip_cur);
+ if (summaryview->sort_type == SORT_ASCENDING)
+ node = summary_find_prev_flagged_msg
+ (summaryview, summaryview->selected, MSG_NEW, TRUE);
+ else
+ node = summary_find_next_flagged_msg
+ (summaryview, summaryview->selected, MSG_NEW, TRUE);
if (!node || node == summaryview->selected) {
AlertValue val = 0;
val = alertpanel(_("No more new messages"),
_("No new message found. "
"Search from the end?"),
- GTK_STOCK_NO, "+"GTK_STOCK_YES, NULL);
+ GTK_STOCK_NO, GTK_STOCK_YES, NULL, ALERTFOCUS_SECOND);
break;
case NEXTUNREADMSGDIALOG_ASSUME_YES:
val = G_ALERTALTERNATE;
_("Internal error: unexpected value for prefs_common.next_unread_msg_dialog\n"));
}
if (val != G_ALERTALTERNATE) return;
- node = summary_find_prev_flagged_msg(summaryview, NULL,
- MSG_NEW, FALSE);
+ if (summaryview->sort_type == SORT_ASCENDING)
+ node = summary_find_prev_flagged_msg(summaryview, NULL,
+ MSG_NEW, FALSE);
+ else
+ node = summary_find_next_flagged_msg(summaryview, NULL,
+ MSG_NEW, FALSE);
}
if (!node)
alertpanel_notice(_("No new messages."));
else
- summary_select_node(summaryview, node, -1);
+ summary_select_node(summaryview, node, OPEN_SELECTED_ON_PREVNEXT);
}
void summary_select_next_new(SummaryView *summaryview)
{
GtkCMCTreeNode *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, node, MSG_NEW, skip_cur);
+ if (summaryview->sort_type == SORT_ASCENDING)
+ node = summary_find_next_flagged_msg
+ (summaryview, node, MSG_NEW, TRUE);
+ else
+ node = summary_find_prev_flagged_msg
+ (summaryview, node, MSG_NEW, TRUE);
if (node)
- summary_select_node(summaryview, node, -1);
+ summary_select_node(summaryview, node, OPEN_SELECTED_ON_PREVNEXT);
else {
- node = summary_find_next_flagged_msg
- (summaryview, NULL, MSG_NEW, FALSE);
- if (node == NULL || node == summaryview->selected) {
- AlertValue val = 0;
-
- switch (prefs_common.next_unread_msg_dialog) {
- case NEXTUNREADMSGDIALOG_ALWAYS:
- val = alertpanel(_("No more new messages"),
- _("No new 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"));
- }
-
- if (val == G_ALERTALTERNATE) {
- folderview_select_next_with_flag(summaryview->folderview, MSG_NEW);
- return;
- }
- else
- return;
- } else
- summary_select_node(summaryview, node, -1);
+ AlertValue val = 0;
+ switch (prefs_common.next_unread_msg_dialog) {
+ case NEXTUNREADMSGDIALOG_ALWAYS:
+ val = alertpanel(_("No more new messages"),
+ _("No new message found. "
+ "Go to next folder?"),
+ GTK_STOCK_NO, GTK_STOCK_YES, NULL, ALERTFOCUS_SECOND);
+ 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"));
+ }
+ if (val == G_ALERTALTERNATE)
+ folderview_select_next_with_flag(summaryview->folderview, MSG_NEW);
}
}
{
GtkCMCTreeNode *node;
- node = summary_find_prev_flagged_msg
- (summaryview, summaryview->selected, MSG_MARKED, TRUE);
+ if (summaryview->sort_type == SORT_ASCENDING)
+ node = summary_find_prev_flagged_msg
+ (summaryview, summaryview->selected, MSG_MARKED, TRUE);
+ else
+ node = summary_find_next_flagged_msg
+ (summaryview, summaryview->selected, MSG_MARKED, TRUE);
if (!node) {
AlertValue val;
val = alertpanel(_("No more marked messages"),
_("No marked message found. "
"Search from the end?"),
- GTK_STOCK_NO, "+"GTK_STOCK_YES, NULL);
+ GTK_STOCK_NO, GTK_STOCK_YES, NULL, ALERTFOCUS_SECOND);
if (val != G_ALERTALTERNATE) return;
node = summary_find_prev_flagged_msg(summaryview, NULL,
MSG_MARKED, TRUE);
if (!node)
alertpanel_notice(_("No marked messages."));
else
- summary_select_node(summaryview, node, -1);
+ summary_select_node(summaryview, node, OPEN_SELECTED_ON_PREVNEXT);
}
void summary_select_next_marked(SummaryView *summaryview)
{
GtkCMCTreeNode *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, node, MSG_MARKED, skip_cur);
+ if (summaryview->sort_type == SORT_ASCENDING)
+ node = summary_find_next_flagged_msg
+ (summaryview, node, MSG_MARKED, TRUE);
+ else
+ node = summary_find_prev_flagged_msg
+ (summaryview, node, MSG_MARKED, TRUE);
if (node)
- summary_select_node(summaryview, node, -1);
+ summary_select_node(summaryview, node, OPEN_SELECTED_ON_PREVNEXT);
else {
- node = summary_find_next_flagged_msg
- (summaryview, NULL, MSG_MARKED, FALSE);
- if (node == NULL || node == summaryview->selected) {
- AlertValue val = 0;
-
- 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"));
- }
-
- if (val == G_ALERTALTERNATE) {
- folderview_select_next_with_flag(summaryview->folderview, MSG_MARKED);
- return;
- }
- else
- return;
- } else
- summary_select_node(summaryview, node, -1);
+ AlertValue val = 0;
+ 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, ALERTFOCUS_SECOND);
+ 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"));
+ }
+ if (val == G_ALERTALTERNATE)
+ folderview_select_next_with_flag(summaryview->folderview, MSG_MARKED);
}
}
{
GtkCMCTreeNode *node;
- node = summary_find_prev_flagged_msg
- (summaryview, summaryview->selected, MSG_CLABEL_FLAG_MASK, TRUE);
+ if (summaryview->sort_type == SORT_ASCENDING)
+ node = summary_find_prev_flagged_msg
+ (summaryview, summaryview->selected, MSG_CLABEL_FLAG_MASK, TRUE);
+ else
+ node = summary_find_next_flagged_msg
+ (summaryview, summaryview->selected, MSG_CLABEL_FLAG_MASK, TRUE);
if (!node) {
AlertValue val;
val = alertpanel(_("No more labeled messages"),
_("No labeled message found. "
"Search from the end?"),
- GTK_STOCK_NO, "+"GTK_STOCK_YES, NULL);
+ GTK_STOCK_NO, GTK_STOCK_YES, NULL, ALERTFOCUS_SECOND);
if (val != G_ALERTALTERNATE) return;
node = summary_find_prev_flagged_msg(summaryview, NULL,
MSG_CLABEL_FLAG_MASK, TRUE);
if (!node)
alertpanel_notice(_("No labeled messages."));
else
- summary_select_node(summaryview, node, -1);
+ summary_select_node(summaryview, node, OPEN_SELECTED_ON_PREVNEXT);
}
void summary_select_next_labeled(SummaryView *summaryview)
{
GtkCMCTreeNode *node;
- node = summary_find_next_flagged_msg
- (summaryview, summaryview->selected, MSG_CLABEL_FLAG_MASK, TRUE);
+ if (summaryview->sort_type == SORT_ASCENDING)
+ node = summary_find_next_flagged_msg
+ (summaryview, summaryview->selected, MSG_CLABEL_FLAG_MASK, TRUE);
+ else
+ node = summary_find_prev_flagged_msg
+ (summaryview, summaryview->selected, MSG_CLABEL_FLAG_MASK, TRUE);
if (!node) {
AlertValue val;
val = alertpanel(_("No more labeled messages"),
_("No labeled message found. "
"Search from the beginning?"),
- GTK_STOCK_NO, "+"GTK_STOCK_YES, NULL);
+ GTK_STOCK_NO, GTK_STOCK_YES, NULL, ALERTFOCUS_SECOND);
if (val != G_ALERTALTERNATE) return;
- node = summary_find_next_flagged_msg(summaryview, NULL,
- MSG_CLABEL_FLAG_MASK, TRUE);
+ if (summaryview->sort_type == SORT_ASCENDING)
+ node = summary_find_next_flagged_msg(summaryview, NULL,
+ MSG_CLABEL_FLAG_MASK, TRUE);
+ else
+ node = summary_find_prev_flagged_msg(summaryview, NULL,
+ MSG_CLABEL_FLAG_MASK, TRUE);
}
if (!node)
alertpanel_notice(_("No labeled messages."));
else
- summary_select_node(summaryview, node, -1);
+ summary_select_node(summaryview, node, OPEN_SELECTED_ON_PREVNEXT);
}
void summary_select_parent(SummaryView *summaryview)
if (summaryview->selected)
node = GTK_CMCTREE_ROW(summaryview->selected)->parent;
if (node)
- summary_select_node(summaryview, node, -1);
-}
-
-void summary_select_by_msgnum(SummaryView *summaryview, guint msgnum)
-{
- GtkCMCTreeNode *node;
-
- node = summary_find_msg_by_msgnum(summaryview, msgnum);
- summary_select_node(summaryview, node, 0);
+ summary_select_node(summaryview, node, OPEN_SELECTED_ON_PREVNEXT);
}
-void summary_display_by_msgnum(SummaryView *summaryview, guint msgnum)
+void summary_select_by_msgnum(SummaryView *summaryview, guint msgnum,
+ gboolean show)
{
GtkCMCTreeNode *node;
node = summary_find_msg_by_msgnum(summaryview, msgnum);
- summary_select_node(summaryview, node, 1);
+ summary_select_node(summaryview, node, show);
}
void summary_select_by_msg_list(SummaryView *summaryview, GSList *msginfos)
for(walk = msgnum_list; walk; walk = walk->next) {
GtkCMCTreeNode *node;
node = summary_find_msg_by_msgnum(summaryview, GPOINTER_TO_UINT(walk->data));
- gtk_cmctree_select(ctree, node);
+ if (node != NULL)
+ gtk_cmctree_select(ctree, node);
}
END_LONG_OPERATION(summaryview);
g_slist_free(msgnum_list);
* summary_select_node:
* @summaryview: Summary view.
* @node: Summary tree node.
- * @force_display: -1 unset, 0 don't show the msg, 1 show the msg.
+ * @display_msg: whether to also display the message
*
* Select @node (bringing it into view by scrolling and expanding its
- * thread, if necessary) and unselect all others. If @force_display is
- * 1, display the corresponding message in the message view, if
- * @force_display is -1, obey prefs_common.always_show_msg.
+ * thread, if necessary) and unselect all others.
**/
+
void summary_select_node(SummaryView *summaryview, GtkCMCTreeNode *node,
- gint force_display)
+ gboolean display_msg)
{
GtkCMCTree *ctree = GTK_CMCTREE(summaryview->ctree);
- gboolean display_msg;
-
- display_msg = force_display > -1? force_display :
- (prefs_common.always_show_msg == OPENMSG_YES) ||
- ((prefs_common.always_show_msg == OPENMSG_WHEN_VIEW_VISIBLE &&
- messageview_is_visible(summaryview->messageview)));
+
+ /* If msgview is hidden, we never want to automatically display
+ * a selected message, since that would unhide the msgview. */
+ if (!messageview_is_visible(summaryview->messageview))
+ display_msg = FALSE;
if (summary_is_locked(summaryview)
&& !GTK_SCTREE(ctree)->selecting_range
if (!summaryview->folder_item)
return;
if (node) {
- summary_cancel_mark_read_timeout(summaryview);
gtkut_ctree_expand_parent_all(ctree, node);
summary_lock(summaryview);
GTK_EVENTS_FLUSH();
summary_unlock(summaryview);
- gtk_widget_grab_focus(GTK_WIDGET(ctree));
+
+ /* If quicksearch has focus, let's keep it there. */
+ if (!quicksearch_has_focus(summaryview->quicksearch))
+ summary_grab_focus(summaryview);
+
gtkut_ctree_node_move_if_on_the_edge(ctree, node, -1);
if (display_msg && summaryview->displayed == node)
n_new, n_unread, n_total,
to_human_readable((goffset)n_size));
+ g_signal_connect(G_OBJECT(summaryview->popupmenu), "selection-done",
+ G_CALLBACK(popup_menu_selection_done), summaryview);
gtk_label_set_text(GTK_LABEL(summaryview->statlabel_msgs), str);
g_free(str);
return all_read;
}
+typedef struct _ThreadSelectedData {
+ guint msgnum;
+ gboolean is_selected;
+} ThreadSelectedData;
+
+static gboolean summary_update_is_selected(GNode *gnode, gpointer data)
+{
+ ThreadSelectedData *selected = (ThreadSelectedData *)data;
+ MsgInfo *msginfo = (MsgInfo *)gnode->data;
+
+ if (msginfo->msgnum == selected->msgnum) {
+ selected->is_selected = TRUE;
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static gboolean summary_thread_is_selected(GNode *gnode, guint selected_msgnum)
+{
+ ThreadSelectedData selected;
+
+ selected.msgnum = selected_msgnum;
+ selected.is_selected = FALSE;
+ g_node_traverse(gnode, G_IN_ORDER, G_TRAVERSE_ALL, -1,
+ summary_update_is_selected, &selected);
+ return selected.is_selected;
+}
+
static gboolean summary_insert_gnode_func(GtkCMCTree *ctree, guint depth, GNode *gnode,
GtkCMCTreeNode *cnode, gpointer data)
{
}
static void summary_set_ctree_from_list(SummaryView *summaryview,
- GSList *mlist)
+ GSList *mlist, guint selected_msgnum)
{
GtkCMCTree *ctree = GTK_CMCTREE(summaryview->ctree);
MsgInfo *msginfo;
for (gnode = root->children; gnode != NULL;
gnode = gnode->next) {
- if (!summaryview->folder_item->hide_read_threads ||
- !summary_thread_is_read(gnode))
- {
- summary_find_thread_age(gnode);
- node = gtk_sctree_insert_gnode
- (ctree, NULL, node, gnode,
- summary_insert_gnode_func, summaryview);
- }
+ if (!summaryview->folder_item->hide_read_threads ||
+ !summary_thread_is_read(gnode) ||
+ summary_thread_is_selected(gnode, selected_msgnum)) {
+ summary_find_thread_age(gnode);
+ node = gtk_sctree_insert_gnode
+ (ctree, NULL, node, gnode,
+ summary_insert_gnode_func, summaryview);
+ }
}
g_node_destroy(root);
{
static gchar date_modified[80];
static gchar col_score[11];
- static gchar buf[BUFFSIZE], tmp1[BUFFSIZE], tmp2[BUFFSIZE], tmp3[BUFFSIZE];
+ static gchar from_buf[BUFFSIZE], to_buf[BUFFSIZE];
+ static gchar tmp1[BUFFSIZE], tmp2[BUFFSIZE+4], tmp3[BUFFSIZE];
gint *col_pos = summaryview->col_pos;
gchar *from_text = NULL, *to_text = NULL, *tags_text = NULL;
gboolean should_swap = FALSE;
} else {
gchar *tmp = summary_complete_address(msginfo->from);
if (tmp) {
- strncpy2(buf, tmp, sizeof(buf));
+ strncpy2(from_buf, tmp, sizeof(from_buf));
g_free(tmp);
- from_text = buf;
+ from_text = from_buf;
} else {
if (prefs_common.summary_from_show == SHOW_NAME)
from_text = msginfo->fromname;
to_text = msginfo->to ? msginfo->to :
(msginfo->cc ? msginfo->cc :
- (msginfo->newsgroups ? msginfo->newsgroups : _("(No Recipient)")
+ (msginfo->newsgroups ? msginfo->newsgroups : NULL
)
);
+ if (!to_text)
+ to_text = _("(No Recipient)");
+ else {
+ if (prefs_common.summary_from_show == SHOW_NAME) {
+ gchar *tmp = procheader_get_fromname(to_text);
+ /* need to keep to_text pointing to stack, so heap-allocated
+ * string from procheader_get_fromname() will be copied to to_buf */
+ if (tmp != NULL) {
+ strncpy2(to_buf, tmp, sizeof(to_buf));
+ g_free(tmp);
+ to_text = to_buf;
+ }
+ } else if (prefs_common.summary_from_show == SHOW_ADDR)
+ extract_address(to_text);
+ }
+
text[col_pos[S_COL_TO]] = to_text;
if (!should_swap) {
text[col_pos[S_COL_FROM]] = from_text;
} else {
if (prefs_common.use_addr_book) {
gchar *tmp = summary_complete_address(to_text);
+ /* need to keep to_text pointing to stack, so heap-allocated
+ * string from summary_complete_address() will be copied to to_buf */
if (tmp) {
- strncpy2(buf, tmp, sizeof(buf));
+ strncpy2(to_buf, tmp, sizeof(to_buf));
g_free(tmp);
- to_text = buf;
+ to_text = to_buf;
} else {
to_text = to_text ? to_text : _("(No From)");
}
}
- snprintf(tmp2, BUFFSIZE-1, "➜ %s", to_text);
+ snprintf(tmp2, BUFFSIZE+4, "➜ %s", to_text);
tmp2[BUFFSIZE-1]='\0';
text[col_pos[S_COL_FROM]] = tmp2;
}
}
static gboolean defer_change(gpointer data);
+typedef enum {
+ FLAGS_UNSET,
+ FLAGS_SET,
+ FLAGS_CHANGE
+} ChangeType;
typedef struct _ChangeData {
MsgInfo *info;
- gint op; /* 0, 1, 2 for unset, set, change */
+ ChangeType op;
MsgPermFlags set_flags;
MsgTmpFlags set_tmp_flags;
MsgPermFlags unset_flags;
} else {
ChangeData *unset_data = g_new0(ChangeData, 1);
unset_data->info = msginfo;
- unset_data->op = 0;
+ unset_data->op = FLAGS_UNSET;
unset_data->unset_flags = flags;
unset_data->unset_tmp_flags = tmp_flags;
debug_print("flags: deferring unset\n");
} else {
ChangeData *set_data = g_new0(ChangeData, 1);
set_data->info = msginfo;
- set_data->op = 1;
+ set_data->op = FLAGS_SET;
set_data->set_flags = flags;
set_data->set_tmp_flags = tmp_flags;
debug_print("flags: deferring set\n");
} else {
ChangeData *change_data = g_new0(ChangeData, 1);
change_data->info = msginfo;
- change_data->op = 2;
+ change_data->op = FLAGS_CHANGE;
change_data->set_flags = add_flags;
change_data->set_tmp_flags = add_tmp_flags;
change_data->unset_flags = rem_flags;
} else {
debug_print("flags: finally doing it\n");
switch(chg->op) {
- case 0:
+ case FLAGS_UNSET:
procmsg_msginfo_unset_flags(chg->info, chg->unset_flags, chg->unset_tmp_flags);
break;
- case 1:
+ case FLAGS_SET:
procmsg_msginfo_set_flags(chg->info, chg->set_flags, chg->set_tmp_flags);
break;
- case 2:
+ case FLAGS_CHANGE:
procmsg_msginfo_change_flags(chg->info, chg->set_flags, chg->set_tmp_flags,
chg->unset_flags, chg->unset_tmp_flags);
break;
msginfo->msgnum);
}
+static void summary_mark_row_as_unread(SummaryView *summaryview,
+ GtkCMCTreeNode *row)
+{
+ GtkCMCTree *ctree = GTK_CMCTREE(summaryview->ctree);
+ MsgInfo *msginfo;
+
+ msginfo = gtk_cmctree_node_get_row_data(ctree, row);
+ cm_return_if_fail(msginfo);
+
+ if(MSG_IS_NEW(msginfo->flags) || MSG_IS_UNREAD(msginfo->flags))
+ return;
+
+ summary_msginfo_set_flags(msginfo, MSG_UNREAD, 0);
+ summary_set_row_marks(summaryview, row);
+ debug_print("Message %d is marked as unread\n",
+ msginfo->msgnum);
+}
+
void summary_mark_as_read(SummaryView *summaryview)
{
GtkCMCTree *ctree = GTK_CMCTREE(summaryview->ctree);
if (summary_is_locked(summaryview))
return;
+
+ if ((summaryview->folder_item->total_msgs == (gint)g_list_length(GTK_CMCLIST(ctree)->selection) &&
+ summaryview->folder_item->total_msgs > 1) &&
+ !summary_mark_all_read_confirm(TRUE))
+ return;
+
START_LONG_OPERATION(summaryview, FALSE);
folder_item_set_batch(summaryview->folder_item, TRUE);
for (cur = GTK_CMCLIST(ctree)->selection; cur != NULL && cur->data != NULL; cur = cur->next)
summary_status_show(summaryview);
}
+void summary_mark_as_unread(SummaryView *summaryview)
+{
+ GtkCMCTree *ctree = GTK_CMCTREE(summaryview->ctree);
+ GList *cur;
+ gboolean froze = FALSE;
+
+ if (summary_is_locked(summaryview))
+ return;
+
+ if ((summaryview->folder_item->total_msgs == (gint)g_list_length(GTK_CMCLIST(ctree)->selection) &&
+ summaryview->folder_item->total_msgs > 1) &&
+ !summary_mark_all_unread_confirm(TRUE))
+ return;
+
+ START_LONG_OPERATION(summaryview, FALSE);
+ folder_item_set_batch(summaryview->folder_item, TRUE);
+ for (cur = GTK_CMCLIST(ctree)->selection; cur != NULL && cur->data != NULL; cur = cur->next)
+ summary_mark_row_as_unread(summaryview,
+ GTK_CMCTREE_NODE(cur->data));
+ folder_item_set_batch(summaryview->folder_item, FALSE);
+ END_LONG_OPERATION(summaryview);
+
+ summary_status_show(summaryview);
+}
+
void summary_msgs_lock(SummaryView *summaryview)
{
GtkCMCTree *ctree = GTK_CMCTREE(summaryview->ctree);
summary_status_show(summaryview);
}
-void summary_mark_all_read(SummaryView *summaryview)
+static gboolean summary_mark_all_read_confirm(gboolean ask_if_needed)
+{
+ /* ask_if_needed is FALSE when user-asking is performed by caller,
+ commonly when the caller is a mark-as-read-recursive func */
+ if (ask_if_needed && prefs_common.ask_mark_all_read) {
+ AlertValue 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, ALERTFOCUS_FIRST,
+ TRUE, NULL, ALERT_QUESTION);
+
+ if ((val & ~G_ALERTDISABLE) != G_ALERTALTERNATE)
+ return FALSE;
+ else if (val & G_ALERTDISABLE)
+ prefs_common.ask_mark_all_read = FALSE;
+ }
+ return TRUE;
+}
+
+void summary_mark_all_read(SummaryView *summaryview, gboolean ask_if_needed)
{
GtkCMCTree *ctree = GTK_CMCTREE(summaryview->ctree);
GtkCMCTreeNode *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_ALERTDEFAULT);
+ if (summary_is_locked(summaryview))
+ return;
+
+ if (!summary_mark_all_read_confirm(ask_if_needed))
+ return;
+
+ START_LONG_OPERATION(summaryview, TRUE);
+ folder_item_set_batch(summaryview->folder_item, TRUE);
+ for (node = GTK_CMCTREE_NODE(GTK_CMCLIST(ctree)->row_list); node != NULL;
+ node = gtkut_ctree_node_next(ctree, node))
+ summary_mark_row_as_read(summaryview, node);
+ folder_item_set_batch(summaryview->folder_item, FALSE);
+ for (node = GTK_CMCTREE_NODE(GTK_CMCLIST(ctree)->row_list); node != NULL;
+ node = gtkut_ctree_node_next(ctree, node)) {
+ if (!GTK_CMCTREE_ROW(node)->expanded)
+ summary_set_row_marks(summaryview, node);
+ }
+ END_LONG_OPERATION(summaryview);
+
+ summary_status_show(summaryview);
+}
+
+static gboolean summary_mark_all_unread_confirm(gboolean ask_if_needed)
+{
+ /* ask_if_needed is FALSE when user-asking is performed by caller,
+ commonly when the caller is a mark-as-unread-recursive func */
+ if (ask_if_needed && prefs_common.ask_mark_all_read) {
+ AlertValue val = alertpanel_full(_("Mark all as unread"),
+ _("Do you really want to mark all mails in this folder as unread?"),
+ GTK_STOCK_NO, GTK_STOCK_YES, NULL, ALERTFOCUS_FIRST,
+ TRUE, NULL, ALERT_QUESTION);
if ((val & ~G_ALERTDISABLE) != G_ALERTALTERNATE)
- return;
+ return FALSE;
else if (val & G_ALERTDISABLE)
prefs_common.ask_mark_all_read = FALSE;
}
-
+ return TRUE;
+}
+
+void summary_mark_all_unread(SummaryView *summaryview, gboolean ask_if_needed)
+{
+ GtkCMCTree *ctree = GTK_CMCTREE(summaryview->ctree);
+ GtkCMCTreeNode *node;
+ gboolean froze = FALSE;
+
if (summary_is_locked(summaryview))
return;
+
+ if (!summary_mark_all_unread_confirm(ask_if_needed))
+ return;
+
START_LONG_OPERATION(summaryview, TRUE);
folder_item_set_batch(summaryview->folder_item, TRUE);
for (node = GTK_CMCTREE_NODE(GTK_CMCLIST(ctree)->row_list); node != NULL;
- node = gtkut_ctree_node_next(ctree, node))
- summary_mark_row_as_read(summaryview, node);
+ node = gtkut_ctree_node_next(ctree, node))
+ summary_mark_row_as_unread(summaryview, node);
folder_item_set_batch(summaryview->folder_item, FALSE);
for (node = GTK_CMCTREE_NODE(GTK_CMCLIST(ctree)->row_list); node != NULL;
- node = gtkut_ctree_node_next(ctree, node)) {
+ node = gtkut_ctree_node_next(ctree, node)) {
if (!GTK_CMCTREE_ROW(node)->expanded)
summary_set_row_marks(summaryview, node);
}
END_LONG_OPERATION(summaryview);
-
+
summary_status_show(summaryview);
}
summary_status_show(summaryview);
}
-
-static void summary_mark_row_as_unread(SummaryView *summaryview,
- GtkCMCTreeNode *row)
-{
- GtkCMCTree *ctree = GTK_CMCTREE(summaryview->ctree);
- MsgInfo *msginfo;
-
- msginfo = gtk_cmctree_node_get_row_data(ctree, row);
- cm_return_if_fail(msginfo);
- if (MSG_IS_DELETED(msginfo->flags)) {
- procmsg_msginfo_set_to_folder(msginfo, NULL);
- summary_msginfo_unset_flags(msginfo, MSG_DELETED, 0);
- summaryview->deleted--;
- }
-
- summary_msginfo_set_flags(msginfo, MSG_UNREAD, 0);
- debug_print("Message %d is marked as unread\n",
- msginfo->msgnum);
-
- summary_set_row_marks(summaryview, row);
-}
-
-void summary_mark_as_unread(SummaryView *summaryview)
-{
- GtkCMCTree *ctree = GTK_CMCTREE(summaryview->ctree);
- GList *cur;
- gboolean froze = FALSE;
-
- if (summary_is_locked(summaryview))
- return;
- START_LONG_OPERATION(summaryview, FALSE);
- folder_item_set_batch(summaryview->folder_item, TRUE);
- for (cur = GTK_CMCLIST(ctree)->selection; cur != NULL && cur->data != NULL;
- cur = cur->next)
- summary_mark_row_as_unread(summaryview,
- GTK_CMCTREE_NODE(cur->data));
- folder_item_set_batch(summaryview->folder_item, FALSE);
- END_LONG_OPERATION(summaryview);
-
- summary_status_show(summaryview);
-}
-
static gboolean check_permission(SummaryView *summaryview, MsgInfo * msginfo)
{
GList * cur;
}
if (!found) {
- alertpanel_error(_("You're not the author of the article.\n"));
+ alertpanel_error(_("You're not the author of the article."));
}
return found;
if (!prefs_common.live_dangerously) {
gchar *buf = NULL;
- int num = g_list_length(GTK_CMCLIST(summaryview->ctree)->selection);
+ guint num = g_list_length(GTK_CMCLIST(summaryview->ctree)->selection);
buf = g_strdup_printf(ngettext(
"Do you really want to delete the selected message?",
"Do you really want to delete the %d selected messages?", num),
num);
aval = alertpanel(ngettext("Delete message", "Delete messages", num),
buf,
- GTK_STOCK_CANCEL, "+"GTK_STOCK_DELETE, NULL);
+ GTK_STOCK_CANCEL, GTK_STOCK_DELETE, NULL, ALERTFOCUS_SECOND);
g_free(buf);
if (aval != G_ALERTALTERNATE) {
END_LONG_OPERATION(summaryview);
if (!node || prefs_common.next_on_delete == FALSE)
node = summary_find_next_msg(summaryview, sel_last,TRUE);
}
- summary_select_node(summaryview, node, -1);
+ summary_select_node(summaryview, node, OPEN_SELECTED_ON_DELETEMOVE);
if (prefs_common.immediate_exec || folder_has_parent_of_type(item, F_TRASH)) {
summary_execute(summaryview);
if (!node || prefs_common.next_on_delete == FALSE)
node = summary_find_next_msg(summaryview, sel_last,TRUE);
}
- summary_select_node(summaryview, node, -1);
+ summary_select_node(summaryview, node, OPEN_SELECTED_ON_DELETEMOVE);
summary_status_show(summaryview);
}
GtkCMCTreeNode *node = gtk_cmctree_node_nth (GTK_CMCTREE(summaryview->ctree),
GTK_CMCLIST(summaryview->ctree)->rows - 1);
if (node)
- summary_select_node(summaryview, node, -1);
+ summary_select_node(summaryview, node, OPEN_SELECTED_ON_DELETEMOVE);
}
}
if (!summaryview->folder_item ||
FOLDER_TYPE(summaryview->folder_item->folder) == F_NEWS) return;
- to_folder = foldersel_folder_sel(NULL, FOLDER_SEL_MOVE, NULL, FALSE);
+ to_folder = foldersel_folder_sel(NULL, FOLDER_SEL_MOVE, NULL, FALSE,
+ ngettext(
+ "Select folder to move selected message to",
+ "Select folder to move selected messages to",
+ g_list_length(GTK_CMCLIST(summaryview->ctree)->selection))
+ );
summary_move_selected_to(summaryview, to_folder);
}
if (!summaryview->folder_item) return;
- to_folder = foldersel_folder_sel(NULL, FOLDER_SEL_COPY, NULL, FALSE);
+ to_folder = foldersel_folder_sel(NULL, FOLDER_SEL_COPY, NULL, FALSE,
+ ngettext(
+ "Select folder to copy selected message to",
+ "Select folder to copy selected messages to",
+ g_list_length(GTK_CMCLIST(summaryview->ctree)->selection))
+ );
summary_copy_selected_to(summaryview, to_folder);
}
void summary_select_all(SummaryView *summaryview)
{
+ GtkCMCTreeNode *node;
+
if (!summaryview->folder_item) return;
+ if (GTK_CMCLIST(summaryview->ctree)->focus_row < 0) {
+ /* If no row is selected, select (but do not open) the first
+ * row, to get summaryview into correct state for selecting all. */
+ debug_print("summary_select_all: no row selected, selecting first one\n");
+ if (GTK_CMCLIST(summaryview->ctree)->row_list != NULL) {
+ node = gtk_cmctree_node_nth(GTK_CMCTREE(summaryview->ctree), 0);
+ summary_select_node(summaryview, node, FALSE);
+ }
+ }
+
+ /* Now select all rows while locking the summaryview for
+ * faster performance. */
summary_lock(summaryview);
gtk_cmclist_select_all(GTK_CMCLIST(summaryview->ctree));
summary_unlock(summaryview);
+
summary_status_show(summaryview);
}
gchar *filename = NULL;
gchar *src, *dest;
gchar *tmp;
+ gchar *filedir = NULL;
AlertValue aval = 0;
g_warning("summary_save_as(): failed to convert character set.");
filename = g_strdup(oldstr);
}
- dest = filesel_select_file_save(_("Save as"), filename);
+ dest = filename;
g_free(filename);
} else
- dest = filesel_select_file_save(_("Save as"), filename);
+ dest = filename;
filename = NULL;
if (!dest) return;
+ if (prefs_common.attach_save_dir && *prefs_common.attach_save_dir)
+ dest = g_strconcat(prefs_common.attach_save_dir, G_DIR_SEPARATOR_S,
+ dest, NULL);
+ dest = filesel_select_file_save(_("Save as"), dest);
+ if (!dest) return;
+
if (is_file_exist(dest)) {
aval = alertpanel(_("Append or Overwrite"),
_("Append or overwrite existing file?"),
- _("_Append"), _("_Overwrite"),
- GTK_STOCK_CANCEL);
+ _("_Append"), _("_Overwrite"), GTK_STOCK_CANCEL,
+ ALERTFOCUS_FIRST);
if (aval != 0 && aval != 1)
return;
}
}
g_free(src);
}
+
+ filedir = g_path_get_dirname(dest);
+ if (filedir && strcmp(filedir, ".")) {
+ g_free(prefs_common.attach_save_dir);
+ prefs_common.attach_save_dir = g_filename_to_utf8(filedir, -1, NULL, NULL, NULL);
+ }
+
g_free(dest);
g_free(tmp);
}
"want to continue?"),
g_list_length(clist->selection));
if (g_list_length(clist->selection) > 9
- && alertpanel(_("Warning"), msg, GTK_STOCK_CANCEL, "+" GTK_STOCK_YES, NULL)
- != G_ALERTALTERNATE) {
+ && alertpanel(_("Warning"), msg, GTK_STOCK_CANCEL, GTK_STOCK_YES,
+ NULL, ALERTFOCUS_SECOND) != G_ALERTALTERNATE) {
g_free(msg);
return;
}
if (new_selected) {
summary_unlock(summaryview);
- gtk_sctree_select
- (GTK_SCTREE(ctree), new_selected);
+ summary_select_node(summaryview, new_selected, OPEN_SELECTED_ON_DELETEMOVE);
summary_lock(summaryview);
}
if (new_selected) {
summary_unlock(summaryview);
- gtk_sctree_select
- (GTK_SCTREE(ctree), new_selected);
+ summary_select_node(summaryview, new_selected, OPEN_SELECTED_ON_DELETEMOVE);
summary_lock(summaryview);
}
while (node && GTK_CMCTREE_ROW(node)->parent) {
focus_node = node = GTK_CMCTREE_ROW(node)->parent;
}
- gtk_sctree_select(GTK_SCTREE(ctree), focus_node);
+ summary_select_node(summaryview, node, OPEN_SELECTED_ON_DIRECTIONAL);
node = GTK_CMCTREE_NODE(GTK_CMCLIST(ctree)->row_list);
while (node) {
if (GTK_CMCTREE_ROW(node)->children) {
_("Filtering"),
_("There are some filtering rules that belong to an account.\n"
"Please choose what to do with these rules:"),
- GTK_STOCK_CANCEL, _("_Filter"), NULL, TRUE, G_ALERTALTERNATE, vbox);
+ GTK_STOCK_CANCEL, _("_Filter"), NULL, ALERTFOCUS_SECOND,
+ TRUE, vbox);
if ((val & ~G_ALERTDISABLE) != G_ALERTALTERNATE) {
return FALSE;
void summary_filter(SummaryView *summaryview, gboolean selected_only)
{
GSList *mlist = NULL, *cur_list;
+ PrefsAccount *ac_prefs = NULL;
summary_lock(summaryview);
/* are there any per-account filtering rules? */
mlist = folder_item_get_msg_list(summaryview->folder_item);
}
+ ac_prefs = ((summaryview->folder_item->folder != NULL) &&
+ (summaryview->folder_item->folder->account != NULL))
+ ? summaryview->folder_item->folder->account : NULL;
+
folder_item_set_batch(summaryview->folder_item, TRUE);
for (cur_list = mlist; cur_list; cur_list = cur_list->next) {
- summary_filter_func((MsgInfo *)cur_list->data);
+ summary_filter_func((MsgInfo *)cur_list->data, ac_prefs);
}
folder_item_set_batch(summaryview->folder_item, FALSE);
summary_show(summaryview, summaryview->folder_item);
}
-static void summary_filter_func(MsgInfo *msginfo)
+static void summary_filter_func(MsgInfo *msginfo, PrefsAccount *ac_prefs)
{
MailFilteringData mail_filtering_data;
if (hooks_invoke(MAIL_MANUAL_FILTERING_HOOKLIST, &mail_filtering_data))
return;
- filter_message_by_msginfo(filtering_rules, msginfo, NULL,
+ filter_message_by_msginfo(filtering_rules, msginfo, ac_prefs,
FILTERING_MANUALLY, NULL);
}
}
/* summary_set_colorlabel_color() - labelcolor parameter is the color *flag*
- * for the messsage; not the color index */
+ * for the message; not the color index */
void summary_set_colorlabel_color(GtkCMCTree *ctree, GtkCMCTreeNode *node,
guint labelcolor)
{
if (color_index < 0 || color_index >= N_COLOR_LABELS) {
if (!prev_style) return;
style = gtk_style_copy(prev_style);
- color = ctree_style->fg[GTK_STATE_NORMAL];
- style->fg[GTK_STATE_NORMAL] = color;
- color = ctree_style->fg[GTK_STATE_SELECTED];
- style->fg[GTK_STATE_SELECTED] = color;
+ color = ctree_style->text[GTK_STATE_NORMAL];
+ style->text[GTK_STATE_NORMAL] = color;
+ color = ctree_style->text[GTK_STATE_SELECTED];
+ style->text[GTK_STATE_SELECTED] = color;
} else {
if (prev_style)
style = gtk_style_copy(prev_style);
else
style = gtk_style_copy(ctree_style);
color = colorlabel_get_color(color_index);
- style->fg[GTK_STATE_NORMAL] = color;
+ style->text[GTK_STATE_NORMAL] = color;
/* get the average of label color and selected fg color
for visibility */
- style->fg[GTK_STATE_SELECTED].red = (color.red + 3*ctree_style->fg[GTK_STATE_SELECTED].red ) / 4;
- style->fg[GTK_STATE_SELECTED].green = (color.green + 3*ctree_style->fg[GTK_STATE_SELECTED].green) / 4;
- style->fg[GTK_STATE_SELECTED].blue = (color.blue + 3*ctree_style->fg[GTK_STATE_SELECTED].blue ) / 4;
+ style->text[GTK_STATE_SELECTED].red = (color.red + 3*ctree_style->text[GTK_STATE_SELECTED].red ) / 4;
+ style->text[GTK_STATE_SELECTED].green = (color.green + 3*ctree_style->text[GTK_STATE_SELECTED].green) / 4;
+ style->text[GTK_STATE_SELECTED].blue = (color.blue + 3*ctree_style->text[GTK_STATE_SELECTED].blue ) / 4;
}
gtk_cmctree_node_set_row_style(ctree, node, style);
GList *cur;
gboolean froze = FALSE;
+ if (prefs_common.ask_override_colorlabel) {
+ GtkCMCTree *ctree = GTK_CMCTREE(summaryview->ctree);
+ gboolean ask = FALSE;
+ AlertValue val;
+ guint color;
+ gboolean already_this_color_everywhere = TRUE;
+
+ /* if clearing color labels (applying 'none', 0):
+ - ask if at least one message has a non-0 color label set
+ if applying a non-0 color label:
+ - ask if at least one of the selected messages has a non-0 color label different
+ from the one we want to apply.
+ - don't ask if all messages have the same color label as the one we're applying
+ */
+ for (cur = GTK_CMCLIST(ctree)->selection;
+ !ask && cur != NULL && cur->data != NULL;
+ cur = cur->next) {
+ MsgInfo *msginfo = gtk_cmctree_node_get_row_data(ctree, GTK_CMCTREE_NODE(cur->data));
+ if (msginfo) {
+ color = MSG_GET_COLORLABEL_VALUE(msginfo->flags);
+ if (labelcolor == 0) {
+ /* clearing color labels */
+ ask = (color != 0);
+ } else {
+ already_this_color_everywhere &= (color == labelcolor);
+ ask = ((color != 0) && (color != labelcolor)) && !already_this_color_everywhere;
+ }
+ }
+ }
+
+ if (ask) {
+ gchar *msg;
+
+ if (labelcolor == 0)
+ msg = _("Do you really want to reset the color label of all selected messages?");
+ else
+ msg = _("Do you really want to apply this color label to all selected messages?");
+ val = alertpanel_full(labelcolor == 0? _("Reset color label"): _("Set color label"), msg,
+ GTK_STOCK_NO, GTK_STOCK_YES, NULL, ALERTFOCUS_FIRST,
+ TRUE, NULL, ALERT_QUESTION);
+
+ if ((val & ~G_ALERTDISABLE) != G_ALERTALTERNATE)
+ return;
+ else if (val & G_ALERTDISABLE)
+ prefs_common.ask_override_colorlabel = FALSE;
+ }
+ }
+
START_LONG_OPERATION(summaryview, FALSE);
for (cur = GTK_CMCLIST(ctree)->selection; cur != NULL && cur->data != NULL; cur = cur->next)
summary_set_row_colorlabel(summaryview,
return TRUE;
}
#endif
+
+static gboolean summary_header_button_pressed(GtkWidget *widget,
+ GdkEvent *_event,
+ gpointer user_data)
+{
+ GdkEventButton *event = (GdkEventButton *)_event;
+ SummaryView *summaryview = (SummaryView *)user_data;
+
+ cm_return_val_if_fail(summaryview != NULL, FALSE);
+
+ /* Only handle single button presses. */
+ if (event->type == GDK_2BUTTON_PRESS ||
+ event->type == GDK_3BUTTON_PRESS)
+ return FALSE;
+
+ /* Handle right-click for context menu */
+ if (event->button == 3) {
+ /* Set up any menu items that need setting up. */
+ summaryview->header_menu_lock = TRUE;
+ cm_toggle_menu_set_active_full(summaryview->mainwin->ui_manager,
+ "Menus/SummaryViewHeaderPopup/LockColumnHeaders",
+ prefs_common_get_prefs()->summary_col_lock);
+ summaryview->header_menu_lock = FALSE;
+
+ gtk_menu_popup(GTK_MENU(summaryview->headerpopupmenu),
+ NULL, NULL, NULL, NULL, 3, event->time);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
static GtkWidget *summary_ctree_create(SummaryView *summaryview)
{
GtkWidget *ctree;
gtk_cmclist_set_column_width(GTK_CMCLIST(ctree), col_pos[S_COL_TAGS],
prefs_common.summary_col_size[S_COL_TAGS]);
- gtk_cmctree_set_line_style(GTK_CMCTREE(ctree), GTK_CMCTREE_LINES_NONE);
gtk_cmctree_set_expander_style(GTK_CMCTREE(ctree),
GTK_CMCTREE_EXPANDER_TRIANGLE);
g_object_set_data(G_OBJECT(ctree), "summaryview", (gpointer)summaryview);
for (pos = 0; pos < N_SUMMARY_COLS; pos++) {
- gtkut_widget_set_can_focus(GTK_CMCLIST(ctree)->column[pos].button,
+ gtk_widget_set_can_focus(GTK_CMCLIST(ctree)->column[pos].button,
FALSE);
if (((pos == summaryview->col_pos[S_COL_FROM] && !FOLDER_SHOWS_TO_HDR(summaryview->folder_item)) ||
(pos == summaryview->col_pos[S_COL_TO] && FOLDER_SHOWS_TO_HDR(summaryview->folder_item)) ||
/* connect signal to the buttons for sorting */
#define CLIST_BUTTON_SIGNAL_CONNECT(col, func) \
+ g_signal_connect \
+ (G_OBJECT(GTK_CMCLIST(ctree)->column[col_pos[col]].button), \
+ "button-press-event", \
+ G_CALLBACK(summary_header_button_pressed), \
+ summaryview); \
g_signal_connect \
(G_OBJECT(GTK_CMCLIST(ctree)->column[col_pos[col]].button), \
"clicked", \
G_CALLBACK(func), \
- summaryview)
-
- CLIST_BUTTON_SIGNAL_CONNECT(S_COL_MARK , summary_mark_clicked);
- CLIST_BUTTON_SIGNAL_CONNECT(S_COL_STATUS , summary_status_clicked);
- CLIST_BUTTON_SIGNAL_CONNECT(S_COL_MIME , summary_mime_clicked);
- CLIST_BUTTON_SIGNAL_CONNECT(S_COL_NUMBER , summary_num_clicked);
- CLIST_BUTTON_SIGNAL_CONNECT(S_COL_SIZE , summary_size_clicked);
- CLIST_BUTTON_SIGNAL_CONNECT(S_COL_DATE , summary_date_clicked);
- CLIST_BUTTON_SIGNAL_CONNECT(S_COL_FROM , summary_from_clicked);
- CLIST_BUTTON_SIGNAL_CONNECT(S_COL_TO , summary_to_clicked);
- CLIST_BUTTON_SIGNAL_CONNECT(S_COL_SUBJECT, summary_subject_clicked);
- CLIST_BUTTON_SIGNAL_CONNECT(S_COL_SCORE, summary_score_clicked);
- CLIST_BUTTON_SIGNAL_CONNECT(S_COL_LOCKED, summary_locked_clicked);
- CLIST_BUTTON_SIGNAL_CONNECT(S_COL_TAGS, summary_tags_clicked);
+ summaryview);
+
+ CLIST_BUTTON_SIGNAL_CONNECT(S_COL_MARK , summary_mark_clicked)
+ CLIST_BUTTON_SIGNAL_CONNECT(S_COL_STATUS , summary_status_clicked)
+ CLIST_BUTTON_SIGNAL_CONNECT(S_COL_MIME , summary_mime_clicked)
+ CLIST_BUTTON_SIGNAL_CONNECT(S_COL_NUMBER , summary_num_clicked)
+ CLIST_BUTTON_SIGNAL_CONNECT(S_COL_SIZE , summary_size_clicked)
+ CLIST_BUTTON_SIGNAL_CONNECT(S_COL_DATE , summary_date_clicked)
+ CLIST_BUTTON_SIGNAL_CONNECT(S_COL_FROM , summary_from_clicked)
+ CLIST_BUTTON_SIGNAL_CONNECT(S_COL_TO , summary_to_clicked)
+ CLIST_BUTTON_SIGNAL_CONNECT(S_COL_SUBJECT, summary_subject_clicked)
+ CLIST_BUTTON_SIGNAL_CONNECT(S_COL_SCORE , summary_score_clicked)
+ CLIST_BUTTON_SIGNAL_CONNECT(S_COL_LOCKED , summary_locked_clicked)
+ CLIST_BUTTON_SIGNAL_CONNECT(S_COL_TAGS , summary_tags_clicked)
#undef CLIST_BUTTON_SIGNAL_CONNECT
summary_show(summaryview, item);
- summary_select_by_msgnum(summaryview, selected_msgnum);
+ summary_select_by_msgnum(summaryview, selected_msgnum, FALSE);
summaryview->selected = summary_find_msg_by_msgnum(summaryview, selected_msgnum);
summaryview->displayed = summary_find_msg_by_msgnum(summaryview, displayed_msgnum);
SummaryView *summaryview)
{
if (!event) return FALSE;
+ if (event->window != GTK_CMCLIST(ctree)->clist_window) return FALSE;
if (event->button == 3) {
/* right clicked */
break;
case GDK_KEY_Down: case GDK_KEY_KP_Down:
next = gtk_cmctree_node_nth(ctree,
- MIN(GTK_CMCLIST(ctree)->focus_row + 1, GTK_CMCLIST(ctree)->rows));
+ MIN(GTK_CMCLIST(ctree)->focus_row + 1, GTK_CMCLIST(ctree)->rows - 1));
break;
case GDK_KEY_Page_Up: case GDK_KEY_KP_Page_Up:
next = gtk_cmctree_node_nth(ctree,
break;
}
- if (next) {
+ if (next != NULL &&
+ next != gtk_cmctree_node_nth(ctree, GTK_CMCLIST(ctree)->focus_row)) {
gtk_sctree_select_with_state
(GTK_SCTREE(ctree), next, (event->state & ~GDK_CONTROL_MASK) );
/* Deprecated - what are the non-deprecated equivalents? */
if (gtk_cmctree_node_is_visible(GTK_CMCTREE(ctree), next) != GTK_VISIBILITY_FULL)
gtkut_ctree_node_move_if_on_the_edge(GTK_CMCTREE(ctree), next, -1);
+ if (!mod_pressed)
+ summary_select_node(summaryview, summaryview->selected, OPEN_SELECTED_ON_DIRECTIONAL);
summaryview->selected = next;
}
}
return g_slist_reverse(msginfo_list);
}
+/*
+ * \brief get number of messages currently selected in SummaryView
+ *
+ * \param summaryview
+ *
+ * \return number of messages currently selected
+ */
+guint summary_get_selection_count(SummaryView *summaryview)
+{
+ cm_return_val_if_fail(summaryview != NULL, 0);
+ return g_list_length(GTK_CMCLIST(summaryview->ctree)->selection);
+}
+
static void summary_sort_by_column_click(SummaryView *summaryview,
FolderSortKey sort_key)
{
+ if (prefs_common.summary_col_lock) {
+ debug_print("summaryview columns locked, ignoring\n");
+ return;
+ }
+
GtkCMCTreeNode *node = NULL;
START_TIMING("");
if (summaryview->sort_key == sort_key)
summaryview->sort_type == SORT_ASCENDING
? SORT_DESCENDING : SORT_ASCENDING);
else
- summary_sort(summaryview, sort_key, SORT_ASCENDING);
+ summary_sort(summaryview, sort_key, summaryview->sort_type);
node = GTK_CMCTREE_NODE(GTK_CMCLIST(summaryview->ctree)->row_list);
return summary_cmp_by_date(clist, ptr1, ptr2);
}
-static void summary_ignore_thread_func(GtkCMCTree *ctree, GtkCMCTreeNode *row, gpointer data)
+static void summary_ignore_thread_func_mark_unread(GtkCMCTree *ctree, GtkCMCTreeNode *row, gpointer data)
{
- SummaryView *summaryview = (SummaryView *) data;
MsgInfo *msginfo;
msginfo = gtk_cmctree_node_get_row_data(ctree, row);
summary_msginfo_unset_flags(msginfo, MSG_WATCH_THREAD, 0);
summary_msginfo_change_flags(msginfo, MSG_IGNORE_THREAD, 0, MSG_NEW | MSG_UNREAD, 0);
+ debug_print("Message %d is marked as ignore thread\n", msginfo->msgnum);
+}
+
+static void summary_ignore_thread_func_set_row(GtkCMCTree *ctree, GtkCMCTreeNode *row, gpointer data)
+{
+ SummaryView *summaryview = (SummaryView *) data;
+ MsgInfo *msginfo;
+
+ msginfo = gtk_cmctree_node_get_row_data(ctree, row);
+ cm_return_if_fail(msginfo);
+
summary_set_row_marks(summaryview, row);
- debug_print("Message %d is marked as ignore thread\n",
- msginfo->msgnum);
+ debug_print("Message %d update in row view\n", msginfo->msgnum);
}
void summary_ignore_thread(SummaryView *summaryview)
START_LONG_OPERATION(summaryview, FALSE);
for (cur = GTK_CMCLIST(ctree)->selection; cur != NULL && cur->data != NULL; cur = cur->next)
- gtk_cmctree_pre_recursive(ctree, GTK_CMCTREE_NODE(cur->data),
- GTK_CMCTREE_FUNC(summary_ignore_thread_func),
+ gtk_cmctree_pre_recursive(ctree, GTK_CMCTREE_NODE(cur->data),
+ GTK_CMCTREE_FUNC(summary_ignore_thread_func_mark_unread),
+ summaryview);
+
+ for (cur = GTK_CMCLIST(ctree)->selection; cur != NULL && cur->data != NULL; cur = cur->next)
+ gtk_cmctree_pre_recursive(ctree, GTK_CMCTREE_NODE(cur->data),
+ GTK_CMCTREE_FUNC(summary_ignore_thread_func_set_row),
summaryview);
END_LONG_OPERATION(summaryview);
summary_watch_thread(summaryview);
}
+
void summary_toggle_show_read_messages(SummaryView *summaryview)
{
FolderItemUpdateData source;
cm_return_val_if_fail(hookdata->item != NULL, FALSE);
cm_return_val_if_fail(summaryview != NULL, FALSE);
- if (hookdata->update_flags & F_ITEM_UPDATE_NAME) {
+ if (hookdata->item == summaryview->folder_item &&
+ hookdata->update_flags & F_ITEM_UPDATE_NAME) {
gchar *name = folder_item_get_name(hookdata->item);
gtk_label_set_text(GTK_LABEL(summaryview->statlabel_folder), name);
g_free(name);
node = gtk_cmctree_node_nth(GTK_CMCTREE(summaryview->ctree), 0);
if (node)
- summary_select_node(summaryview, node, 1);
+ summary_select_node(summaryview, node, OPEN_SELECTED_ON_SEARCH_RESULTS);
}
gint summaryview_export_mbox_list(SummaryView *summaryview)
{
gtk_widget_set_sensitive(summaryview->ctree, TRUE);
}
+
+static void summary_reedit_cb(GtkAction *gaction, gpointer data)
+{
+ SummaryView *summaryview = (SummaryView *)data;
+ summary_reedit(summaryview);
+}
+
+#define DO_ACTION(name, act) { if (!strcmp(a_name, name)) action = act; }
+static void summary_reply_cb(GtkAction *gaction, gpointer data)
+{
+ SummaryView *summaryview = (SummaryView *)data;
+ GSList *msginfo_list = NULL;
+ gint action = COMPOSE_REPLY;
+ const gchar *a_name = gtk_action_get_name(gaction);
+
+ DO_ACTION("SummaryViewPopup/Reply", COMPOSE_REPLY);
+ DO_ACTION("SummaryViewPopup/ReplyTo/All", COMPOSE_REPLY_TO_ALL);
+ DO_ACTION("SummaryViewPopup/ReplyTo/Sender", COMPOSE_REPLY_TO_SENDER);
+ DO_ACTION("SummaryViewPopup/ReplyTo/List", COMPOSE_REPLY_TO_LIST);
+ DO_ACTION("SummaryViewPopup/Forward", COMPOSE_FORWARD_INLINE);
+ DO_ACTION("SummaryViewPopup/ForwardAtt", COMPOSE_FORWARD_AS_ATTACH);
+ DO_ACTION("SummaryViewPopup/Redirect", COMPOSE_REDIRECT);
+
+ msginfo_list = summary_get_selection(summaryview);
+ cm_return_if_fail(msginfo_list != NULL);
+ compose_reply_from_messageview(NULL, msginfo_list, action);
+ g_slist_free(msginfo_list);
+}
+
+gboolean summary_is_opened_message_selected(SummaryView *summaryview)
+{
+ GList *sel = NULL;
+
+ cm_return_val_if_fail(summaryview != NULL, FALSE);
+
+ sel = GTK_CMCLIST(summaryview->ctree)->selection;
+
+ if (summaryview->displayed == NULL || sel == NULL) {
+ return FALSE;
+ }
+
+ for ( ; sel != NULL; sel = sel->next) {
+ if (summaryview->displayed == GTK_CMCTREE_NODE(sel->data)) {
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+gboolean summary_has_opened_message(SummaryView *summaryview)
+{
+ cm_return_val_if_fail(summaryview != NULL, FALSE);
+
+ return (summaryview->displayed != NULL);
+}
+
+static void summary_header_lock_sorting_cb(GtkAction *gaction, gpointer data)
+{
+ SummaryView *summaryview = (SummaryView *)data;
+ gboolean sorting_lock = prefs_common_get_prefs()->summary_col_lock;
+
+ if (summaryview->header_menu_lock)
+ return;
+
+ debug_print("%slocking summaryview columns\n",
+ sorting_lock ? "un" : "");
+ prefs_common_get_prefs()->summary_col_lock = !sorting_lock;
+}
+
+static void summary_header_set_displayed_columns_cb(GtkAction *gaction,
+ gpointer data)
+{
+ SummaryView *summaryview = (SummaryView *)data;
+
+ if (summaryview->header_menu_lock)
+ return;
+
+ prefs_summary_column_open();
+}