blob: f191415ec43af3284c6e30250c1f4eec5224fc8a [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
Andy Huang30e2c242012-01-06 18:14:30 -080018package com.android.mail;
Vikram Aggarwal5e5ac742011-12-19 08:14:16 -080019
20import android.content.Context;
Vikram Aggarwal8183d452012-04-17 09:13:29 -070021import android.net.Uri;
Vikram Aggarwal59926d62012-07-19 14:49:11 -070022import android.text.TextUtils;
Vikram Aggarwal5e5ac742011-12-19 08:14:16 -080023import android.view.LayoutInflater;
24import android.view.View;
25import android.view.ViewGroup;
Vikram Aggarwala9b93f32012-02-23 14:51:58 -080026import android.widget.BaseAdapter;
Vikram Aggarwal5e5ac742011-12-19 08:14:16 -080027import android.widget.TextView;
28
Mindy Pereira28d5f722012-02-15 12:32:40 -080029import com.android.mail.providers.Account;
Vikram Aggarwal7c401b72012-08-13 16:43:47 -070030import com.android.mail.providers.AccountObserver;
Mindy Pereiraf9323cd2012-02-29 13:47:09 -080031import com.android.mail.providers.Folder;
Vikram Aggarwal7a5d95a2012-07-27 16:24:54 -070032import com.android.mail.providers.FolderWatcher;
Vikram Aggarwal7c401b72012-08-13 16:43:47 -070033import com.android.mail.ui.ControllableActivity;
Vikram Aggarwal1a4bcc02012-03-01 10:09:44 -080034import com.android.mail.ui.RecentFolderList;
Paul Westbrookb334c902012-06-25 11:42:46 -070035import com.android.mail.utils.LogTag;
Vikram Aggarwal8183d452012-04-17 09:13:29 -070036import com.android.mail.utils.LogUtils;
Mindy Pereirac1469c72012-03-20 13:56:12 -070037import com.android.mail.utils.Utils;
Vikram Aggarwal8b152632012-02-03 14:58:45 -080038
Marc Blank167faa82012-03-21 13:11:53 -070039import java.util.ArrayList;
40
Vikram Aggarwal5e5ac742011-12-19 08:14:16 -080041/**
Mindy Pereiraae180202012-02-29 13:09:58 -080042 * An adapter to return the list of accounts and folders for the Account Spinner.
Vikram Aggarwala9b93f32012-02-23 14:51:58 -080043 * This class keeps the account and folder information and returns appropriate views.
Vikram Aggarwal5e5ac742011-12-19 08:14:16 -080044 */
Vikram Aggarwala9b93f32012-02-23 14:51:58 -080045public class AccountSpinnerAdapter extends BaseAdapter {
Vikram Aggarwal8b152632012-02-03 14:58:45 -080046 private final LayoutInflater mInflater;
47 /**
Mindy Pereira4067f2e2012-04-18 10:11:14 -070048 * The position of the current account being viewed.
49 */
50 private Account mCurrentAccount = null;
Vikram Aggarwal8b152632012-02-03 14:58:45 -080051 /**
52 * Total number of accounts.
53 */
Vikram Aggarwala9b93f32012-02-23 14:51:58 -080054 private int mNumAccounts = 0;
Vikram Aggarwal8b152632012-02-03 14:58:45 -080055 /**
Vikram Aggarwala9b93f32012-02-23 14:51:58 -080056 * Array of all the accounts on the device.
Vikram Aggarwal8b152632012-02-03 14:58:45 -080057 */
Vikram Aggarwalabd24d82012-04-26 13:23:14 -070058 private Account[] mAllAccounts = new Account[0];
Vikram Aggarwal8b152632012-02-03 14:58:45 -080059 /**
Vikram Aggarwal1a4bcc02012-03-01 10:09:44 -080060 * An object that provides a collection of recent folders, per account.
Vikram Aggarwal8b152632012-02-03 14:58:45 -080061 */
Vikram Aggarwal9d6b6b02012-03-08 10:36:30 -080062 private final RecentFolderList mRecentFolders;
Vikram Aggarwal8b152632012-02-03 14:58:45 -080063 /**
Vikram Aggarwal1a4bcc02012-03-01 10:09:44 -080064 * The actual collection of sorted recent folders obtained from {@link #mRecentFolders}
Vikram Aggarwal8b152632012-02-03 14:58:45 -080065 */
Marc Blank167faa82012-03-21 13:11:53 -070066 private ArrayList<Folder> mRecentFolderList = new ArrayList<Folder>();
Paul Westbrook904b5f22012-04-12 00:29:58 -070067 /**
68 * Boolean indicating whether the "Show All Folders" items should be shown
69 */
70 private final boolean mShowAllFoldersItem;
Vikram Aggarwal67f36fc2012-06-18 14:36:44 -070071 /**
72 * Set to true to enable recent folders, false to disable.
73 */
74 private boolean mRecentFoldersVisible;
Vikram Aggarwal1a4bcc02012-03-01 10:09:44 -080075
76 /** The folder currently being viewed */
Mindy Pereiraf9323cd2012-02-29 13:47:09 -080077 private Folder mCurrentFolder;
Vikram Aggarwal7a5d95a2012-07-27 16:24:54 -070078 private final Context mContext;
79 /** Maintains the most fresh default inbox folder for each account. Used for unread counts. */
80 private final FolderWatcher mFolderWatcher;
Vikram Aggarwal5e5ac742011-12-19 08:14:16 -080081
Vikram Aggarwal3da3c892012-08-21 15:00:22 -070082 /** Type indicating the current account view shown in the actionbar (not the dropdown) */
83 private static final int TYPE_NON_DROPDOWN = 0;
Vikram Aggarwal7a5d95a2012-07-27 16:24:54 -070084 /** Type indicating a dead, non-clickable view that is not shown to the user. */
Vikram Aggarwal3da3c892012-08-21 15:00:22 -070085 public static final int TYPE_DEAD_HEADER = 1;
Vikram Aggarwal7a5d95a2012-07-27 16:24:54 -070086 /** Type indicating an account (user@example.com). */
Vikram Aggarwal3da3c892012-08-21 15:00:22 -070087 public static final int TYPE_ACCOUNT = 2;
Vikram Aggarwal7a5d95a2012-07-27 16:24:54 -070088 /** Type indicating a view that separates the account list from the recent folder list. */
Vikram Aggarwal3da3c892012-08-21 15:00:22 -070089 public static final int TYPE_HEADER = 3;
Vikram Aggarwal7a5d95a2012-07-27 16:24:54 -070090 /** Type indicating a view containing a recent folder (Sent, Outbox). */
Vikram Aggarwal3da3c892012-08-21 15:00:22 -070091 public static final int TYPE_FOLDER = 4;
Vikram Aggarwal7a5d95a2012-07-27 16:24:54 -070092 /** Type indicating the "Show All Folders" view. */
Vikram Aggarwal3da3c892012-08-21 15:00:22 -070093 public static final int TYPE_ALL_FOLDERS = 5;
Vikram Aggarwal8b152632012-02-03 14:58:45 -080094
Paul Westbrookb334c902012-06-25 11:42:46 -070095 private static final String LOG_TAG = LogTag.getLogTag();
Vikram Aggarwal7a5d95a2012-07-27 16:24:54 -070096
Vikram Aggarwal7c401b72012-08-13 16:43:47 -070097 final AccountObserver mAccountObserver = new AccountObserver() {
98 @Override
99 public void onChanged(Account newAccount){
100 // If the account is missing or we have no accounts array, we cannot
101 // proceed.
102 if (newAccount == null) {
103 return;
104 }
105 if (newAccount.uri.equals(getCurrentAccountUri())) {
106 // The current account matches what is being given, get out.
107 return;
108 }
109 mCurrentAccount = newAccount;
110 final int pos = Account.findPosition(mAllAccounts, newAccount.uri);
111 LogUtils.d(LOG_TAG, "setCurrentAccount: mCurrentAccountPos = %d", pos);
112 if (pos >= 0) {
113 requestRecentFoldersAndRedraw();
114 }
115 notifyDataSetChanged();
116 }
117 };
118
Vikram Aggarwala9b93f32012-02-23 14:51:58 -0800119 /**
120 * There can be three types of views: Accounts (test@android.com, fifi@example.com), folders
121 * (Inbox, Outbox) or header and footer. This method returns the type of account at given
122 * position in the drop down list.
123 * @param position
124 * @return the type of account: one of {@link #TYPE_ACCOUNT}, {@link #TYPE_HEADER}, or
125 * {@link #TYPE_FOLDER}.
126 */
Mindy Pereira0e7f4632012-07-11 16:34:30 -0700127 public int getType(int position) {
Vikram Aggarwal67f36fc2012-06-18 14:36:44 -0700128 if (position == 0) {
129 return TYPE_DEAD_HEADER;
130 }
Vikram Aggarwal8b152632012-02-03 14:58:45 -0800131 // First the accounts
Vikram Aggarwal67f36fc2012-06-18 14:36:44 -0700132 if (position <= mNumAccounts) {
Vikram Aggarwal8b152632012-02-03 14:58:45 -0800133 return TYPE_ACCOUNT;
134 }
135 // Then the header
Vikram Aggarwal67f36fc2012-06-18 14:36:44 -0700136 if (position == mNumAccounts + 1) {
Vikram Aggarwal8b152632012-02-03 14:58:45 -0800137 return TYPE_HEADER;
138 }
Vikram Aggarwal67f36fc2012-06-18 14:36:44 -0700139 if (mShowAllFoldersItem && getRecentOffset(position) >= mRecentFolderList.size()) {
140 return TYPE_ALL_FOLDERS;
Paul Westbrook904b5f22012-04-12 00:29:58 -0700141 }
Vikram Aggarwal8b152632012-02-03 14:58:45 -0800142 // Finally, the recent folders.
143 return TYPE_FOLDER;
144 }
145
Vikram Aggarwalec5cbf72012-03-08 15:10:35 -0800146 /**
Vikram Aggarwal3da3c892012-08-21 15:00:22 -0700147 * Given a dropdown view, enable only the type, and disable everything else.
148 * @param view
149 * @param type
150 */
151 private static final void selectRelevant(View view, int type) {
152 if (view == null) {
153 return;
154 }
155 final View anchor = view.findViewById(R.id.anchor);
156 final View account = view.findViewById(R.id.account);
157 final View header = view.findViewById(R.id.header);
158 final View folder = view.findViewById(R.id.folder);
159 final View footer = view.findViewById(R.id.footer);
160 // Disable everything initially.
161 anchor.setVisibility(View.GONE);
162 account.setVisibility(View.GONE);
163 header.setVisibility(View.GONE);
164 folder.setVisibility(View.GONE);
165 footer.setVisibility(View.GONE);
166 switch (type) {
167 case TYPE_NON_DROPDOWN:
168 anchor.setVisibility(View.VISIBLE);
169 break;
170 case TYPE_DEAD_HEADER:
171 // Select nothing.
172 break;
173 case TYPE_ACCOUNT:
174 account.setVisibility(View.VISIBLE);
175 break;
176 case TYPE_HEADER:
177 header.setVisibility(View.VISIBLE);
178 break;
179 case TYPE_FOLDER:
180 folder.setVisibility(View.VISIBLE);
181 break;
182 case TYPE_ALL_FOLDERS:
183 footer.setVisibility(View.VISIBLE);
184 break;
185 }
186 }
187
188 /**
Vikram Aggarwal67f36fc2012-06-18 14:36:44 -0700189 * Given a position in the list, what offset does it correspond to in the Recent Folders
190 * list?
191 * @param position
192 * @return
193 */
194 private final int getRecentOffset(int position) {
195 return position - mNumAccounts - 2;
196 }
197
198 /**
Vikram Aggarwale6340bc2012-03-26 15:57:09 -0700199 * Returns the position of the dead, unselectable element in the spinner.
200 * @return
201 */
Vikram Aggarwal67f36fc2012-06-18 14:36:44 -0700202 public final int getSpacerPosition() {
203 // Return the position of the dead header, which is always at the top.
204 return 0;
Vikram Aggarwale6340bc2012-03-26 15:57:09 -0700205 }
206
207 /**
Vikram Aggarwalec5cbf72012-03-08 15:10:35 -0800208 * Create a spinner adapter with the context and the list of recent folders.
209 * @param context
210 * @param recentFolders
Paul Westbrook904b5f22012-04-12 00:29:58 -0700211 * @param showAllFolders
Vikram Aggarwalec5cbf72012-03-08 15:10:35 -0800212 */
Vikram Aggarwal7c401b72012-08-13 16:43:47 -0700213 public AccountSpinnerAdapter(ControllableActivity activity, Context context,
Vikram Aggarwal7a5d95a2012-07-27 16:24:54 -0700214 RecentFolderList recentFolders, boolean showAllFolders) {
Mindy Pereirac1469c72012-03-20 13:56:12 -0700215 mContext = context;
Vikram Aggarwal6f6afe52012-01-04 14:43:44 -0800216 mInflater = LayoutInflater.from(context);
Vikram Aggarwalec5cbf72012-03-08 15:10:35 -0800217 mRecentFolders = recentFolders;
Paul Westbrook904b5f22012-04-12 00:29:58 -0700218 mShowAllFoldersItem = showAllFolders;
Vikram Aggarwal7a5d95a2012-07-27 16:24:54 -0700219 // Owned by the AccountSpinnerAdapter since nobody else needed it. Move to controller if
Vikram Aggarwal1dd77c92012-08-21 09:27:40 -0700220 // required. The folder watcher tells us directly when new data is available. We are only
221 // interested in unread counts at this point.
222 mFolderWatcher = new FolderWatcher(activity, this);
Vikram Aggarwal7c401b72012-08-13 16:43:47 -0700223 mCurrentAccount = mAccountObserver.initialize(activity.getAccountController());
Vikram Aggarwal6f6afe52012-01-04 14:43:44 -0800224 }
225
Vikram Aggarwal8183d452012-04-17 09:13:29 -0700226 /**
Vikram Aggarwala9b93f32012-02-23 14:51:58 -0800227 * Set the accounts for this spinner.
228 * @param accounts
229 */
Vikram Aggarwalabd24d82012-04-26 13:23:14 -0700230 public void setAccountArray(Account[] accounts) {
Vikram Aggarwal8183d452012-04-17 09:13:29 -0700231 final Uri currentAccount = getCurrentAccountUri();
Vikram Aggarwalabd24d82012-04-26 13:23:14 -0700232 mAllAccounts = accounts;
Vikram Aggarwala9b93f32012-02-23 14:51:58 -0800233 mNumAccounts = accounts.length;
Mindy Pereira4067f2e2012-04-18 10:11:14 -0700234 if (!isCurrentAccountInvalid()) {
Vikram Aggarwal73bffaf2012-06-25 11:29:56 -0700235 final int pos = Account.findPosition(accounts, currentAccount);
236 LogUtils.d(LOG_TAG, "setAccountArray: mCurrentAccountPos = %d", pos);
Vikram Aggarwal8183d452012-04-17 09:13:29 -0700237 }
Vikram Aggarwal7a5d95a2012-07-27 16:24:54 -0700238 // Go through all the accounts and add the default inbox to our watcher.
239 for (int i=0; i < mNumAccounts; i++) {
240 final Uri uri = mAllAccounts[i].settings.defaultInbox;
241 mFolderWatcher.startWatching(uri);
242 }
Vikram Aggarwala9b93f32012-02-23 14:51:58 -0800243 notifyDataSetChanged();
244 }
245
Mindy Pereiraf9323cd2012-02-29 13:47:09 -0800246 /**
Mindy Pereirabc57bf12012-02-29 14:39:09 -0800247 * Set the current folder.
Mindy Pereiraf9323cd2012-02-29 13:47:09 -0800248 * @param folder
Mindy Pereiraa6be8482012-03-21 10:31:57 -0700249 * @return if changed.
Mindy Pereiraf9323cd2012-02-29 13:47:09 -0800250 */
Mindy Pereiraa6be8482012-03-21 10:31:57 -0700251 public boolean setCurrentFolder(Folder folder) {
252 if (folder != null && folder != mCurrentFolder) {
253 mCurrentFolder = folder;
Vikram Aggarwal37263972012-04-17 15:51:14 -0700254 requestRecentFoldersAndRedraw();
Mindy Pereiraa6be8482012-03-21 10:31:57 -0700255 return true;
256 }
257 return false;
Mindy Pereiraf9323cd2012-02-29 13:47:09 -0800258 }
259
Vikram Aggarwal5e5ac742011-12-19 08:14:16 -0800260 @Override
261 public int getCount() {
Vikram Aggarwal67f36fc2012-06-18 14:36:44 -0700262 // If the recent folders are visible, then one header, recent folders, plus one if the
Paul Westbrook904b5f22012-04-12 00:29:58 -0700263 // "show all folders" item should be shown
Vikram Aggarwale93a01e2012-07-23 12:53:00 -0700264 final int numRecents = mRecentFolderList.size();
265 final int numFolders = (mRecentFoldersVisible && numRecents > 0) ?
266 (1 + numRecents + (mShowAllFoldersItem ? 1 : 0)) : 0;
Vikram Aggarwal67f36fc2012-06-18 14:36:44 -0700267 return 1 + mNumAccounts + numFolders;
Vikram Aggarwal5e5ac742011-12-19 08:14:16 -0800268 }
269
Vikram Aggarwal5e5ac742011-12-19 08:14:16 -0800270 @Override
271 public Object getItem(int position) {
Mindy Pereira0e7f4632012-07-11 16:34:30 -0700272 switch (getType(position)){
Vikram Aggarwal67f36fc2012-06-18 14:36:44 -0700273 case TYPE_DEAD_HEADER:
274 return "dead header";
Vikram Aggarwal8b152632012-02-03 14:58:45 -0800275 case TYPE_ACCOUNT:
276 return getAccount(position);
277 case TYPE_HEADER:
278 return "account spinner header";
Paul Westbrook904b5f22012-04-12 00:29:58 -0700279 case TYPE_ALL_FOLDERS:
280 return "show all folders";
Vikram Aggarwal8b152632012-02-03 14:58:45 -0800281 default:
Marc Blank41e764d2012-03-20 20:46:28 -0700282 // Return the folder at this location.
Vikram Aggarwal67f36fc2012-06-18 14:36:44 -0700283 return mRecentFolderList.get(getRecentOffset(position));
Vikram Aggarwal8b152632012-02-03 14:58:45 -0800284 }
Vikram Aggarwal5e5ac742011-12-19 08:14:16 -0800285 }
286
Vikram Aggarwal5e5ac742011-12-19 08:14:16 -0800287 @Override
288 public long getItemId(int position) {
Vikram Aggarwal071fa7e2012-07-18 12:40:33 -0700289 final int type = getType(position);
290 switch (type) {
291 case TYPE_DEAD_HEADER:
292 // Fall-through
293 case TYPE_HEADER:
294 // Fall-through
295 case TYPE_ALL_FOLDERS:
296 return type;
297 case TYPE_ACCOUNT:
298 return getAccount(position).uri.hashCode();
299 default:
300 return mRecentFolderList.get(getRecentOffset(position)).uri.hashCode();
301 }
Vikram Aggarwal5e5ac742011-12-19 08:14:16 -0800302 }
303
Mindy Pereiraf9323cd2012-02-29 13:47:09 -0800304 private String getFolderLabel() {
305 return mCurrentFolder != null ? mCurrentFolder.name : "";
306 }
307
Mindy Pereirae973f222012-03-06 14:29:03 -0800308 private int getFolderUnreadCount() {
309 return mCurrentFolder != null ? mCurrentFolder.unreadCount : 0;
310 }
311
Vikram Aggarwal8183d452012-04-17 09:13:29 -0700312 /**
313 * Returns whether the current account is an invalid offset into the array.
314 * @return true if the current account is invalid, and false otherwise.
315 */
316 private boolean isCurrentAccountInvalid() {
Mindy Pereira4067f2e2012-04-18 10:11:14 -0700317 return mCurrentAccount == null;
Vikram Aggarwal8183d452012-04-17 09:13:29 -0700318 }
319
Mindy Pereiraa6be8482012-03-21 10:31:57 -0700320 private String getCurrentAccountName() {
Vikram Aggarwal73bffaf2012-06-25 11:29:56 -0700321 if (isCurrentAccountInvalid()) {
Vikram Aggarwal8183d452012-04-17 09:13:29 -0700322 return "";
323 }
Mindy Pereira5c9c9b82012-04-18 10:49:07 -0700324 return mCurrentAccount.name;
Vikram Aggarwal8183d452012-04-17 09:13:29 -0700325 }
326
327 private Uri getCurrentAccountUri() {
328 if (isCurrentAccountInvalid()) {
329 return Uri.EMPTY;
330 }
Mindy Pereira4067f2e2012-04-18 10:11:14 -0700331 return mCurrentAccount.uri;
Mindy Pereiraa6be8482012-03-21 10:31:57 -0700332 }
333
Vikram Aggarwal5e5ac742011-12-19 08:14:16 -0800334 @Override
Vikram Aggarwalc1057c62012-08-01 13:55:16 -0700335 public View getView(int position, View view, ViewGroup parent) {
336 if (view == null) {
Vikram Aggarwal3da3c892012-08-21 15:00:22 -0700337 view = mInflater.inflate(R.layout.account_switch_spinner_dropdown_item, null);
Mindy Pereira0e7f4632012-07-11 16:34:30 -0700338 }
Vikram Aggarwal3da3c892012-08-21 15:00:22 -0700339 selectRelevant(view, TYPE_NON_DROPDOWN);
340 ((TextView) view.findViewById(R.id.account_first)).setText(getFolderLabel());
341 ((TextView) view.findViewById(R.id.account_second))
Vikram Aggarwalc1057c62012-08-01 13:55:16 -0700342 .setText(getCurrentAccountName());
Vikram Aggarwal1dd77c92012-08-21 09:27:40 -0700343 final int currentViewUnreadCount = getFolderUnreadCount();
Vikram Aggarwal3da3c892012-08-21 15:00:22 -0700344 populateUnreadCountView((TextView) view.findViewById(R.id.account_unread),
345 currentViewUnreadCount);
Vikram Aggarwalc1057c62012-08-01 13:55:16 -0700346 return view;
Vikram Aggarwal5e5ac742011-12-19 08:14:16 -0800347 }
348
Vikram Aggarwal5e5ac742011-12-19 08:14:16 -0800349 @Override
Vikram Aggarwal5e5ac742011-12-19 08:14:16 -0800350 public boolean hasStableIds() {
Vikram Aggarwal071fa7e2012-07-18 12:40:33 -0700351 // The ID is the hash of the URI of the object.
352 return true;
Vikram Aggarwal5e5ac742011-12-19 08:14:16 -0800353 }
354
Vikram Aggarwal8b152632012-02-03 14:58:45 -0800355 @Override
356 public boolean isEmpty() {
357 // No item will be empty.
358 return false;
359 }
360
Vikram Aggarwal5e5ac742011-12-19 08:14:16 -0800361 @Override
Vikram Aggarwalc1057c62012-08-01 13:55:16 -0700362 public View getDropDownView(int position, View view, ViewGroup parent) {
Vikram Aggarwal5f09b6f2012-06-15 17:03:40 -0700363 // Shown in the first text view with big font.
364 String bigText = "";
365 // Shown in the second text view with smaller font.
366 String smallText = "";
Vikram Aggarwal8b152632012-02-03 14:58:45 -0800367 int unreadCount = 0;
Vikram Aggarwal3da3c892012-08-21 15:00:22 -0700368 // Do not use stop view recycling in getDropDownView!!!
369 // For unknown reasons, using view recycling avoids bugs where the unread count used to
370 // disappear.
371 final int type = getType(position);
372 if (view == null) {
373 view = mInflater.inflate(R.layout.account_switch_spinner_dropdown_item, null);
374 }
375 selectRelevant(view, type);
376 switch (type) {
Vikram Aggarwal67f36fc2012-06-18 14:36:44 -0700377 case TYPE_DEAD_HEADER:
Vikram Aggarwalc1057c62012-08-01 13:55:16 -0700378 return view;
Vikram Aggarwal67f36fc2012-06-18 14:36:44 -0700379 case TYPE_ACCOUNT:
Vikram Aggarwal5e63e8a2012-07-19 10:05:24 -0700380 final Account account = getAccount(position);
Vikram Aggarwalc5a575e2012-08-02 10:05:30 -0700381 View colorView = view.findViewById(R.id.account_spinner_color);
Vikram Aggarwal5e63e8a2012-07-19 10:05:24 -0700382 if (account == null) {
383 bigText = "";
384 smallText = "";
Vikram Aggarwal7a5d95a2012-07-27 16:24:54 -0700385 unreadCount = 0;
Vikram Aggarwalc5a575e2012-08-02 10:05:30 -0700386 colorView.setVisibility(View.INVISIBLE);
Vikram Aggarwal5e63e8a2012-07-19 10:05:24 -0700387 } else {
388 bigText = account.settings.defaultInboxName;
389 smallText = account.name;
Vikram Aggarwalc5a575e2012-08-02 10:05:30 -0700390 final int color = account.color;
391 if (color != 0) {
392 colorView.setVisibility(View.VISIBLE);
393 colorView.setBackgroundColor(color);
394 } else {
395 colorView.setVisibility(View.INVISIBLE);
396 }
Vikram Aggarwal7a5d95a2012-07-27 16:24:54 -0700397 final Folder inbox = mFolderWatcher.get(account.settings.defaultInbox);
398 unreadCount = (inbox != null) ? inbox.unreadCount : 0;
Vikram Aggarwal5e63e8a2012-07-19 10:05:24 -0700399 }
Vikram Aggarwal3da3c892012-08-21 15:00:22 -0700400 displayOrHide(view, R.id.abd_account_first, bigText);
401 displayOrHide(view, R.id.abd_account_second, smallText);
402 populateUnreadCountView(
403 (TextView) view.findViewById(R.id.abd_account_unread), unreadCount);
Vikram Aggarwal67f36fc2012-06-18 14:36:44 -0700404 break;
Vikram Aggarwal8b152632012-02-03 14:58:45 -0800405 case TYPE_HEADER:
Vikram Aggarwalc1057c62012-08-01 13:55:16 -0700406 ((TextView) view.findViewById(R.id.account_spinner_header_account))
407 .setText(getCurrentAccountName());
408 return view;
Vikram Aggarwal8b152632012-02-03 14:58:45 -0800409 case TYPE_FOLDER:
Vikram Aggarwal67f36fc2012-06-18 14:36:44 -0700410 final Folder folder = mRecentFolderList.get(getRecentOffset(position));
Vikram Aggarwal3da3c892012-08-21 15:00:22 -0700411 colorView = view.findViewById(R.id.abd_folder_color);
Vikram Aggarwal5f09b6f2012-06-15 17:03:40 -0700412 bigText = folder.name;
Vikram Aggarwal1a4bcc02012-03-01 10:09:44 -0800413 unreadCount = folder.unreadCount;
Vikram Aggarwalc5a575e2012-08-02 10:05:30 -0700414 Folder.setFolderBlockColor(folder, colorView);
415 colorView.setVisibility(View.VISIBLE);
Vikram Aggarwal3da3c892012-08-21 15:00:22 -0700416 displayOrHide(view, R.id.abd_folder_first, bigText);
417 displayOrHide(view, R.id.abd_folder_second, smallText);
418 populateUnreadCountView(
419 (TextView) view.findViewById(R.id.abd_folder_unread), unreadCount);
Vikram Aggarwal8b152632012-02-03 14:58:45 -0800420 break;
Paul Westbrook904b5f22012-04-12 00:29:58 -0700421 case TYPE_ALL_FOLDERS:
Vikram Aggarwalc1057c62012-08-01 13:55:16 -0700422 return view;
Vikram Aggarwal6f6afe52012-01-04 14:43:44 -0800423 }
Vikram Aggarwalc1057c62012-08-01 13:55:16 -0700424 return view;
Vikram Aggarwal6f6afe52012-01-04 14:43:44 -0800425 }
426
Vikram Aggarwal5f09b6f2012-06-15 17:03:40 -0700427 /**
428 * Sets the text of the TextView to the given text, if it is non-empty. If the given
429 * text is empty, then the TextView is hidden (set to View.GONE).
430 * @param v
431 * @param resourceId
432 * @param toDisplay the given text
433 */
434 static private void displayOrHide(View v, int resourceId, String toDisplay) {
435 final TextView target = (TextView) v.findViewById(resourceId);
Vikram Aggarwal59926d62012-07-19 14:49:11 -0700436 if (TextUtils.isEmpty(toDisplay)) {
Vikram Aggarwal5f09b6f2012-06-15 17:03:40 -0700437 target.setVisibility(View.GONE);
438 return;
439 }
440 target.setText(toDisplay);
441 }
Mindy Pereiraa6be8482012-03-21 10:31:57 -0700442
Vikram Aggarwal1dd77c92012-08-21 09:27:40 -0700443 /**
444 * Sets the unread count, which is a nonzero number or an empty string if there are no unread
445 * messages.
446 * @param unreadCountView
447 * @param unreadCount
448 */
449 private final void populateUnreadCountView(TextView unreadCountView, int unreadCount) {
Mindy Pereiraa6be8482012-03-21 10:31:57 -0700450 unreadCountView.setText(Utils.getUnreadCountString(mContext, unreadCount));
Mindy Pereiraa6be8482012-03-21 10:31:57 -0700451 }
452
Vikram Aggarwal8b152632012-02-03 14:58:45 -0800453 /**
Mindy Pereira28d5f722012-02-15 12:32:40 -0800454 * Returns the account given position in the spinner.
455 * @param position
Vikram Aggarwala9b93f32012-02-23 14:51:58 -0800456 * @return the account at the given position.
Mindy Pereira28d5f722012-02-15 12:32:40 -0800457 */
458 private Account getAccount(int position) {
Vikram Aggarwal5e63e8a2012-07-19 10:05:24 -0700459 if (position >= mNumAccounts + 1) {
460 return null;
461 }
Vikram Aggarwal67f36fc2012-06-18 14:36:44 -0700462 return mAllAccounts[position - 1];
Mindy Pereira28d5f722012-02-15 12:32:40 -0800463 }
464
Vikram Aggarwal8b152632012-02-03 14:58:45 -0800465
Vikram Aggarwal6f6afe52012-01-04 14:43:44 -0800466 @Override
467 public boolean isEnabled(int position) {
468 // Don't want the user selecting the header.
Mindy Pereira0e7f4632012-07-11 16:34:30 -0700469 final int type = getType(position);
Vikram Aggarwal071fa7e2012-07-18 12:40:33 -0700470 return type != TYPE_HEADER;
Vikram Aggarwal6f6afe52012-01-04 14:43:44 -0800471 }
472
473 @Override
474 public boolean areAllItemsEnabled() {
Vikram Aggarwal8b152632012-02-03 14:58:45 -0800475 // The header is not enabled, so return false here.
Vikram Aggarwal6f6afe52012-01-04 14:43:44 -0800476 return false;
Vikram Aggarwal5e5ac742011-12-19 08:14:16 -0800477 }
Mindy Pereiraa46a57f2012-04-03 17:19:31 -0700478
479 /**
480 * Notify that the folder has changed.
481 */
482 public void onFolderUpdated(Folder folder) {
483 mCurrentFolder = folder;
484 notifyDataSetChanged();
485 }
Vikram Aggarwal37263972012-04-17 15:51:14 -0700486
487 /**
488 * Cause a refresh of the recent folders for the current folder and redraw the spinner with
489 * the new information.
490 */
491 public void requestRecentFoldersAndRedraw() {
492 mRecentFolderList = mRecentFolders.getRecentFolderList(mCurrentFolder);
493 notifyDataSetChanged();
494 }
Vikram Aggarwal67f36fc2012-06-18 14:36:44 -0700495
496 /**
497 * Disable recent folders. Can be enabled again with {@link #enableRecentFolders()}
498 */
499 public void disableRecentFolders() {
500 if (mRecentFoldersVisible) {
501 notifyDataSetChanged();
502 mRecentFoldersVisible = false;
503 }
504 }
505
506 /**
507 * Enable recent folders. Can be disabled again with {@link #disableRecentFolders()}
508 */
509 public void enableRecentFolders() {
510 if (!mRecentFoldersVisible) {
511 notifyDataSetChanged();
512 mRecentFoldersVisible = true;
513 }
514 }
Vikram Aggarwal7c401b72012-08-13 16:43:47 -0700515
516 /**
517 * Destroys the spinner adapter
518 */
519 public void destroy() {
520 mAccountObserver.unregisterAndDestroy();
521 }
Vikram Aggarwal5e5ac742011-12-19 08:14:16 -0800522}