diff options
Diffstat (limited to 'libempathy-gtk')
-rw-r--r-- | libempathy-gtk/Makefile.am | 2 | ||||
-rw-r--r-- | libempathy-gtk/empathy-chat-view.c | 278 | ||||
-rw-r--r-- | libempathy-gtk/empathy-chat-view.h | 118 | ||||
-rw-r--r-- | libempathy-gtk/empathy-chat-window.c | 2 | ||||
-rw-r--r-- | libempathy-gtk/empathy-chat.c | 2 | ||||
-rw-r--r-- | libempathy-gtk/empathy-smiley-manager.c | 351 | ||||
-rw-r--r-- | libempathy-gtk/empathy-smiley-manager.h | 75 | ||||
-rw-r--r-- | libempathy-gtk/empathy-ui-utils.c | 98 | ||||
-rw-r--r-- | libempathy-gtk/empathy-ui-utils.h | 2 |
9 files changed, 518 insertions, 410 deletions
diff --git a/libempathy-gtk/Makefile.am b/libempathy-gtk/Makefile.am index f73966a3e..8e4790e3b 100644 --- a/libempathy-gtk/Makefile.am +++ b/libempathy-gtk/Makefile.am @@ -32,6 +32,7 @@ libempathy_gtk_la_SOURCES = \ empathy-contact-list-view.c \ empathy-preferences.c \ empathy-theme-manager.c \ + empathy-smiley-manager.c \ empathy-chat-window.c \ empathy-chat.c \ empathy-chat-view.c \ @@ -79,6 +80,7 @@ libempathy_gtk_headers = \ empathy-contact-list-view.h \ empathy-preferences.h \ empathy-theme-manager.h \ + empathy-smiley-manager.h \ empathy-chat-window.h \ empathy-chat.h \ empathy-chat-view.h \ diff --git a/libempathy-gtk/empathy-chat-view.c b/libempathy-gtk/empathy-chat-view.c index 65094bda9..116892b60 100644 --- a/libempathy-gtk/empathy-chat-view.c +++ b/libempathy-gtk/empathy-chat-view.c @@ -50,6 +50,7 @@ #include "empathy-preferences.h" #include "empathy-theme-manager.h" #include "empathy-ui-utils.h" +#include "empathy-smiley-manager.h" #define DEBUG_DOMAIN "ChatView" @@ -72,6 +73,8 @@ typedef enum { } BlockType; struct _EmpathyChatViewPriv { + EmpathySmileyManager *smiley_manager; + GtkTextBuffer *buffer; gboolean irc_style; @@ -97,102 +100,6 @@ struct _EmpathyChatViewPriv { guint notify_show_avatars_id; }; -typedef struct { - EmpathySmiley smiley; - const gchar *pattern; -} EmpathySmileyPattern; - -static const EmpathySmileyPattern smileys[] = { - /* Forward smileys. */ - { EMPATHY_SMILEY_NORMAL, ":)" }, - { EMPATHY_SMILEY_WINK, ";)" }, - { EMPATHY_SMILEY_WINK, ";-)" }, - { EMPATHY_SMILEY_BIGEYE, "=)" }, - { EMPATHY_SMILEY_NOSE, ":-)" }, - { EMPATHY_SMILEY_CRY, ":'(" }, - { EMPATHY_SMILEY_SAD, ":(" }, - { EMPATHY_SMILEY_SAD, ":-(" }, - { EMPATHY_SMILEY_SCEPTICAL, ":/" }, - { EMPATHY_SMILEY_SCEPTICAL, ":\\" }, - { EMPATHY_SMILEY_BIGSMILE, ":D" }, - { EMPATHY_SMILEY_BIGSMILE, ":-D" }, - { EMPATHY_SMILEY_INDIFFERENT, ":|" }, - { EMPATHY_SMILEY_TOUNGE, ":p" }, - { EMPATHY_SMILEY_TOUNGE, ":-p" }, - { EMPATHY_SMILEY_TOUNGE, ":P" }, - { EMPATHY_SMILEY_TOUNGE, ":-P" }, - { EMPATHY_SMILEY_TOUNGE, ";p" }, - { EMPATHY_SMILEY_TOUNGE, ";-p" }, - { EMPATHY_SMILEY_TOUNGE, ";P" }, - { EMPATHY_SMILEY_TOUNGE, ";-P" }, - { EMPATHY_SMILEY_SHOCKED, ":o" }, - { EMPATHY_SMILEY_SHOCKED, ":-o" }, - { EMPATHY_SMILEY_SHOCKED, ":O" }, - { EMPATHY_SMILEY_SHOCKED, ":-O" }, - { EMPATHY_SMILEY_COOL, "8)" }, - { EMPATHY_SMILEY_COOL, "B)" }, - { EMPATHY_SMILEY_SORRY, "*|" }, - { EMPATHY_SMILEY_KISS, ":*" }, - { EMPATHY_SMILEY_SHUTUP, ":#" }, - { EMPATHY_SMILEY_SHUTUP, ":-#" }, - { EMPATHY_SMILEY_YAWN, "|O" }, - { EMPATHY_SMILEY_CONFUSED, ":S" }, - { EMPATHY_SMILEY_CONFUSED, ":s" }, - { EMPATHY_SMILEY_ANGEL, "<)" }, - { EMPATHY_SMILEY_OOOH, ":x" }, - { EMPATHY_SMILEY_LOOKAWAY, "*)" }, - { EMPATHY_SMILEY_LOOKAWAY, "*-)" }, - { EMPATHY_SMILEY_BLUSH, "*S" }, - { EMPATHY_SMILEY_BLUSH, "*s" }, - { EMPATHY_SMILEY_BLUSH, "*$" }, - { EMPATHY_SMILEY_COOLBIGSMILE, "8D" }, - { EMPATHY_SMILEY_ANGRY, ":@" }, - { EMPATHY_SMILEY_BOSS, "@)" }, - { EMPATHY_SMILEY_MONKEY, "#)" }, - { EMPATHY_SMILEY_SILLY, "O)" }, - { EMPATHY_SMILEY_SICK, "+o(" }, - - /* Backward smileys. */ - { EMPATHY_SMILEY_NORMAL, "(:" }, - { EMPATHY_SMILEY_WINK, "(;" }, - { EMPATHY_SMILEY_WINK, "(-;" }, - { EMPATHY_SMILEY_BIGEYE, "(=" }, - { EMPATHY_SMILEY_NOSE, "(-:" }, - { EMPATHY_SMILEY_CRY, ")':" }, - { EMPATHY_SMILEY_SAD, "):" }, - { EMPATHY_SMILEY_SAD, ")-:" }, - { EMPATHY_SMILEY_SCEPTICAL, "/:" }, - { EMPATHY_SMILEY_SCEPTICAL, "//:" }, - { EMPATHY_SMILEY_INDIFFERENT, "|:" }, - { EMPATHY_SMILEY_TOUNGE, "d:" }, - { EMPATHY_SMILEY_TOUNGE, "d-:" }, - { EMPATHY_SMILEY_TOUNGE, "d;" }, - { EMPATHY_SMILEY_TOUNGE, "d-;" }, - { EMPATHY_SMILEY_SHOCKED, "o:" }, - { EMPATHY_SMILEY_SHOCKED, "O:" }, - { EMPATHY_SMILEY_COOL, "(8" }, - { EMPATHY_SMILEY_COOL, "(B" }, - { EMPATHY_SMILEY_SORRY, "|*" }, - { EMPATHY_SMILEY_KISS, "*:" }, - { EMPATHY_SMILEY_SHUTUP, "#:" }, - { EMPATHY_SMILEY_SHUTUP, "#-:" }, - { EMPATHY_SMILEY_YAWN, "O|" }, - { EMPATHY_SMILEY_CONFUSED, "S:" }, - { EMPATHY_SMILEY_CONFUSED, "s:" }, - { EMPATHY_SMILEY_ANGEL, "(>" }, - { EMPATHY_SMILEY_OOOH, "x:" }, - { EMPATHY_SMILEY_LOOKAWAY, "(*" }, - { EMPATHY_SMILEY_LOOKAWAY, "(-*" }, - { EMPATHY_SMILEY_BLUSH, "S*" }, - { EMPATHY_SMILEY_BLUSH, "s*" }, - { EMPATHY_SMILEY_BLUSH, "$*" }, - { EMPATHY_SMILEY_ANGRY, "@:" }, - { EMPATHY_SMILEY_BOSS, "(@" }, - { EMPATHY_SMILEY_MONKEY, "#)" }, - { EMPATHY_SMILEY_SILLY, "(O" }, - { EMPATHY_SMILEY_SICK, ")o+" } -}; - static void empathy_chat_view_class_init (EmpathyChatViewClass *klass); static void empathy_chat_view_init (EmpathyChatView *view); static void chat_view_finalize (GObject *object); @@ -228,7 +135,7 @@ static void chat_view_copy_address_cb (GtkMenuItem * const gchar *url); static void chat_view_clear_view_cb (GtkMenuItem *menuitem, EmpathyChatView *view); -static void chat_view_insert_text_with_emoticons (GtkTextBuffer *buf, +static void chat_view_insert_text_with_emoticons (EmpathyChatView *view, GtkTextIter *iter, const gchar *str); static gboolean chat_view_is_scrolled_down (EmpathyChatView *view); @@ -278,6 +185,7 @@ empathy_chat_view_init (EmpathyChatView *view) priv = GET_PRIV (view); + priv->smiley_manager = empathy_smiley_manager_new (); priv->buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view)); priv->last_block_type = BLOCK_TYPE_NONE; @@ -344,6 +252,9 @@ chat_view_finalize (GObject *object) empathy_conf_notify_remove (empathy_conf_get (), priv->notify_system_fonts_id); empathy_conf_notify_remove (empathy_conf_get (), priv->notify_show_avatars_id); + if (priv->smiley_manager) { + g_object_unref (priv->smiley_manager); + } if (priv->last_contact) { g_object_unref (priv->last_contact); } @@ -682,16 +593,14 @@ chat_view_clear_view_cb (GtkMenuItem *menuitem, EmpathyChatView *view) } static void -chat_view_insert_text_with_emoticons (GtkTextBuffer *buf, - GtkTextIter *iter, - const gchar *str) +chat_view_insert_text_with_emoticons (EmpathyChatView *view, + GtkTextIter *iter, + const gchar *str) { - const gchar *p; - gunichar c, prev_c; - gint i; - gint match; - gint submatch; - gboolean use_smileys = FALSE; + EmpathyChatViewPriv *priv = GET_PRIV (view); + GtkTextBuffer *buf = priv->buffer; + gboolean use_smileys = FALSE; + GSList *smileys, *l; empathy_conf_get_bool (empathy_conf_get (), EMPATHY_PREFS_CHAT_SHOW_SMILEYS, @@ -702,76 +611,19 @@ chat_view_insert_text_with_emoticons (GtkTextBuffer *buf, return; } - while (*str) { - gint smileys_index[G_N_ELEMENTS (smileys)]; - GdkPixbuf *pixbuf; - gint len; - const gchar *start; - - memset (smileys_index, 0, sizeof (smileys_index)); - - match = -1; - submatch = -1; - p = str; - prev_c = 0; - - while (*p) { - c = g_utf8_get_char (p); - - if (match != -1 && g_unichar_isspace (c)) { - break; - } else { - match = -1; - } - - if (submatch != -1 || prev_c == 0 || g_unichar_isspace (prev_c)) { - submatch = -1; - - for (i = 0; i < G_N_ELEMENTS (smileys); i++) { - /* Only try to match if we already have - * a beginning match for the pattern, or - * if it's the first character in the - * pattern, if it's not in the middle of - * a word. - */ - if (((smileys_index[i] == 0 && (prev_c == 0 || g_unichar_isspace (prev_c))) || - smileys_index[i] > 0) && - smileys[i].pattern[smileys_index[i]] == c) { - submatch = i; - - smileys_index[i]++; - if (!smileys[i].pattern[smileys_index[i]]) { - match = i; - } - } else { - smileys_index[i] = 0; - } - } - } - - prev_c = c; - p = g_utf8_next_char (p); - } - - if (match == -1) { - gtk_text_buffer_insert (buf, iter, str, -1); - return; - } + smileys = empathy_smiley_manager_parse (priv->smiley_manager, str); + for (l = smileys; l; l = l->next) { + EmpathySmiley *smiley; - start = p - strlen (smileys[match].pattern); - - if (start > str) { - len = start - str; - gtk_text_buffer_insert (buf, iter, str, len); + smiley = l->data; + if (smiley->pixbuf) { + gtk_text_buffer_insert_pixbuf (buf, iter, smiley->pixbuf); + } else { + gtk_text_buffer_insert (buf, iter, smiley->str, -1); } - - pixbuf = empathy_chat_view_get_smiley_image (smileys[match].smiley); - gtk_text_buffer_insert_pixbuf (buf, iter, pixbuf); - - gtk_text_buffer_insert (buf, iter, " ", 1); - - str = g_utf8_find_next_char (p, NULL); + empathy_smiley_free (smiley); } + g_slist_free (smileys); } static gboolean @@ -991,7 +843,7 @@ chat_view_append_text (EmpathyChatView *view, if (num_matches == 0) { gtk_text_buffer_get_end_iter (priv->buffer, &iter); - chat_view_insert_text_with_emoticons (priv->buffer, &iter, body); + chat_view_insert_text_with_emoticons (view, &iter, body); } else { gint last = 0; gint s = 0, e = 0; @@ -1005,7 +857,7 @@ chat_view_append_text (EmpathyChatView *view, tmp = empathy_substring (body, last, s); gtk_text_buffer_get_end_iter (priv->buffer, &iter); - chat_view_insert_text_with_emoticons (priv->buffer, + chat_view_insert_text_with_emoticons (view, &iter, tmp); g_free (tmp); @@ -1031,7 +883,7 @@ chat_view_append_text (EmpathyChatView *view, tmp = empathy_substring (body, e, strlen (body)); gtk_text_buffer_get_end_iter (priv->buffer, &iter); - chat_view_insert_text_with_emoticons (priv->buffer, + chat_view_insert_text_with_emoticons (view, &iter, tmp); g_free (tmp); @@ -2104,67 +1956,30 @@ empathy_chat_view_set_margin (EmpathyChatView *view, NULL); } -GdkPixbuf * -empathy_chat_view_get_smiley_image (EmpathySmiley smiley) -{ - static GdkPixbuf *pixbufs[EMPATHY_SMILEY_COUNT]; - static gboolean inited = FALSE; - - if (!inited) { - gint i; - - for (i = 0; i < EMPATHY_SMILEY_COUNT; i++) { - pixbufs[i] = empathy_pixbuf_from_smiley (i, GTK_ICON_SIZE_MENU); - } - - inited = TRUE; - } - - return pixbufs[smiley]; -} - -const gchar * -empathy_chat_view_get_smiley_text (EmpathySmiley smiley) -{ - gint i; - - for (i = 0; i < G_N_ELEMENTS (smileys); i++) { - if (smileys[i].smiley != smiley) { - continue; - } - - return smileys[i].pattern; - } - - return NULL; -} - GtkWidget * empathy_chat_view_get_smiley_menu (GCallback callback, - gpointer user_data, - GtkTooltips *tooltips) + gpointer user_data, + GtkTooltips *tooltips) { - GtkWidget *menu; - gint x; - gint y; - gint i; + EmpathySmileyManager *smiley_manager; + GSList *smileys, *l; + GtkWidget *menu; + gint x = 0; + gint y = 0; g_return_val_if_fail (callback != NULL, NULL); menu = gtk_menu_new (); - for (i = 0, x = 0, y = 0; i < EMPATHY_SMILEY_COUNT; i++) { - GtkWidget *item; - GtkWidget *image; - GdkPixbuf *pixbuf; - const gchar *smiley_text; + smiley_manager = empathy_smiley_manager_new (); + smileys = empathy_smiley_manager_get_all (smiley_manager); + for (l = smileys; l; l = l->next) { + EmpathySmiley *smiley; + GtkWidget *item; + GtkWidget *image; - pixbuf = empathy_chat_view_get_smiley_image (i); - if (!pixbuf) { - continue; - } - - image = gtk_image_new_from_pixbuf (pixbuf); + smiley = l->data; + image = gtk_image_new_from_pixbuf (smiley->pixbuf); item = gtk_image_menu_item_new_with_label (""); gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image); @@ -2172,14 +1987,12 @@ empathy_chat_view_get_smiley_menu (GCallback callback, gtk_menu_attach (GTK_MENU (menu), item, x, x + 1, y, y + 1); - smiley_text = empathy_chat_view_get_smiley_text (i); - gtk_tooltips_set_tip (tooltips, item, - smiley_text, + smiley->str, NULL); - g_object_set_data (G_OBJECT (item), "smiley_text", (gpointer) smiley_text); + g_object_set_data (G_OBJECT (item), "smiley_text", smiley->str); g_signal_connect (item, "activate", callback, user_data); if (x > 3) { @@ -2189,6 +2002,7 @@ empathy_chat_view_get_smiley_menu (GCallback callback, x++; } } + g_object_unref (smiley_manager); gtk_widget_show_all (menu); diff --git a/libempathy-gtk/empathy-chat-view.h b/libempathy-gtk/empathy-chat-view.h index 4478e2116..370c8dd85 100644 --- a/libempathy-gtk/empathy-chat-view.h +++ b/libempathy-gtk/empathy-chat-view.h @@ -52,82 +52,48 @@ struct _EmpathyChatViewClass { GtkTextViewClass parent_class; }; -typedef enum { - EMPATHY_SMILEY_NORMAL, /* :) */ - EMPATHY_SMILEY_WINK, /* ;) */ - EMPATHY_SMILEY_BIGEYE, /* =) */ - EMPATHY_SMILEY_NOSE, /* :-) */ - EMPATHY_SMILEY_CRY, /* :'( */ - EMPATHY_SMILEY_SAD, /* :( */ - EMPATHY_SMILEY_SCEPTICAL, /* :/ */ - EMPATHY_SMILEY_BIGSMILE, /* :D */ - EMPATHY_SMILEY_INDIFFERENT, /* :| */ - EMPATHY_SMILEY_TOUNGE, /* :p */ - EMPATHY_SMILEY_SHOCKED, /* :o */ - EMPATHY_SMILEY_COOL, /* 8) */ - EMPATHY_SMILEY_SORRY, /* *| */ - EMPATHY_SMILEY_KISS, /* :* */ - EMPATHY_SMILEY_SHUTUP, /* :# */ - EMPATHY_SMILEY_YAWN, /* |O */ - EMPATHY_SMILEY_CONFUSED, /* :$ */ - EMPATHY_SMILEY_ANGEL, /* <) */ - EMPATHY_SMILEY_OOOH, /* :x */ - EMPATHY_SMILEY_LOOKAWAY, /* *) */ - EMPATHY_SMILEY_BLUSH, /* *S */ - EMPATHY_SMILEY_COOLBIGSMILE, /* 8D */ - EMPATHY_SMILEY_ANGRY, /* :@ */ - EMPATHY_SMILEY_BOSS, /* @) */ - EMPATHY_SMILEY_MONKEY, /* #) */ - EMPATHY_SMILEY_SILLY, /* O) */ - EMPATHY_SMILEY_SICK, /* +o( */ - - EMPATHY_SMILEY_COUNT -} EmpathySmiley; - -GType empathy_chat_view_get_type (void) G_GNUC_CONST; -EmpathyChatView *empathy_chat_view_new (void); -void empathy_chat_view_append_message (EmpathyChatView *view, - EmpathyMessage *msg); -void empathy_chat_view_append_event (EmpathyChatView *view, - const gchar *str); -void empathy_chat_view_append_button (EmpathyChatView *view, - const gchar *message, - GtkWidget *button1, - GtkWidget *button2); -void empathy_chat_view_set_margin (EmpathyChatView *view, - gint margin); -void empathy_chat_view_scroll (EmpathyChatView *view, - gboolean allow_scrolling); -void empathy_chat_view_scroll_down (EmpathyChatView *view); -gboolean empathy_chat_view_get_selection_bounds (EmpathyChatView *view, - GtkTextIter *start, - GtkTextIter *end); -void empathy_chat_view_clear (EmpathyChatView *view); -gboolean empathy_chat_view_find_previous (EmpathyChatView *view, - const gchar *search_criteria, - gboolean new_search); -gboolean empathy_chat_view_find_next (EmpathyChatView *view, - const gchar *search_criteria, - gboolean new_search); -void empathy_chat_view_find_abilities (EmpathyChatView *view, - const gchar *search_criteria, - gboolean *can_do_previous, - gboolean *can_do_next); -void empathy_chat_view_highlight (EmpathyChatView *view, - const gchar *text); -void empathy_chat_view_copy_clipboard (EmpathyChatView *view); -gboolean empathy_chat_view_get_irc_style (EmpathyChatView *view); -void empathy_chat_view_set_irc_style (EmpathyChatView *view, - gboolean irc_style); -void empathy_chat_view_set_margin (EmpathyChatView *view, - gint margin); -GdkPixbuf * empathy_chat_view_get_smiley_image (EmpathySmiley smiley); -const gchar * empathy_chat_view_get_smiley_text (EmpathySmiley smiley); -GtkWidget * empathy_chat_view_get_smiley_menu (GCallback callback, - gpointer user_data, - GtkTooltips *tooltips); -void empathy_chat_view_set_is_group_chat (EmpathyChatView *view, - gboolean is_group_chat); +GType empathy_chat_view_get_type (void) G_GNUC_CONST; +EmpathyChatView *empathy_chat_view_new (void); +void empathy_chat_view_append_message (EmpathyChatView *view, + EmpathyMessage *msg); +void empathy_chat_view_append_event (EmpathyChatView *view, + const gchar *str); +void empathy_chat_view_append_button (EmpathyChatView *view, + const gchar *message, + GtkWidget *button1, + GtkWidget *button2); +void empathy_chat_view_set_margin (EmpathyChatView *view, + gint margin); +void empathy_chat_view_scroll (EmpathyChatView *view, + gboolean allow_scrolling); +void empathy_chat_view_scroll_down (EmpathyChatView *view); +gboolean empathy_chat_view_get_selection_bounds (EmpathyChatView *view, + GtkTextIter *start, + GtkTextIter *end); +void empathy_chat_view_clear (EmpathyChatView *view); +gboolean empathy_chat_view_find_previous (EmpathyChatView *view, + const gchar *search_criteria, + gboolean new_search); +gboolean empathy_chat_view_find_next (EmpathyChatView *view, + const gchar *search_criteria, + gboolean new_search); +void empathy_chat_view_find_abilities (EmpathyChatView *view, + const gchar *search_criteria, + gboolean *can_do_previous, + gboolean *can_do_next); +void empathy_chat_view_highlight (EmpathyChatView *view, + const gchar *text); +void empathy_chat_view_copy_clipboard (EmpathyChatView *view); +gboolean empathy_chat_view_get_irc_style (EmpathyChatView *view); +void empathy_chat_view_set_irc_style (EmpathyChatView *view, + gboolean irc_style); +void empathy_chat_view_set_margin (EmpathyChatView *view, + gint margin); +GtkWidget * empathy_chat_view_get_smiley_menu (GCallback callback, + gpointer user_data, + GtkTooltips *tooltips); +void empathy_chat_view_set_is_group_chat (EmpathyChatView *view, + gboolean is_group_chat); G_END_DECLS diff --git a/libempathy-gtk/empathy-chat-window.c b/libempathy-gtk/empathy-chat-window.c index c1df38b15..94107e99f 100644 --- a/libempathy-gtk/empathy-chat-window.c +++ b/libempathy-gtk/empathy-chat-window.c @@ -853,7 +853,7 @@ chat_window_update_menu (EmpathyChatWindow *window) } static void -chat_window_insert_smiley_activate_cb (GtkWidget *menuitem, +chat_window_insert_smiley_activate_cb (GtkWidget *menuitem, EmpathyChatWindow *window) { EmpathyChatWindowPriv *priv; diff --git a/libempathy-gtk/empathy-chat.c b/libempathy-gtk/empathy-chat.c index 9de1caa07..af35b0334 100644 --- a/libempathy-gtk/empathy-chat.c +++ b/libempathy-gtk/empathy-chat.c @@ -880,7 +880,7 @@ chat_text_view_realize_cb (GtkWidget *widget, } static void -chat_insert_smiley_activate_cb (GtkWidget *menuitem, +chat_insert_smiley_activate_cb (GtkWidget *menuitem, EmpathyChat *chat) { GtkTextBuffer *buffer; diff --git a/libempathy-gtk/empathy-smiley-manager.c b/libempathy-gtk/empathy-smiley-manager.c new file mode 100644 index 000000000..3d6f9645e --- /dev/null +++ b/libempathy-gtk/empathy-smiley-manager.c @@ -0,0 +1,351 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* + * Copyright (C) 2007 Collabora Ltd. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Authors: Xavier Claessens <xclaesse@gmail.com> + */ + +#include <config.h> + +#include <string.h> + +#include <libempathy/empathy-debug.h> + +#include "empathy-smiley-manager.h" +#include "empathy-ui-utils.h" + +#define GET_PRIV(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \ + EMPATHY_TYPE_SMILEY_MANAGER, EmpathySmileyManagerPriv)) + +#define DEBUG_DOMAIN "SmileyManager" + +typedef struct { + gunichar c; + GdkPixbuf *pixbuf; + GSList *childrens; +} SmileyManagerTree; + +struct _EmpathySmileyManagerPriv { + SmileyManagerTree *tree; + GSList *smileys; +}; + +static void empathy_smiley_manager_class_init (EmpathySmileyManagerClass *klass); +static void empathy_smiley_manager_init (EmpathySmileyManager *manager); + +G_DEFINE_TYPE (EmpathySmileyManager, empathy_smiley_manager, G_TYPE_OBJECT); + +static SmileyManagerTree * +smiley_manager_tree_new (gunichar c) +{ + SmileyManagerTree *tree; + + tree = g_slice_new0 (SmileyManagerTree); + tree->c = c; + tree->pixbuf = NULL; + tree->childrens = NULL; + + return tree; +} + +static void +smiley_manager_tree_free (SmileyManagerTree *tree) +{ + GSList *l; + + if (!tree) { + return; + } + + for (l = tree->childrens; l; l = l->next) { + smiley_manager_tree_free (l->data); + } + + if (tree->pixbuf) { + g_object_unref (tree->pixbuf); + } + g_slist_free (tree->childrens); + g_slice_free (SmileyManagerTree, tree); +} + +static EmpathySmiley * +smiley_new (GdkPixbuf *pixbuf, const gchar *str) +{ + EmpathySmiley *smiley; + + smiley = g_slice_new0 (EmpathySmiley); + if (pixbuf) { + smiley->pixbuf = g_object_ref (pixbuf); + } + smiley->str = g_strdup (str); + + return smiley; +} + +void +empathy_smiley_free (EmpathySmiley *smiley) +{ + if (!smiley) { + return; + } + + if (smiley->pixbuf) { + g_object_unref (smiley->pixbuf); + } + g_free (smiley->str); +} + +static void +smiley_manager_finalize (GObject *object) +{ + EmpathySmileyManagerPriv *priv = GET_PRIV (object); + + smiley_manager_tree_free (priv->tree); + g_slist_foreach (priv->smileys, (GFunc) empathy_smiley_free, NULL); + g_slist_free (priv->smileys); +} + +static void +empathy_smiley_manager_class_init (EmpathySmileyManagerClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = smiley_manager_finalize; + + g_type_class_add_private (object_class, sizeof (EmpathySmileyManagerPriv)); +} + +static void +empathy_smiley_manager_init (EmpathySmileyManager *manager) +{ + EmpathySmileyManagerPriv *priv = GET_PRIV (manager); + + priv->tree = smiley_manager_tree_new ('\0'); + priv->smileys = NULL; +} + +EmpathySmileyManager * +empathy_smiley_manager_new (void) +{ + static EmpathySmileyManager *manager = NULL; + + if (!manager) { + manager = g_object_new (EMPATHY_TYPE_SMILEY_MANAGER, NULL); + g_object_add_weak_pointer (G_OBJECT (manager), (gpointer) &manager); + empathy_smiley_manager_load (manager); + } else { + g_object_ref (manager); + } + + return manager; +} + +static SmileyManagerTree * +smiley_manager_tree_find_child (SmileyManagerTree *tree, gunichar c) +{ + GSList *l; + + for (l = tree->childrens; l; l = l->next) { + SmileyManagerTree *child = l->data; + + if (child->c == c) { + return child; + } + } + + return NULL; +} + +static SmileyManagerTree * +smiley_manager_tree_find_or_insert_child (SmileyManagerTree *tree, gunichar c) +{ + SmileyManagerTree *child; + + child = smiley_manager_tree_find_child (tree, c); + + if (!child) { + child = smiley_manager_tree_new (c); + tree->childrens = g_slist_prepend (tree->childrens, child); + } + + return child; +} + +static void +smiley_manager_tree_insert (SmileyManagerTree *tree, + GdkPixbuf *smiley, + const gchar *str) +{ + SmileyManagerTree *child; + + child = smiley_manager_tree_find_or_insert_child (tree, g_utf8_get_char (str)); + + str = g_utf8_next_char (str); + if (*str) { + smiley_manager_tree_insert (child, smiley, str); + return; + } + + child->pixbuf = g_object_ref (smiley); +} + +static void +smiley_manager_add_valist (EmpathySmileyManager *manager, + GdkPixbuf *smiley, + const gchar *first_str, + va_list var_args) +{ + EmpathySmileyManagerPriv *priv = GET_PRIV (manager); + const gchar *str; + + for (str = first_str; str; str = va_arg (var_args, gchar*)) { + smiley_manager_tree_insert (priv->tree, smiley, str); + } + + priv->smileys = g_slist_prepend (priv->smileys, smiley_new (smiley, first_str)); +} + +void +empathy_smiley_manager_add (EmpathySmileyManager *manager, + const gchar *icon_name, + const gchar *first_str, + ...) +{ + GdkPixbuf *smiley; + va_list var_args; + + g_return_if_fail (EMPATHY_IS_SMILEY_MANAGER (manager)); + g_return_if_fail (!G_STR_EMPTY (icon_name)); + g_return_if_fail (!G_STR_EMPTY (first_str)); + + smiley = empathy_pixbuf_from_icon_name (icon_name, GTK_ICON_SIZE_MENU); + if (smiley) { + va_start (var_args, first_str); + smiley_manager_add_valist (manager, smiley, first_str, var_args); + va_end (var_args); + g_object_unref (smiley); + } +} + +void +empathy_smiley_manager_add_from_pixbuf (EmpathySmileyManager *manager, + GdkPixbuf *smiley, + const gchar *first_str, + ...) +{ + va_list var_args; + + g_return_if_fail (EMPATHY_IS_SMILEY_MANAGER (manager)); + g_return_if_fail (GDK_IS_PIXBUF (smiley)); + g_return_if_fail (!G_STR_EMPTY (first_str)); + + va_start (var_args, first_str); + smiley_manager_add_valist (manager, smiley, first_str, var_args); + va_end (var_args); +} + +void +empathy_smiley_manager_load (EmpathySmileyManager *manager) +{ + g_return_if_fail (EMPATHY_IS_SMILEY_MANAGER (manager)); + + /* From fd.o icon-naming spec */ + empathy_smiley_manager_add (manager, "face-angel", "0:-)", "0:)", NULL); + empathy_smiley_manager_add (manager, "face-crying", ":'(", NULL); + empathy_smiley_manager_add (manager, "face-devil-grin", ">:-)", ">:)", NULL); + empathy_smiley_manager_add (manager, "face-devil-sad", ">:-(", ">:(", NULL); + empathy_smiley_manager_add (manager, "face-glasses", "B-)", "B)", NULL); + empathy_smiley_manager_add (manager, "face-kiss", ":-*", ":*", NULL); + empathy_smiley_manager_add (manager, "face-monkey", ":-(|)", ":(|)", NULL); + empathy_smiley_manager_add (manager, "face-plain", ":-|", ":|", NULL); + empathy_smiley_manager_add (manager, "face-sad", ":-(", ":(", NULL); + empathy_smiley_manager_add (manager, "face-smile", ":-)", ":)", NULL); + empathy_smiley_manager_add (manager, "face-smile-big", ":-D", ":D", NULL); + empathy_smiley_manager_add (manager, "face-smirk", ":-!", ":!", NULL); + empathy_smiley_manager_add (manager, "face-surprise", ":-0", ":0", NULL); + empathy_smiley_manager_add (manager, "face-wink", ";-)", ";)", NULL); +} + +GSList * +empathy_smiley_manager_parse (EmpathySmileyManager *manager, + const gchar *text) +{ + EmpathySmileyManagerPriv *priv = GET_PRIV (manager); + EmpathySmiley *smiley; + SmileyManagerTree *cur_tree = priv->tree; + const gchar *t; + const gchar *cur_str = text; + GSList *smileys = NULL; + + g_return_val_if_fail (EMPATHY_IS_SMILEY_MANAGER (manager), NULL); + g_return_val_if_fail (text != NULL, NULL); + + for (t = text; *t; t = g_utf8_next_char (t)) { + SmileyManagerTree *child; + gunichar c; + + c = g_utf8_get_char (t); + child = smiley_manager_tree_find_child (cur_tree, c); + + if (cur_tree == priv->tree) { + if (child) { + if (t > cur_str) { + smiley = smiley_new (NULL, g_strndup (cur_str, t - cur_str)); + smileys = g_slist_prepend (smileys, smiley); + } + cur_str = t; + cur_tree = child; + } + + continue; + } + + if (child) { + cur_tree = child; + continue; + } + + smiley = smiley_new (cur_tree->pixbuf, g_strndup (cur_str, t - cur_str)); + smileys = g_slist_prepend (smileys, smiley); + if (cur_tree->pixbuf) { + cur_str = t; + cur_tree = smiley_manager_tree_find_child (priv->tree, c); + + if (!cur_tree) { + cur_tree = priv->tree; + } + } else { + cur_str = t; + cur_tree = priv->tree; + } + } + + smiley = smiley_new (cur_tree->pixbuf, g_strndup (cur_str, t - cur_str)); + smileys = g_slist_prepend (smileys, smiley); + + return g_slist_reverse (smileys); +} + +GSList * +empathy_smiley_manager_get_all (EmpathySmileyManager *manager) +{ + EmpathySmileyManagerPriv *priv = GET_PRIV (manager); + + return priv->smileys; +} + diff --git a/libempathy-gtk/empathy-smiley-manager.h b/libempathy-gtk/empathy-smiley-manager.h new file mode 100644 index 000000000..171956e2d --- /dev/null +++ b/libempathy-gtk/empathy-smiley-manager.h @@ -0,0 +1,75 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* + * Copyright (C) 2007 Collabora Ltd. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Authors: Dafydd Harrie <dafydd.harries@collabora.co.uk> + * Xavier Claessens <xclaesse@gmail.com> + */ + +#ifndef __EMPATHY_SMILEY_MANAGER__H__ +#define __EMPATHY_SMILEY_MANAGER_H__ + +#include <glib-object.h> +#include <gtk/gtk.h> + +G_BEGIN_DECLS + +#define EMPATHY_TYPE_SMILEY_MANAGER (empathy_smiley_manager_get_type ()) +#define EMPATHY_SMILEY_MANAGER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), EMPATHY_TYPE_SMILEY_MANAGER, EmpathySmileyManager)) +#define EMPATHY_SMILEY_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), EMPATHY_TYPE_SMILEY_MANAGER, EmpathySmileyManagerClass)) +#define EMPATHY_IS_SMILEY_MANAGER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), EMPATHY_TYPE_SMILEY_MANAGER)) +#define EMPATHY_IS_SMILEY_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), EMPATHY_TYPE_SMILEY_MANAGER)) +#define EMPATHY_SMILEY_MANAGER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), EMPATHY_TYPE_SMILEY_MANAGER, EmpathySmileyManagerClass)) + +typedef struct _EmpathySmileyManager EmpathySmileyManager; +typedef struct _EmpathySmileyManagerClass EmpathySmileyManagerClass; +typedef struct _EmpathySmileyManagerPriv EmpathySmileyManagerPriv; + +struct _EmpathySmileyManager { + GObject parent; +}; + +struct _EmpathySmileyManagerClass { + GObjectClass parent_class; +}; + +typedef struct { + GdkPixbuf *pixbuf; + gchar *str; +} EmpathySmiley; + +GType empathy_smiley_manager_get_type (void) G_GNUC_CONST; +EmpathySmileyManager *empathy_smiley_manager_new (void); +void empathy_smiley_manager_load (EmpathySmileyManager *manager); +void empathy_smiley_manager_add (EmpathySmileyManager *manager, + const gchar *icon_name, + const gchar *first_str, + ...); +void empathy_smiley_manager_add_from_pixbuf (EmpathySmileyManager *manager, + GdkPixbuf *smiley, + const gchar *first_str, + ...); +GSList * empathy_smiley_manager_get_all (EmpathySmileyManager *manager); +GSList * empathy_smiley_manager_parse (EmpathySmileyManager *manager, + const gchar *text); +void empathy_smiley_free (EmpathySmiley *smiley); + +G_END_DECLS + +#endif /* __EMPATHY_SMILEY_MANAGER_H__ */ + diff --git a/libempathy-gtk/empathy-ui-utils.c b/libempathy-gtk/empathy-ui-utils.c index aedacb08b..1c2d79c7b 100644 --- a/libempathy-gtk/empathy-ui-utils.c +++ b/libempathy-gtk/empathy-ui-utils.c @@ -230,104 +230,6 @@ empathy_pixbuf_from_icon_name (const gchar *icon_name, return pixbuf; } -GdkPixbuf * -empathy_pixbuf_from_smiley (EmpathySmiley type, - GtkIconSize icon_size) -{ - const gchar *icon_id; - - switch (type) { - case EMPATHY_SMILEY_NORMAL: /* :) */ - icon_id = "stock_smiley-1"; - break; - case EMPATHY_SMILEY_WINK: /* ;) */ - icon_id = "stock_smiley-3"; - break; - case EMPATHY_SMILEY_BIGEYE: /* =) */ - icon_id = "stock_smiley-2"; - break; - case EMPATHY_SMILEY_NOSE: /* :-) */ - icon_id = "stock_smiley-7"; - break; - case EMPATHY_SMILEY_CRY: /* :'( */ - icon_id = "stock_smiley-11"; - break; - case EMPATHY_SMILEY_SAD: /* :( */ - icon_id = "stock_smiley-4"; - break; - case EMPATHY_SMILEY_SCEPTICAL: /* :/ */ - icon_id = "stock_smiley-9"; - break; - case EMPATHY_SMILEY_BIGSMILE: /* :D */ - icon_id = "stock_smiley-6"; - break; - case EMPATHY_SMILEY_INDIFFERENT: /* :| */ - icon_id = "stock_smiley-8"; - break; - case EMPATHY_SMILEY_TOUNGE: /* :p */ - icon_id = "stock_smiley-10"; - break; - case EMPATHY_SMILEY_SHOCKED: /* :o */ - icon_id = "stock_smiley-5"; - break; - case EMPATHY_SMILEY_COOL: /* 8) */ - icon_id = "stock_smiley-15"; - break; - case EMPATHY_SMILEY_SORRY: /* *| */ - icon_id = "stock_smiley-12"; - break; - case EMPATHY_SMILEY_KISS: /* :* */ - icon_id = "stock_smiley-13"; - break; - case EMPATHY_SMILEY_SHUTUP: /* :# */ - icon_id = "stock_smiley-14"; - break; - case EMPATHY_SMILEY_YAWN: /* |O */ - icon_id = ""; - break; - case EMPATHY_SMILEY_CONFUSED: /* :$ */ - icon_id = "stock_smiley-17"; - break; - case EMPATHY_SMILEY_ANGEL: /* O) */ - icon_id = "stock_smiley-18"; - break; - case EMPATHY_SMILEY_OOOH: /* :x */ - icon_id = "stock_smiley-19"; - break; - case EMPATHY_SMILEY_LOOKAWAY: /* *) */ - icon_id = "stock_smiley-20"; - break; - case EMPATHY_SMILEY_BLUSH: /* *S */ - icon_id = "stock_smiley-23"; - break; - case EMPATHY_SMILEY_COOLBIGSMILE: /* 8D */ - icon_id = "stock_smiley-25"; - break; - case EMPATHY_SMILEY_ANGRY: /* :@ */ - icon_id = "stock_smiley-16"; - break; - case EMPATHY_SMILEY_BOSS: /* @) */ - icon_id = "stock_smiley-21"; - break; - case EMPATHY_SMILEY_MONKEY: /* #) */ - icon_id = "stock_smiley-22"; - break; - case EMPATHY_SMILEY_SILLY: /* O) */ - icon_id = "stock_smiley-24"; - break; - case EMPATHY_SMILEY_SICK: /* +o( */ - icon_id = "stock_smiley-26"; - break; - - default: - g_assert_not_reached (); - icon_id = NULL; - } - - - return empathy_pixbuf_from_icon_name (icon_id, icon_size); -} - const gchar * empathy_icon_name_from_account (McAccount *account) { diff --git a/libempathy-gtk/empathy-ui-utils.h b/libempathy-gtk/empathy-ui-utils.h index a513a30bf..3a8b896cb 100644 --- a/libempathy-gtk/empathy-ui-utils.h +++ b/libempathy-gtk/empathy-ui-utils.h @@ -69,8 +69,6 @@ void empathy_glade_setup_size_group (GladeXML * /* Pixbufs */ GdkPixbuf * empathy_pixbuf_from_icon_name (const gchar *icon_name, GtkIconSize icon_size); -GdkPixbuf * empathy_pixbuf_from_smiley (EmpathySmiley type, - GtkIconSize icon_size); const gchar * empathy_icon_name_from_account (McAccount *account); const gchar * empathy_icon_name_for_presence_state (McPresence state); const gchar * empathy_icon_name_for_presence (EmpathyPresence *presence); |