[darcs-to-svn @ sync with Gossip SVN 2323]
authorXavier Claessens <xclaesse@src.gnome.org>
Wed, 9 May 2007 11:48:33 +0000 (11:48 +0000)
committerXavier Claessens <xclaesse@src.gnome.org>
Wed, 9 May 2007 11:48:33 +0000 (11:48 +0000)
svn path=/trunk/; revision=38

13 files changed:
libempathy-gtk/empathy-main-window.c
libempathy-gtk/empathy.schemas.in
libempathy-gtk/gossip-account-widget-jabber.c
libempathy-gtk/gossip-account-widget-jabber.glade
libempathy-gtk/gossip-accounts-dialog.c
libempathy-gtk/gossip-chat-window.c
libempathy-gtk/gossip-chat.c
libempathy-gtk/gossip-contact-list.c
libempathy-gtk/gossip-contact-list.h
libempathy-gtk/gossip-preferences.c
libempathy-gtk/gossip-preferences.glade
libempathy-gtk/gossip-preferences.h
libempathy/empathy-marshal.list

index 563129d..a34ad5b 100644 (file)
@@ -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);
+               }
+       }
+}
+
index 243e6ce..66de66d 100644 (file)
       </locale>
     </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>
@@ -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>
index 1c3b610..8282777 100644 (file)
@@ -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;
 }
 
index cbb79ca..12eec75 100644 (file)
@@ -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>
index 449577a..5155ced 100644 (file)
@@ -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;
 }
 
index feeda5e..62ace37 100644 (file)
@@ -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);
 
index 614abd7..03f2251 100644 (file)
@@ -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 
index aa5eb38..86ae965 100644 (file)
@@ -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)
index 42c949c..c8e79fb 100644 (file)
 
 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
 
index a02a4fa..bc65187 100644 (file)
@@ -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,
index 41ee4fe..c5cd514 100644 (file)
                  <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>
index 3d635cb..74ecc90 100644 (file)
@@ -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);
index b9bbd27..7d12682 100644 (file)
@@ -4,3 +4,4 @@ VOID:OBJECT,OBJECT
 VOID:INT,STRING
 VOID:OBJECT,OBJECT,UINT
 VOID:UINT,BOOLEAN
+VOID:OBJECT,BOOLEAN