Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
73e7b26
add icone visibity vector
vbernier02 Feb 3, 2025
16d2acd
read-only implementation
vbernier02 Mar 7, 2025
62fe414
Cleaning code
vbernier02 Mar 12, 2025
6b2f88a
Disable read-only button for checklists
vbernier02 Mar 17, 2025
252b7e6
debug read only
vbernier02 Mar 17, 2025
8075ded
format code and optimize imports
vbernier02 Mar 17, 2025
ba56474
cleaning
vbernier02 Mar 17, 2025
3439158
cleaning
vbernier02 Mar 17, 2025
711a296
read-only implementation (2)
vbernier02 Mar 18, 2025
02f16d0
Merge branch 'master' into master
naveensingh Mar 18, 2025
112dcd7
cMerge remote-tracking branch 'upstream/master'
vbernier02 Apr 15, 2025
aa9a2b8
Merge branch 'FossifyOrg:master' into master
vbernier02 Apr 15, 2025
a7c8fb4
Merge branch 'master' of github.com:vbernier02/Notes
vbernier02 Apr 15, 2025
89d43f3
read only v3 -bug to fix-
vbernier02 Apr 15, 2025
c0bda6d
Merge branch 'master' of github.com:vbernier02/Notes
vbernier02 Apr 15, 2025
a4bca77
read only mode functional
vbernier02 Apr 30, 2025
e22bd48
Save text and button undo redo fix
vbernier02 May 6, 2025
56b12f1
fix import
vbernier02 May 6, 2025
b8b4cf8
fix maximum line length
vbernier02 May 7, 2025
52b51f9
Merge branch 'FossifyOrg:master' into master
vbernier02 May 18, 2025
6c8783a
Merge branch 'FossifyOrg:master' into master
vbernier02 May 22, 2025
105ed4f
Merge branch 'FossifyOrg:master' into master
vbernier02 May 24, 2025
71c131e
Merge branch 'FossifyOrg:master' into master
vbernier02 May 26, 2025
b35f515
Merge branch 'FossifyOrg:master' into master
vbernier02 May 31, 2025
e5f3a05
Merge branch 'FossifyOrg:main' into master
vbernier02 Jun 7, 2025
9b78901
Merge branch 'FossifyOrg:main' into master
vbernier02 Jun 11, 2025
76582af
Merge branch 'FossifyOrg:main' into master
vbernier02 Jun 17, 2025
7226d3f
Spell check and keyboard disabled
vbernier02 Jun 17, 2025
dd1d149
Merge branch 'master' of github.com:vbernier02/Notes
vbernier02 Jun 17, 2025
d3391e6
crash long press in read-only mode
vbernier02 Jun 19, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
146 changes: 146 additions & 0 deletions app/schemas/org.fossify.notes.databases.NotesDatabase/5.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
{
"formatVersion": 1,
"database": {
"version": 5,
"identityHash": "966c9b683bea02221758ffc16bf6247c",
"entities": [
{
"tableName": "notes",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `title` TEXT NOT NULL, `value` TEXT NOT NULL, `type` INTEGER NOT NULL, `path` TEXT NOT NULL, `protection_type` INTEGER NOT NULL, `protection_hash` TEXT NOT NULL, `is_read_only` INTEGER NOT NULL)",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "title",
"columnName": "title",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "value",
"columnName": "value",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "type",
"columnName": "type",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "path",
"columnName": "path",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "protectionType",
"columnName": "protection_type",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "protectionHash",
"columnName": "protection_hash",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "isReadOnly",
"columnName": "is_read_only",
"affinity": "INTEGER",
"notNull": true
}
],
"primaryKey": {
"autoGenerate": true,
"columnNames": [
"id"
]
},
"indices": [
{
"name": "index_notes_id",
"unique": true,
"columnNames": [
"id"
],
"orders": [],
"createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_notes_id` ON `${TABLE_NAME}` (`id`)"
}
],
"foreignKeys": []
},
{
"tableName": "widgets",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `widget_id` INTEGER NOT NULL, `note_id` INTEGER NOT NULL, `widget_bg_color` INTEGER NOT NULL, `widget_text_color` INTEGER NOT NULL, `widget_show_title` INTEGER NOT NULL)",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "widgetId",
"columnName": "widget_id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "noteId",
"columnName": "note_id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "widgetBgColor",
"columnName": "widget_bg_color",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "widgetTextColor",
"columnName": "widget_text_color",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "widgetShowTitle",
"columnName": "widget_show_title",
"affinity": "INTEGER",
"notNull": true
}
],
"primaryKey": {
"autoGenerate": true,
"columnNames": [
"id"
]
},
"indices": [
{
"name": "index_widgets_widget_id",
"unique": true,
"columnNames": [
"widget_id"
],
"orders": [],
"createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_widgets_widget_id` ON `${TABLE_NAME}` (`widget_id`)"
}
],
"foreignKeys": []
}
],
"views": [],
"setupQueries": [
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '966c9b683bea02221758ffc16bf6247c')"
]
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,7 @@ class MainActivity : SimpleActivity() {
}
}

applyReadOnlyStateToCurrentNote()
refreshMenuItems()
binding.pagerTabStrip.apply {
val textSize = getPercentageFontSize()
Expand Down Expand Up @@ -255,12 +256,12 @@ class MainActivity : SimpleActivity() {

binding.mainToolbar.menu.apply {
findItem(R.id.undo).apply {
isVisible = showUndoButton && mCurrentNote.type == NoteType.TYPE_TEXT
isVisible = showUndoButton && !mCurrentNote.isReadOnly && mCurrentNote.type == NoteType.TYPE_TEXT
icon?.alpha = if (isEnabled) 255 else 127
}

findItem(R.id.redo).apply {
isVisible = showRedoButton && mCurrentNote.type == NoteType.TYPE_TEXT
isVisible = showRedoButton && !mCurrentNote.isReadOnly && mCurrentNote.type == NoteType.TYPE_TEXT
icon?.alpha = if (isEnabled) 255 else 127
}

Expand All @@ -281,6 +282,9 @@ class MainActivity : SimpleActivity() {
saveNoteButton = findItem(R.id.save_note)
saveNoteButton!!.isVisible =
!config.autosaveNotes && showSaveButton && (::mCurrentNote.isInitialized && mCurrentNote.type == NoteType.TYPE_TEXT)

findItem(R.id.preview_mode).isVisible = (::mCurrentNote.isInitialized && !mCurrentNote.isReadOnly && mCurrentNote.type != NoteType.TYPE_CHECKLIST)
findItem(R.id.edit_mode).isVisible = (::mCurrentNote.isInitialized && mCurrentNote.isReadOnly && mCurrentNote.type != NoteType.TYPE_CHECKLIST)
}

binding.pagerTabStrip.beVisibleIf(multipleNotesExist)
Expand All @@ -307,6 +311,8 @@ class MainActivity : SimpleActivity() {
R.id.cab_create_shortcut -> createShortcut()
R.id.lock_note -> lockNote()
R.id.unlock_note -> unlockNote()
R.id.preview_mode -> toggleReadOnly()
R.id.edit_mode -> toggleReadOnly()
R.id.open_file -> tryOpenFile()
R.id.import_folder -> openFolder()
R.id.export_as_file -> fragment?.handleUnlocking { tryExportAsFile() }
Expand Down Expand Up @@ -564,13 +570,15 @@ class MainActivity : SimpleActivity() {
onPageChangeListener {
mCurrentNote = mNotes[it]
config.currentNoteId = mCurrentNote.id!!
applyReadOnlyStateToCurrentNote()
refreshMenuItems()
}
}

if (!config.showKeyboard || mCurrentNote.type == NoteType.TYPE_CHECKLIST) {
hideKeyboard()
}
applyReadOnlyStateToCurrentNote()
refreshMenuItems()
}
}
Expand Down Expand Up @@ -723,6 +731,7 @@ class MainActivity : SimpleActivity() {
val index = getNoteIndexWithId(id)
binding.viewPager.currentItem = index
mCurrentNote = mNotes[index]
applyReadOnlyStateToCurrentNote()
}
}

Expand All @@ -747,6 +756,7 @@ class MainActivity : SimpleActivity() {
showRedoButton = false
initViewPager(newNoteId)
updateSelectedNote(newNoteId)
applyReadOnlyStateToCurrentNote()
binding.viewPager.onGlobalLayout {
mAdapter?.focusEditText(getNoteIndexWithId(newNoteId))
}
Expand Down Expand Up @@ -1561,4 +1571,20 @@ class MainActivity : SimpleActivity() {
updateWidgets()
}
}

private fun applyReadOnlyStateToCurrentNote() {
getCurrentFragment()?.let { fragment ->
if (fragment is TextFragment) {
fragment.updateReadOnlyState(mCurrentNote.isReadOnly)
}
}
}

private fun toggleReadOnly() {
mCurrentNote.isReadOnly = !mCurrentNote.isReadOnly
NotesHelper(this).insertOrUpdateNote(mCurrentNote) {
applyReadOnlyStateToCurrentNote()
refreshMenuItems()
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import org.fossify.notes.models.NoteType
import org.fossify.notes.models.Widget
import java.util.concurrent.Executors

@Database(entities = [Note::class, Widget::class], version = 4)
@Database(entities = [Note::class, Widget::class], version = 5)
abstract class NotesDatabase : RoomDatabase() {

abstract fun NotesDao(): NotesDao
Expand All @@ -42,6 +42,7 @@ abstract class NotesDatabase : RoomDatabase() {
.addMigrations(MIGRATION_1_2)
.addMigrations(MIGRATION_2_3)
.addMigrations(MIGRATION_3_4)
.addMigrations(MIGRATION_4_5)
.build()
db!!.openHelper.setWriteAheadLoggingEnabled(true)
}
Expand Down Expand Up @@ -85,5 +86,11 @@ abstract class NotesDatabase : RoomDatabase() {
database.execSQL("ALTER TABLE widgets ADD COLUMN widget_show_title INTEGER NOT NULL DEFAULT 0")
}
}

private val MIGRATION_4_5 = object : Migration(4, 5) {
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL("ALTER TABLE notes ADD COLUMN is_read_only INTEGER NOT NULL DEFAULT 0")
}
}
}
}
31 changes: 29 additions & 2 deletions app/src/main/kotlin/org/fossify/notes/fragments/TextFragment.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@ import android.os.Bundle
import android.text.Editable
import android.text.Selection
import android.text.TextWatcher
import android.text.method.KeyListener
import android.text.style.UnderlineSpan
import android.text.util.Linkify
import android.text.InputType
import android.util.TypedValue
import android.view.LayoutInflater
import android.view.MotionEvent
Expand All @@ -21,6 +23,7 @@ import android.widget.TextView
import androidx.viewbinding.ViewBinding
import org.fossify.commons.extensions.*
import org.fossify.commons.views.MyEditText
import org.fossify.commons.extensions.hideKeyboard
import org.fossify.notes.R
import org.fossify.notes.activities.MainActivity
import org.fossify.notes.databinding.FragmentTextBinding
Expand All @@ -47,6 +50,7 @@ class TextFragment : NoteFragment() {
private var noteId = 0L
private var touchDownX = 0f
private var moveXThreshold = 0 // make sure swiping across notes works well, do not swallow the gestures
private var initialKeyListener: KeyListener? = null

private lateinit var binding: FragmentTextBinding
private lateinit var innerBinding: ViewBinding
Expand Down Expand Up @@ -81,17 +85,17 @@ class TextFragment : NoteFragment() {
casted.textNoteView.minWidth = casted.notesHorizontalScrollview.width
}
}

initialKeyListener = noteEditText.keyListener
return binding.root
}

override fun onResume() {
super.onResume()

NotesHelper(requireActivity()).getNoteWithId(noteId) {
if (it != null) {
note = it
setupFragment()
updateReadOnlyState(note!!.isReadOnly)
}
}
}
Expand Down Expand Up @@ -123,6 +127,7 @@ class TextFragment : NoteFragment() {
super.onSaveInstanceState(outState)
if (note != null) {
outState.putString(TEXT, getCurrentNoteViewText())
outState.putBoolean("isReadOnly", note!!.isReadOnly)
}
}

Expand All @@ -132,6 +137,8 @@ class TextFragment : NoteFragment() {
skipTextUpdating = true
val newText = savedInstanceState.getString(TEXT) ?: ""
innerBinding.root.findViewById<TextView>(R.id.text_note_view).text = newText
note!!.isReadOnly = savedInstanceState.getBoolean("isReadOnly")
updateReadOnlyState(note!!.isReadOnly)
}
}

Expand Down Expand Up @@ -178,6 +185,7 @@ class TextFragment : NoteFragment() {
} else {
imeOptions.removeBit(EditorInfo.IME_FLAG_NO_PERSONALIZED_LEARNING)
}
updateReadOnlyState(note!!.isReadOnly)
}

noteEditText.setOnTouchListener { v, event ->
Expand All @@ -198,6 +206,7 @@ class TextFragment : NoteFragment() {
setWordCounter(noteEditText.text.toString())
}

updateReadOnlyState(note!!.isReadOnly)
checkLockState()
setTextWatcher()
}
Expand Down Expand Up @@ -351,4 +360,22 @@ class TextFragment : NoteFragment() {
override val noteLockedShow: TextView = it.noteLockedShow
}
}

fun updateReadOnlyState(isReadOnly: Boolean) {
noteEditText.apply {
val baseInputType = InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_FLAG_MULTI_LINE
if (isReadOnly == true) {
inputType = baseInputType or InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS
keyListener = null
requireActivity().hideKeyboard(this)
}
if (isReadOnly == false) {
inputType = baseInputType
keyListener = initialKeyListener
}
isLongClickable = true
setTextIsSelectable(true)
saveText(force = true)
}
}
}
3 changes: 2 additions & 1 deletion app/src/main/kotlin/org/fossify/notes/models/Note.kt
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ data class Note(
@ColumnInfo(name = "type") var type: NoteType,
@ColumnInfo(name = "path") var path: String,
@ColumnInfo(name = "protection_type") var protectionType: Int,
@ColumnInfo(name = "protection_hash") var protectionHash: String
@ColumnInfo(name = "protection_hash") var protectionHash: String,
@ColumnInfo(name = "is_read_only") var isReadOnly: Boolean = false
) {

fun getNoteStoredValue(context: Context): String? {
Expand Down
3 changes: 3 additions & 0 deletions app/src/main/res/drawable/ic_visibility_off_vector.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="24dp" android:height="24dp" android:viewportWidth="960" android:viewportHeight="960">
<path android:pathData="M607,333q29,29 42.5,66t9.5,76q0,15 -11,25.5T622,511q-15,0 -25.5,-10.5T586,475q5,-26 -3,-50t-25,-41q-17,-17 -41,-26t-51,-4q-15,0 -25.5,-11T430,317q0,-15 10.5,-25.5T466,281q38,-4 75,9.5t66,42.5ZM480,240q-19,0 -37,1.5t-36,5.5q-17,3 -30.5,-5T358,218q-5,-16 3.5,-31t24.5,-18q23,-5 46.5,-7t47.5,-2q137,0 250.5,72T904,426q4,8 6,16.5t2,17.5q0,9 -1.5,17.5T905,494q-18,40 -44.5,75T802,633q-12,11 -28,9t-26,-16q-10,-14 -8.5,-30.5T753,568q24,-23 44,-50t35,-58q-50,-101 -144.5,-160.5T480,240ZM480,760q-134,0 -245,-72.5T60,497q-5,-8 -7.5,-17.5T50,460q0,-10 2,-19t7,-18q20,-40 46.5,-76.5T166,280l-83,-84q-11,-12 -10.5,-28.5T84,140q11,-11 28,-11t28,11l680,680q11,11 11.5,27.5T820,876q-11,11 -28,11t-28,-11L624,738q-35,11 -71,16.5t-73,5.5ZM222,336q-29,26 -53,57t-41,67q50,101 144.5,160.5T480,680q20,0 39,-2.5t39,-5.5l-36,-38q-11,3 -21,4.5t-21,1.5q-75,0 -127.5,-52.5T300,460q0,-11 1.5,-21t4.5,-21l-84,-82ZM541,429ZM390,504Z" android:fillColor="#FFFFFFFF"/>
</vector>
3 changes: 3 additions & 0 deletions app/src/main/res/drawable/ic_visibility_vector.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="24dp" android:height="24dp" android:viewportWidth="960" android:viewportHeight="960">
<path android:pathData="M480,640q75,0 127.5,-52.5T660,460q0,-75 -52.5,-127.5T480,280q-75,0 -127.5,52.5T300,460q0,75 52.5,127.5T480,640ZM480,568q-45,0 -76.5,-31.5T372,460q0,-45 31.5,-76.5T480,352q45,0 76.5,31.5T588,460q0,45 -31.5,76.5T480,568ZM480,760q-134,0 -244.5,-72T61,498q-5,-9 -7.5,-18.5T51,460q0,-10 2.5,-19.5T61,422q64,-118 174.5,-190T480,160q134,0 244.5,72T899,422q5,9 7.5,18.5T909,460q0,10 -2.5,19.5T899,498q-64,118 -174.5,190T480,760ZM480,460ZM480,680q113,0 207.5,-59.5T832,460q-50,-101 -144.5,-160.5T480,240q-113,0 -207.5,59.5T128,460q50,101 144.5,160.5T480,680Z" android:fillColor="#FFFFFFFF"/>
</vector>
Loading
Loading