blob: af170283a201e488c504aa825567924082d35ba2 [file] [log] [blame]
Vikram Aggarwal5e5ac742011-12-19 08:14:16 -08001/*
2 * Copyright (C) 2012 Google Inc.
3 * Licensed to The Android Open Source Project.
4 *
5 * 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
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * 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 */
17
Vikram Aggarwal1ddcf0f2012-01-13 11:45:02 -080018package com.android.mail.ui;
Vikram Aggarwal5e5ac742011-12-19 08:14:16 -080019
20import android.app.ActionBar;
21import android.app.ActionBar.OnNavigationListener;
22import android.content.Context;
23import android.os.Bundle;
24import android.util.AttributeSet;
Vikram Aggarwal2175d0a2012-02-17 16:04:23 -080025import android.util.Log;
Vikram Aggarwal5e5ac742011-12-19 08:14:16 -080026import android.view.Menu;
27import android.view.MenuItem;
28import android.view.View;
29import android.widget.LinearLayout;
30import android.widget.SpinnerAdapter;
31import android.widget.TextView;
32import android.widget.Toast;
33
Vikram Aggarwal1ddcf0f2012-01-13 11:45:02 -080034import com.android.mail.R;
Vikram Aggarwal1ddcf0f2012-01-13 11:45:02 -080035import com.android.mail.AccountSpinnerAdapter;
36import com.android.mail.ConversationListContext;
Mindy Pereira28d5f722012-02-15 12:32:40 -080037import com.android.mail.providers.Account;
Vikram Aggarwal2175d0a2012-02-17 16:04:23 -080038import com.android.mail.providers.UIProvider.AccountCapabilities;
Mindy Pereira28e0c342012-02-17 15:05:13 -080039import com.android.mail.providers.Folder;
Vikram Aggarwal1ddcf0f2012-01-13 11:45:02 -080040
Vikram Aggarwal5e5ac742011-12-19 08:14:16 -080041/**
Vikram Aggarwal2175d0a2012-02-17 16:04:23 -080042 * View to manage the various states of the Mail Action Bar
Vikram Aggarwal1ddcf0f2012-01-13 11:45:02 -080043 *
Vikram Aggarwal2175d0a2012-02-17 16:04:23 -080044 * TODO(viki): Include ConversationSubjectDisplayer here as well.
Vikram Aggarwal5e5ac742011-12-19 08:14:16 -080045 */
Vikram Aggarwal2175d0a2012-02-17 16:04:23 -080046public final class MailActionBar extends LinearLayout implements ActionBarView {
Vikram Aggarwal5e5ac742011-12-19 08:14:16 -080047 /**
48 * This interface is used to send notifications back to the calling
49 * activity. MenuHandler takes care of updating the provider, so this
50 * interface should be used for notification purposes only (such as updating
51 * the UI).
52 */
Vikram Aggarwal2175d0a2012-02-17 16:04:23 -080053 // TODO(viki): This callback is currently unused and may be entirely unnecessary in the new
54 // code, where the Actionbar is switched into navigation mode, relying on the framework for most
55 // heavy lifting. Also, we can switch ViewMode to the appropriate mode and rely on all UI
56 // components updating through ViewMode change listeners.
Vikram Aggarwal5e5ac742011-12-19 08:14:16 -080057 public interface Callback {
58 /**
59 * Enter search mode
60 */
61 void enterSearchMode();
62
63 /**
64 * Exits search mode
65 */
66 void exitSearchMode();
67
68 /**
69 * Returns the current account.
70 */
Vikram Aggarwale9a81032012-02-22 13:15:35 -080071 Account getCurrentAccount();
Vikram Aggarwal5e5ac742011-12-19 08:14:16 -080072
73 /**
74 * Called when the TwoPaneActionBar wants to get the current conversation list context.
75 */
76 ConversationListContext getCurrentListContext();
77
78 /**
Vikram Aggarwal5e5ac742011-12-19 08:14:16 -080079 * Invoked when the user is already viewing search results
80 * and enters a new query.
81 * @param string Query
82 */
83 void reloadSearch(String string);
84
Vikram Aggarwal1ddcf0f2012-01-13 11:45:02 -080085 void showFolderList();
Vikram Aggarwal5e5ac742011-12-19 08:14:16 -080086
87 void startActionBarStatusCursorLoader(String account);
88
89 void stopActionBarStatusCursorLoader(String account);
90 }
91
Vikram Aggarwal1ddcf0f2012-01-13 11:45:02 -080092 private String[] mAccountNames;
Vikram Aggarwal5e5ac742011-12-19 08:14:16 -080093 private ActionBar mActionBar;
Vikram Aggarwal2175d0a2012-02-17 16:04:23 -080094 private RestrictedActivity mActivity;
Mindy Pereira28e0c342012-02-17 15:05:13 -080095 private ActivityController mCallback;
Vikram Aggarwal2175d0a2012-02-17 16:04:23 -080096 private View mFolderView;
97 /**
98 * The current mode of the ActionBar. This references constants in {@link ViewMode}
99 */
100 private int mMode = ViewMode.UNKNOWN;
Vikram Aggarwal1ddcf0f2012-01-13 11:45:02 -0800101
102 private MenuItem mRefreshItem;
103
Vikram Aggarwal5e5ac742011-12-19 08:14:16 -0800104 private MenuItem mSearch;
Vikram Aggarwal1ddcf0f2012-01-13 11:45:02 -0800105 SpinnerAdapter mSpinner;
Vikram Aggarwal2175d0a2012-02-17 16:04:23 -0800106 /**
Vikram Aggarwalbd6c1d32012-02-21 10:14:32 -0800107 * The account currently being shown
Vikram Aggarwal2175d0a2012-02-17 16:04:23 -0800108 */
Vikram Aggarwalbd6c1d32012-02-21 10:14:32 -0800109 private Account mAccount;
Vikram Aggarwal5e5ac742011-12-19 08:14:16 -0800110
111 // TODO(viki): This is a SnippetTextView in the Gmail source code. Resolve.
112 private TextView mSubjectView;
113
Vikram Aggarwal5e5ac742011-12-19 08:14:16 -0800114 public MailActionBar(Context context) {
115 this(context, null);
116 }
117
118 public MailActionBar(Context context, AttributeSet attrs) {
119 this(context, attrs, 0);
120 }
121
Vikram Aggarwal5e5ac742011-12-19 08:14:16 -0800122 public MailActionBar(Context context, AttributeSet attrs, int defStyle) {
123 super(context, attrs, defStyle);
Vikram Aggarwal5e5ac742011-12-19 08:14:16 -0800124 }
125
Vikram Aggarwal5e5ac742011-12-19 08:14:16 -0800126 @Override
127 public boolean createOptionsMenu(Menu menu) {
128 // If the mode is valid, then set the initial menu
Mindy Pereiraf5acda42012-02-15 20:13:59 -0800129 if (mMode == ViewMode.UNKNOWN) {
Vikram Aggarwal5e5ac742011-12-19 08:14:16 -0800130 return false;
131 }
132 mActivity.getMenuInflater().inflate(getOptionsMenuId(), menu);
133 // mSearch = menu.findItem(R.id.search);
134 // mRefreshItem = menu.findItem(R.id.refresh);
135 return true;
136 }
137
Vikram Aggarwal5e5ac742011-12-19 08:14:16 -0800138 @Override
Vikram Aggarwal5e5ac742011-12-19 08:14:16 -0800139 public int getOptionsMenuId() {
Vikram Aggarwal2175d0a2012-02-17 16:04:23 -0800140 // Relies on the ordering of the view modes, since they are integer constants.
141 final int[] modeMenu = {
142 // 0: UNKNOWN
143 R.menu.conversation_list_menu,
144 // 1: CONVERSATION
145 R.menu.conversation_actions,
146 // 2: CONVERSATION_LIST
147 R.menu.conversation_list_menu,
148 // 3: FOLDER_LIST
149 R.menu.folder_list_menu,
150 // 4: SEARCH_RESULTS
151 R.menu.conversation_list_menu
152 };
153 return modeMenu[mMode];
Vikram Aggarwal5e5ac742011-12-19 08:14:16 -0800154 }
155
Vikram Aggarwal5e5ac742011-12-19 08:14:16 -0800156 @Override
157 public void handleRestore(Bundle savedInstanceState) {
Vikram Aggarwal5e5ac742011-12-19 08:14:16 -0800158 }
159
Vikram Aggarwal5e5ac742011-12-19 08:14:16 -0800160 @Override
161 public void handleSaveInstanceState(Bundle outState) {
Vikram Aggarwal5e5ac742011-12-19 08:14:16 -0800162 }
163
Vikram Aggarwal5e5ac742011-12-19 08:14:16 -0800164 @Override
Mindy Pereira28e0c342012-02-17 15:05:13 -0800165 public void initialize(RestrictedActivity activity, ActivityController callback, ViewMode viewMode,
Vikram Aggarwal5e5ac742011-12-19 08:14:16 -0800166 ActionBar actionBar) {
Vikram Aggarwal5e5ac742011-12-19 08:14:16 -0800167 mActionBar = actionBar;
168 mCallback = callback;
169 mActivity = activity;
Vikram Aggarwal5e5ac742011-12-19 08:14:16 -0800170
171 // Set the mode to Navigation mode
172 mActionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);
173 mSpinner = new AccountSpinnerAdapter(getContext());
Vikram Aggarwal5e5ac742011-12-19 08:14:16 -0800174 mActionBar.setListNavigationCallbacks(mSpinner, this);
175 }
176
Vikram Aggarwal1ddcf0f2012-01-13 11:45:02 -0800177 @Override
Vikram Aggarwal2175d0a2012-02-17 16:04:23 -0800178 public boolean onNavigationItemSelected(int position, long id) {
179 final int type = mSpinner.getItemViewType(position);
Mindy Pereira28d5f722012-02-15 12:32:40 -0800180 switch (type) {
181 case AccountSpinnerAdapter.TYPE_ACCOUNT:
Mindy Pereira28e0c342012-02-17 15:05:13 -0800182 mCallback.onAccountChanged((Account) mSpinner.getItem(position));
Vikram Aggarwal2175d0a2012-02-17 16:04:23 -0800183 // Get the capabilities associated with this account.
184 final Object item = mSpinner.getItem(position);
185 assert (item instanceof Account);
Vikram Aggarwalbd6c1d32012-02-21 10:14:32 -0800186 mAccount = (Account) item;
Mindy Pereira28d5f722012-02-15 12:32:40 -0800187 break;
188 }
Vikram Aggarwal1ddcf0f2012-01-13 11:45:02 -0800189 return false;
190 }
191
Vikram Aggarwal5e5ac742011-12-19 08:14:16 -0800192 @Override
193 public void onPause() {
Vikram Aggarwal5e5ac742011-12-19 08:14:16 -0800194 }
195
Vikram Aggarwal5e5ac742011-12-19 08:14:16 -0800196 @Override
197 public void onResume() {
Vikram Aggarwal5e5ac742011-12-19 08:14:16 -0800198 }
199
Vikram Aggarwal5e5ac742011-12-19 08:14:16 -0800200 @Override
201 public void onStatusResult(String account, int status) {
Vikram Aggarwal1ddcf0f2012-01-13 11:45:02 -0800202 // Update the inbox folder if required
Vikram Aggarwal5e5ac742011-12-19 08:14:16 -0800203 mCallback.stopActionBarStatusCursorLoader(account);
204 }
205
Vikram Aggarwal5e5ac742011-12-19 08:14:16 -0800206 @Override
Vikram Aggarwal2175d0a2012-02-17 16:04:23 -0800207 public void onViewModeChanged(int newMode) {
208 mMode = newMode;
209
210 // Always update the options menu and redraw. This will read the new mode and redraw
211 // the options menu.
212 mActivity.invalidateOptionsMenu();
213 }
214
215 /**
216 * If shouldSetView is true, then the view is made visible, otherwise its visiblity is View.GONE
217 * @param view the view whose visibility is modified
218 * @param shouldSetView if true, the view is made visible, GONE otherwise
219 */
220 private void setVisibility(int resourceId, boolean shouldSetView) {
221 final View view = findViewById(resourceId);
222 assert (view != null);
223 final int visibility = shouldSetView ? View.VISIBLE : View.GONE;
224 view.setVisibility(visibility);
225 }
226
227 @Override
Vikram Aggarwal5e5ac742011-12-19 08:14:16 -0800228 public boolean prepareOptionsMenu(Menu menu) {
Vikram Aggarwal2175d0a2012-02-17 16:04:23 -0800229 // We start out with every option enabled. Based on the current view, we disable actions
230 // that are possible.
Vikram Aggarwal5e5ac742011-12-19 08:14:16 -0800231 if (mSubjectView != null){
232 mSubjectView.setVisibility(GONE);
233 }
Vikram Aggarwal1ddcf0f2012-01-13 11:45:02 -0800234 if (mFolderView != null){
235 mFolderView.setVisibility(GONE);
Vikram Aggarwal5e5ac742011-12-19 08:14:16 -0800236 }
237
238 switch (mMode){
Mindy Pereiraf5acda42012-02-15 20:13:59 -0800239 case ViewMode.UNKNOWN:
Vikram Aggarwal5e5ac742011-12-19 08:14:16 -0800240 if (mSearch != null){
241 mSearch.collapseActionView();
242 }
243 break;
Mindy Pereiraf5acda42012-02-15 20:13:59 -0800244 case ViewMode.CONVERSATION_LIST:
Vikram Aggarwal2175d0a2012-02-17 16:04:23 -0800245 // Show compose, search, labels, and sync based on the account
246 // The only option that needs to be disabled is search
Vikram Aggarwalbd6c1d32012-02-21 10:14:32 -0800247 setVisibility(R.id.search, mAccount.supportsCapability(
248 AccountCapabilities.FOLDER_SERVER_SEARCH));
Vikram Aggarwal5e5ac742011-12-19 08:14:16 -0800249 break;
Mindy Pereiraf5acda42012-02-15 20:13:59 -0800250 case ViewMode.CONVERSATION:
Vikram Aggarwalbd6c1d32012-02-21 10:14:32 -0800251 setVisibility(R.id.y_button, mAccount.supportsCapability(
252 AccountCapabilities.ARCHIVE));
253 setVisibility(R.id.report_spam, mAccount.supportsCapability(
254 AccountCapabilities.REPORT_SPAM));
255 setVisibility(R.id.mute, mAccount.supportsCapability(AccountCapabilities.MUTE));
Vikram Aggarwal5e5ac742011-12-19 08:14:16 -0800256 break;
Mindy Pereiraf5acda42012-02-15 20:13:59 -0800257 case ViewMode.SEARCH_RESULTS:
Vikram Aggarwal5e5ac742011-12-19 08:14:16 -0800258 mActionBar.setDisplayHomeAsUpEnabled(true);
Vikram Aggarwal5e5ac742011-12-19 08:14:16 -0800259 if (mSearch != null) {
260 mSearch.collapseActionView();
261 }
Mindy Pereiraf5acda42012-02-15 20:13:59 -0800262 case ViewMode.FOLDER_LIST:
Vikram Aggarwal5e5ac742011-12-19 08:14:16 -0800263 break;
264 }
265 return false;
266 }
267
Vikram Aggarwal5e5ac742011-12-19 08:14:16 -0800268 @Override
269 public void removeBackButton() {
270 if (mActionBar == null) {
271 return;
272 }
Vikram Aggarwal5e5ac742011-12-19 08:14:16 -0800273 mActionBar.setDisplayOptions(
274 ActionBar.DISPLAY_SHOW_HOME,
275 ActionBar.DISPLAY_HOME_AS_UP | ActionBar.DISPLAY_SHOW_HOME);
276 mActivity.getActionBar().setHomeButtonEnabled(false);
277 }
278
Vikram Aggarwal5e5ac742011-12-19 08:14:16 -0800279 @Override
280 public void setBackButton() {
281 if (mActionBar == null){
282 return;
283 }
Vikram Aggarwal5e5ac742011-12-19 08:14:16 -0800284 mActionBar.setDisplayOptions(
285 ActionBar.DISPLAY_HOME_AS_UP | ActionBar.DISPLAY_SHOW_HOME,
286 ActionBar.DISPLAY_HOME_AS_UP | ActionBar.DISPLAY_SHOW_HOME);
287 mActivity.getActionBar().setHomeButtonEnabled(true);
288 }
289
Vikram Aggarwal5e5ac742011-12-19 08:14:16 -0800290 @Override
Vikram Aggarwal1ddcf0f2012-01-13 11:45:02 -0800291 public void setFolder(String folder) {
Vikram Aggarwal5e5ac742011-12-19 08:14:16 -0800292 // TODO(viki): Add this functionality to change the label.
Vikram Aggarwal5e5ac742011-12-19 08:14:16 -0800293 }
294
Vikram Aggarwal5e5ac742011-12-19 08:14:16 -0800295 @Override
Vikram Aggarwal5e5ac742011-12-19 08:14:16 -0800296 public void updateActionBar(String[] accounts, String currentAccount) {
297 }
Vikram Aggarwal5e5ac742011-12-19 08:14:16 -0800298}