Fix custom field creation

This commit is contained in:
J-Jamet
2020-08-04 18:51:00 +02:00
parent 66a60d0357
commit c126a8eba9
6 changed files with 80 additions and 106 deletions

View File

@@ -124,8 +124,7 @@
android:configChanges="keyboardHidden" />
<activity
android:name="com.kunzisoft.keepass.activities.EntryEditActivity"
android:configChanges="keyboardHidden"
android:windowSoftInputMode="adjustPan" />
android:windowSoftInputMode="adjustResize" />
<!-- About and Settings -->
<activity
android:name="com.kunzisoft.keepass.activities.AboutActivity"

View File

@@ -28,6 +28,7 @@ import android.util.Log
import android.view.Menu
import android.view.MenuItem
import android.view.View
import android.view.WindowManager
import android.widget.DatePicker
import android.widget.TimePicker
import androidx.appcompat.app.AlertDialog
@@ -353,15 +354,19 @@ class EntryEditActivity : LockingActivity(),
EntryCustomFieldDialogFragment.getInstance().show(supportFragmentManager, "customFieldDialog")
}
override fun onNewCustomFieldApproved(label: String, name: ProtectedString) {
entryEditContentsView?.putCustomField(label, name)
scrollView?.postDelayed({
override fun onNewCustomFieldApproved(label: String) {
val customFieldView = entryEditContentsView?.putCustomField(label, ProtectedString())
window?.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE)
scrollView?.post {
//scrollView?.smoothScrollTo(0, customFieldView.bottom)
scrollView?.fullScroll(View.FOCUS_DOWN)
entryEditContentsView?.focusLastChild()
}, 500)
customFieldView?.post {
customFieldView.requestFocus()
}
}
}
override fun onNewCustomFieldCanceled(label: String, name: ProtectedString) {}
override fun onNewCustomFieldCanceled(label: String) {}
private fun setupOTP() {
// Retrieve the current otpElement if exists

View File

@@ -22,15 +22,16 @@ package com.kunzisoft.keepass.activities.dialogs
import android.app.Dialog
import android.content.Context
import android.os.Bundle
import android.view.WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE
import android.view.inputmethod.EditorInfo
import android.widget.Button
import android.widget.CompoundButton
import android.widget.TextView
import androidx.annotation.StringRes
import androidx.appcompat.app.AlertDialog
import androidx.fragment.app.DialogFragment
import com.google.android.material.textfield.TextInputLayout
import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.database.element.security.ProtectedString
class EntryCustomFieldDialogFragment: DialogFragment() {
@@ -38,8 +39,6 @@ class EntryCustomFieldDialogFragment: DialogFragment() {
private var newFieldLabelContainer: TextInputLayout? = null
private var newFieldLabel: TextView? = null
private var newFieldValue: TextView? = null
private var newFieldProtection: CompoundButton? = null
override fun onAttach(context: Context) {
super.onAttach(context)
@@ -57,23 +56,29 @@ class EntryCustomFieldDialogFragment: DialogFragment() {
val root = activity.layoutInflater.inflate(R.layout.fragment_entry_new_field, null)
newFieldLabelContainer = root?.findViewById(R.id.new_field_label_container)
newFieldLabel = root?.findViewById(R.id.new_field_label)
newFieldValue = root?.findViewById(R.id.new_field_value)
newFieldProtection = root?.findViewById(R.id.new_field_protection)
val builder = AlertDialog.Builder(activity)
builder.setView(root)
.setPositiveButton(android.R.string.ok, null)
.setNegativeButton(android.R.string.cancel) { _, _ ->
entryCustomFieldListener?.onNewCustomFieldCanceled(
newFieldLabel?.text.toString(),
ProtectedString(
newFieldProtection?.isChecked == true,
newFieldValue?.text.toString()
)
newFieldLabel?.text.toString()
)
}
val dialogCreated = builder.create()
newFieldLabel?.requestFocus()
newFieldLabel?.imeOptions = EditorInfo.IME_ACTION_DONE
newFieldLabel?.setOnEditorActionListener { _, actionId, _ ->
if (actionId == EditorInfo.IME_ACTION_DONE) {
approveIfValid()
}
false
}
dialogCreated.window?.setSoftInputMode(SOFT_INPUT_STATE_VISIBLE)
return dialogCreated
return builder.create()
}
return super.onCreateDialog(savedInstanceState)
}
@@ -86,20 +91,20 @@ class EntryCustomFieldDialogFragment: DialogFragment() {
if (d != null) {
val positiveButton = d.getButton(Dialog.BUTTON_POSITIVE) as Button
positiveButton.setOnClickListener {
if (isValid()) {
entryCustomFieldListener?.onNewCustomFieldApproved(
newFieldLabel?.text.toString(),
ProtectedString(
newFieldProtection?.isChecked == true,
newFieldValue?.text.toString()
)
)
d.dismiss()
}
approveIfValid()
}
}
}
private fun approveIfValid() {
if (isValid()) {
entryCustomFieldListener?.onNewCustomFieldApproved(
newFieldLabel?.text.toString()
)
(dialog as AlertDialog?)?.dismiss()
}
}
private fun isValid(): Boolean {
return if (newFieldLabel?.text?.toString()?.isNotEmpty() != true) {
setError(R.string.error_string_key)
@@ -117,8 +122,8 @@ class EntryCustomFieldDialogFragment: DialogFragment() {
}
interface EntryCustomFieldListener {
fun onNewCustomFieldApproved(label: String, name: ProtectedString)
fun onNewCustomFieldCanceled(label: String, name: ProtectedString)
fun onNewCustomFieldApproved(label: String)
fun onNewCustomFieldCanceled(label: String)
}
companion object {

View File

@@ -215,35 +215,36 @@ class EntryEditContentsView @JvmOverloads constructor(context: Context,
return customFieldsArray
}
/**
* Update a custom field or create a new one if doesn't exists
*/
fun putCustomField(name: String,
value: ProtectedString = ProtectedString()) {
var updateField = false
private fun getCustomFieldByLabel(label: String): EntryEditCustomField? {
for (i in 0..entryExtraFieldsContainer.childCount) {
try {
val extraFieldView = entryExtraFieldsContainer.getChildAt(i) as EntryEditCustomField?
if (extraFieldView?.label == name) {
extraFieldView.setData(name, value, fontInVisibility)
updateField = true
break
if (extraFieldView?.label == label) {
return extraFieldView
}
} catch(e: Exception) {
// Simply ignore when child view is not a custom field
}
}
if (!updateField) {
val entryEditCustomField = EntryEditCustomField(context).apply {
setData(name, value, fontInVisibility)
}
entryExtraFieldsContainer.addView(entryEditCustomField)
}
return null
}
fun focusLastChild() {
val lastChildNumber = entryExtraFieldsContainer.childCount - 1
entryExtraFieldsContainer.getChildAt(lastChildNumber).requestFocus()
/**
* Update a custom field or create a new one if doesn't exists
*/
fun putCustomField(name: String,
value: ProtectedString = ProtectedString())
: EntryEditCustomField {
var extraFieldView = getCustomFieldByLabel(name)
extraFieldView?.setData(name, value, fontInVisibility)
// Create new view if not exists
if (extraFieldView == null) {
extraFieldView = EntryEditCustomField(context).apply {
setData(name, value, fontInVisibility)
}
entryExtraFieldsContainer.addView(extraFieldView)
}
return extraFieldView
}
/**

View File

@@ -18,63 +18,27 @@
along with KeePassDX. If not, see <http://www.gnu.org/licenses/>.
-->
<RelativeLayout
<com.google.android.material.textfield.TextInputLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/new_field_label_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:importantForAutofill="noExcludeDescendants"
tools:targetApi="o">
android:paddingTop="@dimen/default_margin"
android:paddingLeft="@dimen/default_margin"
android:paddingStart="@dimen/default_margin"
android:paddingRight="@dimen/default_margin"
android:paddingEnd="@dimen/default_margin"
tools:ignore="UnusedAttribute">
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/new_field_label_container"
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/new_field_label"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="12dp"
android:paddingLeft="@dimen/default_margin"
android:paddingStart="@dimen/default_margin"
android:paddingRight="@dimen/default_margin"
android:paddingEnd="@dimen/default_margin">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/new_field_label"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/field_name"
android:importantForAccessibility="no"
android:importantForAutofill="no"
android:inputType="text"
android:maxLines="1" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/new_field_value_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="@dimen/default_margin"
android:paddingStart="@dimen/default_margin"
android:paddingRight="@dimen/default_margin"
android:paddingEnd="@dimen/default_margin"
android:layout_below="@+id/new_field_label_container">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/new_field_value"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textMultiLine"
android:importantForAccessibility="no"
android:importantForAutofill="no"
android:hint="@string/field_value" />
</com.google.android.material.textfield.TextInputLayout>
<androidx.appcompat.widget.SwitchCompat
android:id="@+id/new_field_protection"
style="@style/KeepassDXStyle.TextAppearance.Small"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:minHeight="48dp"
android:layout_below="@+id/new_field_value_container"
android:layout_centerHorizontal="true"
android:text="@string/protection" />
</RelativeLayout>
android:hint="@string/field_name"
android:importantForAccessibility="no"
android:importantForAutofill="no"
android:inputType="text"
android:maxLines="1" />
</com.google.android.material.textfield.TextInputLayout>

View File

@@ -75,13 +75,13 @@
style="@style/KeepassDXStyle.TextAppearance.Small"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:minHeight="48dp"
android:layout_marginTop="@dimen/default_margin"
android:minHeight="24dp"
android:layout_marginStart="@dimen/default_margin"
android:layout_marginLeft="@dimen/default_margin"
android:layout_marginEnd="@dimen/default_margin"
android:layout_marginRight="@dimen/default_margin"
app:layout_constraintTop_toBottomOf="@+id/entry_new_field_delete"
android:paddingBottom="@dimen/default_margin"
app:layout_constraintTop_toBottomOf="@+id/new_field_value_container"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:text="@string/protection" />