mirror of
https://github.com/SimpleMobileTools/Simple-Notes.git
synced 2025-02-09 07:58:51 +01:00
adding the undo/redo functionality
This commit is contained in:
parent
48f31b8d83
commit
2c3a6937a7
@ -132,6 +132,8 @@ class MainActivity : SimpleActivity(), ViewPager.OnPageChangeListener {
|
||||
when (item.itemId) {
|
||||
R.id.open_note -> displayOpenNoteDialog()
|
||||
R.id.save_note -> saveNote()
|
||||
R.id.undo -> undo()
|
||||
R.id.redo -> redo()
|
||||
R.id.new_note -> displayNewNoteDialog()
|
||||
R.id.rename_note -> displayRenameDialog()
|
||||
R.id.share -> shareText()
|
||||
@ -287,11 +289,11 @@ class MainActivity : SimpleActivity(), ViewPager.OnPageChangeListener {
|
||||
|
||||
private fun openFile() {
|
||||
FilePickerDialog(this) {
|
||||
openFile(it, true, {
|
||||
openFile(it, true) {
|
||||
OpenFileDialog(this, it.path) {
|
||||
addNewNote(it)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -524,6 +526,14 @@ class MainActivity : SimpleActivity(), ViewPager.OnPageChangeListener {
|
||||
invalidateOptionsMenu()
|
||||
}
|
||||
|
||||
private fun undo() {
|
||||
mAdapter?.undo(view_pager.currentItem)
|
||||
}
|
||||
|
||||
private fun redo() {
|
||||
mAdapter?.redo(view_pager.currentItem)
|
||||
}
|
||||
|
||||
private fun getNoteIndexWithId(id: Int): Int {
|
||||
for (i in 0 until mNotes.count()) {
|
||||
if (mNotes[i].id == id) {
|
||||
|
@ -42,6 +42,10 @@ class NotesPagerAdapter(fm: FragmentManager, val notes: List<Note>, val activity
|
||||
|
||||
fun focusEditText(position: Int) = fragments[position]?.focusEditText()
|
||||
|
||||
fun undo(position: Int) = fragments[position]?.undo()
|
||||
|
||||
fun redo(position: Int) = fragments[position]?.redo()
|
||||
|
||||
override fun finishUpdate(container: ViewGroup) {
|
||||
try {
|
||||
super.finishUpdate(container)
|
||||
|
@ -4,7 +4,9 @@ import android.graphics.Typeface
|
||||
import android.os.Bundle
|
||||
import android.support.v4.app.Fragment
|
||||
import android.text.Editable
|
||||
import android.text.Selection
|
||||
import android.text.TextWatcher
|
||||
import android.text.style.UnderlineSpan
|
||||
import android.text.util.Linkify
|
||||
import android.util.TypedValue
|
||||
import android.view.Gravity
|
||||
@ -22,12 +24,18 @@ import com.simplemobiletools.notes.extensions.getTextSize
|
||||
import com.simplemobiletools.notes.extensions.updateWidget
|
||||
import com.simplemobiletools.notes.helpers.*
|
||||
import com.simplemobiletools.notes.models.Note
|
||||
import com.simplemobiletools.notes.models.TextHistory
|
||||
import com.simplemobiletools.notes.models.TextHistoryItem
|
||||
import kotlinx.android.synthetic.main.fragment_note.*
|
||||
import kotlinx.android.synthetic.main.fragment_note.view.*
|
||||
import kotlinx.android.synthetic.main.note_view_horiz_scrollable.view.*
|
||||
import java.io.File
|
||||
|
||||
// text history handling taken from https://gist.github.com/zeleven/0cfa738c1e8b65b23ff7df1fc30c9f7e
|
||||
class NoteFragment : Fragment() {
|
||||
private var textHistory = TextHistory()
|
||||
|
||||
private var isUndoOrRedo = false
|
||||
private var noteId = 0
|
||||
lateinit var note: Note
|
||||
lateinit var view: ViewGroup
|
||||
@ -161,11 +169,69 @@ class NoteFragment : Fragment() {
|
||||
notes_counter.text = words.count { it.isNotEmpty() }.toString()
|
||||
}
|
||||
|
||||
private var textWatcher: TextWatcher = object : TextWatcher {
|
||||
override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {
|
||||
fun undo() {
|
||||
val edit = textHistory.getPrevious() ?: return
|
||||
|
||||
val text = view.notes_view.editableText
|
||||
val start = edit.start
|
||||
val end = start + if (edit.after != null) edit.after.length else 0
|
||||
|
||||
isUndoOrRedo = true
|
||||
text.replace(start, end, edit.before)
|
||||
isUndoOrRedo = false
|
||||
|
||||
for (span in text.getSpans(0, text.length, UnderlineSpan::class.java)) {
|
||||
text.removeSpan(span)
|
||||
}
|
||||
|
||||
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
|
||||
Selection.setSelection(text, if (edit.before == null) {
|
||||
start
|
||||
} else {
|
||||
start + edit.before.length
|
||||
})
|
||||
}
|
||||
|
||||
fun redo() {
|
||||
val edit = textHistory.getNext() ?: return
|
||||
|
||||
val text = view.notes_view.editableText
|
||||
val start = edit.start
|
||||
val end = start + if (edit.before != null) edit.before.length else 0
|
||||
|
||||
isUndoOrRedo = true
|
||||
text.replace(start, end, edit.after)
|
||||
isUndoOrRedo = false
|
||||
|
||||
for (o in text.getSpans(0, text.length, UnderlineSpan::class.java)) {
|
||||
text.removeSpan(o)
|
||||
}
|
||||
|
||||
Selection.setSelection(text, if (edit.after == null) {
|
||||
start
|
||||
} else {
|
||||
start + edit.after.length
|
||||
})
|
||||
}
|
||||
|
||||
fun isUndoAvailable() = textHistory.position > 0
|
||||
|
||||
fun isRedoAvailable() = textHistory.position < textHistory.history.size
|
||||
|
||||
private var textWatcher: TextWatcher = object : TextWatcher {
|
||||
private var beforeChange: CharSequence? = null
|
||||
private var afterChange: CharSequence? = null
|
||||
|
||||
override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {
|
||||
if (!isUndoOrRedo) {
|
||||
beforeChange = s.subSequence(start, start + count)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {
|
||||
if (!isUndoOrRedo) {
|
||||
afterChange = s.subSequence(start, start + count)
|
||||
textHistory.add(TextHistoryItem(start, beforeChange!!, afterChange!!))
|
||||
}
|
||||
}
|
||||
|
||||
override fun afterTextChanged(editable: Editable) {
|
||||
|
@ -0,0 +1,35 @@
|
||||
package com.simplemobiletools.notes.models
|
||||
|
||||
import java.util.*
|
||||
|
||||
class TextHistory {
|
||||
var position = 0
|
||||
val history = LinkedList<TextHistoryItem>()
|
||||
|
||||
fun getPrevious(): TextHistoryItem? {
|
||||
if (position == 0) {
|
||||
return null
|
||||
}
|
||||
position--
|
||||
return history[position]
|
||||
}
|
||||
|
||||
fun getNext(): TextHistoryItem? {
|
||||
if (position >= history.size) {
|
||||
return null
|
||||
}
|
||||
|
||||
val item = history[position]
|
||||
position++
|
||||
return item
|
||||
}
|
||||
|
||||
fun add(item: TextHistoryItem) {
|
||||
while (history.size > position) {
|
||||
history.removeLast()
|
||||
}
|
||||
|
||||
history.add(item)
|
||||
position++
|
||||
}
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
package com.simplemobiletools.notes.models
|
||||
|
||||
data class TextHistoryItem(val start: Int, val before: CharSequence?, val after: CharSequence?)
|
Loading…
x
Reference in New Issue
Block a user