diff --git a/app/src/main/kotlin/com/simplemobiletools/notes/activities/MainActivity.kt b/app/src/main/kotlin/com/simplemobiletools/notes/activities/MainActivity.kt index 2342d014..b42f5820 100644 --- a/app/src/main/kotlin/com/simplemobiletools/notes/activities/MainActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/notes/activities/MainActivity.kt @@ -336,7 +336,7 @@ class MainActivity : SimpleActivity(), ViewPager.OnPageChangeListener { toast(R.string.invalid_file_format) } else if (file.length() > 10 * 1000 * 1000) { toast(R.string.file_too_large) - } else if (checkTitle && dbHelper.doesTitleExist(path.getFilenameFromPath())) { + } else if (checkTitle && dbHelper.doesNoteTitleExist(path.getFilenameFromPath())) { toast(R.string.title_taken) } else { onChecksPassed(file) @@ -367,7 +367,7 @@ class MainActivity : SimpleActivity(), ViewPager.OnPageChangeListener { private fun openPath(path: String) { openFile(path, false) { var title = path.getFilenameFromPath() - if (dbHelper.doesTitleExist(title)) + if (dbHelper.doesNoteTitleExist(title)) title += " (file)" val note = Note(0, title, "", TYPE_NOTE, path) diff --git a/app/src/main/kotlin/com/simplemobiletools/notes/dialogs/ImportFolderDialog.kt b/app/src/main/kotlin/com/simplemobiletools/notes/dialogs/ImportFolderDialog.kt index e072f854..60df1d00 100644 --- a/app/src/main/kotlin/com/simplemobiletools/notes/dialogs/ImportFolderDialog.kt +++ b/app/src/main/kotlin/com/simplemobiletools/notes/dialogs/ImportFolderDialog.kt @@ -44,7 +44,7 @@ class ImportFolderDialog(val activity: SimpleActivity, val path: String, val cal file.isDirectory -> false filename.isMediaFile() -> false file.length() > 10 * 1000 * 1000 -> false - activity.dbHelper.doesTitleExist(filename) -> false + activity.dbHelper.doesNoteTitleExist(filename) -> false else -> true } }.forEach { diff --git a/app/src/main/kotlin/com/simplemobiletools/notes/dialogs/NewNoteDialog.kt b/app/src/main/kotlin/com/simplemobiletools/notes/dialogs/NewNoteDialog.kt index 213d0c50..e0294dee 100644 --- a/app/src/main/kotlin/com/simplemobiletools/notes/dialogs/NewNoteDialog.kt +++ b/app/src/main/kotlin/com/simplemobiletools/notes/dialogs/NewNoteDialog.kt @@ -25,7 +25,7 @@ class NewNoteDialog(val activity: Activity, val db: DBHelper, callback: (title: val title = view.note_name.value when { title.isEmpty() -> activity.toast(R.string.no_title) - db.doesTitleExist(title) -> activity.toast(R.string.title_taken) + db.doesNoteTitleExist(title) -> activity.toast(R.string.title_taken) else -> { callback(title) dismiss() diff --git a/app/src/main/kotlin/com/simplemobiletools/notes/dialogs/RenameNoteDialog.kt b/app/src/main/kotlin/com/simplemobiletools/notes/dialogs/RenameNoteDialog.kt index c28cf766..8bde16c3 100644 --- a/app/src/main/kotlin/com/simplemobiletools/notes/dialogs/RenameNoteDialog.kt +++ b/app/src/main/kotlin/com/simplemobiletools/notes/dialogs/RenameNoteDialog.kt @@ -26,7 +26,7 @@ class RenameNoteDialog(val activity: SimpleActivity, val note: Note, callback: ( val title = view.note_name.value when { title.isEmpty() -> activity.toast(R.string.no_title) - activity.dbHelper.doesTitleExist(title) -> activity.toast(R.string.title_taken) + activity.dbHelper.doesNoteTitleExist(title) -> activity.toast(R.string.title_taken) else -> { note.title = title val path = note.path diff --git a/app/src/main/kotlin/com/simplemobiletools/notes/fragments/NoteFragment.kt b/app/src/main/kotlin/com/simplemobiletools/notes/fragments/NoteFragment.kt index b770b81d..3f201748 100644 --- a/app/src/main/kotlin/com/simplemobiletools/notes/fragments/NoteFragment.kt +++ b/app/src/main/kotlin/com/simplemobiletools/notes/fragments/NoteFragment.kt @@ -48,7 +48,7 @@ class NoteFragment : Fragment() { view = inflater.inflate(R.layout.fragment_note, container, false) as ViewGroup noteId = arguments!!.getInt(NOTE_ID) db = context!!.dbHelper - note = db.getNote(noteId) ?: return view + note = db.getNoteWithId(noteId) ?: return view retainInstance = true val layoutToInflate = if (context!!.config.enableLineWrap) R.layout.note_view_static else R.layout.note_view_horiz_scrollable diff --git a/app/src/main/kotlin/com/simplemobiletools/notes/helpers/DBHelper.kt b/app/src/main/kotlin/com/simplemobiletools/notes/helpers/DBHelper.kt index e1a64795..9a1968aa 100644 --- a/app/src/main/kotlin/com/simplemobiletools/notes/helpers/DBHelper.kt +++ b/app/src/main/kotlin/com/simplemobiletools/notes/helpers/DBHelper.kt @@ -1,5 +1,7 @@ package com.simplemobiletools.notes.helpers +import android.appwidget.AppWidgetManager +import android.content.ComponentName import android.content.ContentValues import android.content.Context import android.database.Cursor @@ -9,7 +11,9 @@ import android.database.sqlite.SQLiteOpenHelper import com.simplemobiletools.commons.extensions.getIntValue import com.simplemobiletools.commons.extensions.getStringValue import com.simplemobiletools.notes.R +import com.simplemobiletools.notes.extensions.config import com.simplemobiletools.notes.models.Note +import com.simplemobiletools.notes.models.Widget import java.io.File import java.util.* @@ -18,8 +22,9 @@ class DBHelper private constructor(private val mContext: Context) : SQLiteOpenHe companion object { private const val DB_NAME = "notes.db" - private const val DB_VERSION = 3 - private const val TABLE_NAME = "notes" + private const val DB_VERSION = 4 + private const val NOTES_TABLE_NAME = "notes" + private const val WIDGETS_TABLE_NAME = "widgets" private const val COL_ID = "id" private const val COL_TITLE = "title" @@ -27,21 +32,30 @@ class DBHelper private constructor(private val mContext: Context) : SQLiteOpenHe private const val COL_TYPE = "type" private const val COL_PATH = "path" + private const val COL_WIDGET_ID = "widget_id" + private const val COL_NOTE_ID = "note_id" + fun newInstance(context: Context) = DBHelper(context) } override fun onCreate(db: SQLiteDatabase) { - db.execSQL("CREATE TABLE $TABLE_NAME ($COL_ID INTEGER PRIMARY KEY AUTOINCREMENT, $COL_TITLE TEXT UNIQUE, $COL_VALUE TEXT, $COL_TYPE INTEGER DEFAULT 0, $COL_PATH TEXT)") + db.execSQL("CREATE TABLE $NOTES_TABLE_NAME ($COL_ID INTEGER PRIMARY KEY AUTOINCREMENT, $COL_TITLE TEXT UNIQUE, $COL_VALUE TEXT, $COL_TYPE INTEGER DEFAULT 0, $COL_PATH TEXT)") + db.execSQL("CREATE TABLE $WIDGETS_TABLE_NAME ($COL_ID INTEGER PRIMARY KEY AUTOINCREMENT, $COL_WIDGET_ID INTEGER DEFAULT 0, $COL_NOTE_ID INTEGER DEFAULT 0)") insertFirstNote(db) } override fun onUpgrade(db: SQLiteDatabase, oldVersion: Int, newVersion: Int) { if (oldVersion < 2) { - db.execSQL("ALTER TABLE $TABLE_NAME ADD COLUMN $COL_TYPE INTEGER DEFAULT 0") + db.execSQL("ALTER TABLE $NOTES_TABLE_NAME ADD COLUMN $COL_TYPE INTEGER DEFAULT 0") } if (oldVersion < 3) { - db.execSQL("ALTER TABLE $TABLE_NAME ADD COLUMN $COL_PATH TEXT DEFAULT ''") + db.execSQL("ALTER TABLE $NOTES_TABLE_NAME ADD COLUMN $COL_PATH TEXT DEFAULT ''") + } + + if (oldVersion < 4) { + db.execSQL("CREATE TABLE $WIDGETS_TABLE_NAME ($COL_ID INTEGER PRIMARY KEY AUTOINCREMENT, $COL_WIDGET_ID INTEGER DEFAULT 0, $COL_NOTE_ID INTEGER DEFAULT 0)") + insertFirstWidget(db) } } @@ -51,17 +65,36 @@ class DBHelper private constructor(private val mContext: Context) : SQLiteOpenHe insertNote(note, db) } + // if a user has exactly 1 widget active, prefill it. Can happen only at upgrading from older app versions + private fun insertFirstWidget(db: SQLiteDatabase) { + val widgetIDs = AppWidgetManager.getInstance(mContext).getAppWidgetIds(ComponentName(mContext, MyWidgetProvider::class.java)) + if (widgetIDs.size == 1) { + val widget = Widget(widgetIDs.first(), mContext.config.widgetNoteId) + insertWidget(widget, db) + } + } + private fun insertNote(note: Note, db: SQLiteDatabase) { - val values = fillContentValues(note) - db.insert(TABLE_NAME, null, values) + val values = fillNoteContentValues(note) + db.insert(NOTES_TABLE_NAME, null, values) + } + + private fun insertWidget(widget: Widget, db: SQLiteDatabase) { + val values = fillWidgetContentValues(widget) + db.insert(WIDGETS_TABLE_NAME, null, values) } fun insertNote(note: Note): Int { - val values = fillContentValues(note) - return mDb.insertWithOnConflict(TABLE_NAME, null, values, CONFLICT_IGNORE).toInt() + val values = fillNoteContentValues(note) + return mDb.insertWithOnConflict(NOTES_TABLE_NAME, null, values, CONFLICT_IGNORE).toInt() } - private fun fillContentValues(note: Note): ContentValues { + fun insertWidget(widget: Widget): Int { + val values = fillWidgetContentValues(widget) + return mDb.insertWithOnConflict(NOTES_TABLE_NAME, null, values, CONFLICT_IGNORE).toInt() + } + + private fun fillNoteContentValues(note: Note): ContentValues { return ContentValues().apply { put(COL_TITLE, note.title) put(COL_VALUE, note.value) @@ -70,17 +103,24 @@ class DBHelper private constructor(private val mContext: Context) : SQLiteOpenHe } } - fun deleteNote(id: Int) { - mDb.delete(TABLE_NAME, "$COL_ID = $id", null) + private fun fillWidgetContentValues(widget: Widget): ContentValues { + return ContentValues().apply { + put(COL_WIDGET_ID, widget.widgetId) + put(COL_NOTE_ID, widget.noteId) + } } - fun doesTitleExist(title: String): Boolean { + fun deleteNote(id: Int) { + mDb.delete(NOTES_TABLE_NAME, "$COL_ID = $id", null) + } + + fun doesNoteTitleExist(title: String): Boolean { val cols = arrayOf(COL_ID) val selection = "$COL_TITLE = ? COLLATE NOCASE" val selectionArgs = arrayOf(title) var cursor: Cursor? = null try { - cursor = mDb.query(TABLE_NAME, cols, selection, selectionArgs, null, null, null) + cursor = mDb.query(NOTES_TABLE_NAME, cols, selection, selectionArgs, null, null, null) return cursor.count == 1 } finally { cursor?.close() @@ -92,7 +132,7 @@ class DBHelper private constructor(private val mContext: Context) : SQLiteOpenHe val cols = arrayOf(COL_ID, COL_TITLE, COL_VALUE, COL_TYPE, COL_PATH) var cursor: Cursor? = null try { - cursor = mDb.query(TABLE_NAME, cols, null, null, null, null, "$COL_TITLE COLLATE NOCASE ASC") + cursor = mDb.query(NOTES_TABLE_NAME, cols, null, null, null, null, "$COL_TITLE COLLATE NOCASE ASC") if (cursor?.moveToFirst() == true) { do { try { @@ -120,14 +160,14 @@ class DBHelper private constructor(private val mContext: Context) : SQLiteOpenHe return notes } - fun getNote(id: Int): Note? { + fun getNoteWithId(id: Int): Note? { val cols = arrayOf(COL_TITLE, COL_VALUE, COL_TYPE, COL_PATH) val selection = "$COL_ID = ?" val selectionArgs = arrayOf(id.toString()) var note: Note? = null var cursor: Cursor? = null try { - cursor = mDb.query(TABLE_NAME, cols, selection, selectionArgs, null, null, null) + cursor = mDb.query(NOTES_TABLE_NAME, cols, selection, selectionArgs, null, null, null) if (cursor?.moveToFirst() == true) { val title = cursor.getStringValue(COL_TITLE) val value = cursor.getStringValue(COL_VALUE) @@ -147,7 +187,7 @@ class DBHelper private constructor(private val mContext: Context) : SQLiteOpenHe val selectionArgs = arrayOf(path) var cursor: Cursor? = null try { - cursor = mDb.query(TABLE_NAME, cols, selection, selectionArgs, null, null, null) + cursor = mDb.query(NOTES_TABLE_NAME, cols, selection, selectionArgs, null, null, null) if (cursor?.moveToFirst() == true) { return cursor.getIntValue(COL_ID) } @@ -175,7 +215,7 @@ class DBHelper private constructor(private val mContext: Context) : SQLiteOpenHe private fun updateNote(id: Int, values: ContentValues) { val selection = "$COL_ID = ?" val selectionArgs = arrayOf(id.toString()) - mDb.update(TABLE_NAME, values, selection, selectionArgs) + mDb.update(NOTES_TABLE_NAME, values, selection, selectionArgs) } fun isValidId(id: Int) = id > 0 diff --git a/app/src/main/kotlin/com/simplemobiletools/notes/models/Widget.kt b/app/src/main/kotlin/com/simplemobiletools/notes/models/Widget.kt new file mode 100644 index 00000000..e2107a0b --- /dev/null +++ b/app/src/main/kotlin/com/simplemobiletools/notes/models/Widget.kt @@ -0,0 +1,3 @@ +package com.simplemobiletools.notes.models + +data class Widget(var widgetId: Int, var noteId: Int)