/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/*
- * Copyright (C) 2007-2008 Collabora Ltd.
+ * Copyright (C) 2007-2009 Collabora Ltd.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
#include <stdlib.h>
#include <gtk/gtk.h>
-#include <glade/glade.h>
-#include <glib/gi18n.h>
+#include <glib/gi18n-lib.h>
+
+#if HAVE_LIBCHAMPLAIN
+#include <champlain/champlain.h>
+#include <champlain-gtk/champlain-gtk.h>
+#endif
-#include <libmissioncontrol/mc-account.h>
#include <telepathy-glib/util.h>
-#include <libempathy/empathy-contact-factory.h>
+#include <libempathy/empathy-tp-contact-factory.h>
#include <libempathy/empathy-contact-manager.h>
#include <libempathy/empathy-contact-list.h>
+#include <libempathy/empathy-location.h>
+#include <libempathy/empathy-time.h>
#include <libempathy/empathy-utils.h>
+#include <libempathy/empathy-account.h>
#include "empathy-contact-widget.h"
#include "empathy-account-chooser.h"
#include "empathy-avatar-chooser.h"
#include "empathy-avatar-image.h"
#include "empathy-ui-utils.h"
+#include "empathy-kludge-label.h"
+
+#define DEBUG_FLAG EMPATHY_DEBUG_CONTACT
+#include <libempathy/empathy-debug.h>
+
+/**
+ * SECTION:empathy-contact-widget
+ * @title:EmpathyContactWidget
+ * @short_description: A widget used to display and edit details about a contact
+ * @include: libempathy-empathy-contact-widget.h
+ *
+ * #EmpathyContactWidget is a widget which displays appropriate widgets
+ * with details about a contact, also allowing changing these details,
+ * if desired.
+ */
+
+/**
+ * EmpathyContactWidget:
+ * @parent: parent object
+ *
+ * Widget which displays appropriate widgets with details about a contact,
+ * also allowing changing these details, if desired.
+ */
/* Delay before updating the widget when the id entry changed (seconds) */
#define ID_CHANGED_TIMEOUT 1
typedef struct
{
- EmpathyContactFactory *factory;
+ EmpathyTpContactFactory *factory;
EmpathyContactManager *manager;
EmpathyContact *contact;
EmpathyContactWidgetFlags flags;
- GtkCellRenderer *renderer;
guint widget_id_timeout;
GtkWidget *vbox_contact_widget;
GtkWidget *table_contact;
GtkWidget *vbox_avatar;
+ /* Location */
+ GtkWidget *vbox_location;
+ GtkWidget *subvbox_location;
+ GtkWidget *table_location;
+ GtkWidget *label_location;
+#if HAVE_LIBCHAMPLAIN
+ GtkWidget *viewport_map;
+ GtkWidget *map_view_embed;
+ ChamplainView *map_view;
+#endif
+
/* Groups */
GtkWidget *vbox_groups;
GtkWidget *entry_group;
static void contact_widget_change_contact (EmpathyContactWidget *information);
static void contact_widget_avatar_changed_cb (EmpathyAvatarChooser *chooser,
EmpathyContactWidget *information);
-static void contact_widget_update_avatar_chooser_account (
- 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 gboolean contact_widget_entry_alias_focus_event_cb (
static void contact_widget_details_update (EmpathyContactWidget *information);
static void contact_widget_client_setup (EmpathyContactWidget *information);
static void contact_widget_client_update (EmpathyContactWidget *information);
+static void contact_widget_location_update (EmpathyContactWidget *information);
enum
{
COL_COUNT
};
+/**
+ * empathy_contact_widget_new:
+ * @contact: an #EmpathyContact
+ * @flags: #EmpathyContactWidgetFlags for the new contact widget
+ *
+ * Creates a new #EmpathyContactWidget.
+ *
+ * Return value: a new #EmpathyContactWidget
+ */
GtkWidget *
empathy_contact_widget_new (EmpathyContact *contact,
EmpathyContactWidgetFlags flags)
{
EmpathyContactWidget *information;
- GladeXML *glade;
+ GtkBuilder *gui;
gchar *filename;
+ g_return_val_if_fail (contact == NULL || EMPATHY_IS_CONTACT (contact), NULL);
+
information = g_slice_new0 (EmpathyContactWidget);
information->flags = flags;
- information->factory = empathy_contact_factory_new ();
- filename = empathy_file_lookup ("empathy-contact-widget.glade",
+ filename = empathy_file_lookup ("empathy-contact-widget.ui",
"libempathy-gtk");
- glade = empathy_glade_get_file (filename,
- "vbox_contact_widget",
- NULL,
+ gui = empathy_builder_get_file (filename,
"vbox_contact_widget", &information->vbox_contact_widget,
"vbox_contact", &information->vbox_contact,
"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,
"vbox_avatar", &information->vbox_avatar,
+ "vbox_location", &information->vbox_location,
+ "subvbox_location", &information->subvbox_location,
+ "label_location", &information->label_location,
+#if HAVE_LIBCHAMPLAIN
+ "viewport_map", &information->viewport_map,
+#endif
"vbox_groups", &information->vbox_groups,
"entry_group", &information->entry_group,
"button_group", &information->button_group,
NULL);
g_free (filename);
- empathy_glade_connect (glade,
- information,
+ empathy_builder_connect (gui, information,
"vbox_contact_widget", "destroy", contact_widget_destroy_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);
+ information->table_location = NULL;
g_object_set_data (G_OBJECT (information->vbox_contact_widget),
"EmpathyContactWidget",
contact_widget_details_setup (information);
contact_widget_client_setup (information);
- contact_widget_set_contact (information, contact);
+ if (contact != NULL)
+ contact_widget_set_contact (information, contact);
- gtk_widget_show (information->vbox_contact_widget);
+ else if (information->flags & EMPATHY_CONTACT_WIDGET_EDIT_ACCOUNT ||
+ information->flags & EMPATHY_CONTACT_WIDGET_EDIT_ID)
+ contact_widget_change_contact (information);
- return information->vbox_contact_widget;
+ return empathy_builder_unref_and_keep_widget (gui,
+ information->vbox_contact_widget);
}
+/**
+ * empathy_contact_widget_get_contact:
+ * @widget: an #EmpathyContactWidget
+ *
+ * Get the #EmpathyContact related with the #EmpathyContactWidget @widget.
+ *
+ * Returns: the #EmpathyContact associated with @widget
+ */
EmpathyContact *
empathy_contact_widget_get_contact (GtkWidget *widget)
{
return information->contact;
}
+/**
+ * empathy_contact_widget_set_contact:
+ * @widget: an #EmpathyContactWidget
+ * @contact: a different #EmpathyContact
+ *
+ * Change the #EmpathyContact related with the #EmpathyContactWidget @widget.
+ */
void
empathy_contact_widget_set_contact (GtkWidget *widget,
EmpathyContact *contact)
contact_widget_set_contact (information, contact);
}
+/**
+ * empathy_contact_widget_set_account_filter:
+ * @widget: an #EmpathyContactWidget
+ * @filter: a #EmpathyAccountChooserFilterFunc
+ * @user_data: user data to pass to @filter, or %NULL
+ *
+ * Set a filter on the #EmpathyAccountChooser included in the
+ * #EmpathyContactWidget.
+ */
void
empathy_contact_widget_set_account_filter (
GtkWidget *widget,
if (chooser)
empathy_account_chooser_set_filter (chooser, filter, user_data);
}
-
+
static void
contact_widget_destroy_cb (GtkWidget *widget,
EmpathyContactWidget *information)
{
g_source_remove (information->widget_id_timeout);
}
- if (information->factory)
- {
- g_object_unref (information->factory);
- }
if (information->manager)
{
g_object_unref (information->manager);
- }
+ }
g_slice_free (EmpathyContactWidget, information);
}
contact_widget_groups_notify_cb, information);
g_object_unref (information->contact);
+ g_object_unref (information->factory);
information->contact = NULL;
+ information->factory = NULL;
}
}
contact_widget_remove_contact (information);
if (contact)
+ {
+ TpConnection *connection;
+
+ connection = empathy_contact_get_connection (contact);
information->contact = g_object_ref (contact);
+ information->factory = empathy_tp_contact_factory_dup_singleton (connection);
+ }
+
+ /* set the selected account to be the account this contact came from */
+ if (contact && EMPATHY_IS_ACCOUNT_CHOOSER (information->widget_account)) {
+ empathy_account_chooser_set_account (
+ EMPATHY_ACCOUNT_CHOOSER (information->widget_account),
+ empathy_contact_get_account (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);
+ contact_widget_location_update (information);
}
static gboolean
EmpathyContactWidget *self)
{
if (self->widget_id_timeout != 0)
- {
+ {
g_source_remove (self->widget_id_timeout);
}
GtkWidget *dialog;
dialog = gtk_message_dialog_new (NULL, 0,
- GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE,
+ GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE,
_("Unable to save avatar"));
gtk_message_dialog_format_secondary_text (
}
gtk_menu_attach_to_widget (GTK_MENU (menu), parent, NULL);
- gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL,
+ gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL,
button, event_time);
}
return FALSE;
}
+static void
+update_avatar_chooser_account_cb (EmpathyAccountChooser *account_chooser,
+ EmpathyAvatarChooser *avatar_chooser)
+{
+ TpConnection *connection;
+
+ connection = empathy_account_chooser_get_connection (account_chooser);
+ g_object_set (avatar_chooser, "connection", connection, NULL);
+}
+
static void
contact_widget_contact_setup (EmpathyContactWidget *information)
{
+ /* Setup label_status as a KludgeLabel */
+ information->label_status = empathy_kludge_label_new ("");
+ gtk_label_set_line_wrap_mode (GTK_LABEL (information->label_status),
+ PANGO_WRAP_WORD_CHAR);
+ gtk_label_set_line_wrap (GTK_LABEL (information->label_status),
+ TRUE);
+
+ if (!(information->flags & EMPATHY_CONTACT_WIDGET_FOR_TOOLTIP))
+ gtk_label_set_selectable (GTK_LABEL (information->label_status), TRUE);
+
+ gtk_box_pack_start (GTK_BOX (information->hbox_presence),
+ information->label_status, TRUE, TRUE, 0);
+ gtk_widget_show (information->label_status);
+
/* Setup account label/chooser */
if (information->flags & EMPATHY_CONTACT_WIDGET_EDIT_ACCOUNT)
{
information->widget_account = empathy_account_chooser_new ();
- g_signal_connect (information->widget_account, "changed",
- G_CALLBACK (contact_widget_account_changed_cb),
+ g_signal_connect_swapped (information->widget_account, "changed",
+ G_CALLBACK (contact_widget_change_contact),
information);
- contact_widget_update_avatar_chooser_account (information);
}
else
{
g_signal_connect (information->widget_avatar, "changed",
G_CALLBACK (contact_widget_avatar_changed_cb),
information);
+ if (information->flags & EMPATHY_CONTACT_WIDGET_EDIT_ACCOUNT)
+ {
+ g_signal_connect (information->widget_account, "changed",
+ G_CALLBACK (update_avatar_chooser_account_cb),
+ information->widget_avatar);
+ update_avatar_chooser_account_cb (
+ EMPATHY_ACCOUNT_CHOOSER (information->widget_account),
+ EMPATHY_AVATAR_CHOOSER (information->widget_avatar));
+ }
}
else
{
static void
contact_widget_contact_update (EmpathyContactWidget *information)
{
- McAccount *account = NULL;
+ EmpathyAccount *account = NULL;
const gchar *id = NULL;
/* Connect and get info from new contact */
if (account)
{
g_signal_handlers_block_by_func (information->widget_account,
- contact_widget_account_changed_cb,
+ contact_widget_change_contact,
information);
empathy_account_chooser_set_account (
EMPATHY_ACCOUNT_CHOOSER (information->widget_account), account);
g_signal_handlers_unblock_by_func (information->widget_account,
- contact_widget_account_changed_cb, information);
+ contact_widget_change_contact, information);
}
}
else
{
const gchar *name;
- name = mc_account_get_display_name (account);
+ name = empathy_account_get_display_name (account);
gtk_label_set_label (GTK_LABEL (information->widget_account), name);
}
}
}
}
+static void
+contact_widget_got_contact_cb (EmpathyTpContactFactory *factory,
+ EmpathyContact *contact,
+ const GError *error,
+ gpointer user_data,
+ GObject *weak_object)
+{
+ EmpathyContactWidget *information = user_data;
+
+ if (error != NULL)
+ {
+ DEBUG ("Error: %s", error->message);
+ return;
+ }
+
+ contact_widget_set_contact (information, contact);
+}
+
static void
contact_widget_change_contact (EmpathyContactWidget *information)
{
- EmpathyContact *contact;
- McAccount *account;
+ EmpathyTpContactFactory *factory;
+ TpConnection *connection;
- account = empathy_account_chooser_get_account (
+ connection = empathy_account_chooser_get_connection (
EMPATHY_ACCOUNT_CHOOSER (information->widget_account));
- if (!account)
+ if (!connection)
return;
+ factory = empathy_tp_contact_factory_dup_singleton (connection);
if (information->flags & EMPATHY_CONTACT_WIDGET_EDIT_ID)
{
const gchar *id;
id = gtk_entry_get_text (GTK_ENTRY (information->widget_id));
- if (G_STR_EMPTY (id))
- return;
-
- contact = empathy_contact_factory_get_from_id (information->factory,
- account, id);
+ if (!EMP_STR_EMPTY (id))
+ {
+ empathy_tp_contact_factory_get_from_id (factory, id,
+ contact_widget_got_contact_cb, information, NULL,
+ G_OBJECT (information->vbox_contact_widget));
+ }
}
else
{
- contact = empathy_contact_factory_get_user (information->factory,
- account);
+ empathy_tp_contact_factory_get_from_handle (factory,
+ tp_connection_get_self_handle (connection),
+ contact_widget_got_contact_cb, information, NULL,
+ G_OBJECT (information->vbox_contact_widget));
}
- if (contact)
- {
- empathy_contact_run_until_ready (contact,
- EMPATHY_CONTACT_READY_HANDLE |
- EMPATHY_CONTACT_READY_ID,
- NULL);
- contact_widget_set_contact (information, contact);
- g_object_unref (contact);
- }
+ g_object_unref (factory);
}
static void
contact_widget_avatar_changed_cb (EmpathyAvatarChooser *chooser,
EmpathyContactWidget *information)
{
- if (information->contact && empathy_contact_is_user (information->contact))
- {
- McAccount *account;
- const gchar *data;
- gsize size;
- const gchar *mime_type;
-
- account = empathy_contact_get_account (information->contact);
- empathy_avatar_chooser_get_image_data (
- EMPATHY_AVATAR_CHOOSER (information->widget_avatar),
- &data, &size, &mime_type);
- empathy_contact_factory_set_avatar (information->factory, account,
- data, size, mime_type);
- }
-}
-
-static void
-contact_widget_update_avatar_chooser_account (EmpathyContactWidget *information)
-{
- McAccount *account;
- EmpathyAccountChooser *account_chooser;
-
- g_assert (EMPATHY_IS_ACCOUNT_CHOOSER (information->widget_account));
- account_chooser = EMPATHY_ACCOUNT_CHOOSER (information->widget_account);
-
- if (information->flags & EMPATHY_CONTACT_WIDGET_EDIT_AVATAR)
- {
- g_assert (EMPATHY_IS_AVATAR_CHOOSER (information->widget_avatar));
-
- account = empathy_account_chooser_get_account (account_chooser);
- g_object_set (information->widget_avatar, "account", account, NULL);
- }
-}
-
-static void
-contact_widget_account_changed_cb (GtkComboBox *widget,
- EmpathyContactWidget *information)
-{
- contact_widget_update_avatar_chooser_account (information);
- contact_widget_change_contact (information);
+ const gchar *data;
+ gsize size;
+ const gchar *mime_type;
+
+ empathy_avatar_chooser_get_image_data (
+ EMPATHY_AVATAR_CHOOSER (information->widget_avatar),
+ &data, &size, &mime_type);
+ empathy_tp_contact_factory_set_avatar (information->factory,
+ data, size, mime_type);
}
static gboolean
const gchar *alias;
alias = gtk_entry_get_text (GTK_ENTRY (editable));
- empathy_contact_factory_set_alias (information->factory,
+ empathy_tp_contact_factory_set_alias (information->factory,
information->contact, alias);
}
{
if (information->flags & EMPATHY_CONTACT_WIDGET_EDIT_GROUPS)
{
- information->manager = empathy_contact_manager_new ();
+ information->manager = empathy_contact_manager_dup_singleton ();
contact_widget_model_setup (information);
}
}
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
GtkTreeModel *model;
FindName data;
- if (G_STR_EMPTY (name))
+ if (EMP_STR_EMPTY (name))
return FALSE;
data.information = information;
gtk_widget_set_sensitive (GTK_WIDGET (information->button_group), FALSE);
else
gtk_widget_set_sensitive (GTK_WIDGET (information->button_group),
- !G_STR_EMPTY (group));
+ !EMP_STR_EMPTY (group));
}
static void
{
/* FIXME: Needs new telepathy spec */
}
+
+/* Converts the Location's GHashTable's key to a user readable string */
+static const gchar *
+location_key_to_label (const gchar *key)
+{
+ if (tp_strdiff (key, EMPATHY_LOCATION_COUNTRY_CODE) == FALSE)
+ return _("Country ISO Code:");
+ else if (tp_strdiff (key, EMPATHY_LOCATION_COUNTRY) == FALSE)
+ return _("Country:");
+ else if (tp_strdiff (key, EMPATHY_LOCATION_REGION) == FALSE)
+ return _("State:");
+ else if (tp_strdiff (key, EMPATHY_LOCATION_LOCALITY) == FALSE)
+ return _("City:");
+ else if (tp_strdiff (key, EMPATHY_LOCATION_AREA) == FALSE)
+ return _("Area:");
+ else if (tp_strdiff (key, EMPATHY_LOCATION_POSTAL_CODE) == FALSE)
+ return _("Postal Code:");
+ else if (tp_strdiff (key, EMPATHY_LOCATION_STREET) == FALSE)
+ return _("Street:");
+ else if (tp_strdiff (key, EMPATHY_LOCATION_BUILDING) == FALSE)
+ return _("Building:");
+ else if (tp_strdiff (key, EMPATHY_LOCATION_FLOOR) == FALSE)
+ return _("Floor:");
+ else if (tp_strdiff (key, EMPATHY_LOCATION_ROOM) == FALSE)
+ return _("Room:");
+ else if (tp_strdiff (key, EMPATHY_LOCATION_TEXT) == FALSE)
+ return _("Text:");
+ else if (tp_strdiff (key, EMPATHY_LOCATION_DESCRIPTION) == FALSE)
+ return _("Description:");
+ else if (tp_strdiff (key, EMPATHY_LOCATION_URI) == FALSE)
+ return _("URI:");
+ else if (tp_strdiff (key, EMPATHY_LOCATION_ACCURACY_LEVEL) == FALSE)
+ return _("Accuracy Level:");
+ else if (tp_strdiff (key, EMPATHY_LOCATION_ERROR) == FALSE)
+ return _("Error:");
+ else if (tp_strdiff (key, EMPATHY_LOCATION_VERTICAL_ERROR_M) == FALSE)
+ return _("Vertical Error (meters):");
+ else if (tp_strdiff (key, EMPATHY_LOCATION_HORIZONTAL_ERROR_M) == FALSE)
+ return _("Horizontal Error (meters):");
+ else if (tp_strdiff (key, EMPATHY_LOCATION_SPEED) == FALSE)
+ return _("Speed:");
+ else if (tp_strdiff (key, EMPATHY_LOCATION_BEARING) == FALSE)
+ return _("Bearing:");
+ else if (tp_strdiff (key, EMPATHY_LOCATION_CLIMB) == FALSE)
+ return _("Climb Speed:");
+ else if (tp_strdiff (key, EMPATHY_LOCATION_TIMESTAMP) == FALSE)
+ return _("Last Updated on:");
+ else if (tp_strdiff (key, EMPATHY_LOCATION_LON) == FALSE)
+ return _("Longitude:");
+ else if (tp_strdiff (key, EMPATHY_LOCATION_LAT) == FALSE)
+ return _("Latitude:");
+ else if (tp_strdiff (key, EMPATHY_LOCATION_ALT) == FALSE)
+ return _("Altitude:");
+ else
+ {
+ DEBUG ("Unexpected Location key: %s", key);
+ return key;
+ }
+}
+
+static void
+contact_widget_location_update (EmpathyContactWidget *information)
+{
+ GHashTable *location;
+ GValue *value;
+ gdouble lat = 0.0, lon = 0.0;
+ gboolean has_position = TRUE;
+ GtkWidget *label;
+ guint row = 0;
+ GHashTableIter iter;
+ gpointer key, pvalue;
+
+ if (!(information->flags & EMPATHY_CONTACT_WIDGET_SHOW_LOCATION))
+ {
+ gtk_widget_hide (information->vbox_location);
+ return;
+ }
+
+ location = empathy_contact_get_location (information->contact);
+ if (location == NULL || g_hash_table_size (location) == 0)
+ {
+ gtk_widget_hide (information->vbox_location);
+ return;
+ }
+
+ value = g_hash_table_lookup (location, EMPATHY_LOCATION_LAT);
+ if (value == NULL)
+ has_position = FALSE;
+ else
+ lat = g_value_get_double (value);
+
+ value = g_hash_table_lookup (location, EMPATHY_LOCATION_LON);
+ if (value == NULL)
+ has_position = FALSE;
+ else
+ lon = g_value_get_double (value);
+
+ value = g_hash_table_lookup (location, EMPATHY_LOCATION_TIMESTAMP);
+ if (value == NULL)
+ gtk_label_set_markup (GTK_LABEL (information->label_location), _("<b>Location</b>"));
+ else
+ {
+ gchar *user_date;
+ gchar *text;
+ gint64 stamp;
+ time_t time;
+
+ stamp = g_value_get_int64 (value);
+ time = stamp;
+
+ user_date = empathy_time_to_string_relative (time);
+
+ text = g_strconcat ( _("<b>Location</b>, "), user_date, NULL);
+ gtk_label_set_markup (GTK_LABEL (information->label_location), text);
+ g_free (text);
+ }
+
+
+ /* Prepare the location information table */
+ if (information->table_location != NULL)
+ {
+ gtk_widget_destroy (information->table_location);
+ }
+
+ information->table_location = gtk_table_new (1, 2, FALSE);
+ gtk_box_pack_start (GTK_BOX (information->subvbox_location),
+ information->table_location, FALSE, FALSE, 5);
+
+ g_hash_table_iter_init (&iter, location);
+ while (g_hash_table_iter_next (&iter, &key, &pvalue))
+ {
+ const gchar *skey;
+ const gchar* user_label;
+ GValue *gvalue;
+ char *svalue = NULL;
+
+ skey = (const gchar *) key;
+
+ user_label = location_key_to_label (skey);
+ gvalue = (GValue *) pvalue;
+
+ label = gtk_label_new (user_label);
+ gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
+ gtk_table_attach (GTK_TABLE (information->table_location),
+ label, 0, 1, row, row + 1, GTK_FILL, GTK_FILL, 10, 0);
+ gtk_widget_show (label);
+
+ if (G_VALUE_TYPE (gvalue) == G_TYPE_DOUBLE)
+ {
+ gdouble dvalue;
+ dvalue = g_value_get_double (gvalue);
+ svalue = g_strdup_printf ("%f", dvalue);
+ }
+ else if (G_VALUE_TYPE (gvalue) == G_TYPE_STRING)
+ {
+ svalue = g_value_dup_string (gvalue);
+ }
+ else if (G_VALUE_TYPE (gvalue) == G_TYPE_INT64)
+ {
+ time_t time;
+
+ time = g_value_get_int64 (value);
+ svalue = empathy_time_to_string_utc (time, _("%B %e, %Y at %R UTC"));
+ }
+
+ if (svalue != NULL)
+ {
+ label = gtk_label_new (svalue);
+ gtk_table_attach_defaults (GTK_TABLE (information->table_location),
+ label, 1, 2, row, row + 1);
+ gtk_misc_set_alignment (GTK_MISC (label), 0, 0);
+ gtk_widget_show (label);
+ }
+
+ g_free (svalue);
+ row++;
+ }
+
+ gtk_widget_show (information->table_location);
+
+#if HAVE_LIBCHAMPLAIN
+ /* Cannot be displayed in tooltips until Clutter-Gtk can deal with such
+ * windows
+ */
+ if (has_position &&
+ !(information->flags & EMPATHY_CONTACT_WIDGET_FOR_TOOLTIP))
+ {
+ ClutterActor *marker;
+ ChamplainLayer *layer;
+
+ information->map_view_embed = gtk_champlain_embed_new ();
+ information->map_view = gtk_champlain_embed_get_view (
+ GTK_CHAMPLAIN_EMBED (information->map_view_embed));
+
+ gtk_container_add (GTK_CONTAINER (information->viewport_map),
+ information->map_view_embed);
+ g_object_set (G_OBJECT (information->map_view), "show-license", FALSE,
+ "scroll-mode", CHAMPLAIN_SCROLL_MODE_KINETIC,
+ NULL);
+
+ layer = champlain_layer_new ();
+ champlain_view_add_layer (information->map_view, layer);
+
+ marker = champlain_marker_new_with_text (
+ empathy_contact_get_name (information->contact), NULL, NULL, NULL);
+ champlain_base_marker_set_position (CHAMPLAIN_BASE_MARKER (marker), lat, lon);
+ clutter_container_add (CLUTTER_CONTAINER (layer), marker, NULL);
+
+ champlain_view_center_on (information->map_view, lat, lon);
+ gtk_widget_show_all (information->viewport_map);
+ }
+#endif
+
+ gtk_widget_show (information->vbox_location);
+}