diff --git a/res/menu/message_list_context.xml b/res/menu/message_list_context.xml
index 31f63f0c9..7e16dbbce 100644
--- a/res/menu/message_list_context.xml
+++ b/res/menu/message_list_context.xml
@@ -1,68 +1,43 @@
diff --git a/res/values/strings.xml b/res/values/strings.xml
index a265f7669..785531928 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -99,6 +99,7 @@ http://k9mail.googlecode.com/
\u0020(Next poll @ %s)
\u0020(Syncing disabled)
+ selected
Next
Previous
diff --git a/src/com/fsck/k9/activity/MessageList.java b/src/com/fsck/k9/activity/MessageList.java
index 27f2baa0a..3fe385a13 100644
--- a/src/com/fsck/k9/activity/MessageList.java
+++ b/src/com/fsck/k9/activity/MessageList.java
@@ -25,8 +25,6 @@ import android.text.style.ForegroundColorSpan;
import android.text.style.StyleSpan;
import android.util.Log;
import android.util.TypedValue;
-import android.view.ContextMenu;
-import android.view.ContextMenu.ContextMenuInfo;
import android.view.GestureDetector;
import android.view.KeyEvent;
import android.view.LayoutInflater;
@@ -36,9 +34,8 @@ import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.Animation.AnimationListener;
-import android.view.animation.AnimationUtils;
import android.widget.AdapterView;
-import android.widget.AdapterView.AdapterContextMenuInfo;
+import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.BaseAdapter;
import android.widget.CheckBox;
import android.widget.CompoundButton;
@@ -51,7 +48,9 @@ import android.widget.Toast;
import com.actionbarsherlock.app.ActionBar;
import com.actionbarsherlock.app.ActionBar.OnNavigationListener;
+import com.actionbarsherlock.view.ActionMode;
import com.actionbarsherlock.view.Menu;
+import com.actionbarsherlock.view.MenuInflater;
import com.actionbarsherlock.view.MenuItem;
import com.actionbarsherlock.view.Window;
import com.fsck.k9.Account;
@@ -318,6 +317,7 @@ public class MessageList extends K9ListActivity implements OnClickListener,
private View mCustomRefreshView;
private ActionBarNavigationSpinner mNavigationSpinner;
private ActionBar mActionBar;
+ private ActionMode mActionMode;
private Bundle mState = null;
/**
@@ -668,9 +668,7 @@ public class MessageList extends K9ListActivity implements OnClickListener,
MessageInfoHolder message = (MessageInfoHolder) mAdapter.getItem(position);
if (mSelectedCount > 0) {
- // In multiselect mode make sure that clicking on the item results
- // in toggling the 'selected' checkbox.
- setSelected(Collections.singletonList(message), !message.selected);
+ handleContextRelatedClick(position);
} else {
onOpenMessage(message);
}
@@ -694,6 +692,14 @@ public class MessageList extends K9ListActivity implements OnClickListener,
// Enable gesture detection for MessageLists
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
@@ -1316,6 +1322,10 @@ public class MessageList extends K9ListActivity implements OnClickListener,
}
mAdapter.removeMessages(holders);
mController.deleteMessages(messagesToRemove.toArray(EMPTY_MESSAGE_ARRAY), null);
+
+ if (mSelectedCount == 0) {
+ mActionMode.finish();
+ }
}
@Override
@@ -1542,12 +1552,10 @@ public class MessageList extends K9ListActivity implements OnClickListener,
case R.id.select_all:
case R.id.batch_select_all: {
setAllSelected(true);
- toggleBatchButtons();
return true;
}
case R.id.batch_deselect_all: {
setAllSelected(false);
- toggleBatchButtons();
return true;
}
case R.id.batch_delete_op: {
@@ -1715,85 +1723,85 @@ public class MessageList extends K9ListActivity implements OnClickListener,
return true;
}
- @Override
- public boolean onContextItemSelected(android.view.MenuItem item) {
- AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
- final MessageInfoHolder holder = mSelectedMessage == null ? (MessageInfoHolder) mAdapter.getItem(info.position) : mSelectedMessage;
- // don't need this anymore
- mSelectedMessage = null;
-
- final List selection = getSelectionFromMessage(holder);
- switch (item.getItemId()) {
- case R.id.open: {
- onOpenMessage(holder);
- break;
- }
- case R.id.select: {
- setSelected(selection, true);
- break;
- }
- case R.id.deselect: {
- setSelected(selection, false);
- break;
- }
- case R.id.delete: {
- onDelete(selection);
- break;
- }
- case R.id.reply: {
- onReply(holder);
- break;
- }
- case R.id.reply_all: {
- onReplyAll(holder);
- break;
- }
- case R.id.forward: {
- onForward(holder);
- break;
- }
- case R.id.send_again: {
- onResendMessage(holder);
- break;
-
- }
- case R.id.mark_as_read: {
- onToggleRead(holder);
- break;
- }
- case R.id.flag: {
- onToggleFlag(holder);
- break;
- }
- case R.id.archive: {
- onArchive(selection);
- break;
- }
- case R.id.spam: {
- onSpam(selection);
- break;
- }
- case R.id.move: {
- onMove(selection);
- break;
- }
- case R.id.copy: {
- onCopy(selection);
- break;
- }
- case R.id.send_alternate: {
- onSendAlternate(mAccount, holder);
- break;
- }
- case R.id.same_sender: {
- MessageList.actionHandle(MessageList.this,
- "From " + holder.sender, holder.senderAddress, false,
- null, null);
- break;
- }
- }
- return super.onContextItemSelected(item);
- }
+// @Override
+// public boolean onContextItemSelected(android.view.MenuItem item) {
+// AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
+// final MessageInfoHolder holder = mSelectedMessage == null ? (MessageInfoHolder) mAdapter.getItem(info.position) : mSelectedMessage;
+// // don't need this anymore
+// mSelectedMessage = null;
+//
+// final List selection = getSelectionFromMessage(holder);
+// switch (item.getItemId()) {
+// case R.id.open: {
+// onOpenMessage(holder);
+// break;
+// }
+// case R.id.select: {
+// setSelected(selection, true);
+// break;
+// }
+// case R.id.deselect: {
+// setSelected(selection, false);
+// break;
+// }
+// case R.id.delete: {
+// onDelete(selection);
+// break;
+// }
+// case R.id.reply: {
+// onReply(holder);
+// break;
+// }
+// case R.id.reply_all: {
+// onReplyAll(holder);
+// break;
+// }
+// case R.id.forward: {
+// onForward(holder);
+// break;
+// }
+// case R.id.send_again: {
+// onResendMessage(holder);
+// break;
+//
+// }
+// case R.id.mark_as_read: {
+// onToggleRead(holder);
+// break;
+// }
+// case R.id.flag: {
+// onToggleFlag(holder);
+// break;
+// }
+// case R.id.archive: {
+// onArchive(selection);
+// break;
+// }
+// case R.id.spam: {
+// onSpam(selection);
+// break;
+// }
+// case R.id.move: {
+// onMove(selection);
+// break;
+// }
+// case R.id.copy: {
+// onCopy(selection);
+// break;
+// }
+// case R.id.send_alternate: {
+// onSendAlternate(mAccount, holder);
+// break;
+// }
+// case R.id.same_sender: {
+// MessageList.actionHandle(MessageList.this,
+// "From " + holder.sender, holder.senderAddress, false,
+// null, null);
+// break;
+// }
+// }
+// return super.onContextItemSelected(item);
+// }
public void onSendAlternate(Account account, MessageInfoHolder holder) {
mController.sendAlternate(this, account, holder.message);
@@ -1821,70 +1829,63 @@ public class MessageList extends K9ListActivity implements OnClickListener,
mListView.getLocationOnScreen(listPosition);
int position = mListView.pointToPosition((int) downMotion.getRawX() - listPosition[0], (int) downMotion.getRawY() - listPosition[1]);
if (position != AdapterView.INVALID_POSITION) {
- MessageInfoHolder msgInfoHolder = (MessageInfoHolder) mAdapter.getItem(position);
-
- if (msgInfoHolder != null && msgInfoHolder.selected != selected) {
- msgInfoHolder.selected = selected;
- mSelectedCount += (selected ? 1 : -1);
- mAdapter.notifyDataSetChanged();
- toggleBatchButtons();
- }
+ handleContextRelatedClick(position);
}
}
- @Override
- public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
- super.onCreateContextMenu(menu, v, menuInfo);
-
- AdapterContextMenuInfo info = (AdapterContextMenuInfo) menuInfo;
- MessageInfoHolder message = (MessageInfoHolder) mAdapter.getItem(info.position);
- // remember which message was originally selected, in case the list changes while the
- // dialog is up
- mSelectedMessage = message;
-
- if (message == null) {
- return;
- }
-
- getMenuInflater().inflate(R.menu.message_list_context, menu);
-
- menu.setHeaderTitle(message.message.getSubject());
-
- if (message.read) {
- menu.findItem(R.id.mark_as_read).setTitle(R.string.mark_as_unread_action);
- }
-
- if (message.flagged) {
- menu.findItem(R.id.flag).setTitle(R.string.unflag_action);
- }
-
- Account account = message.message.getFolder().getAccount();
- if (!mController.isCopyCapable(account)) {
- menu.findItem(R.id.copy).setVisible(false);
- }
-
- if (!mController.isMoveCapable(account)) {
- menu.findItem(R.id.move).setVisible(false);
- menu.findItem(R.id.archive).setVisible(false);
- menu.findItem(R.id.spam).setVisible(false);
- }
-
- if (!account.hasArchiveFolder()) {
- menu.findItem(R.id.archive).setVisible(false);
- }
-
- if (!account.hasSpamFolder()) {
- menu.findItem(R.id.spam).setVisible(false);
- }
-
- if (message.selected) {
- menu.findItem(R.id.select).setVisible(false);
- menu.findItem(R.id.deselect).setVisible(true);
- } else {
- menu.findItem(R.id.select).setVisible(true);
- menu.findItem(R.id.deselect).setVisible(false);
- }
- }
+// @Override
+// public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
+// super.onCreateContextMenu(menu, v, menuInfo);
+//
+// AdapterContextMenuInfo info = (AdapterContextMenuInfo) menuInfo;
+// MessageInfoHolder message = (MessageInfoHolder) mAdapter.getItem(info.position);
+// // remember which message was originally selected, in case the list changes while the
+// // dialog is up
+// mSelectedMessage = message;
+//
+// if (message == null) {
+// return;
+// }
+//
+// getMenuInflater().inflate(R.menu.message_list_context, menu);
+//
+// menu.setHeaderTitle(message.message.getSubject());
+//
+// if (message.read) {
+// menu.findItem(R.id.mark_as_read).setTitle(R.string.mark_as_unread_action);
+// }
+//
+// if (message.flagged) {
+// menu.findItem(R.id.flag).setTitle(R.string.unflag_action);
+// }
+//
+// Account account = message.message.getFolder().getAccount();
+// if (!mController.isCopyCapable(account)) {
+// menu.findItem(R.id.copy).setVisible(false);
+// }
+//
+// if (!mController.isMoveCapable(account)) {
+// menu.findItem(R.id.move).setVisible(false);
+// menu.findItem(R.id.archive).setVisible(false);
+// menu.findItem(R.id.spam).setVisible(false);
+// }
+//
+// if (!account.hasArchiveFolder()) {
+// menu.findItem(R.id.archive).setVisible(false);
+// }
+//
+// if (!account.hasSpamFolder()) {
+// menu.findItem(R.id.spam).setVisible(false);
+// }
+//
+// if (message.selected) {
+// menu.findItem(R.id.select).setVisible(false);
+// menu.findItem(R.id.deselect).setVisible(true);
+// } else {
+// menu.findItem(R.id.select).setVisible(true);
+// menu.findItem(R.id.deselect).setVisible(false);
+// }
+// }
class MessageListAdapter extends BaseAdapter {
private final List mMessages =
@@ -2084,7 +2085,6 @@ public class MessageList extends K9ListActivity implements OnClickListener,
resetUnreadCount();
notifyDataSetChanged();
- toggleBatchButtons();
}
public void addMessages(final List messages) {
@@ -2578,7 +2578,6 @@ public class MessageList extends K9ListActivity implements OnClickListener,
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 {
public ProgressBar progress;
public TextView main;
@@ -2802,7 +2760,6 @@ public class MessageList extends K9ListActivity implements OnClickListener,
}
mAdapter.notifyDataSetChanged();
- toggleBatchButtons();
}
private void setSelected(final List holders, final boolean newState) {
@@ -2813,7 +2770,18 @@ public class MessageList extends K9ListActivity implements OnClickListener,
}
}
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);
}
+
/**
* Return the currently "open" account if available.
*
@@ -3133,4 +3102,84 @@ public class MessageList extends K9ListActivity implements OnClickListener,
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 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;
+ }
+ }
+ };
}