diff --git a/src/com/fsck/k9/controller/MessagingController.java b/src/com/fsck/k9/controller/MessagingController.java index 103808d85..770742256 100644 --- a/src/com/fsck/k9/controller/MessagingController.java +++ b/src/com/fsck/k9/controller/MessagingController.java @@ -61,6 +61,7 @@ import com.fsck.k9.activity.setup.AccountSetupIncoming; import com.fsck.k9.activity.setup.AccountSetupOutgoing; import com.fsck.k9.cache.EmailProviderCache; import com.fsck.k9.helper.Contacts; +import com.fsck.k9.helper.MessageHelper; import com.fsck.k9.helper.power.TracingPowerManager; import com.fsck.k9.helper.power.TracingPowerManager.TracingWakeLock; import com.fsck.k9.mail.Address; @@ -4695,7 +4696,7 @@ public class MessagingController implements Runnable { if (fromAddrs != null) { isSelf = account.isAnIdentity(fromAddrs); if (!isSelf && fromAddrs.length > 0) { - return fromAddrs[0].toFriendly(contacts).toString(); + return MessageHelper.toFriendly(fromAddrs[0], contacts).toString(); } } @@ -4705,7 +4706,7 @@ public class MessagingController implements Runnable { if (rcpts != null && rcpts.length > 0) { return context.getString(R.string.message_to_fmt, - rcpts[0].toFriendly(contacts).toString()); + MessageHelper.toFriendly(rcpts[0], contacts).toString()); } return context.getString(R.string.general_no_sender); diff --git a/src/com/fsck/k9/helper/Contacts.java b/src/com/fsck/k9/helper/Contacts.java index f5d25a912..022139f89 100644 --- a/src/com/fsck/k9/helper/Contacts.java +++ b/src/com/fsck/k9/helper/Contacts.java @@ -18,7 +18,7 @@ import java.util.List; /** * Helper class to access the contacts stored on the device. */ -public class Contacts implements Address.Lookup { +public class Contacts { /** * The order in which the search results are returned by * {@link #searchContacts(CharSequence)}. diff --git a/src/com/fsck/k9/helper/MessageHelper.java b/src/com/fsck/k9/helper/MessageHelper.java index 55caf8f66..ddc2f4a4d 100644 --- a/src/com/fsck/k9/helper/MessageHelper.java +++ b/src/com/fsck/k9/helper/MessageHelper.java @@ -1,7 +1,11 @@ package com.fsck.k9.helper; import android.content.Context; +import android.text.Spannable; +import android.text.SpannableString; import android.text.SpannableStringBuilder; +import android.text.TextUtils; +import android.text.style.ForegroundColorSpan; import android.util.Log; import com.fsck.k9.Account; @@ -16,6 +20,18 @@ import com.fsck.k9.mail.Message.RecipientType; import com.fsck.k9.mailstore.LocalMessage; public class MessageHelper { + /** + * If the number of addresses exceeds this value the addresses aren't + * resolved to the names of Android contacts. + * + *
+ * TODO: This number was chosen arbitrarily and should be determined by + * performance tests. + *
+ * + * @see #toFriendly(Address[], com.fsck.k9.helper.Contacts) + */ + private static final int TOO_MANY_ADDRESSES = 50; private static MessageHelper sInstance; @@ -55,11 +71,11 @@ public class MessageHelper { Address[] addrs = message.getFrom(); if (addrs.length > 0 && account.isAnIdentity(addrs[0])) { - CharSequence to = Address.toFriendly(message .getRecipients(RecipientType.TO), contactHelper); + CharSequence to = toFriendly(message.getRecipients(RecipientType.TO), contactHelper); target.compareCounterparty = to.toString(); target.sender = new SpannableStringBuilder(mContext.getString(R.string.message_to_label)).append(to); } else { - target.sender = Address.toFriendly(addrs, contactHelper); + target.sender = toFriendly(addrs, contactHelper); target.compareCounterparty = target.sender.toString(); } @@ -83,11 +99,11 @@ public class MessageHelper { CharSequence displayName; if (fromAddrs.length > 0 && account.isAnIdentity(fromAddrs[0])) { - CharSequence to = Address.toFriendly(toAddrs, contactHelper); + CharSequence to = toFriendly(toAddrs, contactHelper); displayName = new SpannableStringBuilder( mContext.getString(R.string.message_to_label)).append(to); } else { - displayName = Address.toFriendly(fromAddrs, contactHelper); + displayName = toFriendly(fromAddrs, contactHelper); } return displayName; @@ -101,4 +117,69 @@ public class MessageHelper { } return false; } + + /** + * Returns the name of the contact this email address belongs to if + * the {@link Contacts contacts} parameter is not {@code null} and a + * contact is found. Otherwise the personal portion of the {@link Address} + * is returned. If that isn't available either, the email address is + * returned. + * + * @param address An {@link com.fsck.k9.mail.Address} + * @param contacts A {@link Contacts} instance or {@code null}. + * @return A "friendly" name for this {@link Address}. + */ + public static CharSequence toFriendly(Address address, Contacts contacts) { + return toFriendly(address,contacts, + K9.showCorrespondentNames(), + K9.changeContactNameColor(), + K9.getContactNameColor()); + } + + public static CharSequence toFriendly(Address[] addresses, Contacts contacts) { + if (addresses == null) { + return null; + } + + if (addresses.length >= TOO_MANY_ADDRESSES) { + // Don't look up contacts if the number of addresses is very high. + contacts = null; + } + + SpannableStringBuilder sb = new SpannableStringBuilder(); + for (int i = 0; i < addresses.length; i++) { + sb.append(toFriendly(addresses[i], contacts)); + if (i < addresses.length - 1) { + sb.append(','); + } + } + return sb; + } + + /* package, for testing */ static CharSequence toFriendly(Address address, Contacts contacts, + boolean showCorrespondentNames, + boolean changeContactNameColor, + int contactNameColor) { + if (!showCorrespondentNames) { + return address.getAddress(); + } else if (contacts != null) { + final String name = contacts.getNameForAddress(address.getAddress()); + // TODO: The results should probably be cached for performance reasons. + if (name != null) { + if (changeContactNameColor) { + final SpannableString coloredName = new SpannableString(name); + coloredName.setSpan(new ForegroundColorSpan(contactNameColor), + 0, + coloredName.length(), + Spannable.SPAN_EXCLUSIVE_EXCLUSIVE + ); + return coloredName; + } else { + return name; + } + } + } + + return (!TextUtils.isEmpty(address.getPersonal())) ? address.getPersonal() : address.getAddress(); + } } diff --git a/src/com/fsck/k9/mail/Address.java b/src/com/fsck/k9/mail/Address.java index 9702c1c8d..76a4ebf45 100644 --- a/src/com/fsck/k9/mail/Address.java +++ b/src/com/fsck/k9/mail/Address.java @@ -24,25 +24,8 @@ import com.fsck.k9.K9; public class Address { - public static interface Lookup { - String getNameForAddress(String address); - } - private static final Pattern ATOM = Pattern.compile("^(?:[a-zA-Z0-9!#$%&'*+\\-/=?^_`{|}~]|\\s)+$"); - /** - * If the number of addresses exceeds this value the addresses aren't - * resolved to the names of Android contacts. - * - *- * TODO: This number was chosen arbitrarily and should be determined by - * performance tests. - *
- * - * @see Address#toFriendly(Address[], com.fsck.k9.mail.Address.Lookup) - */ - private static final int TOO_MANY_ADDRESSES = 50; - /** * Immutable empty {@link Address} array */ @@ -238,73 +221,6 @@ public class Address { return sb.toString(); } - /** - * Returns either the personal portion of the Address or the address portion if the personal - * is not available. - * @return - */ - public CharSequence toFriendly() { - return toFriendly((Lookup)null); - } - - /** - * Returns the name of the contact this email address belongs to if - * the {@link Contacts contacts} parameter is not {@code null} and a - * contact is found. Otherwise the personal portion of the {@link Address} - * is returned. If that isn't available either, the email address is - * returned. - * - * @param contacts - * A {@link Contacts} instance or {@code null}. - * @return - * A "friendly" name for this {@link Address}. - */ - public CharSequence toFriendly(final Lookup contacts) { - if (!K9.showCorrespondentNames()) { - return mAddress; - - } else if (contacts != null) { - final String name = contacts.getNameForAddress(mAddress); - - // TODO: The results should probably be cached for performance reasons. - - if (name != null) { - if (K9.changeContactNameColor()) { - final SpannableString coloredName = new SpannableString(name); - coloredName.setSpan(new ForegroundColorSpan(K9.getContactNameColor()), - 0, - coloredName.length(), - Spannable.SPAN_EXCLUSIVE_EXCLUSIVE - ); - return coloredName; - } else { - return name; - } - } - } - - return (!TextUtils.isEmpty(mPersonal)) ? mPersonal : mAddress; - } - - public static CharSequence toFriendly(Address[] addresses, Lookup contacts) { - if (addresses == null) { - return null; - } - - if (addresses.length >= TOO_MANY_ADDRESSES) { - // Don't look up contacts if the number of addresses is very high. - contacts = null; - } - - SpannableStringBuilder sb = new SpannableStringBuilder(); - for (int i = 0; i < addresses.length; i++) { - sb.append(addresses[i].toFriendly(contacts)); - if (i < addresses.length - 1) { - sb.append(','); - } - } - return sb; - } /** * Unpacks an address list previously packed with packAddressList() diff --git a/src/com/fsck/k9/view/MessageHeader.java b/src/com/fsck/k9/view/MessageHeader.java index 99d02ece4..67c5e130d 100644 --- a/src/com/fsck/k9/view/MessageHeader.java +++ b/src/com/fsck/k9/view/MessageHeader.java @@ -217,9 +217,9 @@ public class MessageHeader extends LinearLayout implements OnClickListener { public void populate(final Message message, final Account account) throws MessagingException { final Contacts contacts = K9.showContactName() ? mContacts : null; - final CharSequence from = Address.toFriendly(message.getFrom(), contacts); - final CharSequence to = Address.toFriendly(message.getRecipients(Message.RecipientType.TO), contacts); - final CharSequence cc = Address.toFriendly(message.getRecipients(Message.RecipientType.CC), contacts); + final CharSequence from = MessageHelper.toFriendly(message.getFrom(), contacts); + final CharSequence to = MessageHelper.toFriendly(message.getRecipients(Message.RecipientType.TO), contacts); + final CharSequence cc = MessageHelper.toFriendly(message.getRecipients(Message.RecipientType.CC), contacts); Address[] fromAddrs = message.getFrom(); Address[] toAddrs = message.getRecipients(Message.RecipientType.TO); diff --git a/tests/src/com/fsck/k9/helper/HtmlConverterTest.java b/tests/src/com/fsck/k9/helper/HtmlConverterTest.java index 32aa241ed..c79958150 100644 --- a/tests/src/com/fsck/k9/helper/HtmlConverterTest.java +++ b/tests/src/com/fsck/k9/helper/HtmlConverterTest.java @@ -1,7 +1,5 @@ package com.fsck.k9.helper; -import com.fsck.k9.helper.HtmlConverter; - import junit.framework.TestCase; import java.io.BufferedWriter; diff --git a/tests/src/com/fsck/k9/helper/MessageHelperTest.java b/tests/src/com/fsck/k9/helper/MessageHelperTest.java new file mode 100644 index 000000000..0d71784e3 --- /dev/null +++ b/tests/src/com/fsck/k9/helper/MessageHelperTest.java @@ -0,0 +1,63 @@ +package com.fsck.k9.helper; + + +import android.graphics.Color; +import android.test.AndroidTestCase; +import android.text.SpannableString; + +import com.fsck.k9.mail.Address; + +public class MessageHelperTest extends AndroidTestCase { + private Contacts contacts; + private Contacts mockContacts; + + @Override + public void setUp() throws Exception { + super.setUp(); + contacts = new Contacts(getContext()); + mockContacts = new Contacts(getContext()) { + @Override public String getNameForAddress(String address) { + if ("test@testor.com".equals(address)) { + return "Tim Testor"; + } else { + return null; + } + } + }; + } + + public void testToFriendlyShowsPersonalPartIfItExists() throws Exception { + Address address = new Address("test@testor.com", "Tim Testor"); + assertEquals("Tim Testor", MessageHelper.toFriendly(address, contacts)); + } + + public void testToFriendlyShowsEmailPartIfNoPersonalPartExists() throws Exception { + Address address = new Address("test@testor.com"); + assertEquals("test@testor.com", MessageHelper.toFriendly(address, contacts)); + } + + public void testToFriendlyArray() throws Exception { + Address address1 = new Address("test@testor.com", "Tim Testor"); + Address address2 = new Address("foo@bar.com", "Foo Bar"); + Address[] addresses = new Address[] { address1, address2 }; + assertEquals("Tim Testor,Foo Bar", MessageHelper.toFriendly(addresses, contacts).toString()); + } + + public void testToFriendlyWithContactLookup() throws Exception { + Address address = new Address("test@testor.com"); + assertEquals("Tim Testor", MessageHelper.toFriendly(address, mockContacts).toString()); + } + + public void testToFriendlyWithChangeContactColor() throws Exception { + Address address = new Address("test@testor.com"); + CharSequence friendly = MessageHelper.toFriendly(address, mockContacts, true, true, Color.RED); + assertTrue(friendly instanceof SpannableString); + assertEquals("Tim Testor", friendly.toString()); + } + + public void testToFriendlyWithoutCorrespondentNames() throws Exception { + Address address = new Address("test@testor.com", "Tim Testor"); + CharSequence friendly = MessageHelper.toFriendly(address, mockContacts, false, false, 0); + assertEquals("test@testor.com", friendly.toString()); + } +}