2006-09-13 [colin] 2.4.0cvs185
[claws.git] / src / summaryview.c
index ccbb6aec033f26dfee33914a7b882a51cf3a87ce..dc224dc24f6162093c25f945751e6c44c19dc592 100644 (file)
@@ -230,8 +230,6 @@ static void summary_execute_delete_func     (GtkCTree               *ctree,
                                         gpointer                data);
 
 static void summary_thread_init                (SummaryView            *summaryview);
-static void summary_ignore_thread      (SummaryView            *summaryview);
-static void summary_unignore_thread     (SummaryView            *summaryview);
 
 static void summary_unthread_for_exec          (SummaryView    *summaryview);
 static void summary_unthread_for_exec_func     (GtkCTree       *ctree,
@@ -850,6 +848,36 @@ static gboolean summaryview_quicksearch_recurse(gpointer data)
        return FALSE;
 }
 
+static gboolean summary_check_consistency(FolderItem *item, GSList *mlist)
+{
+       int u = 0, n = 0, m = 0, t = 0;
+       GSList *cur;
+       START_TIMING("consistency check");
+       for(cur = mlist ; cur != NULL && cur->data != NULL ; cur = g_slist_next(cur)) {
+               MsgInfo * msginfo = (MsgInfo *) cur->data;
+               t++;
+               if (MSG_IS_NEW(msginfo->flags))
+                       n++;
+               if (MSG_IS_UNREAD(msginfo->flags))
+                       u++;
+               if (MSG_IS_MARKED(msginfo->flags))
+                       m++;            
+       }
+       if (t != item->total_msgs
+       ||  n != item->new_msgs
+       ||  u != item->unread_msgs
+       ||  m != item->marked_msgs
+       ||  (m == 0 && item->unreadmarked_msgs != 0)
+       ||  item->unreadmarked_msgs < 0) {
+               debug_print("Inconsistency\n");
+               folder_item_scan_full(item, FALSE);
+               END_TIMING();
+               return FALSE;
+       } 
+       END_TIMING();
+       return TRUE;
+}
+
 gboolean summary_show(SummaryView *summaryview, FolderItem *item)
 {
        GtkCTree *ctree = GTK_CTREE(summaryview->ctree);
@@ -968,6 +996,12 @@ START_TIMING("--------- summary_show");
 
        mlist = folder_item_get_msg_list(item);
 
+       if (!summary_check_consistency(item, mlist)) {
+               debug_print("reloading due to inconsistency\n");
+               procmsg_msg_list_free(mlist);
+               mlist = folder_item_get_msg_list(item);
+       }
+
        if (summaryview->folder_item->hide_read_msgs &&
            quicksearch_is_active(summaryview->quicksearch) == FALSE) {
                GSList *not_killed;
@@ -1366,6 +1400,7 @@ void summary_set_menu_sensitive(SummaryView *summaryview)
                {"/Mark/Mark as unread"         , M_TARGET_EXIST},
                {"/Mark/Mark all read"          , M_TARGET_EXIST},
                {"/Mark/Ignore thread"          , M_TARGET_EXIST},
+               {"/Mark/Unignore thread"        , M_TARGET_EXIST},
                {"/Mark/Lock"                   , M_TARGET_EXIST},
                {"/Mark/Unlock"                 , M_TARGET_EXIST},
                {"/Mark/Mark as spam"           , M_TARGET_EXIST|M_CAN_LEARN_SPAM},
@@ -1757,6 +1792,34 @@ void summary_select_by_msgnum(SummaryView *summaryview, guint msgnum)
        summary_select_node(summaryview, node, FALSE, TRUE);
 }
 
+typedef struct _PostponedSelectData
+{
+       GtkCTree *ctree;
+       GtkCTreeNode *row;
+       GtkCTreeNode *node;
+       GtkScrollType type;
+       gint column;
+       SummaryView *summaryview;
+       gboolean display_msg;
+       gboolean do_refresh;
+} PostponedSelectData;
+
+static gboolean summary_select_retry(void *data)
+{
+       PostponedSelectData *psdata = (PostponedSelectData *)data;
+       debug_print("trying again\n");
+       if (psdata->row)
+               summary_selected(psdata->ctree, psdata->row,
+                           psdata->column, psdata->summaryview);
+       else if (psdata->node)
+               summary_select_node(psdata->summaryview, psdata->node,
+                           psdata->display_msg, psdata->do_refresh);
+       else
+               summary_step(psdata->summaryview, psdata->type);
+       g_free(psdata);
+       return FALSE;
+}
+
 /**
  * summary_select_node:
  * @summaryview: Summary view.
@@ -1773,8 +1836,28 @@ void summary_select_node(SummaryView *summaryview, GtkCTreeNode *node,
                         gboolean display_msg, gboolean do_refresh)
 {
        GtkCTree *ctree = GTK_CTREE(summaryview->ctree);
-       if (summary_is_locked(summaryview))
+       
+       if (summary_is_locked(summaryview)
+       && !GTK_SCTREE(ctree)->selecting_range
+       && summaryview->messageview->mimeview
+       && summaryview->messageview->mimeview->type == MIMEVIEW_TEXT
+       && summaryview->messageview->mimeview->textview->loading) {
+               PostponedSelectData *data = g_new0(PostponedSelectData, 1);
+               summaryview->messageview->mimeview->textview->stop_loading = TRUE;
+               
+               data->ctree = ctree;
+               data->row = NULL;
+               data->node = node;
+               data->summaryview = summaryview;
+               data->display_msg = display_msg;
+               data->do_refresh = do_refresh;
+               debug_print("postponing open of message till end of load\n");
+               g_timeout_add(100, summary_select_retry, data);
+               return;
+       }
+       if (summary_is_locked(summaryview)) {
                return;
+       }
        if (!summaryview->folder_item)
                return;
        if (node) {
@@ -2949,7 +3032,25 @@ gboolean summary_step(SummaryView *summaryview, GtkScrollType type)
        GtkCTree *ctree = GTK_CTREE(summaryview->ctree);
        GtkCTreeNode *node;
 
-       if (summary_is_locked(summaryview)) return FALSE;
+       if (summary_is_locked(summaryview)
+       && !GTK_SCTREE(ctree)->selecting_range
+       && summaryview->messageview->mimeview
+       && summaryview->messageview->mimeview->type == MIMEVIEW_TEXT
+       && summaryview->messageview->mimeview->textview->loading) {
+               PostponedSelectData *data = g_new0(PostponedSelectData, 1);
+               summaryview->messageview->mimeview->textview->stop_loading = TRUE;
+               
+               data->ctree = ctree;
+               data->row = NULL;
+               data->node = NULL;
+               data->type = type;
+               data->summaryview = summaryview;
+               debug_print("postponing open of message till end of load\n");
+               g_timeout_add(100, summary_select_retry, data);
+               return FALSE;
+       }
+       if (summary_is_locked(summaryview))
+               return FALSE;
        if (type == GTK_SCROLL_STEP_FORWARD) {
                node = gtkut_ctree_node_next(ctree, summaryview->selected);
                if (node)
@@ -3953,21 +4054,6 @@ void summary_save_as(SummaryView *summaryview)
        g_free(tmp);
 }
 
-#ifdef USE_GNOMEPRINT
-static void print_mimeview(MimeView *mimeview) 
-{
-       if (!mimeview 
-       ||  !mimeview->textview
-       ||  !mimeview->textview->text)
-               alertpanel_warning(_("Cannot print: the message doesn't "
-                                    "contain text."));
-       else {
-               gtk_widget_realize(mimeview->textview->text);
-               gedit_print(GTK_TEXT_VIEW(mimeview->textview->text));
-       }
-}
-#endif
-
 void summary_print(SummaryView *summaryview)
 {
        GtkCList *clist = GTK_CLIST(summaryview->ctree);
@@ -4008,23 +4094,10 @@ void summary_print(SummaryView *summaryview)
             cur != NULL && cur->data != NULL; 
             cur = cur->next) {
                GtkCTreeNode *node = GTK_CTREE_NODE(cur->data);
-               if (node != summaryview->displayed) {
-                       MessageView *tmpview = messageview_create(
-                                               summaryview->mainwin);
-                       MsgInfo *msginfo = gtk_ctree_node_get_row_data(
-                                               GTK_CTREE(summaryview->ctree),
-                                               node);
-
-                       messageview_init(tmpview);
-                       tmpview->all_headers = summaryview->messageview->all_headers;
-                       if (msginfo && messageview_show(tmpview, msginfo, 
-                               tmpview->all_headers) >= 0) {
-                                       print_mimeview(tmpview->mimeview);
-                       }
-                       messageview_destroy(tmpview);
-               } else {
-                       print_mimeview(summaryview->messageview->mimeview);
-               }
+               MsgInfo *msginfo = gtk_ctree_node_get_row_data(
+                                       GTK_CTREE(summaryview->ctree),
+                                       node);
+               messageview_print(msginfo, summaryview->messageview->all_headers);
        }
 #endif
 }
@@ -4548,7 +4621,7 @@ gboolean summary_filter_get_mode(void)
                        _("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);
+                       _("_Filter"), GTK_STOCK_CANCEL, NULL, TRUE, vbox);
        if ((val & ~G_ALERTDISABLE) != G_ALERTDEFAULT) {
                return FALSE;
        } else if (val & G_ALERTDISABLE)
@@ -4964,6 +5037,8 @@ static GtkWidget *summary_ctree_create(SummaryView *summaryview)
                                     GTK_CTREE_EXPANDER_TRIANGLE);
        }
 
+       gtk_sctree_set_stripes(GTK_SCTREE(ctree), prefs_common.use_stripes_in_summaries);
+
        gtk_ctree_set_indent(GTK_CTREE(ctree), 12);
        g_object_set_data(G_OBJECT(ctree), "summaryview", (gpointer)summaryview); 
 
@@ -5135,12 +5210,61 @@ static gboolean summary_key_pressed(GtkWidget *widget, GdkEventKey *event,
        GtkAdjustment *adj;
        gboolean mod_pressed;
 
-       if (summary_is_locked(summaryview)) return TRUE;
-       if (!event) return TRUE;
+       if (!event) 
+               return TRUE;
 
        if (quicksearch_has_focus(summaryview->quicksearch))
                return FALSE;
 
+       messageview = summaryview->messageview;
+       textview = messageview->mimeview->textview;
+
+       mod_pressed =
+               ((event->state & (GDK_SHIFT_MASK|GDK_MOD1_MASK)) != 0);
+
+       if (summaryview->selected) {
+               gboolean handled = FALSE;
+               switch (event->keyval) {
+               case GDK_space:         /* Page down or go to the next */
+                       handled = TRUE;
+                       if (event->state & GDK_SHIFT_MASK) 
+                               mimeview_scroll_page(messageview->mimeview, TRUE);
+                       else {
+                               if (summaryview->displayed != summaryview->selected) {
+                                       summary_display_msg(summaryview,
+                                                           summaryview->selected);
+                                       break;
+                               }
+                               if (mod_pressed) {
+                                       if (!mimeview_scroll_page(messageview->mimeview, TRUE))
+                                               summary_select_prev_unread(summaryview);
+                               } else {
+                                       if (!mimeview_scroll_page(messageview->mimeview, FALSE))
+                                               summary_select_next_unread(summaryview);
+                               }                               
+                       }
+                       break;
+               case GDK_BackSpace:     /* Page up */
+                       handled = TRUE;
+                       mimeview_scroll_page(messageview->mimeview, TRUE);
+                       break;
+               case GDK_Return:        /* Scroll up/down one line */
+                       handled = TRUE;
+                       if (summaryview->displayed != summaryview->selected) {
+                               summary_display_msg(summaryview,
+                                                   summaryview->selected);
+                               break;
+                       }
+                       mimeview_scroll_one_line(messageview->mimeview, mod_pressed);
+                       break;
+               }
+               
+               if (handled)
+                       return FALSE;
+       }
+       if (summary_is_locked(summaryview)) 
+               return TRUE;
+
        switch (event->keyval) {
        case GDK_Left:          /* Move focus */
                adj = gtk_scrolled_window_get_hadjustment
@@ -5182,42 +5306,7 @@ static gboolean summary_key_pressed(GtkWidget *widget, GdkEventKey *event,
                        return TRUE;
        }
 
-       messageview = summaryview->messageview;
-       textview = messageview->mimeview->textview;
-
-       mod_pressed =
-               ((event->state & (GDK_SHIFT_MASK|GDK_MOD1_MASK)) != 0);
-
        switch (event->keyval) {
-       case GDK_space:         /* Page down or go to the next */
-               if (event->state & GDK_SHIFT_MASK) 
-                       mimeview_scroll_page(messageview->mimeview, TRUE);
-               else {
-                       if (summaryview->displayed != summaryview->selected) {
-                               summary_display_msg(summaryview,
-                                                   summaryview->selected);
-                               break;
-                       }
-                       if (mod_pressed) {
-                               if (!mimeview_scroll_page(messageview->mimeview, TRUE))
-                                       summary_select_prev_unread(summaryview);
-                       } else {
-                               if (!mimeview_scroll_page(messageview->mimeview, FALSE))
-                                       summary_select_next_unread(summaryview);
-                       }                               
-               }
-               break;
-       case GDK_BackSpace:     /* Page up */
-               mimeview_scroll_page(messageview->mimeview, TRUE);
-               break;
-       case GDK_Return:        /* Scroll up/down one line */
-               if (summaryview->displayed != summaryview->selected) {
-                       summary_display_msg(summaryview,
-                                           summaryview->selected);
-                       break;
-               }
-               mimeview_scroll_one_line(messageview->mimeview, mod_pressed);
-               break;
        case GDK_Delete:
                BREAK_ON_MODIFIER_KEY();
                summary_delete_trash(summaryview);
@@ -5308,24 +5397,6 @@ static void summary_unselected(GtkCTree *ctree, GtkCTreeNode *row,
        summary_status_show(summaryview);
 }
 
-typedef struct _PostponedSelectData
-{
-       GtkCTree *ctree;
-       GtkCTreeNode *row;
-       gint column;
-       SummaryView *summaryview;
-} PostponedSelectData;
-
-static gboolean summary_select_retry(void *data)
-{
-       PostponedSelectData *psdata = (PostponedSelectData *)data;
-       debug_print("trying again\n");
-       summary_selected(psdata->ctree, psdata->row,
-                           psdata->column, psdata->summaryview);
-       g_free(psdata);
-       return FALSE;
-}
-
 static void summary_selected(GtkCTree *ctree, GtkCTreeNode *row,
                             gint column, SummaryView *summaryview)
 {
@@ -5342,6 +5413,7 @@ static void summary_selected(GtkCTree *ctree, GtkCTreeNode *row,
                
                data->ctree = ctree;
                data->row = row;
+               data->node = NULL;
                data->column = column;
                data->summaryview = summaryview;
                debug_print("postponing open of message till end of load\n");
@@ -5887,7 +5959,7 @@ static void summary_ignore_thread_func(GtkCTree *ctree, GtkCTreeNode *row, gpoin
            msginfo->msgnum);
 }
 
-static void summary_ignore_thread(SummaryView *summaryview)
+void summary_ignore_thread(SummaryView *summaryview)
 {
        GtkCTree *ctree = GTK_CTREE(summaryview->ctree);
        GList *cur;
@@ -5919,7 +5991,7 @@ static void summary_unignore_thread_func(GtkCTree *ctree, GtkCTreeNode *row, gpo
            msginfo->msgnum);
 }
 
-static void summary_unignore_thread(SummaryView *summaryview)
+void summary_unignore_thread(SummaryView *summaryview)
 {
        GtkCTree *ctree = GTK_CTREE(summaryview->ctree);
        GList *cur;