package com.fsck.k9.ui.messageview;
import java.util.Collections;
import java.util.Locale;
import android.app.Activity;
import android.app.DialogFragment;
import android.app.DownloadManager;
import android.app.Fragment;
import android.app.FragmentManager;
import android.content.Context;
import android.content.Intent;
import android.content.IntentSender;
import android.content.IntentSender.SendIntentException;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Parcelable;
import android.text.TextUtils;
import android.view.ContextThemeWrapper;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.inputmethod.InputMethodManager;
import android.widget.Toast;
import com.fsck.k9.Account;
import com.fsck.k9.K9;
import com.fsck.k9.Preferences;
import com.fsck.k9.R;
import com.fsck.k9.activity.ChooseFolder;
import com.fsck.k9.activity.MessageLoaderHelper;
import com.fsck.k9.activity.MessageLoaderHelper.MessageLoaderCallbacks;
import com.fsck.k9.activity.MessageReference;
import com.fsck.k9.activity.setup.OpenPgpAppSelectDialog;
import com.fsck.k9.controller.MessagingController;
import com.fsck.k9.fragment.AttachmentDownloadDialogFragment;
import com.fsck.k9.fragment.ConfirmationDialogFragment;
import com.fsck.k9.fragment.ConfirmationDialogFragment.ConfirmationDialogFragmentListener;
import com.fsck.k9.helper.FileBrowserHelper;
import com.fsck.k9.helper.FileBrowserHelper.FileBrowserFailOverCallback;
import com.fsck.k9.mail.Flag;
import com.fsck.k9.mailstore.AttachmentViewInfo;
import com.fsck.k9.mailstore.LocalMessage;
import com.fsck.k9.mailstore.MessageViewInfo;
import com.fsck.k9.ui.messageview.CryptoInfoDialog.OnClickShowCryptoKeyListener;
import com.fsck.k9.ui.messageview.MessageCryptoPresenter.MessageCryptoMvpView;
import com.fsck.k9.view.MessageCryptoDisplayStatus;
import com.fsck.k9.view.MessageHeader;
import timber.log.Timber;
public class MessageViewFragment extends Fragment implements ConfirmationDialogFragmentListener,
AttachmentViewCallback, OnClickShowCryptoKeyListener {
private static final String ARG_REFERENCE = "reference";
private static final int ACTIVITY_CHOOSE_FOLDER_MOVE = 1;
private static final int ACTIVITY_CHOOSE_FOLDER_COPY = 2;
private static final int ACTIVITY_CHOOSE_DIRECTORY = 3;
public static final int REQUEST_MASK_LOADER_HELPER = (1 << 8);
public static final int REQUEST_MASK_CRYPTO_PRESENTER = (1 << 9);
public static MessageViewFragment newInstance(MessageReference reference) {
MessageViewFragment fragment = new MessageViewFragment();
Bundle args = new Bundle();
args.putString(ARG_REFERENCE, reference.toIdentityString());
fragment.setArguments(args);
return fragment;
}
private MessageTopView mMessageView;
private Account mAccount;
private MessageReference mMessageReference;
private LocalMessage mMessage;
private MessagingController mController;
private DownloadManager downloadManager;
private Handler handler = new Handler();
private MessageLoaderHelper messageLoaderHelper;
private MessageCryptoPresenter messageCryptoPresenter;
/**
* Used to temporarily store the destination folder for refile operations if a confirmation
* dialog is shown.
*/
private String mDstFolder;
private MessageViewFragmentListener mFragmentListener;
/**
* {@code true} after {@link #onCreate(Bundle)} has been executed. This is used by
* {@code MessageList.configureMenu()} to make sure the fragment has been initialized before
* it is used.
*/
private boolean mInitialized = false;
private Context mContext;
private AttachmentViewInfo currentAttachmentViewInfo;
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
mContext = activity.getApplicationContext();
try {
mFragmentListener = (MessageViewFragmentListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.getClass() +
" must implement MessageViewFragmentListener");
}
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// This fragments adds options to the action bar
setHasOptionsMenu(true);
Context context = getActivity().getApplicationContext();
mController = MessagingController.getInstance(context);
downloadManager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);
messageCryptoPresenter = new MessageCryptoPresenter(savedInstanceState, messageCryptoMvpView);
messageLoaderHelper =
new MessageLoaderHelper(context, getLoaderManager(), getFragmentManager(), messageLoaderCallbacks);
mInitialized = true;
}
@Override
public void onResume() {
super.onResume();
messageCryptoPresenter.onResume();
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
messageCryptoPresenter.onSaveInstanceState(outState);
}
@Override
public void onDestroy() {
super.onDestroy();
Activity activity = getActivity();
boolean isChangingConfigurations = activity != null && activity.isChangingConfigurations();
if (isChangingConfigurations) {
messageLoaderHelper.onDestroyChangingConfigurations();
return;
}
messageLoaderHelper.onDestroy();
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
Context context = new ContextThemeWrapper(inflater.getContext(),
K9.getK9ThemeResourceId(K9.getK9MessageViewTheme()));
LayoutInflater layoutInflater = LayoutInflater.from(context);
View view = layoutInflater.inflate(R.layout.message, container, false);
mMessageView = (MessageTopView) view.findViewById(R.id.message_view);
mMessageView.setAttachmentCallback(this);
mMessageView.setMessageCryptoPresenter(messageCryptoPresenter);
mMessageView.setOnToggleFlagClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
onToggleFlagged();
}
});
mMessageView.setOnDownloadButtonClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
mMessageView.disableDownloadButton();
messageLoaderHelper.downloadCompleteMessage();
}
});
mFragmentListener.messageHeaderViewAvailable(mMessageView.getMessageHeaderView());
return view;
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
Bundle arguments = getArguments();
String messageReferenceString = arguments.getString(ARG_REFERENCE);
MessageReference messageReference = MessageReference.parse(messageReferenceString);
displayMessage(messageReference);
}
private void displayMessage(MessageReference messageReference) {
mMessageReference = messageReference;
Timber.d("MessageView displaying message %s", mMessageReference);
mAccount = Preferences.getPreferences(getApplicationContext()).getAccount(mMessageReference.getAccountUuid());
messageLoaderHelper.asyncStartOrResumeLoadingMessage(messageReference, null);
mFragmentListener.updateMenu();
}
private void hideKeyboard() {
Activity activity = getActivity();
if (activity == null) {
return;
}
InputMethodManager imm = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE);
View decorView = activity.getWindow().getDecorView();
if (decorView != null) {
imm.hideSoftInputFromWindow(decorView.getApplicationWindowToken(), 0);
}
}
private void showUnableToDecodeError() {
Context context = getActivity().getApplicationContext();
Toast.makeText(context, R.string.message_view_toast_unable_to_display_message, Toast.LENGTH_SHORT).show();
}
private void showMessage(MessageViewInfo messageViewInfo) {
hideKeyboard();
boolean handledByCryptoPresenter = messageCryptoPresenter.maybeHandleShowMessage(
mMessageView, mAccount, messageViewInfo);
if (!handledByCryptoPresenter) {
mMessageView.showMessage(mAccount, messageViewInfo);
if (K9.isOpenPgpProviderConfigured()) {
mMessageView.getMessageHeaderView().setCryptoStatusDisabled();
} else {
mMessageView.getMessageHeaderView().hideCryptoStatus();
}
}
}
private void displayHeaderForLoadingMessage(LocalMessage message) {
mMessageView.setHeaders(message, mAccount);
if (K9.isOpenPgpProviderConfigured()) {
mMessageView.getMessageHeaderView().setCryptoStatusLoading();
}
displayMessageSubject(getSubjectForMessage(message));
mFragmentListener.updateMenu();
}
/**
* Called from UI thread when user select Delete
*/
public void onDelete() {
if (K9.confirmDelete() || (K9.confirmDeleteStarred() && mMessage.isSet(Flag.FLAGGED))) {
showDialog(R.id.dialog_confirm_delete);
} else {
delete();
}
}
public void onToggleAllHeadersView() {
mMessageView.getMessageHeaderView().onShowAdditionalHeaders();
}
public boolean allHeadersVisible() {
return mMessageView.getMessageHeaderView().additionalHeadersVisible();
}
private void delete() {
if (mMessage != null) {
// Disable the delete button after it's tapped (to try to prevent
// accidental clicks)
mFragmentListener.disableDeleteAction();
LocalMessage messageToDelete = mMessage;
mFragmentListener.showNextMessageOrReturn();
mController.deleteMessage(mMessageReference, null);
}
}
public void onRefile(String dstFolder) {
if (!mController.isMoveCapable(mAccount)) {
return;
}
if (!mController.isMoveCapable(mMessageReference)) {
Toast toast = Toast.makeText(getActivity(), R.string.move_copy_cannot_copy_unsynced_message, Toast.LENGTH_LONG);
toast.show();
return;
}
if (K9.FOLDER_NONE.equalsIgnoreCase(dstFolder)) {
return;
}
if (mAccount.getSpamFolderName().equals(dstFolder) && K9.confirmSpam()) {
mDstFolder = dstFolder;
showDialog(R.id.dialog_confirm_spam);
} else {
refileMessage(dstFolder);
}
}
private void refileMessage(String dstFolder) {
String srcFolder = mMessageReference.getFolderName();
MessageReference messageToMove = mMessageReference;
mFragmentListener.showNextMessageOrReturn();
mController.moveMessage(mAccount, srcFolder, messageToMove, dstFolder);
}
public void onReply() {
if (mMessage != null) {
mFragmentListener.onReply(mMessage.makeMessageReference(), messageCryptoPresenter.getDecryptionResultForReply());
}
}
public void onReplyAll() {
if (mMessage != null) {
mFragmentListener.onReplyAll(mMessage.makeMessageReference(), messageCryptoPresenter.getDecryptionResultForReply());
}
}
public void onForward() {
if (mMessage != null) {
mFragmentListener.onForward(mMessage.makeMessageReference(), messageCryptoPresenter.getDecryptionResultForReply());
}
}
public void onToggleFlagged() {
if (mMessage != null) {
boolean newState = !mMessage.isSet(Flag.FLAGGED);
mController.setFlag(mAccount, mMessage.getFolder().getName(),
Collections.singletonList(mMessage), Flag.FLAGGED, newState);
mMessageView.setHeaders(mMessage, mAccount);
}
}
public void onMove() {
if ((!mController.isMoveCapable(mAccount))
|| (mMessage == null)) {
return;
}
if (!mController.isMoveCapable(mMessageReference)) {
Toast toast = Toast.makeText(getActivity(), R.string.move_copy_cannot_copy_unsynced_message, Toast.LENGTH_LONG);
toast.show();
return;
}
startRefileActivity(ACTIVITY_CHOOSE_FOLDER_MOVE);
}
public void onCopy() {
if ((!mController.isCopyCapable(mAccount))
|| (mMessage == null)) {
return;
}
if (!mController.isCopyCapable(mMessageReference)) {
Toast toast = Toast.makeText(getActivity(), R.string.move_copy_cannot_copy_unsynced_message, Toast.LENGTH_LONG);
toast.show();
return;
}
startRefileActivity(ACTIVITY_CHOOSE_FOLDER_COPY);
}
public void onArchive() {
onRefile(mAccount.getArchiveFolderName());
}
public void onSpam() {
onRefile(mAccount.getSpamFolderName());
}
public void onSelectText() {
// FIXME
// mMessageView.beginSelectingText();
}
private void startRefileActivity(int activity) {
Intent intent = new Intent(getActivity(), ChooseFolder.class);
intent.putExtra(ChooseFolder.EXTRA_ACCOUNT, mAccount.getUuid());
intent.putExtra(ChooseFolder.EXTRA_CUR_FOLDER, mMessageReference.getFolderName());
intent.putExtra(ChooseFolder.EXTRA_SEL_FOLDER, mAccount.getLastSelectedFolderName());
intent.putExtra(ChooseFolder.EXTRA_MESSAGE, mMessageReference.toIdentityString());
startActivityForResult(intent, activity);
}
private void startOpenPgpChooserActivity() {
Intent i = new Intent(getActivity(), OpenPgpAppSelectDialog.class);
startActivity(i);
}
public void onPendingIntentResult(int requestCode, int resultCode, Intent data) {
if ((requestCode & REQUEST_MASK_LOADER_HELPER) == REQUEST_MASK_LOADER_HELPER) {
requestCode ^= REQUEST_MASK_LOADER_HELPER;
messageLoaderHelper.onActivityResult(requestCode, resultCode, data);
return;
}
if ((requestCode & REQUEST_MASK_CRYPTO_PRESENTER) == REQUEST_MASK_CRYPTO_PRESENTER) {
requestCode ^= REQUEST_MASK_CRYPTO_PRESENTER;
messageCryptoPresenter.onActivityResult(requestCode, resultCode, data);
}
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode != Activity.RESULT_OK) {
return;
}
// Note: because fragments do not have a startIntentSenderForResult method, pending intent activities are
// launched through the MessageList activity, and delivered back via onPendingIntentResult()
switch (requestCode) {
case ACTIVITY_CHOOSE_DIRECTORY: {
if (data != null) {
// obtain the filename
Uri fileUri = data.getData();
if (fileUri != null) {
String filePath = fileUri.getPath();
if (filePath != null) {
getAttachmentController(currentAttachmentViewInfo).saveAttachmentTo(filePath);
}
}
}
break;
}
case ACTIVITY_CHOOSE_FOLDER_MOVE:
case ACTIVITY_CHOOSE_FOLDER_COPY: {
if (data == null) {
return;
}
String destFolderName = data.getStringExtra(ChooseFolder.EXTRA_NEW_FOLDER);
String messageReferenceString = data.getStringExtra(ChooseFolder.EXTRA_MESSAGE);
MessageReference ref = MessageReference.parse(messageReferenceString);
if (mMessageReference.equals(ref)) {
mAccount.setLastSelectedFolderName(destFolderName);
switch (requestCode) {
case ACTIVITY_CHOOSE_FOLDER_MOVE: {
mFragmentListener.showNextMessageOrReturn();
moveMessage(ref, destFolderName);
break;
}
case ACTIVITY_CHOOSE_FOLDER_COPY: {
copyMessage(ref, destFolderName);
break;
}
}
}
break;
}
}
}
public void onSendAlternate() {
if (mMessage != null) {
mController.sendAlternate(getActivity(), mAccount, mMessage);
}
}
public void onToggleRead() {
if (mMessage != null) {
mController.setFlag(mAccount, mMessage.getFolder().getName(),
Collections.singletonList(mMessage), Flag.SEEN, !mMessage.isSet(Flag.SEEN));
mMessageView.setHeaders(mMessage, mAccount);
String subject = mMessage.getSubject();
displayMessageSubject(subject);
mFragmentListener.updateMenu();
}
}
private void setProgress(boolean enable) {
if (mFragmentListener != null) {
mFragmentListener.setProgress(enable);
}
}
private void displayMessageSubject(String subject) {
if (mFragmentListener != null) {
mFragmentListener.displayMessageSubject(subject);
}
}
private String getSubjectForMessage(LocalMessage message) {
String subject = message.getSubject();
if (TextUtils.isEmpty(subject)) {
return mContext.getString(R.string.general_no_subject);
}
return subject;
}
public void moveMessage(MessageReference reference, String destFolderName) {
mController.moveMessage(mAccount, mMessageReference.getFolderName(), reference, destFolderName);
}
public void copyMessage(MessageReference reference, String destFolderName) {
mController.copyMessage(mAccount, mMessageReference.getFolderName(), reference, destFolderName);
}
private void showDialog(int dialogId) {
DialogFragment fragment;
switch (dialogId) {
case R.id.dialog_confirm_delete: {
String title = getString(R.string.dialog_confirm_delete_title);
String message = getString(R.string.dialog_confirm_delete_message);
String confirmText = getString(R.string.dialog_confirm_delete_confirm_button);
String cancelText = getString(R.string.dialog_confirm_delete_cancel_button);
fragment = ConfirmationDialogFragment.newInstance(dialogId, title, message,
confirmText, cancelText);
break;
}
case R.id.dialog_confirm_spam: {
String title = getString(R.string.dialog_confirm_spam_title);
String message = getResources().getQuantityString(R.plurals.dialog_confirm_spam_message, 1);
String confirmText = getString(R.string.dialog_confirm_spam_confirm_button);
String cancelText = getString(R.string.dialog_confirm_spam_cancel_button);
fragment = ConfirmationDialogFragment.newInstance(dialogId, title, message,
confirmText, cancelText);
break;
}
case R.id.dialog_attachment_progress: {
String message = getString(R.string.dialog_attachment_progress_title);
int size = (int) currentAttachmentViewInfo.size;
fragment = AttachmentDownloadDialogFragment.newInstance(size, message);
break;
}
default: {
throw new RuntimeException("Called showDialog(int) with unknown dialog id.");
}
}
fragment.setTargetFragment(this, dialogId);
fragment.show(getFragmentManager(), getDialogTag(dialogId));
}
private void removeDialog(int dialogId) {
FragmentManager fm = getFragmentManager();
if (fm == null || isRemoving() || isDetached()) {
return;
}
// Make sure the "show dialog" transaction has been processed when we call
// findFragmentByTag() below. Otherwise the fragment won't be found and the dialog will
// never be dismissed.
fm.executePendingTransactions();
DialogFragment fragment = (DialogFragment) fm.findFragmentByTag(getDialogTag(dialogId));
if (fragment != null) {
fragment.dismiss();
}
}
private String getDialogTag(int dialogId) {
return String.format(Locale.US, "dialog-%d", dialogId);
}
public void zoom(KeyEvent event) {
// mMessageView.zoom(event);
}
@Override
public void doPositiveClick(int dialogId) {
switch (dialogId) {
case R.id.dialog_confirm_delete: {
delete();
break;
}
case R.id.dialog_confirm_spam: {
refileMessage(mDstFolder);
mDstFolder = null;
break;
}
}
}
@Override
public void doNegativeClick(int dialogId) {
/* do nothing */
}
@Override
public void dialogCancelled(int dialogId) {
/* do nothing */
}
/**
* Get the {@link MessageReference} of the currently displayed message.
*/
public MessageReference getMessageReference() {
return mMessageReference;
}
public boolean isMessageRead() {
return (mMessage != null) ? mMessage.isSet(Flag.SEEN) : false;
}
public boolean isCopyCapable() {
return mController.isCopyCapable(mAccount);
}
public boolean isMoveCapable() {
return mController.isMoveCapable(mAccount);
}
public boolean canMessageBeArchived() {
return (!mMessageReference.getFolderName().equals(mAccount.getArchiveFolderName())
&& mAccount.hasArchiveFolder());
}
public boolean canMessageBeMovedToSpam() {
return (!mMessageReference.getFolderName().equals(mAccount.getSpamFolderName())
&& mAccount.hasSpamFolder());
}
public void updateTitle() {
if (mMessage != null) {
displayMessageSubject(mMessage.getSubject());
}
}
public Context getApplicationContext() {
return mContext;
}
public void disableAttachmentButtons(AttachmentViewInfo attachment) {
// mMessageView.disableAttachmentButtons(attachment);
}
public void enableAttachmentButtons(AttachmentViewInfo attachment) {
// mMessageView.enableAttachmentButtons(attachment);
}
public void runOnMainThread(Runnable runnable) {
handler.post(runnable);
}
public void showAttachmentLoadingDialog() {
// mMessageView.disableAttachmentButtons();
showDialog(R.id.dialog_attachment_progress);
}
public void hideAttachmentLoadingDialogOnMainThread() {
handler.post(new Runnable() {
@Override
public void run() {
removeDialog(R.id.dialog_attachment_progress);
// mMessageView.enableAttachmentButtons();
}
});
}
public void refreshAttachmentThumbnail(AttachmentViewInfo attachment) {
// mMessageView.refreshAttachmentThumbnail(attachment);
}
private MessageCryptoMvpView messageCryptoMvpView = new MessageCryptoMvpView() {
@Override
public void redisplayMessage() {
messageLoaderHelper.asyncReloadMessage();
}
@Override
public void startPendingIntentForCryptoPresenter(IntentSender si, Integer requestCode, Intent fillIntent,
int flagsMask, int flagValues, int extraFlags) throws SendIntentException {
if (requestCode == null) {
getActivity().startIntentSender(si, fillIntent, flagsMask, flagValues, extraFlags);
return;
}
requestCode |= REQUEST_MASK_CRYPTO_PRESENTER;
getActivity().startIntentSenderForResult(
si, requestCode, fillIntent, flagsMask, flagValues, extraFlags);
}
@Override
public void showCryptoInfoDialog(MessageCryptoDisplayStatus displayStatus, boolean hasSecurityWarning) {
CryptoInfoDialog dialog = CryptoInfoDialog.newInstance(displayStatus, hasSecurityWarning);
dialog.setTargetFragment(MessageViewFragment.this, 0);
dialog.show(getFragmentManager(), "crypto_info_dialog");
}
@Override
public void restartMessageCryptoProcessing() {
mMessageView.setToLoadingState();
messageLoaderHelper.asyncRestartMessageCryptoProcessing();
}
@Override
public void showCryptoConfigDialog() {
startOpenPgpChooserActivity();
}
};
@Override
public void onClickShowSecurityWarning() {
messageCryptoPresenter.onClickShowCryptoWarningDetails();
}
@Override
public void onClickShowCryptoKey() {
messageCryptoPresenter.onClickShowCryptoKey();
}
public interface MessageViewFragmentListener {
void onForward(MessageReference messageReference, Parcelable decryptionResultForReply);
void disableDeleteAction();
void onReplyAll(MessageReference messageReference, Parcelable decryptionResultForReply);
void onReply(MessageReference messageReference, Parcelable decryptionResultForReply);
void displayMessageSubject(String title);
void setProgress(boolean b);
void showNextMessageOrReturn();
void messageHeaderViewAvailable(MessageHeader messageHeaderView);
void updateMenu();
}
public boolean isInitialized() {
return mInitialized ;
}
private MessageLoaderCallbacks messageLoaderCallbacks = new MessageLoaderCallbacks() {
@Override
public void onMessageDataLoadFinished(LocalMessage message) {
mMessage = message;
displayHeaderForLoadingMessage(message);
mMessageView.setToLoadingState();
}
@Override
public void onMessageDataLoadFailed() {
Toast.makeText(getActivity(), R.string.status_loading_error, Toast.LENGTH_LONG).show();
}
@Override
public void onMessageViewInfoLoadFinished(MessageViewInfo messageViewInfo) {
showMessage(messageViewInfo);
}
@Override
public void onMessageViewInfoLoadFailed(MessageViewInfo messageViewInfo) {
showMessage(messageViewInfo);
}
@Override
public void setLoadingProgress(int current, int max) {
mMessageView.setLoadingProgress(current, max);
}
@Override
public void onDownloadErrorMessageNotFound() {
mMessageView.enableDownloadButton();
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(getActivity(), R.string.status_invalid_id_error, Toast.LENGTH_LONG).show();
}
});
}
@Override
public void onDownloadErrorNetworkError() {
mMessageView.enableDownloadButton();
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(getActivity(), R.string.status_network_error, Toast.LENGTH_LONG).show();
}
});
}
@Override
public void startIntentSenderForMessageLoaderHelper(IntentSender si, int requestCode, Intent fillIntent,
int flagsMask, int flagValues, int extraFlags) {
try {
requestCode |= REQUEST_MASK_LOADER_HELPER;
getActivity().startIntentSenderForResult(
si, requestCode, fillIntent, flagsMask, flagValues, extraFlags);
} catch (SendIntentException e) {
Timber.e(e, "Irrecoverable error calling PendingIntent!");
}
}
};
@Override
public void onViewAttachment(AttachmentViewInfo attachment) {
currentAttachmentViewInfo = attachment;
getAttachmentController(attachment).viewAttachment();
}
@Override
public void onSaveAttachment(AttachmentViewInfo attachment) {
currentAttachmentViewInfo = attachment;
getAttachmentController(attachment).saveAttachment();
}
@Override
public void onSaveAttachmentToUserProvidedDirectory(final AttachmentViewInfo attachment) {
currentAttachmentViewInfo = attachment;
FileBrowserHelper.getInstance().showFileBrowserActivity(MessageViewFragment.this, null,
ACTIVITY_CHOOSE_DIRECTORY, new FileBrowserFailOverCallback() {
@Override
public void onPathEntered(String path) {
getAttachmentController(attachment).saveAttachmentTo(path);
}
@Override
public void onCancel() {
// Do nothing
}
});
}
private AttachmentController getAttachmentController(AttachmentViewInfo attachment) {
return new AttachmentController(mController, downloadManager, this, attachment);
}
}