71bd27bca4ffbee5cba12e74e4ee1854305c9dec
[claws.git] / src / plugins / rssyl / rssyl_cb_menu.c
1 /*
2  * Claws Mail -- a GTK+ based, lightweight, and fast e-mail client
3  * Copyright (C) 1999-2004 Hiroyuki Yamamoto
4  * This file (C) 2005 Andrej Kacian <andrej@kacian.sk>
5  *
6  * - callback handler functions for folderview rssyl context menu items
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21  */
22
23 #ifdef HAVE_CONFIG_H
24 #  include "config.h"
25 #endif
26
27 /* Global includes */
28 #include <glib.h>
29 #include <glib/gi18n.h>
30 #include <gtk/gtk.h>
31
32 /* Claws Mail includes */
33 #include <folderview.h>
34 #include <alertpanel.h>
35 #include <gtk/inputdialog.h>
36 #include <prefs_common.h>
37 #include <folder_item_prefs.h>
38 #include <filesel.h>
39 #include <inc.h>
40
41 /* Local includes */
42 #include "libfeed/parser_opml.h"
43 #include "rssyl_gtk.h"
44 #include "rssyl_feed.h"
45 #include "rssyl_feed_props.h"
46 #include "rssyl_update_feed.h"
47 #include "rssyl_subscribe.h"
48 #include "opml_import.h"
49
50 void rssyl_new_feed_cb(GtkAction *action,
51                 gpointer data)
52 {
53         FolderView *folderview = (FolderView*)data;
54         FolderItem *item;
55         gchar *url;
56
57         debug_print("RSSyl: new_feed_cb\n");
58
59         g_return_if_fail(folderview->selected != NULL);
60
61         item = folderview_get_selected_item(folderview);
62         g_return_if_fail(item != NULL);
63         g_return_if_fail(item->folder != NULL);
64
65         url = input_dialog(_("Subscribe feed"),
66                         _("Input the URL of the news feed you wish to subscribe:"),
67                         "");
68         if( url == NULL )       /* User cancelled */
69                 return;
70
71         rssyl_subscribe(item, url, RSSYL_SHOW_ERRORS | RSSYL_SHOW_RENAME_DIALOG);
72
73         g_free(url);
74 }
75
76 void rssyl_new_folder_cb(GtkAction *action,
77                 gpointer data)
78 {
79         FolderView *folderview = (FolderView*)data;
80         FolderItem *item;
81         FolderItem *new_item;
82         gchar *new_folder, *p, *tmp;
83         gint i = 1;
84
85         if (!folderview->selected) return;
86
87         item = folderview_get_selected_item(folderview);
88         g_return_if_fail(item != NULL);
89         g_return_if_fail(item->folder != NULL);
90
91         new_folder = input_dialog(_("New folder"),
92                                   _("Input the name of new folder:"),
93                                   _("NewFolder"));
94         if (!new_folder) return;
95
96         p = strchr(new_folder, G_DIR_SEPARATOR);
97         if (p) {
98                 alertpanel_error(_("'%c' can't be used in folder name."),
99                                  G_DIR_SEPARATOR);
100                 g_free(new_folder);
101                 return;
102         }
103
104         if (!folder_local_name_ok(new_folder)) {
105                 g_free(new_folder);
106                 return;
107         }
108
109         /* Find an unused name for new folder */
110         /* TODO: Perhaps stop after X attempts? */
111         tmp = g_strdup(new_folder);
112         while (folder_find_child_item_by_name(item, tmp)) {
113                 debug_print("RSSyl: Folder '%s' already exists, trying another name\n",
114                                 new_folder);
115                 g_free(tmp);
116                 tmp = g_strdup_printf("%s__%d", new_folder, ++i);
117         }
118
119         g_free(new_folder);
120         new_folder = tmp;
121
122         new_item = folder_create_folder(item, new_folder);
123         if (!new_item) {
124                 alertpanel_error(_("Can't create the folder '%s'."), new_folder);
125                 g_free(new_folder);
126                 return;
127         }
128
129         g_free(new_folder);
130
131         folder_write_list();
132 }
133
134 void rssyl_remove_folder_cb(GtkAction *action,
135                              gpointer data)
136 {
137         FolderView *folderview = (FolderView*)data;
138         FolderItem *item, *opened;
139         gchar *message, *name;
140         AlertValue avalue;
141         gchar *old_id;
142
143         item = folderview_get_selected_item(folderview);
144         g_return_if_fail(item != NULL);
145         g_return_if_fail(item->path != NULL);
146         g_return_if_fail(item->folder != NULL);
147         opened = folderview_get_opened_item(folderview);
148
149         name = trim_string(item->name, 32);
150         AUTORELEASE_STR(name, {g_free(name); return;});
151         message = g_strdup_printf
152                 (_("All folders and messages under '%s' will be permanently deleted. "
153                    "Recovery will not be possible.\n\n"
154                    "Do you really want to delete?"), name);
155         avalue = alertpanel_full(_("Delete folder"), message,
156                                  GTK_STOCK_CANCEL, GTK_STOCK_DELETE, NULL, ALERTFOCUS_FIRST, FALSE,
157                                  NULL, ALERT_WARNING);
158         g_free(message);
159         if (avalue != G_ALERTALTERNATE) return;
160
161         old_id = folder_item_get_identifier(item);
162
163         if (item == opened ||
164                         folder_is_child_of(item, opened)) {
165                 summary_clear_all(folderview->summaryview);
166                 folderview_close_opened(folderview, TRUE);
167         }
168
169         if (item->folder->klass->remove_folder(item->folder, item) < 0) {
170                 folder_item_scan(item);
171                 alertpanel_error(_("Can't remove the folder '%s'."), name);
172                 g_free(old_id);
173                 return;
174         }
175
176         folder_write_list();
177
178         prefs_filtering_delete_path(old_id);
179         g_free(old_id);
180
181 }
182
183 void rssyl_rename_cb(GtkAction *action,
184                              gpointer *data)
185 {
186         FolderItem *item;
187         gchar *new_folder;
188         gchar *message;
189         FolderView *folderview = (FolderView*)data;
190         item = folderview_get_selected_item(folderview);
191         g_return_if_fail(item != NULL);
192         g_return_if_fail(item->path != NULL);
193         g_return_if_fail(item->folder != NULL);
194
195         message = g_strdup_printf(_("Input new name for '%s':"), item->name);
196         new_folder = input_dialog(_("Rename folder"), message, item->name);
197         g_free(message);
198         if (!new_folder) return;
199
200         if (strchr(new_folder, G_DIR_SEPARATOR) != NULL) {
201                 alertpanel_error(_("'%c' can't be included in folder name."),
202                                  G_DIR_SEPARATOR);
203                 g_free(new_folder);
204                 return;
205         }
206
207         if (!folder_local_name_ok(new_folder)) {
208                 g_free(new_folder);
209                 return;
210         }
211
212         if (folder_find_child_item_by_name(folder_item_parent(item), new_folder)) {
213                 alertpanel_error(_("The folder '%s' already exists."), new_folder);
214                 g_free(new_folder);
215                 return;
216         }
217
218         if (folder_item_rename(item, new_folder) < 0) {
219                 alertpanel_error(_("The folder could not be renamed.\n"
220                                    "The new folder name is not allowed."));
221                 g_free(new_folder);
222                 return;
223         }
224         g_free(new_folder);
225
226         folder_item_prefs_save_config(item);
227         folder_write_list();
228 }
229
230 void rssyl_refresh_feed_cb(GtkAction *action,
231                 gpointer data)
232 {
233         FolderView *folderview = (FolderView*)data;
234         FolderItem *item = NULL;
235         RFolderItem *ritem = NULL;
236
237         item = folderview_get_selected_item(folderview);
238         g_return_if_fail(item != NULL);
239         g_return_if_fail(item->folder != NULL);
240
241         ritem = (RFolderItem *)item;
242
243         /* Offline check */
244         if( prefs_common_get_prefs()->work_offline &&
245                         !inc_offline_should_override(TRUE,
246                                         ngettext("Claws Mail needs network access in order "
247                                         "to update the feed.",
248                                         "Claws Mail needs network access in order "
249                                         "to update feeds.", 1))) {
250                 return;
251         }
252
253         /* Update feed, displaying errors if any. */
254         rssyl_update_feed(ritem, RSSYL_SHOW_ERRORS);
255 }
256
257 void rssyl_prop_cb(GtkAction *action, gpointer data)
258 {
259         FolderView *folderview = (FolderView*)data;
260         FolderItem *item;
261         RFolderItem *ritem;
262
263         item = folderview_get_selected_item(folderview);
264         g_return_if_fail(item != NULL);
265         g_return_if_fail(item->folder != NULL);
266
267         debug_print("RSSyl: rssyl_prop_cb() for '%s'\n", item->name);
268
269         ritem = (RFolderItem *)item;
270
271         rssyl_gtk_prop(ritem);
272 }
273
274 void rssyl_update_all_cb( GtkAction *action, gpointer data)
275 {
276         FolderItem *item;
277         FolderView *folderview = (FolderView*)data;
278
279         item = folderview_get_selected_item(folderview);
280         g_return_if_fail(item != NULL);
281         g_return_if_fail(item->folder != NULL);
282
283         debug_print("RSSyl: rssyl_update_all_cb(): clicked on '%s'\n", item->name);
284
285         if( item->folder->klass != rssyl_folder_get_class() ) {
286                 debug_print("RSSyl: this is not a RSSyl folder, returning\n");
287                 return;
288         }
289
290         /* Offline check */
291         if( prefs_common_get_prefs()->work_offline &&
292                         !inc_offline_should_override(TRUE,
293                                         ngettext("Claws Mail needs network access in order "
294                                         "to update the feed.",
295                                         "Claws Mail needs network access in order "
296                                         "to update feeds.", 1))) {
297                 return;
298         }
299
300         rssyl_update_recursively(item);
301 }
302
303 void rssyl_remove_mailbox_cb(GtkAction *action, gpointer data)
304 {
305         FolderView *folderview = (FolderView *)data;
306         FolderItem *item = NULL;
307         gchar *n, *message;
308         AlertValue avalue;
309
310         item = folderview_get_selected_item(folderview);
311
312         g_return_if_fail(item != NULL);
313         g_return_if_fail(item->folder != NULL);
314
315         if( folder_item_parent(item) )
316                 return;
317
318         n = trim_string(item->folder->name, 32);
319         message = g_strdup_printf(_("Really remove the feed tree `%s' ?\n"), n);
320         avalue = alertpanel_full(_("Remove feed tree"), message,
321                                  GTK_STOCK_CANCEL, _("_Remove"), NULL, ALERTFOCUS_FIRST, FALSE,
322                                  NULL, ALERT_WARNING);
323         g_free(message);
324         g_free(n);
325
326         if( avalue != G_ALERTALTERNATE )
327                 return;
328
329         folderview_unselect(folderview);
330         summary_clear_all(folderview->summaryview);
331
332         n = folder_item_get_path(item);
333         if( remove_dir_recursive(n) < 0 ) {
334                 g_warning("can't remove directory '%s'", n);
335                 g_free(n);
336                 return;
337         }
338
339         g_free(n);
340         folder_destroy(item->folder);
341 }
342
343 void rssyl_import_feed_list_cb(GtkAction *action, gpointer data)
344 {
345         FolderView *folderview = (FolderView *)data;
346         FolderItem *item = NULL;
347         gchar *path = NULL;
348         OPMLImportCtx *ctx = NULL;
349
350         debug_print("RSSyl: import_feed_list_cb\n");
351
352         /* Ask user for a file to import */
353         path = filesel_select_file_open_with_filter(
354                         _("Select an OPML file"), NULL, "*.opml");
355         if (!is_file_exist(path)) {
356                 g_free(path);
357                 return;
358         }
359
360         /* Find the destination folder for the import */
361         g_return_if_fail(folderview->selected != NULL);
362         item = folderview_get_selected_item(folderview);
363         g_return_if_fail(item != NULL);
364         g_return_if_fail(item->folder != NULL);
365
366         ctx = malloc( sizeof(OPMLImportCtx) );
367         ctx->failures = 0;
368         ctx->depth = rssyl_folder_depth(item) + 1;
369         ctx->current = NULL;
370         ctx->current = g_slist_append(ctx->current, item);
371
372         /* Start the whole shebang - call libfeed's OPML parser with correct
373          * user function */
374         opml_process(path, rssyl_opml_import_func, (gpointer)ctx);
375
376         g_free(ctx);
377 }