Advertisement
Guest User

MessageView fragment

a guest
Sep 20th, 2014
79
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 32.21 KB | None | 0 0
  1. import java.io.File;
  2. import java.util.Collections;
  3. import java.util.Locale;
  4.  
  5. import android.app.Activity;
  6. import android.app.Fragment;
  7. import android.content.Context;
  8. import android.content.Intent;
  9. import android.net.Uri;
  10. import android.os.Bundle;
  11. import android.os.Handler;
  12. import android.app.DialogFragment;
  13. import android.app.FragmentManager;
  14. import android.util.Log;
  15. import android.view.ContextThemeWrapper;
  16. import android.view.KeyEvent;
  17. import android.view.LayoutInflater;
  18. import android.view.MenuItem;
  19. import android.view.View;
  20. import android.view.View.OnClickListener;
  21. import android.view.ViewGroup;
  22. import android.widget.Toast;
  23.  
  24. import com.fsck.k9.Account;
  25. import com.fsck.k9.K9;
  26. import com.fsck.k9.Preferences;
  27. import com.fsck.k9.R;
  28. import com.fsck.k9.activity.ChooseFolder;
  29. import com.fsck.k9.activity.MessageList;
  30. import com.fsck.k9.activity.MessageReference;
  31. import com.fsck.k9.controller.MessagingController;
  32. import com.fsck.k9.controller.MessagingListener;
  33. import com.fsck.k9.crypto.CryptoProvider.CryptoDecryptCallback;
  34. import com.fsck.k9.crypto.PgpData;
  35. import com.fsck.k9.fragment.ConfirmationDialogFragment.ConfirmationDialogFragmentListener;
  36. import com.fsck.k9.helper.FileBrowserHelper;
  37. import com.fsck.k9.helper.FileBrowserHelper.FileBrowserFailOverCallback;
  38. import com.fsck.k9.mail.Flag;
  39. import com.fsck.k9.mail.Message;
  40. import com.fsck.k9.mail.MessagingException;
  41. import com.fsck.k9.mail.Part;
  42. import com.fsck.k9.mail.store.LocalStore.LocalMessage;
  43. import com.fsck.k9.view.AttachmentView;
  44. import com.fsck.k9.view.AttachmentView.AttachmentFileDownloadCallback;
  45. import com.fsck.k9.view.MessageHeader;
  46. import com.fsck.k9.view.SingleMessageView;
  47.  
  48. import org.openintents.openpgp.OpenPgpSignatureResult;
  49.  
  50.  
  51. public class MessageViewFragment extends Fragment implements OnClickListener,
  52.         CryptoDecryptCallback, ConfirmationDialogFragmentListener {
  53.  
  54.     private static final String ARG_REFERENCE = "reference";
  55.  
  56.     private static final String STATE_MESSAGE_REFERENCE = "reference";
  57.     private static final String STATE_PGP_DATA = "pgpData";
  58.  
  59.     private static final int ACTIVITY_CHOOSE_FOLDER_MOVE = 1;
  60.     private static final int ACTIVITY_CHOOSE_FOLDER_COPY = 2;
  61.     private static final int ACTIVITY_CHOOSE_DIRECTORY = 3;
  62.  
  63.  
  64.     public static MessageViewFragment newInstance(MessageReference reference) {
  65.         MessageViewFragment fragment = new MessageViewFragment();
  66.  
  67.         Bundle args = new Bundle();
  68.         args.putParcelable(ARG_REFERENCE, reference);
  69.         fragment.setArguments(args);
  70.  
  71.         return fragment;
  72.     }
  73.  
  74.  
  75.     private SingleMessageView mMessageView;
  76.     private PgpData mPgpData;
  77.     private Account mAccount;
  78.     private MessageReference mMessageReference;
  79.     private Message mMessage;
  80.     private MessagingController mController;
  81.     private Listener mListener = new Listener();
  82.     private MessageViewHandler mHandler = new MessageViewHandler();
  83.     private LayoutInflater mLayoutInflater;
  84.  
  85.     /** this variable is used to save the calling AttachmentView
  86.      *  until the onActivityResult is called.
  87.      *  => with this reference we can identity the caller
  88.      */
  89.     private AttachmentView attachmentTmpStore;
  90.  
  91.     /**
  92.      * Used to temporarily store the destination folder for refile operations if a confirmation
  93.      * dialog is shown.
  94.      */
  95.     private String mDstFolder;
  96.  
  97.     private MessageViewFragmentListener mFragmentListener;
  98.  
  99.     /**
  100.      * {@code true} after {@link #onCreate(Bundle)} has been executed. This is used by
  101.      * {@code MessageList.configureMenu()} to make sure the fragment has been initialized before
  102.      * it is used.
  103.      */
  104.     private boolean mInitialized = false;
  105.  
  106.     private Context mContext;
  107.  
  108.  
  109.     class MessageViewHandler extends Handler {
  110.  
  111.         public void progress(final boolean progress) {
  112.             post(new Runnable() {
  113.                 @Override
  114.                 public void run() {
  115.                     setProgress(progress);
  116.                 }
  117.             });
  118.         }
  119.  
  120.         public void addAttachment(final View attachmentView) {
  121.             post(new Runnable() {
  122.                 @Override
  123.                 public void run() {
  124.                     mMessageView.addAttachment(attachmentView);
  125.                 }
  126.             });
  127.         }
  128.  
  129.         /* A helper for a set of "show a toast" methods */
  130.         private void showToast(final String message, final int toastLength)  {
  131.             post(new Runnable() {
  132.                 @Override
  133.                 public void run() {
  134.                     Toast.makeText(getActivity(), message, toastLength).show();
  135.                 }
  136.             });
  137.         }
  138.  
  139.         public void networkError() {
  140.             // FIXME: This is a hack. Fix the Handler madness!
  141.             Context context = getActivity();
  142.             if (context == null) {
  143.                 return;
  144.             }
  145.  
  146.             showToast(context.getString(R.string.status_network_error), Toast.LENGTH_LONG);
  147.         }
  148.  
  149.         public void invalidIdError() {
  150.             Context context = getActivity();
  151.             if (context == null) {
  152.                 return;
  153.             }
  154.  
  155.             showToast(context.getString(R.string.status_invalid_id_error), Toast.LENGTH_LONG);
  156.         }
  157.  
  158.  
  159.         public void fetchingAttachment() {
  160.             Context context = getActivity();
  161.             if (context == null) {
  162.                 return;
  163.             }
  164.  
  165.             showToast(context.getString(R.string.message_view_fetching_attachment_toast), Toast.LENGTH_SHORT);
  166.         }
  167.     }
  168.  
  169.     @Override
  170.     public void onAttach(Activity activity) {
  171.         super.onAttach(activity);
  172.  
  173.         mContext = activity.getApplicationContext();
  174.  
  175.         try {
  176.             mFragmentListener = (MessageViewFragmentListener) activity;
  177.         } catch (ClassCastException e) {
  178.             throw new ClassCastException(activity.getClass() +
  179.                     " must implement MessageViewFragmentListener");
  180.         }
  181.     }
  182.  
  183.     @Override
  184.     public void onCreate(Bundle savedInstanceState) {
  185.         super.onCreate(savedInstanceState);
  186.  
  187.         // This fragments adds options to the action bar
  188.         setHasOptionsMenu(true);
  189.  
  190.         mController = MessagingController.getInstance(getActivity().getApplication());
  191.         mInitialized = true;
  192.        
  193.         MessageList.mDrawerToggle.setDrawerIndicatorEnabled(false);
  194.     }
  195.  
  196.     @Override
  197.     public View onCreateView(LayoutInflater inflater, ViewGroup container,
  198.             Bundle savedInstanceState) {
  199.         Context context = new ContextThemeWrapper(inflater.getContext(),
  200.                 K9.getK9ThemeResourceId(K9.getK9MessageViewTheme()));
  201.         mLayoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
  202.         View view = mLayoutInflater.inflate(R.layout.message, container, false);
  203.  
  204.  
  205.         mMessageView = (SingleMessageView) view.findViewById(R.id.message_view);
  206.  
  207.         //set a callback for the attachment view. With this callback the attachmentview
  208.         //request the start of a filebrowser activity.
  209.         mMessageView.setAttachmentCallback(new AttachmentFileDownloadCallback() {
  210.  
  211.             @Override
  212.             public void showFileBrowser(final AttachmentView caller) {
  213.                 FileBrowserHelper.getInstance()
  214.                 .showFileBrowserActivity(MessageViewFragment.this,
  215.                                          null,
  216.                                          ACTIVITY_CHOOSE_DIRECTORY,
  217.                                          callback);
  218.                 attachmentTmpStore = caller;
  219.             }
  220.  
  221.             FileBrowserFailOverCallback callback = new FileBrowserFailOverCallback() {
  222.  
  223.                 @Override
  224.                 public void onPathEntered(String path) {
  225.                     attachmentTmpStore.writeFile(new File(path));
  226.                 }
  227.  
  228.                 @Override
  229.                 public void onCancel() {
  230.                     // canceled, do nothing
  231.                 }
  232.             };
  233.         });
  234.  
  235.         mMessageView.initialize(this);
  236.         mMessageView.downloadRemainderButton().setOnClickListener(this);
  237.  
  238.         mFragmentListener.messageHeaderViewAvailable(mMessageView.getMessageHeaderView());
  239.  
  240.         return view;
  241.     }
  242.  
  243.     @Override
  244.     public void onActivityCreated(Bundle savedInstanceState) {
  245.         super.onActivityCreated(savedInstanceState);
  246.  
  247.         MessageReference messageReference;
  248.         if (savedInstanceState != null) {
  249.             mPgpData = (PgpData) savedInstanceState.get(STATE_PGP_DATA);
  250.             messageReference = (MessageReference) savedInstanceState.get(STATE_MESSAGE_REFERENCE);
  251.         } else {
  252.             Bundle args = getArguments();
  253.             messageReference = (MessageReference) args.getParcelable(ARG_REFERENCE);
  254.         }
  255.  
  256.         displayMessage(messageReference, (mPgpData == null));
  257.     }
  258.  
  259.     @Override
  260.     public void onSaveInstanceState(Bundle outState) {
  261.         super.onSaveInstanceState(outState);
  262.         outState.putParcelable(STATE_MESSAGE_REFERENCE, mMessageReference);
  263.         outState.putSerializable(STATE_PGP_DATA, mPgpData);
  264.     }
  265.  
  266.     public void displayMessage(MessageReference ref) {
  267.         displayMessage(ref, true);
  268.     }
  269.  
  270.     private void displayMessage(MessageReference ref, boolean resetPgpData) {
  271.         mMessageReference = ref;
  272.         if (K9.DEBUG) {
  273.             Log.d(K9.LOG_TAG, "MessageView displaying message " + mMessageReference);
  274.         }
  275.  
  276.         Context appContext = getActivity().getApplicationContext();
  277.         mAccount = Preferences.getPreferences(appContext).getAccount(mMessageReference.accountUuid);
  278.  
  279.         if (resetPgpData) {
  280.             // start with fresh, empty PGP data
  281.             mPgpData = new PgpData();
  282.         }
  283.  
  284.         // Clear previous message
  285.         mMessageView.resetView();
  286.         mMessageView.resetHeaderView();
  287.  
  288.         mController.loadMessageForView(mAccount, mMessageReference.folderName, mMessageReference.uid, mListener);
  289.  
  290.         mFragmentListener.updateMenu();
  291.     }
  292.  
  293.     /**
  294.      * Called from UI thread when user select Delete
  295.      */
  296.     public void onDelete() {
  297.         if (K9.confirmDelete() || (K9.confirmDeleteStarred() && mMessage.isSet(Flag.FLAGGED))) {
  298.             showDialog(R.id.dialog_confirm_delete);
  299.         } else {
  300.             delete();
  301.         }
  302.     }
  303.  
  304.     public void onToggleAllHeadersView() {
  305.         mMessageView.getMessageHeaderView().onShowAdditionalHeaders();
  306.     }
  307.  
  308.     public boolean allHeadersVisible() {
  309.         return mMessageView.getMessageHeaderView().additionalHeadersVisible();
  310.     }
  311.  
  312.     private void delete() {
  313.         if (mMessage != null) {
  314.             // Disable the delete button after it's tapped (to try to prevent
  315.             // accidental clicks)
  316.             mFragmentListener.disableDeleteAction();
  317.             Message messageToDelete = mMessage;
  318.             mFragmentListener.showNextMessageOrReturn();
  319.             mController.deleteMessages(Collections.singletonList(messageToDelete), null);
  320.         }
  321.     }
  322.  
  323.     public void onRefile(String dstFolder) {
  324.         if (!mController.isMoveCapable(mAccount)) {
  325.             return;
  326.         }
  327.         if (!mController.isMoveCapable(mMessage)) {
  328.             Toast toast = Toast.makeText(getActivity(), R.string.move_copy_cannot_copy_unsynced_message, Toast.LENGTH_LONG);
  329.             toast.show();
  330.             return;
  331.         }
  332.  
  333.         if (K9.FOLDER_NONE.equalsIgnoreCase(dstFolder)) {
  334.             return;
  335.         }
  336.  
  337.         if (mAccount.getSpamFolderName().equals(dstFolder) && K9.confirmSpam()) {
  338.             mDstFolder = dstFolder;
  339.             showDialog(R.id.dialog_confirm_spam);
  340.         } else {
  341.             refileMessage(dstFolder);
  342.         }
  343.     }
  344.  
  345.     private void refileMessage(String dstFolder) {
  346.         String srcFolder = mMessageReference.folderName;
  347.         Message messageToMove = mMessage;
  348.         mFragmentListener.showNextMessageOrReturn();
  349.         mController.moveMessage(mAccount, srcFolder, messageToMove, dstFolder, null);
  350.     }
  351.  
  352.     public void onReply() {
  353.         if (mMessage != null) {
  354.             mFragmentListener.onReply(mMessage, mPgpData);
  355.         }
  356.     }
  357.  
  358.     public void onReplyAll() {
  359.         if (mMessage != null) {
  360.             mFragmentListener.onReplyAll(mMessage, mPgpData);
  361.         }
  362.     }
  363.  
  364.     public void onForward() {
  365.         if (mMessage != null) {
  366.             mFragmentListener.onForward(mMessage, mPgpData);
  367.         }
  368.     }
  369.  
  370.     public void onToggleFlagged() {
  371.         if (mMessage != null) {
  372.             boolean newState = !mMessage.isSet(Flag.FLAGGED);
  373.             mController.setFlag(mAccount, mMessage.getFolder().getName(),
  374.                     new Message[] { mMessage }, Flag.FLAGGED, newState);
  375.             mMessageView.setHeaders(mMessage, mAccount);
  376.         }
  377.     }
  378.  
  379.     public void onMove() {
  380.         if ((!mController.isMoveCapable(mAccount))
  381.                 || (mMessage == null)) {
  382.             return;
  383.         }
  384.         if (!mController.isMoveCapable(mMessage)) {
  385.             Toast toast = Toast.makeText(getActivity(), R.string.move_copy_cannot_copy_unsynced_message, Toast.LENGTH_LONG);
  386.             toast.show();
  387.             return;
  388.         }
  389.  
  390.         startRefileActivity(ACTIVITY_CHOOSE_FOLDER_MOVE);
  391.  
  392.     }
  393.  
  394.     public void onCopy() {
  395.         if ((!mController.isCopyCapable(mAccount))
  396.                 || (mMessage == null)) {
  397.             return;
  398.         }
  399.         if (!mController.isCopyCapable(mMessage)) {
  400.             Toast toast = Toast.makeText(getActivity(), R.string.move_copy_cannot_copy_unsynced_message, Toast.LENGTH_LONG);
  401.             toast.show();
  402.             return;
  403.         }
  404.  
  405.         startRefileActivity(ACTIVITY_CHOOSE_FOLDER_COPY);
  406.     }
  407.  
  408.     public void onArchive() {
  409.         onRefile(mAccount.getArchiveFolderName());
  410.     }
  411.  
  412.     public void onSpam() {
  413.         onRefile(mAccount.getSpamFolderName());
  414.     }
  415.  
  416.     public void onSelectText() {
  417.         mMessageView.beginSelectingText();
  418.     }
  419.  
  420.     private void startRefileActivity(int activity) {
  421.         Intent intent = new Intent(getActivity(), ChooseFolder.class);
  422.         intent.putExtra(ChooseFolder.EXTRA_ACCOUNT, mAccount.getUuid());
  423.         intent.putExtra(ChooseFolder.EXTRA_CUR_FOLDER, mMessageReference.folderName);
  424.         intent.putExtra(ChooseFolder.EXTRA_SEL_FOLDER, mAccount.getLastSelectedFolderName());
  425.         intent.putExtra(ChooseFolder.EXTRA_MESSAGE, mMessageReference);
  426.         startActivityForResult(intent, activity);
  427.     }
  428.  
  429.  
  430.     @Override
  431.     public void onActivityResult(int requestCode, int resultCode, Intent data) {
  432.         if (mAccount.getCryptoProvider().onDecryptActivityResult(this, requestCode, resultCode, data, mPgpData)) {
  433.             return;
  434.         }
  435.  
  436.         if (resultCode != Activity.RESULT_OK) {
  437.             return;
  438.         }
  439.  
  440.         switch (requestCode) {
  441.             case ACTIVITY_CHOOSE_DIRECTORY: {
  442.                 if (resultCode == Activity.RESULT_OK && data != null) {
  443.                     // obtain the filename
  444.                     Uri fileUri = data.getData();
  445.                     if (fileUri != null) {
  446.                         String filePath = fileUri.getPath();
  447.                         if (filePath != null) {
  448.                             attachmentTmpStore.writeFile(new File(filePath));
  449.                         }
  450.                     }
  451.                 }
  452.                 break;
  453.             }
  454.             case ACTIVITY_CHOOSE_FOLDER_MOVE:
  455.             case ACTIVITY_CHOOSE_FOLDER_COPY: {
  456.                 if (data == null) {
  457.                     return;
  458.                 }
  459.  
  460.                 String destFolderName = data.getStringExtra(ChooseFolder.EXTRA_NEW_FOLDER);
  461.                 MessageReference ref = data.getParcelableExtra(ChooseFolder.EXTRA_MESSAGE);
  462.                 if (mMessageReference.equals(ref)) {
  463.                     mAccount.setLastSelectedFolderName(destFolderName);
  464.                     switch (requestCode) {
  465.                         case ACTIVITY_CHOOSE_FOLDER_MOVE: {
  466.                             mFragmentListener.showNextMessageOrReturn();
  467.                             moveMessage(ref, destFolderName);
  468.                             break;
  469.                         }
  470.                         case ACTIVITY_CHOOSE_FOLDER_COPY: {
  471.                             copyMessage(ref, destFolderName);
  472.                             break;
  473.                         }
  474.                     }
  475.                 }
  476.                 break;
  477.             }
  478.         }
  479.     }
  480.  
  481.     public void onSendAlternate() {
  482.         if (mMessage != null) {
  483.             mController.sendAlternate(getActivity(), mAccount, mMessage);
  484.         }
  485.     }
  486.  
  487.     public void onToggleRead() {
  488.         if (mMessage != null) {
  489.             mController.setFlag(mAccount, mMessage.getFolder().getName(),
  490.                     new Message[] { mMessage }, Flag.SEEN, !mMessage.isSet(Flag.SEEN));
  491.             mMessageView.setHeaders(mMessage, mAccount);
  492.             String subject = mMessage.getSubject();
  493.             displayMessageSubject(subject);
  494.             mFragmentListener.updateMenu();
  495.         }
  496.     }
  497.  
  498.     private void onDownloadRemainder() {
  499.         if (mMessage.isSet(Flag.X_DOWNLOADED_FULL)) {
  500.             return;
  501.         }
  502.         mMessageView.downloadRemainderButton().setEnabled(false);
  503.         mController.loadMessageForViewRemote(mAccount, mMessageReference.folderName, mMessageReference.uid, mListener);
  504.     }
  505.  
  506.     @Override
  507.     public void onClick(View view) {
  508.         switch (view.getId()) {
  509.             case R.id.download: {
  510.                 ((AttachmentView)view).saveFile();
  511.                 break;
  512.             }
  513.             case R.id.download_remainder: {
  514.                 onDownloadRemainder();
  515.                 break;
  516.             }
  517.         }
  518.     }
  519.  
  520.     private void setProgress(boolean enable) {
  521.         if (mFragmentListener != null) {
  522.             mFragmentListener.setProgress(enable);
  523.         }
  524.     }
  525.  
  526.     private void displayMessageSubject(String subject) {
  527.         if (mFragmentListener != null) {
  528.             mFragmentListener.displayMessageSubject(subject);
  529.         }
  530.     }
  531.  
  532.     public void moveMessage(MessageReference reference, String destFolderName) {
  533.         mController.moveMessage(mAccount, mMessageReference.folderName, mMessage,
  534.                 destFolderName, null);
  535.     }
  536.  
  537.     public void copyMessage(MessageReference reference, String destFolderName) {
  538.         mController.copyMessage(mAccount, mMessageReference.folderName, mMessage,
  539.                 destFolderName, null);
  540.     }
  541.  
  542.     class Listener extends MessagingListener {
  543.         @Override
  544.         public void loadMessageForViewHeadersAvailable(final Account account, String folder, String uid,
  545.                 final Message message) {
  546.             if (!mMessageReference.uid.equals(uid) || !mMessageReference.folderName.equals(folder)
  547.                     || !mMessageReference.accountUuid.equals(account.getUuid())) {
  548.                 return;
  549.             }
  550.  
  551.             /*
  552.              * Clone the message object because the original could be modified by
  553.              * MessagingController later. This could lead to a ConcurrentModificationException
  554.              * when that same object is accessed by the UI thread (below).
  555.              *
  556.              * See issue 3953
  557.              *
  558.              * This is just an ugly hack to get rid of the most pressing problem. A proper way to
  559.              * fix this is to make Message thread-safe. Or, even better, rewriting the UI code to
  560.              * access messages via a ContentProvider.
  561.              *
  562.              */
  563.             final Message clonedMessage = message.clone();
  564.  
  565.             mHandler.post(new Runnable() {
  566.                 @Override
  567.                 public void run() {
  568.                     if (!clonedMessage.isSet(Flag.X_DOWNLOADED_FULL) &&
  569.                             !clonedMessage.isSet(Flag.X_DOWNLOADED_PARTIAL)) {
  570.                         String text = mContext.getString(R.string.message_view_downloading);
  571.                         mMessageView.showStatusMessage(text);
  572.                     }
  573.                     mMessageView.setHeaders(clonedMessage, account);
  574.                     final String subject = clonedMessage.getSubject();
  575.                     if (subject == null || subject.equals("")) {
  576.                         displayMessageSubject(mContext.getString(R.string.general_no_subject));
  577.                     } else {
  578.                         displayMessageSubject(clonedMessage.getSubject());
  579.                     }
  580.                     mMessageView.setOnFlagListener(new OnClickListener() {
  581.                         @Override
  582.                         public void onClick(View v) {
  583.                             onToggleFlagged();
  584.                         }
  585.                     });
  586.                 }
  587.             });
  588.         }
  589.  
  590.         @Override
  591.         public void loadMessageForViewBodyAvailable(final Account account, String folder,
  592.                 String uid, final Message message) {
  593.             if (!mMessageReference.uid.equals(uid) ||
  594.                     !mMessageReference.folderName.equals(folder) ||
  595.                     !mMessageReference.accountUuid.equals(account.getUuid())) {
  596.                 return;
  597.             }
  598.  
  599.             mHandler.post(new Runnable() {
  600.                 @Override
  601.                 public void run() {
  602.                     try {
  603.                         mMessage = message;
  604.                         mMessageView.setMessage(account, (LocalMessage) message, mPgpData,
  605.                                 mController, mListener);
  606.                         mFragmentListener.updateMenu();
  607.  
  608.                     } catch (MessagingException e) {
  609.                         Log.v(K9.LOG_TAG, "loadMessageForViewBodyAvailable", e);
  610.                     }
  611.                 }
  612.             });
  613.         }
  614.  
  615.         @Override
  616.         public void loadMessageForViewFailed(Account account, String folder, String uid, final Throwable t) {
  617.             if (!mMessageReference.uid.equals(uid) || !mMessageReference.folderName.equals(folder)
  618.                     || !mMessageReference.accountUuid.equals(account.getUuid())) {
  619.                 return;
  620.             }
  621.             mHandler.post(new Runnable() {
  622.                 @Override
  623.                 public void run() {
  624.                     setProgress(false);
  625.                     if (t instanceof IllegalArgumentException) {
  626.                         mHandler.invalidIdError();
  627.                     } else {
  628.                         mHandler.networkError();
  629.                     }
  630.                     if (mMessage == null || mMessage.isSet(Flag.X_DOWNLOADED_PARTIAL)) {
  631.                         mMessageView.showStatusMessage(
  632.                                 mContext.getString(R.string.webview_empty_message));
  633.                     }
  634.                 }
  635.             });
  636.         }
  637.  
  638.         @Override
  639.         public void loadMessageForViewFinished(Account account, String folder, String uid, final Message message) {
  640.             if (!mMessageReference.uid.equals(uid) || !mMessageReference.folderName.equals(folder)
  641.                     || !mMessageReference.accountUuid.equals(account.getUuid())) {
  642.                 return;
  643.             }
  644.             mHandler.post(new Runnable() {
  645.                 @Override
  646.                 public void run() {
  647.                     setProgress(false);
  648.                     mMessageView.setShowDownloadButton(message);
  649.                 }
  650.             });
  651.         }
  652.  
  653.         @Override
  654.         public void loadMessageForViewStarted(Account account, String folder, String uid) {
  655.             if (!mMessageReference.uid.equals(uid) || !mMessageReference.folderName.equals(folder)
  656.                     || !mMessageReference.accountUuid.equals(account.getUuid())) {
  657.                 return;
  658.             }
  659.             mHandler.post(new Runnable() {
  660.                 @Override
  661.                 public void run() {
  662.                     setProgress(true);
  663.                 }
  664.             });
  665.         }
  666.  
  667.         @Override
  668.         public void loadAttachmentStarted(Account account, Message message, Part part, Object tag, final boolean requiresDownload) {
  669.             if (mMessage != message) {
  670.                 return;
  671.             }
  672.             mHandler.post(new Runnable() {
  673.                 @Override
  674.                 public void run() {
  675.                     mMessageView.setAttachmentsEnabled(false);
  676.                     showDialog(R.id.dialog_attachment_progress);
  677.                     if (requiresDownload) {
  678.                         mHandler.fetchingAttachment();
  679.                     }
  680.                 }
  681.             });
  682.         }
  683.  
  684.         @Override
  685.         public void loadAttachmentFinished(Account account, Message message, Part part, final Object tag) {
  686.             if (mMessage != message) {
  687.                 return;
  688.             }
  689.             mHandler.post(new Runnable() {
  690.                 @Override
  691.                 public void run() {
  692.                     mMessageView.setAttachmentsEnabled(true);
  693.                     removeDialog(R.id.dialog_attachment_progress);
  694.                     Object[] params = (Object[]) tag;
  695.                     boolean download = (Boolean) params[0];
  696.                     AttachmentView attachment = (AttachmentView) params[1];
  697.                     if (download) {
  698.                         attachment.writeFile();
  699.                     } else {
  700.                         attachment.showFile();
  701.                     }
  702.                 }
  703.             });
  704.         }
  705.  
  706.         @Override
  707.         public void loadAttachmentFailed(Account account, Message message, Part part, Object tag, String reason) {
  708.             if (mMessage != message) {
  709.                 return;
  710.             }
  711.             mHandler.post(new Runnable() {
  712.                 @Override
  713.                 public void run() {
  714.                     mMessageView.setAttachmentsEnabled(true);
  715.                     removeDialog(R.id.dialog_attachment_progress);
  716.                     mHandler.networkError();
  717.                 }
  718.             });
  719.         }
  720.     }
  721.    
  722.     /**
  723.      * Used by MessageOpenPgpView
  724.      */
  725.     public void setMessageWithOpenPgp(String decryptedData, OpenPgpSignatureResult signatureResult) {
  726.         try {
  727.             // TODO: get rid of PgpData?
  728.             PgpData data = new PgpData();
  729.             data.setDecryptedData(decryptedData);
  730.             data.setSignatureResult(signatureResult);
  731.             mMessageView.setMessage(mAccount, (LocalMessage) mMessage, data, mController, mListener);
  732.         } catch (MessagingException e) {
  733.             Log.e(K9.LOG_TAG, "displayMessageBody failed", e);
  734.         }
  735.     }
  736.  
  737.     // This REALLY should be in MessageCryptoView
  738.     @Override
  739.     public void onDecryptDone(PgpData pgpData) {
  740.         Account account = mAccount;
  741.         LocalMessage message = (LocalMessage) mMessage;
  742.         MessagingController controller = mController;
  743.         Listener listener = mListener;
  744.         try {
  745.             mMessageView.setMessage(account, message, pgpData, controller, listener);
  746.         } catch (MessagingException e) {
  747.             Log.e(K9.LOG_TAG, "displayMessageBody failed", e);
  748.         }
  749.     }
  750.  
  751.     private void showDialog(int dialogId) {
  752.         DialogFragment fragment;
  753.         switch (dialogId) {
  754.             case R.id.dialog_confirm_delete: {
  755.                 String title = getString(R.string.dialog_confirm_delete_title);
  756.                 String message = getString(R.string.dialog_confirm_delete_message);
  757.                 String confirmText = getString(R.string.dialog_confirm_delete_confirm_button);
  758.                 String cancelText = getString(R.string.dialog_confirm_delete_cancel_button);
  759.  
  760.                 fragment = ConfirmationDialogFragment.newInstance(dialogId, title, message,
  761.                         confirmText, cancelText);
  762.                 break;
  763.             }
  764.             case R.id.dialog_confirm_spam: {
  765.                 String title = getString(R.string.dialog_confirm_spam_title);
  766.                 String message = getResources().getQuantityString(R.plurals.dialog_confirm_spam_message, 1);
  767.                 String confirmText = getString(R.string.dialog_confirm_spam_confirm_button);
  768.                 String cancelText = getString(R.string.dialog_confirm_spam_cancel_button);
  769.  
  770.                 fragment = ConfirmationDialogFragment.newInstance(dialogId, title, message,
  771.                         confirmText, cancelText);
  772.                 break;
  773.             }
  774.             case R.id.dialog_attachment_progress: {
  775.                 String message = getString(R.string.dialog_attachment_progress_title);
  776.                 fragment = ProgressDialogFragment.newInstance(null, message);
  777.                 break;
  778.             }
  779.             default: {
  780.                 throw new RuntimeException("Called showDialog(int) with unknown dialog id.");
  781.             }
  782.         }
  783.  
  784.         fragment.setTargetFragment(this, dialogId);
  785.         fragment.show(getFragmentManager(), getDialogTag(dialogId));
  786.     }
  787.  
  788.     private void removeDialog(int dialogId) {
  789.         FragmentManager fm = getFragmentManager();
  790.  
  791.         if (fm == null || isRemoving() || isDetached()) {
  792.             return;
  793.         }
  794.  
  795.         // Make sure the "show dialog" transaction has been processed when we call
  796.         // findFragmentByTag() below. Otherwise the fragment won't be found and the dialog will
  797.         // never be dismissed.
  798.         fm.executePendingTransactions();
  799.  
  800.         DialogFragment fragment = (DialogFragment) fm.findFragmentByTag(getDialogTag(dialogId));
  801.  
  802.         if (fragment != null) {
  803.             fragment.dismiss();
  804.         }
  805.     }
  806.  
  807.     private String getDialogTag(int dialogId) {
  808.         return String.format(Locale.US, "dialog-%d", dialogId);
  809.     }
  810.  
  811.     public void zoom(KeyEvent event) {
  812.         mMessageView.zoom(event);
  813.     }
  814.  
  815.     @Override
  816.     public void doPositiveClick(int dialogId) {
  817.         switch (dialogId) {
  818.             case R.id.dialog_confirm_delete: {
  819.                 delete();
  820.                 break;
  821.             }
  822.             case R.id.dialog_confirm_spam: {
  823.                 refileMessage(mDstFolder);
  824.                 mDstFolder = null;
  825.                 break;
  826.             }
  827.         }
  828.     }
  829.  
  830.     @Override
  831.     public void doNegativeClick(int dialogId) {
  832.         /* do nothing */
  833.     }
  834.  
  835.     @Override
  836.     public void dialogCancelled(int dialogId) {
  837.         /* do nothing */
  838.     }
  839.  
  840.     /**
  841.      * Get the {@link MessageReference} of the currently displayed message.
  842.      */
  843.     public MessageReference getMessageReference() {
  844.         return mMessageReference;
  845.     }
  846.  
  847.     public boolean isMessageRead() {
  848.         return (mMessage != null) ? mMessage.isSet(Flag.SEEN) : false;
  849.     }
  850.  
  851.     public boolean isCopyCapable() {
  852.         return mController.isCopyCapable(mAccount);
  853.     }
  854.  
  855.     public boolean isMoveCapable() {
  856.         return mController.isMoveCapable(mAccount);
  857.     }
  858.  
  859.     public boolean canMessageBeArchived() {
  860.         return (!mMessageReference.folderName.equals(mAccount.getArchiveFolderName())
  861.                 && mAccount.hasArchiveFolder());
  862.     }
  863.  
  864.     public boolean canMessageBeMovedToSpam() {
  865.         return (!mMessageReference.folderName.equals(mAccount.getSpamFolderName())
  866.                 && mAccount.hasSpamFolder());
  867.     }
  868.  
  869.     public void updateTitle() {
  870.         if (mMessage != null) {
  871.             displayMessageSubject(mMessage.getSubject());
  872.         }
  873.     }
  874.  
  875.     public interface MessageViewFragmentListener {
  876.         public void onForward(Message mMessage, PgpData mPgpData);
  877.         public void disableDeleteAction();
  878.         public void onReplyAll(Message mMessage, PgpData mPgpData);
  879.         public void onReply(Message mMessage, PgpData mPgpData);
  880.         public void displayMessageSubject(String title);
  881.         public void setProgress(boolean b);
  882.         public void showNextMessageOrReturn();
  883.         public void messageHeaderViewAvailable(MessageHeader messageHeaderView);
  884.         public void updateMenu();
  885.     }
  886.  
  887.     public boolean isInitialized() {
  888.         return mInitialized ;
  889.     }
  890.  
  891.     public LayoutInflater getFragmentLayoutInflater() {
  892.         return mLayoutInflater;
  893.     }
  894.  
  895.     @Override
  896.     public boolean onOptionsItemSelected(MenuItem item) {  
  897.         // Get item selected and deal with it
  898.         switch (item.getItemId()) {
  899.             case android.R.id.home:
  900.                 //called when the up affordance/carat in actionbar is pressed
  901.                 getActivity().onBackPressed();
  902.              
  903.                
  904.            
  905.         }
  906.         return true;
  907.     }
  908.  
  909.  
  910. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement