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>
6 * - callback handler functions for folderview rssyl context menu items
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.
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.
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.
29 #include <glib/gi18n.h>
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>
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"
50 void rssyl_new_feed_cb(GtkAction *action,
53 FolderView *folderview = (FolderView*)data;
54 GtkCMCTree *ctree = GTK_CMCTREE(folderview->ctree);
58 debug_print("RSSyl: new_feed_cb\n");
60 g_return_if_fail(folderview->selected != NULL);
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);
66 url = input_dialog(_("Subscribe feed"),
67 _("Input the URL of the news feed you wish to subscribe:"),
69 if( url == NULL ) /* User cancelled */
72 rssyl_subscribe(item, url, TRUE);
77 void rssyl_new_folder_cb(GtkAction *action,
80 FolderView *folderview = (FolderView*)data;
81 GtkCMCTree *ctree = GTK_CMCTREE(folderview->ctree);
84 gchar *new_folder, *p, *tmp;
87 if (!folderview->selected) return;
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);
93 new_folder = input_dialog(_("New folder"),
94 _("Input the name of new folder:"),
96 if (!new_folder) return;
98 p = strchr(new_folder, G_DIR_SEPARATOR);
100 alertpanel_error(_("'%c' can't be used in folder name."),
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",
113 tmp = g_strdup_printf("%s__%d", new_folder, ++i);
119 new_item = folder_create_folder(item, new_folder);
121 alertpanel_error(_("Can't create the folder '%s'."), new_folder);
131 void rssyl_remove_folder_cb(GtkAction *action,
134 FolderView *folderview = (FolderView*)data;
135 GtkCMCTree *ctree = GTK_CMCTREE(folderview->ctree);
137 gchar *message, *name;
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);
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);
156 if (avalue != G_ALERTALTERNATE) return;
158 old_id = folder_item_get_identifier(item);
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;
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);
177 prefs_filtering_delete_path(old_id);
182 void rssyl_rename_cb(GtkAction *action,
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);
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);
200 if (!new_folder) return;
201 AUTORELEASE_STR(new_folder, {g_free(new_folder); return;});
203 if (strchr(new_folder, G_DIR_SEPARATOR) != NULL) {
204 alertpanel_error(_("'%c' can't be included in folder name."),
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);
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."));
222 folder_item_prefs_save_config(item);
226 void rssyl_refresh_feed_cb(GtkAction *action,
229 FolderView *folderview = (FolderView*)data;
230 FolderItem *item = NULL;
231 RFolderItem *ritem = NULL;
233 item = folderview_get_selected_item(folderview);
234 g_return_if_fail(item != NULL);
235 g_return_if_fail(item->folder != NULL);
237 ritem = (RFolderItem *)item;
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))) {
249 /* Update feed, displaying errors if any. */
250 rssyl_update_feed(ritem, TRUE);
253 void rssyl_prop_cb(GtkAction *action, gpointer data)
255 FolderView *folderview = (FolderView*)data;
259 item = folderview_get_selected_item(folderview);
260 g_return_if_fail(item != NULL);
261 g_return_if_fail(item->folder != NULL);
263 debug_print("RSSyl: rssyl_prop_cb() for '%s'\n", item->name);
265 ritem = (RFolderItem *)item;
267 rssyl_gtk_prop(ritem);
270 void rssyl_update_all_cb( GtkAction *action, gpointer data)
273 FolderView *folderview = (FolderView*)data;
275 item = folderview_get_selected_item(folderview);
276 g_return_if_fail(item != NULL);
277 g_return_if_fail(item->folder != NULL);
279 debug_print("RSSyl: rssyl_update_all_cb(): clicked on '%s'\n", item->name);
281 if( item->folder->klass != rssyl_folder_get_class() ) {
282 debug_print("RSSyl: this is not a RSSyl folder, returning\n");
286 rssyl_update_recursively(item);
289 void rssyl_remove_mailbox_cb(GtkAction *action, gpointer data)
291 FolderView *folderview = (FolderView *)data;
292 FolderItem *item = NULL;
296 item = folderview_get_selected_item(folderview);
298 g_return_if_fail(item != NULL);
299 g_return_if_fail(item->folder != NULL);
301 if( folder_item_parent(item) )
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);
312 if( avalue != G_ALERTALTERNATE )
315 folderview_unselect(folderview);
316 summary_clear_all(folderview->summaryview);
318 n = folder_item_get_path(item);
319 if( remove_dir_recursive(n) < 0 ) {
320 g_warning("can't remove directory '%s'\n", n);
326 folder_destroy(item->folder);
329 void rssyl_import_feed_list_cb(GtkAction *action, gpointer data)
331 FolderView *folderview = (FolderView *)data;
332 GtkCMCTree *ctree = GTK_CMCTREE(folderview->ctree);
333 FolderItem *item = NULL;
335 OPMLImportCtx *ctx = NULL;
337 debug_print("RSSyl: import_feed_list_cb\n");
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)) {
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);
353 ctx = malloc( sizeof(OPMLImportCtx) );
355 /* This needs to be +2, since we will be comparing it to depth of
356 * <outline> tag in OPML's XML structure. Topmost outlines are under
357 * <opml> and <body>, hence 2. */
358 ctx->depth = rssyl_folder_depth(item) + 2;
360 ctx->current = g_slist_append(ctx->current, item);
362 /* Start the whole shebang - call libfeed's OPML parser with correct
364 opml_process(path, rssyl_opml_import_func, (gpointer)ctx);