# HG changeset patch # User Michal 'vorner' Vaner # Date 1188288699 -7200 # Node ID 382ec54b584e2f8a4b9f8ea2822031b9fc4cd1ee # Parent 9f64f548ac167c728cf143bb73464156b92d7ded Muc nick coloring functionality diff -r 9f64f548ac16 -r 382ec54b584e mcabber/src/commands.c --- a/mcabber/src/commands.c Sun Aug 26 22:23:30 2007 +0200 +++ b/mcabber/src/commands.c Tue Aug 28 10:11:39 2007 +0200 @@ -257,6 +257,8 @@ // Color category compl_add_category_word(COMPL_COLOR, "roster"); + compl_add_category_word(COMPL_COLOR, "muc"); + compl_add_category_word(COMPL_COLOR, "mucnick"); } // expandalias(line) @@ -724,7 +726,7 @@ if (!strcasecmp(subcmd, "roster")) { char **arglist = split_arg(arg, 3, 0); - char *status = *arglist, *wildcard = arglist[1], *color = arglist[2]; + char *status = *arglist, *wildcard = to_utf8(arglist[1]), *color = arglist[2]; if (status && !strcmp(status, "clear")) { // Not a color command, clear all scr_RosterClearColor(); update_roster = TRUE; @@ -737,6 +739,44 @@ } } free_arg_lst(arglist); + g_free(wildcard); + } else if (!strcasecmp(subcmd, "muc")) { + char **arglist = split_arg(arg, 2, 0); + char *free_muc = to_utf8(*arglist); + const char *muc = free_muc, *mode = arglist[1]; + if (!muc || !*muc) + scr_LogPrint(LPRINT_NORMAL, "What MUC?"); + else { + if (!strcmp(muc, ".")) + if (!(muc = CURRENT_JID)) + scr_LogPrint(LPRINT_NORMAL, "No JID selected"); + if (muc) { + if (check_jid_syntax(muc) && strcmp(muc, "*")) + scr_LogPrint(LPRINT_NORMAL, "Not a JID"); + else { + if (!mode || !*mode || !strcasecmp(mode, "on")) + scr_MucColor(muc, MC_ALL); + else if (!strcasecmp(mode, "preset")) + scr_MucColor(muc, MC_PRESET); + else if (!strcasecmp(mode, "off")) + scr_MucColor(muc, MC_OFF); + else if (!strcmp(mode, "-")) + scr_MucColor(muc, MC_REMOVE); + else + scr_LogPrint(LPRINT_NORMAL, "Unknown coloring mode"); + } + } + } + free_arg_lst(arglist); + g_free(free_muc); + } else if (!strcasecmp(subcmd, "mucnick")) { + char **arglist = split_arg(arg, 2, 0); + const char *nick = *arglist, *color = arglist[1]; + if (!nick || !*nick || !color || !*color) + scr_LogPrint(LPRINT_NORMAL, "Missing argument"); + else + scr_MucNickColor(nick, color); + free_arg_lst(arglist); } else scr_LogPrint(LPRINT_NORMAL, "Unrecognized parameter!"); free_arg_lst(paramlst); diff -r 9f64f548ac16 -r 382ec54b584e mcabber/src/roster.c --- a/mcabber/src/roster.c Sun Aug 26 22:23:30 2007 +0200 +++ b/mcabber/src/roster.c Tue Aug 28 10:11:39 2007 +0200 @@ -867,6 +867,8 @@ const char *buddy_getjid(gpointer rosterdata) { + if (!rosterdata) + return NULL; roster *roster_usr = rosterdata; return roster_usr->jid; } @@ -1270,7 +1272,7 @@ // Look for a buddy with specified jid. // Search begins at buddylist; if no match is found in the the buddylist, // return NULL; -GList *buddy_search_jid(char *jid) +GList *buddy_search_jid(const char *jid) { GList *buddy; roster *roster_usr; diff -r 9f64f548ac16 -r 382ec54b584e mcabber/src/roster.h --- a/mcabber/src/roster.h Sun Aug 26 22:23:30 2007 +0200 +++ b/mcabber/src/roster.h Tue Aug 28 10:11:39 2007 +0200 @@ -193,7 +193,7 @@ void buddy_del_all_resources(gpointer rosterdata); void buddy_setflags(gpointer rosterdata, guint flags, guint value); guint buddy_getflags(gpointer rosterdata); -GList *buddy_search_jid(char *jid); +GList *buddy_search_jid(const char *jid); GList *buddy_search(char *string); void foreach_buddy(guint roster_type, void (*pfunc)(gpointer rosterdata, void *param), diff -r 9f64f548ac16 -r 382ec54b584e mcabber/src/screen.c --- 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 #include #include +#include #ifdef HAVE_ASPELL_H # include @@ -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; diff -r 9f64f548ac16 -r 382ec54b584e mcabber/src/screen.h --- a/mcabber/src/screen.h Sun Aug 26 22:23:30 2007 +0200 +++ b/mcabber/src/screen.h Tue Aug 28 10:11:39 2007 +0200 @@ -92,6 +92,13 @@ } mcode; } keycode; +typedef enum { + MC_ALL, + MC_PRESET, + MC_OFF, + MC_REMOVE +} muccoltype; + void scr_init_bindings(void); void scr_Getch(keycode *kcode); @@ -156,6 +163,8 @@ void scr_BufferScrollUpDown(int updown, unsigned int nblines); bool scr_RosterColor(const char *status, const char *wildcard, const char *color); void scr_RosterClearColor(void); +void scr_MucColor(const char *muc, muccoltype type); +void scr_MucNickColor(const char *nick, const char *color); #ifdef DEBUG_ENABLE void scr_BufferList(void); diff -r 9f64f548ac16 -r 382ec54b584e mcabber/src/utils.c --- a/mcabber/src/utils.c Sun Aug 26 22:23:30 2007 +0200 +++ b/mcabber/src/utils.c Tue Aug 28 10:11:39 2007 +0200 @@ -317,10 +317,10 @@ * Check if the full JID is valid * Return 0 if it is valid, non zero otherwise */ -int check_jid_syntax(char *fjid) +int check_jid_syntax(const char *fjid) { - char *str; - char *domain, *resource; + const char *str; + const char *domain, *resource; int domlen; if (!fjid) return 1; diff -r 9f64f548ac16 -r 382ec54b584e mcabber/src/utils.h --- a/mcabber/src/utils.h Sun Aug 26 22:23:30 2007 +0200 +++ b/mcabber/src/utils.h Tue Aug 28 10:11:39 2007 +0200 @@ -28,7 +28,7 @@ inline void safe_usleep(unsigned int usec); /* Only for delays < 1s */ -int check_jid_syntax(char *fjid); +int check_jid_syntax(const char *fjid); inline void mc_strtolower(char *str);