2 * Claws Mail -- a GTK based, lightweight, and fast e-mail client
3 * Copyright (C) 1999-2022 the Claws Mail team and Hiroyuki Yamamoto
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/>.
22 #include "claws-features.h"
28 #include <glib/gi18n.h>
34 #include "folderview.h"
37 #include "alertpanel.h"
38 #include "grouplistdialog.h"
39 #include "prefs_common.h"
41 #include "common/hooks.h"
44 #include "statusbar.h"
45 #include "inputdialog.h"
47 static void subscribe_newsgroup_cb(GtkAction
*action
, gpointer data
);
48 static void unsubscribe_newsgroup_cb(GtkAction
*action
, gpointer data
);
49 static void rename_newsgroup_cb(GtkAction
*action
, gpointer data
);
50 static void update_tree_cb(GtkAction
*action
, gpointer data
);
51 static void download_cb(GtkAction
*action
, gpointer data
);
52 static void sync_cb(GtkAction
*action
, gpointer data
);
54 static GtkActionEntry news_popup_entries
[] =
56 {"FolderViewPopup/Subscribe", NULL
, N_("_Subscribe to newsgroup..."), NULL
, NULL
, G_CALLBACK(subscribe_newsgroup_cb
) },
57 {"FolderViewPopup/Unsubscribe", NULL
, N_("_Unsubscribe newsgroup"), NULL
, NULL
, G_CALLBACK(unsubscribe_newsgroup_cb
) },
59 {"FolderViewPopup/Synchronise", NULL
, N_("Synchronise"), NULL
, NULL
, G_CALLBACK(sync_cb
) },
60 {"FolderViewPopup/DownloadMessages", NULL
, N_("Down_load messages"), NULL
, NULL
, G_CALLBACK(download_cb
) },
61 {"FolderViewPopup/RenameFolder", NULL
, N_("_Rename folder..."), NULL
, NULL
, G_CALLBACK(rename_newsgroup_cb
) },
63 {"FolderViewPopup/CheckNewMessages", NULL
, N_("_Check for new messages"), NULL
, NULL
, G_CALLBACK(update_tree_cb
) },
67 static void set_sensitivity(GtkUIManager
*ui_manager
, FolderItem
*item
);
68 static void add_menuitems(GtkUIManager
*ui_manager
, FolderItem
*item
);
70 static FolderViewPopup news_popup
=
75 G_N_ELEMENTS(news_popup_entries
),
82 void news_gtk_init(void)
84 folderview_register_popup(&news_popup
);
87 static void add_menuitems(GtkUIManager
*ui_manager
, FolderItem
*item
)
89 MENUITEM_ADDUI_MANAGER(ui_manager
, "/Popup/FolderViewPopup", "Subscribe", "FolderViewPopup/Subscribe", GTK_UI_MANAGER_MENUITEM
)
90 MENUITEM_ADDUI_MANAGER(ui_manager
, "/Popup/FolderViewPopup", "Unsubscribe", "FolderViewPopup/Unsubscribe", GTK_UI_MANAGER_MENUITEM
)
91 MENUITEM_ADDUI_MANAGER(ui_manager
, "/Popup/FolderViewPopup", "SeparatorNews1", "FolderViewPopup/---", GTK_UI_MANAGER_SEPARATOR
)
92 MENUITEM_ADDUI_MANAGER(ui_manager
, "/Popup/FolderViewPopup", "Synchronise", "FolderViewPopup/Synchronise", GTK_UI_MANAGER_MENUITEM
)
93 MENUITEM_ADDUI_MANAGER(ui_manager
, "/Popup/FolderViewPopup", "DownloadMessages", "FolderViewPopup/DownloadMessages", GTK_UI_MANAGER_MENUITEM
)
94 MENUITEM_ADDUI_MANAGER(ui_manager
, "/Popup/FolderViewPopup", "RenameFolder", "FolderViewPopup/RenameFolder", GTK_UI_MANAGER_MENUITEM
)
95 MENUITEM_ADDUI_MANAGER(ui_manager
, "/Popup/FolderViewPopup", "SeparatorNews2", "FolderViewPopup/---", GTK_UI_MANAGER_SEPARATOR
)
96 MENUITEM_ADDUI_MANAGER(ui_manager
, "/Popup/FolderViewPopup", "CheckNewMessages", "FolderViewPopup/CheckNewMessages", GTK_UI_MANAGER_MENUITEM
)
97 MENUITEM_ADDUI_MANAGER(ui_manager
, "/Popup/FolderViewPopup", "SeparatorNews3", "FolderViewPopup/---", GTK_UI_MANAGER_SEPARATOR
)
100 static void set_sensitivity(GtkUIManager
*ui_manager
, FolderItem
*item
)
102 MainWindow
*mainwin
= mainwindow_get_mainwindow();
104 #define SET_SENS(name, sens) \
105 cm_menu_set_sensitive_full(ui_manager, "Popup/"name, sens)
107 SET_SENS("FolderViewPopup/Subscribe",
108 folder_item_parent(item
) == NULL
109 && mainwin
->lock_count
== 0
110 && news_folder_locked(item
->folder
) == 0);
111 SET_SENS("FolderViewPopup/Unsubscribe",
112 folder_item_parent(item
) != NULL
113 && mainwin
->lock_count
== 0
114 && news_folder_locked(item
->folder
) == 0);
115 SET_SENS("FolderViewPopup/CheckNewMessages",
116 folder_item_parent(item
) == NULL
117 && mainwin
->lock_count
== 0
118 && news_folder_locked(item
->folder
) == 0);
119 SET_SENS("FolderViewPopup/Synchronise",
120 item
? (folder_item_parent(item
) != NULL
121 && folder_want_synchronise(item
->folder
))
123 SET_SENS("FolderViewPopup/DownloadMessages",
124 item
? (folder_item_parent(item
) != NULL
127 SET_SENS("FolderViewPopup/RenameFolder",
128 folder_item_parent(item
) != NULL
129 && mainwin
->lock_count
== 0
130 && news_folder_locked(item
->folder
) == 0);
134 static FolderItem
*news_find_child_item(FolderItem
*item
, const gchar
*path
)
139 for (node
= item
->node
->children
; node
!= NULL
; node
= node
->next
) {
140 child
= FOLDER_ITEM(node
->data
);
141 if (g_strcmp0(child
->path
, path
) == 0) {
149 static void subscribe_newsgroup_cb(GtkAction
*action
, gpointer data
)
151 FolderView
*folderview
= (FolderView
*)data
;
154 FolderItem
*rootitem
;
159 MainWindow
*mainwin
= mainwindow_get_mainwindow();
161 if ((item
= folderview_get_selected_item(folderview
)) == NULL
) return;
163 if (mainwin
->lock_count
|| news_folder_locked(item
->folder
))
166 folder
= item
->folder
;
167 cm_return_if_fail(folder
!= NULL
);
168 cm_return_if_fail(FOLDER_TYPE(folder
) == F_NEWS
);
169 cm_return_if_fail(folder
->account
!= NULL
);
171 if ((rootitem
= folder_item_parent(item
)) == NULL
)
174 new_subscr
= grouplist_dialog(folder
);
176 /* remove unsubscribed newsgroups */
177 for (gnode
= folder
->node
->children
; gnode
!= NULL
; ) {
178 GNode
*next
= gnode
->next
;
180 item
= FOLDER_ITEM(gnode
->data
);
181 if (g_slist_find_custom(new_subscr
, item
->path
,
182 (GCompareFunc
)g_ascii_strcasecmp
) != NULL
) {
187 if (folderview_get_opened_item(folderview
) == item
) {
188 summary_clear_all(folderview
->summaryview
);
189 folderview_close_opened(folderview
, TRUE
);
192 folderview_remove_item(folderview
, item
);
193 folder_item_remove(item
);
198 folderview_freeze(folderview
);
200 /* add subscribed newsgroups */
201 for (cur
= new_subscr
; cur
!= NULL
; cur
= cur
->next
) {
202 gchar
*name
= (gchar
*)cur
->data
;
203 FolderUpdateData hookdata
;
205 if (news_find_child_item(rootitem
, name
) != NULL
)
208 newitem
= folder_item_new(folder
, name
, name
);
209 folder_item_append(rootitem
, newitem
);
211 hookdata
.folder
= newitem
->folder
;
212 hookdata
.update_flags
= FOLDER_TREE_CHANGED
| FOLDER_ADD_FOLDERITEM
;
213 hookdata
.item
= newitem
;
214 hookdata
.item2
= NULL
;
215 hooks_invoke(FOLDER_UPDATE_HOOKLIST
, &hookdata
);
218 folderview_thaw(folderview
);
220 slist_free_strings_full(new_subscr
);
225 static void unsubscribe_newsgroup_cb(GtkAction
*action
, gpointer data
)
227 FolderView
*folderview
= (FolderView
*)data
;
233 MainWindow
*mainwin
= mainwindow_get_mainwindow();
235 if (!folderview
->selected
) return;
237 item
= folderview_get_selected_item(folderview
);
238 cm_return_if_fail(item
!= NULL
);
240 if (mainwin
->lock_count
|| news_folder_locked(item
->folder
))
243 cm_return_if_fail(item
->folder
!= NULL
);
244 cm_return_if_fail(FOLDER_TYPE(item
->folder
) == F_NEWS
);
245 cm_return_if_fail(item
->folder
->account
!= NULL
);
247 old_id
= folder_item_get_identifier(item
);
249 name
= trim_string(item
->path
, 32);
250 message
= g_strdup_printf(_("Really unsubscribe newsgroup '%s'?"), name
);
251 avalue
= alertpanel_full(_("Unsubscribe newsgroup"), message
,
252 NULL
, _("_Cancel"), NULL
, _("_Unsubscribe"), NULL
, NULL
,
253 ALERTFOCUS_FIRST
, FALSE
, NULL
, ALERT_WARNING
);
256 if (avalue
!= G_ALERTALTERNATE
) {
261 if (item
== folderview_get_opened_item(folderview
)) {
262 summary_clear_all(folderview
->summaryview
);
263 folderview_close_opened(folderview
, TRUE
);
266 if(item
->folder
->klass
->remove_folder(item
->folder
, item
) < 0) {
267 folder_item_scan(item
);
268 alertpanel_error(_("Can't remove the folder '%s'."), name
);
275 prefs_filtering_delete_path(old_id
);
279 static void rename_newsgroup_cb(GtkAction
*action
, gpointer data
)
281 FolderView
*folderview
= (FolderView
*)data
;
287 item
= folderview_get_selected_item(folderview
);
288 cm_return_if_fail(item
!= NULL
);
289 cm_return_if_fail(item
->path
!= NULL
);
290 cm_return_if_fail(item
->folder
!= NULL
);
292 name
= trim_string(item
->name
, 32);
293 message
= g_strdup_printf(_("Input new name for '%s':"), name
);
294 new_folder
= input_dialog(_("Rename newsgroup folder"), message
, item
->name
);
298 if (!new_folder
) return;
299 AUTORELEASE_STR(new_folder
, {g_free(new_folder
); return;});
301 if (strchr(new_folder
, G_DIR_SEPARATOR
) != NULL
) {
302 alertpanel_error(_("'%c' can't be included in folder name."),
307 if (folder_find_child_item_by_name(folder_item_parent(item
), new_folder
)) {
308 name
= trim_string(new_folder
, 32);
309 alertpanel_error(_("The folder '%s' already exists."), name
);
314 if (folder_item_rename(item
, new_folder
) < 0) {
315 alertpanel_error(_("The folder could not be renamed.\n"
316 "The new folder name is not allowed."));
323 static void update_tree_cb(GtkAction
*action
, gpointer data
)
325 FolderView
*folderview
= (FolderView
*)data
;
327 MainWindow
*mainwin
= mainwindow_get_mainwindow();
329 item
= folderview_get_selected_item(folderview
);
330 cm_return_if_fail(item
!= NULL
);
332 if (mainwin
->lock_count
|| news_folder_locked(item
->folder
))
335 summary_show(folderview
->summaryview
, NULL
, FALSE
);
337 cm_return_if_fail(item
->folder
!= NULL
);
339 folderview_check_new(item
->folder
);
342 static void sync_cb(GtkAction
*action
, gpointer data
)
344 FolderView
*folderview
= (FolderView
*)data
;
347 item
= folderview_get_selected_item(folderview
);
348 cm_return_if_fail(item
!= NULL
);
349 folder_synchronise(item
->folder
);
352 void news_gtk_synchronise(FolderItem
*item
, gint days
)
354 MainWindow
*mainwin
= mainwindow_get_mainwindow();
355 FolderView
*folderview
= mainwin
->folderview
;
360 time_t t
= time(NULL
);
362 cm_return_if_fail(item
!= NULL
);
363 cm_return_if_fail(item
->folder
!= NULL
);
365 if (mainwin
->lock_count
|| news_folder_locked(item
->folder
))
368 total
= item
->total_msgs
;
370 main_window_cursor_wait(mainwin
);
372 main_window_lock(mainwin
);
373 gtk_widget_set_sensitive(folderview
->ctree
, FALSE
);
374 main_window_progress_on(mainwin
);
377 mlist
= folder_item_get_msg_list(item
);
378 for (cur
= mlist
; cur
!= NULL
; cur
= cur
->next
) {
379 MsgInfo
*msginfo
= (MsgInfo
*)cur
->data
;
380 gint age
= (t
- msginfo
->date_t
) / (60*60*24);
381 if (days
== 0 || age
<= days
)
382 folder_item_fetch_msg_full(msginfo
->folder
, msginfo
->msgnum
, TRUE
, TRUE
);
383 statusbar_progress_all(num
++,total
, 100);
388 statusbar_progress_all(0,0,0);
389 procmsg_msg_list_free(mlist
);
390 folder_set_ui_func(item
->folder
, NULL
, NULL
);
391 main_window_progress_off(mainwin
);
392 gtk_widget_set_sensitive(folderview
->ctree
, TRUE
);
393 main_window_unlock(mainwin
);
395 main_window_cursor_normal(mainwin
);
398 static void download_cb(GtkAction
*action
, gpointer data
)
400 FolderView
*folderview
= (FolderView
*)data
;
403 if (!folderview
->selected
) return;
405 item
= folderview_get_selected_item(folderview
);
406 news_gtk_synchronise(item
, 0);