diff --git a/res/drawable/ic_mms_answered_small.png b/res/drawable/ic_mms_answered_small.png
new file mode 100644
index 000000000..2c9c69a66
Binary files /dev/null and b/res/drawable/ic_mms_answered_small.png differ
diff --git a/res/menu/folder_message_list_context.xml b/res/menu/folder_message_list_context.xml
index 27c45af94..a057ff8b9 100644
--- a/res/menu/folder_message_list_context.xml
+++ b/res/menu/folder_message_list_context.xml
@@ -24,6 +24,10 @@
android:id="@+id/mark_as_read"
android:title="@string/mark_as_read_action"
/>
+
- Mark as read
Forward (alternate)
Choose sender
+
+ Flag
+ Unflag
Mark as unread
Move to
@@ -353,8 +356,8 @@ Welcome to K-9 Mail setup. K-9 is an open source email client for Android based
Del (or D) - Delete\u000AR -
Reply\u000AA - Reply All\u000AF - Forward\u000AJ or P - Previous
Message\u000AK, N or space - Next Message\u000AZ - Zoom Out\u000AShift-Z -
- Zoom In
+ Zoom In\u000aG - Flag
Del (or D) - Delete\u000AR -
- Reply\u000AA - Reply All\u000AC - Compose\u000AF - Forward\u000AQ
+ Reply\u000AA - Reply All\u000AC - Compose\u000AF - Forward\\u000aG - Flagu000AQ
- Return to Accounts
diff --git a/src/com/android/email/Account.java b/src/com/android/email/Account.java
index 2bcbf76ae..04486d98a 100644
--- a/src/com/android/email/Account.java
+++ b/src/com/android/email/Account.java
@@ -51,6 +51,7 @@ public class Account implements Serializable {
int mAccountNumber;
boolean mVibrate;
String mRingtoneUri;
+ boolean showOngoing = true;
public enum FolderMode {
ALL, FIRST_CLASS, FIRST_AND_SECOND_CLASS, NOT_SECOND_CLASS;
@@ -505,4 +506,14 @@ public class Account implements Serializable {
mFolderSyncMode = syncMode;
}
+ public boolean isShowOngoing()
+ {
+ return showOngoing;
+ }
+
+ public void setShowOngoing(boolean showOngoing)
+ {
+ this.showOngoing = showOngoing;
+ }
+
}
diff --git a/src/com/android/email/MessagingController.java b/src/com/android/email/MessagingController.java
index 4e1e10969..05a76ea93 100644
--- a/src/com/android/email/MessagingController.java
+++ b/src/com/android/email/MessagingController.java
@@ -87,8 +87,8 @@ public class MessagingController implements Runnable {
private static final String PENDING_COMMAND_TRASH =
"com.android.email.MessagingController.trash";
- private static final String PENDING_COMMAND_MARK_READ =
- "com.android.email.MessagingController.markRead";
+ private static final String PENDING_COMMAND_SET_FLAG =
+ "com.android.email.MessagingController.setFlag";
private static final String PENDING_COMMAND_APPEND =
"com.android.email.MessagingController.append";
private static final String PENDING_COMMAND_MARK_ALL_AS_READ =
@@ -735,16 +735,23 @@ s * critical data as fast as possible, and then we'll fill in the de
fp.add(FetchProfile.Item.FLAGS);
remoteFolder.fetch(remoteMessages.toArray(new Message[0]), fp, null);
for (Message remoteMessage : remoteMessages) {
+ boolean messageChanged = false;
Message localMessage = localFolder.getMessage(remoteMessage.getUid());
if (localMessage == null) {
continue;
}
- if (!remoteMessage.isSet(Flag.X_NO_SEEN_INFO) && remoteMessage.isSet(Flag.SEEN) != localMessage.isSet(Flag.SEEN)) {
- localMessage.setFlag(Flag.SEEN, remoteMessage.isSet(Flag.SEEN));
- for (MessagingListener l : getListeners()) {
- l.synchronizeMailboxNewMessage(account, folder, localMessage);
- }
+ for (Flag flag : new Flag[] { Flag.SEEN, Flag.FLAGGED, Flag.ANSWERED } )
+ {
+ if (remoteMessage.isSet(flag) != localMessage.isSet(flag)) {
+ localMessage.setFlag(flag, remoteMessage.isSet(flag));
+
}
+ }
+ if (messageChanged) {
+ for (MessagingListener l : getListeners()) {
+ l.synchronizeMailboxNewMessage(account, folder, localMessage);
+ }
+ }
}
}
if (Config.LOGV) {
@@ -1071,8 +1078,8 @@ s * critical data as fast as possible, and then we'll fill in the de
if (PENDING_COMMAND_APPEND.equals(command.command)) {
processPendingAppend(command, account);
}
- else if (PENDING_COMMAND_MARK_READ.equals(command.command)) {
- processPendingMarkRead(command, account);
+ else if (PENDING_COMMAND_SET_FLAG.equals(command.command)) {
+ processPendingSetFlag(command, account);
}
else if (PENDING_COMMAND_MARK_ALL_AS_READ.equals(command.command)) {
processPendingMarkAllAsRead(command, account);
@@ -1286,7 +1293,7 @@ s * critical data as fast as possible, and then we'll fill in the de
* @param command arguments = (String folder, String uid, boolean read)
* @param account
*/
- private void processPendingMarkRead(PendingCommand command, Account account)
+ private void processPendingSetFlag(PendingCommand command, Account account)
throws MessagingException {
String folder = command.arguments[0];
String uid = command.arguments[1];
@@ -1296,7 +1303,9 @@ s * critical data as fast as possible, and then we'll fill in the de
return;
}
- boolean read = Boolean.parseBoolean(command.arguments[2]);
+ boolean newState = Boolean.parseBoolean(command.arguments[2]);
+
+ Flag flag = Flag.valueOf(command.arguments[3]);
Store remoteStore = Store.getInstance(account.getStoreUri(), mApplication);
Folder remoteFolder = remoteStore.getFolder(folder);
@@ -1315,7 +1324,7 @@ s * critical data as fast as possible, and then we'll fill in the de
if (remoteMessage == null) {
return;
}
- remoteMessage.setFlag(Flag.SEEN, read);
+ remoteMessage.setFlag(flag, newState);
}
private void processPendingMarkAllAsRead(PendingCommand command, Account account) throws MessagingException {
@@ -1437,6 +1446,9 @@ s * critical data as fast as possible, and then we'll fill in the de
processPendingCommands(account);
}
+
+
+
/**
* Mark the message with the given account, folder and uid either Seen or not Seen.
* @param account
@@ -1449,13 +1461,27 @@ s * critical data as fast as possible, and then we'll fill in the de
final String folder,
final String uid,
final boolean seen) {
+ setMessageFlag(account, folder, uid, Flag.SEEN, seen);
+ }
+
+
+ public void setMessageFlag(
+ final Account account,
+ final String folder,
+ final String uid,
+ final Flag flag,
+ boolean newState) {
try {
Store localStore = Store.getInstance(account.getLocalStoreUri(), mApplication);
Folder localFolder = localStore.getFolder(folder);
localFolder.open(OpenMode.READ_WRITE);
Message message = localFolder.getMessage(uid);
- message.setFlag(Flag.SEEN, seen);
+ message.setFlag(flag, newState);
+
+ for (MessagingListener l : getListeners()) {
+ l.folderStatusChanged(account, folder);
+ }
if (account.getErrorFolderName().equals(folder))
{
@@ -1463,8 +1489,8 @@ s * critical data as fast as possible, and then we'll fill in the de
}
PendingCommand command = new PendingCommand();
- command.command = PENDING_COMMAND_MARK_READ;
- command.arguments = new String[] { folder, uid, Boolean.toString(seen) };
+ command.command = PENDING_COMMAND_SET_FLAG;
+ command.arguments = new String[] { folder, uid, Boolean.toString(newState), flag.toString() };
queuePendingCommand(account, command);
processPendingCommands(account);
}
@@ -1951,8 +1977,8 @@ s * critical data as fast as possible, and then we'll fill in the de
else if (account.getDeletePolicy() == Account.DELETE_POLICY_MARK_AS_READ)
{
PendingCommand command = new PendingCommand();
- command.command = PENDING_COMMAND_MARK_READ;
- command.arguments = new String[] { folder, message.getUid(), Boolean.toString(true) };
+ command.command = PENDING_COMMAND_SET_FLAG;
+ command.arguments = new String[] { folder, message.getUid(), Boolean.toString(true), Flag.SEEN.toString() };
queuePendingCommand(account, command);
processPendingCommands(account);
}
@@ -2108,28 +2134,32 @@ s * critical data as fast as possible, and then we'll fill in the de
}
putBackground("sendPending " + account.getDescription(), null, new Runnable() {
public void run() {
- Notification notif = new Notification(R.drawable.ic_menu_refresh,
- context.getString(R.string.notification_bg_send_ticker, account.getDescription()), System.currentTimeMillis());
- Intent intent = FolderMessageList.actionHandleAccountIntent(context, account, Email.INBOX);
- PendingIntent pi = PendingIntent.getActivity(context, 0, intent, 0);
- notif.setLatestEventInfo(context, context.getString(R.string.notification_bg_send_title),
- account.getDescription() , pi);
- notif.flags = Notification.FLAG_ONGOING_EVENT;
-
- if (Email.NOTIFICATION_LED_WHILE_SYNCING) {
- notif.flags |= Notification.FLAG_SHOW_LIGHTS;
- notif.ledARGB = Email.NOTIFICATION_LED_DIM_COLOR;
- notif.ledOnMS = Email.NOTIFICATION_LED_FAST_ON_TIME;
- notif.ledOffMS = Email.NOTIFICATION_LED_FAST_OFF_TIME;
- }
-
- notifMgr.notify(Email.FETCHING_EMAIL_NOTIFICATION_ID, notif);
+ if (account.isShowOngoing()) {
+ Notification notif = new Notification(R.drawable.ic_menu_refresh,
+ context.getString(R.string.notification_bg_send_ticker, account.getDescription()), System.currentTimeMillis());
+ Intent intent = FolderMessageList.actionHandleAccountIntent(context, account, Email.INBOX);
+ PendingIntent pi = PendingIntent.getActivity(context, 0, intent, 0);
+ notif.setLatestEventInfo(context, context.getString(R.string.notification_bg_send_title),
+ account.getDescription() , pi);
+ notif.flags = Notification.FLAG_ONGOING_EVENT;
+
+ if (Email.NOTIFICATION_LED_WHILE_SYNCING) {
+ notif.flags |= Notification.FLAG_SHOW_LIGHTS;
+ notif.ledARGB = Email.NOTIFICATION_LED_DIM_COLOR;
+ notif.ledOnMS = Email.NOTIFICATION_LED_FAST_ON_TIME;
+ notif.ledOffMS = Email.NOTIFICATION_LED_FAST_OFF_TIME;
+ }
+
+ notifMgr.notify(Email.FETCHING_EMAIL_NOTIFICATION_ID, notif);
+ }
try
{
sendPendingMessagesSynchronous(account);
}
finally {
- notifMgr.cancel(Email.FETCHING_EMAIL_NOTIFICATION_ID);
+ if (account.showOngoing) {
+ notifMgr.cancel(Email.FETCHING_EMAIL_NOTIFICATION_ID);
+ }
}
}
}
@@ -2221,29 +2251,33 @@ s * critical data as fast as possible, and then we'll fill in the de
}
return;
}
- Notification notif = new Notification(R.drawable.ic_menu_refresh,
- context.getString(R.string.notification_bg_sync_ticker, account.getDescription(), folder.getName()),
- System.currentTimeMillis());
- Intent intent = FolderMessageList.actionHandleAccountIntent(context, account, Email.INBOX);
- PendingIntent pi = PendingIntent.getActivity(context, 0, intent, 0);
- notif.setLatestEventInfo(context, context.getString(R.string.notification_bg_sync_title), account.getDescription()
- + context.getString(R.string.notification_bg_title_separator) + folder.getName(), pi);
- notif.flags = Notification.FLAG_ONGOING_EVENT;
- if (Email.NOTIFICATION_LED_WHILE_SYNCING) {
- notif.flags |= Notification.FLAG_SHOW_LIGHTS;
- notif.ledARGB = Email.NOTIFICATION_LED_DIM_COLOR;
- notif.ledOnMS = Email.NOTIFICATION_LED_FAST_ON_TIME;
- notif.ledOffMS = Email.NOTIFICATION_LED_FAST_OFF_TIME;
- }
-
- notifMgr.notify(Email.FETCHING_EMAIL_NOTIFICATION_ID, notif);
+ if (account.isShowOngoing()) {
+ Notification notif = new Notification(R.drawable.ic_menu_refresh,
+ context.getString(R.string.notification_bg_sync_ticker, account.getDescription(), folder.getName()),
+ System.currentTimeMillis());
+ Intent intent = FolderMessageList.actionHandleAccountIntent(context, account, Email.INBOX);
+ PendingIntent pi = PendingIntent.getActivity(context, 0, intent, 0);
+ notif.setLatestEventInfo(context, context.getString(R.string.notification_bg_sync_title), account.getDescription()
+ + context.getString(R.string.notification_bg_title_separator) + folder.getName(), pi);
+ notif.flags = Notification.FLAG_ONGOING_EVENT;
+ if (Email.NOTIFICATION_LED_WHILE_SYNCING) {
+ notif.flags |= Notification.FLAG_SHOW_LIGHTS;
+ notif.ledARGB = Email.NOTIFICATION_LED_DIM_COLOR;
+ notif.ledOnMS = Email.NOTIFICATION_LED_FAST_ON_TIME;
+ notif.ledOffMS = Email.NOTIFICATION_LED_FAST_OFF_TIME;
+ }
+
+ notifMgr.notify(Email.FETCHING_EMAIL_NOTIFICATION_ID, notif);
+ }
try
{
synchronizeMailboxSynchronous(account, folder.getName());
}
finally {
- notifMgr.cancel(Email.FETCHING_EMAIL_NOTIFICATION_ID);
+ if (account.isShowOngoing()) {
+ notifMgr.cancel(Email.FETCHING_EMAIL_NOTIFICATION_ID);
+ }
}
}
catch (Exception e)
diff --git a/src/com/android/email/activity/FolderMessageList.java b/src/com/android/email/activity/FolderMessageList.java
index 45d3a0d36..e702610d6 100644
--- a/src/com/android/email/activity/FolderMessageList.java
+++ b/src/com/android/email/activity/FolderMessageList.java
@@ -639,6 +639,7 @@ public class FolderMessageList extends ExpandableListActivity
case KeyEvent.KEYCODE_F: { onForward(message); return true;}
case KeyEvent.KEYCODE_A: { onReplyAll(message); return true; }
case KeyEvent.KEYCODE_R: { onReply(message); return true; }
+ case KeyEvent.KEYCODE_G: { onToggleFlag(message); return true; }
}
}
}
@@ -832,6 +833,15 @@ public class FolderMessageList extends ExpandableListActivity
// onRefresh(false);
}
+ private void onToggleFlag(MessageInfoHolder holder)
+ {
+
+ MessagingController.getInstance(getApplication()).setMessageFlag(mAccount,
+ holder.message.getFolder().getName(), holder.uid, Flag.FLAGGED, !holder.flagged);
+ holder.flagged = !holder.flagged;
+ mHandler.dataChanged();
+ }
+
@Override
public boolean onOptionsItemSelected(MenuItem item)
{
@@ -901,6 +911,9 @@ public class FolderMessageList extends ExpandableListActivity
case R.id.mark_as_read:
onToggleRead(holder);
break;
+ case R.id.flag:
+ onToggleFlag(holder);
+ break;
case R.id.send_alternate:
onSendAlternate(mAccount, holder);
break;
@@ -976,7 +989,12 @@ public class FolderMessageList extends ExpandableListActivity
{
menu.findItem(R.id.mark_as_read).setTitle(
R.string.mark_as_unread_action);
- }
+ }
+ if (message.flagged)
+ {
+ menu.findItem(R.id.flag).setTitle(
+ R.string.unflag_action);
+ }
}
} else if (ExpandableListView.getPackedPositionType(info.packedPosition) == ExpandableListView.PACKED_POSITION_TYPE_GROUP)
{
@@ -1370,11 +1388,14 @@ public class FolderMessageList extends ExpandableListActivity
};
private Drawable mAttachmentIcon;
+ private Drawable mAnsweredIcon;
FolderMessageListAdapter()
{
mAttachmentIcon = getResources().getDrawable(
R.drawable.ic_mms_attachment_small);
+ mAnsweredIcon = getResources().getDrawable(
+ R.drawable.ic_mms_answered_small);
}
public void removeDeletedUid(String folder, String messageUid) {
@@ -1716,15 +1737,28 @@ public class FolderMessageList extends ExpandableListActivity
if (message != null)
{
holder.chip.getBackground().setAlpha(message.read ? 0 : 255);
+
+ holder.subject.setTypeface(null,
+ message.read && !message.flagged ? Typeface.NORMAL : Typeface.BOLD);
+
+ if (message.flagged)
+ {
+ holder.subject.setTextColor(0xffff4444);
+ }
+ else
+ {
+ holder.subject.setTextColor(0xffffffff);
+ }
holder.subject.setText(message.subject);
- holder.subject.setTypeface(null, message.read ? Typeface.NORMAL
- : Typeface.BOLD);
+
holder.from.setText(message.sender);
- holder.from.setTypeface(null, message.read ? Typeface.NORMAL
- : Typeface.BOLD);
+ holder.from.setTypeface(null, message.read ? Typeface.NORMAL : Typeface.BOLD);
holder.date.setText(message.date);
- holder.subject.setCompoundDrawablesWithIntrinsicBounds(null, null,
- message.hasAttachments ? mAttachmentIcon : null, null);
+ holder.subject.setCompoundDrawablesWithIntrinsicBounds(
+ message.answered ? mAnsweredIcon : null, // left
+ null, // top
+ message.hasAttachments ? mAttachmentIcon : null, // right
+ null); // bottom
}
else
{
@@ -1804,12 +1838,18 @@ public class FolderMessageList extends ExpandableListActivity
public Date compareDate;
public String sender;
+
+ public String[] recipients;
public boolean hasAttachments;
public String uid;
public boolean read;
+
+ public boolean answered;
+
+ public boolean flagged;
public Message message;
@@ -1837,6 +1877,8 @@ public class FolderMessageList extends ExpandableListActivity
}
this.hasAttachments = message.getAttachmentCount() > 0;
this.read = message.isSet(Flag.SEEN);
+ this.answered = message.isSet(Flag.ANSWERED);
+ this.flagged = message.isSet(Flag.FLAGGED);
if (folder.outbox)
{
this.sender = Address.toFriendly(message
diff --git a/src/com/android/email/activity/MessageCompose.java b/src/com/android/email/activity/MessageCompose.java
index b1bfce2aa..99d5f44ae 100644
--- a/src/com/android/email/activity/MessageCompose.java
+++ b/src/com/android/email/activity/MessageCompose.java
@@ -47,6 +47,7 @@ import com.android.email.R;
import com.android.email.Utility;
import com.android.email.mail.Address;
import com.android.email.mail.Body;
+import com.android.email.mail.Flag;
import com.android.email.mail.Message;
import com.android.email.mail.MessagingException;
import com.android.email.mail.Multipart;
@@ -199,7 +200,7 @@ public class MessageCompose extends Activity implements OnClickListener, OnFocus
Context context,
Account account,
Message message,
- boolean replyAll) {
+ boolean replyAll) {
Intent i = new Intent(context, MessageCompose.class);
i.putExtra(EXTRA_ACCOUNT, account);
i.putExtra(EXTRA_FOLDER, message.getFolder().getName());
@@ -394,6 +395,15 @@ public class MessageCompose extends Activity implements OnClickListener, OnFocus
mFolder = (String) intent.getStringExtra(EXTRA_FOLDER);
mSourceMessageUid = (String) intent.getStringExtra(EXTRA_MESSAGE);
}
+
+ Log.d(Email.LOG_TAG, "action = " + action + ", mAccount = " + mAccount + ", mFolder = " + mFolder + ", mSourceMessageUid = " + mSourceMessageUid);
+ if ((ACTION_REPLY.equals(action) || ACTION_REPLY_ALL.equals(action)) && mAccount != null && mFolder != null && mSourceMessageUid != null)
+ {
+ Log.d(Email.LOG_TAG, "Setting message ANSWERED flag to true");
+ // TODO: Really, we should wait until we send the message, but that would require saving the original
+ // message info along with a Draft copy, in case it is left in Drafts for a while before being sent
+ MessagingController.getInstance(getApplication()).setMessageFlag(mAccount, mFolder, mSourceMessageUid, Flag.ANSWERED, true);
+ }
if (ACTION_REPLY.equals(action) || ACTION_REPLY_ALL.equals(action) ||
ACTION_FORWARD.equals(action) || ACTION_EDIT_DRAFT.equals(action)) {
diff --git a/src/com/android/email/activity/MessageView.java b/src/com/android/email/activity/MessageView.java
index 78e3b6a77..4ed91553c 100644
--- a/src/com/android/email/activity/MessageView.java
+++ b/src/com/android/email/activity/MessageView.java
@@ -55,6 +55,7 @@ import com.android.email.MessagingListener;
import com.android.email.R;
import com.android.email.Utility;
import com.android.email.mail.Address;
+import com.android.email.mail.Flag;
import com.android.email.mail.Message;
import com.android.email.mail.MessagingException;
import com.android.email.mail.Multipart;
@@ -132,6 +133,7 @@ public class MessageView extends Activity
case KeyEvent.KEYCODE_F: { onForward(); return true;}
case KeyEvent.KEYCODE_A: { onReplyAll(); return true; }
case KeyEvent.KEYCODE_R: { onReply(); return true; }
+ case KeyEvent.KEYCODE_G: { onFlag(); return true; }
case KeyEvent.KEYCODE_J:
case KeyEvent.KEYCODE_P:
{ onPrevious(); return true; }
@@ -492,6 +494,22 @@ public class MessageView extends Activity
}
}
+ private void onFlag() {
+ if (mMessage != null) {
+ MessagingController.getInstance(getApplication()).setMessageFlag(mAccount,
+ mMessage.getFolder().getName(), mMessage.getUid(), Flag.FLAGGED, !mMessage.isSet(Flag.FLAGGED));
+ try
+ {
+ mMessage.setFlag(Flag.FLAGGED, !mMessage.isSet(Flag.FLAGGED));
+ }
+ catch (MessagingException me)
+ {
+ Log.e(Email.LOG_TAG, "Could not set flag on local message", me);
+ }
+ }
+ }
+
+
private void onSendAlternate() {
if (mMessage != null) {
MessagingController.getInstance(getApplication()).sendAlternate(this, mAccount, mMessage);
diff --git a/src/com/android/email/mail/store/ImapStore.java b/src/com/android/email/mail/store/ImapStore.java
index d1689225d..14dabb20d 100644
--- a/src/com/android/email/mail/store/ImapStore.java
+++ b/src/com/android/email/mail/store/ImapStore.java
@@ -1100,6 +1100,13 @@ public class ImapStore extends Store {
else if (flag == Flag.DELETED) {
flagNames.add("\\Deleted");
}
+ else if (flag == Flag.ANSWERED) {
+ flagNames.add("\\Answered");
+ }
+ else if (flag == Flag.FLAGGED) {
+ flagNames.add("\\Flagged");
+ }
+
}
try {
mConnection.executeSimpleCommand(String.format("UID STORE 1:* %sFLAGS.SILENT (%s)",
@@ -1127,6 +1134,12 @@ public class ImapStore extends Store {
else if (flag == Flag.DELETED) {
flagNames.add("\\Deleted");
}
+ else if (flag == Flag.ANSWERED) {
+ flagNames.add("\\Answered");
+ }
+ else if (flag == Flag.FLAGGED) {
+ flagNames.add("\\Flagged");
+ }
}
try {
mConnection.executeSimpleCommand(String.format("UID STORE %s %sFLAGS.SILENT (%s)",