diff --git a/src/fe-common/core/themes.c b/src/fe-common/core/themes.c index fe5cfe18..d0620048 100644 --- a/src/fe-common/core/themes.c +++ b/src/fe-common/core/themes.c @@ -39,8 +39,9 @@ GHashTable *default_formats; static int init_finished; static char *init_errors; +static THEME_REC *internal_theme; -static int theme_read(THEME_REC *theme, const char *path, const char *data); +static int theme_read(THEME_REC *theme, const char *path); THEME_REC *theme_create(const char *path, const char *name) { @@ -775,6 +776,22 @@ void theme_unregister_module(const char *module) themes_remove_module(module); } +void theme_set_default_abstract(const char *key, const char *value) +{ + gpointer oldkey, oldvalue; + + if (g_hash_table_lookup_extended(internal_theme->abstracts, key, + &oldkey, &oldvalue)) { + /* new values override old ones */ + g_hash_table_remove(internal_theme->abstracts, oldkey); + g_free(oldkey); + g_free(oldvalue); + } + + g_hash_table_insert(internal_theme->abstracts, + g_strdup(key), g_strdup(value)); +} + static THEME_REC *theme_find(const char *name) { GSList *tmp; @@ -840,7 +857,7 @@ THEME_REC *theme_load(const char *setname) oldtheme = theme; theme = theme_create(fname, name); theme->last_modify = statbuf.st_mtime; - if (!theme_read(theme, theme->path, NULL)) { + if (!theme_read(theme, theme->path)) { /* error reading .theme file */ theme_destroy(theme); theme = NULL; @@ -858,6 +875,17 @@ THEME_REC *theme_load(const char *setname) return theme; } +static void copy_abstract_hash(char *key, char *value, GHashTable *dest) +{ + g_hash_table_insert(dest, g_strdup(key), g_strdup(value)); +} + +static void theme_copy_abstracts(THEME_REC *dest, THEME_REC *src) +{ + g_hash_table_foreach(src->abstracts, (GHFunc) copy_abstract_hash, + dest->abstracts); +} + typedef struct { THEME_REC *theme; CONFIG_REC *config; @@ -884,13 +912,13 @@ static void read_error(const char *str) } } -static int theme_read(THEME_REC *theme, const char *path, const char *data) +static int theme_read(THEME_REC *theme, const char *path) { CONFIG_REC *config; THEME_READ_REC rec; char *str; - config = config_open(data == NULL ? path : NULL, -1) ; + config = config_open(path, -1) ; if (config == NULL) { /* didn't exist or no access? */ str = g_strdup_printf("Error reading theme file %s: %s", @@ -900,8 +928,8 @@ static int theme_read(THEME_REC *theme, const char *path, const char *data) return FALSE; } - if (data != NULL) - config_parse_data(config, data, "internal"); + if (path == NULL) + config_parse_data(config, default_theme, "internal"); else config_parse(config); @@ -922,15 +950,8 @@ static int theme_read(THEME_REC *theme, const char *path, const char *data) theme->default_color = -1; theme_read_replaces(config, theme); - if (data == NULL) { - /* get the default abstracts from default theme. */ - CONFIG_REC *default_config; - - default_config = config_open(NULL, -1); - config_parse_data(default_config, default_theme, "internal"); - theme_read_abstracts(default_config, theme); - config_close(default_config); - } + if (path == NULL) + theme_copy_abstracts(theme, internal_theme); theme_read_abstracts(config, theme); rec.theme = theme; @@ -1275,7 +1296,7 @@ static void read_settings(void) change_theme(theme, TRUE); } -static void themes_read(void) +void themes_reload(void) { GSList *refs; char *fname; @@ -1298,7 +1319,7 @@ static void themes_read(void) fname = g_strdup_printf("%s/default.theme", get_irssi_dir()); current_theme = theme_create(fname, "default"); current_theme->default_color = -1; - theme_read(current_theme, NULL, default_theme); + theme_read(current_theme, NULL); g_free(fname); } @@ -1311,25 +1332,41 @@ static void themes_read(void) } } +static THEME_REC *read_internal_theme(void) +{ + CONFIG_REC *config; + THEME_REC *theme; + + theme = theme_create("internal", "_internal"); + + config = config_open(NULL, -1); + config_parse_data(config, default_theme, "internal"); + theme_read_abstracts(config, theme); + config_close(config); + + return theme; +} + void themes_init(void) { settings_add_str("lookandfeel", "theme", "default"); default_formats = g_hash_table_new((GHashFunc) g_str_hash, (GCompareFunc) g_str_equal); + internal_theme = read_internal_theme(); init_finished = FALSE; init_errors = NULL; themes = NULL; - themes_read(); + themes_reload(); command_bind("format", NULL, (SIGNAL_FUNC) cmd_format); command_bind("save", NULL, (SIGNAL_FUNC) cmd_save); signal_add("complete command format", (SIGNAL_FUNC) sig_complete_format); signal_add("irssi init finished", (SIGNAL_FUNC) sig_print_errors); signal_add("setup changed", (SIGNAL_FUNC) read_settings); - signal_add("setup reread", (SIGNAL_FUNC) themes_read); + signal_add("setup reread", (SIGNAL_FUNC) themes_reload); command_set_options("format", "delete reset"); command_set_options("save", "formats"); @@ -1339,6 +1376,7 @@ void themes_deinit(void) { while (themes != NULL) theme_destroy(themes->data); + theme_destroy(internal_theme); g_hash_table_destroy(default_formats); default_formats = NULL; @@ -1348,5 +1386,5 @@ void themes_deinit(void) signal_remove("complete command format", (SIGNAL_FUNC) sig_complete_format); signal_remove("irssi init finished", (SIGNAL_FUNC) sig_print_errors); signal_remove("setup changed", (SIGNAL_FUNC) read_settings); - signal_remove("setup reread", (SIGNAL_FUNC) themes_read); + signal_remove("setup reread", (SIGNAL_FUNC) themes_reload); } diff --git a/src/fe-common/core/themes.h b/src/fe-common/core/themes.h index 0a809b95..dcdea0fc 100644 --- a/src/fe-common/core/themes.h +++ b/src/fe-common/core/themes.h @@ -48,6 +48,8 @@ THEME_REC *theme_load(const char *name); void theme_register_module(const char *module, FORMAT_REC *formats); void theme_unregister_module(const char *module); +void theme_set_default_abstract(const char *key, const char *value); + #define EXPAND_FLAG_IGNORE_REPLACES 0x01 /* don't use the character replaces when expanding */ #define EXPAND_FLAG_IGNORE_EMPTY 0x02 /* if abstract's argument is empty, or the argument is a $variable that is empty, don't try to expand it (ie. {xx }, but not {xx}) */ #define EXPAND_FLAG_RECURSIVE_MASK 0x0f @@ -61,6 +63,8 @@ char *theme_format_expand_data(THEME_REC *theme, const char **format, char *save_last_fg, char *save_last_bg, int flags); +void themes_reload(void); + void themes_init(void); void themes_deinit(void); diff --git a/src/perl/ui/Themes.xs b/src/perl/ui/Themes.xs index 7f1c5277..8aa30410 100644 --- a/src/perl/ui/Themes.xs +++ b/src/perl/ui/Themes.xs @@ -136,6 +136,31 @@ CODE: printformat_perl(&dest, format, arglist); +void +abstracts_register(SV *abstracts) +PREINIT: + AV *av; + char *key, *value; + int i, len; +CODE: + if (!SvROK(abstracts)) + croak("abstracts is not a reference to list"); + av = (AV *) SvRV(abstracts); + len = av_len(av)+1; + if (len == 0 || (len & 1) != 0) + croak("abstracts list is invalid - not divisible by 2 (%d)", len); + + for (i = 0; i < len; i++) { + key = SvPV(*av_fetch(av, i, 0), PL_na); i++; + value = SvPV(*av_fetch(av, i, 0), PL_na); + + theme_set_default_abstract(key, value); + } + themes_reload(); + +void +themes_reload() + #******************************* MODULE = Irssi::UI::Themes PACKAGE = Irssi::Server #*******************************