DroidFS/app/src/main/java/sushi/hardcore/droidfs/explorers/BaseExplorerActivity.kt

582 lines
25 KiB
Kotlin
Raw Normal View History

2020-07-17 16:35:39 +02:00
package sushi.hardcore.droidfs.explorers
2020-12-29 17:05:02 +01:00
import android.content.ComponentName
import android.content.Context
2020-07-17 16:35:39 +02:00
import android.content.Intent
2020-12-29 17:05:02 +01:00
import android.content.ServiceConnection
2020-11-03 17:22:09 +01:00
import android.net.Uri
2020-07-17 16:35:39 +02:00
import android.os.Bundle
2020-12-29 17:05:02 +01:00
import android.os.IBinder
2020-07-17 16:35:39 +02:00
import android.view.Menu
import android.view.MenuItem
import android.view.View
import android.view.WindowManager
import android.widget.AdapterView.OnItemClickListener
import android.widget.AdapterView.OnItemLongClickListener
import android.widget.EditText
2021-06-11 20:23:54 +02:00
import android.widget.ListView
import android.widget.TextView
2020-07-17 16:35:39 +02:00
import android.widget.Toast
import androidx.documentfile.provider.DocumentFile
2020-08-04 11:44:29 +02:00
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
2021-06-11 20:23:54 +02:00
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
2020-07-21 15:05:05 +02:00
import sushi.hardcore.droidfs.BaseActivity
2020-07-17 16:35:39 +02:00
import sushi.hardcore.droidfs.ConstValues
import sushi.hardcore.droidfs.ConstValues.Companion.isAudio
import sushi.hardcore.droidfs.ConstValues.Companion.isImage
import sushi.hardcore.droidfs.ConstValues.Companion.isText
import sushi.hardcore.droidfs.ConstValues.Companion.isVideo
2021-06-26 12:09:29 +02:00
import sushi.hardcore.droidfs.GocryptfsVolume
2020-07-17 16:35:39 +02:00
import sushi.hardcore.droidfs.R
2020-07-27 16:20:52 +02:00
import sushi.hardcore.droidfs.adapters.DialogSingleChoiceAdapter
2020-07-17 16:35:39 +02:00
import sushi.hardcore.droidfs.adapters.ExplorerElementAdapter
2020-08-05 14:06:54 +02:00
import sushi.hardcore.droidfs.adapters.OpenAsDialogAdapter
2021-06-26 12:09:29 +02:00
import sushi.hardcore.droidfs.content_providers.ExternalProvider
import sushi.hardcore.droidfs.content_providers.RestrictedFileProvider
import sushi.hardcore.droidfs.file_operations.FileOperationService
2020-12-29 17:05:02 +01:00
import sushi.hardcore.droidfs.file_operations.OperationFile
2020-07-17 16:35:39 +02:00
import sushi.hardcore.droidfs.file_viewers.AudioPlayer
import sushi.hardcore.droidfs.file_viewers.ImageViewer
import sushi.hardcore.droidfs.file_viewers.TextEditor
import sushi.hardcore.droidfs.file_viewers.VideoPlayer
2020-08-05 14:06:54 +02:00
import sushi.hardcore.droidfs.util.PathUtils
2020-07-27 16:20:52 +02:00
import sushi.hardcore.droidfs.widgets.ColoredAlertDialogBuilder
2020-07-17 16:35:39 +02:00
2020-07-21 15:05:05 +02:00
open class BaseExplorerActivity : BaseActivity() {
2020-08-04 11:44:29 +02:00
private lateinit var sortOrderEntries: Array<String>
private lateinit var sortOrderValues: Array<String>
private var foldersFirst = true
2021-07-10 12:02:56 +02:00
private var mapFolders = true
2020-08-04 11:44:29 +02:00
private var currentSortOrderIndex = 0
2020-07-17 16:35:39 +02:00
protected lateinit var gocryptfsVolume: GocryptfsVolume
private lateinit var volumeName: String
2020-08-04 11:44:29 +02:00
private lateinit var explorerViewModel: ExplorerViewModel
protected var currentDirectoryPath: String = ""
set(value) {
field = value
explorerViewModel.currentDirectoryPath = value
}
2020-12-29 17:05:02 +01:00
protected lateinit var fileOperationService: FileOperationService
protected lateinit var explorerElements: MutableList<ExplorerElement>
protected lateinit var explorerAdapter: ExplorerElementAdapter
2020-08-05 14:06:54 +02:00
private var isCreating = true
protected var isStartingActivity = false
2020-07-17 16:35:39 +02:00
private var usf_open = false
protected var usf_keep_open = false
2021-06-11 20:23:54 +02:00
private lateinit var toolbar: androidx.appcompat.widget.Toolbar
private lateinit var titleText: TextView
private lateinit var listExplorer: ListView
private lateinit var refresher: SwipeRefreshLayout
private lateinit var textDirEmpty: TextView
private lateinit var currentPathText: TextView
private lateinit var totalSizeText: TextView
2020-07-17 16:35:39 +02:00
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
usf_open = sharedPrefs.getBoolean("usf_open", false)
usf_keep_open = sharedPrefs.getBoolean("usf_keep_open", false)
volumeName = intent.getStringExtra("volume_name") ?: ""
2020-07-17 16:35:39 +02:00
val sessionID = intent.getIntExtra("sessionID", -1)
gocryptfsVolume = GocryptfsVolume(sessionID)
2020-08-04 11:44:29 +02:00
sortOrderEntries = resources.getStringArray(R.array.sort_orders_entries)
sortOrderValues = resources.getStringArray(R.array.sort_orders_values)
foldersFirst = sharedPrefs.getBoolean("folders_first", true)
2021-07-10 12:02:56 +02:00
mapFolders = sharedPrefs.getBoolean("map_folders", true)
2020-08-04 11:44:29 +02:00
currentSortOrderIndex = resources.getStringArray(R.array.sort_orders_values).indexOf(sharedPrefs.getString(ConstValues.sort_order_key, "name"))
2020-07-17 16:35:39 +02:00
init()
2021-06-11 20:23:54 +02:00
toolbar = findViewById(R.id.toolbar)
titleText = findViewById(R.id.title_text)
listExplorer = findViewById(R.id.list_explorer)
refresher = findViewById(R.id.refresher)
textDirEmpty = findViewById(R.id.text_dir_empty)
currentPathText = findViewById(R.id.current_path_text)
totalSizeText = findViewById(R.id.total_size_text)
2020-07-17 16:35:39 +02:00
setSupportActionBar(toolbar)
title = ""
2021-06-11 20:23:54 +02:00
titleText.text = getString(R.string.volume, volumeName)
explorerAdapter = ExplorerElementAdapter(this)
2020-08-04 11:44:29 +02:00
explorerViewModel= ViewModelProvider(this).get(ExplorerViewModel::class.java)
currentDirectoryPath = explorerViewModel.currentDirectoryPath
setCurrentPath(currentDirectoryPath)
2021-06-11 20:23:54 +02:00
listExplorer.apply {
adapter = explorerAdapter
onItemClickListener = OnItemClickListener { _, _, position, _ -> onExplorerItemClick(position) }
onItemLongClickListener = OnItemLongClickListener { _, _, position, _ -> onExplorerItemLongClick(position); true }
}
2020-07-17 16:35:39 +02:00
refresher.setOnRefreshListener {
setCurrentPath(currentDirectoryPath)
2020-07-17 16:35:39 +02:00
refresher.isRefreshing = false
}
2020-12-29 17:05:02 +01:00
bindFileOperationService()
2020-07-17 16:35:39 +02:00
}
2020-08-04 11:44:29 +02:00
class ExplorerViewModel: ViewModel() {
var currentDirectoryPath = ""
}
2020-07-17 16:35:39 +02:00
protected open fun init() {
2020-07-19 21:46:29 +02:00
setContentView(R.layout.activity_explorer_base)
2020-07-17 16:35:39 +02:00
}
2020-12-29 17:05:02 +01:00
protected open fun bindFileOperationService(){
Intent(this, FileOperationService::class.java).also {
bindService(it, object : ServiceConnection {
override fun onServiceConnected(className: ComponentName, service: IBinder) {
val binder = service as FileOperationService.LocalBinder
fileOperationService = binder.getService()
binder.setGocryptfsVolume(gocryptfsVolume)
}
override fun onServiceDisconnected(arg0: ComponentName) {
}
}, Context.BIND_AUTO_CREATE)
}
}
2021-03-17 21:11:14 +01:00
private fun startFileViewer(cls: Class<*>, filePath: String){
val intent = Intent(this, cls).apply {
putExtra("path", filePath)
putExtra("sessionID", gocryptfsVolume.sessionID)
putExtra("sortOrder", sortOrderValues[currentSortOrderIndex])
2020-08-04 11:44:29 +02:00
}
isStartingActivity = true
2020-07-17 16:35:39 +02:00
startActivity(intent)
}
2020-09-05 11:37:47 +02:00
private fun openWithExternalApp(fullPath: String){
isStartingActivity = true
ExternalProvider.open(this, gocryptfsVolume, fullPath)
}
2020-07-17 16:35:39 +02:00
protected open fun onExplorerItemClick(position: Int) {
val wasSelecting = explorerAdapter.selectedItems.isNotEmpty()
explorerAdapter.onItemClick(position)
if (explorerAdapter.selectedItems.isEmpty()) {
2020-07-17 16:35:39 +02:00
if (!wasSelecting) {
2020-08-05 14:06:54 +02:00
val fullPath = explorerElements[position].fullPath
2020-07-17 16:35:39 +02:00
when {
explorerElements[position].isDirectory -> {
setCurrentPath(fullPath)
2020-07-17 16:35:39 +02:00
}
explorerElements[position].isParentFolder -> {
setCurrentPath(PathUtils.getParentPath(currentDirectoryPath))
2020-07-17 16:35:39 +02:00
}
isImage(fullPath) -> {
2021-03-17 21:11:14 +01:00
startFileViewer(ImageViewer::class.java, fullPath)
2020-07-17 16:35:39 +02:00
}
isVideo(fullPath) -> {
startFileViewer(VideoPlayer::class.java, fullPath)
2020-07-17 16:35:39 +02:00
}
isText(fullPath) -> {
startFileViewer(TextEditor::class.java, fullPath)
2020-07-17 16:35:39 +02:00
}
isAudio(fullPath) -> {
startFileViewer(AudioPlayer::class.java, fullPath)
2020-07-17 16:35:39 +02:00
}
else -> {
2020-09-05 11:37:47 +02:00
val adapter = OpenAsDialogAdapter(this, usf_open)
2020-07-27 16:20:52 +02:00
ColoredAlertDialogBuilder(this)
.setSingleChoiceItems(adapter, -1){ dialog, which ->
when (adapter.getItem(which)){
"image" -> startFileViewer(ImageViewer::class.java, fullPath)
"video" -> startFileViewer(VideoPlayer::class.java, fullPath)
"audio" -> startFileViewer(AudioPlayer::class.java, fullPath)
"text" -> startFileViewer(TextEditor::class.java, fullPath)
2020-09-05 11:37:47 +02:00
"external" -> if (usf_open){
openWithExternalApp(fullPath)
}
2020-07-27 16:20:52 +02:00
}
dialog.dismiss()
}
2020-07-17 16:35:39 +02:00
.setTitle(getString(R.string.open_as))
.setNegativeButton(R.string.cancel, null)
2020-07-27 16:20:52 +02:00
.show()
2020-07-17 16:35:39 +02:00
}
}
}
}
2020-08-29 20:48:12 +02:00
invalidateOptionsMenu()
}
protected open fun onExplorerItemLongClick(position: Int) {
explorerAdapter.onItemLongClick(position)
2020-07-17 16:35:39 +02:00
invalidateOptionsMenu()
}
2020-07-28 22:25:10 +02:00
protected fun unselectAll(){
explorerAdapter.unSelectAll()
invalidateOptionsMenu()
}
2020-07-18 18:44:53 +02:00
private fun sortExplorerElements() {
ExplorerElement.sortBy(sortOrderValues[currentSortOrderIndex], foldersFirst, explorerElements)
val sharedPrefsEditor = sharedPrefs.edit()
2020-08-04 11:44:29 +02:00
sharedPrefsEditor.putString(ConstValues.sort_order_key, sortOrderValues[currentSortOrderIndex])
sharedPrefsEditor.apply()
2020-07-17 16:35:39 +02:00
}
protected fun setCurrentPath(path: String) {
2021-06-26 12:09:29 +02:00
synchronized(this) {
explorerElements = gocryptfsVolume.listDir(path)
}
2021-06-11 20:23:54 +02:00
textDirEmpty.visibility = if (explorerElements.size == 0) View.VISIBLE else View.INVISIBLE
currentDirectoryPath = path
2021-06-11 20:23:54 +02:00
currentPathText.text = getString(R.string.location, currentDirectoryPath)
2020-08-05 14:06:54 +02:00
Thread{
2021-07-10 12:02:56 +02:00
val totalSizeValue = if (mapFolders) {
var totalSize: Long = 0
synchronized(this) {
for (element in explorerElements){
if (element.isDirectory){
var dirSize: Long = 0
for (subFile in gocryptfsVolume.recursiveMapFiles(element.fullPath)){
if (subFile.isRegularFile){
dirSize += subFile.size
}
2021-06-26 12:09:29 +02:00
}
2021-07-10 12:02:56 +02:00
element.size = dirSize
totalSize += dirSize
} else if (element.isRegularFile) {
totalSize += element.size
}
}
2020-08-05 14:06:54 +02:00
}
2021-07-10 12:02:56 +02:00
PathUtils.formatSize(totalSize)
} else {
getString(R.string.default_total_size)
2020-08-05 14:06:54 +02:00
}
2020-08-25 14:10:46 +02:00
runOnUiThread {
2021-07-10 12:02:56 +02:00
totalSizeText.text = getString(R.string.total_size, totalSizeValue)
2021-06-26 12:09:29 +02:00
synchronized(this) {
sortExplorerElements()
}
if (path.isNotEmpty()) { //not root
2021-06-26 12:09:29 +02:00
synchronized(this) {
explorerElements.add(
0,
ExplorerElement("..", (-1).toShort(), parentPath = currentDirectoryPath)
2021-06-26 12:09:29 +02:00
)
}
}
explorerAdapter.setExplorerElements(explorerElements)
2020-08-25 14:10:46 +02:00
}
2020-08-05 14:06:54 +02:00
}.start()
2020-07-17 16:35:39 +02:00
}
private fun askCloseVolume() {
2020-07-27 16:20:52 +02:00
ColoredAlertDialogBuilder(this)
2020-07-17 16:35:39 +02:00
.setTitle(R.string.warning)
.setMessage(R.string.ask_close_volume)
.setPositiveButton(R.string.ok) { _, _ -> closeVolumeOnUserExit() }
.setNegativeButton(R.string.cancel, null)
.show()
}
override fun onBackPressed() {
if (explorerAdapter.selectedItems.isEmpty()) {
val parentPath = PathUtils.getParentPath(currentDirectoryPath)
if (parentPath == currentDirectoryPath) {
2020-07-17 16:35:39 +02:00
askCloseVolume()
} else {
setCurrentPath(PathUtils.getParentPath(currentDirectoryPath))
2020-07-17 16:35:39 +02:00
}
} else {
2020-07-28 22:25:10 +02:00
unselectAll()
2020-07-17 16:35:39 +02:00
}
}
private fun createFolder(folderName: String){
if (folderName.isEmpty()) {
2020-07-17 16:35:39 +02:00
Toast.makeText(this, R.string.error_filename_empty, Toast.LENGTH_SHORT).show()
} else {
if (!gocryptfsVolume.mkdir(PathUtils.pathJoin(currentDirectoryPath, folderName))) {
2020-07-27 16:20:52 +02:00
ColoredAlertDialogBuilder(this)
2020-07-17 16:35:39 +02:00
.setTitle(R.string.error)
.setMessage(R.string.error_mkdir)
.setPositiveButton(R.string.ok, null)
.show()
} else {
setCurrentPath(currentDirectoryPath)
2020-07-17 16:35:39 +02:00
invalidateOptionsMenu()
}
}
}
2020-08-05 14:06:54 +02:00
protected fun openDialogCreateFolder() {
2020-07-19 21:46:29 +02:00
val dialogEditTextView = layoutInflater.inflate(R.layout.dialog_edit_text, null)
val dialogEditText = dialogEditTextView.findViewById<EditText>(R.id.dialog_edit_text)
2020-07-27 16:20:52 +02:00
val dialog = ColoredAlertDialogBuilder(this)
2020-07-19 21:46:29 +02:00
.setView(dialogEditTextView)
2020-07-17 16:35:39 +02:00
.setTitle(R.string.enter_folder_name)
.setPositiveButton(R.string.ok) { _, _ ->
2020-07-19 21:46:29 +02:00
val folderName = dialogEditText.text.toString()
createFolder(folderName)
2020-07-17 16:35:39 +02:00
}
.setNegativeButton(R.string.cancel, null)
.create()
2020-07-19 21:46:29 +02:00
dialogEditText.setOnEditorActionListener { _, _, _ ->
val folderName = dialogEditText.text.toString()
2020-07-17 16:35:39 +02:00
dialog.dismiss()
2020-07-19 21:46:29 +02:00
createFolder(folderName)
2020-07-17 16:35:39 +02:00
true
}
dialog.window?.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE)
dialog.show()
}
2020-12-29 17:05:02 +01:00
protected fun checkPathOverwrite(items: ArrayList<OperationFile>, dstDirectoryPath: String, callback: (ArrayList<OperationFile>?) -> Unit) {
val srcDirectoryPath = items[0].explorerElement.parentPath
var ready = true
for (i in 0 until items.size) {
val testDstPath: String
if (items[i].dstPath == null){
testDstPath = PathUtils.pathJoin(dstDirectoryPath, PathUtils.getRelativePath(srcDirectoryPath, items[i].explorerElement.fullPath))
if (gocryptfsVolume.pathExists(testDstPath)){
ready = false
} else {
items[i].dstPath = testDstPath
}
} else {
testDstPath = items[i].dstPath!!
if (gocryptfsVolume.pathExists(testDstPath) && !items[i].overwriteConfirmed){
ready = false
}
}
2020-12-29 17:05:02 +01:00
if (!ready){
ColoredAlertDialogBuilder(this)
.setTitle(R.string.warning)
2020-12-29 17:05:02 +01:00
.setMessage(getString(if (items[i].explorerElement.isDirectory){R.string.dir_overwrite_question} else {R.string.file_overwrite_question}, testDstPath))
.setPositiveButton(R.string.yes) {_, _ ->
items[i].dstPath = testDstPath
items[i].overwriteConfirmed = true
checkPathOverwrite(items, dstDirectoryPath, callback)
}
.setNegativeButton(R.string.no) { _, _ ->
val dialogEditTextView = layoutInflater.inflate(R.layout.dialog_edit_text, null)
val dialogEditText = dialogEditTextView.findViewById<EditText>(R.id.dialog_edit_text)
2020-12-29 17:05:02 +01:00
dialogEditText.setText(items[i].explorerElement.name)
dialogEditText.selectAll()
val dialog = ColoredAlertDialogBuilder(this)
2020-12-29 17:05:02 +01:00
.setView(dialogEditTextView)
.setTitle(R.string.enter_new_name)
.setPositiveButton(R.string.ok) { _, _ ->
items[i].dstPath = PathUtils.pathJoin(dstDirectoryPath, PathUtils.getRelativePath(srcDirectoryPath, items[i].explorerElement.parentPath), dialogEditText.text.toString())
if (items[i].explorerElement.isDirectory){
for (j in 0 until items.size){
if (PathUtils.isChildOf(items[j].explorerElement.fullPath, items[i].explorerElement.fullPath)){
items[j].dstPath = PathUtils.pathJoin(items[i].dstPath!!, PathUtils.getRelativePath(items[i].explorerElement.fullPath, items[j].explorerElement.fullPath))
}
}
}
2020-12-29 17:05:02 +01:00
checkPathOverwrite(items, dstDirectoryPath, callback)
}
.setOnCancelListener{
callback(null)
}
.create()
dialogEditText.setOnEditorActionListener { _, _, _ ->
dialog.dismiss()
2020-12-29 17:05:02 +01:00
items[i].dstPath = PathUtils.pathJoin(dstDirectoryPath, PathUtils.getRelativePath(srcDirectoryPath, items[i].explorerElement.parentPath), dialogEditText.text.toString())
checkPathOverwrite(items, dstDirectoryPath, callback)
true
}
dialog.window?.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE)
dialog.show()
}
2020-12-29 17:05:02 +01:00
.setOnCancelListener{
callback(null)
}
.show()
break
}
}
2020-12-29 17:05:02 +01:00
if (ready){
callback(items)
}
}
2020-12-29 17:05:02 +01:00
protected fun importFilesFromUris(uris: List<Uri>, callback: (String?) -> Unit) {
val items = ArrayList<OperationFile>()
2020-11-03 17:22:09 +01:00
for (uri in uris) {
2020-12-29 17:05:02 +01:00
val fileName = PathUtils.getFilenameFromURI(this, uri)
if (fileName == null) {
ColoredAlertDialogBuilder(this)
2020-11-03 17:22:09 +01:00
.setTitle(R.string.error)
.setMessage(getString(R.string.error_retrieving_filename, uri))
.setPositiveButton(R.string.ok, null)
.show()
2020-12-29 17:05:02 +01:00
items.clear()
2020-11-03 17:22:09 +01:00
break
} else {
items.add(OperationFile.fromExplorerElement(ExplorerElement(fileName, 1, parentPath = currentDirectoryPath)))
2020-12-29 17:05:02 +01:00
}
}
if (items.size > 0) {
checkPathOverwrite(items, currentDirectoryPath) { checkedItems ->
checkedItems?.let {
fileOperationService.importFilesFromUris(checkedItems.map { it.dstPath!! }, uris){ failedItem ->
2020-12-29 17:05:02 +01:00
runOnUiThread {
callback(failedItem)
2020-11-03 17:22:09 +01:00
}
}
}
}
}
}
2021-08-27 19:47:35 +02:00
fun importDirectory(sourceUri: Uri, callback: (String?, List<Uri>, DocumentFile) -> Unit) {
val tree = DocumentFile.fromTreeUri(this, sourceUri)!! //non-null after Lollipop
val operation = OperationFile.fromExplorerElement(ExplorerElement(tree.name!!, 0, parentPath = currentDirectoryPath))
checkPathOverwrite(arrayListOf(operation), currentDirectoryPath) { checkedOperation ->
checkedOperation?.let {
fileOperationService.importDirectory(checkedOperation[0].dstPath!!, tree) { failedItem, uris ->
runOnUiThread {
2021-08-27 19:47:35 +02:00
callback(failedItem, uris, tree)
}
}
}
}
}
2020-08-05 14:06:54 +02:00
protected fun rename(old_name: String, new_name: String){
2020-07-17 16:35:39 +02:00
if (new_name.isEmpty()) {
Toast.makeText(this, R.string.error_filename_empty, Toast.LENGTH_SHORT).show()
} else {
2020-11-03 17:22:09 +01:00
if (!gocryptfsVolume.rename(PathUtils.pathJoin(currentDirectoryPath, old_name), PathUtils.pathJoin(currentDirectoryPath, new_name))) {
2020-07-27 16:20:52 +02:00
ColoredAlertDialogBuilder(this)
2020-07-17 16:35:39 +02:00
.setTitle(R.string.error)
.setMessage(getString(R.string.rename_failed, old_name))
.setPositiveButton(R.string.ok, null)
.show()
} else {
setCurrentPath(currentDirectoryPath)
2020-07-17 16:35:39 +02:00
invalidateOptionsMenu()
}
}
}
2020-08-05 14:06:54 +02:00
protected fun handleMenuItems(menu: Menu){
menu.findItem(R.id.rename).isVisible = false
2020-07-17 16:35:39 +02:00
if (usf_open){
menu.findItem(R.id.external_open)?.isVisible = false
2020-07-17 16:35:39 +02:00
}
val noItemSelected = explorerAdapter.selectedItems.isEmpty()
menu.findItem(R.id.sort).isVisible = noItemSelected
menu.findItem(R.id.close).isVisible = noItemSelected
if (noItemSelected){
2020-07-17 16:35:39 +02:00
toolbar.navigationIcon = null
} else {
toolbar.setNavigationIcon(R.drawable.icon_arrow_back)
if (explorerAdapter.selectedItems.size == 1) {
menu.findItem(R.id.rename).isVisible = true
if (usf_open && explorerElements[explorerAdapter.selectedItems[0]].isRegularFile) {
menu.findItem(R.id.external_open)?.isVisible = true
2020-07-17 16:35:39 +02:00
}
}
}
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
return when (item.itemId) {
android.R.id.home -> {
2020-07-28 22:25:10 +02:00
unselectAll()
2020-07-17 16:35:39 +02:00
true
}
R.id.sort -> {
2020-07-27 16:20:52 +02:00
ColoredAlertDialogBuilder(this)
2020-07-17 16:35:39 +02:00
.setTitle(R.string.sort_order)
.setSingleChoiceItems(DialogSingleChoiceAdapter(this, sortOrderEntries.toList()), currentSortOrderIndex) { dialog, which ->
2020-08-04 11:44:29 +02:00
currentSortOrderIndex = which
setCurrentPath(currentDirectoryPath)
2020-07-17 16:35:39 +02:00
dialog.dismiss()
2020-07-27 16:20:52 +02:00
}
2020-12-19 19:55:54 +01:00
.setNegativeButton(R.string.cancel, null)
2020-07-27 16:20:52 +02:00
.show()
2020-07-17 16:35:39 +02:00
true
}
R.id.rename -> {
val dialogEditTextView = layoutInflater.inflate(R.layout.dialog_edit_text, null)
val oldName = explorerElements[explorerAdapter.selectedItems[0]].name
val dialogEditText = dialogEditTextView.findViewById<EditText>(R.id.dialog_edit_text)
dialogEditText.setText(oldName)
dialogEditText.selectAll()
2020-07-27 16:20:52 +02:00
val dialog = ColoredAlertDialogBuilder(this)
.setView(dialogEditTextView)
2020-07-17 16:35:39 +02:00
.setTitle(R.string.rename_title)
.setPositiveButton(R.string.ok) { _, _ ->
val newName = dialogEditText.text.toString()
rename(oldName, newName)
2020-07-17 16:35:39 +02:00
}
.setNegativeButton(R.string.cancel, null)
.create()
dialogEditText.setOnEditorActionListener { _, _, _ ->
val newName = dialogEditText.text.toString()
2020-07-17 16:35:39 +02:00
dialog.dismiss()
rename(oldName, newName)
2020-07-17 16:35:39 +02:00
true
}
dialog.window?.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE)
dialog.show()
true
}
R.id.external_open -> {
2020-07-17 16:35:39 +02:00
if (usf_open){
2020-11-03 17:22:09 +01:00
openWithExternalApp(PathUtils.pathJoin(currentDirectoryPath, explorerElements[explorerAdapter.selectedItems[0]].name))
2020-07-28 22:25:10 +02:00
unselectAll()
2020-07-17 16:35:39 +02:00
}
true
}
R.id.close -> {
2020-07-17 16:35:39 +02:00
askCloseVolume()
true
}
else -> super.onOptionsItemSelected(item)
}
}
protected open fun closeVolumeOnUserExit() {
finish()
}
protected open fun closeVolumeOnDestroy() {
if (!gocryptfsVolume.isClosed()){
gocryptfsVolume.close()
}
RestrictedFileProvider.wipeAll(this) //additional security
}
2020-07-17 16:35:39 +02:00
override fun onDestroy() {
super.onDestroy()
if (!isChangingConfigurations) { //activity won't be recreated
closeVolumeOnDestroy()
}
}
override fun onPause() {
super.onPause()
2020-08-29 20:48:12 +02:00
if (!isChangingConfigurations){
if (isStartingActivity){
isStartingActivity = false
} else if (!usf_keep_open){
2020-08-29 20:48:12 +02:00
finish()
}
}
}
2020-07-17 16:35:39 +02:00
override fun onResume() {
super.onResume()
2020-08-05 14:06:54 +02:00
if (isCreating){
isCreating = false
} else {
if (gocryptfsVolume.isClosed()){
finish()
} else {
isStartingActivity = false
ExternalProvider.removeFiles(this)
2020-12-20 12:27:48 +01:00
setCurrentPath(currentDirectoryPath)
}
2020-08-05 14:06:54 +02:00
}
2020-07-17 16:35:39 +02:00
}
}