#include <glade/glade.h>
#include <libmissioncontrol/mc-account.h>
+#include <libmissioncontrol/mission-control.h>
+#include <libempathy/empathy-contact-list.h>
#include <libempathy/empathy-contact-manager.h>
#include <libempathy/gossip-debug.h>
-#include <libempathy/empathy-session.h>
+#include <libempathy/gossip-utils.h>
+#include "empathy-images.h"
#include "gossip-contact-list.h"
#include "gossip-contact-groups.h"
#include "gossip-cell-renderer-expander.h"
#include "gossip-cell-renderer-text.h"
-#include "gossip-stock.h"
#include "gossip-ui-utils.h"
//#include "gossip-chat-invite.h"
//#include "gossip-contact-info-dialog.h"
#define GET_PRIV(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GOSSIP_TYPE_CONTACT_LIST, GossipContactListPriv))
struct _GossipContactListPriv {
- EmpathyContactManager *manager;
+ EmpathyContactList *list;
GHashTable *groups;
GtkUIManager *ui;
GtkTreeRowReference *drag_row;
+ GtkTreeStore *store;
+ GtkTreeModel *filter;
+ gchar *filter_text;
+
gboolean show_offline;
gboolean show_avatars;
gboolean is_compact;
gboolean show_active;
+
+ GossipContactListSort sort_criterium;
};
typedef struct {
+ GtkTreeIter iter;
const gchar *name;
gboolean found;
- GtkTreeIter iter;
} FindGroup;
typedef struct {
guint param_id,
const GValue *value,
GParamSpec *pspec);
+static gboolean contact_list_row_separator_func (GtkTreeModel *model,
+ GtkTreeIter *iter,
+ gpointer data);
static void contact_list_contact_update (GossipContactList *list,
GossipContact *contact);
-static void contact_list_contact_added_cb (EmpathyContactManager *manager,
+static void contact_list_contact_added_cb (EmpathyContactList *list_iface,
GossipContact *contact,
GossipContactList *list);
static void contact_list_contact_updated_cb (GossipContact *contact,
static void contact_list_contact_groups_updated_cb (GossipContact *contact,
GParamSpec *param,
GossipContactList *list);
-static void contact_list_contact_removed_cb (EmpathyContactManager *manager,
+static void contact_list_contact_removed_cb (EmpathyContactList *list_iface,
GossipContact *contact,
GossipContactList *list);
static void contact_list_contact_set_active (GossipContactList *list,
gboolean *path_is_group);
static void contact_list_get_group (GossipContactList *list,
const gchar *name,
- GtkTreeIter *iter_to_set,
+ GtkTreeIter *iter_group_to_set,
+ GtkTreeIter *iter_separator_to_set,
gboolean *created);
static gboolean contact_list_get_group_foreach (GtkTreeModel *model,
GtkTreePath *path,
GtkTreeIter *iter,
GtkTreePath *path,
gpointer user_data);
-static gint contact_list_sort_func (GtkTreeModel *model,
+static gint contact_list_name_sort_func (GtkTreeModel *model,
GtkTreeIter *iter_a,
GtkTreeIter *iter_b,
gpointer user_data);
+static gint contact_list_state_sort_func (GtkTreeModel *model,
+ GtkTreeIter *iter_a,
+ GtkTreeIter *iter_b,
+ gpointer user_data);
+static gboolean contact_list_filter_func (GtkTreeModel *model,
+ GtkTreeIter *iter,
+ GossipContactList *list);
static GList * contact_list_find_contact (GossipContactList *list,
GossipContact *contact);
static gboolean contact_list_find_contact_foreach (GtkTreeModel *model,
FindContact *fc);
static void contact_list_action_cb (GtkAction *action,
GossipContactList *list);
+static void contact_list_action_activated (GossipContactList *list,
+ GossipContact *contact);
static gboolean contact_list_update_list_mode_foreach (GtkTreeModel *model,
GtkTreePath *path,
GtkTreeIter *iter,
GossipContactList *list);
-enum {
- CONTACT_CHAT,
- CONTACT_INFORMATION,
- CONTACT_EDIT,
- CONTACT_REMOVE,
- CONTACT_INVITE,
- CONTACT_SEND_FILE,
- CONTACT_LOG,
- GROUP_RENAME,
- LAST_SIGNAL
-};
-
-static guint signals[LAST_SIGNAL];
enum {
- COL_PIXBUF_STATUS,
+ COL_ICON_STATUS,
COL_PIXBUF_AVATAR,
COL_PIXBUF_AVATAR_VISIBLE,
COL_NAME,
COL_IS_GROUP,
COL_IS_ACTIVE,
COL_IS_ONLINE,
+ COL_IS_SEPARATOR,
COL_COUNT
};
PROP_SHOW_OFFLINE,
PROP_SHOW_AVATARS,
PROP_IS_COMPACT,
+ PROP_FILTER,
+ PROP_SORT_CRITERIUM
};
static const GtkActionEntry entries[] = {
N_("_Group"),NULL, NULL,
NULL
},
- { "Chat", GOSSIP_STOCK_MESSAGE,
+ { "Chat", EMPATHY_IMAGE_MESSAGE,
N_("_Chat"), NULL, N_("Chat with contact"),
G_CALLBACK (contact_list_action_cb)
},
- { "Information", GOSSIP_STOCK_CONTACT_INFORMATION,
+ { "Information", EMPATHY_IMAGE_CONTACT_INFORMATION,
N_("Infor_mation"), "<control>I", N_("View contact information"),
G_CALLBACK (contact_list_action_cb)
},
N_("_Remove"), NULL, N_("Remove contact"),
G_CALLBACK (contact_list_action_cb)
},
- { "Invite", GOSSIP_STOCK_GROUP_MESSAGE,
+ { "Invite", EMPATHY_IMAGE_GROUP_MESSAGE,
N_("_Invite to Chat Room"), NULL, N_("Invite to a currently open chat room"),
G_CALLBACK (contact_list_action_cb)
},
static GdkAtom drag_atoms_dest[G_N_ELEMENTS (drag_types_dest)];
static GdkAtom drag_atoms_source[G_N_ELEMENTS (drag_types_source)];
+GType
+gossip_contact_list_sort_get_type (void)
+{
+ static GType etype = 0;
+
+ if (etype == 0) {
+ static const GEnumValue values[] = {
+ { GOSSIP_CONTACT_LIST_SORT_NAME,
+ "GOSSIP_CONTACT_LIST_SORT_NAME",
+ "name" },
+ { GOSSIP_CONTACT_LIST_SORT_STATE,
+ "GOSSIP_CONTACT_LIST_SORT_STATE",
+ "state" },
+ { 0, NULL, NULL }
+ };
+
+ etype = g_enum_register_static ("GossipContactListSort", values);
+ }
+
+ return etype;
+}
+
G_DEFINE_TYPE (GossipContactList, gossip_contact_list, GTK_TYPE_TREE_VIEW);
static void
object_class->get_property = contact_list_get_property;
object_class->set_property = contact_list_set_property;
- signals[CONTACT_CHAT] =
- g_signal_new ("contact-chat",
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_LAST,
- 0,
- NULL, NULL,
- g_cclosure_marshal_VOID__OBJECT,
- G_TYPE_NONE,
- 1, GOSSIP_TYPE_CONTACT);
- signals[CONTACT_INFORMATION] =
- g_signal_new ("contact-information",
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_LAST,
- 0,
- NULL, NULL,
- g_cclosure_marshal_VOID__OBJECT,
- G_TYPE_NONE,
- 1, GOSSIP_TYPE_CONTACT);
- signals[CONTACT_EDIT] =
- g_signal_new ("contact-edit",
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_LAST,
- 0,
- NULL, NULL,
- g_cclosure_marshal_VOID__OBJECT,
- G_TYPE_NONE,
- 1, GOSSIP_TYPE_CONTACT);
- signals[CONTACT_REMOVE] =
- g_signal_new ("contact-remove",
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_LAST,
- 0,
- NULL, NULL,
- g_cclosure_marshal_VOID__OBJECT,
- G_TYPE_NONE,
- 1, GOSSIP_TYPE_CONTACT);
- signals[CONTACT_INVITE] =
- g_signal_new ("contact-invite",
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_LAST,
- 0,
- NULL, NULL,
- g_cclosure_marshal_VOID__OBJECT,
- G_TYPE_NONE,
- 1, GOSSIP_TYPE_CONTACT);
- signals[CONTACT_SEND_FILE] =
- g_signal_new ("contact-send-file",
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_LAST,
- 0,
- NULL, NULL,
- g_cclosure_marshal_VOID__OBJECT,
- G_TYPE_NONE,
- 1, GOSSIP_TYPE_CONTACT);
- signals[CONTACT_LOG] =
- g_signal_new ("contact-log",
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_LAST,
- 0,
- NULL, NULL,
- g_cclosure_marshal_VOID__OBJECT,
- G_TYPE_NONE,
- 1, GOSSIP_TYPE_CONTACT);
- signals[GROUP_RENAME] =
- g_signal_new ("group-rename",
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_LAST,
- 0,
- NULL, NULL,
- g_cclosure_marshal_VOID__STRING,
- G_TYPE_NONE,
- 1, G_TYPE_STRING);
-
-
g_object_class_install_property (object_class,
PROP_SHOW_OFFLINE,
g_param_spec_boolean ("show-offline",
FALSE,
G_PARAM_READWRITE));
+ g_object_class_install_property (object_class,
+ PROP_FILTER,
+ g_param_spec_string ("filter",
+ "Filter",
+ "The text to use to filter the contact list",
+ NULL,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (object_class,
+ PROP_SORT_CRITERIUM,
+ g_param_spec_enum ("sort-criterium",
+ "Sort citerium",
+ "The sort criterium to use for sorting the contact list",
+ GOSSIP_TYPE_CONTACT_LIST_SORT,
+ GOSSIP_CONTACT_LIST_SORT_NAME,
+ G_PARAM_READWRITE));
+
g_type_class_add_private (object_class, sizeof (GossipContactListPriv));
}
priv = GET_PRIV (list);
- priv->manager = empathy_session_get_contact_manager ();
- g_object_ref (priv->manager);
+ priv->list = EMPATHY_CONTACT_LIST (empathy_contact_manager_new ());
priv->is_compact = FALSE;
priv->show_active = TRUE;
priv->show_avatars = TRUE;
contact_list_create_model (list);
contact_list_setup_view (list);
- empathy_contact_manager_setup (priv->manager);
+ empathy_contact_list_setup (priv->list);
/* Get saved group states. */
gossip_contact_groups_get_all ();
g_object_unref (action_group);
+ gtk_tree_view_set_row_separator_func (GTK_TREE_VIEW (list),
+ contact_list_row_separator_func,
+ NULL, NULL);
+
/* Signal connection. */
- g_signal_connect (priv->manager,
+ g_signal_connect (priv->list,
"contact-added",
G_CALLBACK (contact_list_contact_added_cb),
list);
- g_signal_connect (priv->manager,
+ g_signal_connect (priv->list,
"contact-removed",
G_CALLBACK (contact_list_contact_removed_cb),
list);
GINT_TO_POINTER (FALSE));
/* Add contacts already created */
- contacts = empathy_contact_manager_get_contacts (priv->manager);
+ contacts = empathy_contact_list_get_contacts (priv->list);
for (l = contacts; l; l = l->next) {
GossipContact *contact;
contact = l->data;
- contact_list_contact_added_cb (priv->manager, contact, list);
+ contact_list_contact_added_cb (priv->list, contact, list);
g_object_unref (contact);
}
+ g_list_free (contacts);
}
static void
priv = GET_PRIV (object);
- /* FIXME: disconnect all signals on the manager and contacts */
+ /* FIXME: disconnect all signals on the list and contacts */
- g_object_unref (priv->manager);
+ g_object_unref (priv->list);
g_object_unref (priv->ui);
+ g_object_unref (priv->store);
+ g_object_unref (priv->filter);
+ g_free (priv->filter_text);
G_OBJECT_CLASS (gossip_contact_list_parent_class)->finalize (object);
}
case PROP_IS_COMPACT:
g_value_set_boolean (value, priv->is_compact);
break;
+ case PROP_FILTER:
+ g_value_set_string (value, priv->filter_text);
+ break;
+ case PROP_SORT_CRITERIUM:
+ g_value_set_enum (value, priv->sort_criterium);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
break;
gossip_contact_list_set_is_compact (GOSSIP_CONTACT_LIST (object),
g_value_get_boolean (value));
break;
+ case PROP_FILTER:
+ gossip_contact_list_set_filter (GOSSIP_CONTACT_LIST (object),
+ g_value_get_string (value));
+ break;
+ case PROP_SORT_CRITERIUM:
+ gossip_contact_list_set_sort_criterium (GOSSIP_CONTACT_LIST (object),
+ g_value_get_enum (value));
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
break;
};
}
+static gboolean
+contact_list_row_separator_func (GtkTreeModel *model,
+ GtkTreeIter *iter,
+ gpointer data)
+{
+ gboolean is_separator = FALSE;
+
+ gtk_tree_model_get (model, iter,
+ COL_IS_SEPARATOR, &is_separator,
+ -1);
+
+ return is_separator;
+}
+
static void
contact_list_contact_update (GossipContactList *list,
GossipContact *contact)
gboolean do_remove = FALSE;
gboolean do_set_active = FALSE;
gboolean do_set_refresh = FALSE;
- GdkPixbuf *pixbuf_presence;
GdkPixbuf *pixbuf_avatar;
priv = GET_PRIV (list);
- model = gtk_tree_view_get_model (GTK_TREE_VIEW (list));
+ model = GTK_TREE_MODEL (priv->store);
iters = contact_list_find_contact (list, contact);
if (!iters) {
/* Get online state before. */
if (iters && g_list_length (iters) > 0) {
- GtkTreeIter *iter;
-
- iter = g_list_nth_data (iters, 0);
- gtk_tree_model_get (model, iter, COL_IS_ONLINE, &was_online, -1);
+ gtk_tree_model_get (model, iters->data, COL_IS_ONLINE, &was_online, -1);
}
/* Is this really an update or an online/offline. */
set_model = TRUE;
}
- pixbuf_presence = gossip_pixbuf_for_contact (contact);
pixbuf_avatar = gossip_pixbuf_avatar_from_contact_scaled (contact, 32, 32);
for (l = iters; l && set_model; l = l->next) {
- gtk_tree_store_set (GTK_TREE_STORE (model), l->data,
- COL_PIXBUF_STATUS, pixbuf_presence,
+ gtk_tree_store_set (priv->store, l->data,
+ COL_ICON_STATUS, gossip_icon_name_for_contact (contact),
COL_STATUS, gossip_contact_get_status (contact),
COL_IS_ONLINE, now_online,
COL_NAME, gossip_contact_get_name (contact),
-1);
}
- if (pixbuf_presence) {
- g_object_unref (pixbuf_presence);
- }
if (pixbuf_avatar) {
g_object_unref (pixbuf_avatar);
}
}
static void
-contact_list_contact_added_cb (EmpathyContactManager *manager,
- GossipContact *contact,
- GossipContactList *list)
+contact_list_contact_added_cb (EmpathyContactList *list_iface,
+ GossipContact *contact,
+ GossipContactList *list)
{
GossipContactListPriv *priv;
priv = GET_PRIV (list);
- gossip_debug (DEBUG_DOMAIN, "Contact:'%s' added",
+ gossip_debug (DEBUG_DOMAIN,
+ "Contact:'%s' added",
gossip_contact_get_name (contact));
- /* Connect notifications for contact updates */
g_signal_connect (contact, "notify::groups",
G_CALLBACK (contact_list_contact_groups_updated_cb),
list);
GParamSpec *param,
GossipContactList *list)
{
+ gossip_debug (DEBUG_DOMAIN,
+ "Contact:'%s' updated, checking roster is in sync...",
+ gossip_contact_get_name (contact));
+
contact_list_contact_update (list, contact);
}
static void
-contact_list_contact_removed_cb (EmpathyContactManager *manager,
- GossipContact *contact,
- GossipContactList *list)
+contact_list_contact_removed_cb (EmpathyContactList *list_iface,
+ GossipContact *contact,
+ GossipContactList *list)
{
gossip_debug (DEBUG_DOMAIN, "Contact:'%s' removed",
gossip_contact_get_name (contact));
gboolean active,
gboolean set_changed)
{
- GtkTreeModel *model;
- GList *iters, *l;
+ GossipContactListPriv *priv;
+ GtkTreeModel *model;
+ GList *iters, *l;
- model = gtk_tree_view_get_model (GTK_TREE_VIEW (list));
+ priv = GET_PRIV (list);
+
+ model = GTK_TREE_MODEL (priv->store);
iters = contact_list_find_contact (list, contact);
for (l = iters; l; l = l->next) {
GtkTreePath *path;
- GtkTreeIter *iter;
-
- iter = l->data;
- gtk_tree_store_set (GTK_TREE_STORE (model), iter,
+ gtk_tree_store_set (priv->store, l->data,
COL_IS_ACTIVE, active,
-1);
+
gossip_debug (DEBUG_DOMAIN, "Set item %s", active ? "active" : "inactive");
if (set_changed) {
- path = gtk_tree_model_get_path (model, iter);
- gtk_tree_model_row_changed (model, path, iter);
+ path = gtk_tree_model_get_path (model, l->data);
+ gtk_tree_model_row_changed (model, path, l->data);
gtk_tree_path_free (path);
}
}
g_list_foreach (iters, (GFunc)gtk_tree_iter_free, NULL);
g_list_free (iters);
+
}
static ShowActiveData *
return name;
}
+static gboolean
+contact_list_get_group_foreach (GtkTreeModel *model,
+ GtkTreePath *path,
+ GtkTreeIter *iter,
+ FindGroup *fg)
+{
+ gchar *str;
+ gboolean is_group;
+
+ /* Groups are only at the top level. */
+ if (gtk_tree_path_get_depth (path) != 1) {
+ return FALSE;
+ }
+
+ gtk_tree_model_get (model, iter,
+ COL_NAME, &str,
+ COL_IS_GROUP, &is_group,
+ -1);
+
+ if (is_group && strcmp (str, fg->name) == 0) {
+ fg->found = TRUE;
+ fg->iter = *iter;
+ }
+
+ g_free (str);
+
+ return fg->found;
+}
+
static void
contact_list_get_group (GossipContactList *list,
const gchar *name,
- GtkTreeIter *iter_to_set,
+ GtkTreeIter *iter_group_to_set,
+ GtkTreeIter *iter_separator_to_set,
gboolean *created)
{
- GtkTreeModel *model;
- FindGroup fg;
+ GossipContactListPriv *priv;
+ GtkTreeModel *model;
+ GtkTreeIter iter_group, iter_separator;
+ FindGroup fg;
+
+ priv = GET_PRIV (list);
memset (&fg, 0, sizeof (fg));
fg.name = name;
- model = gtk_tree_view_get_model (GTK_TREE_VIEW (list));
+ model = GTK_TREE_MODEL (priv->store);
gtk_tree_model_foreach (model,
(GtkTreeModelForeachFunc) contact_list_get_group_foreach,
&fg);
*created = TRUE;
}
- gtk_tree_store_append (GTK_TREE_STORE (model), iter_to_set, NULL);
- gtk_tree_store_set (GTK_TREE_STORE (model), iter_to_set,
- COL_PIXBUF_STATUS, NULL,
+ gtk_tree_store_append (priv->store, &iter_group, NULL);
+ gtk_tree_store_set (priv->store, &iter_group,
+ COL_ICON_STATUS, NULL,
COL_NAME, name,
COL_IS_GROUP, TRUE,
COL_IS_ACTIVE, FALSE,
+ COL_IS_SEPARATOR, FALSE,
+ -1);
+
+ if (iter_group_to_set) {
+ *iter_group_to_set = iter_group;
+ }
+
+ gtk_tree_store_append (priv->store,
+ &iter_separator,
+ &iter_group);
+ gtk_tree_store_set (priv->store, &iter_separator,
+ COL_IS_SEPARATOR, TRUE,
-1);
+
+ if (iter_separator_to_set) {
+ *iter_separator_to_set = iter_separator;
+ }
} else {
if (created) {
*created = FALSE;
}
- *iter_to_set = fg.iter;
- }
-}
-
-static gboolean
-contact_list_get_group_foreach (GtkTreeModel *model,
- GtkTreePath *path,
- GtkTreeIter *iter,
- FindGroup *fg)
-{
- gchar *str;
- gboolean is_group;
+ if (iter_group_to_set) {
+ *iter_group_to_set = fg.iter;
+ }
- /* Groups are only at the top level. */
- if (gtk_tree_path_get_depth (path) != 1) {
- return FALSE;
- }
+ iter_separator = fg.iter;
- gtk_tree_model_get (model, iter,
- COL_NAME, &str,
- COL_IS_GROUP, &is_group,
- -1);
- if (is_group && strcmp (str, fg->name) == 0) {
- fg->found = TRUE;
- fg->iter = *iter;
- }
+ if (gtk_tree_model_iter_next (model, &iter_separator)) {
+ gboolean is_separator;
- g_free (str);
+ gtk_tree_model_get (model, &iter_separator,
+ COL_IS_SEPARATOR, &is_separator,
+ -1);
- return fg->found;
+ if (is_separator && iter_separator_to_set) {
+ *iter_separator_to_set = iter_separator;
+ }
+ }
+ }
}
static void
GossipContact *contact)
{
GossipContactListPriv *priv;
- GtkTreeIter iter, iter_group;
+ GtkTreeIter iter, iter_group, iter_separator;
GtkTreeModel *model;
GList *l, *groups;
/* If no groups just add it at the top level. */
groups = gossip_contact_get_groups (contact);
if (!groups) {
- GdkPixbuf *pixbuf_status;
GdkPixbuf *pixbuf_avatar;
gboolean show_avatar = FALSE;
- pixbuf_status = gossip_pixbuf_for_contact (contact);
- pixbuf_avatar = gossip_pixbuf_avatar_from_contact_scaled (
- contact, 32, 32);
+ pixbuf_avatar = gossip_pixbuf_avatar_from_contact_scaled (contact, 32, 32);
if (priv->show_avatars && !priv->is_compact) {
show_avatar = TRUE;
}
- gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
- gtk_tree_store_set (GTK_TREE_STORE (model), &iter,
- COL_PIXBUF_STATUS, pixbuf_status,
+ gossip_debug (DEBUG_DOMAIN, "");
+ gossip_debug (DEBUG_DOMAIN,
+ "vvvvvvvvvvvvvvvv FIXME: Errors may follow below (since filter work) vvvvvvvvvvvvvvvv");
+
+ gossip_debug (DEBUG_DOMAIN,
+ "**** GossipContact:%p, is GObject:%s, is GossipContact:%s, ADDING CONTACT #1",
+ contact,
+ G_IS_OBJECT (contact) ? "yes" : "no",
+ GOSSIP_IS_CONTACT (contact) ? "yes" : "no");
+
+ gtk_tree_store_append (priv->store, &iter, NULL);
+ gtk_tree_store_set (priv->store, &iter,
+ COL_ICON_STATUS, gossip_icon_name_for_contact (contact),
COL_PIXBUF_AVATAR, pixbuf_avatar,
COL_PIXBUF_AVATAR_VISIBLE, show_avatar,
COL_NAME, gossip_contact_get_name (contact),
COL_IS_GROUP, FALSE,
COL_IS_ACTIVE, FALSE,
COL_IS_ONLINE, gossip_contact_is_online (contact),
+ COL_IS_SEPARATOR, FALSE,
-1);
+ gossip_debug (DEBUG_DOMAIN,
+ "^^^^^^^^^^^^^^^^ FIXME: Errors may occur above (since filter work) ^^^^^^^^^^^^^^^^");
+ gossip_debug (DEBUG_DOMAIN, "");
+
if (pixbuf_avatar) {
g_object_unref (pixbuf_avatar);
}
- if (pixbuf_status) {
- g_object_unref (pixbuf_status);
- }
}
/* Else add to each group. */
for (l = groups; l; l = l->next) {
GtkTreePath *path;
- GdkPixbuf *pixbuf_status;
+ GtkTreeIter model_iter_group;
GdkPixbuf *pixbuf_avatar;
const gchar *name;
gboolean created;
+ gboolean found;
gboolean show_avatar = FALSE;
name = l->data;
continue;
}
- pixbuf_status = gossip_pixbuf_for_contact (contact);
- pixbuf_avatar = gossip_pixbuf_avatar_from_contact_scaled (
- contact, 32, 32);
+ pixbuf_avatar = gossip_pixbuf_avatar_from_contact_scaled (contact, 32, 32);
- contact_list_get_group (list, name, &iter_group, &created);
+ contact_list_get_group (list, name, &iter_group, &iter_separator, &created);
if (priv->show_avatars && !priv->is_compact) {
show_avatar = TRUE;
}
- gtk_tree_store_append (GTK_TREE_STORE (model), &iter, &iter_group);
- gtk_tree_store_set (GTK_TREE_STORE (model), &iter,
- COL_PIXBUF_STATUS, pixbuf_status,
+ gossip_debug (DEBUG_DOMAIN, "");
+ gossip_debug (DEBUG_DOMAIN,
+ "vvvvvvvvvvvvvvvv FIXME: Errors may follow below (since filter work) vvvvvvvvvvvvvvvv");
+
+ gossip_debug (DEBUG_DOMAIN,
+ "**** GossipContact:%p, is GObject:%s, is GossipContact:%s, ADDING CONTACT #2",
+ contact,
+ G_IS_OBJECT (contact) ? "yes" : "no",
+ GOSSIP_IS_CONTACT (contact) ? "yes" : "no");
+
+ gtk_tree_store_insert_after (priv->store, &iter, &iter_group, NULL);
+ gtk_tree_store_set (priv->store, &iter,
+ COL_ICON_STATUS, gossip_icon_name_for_contact (contact),
COL_PIXBUF_AVATAR, pixbuf_avatar,
COL_PIXBUF_AVATAR_VISIBLE, show_avatar,
COL_NAME, gossip_contact_get_name (contact),
COL_IS_GROUP, FALSE,
COL_IS_ACTIVE, FALSE,
COL_IS_ONLINE, gossip_contact_is_online (contact),
+ COL_IS_SEPARATOR, FALSE,
-1);
+ gossip_debug (DEBUG_DOMAIN,
+ "^^^^^^^^^^^^^^^^ FIXME: Errors may occur above (since filter work) ^^^^^^^^^^^^^^^^");
+ gossip_debug (DEBUG_DOMAIN, "");
+
if (pixbuf_avatar) {
g_object_unref (pixbuf_avatar);
}
- if (pixbuf_status) {
- g_object_unref (pixbuf_status);
- }
if (!created) {
continue;
}
- path = gtk_tree_model_get_path (model, &iter_group);
+ found = gtk_tree_model_filter_convert_child_iter_to_iter (GTK_TREE_MODEL_FILTER (priv->filter),
+ &model_iter_group,
+ &iter_group);
+ if (!found) {
+ continue;
+ }
+
+ path = gtk_tree_model_get_path (model, &model_iter_group);
if (!path) {
continue;
}
}
/* Clean up model */
- model = gtk_tree_view_get_model (GTK_TREE_VIEW (list));
+ model = GTK_TREE_MODEL (priv->store);
for (l = iters; l; l = l->next) {
GtkTreeIter parent;
+ /* NOTE: it is only <= 2 here because we have
+ * separators after the group name, otherwise it
+ * should be 1.
+ */
if (gtk_tree_model_iter_parent (model, &parent, l->data) &&
- gtk_tree_model_iter_n_children (model, &parent) <= 1) {
- gtk_tree_store_remove (GTK_TREE_STORE (model), &parent);
+ gtk_tree_model_iter_n_children (model, &parent) <= 2) {
+ gtk_tree_store_remove (priv->store, &parent);
} else {
- gtk_tree_store_remove (GTK_TREE_STORE (model), l->data);
+ gtk_tree_store_remove (priv->store, l->data);
}
}
- g_list_foreach (iters, (GFunc)gtk_tree_iter_free, NULL);
+ g_list_foreach (iters, (GFunc) gtk_tree_iter_free, NULL);
g_list_free (iters);
}
static void
contact_list_create_model (GossipContactList *list)
{
- GtkTreeModel *model;
+ GossipContactListPriv *priv;
+ GtkTreeModel *model;
+
+ priv = GET_PRIV (list);
+
+ if (priv->store) {
+ g_object_unref (priv->store);
+ }
+
+ if (priv->filter) {
+ g_object_unref (priv->filter);
+ }
- model = GTK_TREE_MODEL (
- gtk_tree_store_new (COL_COUNT,
- GDK_TYPE_PIXBUF, /* Status pixbuf */
- GDK_TYPE_PIXBUF, /* Avatar pixbuf */
- G_TYPE_BOOLEAN, /* Avatar pixbuf visible */
- G_TYPE_STRING, /* Name */
- G_TYPE_STRING, /* Status string */
- G_TYPE_BOOLEAN, /* Show status */
- GOSSIP_TYPE_CONTACT, /* Contact type */
- G_TYPE_BOOLEAN, /* Is group */
- G_TYPE_BOOLEAN, /* Is active */
- G_TYPE_BOOLEAN)); /* Is online */
+ priv->store = gtk_tree_store_new (COL_COUNT,
+ G_TYPE_STRING, /* Status icon-name */
+ GDK_TYPE_PIXBUF, /* Avatar pixbuf */
+ G_TYPE_BOOLEAN, /* Avatar pixbuf visible */
+ G_TYPE_STRING, /* Name */
+ G_TYPE_STRING, /* Status string */
+ G_TYPE_BOOLEAN, /* Show status */
+ GOSSIP_TYPE_CONTACT, /* Contact type */
+ G_TYPE_BOOLEAN, /* Is group */
+ G_TYPE_BOOLEAN, /* Is active */
+ G_TYPE_BOOLEAN, /* Is online */
+ G_TYPE_BOOLEAN); /* Is separator */
+ /* Save normal model */
+ model = GTK_TREE_MODEL (priv->store);
+
+ /* Set up sorting */
gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (model),
COL_NAME,
- contact_list_sort_func,
+ contact_list_name_sort_func,
+ list, NULL);
+ gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (model),
+ COL_STATUS,
+ contact_list_state_sort_func,
list, NULL);
- gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (model),
- COL_NAME,
- GTK_SORT_ASCENDING);
+ gossip_contact_list_set_sort_criterium (list, priv->sort_criterium);
+
+ /* Create filter */
+ priv->filter = gtk_tree_model_filter_new (model, NULL);
- gtk_tree_view_set_model (GTK_TREE_VIEW (list), model);
+ gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (priv->filter),
+ (GtkTreeModelFilterVisibleFunc)
+ contact_list_filter_func,
+ list, NULL);
- g_object_unref (model);
+ gtk_tree_view_set_model (GTK_TREE_VIEW (list), priv->filter);
}
static gboolean
gchar *key_folded;
gboolean ret;
- gtk_tree_model_get (model, iter,
- COL_NAME, &name,
- -1);
+ if (!key) {
+ return FALSE;
+ }
+
+ gtk_tree_model_get (model, iter, COL_NAME, &name, -1);
+
+ if (!name) {
+ return FALSE;
+ }
name_folded = g_utf8_casefold (name, -1);
key_folded = g_utf8_casefold (key, -1);
- if (strstr (name_folded, key_folded)) {
+ if (name_folded && key_folded &&
+ strstr (name_folded, key_folded)) {
ret = FALSE;
} else {
ret = TRUE;
id);
/* FIXME: This is ambigous, an id can come from multiple accounts */
- contact = empathy_contact_manager_find (priv->manager, id);
+ contact = empathy_contact_list_find (priv->list, id);
if (!contact) {
gossip_debug (DEBUG_DOMAIN, "No contact found associated with drag & drop");
return;
{
GdkColor color;
GtkStyle *style;
- gint color_sum_normal, color_sum_selected;
g_return_if_fail (list != NULL);
g_return_if_fail (cell != NULL);
NULL);
}
} else {
+#if 0
+ gint color_sum_normal;
+ gint color_sum_selected;
+
color = style->base[GTK_STATE_SELECTED];
color_sum_normal = color.red+color.green+color.blue;
color = style->base[GTK_STATE_NORMAL];
color_sum_selected = color.red+color.green+color.blue;
color = style->text_aa[GTK_STATE_INSENSITIVE];
- if(color_sum_normal < color_sum_selected) {
- /* found a light theme */
+ if (color_sum_normal < color_sum_selected) {
+ /* Found a light theme */
color.red = (color.red + (style->white).red) / 2;
color.green = (color.green + (style->white).green) / 2;
color.blue = (color.blue + (style->white).blue) / 2;
} else {
- /* found a dark theme */
+ /* Found a dark theme */
color.red = (color.red + (style->black).red) / 2;
color.green = (color.green + (style->black).green) / 2;
color.blue = (color.blue + (style->black).blue) / 2;
g_object_set (cell,
"cell-background-gdk", &color,
NULL);
+#endif
}
}
GtkTreeIter *iter,
GossipContactList *list)
{
- GdkPixbuf *pixbuf;
- gboolean is_group;
- gboolean is_active;
+ gchar *icon_name;
+ gboolean is_group;
+ gboolean is_active;
gtk_tree_model_get (model, iter,
COL_IS_GROUP, &is_group,
COL_IS_ACTIVE, &is_active,
- COL_PIXBUF_STATUS, &pixbuf,
+ COL_ICON_STATUS, &icon_name,
-1);
g_object_set (cell,
"visible", !is_group,
- "pixbuf", pixbuf,
+ "icon-name", icon_name,
NULL);
- if (pixbuf) {
- g_object_unref (pixbuf);
- }
+ g_free (icon_name);
contact_list_cell_set_background (list, cell, is_group, is_active);
}
priv = GET_PRIV (list);
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (list));
- model = gtk_tree_view_get_model (GTK_TREE_VIEW (list));
+ model = GTK_TREE_MODEL (priv->store);
gtk_widget_grab_focus (GTK_WIDGET (list));
gtk_tree_model_get (model, &iter, COL_CONTACT, &contact, -1);
if (contact) {
- g_signal_emit (list, signals[CONTACT_CHAT], 0, contact);
+ contact_list_action_activated (list, contact);
g_object_unref (contact);
}
}
}
static gint
-contact_list_sort_func (GtkTreeModel *model,
- GtkTreeIter *iter_a,
- GtkTreeIter *iter_b,
- gpointer user_data)
+contact_list_state_sort_func (GtkTreeModel *model,
+ GtkTreeIter *iter_a,
+ GtkTreeIter *iter_b,
+ gpointer user_data)
+{
+ gint ret_val = 0;
+ gchar *name_a, *name_b;
+ gboolean is_separator_a, is_separator_b;
+ GossipContact *contact_a, *contact_b;
+ GossipPresence *presence_a, *presence_b;
+ McPresence state_a, state_b;
+
+ gtk_tree_model_get (model, iter_a,
+ COL_NAME, &name_a,
+ COL_CONTACT, &contact_a,
+ COL_IS_SEPARATOR, &is_separator_a,
+ -1);
+ gtk_tree_model_get (model, iter_b,
+ COL_NAME, &name_b,
+ COL_CONTACT, &contact_b,
+ COL_IS_SEPARATOR, &is_separator_b,
+ -1);
+
+ /* Separator or group? */
+ if (is_separator_a || is_separator_b) {
+ if (is_separator_a) {
+ ret_val = -1;
+ } else if (is_separator_b) {
+ ret_val = 1;
+ }
+ } else if (!contact_a && contact_b) {
+ ret_val = 1;
+ } else if (contact_a && !contact_b) {
+ ret_val = -1;
+ } else if (!contact_a && !contact_b) {
+ /* Handle groups */
+ ret_val = g_utf8_collate (name_a, name_b);
+ }
+
+ if (ret_val) {
+ goto free_and_out;
+ }
+
+ /* If we managed to get this far, we can start looking at
+ * the presences.
+ */
+ presence_a = gossip_contact_get_presence (GOSSIP_CONTACT (contact_a));
+ presence_b = gossip_contact_get_presence (GOSSIP_CONTACT (contact_b));
+
+ if (!presence_a && presence_b) {
+ ret_val = 1;
+ } else if (presence_a && !presence_b) {
+ ret_val = -1;
+ } else if (!presence_a && !presence_b) {
+ /* Both offline, sort by name */
+ ret_val = g_utf8_collate (name_a, name_b);
+ } else {
+ state_a = gossip_presence_get_state (presence_a);
+ state_b = gossip_presence_get_state (presence_b);
+
+ if (state_a < state_b) {
+ ret_val = -1;
+ } else if (state_a > state_b) {
+ ret_val = 1;
+ } else {
+ /* Fallback: compare by name */
+ ret_val = g_utf8_collate (name_a, name_b);
+ }
+ }
+
+free_and_out:
+ g_free (name_a);
+ g_free (name_b);
+
+ if (contact_a) {
+ g_object_unref (contact_a);
+ }
+
+ if (contact_b) {
+ g_object_unref (contact_b);
+ }
+
+ return ret_val;
+}
+
+static gint
+contact_list_name_sort_func (GtkTreeModel *model,
+ GtkTreeIter *iter_a,
+ GtkTreeIter *iter_b,
+ gpointer user_data)
{
gchar *name_a, *name_b;
GossipContact *contact_a, *contact_b;
+ gboolean is_separator_a, is_separator_b;
gint ret_val;
gtk_tree_model_get (model, iter_a,
COL_NAME, &name_a,
COL_CONTACT, &contact_a,
+ COL_IS_SEPARATOR, &is_separator_a,
-1);
gtk_tree_model_get (model, iter_b,
COL_NAME, &name_b,
COL_CONTACT, &contact_b,
+ COL_IS_SEPARATOR, &is_separator_b,
-1);
/* If contact is NULL it means it's a group. */
- if (!contact_a && contact_b) {
+ if (is_separator_a || is_separator_b) {
+ if (is_separator_a) {
+ ret_val = -1;
+ } else if (is_separator_b) {
+ ret_val = 1;
+ }
+ } else if (!contact_a && contact_b) {
ret_val = 1;
} else if (contact_a && !contact_b) {
ret_val = -1;
return ret_val;
}
+static gboolean
+contact_list_filter_show_contact (GossipContact *contact,
+ const gchar *filter)
+{
+ gchar *str;
+ gboolean visible;
+
+ /* Check contact id */
+ str = g_utf8_casefold (gossip_contact_get_id (contact), -1);
+ visible = G_STR_EMPTY (str) || strstr (str, filter);
+ g_free (str);
+
+ if (visible) {
+ return TRUE;
+ }
+
+ /* Check contact name */
+ str = g_utf8_casefold (gossip_contact_get_name (contact), -1);
+ visible = G_STR_EMPTY (str) || strstr (str, filter);
+ g_free (str);
+
+ return visible;
+}
+
+static gboolean
+contact_list_filter_show_group (GossipContactList *list,
+ const gchar *group,
+ const gchar *filter)
+{
+ GossipContactListPriv *priv;
+ GList *contacts, *l;
+ gchar *str;
+ gboolean show_group = FALSE;
+
+ priv = GET_PRIV (list);
+
+ str = g_utf8_casefold (group, -1);
+ if (!str) {
+ return FALSE;
+ }
+
+ /* If the filter is the partially the group name, we show the
+ * whole group.
+ */
+ if (strstr (str, filter)) {
+ g_free (str);
+ return TRUE;
+ }
+
+ /* At this point, we need to check in advance if this
+ * group should be shown because a contact we want to
+ * show exists in it.
+ */
+ contacts = empathy_contact_list_get_contacts (priv->list);
+ for (l = contacts; l && !show_group; l = l->next) {
+ if (!gossip_contact_is_in_group (l->data, group)) {
+ continue;
+ }
+
+ if (contact_list_filter_show_contact (l->data, filter)) {
+ show_group = TRUE;
+ }
+ }
+ g_list_foreach (contacts, (GFunc) g_object_unref, NULL);
+ g_list_free (contacts);
+ g_free (str);
+
+ return show_group;
+}
+
+static gboolean
+contact_list_filter_func (GtkTreeModel *model,
+ GtkTreeIter *iter,
+ GossipContactList *list)
+{
+ GossipContactListPriv *priv;
+ gboolean is_group;
+ gboolean is_separator;
+ gboolean visible = TRUE;
+
+ priv = GET_PRIV (list);
+
+ if (G_STR_EMPTY (priv->filter_text)) {
+ return TRUE;
+ }
+
+ /* Check to see if iter matches any group names */
+ gtk_tree_model_get (model, iter,
+ COL_IS_GROUP, &is_group,
+ COL_IS_SEPARATOR, &is_separator,
+ -1);
+
+ if (is_group) {
+ gchar *name;
+
+ gtk_tree_model_get (model, iter, COL_NAME, &name, -1);
+ visible &= contact_list_filter_show_group (list,
+ name,
+ priv->filter_text);
+ g_free (name);
+ } else if (is_separator) {
+ /* Do nothing here */
+ } else {
+ GossipContact *contact;
+
+ /* Check contact id */
+ gtk_tree_model_get (model, iter, COL_CONTACT, &contact, -1);
+ visible &= contact_list_filter_show_contact (contact,
+ priv->filter_text);
+ g_object_unref (contact);
+ }
+
+ return visible;
+}
+
static gboolean
contact_list_iter_equal_contact (GtkTreeModel *model,
GtkTreeIter *iter,
return equal;
}
+static gboolean
+contact_list_find_contact_foreach (GtkTreeModel *model,
+ GtkTreePath *path,
+ GtkTreeIter *iter,
+ FindContact *fc)
+{
+ if (contact_list_iter_equal_contact (model, iter, fc->contact)) {
+ fc->found = TRUE;
+ fc->iters = g_list_append (fc->iters, gtk_tree_iter_copy (iter));
+ }
+
+ /* We want to find ALL contacts that match, this means if we
+ * have the same contact in 3 groups, all iters should be
+ * returned.
+ */
+ return FALSE;
+}
+
static GList *
contact_list_find_contact (GossipContactList *list,
GossipContact *contact)
{
- GtkTreeModel *model;
- FindContact fc;
- GList *l = NULL;
+ GossipContactListPriv *priv;
+ GtkTreeModel *model;
+ GList *l = NULL;
+ FindContact fc;
+
+ priv = GET_PRIV (list);
memset (&fc, 0, sizeof (fc));
fc.contact = contact;
- model = gtk_tree_view_get_model (GTK_TREE_VIEW (list));
+ model = GTK_TREE_MODEL (priv->store);
gtk_tree_model_foreach (model,
(GtkTreeModelForeachFunc) contact_list_find_contact_foreach,
&fc);
return l;
}
-static gboolean
-contact_list_find_contact_foreach (GtkTreeModel *model,
- GtkTreePath *path,
- GtkTreeIter *iter,
- FindContact *fc)
-{
- if (contact_list_iter_equal_contact (model, iter, fc->contact)) {
- fc->found = TRUE;
- fc->iters = g_list_append (fc->iters, gtk_tree_iter_copy (iter));
- }
-
- /* We want to find ALL contacts that match, this means if we
- * have the same contact in 3 groups, all iters should be
- * returned.
- */
- return FALSE;
-}
-
static void
contact_list_action_cb (GtkAction *action,
GossipContactList *list)
group = gossip_contact_list_get_selected_group (list);
if (contact && strcmp (name, "Chat") == 0) {
- g_signal_emit (list, signals[CONTACT_CHAT], 0, contact);
+ contact_list_action_activated (list, contact);
}
else if (contact && strcmp (name, "Information") == 0) {
- g_signal_emit (list, signals[CONTACT_INFORMATION], 0, contact);
}
else if (contact && strcmp (name, "Edit") == 0) {
- g_signal_emit (list, signals[CONTACT_EDIT], 0, contact);
}
else if (contact && strcmp (name, "Remove") == 0) {
- g_signal_emit (list, signals[CONTACT_REMOVE], 0, contact);
}
else if (contact && strcmp (name, "Invite") == 0) {
- g_signal_emit (list, signals[CONTACT_INVITE], 0, contact);
}
else if (contact && strcmp (name, "SendFile") == 0) {
- g_signal_emit (list, signals[CONTACT_SEND_FILE], 0, contact);
}
else if (contact && strcmp (name, "Log") == 0) {
- g_signal_emit (list, signals[CONTACT_LOG], 0, contact);
}
else if (group && strcmp (name, "Rename") == 0) {
- g_signal_emit (list, signals[GROUP_RENAME], 0, group);
}
g_free (group);
}
}
+static void
+contact_list_action_activated (GossipContactList *list,
+ GossipContact *contact)
+{
+ MissionControl *mc;
+
+ mc = gossip_mission_control_new ();
+ mission_control_request_channel (mc,
+ gossip_contact_get_account (contact),
+ TP_IFACE_CHANNEL_TYPE_TEXT,
+ gossip_contact_get_handle (contact),
+ TP_HANDLE_TYPE_CONTACT,
+ NULL, NULL);
+ g_object_unref (mc);
+}
+
static gboolean
contact_list_update_list_mode_foreach (GtkTreeModel *model,
GtkTreePath *path,
show_avatar = TRUE;
}
- gtk_tree_store_set (GTK_TREE_STORE (model), iter,
+ gtk_tree_store_set (priv->store, iter,
COL_PIXBUF_AVATAR_VISIBLE, show_avatar,
COL_STATUS_VISIBLE, !priv->is_compact,
-1);
return priv->show_offline;
}
+gboolean
+gossip_contact_list_get_show_avatars (GossipContactList *list)
+{
+ GossipContactListPriv *priv;
+
+ g_return_val_if_fail (GOSSIP_IS_CONTACT_LIST (list), TRUE);
+
+ priv = GET_PRIV (list);
+
+ return priv->show_avatars;
+}
+
+gboolean
+gossip_contact_list_get_is_compact (GossipContactList *list)
+{
+ GossipContactListPriv *priv;
+
+ g_return_val_if_fail (GOSSIP_IS_CONTACT_LIST (list), TRUE);
+
+ priv = GET_PRIV (list);
+
+ return priv->is_compact;
+}
+
+GossipContactListSort
+gossip_contact_list_get_sort_criterium (GossipContactList *list)
+{
+ GossipContactListPriv *priv;
+
+ g_return_val_if_fail (GOSSIP_IS_CONTACT_LIST (list), 0);
+
+ priv = GET_PRIV (list);
+
+ return priv->sort_criterium;
+}
+
void
gossip_contact_list_set_show_offline (GossipContactList *list,
gboolean show_offline)
/* Disable temporarily. */
priv->show_active = FALSE;
- contacts = empathy_contact_manager_get_contacts (priv->manager);
+ contacts = empathy_contact_list_get_contacts (priv->list);
for (l = contacts; l; l = l->next) {
GossipContact *contact;
priv->show_active = show_active;
}
-gboolean
-gossip_contact_list_get_show_avatars (GossipContactList *list)
+void
+gossip_contact_list_set_show_avatars (GossipContactList *list,
+ gboolean show_avatars)
{
GossipContactListPriv *priv;
+ GtkTreeModel *model;
- g_return_val_if_fail (GOSSIP_IS_CONTACT_LIST (list), TRUE);
+ g_return_if_fail (GOSSIP_IS_CONTACT_LIST (list));
priv = GET_PRIV (list);
- return priv->show_avatars;
+ priv->show_avatars = show_avatars;
+
+ model = GTK_TREE_MODEL (priv->store);
+
+ gtk_tree_model_foreach (model,
+ (GtkTreeModelForeachFunc)
+ contact_list_update_list_mode_foreach,
+ list);
}
void
-gossip_contact_list_set_show_avatars (GossipContactList *list,
- gboolean show_avatars)
+gossip_contact_list_set_is_compact (GossipContactList *list,
+ gboolean is_compact)
{
GossipContactListPriv *priv;
GtkTreeModel *model;
priv = GET_PRIV (list);
- priv->show_avatars = show_avatars;
+ priv->is_compact = is_compact;
- model = gtk_tree_view_get_model (GTK_TREE_VIEW (list));
+ model = GTK_TREE_MODEL (priv->store);
gtk_tree_model_foreach (model,
(GtkTreeModelForeachFunc)
list);
}
-gboolean
-gossip_contact_list_get_is_compact (GossipContactList *list)
+void
+gossip_contact_list_set_sort_criterium (GossipContactList *list,
+ GossipContactListSort sort_criterium)
{
GossipContactListPriv *priv;
- g_return_val_if_fail (GOSSIP_IS_CONTACT_LIST (list), TRUE);
+ g_return_if_fail (GOSSIP_IS_CONTACT_LIST (list));
priv = GET_PRIV (list);
- return priv->is_compact;
+ priv->sort_criterium = sort_criterium;
+
+ switch (sort_criterium) {
+ case GOSSIP_CONTACT_LIST_SORT_STATE:
+ gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (priv->store),
+ COL_STATUS,
+ GTK_SORT_ASCENDING);
+ break;
+
+ case GOSSIP_CONTACT_LIST_SORT_NAME:
+ gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (priv->store),
+ COL_NAME,
+ GTK_SORT_ASCENDING);
+ break;
+ }
}
void
-gossip_contact_list_set_is_compact (GossipContactList *list,
- gboolean is_compact)
+gossip_contact_list_set_filter (GossipContactList *list,
+ const gchar *filter)
{
GossipContactListPriv *priv;
- GtkTreeModel *model;
g_return_if_fail (GOSSIP_IS_CONTACT_LIST (list));
priv = GET_PRIV (list);
- priv->is_compact = is_compact;
-
- model = gtk_tree_view_get_model (GTK_TREE_VIEW (list));
+ g_free (priv->filter_text);
+ if (filter) {
+ priv->filter_text = g_utf8_casefold (filter, -1);
+ } else {
+ priv->filter_text = NULL;
+ }
- gtk_tree_model_foreach (model,
- (GtkTreeModelForeachFunc)
- contact_list_update_list_mode_foreach,
- list);
+ gossip_debug (DEBUG_DOMAIN, "Refiltering with filter:'%s' (case folded)", filter);
+ gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (priv->filter));
}
-