Move feature
This commit is contained in:
parent
35a2e35bdc
commit
cac264043f
@ -250,7 +250,7 @@ open class BaseExplorerActivity : BaseActivity() {
|
|||||||
dialog.show()
|
dialog.show()
|
||||||
}
|
}
|
||||||
|
|
||||||
protected fun checkFileOverwrite(path: String): String? {
|
protected fun checkPathOverwrite(path: String, isDirectory: Boolean): String? {
|
||||||
var outputPath: String? = null
|
var outputPath: String? = null
|
||||||
if (gocryptfsVolume.pathExists(path)){
|
if (gocryptfsVolume.pathExists(path)){
|
||||||
val fileName = File(path).name
|
val fileName = File(path).name
|
||||||
@ -261,7 +261,7 @@ open class BaseExplorerActivity : BaseActivity() {
|
|||||||
runOnUiThread {
|
runOnUiThread {
|
||||||
val dialog = ColoredAlertDialogBuilder(this)
|
val dialog = ColoredAlertDialogBuilder(this)
|
||||||
.setTitle(R.string.warning)
|
.setTitle(R.string.warning)
|
||||||
.setMessage(getString(R.string.file_overwrite_question, fileName))
|
.setMessage(getString(if (isDirectory){R.string.dir_overwrite_question} else {R.string.file_overwrite_question}, path))
|
||||||
.setNegativeButton(R.string.no) { _, _ ->
|
.setNegativeButton(R.string.no) { _, _ ->
|
||||||
val dialogEditTextView = layoutInflater.inflate(R.layout.dialog_edit_text, null)
|
val dialogEditTextView = layoutInflater.inflate(R.layout.dialog_edit_text, null)
|
||||||
val dialogEditText = dialogEditTextView.findViewById<EditText>(R.id.dialog_edit_text)
|
val dialogEditText = dialogEditTextView.findViewById<EditText>(R.id.dialog_edit_text)
|
||||||
@ -269,15 +269,15 @@ open class BaseExplorerActivity : BaseActivity() {
|
|||||||
dialogEditText.selectAll()
|
dialogEditText.selectAll()
|
||||||
val dialog = ColoredAlertDialogBuilder(this)
|
val dialog = ColoredAlertDialogBuilder(this)
|
||||||
.setView(dialogEditTextView)
|
.setView(dialogEditTextView)
|
||||||
.setTitle(getString(R.string.enter_new_filename))
|
.setTitle(getString(R.string.enter_new_name))
|
||||||
.setPositiveButton(R.string.ok) { _, _ ->
|
.setPositiveButton(R.string.ok) { _, _ ->
|
||||||
handler.sendMessage(Message().apply { obj = checkFileOverwrite(PathUtils.path_join(PathUtils.getParentPath(path), dialogEditText.text.toString())) })
|
handler.sendMessage(Message().apply { obj = checkPathOverwrite(PathUtils.path_join(PathUtils.getParentPath(path), dialogEditText.text.toString()), isDirectory) })
|
||||||
}
|
}
|
||||||
.setNegativeButton(R.string.cancel) { _, _ -> handler.sendMessage(Message().apply { obj = null }) }
|
.setNegativeButton(R.string.cancel) { _, _ -> handler.sendMessage(Message().apply { obj = null }) }
|
||||||
.create()
|
.create()
|
||||||
dialogEditText.setOnEditorActionListener { _, _, _ ->
|
dialogEditText.setOnEditorActionListener { _, _, _ ->
|
||||||
dialog.dismiss()
|
dialog.dismiss()
|
||||||
handler.sendMessage(Message().apply { obj = checkFileOverwrite(PathUtils.path_join(PathUtils.getParentPath(path), dialogEditText.text.toString())) })
|
handler.sendMessage(Message().apply { obj = checkPathOverwrite(PathUtils.path_join(PathUtils.getParentPath(path), dialogEditText.text.toString()), isDirectory) })
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
dialog.setOnCancelListener { handler.sendMessage(Message().apply { obj = null }) }
|
dialog.setOnCancelListener { handler.sendMessage(Message().apply { obj = null }) }
|
||||||
|
@ -18,16 +18,18 @@ import sushi.hardcore.droidfs.adapters.IconTextDialogAdapter
|
|||||||
import sushi.hardcore.droidfs.util.*
|
import sushi.hardcore.droidfs.util.*
|
||||||
import sushi.hardcore.droidfs.widgets.ColoredAlertDialogBuilder
|
import sushi.hardcore.droidfs.widgets.ColoredAlertDialogBuilder
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import kotlin.collections.ArrayList
|
|
||||||
|
|
||||||
class ExplorerActivity : BaseExplorerActivity() {
|
class ExplorerActivity : BaseExplorerActivity() {
|
||||||
private val PICK_DIRECTORY_REQUEST_CODE = 1
|
companion object {
|
||||||
private val PICK_FILES_REQUEST_CODE = 2
|
private const val PICK_DIRECTORY_REQUEST_CODE = 1
|
||||||
private val PICK_OTHER_VOLUME_ITEMS_REQUEST_CODE = 3
|
private const val PICK_FILES_REQUEST_CODE = 2
|
||||||
|
private const val PICK_OTHER_VOLUME_ITEMS_REQUEST_CODE = 3
|
||||||
|
private enum class ItemsActions {NONE, COPY, MOVE}
|
||||||
|
}
|
||||||
private var usf_decrypt = false
|
private var usf_decrypt = false
|
||||||
private var usf_share = false
|
private var usf_share = false
|
||||||
private var modeSelectLocation = false
|
private var currentItemAction = ItemsActions.NONE
|
||||||
private val filesToCopy = ArrayList<ExplorerElement>()
|
private val itemsToProcess = ArrayList<ExplorerElement>()
|
||||||
override fun init() {
|
override fun init() {
|
||||||
setContentView(R.layout.activity_explorer)
|
setContentView(R.layout.activity_explorer)
|
||||||
usf_decrypt = sharedPrefs.getBoolean("usf_decrypt", false)
|
usf_decrypt = sharedPrefs.getBoolean("usf_decrypt", false)
|
||||||
@ -35,7 +37,7 @@ class ExplorerActivity : BaseExplorerActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onExplorerItemLongClick(position: Int) {
|
override fun onExplorerItemLongClick(position: Int) {
|
||||||
cancelCopy()
|
cancelItemAction()
|
||||||
explorerAdapter.onItemLongClick(position)
|
explorerAdapter.onItemLongClick(position)
|
||||||
invalidateOptionsMenu()
|
invalidateOptionsMenu()
|
||||||
}
|
}
|
||||||
@ -44,7 +46,7 @@ class ExplorerActivity : BaseExplorerActivity() {
|
|||||||
if (fileName.isEmpty()) {
|
if (fileName.isEmpty()) {
|
||||||
Toast.makeText(this, R.string.error_filename_empty, Toast.LENGTH_SHORT).show()
|
Toast.makeText(this, R.string.error_filename_empty, Toast.LENGTH_SHORT).show()
|
||||||
} else {
|
} else {
|
||||||
checkFileOverwrite(PathUtils.path_join(currentDirectoryPath, fileName))?.let {
|
checkPathOverwrite(PathUtils.path_join(currentDirectoryPath, fileName), false)?.let {
|
||||||
val handleID = gocryptfsVolume.openWriteMode(it)
|
val handleID = gocryptfsVolume.openWriteMode(it)
|
||||||
if (handleID == -1) {
|
if (handleID == -1) {
|
||||||
ColoredAlertDialogBuilder(this)
|
ColoredAlertDialogBuilder(this)
|
||||||
@ -62,7 +64,7 @@ class ExplorerActivity : BaseExplorerActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun onClickFAB(view: View) {
|
fun onClickFAB(view: View) {
|
||||||
if (modeSelectLocation){
|
if (currentItemAction != ItemsActions.NONE){
|
||||||
openDialogCreateFolder()
|
openDialogCreateFolder()
|
||||||
} else {
|
} else {
|
||||||
val adapter = IconTextDialogAdapter(this)
|
val adapter = IconTextDialogAdapter(this)
|
||||||
@ -152,7 +154,7 @@ class ExplorerActivity : BaseExplorerActivity() {
|
|||||||
Looper.prepare()
|
Looper.prepare()
|
||||||
var success = false
|
var success = false
|
||||||
for (uri in uris) {
|
for (uri in uris) {
|
||||||
val dstPath = checkFileOverwrite(PathUtils.path_join(currentDirectoryPath, PathUtils.getFilenameFromURI(activity, uri)))
|
val dstPath = checkPathOverwrite(PathUtils.path_join(currentDirectoryPath, PathUtils.getFilenameFromURI(activity, uri)), false)
|
||||||
if (dstPath == null){
|
if (dstPath == null){
|
||||||
break
|
break
|
||||||
} else {
|
} else {
|
||||||
@ -316,7 +318,7 @@ class ExplorerActivity : BaseExplorerActivity() {
|
|||||||
|
|
||||||
override fun onCreateOptionsMenu(menu: Menu): Boolean {
|
override fun onCreateOptionsMenu(menu: Menu): Boolean {
|
||||||
menuInflater.inflate(R.menu.explorer, menu)
|
menuInflater.inflate(R.menu.explorer, menu)
|
||||||
if (modeSelectLocation) {
|
if (currentItemAction != ItemsActions.NONE) {
|
||||||
menu.findItem(R.id.validate).isVisible = true
|
menu.findItem(R.id.validate).isVisible = true
|
||||||
menu.findItem(R.id.close).isVisible = false
|
menu.findItem(R.id.close).isVisible = false
|
||||||
} else {
|
} else {
|
||||||
@ -328,6 +330,7 @@ class ExplorerActivity : BaseExplorerActivity() {
|
|||||||
menu.findItem(R.id.select_all).isVisible = anyItemSelected
|
menu.findItem(R.id.select_all).isVisible = anyItemSelected
|
||||||
menu.findItem(R.id.delete).isVisible = anyItemSelected
|
menu.findItem(R.id.delete).isVisible = anyItemSelected
|
||||||
menu.findItem(R.id.copy).isVisible = anyItemSelected
|
menu.findItem(R.id.copy).isVisible = anyItemSelected
|
||||||
|
menu.findItem(R.id.cut).isVisible = anyItemSelected
|
||||||
menu.findItem(R.id.decrypt).isVisible = anyItemSelected && usf_decrypt
|
menu.findItem(R.id.decrypt).isVisible = anyItemSelected && usf_decrypt
|
||||||
if (anyItemSelected && usf_share){
|
if (anyItemSelected && usf_share){
|
||||||
var containsDir = false
|
var containsDir = false
|
||||||
@ -348,7 +351,7 @@ class ExplorerActivity : BaseExplorerActivity() {
|
|||||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||||
return when (item.itemId) {
|
return when (item.itemId) {
|
||||||
android.R.id.home -> {
|
android.R.id.home -> {
|
||||||
cancelCopy()
|
cancelItemAction()
|
||||||
super.onOptionsItemSelected(item)
|
super.onOptionsItemSelected(item)
|
||||||
}
|
}
|
||||||
R.id.select_all -> {
|
R.id.select_all -> {
|
||||||
@ -356,38 +359,52 @@ class ExplorerActivity : BaseExplorerActivity() {
|
|||||||
invalidateOptionsMenu()
|
invalidateOptionsMenu()
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
R.id.cut -> {
|
||||||
|
for (i in explorerAdapter.selectedItems){
|
||||||
|
itemsToProcess.add(explorerElements[i])
|
||||||
|
}
|
||||||
|
currentItemAction = ItemsActions.MOVE
|
||||||
|
unselectAll()
|
||||||
|
true
|
||||||
|
}
|
||||||
R.id.copy -> {
|
R.id.copy -> {
|
||||||
for (i in explorerAdapter.selectedItems){
|
for (i in explorerAdapter.selectedItems){
|
||||||
filesToCopy.add(explorerElements[i])
|
itemsToProcess.add(explorerElements[i])
|
||||||
}
|
}
|
||||||
modeSelectLocation = true
|
currentItemAction = ItemsActions.COPY
|
||||||
unselectAll()
|
unselectAll()
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
R.id.validate -> {
|
R.id.validate -> {
|
||||||
|
if (currentItemAction == ItemsActions.COPY){
|
||||||
object : LoadingTask(this, R.string.loading_msg_copy){
|
object : LoadingTask(this, R.string.loading_msg_copy){
|
||||||
override fun doTask(activity: AppCompatActivity) {
|
override fun doTask(activity: AppCompatActivity) {
|
||||||
var failedItem: String? = null
|
var failedItem: String? = null
|
||||||
Looper.prepare()
|
Looper.prepare()
|
||||||
for (element in filesToCopy) {
|
for (element in itemsToProcess) {
|
||||||
failedItem = if (element.isDirectory) {
|
val dstPath = checkPathOverwrite(PathUtils.path_join(currentDirectoryPath, element.name), element.isDirectory)
|
||||||
recursiveCopyDirectory(element.fullPath, currentDirectoryPath)
|
failedItem = if (dstPath == null){
|
||||||
} else {
|
|
||||||
val dstPath = checkFileOverwrite(PathUtils.path_join(currentDirectoryPath, element.name))
|
|
||||||
if (dstPath == null){
|
|
||||||
""
|
""
|
||||||
|
} else {
|
||||||
|
if (element.isDirectory) {
|
||||||
|
recursiveCopyDirectory(element.fullPath, dstPath)
|
||||||
} else {
|
} else {
|
||||||
if (copyFile(element.fullPath, dstPath)) null else element.fullPath
|
if (copyFile(element.fullPath, dstPath)) null else element.fullPath
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (failedItem != null && failedItem.isNotEmpty()) {
|
if (failedItem != null){
|
||||||
|
if (failedItem.isNotEmpty()) {
|
||||||
stopTask {
|
stopTask {
|
||||||
ColoredAlertDialogBuilder(activity)
|
ColoredAlertDialogBuilder(activity)
|
||||||
.setTitle(R.string.error)
|
.setTitle(R.string.error)
|
||||||
.setMessage(getString(R.string.copy_failed, failedItem))
|
.setMessage(getString(
|
||||||
|
R.string.copy_failed,
|
||||||
|
failedItem
|
||||||
|
))
|
||||||
.setPositiveButton(R.string.ok, null)
|
.setPositiveButton(R.string.ok, null)
|
||||||
.show()
|
.show()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -402,11 +419,41 @@ class ExplorerActivity : BaseExplorerActivity() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
override fun doFinally(activity: AppCompatActivity) {
|
override fun doFinally(activity: AppCompatActivity) {
|
||||||
cancelCopy()
|
cancelItemAction()
|
||||||
unselectAll()
|
unselectAll()
|
||||||
setCurrentPath(currentDirectoryPath)
|
setCurrentPath(currentDirectoryPath)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if (currentItemAction == ItemsActions.MOVE){
|
||||||
|
object : LoadingTask(this, R.string.loading_msg_move){
|
||||||
|
override fun doTask(activity: AppCompatActivity) {
|
||||||
|
Looper.prepare()
|
||||||
|
val failedItem = moveElements(itemsToProcess, currentDirectoryPath)
|
||||||
|
if (failedItem == null) {
|
||||||
|
stopTask {
|
||||||
|
ColoredAlertDialogBuilder(activity)
|
||||||
|
.setTitle(getString(R.string.move_success))
|
||||||
|
.setMessage(getString(R.string.move_success_msg))
|
||||||
|
.setPositiveButton(R.string.ok, null)
|
||||||
|
.show()
|
||||||
|
}
|
||||||
|
} else if (failedItem.isNotEmpty()){
|
||||||
|
stopTask {
|
||||||
|
ColoredAlertDialogBuilder(activity)
|
||||||
|
.setTitle(R.string.error)
|
||||||
|
.setMessage(getString(R.string.move_failed, failedItem))
|
||||||
|
.setPositiveButton(R.string.ok, null)
|
||||||
|
.show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
override fun doFinally(activity: AppCompatActivity) {
|
||||||
|
cancelItemAction()
|
||||||
|
unselectAll()
|
||||||
|
setCurrentPath(currentDirectoryPath)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
R.id.delete -> {
|
R.id.delete -> {
|
||||||
@ -443,16 +490,16 @@ class ExplorerActivity : BaseExplorerActivity() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun cancelCopy() {
|
private fun cancelItemAction() {
|
||||||
if (modeSelectLocation){
|
if (currentItemAction != ItemsActions.NONE){
|
||||||
modeSelectLocation = false
|
currentItemAction = ItemsActions.NONE
|
||||||
filesToCopy.clear()
|
itemsToProcess.clear()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onBackPressed() {
|
override fun onBackPressed() {
|
||||||
if (modeSelectLocation) {
|
if (currentItemAction != ItemsActions.NONE) {
|
||||||
cancelCopy()
|
cancelItemAction()
|
||||||
invalidateOptionsMenu()
|
invalidateOptionsMenu()
|
||||||
} else {
|
} else {
|
||||||
super.onBackPressed()
|
super.onBackPressed()
|
||||||
@ -488,24 +535,24 @@ class ExplorerActivity : BaseExplorerActivity() {
|
|||||||
return success
|
return success
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun recursiveCopyDirectory(srcDirectoryPath: String, outputPath: String): String? {
|
private fun recursiveCopyDirectory(srcDirectoryPath: String, dstDirectoryPath: String): String? {
|
||||||
val mappedElements = gocryptfsVolume.recursiveMapFiles(srcDirectoryPath)
|
val mappedElements = gocryptfsVolume.recursiveMapFiles(srcDirectoryPath)
|
||||||
val dstDirectoryPath = PathUtils.path_join(outputPath, File(srcDirectoryPath).name)
|
if (!gocryptfsVolume.pathExists(dstDirectoryPath)){
|
||||||
if (!gocryptfsVolume.pathExists(dstDirectoryPath)) {
|
|
||||||
if (!gocryptfsVolume.mkdir(dstDirectoryPath)) {
|
if (!gocryptfsVolume.mkdir(dstDirectoryPath)) {
|
||||||
return dstDirectoryPath
|
return srcDirectoryPath
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (e in mappedElements) {
|
for (e in mappedElements) {
|
||||||
val dstPath = PathUtils.path_join(dstDirectoryPath, PathUtils.getRelativePath(srcDirectoryPath, e.fullPath))
|
val dstPath = checkPathOverwrite(PathUtils.path_join(dstDirectoryPath, PathUtils.getRelativePath(srcDirectoryPath, e.fullPath)), e.isDirectory)
|
||||||
|
if (dstPath == null){
|
||||||
|
return ""
|
||||||
|
} else {
|
||||||
if (e.isDirectory) {
|
if (e.isDirectory) {
|
||||||
|
if (!gocryptfsVolume.pathExists(dstPath)){
|
||||||
if (!gocryptfsVolume.mkdir(dstPath)){
|
if (!gocryptfsVolume.mkdir(dstPath)){
|
||||||
return e.fullPath
|
return e.fullPath
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
val checkedDstPath = checkFileOverwrite(dstPath)
|
|
||||||
if (checkedDstPath == null){
|
|
||||||
return ""
|
|
||||||
} else {
|
} else {
|
||||||
if (!copyFile(e.fullPath, dstPath)) {
|
if (!copyFile(e.fullPath, dstPath)) {
|
||||||
return e.fullPath
|
return e.fullPath
|
||||||
@ -516,6 +563,38 @@ class ExplorerActivity : BaseExplorerActivity() {
|
|||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun moveDirectory(srcDirectoryPath: String, dstDirectoryPath: String): String? {
|
||||||
|
if (!gocryptfsVolume.pathExists(dstDirectoryPath)) {
|
||||||
|
if (!gocryptfsVolume.rename(srcDirectoryPath, dstDirectoryPath)) {
|
||||||
|
return srcDirectoryPath
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
moveElements(gocryptfsVolume.listDir(srcDirectoryPath), dstDirectoryPath)
|
||||||
|
gocryptfsVolume.rmdir(srcDirectoryPath)
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun moveElements(elements: List<ExplorerElement>, dstDirectoryPath: String): String? {
|
||||||
|
for (element in elements){
|
||||||
|
val dstPath = checkPathOverwrite(PathUtils.path_join(dstDirectoryPath, element.name), element.isDirectory)
|
||||||
|
if (dstPath == null){
|
||||||
|
return ""
|
||||||
|
} else {
|
||||||
|
if (element.isDirectory){
|
||||||
|
moveDirectory(element.fullPath, dstPath)?.let{
|
||||||
|
return it
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!gocryptfsVolume.rename(element.fullPath, dstPath)){
|
||||||
|
return element.fullPath
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
private fun importFileFromOtherVolume(remoteGocryptfsVolume: GocryptfsVolume, srcPath: String, dstPath: String): Boolean {
|
private fun importFileFromOtherVolume(remoteGocryptfsVolume: GocryptfsVolume, srcPath: String, dstPath: String): Boolean {
|
||||||
var success = true
|
var success = true
|
||||||
val srcHandleID = remoteGocryptfsVolume.openReadMode(srcPath)
|
val srcHandleID = remoteGocryptfsVolume.openReadMode(srcPath)
|
||||||
@ -525,9 +604,7 @@ class ExplorerActivity : BaseExplorerActivity() {
|
|||||||
var length: Int
|
var length: Int
|
||||||
val ioBuffer = ByteArray(GocryptfsVolume.DefaultBS)
|
val ioBuffer = ByteArray(GocryptfsVolume.DefaultBS)
|
||||||
var offset: Long = 0
|
var offset: Long = 0
|
||||||
while (remoteGocryptfsVolume.readFile(srcHandleID, offset, ioBuffer)
|
while (remoteGocryptfsVolume.readFile(srcHandleID, offset, ioBuffer).also { length = it } > 0) {
|
||||||
.also { length = it } > 0
|
|
||||||
) {
|
|
||||||
val written =
|
val written =
|
||||||
gocryptfsVolume.writeFile(dstHandleID, offset, ioBuffer, length).toLong()
|
gocryptfsVolume.writeFile(dstHandleID, offset, ioBuffer, length).toLong()
|
||||||
if (written == length.toLong()) {
|
if (written == length.toLong()) {
|
||||||
@ -545,39 +622,44 @@ class ExplorerActivity : BaseExplorerActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun safeImportFileFromOtherVolume(remoteGocryptfsVolume: GocryptfsVolume, srcPath: String, dstPath: String): String? {
|
private fun safeImportFileFromOtherVolume(remoteGocryptfsVolume: GocryptfsVolume, srcPath: String, dstPath: String): String? {
|
||||||
val checkedDstPath = checkFileOverwrite(PathUtils.path_join(currentDirectoryPath, File(dstPath).name))
|
val checkedDstPath = checkPathOverwrite(dstPath, false)
|
||||||
return if (checkedDstPath == null){
|
return if (checkedDstPath == null){
|
||||||
""
|
""
|
||||||
} else {
|
} else {
|
||||||
if (importFileFromOtherVolume(remoteGocryptfsVolume, srcPath, checkedDstPath)) null else dstPath
|
if (importFileFromOtherVolume(remoteGocryptfsVolume, srcPath, checkedDstPath)) null else srcPath
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun recursiveImportDirectoryFromOtherVolume(remote_gocryptfsVolume: GocryptfsVolume, remote_directory_path: String, outputPath: String): String? {
|
private fun recursiveImportDirectoryFromOtherVolume(remote_gocryptfsVolume: GocryptfsVolume, remote_directory_path: String, outputPath: String): String? {
|
||||||
val mappedElements = gocryptfsVolume.recursiveMapFiles(remote_directory_path)
|
val mappedElements = gocryptfsVolume.recursiveMapFiles(remote_directory_path)
|
||||||
val dstDirectoryPath = PathUtils.path_join(outputPath, File(remote_directory_path).name)
|
val dstDirectoryPath = checkPathOverwrite(PathUtils.path_join(outputPath, File(remote_directory_path).name), true)
|
||||||
|
if (dstDirectoryPath == null){
|
||||||
|
return ""
|
||||||
|
} else {
|
||||||
if (!gocryptfsVolume.pathExists(dstDirectoryPath)) {
|
if (!gocryptfsVolume.pathExists(dstDirectoryPath)) {
|
||||||
if (!gocryptfsVolume.mkdir(dstDirectoryPath)) {
|
if (!gocryptfsVolume.mkdir(dstDirectoryPath)) {
|
||||||
return dstDirectoryPath
|
return remote_directory_path
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (e in mappedElements) {
|
for (e in mappedElements) {
|
||||||
val dstPath = PathUtils.path_join(dstDirectoryPath, PathUtils.getRelativePath(remote_directory_path, e.fullPath))
|
val dstPath = checkPathOverwrite(PathUtils.path_join(dstDirectoryPath, PathUtils.getRelativePath(remote_directory_path, e.fullPath)), e.isDirectory)
|
||||||
|
if (dstPath == null){
|
||||||
|
return ""
|
||||||
|
} else {
|
||||||
if (e.isDirectory) {
|
if (e.isDirectory) {
|
||||||
|
if (!gocryptfsVolume.pathExists(dstPath)){
|
||||||
if (!gocryptfsVolume.mkdir(dstPath)){
|
if (!gocryptfsVolume.mkdir(dstPath)){
|
||||||
return e.fullPath
|
return e.fullPath
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
val checkedDstPath = checkFileOverwrite(dstPath)
|
if (!importFileFromOtherVolume(remote_gocryptfsVolume, e.fullPath, dstPath)) {
|
||||||
if (checkedDstPath == null){
|
|
||||||
return ""
|
|
||||||
} else {
|
|
||||||
if (!importFileFromOtherVolume(remote_gocryptfsVolume, e.fullPath, checkedDstPath)) {
|
|
||||||
return e.fullPath
|
return e.fullPath
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,25 +45,24 @@ class ExplorerActivityDrop : BaseExplorerActivity() {
|
|||||||
errorMsg = if (uri == null){
|
errorMsg = if (uri == null){
|
||||||
getString(R.string.share_intent_parsing_failed)
|
getString(R.string.share_intent_parsing_failed)
|
||||||
} else {
|
} else {
|
||||||
val outputPathTest = PathUtils.path_join(currentDirectoryPath, PathUtils.getFilenameFromURI(activity, uri))
|
val outputPath = checkPathOverwrite(PathUtils.path_join(currentDirectoryPath, PathUtils.getFilenameFromURI(activity, uri)), false)
|
||||||
val outputPath = checkFileOverwrite(outputPathTest)
|
|
||||||
if (outputPath == null) {
|
if (outputPath == null) {
|
||||||
""
|
""
|
||||||
} else {
|
} else {
|
||||||
if (gocryptfsVolume.importFile(activity, uri, outputPath)) null else getString(R.string.import_failed, outputPath)
|
if (gocryptfsVolume.importFile(activity, uri, outputPath)) null else getString(R.string.import_failed, uri)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (intent.action == Intent.ACTION_SEND_MULTIPLE) {
|
} else if (intent.action == Intent.ACTION_SEND_MULTIPLE) {
|
||||||
val uris = intent.getParcelableArrayListExtra<Uri>(Intent.EXTRA_STREAM)
|
val uris = intent.getParcelableArrayListExtra<Uri>(Intent.EXTRA_STREAM)
|
||||||
if (uris != null){
|
if (uris != null){
|
||||||
for (uri in uris) {
|
for (uri in uris) {
|
||||||
val outputPath = checkFileOverwrite(PathUtils.path_join(currentDirectoryPath, PathUtils.getFilenameFromURI(activity, uri)))
|
val outputPath = checkPathOverwrite(PathUtils.path_join(currentDirectoryPath, PathUtils.getFilenameFromURI(activity, uri)), false)
|
||||||
if (outputPath == null){
|
if (outputPath == null){
|
||||||
errorMsg = ""
|
errorMsg = ""
|
||||||
break
|
break
|
||||||
} else {
|
} else {
|
||||||
if (!gocryptfsVolume.importFile(activity, uri, outputPath)) {
|
if (!gocryptfsVolume.importFile(activity, uri, outputPath)) {
|
||||||
errorMsg = getString(R.string.import_failed, outputPath)
|
errorMsg = getString(R.string.import_failed, uri)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
9
app/src/main/res/drawable/icon_cut.xml
Normal file
9
app/src/main/res/drawable/icon_cut.xml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="48"
|
||||||
|
android:viewportHeight="48">
|
||||||
|
<path
|
||||||
|
android:fillColor="#FFFFFF"
|
||||||
|
android:pathData="M19.28,15.28c0.45,-1 0.72,-2.11 0.72,-3.28 0,-4.42 -3.58,-8 -8,-8s-8,3.58 -8,8 3.58,8 8,8c1.17,0 2.28,-0.27 3.28,-0.72l4.72,4.72 -4.72,4.72c-1,-0.45 -2.11,-0.72 -3.28,-0.72 -4.42,0 -8,3.58 -8,8s3.58,8 8,8 8,-3.58 8,-8c0,-1.17 -0.27,-2.28 -0.72,-3.28l4.72,-4.72 14,14h6v-2l-24.72,-24.72zM12,16c-2.21,0 -4,-1.79 -4,-4s1.79,-4 4,-4 4,1.79 4,4 -1.79,4 -4,4zM12,40c-2.21,0 -4,-1.79 -4,-4s1.79,-4 4,-4 4,1.79 4,4 -1.79,4 -4,4zM24,25c-0.55,0 -1,-0.45 -1,-1s0.45,-1 1,-1 1,0.45 1,1 -0.45,1 -1,1zM38,6l-12,12 4,4 14,-14v-2z"/>
|
||||||
|
</vector>
|
@ -9,10 +9,10 @@
|
|||||||
android:icon="@drawable/icon_select_all"/>
|
android:icon="@drawable/icon_select_all"/>
|
||||||
|
|
||||||
<item
|
<item
|
||||||
android:id="@+id/copy"
|
android:id="@+id/cut"
|
||||||
app:showAsAction="always"
|
app:showAsAction="always"
|
||||||
android:visible="false"
|
android:visible="false"
|
||||||
android:icon="@drawable/icon_copy"/>
|
android:icon="@drawable/icon_cut"/>
|
||||||
|
|
||||||
<item
|
<item
|
||||||
android:id="@+id/delete"
|
android:id="@+id/delete"
|
||||||
@ -20,6 +20,13 @@
|
|||||||
android:visible="false"
|
android:visible="false"
|
||||||
android:icon="@drawable/icon_delete" />
|
android:icon="@drawable/icon_delete" />
|
||||||
|
|
||||||
|
<item
|
||||||
|
android:id="@+id/copy"
|
||||||
|
app:showAsAction="ifRoom"
|
||||||
|
android:visible="false"
|
||||||
|
android:icon="@drawable/icon_copy"
|
||||||
|
android:title="@string/copy_menu_title"/>
|
||||||
|
|
||||||
<item
|
<item
|
||||||
android:id="@+id/decrypt"
|
android:id="@+id/decrypt"
|
||||||
app:showAsAction="ifRoom"
|
app:showAsAction="ifRoom"
|
||||||
|
@ -19,11 +19,11 @@
|
|||||||
<string name="error_mkdir">Folder creation failed.</string>
|
<string name="error_mkdir">Folder creation failed.</string>
|
||||||
<string name="success_import">Import successful !</string>
|
<string name="success_import">Import successful !</string>
|
||||||
<string name="success_import_msg">The selected files have been successfully imported.</string>
|
<string name="success_import_msg">The selected files have been successfully imported.</string>
|
||||||
<string name="import_failed">Import of %1$s failed.</string>
|
<string name="import_failed">Import of %s failed.</string>
|
||||||
<string name="export_failed">Export of %1$s failed.</string>
|
<string name="export_failed">Export of %s failed.</string>
|
||||||
<string name="success_export">Export successful !</string>
|
<string name="success_export">Export successful !</string>
|
||||||
<string name="success_export_msg">The selected files have been successfully exported.</string>
|
<string name="success_export_msg">The selected files have been successfully exported.</string>
|
||||||
<string name="remove_failed">Deletion of %1$s failed</string>
|
<string name="remove_failed">Deletion of %s failed</string>
|
||||||
<string name="passwords_mismatch">Passwords don\'t match</string>
|
<string name="passwords_mismatch">Passwords don\'t match</string>
|
||||||
<string name="dir_not_empty">The selected directory isn\'t empty</string>
|
<string name="dir_not_empty">The selected directory isn\'t empty</string>
|
||||||
<string name="success_volume_create">Volume successfully created !</string>
|
<string name="success_volume_create">Volume successfully created !</string>
|
||||||
@ -40,24 +40,24 @@
|
|||||||
<string name="parent_folder">Parent Folder</string>
|
<string name="parent_folder">Parent Folder</string>
|
||||||
<string name="enter_volume_path">Please enter the volume path</string>
|
<string name="enter_volume_path">Please enter the volume path</string>
|
||||||
<string name="external_open">Open with external app</string>
|
<string name="external_open">Open with external app</string>
|
||||||
<string name="single_delete_confirm">Are you sure you want to delete %1$s ?</string>
|
<string name="single_delete_confirm">Are you sure you want to delete %s ?</string>
|
||||||
<string name="multiple_delete_confirm">Are you sure you want to delete these %1$s items ?</string>
|
<string name="multiple_delete_confirm">Are you sure you want to delete these %s items ?</string>
|
||||||
<string name="location">Location: /%1$s</string>
|
<string name="location">Location: /%s</string>
|
||||||
<string name="total_size">Total size: %1$s</string>
|
<string name="total_size">Total size: %s</string>
|
||||||
<string name="import_from_other_volume">Import from another volume</string>
|
<string name="import_from_other_volume">Import from another volume</string>
|
||||||
<string name="read_file_failed">Failed to open this file.</string>
|
<string name="read_file_failed">Failed to open this file.</string>
|
||||||
<string name="volume">Volume: %1$s</string>
|
<string name="volume">Volume: %s</string>
|
||||||
<string name="yes">YES</string>
|
<string name="yes">YES</string>
|
||||||
<string name="no">NO</string>
|
<string name="no">NO</string>
|
||||||
<string name="ask_for_wipe">Do you want to wipe the original files ?</string>
|
<string name="ask_for_wipe">Do you want to wipe the original files ?</string>
|
||||||
<string name="wipe_failed">Wiping failed: %1$s</string>
|
<string name="wipe_failed">Wiping failed: %s</string>
|
||||||
<string name="wipe_successful">Files successfully wiped !</string>
|
<string name="wipe_successful">Files successfully wiped !</string>
|
||||||
<string name="wipe_success_msg">The imported files have been successfully wiped from their original locations.</string>
|
<string name="wipe_success_msg">The imported files have been successfully wiped from their original locations.</string>
|
||||||
<string name="create_password_warning">Warning !\nThis password will be the only way to decrypt the volume and access the files inside.\nChoose a very strong password (not \"123456\" or \"password\"), do not lose it and keep it secure (preferably only in your mind).\n\nDroidFS cannot protect you from screen recording apps, keyloggers, apk backdooring, compromised root accesses, memory dumps etc.\nDo not type passwords in insecure environments.</string>
|
<string name="create_password_warning">Warning !\nThis password will be the only way to decrypt the volume and access the files inside.\nChoose a very strong password (not \"123456\" or \"password\"), do not lose it and keep it secure (preferably only in your mind).\n\nDroidFS cannot protect you from screen recording apps, keyloggers, apk backdooring, compromised root accesses, memory dumps etc.\nDo not type passwords in insecure environments.</string>
|
||||||
<string name="open_activity_warning">Warning !\nOpening volumes in insecure environments can lead to data leaks.\nDroidFS cannot protect you from screen recording apps, keyloggers, apk backdooring, compromised root accesses, memory dumps etc.\nDo not open volumes containing sensitive data unless you know exactly what you are doing.</string>
|
<string name="open_activity_warning">Warning !\nOpening volumes in insecure environments can lead to data leaks.\nDroidFS cannot protect you from screen recording apps, keyloggers, apk backdooring, compromised root accesses, memory dumps etc.\nDo not open volumes containing sensitive data unless you know exactly what you are doing.</string>
|
||||||
<string name="rename">Rename</string>
|
<string name="rename">Rename</string>
|
||||||
<string name="rename_title">New name:</string>
|
<string name="rename_title">New name:</string>
|
||||||
<string name="rename_failed">Failed to rename %1$s</string>
|
<string name="rename_failed">Failed to rename %s</string>
|
||||||
<string name="remember_volume_path">Remember volume path</string>
|
<string name="remember_volume_path">Remember volume path</string>
|
||||||
<string name="sort_order">Sort order:</string>
|
<string name="sort_order">Sort order:</string>
|
||||||
<string name="old_password">Old password:</string>
|
<string name="old_password">Old password:</string>
|
||||||
@ -137,16 +137,22 @@
|
|||||||
<string name="share">Share</string>
|
<string name="share">Share</string>
|
||||||
<string name="decrypt">Decrypt</string>
|
<string name="decrypt">Decrypt</string>
|
||||||
<string name="loading_msg_copy">Copying selected items…</string>
|
<string name="loading_msg_copy">Copying selected items…</string>
|
||||||
<string name="copy_failed">Copy of %1$s failed.</string>
|
<string name="copy_failed">Copy of %s failed.</string>
|
||||||
<string name="copy_success_msg">The selected items have been successfully copied.</string>
|
<string name="copy_success_msg">The selected items have been successfully copied.</string>
|
||||||
<string name="copy_success">Copy successful !</string>
|
<string name="copy_success">Copy successful !</string>
|
||||||
<string name="fab_dialog_title">Add</string>
|
<string name="fab_dialog_title">Add</string>
|
||||||
<string name="take_photo">Take photo</string>
|
<string name="take_photo">Take photo</string>
|
||||||
<string name="picture_save_success">Picture saved to %1$s</string>
|
<string name="picture_save_success">Picture saved to %s</string>
|
||||||
<string name="picture_save_failed">Failed to save this picture.</string>
|
<string name="picture_save_failed">Failed to save this picture.</string>
|
||||||
<string name="default_total_size">N//A</string>
|
<string name="default_total_size">N//A</string>
|
||||||
<string name="file_overwrite_question">%s already exists, do you want to overwrite it ?</string>
|
<string name="file_overwrite_question">%s already exists, do you want to overwrite it ?</string>
|
||||||
<string name="enter_new_filename">Enter new filename</string>
|
<string name="dir_overwrite_question">%s already exists, do you want to merge its content ?</string>
|
||||||
|
<string name="enter_new_name">Enter new name</string>
|
||||||
<string name="reset_theme_color">Reset theme color</string>
|
<string name="reset_theme_color">Reset theme color</string>
|
||||||
<string name="reset_theme_color_summary">Reset theme color to the default one</string>
|
<string name="reset_theme_color_summary">Reset theme color to the default one</string>
|
||||||
|
<string name="copy_menu_title">Copy</string>
|
||||||
|
<string name="loading_msg_move">Moving selected items…</string>
|
||||||
|
<string name="move_failed">Move of %s failed.</string>
|
||||||
|
<string name="move_success_msg">The selected items have been successfully moved.</string>
|
||||||
|
<string name="move_success">Move successful !</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
Loading…
Reference in New Issue
Block a user