blob: 056de30746011c575d186e0761c53c6e83c39f8a [file] [log] [blame]
Mindy Pereira68f2e222012-03-07 10:36:54 -08001/*
2 * Copyright (C) 2012 Google Inc.
3 * Licensed to The Android Open Source Project.
Vikram Aggarwal5e5ac742011-12-19 08:14:16 -08004 *
Mindy Pereira68f2e222012-03-07 10:36:54 -08005 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
Vikram Aggarwal5e5ac742011-12-19 08:14:16 -08008 *
Mindy Pereira68f2e222012-03-07 10:36:54 -08009 * http://www.apache.org/licenses/LICENSE-2.0
Vikram Aggarwal5e5ac742011-12-19 08:14:16 -080010 *
Mindy Pereira68f2e222012-03-07 10:36:54 -080011 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
Vikram Aggarwal5e5ac742011-12-19 08:14:16 -080017
Vikram Aggarwal1ddcf0f2012-01-13 11:45:02 -080018package com.android.mail.ui;
Vikram Aggarwal5e5ac742011-12-19 08:14:16 -080019
Scott Banachowski53a615d2012-12-19 15:31:20 -080020import android.content.ContentResolver;
Mindy Pereira68f2e222012-03-07 10:36:54 -080021import android.content.Context;
Vikram Aggarwala51ef9f2013-04-02 13:25:35 -070022import android.net.Uri;
23import android.os.AsyncTask;
Vikram Aggarwal5e5ac742011-12-19 08:14:16 -080024import android.os.Bundle;
Andrew Sapperstein52882ff2014-07-27 12:30:18 -070025import android.support.v7.app.ActionBar;
Mindy Pereira0531c9f2012-06-25 14:12:59 -070026import android.text.TextUtils;
Vikram Aggarwal5e5ac742011-12-19 08:14:16 -080027import android.view.Menu;
Mindy Pereira68f2e222012-03-07 10:36:54 -080028import android.view.MenuItem;
Vikram Aggarwala9b93f32012-02-23 14:51:58 -080029
Alice Yang760d9562013-04-02 13:13:24 -070030import com.android.mail.R;
Alice Yang760d9562013-04-02 13:13:24 -070031import com.android.mail.providers.Account;
32import com.android.mail.providers.AccountObserver;
Alice Yang760d9562013-04-02 13:13:24 -070033import com.android.mail.providers.Conversation;
34import com.android.mail.providers.Folder;
35import com.android.mail.providers.FolderObserver;
Alice Yang760d9562013-04-02 13:13:24 -070036import com.android.mail.providers.UIProvider;
37import com.android.mail.providers.UIProvider.AccountCapabilities;
38import com.android.mail.providers.UIProvider.FolderCapabilities;
Scott Kennedy7ee089e2013-03-25 17:05:44 -040039import com.android.mail.providers.UIProvider.FolderType;
Alice Yang760d9562013-04-02 13:13:24 -070040import com.android.mail.utils.LogTag;
41import com.android.mail.utils.LogUtils;
42import com.android.mail.utils.Utils;
43
Vikram Aggarwal5e5ac742011-12-19 08:14:16 -080044/**
Andrew Sapperstein2d86d112014-07-24 20:27:37 -070045 * Controller to manage the various states of the {@link android.app.ActionBar}.
Vikram Aggarwal5e5ac742011-12-19 08:14:16 -080046 */
Jin Caoc6801eb2014-08-12 18:16:57 -070047public class ActionBarController implements ViewMode.ModeChangeListener {
Andrew Sapperstein2d86d112014-07-24 20:27:37 -070048
49 private final Context mContext;
Andy Huangaf65e732013-01-28 20:45:40 -080050
Mindy Pereiraedb135e2012-06-15 08:34:09 -070051 protected ActionBar mActionBar;
Vikram Aggarwal7c401b72012-08-13 16:43:47 -070052 protected ControllableActivity mActivity;
Mindy Pereiraedb135e2012-06-15 08:34:09 -070053 protected ActivityController mController;
Mindy Pereira68f2e222012-03-07 10:36:54 -080054 /**
Tony Mantlerbd091502013-09-16 13:59:47 -070055 * The current mode of the ActionBar and Activity
Mindy Pereira68f2e222012-03-07 10:36:54 -080056 */
Tony Mantlerbd091502013-09-16 13:59:47 -070057 private ViewMode mViewModeController;
Mindy Pereira68f2e222012-03-07 10:36:54 -080058
Mindy Pereira68f2e222012-03-07 10:36:54 -080059 /**
60 * The account currently being shown
61 */
62 private Account mAccount;
Marc Blankedcab012012-04-04 12:42:38 -070063 /**
64 * The folder currently being shown
65 */
66 private Folder mFolder;
Mindy Pereira68f2e222012-03-07 10:36:54 -080067
Scott Kennedy7ee089e2013-03-25 17:05:44 -040068 private MenuItem mEmptyTrashItem;
69 private MenuItem mEmptySpamItem;
Paul Westbrook8c887ef2013-04-24 00:29:28 -070070
Vikram Aggarwalf642b812013-03-15 16:30:21 -070071 /** True if the current device is a tablet, false otherwise. */
Vikram Aggarwalad8b99b2013-04-07 16:37:28 -070072 protected final boolean mIsOnTablet;
Yorke Leef807ba72012-09-20 17:18:05 -070073 private Conversation mCurrentConversation;
Mindy Pereira9b623802012-03-07 17:15:49 -080074
Paul Westbrookb334c902012-06-25 11:42:46 -070075 public static final String LOG_TAG = LogTag.getLogTag();
Andy Huang0d647352012-03-21 21:48:16 -070076
Vikram Aggarwal50ff0e52013-03-14 13:58:02 -070077 private FolderObserver mFolderObserver;
Mindy Pereira68f2e222012-03-07 10:36:54 -080078
Vikram Aggarwala51ef9f2013-04-02 13:25:35 -070079 /** Updates the resolver and tells it the most recent account. */
80 private final class UpdateProvider extends AsyncTask<Bundle, Void, Void> {
81 final Uri mAccount;
82 final ContentResolver mResolver;
83 public UpdateProvider(Uri account, ContentResolver resolver) {
84 mAccount = account;
85 mResolver = resolver;
86 }
87
88 @Override
89 protected Void doInBackground(Bundle... params) {
90 mResolver.call(mAccount, UIProvider.AccountCallMethods.SET_CURRENT_ACCOUNT,
91 mAccount.toString(), params[0]);
92 return null;
93 }
94 }
95
Vikram Aggarwal7c401b72012-08-13 16:43:47 -070096 private final AccountObserver mAccountObserver = new AccountObserver() {
97 @Override
98 public void onChanged(Account newAccount) {
Scott Banachowski53a615d2012-12-19 15:31:20 -080099 updateAccount(newAccount);
Vikram Aggarwal7c401b72012-08-13 16:43:47 -0700100 }
101 };
Andy Huangaf65e732013-01-28 20:45:40 -0800102
Andrew Sapperstein2d86d112014-07-24 20:27:37 -0700103 public ActionBarController(Context context) {
104 mContext = context;
105 mIsOnTablet = Utils.useTabletUI(context.getResources());
Mindy Pereira68f2e222012-03-07 10:36:54 -0800106 }
107
108 public boolean onCreateOptionsMenu(Menu menu) {
James Lemieux640741d2014-03-20 13:56:08 -0700109 mEmptyTrashItem = menu.findItem(R.id.empty_trash);
110 mEmptySpamItem = menu.findItem(R.id.empty_spam);
James Lemieux640741d2014-03-20 13:56:08 -0700111
112 // the menu should be displayed if the mode is known
113 return getMode() != ViewMode.UNKNOWN;
Mindy Pereira68f2e222012-03-07 10:36:54 -0800114 }
115
116 public int getOptionsMenuId() {
Tony Mantlerbd091502013-09-16 13:59:47 -0700117 switch (getMode()) {
Tony Mantlere29b97e2013-08-01 16:37:54 -0700118 case ViewMode.UNKNOWN:
119 return R.menu.conversation_list_menu;
120 case ViewMode.CONVERSATION:
121 return R.menu.conversation_actions;
122 case ViewMode.CONVERSATION_LIST:
123 return R.menu.conversation_list_menu;
124 case ViewMode.SEARCH_RESULTS_LIST:
125 return R.menu.conversation_list_search_results_actions;
126 case ViewMode.SEARCH_RESULTS_CONVERSATION:
127 return R.menu.conversation_actions;
128 case ViewMode.WAITING_FOR_ACCOUNT_INITIALIZATION:
129 return R.menu.wait_mode_actions;
130 }
131 LogUtils.wtf(LOG_TAG, "Menu requested for unknown view mode");
132 return R.menu.conversation_list_menu;
Mindy Pereira68f2e222012-03-07 10:36:54 -0800133 }
134
Vikram Aggarwal7c401b72012-08-13 16:43:47 -0700135 public void initialize(ControllableActivity activity, ActivityController callback,
Vikram Aggarwaldac89fa2013-03-05 16:43:09 -0800136 ActionBar actionBar) {
Mindy Pereira68f2e222012-03-07 10:36:54 -0800137 mActionBar = actionBar;
Vikram Aggarwala7997952012-03-09 10:30:13 -0800138 mController = callback;
Mindy Pereira68f2e222012-03-07 10:36:54 -0800139 mActivity = activity;
Paul Westbrook8c887ef2013-04-24 00:29:28 -0700140
Vikram Aggarwal50ff0e52013-03-14 13:58:02 -0700141 mFolderObserver = new FolderObserver() {
142 @Override
143 public void onChanged(Folder newFolder) {
144 onFolderUpdated(newFolder);
145 }
146 };
Vikram Aggarwal26b0bfd2013-03-29 13:05:08 -0700147 // Return values are purposely discarded. Initialization happens quite early, and we don't
148 // have a valid folder, or a valid list of accounts.
Vikram Aggarwal50ff0e52013-03-14 13:58:02 -0700149 mFolderObserver.initialize(mController);
Scott Banachowski53a615d2012-12-19 15:31:20 -0800150 updateAccount(mAccountObserver.initialize(activity.getAccountController()));
151 }
152
153 private void updateAccount(Account account) {
Vikram Aggarwalf18b1172013-04-17 12:36:23 -0700154 final boolean accountChanged = mAccount == null || !mAccount.uri.equals(account.uri);
Scott Banachowski53a615d2012-12-19 15:31:20 -0800155 mAccount = account;
Vikram Aggarwalf18b1172013-04-17 12:36:23 -0700156 if (mAccount != null && accountChanged) {
Vikram Aggarwalbc462ca2013-03-15 10:41:03 -0700157 final ContentResolver resolver = mActivity.getActivityContext().getContentResolver();
158 final Bundle bundle = new Bundle(1);
Scott Banachowski53a615d2012-12-19 15:31:20 -0800159 bundle.putParcelable(UIProvider.SetCurrentAccountColumns.ACCOUNT, account);
Vikram Aggarwala51ef9f2013-04-02 13:25:35 -0700160 final UpdateProvider updater = new UpdateProvider(mAccount.uri, resolver);
161 updater.execute(bundle);
Andrew Sapperstein2d86d112014-07-24 20:27:37 -0700162 setFolderAndAccount();
Scott Banachowski53a615d2012-12-19 15:31:20 -0800163 }
Vikram Aggarwalabd24d82012-04-26 13:23:14 -0700164 }
Andy Huange303b9b2012-04-19 16:31:09 -0700165
Vikram Aggarwalabd24d82012-04-26 13:23:14 -0700166 /**
Vikram Aggarwal75d1bb12013-04-12 17:17:00 -0700167 * Called by the owner of the ActionBar to change the current folder.
Vikram Aggarwal5e5ac742011-12-19 08:14:16 -0800168 */
Mindy Pereira68f2e222012-03-07 10:36:54 -0800169 public void setFolder(Folder folder) {
Marc Blankedcab012012-04-04 12:42:38 -0700170 mFolder = folder;
Andrew Sapperstein2d86d112014-07-24 20:27:37 -0700171 setFolderAndAccount();
Mindy Pereira68f2e222012-03-07 10:36:54 -0800172 }
Vikram Aggarwal5e5ac742011-12-19 08:14:16 -0800173
Mindy Pereira641de652012-08-02 15:21:50 -0700174 public void onDestroy() {
175 if (mFolderObserver != null) {
Vikram Aggarwal50ff0e52013-03-14 13:58:02 -0700176 mFolderObserver.unregisterAndDestroy();
Mindy Pereira641de652012-08-02 15:21:50 -0700177 mFolderObserver = null;
178 }
Vikram Aggarwal7c401b72012-08-13 16:43:47 -0700179 mAccountObserver.unregisterAndDestroy();
Mindy Pereira68f2e222012-03-07 10:36:54 -0800180 }
181
Vikram Aggarwala7997952012-03-09 10:30:13 -0800182 @Override
Mindy Pereira68f2e222012-03-07 10:36:54 -0800183 public void onViewModeChanged(int newMode) {
Rohan Shah77db7fd2014-08-27 14:18:29 -0700184 final boolean mIsTabletLandscape =
185 mContext.getResources().getBoolean(R.bool.is_tablet_landscape);
186
Andrew Sapperstein52882ff2014-07-27 12:30:18 -0700187 mActivity.supportInvalidateOptionsMenu();
Vikram Aggarwal1a3f3fc2012-07-18 14:49:08 -0700188 // Check if we are either on a phone, or in Conversation mode on tablet. For these, the
189 // recent folders is enabled.
Tony Mantlerbd091502013-09-16 13:59:47 -0700190 switch (getMode()) {
Andy Huangd736a382012-08-29 13:08:58 -0700191 case ViewMode.UNKNOWN:
Andy Huangd736a382012-08-29 13:08:58 -0700192 break;
193 case ViewMode.CONVERSATION_LIST:
194 showNavList();
195 break;
Vikram Aggarwalad8b99b2013-04-07 16:37:28 -0700196 case ViewMode.SEARCH_RESULTS_CONVERSATION:
Vikram Aggarwale875b662013-04-10 15:56:46 -0700197 mActionBar.setDisplayHomeAsUpEnabled(true);
198 setEmptyMode();
199 break;
Andy Huangd736a382012-08-29 13:08:58 -0700200 case ViewMode.CONVERSATION:
Rohan Shah77db7fd2014-08-27 14:18:29 -0700201 // If on tablet landscape, show current folder instead of emptying the action bar
202 if (mIsTabletLandscape) {
203 mActionBar.setDisplayHomeAsUpEnabled(true);
204 showNavList();
205 break;
206 }
207 // Otherwise, fall through to default behavior, shared with Ads ViewMode.
Andrew Sapperstein6c570db2013-08-06 17:21:36 -0700208 case ViewMode.AD:
Andy Huangd736a382012-08-29 13:08:58 -0700209 mActionBar.setDisplayHomeAsUpEnabled(true);
Vikram Aggarwalad8b99b2013-04-07 16:37:28 -0700210 setEmptyMode();
Andy Huangd736a382012-08-29 13:08:58 -0700211 break;
Andy Huangd736a382012-08-29 13:08:58 -0700212 case ViewMode.WAITING_FOR_ACCOUNT_INITIALIZATION:
213 // We want the user to be able to switch accounts while waiting for an account
214 // to sync.
215 showNavList();
216 break;
217 }
Mindy Pereira68f2e222012-03-07 10:36:54 -0800218 }
Vikram Aggarwal5e5ac742011-12-19 08:14:16 -0800219
Mindy Pereiraedb135e2012-06-15 08:34:09 -0700220 protected int getMode() {
Tony Mantlerbd091502013-09-16 13:59:47 -0700221 if (mViewModeController != null) {
222 return mViewModeController.getMode();
223 } else {
224 return ViewMode.UNKNOWN;
225 }
Mindy Pereiraedb135e2012-06-15 08:34:09 -0700226 }
227
Jin Caoe9f07832014-04-15 13:59:37 -0700228 /**
229 * Helper function to ensure that the menu items that are prone to variable changes and race
230 * conditions are properly set to the correct visibility
231 */
232 public void validateVolatileMenuOptionVisibility() {
Jin Caoe9f07832014-04-15 13:59:37 -0700233 if (mEmptyTrashItem != null) {
234 mEmptyTrashItem.setVisible(mAccount != null && mFolder != null
235 && mAccount.supportsCapability(AccountCapabilities.EMPTY_TRASH)
Jin Cao3f386e82014-04-18 11:29:54 -0700236 && mFolder.isTrash() && mFolder.totalCount > 0
237 && (mController.getConversationListCursor() == null
238 || mController.getConversationListCursor().getCount() > 0));
Jin Caoe9f07832014-04-15 13:59:37 -0700239 }
240 if (mEmptySpamItem != null) {
241 mEmptySpamItem.setVisible(mAccount != null && mFolder != null
242 && mAccount.supportsCapability(AccountCapabilities.EMPTY_SPAM)
Jin Cao3f386e82014-04-18 11:29:54 -0700243 && mFolder.isType(FolderType.SPAM) && mFolder.totalCount > 0
244 && (mController.getConversationListCursor() == null
245 || mController.getConversationListCursor().getCount() > 0));
Jin Caoe9f07832014-04-15 13:59:37 -0700246 }
247 }
248
Mindy Pereirab849dfb2012-03-07 18:13:15 -0800249 public boolean onPrepareOptionsMenu(Menu menu) {
Jin Cao1af562a2014-09-09 14:49:53 -0700250 menu.setQwertyMode(true);
Mindy Pereira68f2e222012-03-07 10:36:54 -0800251 // We start out with every option enabled. Based on the current view, we disable actions
252 // that are possible.
Vikram Aggarwal95b28ab2012-04-26 15:53:09 -0700253 LogUtils.d(LOG_TAG, "ActionBarView.onPrepareOptionsMenu().");
Vikram Aggarwal5e5ac742011-12-19 08:14:16 -0800254
Tony Mantlerb3281fb2013-08-20 14:30:29 -0700255 if (mController.shouldHideMenuItems()) {
Ray Chena57da3c2014-06-10 16:01:40 +0200256 // Shortcut: hide all menu items if the drawer is shown
Tony Mantlerb3281fb2013-08-20 14:30:29 -0700257 final int size = menu.size();
258
259 for (int i = 0; i < size; i++) {
260 final MenuItem item = menu.getItem(i);
Ray Chena57da3c2014-06-10 16:01:40 +0200261 item.setVisible(false);
Tony Mantlerb3281fb2013-08-20 14:30:29 -0700262 }
263 return false;
264 }
Jin Caoe9f07832014-04-15 13:59:37 -0700265 validateVolatileMenuOptionVisibility();
Mindy Pereira62c71792012-07-18 09:14:29 -0700266
Tony Mantlerbd091502013-09-16 13:59:47 -0700267 switch (getMode()) {
Yorke Leef807ba72012-09-20 17:18:05 -0700268 case ViewMode.CONVERSATION:
269 case ViewMode.SEARCH_RESULTS_CONVERSATION:
270 // We update the ActionBar options when we are entering conversation view because
271 // waiting for the AbstractConversationViewFragment to do it causes duplicate icons
272 // to show up during the time between the conversation is selected and the fragment
273 // is added.
274 setConversationModeOptions(menu);
275 break;
Jin Caod0334732014-09-01 22:33:14 -0700276 case ViewMode.CONVERSATION_LIST:
Jin Caoa6b45212014-09-18 13:46:54 -0700277 case ViewMode.SEARCH_RESULTS_LIST:
Jin Caod0334732014-09-01 22:33:14 -0700278 // The search menu item should only be visible for non-tablet devices
279 Utils.setMenuItemVisibility(menu, R.id.search,
280 mAccount.supportsSearch() && !mIsOnTablet);
Mindy Pereira68f2e222012-03-07 10:36:54 -0800281 }
Scott Kennedya85831d2013-04-12 15:54:22 -0700282
283 return false;
284 }
285
Scott Kennedy26f2b302013-04-22 17:47:17 -0700286 /**
Vikram Aggarwalad8b99b2013-04-07 16:37:28 -0700287 * Put the ActionBar in List navigation mode.
Vikram Aggarwalabd24d82012-04-26 13:23:14 -0700288 */
Mindy Pereira72a9f392012-03-21 09:41:09 -0700289 private void showNavList() {
Andrew Sapperstein2d86d112014-07-24 20:27:37 -0700290 setTitleModeFlags(ActionBar.DISPLAY_SHOW_TITLE);
291 setFolderAndAccount();
Paul Westbrook8c887ef2013-04-24 00:29:28 -0700292 }
293
Andrew Sapperstein0a0795c2014-01-27 16:52:45 -0800294 private void setTitle(String title) {
Andy Huangc499d712013-06-12 17:37:57 -0700295 if (!TextUtils.equals(title, mActionBar.getTitle())) {
296 mActionBar.setTitle(title);
297 }
mindyp6fb1b622012-09-05 09:27:08 -0700298 }
299
300 /**
Vikram Aggarwalfd7eaba2013-04-11 12:31:46 -0700301 * Set the actionbar mode to empty: no title, no subtitle, no custom view.
mindyp6fb1b622012-09-05 09:27:08 -0700302 */
303 protected void setEmptyMode() {
Vikram Aggarwalfd7eaba2013-04-11 12:31:46 -0700304 // Disable title/subtitle and the custom view by setting the bitmask to all off.
305 setTitleModeFlags(0);
Vikram Aggarwalabd24d82012-04-26 13:23:14 -0700306 }
307
Vikram Aggarwalad8b99b2013-04-07 16:37:28 -0700308 /**
309 * Removes the back button from being shown
310 */
Mindy Pereira68f2e222012-03-07 10:36:54 -0800311 public void removeBackButton() {
312 if (mActionBar == null) {
313 return;
314 }
Vikram Aggarwal649b9ea2012-08-27 12:15:20 -0700315 // Remove the back button but continue showing an icon.
Andrew Sapperstein2d86d112014-07-24 20:27:37 -0700316 final int mask = ActionBar.DISPLAY_HOME_AS_UP | ActionBar.DISPLAY_SHOW_HOME;
317 mActionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_HOME, mask);
Andrew Sapperstein52882ff2014-07-27 12:30:18 -0700318 mActionBar.setHomeButtonEnabled(false);
Mindy Pereira68f2e222012-03-07 10:36:54 -0800319 }
Mindy Pereirabc57bf12012-02-29 14:39:09 -0800320
Mindy Pereira68f2e222012-03-07 10:36:54 -0800321 public void setBackButton() {
Andy Huang12b3ee42013-04-24 22:49:43 -0700322 if (mActionBar == null) {
Mindy Pereira68f2e222012-03-07 10:36:54 -0800323 return;
324 }
Vikram Aggarwal649b9ea2012-08-27 12:15:20 -0700325 // Show home as up, and show an icon.
Andrew Sapperstein2d86d112014-07-24 20:27:37 -0700326 final int mask = ActionBar.DISPLAY_HOME_AS_UP | ActionBar.DISPLAY_SHOW_HOME;
Vikram Aggarwal649b9ea2012-08-27 12:15:20 -0700327 mActionBar.setDisplayOptions(mask, mask);
Andrew Sapperstein52882ff2014-07-27 12:30:18 -0700328 mActionBar.setHomeButtonEnabled(true);
Mindy Pereira68f2e222012-03-07 10:36:54 -0800329 }
Vikram Aggarwal5e5ac742011-12-19 08:14:16 -0800330
Vikram Aggarwalf642b812013-03-15 16:30:21 -0700331 /**
332 * Uses the current state to update the current folder {@link #mFolder} and the current
Vikram Aggarwal75d1bb12013-04-12 17:17:00 -0700333 * account {@link #mAccount} shown in the actionbar. Also updates the actionbar subtitle to
334 * momentarily display the unread count if it has changed.
Vikram Aggarwalf642b812013-03-15 16:30:21 -0700335 */
Andrew Sapperstein2d86d112014-07-24 20:27:37 -0700336 private void setFolderAndAccount() {
Vikram Aggarwal5fce9922013-04-01 21:17:42 -0700337 // Very little can be done if the actionbar or activity is null.
338 if (mActionBar == null || mActivity == null) {
339 return;
340 }
Tony Mantlerbd091502013-09-16 13:59:47 -0700341 if (ViewMode.isWaitingForSync(getMode())) {
Vikram Aggarwal75d1bb12013-04-12 17:17:00 -0700342 // Account is not synced: clear title and update the subtitle.
Paul Westbrook8c887ef2013-04-24 00:29:28 -0700343 setTitle("");
Vikram Aggarwalf642b812013-03-15 16:30:21 -0700344 return;
345 }
Vikram Aggarwal75d1bb12013-04-12 17:17:00 -0700346 // Check if we should be changing the actionbar at all, and back off if not.
Tony Mantlerbd091502013-09-16 13:59:47 -0700347 final boolean isShowingFolder = mIsOnTablet || ViewMode.isListMode(getMode());
Vikram Aggarwal75d1bb12013-04-12 17:17:00 -0700348 if (!isShowingFolder) {
Paul Westbrook91024952013-04-21 15:59:06 -0700349 // It isn't necessary to set the title in this case, as the title view will
350 // be hidden
Vikram Aggarwal75d1bb12013-04-12 17:17:00 -0700351 return;
Vikram Aggarwalf642b812013-03-15 16:30:21 -0700352 }
Vikram Aggarwal26b0bfd2013-03-29 13:05:08 -0700353 if (mFolder == null) {
Paul Westbrook91024952013-04-21 15:59:06 -0700354 // Clear the action bar title. We don't want the app name to be shown while
355 // waiting for the folder query to finish
Paul Westbrook8c887ef2013-04-24 00:29:28 -0700356 setTitle("");
Vikram Aggarwal26b0bfd2013-03-29 13:05:08 -0700357 return;
358 }
Paul Westbrook8c887ef2013-04-24 00:29:28 -0700359 setTitle(mFolder.name);
Vikram Aggarwalf18b1172013-04-17 12:36:23 -0700360 }
361
Vikram Aggarwalbc462ca2013-03-15 10:41:03 -0700362
Mindy Pereiraa46a57f2012-04-03 17:19:31 -0700363 /**
364 * Notify that the folder has changed.
365 */
366 public void onFolderUpdated(Folder folder) {
Vikram Aggarwal26b0bfd2013-03-29 13:05:08 -0700367 if (folder == null) {
368 return;
369 }
Vikram Aggarwale875b662013-04-10 15:56:46 -0700370 /** True if we are changing folders. */
Vikram Aggarwalc18c3382013-04-05 15:29:13 -0700371 mFolder = folder;
Andrew Sapperstein2d86d112014-07-24 20:27:37 -0700372 setFolderAndAccount();
Jin Caoe9f07832014-04-15 13:59:37 -0700373 // make sure that we re-validate the optional menu items
374 validateVolatileMenuOptionVisibility();
Mindy Pereiraa46a57f2012-04-03 17:19:31 -0700375 }
Vikram Aggarwal0dda5732012-04-06 11:20:16 -0700376
Vikram Aggarwalfd7eaba2013-04-11 12:31:46 -0700377 /**
378 * Sets the actionbar mode: Pass it an integer which contains each of these values, perhaps
Paul Westbrook8c887ef2013-04-24 00:29:28 -0700379 * OR'd together: {@link ActionBar#DISPLAY_SHOW_CUSTOM} and
380 * {@link ActionBar#DISPLAY_SHOW_TITLE}. To disable all, pass a zero.
Vikram Aggarwalfd7eaba2013-04-11 12:31:46 -0700381 * @param enabledFlags
382 */
Andy Huangaf65e732013-01-28 20:45:40 -0800383 private void setTitleModeFlags(int enabledFlags) {
Paul Westbrook8c887ef2013-04-24 00:29:28 -0700384 final int mask = ActionBar.DISPLAY_SHOW_TITLE | ActionBar.DISPLAY_SHOW_CUSTOM;
Andy Huangaf65e732013-01-28 20:45:40 -0800385 mActionBar.setDisplayOptions(enabledFlags, mask);
386 }
387
Yorke Leef807ba72012-09-20 17:18:05 -0700388 public void setCurrentConversation(Conversation conversation) {
389 mCurrentConversation = conversation;
390 }
391
392 //We need to do this here instead of in the fragment
393 public void setConversationModeOptions(Menu menu) {
394 if (mCurrentConversation == null) {
395 return;
396 }
397 final boolean showMarkImportant = !mCurrentConversation.isImportant();
398 Utils.setMenuItemVisibility(menu, R.id.mark_important, showMarkImportant
399 && mAccount.supportsCapability(UIProvider.AccountCapabilities.MARK_IMPORTANT));
400 Utils.setMenuItemVisibility(menu, R.id.mark_not_important, !showMarkImportant
401 && mAccount.supportsCapability(UIProvider.AccountCapabilities.MARK_IMPORTANT));
Jin Cao512821c2014-05-30 15:54:04 -0700402 final boolean isOutbox = mFolder.isType(FolderType.OUTBOX);
403 final boolean showDiscardOutbox = mFolder != null && isOutbox &&
404 mCurrentConversation.sendingState == UIProvider.ConversationSendingState.SEND_ERROR;
405 Utils.setMenuItemVisibility(menu, R.id.discard_outbox, showDiscardOutbox);
406 final boolean showDelete = !isOutbox && mFolder != null &&
Yorke Leef807ba72012-09-20 17:18:05 -0700407 mFolder.supportsCapability(UIProvider.FolderCapabilities.DELETE);
408 Utils.setMenuItemVisibility(menu, R.id.delete, showDelete);
409 // We only want to show the discard drafts menu item if we are not showing the delete menu
410 // item, and the current folder is a draft folder and the account supports discarding
411 // drafts for a conversation
412 final boolean showDiscardDrafts = !showDelete && mFolder != null && mFolder.isDraft() &&
413 mAccount.supportsCapability(AccountCapabilities.DISCARD_CONVERSATION_DRAFTS);
414 Utils.setMenuItemVisibility(menu, R.id.discard_drafts, showDiscardDrafts);
415 final boolean archiveVisible = mAccount.supportsCapability(AccountCapabilities.ARCHIVE)
416 && mFolder != null && mFolder.supportsCapability(FolderCapabilities.ARCHIVE)
417 && !mFolder.isTrash();
418 Utils.setMenuItemVisibility(menu, R.id.archive, archiveVisible);
419 Utils.setMenuItemVisibility(menu, R.id.remove_folder, !archiveVisible && mFolder != null
420 && mFolder.supportsCapability(FolderCapabilities.CAN_ACCEPT_MOVED_MESSAGES)
Tony Mantler53b34252013-09-25 16:42:25 -0700421 && !mFolder.isProviderFolder()
422 && mAccount.supportsCapability(AccountCapabilities.ARCHIVE));
Scott Kennedy28f3d5c2013-04-08 16:53:50 -0700423 Utils.setMenuItemVisibility(menu, R.id.move_to, mFolder != null
424 && mFolder.supportsCapability(FolderCapabilities.ALLOWS_REMOVE_CONVERSATION));
Scott Kennedydd2ec682013-06-03 19:16:13 -0700425 Utils.setMenuItemVisibility(menu, R.id.move_to_inbox, mFolder != null
426 && mFolder.supportsCapability(FolderCapabilities.ALLOWS_MOVE_TO_INBOX));
Rohan Shah69419bb2014-08-15 15:53:29 -0700427 Utils.setMenuItemVisibility(menu, R.id.change_folders, mAccount.supportsCapability(
428 UIProvider.AccountCapabilities.MULTIPLE_FOLDERS_PER_CONV));
Scott Kennedydd2ec682013-06-03 19:16:13 -0700429
Yorke Leef807ba72012-09-20 17:18:05 -0700430 final MenuItem removeFolder = menu.findItem(R.id.remove_folder);
Alice Yang40698e62013-03-14 11:31:53 -0700431 if (mFolder != null && removeFolder != null) {
Yorke Leef807ba72012-09-20 17:18:05 -0700432 removeFolder.setTitle(mActivity.getApplicationContext().getString(
433 R.string.remove_folder, mFolder.name));
434 }
435 Utils.setMenuItemVisibility(menu, R.id.report_spam,
436 mAccount.supportsCapability(AccountCapabilities.REPORT_SPAM) && mFolder != null
437 && mFolder.supportsCapability(FolderCapabilities.REPORT_SPAM)
438 && !mCurrentConversation.spam);
439 Utils.setMenuItemVisibility(menu, R.id.mark_not_spam,
440 mAccount.supportsCapability(AccountCapabilities.REPORT_SPAM) && mFolder != null
441 && mFolder.supportsCapability(FolderCapabilities.MARK_NOT_SPAM)
442 && mCurrentConversation.spam);
443 Utils.setMenuItemVisibility(menu, R.id.report_phishing,
444 mAccount.supportsCapability(AccountCapabilities.REPORT_PHISHING) && mFolder != null
445 && mFolder.supportsCapability(FolderCapabilities.REPORT_PHISHING)
446 && !mCurrentConversation.phishing);
447 Utils.setMenuItemVisibility(menu, R.id.mute,
448 mAccount.supportsCapability(AccountCapabilities.MUTE) && mFolder != null
449 && mFolder.supportsCapability(FolderCapabilities.DESTRUCTIVE_MUTE)
450 && !mCurrentConversation.muted);
451 }
Paul Westbrook8c887ef2013-04-24 00:29:28 -0700452
Tony Mantlerbd091502013-09-16 13:59:47 -0700453 public void setViewModeController(ViewMode viewModeController) {
454 mViewModeController = viewModeController;
455 mViewModeController.addListener(this);
456 }
Andrew Sapperstein2d86d112014-07-24 20:27:37 -0700457
458 public Context getContext() {
459 return mContext;
460 }
Vikram Aggarwal5e5ac742011-12-19 08:14:16 -0800461}