Home | History | Annotate | Download | only in latin
      1 /*
      2  * Copyright (C) 2012 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.inputmethod.latin;
     18 
     19 import static com.android.inputmethod.latin.Constants.Subtype.KEYBOARD_MODE;
     20 import static com.android.inputmethod.latin.Constants.Subtype.ExtraValue.IS_ADDITIONAL_SUBTYPE;
     21 import static com.android.inputmethod.latin.Constants.Subtype.ExtraValue.KEYBOARD_LAYOUT_SET;
     22 import static com.android.inputmethod.latin.Constants.Subtype.ExtraValue.UNTRANSLATABLE_STRING_IN_SUBTYPE_NAME;
     23 
     24 import android.os.Build;
     25 import android.text.TextUtils;
     26 import android.view.inputmethod.InputMethodSubtype;
     27 
     28 import java.util.ArrayList;
     29 
     30 public final class AdditionalSubtype {
     31     private static final InputMethodSubtype[] EMPTY_SUBTYPE_ARRAY = new InputMethodSubtype[0];
     32 
     33     private AdditionalSubtype() {
     34         // This utility class is not publicly instantiable.
     35     }
     36 
     37     public static boolean isAdditionalSubtype(final InputMethodSubtype subtype) {
     38         return subtype.containsExtraValueKey(IS_ADDITIONAL_SUBTYPE);
     39     }
     40 
     41     private static final String LOCALE_AND_LAYOUT_SEPARATOR = ":";
     42     private static final String PREF_SUBTYPE_SEPARATOR = ";";
     43 
     44     public static InputMethodSubtype createAdditionalSubtype(final String localeString,
     45             final String keyboardLayoutSetName, final String extraValue) {
     46         final String layoutExtraValue = KEYBOARD_LAYOUT_SET + "=" + keyboardLayoutSetName;
     47         final String layoutDisplayNameExtraValue;
     48         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN
     49                 && SubtypeLocale.isExceptionalLocale(localeString)) {
     50             final String layoutDisplayName = SubtypeLocale.getKeyboardLayoutSetDisplayName(
     51                     keyboardLayoutSetName);
     52             layoutDisplayNameExtraValue = StringUtils.appendToCsvIfNotExists(
     53                     UNTRANSLATABLE_STRING_IN_SUBTYPE_NAME + "=" + layoutDisplayName, extraValue);
     54         } else {
     55             layoutDisplayNameExtraValue = extraValue;
     56         }
     57         final String additionalSubtypeExtraValue = StringUtils.appendToCsvIfNotExists(
     58                 IS_ADDITIONAL_SUBTYPE, layoutDisplayNameExtraValue);
     59         final int nameId = SubtypeLocale.getSubtypeNameId(localeString, keyboardLayoutSetName);
     60         return new InputMethodSubtype(nameId, R.drawable.ic_subtype_keyboard,
     61                 localeString, KEYBOARD_MODE,
     62                 layoutExtraValue + "," + additionalSubtypeExtraValue, false, false);
     63     }
     64 
     65     public static String getPrefSubtype(final InputMethodSubtype subtype) {
     66         final String localeString = subtype.getLocale();
     67         final String keyboardLayoutSetName = SubtypeLocale.getKeyboardLayoutSetName(subtype);
     68         final String layoutExtraValue = KEYBOARD_LAYOUT_SET + "=" + keyboardLayoutSetName;
     69         final String extraValue = StringUtils.removeFromCsvIfExists(layoutExtraValue,
     70                 StringUtils.removeFromCsvIfExists(IS_ADDITIONAL_SUBTYPE, subtype.getExtraValue()));
     71         final String basePrefSubtype = localeString + LOCALE_AND_LAYOUT_SEPARATOR
     72                 + keyboardLayoutSetName;
     73         return extraValue.isEmpty() ? basePrefSubtype
     74                 : basePrefSubtype + LOCALE_AND_LAYOUT_SEPARATOR + extraValue;
     75     }
     76 
     77     public static InputMethodSubtype createAdditionalSubtype(final String prefSubtype) {
     78         final String elems[] = prefSubtype.split(LOCALE_AND_LAYOUT_SEPARATOR);
     79         if (elems.length < 2 || elems.length > 3) {
     80             throw new RuntimeException("Unknown additional subtype specified: " + prefSubtype);
     81         }
     82         final String localeString = elems[0];
     83         final String keyboardLayoutSetName = elems[1];
     84         final String extraValue = (elems.length == 3) ? elems[2] : null;
     85         return createAdditionalSubtype(localeString, keyboardLayoutSetName, extraValue);
     86     }
     87 
     88     public static InputMethodSubtype[] createAdditionalSubtypesArray(final String prefSubtypes) {
     89         if (TextUtils.isEmpty(prefSubtypes)) {
     90             return EMPTY_SUBTYPE_ARRAY;
     91         }
     92         final String[] prefSubtypeArray = prefSubtypes.split(PREF_SUBTYPE_SEPARATOR);
     93         final ArrayList<InputMethodSubtype> subtypesList =
     94                 CollectionUtils.newArrayList(prefSubtypeArray.length);
     95         for (final String prefSubtype : prefSubtypeArray) {
     96             final InputMethodSubtype subtype = createAdditionalSubtype(prefSubtype);
     97             if (subtype.getNameResId() == SubtypeLocale.UNKNOWN_KEYBOARD_LAYOUT) {
     98                 // Skip unknown keyboard layout subtype. This may happen when predefined keyboard
     99                 // layout has been removed.
    100                 continue;
    101             }
    102             subtypesList.add(subtype);
    103         }
    104         return subtypesList.toArray(new InputMethodSubtype[subtypesList.size()]);
    105     }
    106 
    107     public static String createPrefSubtypes(final InputMethodSubtype[] subtypes) {
    108         if (subtypes == null || subtypes.length == 0) {
    109             return "";
    110         }
    111         final StringBuilder sb = new StringBuilder();
    112         for (final InputMethodSubtype subtype : subtypes) {
    113             if (sb.length() > 0) {
    114                 sb.append(PREF_SUBTYPE_SEPARATOR);
    115             }
    116             sb.append(getPrefSubtype(subtype));
    117         }
    118         return sb.toString();
    119     }
    120 
    121     public static String createPrefSubtypes(final String[] prefSubtypes) {
    122         if (prefSubtypes == null || prefSubtypes.length == 0) {
    123             return "";
    124         }
    125         final StringBuilder sb = new StringBuilder();
    126         for (final String prefSubtype : prefSubtypes) {
    127             if (sb.length() > 0) {
    128                 sb.append(PREF_SUBTYPE_SEPARATOR);
    129             }
    130             sb.append(prefSubtype);
    131         }
    132         return sb.toString();
    133     }
    134 }
    135