mirror of
https://github.com/moparisthebest/k-9
synced 2025-02-07 10:40:11 -05:00
Merge pull request #171 from aatdark/aatdark_issue1035
Add $Forwarded IMAP flag support.
This commit is contained in:
commit
05a53daddc
BIN
res/drawable-hdpi/ic_email_forwarded_small.png
Normal file
BIN
res/drawable-hdpi/ic_email_forwarded_small.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 906 B |
BIN
res/drawable/ic_email_forwarded_answered_small.png
Normal file
BIN
res/drawable/ic_email_forwarded_answered_small.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 410 B |
BIN
res/drawable/ic_email_forwarded_small.png
Normal file
BIN
res/drawable/ic_email_forwarded_small.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 900 B |
@ -148,7 +148,12 @@
|
||||
android:layout_height="22sp"
|
||||
android:paddingRight="4dip"
|
||||
android:background="@drawable/ic_email_answered_small"/>
|
||||
|
||||
<View
|
||||
android:id="@+id/forwarded"
|
||||
android:layout_width="22sp"
|
||||
android:layout_height="22sp"
|
||||
android:paddingRight="4dip"
|
||||
android:background="@drawable/ic_email_forwarded_small"/>
|
||||
<CheckBox
|
||||
android:id="@+id/flagged"
|
||||
android:layout_width="wrap_content"
|
||||
|
@ -753,6 +753,9 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc
|
||||
mToView.requestFocus();
|
||||
}
|
||||
|
||||
if (mAction == Action.FORWARD) {
|
||||
mMessageReference.flag = Flag.FORWARDED;
|
||||
}
|
||||
|
||||
mEncryptLayout = findViewById(R.id.layout_encrypt);
|
||||
mCryptoSignatureCheckbox = (CheckBox)findViewById(R.id.cb_crypto_signature);
|
||||
|
@ -16,6 +16,7 @@ public class MessageInfoHolder {
|
||||
public String uid;
|
||||
public boolean read;
|
||||
public boolean answered;
|
||||
public boolean forwarded;
|
||||
public boolean flagged;
|
||||
public boolean dirty;
|
||||
public LocalMessage message;
|
||||
|
@ -2029,11 +2029,15 @@ public class MessageList
|
||||
}
|
||||
|
||||
private Drawable mAttachmentIcon;
|
||||
private Drawable mForwardedIcon;
|
||||
private Drawable mAnsweredIcon;
|
||||
private Drawable mForwardedAnsweredIcon;
|
||||
|
||||
MessageListAdapter() {
|
||||
mAttachmentIcon = getResources().getDrawable(R.drawable.ic_email_attachment_small);
|
||||
mAnsweredIcon = getResources().getDrawable(R.drawable.ic_email_answered_small);
|
||||
mForwardedIcon = getResources().getDrawable(R.drawable.ic_email_forwarded_small);
|
||||
mForwardedAnsweredIcon = getResources().getDrawable(R.drawable.ic_email_forwarded_answered_small);
|
||||
}
|
||||
|
||||
public void markAllMessagesAsDirty() {
|
||||
@ -2405,11 +2409,19 @@ public class MessageList
|
||||
}
|
||||
|
||||
holder.date.setText(message.getDate(mMessageHelper));
|
||||
holder.subject.setCompoundDrawablesWithIntrinsicBounds(
|
||||
message.answered ? mAnsweredIcon : null, // left
|
||||
null, // top
|
||||
message.message.hasAttachments() ? mAttachmentIcon : null, // right
|
||||
null); // bottom
|
||||
|
||||
Drawable statusHolder = null;
|
||||
if (message.forwarded && message.answered) {
|
||||
statusHolder = mForwardedAnsweredIcon;
|
||||
} else if (message.answered) {
|
||||
statusHolder = mAnsweredIcon;
|
||||
} else if (message.forwarded) {
|
||||
statusHolder = mForwardedIcon;
|
||||
}
|
||||
holder.subject.setCompoundDrawablesWithIntrinsicBounds(statusHolder, // left
|
||||
null, // top
|
||||
message.message.hasAttachments() ? mAttachmentIcon : null, // right
|
||||
null); // bottom
|
||||
holder.position = position;
|
||||
}
|
||||
|
||||
|
@ -157,6 +157,8 @@ public class MessagingController implements Runnable {
|
||||
// Key is accountUuid:folderName:messageUid , value is unimportant
|
||||
private ConcurrentHashMap<String, String> deletedUids = new ConcurrentHashMap<String, String>();
|
||||
|
||||
private static final Flag[] SYNC_FLAGS = new Flag[] { Flag.SEEN, Flag.FLAGGED, Flag.ANSWERED, Flag.FORWARDED };
|
||||
|
||||
private String createMessageKey(Account account, String folder, Message message) {
|
||||
return createMessageKey(account, folder, message.getUid());
|
||||
}
|
||||
@ -1763,7 +1765,7 @@ public class MessagingController implements Runnable {
|
||||
messageChanged = true;
|
||||
}
|
||||
} else {
|
||||
for (Flag flag : new Flag[] { Flag.SEEN, Flag.FLAGGED, Flag.ANSWERED }) {
|
||||
for (Flag flag : MessagingController.SYNC_FLAGS) {
|
||||
if (remoteMessage.isSet(flag) != localMessage.isSet(flag)) {
|
||||
localMessage.setFlag(flag, remoteMessage.isSet(flag));
|
||||
messageChanged = true;
|
||||
|
@ -59,6 +59,7 @@ public class MessageHelper {
|
||||
|
||||
target.read = message.isSet(Flag.SEEN);
|
||||
target.answered = message.isSet(Flag.ANSWERED);
|
||||
target.forwarded = message.isSet(Flag.FORWARDED);
|
||||
target.flagged = message.isSet(Flag.FLAGGED);
|
||||
|
||||
Address[] addrs = message.getFrom();
|
||||
|
@ -11,6 +11,7 @@ public enum Flag {
|
||||
FLAGGED,
|
||||
DRAFT,
|
||||
RECENT,
|
||||
FORWARDED,
|
||||
|
||||
/*
|
||||
* The following flags are for internal library use only.
|
||||
|
@ -146,10 +146,15 @@ public abstract class Folder {
|
||||
|
||||
public abstract String getName();
|
||||
|
||||
public abstract Flag[] getPermanentFlags();
|
||||
|
||||
/**
|
||||
*
|
||||
* Indicated by the server "\*" ( * OK [PERMANENTFLAGS (\Answered .. \*)] Flags permitted). that
|
||||
* new keywords may be created
|
||||
*/
|
||||
protected boolean mCanCreateKeywords = false;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param oldPushState
|
||||
* @param message
|
||||
* @return empty string to clear the pushState, null to leave the state as-is
|
||||
|
@ -122,7 +122,7 @@ public class ImapStore extends Store {
|
||||
|
||||
private static int FETCH_WINDOW_SIZE = 100;
|
||||
|
||||
private static final Flag[] PERMANENT_FLAGS = { Flag.DELETED, Flag.SEEN };
|
||||
private Set<Flag> mPermanentFlagsIndex = new HashSet<Flag>();
|
||||
|
||||
private static final String CAPABILITY_IDLE = "IDLE";
|
||||
private static final String COMMAND_IDLE = "IDLE";
|
||||
@ -897,27 +897,38 @@ public class ImapStore extends Store {
|
||||
// 2 OK [READ-WRITE] Select completed.
|
||||
try {
|
||||
msgSeqUidMap.clear();
|
||||
String command = String.format("%s %s", mode == OpenMode.READ_WRITE ? "SELECT" : "EXAMINE",
|
||||
encodeString(encodeFolderName(getPrefixedName())));
|
||||
String command = String.format("%s %s", mode == OpenMode.READ_WRITE ? "SELECT"
|
||||
: "EXAMINE", encodeString(encodeFolderName(getPrefixedName())));
|
||||
|
||||
List<ImapResponse> responses = executeSimpleCommand(command);
|
||||
|
||||
/*
|
||||
* If the command succeeds we expect the folder has been opened read-write
|
||||
* unless we are notified otherwise in the responses.
|
||||
* If the command succeeds we expect the folder has been opened read-write unless we
|
||||
* are notified otherwise in the responses.
|
||||
*/
|
||||
mMode = mode;
|
||||
|
||||
for (ImapResponse response : responses) {
|
||||
if (response.mTag != null && response.size() >= 2) {
|
||||
if (response.size() >= 2) {
|
||||
Object bracketedObj = response.get(1);
|
||||
if (bracketedObj instanceof ImapList) {
|
||||
ImapList bracketed = (ImapList)bracketedObj;
|
||||
if (!(bracketedObj instanceof ImapList)) {
|
||||
continue;
|
||||
}
|
||||
ImapList bracketed = (ImapList) bracketedObj;
|
||||
if (bracketed.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!bracketed.isEmpty()) {
|
||||
Object keyObj = bracketed.get(0);
|
||||
if (keyObj instanceof String) {
|
||||
String key = (String)keyObj;
|
||||
ImapList flags = bracketed.getKeyedList("PERMANENTFLAGS");
|
||||
if (flags != null) {
|
||||
// parse: * OK [PERMANENTFLAGS (\Answered \Flagged \Deleted
|
||||
// \Seen \Draft NonJunk $label1 \*)] Flags permitted.
|
||||
parseFlags(flags);
|
||||
} else {
|
||||
Object keyObj = bracketed.get(0);
|
||||
if (keyObj instanceof String) {
|
||||
String key = (String) keyObj;
|
||||
if (response.mTag != null) {
|
||||
|
||||
if ("READ-ONLY".equalsIgnoreCase(key)) {
|
||||
mMode = OpenMode.READ_ONLY;
|
||||
@ -927,10 +938,8 @@ public class ImapStore extends Store {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
mExists = true;
|
||||
return responses;
|
||||
} catch (IOException ioe) {
|
||||
@ -939,7 +948,33 @@ public class ImapStore extends Store {
|
||||
Log.e(K9.LOG_TAG, "Unable to open connection for " + getLogId(), me);
|
||||
throw me;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses an string like PERMANENTFLAGS (\Answered \Flagged \Deleted // \Seen \Draft NonJunk
|
||||
* $label1 \*)
|
||||
*
|
||||
* the parsed flags are stored in the mPermanentFlagsIndex
|
||||
* @param flags
|
||||
* the imapflags as strings
|
||||
*/
|
||||
private void parseFlags(ImapList flags) {
|
||||
for (Object flag : flags) {
|
||||
flag = flag.toString().toLowerCase();
|
||||
if (flag.equals("\\deleted")) {
|
||||
mPermanentFlagsIndex.add(Flag.DELETED);
|
||||
} else if (flag.equals("\\answered")) {
|
||||
mPermanentFlagsIndex.add(Flag.ANSWERED);
|
||||
} else if (flag.equals("\\seen")) {
|
||||
mPermanentFlagsIndex.add(Flag.SEEN);
|
||||
} else if (flag.equals("\\flagged")) {
|
||||
mPermanentFlagsIndex.add(Flag.FLAGGED);
|
||||
} else if (flag.equals("$forwarded")) {
|
||||
mPermanentFlagsIndex.add(Flag.FORWARDED);
|
||||
} else if (flag.equals("\\*")) {
|
||||
mCanCreateKeywords = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -1626,6 +1661,10 @@ public class ImapStore extends Store {
|
||||
message.setFlagInternal(Flag.SEEN, true);
|
||||
} else if (flag.equalsIgnoreCase("\\Flagged")) {
|
||||
message.setFlagInternal(Flag.FLAGGED, true);
|
||||
} else if (flag.equalsIgnoreCase("$Forwarded")) {
|
||||
message.setFlagInternal(Flag.FORWARDED, true);
|
||||
/* a message contains FORWARDED FLAG -> so we can also create them */
|
||||
mPermanentFlagsIndex.add(Flag.FORWARDED);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1673,11 +1712,6 @@ public class ImapStore extends Store {
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Flag[] getPermanentFlags() {
|
||||
return PERMANENT_FLAGS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle any untagged responses that the caller doesn't care to handle themselves.
|
||||
* @param responses
|
||||
@ -2067,6 +2101,9 @@ public class ImapStore extends Store {
|
||||
flagNames.add("\\Answered");
|
||||
} else if (flag == Flag.FLAGGED) {
|
||||
flagNames.add("\\Flagged");
|
||||
} else if (flag == Flag.FORWARDED
|
||||
&& (mCanCreateKeywords || mPermanentFlagsIndex.contains(Flag.FORWARDED))) {
|
||||
flagNames.add("$Forwarded");
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -2688,12 +2688,6 @@ public class LocalStore extends Store implements Serializable {
|
||||
return mName.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Flag[] getPermanentFlags() {
|
||||
return PERMANENT_FLAGS;
|
||||
}
|
||||
|
||||
|
||||
private void deleteAttachments(final long messageId) throws MessagingException {
|
||||
open(OpenMode.READ_WRITE);
|
||||
database.execute(false, new DbCallback<Void>() {
|
||||
|
@ -19,6 +19,7 @@ import java.net.*;
|
||||
import java.security.GeneralSecurityException;
|
||||
import java.security.SecureRandom;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.LinkedList;
|
||||
import java.util.HashMap;
|
||||
@ -884,11 +885,6 @@ public class Pop3Store extends Store {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Flag[] getPermanentFlags() {
|
||||
return PERMANENT_FLAGS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> appendMessages(Message[] messages) throws MessagingException {
|
||||
return null;
|
||||
|
@ -70,8 +70,6 @@ public class WebDavStore extends Store {
|
||||
private static final short AUTH_TYPE_BASIC = 1;
|
||||
private static final short AUTH_TYPE_FORM_BASED = 2;
|
||||
|
||||
private static final Flag[] PERMANENT_FLAGS = { Flag.DELETED, Flag.SEEN, Flag.ANSWERED };
|
||||
|
||||
private static final String[] EMPTY_STRING_ARRAY = new String[0];
|
||||
|
||||
private static final Message[] EMPTY_MESSAGE_ARRAY = new Message[0];
|
||||
@ -1846,11 +1844,6 @@ public class WebDavStore extends Store {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Flag[] getPermanentFlags() {
|
||||
return PERMANENT_FLAGS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFlags(Message[] messages, Flag[] flags, boolean value)
|
||||
throws MessagingException {
|
||||
|
@ -57,6 +57,7 @@ public class MessageHeader extends ScrollView implements OnClickListener {
|
||||
private LinearLayout mCcContainerView;
|
||||
private TextView mAdditionalHeadersView;
|
||||
private View mAnsweredIcon;
|
||||
private View mForwardedIcon;
|
||||
private Message mMessage;
|
||||
private Account mAccount;
|
||||
private FontSizes mFontSizes = K9.getFontSizes();
|
||||
@ -90,6 +91,7 @@ public class MessageHeader extends ScrollView implements OnClickListener {
|
||||
|
||||
private void initializeLayout() {
|
||||
mAnsweredIcon = findViewById(R.id.answered);
|
||||
mForwardedIcon= findViewById(R.id.forwarded);
|
||||
mFromView = (TextView) findViewById(R.id.from);
|
||||
mToView = (TextView) findViewById(R.id.to);
|
||||
mCcView = (TextView) findViewById(R.id.cc);
|
||||
@ -113,6 +115,8 @@ public class MessageHeader extends ScrollView implements OnClickListener {
|
||||
hideAdditionalHeaders();
|
||||
|
||||
mAnsweredIcon.setVisibility(View.GONE);
|
||||
mForwardedIcon.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());
|
||||
@ -256,6 +260,7 @@ public class MessageHeader extends ScrollView implements OnClickListener {
|
||||
mCcContainerView.setVisibility((cc != null && cc.length() > 0) ? View.VISIBLE : View.GONE);
|
||||
mCcView.setText(cc);
|
||||
mAnsweredIcon.setVisibility(message.isSet(Flag.ANSWERED) ? View.VISIBLE : View.GONE);
|
||||
mForwardedIcon.setVisibility(message.isSet(Flag.FORWARDED) ? View.VISIBLE : View.GONE);
|
||||
mFlagged.setChecked(message.isSet(Flag.FLAGGED));
|
||||
|
||||
int chipColor = mAccount.getChipColor();
|
||||
|
Loading…
Reference in New Issue
Block a user