d0c2ef99f5f9e2f95e4bbbc8cffc946dc5fb078e
[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         GtkCMCTree *ctree = GTK_CMCTREE(folderview->ctree);
55         FolderItem *item;
56         gchar *url;
57
58         debug_print("RSSyl: new_feed_cb\n");
59
60         g_return_if_fail(folderview->selected != NULL);
61
62         item = gtk_cmctree_node_get_row_data(ctree, folderview->selected);
63         g_return_if_fail(item != NULL);
64         g_return_if_fail(item->folder != NULL);
65
66         url = input_dialog(_("Subscribe feed"),
67                         _("Input the URL of the news feed you wish to subscribe:"),
68                         "");
69         if( url == NULL )       /* User cancelled */
70                 return;
71
72         rssyl_subscribe(item, url, TRUE);
73
74         g_free(url);
75 }
76
77 void rssyl_new_folder_cb(GtkAction *action,
78                 gpointer data)
79 {
80         FolderView *folderview = (FolderView*)data;
81         GtkCMCTree *ctree = GTK_CMCTREE(folderview->ctree);
82         FolderItem *item;
83         FolderItem *new_item;
84         gchar *new_folder, *p, *tmp;
85         gint i = 1;
86
87         if (!folderview->selected) return;
88
89         item = gtk_cmctree_node_get_row_data(ctree, folderview->selected);
90         g_return_if_fail(item != NULL);
91         g_return_if_fail(item->folder != NULL);
92
93         new_folder = input_dialog(_("New folder"),
94                                   _("Input the name of new folder:"),
95                                   _("NewFolder"));
96         if (!new_folder) return;
97
98         p = strchr(new_folder, G_DIR_SEPARATOR);
99         if (p) {
100                 alertpanel_error(_("'%c' can't be used in folder name."),
101                                  G_DIR_SEPARATOR);
102                 g_free(new_folder);
103                 return;
104         }
105
106         /* Find an unused name for new folder */
107         /* TODO: Perhaps stop after X attempts? */
108         tmp = g_strdup(new_folder);
109         while (folder_find_child_item_by_name(item, tmp)) {
110                 debug_print("RSSyl: Folder '%s' already exists, trying another name\n",
111                                 new_folder);
112                 g_free(tmp);
113                 tmp = g_strdup_printf("%s__%d", new_folder, ++i);
114         }
115
116         g_free(new_folder);
117         new_folder = tmp;
118
119         new_item = folder_create_folder(item, new_folder);
120         if (!new_item) {
121                 alertpanel_error(_("Can't create the folder '%s'."), new_folder);
122                 g_free(new_folder);
123                 return;
124         }
125
126         g_free(new_folder);
127
128         folder_write_list();
129 }
130
131 void rssyl_remove_folder_cb(GtkAction *action,
132                              gpointer data)
133 {
134         FolderView *folderview = (FolderView*)data;
135         GtkCMCTree *ctree = GTK_CMCTREE(folderview->ctree);
136         FolderItem *item;
137         gchar *message, *name;
138         AlertValue avalue;
139         gchar *old_id;
140
141         item = folderview_get_selected_item(folderview);
142         g_return_if_fail(item != NULL);
143         g_return_if_fail(item->path != NULL);
144         g_return_if_fail(item->folder != NULL);
145
146         name = trim_string(item->name, 32);
147         AUTORELEASE_STR(name, {g_free(name); return;});
148         message = g_strdup_printf
149                 (_("All folders and messages under '%s' will be permanently deleted. "
150                    "Recovery will not be possible.\n\n"
151                    "Do you really want to delete?"), name);
152         avalue = alertpanel_full(_("Delete folder"), message,
153                                  GTK_STOCK_CANCEL, GTK_STOCK_DELETE, NULL, FALSE,
154                                  NULL, ALERT_WARNING, G_ALERTDEFAULT);
155         g_free(message);
156         if (avalue != G_ALERTALTERNATE) return;
157
158         old_id = folder_item_get_identifier(item);
159
160         if (folderview->opened == folderview->selected ||
161             gtk_cmctree_is_ancestor(ctree,
162                                   folderview->selected,
163                                   folderview->opened)) {
164                 summary_clear_all(folderview->summaryview);
165                 folderview->opened = NULL;
166         }
167
168         if (item->folder->klass->remove_folder(item->folder, item) < 0) {
169                 folder_item_scan(item);
170                 alertpanel_error(_("Can't remove the folder '%s'."), name);
171                 g_free(old_id);
172                 return;
173         }
174
175         folder_write_list();
176
177         prefs_filtering_delete_path(old_id);
178         g_free(old_id);
179
180 }
181
182 void rssyl_rename_cb(GtkAction *action,
183                              gpointer *data)
184 {
185         FolderItem *item;
186         gchar *new_folder;
187         gchar *name;
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         name = trim_string(item->name, 32);
196         message = g_strdup_printf(_("Input new name for '%s':"), name);
197         new_folder = input_dialog(_("Rename folder"), message, name);
198         g_free(message);
199         g_free(name);
200         if (!new_folder) return;
201         AUTORELEASE_STR(new_folder, {g_free(new_folder); return;});
202
203         if (strchr(new_folder, G_DIR_SEPARATOR) != NULL) {
204                 alertpanel_error(_("'%c' can't be included in folder name."),
205                                  G_DIR_SEPARATOR);
206                 return;
207         }
208
209         if (folder_find_child_item_by_name(folder_item_parent(item), new_folder)) {
210                 name = trim_string(new_folder, 32);
211                 alertpanel_error(_("The folder '%s' already exists."), name);
212                 g_free(name);
213                 return;
214         }
215
216         if (folder_item_rename(item, new_folder) < 0) {
217                 alertpanel_error(_("The folder could not be renamed.\n"
218                                    "The new folder name is not allowed."));
219                 return;
220         }
221
222         folder_item_prefs_save_config(item);
223         folder_write_list();
224 }
225
226 void rssyl_refresh_feed_cb(GtkAction *action,
227                 gpointer data)
228 {
229         FolderView *folderview = (FolderView*)data;
230         FolderItem *item = NULL;
231         RFolderItem *ritem = NULL;
232
233         item = folderview_get_selected_item(folderview);
234         g_return_if_fail(item != NULL);
235         g_return_if_fail(item->folder != NULL);
236
237         ritem = (RFolderItem *)item;
238
239         /* Offline check */
240         if( prefs_common.work_offline &&
241                         !inc_offline_should_override(TRUE,
242                                         ngettext("Claws-Mail needs network access in order "
243                                         "to update the feed.",
244                                         "Claws-Mail needs network access in order "
245                                         "to update feeds.", 1))) {
246                 return;
247         }
248
249         /* Update feed, displaying errors if any. */
250         rssyl_update_feed(ritem, TRUE);
251 }
252
253 void rssyl_prop_cb(GtkAction *action, gpointer data)
254 {
255         FolderView *folderview = (FolderView*)data;
256         FolderItem *item;
257         RFolderItem *ritem;
258
259         item = folderview_get_selected_item(folderview);
260         g_return_if_fail(item != NULL);
261         g_return_if_fail(item->folder != NULL);
262
263         debug_print("RSSyl: rssyl_prop_cb() for '%s'\n", item->name);
264
265         ritem = (RFolderItem *)item;
266
267         rssyl_gtk_prop(ritem);
268 }
269
270 void rssyl_update_all_cb( GtkAction *action, gpointer data)
271 {
272         FolderItem *item;
273         FolderView *folderview = (FolderView*)data;
274
275         item = folderview_get_selected_item(folderview);
276         g_return_if_fail(item != NULL);
277         g_return_if_fail(item->folder != NULL);
278
279         debug_print("RSSyl: rssyl_update_all_cb(): clicked on '%s'\n", item->name);
280
281         if( item->folder->klass != rssyl_folder_get_class() ) {
282                 debug_print("RSSyl: this is not a RSSyl folder, returning\n");
283                 return;
284         }
285
286         rssyl_update_recursively(item);
287 }
288
289 void rssyl_remove_mailbox_cb(GtkAction *action, gpointer data)
290 {
291         FolderView *folderview = (FolderView *)data;
292         FolderItem *item = NULL;
293         gchar *n, *message;
294         AlertValue avalue;
295
296         item = folderview_get_selected_item(folderview);
297
298         g_return_if_fail(item != NULL);
299         g_return_if_fail(item->folder != NULL);
300
301         if( folder_item_parent(item) )
302                 return;
303
304         n = trim_string(item->folder->name, 32);
305         message = g_strdup_printf(_("Really remove the feed tree `%s' ?\n"), n);
306         avalue = alertpanel_full(_("Remove feed tree"), message,
307                                  GTK_STOCK_CANCEL, _("_Remove"), NULL, FALSE,
308                                  NULL, ALERT_WARNING, G_ALERTDEFAULT);
309         g_free(message);
310         g_free(n);
311
312         if( avalue != G_ALERTALTERNATE )
313                 return;
314
315         folderview_unselect(folderview);
316         summary_clear_all(folderview->summaryview);
317
318         n = folder_item_get_path(item);
319         if( remove_dir_recursive(n) < 0 ) {
320                 g_warning("can't remove directory '%s'\n", n);
321                 g_free(n);
322                 return;
323         }
324
325         g_free(n);
326         folder_destroy(item->folder);
327 }
328
329 void rssyl_import_feed_list_cb(GtkAction *action, gpointer data)
330 {
331         FolderView *folderview = (FolderView *)data;
332         GtkCMCTree *ctree = GTK_CMCTREE(folderview->ctree);
333         FolderItem *item = NULL;
334         gchar *path = NULL;
335         OPMLImportCtx *ctx = NULL;
336
337         debug_print("RSSyl: import_feed_list_cb\n");
338
339         /* Ask user for a file to import */
340         path = filesel_select_file_open_with_filter(
341                         _("Select an OPML file"), NULL, "*.opml");
342         if (!is_file_exist(path)) {
343                 g_free(path);
344                 return;
345         }
346
347         /* Find the destination folder for the import */
348         g_return_if_fail(folderview->selected != NULL);
349         item = gtk_cmctree_node_get_row_data(ctree, folderview->selected);
350         g_return_if_fail(item != NULL);
351         g_return_if_fail(item->folder != NULL);
352
353         ctx = malloc( sizeof(OPMLImportCtx) );
354         ctx->failures = 0;
355         ctx->depth = rssyl_folder_depth(item);
356         ctx->current = NULL;
357         ctx->current = g_slist_append(ctx->current, item);
358
359         /* Start the whole shebang - call libfeed's OPML parser with correct
360          * user function */
361         opml_process(path, rssyl_opml_import_func, (gpointer)ctx);
362
363         g_free(ctx);
364 }