First cut of two pane activity.
How to launch: - Kick "Email 2 Pane" in the app drawer. Major known issues: - When you launches "Email 2 Pane", it starts directly; the logic in Welcom won't be executed. - There's no UI to add accounts. Use the old UI. - There's no way to select non-default accounts. - The on-screen buttons except for older/newer don't work. - No contex menus work. Change-Id: I38374acafafbae62e46f84294a7677e54686cfc2
This commit is contained in:
parent
bab0d45904
commit
d6a2978857
|
@ -4,9 +4,9 @@
|
|||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
@ -66,6 +66,20 @@
|
|||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<!--
|
||||
We show this on the home for the development purpose.
|
||||
STOPSHIP: Remove label, and MAIN/LAUNCHER intent filter.
|
||||
-->
|
||||
<activity
|
||||
android:name=".activity.MessageListXL"
|
||||
android:label="@string/activity_label_2pane"
|
||||
android:theme="@android:style/Theme.WithActionBar"
|
||||
>
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".activity.UpgradeAccounts"
|
||||
android:label="@string/upgrade_accounts_title"
|
||||
|
@ -146,8 +160,8 @@
|
|||
android:launchMode="singleTop"
|
||||
android:theme="@android:style/Theme.WithActionBar" >
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
|
||||
<activity
|
||||
android:name=".activity.AccountShortcutPicker"
|
||||
android:label="@string/app_name"
|
||||
android:enabled="false"
|
||||
|
@ -157,12 +171,12 @@
|
|||
<category android:name="android.intent.category.DEFAULT" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
|
||||
<activity
|
||||
android:name=".activity.MailboxList"
|
||||
android:theme="@android:style/Theme.WithActionBar" >
|
||||
</activity>
|
||||
|
||||
|
||||
<activity
|
||||
android:name=".activity.MessageList"
|
||||
android:theme="@style/ThemeNoTitleBar">
|
||||
|
@ -188,7 +202,7 @@
|
|||
<action android:name="android.intent.action.MAIN" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
|
||||
<activity
|
||||
android:name=".activity.MessageView"
|
||||
android:theme="@android:style/Theme.NoTitleBar" >
|
||||
|
@ -261,12 +275,12 @@
|
|||
android:enabled="false"
|
||||
>
|
||||
</service>
|
||||
|
||||
|
||||
<!--EXCHANGE-REMOVE-SECTION-START-->
|
||||
<!--Required stanza to register the ContactsSyncAdapterService with SyncManager -->
|
||||
<service
|
||||
android:name="com.android.exchange.ContactsSyncAdapterService"
|
||||
android:exported="true">
|
||||
<service
|
||||
android:name="com.android.exchange.ContactsSyncAdapterService"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.content.SyncAdapter" />
|
||||
</intent-filter>
|
||||
|
|
|
@ -0,0 +1,118 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2010 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:orientation="horizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<!-- We put MailboxListFragment here at runtime. -->
|
||||
<FrameLayout
|
||||
android:id="@+id/left_pane"
|
||||
android:layout_width="360dip"
|
||||
android:layout_height="match_parent"
|
||||
/>
|
||||
|
||||
<!--
|
||||
Right pane.
|
||||
Because we need to show buttons for MessageView by ourselves, we need a linear layout here.
|
||||
See also the comment below.
|
||||
-->
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="0dip"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"
|
||||
>
|
||||
<!-- We put MessageList/MessageViewFragment here at runtime. -->
|
||||
<FrameLayout
|
||||
android:id="@+id/right_pane"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dip"
|
||||
android:layout_weight="1" />
|
||||
<!--
|
||||
Bottom buttons
|
||||
These buttons can't be in MessageViewFragment, because the button
|
||||
layout changes on the phone layout.
|
||||
(We can (probably) create a separate layout for XL devices, but not sure if that'd be
|
||||
a good idea, at this point.)
|
||||
|
||||
However, putting these buttons means we have to show/hide them
|
||||
according to the screen state, which means we can't just use the
|
||||
fragment transaction to replace fragments.
|
||||
|
||||
Maybe we should create another fragment, MessageViewWithCommandsFragment,
|
||||
on top of MessageViewFragment.
|
||||
-->
|
||||
<LinearLayout
|
||||
android:id="@+id/message_view_buttons"
|
||||
android:orientation="horizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingTop="5dip"
|
||||
android:paddingLeft="4dip"
|
||||
android:paddingRight="4dip"
|
||||
android:paddingBottom="1dip"
|
||||
android:background="@android:drawable/bottom_bar"
|
||||
android:visibility="gone"
|
||||
>
|
||||
<Button
|
||||
android:id="@+id/delete"
|
||||
android:text="@string/delete_action"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_width="0dip"
|
||||
android:layout_weight="1" />
|
||||
<Button
|
||||
android:id="@+id/unread"
|
||||
android:text="@string/unread_action"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_width="0dip"
|
||||
android:layout_weight="1" />
|
||||
<Button
|
||||
android:id="@+id/reply"
|
||||
android:text="@string/reply_action"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_width="0dip"
|
||||
android:layout_weight="1" />
|
||||
<Button
|
||||
android:id="@+id/reply_all"
|
||||
android:text="@string/reply_all_action"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_width="0dip"
|
||||
android:layout_weight="1" />
|
||||
<Button
|
||||
android:id="@+id/forward"
|
||||
android:text="@string/forward_action"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_width="0dip"
|
||||
android:layout_weight="1" />
|
||||
<Button
|
||||
android:id="@+id/moveToNewer"
|
||||
android:text="@string/message_view_move_to_newer"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_width="0dip"
|
||||
android:layout_weight="1" />
|
||||
<Button
|
||||
android:id="@+id/moveToOlder"
|
||||
android:text="@string/message_view_move_to_older"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_width="0dip"
|
||||
android:layout_weight="1" />
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
|
@ -23,7 +23,7 @@
|
|||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/scrollview"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dip"
|
||||
android:layout_height="match_parent"
|
||||
android:scrollbarStyle="outsideOverlay"
|
||||
android:fadingEdge="none"
|
||||
android:fillViewport="true"
|
||||
|
|
|
@ -737,4 +737,8 @@
|
|||
always a larger value because it represents the limit of displayed results. -->
|
||||
<string name="gal_completed_limited_fmt">First <xliff:g id="results" example="20">%1$d</xliff:g>
|
||||
results from <xliff:g id="domain">%2$s</xliff:g></string>
|
||||
|
||||
<!-- Do Not Translate. STOPSHIP: Dev version only. Remove this. -->
|
||||
<string name="activity_label_2pane">Email 2 Pane</string>
|
||||
|
||||
</resources>
|
||||
|
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* Copyright (C) 2010 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.email.activity;
|
||||
|
||||
import com.android.email.provider.EmailContent.Account;
|
||||
|
||||
import android.content.AsyncTaskLoader;
|
||||
import android.content.Context;
|
||||
|
||||
/**
|
||||
* A Loader to load the default account id asynchronously.
|
||||
*
|
||||
* TODO Test it.
|
||||
*/
|
||||
public class DefaultAccountLoader extends AsyncTaskLoader<Long> {
|
||||
public DefaultAccountLoader(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long loadInBackground() {
|
||||
return Account.getDefaultAccountId(getContext());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() {
|
||||
stopLoading();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startLoading() {
|
||||
cancelLoad();
|
||||
forceLoad();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stopLoading() {
|
||||
cancelLoad();
|
||||
}
|
||||
}
|
|
@ -53,7 +53,7 @@ public class MailboxListFragment extends ListFragment implements OnItemClickList
|
|||
private static final String MESSAGE_MAILBOX_ID_SELECTION = MessageColumns.MAILBOX_KEY + "=?";
|
||||
|
||||
// Account & mailboxes access
|
||||
private long mAccountId;
|
||||
private long mAccountId = -1;
|
||||
private LoadMailboxesTask mLoadMailboxesTask;
|
||||
private MessageCountTask mMessageCountTask;
|
||||
private long mDraftMailboxKey = -1;
|
||||
|
@ -64,6 +64,8 @@ public class MailboxListFragment extends ListFragment implements OnItemClickList
|
|||
private MailboxesAdapter mListAdapter;
|
||||
private Callback mCallback;
|
||||
|
||||
private boolean mStarted;
|
||||
|
||||
/**
|
||||
* Callback interface that owning activities must implement
|
||||
*/
|
||||
|
@ -86,12 +88,10 @@ public class MailboxListFragment extends ListFragment implements OnItemClickList
|
|||
super.onActivityCreated(savedInstanceState);
|
||||
|
||||
mActivity = getActivity();
|
||||
|
||||
ListView listView = getListView();
|
||||
listView.setOnItemClickListener(this);
|
||||
listView.setItemsCanFocus(false);
|
||||
registerForContextMenu(listView);
|
||||
|
||||
mListAdapter = new MailboxesAdapter(mActivity);
|
||||
}
|
||||
|
||||
|
@ -103,6 +103,9 @@ public class MailboxListFragment extends ListFragment implements OnItemClickList
|
|||
public void bindActivityInfo(long accountId, Callback callback) {
|
||||
mAccountId = accountId;
|
||||
mCallback = callback;
|
||||
if (mStarted) {
|
||||
startLoading();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -111,8 +114,8 @@ public class MailboxListFragment extends ListFragment implements OnItemClickList
|
|||
@Override
|
||||
public void onStart() {
|
||||
super.onStart();
|
||||
mLoadMailboxesTask = new LoadMailboxesTask(mAccountId);
|
||||
mLoadMailboxesTask.execute();
|
||||
mStarted = true;
|
||||
startLoading();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -120,6 +123,7 @@ public class MailboxListFragment extends ListFragment implements OnItemClickList
|
|||
*/
|
||||
@Override
|
||||
public void onResume() {
|
||||
mStarted = false;
|
||||
super.onResume();
|
||||
updateMessageCount();
|
||||
}
|
||||
|
@ -139,12 +143,19 @@ public class MailboxListFragment extends ListFragment implements OnItemClickList
|
|||
/**
|
||||
* Called when the fragment is no longer in use.
|
||||
*/
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
|
||||
mListAdapter.changeCursor(null);
|
||||
}
|
||||
}
|
||||
|
||||
private void startLoading() {
|
||||
if (mAccountId != -1) {
|
||||
mLoadMailboxesTask = new LoadMailboxesTask(mAccountId);
|
||||
mLoadMailboxesTask.execute();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This is called via the activity
|
||||
|
|
|
@ -102,6 +102,8 @@ public class MessageListFragment extends ListFragment implements OnItemClickList
|
|||
private int mFirstSelectedItemHeight = -1;
|
||||
private boolean mCanAutoRefresh;
|
||||
|
||||
private boolean mStarted;
|
||||
|
||||
/**
|
||||
* Callback interface that owning activities must implement
|
||||
*/
|
||||
|
@ -166,6 +168,21 @@ public class MessageListFragment extends ListFragment implements OnItemClickList
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart() {
|
||||
super.onStart();
|
||||
mStarted = true;
|
||||
if (mAccountId != -1) {
|
||||
startLoading();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStop() {
|
||||
mStarted = false;
|
||||
super.onStop();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
|
@ -234,8 +251,14 @@ public class MessageListFragment extends ListFragment implements OnItemClickList
|
|||
mAccountId = accountId;
|
||||
mMailboxId = mailboxId;
|
||||
|
||||
if (mStarted) {
|
||||
startLoading();
|
||||
}
|
||||
}
|
||||
|
||||
private void startLoading() {
|
||||
Utility.cancelTaskInterrupt(mLoadMessagesTask);
|
||||
mLoadMessagesTask = new LoadMessagesTask(mailboxId, accountId);
|
||||
mLoadMessagesTask = new LoadMessagesTask(mMailboxId, mAccountId);
|
||||
mLoadMessagesTask.execute();
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,466 @@
|
|||
/*
|
||||
* Copyright (C) 2010 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.email.activity;
|
||||
|
||||
import com.android.email.Email;
|
||||
import com.android.email.R;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.Fragment;
|
||||
import android.app.FragmentTransaction;
|
||||
import android.app.LoaderManager.LoaderCallbacks;
|
||||
import android.content.Context;
|
||||
import android.content.Loader;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
// TODO Where/when/how do we close loaders?? Do we have to? Getting this error:
|
||||
// Finalizing a Cursor that has not been deactivated or closed.
|
||||
// database = /data/data/com.google.android.email/databases/EmailProvider.db,
|
||||
// table = Account, query = SELECT _id, displayName, emailAddress FROM Account
|
||||
|
||||
/**
|
||||
* Two pane activity for XL screen devices.
|
||||
*
|
||||
* TOOD Test it!
|
||||
*/
|
||||
public class MessageListXL extends Activity implements View.OnClickListener {
|
||||
private static final String BUNDLE_KEY_ACCOUNT_ID = "MessageListXl.account_id";
|
||||
private static final String BUNDLE_KEY_MAILBOX_ID = "MessageListXl.mailbox_id";
|
||||
private static final String BUNDLE_KEY_MESSAGE_ID = "MessageListXl.message_id";
|
||||
|
||||
private static final int LOADER_ID_DEFAULT_ACCOUNT = 0;
|
||||
|
||||
private Context mContext;
|
||||
|
||||
private long mAccountId = -1;
|
||||
private long mMailboxId = -1;
|
||||
private long mMessageId = -1;
|
||||
|
||||
private MailboxListFragment mMailboxListFragment;
|
||||
private MessageListFragment mMessageListFragment;
|
||||
private MessageViewFragment mMessageViewFragment;
|
||||
|
||||
private View mMessageViewButtons;
|
||||
private View mMoveToNewer;
|
||||
private View mMoveToOlder;
|
||||
|
||||
private boolean mActivityInitialized;
|
||||
private final ArrayList<Fragment> mRestoredFragments = new ArrayList<Fragment>();
|
||||
private MessageOrderManager mOrderManager;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
setContentView(R.layout.message_list_xl);
|
||||
|
||||
final boolean isRestoring = (savedInstanceState != null);
|
||||
|
||||
mContext = getApplicationContext();
|
||||
|
||||
mMessageViewButtons = findViewById(R.id.message_view_buttons);
|
||||
mMoveToNewer = findViewById(R.id.moveToNewer);
|
||||
mMoveToOlder = findViewById(R.id.moveToOlder);
|
||||
mMoveToNewer.setOnClickListener(this);
|
||||
mMoveToOlder.setOnClickListener(this);
|
||||
|
||||
if (isRestoring) {
|
||||
restoreSavedState(savedInstanceState);
|
||||
}
|
||||
if (mAccountId == -1) {
|
||||
loadDefaultAccount();
|
||||
}
|
||||
// TODO Initialize accounts dropdown.
|
||||
|
||||
mActivityInitialized = true;
|
||||
if (isRestoring) {
|
||||
initRestoredFragments();
|
||||
}
|
||||
}
|
||||
|
||||
private void restoreSavedState(Bundle savedInstanceState) {
|
||||
mAccountId = savedInstanceState.getLong(BUNDLE_KEY_ACCOUNT_ID, -1);
|
||||
mMailboxId = savedInstanceState.getLong(BUNDLE_KEY_MAILBOX_ID, -1);
|
||||
mMessageId = savedInstanceState.getLong(BUNDLE_KEY_MESSAGE_ID, -1);
|
||||
if (Email.DEBUG) {
|
||||
Log.d(Email.LOG_TAG, "MessageListXl: Restoring "
|
||||
+ mAccountId + "," + mMailboxId + "," + mMessageId);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSaveInstanceState(Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
outState.putLong(BUNDLE_KEY_ACCOUNT_ID, mAccountId);
|
||||
outState.putLong(BUNDLE_KEY_MAILBOX_ID, mMailboxId);
|
||||
outState.putLong(BUNDLE_KEY_MESSAGE_ID, mMessageId);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStart() {
|
||||
super.onStart();
|
||||
startMessageOrderManager();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
|
||||
// TODO Add stuff that's done in MessageList.onResume().
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStop() {
|
||||
super.onStop();
|
||||
stopMessageOrderManager();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAttachFragment(Fragment fragment) {
|
||||
if (!mActivityInitialized) {
|
||||
// Fragments are being restored in super.onCreate().
|
||||
// We can't initialize fragments until the activity is initialized, so remember them for
|
||||
// now, and initialize them later in initRestoredFragments().
|
||||
mRestoredFragments.add(fragment);
|
||||
return;
|
||||
}
|
||||
if (Email.DEBUG) {
|
||||
Log.d(Email.LOG_TAG, "MessageListXl.onAttachFragment fragment=" + fragment.getClass());
|
||||
}
|
||||
super.onAttachFragment(fragment);
|
||||
initFragment(fragment);
|
||||
}
|
||||
|
||||
private void initFragment(Fragment fragment) {
|
||||
if (fragment instanceof MailboxListFragment) {
|
||||
initMailboxListFragment((MailboxListFragment) fragment);
|
||||
} else if (fragment instanceof MessageListFragment) {
|
||||
initMessageListFragment((MessageListFragment) fragment);
|
||||
} else if (fragment instanceof MessageViewFragment) {
|
||||
initMessageViewFragment((MessageViewFragment) fragment);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Called from {@link #onCreate}.
|
||||
* Initializes the fragmetns that are restored in super.onCreate().
|
||||
*/
|
||||
private void initRestoredFragments() {
|
||||
for (Fragment f : mRestoredFragments) {
|
||||
initFragment(f);
|
||||
}
|
||||
mRestoredFragments.clear();
|
||||
}
|
||||
|
||||
private void startMessageOrderManager() {
|
||||
if (mMailboxId == -1) {
|
||||
return;
|
||||
}
|
||||
if (mOrderManager != null && mOrderManager.getMailboxId() == mMailboxId) {
|
||||
return;
|
||||
}
|
||||
stopMessageOrderManager();
|
||||
mOrderManager = new MessageOrderManager(this, mMailboxId,
|
||||
new MessageOrderManager.Callback() {
|
||||
@Override
|
||||
public void onMessagesChanged() {
|
||||
updateNavigationArrows();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMessageNotFound() {
|
||||
// Current message removed.
|
||||
selectMailbox(mMailboxId);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void stopMessageOrderManager() {
|
||||
if (mOrderManager != null) {
|
||||
mOrderManager.close();
|
||||
mOrderManager = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void loadDefaultAccount() {
|
||||
getLoaderManager().initLoader(LOADER_ID_DEFAULT_ACCOUNT, null, new LoaderCallbacks<Long>() {
|
||||
@Override
|
||||
public Loader<Long> onCreateLoader(int id, Bundle args) {
|
||||
return new DefaultAccountLoader(mContext);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoadFinished(Loader<Long> loader, Long accountId) {
|
||||
if (Email.DEBUG) {
|
||||
Log.d(Email.LOG_TAG, "Default account=" + accountId);
|
||||
}
|
||||
if (accountId == null || accountId == -1) {
|
||||
onNoAccountFound();
|
||||
} else {
|
||||
selectAccount(accountId);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void onNoAccountFound() {
|
||||
// Open Welcome, which in turn shows the adding a new account screen.
|
||||
Welcome.actionStart(this);
|
||||
finish();
|
||||
return;
|
||||
}
|
||||
|
||||
// NOTE These selectXxx are *not* only methods where mXxxId's are changed.
|
||||
// When the activity is re-created (e.g. for orientation change), the following things happen.
|
||||
// - mXxxId's are restored from Bundle
|
||||
// - Fragments are restored by the framework (in super.onCreate())
|
||||
// - mXxxId's are set to fragments in initXxxFragment()
|
||||
//
|
||||
// So, if you want to do something when, for example, the current account changes,
|
||||
// selectAccount() is probably not a good place to do it, because it'll be skipped when
|
||||
// the activity is re-created.
|
||||
// Instead, do that in initXxxFragment(). Alternatively, adding the same procedure to
|
||||
// initRestoredFragments() too will probably work.
|
||||
|
||||
private void selectAccount(long accountId) {
|
||||
// TODO Handle "combined mailboxes". Who should take care of it? This activity?
|
||||
// MailboxListFragment??
|
||||
if (Email.DEBUG) {
|
||||
Log.d(Email.LOG_TAG, "selectAccount mAccountId=" + mAccountId);
|
||||
}
|
||||
if (accountId == -1) {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
if (mAccountId == accountId) {
|
||||
return;
|
||||
}
|
||||
mAccountId = accountId;
|
||||
mMailboxId = -1;
|
||||
mMessageId = -1;
|
||||
|
||||
// TODO We don't have to replace the fragment, Just update it.
|
||||
// That will be in accordance with our back model.
|
||||
|
||||
final MailboxListFragment fragment = new MailboxListFragment();
|
||||
final FragmentTransaction ft = openFragmentTransaction();
|
||||
ft.replace(R.id.left_pane, fragment);
|
||||
if (mMessageListFragment != null) {
|
||||
ft.remove(mMessageListFragment);
|
||||
}
|
||||
if (mMessageViewFragment != null) {
|
||||
ft.remove(mMessageListFragment);
|
||||
}
|
||||
ft.commit();
|
||||
|
||||
// TODO Open inbox for the selected account.
|
||||
}
|
||||
|
||||
private void selectMailbox(long mailboxId) {
|
||||
if (Email.DEBUG) {
|
||||
Log.d(Email.LOG_TAG, "selectMailbox mMailboxId=" + mMailboxId);
|
||||
}
|
||||
if (mMailboxId == mailboxId) {
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO We don't have to replace the fragment, if it's already the message list. Just
|
||||
// update it.
|
||||
// That will be in accordance with our back model.
|
||||
|
||||
mMailboxId = mailboxId;
|
||||
mMessageId = -1;
|
||||
MessageListFragment fragment = new MessageListFragment();
|
||||
openFragmentTransaction().replace(R.id.right_pane, fragment).commit();
|
||||
}
|
||||
|
||||
private void selectMessage(long messageId) {
|
||||
// TODO: Deal with draft messages. (open MessageCompose instead)
|
||||
if (Email.DEBUG) {
|
||||
Log.d(Email.LOG_TAG, "selectMessage messageId=" + mMessageId);
|
||||
}
|
||||
if (mMessageId == messageId) {
|
||||
return;
|
||||
}
|
||||
mMessageId = messageId;
|
||||
MessageViewFragment fragment = new MessageViewFragment();
|
||||
openFragmentTransaction().replace(R.id.right_pane, fragment).commit();
|
||||
}
|
||||
|
||||
private void initMailboxListFragment(MailboxListFragment fragment) {
|
||||
if (Email.DEBUG) {
|
||||
Log.d(Email.LOG_TAG, "initMailboxListFragment mAccountId=" + mAccountId);
|
||||
}
|
||||
if (mAccountId == -1) {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
mMessageListFragment = null;
|
||||
mMessageViewFragment = null;
|
||||
mMailboxListFragment = fragment;
|
||||
fragment.bindActivityInfo(mAccountId, new MailboxListFragment.Callback() {
|
||||
@Override
|
||||
public void onRefresh(long accountId, long mailboxId) {
|
||||
// Will be removed.
|
||||
}
|
||||
|
||||
// TODO Rename to onSelectMailbox
|
||||
@Override
|
||||
public void onOpen(long accountId, long mailboxId) {
|
||||
selectMailbox(mailboxId);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void initMessageListFragment(MessageListFragment fragment) {
|
||||
if (Email.DEBUG) {
|
||||
Log.d(Email.LOG_TAG, "initMessageListFragment mMailboxId=" + mMailboxId);
|
||||
}
|
||||
if (mAccountId == -1 || mMailboxId == -1) {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
mMessageListFragment = fragment;
|
||||
mMessageViewFragment = null;
|
||||
mMessageViewButtons.setVisibility(View.GONE);
|
||||
fragment.setCallback(new MessageListFragment.Callback() {
|
||||
@Override
|
||||
public void onSelectionChanged() {
|
||||
// TODO Context mode
|
||||
}
|
||||
|
||||
@Override
|
||||
// TODO Rename to onSelectMessage
|
||||
public void onMessageOpen(long messageId, long mailboxId) { // RENAME: OpenMessage ?
|
||||
selectMessage(messageId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMailboxNotFound() { // RENAME: NotExists? (see MessageViewFragment)
|
||||
// TODO: What to do??
|
||||
}
|
||||
});
|
||||
fragment.openMailbox(mAccountId, mMailboxId);
|
||||
}
|
||||
|
||||
private void initMessageViewFragment(MessageViewFragment fragment) {
|
||||
if (Email.DEBUG) {
|
||||
Log.d(Email.LOG_TAG, "initMessageViewFragment messageId=" + mMessageId);
|
||||
}
|
||||
if (mMessageId == -1) {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
mMessageViewFragment = fragment;
|
||||
mMessageListFragment = null;
|
||||
mMessageViewButtons.setVisibility(View.VISIBLE);
|
||||
fragment.setCallback(new MessageViewFragment.Callback() {
|
||||
@Override
|
||||
public boolean onUrlInMessageClicked(String url) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRespondedToInvite(int response) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMessageSetUnread() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMessageNotExists() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoadMessageStarted() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoadMessageFinished() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoadMessageError() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFetchAttachmentStarted(String attachmentName) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFetchAttachmentFinished() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFetchAttachmentError() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCalendarLinkClicked(long epochEventStartTime) {
|
||||
}
|
||||
});
|
||||
fragment.openMessage(mMessageId);
|
||||
startMessageOrderManager();
|
||||
mOrderManager.moveTo(mMessageId);
|
||||
updateNavigationArrows();
|
||||
}
|
||||
|
||||
private void updateNavigationArrows() {
|
||||
mMoveToNewer.setEnabled((mOrderManager != null) && mOrderManager.canMoveToNewer());
|
||||
mMoveToOlder.setEnabled((mOrderManager != null) && mOrderManager.canMoveToOlder());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
switch (view.getId()) {
|
||||
case R.id.moveToOlder:
|
||||
moveToOlder();
|
||||
break;
|
||||
case R.id.moveToNewer:
|
||||
moveToNewer();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean moveToOlder() {
|
||||
if (mOrderManager != null && mOrderManager.moveToOlder()) {
|
||||
mMessageId = mOrderManager.getCurrentMessageId();
|
||||
mMessageViewFragment.openMessage(mMessageId);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean moveToNewer() {
|
||||
if (mOrderManager != null && mOrderManager.moveToNewer()) {
|
||||
mMessageId = mOrderManager.getCurrentMessageId();
|
||||
mMessageViewFragment.openMessage(mMessageId);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -90,6 +90,10 @@ public class MessageOrderManager {
|
|||
startTask();
|
||||
}
|
||||
|
||||
public long getMailboxId() {
|
||||
return mMailboxId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return a {@link Handler} for {@link ContentObserver}.
|
||||
*
|
||||
|
|
|
@ -151,6 +151,8 @@ public class MessageViewFragment extends Fragment implements View.OnClickListene
|
|||
// contains the HTML content as set in WebView.
|
||||
private String mHtmlTextWebView;
|
||||
|
||||
private boolean mStarted;
|
||||
|
||||
/**
|
||||
* Encapsulates known information about a single attachment.
|
||||
*/
|
||||
|
@ -332,6 +334,10 @@ public class MessageViewFragment extends Fragment implements View.OnClickListene
|
|||
@Override
|
||||
public void onStart() {
|
||||
super.onStart();
|
||||
mStarted = true;
|
||||
if (mMessageId != -1 || mFileEmailUri != null) {
|
||||
openMessageInternal();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -346,6 +352,7 @@ public class MessageViewFragment extends Fragment implements View.OnClickListene
|
|||
|
||||
@Override
|
||||
public void onStop() {
|
||||
mStarted = false;
|
||||
super.onStop();
|
||||
}
|
||||
|
||||
|
@ -378,7 +385,9 @@ public class MessageViewFragment extends Fragment implements View.OnClickListene
|
|||
mLoadBodyTask = null;
|
||||
Utility.cancelTaskInterrupt(mLoadAttachmentsTask);
|
||||
mLoadAttachmentsTask = null;
|
||||
mPresenceUpdater.cancelAll();
|
||||
if (mPresenceUpdater != null) {
|
||||
mPresenceUpdater.cancelAll();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -401,7 +410,9 @@ public class MessageViewFragment extends Fragment implements View.OnClickListene
|
|||
mFileEmailUri = null;
|
||||
mMessageId = messageId;
|
||||
mAccountId = -1;
|
||||
openMessageInternal();
|
||||
if (mStarted) {
|
||||
openMessageInternal();
|
||||
}
|
||||
}
|
||||
|
||||
/** Called by activities to a URI to an EML file to open. */
|
||||
|
@ -409,7 +420,9 @@ public class MessageViewFragment extends Fragment implements View.OnClickListene
|
|||
mFileEmailUri = fileEmailUri;
|
||||
mMessageId = -1;
|
||||
mAccountId = -1;
|
||||
openMessageInternal();
|
||||
if (mStarted) {
|
||||
openMessageInternal();
|
||||
}
|
||||
}
|
||||
|
||||
private void openMessageInternal() {
|
||||
|
|
Loading…
Reference in New Issue