~vish/ubuntu/maverick/pidgin/bug25979

« back to all changes in this revision

Viewing changes to pidgin/gtkconv.c

  • Committer: Bazaar Package Importer
  • Author(s): Felix Geyer
  • Date: 2009-10-09 19:40:26 UTC
  • mfrom: (1.4.1 upstream) (46.1.10 karmic)
  • Revision ID: james.westby@ubuntu.com-20091009194026-wbqqh0bsbz19nx5q
Tags: 1:2.6.2-1ubuntu7
* Don't stick the buddy list window to all desktops as some
  window managers have trouble to properly unstick it (LP: #346840)
  - debian/patches/11_buddy_list_really_show.patch
* Always use default tray icon size on KDE (LP: #209440)
  - debian/patches/62_tray_icon_size_kde.patch
* Use scrollbars in the preferences dialog if the screen height is
  below 700 px instead of 600 px
  - debian/patches/60_1024x600_gtkprefs.c.patch

Show diffs side-by-side

added added

removed removed

Lines of Context:
202
202
 
203
203
        switch (purple_conversation_get_type(conv)) {
204
204
                case PURPLE_CONV_TYPE_IM:
205
 
                        node = (PurpleBlistNode*)purple_find_buddy(conv->account, conv->name);
 
205
                        node = PURPLE_BLIST_NODE(purple_find_buddy(conv->account, conv->name));
206
206
                        node = node ? node->parent : NULL;
207
207
                        break;
208
208
                case PURPLE_CONV_TYPE_CHAT:
209
 
                        node = (PurpleBlistNode*)purple_blist_find_chat(conv->account, conv->name);
 
209
                        node = PURPLE_BLIST_NODE(purple_blist_find_chat(conv->account, conv->name));
210
210
                        break;
211
211
                default:
212
212
                        break;
959
959
}
960
960
 
961
961
static void
 
962
menu_join_chat_cb(gpointer data, guint action, GtkWidget *widget)
 
963
{
 
964
        pidgin_blist_joinchat_show();
 
965
}
 
966
 
 
967
static void
962
968
savelog_writefile_cb(void *user_data, const char *filename)
963
969
{
964
970
        PurpleConversation *conv = (PurpleConversation *)user_data;
1201
1207
        gtk_widget_grab_focus(s->entry);
1202
1208
}
1203
1209
 
 
1210
#ifdef USE_VV
 
1211
static void 
 
1212
menu_initiate_media_call_cb(gpointer data, guint action, GtkWidget *widget)
 
1213
{
 
1214
        PidginWindow *win = (PidginWindow *)data;
 
1215
        PurpleConversation *conv = pidgin_conv_window_get_active_conversation(win);
 
1216
        PurpleAccount *account = purple_conversation_get_account(conv);
 
1217
 
 
1218
        purple_prpl_initiate_media(account,
 
1219
                        purple_conversation_get_name(conv),
 
1220
                        action == 0 ? PURPLE_MEDIA_AUDIO :
 
1221
                        action == 1 ? PURPLE_MEDIA_VIDEO :
 
1222
                        action == 2 ? PURPLE_MEDIA_AUDIO |
 
1223
                        PURPLE_MEDIA_VIDEO : PURPLE_MEDIA_NONE);
 
1224
}
 
1225
#endif
 
1226
 
1204
1227
static void
1205
1228
menu_send_file_cb(gpointer data, guint action, GtkWidget *widget)
1206
1229
{
1397
1420
 
1398
1421
        if (logging == purple_conversation_is_logging(conv))
1399
1422
                return;
1400
 
        
 
1423
 
1401
1424
        node = get_conversation_blist_node(conv);
1402
1425
 
1403
1426
        if (logging)
1753
1776
                        g_object_set_data_full(G_OBJECT(button), "user_data", g_strdup(who), g_free);
1754
1777
        }
1755
1778
 
1756
 
        button = pidgin_new_item_from_stock(menu, _("Last said"), GTK_STOCK_INDEX,
 
1779
        button = pidgin_new_item_from_stock(menu, _("Last Said"), GTK_STOCK_INDEX,
1757
1780
                                                G_CALLBACK(menu_last_said_cb), PIDGIN_CONVERSATION(conv), 0, 0, NULL);
1758
1781
        g_object_set_data_full(G_OBJECT(button), "user_data", g_strdup(who), g_free);
1759
1782
        if (!get_mark_for_user(PIDGIN_CONVERSATION(conv), who))
1837
1860
        gtk_tree_selection_select_path(GTK_TREE_SELECTION(
1838
1861
                        gtk_tree_view_get_selection(GTK_TREE_VIEW(gtkchat->list))), path);
1839
1862
        gtk_tree_view_set_cursor(GTK_TREE_VIEW(gtkchat->list),
1840
 
                                                         path, NULL, FALSE); 
 
1863
                                                         path, NULL, FALSE);
1841
1864
        gtk_widget_grab_focus(GTK_WIDGET(gtkchat->list));
1842
1865
 
1843
1866
        gtk_tree_model_get_iter(GTK_TREE_MODEL(model), &iter, path);
1869
1892
        GtkTreeIter iter;
1870
1893
        GtkTreeModel *model;
1871
1894
        gchar *who;
1872
 
        
 
1895
 
1873
1896
        model = gtk_tree_view_get_model(GTK_TREE_VIEW(list));
1874
1897
 
1875
1898
        gtk_tree_model_get_iter(GTK_TREE_MODEL(model), &iter, path);
2063
2086
        gtkconv  = (PidginConversation *)data;
2064
2087
        conv     = gtkconv->active_conv;
2065
2088
        win      = gtkconv->win;
2066
 
        
 
2089
 
2067
2090
        if (conv_keypress_common(gtkconv, event))
2068
2091
                return TRUE;
2069
2092
 
2495
2518
        return get_prpl_icon_list(account);
2496
2519
}
2497
2520
 
 
2521
static const char *
 
2522
pidgin_conv_get_icon_stock(PurpleConversation *conv)
 
2523
{
 
2524
        PurpleAccount *account = NULL;
 
2525
        const char *stock = NULL;
 
2526
 
 
2527
        g_return_val_if_fail(conv != NULL, NULL);
 
2528
 
 
2529
        account = purple_conversation_get_account(conv);
 
2530
        g_return_val_if_fail(account != NULL, NULL);
 
2531
 
 
2532
        /* Use the buddy icon, if possible */
 
2533
        if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) {
 
2534
                const char *name = NULL;
 
2535
                PurpleBuddy *b;
 
2536
                name = purple_conversation_get_name(conv);
 
2537
                b = purple_find_buddy(account, name);
 
2538
                if (b != NULL) {
 
2539
                        PurplePresence *p = purple_buddy_get_presence(b);
 
2540
                        PurpleStatus *active = purple_presence_get_active_status(p);
 
2541
                        PurpleStatusType *type = purple_status_get_type(active);
 
2542
                        PurpleStatusPrimitive prim = purple_status_type_get_primitive(type);
 
2543
                        stock = pidgin_stock_id_from_status_primitive(prim);
 
2544
                } else {
 
2545
                        stock = PIDGIN_STOCK_STATUS_PERSON;
 
2546
                }
 
2547
        } else {
 
2548
                stock = PIDGIN_STOCK_STATUS_CHAT;
 
2549
        }
 
2550
 
 
2551
        return stock;
 
2552
}
 
2553
 
2498
2554
static GdkPixbuf *
2499
2555
pidgin_conv_get_icon(PurpleConversation *conv, GtkWidget *parent, const char *icon_size)
2500
2556
{
2501
2557
        PurpleAccount *account = NULL;
2502
2558
        const char *name = NULL;
 
2559
        const char *stock = NULL;
2503
2560
        GdkPixbuf *status = NULL;
2504
2561
        PurpleBlistUiOps *ops = purple_blist_get_ui_ops();
 
2562
        GtkIconSize size;
 
2563
 
2505
2564
        g_return_val_if_fail(conv != NULL, NULL);
2506
2565
 
2507
2566
        account = purple_conversation_get_account(conv);
2514
2573
        if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) {
2515
2574
                PurpleBuddy *b = purple_find_buddy(account, name);
2516
2575
                if (b != NULL) {
2517
 
                        PurplePresence *p = purple_buddy_get_presence(b);
2518
2576
                        /* I hate this hack.  It fixes a bug where the pending message icon
2519
2577
                         * displays in the conv tab even though it shouldn't.
2520
2578
                         * A better solution would be great. */
2521
2579
                        if (ops && ops->update)
2522
2580
                                ops->update(NULL, (PurpleBlistNode*)b);
2523
 
 
2524
 
                        /* XXX Seanegan: We really need a util function to return a pixbuf for a Presence to avoid all this switching */        
2525
 
                        if (purple_presence_is_status_primitive_active(p, PURPLE_STATUS_AWAY))
2526
 
                                status = pidgin_create_status_icon(PURPLE_STATUS_AWAY, parent, icon_size);
2527
 
                        else if (purple_presence_is_status_primitive_active(p, PURPLE_STATUS_EXTENDED_AWAY))
2528
 
                                status = pidgin_create_status_icon(PURPLE_STATUS_EXTENDED_AWAY, parent, icon_size);
2529
 
                        else if (purple_presence_is_status_primitive_active(p, PURPLE_STATUS_OFFLINE))
2530
 
                                status = pidgin_create_status_icon(PURPLE_STATUS_OFFLINE, parent, icon_size);
2531
 
                        else if (purple_presence_is_status_primitive_active(p, PURPLE_STATUS_AVAILABLE))
2532
 
                                status = pidgin_create_status_icon(PURPLE_STATUS_AVAILABLE, parent, icon_size);
2533
 
                        else if (purple_presence_is_status_primitive_active(p, PURPLE_STATUS_INVISIBLE))
2534
 
                                status = pidgin_create_status_icon(PURPLE_STATUS_INVISIBLE, parent, icon_size);
2535
 
                        else if (purple_presence_is_status_primitive_active(p, PURPLE_STATUS_UNAVAILABLE))
2536
 
                                status = pidgin_create_status_icon(PURPLE_STATUS_UNAVAILABLE, parent, icon_size);
2537
2581
                }
2538
2582
        }
2539
2583
 
2540
 
        /* If they don't have a buddy icon, then use the PRPL icon */
2541
 
        if (status == NULL) {
2542
 
                GtkIconSize size = gtk_icon_size_from_name(icon_size);
2543
 
                if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) {
2544
 
                        status = gtk_widget_render_icon (parent, PIDGIN_STOCK_STATUS_PERSON,
2545
 
                                        size, "GtkWidget");
2546
 
                } else {
2547
 
                        status = gtk_widget_render_icon (parent, PIDGIN_STOCK_STATUS_CHAT,
2548
 
                                        size, "GtkWidget");
2549
 
                }
2550
 
        }       
 
2584
        stock = pidgin_conv_get_icon_stock(conv);
 
2585
        size = gtk_icon_size_from_name(icon_size);
 
2586
        status = gtk_widget_render_icon (parent, stock, size, "GtkWidget");
2551
2587
        return status;
2552
2588
}
2553
2589
 
2565
2601
        PidginConversation *gtkconv;
2566
2602
        PidginWindow *win;
2567
2603
        GList *l;
2568
 
        GdkPixbuf *status = NULL;
2569
 
        GdkPixbuf *infopane_status = NULL;
2570
2604
        GdkPixbuf *emblem = NULL;
 
2605
        const char *status = NULL;
 
2606
        const char *infopane_status = NULL;
2571
2607
 
2572
2608
        g_return_if_fail(conv != NULL);
2573
2609
 
2576
2612
        if (conv != gtkconv->active_conv)
2577
2613
                return;
2578
2614
 
2579
 
        status = pidgin_conv_get_tab_icon(conv, TRUE);
2580
 
        infopane_status = pidgin_conv_get_tab_icon(conv, FALSE);
 
2615
        status = infopane_status = pidgin_conv_get_icon_stock(conv);
2581
2616
 
2582
2617
        if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) {
2583
2618
                PurpleBuddy *b = purple_find_buddy(conv->account, conv->name);
2587
2622
 
2588
2623
        g_return_if_fail(status != NULL);
2589
2624
 
2590
 
        gtk_image_set_from_pixbuf(GTK_IMAGE(gtkconv->icon), status);
2591
 
        gtk_image_set_from_pixbuf(GTK_IMAGE(gtkconv->menu_icon), status);
 
2625
        g_object_set(G_OBJECT(gtkconv->icon), "stock", status, NULL);
 
2626
        g_object_set(G_OBJECT(gtkconv->menu_icon), "stock", status, NULL);
2592
2627
 
2593
 
        gtk_list_store_set(GTK_LIST_STORE(gtkconv->infopane_model), 
 
2628
        gtk_list_store_set(GTK_LIST_STORE(gtkconv->infopane_model),
2594
2629
                        &(gtkconv->infopane_iter),
2595
2630
                        CONV_ICON_COLUMN, infopane_status, -1);
2596
2631
 
2597
 
        gtk_list_store_set(GTK_LIST_STORE(gtkconv->infopane_model), 
 
2632
        gtk_list_store_set(GTK_LIST_STORE(gtkconv->infopane_model),
2598
2633
                        &(gtkconv->infopane_iter),
2599
2634
                        CONV_EMBLEM_COLUMN, emblem, -1);
2600
2635
        if (emblem)
2616
2651
        gtk_widget_queue_resize(gtkconv->infopane);
2617
2652
        gtk_widget_queue_draw(gtkconv->infopane);
2618
2653
 
2619
 
        if (status != NULL)
2620
 
                g_object_unref(status);
2621
 
 
2622
2654
        if (pidgin_conv_window_is_active_conversation(conv) &&
2623
2655
                (purple_conversation_get_type(conv) != PURPLE_CONV_TYPE_IM ||
2624
2656
                 gtkconv->u.im->anim == NULL))
2674
2706
        scale_width = gdk_pixbuf_get_width(buf);
2675
2707
        scale_height = gdk_pixbuf_get_height(buf);
2676
2708
 
2677
 
        gtk_widget_get_size_request(gtkconv->infopane_hbox, NULL, &size);
 
2709
        gtk_widget_get_size_request(gtkconv->u.im->icon_container, NULL, &size);
2678
2710
        size = MIN(size, MIN(scale_width, scale_height));
2679
2711
        size = CLAMP(size, BUDDYICON_SIZE_MIN, BUDDYICON_SIZE_MAX);
2680
2712
 
2732
2764
static void
2733
2765
remove_icon(GtkWidget *widget, PidginConversation *gtkconv)
2734
2766
{
 
2767
        GList *children;
 
2768
        GtkWidget *event;
2735
2769
        PurpleConversation *conv = gtkconv->active_conv;
2736
2770
        PidginWindow *gtkwin;
2737
2771
 
2738
2772
        g_return_if_fail(conv != NULL);
2739
2773
 
2740
 
        if (gtkconv->u.im->icon_container != NULL)
2741
 
                gtk_widget_destroy(gtkconv->u.im->icon_container);
 
2774
        gtk_widget_set_size_request(gtkconv->u.im->icon_container, -1, BUDDYICON_SIZE_MIN);
 
2775
        children = gtk_container_get_children(GTK_CONTAINER(gtkconv->u.im->icon_container));
 
2776
        if (children) {
 
2777
                /* We know there's only one child here. It'd be nice to shortcut to the
 
2778
                   event box, but we can't change the PidginConversation until 3.0 */
 
2779
                event = (GtkWidget *)children->data;
 
2780
                gtk_container_remove(GTK_CONTAINER(gtkconv->u.im->icon_container), event);
 
2781
                g_list_free(children);
 
2782
        }
2742
2783
 
2743
2784
        if (gtkconv->u.im->anim != NULL)
2744
2785
                g_object_unref(G_OBJECT(gtkconv->u.im->anim));
2753
2794
        gtkconv->u.im->icon = NULL;
2754
2795
        gtkconv->u.im->anim = NULL;
2755
2796
        gtkconv->u.im->iter = NULL;
2756
 
        gtkconv->u.im->icon_container = NULL;
2757
2797
        gtkconv->u.im->show_icon = FALSE;
2758
2798
 
2759
2799
        gtkwin = gtkconv->win;
2814
2854
        PurpleConversation *conv = gtkconv->active_conv;
2815
2855
        GSList *buddies;
2816
2856
 
2817
 
        gtk_widget_get_size_request(gtkconv->infopane_hbox, NULL, &size);
 
2857
        gtk_widget_get_size_request(gtkconv->u.im->icon_container, NULL, &size);
2818
2858
 
2819
2859
        if (size == BUDDYICON_SIZE_MAX) {
2820
2860
                size = BUDDYICON_SIZE_MIN;
2822
2862
                size = BUDDYICON_SIZE_MAX;
2823
2863
        }
2824
2864
 
2825
 
        gtk_widget_set_size_request(gtkconv->infopane_hbox, -1, size);
 
2865
        gtk_widget_set_size_request(gtkconv->u.im->icon_container, -1, size);
2826
2866
        pidgin_conv_update_buddy_icon(conv);
2827
2867
 
2828
2868
        buddies = purple_find_buddies(purple_conversation_get_account(conv),
3054
3094
                PurpleConversation *conv = (PurpleConversation*)l->data;
3055
3095
                PidginConversation *gtkconv = PIDGIN_CONVERSATION(conv);
3056
3096
 
3057
 
                GtkWidget *icon = gtk_image_new();
3058
 
                GdkPixbuf *pbuf = pidgin_conv_get_icon(conv, icon, PIDGIN_ICON_SIZE_TANGO_MICROSCOPIC);
 
3097
                GtkWidget *icon = gtk_image_new_from_stock(pidgin_conv_get_icon_stock(conv),
 
3098
                                gtk_icon_size_from_name(PIDGIN_ICON_SIZE_TANGO_MICROSCOPIC));
3059
3099
                GtkWidget *item;
3060
3100
                gchar *text = g_strdup_printf("%s (%d)",
3061
3101
                                gtk_label_get_text(GTK_LABEL(gtkconv->tab_label)),
3062
3102
                                gtkconv->unseen_count);
3063
3103
 
3064
 
                gtk_image_set_from_pixbuf(GTK_IMAGE(icon), pbuf);
3065
 
                g_object_unref(pbuf);
3066
 
 
3067
3104
                item = gtk_image_menu_item_new_with_label(text);
3068
3105
                gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item), icon);
3069
3106
                g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(unseen_conv_menu_cb), conv);
3102
3139
 
3103
3140
        { N_("/Conversation/New Instant _Message..."), "<CTL>M", menu_new_conv_cb,
3104
3141
                        0, "<StockItem>", PIDGIN_STOCK_TOOLBAR_MESSAGE_NEW },
 
3142
        { N_("/Conversation/Join a _Chat..."), NULL, menu_join_chat_cb,
 
3143
                        0, "<StockItem>", PIDGIN_STOCK_CHAT },
3105
3144
 
3106
3145
        { "/Conversation/sep0", NULL, NULL, 0, "<Separator>", NULL },
3107
3146
 
3114
3153
 
3115
3154
        { "/Conversation/sep1", NULL, NULL, 0, "<Separator>", NULL },
3116
3155
 
 
3156
#ifdef USE_VV
 
3157
        { N_("/Conversation/M_edia"), NULL, NULL, 0, "<Branch>", NULL },
 
3158
 
 
3159
        { N_("/Conversation/Media/_Audio Call"), NULL, menu_initiate_media_call_cb, 0,
 
3160
                "<StockItem>", PIDGIN_STOCK_TOOLBAR_AUDIO_CALL },
 
3161
        { N_("/Conversation/Media/_Video Call"), NULL, menu_initiate_media_call_cb, 1,
 
3162
                "<StockItem>", PIDGIN_STOCK_TOOLBAR_VIDEO_CALL },
 
3163
        { N_("/Conversation/Media/Audio\\/Video _Call"), NULL, menu_initiate_media_call_cb, 2,
 
3164
                "<StockItem>", PIDGIN_STOCK_TOOLBAR_VIDEO_CALL },
 
3165
#endif
 
3166
 
3117
3167
        { N_("/Conversation/Se_nd File..."), NULL, menu_send_file_cb, 0, "<StockItem>", PIDGIN_STOCK_TOOLBAR_SEND_FILE },
3118
3168
        { N_("/Conversation/Add Buddy _Pounce..."), NULL, menu_add_pounce_cb,
3119
3169
                        0, "<Item>", NULL },
3251
3301
                                purple_blist_node_set_flags((PurpleBlistNode *)buddy,
3252
3302
                                                PURPLE_BLIST_NODE_FLAG_NO_SAVE);
3253
3303
                                g_object_set_data_full(G_OBJECT(gtkconv->imhtml), "transient_buddy",
3254
 
                                                buddy, (GDestroyNotify)purple_blist_remove_buddy);
 
3304
                                                buddy, (GDestroyNotify)purple_buddy_destroy);
3255
3305
                        }
3256
3306
                }
3257
3307
        }
3284
3334
}
3285
3335
 
3286
3336
static void
 
3337
regenerate_media_items(PidginWindow *win)
 
3338
{
 
3339
#ifdef USE_VV
 
3340
        PurpleAccount *account;
 
3341
        PurpleConversation *conv;
 
3342
 
 
3343
        conv = pidgin_conv_window_get_active_conversation(win);
 
3344
 
 
3345
        if (conv == NULL) {
 
3346
                purple_debug_error("gtkconv", "couldn't get active conversation"
 
3347
                                " when regenerating media items\n");
 
3348
                return;
 
3349
        }
 
3350
 
 
3351
        account = purple_conversation_get_account(conv);
 
3352
 
 
3353
        if (account == NULL) {
 
3354
                purple_debug_error("gtkconv", "couldn't get account when"
 
3355
                                " regenerating media items\n");
 
3356
                return;
 
3357
        }
 
3358
 
 
3359
        /*
 
3360
         * Check if account support voice and/or calls, and
 
3361
         * if the current buddy supports it.
 
3362
         */
 
3363
        if (account != NULL && purple_conversation_get_type(conv)
 
3364
                        == PURPLE_CONV_TYPE_IM) {
 
3365
                PurpleMediaCaps caps =
 
3366
                                purple_prpl_get_media_caps(account,
 
3367
                                purple_conversation_get_name(conv));
 
3368
 
 
3369
                gtk_widget_set_sensitive(win->audio_call,
 
3370
                                caps & PURPLE_MEDIA_CAPS_AUDIO
 
3371
                                ? TRUE : FALSE);
 
3372
                gtk_widget_set_sensitive(win->video_call,
 
3373
                                caps & PURPLE_MEDIA_CAPS_VIDEO
 
3374
                                ? TRUE : FALSE);
 
3375
                gtk_widget_set_sensitive(win->audio_video_call, 
 
3376
                                caps & PURPLE_MEDIA_CAPS_AUDIO_VIDEO
 
3377
                                ? TRUE : FALSE);
 
3378
        } else if (purple_conversation_get_type(conv)
 
3379
                        == PURPLE_CONV_TYPE_CHAT) {
 
3380
                /* for now, don't care about chats... */
 
3381
                gtk_widget_set_sensitive(win->audio_call, FALSE);
 
3382
                gtk_widget_set_sensitive(win->video_call, FALSE);
 
3383
                gtk_widget_set_sensitive(win->audio_video_call, FALSE);
 
3384
        } else {
 
3385
                gtk_widget_set_sensitive(win->audio_call, FALSE);
 
3386
                gtk_widget_set_sensitive(win->video_call, FALSE);
 
3387
                gtk_widget_set_sensitive(win->audio_video_call, FALSE);
 
3388
        }                                                       
 
3389
#endif
 
3390
}
 
3391
 
 
3392
static void
3287
3393
regenerate_options_items(PidginWindow *win)
3288
3394
{
3289
3395
        GtkWidget *menu;
3368
3474
static void menubar_activated(GtkWidget *item, gpointer data)
3369
3475
{
3370
3476
        PidginWindow *win = data;
 
3477
        regenerate_media_items(win);
3371
3478
        regenerate_options_items(win);
3372
3479
        regenerate_plugins_items(win);
3373
3480
 
3424
3531
                gtk_item_factory_get_widget(win->menu.item_factory,
3425
3532
                                            N_("/Conversation/View Log"));
3426
3533
 
 
3534
#ifdef USE_VV
 
3535
        win->audio_call =
 
3536
                gtk_item_factory_get_widget(win->menu.item_factory,
 
3537
                                            N_("/Conversation/Media/Audio Call"));
 
3538
        win->video_call =
 
3539
                gtk_item_factory_get_widget(win->menu.item_factory,
 
3540
                                            N_("/Conversation/Media/Video Call"));
 
3541
        win->audio_video_call =
 
3542
                gtk_item_factory_get_widget(win->menu.item_factory,
 
3543
                                            N_("/Conversation/Media/Audio\\/Video Call"));
 
3544
#endif
 
3545
        
3427
3546
        /* --- */
3428
3547
 
3429
3548
        win->menu.send_file =
3855
3974
                        {
3856
3975
                                PurpleBlistNode *node;
3857
3976
 
3858
 
                                node = (PurpleBlistNode *) purple_buddy_get_contact((PurpleBuddy *)l->data);
 
3977
                                node = PURPLE_BLIST_NODE(purple_buddy_get_contact(PURPLE_BUDDY(l->data)));
3859
3978
 
3860
3979
                                for (node = node->child; node != NULL; node = node->next)
3861
3980
                                {
3901
4020
        update_send_to_selection(win);
3902
4021
}
3903
4022
 
3904
 
static GdkPixbuf *
 
4023
static const char *
3905
4024
get_chat_buddy_status_icon(PurpleConvChat *chat, const char *name, PurpleConvChatBuddyFlags flags)
3906
4025
{
3907
 
        PidginConversation *gtkconv = PIDGIN_CONVERSATION(chat->conv);
3908
 
        GdkPixbuf *pixbuf, *scale, *scale2;
3909
 
        char *filename;
3910
4026
        const char *image = NULL;
3911
4027
 
3912
4028
        if (flags & PURPLE_CBFLAGS_FOUNDER) {
3922
4038
        } else {
3923
4039
                return NULL;
3924
4040
        }
3925
 
 
3926
 
        pixbuf = gtk_widget_render_icon (gtkconv->tab_cont, image, gtk_icon_size_from_name(PIDGIN_ICON_SIZE_TANGO_EXTRA_SMALL),
3927
 
                                         "GtkTreeView");
3928
 
 
3929
 
        if (!pixbuf)
3930
 
                return NULL;
3931
 
 
3932
 
        scale = gdk_pixbuf_scale_simple(pixbuf, 16, 16, GDK_INTERP_BILINEAR);
3933
 
        g_object_unref(pixbuf);
3934
 
 
3935
 
        if (flags && purple_conv_chat_is_user_ignored(chat, name)) {
3936
 
/* TODO: the .../status/default directory isn't installed, should it be? */
3937
 
                filename = g_build_filename(DATADIR, "pixmaps", "pidgin", "status", "default", "ignored.png", NULL);
3938
 
                pixbuf = gdk_pixbuf_new_from_file(filename, NULL);
3939
 
                g_free(filename);
3940
 
                scale2 = gdk_pixbuf_scale_simple(pixbuf, 16, 16, GDK_INTERP_BILINEAR);
3941
 
                g_object_unref(pixbuf);
3942
 
                gdk_pixbuf_composite(scale2, scale, 0, 0, 16, 16, 0, 0, 1, 1, GDK_INTERP_BILINEAR, 192);
3943
 
                g_object_unref(scale2);
3944
 
        }
3945
 
 
3946
 
        return scale;
 
4041
        return image;
3947
4042
}
3948
4043
 
3949
4044
static void
3955
4050
        PurpleConnection *gc;
3956
4051
        PurplePluginProtocolInfo *prpl_info;
3957
4052
        GtkListStore *ls;
3958
 
        GdkPixbuf *pixbuf;
 
4053
        const char *stock;
3959
4054
        GtkTreeIter iter;
3960
4055
        gboolean is_me = FALSE;
3961
4056
        gboolean is_buddy;
3977
4072
 
3978
4073
        ls = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(gtkchat->list)));
3979
4074
 
3980
 
        pixbuf = get_chat_buddy_status_icon(chat, name, flags);
 
4075
        stock = get_chat_buddy_status_icon(chat, name, flags);
3981
4076
 
3982
4077
        if (!strcmp(chat->nick, purple_normalize(conv->account, old_name != NULL ? old_name : name)))
3983
4078
                is_me = TRUE;
3994
4089
                                "send-name");
3995
4090
                g_object_get(tag, "foreground-gdk", &color, NULL);
3996
4091
        } else {
 
4092
                GtkTextTag *tag;
 
4093
                if ((tag = get_buddy_tag(conv, name, 0, FALSE)))
 
4094
                        g_object_set(G_OBJECT(tag), "style", PANGO_STYLE_NORMAL, NULL);
 
4095
                if ((tag = get_buddy_tag(conv, name, PURPLE_MESSAGE_NICK, FALSE)))
 
4096
                        g_object_set(G_OBJECT(tag), "style", PANGO_STYLE_NORMAL, NULL);
3997
4097
                color = (GdkColor*)get_nick_color(gtkconv, name);
3998
4098
        }
3999
4099
 
4007
4107
* Inserting in the "wrong" location has no visible ill effects. - F.P.
4008
4108
*/
4009
4109
                        -1, /* "row" */
4010
 
                        CHAT_USERS_ICON_COLUMN,  pixbuf,
 
4110
                        CHAT_USERS_ICON_STOCK_COLUMN,  stock,
4011
4111
                        CHAT_USERS_ALIAS_COLUMN, alias,
4012
4112
                        CHAT_USERS_ALIAS_KEY_COLUMN, alias_key,
4013
4113
                        CHAT_USERS_NAME_COLUMN,  name,
4018
4118
#else
4019
4119
        gtk_list_store_append(ls, &iter);
4020
4120
        gtk_list_store_set(ls, &iter,
4021
 
                        CHAT_USERS_ICON_COLUMN,  pixbuf,
 
4121
                        CHAT_USERS_ICON_STOCK_COLUMN,  stock,
4022
4122
                        CHAT_USERS_ALIAS_COLUMN, alias,
4023
4123
                        CHAT_USERS_ALIAS_KEY_COLUMN, alias_key,
4024
4124
                        CHAT_USERS_NAME_COLUMN,  name,
4028
4128
                        -1);
4029
4129
#endif
4030
4130
 
4031
 
        if (pixbuf)
4032
 
                g_object_unref(pixbuf);
4033
4131
        if (is_me && color)
4034
4132
                gdk_color_free(color);
4035
4133
        g_free(alias_key);
4275
4373
                return;
4276
4374
        }
4277
4375
 
4278
 
        gtk_entry_set_text(GTK_ENTRY(gtkchat->topic_text), current_topic);
 
4376
        if (current_topic)
 
4377
                gtk_entry_set_text(GTK_ENTRY(gtkchat->topic_text), current_topic);
 
4378
        else
 
4379
                gtk_entry_set_text(GTK_ENTRY(gtkchat->topic_text), "");
 
4380
 
4279
4381
        prpl_info->set_chat_topic(gc, purple_conv_chat_get_id(PURPLE_CONV_CHAT(conv)),
4280
4382
                        new_topic);
4281
4383
 
4471
4573
}
4472
4574
 
4473
4575
static void
4474
 
buddy_added_cb(PurpleBuddy *buddy, PurpleConversation *conv)
 
4576
buddy_added_cb(PurpleBlistNode *node, PurpleConversation *conv)
4475
4577
{
4476
 
        buddy_cb_common(buddy, conv, TRUE);
 
4578
        if (!PURPLE_BLIST_NODE_IS_BUDDY(node))
 
4579
                return;
 
4580
 
 
4581
        buddy_cb_common(PURPLE_BUDDY(node), conv, TRUE);
4477
4582
}
4478
4583
 
4479
4584
static void
4480
 
buddy_removed_cb(PurpleBuddy *buddy, PurpleConversation *conv)
 
4585
buddy_removed_cb(PurpleBlistNode *node, PurpleConversation *conv)
4481
4586
{
 
4587
        if (!PURPLE_BLIST_NODE_IS_BUDDY(node))
 
4588
                return;
 
4589
 
4482
4590
        /* If there's another buddy for the same "dude" on the list, do nothing. */
4483
 
        if (purple_find_buddy(buddy->account, buddy->name) != NULL)
 
4591
        if (purple_find_buddy(purple_buddy_get_account(PURPLE_BUDDY(node)),
 
4592
                                  purple_buddy_get_name(PURPLE_BUDDY(node))) != NULL)
4484
4593
                return;
4485
4594
 
4486
 
        buddy_cb_common(buddy, conv, FALSE);
 
4595
        buddy_cb_common(PURPLE_BUDDY(node), conv, FALSE);
4487
4596
}
4488
4597
 
4489
4598
static void send_menu_cb(GtkWidget *widget, PidginConversation *gtkconv)
4597
4706
                gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
4598
4707
 
4599
4708
                gtkchat->topic_text = gtk_entry_new();
 
4709
                gtk_widget_set_size_request(gtkchat->topic_text, -1, BUDDYICON_SIZE_MIN);
4600
4710
 
4601
4711
                if(prpl_info->set_chat_topic == NULL) {
4602
4712
                        gtk_editable_set_editable(GTK_EDITABLE(gtkchat->topic_text), FALSE);
4676
4786
 
4677
4787
        ls = gtk_list_store_new(CHAT_USERS_COLUMNS, GDK_TYPE_PIXBUF, G_TYPE_STRING,
4678
4788
                                                        G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INT,
4679
 
                                                        GDK_TYPE_COLOR, G_TYPE_INT);
 
4789
                                                        GDK_TYPE_COLOR, G_TYPE_INT, G_TYPE_STRING);
4680
4790
        gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(ls), CHAT_USERS_ALIAS_KEY_COLUMN,
4681
4791
                                                                        sort_chat_users, NULL, NULL);
4682
4792
 
4683
4793
        list = gtk_tree_view_new_with_model(GTK_TREE_MODEL(ls));
4684
4794
 
4685
4795
        rend = gtk_cell_renderer_pixbuf_new();
4686
 
 
 
4796
        g_object_set(G_OBJECT(rend),
 
4797
                                 "stock-size", gtk_icon_size_from_name(PIDGIN_ICON_SIZE_TANGO_EXTRA_SMALL),
 
4798
                                 NULL);
4687
4799
        col = gtk_tree_view_column_new_with_attributes(NULL, rend,
4688
 
                                                                                                   "pixbuf", CHAT_USERS_ICON_COLUMN, NULL);
 
4800
                        "stock-id", CHAT_USERS_ICON_STOCK_COLUMN, NULL);
4689
4801
        gtk_tree_view_column_set_sizing(col, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
4690
4802
        gtk_tree_view_append_column(GTK_TREE_VIEW(list), col);
4691
4803
        ul_width = purple_prefs_get_int(PIDGIN_PREFS_ROOT "/conversations/chat/userlist_width");
4712
4824
                                 "foreground-set", TRUE,
4713
4825
                                 "weight-set", TRUE,
4714
4826
                                 NULL);
4715
 
        g_object_set(G_OBJECT(rend), "editable", TRUE, NULL);
 
4827
        g_object_set(G_OBJECT(rend), "editable", TRUE, NULL);
4716
4828
 
4717
4829
        col = gtk_tree_view_column_new_with_attributes(NULL, rend,
4718
4830
                                                       "text", CHAT_USERS_ALIAS_COLUMN,
4720
4832
                                                       "weight", CHAT_USERS_WEIGHT_COLUMN,
4721
4833
                                                       NULL);
4722
4834
 
4723
 
        purple_signal_connect(blist_handle, "buddy-added",
 
4835
        purple_signal_connect(blist_handle, "blist-node-added",
4724
4836
                                                gtkchat, PURPLE_CALLBACK(buddy_added_cb), conv);
4725
 
        purple_signal_connect(blist_handle, "buddy-removed",
 
4837
        purple_signal_connect(blist_handle, "blist-node-removed",
4726
4838
                                                gtkchat, PURPLE_CALLBACK(buddy_removed_cb), conv);
4727
4839
        purple_signal_connect(blist_handle, "blist-node-aliased",
4728
4840
                                                gtkchat, PURPLE_CALLBACK(blist_node_aliased_cb), conv);
4803
4915
                pidgin_conv_create_tooltip, NULL);
4804
4916
 
4805
4917
        gtkconv->infopane = gtk_cell_view_new();
4806
 
        gtkconv->infopane_model = gtk_list_store_new(CONV_NUM_COLUMNS, GDK_TYPE_PIXBUF, G_TYPE_STRING, GDK_TYPE_PIXBUF, GDK_TYPE_PIXBUF);
4807
 
        gtk_cell_view_set_model(GTK_CELL_VIEW(gtkconv->infopane), 
 
4918
        gtkconv->infopane_model = gtk_list_store_new(CONV_NUM_COLUMNS, G_TYPE_STRING, G_TYPE_STRING, GDK_TYPE_PIXBUF, GDK_TYPE_PIXBUF);
 
4919
        gtk_cell_view_set_model(GTK_CELL_VIEW(gtkconv->infopane),
4808
4920
                                GTK_TREE_MODEL(gtkconv->infopane_model));
4809
4921
        g_object_unref(gtkconv->infopane_model);
4810
4922
        gtk_list_store_append(gtkconv->infopane_model, &(gtkconv->infopane_iter));
4813
4925
        gtk_cell_view_set_displayed_row(GTK_CELL_VIEW(gtkconv->infopane), path);
4814
4926
        gtk_tree_path_free(path);
4815
4927
 
4816
 
        if ((buddy = purple_find_buddy(purple_conversation_get_account(conv),
4817
 
                                        purple_conversation_get_name(conv))) != NULL) {
4818
 
                PurpleContact *contact = purple_buddy_get_contact(buddy);
4819
 
                if (contact) {
4820
 
                        buddyicon_size = purple_blist_node_get_int((PurpleBlistNode*)contact, "pidgin-infopane-iconsize");
 
4928
        if (chat) {
 
4929
                /* This empty widget is used to ensure that the infopane is consistently
 
4930
                   sized for chat windows. The correct fix is to put an icon in the chat
 
4931
                   window as well, because that would make "Set Custom Icon" consistent
 
4932
                   for both the buddy list and the chat window, but PidginConversation
 
4933
                   is pretty much stuck until 3.0. */
 
4934
                GtkWidget *sizing_vbox;
 
4935
                sizing_vbox = gtk_vbox_new(FALSE, 0);
 
4936
                gtk_widget_set_size_request(sizing_vbox, -1, BUDDYICON_SIZE_MIN);
 
4937
                gtk_box_pack_start(GTK_BOX(gtkconv->infopane_hbox), sizing_vbox, FALSE, FALSE, 0);
 
4938
                gtk_widget_show(sizing_vbox);
 
4939
        }
 
4940
        else {
 
4941
                gtkconv->u.im->icon_container = gtk_vbox_new(FALSE, 0);
 
4942
 
 
4943
                if ((buddy = purple_find_buddy(purple_conversation_get_account(conv),
 
4944
                                                purple_conversation_get_name(conv))) != NULL) {
 
4945
                        PurpleContact *contact = purple_buddy_get_contact(buddy);
 
4946
                        if (contact) {
 
4947
                                buddyicon_size = purple_blist_node_get_int((PurpleBlistNode*)contact, "pidgin-infopane-iconsize");
 
4948
                        }
4821
4949
                }
 
4950
                buddyicon_size = CLAMP(buddyicon_size, BUDDYICON_SIZE_MIN, BUDDYICON_SIZE_MAX);
 
4951
                gtk_widget_set_size_request(gtkconv->u.im->icon_container, -1, buddyicon_size);
 
4952
 
 
4953
                gtk_box_pack_start(GTK_BOX(gtkconv->infopane_hbox),
 
4954
                                   gtkconv->u.im->icon_container, FALSE, FALSE, 0);
 
4955
 
 
4956
                gtk_widget_show(gtkconv->u.im->icon_container);
4822
4957
        }
4823
 
        buddyicon_size = CLAMP(buddyicon_size, BUDDYICON_SIZE_MIN, BUDDYICON_SIZE_MAX);
4824
 
        gtk_widget_set_size_request(gtkconv->infopane_hbox, -1, buddyicon_size);
 
4958
 
4825
4959
        gtk_widget_show(gtkconv->infopane);
4826
4960
 
4827
4961
        rend = gtk_cell_renderer_pixbuf_new();
4828
4962
        gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(gtkconv->infopane), rend, FALSE);
4829
 
        gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(gtkconv->infopane), rend, "pixbuf", CONV_ICON_COLUMN, NULL);
4830
 
        g_object_set(rend, "xalign", 0.0, "xpad", 6, "ypad", 0, NULL);
 
4963
        gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(gtkconv->infopane), rend, "stock-id", CONV_ICON_COLUMN, NULL);
 
4964
        g_object_set(rend, "xalign", 0.0, "xpad", 6, "ypad", 0,
 
4965
                        "stock-size", gtk_icon_size_from_name(PIDGIN_ICON_SIZE_TANGO_EXTRA_SMALL),
 
4966
                        NULL);
4831
4967
 
4832
4968
        rend = gtk_cell_renderer_text_new();
4833
4969
        gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(gtkconv->infopane), rend, TRUE);
4872
5008
 
4873
5009
        gtk_widget_set_name(gtkconv->imhtml, "pidgin_conv_imhtml");
4874
5010
        gtk_imhtml_show_comments(GTK_IMHTML(gtkconv->imhtml),TRUE);
 
5011
        g_object_set_data(G_OBJECT(gtkconv->imhtml), "gtkconv", gtkconv);
4875
5012
 
4876
5013
        gtk_scrolled_window_get_policy(GTK_SCROLLED_WINDOW(imhtml_sw),
4877
5014
                                       &imhtml_sw_hscroll, NULL);
4941
5078
        PurpleConversation *conv = gtkconv->active_conv;
4942
5079
        PidginWindow *win = gtkconv->win;
4943
5080
        PurpleConversation *c;
 
5081
        PurpleAccount *convaccount = purple_conversation_get_account(conv);
 
5082
        PurpleConnection *gc = purple_account_get_connection(convaccount);
 
5083
        PurplePluginProtocolInfo *prpl_info = gc ? PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl) : NULL;
 
5084
 
4944
5085
        if (sd->target == gdk_atom_intern("PURPLE_BLIST_NODE", FALSE))
4945
5086
        {
4946
5087
                PurpleBlistNode *n = NULL;
4947
5088
                PurpleBuddy *b;
4948
5089
                PidginConversation *gtkconv = NULL;
 
5090
                PurpleAccount *buddyaccount;
 
5091
                const char *buddyname;
4949
5092
 
4950
5093
                n = *(PurpleBlistNode **)sd->data;
4951
5094
 
4956
5099
                else
4957
5100
                        return;
4958
5101
 
 
5102
                buddyaccount = purple_buddy_get_account(b);
 
5103
                buddyname = purple_buddy_get_name(b);
4959
5104
                /*
4960
 
                 * If we already have an open conversation with this buddy, then
4961
 
                 * just move the conv to this window.  Otherwise, create a new
4962
 
                 * conv and add it to this window.
 
5105
                 * If a buddy is dragged to a chat window of the same protocol,
 
5106
                 * invite him to the chat.
4963
5107
                 */
4964
 
                c = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, b->name, b->account);
4965
 
                if (c != NULL) {
4966
 
                        PidginWindow *oldwin;
4967
 
                        gtkconv = PIDGIN_CONVERSATION(c);
4968
 
                        oldwin = gtkconv->win;
4969
 
                        if (oldwin != win) {
4970
 
                                pidgin_conv_window_remove_gtkconv(oldwin, gtkconv);
4971
 
                                pidgin_conv_window_add_gtkconv(win, gtkconv);
4972
 
                        }
 
5108
                if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT &&
 
5109
                                prpl_info && PURPLE_PROTOCOL_PLUGIN_HAS_FUNC(prpl_info, chat_invite) &&
 
5110
                                strcmp(purple_account_get_protocol_id(convaccount),
 
5111
                                        purple_account_get_protocol_id(buddyaccount)) == 0) {
 
5112
                    purple_conv_chat_invite_user(PURPLE_CONV_CHAT(conv), buddyname, NULL, TRUE);
4973
5113
                } else {
4974
 
                        c = purple_conversation_new(PURPLE_CONV_TYPE_IM, b->account, b->name);
4975
 
                        gtkconv = PIDGIN_CONVERSATION(c);
4976
 
                        if (gtkconv->win != win)
4977
 
                        {
4978
 
                                pidgin_conv_window_remove_gtkconv(gtkconv->win, gtkconv);
4979
 
                                pidgin_conv_window_add_gtkconv(win, gtkconv);
 
5114
                        /*
 
5115
                         * If we already have an open conversation with this buddy, then
 
5116
                         * just move the conv to this window.  Otherwise, create a new
 
5117
                         * conv and add it to this window.
 
5118
                         */
 
5119
                        c = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, buddyname, buddyaccount);
 
5120
                        if (c != NULL) {
 
5121
                                PidginWindow *oldwin;
 
5122
                                gtkconv = PIDGIN_CONVERSATION(c);
 
5123
                                oldwin = gtkconv->win;
 
5124
                                if (oldwin != win) {
 
5125
                                        pidgin_conv_window_remove_gtkconv(oldwin, gtkconv);
 
5126
                                        pidgin_conv_window_add_gtkconv(win, gtkconv);
 
5127
                                }
 
5128
                        } else {
 
5129
                                c = purple_conversation_new(PURPLE_CONV_TYPE_IM, buddyaccount, buddyname);
 
5130
                                gtkconv = PIDGIN_CONVERSATION(c);
 
5131
                                if (gtkconv->win != win) {
 
5132
                                        pidgin_conv_window_remove_gtkconv(gtkconv->win, gtkconv);
 
5133
                                        pidgin_conv_window_add_gtkconv(win, gtkconv);
 
5134
                                }
4980
5135
                        }
 
5136
 
 
5137
                        /* Make this conversation the active conversation */
 
5138
                        pidgin_conv_window_switch_gtkconv(win, gtkconv);
4981
5139
                }
4982
5140
 
4983
 
                /* Make this conversation the active conversation */
4984
 
                pidgin_conv_window_switch_gtkconv(win, gtkconv);
4985
 
 
4986
5141
                gtk_drag_finish(dc, TRUE, (dc->action == GDK_ACTION_MOVE), t);
4987
5142
        }
4988
5143
        else if (sd->target == gdk_atom_intern("application/x-im-contact", FALSE))
5000
5155
                                purple_notify_error(win, NULL,
5001
5156
                                        _("You are not currently signed on with an account that "
5002
5157
                                          "can add that buddy."), NULL);
5003
 
                        }
5004
 
                        else
5005
 
                        {
5006
 
                                c = purple_conversation_new(PURPLE_CONV_TYPE_IM, account, username);
5007
 
                                gtkconv = PIDGIN_CONVERSATION(c);
5008
 
                                if (gtkconv->win != win)
5009
 
                                {
5010
 
                                        pidgin_conv_window_remove_gtkconv(gtkconv->win, gtkconv);
5011
 
                                        pidgin_conv_window_add_gtkconv(win, gtkconv);
 
5158
                        } else {
 
5159
                                /*
 
5160
                                 * If a buddy is dragged to a chat window of the same protocol,
 
5161
                                 * invite him to the chat.
 
5162
                                 */
 
5163
                                if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT &&
 
5164
                                                prpl_info && PURPLE_PROTOCOL_PLUGIN_HAS_FUNC(prpl_info, chat_invite) &&
 
5165
                                                strcmp(purple_account_get_protocol_id(convaccount), protocol) == 0) {
 
5166
                                        purple_conv_chat_invite_user(PURPLE_CONV_CHAT(conv), username, NULL, TRUE);
 
5167
                                } else {
 
5168
                                        c = purple_conversation_new(PURPLE_CONV_TYPE_IM, account, username);
 
5169
                                        gtkconv = PIDGIN_CONVERSATION(c);
 
5170
                                        if (gtkconv->win != win) {
 
5171
                                                pidgin_conv_window_remove_gtkconv(gtkconv->win, gtkconv);
 
5172
                                                pidgin_conv_window_add_gtkconv(win, gtkconv);
 
5173
                                        }
5012
5174
                                }
5013
5175
                        }
5014
5176
                }
5020
5182
        }
5021
5183
        else if (sd->target == gdk_atom_intern("text/uri-list", FALSE)) {
5022
5184
                if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM)
5023
 
                        pidgin_dnd_file_manage(sd, purple_conversation_get_account(conv), purple_conversation_get_name(conv));
 
5185
                        pidgin_dnd_file_manage(sd, convaccount, purple_conversation_get_name(conv));
5024
5186
                gtk_drag_finish(dc, TRUE, (dc->action == GDK_ACTION_MOVE), t);
5025
5187
        }
5026
5188
        else
5038
5200
static PidginConversation *
5039
5201
pidgin_conv_find_gtkconv(PurpleConversation * conv)
5040
5202
{
5041
 
        PurpleBuddy *bud = purple_find_buddy(conv->account, conv->name), *b;
 
5203
        PurpleBuddy *bud = purple_find_buddy(conv->account, conv->name);
5042
5204
        PurpleContact *c;
5043
 
        PurpleBlistNode *cn;
 
5205
        PurpleBlistNode *cn, *bn;
5044
5206
 
5045
5207
        if (!bud)
5046
5208
                return NULL;
5048
5210
        if (!(c = purple_buddy_get_contact(bud)))
5049
5211
                return NULL;
5050
5212
 
5051
 
        cn = (PurpleBlistNode *)c;
5052
 
        for (b = (PurpleBuddy *)cn->child; b; b = (PurpleBuddy *) ((PurpleBlistNode *)b)->next) {
 
5213
        cn = PURPLE_BLIST_NODE(c);
 
5214
        for (bn = purple_blist_node_get_first_child(cn); bn; bn = purple_blist_node_get_sibling_next(bn)) {
 
5215
                PurpleBuddy *b = PURPLE_BUDDY(bn);
5053
5216
                PurpleConversation *conv;
5054
5217
                if ((conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, b->name, b->account))) {
5055
5218
                        if (conv->ui_data)
5066
5229
        GList *list;
5067
5230
 
5068
5231
        g_return_if_fail(bnode);
5069
 
        g_return_if_fail(PURPLE_BLIST_NODE_IS_BUDDY(bnode));
 
5232
        if (!PURPLE_BLIST_NODE_IS_BUDDY(bnode))
 
5233
                return;
5070
5234
 
5071
5235
        for (list = pidgin_conv_windows_get_list(); list; list = list->next)
5072
5236
        {
5281
5445
{
5282
5446
        PurpleConversationUiOps *ui_ops = pidgin_conversations_get_conv_ui_ops();
5283
5447
        gboolean hide = FALSE;
 
5448
        guint timer;
5284
5449
 
5285
5450
        /* create hidden conv if hide_new pref is always */
5286
5451
        if (strcmp(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/conversations/im/hide_new"), "always") == 0)
5304
5469
                purple_conversation_new(PURPLE_CONV_TYPE_IM, account, sender);
5305
5470
                ui_ops->create_conversation = pidgin_conv_new;
5306
5471
        }
 
5472
 
 
5473
        /* Somebody wants to keep this conversation around, so don't time it out */
 
5474
        timer = GPOINTER_TO_INT(purple_conversation_get_data(conv, "close-timer"));
 
5475
        if (timer) {
 
5476
                purple_timeout_remove(timer);
 
5477
                purple_conversation_set_data(conv, "close-timer", GINT_TO_POINTER(0));
 
5478
        }
5307
5479
}
5308
5480
 
5309
5481
static void
5499
5671
        gtkconv->newday = mktime(tm);
5500
5672
}
5501
5673
 
5502
 
/* Detect string direction and encapsulate the string in RLE/LRE/PDF unicode characters 
 
5674
/* Detect string direction and encapsulate the string in RLE/LRE/PDF unicode characters
5503
5675
   str - pointer to string (string is re-allocated and the pointer updated) */
5504
5676
static void
5505
5677
str_embed_direction_chars(char **str)
5535
5707
#endif
5536
5708
}
5537
5709
 
5538
 
/* Returns true if the given HTML contains RTL text */
5539
 
static gboolean 
5540
 
html_is_rtl(const char *html)
5541
 
{
5542
 
        GData *attributes;
5543
 
        const gchar *start, *end;
5544
 
        gboolean res = FALSE;
5545
 
 
5546
 
        if (purple_markup_find_tag("span", html, &start, &end, &attributes)) 
5547
 
        {
5548
 
                /* tmp is a member of attributes and is free with g_datalist_clear call */
5549
 
                const char *tmp = g_datalist_get_data(&attributes, "dir");
5550
 
                if (tmp && !g_ascii_strcasecmp(tmp, "RTL"))
5551
 
                        res = TRUE;
5552
 
                if (!res)
5553
 
                {
5554
 
                        tmp = g_datalist_get_data(&attributes, "style");
5555
 
                        if (tmp)
5556
 
                        {
5557
 
                                char *tmp2 = purple_markup_get_css_property(tmp, "direction");
5558
 
                                if (tmp2 && !g_ascii_strcasecmp(tmp2, "RTL"))
5559
 
                                        res = TRUE;
5560
 
                                g_free(tmp2);
5561
 
                        }
5562
 
 
5563
 
                }
5564
 
                g_datalist_clear(&attributes);
5565
 
        }
5566
 
        return res;
5567
 
}
5568
 
 
5569
 
 
5570
5710
static void
5571
5711
pidgin_conv_write_conv(PurpleConversation *conv, const char *name, const char *alias,
5572
5712
                                                const char *message, PurpleMessageFlags flags,
5728
5868
        }
5729
5869
 
5730
5870
        /* Bi-Directional support - set timestamp direction using unicode characters */
5731
 
        is_rtl_message = html_is_rtl(message);
 
5871
        is_rtl_message = purple_markup_is_rtl(message);
5732
5872
        /* Enforce direction only if message is RTL - doesn't effect LTR users */
5733
5873
        if (is_rtl_message)
5734
5874
                str_embed_direction_chars(&mdate);
5997
6137
        PurpleConvChatBuddy *cbuddy;
5998
6138
        GtkTreeIter iter;
5999
6139
        GtkTreeModel *model;
 
6140
        GtkTextTag *tag;
6000
6141
        int f = 1;
6001
6142
 
6002
6143
        chat    = PURPLE_CONV_CHAT(conv);
6024
6165
                g_free(val);
6025
6166
        }
6026
6167
 
 
6168
        if ((tag = get_buddy_tag(conv, old_name, 0, FALSE)))
 
6169
                g_object_set(G_OBJECT(tag), "style", PANGO_STYLE_ITALIC, NULL);
 
6170
        if ((tag = get_buddy_tag(conv, old_name, PURPLE_MESSAGE_NICK, FALSE)))
 
6171
                g_object_set(G_OBJECT(tag), "style", PANGO_STYLE_ITALIC, NULL);
 
6172
 
6027
6173
        if (!purple_conv_chat_find_user(chat, old_name))
6028
6174
                return;
6029
6175
 
6046
6192
        char tmp[BUF_LONG];
6047
6193
        int num_users;
6048
6194
        gboolean f;
 
6195
        GtkTextTag *tag;
6049
6196
 
6050
6197
        chat    = PURPLE_CONV_CHAT(conv);
6051
6198
        gtkconv = PIDGIN_CONVERSATION(conv);
6078
6225
 
6079
6226
                        g_free(val);
6080
6227
                } while (f);
 
6228
 
 
6229
                if ((tag = get_buddy_tag(conv, l->data, 0, FALSE)))
 
6230
                        g_object_set(G_OBJECT(tag), "style", PANGO_STYLE_ITALIC, NULL);
 
6231
                if ((tag = get_buddy_tag(conv, l->data, PURPLE_MESSAGE_NICK, FALSE)))
 
6232
                        g_object_set(G_OBJECT(tag), "style", PANGO_STYLE_ITALIC, NULL);
6081
6233
        }
6082
6234
 
6083
6235
        g_snprintf(tmp, sizeof(tmp),
6234
6386
        if (!smiley)
6235
6387
                return;
6236
6388
 
 
6389
        smiley->data = g_realloc(smiley->data, smiley->datasize + size);
 
6390
        g_memmove((guchar *)smiley->data + smiley->datasize, data, size);
 
6391
        smiley->datasize += size;
 
6392
 
6237
6393
        loader = smiley->loader;
6238
6394
        if (!loader)
6239
6395
                return;
6405
6561
                        buttons |= GTK_IMHTML_CUSTOM_SMILEY;
6406
6562
                else
6407
6563
                        buttons &= ~GTK_IMHTML_CUSTOM_SMILEY;
6408
 
 
 
6564
                
6409
6565
                gtk_imhtml_set_format_functions(GTK_IMHTML(gtkconv->entry), buttons);
6410
6566
                if (account != NULL)
6411
6567
                        gtk_imhtmltoolbar_associate_smileys(GTK_IMHTMLTOOLBAR(gtkconv->toolbar), purple_account_get_protocol_id(account));
6467
6623
                        PurpleBuddy *buddy = purple_find_buddy(conv->account, conv->name);
6468
6624
                        window_icon =
6469
6625
                                gdk_pixbuf_animation_get_static_image(gtkconv->u.im->anim);
6470
 
                
 
6626
 
6471
6627
                        if (buddy &&  !PURPLE_BUDDY_IS_ONLINE(buddy))
6472
6628
                                gdk_pixbuf_saturate_and_pixelate(window_icon, window_icon, 0.0, FALSE);
6473
 
                        
 
6629
 
6474
6630
                        g_object_ref(window_icon);
6475
6631
                        l = g_list_append(l, window_icon);
6476
6632
                } else {
6663
6819
                        pango_attr_list_unref(list);
6664
6820
                } else
6665
6821
                        gtk_label_set_attributes(GTK_LABEL(gtkconv->tab_label), NULL);
6666
 
                
 
6822
 
6667
6823
                if (pidgin_conv_window_is_active_conversation(conv))
6668
6824
                        update_typing_icon(gtkconv);
6669
6825
 
6730
6886
wrote_msg_update_unseen_cb(PurpleAccount *account, const char *who, const char *message,
6731
6887
                PurpleConversation *conv, PurpleMessageFlags flags, gpointer null)
6732
6888
{
6733
 
        if (conv == NULL || PIDGIN_IS_PIDGIN_CONVERSATION(conv))
 
6889
        PidginConversation *gtkconv = conv ? PIDGIN_CONVERSATION(conv) : NULL;
 
6890
        if (conv == NULL || (gtkconv && gtkconv->win != hidden_convwin))
6734
6891
                return;
6735
6892
        if (flags & (PURPLE_MESSAGE_SEND | PURPLE_MESSAGE_RECV)) {
6736
6893
                PidginUnseenState unseen = PIDGIN_UNSEEN_NONE;
6799
6956
 
6800
6957
        GdkPixbuf *buf;
6801
6958
 
 
6959
        GList *children;
6802
6960
        GtkWidget *event;
6803
6961
        GdkPixbuf *scale;
6804
6962
        int scale_width, scale_height;
6826
6984
                prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(account->gc->prpl);
6827
6985
 
6828
6986
        /* Remove the current icon stuff */
6829
 
        if (gtkconv->u.im->icon_container != NULL)
6830
 
                gtk_widget_destroy(gtkconv->u.im->icon_container);
6831
 
        gtkconv->u.im->icon_container = NULL;
 
6987
        children = gtk_container_get_children(GTK_CONTAINER(gtkconv->u.im->icon_container));
 
6988
        if (children) {
 
6989
                /* We know there's only one child here. It'd be nice to shortcut to the
 
6990
                   event box, but we can't change the PidginConversation until 3.0 */
 
6991
                event = (GtkWidget *)children->data;
 
6992
                gtk_container_remove(GTK_CONTAINER(gtkconv->u.im->icon_container), event);
 
6993
                g_list_free(children);
 
6994
        }
6832
6995
 
6833
6996
        if (gtkconv->u.im->anim != NULL)
6834
6997
                g_object_unref(G_OBJECT(gtkconv->u.im->anim));
6869
7032
                icon = purple_conv_im_get_icon(PURPLE_CONV_IM(conv));
6870
7033
 
6871
7034
                if (icon == NULL)
 
7035
                {
 
7036
                        gtk_widget_set_size_request(gtkconv->u.im->icon_container,
 
7037
                                                    -1, BUDDYICON_SIZE_MIN);
6872
7038
                        return;
 
7039
                }
6873
7040
 
6874
7041
                data = purple_buddy_icon_get_data(icon, &len);
6875
7042
 
6876
7043
                if (data == NULL)
 
7044
                {
 
7045
                        gtk_widget_set_size_request(gtkconv->u.im->icon_container,
 
7046
                                                    -1, BUDDYICON_SIZE_MIN);
6877
7047
                        return;
 
7048
                }
6878
7049
        }
6879
7050
 
6880
7051
        loader = gdk_pixbuf_loader_new();
6916
7087
        scale_width = gdk_pixbuf_get_width(buf);
6917
7088
        scale_height = gdk_pixbuf_get_height(buf);
6918
7089
 
6919
 
        gtk_widget_get_size_request(gtkconv->infopane_hbox, NULL, &size);
 
7090
        gtk_widget_get_size_request(gtkconv->u.im->icon_container, NULL, &size);
6920
7091
        size = MIN(size, MIN(scale_width, scale_height));
6921
7092
 
6922
7093
        /* Some sanity checks */
6935
7106
        g_object_unref(buf);
6936
7107
        if (pidgin_gdk_pixbuf_is_opaque(scale))
6937
7108
                pidgin_gdk_pixbuf_make_round(scale);
6938
 
        gtkconv->u.im->icon_container = gtk_vbox_new(FALSE, 0);
6939
7109
 
6940
7110
        event = gtk_event_box_new();
6941
7111
        gtk_container_add(GTK_CONTAINER(gtkconv->u.im->icon_container), event);
6956
7126
 
6957
7127
        g_object_unref(G_OBJECT(scale));
6958
7128
 
6959
 
        gtk_box_pack_start(GTK_BOX(gtkconv->infopane_hbox),
6960
 
                           gtkconv->u.im->icon_container, FALSE, FALSE, 0);
6961
 
 
6962
 
        gtk_widget_show(gtkconv->u.im->icon_container);
6963
 
 
6964
7129
        /* The buddy icon code needs badly to be fixed. */
6965
7130
        if(pidgin_conv_window_is_active_conversation(conv))
6966
7131
        {
7235
7400
                PurpleConversation *conv = l->data;
7236
7401
                if (!PIDGIN_CONVERSATION(conv))
7237
7402
                        continue;
7238
 
                if (GPOINTER_TO_INT(value)) 
 
7403
                if (GPOINTER_TO_INT(value))
7239
7404
                        gtk_widget_show(PIDGIN_CONVERSATION(conv)->infopane_hbox);
7240
7405
                else
7241
7406
                        gtk_widget_hide(PIDGIN_CONVERSATION(conv)->infopane_hbox);
7443
7608
        }
7444
7609
 
7445
7610
        /* In case a conversation is started after the buddy has signed-on/off */
7446
 
        g_timeout_add(11000, (GSourceFunc)update_buddy_status_timeout, buddy);
 
7611
        purple_timeout_add_seconds(11, (GSourceFunc)update_buddy_status_timeout, buddy);
7447
7612
}
7448
7613
 
7449
7614
static void
7645
7810
        list = purple_conversation_get_message_history(conv);
7646
7811
        if (list) {
7647
7812
                switch (purple_conversation_get_type(conv)) {
7648
 
                        case PURPLE_CONV_TYPE_IM: 
 
7813
                        case PURPLE_CONV_TYPE_IM:
7649
7814
                        {
7650
7815
                                GList *convs;
7651
7816
                                list = g_list_copy(list);
7919
8084
                        handle, PURPLE_CALLBACK(account_status_changed_cb), NULL);
7920
8085
 
7921
8086
        /* Callbacks to update a conversation */
7922
 
        purple_signal_connect(blist_handle, "buddy-added", handle,
 
8087
        purple_signal_connect(blist_handle, "blist-node-added", handle,
7923
8088
                                                G_CALLBACK(buddy_update_cb), NULL);
7924
 
        purple_signal_connect(blist_handle, "buddy-removed", handle,
 
8089
        purple_signal_connect(blist_handle, "blist-node-removed", handle,
7925
8090
                                                G_CALLBACK(buddy_update_cb), NULL);
7926
8091
        purple_signal_connect(blist_handle, "buddy-signed-on",
7927
8092
                                                handle, PURPLE_CALLBACK(update_buddy_sign), "on");
8087
8252
static void
8088
8253
build_warn_close_dialog(PidginWindow *gtkwin)
8089
8254
{
8090
 
        GtkWidget *label;
8091
 
        GtkWidget *vbox, *hbox;
8092
 
        GtkWidget *img;
 
8255
        GtkWidget *label, *vbox, *hbox, *img;
8093
8256
 
8094
8257
        g_return_if_fail(warn_close_dialog == NULL);
8095
8258
 
8096
 
 
8097
 
        warn_close_dialog = gtk_dialog_new_with_buttons(
8098
 
                                                        _("Confirm close"),
 
8259
        warn_close_dialog = gtk_dialog_new_with_buttons(_("Confirm close"),
8099
8260
                                                        GTK_WINDOW(gtkwin->window), GTK_DIALOG_MODAL,
8100
8261
                                                        GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
8101
8262
                                                        GTK_STOCK_CLOSE, GTK_RESPONSE_OK, NULL);
8218
8379
                        gtkconv->unseen_state = state;
8219
8380
        }
8220
8381
 
 
8382
        purple_conversation_set_data(gtkconv->active_conv, "unseen-count", GINT_TO_POINTER(gtkconv->unseen_count));
 
8383
        purple_conversation_set_data(gtkconv->active_conv, "unseen-state", GINT_TO_POINTER(gtkconv->unseen_state));
 
8384
 
8221
8385
        purple_conversation_update(gtkconv->active_conv, PURPLE_CONV_UPDATE_UNSEEN);
8222
8386
}
8223
8387
 
8411
8575
                                                                    G_CALLBACK(notebook_leave_cb), gtkconv->win);
8412
8576
                return FALSE;
8413
8577
        }
8414
 
        
 
8578
 
8415
8579
        if (e->button == 3) {
8416
8580
                /* Right click was pressed. Popup the context menu. */
8417
8581
                GtkWidget *menu = gtk_menu_new(), *sub;
8437
8601
        }
8438
8602
        return FALSE;
8439
8603
}
8440
 
 
 
8604
 
8441
8605
static gboolean
8442
8606
notebook_press_cb(GtkWidget *widget, GdkEventButton *e, PidginWindow *win)
8443
8607
{
9017
9181
 
9018
9182
static gboolean gtk_conv_configure_cb(GtkWidget *w, GdkEventConfigure *event, gpointer data) {
9019
9183
        int x, y;
9020
 
        
 
9184
 
9021
9185
        if (GTK_WIDGET_VISIBLE(w))
9022
9186
                gtk_window_get_position(GTK_WINDOW(w), &x, &y);
9023
9187
        else
9027
9191
        * when the window is being maximized */
9028
9192
        if (gdk_window_get_state(w->window) & GDK_WINDOW_STATE_MAXIMIZED)
9029
9193
                return FALSE;
9030
 
        
 
9194
 
9031
9195
        /* don't save off-screen positioning */
9032
9196
        if (x + event->width < 0 ||
9033
9197
            y + event->height < 0 ||
9043
9207
 
9044
9208
        /* continue to handle event normally */
9045
9209
        return FALSE;
9046
 
                                                
 
9210
 
9047
9211
}
9048
9212
 
9049
9213
static void
9124
9288
        /* Intercept keystrokes from the menu items */
9125
9289
        g_signal_connect(G_OBJECT(win->window), "key_press_event",
9126
9290
                                         G_CALLBACK(window_keypress_cb), win);
9127
 
        
 
9291
 
9128
9292
 
9129
9293
        /* Create the notebook. */
9130
9294
        win->notebook = gtk_notebook_new();
9286
9450
        win->gtkconvs = g_list_append(win->gtkconvs, gtkconv);
9287
9451
        gtkconv->win = win;
9288
9452
 
9289
 
        if (win->gtkconvs && win->gtkconvs->next && win->gtkconvs->next->next == NULL) 
 
9453
        if (win->gtkconvs && win->gtkconvs->next && win->gtkconvs->next->next == NULL)
9290
9454
                pidgin_conv_tab_pack(win, ((PidginConversation*)win->gtkconvs->data));
9291
9455
 
9292
9456
 
9320
9484
        /* Status icon. */
9321
9485
        gtkconv->icon = gtk_image_new();
9322
9486
        gtkconv->menu_icon = gtk_image_new();
 
9487
        g_object_set(G_OBJECT(gtkconv->icon),
 
9488
                        "icon-size", gtk_icon_size_from_name(PIDGIN_ICON_SIZE_TANGO_MICROSCOPIC),
 
9489
                        NULL);
 
9490
        g_object_set(G_OBJECT(gtkconv->menu_icon),
 
9491
                        "icon-size", gtk_icon_size_from_name(PIDGIN_ICON_SIZE_TANGO_MICROSCOPIC),
 
9492
                        NULL);
9323
9493
        gtk_widget_show(gtkconv->icon);
9324
9494
        update_tab_icon(conv);
9325
9495
 
9445
9615
                gtk_notebook_set_tab_label(GTK_NOTEBOOK(win->notebook), gtkconv->tab_cont, ebox);
9446
9616
        }
9447
9617
 
9448
 
        gtk_notebook_set_tab_label_packing(GTK_NOTEBOOK(win->notebook), gtkconv->tab_cont, 
9449
 
                                           !tabs_side && !angle, 
 
9618
        gtk_notebook_set_tab_label_packing(GTK_NOTEBOOK(win->notebook), gtkconv->tab_cont,
 
9619
                                           !tabs_side && !angle,
9450
9620
                                           TRUE, GTK_PACK_START);
9451
9621
 
9452
 
        if (pidgin_conv_window_get_gtkconv_count(win) == 1) 
 
9622
        if (pidgin_conv_window_get_gtkconv_count(win) == 1)
9453
9623
                gtk_notebook_set_show_tabs(GTK_NOTEBOOK(win->notebook),
9454
9624
                                           purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/tabs") &&
9455
9625
                                           (!purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/im/show_buddy_icons") ||
9660
9830
        if (win == NULL) {
9661
9831
                win = pidgin_conv_window_new();
9662
9832
 
9663
 
                g_signal_connect(G_OBJECT(win->window), "configure_event", 
 
9833
                g_signal_connect(G_OBJECT(win->window), "configure_event",
9664
9834
                                G_CALLBACK(gtk_conv_configure_cb), NULL);
9665
9835
 
9666
9836
                pidgin_conv_window_add_gtkconv(win, conv);
9675
9845
conv_placement_last_created_win_type_configured_cb(GtkWidget *w,
9676
9846
                GdkEventConfigure *event, PidginConversation *conv)
9677
9847
{
9678
 
        int x, y;       
 
9848
        int x, y;
9679
9849
        PurpleConversationType type = purple_conversation_get_type(conv->active_conv);
9680
9850
        GList *all;
9681
9851
 
9688
9858
        * when the window is being maximized */
9689
9859
        if (gdk_window_get_state(w->window) & GDK_WINDOW_STATE_MAXIMIZED)
9690
9860
                return FALSE;
9691
 
        
 
9861
 
9692
9862
        /* don't save off-screen positioning */
9693
9863
        if (x + event->width < 0 ||
9694
9864
            y + event->height < 0 ||
9742
9912
                                purple_prefs_get_int(PIDGIN_PREFS_ROOT "/conversations/chat/width"),
9743
9913
                                purple_prefs_get_int(PIDGIN_PREFS_ROOT "/conversations/chat/height"));
9744
9914
                }
9745
 
                                
 
9915
 
9746
9916
                pidgin_conv_window_add_gtkconv(win, conv);
9747
9917
                pidgin_conv_window_show(win);
9748
9918
 
9749
 
                g_signal_connect(G_OBJECT(win->window), "configure_event", 
 
9919
                g_signal_connect(G_OBJECT(win->window), "configure_event",
9750
9920
                                G_CALLBACK(conv_placement_last_created_win_type_configured_cb), conv);
9751
9921
        } else
9752
9922
                pidgin_conv_window_add_gtkconv(win, conv);
9760
9930
 
9761
9931
        win = pidgin_conv_window_new();
9762
9932
 
9763
 
        g_signal_connect(G_OBJECT(win->window), "configure_event", 
 
9933
        g_signal_connect(G_OBJECT(win->window), "configure_event",
9764
9934
                        G_CALLBACK(gtk_conv_configure_cb), NULL);
9765
9935
 
9766
9936
        pidgin_conv_window_add_gtkconv(win, conv);