# HG changeset patch # User Richard Nelson # Date 1196392627 0 # Node ID 3ed9b027479d72a06617f951dd473c8fb46fae79 # Parent 33285f8f68ba6c8b02dfab70dcc055e2396a2446 Add support for colour in gnttreerows, and colourise the blist. Fixes #1490 diff -r 33285f8f68ba -r 3ed9b027479d doc/finch.1.in --- a/doc/finch.1.in Thu Nov 29 23:21:14 2007 +0000 +++ b/doc/finch.1.in Fri Nov 30 03:17:07 2007 +0000 @@ -135,6 +135,18 @@ .TP A sample file looks like: .br +[Finch] +.br +online-color: green; black +.br +away-color: blue; black +.br +idle-color: gray; black +.br +offline-color: red; black +.br +#See below for details on color +.br [general] .br shadow = 0 diff -r 33285f8f68ba -r 3ed9b027479d finch/gntblist.c --- a/finch/gntblist.c Thu Nov 29 23:21:14 2007 +0000 +++ b/finch/gntblist.c Fri Nov 30 03:17:07 2007 +0000 @@ -27,6 +27,7 @@ #include #include +#include #include #include #include @@ -37,6 +38,7 @@ #include "debug.h" #include "gntbox.h" +#include "gntcolors.h" #include "gntcombobox.h" #include "gntentry.h" #include "gntft.h" @@ -46,6 +48,7 @@ #include "gntmenuitem.h" #include "gntmenuitemcheck.h" #include "gntpounce.h" +#include "gntstyle.h" #include "gnttree.h" #include "gntutils.h" #include "gntwindow.h" @@ -124,6 +127,11 @@ static int blist_node_compare_status(PurpleBlistNode *n1, PurpleBlistNode *n2); static int blist_node_compare_log(PurpleBlistNode *n1, PurpleBlistNode *n2); +static int color_available; +static int color_away; +static int color_offline; +static int color_idle; + static gboolean is_contact_online(PurpleContact *contact) { @@ -615,12 +623,20 @@ node->ui_data = gnt_tree_add_row_after(GNT_TREE(ggblist->tree), buddy, gnt_tree_create_row(GNT_TREE(ggblist->tree), get_display_name(node)), contact, NULL); + if (purple_presence_is_idle(purple_buddy_get_presence(buddy))) { - gnt_tree_set_row_flags(GNT_TREE(ggblist->tree), buddy, GNT_TEXT_FLAG_DIM); - gnt_tree_set_row_flags(GNT_TREE(ggblist->tree), contact, GNT_TEXT_FLAG_DIM); - } else { - gnt_tree_set_row_flags(GNT_TREE(ggblist->tree), buddy, 0); - gnt_tree_set_row_flags(GNT_TREE(ggblist->tree), contact, 0); + gnt_tree_set_row_color(GNT_TREE(ggblist->tree), buddy, color_idle); + gnt_tree_set_row_color(GNT_TREE(ggblist->tree), contact, color_idle); + } else if (purple_presence_is_available(purple_buddy_get_presence(buddy)) && color_available) { + gnt_tree_set_row_color(GNT_TREE(ggblist->tree), buddy, color_available); + gnt_tree_set_row_color(GNT_TREE(ggblist->tree), contact, color_available); + } else if (purple_presence_is_online(purple_buddy_get_presence(buddy)) && + !purple_presence_is_available(purple_buddy_get_presence(buddy)) && color_away) { + gnt_tree_set_row_color(GNT_TREE(ggblist->tree), buddy, color_away); + gnt_tree_set_row_color(GNT_TREE(ggblist->tree), contact, color_away); + } else if (!purple_presence_is_online(purple_buddy_get_presence(buddy)) && color_offline) { + gnt_tree_set_row_color(GNT_TREE(ggblist->tree), buddy, color_offline); + gnt_tree_set_row_color(GNT_TREE(ggblist->tree), contact, color_offline); } } @@ -1557,18 +1573,33 @@ draw_tooltip(ggblist); if (purple_presence_is_idle(purple_buddy_get_presence(buddy))) { - gnt_tree_set_row_flags(GNT_TREE(ggblist->tree), buddy, bflag | GNT_TEXT_FLAG_DIM); + gnt_tree_set_row_color(GNT_TREE(ggblist->tree), buddy, color_idle); + gnt_tree_set_row_color(GNT_TREE(ggblist->tree), contact, color_idle); + if (buddy == purple_contact_get_priority_buddy(contact)) + gnt_tree_set_row_color(GNT_TREE(ggblist->tree), contact, color_idle); + } else if (purple_presence_is_available(purple_buddy_get_presence(buddy)) && color_available) { + gnt_tree_set_row_color(GNT_TREE(ggblist->tree), buddy, color_available); + gnt_tree_set_row_color(GNT_TREE(ggblist->tree), contact, color_available); if (buddy == purple_contact_get_priority_buddy(contact)) - gnt_tree_set_row_flags(GNT_TREE(ggblist->tree), contact, cflag | GNT_TEXT_FLAG_DIM); - else + gnt_tree_set_row_color(GNT_TREE(ggblist->tree), contact, color_available); + } else if (purple_presence_is_online(purple_buddy_get_presence(buddy)) && + !purple_presence_is_available(purple_buddy_get_presence(buddy)) && color_away) { + gnt_tree_set_row_color(GNT_TREE(ggblist->tree), buddy, color_away); + gnt_tree_set_row_color(GNT_TREE(ggblist->tree), contact, color_away); + if (buddy == purple_contact_get_priority_buddy(contact)) + gnt_tree_set_row_color(GNT_TREE(ggblist->tree), contact, color_away); + } else if (!purple_presence_is_online(purple_buddy_get_presence(buddy)) && color_offline) { + gnt_tree_set_row_color(GNT_TREE(ggblist->tree), buddy, color_offline); + gnt_tree_set_row_color(GNT_TREE(ggblist->tree), contact, color_offline); + if (buddy == purple_contact_get_priority_buddy(contact)) + gnt_tree_set_row_color(GNT_TREE(ggblist->tree), contact, color_offline); + } + gnt_tree_set_row_flags(GNT_TREE(ggblist->tree), buddy, bflag); + if (buddy == purple_contact_get_priority_buddy(contact)) + gnt_tree_set_row_flags(GNT_TREE(ggblist->tree), contact, cflag); + + if (buddy != purple_contact_get_priority_buddy(contact)) update_buddy_display(purple_contact_get_priority_buddy(contact), ggblist); - } else { - gnt_tree_set_row_flags(GNT_TREE(ggblist->tree), buddy, bflag); - if (buddy == purple_contact_get_priority_buddy(contact)) - gnt_tree_set_row_flags(GNT_TREE(ggblist->tree), contact, cflag); - else - update_buddy_display(purple_contact_get_priority_buddy(contact), ggblist); - } } static void @@ -1736,8 +1767,43 @@ draw_tooltip(ggblist); } +static int +get_color(char *key) +{ +#if GLIB_CHECK_VERSION(2,6,0) + int fg = 0, bg = 0; + gsize n; + char **vals; + vals = gnt_style_get_string_list(NULL, key, &n); + if (vals && n == 2) { + fg = gnt_colors_get_color(vals[0]); + bg = gnt_colors_get_color(vals[1]); + return gnt_color_add_pair(fg, bg); + } + return 0; +#else + return 0; +#endif +} + void finch_blist_init() { + short fg, bg; + if (has_colors()) { + pair_content(GNT_COLOR_NORMAL, &fg, &bg); + color_available = get_color("color-available"); + if (!color_available) + color_available = gnt_color_add_pair(COLOR_GREEN, bg); + color_away = get_color("color-away"); + if (!color_away) + color_away = gnt_color_add_pair(COLOR_BLUE, bg); + color_idle = get_color("color-idle"); + if (!color_idle) + color_idle = gnt_color_add_pair(COLOR_CYAN, bg); + color_offline = get_color("color-offline"); + if (!color_offline) + color_offline = gnt_color_add_pair(COLOR_RED, bg); + } purple_prefs_add_none(PREF_ROOT); purple_prefs_add_none(PREF_ROOT "/size"); purple_prefs_add_int(PREF_ROOT "/size/width", 20); @@ -2550,4 +2616,3 @@ { gnt_widget_set_size(ggblist->window, width, height); } - diff -r 33285f8f68ba -r 3ed9b027479d finch/libgnt/gntcolors.c --- a/finch/libgnt/gntcolors.c Thu Nov 29 23:21:14 2007 +0000 +++ b/finch/libgnt/gntcolors.c Fri Nov 30 03:17:07 2007 +0000 @@ -33,6 +33,7 @@ #include static gboolean hascolors; +static int custom_type = GNT_COLORS; static struct { short r, g, b; @@ -137,8 +138,8 @@ } #if GLIB_CHECK_VERSION(2,6,0) -static int -get_color(char *key) +int +gnt_colors_get_color(char *key) { int color; gboolean custom = can_use_custom_color(); @@ -196,7 +197,7 @@ int color = -1; key = g_ascii_strdown(key, -1); - color = get_color(key); + color = gnt_colors_get_color(key); g_free(key); if (color == -1) continue; @@ -237,8 +238,8 @@ GntColorType type = 0; gchar *fgc = g_ascii_strdown(list[0], -1); gchar *bgc = g_ascii_strdown(list[1], -1); - int fg = get_color(fgc); - int bg = get_color(bgc); + int fg = gnt_colors_get_color(fgc); + int bg = gnt_colors_get_color(bgc); g_free(fgc); g_free(bgc); if (fg == -1 || bg == -1) @@ -287,3 +288,8 @@ pair == GNT_COLOR_TITLE_D || pair == GNT_COLOR_DISABLED) ? 0 : A_STANDOUT)); } +int gnt_color_add_pair(int fg, int bg) +{ + init_pair(custom_type, fg, bg); + return custom_type++; +} diff -r 33285f8f68ba -r 3ed9b027479d finch/libgnt/gntcolors.h --- a/finch/libgnt/gntcolors.h Thu Nov 29 23:21:14 2007 +0000 +++ b/finch/libgnt/gntcolors.h Fri Nov 30 03:17:07 2007 +0000 @@ -86,6 +86,16 @@ */ void gnt_color_pairs_parse(GKeyFile *kfile); +/** + * Parse a string color + * + * @param kfile The string value + * + * @return A color + * + * @since 2.3.1 (gnt), 2.3.1 (pidgin) + */ +int gnt_colors_get_color(char *key); #endif /** @@ -101,4 +111,15 @@ */ int gnt_color_pair(int color); +/** + * Adds a color definition + * + * @param fg Foreground + * @param bg Background + * + * @return A color pair + * + * @since 2.3.1 + */ +int gnt_color_add_pair(int fg, int bg); #endif diff -r 33285f8f68ba -r 3ed9b027479d finch/libgnt/gntstyle.c --- a/finch/libgnt/gntstyle.c Thu Nov 29 23:21:14 2007 +0000 +++ b/finch/libgnt/gntstyle.c Fri Nov 30 03:17:07 2007 +0000 @@ -59,6 +59,21 @@ #endif } +char **gnt_style_get_string_list(const char *group, const char *key, gsize *length) +{ +#if GLIB_CHECK_VERSION(2,6,0) + const char *prg = g_get_prgname(); + if ((group == NULL || *group == '\0') && prg && + g_key_file_has_group(gkfile, prg)) + group = prg; + if (!group) + group = "general"; + return g_key_file_get_string_list(gkfile, group, key, length, NULL); +#else + return NULL; +#endif +} + gboolean gnt_style_get_bool(GntStyle style, gboolean def) { const char * str; diff -r 33285f8f68ba -r 3ed9b027479d finch/libgnt/gntstyle.h --- a/finch/libgnt/gntstyle.h Thu Nov 29 23:21:14 2007 +0000 +++ b/finch/libgnt/gntstyle.h Fri Nov 30 03:17:07 2007 +0000 @@ -65,6 +65,20 @@ char *gnt_style_get_from_name(const char *group, const char *key); /** + * Get the value of a preference in ~/.gntrc. + * + * @param group The name of the group in the keyfile. If @c NULL, the prgname + * will be used first, if available. Otherwise, "general" will be used. + * @param key The key + * @param length Return location for the number of strings returned, or NULL + * + * @return NULL terminated string array. The array should be freed with g_strfreev(). + * + * @since 2.3.1 (gnt), 2.3.1 (pidgin) + */ +char **gnt_style_get_string_list(const char *group, const char *key, gsize *length); + +/** * Parse a boolean preference. For example, if 'value' is "false" (ignoring case) * or "0", the return value will be @c FALSE, otherwise @c TRUE. * diff -r 33285f8f68ba -r 3ed9b027479d finch/libgnt/gnttree.c --- a/finch/libgnt/gnttree.c Thu Nov 29 23:21:14 2007 +0000 +++ b/finch/libgnt/gnttree.c Fri Nov 30 03:17:07 2007 +0000 @@ -75,6 +75,7 @@ If choice is true, then child will be NULL */ gboolean isselected; GntTextFormatFlags flags; + int color; GntTreeRow *parent; GntTreeRow *child; @@ -522,9 +523,14 @@ else { if (flags & GNT_TEXT_FLAG_DIM) - attr |= (A_DIM | gnt_color_pair(GNT_COLOR_DISABLED)); + if (row->color) + attr |= (A_DIM | gnt_color_pair(row->color)); + else + attr |= (A_DIM | gnt_color_pair(GNT_COLOR_DISABLED)); else if (flags & GNT_TEXT_FLAG_HIGHLIGHT) attr |= (A_DIM | gnt_color_pair(GNT_COLOR_HIGHLIGHT)); + else if (row->color) + attr |= gnt_color_pair(row->color); else attr |= gnt_color_pair(GNT_COLOR_NORMAL); } @@ -1559,6 +1565,16 @@ redraw_tree(tree); /* XXX: It shouldn't be necessary to redraw the whole darned tree */ } +void gnt_tree_set_row_color(GntTree *tree, void *key, int color) +{ + GntTreeRow *row = g_hash_table_lookup(tree->hash, key); + if (!row || row->color == color) + return; + + row->color = color; + redraw_tree(tree); +} + void gnt_tree_set_selected(GntTree *tree , void *key) { int dist; diff -r 33285f8f68ba -r 3ed9b027479d finch/libgnt/gnttree.h --- a/finch/libgnt/gnttree.h Thu Nov 29 23:21:14 2007 +0000 +++ b/finch/libgnt/gnttree.h Fri Nov 30 03:17:07 2007 +0000 @@ -325,6 +325,15 @@ void gnt_tree_set_row_flags(GntTree *tree, void *key, GntTextFormatFlags flags); /** + * Set color for the text in a row in the tree. + * + * @param tree The tree + * @param key The key for the row + * @param color The color + */ +void gnt_tree_set_row_color(GntTree *, void *, int); + +/** * Select a row. * * @param tree The tree