Home | History | Annotate | Download | only in text
      1 /*
      2  * Copyright (C) 2006 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 android.text;
     18 
     19 /**
     20  * InputFilters can be attached to {@link Editable}s to constrain the
     21  * changes that can be made to them.
     22  */
     23 public interface InputFilter
     24 {
     25     /**
     26      * This method is called when the buffer is going to replace the
     27      * range <code>dstart &hellip; dend</code> of <code>dest</code>
     28      * with the new text from the range <code>start &hellip; end</code>
     29      * of <code>source</code>.  Return the CharSequence that you would
     30      * like to have placed there instead, including an empty string
     31      * if appropriate, or <code>null</code> to accept the original
     32      * replacement.  Be careful to not to reject 0-length replacements,
     33      * as this is what happens when you delete text.  Also beware that
     34      * you should not attempt to make any changes to <code>dest</code>
     35      * from this method; you may only examine it for context.
     36      *
     37      * Note: If <var>source</var> is an instance of {@link Spanned} or
     38      * {@link Spannable}, the span objects in the <var>source</var> should be
     39      * copied into the filtered result (i.e. the non-null return value).
     40      * {@link TextUtils#copySpansFrom} can be used for convenience.
     41      */
     42     public CharSequence filter(CharSequence source, int start, int end,
     43                                Spanned dest, int dstart, int dend);
     44 
     45     /**
     46      * This filter will capitalize all the lower case letters that are added
     47      * through edits.
     48      */
     49     public static class AllCaps implements InputFilter {
     50         public CharSequence filter(CharSequence source, int start, int end,
     51                                    Spanned dest, int dstart, int dend) {
     52             for (int i = start; i < end; i++) {
     53                 if (Character.isLowerCase(source.charAt(i))) {
     54                     char[] v = new char[end - start];
     55                     TextUtils.getChars(source, start, end, v, 0);
     56                     String s = new String(v).toUpperCase();
     57 
     58                     if (source instanceof Spanned) {
     59                         SpannableString sp = new SpannableString(s);
     60                         TextUtils.copySpansFrom((Spanned) source,
     61                                                 start, end, null, sp, 0);
     62                         return sp;
     63                     } else {
     64                         return s;
     65                     }
     66                 }
     67             }
     68 
     69             return null; // keep original
     70         }
     71     }
     72 
     73     /**
     74      * This filter will constrain edits not to make the length of the text
     75      * greater than the specified length.
     76      */
     77     public static class LengthFilter implements InputFilter {
     78         public LengthFilter(int max) {
     79             mMax = max;
     80         }
     81 
     82         public CharSequence filter(CharSequence source, int start, int end,
     83                                    Spanned dest, int dstart, int dend) {
     84             int keep = mMax - (dest.length() - (dend - dstart));
     85 
     86             if (keep <= 0) {
     87                 return "";
     88             } else if (keep >= end - start) {
     89                 return null; // keep original
     90             } else {
     91                 keep += start;
     92                 if (Character.isHighSurrogate(source.charAt(keep - 1))) {
     93                     --keep;
     94                     if (keep == start) {
     95                         return "";
     96                     }
     97                 }
     98                 return source.subSequence(start, keep);
     99             }
    100         }
    101 
    102         private int mMax;
    103     }
    104 }
    105