Changed terminology from Thread to Sort. Added sorting on sender,
flag, unread and attachments. Really, really, needs better icons.
This commit is contained in:
parent
cd386b17b3
commit
7a5b4d27e1
6 changed files with 246 additions and 70 deletions
BIN
res/drawable/ic_menu_reverse_sort.png
Normal file
BIN
res/drawable/ic_menu_reverse_sort.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.1 KiB |
BIN
res/drawable/ic_menu_set_sort.png
Normal file
BIN
res/drawable/ic_menu_set_sort.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2 KiB |
|
@ -1,17 +1,48 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item
|
||||
android:id="@+id/refresh"
|
||||
android:alphabeticShortcut="r"
|
||||
android:title="@string/refresh_action"
|
||||
android:icon="@drawable/ic_menu_refresh"
|
||||
/>
|
||||
<item
|
||||
<item
|
||||
android:id="@+id/compose"
|
||||
android:alphabeticShortcut="c"
|
||||
android:title="@string/compose_action"
|
||||
android:icon="@drawable/ic_menu_compose"
|
||||
/>
|
||||
<item
|
||||
android:id="@+id/set_sort"
|
||||
android:title="@string/sort_by"
|
||||
android:icon="@drawable/ic_menu_set_sort">
|
||||
|
||||
<menu>
|
||||
<item
|
||||
android:id="@+id/set_sort_date"
|
||||
android:title="@string/sort_by_date"
|
||||
/>
|
||||
<item
|
||||
android:id="@+id/set_sort_subject"
|
||||
android:title="@string/sort_by_subject"
|
||||
/>
|
||||
<item
|
||||
android:id="@+id/set_sort_sender"
|
||||
android:title="@string/sort_by_sender"
|
||||
/>
|
||||
<item
|
||||
android:id="@+id/set_sort_flag"
|
||||
android:title="@string/sort_by_flag"
|
||||
/>
|
||||
<item
|
||||
android:id="@+id/set_sort_unread"
|
||||
android:title="@string/sort_by_unread"
|
||||
/>
|
||||
<item
|
||||
android:id="@+id/set_sort_attach"
|
||||
android:title="@string/sort_by_attach"
|
||||
/>
|
||||
</menu>
|
||||
</item>
|
||||
<item
|
||||
android:id="@+id/reverse_sort"
|
||||
android:title="@string/reverse_sort_action"
|
||||
android:icon="@drawable/ic_menu_reverse_sort"
|
||||
/>
|
||||
<item
|
||||
android:id="@+id/empty_trash"
|
||||
android:alphabeticShortcut="e"
|
||||
|
@ -28,10 +59,12 @@
|
|||
android:title="@string/account_settings_action"
|
||||
android:icon="@android:drawable/ic_menu_preferences"
|
||||
/>
|
||||
<item
|
||||
android:id="@+id/thread"
|
||||
android:title="@string/thread_action"
|
||||
android:icon="@drawable/ic_menu_thread"
|
||||
<item
|
||||
android:id="@+id/refresh"
|
||||
android:alphabeticShortcut="r"
|
||||
android:title="@string/refresh_action"
|
||||
android:icon="@drawable/ic_menu_refresh"
|
||||
/>
|
||||
|
||||
|
||||
</menu>
|
||||
|
|
|
@ -60,8 +60,8 @@
|
|||
<string name="add_attachment_action">Add attachment</string>
|
||||
<string name="dump_settings_action">Dump settings</string>
|
||||
<string name="empty_trash_action">Empty Trash</string>
|
||||
<string name="thread_action">Thread</string>
|
||||
<string name="unthread_action">Unthread</string>
|
||||
<string name="set_sort_action">Choose sort</string>
|
||||
<string name="reverse_sort_action">Reverse sort</string>
|
||||
<string name="about_action">About</string>
|
||||
|
||||
<string name="accounts_context_menu_title">Account options</string>
|
||||
|
@ -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
|
|||
|
||||
<string name="account_settings_deleted_items_label">Deleted Items Folder</string>
|
||||
<string name="account_settings_deleted_items_summary">Set the deleted items folder</string>
|
||||
|
||||
<string name="sort_earliest_first">Earliest messages first</string>
|
||||
<string name="sort_latest_first">Latest messages first</string>
|
||||
<string name="sort_sender_alpha">Sender alphabetical</string>
|
||||
<string name="sort_sender_re_alpha">Sender reverse alphabetical</string>
|
||||
<string name="sort_subject_alpha">Subject alphabetical</string>
|
||||
<string name="sort_subject_re_alpha">Subject reverse alphabetical</string>
|
||||
<string name="sort_flagged_first">Flagged messages first</string>
|
||||
<string name="sort_flagged_last">Unflagged messages first</string>
|
||||
<string name="sort_unread_first">Unread messages first</string>
|
||||
<string name="sort_unread_last">Read messages first</string>
|
||||
<string name="sort_attach_first">Messages with attachments first</string>
|
||||
<string name="sort_unattached_first">Messages without attachments first</string>
|
||||
|
||||
<string name="sort_by">Sort by...</string>
|
||||
<string name="sort_by_date">Date</string>
|
||||
<string name="sort_by_sender">Sender</string>
|
||||
<string name="sort_by_subject">Subject</string>
|
||||
<string name="sort_by_flag">Flag</string>
|
||||
<string name="sort_by_unread">Read/unread</string>
|
||||
<string name="sort_by_attach">Attachments</string>
|
||||
|
||||
<string name="account_delete_dlg_title">Remove</string>
|
||||
<string name="account_delete_dlg_instructions_fmt">The account \"<xliff:g id="account">%s</xliff:g>\" will be removed from Email.</string>
|
||||
|
@ -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</string>
|
||||
<string name="message_list_help_key">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</string>
|
||||
</resources>
|
||||
|
|
|
@ -108,7 +108,44 @@ public class MessagingController implements Runnable {
|
|||
//private Set<MessagingListener> mListeners = Collections.synchronizedSet(new HashSet<MessagingListener>());
|
||||
private Set<MessagingListener> mListeners = new CopyOnWriteArraySet<MessagingListener>();
|
||||
|
||||
private boolean threading = false;
|
||||
private HashMap<SORT_TYPE, Boolean> sortAscending = new HashMap<SORT_TYPE, Boolean>();
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in a new issue