Highlighting cleanups. Added /HILIGHT -priority option.

git-svn-id: http://svn.irssi.org/repos/irssi/trunk@1098 dbcabf3a-b0e7-0310-adc4-f8d773084564
This commit is contained in:
Timo Sirainen 2001-01-09 21:06:45 +00:00 committed by cras
commit d256f71a00
14 changed files with 190 additions and 231 deletions

View file

@ -142,7 +142,7 @@ static void sig_message_public(SERVER_REC *server, const char *msg,
for_me = nick_match_msg(chanrec, msg, server->nick);
color = for_me ? NULL :
hilight_find_nick(target, nick, address, MSGLEVEL_PUBLIC, msg);
hilight_match_nick(target, nick, address, MSGLEVEL_PUBLIC, msg);
print_channel = chanrec == NULL ||
!window_item_is_active((WI_ITEM_REC *) chanrec);

View file

@ -283,7 +283,7 @@ static int sig_query_autoclose(void)
next = tmp->next;
window = window_item_window((WI_ITEM_REC *) rec);
if (window != active_win && rec->new_data == 0 &&
if (window != active_win && rec->data_level == 0 &&
now-window->last_line > query_auto_close)
query_destroy(rec);
}

View file

@ -7,10 +7,10 @@
#include "window-item-def.h"
enum {
NEWDATA_TEXT = 1,
NEWDATA_MSG,
NEWDATA_HILIGHT,
NEWDATA_CUSTOM
DATA_LEVEL_NONE = 0,
DATA_LEVEL_TEXT,
DATA_LEVEL_MSG,
DATA_LEVEL_HILIGHT
};
typedef struct {
@ -21,6 +21,7 @@ typedef struct {
WI_ITEM_REC *active;
SERVER_REC *active_server;
int level; /* message level */
GSList *waiting_channels; /* list of "<server tag> <channel>" */
int lines;
@ -31,9 +32,9 @@ typedef struct {
GList *cmdhist, *histpos;
int histlines;
int level;
int new_data;
int last_color;
int data_level; /* current data level */
int hilight_color; /* current hilight color */
time_t last_timestamp; /* When was last timestamp printed */
time_t last_line; /* When was last line printed */

View file

@ -212,6 +212,9 @@ void format_create_dest(TEXT_DEST_REC *dest,
dest->level = level;
dest->window = window != NULL ? window :
window_find_closest(server, target, level);
dest->hilight_priority = 0;
dest->hilight_color = 0;
}
static char *format_get_text_args(TEXT_DEST_REC *dest,

View file

@ -36,6 +36,9 @@ typedef struct {
void *server;
const char *target;
int level;
int hilight_priority;
int hilight_color;
} TEXT_DEST_REC;
int format_find_tag(const char *module, const char *tag);

View file

@ -34,10 +34,10 @@
#include "formats.h"
#define DEFAULT_HILIGHT_LEVEL \
(MSGLEVEL_PUBLIC | MSGLEVEL_MSGS | \
MSGLEVEL_ACTIONS | MSGLEVEL_DCCMSGS)
(MSGLEVEL_PUBLIC | MSGLEVEL_MSGS | MSGLEVEL_DCCMSGS)
static int hilight_next, last_nick_color;
static HILIGHT_REC *next_hilight;
static int hilight_stop_next;
GSList *hilights;
static void hilight_add_config(HILIGHT_REC *rec)
@ -136,14 +136,6 @@ static HILIGHT_REC *hilight_find(const char *text, char **channels)
return NULL;
}
static void sig_print_text(TEXT_DEST_REC *dest, const char *str)
{
if (hilight_next) {
hilight_next = FALSE;
signal_stop();
}
}
/* color name -> mirc color number */
static int mirc_color_name(const char *name)
{
@ -189,16 +181,16 @@ static int mirc_color_name(const char *name)
return -1;
}
char *hilight_match(const char *channel, const char *nickmask, int level, const char *str)
HILIGHT_REC *hilight_match(const char *channel, const char *nickmask,
int level, const char *str)
{
GSList *tmp;
const char *color;
char number[MAX_INT_STRLEN];
int len, best_match, colornum;
HILIGHT_REC *match;
int len, best_match;
g_return_val_if_fail(str != NULL, NULL);
color = NULL; best_match = 0;
match = NULL; best_match = 0;
for (tmp = hilights; tmp != NULL; tmp = tmp->next) {
HILIGHT_REC *rec = tmp->data;
@ -225,14 +217,24 @@ char *hilight_match(const char *channel, const char *nickmask, int level, const
len = strlen(rec->text);
if (best_match < len) {
best_match = len;
color = rec->color;
match = rec;
}
}
if (best_match == 0)
return NULL;
return match;
}
char *hilight_get_color(HILIGHT_REC *rec)
{
const char *color = rec->color;
char number[MAX_INT_STRLEN];
int colornum;
g_return_val_if_fail(rec != NULL, NULL);
if (color == NULL)
color = settings_get_str("hilight_color");
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);
@ -241,72 +243,87 @@ char *hilight_match(const char *channel, const char *nickmask, int level, const
ltoa(number, colornum);
color = number;
}
return g_strconcat(isdigit(*color) ? "\003" : "", color, NULL);
}
static void sig_print_text_stripped(TEXT_DEST_REC *dest, const char *str)
{
HILIGHT_REC *hilight;
char *newstr, *color;
int oldlevel;
g_return_if_fail(str != NULL);
if (next_hilight != NULL) {
dest->hilight_priority = next_hilight->priority;
color = hilight_get_color(next_hilight);
dest->hilight_color = (color != NULL && *color == 3) ?
atoi(color+1) : 0;
g_free(color);
next_hilight = NULL;
return;
}
if (dest->level & (MSGLEVEL_NOHILIGHT|MSGLEVEL_HILIGHT))
return;
color = hilight_match(dest->target, NULL, dest->level, str);
if (color == NULL) return;
hilight = hilight_match(dest->target, NULL, dest->level, str);
if (hilight == NULL)
return;
/* update the level / hilight info */
dest->level |= MSGLEVEL_HILIGHT;
if (hilight->priority > 0)
dest->hilight_priority = hilight->priority;
color = hilight_get_color(hilight);
if (*color == 3) {
/* colorify */
dest->window->last_color = atoi(color+1);
dest->hilight_color = atoi(color+1);
}
if (dest->window != active_win) {
oldlevel = dest->window->new_data;
dest->window->new_data = NEWDATA_HILIGHT;
signal_emit("window hilight", 2, dest->window, GINT_TO_POINTER(oldlevel));
signal_emit("window activity", 2, dest->window, GINT_TO_POINTER(oldlevel));
}
hilight_stop_next = FALSE;
hilight_next = FALSE;
/* update the level, but let the signal pass through.. */
dest->level |= MSGLEVEL_HILIGHT;
/* send both signals again. "print text stripped" maybe wouldn't
have to be resent, but it would reverse the signal sending
order which some things may depend on, so maybe it's best we
don't do it. */
signal_emit("print text stripped", 2, dest, str);
newstr = g_strconcat(color, str, NULL);
signal_emit("print text", 2, dest, newstr);
g_free(newstr);
hilight_next = TRUE;
hilight_stop_next = TRUE;
g_free_not_null(color);
signal_stop();
}
char *hilight_find_nick(const char *channel, const char *nick,
const char *address, int level, const char *msg)
static void sig_print_text(TEXT_DEST_REC *dest, const char *str)
{
if (hilight_stop_next) {
hilight_stop_next = FALSE;
signal_stop();
}
}
char *hilight_match_nick(const char *channel, const char *nick,
const char *address, int level, const char *msg)
{
HILIGHT_REC *rec;
char *color, *mask;
mask = g_strdup_printf("%s!%s", nick, address);
color = hilight_match(channel, mask, level, msg);
rec = hilight_match(channel, mask, level, msg);
g_free(mask);
last_nick_color = (color != NULL && *color == 3) ?
atoi(color+1) : 0;
color = rec == NULL ? NULL : hilight_get_color(rec);
next_hilight = rec;
return color;
}
int hilight_last_nick_color(void)
{
return last_nick_color;
}
static void sig_message(void)
{
last_nick_color = 0;
}
static void read_hilight_config(void)
{
CONFIG_NODE *node;
@ -338,6 +355,7 @@ 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->priority = config_node_get_int(node, "priority", 0);
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);
@ -389,7 +407,7 @@ static void cmd_hilight(const char *data)
{
GHashTable *optlist;
HILIGHT_REC *rec;
char *colorarg, *levelarg, *chanarg, *text;
char *colorarg, *levelarg, *priorityarg, *chanarg, *text;
char **channels;
void *free_arg;
@ -406,6 +424,7 @@ static void cmd_hilight(const char *data)
chanarg = g_hash_table_lookup(optlist, "channels");
levelarg = g_hash_table_lookup(optlist, "level");
priorityarg = g_hash_table_lookup(optlist, "priority");
colorarg = g_hash_table_lookup(optlist, "color");
if (*text == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS);
@ -429,6 +448,7 @@ static void cmd_hilight(const char *data)
rec->level = (levelarg == NULL || *levelarg == '\0') ? 0 :
level2bits(replace_chars(levelarg, ',', ' '));
rec->priority = priorityarg == NULL ? 0 : atoi(priorityarg);
rec->nick = settings_get_bool("hilight_only_nick") &&
(rec->level == 0 || (rec->level & DEFAULT_HILIGHT_LEVEL) == rec->level) ?
g_hash_table_lookup(optlist, "nonick") == NULL :
@ -473,33 +493,30 @@ static void cmd_dehilight(const char *data)
void hilight_text_init(void)
{
hilight_next = FALSE;
last_nick_color = 0;
next_hilight = NULL;
hilight_stop_next = FALSE;
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);
signal_add_first("print text", (SIGNAL_FUNC) sig_print_text);
signal_add("setup reread", (SIGNAL_FUNC) read_hilight_config);
signal_add_last("message public", (SIGNAL_FUNC) sig_message);
signal_add_last("message private", (SIGNAL_FUNC) sig_message);
command_bind("hilight", NULL, (SIGNAL_FUNC) cmd_hilight);
command_bind("dehilight", NULL, (SIGNAL_FUNC) cmd_dehilight);
command_set_options("hilight", "-color -level -channels nick nonick mask word regexp");
command_set_options("hilight", "-color -level -priority -channels nick nonick mask word regexp");
}
void hilight_text_deinit(void)
{
hilights_destroy_all();
signal_remove("print text", (SIGNAL_FUNC) sig_print_text);
signal_remove("print text stripped", (SIGNAL_FUNC) sig_print_text_stripped);
signal_remove("print text", (SIGNAL_FUNC) sig_print_text);
signal_remove("setup reread", (SIGNAL_FUNC) read_hilight_config);
signal_remove("message public", (SIGNAL_FUNC) sig_message);
signal_remove("message private", (SIGNAL_FUNC) sig_message);
command_unbind("hilight", (SIGNAL_FUNC) cmd_hilight);
command_unbind("dehilight", (SIGNAL_FUNC) cmd_dehilight);
}

View file

@ -8,6 +8,7 @@ typedef struct {
int level; /* match only messages with this level, 0=default */
char *color; /* if starts with number, \003 is automatically
inserted before it. */
int priority;
unsigned int nick:1; /* hilight only the nick, not a full line - works only with msgs. */
unsigned int nickmask:1; /* `text 'is a nick mask - colorify the nick */
@ -17,12 +18,12 @@ typedef struct {
extern GSList *hilights;
char *hilight_match(const char *channel, const char *nickmask,
int level, const char *str);
HILIGHT_REC *hilight_match(const char *channel, const char *nickmask,
int level, const char *str);
char *hilight_get_color(HILIGHT_REC *rec);
char *hilight_find_nick(const char *channel, const char *nick,
const char *address, int level, const char *msg);
int hilight_last_nick_color(void);
char *hilight_match_nick(const char *channel, const char *nick,
const char *address, int level, const char *msg);
void hilight_text_init(void);
void hilight_text_deinit(void);

View file

@ -32,162 +32,100 @@
#include "hilight-text.h"
#include "formats.h"
static const char *noact_channels;
static char **noact_channels;
static int hilight_level, activity_level;
static void window_activity(WINDOW_REC *window,
int data_level, int hilight_color)
{
int old_data_level;
old_data_level = window->data_level;
if (data_level == 0 || window->data_level < data_level) {
window->data_level = data_level;
window->hilight_color = hilight_color;
signal_emit("window hilight", 1, window);
}
signal_emit("window activity", 2, window,
GINT_TO_POINTER(old_data_level));
}
static void window_item_activity(WI_ITEM_REC *item,
int data_level, int hilight_color)
{
int old_data_level;
old_data_level = item->data_level;
if (data_level == 0 || item->data_level < data_level) {
item->data_level = data_level;
item->hilight_color = hilight_color;
signal_emit("window item hilight", 1, item);
}
signal_emit("window item activity", 2, item,
GINT_TO_POINTER(old_data_level));
}
#define hide_target_activity(data_level, target) \
((data_level) < DATA_LEVEL_HILIGHT && (target) != NULL && \
(noact_channels) != NULL && \
strarray_find((noact_channels), target) != -1)
static void sig_hilight_text(TEXT_DEST_REC *dest, const char *msg)
{
int oldlevel, new_data;
WI_ITEM_REC *item;
int data_level;
if (dest->window == active_win ||
(dest->level & (MSGLEVEL_NEVER|MSGLEVEL_NO_ACT)))
return;
/* hilights and private messages get HILIGHT status,
public messages get MSGS status and rest get TEXT */
new_data = (dest->level & (MSGLEVEL_HILIGHT|hilight_level)) ?
NEWDATA_HILIGHT :
((dest->level & activity_level) ? NEWDATA_MSG : NEWDATA_TEXT);
data_level = (dest->level & hilight_level) ?
DATA_LEVEL_HILIGHT+dest->hilight_priority :
((dest->level & activity_level) ?
DATA_LEVEL_MSG : DATA_LEVEL_TEXT);
/* check that channel isn't in "don't show activity" list */
if (new_data < NEWDATA_HILIGHT &&
dest->target != NULL && find_substr(noact_channels, dest->target))
if (hide_target_activity(data_level, dest->target))
return;
oldlevel = dest->window->new_data;
if (dest->window->new_data < new_data) {
dest->window->new_data = new_data;
dest->window->last_color = hilight_last_nick_color();;
signal_emit("window hilight", 1, dest->window);
}
signal_emit("window activity", 2, dest->window, GINT_TO_POINTER(oldlevel));
}
static void sig_dehilight(WINDOW_REC *window, WI_ITEM_REC *item)
{
g_return_if_fail(window != NULL);
if (item != NULL && item->new_data != 0) {
item->new_data = 0;
item->last_color = 0;
signal_emit("window item hilight", 1, item);
if (dest->target != NULL) {
item = window_item_find(dest->server, dest->target);
if (item != NULL) {
window_item_activity(item, data_level,
dest->hilight_color);
}
}
window_activity(dest->window, data_level, dest->hilight_color);
}
static void sig_dehilight_window(WINDOW_REC *window)
{
GSList *tmp;
int oldlevel;
g_return_if_fail(window != NULL);
if (window->new_data == 0)
return;
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));
if (window->data_level != 0) {
window_activity(window, 0, 0);
for (tmp = window->items; tmp != NULL; tmp = tmp->next)
window_item_activity(tmp->data, 0, 0);
}
signal_emit("window activity", 2, window, GINT_TO_POINTER(oldlevel));
for (tmp = window->items; tmp != NULL; tmp = tmp->next)
sig_dehilight(window, tmp->data);
}
static void sig_hilight_window_item(WI_ITEM_REC *item)
{
WINDOW_REC *window;
GSList *tmp;
int level, oldlevel, color;
if (item->new_data < NEWDATA_HILIGHT &&
find_substr(noact_channels, item->name))
return;
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) {
level = item->new_data;
color = item->last_color;
}
}
oldlevel = window->new_data;
if (level == NEWDATA_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));
}
signal_emit("window activity", 2, window, GINT_TO_POINTER(oldlevel));
}
static void sig_message(SERVER_REC *server, const char *msg,
const char *nick, const char *addr,
const char *target, int level)
{
WINDOW_REC *window;
WI_ITEM_REC *item;
/* get window and window item */
item = window_item_find(server, target);
window = item == NULL ?
window_find_closest(server, target, level) :
window_item_window(item);
if (window == active_win)
return;
/* hilight */
if (item != NULL) item->last_color = hilight_last_nick_color();
level = (item != NULL && item->last_color > 0) ||
(level & hilight_level) ?
NEWDATA_HILIGHT : NEWDATA_MSG;
if (item != NULL && item->new_data < level) {
item->new_data = level;
signal_emit("window item hilight", 1, item);
} else {
int oldlevel = window->new_data;
if (window->new_data < level) {
window->new_data = level;
window->last_color = hilight_last_nick_color();
signal_emit("window hilight", 2, window,
GINT_TO_POINTER(oldlevel));
}
signal_emit("window activity", 2, window,
GINT_TO_POINTER(oldlevel));
}
}
static void sig_message_public(SERVER_REC *server, const char *msg,
const char *nick, const char *addr,
const char *target)
{
int level = MSGLEVEL_PUBLIC;
if (nick_match_msg(channel_find(server, target), msg, server->nick))
level |= MSGLEVEL_HILIGHT;
sig_message(server, msg, nick, addr, target, level);
}
static void sig_message_private(SERVER_REC *server, const char *msg,
const char *nick, const char *addr)
{
sig_message(server, msg, nick, addr, nick, MSGLEVEL_MSGS);
}
static void read_settings(void)
{
noact_channels = settings_get_str("noact_channels");
const char *channels;
if (noact_channels != NULL)
g_strfreev(noact_channels);
channels = settings_get_str("noact_channels");
noact_channels = *channels == '\0' ? NULL :
g_strsplit(channels, " ", -1);
activity_level = level2bits(settings_get_str("activity_levels"));
hilight_level = level2bits(settings_get_str("hilight_levels"));
hilight_level = MSGLEVEL_HILIGHT |
level2bits(settings_get_str("hilight_levels"));
}
void window_activity_init(void)
@ -198,23 +136,18 @@ void window_activity_init(void)
read_settings();
signal_add("print text", (SIGNAL_FUNC) sig_hilight_text);
signal_add("window item changed", (SIGNAL_FUNC) sig_dehilight);
signal_add("window changed", (SIGNAL_FUNC) sig_dehilight_window);
signal_add("window dehilight", (SIGNAL_FUNC) sig_dehilight_window);
signal_add("window item hilight", (SIGNAL_FUNC) sig_hilight_window_item);
signal_add("message public", (SIGNAL_FUNC) sig_message_public);
signal_add("message private", (SIGNAL_FUNC) sig_message_private);
signal_add("setup changed", (SIGNAL_FUNC) read_settings);
}
void window_activity_deinit(void)
{
if (noact_channels != NULL)
g_strfreev(noact_channels);
signal_remove("print text", (SIGNAL_FUNC) sig_hilight_text);
signal_remove("window item changed", (SIGNAL_FUNC) sig_dehilight);
signal_remove("window changed", (SIGNAL_FUNC) sig_dehilight_window);
signal_remove("window dehilight", (SIGNAL_FUNC) sig_dehilight_window);
signal_remove("window item hilight", (SIGNAL_FUNC) sig_hilight_window_item);
signal_remove("message public", (SIGNAL_FUNC) sig_message_public);
signal_remove("message private", (SIGNAL_FUNC) sig_message_private);
signal_remove("setup changed", (SIGNAL_FUNC) read_settings);
}

View file

@ -103,8 +103,8 @@ static WINDOW_REC *window_highest_activity(WINDOW_REC *window)
rec = tmp->data;
if (rec->new_data && max_act < rec->new_data) {
max_act = rec->new_data;
if (rec->data_level > 0 && max_act < rec->data_level) {
max_act = rec->data_level;
max_win = rec;
}
}