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 static gboolean
folderutils_mark_all_read_node_func(GNode
*node
, gpointer data
);
33 gint
folderutils_delete_duplicates(FolderItem
*item
,
34 DeleteDuplicatesMode mode
)
37 GSList
*msglist
, *cur
, *duplist
= NULL
;
40 if (item
->folder
->klass
->remove_msg
== NULL
)
43 debug_print("Deleting duplicated messages...\n");
45 msglist
= folder_item_get_msg_list(item
);
48 table
= g_hash_table_new(g_str_hash
, g_str_equal
);
50 folder_item_update_freeze();
51 for (cur
= msglist
; cur
!= NULL
; cur
= g_slist_next(cur
)) {
52 MsgInfo
*msginfo
= (MsgInfo
*) cur
->data
;
53 MsgInfo
*msginfo_dup
= NULL
;
55 if (!msginfo
|| !msginfo
->msgid
|| !*msginfo
->msgid
)
58 msginfo_dup
= g_hash_table_lookup(table
, msginfo
->msgid
);
59 if (msginfo_dup
== NULL
)
60 g_hash_table_insert(table
, msginfo
->msgid
, msginfo
);
62 if ((MSG_IS_UNREAD(msginfo
->flags
) && !MSG_IS_UNREAD(msginfo_dup
->flags
)) ||
63 (MSG_IS_UNREAD(msginfo
->flags
) == MSG_IS_UNREAD(msginfo_dup
->flags
))) {
64 duplist
= g_slist_prepend(duplist
, msginfo
);
66 duplist
= g_slist_prepend(duplist
, msginfo_dup
);
67 g_hash_table_insert(table
, msginfo
->msgid
, msginfo
);
74 case DELETE_DUPLICATES_REMOVE
: {
75 FolderItem
*trash
= NULL
;
76 gboolean in_trash
= FALSE
;
79 if (NULL
!= (ac
= account_find_from_item(item
))) {
80 trash
= account_get_special_folder(ac
, F_TRASH
);
81 in_trash
= (trash
!= NULL
&& trash
== item
);
84 trash
= item
->folder
->trash
;
86 if (folder_has_parent_of_type(item
, F_TRASH
) || trash
== NULL
|| in_trash
)
87 folder_item_remove_msgs(item
, duplist
);
89 folder_item_move_msgs(trash
, duplist
);
92 case DELETE_DUPLICATES_SETFLAG
:
93 for (cur
= duplist
; cur
!= NULL
; cur
= g_slist_next(cur
)) {
94 MsgInfo
*msginfo
= (MsgInfo
*) cur
->data
;
96 procmsg_msginfo_set_to_folder(msginfo
, NULL
);
97 procmsg_msginfo_unset_flags(msginfo
, MSG_MARKED
,
98 MSG_MOVE
| MSG_COPY
| MSG_MOVE_DONE
);
99 procmsg_msginfo_set_flags(msginfo
, MSG_DELETED
, 0);
106 dups
= g_slist_length(duplist
);
107 g_slist_free(duplist
);
109 g_hash_table_destroy(table
);
111 for (cur
= msglist
; cur
!= NULL
; cur
= g_slist_next(cur
)) {
112 MsgInfo
*msginfo
= (MsgInfo
*) cur
->data
;
114 procmsg_msginfo_free(&msginfo
);
116 g_slist_free(msglist
);
118 folder_item_update_thaw();
120 debug_print("done.\n");
125 void folderutils_mark_all_read(FolderItem
*item
, gboolean mark_as_read
)
127 MsgInfoList
*msglist
, *cur
;
128 MainWindow
*mainwin
= mainwindow_get_mainwindow();
130 gchar
*msg
= mark_as_read
?"read":"unread";
131 void(*summary_mark_func
)(SummaryView
*, gboolean
) =
132 mark_as_read
?summary_mark_all_read
:summary_mark_all_unread
;
134 debug_print("marking all %s in item %s\n", msg
, (item
==NULL
)?"NULL":item
->name
);
135 cm_return_if_fail(item
!= NULL
);
137 folder_item_update_freeze();
138 if (mainwin
&& mainwin
->summaryview
&&
139 mainwin
->summaryview
->folder_item
== item
) {
140 debug_print("folder opened, using summary\n");
141 summary_mark_func(mainwin
->summaryview
, FALSE
);
143 msglist
= folder_item_get_msg_list(item
);
144 debug_print("got msglist %p\n", msglist
);
145 if (msglist
== NULL
) {
146 folder_item_update_thaw();
149 folder_item_set_batch(item
, TRUE
);
150 for (cur
= msglist
; cur
!= NULL
; cur
= g_slist_next(cur
)) {
151 MsgInfo
*msginfo
= cur
->data
;
154 if (msginfo
->flags
.perm_flags
& (MSG_NEW
| MSG_UNREAD
)) {
155 procmsg_msginfo_unset_flags(msginfo
, MSG_NEW
| MSG_UNREAD
, 0);
159 if (!(msginfo
->flags
.perm_flags
& MSG_UNREAD
)) {
160 procmsg_msginfo_set_flags(msginfo
, MSG_UNREAD
, 0);
165 procmsg_msginfo_free(&msginfo
);
167 folder_item_set_batch(item
, FALSE
);
168 folder_item_close(item
);
169 debug_print("marked %d messages out of %d as %s\n", m
, i
, msg
);
170 g_slist_free(msglist
);
172 folder_item_update_thaw();
175 static gboolean
folderutils_mark_all_read_node_func(GNode
*node
, gpointer data
)
178 FolderItem
*sub_item
= (FolderItem
*) node
->data
;
179 folderutils_mark_all_read(sub_item
, (gboolean
) GPOINTER_TO_INT(data
));
184 void folderutils_mark_all_read_recursive(FolderItem
*item
, gboolean mark_as_read
)
186 cm_return_if_fail(item
!= NULL
);
188 cm_return_if_fail(item
->folder
!= NULL
);
189 cm_return_if_fail(item
->folder
->node
!= NULL
);
191 g_node_traverse(item
->node
, G_PRE_ORDER
, G_TRAVERSE_ALL
, -1,
192 folderutils_mark_all_read_node_func
,
193 GINT_TO_POINTER(mark_as_read
));