Mercurial > pidgin.yaz
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); |