# HG changeset patch # User Sadrul Habib Chowdhury # Date 1178673675 0 # Node ID ab45289d2c364205bc3d0192947489e44625767e # Parent 9195157482535b003cd5216f9f28ccca79e0cb89 Allow saving custom smileys by right-clicking on them. And use the custom smileys only on the received messages, not for the system/etc. messages. diff -r 919515748253 -r ab45289d2c36 pidgin/gtkconv.c --- a/pidgin/gtkconv.c Wed May 09 00:02:17 2007 +0000 +++ b/pidgin/gtkconv.c Wed May 09 01:21:15 2007 +0000 @@ -4978,6 +4978,8 @@ char *bracket; int tag_count = 0; gboolean is_rtl_message = FALSE; + GtkSmileyTree *tree = NULL; + GHashTable *smiley_data = NULL; g_return_if_fail(conv != NULL); gtkconv = PIDGIN_CONVERSATION(conv); @@ -5121,6 +5123,17 @@ gtk_font_options |= GTK_IMHTML_USE_POINTSIZE; } + if (!(flags & PURPLE_MESSAGE_RECV)) + { + /* Temporarily revert to the original smiley-data to avoid showing up + * custom smileys of the buddy when sending message + */ + tree = GTK_IMHTML(gtkconv->imhtml)->default_smilies; + GTK_IMHTML(gtkconv->imhtml)->default_smilies = + GTK_IMHTML(gtkconv->entry)->default_smilies; + smiley_data = GTK_IMHTML(gtkconv->imhtml)->smiley_data; + GTK_IMHTML(gtkconv->imhtml)->smiley_data = GTK_IMHTML(gtkconv->entry)->smiley_data; + } /* TODO: These colors should not be hardcoded so log.c can use them */ if (flags & PURPLE_MESSAGE_RAW) { @@ -5152,25 +5165,11 @@ * escaped entities making the string longer */ int tag_start_offset = alias ? (strlen(alias_escaped) - strlen(alias)) : 0; int tag_end_offset = 0; - GtkSmileyTree *tree = NULL; - GHashTable *smiley_data = NULL; /* Enforce direction on alias */ if (is_rtl_message) str_embed_direction_chars(&alias_escaped); - if (flags & PURPLE_MESSAGE_SEND) - { - /* Temporarily revert to the original smiley-data to avoid showing up - * custom smileys of the buddy when sending message - */ - tree = GTK_IMHTML(gtkconv->imhtml)->default_smilies; - GTK_IMHTML(gtkconv->imhtml)->default_smilies = - GTK_IMHTML(gtkconv->entry)->default_smilies; - smiley_data = GTK_IMHTML(gtkconv->imhtml)->smiley_data; - GTK_IMHTML(gtkconv->imhtml)->smiley_data = GTK_IMHTML(gtkconv->entry)->smiley_data; - } - if (flags & PURPLE_MESSAGE_WHISPER) { str = g_malloc(1024); @@ -5312,13 +5311,6 @@ gtk_imhtml_append_text(GTK_IMHTML(gtkconv->imhtml), with_font_tag, gtk_font_options | gtk_font_options_all); - if (flags & PURPLE_MESSAGE_SEND) - { - /* Restore the smiley-data */ - GTK_IMHTML(gtkconv->imhtml)->default_smilies = tree; - GTK_IMHTML(gtkconv->imhtml)->smiley_data = smiley_data; - } - g_free(with_font_tag); g_free(new_message); } @@ -5344,6 +5336,13 @@ gtkconv_set_unseen(gtkconv, unseen); } + if (!(flags & PURPLE_MESSAGE_RECV)) + { + /* Restore the smiley-data */ + GTK_IMHTML(gtkconv->imhtml)->default_smilies = tree; + GTK_IMHTML(gtkconv->imhtml)->smiley_data = smiley_data; + } + purple_signal_emit(pidgin_conversations_get_handle(), (type == PURPLE_CONV_TYPE_IM ? "displayed-im-msg" : "displayed-chat-msg"), account, name, displaying, conv, flags); @@ -5607,15 +5606,25 @@ icon, smiley->icon, smiley->smile); #endif if (icon) { + GList *wids; gtk_widget_show(icon); anchor = GTK_TEXT_CHILD_ANCHOR(current->data); + wids = gtk_text_child_anchor_get_widgets(anchor); g_object_set_data_full(G_OBJECT(anchor), "gtkimhtml_plaintext", purple_unescape_html(smiley->smile), g_free); g_object_set_data_full(G_OBJECT(anchor), "gtkimhtml_htmltext", g_strdup(smiley->smile), g_free); - if (smiley->imhtml) - gtk_text_view_add_child_at_anchor(GTK_TEXT_VIEW(smiley->imhtml), icon, anchor); + if (smiley->imhtml) { + if (wids) { + GList *children = gtk_container_get_children(GTK_CONTAINER(wids->data)); + g_list_foreach(children, (GFunc)gtk_widget_destroy, NULL); + g_list_free(children); + gtk_container_add(GTK_CONTAINER(wids->data), icon); + } else + gtk_text_view_add_child_at_anchor(GTK_TEXT_VIEW(smiley->imhtml), icon, anchor); + } + g_list_free(wids); } } diff -r 919515748253 -r ab45289d2c36 pidgin/gtkimhtml.c --- a/pidgin/gtkimhtml.c Wed May 09 00:02:17 2007 +0000 +++ b/pidgin/gtkimhtml.c Wed May 09 01:21:15 2007 +0000 @@ -1872,18 +1872,8 @@ } static GdkPixbufAnimation * -gtk_smiley_tree_image (GtkIMHtml *imhtml, - const gchar *sml, - const gchar *text) +gtk_smiley_get_image(GtkIMHtmlSmiley *smiley) { - - GtkIMHtmlSmiley *smiley; - - smiley = gtk_imhtml_smiley_get(imhtml,sml,text); - - if (!smiley) - return NULL; - if (!smiley->icon && smiley->file) { smiley->icon = gdk_pixbuf_animation_new_from_file(smiley->file, NULL); } else if (!smiley->icon && smiley->loader) { @@ -1895,6 +1885,21 @@ return smiley->icon; } +static GdkPixbufAnimation * +gtk_smiley_tree_image (GtkIMHtml *imhtml, + const gchar *sml, + const gchar *text) +{ + GtkIMHtmlSmiley *smiley; + + smiley = gtk_imhtml_smiley_get(imhtml,sml,text); + + if (!smiley) + return NULL; + + return gtk_smiley_get_image(smiley); +} + #define VALID_TAG(x) if (!g_ascii_strncasecmp (string, x ">", strlen (x ">"))) { \ *tag = g_strndup (string, strlen (x)); \ *len = strlen (x) + 1; \ @@ -3363,6 +3368,29 @@ return FALSE; /* Let clicks go through if we didn't catch anything */ } + +static gboolean gtk_imhtml_smiley_clicked(GtkWidget *w, GdkEvent *event, GtkIMHtmlSmiley *smiley) +{ + GdkPixbufAnimation *anim = NULL; + GdkPixbuf *pix = NULL; + GtkIMHtmlScalable *image = NULL; + gboolean ret; + + if (event->type != GDK_BUTTON_RELEASE || ((GdkEventButton*)event)->button != 3) + return FALSE; + + anim = gtk_smiley_get_image(smiley); + if (!anim) + return FALSE; + + pix = gdk_pixbuf_animation_get_static_image(anim); + image = gtk_imhtml_image_new(pix, NULL, 0); + ret = gtk_imhtml_image_clicked(w, event, (GtkIMHtmlImage*)image); + g_object_set_data_full(G_OBJECT(w), "image-data", image, (GDestroyNotify)gtk_imhtml_image_free); + g_object_unref(G_OBJECT(pix)); + return ret; +} + void gtk_imhtml_image_free(GtkIMHtmlScalable *scale) { GtkIMHtmlImage *image = (GtkIMHtmlImage *)scale; @@ -4378,9 +4406,10 @@ GdkPixbuf *pixbuf = NULL; GdkPixbufAnimation *annipixbuf = NULL; GtkWidget *icon = NULL; - GtkTextChildAnchor *anchor; + GtkTextChildAnchor *anchor = NULL; char *unescaped = purple_unescape_html(smiley); GtkIMHtmlSmiley *imhtml_smiley = gtk_imhtml_smiley_get(imhtml, sml, unescaped); + GtkWidget *ebox = NULL; if (imhtml->format_functions & GTK_IMHTML_SMILEY) { annipixbuf = gtk_smiley_tree_image(imhtml, sml, unescaped); @@ -4397,6 +4426,7 @@ if (anim) { GdkPixbuf *pb = gdk_pixbuf_animation_get_static_image(anim); gtk_image_set_from_pixbuf(image, pb); + g_object_unref(G_OBJECT(pb)); } } else { imhtml->num_animations++; @@ -4407,6 +4437,12 @@ } } + if (imhtml_smiley->flags & GTK_IMHTML_SMILEY_CUSTOM) { + ebox = gtk_event_box_new(); + gtk_event_box_set_visible_window(GTK_EVENT_BOX(ebox), FALSE); + gtk_widget_show(ebox); + } + if (icon) { anchor = gtk_text_buffer_create_child_anchor(imhtml->text_buffer, iter); g_object_set_data_full(G_OBJECT(anchor), "gtkimhtml_plaintext", g_strdup(unescaped), g_free); @@ -4419,14 +4455,26 @@ g_signal_connect(G_OBJECT(icon), "expose-event", G_CALLBACK(image_expose), NULL); gtk_widget_show(icon); - gtk_text_view_add_child_at_anchor(GTK_TEXT_VIEW(imhtml), icon, anchor); + if (ebox) + gtk_container_add(GTK_CONTAINER(ebox), icon); + gtk_text_view_add_child_at_anchor(GTK_TEXT_VIEW(imhtml), ebox ? ebox : icon, anchor); } else if (imhtml_smiley != NULL && (imhtml->format_functions & GTK_IMHTML_SMILEY)) { anchor = gtk_text_buffer_create_child_anchor(imhtml->text_buffer, iter); imhtml_smiley->anchors = g_slist_append(imhtml_smiley->anchors, anchor); + if (ebox) { + GtkWidget *img = gtk_image_new_from_stock(GTK_STOCK_MISSING_IMAGE, GTK_ICON_SIZE_MENU); + gtk_container_add(GTK_CONTAINER(ebox), img); + gtk_widget_show(img); + gtk_text_view_add_child_at_anchor(GTK_TEXT_VIEW(imhtml), ebox, anchor); + } } else { gtk_text_buffer_insert(imhtml->text_buffer, iter, smiley, -1); } + if (ebox) { + g_signal_connect(G_OBJECT(ebox), "event", G_CALLBACK(gtk_imhtml_smiley_clicked), imhtml_smiley); + } + g_free(unescaped); }