]> git.0d.be Git - empathy.git/commitdiff
Add support for marking contacts as favorites (which gives them a highlighted
authorTravis Reitter <treitter@gmail.com>
Tue, 16 Feb 2010 18:11:43 +0000 (10:11 -0800)
committerGuillaume Desmottes <guillaume.desmottes@collabora.co.uk>
Mon, 15 Mar 2010 08:28:40 +0000 (09:28 +0100)
star next to their name and adds them to the top of the contact list)

libempathy-gtk/empathy-contact-list-store.c
libempathy-gtk/empathy-contact-list-store.h
libempathy-gtk/empathy-contact-list-view.c
libempathy-gtk/empathy-images.h
libempathy/empathy-contact-list.c
libempathy/empathy-contact-list.h

index 53a0934b32f8501f9788a650788d5486fae42bea..8592fe96fe72ccc9e2a90b9abcc67a20ab4b9246 100644 (file)
@@ -824,6 +824,7 @@ contact_list_store_setup (EmpathyContactListStore *store)
                G_TYPE_BOOLEAN,       /* Can make audio calls */
                G_TYPE_BOOLEAN,       /* Can make video calls */
                EMPATHY_TYPE_CONTACT_LIST_FLAGS, /* Flags */
+               G_TYPE_BOOLEAN,       /* Is a favourite */
        };
 
        priv = GET_PRIV (store);
@@ -1095,6 +1096,17 @@ contact_list_store_remove_contact (EmpathyContactListStore *store,
        g_list_free (iters);
 }
 
+static gboolean
+list_store_contact_is_favourite (EmpathyContactListStore *store,
+                                EmpathyContact          *contact)
+{
+       EmpathyContactListStorePriv *priv;
+
+       priv = GET_PRIV (store);
+
+       return empathy_contact_list_contact_is_favourite (priv->list, contact);
+}
+
 static void
 contact_list_store_contact_update (EmpathyContactListStore *store,
                                   EmpathyContact          *contact)
@@ -1210,6 +1222,7 @@ contact_list_store_contact_update (EmpathyContactListStore *store,
        pixbuf_status = contact_list_store_get_contact_status_icon (store, contact);
        for (l = iters; l && set_model; l = l->next) {
                gtk_tree_store_set (GTK_TREE_STORE (store), l->data,
+                                   EMPATHY_CONTACT_LIST_STORE_COL_IS_FAVOURITE, list_store_contact_is_favourite (store, contact),
                                    EMPATHY_CONTACT_LIST_STORE_COL_ICON_STATUS, pixbuf_status,
                                    EMPATHY_CONTACT_LIST_STORE_COL_PIXBUF_AVATAR, pixbuf_avatar,
                                    EMPATHY_CONTACT_LIST_STORE_COL_PIXBUF_AVATAR_VISIBLE, show_avatar,
@@ -1433,6 +1446,20 @@ contact_list_store_get_group (EmpathyContactListStore *store,
                                    EMPATHY_CONTACT_LIST_STORE_COL_IS_SEPARATOR, TRUE,
                                    -1);
 
+               /* add a second separator for the favourite contacts group, to
+                * always be sorted at the end. This will provide a visual
+                * distinction between the end of the favourites and the
+                * beginning of the ungrouped contacts */
+               if (!g_strcmp0 (name, EMPATHY_GROUP_FAVOURITES)) {
+                       gtk_tree_store_append (GTK_TREE_STORE (store),
+                                       &iter_separator,
+                                       &iter_group);
+                       gtk_tree_store_set (GTK_TREE_STORE (store), &iter_separator,
+                                       EMPATHY_CONTACT_LIST_STORE_COL_NAME, EMPATHY_GROUP_FAVOURITES,
+                                       EMPATHY_CONTACT_LIST_STORE_COL_IS_SEPARATOR, TRUE,
+                                       -1);
+               }
+
                if (iter_separator_to_set) {
                        *iter_separator_to_set = iter_separator;
                }
@@ -1483,13 +1510,29 @@ contact_list_store_state_sort_func (GtkTreeModel *model,
                            EMPATHY_CONTACT_LIST_STORE_COL_IS_SEPARATOR, &is_separator_b,
                            -1);
 
-       /* Separator or group? */
+       /* Separator, favourites group, or other group? */
        if (is_separator_a || is_separator_b) {
                if (is_separator_a) {
-                       ret_val = -1;
+                       /* sort the special favourites group 2nd separator at
+                        * the end */
+                       if (!g_strcmp0 (name_a, EMPATHY_GROUP_FAVOURITES)) {
+                               ret_val = 1;
+                       } else {
+                               ret_val = -1;
+                       }
                } else if (is_separator_b) {
-                       ret_val = 1;
+                       if (!g_strcmp0 (name_b, EMPATHY_GROUP_FAVOURITES)) {
+                               ret_val = -1;
+                       } else {
+                               ret_val = 1;
+                       }
                }
+       } else if (!contact_a && !g_strcmp0 (name_a,
+                               EMPATHY_GROUP_FAVOURITES)) {
+               ret_val = -1;
+       } else if (!contact_b && !g_strcmp0 (name_b,
+                               EMPATHY_GROUP_FAVOURITES)) {
+               ret_val = 1;
        } else if (!contact_a && contact_b) {
                ret_val = 1;
        } else if (contact_a && !contact_b) {
@@ -1556,10 +1599,26 @@ contact_list_store_name_sort_func (GtkTreeModel *model,
 
        if (is_separator_a || is_separator_b) {
                if (is_separator_a) {
-                       ret_val = -1;
+                       /* sort the special favourites group 2nd separator at
+                        * the end */
+                       if (!g_strcmp0 (name_a, EMPATHY_GROUP_FAVOURITES)) {
+                               ret_val = 1;
+                       } else {
+                               ret_val = -1;
+                       }
                } else if (is_separator_b) {
-                       ret_val = 1;
+                       if (!g_strcmp0 (name_b, EMPATHY_GROUP_FAVOURITES)) {
+                               ret_val = -1;
+                       } else {
+                               ret_val = 1;
+                       }
                }
+       } else if (!contact_a && !g_strcmp0 (name_a,
+                               EMPATHY_GROUP_FAVOURITES)) {
+               ret_val = -1;
+       } else if (!contact_b && !g_strcmp0 (name_b,
+                               EMPATHY_GROUP_FAVOURITES)) {
+               ret_val = 1;
        } else if (!contact_a && contact_b) {
                ret_val = 1;
        } else if (contact_a && !contact_b) {
index afefd28cff22f49b4fe7f218bd06f0a34d1a9edd..b852a1ba87b7d2b3eecbc10d156a32329b5ed227 100644 (file)
@@ -63,7 +63,8 @@ typedef enum {
        EMPATHY_CONTACT_LIST_STORE_COL_CAN_AUDIO_CALL,
        EMPATHY_CONTACT_LIST_STORE_COL_CAN_VIDEO_CALL,
        EMPATHY_CONTACT_LIST_STORE_COL_FLAGS,
-       EMPATHY_CONTACT_LIST_STORE_COL_COUNT
+       EMPATHY_CONTACT_LIST_STORE_COL_IS_FAVOURITE,
+       EMPATHY_CONTACT_LIST_STORE_COL_COUNT,
 } EmpathyContactListStoreCol;
 
 struct _EmpathyContactListStore {
index 705494e4ada377351ff601cbd5b8a930dabda91d..c952bb8ae4a4b7395bafb4d35004ab29844b980a 100644 (file)
@@ -816,6 +816,41 @@ contact_list_view_call_activated_cb (
        g_object_unref (contact);
 }
 
+static void
+contact_list_view_favourite_toggled_cb (
+    EmpathyCellRendererActivatable *cell,
+    const gchar                    *path_string,
+    EmpathyContactListView         *view)
+{
+       EmpathyContactListViewPriv *priv = GET_PRIV (view);
+       GtkTreeModel *model;
+       GtkTreeIter iter;
+       EmpathyContact *contact;
+        EmpathyContactList *list;
+
+       model = gtk_tree_view_get_model (GTK_TREE_VIEW (view));
+       if (!gtk_tree_model_get_iter_from_string (model, &iter, path_string))
+               return;
+
+       gtk_tree_model_get (model, &iter,
+                           EMPATHY_CONTACT_LIST_STORE_COL_CONTACT, &contact,
+                           -1);
+       if (contact == NULL)
+               return;
+
+        list = empathy_contact_list_store_get_list_iface (priv->store);
+
+        if (empathy_contact_list_contact_is_favourite (list, contact)) {
+                empathy_contact_list_remove_from_group (list, contact,
+                                EMPATHY_GROUP_FAVOURITES);
+        } else {
+                empathy_contact_list_add_to_group (list, contact,
+                                EMPATHY_GROUP_FAVOURITES);
+        }
+
+       g_object_unref (contact);
+}
+
 static void
 contact_list_view_cell_set_background (EmpathyContactListView *view,
                                       GtkCellRenderer       *cell,
@@ -955,6 +990,11 @@ contact_list_view_text_cell_data_func (GtkTreeViewColumn     *tree_column,
                            EMPATHY_CONTACT_LIST_STORE_COL_NAME, &name,
                            -1);
 
+        if (is_group && !g_strcmp0 (name, EMPATHY_GROUP_FAVOURITES)) {
+                g_free (name);
+                name = g_strdup (_(EMPATHY_GROUP_FAVOURITES));
+        }
+
        g_object_set (cell,
                      "show-status", show_status,
                      "text", name,
@@ -998,6 +1038,39 @@ contact_list_view_expander_cell_data_func (GtkTreeViewColumn     *column,
        contact_list_view_cell_set_background (view, cell, is_group, is_active);
 }
 
+static void
+contact_list_view_favourite_cell_data_func (
+                                      GtkTreeViewColumn      *tree_column,
+                                      GtkCellRenderer        *cell,
+                                      GtkTreeModel           *model,
+                                      GtkTreeIter            *iter,
+                                      EmpathyContactListView *view)
+{
+       gboolean is_group;
+       gboolean is_active;
+       gboolean is_separator;
+       gboolean is_favourite;
+       const gchar *icon_name = NULL;
+
+       gtk_tree_model_get (model, iter,
+                           EMPATHY_CONTACT_LIST_STORE_COL_IS_GROUP, &is_group,
+                           EMPATHY_CONTACT_LIST_STORE_COL_IS_ACTIVE, &is_active,
+                           EMPATHY_CONTACT_LIST_STORE_COL_IS_SEPARATOR, &is_separator,
+                           EMPATHY_CONTACT_LIST_STORE_COL_IS_FAVOURITE, &is_favourite,
+                           -1);
+
+        if (!is_separator && !is_group)
+                icon_name = (is_favourite? EMPATHY_IMAGE_FAVOURITE :
+                                EMPATHY_IMAGE_UNFAVOURITE);
+
+       g_object_set (cell,
+                     "visible", (icon_name != NULL),
+                     "icon-name", icon_name,
+                     NULL);
+
+       contact_list_view_cell_set_background (view, cell, is_group, is_active);
+}
+
 static void
 contact_list_view_row_expand_or_collapse_cb (EmpathyContactListView *view,
                                             GtkTreeIter           *iter,
@@ -1101,6 +1174,22 @@ contact_list_view_setup (EmpathyContactListView *view)
 
        col = gtk_tree_view_column_new ();
 
+       /* Favourite Icon */
+       cell = empathy_cell_renderer_activatable_new ();
+       gtk_tree_view_column_pack_start (col, cell, FALSE);
+       gtk_tree_view_column_set_cell_data_func (
+               col, cell,
+               (GtkTreeCellDataFunc) contact_list_view_favourite_cell_data_func,
+               view, NULL);
+
+       g_object_set (cell,
+                     "visible", FALSE,
+                     NULL);
+
+       g_signal_connect (cell, "path-activated",
+                         G_CALLBACK (contact_list_view_favourite_toggled_cb),
+                         view);
+
        /* State */
        cell = gtk_cell_renderer_pixbuf_new ();
        gtk_tree_view_column_pack_start (col, cell, FALSE);
index c714f047da60ee130dbddecccb658473c7aa2f04..623774e4cdcbb16a655c65835adbfc3fa40b869d 100644 (file)
@@ -41,6 +41,8 @@ G_BEGIN_DECLS
 #define EMPATHY_IMAGE_VIDEO_CALL          "camera-web"
 #define EMPATHY_IMAGE_LOG                 "document-open-recent"
 #define EMPATHY_IMAGE_DOCUMENT_SEND       "document-send"
+#define EMPATHY_IMAGE_FAVOURITE           "empathy-starred"
+#define EMPATHY_IMAGE_UNFAVOURITE         "empathy-unstarred"
 
 G_END_DECLS
 
index d4859210a6508e3dab49d40d9bf55d710a8a5167..65a1edeec20f47c0cec6289140f198c9316819fa 100644 (file)
@@ -249,3 +249,20 @@ empathy_contact_list_get_flags (EmpathyContactList *list)
                return 0;
        }
 }
+
+/* XXX: this should be an EmpathyContact function, but it would likely require
+ * some awkward refactoring */
+gboolean
+empathy_contact_list_contact_is_favourite (EmpathyContactList *list,
+                                           EmpathyContact     *contact)
+{
+        GList *groups, *l;
+
+        groups = empathy_contact_list_get_groups (list, contact);
+        for (l = groups; l; l = l->next)
+                if (!g_strcmp0 (l->data, EMPATHY_GROUP_FAVOURITES))
+                        return TRUE;
+
+        return FALSE;
+}
+
index 28238e44a16e6b89eb6654344b1f8f326d8e02fc..c3fff727112631963cf1abfda45d5bd7f0fa48f7 100644 (file)
@@ -34,6 +34,9 @@ G_BEGIN_DECLS
 #define EMPATHY_IS_CONTACT_LIST(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), EMPATHY_TYPE_CONTACT_LIST))
 #define EMPATHY_CONTACT_LIST_GET_IFACE(o) (G_TYPE_INSTANCE_GET_INTERFACE ((o), EMPATHY_TYPE_CONTACT_LIST, EmpathyContactListIface))
 
+/* The favourites are just in a specially-handled group */
+#define EMPATHY_GROUP_FAVOURITES "Favorites"
+
 typedef enum {
        EMPATHY_CONTACT_LIST_CAN_ADD            = 1 << 0,
        EMPATHY_CONTACT_LIST_CAN_REMOVE         = 1 << 1,
@@ -104,6 +107,10 @@ EmpathyContactMonitor *
 EmpathyContactListFlags
          empathy_contact_list_get_flags                (EmpathyContactList *list);
 
+gboolean empathy_contact_list_contact_is_favourite
+                                        (EmpathyContactList *list,
+                                         EmpathyContact     *contact);
+
 G_END_DECLS
 
 #endif /* __EMPATHY_CONTACT_LIST_H__ */