--- 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);
--- 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;
--- 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),
--- 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 <locale.h>
#include <langinfo.h>
#include <config.h>
+#include <assert.h>
#ifdef HAVE_ASPELL_H
# include <aspell.h>
@@ -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;
--- 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);
--- 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;
--- 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);