[gnome-chat] Add ChatContactsListDialog
- From: Debarshi Ray <debarshir src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-chat] Add ChatContactsListDialog
- Date: Tue, 10 Sep 2013 11:22:58 +0000 (UTC)
commit 69ceea96279ae5246177ac5e16dc7fb9795ea2c8
Author: Yosef Or Boczko <yoseforb gmail com>
Date: Tue Sep 10 14:04:19 2013 +0300
Add ChatContactsListDialog
src/Makefile.am | 3 +
src/chat-contacts-list-dialog.c | 312 ++++++++++++++++++++++++++++++++++++++
src/chat-contacts-list-dialog.h | 72 +++++++++
src/chat-contacts-list-dialog.ui | 23 +++
src/chat.gresource.xml | 1 +
5 files changed, 411 insertions(+), 0 deletions(-)
---
diff --git a/src/Makefile.am b/src/Makefile.am
index b45830d..ce4317a 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -22,6 +22,8 @@ gnome_chat_SOURCES = \
chat-application.h \
chat-client-factory.c \
chat-client-factory.h \
+ chat-contacts-list-dialog.c \
+ chat-contacts-list-dialog.h \
chat-conversations-list.c \
chat-conversations-list.h \
chat-embed.c \
@@ -47,6 +49,7 @@ EXTRA_DIST = \
chat-generate-about \
chat.gresource.xml \
chat-app-menu.ui \
+ chat-contacts-list-dialog.ui \
chat-embed.ui \
chat-main-toolbar.ui \
chat-main-window.ui \
diff --git a/src/chat-contacts-list-dialog.c b/src/chat-contacts-list-dialog.c
new file mode 100644
index 0000000..5c71b7e
--- /dev/null
+++ b/src/chat-contacts-list-dialog.c
@@ -0,0 +1,312 @@
+/*
+ * Chat - instant messaging client for GNOME
+ * Copyright © 2013 Yosef Or Boczko <yoseforb gmail com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+
+#include "config.h"
+
+#include <glib.h>
+#include <telepathy-glib/telepathy-glib.h>
+#include <telepathy-logger/telepathy-logger.h>
+
+#include "chat-contacts-list-dialog.h"
+
+
+struct _ChatContactsListDialogPrivate
+{
+ GtkWidget *list_box;
+ GHashTable *accounts;
+ TpAccountManager *am;
+};
+
+
+G_DEFINE_TYPE_WITH_PRIVATE (ChatContactsListDialog, chat_contacts_list_dialog, GTK_TYPE_DIALOG);
+
+static gboolean
+chat_contacts_list_dialog_accounts_key_equal_func (gconstpointer a, gconstpointer b)
+{
+ TpAccount *account_a = TP_ACCOUNT (a);
+ TpAccount *account_b = TP_ACCOUNT (b);
+ const gchar *path_suffix_a;
+ const gchar *path_suffix_b;
+
+ path_suffix_a = tp_account_get_path_suffix (account_a);
+ path_suffix_b = tp_account_get_path_suffix (account_b);
+
+ return g_strcmp0 (path_suffix_a, path_suffix_b) == 0;
+}
+
+
+static void
+chat_contacts_list_dialog_accounts_value_destroy_func (gpointer data)
+{
+ g_list_free_full ((GList *) data, g_object_unref);
+}
+
+
+static GtkWidget *
+chat_contacts_list_dialog_get_avatar_image (TpContact *contact)
+{
+ GFile *avatar_file;
+
+ avatar_file = tp_contact_get_avatar_file (contact);
+ if (avatar_file)
+ {
+ GFileInputStream *stream;
+ GdkPixbuf *pixbuf;
+ GError *error = NULL;
+
+ stream = g_file_read (avatar_file, NULL, &error);
+ if (!stream)
+ {
+ g_warning ("Failed to load avatar: %s", error->message);
+ g_error_free (error);
+ }
+ else
+ {
+ pixbuf = gdk_pixbuf_new_from_stream (G_INPUT_STREAM (stream), NULL, &error);
+ if (!pixbuf)
+ {
+ g_warning ("Failed to create avatar: %s", error->message);
+ g_error_free (error);
+ }
+ else
+ {
+ return gtk_image_new_from_pixbuf (pixbuf);
+ }
+ }
+ }
+
+ return gtk_image_new_from_icon_name ("avatar-default-symbolic",
+ GTK_ICON_SIZE_LARGE_TOOLBAR);
+}
+
+
+static const gchar *
+chat_contacts_list_dialog_get_presence_image (TpConnectionPresenceType presence)
+{
+ switch (presence)
+ {
+ case TP_CONNECTION_PRESENCE_TYPE_OFFLINE:
+ return "user-offline-symbolic";
+ case TP_CONNECTION_PRESENCE_TYPE_AVAILABLE:
+ return "user-available-symbolic";
+ case TP_CONNECTION_PRESENCE_TYPE_AWAY:
+ return "user-away-symbolic";
+ case TP_CONNECTION_PRESENCE_TYPE_EXTENDED_AWAY:
+ return "user-idle-symbolic";
+ case TP_CONNECTION_PRESENCE_TYPE_HIDDEN:
+ return "user-invisible-symbolic";
+ case TP_CONNECTION_PRESENCE_TYPE_BUSY:
+ return "user-busy-symbolic";
+ default:
+ return NULL;
+ }
+}
+
+
+static void
+chat_contacts_list_dialog_add_row (ChatContactsListDialog *self, TpContact *contact)
+{
+ ChatContactsListDialogPrivate *priv = self->priv;
+ TpConnectionPresenceType presence;
+ GtkWidget *row;
+ GtkWidget *box;
+ GtkWidget *label;
+ GtkWidget *image;
+ const gchar *state;
+
+ row = gtk_list_box_row_new ();
+ box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
+ gtk_widget_set_hexpand (box, TRUE);
+ gtk_container_set_border_width (GTK_CONTAINER (box), 6);
+ gtk_container_add (GTK_CONTAINER (row), box);
+ gtk_container_add (GTK_CONTAINER (priv->list_box), row);
+
+ presence = tp_contact_get_presence_type (contact);
+ if (presence == TP_CONNECTION_PRESENCE_TYPE_UNSET ||
+ presence == TP_CONNECTION_PRESENCE_TYPE_ERROR)
+ {
+ return;
+ }
+
+ image = chat_contacts_list_dialog_get_avatar_image (contact);
+ gtk_container_add (GTK_CONTAINER (box), image);
+
+ label = gtk_label_new (tp_contact_get_alias (contact));
+ gtk_container_add (GTK_CONTAINER (box), label);
+
+ state = chat_contacts_list_dialog_get_presence_image (presence);
+ if (state)
+ {
+ image = gtk_image_new_from_icon_name (state, GTK_ICON_SIZE_BUTTON);
+ gtk_box_pack_end (GTK_BOX (box), image, FALSE, FALSE, 0);
+ }
+
+ gtk_widget_show_all (row);
+}
+
+
+static void
+chat_contacts_list_dialog_connection_prepare (GObject *source_object, GAsyncResult *res, gpointer user_data)
+{
+ ChatContactsListDialog *self = CHAT_CONTACTS_LIST_DIALOG (user_data);
+ ChatContactsListDialogPrivate *priv = self->priv;
+ GError *error;
+ GList *contacts = NULL;
+ GPtrArray *contact_list = NULL;
+ TpAccount *account;
+ TpConnection *conn = TP_CONNECTION (source_object);
+ TpContactListState state;
+ guint i;
+
+ error = NULL;
+ if (!tp_proxy_prepare_finish (source_object, res, &error))
+ {
+ g_warning ("Unable to prepare the connection: %s", error->message);
+ g_error_free (error);
+ goto out;
+ }
+
+ state = tp_connection_get_contact_list_state (conn);
+ if (state != TP_CONTACT_LIST_STATE_SUCCESS)
+ {
+ g_warning ("Value of connection:contact-list-state %p was %d", conn, state);
+ goto out;
+ }
+
+ account = tp_connection_get_account (conn);
+ contact_list = tp_connection_dup_contact_list (conn);
+ for (i = 0; i < contact_list->len; i++)
+ {
+ TpContact *contact;
+
+ contact = TP_CONTACT (g_ptr_array_index (contact_list, i));
+ chat_contacts_list_dialog_add_row (self, contact);
+
+ contacts = g_list_prepend (contacts, g_object_ref (contact));
+ }
+
+ g_hash_table_insert (priv->accounts, g_object_ref (account), contacts);
+
+ out:
+ if (contact_list != NULL)
+ g_ptr_array_unref (contact_list);
+ g_object_unref (self);
+}
+
+
+static void
+chat_contacts_list_dialog_account_manager_prepare (GObject *source_object, GAsyncResult *res, gpointer
user_data)
+{
+ ChatContactsListDialog *self = CHAT_CONTACTS_LIST_DIALOG (user_data);
+ ChatContactsListDialogPrivate *priv = self->priv;
+ GError *error;
+ GList *accounts = NULL;
+ GList *l;
+
+ error = NULL;
+ if (!tp_proxy_prepare_finish (source_object, res, &error))
+ {
+ g_warning ("Unable to prepare the account manager: %s", error->message);
+ g_error_free (error);
+ goto out;
+ }
+
+ accounts = tp_account_manager_dup_valid_accounts (priv->am);
+ for (l = accounts; l != NULL; l = l->next)
+ {
+ TpAccount *account = TP_ACCOUNT (l->data);
+ TpConnection *conn;
+ const gchar *cm_name;
+
+ cm_name = tp_account_get_cm_name (account);
+ if (g_strcmp0 (cm_name, "idle") == 0)
+ continue;
+
+ conn = tp_account_get_connection (account);
+ if (conn == NULL)
+ continue;
+
+ tp_proxy_prepare_async (conn, NULL, chat_contacts_list_dialog_connection_prepare, g_object_ref (self));
+ g_hash_table_insert (priv->accounts, g_object_ref (account), NULL);
+ }
+
+ out:
+ g_list_free_full (accounts, g_object_unref);
+ g_object_unref (self);
+}
+
+
+static void
+chat_contacts_list_dialog_dispose (GObject *object)
+{
+ ChatContactsListDialog *self = CHAT_CONTACTS_LIST_DIALOG (object);
+ ChatContactsListDialogPrivate *priv = self->priv;
+
+ if (priv->accounts != NULL)
+ {
+ g_hash_table_unref (priv->accounts);
+ priv->accounts = NULL;
+ }
+
+ g_clear_object (&priv->am);
+
+ G_OBJECT_CLASS (chat_contacts_list_dialog_parent_class)->dispose (object);
+}
+
+
+static void
+chat_contacts_list_dialog_init (ChatContactsListDialog *self)
+{
+ ChatContactsListDialogPrivate *priv;
+
+ self->priv = chat_contacts_list_dialog_get_instance_private (self);
+ priv = self->priv;
+
+ gtk_widget_init_template (GTK_WIDGET (self));
+
+ priv->accounts = g_hash_table_new_full (g_direct_hash,
+ chat_contacts_list_dialog_accounts_key_equal_func,
+ g_object_unref,
+ chat_contacts_list_dialog_accounts_value_destroy_func);
+
+ priv->am = tp_account_manager_dup ();
+ tp_proxy_prepare_async (priv->am, NULL, chat_contacts_list_dialog_account_manager_prepare, g_object_ref
(self));
+}
+
+
+static void
+chat_contacts_list_dialog_class_init (ChatContactsListDialogClass *class)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (class);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
+
+ object_class->dispose = chat_contacts_list_dialog_dispose;
+
+ gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/chat/contacts-list-dialog.ui");
+ gtk_widget_class_bind_template_child_private (widget_class, ChatContactsListDialog, list_box);
+}
+
+
+GtkWidget *
+chat_contacts_list_dialog_new (void)
+{
+ return g_object_new (CHAT_TYPE_CONTACTS_LIST_DIALOG, NULL);
+}
diff --git a/src/chat-contacts-list-dialog.h b/src/chat-contacts-list-dialog.h
new file mode 100644
index 0000000..865e86d
--- /dev/null
+++ b/src/chat-contacts-list-dialog.h
@@ -0,0 +1,72 @@
+/*
+ * Chat - instant messaging client for GNOME
+ * Copyright © 2013 Red Hat, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+
+#ifndef CHAT_CONTACTS_LIST_DIALOG_H
+#define CHAT_CONTACTS_LIST_DIALOG_H
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define CHAT_TYPE_CONTACTS_LIST_DIALOG (chat_contacts_list_dialog_get_type ())
+
+#define CHAT_CONTACTS_LIST_DIALOG(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
+ CHAT_TYPE_CONTACTS_LIST_DIALOG, ChatContactsListDialog))
+
+#define CHAT_CONTACTS_LIST_DIALOG_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST ((klass), \
+ CHAT_TYPE_CONTACTS_LIST_DIALOG, ChatContactsListDialogClass))
+
+#define CHAT_IS_CONTACTS_LIST_DIALOG(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
+ CHAT_TYPE_CONTACTS_LIST_DIALOG))
+
+#define CHAT_IS_CONTACTS_LIST_DIALOG_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), \
+ CHAT_TYPE_CONTACTS_LIST_DIALOG))
+
+#define CHAT_CONTACTS_LIST_DIALOG_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), \
+ CHAT_TYPE_CONTACTS_LIST_DIALOG, ChatContactsListDialogClass))
+
+typedef struct _ChatContactsListDialog ChatContactsListDialog;
+typedef struct _ChatContactsListDialogClass ChatContactsListDialogClass;
+typedef struct _ChatContactsListDialogPrivate ChatContactsListDialogPrivate;
+
+struct _ChatContactsListDialog
+{
+ GtkDialog parent_instance;
+ ChatContactsListDialogPrivate *priv;
+};
+
+struct _ChatContactsListDialogClass
+{
+ GtkDialogClass parent_class;
+};
+
+GType chat_contacts_list_dialog_get_type (void) G_GNUC_CONST;
+
+GtkWidget *chat_contacts_list_dialog_new (void);
+
+G_END_DECLS
+
+#endif /* CHAT_CONTACTS_LIST_DIALOG_H */
diff --git a/src/chat-contacts-list-dialog.ui b/src/chat-contacts-list-dialog.ui
new file mode 100644
index 0000000..92d4fa3
--- /dev/null
+++ b/src/chat-contacts-list-dialog.ui
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+ <!-- interface-requires gtk+ 3.10 -->
+ <template class="ChatContactsListDialog" parent="GtkDialog">
+ <property name="can_focus">False</property>
+ <property name="title" translatable="yes">Contacts</property>
+ <property name="modal">True</property>
+ <property name="default_width">320</property>
+ <property name="default_height">260</property>
+ <property name="destroy_with_parent">True</property>
+ <property name="type_hint">dialog</property>
+ <child internal-child="vbox">
+ <object class="GtkBox" id="box">
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkListBox" id="list_box">
+ </object>
+ </child>
+ </object>
+ </child>
+ </template>
+</interface>
diff --git a/src/chat.gresource.xml b/src/chat.gresource.xml
index 7d8bcc9..f058342 100644
--- a/src/chat.gresource.xml
+++ b/src/chat.gresource.xml
@@ -3,6 +3,7 @@
<gresource prefix="/org/gnome/chat">
<file alias="app-menu.ui" preprocess="xml-stripblanks" compressed="true">chat-app-menu.ui</file>
<file alias="embed.ui" preprocess="xml-stripblanks" compressed="true">chat-embed.ui</file>
+ <file alias="contacts-list-dialog.ui" preprocess="xml-stripblanks"
compressed="true">chat-contacts-list-dialog.ui</file>
<file alias="main-toolbar.ui" preprocess="xml-stripblanks" compressed="true">chat-main-toolbar.ui</file>
<file alias="main-window.ui" preprocess="xml-stripblanks" compressed="true">chat-main-window.ui</file>
</gresource>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]