pidgin/gtkconv.c

branch
custom_smiley
changeset 22656
c4c7c4852390
parent 22625
2d5dd1f0a050
parent 22655
718f1149a81c
child 22737
3535c4e90c39
equal deleted inserted replaced
22628:b25a7bbe7272 22656:c4c7c4852390
155 static void gtkconv_set_unseen(PidginConversation *gtkconv, PidginUnseenState state); 155 static void gtkconv_set_unseen(PidginConversation *gtkconv, PidginUnseenState state);
156 static void update_typing_icon(PidginConversation *gtkconv); 156 static void update_typing_icon(PidginConversation *gtkconv);
157 static void update_typing_message(PidginConversation *gtkconv, const char *message); 157 static void update_typing_message(PidginConversation *gtkconv, const char *message);
158 static const char *item_factory_translate_func (const char *path, gpointer func_data); 158 static const char *item_factory_translate_func (const char *path, gpointer func_data);
159 gboolean pidgin_conv_has_focus(PurpleConversation *conv); 159 gboolean pidgin_conv_has_focus(PurpleConversation *conv);
160 static void pidgin_conv_custom_smiley_allocated(GdkPixbufLoader *loader, gpointer user_data);
161 static void pidgin_conv_custom_smiley_closed(GdkPixbufLoader *loader, gpointer user_data);
162 static GdkColor* generate_nick_colors(guint *numcolors, GdkColor background); 160 static GdkColor* generate_nick_colors(guint *numcolors, GdkColor background);
163 static gboolean color_is_visible(GdkColor foreground, GdkColor background, int color_contrast, int brightness_contrast); 161 static gboolean color_is_visible(GdkColor foreground, GdkColor background, int color_contrast, int brightness_contrast);
164 static void pidgin_conv_update_fields(PurpleConversation *conv, PidginConvFields fields); 162 static void pidgin_conv_update_fields(PurpleConversation *conv, PidginConvFields fields);
165 static void focus_out_from_menubar(GtkWidget *wid, PidginWindow *win); 163 static void focus_out_from_menubar(GtkWidget *wid, PidginWindow *win);
166 static void pidgin_conv_tab_pack(PidginWindow *win, PidginConversation *gtkconv); 164 static void pidgin_conv_tab_pack(PidginWindow *win, PidginConversation *gtkconv);
5031 5029
5032 if (nick_colors == NULL) { 5030 if (nick_colors == NULL) {
5033 nbr_nick_colors = NUM_NICK_COLORS; 5031 nbr_nick_colors = NUM_NICK_COLORS;
5034 nick_colors = generate_nick_colors(&nbr_nick_colors, gtk_widget_get_style(gtkconv->imhtml)->base[GTK_STATE_NORMAL]); 5032 nick_colors = generate_nick_colors(&nbr_nick_colors, gtk_widget_get_style(gtkconv->imhtml)->base[GTK_STATE_NORMAL]);
5035 } 5033 }
5034
5035 /* We don't want to see the custom smileys if our buddy send us the
5036 * defined shortcut. */
5037 pidgin_themes_smiley_themeize(gtkconv->imhtml);
5038 /* We want to see our smileys in the entry */
5039 pidgin_themes_smiley_themeize_custom(gtkconv->entry);
5036 } 5040 }
5037 5041
5038 static void 5042 static void
5039 pidgin_conv_new_hidden(PurpleConversation *conv) 5043 pidgin_conv_new_hidden(PurpleConversation *conv)
5040 { 5044 {
5337 char *displaying; 5341 char *displaying;
5338 gboolean plugin_return; 5342 gboolean plugin_return;
5339 char *bracket; 5343 char *bracket;
5340 int tag_count = 0; 5344 int tag_count = 0;
5341 gboolean is_rtl_message = FALSE; 5345 gboolean is_rtl_message = FALSE;
5342 GtkSmileyTree *tree = NULL;
5343 GHashTable *smiley_data = NULL;
5344 5346
5345 g_return_if_fail(conv != NULL); 5347 g_return_if_fail(conv != NULL);
5346 gtkconv = PIDGIN_CONVERSATION(conv); 5348 gtkconv = PIDGIN_CONVERSATION(conv);
5347 g_return_if_fail(gtkconv != NULL); 5349 g_return_if_fail(gtkconv != NULL);
5348 5350
5497 gtk_font_options |= GTK_IMHTML_USE_POINTSIZE; 5499 gtk_font_options |= GTK_IMHTML_USE_POINTSIZE;
5498 } 5500 }
5499 5501
5500 if (!(flags & PURPLE_MESSAGE_RECV)) 5502 if (!(flags & PURPLE_MESSAGE_RECV))
5501 { 5503 {
5502 /* Temporarily revert to the original smiley-data to avoid showing up 5504 /* We want to see our own smileys. Need to revert it after send*/
5503 * custom smileys of the buddy when sending message 5505 pidgin_themes_smiley_themeize_custom(gtkconv->imhtml);
5504 */
5505 tree = GTK_IMHTML(gtkconv->imhtml)->default_smilies;
5506 GTK_IMHTML(gtkconv->imhtml)->default_smilies =
5507 GTK_IMHTML(gtkconv->entry)->default_smilies;
5508 smiley_data = GTK_IMHTML(gtkconv->imhtml)->smiley_data;
5509 GTK_IMHTML(gtkconv->imhtml)->smiley_data = GTK_IMHTML(gtkconv->entry)->smiley_data;
5510 } 5506 }
5511 5507
5512 /* TODO: These colors should not be hardcoded so log.c can use them */ 5508 /* TODO: These colors should not be hardcoded so log.c can use them */
5513 if (flags & PURPLE_MESSAGE_RAW) { 5509 if (flags & PURPLE_MESSAGE_RAW) {
5514 gtk_imhtml_append_text(GTK_IMHTML(gtkconv->imhtml), message, gtk_font_options_all); 5510 gtk_imhtml_append_text(GTK_IMHTML(gtkconv->imhtml), message, gtk_font_options_all);
5750 } 5746 }
5751 5747
5752 if (!(flags & PURPLE_MESSAGE_RECV)) 5748 if (!(flags & PURPLE_MESSAGE_RECV))
5753 { 5749 {
5754 /* Restore the smiley-data */ 5750 /* Restore the smiley-data */
5755 GTK_IMHTML(gtkconv->imhtml)->default_smilies = tree; 5751 pidgin_themes_smiley_themeize(gtkconv->imhtml);
5756 GTK_IMHTML(gtkconv->imhtml)->smiley_data = smiley_data;
5757 } 5752 }
5758 5753
5759 purple_signal_emit(pidgin_conversations_get_handle(), 5754 purple_signal_emit(pidgin_conversations_get_handle(),
5760 (type == PURPLE_CONV_TYPE_IM ? "displayed-im-msg" : "displayed-chat-msg"), 5755 (type == PURPLE_CONV_TYPE_IM ? "displayed-im-msg" : "displayed-chat-msg"),
5761 account, name, displaying, conv, flags); 5756 account, name, displaying, conv, flags);
5979 return TRUE; 5974 return TRUE;
5980 5975
5981 return FALSE; 5976 return FALSE;
5982 } 5977 }
5983 5978
5984 static void pidgin_conv_custom_smiley_allocated(GdkPixbufLoader *loader, gpointer user_data)
5985 {
5986 GtkIMHtmlSmiley *smiley;
5987
5988 smiley = (GtkIMHtmlSmiley *)user_data;
5989 smiley->icon = gdk_pixbuf_loader_get_animation(loader);
5990
5991 if (smiley->icon)
5992 g_object_ref(G_OBJECT(smiley->icon));
5993 #ifdef DEBUG_CUSTOM_SMILEY
5994 purple_debug_info("custom-smiley", "pidgin_conv_custom_smiley_allocated(): got GdkPixbufAnimation %p for smiley '%s'\n", smiley->icon, smiley->smile);
5995 #endif
5996 }
5997
5998 static void pidgin_conv_custom_smiley_closed(GdkPixbufLoader *loader, gpointer user_data)
5999 {
6000 GtkIMHtmlSmiley *smiley;
6001 GtkWidget *icon = NULL;
6002 GtkTextChildAnchor *anchor = NULL;
6003 GSList *current = NULL;
6004
6005 smiley = (GtkIMHtmlSmiley *)user_data;
6006 if (!smiley->imhtml) {
6007 #ifdef DEBUG_CUSTOM_SMILEY
6008 purple_debug_error("custom-smiley", "pidgin_conv_custom_smiley_closed(): orphan smiley found: %p\n", smiley);
6009 #endif
6010 g_object_unref(G_OBJECT(loader));
6011 smiley->loader = NULL;
6012 return;
6013 }
6014
6015 for (current = smiley->anchors; current; current = g_slist_next(current)) {
6016
6017 icon = gtk_image_new_from_animation(smiley->icon);
6018
6019 #ifdef DEBUG_CUSTOM_SMILEY
6020 purple_debug_info("custom-smiley", "pidgin_conv_custom_smiley_closed(): got GtkImage %p from GtkPixbufAnimation %p for smiley '%s'\n",
6021 icon, smiley->icon, smiley->smile);
6022 #endif
6023 if (icon) {
6024 GList *wids;
6025 gtk_widget_show(icon);
6026
6027 anchor = GTK_TEXT_CHILD_ANCHOR(current->data);
6028 wids = gtk_text_child_anchor_get_widgets(anchor);
6029
6030 g_object_set_data_full(G_OBJECT(anchor), "gtkimhtml_plaintext", purple_unescape_html(smiley->smile), g_free);
6031 g_object_set_data_full(G_OBJECT(anchor), "gtkimhtml_htmltext", g_strdup(smiley->smile), g_free);
6032
6033 if (smiley->imhtml) {
6034 if (wids) {
6035 GList *children = gtk_container_get_children(GTK_CONTAINER(wids->data));
6036 g_list_foreach(children, (GFunc)gtk_widget_destroy, NULL);
6037 g_list_free(children);
6038 gtk_container_add(GTK_CONTAINER(wids->data), icon);
6039 } else
6040 gtk_text_view_add_child_at_anchor(GTK_TEXT_VIEW(smiley->imhtml), icon, anchor);
6041 }
6042 g_list_free(wids);
6043 }
6044
6045 }
6046
6047 g_slist_free(smiley->anchors);
6048 smiley->anchors = NULL;
6049
6050 g_object_unref(G_OBJECT(loader));
6051 smiley->loader = NULL;
6052 }
6053
6054 static gboolean 5979 static gboolean
6055 add_custom_smiley_for_imhtml(GtkIMHtml *imhtml, const char *sml, const char *smile) 5980 add_custom_smiley_for_imhtml(GtkIMHtml *imhtml, const char *sml, const char *smile)
6056 { 5981 {
6057 GtkIMHtmlSmiley *smiley; 5982 GtkIMHtmlSmiley *smiley;
6058 GdkPixbufLoader *loader;
6059 5983
6060 smiley = gtk_imhtml_smiley_get(imhtml, sml, smile); 5984 smiley = gtk_imhtml_smiley_get(imhtml, sml, smile);
6061 5985
6062 if (smiley) { 5986 if (smiley) {
6063
6064 if (!(smiley->flags & GTK_IMHTML_SMILEY_CUSTOM)) { 5987 if (!(smiley->flags & GTK_IMHTML_SMILEY_CUSTOM)) {
6065 return FALSE; 5988 return FALSE;
6066 } 5989 }
6067 5990 gtk_imhtml_smiley_reload(smiley);
6068 /* Close the old GdkPixbufAnimation, then create a new one for
6069 * the smiley we are about to receive */
6070 g_object_unref(G_OBJECT(smiley->icon));
6071
6072 /* XXX: Is it necessary to _unref the loader first? */
6073 smiley->loader = gdk_pixbuf_loader_new();
6074 smiley->icon = NULL;
6075
6076 g_signal_connect(smiley->loader, "area_prepared", G_CALLBACK(pidgin_conv_custom_smiley_allocated), smiley);
6077 g_signal_connect(smiley->loader, "closed", G_CALLBACK(pidgin_conv_custom_smiley_closed), smiley);
6078
6079 return TRUE; 5991 return TRUE;
6080 } 5992 }
6081 5993
6082 loader = gdk_pixbuf_loader_new(); 5994 smiley = gtk_imhtml_smiley_create(NULL, smile, FALSE, GTK_IMHTML_SMILEY_CUSTOM);
6083
6084 /* this is wrong, this file ought not call g_new on GtkIMHtmlSmiley */
6085 /* Let gtk_imhtml have a gtk_imhtml_smiley_new function, and let
6086 GtkIMHtmlSmiley by opaque */
6087 smiley = g_new0(GtkIMHtmlSmiley, 1);
6088 smiley->file = NULL;
6089 smiley->smile = g_strdup(smile);
6090 smiley->loader = loader;
6091 smiley->flags = smiley->flags | GTK_IMHTML_SMILEY_CUSTOM;
6092
6093 g_signal_connect(smiley->loader, "area_prepared", G_CALLBACK(pidgin_conv_custom_smiley_allocated), smiley);
6094 g_signal_connect(smiley->loader, "closed", G_CALLBACK(pidgin_conv_custom_smiley_closed), smiley);
6095
6096 gtk_imhtml_associate_smiley(imhtml, sml, smiley); 5995 gtk_imhtml_associate_smiley(imhtml, sml, smiley);
5996 g_signal_connect_swapped(imhtml, "destroy", G_CALLBACK(gtk_imhtml_smiley_destroy), smiley);
6097 5997
6098 return TRUE; 5998 return TRUE;
6099 } 5999 }
6100 6000
6101 static gboolean 6001 static gboolean

mercurial