diff --git a/src/com/android/email/activity/MessageListXL.java b/src/com/android/email/activity/MessageListXL.java
index 9f61f6cd1..4fd381265 100644
--- a/src/com/android/email/activity/MessageListXL.java
+++ b/src/com/android/email/activity/MessageListXL.java
@@ -21,7 +21,6 @@ import com.android.email.Controller;
import com.android.email.ControllerResultUiThreadWrapper;
import com.android.email.Email;
import com.android.email.MessagingExceptionStrings;
-import com.android.email.Preferences;
import com.android.email.R;
import com.android.email.RefreshManager;
import com.android.email.activity.setup.AccountSecurity;
@@ -43,6 +42,7 @@ import android.os.Bundle;
import android.os.Handler;
import android.text.TextUtils;
import android.util.Log;
+import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
@@ -51,12 +51,11 @@ import android.widget.TextView;
import java.security.InvalidParameterException;
/**
- * The main (two-pane) activity for XL devices.
- *
- * TODO Refine "move to".
+ * The main activity for multi-pane UIs. The MessageListXL
class is responsible
+ * for managing the "chrome" area of the screen; which primarily includes the action bar.
+ * The rest of the content area is managed by a fragment manager.
*/
-public class MessageListXL extends Activity implements
- MessageListXLFragmentManager.TargetActivity, MoveMessageToDialog.Callback,
+public class MessageListXL extends Activity implements MessageListXLFragmentManager.TargetActivity,
View.OnClickListener {
private static final String EXTRA_ACCOUNT_ID = "ACCOUNT_ID";
private static final String EXTRA_MAILBOX_ID = "MAILBOX_ID";
@@ -71,28 +70,22 @@ public class MessageListXL extends Activity implements
private final RefreshListener mRefreshListener = new RefreshListener();
private Controller.Result mControllerResult;
- /** True between onCreate() to onDestroy() */
- private boolean mIsCreated;
-
private AccountSelectorAdapter mAccountsSelectorAdapter;
- private final ActionBarNavigationCallback mActionBarNavigationCallback
- = new ActionBarNavigationCallback();
+ private ActionBar mActionBar;
+ private View mActionBarMailboxNameView;
+ private TextView mActionBarMailboxName;
+ private TextView mActionBarUnreadCount;
+ private final ActionBarNavigationCallback mActionBarNavigationCallback =
+ new ActionBarNavigationCallback();
- private MessageOrderManager mOrderManager;
-
- private final MessageListXLFragmentManager mFragmentManager
- = new MessageListXLFragmentManager(this);
-
- private final MessageOrderManagerCallback mMessageOrderManagerCallback
- = new MessageOrderManagerCallback();
+ private final MessageListXLFragmentManager mFragmentManager =
+ new MessageListXLFragmentManager(this);
private final EmailAsyncTask.Tracker mTaskTracker = new EmailAsyncTask.Tracker();
- private BannerController mBannerController;
- private TextView mErrorMessageView;
- /**
- * Id of the account that had a messaging exception most recently.
- */
+ /** Banner to display errors */
+ private BannerController mErrorBanner;
+ /** Id of the account that had a messaging exception most recently. */
private long mLastErrorAccountId;
/**
@@ -162,10 +155,6 @@ public class MessageListXL extends Activity implements
mRefreshManager = RefreshManager.getInstance(this);
mRefreshManager.registerListener(mRefreshListener);
- mFragmentManager.setMailboxListFragmentCallback(new MailboxListFragmentCallback());
- mFragmentManager.setMessageListFragmentCallback(new MessageListFragmentCallback());
- mFragmentManager.setMessageViewFragmentCallback(new MessageViewFragmentCallback());
-
mAccountsSelectorAdapter = new AccountSelectorAdapter(this, null);
if (savedInstanceState != null) {
@@ -178,10 +167,28 @@ public class MessageListXL extends Activity implements
// Set up views
// TODO Probably better to extract mErrorMessageView related code into a separate class,
// so that it'll be easy to reuse for the phone activities.
- mErrorMessageView = (TextView) findViewById(R.id.error_message);
- mErrorMessageView.setOnClickListener(this);
- mBannerController = new BannerController(this, mErrorMessageView,
- getResources().getDimensionPixelSize(R.dimen.error_message_height));
+ TextView errorMessage = (TextView) findViewById(R.id.error_message);
+ errorMessage.setOnClickListener(this);
+ int errorBannerHeight = getResources().getDimensionPixelSize(R.dimen.error_message_height);
+ mErrorBanner = new BannerController(this, errorMessage, errorBannerHeight);
+
+ mActionBar = getActionBar();
+
+ // Set a view for the current mailbox to the action bar.
+ final LayoutInflater inflater = LayoutInflater.from(mContext);
+ mActionBarMailboxNameView = inflater.inflate(R.layout.action_bar_current_mailbox, null);
+ mActionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM, ActionBar.DISPLAY_SHOW_CUSTOM);
+ final ActionBar.LayoutParams customViewLayout = new ActionBar.LayoutParams(
+ ActionBar.LayoutParams.WRAP_CONTENT,
+ ActionBar.LayoutParams.MATCH_PARENT);
+ customViewLayout.setMargins(mContext.getResources().getDimensionPixelSize(
+ R.dimen.action_bar_mailbox_name_left_margin) , 0, 0, 0);
+ mActionBar.setCustomView(mActionBarMailboxNameView, customViewLayout);
+
+ mActionBarMailboxName =
+ (TextView) mActionBarMailboxNameView.findViewById(R.id.mailbox_name);
+ mActionBarUnreadCount =
+ (TextView) mActionBarMailboxNameView.findViewById(R.id.unread_count);
// Halt the progress indicator (we'll display it later when needed)
setProgressBarIndeterminate(true);
@@ -190,8 +197,6 @@ public class MessageListXL extends Activity implements
mControllerResult = new ControllerResultUiThreadWrapper(new Handler(),
new ControllerResult());
mController.addResultCallback(mControllerResult);
-
- mIsCreated = true;
}
private void initFromIntent() {
@@ -221,11 +226,7 @@ public class MessageListXL extends Activity implements
protected void onStart() {
if (Email.DEBUG_LIFECYCLE && Email.DEBUG) Log.d(Logging.LOG_TAG, "MessageListXL onStart");
super.onStart();
-
mFragmentManager.onStart();
- if (mFragmentManager.isMessageSelected()) {
- updateMessageOrderManager();
- }
}
@Override
@@ -233,12 +234,12 @@ public class MessageListXL extends Activity implements
if (Email.DEBUG_LIFECYCLE && Email.DEBUG) Log.d(Logging.LOG_TAG, "MessageListXL onResume");
super.onResume();
mFragmentManager.onResume();
-
- // On MessageList.onResume, we go back to Welcome if an account has been added/removed.
- // We don't need to do that here, because when the activity resumes, the account list loader
- // will load the latest list.
- // And if all the accounts have been removed, the loader will detect it and do
- // appropriate things.
+ /**
+ * In {@link MessageList#onResume()}, we go back to {@link Welcome} if an account
+ * has been added/removed. We don't need to do that here, because we fetch the most
+ * up-to-date account list. Additionally, we detect and do the right thing if all
+ * of the accounts have been removed.
+ */
}
@Override
@@ -252,15 +253,12 @@ public class MessageListXL extends Activity implements
protected void onStop() {
if (Email.DEBUG_LIFECYCLE && Email.DEBUG) Log.d(Logging.LOG_TAG, "MessageListXL onStop");
super.onStop();
-
mFragmentManager.onStop();
- stopMessageOrderManager();
}
@Override
protected void onDestroy() {
if (Email.DEBUG_LIFECYCLE && Email.DEBUG) Log.d(Logging.LOG_TAG, "MessageListXL onDestroy");
- mIsCreated = false;
mController.removeResultCallback(mControllerResult);
mTaskTracker.cancellAllInterrupt();
mRefreshManager.unregisterListener(mRefreshListener);
@@ -279,8 +277,8 @@ public class MessageListXL extends Activity implements
/**
* Performs the back action.
*
- * @param isSystemBackKey set true if the system back key is pressed, rather than the home
- * icon on action bar.
+ * @param isSystemBackKey true
if the system back key was pressed. Otherwise,
+ * false
[e.g. the home icon on action bar were pressed].
*/
private boolean onBackPressed(boolean isSystemBackKey) {
if (mFragmentManager.onBackPressed(isSystemBackKey)) {
@@ -303,237 +301,6 @@ public class MessageListXL extends Activity implements
}
}
- private void onCurrentMessageGone() {
- switch (Preferences.getPreferences(this).getAutoAdvanceDirection()) {
- case Preferences.AUTO_ADVANCE_NEWER:
- if (moveToNewer()) return;
- if (moveToOlder()) return;
- break;
- case Preferences.AUTO_ADVANCE_OLDER:
- if (moveToOlder()) return;
- if (moveToNewer()) return;
- break;
- }
- // Last message in the box or AUTO_ADVANCE_MESSAGE_LIST. Go back to message list.
- mFragmentManager.goBackToMailbox();
- }
-
- private void onMoveMessage() {
- long messageId = mFragmentManager.getMessageId();
- MoveMessageToDialog dialog = MoveMessageToDialog.newInstance(new long[] {messageId},
- null);
- dialog.show(getFragmentManager(), "dialog");
- }
-
- @Override
- public void onMoveToMailboxSelected(long newMailboxId, long[] messageIds) {
- ActivityHelper.moveMessages(this, newMailboxId, messageIds);
- onCurrentMessageGone();
- }
-
- /**
- * Start {@link MessageOrderManager} if not started, and sync it to the current message.
- */
- private void updateMessageOrderManager() {
- if (!mFragmentManager.isMailboxSelected()) {
- return;
- }
- final long mailboxId = mFragmentManager.getMailboxId();
- if (mOrderManager == null || mOrderManager.getMailboxId() != mailboxId) {
- stopMessageOrderManager();
- mOrderManager = new MessageOrderManager(this, mailboxId, mMessageOrderManagerCallback);
- }
- if (mFragmentManager.isMessageSelected()) {
- mOrderManager.moveTo(mFragmentManager.getMessageId());
- }
- }
-
- private class MessageOrderManagerCallback implements MessageOrderManager.Callback {
- @Override
- public void onMessagesChanged() {
- updateNavigationArrows();
- }
-
- @Override
- public void onMessageNotFound() {
- // Current message gone.
- mFragmentManager.goBackToMailbox();
- }
- }
-
- /**
- * Stop {@link MessageOrderManager}.
- */
- private void stopMessageOrderManager() {
- if (mOrderManager != null) {
- mOrderManager.close();
- mOrderManager = null;
- }
- }
-
- /**
- * Called when the default account is not found, i.e. there's no account set up.
- */
- private void onNoAccountFound() {
- // Open Welcome, which in turn shows the adding a new account screen.
- Welcome.actionStart(this);
- finish();
- return;
- }
-
- /**
- * Disable/enable the move-to-newer/older buttons.
- */
- private void updateNavigationArrows() {
- if (mOrderManager == null) {
- // shouldn't happen, but just in case
- mFragmentManager.updateMessageCommandButtons(false, false, 0, 0);
- } else {
- mFragmentManager.updateMessageCommandButtons(
- mOrderManager.canMoveToNewer(), mOrderManager.canMoveToOlder(),
- mOrderManager.getCurrentPosition(), mOrderManager.getTotalMessageCount());
- }
- }
-
- private boolean moveToOlder() {
- if (mFragmentManager.isMessageSelected() && (mOrderManager != null)
- && mOrderManager.moveToOlder()) {
- mFragmentManager.selectMessage(mOrderManager.getCurrentMessageId());
- return true;
- }
- return false;
- }
-
- private boolean moveToNewer() {
- if (mFragmentManager.isMessageSelected() && (mOrderManager != null)
- && mOrderManager.moveToNewer()) {
- mFragmentManager.selectMessage(mOrderManager.getCurrentMessageId());
- return true;
- }
- return false;
- }
-
- private class MailboxListFragmentCallback implements MailboxListFragment.Callback {
- @Override
- public void onMailboxSelected(long accountId, long mailboxId) {
- mFragmentManager.selectMailbox(mailboxId, -1);
- }
-
- @Override
- public void onAccountSelected(long accountId) {
- mFragmentManager.selectAccount(accountId, -1, -1);
- loadAccounts(); // This will update the account spinner, and select the account.
- }
-
- @Override
- public void onCurrentMailboxUpdated(long mailboxId, String mailboxName, int unreadCount) {
- mFragmentManager.setCurrentMailboxName(mailboxName, unreadCount);
- }
- }
-
- private class MessageListFragmentCallback implements MessageListFragment.Callback {
- @Override
- public void onListLoaded() {
- }
-
- @Override
- public void onMessageOpen(long messageId, long messageMailboxId, long listMailboxId,
- int type) {
- if (type == MessageListFragment.Callback.TYPE_DRAFT) {
- MessageCompose.actionEditDraft(MessageListXL.this, messageId);
- } else {
- mFragmentManager.selectMessage(messageId);
- }
- }
-
- @Override
- public void onMailboxNotFound() {
- // TODO: What to do??
- }
-
- @Override
- public void onEnterSelectionMode(boolean enter) {
- }
- }
-
- private class MessageViewFragmentCallback implements MessageViewFragment.Callback {
- @Override
- public void onMessageViewShown(int mailboxType) {
- updateMessageOrderManager();
- updateNavigationArrows();
- }
-
- @Override
- public void onMessageViewGone() {
- stopMessageOrderManager();
- }
-
- @Override
- public boolean onUrlInMessageClicked(String url) {
- return ActivityHelper.openUrlInMessage(MessageListXL.this, url,
- mFragmentManager.getActualAccountId());
- }
-
- @Override
- public void onMessageSetUnread() {
- mFragmentManager.goBackToMailbox();
- }
-
- @Override
- public void onMessageNotExists() {
- mFragmentManager.goBackToMailbox();
- }
-
- @Override
- public void onLoadMessageStarted() {
- // TODO Any nice UI for this?
- }
-
- @Override
- public void onLoadMessageFinished() {
- // TODO Any nice UI for this?
- }
-
- @Override
- public void onLoadMessageError(String errorMessage) {
- }
-
- @Override
- public void onRespondedToInvite(int response) {
- onCurrentMessageGone();
- }
-
- @Override
- public void onCalendarLinkClicked(long epochEventStartTime) {
- ActivityHelper.openCalendar(MessageListXL.this, epochEventStartTime);
- }
-
- @Override
- public void onBeforeMessageDelete() {
- onCurrentMessageGone();
- }
-
- @Override
- public void onMoveMessage() {
- MessageListXL.this.onMoveMessage();
- }
-
- @Override
- public void onForward() {
- MessageCompose.actionForward(MessageListXL.this, mFragmentManager.getMessageId());
- }
-
- @Override
- public void onReply() {
- MessageCompose.actionReply(MessageListXL.this, mFragmentManager.getMessageId(), false);
- }
-
- @Override
- public void onReplyAll() {
- MessageCompose.actionReply(MessageListXL.this, mFragmentManager.getMessageId(), true);
- }
- }
-
@Override
public void onAccountSecurityHold(long accountId) {
startActivity(AccountSecurity.actionUpdateSecurityIntent(this, accountId, true));
@@ -542,6 +309,7 @@ public class MessageListXL extends Activity implements
@Override
public void onAccountChanged(long accountId) {
invalidateOptionsMenu(); // Update the refresh button
+ loadAccounts(); // This will update the account spinner, and select the account.
}
@Override
@@ -550,57 +318,20 @@ public class MessageListXL extends Activity implements
}
@Override
- public void onMoveToNewer() {
- moveToNewer();
- }
+ public void onMailboxNameChanged(String mailboxName, int unreadCount) {
+ mActionBarMailboxName.setText(mailboxName);
- @Override
- public void onMoveToOlder() {
- moveToOlder();
- }
-
- /**
- * Call this when getting a connection error.
- */
- private void showErrorMessage(final String rawMessage, final long accountId) {
- new EmailAsyncTask(mTaskTracker) {
- @Override
- protected String doInBackground(Void... params) {
- Account account = Account.restoreAccountWithId(MessageListXL.this, accountId);
- return (account == null) ? null : account.mDisplayName;
- }
-
- @Override
- protected void onPostExecute(String accountName) {
- final String message;
- if (TextUtils.isEmpty(accountName)) {
- message = rawMessage;
- } else {
- // TODO Use properly designed layout. Don't just concat strings, which isn't
- // good for I18N either.
- message = rawMessage + " (" + accountName + ")";
- }
- if (mBannerController.show(message)) {
- mLastErrorAccountId = accountId;
- }
- }
- }.executeParallel();
- }
-
- /**
- * Call this when the connection for an account is considered working.
- */
- private void clearErrorMessage(long accountId) {
- if (mLastErrorAccountId == accountId) {
- dismissErrorMessage();
- }
+ // Note on action bar, we show only "unread count". Some mailboxes such as Outbox don't
+ // have the idea of "unread count", in which case we just omit the count.
+ mActionBarUnreadCount.setText(
+ UiUtilities.getMessageCountForUi(mContext, unreadCount, true));
}
/**
* Force dismiss the error banner.
*/
private void dismissErrorMessage() {
- mBannerController.dismiss();
+ mErrorBanner.dismiss();
}
/**
@@ -632,7 +363,9 @@ public class MessageListXL extends Activity implements
private void updateAccountList(Cursor accountsCursor) {
final int count = accountsCursor.getCount();
if (count == 0) {
- onNoAccountFound();
+ // Open Welcome, which in turn shows the adding a new account screen.
+ Welcome.actionStart(this);
+ finish();
return;
}
@@ -645,8 +378,6 @@ public class MessageListXL extends Activity implements
ab.setDisplayOptions(ActionBar.DISPLAY_SHOW_TITLE, ActionBar.DISPLAY_SHOW_TITLE);
ab.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
ab.setTitle(AccountSelectorAdapter.getAccountDisplayName(accountsCursor));
-
- selectAccount(AccountSelectorAdapter.getAccountId(accountsCursor));
return;
}
@@ -772,6 +503,16 @@ public class MessageListXL extends Activity implements
mFragmentManager.getMailboxId()).cancelPreviousAndExecuteParallel();
}
+ @Override
+ public void onVisiblePanesChanged(int visiblePanes) {
+ // If the left pane (mailbox list pane) is hidden, the back action on action bar will be
+ // enabled, and we also show the current mailbox name.
+ final boolean leftPaneHidden = ((visiblePanes & ThreePaneLayout.PANE_LEFT) == 0);
+ mActionBar.setDisplayOptions(leftPaneHidden ? ActionBar.DISPLAY_HOME_AS_UP : 0,
+ ActionBar.DISPLAY_HOME_AS_UP);
+ mActionBarMailboxNameView.setVisibility(leftPaneHidden ? View.VISIBLE : View.GONE);
+ }
+
/**
* Class to handle refresh.
*
@@ -917,20 +658,42 @@ public class MessageListXL extends Activity implements
handleError(result, accountId, progress);
}
- private void handleError(MessagingException result, long accountId, int progress) {
+ private void handleError(final MessagingException result, final long accountId,
+ int progress) {
if (accountId == -1) {
return;
}
if (result == null) {
if (progress > 0) {
- // Connection now working.
- clearErrorMessage(accountId);
+ // Connection now working; clear the error message banner
+ if (mLastErrorAccountId == accountId) {
+ dismissErrorMessage();
+ }
}
} else {
- // Connection error.
- showErrorMessage(
- MessagingExceptionStrings.getErrorString(MessageListXL.this, result),
- accountId);
+ // Connection error; show the error message banner
+ new EmailAsyncTask(mTaskTracker) {
+ @Override
+ protected String doInBackground(Void... params) {
+ Account account =
+ Account.restoreAccountWithId(MessageListXL.this, accountId);
+ return (account == null) ? null : account.mDisplayName;
+ }
+
+ @Override
+ protected void onPostExecute(String accountName) {
+ String message =
+ MessagingExceptionStrings.getErrorString(MessageListXL.this, result);
+ if (!TextUtils.isEmpty(accountName)) {
+ // TODO Use properly designed layout. Don't just concatenate strings;
+ // which is generally poor for I18N.
+ message = message + " (" + accountName + ")";
+ }
+ if (mErrorBanner.show(message)) {
+ mLastErrorAccountId = accountId;
+ }
+ }
+ }.executeParallel();
}
}
}
diff --git a/src/com/android/email/activity/MessageListXLFragmentManager.java b/src/com/android/email/activity/MessageListXLFragmentManager.java
index 5ad23c449..3d79b856d 100644
--- a/src/com/android/email/activity/MessageListXLFragmentManager.java
+++ b/src/com/android/email/activity/MessageListXLFragmentManager.java
@@ -17,20 +17,18 @@
package com.android.email.activity;
import com.android.email.Email;
+import com.android.email.Preferences;
import com.android.email.R;
import com.android.emailcommon.Logging;
import com.android.emailcommon.provider.EmailContent.Account;
import com.android.emailcommon.provider.EmailContent.Mailbox;
import android.app.ActionBar;
+import android.app.Activity;
import android.app.FragmentManager;
-import android.content.Context;
import android.os.Bundle;
import android.util.Log;
-import android.view.LayoutInflater;
import android.view.View;
-import android.view.ViewGroup;
-import android.widget.TextView;
import java.security.InvalidParameterException;
@@ -42,16 +40,22 @@ import java.security.InvalidParameterException;
*
* TODO: Test it. It's testable if we implement MockFragmentTransaction, which may be too early
* to do so at this point. (API may not be stable enough yet.)
+ *
+ * TODO Refine "move to".
*/
-class MessageListXLFragmentManager {
+class MessageListXLFragmentManager implements
+ MoveMessageToDialog.Callback,
+ MailboxFinder.Callback,
+ ThreePaneLayout.Callback,
+ MailboxListFragment.Callback,
+ MessageListFragment.Callback,
+ MessageViewFragment.Callback {
private static final String BUNDLE_KEY_ACCOUNT_ID = "MessageListXl.state.account_id";
private static final String BUNDLE_KEY_MAILBOX_ID = "MessageListXl.state.mailbox_id";
private static final String BUNDLE_KEY_MESSAGE_ID = "MessageListXl.state.message_id";
private static final String BUNDLE_KEY_MESSAGE_LIST_STATE
= "MessageListXl.state.message_list_state";
- private final Context mContext;
-
private boolean mIsActivityResumed;
/** Current account id. (-1 = not selected) */
@@ -63,11 +67,7 @@ class MessageListXLFragmentManager {
/** Current message id. (-1 = not selected) */
private long mMessageId = -1;
- private ActionBar mActionBar;
private ThreePaneLayout mThreePane;
- private View mActionBarMailboxNameView;
- private TextView mActionBarMailboxName;
- private TextView mActionBarUnreadCount;
private MailboxListFragment mMailboxListFragment;
private MessageListFragment mMessageListFragment;
@@ -75,52 +75,216 @@ class MessageListXLFragmentManager {
private MessageCommandButtonView mMessageCommandButtons;
private MailboxFinder mMailboxFinder;
- private final MailboxFinderCallback mMailboxFinderCallback = new MailboxFinderCallback();
- private final ThreePaneLayoutCallback mThreePaneLayoutCallback = new ThreePaneLayoutCallback();
- /**
- * Save state for the "message list -> message view -[back press]-> message list" transition.
- */
+ /** Save state for the "message list -> message view -[back press]-> message list" transition */
private MessageListFragment.State mMessageListFragmentState;
+ private MessageOrderManager mOrderManager;
+ private final MessageOrderManagerCallback mMessageOrderManagerCallback =
+ new MessageOrderManagerCallback();
+
/**
* The interface that {@link MessageListXL} implements. We don't call its methods directly,
* in the hope that it'll make writing tests easier, and make it clear which methods are needed
* for MessageListXLFragmentManager.
+ * TODO Consider getting rid of this. The fragment manager needs an {@link Activity}, so,
+ * merely passing around an interface is not sufficient.
*/
public interface TargetActivity {
+ /** Implemented by {@link Activity}, so, signature must match */
public ActionBar getActionBar();
public FragmentManager getFragmentManager();
-
- /**
- * Called when the selected account is on security-hold.
- */
- public void onAccountSecurityHold(long accountId);
-
- /**
- * Called when the current account has changed.
- */
- public void onAccountChanged(long accountId);
-
- /**
- * Called when the current mailbox has changed.
- */
- public void onMailboxChanged(long accountId, long newMailboxId);
-
- /** Called when "move to newer" button is pressed. */
- public void onMoveToNewer();
-
- /** Called when "move to older" button is pressed. */
- public void onMoveToOlder();
-
public View findViewById(int id);
+
+ /** Called when the selected account is on security-hold. */
+ public void onAccountSecurityHold(long accountId);
+ /** Called when the current account has changed. */
+ public void onAccountChanged(long accountId);
+ /** Called when the current mailbox has changed. */
+ public void onMailboxChanged(long accountId, long newMailboxId);
+ /** Called when the current mailbox name / unread count has changed. */
+ public void onMailboxNameChanged(String mailboxName, int unreadCount);
+ /** Called when the visible panes have changed. */
+ public void onVisiblePanesChanged(int visiblePanes);
}
- private final TargetActivity mTargetActivity;
+ private final MessageListXL mActivity;
public MessageListXLFragmentManager(MessageListXL activity) {
- mContext = activity;
- mTargetActivity = activity;
+ mActivity = activity;
+ }
+
+ // MailboxFinder$Callback
+ @Override
+ public void onAccountNotFound() {
+ if (Email.DEBUG_LIFECYCLE && Email.DEBUG) {
+ Log.d(Logging.LOG_TAG, "MessageListXLFragmentManager#onAccountNotFound()");
+ }
+ // Shouldn't happen
+ }
+
+ @Override
+ public void onAccountSecurityHold(long accountId) {
+ if (Email.DEBUG_LIFECYCLE && Email.DEBUG) {
+ Log.d(Logging.LOG_TAG, "MessageListXLFragmentManager#onAccountSecurityHold()");
+ }
+ mActivity.onAccountSecurityHold(accountId);
+ }
+
+ @Override
+ public void onMailboxFound(long accountId, long mailboxId) {
+ if (Email.DEBUG_LIFECYCLE && Email.DEBUG) {
+ Log.d(Logging.LOG_TAG, "MessageListXLFragmentManager#onMailboxFound()");
+ }
+ selectMailbox(mailboxId, -1);
+ }
+
+ @Override
+ public void onMailboxNotFound(long accountId) {
+ if (Email.DEBUG_LIFECYCLE && Email.DEBUG) {
+ Log.d(Logging.LOG_TAG, "MessageListXLFragmentManager#onMailboxNotFound()");
+ }
+ // Shouldn't happen
+ }
+
+ // MoveMessageToDialog$Callback
+ @Override
+ public void onMoveToMailboxSelected(long newMailboxId, long[] messageIds) {
+ ActivityHelper.moveMessages(mActivity, newMailboxId, messageIds);
+ onCurrentMessageGone();
+ }
+
+ // ThreePaneLayoutCallback
+ @Override
+ public void onVisiblePanesChanged(int previousVisiblePanes) {
+ final int visiblePanes = mThreePane.getVisiblePanes();
+ mActivity.onVisiblePanesChanged(visiblePanes);
+ if (((visiblePanes & ThreePaneLayout.PANE_RIGHT) == 0) &&
+ ((previousVisiblePanes & ThreePaneLayout.PANE_RIGHT) != 0)) {
+ // Message view just got hidden
+ mMessageId = -1;
+ mMessageListFragment.setSelectedMessage(-1);
+ mMessageViewFragment.clearContent();
+ }
+ mMessageListFragment.setVisibility((visiblePanes & ThreePaneLayout.PANE_MIDDLE) != 0);
+ }
+
+ // MailboxListFragment$Callback
+ @Override
+ public void onMailboxSelected(long accountId, long mailboxId) {
+ selectMailbox(mailboxId, -1);
+ }
+
+ @Override
+ public void onAccountSelected(long accountId) {
+ selectAccount(accountId, -1, -1);
+ }
+
+ @Override
+ public void onCurrentMailboxUpdated(long mailboxId, String mailboxName, int unreadCount) {
+ mActivity.onMailboxNameChanged(mailboxName, unreadCount);
+ }
+
+ // MessageListFragment$Callback
+ @Override
+ public void onMessageOpen(long messageId, long messageMailboxId, long listMailboxId,
+ int type) {
+ if (type == MessageListFragment.Callback.TYPE_DRAFT) {
+ MessageCompose.actionEditDraft(mActivity, messageId);
+ } else {
+ selectMessage(messageId);
+ }
+ }
+
+ @Override
+ public void onMailboxNotFound() {
+ // TODO: What to do??
+ }
+
+ @Override
+ public void onEnterSelectionMode(boolean enter) {
+ }
+
+ @Override
+ public void onListLoaded() {
+ }
+
+ // MessageViewFragment$Callback
+ @Override
+ public void onMessageViewShown(int mailboxType) {
+ updateMessageOrderManager();
+ updateNavigationArrows();
+ }
+
+ @Override
+ public void onMessageViewGone() {
+ stopMessageOrderManager();
+ }
+
+ @Override
+ public boolean onUrlInMessageClicked(String url) {
+ return ActivityHelper.openUrlInMessage(mActivity, url, getActualAccountId());
+ }
+
+ @Override
+ public void onMessageSetUnread() {
+ goBackToMailbox();
+ }
+
+ @Override
+ public void onMessageNotExists() {
+ goBackToMailbox();
+ }
+
+ @Override
+ public void onLoadMessageStarted() {
+ // TODO Any nice UI for this?
+ }
+
+ @Override
+ public void onLoadMessageFinished() {
+ // TODO Any nice UI for this?
+ }
+
+ @Override
+ public void onLoadMessageError(String errorMessage) {
+ }
+
+ @Override
+ public void onRespondedToInvite(int response) {
+ onCurrentMessageGone();
+ }
+
+ @Override
+ public void onCalendarLinkClicked(long epochEventStartTime) {
+ ActivityHelper.openCalendar(mActivity, epochEventStartTime);
+ }
+
+ @Override
+ public void onBeforeMessageDelete() {
+ onCurrentMessageGone();
+ }
+
+ @Override
+ public void onMoveMessage() {
+ long messageId = getMessageId();
+ MoveMessageToDialog dialog = MoveMessageToDialog.newInstance(new long[] {messageId}, null);
+ dialog.show(mActivity.getFragmentManager(), "dialog");
+ }
+
+ @Override
+ public void onForward() {
+ MessageCompose.actionForward(mActivity, getMessageId());
+ }
+
+ @Override
+ public void onReply() {
+ MessageCompose.actionReply(mActivity, getMessageId(), false);
+ }
+
+ @Override
+ public void onReplyAll() {
+ MessageCompose.actionReply(mActivity, getMessageId(), true);
}
/**
@@ -133,10 +297,10 @@ class MessageListXLFragmentManager {
if (Email.DEBUG_LIFECYCLE && Email.DEBUG) {
Log.d(Logging.LOG_TAG, "MessageListXLFragmentManager.onActivityViewReady");
}
- mThreePane = (ThreePaneLayout) mTargetActivity.findViewById(R.id.three_pane);
- mThreePane.setCallback(mThreePaneLayoutCallback);
+ mThreePane = (ThreePaneLayout) mActivity.findViewById(R.id.three_pane);
+ mThreePane.setCallback(this);
- FragmentManager fm = mTargetActivity.getFragmentManager();
+ FragmentManager fm = mActivity.getFragmentManager();
mMailboxListFragment = (MailboxListFragment) fm.findFragmentById(
mThreePane.getLeftPaneId());
mMessageListFragment = (MessageListFragment) fm.findFragmentById(
@@ -146,41 +310,9 @@ class MessageListXLFragmentManager {
mMessageCommandButtons = mThreePane.getMessageCommandButtons();
mMessageCommandButtons.setCallback(new CommandButtonCallback());
- mActionBar = mTargetActivity.getActionBar();
-
- // Set a view for the current mailbox to the action bar.
- final LayoutInflater inflater = LayoutInflater.from(mContext);
- mActionBarMailboxNameView = inflater.inflate(R.layout.action_bar_current_mailbox, null);
- mActionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM, ActionBar.DISPLAY_SHOW_CUSTOM);
- final ActionBar.LayoutParams customViewLayout = new ActionBar.LayoutParams(
- ActionBar.LayoutParams.WRAP_CONTENT,
- ActionBar.LayoutParams.MATCH_PARENT);
- customViewLayout.setMargins(mContext.getResources().getDimensionPixelSize(
- R.dimen.action_bar_mailbox_name_left_margin) , 0, 0, 0);
- mActionBar.setCustomView(mActionBarMailboxNameView, customViewLayout);
-
- mActionBarMailboxName =
- (TextView) mActionBarMailboxNameView.findViewById(R.id.mailbox_name);
- mActionBarUnreadCount =
- (TextView) mActionBarMailboxNameView.findViewById(R.id.unread_count);
- }
-
- /** Set callback for fragment. */
- public void setMailboxListFragmentCallback(
- MailboxListFragment.Callback mailboxListFragmentCallback) {
- mMailboxListFragment.setCallback(mailboxListFragmentCallback);
- }
-
- /** Set callback for fragment. */
- public void setMessageListFragmentCallback(
- MessageListFragment.Callback messageListFragmentCallback) {
- mMessageListFragment.setCallback(messageListFragmentCallback);
- }
-
- /** Set callback for fragment. */
- public void setMessageViewFragmentCallback(
- MessageViewFragment.Callback messageViewFragmentCallback) {
- mMessageViewFragment.setCallback(messageViewFragmentCallback);
+ mMailboxListFragment.setCallback(this);
+ mMessageListFragment.setCallback(this);
+ mMessageViewFragment.setCallback(this);
}
/**
@@ -225,35 +357,26 @@ class MessageListXLFragmentManager {
return getMessageId() != -1;
}
- public MailboxListFragment getMailboxListFragment() {
- return mMailboxListFragment;
- }
-
- public MessageListFragment getMessageListFragment() {
- return mMessageListFragment;
- }
-
- public MessageViewFragment getMessageViewFragment() {
- return mMessageViewFragment;
- }
-
/**
* Called from {@link MessageListXL#onStart}.
*/
public void onStart() {
- // Nothing to do
+ if (isMessageSelected()) {
+ updateMessageOrderManager();
+ }
}
/**
* Called from {@link MessageListXL#onResume}.
*/
public void onResume() {
+ int visiblePanes = mThreePane.getVisiblePanes();
+ mActivity.onVisiblePanesChanged(visiblePanes);
+
if (mIsActivityResumed) {
return;
}
mIsActivityResumed = true;
-
- updateActionBar();
}
/**
@@ -264,14 +387,14 @@ class MessageListXLFragmentManager {
return;
}
mIsActivityResumed = false;
- saveMessageListFragmentState();
+ mMessageListFragmentState = mMessageListFragment.getState();
}
/**
* Called from {@link MessageListXL#onStop}.
*/
public void onStop() {
- // Nothing to do
+ stopMessageOrderManager();
}
/**
@@ -304,38 +427,6 @@ class MessageListXLFragmentManager {
selectAccount(accountId, mailboxId, messageId);
}
- private void saveMessageListFragmentState() {
- if (mMessageListFragment != null) {
- mMessageListFragmentState = mMessageListFragment.getState();
- }
- }
-
- private void restoreMesasgeListState() {
- if ((mMessageListFragment != null) && (mMessageListFragmentState != null)) {
- mMessageListFragmentState.restore(mMessageListFragment);
- mMessageListFragmentState = null;
- }
- }
-
- private void updateActionBar() {
- // If the left pane (mailbox list pane) is hidden, the back action on action bar will be
- // enabled, and we also show the current mailbox name.
- final int visiblePanes = mThreePane.getVisiblePanes();
- final boolean leftPaneHidden = ((visiblePanes & ThreePaneLayout.PANE_LEFT) == 0);
- mActionBar.setDisplayOptions(leftPaneHidden ? ActionBar.DISPLAY_HOME_AS_UP : 0,
- ActionBar.DISPLAY_HOME_AS_UP);
- mActionBarMailboxNameView.setVisibility(leftPaneHidden ? View.VISIBLE : View.GONE);
- }
-
- public void setCurrentMailboxName(String mailboxName, int unreadCount) {
- mActionBarMailboxName.setText(mailboxName);
-
- // Note on action bar, we show only "unread count". Some mailboxes such as Outbox don't
- // have the idea of "unread count", in which case we just omit the count.
- mActionBarUnreadCount.setText(
- UiUtilities.getMessageCountForUi(mContext, unreadCount, true));
- }
-
/**
* Call it to select an account.
*
@@ -371,11 +462,14 @@ class MessageListXLFragmentManager {
// When opening the Combined view, the right pane will be "combined inbox".
selectMailbox(Mailbox.QUERY_ALL_INBOXES, -1);
} else if (mailboxId == -1) {
- startInboxLookup();
+ // Try to find the inbox for the account
+ closeMailboxFinder();
+ mMailboxFinder = new MailboxFinder(mActivity, mAccountId, Mailbox.TYPE_INBOX, this);
+ mMailboxFinder.startLookup();
} else {
selectMailbox(mailboxId, messageId);
}
- mTargetActivity.onAccountChanged(mAccountId);
+ mActivity.onAccountChanged(mAccountId);
}
/**
@@ -389,59 +483,61 @@ class MessageListXLFragmentManager {
}
/**
- * If the current view is MessageView, go back to MessageList.
+ * Go back to a mailbox list view. If a message view is currently active, it will
+ * be hidden.
*/
- public void goBackToMailbox() {
+ private void goBackToMailbox() {
if (isMessageSelected()) {
mThreePane.showLeftPane(); // Show mailbox list
}
}
/**
- * Call it to select a mailbox.
- *
+ * Select a mailbox and potentially a message within that mailbox.
* We assume the mailbox selected here belongs to the account selected with
* {@link #selectAccount}.
*
* @param mailboxId ID of mailbox
* @param messageId message ID. Pass -1 to not open a message.
*/
- public void selectMailbox(long mailboxId, long messageId) {
+ private void selectMailbox(long mailboxId, long messageId) {
if (Email.DEBUG_LIFECYCLE && Email.DEBUG) {
Log.d(Logging.LOG_TAG, "selectMailbox mMailboxId=" + mailboxId);
}
if (mailboxId == -1) {
throw new InvalidParameterException();
}
-
if (mMailboxId == mailboxId) {
return;
}
- // Update members.
+ // Update members
mMailboxId = mailboxId;
mMessageId = -1;
// Open mailbox
+ if (mMessageListFragmentState != null) {
+ mMessageListFragmentState.restore(mMessageListFragment);
+ mMessageListFragmentState = null;
+ }
mMessageListFragment.openMailbox(mMailboxId);
- restoreMesasgeListState();
-
mMailboxListFragment.setSelectedMailbox(mMailboxId);
- mTargetActivity.onMailboxChanged(mAccountId, mMailboxId);
+ mActivity.onMailboxChanged(mAccountId, mMailboxId);
+
+ // If a message ID was specified, show it; otherwise show the mailbox list
if (messageId == -1) {
- mThreePane.showLeftPane(); // Show mailbox list
+ mThreePane.showLeftPane();
} else {
selectMessage(messageId);
}
}
/**
- * Call it to select a mailbox.
- *
- * We assume the message passed here belongs to the account/mailbox selected with
- * {@link #selectAccount} and {@link #selectMailbox}.
+ * Select a message to view.
+ * We assume the message selected here belongs to the mailbox selected with
+ * {@link #selectMailbox}.
*/
- public void selectMessage(long messageId) {
+ private void selectMessage(long messageId) {
if (Email.DEBUG_LIFECYCLE && Email.DEBUG) {
Log.d(Logging.LOG_TAG, "selectMessage messageId=" + messageId);
}
@@ -452,9 +548,9 @@ class MessageListXLFragmentManager {
return;
}
- saveMessageListFragmentState();
+ mMessageListFragmentState = mMessageListFragment.getState();
- // Update member.
+ // Update member
mMessageId = messageId;
// Open message
@@ -463,28 +559,6 @@ class MessageListXLFragmentManager {
mThreePane.showRightPane(); // Show message view
}
- /**
- * Unselect the currently viewed message, if any, and release the resoruce grabbed by the
- * message view.
- *
- * This must be called when the three pane reports that the message view pane gets hidden.
- */
- private void onMessageViewClosed() {
- mMessageId = -1;
- mMessageListFragment.setSelectedMessage(-1);
- mMessageViewFragment.clearContent();
- }
-
- private void startInboxLookup() {
- if (Email.DEBUG_LIFECYCLE && Email.DEBUG) {
- Log.d(Logging.LOG_TAG, "startLookForInbox account=" + mAccountId);
- }
- closeMailboxFinder();
- mMailboxFinder = new MailboxFinder(mContext, mAccountId, Mailbox.TYPE_INBOX,
- mMailboxFinderCallback);
- mMailboxFinder.startLookup();
- }
-
private void closeMailboxFinder() {
if (mMailboxFinder != null) {
mMailboxFinder.cancel();
@@ -492,69 +566,104 @@ class MessageListXLFragmentManager {
}
}
- private class MailboxFinderCallback implements MailboxFinder.Callback {
- @Override
- public void onAccountNotFound() {
- if (Email.DEBUG_LIFECYCLE && Email.DEBUG) {
- Log.d(Logging.LOG_TAG, "MailboxFinderCallback.onAccountNotFound");
- }
- // Shouldn't happen
- }
-
- @Override
- public void onAccountSecurityHold(long accountId) {
- if (Email.DEBUG_LIFECYCLE && Email.DEBUG) {
- Log.d(Logging.LOG_TAG, "MailboxFinderCallback.onAccountSecurityHold");
- }
- mTargetActivity.onAccountSecurityHold(accountId);
- }
-
- @Override
- public void onMailboxFound(long accountId, long mailboxId) {
- if (Email.DEBUG_LIFECYCLE && Email.DEBUG) {
- Log.d(Logging.LOG_TAG, " Found inbox");
- }
- selectMailbox(mailboxId, -1);
- }
-
- @Override
- public void onMailboxNotFound(long accountId) {
- if (Email.DEBUG_LIFECYCLE && Email.DEBUG) {
- Log.d(Logging.LOG_TAG, "MailboxFinderCallback.onMailboxNotFound");
- }
- // Shouldn't happen
- }
- }
-
- public void updateMessageCommandButtons(boolean enableMoveToNewer, boolean enableMoveToOlder,
- int currentPosition, int countMessages) {
- mMessageCommandButtons.enableNavigationButtons(enableMoveToNewer, enableMoveToOlder,
- currentPosition, countMessages);
- }
-
private class CommandButtonCallback implements MessageCommandButtonView.Callback {
@Override
public void onMoveToNewer() {
- mTargetActivity.onMoveToNewer();
+ MessageListXLFragmentManager.this.onMoveToNewer();
}
@Override
public void onMoveToOlder() {
- mTargetActivity.onMoveToOlder();
+ MessageListXLFragmentManager.this.onMoveToOlder();
}
}
- private class ThreePaneLayoutCallback implements ThreePaneLayout.Callback {
- @Override
- public void onVisiblePanesChanged(int previousVisiblePanes) {
- updateActionBar();
- final int visiblePanes = mThreePane.getVisiblePanes();
- if (((visiblePanes & ThreePaneLayout.PANE_RIGHT) == 0) &&
- ((previousVisiblePanes & ThreePaneLayout.PANE_RIGHT) != 0)) {
- // Message view just got hidden
- onMessageViewClosed();
- }
- mMessageListFragment.setVisibility((visiblePanes & ThreePaneLayout.PANE_MIDDLE) != 0);
+ private void onCurrentMessageGone() {
+ switch (Preferences.getPreferences(mActivity).getAutoAdvanceDirection()) {
+ case Preferences.AUTO_ADVANCE_NEWER:
+ if (onMoveToNewer()) return;
+ if (onMoveToOlder()) return;
+ break;
+ case Preferences.AUTO_ADVANCE_OLDER:
+ if (onMoveToOlder()) return;
+ if (onMoveToNewer()) return;
+ break;
+ }
+ // Last message in the box or AUTO_ADVANCE_MESSAGE_LIST. Go back to message list.
+ goBackToMailbox();
+ }
+
+ /**
+ * Potentially create a new {@link MessageOrderManager}; if it's not already started or if
+ * the account has changed, and sync it to the current message.
+ */
+ private void updateMessageOrderManager() {
+ if (!isMailboxSelected()) {
+ return;
+ }
+ final long mailboxId = getMailboxId();
+ if (mOrderManager == null || mOrderManager.getMailboxId() != mailboxId) {
+ stopMessageOrderManager();
+ mOrderManager =
+ new MessageOrderManager(mActivity, mailboxId, mMessageOrderManagerCallback);
+ }
+ if (isMessageSelected()) {
+ mOrderManager.moveTo(getMessageId());
}
}
+
+ private class MessageOrderManagerCallback implements MessageOrderManager.Callback {
+ @Override
+ public void onMessagesChanged() {
+ updateNavigationArrows();
+ }
+
+ @Override
+ public void onMessageNotFound() {
+ // Current message gone.
+ goBackToMailbox();
+ }
+ }
+
+ /**
+ * Stop {@link MessageOrderManager}.
+ */
+ private void stopMessageOrderManager() {
+ if (mOrderManager != null) {
+ mOrderManager.close();
+ mOrderManager = null;
+ }
+ }
+
+ /**
+ * Disable/enable the move-to-newer/older buttons.
+ */
+ private void updateNavigationArrows() {
+ if (mOrderManager == null) {
+ // shouldn't happen, but just in case
+ mMessageCommandButtons.enableNavigationButtons(false, false, 0, 0);
+ } else {
+ mMessageCommandButtons.enableNavigationButtons(
+ mOrderManager.canMoveToNewer(), mOrderManager.canMoveToOlder(),
+ mOrderManager.getCurrentPosition(), mOrderManager.getTotalMessageCount());
+ }
+ }
+
+ private boolean onMoveToOlder() {
+ if (isMessageSelected() && (mOrderManager != null)
+ && mOrderManager.moveToOlder()) {
+ selectMessage(mOrderManager.getCurrentMessageId());
+ return true;
+ }
+ return false;
+ }
+
+ private boolean onMoveToNewer() {
+ if (isMessageSelected() && (mOrderManager != null)
+ && mOrderManager.moveToNewer()) {
+ selectMessage(mOrderManager.getCurrentMessageId());
+ return true;
+ }
+ return false;
+ }
}