diff options
Diffstat (limited to 'libempathy-gtk/empathy-contact-widget.c')
-rw-r--r-- | libempathy-gtk/empathy-contact-widget.c | 374 |
1 files changed, 289 insertions, 85 deletions
diff --git a/libempathy-gtk/empathy-contact-widget.c b/libempathy-gtk/empathy-contact-widget.c index 58c800f6a..1446c87f4 100644 --- a/libempathy-gtk/empathy-contact-widget.c +++ b/libempathy-gtk/empathy-contact-widget.c @@ -29,41 +29,53 @@ #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); @@ -534,17 +735,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) { @@ -596,11 +786,25 @@ 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 */ } |