summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/DocumentsUI/src/com/android/documentsui/MimePredicate.java5
-rw-r--r--packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java55
-rw-r--r--packages/DocumentsUI/src/com/android/documentsui/dirlist/FragmentTuner.java91
3 files changed, 91 insertions, 60 deletions
diff --git a/packages/DocumentsUI/src/com/android/documentsui/MimePredicate.java b/packages/DocumentsUI/src/com/android/documentsui/MimePredicate.java
index 2f202e7b976b..859763b833f0 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/MimePredicate.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/MimePredicate.java
@@ -17,6 +17,7 @@
package com.android.documentsui;
import android.annotation.Nullable;
+import android.provider.DocumentsContract.Document;
import com.android.documentsui.model.DocumentInfo;
import com.android.internal.util.Predicate;
@@ -99,4 +100,8 @@ public class MimePredicate implements Predicate<DocumentInfo> {
public static boolean isApkType(@Nullable String mimeType) {
return APK_TYPE.equals(mimeType);
}
+
+ public static boolean isDirectoryType(@Nullable String mimeType) {
+ return Document.MIME_TYPE_DIR.equals(mimeType);
+ }
}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java b/packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java
index 312acb593922..7e3e96798c7b 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java
@@ -62,7 +62,6 @@ import android.support.v7.widget.RecyclerView.ViewHolder;
import android.text.TextUtils;
import android.util.Log;
import android.util.SparseArray;
-import android.util.TypedValue;
import android.view.ActionMode;
import android.view.DragEvent;
import android.view.GestureDetector;
@@ -89,6 +88,7 @@ import com.android.documentsui.Events.MotionInputEvent;
import com.android.documentsui.Menus;
import com.android.documentsui.MessageBar;
import com.android.documentsui.Metrics;
+import com.android.documentsui.MimePredicate;
import com.android.documentsui.R;
import com.android.documentsui.RecentsLoader;
import com.android.documentsui.RootsCache;
@@ -103,6 +103,7 @@ import com.android.documentsui.model.RootInfo;
import com.android.documentsui.services.FileOperationService;
import com.android.documentsui.services.FileOperationService.OpType;
import com.android.documentsui.services.FileOperations;
+
import com.google.common.collect.Lists;
import java.lang.annotation.Retention;
@@ -110,7 +111,6 @@ import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
-import java.util.Iterator;
import java.util.List;
import java.util.Objects;
import java.util.Set;
@@ -458,13 +458,17 @@ public class DirectoryFragment extends Fragment
* ActionMode when there is a selection, canceling it when there is no selection,
* and clearing selection when action mode is explicitly exited by the user.
*/
- private final class SelectionModeListener
- implements MultiSelectManager.Callback, ActionMode.Callback {
+ private final class SelectionModeListener implements MultiSelectManager.Callback,
+ ActionMode.Callback, FragmentTuner.SelectionDetails {
private Selection mSelected = new Selection();
- private int mNoCopyCount = 0;
+
+ // Partial files are files that haven't been fully downloaded.
+ private int mPartialCount = 0;
+ private int mDirectoryCount = 0;
private int mNoDeleteCount = 0;
- private int mNoRenameCount = -1;
+ private int mNoRenameCount = 0;
+
private Menu mMenu;
@Override
@@ -506,14 +510,19 @@ public class DirectoryFragment extends Fragment
// TODO: Should this be happening in onSelectionChanged? Technically this callback is
// triggered on "silent" selection updates (i.e. we might be reacting to unfinalized
// selection changes here)
+ final String mimeType = getCursorString(cursor, Document.COLUMN_MIME_TYPE);
+ if (MimePredicate.isDirectoryType(mimeType)) {
+ mDirectoryCount += selected ? 1 : -1;
+ }
+
final int docFlags = getCursorInt(cursor, Document.COLUMN_FLAGS);
if ((docFlags & Document.FLAG_PARTIAL) != 0) {
- mNoCopyCount += selected ? 1 : -1;
+ mPartialCount += selected ? 1 : -1;
}
if ((docFlags & Document.FLAG_SUPPORTS_DELETE) == 0) {
mNoDeleteCount += selected ? 1 : -1;
}
- if ((docFlags & Document.FLAG_SUPPORTS_RENAME) != 0) {
+ if ((docFlags & Document.FLAG_SUPPORTS_RENAME) == 0) {
mNoRenameCount += selected ? 1 : -1;
}
}
@@ -552,8 +561,11 @@ public class DirectoryFragment extends Fragment
// clear selection
mSelectionManager.clearSelection();
mSelected.clear();
+
+ mDirectoryCount = 0;
+ mPartialCount = 0;
mNoDeleteCount = 0;
- mNoRenameCount = -1;
+ mNoRenameCount = 0;
// Re-enable TalkBack for the toolbars, as they are no longer covered by action mode.
final Toolbar toolbar = (Toolbar) getActivity().findViewById(R.id.toolbar);
@@ -601,24 +613,29 @@ public class DirectoryFragment extends Fragment
return true;
}
- boolean canCopySelection() {
- return mNoCopyCount == 0;
+ @Override
+ public boolean containsDirectories() {
+ return mDirectoryCount > 0;
}
- boolean canDeleteSelection() {
+ @Override
+ public boolean containsPartialFiles() {
+ return mPartialCount > 0;
+ }
+
+ @Override
+ public boolean canDelete() {
return mNoDeleteCount == 0;
}
- boolean canRenameSelection() {
+ @Override
+ public boolean canRename() {
return mNoRenameCount == 0 && mSelectionManager.getSelection().size() == 1;
}
private void updateActionMenu() {
assert(mMenu != null);
-
- // Delegate update logic to our owning action, since specialized logic is desired.
- mTuner.updateActionMenu(
- mMenu, mType, canCopySelection(), canDeleteSelection(), canRenameSelection());
+ mTuner.updateActionMenu(mMenu, this);
Menus.disableHiddenItems(mMenu);
}
@@ -1174,7 +1191,7 @@ public class DirectoryFragment extends Fragment
view.setOnDragListener(mOnDragListener);
}
- if (mTuner.allowDragNDrop()) {
+ if (mTuner.dragAndDropEnabled()) {
// Make all items draggable.
view.setOnLongClickListener(onLongClickListener);
}
@@ -1761,7 +1778,7 @@ public class DirectoryFragment extends Fragment
mRoot.authority, mRoot.rootId, mQuery)
: DocumentsContract.buildChildDocumentsUri(
mDocument.authority, mDocument.documentId);
- if (mTuner.enableManagedMode()) {
+ if (mTuner.managedModeEnabled()) {
contentsUri = DocumentsContract.setManageMode(contentsUri);
}
return new DirectoryLoader(
diff --git a/packages/DocumentsUI/src/com/android/documentsui/dirlist/FragmentTuner.java b/packages/DocumentsUI/src/com/android/documentsui/dirlist/FragmentTuner.java
index 9e2b86a8cea9..7b0510be644e 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/dirlist/FragmentTuner.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/dirlist/FragmentTuner.java
@@ -58,9 +58,6 @@ public abstract class FragmentTuner {
}
}
- public abstract void updateActionMenu(
- Menu menu, @ResultType int dirType,
- boolean canCopy, boolean canDelete, boolean canRename);
// Subtly different from isDocumentEnabled. The reason may be illuminated as follows.
// A folder is enabled such that it may be double clicked, even in settings
@@ -73,18 +70,23 @@ public abstract class FragmentTuner {
return true;
}
- abstract void onModelLoaded(Model model, @ResultType int resultType, boolean isSearch);
-
/**
* When managed mode is enabled, active downloads will be visible in the UI.
* Presumably this should only be true when in the downloads directory.
*/
- abstract boolean enableManagedMode();
+ boolean managedModeEnabled() {
+ return false;
+ }
/**
* Whether drag n' drop is allowed in this context
*/
- abstract boolean allowDragNDrop();
+ boolean dragAndDropEnabled() {
+ return false;
+ }
+
+ abstract void updateActionMenu(Menu menu, SelectionDetails selection);
+ abstract void onModelLoaded(Model model, @ResultType int resultType, boolean isSearch);
/**
* Provides support for Platform specific specializations of DirectoryFragment.
@@ -105,7 +107,7 @@ public abstract class FragmentTuner {
return false;
}
- if (isDirectory(docMimeType)) {
+ if (MimePredicate.isDirectoryType(docMimeType)) {
return false;
}
@@ -121,9 +123,9 @@ public abstract class FragmentTuner {
}
@Override
- public boolean isDocumentEnabled(String docMimeType, int docFlags) {
+ public boolean isDocumentEnabled(String mimeType, int docFlags) {
// Directories are always enabled.
- if (isDirectory(docMimeType)) {
+ if (MimePredicate.isDirectoryType(mimeType)) {
return true;
}
@@ -141,13 +143,11 @@ public abstract class FragmentTuner {
}
}
- return MimePredicate.mimeMatches(mState.acceptMimes, docMimeType);
+ return MimePredicate.mimeMatches(mState.acceptMimes, mimeType);
}
@Override
- public void updateActionMenu(
- Menu menu, @ResultType int dirType,
- boolean canCopy, boolean canDelete, boolean canRename) {
+ public void updateActionMenu(Menu menu, SelectionDetails selection) {
MenuItem open = menu.findItem(R.id.menu_open);
MenuItem share = menu.findItem(R.id.menu_share);
@@ -155,8 +155,8 @@ public abstract class FragmentTuner {
MenuItem rename = menu.findItem(R.id.menu_rename);
MenuItem selectAll = menu.findItem(R.id.menu_select_all);
- open.setVisible(mState.action == ACTION_GET_CONTENT ||
- mState.action == ACTION_OPEN);
+ open.setVisible(mState.action == ACTION_GET_CONTENT
+ || mState.action == ACTION_OPEN);
share.setVisible(false);
delete.setVisible(false);
rename.setVisible(false);
@@ -191,16 +191,6 @@ public abstract class FragmentTuner {
}
mModelPreviousLoaded = true;
}
-
- @Override
- public boolean enableManagedMode() {
- return false;
- }
-
- @Override
- public boolean allowDragNDrop() {
- return false;
- }
}
/**
@@ -217,29 +207,39 @@ public abstract class FragmentTuner {
}
@Override
- public void updateActionMenu(
- Menu menu, @ResultType int dirType,
- boolean canCopy, boolean canDelete, boolean canRename) {
+ public void updateActionMenu(Menu menu, SelectionDetails selection) {
+
+ menu.findItem(R.id.menu_open).setVisible(false); // "open" is never used in Files.
+ // Commands accessible only via keyboard...
MenuItem copy = menu.findItem(R.id.menu_copy_to_clipboard);
MenuItem paste = menu.findItem(R.id.menu_paste_from_clipboard);
- copy.setEnabled(canCopy);
+ // Commands visible in the UI...
MenuItem rename = menu.findItem(R.id.menu_rename);
MenuItem moveTo = menu.findItem(R.id.menu_move_to);
MenuItem copyTo = menu.findItem(R.id.menu_copy_to);
+ MenuItem share = menu.findItem(R.id.menu_share);
+ MenuItem delete = menu.findItem(R.id.menu_delete);
+
+ // copy is not visible, keyboard only
+ copy.setEnabled(!selection.containsPartialFiles());
+ // Commands usually on action-bar, so we always manage visibility.
+ share.setVisible(!selection.containsDirectories() && !selection.containsPartialFiles());
+ delete.setVisible(selection.canDelete());
+
+ share.setEnabled(!selection.containsDirectories() && !selection.containsPartialFiles());
+ delete.setEnabled(selection.canDelete());
+
+ // Commands always in overflow, so we don't bother showing/hiding...
copyTo.setVisible(true);
moveTo.setVisible(true);
rename.setVisible(true);
- copyTo.setEnabled(canCopy);
- moveTo.setEnabled(canCopy && canDelete);
- rename.setEnabled(canRename);
-
- menu.findItem(R.id.menu_share).setVisible(true);
- menu.findItem(R.id.menu_delete).setVisible(canDelete);
- menu.findItem(R.id.menu_open).setVisible(false);
+ copyTo.setEnabled(!selection.containsPartialFiles());
+ moveTo.setEnabled(!selection.containsPartialFiles() && selection.canDelete());
+ rename.setEnabled(!selection.containsPartialFiles() && selection.canRename());
Menus.disableHiddenItems(menu, copy, paste);
}
@@ -256,7 +256,7 @@ public abstract class FragmentTuner {
}
@Override
- public boolean enableManagedMode() {
+ public boolean managedModeEnabled() {
// When in downloads top level directory, we also show active downloads.
// And while we don't allow folders in Downloads, we do allow Zip files in
// downloads that themselves can be opened and viewed like directories.
@@ -267,12 +267,21 @@ public abstract class FragmentTuner {
}
@Override
- public boolean allowDragNDrop() {
+ public boolean dragAndDropEnabled() {
return true;
}
}
- private static boolean isDirectory(String mimeType) {
- return Document.MIME_TYPE_DIR.equals(mimeType);
+ /**
+ * Access to meta data about the selection.
+ */
+ interface SelectionDetails {
+ boolean containsDirectories();
+ boolean containsPartialFiles();
+
+ // TODO: Update these to express characteristics instead of answering concrete questions,
+ // since the answer to those questions is (or can be) activity specific.
+ boolean canDelete();
+ boolean canRename();
}
}