Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Unverified Commit 72ce174e authored by solokot's avatar solokot Committed by GitHub
Browse files

Merge pull request #15 from SimpleMobileTools/master

update
parents c0b00a16 ab51dd87
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -6,7 +6,7 @@ buildscript {
        propMinSdkVersion = 16
        propTargetSdkVersion = propCompileSdkVersion
        propVersionCode = 1
        propVersionName = '3.8.12'
        propVersionName = '3.9.9'
        kotlin_version = '1.2.21'
        support_libs = '27.0.2'
    }
+31 −11
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ import android.view.WindowManager
import com.simplemobiletools.commons.R
import com.simplemobiletools.commons.asynctasks.CopyMoveTask
import com.simplemobiletools.commons.dialogs.ConfirmationDialog
import com.simplemobiletools.commons.dialogs.FileConflictDialog
import com.simplemobiletools.commons.extensions.*
import com.simplemobiletools.commons.helpers.APP_LICENSES
import com.simplemobiletools.commons.helpers.APP_NAME
@@ -174,22 +175,13 @@ open class BaseSimpleActivity : AppCompatActivity() {
            return
        }

        if (files.size == 1) {
            if (File(destination, files[0].name).exists()) {
                toast(R.string.name_taken)
                return
            }
        }

        handleSAFDialog(destinationFolder) {
            copyMoveCallback = callback
            if (isCopyOperation) {
                toast(R.string.copying)
                startCopyMove(files, destinationFolder, isCopyOperation, copyPhotoVideoOnly)
            } else {
                if (isPathOnSD(source) || isPathOnSD(destination) || files.first().isDirectory || isNougatPlus()) {
                    handleSAFDialog(File(source)) {
                        toast(R.string.moving)
                        startCopyMove(files, destinationFolder, isCopyOperation, copyPhotoVideoOnly)
                    }
                } else {
@@ -222,8 +214,36 @@ open class BaseSimpleActivity : AppCompatActivity() {
    }

    private fun startCopyMove(files: ArrayList<File>, destinationFolder: File, isCopyOperation: Boolean, copyPhotoVideoOnly: Boolean) {
        checkConflict(files, destinationFolder, 0, LinkedHashMap()) {
            toast(if (isCopyOperation) R.string.copying else R.string.moving)
            val pair = Pair(files, destinationFolder)
        CopyMoveTask(this, isCopyOperation, copyPhotoVideoOnly, copyMoveListener).execute(pair)
            CopyMoveTask(this, isCopyOperation, copyPhotoVideoOnly, it, copyMoveListener).execute(pair)
        }
    }

    private fun checkConflict(files: ArrayList<File>, destinationFolder: File, index: Int, conflictResolutions: LinkedHashMap<String, Int>,
                              callback: (resolutions: LinkedHashMap<String, Int>) -> Unit) {
        if (index == files.size) {
            callback(conflictResolutions)
            return
        }

        val file = files[index]
        val newFile = File(destinationFolder, file.name)
        if (newFile.exists()) {
            FileConflictDialog(this, newFile) { resolution, applyForAll ->
                if (applyForAll) {
                    conflictResolutions.clear()
                    conflictResolutions[""] = resolution
                    checkConflict(files, destinationFolder, files.size, conflictResolutions, callback)
                } else {
                    conflictResolutions[newFile.absolutePath] = resolution
                    checkConflict(files, destinationFolder, index + 1, conflictResolutions, callback)
                }
            }
        } else {
            checkConflict(files, destinationFolder, index + 1, conflictResolutions, callback)
        }
    }

    fun handlePermission(permissionId: Int, callback: (granted: Boolean) -> Unit) {
+14 −3
Original line number Diff line number Diff line
@@ -8,6 +8,7 @@ import android.view.Menu
import android.view.MenuItem
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import com.bignerdranch.android.multiselector.ModalMultiSelectorCallback
import com.bignerdranch.android.multiselector.MultiSelector
import com.bignerdranch.android.multiselector.SwappingHolder
@@ -31,6 +32,7 @@ abstract class MyRecyclerViewAdapter(val activity: BaseSimpleActivity, val recyc

    private val multiSelector = MultiSelector()
    private var actMode: ActionMode? = null
    private var actBarTextView: TextView? = null

    abstract fun getActionMenuId(): Int

@@ -69,10 +71,10 @@ abstract class MyRecyclerViewAdapter(val activity: BaseSimpleActivity, val recyc
    private fun updateTitle(cnt: Int) {
        val selectableItemCount = getSelectableItemCount()
        val selectedCount = Math.min(cnt, selectableItemCount)
        val oldTitle = actMode?.title
        val oldTitle = actBarTextView?.text
        val newTitle = "$selectedCount / $selectableItemCount"
        if (oldTitle != newTitle) {
            actMode?.title = newTitle
            actBarTextView?.text = newTitle
            actMode?.invalidate()
        }
    }
@@ -190,6 +192,15 @@ abstract class MyRecyclerViewAdapter(val activity: BaseSimpleActivity, val recyc
        override fun onCreateActionMode(actionMode: ActionMode?, menu: Menu?): Boolean {
            super.onCreateActionMode(actionMode, menu)
            actMode = actionMode
            actBarTextView = layoutInflater.inflate(R.layout.actionbar_title, null) as TextView
            actMode!!.customView = actBarTextView
            actBarTextView!!.setOnClickListener {
                if (getSelectableItemCount() == selectedPositions.size) {
                    finishActMode()
                } else {
                    selectAll()
                }
            }
            activity.menuInflater.inflate(getActionMenuId(), menu)
            return true
        }
@@ -205,7 +216,7 @@ abstract class MyRecyclerViewAdapter(val activity: BaseSimpleActivity, val recyc
                markItemSelection(false, itemViews[it])
            }
            selectedPositions.clear()
            actMode?.title = ""
            actBarTextView?.text = ""
            actMode = null
        }
    }
+25 −6
Original line number Diff line number Diff line
@@ -8,6 +8,8 @@ import android.support.v4.util.Pair
import com.simplemobiletools.commons.R
import com.simplemobiletools.commons.activities.BaseSimpleActivity
import com.simplemobiletools.commons.extensions.*
import com.simplemobiletools.commons.helpers.CONFLICT_OVERWRITE
import com.simplemobiletools.commons.helpers.CONFLICT_SKIP
import com.simplemobiletools.commons.interfaces.CopyMoveListener
import java.io.File
import java.io.FileInputStream
@@ -16,7 +18,7 @@ import java.io.OutputStream
import java.lang.ref.WeakReference
import java.util.*

class CopyMoveTask(val activity: BaseSimpleActivity, val copyOnly: Boolean = false, val copyMediaOnly: Boolean,
class CopyMoveTask(val activity: BaseSimpleActivity, val copyOnly: Boolean = false, val copyMediaOnly: Boolean, val conflictResolutions: LinkedHashMap<String, Int>,
                   listener: CopyMoveListener) : AsyncTask<Pair<ArrayList<File>, File>, Void, Boolean>() {
    private var mListener: WeakReference<CopyMoveListener>? = null
    private var mMovedFiles: ArrayList<File> = ArrayList()
@@ -28,19 +30,26 @@ class CopyMoveTask(val activity: BaseSimpleActivity, val copyOnly: Boolean = fal
    }

    override fun doInBackground(vararg params: Pair<ArrayList<File>, File>): Boolean? {
        if (params.isEmpty())
        if (params.isEmpty()) {
            return false
        }

        val pair = params[0]
        mFiles = pair.first!!

        for (file in mFiles) {
            try {
                val curFile = File(pair.second, file.name)
                if (curFile.exists())
                val newFile = File(pair.second, file.name)
                if (newFile.exists()) {
                    val resolution = getConflictResolution(newFile)
                    if (resolution == CONFLICT_SKIP) {
                        continue
                    } else if (resolution == CONFLICT_OVERWRITE) {
                        activity.deleteFilesBg(arrayListOf(newFile), true)
                    }
                }

                copy(file, curFile)
                copy(file, newFile)
            } catch (e: Exception) {
                activity.toast(e.toString())
                return false
@@ -55,6 +64,16 @@ class CopyMoveTask(val activity: BaseSimpleActivity, val copyOnly: Boolean = fal
        return true
    }

    private fun getConflictResolution(file: File): Int {
        return if (conflictResolutions.size == 1 && conflictResolutions.containsKey("")) {
            conflictResolutions[""]!!
        } else if (conflictResolutions.containsKey(file.absolutePath)) {
            conflictResolutions[file.absolutePath]!!
        } else {
            CONFLICT_SKIP
        }
    }

    private fun copy(source: File, destination: File) {
        if (source.isDirectory) {
            copyDirectory(source, destination)
+58 −0
Original line number Diff line number Diff line
package com.simplemobiletools.commons.dialogs

import android.app.Activity
import android.support.v7.app.AlertDialog
import com.simplemobiletools.commons.R
import com.simplemobiletools.commons.R.id.conflict_dialog_radio_merge
import com.simplemobiletools.commons.R.id.conflict_dialog_radio_skip
import com.simplemobiletools.commons.extensions.baseConfig
import com.simplemobiletools.commons.extensions.beVisibleIf
import com.simplemobiletools.commons.extensions.setupDialogStuff
import com.simplemobiletools.commons.helpers.CONFLICT_MERGE
import com.simplemobiletools.commons.helpers.CONFLICT_OVERWRITE
import com.simplemobiletools.commons.helpers.CONFLICT_SKIP
import kotlinx.android.synthetic.main.dialog_file_conflict.view.*
import java.io.File

class FileConflictDialog(val activity: Activity, val file: File, val callback: (resolution: Int, applyForAll: Boolean) -> Unit) {
    val view = activity.layoutInflater.inflate(R.layout.dialog_file_conflict, null)!!

    init {
        view.apply {
            val stringBase = if (file.isDirectory) R.string.folder_already_exists else R.string.file_already_exists
            conflict_dialog_title.text = String.format(activity.getString(stringBase), file.name)
            conflict_dialog_apply_to_all.isChecked = activity.baseConfig.lastConflictApplyToAll
            conflict_dialog_radio_merge.beVisibleIf(file.isDirectory)

            val resolutionButton = when (activity.baseConfig.lastConflictResolution) {
                CONFLICT_OVERWRITE -> conflict_dialog_radio_overwrite
                CONFLICT_MERGE -> conflict_dialog_radio_merge
                else -> conflict_dialog_radio_skip
            }
            resolutionButton.isChecked = true
        }

        AlertDialog.Builder(activity)
                .setPositiveButton(R.string.ok, { dialog, which -> dialogConfirmed() })
                .setNegativeButton(R.string.cancel, null)
                .create().apply {
            activity.setupDialogStuff(view, this)
        }
    }

    private fun dialogConfirmed() {
        val resolution = when (view.conflict_dialog_radio_group.checkedRadioButtonId) {
            conflict_dialog_radio_skip -> CONFLICT_SKIP
            conflict_dialog_radio_merge -> CONFLICT_MERGE
            else -> CONFLICT_OVERWRITE
        }

        val applyToAll = view.conflict_dialog_apply_to_all.isChecked
        activity.baseConfig.apply {
            lastConflictApplyToAll = applyToAll
            lastConflictResolution = resolution
        }

        callback(resolution, applyToAll)
    }
}
Loading