Skip to content
This repository has been archived by the owner on Feb 10, 2024. It is now read-only.

Commit

Permalink
Move userlist sorting to frontend
Browse files Browse the repository at this point in the history
This Fixes possible crashes when the two
usertrees get out of sync and a double free occurs.

Also now requires restart to change sort orders.

Fixes #1252
Fixes #818 (probably)
  • Loading branch information
TingPing committed Dec 31, 2014
1 parent fef580e commit 9f7444b
Show file tree
Hide file tree
Showing 9 changed files with 88 additions and 67 deletions.
3 changes: 1 addition & 2 deletions src/common/fe.h
Expand Up @@ -88,11 +88,10 @@ void fe_progressbar_start (struct session *sess);
void fe_progressbar_end (struct server *serv);
void fe_print_text (struct session *sess, char *text, time_t stamp,
gboolean no_activity);
void fe_userlist_insert (struct session *sess, struct User *newuser, int row, int sel);
void fe_userlist_insert (struct session *sess, struct User *newuser, gboolean sel);
int fe_userlist_remove (struct session *sess, struct User *user);
void fe_userlist_rehash (struct session *sess, struct User *user);
void fe_userlist_update (struct session *sess, struct User *user);
void fe_userlist_move (struct session *sess, struct User *user, int new_row);
void fe_userlist_numbers (struct session *sess);
void fe_userlist_clear (struct session *sess);
void fe_userlist_set_selected (struct session *sess);
Expand Down
4 changes: 2 additions & 2 deletions src/common/hexchat.h
Expand Up @@ -37,6 +37,7 @@
#endif

#include "history.h"
#include "tree.h"

#ifdef USE_OPENSSL
#include <openssl/ssl.h> /* SSL_() */
Expand Down Expand Up @@ -369,8 +370,7 @@ typedef struct session
guint8 text_strip;

struct server *server;
void *usertree_alpha; /* pure alphabetical tree */
void *usertree; /* ordered with Ops first */
tree *usertree; /* alphabetical tree */
struct User *me; /* points to myself in the usertree */
char channel[CHANLEN];
char waitchannel[CHANLEN]; /* waiting to join channel (/join sent) */
Expand Down
58 changes: 15 additions & 43 deletions src/common/userlist.c
Expand Up @@ -29,7 +29,7 @@
#include "util.h"


static int
int
nick_cmp_az_ops (server *serv, struct User *user1, struct User *user2)
{
unsigned int access1 = user1->access;
Expand All @@ -52,30 +52,12 @@ nick_cmp_az_ops (server *serv, struct User *user1, struct User *user2)
return serv->p_cmp (user1->nick, user2->nick);
}

static int
int
nick_cmp_alpha (struct User *user1, struct User *user2, server *serv)
{
return serv->p_cmp (user1->nick, user2->nick);
}

static int
nick_cmp (struct User *user1, struct User *user2, server *serv)
{
switch (prefs.hex_gui_ulist_sort)
{
case 0:
return nick_cmp_az_ops (serv, user1, user2);
case 1:
return serv->p_cmp (user1->nick, user2->nick);
case 2:
return -1 * nick_cmp_az_ops (serv, user1, user2);
case 3:
return -1 * serv->p_cmp (user1->nick, user2->nick);
default:
return -1;
}
}

/*
insert name in appropriate place in linked list. Returns row number or:
-1: duplicate
Expand All @@ -86,11 +68,9 @@ userlist_insertname (session *sess, struct User *newuser)
{
if (!sess->usertree)
{
sess->usertree = tree_new ((tree_cmp_func *)nick_cmp, sess->server);
sess->usertree_alpha = tree_new ((tree_cmp_func *)nick_cmp_alpha, sess->server);
sess->usertree = tree_new ((tree_cmp_func *)nick_cmp_alpha, sess->server);
}

tree_insert (sess->usertree_alpha, newuser);
return tree_insert (sess->usertree, newuser);
}

Expand Down Expand Up @@ -188,10 +168,8 @@ userlist_free (session *sess)
{
tree_foreach (sess->usertree, (tree_traverse_func *)free_user, NULL);
tree_destroy (sess->usertree);
tree_destroy (sess->usertree_alpha);

sess->usertree = NULL;
sess->usertree_alpha = NULL;
sess->me = NULL;

sess->ops = 0;
Expand Down Expand Up @@ -219,8 +197,8 @@ userlist_find (struct session *sess, const char *name)
{
int pos;

if (sess->usertree_alpha)
return tree_find (sess->usertree_alpha, name,
if (sess->usertree)
return tree_find (sess->usertree, name,
(tree_cmp_func *)find_cmp, sess->server, &pos);

return NULL;
Expand Down Expand Up @@ -283,7 +261,7 @@ userlist_update_mode (session *sess, char *name, char mode, char sign)

/* remove from binary trees, before we loose track of it */
tree_remove (sess->usertree, user, &pos);
tree_remove (sess->usertree_alpha, user, &pos);
fe_userlist_remove (sess, user);

/* which bit number is affected? */
access = mode_access (sess->server, mode, &prefix);
Expand Down Expand Up @@ -313,11 +291,8 @@ userlist_update_mode (session *sess, char *name, char mode, char sign)
update_counts (sess, user, prefix, level, offset);

/* insert it back into its new place */
tree_insert (sess->usertree_alpha, user);
pos = tree_insert (sess->usertree, user);

/* let GTK move it too */
fe_userlist_move (sess, user, pos);
tree_insert (sess->usertree, user);
fe_userlist_insert (sess, user, FALSE);
fe_userlist_numbers (sess);
}

Expand All @@ -330,14 +305,12 @@ userlist_change (struct session *sess, char *oldname, char *newname)
if (user)
{
tree_remove (sess->usertree, user, &pos);
tree_remove (sess->usertree_alpha, user, &pos);
fe_userlist_remove (sess, user);

safe_strcpy (user->nick, newname, NICKLEN);

tree_insert (sess->usertree_alpha, user);

fe_userlist_move (sess, user, tree_insert (sess->usertree, user));
fe_userlist_numbers (sess);
tree_insert (sess->usertree, user);
fe_userlist_insert (sess, user, FALSE);

return 1;
}
Expand Down Expand Up @@ -376,7 +349,6 @@ userlist_remove_user (struct session *sess, struct User *user)
sess->me = NULL;

tree_remove (sess->usertree, user, &pos);
tree_remove (sess->usertree_alpha, user, &pos);
free_user (user, NULL);
}

Expand Down Expand Up @@ -442,7 +414,7 @@ userlist_add (struct session *sess, char *name, char *hostname,
if (user->me)
sess->me = user;

fe_userlist_insert (sess, user, row, FALSE);
fe_userlist_insert (sess, user, FALSE);
fe_userlist_numbers (sess);
}

Expand All @@ -456,7 +428,7 @@ rehash_cb (struct User *user, session *sess)
void
userlist_rehash (session *sess)
{
tree_foreach (sess->usertree_alpha, (tree_traverse_func *)rehash_cb, sess);
tree_foreach (sess->usertree, (tree_traverse_func *)rehash_cb, sess);
}

static int
Expand All @@ -471,7 +443,7 @@ userlist_flat_list (session *sess)
{
GSList *list = NULL;

tree_foreach (sess->usertree_alpha, (tree_traverse_func *)flat_cb, &list);
tree_foreach (sess->usertree, (tree_traverse_func *)flat_cb, &list);
return g_slist_reverse (list);
}

Expand All @@ -487,6 +459,6 @@ userlist_double_list(session *sess)
{
GList *list = NULL;

tree_foreach (sess->usertree_alpha, (tree_traverse_func *)double_cb, &list);
tree_foreach (sess->usertree, (tree_traverse_func *)double_cb, &list);
return list;
}
2 changes: 2 additions & 0 deletions src/common/userlist.h
Expand Up @@ -61,5 +61,7 @@ void userlist_update_mode (session *sess, char *name, char mode, char sign);
GSList *userlist_flat_list (session *sess);
GList *userlist_double_list (session *sess);
void userlist_rehash (session *sess);
int nick_cmp_az_ops (server *serv, struct User *user1, struct User *user2);
int nick_cmp_alpha (struct User *user1, struct User *user2, server *serv);

#endif
4 changes: 2 additions & 2 deletions src/fe-gtk/maingui.c
Expand Up @@ -1715,7 +1715,7 @@ mg_add_chan (session *sess)
{
sess->res->buffer = gtk_xtext_buffer_new (GTK_XTEXT (sess->gui->xtext));
gtk_xtext_set_time_stamp (sess->res->buffer, prefs.hex_stamp_text);
sess->res->user_model = userlist_create_model ();
sess->res->user_model = userlist_create_model (sess);
}
}

Expand Down Expand Up @@ -3164,7 +3164,7 @@ mg_create_topwindow (session *sess)
sess->res->buffer = gtk_xtext_buffer_new (GTK_XTEXT (sess->gui->xtext));
gtk_xtext_buffer_show (GTK_XTEXT (sess->gui->xtext), sess->res->buffer, TRUE);
gtk_xtext_set_time_stamp (sess->res->buffer, prefs.hex_stamp_text);
sess->res->user_model = userlist_create_model ();
sess->res->user_model = userlist_create_model (sess);
}

userlist_show (sess);
Expand Down
2 changes: 2 additions & 0 deletions src/fe-gtk/setup.c
Expand Up @@ -2114,6 +2114,8 @@ setup_apply (struct hexchatprefs *pr)
noapply = TRUE;
if (DIFF (hex_gui_ulist_style))
noapply = TRUE;
if (DIFF (hex_gui_ulist_sort))
noapply = TRUE;

if (DIFF (hex_gui_tab_dots))
do_layout = TRUE;
Expand Down
74 changes: 62 additions & 12 deletions src/fe-gtk/userlistgui.c
Expand Up @@ -332,9 +332,9 @@ fe_userlist_rehash (session *sess, struct User *user)
}

void
fe_userlist_insert (session *sess, struct User *newuser, int row, int sel)
fe_userlist_insert (session *sess, struct User *newuser, gboolean sel)
{
GtkTreeModel *model = sess->res->user_model;
GtkTreeModel *model = GTK_TREE_MODEL(sess->res->user_model);
GdkPixbuf *pix = get_user_icon (sess->server, newuser);
GtkTreeIter iter;
char *nick;
Expand All @@ -357,7 +357,7 @@ fe_userlist_insert (session *sess, struct User *newuser, int row, int sel)
pix = NULL;
}

gtk_list_store_insert_with_values (GTK_LIST_STORE (model), &iter, row,
gtk_list_store_insert_with_values (GTK_LIST_STORE (model), &iter, 0,
COL_PIX, pix,
COL_NICK, nick,
COL_HOST, newuser->hostname,
Expand Down Expand Up @@ -395,12 +395,6 @@ fe_userlist_insert (session *sess, struct User *newuser, int row, int sel)
}
}

void
fe_userlist_move (session *sess, struct User *user, int new_row)
{
fe_userlist_insert (sess, user, new_row, fe_userlist_remove (sess, user));
}

void
fe_userlist_clear (session *sess)
{
Expand Down Expand Up @@ -459,11 +453,67 @@ userlist_dnd_leave (GtkTreeView *widget, GdkDragContext *context, guint ttime)
return TRUE;
}

void *
userlist_create_model (void)
static int
userlist_alpha_cmp (GtkTreeModel *model, GtkTreeIter *iter_a, GtkTreeIter *iter_b, gpointer userdata)
{
struct User *user_a, *user_b;

gtk_tree_model_get (model, iter_a, COL_USER, &user_a, -1);
gtk_tree_model_get (model, iter_b, COL_USER, &user_b, -1);

return nick_cmp_alpha (user_a, user_b, ((session*)userdata)->server);
}

static int
userlist_ops_cmp (GtkTreeModel *model, GtkTreeIter *iter_a, GtkTreeIter *iter_b, gpointer userdata)
{
struct User *user_a, *user_b;

gtk_tree_model_get (model, iter_a, COL_USER, &user_a, -1);
gtk_tree_model_get (model, iter_b, COL_USER, &user_b, -1);

return nick_cmp_az_ops (((session*)userdata)->server, user_a, user_b);
}

GtkListStore *
userlist_create_model (session *sess)
{
return gtk_list_store_new (5, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_STRING,
GtkListStore *store;
GtkTreeIterCompareFunc cmp_func;
GtkSortType sort_type;

store = gtk_list_store_new (5, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_STRING,
G_TYPE_POINTER, GDK_TYPE_COLOR);

switch (prefs.hex_gui_ulist_sort)
{
case 0:
cmp_func = userlist_ops_cmp;
sort_type = GTK_SORT_ASCENDING;
break;
case 1:
cmp_func = userlist_alpha_cmp;
sort_type = GTK_SORT_ASCENDING;
break;
case 2:
cmp_func = userlist_ops_cmp;
sort_type = GTK_SORT_DESCENDING;
break;
case 3:
cmp_func = userlist_alpha_cmp;
sort_type = GTK_SORT_DESCENDING;
break;
default:
/* No sorting */
gtk_tree_sortable_set_default_sort_func (GTK_TREE_SORTABLE(store), NULL, NULL, NULL);
return store;
}

gtk_tree_sortable_set_default_sort_func (GTK_TREE_SORTABLE(store), cmp_func, sess, NULL);
gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE(store),
GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID, sort_type);

return store;
}

static void
Expand Down
2 changes: 1 addition & 1 deletion src/fe-gtk/userlistgui.h
Expand Up @@ -23,7 +23,7 @@
void userlist_set_value (GtkWidget *treeview, gfloat val);
gfloat userlist_get_value (GtkWidget *treeview);
GtkWidget *userlist_create (GtkWidget *box);
void *userlist_create_model (void);
void *userlist_create_model (session *sess);
void userlist_show (session *sess);
void userlist_select (session *sess, char *name);
char **userlist_selection_list (GtkWidget *widget, int *num_ret);
Expand Down
6 changes: 1 addition & 5 deletions src/fe-text/fe-text.c
Expand Up @@ -678,7 +678,7 @@ fe_progressbar_end (struct server *serv)
{
}
void
fe_userlist_insert (struct session *sess, struct User *newuser, int row, int sel)
fe_userlist_insert (struct session *sess, struct User *newuser, gboolean sel)
{
}
int
Expand All @@ -691,10 +691,6 @@ fe_userlist_rehash (struct session *sess, struct User *user)
{
}
void
fe_userlist_move (struct session *sess, struct User *user, int new_row)
{
}
void
fe_userlist_numbers (struct session *sess)
{
}
Expand Down

0 comments on commit 9f7444b

Please sign in to comment.