Fix default list persistence

This commit is contained in:
J-Jamet
2021-08-02 17:17:00 +02:00
parent d4cd5b73bd
commit 8a2bd23c32
9 changed files with 106 additions and 59 deletions

View File

@@ -41,6 +41,8 @@ class DateTimeEditFieldView @JvmOverloads constructor(context: Context,
private var mDateTime: DateInstant = DateInstant.IN_ONE_MONTH_DATE_TIME private var mDateTime: DateInstant = DateInstant.IN_ONE_MONTH_DATE_TIME
private var mDefault: DateInstant = DateInstant.NEVER_EXPIRES
var setOnDateClickListener: ((DateInstant) -> Unit)? = null var setOnDateClickListener: ((DateInstant) -> Unit)? = null
init { init {
@@ -68,7 +70,7 @@ class DateTimeEditFieldView @JvmOverloads constructor(context: Context,
DateInstant.Type.TIME -> DateInstant.IN_ONE_HOUR_TIME DateInstant.Type.TIME -> DateInstant.IN_ONE_HOUR_TIME
} }
} else { } else {
DateInstant.NEVER_EXPIRES mDefault
} }
} }
@@ -105,7 +107,7 @@ class DateTimeEditFieldView @JvmOverloads constructor(context: Context,
return if (activation) return if (activation)
mDateTime mDateTime
else else
DateInstant.NEVER_EXPIRES mDefault
} }
set(value) { set(value) {
mDateTime = DateInstant(value.date, mDateTime.type) mDateTime = DateInstant(value.date, mDateTime.type)
@@ -124,7 +126,17 @@ class DateTimeEditFieldView @JvmOverloads constructor(context: Context,
mDateTime = try { mDateTime = try {
DateInstant(value) DateInstant(value)
} catch (e: Exception) { } catch (e: Exception) {
DateInstant.NEVER_EXPIRES mDefault
}
}
override var default: String
get() = mDefault.toString()
set(value) {
mDefault = try {
DateInstant(value)
} catch (e: Exception) {
mDefault
} }
} }

View File

@@ -44,6 +44,8 @@ class DateTimeFieldView @JvmOverloads constructor(context: Context,
private var mActivated: Boolean = false private var mActivated: Boolean = false
private var mDateTime: DateInstant = DateInstant.IN_ONE_MONTH_DATE_TIME private var mDateTime: DateInstant = DateInstant.IN_ONE_MONTH_DATE_TIME
private var mDefault: DateInstant = DateInstant.NEVER_EXPIRES
var setOnDateClickListener: ((DateInstant) -> Unit)? = null var setOnDateClickListener: ((DateInstant) -> Unit)? = null
init { init {
@@ -112,7 +114,7 @@ class DateTimeFieldView @JvmOverloads constructor(context: Context,
DateInstant.Type.TIME -> DateInstant.IN_ONE_HOUR_TIME DateInstant.Type.TIME -> DateInstant.IN_ONE_HOUR_TIME
} }
} else { } else {
DateInstant.NEVER_EXPIRES mDefault
} }
} }
@@ -124,7 +126,7 @@ class DateTimeFieldView @JvmOverloads constructor(context: Context,
return if (activation) return if (activation)
mDateTime mDateTime
else else
DateInstant.NEVER_EXPIRES mDefault
} }
set(value) { set(value) {
mDateTime = DateInstant(value.date, mDateTime.type) mDateTime = DateInstant(value.date, mDateTime.type)
@@ -139,7 +141,17 @@ class DateTimeFieldView @JvmOverloads constructor(context: Context,
mDateTime = try { mDateTime = try {
DateInstant(value) DateInstant(value)
} catch (e: Exception) { } catch (e: Exception) {
DateInstant.NEVER_EXPIRES mDefault
}
}
override var default: String
get() = mDefault.toString()
set(value) {
mDefault = try {
DateInstant(value)
} catch (e: Exception) {
mDefault
} }
} }

View File

@@ -3,5 +3,6 @@ package com.kunzisoft.keepass.view
interface GenericFieldView { interface GenericFieldView {
var label: String var label: String
var value: String var value: String
var default: String
var isFieldVisible: Boolean var isFieldVisible: Boolean
} }

View File

@@ -131,7 +131,8 @@ abstract class TemplateAbstractView<
templateAttribute, templateAttribute,
Field( Field(
templateAttribute.label, templateAttribute.label,
ProtectedString(templateAttribute.protected, "") ProtectedString(templateAttribute.protected,
templateAttribute.default)
), ),
fieldTag fieldTag
) )
@@ -223,7 +224,14 @@ abstract class TemplateAbstractView<
val indexOldItem = indexCustomFieldIdByName(field.name) val indexOldItem = indexCustomFieldIdByName(field.name)
if (indexOldItem >= 0) if (indexOldItem >= 0)
mCustomFieldIds.removeAt(indexOldItem) mCustomFieldIds.removeAt(indexOldItem)
mCustomFieldIds.add(FieldId(field.name, itemView!!.id, field.protectedValue.isProtected)) if (itemView?.id != null) {
mCustomFieldIds.add(
FieldId(
itemView.id,
field
)
)
}
} }
return itemView return itemView
} }
@@ -441,32 +449,49 @@ abstract class TemplateAbstractView<
* ------------- * -------------
*/ */
protected data class FieldId(var label: String, var viewId: Int, var protected: Boolean) protected data class FieldId(var viewId: Int, var field: Field)
private fun isStandardFieldName(name: String): Boolean { private fun isStandardFieldName(name: String): Boolean {
return TemplateField.isStandardFieldName(name) return TemplateField.isStandardFieldName(name)
} }
protected fun customFieldIdByName(name: String): FieldId? { protected fun customFieldIdByName(name: String): FieldId? {
return mCustomFieldIds.find { it.label.equals(name, true) } return mCustomFieldIds.find { it.field.name.equals(name, true) }
} }
protected fun indexCustomFieldIdByName(name: String): Int { protected fun indexCustomFieldIdByName(name: String): Int {
return mCustomFieldIds.indexOfFirst { it.label.equals(name, true) } return mCustomFieldIds.indexOfFirst { it.field.name.equals(name, true) }
} }
private fun retrieveCustomFieldsFromView(templateFieldNotEmpty: Boolean = false) { private fun retrieveCustomFieldsFromView(templateFieldNotEmpty: Boolean = false) {
mEntryInfo?.customFields = mCustomFieldIds.mapNotNull { mEntryInfo?.customFields = mCustomFieldIds.mapNotNull {
getCustomField(it.label, templateFieldNotEmpty) getCustomField(it.field.name, templateFieldNotEmpty)
}.toMutableList() }.toMutableList()
} }
protected fun getCustomField(fieldName: String): Field { protected fun getCustomField(fieldName: String): Field {
return getCustomField(fieldName, false) return getCustomField(fieldName, false)
?: Field(fieldName, ProtectedString(false, "")) ?: Field(fieldName, ProtectedString(false))
} }
protected abstract fun getCustomField(fieldName: String, templateFieldNotEmpty: Boolean): Field? protected fun getCustomField(fieldName: String, templateFieldNotEmpty: Boolean): Field? {
customFieldIdByName(fieldName)?.let { fieldId ->
val editView: View? = templateContainerView.findViewById(fieldId.viewId)
?: customFieldsContainerView.findViewById(fieldId.viewId)
if (editView is GenericFieldView) {
// Do not return field with a default value
val defaultViewValue = if (editView.value == editView.default) "" else editView.value
if (!templateFieldNotEmpty
|| (editView.tag == FIELD_CUSTOM_TAG && defaultViewValue.isNotEmpty())) {
return Field(
fieldName,
ProtectedString(fieldId.field.protectedValue.isProtected, defaultViewValue)
)
}
}
}
return null
}
/** /**
* Update a custom field or create a new one if doesn't exists, the old value is lost * Update a custom field or create a new one if doesn't exists, the old value is lost
@@ -483,16 +508,19 @@ abstract class TemplateAbstractView<
replaceCustomField(customField, customField, focus) replaceCustomField(customField, customField, focus)
} else { } else {
val newCustomView = buildViewForCustomField(customField) val newCustomView = buildViewForCustomField(customField)
customFieldsContainerView.addView(newCustomView) newCustomView?.let {
val fieldId = FieldId(customField.name, customFieldsContainerView.addView(newCustomView)
newCustomView!!.id, val fieldId = FieldId(
customField.protectedValue.isProtected) newCustomView.id,
val indexOldItem = indexCustomFieldIdByName(fieldId.label) customField
if (indexOldItem >= 0) )
mCustomFieldIds.removeAt(indexOldItem) val indexOldItem = indexCustomFieldIdByName(fieldId.field.name)
mCustomFieldIds.add(indexOldItem, fieldId) if (indexOldItem >= 0)
if (focus) mCustomFieldIds.removeAt(indexOldItem)
newCustomView.requestFocus() mCustomFieldIds.add(indexOldItem, fieldId)
if (focus)
newCustomView.requestFocus()
}
true true
} }
} else { } else {
@@ -526,12 +554,18 @@ abstract class TemplateAbstractView<
mCustomFieldIds.removeAt(oldPosition) mCustomFieldIds.removeAt(oldPosition)
val newCustomView = buildViewForCustomField(newCustomFieldWithValue) val newCustomView = buildViewForCustomField(newCustomFieldWithValue)
parentGroup.addView(newCustomView, indexInParent) newCustomView?.let {
mCustomFieldIds.add(oldPosition, FieldId(newCustomFieldWithValue.name, parentGroup.addView(newCustomView, indexInParent)
newCustomView!!.id, mCustomFieldIds.add(
newCustomFieldWithValue.protectedValue.isProtected)) oldPosition,
if (focus) FieldId(
newCustomView.requestFocus() newCustomView.id,
newCustomFieldWithValue
)
)
if (focus)
newCustomView.requestFocus()
}
return true return true
} }
} }

View File

@@ -78,6 +78,7 @@ class TemplateEditView @JvmOverloads constructor(context: Context,
return context?.let { return context?.let {
TextSelectFieldView(it).apply { TextSelectFieldView(it).apply {
setItems(templateAttribute.options.getListItems()) setItems(templateAttribute.options.getListItems())
default = field.protectedValue.stringValue
setActionClick(templateAttribute, field, this) setActionClick(templateAttribute, field, this)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
importantForAutofill = View.IMPORTANT_FOR_AUTOFILL_NO importantForAutofill = View.IMPORTANT_FOR_AUTOFILL_NO
@@ -205,20 +206,6 @@ class TemplateEditView @JvmOverloads constructor(context: Context,
}?.otpModel }?.otpModel
} }
override fun getCustomField(fieldName: String, templateFieldNotEmpty: Boolean): Field? {
customFieldIdByName(fieldName)?.let { fieldId ->
val editView: View? = templateContainerView.findViewById(fieldId.viewId)
?: customFieldsContainerView.findViewById(fieldId.viewId)
if (editView is GenericFieldView) {
if (!templateFieldNotEmpty ||
(editView.tag == FIELD_CUSTOM_TAG
&& editView.value.isNotEmpty()))
return Field(fieldName, ProtectedString(fieldId.protected, editView.value))
}
}
return null
}
override fun onRestoreEntryInstanceState(state: SavedState) { override fun onRestoreEntryInstanceState(state: SavedState) {
mTempDateTimeViewId = state.tempDateTimeViewId mTempDateTimeViewId = state.tempDateTimeViewId
} }

View File

@@ -133,20 +133,6 @@ class TemplateView @JvmOverloads constructor(context: Context,
return emptyCustomFields return emptyCustomFields
} }
override fun getCustomField(fieldName: String, templateFieldNotEmpty: Boolean): Field? {
customFieldIdByName(fieldName)?.let { fieldId ->
val editView: View? = templateContainerView.findViewById(fieldId.viewId)
?: customFieldsContainerView.findViewById(fieldId.viewId)
if (editView is GenericFieldView) {
if (!templateFieldNotEmpty ||
(editView.tag == FIELD_CUSTOM_TAG
&& editView.value.isNotEmpty()))
return Field(fieldName, ProtectedString(fieldId.protected, editView.value))
}
}
return null
}
/* /*
* OTP Runnable * OTP Runnable
*/ */

View File

@@ -122,6 +122,8 @@ class TextEditFieldView @JvmOverloads constructor(context: Context,
valueView.setText(value) valueView.setText(value)
} }
override var default: String = ""
fun setMaxChars(numberChars: Int) { fun setMaxChars(numberChars: Int) {
when { when {
numberChars <= 0 -> { numberChars <= 0 -> {

View File

@@ -88,6 +88,8 @@ class TextFieldView @JvmOverloads constructor(context: Context,
changeProtectedValueParameters() changeProtectedValueParameters()
} }
override var default: String = ""
fun setMaxChars(numberChars: Int) { fun setMaxChars(numberChars: Int) {
when { when {
numberChars <= 0 -> { numberChars <= 0 -> {

View File

@@ -26,6 +26,7 @@ class TextSelectFieldView @JvmOverloads constructor(context: Context,
private var valueViewId = ViewCompat.generateViewId() private var valueViewId = ViewCompat.generateViewId()
private var valueSpinnerAdapter = ValueSpinnerAdapter(context) private var valueSpinnerAdapter = ValueSpinnerAdapter(context)
private var actionImageButtonId = ViewCompat.generateViewId() private var actionImageButtonId = ViewCompat.generateViewId()
private var mDefaultPosition = 0
private val labelView = AppCompatTextView(context).apply { private val labelView = AppCompatTextView(context).apply {
setTextAppearance(context, R.style.KeepassDXStyle_TextAppearance_LabelTextStyle) setTextAppearance(context, R.style.KeepassDXStyle_TextAppearance_LabelTextStyle)
@@ -142,12 +143,22 @@ class TextSelectFieldView @JvmOverloads constructor(context: Context,
// To define default value and retrieve selected one // To define default value and retrieve selected one
override var value: String override var value: String
get() { get() {
return valueSpinnerView.selectedItem?.toString() ?: valueSpinnerAdapter.getItem(0) var selectedItemString = valueSpinnerView.selectedItem?.toString()
if (selectedItemString.isNullOrEmpty()) {
selectedItemString = valueSpinnerAdapter.getItem(0)
}
return selectedItemString
} }
set(value) { set(value) {
valueSpinnerView.setSelection(valueSpinnerAdapter.getPosition(value)) valueSpinnerView.setSelection(valueSpinnerAdapter.getPosition(value))
} }
override var default: String
get() = valueSpinnerAdapter.getItem(mDefaultPosition)
set(value) {
mDefaultPosition = valueSpinnerAdapter.getPosition(value)
}
override fun setOnActionClickListener(onActionClickListener: OnClickListener?, override fun setOnActionClickListener(onActionClickListener: OnClickListener?,
@DrawableRes actionImageId: Int?) { @DrawableRes actionImageId: Int?) {
actionImageId?.let { actionImageId?.let {