~ubuntu-branches/ubuntu/precise/empathy/precise

« back to all changes in this revision

Viewing changes to libempathy-gtk/empathy-contact-list-view.c

Tags: upstream-0.21.90
ImportĀ upstreamĀ versionĀ 0.21.90

Show diffs side-by-side

added added

removed removed

Lines of Context:
40
40
#include <libempathy/empathy-contact-list.h>
41
41
#include <libempathy/empathy-log-manager.h>
42
42
#include <libempathy/empathy-tp-group.h>
 
43
#include <libempathy/empathy-contact-groups.h>
43
44
#include <libempathy/empathy-debug.h>
44
45
#include <libempathy/empathy-utils.h>
45
 
#include <libempathy/empathy-marshal.h>
46
46
 
47
47
#include "empathy-contact-list-view.h"
48
48
#include "empathy-contact-list-store.h"
49
49
#include "empathy-images.h"
50
 
#include "empathy-contact-groups.h"
51
50
#include "empathy-cell-renderer-expander.h"
52
51
#include "empathy-cell-renderer-text.h"
53
52
#include "empathy-cell-renderer-activatable.h"
56
55
//#include "empathy-chat-invite.h"
57
56
//#include "empathy-ft-window.h"
58
57
#include "empathy-log-window.h"
 
58
#include "empathy-gtk-enum-types.h"
 
59
#include "empathy-gtk-marshal.h"
59
60
 
60
61
#define DEBUG_DOMAIN "ContactListView"
61
62
 
68
69
 
69
70
#define GET_PRIV(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), EMPATHY_TYPE_CONTACT_LIST_VIEW, EmpathyContactListViewPriv))
70
71
 
71
 
struct _EmpathyContactListViewPriv {
72
 
        EmpathyContactListStore *store;
73
 
        GtkUIManager            *ui;
74
 
        GtkTreeRowReference     *drag_row;
75
 
        gboolean                 interactive;
76
 
};
 
72
typedef struct {
 
73
        EmpathyContactListStore    *store;
 
74
        GtkUIManager               *ui;
 
75
        GtkTreeRowReference        *drag_row;
 
76
        EmpathyContactListFeatures  features;
 
77
} EmpathyContactListViewPriv;
77
78
 
78
79
typedef struct {
79
80
        EmpathyContactListView *view;
188
189
 
189
190
enum {
190
191
        PROP_0,
191
 
        PROP_INTERACTIVE
 
192
        PROP_FEATURES
192
193
};
193
194
 
194
195
static const GtkActionEntry entries[] = {
321
322
                              G_SIGNAL_RUN_LAST,
322
323
                              0,
323
324
                              NULL, NULL,
324
 
                              empathy_marshal_VOID__OBJECT_STRING_STRING,
 
325
                              _empathy_gtk_marshal_VOID__OBJECT_STRING_STRING,
325
326
                              G_TYPE_NONE,
326
327
                              3, EMPATHY_TYPE_CONTACT, G_TYPE_STRING, G_TYPE_STRING);
327
328
 
328
329
        g_object_class_install_property (object_class,
329
 
                                         PROP_INTERACTIVE,
330
 
                                         g_param_spec_boolean ("interactive",
331
 
                                                               "View is interactive",
332
 
                                                               "Is the view interactive",
333
 
                                                               FALSE,
334
 
                                                               G_PARAM_READWRITE));
 
330
                                         PROP_FEATURES,
 
331
                                         g_param_spec_flags ("features",
 
332
                                                             "Features of the view",
 
333
                                                             "Falgs for all enabled features",
 
334
                                                              EMPATHY_TYPE_CONTACT_LIST_FEATURES,
 
335
                                                              0,
 
336
                                                              G_PARAM_READWRITE));
335
337
 
336
338
        g_type_class_add_private (object_class, sizeof (EmpathyContactListViewPriv));
337
339
}
414
416
        priv = GET_PRIV (object);
415
417
 
416
418
        switch (param_id) {
417
 
        case PROP_INTERACTIVE:
418
 
                g_value_set_boolean (value, priv->interactive);
 
419
        case PROP_FEATURES:
 
420
                g_value_set_flags (value, priv->features);
419
421
                break;
420
422
        default:
421
423
                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
435
437
        priv = GET_PRIV (object);
436
438
 
437
439
        switch (param_id) {
438
 
        case PROP_INTERACTIVE:
439
 
                empathy_contact_list_view_set_interactive (view, g_value_get_boolean (value));
 
440
        case PROP_FEATURES:
 
441
                empathy_contact_list_view_set_features (view, g_value_get_flags (value));
440
442
                break;
441
443
        default:
442
444
                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
445
447
}
446
448
 
447
449
EmpathyContactListView *
448
 
empathy_contact_list_view_new (EmpathyContactListStore *store)
 
450
empathy_contact_list_view_new (EmpathyContactListStore    *store,
 
451
                               EmpathyContactListFeatures  features)
449
452
{
450
 
        EmpathyContactListViewPriv *priv;
451
453
        EmpathyContactListView     *view;
 
454
        EmpathyContactListViewPriv *priv;
 
455
 
 
456
        g_return_val_if_fail (EMPATHY_IS_CONTACT_LIST_STORE (store), NULL);
452
457
        
453
 
        view = g_object_new (EMPATHY_TYPE_CONTACT_LIST_VIEW, NULL);
 
458
        view = g_object_new (EMPATHY_TYPE_CONTACT_LIST_VIEW,
 
459
                            "features", features,
 
460
                            NULL);
 
461
 
454
462
        priv = GET_PRIV (view);
455
 
 
456
463
        priv->store = g_object_ref (store);
457
 
        contact_list_view_setup (view);
 
464
        contact_list_view_setup (EMPATHY_CONTACT_LIST_VIEW (view));
458
465
 
459
466
        return view;
460
467
}
461
468
 
462
469
void
463
 
empathy_contact_list_view_set_interactive (EmpathyContactListView  *view,
464
 
                                           gboolean                 interactive)
 
470
empathy_contact_list_view_set_features (EmpathyContactListView     *view,
 
471
                                        EmpathyContactListFeatures  features)
465
472
{
466
473
        EmpathyContactListViewPriv *priv = GET_PRIV (view);
467
474
 
468
475
        g_return_if_fail (EMPATHY_IS_CONTACT_LIST_VIEW (view));
469
476
 
470
 
        priv->interactive = interactive;
471
 
        g_object_notify (G_OBJECT (view), "interactive");
 
477
        priv->features = features;
 
478
 
 
479
        /* Update DnD source/dest */
 
480
        if (features & EMPATHY_CONTACT_LIST_FEATURE_CONTACT_DRAG) {
 
481
                gtk_drag_source_set (GTK_WIDGET (view),
 
482
                                     GDK_BUTTON1_MASK,
 
483
                                     drag_types_source,
 
484
                                     G_N_ELEMENTS (drag_types_source),
 
485
                                     GDK_ACTION_MOVE | GDK_ACTION_COPY);
 
486
        } else {
 
487
                gtk_drag_source_unset (GTK_WIDGET (view));
 
488
 
 
489
        }
 
490
 
 
491
        if (features & EMPATHY_CONTACT_LIST_FEATURE_CONTACT_DROP) {
 
492
                gtk_drag_dest_set (GTK_WIDGET (view),
 
493
                                   GTK_DEST_DEFAULT_ALL,
 
494
                                   drag_types_dest,
 
495
                                   G_N_ELEMENTS (drag_types_dest),
 
496
                                   GDK_ACTION_MOVE | GDK_ACTION_COPY);
 
497
        } else {
 
498
                /* FIXME: URI could still be  droped depending on FT feature */
 
499
                gtk_drag_dest_unset (GTK_WIDGET (view));
 
500
        }
 
501
 
 
502
        g_object_notify (G_OBJECT (view), "features");
472
503
}
473
504
 
474
 
gboolean
475
 
empathy_contact_list_view_get_interactive (EmpathyContactListView  *view)
 
505
EmpathyContactListFeatures
 
506
empathy_contact_list_view_get_features (EmpathyContactListView  *view)
476
507
{
477
508
        EmpathyContactListViewPriv *priv = GET_PRIV (view);
478
509
 
479
510
        g_return_val_if_fail (EMPATHY_IS_CONTACT_LIST_VIEW (view), FALSE);
480
511
 
481
 
        return priv->interactive;
 
512
        return priv->features;
482
513
}
483
514
 
484
515
EmpathyContact *
538
569
        return name;
539
570
}
540
571
 
541
 
GtkWidget *
542
 
empathy_contact_list_view_get_group_menu (EmpathyContactListView *view)
543
 
{
544
 
        EmpathyContactListViewPriv *priv;
545
 
        GtkWidget                 *widget;
546
 
 
547
 
        g_return_val_if_fail (EMPATHY_IS_CONTACT_LIST_VIEW (view), NULL);
548
 
 
549
 
        priv = GET_PRIV (view);
550
 
 
551
 
        widget = gtk_ui_manager_get_widget (priv->ui, "/Group");
552
 
 
553
 
        return widget;
554
 
}
555
 
 
556
 
GtkWidget *
557
 
empathy_contact_list_view_get_contact_menu (EmpathyContactListView *view,
558
 
                                            EmpathyContact         *contact)
559
 
{
560
 
        EmpathyLogManager *log_manager;
561
 
        gboolean           can_show_log;
562
 
        gboolean           can_send_file;
563
 
        gboolean           can_voip;
564
 
 
565
 
        g_return_val_if_fail (EMPATHY_IS_CONTACT_LIST_VIEW (view), NULL);
566
 
        g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), NULL);
567
 
 
568
 
        log_manager = empathy_log_manager_new ();
569
 
        can_show_log = empathy_log_manager_exists (log_manager,
570
 
                                                   empathy_contact_get_account (contact),
571
 
                                                   empathy_contact_get_id (contact),
572
 
                                                   FALSE);
573
 
        g_object_unref (log_manager);
574
 
        can_send_file = FALSE;
575
 
        can_voip = empathy_contact_can_voip (contact);
576
 
 
577
 
        return contact_list_view_get_contact_menu (view,
578
 
                                                   can_send_file,
579
 
                                                   can_show_log,
580
 
                                                   can_voip);
581
 
}
582
 
 
583
572
static void
584
573
contact_list_view_setup (EmpathyContactListView *view)
585
574
{
693
682
                drag_atoms_source[i] = gdk_atom_intern (drag_types_source[i].target,
694
683
                                                        FALSE);
695
684
        }
696
 
 
697
 
        /* Note: We support the COPY action too, but need to make the
698
 
         * MOVE action the default.
699
 
         */
700
 
        gtk_drag_source_set (GTK_WIDGET (view),
701
 
                             GDK_BUTTON1_MASK,
702
 
                             drag_types_source,
703
 
                             G_N_ELEMENTS (drag_types_source),
704
 
                             GDK_ACTION_MOVE | GDK_ACTION_COPY);
705
 
 
706
 
        gtk_drag_dest_set (GTK_WIDGET (view),
707
 
                           GTK_DEST_DEFAULT_ALL,
708
 
                           drag_types_dest,
709
 
                           G_N_ELEMENTS (drag_types_dest),
710
 
                           GDK_ACTION_MOVE | GDK_ACTION_COPY);
711
685
}
712
686
 
713
687
static void
716
690
                                            GtkTreeIter           *iter,
717
691
                                            EmpathyContactListView *view)
718
692
{
 
693
        EmpathyContactListViewPriv *priv = GET_PRIV (view);
719
694
        gboolean  is_group = FALSE;
720
695
        gchar    *name = NULL;
721
696
 
729
704
                return;
730
705
        }
731
706
 
732
 
        if (empathy_contact_group_get_expanded (name)) {
 
707
        if (!(priv->features & EMPATHY_CONTACT_LIST_FEATURE_GROUPS_SAVE) ||
 
708
            empathy_contact_group_get_expanded (name)) {
733
709
                g_signal_handlers_block_by_func (view,
734
710
                                                 contact_list_view_row_expand_or_collapse_cb,
735
711
                                                 GINT_TO_POINTER (TRUE));
953
929
        const gchar                *contact_id;
954
930
        const gchar                *account_id;
955
931
        gchar                      *str;
956
 
        
957
932
 
958
933
        priv = GET_PRIV (widget);
959
934
 
1204
1179
                                    gboolean               can_show_log,
1205
1180
                                    gboolean               can_voip)
1206
1181
{
1207
 
        EmpathyContactListViewPriv *priv;
1208
 
        GtkAction                 *action;
1209
 
        GtkWidget                 *widget;
1210
 
 
1211
 
        priv = GET_PRIV (view);
1212
 
 
1213
 
        /* Sort out sensitive items */
 
1182
        EmpathyContactListViewPriv *priv = GET_PRIV (view);
 
1183
        GtkAction                  *action;
 
1184
 
 
1185
        if (!(priv->features & (EMPATHY_CONTACT_LIST_FEATURE_CONTACT_CHAT |
 
1186
                                EMPATHY_CONTACT_LIST_FEATURE_CONTACT_CALL |
 
1187
                                EMPATHY_CONTACT_LIST_FEATURE_CONTACT_LOG |
 
1188
                                EMPATHY_CONTACT_LIST_FEATURE_CONTACT_FT |
 
1189
                                EMPATHY_CONTACT_LIST_FEATURE_CONTACT_INVITE |
 
1190
                                EMPATHY_CONTACT_LIST_FEATURE_CONTACT_EDIT |
 
1191
                                EMPATHY_CONTACT_LIST_FEATURE_CONTACT_INFO |
 
1192
                                EMPATHY_CONTACT_LIST_FEATURE_CONTACT_REMOVE))) {
 
1193
                return NULL;
 
1194
        }
 
1195
 
 
1196
        /* Sort out sensitive/visible items */
 
1197
        action = gtk_ui_manager_get_action (priv->ui, "/Contact/Chat");
 
1198
        gtk_action_set_visible (action, priv->features & EMPATHY_CONTACT_LIST_FEATURE_CONTACT_CHAT);
 
1199
 
 
1200
#ifdef HAVE_VOIP
 
1201
        action = gtk_ui_manager_get_action (priv->ui, "/Contact/Call");
 
1202
        gtk_action_set_sensitive (action, can_voip);
 
1203
        gtk_action_set_visible (action, priv->features & EMPATHY_CONTACT_LIST_FEATURE_CONTACT_CALL);
 
1204
#endif
 
1205
 
1214
1206
        action = gtk_ui_manager_get_action (priv->ui, "/Contact/Log");
1215
1207
        gtk_action_set_sensitive (action, can_show_log);
 
1208
        gtk_action_set_visible (action, priv->features & EMPATHY_CONTACT_LIST_FEATURE_CONTACT_LOG);
1216
1209
 
1217
 
#ifdef HAVE_VOIP
1218
 
        action = gtk_ui_manager_get_action (priv->ui, "/Contact/Call");
1219
 
        gtk_action_set_sensitive (action, can_voip);
1220
 
#endif
1221
1210
 
1222
1211
        action = gtk_ui_manager_get_action (priv->ui, "/Contact/SendFile");
1223
 
        gtk_action_set_visible (action, can_send_file);
1224
 
 
1225
 
        widget = gtk_ui_manager_get_widget (priv->ui, "/Contact");
1226
 
 
1227
 
        return widget;
 
1212
        gtk_action_set_visible (action, can_send_file && (priv->features & EMPATHY_CONTACT_LIST_FEATURE_CONTACT_FT));
 
1213
 
 
1214
        action = gtk_ui_manager_get_action (priv->ui, "/Contact/Invite");
 
1215
        gtk_action_set_visible (action, priv->features & EMPATHY_CONTACT_LIST_FEATURE_CONTACT_INVITE);
 
1216
 
 
1217
        action = gtk_ui_manager_get_action (priv->ui, "/Contact/Edit");
 
1218
        gtk_action_set_visible (action, priv->features & EMPATHY_CONTACT_LIST_FEATURE_CONTACT_EDIT);
 
1219
 
 
1220
        action = gtk_ui_manager_get_action (priv->ui, "/Contact/Information");
 
1221
        gtk_action_set_visible (action, priv->features & EMPATHY_CONTACT_LIST_FEATURE_CONTACT_INFO);
 
1222
 
 
1223
        action = gtk_ui_manager_get_action (priv->ui, "/Contact/Remove");
 
1224
        gtk_action_set_visible (action, priv->features & EMPATHY_CONTACT_LIST_FEATURE_CONTACT_REMOVE);
 
1225
 
 
1226
        return gtk_ui_manager_get_widget (priv->ui, "/Contact");
 
1227
}
 
1228
 
 
1229
GtkWidget *
 
1230
empathy_contact_list_view_get_group_menu (EmpathyContactListView *view)
 
1231
{
 
1232
        EmpathyContactListViewPriv *priv = GET_PRIV (view);
 
1233
        GtkAction                  *action;
 
1234
 
 
1235
        g_return_val_if_fail (EMPATHY_IS_CONTACT_LIST_VIEW (view), NULL);
 
1236
 
 
1237
        if (!(priv->features & (EMPATHY_CONTACT_LIST_FEATURE_GROUPS_RENAME |
 
1238
                                EMPATHY_CONTACT_LIST_FEATURE_GROUPS_REMOVE))) {
 
1239
                return NULL;
 
1240
        }
 
1241
 
 
1242
        action = gtk_ui_manager_get_action (priv->ui, "/Group/Rename");
 
1243
        gtk_action_set_visible (action, priv->features & EMPATHY_CONTACT_LIST_FEATURE_GROUPS_RENAME);
 
1244
 
 
1245
        action = gtk_ui_manager_get_action (priv->ui, "/Group/Remove");
 
1246
        gtk_action_set_visible (action, priv->features & EMPATHY_CONTACT_LIST_FEATURE_GROUPS_REMOVE);
 
1247
 
 
1248
        return gtk_ui_manager_get_widget (priv->ui, "/Group");
 
1249
}
 
1250
 
 
1251
GtkWidget *
 
1252
empathy_contact_list_view_get_contact_menu (EmpathyContactListView *view,
 
1253
                                            EmpathyContact         *contact)
 
1254
{
 
1255
        EmpathyLogManager *log_manager;
 
1256
        gboolean           can_show_log;
 
1257
        gboolean           can_send_file;
 
1258
        gboolean           can_voip;
 
1259
 
 
1260
        g_return_val_if_fail (EMPATHY_IS_CONTACT_LIST_VIEW (view), NULL);
 
1261
        g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), NULL);
 
1262
 
 
1263
        log_manager = empathy_log_manager_new ();
 
1264
        can_show_log = empathy_log_manager_exists (log_manager,
 
1265
                                                   empathy_contact_get_account (contact),
 
1266
                                                   empathy_contact_get_id (contact),
 
1267
                                                   FALSE);
 
1268
        g_object_unref (log_manager);
 
1269
        can_send_file = FALSE;
 
1270
        can_voip = empathy_contact_can_voip (contact);
 
1271
 
 
1272
        return contact_list_view_get_contact_menu (view,
 
1273
                                                   can_send_file,
 
1274
                                                   can_show_log,
 
1275
                                                   can_voip);
1228
1276
}
1229
1277
 
1230
1278
static gboolean
1243
1291
 
1244
1292
        priv = GET_PRIV (view);
1245
1293
 
1246
 
        if (!priv->interactive || event->button != 3) {
 
1294
        if (event->button != 3) {
1247
1295
                return FALSE;
1248
1296
        }
1249
1297
 
1301
1349
        GtkTreeModel               *model;
1302
1350
        GtkTreeIter                 iter;
1303
1351
 
1304
 
        if (!priv->interactive) {
 
1352
        if (!(priv->features & EMPATHY_CONTACT_LIST_FEATURE_CONTACT_CHAT)) {
1305
1353
                return;
1306
1354
        }
1307
1355
 
1329
1377
        GtkTreeIter                 iter;
1330
1378
        EmpathyContact             *contact;
1331
1379
 
1332
 
        if (!priv->interactive) {
 
1380
        if (!(priv->features & EMPATHY_CONTACT_LIST_FEATURE_CONTACT_CALL)) {
1333
1381
                return;
1334
1382
        }
1335
1383
 
1356
1404
                                             GtkTreePath           *path,
1357
1405
                                             gpointer               user_data)
1358
1406
{
1359
 
        GtkTreeModel *model;
1360
 
        gchar        *name;
1361
 
        gboolean      expanded;
 
1407
        EmpathyContactListViewPriv *priv = GET_PRIV (view);
 
1408
        GtkTreeModel               *model;
 
1409
        gchar                      *name;
 
1410
        gboolean                    expanded;
 
1411
 
 
1412
        if (!(priv->features & EMPATHY_CONTACT_LIST_FEATURE_GROUPS_SAVE)) {
 
1413
                return;
 
1414
        }
1362
1415
 
1363
1416
        model = gtk_tree_view_get_model (GTK_TREE_VIEW (view));
1364
1417
 
1444
1497
contact_list_view_voip_activated (EmpathyContactListView *view,
1445
1498
                                  EmpathyContact         *contact)
1446
1499
{
1447
 
        empathy_call_contact (contact);
 
1500
        empathy_call_with_contact (contact);
1448
1501
}
1449
1502