aboutsummaryrefslogtreecommitdiffstats
path: root/libempathy-gtk/empathy-contact-widget.c
diff options
context:
space:
mode:
Diffstat (limited to 'libempathy-gtk/empathy-contact-widget.c')
-rw-r--r--libempathy-gtk/empathy-contact-widget.c374
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 */
}