]> git.0d.be Git - empathy.git/commitdiff
New widget: EmpathyContactWidget. It displays information about a contact,
authorXavier Claessens <xclaesse@gmail.com>
Wed, 6 Jun 2007 15:03:06 +0000 (15:03 +0000)
committerXavier Claessens <xclaesse@src.gnome.org>
Wed, 6 Jun 2007 15:03:06 +0000 (15:03 +0000)
2007-06-06 Xavier Claessens  <xclaesse@gmail.com>

* libempathy-gtk/empathy-status-icon.c:
* libempathy-gtk/empathy-contact-widget.glade:
* libempathy-gtk/empathy-contact-widget.c:
* libempathy-gtk/empathy-contact-widget.h:
* libempathy-gtk/Makefile.am: New widget: EmpathyContactWidget. It
displays information about a contact, it can be used in any kind of
dialog which needs to display contact information like alias, groups,
avatar, etc. If the contact is the selfcontact information are editable.

* libempathy/empathy-tp-contact-list.c: Do not take care of subscription
changes.

* libempathy/gossip-contact.c: Use
gossip_presence_state_get_default_status (MC_PRESENCE_OFFLINE)
when there is no presence.

svn path=/trunk/; revision=124

ChangeLog
libempathy-gtk/Makefile.am
libempathy-gtk/empathy-contact-widget.c [new file with mode: 0644]
libempathy-gtk/empathy-contact-widget.glade [new file with mode: 0644]
libempathy-gtk/empathy-contact-widget.h [new file with mode: 0644]
libempathy-gtk/empathy-status-icon.c
libempathy/empathy-tp-contact-list.c
libempathy/gossip-contact.c

index c7b9ecb8dc0da13e5db142d4e566a979a80d74c4..78d79ffff4fd1bdd1ef968f0f350033700a749ea 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,21 @@
+2007-06-06 Xavier Claessens  <xclaesse@gmail.com>
+
+       * libempathy-gtk/empathy-status-icon.c:
+       * libempathy-gtk/empathy-contact-widget.glade:
+       * libempathy-gtk/empathy-contact-widget.c:
+       * libempathy-gtk/empathy-contact-widget.h:
+       * libempathy-gtk/Makefile.am: New widget: EmpathyContactWidget. It
+       displays information about a contact, it can be used in any kind of
+       dialog which needs to display contact information like alias, groups,
+       avatar, etc. If the contact is the selfcontact information are editable.
+
+       * libempathy/empathy-tp-contact-list.c: Do not take care of subscription
+       changes.
+
+       * libempathy/gossip-contact.c: Use
+       gossip_presence_state_get_default_status (MC_PRESENCE_OFFLINE)
+       when there is no presence.
+
 2007-06-06 Xavier Claessens  <xclaesse@gmail.com>
 
        * libempathy-gtk/empathy-status-icon.c: Add support for blinking when
index e6d12a78f0aab0233837aa298c5d25b32df88797..ebee9a566fde553781531cde5b1e26d13cf069f9 100644 (file)
@@ -12,6 +12,7 @@ libempathy_gtk_la_SOURCES =                                                   \
        empathy-images.h                                                        \
        empathy-main-window.c                   empathy-main-window.h           \
        empathy-status-icon.c                   empathy-status-icon.h           \
+       empathy-contact-widget.c                empathy-contact-widget.h        \
        gossip-accounts-dialog.c                gossip-accounts-dialog.h        \
        gossip-account-widget-generic.c         gossip-account-widget-generic.h \
        gossip-account-widget-jabber.c          gossip-account-widget-jabber.h  \
@@ -48,6 +49,7 @@ gladedir = $(datadir)/empathy
 glade_DATA =                                   \
        empathy-main-window.glade               \
        empathy-status-icon.glade               \
+       empathy-contact-widget.glade            \
        gossip-preferences.glade                \
        gossip-presence-chooser.glade           \
        gossip-accounts-dialog.glade            \
diff --git a/libempathy-gtk/empathy-contact-widget.c b/libempathy-gtk/empathy-contact-widget.c
new file mode 100644 (file)
index 0000000..bb12283
--- /dev/null
@@ -0,0 +1,637 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2007 Collabora Ltd.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Authors: Xavier Claessens <xclaesse@gmail.com>
+ */
+
+#include <config.h>
+
+#include <string.h>
+#include <stdlib.h>
+
+#include <gtk/gtk.h>
+#include <glade/glade.h>
+#include <glib/gi18n.h>
+
+#include <libempathy/empathy-contact-manager.h>
+
+#include "empathy-contact-widget.h"
+#include "gossip-ui-utils.h"
+
+typedef struct {
+       GossipContact   *contact;
+       gboolean         is_user;
+       gboolean         changes_made;
+       GtkCellRenderer *renderer;
+
+       GtkWidget       *vbox_contact_widget;
+
+       GtkWidget       *vbox_contact;
+       GtkWidget       *label_id;
+       GtkWidget       *entry_alias;
+       GtkWidget       *image_state;
+       GtkWidget       *label_status;
+       GtkWidget       *table_contact;
+       GtkWidget       *hbox_contact;
+       GtkWidget       *image_avatar;
+
+       GtkWidget       *vbox_groups;
+       GtkWidget       *entry_group;
+       GtkWidget       *button_group;
+       GtkWidget       *treeview_groups;
+
+       GtkWidget       *vbox_details;
+       GtkWidget       *table_details;
+       GtkWidget       *hbox_details_requested;
+
+       GtkWidget       *vbox_client;
+       GtkWidget       *table_client;
+       GtkWidget       *hbow_client_requested;
+} EmpathyContactWidget;
+
+typedef struct {
+       EmpathyContactWidget *information;
+       const gchar          *name;
+       gboolean              found;
+       GtkTreeIter           found_iter;
+} FindName;
+
+typedef struct {
+       EmpathyContactWidget *information;
+       GList                *list;
+} FindSelected;
+
+static void     contact_widget_destroy_cb                  (GtkWidget             *widget,
+                                                           EmpathyContactWidget  *information);
+static void     contact_widget_contact_setup               (EmpathyContactWidget  *information);
+static void     contact_widget_name_notify_cb              (EmpathyContactWidget  *information);
+static void     contact_widget_presence_notify_cb          (EmpathyContactWidget  *information);
+static void     contact_widget_avatar_notify_cb            (EmpathyContactWidget  *information);
+static void     contact_widget_groups_setup                (EmpathyContactWidget  *information);
+static void     contact_widget_model_setup                 (EmpathyContactWidget  *information);
+static void     contact_widget_model_populate_columns      (EmpathyContactWidget  *information);
+static void     contact_widget_groups_populate_data        (EmpathyContactWidget  *information);
+static void     contact_widget_groups_notify_cb            (EmpathyContactWidget  *information);
+static gboolean contact_widget_model_find_name             (EmpathyContactWidget  *information,
+                                                           const gchar           *name,
+                                                           GtkTreeIter           *iter);
+static gboolean contact_widget_model_find_name_foreach     (GtkTreeModel          *model,
+                                                           GtkTreePath           *path,
+                                                           GtkTreeIter           *iter,
+                                                           FindName              *data);
+static GList *  contact_widget_model_find_selected         (EmpathyContactWidget  *information);
+static gboolean contact_widget_model_find_selected_foreach (GtkTreeModel          *model,
+                                                           GtkTreePath           *path,
+                                                           GtkTreeIter           *iter,
+                                                           FindSelected          *data);
+static void     contact_widget_cell_toggled                (GtkCellRendererToggle *cell,
+                                                           gchar                 *path_string,
+                                                           EmpathyContactWidget  *information);
+static void     contact_widget_entry_alias_changed_cb      (GtkEditable           *editable,
+                                                           EmpathyContactWidget  *information);
+static void     contact_widget_entry_group_changed_cb      (GtkEditable           *editable,
+                                                           EmpathyContactWidget  *information);
+static void     contact_widget_entry_group_activate_cb     (GtkEntry              *entry,
+                                                           EmpathyContactWidget  *information);
+static void     contact_widget_button_group_clicked_cb     (GtkButton             *button,
+                                                           EmpathyContactWidget  *information);
+static void     contact_widget_details_setup               (EmpathyContactWidget  *information);
+static void     contact_widget_client_setup                (EmpathyContactWidget  *information);
+
+enum {
+       COL_NAME,
+       COL_ENABLED,
+       COL_EDITABLE,
+       COL_COUNT
+};
+
+GtkWidget *
+empathy_contact_widget_new (GossipContact *contact)
+{
+       EmpathyContactWidget *information;
+       GladeXML             *glade;
+       GossipContact        *user_contact;
+
+       g_return_val_if_fail (GOSSIP_IS_CONTACT (contact), NULL);
+
+       information = g_slice_new0 (EmpathyContactWidget);
+       information->contact = g_object_ref (contact);
+       user_contact = gossip_contact_get_user (contact);
+       information->is_user = gossip_contact_equal (contact, user_contact);
+
+       glade = gossip_glade_get_file ("empathy-contact-widget.glade",
+                                      "vbox_contact_widget",
+                                      NULL,
+                                      "vbox_contact_widget", &information->vbox_contact_widget,
+                                      "vbox_contact", &information->vbox_contact,
+                                      "label_id", &information->label_id,
+                                      "entry_alias", &information->entry_alias,
+                                      "image_state", &information->image_state,
+                                      "label_status", &information->label_status,
+                                      "table_contact", &information->table_contact,
+                                      "hbox_contact", &information->hbox_contact,
+                                      "vbox_groups", &information->vbox_groups,
+                                      "entry_group", &information->entry_group,
+                                      "button_group", &information->button_group,
+                                      "treeview_groups", &information->treeview_groups,
+                                      "vbox_details", &information->vbox_details,
+                                      "table_details", &information->table_details,
+                                      "hbox_details_requested", &information->hbox_details_requested,
+                                      "vbox_client", &information->vbox_client,
+                                      "table_client", &information->table_client,
+                                      "hbox_client_requested", &information->hbow_client_requested,
+                                      NULL);
+
+       gossip_glade_connect (glade,
+                             information,
+                             "vbox_contact_widget", "destroy", contact_widget_destroy_cb,
+                             "entry_alias", "changed", contact_widget_entry_alias_changed_cb,
+                             "entry_group", "changed", contact_widget_entry_group_changed_cb,
+                             "entry_group", "activate", contact_widget_entry_group_activate_cb,
+                             "button_group", "clicked", contact_widget_button_group_clicked_cb,
+                             NULL);
+
+       g_object_unref (glade);
+
+       g_object_set_data (G_OBJECT (information->vbox_contact_widget),
+                          "EmpathyContactWidget",
+                          information);
+
+       contact_widget_contact_setup (information);
+       contact_widget_groups_setup (information);
+       contact_widget_details_setup (information);
+       contact_widget_client_setup (information);
+
+       gtk_widget_show (information->vbox_contact_widget);
+
+       return information->vbox_contact_widget;
+}
+
+void
+empathy_contact_widget_save (GtkWidget *widget)
+{
+       EmpathyContactWidget *information;
+       const gchar          *name;
+       GList                *groups;
+
+       g_return_if_fail (GTK_IS_WIDGET (widget));
+
+       information = g_object_get_data (G_OBJECT (widget), "EmpathyContactWidget");
+       if (!information || !information->changes_made) {
+               return;
+       }
+
+       name = gtk_entry_get_text (GTK_ENTRY (information->entry_alias));
+       groups = contact_widget_model_find_selected (information);
+
+       gossip_contact_set_name (information->contact, name);
+       gossip_contact_set_groups (information->contact, groups);
+
+       g_list_foreach (groups, (GFunc) g_free, NULL);
+       g_list_free (groups);
+}
+
+static void
+contact_widget_destroy_cb (GtkWidget            *widget,
+                          EmpathyContactWidget *information)
+{
+       g_object_unref (information->contact);
+       g_slice_free (EmpathyContactWidget, information);
+}
+
+static void
+contact_widget_contact_setup (EmpathyContactWidget *information)
+{
+       g_signal_connect_swapped (information->contact, "notify::name",
+                                 G_CALLBACK (contact_widget_name_notify_cb),
+                                 information);
+       g_signal_connect_swapped (information->contact, "notify::presence",
+                                 G_CALLBACK (contact_widget_presence_notify_cb),
+                                 information);
+       g_signal_connect_swapped (information->contact, "notify::avatar",
+                                 G_CALLBACK (contact_widget_avatar_notify_cb),
+                                 information);
+
+       information->image_avatar = gtk_image_new ();
+       gtk_box_pack_end (GTK_BOX (information->hbox_contact),
+                         information->image_avatar,
+                         FALSE, FALSE,
+                         6);
+
+       gtk_label_set_text (GTK_LABEL (information->label_id),
+                           gossip_contact_get_id (information->contact));
+       contact_widget_name_notify_cb (information);
+       contact_widget_presence_notify_cb (information);
+       contact_widget_avatar_notify_cb (information);
+}
+
+static void
+contact_widget_name_notify_cb (EmpathyContactWidget *information)
+{
+       gtk_entry_set_text (GTK_ENTRY (information->entry_alias),
+                           gossip_contact_get_name (information->contact));
+}
+
+static void
+contact_widget_presence_notify_cb (EmpathyContactWidget *information)
+{
+       gtk_label_set_text (GTK_LABEL (information->label_status),
+                           gossip_contact_get_status (information->contact));
+       gtk_image_set_from_icon_name (GTK_IMAGE (information->image_state),
+                                     gossip_icon_name_for_contact (information->contact),
+                                     GTK_ICON_SIZE_BUTTON);
+
+}
+
+static void
+contact_widget_avatar_notify_cb (EmpathyContactWidget *information)
+{
+       GdkPixbuf *avatar_pixbuf;
+
+       avatar_pixbuf = gossip_pixbuf_avatar_from_contact_scaled (information->contact,
+                                                                 48, 48);
+
+       if (avatar_pixbuf) {
+               gtk_image_set_from_pixbuf (GTK_IMAGE (information->image_avatar),
+                                          avatar_pixbuf);
+               gtk_widget_show  (information->image_avatar);
+               g_object_unref (avatar_pixbuf);
+       } else {
+               gtk_widget_hide  (information->image_avatar);
+       }
+}
+
+static void
+contact_widget_groups_setup (EmpathyContactWidget *information)
+{
+       if (!information->is_user) {
+               contact_widget_model_setup (information);
+
+               g_signal_connect_swapped (information->contact, "notify::groups",
+                                         G_CALLBACK (contact_widget_groups_notify_cb),
+                                         information);
+               contact_widget_groups_populate_data (information);
+
+               gtk_widget_show (information->vbox_groups);
+       }
+}
+
+static void
+contact_widget_model_setup (EmpathyContactWidget *information)
+{
+       GtkTreeView      *view;
+       GtkListStore     *store;
+       GtkTreeSelection *selection;
+
+       view = GTK_TREE_VIEW (information->treeview_groups);
+
+       store = gtk_list_store_new (COL_COUNT,
+                                   G_TYPE_STRING,   /* name */
+                                   G_TYPE_BOOLEAN,  /* enabled */
+                                   G_TYPE_BOOLEAN); /* editable */
+
+       gtk_tree_view_set_model (view, GTK_TREE_MODEL (store));
+
+       selection = gtk_tree_view_get_selection (view);
+       gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE);
+
+       contact_widget_model_populate_columns (information);
+
+       gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (store),
+                                             COL_NAME, GTK_SORT_ASCENDING);
+
+       g_object_unref (store);
+}
+
+static void
+contact_widget_model_populate_columns (EmpathyContactWidget *information)
+{
+       GtkTreeView       *view;
+       GtkTreeModel      *model;
+       GtkTreeViewColumn *column;
+       GtkCellRenderer   *renderer;
+       guint              col_offset;
+
+       view = GTK_TREE_VIEW (information->treeview_groups);
+       model = gtk_tree_view_get_model (view);
+
+       renderer = gtk_cell_renderer_toggle_new ();
+       g_signal_connect (renderer, "toggled",
+                         G_CALLBACK (contact_widget_cell_toggled),
+                         information);
+
+       column = gtk_tree_view_column_new_with_attributes (_("Select"), renderer,
+                                                          "active", COL_ENABLED,
+                                                          NULL);
+
+       gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_FIXED);
+       gtk_tree_view_column_set_fixed_width (column, 50);
+       gtk_tree_view_append_column (view, column);
+
+       renderer = gtk_cell_renderer_text_new ();
+       col_offset = gtk_tree_view_insert_column_with_attributes (view,
+                                                                 -1, _("Group"),
+                                                                 renderer,
+                                                                 "text", COL_NAME,
+                                                                 /* "editable", COL_EDITABLE, */
+                                                                 NULL);
+
+       g_object_set_data (G_OBJECT (renderer),
+                          "column", GINT_TO_POINTER (COL_NAME));
+
+       column = gtk_tree_view_get_column (view, col_offset - 1);
+       gtk_tree_view_column_set_sort_column_id (column, COL_NAME);
+       gtk_tree_view_column_set_resizable (column,FALSE);
+       gtk_tree_view_column_set_clickable (GTK_TREE_VIEW_COLUMN (column), TRUE);
+
+       if (information->renderer) {
+               g_object_unref (information->renderer);
+       }
+
+       information->renderer = g_object_ref (renderer);
+}
+
+static void
+contact_widget_groups_populate_data (EmpathyContactWidget *information)
+{
+       EmpathyContactManager *manager;
+       GtkTreeView           *view;
+       GtkListStore          *store;
+       GtkTreeIter            iter;
+       GList                 *groups, *l;
+       GList                 *my_groups = NULL;
+       GList                 *all_groups;
+
+       view = GTK_TREE_VIEW (information->treeview_groups);
+       store = GTK_LIST_STORE (gtk_tree_view_get_model (view));
+
+       manager = empathy_contact_manager_new ();
+       all_groups = empathy_contact_manager_get_groups (manager);
+       groups = gossip_contact_get_groups (information->contact);
+
+       for (l = groups; l; l = l->next) {
+               const gchar *group_str;
+
+               group_str = l->data;
+               if (strcmp (group_str, _("Unsorted")) == 0) {
+                       continue;
+               }
+
+               my_groups = g_list_append (my_groups, g_strdup (group_str));
+       }
+
+       for (l = all_groups; l; l = l->next) {
+               const gchar *group_str;
+               gboolean     enabled;
+
+               group_str = l->data;
+               if (strcmp (group_str, _("Unsorted")) == 0) {
+                       continue;
+               }
+
+               enabled = g_list_find_custom (my_groups,
+                                             group_str,
+                                             (GCompareFunc) strcmp) != NULL;
+
+               gtk_list_store_append (store, &iter);
+               gtk_list_store_set (store, &iter,
+                                   COL_NAME, group_str,
+                                   COL_EDITABLE, TRUE,
+                                   COL_ENABLED, enabled,
+                                   -1);
+       }
+
+       g_list_foreach (my_groups, (GFunc) g_free, NULL);
+       g_list_free (my_groups);
+
+       g_list_free (all_groups);
+}
+
+static void
+contact_widget_groups_notify_cb (EmpathyContactWidget *information)
+{
+       /* FIXME: not implemented */
+}
+
+static gboolean
+contact_widget_model_find_name (EmpathyContactWidget *information,
+                               const gchar          *name,
+                               GtkTreeIter          *iter)
+{
+       GtkTreeView  *view;
+       GtkTreeModel *model;
+       FindName      data;
+
+       if (G_STR_EMPTY (name)) {
+               return FALSE;
+       }
+
+       data.information = information;
+       data.name = name;
+       data.found = FALSE;
+
+       view = GTK_TREE_VIEW (information->treeview_groups);
+       model = gtk_tree_view_get_model (view);
+
+       gtk_tree_model_foreach (model,
+                               (GtkTreeModelForeachFunc) contact_widget_model_find_name_foreach,
+                               &data);
+
+       if (data.found == TRUE) {
+               *iter = data.found_iter;
+               return TRUE;
+       }
+
+       return FALSE;
+}
+
+static gboolean
+contact_widget_model_find_name_foreach (GtkTreeModel *model,
+                                       GtkTreePath  *path,
+                                       GtkTreeIter  *iter,
+                                       FindName     *data)
+{
+       gchar *name;
+
+       gtk_tree_model_get (model, iter,
+                           COL_NAME, &name,
+                           -1);
+
+       if (!name) {
+               return FALSE;
+       }
+
+       if (data->name && strcmp (data->name, name) == 0) {
+               data->found = TRUE;
+               data->found_iter = *iter;
+
+               g_free (name);
+
+               return TRUE;
+       }
+
+       g_free (name);
+
+       return FALSE;
+}
+
+static GList *
+contact_widget_model_find_selected (EmpathyContactWidget *information)
+{
+       GtkTreeView  *view;
+       GtkTreeModel *model;
+       FindSelected  data;
+
+       data.information = information;
+       data.list = NULL;
+
+       view = GTK_TREE_VIEW (information->treeview_groups);
+       model = gtk_tree_view_get_model (view);
+
+       gtk_tree_model_foreach (model,
+                               (GtkTreeModelForeachFunc) contact_widget_model_find_selected_foreach,
+                               &data);
+
+       return data.list;
+}
+
+static gboolean
+contact_widget_model_find_selected_foreach (GtkTreeModel *model,
+                                           GtkTreePath  *path,
+                                           GtkTreeIter  *iter,
+                                           FindSelected *data)
+{
+       gchar    *name;
+       gboolean  selected;
+
+       gtk_tree_model_get (model, iter,
+                           COL_NAME, &name,
+                           COL_ENABLED, &selected,
+                           -1);
+
+       if (!name) {
+               return FALSE;
+       }
+
+       if (selected) {
+               data->list = g_list_append (data->list, name);
+               return FALSE;
+       }
+
+       g_free (name);
+
+       return FALSE;
+}
+
+static void
+contact_widget_cell_toggled (GtkCellRendererToggle *cell,
+                            gchar                 *path_string,
+                            EmpathyContactWidget  *information)
+{
+       GtkTreeView  *view;
+       GtkTreeModel *model;
+       GtkListStore *store;
+       GtkTreePath  *path;
+       GtkTreeIter   iter;
+       gboolean      enabled;
+
+       view = GTK_TREE_VIEW (information->treeview_groups);
+       model = gtk_tree_view_get_model (view);
+       store = GTK_LIST_STORE (model);
+
+       path = gtk_tree_path_new_from_string (path_string);
+
+       gtk_tree_model_get_iter (model, &iter, path);
+       gtk_tree_model_get (model, &iter, COL_ENABLED, &enabled, -1);
+
+       enabled ^= 1;
+
+       gtk_list_store_set (store, &iter, COL_ENABLED, enabled, -1);
+       gtk_tree_path_free (path);
+
+       information->changes_made = TRUE;
+}
+
+static void
+contact_widget_entry_alias_changed_cb (GtkEditable           *editable,
+                                      EmpathyContactWidget  *information)
+{
+       information->changes_made = TRUE;
+}
+
+static void
+contact_widget_entry_group_changed_cb (GtkEditable           *editable,
+                                      EmpathyContactWidget  *information)
+{
+       GtkTreeIter  iter;
+       const gchar *group;
+
+       group = gtk_entry_get_text (GTK_ENTRY (information->entry_group));
+
+       if (contact_widget_model_find_name (information, group, &iter)) {
+               gtk_widget_set_sensitive (GTK_WIDGET (information->button_group), FALSE);
+
+       } else {
+               gtk_widget_set_sensitive (GTK_WIDGET (information->button_group),
+                                         !G_STR_EMPTY (group));
+       }
+}
+
+static void
+contact_widget_entry_group_activate_cb (GtkEntry              *entry,
+                                       EmpathyContactWidget  *information)
+{
+       gtk_widget_activate (GTK_WIDGET (information->button_group));
+}
+
+static void
+contact_widget_button_group_clicked_cb (GtkButton             *button,
+                                       EmpathyContactWidget  *information)
+{
+       GtkTreeView  *view;
+       GtkListStore *store;
+       GtkTreeIter   iter;
+       const gchar  *group;
+
+       view = GTK_TREE_VIEW (information->treeview_groups);
+       store = GTK_LIST_STORE (gtk_tree_view_get_model (view));
+
+       group = gtk_entry_get_text (GTK_ENTRY (information->entry_group));
+
+       gtk_list_store_append (store, &iter);
+       gtk_list_store_set (store, &iter,
+                           COL_NAME, group,
+                           COL_ENABLED, TRUE,
+                           -1);
+
+       information->changes_made = TRUE;
+}
+
+static void
+contact_widget_details_setup (EmpathyContactWidget *information)
+{
+       /* FIXME: Needs new telepathy spec */
+}
+
+static void
+contact_widget_client_setup (EmpathyContactWidget *information)
+{
+       /* FIXME: Needs new telepathy spec */
+}
+
diff --git a/libempathy-gtk/empathy-contact-widget.glade b/libempathy-gtk/empathy-contact-widget.glade
new file mode 100644 (file)
index 0000000..178c52e
--- /dev/null
@@ -0,0 +1,1007 @@
+<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
+<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd">
+
+<glade-interface>
+
+<widget class="GtkWindow" id="contact_window">
+  <property name="visible">True</property>
+  <property name="title" translatable="yes">Contact information</property>
+  <property name="type">GTK_WINDOW_TOPLEVEL</property>
+  <property name="window_position">GTK_WIN_POS_NONE</property>
+  <property name="modal">False</property>
+  <property name="resizable">True</property>
+  <property name="destroy_with_parent">False</property>
+  <property name="decorated">True</property>
+  <property name="skip_taskbar_hint">False</property>
+  <property name="skip_pager_hint">False</property>
+  <property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property>
+  <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
+  <property name="focus_on_map">True</property>
+  <property name="urgency_hint">False</property>
+
+  <child>
+    <widget class="GtkVBox" id="vbox_contact_widget">
+      <property name="homogeneous">False</property>
+      <property name="spacing">0</property>
+
+      <child>
+       <widget class="GtkHBox" id="hbox_contact">
+         <property name="visible">True</property>
+         <property name="homogeneous">False</property>
+         <property name="spacing">0</property>
+
+         <child>
+           <widget class="GtkVBox" id="vbox_contact">
+             <property name="visible">True</property>
+             <property name="homogeneous">False</property>
+             <property name="spacing">6</property>
+
+             <child>
+               <widget class="GtkLabel" id="label654">
+                 <property name="visible">True</property>
+                 <property name="label" translatable="yes">&lt;b&gt;Contact&lt;/b&gt;</property>
+                 <property name="use_underline">False</property>
+                 <property name="use_markup">True</property>
+                 <property name="justify">GTK_JUSTIFY_LEFT</property>
+                 <property name="wrap">False</property>
+                 <property name="selectable">False</property>
+                 <property name="xalign">0</property>
+                 <property name="yalign">0.5</property>
+                 <property name="xpad">0</property>
+                 <property name="ypad">0</property>
+                 <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+                 <property name="width_chars">-1</property>
+                 <property name="single_line_mode">False</property>
+                 <property name="angle">0</property>
+               </widget>
+               <packing>
+                 <property name="padding">0</property>
+                 <property name="expand">False</property>
+                 <property name="fill">False</property>
+               </packing>
+             </child>
+
+             <child>
+               <widget class="GtkAlignment" id="alignment31">
+                 <property name="visible">True</property>
+                 <property name="xalign">0.5</property>
+                 <property name="yalign">0.5</property>
+                 <property name="xscale">1</property>
+                 <property name="yscale">1</property>
+                 <property name="top_padding">0</property>
+                 <property name="bottom_padding">0</property>
+                 <property name="left_padding">12</property>
+                 <property name="right_padding">0</property>
+
+                 <child>
+                   <widget class="GtkTable" id="table_contact">
+                     <property name="visible">True</property>
+                     <property name="n_rows">3</property>
+                     <property name="n_columns">2</property>
+                     <property name="homogeneous">False</property>
+                     <property name="row_spacing">6</property>
+                     <property name="column_spacing">12</property>
+
+                     <child>
+                       <widget class="GtkLabel" id="label655">
+                         <property name="visible">True</property>
+                         <property name="label" translatable="yes">Identifier:</property>
+                         <property name="use_underline">False</property>
+                         <property name="use_markup">False</property>
+                         <property name="justify">GTK_JUSTIFY_LEFT</property>
+                         <property name="wrap">False</property>
+                         <property name="selectable">False</property>
+                         <property name="xalign">0</property>
+                         <property name="yalign">0.5</property>
+                         <property name="xpad">0</property>
+                         <property name="ypad">0</property>
+                         <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+                         <property name="width_chars">-1</property>
+                         <property name="single_line_mode">False</property>
+                         <property name="angle">0</property>
+                       </widget>
+                       <packing>
+                         <property name="left_attach">0</property>
+                         <property name="right_attach">1</property>
+                         <property name="top_attach">0</property>
+                         <property name="bottom_attach">1</property>
+                         <property name="x_options">fill</property>
+                         <property name="y_options"></property>
+                       </packing>
+                     </child>
+
+                     <child>
+                       <widget class="GtkLabel" id="label658">
+                         <property name="visible">True</property>
+                         <property name="label" translatable="yes">Alias:</property>
+                         <property name="use_underline">False</property>
+                         <property name="use_markup">False</property>
+                         <property name="justify">GTK_JUSTIFY_LEFT</property>
+                         <property name="wrap">False</property>
+                         <property name="selectable">False</property>
+                         <property name="xalign">0</property>
+                         <property name="yalign">0.5</property>
+                         <property name="xpad">0</property>
+                         <property name="ypad">0</property>
+                         <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+                         <property name="width_chars">-1</property>
+                         <property name="single_line_mode">False</property>
+                         <property name="angle">0</property>
+                       </widget>
+                       <packing>
+                         <property name="left_attach">0</property>
+                         <property name="right_attach">1</property>
+                         <property name="top_attach">1</property>
+                         <property name="bottom_attach">2</property>
+                         <property name="x_options">fill</property>
+                         <property name="y_options"></property>
+                       </packing>
+                     </child>
+
+                     <child>
+                       <widget class="GtkLabel" id="label_id">
+                         <property name="visible">True</property>
+                         <property name="label" translatable="yes"></property>
+                         <property name="use_underline">False</property>
+                         <property name="use_markup">False</property>
+                         <property name="justify">GTK_JUSTIFY_LEFT</property>
+                         <property name="wrap">False</property>
+                         <property name="selectable">False</property>
+                         <property name="xalign">0</property>
+                         <property name="yalign">0.5</property>
+                         <property name="xpad">0</property>
+                         <property name="ypad">0</property>
+                         <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+                         <property name="width_chars">-1</property>
+                         <property name="single_line_mode">False</property>
+                         <property name="angle">0</property>
+                       </widget>
+                       <packing>
+                         <property name="left_attach">1</property>
+                         <property name="right_attach">2</property>
+                         <property name="top_attach">0</property>
+                         <property name="bottom_attach">1</property>
+                         <property name="y_options"></property>
+                       </packing>
+                     </child>
+
+                     <child>
+                       <widget class="GtkEntry" id="entry_alias">
+                         <property name="visible">True</property>
+                         <property name="can_focus">True</property>
+                         <property name="editable">True</property>
+                         <property name="visibility">True</property>
+                         <property name="max_length">0</property>
+                         <property name="text" translatable="yes"></property>
+                         <property name="has_frame">True</property>
+                         <property name="invisible_char">●</property>
+                         <property name="activates_default">False</property>
+                       </widget>
+                       <packing>
+                         <property name="left_attach">1</property>
+                         <property name="right_attach">2</property>
+                         <property name="top_attach">1</property>
+                         <property name="bottom_attach">2</property>
+                         <property name="y_options"></property>
+                       </packing>
+                     </child>
+
+                     <child>
+                       <widget class="GtkLabel" id="label680">
+                         <property name="visible">True</property>
+                         <property name="label" translatable="yes">Presence:</property>
+                         <property name="use_underline">False</property>
+                         <property name="use_markup">False</property>
+                         <property name="justify">GTK_JUSTIFY_LEFT</property>
+                         <property name="wrap">False</property>
+                         <property name="selectable">False</property>
+                         <property name="xalign">0</property>
+                         <property name="yalign">0.5</property>
+                         <property name="xpad">0</property>
+                         <property name="ypad">0</property>
+                         <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+                         <property name="width_chars">-1</property>
+                         <property name="single_line_mode">False</property>
+                         <property name="angle">0</property>
+                       </widget>
+                       <packing>
+                         <property name="left_attach">0</property>
+                         <property name="right_attach">1</property>
+                         <property name="top_attach">2</property>
+                         <property name="bottom_attach">3</property>
+                         <property name="x_options">fill</property>
+                         <property name="y_options"></property>
+                       </packing>
+                     </child>
+
+                     <child>
+                       <widget class="GtkHBox" id="hbox186">
+                         <property name="visible">True</property>
+                         <property name="homogeneous">False</property>
+                         <property name="spacing">6</property>
+
+                         <child>
+                           <widget class="GtkImage" id="image_state">
+                             <property name="visible">True</property>
+                             <property name="xalign">0.5</property>
+                             <property name="yalign">0.5</property>
+                             <property name="xpad">0</property>
+                             <property name="ypad">0</property>
+                           </widget>
+                           <packing>
+                             <property name="padding">0</property>
+                             <property name="expand">False</property>
+                             <property name="fill">False</property>
+                           </packing>
+                         </child>
+
+                         <child>
+                           <widget class="GtkLabel" id="label_status">
+                             <property name="visible">True</property>
+                             <property name="label" translatable="yes"></property>
+                             <property name="use_underline">False</property>
+                             <property name="use_markup">True</property>
+                             <property name="justify">GTK_JUSTIFY_LEFT</property>
+                             <property name="wrap">True</property>
+                             <property name="selectable">False</property>
+                             <property name="xalign">0</property>
+                             <property name="yalign">0.5</property>
+                             <property name="xpad">0</property>
+                             <property name="ypad">0</property>
+                             <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+                             <property name="width_chars">-1</property>
+                             <property name="single_line_mode">False</property>
+                             <property name="angle">0</property>
+                           </widget>
+                           <packing>
+                             <property name="padding">0</property>
+                             <property name="expand">True</property>
+                             <property name="fill">True</property>
+                           </packing>
+                         </child>
+                       </widget>
+                       <packing>
+                         <property name="left_attach">1</property>
+                         <property name="right_attach">2</property>
+                         <property name="top_attach">2</property>
+                         <property name="bottom_attach">3</property>
+                         <property name="x_options">fill</property>
+                         <property name="y_options">fill</property>
+                       </packing>
+                     </child>
+                   </widget>
+                 </child>
+               </widget>
+               <packing>
+                 <property name="padding">0</property>
+                 <property name="expand">False</property>
+                 <property name="fill">False</property>
+               </packing>
+             </child>
+           </widget>
+           <packing>
+             <property name="padding">0</property>
+             <property name="expand">True</property>
+             <property name="fill">True</property>
+           </packing>
+         </child>
+
+         <child>
+           <placeholder/>
+         </child>
+       </widget>
+       <packing>
+         <property name="padding">0</property>
+         <property name="expand">False</property>
+         <property name="fill">True</property>
+       </packing>
+      </child>
+
+      <child>
+       <widget class="GtkVBox" id="vbox_groups">
+         <property name="homogeneous">False</property>
+         <property name="spacing">6</property>
+
+         <child>
+           <widget class="GtkLabel" id="label672">
+             <property name="visible">True</property>
+             <property name="label" translatable="yes">&lt;b&gt;Groups&lt;/b&gt;</property>
+             <property name="use_underline">False</property>
+             <property name="use_markup">True</property>
+             <property name="justify">GTK_JUSTIFY_LEFT</property>
+             <property name="wrap">False</property>
+             <property name="selectable">False</property>
+             <property name="xalign">0</property>
+             <property name="yalign">0.5</property>
+             <property name="xpad">0</property>
+             <property name="ypad">0</property>
+             <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+             <property name="width_chars">-1</property>
+             <property name="single_line_mode">False</property>
+             <property name="angle">0</property>
+           </widget>
+           <packing>
+             <property name="padding">0</property>
+             <property name="expand">False</property>
+             <property name="fill">False</property>
+           </packing>
+         </child>
+
+         <child>
+           <widget class="GtkAlignment" id="alignment33">
+             <property name="visible">True</property>
+             <property name="xalign">0.5</property>
+             <property name="yalign">0.5</property>
+             <property name="xscale">1</property>
+             <property name="yscale">1</property>
+             <property name="top_padding">0</property>
+             <property name="bottom_padding">0</property>
+             <property name="left_padding">12</property>
+             <property name="right_padding">0</property>
+
+             <child>
+               <widget class="GtkVBox" id="vbox224">
+                 <property name="visible">True</property>
+                 <property name="homogeneous">False</property>
+                 <property name="spacing">6</property>
+
+                 <child>
+                   <widget class="GtkLabel" id="label679">
+                     <property name="visible">True</property>
+                     <property name="label" translatable="yes">Select the groups you want this contact to appear in, you can select more than one group or no groups.</property>
+                     <property name="use_underline">False</property>
+                     <property name="use_markup">True</property>
+                     <property name="justify">GTK_JUSTIFY_LEFT</property>
+                     <property name="wrap">True</property>
+                     <property name="selectable">False</property>
+                     <property name="xalign">0</property>
+                     <property name="yalign">0.5</property>
+                     <property name="xpad">0</property>
+                     <property name="ypad">0</property>
+                     <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+                     <property name="width_chars">-1</property>
+                     <property name="single_line_mode">False</property>
+                     <property name="angle">0</property>
+                   </widget>
+                   <packing>
+                     <property name="padding">0</property>
+                     <property name="expand">False</property>
+                     <property name="fill">False</property>
+                   </packing>
+                 </child>
+
+                 <child>
+                   <widget class="GtkHBox" id="hbox188">
+                     <property name="visible">True</property>
+                     <property name="homogeneous">False</property>
+                     <property name="spacing">12</property>
+
+                     <child>
+                       <widget class="GtkEntry" id="entry_group">
+                         <property name="visible">True</property>
+                         <property name="can_focus">True</property>
+                         <property name="editable">True</property>
+                         <property name="visibility">True</property>
+                         <property name="max_length">0</property>
+                         <property name="text" translatable="yes"></property>
+                         <property name="has_frame">True</property>
+                         <property name="invisible_char">*</property>
+                         <property name="activates_default">False</property>
+                       </widget>
+                       <packing>
+                         <property name="padding">0</property>
+                         <property name="expand">True</property>
+                         <property name="fill">True</property>
+                       </packing>
+                     </child>
+
+                     <child>
+                       <widget class="GtkButton" id="button_group">
+                         <property name="visible">True</property>
+                         <property name="sensitive">False</property>
+                         <property name="can_focus">True</property>
+                         <property name="label">_Add Group</property>
+                         <property name="use_underline">True</property>
+                         <property name="relief">GTK_RELIEF_NORMAL</property>
+                         <property name="focus_on_click">True</property>
+                       </widget>
+                       <packing>
+                         <property name="padding">0</property>
+                         <property name="expand">False</property>
+                         <property name="fill">False</property>
+                       </packing>
+                     </child>
+                   </widget>
+                   <packing>
+                     <property name="padding">0</property>
+                     <property name="expand">False</property>
+                     <property name="fill">False</property>
+                   </packing>
+                 </child>
+
+                 <child>
+                   <widget class="GtkScrolledWindow" id="scrolledwindow17">
+                     <property name="height_request">100</property>
+                     <property name="visible">True</property>
+                     <property name="can_focus">True</property>
+                     <property name="hscrollbar_policy">GTK_POLICY_NEVER</property>
+                     <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+                     <property name="shadow_type">GTK_SHADOW_IN</property>
+                     <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
+
+                     <child>
+                       <widget class="GtkTreeView" id="treeview_groups">
+                         <property name="visible">True</property>
+                         <property name="can_focus">True</property>
+                         <property name="headers_visible">False</property>
+                         <property name="rules_hint">False</property>
+                         <property name="reorderable">False</property>
+                         <property name="enable_search">False</property>
+                         <property name="fixed_height_mode">False</property>
+                         <property name="hover_selection">False</property>
+                         <property name="hover_expand">False</property>
+                       </widget>
+                     </child>
+                   </widget>
+                   <packing>
+                     <property name="padding">0</property>
+                     <property name="expand">True</property>
+                     <property name="fill">True</property>
+                   </packing>
+                 </child>
+               </widget>
+             </child>
+           </widget>
+           <packing>
+             <property name="padding">0</property>
+             <property name="expand">True</property>
+             <property name="fill">True</property>
+           </packing>
+         </child>
+       </widget>
+       <packing>
+         <property name="padding">0</property>
+         <property name="expand">True</property>
+         <property name="fill">True</property>
+       </packing>
+      </child>
+
+      <child>
+       <widget class="GtkVBox" id="vbox_details">
+         <property name="homogeneous">False</property>
+         <property name="spacing">6</property>
+
+         <child>
+           <widget class="GtkLabel" id="label649">
+             <property name="visible">True</property>
+             <property name="label" translatable="yes">&lt;b&gt;Contact Details&lt;/b&gt;</property>
+             <property name="use_underline">False</property>
+             <property name="use_markup">True</property>
+             <property name="justify">GTK_JUSTIFY_LEFT</property>
+             <property name="wrap">False</property>
+             <property name="selectable">False</property>
+             <property name="xalign">0</property>
+             <property name="yalign">0.5</property>
+             <property name="xpad">0</property>
+             <property name="ypad">0</property>
+             <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+             <property name="width_chars">-1</property>
+             <property name="single_line_mode">False</property>
+             <property name="angle">0</property>
+           </widget>
+           <packing>
+             <property name="padding">0</property>
+             <property name="expand">False</property>
+             <property name="fill">False</property>
+           </packing>
+         </child>
+
+         <child>
+           <widget class="GtkAlignment" id="alignment30">
+             <property name="visible">True</property>
+             <property name="xalign">0.5</property>
+             <property name="yalign">0.5</property>
+             <property name="xscale">1</property>
+             <property name="yscale">1</property>
+             <property name="top_padding">0</property>
+             <property name="bottom_padding">0</property>
+             <property name="left_padding">12</property>
+             <property name="right_padding">0</property>
+
+             <child>
+               <widget class="GtkVBox" id="vbox218">
+                 <property name="visible">True</property>
+                 <property name="homogeneous">False</property>
+                 <property name="spacing">6</property>
+
+                 <child>
+                   <widget class="GtkTable" id="table_details">
+                     <property name="n_rows">4</property>
+                     <property name="n_columns">2</property>
+                     <property name="homogeneous">False</property>
+                     <property name="row_spacing">6</property>
+                     <property name="column_spacing">12</property>
+
+                     <child>
+                       <widget class="GtkLabel" id="label652">
+                         <property name="label" translatable="yes">Birthday:</property>
+                         <property name="use_underline">False</property>
+                         <property name="use_markup">False</property>
+                         <property name="justify">GTK_JUSTIFY_LEFT</property>
+                         <property name="wrap">False</property>
+                         <property name="selectable">False</property>
+                         <property name="xalign">0</property>
+                         <property name="yalign">0.5</property>
+                         <property name="xpad">0</property>
+                         <property name="ypad">0</property>
+                         <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+                         <property name="width_chars">-1</property>
+                         <property name="single_line_mode">False</property>
+                         <property name="angle">0</property>
+                       </widget>
+                       <packing>
+                         <property name="left_attach">0</property>
+                         <property name="right_attach">1</property>
+                         <property name="top_attach">3</property>
+                         <property name="bottom_attach">4</property>
+                         <property name="x_options">fill</property>
+                         <property name="y_options"></property>
+                       </packing>
+                     </child>
+
+                     <child>
+                       <widget class="GtkLabel" id="label651">
+                         <property name="label" translatable="yes">Web site:</property>
+                         <property name="use_underline">False</property>
+                         <property name="use_markup">False</property>
+                         <property name="justify">GTK_JUSTIFY_LEFT</property>
+                         <property name="wrap">False</property>
+                         <property name="selectable">False</property>
+                         <property name="xalign">0</property>
+                         <property name="yalign">0.5</property>
+                         <property name="xpad">0</property>
+                         <property name="ypad">0</property>
+                         <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+                         <property name="width_chars">-1</property>
+                         <property name="single_line_mode">False</property>
+                         <property name="angle">0</property>
+                       </widget>
+                       <packing>
+                         <property name="left_attach">0</property>
+                         <property name="right_attach">1</property>
+                         <property name="top_attach">2</property>
+                         <property name="bottom_attach">3</property>
+                         <property name="x_options">fill</property>
+                         <property name="y_options"></property>
+                       </packing>
+                     </child>
+
+                     <child>
+                       <widget class="GtkLabel" id="label650">
+                         <property name="label" translatable="yes">Email:</property>
+                         <property name="use_underline">False</property>
+                         <property name="use_markup">False</property>
+                         <property name="justify">GTK_JUSTIFY_LEFT</property>
+                         <property name="wrap">False</property>
+                         <property name="selectable">False</property>
+                         <property name="xalign">0</property>
+                         <property name="yalign">0.5</property>
+                         <property name="xpad">0</property>
+                         <property name="ypad">0</property>
+                         <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+                         <property name="width_chars">-1</property>
+                         <property name="single_line_mode">False</property>
+                         <property name="angle">0</property>
+                       </widget>
+                       <packing>
+                         <property name="left_attach">0</property>
+                         <property name="right_attach">1</property>
+                         <property name="top_attach">1</property>
+                         <property name="bottom_attach">2</property>
+                         <property name="x_options">fill</property>
+                         <property name="y_options"></property>
+                       </packing>
+                     </child>
+
+                     <child>
+                       <widget class="GtkLabel" id="label670">
+                         <property name="label" translatable="yes">Fullname:</property>
+                         <property name="use_underline">False</property>
+                         <property name="use_markup">False</property>
+                         <property name="justify">GTK_JUSTIFY_LEFT</property>
+                         <property name="wrap">False</property>
+                         <property name="selectable">False</property>
+                         <property name="xalign">0</property>
+                         <property name="yalign">0.5</property>
+                         <property name="xpad">0</property>
+                         <property name="ypad">0</property>
+                         <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+                         <property name="width_chars">-1</property>
+                         <property name="single_line_mode">False</property>
+                         <property name="angle">0</property>
+                       </widget>
+                       <packing>
+                         <property name="left_attach">0</property>
+                         <property name="right_attach">1</property>
+                         <property name="top_attach">0</property>
+                         <property name="bottom_attach">1</property>
+                         <property name="x_options">fill</property>
+                         <property name="y_options"></property>
+                       </packing>
+                     </child>
+                   </widget>
+                   <packing>
+                     <property name="padding">0</property>
+                     <property name="expand">True</property>
+                     <property name="fill">True</property>
+                   </packing>
+                 </child>
+
+                 <child>
+                   <widget class="GtkHBox" id="hbox_details_requested">
+                     <property name="visible">True</property>
+                     <property name="homogeneous">False</property>
+                     <property name="spacing">6</property>
+
+                     <child>
+                       <widget class="GtkImage" id="image885">
+                         <property name="visible">True</property>
+                         <property name="stock">gtk-dialog-info</property>
+                         <property name="icon_size">4</property>
+                         <property name="xalign">0.5</property>
+                         <property name="yalign">0.5</property>
+                         <property name="xpad">0</property>
+                         <property name="ypad">0</property>
+                       </widget>
+                       <packing>
+                         <property name="padding">0</property>
+                         <property name="expand">False</property>
+                         <property name="fill">False</property>
+                       </packing>
+                     </child>
+
+                     <child>
+                       <widget class="GtkLabel" id="label653">
+                         <property name="visible">True</property>
+                         <property name="label" translatable="yes">Information requested...</property>
+                         <property name="use_underline">False</property>
+                         <property name="use_markup">True</property>
+                         <property name="justify">GTK_JUSTIFY_LEFT</property>
+                         <property name="wrap">True</property>
+                         <property name="selectable">False</property>
+                         <property name="xalign">0</property>
+                         <property name="yalign">0.5</property>
+                         <property name="xpad">0</property>
+                         <property name="ypad">0</property>
+                         <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+                         <property name="width_chars">-1</property>
+                         <property name="single_line_mode">False</property>
+                         <property name="angle">0</property>
+                       </widget>
+                       <packing>
+                         <property name="padding">0</property>
+                         <property name="expand">True</property>
+                         <property name="fill">True</property>
+                       </packing>
+                     </child>
+                   </widget>
+                   <packing>
+                     <property name="padding">0</property>
+                     <property name="expand">False</property>
+                     <property name="fill">False</property>
+                   </packing>
+                 </child>
+               </widget>
+             </child>
+           </widget>
+           <packing>
+             <property name="padding">0</property>
+             <property name="expand">False</property>
+             <property name="fill">False</property>
+           </packing>
+         </child>
+       </widget>
+       <packing>
+         <property name="padding">0</property>
+         <property name="expand">False</property>
+         <property name="fill">True</property>
+       </packing>
+      </child>
+
+      <child>
+       <widget class="GtkVBox" id="vbox_client">
+         <property name="homogeneous">False</property>
+         <property name="spacing">6</property>
+
+         <child>
+           <widget class="GtkLabel" id="label662">
+             <property name="visible">True</property>
+             <property name="label" translatable="yes">&lt;b&gt;Client Information&lt;/b&gt;</property>
+             <property name="use_underline">False</property>
+             <property name="use_markup">True</property>
+             <property name="justify">GTK_JUSTIFY_LEFT</property>
+             <property name="wrap">False</property>
+             <property name="selectable">False</property>
+             <property name="xalign">0</property>
+             <property name="yalign">0.5</property>
+             <property name="xpad">0</property>
+             <property name="ypad">0</property>
+             <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+             <property name="width_chars">-1</property>
+             <property name="single_line_mode">False</property>
+             <property name="angle">0</property>
+           </widget>
+           <packing>
+             <property name="padding">0</property>
+             <property name="expand">False</property>
+             <property name="fill">False</property>
+           </packing>
+         </child>
+
+         <child>
+           <widget class="GtkAlignment" id="alignment32">
+             <property name="visible">True</property>
+             <property name="xalign">0.5</property>
+             <property name="yalign">0.5</property>
+             <property name="xscale">1</property>
+             <property name="yscale">1</property>
+             <property name="top_padding">0</property>
+             <property name="bottom_padding">0</property>
+             <property name="left_padding">12</property>
+             <property name="right_padding">0</property>
+
+             <child>
+               <widget class="GtkVBox" id="vbox222">
+                 <property name="visible">True</property>
+                 <property name="homogeneous">False</property>
+                 <property name="spacing">6</property>
+
+                 <child>
+                   <widget class="GtkTable" id="table_client">
+                     <property name="n_rows">3</property>
+                     <property name="n_columns">2</property>
+                     <property name="homogeneous">False</property>
+                     <property name="row_spacing">6</property>
+                     <property name="column_spacing">12</property>
+
+                     <child>
+                       <widget class="GtkLabel" id="label_os">
+                         <property name="can_focus">True</property>
+                         <property name="label" translatable="yes"></property>
+                         <property name="use_underline">False</property>
+                         <property name="use_markup">False</property>
+                         <property name="justify">GTK_JUSTIFY_LEFT</property>
+                         <property name="wrap">True</property>
+                         <property name="selectable">True</property>
+                         <property name="xalign">0</property>
+                         <property name="yalign">0.5</property>
+                         <property name="xpad">2</property>
+                         <property name="ypad">0</property>
+                         <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+                         <property name="width_chars">-1</property>
+                         <property name="single_line_mode">False</property>
+                         <property name="angle">0</property>
+                       </widget>
+                       <packing>
+                         <property name="left_attach">1</property>
+                         <property name="right_attach">2</property>
+                         <property name="top_attach">2</property>
+                         <property name="bottom_attach">3</property>
+                         <property name="y_options"></property>
+                       </packing>
+                     </child>
+
+                     <child>
+                       <widget class="GtkLabel" id="label_version">
+                         <property name="can_focus">True</property>
+                         <property name="label" translatable="yes"></property>
+                         <property name="use_underline">False</property>
+                         <property name="use_markup">False</property>
+                         <property name="justify">GTK_JUSTIFY_LEFT</property>
+                         <property name="wrap">True</property>
+                         <property name="selectable">True</property>
+                         <property name="xalign">0</property>
+                         <property name="yalign">0.5</property>
+                         <property name="xpad">2</property>
+                         <property name="ypad">0</property>
+                         <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+                         <property name="width_chars">-1</property>
+                         <property name="single_line_mode">False</property>
+                         <property name="angle">0</property>
+                       </widget>
+                       <packing>
+                         <property name="left_attach">1</property>
+                         <property name="right_attach">2</property>
+                         <property name="top_attach">1</property>
+                         <property name="bottom_attach">2</property>
+                         <property name="y_options"></property>
+                       </packing>
+                     </child>
+
+                     <child>
+                       <widget class="GtkLabel" id="label_client">
+                         <property name="can_focus">True</property>
+                         <property name="label" translatable="yes"></property>
+                         <property name="use_underline">False</property>
+                         <property name="use_markup">False</property>
+                         <property name="justify">GTK_JUSTIFY_LEFT</property>
+                         <property name="wrap">True</property>
+                         <property name="selectable">True</property>
+                         <property name="xalign">0</property>
+                         <property name="yalign">0.5</property>
+                         <property name="xpad">2</property>
+                         <property name="ypad">0</property>
+                         <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+                         <property name="width_chars">-1</property>
+                         <property name="single_line_mode">False</property>
+                         <property name="angle">0</property>
+                       </widget>
+                       <packing>
+                         <property name="left_attach">1</property>
+                         <property name="right_attach">2</property>
+                         <property name="top_attach">0</property>
+                         <property name="bottom_attach">1</property>
+                         <property name="y_options"></property>
+                       </packing>
+                     </child>
+
+                     <child>
+                       <widget class="GtkLabel" id="label666">
+                         <property name="label" translatable="yes">Client:</property>
+                         <property name="use_underline">False</property>
+                         <property name="use_markup">False</property>
+                         <property name="justify">GTK_JUSTIFY_LEFT</property>
+                         <property name="wrap">False</property>
+                         <property name="selectable">False</property>
+                         <property name="xalign">0</property>
+                         <property name="yalign">0</property>
+                         <property name="xpad">0</property>
+                         <property name="ypad">0</property>
+                         <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+                         <property name="width_chars">-1</property>
+                         <property name="single_line_mode">False</property>
+                         <property name="angle">0</property>
+                       </widget>
+                       <packing>
+                         <property name="left_attach">0</property>
+                         <property name="right_attach">1</property>
+                         <property name="top_attach">0</property>
+                         <property name="bottom_attach">1</property>
+                         <property name="x_options">fill</property>
+                       </packing>
+                     </child>
+
+                     <child>
+                       <widget class="GtkLabel" id="label667">
+                         <property name="label" translatable="yes">Version:</property>
+                         <property name="use_underline">False</property>
+                         <property name="use_markup">False</property>
+                         <property name="justify">GTK_JUSTIFY_LEFT</property>
+                         <property name="wrap">False</property>
+                         <property name="selectable">False</property>
+                         <property name="xalign">0</property>
+                         <property name="yalign">0</property>
+                         <property name="xpad">0</property>
+                         <property name="ypad">0</property>
+                         <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+                         <property name="width_chars">-1</property>
+                         <property name="single_line_mode">False</property>
+                         <property name="angle">0</property>
+                       </widget>
+                       <packing>
+                         <property name="left_attach">0</property>
+                         <property name="right_attach">1</property>
+                         <property name="top_attach">1</property>
+                         <property name="bottom_attach">2</property>
+                         <property name="x_options">fill</property>
+                       </packing>
+                     </child>
+
+                     <child>
+                       <widget class="GtkLabel" id="label668">
+                         <property name="label" translatable="yes">OS:</property>
+                         <property name="use_underline">False</property>
+                         <property name="use_markup">False</property>
+                         <property name="justify">GTK_JUSTIFY_LEFT</property>
+                         <property name="wrap">False</property>
+                         <property name="selectable">False</property>
+                         <property name="xalign">0</property>
+                         <property name="yalign">0</property>
+                         <property name="xpad">0</property>
+                         <property name="ypad">0</property>
+                         <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+                         <property name="width_chars">-1</property>
+                         <property name="single_line_mode">False</property>
+                         <property name="angle">0</property>
+                       </widget>
+                       <packing>
+                         <property name="left_attach">0</property>
+                         <property name="right_attach">1</property>
+                         <property name="top_attach">2</property>
+                         <property name="bottom_attach">3</property>
+                         <property name="x_options">fill</property>
+                       </packing>
+                     </child>
+                   </widget>
+                   <packing>
+                     <property name="padding">0</property>
+                     <property name="expand">False</property>
+                     <property name="fill">True</property>
+                   </packing>
+                 </child>
+
+                 <child>
+                   <widget class="GtkHBox" id="hbox_client_requested">
+                     <property name="visible">True</property>
+                     <property name="homogeneous">False</property>
+                     <property name="spacing">6</property>
+
+                     <child>
+                       <widget class="GtkImage" id="image887">
+                         <property name="visible">True</property>
+                         <property name="stock">gtk-dialog-info</property>
+                         <property name="icon_size">4</property>
+                         <property name="xalign">0.5</property>
+                         <property name="yalign">0.5</property>
+                         <property name="xpad">0</property>
+                         <property name="ypad">0</property>
+                       </widget>
+                       <packing>
+                         <property name="padding">0</property>
+                         <property name="expand">False</property>
+                         <property name="fill">False</property>
+                       </packing>
+                     </child>
+
+                     <child>
+                       <widget class="GtkLabel" id="label669">
+                         <property name="visible">True</property>
+                         <property name="label" translatable="yes">Information requested...</property>
+                         <property name="use_underline">False</property>
+                         <property name="use_markup">True</property>
+                         <property name="justify">GTK_JUSTIFY_LEFT</property>
+                         <property name="wrap">True</property>
+                         <property name="selectable">False</property>
+                         <property name="xalign">0</property>
+                         <property name="yalign">0.5</property>
+                         <property name="xpad">0</property>
+                         <property name="ypad">0</property>
+                         <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+                         <property name="width_chars">-1</property>
+                         <property name="single_line_mode">False</property>
+                         <property name="angle">0</property>
+                       </widget>
+                       <packing>
+                         <property name="padding">0</property>
+                         <property name="expand">True</property>
+                         <property name="fill">True</property>
+                       </packing>
+                     </child>
+                   </widget>
+                   <packing>
+                     <property name="padding">0</property>
+                     <property name="expand">False</property>
+                     <property name="fill">False</property>
+                   </packing>
+                 </child>
+               </widget>
+             </child>
+           </widget>
+           <packing>
+             <property name="padding">0</property>
+             <property name="expand">False</property>
+             <property name="fill">False</property>
+           </packing>
+         </child>
+       </widget>
+       <packing>
+         <property name="padding">0</property>
+         <property name="expand">False</property>
+         <property name="fill">True</property>
+       </packing>
+      </child>
+    </widget>
+  </child>
+</widget>
+
+</glade-interface>
diff --git a/libempathy-gtk/empathy-contact-widget.h b/libempathy-gtk/empathy-contact-widget.h
new file mode 100644 (file)
index 0000000..c61d973
--- /dev/null
@@ -0,0 +1,36 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2007 Collabora Ltd.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Authors: Xavier Claessens <xclaesse@gmail.com>
+ */
+
+#ifndef __EMPATHY_CONTACT_WIDGET_H__
+#define __EMPATHY_CONTACT_WIDGET_H__
+
+#include <gtk/gtk.h>
+
+#include <libempathy/gossip-contact.h>
+
+G_BEGIN_DECLS
+
+GtkWidget * empathy_contact_widget_new  (GossipContact *contact);
+void        empathy_contact_widget_save (GtkWidget     *widget);
+
+G_END_DECLS
+#endif /*  __EMPATHY_CONTACT_WIDGET_H__ */
index 5c364083b1791a76809f146f5ac97fd47663fc19..17fa9e5dc124fc41d99f27cf420752d9108effee 100644 (file)
@@ -39,6 +39,7 @@
 #include <libempathy/empathy-idle.h>
 
 #include "empathy-status-icon.h"
+#include "empathy-contact-widget.h"
 #include "gossip-presence-chooser.h"
 #include "gossip-preferences.h"
 #include "gossip-ui-utils.h"
@@ -463,6 +464,8 @@ status_icon_event_subscribe_cb (StatusIconEvent *event)
 
        contact = GOSSIP_CONTACT (event->user_data);
 
+       //empathy_subscription_dialog_show (contact);
+
        g_object_unref (contact);
 }
 
index 284f51138e383bc314389d15b3527839d19a5eca..e54ebef384168cb0a7fb799c7bcd3ae7ea7e685f 100644 (file)
@@ -144,9 +144,6 @@ static void                   tp_contact_list_pending_cb               (GossipTe
 static void                   tp_contact_list_groups_updated_cb        (GossipContact                   *contact,
                                                                        GParamSpec                      *param,
                                                                        EmpathyTpContactList            *list);
-static void                   tp_contact_list_subscription_updated_cb  (GossipContact                   *contact,
-                                                                       GParamSpec                      *param,
-                                                                       EmpathyTpContactList            *list);
 static void                   tp_contact_list_name_updated_cb          (GossipContact                   *contact,
                                                                        GParamSpec                      *param,
                                                                        EmpathyTpContactList            *list);
@@ -710,9 +707,6 @@ empathy_tp_contact_list_get_from_handles (EmpathyTpContactList *list,
                g_signal_connect (contact, "notify::groups",
                                  G_CALLBACK (tp_contact_list_groups_updated_cb),
                                  list);
-               g_signal_connect (contact, "notify::subscription",
-                                 G_CALLBACK (tp_contact_list_subscription_updated_cb),
-                                 list);
                g_signal_connect (contact, "notify::name",
                                  G_CALLBACK (tp_contact_list_name_updated_cb),
                                  list);
@@ -870,9 +864,6 @@ tp_contact_list_contact_removed_foreach (guint                 handle,
        g_signal_handlers_disconnect_by_func (contact,
                                              tp_contact_list_groups_updated_cb,
                                              list);
-       g_signal_handlers_disconnect_by_func (contact,
-                                             tp_contact_list_subscription_updated_cb,
-                                             list);
        g_signal_handlers_disconnect_by_func (contact,
                                              tp_contact_list_name_updated_cb,
                                              list);
@@ -887,9 +878,6 @@ tp_contact_list_block_contact (EmpathyTpContactList *list,
        g_signal_handlers_block_by_func (contact,
                                         tp_contact_list_groups_updated_cb,
                                         list);
-       g_signal_handlers_block_by_func (contact,
-                                        tp_contact_list_subscription_updated_cb,
-                                        list);
        g_signal_handlers_block_by_func (contact,
                                         tp_contact_list_name_updated_cb,
                                         list);
@@ -902,9 +890,6 @@ tp_contact_list_unblock_contact (EmpathyTpContactList *list,
        g_signal_handlers_unblock_by_func (contact,
                                           tp_contact_list_groups_updated_cb,
                                           list);
-       g_signal_handlers_unblock_by_func (contact,
-                                          tp_contact_list_subscription_updated_cb,
-                                          list);
        g_signal_handlers_unblock_by_func (contact,
                                           tp_contact_list_name_updated_cb,
                                           list);
@@ -1277,28 +1262,6 @@ tp_contact_list_groups_updated_cb (GossipContact        *contact,
                              &data);
 }
 
-static void
-tp_contact_list_subscription_updated_cb (GossipContact        *contact,
-                                        GParamSpec           *param,
-                                        EmpathyTpContactList *list)
-{
-       EmpathyTpContactListPriv *priv;
-       GossipSubscription        subscription;
-       guint                     handle;
-
-       priv = GET_PRIV (list);
-
-       subscription = gossip_contact_get_subscription (contact);
-       handle = gossip_contact_get_handle (contact);
-
-       /* FIXME: what to do here, I'm a bit lost... */
-       if (subscription) {
-               gossip_telepathy_group_add_member (priv->publish, handle, "");
-       } else {
-               gossip_telepathy_group_remove_member (priv->publish, handle, "");
-       }
-}
-
 static void
 tp_contact_list_name_updated_cb (GossipContact        *contact,
                                 GParamSpec           *param,
index 78b2eefd00de6d74fcb9f7b2320d4f55a4a08b0c..267d8664684acbe6e5d5d62d27e36e4b74bdf219 100644 (file)
@@ -652,7 +652,7 @@ gossip_contact_get_status (GossipContact *contact)
                return status;
        }
 
-       return _("Offline");
+       return gossip_presence_state_get_default_status (MC_PRESENCE_OFFLINE);
 }
 
 GossipContact *