]> git.0d.be Git - empathy.git/commitdiff
We can now add a new contact. EmpathyContactWidget can change the contact
authorXavier Claessens <xclaesse@gmail.com>
Sat, 9 Jun 2007 12:47:48 +0000 (12:47 +0000)
committerXavier Claessens <xclaesse@src.gnome.org>
Sat, 9 Jun 2007 12:47:48 +0000 (12:47 +0000)
2007-06-09 Xavier Claessens  <xclaesse@gmail.com>

* libempathy-gtk/empathy-main-window.c:
* libempathy-gtk/empathy-contact-widget.glade:
* libempathy-gtk/empathy-contact-dialogs.c:
* libempathy-gtk/empathy-contact-dialogs.h:
* libempathy-gtk/empathy-contact-widget.c: We can now add a new contact.
EmpathyContactWidget can change the contact it's displaying on-the-fly,
like that we can display info when typing the contact ID we want to
add to our contact list.

* libempathy/empathy-tp-contact-list.c: Fix a refcount bug.

svn path=/trunk/; revision=134

ChangeLog
libempathy-gtk/empathy-contact-dialogs.c
libempathy-gtk/empathy-contact-dialogs.h
libempathy-gtk/empathy-contact-widget.c
libempathy-gtk/empathy-contact-widget.glade
libempathy-gtk/empathy-main-window.c
libempathy/empathy-tp-contact-list.c

index efc1208c47e29fdf4db67da4ac7dd73407cec676..c080397ac8fa32e839fc37df55099a1d96fae797 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2007-06-09 Xavier Claessens  <xclaesse@gmail.com>
+
+       * libempathy-gtk/empathy-main-window.c:
+       * libempathy-gtk/empathy-contact-widget.glade:
+       * libempathy-gtk/empathy-contact-dialogs.c:
+       * libempathy-gtk/empathy-contact-dialogs.h:
+       * libempathy-gtk/empathy-contact-widget.c: We can now add a new contact.
+       EmpathyContactWidget can change the contact it's displaying on-the-fly,
+       like that we can display info when typing the contact ID we want to
+       add to our contact list.
+
+       * libempathy/empathy-tp-contact-list.c: Fix a refcount bug.
+
 2007-06-08 Xavier Claessens  <xclaesse@gmail.com>
 
        * libempathy/gossip-chatroom-manager.c: Checks if the chatroom has
index ff2f87134eb71a90365e6f38b04eb39ca57ebe56..051876940f5fa8ca930717ba4a132e3435222a46 100644 (file)
 #include "empathy-contact-widget.h"
 #include "gossip-ui-utils.h"
 
-static GHashTable *subscription_dialogs = NULL;
-static GHashTable *information_dialogs = NULL;
+static GList *subscription_dialogs = NULL;
+static GList *information_dialogs = NULL;
+static GtkWidget *new_contact_dialog = NULL;
+
+
+static gint
+contact_dialogs_find (GtkDialog     *dialog,
+                     GossipContact *contact)
+{
+       GtkWidget     *contact_widget;
+       GossipContact *this_contact;
+
+       contact_widget = g_object_get_data (G_OBJECT (dialog), "contact_widget");
+       this_contact = empathy_contact_widget_get_contact (contact_widget);
+
+       return !gossip_contact_equal (contact, this_contact);
+}
 
 /*
  *  Subscription dialog
@@ -65,7 +80,8 @@ subscription_dialog_response_cb (GtkDialog *dialog,
                                             _("Sorry, I don't want you in my contact list."));
        }
 
-       g_hash_table_remove (subscription_dialogs, contact);
+       subscription_dialogs = g_list_remove (subscription_dialogs, dialog);
+       gtk_widget_destroy (GTK_WIDGET (dialog));
        g_object_unref (manager);
 }
 
@@ -76,19 +92,15 @@ empathy_subscription_dialog_show (GossipContact *contact,
        GtkWidget *dialog;
        GtkWidget *hbox_subscription;
        GtkWidget *contact_widget;
+       GList     *l;
 
        g_return_if_fail (GOSSIP_IS_CONTACT (contact));
 
-       if (!subscription_dialogs) {
-               subscription_dialogs = g_hash_table_new_full (gossip_contact_hash,
-                                                             gossip_contact_equal,
-                                                             (GDestroyNotify) g_object_unref,
-                                                             (GDestroyNotify) gtk_widget_destroy);
-       }
-
-       dialog = g_hash_table_lookup (subscription_dialogs, contact);
-       if (dialog) {
-               gtk_window_present (GTK_WINDOW (dialog));
+       l = g_list_find_custom (subscription_dialogs,
+                               contact,
+                               (GCompareFunc) contact_dialogs_find);
+       if (l) {
+               gtk_window_present (GTK_WINDOW (l->data));
                return;
        }
 
@@ -99,14 +111,15 @@ empathy_subscription_dialog_show (GossipContact *contact,
                                      "hbox_subscription", &hbox_subscription,
                                      NULL);
 
-       g_hash_table_insert (subscription_dialogs, g_object_ref (contact), dialog);
-
        contact_widget = empathy_contact_widget_new (contact, TRUE);
        gtk_box_pack_end (GTK_BOX (hbox_subscription),
                          contact_widget,
                          TRUE, TRUE,
                          0);
 
+       g_object_set_data (G_OBJECT (dialog), "contact_widget", contact_widget);
+       subscription_dialogs = g_list_prepend (subscription_dialogs, dialog);
+
        g_signal_connect (dialog, "response",
                          G_CALLBACK (subscription_dialog_response_cb),
                          contact_widget);
@@ -127,10 +140,8 @@ contact_information_response_cb (GtkDialog *dialog,
                                 gint       response,
                                 GtkWidget *contact_widget)
 {
-       GossipContact *contact;
-
-       contact = empathy_contact_widget_get_contact (contact_widget);
-       g_hash_table_remove (information_dialogs, contact);
+       information_dialogs = g_list_remove (information_dialogs, dialog);
+       gtk_widget_destroy (GTK_WIDGET (dialog));
 }
 
 void
@@ -141,19 +152,15 @@ empathy_contact_information_dialog_show (GossipContact *contact,
        GtkWidget *dialog;
        GtkWidget *button;
        GtkWidget *contact_widget;
+       GList     *l;
 
        g_return_if_fail (GOSSIP_IS_CONTACT (contact));
 
-       if (!information_dialogs) {
-               information_dialogs = g_hash_table_new_full (gossip_contact_hash,
-                                                            gossip_contact_equal,
-                                                            (GDestroyNotify) g_object_unref,
-                                                            (GDestroyNotify) gtk_widget_destroy);
-       }
-
-       dialog = g_hash_table_lookup (information_dialogs, contact);
-       if (dialog) {
-               gtk_window_present (GTK_WINDOW (dialog));
+       l = g_list_find_custom (information_dialogs,
+                               contact,
+                               (GCompareFunc) contact_dialogs_find);
+       if (l) {
+               gtk_window_present (GTK_WINDOW (l->data));
                return;
        }
 
@@ -176,11 +183,90 @@ empathy_contact_information_dialog_show (GossipContact *contact,
                            contact_widget,
                            TRUE, TRUE, 0);
 
+       g_object_set_data (G_OBJECT (dialog), "contact_widget", contact_widget);
+       information_dialogs = g_list_prepend (information_dialogs, dialog);
+
        g_signal_connect (dialog, "response",
                          G_CALLBACK (contact_information_response_cb),
                          contact_widget);
 
-       g_hash_table_insert (information_dialogs, g_object_ref (contact), dialog);
+       if (parent) {
+               gtk_window_set_transient_for (GTK_WINDOW (dialog), parent);
+       }
+
+       gtk_widget_show (dialog);
+}
+
+/*
+ *  New contact dialog
+ */
+
+static void
+new_contact_response_cb (GtkDialog *dialog,
+                        gint       response,
+                        GtkWidget *contact_widget)
+{
+       EmpathyContactManager *manager;
+       GossipContact         *contact;
+
+       manager = empathy_contact_manager_new ();
+       contact = empathy_contact_widget_get_contact (contact_widget);
+
+       if (contact && response == GTK_RESPONSE_OK) {
+               empathy_contact_list_add (EMPATHY_CONTACT_LIST (manager),
+                                         contact,
+                                         _("I would like to add you to my contact list."));
+       }
+
+       new_contact_dialog = NULL;
+       gtk_widget_destroy (GTK_WIDGET (dialog));
+       g_object_unref (manager);
+}
+
+void
+empathy_new_contact_dialog_show (GtkWindow *parent)
+{
+       GtkWidget *dialog;
+       GtkWidget *button;
+       GtkWidget *contact_widget;
+
+       if (new_contact_dialog) {
+               gtk_window_present (GTK_WINDOW (new_contact_dialog));
+               return;
+       }
+
+       /* Create dialog */
+       dialog = gtk_dialog_new ();
+       gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE);
+       gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE);
+
+       /* Cancel button */
+       button = gtk_button_new_with_label (GTK_STOCK_CANCEL);
+       gtk_button_set_use_stock (GTK_BUTTON (button), TRUE);
+       gtk_dialog_add_action_widget (GTK_DIALOG (dialog),
+                                     button,
+                                     GTK_RESPONSE_CANCEL);
+       gtk_widget_show (button);
+       
+       /* Add button */
+       button = gtk_button_new_with_label (GTK_STOCK_ADD);
+       gtk_button_set_use_stock (GTK_BUTTON (button), TRUE);
+       gtk_dialog_add_action_widget (GTK_DIALOG (dialog),
+                                     button,
+                                     GTK_RESPONSE_OK);
+       gtk_widget_show (button);
+
+       /* Contact infor widget */
+       contact_widget = empathy_contact_widget_new (NULL, TRUE);
+       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
+                           contact_widget,
+                           TRUE, TRUE, 0);
+
+       new_contact_dialog = dialog;
+
+       g_signal_connect (dialog, "response",
+                         G_CALLBACK (new_contact_response_cb),
+                         contact_widget);
 
        if (parent) {
                gtk_window_set_transient_for (GTK_WINDOW (dialog), parent);
index 809623d47cddcb892999b303c73107d0e9fdf7d0..55b5a186b82c6904a2fb5661db2ce3792ed678ea 100644 (file)
@@ -34,6 +34,7 @@ void empathy_subscription_dialog_show        (GossipContact *contact,
 void empathy_contact_information_dialog_show (GossipContact *contact,
                                              GtkWindow     *parent,
                                              gboolean       edit);
+void empathy_new_contact_dialog_show         (GtkWindow     *parent);
 
 G_END_DECLS
 
index 58c800f6ab847077cec122b48478afa084c351f6..1446c87f475dd999898bb159c40e4a25fa6eaf62 100644 (file)
 #include <glade/glade.h>
 #include <glib/gi18n.h>
 
+#include <libmissioncontrol/mc-account.h>
+
 #include <libempathy/empathy-contact-manager.h>
 
 #include "empathy-contact-widget.h"
+#include "gossip-account-chooser.h"
 #include "gossip-ui-utils.h"
 
 typedef struct {
        GossipContact   *contact;
        gboolean         is_user;
        gboolean         editable;
+       gboolean         can_change_contact;
        GtkCellRenderer *renderer;
 
        GtkWidget       *vbox_contact_widget;
 
+       /* Contact */
        GtkWidget       *vbox_contact;
        GtkWidget       *widget_avatar;
-       GtkWidget       *label_id;
-       GtkWidget       *entry_alias;
+       GtkWidget       *widget_account;
+       GtkWidget       *widget_id;
        GtkWidget       *widget_alias;
+       GtkWidget       *label_alias;
+       GtkWidget       *entry_alias;
+       GtkWidget       *hbox_presence;
        GtkWidget       *image_state;
        GtkWidget       *label_status;
        GtkWidget       *table_contact;
        GtkWidget       *hbox_contact;
 
+       /* Groups */
        GtkWidget       *vbox_groups;
        GtkWidget       *entry_group;
        GtkWidget       *button_group;
        GtkWidget       *treeview_groups;
 
+       /* Details */
        GtkWidget       *vbox_details;
        GtkWidget       *table_details;
        GtkWidget       *hbox_details_requested;
 
+       /* Client */
        GtkWidget       *vbox_client;
        GtkWidget       *table_client;
        GtkWidget       *hbow_client_requested;
+
 } EmpathyContactWidget;
 
 typedef struct {
@@ -73,38 +85,51 @@ typedef struct {
        GtkTreeIter           found_iter;
 } FindName;
 
-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 void     contact_widget_cell_toggled                (GtkCellRendererToggle *cell,
-                                                           gchar                 *path_string,
-                                                           EmpathyContactWidget  *information);
-static void     contact_widget_entry_alias_focus_event_cb  (GtkEditable           *editable,
-                                                           GdkEventFocus         *event,
-                                                           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);
+static void     contact_widget_destroy_cb                 (GtkWidget             *widget,
+                                                          EmpathyContactWidget  *information);
+static void     contact_widget_remove_contact             (EmpathyContactWidget  *information);
+static void     contact_widget_set_contact                (EmpathyContactWidget  *information,
+                                                          GossipContact         *contact);
+static void     contact_widget_contact_setup              (EmpathyContactWidget  *information);
+static void     contact_widget_contact_update             (EmpathyContactWidget  *information);
+static gboolean contact_widget_update_contact             (EmpathyContactWidget  *information);
+static void     contact_widget_account_changed_cb         (GtkComboBox           *widget,
+                                                          EmpathyContactWidget  *information);
+static gboolean contact_widget_id_focus_out_cb            (GtkWidget             *widget,
+                                                          GdkEventFocus         *event,
+                                                          EmpathyContactWidget  *information);
+static void     contact_widget_entry_alias_focus_event_cb (GtkEditable           *editable,
+                                                          GdkEventFocus         *event,
+                                                          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_groups_update              (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 void     contact_widget_cell_toggled               (GtkCellRendererToggle *cell,
+                                                          gchar                 *path_string,
+                                                          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_details_update             (EmpathyContactWidget  *information);
+static void     contact_widget_client_setup               (EmpathyContactWidget  *information);
+static void     contact_widget_client_update              (EmpathyContactWidget  *information);
 
 enum {
        COL_NAME,
@@ -119,22 +144,27 @@ 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);
        information->editable = editable;
+       if (contact) {
+               GossipContact *user_contact;
+       
+               user_contact = gossip_contact_get_user (contact);
+               information->is_user = gossip_contact_equal (contact, user_contact);
+               information->can_change_contact = FALSE;
+       } else {
+               information->is_user = FALSE;
+               information->can_change_contact = TRUE;
+       }
 
        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,
+                                      "hbox_presence", &information->hbox_presence,
+                                      "label_alias", &information->label_alias,
                                       "image_state", &information->image_state,
                                       "label_status", &information->label_status,
                                       "table_contact", &information->table_contact,
@@ -165,11 +195,14 @@ empathy_contact_widget_new (GossipContact *contact,
                           "EmpathyContactWidget",
                           information);
 
+       /* Create widgets */
        contact_widget_contact_setup (information);
        contact_widget_groups_setup (information);
        contact_widget_details_setup (information);
        contact_widget_client_setup (information);
 
+       contact_widget_set_contact (information, contact);
+
        gtk_widget_show (information->vbox_contact_widget);
 
        return information->vbox_contact_widget;
@@ -194,36 +227,51 @@ static void
 contact_widget_destroy_cb (GtkWidget            *widget,
                           EmpathyContactWidget *information)
 {
-       g_signal_handlers_disconnect_by_func (information->contact,
-                                             contact_widget_name_notify_cb,
-                                             information);
-       g_signal_handlers_disconnect_by_func (information->contact,
-                                             contact_widget_presence_notify_cb,
-                                             information);
-       g_signal_handlers_disconnect_by_func (information->contact,
-                                             contact_widget_avatar_notify_cb,
-                                             information);
-       g_signal_handlers_disconnect_by_func (information->contact,
-                                             contact_widget_groups_notify_cb,
-                                             information);
-
-       g_object_unref (information->contact);
+       contact_widget_remove_contact (information);
        g_slice_free (EmpathyContactWidget, information);
 }
 
 static void
-contact_widget_contact_setup (EmpathyContactWidget *information)
+contact_widget_remove_contact (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);
+       if (information->contact) {
+               g_signal_handlers_disconnect_by_func (information->contact,
+                                                     contact_widget_name_notify_cb,
+                                                     information);
+               g_signal_handlers_disconnect_by_func (information->contact,
+                                                     contact_widget_presence_notify_cb,
+                                                     information);
+               g_signal_handlers_disconnect_by_func (information->contact,
+                                                     contact_widget_avatar_notify_cb,
+                                                     information);
+               g_signal_handlers_disconnect_by_func (information->contact,
+                                                     contact_widget_groups_notify_cb,
+                                                     information);
+
+               g_object_unref (information->contact);
+               information->contact = NULL;
+       }
+}
+
+static void
+contact_widget_set_contact (EmpathyContactWidget *information,
+                           GossipContact        *contact)
+{
+       contact_widget_remove_contact (information);
+       if (contact) {
+               information->contact = g_object_ref (contact);
+       }
+
+       /* Update information for widgets */
+       contact_widget_contact_update (information);
+       contact_widget_groups_update (information);
+       contact_widget_details_update (information);
+       contact_widget_client_update (information);
+}
 
+static void
+contact_widget_contact_setup (EmpathyContactWidget *information)
+{
        /* FIXME: Use GossipAvatarImage if (editable && is_user)  */
        information->widget_avatar = gtk_image_new ();
        gtk_box_pack_end (GTK_BOX (information->hbox_contact),
@@ -231,7 +279,37 @@ contact_widget_contact_setup (EmpathyContactWidget *information)
                          FALSE, FALSE,
                          6);
 
-       /* Setup alias entry or label */
+       /* Setup account label/chooser */
+       if (information->can_change_contact) {
+               information->widget_account = gossip_account_chooser_new ();
+               g_signal_connect (information->widget_account, "changed",
+                                 G_CALLBACK (contact_widget_account_changed_cb),
+                                 information);
+       } else {
+               information->widget_account = gtk_label_new (NULL);
+               gtk_label_set_selectable (GTK_LABEL (information->widget_account), TRUE);
+       }
+       gtk_table_attach_defaults (GTK_TABLE (information->table_contact),
+                                  information->widget_account,
+                                  1, 2, 0, 1);
+       gtk_widget_show (information->widget_account);
+
+       /* Setup id label/entry */
+       if (information->can_change_contact) {
+               information->widget_id = gtk_entry_new ();
+               g_signal_connect (information->widget_id, "focus-out-event",
+                                 G_CALLBACK (contact_widget_id_focus_out_cb),
+                                 information);
+       } else {
+               information->widget_id = gtk_label_new (NULL);
+               gtk_label_set_selectable (GTK_LABEL (information->widget_id), TRUE);
+       }
+       gtk_table_attach_defaults (GTK_TABLE (information->table_contact),
+                                  information->widget_id,
+                                  1, 2, 1, 2);
+       gtk_widget_show (information->widget_id);
+
+       /* Setup alias label/entry */
        if (information->editable) {
                information->widget_alias = gtk_entry_new ();
                g_signal_connect (information->widget_alias, "focus-out-event",
@@ -243,17 +321,131 @@ contact_widget_contact_setup (EmpathyContactWidget *information)
        }
        gtk_table_attach_defaults (GTK_TABLE (information->table_contact),
                                   information->widget_alias,
-                                  1, 2, 1, 2);
+                                  1, 2, 2, 3);
        gtk_widget_show (information->widget_alias);
+}
+
+static void
+contact_widget_contact_update (EmpathyContactWidget *information)
+{
+       McAccount   *account = NULL;
+       const gchar *id = NULL;
 
-       /* Setup id label */
-       gtk_label_set_text (GTK_LABEL (information->label_id),
-                           gossip_contact_get_id (information->contact));
+       /* Connect and get info from new contact */
+       if (information->contact) {
+               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);
 
-       /* Update all widgets */
-       contact_widget_name_notify_cb (information);
-       contact_widget_presence_notify_cb (information);
-       contact_widget_avatar_notify_cb (information);
+               account = gossip_contact_get_account (information->contact);
+               id = gossip_contact_get_id (information->contact);
+       }
+
+       /* Update account widget */
+       if (information->can_change_contact) {
+               if (account) {
+                       g_signal_handlers_block_by_func (information->widget_account,
+                                                        contact_widget_account_changed_cb,
+                                                        information);
+                       gossip_account_chooser_set_account (GOSSIP_ACCOUNT_CHOOSER (information->widget_account),
+                                                           account);
+                       g_signal_handlers_unblock_by_func (information->widget_account,
+                                                          contact_widget_account_changed_cb,
+                                                          information);
+               }
+       }
+       else if (account) {
+               const gchar *name;
+
+               name = mc_account_get_display_name (account);
+               gtk_label_set_label (GTK_LABEL (information->widget_account), name);
+       }
+
+       /* Update id widget */
+       if (information->can_change_contact) {
+               if (!G_STR_EMPTY (id)) {
+                       gtk_entry_set_text (GTK_ENTRY (information->widget_id), id);
+               }
+       } else {
+               gtk_label_set_label (GTK_LABEL (information->widget_id), id);
+       }
+
+       /* Update other widgets */
+       if (information->contact) {
+               contact_widget_name_notify_cb (information);
+               contact_widget_presence_notify_cb (information);
+               contact_widget_avatar_notify_cb (information);
+
+               gtk_widget_show (information->label_alias);
+               gtk_widget_show (information->widget_alias);
+               gtk_widget_show (information->hbox_presence);
+       } else {
+               gtk_widget_hide (information->label_alias);
+               gtk_widget_hide (information->widget_alias);
+               gtk_widget_hide (information->hbox_presence);
+               gtk_widget_hide (information->widget_avatar);
+       }
+}
+
+static gboolean
+contact_widget_update_contact (EmpathyContactWidget *information)
+{
+       McAccount   *account;
+       const gchar *id;
+
+       account = gossip_account_chooser_get_account (GOSSIP_ACCOUNT_CHOOSER (information->widget_account));
+       id = gtk_entry_get_text (GTK_ENTRY (information->widget_id));
+
+       if (account && !G_STR_EMPTY (id)) {
+               EmpathyContactManager *manager;
+               GossipContact         *contact;
+
+               manager = empathy_contact_manager_new ();
+               contact = empathy_contact_manager_create (manager, account, id);
+               contact_widget_set_contact (information, contact);
+
+               if (contact) {
+                       g_object_unref (contact);
+               }
+               g_object_unref (manager);
+       }
+
+       return FALSE;
+}
+
+static void
+contact_widget_account_changed_cb (GtkComboBox          *widget,
+                                  EmpathyContactWidget *information)
+{
+       contact_widget_update_contact (information);
+}
+
+static gboolean
+contact_widget_id_focus_out_cb (GtkWidget            *widget,
+                               GdkEventFocus        *event,
+                               EmpathyContactWidget *information)
+{
+       contact_widget_update_contact (information);
+       return FALSE;
+}
+
+static void
+contact_widget_entry_alias_focus_event_cb (GtkEditable          *editable,
+                                          GdkEventFocus        *event,
+                                          EmpathyContactWidget *information)
+{
+       if (information->contact) {
+               const gchar *name;
+
+               name = gtk_entry_get_text (GTK_ENTRY (editable));
+               gossip_contact_set_name (information->contact, name);
+       }
 }
 
 static void
@@ -302,13 +494,21 @@ contact_widget_groups_setup (EmpathyContactWidget *information)
 {
        if (information->editable) {
                contact_widget_model_setup (information);
+       }
+}
 
+static void
+contact_widget_groups_update (EmpathyContactWidget *information)
+{
+       if (information->editable && information->contact) {
                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);
+       } else {
+               gtk_widget_hide (information->vbox_groups);
        }
 }
 
@@ -399,6 +599,7 @@ contact_widget_groups_populate_data (EmpathyContactWidget *information)
 
        view = GTK_TREE_VIEW (information->treeview_groups);
        store = GTK_LIST_STORE (gtk_tree_view_get_model (view));
+       gtk_list_store_clear (store);
 
        manager = empathy_contact_manager_new ();
        all_groups = empathy_contact_manager_get_groups (manager);
@@ -533,17 +734,6 @@ contact_widget_cell_toggled (GtkCellRendererToggle *cell,
        }
 }
 
-static void
-contact_widget_entry_alias_focus_event_cb (GtkEditable          *editable,
-                                          GdkEventFocus        *event,
-                                          EmpathyContactWidget *information)
-{
-       const gchar *name;
-
-       name = gtk_entry_get_text (GTK_ENTRY (editable));
-       gossip_contact_set_name (information->contact, name);
-}
-
 static void
 contact_widget_entry_group_changed_cb (GtkEditable           *editable,
                                       EmpathyContactWidget  *information)
@@ -594,12 +784,26 @@ contact_widget_button_group_clicked_cb (GtkButton             *button,
 
 static void
 contact_widget_details_setup (EmpathyContactWidget *information)
+{
+       /* FIXME: Needs new telepathy spec */
+       gtk_widget_hide (information->vbox_details);
+}
+
+static void
+contact_widget_details_update (EmpathyContactWidget *information)
 {
        /* FIXME: Needs new telepathy spec */
 }
 
 static void
 contact_widget_client_setup (EmpathyContactWidget *information)
+{
+       /* FIXME: Needs new telepathy spec */
+       gtk_widget_hide (information->vbox_client);
+}
+
+static void
+contact_widget_client_update (EmpathyContactWidget *information)
 {
        /* FIXME: Needs new telepathy spec */
 }
index d36971b780ff65240b9e47da2d431bf079c1711e..74347a06b3f52061f93a12e9d57af4a683d3d952 100644 (file)
                      <child>
                        <widget class="GtkTable" id="table_contact">
                          <property name="visible">True</property>
-                         <property name="n_rows">2</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">
+                           <widget class="GtkLabel" id="label_alias">
                              <property name="visible">True</property>
-                             <property name="label" translatable="yes">Identifier:</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>
                            <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="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="label658">
+                           <widget class="GtkLabel" id="label655">
                              <property name="visible">True</property>
-                             <property name="label" translatable="yes">Alias:</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>
                          </child>
 
                          <child>
-                           <widget class="GtkLabel" id="label_id">
+                           <widget class="GtkLabel" id="label680">
                              <property name="visible">True</property>
-                             <property name="can_focus">True</property>
-                             <property name="label" translatable="yes"></property>
+                             <property name="label" translatable="yes">Account:</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">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="angle">0</property>
                            </widget>
                            <packing>
-                             <property name="left_attach">1</property>
-                             <property name="right_attach">2</property>
+                             <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>
 
                      <child>
-                       <widget class="GtkHBox" id="hbox186">
+                       <widget class="GtkHBox" id="hbox_presence">
                          <property name="visible">True</property>
                          <property name="homogeneous">False</property>
                          <property name="spacing">6</property>
index 1ae2274104876b786fb9f5700e578b47d4b64d65..7f86932788599fb0b32154f3c64e5c0a5a61f1a0 100644 (file)
@@ -37,6 +37,7 @@
 #include <libempathy/empathy-contact-manager.h>
 
 #include "empathy-main-window.h"
+#include "empathy-contact-dialogs.h"
 #include "ephy-spinner.h"
 #include "gossip-contact-list-store.h"
 #include "gossip-contact-list-view.h"
@@ -566,7 +567,7 @@ static void
 main_window_chat_add_contact_cb (GtkWidget         *widget,
                                 EmpathyMainWindow *window)
 {
-       //gossip_add_contact_dialog_show (GTK_WINDOW (window->window), NULL);
+       empathy_new_contact_dialog_show (GTK_WINDOW (window->window));
 }
 
 static void
index 97948a4f2a033228d8c9e450fd22ecf03b7829a9..c81279043c3a43e0d44c6aca05945d28e8f2c494 100644 (file)
@@ -562,7 +562,7 @@ empathy_tp_contact_list_get_from_id (EmpathyTpContactList *list,
 
        contact = tp_contact_list_find (EMPATHY_CONTACT_LIST (list), id);
        if (contact) {
-               return contact;
+               return g_object_ref (contact);
        }
 
        /* The id is unknown, requests a new handle */
@@ -574,7 +574,7 @@ empathy_tp_contact_list_get_from_id (EmpathyTpContactList *list,
                              "RequestHandle for %s failed: %s", id,
                              error ? error->message : "No error given");
                g_clear_error (&error);
-               return 0;
+               return NULL;
        }
 
        handle = g_array_index(handles, guint, 0);