Add Empty trash/spam option
Bug: 4559378
Change-Id: I8dc5715a5f14f9fd6e8962ab665c4c25f3c64302
diff --git a/res/menu-sw600dp/conversation_list_menu.xml b/res/menu-sw600dp/conversation_list_menu.xml
index e54c963..ef35f84 100644
--- a/res/menu-sw600dp/conversation_list_menu.xml
+++ b/res/menu-sw600dp/conversation_list_menu.xml
@@ -15,6 +15,7 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
+
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@+id/compose"
@@ -37,6 +38,18 @@
android:icon="@drawable/ic_menu_refresh_holo_light"
android:alphabeticShortcut="@string/trigger_refresh_char" />
+ <!-- Available only in the trash folder, when the account supports emptying it -->
+ <item android:id="@+id/empty_trash"
+ android:title="@string/empty_trash"
+ android:showAsAction="never"
+ android:icon="@drawable/ic_menu_trash_holo_light" />
+
+ <!-- Available only in the spam folder, when the account supports emptying it -->
+ <item android:id="@+id/empty_spam"
+ android:title="@string/empty_spam"
+ android:showAsAction="never"
+ android:icon="@drawable/ic_menu_trash_holo_light" />
+
<!-- Available for Folders with SUPPORTS_SETTINGS capability -->
<item android:id="@+id/folder_options"
android:title="@string/menu_folder_options"
diff --git a/res/menu/conversation_list_menu.xml b/res/menu/conversation_list_menu.xml
index 2a7d6e2..e2483b5 100644
--- a/res/menu/conversation_list_menu.xml
+++ b/res/menu/conversation_list_menu.xml
@@ -31,6 +31,18 @@
android:icon="@drawable/ic_menu_search_holo_light"
android:actionLayout="@layout/mail_actionbar_searchview" />
+ <!-- Available only in the trash folder, when the account supports emptying it -->
+ <item android:id="@+id/empty_trash"
+ android:title="@string/empty_trash"
+ android:showAsAction="never"
+ android:icon="@drawable/ic_menu_trash_holo_light" />
+
+ <!-- Available only in the spam folder, when the account supports emptying it -->
+ <item android:id="@+id/empty_spam"
+ android:title="@string/empty_spam"
+ android:showAsAction="never"
+ android:icon="@drawable/ic_menu_trash_holo_light" />
+
<!-- Always available -->
<item android:id="@+id/show_all_folders"
android:title="@string/show_all_folders"
diff --git a/res/values/strings.xml b/res/values/strings.xml
index a1a02ec..c2782fd 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -877,4 +877,9 @@
indicate that a sync is in progress. [CHAR LIMIT=60] -->
<string name="checking_for_mail">Checking for mail</string>
+ <!-- Conversation list screen overflow menu in trash folder [CHAR LIMIT=50] -->
+ <string name="empty_trash">Empty trash</string>
+
+ <!-- Conversation list screen overflow menu in spam folder [CHAR LIMIT=50] -->
+ <string name="empty_spam">Empty spam</string>
</resources>
diff --git a/src/com/android/mail/browse/ConversationCursor.java b/src/com/android/mail/browse/ConversationCursor.java
index d9dfd46..eda54f8 100644
--- a/src/com/android/mail/browse/ConversationCursor.java
+++ b/src/com/android/mail/browse/ConversationCursor.java
@@ -74,7 +74,7 @@
* caching for quick UI response. This is effectively a singleton class, as the cache is
* implemented as a static HashMap.
*/
-public final class ConversationCursor implements Cursor, ConversationCursorMarkSeenListener {
+public final class ConversationCursor implements Cursor, ConversationCursorOperationListener {
private static final boolean ENABLE_CONVERSATION_PRECACHING = true;
@@ -2060,11 +2060,13 @@
}
}
- /**
- * Marks all contents of this cursor as seen. This may have no effect with certain providers.
- */
@Override
public void markContentsSeen() {
- ConversationCursorMarkSeenListener.MarkSeenHelper.markContentsSeen(mUnderlyingCursor);
+ ConversationCursorOperationListener.OperationHelper.markContentsSeen(mUnderlyingCursor);
+ }
+
+ @Override
+ public void emptyFolder() {
+ ConversationCursorOperationListener.OperationHelper.emptyFolder(mUnderlyingCursor);
}
}
diff --git a/src/com/android/mail/browse/ConversationCursorMarkSeenListener.java b/src/com/android/mail/browse/ConversationCursorMarkSeenListener.java
deleted file mode 100644
index 0956859..0000000
--- a/src/com/android/mail/browse/ConversationCursorMarkSeenListener.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2013 Google Inc.
- * Licensed to The Android Open Source Project.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *******************************************************************************/
-package com.android.mail.browse;
-
-import android.database.Cursor;
-import android.database.CursorWrapper;
-
-public interface ConversationCursorMarkSeenListener {
- /**
- * Marks all contents of this cursor as seen.
- */
- void markContentsSeen();
-
- public class MarkSeenHelper {
- /**
- * Invokes {@link ConversationCursorMarkSeenListener#markContentsSeen(Cursor)} on the
- * specified {@link Cursor}, recursively calls {@link #markContentsSeen(Cursor)} on a
- * wrapped cursor, or returns.
- */
- public static void markContentsSeen(final Cursor cursor) {
- if (cursor == null) {
- return;
- }
-
- if (cursor instanceof ConversationCursorMarkSeenListener) {
- ((ConversationCursorMarkSeenListener) cursor).markContentsSeen();
- } else if (cursor instanceof CursorWrapper) {
- markContentsSeen(((CursorWrapper) cursor).getWrappedCursor());
- }
- }
- }
-}
diff --git a/src/com/android/mail/browse/ConversationCursorOperationListener.java b/src/com/android/mail/browse/ConversationCursorOperationListener.java
new file mode 100644
index 0000000..1ca8116
--- /dev/null
+++ b/src/com/android/mail/browse/ConversationCursorOperationListener.java
@@ -0,0 +1,68 @@
+/*******************************************************************************
+ * Copyright (C) 2013 Google Inc.
+ * Licensed to The Android Open Source Project.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *******************************************************************************/
+package com.android.mail.browse;
+
+import android.database.Cursor;
+import android.database.CursorWrapper;
+
+public interface ConversationCursorOperationListener {
+ /**
+ * Marks all contents of this cursor as seen.
+ */
+ void markContentsSeen();
+
+ /**
+ * Empties the folder of all messages, if possible.
+ */
+ void emptyFolder();
+
+ public class OperationHelper {
+ /**
+ * Invokes {@link ConversationCursorOperationListener#markContentsSeen(Cursor)} on the
+ * specified {@link Cursor}, recursively calls {@link #markContentsSeen(Cursor)} on a
+ * wrapped cursor, or returns.
+ */
+ public static void markContentsSeen(final Cursor cursor) {
+ if (cursor == null) {
+ return;
+ }
+
+ if (cursor instanceof ConversationCursorOperationListener) {
+ ((ConversationCursorOperationListener) cursor).markContentsSeen();
+ } else if (cursor instanceof CursorWrapper) {
+ markContentsSeen(((CursorWrapper) cursor).getWrappedCursor());
+ }
+ }
+
+ /**
+ * Invokes {@link ConversationCursorOperationListener#emptyFolder(Cursor)} on the
+ * specified {@link Cursor}, recursively calls {@link #emptyFolder(Cursor)} on a
+ * wrapped cursor, or returns.
+ */
+ public static void emptyFolder(final Cursor cursor) {
+ if (cursor == null) {
+ return;
+ }
+
+ if (cursor instanceof ConversationCursorOperationListener) {
+ ((ConversationCursorOperationListener) cursor).emptyFolder();
+ } else if (cursor instanceof CursorWrapper) {
+ emptyFolder(((CursorWrapper) cursor).getWrappedCursor());
+ }
+ }
+ }
+}
diff --git a/src/com/android/mail/providers/UIProvider.java b/src/com/android/mail/providers/UIProvider.java
index f602741..b6e37b7 100644
--- a/src/com/android/mail/providers/UIProvider.java
+++ b/src/com/android/mail/providers/UIProvider.java
@@ -284,6 +284,14 @@
* removed when all providers support this capability
*/
public static final int DISCARD_CONVERSATION_DRAFTS = 0x100000;
+ /**
+ * Whether the account supports emptying the trash folder
+ */
+ public static final int EMPTY_TRASH = 0x200000;
+ /**
+ * Whether the account supports emptying the spam folder
+ */
+ public static final int EMPTY_SPAM = 0x400000;
}
public static final class AccountColumns implements BaseColumns {
diff --git a/src/com/android/mail/ui/AbstractActivityController.java b/src/com/android/mail/ui/AbstractActivityController.java
index 6cf271f..3f48590 100644
--- a/src/com/android/mail/ui/AbstractActivityController.java
+++ b/src/com/android/mail/ui/AbstractActivityController.java
@@ -1069,6 +1069,10 @@
dialog.show();
}
break;
+ case R.id.empty_trash:
+ case R.id.empty_spam:
+ emptyFolder();
+ break;
default:
handled = false;
break;
@@ -1076,6 +1080,10 @@
return handled;
}
+ private void emptyFolder() {
+ mConversationListCursor.emptyFolder();
+ }
+
/**
* Stand-in method overriden in OnePaneController for toggling the state
* of the drawer.
diff --git a/src/com/android/mail/ui/MailActionBarView.java b/src/com/android/mail/ui/MailActionBarView.java
index 3fcda76..067fd20 100644
--- a/src/com/android/mail/ui/MailActionBarView.java
+++ b/src/com/android/mail/ui/MailActionBarView.java
@@ -53,6 +53,7 @@
import com.android.mail.providers.UIProvider;
import com.android.mail.providers.UIProvider.AccountCapabilities;
import com.android.mail.providers.UIProvider.FolderCapabilities;
+import com.android.mail.providers.UIProvider.FolderType;
import com.android.mail.utils.LogTag;
import com.android.mail.utils.LogUtils;
import com.android.mail.utils.Utils;
@@ -97,6 +98,8 @@
private MenuItem mSendFeedbackItem;
private MenuItem mRefreshItem;
private MenuItem mFolderSettingsItem;
+ private MenuItem mEmptyTrashItem;
+ private MenuItem mEmptySpamItem;
private View mRefreshActionView;
/** True if the current device is a tablet, false otherwise. */
protected final boolean mIsOnTablet;
@@ -234,6 +237,8 @@
mSendFeedbackItem = menu.findItem(R.id.feedback_menu_item);
mRefreshItem = menu.findItem(R.id.refresh);
mFolderSettingsItem = menu.findItem(R.id.folder_options);
+ mEmptyTrashItem = menu.findItem(R.id.empty_trash);
+ mEmptySpamItem = menu.findItem(R.id.empty_spam);
return true;
}
@@ -401,6 +406,16 @@
mFolderSettingsItem.setVisible(mFolder != null
&& mFolder.supportsCapability(FolderCapabilities.SUPPORTS_SETTINGS));
}
+ if (mEmptyTrashItem != null) {
+ mEmptyTrashItem.setVisible(mAccount != null && mFolder != null
+ && mAccount.supportsCapability(AccountCapabilities.EMPTY_TRASH)
+ && mFolder.isTrash());
+ }
+ if (mEmptySpamItem != null) {
+ mEmptySpamItem.setVisible(mAccount != null && mFolder != null
+ && mAccount.supportsCapability(AccountCapabilities.EMPTY_SPAM)
+ && mFolder.isType(FolderType.SPAM));
+ }
switch (mMode) {
case ViewMode.CONVERSATION: