diff options
author | Alice Yang <alice@google.com> | 2013-03-13 17:18:52 -0700 |
---|---|---|
committer | Alice Yang <alice@google.com> | 2013-03-13 17:18:52 -0700 |
commit | 4aa10b1bc14290397756b05e97ff9bc8a3b7564b (patch) | |
tree | 0a82e828153f83190ab6b640644889ee56316c8e /chips/src/com | |
parent | 5ee4f94a5a4edfd18a69fbdc89786caec4cf3371 (diff) | |
parent | f1d0416bad440e015c8f09c3827acc19d939d71a (diff) | |
download | android_frameworks_ex-4aa10b1bc14290397756b05e97ff9bc8a3b7564b.tar.gz android_frameworks_ex-4aa10b1bc14290397756b05e97ff9bc8a3b7564b.tar.bz2 android_frameworks_ex-4aa10b1bc14290397756b05e97ff9bc8a3b7564b.zip |
Merge remote-tracking branch 'goog/jb-ub-mail-ur9' into merge
Merge UR8 into MR2.
Change-Id: Ia04852cf84c05ab2ee4898662d347a06d40e5f11
Diffstat (limited to 'chips/src/com')
-rw-r--r-- | chips/src/com/android/ex/chips/BaseRecipientAdapter.java | 18 | ||||
-rw-r--r-- | chips/src/com/android/ex/chips/InvisibleRecipientChip.java | 155 | ||||
-rw-r--r-- | chips/src/com/android/ex/chips/RecipientAlternatesAdapter.java | 9 | ||||
-rw-r--r-- | chips/src/com/android/ex/chips/RecipientEditTextView.java | 343 | ||||
-rw-r--r-- | chips/src/com/android/ex/chips/RecipientEntry.java | 9 | ||||
-rw-r--r-- | chips/src/com/android/ex/chips/SingleRecipientArrayAdapter.java | 4 | ||||
-rw-r--r-- | chips/src/com/android/ex/chips/recipientchip/BaseRecipientChip.java (renamed from chips/src/com/android/ex/chips/RecipientChip.java) | 41 | ||||
-rw-r--r-- | chips/src/com/android/ex/chips/recipientchip/DrawableRecipientChip.java | 36 | ||||
-rw-r--r-- | chips/src/com/android/ex/chips/recipientchip/InvisibleRecipientChip.java | 105 | ||||
-rw-r--r-- | chips/src/com/android/ex/chips/recipientchip/SimpleRecipientChip.java (renamed from chips/src/com/android/ex/chips/VisibleRecipientChip.java) | 76 | ||||
-rw-r--r-- | chips/src/com/android/ex/chips/recipientchip/VisibleRecipientChip.java | 99 |
11 files changed, 470 insertions, 425 deletions
diff --git a/chips/src/com/android/ex/chips/BaseRecipientAdapter.java b/chips/src/com/android/ex/chips/BaseRecipientAdapter.java index f742cf1..71b610e 100644 --- a/chips/src/com/android/ex/chips/BaseRecipientAdapter.java +++ b/chips/src/com/android/ex/chips/BaseRecipientAdapter.java @@ -234,8 +234,8 @@ public abstract class BaseRecipientAdapter extends BaseAdapter implements Filter } // We'll copy this result to mEntry in publicResults() (run in the UX thread). - final List<RecipientEntry> entries = constructEntryList(false, - entryMap, nonAggregatedEntries, existingDestinations); + final List<RecipientEntry> entries = constructEntryList( + entryMap, nonAggregatedEntries); // After having local results, check the size of results. If the results are // not enough, we search remote directories, which will take longer time. @@ -424,8 +424,7 @@ public abstract class BaseRecipientAdapter extends BaseAdapter implements Filter } // Show the list again without "waiting" message. - updateEntries(constructEntryList(false, - mEntryMap, mNonAggregatedEntries, mExistingDestinations)); + updateEntries(constructEntryList(mEntryMap, mNonAggregatedEntries)); } } @@ -482,8 +481,7 @@ public abstract class BaseRecipientAdapter extends BaseAdapter implements Filter @Override public void handleMessage(Message msg) { if (mRemainingDirectoryCount > 0) { - updateEntries(constructEntryList(true, - mEntryMap, mNonAggregatedEntries, mExistingDestinations)); + updateEntries(constructEntryList(mEntryMap, mNonAggregatedEntries)); } } @@ -634,7 +632,7 @@ public abstract class BaseRecipientAdapter extends BaseAdapter implements Filter mDelayedMessageHandler.sendDelayedLoadMessage(); } - private void putOneEntry(TemporaryEntry entry, boolean isAggregatedEntry, + private static void putOneEntry(TemporaryEntry entry, boolean isAggregatedEntry, LinkedHashMap<Long, List<RecipientEntry>> entryMap, List<RecipientEntry> nonAggregatedEntries, Set<String> existingDestinations) { @@ -675,10 +673,8 @@ public abstract class BaseRecipientAdapter extends BaseAdapter implements Filter * thread to get one from directories. */ private List<RecipientEntry> constructEntryList( - boolean showMessageIfDirectoryLoadRemaining, LinkedHashMap<Long, List<RecipientEntry>> entryMap, - List<RecipientEntry> nonAggregatedEntries, - Set<String> existingDestinations) { + List<RecipientEntry> nonAggregatedEntries) { final List<RecipientEntry> entries = new ArrayList<RecipientEntry>(); int validEntryCount = 0; for (Map.Entry<Long, List<RecipientEntry>> mapEntry : entryMap.entrySet()) { @@ -912,7 +908,7 @@ public abstract class BaseRecipientAdapter extends BaseAdapter implements Filter if (imageView != null) { imageView.setVisibility(View.VISIBLE); final byte[] photoBytes = entry.getPhotoBytes(); - if (photoBytes != null && imageView != null) { + if (photoBytes != null) { final Bitmap photo = BitmapFactory.decodeByteArray(photoBytes, 0, photoBytes.length); imageView.setImageBitmap(photo); diff --git a/chips/src/com/android/ex/chips/InvisibleRecipientChip.java b/chips/src/com/android/ex/chips/InvisibleRecipientChip.java deleted file mode 100644 index 83f7f8e..0000000 --- a/chips/src/com/android/ex/chips/InvisibleRecipientChip.java +++ /dev/null @@ -1,155 +0,0 @@ -/* - * Copyright (C) 2011 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.ex.chips; - -import android.graphics.Canvas; -import android.graphics.Paint; -import android.graphics.Rect; -import android.text.TextUtils; -import android.text.style.ReplacementSpan; - -/** - * RecipientChip defines a span that contains information relevant to a - * particular recipient. - */ -/* package */class InvisibleRecipientChip extends ReplacementSpan implements RecipientChip { - private final CharSequence mDisplay; - - private final CharSequence mValue; - - private final long mContactId; - - private final long mDataId; - - private RecipientEntry mEntry; - - private boolean mSelected = false; - - private CharSequence mOriginalText; - - /** <code>true</code> to display the original text, <code>false</code> to display nothing */ - private boolean mDisplayOriginalText = false; - - public InvisibleRecipientChip(RecipientEntry entry, int offset) { - super(); - mDisplay = entry.getDisplayName(); - mValue = entry.getDestination().trim(); - mContactId = entry.getContactId(); - mDataId = entry.getDataId(); - mEntry = entry; - } - - /** - * Set the selected state of the chip. - * @param selected - */ - public void setSelected(boolean selected) { - mSelected = selected; - } - - /** - * Return true if the chip is selected. - */ - public boolean isSelected() { - return mSelected; - } - - /** - * Get the text displayed in the chip. - */ - public CharSequence getDisplay() { - return mDisplay; - } - - /** - * Get the text value this chip represents. - */ - public CharSequence getValue() { - return mValue; - } - - /** - * Get the id of the contact associated with this chip. - */ - public long getContactId() { - return mContactId; - } - - /** - * Get the id of the data associated with this chip. - */ - public long getDataId() { - return mDataId; - } - - /** - * Get associated RecipientEntry. - */ - public RecipientEntry getEntry() { - return mEntry; - } - - public void setOriginalText(String text) { - if (!TextUtils.isEmpty(text)) { - text = text.trim(); - } - mOriginalText = text; - } - - public CharSequence getOriginalText() { - return !TextUtils.isEmpty(mOriginalText) ? mOriginalText : mEntry.getDestination(); - } - - public void setDisplayOriginalText(final boolean displayOriginalText) { - mDisplayOriginalText = displayOriginalText; - } - - @Override - public void draw(Canvas canvas, CharSequence text, int start, int end, float x, int top, int y, - int bottom, Paint paint) { - if (mDisplayOriginalText) { - canvas.drawText(text, start, end, x, y, paint); - } else { - // Do nothing. - } - } - - @Override - public int getSize( - Paint paint, CharSequence text, int start, int end, Paint.FontMetricsInt fm) { - if (mDisplayOriginalText) { - return (int) paint.measureText(text, start, end); - } else { - return 0; - } - } - - @Override - public Rect getBounds() { - return new Rect(0, 0, 0, 0); - } - - @Override - public void draw(Canvas canvas) { - // do nothing. - } - - @Override - public String toString() { - return mDisplay + " <" + mValue + ">"; - } -} diff --git a/chips/src/com/android/ex/chips/RecipientAlternatesAdapter.java b/chips/src/com/android/ex/chips/RecipientAlternatesAdapter.java index f825e93..465c90e 100644 --- a/chips/src/com/android/ex/chips/RecipientAlternatesAdapter.java +++ b/chips/src/com/android/ex/chips/RecipientAlternatesAdapter.java @@ -70,7 +70,7 @@ public class RecipientAlternatesAdapter extends CursorAdapter { /** * Called with all addresses that could not be resolved to valid recipients. */ - public void matchesNotFound(Set<String> addresses); + public void matchesNotFound(Set<String> unfoundAddresses); } public static void getMatchingRecipients(Context context, ArrayList<String> inAddresses, @@ -229,7 +229,6 @@ public class RecipientAlternatesAdapter extends CursorAdapter { * Given two {@link RecipientEntry}s for the same email address, this will return the one that * contains more complete information for display purposes. Defaults to <code>entry2</code> if * no significant differences are found. - * TODO(skennedy) Add tests */ static RecipientEntry getBetterRecipient(final RecipientEntry entry1, final RecipientEntry entry2) { @@ -300,12 +299,12 @@ public class RecipientAlternatesAdapter extends CursorAdapter { return cursor; } - public RecipientAlternatesAdapter(Context context, long contactId, long currentId, int viewId, + public RecipientAlternatesAdapter(Context context, long contactId, long currentId, OnCheckedItemChangedListener listener) { - this(context, contactId, currentId, viewId, QUERY_TYPE_EMAIL, listener); + this(context, contactId, currentId, QUERY_TYPE_EMAIL, listener); } - public RecipientAlternatesAdapter(Context context, long contactId, long currentId, int viewId, + public RecipientAlternatesAdapter(Context context, long contactId, long currentId, int queryMode, OnCheckedItemChangedListener listener) { super(context, getCursorForConstruction(context, contactId, queryMode), 0); mLayoutInflater = LayoutInflater.from(context); diff --git a/chips/src/com/android/ex/chips/RecipientEditTextView.java b/chips/src/com/android/ex/chips/RecipientEditTextView.java index 551245c..67a5ca9 100644 --- a/chips/src/com/android/ex/chips/RecipientEditTextView.java +++ b/chips/src/com/android/ex/chips/RecipientEditTextView.java @@ -1,4 +1,5 @@ /* + * Copyright (C) 2011 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -16,6 +17,18 @@ package com.android.ex.chips; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + import android.app.Dialog; import android.content.ClipData; import android.content.ClipDescription; @@ -81,18 +94,9 @@ import android.widget.ScrollView; import android.widget.TextView; import com.android.ex.chips.RecipientAlternatesAdapter.RecipientMatchCallback; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.regex.Matcher; -import java.util.regex.Pattern; +import com.android.ex.chips.recipientchip.DrawableRecipientChip; +import com.android.ex.chips.recipientchip.InvisibleRecipientChip; +import com.android.ex.chips.recipientchip.VisibleRecipientChip; /** * RecipientEditTextView is an auto complete text view for use with applications @@ -105,8 +109,6 @@ public class RecipientEditTextView extends MultiAutoCompleteTextView implements private static final char COMMIT_CHAR_COMMA = ','; - private static final char NAME_WRAPPER_CHAR = '"'; - private static final char COMMIT_CHAR_SEMICOLON = ';'; private static final char COMMIT_CHAR_SPACE = ' '; @@ -149,7 +151,7 @@ public class RecipientEditTextView extends MultiAutoCompleteTextView implements private Validator mValidator; - private RecipientChip mSelectedChip; + private DrawableRecipientChip mSelectedChip; private int mAlternatesLayout; @@ -159,7 +161,8 @@ public class RecipientEditTextView extends MultiAutoCompleteTextView implements private TextView mMoreItem; - private final ArrayList<String> mPendingChips = new ArrayList<String>(); + // VisibleForTesting + final ArrayList<String> mPendingChips = new ArrayList<String>(); private Handler mHandler; @@ -171,9 +174,10 @@ public class RecipientEditTextView extends MultiAutoCompleteTextView implements private ListPopupWindow mAddressPopup; - private ArrayList<RecipientChip> mTemporaryRecipients; + // VisibleForTesting + ArrayList<DrawableRecipientChip> mTemporaryRecipients; - private ArrayList<RecipientChip> mRemovedSpans; + private ArrayList<DrawableRecipientChip> mRemovedSpans; private boolean mShouldShrink = true; @@ -322,9 +326,9 @@ public class RecipientEditTextView extends MultiAutoCompleteTextView implements return connection; } - /*package*/ RecipientChip getLastChip() { - RecipientChip last = null; - RecipientChip[] chips = getSortedRecipients(); + /*package*/ DrawableRecipientChip getLastChip() { + DrawableRecipientChip last = null; + DrawableRecipientChip[] chips = getSortedRecipients(); if (chips != null && chips.length > 0) { last = chips[chips.length - 1]; } @@ -335,7 +339,7 @@ public class RecipientEditTextView extends MultiAutoCompleteTextView implements public void onSelectionChanged(int start, int end) { // When selection changes, see if it is inside the chips area. // If so, move the cursor back after the chips again. - RecipientChip last = getLastChip(); + DrawableRecipientChip last = getLastChip(); if (last != null && start < getSpannable().getSpanEnd(last)) { // Grab the last chip and set the cursor to after it. setSelection(Math.min(getSpannable().getSpanEnd(last) + 1, getText().length())); @@ -475,7 +479,8 @@ public class RecipientEditTextView extends MultiAutoCompleteTextView implements Editable editable = getText(); int end = getSelectionEnd(); int start = mTokenizer.findTokenStart(editable, end); - RecipientChip[] chips = getSpannable().getSpans(start, end, RecipientChip.class); + DrawableRecipientChip[] chips = + getSpannable().getSpans(start, end, DrawableRecipientChip.class); if ((chips == null || chips.length == 0)) { Editable text = getText(); int whatEnd = mTokenizer.findTokenEnd(text, start); @@ -523,7 +528,7 @@ public class RecipientEditTextView extends MultiAutoCompleteTextView implements TextUtils.TruncateAt.END); } - private Bitmap createSelectedChip(RecipientEntry contact, TextPaint paint, Layout layout) { + private Bitmap createSelectedChip(RecipientEntry contact, TextPaint paint) { // Ellipsize the text so that it takes AT MOST the entire width of the // autocomplete text entry area. Make sure to leave space for padding // on the sides. @@ -532,7 +537,7 @@ public class RecipientEditTextView extends MultiAutoCompleteTextView implements float[] widths = new float[1]; paint.getTextWidths(" ", widths); CharSequence ellipsizedText = ellipsizeText(createChipDisplayText(contact), paint, - calculateAvailableWidth(true) - deleteWidth - widths[0]); + calculateAvailableWidth() - deleteWidth - widths[0]); // Make sure there is a minimum chip width so the user can ALWAYS // tap a chip without difficulty. @@ -565,7 +570,7 @@ public class RecipientEditTextView extends MultiAutoCompleteTextView implements } - private Bitmap createUnselectedChip(RecipientEntry contact, TextPaint paint, Layout layout, + private Bitmap createUnselectedChip(RecipientEntry contact, TextPaint paint, boolean leaveBlankIconSpacer) { // Ellipsize the text so that it takes AT MOST the entire width of the // autocomplete text entry area. Make sure to leave space for padding @@ -575,7 +580,7 @@ public class RecipientEditTextView extends MultiAutoCompleteTextView implements float[] widths = new float[1]; paint.getTextWidths(" ", widths); CharSequence ellipsizedText = ellipsizeText(createChipDisplayText(contact), paint, - calculateAvailableWidth(false) - iconWidth - widths[0]); + calculateAvailableWidth() - iconWidth - widths[0]); // Make sure there is a minimum chip width so the user can ALWAYS // tap a chip without difficulty. int width = Math.max(iconWidth * 2, (int) Math.floor(paint.measureText(ellipsizedText, 0, @@ -649,20 +654,19 @@ public class RecipientEditTextView extends MultiAutoCompleteTextView implements return contact.isValid() ? mChipBackground : mInvalidChipBackground; } - private float getTextYOffset(String text, TextPaint paint, int height) { + private static float getTextYOffset(String text, TextPaint paint, int height) { Rect bounds = new Rect(); paint.getTextBounds(text, 0, text.length(), bounds); int textHeight = bounds.bottom - bounds.top ; return height - ((height - textHeight) / 2) - (int)paint.descent(); } - private RecipientChip constructChipSpan(RecipientEntry contact, int offset, boolean pressed, + private DrawableRecipientChip constructChipSpan(RecipientEntry contact, boolean pressed, boolean leaveIconSpace) throws NullPointerException { if (mChipBackground == null) { throw new NullPointerException( "Unable to render any chips as setChipDimensions was not called."); } - Layout layout = getLayout(); TextPaint paint = getPaint(); float defaultSize = paint.getTextSize(); @@ -670,16 +674,16 @@ public class RecipientEditTextView extends MultiAutoCompleteTextView implements Bitmap tmpBitmap; if (pressed) { - tmpBitmap = createSelectedChip(contact, paint, layout); + tmpBitmap = createSelectedChip(contact, paint); } else { - tmpBitmap = createUnselectedChip(contact, paint, layout, leaveIconSpace); + tmpBitmap = createUnselectedChip(contact, paint, leaveIconSpace); } // Pass the full text, un-ellipsized, to the chip. Drawable result = new BitmapDrawable(getResources(), tmpBitmap); result.setBounds(0, 0, tmpBitmap.getWidth(), tmpBitmap.getHeight()); - RecipientChip recipientChip = new VisibleRecipientChip(result, contact, offset); + DrawableRecipientChip recipientChip = new VisibleRecipientChip(result, contact); // Return text to the original size. paint.setTextSize(defaultSize); paint.setColor(defaultColor); @@ -704,7 +708,7 @@ public class RecipientEditTextView extends MultiAutoCompleteTextView implements * account the width of the EditTextView, any view padding, and padding * that will be added to the chip. */ - private float calculateAvailableWidth(boolean pressed) { + private float calculateAvailableWidth() { return getWidth() - getPaddingLeft() - getPaddingRight() - (mChipPadding * 2); } @@ -821,10 +825,10 @@ public class RecipientEditTextView extends MultiAutoCompleteTextView implements private void checkChipWidths() { // Check the widths of the associated chips. - RecipientChip[] chips = getSortedRecipients(); + DrawableRecipientChip[] chips = getSortedRecipients(); if (chips != null) { Rect bounds; - for (RecipientChip chip : chips) { + for (DrawableRecipientChip chip : chips) { bounds = chip.getBounds(); if (getWidth() > 0 && bounds.right - bounds.left > getWidth()) { // Need to redraw that chip. @@ -880,10 +884,10 @@ public class RecipientEditTextView extends MultiAutoCompleteTextView implements } else { // Create the "more" chip mIndividualReplacements = new IndividualReplacementTask(); - mIndividualReplacements.execute(new ArrayList<RecipientChip>( + mIndividualReplacements.execute(new ArrayList<DrawableRecipientChip>( mTemporaryRecipients.subList(0, CHIP_LIMIT))); if (mTemporaryRecipients.size() > CHIP_LIMIT) { - mTemporaryRecipients = new ArrayList<RecipientChip>( + mTemporaryRecipients = new ArrayList<DrawableRecipientChip>( mTemporaryRecipients.subList(CHIP_LIMIT, mTemporaryRecipients.size())); } else { @@ -917,7 +921,7 @@ public class RecipientEditTextView extends MultiAutoCompleteTextView implements return; } // Find the last chip; eliminate any commit characters after it. - RecipientChip[] chips = getSortedRecipients(); + DrawableRecipientChip[] chips = getSortedRecipients(); Spannable spannable = getSpannable(); if (chips != null && chips.length > 0) { int end; @@ -944,7 +948,8 @@ public class RecipientEditTextView extends MultiAutoCompleteTextView implements * Create a chip that represents just the email address of a recipient. At some later * point, this chip will be attached to a real contact entry, if one exists. */ - private void createReplacementChip(int tokenStart, int tokenEnd, Editable editable, + // VisibleForTesting + void createReplacementChip(int tokenStart, int tokenEnd, Editable editable, boolean visible) { if (alreadyHasChip(tokenStart, tokenEnd)) { // There is already a chip present at this location. @@ -952,15 +957,14 @@ public class RecipientEditTextView extends MultiAutoCompleteTextView implements return; } String token = editable.toString().substring(tokenStart, tokenEnd); - int commitCharIndex = token.trim().lastIndexOf(COMMIT_CHAR_COMMA); - if (commitCharIndex == token.length() - 1) { - token = token.substring(0, token.length() - 1); + final String trimmedToken = token.trim(); + int commitCharIndex = trimmedToken.lastIndexOf(COMMIT_CHAR_COMMA); + if (commitCharIndex == trimmedToken.length() - 1) { + token = trimmedToken.substring(0, trimmedToken.length() - 1); } RecipientEntry entry = createTokenizedEntry(token); if (entry != null) { - String destText = createAddressText(entry); - SpannableString chipText = new SpannableString(destText); - RecipientChip chip = null; + DrawableRecipientChip chip = null; try { if (!mNoChips) { /* @@ -971,8 +975,8 @@ public class RecipientEditTextView extends MultiAutoCompleteTextView implements || TextUtils.equals(entry.getDisplayName(), entry.getDestination()); chip = visible ? - constructChipSpan(entry, tokenStart, false, leaveSpace) - : new InvisibleRecipientChip(entry, commitCharIndex); + constructChipSpan(entry, false, leaveSpace) + : new InvisibleRecipientChip(entry); } } catch (NullPointerException e) { Log.e(TAG, e.getMessage(), e); @@ -981,7 +985,7 @@ public class RecipientEditTextView extends MultiAutoCompleteTextView implements // Add this chip to the list of entries "to replace" if (chip != null) { if (mTemporaryRecipients == null) { - mTemporaryRecipients = new ArrayList<RecipientChip>(); + mTemporaryRecipients = new ArrayList<DrawableRecipientChip>(); } chip.setOriginalText(token); mTemporaryRecipients.add(chip); @@ -1061,7 +1065,7 @@ public class RecipientEditTextView extends MultiAutoCompleteTextView implements return mValidator == null ? true : mValidator.isValid(text); } - private String tokenizeAddress(String destination) { + private static String tokenizeAddress(String destination) { Rfc822Token[] tokens = Rfc822Tokenizer.tokenize(destination); if (tokens != null && tokens.length > 0) { return tokens[0].getAddress(); @@ -1114,20 +1118,6 @@ public class RecipientEditTextView extends MultiAutoCompleteTextView implements @Override public boolean onKeyUp(int keyCode, KeyEvent event) { switch (keyCode) { - case KeyEvent.KEYCODE_ENTER: - case KeyEvent.KEYCODE_DPAD_CENTER: - if (event.hasNoModifiers()) { - if (commitDefault()) { - return true; - } - if (mSelectedChip != null) { - clearSelectedChip(); - return true; - } else if (focusNext()) { - return true; - } - } - break; case KeyEvent.KEYCODE_TAB: if (event.hasNoModifiers()) { if (mSelectedChip != null) { @@ -1135,9 +1125,6 @@ public class RecipientEditTextView extends MultiAutoCompleteTextView implements } else { commitDefault(); } - if (focusNext()) { - return true; - } } break; } @@ -1245,10 +1232,10 @@ public class RecipientEditTextView extends MultiAutoCompleteTextView implements return; } // Find the last chip. - RecipientChip[] recips = getSortedRecipients(); + DrawableRecipientChip[] recips = getSortedRecipients(); if (recips != null && recips.length > 0) { - RecipientChip last = recips[recips.length - 1]; - RecipientChip beforeLast = null; + DrawableRecipientChip last = recips[recips.length - 1]; + DrawableRecipientChip beforeLast = null; if (recips.length > 1) { beforeLast = recips[recips.length - 2]; } @@ -1279,7 +1266,8 @@ public class RecipientEditTextView extends MultiAutoCompleteTextView implements if (mNoChips) { return true; } - RecipientChip[] chips = getSpannable().getSpans(start, end, RecipientChip.class); + DrawableRecipientChip[] chips = + getSpannable().getSpans(start, end, DrawableRecipientChip.class); if ((chips == null || chips.length == 0)) { return false; } @@ -1322,6 +1310,23 @@ public class RecipientEditTextView extends MultiAutoCompleteTextView implements removeChip(mSelectedChip); } + switch (keyCode) { + case KeyEvent.KEYCODE_ENTER: + case KeyEvent.KEYCODE_DPAD_CENTER: + if (event.hasNoModifiers()) { + if (commitDefault()) { + return true; + } + if (mSelectedChip != null) { + clearSelectedChip(); + return true; + } else if (focusNext()) { + return true; + } + } + break; + } + return super.onKeyDown(keyCode, event); } @@ -1330,11 +1335,11 @@ public class RecipientEditTextView extends MultiAutoCompleteTextView implements return getText(); } - private int getChipStart(RecipientChip chip) { + private int getChipStart(DrawableRecipientChip chip) { return getSpannable().getSpanStart(chip); } - private int getChipEnd(RecipientChip chip) { + private int getChipEnd(DrawableRecipientChip chip) { return getSpannable().getSpanEnd(chip); } @@ -1354,7 +1359,7 @@ public class RecipientEditTextView extends MultiAutoCompleteTextView implements // If this is a RecipientChip, don't filter // on its contents. Spannable span = getSpannable(); - RecipientChip[] chips = span.getSpans(start, end, RecipientChip.class); + DrawableRecipientChip[] chips = span.getSpans(start, end, DrawableRecipientChip.class); if (chips != null && chips.length > 0) { return; } @@ -1412,7 +1417,7 @@ public class RecipientEditTextView extends MultiAutoCompleteTextView implements float x = event.getX(); float y = event.getY(); int offset = putOffsetInRange(getOffsetForPosition(x, y)); - RecipientChip currentChip = findChip(offset); + DrawableRecipientChip currentChip = findChip(offset); if (currentChip != null) { if (action == MotionEvent.ACTION_UP) { if (mSelectedChip != null && mSelectedChip != currentChip) { @@ -1444,8 +1449,8 @@ public class RecipientEditTextView extends MultiAutoCompleteTextView implements } } - private void showAlternates(RecipientChip currentChip, ListPopupWindow alternatesPopup, - int width, Context context) { + private void showAlternates(DrawableRecipientChip currentChip, ListPopupWindow alternatesPopup, + int width) { int line = getLayout().getLineForOffset(getChipStart(currentChip)); int bottom; if (line == getLineCount() -1) { @@ -1476,12 +1481,12 @@ public class RecipientEditTextView extends MultiAutoCompleteTextView implements } } - private ListAdapter createAlternatesAdapter(RecipientChip chip) { + private ListAdapter createAlternatesAdapter(DrawableRecipientChip chip) { return new RecipientAlternatesAdapter(getContext(), chip.getContactId(), chip.getDataId(), - mAlternatesLayout, ((BaseRecipientAdapter)getAdapter()).getQueryType(), this); + ((BaseRecipientAdapter)getAdapter()).getQueryType(), this); } - private ListAdapter createSingleAddressAdapter(RecipientChip currentChip) { + private ListAdapter createSingleAddressAdapter(DrawableRecipientChip currentChip) { return new SingleRecipientArrayAdapter(getContext(), mAlternatesLayout, currentChip .getEntry()); } @@ -1525,18 +1530,19 @@ public class RecipientEditTextView extends MultiAutoCompleteTextView implements return offset; } - private int findText(Editable text, int offset) { + private static int findText(Editable text, int offset) { if (text.charAt(offset) != ' ') { return offset; } return -1; } - private RecipientChip findChip(int offset) { - RecipientChip[] chips = getSpannable().getSpans(0, getText().length(), RecipientChip.class); + private DrawableRecipientChip findChip(int offset) { + DrawableRecipientChip[] chips = + getSpannable().getSpans(0, getText().length(), DrawableRecipientChip.class); // Find the chip that contains this offset. for (int i = 0; i < chips.length; i++) { - RecipientChip chip = chips[i]; + DrawableRecipientChip chip = chips[i]; int start = getChipStart(chip); int end = getChipEnd(chip); if (offset >= start && offset <= end) { @@ -1599,13 +1605,11 @@ public class RecipientEditTextView extends MultiAutoCompleteTextView implements } SpannableString chipText = null; // Always leave a blank space at the end of a chip. - int end = getSelectionEnd(); - int start = mTokenizer.findTokenStart(getText(), end); - int textLength = displayText.length()-1; + int textLength = displayText.length() - 1; chipText = new SpannableString(displayText); if (!mNoChips) { try { - RecipientChip chip = constructChipSpan(entry, start, pressed, + DrawableRecipientChip chip = constructChipSpan(entry, pressed, false /* leave space for contact icon */); chipText.setSpan(chip, 0, textLength, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); @@ -1673,9 +1677,9 @@ public class RecipientEditTextView extends MultiAutoCompleteTextView implements /** Returns a collection of contact Id for each chip inside this View. */ /* package */ Collection<Long> getContactIds() { final Set<Long> result = new HashSet<Long>(); - RecipientChip[] chips = getSortedRecipients(); + DrawableRecipientChip[] chips = getSortedRecipients(); if (chips != null) { - for (RecipientChip chip : chips) { + for (DrawableRecipientChip chip : chips) { result.add(chip.getContactId()); } } @@ -1686,9 +1690,9 @@ public class RecipientEditTextView extends MultiAutoCompleteTextView implements /** Returns a collection of data Id for each chip inside this View. May be null. */ /* package */ Collection<Long> getDataIds() { final Set<Long> result = new HashSet<Long>(); - RecipientChip [] chips = getSortedRecipients(); + DrawableRecipientChip [] chips = getSortedRecipients(); if (chips != null) { - for (RecipientChip chip : chips) { + for (DrawableRecipientChip chip : chips) { result.add(chip.getDataId()); } } @@ -1696,16 +1700,16 @@ public class RecipientEditTextView extends MultiAutoCompleteTextView implements } // Visible for testing. - /* package */RecipientChip[] getSortedRecipients() { - RecipientChip[] recips = getSpannable() - .getSpans(0, getText().length(), RecipientChip.class); - ArrayList<RecipientChip> recipientsList = new ArrayList<RecipientChip>(Arrays - .asList(recips)); + /* package */DrawableRecipientChip[] getSortedRecipients() { + DrawableRecipientChip[] recips = getSpannable() + .getSpans(0, getText().length(), DrawableRecipientChip.class); + ArrayList<DrawableRecipientChip> recipientsList = new ArrayList<DrawableRecipientChip>( + Arrays.asList(recips)); final Spannable spannable = getSpannable(); - Collections.sort(recipientsList, new Comparator<RecipientChip>() { + Collections.sort(recipientsList, new Comparator<DrawableRecipientChip>() { @Override - public int compare(RecipientChip first, RecipientChip second) { + public int compare(DrawableRecipientChip first, DrawableRecipientChip second) { int firstStart = spannable.getSpanStart(first); int secondStart = spannable.getSpanStart(second); if (firstStart < secondStart) { @@ -1717,7 +1721,7 @@ public class RecipientEditTextView extends MultiAutoCompleteTextView implements } } }); - return recipientsList.toArray(new RecipientChip[recipientsList.size()]); + return recipientsList.toArray(new DrawableRecipientChip[recipientsList.size()]); } @Override @@ -1824,7 +1828,7 @@ public class RecipientEditTextView extends MultiAutoCompleteTextView implements if (tempMore.length > 0) { getSpannable().removeSpan(tempMore[0]); } - RecipientChip[] recipients = getSortedRecipients(); + DrawableRecipientChip[] recipients = getSortedRecipients(); if (recipients == null || recipients.length <= CHIP_LIMIT) { mMoreChip = null; @@ -1834,7 +1838,7 @@ public class RecipientEditTextView extends MultiAutoCompleteTextView implements int numRecipients = recipients.length; int overage = numRecipients - CHIP_LIMIT; MoreImageSpan moreSpan = createMoreSpan(overage); - mRemovedSpans = new ArrayList<RecipientChip>(); + mRemovedSpans = new ArrayList<DrawableRecipientChip>(); int totalReplaceStart = 0; int totalReplaceEnd = 0; Editable text = getText(); @@ -1881,7 +1885,7 @@ public class RecipientEditTextView extends MultiAutoCompleteTextView implements // Re-add the spans that were removed. if (mRemovedSpans != null && mRemovedSpans.size() > 0) { // Recreate each removed span. - RecipientChip[] recipients = getSortedRecipients(); + DrawableRecipientChip[] recipients = getSortedRecipients(); // Start the search for tokens after the last currently visible // chip. if (recipients == null || recipients.length == 0) { @@ -1889,7 +1893,7 @@ public class RecipientEditTextView extends MultiAutoCompleteTextView implements } int end = span.getSpanEnd(recipients[recipients.length - 1]); Editable editable = getText(); - for (RecipientChip chip : mRemovedSpans) { + for (DrawableRecipientChip chip : mRemovedSpans) { int chipStart; int chipEnd; String token; @@ -1903,13 +1907,6 @@ public class RecipientEditTextView extends MultiAutoCompleteTextView implements end = chipEnd = Math.min(editable.length(), chipStart + token.length()); // Only set the span if we found a matching token. if (chipStart != -1) { - if (chip instanceof InvisibleRecipientChip) { - /* - * We want the original text to be displayed until we can replace it - * with a real chip - */ - // ((InvisibleRecipientChip) chip).setDisplayOriginalText(true); - } editable.setSpan(chip, chipStart, chipEnd, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); } @@ -1931,7 +1928,7 @@ public class RecipientEditTextView extends MultiAutoCompleteTextView implements * @return A RecipientChip in the selected state or null if the chip * just contained an email address. */ - private RecipientChip selectChip(RecipientChip currentChip) { + private DrawableRecipientChip selectChip(DrawableRecipientChip currentChip) { if (shouldShowEditableText(currentChip)) { CharSequence text = currentChip.getValue(); Editable editable = getText(); @@ -1945,17 +1942,17 @@ public class RecipientEditTextView extends MultiAutoCompleteTextView implements editable.append(text); return constructChipSpan( RecipientEntry.constructFakeEntry((String) text, isValid(text.toString())), - getSelectionStart(), true, false); + true, false); } else if (currentChip.getContactId() == RecipientEntry.GENERATED_CONTACT) { int start = getChipStart(currentChip); int end = getChipEnd(currentChip); getSpannable().removeSpan(currentChip); - RecipientChip newChip; + DrawableRecipientChip newChip; try { if (mNoChips) { return null; } - newChip = constructChipSpan(currentChip.getEntry(), start, true, false); + newChip = constructChipSpan(currentChip.getEntry(), true, false); } catch (NullPointerException e) { Log.e(TAG, e.getMessage(), e); return null; @@ -1971,16 +1968,16 @@ public class RecipientEditTextView extends MultiAutoCompleteTextView implements if (shouldShowEditableText(newChip)) { scrollLineIntoView(getLayout().getLineForOffset(getChipStart(newChip))); } - showAddress(newChip, mAddressPopup, getWidth(), getContext()); + showAddress(newChip, mAddressPopup, getWidth()); setCursorVisible(false); return newChip; } else { int start = getChipStart(currentChip); int end = getChipEnd(currentChip); getSpannable().removeSpan(currentChip); - RecipientChip newChip; + DrawableRecipientChip newChip; try { - newChip = constructChipSpan(currentChip.getEntry(), start, true, false); + newChip = constructChipSpan(currentChip.getEntry(), true, false); } catch (NullPointerException e) { Log.e(TAG, e.getMessage(), e); return null; @@ -1996,20 +1993,20 @@ public class RecipientEditTextView extends MultiAutoCompleteTextView implements if (shouldShowEditableText(newChip)) { scrollLineIntoView(getLayout().getLineForOffset(getChipStart(newChip))); } - showAlternates(newChip, mAlternatesPopup, getWidth(), getContext()); + showAlternates(newChip, mAlternatesPopup, getWidth()); setCursorVisible(false); return newChip; } } - private boolean shouldShowEditableText(RecipientChip currentChip) { + private boolean shouldShowEditableText(DrawableRecipientChip currentChip) { long contactId = currentChip.getContactId(); return contactId == RecipientEntry.INVALID_CONTACT || (!isPhoneQuery() && contactId == RecipientEntry.GENERATED_CONTACT); } - private void showAddress(final RecipientChip currentChip, final ListPopupWindow popup, - int width, Context context) { + private void showAddress(final DrawableRecipientChip currentChip, final ListPopupWindow popup, + int width) { int line = getLayout().getLineForOffset(getChipStart(currentChip)); int bottom = calculateOffsetFromBottom(line); // Align the alternates popup with the left side of the View, @@ -2036,7 +2033,7 @@ public class RecipientEditTextView extends MultiAutoCompleteTextView implements * the chip without a delete icon and with an unfocused background. This is * called when the RecipientChip no longer has focus. */ - private void unselectChip(RecipientChip chip) { + private void unselectChip(DrawableRecipientChip chip) { int start = getChipStart(chip); int end = getChipEnd(chip); Editable editable = getText(); @@ -2051,7 +2048,7 @@ public class RecipientEditTextView extends MultiAutoCompleteTextView implements editable.removeSpan(chip); try { if (!mNoChips) { - editable.setSpan(constructChipSpan(chip.getEntry(), start, false, false), + editable.setSpan(constructChipSpan(chip.getEntry(), false, false), start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); } } catch (NullPointerException e) { @@ -2074,9 +2071,10 @@ public class RecipientEditTextView extends MultiAutoCompleteTextView implements * right after the selected chip. * @return boolean */ - private boolean isInDelete(RecipientChip chip, int offset, float x, float y) { + private boolean isInDelete(DrawableRecipientChip chip, int offset, float x, float y) { // Figure out the bounds of this chip and whether or not // the user clicked in the X portion. + // TODO: Should x and y be used, or removed? return chip.isSelected() && offset == getChipEnd(chip); } @@ -2084,7 +2082,7 @@ public class RecipientEditTextView extends MultiAutoCompleteTextView implements * Remove the chip and any text associated with it from the RecipientEditTextView. */ // Visible for testing. - /*pacakge*/ void removeChip(RecipientChip chip) { + /*pacakge*/ void removeChip(DrawableRecipientChip chip) { Spannable spannable = getSpannable(); int spanStart = spannable.getSpanStart(chip); int spanEnd = spannable.getSpanEnd(chip); @@ -2113,7 +2111,7 @@ public class RecipientEditTextView extends MultiAutoCompleteTextView implements * that uses the contact data provided. */ // Visible for testing. - /*package*/ void replaceChip(RecipientChip chip, RecipientEntry entry) { + /*package*/ void replaceChip(DrawableRecipientChip chip, RecipientEntry entry) { boolean wasSelected = chip == mSelectedChip; if (wasSelected) { mSelectedChip = null; @@ -2151,7 +2149,7 @@ public class RecipientEditTextView extends MultiAutoCompleteTextView implements * event, see if that event was in the delete icon. If so, delete it. * Otherwise, unselect the chip. */ - public void onClick(RecipientChip chip, int offset, float x, float y) { + public void onClick(DrawableRecipientChip chip, int offset, float x, float y) { if (chip.isSelected()) { if (isInDelete(chip, offset, x, y)) { removeChip(chip); @@ -2180,9 +2178,9 @@ public class RecipientEditTextView extends MultiAutoCompleteTextView implements if (TextUtils.isEmpty(s)) { // Remove all the chips spans. Spannable spannable = getSpannable(); - RecipientChip[] chips = spannable.getSpans(0, getText().length(), - RecipientChip.class); - for (RecipientChip chip : chips) { + DrawableRecipientChip[] chips = spannable.getSpans(0, getText().length(), + DrawableRecipientChip.class); + for (DrawableRecipientChip chip : chips) { spannable.removeSpan(chip); } if (mMoreChip != null) { @@ -2247,8 +2245,8 @@ public class RecipientEditTextView extends MultiAutoCompleteTextView implements // If the item deleted is a space, and the thing before the // space is a chip, delete the entire span. int selStart = getSelectionStart(); - RecipientChip[] repl = getSpannable().getSpans(selStart, selStart, - RecipientChip.class); + DrawableRecipientChip[] repl = getSpannable().getSpans(selStart, selStart, + DrawableRecipientChip.class); if (repl.length > 0) { // There is a chip there! Just remove it. Editable editable = getText(); @@ -2291,7 +2289,7 @@ public class RecipientEditTextView extends MultiAutoCompleteTextView implements return last == COMMIT_CHAR_COMMA || last == COMMIT_CHAR_SEMICOLON; } - public boolean isGeneratedContact(RecipientChip chip) { + public boolean isGeneratedContact(DrawableRecipientChip chip) { long contactId = chip.getContactId(); return contactId == RecipientEntry.INVALID_CONTACT || (!isPhoneQuery() && contactId == RecipientEntry.GENERATED_CONTACT); @@ -2335,7 +2333,7 @@ public class RecipientEditTextView extends MultiAutoCompleteTextView implements } private void handlePasteAndReplace() { - ArrayList<RecipientChip> created = handlePaste(); + ArrayList<DrawableRecipientChip> created = handlePaste(); if (created != null && created.size() > 0) { // Perform reverse lookups on the pasted contacts. IndividualReplacementTask replace = new IndividualReplacementTask(); @@ -2344,14 +2342,14 @@ public class RecipientEditTextView extends MultiAutoCompleteTextView implements } // Visible for testing. - /* package */ArrayList<RecipientChip> handlePaste() { + /* package */ArrayList<DrawableRecipientChip> handlePaste() { String text = getText().toString(); int originalTokenStart = mTokenizer.findTokenStart(text, getSelectionEnd()); String lastAddress = text.substring(originalTokenStart); int tokenStart = originalTokenStart; int prevTokenStart = tokenStart; - RecipientChip findChip = null; - ArrayList<RecipientChip> created = new ArrayList<RecipientChip>(); + DrawableRecipientChip findChip = null; + ArrayList<DrawableRecipientChip> created = new ArrayList<DrawableRecipientChip>(); if (tokenStart != 0) { // There are things before this! while (tokenStart != 0 && findChip == null) { @@ -2367,7 +2365,7 @@ public class RecipientEditTextView extends MultiAutoCompleteTextView implements tokenStart = prevTokenStart; } int tokenEnd; - RecipientChip createdChip; + DrawableRecipientChip createdChip; while (tokenStart < originalTokenStart) { tokenEnd = movePastTerminators(mTokenizer.findTokenEnd(getText().toString(), tokenStart)); @@ -2411,12 +2409,12 @@ public class RecipientEditTextView extends MultiAutoCompleteTextView implements } private class RecipientReplacementTask extends AsyncTask<Void, Void, Void> { - private RecipientChip createFreeChip(RecipientEntry entry) { + private DrawableRecipientChip createFreeChip(RecipientEntry entry) { try { if (mNoChips) { return null; } - return constructChipSpan(entry, -1, false, + return constructChipSpan(entry, false, false /*leave space for contact icon */); } catch (NullPointerException e) { Log.e(TAG, e.getMessage(), e); @@ -2428,8 +2426,9 @@ public class RecipientEditTextView extends MultiAutoCompleteTextView implements protected void onPreExecute() { // Ensure everything is in chip-form already, so we don't have text that slowly gets // replaced - final List<RecipientChip> originalRecipients = new ArrayList<RecipientChip>(); - final RecipientChip[] existingChips = getSortedRecipients(); + final List<DrawableRecipientChip> originalRecipients = + new ArrayList<DrawableRecipientChip>(); + final DrawableRecipientChip[] existingChips = getSortedRecipients(); for (int i = 0; i < existingChips.length; i++) { originalRecipients.add(existingChips[i]); } @@ -2437,10 +2436,10 @@ public class RecipientEditTextView extends MultiAutoCompleteTextView implements originalRecipients.addAll(mRemovedSpans); } - final List<RecipientChip> replacements = - new ArrayList<RecipientChip>(originalRecipients.size()); + final List<DrawableRecipientChip> replacements = + new ArrayList<DrawableRecipientChip>(originalRecipients.size()); - for (final RecipientChip chip : originalRecipients) { + for (final DrawableRecipientChip chip : originalRecipients) { if (RecipientEntry.isCreatedRecipient(chip.getEntry().getContactId()) && getSpannable().getSpanStart(chip) != -1) { replacements.add(createFreeChip(chip.getEntry())); @@ -2460,8 +2459,9 @@ public class RecipientEditTextView extends MultiAutoCompleteTextView implements // For each chip in the list, look up the matching contact. // If there is a match, replace that chip with the matching // chip. - final ArrayList<RecipientChip> recipients = new ArrayList<RecipientChip>(); - RecipientChip[] existingChips = getSortedRecipients(); + final ArrayList<DrawableRecipientChip> recipients = + new ArrayList<DrawableRecipientChip>(); + DrawableRecipientChip[] existingChips = getSortedRecipients(); for (int i = 0; i < existingChips.length; i++) { recipients.add(existingChips[i]); } @@ -2469,7 +2469,7 @@ public class RecipientEditTextView extends MultiAutoCompleteTextView implements recipients.addAll(mRemovedSpans); } ArrayList<String> addresses = new ArrayList<String>(); - RecipientChip chip; + DrawableRecipientChip chip; for (int i = 0; i < recipients.size(); i++) { chip = recipients.get(i); if (chip != null) { @@ -2482,9 +2482,9 @@ public class RecipientEditTextView extends MultiAutoCompleteTextView implements @Override public void matchesFound(Map<String, RecipientEntry> entries) { - final ArrayList<RecipientChip> replacements = - new ArrayList<RecipientChip>(); - for (final RecipientChip temp : recipients) { + final ArrayList<DrawableRecipientChip> replacements = + new ArrayList<DrawableRecipientChip>(); + for (final DrawableRecipientChip temp : recipients) { RecipientEntry entry = null; if (temp != null && RecipientEntry.isCreatedRecipient( temp.getEntry().getContactId()) @@ -2504,15 +2504,16 @@ public class RecipientEditTextView extends MultiAutoCompleteTextView implements } @Override - public void matchesNotFound(final Set<String> addresses) { - final List<RecipientChip> replacements = - new ArrayList<RecipientChip>(addresses.size()); + public void matchesNotFound(final Set<String> unfoundAddresses) { + final List<DrawableRecipientChip> replacements = + new ArrayList<DrawableRecipientChip>(unfoundAddresses.size()); - for (final RecipientChip temp : recipients) { + for (final DrawableRecipientChip temp : recipients) { if (temp != null && RecipientEntry.isCreatedRecipient( temp.getEntry().getContactId()) && getSpannable().getSpanStart(temp) != -1) { - if (addresses.contains(temp.getEntry().getDestination())) { + if (unfoundAddresses.contains( + temp.getEntry().getDestination())) { replacements.add(createFreeChip(temp.getEntry())); } else { replacements.add(null); @@ -2528,8 +2529,8 @@ public class RecipientEditTextView extends MultiAutoCompleteTextView implements return null; } - private void processReplacements(final List<RecipientChip> recipients, - final List<RecipientChip> replacements) { + private void processReplacements(final List<DrawableRecipientChip> recipients, + final List<DrawableRecipientChip> replacements) { if (replacements != null && replacements.size() > 0) { final Runnable runnable = new Runnable() { @Override @@ -2537,8 +2538,8 @@ public class RecipientEditTextView extends MultiAutoCompleteTextView implements Editable oldText = getText(); int start, end; int i = 0; - for (RecipientChip chip : recipients) { - RecipientChip replacement = replacements.get(i); + for (DrawableRecipientChip chip : recipients) { + DrawableRecipientChip replacement = replacements.get(i); if (replacement != null) { final RecipientEntry oldEntry = chip.getEntry(); final RecipientEntry newEntry = replacement.getEntry(); @@ -2589,15 +2590,15 @@ public class RecipientEditTextView extends MultiAutoCompleteTextView implements } private class IndividualReplacementTask - extends AsyncTask<ArrayList<RecipientChip>, Void, Void> { + extends AsyncTask<ArrayList<DrawableRecipientChip>, Void, Void> { @Override - protected Void doInBackground(ArrayList<RecipientChip>... params) { + protected Void doInBackground(ArrayList<DrawableRecipientChip>... params) { // For each chip in the list, look up the matching contact. // If there is a match, replace that chip with the matching // chip. - final ArrayList<RecipientChip> originalRecipients = params[0]; + final ArrayList<DrawableRecipientChip> originalRecipients = params[0]; ArrayList<String> addresses = new ArrayList<String>(); - RecipientChip chip; + DrawableRecipientChip chip; for (int i = 0; i < originalRecipients.size(); i++) { chip = originalRecipients.get(i); if (chip != null) { @@ -2610,7 +2611,7 @@ public class RecipientEditTextView extends MultiAutoCompleteTextView implements @Override public void matchesFound(Map<String, RecipientEntry> entries) { - for (final RecipientChip temp : originalRecipients) { + for (final DrawableRecipientChip temp : originalRecipients) { if (RecipientEntry.isCreatedRecipient(temp.getEntry() .getContactId()) && getSpannable().getSpanStart(temp) != -1) { @@ -2638,7 +2639,7 @@ public class RecipientEditTextView extends MultiAutoCompleteTextView implements } @Override - public void matchesNotFound(final Set<String> addresses) { + public void matchesNotFound(final Set<String> unfoundAddresses) { // No action required } }); @@ -2676,7 +2677,7 @@ public class RecipientEditTextView extends MultiAutoCompleteTextView implements float x = event.getX(); float y = event.getY(); int offset = putOffsetInRange(getOffsetForPosition(x, y)); - RecipientChip currentChip = findChip(offset); + DrawableRecipientChip currentChip = findChip(offset); if (currentChip != null) { if (mDragEnabled) { // Start drag-and-drop for the selected chip. @@ -2698,7 +2699,7 @@ public class RecipientEditTextView extends MultiAutoCompleteTextView implements /** * Starts drag-and-drop for the selected chip. */ - private void startDrag(RecipientChip currentChip) { + private void startDrag(DrawableRecipientChip currentChip) { String address = currentChip.getEntry().getDestination(); ClipData data = ClipData.newPlainText(address, address + COMMIT_CHAR_COMMA); @@ -2733,9 +2734,9 @@ public class RecipientEditTextView extends MultiAutoCompleteTextView implements * Drag shadow for a {@link RecipientChip}. */ private final class RecipientChipShadow extends DragShadowBuilder { - private final RecipientChip mChip; + private final DrawableRecipientChip mChip; - public RecipientChipShadow(RecipientChip chip) { + public RecipientChipShadow(DrawableRecipientChip chip) { mChip = chip; } diff --git a/chips/src/com/android/ex/chips/RecipientEntry.java b/chips/src/com/android/ex/chips/RecipientEntry.java index 1a79f32..14b11e1 100644 --- a/chips/src/com/android/ex/chips/RecipientEntry.java +++ b/chips/src/com/android/ex/chips/RecipientEntry.java @@ -19,6 +19,8 @@ package com.android.ex.chips; import android.net.Uri; import android.provider.ContactsContract.CommonDataKinds.Email; import android.provider.ContactsContract.DisplayNameSources; +import android.text.util.Rfc822Token; +import android.text.util.Rfc822Tokenizer; /** * Represents one entry inside recipient auto-complete list. @@ -106,8 +108,11 @@ public class RecipientEntry { * This address has not been resolved to a contact and therefore does not * have a contact id or photo. */ - public static RecipientEntry constructFakeEntry(String address, boolean isValid) { - return new RecipientEntry(ENTRY_TYPE_PERSON, address, address, + public static RecipientEntry constructFakeEntry(final String address, final boolean isValid) { + final Rfc822Token[] tokens = Rfc822Tokenizer.tokenize(address); + final String tokenizedAddress = tokens[0].getAddress(); + + return new RecipientEntry(ENTRY_TYPE_PERSON, tokenizedAddress, tokenizedAddress, INVALID_DESTINATION_TYPE, null, INVALID_CONTACT, INVALID_CONTACT, null, true, isValid); } diff --git a/chips/src/com/android/ex/chips/SingleRecipientArrayAdapter.java b/chips/src/com/android/ex/chips/SingleRecipientArrayAdapter.java index 8131fc3..0571a4e 100644 --- a/chips/src/com/android/ex/chips/SingleRecipientArrayAdapter.java +++ b/chips/src/com/android/ex/chips/SingleRecipientArrayAdapter.java @@ -43,7 +43,7 @@ class SingleRecipientArrayAdapter extends ArrayAdapter<RecipientEntry> { if (convertView == null) { convertView = newView(); } - bindView(convertView, convertView.getContext(), getItem(position)); + bindView(convertView, getItem(position)); return convertView; } @@ -51,7 +51,7 @@ class SingleRecipientArrayAdapter extends ArrayAdapter<RecipientEntry> { return mLayoutInflater.inflate(mLayoutId, null); } - private void bindView(View view, Context context, RecipientEntry entry) { + private static void bindView(View view, RecipientEntry entry) { TextView display = (TextView) view.findViewById(android.R.id.title); ImageView imageView = (ImageView) view.findViewById(android.R.id.icon); display.setText(entry.getDisplayName()); diff --git a/chips/src/com/android/ex/chips/RecipientChip.java b/chips/src/com/android/ex/chips/recipientchip/BaseRecipientChip.java index c7745c2..a080ee7 100644 --- a/chips/src/com/android/ex/chips/RecipientChip.java +++ b/chips/src/com/android/ex/chips/recipientchip/BaseRecipientChip.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011 The Android Open Source Project + * Copyright (C) 2013 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. @@ -14,71 +14,60 @@ * limitations under the License. */ -package com.android.ex.chips; +package com.android.ex.chips.recipientchip; -import android.graphics.Canvas; -import android.graphics.Rect; +import com.android.ex.chips.RecipientEntry; /** - * RecipientChip defines a drawable object that contains information relevant to a + * BaseRecipientChip defines an object that contains information relevant to a * particular recipient. */ -/* package */interface RecipientChip { +interface BaseRecipientChip { /** * Set the selected state of the chip. - * @param selected */ - public void setSelected(boolean selected); + void setSelected(boolean selected); + /** * Return true if the chip is selected. */ - public boolean isSelected(); + boolean isSelected(); /** * Get the text displayed in the chip. */ - public CharSequence getDisplay(); + CharSequence getDisplay(); /** * Get the text value this chip represents. */ - public CharSequence getValue(); + CharSequence getValue(); /** * Get the id of the contact associated with this chip. */ - public long getContactId(); + long getContactId(); /** * Get the id of the data associated with this chip. */ - public long getDataId(); + long getDataId(); /** * Get associated RecipientEntry. */ - public RecipientEntry getEntry(); + RecipientEntry getEntry(); /** * Set the text in the edittextview originally associated with this chip * before any reverse lookups. */ - public void setOriginalText(String text); + void setOriginalText(String text); /** * Set the text in the edittextview originally associated with this chip * before any reverse lookups. */ - public CharSequence getOriginalText(); - - /** - * Get the bounds of the chip; may be 0,0 if it is not visibly rendered. - */ - public Rect getBounds(); - - /** - * Draw the chip. - */ - public void draw(Canvas canvas); + CharSequence getOriginalText(); } diff --git a/chips/src/com/android/ex/chips/recipientchip/DrawableRecipientChip.java b/chips/src/com/android/ex/chips/recipientchip/DrawableRecipientChip.java new file mode 100644 index 0000000..396a8ac --- /dev/null +++ b/chips/src/com/android/ex/chips/recipientchip/DrawableRecipientChip.java @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2011 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.ex.chips.recipientchip; + +import android.graphics.Canvas; +import android.graphics.Rect; + +/** + * RecipientChip defines a drawable object that contains information relevant to a + * particular recipient. + */ +public interface DrawableRecipientChip extends BaseRecipientChip { + /** + * Get the bounds of the chip; may be 0,0 if it is not visibly rendered. + */ + Rect getBounds(); + + /** + * Draw the chip. + */ + void draw(Canvas canvas); +} diff --git a/chips/src/com/android/ex/chips/recipientchip/InvisibleRecipientChip.java b/chips/src/com/android/ex/chips/recipientchip/InvisibleRecipientChip.java new file mode 100644 index 0000000..0380a81 --- /dev/null +++ b/chips/src/com/android/ex/chips/recipientchip/InvisibleRecipientChip.java @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2011 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.ex.chips.recipientchip; + +import android.graphics.Canvas; +import android.graphics.Paint; +import android.graphics.Rect; +import android.text.style.ReplacementSpan; + +import com.android.ex.chips.RecipientEntry; + +/** + * RecipientChip defines a span that contains information relevant to a + * particular recipient. + */ +public class InvisibleRecipientChip extends ReplacementSpan implements DrawableRecipientChip { + private final SimpleRecipientChip mDelegate; + + public InvisibleRecipientChip(final RecipientEntry entry) { + super(); + + mDelegate = new SimpleRecipientChip(entry); + } + + @Override + public void setSelected(final boolean selected) { + mDelegate.setSelected(selected); + } + + @Override + public boolean isSelected() { + return mDelegate.isSelected(); + } + + @Override + public CharSequence getDisplay() { + return mDelegate.getDisplay(); + } + + @Override + public CharSequence getValue() { + return mDelegate.getValue(); + } + + @Override + public long getContactId() { + return mDelegate.getContactId(); + } + + @Override + public long getDataId() { + return mDelegate.getDataId(); + } + + @Override + public RecipientEntry getEntry() { + return mDelegate.getEntry(); + } + + @Override + public void setOriginalText(final String text) { + mDelegate.setOriginalText(text); + } + + @Override + public CharSequence getOriginalText() { + return mDelegate.getOriginalText(); + } + + @Override + public void draw(final Canvas canvas, final CharSequence text, final int start, final int end, + final float x, final int top, final int y, final int bottom, final Paint paint) { + // Do nothing. + } + + @Override + public int getSize(final Paint paint, final CharSequence text, final int start, final int end, + final Paint.FontMetricsInt fm) { + return 0; + } + + @Override + public Rect getBounds() { + return new Rect(0, 0, 0, 0); + } + + @Override + public void draw(final Canvas canvas) { + // do nothing. + } +} diff --git a/chips/src/com/android/ex/chips/VisibleRecipientChip.java b/chips/src/com/android/ex/chips/recipientchip/SimpleRecipientChip.java index 49be32f..c04b3be 100644 --- a/chips/src/com/android/ex/chips/VisibleRecipientChip.java +++ b/chips/src/com/android/ex/chips/recipientchip/SimpleRecipientChip.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011 The Android Open Source Project + * Copyright (C) 2013 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. @@ -14,20 +14,13 @@ * limitations under the License. */ -package com.android.ex.chips; +package com.android.ex.chips.recipientchip; + +import com.android.ex.chips.RecipientEntry; -import android.graphics.Canvas; -import android.graphics.Rect; -import android.graphics.drawable.Drawable; import android.text.TextUtils; -import android.text.style.DynamicDrawableSpan; -import android.text.style.ImageSpan; -/** - * VisibleRecipientChip defines an ImageSpan that contains information relevant to a - * particular recipient and renders a background asset to go with it. - */ -/* package */class VisibleRecipientChip extends ImageSpan implements RecipientChip { +class SimpleRecipientChip implements BaseRecipientChip { private final CharSequence mDisplay; private final CharSequence mValue; @@ -36,14 +29,13 @@ import android.text.style.ImageSpan; private final long mDataId; - private RecipientEntry mEntry; + private final RecipientEntry mEntry; private boolean mSelected = false; private CharSequence mOriginalText; - public VisibleRecipientChip(Drawable drawable, RecipientEntry entry, int offset) { - super(drawable, DynamicDrawableSpan.ALIGN_BOTTOM); + public SimpleRecipientChip(final RecipientEntry entry) { mDisplay = entry.getDisplayName(); mValue = entry.getDestination().trim(); mContactId = entry.getContactId(); @@ -51,79 +43,57 @@ import android.text.style.ImageSpan; mEntry = entry; } - /** - * Set the selected state of the chip. - * @param selected - */ - public void setSelected(boolean selected) { + @Override + public void setSelected(final boolean selected) { mSelected = selected; } - /** - * Return true if the chip is selected. - */ + @Override public boolean isSelected() { return mSelected; } - /** - * Get the text displayed in the chip. - */ + @Override public CharSequence getDisplay() { return mDisplay; } - /** - * Get the text value this chip represents. - */ + @Override public CharSequence getValue() { return mValue; } - /** - * Get the id of the contact associated with this chip. - */ + @Override public long getContactId() { return mContactId; } - /** - * Get the id of the data associated with this chip. - */ + @Override public long getDataId() { return mDataId; } - /** - * Get associated RecipientEntry. - */ + @Override public RecipientEntry getEntry() { return mEntry; } - public void setOriginalText(String text) { - if (!TextUtils.isEmpty(text)) { - text = text.trim(); + @Override + public void setOriginalText(final String text) { + if (TextUtils.isEmpty(text)) { + mOriginalText = text; + } else { + mOriginalText = text.trim(); } - mOriginalText = text; } + @Override public CharSequence getOriginalText() { return !TextUtils.isEmpty(mOriginalText) ? mOriginalText : mEntry.getDestination(); } @Override - public Rect getBounds() { - return getDrawable().getBounds(); - } - - @Override - public void draw(Canvas canvas) { - getDrawable().draw(canvas); - } - - @Override public String toString() { return mDisplay + " <" + mValue + ">"; } -} +}
\ No newline at end of file diff --git a/chips/src/com/android/ex/chips/recipientchip/VisibleRecipientChip.java b/chips/src/com/android/ex/chips/recipientchip/VisibleRecipientChip.java new file mode 100644 index 0000000..acade7f --- /dev/null +++ b/chips/src/com/android/ex/chips/recipientchip/VisibleRecipientChip.java @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2011 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.ex.chips.recipientchip; + +import android.graphics.Canvas; +import android.graphics.Rect; +import android.graphics.drawable.Drawable; +import android.text.style.DynamicDrawableSpan; +import android.text.style.ImageSpan; + +import com.android.ex.chips.RecipientEntry; + +/** + * VisibleRecipientChip defines an ImageSpan that contains information relevant to a + * particular recipient and renders a background asset to go with it. + */ +public class VisibleRecipientChip extends ImageSpan implements DrawableRecipientChip { + private final SimpleRecipientChip mDelegate; + + public VisibleRecipientChip(final Drawable drawable, final RecipientEntry entry) { + super(drawable, DynamicDrawableSpan.ALIGN_BOTTOM); + + mDelegate = new SimpleRecipientChip(entry); + } + + @Override + public void setSelected(final boolean selected) { + mDelegate.setSelected(selected); + } + + @Override + public boolean isSelected() { + return mDelegate.isSelected(); + } + + @Override + public CharSequence getDisplay() { + return mDelegate.getDisplay(); + } + + @Override + public CharSequence getValue() { + return mDelegate.getValue(); + } + + @Override + public long getContactId() { + return mDelegate.getContactId(); + } + + @Override + public long getDataId() { + return mDelegate.getDataId(); + } + + @Override + public RecipientEntry getEntry() { + return mDelegate.getEntry(); + } + + @Override + public void setOriginalText(final String text) { + mDelegate.setOriginalText(text); + } + + @Override + public CharSequence getOriginalText() { + return mDelegate.getOriginalText(); + } + + @Override + public Rect getBounds() { + return getDrawable().getBounds(); + } + + @Override + public void draw(final Canvas canvas) { + getDrawable().draw(canvas); + } + + @Override + public String toString() { + return mDelegate.toString(); + } +} |