mirror of
https://github.com/Kunzisoft/KeePassDX.git
synced 2025-12-04 15:49:33 +01:00
Change credit card implementation
This commit is contained in:
@@ -49,7 +49,7 @@ import com.kunzisoft.keepass.database.element.Entry
|
||||
import com.kunzisoft.keepass.database.element.node.NodeId
|
||||
import com.kunzisoft.keepass.education.EntryActivityEducation
|
||||
import com.kunzisoft.keepass.magikeyboard.MagikIME
|
||||
import com.kunzisoft.keepass.model.TemplatesCustomFields
|
||||
import com.kunzisoft.keepass.database.element.template.TemplatesFields
|
||||
import com.kunzisoft.keepass.model.EntryAttachmentState
|
||||
import com.kunzisoft.keepass.model.StreamDirection
|
||||
import com.kunzisoft.keepass.otp.OtpEntryFields
|
||||
@@ -334,7 +334,7 @@ class EntryActivity : LockingActivity() {
|
||||
clipboardHelper?.timeoutCopyToClipboard(
|
||||
value.toString(),
|
||||
getString(R.string.copy_field,
|
||||
TemplatesCustomFields.getLocalizedName(applicationContext, field.name))
|
||||
TemplatesFields.getLocalizedName(applicationContext, field.name))
|
||||
)
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -41,19 +41,16 @@ import com.kunzisoft.keepass.database.element.Database
|
||||
import com.kunzisoft.keepass.database.element.DateInstant
|
||||
import com.kunzisoft.keepass.database.element.icon.IconImage
|
||||
import com.kunzisoft.keepass.database.element.security.ProtectedString
|
||||
import com.kunzisoft.keepass.database.element.template.Template
|
||||
import com.kunzisoft.keepass.database.element.template.TemplateAttribute
|
||||
import com.kunzisoft.keepass.database.element.template.TemplateAttributeAction
|
||||
import com.kunzisoft.keepass.database.element.template.TemplateAttributeType
|
||||
import com.kunzisoft.keepass.database.element.template.*
|
||||
import com.kunzisoft.keepass.education.EntryEditActivityEducation
|
||||
import com.kunzisoft.keepass.icons.IconDrawableFactory
|
||||
import com.kunzisoft.keepass.model.*
|
||||
import com.kunzisoft.keepass.model.TemplatesCustomFields.STANDARD_EXPIRATION
|
||||
import com.kunzisoft.keepass.model.TemplatesCustomFields.STANDARD_NOTES
|
||||
import com.kunzisoft.keepass.model.TemplatesCustomFields.STANDARD_PASSWORD
|
||||
import com.kunzisoft.keepass.model.TemplatesCustomFields.STANDARD_TITLE
|
||||
import com.kunzisoft.keepass.model.TemplatesCustomFields.STANDARD_URL
|
||||
import com.kunzisoft.keepass.model.TemplatesCustomFields.STANDARD_USERNAME
|
||||
import com.kunzisoft.keepass.database.element.template.TemplatesFields.STANDARD_EXPIRATION
|
||||
import com.kunzisoft.keepass.database.element.template.TemplatesFields.STANDARD_NOTES
|
||||
import com.kunzisoft.keepass.database.element.template.TemplatesFields.STANDARD_PASSWORD
|
||||
import com.kunzisoft.keepass.database.element.template.TemplatesFields.STANDARD_TITLE
|
||||
import com.kunzisoft.keepass.database.element.template.TemplatesFields.STANDARD_URL
|
||||
import com.kunzisoft.keepass.database.element.template.TemplatesFields.STANDARD_USERNAME
|
||||
import com.kunzisoft.keepass.otp.OtpEntryFields
|
||||
import com.kunzisoft.keepass.settings.PreferencesUtil
|
||||
import com.kunzisoft.keepass.view.*
|
||||
@@ -352,7 +349,7 @@ class EntryEditFragment : StylishFragment() {
|
||||
// Add an action icon if needed
|
||||
return context?.let {
|
||||
EntryEditFieldView(it).apply {
|
||||
label = TemplatesCustomFields.getLocalizedName(context, field.name)
|
||||
label = TemplatesFields.getLocalizedName(context, field.name)
|
||||
setProtection(field.protectedValue.isProtected, mHideProtectedValue)
|
||||
setValue(field.protectedValue.toString(), when (templateAttribute.type) {
|
||||
TemplateAttributeType.MULTILINE -> EntryEditFieldView.TextType.MULTI_LINE
|
||||
@@ -385,7 +382,7 @@ class EntryEditFragment : StylishFragment() {
|
||||
field: Field): View? {
|
||||
return context?.let {
|
||||
DateTimeView(it).apply {
|
||||
label = TemplatesCustomFields.getLocalizedName(context, field.name)
|
||||
label = TemplatesFields.getLocalizedName(context, field.name)
|
||||
try {
|
||||
val value = field.protectedValue.toString()
|
||||
activation = value.trim().isNotEmpty()
|
||||
@@ -525,7 +522,7 @@ class EntryEditFragment : StylishFragment() {
|
||||
private data class FieldId(var viewId: Int, var protected: Boolean)
|
||||
|
||||
private fun isStandardFieldName(name: String): Boolean {
|
||||
return TemplatesCustomFields.isStandardFieldName(name)
|
||||
return TemplatesFields.isStandardFieldName(name)
|
||||
}
|
||||
|
||||
private fun containsCustomFieldName(name: String): Boolean {
|
||||
|
||||
@@ -48,7 +48,7 @@ import com.kunzisoft.keepass.database.element.Database
|
||||
import com.kunzisoft.keepass.database.element.icon.IconImage
|
||||
import com.kunzisoft.keepass.model.EntryInfo
|
||||
import com.kunzisoft.keepass.model.SearchInfo
|
||||
import com.kunzisoft.keepass.model.TemplatesCustomFields
|
||||
import com.kunzisoft.keepass.database.element.template.TemplatesFields
|
||||
import com.kunzisoft.keepass.settings.AutofillSettingsActivity
|
||||
import com.kunzisoft.keepass.settings.PreferencesUtil
|
||||
import java.util.*
|
||||
@@ -121,36 +121,16 @@ object AutofillHelper {
|
||||
builder.setValue(passwordId, AutofillValue.forText(entryInfo.password))
|
||||
}
|
||||
|
||||
for (field in entryInfo.customFields) {
|
||||
if (field.name == TemplatesCustomFields.CREDIT_CARD_CARDHOLDER) {
|
||||
struct.ccNameId?.let { ccNameId ->
|
||||
builder.setValue(ccNameId, AutofillValue.forText(field.protectedValue.stringValue))
|
||||
}
|
||||
}
|
||||
if (field.name == TemplatesCustomFields.CREDIT_CARD_NUMBER) {
|
||||
struct.ccnId?.let { ccnId ->
|
||||
builder.setValue(ccnId, AutofillValue.forText(field.protectedValue.stringValue))
|
||||
}
|
||||
}
|
||||
if (field.name == TemplatesCustomFields.CREDIT_CARD_EXPIRATION) {
|
||||
// the database stores the expiration month and year as a String
|
||||
// of length four in the format MMYY
|
||||
if (field.protectedValue.stringValue.length != 4) continue
|
||||
|
||||
if (entryInfo.expires) {
|
||||
// get month (month in database entry is stored as String in the format MM)
|
||||
val monthString = field.protectedValue.stringValue.substring(0, 2)
|
||||
val month = monthString.toIntOrNull() ?: 0
|
||||
if (month < 1 || month > 12) continue
|
||||
|
||||
val month = entryInfo.expiryTime.getMonthInt()
|
||||
// get year (year in database entry is stored as String in the format YY)
|
||||
val yearString = field.protectedValue.stringValue.substring(2, 4)
|
||||
val year = "20$yearString".toIntOrNull() ?: 0
|
||||
if (year == 0) continue
|
||||
val year = entryInfo.expiryTime.getYearInt()
|
||||
|
||||
struct.ccExpDateId?.let {
|
||||
if (struct.isWebView) {
|
||||
// set date string as defined in https://html.spec.whatwg.org
|
||||
val dateString = "20$yearString\u002D$monthString"
|
||||
val dateString = "$year\u002D$month"
|
||||
builder.setValue(it, AutofillValue.forText(dateString))
|
||||
} else {
|
||||
val calendar = Calendar.getInstance()
|
||||
@@ -164,13 +144,13 @@ object AutofillHelper {
|
||||
}
|
||||
struct.ccExpDateMonthId?.let {
|
||||
if (struct.isWebView) {
|
||||
builder.setValue(it, AutofillValue.forText(monthString))
|
||||
builder.setValue(it, AutofillValue.forText(month.toString()))
|
||||
} else {
|
||||
if (struct.ccExpMonthOptions != null) {
|
||||
// index starts at 0
|
||||
builder.setValue(it, AutofillValue.forList(month - 1))
|
||||
} else {
|
||||
builder.setValue(it, AutofillValue.forText(monthString))
|
||||
builder.setValue(it, AutofillValue.forText(month.toString()))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -178,10 +158,10 @@ object AutofillHelper {
|
||||
var autofillValue: AutofillValue? = null
|
||||
|
||||
struct.ccExpYearOptions?.let { options ->
|
||||
var yearIndex = options.indexOf(yearString)
|
||||
var yearIndex = options.indexOf(year.toString().substring(0, 2))
|
||||
|
||||
if (yearIndex == -1) {
|
||||
yearIndex = options.indexOf("20$yearString")
|
||||
yearIndex = options.indexOf(year.toString())
|
||||
}
|
||||
if (yearIndex != -1) {
|
||||
autofillValue = AutofillValue.forList(yearIndex)
|
||||
@@ -190,11 +170,22 @@ object AutofillHelper {
|
||||
}
|
||||
|
||||
if (autofillValue == null) {
|
||||
builder.setValue(it, AutofillValue.forText("20$yearString"))
|
||||
builder.setValue(it, AutofillValue.forText(year.toString()))
|
||||
}
|
||||
}
|
||||
}
|
||||
if (field.name == TemplatesCustomFields.CREDIT_CARD_CVV) {
|
||||
for (field in entryInfo.customFields) {
|
||||
if (field.name == TemplatesFields.CREDIT_CARD_CARDHOLDER) {
|
||||
struct.ccNameId?.let { ccNameId ->
|
||||
builder.setValue(ccNameId, AutofillValue.forText(field.protectedValue.stringValue))
|
||||
}
|
||||
}
|
||||
if (field.name == TemplatesFields.CREDIT_CARD_NUMBER) {
|
||||
struct.ccnId?.let { ccnId ->
|
||||
builder.setValue(ccnId, AutofillValue.forText(field.protectedValue.stringValue))
|
||||
}
|
||||
}
|
||||
if (field.name == TemplatesFields.CREDIT_CARD_CVV) {
|
||||
struct.cvvId?.let { cvvId ->
|
||||
builder.setValue(cvvId, AutofillValue.forText(field.protectedValue.stringValue))
|
||||
}
|
||||
|
||||
@@ -91,6 +91,14 @@ class DateInstant : Parcelable {
|
||||
}
|
||||
}
|
||||
|
||||
fun getMonthInt(): Int {
|
||||
return Companion.getMonthInt(jDate)
|
||||
}
|
||||
|
||||
fun getYearInt(): Int {
|
||||
return Companion.getYearInt(jDate)
|
||||
}
|
||||
|
||||
override fun toString(): String {
|
||||
return when (type) {
|
||||
Type.DATE -> dateFormat.format(jDate)
|
||||
@@ -173,6 +181,16 @@ class DateInstant : Parcelable {
|
||||
|
||||
}
|
||||
|
||||
fun getMonthInt(date: Date): Int {
|
||||
val dateFormat = SimpleDateFormat("MM", Locale.ENGLISH)
|
||||
return dateFormat.format(date).toInt()
|
||||
}
|
||||
|
||||
fun getYearInt(date: Date): Int {
|
||||
val dateFormat = SimpleDateFormat("yyyy", Locale.ENGLISH)
|
||||
return dateFormat.format(date).toInt()
|
||||
}
|
||||
|
||||
fun getDateTimeString(resources: Resources, date: Date): String {
|
||||
return java.text.DateFormat.getDateTimeInstance(
|
||||
java.text.DateFormat.MEDIUM,
|
||||
|
||||
@@ -23,12 +23,11 @@ import android.os.ParcelUuid
|
||||
import android.os.Parcelable
|
||||
import com.kunzisoft.keepass.database.element.database.DatabaseVersioned
|
||||
import com.kunzisoft.keepass.database.element.icon.IconImage
|
||||
import com.kunzisoft.keepass.model.TemplatesCustomFields.STANDARD_EXPIRATION
|
||||
import com.kunzisoft.keepass.model.TemplatesCustomFields.STANDARD_NOTES
|
||||
import com.kunzisoft.keepass.model.TemplatesCustomFields.STANDARD_PASSWORD
|
||||
import com.kunzisoft.keepass.model.TemplatesCustomFields.STANDARD_TITLE
|
||||
import com.kunzisoft.keepass.model.TemplatesCustomFields.STANDARD_URL
|
||||
import com.kunzisoft.keepass.model.TemplatesCustomFields.STANDARD_USERNAME
|
||||
import com.kunzisoft.keepass.database.element.template.TemplatesFields.STANDARD_EXPIRATION
|
||||
import com.kunzisoft.keepass.database.element.template.TemplatesFields.STANDARD_NOTES
|
||||
import com.kunzisoft.keepass.database.element.template.TemplatesFields.STANDARD_PASSWORD
|
||||
import com.kunzisoft.keepass.database.element.template.TemplatesFields.STANDARD_URL
|
||||
import com.kunzisoft.keepass.database.element.template.TemplatesFields.STANDARD_USERNAME
|
||||
import java.util.*
|
||||
import kotlin.collections.ArrayList
|
||||
|
||||
|
||||
@@ -73,7 +73,11 @@ class TemplateEngine(private val databaseKDBX: DatabaseKDBX) {
|
||||
try {
|
||||
val attributeName = key.substring(TEMPLATE_ATTRIBUTE_TITLE_PREFIX.length)
|
||||
val attribute = getOrRetrieveAttributeFromName(attributes, attributeName)
|
||||
attribute.attribute.label = value.stringValue
|
||||
var referenceLabel = value.stringValue
|
||||
if (referenceLabel.equals(TEMPLATE_ATTRIBUTE_TITLE_EXPIRATION, true)) {
|
||||
referenceLabel = TemplatesFields.STANDARD_EXPIRATION
|
||||
}
|
||||
attribute.attribute.label = referenceLabel
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "Unable to retrieve template position", e)
|
||||
}
|
||||
@@ -154,6 +158,7 @@ class TemplateEngine(private val databaseKDBX: DatabaseKDBX) {
|
||||
private const val TEMPLATE_ENTRY_UUID = "_etm_template_uuid"
|
||||
private const val TEMPLATE_ATTRIBUTE_POSITION_PREFIX = "_etm_position"
|
||||
private const val TEMPLATE_ATTRIBUTE_TITLE_PREFIX = "_etm_title"
|
||||
private const val TEMPLATE_ATTRIBUTE_TITLE_EXPIRATION = "@exp_date"
|
||||
private const val TEMPLATE_ATTRIBUTE_TYPE_PREFIX = "_etm_type"
|
||||
private const val TEMPLATE_ATTRIBUTE_TYPE_PROTECTED = "Protected"
|
||||
private const val TEMPLATE_ATTRIBUTE_TYPE_INLINE = "Inline"
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
package com.kunzisoft.keepass.model
|
||||
package com.kunzisoft.keepass.database.element.template
|
||||
|
||||
import android.content.Context
|
||||
import com.kunzisoft.keepass.R
|
||||
|
||||
object TemplatesCustomFields {
|
||||
object TemplatesFields {
|
||||
|
||||
const val STANDARD_TITLE = "title"
|
||||
const val STANDARD_USERNAME = "username"
|
||||
@@ -14,7 +14,6 @@ object TemplatesCustomFields {
|
||||
|
||||
const val CREDIT_CARD_CARDHOLDER = "Card holder"
|
||||
const val CREDIT_CARD_NUMBER = "Number"
|
||||
const val CREDIT_CARD_EXPIRATION = "@exp_date"
|
||||
const val CREDIT_CARD_CVV = "CVV"
|
||||
private const val CREDIT_CARD_PIN = "PIN"
|
||||
|
||||
@@ -42,9 +41,10 @@ object TemplatesCustomFields {
|
||||
|
||||
CREDIT_CARD_CARDHOLDER -> context.getString(R.string.credit_card_cardholder)
|
||||
CREDIT_CARD_NUMBER -> context.getString(R.string.credit_card_number)
|
||||
CREDIT_CARD_EXPIRATION -> context.getString(R.string.credit_card_expiration)
|
||||
CREDIT_CARD_CVV -> context.getString(R.string.credit_card_security_code)
|
||||
CREDIT_CARD_PIN -> context.getString(R.string.credit_card_pin)
|
||||
|
||||
// TODO Others translations
|
||||
else -> fieldName
|
||||
}
|
||||
}
|
||||
@@ -3,8 +3,10 @@ package com.kunzisoft.keepass.model
|
||||
import android.os.Parcel
|
||||
import android.os.Parcelable
|
||||
|
||||
data class CreditCard(val cardholder: String?, val number: String?,
|
||||
val expiration: String?, val cvv: String?) : Parcelable {
|
||||
data class CreditCard(val cardholder: String?,
|
||||
val number: String?,
|
||||
val expiration: String?,
|
||||
val cvv: String?) : Parcelable {
|
||||
|
||||
constructor(parcel: Parcel) : this(
|
||||
parcel.readString(),
|
||||
@@ -20,22 +22,6 @@ data class CreditCard(val cardholder: String?, val number: String?,
|
||||
parcel.writeString(cvv)
|
||||
}
|
||||
|
||||
fun getExpirationMonth(): String {
|
||||
return if (expiration?.length == 4) {
|
||||
expiration.substring(0, 2)
|
||||
} else {
|
||||
""
|
||||
}
|
||||
}
|
||||
|
||||
fun getExpirationYear(): String {
|
||||
return if (expiration?.length == 4) {
|
||||
expiration.substring(2, 4)
|
||||
} else {
|
||||
""
|
||||
}
|
||||
}
|
||||
|
||||
override fun describeContents(): Int {
|
||||
return 0
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ import android.os.Parcelable
|
||||
import com.kunzisoft.keepass.database.element.Attachment
|
||||
import com.kunzisoft.keepass.database.element.Database
|
||||
import com.kunzisoft.keepass.database.element.security.ProtectedString
|
||||
import com.kunzisoft.keepass.database.element.template.TemplatesFields
|
||||
import com.kunzisoft.keepass.otp.OtpElement
|
||||
import com.kunzisoft.keepass.otp.OtpEntryFields
|
||||
import com.kunzisoft.keepass.otp.OtpEntryFields.OTP_TOKEN_FIELD
|
||||
@@ -166,19 +167,19 @@ class EntryInfo : NodeInfo {
|
||||
creditCard?.let { cc ->
|
||||
cc.cardholder?.let {
|
||||
val v = ProtectedString(false, it)
|
||||
addUniqueField(Field(TemplatesCustomFields.CREDIT_CARD_CARDHOLDER, v))
|
||||
addUniqueField(Field(TemplatesFields.CREDIT_CARD_CARDHOLDER, v))
|
||||
}
|
||||
cc.expiration?.let {
|
||||
val v = ProtectedString(false, it)
|
||||
addUniqueField(Field(TemplatesCustomFields.CREDIT_CARD_EXPIRATION, v))
|
||||
expires = true
|
||||
// TODO Expiration expiryTime = it
|
||||
}
|
||||
cc.number?.let {
|
||||
val v = ProtectedString(false, it)
|
||||
addUniqueField(Field(TemplatesCustomFields.CREDIT_CARD_NUMBER, v))
|
||||
addUniqueField(Field(TemplatesFields.CREDIT_CARD_NUMBER, v))
|
||||
}
|
||||
cc.cvv?.let {
|
||||
val v = ProtectedString(true, it)
|
||||
addUniqueField(Field(TemplatesCustomFields.CREDIT_CARD_CVV, v))
|
||||
addUniqueField(Field(TemplatesFields.CREDIT_CARD_CVV, v))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ import com.kunzisoft.keepass.database.element.security.ProtectedString
|
||||
import com.kunzisoft.keepass.utils.UuidUtil
|
||||
import com.kunzisoft.keepass.model.EntryAttachmentState
|
||||
import com.kunzisoft.keepass.model.StreamDirection
|
||||
import com.kunzisoft.keepass.model.TemplatesCustomFields
|
||||
import com.kunzisoft.keepass.database.element.template.TemplatesFields
|
||||
import com.kunzisoft.keepass.otp.OtpElement
|
||||
import com.kunzisoft.keepass.otp.OtpType
|
||||
import com.kunzisoft.keepass.settings.PreferencesUtil
|
||||
@@ -313,7 +313,7 @@ class EntryContentsView @JvmOverloads constructor(context: Context,
|
||||
onCopyButtonClickListener: OnClickListener?) {
|
||||
|
||||
extraFieldsListView.addView(EntryFieldView(context).apply {
|
||||
setLabel(TemplatesCustomFields.getLocalizedName(context, title))
|
||||
setLabel(TemplatesFields.getLocalizedName(context, title))
|
||||
setValue(value.toString(), value.isProtected)
|
||||
setAutoLink()
|
||||
activateCopyButton(allowCopy)
|
||||
|
||||
@@ -1,143 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
Copyright 2019 Jeremy Jamet / Kunzisoft.
|
||||
|
||||
This file is part of KeePassDX.
|
||||
|
||||
KeePassDX is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
KeePassDX is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with KeePassDX. If not, see <http://www.gnu.org/licenses/>.
|
||||
-->
|
||||
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:importantForAutofill="noExcludeDescendants"
|
||||
android:orientation="vertical"
|
||||
android:padding="@dimen/default_margin"
|
||||
tools:targetApi="o">
|
||||
|
||||
<androidx.cardview.widget.CardView
|
||||
android:id="@+id/card_view_cc_details"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:layout_margin="4dp"
|
||||
app:cardCornerRadius="4dp">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
tools:ignore="UnusedAttribute">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/creditCardholderNameLabel"
|
||||
style="@style/KeepassDXStyle.TextAppearance.LabelTextStyle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:labelFor="@+id/creditCardNumberField"
|
||||
android:text="@string/credit_card_cardholder"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/creditCardholderNameField"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:ems="10"
|
||||
android:focusedByDefault="true"
|
||||
android:hint="@string/credit_card_cardholder"
|
||||
android:inputType="textPersonName"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/creditCardholderNameLabel" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/creditCardNumberLabel"
|
||||
style="@style/KeepassDXStyle.TextAppearance.LabelTextStyle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:labelFor="@+id/creditCardNumberField"
|
||||
android:text="@string/credit_card_number"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/creditCardholderNameField" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/creditCardNumberField"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:ems="10"
|
||||
android:focusedByDefault="true"
|
||||
android:hint="@string/credit_card_number"
|
||||
android:inputType="number"
|
||||
android:maxLength="16"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/creditCardNumberLabel" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/creditCardExpirationLabel"
|
||||
style="@style/KeepassDXStyle.TextAppearance.LabelTextStyle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/credit_card_expiration"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/creditCardNumberField" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatSpinner
|
||||
android:id="@+id/expirationMonth"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:minHeight="48dp"
|
||||
app:layout_constraintEnd_toStartOf="@+id/expirationYear"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/creditCardExpirationLabel" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatSpinner
|
||||
android:id="@+id/expirationYear"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginLeft="16dp"
|
||||
android:minHeight="48dp"
|
||||
app:layout_constraintStart_toEndOf="@+id/expirationMonth"
|
||||
app:layout_constraintTop_toBottomOf="@+id/creditCardExpirationLabel" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/creditCardSecurityCodeLabel"
|
||||
style="@style/KeepassDXStyle.TextAppearance.LabelTextStyle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:labelFor="@+id/creditCardSecurityCode"
|
||||
android:text="@string/credit_card_security_code"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/expirationYear" />
|
||||
|
||||
<!-- American Express has four digits? -->
|
||||
<EditText
|
||||
android:id="@+id/creditCardSecurityCode"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignBaseline="@+id/creditCardSecurityCodeLabel"
|
||||
android:ems="6"
|
||||
android:hint="@string/credit_card_security_code"
|
||||
android:inputType="number"
|
||||
android:maxLength="4"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/creditCardSecurityCodeLabel" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</androidx.cardview.widget.CardView>
|
||||
</LinearLayout>
|
||||
</ScrollView>
|
||||
@@ -371,7 +371,6 @@
|
||||
<string name="otp_algorithm">Algorithmus</string>
|
||||
<string name="credit_card_cardholder">Karteninhaber</string>
|
||||
<string name="credit_card_number">Nummer</string>
|
||||
<string name="credit_card_expiration">Gültig bis</string>
|
||||
<string name="credit_card_security_code">Prüfnummer</string>
|
||||
<string name="entry_otp">OTP</string>
|
||||
<string name="error_invalid_OTP">Ungültiges OTP-Geheimnis.</string>
|
||||
|
||||
@@ -371,7 +371,6 @@
|
||||
<string name="otp_algorithm">Algorithme</string>
|
||||
<string name="credit_card_cardholder">Titulaire de la carte</string>
|
||||
<string name="credit_card_number">Numéros</string>
|
||||
<string name="credit_card_expiration">Expiration</string>
|
||||
<string name="credit_card_security_code">CVV</string>
|
||||
<string name="credit_card_pin">PIN</string>
|
||||
<string name="entry_otp">OTP</string>
|
||||
|
||||
@@ -101,7 +101,6 @@
|
||||
<string name="otp_algorithm">Algorithm</string>
|
||||
<string name="credit_card_cardholder">Cardholder</string>
|
||||
<string name="credit_card_number">Number</string>
|
||||
<string name="credit_card_expiration">Expiration</string>
|
||||
<string name="credit_card_security_code">CVV</string>
|
||||
<string name="credit_card_pin">PIN</string>
|
||||
<string name="entry_otp">OTP</string>
|
||||
|
||||
Reference in New Issue
Block a user