Revert commit dc6d8a1 to restore correct meaning of the silent_update feed setting.
[claws.git] / src / plugins / rssyl / rssyl_gtk.c
1 /*
2  * Sylpheed -- 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  * - GUI handling functions
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 #include "claws-features.h"
26 #endif
27
28 #include <glib.h>
29 #include <glib/gi18n.h>
30
31 #include <gtk/gtk.h>
32
33 #include "gtk/menu.h"
34 #include "mainwindow.h"
35 #include "inputdialog.h"
36 #include "folderview.h"
37 #include "alertpanel.h"
38 #include "summaryview.h"
39
40 #include "main.h"
41 #include "gtkutils.h"
42
43 #include "feed.h"
44 #include "feedprops.h"
45 #include "rssyl.h"
46 #include "rssyl_cb_gtk.h"
47 #include "rssyl_cb_menu.h"
48 #include "rssyl_gtk.h"
49 #include "rssyl_prefs.h"
50
51 static char *rssyl_popup_menu_labels[] =
52 {
53         N_("_Refresh feed"),
54         N_("Refresh _all feeds"),
55         N_("Subscribe _new feed..."),
56         N_("_Unsubscribe feed..."),
57         N_("Feed pr_operties..."),
58         N_("Import feed list..."),
59         N_("Rena_me..."),
60         N_("_Create new folder..."),
61         N_("_Delete folder..."),
62         N_("Remove folder _tree..."),
63         NULL
64 };
65
66 static GtkActionEntry rssyl_popup_entries[] = 
67 {
68         {"FolderViewPopup/RefreshFeed",         NULL, NULL, NULL, NULL, G_CALLBACK(rssyl_refresh_cb) },
69         {"FolderViewPopup/RefreshAllFeeds",     NULL, NULL, NULL, NULL, G_CALLBACK(rssyl_refresh_all_cb) },
70
71         {"FolderViewPopup/NewFeed",             NULL, NULL, NULL, NULL, G_CALLBACK(rssyl_new_feed_cb) },
72         {"FolderViewPopup/RemoveFeed",          NULL, NULL, NULL, NULL, G_CALLBACK(rssyl_remove_feed_cb) },
73         {"FolderViewPopup/FeedProperties",      NULL, NULL, NULL, NULL, G_CALLBACK(rssyl_prop_cb) },
74         {"FolderViewPopup/ImportFeedlist",      NULL, NULL, NULL, NULL, G_CALLBACK(rssyl_import_feed_list_cb) },
75
76         {"FolderViewPopup/RenameFolder",        NULL, NULL, NULL, NULL, G_CALLBACK(rssyl_rename_cb) },
77
78         {"FolderViewPopup/NewFolder",           NULL, NULL, NULL, NULL, G_CALLBACK(rssyl_new_folder_cb) },
79         {"FolderViewPopup/RemoveFolder",        NULL, NULL, NULL, NULL, G_CALLBACK(rssyl_remove_folder_cb) },
80
81         {"FolderViewPopup/RemoveMailbox",       NULL, NULL, NULL, NULL, G_CALLBACK(rssyl_remove_rss_cb) },
82
83 };
84
85 static void rssyl_add_menuitems(GtkUIManager *ui_manager, FolderItem *item)
86 {
87         MENUITEM_ADDUI_MANAGER(ui_manager, "/Popup/FolderViewPopup", "RefreshFeed", "FolderViewPopup/RefreshFeed", GTK_UI_MANAGER_MENUITEM)
88         MENUITEM_ADDUI_MANAGER(ui_manager, "/Popup/FolderViewPopup", "RefreshAllFeeds", "FolderViewPopup/RefreshAllFeeds", GTK_UI_MANAGER_MENUITEM)
89         MENUITEM_ADDUI_MANAGER(ui_manager, "/Popup/FolderViewPopup", "SeparatorRSS1", "FolderViewPopup/---", GTK_UI_MANAGER_SEPARATOR)
90         MENUITEM_ADDUI_MANAGER(ui_manager, "/Popup/FolderViewPopup", "NewFeed", "FolderViewPopup/NewFeed", GTK_UI_MANAGER_MENUITEM)
91         MENUITEM_ADDUI_MANAGER(ui_manager, "/Popup/FolderViewPopup", "RemoveFeed", "FolderViewPopup/RemoveFeed", GTK_UI_MANAGER_MENUITEM)
92         MENUITEM_ADDUI_MANAGER(ui_manager, "/Popup/FolderViewPopup", "FeedProperties", "FolderViewPopup/FeedProperties", GTK_UI_MANAGER_MENUITEM)
93         MENUITEM_ADDUI_MANAGER(ui_manager, "/Popup/FolderViewPopup", "ImportFeedlist", "FolderViewPopup/ImportFeedlist", GTK_UI_MANAGER_MENUITEM)
94         MENUITEM_ADDUI_MANAGER(ui_manager, "/Popup/FolderViewPopup", "SeparatorRSS2", "FolderViewPopup/---", GTK_UI_MANAGER_SEPARATOR)
95         MENUITEM_ADDUI_MANAGER(ui_manager, "/Popup/FolderViewPopup", "RenameFolder", "FolderViewPopup/RenameFolder", GTK_UI_MANAGER_MENUITEM)
96         MENUITEM_ADDUI_MANAGER(ui_manager, "/Popup/FolderViewPopup", "SeparatorRSS3", "FolderViewPopup/---", GTK_UI_MANAGER_SEPARATOR)
97         MENUITEM_ADDUI_MANAGER(ui_manager, "/Popup/FolderViewPopup", "NewFolder", "FolderViewPopup/NewFolder", GTK_UI_MANAGER_MENUITEM)
98         MENUITEM_ADDUI_MANAGER(ui_manager, "/Popup/FolderViewPopup", "RemoveFolder", "FolderViewPopup/RemoveFolder", GTK_UI_MANAGER_MENUITEM)
99         MENUITEM_ADDUI_MANAGER(ui_manager, "/Popup/FolderViewPopup", "SeparatorRSS4", "FolderViewPopup/---", GTK_UI_MANAGER_SEPARATOR)
100         MENUITEM_ADDUI_MANAGER(ui_manager, "/Popup/FolderViewPopup", "RemoveMailbox", "FolderViewPopup/RemoveMailbox", GTK_UI_MANAGER_MENUITEM)
101         MENUITEM_ADDUI_MANAGER(ui_manager, "/Popup/FolderViewPopup", "SeparatorRSS5", "FolderViewPopup/---", GTK_UI_MANAGER_SEPARATOR)
102 }
103
104 static void rssyl_set_sensitivity(GtkUIManager *ui_manager, FolderItem *item)
105 {
106 #define SET_SENS(name, sens) \
107         cm_menu_set_sensitive_full(ui_manager, "Popup/"name, sens)
108
109         RSSylFolderItem *ritem = (RSSylFolderItem *)item;
110         SET_SENS("FolderViewPopup/RefreshFeed", folder_item_parent(item) != NULL && ritem->url);
111         SET_SENS("FolderViewPopup/RefreshAllFeeds", folder_item_parent(item) == NULL );
112         SET_SENS("FolderViewPopup/NewFeed", TRUE);
113         SET_SENS("FolderViewPopup/ImportFeedlist", TRUE );
114         SET_SENS("FolderViewPopup/RemoveFeed", folder_item_parent(item) != NULL && ritem->url );
115         SET_SENS("FolderViewPopup/FeedProperties", folder_item_parent(item) != NULL && ritem->url );
116         SET_SENS("FolderViewPopup/RenameFolder", folder_item_parent(item) != NULL );
117         SET_SENS("FolderViewPopup/NewFolder", TRUE );
118         SET_SENS("FolderViewPopup/RemoveFolder", folder_item_parent(item) != NULL && !ritem->url );
119         SET_SENS("FolderViewPopup/RemoveMailbox", folder_item_parent(item) == NULL );
120
121 #undef SET_SENS
122 }
123
124 static FolderViewPopup rssyl_popup =
125 {
126         "rssyl",
127         "<rssyl>",
128         rssyl_popup_entries,
129         G_N_ELEMENTS(rssyl_popup_entries),
130         NULL, 0,
131         NULL, 0, 0, NULL,
132         rssyl_add_menuitems,
133         rssyl_set_sensitivity
134 };
135
136 static void rssyl_fill_popup_menu_labels(void)
137 {
138         gint i;
139
140         for( i = 0; rssyl_popup_menu_labels[i] != NULL; i++ ) {
141                 (rssyl_popup_entries[i]).label = _(rssyl_popup_menu_labels[i]);
142         }
143 }
144
145 static void rssyl_add_mailbox(GtkAction *action, gpointer callback_data)
146 {
147         MainWindow *mainwin = (MainWindow *) callback_data;
148         gchar *path;
149         gchar *base = NULL;
150         Folder *folder;
151
152         path = input_dialog(_("Add RSS folder tree"),
153                         _("Enter name for a new RSS folder tree."),
154                         RSSYL_DEFAULT_MAILBOX);
155         if( !path ) return;
156
157         if( folder_find_from_path(path) ) {
158                 alertpanel_error(_("The mailbox '%s' already exists."), path);
159                 g_free(path);
160                 return;
161         }
162
163         base = g_path_get_basename(path);
164         folder = folder_new(folder_get_class_from_string("rssyl"),
165                         base, path);
166         g_free(base);
167
168         if( folder->klass->create_tree(folder) < 0 ) {
169                 alertpanel_error(_("Creation of folder tree failed.\n"
170                                 "Maybe some files already exist, or you don't have the permission "
171                                 "to write there?"));
172                 folder_destroy(folder);
173                 return;
174         }
175
176         folder_add(folder);
177         folder_scan_tree(folder, TRUE);
178
179         folderview_set(mainwin->folderview);
180 }
181
182 static GtkActionEntry mainwindow_add_mailbox[] = {{
183         "File/AddMailbox/RSSyl",
184         NULL, N_("RSSyl..."), NULL, NULL, G_CALLBACK(rssyl_add_mailbox)
185 }};
186
187 static guint main_menu_id = 0;
188
189 void rssyl_gtk_init(void)
190 {
191         MainWindow *mainwin = mainwindow_get_mainwindow();
192
193         gtk_action_group_add_actions(mainwin->action_group, mainwindow_add_mailbox,
194                         1, (gpointer)mainwin);
195         MENUITEM_ADDUI_ID_MANAGER(mainwin->ui_manager, "/Menu/File/AddMailbox", "RSSyl", 
196                           "File/AddMailbox/RSSyl", GTK_UI_MANAGER_MENUITEM,
197                           main_menu_id)
198
199
200         rssyl_fill_popup_menu_labels();
201         folderview_register_popup(&rssyl_popup);
202 }
203
204 void rssyl_gtk_done(void)
205 {
206         MainWindow *mainwin = mainwindow_get_mainwindow();
207         FolderView *folderview = NULL;
208         FolderItem *fitem = NULL;
209
210         if (mainwin == NULL || claws_is_exiting())
211                 return;
212
213         folderview = mainwin->folderview;
214         fitem = folderview->summaryview->folder_item;
215
216         if( fitem && IS_RSSYL_FOLDER_ITEM(fitem) ) {
217                 folderview_unselect(folderview);
218                 summary_clear_all(folderview->summaryview);
219         }
220
221         folderview_unregister_popup(&rssyl_popup);
222
223         MENUITEM_REMUI_MANAGER(mainwin->ui_manager,mainwin->action_group, "File/AddMailbox/RSSyl", main_menu_id);
224         main_menu_id = 0;
225 }
226
227 /***********************************************/
228
229 static RSSylFeedProp *rssyl_gtk_prop_real(RSSylFolderItem *ritem)
230 {
231         MainWindow *mainwin = mainwindow_get_mainwindow();
232         RSSylFeedProp *feedprop;
233         GtkWidget *vbox, *urllabel, *urlframe, *urlalign, *table, *refresh_label,
234                                                 *expired_label, *hsep, *sep, *bbox, *cancel_button, *cancel_align,
235                                                 *cancel_hbox, *cancel_image, *cancel_label, *ok_button, *ok_align,
236                                                 *ok_hbox, *ok_image, *ok_label, *silent_update_label;
237
238         GtkObject *refresh_adj, *expired_adj, *fetch_comments_for_adj;
239         gint refresh;
240         gint row = 0;
241
242         g_return_val_if_fail(ritem != NULL, NULL);
243
244         feedprop = g_new0(RSSylFeedProp, 1);
245
246         /* Create required widgets */
247
248         /* Window */
249         feedprop->window = gtkut_window_new(GTK_WINDOW_TOPLEVEL, "rssyl_gtk");
250
251         /* URL entry */
252         feedprop->url = gtk_entry_new();
253         gtk_entry_set_text(GTK_ENTRY(feedprop->url), ritem->url);
254
255         /* "Use default refresh interval" checkbutton */
256         feedprop->default_refresh_interval = gtk_check_button_new_with_mnemonic(
257                         _("Use default refresh interval"));
258         gtk_toggle_button_set_active(
259                         GTK_TOGGLE_BUTTON(feedprop->default_refresh_interval),
260                         ritem->default_refresh_interval);
261
262         if( ritem->refresh_interval >= 0 && !ritem->default_refresh_interval )
263                 refresh = ritem->refresh_interval;
264         else
265                 refresh = rssyl_prefs_get()->refresh;
266
267         /* "Keep default number of expired items" checkbutton */
268         feedprop->default_expired_num = gtk_check_button_new_with_mnemonic(
269                         _("Keep default number of expired entries"));
270         gtk_toggle_button_set_active(
271                         GTK_TOGGLE_BUTTON(feedprop->default_expired_num),
272                         ritem->default_expired_num);
273
274         feedprop->fetch_comments = gtk_check_button_new_with_mnemonic(
275                         _("Fetch comments if possible"));
276         gtk_toggle_button_set_active(
277                         GTK_TOGGLE_BUTTON(feedprop->fetch_comments),
278                         ritem->fetch_comments);
279
280         /* Refresh interval spinbutton */
281         fetch_comments_for_adj = gtk_adjustment_new(ritem->fetch_comments_for,
282                         -1, 100000, 1, 10, 0);
283         feedprop->fetch_comments_for = gtk_spin_button_new(GTK_ADJUSTMENT(fetch_comments_for_adj),
284                         1, 0);
285
286         /* Refresh interval spinbutton */
287         refresh_adj = gtk_adjustment_new(refresh,
288                         0, 100000, 1, 10, 0);
289         feedprop->refresh_interval = gtk_spin_button_new(GTK_ADJUSTMENT(refresh_adj),
290                         1, 0);
291
292         /* Expired num spinbutton */
293         expired_adj = gtk_adjustment_new(ritem->expired_num, -1, 100000, 1, 10, 0);
294         feedprop->expired_num = gtk_spin_button_new(GTK_ADJUSTMENT(expired_adj),
295                         1, 0);
296
297         vbox = gtk_vbox_new(FALSE, 0);
298         gtk_container_add(GTK_CONTAINER(feedprop->window), vbox);
299
300         /* URL frame */
301         urlframe = gtk_frame_new(NULL);
302         gtk_container_set_border_width(GTK_CONTAINER(urlframe), 5);
303         gtk_frame_set_label_align(GTK_FRAME(urlframe), 0.05, 0.5);
304         gtk_frame_set_shadow_type(GTK_FRAME(urlframe), GTK_SHADOW_ETCHED_OUT);
305         gtk_box_pack_start(GTK_BOX(vbox), urlframe, FALSE, FALSE, 0);
306
307         /* Label for URL frame */
308         urllabel = gtk_label_new(_("<b>Source URL:</b>"));
309         gtk_label_set_use_markup(GTK_LABEL(urllabel), TRUE);
310         gtk_misc_set_padding(GTK_MISC(urllabel), 5, 0);
311         gtk_frame_set_label_widget(GTK_FRAME(urlframe), urllabel);
312
313         /* URL entry (+ alignment in frame) */
314         urlalign = gtk_alignment_new(0, 0.5, 1, 1);
315         gtk_alignment_set_padding(GTK_ALIGNMENT(urlalign), 5, 5, 5, 5);
316         gtk_container_add(GTK_CONTAINER(urlframe), urlalign);
317
318         gtk_entry_set_activates_default(GTK_ENTRY(feedprop->url), TRUE);
319         gtk_container_add(GTK_CONTAINER(urlalign), feedprop->url);
320
321         /* Table for remaining properties */
322         table = gtk_table_new(8, 2, FALSE);
323         gtk_box_pack_start(GTK_BOX(vbox), table, TRUE, TRUE, 0);
324
325         /* Fetch comments - checkbutton */
326         gtk_table_attach(GTK_TABLE(table), feedprop->fetch_comments,
327                         0, 2, row, row+1,
328                         (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
329                         (GtkAttachOptions) (0), 10, 0);
330         g_signal_connect(G_OBJECT(feedprop->fetch_comments), "toggled",
331                         G_CALLBACK(rssyl_fetch_comments_toggled_cb),
332                         (gpointer)feedprop->fetch_comments_for);
333         row++;
334
335         /* Fetch comments for - label */
336         refresh_label = gtk_label_new(_("<b>Fetch comments on posts aged less than:</b>\n"
337                         "<small>(In days; set to -1 to fetch all comments)"
338                         "</small>"));
339         gtk_label_set_use_markup(GTK_LABEL(refresh_label), TRUE);
340         gtk_misc_set_alignment(GTK_MISC(refresh_label), 0, 0.5);
341         gtk_table_attach(GTK_TABLE(table), refresh_label, 0, 1, row, row+1,
342                         (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
343                         (GtkAttachOptions) (0), 10, 5);
344
345         /* Fetch comments for - spinbutton */
346         gtk_widget_set_sensitive(feedprop->fetch_comments_for,
347                         ritem->fetch_comments);
348         gtk_table_attach(GTK_TABLE(table), feedprop->fetch_comments_for, 1, 2, row, row+1,
349                         (GtkAttachOptions) (0),
350                         (GtkAttachOptions) (0), 10, 5);
351
352         row++;
353         hsep = gtk_hseparator_new();
354         gtk_widget_set_size_request(hsep, -1, 10);
355         gtk_table_attach(GTK_TABLE(table), hsep, 0, 2, row, row+1,
356                         (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
357                         (GtkAttachOptions) (0), 10, 5);
358
359         row++;
360         /* Use default refresh interval - checkbutton */
361         gtk_table_attach(GTK_TABLE(table), feedprop->default_refresh_interval,
362                         0, 2, row, row+1,
363                         (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
364                         (GtkAttachOptions) (0), 10, 0);
365         g_signal_connect(G_OBJECT(feedprop->default_refresh_interval), "toggled",
366                         G_CALLBACK(rssyl_default_refresh_interval_toggled_cb),
367                         (gpointer)feedprop->refresh_interval);
368         row++;
369         /* Refresh interval - label */
370         refresh_label = gtk_label_new(_("<b>Refresh interval in minutes:</b>\n"
371                         "<small>(Set to 0 to disable automatic refreshing for this feed)"
372                         "</small>"));
373         gtk_label_set_use_markup(GTK_LABEL(refresh_label), TRUE);
374         gtk_misc_set_alignment(GTK_MISC(refresh_label), 0, 0.5);
375         gtk_table_attach(GTK_TABLE(table), refresh_label, 0, 1, row, row+1,
376                         (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
377                         (GtkAttachOptions) (0), 10, 5);
378
379         /* Refresh interval - spinbutton */
380         gtk_widget_set_sensitive(feedprop->refresh_interval,
381                         !ritem->default_refresh_interval);
382         gtk_table_attach(GTK_TABLE(table), feedprop->refresh_interval, 1, 2, row, row+1,
383                         (GtkAttachOptions) (0),
384                         (GtkAttachOptions) (0), 10, 5);
385         row++;
386         hsep = gtk_hseparator_new();
387         gtk_widget_set_size_request(hsep, -1, 10);
388         gtk_table_attach(GTK_TABLE(table), hsep, 0, 2, row, row+1,
389                         (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
390                         (GtkAttachOptions) (0), 10, 5);
391
392         row++;
393         /* Use default number for expired - checkbutton */
394         gtk_table_attach(GTK_TABLE(table), feedprop->default_expired_num,       0, 2, row, row+1,
395                         (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
396                         (GtkAttachOptions) (0), 10, 0);
397         g_signal_connect(G_OBJECT(feedprop->default_expired_num), "toggled",
398                         G_CALLBACK(rssyl_default_expired_num_toggled_cb),
399                         (gpointer)feedprop->expired_num);
400
401         row++;
402         /* Expired items - label */
403         expired_label = gtk_label_new(_("<b>Number of expired entries to keep:"
404                         "</b>\n<small>(Set to -1 if you want to keep expired entries)"
405                         "</small>"));
406         gtk_label_set_use_markup(GTK_LABEL(expired_label), TRUE);
407         gtk_misc_set_alignment(GTK_MISC(expired_label), 0, 0.5);
408         gtk_table_attach(GTK_TABLE(table), expired_label, 0, 1, row, row+1,
409                         (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
410                         (GtkAttachOptions) (0), 10, 5);
411
412         /* Expired items - spinbutton */
413         gtk_widget_set_sensitive(feedprop->expired_num,
414                         !ritem->default_expired_num);
415         gtk_table_attach(GTK_TABLE(table), feedprop->expired_num, 1, 2, row, row+1,
416                         (GtkAttachOptions) (0),
417                         (GtkAttachOptions) (0), 10, 5);
418
419         row++;
420         hsep = gtk_hseparator_new();
421         gtk_widget_set_size_request(hsep, -1, 10);
422         gtk_table_attach(GTK_TABLE(table), hsep, 0, 2, row, row+1,
423                         (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
424                         (GtkAttachOptions) (0), 10, 5);
425
426         row++;
427         /* Silent update - label */
428         silent_update_label =
429                 gtk_label_new(_("<b>If an item changes, do not mark it as unread:</b>"));
430         gtk_label_set_use_markup(GTK_LABEL(silent_update_label), TRUE);
431         gtk_misc_set_alignment(GTK_MISC(silent_update_label), 0, 0.5);
432         gtk_table_attach(GTK_TABLE(table), silent_update_label, 0, 1, row, row+1,
433                         (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
434                         (GtkAttachOptions) (0), 10, 5);
435
436         /* Silent update - combobox */
437         feedprop->silent_update = gtk_combo_box_new_text();
438         gtk_combo_box_append_text(GTK_COMBO_BOX(feedprop->silent_update),
439                         _("Always mark as unread"));
440         gtk_combo_box_append_text(GTK_COMBO_BOX(feedprop->silent_update),
441                         _("If only its text has changed"));
442         gtk_combo_box_append_text(GTK_COMBO_BOX(feedprop->silent_update),
443                         _("Never mark as unread"));
444         gtk_table_attach(GTK_TABLE(table), feedprop->silent_update, 1, 2, row, row+1,
445                         (GtkAttachOptions) (0),
446                         (GtkAttachOptions) (0), 10, 5);
447         gtk_combo_box_set_active(GTK_COMBO_BOX(feedprop->silent_update),
448                         ritem->silent_update);
449
450         row++;
451         hsep = gtk_hseparator_new();
452         gtk_widget_set_size_request(hsep, -1, 10);
453         gtk_table_attach(GTK_TABLE(table), hsep, 0, 2, row, row+1,
454                         (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
455                         (GtkAttachOptions) (0), 10, 5);
456
457         row++;
458         feedprop->ssl_verify_peer_checkbtn = gtk_check_button_new_with_label(
459                 _("Verify SSL certificate validity"));
460         gtk_widget_show(feedprop->ssl_verify_peer_checkbtn);
461         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(feedprop->ssl_verify_peer_checkbtn), 
462                         ritem->ssl_verify_peer);
463         gtk_table_attach(GTK_TABLE(table), feedprop->ssl_verify_peer_checkbtn, 0, 1, row, row+1,
464                         (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
465                         (GtkAttachOptions) (0), 10, 5);
466
467
468         /* Separator above the button box */
469         sep = gtk_hseparator_new();
470         gtk_widget_set_size_request(sep, -1, 10);
471         gtk_box_pack_start(GTK_BOX(vbox), sep, FALSE, FALSE, 0);
472
473         /* Buttonbox */
474         bbox = gtk_hbutton_box_new();
475         gtk_container_set_border_width(GTK_CONTAINER(bbox), 5);
476         gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_END);
477         gtk_box_set_spacing(GTK_BOX(bbox), 5);
478         gtk_box_pack_end(GTK_BOX(vbox), bbox, FALSE, FALSE, 0);
479
480         /* Cancel button */
481         cancel_button = gtk_button_new();
482         gtk_container_add(GTK_CONTAINER(bbox), cancel_button);
483
484         cancel_align = gtk_alignment_new(0.5, 0.5, 0, 0);
485         gtk_container_add(GTK_CONTAINER(cancel_button), cancel_align);
486
487         cancel_hbox = gtk_hbox_new(FALSE, 2);
488         gtk_container_add(GTK_CONTAINER(cancel_align), cancel_hbox);
489
490         cancel_image = gtk_image_new_from_stock(GTK_STOCK_CANCEL,
491                         GTK_ICON_SIZE_BUTTON);
492         gtk_box_pack_start(GTK_BOX(cancel_hbox), cancel_image, FALSE, FALSE, 0);
493
494         cancel_label = gtk_label_new_with_mnemonic(_("_Cancel"));
495         gtk_box_pack_end(GTK_BOX(cancel_hbox), cancel_label, FALSE, FALSE, 0);
496
497         g_signal_connect(G_OBJECT(cancel_button), "clicked",
498                         G_CALLBACK(rssyl_props_cancel_cb), ritem);
499
500         /* OK button */
501         ok_button = gtk_button_new();
502         gtk_container_add(GTK_CONTAINER(bbox), ok_button);
503         gtkut_widget_set_can_default(ok_button, TRUE);
504
505         ok_align = gtk_alignment_new(0.5, 0.5, 0, 0);
506         gtk_container_add(GTK_CONTAINER(ok_button), ok_align);
507
508         ok_hbox = gtk_hbox_new(FALSE, 2);
509         gtk_container_add(GTK_CONTAINER(ok_align), ok_hbox);
510
511         ok_image = gtk_image_new_from_stock(GTK_STOCK_OK,
512                         GTK_ICON_SIZE_BUTTON);
513         gtk_box_pack_start(GTK_BOX(ok_hbox), ok_image, FALSE, FALSE, 0);
514
515         ok_label = gtk_label_new_with_mnemonic(_("_OK"));
516         gtk_box_pack_end(GTK_BOX(ok_hbox), ok_label, FALSE, FALSE, 0);
517
518         g_signal_connect(G_OBJECT(ok_button), "clicked",
519                         G_CALLBACK(rssyl_props_ok_cb), ritem);
520
521         /* Set some misc. stuff */
522         gtk_window_set_title(GTK_WINDOW(feedprop->window),
523                         g_strdup(_("Set feed properties")) );
524         gtk_window_set_modal(GTK_WINDOW(feedprop->window), TRUE);
525         gtk_window_set_transient_for(GTK_WINDOW(feedprop->window),
526                         GTK_WINDOW(mainwin->window) );
527
528         /* Attach callbacks to handle Enter and Escape keys */
529         g_signal_connect(G_OBJECT(feedprop->window), "key_press_event",
530                         G_CALLBACK(rssyl_props_key_press_cb), ritem);
531
532         /* ...and voila! */
533         gtk_widget_show_all(feedprop->window);
534         gtk_widget_grab_default(ok_button);
535
536         /* Unselect the text in URL entry */
537         gtk_editable_select_region(GTK_EDITABLE(feedprop->url), 0, 0);
538
539         ritem->feedprop = feedprop;
540
541         return feedprop;
542 }
543
544 void rssyl_gtk_prop(RSSylFolderItem *ritem)
545 {
546         g_return_if_fail(ritem != NULL);
547
548         rssyl_gtk_prop_real(ritem);
549 }
550
551 void rssyl_gtk_prop_store(RSSylFolderItem *ritem)
552 {
553         gchar *url;
554         gint x, old_ri, old_ex, old_fetch_comments;
555         gboolean use_default_ri = FALSE, use_default_ex = FALSE;
556
557         g_return_if_fail(ritem != NULL);
558         g_return_if_fail(ritem->feedprop != NULL);
559
560         url = (gchar *)gtk_entry_get_text(GTK_ENTRY(ritem->feedprop->url));
561
562         if( strlen(url) ) {
563                 if( ritem->url ) {
564                         g_free(ritem->url);
565                 }
566                 ritem->url = g_strdup(url);
567         }
568
569         use_default_ri = gtk_toggle_button_get_active(
570                         GTK_TOGGLE_BUTTON(ritem->feedprop->default_refresh_interval));
571         ritem->default_refresh_interval = use_default_ri;
572         debug_print("store: default is %s\n", ( use_default_ri ? "ON" : "OFF" ) );
573
574         /* Use default if checkbutton is set */
575         if( use_default_ri )
576                 x = rssyl_prefs_get()->refresh;
577         else
578                 x = gtk_spin_button_get_value_as_int(
579                                 GTK_SPIN_BUTTON(ritem->feedprop->refresh_interval) );
580
581         old_ri = ritem->refresh_interval;
582         ritem->refresh_interval = x;
583
584         /* Update refresh interval setting if it has changed and has a sane value */
585         if( old_ri != x && x >= 0 ) {
586                 debug_print("RSSyl: GTK - refresh interval changed to %d , updating "
587                                 "timeout\n", ritem->refresh_interval);
588                 /* Value of 0 means we do not want to update automatically */
589                 if( x > 0 )
590                         rssyl_start_refresh_timeout(ritem);
591         }
592
593         old_fetch_comments = ritem->fetch_comments;
594         ritem->fetch_comments = gtk_toggle_button_get_active(
595                         GTK_TOGGLE_BUTTON(ritem->feedprop->fetch_comments));
596
597         ritem->fetch_comments_for = gtk_spin_button_get_value_as_int(
598                                 GTK_SPIN_BUTTON(ritem->feedprop->fetch_comments_for));
599
600         if (!old_fetch_comments && ritem->fetch_comments) {
601                 /* reset the RSSylFolderItem's mtime to be sure we get all 
602                  * available comments */
603                  ritem->item.mtime = 0;
604         }
605         
606         use_default_ex = gtk_toggle_button_get_active(
607                         GTK_TOGGLE_BUTTON(ritem->feedprop->default_expired_num));
608         ritem->default_expired_num = use_default_ex;
609         debug_print("store: default is %s\n", ( use_default_ex ? "ON" : "OFF" ) );
610
611         /* Use default if checkbutton is set */
612         if( use_default_ex )
613                 x = rssyl_prefs_get()->expired;
614         else
615                 x = gtk_spin_button_get_value_as_int(
616                                 GTK_SPIN_BUTTON(ritem->feedprop->expired_num) );
617
618         old_ex = ritem->expired_num;
619         ritem->expired_num = x;
620
621         ritem->silent_update =
622                 gtk_combo_box_get_active(GTK_COMBO_BOX(ritem->feedprop->silent_update));
623         if( ritem->silent_update < 0 )
624                 ritem->silent_update = 0;
625
626         ritem->ssl_verify_peer = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON
627                                          (ritem->feedprop->ssl_verify_peer_checkbtn));;
628
629         rssyl_store_feed_props(ritem);
630
631         debug_print("last_count %d, x %d, old_ex %d\n", ritem->last_count, x, old_ex);
632
633         /* update if new setting is lower, or if it was changed from -1 */
634         if( ritem->last_count != 0 && x != -1 && (old_ex > x || old_ex == -1) ) {
635                 debug_print("RSSyl: GTK - expired_num has changed to %d, expiring\n",
636                                 ritem->expired_num);
637                 rssyl_expire_items(ritem);
638         }
639 }
640
641 GtkWidget *rssyl_feed_removal_dialog(gchar *name, GtkWidget **rmcache_widget)
642 {
643         gchar *message;
644         GtkWidget *dialog, *vbox, *hbox, *image, *vbox2, *label, *cb, *aa,
645                                                 *bno, *byes;
646         MainWindow *mainwin = mainwindow_get_mainwindow();
647
648         g_return_val_if_fail(name != NULL, NULL);
649
650         dialog = gtk_dialog_new();
651         gtk_window_set_title(GTK_WINDOW(dialog), _("Unsubscribe feed"));
652         gtk_window_set_type_hint(GTK_WINDOW(dialog), GDK_WINDOW_TYPE_HINT_DIALOG);
653
654         vbox = GTK_DIALOG(dialog)->vbox;
655
656         hbox = gtk_hbox_new(FALSE, 0);
657         gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 0);
658
659         /* Question icon */
660         image = gtk_image_new_from_stock(GTK_STOCK_DIALOG_QUESTION,
661                         GTK_ICON_SIZE_DIALOG);
662         gtk_misc_set_alignment(GTK_MISC(image), 0.5, 0.30);
663         gtk_misc_set_padding(GTK_MISC(image), 12, 0);
664         gtk_box_pack_start(GTK_BOX(hbox), image, FALSE, FALSE, 0);
665
666         vbox2 = gtk_vbox_new(FALSE, 0);
667         gtk_box_pack_start(GTK_BOX(hbox), vbox2, TRUE, TRUE, 0);
668
669         /* Dialog text label */
670         label = gtk_label_new("");
671         gtk_misc_set_alignment(GTK_MISC(label), 0.1, 0);
672         gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
673         gtk_misc_set_padding(GTK_MISC(label), 0, 12);
674         message = g_markup_printf_escaped("<span size='x-large'><b>%s</b></span>"
675                         "\n\n%s '%s' ?", _("Unsubscribe feed"),
676                         _("Do you really want to remove feed"), name);
677         gtk_label_set_markup(GTK_LABEL(label), message);
678         g_free(message);
679         gtk_box_pack_start(GTK_BOX(vbox2), label, FALSE, FALSE, 0);
680
681         /* Remove cache checkbutton */
682         cb = gtk_check_button_new_with_mnemonic(_("Remove cached entries"));
683         gtk_button_set_focus_on_click(GTK_BUTTON(cb), FALSE);
684         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(cb), TRUE);
685         gtk_box_pack_start(GTK_BOX(vbox2), cb, FALSE, FALSE, 0);
686         *rmcache_widget = cb;
687
688         aa = GTK_DIALOG(dialog)->action_area;
689         gtk_button_box_set_layout(GTK_BUTTON_BOX(aa), GTK_BUTTONBOX_END);
690
691         bno = gtk_button_new_from_stock(GTK_STOCK_CANCEL);
692         gtk_dialog_add_action_widget(GTK_DIALOG(dialog), bno, GTK_RESPONSE_NO);
693         gtkut_widget_set_can_default(bno, TRUE);
694         
695         byes = gtk_button_new_with_mnemonic(_("_Unsubscribe"));
696         gtk_dialog_add_action_widget(GTK_DIALOG(dialog), byes, GTK_RESPONSE_YES);
697
698         gtk_widget_grab_default(bno);
699         gtk_window_set_transient_for(GTK_WINDOW(dialog),
700                         GTK_WINDOW(mainwin->window) );
701
702         return dialog;
703 }