Merge branch 'develop' into feature/DatabaseProvider

This commit is contained in:
J-Jamet
2021-08-02 18:47:10 +02:00
12 changed files with 130 additions and 80 deletions

View File

@@ -674,7 +674,10 @@ class GroupActivity : LockingActivity(),
private fun updateEntryWithSearchInfo(database: Database, entry: Entry, searchInfo: SearchInfo) {
val newEntry = Entry(entry)
newEntry.setEntryInfo(database, newEntry.getEntryInfo(database, true).apply {
newEntry.setEntryInfo(database, newEntry.getEntryInfo(database,
raw = true,
removeTemplateConfiguration = false
).apply {
saveSearchInfo(database, searchInfo)
})
updateEntry(entry, newEntry)

View File

@@ -397,10 +397,16 @@ class Entry : Node, EntryVersionedInterface<Group> {
* Retrieve generated entry info.
* If are not [raw] data, remove parameter fields and add auto generated elements in auto custom fields
*/
fun getEntryInfo(database: Database?, raw: Boolean = false): EntryInfo {
fun getEntryInfo(database: Database?,
raw: Boolean = false,
removeTemplateConfiguration: Boolean = true): EntryInfo {
val entryInfo = EntryInfo()
// Remove unwanted template fields
(database?.removeTemplateConfiguration(this) ?: this).apply {
val baseInfo = if (removeTemplateConfiguration)
database?.removeTemplateConfiguration(this) ?: this
else
this
baseInfo.apply {
if (raw)
database?.stopManageEntry(this)
else

View File

@@ -170,24 +170,18 @@ class EntryInfo : NodeInfo {
if (database?.allowEntryCustomFields() == true) {
val creditCard: CreditCard? = registerInfo.creditCard
creditCard?.let { cc ->
cc.cardholder?.let {
val v = ProtectedString(false, it)
addUniqueField(Field(TemplateField.LABEL_HOLDER, v))
}
cc.expiration?.let {
expires = true
expiryTime = DateInstant(cc.expiration.millis)
}
cc.number?.let {
val v = ProtectedString(false, it)
addUniqueField(Field(TemplateField.LABEL_NUMBER, v))
}
cc.cvv?.let {
val v = ProtectedString(true, it)
addUniqueField(Field(TemplateField.LABEL_CVV, v))
}
creditCard?.cardholder?.let {
addUniqueField(Field(TemplateField.LABEL_HOLDER, ProtectedString(false, it)))
}
creditCard?.expiration?.let {
expires = true
expiryTime = DateInstant(creditCard.expiration.millis)
}
creditCard?.number?.let {
addUniqueField(Field(TemplateField.LABEL_NUMBER, ProtectedString(false, it)))
}
creditCard?.cvv?.let {
addUniqueField(Field(TemplateField.LABEL_CVV, ProtectedString(true, it)))
}
}
}

View File

@@ -41,6 +41,8 @@ class DateTimeEditFieldView @JvmOverloads constructor(context: Context,
private var mDateTime: DateInstant = DateInstant.IN_ONE_MONTH_DATE_TIME
private var mDefault: DateInstant = DateInstant.NEVER_EXPIRES
var setOnDateClickListener: ((DateInstant) -> Unit)? = null
init {
@@ -68,7 +70,7 @@ class DateTimeEditFieldView @JvmOverloads constructor(context: Context,
DateInstant.Type.TIME -> DateInstant.IN_ONE_HOUR_TIME
}
} else {
DateInstant.NEVER_EXPIRES
mDefault
}
}
@@ -105,7 +107,7 @@ class DateTimeEditFieldView @JvmOverloads constructor(context: Context,
return if (activation)
mDateTime
else
DateInstant.NEVER_EXPIRES
mDefault
}
set(value) {
mDateTime = DateInstant(value.date, mDateTime.type)
@@ -124,7 +126,17 @@ class DateTimeEditFieldView @JvmOverloads constructor(context: Context,
mDateTime = try {
DateInstant(value)
} 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 mDateTime: DateInstant = DateInstant.IN_ONE_MONTH_DATE_TIME
private var mDefault: DateInstant = DateInstant.NEVER_EXPIRES
var setOnDateClickListener: ((DateInstant) -> Unit)? = null
init {
@@ -112,7 +114,7 @@ class DateTimeFieldView @JvmOverloads constructor(context: Context,
DateInstant.Type.TIME -> DateInstant.IN_ONE_HOUR_TIME
}
} else {
DateInstant.NEVER_EXPIRES
mDefault
}
}
@@ -124,7 +126,7 @@ class DateTimeFieldView @JvmOverloads constructor(context: Context,
return if (activation)
mDateTime
else
DateInstant.NEVER_EXPIRES
mDefault
}
set(value) {
mDateTime = DateInstant(value.date, mDateTime.type)
@@ -139,7 +141,17 @@ class DateTimeFieldView @JvmOverloads constructor(context: Context,
mDateTime = try {
DateInstant(value)
} 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 {
var label: String
var value: String
var default: String
var isFieldVisible: Boolean
}

View File

@@ -141,7 +141,8 @@ abstract class TemplateAbstractView<
templateAttribute,
Field(
templateAttribute.label,
ProtectedString(templateAttribute.protected, "")
ProtectedString(templateAttribute.protected,
templateAttribute.default)
),
fieldTag
)
@@ -233,7 +234,14 @@ abstract class TemplateAbstractView<
val indexOldItem = indexCustomFieldIdByName(field.name)
if (indexOldItem >= 0)
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
}
@@ -451,32 +459,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 {
return TemplateField.isStandardFieldName(name)
}
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 {
return mCustomFieldIds.indexOfFirst { it.label.equals(name, true) }
return mCustomFieldIds.indexOfFirst { it.field.name.equals(name, true) }
}
private fun retrieveCustomFieldsFromView(templateFieldNotEmpty: Boolean = false) {
mEntryInfo?.customFields = mCustomFieldIds.mapNotNull {
getCustomField(it.label, templateFieldNotEmpty)
getCustomField(it.field.name, templateFieldNotEmpty)
}.toMutableList()
}
protected fun getCustomField(fieldName: String): Field {
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
@@ -493,16 +518,19 @@ abstract class TemplateAbstractView<
replaceCustomField(customField, customField, focus)
} else {
val newCustomView = buildViewForCustomField(customField)
customFieldsContainerView.addView(newCustomView)
val fieldId = FieldId(customField.name,
newCustomView!!.id,
customField.protectedValue.isProtected)
val indexOldItem = indexCustomFieldIdByName(fieldId.label)
if (indexOldItem >= 0)
mCustomFieldIds.removeAt(indexOldItem)
mCustomFieldIds.add(indexOldItem, fieldId)
if (focus)
newCustomView.requestFocus()
newCustomView?.let {
customFieldsContainerView.addView(newCustomView)
val fieldId = FieldId(
newCustomView.id,
customField
)
val indexOldItem = indexCustomFieldIdByName(fieldId.field.name)
if (indexOldItem >= 0)
mCustomFieldIds.removeAt(indexOldItem)
mCustomFieldIds.add(indexOldItem, fieldId)
if (focus)
newCustomView.requestFocus()
}
true
}
} else {
@@ -536,12 +564,18 @@ abstract class TemplateAbstractView<
mCustomFieldIds.removeAt(oldPosition)
val newCustomView = buildViewForCustomField(newCustomFieldWithValue)
parentGroup.addView(newCustomView, indexInParent)
mCustomFieldIds.add(oldPosition, FieldId(newCustomFieldWithValue.name,
newCustomView!!.id,
newCustomFieldWithValue.protectedValue.isProtected))
if (focus)
newCustomView.requestFocus()
newCustomView?.let {
parentGroup.addView(newCustomView, indexInParent)
mCustomFieldIds.add(
oldPosition,
FieldId(
newCustomView.id,
newCustomFieldWithValue
)
)
if (focus)
newCustomView.requestFocus()
}
return true
}
}

View File

@@ -78,6 +78,7 @@ class TemplateEditView @JvmOverloads constructor(context: Context,
return context?.let {
TextSelectFieldView(it).apply {
setItems(templateAttribute.options.getListItems())
default = field.protectedValue.stringValue
setActionClick(templateAttribute, field, this)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
importantForAutofill = View.IMPORTANT_FOR_AUTOFILL_NO
@@ -203,20 +204,6 @@ class TemplateEditView @JvmOverloads constructor(context: Context,
}?.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) {
mTempDateTimeViewId = state.tempDateTimeViewId
}

View File

@@ -133,20 +133,6 @@ class TemplateView @JvmOverloads constructor(context: Context,
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
*/

View File

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

View File

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

View File

@@ -26,6 +26,7 @@ class TextSelectFieldView @JvmOverloads constructor(context: Context,
private var valueViewId = ViewCompat.generateViewId()
private var valueSpinnerAdapter = ValueSpinnerAdapter(context)
private var actionImageButtonId = ViewCompat.generateViewId()
private var mDefaultPosition = 0
private val labelView = AppCompatTextView(context).apply {
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
override var value: String
get() {
return valueSpinnerView.selectedItem?.toString() ?: valueSpinnerAdapter.getItem(0)
var selectedItemString = valueSpinnerView.selectedItem?.toString()
if (selectedItemString.isNullOrEmpty()) {
selectedItemString = valueSpinnerAdapter.getItem(0)
}
return selectedItemString
}
set(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?,
@DrawableRes actionImageId: Int?) {
actionImageId?.let {