c4e116c355a73e3f24538304cf63e284121b873b
[claws.git] / src / news_gtk.c
1 /*
2  * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
3  * Copyright (C) 1999-2004 Hiroyuki Yamamoto & the Sylpheed-Claws Team
4  *
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 2 of the License, or
8  * (at your option) any later version.
9  *
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.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18  */
19
20 #ifdef HAVE_CONFIG_H
21 #  include "config.h"
22 #endif
23
24 #include "defs.h"
25
26 #include <glib.h>
27
28 #include <gtk/gtk.h>
29
30 #include "intl.h"
31 #include "utils.h"
32 #include "folder.h"
33 #include "folderview.h"
34 #include "menu.h"
35 #include "account.h"
36 #include "alertpanel.h"
37 #include "grouplistdialog.h"
38 #include "common/hooks.h"
39 #include "inc.h"
40
41 static void subscribe_newsgroup_cb(FolderView *folderview, guint action, GtkWidget *widget);
42 static void unsubscribe_newsgroup_cb(FolderView *folderview, guint action, GtkWidget *widget);
43 static void news_settings_cb(FolderView *folderview, guint action, GtkWidget *widget);
44 static void remove_news_server_cb(FolderView *folderview, guint action, GtkWidget *widget);
45 static void update_tree_cb(FolderView *folderview, guint action, GtkWidget *widget);
46 static void download_cb(FolderView *folderview, guint action, GtkWidget *widget);
47
48 static GtkItemFactoryEntry news_popup_entries[] =
49 {
50         {N_("/_Subscribe to newsgroup..."),     NULL, subscribe_newsgroup_cb,    0, NULL},
51         {N_("/_Unsubscribe newsgroup"),         NULL, unsubscribe_newsgroup_cb,  0, NULL},
52         {N_("/---"),                            NULL, NULL,                      0, "<Separator>"},
53         {N_("/Down_load"),                      NULL, download_cb,               0, NULL},
54         {N_("/---"),                            NULL, NULL,                      0, "<Separator>"},
55         {N_("/_Check for new messages"),        NULL, update_tree_cb,            0, NULL},
56         {N_("/---"),                            NULL, NULL,                      0, "<Separator>"},
57         {N_("/News _account settings"),         NULL, news_settings_cb,          0, NULL},
58         {N_("/Remove _news account"),           NULL, remove_news_server_cb,     0, NULL},
59         {N_("/---"),                            NULL, NULL,                      0, "<Separator>"},
60 };
61
62 static void set_sensitivity(GtkItemFactory *factory, FolderItem *item);
63
64 static FolderViewPopup news_popup =
65 {
66         "news",
67         "<NewsFolder>",
68         NULL,
69         set_sensitivity
70 };
71
72 void news_gtk_init(void)
73 {
74         guint i, n_entries;
75
76         n_entries = sizeof(news_popup_entries) /
77                 sizeof(news_popup_entries[0]);
78         for (i = 0; i < n_entries; i++)
79                 news_popup.entries = g_slist_append(news_popup.entries, &news_popup_entries[i]);
80
81         folderview_register_popup(&news_popup);
82 }
83
84 static void set_sensitivity(GtkItemFactory *factory, FolderItem *item)
85 {
86 #define SET_SENS(name, sens) \
87         menu_set_sensitive(factory, name, sens)
88
89         SET_SENS("/Subscribe to newsgroup...", folder_item_parent(item) == NULL);
90         SET_SENS("/Unsubscribe newsgroup",     folder_item_parent(item) != NULL);
91         SET_SENS("/Remove news account",       folder_item_parent(item) == NULL);
92
93         SET_SENS("/Check for new messages",    folder_item_parent(item) == NULL);
94
95 #undef SET_SENS
96 }
97
98 static void subscribe_newsgroup_cb(FolderView *folderview, guint action, GtkWidget *widget)
99 {
100         GtkCTree *ctree = GTK_CTREE(folderview->ctree);
101         GtkCTreeNode *servernode, *node;
102         Folder *folder;
103         FolderItem *item;
104         FolderItem *rootitem;
105         FolderItem *newitem;
106         GSList *new_subscr;
107         GSList *cur;
108         GNode *gnode;
109
110         if (!folderview->selected) return;
111
112         item = gtk_ctree_node_get_row_data(ctree, folderview->selected);
113         g_return_if_fail(item != NULL);
114         folder = item->folder;
115         g_return_if_fail(folder != NULL);
116         g_return_if_fail(FOLDER_TYPE(folder) == F_NEWS);
117         g_return_if_fail(folder->account != NULL);
118
119         if (GTK_CTREE_ROW(folderview->selected)->parent != NULL)
120                 servernode = GTK_CTREE_ROW(folderview->selected)->parent;
121         else
122                 servernode = folderview->selected;
123
124         rootitem = gtk_ctree_node_get_row_data(ctree, servernode);
125
126         new_subscr = grouplist_dialog(folder);
127
128         /* remove unsubscribed newsgroups */
129         for (gnode = folder->node->children; gnode != NULL; ) {
130                 GNode *next = gnode->next;
131
132                 item = FOLDER_ITEM(gnode->data);
133                 if (g_slist_find_custom(new_subscr, item->path,
134                                         (GCompareFunc)g_strcasecmp) != NULL) {
135                         gnode = next;
136                         continue;
137                 }
138
139                 node = gtk_ctree_find_by_row_data(ctree, servernode, item);
140                 if (!node) {
141                         gnode = next;
142                         continue;
143                 }
144
145                 if (folderview->opened == node) {
146                         summary_clear_all(folderview->summaryview);
147                         folderview->opened = NULL;
148                 }
149
150                 gtk_ctree_remove_node(ctree, node);
151                 folder_item_remove(item);
152
153                 gnode = next;
154         }
155
156         gtk_clist_freeze(GTK_CLIST(ctree));
157
158         /* add subscribed newsgroups */
159         for (cur = new_subscr; cur != NULL; cur = cur->next) {
160                 gchar *name = (gchar *)cur->data;
161                 FolderUpdateData hookdata;
162
163                 if (folder_find_child_item_by_name(rootitem, name) != NULL)
164                         continue;
165
166                 newitem = folder_item_new(folder, name, name);
167                 folder_item_append(rootitem, newitem);
168
169                 hookdata.folder = newitem->folder;
170                 hookdata.update_flags = FOLDER_TREE_CHANGED | FOLDER_ADD_FOLDERITEM;
171                 hookdata.item = newitem;
172                 hooks_invoke(FOLDER_UPDATE_HOOKLIST, &hookdata);
173         }
174
175         gtk_clist_thaw(GTK_CLIST(ctree));
176
177         slist_free_strings(new_subscr);
178         g_slist_free(new_subscr);
179
180         folder_write_list();
181 }
182
183 static void unsubscribe_newsgroup_cb(FolderView *folderview, guint action,
184                                      GtkWidget *widget)
185 {
186         GtkCTree *ctree = GTK_CTREE(folderview->ctree);
187         FolderItem *item;
188         gchar *name;
189         gchar *message;
190         gchar *old_id;
191         AlertValue avalue;
192
193         if (!folderview->selected) return;
194
195         item = gtk_ctree_node_get_row_data(ctree, folderview->selected);
196         g_return_if_fail(item != NULL);
197         g_return_if_fail(item->folder != NULL);
198         g_return_if_fail(FOLDER_TYPE(item->folder) == F_NEWS);
199         g_return_if_fail(item->folder->account != NULL);
200
201         old_id = folder_item_get_identifier(item);
202
203         name = trim_string(item->path, 32);
204         message = g_strdup_printf(_("Really unsubscribe newsgroup `%s'?"), name);
205         avalue = alertpanel(_("Unsubscribe newsgroup"), message,
206                             _("Yes"), _("+No"), NULL);
207         g_free(message);
208         g_free(name);
209         if (avalue != G_ALERTDEFAULT) return;
210
211         if (folderview->opened == folderview->selected) {
212                 summary_clear_all(folderview->summaryview);
213                 folderview->opened = NULL;
214         }
215
216         folder_item_remove(item);
217         folder_write_list();
218         
219         prefs_filtering_delete_path(old_id);
220         g_free(old_id);
221 }
222
223 static void news_settings_cb(FolderView *folderview, guint action, GtkWidget *widget)
224 {
225         FolderItem *item;
226
227         item = folderview_get_selected_item(folderview);
228         if (item == NULL)
229                 return;
230
231         account_open(item->folder->account);
232 }
233
234 static void remove_news_server_cb(FolderView *folderview, guint action,
235                                   GtkWidget *widget)
236 {
237         GtkCTree *ctree = GTK_CTREE(folderview->ctree);
238         FolderItem *item;
239         PrefsAccount *account;
240         gchar *name;
241         gchar *message;
242         AlertValue avalue;
243
244         if (!folderview->selected) return;
245
246         item = gtk_ctree_node_get_row_data(ctree, folderview->selected);
247         g_return_if_fail(item != NULL);
248         g_return_if_fail(item->folder != NULL);
249         g_return_if_fail(FOLDER_TYPE(item->folder) == F_NEWS);
250         g_return_if_fail(item->folder->account != NULL);
251
252         name = trim_string(item->folder->name, 32);
253         message = g_strdup_printf(_("Really delete news account `%s'?"), name);
254         avalue = alertpanel(_("Delete news account"), message,
255                             _("Yes"), _("+No"), NULL);
256         g_free(message);
257         g_free(name);
258
259         if (avalue != G_ALERTDEFAULT) return;
260
261         if (folderview->opened == folderview->selected ||
262             gtk_ctree_is_ancestor(ctree,
263                                   folderview->selected,
264                                   folderview->opened)) {
265                 summary_clear_all(folderview->summaryview);
266                 folderview->opened = NULL;
267         }
268
269         account = item->folder->account;
270         folderview_unselect(folderview);
271         summary_clear_all(folderview->summaryview);
272         folder_destroy(item->folder);
273         account_destroy(account);
274         account_set_menu();
275         main_window_reflect_prefs_all();
276         folder_write_list();
277 }
278
279 static void update_tree_cb(FolderView *folderview, guint action,
280                            GtkWidget *widget)
281 {
282         FolderItem *item;
283
284         item = folderview_get_selected_item(folderview);
285         g_return_if_fail(item != NULL);
286
287         summary_show(folderview->summaryview, NULL);
288
289         g_return_if_fail(item->folder != NULL);
290
291         folderview_check_new(item->folder);
292 }
293
294 static void download_cb(FolderView *folderview, guint action,
295                         GtkWidget *widget)
296 {
297         GtkCTree *ctree = GTK_CTREE(folderview->ctree);
298         MainWindow *mainwin = folderview->mainwin;
299         FolderItem *item;
300
301         if (!folderview->selected) return;
302
303         item = gtk_ctree_node_get_row_data(ctree, folderview->selected);
304         g_return_if_fail(item != NULL);
305         g_return_if_fail(item->folder != NULL);
306 #if 0
307         if (!prefs_common.online_mode) {
308                 if (alertpanel(_("Offline"),
309                                _("You are offline. Go online?"),
310                                _("Yes"), _("No"), NULL) == G_ALERTDEFAULT)
311                         main_window_toggle_online(folderview->mainwin, TRUE);
312                 else
313                         return;
314         }
315 #endif
316         main_window_cursor_wait(mainwin);
317         inc_lock();
318         main_window_lock(mainwin);
319         gtk_widget_set_sensitive(folderview->ctree, FALSE);
320         main_window_progress_on(mainwin);
321         GTK_EVENTS_FLUSH();
322         if (folder_item_fetch_all_msg(item) < 0) {
323                 gchar *name;
324
325                 name = trim_string(item->name, 32);
326                 alertpanel_error(_("Error occurred while downloading messages in `%s'."), name);
327                 g_free(name);
328         }
329         folder_set_ui_func(item->folder, NULL, NULL);
330         main_window_progress_off(mainwin);
331         gtk_widget_set_sensitive(folderview->ctree, TRUE);
332         main_window_unlock(mainwin);
333         inc_unlock();
334         main_window_cursor_normal(mainwin);
335 }