aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTravis Reitter <treitter@gmail.com>2010-02-17 02:11:43 +0800
committerGuillaume Desmottes <guillaume.desmottes@collabora.co.uk>2010-03-15 16:28:40 +0800
commitb8657a61fe72be0da2d91325b0851dd4d7fd533c (patch)
tree497904127e697e2a4bfab0e9666057a784606be2
parent870983d8050e267e1894f36c7ab6fe7fe0295441 (diff)
downloadgsoc2013-empathy-b8657a61fe72be0da2d91325b0851dd4d7fd533c.tar
gsoc2013-empathy-b8657a61fe72be0da2d91325b0851dd4d7fd533c.tar.gz
gsoc2013-empathy-b8657a61fe72be0da2d91325b0851dd4d7fd533c.tar.bz2
gsoc2013-empathy-b8657a61fe72be0da2d91325b0851dd4d7fd533c.tar.lz
gsoc2013-empathy-b8657a61fe72be0da2d91325b0851dd4d7fd533c.tar.xz
gsoc2013-empathy-b8657a61fe72be0da2d91325b0851dd4d7fd533c.tar.zst
gsoc2013-empathy-b8657a61fe72be0da2d91325b0851dd4d7fd533c.zip
Add support for marking contacts as favorites (which gives them a highlighted
star next to their name and adds them to the top of the contact list)
-rw-r--r--libempathy-gtk/empathy-contact-list-store.c69
-rw-r--r--libempathy-gtk/empathy-contact-list-store.h3
-rw-r--r--libempathy-gtk/empathy-contact-list-view.c89
-rw-r--r--libempathy-gtk/empathy-images.h2
-rw-r--r--libempathy/empathy-contact-list.c17
-rw-r--r--libempathy/empathy-contact-list.h7
6 files changed, 181 insertions, 6 deletions
diff --git a/libempathy-gtk/empathy-contact-list-store.c b/libempathy-gtk/empathy-contact-list-store.c
index 53a0934b3..8592fe96f 100644
--- a/libempathy-gtk/empathy-contact-list-store.c
+++ b/libempathy-gtk/empathy-contact-list-store.c
@@ -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) {
diff --git a/libempathy-gtk/empathy-contact-list-store.h b/libempathy-gtk/empathy-contact-list-store.h
index afefd28cf..b852a1ba8 100644
--- a/libempathy-gtk/empathy-contact-list-store.h
+++ b/libempathy-gtk/empathy-contact-list-store.h
@@ -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 {
diff --git a/libempathy-gtk/empathy-contact-list-view.c b/libempathy-gtk/empathy-contact-list-view.c
index 705494e4a..c952bb8ae 100644
--- a/libempathy-gtk/empathy-contact-list-view.c
+++ b/libempathy-gtk/empathy-contact-list-view.c
@@ -817,6 +817,41 @@ contact_list_view_call_activated_cb (
}
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,
gboolean is_group,
@@ -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,
@@ -999,6 +1039,39 @@ contact_list_view_expander_cell_data_func (GtkTreeViewColumn *column,
}
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,
GtkTreePath *path,
@@ -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);
diff --git a/libempathy-gtk/empathy-images.h b/libempathy-gtk/empathy-images.h
index c714f047d..623774e4c 100644
--- a/libempathy-gtk/empathy-images.h
+++ b/libempathy-gtk/empathy-images.h
@@ -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
diff --git a/libempathy/empathy-contact-list.c b/libempathy/empathy-contact-list.c
index d4859210a..65a1edeec 100644
--- a/libempathy/empathy-contact-list.c
+++ b/libempathy/empathy-contact-list.c
@@ -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;
+}
+
diff --git a/libempathy/empathy-contact-list.h b/libempathy/empathy-contact-list.h
index 28238e44a..c3fff7271 100644
--- a/libempathy/empathy-contact-list.h
+++ b/libempathy/empathy-contact-list.h
@@ -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__ */