blob: 09dae1a53137297816dbe87307f974cc3b9f1826 [file] [log] [blame]
/*
* Copyright (C) 2012 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.mail.ui;
import android.app.Fragment;
import android.app.FragmentTransaction;
import android.appwidget.AppWidgetManager;
import android.content.ContentResolver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.DataSetObservable;
import android.database.DataSetObserver;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ListView;
import com.android.bitmap.BitmapCache;
import com.android.mail.R;
import com.android.mail.bitmap.ContactResolver;
import com.android.mail.providers.Account;
import com.android.mail.providers.Folder;
import com.android.mail.providers.FolderWatcher;
import com.android.mail.utils.LogTag;
import com.android.mail.utils.LogUtils;
import com.android.mail.utils.MailObservable;
import com.android.mail.utils.Utils;
import com.android.mail.utils.VeiledAddressMatcher;
import com.android.mail.widget.WidgetProvider;
import java.util.ArrayList;
/**
* This activity displays the list of available folders for the current account.
*/
public class FolderSelectionActivity extends AppCompatActivity implements OnClickListener,
DialogInterface.OnClickListener, ControllableActivity,
FolderSelector {
public static final String EXTRA_ACCOUNT_SHORTCUT = "account-shortcut";
private static final String LOG_TAG = LogTag.getLogTag();
private static final int CONFIGURE = 0;
private static final int VIEW = 1;
private Account mAccount;
private Folder mSelectedFolder;
private boolean mConfigureShortcut;
protected boolean mConfigureWidget;
private int mAppWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID;
private int mMode = -1;
/** Empty placeholder for communicating to the consumer of the drawer observer. */
private final DataSetObservable mFolderOrAccountObservers =
new MailObservable("FolderOrAccount");
private final AccountController mAccountController = new AccountController() {
@Override
public void registerAccountObserver(DataSetObserver observer) {
// Do nothing
}
@Override
public void unregisterAccountObserver(DataSetObserver observer) {
// Do nothing
}
@Override
public Account getAccount() {
return mAccount;
}
@Override
public void registerAllAccountObserver(DataSetObserver observer) {
// Do nothing
}
@Override
public void unregisterAllAccountObserver(DataSetObserver observer) {
// Do nothing
}
@Override
public Account[] getAllAccounts() {
return new Account[]{mAccount};
}
@Override
public VeiledAddressMatcher getVeiledAddressMatcher() {
return null;
}
@Override
public void switchToDefaultInboxOrChangeAccount(Account account) {
// Never gets called, so do nothing here.
LogUtils.wtf(LOG_TAG,"FolderSelectionActivity.switchToDefaultInboxOrChangeAccount() " +
"called when NOT expected.");
}
@Override
public void registerFolderOrAccountChangedObserver(final DataSetObserver observer) {
mFolderOrAccountObservers.registerObserver(observer);
}
@Override
public void unregisterFolderOrAccountChangedObserver(final DataSetObserver observer) {
mFolderOrAccountObservers.unregisterObserver(observer);
}
/**
* Since there is no drawer to wait for, notifyChanged to the observers.
*/
@Override
public void closeDrawer(final boolean hasNewFolderOrAccount,
Account account, Folder folder) {
mFolderOrAccountObservers.notifyChanged();
}
@Override
public void setFolderWatcher(FolderWatcher watcher) {
// Unsupported.
}
@Override
public boolean isDrawerPullEnabled() {
// Unsupported
return false;
}
@Override
public int getFolderListViewChoiceMode() {
return ListView.CHOICE_MODE_NONE;
}
};
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.folders_activity);
final Intent intent = getIntent();
final String action = intent.getAction();
mConfigureShortcut = Intent.ACTION_CREATE_SHORTCUT.equals(action);
mConfigureWidget = AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action);
if (!mConfigureShortcut && !mConfigureWidget) {
LogUtils.wtf(LOG_TAG, "unexpected intent: %s", intent);
}
if (mConfigureShortcut || mConfigureWidget) {
mMode = CONFIGURE;
} else {
mMode = VIEW;
}
if (mConfigureWidget) {
mAppWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID,
AppWidgetManager.INVALID_APPWIDGET_ID);
if (mAppWidgetId == AppWidgetManager.INVALID_APPWIDGET_ID) {
LogUtils.wtf(LOG_TAG, "invalid widgetId");
}
}
mAccount = intent.getParcelableExtra(EXTRA_ACCOUNT_SHORTCUT);
final Button firstButton = (Button) findViewById(R.id.first_button);
firstButton.setVisibility(View.VISIBLE);
// TODO(mindyp) disable the manage folders buttons until we have a manage folders screen.
if (mMode == VIEW) {
firstButton.setEnabled(false);
}
firstButton.setOnClickListener(this);
createFolderListFragment(FolderListFragment.ofTopLevelTree(mAccount.folderListUri,
getExcludedFolderTypes()));
}
/**
* Create a Fragment showing this folder and its children.
*/
private void createFolderListFragment(Fragment fragment) {
final FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.content_pane, fragment);
fragmentTransaction.commitAllowingStateLoss();
}
/**
* Gets an {@link ArrayList} of canonical names of any folders to exclude from displaying.
* By default, this list is empty.
*
* @return An {@link ArrayList} of folder canonical names
*/
protected ArrayList<Integer> getExcludedFolderTypes() {
return new ArrayList<Integer>();
}
@Override
protected void onResume() {
super.onResume();
// TODO: (mindyp) Make sure we're operating on the same account as
// before. If the user switched accounts, switch back.
}
@Override
public void onClick(View v) {
final int id = v.getId();
if (id == R.id.first_button) {
if (mMode == CONFIGURE) {
doCancel();
} else {
// TODO (mindyp): open manage folders screen.
}
}
}
private void doCancel() {
setResult(RESULT_CANCELED);
finish();
}
/**
* Create a widget for the specified account and folder
*/
protected void createWidget(int id, Account account, Folder selectedFolder) {
WidgetProvider.updateWidget(this, id, account, selectedFolder.type,
selectedFolder.capabilities, selectedFolder.folderUri.fullUri,
selectedFolder.conversationListUri, selectedFolder.name);
final Intent result = new Intent();
result.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, id);
setResult(RESULT_OK, result);
finish();
}
@Override
public void onClick(DialogInterface dialog, int which) {
if (which == DialogInterface.BUTTON_POSITIVE) {
// The only dialog that is
createWidget(mAppWidgetId, mAccount, mSelectedFolder);
} else {
doCancel();
}
}
private void onFolderChanged(Folder folder, final boolean force) {
if (!folder.equals(mSelectedFolder)) {
mSelectedFolder = folder;
Intent resultIntent = new Intent();
if (mConfigureShortcut) {
/*
* Create the shortcut Intent based on it with the additional
* information that we have in this activity: name of the
* account, calculate the human readable name of the folder and
* use it as the shortcut name, etc...
*/
final Intent clickIntent = Utils.createViewFolderIntent(this,
mSelectedFolder.folderUri.fullUri, mAccount);
resultIntent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, clickIntent);
resultIntent.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE,
Intent.ShortcutIconResource.fromContext(this,
R.mipmap.ic_launcher_shortcut_folder));
/**
* Note: Email1 created shortcuts using R.mipmap#ic_launcher_email
* so don't delete that resource until we have an upgrade/migration solution
*/
final CharSequence humanFolderName = mSelectedFolder.name;
resultIntent.putExtra(Intent.EXTRA_SHORTCUT_NAME, humanFolderName);
// Now ask the user what name they want for this shortcut. Pass
// the
// shortcut intent that we just created, the user can modify the
// folder in
// ShortcutNameActivity.
final Intent shortcutNameIntent = new Intent(this, ShortcutNameActivity.class);
shortcutNameIntent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY
| Intent.FLAG_ACTIVITY_FORWARD_RESULT);
shortcutNameIntent.putExtra(ShortcutNameActivity.EXTRA_FOLDER_CLICK_INTENT,
resultIntent);
shortcutNameIntent.putExtra(ShortcutNameActivity.EXTRA_SHORTCUT_NAME,
humanFolderName);
startActivity(shortcutNameIntent);
finish();
} else if (mConfigureWidget) {
createWidget(mAppWidgetId, mAccount, mSelectedFolder);
}
}
}
@Override
public Context getActivityContext() {
return this;
}
@Override
public ViewMode getViewMode() {
return null;
}
@Override
public ConversationListCallbacks getListHandler() {
return null;
}
@Override
public ConversationCheckedSet getCheckedSet() {
return null;
}
private Folder mNavigatedFolder;
@Override
public void onFolderSelected(Folder folder) {
if (folder.hasChildren && !folder.equals(mNavigatedFolder)) {
mNavigatedFolder = folder;
// Replace this fragment with a new FolderListFragment
// showing this folder's children if we are not already looking
// at the child view for this folder.
createFolderListFragment(FolderListFragment.ofTree(folder));
return;
}
onFolderChanged(folder, false /* force */);
}
@Override
public FolderSelector getFolderSelector() {
return this;
}
@Override
public void onUndoAvailable(ToastBarOperation undoOp) {
// Do nothing.
}
@Override
public Folder getHierarchyFolder() {
return null;
}
@Override
public ConversationUpdater getConversationUpdater() {
return null;
}
@Override
public ErrorListener getErrorListener() {
return null;
}
@Override
public void setPendingToastOperation(ToastBarOperation op) {
// Do nothing.
}
@Override
public ToastBarOperation getPendingToastOperation() {
return null;
}
@Override
public FolderController getFolderController() {
return null;
}
@Override
public void onAnimationEnd(AnimatedAdapter animatedAdapter) {
}
@Override
public AccountController getAccountController() {
return mAccountController;
}
@Override
public void onFooterViewLoadMoreClick(Folder folder) {
// Unsupported
}
@Override
public RecentFolderController getRecentFolderController() {
// Unsupported
return null;
}
@Override
public DrawerController getDrawerController() {
// Unsupported
return null;
}
@Override
public KeyboardNavigationController getKeyboardNavigationController() {
// Unsupported
return null;
}
@Override
public boolean isAccessibilityEnabled() {
// Unsupported
return true;
}
@Override
public ConversationListHelper getConversationListHelper() {
// Unsupported
return null;
}
@Override
public FragmentLauncher getFragmentLauncher() {
// Unsupported
return null;
}
@Override
public ContactLoaderCallbacks getContactLoaderCallbacks() {
// Unsupported
return null;
}
@Override
public ContactResolver getContactResolver(ContentResolver resolver, BitmapCache bitmapCache) {
// Unsupported
return null;
}
@Override
public BitmapCache getSenderImageCache() {
// Unsupported
return null;
}
@Override
public void resetSenderImageCache() {
// Unsupported
}
@Override
public void showHelp(Account account, int viewMode) {
// Unsupported
}
}