1
0
mirror of https://github.com/moparisthebest/k-9 synced 2024-08-13 17:03:48 -04:00
k-9/src/com/fsck/k9/activity/FolderList.java
Daniel Applebaum 9cf42ef913 Provide for tracking all WakeLock usage.
Simplify WakeLocks use by pushing.

Correct fault in IMAP IDLE WakeLock usage.  The ThreadLocal in
MessagingControllerPushReceiver meant that the WakeLock acquired when
the DONE was sent was not being released when entering back into IDLE
state.

Consolidate the account notification so that all Activities use the
methods in MessagingController.
2010-05-17 00:30:32 +00:00

1543 lines
45 KiB
Java

package com.fsck.k9.activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.PowerManager;
import android.os.PowerManager.WakeLock;
import android.util.Config;
import android.util.Log;
import android.util.TypedValue;
import android.view.*;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.View.OnClickListener;
import android.widget.*;
import android.widget.AdapterView.AdapterContextMenuInfo;
import android.widget.AdapterView.OnItemClickListener;
import com.fsck.k9.*;
import com.fsck.k9.Account.FolderMode;
import com.fsck.k9.activity.setup.AccountSettings;
import com.fsck.k9.activity.setup.FolderSettings;
import com.fsck.k9.helper.power.TracingPowerManager;
import com.fsck.k9.helper.power.TracingPowerManager.TracingWakeLock;
import com.fsck.k9.mail.Flag;
import com.fsck.k9.mail.Folder;
import com.fsck.k9.mail.Message;
import com.fsck.k9.mail.MessagingException;
import com.fsck.k9.service.MailService;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
/**
* FolderList is the primary user interface for the program. This
* Activity shows list of the Account's folders
*/
public class FolderList extends K9ListActivity
{
private static final int DIALOG_MARK_ALL_AS_READ = 1;
private static final String EXTRA_ACCOUNT = "account";
private static final String EXTRA_INITIAL_FOLDER = "initialFolder";
private static final String EXTRA_FROM_NOTIFICATION = "fromNotification";
private static final boolean REFRESH_REMOTE = true;
private ListView mListView;
private FolderListAdapter mAdapter;
private LayoutInflater mInflater;
private Account mAccount;
private FolderListHandler mHandler = new FolderListHandler();
private int mUnreadMessageCount;
private FontSizes mFontSizes = K9.getFontSizes();
class FolderListHandler extends Handler
{
public void refreshTitle()
{
runOnUiThread(new Runnable()
{
public void run()
{
String dispString = mAdapter.mListener.formatHeader(FolderList.this,
getString(R.string.folder_list_title, mAccount.getDescription()), mUnreadMessageCount, getTimeFormat());
setTitle(dispString);
}
});
}
public void newFolders(final List<FolderInfoHolder> newFolders)
{
runOnUiThread(new Runnable()
{
public void run()
{
mAdapter.mFolders.clear();
mAdapter.mFolders.addAll(newFolders);
mHandler.dataChanged();
}
});
}
public void workingAccount(final int res)
{
runOnUiThread(new Runnable()
{
public void run()
{
String toastText = getString(res, mAccount.getDescription());
Toast toast = Toast.makeText(getApplication(), toastText, Toast.LENGTH_SHORT);
toast.show();
}
});
}
public void accountSizeChanged(final long oldSize, final long newSize)
{
runOnUiThread(new Runnable()
{
public void run()
{
String toastText = getString(R.string.account_size_changed, mAccount.getDescription(), SizeFormatter.formatSize(getApplication(), oldSize), SizeFormatter.formatSize(getApplication(), newSize));
Toast toast = Toast.makeText(getApplication(), toastText, Toast.LENGTH_LONG);
toast.show();
}
});
}
public void folderLoading(final String folder, final boolean loading)
{
runOnUiThread(new Runnable()
{
public void run()
{
FolderInfoHolder folderHolder = mAdapter.getFolder(folder);
if (folderHolder != null)
{
folderHolder.loading = loading;
}
}
});
}
public void progress(final boolean progress)
{
runOnUiThread(new Runnable()
{
public void run()
{
setProgressBarIndeterminateVisibility(progress);
}
});
}
public void dataChanged()
{
runOnUiThread(new Runnable()
{
public void run()
{
mAdapter.notifyDataSetChanged();
}
});
}
}
/**
* This class is responsible for reloading the list of local messages for a
* given folder, notifying the adapter that the message have been loaded and
* queueing up a remote update of the folder.
*/
private void checkMail(FolderInfoHolder folder)
{
TracingPowerManager pm = TracingPowerManager.getPowerManager(this);
final TracingWakeLock wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "FolderList checkMail");
wakeLock.setReferenceCounted(false);
wakeLock.acquire(K9.WAKE_LOCK_TIMEOUT);
MessagingListener listener = new MessagingListener()
{
@Override
public void synchronizeMailboxFinished(Account account, String folder, int totalMessagesInMailbox, int numNewMessages)
{
if (!account.equals(mAccount))
{
return;
}
wakeLock.release();
}
@Override
public void synchronizeMailboxFailed(Account account, String folder,
String message)
{
if (!account.equals(mAccount))
{
return;
}
wakeLock.release();
}
};
MessagingController.getInstance(getApplication()).synchronizeMailbox(mAccount, folder.name, listener, null);
sendMail(mAccount);
}
private static void actionHandleAccount(Context context, Account account, String initialFolder)
{
Intent intent = new Intent(context, FolderList.class);
intent.putExtra(EXTRA_ACCOUNT, account.getUuid());
if (initialFolder != null)
{
intent.putExtra(EXTRA_INITIAL_FOLDER, initialFolder);
}
context.startActivity(intent);
}
public static void actionHandleAccount(Context context, Account account)
{
actionHandleAccount(context, account, null);
}
public static Intent actionHandleNotification(Context context, Account account, String initialFolder)
{
Intent intent = new Intent(
Intent.ACTION_VIEW,
Uri.parse("email://accounts/" + account.getAccountNumber()),
context,
FolderList.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra(EXTRA_ACCOUNT, account.getUuid());
intent.putExtra(EXTRA_FROM_NOTIFICATION, true);
if (initialFolder != null)
{
intent.putExtra(EXTRA_INITIAL_FOLDER, initialFolder);
}
return intent;
}
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
setContentView(R.layout.folder_list);
mListView = getListView();
mListView.setScrollBarStyle(View.SCROLLBARS_OUTSIDE_INSET);
mListView.setLongClickable(true);
mListView.setFastScrollEnabled(true);
mListView.setScrollingCacheEnabled(true);
mListView.setOnItemClickListener(new OnItemClickListener()
{
public void onItemClick(AdapterView<?> parent, View view, int position, long id)
{
onOpenFolder(((FolderInfoHolder)mAdapter.getItem(id)).name);
}
});
registerForContextMenu(mListView);
mListView.setSaveEnabled(true);
mInflater = getLayoutInflater();
onNewIntent(getIntent());
}
@Override
public void onNewIntent(Intent intent)
{
setIntent(intent); // onNewIntent doesn't autoset our "internal" intent
String initialFolder;
mUnreadMessageCount = 0;
String accountUuid = intent.getStringExtra(EXTRA_ACCOUNT);
mAccount = Preferences.getPreferences(this).getAccount(accountUuid);
initialFolder = intent.getStringExtra(EXTRA_INITIAL_FOLDER);
boolean fromNotification = intent.getBooleanExtra(EXTRA_FROM_NOTIFICATION, false);
if (fromNotification && mAccount.goToUnreadMessageSearch())
{
MessagingController.getInstance(getApplication()).notifyAccountCancel(this, mAccount);
openUnreadSearch(this, mAccount);
finish();
}
else if (initialFolder != null && !K9.FOLDER_NONE.equals(initialFolder))
{
onOpenFolder(initialFolder);
finish();
}
else
{
initializeActivityView();
}
}
private void initializeActivityView()
{
mAdapter = new FolderListAdapter();
final Object previousData = getLastNonConfigurationInstance();
if (previousData != null)
{
//noinspection unchecked
mAdapter.mFolders = (ArrayList<FolderInfoHolder>) previousData;
}
setListAdapter(mAdapter);
setTitle(mAccount.getDescription());
}
@Override public Object onRetainNonConfigurationInstance()
{
return mAdapter.mFolders;
}
@Override public void onPause()
{
super.onPause();
MessagingController.getInstance(getApplication()).removeListener(mAdapter.mListener);
}
/**
* On resume we refresh the folder list (in the background) and we refresh the
* messages for any folder that is currently open. This guarantees that things
* like unread message count and read status are updated.
*/
@Override public void onResume()
{
super.onResume();
if (mAdapter == null)
initializeActivityView();
MessagingController.getInstance(getApplication()).addListener(mAdapter.mListener);
//mAccount.refresh(Preferences.getPreferences(this));
MessagingController.getInstance(getApplication()).getAccountStats(this, mAccount, mAdapter.mListener);
onRefresh(!REFRESH_REMOTE);
MessagingController.getInstance(getApplication()).notifyAccountCancel(this, mAccount);
}
@Override public boolean onKeyDown(int keyCode, KeyEvent event)
{
//Shortcuts that work no matter what is selected
switch (keyCode)
{
case KeyEvent.KEYCODE_Q:
//case KeyEvent.KEYCODE_BACK:
{
onAccounts();
return true;
}
case KeyEvent.KEYCODE_S:
{
onEditAccount();
return true;
}
case KeyEvent.KEYCODE_H:
{
Toast toast = Toast.makeText(this, R.string.folder_list_help_key, Toast.LENGTH_LONG);
toast.show();
return true;
}
case KeyEvent.KEYCODE_1:
{
setDisplayMode(FolderMode.FIRST_CLASS);
return true;
}
case KeyEvent.KEYCODE_2:
{
setDisplayMode(FolderMode.FIRST_AND_SECOND_CLASS);
return true;
}
case KeyEvent.KEYCODE_3:
{
setDisplayMode(FolderMode.NOT_SECOND_CLASS);
return true;
}
case KeyEvent.KEYCODE_4:
{
setDisplayMode(FolderMode.ALL);
return true;
}
}//switch
return super.onKeyDown(keyCode, event);
}//onKeyDown
private void setDisplayMode(FolderMode newMode)
{
mAccount.setFolderDisplayMode(newMode);
mAccount.save(Preferences.getPreferences(this));
if (mAccount.getFolderPushMode() != FolderMode.NONE)
{
MailService.actionRestartPushers(this, null);
}
onRefresh(false);
}
private void onRefresh(final boolean forceRemote)
{
MessagingController.getInstance(getApplication()).listFolders(mAccount, forceRemote, mAdapter.mListener);
}
private void onEditAccount()
{
AccountSettings.actionSettings(this, mAccount);
}
private void onEditFolder(Account account, String folderName)
{
FolderSettings.actionSettings(this, account, folderName);
}
private void onAccounts()
{
Accounts.listAccounts(this);
finish();
}
private void onEmptyTrash(final Account account)
{
mHandler.dataChanged();
MessagingController.getInstance(getApplication()).emptyTrash(account, null);
}
private void onExpunge(final Account account, String folderName)
{
MessagingController.getInstance(getApplication()).expunge(account, folderName, null);
}
private void checkMail(final Account account)
{
MessagingController.getInstance(getApplication()).checkMail(this, account, true, true, mAdapter.mListener);
}
private void sendMail(Account account)
{
MessagingController.getInstance(getApplication()).sendPendingMessages(account, mAdapter.mListener);
}
@Override public boolean onOptionsItemSelected(MenuItem item)
{
switch (item.getItemId())
{
case R.id.compose:
MessageCompose.actionCompose(this, mAccount);
return true;
case R.id.check_mail:
checkMail(mAccount);
return true;
case R.id.send_messages:
MessagingController.getInstance(getApplication()).sendPendingMessages(mAccount, null);
return true;
case R.id.accounts:
onAccounts();
return true;
case R.id.list_folders:
onRefresh(REFRESH_REMOTE);
return true;
case R.id.account_settings:
onEditAccount();
return true;
case R.id.empty_trash:
onEmptyTrash(mAccount);
return true;
case R.id.compact:
onCompact(mAccount);
return true;
case R.id.display_1st_class:
{
setDisplayMode(FolderMode.FIRST_CLASS);
return true;
}
case R.id.display_1st_and_2nd_class:
{
setDisplayMode(FolderMode.FIRST_AND_SECOND_CLASS);
return true;
}
case R.id.display_not_second_class:
{
setDisplayMode(FolderMode.NOT_SECOND_CLASS);
return true;
}
case R.id.display_all:
{
setDisplayMode(FolderMode.ALL);
return true;
}
default:
return super.onOptionsItemSelected(item);
}
}
private void onOpenFolder(String folder)
{
MessageList.actionHandleFolder(this, mAccount, folder);
}
private void onCompact(Account account)
{
mHandler.workingAccount(R.string.compacting_account);
MessagingController.getInstance(getApplication()).compact(account, null);
}
@Override public boolean onCreateOptionsMenu(Menu menu)
{
super.onCreateOptionsMenu(menu);
getMenuInflater().inflate(R.menu.folder_list_option, menu);
return true;
}
@Override public boolean onContextItemSelected(MenuItem item)
{
AdapterContextMenuInfo info = (AdapterContextMenuInfo) item .getMenuInfo();
FolderInfoHolder folder = (FolderInfoHolder) mAdapter.getItem(info.position);
switch (item.getItemId())
{
case R.id.open_folder:
onOpenFolder(folder.name);
break;
case R.id.mark_all_as_read:
onMarkAllAsRead(mAccount, folder.name);
break;
case R.id.send_messages:
sendMail(mAccount);
break;
case R.id.check_mail:
checkMail(folder);
break;
case R.id.folder_settings:
onEditFolder(mAccount, folder.name);
break;
case R.id.empty_trash:
onEmptyTrash(mAccount);
break;
case R.id.expunge:
onExpunge(mAccount, folder.name);
break;
}
return super.onContextItemSelected(item);
}
private FolderInfoHolder mSelectedContextFolder = null;
private void onMarkAllAsRead(final Account account, final String folder)
{
mSelectedContextFolder = mAdapter.getFolder(folder);
showDialog(DIALOG_MARK_ALL_AS_READ);
}
@Override
public Dialog onCreateDialog(int id)
{
switch (id)
{
case DIALOG_MARK_ALL_AS_READ:
return createMarkAllAsReadDialog();
}
return super.onCreateDialog(id);
}
@Override
public void onPrepareDialog(int id, Dialog dialog)
{
switch (id)
{
case DIALOG_MARK_ALL_AS_READ:
((AlertDialog)dialog).setMessage(getString(R.string.mark_all_as_read_dlg_instructions_fmt,
mSelectedContextFolder.displayName));
break;
default:
super.onPrepareDialog(id, dialog);
}
}
private Dialog createMarkAllAsReadDialog()
{
return new AlertDialog.Builder(this)
.setTitle(R.string.mark_all_as_read_dlg_title)
.setMessage(getString(R.string.mark_all_as_read_dlg_instructions_fmt,
mSelectedContextFolder.displayName))
.setPositiveButton(R.string.okay_action, new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int whichButton)
{
dismissDialog(DIALOG_MARK_ALL_AS_READ);
try
{
MessagingController.getInstance(getApplication()).markAllMessagesRead(mAccount, mSelectedContextFolder.name);
mSelectedContextFolder.unreadMessageCount = 0;
mHandler.dataChanged();
}
catch (Exception e)
{
// Ignore
}
}
})
.setNegativeButton(R.string.cancel_action, new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int whichButton)
{
dismissDialog(DIALOG_MARK_ALL_AS_READ);
}
})
.create();
}
@Override public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo)
{
super.onCreateContextMenu(menu, v, menuInfo);
AdapterContextMenuInfo info = (AdapterContextMenuInfo) menuInfo;
getMenuInflater().inflate(R.menu.folder_context, menu);
FolderInfoHolder folder = (FolderInfoHolder) mAdapter.getItem(info.position);
menu.setHeaderTitle((CharSequence) folder.displayName);
if (!folder.name.equals(mAccount.getTrashFolderName()))
menu.findItem(R.id.empty_trash).setVisible(false);
if (folder.outbox)
{
menu.findItem(R.id.check_mail).setVisible(false);
}
else
{
menu.findItem(R.id.send_messages).setVisible(false);
}
if (K9.ERROR_FOLDER_NAME.equals(folder.name))
{
menu.findItem(R.id.expunge).setVisible(false);
}
menu.setHeaderTitle(folder.displayName);
}
private String truncateStatus(String mess)
{
if (mess != null && mess.length() > 27)
{
mess = mess.substring(0, 27);
}
return mess;
}
class FolderListAdapter extends BaseAdapter
{
private ArrayList<FolderInfoHolder> mFolders = new ArrayList<FolderInfoHolder>();
public Object getItem(long position)
{
return getItem((int)position);
}
public Object getItem(int position)
{
return mFolders.get(position);
}
public long getItemId(int position)
{
return position ;
}
public int getCount()
{
return mFolders.size();
}
@Override
public boolean isEnabled(int item)
{
return true;
}
@Override
public boolean areAllItemsEnabled()
{
return true;
}
private ActivityListener mListener = new ActivityListener()
{
@Override
public void accountStatusChanged(BaseAccount account, AccountStats stats)
{
if (!account.equals(mAccount))
{
return;
}
mUnreadMessageCount = stats.unreadMessageCount;
mHandler.refreshTitle();
}
@Override
public void listFoldersStarted(Account account)
{
if (!account.equals(mAccount))
{
return;
}
mHandler.progress(true);
}
@Override
public void listFoldersFailed(Account account, String message)
{
if (!account.equals(mAccount))
{
return;
}
mHandler.progress(false);
if (Config.LOGV)
{
Log.v(K9.LOG_TAG, "listFoldersFailed " + message);
}
}
@Override
public void listFoldersFinished(Account account)
{
if (!account.equals(mAccount))
{
return;
}
mHandler.progress(false);
MessagingController.getInstance(getApplication()).refreshListener(mAdapter.mListener);
mHandler.dataChanged();
}
@Override
public void listFolders(Account account, Folder[] folders)
{
if (!account.equals(mAccount))
{
return;
}
List<FolderInfoHolder> newFolders = new LinkedList<FolderInfoHolder>();
List<FolderInfoHolder> topFolders = new LinkedList<FolderInfoHolder>();
Account.FolderMode aMode = account.getFolderDisplayMode();
Preferences prefs = Preferences.getPreferences(getApplication().getApplicationContext());
for (Folder folder : folders)
{
try
{
folder.refresh(prefs);
Folder.FolderClass fMode = folder.getDisplayClass();
if ((aMode == Account.FolderMode.FIRST_CLASS && fMode != Folder.FolderClass.FIRST_CLASS)
|| (aMode == Account.FolderMode.FIRST_AND_SECOND_CLASS &&
fMode != Folder.FolderClass.FIRST_CLASS &&
fMode != Folder.FolderClass.SECOND_CLASS)
|| (aMode == Account.FolderMode.NOT_SECOND_CLASS && fMode == Folder.FolderClass.SECOND_CLASS))
{
continue;
}
}
catch (MessagingException me)
{
Log.e(K9.LOG_TAG, "Couldn't get prefs to check for displayability of folder " + folder.getName(), me);
}
FolderInfoHolder holder = null;
int folderIndex = getFolderIndex(folder.getName());
if (folderIndex >= 0)
{
holder = (FolderInfoHolder) getItem(folderIndex);
}
int unreadMessageCount = 0;
try
{
unreadMessageCount = folder.getUnreadMessageCount();
}
catch (Exception e)
{
Log.e(K9.LOG_TAG, "Unable to get unreadMessageCount for " + mAccount.getDescription() + ":"
+ folder.getName());
}
if (holder == null)
{
holder = new FolderInfoHolder(folder, unreadMessageCount);
}
else
{
holder.populate(folder, unreadMessageCount);
}
if (folder.isInTopGroup())
{
topFolders.add(holder);
}
else
{
newFolders.add(holder);
}
}
Collections.sort(newFolders);
Collections.sort(topFolders);
topFolders.addAll(newFolders);
mHandler.newFolders(topFolders);
mHandler.refreshTitle();
}
@Override
public void synchronizeMailboxStarted(Account account, String folder)
{
super.synchronizeMailboxStarted(account, folder);
mHandler.refreshTitle();
if (!account.equals(mAccount))
{
return;
}
mHandler.progress(true);
mHandler.folderLoading(folder, true);
mHandler.dataChanged();
}
@Override
public void synchronizeMailboxProgress(Account account, String folder, int completed, int total)
{
super.synchronizeMailboxProgress(account, folder, completed, total);
mHandler.refreshTitle();
}
@Override
public void synchronizeMailboxFinished(Account account, String folder, int totalMessagesInMailbox, int numNewMessages)
{
super.synchronizeMailboxFinished(account, folder, totalMessagesInMailbox, numNewMessages);
mHandler.refreshTitle();
if (!account.equals(mAccount))
{
return;
}
mHandler.progress(false);
mHandler.folderLoading(folder, false);
refreshFolder(account, folder);
}
private void refreshFolder(Account account, String folderName)
{
// There has to be a cheaper way to get at the localFolder object than this
Folder localFolder = null;
try
{
if (account != null && folderName != null)
{
localFolder = account.getLocalStore().getFolder(folderName);
int unreadMessageCount = localFolder.getUnreadMessageCount();
if (localFolder != null)
{
FolderInfoHolder folderHolder = getFolder(folderName);
if (folderHolder != null)
{
folderHolder.populate(localFolder, unreadMessageCount);
mHandler.dataChanged();
}
}
}
}
catch (Exception e)
{
Log.e(K9.LOG_TAG, "Exception while populating folder", e);
}
finally
{
if (localFolder != null)
{
localFolder.close();
}
}
}
@Override
public void synchronizeMailboxFailed(Account account, String folder,
String message)
{
super.synchronizeMailboxFailed(account, folder, message);
mHandler.refreshTitle();
if (!account.equals(mAccount))
{
return;
}
mHandler.progress(false);
mHandler.folderLoading(folder, false);
// String mess = truncateStatus(message);
// mHandler.folderStatus(folder, mess);
FolderInfoHolder holder = getFolder(folder);
if (holder != null)
{
holder.lastChecked = 0;
}
mHandler.dataChanged();
}
@Override
public void setPushActive(Account account, String folderName, boolean enabled)
{
if (!account.equals(mAccount))
{
return;
}
FolderInfoHolder holder = getFolder(folderName);
if (holder != null)
{
holder.pushActive = enabled;
mHandler.dataChanged();
}
}
@Override
public void messageDeleted(Account account,
String folder, Message message)
{
synchronizeMailboxRemovedMessage(account,
folder, message);
}
@Override
public void emptyTrashCompleted(Account account)
{
if (!account.equals(mAccount))
{
return;
}
refreshFolder(account, mAccount.getTrashFolderName());
}
@Override
public void folderStatusChanged(Account account, String folderName, int unreadMessageCount)
{
if (!account.equals(mAccount))
{
return;
}
refreshFolder(account, folderName);
}
@Override
public void sendPendingMessagesCompleted(Account account)
{
super.sendPendingMessagesCompleted(account);
mHandler.refreshTitle();
if (!account.equals(mAccount))
{
return;
}
refreshFolder(account, mAccount.getOutboxFolderName());
}
@Override
public void sendPendingMessagesStarted(Account account)
{
super.sendPendingMessagesStarted(account);
mHandler.refreshTitle();
if (!account.equals(mAccount))
{
return;
}
mHandler.dataChanged();
}
@Override
public void sendPendingMessagesFailed(Account account)
{
super.sendPendingMessagesFailed(account);
mHandler.refreshTitle();
if (!account.equals(mAccount))
{
return;
}
refreshFolder(account, mAccount.getOutboxFolderName());
}
@Override
public void accountSizeChanged(Account account, long oldSize, long newSize)
{
if (!account.equals(mAccount))
{
return;
}
mHandler.accountSizeChanged(oldSize, newSize);
}
@Override
public void pendingCommandsProcessing(Account account)
{
super.pendingCommandsProcessing(account);
mHandler.refreshTitle();
}
@Override
public void pendingCommandsFinished(Account account)
{
super.pendingCommandsFinished(account);
mHandler.refreshTitle();
}
@Override
public void pendingCommandStarted(Account account, String commandTitle)
{
super.pendingCommandStarted(account, commandTitle);
mHandler.refreshTitle();
}
@Override
public void pendingCommandCompleted(Account account, String commandTitle)
{
super.pendingCommandCompleted(account, commandTitle);
mHandler.refreshTitle();
}
};
public int getFolderIndex(String folder)
{
FolderInfoHolder searchHolder = new FolderInfoHolder();
searchHolder.name = folder;
return mFolders.indexOf((Object) searchHolder);
}
public FolderInfoHolder getFolder(String folder)
{
FolderInfoHolder holder = null;
int index = getFolderIndex(folder);
if (index >= 0)
{
holder = (FolderInfoHolder) getItem(index);
if (holder != null)
{
return holder;
}
}
return null;
}
public View getView(int position, View convertView, ViewGroup parent)
{
if (position <= getCount())
{
return getItemView(position, convertView, parent);
}
else
{
// XXX TODO - should catch an exception here
return null;
}
}
public View getItemView(int itemPosition, View convertView, ViewGroup parent)
{
FolderInfoHolder folder = (FolderInfoHolder) getItem(itemPosition);
View view;
if ((convertView != null) && (convertView.getId() == R.layout.folder_list_item))
{
view = convertView;
}
else
{
view = mInflater.inflate(R.layout.folder_list_item, parent, false);
view.setId(R.layout.folder_list_item);
}
FolderViewHolder holder = (FolderViewHolder) view.getTag();
if (holder == null)
{
holder = new FolderViewHolder();
holder.folderName = (TextView) view.findViewById(R.id.folder_name);
holder.newMessageCount = (TextView) view.findViewById(R.id.folder_unread_message_count);
holder.flaggedMessageCount = (TextView) view.findViewById(R.id.folder_flagged_message_count);
holder.folderStatus = (TextView) view.findViewById(R.id.folder_status);
holder.activeIcons = (RelativeLayout) view.findViewById(R.id.active_icons);
holder.chip = view.findViewById(R.id.chip);
holder.rawFolderName = folder.name;
view.setTag(holder);
}
if (folder == null)
{
return view;
}
holder.folderName.setText(folder.displayName);
String statusText = "";
if (folder.loading)
{
statusText = getString(R.string.status_loading);
}
else if (folder.status != null)
{
statusText = folder.status;
}
else if (folder.lastChecked != 0)
{
Date lastCheckedDate = new Date(folder.lastChecked);
statusText = getTimeFormat().format(lastCheckedDate) + " "+
getDateFormat().format(lastCheckedDate);
}
if (folder.pushActive)
{
statusText = getString(R.string.folder_push_active_symbol) + " "+ statusText;
}
if (statusText != null)
{
holder.folderStatus.setText(statusText);
holder.folderStatus.setVisibility(View.VISIBLE);
}
else
{
holder.folderStatus.setText(null);
holder.folderStatus.setVisibility(View.GONE);
}
if (folder.unreadMessageCount != 0)
{
holder.newMessageCount.setText(Integer
.toString(folder.unreadMessageCount));
holder.newMessageCount.setOnClickListener(new FolderClickListener(mAccount, folder.name, folder.displayName, SearchModifier.UNREAD));
holder.newMessageCount.setVisibility(View.VISIBLE);
}
else
{
holder.newMessageCount.setVisibility(View.GONE);
}
if (K9.messageListStars() && folder.flaggedMessageCount > 0)
{
holder.flaggedMessageCount.setText(Integer
.toString(folder.flaggedMessageCount));
holder.flaggedMessageCount.setOnClickListener(new FolderClickListener(mAccount, folder.name, folder.displayName, SearchModifier.FLAGGED));
holder.flaggedMessageCount.setVisibility(View.VISIBLE);
}
else
{
holder.flaggedMessageCount.setVisibility(View.GONE);
}
holder.activeIcons.setOnClickListener(new OnClickListener()
{
public void onClick(View v)
{
Toast toast = Toast.makeText(getApplication(), getString(R.string.tap_hint), Toast.LENGTH_SHORT);
toast.show();
}
}
);
holder.chip.setBackgroundColor(mAccount.getChipColor());
holder.chip.getBackground().setAlpha(folder.unreadMessageCount == 0 ? 127 : 255);
holder.folderName.setTextSize(TypedValue.COMPLEX_UNIT_DIP, mFontSizes.getFolderName());
holder.folderStatus.setTextSize(TypedValue.COMPLEX_UNIT_DIP, mFontSizes.getFolderStatus());
return view;
}
@Override
public boolean hasStableIds()
{
return false;
}
public boolean isItemSelectable(int position)
{
return true;
}
}
public class FolderInfoHolder implements Comparable<FolderInfoHolder>
{
public String name;
public String displayName;
public long lastChecked;
public int unreadMessageCount;
public int flaggedMessageCount;
public boolean loading;
public String status;
public boolean pushActive;
public boolean lastCheckFailed;
/**
* Outbox is handled differently from any other folder.
*/
public boolean outbox;
@Override
public boolean equals(Object o)
{
return this.name.equals(((FolderInfoHolder)o).name);
}
@Override
public int hashCode()
{
return name.hashCode();
}
public int compareTo(FolderInfoHolder o)
{
String s1 = this.name;
String s2 = o.name;
int ret = s1.compareToIgnoreCase(s2);
if (ret != 0)
{
return ret;
}
else
{
return s1.compareTo(s2);
}
}
// constructor for an empty object for comparisons
public FolderInfoHolder()
{
}
public FolderInfoHolder(Folder folder, int unreadCount)
{
populate(folder, unreadCount);
}
public void populate(Folder folder, int unreadCount)
{
try
{
folder.open(Folder.OpenMode.READ_WRITE);
// unreadCount = folder.getUnreadMessageCount();
}
catch (MessagingException me)
{
Log.e(K9.LOG_TAG, "Folder.getUnreadMessageCount() failed", me);
}
this.name = folder.getName();
if (this.name.equalsIgnoreCase(K9.INBOX))
{
this.displayName = getString(R.string.special_mailbox_name_inbox);
}
else
{
this.displayName = folder.getName();
}
if (this.name.equals(mAccount.getOutboxFolderName()))
{
this.displayName = String.format(getString(R.string.special_mailbox_name_outbox_fmt), this.name);
this.outbox = true;
}
if (this.name.equals(mAccount.getDraftsFolderName()))
{
this.displayName = String.format(getString(R.string.special_mailbox_name_drafts_fmt), this.name);
}
if (this.name.equals(mAccount.getTrashFolderName()))
{
this.displayName = String.format(getString(R.string.special_mailbox_name_trash_fmt), this.name);
}
if (this.name.equals(mAccount.getSentFolderName()))
{
this.displayName = String.format(getString(R.string.special_mailbox_name_sent_fmt), this.name);
}
this.lastChecked = folder.getLastUpdate();
String mess = truncateStatus(folder.getStatus());
this.status = mess;
this.unreadMessageCount = unreadCount;
try
{
this.flaggedMessageCount = folder.getFlaggedMessageCount();
}
catch (Exception e)
{
Log.e(K9.LOG_TAG, "Unable to get flaggedMessageCount", e);
}
folder.close();
}
}
class FolderViewHolder
{
public TextView folderName;
public TextView folderStatus;
public TextView newMessageCount;
public TextView flaggedMessageCount;
public RelativeLayout activeIcons;
public String rawFolderName;
public View chip;
}
private class FolderClickListener implements OnClickListener
{
final BaseAccount account;
final String folderName;
final String displayName;
final SearchModifier searchModifier;
FolderClickListener(BaseAccount nAccount, String folderName, String displayName, SearchModifier nSearchModifier)
{
account = nAccount;
this.folderName = folderName;
searchModifier = nSearchModifier;
this.displayName = displayName;
}
@Override
public void onClick(View v)
{
String description = getString(R.string.search_title,
getString(R.string.message_list_title, account.getDescription(), displayName),
getString(searchModifier.resId));
SearchSpecification searchSpec = new SearchSpecification()
{
@Override
public String[] getAccountUuids()
{
return new String[] { account.getUuid() };
}
@Override
public Flag[] getForbiddenFlags()
{
return searchModifier.forbiddenFlags;
}
@Override
public String getQuery()
{
return "";
}
@Override
public Flag[] getRequiredFlags()
{
return searchModifier.requiredFlags;
}
@Override
public boolean isIntegrate()
{
return false;
}
@Override
public String[] getFolderNames()
{
return new String[] { folderName };
}
};
MessageList.actionHandle(FolderList.this, description, searchSpec);
}
}
private static Flag[] UNREAD_FLAG_ARRAY = { Flag.SEEN };
private void openUnreadSearch(Context context, final Account account)
{
String description = getString(R.string.search_title, mAccount.getDescription(), getString(R.string.unread_modifier));
SearchSpecification searchSpec = new SearchSpecification()
{
@Override
public String[] getAccountUuids()
{
return new String[] { account.getUuid() };
}
@Override
public Flag[] getForbiddenFlags()
{
return UNREAD_FLAG_ARRAY;
}
@Override
public String getQuery()
{
return "";
}
@Override
public Flag[] getRequiredFlags()
{
return null;
}
@Override
public boolean isIntegrate()
{
return false;
}
@Override
public String[] getFolderNames()
{
return null;
}
};
MessageList.actionHandle(context, description, searchSpec);
}
}