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

628 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
2022-04-09 15:09:14 +02:00
import android.widget.ImageButton
2021-06-11 20:23:54 +02:00
import android.widget.TextView
2020-07-17 16:35:39 +02:00
import android.widget.Toast
2021-11-09 11:12:09 +01:00
import androidx.core.content.ContextCompat
2020-08-04 11:44:29 +02:00
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
2022-04-20 15:17:33 +02:00
import androidx.lifecycle.lifecycleScope
2022-04-09 15:09:14 +02:00
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
2021-06-11 20:23:54 +02:00
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
2022-04-20 15:17:33 +02:00
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
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
2022-03-23 16:35:13 +01:00
import sushi.hardcore.droidfs.ConstValues.isAudio
import sushi.hardcore.droidfs.ConstValues.isImage
import sushi.hardcore.droidfs.ConstValues.isPDF
import sushi.hardcore.droidfs.ConstValues.isText
import sushi.hardcore.droidfs.ConstValues.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
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
2022-02-18 15:53:48 +01:00
import sushi.hardcore.droidfs.file_viewers.*
2020-08-05 14:06:54 +02:00
import sushi.hardcore.droidfs.util.PathUtils
2021-11-09 11:12:09 +01:00
import sushi.hardcore.droidfs.widgets.CustomAlertDialogBuilder
2022-03-24 20:08:23 +01:00
import sushi.hardcore.droidfs.widgets.EditTextDialog
2020-07-17 16:35:39 +02:00
2022-04-17 15:52:34 +02:00
open class BaseExplorerActivity : BaseActivity(), ExplorerElementAdapter.Listener {
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
2022-04-09 15:09:14 +02:00
private lateinit var linearLayoutManager: LinearLayoutManager
private var isUsingListLayout = true
private lateinit var layoutIcon: ImageButton
2021-06-11 20:23:54 +02:00
private lateinit var titleText: TextView
private lateinit var recycler_view_explorer: RecyclerView
2021-06-11 20:23:54 +02:00
private lateinit var refresher: SwipeRefreshLayout
private lateinit var textDirEmpty: TextView
private lateinit var currentPathText: TextView
private lateinit var numberOfFilesText: TextView
private lateinit var numberOfFoldersText: TextView
2021-06-11 20:23:54 +02:00
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)
2021-11-11 15:05:33 +01:00
gocryptfsVolume = GocryptfsVolume(applicationContext, 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)
2022-03-23 16:35:13 +01: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()
recycler_view_explorer = findViewById(R.id.recycler_view_explorer)
2021-06-11 20:23:54 +02:00
refresher = findViewById(R.id.refresher)
textDirEmpty = findViewById(R.id.text_dir_empty)
currentPathText = findViewById(R.id.current_path_text)
numberOfFilesText = findViewById(R.id.number_of_files_text)
numberOfFoldersText = findViewById(R.id.number_of_folders_text)
2021-06-11 20:23:54 +02:00
totalSizeText = findViewById(R.id.total_size_text)
2022-03-05 12:51:02 +01:00
supportActionBar?.apply {
setDisplayShowCustomEnabled(true)
setCustomView(R.layout.action_bar)
titleText = customView.findViewById(R.id.title_text)
}
2020-07-17 16:35:39 +02:00
title = ""
2022-04-17 15:52:34 +02:00
setVolumeNameTitle()
2021-11-11 15:05:33 +01:00
explorerAdapter = ExplorerElementAdapter(
this,
if (sharedPrefs.getBoolean("thumbnails", true)) {
gocryptfsVolume
} else {
null
},
2022-04-17 15:52:34 +02:00
this,
2022-03-23 16:35:13 +01:00
sharedPrefs.getLong(ConstValues.THUMBNAIL_MAX_SIZE_KEY, ConstValues.DEFAULT_THUMBNAIL_MAX_SIZE)*1000,
2021-11-11 15:05:33 +01:00
)
2022-04-09 15:09:14 +02:00
explorerViewModel = ViewModelProvider(this).get(ExplorerViewModel::class.java)
2020-08-04 11:44:29 +02:00
currentDirectoryPath = explorerViewModel.currentDirectoryPath
setCurrentPath(currentDirectoryPath)
2022-04-09 15:09:14 +02:00
linearLayoutManager = LinearLayoutManager(this@BaseExplorerActivity)
recycler_view_explorer.adapter = explorerAdapter
isUsingListLayout = sharedPrefs.getBoolean("useListLayout", true)
layoutIcon = findViewById(R.id.layout_icon)
setRecyclerViewLayout()
layoutIcon.setOnClickListener {
isUsingListLayout = !isUsingListLayout
setRecyclerViewLayout()
recycler_view_explorer.recycledViewPool.clear()
with (sharedPrefs.edit()) {
putBoolean("useListLayout", isUsingListLayout)
apply()
}
2021-06-11 20:23:54 +02:00
}
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 = ""
}
2022-04-09 15:09:14 +02:00
private fun setRecyclerViewLayout() {
layoutIcon.setImageResource(if (isUsingListLayout) {
recycler_view_explorer.layoutManager = linearLayoutManager
explorerAdapter.isUsingListLayout = true
R.drawable.icon_view_grid
2022-04-09 15:09:14 +02:00
} else {
val displayMetrics = resources.displayMetrics
val columnsNumber = (displayMetrics.widthPixels / displayMetrics.density / 200 + 0.5).toInt()
recycler_view_explorer.layoutManager = GridLayoutManager(this, columnsNumber)
explorerAdapter.isUsingListLayout = false
R.drawable.icon_view_list
2022-04-09 15:09:14 +02:00
})
}
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
2021-11-09 11:12:09 +01:00
ExternalProvider.open(this, themeValue, gocryptfsVolume, fullPath)
2020-09-05 11:37:47 +02:00
}
2021-10-19 11:24:20 +02:00
private fun showOpenAsDialog(path: String) {
val adapter = OpenAsDialogAdapter(this, usf_open)
2021-11-09 11:12:09 +01:00
CustomAlertDialogBuilder(this, themeValue)
2021-10-19 11:24:20 +02:00
.setSingleChoiceItems(adapter, -1) { dialog, which ->
when (adapter.getItem(which)) {
"image" -> startFileViewer(ImageViewer::class.java, path)
"video" -> startFileViewer(VideoPlayer::class.java, path)
"audio" -> startFileViewer(AudioPlayer::class.java, path)
2022-02-18 15:53:48 +01:00
"pdf" -> startFileViewer(PdfViewer::class.java, path)
2021-10-19 11:24:20 +02:00
"text" -> startFileViewer(TextEditor::class.java, path)
"external" -> if (usf_open) {
openWithExternalApp(path)
}
}
dialog.dismiss()
}
.setTitle(getString(R.string.open_as) + ':')
.setNegativeButton(R.string.cancel, null)
.show()
}
2022-04-17 15:52:34 +02:00
private fun setVolumeNameTitle() {
titleText.text = getString(R.string.volume, volumeName)
}
override fun onSelectionChanged(size: Int) {
if (size == 0) {
setVolumeNameTitle()
} else {
titleText.text = getString(R.string.elements_selected, size, explorerElements.count { !it.isParentFolder })
}
}
override fun onExplorerElementClick(position: Int) {
if (explorerAdapter.selectedItems.isEmpty()) {
2022-03-05 12:51:02 +01:00
val fullPath = explorerElements[position].fullPath
when {
explorerElements[position].isDirectory -> {
setCurrentPath(fullPath)
2020-07-17 16:35:39 +02:00
}
2022-03-05 12:51:02 +01:00
explorerElements[position].isParentFolder -> {
setCurrentPath(PathUtils.getParentPath(currentDirectoryPath))
}
isImage(fullPath) -> {
startFileViewer(ImageViewer::class.java, fullPath)
}
isVideo(fullPath) -> {
startFileViewer(VideoPlayer::class.java, fullPath)
}
isText(fullPath) -> {
startFileViewer(TextEditor::class.java, fullPath)
}
isPDF(fullPath) -> {
startFileViewer(PdfViewer::class.java, fullPath)
}
isAudio(fullPath) -> {
startFileViewer(AudioPlayer::class.java, fullPath)
}
else -> showOpenAsDialog(fullPath)
2020-07-17 16:35:39 +02:00
}
}
2020-08-29 20:48:12 +02:00
invalidateOptionsMenu()
}
2022-04-17 15:52:34 +02:00
override fun onExplorerElementLongClick(position: Int) {
2020-07-17 16:35:39 +02:00
invalidateOptionsMenu()
}
protected fun unselectAll(notifyChange: Boolean = true) {
explorerAdapter.unSelectAll(notifyChange)
2020-07-28 22:25:10 +02:00
invalidateOptionsMenu()
}
private fun displayExplorerElements(totalSize: Long) {
totalSizeText.text = getString(R.string.total_size, PathUtils.formatSize(totalSize))
2021-11-11 20:14:48 +01:00
synchronized(this) {
ExplorerElement.sortBy(sortOrderValues[currentSortOrderIndex], foldersFirst, explorerElements)
}
unselectAll(false)
2021-11-11 20:14:48 +01:00
explorerAdapter.explorerElements = explorerElements
val sharedPrefsEditor = sharedPrefs.edit()
2022-03-23 16:35:13 +01:00
sharedPrefsEditor.putString(ConstValues.SORT_ORDER_KEY, sortOrderValues[currentSortOrderIndex])
sharedPrefsEditor.apply()
2020-07-17 16:35:39 +02:00
}
2022-03-06 14:59:45 +01:00
private fun recursiveSetSize(directory: ExplorerElement) {
for (child in gocryptfsVolume.listDir(directory.fullPath)) {
if (child.isDirectory) {
recursiveSetSize(child)
}
directory.size += child.size
}
}
private fun displayNumberOfElements(textView: TextView, stringIdSingular: Int, stringIdPlural: Int, count: Int) {
with(textView) {
visibility = if (count == 0) {
View.GONE
} else {
text = if (count == 1) {
getString(stringIdSingular)
} else {
getString(stringIdPlural, count)
}
View.VISIBLE
}
}
}
2021-11-11 20:14:48 +01:00
protected fun setCurrentPath(path: String, onDisplayed: (() -> Unit)? = null) {
2021-06-26 12:09:29 +02:00
synchronized(this) {
explorerElements = gocryptfsVolume.listDir(path)
2021-11-11 20:14:48 +01:00
if (path.isNotEmpty()) { //not root
explorerElements.add(
0,
ExplorerElement("..", (-1).toShort(), parentPath = currentDirectoryPath)
)
}
2021-06-26 12:09:29 +02:00
}
2022-03-05 12:51:02 +01:00
textDirEmpty.visibility = if (explorerElements.size == 0) View.VISIBLE else View.GONE
currentDirectoryPath = path
2021-06-11 20:23:54 +02:00
currentPathText.text = getString(R.string.location, currentDirectoryPath)
displayNumberOfElements(numberOfFilesText, R.string.one_file, R.string.multiple_files, explorerElements.count { it.isRegularFile })
displayNumberOfElements(numberOfFoldersText, R.string.one_folder, R.string.multiple_folders, explorerElements.count { it.isDirectory })
2021-11-11 20:14:48 +01:00
if (mapFolders) {
2022-04-20 15:17:33 +02:00
lifecycleScope.launch {
2021-07-10 12:02:56 +02:00
var totalSize: Long = 0
2022-04-20 15:17:33 +02:00
withContext(Dispatchers.IO) {
synchronized(this@BaseExplorerActivity) {
for (element in explorerElements) {
if (element.isDirectory) {
recursiveSetSize(element)
}
totalSize += element.size
}
}
2020-08-05 14:06:54 +02:00
}
2022-04-20 15:17:33 +02:00
displayExplorerElements(totalSize)
onDisplayed?.invoke()
}
2021-11-11 20:14:48 +01:00
} else {
displayExplorerElements(explorerElements.filter { !it.isParentFolder }.sumOf { it.size })
2021-11-11 20:14:48 +01:00
onDisplayed?.invoke()
}
2020-07-17 16:35:39 +02:00
}
private fun askCloseVolume() {
2021-11-09 11:12:09 +01:00
CustomAlertDialogBuilder(this, themeValue)
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))) {
2021-11-09 11:12:09 +01:00
CustomAlertDialogBuilder(this, themeValue)
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() {
2022-03-24 20:08:23 +01:00
EditTextDialog(this, R.string.enter_folder_name) {
createFolder(it)
}.show()
2020-07-17 16:35:39 +02:00
}
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){
2021-11-09 11:12:09 +01:00
CustomAlertDialogBuilder(this, themeValue)
.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) { _, _ ->
2022-03-24 20:08:23 +01:00
with(EditTextDialog(this, R.string.enter_new_name) {
items[i].dstPath = PathUtils.pathJoin(dstDirectoryPath, PathUtils.getRelativePath(srcDirectoryPath, items[i].explorerElement.parentPath), it)
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
}
2022-03-24 20:08:23 +01:00
}
2020-12-29 17:05:02 +01:00
checkPathOverwrite(items, dstDirectoryPath, callback)
2022-03-24 20:08:23 +01:00
}) {
setSelectedText(items[i].explorerElement.name)
2022-03-24 20:08:23 +01:00
setOnCancelListener{
callback(null)
}
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) {
2021-11-09 11:12:09 +01:00
CustomAlertDialogBuilder(this, themeValue)
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 {
2022-04-20 15:17:33 +02:00
lifecycleScope.launch {
val taskResult = fileOperationService.importFilesFromUris(checkedItems.map { it.dstPath!! }, uris)
if (taskResult.cancelled) {
setCurrentPath(currentDirectoryPath)
} else {
callback(taskResult.failedItem)
2020-11-03 17:22:09 +01:00
}
}
}
}
}
}
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))) {
2021-11-09 11:12:09 +01:00
CustomAlertDialogBuilder(this, themeValue)
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 {
2021-11-11 20:14:48 +01:00
setCurrentPath(currentDirectoryPath) {
invalidateOptionsMenu()
}
2020-07-17 16:35:39 +02:00
}
}
}
2021-11-09 11:12:09 +01:00
private fun setMenuIconTint(menu: Menu, iconColor: Int, menuItemId: Int, drawableId: Int) {
menu.findItem(menuItemId)?.let {
it.icon = ContextCompat.getDrawable(this, drawableId)?.apply {
setTint(iconColor)
}
}
}
2020-08-05 14:06:54 +02:00
protected fun handleMenuItems(menu: Menu){
menu.findItem(R.id.rename).isVisible = false
2021-10-19 11:24:20 +02:00
menu.findItem(R.id.open_as)?.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()
val iconColor = ContextCompat.getColor(this, R.color.neutralIconTint)
2021-11-09 11:12:09 +01:00
setMenuIconTint(menu, iconColor, R.id.sort, R.drawable.icon_sort)
setMenuIconTint(menu, iconColor, R.id.decrypt, R.drawable.icon_decrypt)
setMenuIconTint(menu, iconColor, R.id.share, R.drawable.icon_share)
menu.findItem(R.id.sort).isVisible = noItemSelected
menu.findItem(R.id.close).isVisible = noItemSelected
2022-03-05 12:51:02 +01:00
supportActionBar?.setDisplayHomeAsUpEnabled(!noItemSelected)
if (!noItemSelected) {
if (explorerAdapter.selectedItems.size == 1) {
menu.findItem(R.id.rename).isVisible = true
if (explorerElements[explorerAdapter.selectedItems.first()].isRegularFile) {
2021-10-19 11:24:20 +02:00
menu.findItem(R.id.open_as)?.isVisible = true
if (usf_open) {
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 -> {
2021-11-09 11:12:09 +01:00
CustomAlertDialogBuilder(this, themeValue)
2020-07-17 16:35:39 +02:00
.setTitle(R.string.sort_order)
2022-01-18 20:42:13 +01:00
.setSingleChoiceItems(sortOrderEntries, 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 oldName = explorerElements[explorerAdapter.selectedItems.first()].name
2022-03-24 20:08:23 +01:00
with(EditTextDialog(this, R.string.rename_title) {
rename(oldName, it)
}) {
setSelectedText(oldName)
2022-03-24 20:08:23 +01:00
show()
2020-07-17 16:35:39 +02:00
}
true
}
2021-10-19 11:24:20 +02:00
R.id.open_as -> {
showOpenAsDialog(
PathUtils.pathJoin(
currentDirectoryPath,
explorerElements[explorerAdapter.selectedItems.first()].name
)
)
2021-10-19 11:24:20 +02:00
true
}
R.id.external_open -> {
2020-07-17 16:35:39 +02:00
if (usf_open){
openWithExternalApp(
PathUtils.pathJoin(
currentDirectoryPath,
explorerElements[explorerAdapter.selectedItems.first()].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
2022-04-20 15:17:33 +02:00
ExternalProvider.removeFilesAsync(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
}
}