2 * Claws Mail -- a GTK based, lightweight, and fast e-mail client
3 * Copyright (C) 2005-2023 the Claws Mail Team and Andrej Kacian <andrej@kacian.sk>
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/>.
25 #include <glib/gi18n.h>
28 /* Claws Mail includes */
29 #include <folderview.h>
30 #include <alertpanel.h>
31 #include <gtk/inputdialog.h>
32 #include <prefs_common.h>
33 #include <folder_item_prefs.h>
38 #include "libfeed/parser_opml.h"
39 #include "rssyl_gtk.h"
40 #include "rssyl_feed.h"
41 #include "rssyl_feed_props.h"
42 #include "rssyl_update_feed.h"
43 #include "rssyl_subscribe.h"
44 #include "opml_import.h"
46 void rssyl_new_feed_cb(GtkAction *action,
49 FolderView *folderview = (FolderView*)data;
52 gchar *clip_text = NULL, *str = NULL;
54 debug_print("RSSyl: new_feed_cb\n");
56 g_return_if_fail(folderview->selected != NULL);
58 item = folderview_get_selected_item(folderview);
59 g_return_if_fail(item != NULL);
60 g_return_if_fail(item->folder != NULL);
62 clip_text = gtk_clipboard_wait_for_text(gtk_clipboard_get(GDK_SELECTION_CLIPBOARD));
66 #if GLIB_CHECK_VERSION(2,66,0)
70 /* skip any leading white-space */
71 while (str && *str && g_ascii_isspace(*str))
73 uri = g_uri_parse(str, G_URI_FLAGS_PARSE_RELAXED, &error);
75 g_warning("could not parse clipboard text for URI: '%s'", error->message);
79 gchar* newstr = g_uri_to_string(uri);
81 debug_print("URI: '%s' -> '%s'\n", str, newstr ? newstr : "N/A");
87 if (!is_uri_string(str)) {
89 /* if no URL, ignore clipboard text */
94 url = input_dialog(_("Subscribe feed"),
95 _("Input the URL of the news feed you wish to subscribe:"),
101 if( url == NULL ) /* User cancelled */
104 rssyl_subscribe(item, url, RSSYL_SHOW_ERRORS | RSSYL_SHOW_RENAME_DIALOG);
109 void rssyl_new_folder_cb(GtkAction *action,
112 FolderView *folderview = (FolderView*)data;
114 FolderItem *new_item;
115 gchar *new_folder, *p, *tmp;
118 if (!folderview->selected) return;
120 item = folderview_get_selected_item(folderview);
121 g_return_if_fail(item != NULL);
122 g_return_if_fail(item->folder != NULL);
124 new_folder = input_dialog(_("New folder"),
125 _("Input the name of new folder:"),
127 if (!new_folder) return;
129 p = strchr(new_folder, G_DIR_SEPARATOR);
131 alertpanel_error(_("'%c' can't be used in folder name."),
137 if (!folder_local_name_ok(new_folder)) {
142 /* Find an unused name for new folder */
143 /* TODO: Perhaps stop after X attempts? */
144 tmp = g_strdup(new_folder);
145 while (folder_find_child_item_by_name(item, tmp)) {
146 debug_print("RSSyl: Folder '%s' already exists, trying another name\n",
149 tmp = g_strdup_printf("%s__%d", new_folder, ++i);
155 new_item = folder_create_folder(item, new_folder);
157 alertpanel_error(_("Can't create the folder '%s'."), new_folder);
167 void rssyl_remove_folder_cb(GtkAction *action,
170 FolderView *folderview = (FolderView*)data;
171 FolderItem *item, *opened;
172 gchar *message, *name;
176 item = folderview_get_selected_item(folderview);
177 g_return_if_fail(item != NULL);
178 g_return_if_fail(item->path != NULL);
179 g_return_if_fail(item->folder != NULL);
180 opened = folderview_get_opened_item(folderview);
182 name = trim_string(item->name, 32);
183 AUTORELEASE_STR(name, {g_free(name); return;});
184 message = g_strdup_printf
185 (_("All folders and messages under '%s' will be permanently deleted.\n"
186 "Recovery will not be possible.\n\n"
187 "Do you really want to delete?"), name);
188 avalue = alertpanel_full(_("Delete folder"), message,
189 NULL, _("_Cancel"), "edit-delete", _("_Delete"),
190 NULL, NULL, ALERTFOCUS_FIRST, FALSE,
191 NULL, ALERT_WARNING);
193 if (avalue != G_ALERTALTERNATE) return;
195 old_id = folder_item_get_identifier(item);
197 if (item == opened ||
198 folder_is_child_of(item, opened)) {
199 summary_clear_all(folderview->summaryview);
200 folderview_close_opened(folderview, TRUE);
203 if (item->folder->klass->remove_folder(item->folder, item) < 0) {
204 folder_item_scan(item);
205 alertpanel_error(_("Can't remove the folder '%s'."), name);
212 prefs_filtering_delete_path(old_id);
217 void rssyl_rename_cb(GtkAction *action,
223 FolderView *folderview = (FolderView*)data;
224 item = folderview_get_selected_item(folderview);
225 g_return_if_fail(item != NULL);
226 g_return_if_fail(item->path != NULL);
227 g_return_if_fail(item->folder != NULL);
229 message = g_strdup_printf(_("Input new name for '%s':"), item->name);
230 new_folder = input_dialog(_("Rename folder"), message, item->name);
232 if (!new_folder) return;
234 if (strchr(new_folder, G_DIR_SEPARATOR) != NULL) {
235 alertpanel_error(_("'%c' can't be included in folder name."),
241 if (!folder_local_name_ok(new_folder)) {
246 if (folder_find_child_item_by_name(folder_item_parent(item), new_folder)) {
247 alertpanel_error(_("The folder '%s' already exists."), new_folder);
252 if (folder_item_rename(item, new_folder) < 0) {
253 alertpanel_error(_("The folder could not be renamed.\n"
254 "The new folder name is not allowed."));
260 folder_item_prefs_save_config(item);
261 prefs_matcher_write_config();
265 void rssyl_refresh_feed_cb(GtkAction *action,
268 FolderView *folderview = (FolderView*)data;
269 FolderItem *item = NULL;
270 RFolderItem *ritem = NULL;
272 item = folderview_get_selected_item(folderview);
273 g_return_if_fail(item != NULL);
274 g_return_if_fail(item->folder != NULL);
276 ritem = (RFolderItem *)item;
279 if( prefs_common_get_prefs()->work_offline &&
280 !inc_offline_should_override(TRUE,
281 ngettext("Claws Mail needs network access in order "
282 "to update the feed.",
283 "Claws Mail needs network access in order "
284 "to update feeds.", 1))) {
288 /* Update feed, displaying errors if any. */
289 rssyl_update_feed(ritem, RSSYL_SHOW_ERRORS);
292 void rssyl_prop_cb(GtkAction *action, gpointer data)
294 FolderView *folderview = (FolderView*)data;
298 item = folderview_get_selected_item(folderview);
299 g_return_if_fail(item != NULL);
300 g_return_if_fail(item->folder != NULL);
302 debug_print("RSSyl: rssyl_prop_cb() for '%s'\n", item->name);
304 ritem = (RFolderItem *)item;
306 rssyl_gtk_prop(ritem);
309 void rssyl_update_all_cb( GtkAction *action, gpointer data)
312 FolderView *folderview = (FolderView*)data;
314 item = folderview_get_selected_item(folderview);
315 g_return_if_fail(item != NULL);
316 g_return_if_fail(item->folder != NULL);
318 debug_print("RSSyl: rssyl_update_all_cb(): clicked on '%s'\n", item->name);
320 if( item->folder->klass != rssyl_folder_get_class() ) {
321 debug_print("RSSyl: this is not a RSSyl folder, returning\n");
326 if( prefs_common_get_prefs()->work_offline &&
327 !inc_offline_should_override(TRUE,
328 ngettext("Claws Mail needs network access in order "
329 "to update the feed.",
330 "Claws Mail needs network access in order "
331 "to update feeds.", 1))) {
335 rssyl_update_recursively(item);
338 void rssyl_remove_mailbox_cb(GtkAction *action, gpointer data)
340 FolderView *folderview = (FolderView *)data;
341 FolderItem *item = NULL;
345 item = folderview_get_selected_item(folderview);
347 g_return_if_fail(item != NULL);
348 g_return_if_fail(item->folder != NULL);
350 if( folder_item_parent(item) )
353 n = trim_string(item->folder->name, 32);
354 message = g_strdup_printf(_("Really remove the feed tree `%s' ?\n"), n);
355 avalue = alertpanel_full(_("Remove feed tree"), message,
356 NULL, _("_Cancel"), "list-remove", _("_Remove"),
357 NULL, NULL, ALERTFOCUS_FIRST, FALSE,
358 NULL, ALERT_WARNING);
362 if( avalue != G_ALERTALTERNATE )
365 folderview_unselect(folderview);
366 summary_clear_all(folderview->summaryview);
368 n = folder_item_get_path(item);
369 if( remove_dir_recursive(n) < 0 ) {
370 g_warning("can't remove directory '%s'", n);
376 folder_destroy(item->folder);
379 void rssyl_import_feed_list_cb(GtkAction *action, gpointer data)
381 FolderView *folderview = (FolderView *)data;
382 FolderItem *item = NULL;
384 OPMLImportCtx *ctx = NULL;
386 debug_print("RSSyl: import_feed_list_cb\n");
388 /* Ask user for a file to import */
389 path = filesel_select_file_open_with_filter(
390 _("Select an OPML file"), NULL, "*.opml");
391 if (!is_file_exist(path)) {
396 /* Find the destination folder for the import */
397 g_return_if_fail(folderview->selected != NULL);
398 item = folderview_get_selected_item(folderview);
399 g_return_if_fail(item != NULL);
400 g_return_if_fail(item->folder != NULL);
402 ctx = g_malloc( sizeof(OPMLImportCtx) );
404 ctx->depth = rssyl_folder_depth(item) + 1;
406 ctx->current = g_slist_append(ctx->current, item);
408 /* Start the whole shebang - call libfeed's OPML parser with correct
410 opml_process(path, rssyl_opml_import_func, (gpointer)ctx);