summaryrefslogtreecommitdiff
path: root/src/fe-common/core
diff options
context:
space:
mode:
authorTimo Sirainen <cras@irssi.org>2001-03-15 02:26:12 +0000
committercras <cras@dbcabf3a-b0e7-0310-adc4-f8d773084564>2001-03-15 02:26:12 +0000
commit87777968c3ed367f51524ca1d1aa5bcd2e5ed7a9 (patch)
treef34d29e76398a18dd2f5c232c85fe8a087469743 /src/fe-common/core
parent2680011ad740f7e93b0c93585ff62baef33b24fa (diff)
downloadirssi-87777968c3ed367f51524ca1d1aa5bcd2e5ed7a9.zip
Beginnings of configurable statusbar. The existing items can be configured
in default.theme. If some abstract isn't set in theme, it fallbacks to the one in default.theme now. This should help with old themes, and maybe themes that don't change something should just keep those parts commented out.. git-svn-id: http://svn.irssi.org/repos/irssi/trunk@1386 dbcabf3a-b0e7-0310-adc4-f8d773084564
Diffstat (limited to 'src/fe-common/core')
-rw-r--r--src/fe-common/core/themes.c255
-rw-r--r--src/fe-common/core/themes.h15
2 files changed, 176 insertions, 94 deletions
diff --git a/src/fe-common/core/themes.c b/src/fe-common/core/themes.c
index 5646b7bc..997395a3 100644
--- a/src/fe-common/core/themes.c
+++ b/src/fe-common/core/themes.c
@@ -94,8 +94,6 @@ void theme_destroy(THEME_REC *rec)
g_hash_table_foreach(rec->modules, (GHFunc) theme_module_destroy, NULL);
g_hash_table_destroy(rec->modules);
- g_slist_foreach(rec->replace_keys, (GFunc) g_free, NULL);
- g_slist_free(rec->replace_keys);
g_slist_foreach(rec->replace_values, (GFunc) g_free, NULL);
g_slist_free(rec->replace_values);
@@ -104,30 +102,10 @@ void theme_destroy(THEME_REC *rec)
g_free(rec);
}
-#define EXPAND_FLAG_ROOT 0x01
-#define EXPAND_FLAG_LASTCOLOR_ARG 0x02
-static char *theme_format_expand_data(THEME_REC *theme,
- const char **format,
- char default_color,
- char *save_color, int flags);
-
-static int theme_replace_find(THEME_REC *theme, char chr)
-{
- GSList *tmp;
- int index = 0;
-
- for (tmp = theme->replace_keys; tmp != NULL; tmp = tmp->next) {
- if (strchr(tmp->data, chr) != NULL)
- return index;
- index++;
- }
-
- return -1;
-}
-
static char *theme_replace_expand(THEME_REC *theme, int index,
- char default_color, char *last_color,
- char chr)
+ char default_fg, char default_bg,
+ char *last_fg, char *last_bg,
+ char chr, int flags)
{
GSList *rec;
char *ret, *abstract, data[2];
@@ -139,16 +117,20 @@ static char *theme_replace_expand(THEME_REC *theme, int index,
abstract = rec->data;
abstract = theme_format_expand_data(theme, (const char **) &abstract,
- default_color, last_color, 0);
+ default_fg, default_bg,
+ last_fg, last_bg, flags);
ret = parse_special_string(abstract, NULL, NULL, data, NULL, 0);
g_free(abstract);
return ret;
}
-static const char *colorformats = "n01234567krgybmpcwKRGYBMPCW";
+static const char *fgcolorformats = "nkrgybmpcwKRGYBMPCW";
+static const char *bgcolorformats = "n01234567";
-#define IS_COLOR_FORMAT(c) \
- ((c) != '\0' && strchr(colorformats, c) != NULL)
+#define IS_FGCOLOR_FORMAT(c) \
+ ((c) != '\0' && strchr(fgcolorformats, c) != NULL)
+#define IS_BGCOLOR_FORMAT(c) \
+ ((c) != '\0' && strchr(bgcolorformats, c) != NULL)
/* append "variable" part in $variable, ie. not the contents of the variable */
static void theme_format_append_variable(GString *str, const char **format)
@@ -174,7 +156,9 @@ static void theme_format_append_variable(GString *str, const char **format)
/* append next "item", either a character, $variable or %format */
static void theme_format_append_next(THEME_REC *theme, GString *str,
const char **format,
- char default_color, char *last_color)
+ char default_fg, char default_bg,
+ char *last_fg, char *last_bg,
+ int flags)
{
int index;
char chr;
@@ -200,14 +184,32 @@ static void theme_format_append_next(THEME_REC *theme, GString *str,
(*format)++;
if (**format != '{' && **format != '}') {
chr = **format;
- if (**format == 'n')
- chr = default_color;
-
- if (IS_COLOR_FORMAT(chr))
- *last_color = chr;
-
- g_string_append_c(str, '%');
- g_string_append_c(str, chr);
+ if (**format == 'n') {
+ /* %n = change to default color */
+ if (default_fg == 'n' || default_bg == 'n') {
+ if (*last_fg != 'n')
+ g_string_append(str, "%n");
+ *last_bg = *last_fg = 'n';
+ }
+ if (default_bg != *last_bg) {
+ g_string_append_c(str, '%');
+ g_string_append_c(str, default_bg);
+ }
+ if (default_fg != *last_fg) {
+ g_string_append_c(str, '%');
+ g_string_append_c(str, default_fg);
+ }
+
+ *last_fg = default_fg;
+ *last_bg = default_bg;
+ } else {
+ if (IS_FGCOLOR_FORMAT(chr))
+ *last_fg = chr;
+ if (IS_BGCOLOR_FORMAT(chr))
+ *last_bg = chr;
+ g_string_append_c(str, '%');
+ g_string_append_c(str, chr);
+ }
(*format)++;
return;
}
@@ -216,14 +218,16 @@ static void theme_format_append_next(THEME_REC *theme, GString *str,
chr = **format;
}
- index = theme_replace_find(theme, chr);
+ index = (flags & EXPAND_FLAG_IGNORE_REPLACES) ? -1 :
+ theme->replace_keys[(int) chr];
if (index == -1)
g_string_append_c(str, chr);
else {
char *value;
- value = theme_replace_expand(theme, index, default_color,
- last_color, chr);
+ value = theme_replace_expand(theme, index,
+ default_fg, default_bg,
+ last_fg, last_bg, chr, flags);
g_string_append(str, value);
g_free(value);
}
@@ -234,7 +238,8 @@ static void theme_format_append_next(THEME_REC *theme, GString *str,
/* expand a single {abstract ...data... } */
static char *theme_format_expand_abstract(THEME_REC *theme,
const char **formatp,
- char default_color)
+ char default_fg, char default_bg,
+ int flags)
{
const char *p, *format;
char *abstract, *data, *ret;
@@ -252,9 +257,23 @@ static char *theme_format_expand_abstract(THEME_REC *theme,
len = (int) (p-format);
abstract = g_strndup(format, len);
- /* skip the following space */
- if (*p == ' ') len++;
- *formatp = format + len;
+ /* skip the following space, if there's any more spaces they're
+ treated as arguments */
+ if (*p == ' ') {
+ len++;
+ if ((flags & EXPAND_FLAG_IGNORE_EMPTY)) {
+ /* if the data is empty, ignore the abstract */
+ p = format+len;
+ while (*p == ' ') p++;
+ if (*p == '}') {
+ *formatp = p+1;
+ g_free(abstract);
+ return NULL;
+ }
+ }
+
+ }
+ *formatp = format+len;
/* get the abstract data */
data = g_hash_table_lookup(theme->abstracts, abstract);
@@ -265,19 +284,12 @@ static char *theme_format_expand_abstract(THEME_REC *theme,
}
abstract = g_strdup(data);
- /* abstract may itself contain abstracts or replaces :) */
- p = data = abstract;
- abstract = theme_format_expand_data(theme, &p, default_color,
- &default_color,
- EXPAND_FLAG_LASTCOLOR_ARG);
- g_free(data);
-
- /* now we'll need to get the data part. it may contain
+ /* we'll need to get the data part. it may contain
more abstracts, they are automatically expanded. */
- data = theme_format_expand_data(theme, formatp, default_color,
- NULL, 0);
-
+ data = theme_format_expand_data(theme, formatp, default_fg, default_bg,
+ NULL, NULL, flags);
len = strlen(data);
+
if (len > 1 && isdigit(data[len-1]) && data[len-2] == '$') {
/* ends with $<digit> .. this breaks things if next
character is digit or '-' */
@@ -293,23 +305,34 @@ static char *theme_format_expand_abstract(THEME_REC *theme,
ret = parse_special_string(abstract, NULL, NULL, data, NULL, 0);
g_free(abstract);
- g_free(data);
+ g_free(data);
+ abstract = ret;
+
+ /* abstract may itself contain abstracts or replaces */
+ p = abstract;
+ ret = theme_format_expand_data(theme, &p, default_fg, default_bg,
+ &default_fg, &default_bg,
+ flags | EXPAND_FLAG_LASTCOLOR_ARG);
+ g_free(abstract);
return ret;
}
/* expand the data part in {abstract data} */
-static char *theme_format_expand_data(THEME_REC *theme,
- const char **format,
- char default_color,
- char *save_last_color,
- int flags)
+char *theme_format_expand_data(THEME_REC *theme, const char **format,
+ char default_fg, char default_bg,
+ char *save_last_fg, char *save_last_bg,
+ int flags)
{
GString *str;
char *ret, *abstract;
- char last_color = default_color;
+ char last_fg, last_bg;
+ int recurse_flags;
- str = g_string_new(NULL);
+ last_fg = default_fg;
+ last_bg = default_bg;
+ recurse_flags = flags & EXPAND_FLAG_RECURSIVE_MASK;
+ str = g_string_new(NULL);
while (**format != '\0') {
if ((flags & EXPAND_FLAG_ROOT) == 0 && **format == '}') {
/* ignore } if we're expanding original string */
@@ -318,17 +341,24 @@ static char *theme_format_expand_data(THEME_REC *theme,
}
if (**format != '{') {
- if (save_last_color != NULL &&
- (flags & EXPAND_FLAG_LASTCOLOR_ARG) &&
+ if ((flags & EXPAND_FLAG_LASTCOLOR_ARG) &&
**format == '$' && (*format)[1] == '0') {
/* save the color before $0 ..
this is for the %n replacing */
- *save_last_color = last_color;
- save_last_color = NULL;
+ if (save_last_fg != NULL) {
+ *save_last_fg = last_fg;
+ save_last_fg = NULL;
+ }
+ if (save_last_bg != NULL) {
+ *save_last_bg = last_bg;
+ save_last_bg = NULL;
+ }
}
theme_format_append_next(theme, str, format,
- default_color, &last_color);
+ default_fg, default_bg,
+ &last_fg, &last_bg,
+ recurse_flags);
continue;
}
@@ -338,17 +368,20 @@ static char *theme_format_expand_data(THEME_REC *theme,
/* get a single {...} */
abstract = theme_format_expand_abstract(theme, format,
- last_color);
+ last_fg, last_bg,
+ recurse_flags);
if (abstract != NULL) {
g_string_append(str, abstract);
g_free(abstract);
}
}
- if (save_last_color != NULL &&
- (flags & EXPAND_FLAG_LASTCOLOR_ARG) == 0) {
+ if ((flags & EXPAND_FLAG_LASTCOLOR_ARG) == 0) {
/* save the last color */
- *save_last_color = last_color;
+ if (save_last_fg != NULL)
+ *save_last_fg = last_fg;
+ if (save_last_bg != NULL)
+ *save_last_bg = last_bg;
}
ret = str->str;
@@ -356,18 +389,23 @@ static char *theme_format_expand_data(THEME_REC *theme,
return ret;
}
+#define IS_OLD_FORMAT(code, last_fg, last_bg) \
+ (((code) == 'n' && (last_fg) == 'n' && (last_bg) == 'n') || \
+ ((code) != 'n' && ((code) == (last_fg) || (code) == (last_bg))))
+
static char *theme_format_compress_colors(THEME_REC *theme, const char *format)
{
GString *str;
- char *ret, last_color = 'n';
+ char *ret, last_fg, last_bg;
str = g_string_new(NULL);
+ last_fg = last_bg = 'n';
while (*format != '\0') {
if (*format == '$') {
/* $variable, skrip it entirely */
theme_format_append_variable(str, &format);
- last_color = '\0';
+ last_fg = last_bg = '\0';
} else if (*format != '%') {
/* a normal character */
g_string_append_c(str, *format);
@@ -375,19 +413,24 @@ static char *theme_format_compress_colors(THEME_REC *theme, const char *format)
} else {
/* %format */
format++;
- if (*format == last_color) {
+ if (IS_OLD_FORMAT(*format, last_fg, last_bg)) {
/* active color set again */
- } else if (IS_COLOR_FORMAT(*format) &&
+ } else if (IS_FGCOLOR_FORMAT(*format) &&
+ (*format != 'n' || format[2] == 'n') &&
format[1] == '%' &&
- IS_COLOR_FORMAT(format[2])) {
- /* two colors in a row */
+ IS_FGCOLOR_FORMAT(format[2])) {
+ /* two fg colors in a row. bg colors are
+ so rare that we don't bother checking
+ them */
} else {
/* some format, add it */
g_string_append_c(str, '%');
g_string_append_c(str, *format);
- if (IS_COLOR_FORMAT(*format))
- last_color = *format;
+ if (IS_FGCOLOR_FORMAT(*format))
+ last_fg = *format;
+ if (IS_BGCOLOR_FORMAT(*format))
+ last_bg = *format;
}
format++;
}
@@ -398,16 +441,16 @@ static char *theme_format_compress_colors(THEME_REC *theme, const char *format)
return ret;
}
-static char *theme_format_expand(THEME_REC *theme, const char *format)
+char *theme_format_expand(THEME_REC *theme, const char *format)
{
char *data, *ret;
g_return_val_if_fail(theme != NULL, NULL);
g_return_val_if_fail(format != NULL, NULL);
- data = theme_format_expand_data(theme, &format, 'n', NULL,
+ data = theme_format_expand_data(theme, &format, 'n', 'n', NULL, NULL,
EXPAND_FLAG_ROOT);
- ret = theme_format_compress_colors(theme, data);
+ ret = theme_format_compress_colors(theme, data);
g_free(data);
return ret;
}
@@ -438,20 +481,28 @@ static void theme_read_replaces(CONFIG_REC *config, THEME_REC *theme)
{
GSList *tmp;
CONFIG_NODE *node;
+ const char *p;
+ int index;
node = config_node_traverse(config, "replaces", FALSE);
if (node == NULL || node->type != NODE_TYPE_BLOCK) return;
+ /* reset replace keys */
+ for (index = 0; index < 256; index++)
+ theme->replace_keys[index] = -1;
+ index = 0;
+
for (tmp = node->value; tmp != NULL; tmp = tmp->next) {
node = tmp->data;
if (node->key != NULL && node->value != NULL) {
- theme->replace_keys =
- g_slist_append(theme->replace_keys,
- g_strdup(node->key));
+ for (p = node->key; *p != '\0'; p++)
+ theme->replace_keys[(int) *p] = index;
+
theme->replace_values =
g_slist_append(theme->replace_values,
g_strdup(node->value));
+ index++;
}
}
}
@@ -460,6 +511,7 @@ static void theme_read_abstracts(CONFIG_REC *config, THEME_REC *theme)
{
GSList *tmp;
CONFIG_NODE *node;
+ gpointer oldkey, oldvalue;
node = config_node_traverse(config, "abstracts", FALSE);
if (node == NULL || node->type != NODE_TYPE_BLOCK) return;
@@ -467,12 +519,19 @@ static void theme_read_abstracts(CONFIG_REC *config, THEME_REC *theme)
for (tmp = node->value; tmp != NULL; tmp = tmp->next) {
node = tmp->data;
- if (node->key != NULL && node->value != NULL &&
- g_hash_table_lookup(theme->abstracts, node->key) == NULL) {
- g_hash_table_insert(theme->abstracts,
- g_strdup(node->key),
- g_strdup(node->value));
+ if (node->key == NULL || node->value == NULL)
+ continue;
+
+ if (g_hash_table_lookup_extended(theme->abstracts, node->key,
+ &oldkey, &oldvalue)) {
+ /* new values override old ones */
+ g_hash_table_remove(theme->abstracts, oldkey);
+ g_free(oldkey);
+ g_free(oldvalue);
}
+
+ g_hash_table_insert(theme->abstracts, g_strdup(node->key),
+ g_strdup(node->value));
}
}
@@ -742,7 +801,17 @@ static int theme_read(THEME_REC *theme, const char *path, const char *data)
config_get_int(config, NULL, "default_color", 0);
theme->default_real_color =
config_get_int(config, NULL, "default_real_color", 7);
- theme_read_replaces(config, theme);
+ 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);
+ }
theme_read_abstracts(config, theme);
rec.theme = theme;
diff --git a/src/fe-common/core/themes.h b/src/fe-common/core/themes.h
index d1e0283f..96f23400 100644
--- a/src/fe-common/core/themes.h
+++ b/src/fe-common/core/themes.h
@@ -23,7 +23,7 @@ typedef struct {
wanted. default is 7 (white). */
GHashTable *modules;
- GSList *replace_keys;
+ int replace_keys[256]; /* index to replace_values for each char */
GSList *replace_values;
GHashTable *abstracts;
@@ -46,6 +46,19 @@ THEME_REC *theme_load(const char *name);
void theme_register_module(const char *module, FORMAT_REC *formats);
void theme_unregister_module(const char *module);
+#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, don't try to expand it (ie. {xx }, but not {xx}) */
+#define EXPAND_FLAG_RECURSIVE_MASK 0x0f
+/* private */
+#define EXPAND_FLAG_ROOT 0x10
+#define EXPAND_FLAG_LASTCOLOR_ARG 0x20
+
+char *theme_format_expand(THEME_REC *theme, const char *format);
+char *theme_format_expand_data(THEME_REC *theme, const char **format,
+ char default_fg, char default_bg,
+ char *save_last_fg, char *save_last_bg,
+ int flags);
+
void themes_init(void);
void themes_deinit(void);