diff --git a/app/build.gradle b/app/build.gradle index e7c537d0..d9ce7e97 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -45,7 +45,7 @@ ext { } dependencies { - implementation 'com.simplemobiletools:commons:3.12.3' + implementation 'com.simplemobiletools:commons:3.12.5' implementation files('../libs/RootTools.jar') diff --git a/app/src/main/kotlin/com/simplemobiletools/filemanager/adapters/ItemsAdapter.kt b/app/src/main/kotlin/com/simplemobiletools/filemanager/adapters/ItemsAdapter.kt index 05ad240e..7f10a7f6 100644 --- a/app/src/main/kotlin/com/simplemobiletools/filemanager/adapters/ItemsAdapter.kt +++ b/app/src/main/kotlin/com/simplemobiletools/filemanager/adapters/ItemsAdapter.kt @@ -18,6 +18,8 @@ import com.simplemobiletools.commons.dialogs.FilePickerDialog import com.simplemobiletools.commons.dialogs.PropertiesDialog import com.simplemobiletools.commons.dialogs.RenameItemDialog import com.simplemobiletools.commons.extensions.* +import com.simplemobiletools.commons.helpers.CONFLICT_OVERWRITE +import com.simplemobiletools.commons.helpers.CONFLICT_SKIP import com.simplemobiletools.commons.models.FileDirItem import com.simplemobiletools.commons.views.FastScroller import com.simplemobiletools.commons.views.MyRecyclerView @@ -235,7 +237,7 @@ class ItemsAdapter(activity: SimpleActivity, var fileDirItems: MutableList): Boolean { - sourcePaths.map { File(it) } - .forEach { - try { - val zipFile = ZipFile(it) - val entries = zipFile.entries() - while (entries.hasMoreElements()) { - val entry = entries.nextElement() - val file = File(it.parent, entry.name) - if (entry.isDirectory) { - if (!activity.createDirectorySync(file.absolutePath)) { - val error = String.format(activity.getString(R.string.could_not_create_file), file.absolutePath) - activity.showErrorToast(error) - return false + private fun tryDecompressingPaths(sourcePaths: List, callback: (success: Boolean) -> Unit) { + sourcePaths.forEach { + try { + val zipFile = ZipFile(it) + val entries = zipFile.entries() + val fileDirItems = ArrayList() + while (entries.hasMoreElements()) { + val entry = entries.nextElement() + val currPath = if (entry.isDirectory) it else "${it.getParentPath()}${entry.name}" + val fileDirItem = FileDirItem(currPath, entry.name, entry.isDirectory, 0, entry.size) + fileDirItems.add(fileDirItem) + } + + val destinationFileDirItem = FileDirItem(fileDirItems.first().getParentPath().trimEnd('/')) + activity.checkConflicts(fileDirItems, destinationFileDirItem, 0, LinkedHashMap()) { + Thread { + decompressPaths(sourcePaths, it, callback) + }.start() + } + } catch (exception: Exception) { + activity.showErrorToast(exception) + } + } + } + + private fun decompressPaths(paths: List, conflictResolutions: LinkedHashMap, callback: (success: Boolean) -> Unit) { + paths.forEach { + try { + val zipFile = ZipFile(it) + val entries = zipFile.entries() + while (entries.hasMoreElements()) { + val entry = entries.nextElement() + val newPath = "${it.getParentPath()}${entry.name}" + + val resolution = getConflictResolution(conflictResolutions, newPath) + val doesPathExist = activity.getDoesFilePathExist(newPath) + if (doesPathExist && resolution == CONFLICT_OVERWRITE) { + val fileDirItem = FileDirItem(newPath, newPath.getFilenameFromPath(), entry.isDirectory) + if (activity.getIsPathDirectory(it)) { + activity.deleteFolderBg(fileDirItem, false) { + if (it) { + extractEntry(newPath, entry, zipFile) + } else { + callback(false) } - } else { - val ins = zipFile.getInputStream(entry) - ins.use { - val fos = activity.getFileOutputStreamSync(file.absolutePath, file.getMimeType()) - if (fos != null) - ins.copyTo(fos) + } + } else { + activity.deleteFileBg(fileDirItem, false) { + if (it) { + extractEntry(newPath, entry, zipFile) + } else { + callback(false) } } } - } catch (exception: Exception) { - activity.showErrorToast(exception) - return false + } else if (!doesPathExist) { + extractEntry(newPath, entry, zipFile) } } - return true + callback(true) + } catch (e: Exception) { + activity.showErrorToast(e) + callback(false) + } + } } - private fun zipPaths(sourcePaths: List, targetPath: String): Boolean { + private fun extractEntry(newPath: String, entry: ZipEntry, zipFile: ZipFile) { + if (entry.isDirectory) { + if (!activity.createDirectorySync(newPath)) { + val error = String.format(activity.getString(R.string.could_not_create_file), newPath) + activity.showErrorToast(error) + } + } else { + val ins = zipFile.getInputStream(entry) + ins.use { + val fos = activity.getFileOutputStreamSync(newPath, newPath.getMimeType()) + if (fos != null) { + ins.copyTo(fos) + } + } + } + } + + private fun getConflictResolution(conflictResolutions: LinkedHashMap, path: String): Int { + return if (conflictResolutions.size == 1 && conflictResolutions.containsKey("")) { + conflictResolutions[""]!! + } else if (conflictResolutions.containsKey(path)) { + conflictResolutions[path]!! + } else { + CONFLICT_SKIP + } + } + + private fun compressPaths(sourcePaths: List, targetPath: String): Boolean { val queue = LinkedList() val fos = activity.getFileOutputStreamSync(targetPath, "application/zip") ?: return false diff --git a/app/src/main/kotlin/com/simplemobiletools/filemanager/dialogs/CompressAsDialog.kt b/app/src/main/kotlin/com/simplemobiletools/filemanager/dialogs/CompressAsDialog.kt index be8f6278..61fc6a65 100644 --- a/app/src/main/kotlin/com/simplemobiletools/filemanager/dialogs/CompressAsDialog.kt +++ b/app/src/main/kotlin/com/simplemobiletools/filemanager/dialogs/CompressAsDialog.kt @@ -43,7 +43,7 @@ class CompressAsDialog(val activity: BaseSimpleActivity, val path: String, val c name.isEmpty() -> activity.toast(R.string.empty_name) name.isAValidFilename() -> { val newPath = "$realPath/$name.zip" - if (activity.doesFilePathExist(newPath)) { + if (activity.getDoesFilePathExist(newPath)) { activity.toast(R.string.name_taken) return@OnClickListener } diff --git a/app/src/main/kotlin/com/simplemobiletools/filemanager/dialogs/CreateNewItemDialog.kt b/app/src/main/kotlin/com/simplemobiletools/filemanager/dialogs/CreateNewItemDialog.kt index b126b1aa..72b7440e 100644 --- a/app/src/main/kotlin/com/simplemobiletools/filemanager/dialogs/CreateNewItemDialog.kt +++ b/app/src/main/kotlin/com/simplemobiletools/filemanager/dialogs/CreateNewItemDialog.kt @@ -26,7 +26,7 @@ class CreateNewItemDialog(val activity: BaseSimpleActivity, val path: String, va activity.toast(R.string.empty_name) } else if (name.isAValidFilename()) { val newPath = "$path/$name" - if (activity.doesFilePathExist(newPath)) { + if (activity.getDoesFilePathExist(newPath)) { activity.toast(R.string.name_taken) return@OnClickListener } diff --git a/app/src/main/kotlin/com/simplemobiletools/filemanager/dialogs/SaveAsDialog.kt b/app/src/main/kotlin/com/simplemobiletools/filemanager/dialogs/SaveAsDialog.kt index efacd18e..08498e06 100644 --- a/app/src/main/kotlin/com/simplemobiletools/filemanager/dialogs/SaveAsDialog.kt +++ b/app/src/main/kotlin/com/simplemobiletools/filemanager/dialogs/SaveAsDialog.kt @@ -66,7 +66,7 @@ class SaveAsDialog(val activity: BaseSimpleActivity, var path: String, val callb return@setOnClickListener } - if (activity.doesFilePathExist(newPath)) { + if (activity.getDoesFilePathExist(newPath)) { val title = String.format(activity.getString(R.string.file_already_exists_overwrite), newFilename) ConfirmationDialog(activity, title) { callback(newPath)