diff --git a/src/roster_list.c b/src/roster_list.c index f80f47cd..be99112e 100644 --- a/src/roster_list.c +++ b/src/roster_list.c @@ -493,41 +493,6 @@ roster_fulljid_autocomplete(const char *const search_str) return autocomplete_complete(roster->fulljid_ac, search_str, TRUE); } -GSList* -roster_get_nogroup(roster_ord_t order, gboolean include_offline) -{ - assert(roster != NULL); - - GSList *result = NULL; - GHashTableIter iter; - gpointer key; - gpointer value; - - GCompareFunc cmp_func; - if (order == ROSTER_ORD_PRESENCE) { - cmp_func = (GCompareFunc) _compare_presence; - } else { - cmp_func = (GCompareFunc) _compare_name; - } - - g_hash_table_iter_init(&iter, roster->contacts); - while (g_hash_table_iter_next(&iter, &key, &value)) { - PContact contact = value; - const char *presence = p_contact_presence(contact); - if (!include_offline && (g_strcmp0(presence, "offline") == 0)) { - continue; - } - - GSList *groups = p_contact_groups(value); - if (groups == NULL) { - result = g_slist_insert_sorted(result, value, cmp_func); - } - } - - // return all contact structs - return result; -} - GSList* roster_get_group(const char *const group, roster_ord_t order, gboolean include_offline) { @@ -554,12 +519,18 @@ roster_get_group(const char *const group, roster_ord_t order, gboolean include_o } GSList *groups = p_contact_groups(value); - while (groups) { - if (strcmp(groups->data, group) == 0) { + if (group == NULL) { + if (groups == NULL) { result = g_slist_insert_sorted(result, value, cmp_func); - break; } - groups = g_slist_next(groups); + } else { + while (groups) { + if (strcmp(groups->data, group) == 0) { + result = g_slist_insert_sorted(result, value, cmp_func); + break; + } + groups = g_slist_next(groups); + } } } diff --git a/src/roster_list.h b/src/roster_list.h index b41d51ad..1b35febd 100644 --- a/src/roster_list.h +++ b/src/roster_list.h @@ -69,7 +69,6 @@ GSList* roster_get_groups(void); char* roster_group_autocomplete(const char *const search_str); char* roster_barejid_autocomplete(const char *const search_str); GSList* roster_get_contacts_by_presence(const char *const presence); -GSList* roster_get_nogroup(roster_ord_t order, gboolean include_offline); char* roster_get_msg_display_name(const char *const barejid, const char *const resource); #endif diff --git a/src/ui/rosterwin.c b/src/ui/rosterwin.c index ee57e145..4144b660 100644 --- a/src/ui/rosterwin.c +++ b/src/ui/rosterwin.c @@ -49,6 +49,244 @@ typedef enum { ROSTER_CONTACT_UNREAD } roster_contact_theme_t; +static void _rosterwin_contacts_all(ProfLayoutSplit *layout, gboolean newline); +static void _rosterwin_contacts_by_presence(ProfLayoutSplit *layout, const char *const presence, char *title, + gboolean newline); +static void _rosterwin_contacts_by_group(ProfLayoutSplit *layout, char *group, gboolean newline); +static void _rosterwin_contacts_header(ProfLayoutSplit *layout, const char *title, gboolean newline, GSList *contacts); + +static void _rosterwin_contact(ProfLayoutSplit *layout, PContact contact); +static void _rosterwin_presence(ProfLayoutSplit *layout, theme_item_t colour, const char *presence, const char *status, + int current_indent); +static void _rosterwin_resources(ProfLayoutSplit *layout, PContact contact, int current_indent, + roster_contact_theme_t theme_type, int unread); + +static void _rosterwin_rooms(ProfLayoutSplit *layout, gboolean newline); +static void _rosterwin_rooms_header(ProfLayoutSplit *layout, gboolean newline, GList *rooms); +static void _rosterwin_room(ProfLayoutSplit *layout, ProfMucWin *mucwin); + +static void _rosterwin_private_chats(ProfLayoutSplit *layout); +static void _rosterwin_private_header(ProfLayoutSplit *layout, GList *privs); + +static theme_item_t _get_roster_theme(roster_contact_theme_t theme_type, const char *presence); +static int _compare_rooms_name(ProfMucWin *a, ProfMucWin *b); +static int _compare_rooms_unread(ProfMucWin *a, ProfMucWin *b); + +void +rosterwin_roster(void) +{ + ProfWin *console = wins_get_console(); + if (!console) { + return; + } + + jabber_conn_status_t conn_status = jabber_get_connection_status(); + if (conn_status != JABBER_CONNECTED) { + return; + } + + ProfLayoutSplit *layout = (ProfLayoutSplit*)console->layout; + assert(layout->memcheck == LAYOUT_SPLIT_MEMCHECK); + werase(layout->subwin); + + gboolean newline = FALSE; + char *roomspos = prefs_get_string(PREF_ROSTER_ROOMS_POS); + if (prefs_get_boolean(PREF_ROSTER_ROOMS) && (g_strcmp0(roomspos, "first") == 0)) { + _rosterwin_rooms(layout, newline); + newline = TRUE; + } + + if (prefs_get_boolean(PREF_ROSTER_CONTACTS)) { + char *by = prefs_get_string(PREF_ROSTER_BY); + if (g_strcmp0(by, "presence") == 0) { + _rosterwin_contacts_by_presence(layout, "chat", "Available for chat", newline); + _rosterwin_contacts_by_presence(layout, "online", "Online", TRUE); + _rosterwin_contacts_by_presence(layout, "away", "Away", TRUE); + _rosterwin_contacts_by_presence(layout, "xa", "Extended Away", TRUE); + _rosterwin_contacts_by_presence(layout, "dnd", "Do not disturb", TRUE); + _rosterwin_contacts_by_presence(layout, "offline", "Offline", TRUE); + } else if (g_strcmp0(by, "group") == 0) { + GSList *groups = roster_get_groups(); + GSList *curr_group = groups; + while (curr_group) { + _rosterwin_contacts_by_group(layout, curr_group->data, newline); + newline = TRUE; + curr_group = g_slist_next(curr_group); + } + g_slist_free_full(groups, free); + _rosterwin_contacts_by_group(layout, NULL, newline); + } else { + _rosterwin_contacts_all(layout, newline); + } + prefs_free_string(by); + } + + if (prefs_get_boolean(PREF_ROSTER_ROOMS) && (g_strcmp0(roomspos, "last") == 0)) { + _rosterwin_rooms(layout, TRUE); + } + + prefs_free_string(roomspos); +} + +static void +_rosterwin_contacts_all(ProfLayoutSplit *layout, gboolean newline) +{ + GSList *contacts = NULL; + + char *order = prefs_get_string(PREF_ROSTER_ORDER); + gboolean offline = prefs_get_boolean(PREF_ROSTER_OFFLINE); + if (g_strcmp0(order, "presence") == 0) { + contacts = roster_get_contacts(ROSTER_ORD_PRESENCE, offline); + } else { + contacts = roster_get_contacts(ROSTER_ORD_NAME, offline); + } + prefs_free_string(order); + + _rosterwin_contacts_header(layout, "Roster", newline, contacts); + + if (contacts) { + GSList *curr_contact = contacts; + while (curr_contact) { + PContact contact = curr_contact->data; + _rosterwin_contact(layout, contact); + curr_contact = g_slist_next(curr_contact); + } + } + g_slist_free(contacts); +} + +static void +_rosterwin_contacts_by_presence(ProfLayoutSplit *layout, const char *const presence, char *title, gboolean newline) +{ + if ((g_strcmp0(presence, "offline") == 0) && !prefs_get_boolean(PREF_ROSTER_OFFLINE)) { + return; + } + + GSList *contacts = roster_get_contacts_by_presence(presence); + + // if this group has contacts, or if we want to show empty groups + if (contacts || prefs_get_boolean(PREF_ROSTER_EMPTY)) { + _rosterwin_contacts_header(layout, title, newline, contacts); + } + + if (contacts) { + GSList *curr_contact = contacts; + while (curr_contact) { + PContact contact = curr_contact->data; + _rosterwin_contact(layout, contact); + curr_contact = g_slist_next(curr_contact); + } + } + g_slist_free(contacts); +} + +static void +_rosterwin_contacts_by_group(ProfLayoutSplit *layout, char *group, gboolean newline) +{ + GSList *contacts = NULL; + + char *order = prefs_get_string(PREF_ROSTER_ORDER); + gboolean offline = prefs_get_boolean(PREF_ROSTER_OFFLINE); + if (g_strcmp0(order, "presence") == 0) { + contacts = roster_get_group(group, ROSTER_ORD_PRESENCE, offline); + } else { + contacts = roster_get_group(group, ROSTER_ORD_NAME, offline); + } + prefs_free_string(order); + + if (contacts || prefs_get_boolean(PREF_ROSTER_EMPTY)) { + if (group) { + _rosterwin_contacts_header(layout, group, newline, contacts); + } else { + _rosterwin_contacts_header(layout, "no group", newline, contacts); + } + + GSList *curr_contact = contacts; + while (curr_contact) { + PContact contact = curr_contact->data; + _rosterwin_contact(layout, contact); + curr_contact = g_slist_next(curr_contact); + } + } + g_slist_free(contacts); +} + +static void +_rosterwin_contact(ProfLayoutSplit *layout, PContact contact) +{ + const char *name = p_contact_name_or_jid(contact); + const char *presence = p_contact_presence(contact); + const char *status = p_contact_status(contact); + const char *barejid = p_contact_barejid(contact); + int unread = 0; + + roster_contact_theme_t theme_type = ROSTER_CONTACT; + ProfChatWin *chatwin = wins_get_chat(barejid); + if (chatwin) { + if (chatwin->unread > 0) { + theme_type = ROSTER_CONTACT_UNREAD; + unread = chatwin->unread; + } else { + theme_type = ROSTER_CONTACT_ACTIVE; + } + } + + theme_item_t presence_colour = _get_roster_theme(theme_type, presence); + + wattron(layout->subwin, theme_attrs(presence_colour)); + GString *msg = g_string_new(" "); + int indent = prefs_get_roster_contact_indent(); + int current_indent = 0; + if (indent > 0) { + current_indent += indent; + while (indent > 0) { + g_string_append(msg, " "); + indent--; + } + } + char ch = prefs_get_roster_contact_char(); + if (ch) { + g_string_append_printf(msg, "%c", ch); + } + + char *unreadpos = prefs_get_string(PREF_ROSTER_UNREAD); + if ((g_strcmp0(unreadpos, "before") == 0) && unread > 0) { + g_string_append_printf(msg, "(%d) ", unread); + unread = 0; + } + g_string_append(msg, name); + if (g_strcmp0(unreadpos, "after") == 0) { + if (!prefs_get_boolean(PREF_ROSTER_RESOURCE)) { + if (unread > 0) { + g_string_append_printf(msg, " (%d)", unread); + } + unread = 0; + } + } + prefs_free_string(unreadpos); + + win_sub_newline_lazy(layout->subwin); + gboolean wrap = prefs_get_boolean(PREF_ROSTER_WRAP); + win_sub_print(layout->subwin, msg->str, FALSE, wrap, current_indent); + g_string_free(msg, TRUE); + wattroff(layout->subwin, theme_attrs(presence_colour)); + + if (prefs_get_boolean(PREF_ROSTER_RESOURCE)) { + _rosterwin_resources(layout, contact, current_indent, theme_type, unread); + } else if (prefs_get_boolean(PREF_ROSTER_PRESENCE) || prefs_get_boolean(PREF_ROSTER_STATUS)) { + if (unread > 0) { + GString *unreadmsg = g_string_new(""); + g_string_append_printf(unreadmsg, " (%d)", unread); + wattron(layout->subwin, theme_attrs(presence_colour)); + win_sub_print(layout->subwin, unreadmsg->str, FALSE, wrap, current_indent); + g_string_free(unreadmsg, TRUE); + wattroff(layout->subwin, theme_attrs(presence_colour)); + } + + _rosterwin_presence(layout, presence_colour, presence, status, current_indent); + } +} + static void _rosterwin_presence(ProfLayoutSplit *layout, theme_item_t colour, const char *presence, const char *status, int current_indent) @@ -132,19 +370,9 @@ _rosterwin_presence(ProfLayoutSplit *layout, theme_item_t colour, const char *pr } } -theme_item_t -_get_roster_theme(roster_contact_theme_t theme_type, const char *presence) -{ - switch (theme_type) { - case ROSTER_CONTACT: return theme_roster_presence_attrs(presence); - case ROSTER_CONTACT_ACTIVE: return theme_roster_active_presence_attrs(presence); - case ROSTER_CONTACT_UNREAD: return theme_roster_unread_presence_attrs(presence); - default: return theme_roster_presence_attrs(presence); - } -} - static void -_rosterwin_resources(ProfLayoutSplit *layout, PContact contact, int current_indent, roster_contact_theme_t theme_type, int unread) +_rosterwin_resources(ProfLayoutSplit *layout, PContact contact, int current_indent, roster_contact_theme_t theme_type, + int unread) { gboolean join = prefs_get_boolean(PREF_ROSTER_RESOURCE_JOIN); @@ -276,283 +504,47 @@ _rosterwin_resources(ProfLayoutSplit *layout, PContact contact, int current_inde } static void -_rosterwin_contact(ProfLayoutSplit *layout, PContact contact) +_rosterwin_rooms(ProfLayoutSplit *layout, gboolean newline) { - const char *name = p_contact_name_or_jid(contact); - const char *presence = p_contact_presence(contact); - const char *status = p_contact_status(contact); - const char *barejid = p_contact_barejid(contact); - int unread = 0; - - roster_contact_theme_t theme_type = ROSTER_CONTACT; - ProfChatWin *chatwin = wins_get_chat(barejid); - if (chatwin) { - if (chatwin->unread > 0) { - theme_type = ROSTER_CONTACT_UNREAD; - unread = chatwin->unread; - } else { - theme_type = ROSTER_CONTACT_ACTIVE; - } - } - - theme_item_t presence_colour = _get_roster_theme(theme_type, presence); - - wattron(layout->subwin, theme_attrs(presence_colour)); - GString *msg = g_string_new(" "); - int indent = prefs_get_roster_contact_indent(); - int current_indent = 0; - if (indent > 0) { - current_indent += indent; - while (indent > 0) { - g_string_append(msg, " "); - indent--; - } - } - char ch = prefs_get_roster_contact_char(); - if (ch) { - g_string_append_printf(msg, "%c", ch); - } - - char *unreadpos = prefs_get_string(PREF_ROSTER_UNREAD); - if ((g_strcmp0(unreadpos, "before") == 0) && unread > 0) { - g_string_append_printf(msg, "(%d) ", unread); - unread = 0; - } - g_string_append(msg, name); - if (g_strcmp0(unreadpos, "after") == 0) { - if (!prefs_get_boolean(PREF_ROSTER_RESOURCE)) { - if (unread > 0) { - g_string_append_printf(msg, " (%d)", unread); + GList *rooms = muc_rooms(); + GList *rooms_sorted = NULL; + GList *curr_room = rooms; + while (curr_room) { + ProfMucWin *mucwin = wins_get_muc(curr_room->data); + if (mucwin) { + char *order = prefs_get_string(PREF_ROSTER_ROOMS_ORDER); + if (g_strcmp0(order, "unread") == 0) { + rooms_sorted = g_list_insert_sorted(rooms_sorted, mucwin, (GCompareFunc)_compare_rooms_unread); + } else { + rooms_sorted = g_list_insert_sorted(rooms_sorted, mucwin, (GCompareFunc)_compare_rooms_name); } - unread = 0; + prefs_free_string(order); + } + curr_room = g_list_next(curr_room); + } + g_list_free(rooms); + + // if there are active rooms, or if we want to show empty groups + if (rooms_sorted || prefs_get_boolean(PREF_ROSTER_EMPTY)) { + _rosterwin_rooms_header(layout, newline, rooms_sorted); + + GList *curr_room = rooms_sorted; + while (curr_room) { + _rosterwin_room(layout, curr_room->data); + curr_room = g_list_next(curr_room); } } - prefs_free_string(unreadpos); - win_sub_newline_lazy(layout->subwin); - gboolean wrap = prefs_get_boolean(PREF_ROSTER_WRAP); - win_sub_print(layout->subwin, msg->str, FALSE, wrap, current_indent); - g_string_free(msg, TRUE); - wattroff(layout->subwin, theme_attrs(presence_colour)); + g_list_free(rooms_sorted); - if (prefs_get_boolean(PREF_ROSTER_RESOURCE)) { - _rosterwin_resources(layout, contact, current_indent, theme_type, unread); - } else if (prefs_get_boolean(PREF_ROSTER_PRESENCE) || prefs_get_boolean(PREF_ROSTER_STATUS)) { - if (unread > 0) { - GString *unreadmsg = g_string_new(""); - g_string_append_printf(unreadmsg, " (%d)", unread); - wattron(layout->subwin, theme_attrs(presence_colour)); - win_sub_print(layout->subwin, unreadmsg->str, FALSE, wrap, current_indent); - g_string_free(unreadmsg, TRUE); - wattroff(layout->subwin, theme_attrs(presence_colour)); - } - - _rosterwin_presence(layout, presence_colour, presence, status, current_indent); + char *privpref = prefs_get_string(PREF_ROSTER_PRIVATE); + if (g_strcmp0(privpref, "group") == 0) { + _rosterwin_private_chats(layout); } + prefs_free_string(privpref); } static void -_rosterwin_contacts_by_presence(ProfLayoutSplit *layout, const char *const presence, char *title, gboolean newline) -{ - GSList *contacts = roster_get_contacts_by_presence(presence); - - // if this group has contacts, or if we want to show empty groups - if (contacts || prefs_get_boolean(PREF_ROSTER_EMPTY)) { - if (newline) { - win_sub_newline_lazy(layout->subwin); - } - wattron(layout->subwin, theme_attrs(THEME_ROSTER_HEADER)); - GString *title_str = g_string_new(" "); - char ch = prefs_get_roster_header_char(); - if (ch) { - g_string_append_printf(title_str, "%c", ch); - } - g_string_append(title_str, title); - - char *countpref = prefs_get_string(PREF_ROSTER_COUNT); - if (g_strcmp0(countpref, "items") == 0) { - int itemcount = g_slist_length(contacts); - if (itemcount == 0 && prefs_get_boolean(PREF_ROSTER_COUNT_ZERO)) { - g_string_append_printf(title_str, " (%d)", itemcount); - } else if (itemcount > 0) { - g_string_append_printf(title_str, " (%d)", itemcount); - } - } else if (g_strcmp0(countpref, "unread") == 0) { - int unreadcount = 0; - GSList *curr = contacts; - while (curr) { - PContact contact = curr->data; - const char *barejid = p_contact_barejid(contact); - ProfChatWin *chatwin = wins_get_chat(barejid); - if (chatwin) { - unreadcount += chatwin->unread; - } - curr = g_slist_next(curr); - } - if (unreadcount == 0 && prefs_get_boolean(PREF_ROSTER_COUNT_ZERO)) { - g_string_append_printf(title_str, " (%d)", unreadcount); - } else if (unreadcount > 0) { - g_string_append_printf(title_str, " (%d)", unreadcount); - } - } - prefs_free_string(countpref); - - gboolean wrap = prefs_get_boolean(PREF_ROSTER_WRAP); - win_sub_print(layout->subwin, title_str->str, FALSE, wrap, 1); - g_string_free(title_str, TRUE); - wattroff(layout->subwin, theme_attrs(THEME_ROSTER_HEADER)); - } - - if (contacts) { - GSList *curr_contact = contacts; - while (curr_contact) { - PContact contact = curr_contact->data; - _rosterwin_contact(layout, contact); - curr_contact = g_slist_next(curr_contact); - } - } - g_slist_free(contacts); -} - -static void -_rosterwin_contacts_by_group(ProfLayoutSplit *layout, char *group, gboolean newline) -{ - GSList *contacts = NULL; - - char *order = prefs_get_string(PREF_ROSTER_ORDER); - gboolean offline = prefs_get_boolean(PREF_ROSTER_OFFLINE); - if (g_strcmp0(order, "presence") == 0) { - contacts = roster_get_group(group, ROSTER_ORD_PRESENCE, offline); - } else { - contacts = roster_get_group(group, ROSTER_ORD_NAME, offline); - } - prefs_free_string(order); - - if (contacts || prefs_get_boolean(PREF_ROSTER_EMPTY)) { - if (newline) { - win_sub_newline_lazy(layout->subwin); - } - wattron(layout->subwin, theme_attrs(THEME_ROSTER_HEADER)); - GString *title = g_string_new(" "); - char ch = prefs_get_roster_header_char(); - if (ch) { - g_string_append_printf(title, "%c", ch); - } - g_string_append(title, group); - - char *countpref = prefs_get_string(PREF_ROSTER_COUNT); - if (g_strcmp0(countpref, "items") == 0) { - int itemcount = g_slist_length(contacts); - if (itemcount == 0 && prefs_get_boolean(PREF_ROSTER_COUNT_ZERO)) { - g_string_append_printf(title, " (%d)", itemcount); - } else if (itemcount > 0) { - g_string_append_printf(title, " (%d)", itemcount); - } - } else if (g_strcmp0(countpref, "unread") == 0) { - int unreadcount = 0; - GSList *curr = contacts; - while (curr) { - PContact contact = curr->data; - const char *barejid = p_contact_barejid(contact); - ProfChatWin *chatwin = wins_get_chat(barejid); - if (chatwin) { - unreadcount += chatwin->unread; - } - curr = g_slist_next(curr); - } - if (unreadcount == 0 && prefs_get_boolean(PREF_ROSTER_COUNT_ZERO)) { - g_string_append_printf(title, " (%d)", unreadcount); - } else if (unreadcount > 0) { - g_string_append_printf(title, " (%d)", unreadcount); - } - } - prefs_free_string(countpref); - - gboolean wrap = prefs_get_boolean(PREF_ROSTER_WRAP); - win_sub_print(layout->subwin, title->str, FALSE, wrap, 1); - g_string_free(title, TRUE); - wattroff(layout->subwin, theme_attrs(THEME_ROSTER_HEADER)); - - GSList *curr_contact = contacts; - while (curr_contact) { - PContact contact = curr_contact->data; - _rosterwin_contact(layout, contact); - curr_contact = g_slist_next(curr_contact); - } - } - g_slist_free(contacts); -} - -static void -_rosterwin_contacts_by_no_group(ProfLayoutSplit *layout, gboolean newline) -{ - GSList *contacts = NULL; - - char *order = prefs_get_string(PREF_ROSTER_ORDER); - gboolean offline = prefs_get_boolean(PREF_ROSTER_OFFLINE); - if (g_strcmp0(order, "presence") == 0) { - contacts = roster_get_nogroup(ROSTER_ORD_PRESENCE, offline); - } else { - contacts = roster_get_nogroup(ROSTER_ORD_NAME, offline); - } - prefs_free_string(order); - - if (contacts || prefs_get_boolean(PREF_ROSTER_EMPTY)) { - if (newline) { - win_sub_newline_lazy(layout->subwin); - } - wattron(layout->subwin, theme_attrs(THEME_ROSTER_HEADER)); - GString *title = g_string_new(" "); - char ch = prefs_get_roster_header_char(); - if (ch) { - g_string_append_printf(title, "%c", ch); - } - g_string_append(title, "no group"); - - char *countpref = prefs_get_string(PREF_ROSTER_COUNT); - if (g_strcmp0(countpref, "items") == 0) { - int itemcount = g_slist_length(contacts); - if (itemcount == 0 && prefs_get_boolean(PREF_ROSTER_COUNT_ZERO)) { - g_string_append_printf(title, " (%d)", itemcount); - } else if (itemcount > 0) { - g_string_append_printf(title, " (%d)", itemcount); - } - } else if (g_strcmp0(countpref, "unread") == 0) { - int unreadcount = 0; - GSList *curr = contacts; - while (curr) { - PContact contact = curr->data; - const char *barejid = p_contact_barejid(contact); - ProfChatWin *chatwin = wins_get_chat(barejid); - if (chatwin) { - unreadcount += chatwin->unread; - } - curr = g_slist_next(curr); - } - if (unreadcount == 0 && prefs_get_boolean(PREF_ROSTER_COUNT_ZERO)) { - g_string_append_printf(title, " (%d)", unreadcount); - } else if (unreadcount > 0) { - g_string_append_printf(title, " (%d)", unreadcount); - } - } - prefs_free_string(countpref); - - gboolean wrap = prefs_get_boolean(PREF_ROSTER_WRAP); - win_sub_print(layout->subwin, title->str, FALSE, wrap, 1); - g_string_free(title, TRUE); - wattroff(layout->subwin, theme_attrs(THEME_ROSTER_HEADER)); - - GSList *curr_contact = contacts; - while (curr_contact) { - PContact contact = curr_contact->data; - _rosterwin_contact(layout, contact); - curr_contact = g_slist_next(curr_contact); - } - } - g_slist_free(contacts); -} - -void _rosterwin_room(ProfLayoutSplit *layout, ProfMucWin *mucwin) { GString *msg = g_string_new(" "); @@ -676,66 +668,12 @@ _rosterwin_room(ProfLayoutSplit *layout, ProfMucWin *mucwin) prefs_free_string(privpref); } -static int -_compare_rooms_name(ProfMucWin *a, ProfMucWin *b) -{ - return g_strcmp0(a->roomjid, b->roomjid); -} - -static int -_compare_rooms_unread(ProfMucWin *a, ProfMucWin *b) -{ - if (a->unread > b->unread) { - return -1; - } else if (a->unread == b->unread) { - return g_strcmp0(a->roomjid, b->roomjid); - } else { - return 1; - } -} - -void +static void _rosterwin_private_chats(ProfLayoutSplit *layout) { GList *privs = wins_get_private_chats(NULL); if (privs || prefs_get_boolean(PREF_ROSTER_EMPTY)) { - win_sub_newline_lazy(layout->subwin); - wattron(layout->subwin, theme_attrs(THEME_ROSTER_HEADER)); - GString *title_str = g_string_new(" "); - char ch = prefs_get_roster_header_char(); - if (ch) { - g_string_append_printf(title_str, "%c", ch); - } - g_string_append(title_str, "Private chats"); - - char *countpref = prefs_get_string(PREF_ROSTER_COUNT); - if (g_strcmp0(countpref, "items") == 0) { - int itemcount = g_list_length(privs); - if (itemcount == 0 && prefs_get_boolean(PREF_ROSTER_COUNT_ZERO)) { - g_string_append_printf(title_str, " (%d)", itemcount); - } else if (itemcount > 0) { - g_string_append_printf(title_str, " (%d)", itemcount); - } - } else if (g_strcmp0(countpref, "unread") == 0) { - int unreadcount = 0; - GList *curr = privs; - while (curr) { - ProfPrivateWin *privwin = curr->data; - unreadcount += privwin->unread; - curr = g_list_next(curr); - } - if (unreadcount == 0 && prefs_get_boolean(PREF_ROSTER_COUNT_ZERO)) { - g_string_append_printf(title_str, " (%d)", unreadcount); - } else if (unreadcount > 0) { - g_string_append_printf(title_str, " (%d)", unreadcount); - } - } - prefs_free_string(countpref); - - gboolean wrap = prefs_get_boolean(PREF_ROSTER_WRAP); - win_sub_print(layout->subwin, title_str->str, FALSE, wrap, 1); - g_string_free(title_str, TRUE); - wattroff(layout->subwin, theme_attrs(THEME_ROSTER_HEADER)); + _rosterwin_private_header(layout, privs); GList *curr = privs; while (curr) { @@ -758,7 +696,7 @@ _rosterwin_private_chats(ProfLayoutSplit *layout) g_string_append_printf(privmsg, "(%d) ", privwin->unread); } - ch = prefs_get_roster_private_char(); + char ch = prefs_get_roster_private_char(); if (ch) { g_string_append_printf(privmsg, "%c", ch); } @@ -776,6 +714,7 @@ _rosterwin_private_chats(ProfLayoutSplit *layout) wattron(layout->subwin, theme_attrs(THEME_ROSTER_ROOM)); } + gboolean wrap = prefs_get_boolean(PREF_ROSTER_WRAP); win_sub_print(layout->subwin, privmsg->str, FALSE, wrap, current_indent); if (privwin->unread > 0) { @@ -792,210 +731,187 @@ _rosterwin_private_chats(ProfLayoutSplit *layout) } } -void -_rosterwin_rooms(ProfLayoutSplit *layout, gboolean newline) +static theme_item_t +_get_roster_theme(roster_contact_theme_t theme_type, const char *presence) { - int unread = 0; - GList *rooms = muc_rooms(); - GList *rooms_sorted = NULL; - GList *curr_room = rooms; - while (curr_room) { - ProfMucWin *mucwin = wins_get_muc(curr_room->data); - if (mucwin) { - char *order = prefs_get_string(PREF_ROSTER_ROOMS_ORDER); - if (g_strcmp0(order, "unread") == 0) { - rooms_sorted = g_list_insert_sorted(rooms_sorted, mucwin, (GCompareFunc)_compare_rooms_unread); - } else { - rooms_sorted = g_list_insert_sorted(rooms_sorted, mucwin, (GCompareFunc)_compare_rooms_name); - } - prefs_free_string(order); - unread += mucwin->unread; - } - curr_room = g_list_next(curr_room); + switch (theme_type) { + case ROSTER_CONTACT: return theme_roster_presence_attrs(presence); + case ROSTER_CONTACT_ACTIVE: return theme_roster_active_presence_attrs(presence); + case ROSTER_CONTACT_UNREAD: return theme_roster_unread_presence_attrs(presence); + default: return theme_roster_presence_attrs(presence); } - g_list_free(rooms); - - // if there are active rooms, or if we want to show empty groups - if (rooms_sorted || prefs_get_boolean(PREF_ROSTER_EMPTY)) { - if (newline) { - win_sub_newline_lazy(layout->subwin); - } - wattron(layout->subwin, theme_attrs(THEME_ROSTER_HEADER)); - GString *title_str = g_string_new(" "); - char ch = prefs_get_roster_header_char(); - if (ch) { - g_string_append_printf(title_str, "%c", ch); - } - g_string_append(title_str, "Rooms"); - - char *countpref = prefs_get_string(PREF_ROSTER_COUNT); - if (g_strcmp0(countpref, "items") == 0) { - int count = g_list_length(rooms_sorted); - if (count == 0 && prefs_get_boolean(PREF_ROSTER_COUNT_ZERO)) { - g_string_append_printf(title_str, " (%d)", count); - } else if (count > 0) { - g_string_append_printf(title_str, " (%d)", count); - } - } else if (g_strcmp0(countpref, "unread") == 0) { - char *prefpriv = prefs_get_string(PREF_ROSTER_PRIVATE); - if (g_strcmp0(prefpriv, "room") == 0) { - GList *privwins = wins_get_private_chats(NULL); - GList *curr = privwins; - while (curr) { - ProfPrivateWin *privwin = curr->data; - unread += privwin->unread; - curr = g_list_next(curr); - } - g_list_free(privwins); - } - prefs_free_string(prefpriv); - if (unread == 0 && prefs_get_boolean(PREF_ROSTER_COUNT_ZERO)) { - g_string_append_printf(title_str, " (%d)", unread); - } else if (unread > 0) { - g_string_append_printf(title_str, " (%d)", unread); - } - } - prefs_free_string(countpref); - - gboolean wrap = prefs_get_boolean(PREF_ROSTER_WRAP); - win_sub_print(layout->subwin, title_str->str, FALSE, wrap, 1); - g_string_free(title_str, TRUE); - wattroff(layout->subwin, theme_attrs(THEME_ROSTER_HEADER)); - - GList *curr_room = rooms_sorted; - while (curr_room) { - _rosterwin_room(layout, curr_room->data); - curr_room = g_list_next(curr_room); - } - } - - g_list_free(rooms_sorted); - - char *privpref = prefs_get_string(PREF_ROSTER_PRIVATE); - if (g_strcmp0(privpref, "group") == 0) { - _rosterwin_private_chats(layout); - } - prefs_free_string(privpref); } -void -rosterwin_roster(void) +static int +_compare_rooms_name(ProfMucWin *a, ProfMucWin *b) { - ProfWin *console = wins_get_console(); - if (!console) { - return; + return g_strcmp0(a->roomjid, b->roomjid); +} + +static int +_compare_rooms_unread(ProfMucWin *a, ProfMucWin *b) +{ + if (a->unread > b->unread) { + return -1; + } else if (a->unread == b->unread) { + return g_strcmp0(a->roomjid, b->roomjid); + } else { + return 1; + } +} + +static void +_rosterwin_contacts_header(ProfLayoutSplit *layout, const char *const title, gboolean newline, GSList *contacts) +{ + if (newline) { + win_sub_newline_lazy(layout->subwin); } - jabber_conn_status_t conn_status = jabber_get_connection_status(); - if (conn_status != JABBER_CONNECTED) { - return; + GString *header = g_string_new(" "); + char ch = prefs_get_roster_header_char(); + if (ch) { + g_string_append_printf(header, "%c", ch); } - ProfLayoutSplit *layout = (ProfLayoutSplit*)console->layout; - assert(layout->memcheck == LAYOUT_SPLIT_MEMCHECK); - werase(layout->subwin); + g_string_append(header, title); - gboolean newline = FALSE; - char *roomspos = prefs_get_string(PREF_ROSTER_ROOMS_POS); - if (prefs_get_boolean(PREF_ROSTER_ROOMS) && (g_strcmp0(roomspos, "first") == 0)) { - _rosterwin_rooms(layout, newline); - newline = TRUE; - } - - if (prefs_get_boolean(PREF_ROSTER_CONTACTS)) { - char *by = prefs_get_string(PREF_ROSTER_BY); - if (g_strcmp0(by, "presence") == 0) { - _rosterwin_contacts_by_presence(layout, "chat", "Available for chat", newline); - _rosterwin_contacts_by_presence(layout, "online", "Online", TRUE); - _rosterwin_contacts_by_presence(layout, "away", "Away", TRUE); - _rosterwin_contacts_by_presence(layout, "xa", "Extended Away", TRUE); - _rosterwin_contacts_by_presence(layout, "dnd", "Do not disturb", TRUE); - if (prefs_get_boolean(PREF_ROSTER_OFFLINE)) { - _rosterwin_contacts_by_presence(layout, "offline", "Offline", TRUE); - } - } else if (g_strcmp0(by, "group") == 0) { - GSList *groups = roster_get_groups(); - GSList *curr_group = groups; - while (curr_group) { - _rosterwin_contacts_by_group(layout, curr_group->data, newline); - newline = TRUE; - curr_group = g_slist_next(curr_group); - } - g_slist_free_full(groups, free); - _rosterwin_contacts_by_no_group(layout, newline); + char *countpref = prefs_get_string(PREF_ROSTER_COUNT); + if (g_strcmp0(countpref, "items") == 0) { + int itemcount = g_slist_length(contacts); + if (itemcount == 0 && prefs_get_boolean(PREF_ROSTER_COUNT_ZERO)) { + g_string_append_printf(header, " (%d)", itemcount); } else { - GSList *contacts = NULL; - - char *order = prefs_get_string(PREF_ROSTER_ORDER); - gboolean offline = prefs_get_boolean(PREF_ROSTER_OFFLINE); - if (g_strcmp0(order, "presence") == 0) { - contacts = roster_get_contacts(ROSTER_ORD_PRESENCE, offline); - } else { - contacts = roster_get_contacts(ROSTER_ORD_NAME, offline); - } - prefs_free_string(order); - - wattron(layout->subwin, theme_attrs(THEME_ROSTER_HEADER)); - GString *title = g_string_new(" "); - char ch = prefs_get_roster_header_char(); - if (ch) { - g_string_append_printf(title, "%c", ch); - } - if (newline) { - win_sub_newline_lazy(layout->subwin); - } - - g_string_append(title, "Roster"); - - char *countpref = prefs_get_string(PREF_ROSTER_COUNT); - if (g_strcmp0(countpref, "items") == 0) { - int itemcount = g_slist_length(contacts); - if (itemcount == 0 && prefs_get_boolean(PREF_ROSTER_COUNT_ZERO)) { - g_string_append_printf(title, " (%d)", itemcount); - } else { - g_string_append_printf(title, " (%d)", itemcount); - } - } else if (g_strcmp0(countpref, "unread") == 0) { - int unreadcount = 0; - GSList *curr = contacts; - while (curr) { - PContact contact = curr->data; - const char *barejid = p_contact_barejid(contact); - ProfChatWin *chatwin = wins_get_chat(barejid); - if (chatwin) { - unreadcount += chatwin->unread; - } - curr = g_slist_next(curr); - } - if (unreadcount == 0 && prefs_get_boolean(PREF_ROSTER_COUNT_ZERO)) { - g_string_append_printf(title, " (%d)", unreadcount); - } else if (unreadcount > 0) { - g_string_append_printf(title, " (%d)", unreadcount); - } - } - prefs_free_string(countpref); - - gboolean wrap = prefs_get_boolean(PREF_ROSTER_WRAP); - win_sub_print(layout->subwin, title->str, FALSE, wrap, 1); - g_string_free(title, TRUE); - wattroff(layout->subwin, theme_attrs(THEME_ROSTER_HEADER)); - - if (contacts) { - GSList *curr_contact = contacts; - while (curr_contact) { - PContact contact = curr_contact->data; - _rosterwin_contact(layout, contact); - curr_contact = g_slist_next(curr_contact); - } - } - g_slist_free(contacts); + g_string_append_printf(header, " (%d)", itemcount); + } + } else if (g_strcmp0(countpref, "unread") == 0) { + int unreadcount = 0; + GSList *curr = contacts; + while (curr) { + PContact contact = curr->data; + const char *barejid = p_contact_barejid(contact); + ProfChatWin *chatwin = wins_get_chat(barejid); + if (chatwin) { + unreadcount += chatwin->unread; + } + curr = g_slist_next(curr); + } + if (unreadcount == 0 && prefs_get_boolean(PREF_ROSTER_COUNT_ZERO)) { + g_string_append_printf(header, " (%d)", unreadcount); + } else if (unreadcount > 0) { + g_string_append_printf(header, " (%d)", unreadcount); } - prefs_free_string(by); } + prefs_free_string(countpref); - if (prefs_get_boolean(PREF_ROSTER_ROOMS) && (g_strcmp0(roomspos, "last") == 0)) { - _rosterwin_rooms(layout, TRUE); - } + gboolean wrap = prefs_get_boolean(PREF_ROSTER_WRAP); - prefs_free_string(roomspos); + wattron(layout->subwin, theme_attrs(THEME_ROSTER_HEADER)); + win_sub_print(layout->subwin, header->str, FALSE, wrap, 1); + wattroff(layout->subwin, theme_attrs(THEME_ROSTER_HEADER)); + + g_string_free(header, TRUE); +} + +static void +_rosterwin_rooms_header(ProfLayoutSplit *layout, gboolean newline, GList *rooms) +{ + if (newline) { + win_sub_newline_lazy(layout->subwin); + } + GString *header = g_string_new(" "); + char ch = prefs_get_roster_header_char(); + if (ch) { + g_string_append_printf(header, "%c", ch); + } + g_string_append(header, "Rooms"); + + char *countpref = prefs_get_string(PREF_ROSTER_COUNT); + if (g_strcmp0(countpref, "items") == 0) { + int count = g_list_length(rooms); + if (count == 0 && prefs_get_boolean(PREF_ROSTER_COUNT_ZERO)) { + g_string_append_printf(header, " (%d)", count); + } else if (count > 0) { + g_string_append_printf(header, " (%d)", count); + } + } else if (g_strcmp0(countpref, "unread") == 0) { + int unread = 0; + GList *curr = rooms; + while (curr) { + ProfMucWin *mucwin = curr->data; + unread += mucwin->unread; + curr = g_list_next(curr); + } + + char *prefpriv = prefs_get_string(PREF_ROSTER_PRIVATE); + if (g_strcmp0(prefpriv, "room") == 0) { + GList *privwins = wins_get_private_chats(NULL); + GList *curr = privwins; + while (curr) { + ProfPrivateWin *privwin = curr->data; + unread += privwin->unread; + curr = g_list_next(curr); + } + g_list_free(privwins); + } + prefs_free_string(prefpriv); + if (unread == 0 && prefs_get_boolean(PREF_ROSTER_COUNT_ZERO)) { + g_string_append_printf(header, " (%d)", unread); + } else if (unread > 0) { + g_string_append_printf(header, " (%d)", unread); + } + } + prefs_free_string(countpref); + + gboolean wrap = prefs_get_boolean(PREF_ROSTER_WRAP); + + wattron(layout->subwin, theme_attrs(THEME_ROSTER_HEADER)); + win_sub_print(layout->subwin, header->str, FALSE, wrap, 1); + wattroff(layout->subwin, theme_attrs(THEME_ROSTER_HEADER)); + + g_string_free(header, TRUE); +} + +static void +_rosterwin_private_header(ProfLayoutSplit *layout, GList *privs) +{ + win_sub_newline_lazy(layout->subwin); + + GString *title_str = g_string_new(" "); + char ch = prefs_get_roster_header_char(); + if (ch) { + g_string_append_printf(title_str, "%c", ch); + } + g_string_append(title_str, "Private chats"); + + char *countpref = prefs_get_string(PREF_ROSTER_COUNT); + if (g_strcmp0(countpref, "items") == 0) { + int itemcount = g_list_length(privs); + if (itemcount == 0 && prefs_get_boolean(PREF_ROSTER_COUNT_ZERO)) { + g_string_append_printf(title_str, " (%d)", itemcount); + } else if (itemcount > 0) { + g_string_append_printf(title_str, " (%d)", itemcount); + } + } else if (g_strcmp0(countpref, "unread") == 0) { + int unreadcount = 0; + GList *curr = privs; + while (curr) { + ProfPrivateWin *privwin = curr->data; + unreadcount += privwin->unread; + curr = g_list_next(curr); + } + if (unreadcount == 0 && prefs_get_boolean(PREF_ROSTER_COUNT_ZERO)) { + g_string_append_printf(title_str, " (%d)", unreadcount); + } else if (unreadcount > 0) { + g_string_append_printf(title_str, " (%d)", unreadcount); + } + } + prefs_free_string(countpref); + + gboolean wrap = prefs_get_boolean(PREF_ROSTER_WRAP); + + wattron(layout->subwin, theme_attrs(THEME_ROSTER_HEADER)); + win_sub_print(layout->subwin, title_str->str, FALSE, wrap, 1); + wattroff(layout->subwin, theme_attrs(THEME_ROSTER_HEADER)); + + g_string_free(title_str, TRUE); } diff --git a/tests/unittests/unittests.c b/tests/unittests/unittests.c index e511df9d..c9c1a662 100644 --- a/tests/unittests/unittests.c +++ b/tests/unittests/unittests.c @@ -622,7 +622,9 @@ int main(int argc, char* argv[]) { unit_test(remove_text_multi_value_removes_when_one), unit_test(remove_text_multi_value_removes_when_many), - unit_test(clears_chat_sessions), + unit_test_setup_teardown(clears_chat_sessions, + load_preferences, + close_preferences), }; return run_tests(all_tests);