1
0
mirror of https://github.com/moparisthebest/k-9 synced 2024-11-13 13:05:03 -05:00
k-9/src/com/fsck/k9/activity/FolderList.java
Daniel Applebaum 8b92bc3836 Fixes Issue 1474
Fixes Issue 1562

Issue 1474:
Provide new facility to totally wipe all data for an account but leave
settings intact.  This is useful because sometimes storage is so full
that SQLite cannot perform the usual VACUUM or message deletion.

Add confirmation dialogs to destructive Clear and Recreate operations.

Remove destructive Clear from FolderList so as not to have to
duplicate the confirmation dialogs.

Issue 1562:
Suppress notifications when new messages arrive in Trash, Sent or
Drafts special folders.
2010-05-12 04:17:52 +00:00

1502 lines
44 KiB
Java

package com.fsck.k9.activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.NotificationManager;
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.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 STATE_CURRENT_FOLDER = "com.fsck.k9.activity.folderlist_folder";
private static final String EXTRA_CLEAR_NOTIFICATION = "clearNotification";
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)
{
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
final WakeLock wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "Email - UpdateWorker");
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);
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 actionHandleAccountIntent(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_CLEAR_NOTIFICATION, true);
if (initialFolder != null)
{
intent.putExtra(EXTRA_INITIAL_FOLDER, initialFolder);
}
return intent;
}
public static Intent actionHandleAccountIntent(Context context, Account account)
{
return actionHandleAccountIntent(context, account, null);
}
@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);
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);
NotificationManager notifMgr = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notifMgr.cancel(mAccount.getAccountNumber());
notifMgr.cancel(-1000 - mAccount.getAccountNumber());
}
@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);
}
}
}