diff options
-rw-r--r-- | libempathy-gtk/empathy-contact-list-store.c | 69 | ||||
-rw-r--r-- | libempathy-gtk/empathy-contact-list-store.h | 3 | ||||
-rw-r--r-- | libempathy-gtk/empathy-contact-list-view.c | 89 | ||||
-rw-r--r-- | libempathy-gtk/empathy-images.h | 2 | ||||
-rw-r--r-- | libempathy/empathy-contact-list.c | 17 | ||||
-rw-r--r-- | libempathy/empathy-contact-list.h | 7 |
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__ */ |