Mercurial > ~mikael > mcabber > hg
diff mcabber/src/screen.c @ 1292:382ec54b584e
Muc nick coloring functionality
author | Michal 'vorner' Vaner <vorner@ucw.cz> |
---|---|
date | Tue, 28 Aug 2007 10:11:39 +0200 |
parents | 9f64f548ac16 |
children | 86caabe72f3a |
line wrap: on
line diff
--- a/mcabber/src/screen.c Sun Aug 26 22:23:30 2007 +0200 +++ b/mcabber/src/screen.c Tue Aug 28 10:11:39 2007 +0200 @@ -28,6 +28,7 @@ #include <locale.h> #include <langinfo.h> #include <config.h> +#include <assert.h> #ifdef HAVE_ASPELL_H # include <aspell.h> @@ -150,7 +151,17 @@ GPatternSpec *compiled; } rostercolor; -GSList *rostercolrules = NULL; +static GSList *rostercolrules = NULL; + +static GHashTable *muccolors = NULL, *nickcolors = NULL; + +typedef struct { + bool manual;//Manually set? + int color; +} nickcolor; + +static int nickcolcount = 0, *nickcols = NULL; +static muccoltype glob_muccol = MC_OFF; /* Functions */ @@ -230,6 +241,90 @@ return -1; } +static void ensure_string_htable(GHashTable **table, + GDestroyNotify value_destroy_func) +{ + if (*table)//Have it already + return; + *table = g_hash_table_new_full(g_str_hash, g_str_equal, + g_free, value_destroy_func); +} + +// Sets the coloring mode for given MUC +// The MUC room does not need to be in the roster at that time +// muc - the JID of room +// type - the new type +void scr_MucColor(const char *muc, muccoltype type) +{ + gchar *muclow = g_utf8_strdown(muc, -1); + if (type == MC_REMOVE) {//Remove it + if (strcmp(muc, "*")) { + if (muccolors && g_hash_table_lookup(muccolors, muclow)) + g_hash_table_remove(muccolors, muclow); + } else { + scr_LogPrint(LPRINT_NORMAL, "Can not remove global coloring mode"); + } + g_free(muclow); + } else {//Add or overwrite + if (strcmp(muc, "*")) { + ensure_string_htable(&muccolors, g_free); + muccoltype *value = g_new(muccoltype, 1); + *value = type; + g_hash_table_replace(muccolors, muclow, value); + } else { + glob_muccol = type; + g_free(muclow); + } + } + //Need to redraw? + if (chatmode && ((buddy_search_jid(muc) == current_buddy) || !strcmp(muc, "*"))) + scr_UpdateBuddyWindow(); +} + +// Sets the color for nick in MUC +// If color is "-", the color is marked as automaticly assigned and is +// not used if the room is in the "preset" mode +void scr_MucNickColor(const char *nick, const char *color) +{ + char *snick = g_strdup_printf("<%s>", nick), *mnick = g_strdup_printf("*%s ", nick); + bool need_update = false; + if (!strcmp(color, "-")) {//Remove the color + if (nickcolors) { + nickcolor *nc = g_hash_table_lookup(nickcolors, snick); + if (nc) {//Have this nick already + nc->manual = false; + nc = g_hash_table_lookup(nickcolors, mnick); + assert(nc);//Must have both at the same time + nc->manual = false; + }// Else -> no color saved, nothing to delete + } + g_free(snick);//They are not saved in the hash + g_free(mnick); + need_update = true; + } else { + int cl = color_to_color_fg(FindColorInternal(color)); + if (cl < 0) { + scr_LogPrint(LPRINT_NORMAL, "No such color name"); + g_free(snick); + g_free(mnick); + } else { + nickcolor *nc = g_new(nickcolor, 1); + ensure_string_htable(&nickcolors, NULL); + nc->manual = true; + nc->color = cl; + //Free the struct, if any there already + g_free(g_hash_table_lookup(nickcolors, mnick)); + //Save the new ones + g_hash_table_replace(nickcolors, mnick, nc); + g_hash_table_replace(nickcolors, snick, nc); + need_update = true; + } + } + if (need_update && chatmode && + (buddy_gettype(BUDDATA(current_buddy)) & ROSTER_TYPE_ROOM)) + scr_UpdateBuddyWindow(); +} + static void free_rostercolrule(rostercolor *col) { g_free(col->status); @@ -404,6 +499,40 @@ if (i >= COLOR_BLACK_BOLD_FG) COLOR_ATTRIB[i] = A_BOLD; } + char *ncolors = g_strdup(settings_opt_get("nick_colors")), + *ncolor_start = ncolors; + if (ncolors) { + while (*ncolors) { + if ((*ncolors == ' ') || (*ncolors == '\t')) { + ncolors ++; + } else { + char *end = ncolors; + bool ended = false; + while (*end && (*end != ' ') && (*end != '\t')) + end++; + if (!end) + ended = true; + *end = '\0'; + int cl = color_to_color_fg(FindColorInternal(ncolors)); + if (cl < 0) { + scr_LogPrint(LPRINT_NORMAL, "Unknown color %s", ncolors); + } else { + nickcols = g_realloc(nickcols, (++nickcolcount) * sizeof *nickcols); + nickcols[nickcolcount-1] = cl; + } + if (ended) + ncolors = NULL; + else + ncolors = end+1; + } + } + g_free(ncolor_start); + } + if (!nickcols) {//Fallback to have something + nickcolcount = 1; + nickcols = g_new(int, 1); + *nickcols = COLOR_GENERAL; + } } static void init_keycodes(void) @@ -910,10 +1039,37 @@ if (line->mucnicklen && (line->flags & HBB_PREFIX_IN)) { //Store the char after the nick char tmp = line->text[line->mucnicklen]; - //TODO choose the color in proper way - wattrset(win_entry->win, get_color(COLOR_RED_BOLD_FG)); + muccoltype type = glob_muccol, *typetmp; //Terminate the string after the nick line->text[line->mucnicklen] = '\0'; + char *mucjid = g_utf8_strdown(CURRENT_JID, -1); + if (muccolors) { + typetmp = g_hash_table_lookup(muccolors, mucjid); + if (typetmp) + type = *typetmp; + } + g_free(mucjid); + nickcolor *actual = NULL; + // Need to generate some random color? + if ((type == MC_ALL) && (!nickcolors || + !g_hash_table_lookup(nickcolors, line->text))) { + ensure_string_htable(&nickcolors, NULL); + char *snick = g_strdup(line->text), *mnick = g_strdup(line->text); + nickcolor *nc = g_new(nickcolor, 1); + nc->color = nickcols[random() % nickcolcount]; + nc->manual = false; + *snick = '<'; + snick[strlen(snick)-1] = '>'; + *mnick = '*'; + mnick[strlen(mnick)-1] = ' '; + //Insert them + g_hash_table_insert(nickcolors, snick, nc); + g_hash_table_insert(nickcolors, mnick, nc); + } + if (nickcolors) + actual = g_hash_table_lookup(nickcolors, line->text); + if (actual && ((type == MC_ALL) || (actual->manual))) + wattrset(win_entry->win, get_color(actual->color)); wprintw(win_entry->win, "%s", line->text); //Return the char line->text[line->mucnicklen] = tmp;