--- a/mcabber/mcabberrc.example Mon Aug 20 21:30:16 2007 +0200
+++ b/mcabber/mcabberrc.example Tue Aug 21 20:49:03 2007 +0200
@@ -279,6 +279,13 @@
#set color_rosterselmsg = red
#set color_rosternewmsg = red
+#You can color roster items by their status and JID. For example, to have all
+#roster items white, just all contacts from jabber.org that are away, not
+#available or do not disturb yellow, you do this:
+#
+#color roster * * white
+#color roster adn *@jabber.org yellow
+
# Style
# Note: the "log_win_height" and "roster_width" values below can be set
# in real time when mcabber is running. Refresh the screen (Ctrl-l) to
--- a/mcabber/src/commands.c Mon Aug 20 21:30:16 2007 +0200
+++ b/mcabber/src/commands.c Tue Aug 21 20:49:03 2007 +0200
@@ -77,6 +77,7 @@
static void do_screen_refresh(char *arg);
static void do_chat_disable(char *arg);
static void do_source(char *arg);
+static void do_color(char *arg);
// Global variable for the commands list
static GSList *Commands;
@@ -147,6 +148,7 @@
cmd_add("status_to", "Show or set your status for one recipient",
COMPL_JID, COMPL_STATUS, &do_status_to);
cmd_add("version", "Show mcabber version", 0, 0, &do_version);
+ cmd_add("color", "Set coloring options", COMPL_COLOR, 0, &do_color);
// Status category
compl_add_category_word(COMPL_STATUS, "online");
@@ -252,6 +254,9 @@
compl_add_category_word(COMPL_PGP, "force");
compl_add_category_word(COMPL_PGP, "info");
compl_add_category_word(COMPL_PGP, "setkey");
+
+ // Color category
+ compl_add_category_word(COMPL_COLOR, "roster");
}
// expandalias(line)
@@ -702,6 +707,41 @@
free_arg_lst(paramlst);
}
+void do_color(char *arg)
+{
+ char **paramlst;
+ char *subcmd;
+
+ paramlst = split_arg(arg, 2, 1); // subcmd, arg
+ subcmd = *paramlst;
+ arg = *(paramlst+1);
+
+ if (!subcmd || !*subcmd) {
+ scr_LogPrint(LPRINT_NORMAL, "Missing parameter.");
+ free_arg_lst(paramlst);
+ return;
+ }
+
+ if (!strcasecmp(subcmd, "roster")) {
+ char **arglist = split_arg(arg, 3, 0);
+ char *status = *arglist, *wildcard = arglist[1], *color = arglist[2];
+ if (status && !strcmp(status, "clear")) { // Not a color command, clear all
+ scr_RosterClearColor();
+ update_roster = TRUE;
+ } else {
+ if (!status || !*status || !wildcard || !*wildcard || !color || !*color) {
+ scr_LogPrint(LPRINT_NORMAL, "Missing argument");
+ } else {
+ update_roster = scr_RosterColor(status, wildcard, color)
+ || update_roster;
+ }
+ }
+ free_arg_lst(arglist);
+ } else
+ scr_LogPrint(LPRINT_NORMAL, "Unrecognized parameter!");
+ free_arg_lst(paramlst);
+}
+
// setstatus(recipient, arg)
// Set your Jabber status.
// - if recipient is not NULL, the status is sent to this contact only
--- a/mcabber/src/compl.h Mon Aug 20 21:30:16 2007 +0200
+++ b/mcabber/src/compl.h Tue Aug 21 20:49:03 2007 +0200
@@ -21,6 +21,7 @@
#define COMPL_EVENTS (1U<<15)
#define COMPL_EVENTSID (1U<<16)
#define COMPL_PGP (1U<<17)
+#define COMPL_COLOR (1U<<18)
void compl_add_category_word(guint, const char *command);
void compl_del_category_word(guint categ, const char *word);
--- a/mcabber/src/screen.c Mon Aug 20 21:30:16 2007 +0200
+++ b/mcabber/src/screen.c Tue Aug 21 20:49:03 2007 +0200
@@ -143,9 +143,59 @@
AspellSpeller *spell_checker;
#endif
+typedef struct {
+ char *status, *wildcard;
+ int color;
+ GPatternSpec *compiled;
+} rostercolor;
+
+GSList *rostercolrules = NULL;
+
/* Functions */
-static int FindColor(const char *name)
+static int color_conv_table[] = {
+ COLOR_BLACK,
+ COLOR_RED,
+ COLOR_GREEN,
+ COLOR_YELLOW,
+ COLOR_BLUE,
+ COLOR_MAGENTA,
+ COLOR_CYAN,
+ COLOR_WHITE
+};
+
+static int color_conv_table_fg[] = {
+ COLOR_BLACK_FG,
+ COLOR_RED_FG,
+ COLOR_GREEN_FG,
+ COLOR_YELLOW_FG,
+ COLOR_BLUE_FG,
+ COLOR_MAGENTA_FG,
+ COLOR_CYAN_FG,
+ COLOR_WHITE_FG
+};
+
+static int color_to_color_fg(int color)
+{
+ unsigned i = 0;
+ for ( ; i < sizeof color_conv_table / sizeof *color_conv_table; i++)
+ if (color == color_conv_table[i])
+ return color_conv_table_fg[i];
+ return -1;
+}
+
+static int color_fg_to_color(int color)
+{
+ unsigned i = 0;
+ if (color >= COLOR_BLACK_BOLD_FG)
+ color -= COLOR_BLACK_BOLD_FG - COLOR_BLACK_FG;
+ for ( ; i < sizeof color_conv_table_fg / sizeof *color_conv_table_fg; i++)
+ if (color == color_conv_table_fg[i])
+ return color_conv_table[i];
+ return -1;
+}
+
+static int FindColorInternal(const char *name)
{
if (!strcmp(name, "default"))
return -1;
@@ -166,10 +216,87 @@
if (!strcmp(name, "white"))
return COLOR_WHITE;
+ return -2;
+}
+
+static int FindColor(const char *name)
+{
+ int result = FindColorInternal(name);
+ if (result != -2)
+ return result;
+
scr_LogPrint(LPRINT_LOGNORM, "ERROR: Wrong color: %s", name);
return -1;
}
+static void free_rostercolrule(rostercolor *col)
+{
+ g_free(col->status);
+ g_free(col->wildcard);
+ g_pattern_spec_free(col->compiled);
+ g_free(col);
+}
+
+void scr_RosterClearColor(void)
+{
+ GSList *head;
+ for (head = rostercolrules; head; head = g_slist_next(head)) {
+ free_rostercolrule(head->data);
+ }
+ g_slist_free(rostercolrules);
+ rostercolrules = NULL;
+}
+
+bool scr_RosterColor(const char *status, const char *wildcard,
+ const char *color)
+{
+ GSList *head;
+ GSList *found = NULL;
+ for (head = rostercolrules; head; head = g_slist_next(head)) {
+ rostercolor *rc = head->data;
+ if ((!strcmp(status, rc->status)) && (!strcmp(wildcard, rc->wildcard))) {
+ found = head;
+ break;
+ }
+ }
+ if (!strcmp(color,"-")) {//Delete the rule
+ if (found) {
+ free_rostercolrule(found->data);
+ rostercolrules = g_slist_delete_link(rostercolrules, found);
+ return TRUE;
+ } else {
+ scr_LogPrint(LPRINT_NORMAL, "No such color rule, nothing removed");
+ return FALSE;
+ }
+ } else {
+ bool isbright = false;
+ int cl;
+ if (!strncmp(color, "bright", 6)) {
+ isbright = true;
+ color += 6;
+ }
+ cl = color_to_color_fg(FindColorInternal(color));
+ if (isbright)
+ cl += COLOR_BLACK_BOLD_FG - COLOR_BLACK_FG;
+ if (cl < 0 ) {
+ scr_LogPrint(LPRINT_NORMAL, "No such color name");
+ return FALSE;
+ }
+ if (found) {
+ rostercolor *rc = found->data;
+ rc->color = cl;
+ } else {
+ rostercolor *rc = g_new(rostercolor, 1);
+ rc->status = g_strdup(status);
+ rc->wildcard = g_strdup(wildcard);
+ rc->compiled = g_pattern_spec_new(wildcard);
+ rc->color = cl;
+ rostercolrules = g_slist_prepend(rostercolrules, rc);
+ }
+ return TRUE;
+ }
+}
+
static void ParseColors(void)
{
const char *colors[] = {
@@ -263,6 +390,11 @@
break;
}
}
+ for (i = COLOR_BLACK_FG; i < COLOR_max; i++) {
+ init_pair(i, color_fg_to_color(i), FindColor(background));
+ if (i >= COLOR_BLACK_BOLD_FG)
+ COLOR_ATTRIB[i] = A_BOLD;
+ }
}
static void init_keycodes(void)
@@ -1429,8 +1561,22 @@
} else {
if (pending == '#')
wattrset(rosterWnd, get_color(COLOR_ROSTERNMSG));
- else
- wattrset(rosterWnd, get_color(COLOR_ROSTER));
+ else {
+ int color = get_color(COLOR_ROSTER);
+ if ((!isspe) && (!isgrp)) {//Look for color rules
+ GSList *head;
+ const char *jid = buddy_getjid(BUDDATA(buddy));
+ for (head = rostercolrules; head; head = g_slist_next(head)) {
+ rostercolor *rc = head->data;
+ if (g_pattern_match_string(rc->compiled, jid) &&
+ (!strcmp("*", rc->status) || strchr(rc->status, status))) {
+ color = get_color(rc->color);
+ break;
+ }
+ }
+ }
+ wattrset(rosterWnd, color);
+ }
}
if (Roster_Width > 7)
--- a/mcabber/src/screen.h Mon Aug 20 21:30:16 2007 +0200
+++ b/mcabber/src/screen.h Tue Aug 21 20:49:03 2007 +0200
@@ -48,6 +48,25 @@
COLOR_ROSTERNMSG,
COLOR_INFO,
COLOR_MSGIN,
+ //Foreground color on usual backgroud
+ //curses do not allow telling color only ->
+ //needs colorpairs
+ COLOR_BLACK_FG,
+ COLOR_RED_FG,
+ COLOR_GREEN_FG,
+ COLOR_YELLOW_FG,
+ COLOR_BLUE_FG,
+ COLOR_MAGENTA_FG,
+ COLOR_CYAN_FG,
+ COLOR_WHITE_FG,
+ COLOR_BLACK_BOLD_FG,
+ COLOR_RED_BOLD_FG,
+ COLOR_GREEN_BOLD_FG,
+ COLOR_YELLOW_BOLD_FG,
+ COLOR_BLUE_BOLD_FG,
+ COLOR_MAGENTA_BOLD_FG,
+ COLOR_CYAN_BOLD_FG,
+ COLOR_WHITE_BOLD_FG,
COLOR_max
};
@@ -139,6 +158,8 @@
void scr_RosterUnreadMessage(int);
void scr_RosterJumpAlternate(void);
void scr_BufferScrollUpDown(int updown, unsigned int nblines);
+bool scr_RosterColor(const char *status, const char *wildcard, const char *color);
+void scr_RosterClearColor(void);
#ifdef DEBUG_ENABLE
void scr_BufferList(void);
--- a/mcabber/src/settings.c Mon Aug 20 21:30:16 2007 +0200
+++ b/mcabber/src/settings.c Tue Aug 21 20:49:03 2007 +0200
@@ -153,15 +153,18 @@
if ((*line == '\n') || (*line == '\0') || (*line == '#'))
continue;
- // We only allow assignments line, except for commands "pgp" and "source"
+ // We only allow assignments line, except for commands "pgp", "source"
+ // and "color"
if ((strchr(line, '=') != NULL) ||
- startswith(line, "pgp ", FALSE) || startswith(line, "source ", FALSE)) {
+ startswith(line, "pgp ", FALSE) || startswith(line, "source ", FALSE) ||
+ startswith(line, "color ", FALSE)) {
// Only accept the set, alias, bind, pgp and source commands
if (!startswith(line, "set ", FALSE) &&
!startswith(line, "bind ", FALSE) &&
!startswith(line, "alias ", FALSE) &&
!startswith(line, "pgp ", FALSE) &&
- !startswith(line, "source ", FALSE)) {
+ !startswith(line, "source ", FALSE) &&
+ !startswith(line, "color ", FALSE)) {
scr_LogPrint(LPRINT_LOGNORM,
"Error in configuration file (l. %d): bad command", ln);
err++;