/** * Copyright (c) 2013, Redsolution LTD. All rights reserved. * * This file is part of Xabber project; you can redistribute it and/or * modify it under the terms of the GNU General Public License, Version 3. * * Xabber 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, see http://www.gnu.org/licenses/. */ package com.xabber.android.utils; import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; import java.util.regex.Matcher; import java.util.regex.Pattern; import android.content.Context; import android.graphics.drawable.Drawable; import android.text.Spannable; import android.text.Spannable.Factory; import android.text.style.DynamicDrawableSpan; import android.text.style.ImageSpan; import android.widget.TextView; import com.xabber.android.data.SettingsManager; import com.xabber.android.R; /** * Emoticons. * * @author alexander.ivanov */ public class Emoticons { public static final Map<Pattern, Integer> ANDROID_EMOTICONS = new HashMap<>(); public static final Map<Pattern, Integer> NONE_EMOTICONS = new HashMap<>(); private static final Factory spannableFactory = Spannable.Factory .getInstance(); static { addPattern(ANDROID_EMOTICONS, ":)", R.drawable.emo_im_happy); addPattern(ANDROID_EMOTICONS, ":-)", R.drawable.emo_im_happy); addPattern(ANDROID_EMOTICONS, "=)", R.drawable.emo_im_happy); addPattern(ANDROID_EMOTICONS, ":(", R.drawable.emo_im_sad); addPattern(ANDROID_EMOTICONS, ":-(", R.drawable.emo_im_sad); addPattern(ANDROID_EMOTICONS, ";)", R.drawable.emo_im_winking); addPattern(ANDROID_EMOTICONS, ";-)", R.drawable.emo_im_winking); addPattern(ANDROID_EMOTICONS, ":P", R.drawable.emo_im_tongue_sticking_out); addPattern(ANDROID_EMOTICONS, ":-P", R.drawable.emo_im_tongue_sticking_out); addPattern(ANDROID_EMOTICONS, "=-O", R.drawable.emo_im_surprised); addPattern(ANDROID_EMOTICONS, ":*", R.drawable.emo_im_kissing); addPattern(ANDROID_EMOTICONS, ":-*", R.drawable.emo_im_kissing); addPattern(ANDROID_EMOTICONS, ":O", R.drawable.emo_im_wtf); addPattern(ANDROID_EMOTICONS, ":-O", R.drawable.emo_im_wtf); addPattern(ANDROID_EMOTICONS, "B)", R.drawable.emo_im_cool); addPattern(ANDROID_EMOTICONS, "B-)", R.drawable.emo_im_cool); addPattern(ANDROID_EMOTICONS, "8)", R.drawable.emo_im_cool); addPattern(ANDROID_EMOTICONS, "8-)", R.drawable.emo_im_cool); addPattern(ANDROID_EMOTICONS, ":-!", R.drawable.emo_im_foot_in_mouth); addPattern(ANDROID_EMOTICONS, ":-[", R.drawable.emo_im_embarrassed); addPattern(ANDROID_EMOTICONS, "O:)", R.drawable.emo_im_angel); addPattern(ANDROID_EMOTICONS, "O:-)", R.drawable.emo_im_angel); addPattern(ANDROID_EMOTICONS, ":\\", R.drawable.emo_im_undecided); addPattern(ANDROID_EMOTICONS, ":-\\", R.drawable.emo_im_undecided); addPattern(ANDROID_EMOTICONS, ":'(", R.drawable.emo_im_crying); addPattern(ANDROID_EMOTICONS, ":D", R.drawable.emo_im_laughing); addPattern(ANDROID_EMOTICONS, ":-D", R.drawable.emo_im_laughing); addPattern(ANDROID_EMOTICONS, "O_o", R.drawable.emo_im_wtf); addPattern(ANDROID_EMOTICONS, "o_O", R.drawable.emo_im_wtf); addPattern(ANDROID_EMOTICONS, ">:O", R.drawable.emo_im_yelling); addPattern(ANDROID_EMOTICONS, ">:0", R.drawable.emo_im_yelling); addPattern(ANDROID_EMOTICONS, ":S", R.drawable.emo_im_lips_are_sealed); addPattern(ANDROID_EMOTICONS, ":-S", R.drawable.emo_im_lips_are_sealed); addPattern(ANDROID_EMOTICONS, ":-$", R.drawable.emo_im_lips_are_sealed); } private static void addPattern(Map<Pattern, Integer> map, String smile, int resource) { map.put(Pattern.compile(Pattern.quote(smile)), resource); } private Emoticons() { } /** * @param text * @return new spannable. */ public static Spannable newSpannable(CharSequence text) { return spannableFactory.newSpannable(text); } /** * @param context * @param spannable * @return Whether smiles have been added into <code>spannable</code>. */ public static boolean getSmiledText(Context context, Spannable spannable, TextView textView) { boolean hasChanges = false; Map<Pattern, Integer> emoticons = SettingsManager.interfaceSmiles(); for (Entry<Pattern, Integer> entry : emoticons.entrySet()) { Matcher matcher = entry.getKey().matcher(spannable); while (matcher.find()) { boolean set = true; for (ImageSpan span : spannable.getSpans(matcher.start(), matcher.end(), ImageSpan.class)) if (spannable.getSpanStart(span) >= matcher.start() && spannable.getSpanEnd(span) <= matcher.end()) { spannable.removeSpan(span); } else { set = false; break; } if (set) { Drawable myIcon = context.getResources().getDrawable(entry.getValue()); myIcon.setBounds(0, 0, textView.getLineHeight(), textView.getLineHeight()); spannable.setSpan(new ImageSpan(myIcon, DynamicDrawableSpan.ALIGN_BOTTOM), matcher.start(), matcher.end(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); hasChanges = true; } } } return hasChanges; } /** * @param context * @param text * @return New spannable with added smiles if needed. */ public static Spannable getSmiledText(Context context, CharSequence text, TextView textView) { Spannable spannable = spannableFactory.newSpannable(text); getSmiledText(context, spannable, textView); return spannable; } }