mirror of
https://github.com/SimpleMobileTools/Simple-Notes.git
synced 2025-03-20 10:30:07 +01:00
Merge pull request #644 from Merkost/migration_settings
Notes import/export moved to settings
This commit is contained in:
commit
6c7d3aa0cd
@ -1,7 +1,10 @@
|
|||||||
apply plugin: 'com.android.application'
|
plugins {
|
||||||
apply plugin: 'kotlin-android'
|
id 'com.android.application'
|
||||||
apply plugin: 'kotlin-android-extensions'
|
id 'kotlin-android'
|
||||||
apply plugin: 'kotlin-kapt'
|
id 'kotlin-android-extensions'
|
||||||
|
id 'kotlin-kapt'
|
||||||
|
id 'org.jetbrains.kotlin.plugin.serialization' version "$kotlin_version"
|
||||||
|
}
|
||||||
|
|
||||||
def keystorePropertiesFile = rootProject.file("keystore.properties")
|
def keystorePropertiesFile = rootProject.file("keystore.properties")
|
||||||
def keystoreProperties = new Properties()
|
def keystoreProperties = new Properties()
|
||||||
@ -10,7 +13,7 @@ if (keystorePropertiesFile.exists()) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
android {
|
android {
|
||||||
compileSdkVersion 33
|
compileSdk 33
|
||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
applicationId "com.simplemobiletools.notes.pro"
|
applicationId "com.simplemobiletools.notes.pro"
|
||||||
@ -70,4 +73,6 @@ dependencies {
|
|||||||
kapt 'androidx.room:room-compiler:2.5.1'
|
kapt 'androidx.room:room-compiler:2.5.1'
|
||||||
implementation 'androidx.room:room-runtime:2.5.1'
|
implementation 'androidx.room:room-runtime:2.5.1'
|
||||||
annotationProcessor 'androidx.room:room-compiler:2.5.1'
|
annotationProcessor 'androidx.room:room-compiler:2.5.1'
|
||||||
|
|
||||||
|
implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:1.4.1"
|
||||||
}
|
}
|
||||||
|
24
app/proguard-rules.pro
vendored
24
app/proguard-rules.pro
vendored
@ -1,3 +1,27 @@
|
|||||||
-keep class com.simplemobiletools.notes.pro.models.* {
|
-keep class com.simplemobiletools.notes.pro.models.* {
|
||||||
<fields>;
|
<fields>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Keep `Companion` object fields of serializable classes.
|
||||||
|
# This avoids serializer lookup through `getDeclaredClasses` as done for named companion objects.
|
||||||
|
-if @kotlinx.serialization.Serializable class **
|
||||||
|
-keepclassmembers class <1> {
|
||||||
|
static <1>$Companion Companion;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Keep `serializer()` on companion objects (both default and named) of serializable classes.
|
||||||
|
-if @kotlinx.serialization.Serializable class ** {
|
||||||
|
static **$* *;
|
||||||
|
}
|
||||||
|
-keepclassmembers class <2>$<3> {
|
||||||
|
kotlinx.serialization.KSerializer serializer(...);
|
||||||
|
}
|
||||||
|
|
||||||
|
# Keep `INSTANCE.serializer()` of serializable objects.
|
||||||
|
-if @kotlinx.serialization.Serializable class ** {
|
||||||
|
public static ** INSTANCE;
|
||||||
|
}
|
||||||
|
-keepclassmembers class <1> {
|
||||||
|
public static <1> INSTANCE;
|
||||||
|
kotlinx.serialization.KSerializer serializer(...);
|
||||||
|
}
|
||||||
|
@ -43,13 +43,11 @@ import com.simplemobiletools.notes.pro.dialogs.*
|
|||||||
import com.simplemobiletools.notes.pro.extensions.*
|
import com.simplemobiletools.notes.pro.extensions.*
|
||||||
import com.simplemobiletools.notes.pro.fragments.TextFragment
|
import com.simplemobiletools.notes.pro.fragments.TextFragment
|
||||||
import com.simplemobiletools.notes.pro.helpers.*
|
import com.simplemobiletools.notes.pro.helpers.*
|
||||||
import com.simplemobiletools.notes.pro.helpers.NotesImporter.ImportResult
|
|
||||||
import com.simplemobiletools.notes.pro.models.Note
|
import com.simplemobiletools.notes.pro.models.Note
|
||||||
|
import com.simplemobiletools.notes.pro.models.NoteType
|
||||||
import kotlinx.android.synthetic.main.activity_main.*
|
import kotlinx.android.synthetic.main.activity_main.*
|
||||||
import kotlinx.android.synthetic.main.item_checklist.*
|
import kotlinx.android.synthetic.main.item_checklist.*
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.io.FileOutputStream
|
|
||||||
import java.io.OutputStream
|
|
||||||
import java.nio.charset.Charset
|
import java.nio.charset.Charset
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
@ -63,11 +61,8 @@ class MainActivity : SimpleActivity() {
|
|||||||
private val PICK_OPEN_FILE_INTENT = 1
|
private val PICK_OPEN_FILE_INTENT = 1
|
||||||
private val PICK_EXPORT_FILE_INTENT = 2
|
private val PICK_EXPORT_FILE_INTENT = 2
|
||||||
|
|
||||||
private val PICK_IMPORT_NOTES_INTENT = 3
|
|
||||||
private val PICK_EXPORT_NOTES_INTENT = 4
|
|
||||||
|
|
||||||
private lateinit var mCurrentNote: Note
|
private lateinit var mCurrentNote: Note
|
||||||
private var mNotes = ArrayList<Note>()
|
private var mNotes = listOf<Note>()
|
||||||
private var mAdapter: NotesPagerAdapter? = null
|
private var mAdapter: NotesPagerAdapter? = null
|
||||||
private var noteViewWithTextSelected: MyEditText? = null
|
private var noteViewWithTextSelected: MyEditText? = null
|
||||||
private var saveNoteButton: MenuItem? = null
|
private var saveNoteButton: MenuItem? = null
|
||||||
@ -132,6 +127,12 @@ class MainActivity : SimpleActivity() {
|
|||||||
initViewPager()
|
initViewPager()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NotesHelper(this).getNotes { lastestNotes ->
|
||||||
|
if (mNotes.size != lastestNotes.size) {
|
||||||
|
initViewPager()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
refreshMenuItems()
|
refreshMenuItems()
|
||||||
pager_tab_strip.apply {
|
pager_tab_strip.apply {
|
||||||
setTextSize(TypedValue.COMPLEX_UNIT_PX, getPercentageFontSize())
|
setTextSize(TypedValue.COMPLEX_UNIT_PX, getPercentageFontSize())
|
||||||
@ -171,31 +172,29 @@ class MainActivity : SimpleActivity() {
|
|||||||
|
|
||||||
main_toolbar.menu.apply {
|
main_toolbar.menu.apply {
|
||||||
findItem(R.id.undo).apply {
|
findItem(R.id.undo).apply {
|
||||||
isVisible = showUndoButton && mCurrentNote.type == NoteType.TYPE_TEXT.value
|
isVisible = showUndoButton && mCurrentNote.type == NoteType.TYPE_TEXT
|
||||||
icon?.alpha = if (isEnabled) 255 else 127
|
icon?.alpha = if (isEnabled) 255 else 127
|
||||||
}
|
}
|
||||||
|
|
||||||
findItem(R.id.redo).apply {
|
findItem(R.id.redo).apply {
|
||||||
isVisible = showRedoButton && mCurrentNote.type == NoteType.TYPE_TEXT.value
|
isVisible = showRedoButton && mCurrentNote.type == NoteType.TYPE_TEXT
|
||||||
icon?.alpha = if (isEnabled) 255 else 127
|
icon?.alpha = if (isEnabled) 255 else 127
|
||||||
}
|
}
|
||||||
|
|
||||||
findItem(R.id.rename_note).isVisible = multipleNotesExist
|
findItem(R.id.rename_note).isVisible = multipleNotesExist
|
||||||
findItem(R.id.open_note).isVisible = multipleNotesExist
|
findItem(R.id.open_note).isVisible = multipleNotesExist
|
||||||
findItem(R.id.delete_note).isVisible = multipleNotesExist
|
findItem(R.id.delete_note).isVisible = multipleNotesExist
|
||||||
findItem(R.id.export_all_notes).isVisible = multipleNotesExist
|
|
||||||
findItem(R.id.open_search).isVisible = !isCurrentItemChecklist
|
findItem(R.id.open_search).isVisible = !isCurrentItemChecklist
|
||||||
findItem(R.id.remove_done_items).isVisible = isCurrentItemChecklist
|
findItem(R.id.remove_done_items).isVisible = isCurrentItemChecklist
|
||||||
findItem(R.id.sort_checklist).isVisible = isCurrentItemChecklist
|
findItem(R.id.sort_checklist).isVisible = isCurrentItemChecklist
|
||||||
findItem(R.id.import_folder).isVisible = !isQPlus()
|
findItem(R.id.import_folder).isVisible = !isQPlus()
|
||||||
findItem(R.id.import_notes).isVisible = isQPlus()
|
|
||||||
findItem(R.id.lock_note).isVisible = mNotes.isNotEmpty() && (::mCurrentNote.isInitialized && !mCurrentNote.isLocked())
|
findItem(R.id.lock_note).isVisible = mNotes.isNotEmpty() && (::mCurrentNote.isInitialized && !mCurrentNote.isLocked())
|
||||||
findItem(R.id.unlock_note).isVisible = mNotes.isNotEmpty() && (::mCurrentNote.isInitialized && mCurrentNote.isLocked())
|
findItem(R.id.unlock_note).isVisible = mNotes.isNotEmpty() && (::mCurrentNote.isInitialized && mCurrentNote.isLocked())
|
||||||
findItem(R.id.more_apps_from_us).isVisible = !resources.getBoolean(R.bool.hide_google_relations)
|
findItem(R.id.more_apps_from_us).isVisible = !resources.getBoolean(R.bool.hide_google_relations)
|
||||||
|
|
||||||
saveNoteButton = findItem(R.id.save_note)
|
saveNoteButton = findItem(R.id.save_note)
|
||||||
saveNoteButton!!.isVisible =
|
saveNoteButton!!.isVisible =
|
||||||
!config.autosaveNotes && showSaveButton && (::mCurrentNote.isInitialized && mCurrentNote.type == NoteType.TYPE_TEXT.value)
|
!config.autosaveNotes && showSaveButton && (::mCurrentNote.isInitialized && mCurrentNote.type == NoteType.TYPE_TEXT)
|
||||||
}
|
}
|
||||||
|
|
||||||
pager_tab_strip.beVisibleIf(multipleNotesExist)
|
pager_tab_strip.beVisibleIf(multipleNotesExist)
|
||||||
@ -223,8 +222,6 @@ class MainActivity : SimpleActivity() {
|
|||||||
R.id.open_file -> tryOpenFile()
|
R.id.open_file -> tryOpenFile()
|
||||||
R.id.import_folder -> openFolder()
|
R.id.import_folder -> openFolder()
|
||||||
R.id.export_as_file -> fragment?.handleUnlocking { tryExportAsFile() }
|
R.id.export_as_file -> fragment?.handleUnlocking { tryExportAsFile() }
|
||||||
R.id.export_all_notes -> tryExportNotes()
|
|
||||||
R.id.import_notes -> tryImportNotes()
|
|
||||||
R.id.print -> fragment?.handleUnlocking { printText() }
|
R.id.print -> fragment?.handleUnlocking { printText() }
|
||||||
R.id.delete_note -> fragment?.handleUnlocking { displayDeleteNotePrompt() }
|
R.id.delete_note -> fragment?.handleUnlocking { displayDeleteNotePrompt() }
|
||||||
R.id.more_apps_from_us -> launchMoreAppsFromUsIntent()
|
R.id.more_apps_from_us -> launchMoreAppsFromUsIntent()
|
||||||
@ -288,15 +285,10 @@ class MainActivity : SimpleActivity() {
|
|||||||
val takeFlags = Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION
|
val takeFlags = Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION
|
||||||
applicationContext.contentResolver.takePersistableUriPermission(resultData.data!!, takeFlags)
|
applicationContext.contentResolver.takePersistableUriPermission(resultData.data!!, takeFlags)
|
||||||
showExportFilePickUpdateDialog(resultData.dataString!!, getCurrentNoteValue())
|
showExportFilePickUpdateDialog(resultData.dataString!!, getCurrentNoteValue())
|
||||||
} else if (requestCode == PICK_EXPORT_NOTES_INTENT && resultCode == Activity.RESULT_OK && resultData != null && resultData.data != null) {
|
|
||||||
val outputStream = contentResolver.openOutputStream(resultData.data!!)
|
|
||||||
exportNotesTo(outputStream)
|
|
||||||
} else if (requestCode == PICK_IMPORT_NOTES_INTENT && resultCode == Activity.RESULT_OK && resultData != null && resultData.data != null) {
|
|
||||||
tryImportingAsJson(resultData.data!!)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun isCurrentItemChecklist() = if (::mCurrentNote.isInitialized) mCurrentNote.type == NoteType.TYPE_CHECKLIST.value else false
|
private fun isCurrentItemChecklist() = if (::mCurrentNote.isInitialized) mCurrentNote.type == NoteType.TYPE_CHECKLIST else false
|
||||||
|
|
||||||
@SuppressLint("NewApi")
|
@SuppressLint("NewApi")
|
||||||
private fun checkShortcuts() {
|
private fun checkShortcuts() {
|
||||||
@ -368,10 +360,10 @@ class MainActivity : SimpleActivity() {
|
|||||||
val file = File(realPath)
|
val file = File(realPath)
|
||||||
handleUri(Uri.fromFile(file))
|
handleUri(Uri.fromFile(file))
|
||||||
} else if (intent.getBooleanExtra(NEW_TEXT_NOTE, false)) {
|
} else if (intent.getBooleanExtra(NEW_TEXT_NOTE, false)) {
|
||||||
val newTextNote = Note(null, getCurrentFormattedDateTime(), "", NoteType.TYPE_TEXT.value, "", PROTECTION_NONE, "")
|
val newTextNote = Note(null, getCurrentFormattedDateTime(), "", NoteType.TYPE_TEXT, "", PROTECTION_NONE, "")
|
||||||
addNewNote(newTextNote)
|
addNewNote(newTextNote)
|
||||||
} else if (intent.getBooleanExtra(NEW_CHECKLIST, false)) {
|
} else if (intent.getBooleanExtra(NEW_CHECKLIST, false)) {
|
||||||
val newChecklist = Note(null, getCurrentFormattedDateTime(), "", NoteType.TYPE_CHECKLIST.value, "", PROTECTION_NONE, "")
|
val newChecklist = Note(null, getCurrentFormattedDateTime(), "", NoteType.TYPE_CHECKLIST, "", PROTECTION_NONE, "")
|
||||||
addNewNote(newChecklist)
|
addNewNote(newChecklist)
|
||||||
} else {
|
} else {
|
||||||
handleUri(data!!)
|
handleUri(data!!)
|
||||||
@ -446,7 +438,7 @@ class MainActivity : SimpleActivity() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!config.showKeyboard || mCurrentNote.type == NoteType.TYPE_CHECKLIST.value) {
|
if (!config.showKeyboard || mCurrentNote.type == NoteType.TYPE_CHECKLIST) {
|
||||||
hideKeyboard()
|
hideKeyboard()
|
||||||
}
|
}
|
||||||
refreshMenuItems()
|
refreshMenuItems()
|
||||||
@ -678,7 +670,7 @@ class MainActivity : SimpleActivity() {
|
|||||||
val checklistItems = fileText.parseChecklistItems()
|
val checklistItems = fileText.parseChecklistItems()
|
||||||
if (checklistItems != null) {
|
if (checklistItems != null) {
|
||||||
val title = it.absolutePath.getFilenameFromPath().substringBeforeLast('.')
|
val title = it.absolutePath.getFilenameFromPath().substringBeforeLast('.')
|
||||||
val note = Note(null, title, fileText, NoteType.TYPE_CHECKLIST.value, "", PROTECTION_NONE, "")
|
val note = Note(null, title, fileText, NoteType.TYPE_CHECKLIST, "", PROTECTION_NONE, "")
|
||||||
runOnUiThread {
|
runOnUiThread {
|
||||||
OpenFileDialog(this, it.path) {
|
OpenFileDialog(this, it.path) {
|
||||||
displayNewNoteDialog(note.value, title = it.title, it.path, setChecklistAsDefault = true)
|
displayNewNoteDialog(note.value, title = it.title, it.path, setChecklistAsDefault = true)
|
||||||
@ -732,29 +724,23 @@ class MainActivity : SimpleActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun importUri(uri: Uri) {
|
private fun importUri(uri: Uri) {
|
||||||
tryImportingAsJson(uri, force = true, showToasts = false) { success ->
|
when (uri.scheme) {
|
||||||
if (success) {
|
"file" -> openPath(uri.path!!)
|
||||||
return@tryImportingAsJson
|
"content" -> {
|
||||||
}
|
val realPath = getRealPathFromURI(uri)
|
||||||
|
if (hasPermission(PERMISSION_READ_STORAGE)) {
|
||||||
when (uri.scheme) {
|
if (realPath != null) {
|
||||||
"file" -> openPath(uri.path!!)
|
openPath(realPath)
|
||||||
"content" -> {
|
|
||||||
val realPath = getRealPathFromURI(uri)
|
|
||||||
if (hasPermission(PERMISSION_READ_STORAGE)) {
|
|
||||||
if (realPath != null) {
|
|
||||||
openPath(realPath)
|
|
||||||
} else {
|
|
||||||
R.string.unknown_error_occurred
|
|
||||||
}
|
|
||||||
} else if (realPath != null && realPath != "") {
|
|
||||||
checkFile(realPath, false) {
|
|
||||||
addNoteFromUri(uri, realPath.getFilenameFromPath())
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
checkUri(uri) {
|
R.string.unknown_error_occurred
|
||||||
addNoteFromUri(uri)
|
}
|
||||||
}
|
} else if (realPath != null && realPath != "") {
|
||||||
|
checkFile(realPath, false) {
|
||||||
|
addNoteFromUri(uri, realPath.getFilenameFromPath())
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
checkUri(uri) {
|
||||||
|
addNoteFromUri(uri)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -786,7 +772,7 @@ class MainActivity : SimpleActivity() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val noteType = if (checklistItems != null) NoteType.TYPE_CHECKLIST.value else NoteType.TYPE_TEXT.value
|
val noteType = if (checklistItems != null) NoteType.TYPE_CHECKLIST else NoteType.TYPE_TEXT
|
||||||
if (!canSyncNoteWithFile) {
|
if (!canSyncNoteWithFile) {
|
||||||
val note = Note(null, noteTitle, content, noteType, "", PROTECTION_NONE, "")
|
val note = Note(null, noteTitle, content, noteType, "", PROTECTION_NONE, "")
|
||||||
displayNewNoteDialog(note.value, title = noteTitle, "")
|
displayNewNoteDialog(note.value, title = noteTitle, "")
|
||||||
@ -812,9 +798,9 @@ class MainActivity : SimpleActivity() {
|
|||||||
val fileText = it.readText().trim()
|
val fileText = it.readText().trim()
|
||||||
val checklistItems = fileText.parseChecklistItems()
|
val checklistItems = fileText.parseChecklistItems()
|
||||||
val note = if (checklistItems != null) {
|
val note = if (checklistItems != null) {
|
||||||
Note(null, title.substringBeforeLast('.'), fileText, NoteType.TYPE_CHECKLIST.value, "", PROTECTION_NONE, "")
|
Note(null, title.substringBeforeLast('.'), fileText, NoteType.TYPE_CHECKLIST, "", PROTECTION_NONE, "")
|
||||||
} else {
|
} else {
|
||||||
Note(null, title, "", NoteType.TYPE_TEXT.value, path, PROTECTION_NONE, "")
|
Note(null, title, "", NoteType.TYPE_TEXT, path, PROTECTION_NONE, "")
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mNotes.any { it.title.equals(note.title, true) }) {
|
if (mNotes.any { it.title.equals(note.title, true) }) {
|
||||||
@ -885,10 +871,10 @@ class MainActivity : SimpleActivity() {
|
|||||||
|
|
||||||
private fun exportAsFile() {
|
private fun exportAsFile() {
|
||||||
ExportFileDialog(this, mCurrentNote) {
|
ExportFileDialog(this, mCurrentNote) {
|
||||||
val textToExport = if (mCurrentNote.type == NoteType.TYPE_TEXT.value) getCurrentNoteText() else mCurrentNote.value
|
val textToExport = if (mCurrentNote.type == NoteType.TYPE_TEXT) getCurrentNoteText() else mCurrentNote.value
|
||||||
if (textToExport == null || textToExport.isEmpty()) {
|
if (textToExport == null || textToExport.isEmpty()) {
|
||||||
toast(R.string.unknown_error_occurred)
|
toast(R.string.unknown_error_occurred)
|
||||||
} else if (mCurrentNote.type == NoteType.TYPE_TEXT.value) {
|
} else if (mCurrentNote.type == NoteType.TYPE_TEXT) {
|
||||||
showExportFilePickUpdateDialog(it, textToExport)
|
showExportFilePickUpdateDialog(it, textToExport)
|
||||||
} else {
|
} else {
|
||||||
tryExportNoteValueToFile(it, mCurrentNote.title, textToExport, true)
|
tryExportNoteValueToFile(it, mCurrentNote.title, textToExport, true)
|
||||||
@ -896,138 +882,6 @@ class MainActivity : SimpleActivity() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun tryExportNotes() {
|
|
||||||
if (isQPlus()) {
|
|
||||||
hideKeyboard()
|
|
||||||
val fileName = "${getString(R.string.notes)}_${getCurrentFormattedDateTime()}"
|
|
||||||
Intent(Intent.ACTION_CREATE_DOCUMENT).apply {
|
|
||||||
type = EXPORT_MIME_TYPE
|
|
||||||
putExtra(Intent.EXTRA_TITLE, fileName)
|
|
||||||
addCategory(Intent.CATEGORY_OPENABLE)
|
|
||||||
|
|
||||||
try {
|
|
||||||
startActivityForResult(this, PICK_EXPORT_NOTES_INTENT)
|
|
||||||
} catch (e: ActivityNotFoundException) {
|
|
||||||
toast(R.string.system_service_disabled, Toast.LENGTH_LONG)
|
|
||||||
} catch (e: Exception) {
|
|
||||||
showErrorToast(e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
tryExportAllNotesBelowQ()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun requestUnlockNotes(callback: (unlockedNoteIds: List<Long>) -> Unit) {
|
|
||||||
val lockedNotes = mNotes.filter { it.isLocked() }
|
|
||||||
if (lockedNotes.isNotEmpty()) {
|
|
||||||
runOnUiThread {
|
|
||||||
UnlockNotesDialog(this, lockedNotes, callback)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
callback(emptyList())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun exportNotesTo(outputStream: OutputStream?) {
|
|
||||||
ensureBackgroundThread {
|
|
||||||
NotesHelper(this).getNotes {
|
|
||||||
mNotes = it
|
|
||||||
requestUnlockNotes { unlockedNoteIds ->
|
|
||||||
toast(R.string.exporting)
|
|
||||||
val notesExporter = NotesExporter(this)
|
|
||||||
notesExporter.exportNotes(mNotes, unlockedNoteIds, outputStream) { result ->
|
|
||||||
val toastId = when (result) {
|
|
||||||
NotesExporter.ExportResult.EXPORT_OK -> R.string.exporting_successful
|
|
||||||
else -> R.string.exporting_failed
|
|
||||||
}
|
|
||||||
|
|
||||||
toast(toastId)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun tryImportNotes() {
|
|
||||||
hideKeyboard()
|
|
||||||
Intent(Intent.ACTION_GET_CONTENT).apply {
|
|
||||||
addCategory(Intent.CATEGORY_OPENABLE)
|
|
||||||
type = EXPORT_MIME_TYPE
|
|
||||||
|
|
||||||
try {
|
|
||||||
startActivityForResult(this, PICK_IMPORT_NOTES_INTENT)
|
|
||||||
} catch (e: ActivityNotFoundException) {
|
|
||||||
toast(R.string.system_service_disabled, Toast.LENGTH_LONG)
|
|
||||||
} catch (e: Exception) {
|
|
||||||
showErrorToast(e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun tryImportingAsJson(uri: Uri, force: Boolean = false, showToasts: Boolean = true, callback: ((success: Boolean) -> Unit)? = null) {
|
|
||||||
val path: String
|
|
||||||
val filename: String
|
|
||||||
when (uri.scheme) {
|
|
||||||
"file" -> {
|
|
||||||
path = uri.path!!
|
|
||||||
filename = path.getFilenameFromPath()
|
|
||||||
}
|
|
||||||
"content" -> {
|
|
||||||
val tempFile = getTempFile("messages", "backup.txt")
|
|
||||||
if (tempFile == null) {
|
|
||||||
maybeToast(R.string.unknown_error_occurred, showToasts)
|
|
||||||
callback?.invoke(false)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
filename = getFilenameFromUri(uri)
|
|
||||||
val inputStream = contentResolver.openInputStream(uri)
|
|
||||||
val out = FileOutputStream(tempFile)
|
|
||||||
inputStream!!.copyTo(out)
|
|
||||||
path = tempFile.absolutePath
|
|
||||||
} catch (e: Exception) {
|
|
||||||
showErrorToast(e)
|
|
||||||
callback?.invoke(false)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else -> {
|
|
||||||
maybeToast(R.string.invalid_file_format, showToasts)
|
|
||||||
callback?.invoke(false)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
maybeToast(R.string.importing, showToasts)
|
|
||||||
ensureBackgroundThread {
|
|
||||||
NotesImporter(this).importNotes(path, filename, force) { importResult ->
|
|
||||||
if (importResult == ImportResult.IMPORT_FAIL) {
|
|
||||||
maybeToast(R.string.no_new_items, showToasts)
|
|
||||||
runOnUiThread { callback?.invoke(false) }
|
|
||||||
return@importNotes
|
|
||||||
}
|
|
||||||
|
|
||||||
toast(
|
|
||||||
when (importResult) {
|
|
||||||
ImportResult.IMPORT_OK -> R.string.importing_successful
|
|
||||||
ImportResult.IMPORT_PARTIAL -> R.string.importing_some_entries_failed
|
|
||||||
else -> R.string.no_new_items
|
|
||||||
}
|
|
||||||
)
|
|
||||||
initViewPager()
|
|
||||||
runOnUiThread { callback?.invoke(true) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun maybeToast(id: Int, show: Boolean) {
|
|
||||||
if (show) {
|
|
||||||
toast(id)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun showExportFilePickUpdateDialog(exportPath: String, textToExport: String) {
|
private fun showExportFilePickUpdateDialog(exportPath: String, textToExport: String) {
|
||||||
val items = arrayListOf(
|
val items = arrayListOf(
|
||||||
RadioItem(EXPORT_FILE_SYNC, getString(R.string.update_file_at_note)),
|
RadioItem(EXPORT_FILE_SYNC, getString(R.string.update_file_at_note)),
|
||||||
@ -1053,73 +907,6 @@ class MainActivity : SimpleActivity() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun tryExportAllNotesBelowQ() {
|
|
||||||
handlePermission(PERMISSION_WRITE_STORAGE) {
|
|
||||||
if (it) {
|
|
||||||
exportAllNotesBelowQ()
|
|
||||||
} else {
|
|
||||||
toast(R.string.no_storage_permissions)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun exportAllNotesBelowQ() {
|
|
||||||
ensureBackgroundThread {
|
|
||||||
NotesHelper(this).getNotes { notes ->
|
|
||||||
mNotes = notes
|
|
||||||
requestUnlockNotes { unlockedNoteIds ->
|
|
||||||
ExportFilesDialog(this, mNotes) { parent, extension ->
|
|
||||||
val items = arrayListOf(
|
|
||||||
RadioItem(EXPORT_FILE_SYNC, getString(R.string.update_file_at_note)),
|
|
||||||
RadioItem(EXPORT_FILE_NO_SYNC, getString(R.string.only_export_file_content))
|
|
||||||
)
|
|
||||||
|
|
||||||
RadioGroupDialog(this, items) { any ->
|
|
||||||
val syncFile = any as Int == EXPORT_FILE_SYNC
|
|
||||||
var failCount = 0
|
|
||||||
mNotes.filter { !it.isLocked() || it.id in unlockedNoteIds }.forEachIndexed { index, note ->
|
|
||||||
val filename = if (extension.isEmpty()) note.title else "${note.title}.$extension"
|
|
||||||
val file = File(parent, filename)
|
|
||||||
if (!filename.isAValidFilename()) {
|
|
||||||
toast(String.format(getString(R.string.filename_invalid_characters_placeholder, filename)))
|
|
||||||
} else {
|
|
||||||
val noteStoredValue = note.getNoteStoredValue(this) ?: ""
|
|
||||||
tryExportNoteValueToFile(file.absolutePath, mCurrentNote.title, note.value, false) { exportedSuccessfully ->
|
|
||||||
if (exportedSuccessfully) {
|
|
||||||
if (syncFile) {
|
|
||||||
note.path = file.absolutePath
|
|
||||||
note.value = ""
|
|
||||||
} else {
|
|
||||||
note.path = ""
|
|
||||||
note.value = noteStoredValue
|
|
||||||
}
|
|
||||||
|
|
||||||
NotesHelper(this).insertOrUpdateNote(note)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mCurrentNote.id == note.id) {
|
|
||||||
mCurrentNote.value = note.value
|
|
||||||
mCurrentNote.path = note.path
|
|
||||||
getPagerAdapter().updateCurrentNoteData(view_pager.currentItem, mCurrentNote.path, mCurrentNote.value)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!exportedSuccessfully) {
|
|
||||||
failCount++
|
|
||||||
}
|
|
||||||
|
|
||||||
if (index == mNotes.size - 1) {
|
|
||||||
toast(if (failCount == 0) R.string.exporting_successful else R.string.exporting_some_entries_failed)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun tryExportNoteValueToFile(path: String, title: String, content: String, showSuccessToasts: Boolean, callback: ((success: Boolean) -> Unit)? = null) {
|
fun tryExportNoteValueToFile(path: String, title: String, content: String, showSuccessToasts: Boolean, callback: ((success: Boolean) -> Unit)? = null) {
|
||||||
if (path.startsWith("content://")) {
|
if (path.startsWith("content://")) {
|
||||||
exportNoteValueToUri(Uri.parse(path), title, content, showSuccessToasts, callback)
|
exportNoteValueToUri(Uri.parse(path), title, content, showSuccessToasts, callback)
|
||||||
@ -1238,7 +1025,7 @@ class MainActivity : SimpleActivity() {
|
|||||||
private fun getCurrentNoteText() = getPagerAdapter().getCurrentNoteViewText(view_pager.currentItem)
|
private fun getCurrentNoteText() = getPagerAdapter().getCurrentNoteViewText(view_pager.currentItem)
|
||||||
|
|
||||||
private fun getCurrentNoteValue(): String {
|
private fun getCurrentNoteValue(): String {
|
||||||
return if (mCurrentNote.type == NoteType.TYPE_TEXT.value) {
|
return if (mCurrentNote.type == NoteType.TYPE_TEXT) {
|
||||||
getCurrentNoteText() ?: ""
|
getCurrentNoteText() ?: ""
|
||||||
} else {
|
} else {
|
||||||
getPagerAdapter().getNoteChecklistItems(view_pager.currentItem) ?: ""
|
getPagerAdapter().getNoteChecklistItems(view_pager.currentItem) ?: ""
|
||||||
@ -1246,7 +1033,7 @@ class MainActivity : SimpleActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun getPrintableText(): String {
|
private fun getPrintableText(): String {
|
||||||
return if (mCurrentNote.type == NoteType.TYPE_TEXT.value) {
|
return if (mCurrentNote.type == NoteType.TYPE_TEXT) {
|
||||||
getCurrentNoteText() ?: ""
|
getCurrentNoteText() ?: ""
|
||||||
} else {
|
} else {
|
||||||
var printableText = ""
|
var printableText = ""
|
||||||
@ -1261,7 +1048,7 @@ class MainActivity : SimpleActivity() {
|
|||||||
|
|
||||||
private fun saveCurrentNote(force: Boolean) {
|
private fun saveCurrentNote(force: Boolean) {
|
||||||
getPagerAdapter().saveCurrentNote(view_pager.currentItem, force)
|
getPagerAdapter().saveCurrentNote(view_pager.currentItem, force)
|
||||||
if (mCurrentNote.type == NoteType.TYPE_CHECKLIST.value) {
|
if (mCurrentNote.type == NoteType.TYPE_CHECKLIST) {
|
||||||
mCurrentNote.value = getPagerAdapter().getNoteChecklistItems(view_pager.currentItem) ?: ""
|
mCurrentNote.value = getPagerAdapter().getNoteChecklistItems(view_pager.currentItem) ?: ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1359,8 +1146,8 @@ class MainActivity : SimpleActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun shareText() {
|
private fun shareText() {
|
||||||
val text = if (mCurrentNote.type == NoteType.TYPE_TEXT.value) getCurrentNoteText() else mCurrentNote.value
|
val text = if (mCurrentNote.type == NoteType.TYPE_TEXT) getCurrentNoteText() else mCurrentNote.value
|
||||||
if (text == null || text.isEmpty()) {
|
if (text.isNullOrEmpty()) {
|
||||||
toast(R.string.cannot_share_empty_text)
|
toast(R.string.cannot_share_empty_text)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -1,25 +1,33 @@
|
|||||||
package com.simplemobiletools.notes.pro.activities
|
package com.simplemobiletools.notes.pro.activities
|
||||||
|
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
|
import android.net.Uri
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.Menu
|
import android.view.Menu
|
||||||
|
import androidx.activity.result.contract.ActivityResultContracts
|
||||||
import com.simplemobiletools.commons.dialogs.RadioGroupDialog
|
import com.simplemobiletools.commons.dialogs.RadioGroupDialog
|
||||||
import com.simplemobiletools.commons.extensions.beVisibleIf
|
import com.simplemobiletools.commons.extensions.*
|
||||||
import com.simplemobiletools.commons.extensions.getProperPrimaryColor
|
|
||||||
import com.simplemobiletools.commons.extensions.updateTextColors
|
|
||||||
import com.simplemobiletools.commons.helpers.*
|
import com.simplemobiletools.commons.helpers.*
|
||||||
import com.simplemobiletools.commons.models.RadioItem
|
import com.simplemobiletools.commons.models.RadioItem
|
||||||
import com.simplemobiletools.notes.pro.R
|
import com.simplemobiletools.notes.pro.R
|
||||||
|
import com.simplemobiletools.notes.pro.dialogs.ExportNotesDialog
|
||||||
import com.simplemobiletools.notes.pro.extensions.config
|
import com.simplemobiletools.notes.pro.extensions.config
|
||||||
|
import com.simplemobiletools.notes.pro.extensions.requestUnlockNotes
|
||||||
import com.simplemobiletools.notes.pro.extensions.updateWidgets
|
import com.simplemobiletools.notes.pro.extensions.updateWidgets
|
||||||
import com.simplemobiletools.notes.pro.extensions.widgetsDB
|
import com.simplemobiletools.notes.pro.extensions.widgetsDB
|
||||||
import com.simplemobiletools.notes.pro.helpers.*
|
import com.simplemobiletools.notes.pro.helpers.*
|
||||||
|
import com.simplemobiletools.notes.pro.models.Note
|
||||||
import com.simplemobiletools.notes.pro.models.Widget
|
import com.simplemobiletools.notes.pro.models.Widget
|
||||||
import kotlinx.android.synthetic.main.activity_settings.*
|
import kotlinx.android.synthetic.main.activity_settings.*
|
||||||
import java.util.*
|
import kotlinx.serialization.SerializationException
|
||||||
|
import kotlinx.serialization.decodeFromString
|
||||||
|
import kotlinx.serialization.encodeToString
|
||||||
|
import kotlinx.serialization.json.Json
|
||||||
|
import java.util.Locale
|
||||||
import kotlin.system.exitProcess
|
import kotlin.system.exitProcess
|
||||||
|
|
||||||
class SettingsActivity : SimpleActivity() {
|
class SettingsActivity : SimpleActivity() {
|
||||||
|
private val notesFileType = "application/json"
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
isMaterialActivity = true
|
isMaterialActivity = true
|
||||||
@ -50,6 +58,8 @@ class SettingsActivity : SimpleActivity() {
|
|||||||
setupCursorPlacement()
|
setupCursorPlacement()
|
||||||
setupIncognitoMode()
|
setupIncognitoMode()
|
||||||
setupCustomizeWidgetColors()
|
setupCustomizeWidgetColors()
|
||||||
|
setupNotesExport()
|
||||||
|
setupNotesImport()
|
||||||
updateTextColors(settings_nested_scrollview)
|
updateTextColors(settings_nested_scrollview)
|
||||||
|
|
||||||
arrayOf(
|
arrayOf(
|
||||||
@ -57,7 +67,8 @@ class SettingsActivity : SimpleActivity() {
|
|||||||
settings_general_settings_label,
|
settings_general_settings_label,
|
||||||
settings_text_label,
|
settings_text_label,
|
||||||
settings_startup_label,
|
settings_startup_label,
|
||||||
settings_saving_label
|
settings_saving_label,
|
||||||
|
settings_migrating_label,
|
||||||
).forEach {
|
).forEach {
|
||||||
it.setTextColor(getProperPrimaryColor())
|
it.setTextColor(getProperPrimaryColor())
|
||||||
}
|
}
|
||||||
@ -68,6 +79,26 @@ class SettingsActivity : SimpleActivity() {
|
|||||||
return super.onCreateOptionsMenu(menu)
|
return super.onCreateOptionsMenu(menu)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private val getContent = registerForActivityResult(ActivityResultContracts.GetContent()) { uri ->
|
||||||
|
if (uri != null) {
|
||||||
|
toast(R.string.importing)
|
||||||
|
importNotes(uri)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private val saveDocument = registerForActivityResult(ActivityResultContracts.CreateDocument(notesFileType)) { uri ->
|
||||||
|
if (uri != null) {
|
||||||
|
toast(R.string.exporting)
|
||||||
|
NotesHelper(this).getNotes { notes ->
|
||||||
|
requestUnlockNotes(notes) { unlockedNotes ->
|
||||||
|
val notLockedNotes = notes.filterNot { it.isLocked() }
|
||||||
|
val notesToExport = unlockedNotes + notLockedNotes
|
||||||
|
exportNotes(notesToExport, uri)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun setupCustomizeColors() {
|
private fun setupCustomizeColors() {
|
||||||
settings_color_customization_holder.setOnClickListener {
|
settings_color_customization_holder.setOnClickListener {
|
||||||
startCustomizationActivity()
|
startCustomizationActivity()
|
||||||
@ -257,4 +288,63 @@ class SettingsActivity : SimpleActivity() {
|
|||||||
config.useIncognitoMode = settings_use_incognito_mode.isChecked
|
config.useIncognitoMode = settings_use_incognito_mode.isChecked
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun setupNotesExport() {
|
||||||
|
settings_export_notes_holder.setOnClickListener {
|
||||||
|
ExportNotesDialog(this) { filename ->
|
||||||
|
saveDocument.launch(filename)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun setupNotesImport() {
|
||||||
|
settings_import_notes_holder.setOnClickListener {
|
||||||
|
getContent.launch(notesFileType)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun exportNotes(notes: List<Note>, uri: Uri) {
|
||||||
|
if (notes.isEmpty()) {
|
||||||
|
toast(R.string.no_entries_for_exporting)
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
val outputStream = contentResolver.openOutputStream(uri)!!
|
||||||
|
|
||||||
|
val jsonString = Json.encodeToString(notes)
|
||||||
|
outputStream.use {
|
||||||
|
it.write(jsonString.toByteArray())
|
||||||
|
}
|
||||||
|
toast(R.string.exporting_successful)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
showErrorToast(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun importNotes(uri: Uri) {
|
||||||
|
try {
|
||||||
|
val jsonString = contentResolver.openInputStream(uri)!!.use { inputStream ->
|
||||||
|
inputStream.bufferedReader().readText()
|
||||||
|
}
|
||||||
|
val objects = Json.decodeFromString<List<Note>>(jsonString)
|
||||||
|
if (objects.isEmpty()) {
|
||||||
|
toast(R.string.no_entries_for_importing)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
NotesHelper(this).importNotes(this, objects) { importResult ->
|
||||||
|
when (importResult) {
|
||||||
|
NotesHelper.ImportResult.IMPORT_OK -> toast(R.string.importing_successful)
|
||||||
|
NotesHelper.ImportResult.IMPORT_PARTIAL -> toast(R.string.importing_some_entries_failed)
|
||||||
|
NotesHelper.ImportResult.IMPORT_NOTHING_NEW -> toast(R.string.no_new_items)
|
||||||
|
else -> toast(R.string.importing_failed)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (_: SerializationException) {
|
||||||
|
toast(R.string.invalid_file_format)
|
||||||
|
} catch (_: IllegalArgumentException) {
|
||||||
|
toast(R.string.invalid_file_format)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
showErrorToast(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,8 +27,11 @@ import com.simplemobiletools.notes.pro.extensions.widgetsDB
|
|||||||
import com.simplemobiletools.notes.pro.helpers.*
|
import com.simplemobiletools.notes.pro.helpers.*
|
||||||
import com.simplemobiletools.notes.pro.models.ChecklistItem
|
import com.simplemobiletools.notes.pro.models.ChecklistItem
|
||||||
import com.simplemobiletools.notes.pro.models.Note
|
import com.simplemobiletools.notes.pro.models.Note
|
||||||
|
import com.simplemobiletools.notes.pro.models.NoteType
|
||||||
import com.simplemobiletools.notes.pro.models.Widget
|
import com.simplemobiletools.notes.pro.models.Widget
|
||||||
import kotlinx.android.synthetic.main.widget_config.*
|
import kotlinx.android.synthetic.main.widget_config.*
|
||||||
|
import kotlinx.serialization.decodeFromString
|
||||||
|
import kotlinx.serialization.json.Json
|
||||||
|
|
||||||
class WidgetConfigureActivity : SimpleActivity() {
|
class WidgetConfigureActivity : SimpleActivity() {
|
||||||
private var mBgAlpha = 0f
|
private var mBgAlpha = 0f
|
||||||
@ -39,7 +42,7 @@ class WidgetConfigureActivity : SimpleActivity() {
|
|||||||
private var mCurrentNoteId = 0L
|
private var mCurrentNoteId = 0L
|
||||||
private var mIsCustomizingColors = false
|
private var mIsCustomizingColors = false
|
||||||
private var mShowTitle = false
|
private var mShowTitle = false
|
||||||
private var mNotes = ArrayList<Note>()
|
private var mNotes = listOf<Note>()
|
||||||
|
|
||||||
public override fun onCreate(savedInstanceState: Bundle?) {
|
public override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
useDynamicTheme = false
|
useDynamicTheme = false
|
||||||
@ -156,7 +159,7 @@ class WidgetConfigureActivity : SimpleActivity() {
|
|||||||
mCurrentNoteId = note.id!!
|
mCurrentNoteId = note.id!!
|
||||||
notes_picker_value.text = note.title
|
notes_picker_value.text = note.title
|
||||||
text_note_view_title.text = note.title
|
text_note_view_title.text = note.title
|
||||||
if (note.type == NoteType.TYPE_CHECKLIST.value) {
|
if (note.type == NoteType.TYPE_CHECKLIST) {
|
||||||
val checklistItemType = object : TypeToken<List<ChecklistItem>>() {}.type
|
val checklistItemType = object : TypeToken<List<ChecklistItem>>() {}.type
|
||||||
val items = Gson().fromJson<ArrayList<ChecklistItem>>(note.value, checklistItemType) ?: ArrayList(1)
|
val items = Gson().fromJson<ArrayList<ChecklistItem>>(note.value, checklistItemType) ?: ArrayList(1)
|
||||||
items.apply {
|
items.apply {
|
||||||
|
@ -31,7 +31,7 @@ import kotlinx.android.synthetic.main.item_checklist.view.*
|
|||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
class ChecklistAdapter(
|
class ChecklistAdapter(
|
||||||
activity: BaseSimpleActivity, var items: ArrayList<ChecklistItem>, val listener: ChecklistItemsListener?,
|
activity: BaseSimpleActivity, var items: MutableList<ChecklistItem>, val listener: ChecklistItemsListener?,
|
||||||
recyclerView: MyRecyclerView, val showIcons: Boolean, itemClick: (Any) -> Unit
|
recyclerView: MyRecyclerView, val showIcons: Boolean, itemClick: (Any) -> Unit
|
||||||
) :
|
) :
|
||||||
MyRecyclerViewAdapter(activity, recyclerView, itemClick), ItemTouchHelperContract {
|
MyRecyclerViewAdapter(activity, recyclerView, itemClick), ItemTouchHelperContract {
|
||||||
|
@ -10,8 +10,8 @@ import com.simplemobiletools.notes.pro.fragments.ChecklistFragment
|
|||||||
import com.simplemobiletools.notes.pro.fragments.NoteFragment
|
import com.simplemobiletools.notes.pro.fragments.NoteFragment
|
||||||
import com.simplemobiletools.notes.pro.fragments.TextFragment
|
import com.simplemobiletools.notes.pro.fragments.TextFragment
|
||||||
import com.simplemobiletools.notes.pro.helpers.NOTE_ID
|
import com.simplemobiletools.notes.pro.helpers.NOTE_ID
|
||||||
import com.simplemobiletools.notes.pro.helpers.NoteType
|
|
||||||
import com.simplemobiletools.notes.pro.models.Note
|
import com.simplemobiletools.notes.pro.models.Note
|
||||||
|
import com.simplemobiletools.notes.pro.models.NoteType
|
||||||
|
|
||||||
class NotesPagerAdapter(fm: FragmentManager, val notes: List<Note>, val activity: Activity) : FragmentStatePagerAdapter(fm) {
|
class NotesPagerAdapter(fm: FragmentManager, val notes: List<Note>, val activity: Activity) : FragmentStatePagerAdapter(fm) {
|
||||||
private var fragments: HashMap<Int, NoteFragment> = LinkedHashMap()
|
private var fragments: HashMap<Int, NoteFragment> = LinkedHashMap()
|
||||||
@ -30,7 +30,7 @@ class NotesPagerAdapter(fm: FragmentManager, val notes: List<Note>, val activity
|
|||||||
return fragments[position]!!
|
return fragments[position]!!
|
||||||
}
|
}
|
||||||
|
|
||||||
val fragment = if (note.type == NoteType.TYPE_TEXT.value) TextFragment() else ChecklistFragment()
|
val fragment = if (note.type == NoteType.TYPE_TEXT) TextFragment() else ChecklistFragment()
|
||||||
fragment.arguments = bundle
|
fragment.arguments = bundle
|
||||||
fragments[position] = fragment
|
fragments[position] = fragment
|
||||||
return fragment
|
return fragment
|
||||||
|
@ -20,6 +20,9 @@ import com.simplemobiletools.notes.pro.extensions.notesDB
|
|||||||
import com.simplemobiletools.notes.pro.helpers.*
|
import com.simplemobiletools.notes.pro.helpers.*
|
||||||
import com.simplemobiletools.notes.pro.models.ChecklistItem
|
import com.simplemobiletools.notes.pro.models.ChecklistItem
|
||||||
import com.simplemobiletools.notes.pro.models.Note
|
import com.simplemobiletools.notes.pro.models.Note
|
||||||
|
import com.simplemobiletools.notes.pro.models.NoteType
|
||||||
|
import kotlinx.serialization.decodeFromString
|
||||||
|
import kotlinx.serialization.json.Json
|
||||||
|
|
||||||
class WidgetAdapter(val context: Context, val intent: Intent) : RemoteViewsService.RemoteViewsFactory {
|
class WidgetAdapter(val context: Context, val intent: Intent) : RemoteViewsService.RemoteViewsFactory {
|
||||||
private val textIds = arrayOf(
|
private val textIds = arrayOf(
|
||||||
@ -32,7 +35,7 @@ class WidgetAdapter(val context: Context, val intent: Intent) : RemoteViewsServi
|
|||||||
)
|
)
|
||||||
private var widgetTextColor = DEFAULT_WIDGET_TEXT_COLOR
|
private var widgetTextColor = DEFAULT_WIDGET_TEXT_COLOR
|
||||||
private var note: Note? = null
|
private var note: Note? = null
|
||||||
private var checklistItems = ArrayList<ChecklistItem>()
|
private var checklistItems = mutableListOf<ChecklistItem>()
|
||||||
|
|
||||||
override fun getViewAt(position: Int): RemoteViews {
|
override fun getViewAt(position: Int): RemoteViews {
|
||||||
val noteId = intent.getLongExtra(NOTE_ID, 0L)
|
val noteId = intent.getLongExtra(NOTE_ID, 0L)
|
||||||
@ -43,7 +46,7 @@ class WidgetAdapter(val context: Context, val intent: Intent) : RemoteViewsServi
|
|||||||
}
|
}
|
||||||
|
|
||||||
val textSize = context.getPercentageFontSize() / context.resources.displayMetrics.density
|
val textSize = context.getPercentageFontSize() / context.resources.displayMetrics.density
|
||||||
if (note!!.type == NoteType.TYPE_CHECKLIST.value) {
|
if (note!!.type == NoteType.TYPE_CHECKLIST) {
|
||||||
remoteView = RemoteViews(context.packageName, R.layout.item_checklist_widget).apply {
|
remoteView = RemoteViews(context.packageName, R.layout.item_checklist_widget).apply {
|
||||||
val checklistItem = checklistItems.getOrNull(position) ?: return@apply
|
val checklistItem = checklistItems.getOrNull(position) ?: return@apply
|
||||||
val widgetNewTextColor = if (checklistItem.isDone) widgetTextColor.adjustAlpha(DONE_CHECKLIST_ITEM_ALPHA) else widgetTextColor
|
val widgetNewTextColor = if (checklistItem.isDone) widgetTextColor.adjustAlpha(DONE_CHECKLIST_ITEM_ALPHA) else widgetTextColor
|
||||||
@ -123,9 +126,8 @@ class WidgetAdapter(val context: Context, val intent: Intent) : RemoteViewsServi
|
|||||||
widgetTextColor = intent.getIntExtra(WIDGET_TEXT_COLOR, DEFAULT_WIDGET_TEXT_COLOR)
|
widgetTextColor = intent.getIntExtra(WIDGET_TEXT_COLOR, DEFAULT_WIDGET_TEXT_COLOR)
|
||||||
val noteId = intent.getLongExtra(NOTE_ID, 0L)
|
val noteId = intent.getLongExtra(NOTE_ID, 0L)
|
||||||
note = context.notesDB.getNoteWithId(noteId)
|
note = context.notesDB.getNoteWithId(noteId)
|
||||||
if (note?.type == NoteType.TYPE_CHECKLIST.value) {
|
if (note?.type == NoteType.TYPE_CHECKLIST) {
|
||||||
val checklistItemType = object : TypeToken<List<ChecklistItem>>() {}.type
|
checklistItems = note!!.getNoteStoredValue(context)?.let { Json.decodeFromString(it) } ?: mutableListOf()
|
||||||
checklistItems = Gson().fromJson<ArrayList<ChecklistItem>>(note!!.getNoteStoredValue(context), checklistItemType) ?: ArrayList(1)
|
|
||||||
|
|
||||||
// checklist title can be null only because of the glitch in upgrade to 6.6.0, remove this check in the future
|
// checklist title can be null only because of the glitch in upgrade to 6.6.0, remove this check in the future
|
||||||
checklistItems = checklistItems.filter { it.title != null }.toMutableList() as ArrayList<ChecklistItem>
|
checklistItems = checklistItems.filter { it.title != null }.toMutableList() as ArrayList<ChecklistItem>
|
||||||
@ -135,7 +137,7 @@ class WidgetAdapter(val context: Context, val intent: Intent) : RemoteViewsServi
|
|||||||
override fun hasStableIds() = true
|
override fun hasStableIds() = true
|
||||||
|
|
||||||
override fun getCount(): Int {
|
override fun getCount(): Int {
|
||||||
return if (note?.type == NoteType.TYPE_CHECKLIST.value) {
|
return if (note?.type == NoteType.TYPE_CHECKLIST) {
|
||||||
checklistItems.size
|
checklistItems.size
|
||||||
} else {
|
} else {
|
||||||
1
|
1
|
||||||
|
@ -9,10 +9,10 @@ import androidx.sqlite.db.SupportSQLiteDatabase
|
|||||||
import com.simplemobiletools.commons.helpers.PROTECTION_NONE
|
import com.simplemobiletools.commons.helpers.PROTECTION_NONE
|
||||||
import com.simplemobiletools.notes.pro.R
|
import com.simplemobiletools.notes.pro.R
|
||||||
import com.simplemobiletools.notes.pro.helpers.DEFAULT_WIDGET_TEXT_COLOR
|
import com.simplemobiletools.notes.pro.helpers.DEFAULT_WIDGET_TEXT_COLOR
|
||||||
import com.simplemobiletools.notes.pro.helpers.NoteType
|
|
||||||
import com.simplemobiletools.notes.pro.interfaces.NotesDao
|
import com.simplemobiletools.notes.pro.interfaces.NotesDao
|
||||||
import com.simplemobiletools.notes.pro.interfaces.WidgetsDao
|
import com.simplemobiletools.notes.pro.interfaces.WidgetsDao
|
||||||
import com.simplemobiletools.notes.pro.models.Note
|
import com.simplemobiletools.notes.pro.models.Note
|
||||||
|
import com.simplemobiletools.notes.pro.models.NoteType
|
||||||
import com.simplemobiletools.notes.pro.models.Widget
|
import com.simplemobiletools.notes.pro.models.Widget
|
||||||
import java.util.concurrent.Executors
|
import java.util.concurrent.Executors
|
||||||
|
|
||||||
@ -57,7 +57,7 @@ abstract class NotesDatabase : RoomDatabase() {
|
|||||||
private fun insertFirstNote(context: Context) {
|
private fun insertFirstNote(context: Context) {
|
||||||
Executors.newSingleThreadScheduledExecutor().execute {
|
Executors.newSingleThreadScheduledExecutor().execute {
|
||||||
val generalNote = context.resources.getString(R.string.general_note)
|
val generalNote = context.resources.getString(R.string.general_note)
|
||||||
val note = Note(null, generalNote, "", NoteType.TYPE_TEXT.value, "", PROTECTION_NONE, "")
|
val note = Note(null, generalNote, "", NoteType.TYPE_TEXT, "", PROTECTION_NONE, "")
|
||||||
db!!.NotesDao().insertOrUpdate(note)
|
db!!.NotesDao().insertOrUpdate(note)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,42 @@
|
|||||||
|
package com.simplemobiletools.notes.pro.dialogs
|
||||||
|
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import androidx.appcompat.app.AlertDialog
|
||||||
|
import com.simplemobiletools.commons.extensions.*
|
||||||
|
import com.simplemobiletools.notes.pro.R
|
||||||
|
import com.simplemobiletools.notes.pro.activities.SimpleActivity
|
||||||
|
import kotlinx.android.synthetic.main.dialog_export_notes.view.export_notes_filename
|
||||||
|
|
||||||
|
class ExportNotesDialog(val activity: SimpleActivity, callback: (filename: String) -> Unit) {
|
||||||
|
|
||||||
|
init {
|
||||||
|
val view = (activity.layoutInflater.inflate(R.layout.dialog_export_notes, null) as ViewGroup).apply {
|
||||||
|
export_notes_filename.setText(
|
||||||
|
buildString {
|
||||||
|
append(context.getString(R.string.notes))
|
||||||
|
append("_")
|
||||||
|
append(context.getCurrentFormattedDateTime())
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
activity.getAlertDialogBuilder().setPositiveButton(R.string.ok, null).setNegativeButton(R.string.cancel, null).apply {
|
||||||
|
activity.setupDialogStuff(view, this, R.string.export_notes) { alertDialog ->
|
||||||
|
alertDialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener {
|
||||||
|
|
||||||
|
val filename = view.export_notes_filename.value
|
||||||
|
when {
|
||||||
|
filename.isEmpty() -> activity.toast(R.string.empty_name)
|
||||||
|
filename.isAValidFilename() -> {
|
||||||
|
callback(filename)
|
||||||
|
alertDialog.dismiss()
|
||||||
|
}
|
||||||
|
|
||||||
|
else -> activity.toast(R.string.invalid_name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -9,10 +9,11 @@ import com.simplemobiletools.notes.pro.R
|
|||||||
import com.simplemobiletools.notes.pro.activities.SimpleActivity
|
import com.simplemobiletools.notes.pro.activities.SimpleActivity
|
||||||
import com.simplemobiletools.notes.pro.extensions.notesDB
|
import com.simplemobiletools.notes.pro.extensions.notesDB
|
||||||
import com.simplemobiletools.notes.pro.extensions.parseChecklistItems
|
import com.simplemobiletools.notes.pro.extensions.parseChecklistItems
|
||||||
import com.simplemobiletools.notes.pro.helpers.NoteType
|
|
||||||
import com.simplemobiletools.notes.pro.helpers.NotesHelper
|
import com.simplemobiletools.notes.pro.helpers.NotesHelper
|
||||||
import com.simplemobiletools.notes.pro.models.Note
|
import com.simplemobiletools.notes.pro.models.Note
|
||||||
import kotlinx.android.synthetic.main.dialog_import_folder.view.*
|
import com.simplemobiletools.notes.pro.models.NoteType
|
||||||
|
import kotlinx.android.synthetic.main.dialog_import_folder.view.open_file_filename
|
||||||
|
import kotlinx.android.synthetic.main.dialog_import_folder.view.open_file_type
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
class ImportFolderDialog(val activity: SimpleActivity, val path: String, val callback: () -> Unit) : AlertDialog.Builder(activity) {
|
class ImportFolderDialog(val activity: SimpleActivity, val path: String, val callback: () -> Unit) : AlertDialog.Builder(activity) {
|
||||||
@ -50,21 +51,21 @@ class ImportFolderDialog(val activity: SimpleActivity, val path: String, val cal
|
|||||||
activity.notesDB.getNoteIdWithTitle(filename) != null -> false
|
activity.notesDB.getNoteIdWithTitle(filename) != null -> false
|
||||||
else -> true
|
else -> true
|
||||||
}
|
}
|
||||||
}.forEach {
|
}?.forEach {
|
||||||
val storePath = if (updateFilesOnEdit) it.absolutePath else ""
|
val storePath = if (updateFilesOnEdit) it.absolutePath else ""
|
||||||
val title = it.absolutePath.getFilenameFromPath()
|
val title = it.absolutePath.getFilenameFromPath()
|
||||||
val value = if (updateFilesOnEdit) "" else it.readText()
|
val value = if (updateFilesOnEdit) "" else it.readText()
|
||||||
val fileText = it.readText().trim()
|
val fileText = it.readText().trim()
|
||||||
val checklistItems = fileText.parseChecklistItems()
|
val checklistItems = fileText.parseChecklistItems()
|
||||||
if (checklistItems != null) {
|
if (checklistItems != null) {
|
||||||
saveNote(title.substringBeforeLast('.'), fileText, NoteType.TYPE_CHECKLIST.value, "")
|
saveNote(title.substringBeforeLast('.'), fileText, NoteType.TYPE_CHECKLIST, "")
|
||||||
} else {
|
} else {
|
||||||
if (updateFilesOnEdit) {
|
if (updateFilesOnEdit) {
|
||||||
activity.handleSAFDialog(path) {
|
activity.handleSAFDialog(path) {
|
||||||
saveNote(title, value, NoteType.TYPE_TEXT.value, storePath)
|
saveNote(title, value, NoteType.TYPE_TEXT, storePath)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
saveNote(title, value, NoteType.TYPE_TEXT.value, storePath)
|
saveNote(title, value, NoteType.TYPE_TEXT, storePath)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -75,7 +76,7 @@ class ImportFolderDialog(val activity: SimpleActivity, val path: String, val cal
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun saveNote(title: String, value: String, type: Int, path: String) {
|
private fun saveNote(title: String, value: String, type: NoteType, path: String) {
|
||||||
val note = Note(null, title, value, type, path, PROTECTION_NONE, "")
|
val note = Note(null, title, value, type, path, PROTECTION_NONE, "")
|
||||||
NotesHelper(activity).insertOrUpdateNote(note)
|
NotesHelper(activity).insertOrUpdateNote(note)
|
||||||
}
|
}
|
||||||
|
@ -8,8 +8,8 @@ import com.simplemobiletools.commons.helpers.ensureBackgroundThread
|
|||||||
import com.simplemobiletools.notes.pro.R
|
import com.simplemobiletools.notes.pro.R
|
||||||
import com.simplemobiletools.notes.pro.extensions.config
|
import com.simplemobiletools.notes.pro.extensions.config
|
||||||
import com.simplemobiletools.notes.pro.extensions.notesDB
|
import com.simplemobiletools.notes.pro.extensions.notesDB
|
||||||
import com.simplemobiletools.notes.pro.helpers.NoteType
|
|
||||||
import com.simplemobiletools.notes.pro.models.Note
|
import com.simplemobiletools.notes.pro.models.Note
|
||||||
|
import com.simplemobiletools.notes.pro.models.NoteType
|
||||||
import kotlinx.android.synthetic.main.dialog_new_note.view.*
|
import kotlinx.android.synthetic.main.dialog_new_note.view.*
|
||||||
|
|
||||||
class NewNoteDialog(val activity: Activity, title: String? = null, val setChecklistAsDefault: Boolean, callback: (note: Note) -> Unit) {
|
class NewNoteDialog(val activity: Activity, title: String? = null, val setChecklistAsDefault: Boolean, callback: (note: Note) -> Unit) {
|
||||||
@ -40,12 +40,12 @@ class NewNoteDialog(val activity: Activity, title: String? = null, val setCheckl
|
|||||||
activity.notesDB.getNoteIdWithTitle(newTitle) != null -> activity.toast(R.string.title_taken)
|
activity.notesDB.getNoteIdWithTitle(newTitle) != null -> activity.toast(R.string.title_taken)
|
||||||
else -> {
|
else -> {
|
||||||
val type = if (view.new_note_type.checkedRadioButtonId == view.type_checklist.id) {
|
val type = if (view.new_note_type.checkedRadioButtonId == view.type_checklist.id) {
|
||||||
NoteType.TYPE_CHECKLIST.value
|
NoteType.TYPE_CHECKLIST
|
||||||
} else {
|
} else {
|
||||||
NoteType.TYPE_TEXT.value
|
NoteType.TYPE_TEXT
|
||||||
}
|
}
|
||||||
|
|
||||||
activity.config.lastCreatedNoteType = type
|
activity.config.lastCreatedNoteType = type.value
|
||||||
val newNote = Note(null, newTitle, "", type, "", PROTECTION_NONE, "")
|
val newNote = Note(null, newTitle, "", type, "", PROTECTION_NONE, "")
|
||||||
callback(newNote)
|
callback(newNote)
|
||||||
alertDialog.dismiss()
|
alertDialog.dismiss()
|
||||||
|
@ -9,8 +9,8 @@ import com.simplemobiletools.commons.extensions.setupDialogStuff
|
|||||||
import com.simplemobiletools.commons.helpers.PROTECTION_NONE
|
import com.simplemobiletools.commons.helpers.PROTECTION_NONE
|
||||||
import com.simplemobiletools.notes.pro.R
|
import com.simplemobiletools.notes.pro.R
|
||||||
import com.simplemobiletools.notes.pro.activities.SimpleActivity
|
import com.simplemobiletools.notes.pro.activities.SimpleActivity
|
||||||
import com.simplemobiletools.notes.pro.helpers.NoteType
|
|
||||||
import com.simplemobiletools.notes.pro.models.Note
|
import com.simplemobiletools.notes.pro.models.Note
|
||||||
|
import com.simplemobiletools.notes.pro.models.NoteType
|
||||||
import kotlinx.android.synthetic.main.dialog_open_file.view.*
|
import kotlinx.android.synthetic.main.dialog_open_file.view.*
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
@ -47,7 +47,7 @@ class OpenFileDialog(val activity: SimpleActivity, val path: String, val callbac
|
|||||||
|
|
||||||
private fun saveNote(storeContent: String, storePath: String) {
|
private fun saveNote(storeContent: String, storePath: String) {
|
||||||
val filename = path.getFilenameFromPath()
|
val filename = path.getFilenameFromPath()
|
||||||
val note = Note(null, filename, storeContent, NoteType.TYPE_TEXT.value, storePath, PROTECTION_NONE, "")
|
val note = Note(null, filename, storeContent, NoteType.TYPE_TEXT, storePath, PROTECTION_NONE, "")
|
||||||
callback(note)
|
callback(note)
|
||||||
dialog?.dismiss()
|
dialog?.dismiss()
|
||||||
}
|
}
|
||||||
|
@ -31,7 +31,7 @@ class OpenNoteDialog(val activity: Activity, val callback: (checkedId: Long, new
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun initDialog(notes: ArrayList<Note>, view: View) {
|
private fun initDialog(notes: List<Note>, view: View) {
|
||||||
val textColor = activity.getProperTextColor()
|
val textColor = activity.getProperTextColor()
|
||||||
notes.forEach {
|
notes.forEach {
|
||||||
activity.layoutInflater.inflate(R.layout.open_note_item, null).apply {
|
activity.layoutInflater.inflate(R.layout.open_note_item, null).apply {
|
||||||
|
@ -10,7 +10,7 @@ import com.simplemobiletools.notes.pro.models.Note
|
|||||||
import kotlinx.android.synthetic.main.dialog_unlock_notes.view.*
|
import kotlinx.android.synthetic.main.dialog_unlock_notes.view.*
|
||||||
import kotlinx.android.synthetic.main.item_locked_note.view.*
|
import kotlinx.android.synthetic.main.item_locked_note.view.*
|
||||||
|
|
||||||
class UnlockNotesDialog(val activity: BaseSimpleActivity, val notes: List<Note>, callback: (unlockedNoteIds: List<Long>) -> Unit) {
|
class UnlockNotesDialog(val activity: BaseSimpleActivity, val notes: List<Note>, callback: (unlockedNotes: List<Note>) -> Unit) {
|
||||||
private var dialog: AlertDialog? = null
|
private var dialog: AlertDialog? = null
|
||||||
private val view = activity.layoutInflater.inflate(R.layout.dialog_unlock_notes, null) as ViewGroup
|
private val view = activity.layoutInflater.inflate(R.layout.dialog_unlock_notes, null) as ViewGroup
|
||||||
private val redColor = activity.getColor(R.color.md_red)
|
private val redColor = activity.getColor(R.color.md_red)
|
||||||
@ -29,7 +29,7 @@ class UnlockNotesDialog(val activity: BaseSimpleActivity, val notes: List<Note>,
|
|||||||
activity.setupDialogStuff(view, this, R.string.unlock_notes, cancelOnTouchOutside = false) { alertDialog ->
|
activity.setupDialogStuff(view, this, R.string.unlock_notes, cancelOnTouchOutside = false) { alertDialog ->
|
||||||
dialog = alertDialog
|
dialog = alertDialog
|
||||||
alertDialog.getButton(DialogInterface.BUTTON_POSITIVE).setOnClickListener {
|
alertDialog.getButton(DialogInterface.BUTTON_POSITIVE).setOnClickListener {
|
||||||
callback(unlockedNoteIds)
|
callback(unlockedNoteIds.mapNotNull { id -> notes.firstOrNull { it.id == id } })
|
||||||
alertDialog.dismiss()
|
alertDialog.dismiss()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,12 +4,15 @@ import android.appwidget.AppWidgetManager
|
|||||||
import android.content.ComponentName
|
import android.content.ComponentName
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
|
import com.simplemobiletools.commons.activities.BaseSimpleActivity
|
||||||
import com.simplemobiletools.notes.pro.R
|
import com.simplemobiletools.notes.pro.R
|
||||||
import com.simplemobiletools.notes.pro.databases.NotesDatabase
|
import com.simplemobiletools.notes.pro.databases.NotesDatabase
|
||||||
|
import com.simplemobiletools.notes.pro.dialogs.UnlockNotesDialog
|
||||||
import com.simplemobiletools.notes.pro.helpers.Config
|
import com.simplemobiletools.notes.pro.helpers.Config
|
||||||
import com.simplemobiletools.notes.pro.helpers.MyWidgetProvider
|
import com.simplemobiletools.notes.pro.helpers.MyWidgetProvider
|
||||||
import com.simplemobiletools.notes.pro.interfaces.NotesDao
|
import com.simplemobiletools.notes.pro.interfaces.NotesDao
|
||||||
import com.simplemobiletools.notes.pro.interfaces.WidgetsDao
|
import com.simplemobiletools.notes.pro.interfaces.WidgetsDao
|
||||||
|
import com.simplemobiletools.notes.pro.models.Note
|
||||||
|
|
||||||
val Context.config: Config get() = Config.newInstance(applicationContext)
|
val Context.config: Config get() = Config.newInstance(applicationContext)
|
||||||
|
|
||||||
@ -29,3 +32,14 @@ fun Context.updateWidgets() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun Context.getPercentageFontSize() = resources.getDimension(R.dimen.middle_text_size) * (config.fontSizePercentage / 100f)
|
fun Context.getPercentageFontSize() = resources.getDimension(R.dimen.middle_text_size) * (config.fontSizePercentage / 100f)
|
||||||
|
|
||||||
|
fun BaseSimpleActivity.requestUnlockNotes(notes: List<Note>, callback: (unlockedNotes: List<Note>) -> Unit) {
|
||||||
|
val lockedNotes = notes.filter { it.isLocked() }
|
||||||
|
if (lockedNotes.isNotEmpty()) {
|
||||||
|
runOnUiThread {
|
||||||
|
UnlockNotesDialog(this, lockedNotes, callback)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
callback(emptyList())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -29,7 +29,7 @@ class ChecklistFragment : NoteFragment(), ChecklistItemsListener {
|
|||||||
|
|
||||||
lateinit var view: ViewGroup
|
lateinit var view: ViewGroup
|
||||||
|
|
||||||
var items = ArrayList<ChecklistItem>()
|
var items = mutableListOf<ChecklistItem>()
|
||||||
|
|
||||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||||
view = inflater.inflate(R.layout.fragment_checklist, container, false) as ViewGroup
|
view = inflater.inflate(R.layout.fragment_checklist, container, false) as ViewGroup
|
||||||
|
@ -5,6 +5,7 @@ import android.content.Context
|
|||||||
import android.os.Environment
|
import android.os.Environment
|
||||||
import android.view.Gravity
|
import android.view.Gravity
|
||||||
import com.simplemobiletools.commons.helpers.BaseConfig
|
import com.simplemobiletools.commons.helpers.BaseConfig
|
||||||
|
import com.simplemobiletools.notes.pro.models.NoteType
|
||||||
|
|
||||||
class Config(context: Context) : BaseConfig(context) {
|
class Config(context: Context) : BaseConfig(context) {
|
||||||
companion object {
|
companion object {
|
||||||
|
@ -44,9 +44,6 @@ const val GRAVITY_LEFT = 0
|
|||||||
const val GRAVITY_CENTER = 1
|
const val GRAVITY_CENTER = 1
|
||||||
const val GRAVITY_RIGHT = 2
|
const val GRAVITY_RIGHT = 2
|
||||||
|
|
||||||
// note types
|
|
||||||
enum class NoteType(val value: Int) { TYPE_TEXT(0), TYPE_CHECKLIST(1) }
|
|
||||||
|
|
||||||
// mime types
|
// mime types
|
||||||
const val MIME_TEXT_PLAIN = "text/plain"
|
const val MIME_TEXT_PLAIN = "text/plain"
|
||||||
|
|
||||||
|
@ -1,48 +0,0 @@
|
|||||||
package com.simplemobiletools.notes.pro.helpers
|
|
||||||
|
|
||||||
import android.content.Context
|
|
||||||
import com.google.gson.Gson
|
|
||||||
import com.google.gson.stream.JsonWriter
|
|
||||||
import com.simplemobiletools.commons.helpers.PROTECTION_NONE
|
|
||||||
import com.simplemobiletools.commons.helpers.ensureBackgroundThread
|
|
||||||
import com.simplemobiletools.notes.pro.models.Note
|
|
||||||
import java.io.OutputStream
|
|
||||||
|
|
||||||
class NotesExporter(private val context: Context) {
|
|
||||||
enum class ExportResult {
|
|
||||||
EXPORT_FAIL, EXPORT_OK
|
|
||||||
}
|
|
||||||
|
|
||||||
private val gson = Gson()
|
|
||||||
|
|
||||||
fun exportNotes(notes: List<Note>, unlockedNoteIds: List<Long>, outputStream: OutputStream?, callback: (result: ExportResult) -> Unit) {
|
|
||||||
ensureBackgroundThread {
|
|
||||||
if (outputStream == null) {
|
|
||||||
callback.invoke(ExportResult.EXPORT_FAIL)
|
|
||||||
return@ensureBackgroundThread
|
|
||||||
}
|
|
||||||
val writer = JsonWriter(outputStream.bufferedWriter())
|
|
||||||
writer.use {
|
|
||||||
try {
|
|
||||||
var written = 0
|
|
||||||
writer.beginArray()
|
|
||||||
for (note in notes) {
|
|
||||||
if (!note.isLocked() || note.id in unlockedNoteIds) {
|
|
||||||
val noteToSave = getNoteToExport(note)
|
|
||||||
writer.jsonValue(gson.toJson(noteToSave))
|
|
||||||
written++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
writer.endArray()
|
|
||||||
callback.invoke(ExportResult.EXPORT_OK)
|
|
||||||
} catch (e: Exception) {
|
|
||||||
callback.invoke(ExportResult.EXPORT_FAIL)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getNoteToExport(note: Note): Note {
|
|
||||||
return Note(null, note.title, note.getNoteStoredValue(context) ?: "", note.type, "", PROTECTION_NONE, "")
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,19 +1,20 @@
|
|||||||
package com.simplemobiletools.notes.pro.helpers
|
package com.simplemobiletools.notes.pro.helpers
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.net.Uri
|
|
||||||
import android.os.Handler
|
import android.os.Handler
|
||||||
import android.os.Looper
|
import android.os.Looper
|
||||||
|
import com.simplemobiletools.commons.activities.BaseSimpleActivity
|
||||||
import com.simplemobiletools.commons.helpers.PROTECTION_NONE
|
import com.simplemobiletools.commons.helpers.PROTECTION_NONE
|
||||||
import com.simplemobiletools.commons.helpers.ensureBackgroundThread
|
import com.simplemobiletools.commons.helpers.ensureBackgroundThread
|
||||||
import com.simplemobiletools.notes.pro.R
|
import com.simplemobiletools.notes.pro.R
|
||||||
import com.simplemobiletools.notes.pro.extensions.config
|
import com.simplemobiletools.notes.pro.extensions.config
|
||||||
import com.simplemobiletools.notes.pro.extensions.notesDB
|
import com.simplemobiletools.notes.pro.extensions.notesDB
|
||||||
import com.simplemobiletools.notes.pro.models.Note
|
import com.simplemobiletools.notes.pro.models.Note
|
||||||
|
import com.simplemobiletools.notes.pro.models.NoteType
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
class NotesHelper(val context: Context) {
|
class NotesHelper(val context: Context) {
|
||||||
fun getNotes(callback: (notes: ArrayList<Note>) -> Unit) {
|
fun getNotes(callback: (notes: List<Note>) -> Unit) {
|
||||||
ensureBackgroundThread {
|
ensureBackgroundThread {
|
||||||
// make sure the initial note has enough time to be precreated
|
// make sure the initial note has enough time to be precreated
|
||||||
if (context.config.appRunCount <= 1) {
|
if (context.config.appRunCount <= 1) {
|
||||||
@ -21,8 +22,8 @@ class NotesHelper(val context: Context) {
|
|||||||
Thread.sleep(200)
|
Thread.sleep(200)
|
||||||
}
|
}
|
||||||
|
|
||||||
val notes = context.notesDB.getNotes() as ArrayList<Note>
|
val notes = context.notesDB.getNotes().toMutableList()
|
||||||
val notesToDelete = ArrayList<Note>(notes.size)
|
val notesToDelete = mutableListOf<Note>()
|
||||||
notes.forEach {
|
notes.forEach {
|
||||||
if (it.path.isNotEmpty()) {
|
if (it.path.isNotEmpty()) {
|
||||||
if (!it.path.startsWith("content://") && !File(it.path).exists()) {
|
if (!it.path.startsWith("content://") && !File(it.path).exists()) {
|
||||||
@ -36,7 +37,7 @@ class NotesHelper(val context: Context) {
|
|||||||
|
|
||||||
if (notes.isEmpty()) {
|
if (notes.isEmpty()) {
|
||||||
val generalNote = context.resources.getString(R.string.general_note)
|
val generalNote = context.resources.getString(R.string.general_note)
|
||||||
val note = Note(null, generalNote, "", NoteType.TYPE_TEXT.value, "", PROTECTION_NONE, "")
|
val note = Note(null, generalNote, "", NoteType.TYPE_TEXT, "", PROTECTION_NONE, "")
|
||||||
context.notesDB.insertOrUpdate(note)
|
context.notesDB.insertOrUpdate(note)
|
||||||
notes.add(note)
|
notes.add(note)
|
||||||
}
|
}
|
||||||
@ -73,4 +74,57 @@ class NotesHelper(val context: Context) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun insertOrUpdateNotes(notes: List<Note>, callback: ((newNoteIds: List<Long>) -> Unit)? = null) {
|
||||||
|
ensureBackgroundThread {
|
||||||
|
val noteIds = context.notesDB.insertOrUpdate(notes)
|
||||||
|
Handler(Looper.getMainLooper()).post {
|
||||||
|
callback?.invoke(noteIds)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun importNotes(activity: BaseSimpleActivity, notes: List<Note>, callback: (ImportResult) -> Unit) {
|
||||||
|
ensureBackgroundThread {
|
||||||
|
val currentNotes = activity.notesDB.getNotes()
|
||||||
|
if (currentNotes.isEmpty()) {
|
||||||
|
insertOrUpdateNotes(notes) { savedNotes ->
|
||||||
|
|
||||||
|
val newCurrentNotes = activity.notesDB.getNotes()
|
||||||
|
|
||||||
|
val result = when {
|
||||||
|
currentNotes.size == newCurrentNotes.size -> ImportResult.IMPORT_NOTHING_NEW
|
||||||
|
notes.size == savedNotes.size -> ImportResult.IMPORT_OK
|
||||||
|
savedNotes.isEmpty() -> ImportResult.IMPORT_FAIL
|
||||||
|
else -> ImportResult.IMPORT_PARTIAL
|
||||||
|
}
|
||||||
|
callback(result)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
var imported = 0
|
||||||
|
var skipped = 0
|
||||||
|
|
||||||
|
notes.forEach { note ->
|
||||||
|
val exists = context.notesDB.getNoteIdWithTitle(note.title) != null
|
||||||
|
if (!exists) {
|
||||||
|
context.notesDB.insertOrUpdate(note)
|
||||||
|
imported++
|
||||||
|
} else {
|
||||||
|
skipped++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val result = when {
|
||||||
|
skipped == notes.size || imported == 0 -> ImportResult.IMPORT_NOTHING_NEW
|
||||||
|
imported == notes.size -> ImportResult.IMPORT_OK
|
||||||
|
else -> ImportResult.IMPORT_PARTIAL
|
||||||
|
}
|
||||||
|
callback(result)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
enum class ImportResult {
|
||||||
|
IMPORT_FAIL, IMPORT_OK, IMPORT_PARTIAL, IMPORT_NOTHING_NEW
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,101 +0,0 @@
|
|||||||
package com.simplemobiletools.notes.pro.helpers
|
|
||||||
|
|
||||||
import android.content.Context
|
|
||||||
import com.google.gson.Gson
|
|
||||||
import com.google.gson.JsonSyntaxException
|
|
||||||
import com.google.gson.reflect.TypeToken
|
|
||||||
import com.simplemobiletools.commons.extensions.showErrorToast
|
|
||||||
import com.simplemobiletools.commons.helpers.PROTECTION_NONE
|
|
||||||
import com.simplemobiletools.commons.helpers.ensureBackgroundThread
|
|
||||||
import com.simplemobiletools.notes.pro.extensions.notesDB
|
|
||||||
import com.simplemobiletools.notes.pro.models.Note
|
|
||||||
import java.io.File
|
|
||||||
|
|
||||||
class NotesImporter(private val context: Context) {
|
|
||||||
enum class ImportResult {
|
|
||||||
IMPORT_FAIL, IMPORT_OK, IMPORT_PARTIAL, IMPORT_NOTHING_NEW
|
|
||||||
}
|
|
||||||
|
|
||||||
private val gson = Gson()
|
|
||||||
private var notesImported = 0
|
|
||||||
private var notesFailed = 0
|
|
||||||
private var notesSkipped = 0
|
|
||||||
|
|
||||||
fun importNotes(path: String, filename: String, force: Boolean = false, callback: (result: ImportResult) -> Unit) {
|
|
||||||
ensureBackgroundThread {
|
|
||||||
try {
|
|
||||||
val inputStream = if (path.contains("/")) {
|
|
||||||
File(path).inputStream()
|
|
||||||
} else {
|
|
||||||
context.assets.open(path)
|
|
||||||
}
|
|
||||||
|
|
||||||
inputStream.bufferedReader().use { reader ->
|
|
||||||
val json = reader.readText()
|
|
||||||
val type = object : TypeToken<List<Note>>() {}.type
|
|
||||||
val notes = gson.fromJson<List<Note>>(json, type)
|
|
||||||
val totalNotes = notes?.size ?: 0
|
|
||||||
if (totalNotes <= 0) {
|
|
||||||
callback.invoke(ImportResult.IMPORT_FAIL)
|
|
||||||
return@ensureBackgroundThread
|
|
||||||
}
|
|
||||||
|
|
||||||
for (note in notes) {
|
|
||||||
val exists = context.notesDB.getNoteIdWithTitle(note.title) != null
|
|
||||||
if (!exists) {
|
|
||||||
context.notesDB.insertOrUpdate(note)
|
|
||||||
notesImported++
|
|
||||||
} else {
|
|
||||||
notesSkipped++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (e: JsonSyntaxException) {
|
|
||||||
if (force) {
|
|
||||||
callback(ImportResult.IMPORT_FAIL)
|
|
||||||
return@ensureBackgroundThread
|
|
||||||
}
|
|
||||||
|
|
||||||
// Import notes expects a json with note name, content etc, but lets be more flexible and accept the basic files with note content only too
|
|
||||||
val inputStream = if (path.contains("/")) {
|
|
||||||
File(path).inputStream()
|
|
||||||
} else {
|
|
||||||
context.assets.open(path)
|
|
||||||
}
|
|
||||||
|
|
||||||
inputStream.bufferedReader().use { reader ->
|
|
||||||
val text = reader.readText()
|
|
||||||
val note = Note(null, filename, text, NoteType.TYPE_TEXT.value, "", PROTECTION_NONE, "")
|
|
||||||
var i = 1
|
|
||||||
if (context.notesDB.getNoteIdWithTitle(note.title) != null) {
|
|
||||||
while (true) {
|
|
||||||
val tryTitle = "$filename ($i)"
|
|
||||||
if (context.notesDB.getNoteIdWithTitle(tryTitle) == null) {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
i++
|
|
||||||
}
|
|
||||||
|
|
||||||
note.title = "$filename ($i)"
|
|
||||||
}
|
|
||||||
|
|
||||||
context.notesDB.insertOrUpdate(note)
|
|
||||||
notesImported++
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (e: Exception) {
|
|
||||||
context.showErrorToast(e)
|
|
||||||
notesFailed++
|
|
||||||
}
|
|
||||||
|
|
||||||
callback.invoke(
|
|
||||||
when {
|
|
||||||
notesSkipped > 0 && notesImported == 0 -> ImportResult.IMPORT_NOTHING_NEW
|
|
||||||
notesImported == 0 -> ImportResult.IMPORT_FAIL
|
|
||||||
notesFailed > 0 -> ImportResult.IMPORT_PARTIAL
|
|
||||||
else -> ImportResult.IMPORT_OK
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -23,6 +23,9 @@ interface NotesDao {
|
|||||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||||
fun insertOrUpdate(note: Note): Long
|
fun insertOrUpdate(note: Note): Long
|
||||||
|
|
||||||
|
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||||
|
fun insertOrUpdate(notes: List<Note>): List<Long>
|
||||||
|
|
||||||
@Delete
|
@Delete
|
||||||
fun deleteNote(note: Note)
|
fun deleteNote(note: Note)
|
||||||
}
|
}
|
||||||
|
@ -3,8 +3,16 @@ package com.simplemobiletools.notes.pro.models
|
|||||||
import com.simplemobiletools.commons.helpers.AlphanumericComparator
|
import com.simplemobiletools.commons.helpers.AlphanumericComparator
|
||||||
import com.simplemobiletools.commons.helpers.SORT_BY_TITLE
|
import com.simplemobiletools.commons.helpers.SORT_BY_TITLE
|
||||||
import com.simplemobiletools.commons.helpers.SORT_DESCENDING
|
import com.simplemobiletools.commons.helpers.SORT_DESCENDING
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class ChecklistItem(
|
||||||
|
val id: Int,
|
||||||
|
val dateCreated: Long = 0L,
|
||||||
|
var title: String,
|
||||||
|
var isDone: Boolean
|
||||||
|
) : Comparable<ChecklistItem> {
|
||||||
|
|
||||||
data class ChecklistItem(val id: Int, val dateCreated: Long = 0L, var title: String, var isDone: Boolean) : Comparable<ChecklistItem> {
|
|
||||||
companion object {
|
companion object {
|
||||||
var sorting = 0
|
var sorting = 0
|
||||||
}
|
}
|
||||||
|
@ -2,21 +2,27 @@ package com.simplemobiletools.notes.pro.models
|
|||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import androidx.room.ColumnInfo
|
import androidx.room.*
|
||||||
import androidx.room.Entity
|
|
||||||
import androidx.room.Index
|
|
||||||
import androidx.room.PrimaryKey
|
|
||||||
import com.simplemobiletools.commons.extensions.isBiometricIdAvailable
|
import com.simplemobiletools.commons.extensions.isBiometricIdAvailable
|
||||||
import com.simplemobiletools.commons.helpers.PROTECTION_FINGERPRINT
|
import com.simplemobiletools.commons.helpers.PROTECTION_FINGERPRINT
|
||||||
import com.simplemobiletools.commons.helpers.PROTECTION_NONE
|
import com.simplemobiletools.commons.helpers.PROTECTION_NONE
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a note.
|
||||||
|
*
|
||||||
|
* @property value The content of the note. Could be plain text or [ChecklistItem]
|
||||||
|
* @property type The type of the note. Should be one of the [NoteType] enum entries.
|
||||||
|
*/
|
||||||
|
@Serializable
|
||||||
@Entity(tableName = "notes", indices = [(Index(value = ["id"], unique = true))])
|
@Entity(tableName = "notes", indices = [(Index(value = ["id"], unique = true))])
|
||||||
|
@TypeConverters(NoteTypeConverter::class)
|
||||||
data class Note(
|
data class Note(
|
||||||
@PrimaryKey(autoGenerate = true) var id: Long?,
|
@PrimaryKey(autoGenerate = true) var id: Long?,
|
||||||
@ColumnInfo(name = "title") var title: String,
|
@ColumnInfo(name = "title") var title: String,
|
||||||
@ColumnInfo(name = "value") var value: String,
|
@ColumnInfo(name = "value") var value: String,
|
||||||
@ColumnInfo(name = "type") var type: Int,
|
@ColumnInfo(name = "type") var type: NoteType,
|
||||||
@ColumnInfo(name = "path") var path: String,
|
@ColumnInfo(name = "path") var path: String,
|
||||||
@ColumnInfo(name = "protection_type") var protectionType: Int,
|
@ColumnInfo(name = "protection_type") var protectionType: Int,
|
||||||
@ColumnInfo(name = "protection_hash") var protectionHash: String
|
@ColumnInfo(name = "protection_hash") var protectionHash: String
|
||||||
|
@ -0,0 +1,15 @@
|
|||||||
|
package com.simplemobiletools.notes.pro.models
|
||||||
|
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
enum class NoteType(val value: Int) {
|
||||||
|
TYPE_TEXT(0),
|
||||||
|
TYPE_CHECKLIST(1);
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun fromValue(value: Int): NoteType {
|
||||||
|
return values().find { it.value == value } ?: TYPE_TEXT
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,15 @@
|
|||||||
|
package com.simplemobiletools.notes.pro.models
|
||||||
|
|
||||||
|
import androidx.room.TypeConverter
|
||||||
|
|
||||||
|
class NoteTypeConverter {
|
||||||
|
@TypeConverter
|
||||||
|
fun fromNoteType(noteType: NoteType): Int {
|
||||||
|
return noteType.value
|
||||||
|
}
|
||||||
|
|
||||||
|
@TypeConverter
|
||||||
|
fun toNoteType(value: Int): NoteType {
|
||||||
|
return NoteType.fromValue(value)
|
||||||
|
}
|
||||||
|
}
|
@ -346,6 +346,46 @@
|
|||||||
android:text="@string/display_success_message" />
|
android:text="@string/display_success_message" />
|
||||||
|
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
||||||
|
|
||||||
|
<include
|
||||||
|
android:id="@+id/settings_general_settings_divider"
|
||||||
|
layout="@layout/divider" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/settings_migrating_label"
|
||||||
|
style="@style/SettingsSectionLabelStyle"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/migrating" />
|
||||||
|
|
||||||
|
<RelativeLayout
|
||||||
|
android:id="@+id/settings_export_notes_holder"
|
||||||
|
style="@style/SettingsHolderTextViewOneLinerStyle"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
|
<com.simplemobiletools.commons.views.MyTextView
|
||||||
|
android:id="@+id/settings_export_notes_label"
|
||||||
|
style="@style/SettingsTextLabelStyle"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:text="@string/export_notes" />
|
||||||
|
</RelativeLayout>
|
||||||
|
|
||||||
|
<RelativeLayout
|
||||||
|
android:id="@+id/settings_import_notes_holder"
|
||||||
|
style="@style/SettingsHolderTextViewOneLinerStyle"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
|
<com.simplemobiletools.commons.views.MyTextView
|
||||||
|
android:id="@+id/settings_import_notes_label"
|
||||||
|
style="@style/SettingsTextLabelStyle"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:text="@string/import_notes" />
|
||||||
|
</RelativeLayout>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
</androidx.core.widget.NestedScrollView>
|
</androidx.core.widget.NestedScrollView>
|
||||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||||
|
34
app/src/main/res/layout/dialog_export_notes.xml
Normal file
34
app/src/main/res/layout/dialog_export_notes.xml
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:id="@+id/export_notes_scrollview"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/export_notes_holder"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:paddingTop="@dimen/activity_margin">
|
||||||
|
|
||||||
|
<com.simplemobiletools.commons.views.MyTextInputLayout
|
||||||
|
android:id="@+id/export_notes_filename_hint"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginBottom="@dimen/medium_margin"
|
||||||
|
android:hint="@string/filename_without_json"
|
||||||
|
android:paddingStart="@dimen/activity_margin"
|
||||||
|
android:paddingEnd="@dimen/activity_margin">
|
||||||
|
|
||||||
|
<com.google.android.material.textfield.TextInputEditText
|
||||||
|
android:id="@+id/export_notes_filename"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:singleLine="true"
|
||||||
|
android:textCursorDrawable="@null"
|
||||||
|
android:textSize="@dimen/bigger_text_size" />
|
||||||
|
|
||||||
|
</com.simplemobiletools.commons.views.MyTextInputLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
</ScrollView>
|
@ -70,18 +70,10 @@
|
|||||||
android:id="@+id/import_folder"
|
android:id="@+id/import_folder"
|
||||||
android:title="@string/import_folder"
|
android:title="@string/import_folder"
|
||||||
app:showAsAction="never" />
|
app:showAsAction="never" />
|
||||||
<item
|
|
||||||
android:id="@+id/import_notes"
|
|
||||||
android:title="@string/import_notes"
|
|
||||||
app:showAsAction="never" />
|
|
||||||
<item
|
<item
|
||||||
android:id="@+id/export_as_file"
|
android:id="@+id/export_as_file"
|
||||||
android:title="@string/export_as_file"
|
android:title="@string/export_as_file"
|
||||||
app:showAsAction="never" />
|
app:showAsAction="never" />
|
||||||
<item
|
|
||||||
android:id="@+id/export_all_notes"
|
|
||||||
android:title="@string/export_notes"
|
|
||||||
app:showAsAction="never" />
|
|
||||||
<item
|
<item
|
||||||
android:id="@+id/print"
|
android:id="@+id/print"
|
||||||
android:title="@string/print"
|
android:title="@string/print"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user