src/com/android/mms/util/SmileyParser.java
changeset 1007 c3598834218b
equal deleted inserted replaced
1006:246d10f27fc6 1007:c3598834218b
       
     1 /*
       
     2  * Copyright (C) 2009 The Android Open Source Project
       
     3  *
       
     4  * Licensed under the Apache License, Version 2.0 (the "License");
       
     5  * you may not use this file except in compliance with the License.
       
     6  * You may obtain a copy of the License at
       
     7  *
       
     8  *      http://www.apache.org/licenses/LICENSE-2.0
       
     9  *
       
    10  * Unless required by applicable law or agreed to in writing, software
       
    11  * distributed under the License is distributed on an "AS IS" BASIS,
       
    12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
       
    13  * See the License for the specific language governing permissions and
       
    14  * limitations under the License.
       
    15  */
       
    16 
       
    17 package com.android.mms.util;
       
    18 
       
    19 import java.util.HashMap;
       
    20 import java.util.regex.Matcher;
       
    21 import java.util.regex.Pattern;
       
    22 
       
    23 import android.content.Context;
       
    24 import android.text.Spannable;
       
    25 import android.text.SpannableStringBuilder;
       
    26 import android.text.style.ImageSpan;
       
    27 
       
    28 import com.beem.project.beem.R;
       
    29 
       
    30 /**
       
    31  * A class for annotating a CharSequence with spans to convert textual emoticons
       
    32  * to graphical ones.
       
    33  */
       
    34 public class SmileyParser {
       
    35     // Singleton stuff
       
    36     private static SmileyParser sInstance;
       
    37     public static SmileyParser getInstance() { return sInstance; }
       
    38     public static void init(Context context) {
       
    39         sInstance = new SmileyParser(context);
       
    40     }
       
    41 
       
    42     private final Context mContext;
       
    43     private final String[] mSmileyTexts;
       
    44     private final Pattern mPattern;
       
    45     private final HashMap<String, Integer> mSmileyToRes;
       
    46 
       
    47     private SmileyParser(Context context) {
       
    48         mContext = context;
       
    49         mSmileyTexts = mContext.getResources().getStringArray(DEFAULT_SMILEY_TEXTS);
       
    50         mSmileyToRes = buildSmileyToRes();
       
    51         mPattern = buildPattern();
       
    52     }
       
    53 
       
    54     static class Smileys {
       
    55         private static final int[] sIconIds = {
       
    56             R.drawable.emo_im_happy,
       
    57             R.drawable.emo_im_sad,
       
    58             R.drawable.emo_im_winking,
       
    59             R.drawable.emo_im_tongue_sticking_out,
       
    60             R.drawable.emo_im_surprised,
       
    61             R.drawable.emo_im_kissing,
       
    62             R.drawable.emo_im_yelling,
       
    63             R.drawable.emo_im_cool,
       
    64             R.drawable.emo_im_money_mouth,
       
    65             R.drawable.emo_im_foot_in_mouth,
       
    66             R.drawable.emo_im_embarrassed,
       
    67             R.drawable.emo_im_angel,
       
    68             R.drawable.emo_im_undecided,
       
    69             R.drawable.emo_im_crying,
       
    70             R.drawable.emo_im_lips_are_sealed,
       
    71             R.drawable.emo_im_laughing,
       
    72             R.drawable.emo_im_wtf,
       
    73             R.drawable.emo_im_heart,
       
    74             R.drawable.emo_im_mad,
       
    75             R.drawable.emo_im_smirk,
       
    76             R.drawable.emo_im_pokerface
       
    77         };
       
    78 
       
    79         public static int HAPPY = 0;
       
    80         public static int SAD = 1;
       
    81         public static int WINKING = 2;
       
    82         public static int TONGUE_STICKING_OUT = 3;
       
    83         public static int SURPRISED = 4;
       
    84         public static int KISSING = 5;
       
    85         public static int YELLING = 6;
       
    86         public static int COOL = 7;
       
    87         public static int MONEY_MOUTH = 8;
       
    88         public static int FOOT_IN_MOUTH = 9;
       
    89         public static int EMBARRASSED = 10;
       
    90         public static int ANGEL = 11;
       
    91         public static int UNDECIDED = 12;
       
    92         public static int CRYING = 13;
       
    93         public static int LIPS_ARE_SEALED = 14;
       
    94         public static int LAUGHING = 15;
       
    95         public static int WTF = 16;
       
    96         public static int MAD = 17;
       
    97         public static int HEART = 18;
       
    98         public static int SMIRK = 19;
       
    99         public static int POKERFACE = 20;
       
   100 
       
   101         public static int getSmileyResource(int which) {
       
   102             return sIconIds[which];
       
   103         }
       
   104     }
       
   105 
       
   106     // NOTE: if you change anything about this array, you must make the corresponding change
       
   107     // to the string arrays: default_smiley_texts and default_smiley_names in res/values/arrays.xml
       
   108     public static final int[] DEFAULT_SMILEY_RES_IDS = {
       
   109         Smileys.getSmileyResource(Smileys.HAPPY),                //  0
       
   110         Smileys.getSmileyResource(Smileys.SAD),                  //  1
       
   111         Smileys.getSmileyResource(Smileys.WINKING),              //  2
       
   112         Smileys.getSmileyResource(Smileys.TONGUE_STICKING_OUT),  //  3
       
   113         Smileys.getSmileyResource(Smileys.SURPRISED),            //  4
       
   114         Smileys.getSmileyResource(Smileys.KISSING),              //  5
       
   115         Smileys.getSmileyResource(Smileys.YELLING),              //  6
       
   116         Smileys.getSmileyResource(Smileys.COOL),                 //  7
       
   117         Smileys.getSmileyResource(Smileys.MONEY_MOUTH),          //  8
       
   118         Smileys.getSmileyResource(Smileys.FOOT_IN_MOUTH),        //  9
       
   119         Smileys.getSmileyResource(Smileys.EMBARRASSED),          //  10
       
   120         Smileys.getSmileyResource(Smileys.ANGEL),                //  11
       
   121         Smileys.getSmileyResource(Smileys.UNDECIDED),            //  12
       
   122         Smileys.getSmileyResource(Smileys.CRYING),               //  13
       
   123         Smileys.getSmileyResource(Smileys.LIPS_ARE_SEALED),      //  14
       
   124         Smileys.getSmileyResource(Smileys.LAUGHING),             //  15
       
   125         Smileys.getSmileyResource(Smileys.WTF),                  //  16
       
   126         Smileys.getSmileyResource(Smileys.MAD),                  //  17
       
   127         Smileys.getSmileyResource(Smileys.HEART),                //  18
       
   128         Smileys.getSmileyResource(Smileys.SMIRK),                //  19
       
   129         Smileys.getSmileyResource(Smileys.POKERFACE),            //  20
       
   130     };
       
   131 
       
   132     public static final int DEFAULT_SMILEY_TEXTS = R.array.default_smiley_texts;
       
   133     public static final int DEFAULT_SMILEY_NAMES = R.array.default_smiley_names;
       
   134 
       
   135     /**
       
   136      * Builds the hashtable we use for mapping the string version
       
   137      * of a smiley (e.g. ":-)") to a resource ID for the icon version.
       
   138      */
       
   139     private HashMap<String, Integer> buildSmileyToRes() {
       
   140         if (DEFAULT_SMILEY_RES_IDS.length != mSmileyTexts.length) {
       
   141             // Throw an exception if someone updated DEFAULT_SMILEY_RES_IDS
       
   142             // and failed to update arrays.xml
       
   143             throw new IllegalStateException("Smiley resource ID/text mismatch");
       
   144         }
       
   145 
       
   146         HashMap<String, Integer> smileyToRes =
       
   147                             new HashMap<String, Integer>(mSmileyTexts.length);
       
   148         for (int i = 0; i < mSmileyTexts.length; i++) {
       
   149             smileyToRes.put(mSmileyTexts[i], DEFAULT_SMILEY_RES_IDS[i]);
       
   150         }
       
   151 
       
   152         return smileyToRes;
       
   153     }
       
   154 
       
   155     /**
       
   156      * Builds the regular expression we use to find smileys in {@link #addSmileySpans}.
       
   157      */
       
   158     private Pattern buildPattern() {
       
   159         // Set the StringBuilder capacity with the assumption that the average
       
   160         // smiley is 3 characters long.
       
   161         StringBuilder patternString = new StringBuilder(mSmileyTexts.length * 3);
       
   162 
       
   163         // Build a regex that looks like (:-)|:-(|...), but escaping the smilies
       
   164         // properly so they will be interpreted literally by the regex matcher.
       
   165         patternString.append('(');
       
   166         for (String s : mSmileyTexts) {
       
   167             patternString.append(Pattern.quote(s));
       
   168             patternString.append('|');
       
   169         }
       
   170         // Replace the extra '|' with a ')'
       
   171         patternString.replace(patternString.length() - 1, patternString.length(), ")");
       
   172 
       
   173         return Pattern.compile(patternString.toString());
       
   174     }
       
   175 
       
   176 
       
   177     /**
       
   178      * Adds ImageSpans to a CharSequence that replace textual emoticons such
       
   179      * as :-) with a graphical version.
       
   180      *
       
   181      * @param text A CharSequence possibly containing emoticons
       
   182      * @return A CharSequence annotated with ImageSpans covering any
       
   183      *         recognized emoticons.
       
   184      */
       
   185     public CharSequence addSmileySpans(CharSequence text) {
       
   186         SpannableStringBuilder builder = new SpannableStringBuilder(text);
       
   187 
       
   188         Matcher matcher = mPattern.matcher(text);
       
   189         while (matcher.find()) {
       
   190             int resId = mSmileyToRes.get(matcher.group());
       
   191             builder.setSpan(new ImageSpan(mContext, resId),
       
   192                             matcher.start(), matcher.end(),
       
   193                             Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
       
   194         }
       
   195 
       
   196         return builder;
       
   197     }
       
   198 }
       
   199 
       
   200