|
@@ -29,6 +29,8 @@ import android.view.Menu;
|
|
|
import android.view.MenuItem;
|
|
|
|
|
|
import com.google.gson.Gson;
|
|
|
+import com.nextcloud.client.account.User;
|
|
|
+import com.nextcloud.client.device.DeviceInfo;
|
|
|
import com.owncloud.android.R;
|
|
|
import com.owncloud.android.datamodel.ArbitraryDataProvider;
|
|
|
import com.owncloud.android.datamodel.OCFile;
|
|
@@ -58,45 +60,62 @@ public class FileMenuFilter {
|
|
|
|
|
|
private static final int SINGLE_SELECT_ITEMS = 1;
|
|
|
|
|
|
- private int mNumberOfAllFiles;
|
|
|
- private Collection<OCFile> mFiles;
|
|
|
- private ComponentsGetter mComponentsGetter;
|
|
|
- private Account mAccount;
|
|
|
- private Context mContext;
|
|
|
- private boolean mOverflowMenu;
|
|
|
+ private int numberOfAllFiles;
|
|
|
+ private Collection<OCFile> files;
|
|
|
+ private ComponentsGetter componentsGetter;
|
|
|
+ private Account account;
|
|
|
+ private Context context;
|
|
|
+ private boolean overflowMenu;
|
|
|
+ private DeviceInfo deviceInfo;
|
|
|
+ private User user;
|
|
|
|
|
|
/**
|
|
|
* Constructor
|
|
|
*
|
|
|
* @param numberOfAllFiles Number of all displayed files
|
|
|
- * @param targetFiles Collection of {@link OCFile} file targets of the action to filter in the {@link Menu}.
|
|
|
+ * @param files Collection of {@link OCFile} file targets of the action to filter in the {@link Menu}.
|
|
|
* @param account ownCloud {@link Account} holding targetFile.
|
|
|
- * @param cg Accessor to app components, needed to access synchronization services
|
|
|
+ * @param componentsGetter Accessor to app components, needed to access synchronization services
|
|
|
* @param context Android {@link Context}, needed to access build setup resources.
|
|
|
* @param overflowMenu true if the overflow menu items are being filtered
|
|
|
*/
|
|
|
- public FileMenuFilter(int numberOfAllFiles, Collection<OCFile> targetFiles, Account account,
|
|
|
- ComponentsGetter cg, Context context, boolean overflowMenu) {
|
|
|
- mNumberOfAllFiles = numberOfAllFiles;
|
|
|
- mFiles = targetFiles;
|
|
|
- mAccount = account;
|
|
|
- mComponentsGetter = cg;
|
|
|
- mContext = context;
|
|
|
- mOverflowMenu = overflowMenu;
|
|
|
+ public FileMenuFilter(int numberOfAllFiles,
|
|
|
+ Collection<OCFile> files,
|
|
|
+ Account account,
|
|
|
+ ComponentsGetter componentsGetter,
|
|
|
+ Context context,
|
|
|
+ boolean overflowMenu,
|
|
|
+ DeviceInfo deviceInfo,
|
|
|
+ User user
|
|
|
+ ) {
|
|
|
+ this.numberOfAllFiles = numberOfAllFiles;
|
|
|
+ this.files = files;
|
|
|
+ this.account = account;
|
|
|
+ this.componentsGetter = componentsGetter;
|
|
|
+ this.context = context;
|
|
|
+ this.overflowMenu = overflowMenu;
|
|
|
+ this.deviceInfo = deviceInfo;
|
|
|
+ this.user = user;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* Constructor
|
|
|
*
|
|
|
- * @param targetFile {@link OCFile} target of the action to filter in the {@link Menu}.
|
|
|
+ * @param file {@link OCFile} target of the action to filter in the {@link Menu}.
|
|
|
* @param account ownCloud {@link Account} holding targetFile.
|
|
|
- * @param cg Accessor to app components, needed to access synchronization services
|
|
|
+ * @param componentsGetter Accessor to app components, needed to access synchronization services
|
|
|
* @param context Android {@link Context}, needed to access build setup resources.
|
|
|
* @param overflowMenu true if the overflow menu items are being filtered
|
|
|
*/
|
|
|
- public FileMenuFilter(OCFile targetFile, Account account, ComponentsGetter cg, Context context,
|
|
|
- boolean overflowMenu) {
|
|
|
- this(1, Collections.singletonList(targetFile), account, cg, context, overflowMenu);
|
|
|
+ public FileMenuFilter(OCFile file,
|
|
|
+ Account account,
|
|
|
+ ComponentsGetter componentsGetter,
|
|
|
+ Context context,
|
|
|
+ boolean overflowMenu,
|
|
|
+ DeviceInfo deviceInfo,
|
|
|
+ User user
|
|
|
+ ) {
|
|
|
+ this(1, Collections.singletonList(file), account, componentsGetter, context, overflowMenu, deviceInfo, user);
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -108,7 +127,7 @@ public class FileMenuFilter {
|
|
|
* @param isMediaSupported True is media playback is supported for this user
|
|
|
*/
|
|
|
public void filter(Menu menu, boolean inSingleFileFragment, boolean isMediaSupported) {
|
|
|
- if (mFiles == null || mFiles.isEmpty()) {
|
|
|
+ if (files == null || files.isEmpty()) {
|
|
|
hideAll(menu);
|
|
|
} else {
|
|
|
List<Integer> toShow = new ArrayList<>();
|
|
@@ -177,7 +196,7 @@ public class FileMenuFilter {
|
|
|
boolean isMediaSupported,
|
|
|
Menu menu) {
|
|
|
boolean synchronizing = anyFileSynchronizing();
|
|
|
- OCCapability capability = mComponentsGetter.getStorageManager().getCapability(mAccount.name);
|
|
|
+ OCCapability capability = componentsGetter.getStorageManager().getCapability(account.name);
|
|
|
boolean endToEndEncryptionEnabled = capability.getEndToEndEncryption().isTrue();
|
|
|
|
|
|
filterEdit(toShow, toHide, capability);
|
|
@@ -202,8 +221,8 @@ public class FileMenuFilter {
|
|
|
|
|
|
private void filterShareFile(List<Integer> toShow, List<Integer> toHide, OCCapability capability) {
|
|
|
if (containsEncryptedFile() || (!isShareViaLinkAllowed() && !isShareWithUsersAllowed()) ||
|
|
|
- !isSingleSelection() || !isShareApiEnabled(capability) || !mFiles.iterator().next().canReshare()
|
|
|
- || mOverflowMenu) {
|
|
|
+ !isSingleSelection() || !isShareApiEnabled(capability) || !files.iterator().next().canReshare()
|
|
|
+ || overflowMenu) {
|
|
|
toHide.add(R.id.action_send_share_file);
|
|
|
} else {
|
|
|
toShow.add(R.id.action_send_share_file);
|
|
@@ -219,7 +238,7 @@ public class FileMenuFilter {
|
|
|
}
|
|
|
|
|
|
private void filterFavorite(List<Integer> toShow, List<Integer> toHide, boolean synchronizing) {
|
|
|
- if (mFiles.isEmpty() || synchronizing || allFavorites()) {
|
|
|
+ if (files.isEmpty() || synchronizing || allFavorites()) {
|
|
|
toHide.add(R.id.action_favorite);
|
|
|
} else {
|
|
|
toShow.add(R.id.action_favorite);
|
|
@@ -227,7 +246,7 @@ public class FileMenuFilter {
|
|
|
}
|
|
|
|
|
|
private void filterUnfavorite(List<Integer> toShow, List<Integer> toHide, boolean synchronizing) {
|
|
|
- if (mFiles.isEmpty() || synchronizing || allNotFavorites()) {
|
|
|
+ if (files.isEmpty() || synchronizing || allNotFavorites()) {
|
|
|
toHide.add(R.id.action_unset_favorite);
|
|
|
} else {
|
|
|
toShow.add(R.id.action_unset_favorite);
|
|
@@ -235,7 +254,7 @@ public class FileMenuFilter {
|
|
|
}
|
|
|
|
|
|
private void filterEncrypt(List<Integer> toShow, List<Integer> toHide, boolean endToEndEncryptionEnabled) {
|
|
|
- if (mFiles.isEmpty() || !isSingleSelection() || isSingleFile() || isEncryptedFolder()
|
|
|
+ if (files.isEmpty() || !isSingleSelection() || isSingleFile() || isEncryptedFolder()
|
|
|
|| !endToEndEncryptionEnabled) {
|
|
|
toHide.add(R.id.action_encrypted);
|
|
|
} else {
|
|
@@ -244,7 +263,7 @@ public class FileMenuFilter {
|
|
|
}
|
|
|
|
|
|
private void filterUnsetEncrypted(List<Integer> toShow, List<Integer> toHide, boolean endToEndEncryptionEnabled) {
|
|
|
- if (mFiles.isEmpty() || !isSingleSelection() || isSingleFile() || !isEncryptedFolder()
|
|
|
+ if (files.isEmpty() || !isSingleSelection() || isSingleFile() || !isEncryptedFolder()
|
|
|
|| !endToEndEncryptionEnabled) {
|
|
|
toHide.add(R.id.action_unset_encrypted);
|
|
|
} else {
|
|
@@ -253,7 +272,7 @@ public class FileMenuFilter {
|
|
|
}
|
|
|
|
|
|
private void filterSetPictureAs(List<Integer> toShow, List<Integer> toHide) {
|
|
|
- if (isSingleImage() && !MimeTypeUtil.isSVG(mFiles.iterator().next())) {
|
|
|
+ if (isSingleImage() && !MimeTypeUtil.isSVG(files.iterator().next())) {
|
|
|
toShow.add(R.id.action_set_as_wallpaper);
|
|
|
} else {
|
|
|
toHide.add(R.id.action_set_as_wallpaper);
|
|
@@ -264,15 +283,15 @@ public class FileMenuFilter {
|
|
|
List<Integer> toHide,
|
|
|
OCCapability capability
|
|
|
) {
|
|
|
- if (android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
|
|
|
+ if (deviceInfo.editorSupported()) {
|
|
|
toHide.add(R.id.action_edit);
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- String mimeType = mFiles.iterator().next().getMimeType();
|
|
|
+ String mimeType = files.iterator().next().getMimeType();
|
|
|
|
|
|
- if (isRichDocumentEditingSupported(capability, mimeType) || isEditorAvailable(mContext.getContentResolver(),
|
|
|
- mAccount,
|
|
|
+ if (isRichDocumentEditingSupported(capability, mimeType) || isEditorAvailable(context.getContentResolver(),
|
|
|
+ user,
|
|
|
mimeType)) {
|
|
|
toShow.add(R.id.action_edit);
|
|
|
} else {
|
|
@@ -280,13 +299,14 @@ public class FileMenuFilter {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- public static boolean isEditorAvailable(ContentResolver contentResolver, Account account, String mimeType) {
|
|
|
- return getEditor(contentResolver, account, mimeType) != null;
|
|
|
+ public static boolean isEditorAvailable(ContentResolver contentResolver, User user, String mimeType) {
|
|
|
+ return getEditor(contentResolver, user, mimeType) != null;
|
|
|
}
|
|
|
|
|
|
@Nullable
|
|
|
- public static Editor getEditor(ContentResolver contentResolver, Account account, String mimeType) {
|
|
|
- String json = new ArbitraryDataProvider(contentResolver).getValue(account, ArbitraryDataProvider.DIRECT_EDITING);
|
|
|
+ public static Editor getEditor(ContentResolver contentResolver, User user, String mimeType) {
|
|
|
+ String json = new ArbitraryDataProvider(contentResolver).getValue(user.toPlatformAccount(),
|
|
|
+ ArbitraryDataProvider.DIRECT_EDITING);
|
|
|
|
|
|
if (json.isEmpty()) {
|
|
|
return null;
|
|
@@ -315,7 +335,7 @@ public class FileMenuFilter {
|
|
|
}
|
|
|
|
|
|
private void filterSync(List<Integer> toShow, List<Integer> toHide, boolean synchronizing) {
|
|
|
- if (mFiles.isEmpty() || (!anyFileDown() && !containsFolder()) || synchronizing) {
|
|
|
+ if (files.isEmpty() || (!anyFileDown() && !containsFolder()) || synchronizing) {
|
|
|
toHide.add(R.id.action_sync_file);
|
|
|
} else {
|
|
|
toShow.add(R.id.action_sync_file);
|
|
@@ -323,7 +343,7 @@ public class FileMenuFilter {
|
|
|
}
|
|
|
|
|
|
private void filterCancelSync(List<Integer> toShow, List<Integer> toHide, boolean synchronizing) {
|
|
|
- if (mFiles.isEmpty() || !synchronizing) {
|
|
|
+ if (files.isEmpty() || !synchronizing) {
|
|
|
toHide.add(R.id.action_cancel_sync);
|
|
|
} else {
|
|
|
toShow.add(R.id.action_cancel_sync);
|
|
@@ -344,7 +364,7 @@ public class FileMenuFilter {
|
|
|
toHide.add(R.id.action_deselect_all_action_menu);
|
|
|
} else {
|
|
|
// Show only if at least one item is selected.
|
|
|
- if (mFiles.isEmpty() || mOverflowMenu) {
|
|
|
+ if (files.isEmpty() || overflowMenu) {
|
|
|
toHide.add(R.id.action_deselect_all_action_menu);
|
|
|
} else {
|
|
|
toShow.add(R.id.action_deselect_all_action_menu);
|
|
@@ -355,7 +375,7 @@ public class FileMenuFilter {
|
|
|
private void filterSelectAll(List<Integer> toShow, List<Integer> toHide, boolean inSingleFileFragment) {
|
|
|
if (!inSingleFileFragment) {
|
|
|
// Show only if at least one item isn't selected.
|
|
|
- if (mFiles.size() >= mNumberOfAllFiles || mOverflowMenu) {
|
|
|
+ if (files.size() >= numberOfAllFiles || overflowMenu) {
|
|
|
toHide.add(R.id.action_select_all_action_menu);
|
|
|
} else {
|
|
|
toShow.add(R.id.action_select_all_action_menu);
|
|
@@ -367,7 +387,7 @@ public class FileMenuFilter {
|
|
|
}
|
|
|
|
|
|
private void filterRemove(List<Integer> toShow, List<Integer> toHide, boolean synchronizing) {
|
|
|
- if (mFiles.isEmpty() || synchronizing || containsEncryptedFolder()) {
|
|
|
+ if (files.isEmpty() || synchronizing || containsEncryptedFolder()) {
|
|
|
toHide.add(R.id.action_remove_file);
|
|
|
} else {
|
|
|
toShow.add(R.id.action_remove_file);
|
|
@@ -375,7 +395,7 @@ public class FileMenuFilter {
|
|
|
}
|
|
|
|
|
|
private void filterMoveCopy(List<Integer> toShow, List<Integer> toHide, boolean synchronizing) {
|
|
|
- if (mFiles.isEmpty() || synchronizing || containsEncryptedFile() || containsEncryptedFolder()) {
|
|
|
+ if (files.isEmpty() || synchronizing || containsEncryptedFile() || containsEncryptedFolder()) {
|
|
|
toHide.add(R.id.action_move);
|
|
|
toHide.add(R.id.action_copy);
|
|
|
} else {
|
|
@@ -393,7 +413,7 @@ public class FileMenuFilter {
|
|
|
}
|
|
|
|
|
|
private void filterDownload(List<Integer> toShow, List<Integer> toHide, boolean synchronizing) {
|
|
|
- if (mFiles.isEmpty() || containsFolder() || anyFileDown() || synchronizing) {
|
|
|
+ if (files.isEmpty() || containsFolder() || anyFileDown() || synchronizing) {
|
|
|
toHide.add(R.id.action_download_file);
|
|
|
} else {
|
|
|
toShow.add(R.id.action_download_file);
|
|
@@ -401,7 +421,7 @@ public class FileMenuFilter {
|
|
|
}
|
|
|
|
|
|
private void filterStream(List<Integer> toShow, List<Integer> toHide, boolean isMediaSupported) {
|
|
|
- if (mFiles.isEmpty() || !isSingleFile() || !isSingleMedia() || !isMediaSupported) {
|
|
|
+ if (files.isEmpty() || !isSingleFile() || !isSingleMedia() || !isMediaSupported) {
|
|
|
toHide.add(R.id.action_stream_media);
|
|
|
} else {
|
|
|
toShow.add(R.id.action_stream_media);
|
|
@@ -410,10 +430,10 @@ public class FileMenuFilter {
|
|
|
|
|
|
private boolean anyFileSynchronizing() {
|
|
|
boolean synchronizing = false;
|
|
|
- if (mComponentsGetter != null && !mFiles.isEmpty() && mAccount != null) {
|
|
|
- OperationsServiceBinder opsBinder = mComponentsGetter.getOperationsServiceBinder();
|
|
|
- FileUploaderBinder uploaderBinder = mComponentsGetter.getFileUploaderBinder();
|
|
|
- FileDownloaderBinder downloaderBinder = mComponentsGetter.getFileDownloaderBinder();
|
|
|
+ if (componentsGetter != null && !files.isEmpty() && account != null) {
|
|
|
+ OperationsServiceBinder opsBinder = componentsGetter.getOperationsServiceBinder();
|
|
|
+ FileUploaderBinder uploaderBinder = componentsGetter.getFileUploaderBinder();
|
|
|
+ FileDownloaderBinder downloaderBinder = componentsGetter.getFileDownloaderBinder();
|
|
|
synchronizing = anyFileSynchronizing(opsBinder) || // comparing local and remote
|
|
|
anyFileDownloading(downloaderBinder) ||
|
|
|
anyFileUploading(uploaderBinder);
|
|
@@ -424,8 +444,8 @@ public class FileMenuFilter {
|
|
|
private boolean anyFileSynchronizing(OperationsServiceBinder opsBinder) {
|
|
|
boolean synchronizing = false;
|
|
|
if (opsBinder != null) {
|
|
|
- for (Iterator<OCFile> iterator = mFiles.iterator(); !synchronizing && iterator.hasNext(); ) {
|
|
|
- synchronizing = opsBinder.isSynchronizing(mAccount, iterator.next());
|
|
|
+ for (Iterator<OCFile> iterator = files.iterator(); !synchronizing && iterator.hasNext(); ) {
|
|
|
+ synchronizing = opsBinder.isSynchronizing(account, iterator.next());
|
|
|
}
|
|
|
}
|
|
|
return synchronizing;
|
|
@@ -434,8 +454,8 @@ public class FileMenuFilter {
|
|
|
private boolean anyFileDownloading(FileDownloaderBinder downloaderBinder) {
|
|
|
boolean downloading = false;
|
|
|
if (downloaderBinder != null) {
|
|
|
- for (Iterator<OCFile> iterator = mFiles.iterator(); !downloading && iterator.hasNext(); ) {
|
|
|
- downloading = downloaderBinder.isDownloading(mAccount, iterator.next());
|
|
|
+ for (Iterator<OCFile> iterator = files.iterator(); !downloading && iterator.hasNext(); ) {
|
|
|
+ downloading = downloaderBinder.isDownloading(account, iterator.next());
|
|
|
}
|
|
|
}
|
|
|
return downloading;
|
|
@@ -444,8 +464,8 @@ public class FileMenuFilter {
|
|
|
private boolean anyFileUploading(FileUploaderBinder uploaderBinder) {
|
|
|
boolean uploading = false;
|
|
|
if (uploaderBinder != null) {
|
|
|
- for (Iterator<OCFile> iterator = mFiles.iterator(); !uploading && iterator.hasNext(); ) {
|
|
|
- uploading = uploaderBinder.isUploading(mAccount, iterator.next());
|
|
|
+ for (Iterator<OCFile> iterator = files.iterator(); !uploading && iterator.hasNext(); ) {
|
|
|
+ uploading = uploaderBinder.isUploading(account, iterator.next());
|
|
|
}
|
|
|
}
|
|
|
return uploading;
|
|
@@ -459,26 +479,26 @@ public class FileMenuFilter {
|
|
|
}
|
|
|
|
|
|
private boolean isShareWithUsersAllowed() {
|
|
|
- return mContext != null &&
|
|
|
- mContext.getResources().getBoolean(R.bool.share_with_users_feature);
|
|
|
+ return context != null &&
|
|
|
+ context.getResources().getBoolean(R.bool.share_with_users_feature);
|
|
|
}
|
|
|
|
|
|
private boolean isShareViaLinkAllowed() {
|
|
|
- return mContext != null &&
|
|
|
- mContext.getResources().getBoolean(R.bool.share_via_link_feature);
|
|
|
+ return context != null &&
|
|
|
+ context.getResources().getBoolean(R.bool.share_via_link_feature);
|
|
|
}
|
|
|
|
|
|
private boolean isSingleSelection() {
|
|
|
- return mFiles.size() == SINGLE_SELECT_ITEMS;
|
|
|
+ return files.size() == SINGLE_SELECT_ITEMS;
|
|
|
}
|
|
|
|
|
|
private boolean isSingleFile() {
|
|
|
- return isSingleSelection() && !mFiles.iterator().next().isFolder();
|
|
|
+ return isSingleSelection() && !files.iterator().next().isFolder();
|
|
|
}
|
|
|
|
|
|
private boolean isEncryptedFolder() {
|
|
|
if (isSingleSelection()) {
|
|
|
- OCFile file = mFiles.iterator().next();
|
|
|
+ OCFile file = files.iterator().next();
|
|
|
|
|
|
return file.isFolder() && file.isEncrypted();
|
|
|
} else {
|
|
@@ -487,16 +507,16 @@ public class FileMenuFilter {
|
|
|
}
|
|
|
|
|
|
private boolean isSingleImage() {
|
|
|
- return isSingleSelection() && MimeTypeUtil.isImage(mFiles.iterator().next());
|
|
|
+ return isSingleSelection() && MimeTypeUtil.isImage(files.iterator().next());
|
|
|
}
|
|
|
|
|
|
private boolean isSingleMedia() {
|
|
|
- OCFile file = mFiles.iterator().next();
|
|
|
+ OCFile file = files.iterator().next();
|
|
|
return isSingleSelection() && (MimeTypeUtil.isVideo(file) || MimeTypeUtil.isAudio(file));
|
|
|
}
|
|
|
|
|
|
private boolean containsEncryptedFile() {
|
|
|
- for (OCFile file : mFiles) {
|
|
|
+ for (OCFile file : files) {
|
|
|
if (!file.isFolder() && file.isEncrypted()) {
|
|
|
return true;
|
|
|
}
|
|
@@ -505,7 +525,7 @@ public class FileMenuFilter {
|
|
|
}
|
|
|
|
|
|
private boolean containsEncryptedFolder() {
|
|
|
- for (OCFile file : mFiles) {
|
|
|
+ for (OCFile file : files) {
|
|
|
if (file.isFolder() && file.isEncrypted()) {
|
|
|
return true;
|
|
|
}
|
|
@@ -514,7 +534,7 @@ public class FileMenuFilter {
|
|
|
}
|
|
|
|
|
|
private boolean containsFolder() {
|
|
|
- for (OCFile file : mFiles) {
|
|
|
+ for (OCFile file : files) {
|
|
|
if (file.isFolder()) {
|
|
|
return true;
|
|
|
}
|
|
@@ -523,7 +543,7 @@ public class FileMenuFilter {
|
|
|
}
|
|
|
|
|
|
private boolean anyFileDown() {
|
|
|
- for (OCFile file : mFiles) {
|
|
|
+ for (OCFile file : files) {
|
|
|
if (file.isDown()) {
|
|
|
return true;
|
|
|
}
|
|
@@ -532,7 +552,7 @@ public class FileMenuFilter {
|
|
|
}
|
|
|
|
|
|
private boolean allFavorites() {
|
|
|
- for (OCFile file : mFiles) {
|
|
|
+ for (OCFile file : files) {
|
|
|
if (!file.isFavorite()) {
|
|
|
return false;
|
|
|
}
|
|
@@ -541,7 +561,7 @@ public class FileMenuFilter {
|
|
|
}
|
|
|
|
|
|
private boolean allNotFavorites() {
|
|
|
- for (OCFile file : mFiles) {
|
|
|
+ for (OCFile file : files) {
|
|
|
if (file.isFavorite()) {
|
|
|
return false;
|
|
|
}
|