mirror of
https://github.com/Kunzisoft/KeePassDX.git
synced 2025-12-04 15:49:33 +01:00
Fix default list persistence
This commit is contained in:
@@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
}
|
}
|
||||||
@@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -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 -> {
|
||||||
|
|||||||
@@ -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 -> {
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
Reference in New Issue
Block a user