2 * Claws Mail -- a GTK based, lightweight, and fast e-mail client
3 * Copyright (C) 2004-2012 Hiroyuki Yamamoto & The Claws Mail Team
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 3 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
25 #include "prefs_common.h"
26 #include "folderutils.h"
27 #include "prefs_account.h"
29 #include "mainwindow.h"
30 #include "summaryview.h"
32 static gboolean
folderutils_mark_all_read_node_func(GNode
*node
, gpointer data
);
35 gint
folderutils_delete_duplicates(FolderItem
*item
,
36 DeleteDuplicatesMode mode
)
39 GSList
*msglist
, *cur
, *duplist
= NULL
;
42 if (item
->folder
->klass
->remove_msg
== NULL
)
45 debug_print("Deleting duplicated messages...\n");
47 msglist
= folder_item_get_msg_list(item
);
50 table
= g_hash_table_new(g_str_hash
, g_str_equal
);
52 folder_item_update_freeze();
53 for (cur
= msglist
; cur
!= NULL
; cur
= g_slist_next(cur
)) {
54 MsgInfo
*msginfo
= (MsgInfo
*) cur
->data
;
55 MsgInfo
*msginfo_dup
= NULL
;
57 if (!msginfo
|| !msginfo
->msgid
|| !*msginfo
->msgid
)
60 msginfo_dup
= g_hash_table_lookup(table
, msginfo
->msgid
);
61 if (msginfo_dup
== NULL
)
62 g_hash_table_insert(table
, msginfo
->msgid
, msginfo
);
64 if ((MSG_IS_UNREAD(msginfo
->flags
) && !MSG_IS_UNREAD(msginfo_dup
->flags
)) ||
65 (MSG_IS_UNREAD(msginfo
->flags
) == MSG_IS_UNREAD(msginfo_dup
->flags
))) {
66 duplist
= g_slist_prepend(duplist
, msginfo
);
68 duplist
= g_slist_prepend(duplist
, msginfo_dup
);
69 g_hash_table_insert(table
, msginfo
->msgid
, msginfo
);
76 case DELETE_DUPLICATES_REMOVE
: {
77 FolderItem
*trash
= NULL
;
78 gboolean in_trash
= FALSE
;
81 if (NULL
!= (ac
= account_find_from_item(item
))) {
82 trash
= account_get_special_folder(ac
, F_TRASH
);
83 in_trash
= (trash
!= NULL
&& trash
== item
);
86 trash
= item
->folder
->trash
;
88 if (folder_has_parent_of_type(item
, F_TRASH
) || trash
== NULL
|| in_trash
)
89 folder_item_remove_msgs(item
, duplist
);
91 folder_item_move_msgs(trash
, duplist
);
94 case DELETE_DUPLICATES_SETFLAG
:
95 for (cur
= duplist
; cur
!= NULL
; cur
= g_slist_next(cur
)) {
96 MsgInfo
*msginfo
= (MsgInfo
*) cur
->data
;
98 procmsg_msginfo_set_to_folder(msginfo
, NULL
);
99 procmsg_msginfo_unset_flags(msginfo
, MSG_MARKED
,
100 MSG_MOVE
| MSG_COPY
| MSG_MOVE_DONE
);
101 procmsg_msginfo_set_flags(msginfo
, MSG_DELETED
, 0);
108 dups
= g_slist_length(duplist
);
109 g_slist_free(duplist
);
111 g_hash_table_destroy(table
);
113 for (cur
= msglist
; cur
!= NULL
; cur
= g_slist_next(cur
)) {
114 MsgInfo
*msginfo
= (MsgInfo
*) cur
->data
;
116 procmsg_msginfo_free(&msginfo
);
118 g_slist_free(msglist
);
120 folder_item_update_thaw();
122 debug_print("done.\n");
127 void folderutils_mark_all_read(FolderItem
*item
, gboolean mark_as_read
)
129 MsgInfoList
*msglist
, *cur
;
130 MainWindow
*mainwin
= mainwindow_get_mainwindow();
132 gchar
*msg
= mark_as_read
?"read":"unread";
133 void(*summary_mark_func
)(SummaryView
*, gboolean
) =
134 mark_as_read
?summary_mark_all_read
:summary_mark_all_unread
;
136 debug_print("marking all %s in item %s\n", msg
, (item
==NULL
)?"NULL":item
->name
);
137 cm_return_if_fail(item
!= NULL
);
139 folder_item_update_freeze();
140 if (mainwin
&& mainwin
->summaryview
&&
141 mainwin
->summaryview
->folder_item
== item
) {
142 debug_print("folder opened, using summary\n");
143 summary_mark_func(mainwin
->summaryview
, FALSE
);
145 msglist
= folder_item_get_msg_list(item
);
146 debug_print("got msglist %p\n", msglist
);
147 if (msglist
== NULL
) {
148 folder_item_update_thaw();
151 folder_item_set_batch(item
, TRUE
);
152 for (cur
= msglist
; cur
!= NULL
; cur
= g_slist_next(cur
)) {
153 MsgInfo
*msginfo
= cur
->data
;
156 if (msginfo
->flags
.perm_flags
& (MSG_NEW
| MSG_UNREAD
)) {
157 procmsg_msginfo_unset_flags(msginfo
, MSG_NEW
| MSG_UNREAD
, 0);
161 if (!(msginfo
->flags
.perm_flags
& MSG_UNREAD
)) {
162 procmsg_msginfo_set_flags(msginfo
, MSG_UNREAD
, 0);
167 procmsg_msginfo_free(&msginfo
);
169 folder_item_set_batch(item
, FALSE
);
170 folder_item_close(item
);
171 debug_print("marked %d messages out of %d as %s\n", m
, i
, msg
);
172 g_slist_free(msglist
);
174 folder_item_update_thaw();
177 static gboolean
folderutils_mark_all_read_node_func(GNode
*node
, gpointer data
)
180 FolderItem
*sub_item
= (FolderItem
*) node
->data
;
181 if (prefs_common
.run_processingrules_before_mark_all
)
182 folderview_run_processing(sub_item
);
183 folderutils_mark_all_read(sub_item
, (gboolean
) GPOINTER_TO_INT(data
));
188 void folderutils_mark_all_read_recursive(FolderItem
*item
, gboolean mark_as_read
)
190 cm_return_if_fail(item
!= NULL
);
192 cm_return_if_fail(item
->folder
!= NULL
);
193 cm_return_if_fail(item
->folder
->node
!= NULL
);
195 g_node_traverse(item
->node
, G_PRE_ORDER
, G_TRAVERSE_ALL
, -1,
196 folderutils_mark_all_read_node_func
,
197 GINT_TO_POINTER(mark_as_read
));