# HG changeset patch # User Sadrul Habib Chowdhury # Date 1210478675 0 # Node ID 53b3c75c9e260d0c1b641568386cae717cd6b224 # Parent 3f39147884ce2863e4f1d6188d1e24fe114944ad Separate the custom smileys from the regular smileys, and add a 'Manage' button in the smiley dialog for the custom smileys. This should make it more obvious that custom smileys are supported (do we actually want it to be? ;) ) diff -r 3f39147884ce -r 53b3c75c9e26 libpurple/smiley.c --- a/libpurple/smiley.c Sat May 10 17:05:25 2008 +0000 +++ b/libpurple/smiley.c Sun May 11 04:04:35 2008 +0000 @@ -300,6 +300,7 @@ }; static guint signals[SIG_LAST]; +static GObjectClass *parent_class; static void purple_smiley_init(GTypeInstance *instance, gpointer klass) @@ -366,7 +367,6 @@ purple_smiley_finalize(GObject *obj) { PurpleSmiley *smiley = PURPLE_SMILEY(obj); - g_signal_emit(obj, signals[SIG_DESTROY], 0); if (g_hash_table_lookup(smiley_shortcut_index, smiley->shortcut)) { g_hash_table_remove(smiley_shortcut_index, smiley->shortcut); @@ -383,14 +383,24 @@ } static void +purple_smiley_dispose(GObject *gobj) +{ + g_signal_emit(gobj, signals[SIG_DESTROY], 0); + parent_class->dispose(gobj); +} + +static void purple_smiley_class_init(PurpleSmileyClass *klass) { GObjectClass *gobj_class = G_OBJECT_CLASS(klass); GParamSpec *pspec; + parent_class = g_type_class_peek_parent(klass); + gobj_class->get_property = purple_smiley_get_property; gobj_class->set_property = purple_smiley_set_property; gobj_class->finalize = purple_smiley_finalize; + gobj_class->dispose = purple_smiley_dispose; /* Shortcut */ pspec = g_param_spec_string(PROP_SHORTCUT_S, _("Shortcut"), diff -r 3f39147884ce -r 53b3c75c9e26 pidgin/gtkimhtmltoolbar.c --- a/pidgin/gtkimhtmltoolbar.c Sat May 10 17:05:25 2008 +0000 +++ b/pidgin/gtkimhtmltoolbar.c Sun May 11 04:04:35 2008 +0000 @@ -580,8 +580,7 @@ } static gboolean -close_smiley_dialog(GtkWidget *widget, GdkEvent *event, - GtkIMHtmlToolbar *toolbar) +close_smiley_dialog(GtkIMHtmlToolbar *toolbar) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(toolbar->smiley), FALSE); return FALSE; @@ -602,13 +601,14 @@ g_free(escaped_smiley); - close_smiley_dialog(NULL, NULL, toolbar); + close_smiley_dialog(toolbar); } /* smiley buttons list */ struct smiley_button_list { int width, height; GtkWidget *button; + const GtkIMHtmlSmiley *smiley; struct smiley_button_list *next; }; @@ -624,6 +624,7 @@ struct smiley_button_list *it, *it_last; const gchar *filename = smiley->file; gchar *face = smiley->smile; + PurpleSmiley *psmiley = NULL; cur = g_new0(struct smiley_button_list, 1); it = ls; @@ -673,31 +674,26 @@ /* these look really weird with borders */ gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE); + psmiley = purple_smileys_find_by_shortcut(smiley->smile); /* If this is a "non-custom" smiley, check to see if its shortcut is "shadowed" by any custom smiley. This can only happen if the connection is custom smiley-enabled */ - if (!(smiley->flags & GTK_IMHTML_SMILEY_CUSTOM)) { - /* Perhaps using purple_smileys_find_by_shortcut can be used instead? -- sadrul */ - for (; custom_smileys ; custom_smileys = g_slist_next(custom_smileys)) { - const GtkIMHtmlSmiley *custom_smiley = (GtkIMHtmlSmiley *) custom_smileys->data; - const gchar *shortcut = custom_smiley->smile; - - if (strcmp(face, shortcut) == 0) { - /* The smiley of the current button has the same shortcut as - this custom smiley, grey it out */ - gtk_tooltips_set_tip(toolbar->tooltips, button, - _("This smiley is disabled because a custom smiley exists for this shortcut."), - NULL); - gtk_widget_set_sensitive(button, FALSE); - break; - } - } + if (psmiley && !(smiley->flags & GTK_IMHTML_SMILEY_CUSTOM)) { + gtk_tooltips_set_tip(toolbar->tooltips, button, + _("This smiley is disabled because a custom smiley exists for this shortcut."), + NULL); + gtk_widget_set_sensitive(button, FALSE); + } else if (psmiley) { + /* Remove the button if the smiley is destroyed */ + g_signal_connect_object(G_OBJECT(psmiley), "destroy", G_CALLBACK(gtk_widget_destroy), + button, G_CONNECT_SWAPPED); } /* set current element to add */ cur->height = size.height; cur->width = size.width; cur->button = button; + cur->smiley = smiley; cur->next = ls; /* check where to insert by height */ @@ -730,7 +726,7 @@ if ((event->type == GDK_KEY_PRESS && event->key.keyval == GDK_Escape) || (event->type == GDK_BUTTON_PRESS && event->button.button == 1)) { - close_smiley_dialog(NULL, NULL, toolbar); + close_smiley_dialog(toolbar); return TRUE; } @@ -738,12 +734,41 @@ } static void +add_smiley_list(GtkWidget *container, struct smiley_button_list *list, + int max_width, gboolean custom) +{ + GtkWidget *line; + int line_width = 0; + + if (!list) + return; + + line = gtk_hbox_new(FALSE, 0); + gtk_box_pack_start(GTK_BOX(container), line, FALSE, FALSE, 0); + for (; list; list = list->next) { + if (custom != !!(list->smiley->flags & GTK_IMHTML_SMILEY_CUSTOM)) + continue; + gtk_box_pack_start(GTK_BOX(line), list->button, FALSE, FALSE, 0); + gtk_widget_show(list->button); + line_width += list->width; + if (line_width >= max_width) { + if (list->next) { + line = gtk_hbox_new(FALSE, 0); + gtk_box_pack_start(GTK_BOX(container), line, FALSE, FALSE, 0); + } + line_width = 0; + } + } +} + +static void insert_smiley_cb(GtkWidget *smiley, GtkIMHtmlToolbar *toolbar) { GtkWidget *dialog; GtkWidget *smiley_table = NULL; GSList *smileys, *unique_smileys = NULL; const GSList *custom_smileys = NULL; + gboolean supports_custom = FALSE; if (!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(smiley))) { destroy_smiley_dialog(toolbar); @@ -765,9 +790,8 @@ } smileys = smileys->next; } - - if (toolbar->imhtml && - (gtk_imhtml_get_format_functions(GTK_IMHTML(toolbar->imhtml)) & GTK_IMHTML_CUSTOM_SMILEY)) { + supports_custom = (gtk_imhtml_get_format_functions(GTK_IMHTML(toolbar->imhtml)) & GTK_IMHTML_CUSTOM_SMILEY); + if (toolbar->imhtml && supports_custom) { const GSList *iterator = NULL; custom_smileys = pidgin_smileys_get_all(); @@ -783,20 +807,27 @@ gtk_window_set_position(GTK_WINDOW(dialog), GTK_WIN_POS_MOUSE); if (unique_smileys != NULL) { - struct smiley_button_list *ls, *it, *it_tmp; - GtkWidget *line; - int line_width = 0; - int max_line_width, num_lines; - int col=0; + struct smiley_button_list *ls; + int max_line_width, num_lines, button_width = 0; /* We use hboxes packed in a vbox */ ls = NULL; - line = gtk_hbox_new(FALSE, 0); - line_width = 0; max_line_width = 0; num_lines = floor(sqrt(g_slist_length(unique_smileys))); smiley_table = gtk_vbox_new(FALSE, 0); + if (supports_custom) { + GtkWidget *manage = gtk_button_new_with_mnemonic(_("_Manage custom smileys")); + GtkRequisition req; + g_signal_connect(G_OBJECT(manage), "clicked", + G_CALLBACK(pidgin_smiley_manager_show), NULL); + g_signal_connect_swapped(G_OBJECT(manage), "clicked", + G_CALLBACK(gtk_widget_destroy), dialog); + gtk_box_pack_end(GTK_BOX(smiley_table), manage, TRUE, FALSE, 0); + gtk_widget_size_request(manage, &req); + button_width = req.width; + } + /* create list of smileys sorted by height */ while (unique_smileys) { GtkIMHtmlSmiley *smiley = (GtkIMHtmlSmiley *) unique_smileys->data; @@ -805,26 +836,20 @@ } unique_smileys = g_slist_delete_link(unique_smileys, unique_smileys); } + /* The window will be at least as wide as the 'Manage ..' button */ + max_line_width = MAX(button_width, max_line_width / num_lines); + /* pack buttons of the list */ - max_line_width = max_line_width / num_lines; - it = ls; - while (it != NULL) - { - it_tmp = it; - gtk_box_pack_start(GTK_BOX(line), it->button, FALSE, FALSE, 0); - gtk_widget_show(it->button); - line_width += it->width; - if (line_width >= max_line_width) { - gtk_box_pack_start(GTK_BOX(smiley_table), line, FALSE, FALSE, 0); - line = gtk_hbox_new(FALSE, 0); - line_width = 0; - col = 0; - } - col++; - it = it->next; - g_free(it_tmp); + add_smiley_list(smiley_table, ls, max_line_width, FALSE); + if (supports_custom) { + gtk_box_pack_start(GTK_BOX(smiley_table), gtk_hseparator_new(), TRUE, FALSE, 0); + add_smiley_list(smiley_table, ls, max_line_width, TRUE); } - gtk_box_pack_start(GTK_BOX(smiley_table), line, FALSE, TRUE, 0); + while (ls) { + struct smiley_button_list *tmp = ls->next; + g_free(ls); + ls = tmp; + } gtk_widget_add_events(dialog, GDK_KEY_PRESS_MASK); } @@ -840,8 +865,7 @@ gtk_widget_show(smiley_table); /* connect signals */ - g_signal_connect(G_OBJECT(dialog), "delete_event", - G_CALLBACK(close_smiley_dialog), toolbar); + g_signal_connect_swapped(G_OBJECT(dialog), "destroy", G_CALLBACK(close_smiley_dialog), toolbar); /* show everything */ gtk_widget_show_all(dialog);