make 'next_on_delete' hidden pref apply after trashing or moving a msg in addition...
[claws.git] / src / summaryview.c
index aace5d56ddf1c7b545f3e60638ca83af478ce77e..4a519df1a11c1d7e26af8ccb461181fa93c40edc 100644 (file)
@@ -1,6 +1,6 @@
 /*
- * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 1999-2013 Hiroyuki Yamamoto and the Claws Mail team
+ * Claws Mail -- a GTK+ based, lightweight, and fast e-mail client
+ * Copyright (C) 1999-2016 Hiroyuki Yamamoto and the Claws Mail team
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -14,7 +14,6 @@
  *
  * You should have received a copy of the GNU General Public License
  * along with this program. If not, see <http://www.gnu.org/licenses/>.
- * 
  */
 
 #include "defs.h"
@@ -58,7 +57,7 @@
 #include "colorlabel.h"
 #include "inc.h"
 #include "imap.h"
-#ifndef USE_NEW_ADDRBOOK
+#ifndef USE_ALT_ADDRBOOK
        #include "addressbook.h"
 #else
        #include "addressbook-dbus.h"
@@ -993,9 +992,7 @@ void summary_init(SummaryView *summaryview)
        summaryview->sort_type = SORT_ASCENDING;
 
        /* Init summaryview extra data */
-#ifndef G_OS_WIN32
        summaryview->simplify_subject_preg = NULL;
-#endif
        summary_clear_list(summaryview);
        summary_set_column_titles(summaryview);
        summary_colorlabel_menu_create(summaryview, FALSE);
@@ -1321,7 +1318,7 @@ gboolean summary_show(SummaryView *summaryview, FolderItem *item)
        buf = NULL;
        if (!item || !item->path || !folder_item_parent(item) || item->no_select) {
                g_free(buf);
-               debug_print("empty folder (%p %s %p %d)\n\n",
+               debug_print("empty folder (%p %s %p %d)\n",
                                item, 
                                (item && item->path)?item->path:"(null)",
                                item?folder_item_parent(item):0x0,
@@ -1411,7 +1408,7 @@ gboolean summary_show(SummaryView *summaryview, FolderItem *item)
                        
                        if (!msginfo->hidden) {
                                if (MSG_IS_DELETED(msginfo->flags) && summaryview->folder_item->hide_del_msgs) {
-                                       procmsg_msginfo_free(msginfo);
+                                       procmsg_msginfo_free(&msginfo);
                                        continue;
                                }
                                if (summaryview->folder_item->hide_read_msgs) {
@@ -1426,12 +1423,12 @@ gboolean summary_show(SummaryView *summaryview, FolderItem *item)
                                                 msginfo->msgnum == displayed_msgnum))
                                                not_killed = g_slist_prepend(not_killed, msginfo);
                                        else
-                                               procmsg_msginfo_free(msginfo);
+                                               procmsg_msginfo_free(&msginfo);
                                } else {
                                        not_killed = g_slist_prepend(not_killed, msginfo);
                                }
                         } else
-                               procmsg_msginfo_free(msginfo);
+                               procmsg_msginfo_free(&msginfo);
                }
                hidden_removed = TRUE;
                g_slist_free(mlist);
@@ -1454,7 +1451,7 @@ gboolean summary_show(SummaryView *summaryview, FolderItem *item)
                        if (!msginfo->hidden)
                                not_killed = g_slist_prepend(not_killed, msginfo);
                        else
-                               procmsg_msginfo_free(msginfo);
+                               procmsg_msginfo_free(&msginfo);
                }
                g_slist_free(mlist);
                mlist = not_killed;
@@ -2502,7 +2499,7 @@ static void summary_free_msginfo_func(GtkCMCTree *ctree, GtkCMCTreeNode *node,
        MsgInfo *msginfo = gtk_cmctree_node_get_row_data(ctree, node);
 
        if (msginfo)
-               procmsg_msginfo_free(msginfo);
+               procmsg_msginfo_free(&msginfo);
 }
 
 static void summary_set_marks_func(GtkCMCTree *ctree, GtkCMCTreeNode *node,
@@ -2680,21 +2677,28 @@ static void summary_status_show(SummaryView *summaryview)
 
                gtk_label_set_text(GTK_LABEL(summaryview->statlabel_msgs), str);
                g_free(str);
-               tooltip = g_strdup_printf(_("<b>Message summary</b>\n"
-                                           "<b>New:</b> %d\n"
-                                           "<b>Unread:</b> %d\n"
-                                           "<b>Total:</b> %d\n"
-                                           "<b>Size:</b> %s\n\n"
-                                           "<b>Marked:</b> %d\n"
-                                           "<b>Replied:</b> %d\n"
-                                           "<b>Forwarded:</b> %d\n"
-                                           "<b>Locked:</b> %d\n"
-                                           "<b>Ignored:</b> %d\n"
-                                           "<b>Watched:</b> %d"),
-                                             n_new, n_unread, n_total,
-                                             to_human_readable((goffset)n_size),
-                                             n_marked,n_replied,n_forwarded,
-                                             n_locked,n_ignored,n_watched);
+               tooltip = g_strdup_printf("<b>%s</b>\n"
+                                       "<b>%s</b> %d\n"
+                                       "<b>%s</b> %d\n"
+                                       "<b>%s</b> %d\n"
+                                       "<b>%s</b> %s\n\n"
+                                       "<b>%s</b> %d\n"
+                                       "<b>%s</b> %d\n"
+                                       "<b>%s</b> %d\n"
+                                       "<b>%s</b> %d\n"
+                                       "<b>%s</b> %d\n"
+                                       "<b>%s</b> %d",
+                                       _("Message summary"),
+                                       _("New:"), n_new,
+                                       _("Unread:"), n_unread,
+                                       _("Total:"), n_total,
+                                       _("Size:"), to_human_readable((goffset)n_size),
+                                       _("Marked:"), n_marked,
+                                       _("Replied:"), n_replied,
+                                       _("Forwarded:"), n_forwarded,
+                                       _("Locked:"), n_locked,
+                                       _("Ignored:"), n_ignored,
+                                       _("Watched:"), n_watched);
 
                gtk_widget_set_tooltip_markup(GTK_WIDGET(summaryview->statlabel_msgs),
                                            tooltip); 
@@ -2946,11 +2950,9 @@ void summary_sort(SummaryView *summaryview,
                cmp_func = (GtkCMCListCompareFunc)summary_cmp_by_from;
                break;
        case SORT_BY_SUBJECT:
-#ifndef G_OS_WIN32
                if (summaryview->simplify_subject_preg)
                        cmp_func = (GtkCMCListCompareFunc)summary_cmp_by_simplified_subject;
                else
-#endif
                        cmp_func = (GtkCMCListCompareFunc)summary_cmp_by_subject;
                break;
        case SORT_BY_SCORE:
@@ -3400,31 +3402,33 @@ static inline void summary_set_header(SummaryView *summaryview, gchar *text[],
                                to_text = to_text ? to_text : _("(No From)");
                        }
                }
-               snprintf(tmp2, BUFFSIZE-1, "--> %s", to_text);
+               snprintf(tmp2, BUFFSIZE-1, " %s", to_text);
                tmp2[BUFFSIZE-1]='\0';
                text[col_pos[S_COL_FROM]] = tmp2;
        }
        
-#ifndef G_OS_WIN32
        if (summaryview->simplify_subject_preg != NULL)
                text[col_pos[S_COL_SUBJECT]] = msginfo->subject ? 
                        string_remove_match(tmp3, BUFFSIZE, msginfo->subject, 
                                        summaryview->simplify_subject_preg) : 
                        _("(No Subject)");
        else 
-#endif
                text[col_pos[S_COL_SUBJECT]] = msginfo->subject ? msginfo->subject :
                        _("(No Subject)");
        if ((vert_layout || small_layout) && prefs_common.two_line_vert) {
                if (!FOLDER_SHOWS_TO_HDR(summaryview->folder_item)) {
-                       gchar *tmp = g_markup_printf_escaped(_("%s\n<span color='%s' style='italic'>From: %s, on %s</span>"),
+                       gchar *tmp = g_markup_printf_escaped(g_strconcat("%s\n",
+                                                                       "<span color='%s' style='italic'>",
+                                                                       _("From: %s, on %s"), "</span>", NULL),
                                        text[col_pos[S_COL_SUBJECT]],
                                        color_dim_rgb,
                                        text[col_pos[S_COL_FROM]],
                                        text[col_pos[S_COL_DATE]]);
                        text[col_pos[S_COL_SUBJECT]] = tmp;
                } else {
-                       gchar *tmp = g_markup_printf_escaped(_("%s\n<span color='%s' style='italic'>To: %s, on %s</span>"),
+                       gchar *tmp = g_markup_printf_escaped(g_strconcat("%s\n",
+                                                                        "<span color='%s' style='italic'>",
+                                                                       _("To: %s, on %s"), "</span>", NULL),
                                        text[col_pos[S_COL_SUBJECT]],
                                        color_dim_rgb,
                                        text[col_pos[S_COL_TO]],
@@ -3555,12 +3559,14 @@ static int msginfo_mark_as_read_timeout(void *data)
        if (!mdata)
                return FALSE;
 
+       summary_lock(mdata->summaryview);
        if (mdata->msginfo == summary_get_selected_msg(mdata->summaryview))
                msginfo_mark_as_read(mdata->summaryview, mdata->msginfo,
                                     mdata->summaryview->selected);
-       procmsg_msginfo_free(mdata->msginfo);
+       procmsg_msginfo_free(&(mdata->msginfo));
 
        mdata->summaryview->mark_as_read_timeout_tag = 0;
+       summary_unlock(mdata->summaryview);
 
        g_free(mdata);
        return FALSE;
@@ -4336,8 +4342,6 @@ static void summary_delete_row(SummaryView *summaryview, GtkCMCTreeNode *row)
        if (!prefs_common.immediate_exec && 
            !folder_has_parent_of_type(summaryview->folder_item, F_TRASH)) {
                summary_set_row_marks(summaryview, row);
-       } else if (summaryview->folder_item->folder->account && !summaryview->folder_item->folder->account->imap_use_trash) {
-               summary_set_row_marks(summaryview, row);
        }
        debug_print("Message %s/%d is set to delete\n",
                    msginfo->folder->path, msginfo->msgnum);
@@ -4389,22 +4393,20 @@ void summary_delete(SummaryView *summaryview)
        
        START_LONG_OPERATION(summaryview, FALSE);
 
-       if (!summaryview->folder_item->folder->account || summaryview->folder_item->folder->account->imap_use_trash) {
-               if (!prefs_common.live_dangerously) {
-                       gchar *buf = NULL;
-                       int 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(_("Delete message(s)"),
-                                         buf,
-                                         GTK_STOCK_CANCEL, "+"GTK_STOCK_DELETE, NULL);
-                       g_free(buf);
-                       if (aval != G_ALERTALTERNATE) {
-                               END_LONG_OPERATION(summaryview);
-                               return;
-                       }
+       if (!prefs_common.live_dangerously) {
+               gchar *buf = NULL;
+               int 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);
+               g_free(buf);
+               if (aval != G_ALERTALTERNATE) {
+                       END_LONG_OPERATION(summaryview);
+                       return;
                }
        }
 
@@ -4466,8 +4468,7 @@ void summary_delete_trash(SummaryView *summaryview)
                to_folder = summaryview->folder_item->folder->trash;
        
        if (to_folder == NULL || to_folder == summaryview->folder_item
-           || folder_has_parent_of_type(summaryview->folder_item, F_TRASH)
-           || (summaryview->folder_item->folder->account && !summaryview->folder_item->folder->account->imap_use_trash))
+           || folder_has_parent_of_type(summaryview->folder_item, F_TRASH))
                summary_delete(summaryview);
        else
                summary_move_selected_to(summaryview, to_folder);
@@ -4544,8 +4545,6 @@ static void summary_move_row_to(SummaryView *summaryview, GtkCMCTreeNode *row,
        
        if (!prefs_common.immediate_exec) {
                summary_set_row_marks(summaryview, row);
-       } else if (msginfo->folder->folder->account && !msginfo->folder->folder->account->imap_use_trash) {
-               summary_set_row_marks(summaryview, row);
        }
 
        debug_print("Message %d is set to move to %s\n",
@@ -4595,11 +4594,11 @@ void summary_move_selected_to(SummaryView *summaryview, FolderItem *to_folder)
                GtkCMCTreeNode *node = NULL;
                if (summaryview->sort_type == SORT_ASCENDING) {
                        node = summary_find_next_msg(summaryview, sel_last);
-                       if (!node)
+                       if (!node || prefs_common.next_on_delete == FALSE)
                                node = summary_find_prev_msg(summaryview, sel_last);
                } else {
                        node = summary_find_prev_msg(summaryview, sel_last);
-                       if (!node)
+                       if (!node || prefs_common.next_on_delete == FALSE)
                                node = summary_find_next_msg(summaryview, sel_last);
                }
                summary_select_node(summaryview, node, summaryview->display_msg, TRUE);
@@ -4727,12 +4726,12 @@ void summary_add_address(SummaryView *summaryview)
        avatarr = avatars_avatarrender_new(full_msginfo);
        hooks_invoke(AVATAR_IMAGE_RENDER_HOOKLIST, avatarr);
 
-       procmsg_msginfo_free(full_msginfo);
+       procmsg_msginfo_free(&full_msginfo);
 
        if (avatarr->image)
                picture = gtk_image_get_pixbuf(GTK_IMAGE(avatarr->image));
 
-#ifndef USE_NEW_ADDRBOOK
+#ifndef USE_ALT_ADDRBOOK
        addressbook_add_contact(msginfo->fromname, from, NULL, picture);
 #else
        if (addressadd_selection(msginfo->fromname, from, NULL, picture)) {
@@ -4965,11 +4964,11 @@ gboolean summary_execute(SummaryView *summaryview)
                        summary_unselect_all(summaryview);
                        if (summaryview->sort_type == SORT_ASCENDING) {
                                new_selected = summary_find_next_msg(summaryview, node);
-                               if (!new_selected)
+                               if (!new_selected || prefs_common.next_on_delete == FALSE)
                                        new_selected = summary_find_prev_msg(summaryview, node);
                        } else {
                                new_selected = summary_find_prev_msg(summaryview, node);
-                               if (!new_selected)
+                               if (!new_selected || prefs_common.next_on_delete == FALSE)
                                        new_selected = summary_find_next_msg(summaryview, node);
                        }
                }
@@ -5118,23 +5117,6 @@ gboolean summary_expunge(SummaryView *summaryview)
        return TRUE;
 }
 
-static void summary_set_deleted_func(GtkCMCTree *ctree, GtkCMCTreeNode *node,
-                                     gpointer data)
-{
-       SummaryView *summaryview = data;
-       MsgInfo *msginfo;
-
-       msginfo = GTKUT_CTREE_NODE_GET_ROW_DATA(node);
-
-       if (msginfo && MSG_IS_MOVE(msginfo->flags)) {
-               msginfo->flags.tmp_flags &= ~ MSG_MOVE;
-               msginfo->flags.perm_flags |= MSG_DELETED;
-               summary_set_row_marks(summaryview, node);
-               summaryview->moved--;
-               summaryview->deleted++;
-       }
-}
-
 static gint summary_execute_move(SummaryView *summaryview)
 {
        GtkCMCTree *ctree = GTK_CMCTREE(summaryview->ctree);
@@ -5153,14 +5135,10 @@ static gint summary_execute_move(SummaryView *summaryview)
                hooks_register_hook(MSGINFO_UPDATE_HOOKLIST, 
                        summary_update_msg, (gpointer) summaryview);
 
-               if (!summaryview->folder_item->folder->account || summaryview->folder_item->folder->account->imap_use_trash) {
-                       for (cur = summaryview->mlist; cur != NULL && cur->data != NULL; cur = cur->next)
-                               procmsg_msginfo_free((MsgInfo *)cur->data);
-               } 
-               if (summaryview->folder_item->folder->account && !summaryview->folder_item->folder->account->imap_use_trash) {
-                       gtk_cmctree_pre_recursive(ctree, NULL, summary_set_deleted_func,
-                                       summaryview);
+               for (cur = summaryview->mlist; cur != NULL && cur->data != NULL; cur = cur->next) {
+                       procmsg_msginfo_free((MsgInfo **)&(cur->data));
                }
+
                g_slist_free(summaryview->mlist);
                summaryview->mlist = NULL;
                return val;
@@ -5179,22 +5157,19 @@ static void summary_execute_move_func(GtkCMCTree *ctree, GtkCMCTreeNode *node,
        if (msginfo && MSG_IS_MOVE(msginfo->flags) && msginfo->to_folder) {
                summaryview->mlist =
                        g_slist_prepend(summaryview->mlist, msginfo);
-               if (!summaryview->folder_item->folder->account || 
-                    summaryview->folder_item->folder->account->imap_use_trash) {
-                       gtk_cmctree_node_set_row_data(ctree, node, NULL);
-
-                       if (msginfo->msgid && *msginfo->msgid &&
-                           node == g_hash_table_lookup(summaryview->msgid_table,
-                                                       msginfo->msgid))
-                               g_hash_table_remove(summaryview->msgid_table,
-                                                   msginfo->msgid);
-                       if (prefs_common.thread_by_subject &&
-                           msginfo->subject && *msginfo->subject && 
-                           node == subject_table_lookup(summaryview->subject_table,
-                                                        msginfo->subject)) {
-                               subject_table_remove(summaryview->subject_table,
-                                                    msginfo->subject);
-                       }
+               gtk_cmctree_node_set_row_data(ctree, node, NULL);
+
+               if (msginfo->msgid && *msginfo->msgid &&
+                   node == g_hash_table_lookup(summaryview->msgid_table,
+                                               msginfo->msgid))
+                       g_hash_table_remove(summaryview->msgid_table,
+                                           msginfo->msgid);
+               if (prefs_common.thread_by_subject &&
+                   msginfo->subject && *msginfo->subject &&
+                   node == subject_table_lookup(summaryview->subject_table,
+                                                msginfo->subject)) {
+                       subject_table_remove(summaryview->subject_table,
+                                            msginfo->subject);
                }
        }
 }
@@ -5217,7 +5192,7 @@ static void summary_execute_copy(SummaryView *summaryview)
                summaryview->mlist = NULL;
        }
        summaryview->msginfo_update_callback_id =
-               hooks_register_hook(MSGINFO_UPDATE_HOOKLIST, 
+               hooks_register_hook(MSGINFO_UPDATE_HOOKLIST,
                        summary_update_msg, (gpointer) summaryview);
 }
 
@@ -5244,10 +5219,9 @@ static void summary_execute_delete(SummaryView *summaryview)
        GSList *cur;
 
        /* search deleting messages and execute */
-       if (!summaryview->folder_item->folder->account || summaryview->folder_item->folder->account->imap_use_trash) {
-               gtk_cmctree_pre_recursive
-                       (ctree, NULL, summary_execute_delete_func, summaryview);
-       }
+       gtk_cmctree_pre_recursive
+               (ctree, NULL, summary_execute_delete_func, summaryview);
+
        if (!summaryview->mlist) return;
 
        hooks_unregister_hook(MSGINFO_UPDATE_HOOKLIST,
@@ -5259,10 +5233,11 @@ static void summary_execute_delete(SummaryView *summaryview)
        summaryview->msginfo_update_callback_id =
                hooks_register_hook(MSGINFO_UPDATE_HOOKLIST, 
                        summary_update_msg, (gpointer) summaryview);
-       if (!summaryview->folder_item->folder->account || summaryview->folder_item->folder->account->imap_use_trash) {
-               for (cur = summaryview->mlist; cur != NULL && cur->data != NULL; cur = cur->next)
-                       procmsg_msginfo_free((MsgInfo *)cur->data);
+
+       for (cur = summaryview->mlist; cur != NULL && cur->data != NULL; cur = cur->next) {
+                       procmsg_msginfo_free((MsgInfo **)&(cur->data));
        }
+
        g_slist_free(summaryview->mlist);
        summaryview->mlist = NULL;
 }
@@ -5342,7 +5317,7 @@ static void summary_execute_expunge(SummaryView *summaryview)
                hooks_register_hook(MSGINFO_UPDATE_HOOKLIST, 
                        summary_update_msg, (gpointer) summaryview);
        for (cur = summaryview->mlist; cur != NULL && cur->data != NULL; cur = cur->next)
-               procmsg_msginfo_free((MsgInfo *)cur->data);
+               procmsg_msginfo_free((MsgInfo **)&(cur->data));
 
        g_slist_free(summaryview->mlist);
        summaryview->mlist = NULL;
@@ -5704,7 +5679,7 @@ void summary_filter(SummaryView *summaryview, gboolean selected_only)
        filtering_move_and_copy_msgs(mlist);
        
        for (cur_list = mlist; cur_list; cur_list = cur_list->next) {
-               procmsg_msginfo_free((MsgInfo *)cur_list->data);
+               procmsg_msginfo_free((MsgInfo **)&(cur_list->data));
        }
        g_slist_free(mlist);
 
@@ -6171,13 +6146,11 @@ static void summary_tags_menu_item_activate_item_cb(GtkMenuItem *menu_item,
 
 void summaryview_destroy(SummaryView *summaryview)
 {
-#ifndef G_OS_WIN32
        if(summaryview->simplify_subject_preg) {
                regfree(summaryview->simplify_subject_preg);
                g_free(summaryview->simplify_subject_preg);
                summaryview->simplify_subject_preg = NULL;
        }
-#endif
 }
 static void summary_tags_menu_item_apply_tags_activate_cb(GtkWidget *widget,
                                                     gpointer data)
@@ -7985,7 +7958,6 @@ void summary_harvest_address(SummaryView *summaryview)
        g_list_free( msgList );
 }
 
-#ifndef G_OS_WIN32
 static regex_t *summary_compile_simplify_regexp(gchar *simplify_subject_regexp)
 {
        int err;
@@ -8005,7 +7977,6 @@ static regex_t *summary_compile_simplify_regexp(gchar *simplify_subject_regexp)
        
        return preg;
 }
-#endif
 void summary_set_prefs_from_folderitem(SummaryView *summaryview, FolderItem *item)
 {
        FolderSortKey sort_key;
@@ -8014,7 +7985,6 @@ void summary_set_prefs_from_folderitem(SummaryView *summaryview, FolderItem *ite
        cm_return_if_fail(item != NULL);
 
        /* Subject simplification */
-#ifndef G_OS_WIN32
        if(summaryview->simplify_subject_preg) {
                regfree(summaryview->simplify_subject_preg);
                g_free(summaryview->simplify_subject_preg);
@@ -8023,7 +7993,7 @@ void summary_set_prefs_from_folderitem(SummaryView *summaryview, FolderItem *ite
        if(item->prefs && item->prefs->simplify_subject_regexp && 
           item->prefs->simplify_subject_regexp[0] && item->prefs->enable_simplify_subject)
                summaryview->simplify_subject_preg = summary_compile_simplify_regexp(item->prefs->simplify_subject_regexp);
-#endif
+
        /* Sorting */
        sort_key = item->sort_key;
        sort_type = item->sort_type;