#include <gtk/gtk.h>
#include <glib/gi18n-lib.h>
-#include <libmissioncontrol/mc-account.h>
+#if HAVE_LIBCHAMPLAIN
+#include <champlain/champlain.h>
+#include <champlain-gtk/champlain-gtk.h>
+#endif
+
#include <telepathy-glib/util.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>
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_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
{
"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,
"entry_group", "activate", contact_widget_entry_group_activate_cb,
"button_group", "clicked", contact_widget_button_group_clicked_cb,
NULL);
+ information->table_location = NULL;
g_object_set_data (G_OBJECT (information->vbox_contact_widget),
"EmpathyContactWidget",
if (chooser)
empathy_account_chooser_set_filter (chooser, filter, user_data);
}
-
+
static void
contact_widget_destroy_cb (GtkWidget *widget,
EmpathyContactWidget *information)
if (information->manager)
{
g_object_unref (information->manager);
- }
+ }
g_slice_free (EmpathyContactWidget, information);
}
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);
}
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)
{
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 */
{
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);
}
}
{
/* 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);
+}