diff --git a/images/drawables-pgp/status_lock_closed.svg b/images/drawables-pgp/status_lock_closed.svg new file mode 100644 index 000000000..286e89297 --- /dev/null +++ b/images/drawables-pgp/status_lock_closed.svg @@ -0,0 +1,12 @@ + + + + lock-closed + Created with Sketch. + + + + + + + \ No newline at end of file diff --git a/images/drawables-pgp/status_lock_error.svg b/images/drawables-pgp/status_lock_error.svg new file mode 100644 index 000000000..d3c4e1d1d --- /dev/null +++ b/images/drawables-pgp/status_lock_error.svg @@ -0,0 +1,12 @@ + + + + lock-error + Created with Sketch. + + + + + + + \ No newline at end of file diff --git a/images/drawables-pgp/status_lock_open.svg b/images/drawables-pgp/status_lock_open.svg new file mode 100644 index 000000000..9beb127af --- /dev/null +++ b/images/drawables-pgp/status_lock_open.svg @@ -0,0 +1,12 @@ + + + + lock-open + Created with Sketch. + + + + + + + \ No newline at end of file diff --git a/images/drawables-pgp/status_signature_expired_cutout.svg b/images/drawables-pgp/status_signature_expired_cutout.svg new file mode 100644 index 000000000..61ac8fdd0 --- /dev/null +++ b/images/drawables-pgp/status_signature_expired_cutout.svg @@ -0,0 +1,12 @@ + + + + signature-expired-cutout + Created with Sketch. + + + + + + + \ No newline at end of file diff --git a/images/drawables-pgp/status_signature_invalid_cutout.svg b/images/drawables-pgp/status_signature_invalid_cutout.svg new file mode 100644 index 000000000..61fd2ace0 --- /dev/null +++ b/images/drawables-pgp/status_signature_invalid_cutout.svg @@ -0,0 +1,12 @@ + + + + signature-invalid-cutout + Created with Sketch. + + + + + + + \ No newline at end of file diff --git a/images/drawables-pgp/status_signature_revoked_cutout.svg b/images/drawables-pgp/status_signature_revoked_cutout.svg new file mode 100644 index 000000000..0421286fe --- /dev/null +++ b/images/drawables-pgp/status_signature_revoked_cutout.svg @@ -0,0 +1,12 @@ + + + + signature-revoked-cutout + Created with Sketch. + + + + + + + \ No newline at end of file diff --git a/images/drawables-pgp/status_signature_unknown_cutout.svg b/images/drawables-pgp/status_signature_unknown_cutout.svg new file mode 100644 index 000000000..402bffcaa --- /dev/null +++ b/images/drawables-pgp/status_signature_unknown_cutout.svg @@ -0,0 +1,12 @@ + + + + signature-unknown-cutout + Created with Sketch. + + + + + + + \ No newline at end of file diff --git a/images/drawables-pgp/status_signature_unverified_cutout.svg b/images/drawables-pgp/status_signature_unverified_cutout.svg new file mode 100644 index 000000000..ffa98580a --- /dev/null +++ b/images/drawables-pgp/status_signature_unverified_cutout.svg @@ -0,0 +1,12 @@ + + + + signature-unverified-cutout + Created with Sketch. + + + + + + + \ No newline at end of file diff --git a/images/drawables-pgp/status_signature_verified_cutout.svg b/images/drawables-pgp/status_signature_verified_cutout.svg new file mode 100644 index 000000000..04356a977 --- /dev/null +++ b/images/drawables-pgp/status_signature_verified_cutout.svg @@ -0,0 +1,12 @@ + + + + signature-verified-cutout + Created with Sketch. + + + + + + + \ No newline at end of file diff --git a/images/update-drawables-pgp.sh b/images/update-drawables-pgp.sh new file mode 100755 index 000000000..45220ebc5 --- /dev/null +++ b/images/update-drawables-pgp.sh @@ -0,0 +1,19 @@ +#!/bin/bash + +APP_DIR=../k9mail/src/main +MDPI_DIR=$APP_DIR/res/drawable-mdpi +HDPI_DIR=$APP_DIR/res/drawable-hdpi +XDPI_DIR=$APP_DIR/res/drawable-xhdpi +XXDPI_DIR=$APP_DIR/res/drawable-xxhdpi +XXXDPI_DIR=$APP_DIR/res/drawable-xxxhdpi +SRC_DIR=./drawables-pgp/ + + +for NAME in "status_lock_closed" "status_lock_error" "status_lock_open" "status_signature_expired_cutout" "status_signature_invalid_cutout" "status_signature_revoked_cutout" "status_signature_unknown_cutout" "status_signature_unverified_cutout" "status_signature_verified_cutout" +do +echo $NAME +inkscape -w 24 -h 24 -e "$MDPI_DIR/$NAME.png" "$SRC_DIR/$NAME.svg" +inkscape -w 32 -h 32 -e "$HDPI_DIR/$NAME.png" "$SRC_DIR/$NAME.svg" +inkscape -w 48 -h 48 -e "$XDPI_DIR/$NAME.png" "$SRC_DIR/$NAME.svg" +inkscape -w 64 -h 64 -e "$XXDPI_DIR/$NAME.png" "$SRC_DIR/$NAME.svg" +done diff --git a/k9mail/src/androidTest/java/com/fsck/k9/mailstore/LocalMessageExtractorTest.java b/k9mail/src/androidTest/java/com/fsck/k9/mailstore/LocalMessageExtractorTest.java index 6086118af..ba2c0471d 100644 --- a/k9mail/src/androidTest/java/com/fsck/k9/mailstore/LocalMessageExtractorTest.java +++ b/k9mail/src/androidTest/java/com/fsck/k9/mailstore/LocalMessageExtractorTest.java @@ -1,5 +1,6 @@ package com.fsck.k9.mailstore; +import java.util.ArrayList; import java.util.Date; import java.util.Locale; import java.util.TimeZone; @@ -11,6 +12,8 @@ import com.fsck.k9.activity.K9ActivityCommon; import com.fsck.k9.mail.Address; import com.fsck.k9.mail.Message.RecipientType; import com.fsck.k9.mail.MessagingException; +import com.fsck.k9.mail.Part; +import com.fsck.k9.mail.internet.MessageExtractor; import com.fsck.k9.mail.internet.MimeBodyPart; import com.fsck.k9.mail.internet.MimeMessage; import com.fsck.k9.mail.internet.MimeMessageHelper; @@ -38,7 +41,8 @@ public class LocalMessageExtractorTest { MimeMessageHelper.setBody(message, body); // Extract text - ViewableContainer container = extractTextAndAttachments(InstrumentationRegistry.getTargetContext(), message); + ViewableContainer container = extractTextAndAttachments(InstrumentationRegistry.getTargetContext(), + MessageExtractor.getViewables(message, attachments), new ArrayList()); String expectedText = bodyText; String expectedHtml = @@ -63,7 +67,8 @@ public class LocalMessageExtractorTest { MimeMessageHelper.setBody(message, body); // Extract text - ViewableContainer container = extractTextAndAttachments(InstrumentationRegistry.getTargetContext(), message); + ViewableContainer container = extractTextAndAttachments(InstrumentationRegistry.getTargetContext(), + MessageExtractor.getViewables(message, attachments), new ArrayList()); String expectedText = "K-9 Mail rocks :>"; String expectedHtml = @@ -94,7 +99,8 @@ public class LocalMessageExtractorTest { MimeMessageHelper.setBody(message, multipart); // Extract text - ViewableContainer container = extractTextAndAttachments(InstrumentationRegistry.getTargetContext(), message); + ViewableContainer container = extractTextAndAttachments(InstrumentationRegistry.getTargetContext(), + MessageExtractor.getViewables(message, attachments), new ArrayList()); String expectedText = bodyText1 + "\r\n\r\n" + @@ -151,7 +157,8 @@ public class LocalMessageExtractorTest { MimeMessageHelper.setBody(message, multipart); // Extract text - ViewableContainer container = extractTextAndAttachments(InstrumentationRegistry.getTargetContext(), message); + ViewableContainer container = extractTextAndAttachments(InstrumentationRegistry.getTargetContext(), + MessageExtractor.getViewables(message, attachments), new ArrayList()); String expectedText = bodyText + diff --git a/k9mail/src/main/java/com/fsck/k9/activity/MessageList.java b/k9mail/src/main/java/com/fsck/k9/activity/MessageList.java index a1a817863..d85217683 100644 --- a/k9mail/src/main/java/com/fsck/k9/activity/MessageList.java +++ b/k9mail/src/main/java/com/fsck/k9/activity/MessageList.java @@ -51,7 +51,7 @@ import com.fsck.k9.search.SearchSpecification.Attribute; import com.fsck.k9.search.SearchSpecification.SearchCondition; import com.fsck.k9.search.SearchSpecification.Searchfield; import com.fsck.k9.view.MessageHeader; -import com.fsck.k9.ui.messageview.MessageOpenPgpView; +import com.fsck.k9.ui.messageview.MessageOpenPgpViewOld; import com.fsck.k9.view.MessageTitleView; import com.fsck.k9.view.ViewSwitcher; import com.fsck.k9.view.ViewSwitcher.OnSwitchCompleteListener; @@ -1564,7 +1564,7 @@ public class MessageList extends K9Activity implements MessageListFragmentListen // handle OpenPGP results from PendingIntents in OpenPGP view // must be handled in this main activity, because startIntentSenderForResult() does not support Fragments - MessageOpenPgpView openPgpView = (MessageOpenPgpView) findViewById(R.id.layout_decrypt_openpgp); + MessageOpenPgpViewOld openPgpView = (MessageOpenPgpViewOld) findViewById(R.id.layout_decrypt_openpgp); if (openPgpView != null && openPgpView.handleOnActivityResult(requestCode, resultCode, data)) { return; } diff --git a/k9mail/src/main/java/com/fsck/k9/mailstore/LocalMessageExtractor.java b/k9mail/src/main/java/com/fsck/k9/mailstore/LocalMessageExtractor.java index 64b1a3ce0..80a05d93e 100644 --- a/k9mail/src/main/java/com/fsck/k9/mailstore/LocalMessageExtractor.java +++ b/k9mail/src/main/java/com/fsck/k9/mailstore/LocalMessageExtractor.java @@ -13,7 +13,9 @@ import com.fsck.k9.mail.internet.MessageExtractor; import com.fsck.k9.mail.internet.MimeHeader; import com.fsck.k9.mail.internet.MimeUtility; import com.fsck.k9.mail.internet.Viewable; +import com.fsck.k9.mailstore.MessageViewInfo.MessageViewContainer; import com.fsck.k9.provider.AttachmentProvider; +import org.openintents.openpgp.OpenPgpSignatureResult; import java.util.ArrayList; import java.util.Date; @@ -40,18 +42,19 @@ public class LocalMessageExtractor { * Extract the viewable textual parts of a message and return the rest as attachments. * * @param context A {@link android.content.Context} instance that will be used to get localized strings. + * @param viewables + * @param attachments * @return A {@link ViewableContainer} instance containing the textual parts of the message as * plain text and HTML, and a list of message parts considered attachments. * * @throws com.fsck.k9.mail.MessagingException * In case of an error. */ - public static ViewableContainer extractTextAndAttachments(Context context, Message message) throws MessagingException { + public static ViewableContainer extractTextAndAttachments(Context context, List viewables, + List attachments) throws MessagingException { try { - List attachments = new ArrayList(); // Collect all viewable parts - List viewables = MessageExtractor.getViewables(message, attachments); /* * Convert the tree of viewable parts into text and HTML @@ -412,10 +415,33 @@ public class LocalMessageExtractor { } public static MessageViewInfo decodeMessageForView(Context context, Message message) throws MessagingException { - //TODO: Modify extractTextAndAttachments() to only extract the text type (plain vs. HTML) we currently need. - ViewableContainer viewable = LocalMessageExtractor.extractTextAndAttachments(context, message); - List attachments = extractAttachmentInfos(viewable.attachments); - return new MessageViewInfo(viewable.html, attachments, message); + + // 1. break mime structure on encryption/signature boundaries + ArrayList parts = new ArrayList(); + // TODO: actually break it down + parts.add(message); +// parts.add(message); + + // 2. extract viewables/attachments of parts + ArrayList containers = new ArrayList(); + for (Part part : parts) { + ArrayList attachments = new ArrayList(); + List viewables = MessageExtractor.getViewables(part, attachments); + + // 3. parse viewables into html string + ViewableContainer viewable = LocalMessageExtractor.extractTextAndAttachments(context, viewables, + attachments); + List attachmentInfos = extractAttachmentInfos(attachments); + + // TODO correctly extract OpenPgpSignatureResult and add to MessageViewContainer + OpenPgpSignatureResult result = null; + result = new OpenPgpSignatureResult(OpenPgpSignatureResult.SIGNATURE_SUCCESS_CERTIFIED, "lul", false, 0x123, + new ArrayList()); + containers.add(new MessageViewContainer(viewable.html, attachmentInfos, result, true, null)); + + } + + return new MessageViewInfo(containers, message); } private static List extractAttachmentInfos(List attachmentParts) diff --git a/k9mail/src/main/java/com/fsck/k9/mailstore/MessageViewInfo.java b/k9mail/src/main/java/com/fsck/k9/mailstore/MessageViewInfo.java index 98f8fc2b2..39509fd0e 100644 --- a/k9mail/src/main/java/com/fsck/k9/mailstore/MessageViewInfo.java +++ b/k9mail/src/main/java/com/fsck/k9/mailstore/MessageViewInfo.java @@ -1,20 +1,58 @@ package com.fsck.k9.mailstore; -import java.util.Collections; +import android.app.PendingIntent; + +import java.util.ArrayList; import java.util.List; import com.fsck.k9.mail.Message; +import org.openintents.openpgp.OpenPgpSignatureResult; public class MessageViewInfo { - public final String text; - public final List attachments; - public final Message message; + public final Message message; + public final List containers; + + @Deprecated public MessageViewInfo(String text, List attachments, Message message) { - this.text = text; - this.attachments = Collections.unmodifiableList(attachments); + containers = new ArrayList(); + containers.add(new MessageViewContainer(text, attachments)); this.message = message; } + + public MessageViewInfo(List containers, Message message) { + this.containers = containers; + this.message = message; + } + + public static class MessageViewContainer { + + final public String text; + final public List attachments; + final public boolean encrypted; + final public OpenPgpSignatureResult signatureResult; + final public PendingIntent pgpPendingIntent; + + MessageViewContainer(String text, List attachments) { + this.text = text; + this.attachments = attachments; + this.signatureResult = null; + this.encrypted = false; + this.pgpPendingIntent = null; + } + + MessageViewContainer(String text, List attachments, + OpenPgpSignatureResult signatureResult, boolean encrypted, + PendingIntent pgpPendingIntent) { + this.text = text; + this.attachments = attachments; + this.signatureResult = signatureResult; + this.encrypted = encrypted; + this.pgpPendingIntent = pgpPendingIntent; + } + + } + } diff --git a/k9mail/src/main/java/com/fsck/k9/ui/messageview/SingleMessageView.java b/k9mail/src/main/java/com/fsck/k9/ui/messageview/MessageContainerView.java similarity index 82% rename from k9mail/src/main/java/com/fsck/k9/ui/messageview/SingleMessageView.java rename to k9mail/src/main/java/com/fsck/k9/ui/messageview/MessageContainerView.java index ac9ed9953..2eac9e7b3 100644 --- a/k9mail/src/main/java/com/fsck/k9/ui/messageview/SingleMessageView.java +++ b/k9mail/src/main/java/com/fsck/k9/ui/messageview/MessageContainerView.java @@ -15,12 +15,12 @@ import android.content.ContentResolver; import android.content.Context; import android.content.Intent; import android.database.Cursor; +import android.graphics.Color; import android.net.Uri; import android.os.AsyncTask; import android.os.Parcel; import android.os.Parcelable; import android.util.AttributeSet; -import android.util.Log; import android.util.TypedValue; import android.view.ContextMenu; import android.view.ContextMenu.ContextMenuInfo; @@ -32,38 +32,33 @@ import android.view.MenuItem.OnMenuItemClickListener; import android.view.View; import android.view.View.OnClickListener; import android.view.View.OnCreateContextMenuListener; +import android.view.ViewStub; import android.webkit.WebView; import android.webkit.WebView.HitTestResult; import android.widget.Button; import android.widget.LinearLayout; +import android.widget.RelativeLayout; import android.widget.Toast; -import com.fsck.k9.Account; import com.fsck.k9.K9; import com.fsck.k9.R; -import com.fsck.k9.crypto.PgpData; import com.fsck.k9.helper.ClipboardManager; import com.fsck.k9.helper.Contacts; import com.fsck.k9.helper.FileHelper; -import com.fsck.k9.helper.HtmlConverter; import com.fsck.k9.helper.UrlEncodingHelper; -import com.fsck.k9.helper.Utility; import com.fsck.k9.mail.Address; -import com.fsck.k9.mail.Flag; -import com.fsck.k9.mail.Message; import com.fsck.k9.mail.MessagingException; import com.fsck.k9.mail.internet.MimeUtility; import com.fsck.k9.mailstore.AttachmentViewInfo; -import com.fsck.k9.mailstore.MessageViewInfo; +import com.fsck.k9.mailstore.MessageViewInfo.MessageViewContainer; import com.fsck.k9.provider.AttachmentProvider.AttachmentProviderColumns; -import com.fsck.k9.view.MessageHeader; import com.fsck.k9.view.MessageHeader.OnLayoutChangedListener; import com.fsck.k9.view.MessageWebView; import org.apache.commons.io.IOUtils; -public class SingleMessageView extends LinearLayout implements OnClickListener, +public class MessageContainerView extends LinearLayout implements OnClickListener, OnLayoutChangedListener, OnCreateContextMenuListener { private static final int MENU_ITEM_LINK_VIEW = Menu.FIRST; private static final int MENU_ITEM_LINK_SHARE = Menu.FIRST + 1; @@ -87,10 +82,9 @@ public class SingleMessageView extends LinearLayout implements OnClickListener, }; private static final int DISPLAY_NAME_INDEX = 1; - - private MessageOpenPgpView mOpenPgpView; + private ViewStub mOpenPgpHeaderStub; + private View mSidebar; private MessageWebView mMessageContentView; - private MessageHeader mHeaderContainer; private LinearLayout mAttachments; private Button mShowHiddenAttachments; private LinearLayout mHiddenAttachments; @@ -99,10 +93,11 @@ public class SingleMessageView extends LinearLayout implements OnClickListener, private View mShowAttachmentsAction; private boolean mShowPictures; private boolean mHasAttachments; - private Button mDownloadRemainder; + private boolean mHasOpenPgpInfo; private LayoutInflater mInflater; private Contacts mContacts; private AttachmentViewCallback attachmentCallback; + private OpenPgpHeaderViewCallback openPgpHeaderViewCallback; private View mAttachmentsContainer; private SavedState mSavedState; private ClipboardManager mClipboardManager; @@ -110,25 +105,26 @@ public class SingleMessageView extends LinearLayout implements OnClickListener, private Map attachments = new HashMap(); - public void initialize(Fragment fragment) { + public void initialize(Fragment fragment, AttachmentViewCallback attachmentCallback, + OpenPgpHeaderViewCallback openPgpHeaderViewCallback) { + this.attachmentCallback = attachmentCallback; + this.openPgpHeaderViewCallback = openPgpHeaderViewCallback; + + mOpenPgpHeaderStub = (ViewStub) findViewById(R.id.openpgp_header_stub); + mSidebar = findViewById(R.id.message_sidebar); + Activity activity = fragment.getActivity(); mMessageContentView = (MessageWebView) findViewById(R.id.message_content); mMessageContentView.configure(); activity.registerForContextMenu(mMessageContentView); mMessageContentView.setOnCreateContextMenuListener(this); - mHeaderContainer = (MessageHeader) findViewById(R.id.header_container); - mHeaderContainer.setOnLayoutChangedListener(this); - mAttachmentsContainer = findViewById(R.id.attachments_container); mAttachments = (LinearLayout) findViewById(R.id.attachments); mHiddenAttachments = (LinearLayout) findViewById(R.id.hidden_attachments); mHiddenAttachments.setVisibility(View.GONE); mShowHiddenAttachments = (Button) findViewById(R.id.show_hidden_attachments); mShowHiddenAttachments.setVisibility(View.GONE); - mOpenPgpView = (MessageOpenPgpView) findViewById(R.id.layout_decrypt_openpgp); - mOpenPgpView.setFragment(fragment); - mOpenPgpView.setupChildViews(); mShowPicturesAction = findViewById(R.id.show_pictures); mShowMessageAction = findViewById(R.id.show_message); @@ -139,23 +135,19 @@ public class SingleMessageView extends LinearLayout implements OnClickListener, mContacts = Contacts.getInstance(activity); mInflater = ((MessageViewFragment) fragment).getFragmentLayoutInflater(); - mDownloadRemainder = (Button) findViewById(R.id.download_remainder); - mDownloadRemainder.setVisibility(View.GONE); - mAttachmentsContainer.setVisibility(View.GONE); mMessageContentView.setVisibility(View.VISIBLE); // the HTC version of WebView tries to force the background of the // titlebar, which is really unfair. TypedValue outValue = new TypedValue(); getContext().getTheme().resolveAttribute(R.attr.messageViewHeaderBackgroundColor, outValue, true); - mHeaderContainer.setBackgroundColor(outValue.data); // also set background of the whole view (including the attachments view) setBackgroundColor(outValue.data); mShowHiddenAttachments.setOnClickListener(this); - mShowMessageAction.setOnClickListener(this); - mShowAttachmentsAction.setOnClickListener(this); - mShowPicturesAction.setOnClickListener(this); + // mShowMessageAction.setOnClickListener(this); + // mShowAttachmentsAction.setOnClickListener(this); + // mShowPicturesAction.setOnClickListener(this); mClipboardManager = ClipboardManager.getInstance(activity); } @@ -382,14 +374,6 @@ public class SingleMessageView extends LinearLayout implements OnClickListener, onShowHiddenAttachments(); break; } - case R.id.show_message: { - onShowMessage(); - break; - } - case R.id.show_attachments: { - onShowAttachments(); - break; - } case R.id.show_pictures: { // Allow network access first... setLoadPictures(true); @@ -405,21 +389,7 @@ public class SingleMessageView extends LinearLayout implements OnClickListener, mHiddenAttachments.setVisibility(View.VISIBLE); } - public void onShowMessage() { - showShowMessageAction(false); - showAttachments(false); - showShowAttachmentsAction(mHasAttachments); - showMessageWebView(true); - } - - public void onShowAttachments() { - showMessageWebView(false); - showShowAttachmentsAction(false); - showShowMessageAction(true); - showAttachments(true); - } - - public SingleMessageView(Context context, AttributeSet attrs) { + public MessageContainerView(Context context, AttributeSet attrs) { super(context, attrs); } @@ -446,58 +416,7 @@ public class SingleMessageView extends LinearLayout implements OnClickListener, } public void showShowPicturesAction(boolean show) { - mShowPicturesAction.setVisibility(show ? View.VISIBLE : View.GONE); - } - public void showShowMessageAction(boolean show) { - mShowMessageAction.setVisibility(show ? View.VISIBLE : View.GONE); - } - public void showShowAttachmentsAction(boolean show) { - mShowAttachmentsAction.setVisibility(show ? View.VISIBLE : View.GONE); - } - - /** - * Fetch the message header view. This is not the same as the message headers; this is the View shown at the top - * of messages. - * @return MessageHeader View. - */ - public MessageHeader getMessageHeaderView() { - return mHeaderContainer; - } - - public void setHeaders(final Message message, Account account) { - try { - mHeaderContainer.populate(message, account); - mHeaderContainer.setVisibility(View.VISIBLE); - - - } catch (Exception me) { - Log.e(K9.LOG_TAG, "setHeaders - error", me); - } - } - - public void setOnToggleFlagClickListener(OnClickListener listener) { - mHeaderContainer.setOnFlagListener(listener); - } - - public void setOnDownloadButtonClickListener(OnClickListener listener) { - mDownloadRemainder.setOnClickListener(listener); - } - - public void enableDownloadButton() { - mDownloadRemainder.setEnabled(true); - } - - public void disableDownloadButton() { - mDownloadRemainder.setEnabled(false); - } - - public void setShowDownloadButton(Message message) { - if (message.isSet(Flag.X_DOWNLOADED_FULL)) { - mDownloadRemainder.setVisibility(View.GONE); - } else { - mDownloadRemainder.setEnabled(true); - mDownloadRemainder.setVisibility(View.VISIBLE); - } + // mShowPicturesAction.setVisibility(show ? View.VISIBLE : View.GONE); } public void enableAttachmentButtons() { @@ -512,36 +431,24 @@ public class SingleMessageView extends LinearLayout implements OnClickListener, } } - public void showAllHeaders() { - mHeaderContainer.onShowAdditionalHeaders(); - } - - public boolean additionalHeadersVisible() { - return mHeaderContainer.additionalHeadersVisible(); - } - - public void setMessage(Account account, MessageViewInfo messageViewInfo, PgpData pgpData) + public void setMessage(MessageViewContainer messageViewContainer) throws MessagingException { resetView(); - String text = null; - if (pgpData != null) { - text = pgpData.getDecryptedData(); - if (text != null) { - text = HtmlConverter.textToHtml(text); - } - } +// mHasOpenPgpInfo = (messageViewContainer.signatureResult != null +// || messageViewContainer.encrypted); +// if (mHasOpenPgpInfo) { + renderOpenPgpHeader(messageViewContainer); + mSidebar.setVisibility(View.VISIBLE); - if (text == null) { - text = messageViewInfo.text; - } +// } // Save the text so we can reset the WebView when the user clicks the "Show pictures" button - mText = text; + mText = messageViewContainer.text; - mHasAttachments = !messageViewInfo.attachments.isEmpty(); + mHasAttachments = !messageViewContainer.attachments.isEmpty(); if (mHasAttachments) { - renderAttachments(messageViewInfo); + renderAttachments(messageViewContainer); } mHiddenAttachments.setVisibility(View.GONE); @@ -553,27 +460,20 @@ public class SingleMessageView extends LinearLayout implements OnClickListener, lookForImages = false; } - if (mSavedState.attachmentViewVisible) { - onShowAttachments(); - } else { - onShowMessage(); - } - if (mSavedState.hiddenAttachmentsVisible) { onShowHiddenAttachments(); } mSavedState = null; - } else { - onShowMessage(); } + /* if (text != null && lookForImages) { // If the message contains external pictures and the "Show pictures" // button wasn't already pressed, see if the user's preferences has us // showing them anyway. if (Utility.hasExternalImages(text) && !showPictures()) { - Address[] from = messageViewInfo.message.getFrom(); + Address[] from = messageViewContainer.message.getFrom(); if ((account.getShowPictures() == Account.ShowPictures.ALWAYS) || ((account.getShowPictures() == Account.ShowPictures.ONLY_FROM_CONTACTS) && // Make sure we have at least one from address @@ -585,11 +485,10 @@ public class SingleMessageView extends LinearLayout implements OnClickListener, } } } + */ - if (text != null) { - loadBodyFromText(text); - mOpenPgpView.updateLayout(account, pgpData.getDecryptedData(), - pgpData.getSignatureResult(), messageViewInfo.message); + if (mText != null) { + loadBodyFromText(mText); } else { showStatusMessage(getContext().getString(R.string.webview_empty_message)); } @@ -604,18 +503,15 @@ public class SingleMessageView extends LinearLayout implements OnClickListener, mMessageContentView.setText(emailText); } - public void showAttachments(boolean show) { - mAttachmentsContainer.setVisibility(show ? View.VISIBLE : View.GONE); - boolean showHidden = (show && mHiddenAttachments.getVisibility() == View.GONE && - mHiddenAttachments.getChildCount() > 0); - mShowHiddenAttachments.setVisibility(showHidden ? View.VISIBLE : View.GONE); + public void renderOpenPgpHeader(MessageViewContainer messageContainer) { + // inflate real header into stub + OpenPgpHeaderView view = (OpenPgpHeaderView) mOpenPgpHeaderStub.inflate(); + view.setCallback(openPgpHeaderViewCallback); + view.setOpenPgpData(messageContainer.signatureResult, messageContainer.encrypted, + messageContainer.pgpPendingIntent); } - public void showMessageWebView(boolean show) { - mMessageContentView.setVisibility(show ? View.VISIBLE : View.GONE); - } - - public void renderAttachments(MessageViewInfo messageContainer) throws MessagingException { + public void renderAttachments(MessageViewContainer messageContainer) throws MessagingException { for (AttachmentViewInfo attachment : messageContainer.attachments) { AttachmentView view = (AttachmentView) mInflater.inflate(R.layout.message_view_attachment, null); view.setCallback(attachmentCallback); @@ -652,10 +548,7 @@ public class SingleMessageView extends LinearLayout implements OnClickListener, } public void resetView() { - mDownloadRemainder.setVisibility(View.GONE); setLoadPictures(false); - showShowAttachmentsAction(false); - showShowMessageAction(false); showShowPicturesAction(false); mAttachments.removeAllViews(); mHiddenAttachments.removeAllViews(); @@ -670,14 +563,6 @@ public class SingleMessageView extends LinearLayout implements OnClickListener, loadBodyFromText(""); } - public void resetHeaderView() { - mHeaderContainer.setVisibility(View.GONE); - } - - public void setAttachmentCallback(AttachmentViewCallback attachmentCallback) { - this.attachmentCallback = attachmentCallback; - } - @Override public Parcelable onSaveInstanceState() { Parcelable superState = super.onSaveInstanceState(); diff --git a/k9mail/src/main/java/com/fsck/k9/ui/messageview/MessageOpenPgpView.java b/k9mail/src/main/java/com/fsck/k9/ui/messageview/MessageOpenPgpViewOld.java similarity index 94% rename from k9mail/src/main/java/com/fsck/k9/ui/messageview/MessageOpenPgpView.java rename to k9mail/src/main/java/com/fsck/k9/ui/messageview/MessageOpenPgpViewOld.java index ede1247f9..ce1462be7 100644 --- a/k9mail/src/main/java/com/fsck/k9/ui/messageview/MessageOpenPgpView.java +++ b/k9mail/src/main/java/com/fsck/k9/ui/messageview/MessageOpenPgpViewOld.java @@ -42,7 +42,7 @@ import org.openintents.openpgp.OpenPgpSignatureResult; import org.openintents.openpgp.util.OpenPgpApi; import org.openintents.openpgp.util.OpenPgpServiceConnection; -public class MessageOpenPgpView extends LinearLayout { +public class MessageOpenPgpViewOld extends LinearLayout { private Context mContext; private MessageViewFragment mFragment; @@ -66,7 +66,7 @@ public class MessageOpenPgpView extends LinearLayout { String mData; Account mAccount; - public MessageOpenPgpView(Context context, AttributeSet attrs) { + public MessageOpenPgpViewOld(Context context, AttributeSet attrs) { super(context, attrs); mContext = context; } @@ -127,7 +127,7 @@ public class MessageOpenPgpView extends LinearLayout { if (decryptedData != null && signatureResult == null) { // encrypted-only - MessageOpenPgpView.this.setBackgroundColor(mFragment.getResources().getColor( + MessageOpenPgpViewOld.this.setBackgroundColor(mFragment.getResources().getColor( R.color.openpgp_blue)); mText.setText(R.string.openpgp_successful_decryption); @@ -140,7 +140,7 @@ public class MessageOpenPgpView extends LinearLayout { case OpenPgpSignatureResult.SIGNATURE_ERROR: // TODO: signature error but decryption works? mText.setText(R.string.openpgp_signature_invalid); - MessageOpenPgpView.this.setBackgroundColor(mFragment.getResources().getColor( + MessageOpenPgpViewOld.this.setBackgroundColor(mFragment.getResources().getColor( R.color.openpgp_red)); mGetKeyButton.setVisibility(View.GONE); @@ -155,7 +155,7 @@ public class MessageOpenPgpView extends LinearLayout { else { mText.setText(R.string.openpgp_successful_decryption_valid_signature_certified); } - MessageOpenPgpView.this.setBackgroundColor(mFragment.getResources().getColor( + MessageOpenPgpViewOld.this.setBackgroundColor(mFragment.getResources().getColor( R.color.openpgp_green)); mGetKeyButton.setVisibility(View.GONE); @@ -172,7 +172,7 @@ public class MessageOpenPgpView extends LinearLayout { else { mText.setText(R.string.openpgp_successful_decryption_unknown_signature); } - MessageOpenPgpView.this.setBackgroundColor(mFragment.getResources().getColor( + MessageOpenPgpViewOld.this.setBackgroundColor(mFragment.getResources().getColor( R.color.openpgp_orange)); mGetKeyButton.setVisibility(View.VISIBLE); @@ -189,7 +189,7 @@ public class MessageOpenPgpView extends LinearLayout { else { mText.setText(R.string.openpgp_successful_decryption_valid_signature_uncertified); } - MessageOpenPgpView.this.setBackgroundColor(mFragment.getResources().getColor( + MessageOpenPgpViewOld.this.setBackgroundColor(mFragment.getResources().getColor( R.color.openpgp_orange)); mGetKeyButton.setVisibility(View.GONE); @@ -229,7 +229,7 @@ public class MessageOpenPgpView extends LinearLayout { private void decryptAndVerify(final Message message) { this.setVisibility(View.VISIBLE); mProgress.setVisibility(View.VISIBLE); - MessageOpenPgpView.this.setBackgroundColor(mFragment.getResources().getColor( + MessageOpenPgpViewOld.this.setBackgroundColor(mFragment.getResources().getColor( R.color.openpgp_orange)); mText.setText(R.string.openpgp_decrypting_verifying); @@ -393,7 +393,7 @@ public class MessageOpenPgpView extends LinearLayout { mText.setText(mFragment.getString(R.string.openpgp_error) + " " + error.getMessage()); - MessageOpenPgpView.this.setBackgroundColor(mFragment.getResources().getColor( + MessageOpenPgpViewOld.this.setBackgroundColor(mFragment.getResources().getColor( R.color.openpgp_red)); } }); diff --git a/k9mail/src/main/java/com/fsck/k9/ui/messageview/MessageTopView.java b/k9mail/src/main/java/com/fsck/k9/ui/messageview/MessageTopView.java new file mode 100644 index 000000000..90c595d68 --- /dev/null +++ b/k9mail/src/main/java/com/fsck/k9/ui/messageview/MessageTopView.java @@ -0,0 +1,136 @@ +package com.fsck.k9.ui.messageview; + +import android.app.Activity; +import android.app.Fragment; +import android.content.Context; +import android.util.AttributeSet; +import android.util.Log; +import android.util.TypedValue; +import android.view.LayoutInflater; +import android.view.View; +import android.widget.Button; +import android.widget.LinearLayout; + +import com.fsck.k9.Account; +import com.fsck.k9.K9; +import com.fsck.k9.R; +import com.fsck.k9.crypto.PgpData; +import com.fsck.k9.mail.Flag; +import com.fsck.k9.mail.Message; +import com.fsck.k9.mail.MessagingException; +import com.fsck.k9.mailstore.MessageViewInfo; +import com.fsck.k9.mailstore.MessageViewInfo.MessageViewContainer; +import com.fsck.k9.view.MessageHeader; + + +public class MessageTopView extends LinearLayout { + + private MessageHeader mHeaderContainer; + private LayoutInflater mInflater; + private LinearLayout containerViews; + private Fragment fragment; + private Button mDownloadRemainder; + private AttachmentViewCallback attachmentCallback; + private OpenPgpHeaderViewCallback openPgpHeaderViewCallback; + + public MessageTopView(Context context, AttributeSet attrs) { + super(context, attrs); + } + + public void initialize (Fragment fragment, AttachmentViewCallback attachmentCallback, + OpenPgpHeaderViewCallback openPgpHeaderViewCallback) { + this.fragment = fragment; + this.attachmentCallback = attachmentCallback; + this.openPgpHeaderViewCallback = openPgpHeaderViewCallback; + + mHeaderContainer = (MessageHeader) findViewById(R.id.header_container); + // mHeaderContainer.setOnLayoutChangedListener(this); + mInflater = ((MessageViewFragment) fragment).getFragmentLayoutInflater(); + + TypedValue outValue = new TypedValue(); + getContext().getTheme().resolveAttribute(R.attr.messageViewHeaderBackgroundColor, outValue, true); + mHeaderContainer.setBackgroundColor(outValue.data); + + mDownloadRemainder = (Button) findViewById(R.id.download_remainder); + mDownloadRemainder.setVisibility(View.GONE); + + containerViews = (LinearLayout) findViewById(R.id.message_containers); + + } + + public void resetView() { + mDownloadRemainder.setVisibility(View.GONE); + containerViews.removeAllViews(); + } + + public void setMessage(Account account, MessageViewInfo messageViewInfo) + throws MessagingException { + resetView(); + + for (MessageViewContainer container : messageViewInfo.containers) { + MessageContainerView view = (MessageContainerView) mInflater.inflate(R.layout.message_container, null); + view.initialize(fragment, attachmentCallback, openPgpHeaderViewCallback); + view.setMessage(container); + containerViews.addView(view); + } + + } + + /** + * Fetch the message header view. This is not the same as the message headers; this is the View shown at the top + * of messages. + * @return MessageHeader View. + */ + public MessageHeader getMessageHeaderView() { + return mHeaderContainer; + } + + public void setHeaders(final Message message, Account account) { + try { + mHeaderContainer.populate(message, account); + mHeaderContainer.setVisibility(View.VISIBLE); + + + } catch (Exception me) { + Log.e(K9.LOG_TAG, "setHeaders - error", me); + } + } + + public void setOnToggleFlagClickListener(OnClickListener listener) { + mHeaderContainer.setOnFlagListener(listener); + } + + public void showAllHeaders() { + mHeaderContainer.onShowAdditionalHeaders(); + } + + public boolean additionalHeadersVisible() { + return mHeaderContainer.additionalHeadersVisible(); + } + + public void resetHeaderView() { + mHeaderContainer.setVisibility(View.GONE); + } + + public void setOnDownloadButtonClickListener(OnClickListener listener) { + mDownloadRemainder.setOnClickListener(listener); + } + + public void enableDownloadButton() { + mDownloadRemainder.setEnabled(true); + } + + public void disableDownloadButton() { + mDownloadRemainder.setEnabled(false); + } + + public void setShowDownloadButton(Message message) { + if (message.isSet(Flag.X_DOWNLOADED_FULL)) { + mDownloadRemainder.setVisibility(View.GONE); + } else { + mDownloadRemainder.setEnabled(true); + mDownloadRemainder.setVisibility(View.VISIBLE); + } + } + +} diff --git a/k9mail/src/main/java/com/fsck/k9/ui/messageview/MessageViewFragment.java b/k9mail/src/main/java/com/fsck/k9/ui/messageview/MessageViewFragment.java index 943b4fd83..507fbf3c4 100644 --- a/k9mail/src/main/java/com/fsck/k9/ui/messageview/MessageViewFragment.java +++ b/k9mail/src/main/java/com/fsck/k9/ui/messageview/MessageViewFragment.java @@ -16,8 +16,10 @@ import android.app.Fragment; import android.app.FragmentManager; import android.app.LoaderManager; import android.app.LoaderManager.LoaderCallbacks; +import android.app.PendingIntent; import android.content.Context; import android.content.Intent; +import android.content.IntentSender; import android.content.Loader; import android.net.Uri; import android.os.AsyncTask; @@ -74,7 +76,7 @@ import org.openintents.openpgp.util.OpenPgpServiceConnection.OnBound; public class MessageViewFragment extends Fragment implements ConfirmationDialogFragmentListener, - AttachmentViewCallback { + AttachmentViewCallback, OpenPgpHeaderViewCallback { private static final String ARG_REFERENCE = "reference"; @@ -100,7 +102,7 @@ public class MessageViewFragment extends Fragment implements ConfirmationDialogF } - private SingleMessageView mMessageView; + private MessageTopView mMessageView; private PgpData mPgpData; private Account mAccount; private MessageReference mMessageReference; @@ -170,17 +172,16 @@ public class MessageViewFragment extends Fragment implements ConfirmationDialogF View view = mLayoutInflater.inflate(R.layout.message, container, false); - mMessageView = (SingleMessageView) view.findViewById(R.id.message_view); + mMessageView = (MessageTopView) view.findViewById(R.id.message_view); - mMessageView.setAttachmentCallback(this); - - mMessageView.initialize(this); + mMessageView.initialize(this, this, this); mMessageView.setOnToggleFlagClickListener(new OnClickListener() { @Override public void onClick(View v) { onToggleFlagged(); } }); + mMessageView.setOnDownloadButtonClickListener(new OnClickListener() { @Override public void onClick(View v) { @@ -420,7 +421,7 @@ public class MessageViewFragment extends Fragment implements ConfirmationDialogF } private void onLoadMessageFromDatabaseFailed() { - mMessageView.showStatusMessage(mContext.getString(R.string.status_invalid_id_error)); + // mMessageView.showStatusMessage(mContext.getString(R.string.status_invalid_id_error)); } private void startDownloadingMessageBody(LocalMessage message) { @@ -460,7 +461,7 @@ public class MessageViewFragment extends Fragment implements ConfirmationDialogF private void showMessage(MessageViewInfo messageContainer) { try { - mMessageView.setMessage(mAccount, messageContainer, mPgpData); + mMessageView.setMessage(mAccount, messageContainer); mMessageView.setShowDownloadButton(mMessage); } catch (MessagingException e) { Log.e(K9.LOG_TAG, "Error while trying to display message", e); @@ -597,7 +598,8 @@ public class MessageViewFragment extends Fragment implements ConfirmationDialogF } public void onSelectText() { - mMessageView.beginSelectingText(); + // FIXME + // mMessageView.beginSelectingText(); } private void startRefileActivity(int activity) { @@ -609,7 +611,6 @@ public class MessageViewFragment extends Fragment implements ConfirmationDialogF startActivityForResult(intent, activity); } - @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { if (resultCode != Activity.RESULT_OK) { @@ -724,7 +725,7 @@ public class MessageViewFragment extends Fragment implements ConfirmationDialogF PgpData data = new PgpData(); data.setDecryptedData(decryptedData); data.setSignatureResult(signatureResult); - mMessageView.setMessage(mAccount, messageViewInfo, data); + mMessageView.setMessage(mAccount, messageViewInfo); } catch (MessagingException e) { Log.e(K9.LOG_TAG, "displayMessageBody failed", e); } @@ -791,7 +792,7 @@ public class MessageViewFragment extends Fragment implements ConfirmationDialogF } public void zoom(KeyEvent event) { - mMessageView.zoom(event); + // mMessageView.zoom(event); } @Override @@ -859,11 +860,11 @@ public class MessageViewFragment extends Fragment implements ConfirmationDialogF } public void disableAttachmentButtons(AttachmentViewInfo attachment) { - mMessageView.disableAttachmentButtons(attachment); + // mMessageView.disableAttachmentButtons(attachment); } public void enableAttachmentButtons(AttachmentViewInfo attachment) { - mMessageView.enableAttachmentButtons(attachment); + // mMessageView.enableAttachmentButtons(attachment); } public void runOnMainThread(Runnable runnable) { @@ -871,7 +872,7 @@ public class MessageViewFragment extends Fragment implements ConfirmationDialogF } public void showAttachmentLoadingDialog() { - mMessageView.disableAttachmentButtons(); + // mMessageView.disableAttachmentButtons(); showDialog(R.id.dialog_attachment_progress); } @@ -880,13 +881,24 @@ public class MessageViewFragment extends Fragment implements ConfirmationDialogF @Override public void run() { removeDialog(R.id.dialog_attachment_progress); - mMessageView.enableAttachmentButtons(); + // mMessageView.enableAttachmentButtons(); } }); } public void refreshAttachmentThumbnail(AttachmentViewInfo attachment) { - mMessageView.refreshAttachmentThumbnail(attachment); + // mMessageView.refreshAttachmentThumbnail(attachment); + } + + @Override + public void onPgpSignatureButtonClick(PendingIntent pendingIntent) { + try { + getActivity().startIntentSenderForResult( + pendingIntent.getIntentSender(), + 42, null, 0, 0, 0); + } catch (IntentSender.SendIntentException e) { + Log.e(K9.LOG_TAG, "SendIntentException", e); + } } public interface MessageViewFragmentListener { diff --git a/k9mail/src/main/java/com/fsck/k9/ui/messageview/OpenPgpHeaderView.java b/k9mail/src/main/java/com/fsck/k9/ui/messageview/OpenPgpHeaderView.java new file mode 100644 index 000000000..1fff39685 --- /dev/null +++ b/k9mail/src/main/java/com/fsck/k9/ui/messageview/OpenPgpHeaderView.java @@ -0,0 +1,296 @@ + +package com.fsck.k9.ui.messageview; + +import android.app.PendingIntent; +import android.content.Context; +import android.graphics.PorterDuff; +import android.util.AttributeSet; +import android.view.View; +import android.widget.Button; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.TextView; + +import com.fsck.k9.R; + +import org.openintents.openpgp.OpenPgpSignatureResult; +import org.openintents.openpgp.util.OpenPgpUtils; + +public class OpenPgpHeaderView extends LinearLayout { + private Context mContext; + private OpenPgpHeaderViewCallback callback; + + private OpenPgpSignatureResult signatureResult; + private boolean encrypted; + private PendingIntent pendingIntent; + + private ImageView mResultEncryptionIcon; + private TextView mResultEncryptionText; + private ImageView mResultSignatureIcon; + private TextView mResultSignatureText; + private LinearLayout mResultSignatureLayout; + private TextView mResultSignatureName; + private TextView mResultSignatureEmail; + private Button mResultSignatureButton; + + public OpenPgpHeaderView(Context context, AttributeSet attrs) { + super(context, attrs); + mContext = context; + } + + public void setOpenPgpData(OpenPgpSignatureResult signatureResult, + boolean encrypted, PendingIntent pendingIntent) { + this.signatureResult = signatureResult; + this.encrypted = encrypted; + this.pendingIntent = pendingIntent; + + displayOpenPgpView(); + } + + public void setCallback(OpenPgpHeaderViewCallback callback) { + this.callback = callback; + } + + public void displayOpenPgpView() { + mResultEncryptionIcon = (ImageView) findViewById(R.id.result_encryption_icon); + mResultEncryptionText = (TextView) findViewById(R.id.result_encryption_text); + mResultSignatureIcon = (ImageView) findViewById(R.id.result_signature_icon); + mResultSignatureText = (TextView) findViewById(R.id.result_signature_text); + mResultSignatureLayout = (LinearLayout) findViewById(R.id.result_signature_layout); + mResultSignatureName = (TextView) findViewById(R.id.result_signature_name); + mResultSignatureEmail = (TextView) findViewById(R.id.result_signature_email); + mResultSignatureButton = (Button) findViewById(R.id.result_signature_button); + + mResultSignatureButton.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + callback.onPgpSignatureButtonClick(pendingIntent); + } + }); + + if (encrypted) { + setStatusImage(mContext, mResultEncryptionIcon, mResultEncryptionText, STATE_ENCRYPTED); + mResultEncryptionText.setText(R.string.openpgp_result_encrypted); + } else { + setStatusImage(mContext, mResultEncryptionIcon, mResultEncryptionText, STATE_NOT_ENCRYPTED); + mResultEncryptionText.setText(R.string.openpgp_result_not_encrypted); + } + + if (signatureResult == null) { + setStatusImage(mContext, mResultSignatureIcon, mResultSignatureText, STATE_NOT_SIGNED); + mResultSignatureText.setText(R.string.openpgp_result_no_signature); + mResultSignatureLayout.setVisibility(View.GONE); + } else { + switch (signatureResult.getStatus()) { + case OpenPgpSignatureResult.SIGNATURE_ERROR: { + setStatusImage(mContext, mResultSignatureIcon, mResultSignatureText, STATE_INVALID); + mResultSignatureText.setText(R.string.openpgp_result_invalid_signature); + + mResultSignatureButton.setVisibility(View.GONE); + mResultSignatureLayout.setVisibility(View.GONE); + break; + } + case OpenPgpSignatureResult.SIGNATURE_SUCCESS_CERTIFIED: { + setStatusImage(mContext, mResultSignatureIcon, mResultSignatureText, STATE_VERIFIED); + mResultSignatureText.setText(R.string.openpgp_result_signature_certified); + + setUserId(signatureResult); + mResultSignatureButton.setText(R.string.openpgp_result_action_show); + mResultSignatureButton.setVisibility(View.VISIBLE); + mResultSignatureLayout.setVisibility(View.VISIBLE); + + break; + } + case OpenPgpSignatureResult.SIGNATURE_KEY_MISSING: { + setStatusImage(mContext, mResultSignatureIcon, mResultSignatureText, STATE_UNKNOWN_KEY); + mResultSignatureText.setText(R.string.openpgp_result_signature_missing_key); + + setUserId(signatureResult); + mResultSignatureButton.setText(R.string.openpgp_result_action_lookup); + mResultSignatureButton.setVisibility(View.VISIBLE); + mResultSignatureLayout.setVisibility(View.VISIBLE); + + break; + } + case OpenPgpSignatureResult.SIGNATURE_SUCCESS_UNCERTIFIED: { + setStatusImage(mContext, mResultSignatureIcon, mResultSignatureText, STATE_UNVERIFIED); + mResultSignatureText.setText(R.string.openpgp_result_signature_uncertified); + + setUserId(signatureResult); + mResultSignatureButton.setText(R.string.openpgp_result_action_show); + mResultSignatureButton.setVisibility(View.VISIBLE); + mResultSignatureLayout.setVisibility(View.VISIBLE); + + break; + } + case OpenPgpSignatureResult.SIGNATURE_KEY_EXPIRED: { + setStatusImage(mContext, mResultSignatureIcon, mResultSignatureText, STATE_EXPIRED); + mResultSignatureText.setText(R.string.openpgp_result_signature_expired_key); + + setUserId(signatureResult); + mResultSignatureButton.setText(R.string.openpgp_result_action_show); + mResultSignatureButton.setVisibility(View.VISIBLE); + mResultSignatureLayout.setVisibility(View.VISIBLE); + + break; + } + case OpenPgpSignatureResult.SIGNATURE_KEY_REVOKED: { + setStatusImage(mContext, mResultSignatureIcon, mResultSignatureText, STATE_REVOKED); + mResultSignatureText.setText(R.string.openpgp_result_signature_revoked_key); + + setUserId(signatureResult); + mResultSignatureButton.setText(R.string.openpgp_result_action_show); + mResultSignatureButton.setVisibility(View.VISIBLE); + mResultSignatureLayout.setVisibility(View.VISIBLE); + + break; + } + + default: + break; + } + + } + } + + private void setUserId(OpenPgpSignatureResult signatureResult) { + String[] splitUserId = OpenPgpUtils.splitUserId(signatureResult.getPrimaryUserId()); + if (splitUserId[0] != null) { + mResultSignatureName.setText(splitUserId[0]); + } else { + mResultSignatureName.setText(R.string.openpgp_result_no_name); + } + if (splitUserId[1] != null) { + mResultSignatureEmail.setText(splitUserId[1]); + } else { + mResultSignatureEmail.setText(R.string.openpgp_result_no_email); + } + } + + public static final int STATE_REVOKED = 1; + public static final int STATE_EXPIRED = 2; + public static final int STATE_VERIFIED = 3; + public static final int STATE_UNAVAILABLE = 4; + public static final int STATE_ENCRYPTED = 5; + public static final int STATE_NOT_ENCRYPTED = 6; + public static final int STATE_UNVERIFIED = 7; + public static final int STATE_UNKNOWN_KEY = 8; + public static final int STATE_INVALID = 9; + public static final int STATE_NOT_SIGNED = 10; + + public static void setStatusImage(Context context, ImageView statusIcon, int state) { + setStatusImage(context, statusIcon, null, state); + } + + /** + * Sets status image based on constant + */ + public static void setStatusImage(Context context, ImageView statusIcon, TextView statusText, + int state) { + switch (state) { + /** GREEN: everything is good **/ + case STATE_VERIFIED: { + statusIcon.setImageDrawable( + context.getResources().getDrawable(R.drawable.status_signature_verified_cutout)); + int color = R.color.openpgp_green; + statusIcon.setColorFilter(context.getResources().getColor(color), + PorterDuff.Mode.SRC_IN); + if (statusText != null) { + statusText.setTextColor(context.getResources().getColor(color)); + } + break; + } + case STATE_ENCRYPTED: { + statusIcon.setImageDrawable( + context.getResources().getDrawable(R.drawable.status_lock_closed)); + int color = R.color.openpgp_green; + statusIcon.setColorFilter(context.getResources().getColor(color), + PorterDuff.Mode.SRC_IN); + if (statusText != null) { + statusText.setTextColor(context.getResources().getColor(color)); + } + break; + } + /** ORANGE: mostly bad... **/ + case STATE_UNVERIFIED: { + statusIcon.setImageDrawable( + context.getResources().getDrawable(R.drawable.status_signature_unverified_cutout)); + int color = R.color.openpgp_orange; + statusIcon.setColorFilter(context.getResources().getColor(color), + PorterDuff.Mode.SRC_IN); + if (statusText != null) { + statusText.setTextColor(context.getResources().getColor(color)); + } + break; + } + case STATE_UNKNOWN_KEY: { + statusIcon.setImageDrawable( + context.getResources().getDrawable(R.drawable.status_signature_unknown_cutout)); + int color = R.color.openpgp_orange; + statusIcon.setColorFilter(context.getResources().getColor(color), + PorterDuff.Mode.SRC_IN); + if (statusText != null) { + statusText.setTextColor(context.getResources().getColor(color)); + } + break; + } + /** RED: really bad... **/ + case STATE_REVOKED: { + statusIcon.setImageDrawable( + context.getResources().getDrawable(R.drawable.status_signature_revoked_cutout)); + int color = R.color.openpgp_red; + statusIcon.setColorFilter(context.getResources().getColor(color), + PorterDuff.Mode.SRC_IN); + if (statusText != null) { + statusText.setTextColor(context.getResources().getColor(color)); + } + break; + } + case STATE_EXPIRED: { + statusIcon.setImageDrawable( + context.getResources().getDrawable(R.drawable.status_signature_expired_cutout)); + int color = R.color.openpgp_red; + statusIcon.setColorFilter(context.getResources().getColor(color), + PorterDuff.Mode.SRC_IN); + if (statusText != null) { + statusText.setTextColor(context.getResources().getColor(color)); + } + break; + } + case STATE_NOT_ENCRYPTED: { + statusIcon.setImageDrawable( + context.getResources().getDrawable(R.drawable.status_lock_open)); + int color = R.color.openpgp_red; + statusIcon.setColorFilter(context.getResources().getColor(color), + PorterDuff.Mode.SRC_IN); + if (statusText != null) { + statusText.setTextColor(context.getResources().getColor(color)); + } + break; + } + case STATE_NOT_SIGNED: { + statusIcon.setImageDrawable( + context.getResources().getDrawable(R.drawable.status_signature_unknown_cutout)); + int color = R.color.openpgp_red; + statusIcon.setColorFilter(context.getResources().getColor(color), + PorterDuff.Mode.SRC_IN); + if (statusText != null) { + statusText.setTextColor(context.getResources().getColor(color)); + } + break; + } + case STATE_INVALID: { + statusIcon.setImageDrawable( + context.getResources().getDrawable(R.drawable.status_signature_invalid_cutout)); + int color = R.color.openpgp_red; + statusIcon.setColorFilter(context.getResources().getColor(color), + PorterDuff.Mode.SRC_IN); + if (statusText != null) { + statusText.setTextColor(context.getResources().getColor(color)); + } + break; + } + } + } + +} diff --git a/k9mail/src/main/java/com/fsck/k9/ui/messageview/OpenPgpHeaderViewCallback.java b/k9mail/src/main/java/com/fsck/k9/ui/messageview/OpenPgpHeaderViewCallback.java new file mode 100644 index 000000000..351e6a567 --- /dev/null +++ b/k9mail/src/main/java/com/fsck/k9/ui/messageview/OpenPgpHeaderViewCallback.java @@ -0,0 +1,9 @@ +package com.fsck.k9.ui.messageview; + + +import android.app.PendingIntent; + + +interface OpenPgpHeaderViewCallback { + void onPgpSignatureButtonClick(PendingIntent pendingIntent); +} diff --git a/k9mail/src/main/java/com/fsck/k9/view/MessageWebView.java b/k9mail/src/main/java/com/fsck/k9/view/MessageWebView.java index 0f64194e2..fdf6ff6d2 100644 --- a/k9mail/src/main/java/com/fsck/k9/view/MessageWebView.java +++ b/k9mail/src/main/java/com/fsck/k9/view/MessageWebView.java @@ -16,7 +16,6 @@ import com.fsck.k9.helper.HtmlSanitizer; public class MessageWebView extends RigidWebView { - public MessageWebView(Context context) { super(context); } diff --git a/k9mail/src/main/res/drawable-hdpi/status_lock_closed.png b/k9mail/src/main/res/drawable-hdpi/status_lock_closed.png new file mode 100644 index 000000000..a1b090630 Binary files /dev/null and b/k9mail/src/main/res/drawable-hdpi/status_lock_closed.png differ diff --git a/k9mail/src/main/res/drawable-hdpi/status_lock_error.png b/k9mail/src/main/res/drawable-hdpi/status_lock_error.png new file mode 100644 index 000000000..e567055aa Binary files /dev/null and b/k9mail/src/main/res/drawable-hdpi/status_lock_error.png differ diff --git a/k9mail/src/main/res/drawable-hdpi/status_lock_open.png b/k9mail/src/main/res/drawable-hdpi/status_lock_open.png new file mode 100644 index 000000000..98e32eadc Binary files /dev/null and b/k9mail/src/main/res/drawable-hdpi/status_lock_open.png differ diff --git a/k9mail/src/main/res/drawable-hdpi/status_signature_expired_cutout.png b/k9mail/src/main/res/drawable-hdpi/status_signature_expired_cutout.png new file mode 100644 index 000000000..84ac9bec2 Binary files /dev/null and b/k9mail/src/main/res/drawable-hdpi/status_signature_expired_cutout.png differ diff --git a/k9mail/src/main/res/drawable-hdpi/status_signature_invalid_cutout.png b/k9mail/src/main/res/drawable-hdpi/status_signature_invalid_cutout.png new file mode 100644 index 000000000..967e00e80 Binary files /dev/null and b/k9mail/src/main/res/drawable-hdpi/status_signature_invalid_cutout.png differ diff --git a/k9mail/src/main/res/drawable-hdpi/status_signature_revoked_cutout.png b/k9mail/src/main/res/drawable-hdpi/status_signature_revoked_cutout.png new file mode 100644 index 000000000..244dd0708 Binary files /dev/null and b/k9mail/src/main/res/drawable-hdpi/status_signature_revoked_cutout.png differ diff --git a/k9mail/src/main/res/drawable-hdpi/status_signature_unknown_cutout.png b/k9mail/src/main/res/drawable-hdpi/status_signature_unknown_cutout.png new file mode 100644 index 000000000..82cc25a4b Binary files /dev/null and b/k9mail/src/main/res/drawable-hdpi/status_signature_unknown_cutout.png differ diff --git a/k9mail/src/main/res/drawable-hdpi/status_signature_unverified_cutout.png b/k9mail/src/main/res/drawable-hdpi/status_signature_unverified_cutout.png new file mode 100644 index 000000000..e752eaeab Binary files /dev/null and b/k9mail/src/main/res/drawable-hdpi/status_signature_unverified_cutout.png differ diff --git a/k9mail/src/main/res/drawable-hdpi/status_signature_verified_cutout.png b/k9mail/src/main/res/drawable-hdpi/status_signature_verified_cutout.png new file mode 100644 index 000000000..08a9f464c Binary files /dev/null and b/k9mail/src/main/res/drawable-hdpi/status_signature_verified_cutout.png differ diff --git a/k9mail/src/main/res/drawable-mdpi/status_lock_closed.png b/k9mail/src/main/res/drawable-mdpi/status_lock_closed.png new file mode 100644 index 000000000..cfc39f0e7 Binary files /dev/null and b/k9mail/src/main/res/drawable-mdpi/status_lock_closed.png differ diff --git a/k9mail/src/main/res/drawable-mdpi/status_lock_error.png b/k9mail/src/main/res/drawable-mdpi/status_lock_error.png new file mode 100644 index 000000000..824dc2672 Binary files /dev/null and b/k9mail/src/main/res/drawable-mdpi/status_lock_error.png differ diff --git a/k9mail/src/main/res/drawable-mdpi/status_lock_open.png b/k9mail/src/main/res/drawable-mdpi/status_lock_open.png new file mode 100644 index 000000000..9bca59ae3 Binary files /dev/null and b/k9mail/src/main/res/drawable-mdpi/status_lock_open.png differ diff --git a/k9mail/src/main/res/drawable-mdpi/status_signature_expired_cutout.png b/k9mail/src/main/res/drawable-mdpi/status_signature_expired_cutout.png new file mode 100644 index 000000000..bc91094b5 Binary files /dev/null and b/k9mail/src/main/res/drawable-mdpi/status_signature_expired_cutout.png differ diff --git a/k9mail/src/main/res/drawable-mdpi/status_signature_invalid_cutout.png b/k9mail/src/main/res/drawable-mdpi/status_signature_invalid_cutout.png new file mode 100644 index 000000000..bc2f56e2a Binary files /dev/null and b/k9mail/src/main/res/drawable-mdpi/status_signature_invalid_cutout.png differ diff --git a/k9mail/src/main/res/drawable-mdpi/status_signature_revoked_cutout.png b/k9mail/src/main/res/drawable-mdpi/status_signature_revoked_cutout.png new file mode 100644 index 000000000..2d2593194 Binary files /dev/null and b/k9mail/src/main/res/drawable-mdpi/status_signature_revoked_cutout.png differ diff --git a/k9mail/src/main/res/drawable-mdpi/status_signature_unknown_cutout.png b/k9mail/src/main/res/drawable-mdpi/status_signature_unknown_cutout.png new file mode 100644 index 000000000..0fc74d07e Binary files /dev/null and b/k9mail/src/main/res/drawable-mdpi/status_signature_unknown_cutout.png differ diff --git a/k9mail/src/main/res/drawable-mdpi/status_signature_unverified_cutout.png b/k9mail/src/main/res/drawable-mdpi/status_signature_unverified_cutout.png new file mode 100644 index 000000000..96a2d1413 Binary files /dev/null and b/k9mail/src/main/res/drawable-mdpi/status_signature_unverified_cutout.png differ diff --git a/k9mail/src/main/res/drawable-mdpi/status_signature_verified_cutout.png b/k9mail/src/main/res/drawable-mdpi/status_signature_verified_cutout.png new file mode 100644 index 000000000..9f7cf837c Binary files /dev/null and b/k9mail/src/main/res/drawable-mdpi/status_signature_verified_cutout.png differ diff --git a/k9mail/src/main/res/drawable-xhdpi/status_lock_closed.png b/k9mail/src/main/res/drawable-xhdpi/status_lock_closed.png new file mode 100644 index 000000000..7c6bb2d18 Binary files /dev/null and b/k9mail/src/main/res/drawable-xhdpi/status_lock_closed.png differ diff --git a/k9mail/src/main/res/drawable-xhdpi/status_lock_error.png b/k9mail/src/main/res/drawable-xhdpi/status_lock_error.png new file mode 100644 index 000000000..da4a5d89a Binary files /dev/null and b/k9mail/src/main/res/drawable-xhdpi/status_lock_error.png differ diff --git a/k9mail/src/main/res/drawable-xhdpi/status_lock_open.png b/k9mail/src/main/res/drawable-xhdpi/status_lock_open.png new file mode 100644 index 000000000..cd02fc1e4 Binary files /dev/null and b/k9mail/src/main/res/drawable-xhdpi/status_lock_open.png differ diff --git a/k9mail/src/main/res/drawable-xhdpi/status_signature_expired_cutout.png b/k9mail/src/main/res/drawable-xhdpi/status_signature_expired_cutout.png new file mode 100644 index 000000000..83f6fde35 Binary files /dev/null and b/k9mail/src/main/res/drawable-xhdpi/status_signature_expired_cutout.png differ diff --git a/k9mail/src/main/res/drawable-xhdpi/status_signature_invalid_cutout.png b/k9mail/src/main/res/drawable-xhdpi/status_signature_invalid_cutout.png new file mode 100644 index 000000000..29830f5ba Binary files /dev/null and b/k9mail/src/main/res/drawable-xhdpi/status_signature_invalid_cutout.png differ diff --git a/k9mail/src/main/res/drawable-xhdpi/status_signature_revoked_cutout.png b/k9mail/src/main/res/drawable-xhdpi/status_signature_revoked_cutout.png new file mode 100644 index 000000000..2f7695043 Binary files /dev/null and b/k9mail/src/main/res/drawable-xhdpi/status_signature_revoked_cutout.png differ diff --git a/k9mail/src/main/res/drawable-xhdpi/status_signature_unknown_cutout.png b/k9mail/src/main/res/drawable-xhdpi/status_signature_unknown_cutout.png new file mode 100644 index 000000000..2ce28c7ca Binary files /dev/null and b/k9mail/src/main/res/drawable-xhdpi/status_signature_unknown_cutout.png differ diff --git a/k9mail/src/main/res/drawable-xhdpi/status_signature_unverified_cutout.png b/k9mail/src/main/res/drawable-xhdpi/status_signature_unverified_cutout.png new file mode 100644 index 000000000..442c55eee Binary files /dev/null and b/k9mail/src/main/res/drawable-xhdpi/status_signature_unverified_cutout.png differ diff --git a/k9mail/src/main/res/drawable-xhdpi/status_signature_verified_cutout.png b/k9mail/src/main/res/drawable-xhdpi/status_signature_verified_cutout.png new file mode 100644 index 000000000..160ec7cbe Binary files /dev/null and b/k9mail/src/main/res/drawable-xhdpi/status_signature_verified_cutout.png differ diff --git a/k9mail/src/main/res/drawable-xxhdpi/status_lock_closed.png b/k9mail/src/main/res/drawable-xxhdpi/status_lock_closed.png new file mode 100644 index 000000000..5a9664d59 Binary files /dev/null and b/k9mail/src/main/res/drawable-xxhdpi/status_lock_closed.png differ diff --git a/k9mail/src/main/res/drawable-xxhdpi/status_lock_error.png b/k9mail/src/main/res/drawable-xxhdpi/status_lock_error.png new file mode 100644 index 000000000..608f065af Binary files /dev/null and b/k9mail/src/main/res/drawable-xxhdpi/status_lock_error.png differ diff --git a/k9mail/src/main/res/drawable-xxhdpi/status_lock_open.png b/k9mail/src/main/res/drawable-xxhdpi/status_lock_open.png new file mode 100644 index 000000000..ee34dd396 Binary files /dev/null and b/k9mail/src/main/res/drawable-xxhdpi/status_lock_open.png differ diff --git a/k9mail/src/main/res/drawable-xxhdpi/status_signature_expired_cutout.png b/k9mail/src/main/res/drawable-xxhdpi/status_signature_expired_cutout.png new file mode 100644 index 000000000..33a3efed1 Binary files /dev/null and b/k9mail/src/main/res/drawable-xxhdpi/status_signature_expired_cutout.png differ diff --git a/k9mail/src/main/res/drawable-xxhdpi/status_signature_invalid_cutout.png b/k9mail/src/main/res/drawable-xxhdpi/status_signature_invalid_cutout.png new file mode 100644 index 000000000..bc39d3496 Binary files /dev/null and b/k9mail/src/main/res/drawable-xxhdpi/status_signature_invalid_cutout.png differ diff --git a/k9mail/src/main/res/drawable-xxhdpi/status_signature_revoked_cutout.png b/k9mail/src/main/res/drawable-xxhdpi/status_signature_revoked_cutout.png new file mode 100644 index 000000000..58929661f Binary files /dev/null and b/k9mail/src/main/res/drawable-xxhdpi/status_signature_revoked_cutout.png differ diff --git a/k9mail/src/main/res/drawable-xxhdpi/status_signature_unknown_cutout.png b/k9mail/src/main/res/drawable-xxhdpi/status_signature_unknown_cutout.png new file mode 100644 index 000000000..3020357a4 Binary files /dev/null and b/k9mail/src/main/res/drawable-xxhdpi/status_signature_unknown_cutout.png differ diff --git a/k9mail/src/main/res/drawable-xxhdpi/status_signature_unverified_cutout.png b/k9mail/src/main/res/drawable-xxhdpi/status_signature_unverified_cutout.png new file mode 100644 index 000000000..3829bb3a0 Binary files /dev/null and b/k9mail/src/main/res/drawable-xxhdpi/status_signature_unverified_cutout.png differ diff --git a/k9mail/src/main/res/drawable-xxhdpi/status_signature_verified_cutout.png b/k9mail/src/main/res/drawable-xxhdpi/status_signature_verified_cutout.png new file mode 100644 index 000000000..3548ee2b6 Binary files /dev/null and b/k9mail/src/main/res/drawable-xxhdpi/status_signature_verified_cutout.png differ diff --git a/k9mail/src/main/res/layout/message.xml b/k9mail/src/main/res/layout/message.xml index cbf2552de..a3f18a080 100644 --- a/k9mail/src/main/res/layout/message.xml +++ b/k9mail/src/main/res/layout/message.xml @@ -1,5 +1,5 @@ - - - - - - - - - - - -