forked from hardcoresushi/DroidFS
Move feature
This commit is contained in:
parent
35a2e35bdc
commit
cac264043f
@ -250,7 +250,7 @@ open class BaseExplorerActivity : BaseActivity() {
|
||||
dialog.show()
|
||||
}
|
||||
|
||||
protected fun checkFileOverwrite(path: String): String? {
|
||||
protected fun checkPathOverwrite(path: String, isDirectory: Boolean): String? {
|
||||
var outputPath: String? = null
|
||||
if (gocryptfsVolume.pathExists(path)){
|
||||
val fileName = File(path).name
|
||||
@ -261,7 +261,7 @@ open class BaseExplorerActivity : BaseActivity() {
|
||||
runOnUiThread {
|
||||
val dialog = ColoredAlertDialogBuilder(this)
|
||||
.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) { _, _ ->
|
||||
val dialogEditTextView = layoutInflater.inflate(R.layout.dialog_edit_text, null)
|
||||
val dialogEditText = dialogEditTextView.findViewById<EditText>(R.id.dialog_edit_text)
|
||||
@ -269,15 +269,15 @@ open class BaseExplorerActivity : BaseActivity() {
|
||||
dialogEditText.selectAll()
|
||||
val dialog = ColoredAlertDialogBuilder(this)
|
||||
.setView(dialogEditTextView)
|
||||
.setTitle(getString(R.string.enter_new_filename))
|
||||
.setTitle(getString(R.string.enter_new_name))
|
||||
.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 }) }
|
||||
.create()
|
||||
dialogEditText.setOnEditorActionListener { _, _, _ ->
|
||||
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
|
||||
}
|
||||
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.widgets.ColoredAlertDialogBuilder
|
||||
import java.io.File
|
||||
import kotlin.collections.ArrayList
|
||||
|
||||
class ExplorerActivity : BaseExplorerActivity() {
|
||||
private val PICK_DIRECTORY_REQUEST_CODE = 1
|
||||
private val PICK_FILES_REQUEST_CODE = 2
|
||||
private val PICK_OTHER_VOLUME_ITEMS_REQUEST_CODE = 3
|
||||
companion object {
|
||||
private const val PICK_DIRECTORY_REQUEST_CODE = 1
|
||||
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_share = false
|
||||
private var modeSelectLocation = false
|
||||
private val filesToCopy = ArrayList<ExplorerElement>()
|
||||
private var currentItemAction = ItemsActions.NONE
|
||||
private val itemsToProcess = ArrayList<ExplorerElement>()
|
||||
override fun init() {
|
||||
setContentView(R.layout.activity_explorer)
|
||||
usf_decrypt = sharedPrefs.getBoolean("usf_decrypt", false)
|
||||
@ -35,7 +37,7 @@ class ExplorerActivity : BaseExplorerActivity() {
|
||||
}
|
||||
|
||||
override fun onExplorerItemLongClick(position: Int) {
|
||||
cancelCopy()
|
||||
cancelItemAction()
|
||||
explorerAdapter.onItemLongClick(position)
|
||||
invalidateOptionsMenu()
|
||||
}
|
||||
@ -44,7 +46,7 @@ class ExplorerActivity : BaseExplorerActivity() {
|
||||
if (fileName.isEmpty()) {
|
||||
Toast.makeText(this, R.string.error_filename_empty, Toast.LENGTH_SHORT).show()
|
||||
} else {
|
||||
checkFileOverwrite(PathUtils.path_join(currentDirectoryPath, fileName))?.let {
|
||||
checkPathOverwrite(PathUtils.path_join(currentDirectoryPath, fileName), false)?.let {
|
||||
val handleID = gocryptfsVolume.openWriteMode(it)
|
||||
if (handleID == -1) {
|
||||
ColoredAlertDialogBuilder(this)
|
||||
@ -62,7 +64,7 @@ class ExplorerActivity : BaseExplorerActivity() {
|
||||
}
|
||||
|
||||
fun onClickFAB(view: View) {
|
||||
if (modeSelectLocation){
|
||||
if (currentItemAction != ItemsActions.NONE){
|
||||
openDialogCreateFolder()
|
||||
} else {
|
||||
val adapter = IconTextDialogAdapter(this)
|
||||
@ -152,7 +154,7 @@ class ExplorerActivity : BaseExplorerActivity() {
|
||||
Looper.prepare()
|
||||
var success = false
|
||||
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){
|
||||
break
|
||||
} else {
|
||||
@ -316,7 +318,7 @@ class ExplorerActivity : BaseExplorerActivity() {
|
||||
|
||||
override fun onCreateOptionsMenu(menu: Menu): Boolean {
|
||||
menuInflater.inflate(R.menu.explorer, menu)
|
||||
if (modeSelectLocation) {
|
||||
if (currentItemAction != ItemsActions.NONE) {
|
||||
menu.findItem(R.id.validate).isVisible = true
|
||||
menu.findItem(R.id.close).isVisible = false
|
||||
} else {
|
||||
@ -328,6 +330,7 @@ class ExplorerActivity : BaseExplorerActivity() {
|
||||
menu.findItem(R.id.select_all).isVisible = anyItemSelected
|
||||
menu.findItem(R.id.delete).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
|
||||
if (anyItemSelected && usf_share){
|
||||
var containsDir = false
|
||||
@ -348,7 +351,7 @@ class ExplorerActivity : BaseExplorerActivity() {
|
||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||
return when (item.itemId) {
|
||||
android.R.id.home -> {
|
||||
cancelCopy()
|
||||
cancelItemAction()
|
||||
super.onOptionsItemSelected(item)
|
||||
}
|
||||
R.id.select_all -> {
|
||||
@ -356,55 +359,99 @@ class ExplorerActivity : BaseExplorerActivity() {
|
||||
invalidateOptionsMenu()
|
||||
true
|
||||
}
|
||||
R.id.cut -> {
|
||||
for (i in explorerAdapter.selectedItems){
|
||||
itemsToProcess.add(explorerElements[i])
|
||||
}
|
||||
currentItemAction = ItemsActions.MOVE
|
||||
unselectAll()
|
||||
true
|
||||
}
|
||||
R.id.copy -> {
|
||||
for (i in explorerAdapter.selectedItems){
|
||||
filesToCopy.add(explorerElements[i])
|
||||
itemsToProcess.add(explorerElements[i])
|
||||
}
|
||||
modeSelectLocation = true
|
||||
currentItemAction = ItemsActions.COPY
|
||||
unselectAll()
|
||||
true
|
||||
}
|
||||
R.id.validate -> {
|
||||
object : LoadingTask(this, R.string.loading_msg_copy){
|
||||
override fun doTask(activity: AppCompatActivity) {
|
||||
var failedItem: String? = null
|
||||
Looper.prepare()
|
||||
for (element in filesToCopy) {
|
||||
failedItem = if (element.isDirectory) {
|
||||
recursiveCopyDirectory(element.fullPath, currentDirectoryPath)
|
||||
} else {
|
||||
val dstPath = checkFileOverwrite(PathUtils.path_join(currentDirectoryPath, element.name))
|
||||
if (dstPath == null){
|
||||
if (currentItemAction == ItemsActions.COPY){
|
||||
object : LoadingTask(this, R.string.loading_msg_copy){
|
||||
override fun doTask(activity: AppCompatActivity) {
|
||||
var failedItem: String? = null
|
||||
Looper.prepare()
|
||||
for (element in itemsToProcess) {
|
||||
val dstPath = checkPathOverwrite(PathUtils.path_join(currentDirectoryPath, element.name), element.isDirectory)
|
||||
failedItem = if (dstPath == null){
|
||||
""
|
||||
} else {
|
||||
if (copyFile(element.fullPath, dstPath)) null else element.fullPath
|
||||
if (element.isDirectory) {
|
||||
recursiveCopyDirectory(element.fullPath, dstPath)
|
||||
} else {
|
||||
if (copyFile(element.fullPath, dstPath)) null else element.fullPath
|
||||
}
|
||||
}
|
||||
if (failedItem != null){
|
||||
if (failedItem.isNotEmpty()) {
|
||||
stopTask {
|
||||
ColoredAlertDialogBuilder(activity)
|
||||
.setTitle(R.string.error)
|
||||
.setMessage(getString(
|
||||
R.string.copy_failed,
|
||||
failedItem
|
||||
))
|
||||
.setPositiveButton(R.string.ok, null)
|
||||
.show()
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
if (failedItem != null && failedItem.isNotEmpty()) {
|
||||
if (failedItem == null) {
|
||||
stopTask {
|
||||
ColoredAlertDialogBuilder(activity)
|
||||
.setTitle(R.string.error)
|
||||
.setMessage(getString(R.string.copy_failed, failedItem))
|
||||
.setTitle(getString(R.string.copy_success))
|
||||
.setMessage(getString(R.string.copy_success_msg))
|
||||
.setPositiveButton(R.string.ok, null)
|
||||
.show()
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
if (failedItem == null) {
|
||||
stopTask {
|
||||
ColoredAlertDialogBuilder(activity)
|
||||
.setTitle(getString(R.string.copy_success))
|
||||
.setMessage(getString(R.string.copy_success_msg))
|
||||
.setPositiveButton(R.string.ok, null)
|
||||
.show()
|
||||
}
|
||||
override fun doFinally(activity: AppCompatActivity) {
|
||||
cancelItemAction()
|
||||
unselectAll()
|
||||
setCurrentPath(currentDirectoryPath)
|
||||
}
|
||||
}
|
||||
override fun doFinally(activity: AppCompatActivity) {
|
||||
cancelCopy()
|
||||
unselectAll()
|
||||
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
|
||||
@ -443,16 +490,16 @@ class ExplorerActivity : BaseExplorerActivity() {
|
||||
}
|
||||
}
|
||||
|
||||
private fun cancelCopy() {
|
||||
if (modeSelectLocation){
|
||||
modeSelectLocation = false
|
||||
filesToCopy.clear()
|
||||
private fun cancelItemAction() {
|
||||
if (currentItemAction != ItemsActions.NONE){
|
||||
currentItemAction = ItemsActions.NONE
|
||||
itemsToProcess.clear()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onBackPressed() {
|
||||
if (modeSelectLocation) {
|
||||
cancelCopy()
|
||||
if (currentItemAction != ItemsActions.NONE) {
|
||||
cancelItemAction()
|
||||
invalidateOptionsMenu()
|
||||
} else {
|
||||
super.onBackPressed()
|
||||
@ -488,24 +535,24 @@ class ExplorerActivity : BaseExplorerActivity() {
|
||||
return success
|
||||
}
|
||||
|
||||
private fun recursiveCopyDirectory(srcDirectoryPath: String, outputPath: String): String? {
|
||||
private fun recursiveCopyDirectory(srcDirectoryPath: String, dstDirectoryPath: String): String? {
|
||||
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)) {
|
||||
return dstDirectoryPath
|
||||
return srcDirectoryPath
|
||||
}
|
||||
}
|
||||
for (e in mappedElements) {
|
||||
val dstPath = PathUtils.path_join(dstDirectoryPath, PathUtils.getRelativePath(srcDirectoryPath, e.fullPath))
|
||||
if (e.isDirectory) {
|
||||
if (!gocryptfsVolume.mkdir(dstPath)){
|
||||
return e.fullPath
|
||||
}
|
||||
val dstPath = checkPathOverwrite(PathUtils.path_join(dstDirectoryPath, PathUtils.getRelativePath(srcDirectoryPath, e.fullPath)), e.isDirectory)
|
||||
if (dstPath == null){
|
||||
return ""
|
||||
} else {
|
||||
val checkedDstPath = checkFileOverwrite(dstPath)
|
||||
if (checkedDstPath == null){
|
||||
return ""
|
||||
if (e.isDirectory) {
|
||||
if (!gocryptfsVolume.pathExists(dstPath)){
|
||||
if (!gocryptfsVolume.mkdir(dstPath)){
|
||||
return e.fullPath
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (!copyFile(e.fullPath, dstPath)) {
|
||||
return e.fullPath
|
||||
@ -516,6 +563,38 @@ class ExplorerActivity : BaseExplorerActivity() {
|
||||
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 {
|
||||
var success = true
|
||||
val srcHandleID = remoteGocryptfsVolume.openReadMode(srcPath)
|
||||
@ -525,9 +604,7 @@ class ExplorerActivity : BaseExplorerActivity() {
|
||||
var length: Int
|
||||
val ioBuffer = ByteArray(GocryptfsVolume.DefaultBS)
|
||||
var offset: Long = 0
|
||||
while (remoteGocryptfsVolume.readFile(srcHandleID, offset, ioBuffer)
|
||||
.also { length = it } > 0
|
||||
) {
|
||||
while (remoteGocryptfsVolume.readFile(srcHandleID, offset, ioBuffer).also { length = it } > 0) {
|
||||
val written =
|
||||
gocryptfsVolume.writeFile(dstHandleID, offset, ioBuffer, length).toLong()
|
||||
if (written == length.toLong()) {
|
||||
@ -545,35 +622,40 @@ class ExplorerActivity : BaseExplorerActivity() {
|
||||
}
|
||||
|
||||
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){
|
||||
""
|
||||
} 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? {
|
||||
val mappedElements = gocryptfsVolume.recursiveMapFiles(remote_directory_path)
|
||||
val dstDirectoryPath = PathUtils.path_join(outputPath, File(remote_directory_path).name)
|
||||
if (!gocryptfsVolume.pathExists(dstDirectoryPath)) {
|
||||
if (!gocryptfsVolume.mkdir(dstDirectoryPath)) {
|
||||
return dstDirectoryPath
|
||||
}
|
||||
}
|
||||
for (e in mappedElements) {
|
||||
val dstPath = PathUtils.path_join(dstDirectoryPath, PathUtils.getRelativePath(remote_directory_path, e.fullPath))
|
||||
if (e.isDirectory) {
|
||||
if (!gocryptfsVolume.mkdir(dstPath)){
|
||||
return e.fullPath
|
||||
val dstDirectoryPath = checkPathOverwrite(PathUtils.path_join(outputPath, File(remote_directory_path).name), true)
|
||||
if (dstDirectoryPath == null){
|
||||
return ""
|
||||
} else {
|
||||
if (!gocryptfsVolume.pathExists(dstDirectoryPath)) {
|
||||
if (!gocryptfsVolume.mkdir(dstDirectoryPath)) {
|
||||
return remote_directory_path
|
||||
}
|
||||
} else {
|
||||
val checkedDstPath = checkFileOverwrite(dstPath)
|
||||
if (checkedDstPath == null){
|
||||
}
|
||||
for (e in mappedElements) {
|
||||
val dstPath = checkPathOverwrite(PathUtils.path_join(dstDirectoryPath, PathUtils.getRelativePath(remote_directory_path, e.fullPath)), e.isDirectory)
|
||||
if (dstPath == null){
|
||||
return ""
|
||||
} else {
|
||||
if (!importFileFromOtherVolume(remote_gocryptfsVolume, e.fullPath, checkedDstPath)) {
|
||||
return e.fullPath
|
||||
if (e.isDirectory) {
|
||||
if (!gocryptfsVolume.pathExists(dstPath)){
|
||||
if (!gocryptfsVolume.mkdir(dstPath)){
|
||||
return e.fullPath
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (!importFileFromOtherVolume(remote_gocryptfsVolume, e.fullPath, dstPath)) {
|
||||
return e.fullPath
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -45,25 +45,24 @@ class ExplorerActivityDrop : BaseExplorerActivity() {
|
||||
errorMsg = if (uri == null){
|
||||
getString(R.string.share_intent_parsing_failed)
|
||||
} else {
|
||||
val outputPathTest = PathUtils.path_join(currentDirectoryPath, PathUtils.getFilenameFromURI(activity, uri))
|
||||
val outputPath = checkFileOverwrite(outputPathTest)
|
||||
val outputPath = checkPathOverwrite(PathUtils.path_join(currentDirectoryPath, PathUtils.getFilenameFromURI(activity, uri)), false)
|
||||
if (outputPath == null) {
|
||||
""
|
||||
} 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) {
|
||||
val uris = intent.getParcelableArrayListExtra<Uri>(Intent.EXTRA_STREAM)
|
||||
if (uris != null){
|
||||
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){
|
||||
errorMsg = ""
|
||||
break
|
||||
} else {
|
||||
if (!gocryptfsVolume.importFile(activity, uri, outputPath)) {
|
||||
errorMsg = getString(R.string.import_failed, outputPath)
|
||||
errorMsg = getString(R.string.import_failed, uri)
|
||||
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"/>
|
||||
|
||||
<item
|
||||
android:id="@+id/copy"
|
||||
android:id="@+id/cut"
|
||||
app:showAsAction="always"
|
||||
android:visible="false"
|
||||
android:icon="@drawable/icon_copy"/>
|
||||
android:icon="@drawable/icon_cut"/>
|
||||
|
||||
<item
|
||||
android:id="@+id/delete"
|
||||
@ -20,6 +20,13 @@
|
||||
android:visible="false"
|
||||
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
|
||||
android:id="@+id/decrypt"
|
||||
app:showAsAction="ifRoom"
|
||||
|
@ -19,11 +19,11 @@
|
||||
<string name="error_mkdir">Folder creation failed.</string>
|
||||
<string name="success_import">Import successful !</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="export_failed">Export of %1$s failed.</string>
|
||||
<string name="import_failed">Import of %s failed.</string>
|
||||
<string name="export_failed">Export of %s failed.</string>
|
||||
<string name="success_export">Export successful !</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="dir_not_empty">The selected directory isn\'t empty</string>
|
||||
<string name="success_volume_create">Volume successfully created !</string>
|
||||
@ -40,24 +40,24 @@
|
||||
<string name="parent_folder">Parent Folder</string>
|
||||
<string name="enter_volume_path">Please enter the volume path</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="multiple_delete_confirm">Are you sure you want to delete these %1$s items ?</string>
|
||||
<string name="location">Location: /%1$s</string>
|
||||
<string name="total_size">Total size: %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 %s items ?</string>
|
||||
<string name="location">Location: /%s</string>
|
||||
<string name="total_size">Total size: %s</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="volume">Volume: %1$s</string>
|
||||
<string name="volume">Volume: %s</string>
|
||||
<string name="yes">YES</string>
|
||||
<string name="no">NO</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_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="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_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="sort_order">Sort order:</string>
|
||||
<string name="old_password">Old password:</string>
|
||||
@ -137,16 +137,22 @@
|
||||
<string name="share">Share</string>
|
||||
<string name="decrypt">Decrypt</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">Copy successful !</string>
|
||||
<string name="fab_dialog_title">Add</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="default_total_size">N//A</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_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>
|
||||
|
Loading…
Reference in New Issue
Block a user