2 * Sylpheed -- 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/>.
23 #include "prefs_common.h"
24 #include "folderutils.h"
25 #include "prefs_account.h"
27 #include "mainwindow.h"
28 #include "summaryview.h"
30 gint
folderutils_delete_duplicates(FolderItem
*item
,
31 DeleteDuplicatesMode mode
)
34 GSList
*msglist
, *cur
, *duplist
= NULL
;
37 if (item
->folder
->klass
->remove_msg
== NULL
)
40 debug_print("Deleting duplicated messages...\n");
42 msglist
= folder_item_get_msg_list(item
);
45 table
= g_hash_table_new(g_str_hash
, g_str_equal
);
47 folder_item_update_freeze();
48 for (cur
= msglist
; cur
!= NULL
; cur
= g_slist_next(cur
)) {
49 MsgInfo
*msginfo
= (MsgInfo
*) cur
->data
;
50 MsgInfo
*msginfo_dup
= NULL
;
52 if (!msginfo
|| !msginfo
->msgid
|| !*msginfo
->msgid
)
55 msginfo_dup
= g_hash_table_lookup(table
, msginfo
->msgid
);
56 if (msginfo_dup
== NULL
)
57 g_hash_table_insert(table
, msginfo
->msgid
, msginfo
);
59 if ((MSG_IS_UNREAD(msginfo
->flags
) && !MSG_IS_UNREAD(msginfo_dup
->flags
)) ||
60 (MSG_IS_UNREAD(msginfo
->flags
) == MSG_IS_UNREAD(msginfo_dup
->flags
))) {
61 duplist
= g_slist_prepend(duplist
, msginfo
);
63 duplist
= g_slist_prepend(duplist
, msginfo_dup
);
64 g_hash_table_insert(table
, msginfo
->msgid
, msginfo
);
71 case DELETE_DUPLICATES_REMOVE
: {
72 FolderItem
*trash
= NULL
;
73 gboolean in_trash
= FALSE
;
76 if (NULL
!= (ac
= account_find_from_item(item
))) {
77 trash
= account_get_special_folder(ac
, F_TRASH
);
78 in_trash
= (trash
!= NULL
&& trash
== item
);
81 trash
= item
->folder
->trash
;
83 if (folder_has_parent_of_type(item
, F_TRASH
) || trash
== NULL
|| in_trash
)
84 folder_item_remove_msgs(item
, duplist
);
86 folder_item_move_msgs(trash
, duplist
);
89 case DELETE_DUPLICATES_SETFLAG
:
90 for (cur
= duplist
; cur
!= NULL
; cur
= g_slist_next(cur
)) {
91 MsgInfo
*msginfo
= (MsgInfo
*) cur
->data
;
93 procmsg_msginfo_set_to_folder(msginfo
, NULL
);
94 procmsg_msginfo_unset_flags(msginfo
, MSG_MARKED
,
95 MSG_MOVE
| MSG_COPY
| MSG_MOVE_DONE
);
96 procmsg_msginfo_set_flags(msginfo
, MSG_DELETED
, 0);
103 dups
= g_slist_length(duplist
);
104 g_slist_free(duplist
);
106 g_hash_table_destroy(table
);
108 for (cur
= msglist
; cur
!= NULL
; cur
= g_slist_next(cur
)) {
109 MsgInfo
*msginfo
= (MsgInfo
*) cur
->data
;
111 procmsg_msginfo_free(&msginfo
);
113 g_slist_free(msglist
);
115 folder_item_update_thaw();
117 debug_print("done.\n");
122 void folderutils_mark_all_read(FolderItem
*item
)
124 MsgInfoList
*msglist
, *cur
;
125 MainWindow
*mainwin
= mainwindow_get_mainwindow();
127 debug_print("marking all read in item %s\n", (item
==NULL
)?"NULL":item
->name
);
128 cm_return_if_fail(item
!= NULL
);
131 folder_item_update_freeze();
132 if (mainwin
&& mainwin
->summaryview
&&
133 mainwin
->summaryview
->folder_item
== item
) {
134 debug_print("folder opened, using summary\n");
135 summary_mark_all_read(mainwin
->summaryview
, FALSE
);
137 msglist
= folder_item_get_msg_list(item
);
138 debug_print("got msglist %p\n", msglist
);
139 if (msglist
== NULL
) {
140 folder_item_update_thaw();
143 folder_item_set_batch(item
, TRUE
);
144 for (cur
= msglist
; cur
!= NULL
; cur
= g_slist_next(cur
)) {
145 MsgInfo
*msginfo
= cur
->data
;
147 if (msginfo
->flags
.perm_flags
& (MSG_NEW
| MSG_UNREAD
)) {
148 procmsg_msginfo_unset_flags(msginfo
, MSG_NEW
| MSG_UNREAD
, 0);
152 procmsg_msginfo_free(&msginfo
);
154 folder_item_set_batch(item
, FALSE
);
155 folder_item_close(item
);
156 debug_print("marked %d messages out of %d as read\n", m
, i
);
157 g_slist_free(msglist
);
159 folder_item_update_thaw();
162 void folderutils_mark_all_unread(FolderItem
*item
)
164 MsgInfoList
*msglist
, *cur
;
165 MainWindow
*mainwin
= mainwindow_get_mainwindow();
167 debug_print("marking all unread in item %s\n", (item
==NULL
)?"NULL":item
->name
);
168 cm_return_if_fail(item
!= NULL
);
171 folder_item_update_freeze();
172 if (mainwin
&& mainwin
->summaryview
&&
173 mainwin
->summaryview
->folder_item
== item
) {
174 debug_print("folder opened, using summary\n");
175 summary_mark_all_unread(mainwin
->summaryview
, FALSE
);
177 msglist
= folder_item_get_msg_list(item
);
178 debug_print("got msglist %p\n", msglist
);
179 if (msglist
== NULL
) {
180 folder_item_update_thaw();
183 folder_item_set_batch(item
, TRUE
);
184 for (cur
= msglist
; cur
!= NULL
; cur
= g_slist_next(cur
)) {
185 MsgInfo
*msginfo
= cur
->data
;
187 if (!(msginfo
->flags
.perm_flags
& MSG_UNREAD
)) {
188 procmsg_msginfo_set_flags(msginfo
, MSG_UNREAD
, 0);
192 procmsg_msginfo_free(&msginfo
);
194 folder_item_set_batch(item
, FALSE
);
195 folder_item_close(item
);
196 debug_print("marked %d messages out of %d as unread\n", m
, i
);
197 g_slist_free(msglist
);
199 folder_item_update_thaw();
202 void folderutils_mark_all_read_recursive(FolderItem
*item
)
206 cm_return_if_fail(item
!= NULL
);
208 folderutils_mark_all_read(item
);
210 cm_return_if_fail(item
->folder
!= NULL
);
211 cm_return_if_fail(item
->folder
->node
!= NULL
);
213 node
= item
->folder
->node
;
214 node
= g_node_find(node
, G_PRE_ORDER
, G_TRAVERSE_ALL
, item
);
215 node
= node
->children
;
217 while (node
!= NULL
) {
218 if (node
->data
!= NULL
) {
219 FolderItem
*sub_item
= (FolderItem
*) node
->data
;
221 folderutils_mark_all_read_recursive(sub_item
);
226 void folderutils_mark_all_unread_recursive(FolderItem
*item
)
230 cm_return_if_fail(item
!= NULL
);
232 folderutils_mark_all_unread(item
);
234 cm_return_if_fail(item
->folder
!= NULL
);
235 cm_return_if_fail(item
->folder
->node
!= NULL
);
237 node
= item
->folder
->node
;
238 node
= g_node_find(node
, G_PRE_ORDER
, G_TRAVERSE_ALL
, item
);
239 node
= node
->children
;
241 while (node
!= NULL
) {
242 if (node
->data
!= NULL
) {
243 FolderItem
*sub_item
= (FolderItem
*) node
->data
;
245 folderutils_mark_all_unread_recursive(sub_item
);