comparison pidgin/gtkconv.c @ 32162:accce7b79737

merged from im.pidgin.pidgin
author Yoshiki Yazawa <yaz@honeyplanet.jp>
date Sun, 26 Jun 2011 02:27:01 +0900
parents 6b3bc0947068 47c604efed32
children 9aee8493db7f
comparison
equal deleted inserted replaced
32108:fa9d736e9937 32162:accce7b79737
4049 } 4049 }
4050 return image; 4050 return image;
4051 } 4051 }
4052 4052
4053 static void 4053 static void
4054 deleting_chat_buddy_cb(PurpleConvChatBuddy *cb)
4055 {
4056 if (cb->ui_data) {
4057 GtkTreeRowReference *ref = cb->ui_data;
4058 gtk_tree_row_reference_free(ref);
4059 cb->ui_data = NULL;
4060 }
4061 }
4062
4063 static void
4054 add_chat_buddy_common(PurpleConversation *conv, PurpleConvChatBuddy *cb, const char *old_name) 4064 add_chat_buddy_common(PurpleConversation *conv, PurpleConvChatBuddy *cb, const char *old_name)
4055 { 4065 {
4056 PidginConversation *gtkconv; 4066 PidginConversation *gtkconv;
4057 PidginChatPane *gtkchat; 4067 PidginChatPane *gtkchat;
4058 PurpleConvChat *chat; 4068 PurpleConvChat *chat;
4059 PurpleConnection *gc; 4069 PurpleConnection *gc;
4060 PurplePluginProtocolInfo *prpl_info; 4070 PurplePluginProtocolInfo *prpl_info;
4071 GtkTreeModel *tm;
4061 GtkListStore *ls; 4072 GtkListStore *ls;
4073 GtkTreePath *newpath;
4062 const char *stock; 4074 const char *stock;
4063 GtkTreeIter iter; 4075 GtkTreeIter iter;
4064 gboolean is_me = FALSE; 4076 gboolean is_me = FALSE;
4065 gboolean is_buddy; 4077 gboolean is_buddy;
4066 gchar *tmp, *alias_key, *name, *alias; 4078 gchar *tmp, *alias_key, *name, *alias;
4067 int flags; 4079 PurpleConvChatBuddyFlags flags;
4068 GdkColor *color = NULL; 4080 GdkColor *color = NULL;
4069 4081
4070 alias = cb->alias; 4082 alias = cb->alias;
4071 name = cb->name; 4083 name = cb->name;
4072 flags = GPOINTER_TO_INT(cb->flags); 4084 flags = cb->flags;
4073 4085
4074 chat = PURPLE_CONV_CHAT(conv); 4086 chat = PURPLE_CONV_CHAT(conv);
4075 gtkconv = PIDGIN_CONVERSATION(conv); 4087 gtkconv = PIDGIN_CONVERSATION(conv);
4076 gtkchat = gtkconv->u.chat; 4088 gtkchat = gtkconv->u.chat;
4077 gc = purple_conversation_get_gc(conv); 4089 gc = purple_conversation_get_gc(conv);
4078 4090
4079 if (!gc || !(prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl))) 4091 if (!gc || !(prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl)))
4080 return; 4092 return;
4081 4093
4082 ls = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(gtkchat->list))); 4094 tm = gtk_tree_view_get_model(GTK_TREE_VIEW(gtkchat->list));
4095 ls = GTK_LIST_STORE(tm);
4083 4096
4084 stock = get_chat_buddy_status_icon(chat, name, flags); 4097 stock = get_chat_buddy_status_icon(chat, name, flags);
4085 4098
4086 if (!strcmp(chat->nick, purple_normalize(conv->account, old_name != NULL ? old_name : name))) 4099 if (!strcmp(chat->nick, purple_normalize(conv->account, old_name != NULL ? old_name : name)))
4087 is_me = TRUE; 4100 is_me = TRUE;
4121 CHAT_USERS_NAME_COLUMN, name, 4134 CHAT_USERS_NAME_COLUMN, name,
4122 CHAT_USERS_FLAGS_COLUMN, flags, 4135 CHAT_USERS_FLAGS_COLUMN, flags,
4123 CHAT_USERS_COLOR_COLUMN, color, 4136 CHAT_USERS_COLOR_COLUMN, color,
4124 CHAT_USERS_WEIGHT_COLUMN, is_buddy ? PANGO_WEIGHT_BOLD : PANGO_WEIGHT_NORMAL, 4137 CHAT_USERS_WEIGHT_COLUMN, is_buddy ? PANGO_WEIGHT_BOLD : PANGO_WEIGHT_NORMAL,
4125 -1); 4138 -1);
4139
4140 if (cb->ui_data) {
4141 GtkTreeRowReference *ref = cb->ui_data;
4142 gtk_tree_row_reference_free(ref);
4143 }
4144
4145 newpath = gtk_tree_model_get_path(tm, &iter);
4146 cb->ui_data = gtk_tree_row_reference_new(tm, newpath);
4147 gtk_tree_path_free(newpath);
4126 4148
4127 if (is_me && color) 4149 if (is_me && color)
4128 gdk_color_free(color); 4150 gdk_color_free(color);
4129 g_free(alias_key); 4151 g_free(alias_key);
4130 } 4152 }
4416 gtk_tree_model_get(model, b, 4438 gtk_tree_model_get(model, b,
4417 CHAT_USERS_ALIAS_KEY_COLUMN, &user2, 4439 CHAT_USERS_ALIAS_KEY_COLUMN, &user2,
4418 CHAT_USERS_FLAGS_COLUMN, &f2, 4440 CHAT_USERS_FLAGS_COLUMN, &f2,
4419 CHAT_USERS_WEIGHT_COLUMN, &buddy2, 4441 CHAT_USERS_WEIGHT_COLUMN, &buddy2,
4420 -1); 4442 -1);
4443
4444 /* Only sort by membership levels */
4445 f1 &= PURPLE_CBFLAGS_VOICE | PURPLE_CBFLAGS_HALFOP | PURPLE_CBFLAGS_OP |
4446 PURPLE_CBFLAGS_FOUNDER;
4447 f2 &= PURPLE_CBFLAGS_VOICE | PURPLE_CBFLAGS_HALFOP | PURPLE_CBFLAGS_OP |
4448 PURPLE_CBFLAGS_FOUNDER;
4421 4449
4422 if (user1 == NULL || user2 == NULL) { 4450 if (user1 == NULL || user2 == NULL) {
4423 if (!(user1 == NULL && user2 == NULL)) 4451 if (!(user1 == NULL && user2 == NULL))
4424 ret = (user1 == NULL) ? -1: 1; 4452 ret = (user1 == NULL) ? -1: 1;
4425 } else if (f1 != f2) { 4453 } else if (f1 != f2) {
6193 account, name, displaying, conv, flags); 6221 account, name, displaying, conv, flags);
6194 g_free(displaying); 6222 g_free(displaying);
6195 update_typing_message(gtkconv, NULL); 6223 update_typing_message(gtkconv, NULL);
6196 } 6224 }
6197 6225
6226 static gboolean get_iter_from_chatbuddy(PurpleConvChatBuddy *cb, GtkTreeIter *iter)
6227 {
6228 GtkTreeRowReference *ref = cb->ui_data;
6229 GtkTreePath *path;
6230 GtkTreeModel *model;
6231
6232 if (!ref)
6233 return FALSE;
6234
6235 if ((path = gtk_tree_row_reference_get_path(ref)) == NULL)
6236 return FALSE;
6237
6238 model = gtk_tree_row_reference_get_model(ref);
6239 if (!gtk_tree_model_get_iter(GTK_TREE_MODEL(model), iter, path)) {
6240 gtk_tree_path_free(path);
6241 return FALSE;
6242 }
6243
6244 gtk_tree_path_free(path);
6245 return TRUE;
6246 }
6247
6198 static void 6248 static void
6199 pidgin_conv_chat_add_users(PurpleConversation *conv, GList *cbuddies, gboolean new_arrivals) 6249 pidgin_conv_chat_add_users(PurpleConversation *conv, GList *cbuddies, gboolean new_arrivals)
6200 { 6250 {
6201 PurpleConvChat *chat; 6251 PurpleConvChat *chat;
6202 PidginConversation *gtkconv; 6252 PidginConversation *gtkconv;
6243 const char *new_name, const char *new_alias) 6293 const char *new_name, const char *new_alias)
6244 { 6294 {
6245 PurpleConvChat *chat; 6295 PurpleConvChat *chat;
6246 PidginConversation *gtkconv; 6296 PidginConversation *gtkconv;
6247 PidginChatPane *gtkchat; 6297 PidginChatPane *gtkchat;
6248 PurpleConvChatBuddyFlags flags; 6298 PurpleConvChatBuddy *old_cbuddy, *new_cbuddy;
6249 PurpleConvChatBuddy *cbuddy;
6250 GtkTreeIter iter; 6299 GtkTreeIter iter;
6251 GtkTreeModel *model; 6300 GtkTreeModel *model;
6252 GtkTextTag *tag; 6301 GtkTextTag *tag;
6253 int f = 1;
6254 6302
6255 chat = PURPLE_CONV_CHAT(conv); 6303 chat = PURPLE_CONV_CHAT(conv);
6256 gtkconv = PIDGIN_CONVERSATION(conv); 6304 gtkconv = PIDGIN_CONVERSATION(conv);
6257 gtkchat = gtkconv->u.chat; 6305 gtkchat = gtkconv->u.chat;
6258 6306
6259 model = gtk_tree_view_get_model(GTK_TREE_VIEW(gtkchat->list)); 6307 model = gtk_tree_view_get_model(GTK_TREE_VIEW(gtkchat->list));
6260 6308
6261 if (!gtk_tree_model_get_iter_first(GTK_TREE_MODEL(model), &iter)) 6309 if (!gtk_tree_model_get_iter_first(GTK_TREE_MODEL(model), &iter))
6262 return; 6310 return;
6263 6311
6264 while (f != 0) { 6312 old_cbuddy = purple_conv_chat_cb_find(chat, old_name);
6265 char *val; 6313 if (get_iter_from_chatbuddy(old_cbuddy, &iter)) {
6266 6314 GtkTreeRowReference *ref = old_cbuddy->ui_data;
6267 gtk_tree_model_get(GTK_TREE_MODEL(model), &iter, CHAT_USERS_NAME_COLUMN, &val, CHAT_USERS_FLAGS_COLUMN, &flags, -1); 6315
6268 6316 gtk_list_store_remove(GTK_LIST_STORE(model), &iter);
6269 if (!purple_utf8_strcasecmp(old_name, val)) { 6317 gtk_tree_row_reference_free(ref);
6270 gtk_list_store_remove(GTK_LIST_STORE(model), &iter); 6318 old_cbuddy->ui_data = NULL;
6271 g_free(val);
6272 break;
6273 }
6274
6275 f = gtk_tree_model_iter_next(GTK_TREE_MODEL(model), &iter);
6276
6277 g_free(val);
6278 } 6319 }
6279 6320
6280 if ((tag = get_buddy_tag(conv, old_name, 0, FALSE))) 6321 if ((tag = get_buddy_tag(conv, old_name, 0, FALSE)))
6281 g_object_set(G_OBJECT(tag), "style", PANGO_STYLE_ITALIC, NULL); 6322 g_object_set(G_OBJECT(tag), "style", PANGO_STYLE_ITALIC, NULL);
6282 if ((tag = get_buddy_tag(conv, old_name, PURPLE_MESSAGE_NICK, FALSE))) 6323 if ((tag = get_buddy_tag(conv, old_name, PURPLE_MESSAGE_NICK, FALSE)))
6283 g_object_set(G_OBJECT(tag), "style", PANGO_STYLE_ITALIC, NULL); 6324 g_object_set(G_OBJECT(tag), "style", PANGO_STYLE_ITALIC, NULL);
6284 6325
6285 if (!purple_conv_chat_find_user(chat, old_name)) 6326 if (!old_cbuddy)
6286 return; 6327 return;
6287 6328
6288 g_return_if_fail(new_alias != NULL); 6329 g_return_if_fail(new_alias != NULL);
6289 6330
6290 cbuddy = purple_conv_chat_cb_find(chat, new_name); 6331 new_cbuddy = purple_conv_chat_cb_find(chat, new_name);
6291 6332
6292 add_chat_buddy_common(conv, cbuddy, old_name); 6333 add_chat_buddy_common(conv, new_cbuddy, old_name);
6293 } 6334 }
6294 6335
6295 static void 6336 static void
6296 pidgin_conv_chat_remove_users(PurpleConversation *conv, GList *users) 6337 pidgin_conv_chat_remove_users(PurpleConversation *conv, GList *users)
6297 { 6338 {
6314 6355
6315 for (l = users; l != NULL; l = l->next) { 6356 for (l = users; l != NULL; l = l->next) {
6316 model = gtk_tree_view_get_model(GTK_TREE_VIEW(gtkchat->list)); 6357 model = gtk_tree_view_get_model(GTK_TREE_VIEW(gtkchat->list));
6317 6358
6318 if (!gtk_tree_model_get_iter_first(GTK_TREE_MODEL(model), &iter)) 6359 if (!gtk_tree_model_get_iter_first(GTK_TREE_MODEL(model), &iter))
6360 /* XXX: Break? */
6319 continue; 6361 continue;
6320 6362
6321 do { 6363 do {
6322 char *val; 6364 char *val;
6323 6365
6353 PurpleConvChatBuddy *cbuddy; 6395 PurpleConvChatBuddy *cbuddy;
6354 PidginConversation *gtkconv; 6396 PidginConversation *gtkconv;
6355 PidginChatPane *gtkchat; 6397 PidginChatPane *gtkchat;
6356 GtkTreeIter iter; 6398 GtkTreeIter iter;
6357 GtkTreeModel *model; 6399 GtkTreeModel *model;
6358 int f = 1;
6359 char *alias = NULL;
6360 6400
6361 chat = PURPLE_CONV_CHAT(conv); 6401 chat = PURPLE_CONV_CHAT(conv);
6362 gtkconv = PIDGIN_CONVERSATION(conv); 6402 gtkconv = PIDGIN_CONVERSATION(conv);
6363 gtkchat = gtkconv->u.chat; 6403 gtkchat = gtkconv->u.chat;
6364 6404
6365 model = gtk_tree_view_get_model(GTK_TREE_VIEW(gtkchat->list)); 6405 model = gtk_tree_view_get_model(GTK_TREE_VIEW(gtkchat->list));
6366 6406
6367 if (!gtk_tree_model_get_iter_first(GTK_TREE_MODEL(model), &iter)) 6407 if (!gtk_tree_model_get_iter_first(GTK_TREE_MODEL(model), &iter))
6368 return; 6408 return;
6369 6409
6370 while (f != 0) {
6371 char *val;
6372
6373 gtk_tree_model_get(GTK_TREE_MODEL(model), &iter, CHAT_USERS_NAME_COLUMN, &val, -1);
6374
6375 if (!purple_utf8_strcasecmp(user, val)) {
6376 gtk_tree_model_get(GTK_TREE_MODEL(model), &iter, CHAT_USERS_ALIAS_COLUMN, &alias, -1);
6377 gtk_list_store_remove(GTK_LIST_STORE(model), &iter);
6378 g_free(val);
6379 break;
6380 }
6381
6382 f = gtk_tree_model_iter_next(GTK_TREE_MODEL(model), &iter);
6383
6384 g_free(val);
6385 }
6386
6387 if (!purple_conv_chat_find_user(chat, user))
6388 {
6389 g_free(alias);
6390 return;
6391 }
6392
6393 g_return_if_fail(alias != NULL);
6394
6395 cbuddy = purple_conv_chat_cb_find(chat, user); 6410 cbuddy = purple_conv_chat_cb_find(chat, user);
6411 if (get_iter_from_chatbuddy(cbuddy, &iter)) {
6412 GtkTreeRowReference *ref = cbuddy->ui_data;
6413 gtk_list_store_remove(GTK_LIST_STORE(model), &iter);
6414 gtk_tree_row_reference_free(ref);
6415 cbuddy->ui_data = NULL;
6416 }
6417
6396 if (cbuddy) 6418 if (cbuddy)
6397 add_chat_buddy_common(conv, cbuddy, NULL); 6419 add_chat_buddy_common(conv, cbuddy, NULL);
6398 g_free(alias);
6399 } 6420 }
6400 6421
6401 gboolean 6422 gboolean
6402 pidgin_conv_has_focus(PurpleConversation *conv) 6423 pidgin_conv_has_focus(PurpleConversation *conv)
6403 { 6424 {
6478 pidgin_conv_custom_smiley_write(PurpleConversation *conv, const char *smile, 6499 pidgin_conv_custom_smiley_write(PurpleConversation *conv, const char *smile,
6479 const guchar *data, gsize size) 6500 const guchar *data, gsize size)
6480 { 6501 {
6481 PidginConversation *gtkconv; 6502 PidginConversation *gtkconv;
6482 GtkIMHtmlSmiley *smiley; 6503 GtkIMHtmlSmiley *smiley;
6483 GdkPixbufLoader *loader;
6484 const char *sml; 6504 const char *sml;
6505 GError *error = NULL;
6485 6506
6486 sml = purple_account_get_protocol_name(conv->account); 6507 sml = purple_account_get_protocol_name(conv->account);
6487 gtkconv = PIDGIN_CONVERSATION(conv); 6508 gtkconv = PIDGIN_CONVERSATION(conv);
6488 smiley = gtk_imhtml_smiley_get(GTK_IMHTML(gtkconv->imhtml), sml, smile); 6509 smiley = gtk_imhtml_smiley_get(GTK_IMHTML(gtkconv->imhtml), sml, smile);
6489 6510
6492 6513
6493 smiley->data = g_realloc(smiley->data, smiley->datasize + size); 6514 smiley->data = g_realloc(smiley->data, smiley->datasize + size);
6494 g_memmove((guchar *)smiley->data + smiley->datasize, data, size); 6515 g_memmove((guchar *)smiley->data + smiley->datasize, data, size);
6495 smiley->datasize += size; 6516 smiley->datasize += size;
6496 6517
6497 loader = smiley->loader; 6518 if (!smiley->loader)
6498 if (!loader)
6499 return; 6519 return;
6500 6520
6501 gdk_pixbuf_loader_write(loader, data, size, NULL); 6521 if (!gdk_pixbuf_loader_write(smiley->loader, data, size, &error) || error) {
6522 purple_debug_warning("gtkconv", "gdk_pixbuf_loader_write() "
6523 "failed with size=%zu: %s\n", size,
6524 error ? error->message : "(no error message)");
6525 if (error)
6526 g_error_free(error);
6527 /* We must stop using the GdkPixbufLoader because trying to load
6528 certain invalid GIFs with at least gdk-pixbuf 2.23.3 can return
6529 a GdkPixbuf that will cause some operations (like
6530 gdk_pixbuf_scale_simple()) to consume memory in an infinite loop.
6531 But we also don't want to set smiley->loader to NULL because our
6532 code might expect it to be set. So create a new loader. */
6533 g_object_unref(G_OBJECT(smiley->loader));
6534 smiley->loader = gdk_pixbuf_loader_new();
6535 }
6502 } 6536 }
6503 6537
6504 static void 6538 static void
6505 pidgin_conv_custom_smiley_close(PurpleConversation *conv, const char *smile) 6539 pidgin_conv_custom_smiley_close(PurpleConversation *conv, const char *smile)
6506 { 6540 {
6507 PidginConversation *gtkconv; 6541 PidginConversation *gtkconv;
6508 GtkIMHtmlSmiley *smiley; 6542 GtkIMHtmlSmiley *smiley;
6509 GdkPixbufLoader *loader;
6510 const char *sml; 6543 const char *sml;
6544 GError *error = NULL;
6511 6545
6512 g_return_if_fail(conv != NULL); 6546 g_return_if_fail(conv != NULL);
6513 g_return_if_fail(smile != NULL); 6547 g_return_if_fail(smile != NULL);
6514 6548
6515 sml = purple_account_get_protocol_name(conv->account); 6549 sml = purple_account_get_protocol_name(conv->account);
6517 smiley = gtk_imhtml_smiley_get(GTK_IMHTML(gtkconv->imhtml), sml, smile); 6551 smiley = gtk_imhtml_smiley_get(GTK_IMHTML(gtkconv->imhtml), sml, smile);
6518 6552
6519 if (!smiley) 6553 if (!smiley)
6520 return; 6554 return;
6521 6555
6522 loader = smiley->loader; 6556 if (!smiley->loader)
6523
6524 if (!loader)
6525 return; 6557 return;
6526 6558
6527
6528
6529 purple_debug_info("gtkconv", "About to close the smiley pixbuf\n"); 6559 purple_debug_info("gtkconv", "About to close the smiley pixbuf\n");
6530 6560
6531 gdk_pixbuf_loader_close(loader, NULL); 6561 if (!gdk_pixbuf_loader_close(smiley->loader, &error) || error) {
6532 6562 purple_debug_warning("gtkconv", "gdk_pixbuf_loader_close() "
6563 "failed: %s\n",
6564 error ? error->message : "(no error message)");
6565 if (error)
6566 g_error_free(error);
6567 /* We must stop using the GdkPixbufLoader because if we tried to
6568 load certain invalid GIFs with all current versions of GDK (as
6569 of 2011-06-15) then it's possible the loader will contain data
6570 that could cause some operations (like gdk_pixbuf_scale_simple())
6571 to consume memory in an infinite loop. But we also don't want
6572 to set smiley->loader to NULL because our code might expect it
6573 to be set. So create a new loader. */
6574 g_object_unref(G_OBJECT(smiley->loader));
6575 smiley->loader = gdk_pixbuf_loader_new();
6576 }
6533 } 6577 }
6534 6578
6535 static void 6579 static void
6536 pidgin_conv_send_confirm(PurpleConversation *conv, const char *message) 6580 pidgin_conv_send_confirm(PurpleConversation *conv, const char *message)
6537 { 6581 {
6680 gtk_widget_set_sensitive(win->menu.insert_link, (conv->features & PURPLE_CONNECTION_HTML)); 6724 gtk_widget_set_sensitive(win->menu.insert_link, (conv->features & PURPLE_CONNECTION_HTML));
6681 gtk_widget_set_sensitive(win->menu.insert_image, !(conv->features & PURPLE_CONNECTION_NO_IMAGES)); 6725 gtk_widget_set_sensitive(win->menu.insert_image, !(conv->features & PURPLE_CONNECTION_NO_IMAGES));
6682 6726
6683 if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) 6727 if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM)
6684 { 6728 {
6685 gtk_widget_set_sensitive(win->menu.add, (prpl_info->add_buddy != NULL)); 6729 gtk_widget_set_sensitive(win->menu.add, (prpl_info->add_buddy != NULL) || (prpl_info->add_buddy_with_invite != NULL));
6686 gtk_widget_set_sensitive(win->menu.remove, (prpl_info->remove_buddy != NULL)); 6730 gtk_widget_set_sensitive(win->menu.remove, (prpl_info->remove_buddy != NULL));
6687 gtk_widget_set_sensitive(win->menu.send_file, 6731 gtk_widget_set_sensitive(win->menu.send_file,
6688 (prpl_info->send_file != NULL && (!prpl_info->can_receive_file || 6732 (prpl_info->send_file != NULL && (!prpl_info->can_receive_file ||
6689 prpl_info->can_receive_file(gc, purple_conversation_get_name(conv))))); 6733 prpl_info->can_receive_file(gc, purple_conversation_get_name(conv)))));
6690 gtk_widget_set_sensitive(g_object_get_data(G_OBJECT(win->window), "get_attention"), (prpl_info->send_attention != NULL)); 6734 gtk_widget_set_sensitive(g_object_get_data(G_OBJECT(win->window), "get_attention"), (prpl_info->send_attention != NULL));
7048 PidginConversation *gtkconv; 7092 PidginConversation *gtkconv;
7049 PidginWindow *win; 7093 PidginWindow *win;
7050 7094
7051 PurpleBuddy *buddy; 7095 PurpleBuddy *buddy;
7052 7096
7053 GdkPixbufLoader *loader;
7054 GdkPixbufAnimation *anim;
7055 GError *err = NULL;
7056
7057 PurpleStoredImage *custom_img = NULL; 7097 PurpleStoredImage *custom_img = NULL;
7058 gconstpointer data = NULL; 7098 gconstpointer data = NULL;
7059 size_t len; 7099 size_t len;
7060 7100
7061 GdkPixbuf *buf; 7101 GdkPixbuf *buf;
7129 } 7169 }
7130 } 7170 }
7131 7171
7132 if (data == NULL) { 7172 if (data == NULL) {
7133 icon = purple_conv_im_get_icon(PURPLE_CONV_IM(conv)); 7173 icon = purple_conv_im_get_icon(PURPLE_CONV_IM(conv));
7134
7135 if (icon == NULL) 7174 if (icon == NULL)
7136 { 7175 {
7137 gtk_widget_set_size_request(gtkconv->u.im->icon_container, 7176 gtk_widget_set_size_request(gtkconv->u.im->icon_container,
7138 -1, BUDDYICON_SIZE_MIN); 7177 -1, BUDDYICON_SIZE_MIN);
7139 return; 7178 return;
7140 } 7179 }
7141 7180
7142 data = purple_buddy_icon_get_data(icon, &len); 7181 data = purple_buddy_icon_get_data(icon, &len);
7143
7144 if (data == NULL) 7182 if (data == NULL)
7145 { 7183 {
7146 gtk_widget_set_size_request(gtkconv->u.im->icon_container, 7184 gtk_widget_set_size_request(gtkconv->u.im->icon_container,
7147 -1, BUDDYICON_SIZE_MIN); 7185 -1, BUDDYICON_SIZE_MIN);
7148 return; 7186 return;
7149 } 7187 }
7150 } 7188 }
7151 7189
7152 loader = gdk_pixbuf_loader_new(); 7190 gtkconv->u.im->anim = pidgin_pixbuf_anim_from_data(data, len);
7153 gdk_pixbuf_loader_write(loader, data, len, NULL);
7154 gdk_pixbuf_loader_close(loader, &err);
7155
7156 purple_imgstore_unref(custom_img); 7191 purple_imgstore_unref(custom_img);
7157 7192
7158 anim = gdk_pixbuf_loader_get_animation(loader); 7193 if (!gtkconv->u.im->anim) {
7159 if (anim) 7194 purple_debug_error("gtkconv", "Couldn't load icon for conv %s\n",
7160 g_object_ref(G_OBJECT(anim)); 7195 purple_conversation_get_name(conv));
7161 g_object_unref(loader);
7162
7163 if (!anim)
7164 return; 7196 return;
7165 gtkconv->u.im->anim = anim;
7166
7167 if (err) {
7168 purple_debug(PURPLE_DEBUG_ERROR, "gtkconv",
7169 "Buddy icon error: %s\n", err->message);
7170 g_error_free(err);
7171 } 7197 }
7172 7198
7173 if (gdk_pixbuf_animation_is_static_image(gtkconv->u.im->anim)) { 7199 if (gdk_pixbuf_animation_is_static_image(gtkconv->u.im->anim)) {
7174 GdkPixbuf *stat; 7200 GdkPixbuf *stat;
7175 gtkconv->u.im->iter = NULL; 7201 gtkconv->u.im->iter = NULL;
8216 8242
8217 purple_signal_connect(purple_conversations_get_handle(), "received-im-msg", 8243 purple_signal_connect(purple_conversations_get_handle(), "received-im-msg",
8218 handle, G_CALLBACK(received_im_msg_cb), NULL); 8244 handle, G_CALLBACK(received_im_msg_cb), NULL);
8219 purple_signal_connect(purple_conversations_get_handle(), "cleared-message-history", 8245 purple_signal_connect(purple_conversations_get_handle(), "cleared-message-history",
8220 handle, G_CALLBACK(clear_conversation_scrollback_cb), NULL); 8246 handle, G_CALLBACK(clear_conversation_scrollback_cb), NULL);
8247
8248 purple_signal_connect(purple_conversations_get_handle(), "deleting-chat-buddy",
8249 handle, G_CALLBACK(deleting_chat_buddy_cb), NULL);
8221 8250
8222 purple_conversations_set_ui_ops(&conversation_ui_ops); 8251 purple_conversations_set_ui_ops(&conversation_ui_ops);
8223 8252
8224 hidden_convwin = pidgin_conv_window_new(); 8253 hidden_convwin = pidgin_conv_window_new();
8225 window_list = g_list_remove(window_list, hidden_convwin); 8254 window_list = g_list_remove(window_list, hidden_convwin);