diff -r 7d6f2526244a -r 197a85a35cba app/src/main/java/com/android/mms/util/SmileyParser.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/app/src/main/java/com/android/mms/util/SmileyParser.java Sun Mar 15 18:03:03 2015 +0100 @@ -0,0 +1,200 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.mms.util; + +import java.util.HashMap; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import android.content.Context; +import android.text.Spannable; +import android.text.SpannableStringBuilder; +import android.text.style.ImageSpan; + +import com.beem.project.beem.R; + +/** + * A class for annotating a CharSequence with spans to convert textual emoticons + * to graphical ones. + */ +public class SmileyParser { + // Singleton stuff + private static SmileyParser sInstance; + public static SmileyParser getInstance() { return sInstance; } + public static void init(Context context) { + sInstance = new SmileyParser(context); + } + + private final Context mContext; + private final String[] mSmileyTexts; + private final Pattern mPattern; + private final HashMap mSmileyToRes; + + private SmileyParser(Context context) { + mContext = context; + mSmileyTexts = mContext.getResources().getStringArray(DEFAULT_SMILEY_TEXTS); + mSmileyToRes = buildSmileyToRes(); + mPattern = buildPattern(); + } + + static class Smileys { + private static final int[] sIconIds = { + R.drawable.emo_im_happy, + R.drawable.emo_im_sad, + R.drawable.emo_im_winking, + R.drawable.emo_im_tongue_sticking_out, + R.drawable.emo_im_surprised, + R.drawable.emo_im_kissing, + R.drawable.emo_im_yelling, + R.drawable.emo_im_cool, + R.drawable.emo_im_money_mouth, + R.drawable.emo_im_foot_in_mouth, + R.drawable.emo_im_embarrassed, + R.drawable.emo_im_angel, + R.drawable.emo_im_undecided, + R.drawable.emo_im_crying, + R.drawable.emo_im_lips_are_sealed, + R.drawable.emo_im_laughing, + R.drawable.emo_im_wtf, + R.drawable.emo_im_heart, + R.drawable.emo_im_mad, + R.drawable.emo_im_smirk, + R.drawable.emo_im_pokerface + }; + + public static int HAPPY = 0; + public static int SAD = 1; + public static int WINKING = 2; + public static int TONGUE_STICKING_OUT = 3; + public static int SURPRISED = 4; + public static int KISSING = 5; + public static int YELLING = 6; + public static int COOL = 7; + public static int MONEY_MOUTH = 8; + public static int FOOT_IN_MOUTH = 9; + public static int EMBARRASSED = 10; + public static int ANGEL = 11; + public static int UNDECIDED = 12; + public static int CRYING = 13; + public static int LIPS_ARE_SEALED = 14; + public static int LAUGHING = 15; + public static int WTF = 16; + public static int MAD = 17; + public static int HEART = 18; + public static int SMIRK = 19; + public static int POKERFACE = 20; + + public static int getSmileyResource(int which) { + return sIconIds[which]; + } + } + + // NOTE: if you change anything about this array, you must make the corresponding change + // to the string arrays: default_smiley_texts and default_smiley_names in res/values/arrays.xml + public static final int[] DEFAULT_SMILEY_RES_IDS = { + Smileys.getSmileyResource(Smileys.HAPPY), // 0 + Smileys.getSmileyResource(Smileys.SAD), // 1 + Smileys.getSmileyResource(Smileys.WINKING), // 2 + Smileys.getSmileyResource(Smileys.TONGUE_STICKING_OUT), // 3 + Smileys.getSmileyResource(Smileys.SURPRISED), // 4 + Smileys.getSmileyResource(Smileys.KISSING), // 5 + Smileys.getSmileyResource(Smileys.YELLING), // 6 + Smileys.getSmileyResource(Smileys.COOL), // 7 + Smileys.getSmileyResource(Smileys.MONEY_MOUTH), // 8 + Smileys.getSmileyResource(Smileys.FOOT_IN_MOUTH), // 9 + Smileys.getSmileyResource(Smileys.EMBARRASSED), // 10 + Smileys.getSmileyResource(Smileys.ANGEL), // 11 + Smileys.getSmileyResource(Smileys.UNDECIDED), // 12 + Smileys.getSmileyResource(Smileys.CRYING), // 13 + Smileys.getSmileyResource(Smileys.LIPS_ARE_SEALED), // 14 + Smileys.getSmileyResource(Smileys.LAUGHING), // 15 + Smileys.getSmileyResource(Smileys.WTF), // 16 + Smileys.getSmileyResource(Smileys.MAD), // 17 + Smileys.getSmileyResource(Smileys.HEART), // 18 + Smileys.getSmileyResource(Smileys.SMIRK), // 19 + Smileys.getSmileyResource(Smileys.POKERFACE), // 20 + }; + + public static final int DEFAULT_SMILEY_TEXTS = R.array.default_smiley_texts; + public static final int DEFAULT_SMILEY_NAMES = R.array.default_smiley_names; + + /** + * Builds the hashtable we use for mapping the string version + * of a smiley (e.g. ":-)") to a resource ID for the icon version. + */ + private HashMap buildSmileyToRes() { + if (DEFAULT_SMILEY_RES_IDS.length != mSmileyTexts.length) { + // Throw an exception if someone updated DEFAULT_SMILEY_RES_IDS + // and failed to update arrays.xml + throw new IllegalStateException("Smiley resource ID/text mismatch"); + } + + HashMap smileyToRes = + new HashMap(mSmileyTexts.length); + for (int i = 0; i < mSmileyTexts.length; i++) { + smileyToRes.put(mSmileyTexts[i], DEFAULT_SMILEY_RES_IDS[i]); + } + + return smileyToRes; + } + + /** + * Builds the regular expression we use to find smileys in {@link #addSmileySpans}. + */ + private Pattern buildPattern() { + // Set the StringBuilder capacity with the assumption that the average + // smiley is 3 characters long. + StringBuilder patternString = new StringBuilder(mSmileyTexts.length * 3); + + // Build a regex that looks like (:-)|:-(|...), but escaping the smilies + // properly so they will be interpreted literally by the regex matcher. + patternString.append('('); + for (String s : mSmileyTexts) { + patternString.append(Pattern.quote(s)); + patternString.append('|'); + } + // Replace the extra '|' with a ')' + patternString.replace(patternString.length() - 1, patternString.length(), ")"); + + return Pattern.compile(patternString.toString()); + } + + + /** + * Adds ImageSpans to a CharSequence that replace textual emoticons such + * as :-) with a graphical version. + * + * @param text A CharSequence possibly containing emoticons + * @return A CharSequence annotated with ImageSpans covering any + * recognized emoticons. + */ + public CharSequence addSmileySpans(CharSequence text) { + SpannableStringBuilder builder = new SpannableStringBuilder(text); + + Matcher matcher = mPattern.matcher(text); + while (matcher.find()) { + int resId = mSmileyToRes.get(matcher.group()); + builder.setSpan(new ImageSpan(mContext, resId), + matcher.start(), matcher.end(), + Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); + } + + return builder; + } +} + +