111b0bbdf024ec1413f90b2baac2c18a8f1c01d71Mindy Pereira/*
211b0bbdf024ec1413f90b2baac2c18a8f1c01d71Mindy Pereira * Copyright (C) 2010 Google Inc.
311b0bbdf024ec1413f90b2baac2c18a8f1c01d71Mindy Pereira * Licensed to The Android Open Source Project.
411b0bbdf024ec1413f90b2baac2c18a8f1c01d71Mindy Pereira *
511b0bbdf024ec1413f90b2baac2c18a8f1c01d71Mindy Pereira * Licensed under the Apache License, Version 2.0 (the "License");
611b0bbdf024ec1413f90b2baac2c18a8f1c01d71Mindy Pereira * you may not use this file except in compliance with the License.
711b0bbdf024ec1413f90b2baac2c18a8f1c01d71Mindy Pereira * You may obtain a copy of the License at
811b0bbdf024ec1413f90b2baac2c18a8f1c01d71Mindy Pereira *
911b0bbdf024ec1413f90b2baac2c18a8f1c01d71Mindy Pereira *      http://www.apache.org/licenses/LICENSE-2.0
1011b0bbdf024ec1413f90b2baac2c18a8f1c01d71Mindy Pereira *
1111b0bbdf024ec1413f90b2baac2c18a8f1c01d71Mindy Pereira * Unless required by applicable law or agreed to in writing, software
1211b0bbdf024ec1413f90b2baac2c18a8f1c01d71Mindy Pereira * distributed under the License is distributed on an "AS IS" BASIS,
1311b0bbdf024ec1413f90b2baac2c18a8f1c01d71Mindy Pereira * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1411b0bbdf024ec1413f90b2baac2c18a8f1c01d71Mindy Pereira * See the License for the specific language governing permissions and
1511b0bbdf024ec1413f90b2baac2c18a8f1c01d71Mindy Pereira * limitations under the License.
1611b0bbdf024ec1413f90b2baac2c18a8f1c01d71Mindy Pereira */
1711b0bbdf024ec1413f90b2baac2c18a8f1c01d71Mindy Pereira
1811b0bbdf024ec1413f90b2baac2c18a8f1c01d71Mindy Pereirapackage com.android.mail.browse;
1911b0bbdf024ec1413f90b2baac2c18a8f1c01d71Mindy Pereira
20bf232c3735f65b1a4746943e4a134e59e36f0bdePaul Westbrookimport android.content.Context;
21a6b671dd9f5ba358a05888b3ab3bf1c5cb5cf493Marc Blankimport android.net.Uri;
22dd2ec688cf18e0ec132d936168ccaa3c43cdefb1Scott Kennedyimport android.os.AsyncTask;
2352882ff08fe9420fe2dbb3f681545a330222e9c8Andrew Sappersteinimport android.support.v7.view.ActionMode;
24bf232c3735f65b1a4746943e4a134e59e36f0bdePaul Westbrookimport android.view.Menu;
25bf232c3735f65b1a4746943e4a134e59e36f0bdePaul Westbrookimport android.view.MenuInflater;
26bf232c3735f65b1a4746943e4a134e59e36f0bdePaul Westbrookimport android.view.MenuItem;
27a6b671dd9f5ba358a05888b3ab3bf1c5cb5cf493Marc Blankimport android.widget.Toast;
28bf232c3735f65b1a4746943e4a134e59e36f0bdePaul Westbrook
2911b0bbdf024ec1413f90b2baac2c18a8f1c01d71Mindy Pereiraimport com.android.mail.R;
30042a530b2296487fa5899a3e871214ac4a47e3d8Andy Huangimport com.android.mail.analytics.Analytics;
3130d2d329418045d1f6af60877fa14183ec28ead4Mindy Pereiraimport com.android.mail.providers.Account;
327c401b7896910c00e6234e8774aab0be45740d32Vikram Aggarwalimport com.android.mail.providers.AccountObserver;
3311b0bbdf024ec1413f90b2baac2c18a8f1c01d71Mindy Pereiraimport com.android.mail.providers.Conversation;
344f166dead6323b6fd21c76cef66174c6cd4bf11cMindy Pereiraimport com.android.mail.providers.Folder;
35a6b671dd9f5ba358a05888b3ab3bf1c5cb5cf493Marc Blankimport com.android.mail.providers.MailAppProvider;
36efe3d25aa19da172fd5c3ec39539cdd91f29e927Mindy Pereiraimport com.android.mail.providers.Settings;
37f98b318572750dae998a55a60199598933770b68Mindy Pereiraimport com.android.mail.providers.UIProvider;
38ef3625472596326b910a4445307d1a8eb8c9cc3fPaul Westbrookimport com.android.mail.providers.UIProvider.AccountCapabilities;
39cf164d64bcb1da92b427bda99b97f7ec310ef704Marc Blankimport com.android.mail.providers.UIProvider.ConversationColumns;
40bf232c3735f65b1a4746943e4a134e59e36f0bdePaul Westbrookimport com.android.mail.providers.UIProvider.FolderCapabilities;
419ba4251297f1645af2490fcc2dc43f5063e12a29Mindy Pereiraimport com.android.mail.providers.UIProvider.FolderType;
42531488ed848766708252a5fdc01c4ecf0fd167d1Vikram Aggarwalimport com.android.mail.ui.ControllableActivity;
43ec0fa48764bede0772e9c711f3e33361b62f3608Jin Caoimport com.android.mail.ui.ConversationCheckedSet;
44a8e4318bb9921e2ec6045c5f7187a4b78c55fe10Vikram Aggarwalimport com.android.mail.ui.ConversationListCallbacks;
451ddcf0f2bf44d3c9db89112ef52510d9b2433ac4Vikram Aggarwalimport com.android.mail.ui.ConversationSetObserver;
46531488ed848766708252a5fdc01c4ecf0fd167d1Vikram Aggarwalimport com.android.mail.ui.ConversationUpdater;
47a6b671dd9f5ba358a05888b3ab3bf1c5cb5cf493Marc Blankimport com.android.mail.ui.DestructiveAction;
48dd2ec688cf18e0ec132d936168ccaa3c43cdefb1Scott Kennedyimport com.android.mail.ui.FolderOperation;
499eb1c9a76a400f84c002b58c831119119ebf4870Mark Weiimport com.android.mail.ui.FolderSelectionDialog;
50b334c9035e9b7a38766bb66c29da2208525d1e11Paul Westbrookimport com.android.mail.utils.LogTag;
5111b0bbdf024ec1413f90b2baac2c18a8f1c01d71Mindy Pereiraimport com.android.mail.utils.LogUtils;
52efe3d25aa19da172fd5c3ec39539cdd91f29e927Mindy Pereiraimport com.android.mail.utils.Utils;
5311b0bbdf024ec1413f90b2baac2c18a8f1c01d71Mindy Pereiraimport com.google.common.annotations.VisibleForTesting;
54dd2ec688cf18e0ec132d936168ccaa3c43cdefb1Scott Kennedyimport com.google.common.collect.Lists;
5511b0bbdf024ec1413f90b2baac2c18a8f1c01d71Mindy Pereira
5611b0bbdf024ec1413f90b2baac2c18a8f1c01d71Mindy Pereiraimport java.util.Collection;
57dd2ec688cf18e0ec132d936168ccaa3c43cdefb1Scott Kennedyimport java.util.List;
5811b0bbdf024ec1413f90b2baac2c18a8f1c01d71Mindy Pereira
5911b0bbdf024ec1413f90b2baac2c18a8f1c01d71Mindy Pereira/**
6011b0bbdf024ec1413f90b2baac2c18a8f1c01d71Mindy Pereira * A component that displays a custom view for an {@code ActionBar}'s {@code
6111b0bbdf024ec1413f90b2baac2c18a8f1c01d71Mindy Pereira * ContextMode} specific to operating on a set of conversations.
6211b0bbdf024ec1413f90b2baac2c18a8f1c01d71Mindy Pereira */
6311b0bbdf024ec1413f90b2baac2c18a8f1c01d71Mindy Pereirapublic class SelectedConversationsActionMenu implements ActionMode.Callback,
64d503df4f0c31bbf842c6a1d3cba18df8c074bf67Vikram Aggarwal        ConversationSetObserver {
6511b0bbdf024ec1413f90b2baac2c18a8f1c01d71Mindy Pereira
66b334c9035e9b7a38766bb66c29da2208525d1e11Paul Westbrook    private static final String LOG_TAG = LogTag.getLogTag();
6711b0bbdf024ec1413f90b2baac2c18a8f1c01d71Mindy Pereira
6811b0bbdf024ec1413f90b2baac2c18a8f1c01d71Mindy Pereira    /**
6911b0bbdf024ec1413f90b2baac2c18a8f1c01d71Mindy Pereira     * The set of conversations to display the menu for.
7011b0bbdf024ec1413f90b2baac2c18a8f1c01d71Mindy Pereira     */
71ec0fa48764bede0772e9c711f3e33361b62f3608Jin Cao    protected final ConversationCheckedSet mCheckedSet;
7211b0bbdf024ec1413f90b2baac2c18a8f1c01d71Mindy Pereira
73a8e4318bb9921e2ec6045c5f7187a4b78c55fe10Vikram Aggarwal    private final ControllableActivity mActivity;
74a8e4318bb9921e2ec6045c5f7187a4b78c55fe10Vikram Aggarwal    private final ConversationListCallbacks mListController;
75cd8bf0a4c081f95ac8666025adb85d4908c2018aVikram Aggarwal    /**
76cd8bf0a4c081f95ac8666025adb85d4908c2018aVikram Aggarwal     * Context of the activity. A dialog requires the context of an activity rather than the global
77cd8bf0a4c081f95ac8666025adb85d4908c2018aVikram Aggarwal     * root context of the process. So mContext = mActivity.getApplicationContext() will fail.
78cd8bf0a4c081f95ac8666025adb85d4908c2018aVikram Aggarwal     */
7911b0bbdf024ec1413f90b2baac2c18a8f1c01d71Mindy Pereira    private final Context mContext;
8011b0bbdf024ec1413f90b2baac2c18a8f1c01d71Mindy Pereira
8111b0bbdf024ec1413f90b2baac2c18a8f1c01d71Mindy Pereira    @VisibleForTesting
824f4782bcc53e13b30f1fd417beb1a6c04a54faedVikram Aggarwal    private ActionMode mActionMode;
8311b0bbdf024ec1413f90b2baac2c18a8f1c01d71Mindy Pereira
8411b0bbdf024ec1413f90b2baac2c18a8f1c01d71Mindy Pereira    private boolean mActivated = false;
8511b0bbdf024ec1413f90b2baac2c18a8f1c01d71Mindy Pereira
86531488ed848766708252a5fdc01c4ecf0fd167d1Vikram Aggarwal    /** Object that can update conversation state on our behalf. */
87531488ed848766708252a5fdc01c4ecf0fd167d1Vikram Aggarwal    private final ConversationUpdater mUpdater;
8830d2d329418045d1f6af60877fa14183ec28ead4Mindy Pereira
897c401b7896910c00e6234e8774aab0be45740d32Vikram Aggarwal    private Account mAccount;
90d92e9f3d45cfedd3ebfedcf0805283007053e091Mindy Pereira
91531488ed848766708252a5fdc01c4ecf0fd167d1Vikram Aggarwal    private final Folder mFolder;
924f166dead6323b6fd21c76cef66174c6cd4bf11cMindy Pereira
9314f64ec84173e5ee8b7157a74e8d62eff7693c19Mindy Pereira    private AccountObserver mAccountObserver;
9407118a01f7183645957010779222b84930f75b4eMindy Pereira
95512821c11d89d49908f3cfdee0b582601f500f3dJin Cao    private MenuItem mDiscardOutboxMenuItem;
96512821c11d89d49908f3cfdee0b582601f500f3dJin Cao
977704d79def5e5f36a1cbe22fbbe6e9520503899cVikram Aggarwal    public SelectedConversationsActionMenu(
98ec0fa48764bede0772e9c711f3e33361b62f3608Jin Cao            ControllableActivity activity, ConversationCheckedSet checkedSet, Folder folder) {
9911b0bbdf024ec1413f90b2baac2c18a8f1c01d71Mindy Pereira        mActivity = activity;
100a8e4318bb9921e2ec6045c5f7187a4b78c55fe10Vikram Aggarwal        mListController = activity.getListHandler();
101ec0fa48764bede0772e9c711f3e33361b62f3608Jin Cao        mCheckedSet = checkedSet;
10214f64ec84173e5ee8b7157a74e8d62eff7693c19Mindy Pereira        mAccountObserver = new AccountObserver() {
10314f64ec84173e5ee8b7157a74e8d62eff7693c19Mindy Pereira            @Override
10414f64ec84173e5ee8b7157a74e8d62eff7693c19Mindy Pereira            public void onChanged(Account newAccount) {
10514f64ec84173e5ee8b7157a74e8d62eff7693c19Mindy Pereira                mAccount = newAccount;
10614f64ec84173e5ee8b7157a74e8d62eff7693c19Mindy Pereira            }
10714f64ec84173e5ee8b7157a74e8d62eff7693c19Mindy Pereira        };
1087c401b7896910c00e6234e8774aab0be45740d32Vikram Aggarwal        mAccount = mAccountObserver.initialize(activity.getAccountController());
1094f166dead6323b6fd21c76cef66174c6cd4bf11cMindy Pereira        mFolder = folder;
11004dc819886abc2e4f56e644b03449e29cdbae2d0Vikram Aggarwal        mContext = mActivity.getActivityContext();
11154f120f6ada40c7191811dfff99b151e9e192c78mindyp        mUpdater = activity.getConversationUpdater();
112e8a85328eadff76fcd78141f1343bde0a1cd27e7Vikram Aggarwal    }
113e8a85328eadff76fcd78141f1343bde0a1cd27e7Vikram Aggarwal
114a6b45218b8d90d7fc3a5ca0901293c71df404553Jin Cao    public boolean onActionItemClicked(MenuItem item) {
115a6b45218b8d90d7fc3a5ca0901293c71df404553Jin Cao        return onActionItemClicked(mActionMode, item);
116a6b45218b8d90d7fc3a5ca0901293c71df404553Jin Cao    }
117a6b45218b8d90d7fc3a5ca0901293c71df404553Jin Cao
11811b0bbdf024ec1413f90b2baac2c18a8f1c01d71Mindy Pereira    @Override
11911b0bbdf024ec1413f90b2baac2c18a8f1c01d71Mindy Pereira    public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
12011b0bbdf024ec1413f90b2baac2c18a8f1c01d71Mindy Pereira        boolean handled = true;
1218937bf1552a86853efc798a4d8df34c01115cdfdMindy Pereira        // If the user taps a new menu item, commit any existing destructive actions.
122a8e4318bb9921e2ec6045c5f7187a4b78c55fe10Vikram Aggarwal        mListController.commitDestructiveActions(true);
1232b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy        final int itemId = item.getItemId();
124042a530b2296487fa5899a3e871214ac4a47e3d8Andy Huang
1252b55549d4fbe25e91f673a0727fc89ff755d9327Andy Huang        Analytics.getInstance().sendMenuItemEvent(Analytics.EVENT_CATEGORY_MENU_ITEM, itemId,
1262b55549d4fbe25e91f673a0727fc89ff755d9327Andy Huang                "cab_mode", 0);
127042a530b2296487fa5899a3e871214ac4a47e3d8Andy Huang
128f55863727de2bb15f1906944bbc88c82703a3affJin Cao        UndoCallback undoCallback = null;   // not applicable here (yet)
1292b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy        if (itemId == R.id.delete) {
1302b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy            LogUtils.i(LOG_TAG, "Delete selected from CAB menu");
131f55863727de2bb15f1906944bbc88c82703a3affJin Cao            performDestructiveAction(R.id.delete, undoCallback);
1322b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy        } else if (itemId == R.id.discard_drafts) {
133512821c11d89d49908f3cfdee0b582601f500f3dJin Cao            LogUtils.i(LOG_TAG, "Discard drafts selected from CAB menu");
134f55863727de2bb15f1906944bbc88c82703a3affJin Cao            performDestructiveAction(R.id.discard_drafts, undoCallback);
135512821c11d89d49908f3cfdee0b582601f500f3dJin Cao        } else if (itemId == R.id.discard_outbox) {
136512821c11d89d49908f3cfdee0b582601f500f3dJin Cao            LogUtils.i(LOG_TAG, "Discard outbox selected from CAB menu");
137512821c11d89d49908f3cfdee0b582601f500f3dJin Cao            performDestructiveAction(R.id.discard_outbox, undoCallback);
1382b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy        } else if (itemId == R.id.archive) {
1392b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy            LogUtils.i(LOG_TAG, "Archive selected from CAB menu");
140f55863727de2bb15f1906944bbc88c82703a3affJin Cao            performDestructiveAction(R.id.archive, undoCallback);
1412b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy        } else if (itemId == R.id.remove_folder) {
142ec0fa48764bede0772e9c711f3e33361b62f3608Jin Cao            destroy(R.id.remove_folder, mCheckedSet.values(),
143ec0fa48764bede0772e9c711f3e33361b62f3608Jin Cao                    mUpdater.getDeferredRemoveFolder(mCheckedSet.values(), mFolder, true,
144f55863727de2bb15f1906944bbc88c82703a3affJin Cao                            true, true, undoCallback));
1452b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy        } else if (itemId == R.id.mute) {
146ec0fa48764bede0772e9c711f3e33361b62f3608Jin Cao            destroy(R.id.mute, mCheckedSet.values(), mUpdater.getBatchAction(R.id.mute,
147f55863727de2bb15f1906944bbc88c82703a3affJin Cao                    undoCallback));
1482b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy        } else if (itemId == R.id.report_spam) {
149ec0fa48764bede0772e9c711f3e33361b62f3608Jin Cao            destroy(R.id.report_spam, mCheckedSet.values(),
150f55863727de2bb15f1906944bbc88c82703a3affJin Cao                    mUpdater.getBatchAction(R.id.report_spam, undoCallback));
1512b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy        } else if (itemId == R.id.mark_not_spam) {
1522b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy            // Currently, since spam messages are only shown in list with other spam messages,
1532b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy            // marking a message not as spam is a destructive action
1542b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy            destroy (R.id.mark_not_spam,
155ec0fa48764bede0772e9c711f3e33361b62f3608Jin Cao                    mCheckedSet.values(), mUpdater.getBatchAction(R.id.mark_not_spam,
156f55863727de2bb15f1906944bbc88c82703a3affJin Cao                            undoCallback)) ;
1572b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy        } else if (itemId == R.id.report_phishing) {
1582b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy            destroy(R.id.report_phishing,
159ec0fa48764bede0772e9c711f3e33361b62f3608Jin Cao                    mCheckedSet.values(), mUpdater.getBatchAction(R.id.report_phishing,
160f55863727de2bb15f1906944bbc88c82703a3affJin Cao                            undoCallback));
1612b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy        } else if (itemId == R.id.read) {
1622b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy            markConversationsRead(true);
1632b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy        } else if (itemId == R.id.unread) {
1642b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy            markConversationsRead(false);
1652b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy        } else if (itemId == R.id.star) {
1662b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy            starConversations(true);
167a6b45218b8d90d7fc3a5ca0901293c71df404553Jin Cao        } else if (itemId == R.id.toggle_read_unread) {
168a6b45218b8d90d7fc3a5ca0901293c71df404553Jin Cao            if (mActionMode != null) {
169a6b45218b8d90d7fc3a5ca0901293c71df404553Jin Cao                markConversationsRead(mActionMode.getMenu().findItem(R.id.read).isVisible());
170a6b45218b8d90d7fc3a5ca0901293c71df404553Jin Cao            }
1712b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy        } else if (itemId == R.id.remove_star) {
1722b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy            if (mFolder.isType(UIProvider.FolderType.STARRED)) {
1732b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy                LogUtils.d(LOG_TAG, "We are in a starred folder, removing the star");
174f55863727de2bb15f1906944bbc88c82703a3affJin Cao                performDestructiveAction(R.id.remove_star, undoCallback);
1752b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy            } else {
1762b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy                LogUtils.d(LOG_TAG, "Not in a starred folder.");
1772b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy                starConversations(false);
1782b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy            }
1796c570db71b8adc43d7dc2f31e6fa63cf50c1426eAndrew Sapperstein        } else if (itemId == R.id.move_to || itemId == R.id.change_folders) {
1802b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy            boolean cantMove = false;
1812b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy            Account acct = mAccount;
1822b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy            // Special handling for virtual folders
1832b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy            if (mFolder.supportsCapability(FolderCapabilities.IS_VIRTUAL)) {
1842b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy                Uri accountUri = null;
185ec0fa48764bede0772e9c711f3e33361b62f3608Jin Cao                for (Conversation conv: mCheckedSet.values()) {
1862b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy                    if (accountUri == null) {
1872b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy                        accountUri = conv.accountUri;
1882b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy                    } else if (!accountUri.equals(conv.accountUri)) {
1892b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy                        // Tell the user why we can't do this
1902b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy                        Toast.makeText(mContext, R.string.cant_move_or_change_labels,
1912b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy                                Toast.LENGTH_LONG).show();
1922b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy                        cantMove = true;
1932b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy                        return handled;
194a6b671dd9f5ba358a05888b3ab3bf1c5cb5cf493Marc Blank                    }
195a6b671dd9f5ba358a05888b3ab3bf1c5cb5cf493Marc Blank                }
196a6b671dd9f5ba358a05888b3ab3bf1c5cb5cf493Marc Blank                if (!cantMove) {
1972b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy                    // Get the actual account here, so that we display its folders in the dialog
1982b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy                    acct = MailAppProvider.getAccountFromAccountUri(accountUri);
1992b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy                }
2002b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy            }
2012b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy            if (!cantMove) {
2022b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy                final FolderSelectionDialog dialog = FolderSelectionDialog.getInstance(
203ec0fa48764bede0772e9c711f3e33361b62f3608Jin Cao                        acct, mCheckedSet.values(), true, mFolder,
2042b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy                        item.getItemId() == R.id.move_to);
2052b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy                if (dialog != null) {
2062a4be2459962700e1a38ba897de5d2f5913412f5Tony Mantler                    dialog.show(mActivity.getFragmentManager(), null);
2072b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy                }
2082b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy            }
2092b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy        } else if (itemId == R.id.move_to_inbox) {
2102b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy            new AsyncTask<Void, Void, Folder>() {
2112b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy                @Override
2122b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy                protected Folder doInBackground(final Void... params) {
2132b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy                    // Get the "move to" inbox
2142b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy                    return Utils.getFolder(mContext, mAccount.settings.moveToInbox,
2152b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy                            true /* allowHidden */);
216a6b671dd9f5ba358a05888b3ab3bf1c5cb5cf493Marc Blank                }
217dd2ec688cf18e0ec132d936168ccaa3c43cdefb1Scott Kennedy
2182b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy                @Override
2192b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy                protected void onPostExecute(final Folder moveToInbox) {
2202b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy                    final List<FolderOperation> ops = Lists.newArrayListWithCapacity(1);
2212b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy                    // Add inbox
2222b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy                    ops.add(new FolderOperation(moveToInbox, true));
223ec0fa48764bede0772e9c711f3e33361b62f3608Jin Cao                    mUpdater.assignFolder(ops, mCheckedSet.values(), true,
2242b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy                            true /* showUndo */, false /* isMoveTo */);
22504dc819886abc2e4f56e644b03449e29cdbae2d0Vikram Aggarwal                }
2262b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy            }.execute((Void[]) null);
2272b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy        } else if (itemId == R.id.mark_important) {
2282b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy            markConversationsImportant(true);
2292b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy        } else if (itemId == R.id.mark_not_important) {
2302b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy            if (mFolder.supportsCapability(UIProvider.FolderCapabilities.ONLY_IMPORTANT)) {
231f55863727de2bb15f1906944bbc88c82703a3affJin Cao                performDestructiveAction(R.id.mark_not_important, undoCallback);
2322b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy            } else {
2332b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy                markConversationsImportant(false);
2342b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy            }
2352b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy        } else {
2362b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy            handled = false;
23711b0bbdf024ec1413f90b2baac2c18a8f1c01d71Mindy Pereira        }
23811b0bbdf024ec1413f90b2baac2c18a8f1c01d71Mindy Pereira        return handled;
23911b0bbdf024ec1413f90b2baac2c18a8f1c01d71Mindy Pereira    }
24011b0bbdf024ec1413f90b2baac2c18a8f1c01d71Mindy Pereira
241ad6d6282136b54090f1bf80ff5d37056ff5907c8Vikram Aggarwal    /**
242ad6d6282136b54090f1bf80ff5d37056ff5907c8Vikram Aggarwal     * Clear the selection and perform related UI changes to keep the state consistent.
243ad6d6282136b54090f1bf80ff5d37056ff5907c8Vikram Aggarwal     */
244ec0fa48764bede0772e9c711f3e33361b62f3608Jin Cao    private void clearChecked() {
245ec0fa48764bede0772e9c711f3e33361b62f3608Jin Cao        mCheckedSet.clear();
246ad6d6282136b54090f1bf80ff5d37056ff5907c8Vikram Aggarwal    }
247ad6d6282136b54090f1bf80ff5d37056ff5907c8Vikram Aggarwal
24804dc819886abc2e4f56e644b03449e29cdbae2d0Vikram Aggarwal    /**
24904dc819886abc2e4f56e644b03449e29cdbae2d0Vikram Aggarwal     * Update the underlying list adapter and redraw the menus if necessary.
25004dc819886abc2e4f56e644b03449e29cdbae2d0Vikram Aggarwal     */
25104dc819886abc2e4f56e644b03449e29cdbae2d0Vikram Aggarwal    private void updateSelection() {
2524f4782bcc53e13b30f1fd417beb1a6c04a54faedVikram Aggarwal        mUpdater.refreshConversationList();
25304dc819886abc2e4f56e644b03449e29cdbae2d0Vikram Aggarwal        if (mActionMode != null) {
25404dc819886abc2e4f56e644b03449e29cdbae2d0Vikram Aggarwal            // Calling mActivity.invalidateOptionsMenu doesn't have the correct behavior, since
25504dc819886abc2e4f56e644b03449e29cdbae2d0Vikram Aggarwal            // the action mode is not refreshed when activity's options menu is invalidated.
25604dc819886abc2e4f56e644b03449e29cdbae2d0Vikram Aggarwal            // Since we need to refresh our own menu, it is easy to call onPrepareActionMode
25704dc819886abc2e4f56e644b03449e29cdbae2d0Vikram Aggarwal            // directly.
25804dc819886abc2e4f56e644b03449e29cdbae2d0Vikram Aggarwal            onPrepareActionMode(mActionMode, mActionMode.getMenu());
25904dc819886abc2e4f56e644b03449e29cdbae2d0Vikram Aggarwal        }
26004dc819886abc2e4f56e644b03449e29cdbae2d0Vikram Aggarwal    }
26104dc819886abc2e4f56e644b03449e29cdbae2d0Vikram Aggarwal
262f55863727de2bb15f1906944bbc88c82703a3affJin Cao    private void performDestructiveAction(final int action, UndoCallback undoCallback) {
263ec0fa48764bede0772e9c711f3e33361b62f3608Jin Cao        final Collection<Conversation> conversations = mCheckedSet.values();
2646cadbfce032c5f8d61c873d91989bff1fb7cc4e5Vikram Aggarwal        final Settings settings = mAccount.settings;
265121c8b877090e780b4a16d5a14507c3649e61d7fAndy Huang        final boolean showDialog;
266121c8b877090e780b4a16d5a14507c3649e61d7fAndy Huang        // no confirmation dialog by default unless user preference or common sense dictates one
267121c8b877090e780b4a16d5a14507c3649e61d7fAndy Huang        if (action == R.id.discard_drafts) {
268121c8b877090e780b4a16d5a14507c3649e61d7fAndy Huang            // drafts are lost forever, so always confirm
269121c8b877090e780b4a16d5a14507c3649e61d7fAndy Huang            showDialog = true;
270121c8b877090e780b4a16d5a14507c3649e61d7fAndy Huang        } else if (settings != null && (action == R.id.archive || action == R.id.delete)) {
271121c8b877090e780b4a16d5a14507c3649e61d7fAndy Huang            showDialog = (action == R.id.delete) ? settings.confirmDelete : settings.confirmArchive;
272121c8b877090e780b4a16d5a14507c3649e61d7fAndy Huang        } else {
273121c8b877090e780b4a16d5a14507c3649e61d7fAndy Huang            showDialog = false;
274121c8b877090e780b4a16d5a14507c3649e61d7fAndy Huang        }
275efe3d25aa19da172fd5c3ec39539cdd91f29e927Mindy Pereira        if (showDialog) {
276f55863727de2bb15f1906944bbc88c82703a3affJin Cao            mUpdater.makeDialogListener(action, true /* fromSelectedSet */, null /* undoCallback */);
277ef3625472596326b910a4445307d1a8eb8c9cc3fPaul Westbrook            final int resId;
2782b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy            if (action == R.id.delete) {
2792b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy                resId = R.plurals.confirm_delete_conversation;
2802b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy            } else if (action == R.id.discard_drafts) {
2812b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy                resId = R.plurals.confirm_discard_drafts_conversation;
2822b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy            } else {
2832b9d80eb16156173f11a02eae4f770d8c975927cScott Kennedy                resId = R.plurals.confirm_archive_conversation;
284ef3625472596326b910a4445307d1a8eb8c9cc3fPaul Westbrook            }
2856cadbfce032c5f8d61c873d91989bff1fb7cc4e5Vikram Aggarwal            final CharSequence message = Utils.formatPlural(mContext, resId, conversations.size());
2866cadbfce032c5f8d61c873d91989bff1fb7cc4e5Vikram Aggarwal            final ConfirmDialogFragment c = ConfirmDialogFragment.newInstance(message);
287b8c3171710b7f97247fd0c841ce95f5f515ef576Vikram Aggarwal            c.displayDialog(mActivity.getFragmentManager());
288efe3d25aa19da172fd5c3ec39539cdd91f29e927Mindy Pereira        } else {
2896cadbfce032c5f8d61c873d91989bff1fb7cc4e5Vikram Aggarwal            // No need to show the dialog, just make a destructive action and destroy the
2906cadbfce032c5f8d61c873d91989bff1fb7cc4e5Vikram Aggarwal            // selected set immediately.
291b8c3171710b7f97247fd0c841ce95f5f515ef576Vikram Aggarwal            // TODO(viki): Stop using the deferred action here. Use the registered action.
292f55863727de2bb15f1906944bbc88c82703a3affJin Cao            destroy(action, conversations, mUpdater.getDeferredBatchAction(action, undoCallback));
29307118a01f7183645957010779222b84930f75b4eMindy Pereira        }
29407118a01f7183645957010779222b84930f75b4eMindy Pereira    }
29507118a01f7183645957010779222b84930f75b4eMindy Pereira
29684fe99431df3b989dff9b363562f09fd2757b63cVikram Aggarwal    /**
29784fe99431df3b989dff9b363562f09fd2757b63cVikram Aggarwal     * Destroy these conversations through the conversation updater
29884fe99431df3b989dff9b363562f09fd2757b63cVikram Aggarwal     * @param actionId the ID of the action: R.id.archive, R.id.delete, ...
29984fe99431df3b989dff9b363562f09fd2757b63cVikram Aggarwal     * @param target conversations to destroy
30084fe99431df3b989dff9b363562f09fd2757b63cVikram Aggarwal     * @param action the action that performs the destruction
30184fe99431df3b989dff9b363562f09fd2757b63cVikram Aggarwal     */
30284fe99431df3b989dff9b363562f09fd2757b63cVikram Aggarwal    private void destroy(int actionId, final Collection<Conversation> target,
30384fe99431df3b989dff9b363562f09fd2757b63cVikram Aggarwal            final DestructiveAction action) {
304193e05a8c38b87c400ac594b53b54eb211d35602Alice Yang        LogUtils.i(LOG_TAG, "About to remove %d converations", target.size());
305caaeed3837316175111bb16e6b60aeb0d523debfScott Kennedy        mUpdater.delete(actionId, target, action, true);
306efe3d25aa19da172fd5c3ec39539cdd91f29e927Mindy Pereira    }
307efe3d25aa19da172fd5c3ec39539cdd91f29e927Mindy Pereira
3080e091c52d3a0135afb6904f78e06554567bfe591Vikram Aggarwal    /**
3090e091c52d3a0135afb6904f78e06554567bfe591Vikram Aggarwal     * Marks the read state of currently selected conversations (<b>and</b> the backing storage)
3100e091c52d3a0135afb6904f78e06554567bfe591Vikram Aggarwal     * to the value provided here.
3110e091c52d3a0135afb6904f78e06554567bfe591Vikram Aggarwal     * @param read is true if the conversations are to be marked as read, false if they are to be
3120e091c52d3a0135afb6904f78e06554567bfe591Vikram Aggarwal     * marked unread.
3130e091c52d3a0135afb6904f78e06554567bfe591Vikram Aggarwal     */
314febeb5fd53b0041e3d3b74ff6e3ba414475b2b31Mindy Pereira    private void markConversationsRead(boolean read) {
315ec0fa48764bede0772e9c711f3e33361b62f3608Jin Cao        final Collection<Conversation> targets = mCheckedSet.values();
31666bc2aaf76bb0dfa4fc38f8fcbaaf9e413e321ddVikram Aggarwal        // The conversations are marked read but not viewed.
31766bc2aaf76bb0dfa4fc38f8fcbaaf9e413e321ddVikram Aggarwal        mUpdater.markConversationsRead(targets, read, false);
31804dc819886abc2e4f56e644b03449e29cdbae2d0Vikram Aggarwal        updateSelection();
319febeb5fd53b0041e3d3b74ff6e3ba414475b2b31Mindy Pereira    }
320febeb5fd53b0041e3d3b74ff6e3ba414475b2b31Mindy Pereira
3210e091c52d3a0135afb6904f78e06554567bfe591Vikram Aggarwal    /**
3220e091c52d3a0135afb6904f78e06554567bfe591Vikram Aggarwal     * Marks the important state of currently selected conversations (<b>and</b> the backing
3230e091c52d3a0135afb6904f78e06554567bfe591Vikram Aggarwal     * storage) to the value provided here.
3240e091c52d3a0135afb6904f78e06554567bfe591Vikram Aggarwal     * @param important is true if the conversations are to be marked as important, false if they
3250e091c52d3a0135afb6904f78e06554567bfe591Vikram Aggarwal     * are to be marked not important.
3260e091c52d3a0135afb6904f78e06554567bfe591Vikram Aggarwal     */
3277f0a962513503cb01aec093b14c1b48dfae08f12Mindy Pereira    private void markConversationsImportant(boolean important) {
328ec0fa48764bede0772e9c711f3e33361b62f3608Jin Cao        final Collection<Conversation> target = mCheckedSet.values();
32904dc819886abc2e4f56e644b03449e29cdbae2d0Vikram Aggarwal        final int priority = important ? UIProvider.ConversationPriority.HIGH
3307f0a962513503cb01aec093b14c1b48dfae08f12Mindy Pereira                : UIProvider.ConversationPriority.LOW;
3310e091c52d3a0135afb6904f78e06554567bfe591Vikram Aggarwal        mUpdater.updateConversation(target, ConversationColumns.PRIORITY, priority);
3320e091c52d3a0135afb6904f78e06554567bfe591Vikram Aggarwal        // Update the conversations in the selection too.
3330e091c52d3a0135afb6904f78e06554567bfe591Vikram Aggarwal        for (final Conversation c : target) {
3340e091c52d3a0135afb6904f78e06554567bfe591Vikram Aggarwal            c.priority = priority;
3350e091c52d3a0135afb6904f78e06554567bfe591Vikram Aggarwal        }
33604dc819886abc2e4f56e644b03449e29cdbae2d0Vikram Aggarwal        updateSelection();
3377f0a962513503cb01aec093b14c1b48dfae08f12Mindy Pereira    }
3387f0a962513503cb01aec093b14c1b48dfae08f12Mindy Pereira
33904dc819886abc2e4f56e644b03449e29cdbae2d0Vikram Aggarwal    /**
3400e091c52d3a0135afb6904f78e06554567bfe591Vikram Aggarwal     * Marks the selected conversations with the star setting provided here.
34104dc819886abc2e4f56e644b03449e29cdbae2d0Vikram Aggarwal     * @param star true if you want all the conversations to have stars, false if you want to remove
34204dc819886abc2e4f56e644b03449e29cdbae2d0Vikram Aggarwal     * stars from all conversations
34304dc819886abc2e4f56e644b03449e29cdbae2d0Vikram Aggarwal     */
344febeb5fd53b0041e3d3b74ff6e3ba414475b2b31Mindy Pereira    private void starConversations(boolean star) {
345ec0fa48764bede0772e9c711f3e33361b62f3608Jin Cao        final Collection<Conversation> target = mCheckedSet.values();
3460e091c52d3a0135afb6904f78e06554567bfe591Vikram Aggarwal        mUpdater.updateConversation(target, ConversationColumns.STARRED, star);
3470e091c52d3a0135afb6904f78e06554567bfe591Vikram Aggarwal        // Update the conversations in the selection too.
3480e091c52d3a0135afb6904f78e06554567bfe591Vikram Aggarwal        for (final Conversation c : target) {
3490e091c52d3a0135afb6904f78e06554567bfe591Vikram Aggarwal            c.starred = star;
3500e091c52d3a0135afb6904f78e06554567bfe591Vikram Aggarwal        }
35104dc819886abc2e4f56e644b03449e29cdbae2d0Vikram Aggarwal        updateSelection();
352febeb5fd53b0041e3d3b74ff6e3ba414475b2b31Mindy Pereira    }
353febeb5fd53b0041e3d3b74ff6e3ba414475b2b31Mindy Pereira
35411b0bbdf024ec1413f90b2baac2c18a8f1c01d71Mindy Pereira    @Override
35511b0bbdf024ec1413f90b2baac2c18a8f1c01d71Mindy Pereira    public boolean onCreateActionMode(ActionMode mode, Menu menu) {
356ec0fa48764bede0772e9c711f3e33361b62f3608Jin Cao        mCheckedSet.addObserver(this);
3577f602f7a64f176894ccb7942a6642f22584c3894Vikram Aggarwal        final MenuInflater inflater = mActivity.getMenuInflater();
35811b0bbdf024ec1413f90b2baac2c18a8f1c01d71Mindy Pereira        inflater.inflate(R.menu.conversation_list_selection_actions_menu, menu);
35911b0bbdf024ec1413f90b2baac2c18a8f1c01d71Mindy Pereira        mActionMode = mode;
360db861e9f08677da6d685d9cffc9072d2f98c0944Andrew Sapperstein        updateCount();
36111b0bbdf024ec1413f90b2baac2c18a8f1c01d71Mindy Pereira        return true;
36211b0bbdf024ec1413f90b2baac2c18a8f1c01d71Mindy Pereira    }
36311b0bbdf024ec1413f90b2baac2c18a8f1c01d71Mindy Pereira
36411b0bbdf024ec1413f90b2baac2c18a8f1c01d71Mindy Pereira    @Override
36511b0bbdf024ec1413f90b2baac2c18a8f1c01d71Mindy Pereira    public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
366e5e917c10cbc4afd31358c0425954e2c27e0fb8eVikram Aggarwal        // Update the actionbar to select operations available on the current conversation.
367ec0fa48764bede0772e9c711f3e33361b62f3608Jin Cao        final Collection<Conversation> conversations = mCheckedSet.values();
368febeb5fd53b0041e3d3b74ff6e3ba414475b2b31Mindy Pereira        boolean showStar = false;
369febeb5fd53b0041e3d3b74ff6e3ba414475b2b31Mindy Pereira        boolean showMarkUnread = false;
3707f0a962513503cb01aec093b14c1b48dfae08f12Mindy Pereira        boolean showMarkImportant = false;
37177eee625cd8c317c605acfd06cd3a7e22120a0fdPaul Westbrook        boolean showMarkNotSpam = false;
37276b2062b8c6d18a7b3a05292c385b47b0fcbd09fPaul Westbrook        boolean showMarkAsPhishing = false;
3737f0a962513503cb01aec093b14c1b48dfae08f12Mindy Pereira
3741e5bccefa627306120fbfd783838e1ef8b7fe0d8Jin Cao        // TODO(shahrk): Clean up these dirty calls using Utils.setMenuItemPresent(...) or
37569419bb35240747d14765d4c74d4c2de58f4f8c5Rohan Shah        // in another way
37669419bb35240747d14765d4c74d4c2de58f4f8c5Rohan Shah
377febeb5fd53b0041e3d3b74ff6e3ba414475b2b31Mindy Pereira        for (Conversation conversation : conversations) {
378febeb5fd53b0041e3d3b74ff6e3ba414475b2b31Mindy Pereira            if (!conversation.starred) {
379febeb5fd53b0041e3d3b74ff6e3ba414475b2b31Mindy Pereira                showStar = true;
380febeb5fd53b0041e3d3b74ff6e3ba414475b2b31Mindy Pereira            }
381febeb5fd53b0041e3d3b74ff6e3ba414475b2b31Mindy Pereira            if (conversation.read) {
382febeb5fd53b0041e3d3b74ff6e3ba414475b2b31Mindy Pereira                showMarkUnread = true;
383febeb5fd53b0041e3d3b74ff6e3ba414475b2b31Mindy Pereira            }
3847f0a962513503cb01aec093b14c1b48dfae08f12Mindy Pereira            if (!conversation.isImportant()) {
3857f0a962513503cb01aec093b14c1b48dfae08f12Mindy Pereira                showMarkImportant = true;
3867f0a962513503cb01aec093b14c1b48dfae08f12Mindy Pereira            }
38777eee625cd8c317c605acfd06cd3a7e22120a0fdPaul Westbrook            if (conversation.spam) {
38877eee625cd8c317c605acfd06cd3a7e22120a0fdPaul Westbrook                showMarkNotSpam = true;
38977eee625cd8c317c605acfd06cd3a7e22120a0fdPaul Westbrook            }
39076b2062b8c6d18a7b3a05292c385b47b0fcbd09fPaul Westbrook            if (!conversation.phishing) {
39176b2062b8c6d18a7b3a05292c385b47b0fcbd09fPaul Westbrook                showMarkAsPhishing = true;
39276b2062b8c6d18a7b3a05292c385b47b0fcbd09fPaul Westbrook            }
39376b2062b8c6d18a7b3a05292c385b47b0fcbd09fPaul Westbrook            if (showStar && showMarkUnread && showMarkImportant && showMarkNotSpam &&
39476b2062b8c6d18a7b3a05292c385b47b0fcbd09fPaul Westbrook                    showMarkAsPhishing) {
395febeb5fd53b0041e3d3b74ff6e3ba414475b2b31Mindy Pereira                break;
396febeb5fd53b0041e3d3b74ff6e3ba414475b2b31Mindy Pereira            }
397febeb5fd53b0041e3d3b74ff6e3ba414475b2b31Mindy Pereira        }
398ec86c424934205dcbc21078543be116d50e1b183Tony Mantler        final boolean canStar = mFolder != null && !mFolder.isTrash();
399334e64af904085984cdcbecbcbc18cf488a9ceaePaul Westbrook        final MenuItem star = menu.findItem(R.id.star);
400ec86c424934205dcbc21078543be116d50e1b183Tony Mantler        star.setVisible(showStar && canStar);
401334e64af904085984cdcbecbcbc18cf488a9ceaePaul Westbrook        final MenuItem unstar = menu.findItem(R.id.remove_star);
402ec86c424934205dcbc21078543be116d50e1b183Tony Mantler        unstar.setVisible(!showStar && canStar);
403334e64af904085984cdcbecbcbc18cf488a9ceaePaul Westbrook        final MenuItem read = menu.findItem(R.id.read);
404febeb5fd53b0041e3d3b74ff6e3ba414475b2b31Mindy Pereira        read.setVisible(!showMarkUnread);
405334e64af904085984cdcbecbcbc18cf488a9ceaePaul Westbrook        final MenuItem unread = menu.findItem(R.id.unread);
406febeb5fd53b0041e3d3b74ff6e3ba414475b2b31Mindy Pereira        unread.setVisible(showMarkUnread);
407a6b45218b8d90d7fc3a5ca0901293c71df404553Jin Cao
4089ba4251297f1645af2490fcc2dc43f5063e12a29Mindy Pereira        // We only ever show one of:
4099ba4251297f1645af2490fcc2dc43f5063e12a29Mindy Pereira        // 1) remove folder
4109ba4251297f1645af2490fcc2dc43f5063e12a29Mindy Pereira        // 2) archive
41101f30509c4c8ad0d13b7635447b7f023c7a0cab7Mindy Pereira        final MenuItem removeFolder = menu.findItem(R.id.remove_folder);
412aab9bc71f2d8742128361dff72f77543f81dde52Rohan Shah        final MenuItem moveTo = menu.findItem(R.id.move_to);
413dd2ec688cf18e0ec132d936168ccaa3c43cdefb1Scott Kennedy        final MenuItem moveToInbox = menu.findItem(R.id.move_to_inbox);
4148c1058ee75ec4a5824a68c3c5275bc48d56bbad8Scott Kennedy        final boolean showRemoveFolder = mFolder != null && mFolder.isType(FolderType.DEFAULT)
4159ba4251297f1645af2490fcc2dc43f5063e12a29Mindy Pereira                && mFolder.supportsCapability(FolderCapabilities.CAN_ACCEPT_MOVED_MESSAGES)
41653b34250c0029ac3dae4c72822f79d9fad85caa4Tony Mantler                && !mFolder.isProviderFolder()
41753b34250c0029ac3dae4c72822f79d9fad85caa4Tony Mantler                && mAccount.supportsCapability(AccountCapabilities.ARCHIVE);
418aab9bc71f2d8742128361dff72f77543f81dde52Rohan Shah        final boolean showMoveTo = mFolder != null
419aab9bc71f2d8742128361dff72f77543f81dde52Rohan Shah                && mFolder.supportsCapability(FolderCapabilities.ALLOWS_REMOVE_CONVERSATION);
420dd2ec688cf18e0ec132d936168ccaa3c43cdefb1Scott Kennedy        final boolean showMoveToInbox = mFolder != null
421dd2ec688cf18e0ec132d936168ccaa3c43cdefb1Scott Kennedy                && mFolder.supportsCapability(FolderCapabilities.ALLOWS_MOVE_TO_INBOX);
4229ba4251297f1645af2490fcc2dc43f5063e12a29Mindy Pereira        removeFolder.setVisible(showRemoveFolder);
42328f3d5c247927890a45880345b4bf6788f29a820Scott Kennedy        moveTo.setVisible(showMoveTo);
424dd2ec688cf18e0ec132d936168ccaa3c43cdefb1Scott Kennedy        moveToInbox.setVisible(showMoveToInbox);
425dd2ec688cf18e0ec132d936168ccaa3c43cdefb1Scott Kennedy
42669419bb35240747d14765d4c74d4c2de58f4f8c5Rohan Shah        final MenuItem changeFolders = menu.findItem(R.id.change_folders);
42769419bb35240747d14765d4c74d4c2de58f4f8c5Rohan Shah        changeFolders.setVisible(mAccount.supportsCapability(
42869419bb35240747d14765d4c74d4c2de58f4f8c5Rohan Shah                UIProvider.AccountCapabilities.MULTIPLE_FOLDERS_PER_CONV));
42969419bb35240747d14765d4c74d4c2de58f4f8c5Rohan Shah
4309ba4251297f1645af2490fcc2dc43f5063e12a29Mindy Pereira        if (mFolder != null && showRemoveFolder) {
43101f30509c4c8ad0d13b7635447b7f023c7a0cab7Mindy Pereira            removeFolder.setTitle(mActivity.getActivityContext().getString(R.string.remove_folder,
43201f30509c4c8ad0d13b7635447b7f023c7a0cab7Mindy Pereira                    mFolder.name));
43301f30509c4c8ad0d13b7635447b7f023c7a0cab7Mindy Pereira        }
4349ba4251297f1645af2490fcc2dc43f5063e12a29Mindy Pereira        final MenuItem archive = menu.findItem(R.id.archive);
4353047a9f03d9febaf2aba1e5ea0827e0b740d1ab2Andrew Sapperstein        if (archive != null) {
4363047a9f03d9febaf2aba1e5ea0827e0b740d1ab2Andrew Sapperstein            archive.setVisible(
4373047a9f03d9febaf2aba1e5ea0827e0b740d1ab2Andrew Sapperstein                    mAccount.supportsCapability(UIProvider.AccountCapabilities.ARCHIVE) &&
4383047a9f03d9febaf2aba1e5ea0827e0b740d1ab2Andrew Sapperstein                    mFolder.supportsCapability(FolderCapabilities.ARCHIVE));
43950cfeda191d0744d61d278890763c8d261389e03Mindy Pereira        }
440334e64af904085984cdcbecbcbc18cf488a9ceaePaul Westbrook        final MenuItem spam = menu.findItem(R.id.report_spam);
4419ba4251297f1645af2490fcc2dc43f5063e12a29Mindy Pereira        spam.setVisible(!showMarkNotSpam
4429ba4251297f1645af2490fcc2dc43f5063e12a29Mindy Pereira                && mAccount.supportsCapability(UIProvider.AccountCapabilities.REPORT_SPAM)
4439ba4251297f1645af2490fcc2dc43f5063e12a29Mindy Pereira                && mFolder.supportsCapability(FolderCapabilities.REPORT_SPAM));
44477eee625cd8c317c605acfd06cd3a7e22120a0fdPaul Westbrook        final MenuItem notSpam = menu.findItem(R.id.mark_not_spam);
44577eee625cd8c317c605acfd06cd3a7e22120a0fdPaul Westbrook        notSpam.setVisible(showMarkNotSpam &&
44677eee625cd8c317c605acfd06cd3a7e22120a0fdPaul Westbrook                mAccount.supportsCapability(UIProvider.AccountCapabilities.REPORT_SPAM) &&
44777eee625cd8c317c605acfd06cd3a7e22120a0fdPaul Westbrook                mFolder.supportsCapability(FolderCapabilities.MARK_NOT_SPAM));
44876b2062b8c6d18a7b3a05292c385b47b0fcbd09fPaul Westbrook        final MenuItem phishing = menu.findItem(R.id.report_phishing);
44976b2062b8c6d18a7b3a05292c385b47b0fcbd09fPaul Westbrook        phishing.setVisible(showMarkAsPhishing &&
45076b2062b8c6d18a7b3a05292c385b47b0fcbd09fPaul Westbrook                mAccount.supportsCapability(UIProvider.AccountCapabilities.REPORT_PHISHING) &&
45176b2062b8c6d18a7b3a05292c385b47b0fcbd09fPaul Westbrook                mFolder.supportsCapability(FolderCapabilities.REPORT_PHISHING));
45276b2062b8c6d18a7b3a05292c385b47b0fcbd09fPaul Westbrook
453334e64af904085984cdcbecbcbc18cf488a9ceaePaul Westbrook        final MenuItem mute = menu.findItem(R.id.mute);
45450cfeda191d0744d61d278890763c8d261389e03Mindy Pereira        if (mute != null) {
45550cfeda191d0744d61d278890763c8d261389e03Mindy Pereira            mute.setVisible(mAccount.supportsCapability(UIProvider.AccountCapabilities.MUTE)
456962a6922af499db189ace88ed3ba518946764197Scott Kennedy                    && (mFolder != null && mFolder.isInbox()));
45750cfeda191d0744d61d278890763c8d261389e03Mindy Pereira        }
4587f0a962513503cb01aec093b14c1b48dfae08f12Mindy Pereira        final MenuItem markImportant = menu.findItem(R.id.mark_important);
4597f0a962513503cb01aec093b14c1b48dfae08f12Mindy Pereira        markImportant.setVisible(showMarkImportant
4607f0a962513503cb01aec093b14c1b48dfae08f12Mindy Pereira                && mAccount.supportsCapability(UIProvider.AccountCapabilities.MARK_IMPORTANT));
4617f0a962513503cb01aec093b14c1b48dfae08f12Mindy Pereira        final MenuItem markNotImportant = menu.findItem(R.id.mark_not_important);
4627f0a962513503cb01aec093b14c1b48dfae08f12Mindy Pereira        markNotImportant.setVisible(!showMarkImportant
4637f0a962513503cb01aec093b14c1b48dfae08f12Mindy Pereira                && mAccount.supportsCapability(UIProvider.AccountCapabilities.MARK_IMPORTANT));
464512821c11d89d49908f3cfdee0b582601f500f3dJin Cao
465512821c11d89d49908f3cfdee0b582601f500f3dJin Cao        boolean shouldShowDiscardOutbox = mFolder != null && mFolder.isType(FolderType.OUTBOX);
466512821c11d89d49908f3cfdee0b582601f500f3dJin Cao        mDiscardOutboxMenuItem = menu.findItem(R.id.discard_outbox);
467512821c11d89d49908f3cfdee0b582601f500f3dJin Cao        if (mDiscardOutboxMenuItem != null) {
468512821c11d89d49908f3cfdee0b582601f500f3dJin Cao            mDiscardOutboxMenuItem.setVisible(shouldShowDiscardOutbox);
469512821c11d89d49908f3cfdee0b582601f500f3dJin Cao        }
470512821c11d89d49908f3cfdee0b582601f500f3dJin Cao        final boolean showDelete = mFolder != null && !mFolder.isType(FolderType.OUTBOX)
471ef3625472596326b910a4445307d1a8eb8c9cc3fPaul Westbrook                && mFolder.supportsCapability(UIProvider.FolderCapabilities.DELETE);
472b807337282fb19d1a38cdbe092a2f472b0e30321Mindy Pereira        final MenuItem trash = menu.findItem(R.id.delete);
473ef3625472596326b910a4445307d1a8eb8c9cc3fPaul Westbrook        trash.setVisible(showDelete);
474ef3625472596326b910a4445307d1a8eb8c9cc3fPaul Westbrook        // We only want to show the discard drafts menu item if we are not showing the delete menu
475ef3625472596326b910a4445307d1a8eb8c9cc3fPaul Westbrook        // item, and the current folder is a draft folder and the account supports discarding
476ef3625472596326b910a4445307d1a8eb8c9cc3fPaul Westbrook        // drafts for a conversation
477ef3625472596326b910a4445307d1a8eb8c9cc3fPaul Westbrook        final boolean showDiscardDrafts = !showDelete && mFolder != null && mFolder.isDraft() &&
478ef3625472596326b910a4445307d1a8eb8c9cc3fPaul Westbrook                mAccount.supportsCapability(AccountCapabilities.DISCARD_CONVERSATION_DRAFTS);
479ef3625472596326b910a4445307d1a8eb8c9cc3fPaul Westbrook        final MenuItem discardDrafts = menu.findItem(R.id.discard_drafts);
480ef3625472596326b910a4445307d1a8eb8c9cc3fPaul Westbrook        if (discardDrafts != null) {
481ef3625472596326b910a4445307d1a8eb8c9cc3fPaul Westbrook            discardDrafts.setVisible(showDiscardDrafts);
482ef3625472596326b910a4445307d1a8eb8c9cc3fPaul Westbrook        }
483ef3625472596326b910a4445307d1a8eb8c9cc3fPaul Westbrook
48411b0bbdf024ec1413f90b2baac2c18a8f1c01d71Mindy Pereira        return true;
48511b0bbdf024ec1413f90b2baac2c18a8f1c01d71Mindy Pereira    }
48611b0bbdf024ec1413f90b2baac2c18a8f1c01d71Mindy Pereira
48711b0bbdf024ec1413f90b2baac2c18a8f1c01d71Mindy Pereira    @Override
48811b0bbdf024ec1413f90b2baac2c18a8f1c01d71Mindy Pereira    public void onDestroyActionMode(ActionMode mode) {
48911b0bbdf024ec1413f90b2baac2c18a8f1c01d71Mindy Pereira        mActionMode = null;
49011b0bbdf024ec1413f90b2baac2c18a8f1c01d71Mindy Pereira        // The action mode may have been destroyed due to this menu being deactivated, in which
49111b0bbdf024ec1413f90b2baac2c18a8f1c01d71Mindy Pereira        // case resources need not be cleaned up. However, if it was destroyed while this menu is
49211b0bbdf024ec1413f90b2baac2c18a8f1c01d71Mindy Pereira        // active, that implies the user hit "Done" in the top right, and resources need cleaning.
49311b0bbdf024ec1413f90b2baac2c18a8f1c01d71Mindy Pereira        if (mActivated) {
49411b0bbdf024ec1413f90b2baac2c18a8f1c01d71Mindy Pereira            destroy();
49554f120f6ada40c7191811dfff99b151e9e192c78mindyp            // Only commit destructive actions if the user actually pressed
49654f120f6ada40c7191811dfff99b151e9e192c78mindyp            // done; otherwise, this was handled when we toggled conversation
49754f120f6ada40c7191811dfff99b151e9e192c78mindyp            // selection state.
498ff8553f20964f4c31b0c503a9e1daff6ae08a9c7Scott Kennedy            mActivity.getListHandler().commitDestructiveActions(true);
49911b0bbdf024ec1413f90b2baac2c18a8f1c01d71Mindy Pereira        }
50011b0bbdf024ec1413f90b2baac2c18a8f1c01d71Mindy Pereira    }
50111b0bbdf024ec1413f90b2baac2c18a8f1c01d71Mindy Pereira
50211b0bbdf024ec1413f90b2baac2c18a8f1c01d71Mindy Pereira    @Override
503ec0fa48764bede0772e9c711f3e33361b62f3608Jin Cao    public void onSetPopulated(ConversationCheckedSet set) {
50411b0bbdf024ec1413f90b2baac2c18a8f1c01d71Mindy Pereira        // Noop. This object can only exist while the set is non-empty.
50511b0bbdf024ec1413f90b2baac2c18a8f1c01d71Mindy Pereira    }
50611b0bbdf024ec1413f90b2baac2c18a8f1c01d71Mindy Pereira
50711b0bbdf024ec1413f90b2baac2c18a8f1c01d71Mindy Pereira    @Override
5081ddcf0f2bf44d3c9db89112ef52510d9b2433ac4Vikram Aggarwal    public void onSetEmpty() {
509ad6d6282136b54090f1bf80ff5d37056ff5907c8Vikram Aggarwal        LogUtils.d(LOG_TAG, "onSetEmpty called.");
51011b0bbdf024ec1413f90b2baac2c18a8f1c01d71Mindy Pereira        destroy();
51111b0bbdf024ec1413f90b2baac2c18a8f1c01d71Mindy Pereira    }
51211b0bbdf024ec1413f90b2baac2c18a8f1c01d71Mindy Pereira
51311b0bbdf024ec1413f90b2baac2c18a8f1c01d71Mindy Pereira    @Override
514ec0fa48764bede0772e9c711f3e33361b62f3608Jin Cao    public void onSetChanged(ConversationCheckedSet set) {
51511b0bbdf024ec1413f90b2baac2c18a8f1c01d71Mindy Pereira        // If the set is empty, the menu buttons are invalid and most like the menu will be cleaned
51611b0bbdf024ec1413f90b2baac2c18a8f1c01d71Mindy Pereira        // up. Avoid making any changes to stop flickering ("Add Star" -> "Remove Star") just
51711b0bbdf024ec1413f90b2baac2c18a8f1c01d71Mindy Pereira        // before hiding the menu.
51811b0bbdf024ec1413f90b2baac2c18a8f1c01d71Mindy Pereira        if (set.isEmpty()) {
51911b0bbdf024ec1413f90b2baac2c18a8f1c01d71Mindy Pereira            return;
52011b0bbdf024ec1413f90b2baac2c18a8f1c01d71Mindy Pereira        }
521db861e9f08677da6d685d9cffc9072d2f98c0944Andrew Sapperstein        updateCount();
52211b0bbdf024ec1413f90b2baac2c18a8f1c01d71Mindy Pereira    }
52311b0bbdf024ec1413f90b2baac2c18a8f1c01d71Mindy Pereira
52411b0bbdf024ec1413f90b2baac2c18a8f1c01d71Mindy Pereira    /**
525db861e9f08677da6d685d9cffc9072d2f98c0944Andrew Sapperstein     * Updates the visible count of how many conversations are selected.
526db861e9f08677da6d685d9cffc9072d2f98c0944Andrew Sapperstein     */
527db861e9f08677da6d685d9cffc9072d2f98c0944Andrew Sapperstein    private void updateCount() {
528db861e9f08677da6d685d9cffc9072d2f98c0944Andrew Sapperstein        if (mActionMode != null) {
529e64d20ca9e541ef9f48b31bd5ae92fa02b64327aAndrew Sapperstein            mActionMode.setTitle(String.format("%d", mCheckedSet.size()));
530db861e9f08677da6d685d9cffc9072d2f98c0944Andrew Sapperstein        }
531db861e9f08677da6d685d9cffc9072d2f98c0944Andrew Sapperstein    }
532db861e9f08677da6d685d9cffc9072d2f98c0944Andrew Sapperstein
533db861e9f08677da6d685d9cffc9072d2f98c0944Andrew Sapperstein    /**
534e128fc21fab03f6d66c656efeee2155fab449a7fVikram Aggarwal     * Activates and shows this menu (essentially starting an {@link ActionMode}) if the selected
535e128fc21fab03f6d66c656efeee2155fab449a7fVikram Aggarwal     * set is non-empty.
53611b0bbdf024ec1413f90b2baac2c18a8f1c01d71Mindy Pereira     */
53711b0bbdf024ec1413f90b2baac2c18a8f1c01d71Mindy Pereira    public void activate() {
538ec0fa48764bede0772e9c711f3e33361b62f3608Jin Cao        if (mCheckedSet.isEmpty()) {
539e128fc21fab03f6d66c656efeee2155fab449a7fVikram Aggarwal            return;
540e128fc21fab03f6d66c656efeee2155fab449a7fVikram Aggarwal        }
5412f542873183b37fa38a0d468f46bbfebc1f537e2Andrew Sapperstein        mListController.onCabModeEntered();
54211b0bbdf024ec1413f90b2baac2c18a8f1c01d71Mindy Pereira        mActivated = true;
54311b0bbdf024ec1413f90b2baac2c18a8f1c01d71Mindy Pereira        if (mActionMode == null) {
54452882ff08fe9420fe2dbb3f681545a330222e9c8Andrew Sapperstein            mActivity.startSupportActionMode(this);
54511b0bbdf024ec1413f90b2baac2c18a8f1c01d71Mindy Pereira        }
54611b0bbdf024ec1413f90b2baac2c18a8f1c01d71Mindy Pereira    }
54711b0bbdf024ec1413f90b2baac2c18a8f1c01d71Mindy Pereira
54811b0bbdf024ec1413f90b2baac2c18a8f1c01d71Mindy Pereira    /**
54911b0bbdf024ec1413f90b2baac2c18a8f1c01d71Mindy Pereira     * De-activates and hides the menu (essentially disabling the {@link ActionMode}), but maintains
55011b0bbdf024ec1413f90b2baac2c18a8f1c01d71Mindy Pereira     * the selection conversation set, and internally updates state as necessary.
55111b0bbdf024ec1413f90b2baac2c18a8f1c01d71Mindy Pereira     */
55211b0bbdf024ec1413f90b2baac2c18a8f1c01d71Mindy Pereira    public void deactivate() {
553cc139833bc5829ba70244519e9870de783c41848Scott Kennedy        mListController.onCabModeExited();
5544c92874d9acedc81184339645b24eaeebacbb782Andrew Sapperstein        mActivated = false;
55511b0bbdf024ec1413f90b2baac2c18a8f1c01d71Mindy Pereira        if (mActionMode != null) {
55611b0bbdf024ec1413f90b2baac2c18a8f1c01d71Mindy Pereira            mActionMode.finish();
55711b0bbdf024ec1413f90b2baac2c18a8f1c01d71Mindy Pereira        }
55811b0bbdf024ec1413f90b2baac2c18a8f1c01d71Mindy Pereira    }
55911b0bbdf024ec1413f90b2baac2c18a8f1c01d71Mindy Pereira
56011b0bbdf024ec1413f90b2baac2c18a8f1c01d71Mindy Pereira    @VisibleForTesting
5614c92874d9acedc81184339645b24eaeebacbb782Andrew Sapperstein    /**
5624c92874d9acedc81184339645b24eaeebacbb782Andrew Sapperstein     * Returns true if CAB mode is active.
5634c92874d9acedc81184339645b24eaeebacbb782Andrew Sapperstein     */
56411b0bbdf024ec1413f90b2baac2c18a8f1c01d71Mindy Pereira    public boolean isActivated() {
56511b0bbdf024ec1413f90b2baac2c18a8f1c01d71Mindy Pereira        return mActivated;
56611b0bbdf024ec1413f90b2baac2c18a8f1c01d71Mindy Pereira    }
56711b0bbdf024ec1413f90b2baac2c18a8f1c01d71Mindy Pereira
56811b0bbdf024ec1413f90b2baac2c18a8f1c01d71Mindy Pereira    /**
56911b0bbdf024ec1413f90b2baac2c18a8f1c01d71Mindy Pereira     * Destroys and cleans up the resources associated with this menu.
57011b0bbdf024ec1413f90b2baac2c18a8f1c01d71Mindy Pereira     */
571ad6d6282136b54090f1bf80ff5d37056ff5907c8Vikram Aggarwal    private void destroy() {
57211b0bbdf024ec1413f90b2baac2c18a8f1c01d71Mindy Pereira        deactivate();
573ec0fa48764bede0772e9c711f3e33361b62f3608Jin Cao        mCheckedSet.removeObserver(this);
574ec0fa48764bede0772e9c711f3e33361b62f3608Jin Cao        clearChecked();
5754f4782bcc53e13b30f1fd417beb1a6c04a54faedVikram Aggarwal        mUpdater.refreshConversationList();
57614f64ec84173e5ee8b7157a74e8d62eff7693c19Mindy Pereira        if (mAccountObserver != null) {
57714f64ec84173e5ee8b7157a74e8d62eff7693c19Mindy Pereira            mAccountObserver.unregisterAndDestroy();
57814f64ec84173e5ee8b7157a74e8d62eff7693c19Mindy Pereira            mAccountObserver = null;
57914f64ec84173e5ee8b7157a74e8d62eff7693c19Mindy Pereira        }
58011b0bbdf024ec1413f90b2baac2c18a8f1c01d71Mindy Pereira    }
58111b0bbdf024ec1413f90b2baac2c18a8f1c01d71Mindy Pereira}
582