@@ -18,6 +18,8 @@ import com.simplemobiletools.commons.dialogs.FilePickerDialog
1818import com.simplemobiletools.commons.dialogs.PropertiesDialog
1919import com.simplemobiletools.commons.dialogs.RenameItemDialog
2020import com.simplemobiletools.commons.extensions.*
21+ import com.simplemobiletools.commons.helpers.CONFLICT_OVERWRITE
22+ import com.simplemobiletools.commons.helpers.CONFLICT_SKIP
2123import com.simplemobiletools.commons.models.FileDirItem
2224import com.simplemobiletools.commons.views.FastScroller
2325import com.simplemobiletools.commons.views.MyRecyclerView
@@ -235,7 +237,7 @@ class ItemsAdapter(activity: SimpleActivity, var fileDirItems: MutableList<FileD
235237 activity.toast(R .string.compressing)
236238 val paths = selectedPositions.map { fileDirItems[it].path }
237239 Thread {
238- if (zipPaths (paths, it)) {
240+ if (compressPaths (paths, it)) {
239241 activity.runOnUiThread {
240242 activity.toast(R .string.compression_successful)
241243 listener?.refreshItems()
@@ -257,10 +259,9 @@ class ItemsAdapter(activity: SimpleActivity, var fileDirItems: MutableList<FileD
257259 }
258260
259261 activity.handleSAFDialog(firstPath) {
260- activity.toast(R .string.decompressing)
261262 val paths = selectedPositions.map { fileDirItems[it].path }.filter { it.isZipFile() }
262- Thread {
263- if (unzipPaths(paths) ) {
263+ tryDecompressingPaths(paths) {
264+ if (it ) {
264265 activity.toast(R .string.decompression_successful)
265266 activity.runOnUiThread {
266267 listener?.refreshItems()
@@ -269,43 +270,105 @@ class ItemsAdapter(activity: SimpleActivity, var fileDirItems: MutableList<FileD
269270 } else {
270271 activity.toast(R .string.decompressing_failed)
271272 }
272- }.start()
273+ }
274+ }
275+ }
276+
277+ private fun tryDecompressingPaths (sourcePaths : List <String >, callback : (success: Boolean ) -> Unit ) {
278+ sourcePaths.forEach {
279+ try {
280+ val zipFile = ZipFile (it)
281+ val entries = zipFile.entries()
282+ val fileDirItems = ArrayList <FileDirItem >()
283+ while (entries.hasMoreElements()) {
284+ val entry = entries.nextElement()
285+ val currPath = if (entry.isDirectory) it else " ${it.getParentPath()}${entry.name} "
286+ val fileDirItem = FileDirItem (currPath, entry.name, entry.isDirectory, 0 , entry.size)
287+ fileDirItems.add(fileDirItem)
288+ }
289+
290+ val destinationFileDirItem = FileDirItem (fileDirItems.first().getParentPath().trimEnd(' /' ))
291+ activity.checkConflicts(fileDirItems, destinationFileDirItem, 0 , LinkedHashMap ()) {
292+ Thread {
293+ decompressPaths(sourcePaths, it, callback)
294+ }.start()
295+ }
296+ } catch (exception: Exception ) {
297+ activity.showErrorToast(exception)
298+ }
273299 }
274300 }
275301
276- private fun unzipPaths (sourcePaths : List <String >): Boolean {
277- sourcePaths.map { File (it) }
278- .forEach {
279- try {
280- val zipFile = ZipFile (it)
281- val entries = zipFile.entries()
282- while (entries.hasMoreElements()) {
283- val entry = entries.nextElement()
284- val file = File (it.parent, entry.name)
285- if (entry.isDirectory) {
286- if (! activity.createDirectorySync(file.absolutePath)) {
287- val error = String .format(activity.getString(R .string.could_not_create_file), file.absolutePath)
288- activity.showErrorToast(error)
289- return false
302+ private fun decompressPaths (paths : List <String >, conflictResolutions : LinkedHashMap <String , Int >, callback : (success: Boolean ) -> Unit ) {
303+ paths.forEach {
304+ try {
305+ val zipFile = ZipFile (it)
306+ val entries = zipFile.entries()
307+ while (entries.hasMoreElements()) {
308+ val entry = entries.nextElement()
309+ val newPath = " ${it.getParentPath()}${entry.name} "
310+
311+ val resolution = getConflictResolution(conflictResolutions, newPath)
312+ val doesPathExist = activity.getDoesFilePathExist(newPath)
313+ if (doesPathExist && resolution == CONFLICT_OVERWRITE ) {
314+ val fileDirItem = FileDirItem (newPath, newPath.getFilenameFromPath(), entry.isDirectory)
315+ if (activity.getIsPathDirectory(it)) {
316+ activity.deleteFolderBg(fileDirItem, false ) {
317+ if (it) {
318+ extractEntry(newPath, entry, zipFile)
319+ } else {
320+ callback(false )
290321 }
291- } else {
292- val ins = zipFile.getInputStream(entry)
293- ins.use {
294- val fos = activity.getFileOutputStreamSync(file.absolutePath, file.getMimeType())
295- if (fos != null )
296- ins.copyTo(fos)
322+ }
323+ } else {
324+ activity.deleteFileBg(fileDirItem, false ) {
325+ if (it) {
326+ extractEntry(newPath, entry, zipFile)
327+ } else {
328+ callback(false )
297329 }
298330 }
299331 }
300- } catch (exception: Exception ) {
301- activity.showErrorToast(exception)
302- return false
332+ } else if (! doesPathExist) {
333+ extractEntry(newPath, entry, zipFile)
303334 }
304335 }
305- return true
336+ callback(true )
337+ } catch (e: Exception ) {
338+ activity.showErrorToast(e)
339+ callback(false )
340+ }
341+ }
342+ }
343+
344+ private fun extractEntry (newPath : String , entry : ZipEntry , zipFile : ZipFile ) {
345+ if (entry.isDirectory) {
346+ if (! activity.createDirectorySync(newPath)) {
347+ val error = String .format(activity.getString(R .string.could_not_create_file), newPath)
348+ activity.showErrorToast(error)
349+ }
350+ } else {
351+ val ins = zipFile.getInputStream(entry)
352+ ins.use {
353+ val fos = activity.getFileOutputStreamSync(newPath, newPath.getMimeType())
354+ if (fos != null ) {
355+ ins.copyTo(fos)
356+ }
357+ }
358+ }
359+ }
360+
361+ private fun getConflictResolution (conflictResolutions : LinkedHashMap <String , Int >, path : String ): Int {
362+ return if (conflictResolutions.size == 1 && conflictResolutions.containsKey(" " )) {
363+ conflictResolutions[" " ]!!
364+ } else if (conflictResolutions.containsKey(path)) {
365+ conflictResolutions[path]!!
366+ } else {
367+ CONFLICT_SKIP
368+ }
306369 }
307370
308- private fun zipPaths (sourcePaths : List <String >, targetPath : String ): Boolean {
371+ private fun compressPaths (sourcePaths : List <String >, targetPath : String ): Boolean {
309372 val queue = LinkedList <File >()
310373 val fos = activity.getFileOutputStreamSync(targetPath, " application/zip" ) ? : return false
311374
0 commit comments