Fix bug #3363 “preferences page composition seems weird”
[claws.git] / src / plugins / rssyl / rssyl_prefs.c
index ea8e73f9d335332d3d3aef577f00b2687f7e7dae..374a862b7ccc3e2f08aa8257ab99405d91e06cbe 100644 (file)
@@ -1,7 +1,7 @@
 /*
- * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 1999-2004 Hiroyuki Yamamoto
- * This file (C) 2005 Andrej Kacian <andrej@kacian.sk>
+ * Claws Mail -- a GTK+ based, lightweight, and fast e-mail client
+ * Copyright (C) 1999-2015 Hiroyuki Yamamoto and the Claws Mail team
+ * This file (C) 2005-2015 Andrej Kacian <andrej@kacian.sk>
  *
  * - Plugin preferences
  *
 
 #ifdef HAVE_CONFIG_H
 #  include "config.h"
-#include "claws-features.h"
 #endif
 
+/* Global includes */
 #include <glib.h>
 #include <glib/gi18n.h>
 
-#include "common/defs.h"
-#include "common/utils.h"
-#include "gtk/gtkutils.h"
-#include "prefs_gtk.h"
+/* Claws Mail includes */
+#include <common/defs.h>
+#include <prefs_gtk.h>
+#include <mainwindow.h>
 
+/* Local includes */
+#include "rssyl.h"
 #include "rssyl_prefs.h"
+#include "rssyl_feed.h"
 
-static RSSylPrefsPage rssyl_prefs_page;
-RSSylPrefs rssyl_prefs;
+static RPrefsPage rssyl_gtk_prefs_page;
+RPrefs rssyl_prefs;
 
 static void destroy_rssyl_prefs_page(PrefsPage *page);
 static void create_rssyl_prefs_page(PrefsPage *page,
                GtkWindow *window, gpointer data);
 static void save_rssyl_prefs(PrefsPage *page);
+static void rssyl_apply_prefs(void);
 
 static PrefParam param[] = {
-       { "refresh_interval", RSSYL_PREF_DEFAULT_REFRESH, &rssyl_prefs.refresh, P_INT,
-               NULL, NULL, NULL },
-       { "expired_keep", RSSYL_PREF_DEFAULT_EXPIRED, &rssyl_prefs.expired, P_INT,
-               NULL, NULL, NULL },
-       { "refresh_on_startup", FALSE, &rssyl_prefs.refresh_on_startup, P_BOOL,
-               NULL, NULL, NULL },
-       { "cookies_path", "", &rssyl_prefs.cookies_path, P_STRING,
-               NULL, NULL, NULL },
+       { "refresh_interval", PREF_DEFAULT_REFRESH, &rssyl_prefs.refresh,
+               P_INT, NULL, NULL, NULL },
+       { "refresh_on_startup", "FALSE", &rssyl_prefs.refresh_on_startup,
+               P_BOOL, NULL, NULL, NULL },
+       { "refresh_enabled", "TRUE", &rssyl_prefs.refresh_enabled,
+               P_BOOL, NULL, NULL, NULL },
+       { "cookies_path", "", &rssyl_prefs.cookies_path,
+               P_STRING, NULL, NULL, NULL },
+       { "ssl_verify_peer", "TRUE", &rssyl_prefs.ssl_verify_peer,
+               P_BOOL, NULL, NULL, NULL },
        { 0, 0, 0, 0, 0, 0, 0 }
 };
 
@@ -69,89 +75,139 @@ void rssyl_prefs_init(void)
        prefs_read_config(param, PREFS_BLOCK_NAME, rcpath, NULL);
        g_free(rcpath);
 
-       rssyl_prefs_page.page.path = path;
-       rssyl_prefs_page.page.create_widget = create_rssyl_prefs_page;
-       rssyl_prefs_page.page.destroy_widget = destroy_rssyl_prefs_page;
-       rssyl_prefs_page.page.save_page = save_rssyl_prefs;
-       rssyl_prefs_page.page.weight = 30.0;
+       rssyl_gtk_prefs_page.page.path = path;
+       rssyl_gtk_prefs_page.page.create_widget = create_rssyl_prefs_page;
+       rssyl_gtk_prefs_page.page.destroy_widget = destroy_rssyl_prefs_page;
+       rssyl_gtk_prefs_page.page.save_page = save_rssyl_prefs;
+       rssyl_gtk_prefs_page.page.weight = 30.0;
 
-       prefs_gtk_register_page((PrefsPage *) &rssyl_prefs_page);
+       prefs_gtk_register_page((PrefsPage *) &rssyl_gtk_prefs_page);
 }
 
 void rssyl_prefs_done(void)
 {
-       prefs_gtk_unregister_page((PrefsPage *) &rssyl_prefs_page);
+       prefs_gtk_unregister_page((PrefsPage *) &rssyl_gtk_prefs_page);
+}
+
+/* Toggle the refresh timeout spinbutton sensitivity after the
+ * checkbutton was toggled. */
+static gboolean
+rssyl_refresh_enabled_toggled_cb(GtkToggleButton *tb, gpointer data)
+{
+       gtk_widget_set_sensitive(GTK_WIDGET(data),
+                       gtk_toggle_button_get_active(tb));
+       return FALSE;
+}
+
+/* Open a file select dialog and set file path to cookies entry */
+static void
+rssyl_prefs_cookies_browse_cb(GtkWidget* widget, gpointer data)
+{
+       gchar *filename;
+       gchar *utf8_filename;
+       GtkEntry *dest = GTK_ENTRY(data);
+
+       filename = filesel_select_file_open(_("Select cookies file"), NULL);
+       if (!filename) return;
+
+       utf8_filename = g_filename_to_utf8(filename, -1, NULL, NULL, NULL);
+       if (!utf8_filename) {
+               g_warning("rssyl_prefs_cookies_browse_cb(): failed to convert character set.");
+               utf8_filename = g_strdup(filename);
+       }
+       gtk_entry_set_text(GTK_ENTRY(dest), utf8_filename);
+       g_free(utf8_filename);
 }
 
 static void create_rssyl_prefs_page(PrefsPage *page,
                GtkWindow *window, gpointer data)
 {
-       RSSylPrefsPage *prefs_page = (RSSylPrefsPage *) page;
-       GtkWidget *table;
-       GtkWidget *refresh;
-       GtkWidget *expired;
-       GtkWidget *refresh_on_startup;
-       GtkWidget *cookies_path;
+       RPrefsPage *prefs_page = (RPrefsPage *) page;
+       GtkWidget *vbox, *vbox1, *vbox2;
+       GtkWidget *frame;
+       GtkWidget *refresh, *refresh_enabled, *refresh_hbox;
        GtkWidget *label;
-       GtkObject *refresh_adj, *expired_adj;
+       GtkWidget *refresh_on_startup;
+       GtkObject *refresh_adj;
+       GtkWidget *cookies_path, *cookies_btn, *cookies_hbox;
+       GtkWidget *ssl_verify_peer;
 
-       table = gtk_table_new(RSSYL_NUM_PREFS, 2, FALSE);
-       gtk_container_set_border_width(GTK_CONTAINER(table), 5);
-       gtk_table_set_row_spacings(GTK_TABLE(table), VSPACING_NARROW);
-       gtk_table_set_col_spacings(GTK_TABLE(table), 8);
+       vbox1 = gtk_vbox_new(FALSE, 6);
 
-       label = gtk_label_new(_("Default refresh interval in minutes"));
-       gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5);
-       gtk_table_attach(GTK_TABLE(table), label, 0, 1, 0, 1,
-                       GTK_FILL, 0, 0, 0);
+       /* Refresh interval */
+       refresh_hbox = gtk_hbox_new(FALSE, 6);
+       refresh_enabled = gtk_check_button_new_with_label(
+                       _("Default refresh interval"));
+       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(refresh_enabled),
+                       rssyl_prefs.refresh_enabled);
+       gtk_box_pack_start(GTK_BOX(refresh_hbox), refresh_enabled, FALSE, FALSE, 0);
 
        refresh_adj = gtk_adjustment_new(rssyl_prefs.refresh,
-                       0, 100000, 1, 10, 0);
+                       1, 100000, 1, 10, 0);
        refresh = gtk_spin_button_new(GTK_ADJUSTMENT(refresh_adj), 1, 0);
-       gtk_table_attach(GTK_TABLE(table), refresh, 1, 2, 0, 1,
-                       GTK_FILL, 0, 0, 0);
-       CLAWS_SET_TIP(refresh,
-                       _("Set to 0 to disable automatic refreshing"));
-
-       label = gtk_label_new(_("Default number of expired items to keep"));
-       gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5);
-       gtk_table_attach(GTK_TABLE(table), label, 0, 1, 1, 2,
-                       GTK_FILL, 0, 0, 0);
-
-       expired_adj = gtk_adjustment_new(rssyl_prefs.expired,
-                       -1, 100000, 1, 10, 0);
-       expired = gtk_spin_button_new(GTK_ADJUSTMENT(expired_adj), 1, 0);
-       gtk_table_attach(GTK_TABLE(table), expired, 1, 2, 1, 2,
-                       GTK_FILL, 0, 0, 0);
-       CLAWS_SET_TIP(expired,
-                       _("Set to -1 to keep expired items"));
+       gtk_widget_set_sensitive(GTK_WIDGET(refresh), rssyl_prefs.refresh_enabled);
+       g_signal_connect(G_OBJECT(refresh_enabled), "toggled",
+                       G_CALLBACK(rssyl_refresh_enabled_toggled_cb), refresh);
+       gtk_box_pack_start(GTK_BOX(refresh_hbox), refresh, FALSE, FALSE, 0);
+
+       label = gtk_label_new(_("minute(s)"));
+       gtk_box_pack_start(GTK_BOX(refresh_hbox), label, FALSE, FALSE, 0);
+
+       gtk_box_pack_start(GTK_BOX(vbox1), refresh_hbox, FALSE, FALSE, 0);
 
+       /* Whether to refresh all feeds on CM startup */
        refresh_on_startup = gtk_check_button_new_with_label(
                        _("Refresh all feeds on application start"));
        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(refresh_on_startup),
                        rssyl_prefs.refresh_on_startup);
-       gtk_table_attach(GTK_TABLE(table), refresh_on_startup, 0, 2, 3, 4,
-                       GTK_FILL | GTK_EXPAND, 0, 0, 0);
+       gtk_box_pack_start(GTK_BOX(vbox1), refresh_on_startup, FALSE, FALSE, 0);
+
+       vbox2 = gtk_vbox_new(FALSE, 6);
+
+       /* Whether to verify SSL peer certificate */
+       ssl_verify_peer = gtk_check_button_new_with_label(
+                       _("Verify SSL certificates validity for new feeds"));
+       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(ssl_verify_peer),
+                       rssyl_prefs.ssl_verify_peer);
+       gtk_box_pack_start(GTK_BOX(vbox2), ssl_verify_peer, FALSE, FALSE, 0);
 
+       /* Path to cookies file for libcurl to use */
+       cookies_hbox = gtk_hbox_new(FALSE, 6);
        label = gtk_label_new(_("Path to cookies file"));
-       gtk_table_attach(GTK_TABLE(table), label, 0, 1, 4, 5,
-                       GTK_FILL, 0, 0, 0);
-       gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5);
+       gtk_box_pack_start(GTK_BOX(cookies_hbox), label, FALSE, FALSE, 0);
 
-       cookies_path = gtk_entry_new ();
+       cookies_path = gtk_entry_new();
        gtk_entry_set_text(GTK_ENTRY(cookies_path), rssyl_prefs.cookies_path);
-       gtk_table_attach(GTK_TABLE(table), cookies_path, 1, 2, 4, 5,
-                       GTK_FILL | GTK_EXPAND, 0, 0, 0);
-       CLAWS_SET_TIP(cookies_path,
+       gtk_box_pack_start(GTK_BOX(cookies_hbox), cookies_path, TRUE, TRUE, 0);
+       gtk_widget_set_tooltip_text(cookies_path,
                        _("Path to Netscape-style cookies.txt file containing your cookies"));
 
-       gtk_widget_show_all(table);
+       cookies_btn = gtkut_get_browse_file_btn(_("Bro_wse"));
+       gtk_box_pack_start(GTK_BOX(cookies_hbox), cookies_btn, FALSE, FALSE, 0);
+       g_signal_connect(G_OBJECT(cookies_btn), "clicked",
+               G_CALLBACK(rssyl_prefs_cookies_browse_cb), cookies_path);
+       gtk_box_pack_start(GTK_BOX(vbox2), cookies_hbox, FALSE, FALSE, 0);
+
+       vbox = gtk_vbox_new(FALSE, 6);
+       gtk_container_set_border_width (GTK_CONTAINER (vbox), 6);
+
+       PACK_FRAME (vbox, frame, _("Refreshing"));
+       gtk_container_set_border_width(GTK_CONTAINER(vbox1), 6);
+       gtk_container_add(GTK_CONTAINER(frame), vbox1);
+
+       PACK_FRAME (vbox, frame, _("Security and privacy"));
+       gtk_container_set_border_width(GTK_CONTAINER(vbox2), 6);
+       gtk_container_add(GTK_CONTAINER(frame), vbox2);
+
+       gtk_widget_show_all(vbox);
 
-       prefs_page->page.widget = table;
+       /* Store pointers to relevant widgets */
+       prefs_page->page.widget = vbox;
+       prefs_page->refresh_enabled = refresh_enabled;
        prefs_page->refresh = refresh;
-       prefs_page->expired = expired;
        prefs_page->refresh_on_startup = refresh_on_startup;
        prefs_page->cookies_path = cookies_path;
+       prefs_page->ssl_verify_peer = ssl_verify_peer;
 }
 
 static void destroy_rssyl_prefs_page(PrefsPage *page)
@@ -161,21 +217,25 @@ static void destroy_rssyl_prefs_page(PrefsPage *page)
 
 static void save_rssyl_prefs(PrefsPage *page)
 {
-       RSSylPrefsPage *prefs_page = (RSSylPrefsPage *)page;
+       RPrefsPage *prefs_page = (RPrefsPage *)page;
        PrefFile *pref_file;
        gchar *rc_file_path = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S,
                        COMMON_RC, NULL);
 
+       /* Grab values from GTK widgets */
+       rssyl_prefs.refresh_enabled = gtk_toggle_button_get_active(
+                       GTK_TOGGLE_BUTTON(prefs_page->refresh_enabled));
        rssyl_prefs.refresh = gtk_spin_button_get_value_as_int(
                        GTK_SPIN_BUTTON(prefs_page->refresh));
-       rssyl_prefs.expired = gtk_spin_button_get_value_as_int(
-                       GTK_SPIN_BUTTON(prefs_page->expired));
        rssyl_prefs.refresh_on_startup = gtk_toggle_button_get_active(
                        GTK_TOGGLE_BUTTON(prefs_page->refresh_on_startup));
        g_free(rssyl_prefs.cookies_path);
        rssyl_prefs.cookies_path = g_strdup(gtk_entry_get_text(
-                       GTK_ENTRY(prefs_page->cookies_path)));
+                               GTK_ENTRY(prefs_page->cookies_path)));
+       rssyl_prefs.ssl_verify_peer = gtk_toggle_button_get_active(
+                       GTK_TOGGLE_BUTTON(prefs_page->ssl_verify_peer));
 
+       /* Store prefs in rc file */
        pref_file = prefs_write_open(rc_file_path);
        g_free(rc_file_path);
 
@@ -188,14 +248,56 @@ static void save_rssyl_prefs(PrefsPage *page)
                return;
        }
 
-        if (fprintf(pref_file->fp, "\n") < 0) {
-               FILE_OP_ERROR(rc_file_path, "fprintf");
-               prefs_file_close_revert(pref_file);
-       } else
-               prefs_file_close(pref_file);
+       fprintf(pref_file->fp, "\n");
+       prefs_file_close(pref_file);
+
+       rssyl_apply_prefs();
 }
 
-RSSylPrefs *rssyl_prefs_get(void)
+RPrefs *rssyl_prefs_get(void)
 {
        return &rssyl_prefs;
 }
+
+static void rssyl_start_default_refresh_timeouts_func(FolderItem *item,
+               gpointer data)
+{
+       RFolderItem *ritem = (RFolderItem *)item;
+       guint prefs_interval = GPOINTER_TO_UINT(data);
+
+       if( !IS_RSSYL_FOLDER_ITEM(item) )
+               return;
+
+       if( folder_item_parent(item) == NULL || ritem->url == NULL )
+               return;
+
+       /* Feeds which use default refresh interval */
+       if( ritem->default_refresh_interval ) {
+               /* Start a new timer if the default value has changed
+                * (ritem->refresh_interval should contain previous default
+                * value in this case). */
+               if( ritem->refresh_interval != prefs_interval ) {
+                       ritem->refresh_interval = prefs_interval;
+                       rssyl_feed_start_refresh_timeout(ritem);
+               }
+       }
+}
+
+static void rssyl_start_default_refresh_timeouts(void)
+{
+       RPrefs *rsprefs = rssyl_prefs_get();
+
+       folder_func_to_all_folders(
+                       (FolderItemFunc)rssyl_start_default_refresh_timeouts_func,
+                       GUINT_TO_POINTER(rsprefs->refresh));
+}
+
+/* rssyl_apply_prefs():
+ * Do what's needed to start using newly set preferences */
+static void rssyl_apply_prefs(void)
+{
+       /* Update refresh timeouts for feeds which use default interval. */
+       rssyl_start_default_refresh_timeouts();
+
+       /* Nothing else here, so far... */
+}