#include "sourcewindow.h"
#include "prefs_common.h"
#include "prefs_summary_column.h"
+#include "prefs_filter.h"
#include "account.h"
#include "compose.h"
#include "utils.h"
static void summary_display_msg (SummaryView *summaryview,
GtkCTreeNode *row,
gboolean new_window);
-static void summary_toggle_view (SummaryView *summaryview);
+
static void summary_set_row_marks (SummaryView *summaryview,
GtkCTreeNode *row);
static void summaryview_subject_filter_init (PrefsFolderItem *prefs);
static GtkWidget *summary_ctree_create (SummaryView *summaryview);
+static void summary_toggle_view(SummaryView *summarview);
+
/* callback functions */
-static void summary_toggle_pressed (GtkWidget *eventbox,
- GdkEventButton *event,
- SummaryView *summaryview);
+static void summary_toggle_view_cb (GtkWidget *widget,
+ gpointer data);
static void summary_button_pressed (GtkWidget *ctree,
GdkEventButton *event,
SummaryView *summaryview);
{N_("/_Mark/---"), NULL, NULL, 0, "<Separator>"},
{N_("/_Mark/Mark as unr_ead"), NULL, summary_mark_as_unread, 0, NULL},
{N_("/_Mark/Mark as rea_d"), NULL, summary_mark_as_read, 0, NULL},
- {N_("/_Mark/Mark all read"), NULL, summary_mark_all_read, 0, NULL},
{N_("/_Mark/Ignore thread"), NULL, summary_ignore_thread, 0, NULL},
{N_("/_Mark/Unignore thread"), NULL, summary_unignore_thread, 0, NULL},
{N_("/Color la_bel"), NULL, NULL, 0, NULL},
GtkWidget *statlabel_folder;
GtkWidget *statlabel_select;
GtkWidget *statlabel_msgs;
- GtkWidget *toggle_eventbox;
- GtkWidget *toggle_arrow;
+ GtkWidget *toggle_view_btn;
+ GtkWidget *toggle_view_arrow;
GtkWidget *popupmenu;
GtkItemFactory *popupfactory;
gint n_entries;
statlabel_select = gtk_label_new("");
gtk_box_pack_start(GTK_BOX(hbox), statlabel_select, FALSE, FALSE, 16);
- /* toggle view button */
- toggle_eventbox = gtk_event_box_new();
- gtk_box_pack_end(GTK_BOX(hbox), toggle_eventbox, FALSE, FALSE, 4);
- toggle_arrow = gtk_arrow_new(GTK_ARROW_DOWN, GTK_SHADOW_OUT);
- gtk_container_add(GTK_CONTAINER(toggle_eventbox), toggle_arrow);
- gtk_signal_connect(GTK_OBJECT(toggle_eventbox), "button_press_event",
- GTK_SIGNAL_FUNC(summary_toggle_pressed),
- summaryview);
+ /* toggle view buttons */
+ toggle_view_btn = gtk_button_new();
+ gtk_box_pack_end(GTK_BOX(hbox), toggle_view_btn, FALSE, FALSE, 0);
+ gtk_button_set_relief(GTK_BUTTON(toggle_view_btn), GTK_RELIEF_NONE);
+ toggle_view_arrow=gtk_arrow_new(GTK_ARROW_DOWN, GTK_SHADOW_OUT);
+ gtk_container_add(GTK_CONTAINER(toggle_view_btn), toggle_view_arrow);
+ gtk_signal_connect(GTK_OBJECT(toggle_view_btn), "clicked",
+ GTK_SIGNAL_FUNC(summary_toggle_view_cb), summaryview);
statlabel_msgs = gtk_label_new("");
gtk_box_pack_end(GTK_BOX(hbox), statlabel_msgs, FALSE, FALSE, 4);
summaryview->statlabel_folder = statlabel_folder;
summaryview->statlabel_select = statlabel_select;
summaryview->statlabel_msgs = statlabel_msgs;
- summaryview->toggle_eventbox = toggle_eventbox;
- summaryview->toggle_arrow = toggle_arrow;
+ summaryview->toggle_view_btn = toggle_view_btn;
+ summaryview->toggle_view_arrow = toggle_view_arrow;
summaryview->popupmenu = popupmenu;
summaryview->popupfactory = popupfactory;
summaryview->msg_is_toggled_on = TRUE;
return FALSE;
}
folder_update_op_count();
- } else
- summary_write_cache(summaryview);
+ } else {
+ /*
+ * CLAWS: summary_show() is responsible for updating the caches.
+ * after filtering inc.c::inc_finished() forces the update of
+ * the cache by indirectly calling summary_show() (by re-selecting
+ * the currently selected mail folder).
+ * this collides with the new filtering system that may have set
+ * any message flag before calling summary_show().
+ * we can prevent this cache-write by checking the opened member
+ * of the folderview. if this is NULL, the folderview forced
+ * an update of the summary view.
+ */
+ if (summaryview->folderview->opened)
+ summary_write_cache(summaryview);
+ }
summaryview->folderview->opened = selected_node;
menu_set_sensitive(ifactory, "/Mark/Mark as unread", TRUE);
menu_set_sensitive(ifactory, "/Mark/Mark as read", TRUE);
- menu_set_sensitive(ifactory, "/Mark/Mark all read", TRUE);
menu_set_sensitive(ifactory, "/Mark/Ignore thread", TRUE);
menu_set_sensitive(ifactory, "/Mark/Unignore thread", TRUE);
void summary_select_next_unread(SummaryView *summaryview)
{
- GtkCTreeNode *node;
+ GtkCTreeNode *node = summaryview->selected;
GtkCTree *ctree = GTK_CTREE(summaryview->ctree);
- node = summary_find_next_unread_msg(summaryview, summaryview->selected);
-
- if (node) {
- gtkut_ctree_expand_parent_all(ctree, node);
- gtk_sctree_unselect_all(GTK_SCTREE(ctree));
- gtk_sctree_select(GTK_SCTREE(ctree), node);
- if (summaryview->displayed == node)
- summaryview->displayed = NULL;
- summary_display_msg(summaryview, node, FALSE);
- } else {
+ while ((node = summary_find_next_unread_msg(summaryview, node)) == NULL) {
AlertValue val;
switch (prefs_common.next_unread_msg_dialog) {
val = alertpanel(_("No more unread messages"),
_("No unread message found. "
"Go to next folder?"),
- _("Yes"), _("No"), NULL);
+ _("Yes"), _("Search again"), _("No"));
break;
case NEXTUNREADMSGDIALOG_ASSUME_YES:
val = G_ALERTDEFAULT;
(GTK_OBJECT(ctree),
"key_press_event");
folderview_select_next_unread(summaryview->folderview);
- }
+ return;
+ } else if (val == G_ALERTALTERNATE)
+ node = NULL;
+ else
+ return;
+ }
+
+ if (node) {
+ gtkut_ctree_expand_parent_all(ctree, node);
+ gtk_sctree_unselect_all(GTK_SCTREE(ctree));
+ gtk_sctree_select(GTK_SCTREE(ctree), node);
+ if (summaryview->displayed == node)
+ summaryview->displayed = NULL;
+ summary_display_msg(summaryview, node, FALSE);
}
}
}
static void summary_toggle_view(SummaryView *summaryview)
+{
+ MainWindow *mainwin = summaryview->mainwin;
+ GtkItemFactory *ifactory;
+
+ if (!mainwin) return;
+
+ ifactory = gtk_item_factory_from_widget(mainwin->menubar);
+ menu_toggle_toggle(ifactory, "/View/Expand Summary View");
+}
+
+void summary_toggle_view_real(SummaryView *summaryview)
{
MainWindow *mainwin = summaryview->mainwin;
union CompositeWin *cwin = &mainwin->win;
GtkWidget *vpaned = NULL;
GtkWidget *container = NULL;
-
+ GtkWidget *toggle_view_btn;
+ GtkWidget *toggle_view_arrow;
+ GtkItemFactory *ifactory = gtk_item_factory_from_widget(mainwin->menubar);
+
switch (mainwin->type) {
case SEPARATE_NONE:
vpaned = cwin->sep_none.vpaned;
gtk_widget_ref(vpaned);
gtkut_container_remove(GTK_CONTAINER(container), vpaned);
gtk_widget_reparent(GTK_WIDGET_PTR(summaryview), container);
- gtk_arrow_set(GTK_ARROW(summaryview->toggle_arrow),
- GTK_ARROW_UP, GTK_SHADOW_OUT);
+
+ gtk_widget_destroy(summaryview->toggle_view_arrow);
+ gtk_widget_destroy(summaryview->toggle_view_btn);
+
+ toggle_view_btn = gtk_button_new();
+ gtk_box_pack_end(GTK_BOX(summaryview->hbox), toggle_view_btn, FALSE, FALSE, 0);
+ gtk_box_reorder_child(GTK_BOX(summaryview->hbox), toggle_view_btn, 0);
+ gtk_button_set_relief(GTK_BUTTON(toggle_view_btn), GTK_RELIEF_NONE);
+ toggle_view_arrow=gtk_arrow_new(GTK_ARROW_UP, GTK_SHADOW_OUT);
+ gtk_container_add(GTK_CONTAINER(toggle_view_btn), toggle_view_arrow);
+ gtk_signal_connect(GTK_OBJECT(toggle_view_btn), "clicked",
+ GTK_SIGNAL_FUNC(summary_toggle_view_cb), summaryview);
+ gtk_widget_show_all(toggle_view_btn);
+ menu_set_sensitive(ifactory, "/View/Expand Message View", FALSE);
} else {
summaryview->msg_is_toggled_on = TRUE;
gtk_widget_reparent(GTK_WIDGET_PTR(summaryview), vpaned);
gtk_container_add(GTK_CONTAINER(container), vpaned);
gtk_widget_unref(vpaned);
- gtk_arrow_set(GTK_ARROW(summaryview->toggle_arrow),
- GTK_ARROW_DOWN, GTK_SHADOW_OUT);
+
+ gtk_widget_destroy(summaryview->toggle_view_arrow);
+ gtk_widget_destroy(summaryview->toggle_view_btn);
+
+ toggle_view_btn = gtk_button_new();
+ gtk_box_pack_end(GTK_BOX(summaryview->hbox), toggle_view_btn, FALSE, FALSE, 0);
+ gtk_box_reorder_child(GTK_BOX(summaryview->hbox), toggle_view_btn, 0);
+ gtk_button_set_relief(GTK_BUTTON(toggle_view_btn), GTK_RELIEF_NONE);
+ toggle_view_arrow=gtk_arrow_new(GTK_ARROW_DOWN, GTK_SHADOW_OUT);
+ gtk_container_add(GTK_CONTAINER(toggle_view_btn), toggle_view_arrow);
+ gtk_signal_connect(GTK_OBJECT(toggle_view_btn), "clicked",
+ GTK_SIGNAL_FUNC(summary_toggle_view_cb), summaryview);
+ gtk_widget_show_all(toggle_view_btn);
+ menu_set_sensitive(ifactory, "/View/Expand Message View", TRUE);
}
gtk_widget_grab_focus(summaryview->ctree);
+
+ summaryview->toggle_view_btn = toggle_view_btn;
+ summaryview->toggle_view_arrow = toggle_view_arrow;
}
static gboolean summary_search_unread_recursive(GtkCTree *ctree,
summary_unlock(summaryview);
- /* CLAWS: summary_show() only valid after having a lock. ideally
- * we want the lock to be context aware... */
- if (global_processing)
- summary_show(summaryview, summaryview->folder_item, FALSE);
+ /*
+ * CLAWS: summary_show() only valid after having a lock. ideally
+ * we want the lock to be context aware...
+ */
+ if (global_processing) {
+ /*
+ * CLAWS: to prevent summary_show to write the cache,
+ * we force an update of the summaryview in a special way,
+ * like inc.c::inc_finished().
+ */
+ folderview_unselect(summaryview->folderview);
+ folderview_select(summaryview->folderview, summaryview->folder_item);
+ }
}
static void summary_filter_func(GtkCTree *ctree, GtkCTreeNode *node,
summaryview->folder_table);
}
+void summary_filter_open(SummaryView *summaryview, PrefsFilterType type)
+{
+ static HeaderEntry hentry[] = {{"List-Id:", NULL, FALSE},
+ {"X-ML-Name:", NULL, FALSE},
+ {"X-List:", NULL, FALSE},
+ {"X-Mailing-list:", NULL, FALSE},
+ {NULL, NULL, FALSE}};
+ enum
+ {
+ H_LIST_ID = 0,
+ H_X_ML_NAME = 1,
+ H_X_LIST = 2,
+ H_X_MAILING_LIST = 3
+ };
+
+ MsgInfo *msginfo;
+ gchar *header = NULL;
+ gchar *key = NULL;
+ FILE *fp;
+
+ if (!summaryview->selected) return;
+
+ msginfo = gtk_ctree_node_get_row_data(GTK_CTREE(summaryview->ctree),
+ summaryview->selected);
+ if (!msginfo) return;
+
+ switch (type) {
+ case FILTER_BY_NONE:
+ break;
+ case FILTER_BY_AUTO:
+ if ((fp = procmsg_open_message(msginfo)) == NULL) return;
+ procheader_get_header_fields(fp, hentry);
+ fclose(fp);
+
+ if (hentry[H_LIST_ID].body != NULL) {
+ header = "List-Id";
+ Xstrdup_a(key, hentry[H_LIST_ID].body, );
+ } else if (hentry[H_X_ML_NAME].body != NULL) {
+ header = "X-ML-Name";
+ Xstrdup_a(key, hentry[H_X_ML_NAME].body, );
+ } else if (hentry[H_X_LIST].body != NULL) {
+ header = "X-List";
+ Xstrdup_a(key, hentry[H_X_LIST].body, );
+ } else if (hentry[H_X_MAILING_LIST].body != NULL) {
+ header = "X-Mailing-list";
+ Xstrdup_a(key, hentry[H_X_MAILING_LIST].body, );
+ } else if (msginfo->subject) {
+ header = "Subject";
+ key = msginfo->subject;
+ }
+
+ g_free(hentry[H_LIST_ID].body);
+ hentry[H_LIST_ID].body = NULL;
+ g_free(hentry[H_X_ML_NAME].body);
+ hentry[H_X_ML_NAME].body = NULL;
+ g_free(hentry[H_X_LIST].body);
+ hentry[H_X_LIST].body = NULL;
+ g_free(hentry[H_X_MAILING_LIST].body);
+ hentry[H_X_MAILING_LIST].body = NULL;
+
+ break;
+ case FILTER_BY_FROM:
+ header = "From";
+ key = msginfo->from;
+ break;
+ case FILTER_BY_TO:
+ header = "To";
+ key = msginfo->to;
+ break;
+ case FILTER_BY_SUBJECT:
+ header = "Subject";
+ key = msginfo->subject;
+ break;
+ default:
+ break;
+ }
+
+ prefs_filter_open(header, key);
+}
+
/* color label */
#define N_COLOR_LABELS colorlabel_get_color_count()
/* callback functions */
-static void summary_toggle_pressed(GtkWidget *eventbox, GdkEventButton *event,
- SummaryView *summaryview)
+static void summary_toggle_view_cb(GtkWidget *button,
+ gpointer data)
{
- if (!event)
- return;
-
+ SummaryView *summaryview = (SummaryView *) data;
+
if (!summaryview->msg_is_toggled_on && summaryview->selected)
summary_display_msg(summaryview, summaryview->selected, FALSE);
else
FALSE))
summary_select_next_unread(summaryview);
break;
- case GDK_v: /* Toggle summary mode / message mode */
- case GDK_V:
- BREAK_ON_MODIFIER_KEY();
-
- if (!summaryview->msg_is_toggled_on && summaryview->selected)
- summary_display_msg(summaryview,
- summaryview->selected, FALSE);
- else
- summary_toggle_view(summaryview);
- break;
case GDK_Return: /* Scroll up/down one line */
if (summaryview->displayed != summaryview->selected) {
summary_display_msg(summaryview,
BREAK_ON_MODIFIER_KEY();
summary_delete(summaryview);
break;
+ case GDK_asterisk: /* Mark */
+ summary_mark(summaryview);
+ break;
+ case GDK_exclam: /* Mark as unread */
+ summary_mark_as_unread(summaryview);
+ break;
+ case GDK_BackSpace: /* Page up */
+ textview_scroll_page(summaryview->messageview->textview, TRUE);
+ break;
default:
break;
}