Do not clear selection for non-destructive actions
Change-Id: Ie38119b1ceede61d810c354deba3348126d406f7
diff --git a/src/com/android/mail/browse/SelectedConversationsActionMenu.java b/src/com/android/mail/browse/SelectedConversationsActionMenu.java
index 1c6f42a..17e4700 100644
--- a/src/com/android/mail/browse/SelectedConversationsActionMenu.java
+++ b/src/com/android/mail/browse/SelectedConversationsActionMenu.java
@@ -100,6 +100,8 @@
private Folder mFolder;
+ // These listeners are called at the end of the animation and they perform their actions on
+ // the conversations.
private final ActionCompleteListener mDeleteListener =
new DestructiveActionListener(R.id.delete);
private final ActionCompleteListener mArchiveListener =
@@ -107,6 +109,10 @@
private final ActionCompleteListener mMuteListener = new DestructiveActionListener(R.id.mute);
private final ActionCompleteListener mSpamListener =
new DestructiveActionListener(R.id.report_spam);
+ private final ActionCompleteListener mRemoveStarListener =
+ new DestructiveActionListener(R.id.remove_star);
+ private final ActionCompleteListener mRemoveImportanceListener =
+ new DestructiveActionListener(R.id.mark_not_important);
private SwipeableListView mListView;
@@ -114,15 +120,16 @@
ConversationSelectionSet selectionSet, AnimatedAdapter adapter,
ActionCompleteListener listener, UndoListener undoListener, Account account,
Folder folder, SwipeableListView list) {
- mSelectionSet = selectionSet;
mActivity = activity;
- mContext = mActivity.getActivityContext();
+ mSelectionSet = selectionSet;
mListAdapter = adapter;
mActionCompleteListener = listener;
mUndoListener = undoListener;
mAccount = account;
mFolder = folder;
mListView = list;
+
+ mContext = mActivity.getActivityContext();
}
@Override
@@ -152,7 +159,13 @@
starConversations(true);
break;
case R.id.remove_star:
- starConversations(false);
+ if (mFolder.type == UIProvider.FolderType.STARRED) {
+ LogUtils.d(LOG_TAG, "We are in a starred folder, removing the star");
+ performDestructiveAction(R.id.remove_star, mRemoveStarListener);
+ } else {
+ LogUtils.d(LOG_TAG, "Not in a starred folder.");
+ starConversations(false);
+ }
break;
case R.id.change_folder:
showChangeFoldersDialog();
@@ -161,7 +174,11 @@
markConversationsImportant(true);
break;
case R.id.mark_not_important:
- markConversationsImportant(false);
+ if (mFolder.supportsCapability(UIProvider.FolderCapabilities.ONLY_IMPORTANT)) {
+ performDestructiveAction(R.id.mark_not_important, mRemoveImportanceListener);
+ } else {
+ markConversationsImportant(false);
+ }
break;
default:
handled = false;
@@ -179,6 +196,20 @@
mListAdapter.notifyDataSetChanged();
}
+ /**
+ * Update the underlying list adapter and redraw the menus if necessary.
+ */
+ private void updateSelection() {
+ mListAdapter.notifyDataSetChanged();
+ if (mActionMode != null) {
+ // Calling mActivity.invalidateOptionsMenu doesn't have the correct behavior, since
+ // the action mode is not refreshed when activity's options menu is invalidated.
+ // Since we need to refresh our own menu, it is easy to call onPrepareActionMode
+ // directly.
+ onPrepareActionMode(mActionMode, mActionMode.getMenu());
+ }
+ }
+
private void performDestructiveAction(final int id, final ActionCompleteListener listener) {
Settings settings = mActivity.getSettings();
final Collection<Conversation> conversations = mSelectionSet.values();
@@ -217,26 +248,30 @@
}
private void markConversationsRead(boolean read) {
- Collection<Conversation> conversations = mSelectionSet.values();
+ final Collection<Conversation> conversations = mSelectionSet.values();
Conversation.updateBoolean(mContext, conversations, ConversationColumns.READ, read);
- clearSelection();
+ updateSelection();
}
private void markConversationsImportant(boolean important) {
- Collection<Conversation> conversations = mSelectionSet.values();
- int priority = important ? UIProvider.ConversationPriority.HIGH
+ final Collection<Conversation> conversations = mSelectionSet.values();
+ final int priority = important ? UIProvider.ConversationPriority.HIGH
: UIProvider.ConversationPriority.LOW;
Conversation.updateInt(mContext, conversations, ConversationColumns.PRIORITY, priority);
- clearSelection();
+ updateSelection();
}
+ /**
+ * Mark the selected conversations with the star setting provided here.
+ * @param star true if you want all the conversations to have stars, false if you want to remove
+ * stars from all conversations
+ */
private void starConversations(boolean star) {
- Collection<Conversation> conversations = mSelectionSet.values();
+ final Collection<Conversation> conversations = mSelectionSet.values();
if (conversations.size() > 0) {
- Conversation.updateBoolean(mContext, conversations,
- ConversationColumns.STARRED, star);
+ Conversation.updateBoolean(mContext, conversations, ConversationColumns.STARRED, star);
}
- clearSelection();
+ updateSelection();
}
private void showChangeFoldersDialog() {
@@ -318,7 +353,7 @@
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
// Determine read/ unread
// Star/ unstar
- Collection<Conversation> conversations = mSelectionSet.values();
+ final Collection<Conversation> conversations = mSelectionSet.values();
boolean showStar = false;
boolean showMarkUnread = false;
boolean showMarkImportant = false;
@@ -363,12 +398,6 @@
return true;
}
- public void onPrepareActionMode() {
- if (mActionMode != null) {
- onPrepareActionMode(mActionMode, mActionMode.getMenu());
- }
- }
-
@Override
public void onDestroyActionMode(ActionMode mode) {
mActionMode = null;
@@ -486,7 +515,7 @@
@Override
public void onActionComplete() {
// This is where we actually delete.
- Collection<Conversation> conversations = mSelectionSet.values();
+ final Collection<Conversation> conversations = mSelectionSet.values();
mActionCompleteListener.onActionComplete();
mUndoListener.onUndoAvailable(new UndoOperation(conversations.size(), mAction));
switch (mAction) {
@@ -508,6 +537,17 @@
case R.id.report_spam:
Conversation.reportSpam(mContext, conversations);
break;
+ case R.id.remove_star:
+ // Star removal is destructive in the Starred folder.
+ Conversation.updateBoolean(mContext, conversations, ConversationColumns.STARRED,
+ false);
+ break;
+ case R.id.mark_not_important:
+ // Marking not important is destructive in a mailbox containing only important
+ // messages
+ Conversation.updateInt(mContext, conversations, ConversationColumns.PRIORITY,
+ UIProvider.ConversationPriority.LOW);
+ break;
}
clearSelection();
}
diff --git a/src/com/android/mail/providers/UIProvider.java b/src/com/android/mail/providers/UIProvider.java
index 5f29e03..2318e77 100644
--- a/src/com/android/mail/providers/UIProvider.java
+++ b/src/com/android/mail/providers/UIProvider.java
@@ -522,6 +522,7 @@
public static final int SENT = 4;
public static final int TRASH = 5;
public static final int SPAM = 6;
+ public static final int STARRED = 7;
}
public static final class FolderCapabilities {
@@ -551,6 +552,10 @@
* Indicates that a folder supports settings (sync lookback, etc.)
*/
public static final int SUPPORTS_SETTINGS = 0x0080;
+ /**
+ * All the messages in this folder are important.
+ */
+ public static final int ONLY_IMPORTANT = 0x0100;
}
public static final class FolderColumns {
diff --git a/src/com/android/mail/ui/AbstractActivityController.java b/src/com/android/mail/ui/AbstractActivityController.java
index 63ee61e..4b5304d 100644
--- a/src/com/android/mail/ui/AbstractActivityController.java
+++ b/src/com/android/mail/ui/AbstractActivityController.java
@@ -1319,6 +1319,11 @@
@Override
public void onRefreshReady() {
ArrayList<Integer> deletedRows = mConversationListCursor.getRefreshDeletions();
+ // If we have any deletions from the server, and the conversations are in the list view,
+ // remove them from a selected set, if any
+ if (!deletedRows.isEmpty() && !mSelectedSet.isEmpty()) {
+ mSelectedSet.delete(deletedRows);
+ }
// If we have any deletions from the server, animate them away
if (!deletedRows.isEmpty() && mConversationListFragment != null) {
AnimatedAdapter adapter = mConversationListFragment.getAnimatedAdapter();
diff --git a/src/com/android/mail/ui/AnimatedAdapter.java b/src/com/android/mail/ui/AnimatedAdapter.java
index c61f2ae..1943af2 100644
--- a/src/com/android/mail/ui/AnimatedAdapter.java
+++ b/src/com/android/mail/ui/AnimatedAdapter.java
@@ -24,7 +24,6 @@
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
-import android.widget.ListView;
import android.widget.SimpleCursorAdapter;
import com.android.mail.browse.ConversationCursor;
@@ -154,8 +153,7 @@
* @param conversations
* @param listener
*/
- public void delete(Collection<Conversation> conversations,
- ActionCompleteListener listener) {
+ public void delete(Collection<Conversation> conversations, ActionCompleteListener listener) {
// Animate out the positions.
// Call when all the animations are complete.
final ArrayList<Integer> positions = new ArrayList<Integer>();
diff --git a/src/com/android/mail/ui/ConversationSelectionSet.java b/src/com/android/mail/ui/ConversationSelectionSet.java
index 9f26fe3..45ec7b5 100644
--- a/src/com/android/mail/ui/ConversationSelectionSet.java
+++ b/src/com/android/mail/ui/ConversationSelectionSet.java
@@ -247,4 +247,13 @@
public Collection<ConversationItemView> views() {
return mInternalViewMap.values();
}
+
+ /**
+ * @param deletedRows an arraylist of conversation IDs which have been deleted.
+ */
+ public void delete(ArrayList<Integer> deletedRows) {
+ for (long id : deletedRows) {
+ remove(id);
+ }
+ }
}