Loading res/values/strings.xml +3 −0 Original line number Diff line number Diff line Loading @@ -1149,4 +1149,7 @@ Please submit bug reports, contribute new features and ask questions at <string name="mark_all_as_read">Mark all as read</string> <string name="loading_attachment">Loading attachment…</string> <string name="fetching_attachment_dialog_title_send">Sending message</string> <string name="fetching_attachment_dialog_title_save">Saving draft</string> <string name="fetching_attachment_dialog_message">Fetching attachment…</string> </resources> src/com/fsck/k9/activity/MessageCompose.java +145 −2 Original line number Diff line number Diff line Loading @@ -61,6 +61,7 @@ import com.fsck.k9.controller.MessagingController; import com.fsck.k9.controller.MessagingListener; import com.fsck.k9.crypto.CryptoProvider; import com.fsck.k9.crypto.PgpData; import com.fsck.k9.fragment.ProgressDialogFragment; import com.fsck.k9.helper.ContactItem; import com.fsck.k9.helper.Contacts; import com.fsck.k9.helper.HtmlConverter; Loading Loading @@ -94,7 +95,6 @@ import java.util.Collections; import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Locale; import java.util.Map; Loading @@ -103,7 +103,9 @@ import java.util.StringTokenizer; import java.util.regex.Matcher; import java.util.regex.Pattern; public class MessageCompose extends K9Activity implements OnClickListener { public class MessageCompose extends K9Activity implements OnClickListener, ProgressDialogFragment.CancelListener { private static final int DIALOG_SAVE_OR_DISCARD_DRAFT_MESSAGE = 1; private static final int DIALOG_REFUSE_TO_SAVE_DRAFT_MARKED_ENCRYPTED = 2; private static final int DIALOG_CONTINUE_WITHOUT_PUBLIC_KEY = 3; Loading Loading @@ -147,14 +149,19 @@ public class MessageCompose extends K9Activity implements OnClickListener { "com.fsck.k9.activity.MessageCompose.forcePlainText"; private static final String STATE_KEY_QUOTED_TEXT_FORMAT = "com.fsck.k9.activity.MessageCompose.quotedTextFormat"; private static final String STATE_KEY_NUM_ATTACHMENTS_LOADING = "numAttachmentsLoading"; private static final String STATE_KEY_WAITING_FOR_ATTACHMENTS = "waitingForAttachments"; private static final String LOADER_ARG_ATTACHMENT = "attachment"; private static final String FRAGMENT_WAITING_FOR_ATTACHMENT = "waitingForAttachment"; private static final int MSG_PROGRESS_ON = 1; private static final int MSG_PROGRESS_OFF = 2; private static final int MSG_SKIPPED_ATTACHMENTS = 3; private static final int MSG_SAVED_DRAFT = 4; private static final int MSG_DISCARDED_DRAFT = 5; private static final int MSG_PERFORM_STALLED_ACTION = 6; private static final int ACTIVITY_REQUEST_PICK_ATTACHMENT = 1; private static final int CONTACT_PICKER_TO = 4; Loading Loading @@ -326,6 +333,23 @@ public class MessageCompose extends K9Activity implements OnClickListener { */ private long mDraftId = INVALID_DRAFT_ID; /** * Number of attachments currently being fetched. */ private int mNumAttachmentsLoading = 0; private enum WaitingAction { NONE, SEND, SAVE } /** * Specifies what action to perform once attachments have been fetched. */ private WaitingAction mWaitingForAttachments = WaitingAction.NONE; private Handler mHandler = new Handler() { @Override public void handleMessage(android.os.Message msg) { Loading Loading @@ -354,6 +378,9 @@ public class MessageCompose extends K9Activity implements OnClickListener { getString(R.string.message_discarded_toast), Toast.LENGTH_LONG).show(); break; case MSG_PERFORM_STALLED_ACTION: performStalledAction(); break; default: super.handleMessage(msg); break; Loading Loading @@ -1080,6 +1107,8 @@ public class MessageCompose extends K9Activity implements OnClickListener { attachments.add(attachment); } outState.putInt(STATE_KEY_NUM_ATTACHMENTS_LOADING, mNumAttachmentsLoading); outState.putString(STATE_KEY_WAITING_FOR_ATTACHMENTS, mWaitingForAttachments.name()); outState.putParcelableArrayList(STATE_KEY_ATTACHMENTS, attachments); outState.putBoolean(STATE_KEY_CC_SHOWN, mCcWrapper.getVisibility() == View.VISIBLE); outState.putBoolean(STATE_KEY_BCC_SHOWN, mBccWrapper.getVisibility() == View.VISIBLE); Loading @@ -1105,6 +1134,16 @@ public class MessageCompose extends K9Activity implements OnClickListener { mAttachments.removeAllViews(); mMaxLoaderId = 0; mNumAttachmentsLoading = savedInstanceState.getInt(STATE_KEY_NUM_ATTACHMENTS_LOADING); mWaitingForAttachments = WaitingAction.NONE; try { String waitingFor = savedInstanceState.getString(STATE_KEY_WAITING_FOR_ATTACHMENTS); mWaitingForAttachments = WaitingAction.valueOf(waitingFor); } catch (Exception e) { Log.w(K9.LOG_TAG, "Couldn't read value \" + STATE_KEY_WAITING_FOR_ATTACHMENTS +" + "\" from saved instance state", e); } ArrayList<Attachment> attachments = savedInstanceState.getParcelableArrayList(STATE_KEY_ATTACHMENTS); for (Attachment attachment : attachments) { addAttachmentView(attachment); Loading Loading @@ -1784,6 +1823,20 @@ public class MessageCompose extends K9Activity implements OnClickListener { Toast.makeText(this, getString(R.string.message_compose_error_no_recipients), Toast.LENGTH_LONG).show(); return; } if (mWaitingForAttachments != WaitingAction.NONE) { return; } if (mNumAttachmentsLoading > 0) { mWaitingForAttachments = WaitingAction.SEND; showWaitingForAttachmentDialog(); } else { performSend(); } } private void performSend() { final CryptoProvider crypto = mAccount.getCryptoProvider(); if (mEncryptCheckbox.isChecked() && !mPgpData.hasEncryptionKeys()) { // key selection before encryption Loading Loading @@ -1847,6 +1900,19 @@ public class MessageCompose extends K9Activity implements OnClickListener { } private void onSave() { if (mWaitingForAttachments != WaitingAction.NONE) { return; } if (mNumAttachmentsLoading > 0) { mWaitingForAttachments = WaitingAction.SAVE; showWaitingForAttachmentDialog(); } else { performSend(); } } private void performSave() { saveIfNeeded(); finish(); } Loading Loading @@ -1987,6 +2053,7 @@ public class MessageCompose extends K9Activity implements OnClickListener { new LoaderManager.LoaderCallbacks<Attachment>() { @Override public Loader<Attachment> onCreateLoader(int id, Bundle args) { onFetchAttachmentStarted(); Attachment attachment = args.getParcelable(LOADER_ARG_ATTACHMENT); return new AttachmentInfoLoader(MessageCompose.this, attachment); } Loading @@ -2004,6 +2071,8 @@ public class MessageCompose extends K9Activity implements OnClickListener { attachment.loaderId = ++mMaxLoaderId; initAttachmentContentLoader(attachment); } else { onFetchAttachmentFinished(); } getSupportLoaderManager().destroyLoader(loaderId); Loading @@ -2011,6 +2080,7 @@ public class MessageCompose extends K9Activity implements OnClickListener { @Override public void onLoaderReset(Loader<Attachment> loader) { onFetchAttachmentFinished(); } }; Loading Loading @@ -2038,14 +2108,48 @@ public class MessageCompose extends K9Activity implements OnClickListener { } } onFetchAttachmentFinished(); getSupportLoaderManager().destroyLoader(loaderId); } @Override public void onLoaderReset(Loader<Attachment> loader) { onFetchAttachmentFinished(); } }; private void onFetchAttachmentStarted() { mNumAttachmentsLoading += 1; } private void onFetchAttachmentFinished() { // We're not allowed to perform fragment transactions when called from onLoadFinished(). // So we use the Handler to call performStalledAction(). mHandler.sendEmptyMessage(MSG_PERFORM_STALLED_ACTION); } private void performStalledAction() { mNumAttachmentsLoading -= 1; WaitingAction waitingFor = mWaitingForAttachments; mWaitingForAttachments = WaitingAction.NONE; if (waitingFor != WaitingAction.NONE) { dismissWaitingForAttachmentDialog(); } switch (waitingFor) { case SEND: { performSend(); break; } case SAVE: { performSave(); break; } } } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { Loading Loading @@ -2380,6 +2484,45 @@ public class MessageCompose extends K9Activity implements OnClickListener { } } private void showWaitingForAttachmentDialog() { String title; switch (mWaitingForAttachments) { case SEND: { title = getString(R.string.fetching_attachment_dialog_title_send); break; } case SAVE: { title = getString(R.string.fetching_attachment_dialog_title_save); break; } default: { return; } } ProgressDialogFragment fragment = ProgressDialogFragment.newInstance(title, getString(R.string.fetching_attachment_dialog_message)); fragment.show(getSupportFragmentManager(), FRAGMENT_WAITING_FOR_ATTACHMENT); } public void onCancel(ProgressDialogFragment fragment) { attachmentProgressDialogCancelled(); } void attachmentProgressDialogCancelled() { mWaitingForAttachments = WaitingAction.NONE; } private void dismissWaitingForAttachmentDialog() { ProgressDialogFragment fragment = (ProgressDialogFragment) getSupportFragmentManager().findFragmentByTag(FRAGMENT_WAITING_FOR_ATTACHMENT); if (fragment != null) { fragment.dismiss(); } } @Override public Dialog onCreateDialog(int id) { switch (id) { Loading src/com/fsck/k9/fragment/MessageViewFragment.java +2 −2 Original line number Diff line number Diff line Loading @@ -752,8 +752,8 @@ public class MessageViewFragment extends SherlockFragment implements OnClickList break; } case R.id.dialog_attachment_progress: { String title = getString(R.string.dialog_attachment_progress_title); fragment = ProgressDialogFragment.newInstance(title); String message = getString(R.string.dialog_attachment_progress_title); fragment = ProgressDialogFragment.newInstance(null, message); break; } default: { Loading src/com/fsck/k9/fragment/ProgressDialogFragment.java +22 −2 Original line number Diff line number Diff line Loading @@ -2,19 +2,22 @@ package com.fsck.k9.fragment; import android.app.Dialog; import android.app.ProgressDialog; import android.content.DialogInterface; import android.os.Bundle; import com.actionbarsherlock.app.SherlockDialogFragment; public class ProgressDialogFragment extends SherlockDialogFragment { private static final String ARG_TITLE = "title"; protected static final String ARG_TITLE = "title"; protected static final String ARG_MESSAGE = "message"; public static ProgressDialogFragment newInstance(String title) { public static ProgressDialogFragment newInstance(String title, String message) { ProgressDialogFragment fragment = new ProgressDialogFragment(); Bundle args = new Bundle(); args.putString(ARG_TITLE, title); args.putString(ARG_MESSAGE, message); fragment.setArguments(args); return fragment; Loading @@ -25,11 +28,28 @@ public class ProgressDialogFragment extends SherlockDialogFragment { public Dialog onCreateDialog(Bundle savedInstanceState) { Bundle args = getArguments(); String title = args.getString(ARG_TITLE); String message = args.getString(ARG_MESSAGE); ProgressDialog dialog = new ProgressDialog(getActivity()); dialog.setIndeterminate(true); dialog.setTitle(title); dialog.setMessage(message); return dialog; } @Override public void onCancel(DialogInterface dialog) { CancelListener listener = (CancelListener) getActivity(); if (listener != null && listener instanceof CancelListener) { listener.onCancel(this); } super.onCancel(dialog); } public interface CancelListener { void onCancel(ProgressDialogFragment fragment); } } Loading
res/values/strings.xml +3 −0 Original line number Diff line number Diff line Loading @@ -1149,4 +1149,7 @@ Please submit bug reports, contribute new features and ask questions at <string name="mark_all_as_read">Mark all as read</string> <string name="loading_attachment">Loading attachment…</string> <string name="fetching_attachment_dialog_title_send">Sending message</string> <string name="fetching_attachment_dialog_title_save">Saving draft</string> <string name="fetching_attachment_dialog_message">Fetching attachment…</string> </resources>
src/com/fsck/k9/activity/MessageCompose.java +145 −2 Original line number Diff line number Diff line Loading @@ -61,6 +61,7 @@ import com.fsck.k9.controller.MessagingController; import com.fsck.k9.controller.MessagingListener; import com.fsck.k9.crypto.CryptoProvider; import com.fsck.k9.crypto.PgpData; import com.fsck.k9.fragment.ProgressDialogFragment; import com.fsck.k9.helper.ContactItem; import com.fsck.k9.helper.Contacts; import com.fsck.k9.helper.HtmlConverter; Loading Loading @@ -94,7 +95,6 @@ import java.util.Collections; import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Locale; import java.util.Map; Loading @@ -103,7 +103,9 @@ import java.util.StringTokenizer; import java.util.regex.Matcher; import java.util.regex.Pattern; public class MessageCompose extends K9Activity implements OnClickListener { public class MessageCompose extends K9Activity implements OnClickListener, ProgressDialogFragment.CancelListener { private static final int DIALOG_SAVE_OR_DISCARD_DRAFT_MESSAGE = 1; private static final int DIALOG_REFUSE_TO_SAVE_DRAFT_MARKED_ENCRYPTED = 2; private static final int DIALOG_CONTINUE_WITHOUT_PUBLIC_KEY = 3; Loading Loading @@ -147,14 +149,19 @@ public class MessageCompose extends K9Activity implements OnClickListener { "com.fsck.k9.activity.MessageCompose.forcePlainText"; private static final String STATE_KEY_QUOTED_TEXT_FORMAT = "com.fsck.k9.activity.MessageCompose.quotedTextFormat"; private static final String STATE_KEY_NUM_ATTACHMENTS_LOADING = "numAttachmentsLoading"; private static final String STATE_KEY_WAITING_FOR_ATTACHMENTS = "waitingForAttachments"; private static final String LOADER_ARG_ATTACHMENT = "attachment"; private static final String FRAGMENT_WAITING_FOR_ATTACHMENT = "waitingForAttachment"; private static final int MSG_PROGRESS_ON = 1; private static final int MSG_PROGRESS_OFF = 2; private static final int MSG_SKIPPED_ATTACHMENTS = 3; private static final int MSG_SAVED_DRAFT = 4; private static final int MSG_DISCARDED_DRAFT = 5; private static final int MSG_PERFORM_STALLED_ACTION = 6; private static final int ACTIVITY_REQUEST_PICK_ATTACHMENT = 1; private static final int CONTACT_PICKER_TO = 4; Loading Loading @@ -326,6 +333,23 @@ public class MessageCompose extends K9Activity implements OnClickListener { */ private long mDraftId = INVALID_DRAFT_ID; /** * Number of attachments currently being fetched. */ private int mNumAttachmentsLoading = 0; private enum WaitingAction { NONE, SEND, SAVE } /** * Specifies what action to perform once attachments have been fetched. */ private WaitingAction mWaitingForAttachments = WaitingAction.NONE; private Handler mHandler = new Handler() { @Override public void handleMessage(android.os.Message msg) { Loading Loading @@ -354,6 +378,9 @@ public class MessageCompose extends K9Activity implements OnClickListener { getString(R.string.message_discarded_toast), Toast.LENGTH_LONG).show(); break; case MSG_PERFORM_STALLED_ACTION: performStalledAction(); break; default: super.handleMessage(msg); break; Loading Loading @@ -1080,6 +1107,8 @@ public class MessageCompose extends K9Activity implements OnClickListener { attachments.add(attachment); } outState.putInt(STATE_KEY_NUM_ATTACHMENTS_LOADING, mNumAttachmentsLoading); outState.putString(STATE_KEY_WAITING_FOR_ATTACHMENTS, mWaitingForAttachments.name()); outState.putParcelableArrayList(STATE_KEY_ATTACHMENTS, attachments); outState.putBoolean(STATE_KEY_CC_SHOWN, mCcWrapper.getVisibility() == View.VISIBLE); outState.putBoolean(STATE_KEY_BCC_SHOWN, mBccWrapper.getVisibility() == View.VISIBLE); Loading @@ -1105,6 +1134,16 @@ public class MessageCompose extends K9Activity implements OnClickListener { mAttachments.removeAllViews(); mMaxLoaderId = 0; mNumAttachmentsLoading = savedInstanceState.getInt(STATE_KEY_NUM_ATTACHMENTS_LOADING); mWaitingForAttachments = WaitingAction.NONE; try { String waitingFor = savedInstanceState.getString(STATE_KEY_WAITING_FOR_ATTACHMENTS); mWaitingForAttachments = WaitingAction.valueOf(waitingFor); } catch (Exception e) { Log.w(K9.LOG_TAG, "Couldn't read value \" + STATE_KEY_WAITING_FOR_ATTACHMENTS +" + "\" from saved instance state", e); } ArrayList<Attachment> attachments = savedInstanceState.getParcelableArrayList(STATE_KEY_ATTACHMENTS); for (Attachment attachment : attachments) { addAttachmentView(attachment); Loading Loading @@ -1784,6 +1823,20 @@ public class MessageCompose extends K9Activity implements OnClickListener { Toast.makeText(this, getString(R.string.message_compose_error_no_recipients), Toast.LENGTH_LONG).show(); return; } if (mWaitingForAttachments != WaitingAction.NONE) { return; } if (mNumAttachmentsLoading > 0) { mWaitingForAttachments = WaitingAction.SEND; showWaitingForAttachmentDialog(); } else { performSend(); } } private void performSend() { final CryptoProvider crypto = mAccount.getCryptoProvider(); if (mEncryptCheckbox.isChecked() && !mPgpData.hasEncryptionKeys()) { // key selection before encryption Loading Loading @@ -1847,6 +1900,19 @@ public class MessageCompose extends K9Activity implements OnClickListener { } private void onSave() { if (mWaitingForAttachments != WaitingAction.NONE) { return; } if (mNumAttachmentsLoading > 0) { mWaitingForAttachments = WaitingAction.SAVE; showWaitingForAttachmentDialog(); } else { performSend(); } } private void performSave() { saveIfNeeded(); finish(); } Loading Loading @@ -1987,6 +2053,7 @@ public class MessageCompose extends K9Activity implements OnClickListener { new LoaderManager.LoaderCallbacks<Attachment>() { @Override public Loader<Attachment> onCreateLoader(int id, Bundle args) { onFetchAttachmentStarted(); Attachment attachment = args.getParcelable(LOADER_ARG_ATTACHMENT); return new AttachmentInfoLoader(MessageCompose.this, attachment); } Loading @@ -2004,6 +2071,8 @@ public class MessageCompose extends K9Activity implements OnClickListener { attachment.loaderId = ++mMaxLoaderId; initAttachmentContentLoader(attachment); } else { onFetchAttachmentFinished(); } getSupportLoaderManager().destroyLoader(loaderId); Loading @@ -2011,6 +2080,7 @@ public class MessageCompose extends K9Activity implements OnClickListener { @Override public void onLoaderReset(Loader<Attachment> loader) { onFetchAttachmentFinished(); } }; Loading Loading @@ -2038,14 +2108,48 @@ public class MessageCompose extends K9Activity implements OnClickListener { } } onFetchAttachmentFinished(); getSupportLoaderManager().destroyLoader(loaderId); } @Override public void onLoaderReset(Loader<Attachment> loader) { onFetchAttachmentFinished(); } }; private void onFetchAttachmentStarted() { mNumAttachmentsLoading += 1; } private void onFetchAttachmentFinished() { // We're not allowed to perform fragment transactions when called from onLoadFinished(). // So we use the Handler to call performStalledAction(). mHandler.sendEmptyMessage(MSG_PERFORM_STALLED_ACTION); } private void performStalledAction() { mNumAttachmentsLoading -= 1; WaitingAction waitingFor = mWaitingForAttachments; mWaitingForAttachments = WaitingAction.NONE; if (waitingFor != WaitingAction.NONE) { dismissWaitingForAttachmentDialog(); } switch (waitingFor) { case SEND: { performSend(); break; } case SAVE: { performSave(); break; } } } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { Loading Loading @@ -2380,6 +2484,45 @@ public class MessageCompose extends K9Activity implements OnClickListener { } } private void showWaitingForAttachmentDialog() { String title; switch (mWaitingForAttachments) { case SEND: { title = getString(R.string.fetching_attachment_dialog_title_send); break; } case SAVE: { title = getString(R.string.fetching_attachment_dialog_title_save); break; } default: { return; } } ProgressDialogFragment fragment = ProgressDialogFragment.newInstance(title, getString(R.string.fetching_attachment_dialog_message)); fragment.show(getSupportFragmentManager(), FRAGMENT_WAITING_FOR_ATTACHMENT); } public void onCancel(ProgressDialogFragment fragment) { attachmentProgressDialogCancelled(); } void attachmentProgressDialogCancelled() { mWaitingForAttachments = WaitingAction.NONE; } private void dismissWaitingForAttachmentDialog() { ProgressDialogFragment fragment = (ProgressDialogFragment) getSupportFragmentManager().findFragmentByTag(FRAGMENT_WAITING_FOR_ATTACHMENT); if (fragment != null) { fragment.dismiss(); } } @Override public Dialog onCreateDialog(int id) { switch (id) { Loading
src/com/fsck/k9/fragment/MessageViewFragment.java +2 −2 Original line number Diff line number Diff line Loading @@ -752,8 +752,8 @@ public class MessageViewFragment extends SherlockFragment implements OnClickList break; } case R.id.dialog_attachment_progress: { String title = getString(R.string.dialog_attachment_progress_title); fragment = ProgressDialogFragment.newInstance(title); String message = getString(R.string.dialog_attachment_progress_title); fragment = ProgressDialogFragment.newInstance(null, message); break; } default: { Loading
src/com/fsck/k9/fragment/ProgressDialogFragment.java +22 −2 Original line number Diff line number Diff line Loading @@ -2,19 +2,22 @@ package com.fsck.k9.fragment; import android.app.Dialog; import android.app.ProgressDialog; import android.content.DialogInterface; import android.os.Bundle; import com.actionbarsherlock.app.SherlockDialogFragment; public class ProgressDialogFragment extends SherlockDialogFragment { private static final String ARG_TITLE = "title"; protected static final String ARG_TITLE = "title"; protected static final String ARG_MESSAGE = "message"; public static ProgressDialogFragment newInstance(String title) { public static ProgressDialogFragment newInstance(String title, String message) { ProgressDialogFragment fragment = new ProgressDialogFragment(); Bundle args = new Bundle(); args.putString(ARG_TITLE, title); args.putString(ARG_MESSAGE, message); fragment.setArguments(args); return fragment; Loading @@ -25,11 +28,28 @@ public class ProgressDialogFragment extends SherlockDialogFragment { public Dialog onCreateDialog(Bundle savedInstanceState) { Bundle args = getArguments(); String title = args.getString(ARG_TITLE); String message = args.getString(ARG_MESSAGE); ProgressDialog dialog = new ProgressDialog(getActivity()); dialog.setIndeterminate(true); dialog.setTitle(title); dialog.setMessage(message); return dialog; } @Override public void onCancel(DialogInterface dialog) { CancelListener listener = (CancelListener) getActivity(); if (listener != null && listener instanceof CancelListener) { listener.onCancel(this); } super.onCancel(dialog); } public interface CancelListener { void onCancel(ProgressDialogFragment fragment); } }