| 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); |
| 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); |
| 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 |