diff --git a/src/fe-common/core/hilight-text.c b/src/fe-common/core/hilight-text.c index 1ba14031..881a3be7 100644 --- a/src/fe-common/core/hilight-text.c +++ b/src/fe-common/core/hilight-text.c @@ -141,11 +141,57 @@ static void sig_print_text(WINDOW_REC *window, SERVER_REC *server, const char *c } } +/* color name -> mirc color number */ +static int mirc_color_name(const char *name) +{ + static const char *names[] = { + "bla dbla", /* black */ + "blu dblu", /* blue */ + "gree dgree", /* green */ + "r dr br lr", /* red .. um.. only one of them. */ + "br dbr dy", /* brown / dark yello */ + "m p dm dp", /* magenta / purple */ + "o", /* orange */ + "y by", /* yellow */ + "bg lg", /* bright green */ + "c dc", /* cyan */ + "bc lc", /* bright cyan */ + "bb lb", /* bright blue */ + "bm bp lm lp", /* bright magenta/purple */ + "dgray dgrey", /* dark grey */ + "grey gray", /* grey */ + "w", /* white */ + NULL + }; + + const char *p, *pname; + int n, ok; + + for (n = 0; names[n] != NULL; n++) { + pname = name; ok = TRUE; + for (p = names[n]; ; p++) { + if (*p == ' ' || *p == '\0') { + if (ok) return n+1; + if (*p == '\0') break; + + ok = TRUE; + pname = name; + } else if (toupper((int) *p) == toupper((int) *pname)) + pname++; + else + ok = FALSE; + } + } + + return -1; +} + char *hilight_match(const char *channel, const char *nickmask, int level, const char *str) { GSList *tmp; const char *color; - int len, best_match; + char number[MAX_INT_STRLEN]; + int len, best_match, colornum; g_return_val_if_fail(str != NULL, NULL); @@ -155,6 +201,9 @@ char *hilight_match(const char *channel, const char *nickmask, int level, const if ((level & (rec->level > 0 ? rec->level : DEFAULT_HILIGHT_CHECK_LEVEL)) == 0) continue; + if ((rec->nick && nickmask == NULL) || + (!rec->nick && nickmask != NULL)) + continue; if (rec->channels != NULL && (channel == NULL || strarray_find(rec->channels, channel) == -1)) continue; if (rec->nickmask) { @@ -182,13 +231,21 @@ char *hilight_match(const char *channel, const char *nickmask, int level, const return NULL; if (color == NULL) color = settings_get_str("hilight_color"); + if (isalpha((int) *color)) { + /* color was specified with it's name - try to convert it */ + colornum = mirc_color_name(color); + if (colornum <= 0) colornum = 16; + + ltoa(number, colornum); + color = number; + } return g_strconcat(isdigit(*color) ? "\003" : "", color, NULL); } static void sig_print_text_stripped(WINDOW_REC *window, SERVER_REC *server, const char *channel, gpointer plevel, const char *str) { char *newstr, *color; - int level; + int level, oldlevel; g_return_if_fail(str != NULL); @@ -196,7 +253,17 @@ static void sig_print_text_stripped(WINDOW_REC *window, SERVER_REC *server, cons if (level & (MSGLEVEL_NOHILIGHT|MSGLEVEL_HILIGHT)) return; color = hilight_match(channel, NULL, level, str); - if (color == NULL) return; + if (color == NULL) return; + + if (*color == 3) { + /* colorify */ + window->last_color = atoi(color+1); + } + + oldlevel = window->new_data; + window->new_data = NEWDATA_HILIGHT; + signal_emit("window hilight", 2, window, GINT_TO_POINTER(oldlevel)); + signal_emit("window activity", 2, window, GINT_TO_POINTER(oldlevel)); hilight_next = FALSE; @@ -208,6 +275,8 @@ static void sig_print_text_stripped(WINDOW_REC *window, SERVER_REC *server, cons g_free(newstr); hilight_next = TRUE; + + g_free_not_null(color); } static void read_hilight_config(void) @@ -241,7 +310,8 @@ static void read_hilight_config(void) rec->color = color == NULL || *color == '\0' ? NULL : g_strdup(color); rec->level = config_node_get_int(node, "level", 0); - rec->nickmask = config_node_get_bool(node, "nickmask", FALSE); + rec->nick = config_node_get_bool(node, "nick", TRUE); + rec->nickmask = config_node_get_bool(node, "mask", FALSE); rec->fullword = config_node_get_bool(node, "fullword", FALSE); rec->regexp = config_node_get_bool(node, "regexp", FALSE); @@ -286,7 +356,7 @@ static void cmd_hilight_show(void) static void cmd_hilight(const char *data) { - /* /HILIGHT [-nick] [-mask | -regexp | -word] [-color ] [-level ] [-channels ] */ + /* /HILIGHT [-nick | -nonick] [-mask | -regexp | -word] [-color ] [-level ] [-channels ] */ GHashTable *optlist; HILIGHT_REC *rec; char *colorarg, *levelarg, *chanarg, *text; @@ -328,7 +398,9 @@ static void cmd_hilight(const char *data) } hilights = g_slist_append(hilights, rec); - rec->nick = g_hash_table_lookup(optlist, "nick") != NULL; + rec->nick = settings_get_bool("hilight_only_nick") ? + g_hash_table_lookup(optlist, "nonick") == NULL : + g_hash_table_lookup(optlist, "nick") != NULL; rec->nickmask = g_hash_table_lookup(optlist, "mask") != NULL; rec->fullword = g_hash_table_lookup(optlist, "word") != NULL; rec->regexp = g_hash_table_lookup(optlist, "regexp") != NULL; @@ -373,6 +445,7 @@ void hilight_text_init(void) read_hilight_config(); settings_add_str("misc", "hilight_color", "8"); + settings_add_bool("misc", "hilight_only_nick", TRUE); signal_add_first("print text", (SIGNAL_FUNC) sig_print_text); signal_add_first("print text stripped", (SIGNAL_FUNC) sig_print_text_stripped); @@ -380,7 +453,7 @@ void hilight_text_init(void) command_bind("hilight", NULL, (SIGNAL_FUNC) cmd_hilight); command_bind("dehilight", NULL, (SIGNAL_FUNC) cmd_dehilight); - command_set_options("hilight", "-color -level -channels nick mask word regexp"); + command_set_options("hilight", "-color -level -channels nick nonick mask word regexp"); } void hilight_text_deinit(void) diff --git a/src/fe-common/core/window-activity.c b/src/fe-common/core/window-activity.c index 459e3a1a..1f18b12f 100644 --- a/src/fe-common/core/window-activity.c +++ b/src/fe-common/core/window-activity.c @@ -39,15 +39,16 @@ static void sig_hilight_text(WINDOW_REC *window, SERVER_REC *server, const char return; new_data = (level & MSGLEVEL_HILIGHT) ? - NEWDATA_MSG_FORYOU : NEWDATA_TEXT; + NEWDATA_HILIGHT : NEWDATA_TEXT; - if (new_data < NEWDATA_MSG_FORYOU && + if (new_data < NEWDATA_HILIGHT && channel != NULL && find_substr(noact_channels, channel)) return; oldlevel = window->new_data; if (window->new_data < new_data) { window->new_data = new_data; + window->last_color = 0; signal_emit("window hilight", 1, window); } @@ -60,6 +61,7 @@ static void sig_dehilight(WINDOW_REC *window, WI_ITEM_REC *item) if (item != NULL && item->new_data != 0) { item->new_data = 0; + item->last_color = 0; signal_emit("window item hilight", 1, item); } } @@ -77,6 +79,7 @@ static void sig_dehilight_window(WINDOW_REC *window) if (window->new_data != 0) { oldlevel = window->new_data; window->new_data = 0; + window->last_color = 0; signal_emit("window hilight", 2, window, GINT_TO_POINTER(oldlevel)); } signal_emit("window activity", 2, window, GINT_TO_POINTER(oldlevel)); @@ -89,21 +92,25 @@ static void sig_hilight_window_item(WI_ITEM_REC *item) { WINDOW_REC *window; GSList *tmp; - int level, oldlevel; + int level, oldlevel, color; - if (item->new_data < NEWDATA_MSG_FORYOU && + if (item->new_data < NEWDATA_HILIGHT && find_substr(noact_channels, item->name)) return; - window = window_item_window(item); level = 0; + window = window_item_window(item); level = 0; color = 0; for (tmp = window->items; tmp != NULL; tmp = tmp->next) { item = tmp->data; - if (item->new_data > level) + if (item->new_data > level) { level = item->new_data; + color = item->last_color; + } } oldlevel = window->new_data; + if (level == MSGLEVEL_HILIGHT) + window->last_color = color; if (window->new_data < level || level == 0) { window->new_data = level; signal_emit("window hilight", 2, window, GINT_TO_POINTER(oldlevel)); diff --git a/src/fe-common/core/windows.h b/src/fe-common/core/windows.h index 69f292e4..a74f575d 100644 --- a/src/fe-common/core/windows.h +++ b/src/fe-common/core/windows.h @@ -4,7 +4,7 @@ enum { NEWDATA_TEXT = 1, NEWDATA_MSG, - NEWDATA_MSG_FORYOU, + NEWDATA_HILIGHT, NEWDATA_CUSTOM }; @@ -19,6 +19,7 @@ typedef struct { char *name; int new_data; + int last_color; /* if NEWDATA_HILIGHT is set, color number could be specified here */ } WI_ITEM_REC; typedef struct { @@ -40,6 +41,7 @@ typedef struct { int level; int new_data; + int last_color; time_t last_timestamp; /* When was last timestamp printed */ time_t last_line; /* When was last line printed */ diff --git a/src/fe-common/irc/fe-common-irc.c b/src/fe-common/irc/fe-common-irc.c index 83f20899..25f4886b 100644 --- a/src/fe-common/irc/fe-common-irc.c +++ b/src/fe-common/irc/fe-common-irc.c @@ -61,15 +61,18 @@ void fe_ignore_deinit(void); void fe_query_init(void); void fe_query_deinit(void); -void irc_window_activity_init(void); -void irc_window_activity_deinit(void); - void irc_completion_init(void); void irc_completion_deinit(void); void fe_netsplit_init(void); void fe_netsplit_deinit(void); +void irc_hilight_text_init(void); +void irc_hilight_text_deinit(void); + +void irc_window_activity_init(void); +void irc_window_activity_deinit(void); + static char *autocon_server; static char *autocon_password; static int autocon_port; @@ -115,6 +118,7 @@ void fe_common_irc_init(void) fe_netsplit_init(); fe_query_init(); irc_completion_init(); + irc_hilight_text_init(); irc_window_activity_init(); fe_irc_modules_init(); @@ -135,6 +139,7 @@ void fe_common_irc_deinit(void) fe_netsplit_deinit(); fe_query_deinit(); irc_completion_deinit(); + irc_hilight_text_deinit(); irc_window_activity_deinit(); theme_unregister(); diff --git a/src/fe-common/irc/irc-hilight-text.c b/src/fe-common/irc/irc-hilight-text.c index 7c8a46be..7969f7d4 100644 --- a/src/fe-common/irc/irc-hilight-text.c +++ b/src/fe-common/irc/irc-hilight-text.c @@ -19,10 +19,13 @@ */ #include "module.h" +#include "signals.h" #include "settings.h" #include "hilight-text.h" +static int last_color; + char *irc_hilight_find_nick(const char *channel, const char *nick, const char *address, int level, const char *msg) { @@ -32,6 +35,28 @@ char *irc_hilight_find_nick(const char *channel, const char *nick, color = hilight_match(channel, mask, level, msg); g_free(mask); + last_color = (color != NULL && *color == 3) ? + atoi(color+1) : 0; return color; } +int irc_hilight_last_color(void) +{ + return last_color; +} + +static void event_privmsg(void) +{ + last_color = 0; +} + +void irc_hilight_text_init(void) +{ + last_color = 0; + signal_add_last("event privmsg", (SIGNAL_FUNC) event_privmsg); +} + +void irc_hilight_text_deinit(void) +{ + signal_remove("event privmsg", (SIGNAL_FUNC) event_privmsg); +} diff --git a/src/fe-common/irc/irc-hilight-text.h b/src/fe-common/irc/irc-hilight-text.h index 243ec653..9d2b1b3d 100644 --- a/src/fe-common/irc/irc-hilight-text.h +++ b/src/fe-common/irc/irc-hilight-text.h @@ -4,4 +4,6 @@ char *irc_hilight_find_nick(const char *channel, const char *nick, const char *address, int level, const char *msg); +int irc_hilight_last_color(void); + #endif diff --git a/src/fe-common/irc/irc-window-activity.c b/src/fe-common/irc/irc-window-activity.c index 765939ff..6fd433a9 100644 --- a/src/fe-common/irc/irc-window-activity.c +++ b/src/fe-common/irc/irc-window-activity.c @@ -30,6 +30,7 @@ #include "completion.h" #include "windows.h" #include "window-items.h" +#include "irc-hilight-text.h" static void event_privmsg(const char *data, IRC_SERVER_REC *server, const char *nick, const char *addr) { @@ -53,9 +54,10 @@ static void event_privmsg(const char *data, IRC_SERVER_REC *server, const char * that it didn't get ignored */ if (window != active_win && !ignore_check(server, nick, addr, target, msg, level)) { /* hilight */ - level = !ischannel(*target) || + item->last_color = irc_hilight_last_color(); + level = item->last_color > 0 || !ischannel(*target) || irc_nick_match(server->nick, msg) ? - NEWDATA_MSG_FORYOU : NEWDATA_MSG; + NEWDATA_HILIGHT : NEWDATA_MSG; if (item != NULL && item->new_data < level) { item->new_data = level; signal_emit("window item hilight", 1, item); @@ -64,6 +66,7 @@ static void event_privmsg(const char *data, IRC_SERVER_REC *server, const char * if (window->new_data < level) { window->new_data = level; + window->last_color = irc_hilight_last_color(); signal_emit("window hilight", 2, window, GINT_TO_POINTER(oldlevel)); } signal_emit("window activity", 2, window, GINT_TO_POINTER(oldlevel)); diff --git a/src/fe-text/gui-printtext.c b/src/fe-text/gui-printtext.c index e80afa19..07f63ee9 100644 --- a/src/fe-text/gui-printtext.c +++ b/src/fe-text/gui-printtext.c @@ -32,7 +32,7 @@ #define TEXT_CHUNK_USABLE_SIZE (LINE_TEXT_CHUNK_SIZE-2-sizeof(char*)) -static int mirc_colors[] = { 15, 0, 1, 2, 4, 6, 5, 4, 14, 10, 3, 11, 9, 13, 8, 7, 15 }; +int mirc_colors[] = { 15, 0, 1, 2, 12, 6, 5, 4, 14, 10, 3, 11, 9, 13, 8, 7, 15 }; static int scrollback_lines, scrollback_hours; #define mark_temp_eol(text) \ diff --git a/src/fe-text/gui-printtext.h b/src/fe-text/gui-printtext.h index 6c6e24d9..aeeb5cce 100644 --- a/src/fe-text/gui-printtext.h +++ b/src/fe-text/gui-printtext.h @@ -22,6 +22,8 @@ enum NUM_COLORS }; +extern int mirc_colors[]; + void gui_printtext_init(void); void gui_printtext_deinit(void); diff --git a/src/fe-text/statusbar-items.c b/src/fe-text/statusbar-items.c index 12c8b75a..4705cc64 100644 --- a/src/fe-text/statusbar-items.c +++ b/src/fe-text/statusbar-items.c @@ -327,7 +327,7 @@ static void draw_activity(gchar *title, gboolean act, gboolean det) { window = tmp->data; - is_det = window->new_data == NEWDATA_MSG_FORYOU; + is_det = window->new_data >= NEWDATA_HILIGHT; if (is_det && !det) continue; if (!is_det && !act) continue; @@ -342,14 +342,14 @@ static void draw_activity(gchar *title, gboolean act, gboolean det) ltoa(str, window->refnum); switch (window->new_data) { - case NEWDATA_TEXT: + case NEWDATA_TEXT: set_color((1 << 4)+3); break; - case NEWDATA_MSG: + case NEWDATA_MSG: set_color((1 << 4)+15); break; - case NEWDATA_MSG_FORYOU: - set_color((1 << 4)+13); + case NEWDATA_HILIGHT: + set_color((1 << 4) + (window->last_color > 0 ? mirc_colors[window->last_color] : 13)); break; } addstr(str); @@ -372,7 +372,7 @@ static void statusbar_activity(SBAR_ITEM_REC *item, int ypos) size_needed += 1+ltoa(str, window->refnum); - if (!use_colors && window->new_data == NEWDATA_MSG_FORYOU) + if (!use_colors && window->new_data >= NEWDATA_HILIGHT) det = TRUE; else act = TRUE;