From beb301da43c57e64e781b7f5c69b2bc667f46b1d Mon Sep 17 00:00:00 2001 From: Xavier Claessens Date: Wed, 9 May 2007 11:48:33 +0000 Subject: [PATCH] [darcs-to-svn @ sync with Gossip SVN 2323] svn path=/trunk/; revision=38 --- libempathy-gtk/empathy-main-window.c | 46 ++++- libempathy-gtk/empathy.schemas.in | 18 +- libempathy-gtk/gossip-account-widget-jabber.c | 2 + .../gossip-account-widget-jabber.glade | 1 - libempathy-gtk/gossip-accounts-dialog.c | 29 +-- libempathy-gtk/gossip-chat-window.c | 14 +- libempathy-gtk/gossip-chat.c | 7 +- libempathy-gtk/gossip-contact-list.c | 192 +++++++++++++++++- libempathy-gtk/gossip-contact-list.h | 54 +++-- libempathy-gtk/gossip-preferences.c | 137 +++++++++++-- libempathy-gtk/gossip-preferences.glade | 97 +++++++++ libempathy-gtk/gossip-preferences.h | 1 + libempathy/empathy-marshal.list | 1 + 13 files changed, 520 insertions(+), 79 deletions(-) diff --git a/libempathy-gtk/empathy-main-window.c b/libempathy-gtk/empathy-main-window.c index 563129dc..a34ad5bf 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 243e6ce2..66de66d6 100644 --- a/libempathy-gtk/empathy.schemas.in +++ b/libempathy-gtk/empathy.schemas.in @@ -15,6 +15,22 @@ + + /schemas/apps/gossip/contacts/sort_criterium + /apps/gossip/contacts/sort_criterium + gossip + string + name + + Contact list sort criterium + + 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. + + + + /schemas/apps/empathy/ui/show_avatars /apps/empathy/ui/show_avatars @@ -25,7 +41,7 @@ Show avatars Whether or not to show avatars for contacts in the contact - list and chat windows. + list and chat windows. diff --git a/libempathy-gtk/gossip-account-widget-jabber.c b/libempathy-gtk/gossip-account-widget-jabber.c index 1c3b6108..8282777b 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 cbb79caf..12eec757 100644 --- a/libempathy-gtk/gossip-account-widget-jabber.glade +++ b/libempathy-gtk/gossip-account-widget-jabber.glade @@ -21,7 +21,6 @@ - True 6 3 False diff --git a/libempathy-gtk/gossip-accounts-dialog.c b/libempathy-gtk/gossip-accounts-dialog.c index 449577ae..5155ced1 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 feeda5e0..62ace37b 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 614abd7d..03f22514 100644 --- a/libempathy-gtk/gossip-chat.c +++ b/libempathy-gtk/gossip-chat.c @@ -39,6 +39,7 @@ #include #include #include +#include #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 aa5eb385..86ae9656 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) @@ -2616,6 +2761,33 @@ gossip_contact_list_set_is_compact (GossipContactList *list, 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 42c949c1..c8e79fb9 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 a02a4fa9..bc65187e 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); } @@ -775,6 +828,44 @@ preferences_toggle_button_toggled_cb (GtkWidget *button, gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (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 41ee4fe7..c5cd5147 100644 --- a/libempathy-gtk/gossip-preferences.glade +++ b/libempathy-gtk/gossip-preferences.glade @@ -253,6 +253,103 @@ False + + + True + 0 + 0.5 + GTK_SHADOW_NONE + + + + True + 0.5 + 0.5 + 1 + 1 + 6 + 0 + 12 + 0 + + + + True + False + 0 + + + + True + True + Sort by _name + True + GTK_RELIEF_NORMAL + True + False + False + True + + + 0 + False + False + + + + + + True + True + Sort by s_tate + True + GTK_RELIEF_NORMAL + True + False + False + True + radiobutton_contact_list_sort_by_name + + + 0 + False + False + + + + + + + + + + True + <b>Contact List</b> + False + True + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + label_item + + + + + 0 + True + True + + False diff --git a/libempathy-gtk/gossip-preferences.h b/libempathy-gtk/gossip-preferences.h index 3d635cb6..74ecc904 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 b9bbd27a..7d126825 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 -- 2.39.2