aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libempathy-gtk/empathy-main-window.c46
-rw-r--r--libempathy-gtk/empathy.schemas.in18
-rw-r--r--libempathy-gtk/gossip-account-widget-jabber.c2
-rw-r--r--libempathy-gtk/gossip-account-widget-jabber.glade1
-rw-r--r--libempathy-gtk/gossip-accounts-dialog.c29
-rw-r--r--libempathy-gtk/gossip-chat-window.c14
-rw-r--r--libempathy-gtk/gossip-chat.c7
-rw-r--r--libempathy-gtk/gossip-contact-list.c192
-rw-r--r--libempathy-gtk/gossip-contact-list.h54
-rw-r--r--libempathy-gtk/gossip-preferences.c137
-rw-r--r--libempathy-gtk/gossip-preferences.glade97
-rw-r--r--libempathy-gtk/gossip-preferences.h1
-rw-r--r--libempathy/empathy-marshal.list1
13 files changed, 520 insertions, 79 deletions
diff --git a/libempathy-gtk/empathy-main-window.c b/libempathy-gtk/empathy-main-window.c
index 563129dc4..a34ad5bff 100644
--- a/libempathy-gtk/empathy-main-window.c
+++ b/libempathy-gtk/empathy-main-window.c
@@ -152,6 +152,9 @@ static void main_window_notify_show_avatars_cb (GossipConf
static void main_window_notify_compact_contact_list_cb (GossipConf *conf,
const gchar *key,
EmpathyMainWindow *window);
+static void main_window_notify_sort_criterium_cb (GossipConf *conf,
+ const gchar *key,
+ EmpathyMainWindow *window);
GtkWidget *
empathy_main_window_show (void)
@@ -308,8 +311,9 @@ empathy_main_window_show (void)
gtk_window_move (GTK_WINDOW (window->window), x, y);
}
- /* Get preferences */
conf = gossip_conf_get ();
+
+ /* Show offline ? */
gossip_conf_get_bool (conf,
GOSSIP_PREFS_CONTACTS_SHOW_OFFLINE,
&show_offline);
@@ -321,6 +325,7 @@ empathy_main_window_show (void)
gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (show_offline_widget),
show_offline);
+ /* Show avatars ? */
gossip_conf_get_bool (conf,
GOSSIP_PREFS_UI_SHOW_AVATARS,
&show_avatars);
@@ -328,6 +333,9 @@ empathy_main_window_show (void)
GOSSIP_PREFS_UI_SHOW_AVATARS,
(GossipConfNotifyFunc) main_window_notify_show_avatars_cb,
window);
+ gossip_contact_list_set_show_avatars (window->contact_list, show_avatars);
+
+ /* Is compact ? */
gossip_conf_get_bool (conf,
GOSSIP_PREFS_UI_COMPACT_CONTACT_LIST,
&compact_contact_list);
@@ -335,11 +343,16 @@ empathy_main_window_show (void)
GOSSIP_PREFS_UI_COMPACT_CONTACT_LIST,
(GossipConfNotifyFunc) main_window_notify_compact_contact_list_cb,
window);
+ gossip_contact_list_set_is_compact (window->contact_list, compact_contact_list);
- g_object_set (window->contact_list,
- "show-avatars", show_avatars,
- "is-compact", compact_contact_list,
- NULL);
+ /* Sort criterium */
+ gossip_conf_notify_add (conf,
+ GOSSIP_PREFS_CONTACTS_SORT_CRITERIUM,
+ (GossipConfNotifyFunc) main_window_notify_sort_criterium_cb,
+ window);
+ main_window_notify_sort_criterium_cb (conf,
+ GOSSIP_PREFS_CONTACTS_SORT_CRITERIUM,
+ window);
gtk_widget_show (window->window);
@@ -838,3 +851,26 @@ main_window_notify_compact_contact_list_cb (GossipConf *conf,
}
}
+static void
+main_window_notify_sort_criterium_cb (GossipConf *conf,
+ const gchar *key,
+ EmpathyMainWindow *window)
+{
+ gchar *str = NULL;
+
+ if (gossip_conf_get_string (conf, key, &str)) {
+ GType type;
+ GEnumClass *enum_class;
+ GEnumValue *enum_value;
+
+ type = gossip_contact_list_sort_get_type ();
+ enum_class = G_ENUM_CLASS (g_type_class_peek (type));
+ enum_value = g_enum_get_value_by_nick (enum_class, str);
+
+ if (enum_value) {
+ gossip_contact_list_set_sort_criterium (window->contact_list,
+ enum_value->value);
+ }
+ }
+}
+
diff --git a/libempathy-gtk/empathy.schemas.in b/libempathy-gtk/empathy.schemas.in
index 243e6ce27..66de66d62 100644
--- a/libempathy-gtk/empathy.schemas.in
+++ b/libempathy-gtk/empathy.schemas.in
@@ -16,6 +16,22 @@
</schema>
<schema>
+ <key>/schemas/apps/gossip/contacts/sort_criterium</key>
+ <applyto>/apps/gossip/contacts/sort_criterium</applyto>
+ <owner>gossip</owner>
+ <type>string</type>
+ <default>name</default>
+ <locale name="C">
+ <short>Contact list sort criterium</short>
+ <long>
+ Which criterium to use when sorting the contact list.
+ Default is to use sort by the contact's name with the value
+ "name". A value of "state" will sort the contact list by state.
+ </long>
+ </locale>
+ </schema>
+
+ <schema>
<key>/schemas/apps/empathy/ui/show_avatars</key>
<applyto>/apps/empathy/ui/show_avatars</applyto>
<owner>empathy</owner>
@@ -25,7 +41,7 @@
<short>Show avatars</short>
<long>
Whether or not to show avatars for contacts in the contact
- list and chat windows.
+ list and chat windows.
</long>
</locale>
</schema>
diff --git a/libempathy-gtk/gossip-account-widget-jabber.c b/libempathy-gtk/gossip-account-widget-jabber.c
index 1c3b6108c..8282777bd 100644
--- a/libempathy-gtk/gossip-account-widget-jabber.c
+++ b/libempathy-gtk/gossip-account-widget-jabber.c
@@ -260,6 +260,8 @@ gossip_account_widget_jabber_new (McAccount *account)
g_object_unref (size_group);
+ gtk_widget_show (settings->vbox_settings);
+
return settings->vbox_settings;
}
diff --git a/libempathy-gtk/gossip-account-widget-jabber.glade b/libempathy-gtk/gossip-account-widget-jabber.glade
index cbb79caf5..12eec7576 100644
--- a/libempathy-gtk/gossip-account-widget-jabber.glade
+++ b/libempathy-gtk/gossip-account-widget-jabber.glade
@@ -21,7 +21,6 @@
<child>
<widget class="GtkTable" id="vbox_jabber_settings">
- <property name="visible">True</property>
<property name="n_rows">6</property>
<property name="n_columns">3</property>
<property name="homogeneous">False</property>
diff --git a/libempathy-gtk/gossip-accounts-dialog.c b/libempathy-gtk/gossip-accounts-dialog.c
index 449577aec..5155ced12 100644
--- a/libempathy-gtk/gossip-accounts-dialog.c
+++ b/libempathy-gtk/gossip-accounts-dialog.c
@@ -186,12 +186,12 @@ accounts_dialog_setup (GossipAccountsDialog *dialog)
status = mission_control_get_connection_status (dialog->mc, account, NULL);
- gtk_list_store_append (store, &iter);
- gtk_list_store_set (store, &iter,
- COL_NAME, name,
- COL_STATUS, status,
- COL_ACCOUNT_POINTER, account,
- -1);
+ gtk_list_store_insert_with_values (store, &iter,
+ -1,
+ COL_NAME, name,
+ COL_STATUS, status,
+ COL_ACCOUNT_POINTER, account,
+ -1);
accounts_dialog_status_changed_cb (dialog->mc,
status,
@@ -591,12 +591,12 @@ accounts_dialog_add_account (GossipAccountsDialog *dialog,
gossip_debug (DEBUG_DOMAIN, "Adding new account: %s", name);
- gtk_list_store_append (store, &iter);
- gtk_list_store_set (store, &iter,
- COL_NAME, name,
- COL_STATUS, status,
- COL_ACCOUNT_POINTER, account,
- -1);
+ gtk_list_store_insert_with_values (store, &iter,
+ -1,
+ COL_NAME, name,
+ COL_STATUS, status,
+ COL_ACCOUNT_POINTER, account,
+ -1);
}
static void
@@ -737,6 +737,8 @@ accounts_dialog_status_changed_cb (MissionControl *mc,
g_source_remove (dialog->connecting_id);
dialog->connecting_id = 0;
}
+
+ gtk_widget_show (dialog->window);
}
static void
@@ -1019,11 +1021,10 @@ gossip_accounts_dialog_show (void)
accounts_dialog_model_setup (dialog);
accounts_dialog_setup (dialog);
+ accounts_dialog_model_select_first (dialog);
gtk_widget_show (dialog->window);
- accounts_dialog_model_select_first (dialog);
-
return dialog->window;
}
diff --git a/libempathy-gtk/gossip-chat-window.c b/libempathy-gtk/gossip-chat-window.c
index feeda5e00..62ace37b4 100644
--- a/libempathy-gtk/gossip-chat-window.c
+++ b/libempathy-gtk/gossip-chat-window.c
@@ -177,6 +177,7 @@ static void chat_window_composing_cb (GossipChat *
GossipChatWindow *window);
static void chat_window_new_message_cb (GossipChat *chat,
GossipMessage *message,
+ gboolean is_backlog,
GossipChatWindow *window);
static GtkNotebook* chat_window_detach_hook (GtkNotebook *source,
GtkWidget *page,
@@ -1339,6 +1340,7 @@ chat_window_composing_cb (GossipChat *chat,
static void
chat_window_new_message_cb (GossipChat *chat,
GossipMessage *message,
+ gboolean is_backlog,
GossipChatWindow *window)
{
GossipChatWindowPriv *priv;
@@ -1358,7 +1360,8 @@ chat_window_new_message_cb (GossipChat *chat,
needs_urgency = FALSE;
if (gossip_chat_is_group_chat (chat)) {
- if (gossip_chat_should_highlight_nick (message)) {
+ if (!is_backlog &&
+ gossip_chat_should_highlight_nick (message)) {
gossip_debug (DEBUG_DOMAIN, "Highlight this nick");
needs_urgency = TRUE;
}
@@ -1370,7 +1373,8 @@ chat_window_new_message_cb (GossipChat *chat,
chat_window_set_urgency_hint (window, TRUE);
}
- if (!g_list_find (priv->chats_new_msg, chat)) {
+ if (!is_backlog &&
+ !g_list_find (priv->chats_new_msg, chat)) {
priv->chats_new_msg = g_list_prepend (priv->chats_new_msg, chat);
chat_window_update_status (window, chat);
}
@@ -1476,16 +1480,16 @@ chat_window_page_added_cb (GtkNotebook *notebook,
gossip_chat_set_window (chat, window);
/* Connect chat signals for this window */
- g_signal_connect (chat, "status_changed",
+ g_signal_connect (chat, "status-changed",
G_CALLBACK (chat_window_status_changed_cb),
window);
- g_signal_connect (chat, "name_changed",
+ g_signal_connect (chat, "name-changed",
G_CALLBACK (chat_window_name_changed_cb),
window);
g_signal_connect (chat, "composing",
G_CALLBACK (chat_window_composing_cb),
window);
- g_signal_connect (chat, "new_message",
+ g_signal_connect (chat, "new-message",
G_CALLBACK (chat_window_new_message_cb),
window);
diff --git a/libempathy-gtk/gossip-chat.c b/libempathy-gtk/gossip-chat.c
index 614abd7d7..03f22514a 100644
--- a/libempathy-gtk/gossip-chat.c
+++ b/libempathy-gtk/gossip-chat.c
@@ -39,6 +39,7 @@
#include <libempathy/gossip-debug.h>
#include <libempathy/gossip-utils.h>
#include <libempathy/gossip-conf.h>
+#include <libempathy/empathy-marshal.h>
#include "gossip-chat.h"
#include "gossip-chat-window.h"
@@ -175,9 +176,9 @@ gossip_chat_class_init (GossipChatClass *klass)
G_SIGNAL_RUN_LAST,
0,
NULL, NULL,
- g_cclosure_marshal_VOID__OBJECT,
+ empathy_marshal_VOID__OBJECT_BOOLEAN,
G_TYPE_NONE,
- 1, GOSSIP_TYPE_MESSAGE);
+ 2, GOSSIP_TYPE_MESSAGE, G_TYPE_BOOLEAN);
chat_signals[NAME_CHANGED] =
g_signal_new ("name-changed",
@@ -403,7 +404,7 @@ chat_message_received_cb (EmpathyTpChat *tp_chat,
// FIXME: gossip_sound_play (GOSSIP_SOUND_CHAT);
}
- g_signal_emit_by_name (chat, "new-message", message);
+ g_signal_emit_by_name (chat, "new-message", message, FALSE);
}
void
diff --git a/libempathy-gtk/gossip-contact-list.c b/libempathy-gtk/gossip-contact-list.c
index aa5eb3855..86ae9656b 100644
--- a/libempathy-gtk/gossip-contact-list.c
+++ b/libempathy-gtk/gossip-contact-list.c
@@ -82,6 +82,8 @@ struct _GossipContactListPriv {
gboolean show_avatars;
gboolean is_compact;
gboolean show_active;
+
+ GossipContactListSort sort_criterium;
};
typedef struct {
@@ -234,7 +236,11 @@ static void contact_list_row_expand_or_collapse_cb (GossipContactList
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);
@@ -276,7 +282,8 @@ enum {
PROP_SHOW_OFFLINE,
PROP_SHOW_AVATARS,
PROP_IS_COMPACT,
- PROP_FILTER
+ PROP_FILTER,
+ PROP_SORT_CRITERIUM
};
static const GtkActionEntry entries[] = {
@@ -363,6 +370,28 @@ static const GtkTargetEntry drag_types_source[] = {
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
@@ -406,6 +435,15 @@ gossip_contact_list_class_init (GossipContactListClass *klass)
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));
}
@@ -533,6 +571,9 @@ contact_list_get_property (GObject *object,
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;
@@ -566,6 +607,10 @@ contact_list_set_property (GObject *object,
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;
@@ -1306,12 +1351,14 @@ contact_list_create_model (GossipContactList *list)
/* 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);
@@ -2129,10 +2176,96 @@ contact_list_row_expand_or_collapse_cb (GossipContactList *list,
}
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;
@@ -2540,6 +2673,18 @@ gossip_contact_list_get_is_compact (GossipContactList *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)
@@ -2617,6 +2762,33 @@ gossip_contact_list_set_is_compact (GossipContactList *list,
}
void
+gossip_contact_list_set_sort_criterium (GossipContactList *list,
+ GossipContactListSort sort_criterium)
+{
+ GossipContactListPriv *priv;
+
+ g_return_if_fail (GOSSIP_IS_CONTACT_LIST (list));
+
+ priv = GET_PRIV (list);
+
+ 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_filter (GossipContactList *list,
const gchar *filter)
{
diff --git a/libempathy-gtk/gossip-contact-list.h b/libempathy-gtk/gossip-contact-list.h
index 42c949c11..c8e79fb90 100644
--- a/libempathy-gtk/gossip-contact-list.h
+++ b/libempathy-gtk/gossip-contact-list.h
@@ -30,6 +30,21 @@
G_BEGIN_DECLS
+/*
+ * GossipContactListSort
+ */
+#define GOSSIP_TYPE_CONTACT_LIST_SORT (gossip_contact_list_sort_get_type ())
+
+typedef enum {
+ GOSSIP_CONTACT_LIST_SORT_STATE,
+ GOSSIP_CONTACT_LIST_SORT_NAME
+} GossipContactListSort;
+
+GType gossip_contact_list_sort_get_type (void) G_GNUC_CONST;
+
+/*
+ * GossipContactList
+ */
#define GOSSIP_TYPE_CONTACT_LIST (gossip_contact_list_get_type ())
#define GOSSIP_CONTACT_LIST(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GOSSIP_TYPE_CONTACT_LIST, GossipContactList))
#define GOSSIP_CONTACT_LIST_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GOSSIP_TYPE_CONTACT_LIST, GossipContactListClass))
@@ -49,24 +64,27 @@ struct _GossipContactListClass {
GtkTreeViewClass parent_class;
};
-GType gossip_contact_list_get_type (void) G_GNUC_CONST;
-GossipContactList *gossip_contact_list_new (void);
-GossipContact * gossip_contact_list_get_selected (GossipContactList *list);
-gchar * gossip_contact_list_get_selected_group (GossipContactList *list);
-gboolean gossip_contact_list_get_show_offline (GossipContactList *list);
-gboolean gossip_contact_list_get_show_avatars (GossipContactList *list);
-gboolean gossip_contact_list_get_is_compact (GossipContactList *list);
-GtkWidget * gossip_contact_list_get_contact_menu (GossipContactList *list,
- GossipContact *contact);
-GtkWidget * gossip_contact_list_get_group_menu (GossipContactList *list);
-void gossip_contact_list_set_show_offline (GossipContactList *list,
- gboolean show_offline);
-void gossip_contact_list_set_show_avatars (GossipContactList *list,
- gboolean show_avatars);
-void gossip_contact_list_set_is_compact (GossipContactList *list,
- gboolean is_compact);
-void gossip_contact_list_set_filter (GossipContactList *list,
- const gchar *filter);
+GType gossip_contact_list_get_type (void) G_GNUC_CONST;
+GossipContactList * gossip_contact_list_new (void);
+GossipContact * gossip_contact_list_get_selected (GossipContactList *list);
+gchar * gossip_contact_list_get_selected_group (GossipContactList *list);
+gboolean gossip_contact_list_get_show_offline (GossipContactList *list);
+gboolean gossip_contact_list_get_show_avatars (GossipContactList *list);
+gboolean gossip_contact_list_get_is_compact (GossipContactList *list);
+GossipContactListSort gossip_contact_list_get_sort_criterium (GossipContactList *list);
+GtkWidget * gossip_contact_list_get_contact_menu (GossipContactList *list,
+ GossipContact *contact);
+GtkWidget * gossip_contact_list_get_group_menu (GossipContactList *list);
+void gossip_contact_list_set_show_offline (GossipContactList *list,
+ gboolean show_offline);
+void gossip_contact_list_set_show_avatars (GossipContactList *list,
+ gboolean show_avatars);
+void gossip_contact_list_set_is_compact (GossipContactList *list,
+ gboolean is_compact);
+void gossip_contact_list_set_sort_criterium (GossipContactList *list,
+ GossipContactListSort sort_criterium);
+void gossip_contact_list_set_filter (GossipContactList *list,
+ const gchar *filter);
G_END_DECLS
diff --git a/libempathy-gtk/gossip-preferences.c b/libempathy-gtk/gossip-preferences.c
index a02a4fa96..bc65187ec 100644
--- a/libempathy-gtk/gossip-preferences.c
+++ b/libempathy-gtk/gossip-preferences.c
@@ -36,6 +36,7 @@
#include "gossip-ui-utils.h"
#include "gossip-theme-manager.h"
#include "gossip-spell.h"
+#include "gossip-contact-list.h"
typedef struct {
GtkWidget *dialog;
@@ -48,6 +49,8 @@ typedef struct {
GtkWidget *combobox_chat_theme;
GtkWidget *checkbutton_theme_chat_room;
GtkWidget *checkbutton_separate_chat_windows;
+ GtkWidget *radiobutton_contact_list_sort_by_name;
+ GtkWidget *radiobutton_contact_list_sort_by_state;
GtkWidget *checkbutton_sounds_for_messages;
GtkWidget *checkbutton_sounds_when_busy;
@@ -109,6 +112,9 @@ static void preferences_hookup_entry (GossipPreferences
static void preferences_hookup_toggle_button (GossipPreferences *preferences,
const gchar *key,
GtkWidget *widget);
+static void preferences_hookup_radio_button (GossipPreferences *preferences,
+ const gchar *key,
+ GtkWidget *widget);
static void preferences_hookup_string_combo (GossipPreferences *preferences,
const gchar *key,
GtkWidget *widget);
@@ -121,6 +127,8 @@ static void preferences_entry_value_changed_cb (GtkWidget
gpointer user_data);
static void preferences_toggle_button_toggled_cb (GtkWidget *button,
gpointer user_data);
+static void preferences_radio_button_toggled_cb (GtkWidget *button,
+ gpointer user_data);
static void preferences_string_combo_changed_cb (GtkWidget *button,
gpointer user_data);
static void preferences_destroy_cb (GtkWidget *widget,
@@ -195,6 +203,10 @@ preferences_setup_widgets (GossipPreferences *preferences)
preferences_hookup_sensitivity (preferences,
GOSSIP_PREFS_CHAT_SPELL_CHECKER_ENABLED,
preferences->treeview_spell_checker);
+
+ preferences_hookup_radio_button (preferences,
+ GOSSIP_PREFS_CONTACTS_SORT_CRITERIUM,
+ preferences->radiobutton_contact_list_sort_by_name);
}
static void
@@ -476,7 +488,9 @@ preferences_widget_sync_int (const gchar *key, GtkWidget *widget)
gint value;
if (gossip_conf_get_int (gossip_conf_get (), key, &value)) {
- gtk_spin_button_set_value (GTK_SPIN_BUTTON (widget), value);
+ if (GTK_IS_SPIN_BUTTON (widget)) {
+ gtk_spin_button_set_value (GTK_SPIN_BUTTON (widget), value);
+ }
}
}
@@ -486,7 +500,31 @@ preferences_widget_sync_string (const gchar *key, GtkWidget *widget)
gchar *value;
if (gossip_conf_get_string (gossip_conf_get (), key, &value) && value) {
- gtk_entry_set_text (GTK_ENTRY (widget), value);
+ if (GTK_IS_ENTRY (widget)) {
+ gtk_entry_set_text (GTK_ENTRY (widget), value);
+ } else if (GTK_IS_RADIO_BUTTON (widget)) {
+ if (strcmp (key, GOSSIP_PREFS_CONTACTS_SORT_CRITERIUM) == 0) {
+ GType type;
+ GEnumClass *enum_class;
+ GEnumValue *enum_value;
+ GSList *list;
+ GtkWidget *toggle_widget;
+
+ /* Get index from new string */
+ type = gossip_contact_list_sort_get_type ();
+ enum_class = G_ENUM_CLASS (g_type_class_peek (type));
+ enum_value = g_enum_get_value_by_nick (enum_class, value);
+
+ if (enum_value) {
+ list = gtk_radio_button_get_group (GTK_RADIO_BUTTON (widget));
+ toggle_widget = g_slist_nth_data (list, enum_value->value);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle_widget), TRUE);
+ }
+ } else {
+ g_warning ("Unhandled key:'%s' just had string change", key);
+ }
+ }
+
g_free (value);
}
}
@@ -541,11 +579,7 @@ preferences_notify_int_cb (GossipConf *conf,
const gchar *key,
gpointer user_data)
{
- gint value;
-
- if (gossip_conf_get_int (conf, key, &value)) {
- gtk_spin_button_set_value (GTK_SPIN_BUTTON (user_data), value);
- }
+ preferences_widget_sync_int (key, user_data);
}
static void
@@ -553,12 +587,7 @@ preferences_notify_string_cb (GossipConf *conf,
const gchar *key,
gpointer user_data)
{
- gchar *value;
-
- if (gossip_conf_get_string (conf, key, &value) && value) {
- gtk_entry_set_text (GTK_ENTRY (user_data), value);
- g_free (value);
- }
+ preferences_widget_sync_string (key, user_data);
}
static void
@@ -575,12 +604,6 @@ preferences_notify_bool_cb (GossipConf *conf,
gpointer user_data)
{
preferences_widget_sync_bool (key, user_data);
-/*
- if (gossip_conf_get_bool (conf, key, &value)) {
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (user_data),
- gconf_value_get_bool (value));
- }
-*/
}
static void
@@ -681,9 +704,39 @@ preferences_hookup_toggle_button (GossipPreferences *preferences,
NULL);
id = gossip_conf_notify_add (gossip_conf_get (),
- key,
- preferences_notify_bool_cb,
- widget);
+ key,
+ preferences_notify_bool_cb,
+ widget);
+ if (id) {
+ preferences_add_id (preferences, id);
+ }
+}
+
+static void
+preferences_hookup_radio_button (GossipPreferences *preferences,
+ const gchar *key,
+ GtkWidget *widget)
+{
+ GSList *group, *l;
+ guint id;
+
+ preferences_widget_sync_string (key, widget);
+
+ group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (widget));
+ for (l = group; l; l = l->next) {
+ g_signal_connect (l->data,
+ "toggled",
+ G_CALLBACK (preferences_radio_button_toggled_cb),
+ NULL);
+
+ g_object_set_data_full (G_OBJECT (l->data), "key",
+ g_strdup (key), g_free);
+ }
+
+ id = gossip_conf_notify_add (gossip_conf_get (),
+ key,
+ preferences_notify_string_cb,
+ widget);
if (id) {
preferences_add_id (preferences, id);
}
@@ -776,6 +829,44 @@ preferences_toggle_button_toggled_cb (GtkWidget *button,
}
static void
+preferences_radio_button_toggled_cb (GtkWidget *button,
+ gpointer user_data)
+{
+ const gchar *key;
+ const gchar *value = NULL;
+
+ if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button))) {
+ return;
+ }
+
+ key = g_object_get_data (G_OBJECT (button), "key");
+
+ if (key && strcmp (key, GOSSIP_PREFS_CONTACTS_SORT_CRITERIUM) == 0) {
+ GSList *group;
+ GType type;
+ GEnumClass *enum_class;
+ GEnumValue *enum_value;
+
+ group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (button));
+
+ /* Get string from index */
+ type = gossip_contact_list_sort_get_type ();
+ enum_class = G_ENUM_CLASS (g_type_class_peek (type));
+ enum_value = g_enum_get_value (enum_class, g_slist_index (group, button));
+
+ if (!enum_value) {
+ g_warning ("No GEnumValue for GossipContactListSort with GtkRadioButton index:%d",
+ g_slist_index (group, button));
+ return;
+ }
+
+ value = enum_value->value_nick;
+ }
+
+ gossip_conf_set_string (gossip_conf_get (), key, value);
+}
+
+static void
preferences_string_combo_changed_cb (GtkWidget *combo,
gpointer user_data)
{
@@ -847,6 +938,8 @@ gossip_preferences_show (void)
"combobox_chat_theme", &preferences->combobox_chat_theme,
"checkbutton_theme_chat_room", &preferences->checkbutton_theme_chat_room,
"checkbutton_separate_chat_windows", &preferences->checkbutton_separate_chat_windows,
+ "radiobutton_contact_list_sort_by_name", &preferences->radiobutton_contact_list_sort_by_name,
+ "radiobutton_contact_list_sort_by_state", &preferences->radiobutton_contact_list_sort_by_state,
"checkbutton_sounds_for_messages", &preferences->checkbutton_sounds_for_messages,
"checkbutton_sounds_when_busy", &preferences->checkbutton_sounds_when_busy,
"checkbutton_sounds_when_away", &preferences->checkbutton_sounds_when_away,
diff --git a/libempathy-gtk/gossip-preferences.glade b/libempathy-gtk/gossip-preferences.glade
index 41ee4fe71..c5cd51470 100644
--- a/libempathy-gtk/gossip-preferences.glade
+++ b/libempathy-gtk/gossip-preferences.glade
@@ -253,6 +253,103 @@
<property name="fill">False</property>
</packing>
</child>
+ <child>
+ <widget class="GtkFrame" id="frame13">
+ <property name="visible">True</property>
+ <property name="label_xalign">0</property>
+ <property name="label_yalign">0.5</property>
+ <property name="shadow_type">GTK_SHADOW_NONE</property>
+
+ <child>
+ <widget class="GtkAlignment" id="alignment31">
+ <property name="visible">True</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xscale">1</property>
+ <property name="yscale">1</property>
+ <property name="top_padding">6</property>
+ <property name="bottom_padding">0</property>
+ <property name="left_padding">12</property>
+ <property name="right_padding">0</property>
+
+ <child>
+ <widget class="GtkVBox" id="vbox217">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child>
+ <widget class="GtkRadioButton" id="radiobutton_contact_list_sort_by_name">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="label" translatable="yes">Sort by _name</property>
+ <property name="use_underline">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="active">False</property>
+ <property name="inconsistent">False</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkRadioButton" id="radiobutton_contact_list_sort_by_state">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="label" translatable="yes">Sort by s_tate</property>
+ <property name="use_underline">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="active">False</property>
+ <property name="inconsistent">False</property>
+ <property name="draw_indicator">True</property>
+ <property name="group">radiobutton_contact_list_sort_by_name</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkLabel" id="label644">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">&lt;b&gt;Contact List&lt;/b&gt;</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">True</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </widget>
+ <packing>
+ <property name="type">label_item</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
</widget>
<packing>
<property name="tab_expand">False</property>
diff --git a/libempathy-gtk/gossip-preferences.h b/libempathy-gtk/gossip-preferences.h
index 3d635cb61..74ecc9041 100644
--- a/libempathy-gtk/gossip-preferences.h
+++ b/libempathy-gtk/gossip-preferences.h
@@ -46,6 +46,7 @@ G_BEGIN_DECLS
#define GOSSIP_PREFS_UI_SHOW_AVATARS GOSSIP_PREFS_PATH "/ui/show_avatars"
#define GOSSIP_PREFS_UI_COMPACT_CONTACT_LIST GOSSIP_PREFS_PATH "/ui/compact_contact_list"
#define GOSSIP_PREFS_CONTACTS_SHOW_OFFLINE GOSSIP_PREFS_PATH "/contacts/show_offline"
+#define GOSSIP_PREFS_CONTACTS_SORT_CRITERIUM GOSSIP_PREFS_PATH "/contacts/sort_criterium"
#define GOSSIP_PREFS_HINTS_CLOSE_MAIN_WINDOW GOSSIP_PREFS_PATH "/hints/close_main_window"
GtkWidget * gossip_preferences_show (void);
diff --git a/libempathy/empathy-marshal.list b/libempathy/empathy-marshal.list
index b9bbd27a7..7d1268250 100644
--- a/libempathy/empathy-marshal.list
+++ b/libempathy/empathy-marshal.list
@@ -4,3 +4,4 @@ VOID:OBJECT,OBJECT
VOID:INT,STRING
VOID:OBJECT,OBJECT,UINT
VOID:UINT,BOOLEAN
+VOID:OBJECT,BOOLEAN