DroidFS/app/src/main/java/sushi/hardcore/droidfs/file_viewers/TextEditor.kt

147 lines
5.1 KiB
Kotlin
Raw Normal View History

2020-07-17 16:35:39 +02:00
package sushi.hardcore.droidfs.file_viewers
import android.text.Editable
import android.text.TextWatcher
import android.view.Menu
import android.view.MenuItem
import android.widget.EditText
import android.widget.TextView
import android.widget.Toast
import androidx.appcompat.widget.Toolbar
import sushi.hardcore.droidfs.R
import sushi.hardcore.droidfs.util.GocryptfsVolume
2020-07-27 16:20:52 +02:00
import sushi.hardcore.droidfs.widgets.ColoredAlertDialogBuilder
2020-07-17 16:35:39 +02:00
import java.io.ByteArrayInputStream
import java.io.File
class TextEditor: FileViewerActivity() {
private lateinit var fileName: String
private lateinit var editor: EditText
private lateinit var toolbar: Toolbar
private lateinit var titleText: TextView
private var changedSinceLastSave = false
private var wordWrap = true
override fun hideSystemUi() {
//don't hide system ui
2020-07-17 16:35:39 +02:00
}
override fun viewFile() {
loadWholeFile(filePath)?.let {
fileName = File(filePath).name
try {
loadLayout(String(it))
} catch (e: OutOfMemoryError){
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.outofmemoryerror_msg)
2020-07-17 16:35:39 +02:00
.setCancelable(false)
.setPositiveButton(getString(R.string.ok)) { _, _ -> goBackToExplorer()}
2020-07-17 16:35:39 +02:00
.show()
}
}
}
private fun loadLayout(fileContent: String){
if (wordWrap){
setContentView(R.layout.activity_text_editor_wrap)
} else {
setContentView(R.layout.activity_text_editor)
}
toolbar = findViewById(R.id.toolbar)
setSupportActionBar(toolbar)
title = ""
titleText = findViewById(R.id.title_text)
titleText.text = fileName
editor = findViewById(R.id.text_editor)
editor.setText(fileContent)
editor.addTextChangedListener(object: TextWatcher {
override fun afterTextChanged(s: Editable?) {
}
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
if (!changedSinceLastSave){
changedSinceLastSave = true
titleText.text = "*$fileName"
}
}
})
}
private fun save(): Boolean{
var success = false
val content = editor.text.toString().toByteArray()
2020-08-01 16:43:48 +02:00
val handleID = gocryptfsVolume.openWriteMode(filePath)
2020-07-17 16:35:39 +02:00
if (handleID != -1){
val buff = ByteArrayInputStream(content)
var offset: Long = 0
val io_buffer = ByteArray(GocryptfsVolume.DefaultBS)
var length: Int
while (buff.read(io_buffer).also { length = it } > 0) {
2020-08-01 16:43:48 +02:00
val written = gocryptfsVolume.writeFile(handleID, offset, io_buffer, length).toLong()
2020-07-17 16:35:39 +02:00
if (written == length.toLong()) {
offset += written
} else {
break
}
}
if (offset == content.size.toLong()){
success = gocryptfsVolume.truncate(filePath, offset)
}
2020-08-01 16:43:48 +02:00
gocryptfsVolume.closeFile(handleID)
2020-07-17 16:35:39 +02:00
buff.close()
}
if (success){
Toast.makeText(this, getString(R.string.file_saved), Toast.LENGTH_SHORT).show()
} else {
Toast.makeText(this, getString(R.string.save_failed), Toast.LENGTH_SHORT).show()
}
return success
}
private fun checkSaveAndExit(){
if (changedSinceLastSave){
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_save)
2020-07-17 16:35:39 +02:00
.setPositiveButton(getString(R.string.save)) { _, _ ->
if (save()){
goBackToExplorer()
2020-07-17 16:35:39 +02:00
}
}
.setNegativeButton(getString(R.string.discard)){ _, _ -> goBackToExplorer()}
2020-07-17 16:35:39 +02:00
.show()
} else {
goBackToExplorer()
2020-07-17 16:35:39 +02:00
}
}
override fun onCreateOptionsMenu(menu: Menu): Boolean {
menuInflater.inflate(R.menu.text_editor, menu)
toolbar.setNavigationIcon(R.drawable.icon_arrow_back)
menu.findItem(R.id.word_wrap).isChecked = wordWrap
return true
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
when (item.itemId){
android.R.id.home -> {
checkSaveAndExit()
}
R.id.menu_save -> {
if (save()){
changedSinceLastSave = false
titleText.text = fileName
}
}
R.id.word_wrap -> {
wordWrap = !item.isChecked
loadLayout(editor.text.toString())
invalidateOptionsMenu()
}
else -> super.onOptionsItemSelected(item)
}
return true
}
override fun onBackPressed() {
checkSaveAndExit()
}
}