Merge "Prevent NPE when no inboxUri"
diff --git a/res/layout/conversation_item_view_wide.xml b/res/layout/conversation_item_view_wide.xml
index 9d6ccdb..8e46a7b 100644
--- a/res/layout/conversation_item_view_wide.xml
+++ b/res/layout/conversation_item_view_wide.xml
@@ -43,7 +43,7 @@
android:textSize="@dimen/wide_senders_font_size"
android:layout_gravity="center_vertical"
android:maxLines="2"
- android:layout_marginTop="@dimen/wide_senders_margin_top" />
+ android:layout_marginTop="@dimen/wide_senders_margin_top" />
<TextView
android:id="@+id/subject"
android:layout_width="0dip"
diff --git a/src/com/android/mail/browse/ConversationItemView.java b/src/com/android/mail/browse/ConversationItemView.java
index 91cd325..4f2ebf2 100644
--- a/src/com/android/mail/browse/ConversationItemView.java
+++ b/src/com/android/mail/browse/ConversationItemView.java
@@ -549,7 +549,7 @@
createSubjectSpans(isUnread);
// Parse senders fragments.
- mCoordinates.sendersView.parseSendersFragments(mHeader, isUnread, mMode);
+ mCoordinates.sendersView.formatSenders(mHeader, isUnread, mMode);
pauseTimer(PERF_TAG_CALCULATE_SENDER_SUBJECT);
pauseTimer(PERF_TAG_CALCULATE_TEXTS_BITMAPS);
diff --git a/src/com/android/mail/browse/SendersView.java b/src/com/android/mail/browse/SendersView.java
index b99747e..15712f5 100644
--- a/src/com/android/mail/browse/SendersView.java
+++ b/src/com/android/mail/browse/SendersView.java
@@ -18,20 +18,35 @@
package com.android.mail.browse;
import android.content.Context;
+import android.content.res.Resources;
import android.graphics.Typeface;
+import android.text.SpannableStringBuilder;
import android.text.TextUtils;
import android.text.style.CharacterStyle;
+import android.text.style.ForegroundColorSpan;
import android.text.style.StyleSpan;
import android.text.util.Rfc822Token;
import android.text.util.Rfc822Tokenizer;
import android.util.AttributeSet;
import android.widget.TextView;
+import com.android.mail.R;
import com.android.mail.providers.Address;
import com.android.mail.providers.Conversation;
+import com.android.mail.utils.Utils;
+
+import java.util.regex.Pattern;
public class SendersView extends TextView {
+ public static final int DEFAULT_FORMATTING = 0;
+ public static final int MERGED_FORMATTING = 1;
+ public static String SENDERS_VERSION_SEPARATOR = "^**^";
CharacterStyle sNormalTextStyle = new StyleSpan(Typeface.NORMAL);
+ private Pattern SENDERS_VERSION_SEPARATOR_PATTERN = Pattern.compile("\\^\\*\\*\\^");
+ private int mFormatVersion = -1;
+ private ForegroundColorSpan sLightTextStyle;
+ private int DRAFT_TEXT_COLOR;
+ private int LIGHT_TEXT_COLOR;
public SendersView(Context context) {
this(context, null);
@@ -43,26 +58,45 @@
public SendersView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
+ Resources res = context.getResources();
+ LIGHT_TEXT_COLOR = res.getColor(R.color.light_text_color);
+ DRAFT_TEXT_COLOR = res.getColor(R.color.drafts);
+ sLightTextStyle = new ForegroundColorSpan(LIGHT_TEXT_COLOR);
}
public Typeface getTypeface(boolean isUnread) {
- return isUnread ? Typeface.DEFAULT_BOLD : Typeface.DEFAULT;
+ return mFormatVersion == DEFAULT_FORMATTING ? isUnread ? Typeface.DEFAULT_BOLD
+ : Typeface.DEFAULT : Typeface.DEFAULT;
}
- /**
- * Parses senders text into small fragments.
- */
- public void parseSendersFragments(ConversationItemViewModel header, boolean isUnread,
- int mode) {
+ public void formatSenders(ConversationItemViewModel header, boolean isUnread, int mode) {
if (TextUtils.isEmpty(header.conversation.senders)) {
return;
}
- header.sendersText = formatSenders(header.conversation);
- header.addSenderFragment(0, header.sendersText.length(), sNormalTextStyle, true);
+ Conversation conversation = header.conversation;
+ String sendersString = "";
+ String[] splits = TextUtils.split(conversation.senders, SENDERS_VERSION_SEPARATOR_PATTERN);
+ if (splits == null || splits.length < 2) {
+ mFormatVersion = DEFAULT_FORMATTING;
+ sendersString = header.conversation.senders;
+ } else {
+ mFormatVersion = Integer.parseInt(splits[0]);
+ // Format the rest of the senders string once the format version is
+ // stripped.
+ sendersString = splits[1];
+ }
+ switch (mFormatVersion) {
+ case MERGED_FORMATTING:
+ formatMerged(header, sendersString, isUnread, mode);
+ break;
+ case DEFAULT_FORMATTING:
+ default:
+ formatDefault(header, sendersString);
+ break;
+ }
}
- public String formatSenders(Conversation conversation) {
- String sendersString = conversation.senders;
+ private void formatDefault(ConversationItemViewModel header, String sendersString) {
String[] senders = TextUtils.split(sendersString, Address.ADDRESS_DELIMETER);
String[] namesOnly = new String[senders.length];
Rfc822Token[] senderTokens;
@@ -77,6 +111,72 @@
namesOnly[i] = display;
}
}
- return TextUtils.join(Address.ADDRESS_DELIMETER + " ", namesOnly);
+ header.sendersText = TextUtils.join(Address.ADDRESS_DELIMETER + " ", namesOnly);
+ header.addSenderFragment(0, header.sendersText.length(), sNormalTextStyle, true);
+ }
+
+ private void formatMerged(ConversationItemViewModel header, String sendersString,
+ boolean isUnread, int mode) {
+ SpannableStringBuilder sendersBuilder = new SpannableStringBuilder();
+ SpannableStringBuilder statusBuilder = new SpannableStringBuilder();
+ Utils.getStyledSenderSnippet(getContext(), sendersString, sendersBuilder,
+ statusBuilder, ConversationItemViewCoordinates.getSubjectLength(getContext(), mode,
+ header.folderDisplayer.hasVisibleFolders(),
+ header.conversation.hasAttachments), false, false, header.hasDraftMessage);
+ header.sendersText = sendersBuilder.toString();
+
+ CharacterStyle[] spans = sendersBuilder.getSpans(0, sendersBuilder.length(),
+ CharacterStyle.class);
+ header.clearSenderFragments();
+ int lastPosition = 0;
+ CharacterStyle style = sNormalTextStyle;
+ if (spans != null) {
+ for (CharacterStyle span : spans) {
+ style = span;
+ int start = sendersBuilder.getSpanStart(style);
+ int end = sendersBuilder.getSpanEnd(style);
+ if (start > lastPosition) {
+ header.addSenderFragment(lastPosition, start, sNormalTextStyle, false);
+ }
+ // From instructions won't be updated until the next sync. So we
+ // have to override the text style here to be consistent with
+ // the background color.
+ if (isUnread) {
+ header.addSenderFragment(start, end, style, false);
+ } else {
+ header.addSenderFragment(start, end, sNormalTextStyle, false);
+ }
+ lastPosition = end;
+ }
+ }
+ if (lastPosition < sendersBuilder.length()) {
+ style = sLightTextStyle;
+ header.addSenderFragment(lastPosition, sendersBuilder.length(), style, true);
+ }
+ if (statusBuilder.length() > 0) {
+ if (header.sendersText.length() > 0) {
+ header.sendersText = header.sendersText.concat(", ");
+
+ // Extend the last fragment to include the comma.
+ int lastIndex = header.senderFragments.size() - 1;
+ int start = header.senderFragments.get(lastIndex).start;
+ int end = header.senderFragments.get(lastIndex).end + 2;
+ style = header.senderFragments.get(lastIndex).style;
+
+ // The new fragment is only fixed if the previous fragment
+ // is fixed.
+ boolean isFixed = header.senderFragments.get(lastIndex).isFixed;
+
+ // Remove the old fragment.
+ header.senderFragments.remove(lastIndex);
+
+ // Add new fragment.
+ header.addSenderFragment(start, end, style, isFixed);
+ }
+ int pos = header.sendersText.length();
+ header.sendersText = header.sendersText.concat(statusBuilder.toString());
+ header.addSenderFragment(pos, header.sendersText.length(), new ForegroundColorSpan(
+ DRAFT_TEXT_COLOR), true);
+ }
}
}