From f91b21a1d67f97f2ba55d32358f85df9ffe3d175 Mon Sep 17 00:00:00 2001 From: James Booth Date: Mon, 1 Feb 2016 01:11:01 +0000 Subject: [PATCH] Allow splitting roster rooms by conference server --- src/command/command.c | 17 ++++- src/command/commands.c | 19 ++++++ src/config/preferences.c | 5 ++ src/config/preferences.h | 1 + src/config/theme.c | 1 + src/ui/console.c | 4 ++ src/ui/rosterwin.c | 130 +++++++++++++++++++++++++++++++-------- theme_template | 1 + themes/boothj5 | 1 + themes/complex | 1 + 10 files changed, 154 insertions(+), 26 deletions(-) diff --git a/src/command/command.c b/src/command/command.c index 5f2f64fb..6191caef 100644 --- a/src/command/command.c +++ b/src/command/command.c @@ -271,7 +271,7 @@ static struct cmd_t command_defs[] = }, { "/roster", - cmd_roster, parse_args_with_freetext, 0, 3, NULL, + cmd_roster, parse_args_with_freetext, 0, 4, NULL, CMD_TAGS( CMD_TAG_ROSTER, CMD_TAG_UI) @@ -288,6 +288,7 @@ static struct cmd_t command_defs[] = "/roster room char |none", "/roster room private char |none", "/roster room position first|last", + "/roster room by service|none", "/roster room order name|unread", "/roster room unread before|after|off", "/roster private room|group|off", @@ -348,6 +349,8 @@ static struct cmd_t command_defs[] = { "room private char none", "Remove private room chat character prefix when displayed with room." }, { "room position first", "Show rooms first in roster." }, { "room position last", "Show rooms last in roster." }, + { "room by service", "Group rooms by chat service." }, + { "room by none", "Do not group rooms." }, { "room order name", "Order rooms by name." }, { "room order unread", "Order rooms by unread messages, and then by name." }, { "room unread before", "Show unread message count before room." }, @@ -1948,6 +1951,7 @@ static Autocomplete roster_char_ac; static Autocomplete roster_remove_all_ac; static Autocomplete roster_room_ac; static Autocomplete roster_room_position_ac; +static Autocomplete roster_room_by_ac; static Autocomplete roster_room_order_ac; static Autocomplete roster_unread_ac; static Autocomplete roster_private_ac; @@ -2278,10 +2282,15 @@ cmd_init(void) roster_room_ac = autocomplete_new(); autocomplete_add(roster_room_ac, "char"); autocomplete_add(roster_room_ac, "position"); + autocomplete_add(roster_room_ac, "by"); autocomplete_add(roster_room_ac, "order"); autocomplete_add(roster_room_ac, "unread"); autocomplete_add(roster_room_ac, "private"); + roster_room_by_ac = autocomplete_new(); + autocomplete_add(roster_room_by_ac, "service"); + autocomplete_add(roster_room_by_ac, "none"); + roster_room_order_ac = autocomplete_new(); autocomplete_add(roster_room_order_ac, "name"); autocomplete_add(roster_room_order_ac, "unread"); @@ -2564,6 +2573,7 @@ cmd_uninit(void) autocomplete_free(roster_count_ac); autocomplete_free(roster_order_ac); autocomplete_free(roster_room_ac); + autocomplete_free(roster_room_by_ac); autocomplete_free(roster_unread_ac); autocomplete_free(roster_room_position_ac); autocomplete_free(roster_room_order_ac); @@ -2778,6 +2788,7 @@ cmd_reset_autocomplete(ProfWin *window) autocomplete_reset(roster_count_ac); autocomplete_reset(roster_order_ac); autocomplete_reset(roster_room_ac); + autocomplete_reset(roster_room_by_ac); autocomplete_reset(roster_unread_ac); autocomplete_reset(roster_room_position_ac); autocomplete_reset(roster_room_order_ac); @@ -3210,6 +3221,10 @@ _roster_autocomplete(ProfWin *window, const char *const input) if (result) { return result; } + result = autocomplete_param_with_ac(input, "/roster room by", roster_room_by_ac, TRUE); + if (result) { + return result; + } result = autocomplete_param_with_ac(input, "/roster room order", roster_room_order_ac, TRUE); if (result) { return result; diff --git a/src/command/commands.c b/src/command/commands.c index 0a88d2bb..c8c01778 100644 --- a/src/command/commands.c +++ b/src/command/commands.c @@ -2565,6 +2565,25 @@ cmd_roster(ProfWin *window, const char *const command, gchar **args) cons_bad_cmd_usage(command); return TRUE; } + } else if (g_strcmp0(args[1], "by") == 0) { + if (g_strcmp0(args[2], "service") == 0) { + cons_show("Grouping rooms by service"); + prefs_set_string(PREF_ROSTER_ROOMS_BY, "service"); + if (conn_status == JABBER_CONNECTED) { + rosterwin_roster(); + } + return TRUE; + } else if (g_strcmp0(args[2], "none") == 0) { + cons_show("Roster room grouping disabled"); + prefs_set_string(PREF_ROSTER_ROOMS_BY, "none"); + if (conn_status == JABBER_CONNECTED) { + rosterwin_roster(); + } + return TRUE; + } else { + cons_bad_cmd_usage(command); + return TRUE; + } } else { cons_bad_cmd_usage(command); return TRUE; diff --git a/src/config/preferences.c b/src/config/preferences.c index 0a2ae3cc..3ce1997c 100644 --- a/src/config/preferences.c +++ b/src/config/preferences.c @@ -1147,6 +1147,7 @@ _get_group(preference_t pref) case PREF_ROSTER_CONTACTS: case PREF_ROSTER_ROOMS: case PREF_ROSTER_ROOMS_POS: + case PREF_ROSTER_ROOMS_BY: case PREF_ROSTER_ROOMS_ORDER: case PREF_ROSTER_ROOMS_UNREAD: case PREF_ROSTER_PRIVATE: @@ -1354,6 +1355,8 @@ _get_key(preference_t pref) return "roster.rooms"; case PREF_ROSTER_ROOMS_POS: return "roster.rooms.pos"; + case PREF_ROSTER_ROOMS_BY: + return "roster.rooms.by"; case PREF_ROSTER_ROOMS_ORDER: return "roster.rooms.order"; case PREF_ROSTER_ROOMS_UNREAD: @@ -1454,6 +1457,8 @@ _get_default_string(preference_t pref) return "after"; case PREF_ROSTER_ROOMS_POS: return "last"; + case PREF_ROSTER_ROOMS_BY: + return "none"; case PREF_ROSTER_ROOMS_ORDER: return "name"; case PREF_ROSTER_ROOMS_UNREAD: diff --git a/src/config/preferences.h b/src/config/preferences.h index ff8b687d..ac79a076 100644 --- a/src/config/preferences.h +++ b/src/config/preferences.h @@ -78,6 +78,7 @@ typedef enum { PREF_ROSTER_CONTACTS, PREF_ROSTER_ROOMS, PREF_ROSTER_ROOMS_POS, + PREF_ROSTER_ROOMS_BY, PREF_ROSTER_ROOMS_ORDER, PREF_ROSTER_ROOMS_UNREAD, PREF_ROSTER_PRIVATE, diff --git a/src/config/theme.c b/src/config/theme.c index 40bf3539..614deeb7 100644 --- a/src/config/theme.c +++ b/src/config/theme.c @@ -416,6 +416,7 @@ _load_preferences(void) _set_string_preference("roster.rooms.order", PREF_ROSTER_ROOMS_ORDER); _set_string_preference("roster.rooms.unread", PREF_ROSTER_ROOMS_UNREAD); _set_string_preference("roster.rooms.pos", PREF_ROSTER_ROOMS_POS); + _set_string_preference("roster.rooms.by", PREF_ROSTER_ROOMS_BY); _set_string_preference("roster.private", PREF_ROSTER_PRIVATE); _set_string_preference("roster.count", PREF_ROSTER_COUNT); diff --git a/src/ui/console.c b/src/ui/console.c index 5c05c5dc..3d88ac16 100644 --- a/src/ui/console.c +++ b/src/ui/console.c @@ -1434,6 +1434,10 @@ cons_roster_setting(void) cons_show("Roster rooms position (/roster) : %s", rooms_pos); prefs_free_string(rooms_pos); + char *rooms_by = prefs_get_string(PREF_ROSTER_ROOMS_BY); + cons_show("Roster rooms by (/roster) : %s", rooms_by); + prefs_free_string(rooms_by); + char *rooms_order = prefs_get_string(PREF_ROSTER_ROOMS_ORDER); cons_show("Roster rooms order (/roster) : %s", rooms_order); prefs_free_string(rooms_order); diff --git a/src/ui/rosterwin.c b/src/ui/rosterwin.c index 6b63a13e..6d25b6ec 100644 --- a/src/ui/rosterwin.c +++ b/src/ui/rosterwin.c @@ -61,8 +61,9 @@ static void _rosterwin_presence(ProfLayoutSplit *layout, const char *presence, c 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_rooms(ProfLayoutSplit *layout, gboolean newline, char *title, GList *rooms); +static void _rosterwin_rooms_by_service(ProfLayoutSplit *layout, gboolean newline); +static void _rosterwin_rooms_header(ProfLayoutSplit *layout, gboolean newline, GList *rooms, char *title); static void _rosterwin_room(ProfLayoutSplit *layout, ProfMucWin *mucwin); static void _rosterwin_private_chats(ProfLayoutSplit *layout, GList *orphaned_privchats); @@ -94,8 +95,36 @@ rosterwin_roster(void) 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); + char *roomsbypref = prefs_get_string(PREF_ROSTER_ROOMS_BY); + if (g_strcmp0(roomsbypref, "service") == 0) { + _rosterwin_rooms_by_service(layout, newline); + } else { + GList *rooms = muc_rooms(); + _rosterwin_rooms(layout, newline, "Rooms", rooms); + } newline = TRUE; + prefs_free_string(roomsbypref); + + GList *orphaned_privchats = NULL; + GList *privchats = wins_get_private_chats(NULL); + GList *curr = privchats; + while (curr) { + ProfPrivateWin *privwin = curr->data; + Jid *jidp = jid_create(privwin->fulljid); + if (!muc_active(jidp->barejid)) { + orphaned_privchats = g_list_append(orphaned_privchats, privwin); + } + jid_destroy(jidp); + curr = g_list_next(curr); + } + + char *privpref = prefs_get_string(PREF_ROSTER_PRIVATE); + if (g_strcmp0(privpref, "group") == 0 || orphaned_privchats) { + _rosterwin_private_chats(layout, orphaned_privchats); + } + prefs_free_string(privpref); + g_list_free(orphaned_privchats); + } if (prefs_get_boolean(PREF_ROSTER_CONTACTS)) { @@ -124,7 +153,34 @@ rosterwin_roster(void) } if (prefs_get_boolean(PREF_ROSTER_ROOMS) && (g_strcmp0(roomspos, "last") == 0)) { - _rosterwin_rooms(layout, TRUE); + char *roomsbypref = prefs_get_string(PREF_ROSTER_ROOMS_BY); + if (g_strcmp0(roomsbypref, "service") == 0) { + _rosterwin_rooms_by_service(layout, newline); + } else { + GList *rooms = muc_rooms(); + _rosterwin_rooms(layout, newline, "Rooms", rooms); + } + prefs_free_string(roomsbypref); + + GList *orphaned_privchats = NULL; + GList *privchats = wins_get_private_chats(NULL); + GList *curr = privchats; + while (curr) { + ProfPrivateWin *privwin = curr->data; + Jid *jidp = jid_create(privwin->fulljid); + if (!muc_active(jidp->barejid)) { + orphaned_privchats = g_list_append(orphaned_privchats, privwin); + } + jid_destroy(jidp); + curr = g_list_next(curr); + } + + char *privpref = prefs_get_string(PREF_ROSTER_PRIVATE); + if (g_strcmp0(privpref, "group") == 0 || orphaned_privchats) { + _rosterwin_private_chats(layout, orphaned_privchats); + } + prefs_free_string(privpref); + g_list_free(orphaned_privchats); } prefs_free_string(roomspos); @@ -514,9 +570,8 @@ _rosterwin_resources(ProfLayoutSplit *layout, PContact contact, int current_inde } static void -_rosterwin_rooms(ProfLayoutSplit *layout, gboolean newline) +_rosterwin_rooms(ProfLayoutSplit *layout, gboolean newline, char *title, GList *rooms) { - GList *rooms = muc_rooms(); GList *rooms_sorted = NULL; GList *curr_room = rooms; while (curr_room) { @@ -536,7 +591,7 @@ _rosterwin_rooms(ProfLayoutSplit *layout, gboolean newline) // 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); + _rosterwin_rooms_header(layout, newline, rooms_sorted, title); GList *curr_room = rooms_sorted; while (curr_room) { @@ -546,26 +601,44 @@ _rosterwin_rooms(ProfLayoutSplit *layout, gboolean newline) } g_list_free(rooms_sorted); +} - GList *orphaned_privchats = NULL; - GList *privchats = wins_get_private_chats(NULL); - GList *curr = privchats; - while (curr) { - ProfPrivateWin *privwin = curr->data; - Jid *jidp = jid_create(privwin->fulljid); - if (!muc_active(jidp->barejid)) { - orphaned_privchats = g_list_append(orphaned_privchats, privwin); +static void +_rosterwin_rooms_by_service(ProfLayoutSplit *layout, gboolean newline) +{ + GList *curr_room = muc_rooms(); + GList *services = NULL; + while (curr_room) { + char *roomjid = curr_room->data; + Jid *jidp = jid_create(roomjid); + if (!g_list_find_custom(services, jidp->domainpart, (GCompareFunc)g_strcmp0)) { + services = g_list_insert_sorted(services, strdup(jidp->domainpart), (GCompareFunc)g_strcmp0); } - jid_destroy(jidp); - curr = g_list_next(curr); + curr_room = g_list_next(curr_room); } - char *privpref = prefs_get_string(PREF_ROSTER_PRIVATE); - if (g_strcmp0(privpref, "group") == 0 || orphaned_privchats) { - _rosterwin_private_chats(layout, orphaned_privchats); + GList *curr_service = services; + while (curr_service) { + char *service = curr_service->data; + GList *filtered_rooms = NULL; + + curr_room = muc_rooms(); + while (curr_room) { + char *roomjid = curr_room->data; + Jid *jidp = jid_create(roomjid); + + if (g_strcmp0(curr_service->data, jidp->domainpart) == 0) { + filtered_rooms = g_list_append(filtered_rooms, jidp->barejid); + } + + curr_room = g_list_next(curr_room); + } + + _rosterwin_rooms(layout, newline, service, filtered_rooms); + newline = TRUE; + + curr_service = g_list_next(curr_service); } - prefs_free_string(privpref); - g_list_free(orphaned_privchats); } static void @@ -601,7 +674,14 @@ _rosterwin_room(ProfLayoutSplit *layout, ProfMucWin *mucwin) if ((g_strcmp0(unreadpos, "before") == 0) && mucwin->unread > 0) { g_string_append_printf(msg, "(%d) ", mucwin->unread); } - g_string_append(msg, mucwin->roomjid); + char *roombypref = prefs_get_string(PREF_ROSTER_ROOMS_BY); + if (g_strcmp0(roombypref, "service") == 0) { + Jid *jidp = jid_create(mucwin->roomjid); + g_string_append(msg, jidp->localpart); + jid_destroy(jidp); + } else { + g_string_append(msg, mucwin->roomjid); + } if ((g_strcmp0(unreadpos, "after") == 0) && mucwin->unread > 0) { g_string_append_printf(msg, " (%d)", mucwin->unread); } @@ -861,7 +941,7 @@ _rosterwin_contacts_header(ProfLayoutSplit *layout, const char *const title, gbo } static void -_rosterwin_rooms_header(ProfLayoutSplit *layout, gboolean newline, GList *rooms) +_rosterwin_rooms_header(ProfLayoutSplit *layout, gboolean newline, GList *rooms, char *title) { if (newline) { win_sub_newline_lazy(layout->subwin); @@ -871,7 +951,7 @@ _rosterwin_rooms_header(ProfLayoutSplit *layout, gboolean newline, GList *rooms) if (ch) { g_string_append_printf(header, "%c", ch); } - g_string_append(header, "Rooms"); + g_string_append(header, title); char *countpref = prefs_get_string(PREF_ROSTER_COUNT); if (g_strcmp0(countpref, "items") == 0) { diff --git a/theme_template b/theme_template index 49288cab..b4eaf3ef 100644 --- a/theme_template +++ b/theme_template @@ -119,6 +119,7 @@ roster.rooms= roster.rooms.order= roster.rooms.unread= roster.rooms.pos= +roster.rooms.by= roster.rooms.char= roster.rooms.private.char= roster.private= diff --git a/themes/boothj5 b/themes/boothj5 index c4efb529..36c66af0 100644 --- a/themes/boothj5 +++ b/themes/boothj5 @@ -118,6 +118,7 @@ roster.rooms=true roster.rooms.order=name roster.rooms.unread=after roster.rooms.pos=last +roster.rooms.by=none roster.rooms.private.char=/ roster.private=room roster.count=unread diff --git a/themes/complex b/themes/complex index 677427e1..c37a8018 100644 --- a/themes/complex +++ b/themes/complex @@ -43,6 +43,7 @@ roster.rooms=true roster.rooms.order=unread roster.rooms.unread=after roster.rooms.pos=last +roster.rooms.by=service roster.rooms.char=# roster.rooms.private.char=/ roster.private=room