1
0
mirror of https://github.com/moparisthebest/k-9 synced 2024-08-13 17:03:48 -04:00
k-9/src/com/fsck/k9/view/MessageHeader.java
cketti 8e627834c1 Changed font size unit from DIP to SP
"Scale-independent Pixels - this is like the dp unit, but it is also
scaled by the user's font size preference. It is recommend you use this
unit when specifying font sizes, so they will be adjusted for both the
screen density and the user's preference." - Android Developer Docs
2012-01-12 02:18:41 +01:00

298 lines
12 KiB
Java

package com.fsck.k9.view;
import android.content.Context;
import android.graphics.Typeface;
import android.text.SpannableString;
import android.text.SpannableStringBuilder;
import android.text.style.StyleSpan;
import android.util.Log;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.View;
import android.widget.CheckBox;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import com.fsck.k9.FontSizes;
import com.fsck.k9.K9;
import com.fsck.k9.R;
import com.fsck.k9.helper.Contacts;
import com.fsck.k9.Account;
import com.fsck.k9.helper.DateFormatter;
import com.fsck.k9.mail.Address;
import com.fsck.k9.mail.Flag;
import com.fsck.k9.mail.Message;
import com.fsck.k9.mail.MessagingException;
import com.fsck.k9.mail.internet.MimeUtility;
import com.fsck.k9.mail.store.LocalStore;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.text.DateFormat;
public class MessageHeader extends LinearLayout {
private Context mContext;
private TextView mFromView;
private TextView mDateView;
private TextView mTimeView;
private TextView mToView;
private TextView mCcView;
private TextView mSubjectView;
private DateFormat mDateFormat;
private DateFormat mTimeFormat;
private View mChip;
private CheckBox mFlagged;
private int defaultSubjectColor;
private LinearLayout mToContainerView;
private LinearLayout mCcContainerView;
private TextView mAdditionalHeadersView;
private View mAttachmentIcon;
private View mAnsweredIcon;
private Message mMessage;
private Account mAccount;
private FontSizes mFontSizes = K9.getFontSizes();
private Contacts mContacts;
/**
* Pair class is only available since API Level 5, so we need
* this helper class unfortunately
*/
private static class HeaderEntry {
public String label;
public String value;
public HeaderEntry(String label, String value) {
this.label = label;
this.value = value;
}
}
public MessageHeader(Context context, AttributeSet attrs) {
super(context, attrs);
mContext = context;
mDateFormat = DateFormatter.getDateFormat(mContext);
mTimeFormat = android.text.format.DateFormat.getTimeFormat(mContext); // 12/24 date format
mContacts = Contacts.getInstance(mContext);
}
private void initializeLayout() {
mAttachmentIcon = findViewById(R.id.attachment);
mAnsweredIcon = findViewById(R.id.answered);
mFromView = (TextView) findViewById(R.id.from);
mToView = (TextView) findViewById(R.id.to);
mCcView = (TextView) findViewById(R.id.cc);
mToContainerView = (LinearLayout) findViewById(R.id.to_container);
mCcContainerView = (LinearLayout) findViewById(R.id.cc_container);
mSubjectView = (TextView) findViewById(R.id.subject);
mAdditionalHeadersView = (TextView) findViewById(R.id.additional_headers_view);
mChip = findViewById(R.id.chip);
mDateView = (TextView) findViewById(R.id.date);
mTimeView = (TextView) findViewById(R.id.time);
mFlagged = (CheckBox) findViewById(R.id.flagged);
defaultSubjectColor = mSubjectView.getCurrentTextColor();
mSubjectView.setTextSize(TypedValue.COMPLEX_UNIT_SP, mFontSizes.getMessageViewSubject());
mTimeView.setTextSize(TypedValue.COMPLEX_UNIT_SP, mFontSizes.getMessageViewTime());
mDateView.setTextSize(TypedValue.COMPLEX_UNIT_SP, mFontSizes.getMessageViewDate());
mAdditionalHeadersView.setTextSize(TypedValue.COMPLEX_UNIT_SP, mFontSizes.getMessageViewAdditionalHeaders());
mAdditionalHeadersView.setVisibility(View.GONE);
mAttachmentIcon.setVisibility(View.GONE);
mAnsweredIcon.setVisibility(View.GONE);
mFromView.setTextSize(TypedValue.COMPLEX_UNIT_SP, mFontSizes.getMessageViewSender());
mToView.setTextSize(TypedValue.COMPLEX_UNIT_SP, mFontSizes.getMessageViewTo());
mCcView.setTextSize(TypedValue.COMPLEX_UNIT_SP, mFontSizes.getMessageViewCC());
((TextView) findViewById(R.id.to_label)).setTextSize(TypedValue.COMPLEX_UNIT_SP, mFontSizes.getMessageViewTo());
((TextView) findViewById(R.id.cc_label)).setTextSize(TypedValue.COMPLEX_UNIT_SP, mFontSizes.getMessageViewCC());
setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
onShowAdditionalHeaders();
}
});
mFromView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (mMessage != null) {
try {
final Address senderEmail = mMessage.getFrom()[0];
mContacts.createContact(senderEmail);
} catch (Exception e) {
Log.e(K9.LOG_TAG, "Couldn't create contact", e);
}
}
}
});
}
public void setOnFlagListener(OnClickListener listener) {
mFlagged.setOnClickListener(listener);
}
public boolean additionalHeadersVisible() {
if (mAdditionalHeadersView != null && mAdditionalHeadersView.getVisibility() == View.VISIBLE) {
return true;
} else {
return false;
}
}
/**
* Clear the text field for the additional headers display if they are
* not shown, to save UI resources.
*/
private void hideAdditionalHeaders() {
mAdditionalHeadersView.setVisibility(View.GONE);
mAdditionalHeadersView.setText("");
}
/**
* Set up and then show the additional headers view. Called by
* {@link #onShowAdditionalHeaders()}
* (when switching between messages).
*/
private void showAdditionalHeaders() {
Integer messageToShow = null;
try {
// Retrieve additional headers
boolean allHeadersDownloaded = mMessage.isSet(Flag.X_GOT_ALL_HEADERS);
List<HeaderEntry> additionalHeaders = getAdditionalHeaders(mMessage);
if (!additionalHeaders.isEmpty()) {
// Show the additional headers that we have got.
populateAdditionalHeadersView(additionalHeaders);
mAdditionalHeadersView.setVisibility(View.VISIBLE);
}
if (!allHeadersDownloaded) {
/*
* Tell the user about the "save all headers" setting
*
* NOTE: This is only a temporary solution... in fact,
* the system should download headers on-demand when they
* have not been saved in their entirety initially.
*/
messageToShow = R.string.message_additional_headers_not_downloaded;
} else if (additionalHeaders.isEmpty()) {
// All headers have been downloaded, but there are no additional headers.
messageToShow = R.string.message_no_additional_headers_available;
}
} catch (MessagingException e) {
messageToShow = R.string.message_additional_headers_retrieval_failed;
}
// Show a message to the user, if any
if (messageToShow != null) {
Toast toast = Toast.makeText(mContext, messageToShow, Toast.LENGTH_LONG);
toast.setGravity(Gravity.CENTER_VERTICAL | Gravity.CENTER_HORIZONTAL, 0, 0);
toast.show();
}
}
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 String date = mDateFormat.format(message.getSentDate());
final String time = mTimeFormat.format(message.getSentDate());
final CharSequence to = Address.toFriendly(message.getRecipients(Message.RecipientType.TO), contacts);
final CharSequence cc = Address.toFriendly(message.getRecipients(Message.RecipientType.CC), contacts);
mMessage = message;
mAccount = account;
initializeLayout();
String subject = message.getSubject();
if (subject == null || subject.equals("")) {
mSubjectView.setText(mContext.getText(R.string.general_no_subject));
} else {
mSubjectView.setText(subject);
}
mSubjectView.setTextColor(0xff000000 | defaultSubjectColor);
mFromView.setText(from);
if (date != null) {
mDateView.setText(date);
mDateView.setVisibility(View.VISIBLE);
} else {
mDateView.setVisibility(View.GONE);
}
mTimeView.setText(time);
mToContainerView.setVisibility((to != null && to.length() > 0) ? View.VISIBLE : View.GONE);
mToView.setText(to);
mCcContainerView.setVisibility((cc != null && cc.length() > 0) ? View.VISIBLE : View.GONE);
mCcView.setText(cc);
mAttachmentIcon.setVisibility(((LocalStore.LocalMessage) message).hasAttachments() ? View.VISIBLE : View.GONE);
mAnsweredIcon.setVisibility(message.isSet(Flag.ANSWERED) ? View.VISIBLE : View.GONE);
mFlagged.setChecked(message.isSet(Flag.FLAGGED));
mChip.setBackgroundDrawable(mAccount.generateColorChip().drawable());
mChip.getBackground().setAlpha(!message.isSet(Flag.SEEN) ? 255 : 127);
setVisibility(View.VISIBLE);
if (mAdditionalHeadersView.getVisibility() == View.VISIBLE) {
showAdditionalHeaders();
}
}
public void onShowAdditionalHeaders() {
int currentVisibility = mAdditionalHeadersView.getVisibility();
if (currentVisibility == View.VISIBLE) {
hideAdditionalHeaders();
} else {
showAdditionalHeaders();
}
}
private List<HeaderEntry> getAdditionalHeaders(final Message message)
throws MessagingException {
List<HeaderEntry> additionalHeaders = new LinkedList<HeaderEntry>();
/*
* Remove "Subject" header as it is already shown in the standard
* message view header. But do show "From", "To", and "Cc" again.
* This time including the email addresses. See issue 1805.
*/
Set<String> headerNames = new LinkedHashSet<String>(message.getHeaderNames());
headerNames.remove("Subject");
for (String headerName : headerNames) {
String[] headerValues = message.getHeader(headerName);
for (String headerValue : headerValues) {
additionalHeaders.add(new HeaderEntry(headerName, headerValue));
}
}
return additionalHeaders;
}
/**
* Set up the additional headers text view with the supplied header data.
*
* @param additionalHeaders List of header entries. Each entry consists of a header
* name and a header value. Header names may appear multiple
* times.
* <p/>
* This method is always called from within the UI thread by
* {@link #showAdditionalHeaders()}.
*/
private void populateAdditionalHeadersView(final List<HeaderEntry> additionalHeaders) {
SpannableStringBuilder sb = new SpannableStringBuilder();
boolean first = true;
for (HeaderEntry additionalHeader : additionalHeaders) {
if (!first) {
sb.append("\n");
} else {
first = false;
}
StyleSpan boldSpan = new StyleSpan(Typeface.BOLD);
SpannableString label = new SpannableString(additionalHeader.label + ": ");
label.setSpan(boldSpan, 0, label.length(), 0);
sb.append(label);
sb.append(MimeUtility.unfoldAndDecode(additionalHeader.value));
}
mAdditionalHeadersView.setText(sb);
}
}