19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2006 The Android Open Source Project
39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License.
69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at
79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and
149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License.
159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.text;
189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**
209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * InputFilters can be attached to {@link Editable}s to constrain the
219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * changes that can be made to them.
229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic interface InputFilter
249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This method is called when the buffer is going to replace the
279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * range <code>dstart &hellip; dend</code> of <code>dest</code>
289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * with the new text from the range <code>start &hellip; end</code>
299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * of <code>source</code>.  Return the CharSequence that you would
309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * like to have placed there instead, including an empty string
319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * if appropriate, or <code>null</code> to accept the original
329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * replacement.  Be careful to not to reject 0-length replacements,
339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * as this is what happens when you delete text.  Also beware that
349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * you should not attempt to make any changes to <code>dest</code>
359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * from this method; you may only examine it for context.
369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Note: If <var>source</var> is an instance of {@link Spanned} or
389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link Spannable}, the span objects in the <var>source</var> should be
399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * copied into the filtered result (i.e. the non-null return value).
409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link TextUtils#copySpansFrom} can be used for convenience.
419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public CharSequence filter(CharSequence source, int start, int end,
439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                               Spanned dest, int dstart, int dend);
449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This filter will capitalize all the lower case letters that are added
479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * through edits.
489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static class AllCaps implements InputFilter {
509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public CharSequence filter(CharSequence source, int start, int end,
519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                   Spanned dest, int dstart, int dend) {
529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            for (int i = start; i < end; i++) {
539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (Character.isLowerCase(source.charAt(i))) {
549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    char[] v = new char[end - start];
559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    TextUtils.getChars(source, start, end, v, 0);
569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    String s = new String(v).toUpperCase();
579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (source instanceof Spanned) {
599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        SpannableString sp = new SpannableString(s);
609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        TextUtils.copySpansFrom((Spanned) source,
619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                                start, end, null, sp, 0);
629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        return sp;
639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    } else {
649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        return s;
659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return null; // keep original
709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This filter will constrain edits not to make the length of the text
759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * greater than the specified length.
769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static class LengthFilter implements InputFilter {
78029942f77d05ed3d20256403652b220c83dad6e1Alan Viverette        private final int mMax;
79029942f77d05ed3d20256403652b220c83dad6e1Alan Viverette
809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public LengthFilter(int max) {
819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mMax = max;
829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
84029942f77d05ed3d20256403652b220c83dad6e1Alan Viverette        public CharSequence filter(CharSequence source, int start, int end, Spanned dest,
85029942f77d05ed3d20256403652b220c83dad6e1Alan Viverette                int dstart, int dend) {
869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int keep = mMax - (dest.length() - (dend - dstart));
879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (keep <= 0) {
889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return "";
899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (keep >= end - start) {
909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return null; // keep original
919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
922f0f44212fc1e86bd7bd54431bf6a0cd62aa093cIshibashi Takako                keep += start;
932f0f44212fc1e86bd7bd54431bf6a0cd62aa093cIshibashi Takako                if (Character.isHighSurrogate(source.charAt(keep - 1))) {
942f0f44212fc1e86bd7bd54431bf6a0cd62aa093cIshibashi Takako                    --keep;
952f0f44212fc1e86bd7bd54431bf6a0cd62aa093cIshibashi Takako                    if (keep == start) {
962f0f44212fc1e86bd7bd54431bf6a0cd62aa093cIshibashi Takako                        return "";
972f0f44212fc1e86bd7bd54431bf6a0cd62aa093cIshibashi Takako                    }
982f0f44212fc1e86bd7bd54431bf6a0cd62aa093cIshibashi Takako                }
992f0f44212fc1e86bd7bd54431bf6a0cd62aa093cIshibashi Takako                return source.subSequence(start, keep);
1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
103029942f77d05ed3d20256403652b220c83dad6e1Alan Viverette        /**
104029942f77d05ed3d20256403652b220c83dad6e1Alan Viverette         * @return the maximum length enforced by this input filter
105029942f77d05ed3d20256403652b220c83dad6e1Alan Viverette         */
106029942f77d05ed3d20256403652b220c83dad6e1Alan Viverette        public int getMax() {
107029942f77d05ed3d20256403652b220c83dad6e1Alan Viverette            return mMax;
108029942f77d05ed3d20256403652b220c83dad6e1Alan Viverette        }
1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
111