Fix bug #3363 “preferences page composition seems weird”
[claws.git] / src / plugins / rssyl / rssyl_prefs.c
1 /*
2  * Claws Mail -- a GTK+ based, lightweight, and fast e-mail client
3  * Copyright (C) 1999-2015 Hiroyuki Yamamoto and the Claws Mail team
4  * This file (C) 2005-2015 Andrej Kacian <andrej@kacian.sk>
5  *
6  * - Plugin preferences
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
31 /* Claws Mail includes */
32 #include <common/defs.h>
33 #include <prefs_gtk.h>
34 #include <mainwindow.h>
35
36 /* Local includes */
37 #include "rssyl.h"
38 #include "rssyl_prefs.h"
39 #include "rssyl_feed.h"
40
41 static RPrefsPage rssyl_gtk_prefs_page;
42 RPrefs rssyl_prefs;
43
44 static void destroy_rssyl_prefs_page(PrefsPage *page);
45 static void create_rssyl_prefs_page(PrefsPage *page,
46                 GtkWindow *window, gpointer data);
47 static void save_rssyl_prefs(PrefsPage *page);
48 static void rssyl_apply_prefs(void);
49
50 static PrefParam param[] = {
51         { "refresh_interval", PREF_DEFAULT_REFRESH, &rssyl_prefs.refresh,
52                 P_INT, NULL, NULL, NULL },
53         { "refresh_on_startup", "FALSE", &rssyl_prefs.refresh_on_startup,
54                 P_BOOL, NULL, NULL, NULL },
55         { "refresh_enabled", "TRUE", &rssyl_prefs.refresh_enabled,
56                 P_BOOL, NULL, NULL, NULL },
57         { "cookies_path", "", &rssyl_prefs.cookies_path,
58                 P_STRING, NULL, NULL, NULL },
59         { "ssl_verify_peer", "TRUE", &rssyl_prefs.ssl_verify_peer,
60                 P_BOOL, NULL, NULL, NULL },
61         { 0, 0, 0, 0, 0, 0, 0 }
62 };
63
64 void rssyl_prefs_init(void)
65 {
66         static gchar *path[3];
67         gchar *rcpath;
68
69         path[0] = _("Plugins");
70         path[1] = "RSSyl";              /* We don't need this translated */
71         path[2] = NULL;
72
73         prefs_set_default(param);
74         rcpath = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S, COMMON_RC, NULL);
75         prefs_read_config(param, PREFS_BLOCK_NAME, rcpath, NULL);
76         g_free(rcpath);
77
78         rssyl_gtk_prefs_page.page.path = path;
79         rssyl_gtk_prefs_page.page.create_widget = create_rssyl_prefs_page;
80         rssyl_gtk_prefs_page.page.destroy_widget = destroy_rssyl_prefs_page;
81         rssyl_gtk_prefs_page.page.save_page = save_rssyl_prefs;
82         rssyl_gtk_prefs_page.page.weight = 30.0;
83
84         prefs_gtk_register_page((PrefsPage *) &rssyl_gtk_prefs_page);
85 }
86
87 void rssyl_prefs_done(void)
88 {
89         prefs_gtk_unregister_page((PrefsPage *) &rssyl_gtk_prefs_page);
90 }
91
92 /* Toggle the refresh timeout spinbutton sensitivity after the
93  * checkbutton was toggled. */
94 static gboolean
95 rssyl_refresh_enabled_toggled_cb(GtkToggleButton *tb, gpointer data)
96 {
97         gtk_widget_set_sensitive(GTK_WIDGET(data),
98                         gtk_toggle_button_get_active(tb));
99         return FALSE;
100 }
101
102 /* Open a file select dialog and set file path to cookies entry */
103 static void
104 rssyl_prefs_cookies_browse_cb(GtkWidget* widget, gpointer data)
105 {
106         gchar *filename;
107         gchar *utf8_filename;
108         GtkEntry *dest = GTK_ENTRY(data);
109
110         filename = filesel_select_file_open(_("Select cookies file"), NULL);
111         if (!filename) return;
112
113         utf8_filename = g_filename_to_utf8(filename, -1, NULL, NULL, NULL);
114         if (!utf8_filename) {
115                 g_warning("rssyl_prefs_cookies_browse_cb(): failed to convert character set.");
116                 utf8_filename = g_strdup(filename);
117         }
118         gtk_entry_set_text(GTK_ENTRY(dest), utf8_filename);
119         g_free(utf8_filename);
120 }
121
122 static void create_rssyl_prefs_page(PrefsPage *page,
123                 GtkWindow *window, gpointer data)
124 {
125         RPrefsPage *prefs_page = (RPrefsPage *) page;
126         GtkWidget *vbox, *vbox1, *vbox2;
127         GtkWidget *frame;
128         GtkWidget *refresh, *refresh_enabled, *refresh_hbox;
129         GtkWidget *label;
130         GtkWidget *refresh_on_startup;
131         GtkObject *refresh_adj;
132         GtkWidget *cookies_path, *cookies_btn, *cookies_hbox;
133         GtkWidget *ssl_verify_peer;
134
135         vbox1 = gtk_vbox_new(FALSE, 6);
136
137         /* Refresh interval */
138         refresh_hbox = gtk_hbox_new(FALSE, 6);
139         refresh_enabled = gtk_check_button_new_with_label(
140                         _("Default refresh interval"));
141         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(refresh_enabled),
142                         rssyl_prefs.refresh_enabled);
143         gtk_box_pack_start(GTK_BOX(refresh_hbox), refresh_enabled, FALSE, FALSE, 0);
144
145         refresh_adj = gtk_adjustment_new(rssyl_prefs.refresh,
146                         1, 100000, 1, 10, 0);
147         refresh = gtk_spin_button_new(GTK_ADJUSTMENT(refresh_adj), 1, 0);
148         gtk_widget_set_sensitive(GTK_WIDGET(refresh), rssyl_prefs.refresh_enabled);
149         g_signal_connect(G_OBJECT(refresh_enabled), "toggled",
150                         G_CALLBACK(rssyl_refresh_enabled_toggled_cb), refresh);
151         gtk_box_pack_start(GTK_BOX(refresh_hbox), refresh, FALSE, FALSE, 0);
152
153         label = gtk_label_new(_("minute(s)"));
154         gtk_box_pack_start(GTK_BOX(refresh_hbox), label, FALSE, FALSE, 0);
155
156         gtk_box_pack_start(GTK_BOX(vbox1), refresh_hbox, FALSE, FALSE, 0);
157
158         /* Whether to refresh all feeds on CM startup */
159         refresh_on_startup = gtk_check_button_new_with_label(
160                         _("Refresh all feeds on application start"));
161         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(refresh_on_startup),
162                         rssyl_prefs.refresh_on_startup);
163         gtk_box_pack_start(GTK_BOX(vbox1), refresh_on_startup, FALSE, FALSE, 0);
164
165         vbox2 = gtk_vbox_new(FALSE, 6);
166
167         /* Whether to verify SSL peer certificate */
168         ssl_verify_peer = gtk_check_button_new_with_label(
169                         _("Verify SSL certificates validity for new feeds"));
170         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(ssl_verify_peer),
171                         rssyl_prefs.ssl_verify_peer);
172         gtk_box_pack_start(GTK_BOX(vbox2), ssl_verify_peer, FALSE, FALSE, 0);
173
174         /* Path to cookies file for libcurl to use */
175         cookies_hbox = gtk_hbox_new(FALSE, 6);
176         label = gtk_label_new(_("Path to cookies file"));
177         gtk_box_pack_start(GTK_BOX(cookies_hbox), label, FALSE, FALSE, 0);
178
179         cookies_path = gtk_entry_new();
180         gtk_entry_set_text(GTK_ENTRY(cookies_path), rssyl_prefs.cookies_path);
181         gtk_box_pack_start(GTK_BOX(cookies_hbox), cookies_path, TRUE, TRUE, 0);
182         gtk_widget_set_tooltip_text(cookies_path,
183                         _("Path to Netscape-style cookies.txt file containing your cookies"));
184
185         cookies_btn = gtkut_get_browse_file_btn(_("Bro_wse"));
186         gtk_box_pack_start(GTK_BOX(cookies_hbox), cookies_btn, FALSE, FALSE, 0);
187         g_signal_connect(G_OBJECT(cookies_btn), "clicked",
188                 G_CALLBACK(rssyl_prefs_cookies_browse_cb), cookies_path);
189         gtk_box_pack_start(GTK_BOX(vbox2), cookies_hbox, FALSE, FALSE, 0);
190
191         vbox = gtk_vbox_new(FALSE, 6);
192         gtk_container_set_border_width (GTK_CONTAINER (vbox), 6);
193
194         PACK_FRAME (vbox, frame, _("Refreshing"));
195         gtk_container_set_border_width(GTK_CONTAINER(vbox1), 6);
196         gtk_container_add(GTK_CONTAINER(frame), vbox1);
197
198         PACK_FRAME (vbox, frame, _("Security and privacy"));
199         gtk_container_set_border_width(GTK_CONTAINER(vbox2), 6);
200         gtk_container_add(GTK_CONTAINER(frame), vbox2);
201
202         gtk_widget_show_all(vbox);
203
204         /* Store pointers to relevant widgets */
205         prefs_page->page.widget = vbox;
206         prefs_page->refresh_enabled = refresh_enabled;
207         prefs_page->refresh = refresh;
208         prefs_page->refresh_on_startup = refresh_on_startup;
209         prefs_page->cookies_path = cookies_path;
210         prefs_page->ssl_verify_peer = ssl_verify_peer;
211 }
212
213 static void destroy_rssyl_prefs_page(PrefsPage *page)
214 {
215         /* Do nothing! */
216 }
217
218 static void save_rssyl_prefs(PrefsPage *page)
219 {
220         RPrefsPage *prefs_page = (RPrefsPage *)page;
221         PrefFile *pref_file;
222         gchar *rc_file_path = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S,
223                         COMMON_RC, NULL);
224
225         /* Grab values from GTK widgets */
226         rssyl_prefs.refresh_enabled = gtk_toggle_button_get_active(
227                         GTK_TOGGLE_BUTTON(prefs_page->refresh_enabled));
228         rssyl_prefs.refresh = gtk_spin_button_get_value_as_int(
229                         GTK_SPIN_BUTTON(prefs_page->refresh));
230         rssyl_prefs.refresh_on_startup = gtk_toggle_button_get_active(
231                         GTK_TOGGLE_BUTTON(prefs_page->refresh_on_startup));
232         g_free(rssyl_prefs.cookies_path);
233         rssyl_prefs.cookies_path = g_strdup(gtk_entry_get_text(
234                                 GTK_ENTRY(prefs_page->cookies_path)));
235         rssyl_prefs.ssl_verify_peer = gtk_toggle_button_get_active(
236                         GTK_TOGGLE_BUTTON(prefs_page->ssl_verify_peer));
237
238         /* Store prefs in rc file */
239         pref_file = prefs_write_open(rc_file_path);
240         g_free(rc_file_path);
241
242         if( !pref_file || prefs_set_block_label(pref_file, PREFS_BLOCK_NAME) < 0 )
243                                 return;
244
245         if( prefs_write_param(param, pref_file->fp) < 0 ) {
246                 g_warning("Failed to write RSSyl plugin configuration\n");
247                 prefs_file_close_revert(pref_file);
248                 return;
249         }
250
251         fprintf(pref_file->fp, "\n");
252         prefs_file_close(pref_file);
253
254         rssyl_apply_prefs();
255 }
256
257 RPrefs *rssyl_prefs_get(void)
258 {
259         return &rssyl_prefs;
260 }
261
262 static void rssyl_start_default_refresh_timeouts_func(FolderItem *item,
263                 gpointer data)
264 {
265         RFolderItem *ritem = (RFolderItem *)item;
266         guint prefs_interval = GPOINTER_TO_UINT(data);
267
268         if( !IS_RSSYL_FOLDER_ITEM(item) )
269                 return;
270
271         if( folder_item_parent(item) == NULL || ritem->url == NULL )
272                 return;
273
274         /* Feeds which use default refresh interval */
275         if( ritem->default_refresh_interval ) {
276                 /* Start a new timer if the default value has changed
277                  * (ritem->refresh_interval should contain previous default
278                  * value in this case). */
279                 if( ritem->refresh_interval != prefs_interval ) {
280                         ritem->refresh_interval = prefs_interval;
281                         rssyl_feed_start_refresh_timeout(ritem);
282                 }
283         }
284 }
285
286 static void rssyl_start_default_refresh_timeouts(void)
287 {
288         RPrefs *rsprefs = rssyl_prefs_get();
289
290         folder_func_to_all_folders(
291                         (FolderItemFunc)rssyl_start_default_refresh_timeouts_func,
292                         GUINT_TO_POINTER(rsprefs->refresh));
293 }
294
295 /* rssyl_apply_prefs():
296  * Do what's needed to start using newly set preferences */
297 static void rssyl_apply_prefs(void)
298 {
299         /* Update refresh timeouts for feeds which use default interval. */
300         rssyl_start_default_refresh_timeouts();
301
302         /* Nothing else here, so far... */
303 }