comparison 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
comparison
equal deleted inserted replaced
1291:9f64f548ac16 1292:382ec54b584e
26 #include <time.h> 26 #include <time.h>
27 #include <ctype.h> 27 #include <ctype.h>
28 #include <locale.h> 28 #include <locale.h>
29 #include <langinfo.h> 29 #include <langinfo.h>
30 #include <config.h> 30 #include <config.h>
31 #include <assert.h>
31 32
32 #ifdef HAVE_ASPELL_H 33 #ifdef HAVE_ASPELL_H
33 # include <aspell.h> 34 # include <aspell.h>
34 #endif 35 #endif
35 36
148 char *status, *wildcard; 149 char *status, *wildcard;
149 int color; 150 int color;
150 GPatternSpec *compiled; 151 GPatternSpec *compiled;
151 } rostercolor; 152 } rostercolor;
152 153
153 GSList *rostercolrules = NULL; 154 static GSList *rostercolrules = NULL;
155
156 static GHashTable *muccolors = NULL, *nickcolors = NULL;
157
158 typedef struct {
159 bool manual;//Manually set?
160 int color;
161 } nickcolor;
162
163 static int nickcolcount = 0, *nickcols = NULL;
164 static muccoltype glob_muccol = MC_OFF;
154 165
155 /* Functions */ 166 /* Functions */
156 167
157 static int color_conv_table[] = { 168 static int color_conv_table[] = {
158 COLOR_BLACK, 169 COLOR_BLACK,
226 if (result != -2) 237 if (result != -2)
227 return result; 238 return result;
228 239
229 scr_LogPrint(LPRINT_LOGNORM, "ERROR: Wrong color: %s", name); 240 scr_LogPrint(LPRINT_LOGNORM, "ERROR: Wrong color: %s", name);
230 return -1; 241 return -1;
242 }
243
244 static void ensure_string_htable(GHashTable **table,
245 GDestroyNotify value_destroy_func)
246 {
247 if (*table)//Have it already
248 return;
249 *table = g_hash_table_new_full(g_str_hash, g_str_equal,
250 g_free, value_destroy_func);
251 }
252
253 // Sets the coloring mode for given MUC
254 // The MUC room does not need to be in the roster at that time
255 // muc - the JID of room
256 // type - the new type
257 void scr_MucColor(const char *muc, muccoltype type)
258 {
259 gchar *muclow = g_utf8_strdown(muc, -1);
260 if (type == MC_REMOVE) {//Remove it
261 if (strcmp(muc, "*")) {
262 if (muccolors && g_hash_table_lookup(muccolors, muclow))
263 g_hash_table_remove(muccolors, muclow);
264 } else {
265 scr_LogPrint(LPRINT_NORMAL, "Can not remove global coloring mode");
266 }
267 g_free(muclow);
268 } else {//Add or overwrite
269 if (strcmp(muc, "*")) {
270 ensure_string_htable(&muccolors, g_free);
271 muccoltype *value = g_new(muccoltype, 1);
272 *value = type;
273 g_hash_table_replace(muccolors, muclow, value);
274 } else {
275 glob_muccol = type;
276 g_free(muclow);
277 }
278 }
279 //Need to redraw?
280 if (chatmode && ((buddy_search_jid(muc) == current_buddy) || !strcmp(muc, "*")))
281 scr_UpdateBuddyWindow();
282 }
283
284 // Sets the color for nick in MUC
285 // If color is "-", the color is marked as automaticly assigned and is
286 // not used if the room is in the "preset" mode
287 void scr_MucNickColor(const char *nick, const char *color)
288 {
289 char *snick = g_strdup_printf("<%s>", nick), *mnick = g_strdup_printf("*%s ", nick);
290 bool need_update = false;
291 if (!strcmp(color, "-")) {//Remove the color
292 if (nickcolors) {
293 nickcolor *nc = g_hash_table_lookup(nickcolors, snick);
294 if (nc) {//Have this nick already
295 nc->manual = false;
296 nc = g_hash_table_lookup(nickcolors, mnick);
297 assert(nc);//Must have both at the same time
298 nc->manual = false;
299 }// Else -> no color saved, nothing to delete
300 }
301 g_free(snick);//They are not saved in the hash
302 g_free(mnick);
303 need_update = true;
304 } else {
305 int cl = color_to_color_fg(FindColorInternal(color));
306 if (cl < 0) {
307 scr_LogPrint(LPRINT_NORMAL, "No such color name");
308 g_free(snick);
309 g_free(mnick);
310 } else {
311 nickcolor *nc = g_new(nickcolor, 1);
312 ensure_string_htable(&nickcolors, NULL);
313 nc->manual = true;
314 nc->color = cl;
315 //Free the struct, if any there already
316 g_free(g_hash_table_lookup(nickcolors, mnick));
317 //Save the new ones
318 g_hash_table_replace(nickcolors, mnick, nc);
319 g_hash_table_replace(nickcolors, snick, nc);
320 need_update = true;
321 }
322 }
323 if (need_update && chatmode &&
324 (buddy_gettype(BUDDATA(current_buddy)) & ROSTER_TYPE_ROOM))
325 scr_UpdateBuddyWindow();
231 } 326 }
232 327
233 static void free_rostercolrule(rostercolor *col) 328 static void free_rostercolrule(rostercolor *col)
234 { 329 {
235 g_free(col->status); 330 g_free(col->status);
401 } 496 }
402 for (i = COLOR_BLACK_FG; i < COLOR_max; i++) { 497 for (i = COLOR_BLACK_FG; i < COLOR_max; i++) {
403 init_pair(i, color_fg_to_color(i), FindColor(background)); 498 init_pair(i, color_fg_to_color(i), FindColor(background));
404 if (i >= COLOR_BLACK_BOLD_FG) 499 if (i >= COLOR_BLACK_BOLD_FG)
405 COLOR_ATTRIB[i] = A_BOLD; 500 COLOR_ATTRIB[i] = A_BOLD;
501 }
502 char *ncolors = g_strdup(settings_opt_get("nick_colors")),
503 *ncolor_start = ncolors;
504 if (ncolors) {
505 while (*ncolors) {
506 if ((*ncolors == ' ') || (*ncolors == '\t')) {
507 ncolors ++;
508 } else {
509 char *end = ncolors;
510 bool ended = false;
511 while (*end && (*end != ' ') && (*end != '\t'))
512 end++;
513 if (!end)
514 ended = true;
515 *end = '\0';
516 int cl = color_to_color_fg(FindColorInternal(ncolors));
517 if (cl < 0) {
518 scr_LogPrint(LPRINT_NORMAL, "Unknown color %s", ncolors);
519 } else {
520 nickcols = g_realloc(nickcols, (++nickcolcount) * sizeof *nickcols);
521 nickcols[nickcolcount-1] = cl;
522 }
523 if (ended)
524 ncolors = NULL;
525 else
526 ncolors = end+1;
527 }
528 }
529 g_free(ncolor_start);
530 }
531 if (!nickcols) {//Fallback to have something
532 nickcolcount = 1;
533 nickcols = g_new(int, 1);
534 *nickcols = COLOR_GENERAL;
406 } 535 }
407 } 536 }
408 537
409 static void init_keycodes(void) 538 static void init_keycodes(void)
410 { 539 {
908 1037
909 //The MUC nick - overwrite with propper color 1038 //The MUC nick - overwrite with propper color
910 if (line->mucnicklen && (line->flags & HBB_PREFIX_IN)) { 1039 if (line->mucnicklen && (line->flags & HBB_PREFIX_IN)) {
911 //Store the char after the nick 1040 //Store the char after the nick
912 char tmp = line->text[line->mucnicklen]; 1041 char tmp = line->text[line->mucnicklen];
913 //TODO choose the color in proper way 1042 muccoltype type = glob_muccol, *typetmp;
914 wattrset(win_entry->win, get_color(COLOR_RED_BOLD_FG));
915 //Terminate the string after the nick 1043 //Terminate the string after the nick
916 line->text[line->mucnicklen] = '\0'; 1044 line->text[line->mucnicklen] = '\0';
1045 char *mucjid = g_utf8_strdown(CURRENT_JID, -1);
1046 if (muccolors) {
1047 typetmp = g_hash_table_lookup(muccolors, mucjid);
1048 if (typetmp)
1049 type = *typetmp;
1050 }
1051 g_free(mucjid);
1052 nickcolor *actual = NULL;
1053 // Need to generate some random color?
1054 if ((type == MC_ALL) && (!nickcolors ||
1055 !g_hash_table_lookup(nickcolors, line->text))) {
1056 ensure_string_htable(&nickcolors, NULL);
1057 char *snick = g_strdup(line->text), *mnick = g_strdup(line->text);
1058 nickcolor *nc = g_new(nickcolor, 1);
1059 nc->color = nickcols[random() % nickcolcount];
1060 nc->manual = false;
1061 *snick = '<';
1062 snick[strlen(snick)-1] = '>';
1063 *mnick = '*';
1064 mnick[strlen(mnick)-1] = ' ';
1065 //Insert them
1066 g_hash_table_insert(nickcolors, snick, nc);
1067 g_hash_table_insert(nickcolors, mnick, nc);
1068 }
1069 if (nickcolors)
1070 actual = g_hash_table_lookup(nickcolors, line->text);
1071 if (actual && ((type == MC_ALL) || (actual->manual)))
1072 wattrset(win_entry->win, get_color(actual->color));
917 wprintw(win_entry->win, "%s", line->text); 1073 wprintw(win_entry->win, "%s", line->text);
918 //Return the char 1074 //Return the char
919 line->text[line->mucnicklen] = tmp; 1075 line->text[line->mucnicklen] = tmp;
920 //Return the color back 1076 //Return the color back
921 wattrset(win_entry->win, get_color(color)); 1077 wattrset(win_entry->win, get_color(color));