1
0
mirror of https://github.com/moparisthebest/k-9 synced 2024-11-16 06:25:06 -05:00

Selection with context actionbar working.

This commit is contained in:
Sander Bogaert 2012-07-19 16:39:30 -04:00 committed by Andrew Chen
parent f8bd9e481c
commit e01232a500
3 changed files with 256 additions and 231 deletions

View File

@ -1,68 +1,43 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"> <menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/open"
android:title="@string/open_action"
/>
<item
android:id="@+id/select"
android:title="@string/select_action"
/>
<item
android:id="@+id/deselect"
android:visible="false"
android:title="@string/deselect_action"
/>
<item <item
android:id="@+id/delete" android:id="@+id/delete"
android:title="@string/delete_action" android:title="@string/delete_action"
/> android:showAsAction="always"
<item
android:id="@+id/forward"
android:title="@string/forward_action"
/>
<item
android:id="@+id/reply_all"
android:title="@string/reply_all_action"
/>
<item
android:id="@+id/reply"
android:title="@string/reply_action"
/>
<item
android:id="@+id/send_again"
android:title="@string/send_again_action"
/> />
<item <item
android:id="@+id/mark_as_read" android:id="@+id/mark_as_read"
android:title="@string/mark_as_read_action" android:title="@string/mark_as_read_action"
/> android:showAsAction="always"
<item
android:id="@+id/flag"
android:title="@string/flag_action"
/> />
<item <item
android:id="@+id/archive" android:id="@+id/archive"
android:title="@string/archive_action" android:title="@string/archive_action"
android:showAsAction="always"
/>
<item
android:id="@+id/flag"
android:title="@string/flag_action"
android:showAsAction="ifRoom"
/> />
<item <item
android:id="@+id/spam" android:id="@+id/spam"
android:title="@string/spam_action" android:title="@string/spam_action"
android:showAsAction="ifRoom"
/> />
<item <item
android:id="@+id/move" android:id="@+id/move"
android:title="@string/move_action" android:title="@string/move_action"
android:showAsAction="ifRoom"
/> />
<item <item
android:id="@+id/copy" android:id="@+id/copy"
android:title="@string/copy_action" android:title="@string/copy_action"
android:showAsAction="ifRoom"
/> />
<item <item
android:id="@+id/send_alternate" android:id="@+id/send_alternate"
android:title="@string/send_alternate_action" android:title="@string/send_alternate_action"
/> android:showAsAction="ifRoom"
<item
android:id="@+id/same_sender"
android:title="@string/from_same_sender"
/> />
</menu> </menu>

View File

@ -99,6 +99,7 @@ http://k9mail.googlecode.com/
<string name="status_next_poll">\u0020(Next poll @ <xliff:g id="nexttime">%s</xliff:g>)</string> <string name="status_next_poll">\u0020(Next poll @ <xliff:g id="nexttime">%s</xliff:g>)</string>
<string name="status_syncing_off">\u0020(Syncing disabled)</string> <string name="status_syncing_off">\u0020(Syncing disabled)</string>
<string name="actionbar_selected">selected</string>
<!-- Actions will be used as buttons and in menu items --> <!-- Actions will be used as buttons and in menu items -->
<string name="next_action">Next</string> <!-- Used as part of a multi-step process --> <string name="next_action">Next</string> <!-- Used as part of a multi-step process -->
<string name="previous_action">Previous</string> <!-- Used as part of a multi-step process --> <string name="previous_action">Previous</string> <!-- Used as part of a multi-step process -->

View File

@ -25,8 +25,6 @@ import android.text.style.ForegroundColorSpan;
import android.text.style.StyleSpan; import android.text.style.StyleSpan;
import android.util.Log; import android.util.Log;
import android.util.TypedValue; import android.util.TypedValue;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.GestureDetector; import android.view.GestureDetector;
import android.view.KeyEvent; import android.view.KeyEvent;
import android.view.LayoutInflater; import android.view.LayoutInflater;
@ -36,9 +34,8 @@ import android.view.View.OnClickListener;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.view.animation.Animation; import android.view.animation.Animation;
import android.view.animation.Animation.AnimationListener; import android.view.animation.Animation.AnimationListener;
import android.view.animation.AnimationUtils;
import android.widget.AdapterView; import android.widget.AdapterView;
import android.widget.AdapterView.AdapterContextMenuInfo; import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.BaseAdapter; import android.widget.BaseAdapter;
import android.widget.CheckBox; import android.widget.CheckBox;
import android.widget.CompoundButton; import android.widget.CompoundButton;
@ -51,7 +48,9 @@ import android.widget.Toast;
import com.actionbarsherlock.app.ActionBar; import com.actionbarsherlock.app.ActionBar;
import com.actionbarsherlock.app.ActionBar.OnNavigationListener; import com.actionbarsherlock.app.ActionBar.OnNavigationListener;
import com.actionbarsherlock.view.ActionMode;
import com.actionbarsherlock.view.Menu; import com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.view.MenuInflater;
import com.actionbarsherlock.view.MenuItem; import com.actionbarsherlock.view.MenuItem;
import com.actionbarsherlock.view.Window; import com.actionbarsherlock.view.Window;
import com.fsck.k9.Account; import com.fsck.k9.Account;
@ -318,6 +317,7 @@ public class MessageList extends K9ListActivity implements OnClickListener,
private View mCustomRefreshView; private View mCustomRefreshView;
private ActionBarNavigationSpinner mNavigationSpinner; private ActionBarNavigationSpinner mNavigationSpinner;
private ActionBar mActionBar; private ActionBar mActionBar;
private ActionMode mActionMode;
private Bundle mState = null; private Bundle mState = null;
/** /**
@ -668,9 +668,7 @@ public class MessageList extends K9ListActivity implements OnClickListener,
MessageInfoHolder message = (MessageInfoHolder) mAdapter.getItem(position); MessageInfoHolder message = (MessageInfoHolder) mAdapter.getItem(position);
if (mSelectedCount > 0) { if (mSelectedCount > 0) {
// In multiselect mode make sure that clicking on the item results handleContextRelatedClick(position);
// in toggling the 'selected' checkbox.
setSelected(Collections.singletonList(message), !message.selected);
} else { } else {
onOpenMessage(message); onOpenMessage(message);
} }
@ -694,6 +692,14 @@ public class MessageList extends K9ListActivity implements OnClickListener,
// Enable gesture detection for MessageLists // Enable gesture detection for MessageLists
mGestureDetector = new GestureDetector(new SwipeGestureDetector(this, this)); mGestureDetector = new GestureDetector(new SwipeGestureDetector(this, this));
// Enable context action bar behaviour
getListView().setOnItemLongClickListener(new OnItemLongClickListener() {
@Override
public boolean onItemLongClick(AdapterView<?> parent, View view,
int position, long id) {
return handleContextRelatedClick(position);
}});
} }
@Override @Override
@ -1316,6 +1322,10 @@ public class MessageList extends K9ListActivity implements OnClickListener,
} }
mAdapter.removeMessages(holders); mAdapter.removeMessages(holders);
mController.deleteMessages(messagesToRemove.toArray(EMPTY_MESSAGE_ARRAY), null); mController.deleteMessages(messagesToRemove.toArray(EMPTY_MESSAGE_ARRAY), null);
if (mSelectedCount == 0) {
mActionMode.finish();
}
} }
@Override @Override
@ -1542,12 +1552,10 @@ public class MessageList extends K9ListActivity implements OnClickListener,
case R.id.select_all: case R.id.select_all:
case R.id.batch_select_all: { case R.id.batch_select_all: {
setAllSelected(true); setAllSelected(true);
toggleBatchButtons();
return true; return true;
} }
case R.id.batch_deselect_all: { case R.id.batch_deselect_all: {
setAllSelected(false); setAllSelected(false);
toggleBatchButtons();
return true; return true;
} }
case R.id.batch_delete_op: { case R.id.batch_delete_op: {
@ -1715,85 +1723,85 @@ public class MessageList extends K9ListActivity implements OnClickListener,
return true; return true;
} }
@Override // @Override
public boolean onContextItemSelected(android.view.MenuItem item) { // public boolean onContextItemSelected(android.view.MenuItem item) {
AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo(); // AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
final MessageInfoHolder holder = mSelectedMessage == null ? (MessageInfoHolder) mAdapter.getItem(info.position) : mSelectedMessage; // final MessageInfoHolder holder = mSelectedMessage == null ? (MessageInfoHolder) mAdapter.getItem(info.position) : mSelectedMessage;
// don't need this anymore // // don't need this anymore
mSelectedMessage = null; // mSelectedMessage = null;
//
final List<MessageInfoHolder> selection = getSelectionFromMessage(holder); // final List<MessageInfoHolder> selection = getSelectionFromMessage(holder);
switch (item.getItemId()) { // switch (item.getItemId()) {
case R.id.open: { // case R.id.open: {
onOpenMessage(holder); // onOpenMessage(holder);
break; // break;
} // }
case R.id.select: { // case R.id.select: {
setSelected(selection, true); // setSelected(selection, true);
break; // break;
} // }
case R.id.deselect: { // case R.id.deselect: {
setSelected(selection, false); // setSelected(selection, false);
break; // break;
} // }
case R.id.delete: { // case R.id.delete: {
onDelete(selection); // onDelete(selection);
break; // break;
} // }
case R.id.reply: { // case R.id.reply: {
onReply(holder); // onReply(holder);
break; // break;
} // }
case R.id.reply_all: { // case R.id.reply_all: {
onReplyAll(holder); // onReplyAll(holder);
break; // break;
} // }
case R.id.forward: { // case R.id.forward: {
onForward(holder); // onForward(holder);
break; // break;
} // }
case R.id.send_again: { // case R.id.send_again: {
onResendMessage(holder); // onResendMessage(holder);
break; // break;
//
} // }
case R.id.mark_as_read: { // case R.id.mark_as_read: {
onToggleRead(holder); // onToggleRead(holder);
break; // break;
} // }
case R.id.flag: { // case R.id.flag: {
onToggleFlag(holder); // onToggleFlag(holder);
break; // break;
} // }
case R.id.archive: { // case R.id.archive: {
onArchive(selection); // onArchive(selection);
break; // break;
} // }
case R.id.spam: { // case R.id.spam: {
onSpam(selection); // onSpam(selection);
break; // break;
} // }
case R.id.move: { // case R.id.move: {
onMove(selection); // onMove(selection);
break; // break;
} // }
case R.id.copy: { // case R.id.copy: {
onCopy(selection); // onCopy(selection);
break; // break;
} // }
case R.id.send_alternate: { // case R.id.send_alternate: {
onSendAlternate(mAccount, holder); // onSendAlternate(mAccount, holder);
break; // break;
} // }
case R.id.same_sender: { // case R.id.same_sender: {
MessageList.actionHandle(MessageList.this, // MessageList.actionHandle(MessageList.this,
"From " + holder.sender, holder.senderAddress, false, // "From " + holder.sender, holder.senderAddress, false,
null, null); // null, null);
break; // break;
} // }
} // }
return super.onContextItemSelected(item); // return super.onContextItemSelected(item);
} // }
public void onSendAlternate(Account account, MessageInfoHolder holder) { public void onSendAlternate(Account account, MessageInfoHolder holder) {
mController.sendAlternate(this, account, holder.message); mController.sendAlternate(this, account, holder.message);
@ -1821,70 +1829,63 @@ public class MessageList extends K9ListActivity implements OnClickListener,
mListView.getLocationOnScreen(listPosition); mListView.getLocationOnScreen(listPosition);
int position = mListView.pointToPosition((int) downMotion.getRawX() - listPosition[0], (int) downMotion.getRawY() - listPosition[1]); int position = mListView.pointToPosition((int) downMotion.getRawX() - listPosition[0], (int) downMotion.getRawY() - listPosition[1]);
if (position != AdapterView.INVALID_POSITION) { if (position != AdapterView.INVALID_POSITION) {
MessageInfoHolder msgInfoHolder = (MessageInfoHolder) mAdapter.getItem(position); handleContextRelatedClick(position);
if (msgInfoHolder != null && msgInfoHolder.selected != selected) {
msgInfoHolder.selected = selected;
mSelectedCount += (selected ? 1 : -1);
mAdapter.notifyDataSetChanged();
toggleBatchButtons();
}
} }
} }
@Override // @Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { // public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo); // super.onCreateContextMenu(menu, v, menuInfo);
//
AdapterContextMenuInfo info = (AdapterContextMenuInfo) menuInfo; // AdapterContextMenuInfo info = (AdapterContextMenuInfo) menuInfo;
MessageInfoHolder message = (MessageInfoHolder) mAdapter.getItem(info.position); // MessageInfoHolder message = (MessageInfoHolder) mAdapter.getItem(info.position);
// remember which message was originally selected, in case the list changes while the // // remember which message was originally selected, in case the list changes while the
// dialog is up // // dialog is up
mSelectedMessage = message; // mSelectedMessage = message;
//
if (message == null) { // if (message == null) {
return; // return;
} // }
//
getMenuInflater().inflate(R.menu.message_list_context, menu); // getMenuInflater().inflate(R.menu.message_list_context, menu);
//
menu.setHeaderTitle(message.message.getSubject()); // menu.setHeaderTitle(message.message.getSubject());
//
if (message.read) { // if (message.read) {
menu.findItem(R.id.mark_as_read).setTitle(R.string.mark_as_unread_action); // menu.findItem(R.id.mark_as_read).setTitle(R.string.mark_as_unread_action);
} // }
//
if (message.flagged) { // if (message.flagged) {
menu.findItem(R.id.flag).setTitle(R.string.unflag_action); // menu.findItem(R.id.flag).setTitle(R.string.unflag_action);
} // }
//
Account account = message.message.getFolder().getAccount(); // Account account = message.message.getFolder().getAccount();
if (!mController.isCopyCapable(account)) { // if (!mController.isCopyCapable(account)) {
menu.findItem(R.id.copy).setVisible(false); // menu.findItem(R.id.copy).setVisible(false);
} // }
//
if (!mController.isMoveCapable(account)) { // if (!mController.isMoveCapable(account)) {
menu.findItem(R.id.move).setVisible(false); // menu.findItem(R.id.move).setVisible(false);
menu.findItem(R.id.archive).setVisible(false); // menu.findItem(R.id.archive).setVisible(false);
menu.findItem(R.id.spam).setVisible(false); // menu.findItem(R.id.spam).setVisible(false);
} // }
//
if (!account.hasArchiveFolder()) { // if (!account.hasArchiveFolder()) {
menu.findItem(R.id.archive).setVisible(false); // menu.findItem(R.id.archive).setVisible(false);
} // }
//
if (!account.hasSpamFolder()) { // if (!account.hasSpamFolder()) {
menu.findItem(R.id.spam).setVisible(false); // menu.findItem(R.id.spam).setVisible(false);
} // }
//
if (message.selected) { // if (message.selected) {
menu.findItem(R.id.select).setVisible(false); // menu.findItem(R.id.select).setVisible(false);
menu.findItem(R.id.deselect).setVisible(true); // menu.findItem(R.id.deselect).setVisible(true);
} else { // } else {
menu.findItem(R.id.select).setVisible(true); // menu.findItem(R.id.select).setVisible(true);
menu.findItem(R.id.deselect).setVisible(false); // menu.findItem(R.id.deselect).setVisible(false);
} // }
} // }
class MessageListAdapter extends BaseAdapter { class MessageListAdapter extends BaseAdapter {
private final List<MessageInfoHolder> mMessages = private final List<MessageInfoHolder> mMessages =
@ -2084,7 +2085,6 @@ public class MessageList extends K9ListActivity implements OnClickListener,
resetUnreadCount(); resetUnreadCount();
notifyDataSetChanged(); notifyDataSetChanged();
toggleBatchButtons();
} }
public void addMessages(final List<MessageInfoHolder> messages) { public void addMessages(final List<MessageInfoHolder> messages) {
@ -2578,7 +2578,6 @@ public class MessageList extends K9ListActivity implements OnClickListener,
selected.setVisibility(View.GONE); selected.setVisibility(View.GONE);
} }
} }
toggleBatchButtons();
} }
} }
} }
@ -2640,47 +2639,6 @@ public class MessageList extends K9ListActivity implements OnClickListener,
// } // }
} }
private void toggleBatchButtons() {
runOnUiThread(new Runnable() {
@Override
public void run() {
if (mSelectedCount < 0) {
mSelectedCount = 0;
}
int readButtonIconId;
int flagButtonIconId;
if (mSelectedCount == 0) {
readButtonIconId = R.drawable.ic_button_mark_read;
flagButtonIconId = R.drawable.ic_button_flag;
hideBatchButtons();
} else {
boolean newReadState = computeBatchDirection(false);
if (newReadState) {
readButtonIconId = R.drawable.ic_button_mark_read;
} else {
readButtonIconId = R.drawable.ic_button_mark_unread;
}
boolean newFlagState = computeBatchDirection(true);
if (newFlagState) {
flagButtonIconId = R.drawable.ic_button_flag;
} else {
flagButtonIconId = R.drawable.ic_button_unflag;
}
showBatchButtons();
}
// mBatchReadButton.setImageResource(readButtonIconId);
// mBatchFlagButton.setImageResource(flagButtonIconId);
}
});
}
static class FooterViewHolder { static class FooterViewHolder {
public ProgressBar progress; public ProgressBar progress;
public TextView main; public TextView main;
@ -2802,7 +2760,6 @@ public class MessageList extends K9ListActivity implements OnClickListener,
} }
mAdapter.notifyDataSetChanged(); mAdapter.notifyDataSetChanged();
toggleBatchButtons();
} }
private void setSelected(final List<MessageInfoHolder> holders, final boolean newState) { private void setSelected(final List<MessageInfoHolder> holders, final boolean newState) {
@ -2813,7 +2770,18 @@ public class MessageList extends K9ListActivity implements OnClickListener,
} }
} }
mAdapter.notifyDataSetChanged(); mAdapter.notifyDataSetChanged();
toggleBatchButtons(); }
private void toggleMessageSelect(final MessageInfoHolder holder){
if (holder.selected) {
holder.selected = false;
mSelectedCount -= 1;
} else {
holder.selected = true;
mSelectedCount += 1;
}
mAdapter.notifyDataSetChanged();
mActionMode.setTitle(mSelectedCount+" "+getString(R.string.actionbar_selected));
} }
/** /**
@ -3099,6 +3067,7 @@ public class MessageList extends K9ListActivity implements OnClickListener,
Accounts.listAccounts(this); Accounts.listAccounts(this);
} }
/** /**
* Return the currently "open" account if available. * Return the currently "open" account if available.
* *
@ -3133,4 +3102,84 @@ public class MessageList extends K9ListActivity implements OnClickListener,
return false; return false;
} }
private boolean handleContextRelatedClick(int position){
MessageInfoHolder holder = (MessageInfoHolder) mAdapter.getItem(position);
if (mActionMode != null) {
if (mSelectedCount > 1) {
toggleMessageSelect(holder);
} else {
if( holder.selected ) mActionMode.finish();
else toggleMessageSelect(holder);
}
}else{
mActionMode = MessageList.this.startActionMode(mActionModeCallback);
toggleMessageSelect(holder);
}
return true;
}
private ActionMode.Callback mActionModeCallback = new ActionMode.Callback() {
@Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
// TODO Auto-generated method stub
return false;
}
@Override
public void onDestroyActionMode(ActionMode mode) {
mActionMode = null;
setAllSelected(false);
}
@Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
MenuInflater inflater = mode.getMenuInflater();
inflater.inflate(R.menu.message_list_context, menu);
return true;
}
@Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
final List<MessageInfoHolder> selection = getSelectionFromCheckboxes();
switch (item.getItemId()) {
case R.id.delete: {
onDelete(selection);
return true;
}
/*case R.id.mark_as_read: {
onToggleRead(holder);
break;
}
case R.id.flag: {
onToggleFlag(holder);
break;
}*/
case R.id.archive: {
onArchive(selection);
return true;
}
case R.id.spam: {
onSpam(selection);
return true;
}
case R.id.move: {
onMove(selection);
return true;
}
case R.id.copy: {
onCopy(selection);
return true;
}
/*case R.id.send_alternate: {
onSendAlternate(mAccount, holder);
break;
}*/
default: return false;
}
}
};
} }