mirror of
https://github.com/Kunzisoft/KeePassDX.git
synced 2025-12-04 15:49:33 +01:00
Add not referenced fields section and encapsulate code
This commit is contained in:
@@ -25,6 +25,7 @@ import android.view.LayoutInflater
|
||||
import android.widget.CompoundButton
|
||||
import android.widget.FrameLayout
|
||||
import android.widget.TextView
|
||||
import androidx.core.view.isVisible
|
||||
import com.google.android.material.textfield.TextInputLayout
|
||||
import com.kunzisoft.keepass.R
|
||||
import com.kunzisoft.keepass.database.element.DateInstant
|
||||
@@ -32,7 +33,7 @@ import com.kunzisoft.keepass.database.element.DateInstant
|
||||
class DateTimeEditView @JvmOverloads constructor(context: Context,
|
||||
attrs: AttributeSet? = null,
|
||||
defStyle: Int = 0)
|
||||
: FrameLayout(context, attrs, defStyle) {
|
||||
: FrameLayout(context, attrs, defStyle), GenericDateTimeView {
|
||||
|
||||
private var entryExpiresLabelView: TextInputLayout
|
||||
private var entryExpiresTextView: TextView
|
||||
@@ -80,7 +81,7 @@ class DateTimeEditView @JvmOverloads constructor(context: Context,
|
||||
entryExpiresLabelView.hint = value
|
||||
}
|
||||
|
||||
var activation: Boolean
|
||||
override var activation: Boolean
|
||||
get() {
|
||||
return entryExpiresCheckBox.isChecked
|
||||
}
|
||||
@@ -96,7 +97,7 @@ class DateTimeEditView @JvmOverloads constructor(context: Context,
|
||||
assignExpiresDateText()
|
||||
}
|
||||
|
||||
var dateTime: DateInstant
|
||||
override var dateTime: DateInstant
|
||||
get() {
|
||||
return if (activation)
|
||||
mDateTime
|
||||
@@ -107,4 +108,12 @@ class DateTimeEditView @JvmOverloads constructor(context: Context,
|
||||
mDateTime = value
|
||||
assignExpiresDateText()
|
||||
}
|
||||
|
||||
override var isFieldVisible: Boolean
|
||||
get() {
|
||||
return isVisible
|
||||
}
|
||||
set(value) {
|
||||
isVisible = value
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ import java.util.*
|
||||
class DateTimeView @JvmOverloads constructor(context: Context,
|
||||
attrs: AttributeSet? = null,
|
||||
defStyle: Int = 0)
|
||||
: FrameLayout(context, attrs, defStyle) {
|
||||
: FrameLayout(context, attrs, defStyle), GenericDateTimeView {
|
||||
|
||||
private var dateTimeLabelView: TextView
|
||||
private var dateTimeValueView: TextView
|
||||
@@ -71,7 +71,7 @@ class DateTimeView @JvmOverloads constructor(context: Context,
|
||||
dateTimeLabelView.text = value
|
||||
}
|
||||
|
||||
var activation: Boolean
|
||||
override var activation: Boolean
|
||||
get() {
|
||||
return mActivated
|
||||
}
|
||||
@@ -87,7 +87,7 @@ class DateTimeView @JvmOverloads constructor(context: Context,
|
||||
assignExpiresDateText()
|
||||
}
|
||||
|
||||
var dateTime: DateInstant
|
||||
override var dateTime: DateInstant
|
||||
get() {
|
||||
return if (activation)
|
||||
mDateTime
|
||||
@@ -98,4 +98,12 @@ class DateTimeView @JvmOverloads constructor(context: Context,
|
||||
mDateTime = value
|
||||
assignExpiresDateText()
|
||||
}
|
||||
|
||||
override var isFieldVisible: Boolean
|
||||
get() {
|
||||
return isVisible
|
||||
}
|
||||
set(value) {
|
||||
isVisible = value
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ import androidx.annotation.DrawableRes
|
||||
import androidx.appcompat.widget.AppCompatImageButton
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.view.ViewCompat
|
||||
import androidx.core.view.isVisible
|
||||
import com.google.android.material.textfield.TextInputEditText
|
||||
import com.google.android.material.textfield.TextInputLayout
|
||||
import com.kunzisoft.keepass.R
|
||||
@@ -20,7 +21,7 @@ import com.kunzisoft.keepass.R
|
||||
class EntryEditFieldView @JvmOverloads constructor(context: Context,
|
||||
attrs: AttributeSet? = null,
|
||||
defStyle: Int = 0)
|
||||
: RelativeLayout(context, attrs, defStyle) {
|
||||
: RelativeLayout(context, attrs, defStyle), GenericEntryFieldView {
|
||||
|
||||
private var labelViewId = ViewCompat.generateViewId()
|
||||
private var valueViewId = ViewCompat.generateViewId()
|
||||
@@ -90,7 +91,7 @@ class EntryEditFieldView @JvmOverloads constructor(context: Context,
|
||||
}
|
||||
}
|
||||
|
||||
fun applyFontVisibility(fontInVisibility: Boolean) {
|
||||
override fun applyFontVisibility(fontInVisibility: Boolean) {
|
||||
if (fontInVisibility)
|
||||
valueView.applyFontVisibility()
|
||||
}
|
||||
@@ -112,7 +113,7 @@ class EntryEditFieldView @JvmOverloads constructor(context: Context,
|
||||
buildViews()
|
||||
}
|
||||
|
||||
var value: String
|
||||
override var value: String
|
||||
get() {
|
||||
return valueView.text?.toString() ?: ""
|
||||
}
|
||||
@@ -159,4 +160,11 @@ class EntryEditFieldView @JvmOverloads constructor(context: Context,
|
||||
actionImageButton.visibility = if (onActionClickListener == null) View.GONE else View.VISIBLE
|
||||
}
|
||||
|
||||
override var isFieldVisible: Boolean
|
||||
get() {
|
||||
return isVisible
|
||||
}
|
||||
set(value) {
|
||||
isVisible = value
|
||||
}
|
||||
}
|
||||
@@ -39,7 +39,7 @@ import com.kunzisoft.keepass.utils.UriUtil
|
||||
class EntryFieldView @JvmOverloads constructor(context: Context,
|
||||
attrs: AttributeSet? = null,
|
||||
defStyle: Int = 0)
|
||||
: LinearLayout(context, attrs, defStyle) {
|
||||
: LinearLayout(context, attrs, defStyle), GenericEntryFieldView {
|
||||
|
||||
private val labelView: TextView
|
||||
private val valueView: TextView
|
||||
@@ -57,7 +57,7 @@ class EntryFieldView @JvmOverloads constructor(context: Context,
|
||||
copyButtonView.visibility = View.GONE
|
||||
}
|
||||
|
||||
fun applyFontVisibility(fontInVisibility: Boolean) {
|
||||
override fun applyFontVisibility(fontInVisibility: Boolean) {
|
||||
if (fontInVisibility)
|
||||
valueView.applyFontVisibility()
|
||||
}
|
||||
@@ -74,7 +74,7 @@ class EntryFieldView @JvmOverloads constructor(context: Context,
|
||||
labelView.setText(labelId)
|
||||
}
|
||||
|
||||
var value: String
|
||||
override var value: String
|
||||
get() {
|
||||
return valueView.text.toString()
|
||||
}
|
||||
@@ -181,6 +181,14 @@ class EntryFieldView @JvmOverloads constructor(context: Context,
|
||||
copyButtonView.isVisible = onClickActionListener != null
|
||||
}
|
||||
|
||||
override var isFieldVisible: Boolean
|
||||
get() {
|
||||
return isVisible
|
||||
}
|
||||
set(value) {
|
||||
isVisible = value
|
||||
}
|
||||
|
||||
enum class ButtonState {
|
||||
ACTIVATE, DEACTIVATE, GONE
|
||||
}
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
package com.kunzisoft.keepass.view
|
||||
|
||||
import com.kunzisoft.keepass.database.element.DateInstant
|
||||
|
||||
interface GenericDateTimeView {
|
||||
|
||||
var activation: Boolean
|
||||
var dateTime: DateInstant
|
||||
var isFieldVisible: Boolean
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package com.kunzisoft.keepass.view
|
||||
|
||||
interface GenericEntryFieldView {
|
||||
|
||||
var value: String
|
||||
fun applyFontVisibility(fontInVisibility: Boolean)
|
||||
var isFieldVisible: Boolean
|
||||
}
|
||||
@@ -7,6 +7,7 @@ import android.os.Parcel
|
||||
import android.os.Parcelable
|
||||
import android.os.Parcelable.Creator
|
||||
import android.util.AttributeSet
|
||||
import android.util.Log
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
@@ -15,6 +16,7 @@ import android.widget.FrameLayout
|
||||
import android.widget.ImageView
|
||||
import androidx.annotation.IdRes
|
||||
import com.kunzisoft.keepass.R
|
||||
import com.kunzisoft.keepass.database.element.DateInstant
|
||||
import com.kunzisoft.keepass.database.element.Field
|
||||
import com.kunzisoft.keepass.database.element.icon.IconImage
|
||||
import com.kunzisoft.keepass.database.element.security.ProtectedString
|
||||
@@ -42,6 +44,7 @@ abstract class TemplateAbstractView @JvmOverloads constructor(context: Context,
|
||||
protected var entryIconView: ImageView
|
||||
protected var templateContainerView: ViewGroup
|
||||
protected var customFieldsContainerView: SectionView
|
||||
protected var notReferencedFieldsContainerView: SectionView
|
||||
|
||||
init {
|
||||
val inflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater?
|
||||
@@ -57,6 +60,7 @@ abstract class TemplateAbstractView @JvmOverloads constructor(context: Context,
|
||||
templateContainerView.setPadding(paddingHorizontal, paddingVertical, paddingHorizontal, paddingVertical)
|
||||
}
|
||||
customFieldsContainerView = findViewById(R.id.custom_fields_container)
|
||||
notReferencedFieldsContainerView = findViewById(R.id.not_referenced_fields_container)
|
||||
}
|
||||
|
||||
// To show icon image
|
||||
@@ -82,6 +86,7 @@ abstract class TemplateAbstractView @JvmOverloads constructor(context: Context,
|
||||
// Build each template section
|
||||
templateContainerView.removeAllViews()
|
||||
customFieldsContainerView.removeAllViews()
|
||||
notReferencedFieldsContainerView.removeAllViews()
|
||||
mCustomFieldIds.clear()
|
||||
|
||||
mTemplate?.let { template ->
|
||||
@@ -94,33 +99,7 @@ abstract class TemplateAbstractView @JvmOverloads constructor(context: Context,
|
||||
|
||||
// Build each attribute
|
||||
templateSection.attributes.forEach { templateAttribute ->
|
||||
val fieldTag: String
|
||||
when {
|
||||
templateAttribute.label.equals(TemplateField.LABEL_TITLE, true) -> {
|
||||
throw Exception("title cannot be in template attribute")
|
||||
}
|
||||
templateAttribute.label.equals(TemplateField.LABEL_USERNAME, true) -> {
|
||||
fieldTag = FIELD_USERNAME_TAG
|
||||
}
|
||||
templateAttribute.label.equals(TemplateField.LABEL_PASSWORD, true) -> {
|
||||
fieldTag = FIELD_PASSWORD_TAG
|
||||
}
|
||||
templateAttribute.label.equals(TemplateField.LABEL_URL, true) -> {
|
||||
fieldTag = FIELD_URL_TAG
|
||||
}
|
||||
templateAttribute.label.equals(
|
||||
TemplateField.LABEL_EXPIRATION,
|
||||
true
|
||||
) -> {
|
||||
fieldTag = FIELD_EXPIRES_TAG
|
||||
}
|
||||
templateAttribute.label.equals(TemplateField.LABEL_NOTES, true) -> {
|
||||
fieldTag = FIELD_NOTES_TAG
|
||||
}
|
||||
else -> {
|
||||
fieldTag = FIELD_CUSTOM_TAG
|
||||
}
|
||||
}
|
||||
val fieldTag: String = getTagFromStandardTemplateAttribute(templateAttribute)
|
||||
|
||||
val attributeView = buildViewForTemplateField(
|
||||
templateAttribute,
|
||||
@@ -139,8 +118,46 @@ abstract class TemplateAbstractView @JvmOverloads constructor(context: Context,
|
||||
}
|
||||
}
|
||||
|
||||
private fun getTagFromStandardTemplateAttribute(templateAttribute: TemplateAttribute): String {
|
||||
val fieldTag: String
|
||||
when {
|
||||
templateAttribute.label.equals(TemplateField.LABEL_TITLE, true) -> {
|
||||
throw Exception("title cannot be in template attribute")
|
||||
}
|
||||
templateAttribute.label.equals(TemplateField.LABEL_USERNAME, true) -> {
|
||||
fieldTag = FIELD_USERNAME_TAG
|
||||
}
|
||||
templateAttribute.label.equals(TemplateField.LABEL_PASSWORD, true) -> {
|
||||
fieldTag = FIELD_PASSWORD_TAG
|
||||
}
|
||||
templateAttribute.label.equals(TemplateField.LABEL_URL, true) -> {
|
||||
fieldTag = FIELD_URL_TAG
|
||||
}
|
||||
templateAttribute.label.equals(TemplateField.LABEL_EXPIRATION,true) -> {
|
||||
fieldTag = FIELD_EXPIRES_TAG
|
||||
}
|
||||
templateAttribute.label.equals(TemplateField.LABEL_NOTES, true) -> {
|
||||
fieldTag = FIELD_NOTES_TAG
|
||||
}
|
||||
else -> {
|
||||
fieldTag = FIELD_CUSTOM_TAG
|
||||
}
|
||||
}
|
||||
return fieldTag
|
||||
}
|
||||
|
||||
abstract fun buildHeader()
|
||||
|
||||
private fun buildViewForNotReferencedField(field: Field): View? {
|
||||
val standardFieldTemplateAttribute = TemplateAttribute(
|
||||
field.name,
|
||||
TemplateAttributeType.MULTILINE,
|
||||
field.protectedValue.isProtected,
|
||||
field.protectedValue.stringValue)
|
||||
val fieldTag: String = getTagFromStandardTemplateAttribute(standardFieldTemplateAttribute)
|
||||
return buildViewForTemplateField(standardFieldTemplateAttribute, field, fieldTag)
|
||||
}
|
||||
|
||||
private fun buildViewForCustomField(field: Field): View? {
|
||||
val customFieldTemplateAttribute = TemplateAttribute(
|
||||
field.name,
|
||||
@@ -204,13 +221,142 @@ abstract class TemplateAbstractView @JvmOverloads constructor(context: Context,
|
||||
|
||||
protected abstract fun populateViewsWithEntryInfo()
|
||||
|
||||
protected fun <T: GenericEntryFieldView, U: GenericDateTimeView>
|
||||
populateSpecificViewsWithEntryInfo(showEmptyFields: Boolean = true,
|
||||
actionWithEmptyCustomFields: ((List<FieldId>) -> Unit)? = null) {
|
||||
mEntryInfo?.let { entryInfo ->
|
||||
|
||||
val titleView: T? = findViewWithTag(FIELD_TITLE_TAG)
|
||||
titleView?.value = entryInfo.title
|
||||
titleView?.applyFontVisibility(mFontInVisibility)
|
||||
if (!showEmptyFields && entryInfo.title.isEmpty()) {
|
||||
titleView?.isFieldVisible = false
|
||||
}
|
||||
|
||||
val userNameView: T? = findViewWithTag(FIELD_USERNAME_TAG)
|
||||
userNameView?.value = entryInfo.username
|
||||
userNameView?.applyFontVisibility(mFontInVisibility)
|
||||
if (!showEmptyFields && entryInfo.username.isEmpty()) {
|
||||
userNameView?.isFieldVisible = false
|
||||
}
|
||||
|
||||
val passwordView: T? = findViewWithTag(FIELD_PASSWORD_TAG)
|
||||
passwordView?.value = entryInfo.password
|
||||
passwordView?.applyFontVisibility(mFontInVisibility)
|
||||
if (!showEmptyFields && entryInfo.password.isEmpty()) {
|
||||
passwordView?.isFieldVisible = false
|
||||
}
|
||||
|
||||
var urlView: T? = findViewWithTag(FIELD_URL_TAG)
|
||||
if (!showEmptyFields && entryInfo.url.isEmpty()) {
|
||||
urlView?.isFieldVisible = false
|
||||
} else if (urlView == null && entryInfo.url.isNotEmpty()) {
|
||||
urlView = buildViewForNotReferencedField(
|
||||
Field(TemplateField.LABEL_URL,
|
||||
ProtectedString(false, entryInfo.url))
|
||||
) as? T?
|
||||
urlView?.let {
|
||||
addNotReferencedView(it as View)
|
||||
}
|
||||
}
|
||||
urlView?.value = entryInfo.url
|
||||
urlView?.applyFontVisibility(mFontInVisibility)
|
||||
|
||||
val expirationView: U? = findViewWithTag(FIELD_EXPIRES_TAG)
|
||||
expirationView?.activation = entryInfo.expires
|
||||
expirationView?.dateTime = entryInfo.expiryTime
|
||||
if (!showEmptyFields && !entryInfo.expires) {
|
||||
expirationView?.isFieldVisible = false
|
||||
}
|
||||
|
||||
val notesView: T? = findViewWithTag(FIELD_NOTES_TAG)
|
||||
notesView?.value = entryInfo.notes
|
||||
notesView?.applyFontVisibility(mFontInVisibility)
|
||||
if (!showEmptyFields && entryInfo.notes.isEmpty()) {
|
||||
notesView?.isFieldVisible = false
|
||||
}
|
||||
|
||||
customFieldsContainerView.removeAllViews()
|
||||
val emptyCustomFields = mutableListOf<FieldId>().also { it.addAll(mCustomFieldIds) }
|
||||
entryInfo.customFields.forEach { customField ->
|
||||
val indexFieldViewId = indexCustomFieldIdByName(customField.name)
|
||||
if (indexFieldViewId >= 0) {
|
||||
// Template contains the custom view
|
||||
val customFieldId = mCustomFieldIds[indexFieldViewId]
|
||||
emptyCustomFields.remove(customFieldId)
|
||||
templateContainerView.findViewById<View>(customFieldId.viewId)
|
||||
?.let { customView ->
|
||||
if (customView is GenericEntryFieldView) {
|
||||
customView.value = customField.protectedValue.stringValue
|
||||
customView.applyFontVisibility(mFontInVisibility)
|
||||
} else if (customView is GenericDateTimeView) {
|
||||
try {
|
||||
customView.dateTime =
|
||||
DateInstant(customField.protectedValue.stringValue)
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "unable to populate date time view", e)
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// If template view not found, create a new custom view
|
||||
putCustomField(customField, false)
|
||||
}
|
||||
}
|
||||
actionWithEmptyCustomFields?.invoke(emptyCustomFields)
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract fun populateEntryInfoWithViews(templateFieldNotEmpty: Boolean)
|
||||
|
||||
protected fun <T: GenericEntryFieldView, U: GenericDateTimeView>
|
||||
populateSpecificEntryInfoWithViews(templateFieldNotEmpty: Boolean) {
|
||||
if (mEntryInfo == null)
|
||||
mEntryInfo = EntryInfo()
|
||||
|
||||
// Icon already populate
|
||||
|
||||
val titleView: T? = findViewWithTag(FIELD_TITLE_TAG)
|
||||
titleView?.value?.let {
|
||||
mEntryInfo?.title = it
|
||||
}
|
||||
|
||||
val userNameView: T? = findViewWithTag(FIELD_USERNAME_TAG)
|
||||
userNameView?.value?.let {
|
||||
mEntryInfo?.username = it
|
||||
}
|
||||
|
||||
val passwordView: T? = findViewWithTag(FIELD_PASSWORD_TAG)
|
||||
passwordView?.value?.let {
|
||||
mEntryInfo?.password = it
|
||||
}
|
||||
|
||||
val urlView: T? = findViewWithTag(FIELD_URL_TAG)
|
||||
urlView?.value?.let {
|
||||
mEntryInfo?.url = it
|
||||
}
|
||||
|
||||
val expirationView: U? = findViewWithTag(FIELD_EXPIRES_TAG)
|
||||
expirationView?.activation?.let {
|
||||
mEntryInfo?.expires = it
|
||||
}
|
||||
expirationView?.dateTime?.let {
|
||||
mEntryInfo?.expiryTime = it
|
||||
}
|
||||
|
||||
val notesView: T? = findViewWithTag(FIELD_NOTES_TAG)
|
||||
notesView?.value?.let {
|
||||
mEntryInfo?.notes = it
|
||||
}
|
||||
|
||||
retrieveCustomFieldsFromView(templateFieldNotEmpty)
|
||||
}
|
||||
|
||||
fun getEntryInfo(): EntryInfo {
|
||||
populateEntryInfoWithViews(true)
|
||||
return mEntryInfo ?: EntryInfo()
|
||||
}
|
||||
|
||||
abstract fun populateEntryInfoWithViews(templateFieldNotEmpty: Boolean)
|
||||
|
||||
fun reload() {
|
||||
buildTemplateAndPopulateInfo()
|
||||
}
|
||||
@@ -230,6 +376,7 @@ abstract class TemplateAbstractView @JvmOverloads constructor(context: Context,
|
||||
protected fun getFieldViewById(@IdRes viewId: Int): View? {
|
||||
return templateContainerView.findViewById(viewId)
|
||||
?: customFieldsContainerView.findViewById(viewId)
|
||||
?: notReferencedFieldsContainerView.findViewById(viewId)
|
||||
}
|
||||
|
||||
/* -------------
|
||||
@@ -347,6 +494,10 @@ abstract class TemplateAbstractView @JvmOverloads constructor(context: Context,
|
||||
retrieveCustomFieldsFromView()
|
||||
}
|
||||
|
||||
fun addNotReferencedView(view: View) {
|
||||
notReferencedFieldsContainerView.addView(view)
|
||||
}
|
||||
|
||||
fun putOtpElement(otpElement: OtpElement) {
|
||||
val otpField = OtpEntryFields.buildOtpField(otpElement,
|
||||
mEntryInfo?.title, mEntryInfo?.username)
|
||||
@@ -428,5 +579,7 @@ abstract class TemplateAbstractView @JvmOverloads constructor(context: Context,
|
||||
const val FIELD_EXPIRES_TAG = "FIELD_EXPIRES_TAG"
|
||||
const val FIELD_NOTES_TAG = "FIELD_NOTES_TAG"
|
||||
const val FIELD_CUSTOM_TAG = "FIELD_CUSTOM_TAG"
|
||||
|
||||
private val TAG = TemplateAbstractView::class.java.name
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,6 @@ package com.kunzisoft.keepass.view
|
||||
|
||||
import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import android.util.Log
|
||||
import android.view.View
|
||||
import androidx.annotation.IdRes
|
||||
import androidx.core.view.isVisible
|
||||
@@ -16,7 +15,6 @@ import com.kunzisoft.keepass.database.element.template.TemplateAttributeAction
|
||||
import com.kunzisoft.keepass.database.element.template.TemplateAttributeType
|
||||
import com.kunzisoft.keepass.database.element.template.TemplateField
|
||||
import com.kunzisoft.keepass.database.element.template.TemplateField.LABEL_TITLE
|
||||
import com.kunzisoft.keepass.model.EntryInfo
|
||||
import com.kunzisoft.keepass.otp.OtpEntryFields
|
||||
import org.joda.time.DateTime
|
||||
|
||||
@@ -191,107 +189,12 @@ class TemplateEditView @JvmOverloads constructor(context: Context,
|
||||
override fun populateViewsWithEntryInfo() {
|
||||
mEntryInfo?.let { entryInfo ->
|
||||
setIcon(entryInfo.icon)
|
||||
|
||||
val titleView: EntryEditFieldView? =
|
||||
findViewWithTag(FIELD_TITLE_TAG)
|
||||
titleView?.value = entryInfo.title
|
||||
titleView?.applyFontVisibility(mFontInVisibility)
|
||||
|
||||
val userNameView: EntryEditFieldView? =
|
||||
templateContainerView.findViewWithTag(FIELD_USERNAME_TAG)
|
||||
userNameView?.value = entryInfo.username
|
||||
userNameView?.applyFontVisibility(mFontInVisibility)
|
||||
|
||||
val passwordView: EntryEditFieldView? =
|
||||
templateContainerView.findViewWithTag(FIELD_PASSWORD_TAG)
|
||||
passwordView?.value = entryInfo.password
|
||||
passwordView?.applyFontVisibility(mFontInVisibility)
|
||||
|
||||
val urlView: EntryEditFieldView? = templateContainerView.findViewWithTag(
|
||||
FIELD_URL_TAG
|
||||
)
|
||||
urlView?.value = entryInfo.url
|
||||
urlView?.applyFontVisibility(mFontInVisibility)
|
||||
|
||||
val expirationView: DateTimeEditView? =
|
||||
templateContainerView.findViewWithTag(FIELD_EXPIRES_TAG)
|
||||
expirationView?.activation = entryInfo.expires
|
||||
expirationView?.dateTime = entryInfo.expiryTime
|
||||
|
||||
val notesView: EntryEditFieldView? =
|
||||
templateContainerView.findViewWithTag(FIELD_NOTES_TAG)
|
||||
notesView?.value = entryInfo.notes
|
||||
notesView?.applyFontVisibility(mFontInVisibility)
|
||||
|
||||
customFieldsContainerView.removeAllViews()
|
||||
entryInfo.customFields.forEach { customField ->
|
||||
val indexFieldViewId = indexCustomFieldIdByName(customField.name)
|
||||
if (indexFieldViewId >= 0) {
|
||||
// Template contains the custom view
|
||||
val customFieldId = mCustomFieldIds[indexFieldViewId]
|
||||
templateContainerView.findViewById<View>(customFieldId.viewId)
|
||||
?.let { customView ->
|
||||
if (customView is EntryEditFieldView) {
|
||||
customView.value = customField.protectedValue.stringValue
|
||||
customView.applyFontVisibility(mFontInVisibility)
|
||||
} else if (customView is DateTimeEditView) {
|
||||
try {
|
||||
customView.dateTime =
|
||||
DateInstant(customField.protectedValue.stringValue)
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "unable to populate date time view", e)
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// If template view not found, create a new custom view
|
||||
putCustomField(customField, false)
|
||||
}
|
||||
}
|
||||
}
|
||||
populateSpecificViewsWithEntryInfo<EntryEditFieldView, DateTimeEditView>(true)
|
||||
}
|
||||
|
||||
override fun populateEntryInfoWithViews(templateFieldNotEmpty: Boolean) {
|
||||
if (mEntryInfo == null)
|
||||
mEntryInfo = EntryInfo()
|
||||
|
||||
// Icon already populate
|
||||
|
||||
val titleView: EntryEditFieldView? = findViewWithTag(FIELD_TITLE_TAG)
|
||||
titleView?.value?.let {
|
||||
mEntryInfo?.title = it
|
||||
}
|
||||
|
||||
val userNameView: EntryEditFieldView? = templateContainerView.findViewWithTag(FIELD_USERNAME_TAG)
|
||||
userNameView?.value?.let {
|
||||
mEntryInfo?.username = it
|
||||
}
|
||||
|
||||
val passwordView: EntryEditFieldView? = templateContainerView.findViewWithTag(FIELD_PASSWORD_TAG)
|
||||
passwordView?.value?.let {
|
||||
mEntryInfo?.password = it
|
||||
}
|
||||
|
||||
val urlView: EntryEditFieldView? = templateContainerView.findViewWithTag(FIELD_URL_TAG)
|
||||
urlView?.value?.let {
|
||||
mEntryInfo?.url = it
|
||||
}
|
||||
|
||||
val expirationView: DateTimeEditView? = templateContainerView.findViewWithTag(FIELD_EXPIRES_TAG)
|
||||
expirationView?.activation?.let {
|
||||
mEntryInfo?.expires = it
|
||||
}
|
||||
expirationView?.dateTime?.let {
|
||||
mEntryInfo?.expiryTime = it
|
||||
}
|
||||
|
||||
val notesView: EntryEditFieldView? = templateContainerView.findViewWithTag(FIELD_NOTES_TAG)
|
||||
notesView?.value?.let {
|
||||
mEntryInfo?.notes = it
|
||||
}
|
||||
|
||||
retrieveCustomFieldsFromView(templateFieldNotEmpty)
|
||||
|
||||
populateSpecificEntryInfoWithViews<EntryEditFieldView, DateTimeEditView>(templateFieldNotEmpty)
|
||||
mEntryInfo?.otpModel = OtpEntryFields.parseFields { key ->
|
||||
getCustomField(key).protectedValue.toString()
|
||||
}?.otpModel
|
||||
@@ -325,8 +228,4 @@ class TemplateEditView @JvmOverloads constructor(context: Context,
|
||||
override fun onSaveEntryInstanceState(savedState: SavedState) {
|
||||
savedState.tempDateTimeViewId = this.mTempDateTimeViewId
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val TAG = TemplateEditView::class.java.name
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,6 @@ package com.kunzisoft.keepass.view
|
||||
|
||||
import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import android.util.Log
|
||||
import android.view.View
|
||||
import androidx.core.view.isVisible
|
||||
import com.kunzisoft.keepass.R
|
||||
@@ -12,7 +11,6 @@ import com.kunzisoft.keepass.database.element.security.ProtectedString
|
||||
import com.kunzisoft.keepass.database.element.template.TemplateAttribute
|
||||
import com.kunzisoft.keepass.database.element.template.TemplateAttributeType
|
||||
import com.kunzisoft.keepass.database.element.template.TemplateField
|
||||
import com.kunzisoft.keepass.model.EntryInfo
|
||||
import com.kunzisoft.keepass.model.OtpModel
|
||||
import com.kunzisoft.keepass.otp.OtpElement
|
||||
import com.kunzisoft.keepass.otp.OtpEntryFields.OTP_TOKEN_FIELD
|
||||
@@ -123,91 +121,15 @@ class TemplateView @JvmOverloads constructor(context: Context,
|
||||
}
|
||||
|
||||
override fun populateViewsWithEntryInfo() {
|
||||
mEntryInfo?.let { entryInfo ->
|
||||
|
||||
val titleView: EntryFieldView? =
|
||||
findViewWithTag(FIELD_TITLE_TAG)
|
||||
titleView?.value = entryInfo.title
|
||||
titleView?.applyFontVisibility(mFontInVisibility)
|
||||
if (entryInfo.title.isEmpty()) {
|
||||
titleView?.isVisible = false
|
||||
}
|
||||
|
||||
val userNameView: EntryFieldView? =
|
||||
templateContainerView.findViewWithTag(FIELD_USERNAME_TAG)
|
||||
userNameView?.value = entryInfo.username
|
||||
userNameView?.applyFontVisibility(mFontInVisibility)
|
||||
if (entryInfo.username.isEmpty()) {
|
||||
userNameView?.isVisible = false
|
||||
}
|
||||
|
||||
val passwordView: EntryFieldView? =
|
||||
templateContainerView.findViewWithTag(FIELD_PASSWORD_TAG)
|
||||
passwordView?.value = entryInfo.password
|
||||
passwordView?.applyFontVisibility(mFontInVisibility)
|
||||
if (entryInfo.password.isEmpty()) {
|
||||
passwordView?.isVisible = false
|
||||
}
|
||||
|
||||
val urlView: EntryFieldView? = templateContainerView.findViewWithTag(
|
||||
FIELD_URL_TAG
|
||||
)
|
||||
urlView?.value = entryInfo.url
|
||||
urlView?.applyFontVisibility(mFontInVisibility)
|
||||
if (entryInfo.url.isEmpty()) {
|
||||
urlView?.isVisible = false
|
||||
}
|
||||
|
||||
val expirationView: DateTimeView? =
|
||||
templateContainerView.findViewWithTag(FIELD_EXPIRES_TAG)
|
||||
expirationView?.activation = entryInfo.expires
|
||||
expirationView?.dateTime = entryInfo.expiryTime
|
||||
if (!entryInfo.expires) {
|
||||
expirationView?.isVisible = false
|
||||
}
|
||||
|
||||
val notesView: EntryFieldView? =
|
||||
templateContainerView.findViewWithTag(FIELD_NOTES_TAG)
|
||||
notesView?.value = entryInfo.notes
|
||||
notesView?.applyFontVisibility(mFontInVisibility)
|
||||
if (entryInfo.notes.isEmpty()) {
|
||||
notesView?.isVisible = false
|
||||
}
|
||||
|
||||
customFieldsContainerView.removeAllViews()
|
||||
val emptyCustomFields = mutableListOf<FieldId>().also { it.addAll(mCustomFieldIds) }
|
||||
entryInfo.customFields.forEach { customField ->
|
||||
val indexFieldViewId = indexCustomFieldIdByName(customField.name)
|
||||
if (indexFieldViewId >= 0) {
|
||||
// Template contains the custom view
|
||||
val customFieldId = mCustomFieldIds[indexFieldViewId]
|
||||
emptyCustomFields.remove(customFieldId)
|
||||
templateContainerView.findViewById<View>(customFieldId.viewId)
|
||||
?.let { customView ->
|
||||
if (customView is EntryFieldView) {
|
||||
customView.value = customField.protectedValue.stringValue
|
||||
customView.applyFontVisibility(mFontInVisibility)
|
||||
} else if (customView is DateTimeView) {
|
||||
try {
|
||||
customView.dateTime =
|
||||
DateInstant(customField.protectedValue.stringValue)
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "unable to populate date time view", e)
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// If template view not found, create a new custom view
|
||||
putCustomField(customField, false)
|
||||
}
|
||||
}
|
||||
|
||||
populateSpecificViewsWithEntryInfo<EntryFieldView, DateTimeView>(false) { emptyCustomFields ->
|
||||
// Hide empty custom fields
|
||||
emptyCustomFields.forEach { customFieldId ->
|
||||
templateContainerView.findViewById<View>(customFieldId.viewId)
|
||||
.isVisible = false
|
||||
}
|
||||
}
|
||||
|
||||
mEntryInfo?.let { entryInfo ->
|
||||
// Assign specific OTP dynamic view
|
||||
removeOtpRunnable()
|
||||
entryInfo.otpModel?.let {
|
||||
@@ -217,45 +139,7 @@ class TemplateView @JvmOverloads constructor(context: Context,
|
||||
}
|
||||
|
||||
override fun populateEntryInfoWithViews(templateFieldNotEmpty: Boolean) {
|
||||
if (mEntryInfo == null)
|
||||
mEntryInfo = EntryInfo()
|
||||
|
||||
// Icon already populate
|
||||
|
||||
val titleView: EntryFieldView? = findViewWithTag(FIELD_TITLE_TAG)
|
||||
titleView?.value?.let {
|
||||
mEntryInfo?.title = it
|
||||
}
|
||||
|
||||
val userNameView: EntryFieldView? = templateContainerView.findViewWithTag(FIELD_USERNAME_TAG)
|
||||
userNameView?.value?.let {
|
||||
mEntryInfo?.username = it
|
||||
}
|
||||
|
||||
val passwordView: EntryFieldView? = templateContainerView.findViewWithTag(FIELD_PASSWORD_TAG)
|
||||
passwordView?.value?.let {
|
||||
mEntryInfo?.password = it
|
||||
}
|
||||
|
||||
val urlView: EntryFieldView? = templateContainerView.findViewWithTag(FIELD_URL_TAG)
|
||||
urlView?.value?.let {
|
||||
mEntryInfo?.url = it
|
||||
}
|
||||
|
||||
val expirationView: DateTimeView? = templateContainerView.findViewWithTag(FIELD_EXPIRES_TAG)
|
||||
expirationView?.activation?.let {
|
||||
mEntryInfo?.expires = it
|
||||
}
|
||||
expirationView?.dateTime?.let {
|
||||
mEntryInfo?.expiryTime = it
|
||||
}
|
||||
|
||||
val notesView: EntryFieldView? = templateContainerView.findViewWithTag(FIELD_NOTES_TAG)
|
||||
notesView?.value?.let {
|
||||
mEntryInfo?.notes = it
|
||||
}
|
||||
|
||||
retrieveCustomFieldsFromView(templateFieldNotEmpty)
|
||||
populateSpecificEntryInfoWithViews<EntryFieldView, DateTimeView>(templateFieldNotEmpty)
|
||||
}
|
||||
|
||||
override fun getCustomField(fieldName: String, templateFieldNotEmpty: Boolean): Field? {
|
||||
@@ -339,8 +223,4 @@ class TemplateView @JvmOverloads constructor(context: Context,
|
||||
mLastOtpTokenView?.removeCallbacks(mOtpRunnable)
|
||||
mLastOtpTokenView = null
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val TAG = TemplateEditView::class.java.name
|
||||
}
|
||||
}
|
||||
@@ -62,16 +62,24 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintTop_toBottomOf="@+id/entry_edit_header_container"
|
||||
app:layout_constraintBottom_toTopOf="@+id/custom_fields_container"
|
||||
app:layout_constraintBottom_toTopOf="@+id/not_referenced_fields_container"
|
||||
android:orientation="vertical" />
|
||||
|
||||
<com.kunzisoft.keepass.view.SectionView
|
||||
android:id="@+id/not_referenced_fields_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
style="?attr/cardViewStyle"
|
||||
android:layout_marginBottom="@dimen/card_view_margin_vertical"
|
||||
app:layout_constraintTop_toBottomOf="@+id/template_fields_container"
|
||||
app:layout_constraintBottom_toTopOf="@+id/custom_fields_container"/>
|
||||
|
||||
<com.kunzisoft.keepass.view.SectionView
|
||||
android:id="@+id/custom_fields_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
style="?attr/cardViewStyle"
|
||||
android:layout_marginBottom="@dimen/card_view_margin_vertical"
|
||||
app:layout_constraintTop_toBottomOf="@+id/template_fields_container"
|
||||
app:layout_constraintTop_toBottomOf="@+id/not_referenced_fields_container"
|
||||
app:layout_constraintBottom_toBottomOf="parent"/>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
Reference in New Issue
Block a user