Merge Irssi 0.8.16-rc1
[silc.git] / apps / irssi / src / fe-common / core / fe-settings.c
index 0d8aaa933d13db2a87650954270fe097407509b1..59f136b28bc04f02e3dc5e6877e0086f2b505360 100644 (file)
@@ -13,9 +13,9 @@
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
 
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+    You should have received a copy of the GNU General Public License along
+    with this program; if not, write to the Free Software Foundation, Inc.,
+    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */
 
 #include "module.h"
 
 static void set_print(SETTINGS_REC *rec)
 {
-       const char *value;
-       char value_int[MAX_INT_STRLEN];
-
-       switch (rec->type) {
-       case SETTING_TYPE_BOOLEAN:
-               value = settings_get_bool(rec->key) ? "ON" : "OFF";
-               break;
-       case SETTING_TYPE_INT:
-               ltoa(value_int, settings_get_int(rec->key));
-               value = value_int;
-               break;
-       case SETTING_TYPE_STRING:
-               value = settings_get_str(rec->key);
-               break;
-       default:
-               value = "";
+       char *value;
+
+       value = settings_get_print(rec);
+       printformat(NULL, NULL, MSGLEVEL_CLIENTCRAP, TXT_SET_ITEM,
+                   rec->key, value);
+       g_free(value);
+}
+
+static void set_print_pattern(const char *pattern)
+{
+       GSList *sets, *tmp;
+       const char *last_section;
+
+       last_section = "";
+       sets = settings_get_sorted();
+       for (tmp = sets; tmp != NULL; tmp = tmp->next) {
+               SETTINGS_REC *rec = tmp->data;
+
+               if (stristr(rec->key, pattern) == NULL)
+                       continue;
+               if (strcmp(last_section, rec->section) != 0) {
+                       /* print section */
+                       printformat(NULL, NULL, MSGLEVEL_CLIENTCRAP,
+                                   TXT_SET_TITLE, rec->section);
+                       last_section = rec->section;
+               }
+               set_print(rec);
        }
-       printtext(NULL, NULL, MSGLEVEL_CLIENTCRAP, "%s = %s", rec->key, value);
+       g_slist_free(sets);
 }
 
 static void set_boolean(const char *key, const char *value)
 {
-       if (g_strcasecmp(value, "ON") == 0)
+       char *stripped_value;
+       stripped_value = g_strdup(value);
+       g_strstrip(stripped_value);
+
+       if (g_ascii_strcasecmp(stripped_value, "ON") == 0)
                settings_set_bool(key, TRUE);
-       else if (g_strcasecmp(value, "OFF") == 0)
+       else if (g_ascii_strcasecmp(stripped_value, "OFF") == 0)
                settings_set_bool(key, FALSE);
-       else if (g_strcasecmp(value, "TOGGLE") == 0)
+       else if (g_ascii_strcasecmp(stripped_value, "TOGGLE") == 0)
                settings_set_bool(key, !settings_get_bool(key));
        else
-               printformat(NULL, NULL, MSGLEVEL_CLIENTCRAP, TXT_NOT_TOGGLE);
+               printformat(NULL, NULL, MSGLEVEL_CLIENTERROR, TXT_NOT_TOGGLE);
+
+    g_free(stripped_value);
+}
+
+static void set_int(const char *key, const char *value)
+{
+       char *endp;
+       long longval;
+       int error;
+
+       errno = 0;
+       longval = strtol(value, &endp, 10);
+       error = errno;
+       while (i_isspace(*endp))
+               endp++;
+       if (error != 0 || *endp != '\0' || longval < INT_MIN || longval > INT_MAX)
+               printformat(NULL, NULL, MSGLEVEL_CLIENTERROR, TXT_INVALID_NUMBER);
+       else
+               settings_set_int(key, (int)longval);
 }
 
-/* SYNTAX: SET [-clear] [<key> [<value>]] */
+/* SYNTAX: SET [-clear | -default] [<key> [<value>]] */
 static void cmd_set(char *data)
 {
         GHashTable *optlist;
-       GSList *sets, *tmp;
-       const char *last_section;
        char *key, *value;
        void *free_arg;
-       int found, clear;
+       int clear, set_default;
+       SETTINGS_REC *rec;
 
        if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_GETREST | PARAM_FLAG_OPTIONS,
                            "set", &optlist, &key, &value))
                return;
 
        clear = g_hash_table_lookup(optlist, "clear") != NULL;
+       set_default = g_hash_table_lookup(optlist, "default") != NULL;
 
-       last_section = ""; found = 0;
-       sets = settings_get_sorted();
-       for (tmp = sets; tmp != NULL; tmp = tmp->next) {
-               SETTINGS_REC *rec = tmp->data;
+       if (*key == '\0')
+               clear = set_default = FALSE;
 
-               if (((clear || *value != '\0') && g_strcasecmp(rec->key, key) != 0) ||
-                   (*value == '\0' && *key != '\0' && stristr(rec->key, key) == NULL))
-                       continue;
-
-               if (strcmp(last_section, rec->section) != 0) {
-                       /* print section */
-                       printtext(NULL, NULL, MSGLEVEL_CLIENTCRAP, "%_[ %s ]", rec->section);
-                       last_section = rec->section;
-               }
-
-               if (clear || *value != '\0') {
+       if (!(clear || set_default || *value != '\0'))
+               set_print_pattern(key);
+       else {
+               rec = settings_get_record(key);
+               if (rec != NULL) {
                        /* change the setting */
                        switch (rec->type) {
                        case SETTING_TYPE_BOOLEAN:
                                 if (clear)
                                        settings_set_bool(key, FALSE);
-                                else
+                               else if (set_default)
+                                       settings_set_bool(key, rec->default_value.v_bool);
+                               else
                                        set_boolean(key, value);
                                break;
                        case SETTING_TYPE_INT:
-                               settings_set_int(key, clear ? 0 : atoi(value));
+                               if (clear)
+                                       settings_set_int(key, 0);
+                               else if (set_default)
+                                       settings_set_int(key, rec->default_value.v_int);
+                               else
+                                       set_int(key, value);
                                break;
                        case SETTING_TYPE_STRING:
-                               settings_set_str(key, clear ? "" : value);
+                               settings_set_str(key, clear ? "" :
+                                                set_default ? rec->default_value.v_string :
+                                                value);
+                               break;
+                       case SETTING_TYPE_TIME:
+                               if (!settings_set_time(key, clear ? "0" :
+                                                      set_default ? rec->default_value.v_string : value))
+                                       printformat(NULL, NULL, MSGLEVEL_CLIENTERROR,
+                                                   TXT_INVALID_TIME);
+                               break;
+                       case SETTING_TYPE_LEVEL:
+                               if (!settings_set_level(key, clear ? "" :
+                                                       set_default ? rec->default_value.v_string : value))
+                                       printformat(NULL, NULL, MSGLEVEL_CLIENTERROR,
+                                                   TXT_INVALID_LEVEL);
+                               break;
+                       case SETTING_TYPE_SIZE:
+                               if (!settings_set_size(key, clear ? "0" :
+                                                      set_default ? rec->default_value.v_string : value))
+                                       printformat(NULL, NULL, MSGLEVEL_CLIENTERROR,
+                                                   TXT_INVALID_SIZE);
                                break;
                        }
                        signal_emit("setup changed", 0);
-               }
-
-                set_print(rec);
-               found = TRUE;
-
-               if (clear || *value != '\0')
-                       break;
+                       printformat(NULL, NULL, MSGLEVEL_CLIENTCRAP,
+                                   TXT_SET_TITLE, rec->section);
+                       set_print(rec);
+               } else
+                       printformat(NULL, NULL, MSGLEVEL_CLIENTERROR,
+                                   TXT_SET_UNKNOWN, key);
        }
-       g_slist_free(sets);
-
-        if (!found)
-               printtext(NULL, NULL, MSGLEVEL_CLIENTERROR, "Unknown setting %s", key);
 
         cmd_params_free(free_arg);
 }
@@ -143,12 +191,13 @@ static void cmd_toggle(const char *data)
 
        type = settings_get_type(key);
         if (type == -1)
-               printtext(NULL, NULL, MSGLEVEL_CLIENTERROR, "Unknown setting %_%s", key);
+               printformat(NULL, NULL, MSGLEVEL_CLIENTERROR, TXT_SET_UNKNOWN, key);
        else if (type != SETTING_TYPE_BOOLEAN)
-               printtext(NULL, NULL, MSGLEVEL_CLIENTERROR, "Setting %_%s%_ isn't boolean, use /SET", key);
+               printformat(NULL, NULL, MSGLEVEL_CLIENTERROR, TXT_SET_NOT_BOOLEAN, key);
        else {
                set_boolean(key, *value != '\0' ? value : "TOGGLE");
                 set_print(settings_get_record(key));
+               signal_emit("setup changed", 0);
        }
 
         cmd_params_free(free_arg);
@@ -168,12 +217,12 @@ static void show_aliases(const char *alias)
        printformat(NULL, NULL, MSGLEVEL_CLIENTCRAP, TXT_ALIASLIST_HEADER);
 
        node = iconfig_node_traverse("aliases", FALSE);
-       tmp = node == NULL ? NULL : node->value;
+       tmp = node == NULL ? NULL : config_node_first(node->value);
 
        /* first get the list of aliases sorted */
        list = NULL;
        aliaslen = strlen(alias);
-       for (; tmp != NULL; tmp = tmp->next) {
+       for (; tmp != NULL; tmp = config_node_next(tmp)) {
                CONFIG_NODE *node = tmp->data;
 
                if (node->type != NODE_TYPE_KEY)
@@ -204,6 +253,8 @@ static void alias_remove(const char *alias)
        else {
                printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, TXT_ALIAS_REMOVED, alias);
                iconfig_set_str("aliases", alias, NULL);
+
+               signal_emit("alias removed", 1, alias);
        }
 }
 
@@ -225,6 +276,7 @@ static void cmd_alias(const char *data)
        else {
                printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, TXT_ALIAS_ADDED, alias);
                iconfig_set_str("aliases", alias, value);
+               signal_emit("alias added", 2, alias, value);
        }
         cmd_params_free(free_arg);
 }
@@ -232,29 +284,35 @@ static void cmd_alias(const char *data)
 /* SYNTAX: UNALIAS <alias> */
 static void cmd_unalias(const char *data)
 {
+       char *alias;
+       void *free_arg;
+
        g_return_if_fail(data != NULL);
-       if (*data == '\0') cmd_return_error(CMDERR_NOT_ENOUGH_PARAMS);
 
-       alias_remove(data);
+       if (!cmd_get_params(data, &free_arg, 1, &alias))
+               return;
+       if (*alias == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS);
+
+       alias_remove(alias);
+        cmd_params_free(free_arg);
 }
 
 /* SYNTAX: RELOAD [<file>] */
 static void cmd_reload(const char *data)
 {
-       char *fname;
+       const char *fname;
+
+       fname = *data == '\0' ? get_irssi_config() : data;
 
-       fname = *data != '\0' ? g_strdup(data) :
-               g_strdup_printf("%s/.silc/config", g_get_home_dir());
        if (settings_reread(fname)) {
                printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE,
                            TXT_CONFIG_RELOADED, fname);
        }
-       g_free(fname);
 }
 
 static void settings_save_fe(const char *fname)
 {
-       if (settings_save(fname)) {
+       if (settings_save(fname, FALSE /* not autosaved */)) {
                printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE,
                            TXT_CONFIG_SAVED, fname);
        }
@@ -262,7 +320,7 @@ static void settings_save_fe(const char *fname)
 
 static void settings_save_confirm(const char *line, char *fname)
 {
-       if (line[0] == 'Y')
+       if (i_toupper(line[0]) == 'Y')
                settings_save_fe(fname);
        g_free(fname);
 }
@@ -270,29 +328,37 @@ static void settings_save_confirm(const char *line, char *fname)
 /* SYNTAX: SAVE [<file>] */
 static void cmd_save(const char *data)
 {
-       char *format;
-
-       if (*data == '\0')
-               data = mainconfig->fname;
+        GHashTable *optlist;
+       char *format, *fname;
+        void *free_arg;
 
-       if (!irssi_config_is_changed(data)) {
-               settings_save_fe(data);
+       if (!cmd_get_params(data, &free_arg, 1 | PARAM_FLAG_OPTIONS,
+                           "save", &optlist, &fname))
                return;
-       }
 
-       printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE,
-                   TXT_CONFIG_MODIFIED, data);
+       if (*fname == '\0')
+               fname = mainconfig->fname;
+
+       if (!irssi_config_is_changed(fname))
+               settings_save_fe(fname);
+       else {
+                /* config file modified outside irssi */
+               printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE,
+                           TXT_CONFIG_MODIFIED, fname);
+
+               format = format_get_text(MODULE_NAME, NULL, NULL, NULL,
+                                        TXT_OVERWRITE_CONFIG);
+               keyboard_entry_redirect((SIGNAL_FUNC) settings_save_confirm,
+                                       format, 0, g_strdup(fname));
+               g_free(format);
+       }
 
-       format = format_get_text(MODULE_NAME, NULL, NULL, NULL,
-                                TXT_OVERWRITE_CONFIG);
-       keyboard_entry_redirect((SIGNAL_FUNC) settings_save_confirm,
-                               format, 0, g_strdup(data));
-        g_free(format);
+       cmd_params_free(free_arg);
 }
 
 static void settings_clean_confirm(const char *line)
 {
-       if (line[0] == 'Y')
+       if (i_toupper(line[0]) == 'Y')
                 settings_clean_invalid();
 }
 
@@ -312,7 +378,7 @@ void fe_settings_init(void)
        command_bind("unalias", NULL, (SIGNAL_FUNC) cmd_unalias);
        command_bind("reload", NULL, (SIGNAL_FUNC) cmd_reload);
        command_bind("save", NULL, (SIGNAL_FUNC) cmd_save);
-       command_set_options("set", "clear");
+       command_set_options("set", "clear default");
 
         signal_add("settings errors", (SIGNAL_FUNC) sig_settings_errors);
 }