Merge pull request #2347 from philipwhiuk/tidyUpMessageListFragment

Tidying up MessageListFragment
This commit is contained in:
Philip 2017-03-17 13:36:49 +00:00 committed by GitHub
commit 0763b09c83
7 changed files with 1295 additions and 1189 deletions

View file

@ -0,0 +1,60 @@
package com.fsck.k9.fragment;
import java.util.Arrays;
import com.fsck.k9.provider.EmailProvider.MessageColumns;
import com.fsck.k9.provider.EmailProvider.SpecialColumns;
import com.fsck.k9.provider.EmailProvider.ThreadColumns;
public final class MLFProjectionInfo {
static final String[] THREADED_PROJECTION = {
MessageColumns.ID,
MessageColumns.UID,
MessageColumns.INTERNAL_DATE,
MessageColumns.SUBJECT,
MessageColumns.DATE,
MessageColumns.SENDER_LIST,
MessageColumns.TO_LIST,
MessageColumns.CC_LIST,
MessageColumns.READ,
MessageColumns.FLAGGED,
MessageColumns.ANSWERED,
MessageColumns.FORWARDED,
MessageColumns.ATTACHMENT_COUNT,
MessageColumns.FOLDER_ID,
MessageColumns.PREVIEW_TYPE,
MessageColumns.PREVIEW,
ThreadColumns.ROOT,
SpecialColumns.ACCOUNT_UUID,
SpecialColumns.FOLDER_NAME,
SpecialColumns.THREAD_COUNT,
};
static final int ID_COLUMN = 0;
static final int UID_COLUMN = 1;
static final int INTERNAL_DATE_COLUMN = 2;
static final int SUBJECT_COLUMN = 3;
static final int DATE_COLUMN = 4;
static final int SENDER_LIST_COLUMN = 5;
static final int TO_LIST_COLUMN = 6;
static final int CC_LIST_COLUMN = 7;
static final int READ_COLUMN = 8;
static final int FLAGGED_COLUMN = 9;
static final int ANSWERED_COLUMN = 10;
static final int FORWARDED_COLUMN = 11;
static final int ATTACHMENT_COUNT_COLUMN = 12;
static final int FOLDER_ID_COLUMN = 13;
static final int PREVIEW_TYPE_COLUMN = 14;
static final int PREVIEW_COLUMN = 15;
static final int THREAD_ROOT_COLUMN = 16;
static final int ACCOUNT_UUID_COLUMN = 17;
static final int FOLDER_NAME_COLUMN = 18;
static final int THREAD_COUNT_COLUMN = 19;
static final String[] PROJECTION = Arrays.copyOf(THREADED_PROJECTION,
THREAD_COUNT_COLUMN);
}

View file

@ -0,0 +1,370 @@
package com.fsck.k9.fragment;
import android.content.Context;
import android.database.Cursor;
import android.graphics.Color;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.text.Spannable;
import android.text.SpannableStringBuilder;
import android.text.format.DateUtils;
import android.text.style.AbsoluteSizeSpan;
import android.text.style.ForegroundColorSpan;
import android.util.TypedValue;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.CursorAdapter;
import android.widget.TextView;
import com.fsck.k9.Account;
import com.fsck.k9.FontSizes;
import com.fsck.k9.K9;
import com.fsck.k9.R;
import com.fsck.k9.helper.Utility;
import com.fsck.k9.mail.Address;
import com.fsck.k9.mailstore.DatabasePreviewType;
import com.fsck.k9.ui.ContactBadge;
import static com.fsck.k9.fragment.MLFProjectionInfo.ANSWERED_COLUMN;
import static com.fsck.k9.fragment.MLFProjectionInfo.ATTACHMENT_COUNT_COLUMN;
import static com.fsck.k9.fragment.MLFProjectionInfo.CC_LIST_COLUMN;
import static com.fsck.k9.fragment.MLFProjectionInfo.DATE_COLUMN;
import static com.fsck.k9.fragment.MLFProjectionInfo.FLAGGED_COLUMN;
import static com.fsck.k9.fragment.MLFProjectionInfo.FOLDER_NAME_COLUMN;
import static com.fsck.k9.fragment.MLFProjectionInfo.FORWARDED_COLUMN;
import static com.fsck.k9.fragment.MLFProjectionInfo.PREVIEW_COLUMN;
import static com.fsck.k9.fragment.MLFProjectionInfo.PREVIEW_TYPE_COLUMN;
import static com.fsck.k9.fragment.MLFProjectionInfo.READ_COLUMN;
import static com.fsck.k9.fragment.MLFProjectionInfo.SENDER_LIST_COLUMN;
import static com.fsck.k9.fragment.MLFProjectionInfo.SUBJECT_COLUMN;
import static com.fsck.k9.fragment.MLFProjectionInfo.THREAD_COUNT_COLUMN;
import static com.fsck.k9.fragment.MLFProjectionInfo.TO_LIST_COLUMN;
import static com.fsck.k9.fragment.MLFProjectionInfo.UID_COLUMN;
public class MessageListAdapter extends CursorAdapter {
private final MessageListFragment fragment;
private Drawable mAttachmentIcon;
private Drawable mForwardedIcon;
private Drawable mAnsweredIcon;
private Drawable mForwardedAnsweredIcon;
private FontSizes fontSizes = K9.getFontSizes();
MessageListAdapter(MessageListFragment fragment) {
super(fragment.getActivity(), null, 0);
this.fragment = fragment;
mAttachmentIcon = fragment.getResources().getDrawable(R.drawable.ic_email_attachment_small);
mAnsweredIcon = fragment.getResources().getDrawable(R.drawable.ic_email_answered_small);
mForwardedIcon = fragment.getResources().getDrawable(R.drawable.ic_email_forwarded_small);
mForwardedAnsweredIcon = fragment.getResources().getDrawable(R.drawable.ic_email_forwarded_answered_small);
}
private String recipientSigil(boolean toMe, boolean ccMe) {
if (toMe) {
return fragment.getString(R.string.messagelist_sent_to_me_sigil);
} else if (ccMe) {
return fragment.getString(R.string.messagelist_sent_cc_me_sigil);
} else {
return "";
}
}
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
View view = fragment.getLayoutInflater().inflate(R.layout.message_list_item, parent, false);
MessageViewHolder holder = new MessageViewHolder(fragment);
holder.date = (TextView) view.findViewById(R.id.date);
holder.chip = view.findViewById(R.id.chip);
if (fragment.previewLines == 0 && fragment.contactsPictureLoader == null) {
view.findViewById(R.id.preview).setVisibility(View.GONE);
holder.preview = (TextView) view.findViewById(R.id.sender_compact);
holder.flagged = (CheckBox) view.findViewById(R.id.flagged_center_right);
view.findViewById(R.id.flagged_bottom_right).setVisibility(View.GONE);
} else {
view.findViewById(R.id.sender_compact).setVisibility(View.GONE);
holder.preview = (TextView) view.findViewById(R.id.preview);
holder.flagged = (CheckBox) view.findViewById(R.id.flagged_bottom_right);
view.findViewById(R.id.flagged_center_right).setVisibility(View.GONE);
}
ContactBadge contactBadge =
(ContactBadge) view.findViewById(R.id.contact_badge);
if (fragment.contactsPictureLoader != null) {
holder.contactBadge = contactBadge;
} else {
contactBadge.setVisibility(View.GONE);
}
if (fragment.senderAboveSubject) {
holder.from = (TextView) view.findViewById(R.id.subject);
fontSizes.setViewTextSize(holder.from, fontSizes.getMessageListSender());
} else {
holder.subject = (TextView) view.findViewById(R.id.subject);
fontSizes.setViewTextSize(holder.subject, fontSizes.getMessageListSubject());
}
fontSizes.setViewTextSize(holder.date, fontSizes.getMessageListDate());
// 1 preview line is needed even if it is set to 0, because subject is part of the same text view
holder.preview.setLines(Math.max(fragment.previewLines,1));
fontSizes.setViewTextSize(holder.preview, fontSizes.getMessageListPreview());
holder.threadCount = (TextView) view.findViewById(R.id.thread_count);
fontSizes.setViewTextSize(holder.threadCount, fontSizes.getMessageListSubject()); // thread count is next to subject
view.findViewById(R.id.selected_checkbox_wrapper).setVisibility((fragment.checkboxes) ? View.VISIBLE : View.GONE);
holder.flagged.setVisibility(fragment.stars ? View.VISIBLE : View.GONE);
holder.flagged.setOnClickListener(holder);
holder.selected = (CheckBox) view.findViewById(R.id.selected_checkbox);
holder.selected.setOnClickListener(holder);
view.setTag(holder);
return view;
}
@Override
public void bindView(View view, Context context, Cursor cursor) {
Account account = fragment.getAccountFromCursor(cursor);
String fromList = cursor.getString(SENDER_LIST_COLUMN);
String toList = cursor.getString(TO_LIST_COLUMN);
String ccList = cursor.getString(CC_LIST_COLUMN);
Address[] fromAddrs = Address.unpack(fromList);
Address[] toAddrs = Address.unpack(toList);
Address[] ccAddrs = Address.unpack(ccList);
boolean fromMe = fragment.messageHelper.toMe(account, fromAddrs);
boolean toMe = fragment.messageHelper.toMe(account, toAddrs);
boolean ccMe = fragment.messageHelper.toMe(account, ccAddrs);
CharSequence displayName = fragment.messageHelper.getDisplayName(account, fromAddrs, toAddrs);
CharSequence displayDate = DateUtils.getRelativeTimeSpanString(context, cursor.getLong(DATE_COLUMN));
Address counterpartyAddress = fetchCounterPartyAddress(fromMe, toAddrs, ccAddrs, fromAddrs);
int threadCount = (fragment.showingThreadedList) ? cursor.getInt(THREAD_COUNT_COLUMN) : 0;
String subject = MlfUtils.buildSubject(cursor.getString(SUBJECT_COLUMN),
fragment.getString(R.string.general_no_subject), threadCount);
boolean read = (cursor.getInt(READ_COLUMN) == 1);
boolean flagged = (cursor.getInt(FLAGGED_COLUMN) == 1);
boolean answered = (cursor.getInt(ANSWERED_COLUMN) == 1);
boolean forwarded = (cursor.getInt(FORWARDED_COLUMN) == 1);
boolean hasAttachments = (cursor.getInt(ATTACHMENT_COUNT_COLUMN) > 0);
MessageViewHolder holder = (MessageViewHolder) view.getTag();
int maybeBoldTypeface = (read) ? Typeface.NORMAL : Typeface.BOLD;
long uniqueId = cursor.getLong(fragment.uniqueIdColumn);
boolean selected = fragment.selected.contains(uniqueId);
holder.chip.setBackgroundColor(account.getChipColor());
if (fragment.checkboxes) {
holder.selected.setChecked(selected);
}
if (fragment.stars) {
holder.flagged.setChecked(flagged);
}
holder.position = cursor.getPosition();
if (holder.contactBadge != null) {
updateContactBadge(holder, counterpartyAddress);
}
setBackgroundColor(view, selected, read);
if (fragment.activeMessage != null) {
changeBackgroundColorIfActiveMessage(cursor, account, view);
}
updateWithThreadCount(holder, threadCount);
CharSequence beforePreviewText = (fragment.senderAboveSubject) ? subject : displayName;
String sigil = recipientSigil(toMe, ccMe);
SpannableStringBuilder messageStringBuilder = new SpannableStringBuilder(sigil)
.append(beforePreviewText);
if (fragment.previewLines > 0) {
String preview = getPreview(cursor);
messageStringBuilder.append(" ").append(preview);
}
holder.preview.setText(messageStringBuilder, TextView.BufferType.SPANNABLE);
formatPreviewText(holder.preview, beforePreviewText, sigil);
Drawable statusHolder = buildStatusHolder(forwarded, answered);
if (holder.from != null ) {
holder.from.setTypeface(Typeface.create(holder.from.getTypeface(), maybeBoldTypeface));
if (fragment.senderAboveSubject) {
holder.from.setCompoundDrawablesWithIntrinsicBounds(
statusHolder, // left
null, // top
hasAttachments ? mAttachmentIcon : null, // right
null); // bottom
holder.from.setText(displayName);
} else {
holder.from.setText(new SpannableStringBuilder(sigil).append(displayName));
}
}
if (holder.subject != null ) {
if (!fragment.senderAboveSubject) {
holder.subject.setCompoundDrawablesWithIntrinsicBounds(
statusHolder, // left
null, // top
hasAttachments ? mAttachmentIcon : null, // right
null); // bottom
}
holder.subject.setTypeface(Typeface.create(holder.subject.getTypeface(), maybeBoldTypeface));
holder.subject.setText(subject);
}
holder.date.setText(displayDate);
}
private void formatPreviewText(TextView preview, CharSequence beforePreviewText, String sigil) {
Spannable previewText = (Spannable)preview.getText();
previewText.setSpan(buildSenderSpan(), 0, beforePreviewText.length() + sigil.length(),
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
int previewSpanColor = buildPreviewSpanColor();
// Set span (color) for preview message
previewText.setSpan(new ForegroundColorSpan(previewSpanColor), beforePreviewText.length() + sigil.length(),
previewText.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
/**
* Create a span section for the sender, and assign the correct font size and weight
*/
private AbsoluteSizeSpan buildSenderSpan() {
int fontSize = (fragment.senderAboveSubject) ?
fontSizes.getMessageListSubject():
fontSizes.getMessageListSender();
return new AbsoluteSizeSpan(fontSize, true);
}
private Address fetchCounterPartyAddress(boolean fromMe, Address[] toAddrs, Address[] ccAddrs, Address[] fromAddrs) {
if (fromMe) {
if (toAddrs.length > 0) {
return toAddrs[0];
} else if (ccAddrs.length > 0) {
return ccAddrs[0];
}
} else if (fromAddrs.length > 0) {
return fromAddrs[0];
}
return null;
}
private void updateContactBadge(MessageViewHolder holder, Address counterpartyAddress) {
if (counterpartyAddress != null) {
Utility.setContactForBadge(holder.contactBadge, counterpartyAddress);
/*
* At least in Android 2.2 a different background + padding is used when no
* email address is available. ListView reuses the views but ContactBadge
* doesn't reset the padding, so we do it ourselves.
*/
holder.contactBadge.setPadding(0, 0, 0, 0);
fragment.contactsPictureLoader.loadContactPicture(counterpartyAddress, holder.contactBadge);
} else {
holder.contactBadge.assignContactUri(null);
holder.contactBadge.setImageResource(R.drawable.ic_contact_picture);
}
}
private void changeBackgroundColorIfActiveMessage(Cursor cursor, Account account, View view) {
String uid = cursor.getString(UID_COLUMN);
String folderName = cursor.getString(FOLDER_NAME_COLUMN);
if (account.getUuid().equals(fragment.activeMessage.getAccountUuid()) &&
folderName.equals(fragment.activeMessage.getFolderName()) &&
uid.equals(fragment.activeMessage.getUid())) {
int res = R.attr.messageListActiveItemBackgroundColor;
TypedValue outValue = new TypedValue();
fragment.getActivity().getTheme().resolveAttribute(res, outValue, true);
view.setBackgroundColor(outValue.data);
}
}
private int buildPreviewSpanColor() {
//TODO: make this part of the theme
return (K9.getK9Theme() == K9.Theme.LIGHT) ?
Color.rgb(105, 105, 105) :
Color.rgb(160, 160, 160);
}
private Drawable buildStatusHolder(boolean forwarded, boolean answered) {
if (forwarded && answered) {
return mForwardedAnsweredIcon;
} else if (answered) {
return mAnsweredIcon;
} else if (forwarded) {
return mForwardedIcon;
}
return null;
}
private void setBackgroundColor(View view, boolean selected, boolean read) {
if (selected || K9.useBackgroundAsUnreadIndicator()) {
int res;
if (selected) {
res = R.attr.messageListSelectedBackgroundColor;
} else if (read) {
res = R.attr.messageListReadItemBackgroundColor;
} else {
res = R.attr.messageListUnreadItemBackgroundColor;
}
TypedValue outValue = new TypedValue();
fragment.getActivity().getTheme().resolveAttribute(res, outValue, true);
view.setBackgroundColor(outValue.data);
} else {
view.setBackgroundColor(Color.TRANSPARENT);
}
}
private void updateWithThreadCount(MessageViewHolder holder, int threadCount) {
if (threadCount > 1) {
holder.threadCount.setText(String.format("%d", threadCount));
holder.threadCount.setVisibility(View.VISIBLE);
} else {
holder.threadCount.setVisibility(View.GONE);
}
}
private String getPreview(Cursor cursor) {
String previewTypeString = cursor.getString(PREVIEW_TYPE_COLUMN);
DatabasePreviewType previewType = DatabasePreviewType.fromDatabaseValue(previewTypeString);
switch (previewType) {
case NONE:
case ERROR: {
return "";
}
case ENCRYPTED: {
return fragment.getString(R.string.preview_encrypted);
}
case TEXT: {
return cursor.getString(PREVIEW_COLUMN);
}
}
throw new AssertionError("Unknown preview type: " + previewType);
}
}

View file

@ -2,9 +2,6 @@ package com.fsck.k9.fragment;
import android.database.Cursor;
import com.fsck.k9.fragment.MessageListFragment;
import com.fsck.k9.mail.Message;
import java.util.Comparator;
import java.util.List;
@ -82,8 +79,8 @@ public class MessageListFragmentComparators {
@Override
public int compare(Cursor cursor1, Cursor cursor2) {
int o1HasAttachment = (cursor1.getInt(MessageListFragment.ATTACHMENT_COUNT_COLUMN) > 0) ? 0 : 1;
int o2HasAttachment = (cursor2.getInt(MessageListFragment.ATTACHMENT_COUNT_COLUMN) > 0) ? 0 : 1;
int o1HasAttachment = (cursor1.getInt(MLFProjectionInfo.ATTACHMENT_COUNT_COLUMN) > 0) ? 0 : 1;
int o2HasAttachment = (cursor2.getInt(MLFProjectionInfo.ATTACHMENT_COUNT_COLUMN) > 0) ? 0 : 1;
return o1HasAttachment - o2HasAttachment;
}
}
@ -92,8 +89,8 @@ public class MessageListFragmentComparators {
@Override
public int compare(Cursor cursor1, Cursor cursor2) {
int o1IsFlagged = (cursor1.getInt(MessageListFragment.FLAGGED_COLUMN) == 1) ? 0 : 1;
int o2IsFlagged = (cursor2.getInt(MessageListFragment.FLAGGED_COLUMN) == 1) ? 0 : 1;
int o1IsFlagged = (cursor1.getInt(MLFProjectionInfo.FLAGGED_COLUMN) == 1) ? 0 : 1;
int o2IsFlagged = (cursor2.getInt(MLFProjectionInfo.FLAGGED_COLUMN) == 1) ? 0 : 1;
return o1IsFlagged - o2IsFlagged;
}
}
@ -102,8 +99,8 @@ public class MessageListFragmentComparators {
@Override
public int compare(Cursor cursor1, Cursor cursor2) {
int o1IsUnread = cursor1.getInt(MessageListFragment.READ_COLUMN);
int o2IsUnread = cursor2.getInt(MessageListFragment.READ_COLUMN);
int o1IsUnread = cursor1.getInt(MLFProjectionInfo.READ_COLUMN);
int o2IsUnread = cursor2.getInt(MLFProjectionInfo.READ_COLUMN);
return o1IsUnread - o2IsUnread;
}
}
@ -112,8 +109,8 @@ public class MessageListFragmentComparators {
@Override
public int compare(Cursor cursor1, Cursor cursor2) {
long o1Date = cursor1.getLong(MessageListFragment.DATE_COLUMN);
long o2Date = cursor2.getLong(MessageListFragment.DATE_COLUMN);
long o1Date = cursor1.getLong(MLFProjectionInfo.DATE_COLUMN);
long o2Date = cursor2.getLong(MLFProjectionInfo.DATE_COLUMN);
if (o1Date < o2Date) {
return -1;
} else if (o1Date == o2Date) {
@ -128,8 +125,8 @@ public class MessageListFragmentComparators {
@Override
public int compare(Cursor cursor1, Cursor cursor2) {
long o1Date = cursor1.getLong(MessageListFragment.INTERNAL_DATE_COLUMN);
long o2Date = cursor2.getLong(MessageListFragment.INTERNAL_DATE_COLUMN);
long o1Date = cursor1.getLong(MLFProjectionInfo.INTERNAL_DATE_COLUMN);
long o2Date = cursor2.getLong(MLFProjectionInfo.INTERNAL_DATE_COLUMN);
if (o1Date == o2Date) {
return 0;
} else if (o1Date < o2Date) {
@ -144,8 +141,8 @@ public class MessageListFragmentComparators {
@Override
public int compare(Cursor cursor1, Cursor cursor2) {
String subject1 = cursor1.getString(MessageListFragment.SUBJECT_COLUMN);
String subject2 = cursor2.getString(MessageListFragment.SUBJECT_COLUMN);
String subject1 = cursor1.getString(MLFProjectionInfo.SUBJECT_COLUMN);
String subject2 = cursor2.getString(MLFProjectionInfo.SUBJECT_COLUMN);
if (subject1 == null) {
return (subject2 == null) ? 0 : -1;
@ -161,8 +158,8 @@ public class MessageListFragmentComparators {
@Override
public int compare(Cursor cursor1, Cursor cursor2) {
String sender1 = MessageListFragment.getSenderAddressFromCursor(cursor1);
String sender2 = MessageListFragment.getSenderAddressFromCursor(cursor2);
String sender1 = MlfUtils.getSenderAddressFromCursor(cursor1);
String sender2 = MlfUtils.getSenderAddressFromCursor(cursor2);
if (sender1 == null && sender2 == null) {
return 0;

View file

@ -0,0 +1,142 @@
package com.fsck.k9.fragment;
import java.lang.ref.WeakReference;
import android.app.Activity;
import android.os.Handler;
import android.os.Parcelable;
import com.fsck.k9.activity.MessageReference;
/**
* This class is used to run operations that modify UI elements in the UI thread.
*
* <p>We are using convenience methods that add a {@link android.os.Message} instance or a
* {@link Runnable} to the message queue.</p>
*
* <p><strong>Note:</strong> If you add a method to this class make sure you don't accidentally
* perform the operation in the calling thread.</p>
*/
public class MessageListHandler extends Handler {
private static final int ACTION_FOLDER_LOADING = 1;
private static final int ACTION_REFRESH_TITLE = 2;
private static final int ACTION_PROGRESS = 3;
private static final int ACTION_REMOTE_SEARCH_FINISHED = 4;
private static final int ACTION_GO_BACK = 5;
private static final int ACTION_RESTORE_LIST_POSITION = 6;
private static final int ACTION_OPEN_MESSAGE = 7;
private WeakReference<MessageListFragment> mFragment;
public MessageListHandler(MessageListFragment fragment) {
mFragment = new WeakReference<>(fragment);
}
public void folderLoading(String folder, boolean loading) {
android.os.Message msg = android.os.Message.obtain(this, ACTION_FOLDER_LOADING,
(loading) ? 1 : 0, 0, folder);
sendMessage(msg);
}
public void refreshTitle() {
android.os.Message msg = android.os.Message.obtain(this, ACTION_REFRESH_TITLE);
sendMessage(msg);
}
public void progress(final boolean progress) {
android.os.Message msg = android.os.Message.obtain(this, ACTION_PROGRESS,
(progress) ? 1 : 0, 0);
sendMessage(msg);
}
public void remoteSearchFinished() {
android.os.Message msg = android.os.Message.obtain(this, ACTION_REMOTE_SEARCH_FINISHED);
sendMessage(msg);
}
public void updateFooter(final String message) {
post(new Runnable() {
@Override
public void run() {
MessageListFragment fragment = mFragment.get();
if (fragment != null) {
fragment.updateFooter(message);
}
}
});
}
public void goBack() {
android.os.Message msg = android.os.Message.obtain(this, ACTION_GO_BACK);
sendMessage(msg);
}
public void restoreListPosition() {
MessageListFragment fragment = mFragment.get();
if (fragment != null) {
android.os.Message msg = android.os.Message.obtain(this, ACTION_RESTORE_LIST_POSITION,
fragment.savedListState);
fragment.savedListState = null;
sendMessage(msg);
}
}
public void openMessage(MessageReference messageReference) {
android.os.Message msg = android.os.Message.obtain(this, ACTION_OPEN_MESSAGE,
messageReference);
sendMessage(msg);
}
@Override
public void handleMessage(android.os.Message msg) {
MessageListFragment fragment = mFragment.get();
if (fragment == null) {
return;
}
// The following messages don't need an attached activity.
switch (msg.what) {
case ACTION_REMOTE_SEARCH_FINISHED: {
fragment.remoteSearchFinished();
return;
}
}
// Discard messages if the fragment isn't attached to an activity anymore.
Activity activity = fragment.getActivity();
if (activity == null) {
return;
}
switch (msg.what) {
case ACTION_FOLDER_LOADING: {
String folder = (String) msg.obj;
boolean loading = (msg.arg1 == 1);
fragment.folderLoading(folder, loading);
break;
}
case ACTION_REFRESH_TITLE: {
fragment.updateTitle();
break;
}
case ACTION_PROGRESS: {
boolean progress = (msg.arg1 == 1);
fragment.progress(progress);
break;
}
case ACTION_GO_BACK: {
fragment.fragmentListener.goBack();
break;
}
case ACTION_RESTORE_LIST_POSITION: {
fragment.listView.onRestoreInstanceState((Parcelable) msg.obj);
break;
}
case ACTION_OPEN_MESSAGE: {
MessageReference messageReference = (MessageReference) msg.obj;
fragment.fragmentListener.openMessage(messageReference);
break;
}
}
}
}

View file

@ -0,0 +1,44 @@
package com.fsck.k9.fragment;
import android.view.View;
import android.widget.CheckBox;
import android.widget.TextView;
import com.fsck.k9.R;
import com.fsck.k9.ui.ContactBadge;
public class MessageViewHolder implements View.OnClickListener {
private final MessageListFragment fragment;
public TextView subject;
public TextView preview;
public TextView from;
public TextView time;
public TextView date;
public View chip;
public TextView threadCount;
public CheckBox flagged;
public CheckBox selected;
public int position = -1;
public ContactBadge contactBadge;
public MessageViewHolder(MessageListFragment fragment) {
this.fragment = fragment;
}
@Override
public void onClick(View view) {
if (position != -1) {
switch (view.getId()) {
case R.id.selected_checkbox:
fragment.toggleMessageSelectWithAdapterPosition(position);
break;
case R.id.flagged_bottom_right:
case R.id.flagged_center_right:
fragment.toggleMessageFlagWithAdapterPosition(position);
break;
}
}
}
}

View file

@ -0,0 +1,60 @@
package com.fsck.k9.fragment;
import java.util.List;
import android.database.Cursor;
import android.text.TextUtils;
import com.fsck.k9.Account;
import com.fsck.k9.Preferences;
import com.fsck.k9.activity.MessageReference;
import com.fsck.k9.helper.Utility;
import com.fsck.k9.mail.Address;
import com.fsck.k9.mail.Folder;
import com.fsck.k9.mail.MessagingException;
import com.fsck.k9.mailstore.LocalFolder;
import com.fsck.k9.mailstore.LocalStore;
import timber.log.Timber;
import static com.fsck.k9.fragment.MLFProjectionInfo.SENDER_LIST_COLUMN;
public class MlfUtils {
static LocalFolder getOpenFolder(String folderName, Account account) throws MessagingException {
LocalStore localStore = account.getLocalStore();
LocalFolder localFolder = localStore.getFolder(folderName);
localFolder.open(Folder.OPEN_MODE_RO);
return localFolder;
}
static void setLastSelectedFolderName(Preferences preferences,
List<MessageReference> messages, String destFolderName) {
try {
MessageReference firstMsg = messages.get(0);
Account account = preferences.getAccount(firstMsg.getAccountUuid());
LocalFolder firstMsgFolder = MlfUtils.getOpenFolder(firstMsg.getFolderName(), account);
firstMsgFolder.setLastSelectedFolderName(destFolderName);
} catch (MessagingException e) {
Timber.e(e, "Error getting folder for setLastSelectedFolderName()");
}
}
static String getSenderAddressFromCursor(Cursor cursor) {
String fromList = cursor.getString(SENDER_LIST_COLUMN);
Address[] fromAddrs = Address.unpack(fromList);
return (fromAddrs.length > 0) ? fromAddrs[0].getAddress() : null;
}
static String buildSubject(String subjectFromCursor, String emptySubject, int threadCount) {
String subject = subjectFromCursor;
if (TextUtils.isEmpty(subject)) {
return emptySubject;
} else if (threadCount > 1) {
// If this is a thread, strip the RE/FW from the subject. "Be like Outlook."
return Utility.stripSubject(subject);
}
return subject;
}
}