diff --git a/src/com/fsck/k9/activity/MessageView.java b/src/com/fsck/k9/activity/MessageView.java index 91e9c7f4a..da64d2acf 100644 --- a/src/com/fsck/k9/activity/MessageView.java +++ b/src/com/fsck/k9/activity/MessageView.java @@ -17,12 +17,16 @@ import com.fsck.k9.*; import com.fsck.k9.controller.MessagingController; import com.fsck.k9.controller.MessagingListener; import com.fsck.k9.crypto.PgpData; +import com.fsck.k9.helper.FileBrowserHelper; +import com.fsck.k9.helper.FileBrowserHelper.FileBrowserFailOverCallback; import com.fsck.k9.mail.*; import com.fsck.k9.mail.store.StorageManager; import com.fsck.k9.view.AttachmentView; import com.fsck.k9.view.ToggleScrollView; import com.fsck.k9.view.SingleMessageView; +import com.fsck.k9.view.AttachmentView.AttachmentFileDownloadCallback; +import java.io.File; import java.util.*; public class MessageView extends K9Activity implements OnClickListener { @@ -33,7 +37,7 @@ public class MessageView extends K9Activity implements OnClickListener { private static final String STATE_PGP_DATA = "pgpData"; 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; private SingleMessageView mMessageView; @@ -61,6 +65,12 @@ public class MessageView extends K9Activity implements OnClickListener { private MessageViewHandler mHandler = new MessageViewHandler(); private StorageManager.StorageListener mStorageListener = new StorageListenerImplementation(); + /** this variable is used to save the calling AttachmentView + * until the onActivityResult is called. + * => with this reference we can identity the caller + */ + private AttachmentView attachmentTmpStore; + /** * Used to temporarily store the destination folder for refile operations if a confirmation * dialog is shown. @@ -295,6 +305,32 @@ public class MessageView extends K9Activity implements OnClickListener { mTopView = mToggleScrollView = (ToggleScrollView) findViewById(R.id.top_view); mMessageView = (SingleMessageView) findViewById(R.id.message_view); + //set a callback for the attachment view. With this callback the attachmentview + //request the start of a filebrowser activity. + mMessageView.setAttachmentCallback(new AttachmentFileDownloadCallback() { + + @Override + public void showFileBrowser(final AttachmentView caller) { + FileBrowserHelper.getInstance() + .showFileBrowserActivity(MessageView.this, + null, + MessageView.ACTIVITY_CHOOSE_DIRECTORY, + callback); + attachmentTmpStore = caller; + } + FileBrowserFailOverCallback callback = new FileBrowserFailOverCallback() { + + @Override + public void onPathEntered(String path) { + attachmentTmpStore.writeFile(new File(path)); + } + + @Override + public void onCancel() { + // canceled, do nothing + } + }; + }); mMessageView.initialize(this); setTitle(""); @@ -712,6 +748,19 @@ public class MessageView extends K9Activity implements OnClickListener { if (resultCode != RESULT_OK) return; switch (requestCode) { + case ACTIVITY_CHOOSE_DIRECTORY: + if (resultCode == RESULT_OK && data != null) { + // obtain the filename + Uri fileUri = data.getData(); + if (fileUri != null) { + String filePath = fileUri.getPath(); + if (filePath != null) { + attachmentTmpStore.writeFile(new File(filePath)); + } + } + } + + break; case ACTIVITY_CHOOSE_FOLDER_MOVE: case ACTIVITY_CHOOSE_FOLDER_COPY: if (data == null) diff --git a/src/com/fsck/k9/view/AttachmentView.java b/src/com/fsck/k9/view/AttachmentView.java index 0ebfa228e..cf24aa322 100644 --- a/src/com/fsck/k9/view/AttachmentView.java +++ b/src/com/fsck/k9/view/AttachmentView.java @@ -53,6 +53,8 @@ public class AttachmentView extends FrameLayout { public long size; public ImageView iconView; + private AttachmentFileDownloadCallback callback; + public AttachmentView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); mContext = context; @@ -67,7 +69,18 @@ public class AttachmentView extends FrameLayout { } - + public interface AttachmentFileDownloadCallback { + /** + * this method i called by the attachmentview when + * he wants to show a filebrowser + * the provider should show the filebrowser activity + * and save the reference to the attachment view for later. + * in his onActivityResult he can get the saved reference and + * call the saveFile method of AttachmentView + * @param view + */ + public void showFileBrowser(AttachmentView caller); + } public boolean populateFromPart(Part inputPart, Message message, Account account, MessagingController controller, MessagingListener listener) { try { part = (LocalAttachmentBodyPart) inputPart; @@ -124,6 +137,14 @@ public class AttachmentView extends FrameLayout { return; } }); + downloadButton.setOnLongClickListener(new OnLongClickListener() { + + @Override + public boolean onLongClick(View v) { + callback.showFileBrowser(AttachmentView.this); + return true; + } + }); attachmentName.setText(name); attachmentInfo.setText(SizeFormatter.formatSize(mContext, size)); @@ -169,9 +190,13 @@ public class AttachmentView extends FrameLayout { saveFile(); } - public void writeFile() { + /** + * Writes the attachment onto the given path + * @param directory: the base dir where the file should be saved. + */ + public void writeFile(File directory) { try { - File file = Utility.createUniqueFile(Environment.getExternalStorageDirectory(), name); + File file = Utility.createUniqueFile(directory, name); Uri uri = AttachmentProvider.getAttachmentUri(mAccount, part.getAttachmentId()); InputStream in = mContext.getContentResolver().openInputStream(uri); OutputStream out = new FileOutputStream(file); @@ -179,14 +204,22 @@ public class AttachmentView extends FrameLayout { out.flush(); out.close(); in.close(); - attachmentSaved(file.getName()); + attachmentSaved(file.toString()); new MediaScannerNotifier(mContext, file); } catch (IOException ioe) { attachmentNotSaved(); } } + /** + * saves the file to the defaultpath setting in the config, or if the config + * is not set => to the Environment + */ + public void writeFile() { + writeFile(new File(K9.getAttachmentDefaultPath())); + } public void saveFile() { + //TODO: Can the user save attachments on the internal filesystem or sd card only? if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { /* * Abort early if there's no place to save the attachment. We don't want to spend @@ -259,4 +292,11 @@ public class AttachmentView extends FrameLayout { mContext.getString(R.string.message_view_status_attachment_not_saved), Toast.LENGTH_LONG).show(); } + public AttachmentFileDownloadCallback getCallback() { + return callback; + } + public void setCallback(AttachmentFileDownloadCallback callback) { + this.callback = callback; + } + } diff --git a/src/com/fsck/k9/view/SingleMessageView.java b/src/com/fsck/k9/view/SingleMessageView.java index 3f0ceb146..5b84fc57f 100644 --- a/src/com/fsck/k9/view/SingleMessageView.java +++ b/src/com/fsck/k9/view/SingleMessageView.java @@ -44,7 +44,7 @@ public class SingleMessageView extends LinearLayout { private Button mDownloadRemainder; private LayoutInflater mInflater; private Contacts mContacts; - + private AttachmentView.AttachmentFileDownloadCallback attachmentCallback; public void initialize(Activity activity) { mMessageContentView = (MessageWebView) findViewById(R.id.message_content); @@ -265,6 +265,7 @@ public class SingleMessageView extends LinearLayout { return; } AttachmentView view = (AttachmentView)mInflater.inflate(R.layout.message_view_attachment, null); + view.setCallback(attachmentCallback); if (view.populateFromPart(part, message, account, controller, listener)) { addAttachment(view); } @@ -299,4 +300,14 @@ public class SingleMessageView extends LinearLayout { mMessageContentView.clearView(); mAttachments.removeAllViews(); } + + public AttachmentView.AttachmentFileDownloadCallback getAttachmentCallback() { + return attachmentCallback; + } + + public void setAttachmentCallback( + AttachmentView.AttachmentFileDownloadCallback attachmentCallback) { + this.attachmentCallback = attachmentCallback; + } + }