1
0
mirror of https://github.com/moparisthebest/k-9 synced 2025-02-07 02:30:10 -05:00

+ add support for $Forwarded IMAP flag

This commit is contained in:
Bernhard Redl 2012-08-21 04:09:34 +02:00
parent c0153a1636
commit 56105bcfe3
16 changed files with 103 additions and 46 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 906 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 410 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 900 B

View File

@ -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"

View File

@ -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);

View File

@ -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;

View File

@ -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_answerred_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;
}

View File

@ -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[] SYNCFLAGS = 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.SYNCFLAGS) {
if (remoteMessage.isSet(flag) != localMessage.isSet(flag)) {
localMessage.setFlag(flag, remoteMessage.isSet(flag));
messageChanged = true;

View File

@ -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();

View File

@ -11,6 +11,7 @@ public enum Flag {
FLAGGED,
DRAFT,
RECENT,
FORWARDED,
/*
* The following flags are for internal library use only.

View File

@ -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

View File

@ -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, mPermanentFlagsIndex);
} 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,35 @@ 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 \*)
* @param flags
* the imapflags as strings
* @param out
* an already initialized Set which is used return the found flags
*/
private void parseFlags(ImapList flags, Set<Flag> out) {
for (Object flag : flags) {
flag = flag.toString().toLowerCase();
if (flag.equals("permanentflags")) {
continue;
} else if (flag.equals("\\deleted")) {
out.add(Flag.DELETED);
} else if (flag.equals("\\answered")) {
out.add(Flag.ANSWERED);
} else if (flag.equals("\\seen")) {
out.add(Flag.SEEN);
} else if (flag.equals("\\flagged")) {
out.add(Flag.FLAGGED);
} else if (flag.equals("$forwarded")) {
out.add(Flag.FORWARDED);
} else if (flag.equals("\\*")) {
mCanCreateKeywords = true;
}
}
}
@Override
@ -1626,6 +1663,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 +1714,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 +2103,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");
}
}

View File

@ -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>() {

View File

@ -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;

View File

@ -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 {

View File

@ -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();