~ubuntu-branches/ubuntu/precise/empathy/precise-proposed-201205180810

« back to all changes in this revision

Viewing changes to libempathy-gtk/empathy-individual-widget.c

  • Committer: Bazaar Package Importer
  • Author(s): Brian Curtis, Brian Curtis, Ken VanDine
  • Date: 2011-06-01 10:35:24 UTC
  • mfrom: (1.1.70 upstream) (6.3.44 experimental)
  • Revision ID: james.westby@ubuntu.com-20110601103524-wx3wgp71394730jt
Tags: 3.1.1-1ubuntu1
[ Brian Curtis ]
* Merge with Debian experimental, remaining Ubuntu changes:
* debian/control:
  - Drop geoclue/mapping build-depends (they are in Universe)
  - Add Vcz-Bzr link
  - Add Suggests on telepathy-idle
  - Bump telepathy-butterfly, telepathy-haze to recommends
  - Don't recommend the freedesktop sound theme we have an ubuntu one
  - Add build depend for libunity-dev
* debian/rules:
  - Use autoreconf.mk
  - Disable map and location
* debian/empathy.install:
  - Install message indicator configuration
* debian/indicators/empathy:
  - Message indicator configuration
* debian/patches/01_lpi.patch:
  - Add Launchpad integration
* debian/patches/10_use_notify_osd_icons.patch:
  - Use the notify-osd image for new messages
* debian/patches/34_start_raised_execpt_in_session.patch
  - If not started with the session, we should always raise
* debian/patches/36_chat_window_default_size.patch:
  - Make the default chat window size larger
* debian/patches/37_facebook_default.patch:
  - Make facebook the default chat account type
* debian/patches/38_lp_569289.patch
  - Set freenode as default IRC network for new IRC accounts 
* debian/patches/41_unity_launcher_progress.patch
  - Display file transfer progress in the unity launcher

[ Ken VanDine ]
* debian/control
  - build depend on libgcr-3-dev instead of libgcr-dev
  - dropped build depends for libindicate, we will use telepathy-indicator
  - Depend on dconf-gsettings-backend | gsettings-backend
  - Added a Recommends for telepathy-indicator
* +debian/empathy.gsettings-override
  - Added an override for notifications-focus
* debian/patches/series
  - commented out 23_idomessagedialog_for_voip_and_ft.patch, until ido has 
    been ported to gtk3

Show diffs side-by-side

added added

removed removed

Lines of Context:
45
45
#include "empathy-groups-widget.h"
46
46
#include "empathy-gtk-enum-types.h"
47
47
#include "empathy-individual-widget.h"
48
 
#include "empathy-kludge-label.h"
49
48
#include "empathy-string-parser.h"
50
49
#include "empathy-ui-utils.h"
51
50
 
79
78
  EmpathyIndividualWidgetFlags flags;
80
79
 
81
80
  /* weak pointer to the contact whose contact details we're displaying */
82
 
  TpContact *contact_info_contact;
 
81
  TpContact *contact;
83
82
 
84
83
  /* unowned Persona (borrowed from priv->individual) -> GtkTable child */
85
84
  GHashTable *persona_tables;
107
106
  /* Groups */
108
107
  GtkWidget *groups_widget;
109
108
 
 
109
  /* Client types */
 
110
  GtkWidget *hbox_client_types;
 
111
 
110
112
  /* Details */
111
113
  GtkWidget *vbox_details;
112
114
  GtkWidget *table_details;
123
125
  PROP_FLAGS
124
126
};
125
127
 
 
128
static void client_types_update (EmpathyIndividualWidget *self);
 
129
static void remove_weak_contact (EmpathyIndividualWidget *self);
 
130
 
126
131
static void
127
132
details_set_up (EmpathyIndividualWidget *self)
128
133
{
194
199
  return contact_info_field_name_cmp (field1->field_name, field2->field_name);
195
200
}
196
201
 
 
202
static void
 
203
client_types_notify_cb (TpContact *contact,
 
204
    GParamSpec *pspec,
 
205
    EmpathyIndividualWidget *self)
 
206
{
 
207
  client_types_update (self);
 
208
}
 
209
 
 
210
static void
 
211
update_weak_contact (EmpathyIndividualWidget *self)
 
212
{
 
213
  EmpathyIndividualWidgetPriv *priv = GET_PRIV (self);
 
214
  TpContact *tp_contact = NULL;
 
215
 
 
216
  remove_weak_contact (self);
 
217
 
 
218
  if (priv->individual != NULL)
 
219
    {
 
220
      /* FIXME: We take the most available TpContact we find and only
 
221
       * use its details. It would be a lot better if we would get the
 
222
       * details for every TpContact in the Individual and merge them
 
223
       * all, but that requires vCard support in libfolks for it to
 
224
       * not be hideously complex.  (bgo#627399) */
 
225
      GList *personas, *l;
 
226
      FolksPresenceType presence_type = FOLKS_PRESENCE_TYPE_UNSET;
 
227
 
 
228
      personas = folks_individual_get_personas (priv->individual);
 
229
      for (l = personas; l != NULL; l = l->next)
 
230
        {
 
231
          FolksPresenceDetails *presence;
 
232
 
 
233
          /* We only want personas which implement FolksPresence */
 
234
          if (!FOLKS_IS_PRESENCE_DETAILS (l->data))
 
235
            continue;
 
236
 
 
237
          presence = FOLKS_PRESENCE_DETAILS (l->data);
 
238
 
 
239
          if (folks_presence_details_typecmp (
 
240
                  folks_presence_details_get_presence_type (presence),
 
241
                  presence_type) > 0 &&
 
242
              empathy_folks_persona_is_interesting (FOLKS_PERSONA (presence)))
 
243
            {
 
244
              presence_type = folks_presence_details_get_presence_type (
 
245
                  presence);
 
246
              tp_contact = tpf_persona_get_contact (TPF_PERSONA (l->data));
 
247
            }
 
248
        }
 
249
    }
 
250
 
 
251
  if (tp_contact != NULL)
 
252
    {
 
253
      priv->contact = tp_contact;
 
254
      g_object_add_weak_pointer (G_OBJECT (tp_contact),
 
255
          (gpointer *) &priv->contact);
 
256
 
 
257
      g_signal_connect (priv->contact, "notify::client-types",
 
258
          (GCallback) client_types_notify_cb, self);
 
259
    }
 
260
}
 
261
 
197
262
typedef struct {
198
263
  EmpathyIndividualWidget *widget; /* weak */
199
264
  TpContact *contact; /* owned */
325
390
 
326
391
      tp_clear_object (&priv->details_cancellable);
327
392
 
328
 
      /* We need a (weak) pointer to the contact so that we can disconnect the
329
 
       * signal handler on deconstruction. */
330
 
      if (priv->contact_info_contact != NULL)
331
 
        {
332
 
          g_object_remove_weak_pointer (G_OBJECT (priv->contact_info_contact),
333
 
            (gpointer *) &priv->contact_info_contact);
334
 
        }
335
 
 
336
 
      priv->contact_info_contact = contact;
337
 
      g_object_add_weak_pointer (G_OBJECT (contact),
338
 
          (gpointer *) &priv->contact_info_contact);
339
 
 
340
393
      g_signal_connect (contact, "notify::contact-info",
341
394
          (GCallback) details_notify_cb, self);
342
395
    }
381
434
details_update (EmpathyIndividualWidget *self)
382
435
{
383
436
  EmpathyIndividualWidgetPriv *priv = GET_PRIV (self);
384
 
  TpContact *tp_contact = NULL;
385
437
 
386
438
  if (!(priv->flags & EMPATHY_INDIVIDUAL_WIDGET_SHOW_DETAILS))
387
439
    return;
388
440
 
389
441
  gtk_widget_hide (priv->vbox_details);
390
442
 
391
 
  if (priv->individual != NULL)
392
 
    {
393
 
      /* FIXME: We take the first TpContact we find and only use its details.
394
 
       * It would be a lot better if we would get the details for every
395
 
       * TpContact in the Individual and merge them all, but that requires
396
 
       * vCard support in libfolks for it to not be hideously complex.
397
 
       * (bgo#627399) */
398
 
      GList *personas, *l;
399
 
 
400
 
      personas = folks_individual_get_personas (priv->individual);
401
 
      for (l = personas; l != NULL; l = l->next)
402
 
        {
403
 
          if (empathy_folks_persona_is_interesting (FOLKS_PERSONA (l->data)))
404
 
            {
405
 
              tp_contact = tpf_persona_get_contact (TPF_PERSONA (l->data));
406
 
              if (tp_contact != NULL)
407
 
                break;
408
 
            }
409
 
        }
410
 
    }
411
 
 
412
 
  if (tp_contact != NULL)
 
443
  if (priv->contact == NULL)
 
444
    update_weak_contact (self);
 
445
 
 
446
  if (priv->contact != NULL)
413
447
    {
414
448
      GQuark features[] = { TP_CONNECTION_FEATURE_CONTACT_INFO, 0 };
415
449
      TpConnection *connection;
418
452
      data = g_slice_new (DetailsData);
419
453
      data->widget = self;
420
454
      g_object_add_weak_pointer (G_OBJECT (self), (gpointer *) &data->widget);
421
 
      data->contact = g_object_ref (tp_contact);
 
455
      data->contact = g_object_ref (priv->contact);
422
456
 
423
457
      /* First, make sure the CONTACT_INFO feature is ready on the connection */
424
 
      connection = tp_contact_get_connection (tp_contact);
 
458
      connection = tp_contact_get_connection (priv->contact);
425
459
      tp_proxy_prepare_async (connection, features,
426
460
          (GAsyncReadyCallback) details_feature_prepared_cb, data);
427
461
    }
588
622
      gchar *user_date;
589
623
      gchar *text;
590
624
      gint64 stamp;
591
 
      time_t time_;
592
625
      gchar *tmp;
593
626
 
594
627
      stamp = g_value_get_int64 (value);
595
 
      time_ = stamp;
596
628
 
597
 
      user_date = empathy_time_to_string_relative (time_);
 
629
      user_date = empathy_time_to_string_relative (stamp);
598
630
 
599
631
      tmp = g_strdup_printf ("<b>%s</b>", _("Location"));
600
632
      /* translators: format is "Location, $date" */
644
676
        }
645
677
      else if (G_VALUE_TYPE (gvalue) == G_TYPE_INT64)
646
678
        {
647
 
          time_t time_;
 
679
          gint64 time_;
648
680
 
649
681
          time_ = g_value_get_int64 (value);
650
682
          svalue = empathy_time_to_string_utc (time_, _("%B %e, %Y at %R UTC"));
695
727
#ifdef HAVE_LIBCHAMPLAIN
696
728
  if (display_map == TRUE)
697
729
    {
698
 
      GPtrArray *markers;
699
 
      ChamplainLayer *layer;
 
730
      ChamplainMarkerLayer *layer;
700
731
 
701
732
      priv->map_view_embed = gtk_champlain_embed_new ();
702
733
      priv->map_view = gtk_champlain_embed_get_view (
705
736
      gtk_container_add (GTK_CONTAINER (priv->viewport_map),
706
737
          priv->map_view_embed);
707
738
      g_object_set (G_OBJECT (priv->map_view),
708
 
          "show-license", TRUE,
709
 
          "scroll-mode", CHAMPLAIN_SCROLL_MODE_KINETIC,
 
739
          "kinetic-mode", TRUE,
710
740
          "zoom-level", 10,
711
741
          NULL);
712
742
 
713
 
      layer = champlain_layer_new ();
714
 
      champlain_view_add_layer (priv->map_view, layer);
715
 
      markers = g_ptr_array_new ();
 
743
      layer = champlain_marker_layer_new ();
 
744
      champlain_view_add_layer (priv->map_view, CHAMPLAIN_LAYER (layer));
716
745
 
717
746
      /* FIXME: For now, we have to do this manually. Once libfolks grows a
718
747
       * location interface, we can use that. (bgo#627400) */
760
789
              lon = g_value_get_double (value);
761
790
 
762
791
              /* Add a marker to the map */
763
 
              marker = champlain_marker_new_with_text (
 
792
              marker = champlain_label_new_with_text (
764
793
                  folks_alias_details_get_alias (FOLKS_ALIAS_DETAILS (persona)),
765
794
                  NULL, NULL, NULL);
766
 
              champlain_base_marker_set_position (
767
 
                  CHAMPLAIN_BASE_MARKER (marker), lat, lon);
768
 
              clutter_container_add (CLUTTER_CONTAINER (layer), marker, NULL);
769
 
 
770
 
              g_ptr_array_add (markers, marker);
 
795
              champlain_location_set_location (CHAMPLAIN_LOCATION (marker),
 
796
                  lat, lon);
 
797
              champlain_marker_layer_add_marker (layer,
 
798
                  CHAMPLAIN_MARKER (marker));
771
799
 
772
800
              g_object_unref (contact);
773
801
            }
774
802
        }
775
803
 
776
804
      /* Zoom to show all of the markers */
777
 
      g_ptr_array_add (markers, NULL); /* NULL-terminate the array */
778
 
      champlain_view_ensure_markers_visible (priv->map_view,
779
 
          (ChamplainBaseMarker **) markers->pdata, FALSE);
780
 
      g_ptr_array_free (markers, TRUE);
 
805
      champlain_view_ensure_layers_visible (priv->map_view, FALSE);
781
806
 
782
807
      gtk_widget_show_all (priv->viewport_map);
783
808
    }
786
811
    gtk_widget_show (priv->vbox_location);
787
812
}
788
813
 
 
814
static void
 
815
client_types_update (EmpathyIndividualWidget *self)
 
816
{
 
817
  EmpathyIndividualWidgetPriv *priv = GET_PRIV (self);
 
818
  const gchar * const *types;
 
819
 
 
820
  if (!(priv->flags & EMPATHY_INDIVIDUAL_WIDGET_SHOW_CLIENT_TYPES) ||
 
821
      priv->individual == NULL)
 
822
    {
 
823
      gtk_widget_hide (priv->hbox_client_types);
 
824
      return;
 
825
    }
 
826
 
 
827
  if (priv->contact == NULL)
 
828
    update_weak_contact (self);
 
829
 
 
830
  /* let's try that again... */
 
831
  if (priv->contact == NULL)
 
832
    return;
 
833
 
 
834
  types = tp_contact_get_client_types (priv->contact);
 
835
 
 
836
  if (types != NULL
 
837
      && g_strv_length ((gchar **) types) > 0
 
838
      && !tp_strdiff (types[0], "phone"))
 
839
    {
 
840
      gtk_widget_show (priv->hbox_client_types);
 
841
    }
 
842
  else
 
843
    {
 
844
      gtk_widget_hide (priv->hbox_client_types);
 
845
    }
 
846
 
 
847
}
 
848
 
 
849
static void
 
850
remove_weak_contact (EmpathyIndividualWidget *self)
 
851
{
 
852
  EmpathyIndividualWidgetPriv *priv = GET_PRIV (self);
 
853
 
 
854
  if (priv->contact == NULL)
 
855
    return;
 
856
 
 
857
  g_signal_handlers_disconnect_by_func (priv->contact, client_types_notify_cb,
 
858
      self);
 
859
 
 
860
  g_object_remove_weak_pointer (G_OBJECT (priv->contact),
 
861
      (gpointer *) &priv->contact);
 
862
  priv->contact = NULL;
 
863
}
 
864
 
789
865
static EmpathyAvatar *
790
866
persona_dup_avatar (FolksPersona *persona)
791
867
{
934
1010
    return FALSE;
935
1011
  empathy_avatar_unref (avatar);
936
1012
 
937
 
  menu = gtk_menu_new ();
 
1013
  menu = empathy_context_menu_new (parent);
938
1014
 
939
1015
  /* Add "Save as..." entry */
940
1016
  item = gtk_image_menu_item_new_from_stock (GTK_STOCK_SAVE_AS, NULL);
955
1031
      event_time = gtk_get_current_event_time ();
956
1032
    }
957
1033
 
958
 
  gtk_menu_attach_to_widget (GTK_MENU (menu), parent, NULL);
959
1034
  gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL, button, event_time);
960
 
  g_object_ref_sink (menu);
961
 
  g_object_unref (menu);
962
1035
 
963
1036
  return TRUE;
964
1037
}
996
1069
    {
997
1070
      FolksPersona *persona = FOLKS_PERSONA (l->data);
998
1071
 
999
 
      if (empathy_folks_persona_is_interesting (persona))
 
1072
      if (TPF_IS_PERSONA (persona))
1000
1073
        {
1001
1074
          TpContact *tp_contact;
1002
1075
          EmpathyContact *contact;
1272
1345
      FALSE, 0);
1273
1346
  gtk_widget_show (image);
1274
1347
 
1275
 
  /* Set up status_label as a KludgeLabel */
1276
 
  label = empathy_kludge_label_new ("");
 
1348
  label = gtk_label_new ("");
1277
1349
  gtk_label_set_line_wrap_mode (GTK_LABEL (label), PANGO_WRAP_WORD_CHAR);
1278
1350
  gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
 
1351
  gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
1279
1352
 
1280
1353
  gtk_label_set_selectable (GTK_LABEL (label),
1281
1354
      (priv->flags & EMPATHY_INDIVIDUAL_WIDGET_FOR_TOOLTIP) ? FALSE : TRUE);
1571
1644
            num_personas++;
1572
1645
        }
1573
1646
 
1574
 
      message = g_strdup_printf (ngettext ("Meta-contact containing %u contact",
1575
 
          "Meta-contact containing %u contacts", num_personas), num_personas);
 
1647
      /* Translators: the plurality applies to both instances of the word
 
1648
       * "contact" */
 
1649
      message = g_strdup_printf (
 
1650
          ngettext ("Linked contact containing %u contact",
 
1651
              "Linked contacts containing %u contacts", num_personas),
 
1652
          num_personas);
1576
1653
      label = gtk_label_new (message);
1577
1654
      gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
1578
1655
      g_free (message);
1747
1824
        remove_persona (self, FOLKS_PERSONA (l->data));
1748
1825
      individual_table_destroy (self);
1749
1826
 
1750
 
      if (priv->contact_info_contact != NULL)
1751
 
        {
1752
 
          g_signal_handlers_disconnect_by_func (priv->contact_info_contact,
1753
 
              details_notify_cb, self);
1754
 
          g_object_remove_weak_pointer (G_OBJECT (priv->contact_info_contact),
1755
 
              (gpointer *) &priv->contact_info_contact);
1756
 
          priv->contact_info_contact = NULL;
1757
 
        }
 
1827
      if (priv->contact != NULL)
 
1828
        remove_weak_contact (self);
1758
1829
 
1759
1830
      tp_clear_object (&priv->individual);
1760
1831
    }
1853
1924
      "vbox_details", &priv->vbox_details,
1854
1925
      "table_details", &priv->table_details,
1855
1926
      "hbox_details_requested", &priv->hbox_details_requested,
 
1927
      "hbox_client_types", &priv->hbox_client_types,
1856
1928
      NULL);
1857
1929
  g_free (filename);
1858
1930
 
2086
2158
  groups_update (self);
2087
2159
  details_update (self);
2088
2160
  location_update (self);
 
2161
  client_types_update (self);
2089
2162
}