diff --git a/res/drawable/ic_menu_reverse_sort.png b/res/drawable/ic_menu_reverse_sort.png new file mode 100644 index 000000000..aaf4ce512 Binary files /dev/null and b/res/drawable/ic_menu_reverse_sort.png differ diff --git a/res/drawable/ic_menu_set_sort.png b/res/drawable/ic_menu_set_sort.png new file mode 100644 index 000000000..ef076b693 Binary files /dev/null and b/res/drawable/ic_menu_set_sort.png differ diff --git a/res/menu/folder_message_list_option.xml b/res/menu/folder_message_list_option.xml index f163c1c7e..1c5800848 100644 --- a/res/menu/folder_message_list_option.xml +++ b/res/menu/folder_message_list_option.xml @@ -1,17 +1,48 @@ - - + + + + + + + + + + + + - + diff --git a/res/values/strings.xml b/res/values/strings.xml index 81e790c28..201815f3a 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -60,8 +60,8 @@ Add attachment Dump settings Empty Trash - Thread - Unthread + Choose sort + Reverse sort About Account options @@ -115,7 +115,7 @@ Welcome to K-9 Mail setup. K-9 is an open source email client for Android based * Better IMAP support * Saving attachments to SD * Empty Trash - * Threading + * Message sorting * ...and more \nPlease note that K-9 does not support most free hotmail accounts and, like many email clients, has some quirks when talking to Microsoft Exchange. \nSubmit bug reports, contribute new features and ask questions at http://code.google.com/p/k9mail @@ -356,6 +356,27 @@ Welcome to K-9 Mail setup. K-9 is an open source email client for Android based Deleted Items Folder Set the deleted items folder + + Earliest messages first + Latest messages first + Sender alphabetical + Sender reverse alphabetical + Subject alphabetical + Subject reverse alphabetical + Flagged messages first + Unflagged messages first + Unread messages first + Read messages first + Messages with attachments first + Messages without attachments first + + Sort by... + Date + Sender + Subject + Flag + Read/unread + Attachments Remove The account \"%s\" will be removed from Email. @@ -376,6 +397,6 @@ Welcome to K-9 Mail setup. K-9 is an open source email client for Android based Message\u000AK, N - Next Message\u000AZ - Zoom Out\u000AShift-Z - Zoom In\u000aG - Flag Del (or D) - Delete\u000AR - - Reply\u000AA - Reply All\u000AC - Compose\u000AF - Forward\u000aG - Flag\u000AT - Thread\u000AQ + Reply\u000AA - Reply All\u000AC - Compose\u000AF - Forward\u000aG - Flag\u000AO - Sort type\u000AI - Sort order\u000AQ - Return to Accounts diff --git a/src/com/android/email/MessagingController.java b/src/com/android/email/MessagingController.java index b55ed78b8..2637d2aac 100644 --- a/src/com/android/email/MessagingController.java +++ b/src/com/android/email/MessagingController.java @@ -108,7 +108,44 @@ public class MessagingController implements Runnable { //private Set mListeners = Collections.synchronizedSet(new HashSet()); private Set mListeners = new CopyOnWriteArraySet(); - private boolean threading = false; + private HashMap sortAscending = new HashMap(); + + public enum SORT_TYPE { + SORT_DATE(R.string.sort_earliest_first, R.string.sort_latest_first, false), + SORT_SUBJECT(R.string.sort_subject_alpha, R.string.sort_subject_re_alpha, true), + SORT_SENDER(R.string.sort_sender_alpha, R.string.sort_sender_re_alpha, true), + SORT_UNREAD(R.string.sort_unread_first, R.string.sort_unread_last, true), + SORT_FLAGGED(R.string.sort_flagged_first, R.string.sort_flagged_last, true), + SORT_ATTACHMENT(R.string.sort_attach_first, R.string.sort_unattached_first, true); + + private int ascendingToast; + private int descendingToast; + private boolean defaultAscending; + + SORT_TYPE(int ascending, int descending, boolean ndefaultAscending) + { + ascendingToast = ascending; + descendingToast = descending; + defaultAscending = ndefaultAscending; + } + + public int getToast(boolean ascending) + { + if (ascending) + { + return ascendingToast; + } + else + { + return descendingToast; + } + } + public boolean isDefaultAscending() + { + return defaultAscending; + } + }; + private SORT_TYPE sortType = SORT_TYPE.SORT_DATE; private MessagingListener checkMailListener = null; @@ -2503,13 +2540,28 @@ s * critical data as fast as possible, and then we'll fill in the de } } - public boolean isThreading() + public SORT_TYPE getSortType() { - return threading; + return sortType; } - public void setThreading(boolean threading) + public void setSortType(SORT_TYPE sortType) { - this.threading = threading; + this.sortType = sortType; + } + + public boolean isSortAscending(SORT_TYPE sortType) + { + Boolean sortAsc = sortAscending.get(sortType); + if (sortAsc == null) + { + return sortType.isDefaultAscending(); + } + else return sortAsc; + } + + public void setSortAscending(SORT_TYPE sortType, boolean nsortAscending) + { + sortAscending.put(sortType, nsortAscending); } } diff --git a/src/com/android/email/activity/FolderMessageList.java b/src/com/android/email/activity/FolderMessageList.java index 75f2d85f1..6ce637ffb 100644 --- a/src/com/android/email/activity/FolderMessageList.java +++ b/src/com/android/email/activity/FolderMessageList.java @@ -1,10 +1,12 @@ package com.android.email.activity; +import java.lang.reflect.Array; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Collections; import java.util.Date; +import java.util.EnumMap; import java.util.List; import java.util.concurrent.ConcurrentHashMap; import java.util.regex.Matcher; @@ -41,6 +43,7 @@ import android.widget.ExpandableListView.ExpandableListContextMenuInfo; import com.android.email.Account; import com.android.email.Email; import com.android.email.MessagingController; +import static com.android.email.MessagingController.SORT_TYPE; import com.android.email.MessagingListener; import com.android.email.R; import com.android.email.Utility; @@ -130,8 +133,6 @@ public class FolderMessageList extends ExpandableListActivity private LayoutInflater mInflater; private Account mAccount; - - private Menu optionsMenu = null; /** @@ -152,7 +153,9 @@ public class FolderMessageList extends ExpandableListActivity private DateFormat timeFormat = null; - private boolean thread = false; + private SORT_TYPE sortType = SORT_TYPE.SORT_DATE; + private boolean sortAscending = true; + private boolean sortDateAscending = false; private DateFormat getDateFormat() { @@ -577,6 +580,9 @@ public class FolderMessageList extends ExpandableListActivity { super.onResume(); clearFormats(); + sortType = MessagingController.getInstance(getApplication()).getSortType(); + sortAscending = MessagingController.getInstance(getApplication()).isSortAscending(sortType); + sortDateAscending = MessagingController.getInstance(getApplication()).isSortAscending(SORT_TYPE.SORT_DATE); MessagingController.getInstance(getApplication()).addListener( mAdapter.mListener); @@ -585,9 +591,7 @@ public class FolderMessageList extends ExpandableListActivity NotificationManager notifMgr = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); notifMgr.cancel(mAccount.getAccountNumber()); - thread = MessagingController.getInstance(getApplication()).isThreading(); - - + } @Override @@ -644,7 +648,8 @@ public class FolderMessageList extends ExpandableListActivity case KeyEvent.KEYCODE_C: { onCompose(); return true;} case KeyEvent.KEYCODE_Q: { onAccounts(); return true; } case KeyEvent.KEYCODE_S: { onEditAccount(); return true; } - case KeyEvent.KEYCODE_T: { onToggleThread(); return true; } + case KeyEvent.KEYCODE_O: { onCycleSort(); return true; } + case KeyEvent.KEYCODE_I: { onToggleSortAscending(); return true; } case KeyEvent.KEYCODE_H: { Toast toast = Toast.makeText(this, R.string.message_list_help_key, Toast.LENGTH_LONG); toast.show(); @@ -785,19 +790,57 @@ public class FolderMessageList extends ExpandableListActivity MessageCompose.actionCompose(this, mAccount); } - private void onToggleThread() + private void changeSort(SORT_TYPE newSortType) { - thread = !thread; - - for (FolderInfoHolder folder : mAdapter.mFolders) - { - Collections.sort(folder.messages); - } - mAdapter.notifyDataSetChanged(); - setMenuThread(); - MessagingController.getInstance(getApplication()).setThreading(thread); - + sortType = newSortType; + MessagingController.getInstance(getApplication()).setSortType(sortType); + sortAscending = MessagingController.getInstance(getApplication()).isSortAscending(sortType); + sortDateAscending = MessagingController.getInstance(getApplication()).isSortAscending(SORT_TYPE.SORT_DATE); + reSort(); } + + private void reSort() + { + int toastString = sortType.getToast(sortAscending); + + Toast toast = Toast.makeText(this, toastString, Toast.LENGTH_SHORT); + toast.show(); + + for (FolderInfoHolder folder : mAdapter.mFolders) + { + Collections.sort(folder.messages); + } + mAdapter.notifyDataSetChanged(); + + } + + private void onCycleSort() + { + SORT_TYPE[] sorts = SORT_TYPE.values(); + int curIndex = 0; + for (int i = 0; i < sorts.length; i++) + { + if (sorts[i] == sortType) + { + curIndex = i; + break; + } + } + curIndex++; + if (curIndex == sorts.length) + { + curIndex = 0; + } + + changeSort(sorts[curIndex]); + } + + private void onToggleSortAscending() + { + sortAscending = !sortAscending; + MessagingController.getInstance(getApplication()).setSortAscending(sortType, sortAscending); + reSort(); + } private void onDelete(MessageInfoHolder holder) { @@ -908,41 +951,43 @@ public class FolderMessageList extends ExpandableListActivity case R.id.account_settings: onEditAccount(); return true; - case R.id.thread: - onToggleThread(); + case R.id.set_sort_date: + changeSort(SORT_TYPE.SORT_DATE); return true; - case R.id.empty_trash: - onEmptyTrash(mAccount); - return true; + case R.id.set_sort_subject: + changeSort(SORT_TYPE.SORT_SUBJECT); + return true; + case R.id.set_sort_sender: + changeSort(SORT_TYPE.SORT_SENDER); + return true; + case R.id.set_sort_flag: + changeSort(SORT_TYPE.SORT_FLAGGED); + return true; + case R.id.set_sort_unread: + changeSort(SORT_TYPE.SORT_UNREAD); + return true; + case R.id.set_sort_attach: + changeSort(SORT_TYPE.SORT_ATTACHMENT); + return true; + case R.id.reverse_sort: + onToggleSortAscending(); + return true; + case R.id.empty_trash: + onEmptyTrash(mAccount); + return true; default: return super.onOptionsItemSelected(item); - } - } + } + } @Override public boolean onCreateOptionsMenu(Menu menu) { super.onCreateOptionsMenu(menu); getMenuInflater().inflate(R.menu.folder_message_list_option, menu); - optionsMenu = menu; - setMenuThread(); return true; } - - private void setMenuThread() - { - Menu menu = optionsMenu; - if (menu != null) - { - MenuItem threadItem = menu.findItem(R.id.thread); - if (threadItem != null) - { - threadItem.setTitle(thread ? R.string.unthread_action : R.string.thread_action); - threadItem.setIcon(thread ? R.drawable.ic_menu_unthread : R.drawable.ic_menu_thread); - } - } - } @Override public boolean onContextItemSelected(MenuItem item) @@ -1082,6 +1127,7 @@ public class FolderMessageList extends ExpandableListActivity } } + private String truncateStatus(String mess) { if (mess != null && mess.length() > 27) @@ -1977,9 +2023,13 @@ public class FolderMessageList extends ExpandableListActivity } } + @Override public int compareTo(MessageInfoHolder o) { - if (thread) + int ascender = (sortAscending ? 1 : -1); + int comparison = 0; + + if (sortType == SORT_TYPE.SORT_SUBJECT) { if (compareSubject == null) { @@ -1989,15 +2039,35 @@ public class FolderMessageList extends ExpandableListActivity { o.compareSubject = stripPrefixes(o.subject).toLowerCase(); } - int subjCompare = this.compareSubject.compareTo(o.compareSubject); - if (subjCompare != 0) - { - return subjCompare; - } + comparison = this.compareSubject.compareTo(o.compareSubject); } - - return this.compareDate.compareTo(o.compareDate) * -1; - } + else if (sortType == SORT_TYPE.SORT_SENDER) + { + comparison = this.sender.toLowerCase().compareTo(o.sender.toLowerCase()); + } + else if (sortType == SORT_TYPE.SORT_FLAGGED) + { + comparison = (this.flagged ? 0 : 1) - (o.flagged ? 0 : 1); + + } + else if (sortType == SORT_TYPE.SORT_UNREAD) + { + comparison = (this.read ? 1 : 0) - (o.read ? 1 : 0); + } + else if (sortType == SORT_TYPE.SORT_ATTACHMENT) + { + comparison = (this.hasAttachments ? 0 : 1) - (o.hasAttachments ? 0 : 1); + + } + if (comparison != 0) + { + return comparison * ascender; + } + + int dateAscender = (sortDateAscending ? 1 : -1); + + return this.compareDate.compareTo(o.compareDate) * dateAscender; + } Pattern pattern = null; String patternString = "^ *(re|fw|fwd): *"; private String stripPrefixes(String in)