Mercurial > ~mikael > mcabber > hg
diff mcabber/src/screen.c @ 1272:033576acac4c
Add configurable roster colors (Michal 'vorner' Vaner)
author | Mikael Berthe <mikael@lilotux.net> |
---|---|
date | Tue, 21 Aug 2007 20:49:03 +0200 |
parents | dbc907b2d92f |
children | 8bbc764139ef |
line wrap: on
line diff
--- a/mcabber/src/screen.c Mon Aug 20 21:30:16 2007 +0200 +++ b/mcabber/src/screen.c Tue Aug 21 20:49:03 2007 +0200 @@ -143,9 +143,59 @@ AspellSpeller *spell_checker; #endif +typedef struct { + char *status, *wildcard; + int color; + GPatternSpec *compiled; +} rostercolor; + +GSList *rostercolrules = NULL; + /* Functions */ -static int FindColor(const char *name) +static int color_conv_table[] = { + COLOR_BLACK, + COLOR_RED, + COLOR_GREEN, + COLOR_YELLOW, + COLOR_BLUE, + COLOR_MAGENTA, + COLOR_CYAN, + COLOR_WHITE +}; + +static int color_conv_table_fg[] = { + COLOR_BLACK_FG, + COLOR_RED_FG, + COLOR_GREEN_FG, + COLOR_YELLOW_FG, + COLOR_BLUE_FG, + COLOR_MAGENTA_FG, + COLOR_CYAN_FG, + COLOR_WHITE_FG +}; + +static int color_to_color_fg(int color) +{ + unsigned i = 0; + for ( ; i < sizeof color_conv_table / sizeof *color_conv_table; i++) + if (color == color_conv_table[i]) + return color_conv_table_fg[i]; + return -1; +} + +static int color_fg_to_color(int color) +{ + unsigned i = 0; + if (color >= COLOR_BLACK_BOLD_FG) + color -= COLOR_BLACK_BOLD_FG - COLOR_BLACK_FG; + for ( ; i < sizeof color_conv_table_fg / sizeof *color_conv_table_fg; i++) + if (color == color_conv_table_fg[i]) + return color_conv_table[i]; + return -1; +} + +static int FindColorInternal(const char *name) { if (!strcmp(name, "default")) return -1; @@ -166,10 +216,87 @@ if (!strcmp(name, "white")) return COLOR_WHITE; + return -2; +} + +static int FindColor(const char *name) +{ + int result = FindColorInternal(name); + if (result != -2) + return result; + scr_LogPrint(LPRINT_LOGNORM, "ERROR: Wrong color: %s", name); return -1; } +static void free_rostercolrule(rostercolor *col) +{ + g_free(col->status); + g_free(col->wildcard); + g_pattern_spec_free(col->compiled); + g_free(col); +} + +void scr_RosterClearColor(void) +{ + GSList *head; + for (head = rostercolrules; head; head = g_slist_next(head)) { + free_rostercolrule(head->data); + } + g_slist_free(rostercolrules); + rostercolrules = NULL; +} + +bool scr_RosterColor(const char *status, const char *wildcard, + const char *color) +{ + GSList *head; + GSList *found = NULL; + for (head = rostercolrules; head; head = g_slist_next(head)) { + rostercolor *rc = head->data; + if ((!strcmp(status, rc->status)) && (!strcmp(wildcard, rc->wildcard))) { + found = head; + break; + } + } + if (!strcmp(color,"-")) {//Delete the rule + if (found) { + free_rostercolrule(found->data); + rostercolrules = g_slist_delete_link(rostercolrules, found); + return TRUE; + } else { + scr_LogPrint(LPRINT_NORMAL, "No such color rule, nothing removed"); + return FALSE; + } + } else { + bool isbright = false; + int cl; + if (!strncmp(color, "bright", 6)) { + isbright = true; + color += 6; + } + cl = color_to_color_fg(FindColorInternal(color)); + if (isbright) + cl += COLOR_BLACK_BOLD_FG - COLOR_BLACK_FG; + if (cl < 0 ) { + scr_LogPrint(LPRINT_NORMAL, "No such color name"); + return FALSE; + } + if (found) { + rostercolor *rc = found->data; + rc->color = cl; + } else { + rostercolor *rc = g_new(rostercolor, 1); + rc->status = g_strdup(status); + rc->wildcard = g_strdup(wildcard); + rc->compiled = g_pattern_spec_new(wildcard); + rc->color = cl; + rostercolrules = g_slist_prepend(rostercolrules, rc); + } + return TRUE; + } +} + static void ParseColors(void) { const char *colors[] = { @@ -263,6 +390,11 @@ break; } } + for (i = COLOR_BLACK_FG; i < COLOR_max; i++) { + init_pair(i, color_fg_to_color(i), FindColor(background)); + if (i >= COLOR_BLACK_BOLD_FG) + COLOR_ATTRIB[i] = A_BOLD; + } } static void init_keycodes(void) @@ -1429,8 +1561,22 @@ } else { if (pending == '#') wattrset(rosterWnd, get_color(COLOR_ROSTERNMSG)); - else - wattrset(rosterWnd, get_color(COLOR_ROSTER)); + else { + int color = get_color(COLOR_ROSTER); + if ((!isspe) && (!isgrp)) {//Look for color rules + GSList *head; + const char *jid = buddy_getjid(BUDDATA(buddy)); + for (head = rostercolrules; head; head = g_slist_next(head)) { + rostercolor *rc = head->data; + if (g_pattern_match_string(rc->compiled, jid) && + (!strcmp("*", rc->status) || strchr(rc->status, status))) { + color = get_color(rc->color); + break; + } + } + } + wattrset(rosterWnd, color); + } } if (Roster_Width > 7)