pidgin/gtkconv.c

branch
next.minor
changeset 23289
91b0e34f4a88
parent 23036
5b415c84861f
parent 23010
6230fac29cee
child 23298
668308bb9175
equal deleted inserted replaced
23281:0f8e81fcea75 23289:91b0e34f4a88
157 static void gtkconv_set_unseen(PidginConversation *gtkconv, PidginUnseenState state); 157 static void gtkconv_set_unseen(PidginConversation *gtkconv, PidginUnseenState state);
158 static void update_typing_icon(PidginConversation *gtkconv); 158 static void update_typing_icon(PidginConversation *gtkconv);
159 static void update_typing_message(PidginConversation *gtkconv, const char *message); 159 static void update_typing_message(PidginConversation *gtkconv, const char *message);
160 static const char *item_factory_translate_func (const char *path, gpointer func_data); 160 static const char *item_factory_translate_func (const char *path, gpointer func_data);
161 gboolean pidgin_conv_has_focus(PurpleConversation *conv); 161 gboolean pidgin_conv_has_focus(PurpleConversation *conv);
162 static void pidgin_conv_custom_smiley_allocated(GdkPixbufLoader *loader, gpointer user_data);
163 static void pidgin_conv_custom_smiley_closed(GdkPixbufLoader *loader, gpointer user_data);
164 static GdkColor* generate_nick_colors(guint *numcolors, GdkColor background); 162 static GdkColor* generate_nick_colors(guint *numcolors, GdkColor background);
165 static gboolean color_is_visible(GdkColor foreground, GdkColor background, int color_contrast, int brightness_contrast); 163 static gboolean color_is_visible(GdkColor foreground, GdkColor background, int color_contrast, int brightness_contrast);
166 static void pidgin_conv_update_fields(PurpleConversation *conv, PidginConvFields fields); 164 static void pidgin_conv_update_fields(PurpleConversation *conv, PidginConvFields fields);
167 static void focus_out_from_menubar(GtkWidget *wid, PidginWindow *win); 165 static void focus_out_from_menubar(GtkWidget *wid, PidginWindow *win);
168 static void pidgin_conv_tab_pack(PidginWindow *win, PidginConversation *gtkconv); 166 static void pidgin_conv_tab_pack(PidginWindow *win, PidginConversation *gtkconv);
5178 5176
5179 if (nick_colors == NULL) { 5177 if (nick_colors == NULL) {
5180 nbr_nick_colors = NUM_NICK_COLORS; 5178 nbr_nick_colors = NUM_NICK_COLORS;
5181 nick_colors = generate_nick_colors(&nbr_nick_colors, gtk_widget_get_style(gtkconv->imhtml)->base[GTK_STATE_NORMAL]); 5179 nick_colors = generate_nick_colors(&nbr_nick_colors, gtk_widget_get_style(gtkconv->imhtml)->base[GTK_STATE_NORMAL]);
5182 } 5180 }
5181
5182 /* We don't want to see the custom smileys if our buddy send us the
5183 * defined shortcut. */
5184 pidgin_themes_smiley_themeize(gtkconv->imhtml);
5185 /* We want to see our smileys in the entry */
5186 pidgin_themes_smiley_themeize_custom(gtkconv->entry);
5183 } 5187 }
5184 5188
5185 static void 5189 static void
5186 pidgin_conv_new_hidden(PurpleConversation *conv) 5190 pidgin_conv_new_hidden(PurpleConversation *conv)
5187 { 5191 {
5484 char *displaying; 5488 char *displaying;
5485 gboolean plugin_return; 5489 gboolean plugin_return;
5486 char *bracket; 5490 char *bracket;
5487 int tag_count = 0; 5491 int tag_count = 0;
5488 gboolean is_rtl_message = FALSE; 5492 gboolean is_rtl_message = FALSE;
5489 GtkSmileyTree *tree = NULL;
5490 GHashTable *smiley_data = NULL;
5491 5493
5492 g_return_if_fail(conv != NULL); 5494 g_return_if_fail(conv != NULL);
5493 gtkconv = PIDGIN_CONVERSATION(conv); 5495 gtkconv = PIDGIN_CONVERSATION(conv);
5494 g_return_if_fail(gtkconv != NULL); 5496 g_return_if_fail(gtkconv != NULL);
5495 5497
5644 gtk_font_options |= GTK_IMHTML_USE_POINTSIZE; 5646 gtk_font_options |= GTK_IMHTML_USE_POINTSIZE;
5645 } 5647 }
5646 5648
5647 if (!(flags & PURPLE_MESSAGE_RECV)) 5649 if (!(flags & PURPLE_MESSAGE_RECV))
5648 { 5650 {
5649 /* Temporarily revert to the original smiley-data to avoid showing up 5651 /* We want to see our own smileys. Need to revert it after send*/
5650 * custom smileys of the buddy when sending message 5652 pidgin_themes_smiley_themeize_custom(gtkconv->imhtml);
5651 */
5652 tree = GTK_IMHTML(gtkconv->imhtml)->default_smilies;
5653 GTK_IMHTML(gtkconv->imhtml)->default_smilies =
5654 GTK_IMHTML(gtkconv->entry)->default_smilies;
5655 smiley_data = GTK_IMHTML(gtkconv->imhtml)->smiley_data;
5656 GTK_IMHTML(gtkconv->imhtml)->smiley_data = GTK_IMHTML(gtkconv->entry)->smiley_data;
5657 } 5653 }
5658 5654
5659 /* TODO: These colors should not be hardcoded so log.c can use them */ 5655 /* TODO: These colors should not be hardcoded so log.c can use them */
5660 if (flags & PURPLE_MESSAGE_RAW) { 5656 if (flags & PURPLE_MESSAGE_RAW) {
5661 gtk_imhtml_append_text(GTK_IMHTML(gtkconv->imhtml), message, gtk_font_options_all); 5657 gtk_imhtml_append_text(GTK_IMHTML(gtkconv->imhtml), message, gtk_font_options_all);
5897 } 5893 }
5898 5894
5899 if (!(flags & PURPLE_MESSAGE_RECV)) 5895 if (!(flags & PURPLE_MESSAGE_RECV))
5900 { 5896 {
5901 /* Restore the smiley-data */ 5897 /* Restore the smiley-data */
5902 GTK_IMHTML(gtkconv->imhtml)->default_smilies = tree; 5898 pidgin_themes_smiley_themeize(gtkconv->imhtml);
5903 GTK_IMHTML(gtkconv->imhtml)->smiley_data = smiley_data;
5904 } 5899 }
5905 5900
5906 purple_signal_emit(pidgin_conversations_get_handle(), 5901 purple_signal_emit(pidgin_conversations_get_handle(),
5907 (type == PURPLE_CONV_TYPE_IM ? "displayed-im-msg" : "displayed-chat-msg"), 5902 (type == PURPLE_CONV_TYPE_IM ? "displayed-im-msg" : "displayed-chat-msg"),
5908 account, name, displaying, conv, flags); 5903 account, name, displaying, conv, flags);
6126 return TRUE; 6121 return TRUE;
6127 6122
6128 return FALSE; 6123 return FALSE;
6129 } 6124 }
6130 6125
6131 static void pidgin_conv_custom_smiley_allocated(GdkPixbufLoader *loader, gpointer user_data)
6132 {
6133 GtkIMHtmlSmiley *smiley;
6134
6135 smiley = (GtkIMHtmlSmiley *)user_data;
6136 smiley->icon = gdk_pixbuf_loader_get_animation(loader);
6137
6138 if (smiley->icon)
6139 g_object_ref(G_OBJECT(smiley->icon));
6140 #ifdef DEBUG_CUSTOM_SMILEY
6141 purple_debug_info("custom-smiley", "pidgin_conv_custom_smiley_allocated(): got GdkPixbufAnimation %p for smiley '%s'\n", smiley->icon, smiley->smile);
6142 #endif
6143 }
6144
6145 static void pidgin_conv_custom_smiley_closed(GdkPixbufLoader *loader, gpointer user_data)
6146 {
6147 GtkIMHtmlSmiley *smiley;
6148 GtkWidget *icon = NULL;
6149 GtkTextChildAnchor *anchor = NULL;
6150 GSList *current = NULL;
6151
6152 smiley = (GtkIMHtmlSmiley *)user_data;
6153 if (!smiley->imhtml) {
6154 #ifdef DEBUG_CUSTOM_SMILEY
6155 purple_debug_error("custom-smiley", "pidgin_conv_custom_smiley_closed(): orphan smiley found: %p\n", smiley);
6156 #endif
6157 g_object_unref(G_OBJECT(loader));
6158 smiley->loader = NULL;
6159 return;
6160 }
6161
6162 for (current = smiley->anchors; current; current = g_slist_next(current)) {
6163
6164 icon = gtk_image_new_from_animation(smiley->icon);
6165
6166 #ifdef DEBUG_CUSTOM_SMILEY
6167 purple_debug_info("custom-smiley", "pidgin_conv_custom_smiley_closed(): got GtkImage %p from GtkPixbufAnimation %p for smiley '%s'\n",
6168 icon, smiley->icon, smiley->smile);
6169 #endif
6170 if (icon) {
6171 GList *wids;
6172 gtk_widget_show(icon);
6173
6174 anchor = GTK_TEXT_CHILD_ANCHOR(current->data);
6175 wids = gtk_text_child_anchor_get_widgets(anchor);
6176
6177 g_object_set_data_full(G_OBJECT(anchor), "gtkimhtml_plaintext", purple_unescape_html(smiley->smile), g_free);
6178 g_object_set_data_full(G_OBJECT(anchor), "gtkimhtml_htmltext", g_strdup(smiley->smile), g_free);
6179
6180 if (smiley->imhtml) {
6181 if (wids) {
6182 GList *children = gtk_container_get_children(GTK_CONTAINER(wids->data));
6183 g_list_foreach(children, (GFunc)gtk_widget_destroy, NULL);
6184 g_list_free(children);
6185 gtk_container_add(GTK_CONTAINER(wids->data), icon);
6186 } else
6187 gtk_text_view_add_child_at_anchor(GTK_TEXT_VIEW(smiley->imhtml), icon, anchor);
6188 }
6189 g_list_free(wids);
6190 }
6191
6192 }
6193
6194 g_slist_free(smiley->anchors);
6195 smiley->anchors = NULL;
6196
6197 g_object_unref(G_OBJECT(loader));
6198 smiley->loader = NULL;
6199 }
6200
6201 static gboolean 6126 static gboolean
6202 add_custom_smiley_for_imhtml(GtkIMHtml *imhtml, const char *sml, const char *smile) 6127 add_custom_smiley_for_imhtml(GtkIMHtml *imhtml, const char *sml, const char *smile)
6203 { 6128 {
6204 GtkIMHtmlSmiley *smiley; 6129 GtkIMHtmlSmiley *smiley;
6205 GdkPixbufLoader *loader;
6206 6130
6207 smiley = gtk_imhtml_smiley_get(imhtml, sml, smile); 6131 smiley = gtk_imhtml_smiley_get(imhtml, sml, smile);
6208 6132
6209 if (smiley) { 6133 if (smiley) {
6210
6211 if (!(smiley->flags & GTK_IMHTML_SMILEY_CUSTOM)) { 6134 if (!(smiley->flags & GTK_IMHTML_SMILEY_CUSTOM)) {
6212 return FALSE; 6135 return FALSE;
6213 } 6136 }
6214 6137 gtk_imhtml_smiley_reload(smiley);
6215 /* Close the old GdkPixbufAnimation, then create a new one for
6216 * the smiley we are about to receive */
6217 g_object_unref(G_OBJECT(smiley->icon));
6218
6219 /* XXX: Is it necessary to _unref the loader first? */
6220 smiley->loader = gdk_pixbuf_loader_new();
6221 smiley->icon = NULL;
6222
6223 g_signal_connect(smiley->loader, "area_prepared", G_CALLBACK(pidgin_conv_custom_smiley_allocated), smiley);
6224 g_signal_connect(smiley->loader, "closed", G_CALLBACK(pidgin_conv_custom_smiley_closed), smiley);
6225
6226 return TRUE; 6138 return TRUE;
6227 } 6139 }
6228 6140
6229 loader = gdk_pixbuf_loader_new(); 6141 smiley = gtk_imhtml_smiley_create(NULL, smile, FALSE, GTK_IMHTML_SMILEY_CUSTOM);
6230
6231 /* this is wrong, this file ought not call g_new on GtkIMHtmlSmiley */
6232 /* Let gtk_imhtml have a gtk_imhtml_smiley_new function, and let
6233 GtkIMHtmlSmiley by opaque */
6234 smiley = g_new0(GtkIMHtmlSmiley, 1);
6235 smiley->file = NULL;
6236 smiley->smile = g_strdup(smile);
6237 smiley->loader = loader;
6238 smiley->flags = smiley->flags | GTK_IMHTML_SMILEY_CUSTOM;
6239
6240 g_signal_connect(smiley->loader, "area_prepared", G_CALLBACK(pidgin_conv_custom_smiley_allocated), smiley);
6241 g_signal_connect(smiley->loader, "closed", G_CALLBACK(pidgin_conv_custom_smiley_closed), smiley);
6242
6243 gtk_imhtml_associate_smiley(imhtml, sml, smiley); 6142 gtk_imhtml_associate_smiley(imhtml, sml, smiley);
6143 g_signal_connect_swapped(imhtml, "destroy", G_CALLBACK(gtk_imhtml_smiley_destroy), smiley);
6244 6144
6245 return TRUE; 6145 return TRUE;
6246 } 6146 }
6247 6147
6248 static gboolean 6148 static gboolean
6462 if (!(prpl_info->options & OPT_PROTO_IM_IMAGE)) 6362 if (!(prpl_info->options & OPT_PROTO_IM_IMAGE))
6463 conv->features |= PURPLE_CONNECTION_NO_IMAGES; 6363 conv->features |= PURPLE_CONNECTION_NO_IMAGES;
6464 6364
6465 if(conv->features & PURPLE_CONNECTION_NO_IMAGES) 6365 if(conv->features & PURPLE_CONNECTION_NO_IMAGES)
6466 buttons &= ~GTK_IMHTML_IMAGE; 6366 buttons &= ~GTK_IMHTML_IMAGE;
6367
6368 if (conv->features & PURPLE_CONNECTION_ALLOW_CUSTOM_SMILEY)
6369 buttons |= GTK_IMHTML_CUSTOM_SMILEY;
6370 else
6371 buttons &= ~GTK_IMHTML_CUSTOM_SMILEY;
6467 6372
6468 gtk_imhtml_set_format_functions(GTK_IMHTML(gtkconv->entry), buttons); 6373 gtk_imhtml_set_format_functions(GTK_IMHTML(gtkconv->entry), buttons);
6469 if (account != NULL) 6374 if (account != NULL)
6470 gtk_imhtmltoolbar_associate_smileys(GTK_IMHTMLTOOLBAR(gtkconv->toolbar), purple_account_get_protocol_id(account)); 6375 gtk_imhtmltoolbar_associate_smileys(GTK_IMHTMLTOOLBAR(gtkconv->toolbar), purple_account_get_protocol_id(account));
6471 6376

mercurial