aboutsummaryrefslogtreecommitdiffstats
path: root/libempathy-gtk
diff options
context:
space:
mode:
authorchantra <chantra@debuntu.org>2009-12-17 00:20:36 +0800
committerGuillaume Desmottes <guillaume.desmottes@collabora.co.uk>2009-12-17 00:22:01 +0800
commitfbaeb693027d63d94488702635630644971dfc2f (patch)
tree9b58024f0089129e197824550b68ee1f30fbea05 /libempathy-gtk
parentd6152461b68592397130f5df2dd285b5651eb460 (diff)
downloadgsoc2013-empathy-fbaeb693027d63d94488702635630644971dfc2f.tar
gsoc2013-empathy-fbaeb693027d63d94488702635630644971dfc2f.tar.gz
gsoc2013-empathy-fbaeb693027d63d94488702635630644971dfc2f.tar.bz2
gsoc2013-empathy-fbaeb693027d63d94488702635630644971dfc2f.tar.lz
gsoc2013-empathy-fbaeb693027d63d94488702635630644971dfc2f.tar.xz
gsoc2013-empathy-fbaeb693027d63d94488702635630644971dfc2f.tar.zst
gsoc2013-empathy-fbaeb693027d63d94488702635630644971dfc2f.zip
contact_list: displays an icon showing the protocol by the contact (#603877)
Diffstat (limited to 'libempathy-gtk')
-rw-r--r--libempathy-gtk/empathy-conf.h1
-rw-r--r--libempathy-gtk/empathy-contact-list-store.c143
-rw-r--r--libempathy-gtk/empathy-contact-list-store.h8
-rw-r--r--libempathy-gtk/empathy-contact-list-view.c14
-rw-r--r--libempathy-gtk/empathy-contact-selector.c2
-rw-r--r--libempathy-gtk/empathy-ui-utils.c112
-rw-r--r--libempathy-gtk/empathy-ui-utils.h9
7 files changed, 279 insertions, 10 deletions
diff --git a/libempathy-gtk/empathy-conf.h b/libempathy-gtk/empathy-conf.h
index 8d0066d90..551627364 100644
--- a/libempathy-gtk/empathy-conf.h
+++ b/libempathy-gtk/empathy-conf.h
@@ -73,6 +73,7 @@ struct _EmpathyConfClass {
#define EMPATHY_PREFS_UI_MAIN_WINDOW_HIDDEN EMPATHY_PREFS_PATH "/ui/main_window_hidden"
#define EMPATHY_PREFS_UI_AVATAR_DIRECTORY EMPATHY_PREFS_PATH "/ui/avatar_directory"
#define EMPATHY_PREFS_UI_SHOW_AVATARS EMPATHY_PREFS_PATH "/ui/show_avatars"
+#define EMPATHY_PREFS_UI_SHOW_PROTOCOLS EMPATHY_PREFS_PATH "/ui/show_protocols"
#define EMPATHY_PREFS_UI_COMPACT_CONTACT_LIST EMPATHY_PREFS_PATH "/ui/compact_contact_list"
#define EMPATHY_PREFS_UI_CHAT_WINDOW_PANED_POS EMPATHY_PREFS_PATH "/ui/chat_window_paned_pos"
#define EMPATHY_PREFS_CONTACTS_SHOW_OFFLINE EMPATHY_PREFS_PATH "/contacts/show_offline"
diff --git a/libempathy-gtk/empathy-contact-list-store.c b/libempathy-gtk/empathy-contact-list-store.c
index c516dbf7c..4660a0b14 100644
--- a/libempathy-gtk/empathy-contact-list-store.c
+++ b/libempathy-gtk/empathy-contact-list-store.c
@@ -60,11 +60,13 @@ typedef struct {
gboolean show_avatars;
gboolean show_groups;
gboolean is_compact;
+ gboolean show_protocols;
gboolean show_active;
EmpathyContactListStoreSort sort_criterium;
guint inhibit_active;
guint setup_idle_id;
gboolean dispose_has_run;
+ GHashTable *status_icons;
} EmpathyContactListStorePriv;
typedef struct {
@@ -165,6 +167,7 @@ enum {
PROP_CONTACT_LIST,
PROP_SHOW_OFFLINE,
PROP_SHOW_AVATARS,
+ PROP_SHOW_PROTOCOLS,
PROP_SHOW_GROUPS,
PROP_IS_COMPACT,
PROP_SORT_CRITERIUM
@@ -256,6 +259,14 @@ empathy_contact_list_store_class_init (EmpathyContactListStoreClass *klass)
TRUE,
G_PARAM_READWRITE));
g_object_class_install_property (object_class,
+ PROP_SHOW_PROTOCOLS,
+ g_param_spec_boolean ("show-protocols",
+ "Show Protocols",
+ "Whether contact list should display "
+ "protocols for contacts",
+ FALSE,
+ G_PARAM_READWRITE));
+ g_object_class_install_property (object_class,
PROP_SHOW_GROUPS,
g_param_spec_boolean ("show-groups",
"Show Groups",
@@ -292,9 +303,11 @@ empathy_contact_list_store_init (EmpathyContactListStore *store)
store->priv = priv;
priv->show_avatars = TRUE;
priv->show_groups = TRUE;
+ priv->show_protocols = FALSE;
priv->inhibit_active = g_timeout_add_seconds (ACTIVE_USER_WAIT_TO_ENABLE_TIME,
(GSourceFunc) contact_list_store_inibit_active_cb,
store);
+ priv->status_icons = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref);
contact_list_store_setup (store);
}
@@ -337,6 +350,7 @@ contact_list_store_dispose (GObject *object)
g_source_remove (priv->setup_idle_id);
}
+ g_hash_table_destroy (priv->status_icons);
G_OBJECT_CLASS (empathy_contact_list_store_parent_class)->dispose (object);
}
@@ -360,6 +374,9 @@ contact_list_store_get_property (GObject *object,
case PROP_SHOW_AVATARS:
g_value_set_boolean (value, priv->show_avatars);
break;
+ case PROP_SHOW_PROTOCOLS:
+ g_value_set_boolean (value, priv->show_protocols);
+ break;
case PROP_SHOW_GROUPS:
g_value_set_boolean (value, priv->show_groups);
break;
@@ -398,6 +415,10 @@ contact_list_store_set_property (GObject *object,
empathy_contact_list_store_set_show_avatars (EMPATHY_CONTACT_LIST_STORE (object),
g_value_get_boolean (value));
break;
+ case PROP_SHOW_PROTOCOLS:
+ empathy_contact_list_store_set_show_protocols (EMPATHY_CONTACT_LIST_STORE (object),
+ g_value_get_boolean (value));
+ break;
case PROP_SHOW_GROUPS:
empathy_contact_list_store_set_show_groups (EMPATHY_CONTACT_LIST_STORE (object),
g_value_get_boolean (value));
@@ -517,6 +538,42 @@ empathy_contact_list_store_set_show_avatars (EmpathyContactListStore *store,
g_object_notify (G_OBJECT (store), "show-avatars");
}
+
+gboolean
+empathy_contact_list_store_get_show_protocols (EmpathyContactListStore *store)
+{
+ EmpathyContactListStorePriv *priv;
+
+ g_return_val_if_fail (EMPATHY_IS_CONTACT_LIST_STORE (store), TRUE);
+
+ priv = GET_PRIV (store);
+
+ return priv->show_protocols;
+}
+
+void
+empathy_contact_list_store_set_show_protocols (EmpathyContactListStore *store,
+ gboolean show_protocols)
+{
+ EmpathyContactListStorePriv *priv;
+ GtkTreeModel *model;
+
+ g_return_if_fail (EMPATHY_IS_CONTACT_LIST_STORE (store));
+
+ priv = GET_PRIV (store);
+
+ priv->show_protocols = show_protocols;
+
+ model = GTK_TREE_MODEL (store);
+
+ gtk_tree_model_foreach (model,
+ (GtkTreeModelForeachFunc)
+ contact_list_store_update_list_mode_foreach,
+ store);
+
+ g_object_notify (G_OBJECT (store), "show-protocols");
+}
+
gboolean
empathy_contact_list_store_get_show_groups (EmpathyContactListStore *store)
{
@@ -753,7 +810,7 @@ contact_list_store_setup (EmpathyContactListStore *store)
{
EmpathyContactListStorePriv *priv;
GType types[] = {
- G_TYPE_STRING, /* Status icon-name */
+ GDK_TYPE_PIXBUF, /* Status pixbuf */
GDK_TYPE_PIXBUF, /* Avatar pixbuf */
G_TYPE_BOOLEAN, /* Avatar pixbuf visible */
G_TYPE_STRING, /* Name */
@@ -1055,7 +1112,9 @@ contact_list_store_contact_update (EmpathyContactListStore *store,
gboolean do_set_active = FALSE;
gboolean do_set_refresh = FALSE;
gboolean show_avatar = FALSE;
+ gboolean show_protocol = FALSE;
GdkPixbuf *pixbuf_avatar;
+ GdkPixbuf *pixbuf_status;
priv = GET_PRIV (store);
@@ -1148,10 +1207,14 @@ contact_list_store_contact_update (EmpathyContactListStore *store,
if (priv->show_avatars && !priv->is_compact) {
show_avatar = TRUE;
}
+ if (priv->show_protocols && !priv->is_compact) {
+ show_protocol = TRUE;
+ }
pixbuf_avatar = empathy_pixbuf_avatar_from_contact_scaled (contact, 32, 32);
+ 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_ICON_STATUS, empathy_icon_name_for_contact (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,
EMPATHY_CONTACT_LIST_STORE_COL_NAME, empathy_contact_get_name (contact),
@@ -1581,15 +1644,32 @@ contact_list_store_update_list_mode_foreach (GtkTreeModel *model,
EmpathyContactListStore *store)
{
EmpathyContactListStorePriv *priv;
- gboolean show_avatar = FALSE;
+ gboolean show_avatar = FALSE;
+ gboolean show_protocol = FALSE;
+ EmpathyContact *contact;
+ GdkPixbuf *pixbuf_status;
priv = GET_PRIV (store);
if (priv->show_avatars && !priv->is_compact) {
show_avatar = TRUE;
}
+ if (priv->show_protocols && !priv->is_compact) {
+ show_protocol = TRUE;
+ }
+
+ gtk_tree_model_get (model, iter,
+ EMPATHY_CONTACT_LIST_STORE_COL_CONTACT, &contact,
+ -1);
+
+ if (contact == NULL){
+ return FALSE;
+ }
+ /* get icon from hash_table */
+ pixbuf_status = contact_list_store_get_contact_status_icon (store, contact);
gtk_tree_store_set (GTK_TREE_STORE (store), iter,
+ EMPATHY_CONTACT_LIST_STORE_COL_ICON_STATUS, pixbuf_status,
EMPATHY_CONTACT_LIST_STORE_COL_PIXBUF_AVATAR_VISIBLE, show_avatar,
EMPATHY_CONTACT_LIST_STORE_COL_STATUS_VISIBLE, !priv->is_compact,
-1);
@@ -1597,3 +1677,60 @@ contact_list_store_update_list_mode_foreach (GtkTreeModel *model,
return FALSE;
}
+GdkPixbuf *
+contact_list_store_get_contact_status_icon (EmpathyContactListStore *store,
+ EmpathyContact *contact)
+{
+ GdkPixbuf *pixbuf_status = NULL;
+ const gchar *status_icon_name = NULL;
+
+ status_icon_name = empathy_icon_name_for_contact (contact);
+ pixbuf_status = contact_list_store_get_contact_status_icon_with_icon_name (
+ store,
+ contact,
+ status_icon_name);
+
+ return pixbuf_status;
+}
+
+GdkPixbuf *
+contact_list_store_get_contact_status_icon_with_icon_name (
+ EmpathyContactListStore *store,
+ EmpathyContact *contact,
+ const gchar *status_icon_name)
+{
+ GdkPixbuf *pixbuf_status = NULL;
+ EmpathyContactListStorePriv *priv;
+ const gchar *protocol_name = NULL;
+ gchar *icon_name = NULL;
+ gboolean show_protocol = FALSE;
+
+ priv = GET_PRIV (store);
+
+ if (priv->show_protocols && !priv->is_compact) {
+ show_protocol = TRUE;
+ }
+ if (show_protocol) {
+ protocol_name = empathy_protocol_name_for_contact (contact);
+ icon_name = g_strdup_printf ("%s-%s", status_icon_name, protocol_name);
+ } else {
+ icon_name = g_strdup_printf ("%s", status_icon_name);
+ }
+ pixbuf_status = g_hash_table_lookup (priv->status_icons, icon_name);
+ if (pixbuf_status == NULL) {
+ pixbuf_status = empathy_pixbuf_contact_status_icon_with_icon_name (contact,
+ status_icon_name,
+ show_protocol);
+ if (pixbuf_status != NULL) {
+ g_hash_table_insert (priv->status_icons,
+ g_strdup (icon_name),
+ pixbuf_status);
+ DEBUG( "Created status icon %s\n", icon_name);
+ }
+ } else {
+ DEBUG( "retrieved from cache status icon %s\n", icon_name);
+ }
+ g_free (icon_name);
+ return pixbuf_status;
+}
+
diff --git a/libempathy-gtk/empathy-contact-list-store.h b/libempathy-gtk/empathy-contact-list-store.h
index f97853991..c46e9e831 100644
--- a/libempathy-gtk/empathy-contact-list-store.h
+++ b/libempathy-gtk/empathy-contact-list-store.h
@@ -90,6 +90,9 @@ void empathy_contact_list_store_set_show_groups (Empathy
gboolean empathy_contact_list_store_get_is_compact (EmpathyContactListStore *store);
void empathy_contact_list_store_set_is_compact (EmpathyContactListStore *store,
gboolean is_compact);
+gboolean empathy_contact_list_store_get_show_protocols (EmpathyContactListStore *store);
+void empathy_contact_list_store_set_show_protocols (EmpathyContactListStore *store,
+ gboolean show_protocols);
EmpathyContactListStoreSort empathy_contact_list_store_get_sort_criterium (EmpathyContactListStore *store);
void empathy_contact_list_store_set_sort_criterium (EmpathyContactListStore *store,
EmpathyContactListStoreSort sort_criterium);
@@ -104,6 +107,11 @@ gboolean empathy_contact_list_store_search_equal_func (GtkTre
const gchar *key,
GtkTreeIter *iter,
gpointer search_data);
+GdkPixbuf * contact_list_store_get_contact_status_icon ( EmpathyContactListStore *store,
+ EmpathyContact *contact);
+GdkPixbuf * contact_list_store_get_contact_status_icon_with_icon_name (EmpathyContactListStore *store,
+ EmpathyContact *contact,
+ const gchar *status_icon_name);
G_END_DECLS
diff --git a/libempathy-gtk/empathy-contact-list-view.c b/libempathy-gtk/empathy-contact-list-view.c
index 6b25cc10f..e11a2e93f 100644
--- a/libempathy-gtk/empathy-contact-list-view.c
+++ b/libempathy-gtk/empathy-contact-list-view.c
@@ -842,22 +842,24 @@ contact_list_view_pixbuf_cell_data_func (GtkTreeViewColumn *tree_column,
GtkTreeIter *iter,
EmpathyContactListView *view)
{
- gchar *icon_name;
- gboolean is_group;
- gboolean is_active;
+ GdkPixbuf *pixbuf;
+ gboolean is_group;
+ gboolean is_active;
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_ICON_STATUS, &icon_name,
+ EMPATHY_CONTACT_LIST_STORE_COL_ICON_STATUS, &pixbuf,
-1);
g_object_set (cell,
"visible", !is_group,
- "icon-name", icon_name,
+ "pixbuf", pixbuf,
NULL);
- g_free (icon_name);
+ if (pixbuf != NULL) {
+ g_object_unref (pixbuf);
+ }
contact_list_view_cell_set_background (view, cell, is_group, is_active);
}
diff --git a/libempathy-gtk/empathy-contact-selector.c b/libempathy-gtk/empathy-contact-selector.c
index 8aa02fa6d..027ca41c2 100644
--- a/libempathy-gtk/empathy-contact-selector.c
+++ b/libempathy-gtk/empathy-contact-selector.c
@@ -211,7 +211,7 @@ contact_selector_constructor (GType type,
priv->store = empathy_contact_list_store_new (priv->contact_list);
g_object_set (priv->store, "is-compact", TRUE, "show-avatars", FALSE,
- "show-offline", FALSE, "show-groups", FALSE,
+ "show-offline", FALSE, "show-groups", FALSE, "show-protocols", FALSE,
"sort-criterium", EMPATHY_CONTACT_LIST_STORE_SORT_NAME, NULL);
g_signal_connect_swapped (priv->store, "row-changed",
diff --git a/libempathy-gtk/empathy-ui-utils.c b/libempathy-gtk/empathy-ui-utils.c
index 2d8f4091c..3fa39d53f 100644
--- a/libempathy-gtk/empathy-ui-utils.c
+++ b/libempathy-gtk/empathy-ui-utils.c
@@ -230,6 +230,21 @@ empathy_icon_name_for_contact (EmpathyContact *contact)
return empathy_icon_name_for_presence (presence);
}
+const gchar *
+empathy_protocol_name_for_contact (EmpathyContact *contact)
+{
+ TpAccount *account;
+
+ g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), NULL);
+
+ account = empathy_contact_get_account (contact);
+ if (account == NULL) {
+ return NULL;
+ }
+
+ return tp_account_get_icon_name (account);
+}
+
GdkPixbuf *
empathy_pixbuf_from_data (gchar *data,
gsize data_size)
@@ -491,6 +506,103 @@ empathy_pixbuf_avatar_from_contact_scaled (EmpathyContact *contact,
}
GdkPixbuf *
+empathy_pixbuf_contact_status_icon (EmpathyContact *contact,
+ gboolean show_protocol)
+{
+ const gchar *icon_name;
+
+ g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), NULL);
+
+ icon_name = empathy_icon_name_for_contact (contact);
+
+ if (icon_name == NULL) {
+ return NULL;
+ }
+ return empathy_pixbuf_contact_status_icon_with_icon_name (contact,
+ icon_name,
+ show_protocol);
+}
+
+GdkPixbuf *
+empathy_pixbuf_contact_status_icon_with_icon_name (EmpathyContact *contact,
+ const gchar *icon_name,
+ gboolean show_protocol)
+{
+ GdkPixbuf *pix_status;
+ GdkPixbuf *pix_protocol;
+ gchar *icon_filename;
+ gint height, width;
+ gint numerator, denominator;
+
+ g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), NULL);
+
+ numerator = 3;
+ denominator = 4;
+
+ icon_filename = empathy_filename_from_icon_name (icon_name,
+ GTK_ICON_SIZE_MENU);
+ if (icon_filename == NULL) {
+ DEBUG ("icon name: %s could not be found\n", icon_name);
+ return NULL;
+ }
+
+ pix_status = gdk_pixbuf_new_from_file (icon_filename, NULL);
+
+ g_free (icon_filename);
+
+ if (pix_status == NULL) {
+ DEBUG ("Could not open icon %s\n", icon_filename);
+ return NULL;
+ }
+
+ if (!show_protocol)
+ return pix_status;
+
+ height = gdk_pixbuf_get_height (pix_status);
+ width = gdk_pixbuf_get_width (pix_status);
+
+ pix_protocol = empathy_pixbuf_protocol_from_contact_scaled (contact,
+ width * numerator / denominator,
+ height * numerator / denominator);
+
+ if (pix_protocol == NULL) {
+ return pix_status;
+ }
+ gdk_pixbuf_composite (pix_protocol, pix_status,
+ 0, height - height * numerator / denominator,
+ width * numerator / denominator, height * numerator / denominator,
+ 0, height - height * numerator / denominator,
+ 1, 1,
+ GDK_INTERP_BILINEAR, 255);
+
+ g_object_unref (pix_protocol);
+
+ return pix_status;
+}
+
+GdkPixbuf *
+empathy_pixbuf_protocol_from_contact_scaled (EmpathyContact *contact,
+ gint width,
+ gint height)
+{
+ TpAccount *account;
+ gchar *filename;
+ GdkPixbuf *pixbuf = NULL;
+
+ g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), NULL);
+
+ account = empathy_contact_get_account (contact);
+ filename = empathy_filename_from_icon_name (tp_account_get_icon_name (account),
+ GTK_ICON_SIZE_MENU);
+ if (filename != NULL) {
+ pixbuf = gdk_pixbuf_new_from_file_at_size (filename, width, height, NULL);
+ g_free (filename);
+ }
+
+ return pixbuf;
+}
+
+GdkPixbuf *
empathy_pixbuf_scale_down_if_necessary (GdkPixbuf *pixbuf, gint max_size)
{
gint width, height;
diff --git a/libempathy-gtk/empathy-ui-utils.h b/libempathy-gtk/empathy-ui-utils.h
index 0eacd49b8..925ecc5cb 100644
--- a/libempathy-gtk/empathy-ui-utils.h
+++ b/libempathy-gtk/empathy-ui-utils.h
@@ -63,6 +63,7 @@ GtkWidget *empathy_builder_unref_and_keep_widget (GtkBuilder *gui,
/* Pixbufs */
const gchar * empathy_icon_name_for_presence (TpConnectionPresenceType presence);
const gchar * empathy_icon_name_for_contact (EmpathyContact *contact);
+const gchar * empathy_protocol_name_for_contact (EmpathyContact *contact);
GdkPixbuf * empathy_pixbuf_from_data (gchar *data,
gsize data_size);
GdkPixbuf * empathy_pixbuf_from_data_and_mime (gchar *data,
@@ -74,6 +75,14 @@ GdkPixbuf * empathy_pixbuf_from_avatar_scaled (EmpathyAvatar *avata
GdkPixbuf * empathy_pixbuf_avatar_from_contact_scaled (EmpathyContact *contact,
gint width,
gint height);
+GdkPixbuf * empathy_pixbuf_protocol_from_contact_scaled (EmpathyContact *contact,
+ gint width,
+ gint height);
+GdkPixbuf * empathy_pixbuf_contact_status_icon (EmpathyContact *contact,
+ gboolean show_protocol);
+GdkPixbuf * empathy_pixbuf_contact_status_icon_with_icon_name (EmpathyContact *contact,
+ const gchar *icon_name,
+ gboolean show_protocol);
GdkPixbuf * empathy_pixbuf_scale_down_if_necessary (GdkPixbuf *pixbuf,
gint max_size);
GdkPixbuf * empathy_pixbuf_from_icon_name (const gchar *icon_name,