mirror of
https://github.com/Kunzisoft/KeePassDX.git
synced 2025-12-04 15:49:33 +01:00
Fix attachments deletion and change entry edit layout
This commit is contained in:
@@ -332,22 +332,16 @@ class EntryActivity : LockingActivity() {
|
||||
entryContentsView?.setHiddenPasswordStyle(!mShowPassword)
|
||||
|
||||
// Manage attachments
|
||||
val attachments = entry.getAttachments()
|
||||
val showAttachmentsView = attachments.isNotEmpty()
|
||||
entryContentsView?.showAttachments(showAttachmentsView)
|
||||
if (showAttachmentsView) {
|
||||
entryContentsView?.assignAttachments(attachments)
|
||||
entryContentsView?.onAttachmentClick { attachmentItem, _ ->
|
||||
when (attachmentItem.downloadState) {
|
||||
AttachmentState.NULL, AttachmentState.ERROR, AttachmentState.COMPLETE -> {
|
||||
createDocument(this, attachmentItem.name)?.let { requestCode ->
|
||||
mAttachmentsToDownload[requestCode] = attachmentItem
|
||||
}
|
||||
}
|
||||
else -> {
|
||||
// TODO Stop download
|
||||
entryContentsView?.assignAttachments(entry.getAttachments()) { attachmentItem ->
|
||||
when (attachmentItem.downloadState) {
|
||||
AttachmentState.NULL, AttachmentState.ERROR, AttachmentState.COMPLETE -> {
|
||||
createDocument(this, attachmentItem.name)?.let { requestCode ->
|
||||
mAttachmentsToDownload[requestCode] = attachmentItem
|
||||
}
|
||||
}
|
||||
else -> {
|
||||
// TODO Stop download
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -301,10 +301,9 @@ class EntryEditActivity : LockingActivity(),
|
||||
assignExtraFields(newEntry.customFields.mapTo(ArrayList()) {
|
||||
Field(it.key, it.value)
|
||||
})
|
||||
assignAttachments(newEntry.getAttachments())
|
||||
onAttachmentDeleted { attachment, _ ->
|
||||
assignAttachments(newEntry.getAttachments(), { attachment ->
|
||||
newEntry.removeAttachment(attachment)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -32,14 +32,17 @@ import com.kunzisoft.keepass.database.element.Database
|
||||
import com.kunzisoft.keepass.database.element.database.CompressionAlgorithm
|
||||
import com.kunzisoft.keepass.model.AttachmentState
|
||||
import com.kunzisoft.keepass.model.EntryAttachment
|
||||
import com.kunzisoft.keepass.view.collapse
|
||||
|
||||
class EntryAttachmentsAdapter(val context: Context, private val editable: Boolean)
|
||||
: RecyclerView.Adapter<EntryAttachmentsAdapter.EntryBinariesViewHolder>() {
|
||||
|
||||
private val inflater: LayoutInflater = LayoutInflater.from(context)
|
||||
var entryAttachmentsList: MutableList<EntryAttachment> = ArrayList()
|
||||
var onItemClickListener: ((item: EntryAttachment, position: Int)->Unit)? = null
|
||||
var onDeleteListener: ((item: EntryAttachment, position: Int)->Unit)? = null
|
||||
var onItemClickListener: ((item: EntryAttachment)->Unit)? = null
|
||||
var onDeleteListener: ((item: EntryAttachment, lastOne: Boolean)->Unit)? = null
|
||||
|
||||
private var mAttachmentToRemove: EntryAttachment? = null
|
||||
|
||||
private val mDatabase = Database.getInstance()
|
||||
|
||||
@@ -67,9 +70,16 @@ class EntryAttachmentsAdapter(val context: Context, private val editable: Boolea
|
||||
holder.binaryFileProgressContainer.visibility = View.GONE
|
||||
holder.binaryFileDeleteButton.apply {
|
||||
visibility = View.VISIBLE
|
||||
setOnClickListener {
|
||||
onDeleteListener?.invoke(entryAttachment, position)
|
||||
deleteAttachment(entryAttachment)
|
||||
if (mAttachmentToRemove == entryAttachment) {
|
||||
holder.itemView.collapse(true) {
|
||||
deleteAttachment(entryAttachment)
|
||||
}
|
||||
setOnClickListener(null)
|
||||
} else {
|
||||
setOnClickListener {
|
||||
mAttachmentToRemove = entryAttachment
|
||||
notifyItemChanged(position)
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -83,7 +93,7 @@ class EntryAttachmentsAdapter(val context: Context, private val editable: Boolea
|
||||
progress = entryAttachment.downloadProgression
|
||||
}
|
||||
holder.itemView.setOnClickListener {
|
||||
onItemClickListener?.invoke(entryAttachment, position)
|
||||
onItemClickListener?.invoke(entryAttachment)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -100,13 +110,17 @@ class EntryAttachmentsAdapter(val context: Context, private val editable: Boolea
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
|
||||
fun deleteAttachment(attachment: EntryAttachment) {
|
||||
private fun deleteAttachment(attachment: EntryAttachment) {
|
||||
val position = entryAttachmentsList.indexOf(attachment)
|
||||
if (position >= 0) {
|
||||
entryAttachmentsList.removeAt(position)
|
||||
notifyItemRemoved(position)
|
||||
onDeleteListener?.invoke(attachment, entryAttachmentsList.isEmpty())
|
||||
mAttachmentToRemove = null
|
||||
for (i in 0 until entryAttachmentsList.size) {
|
||||
notifyItemChanged(i)
|
||||
}
|
||||
}
|
||||
// TODO Animation
|
||||
}
|
||||
|
||||
fun updateProgress(entryAttachment: EntryAttachment) {
|
||||
|
||||
@@ -75,8 +75,8 @@ class EntryContentsView @JvmOverloads constructor(context: Context,
|
||||
private val notesContainerView: View
|
||||
private val notesView: TextView
|
||||
|
||||
private val extrasContainerView: View
|
||||
private val extrasView: ViewGroup
|
||||
private val entryExtraFieldsContainerParent: View
|
||||
private val entryExtraFieldsContainer: ViewGroup
|
||||
|
||||
private val creationDateView: TextView
|
||||
private val modificationDateView: TextView
|
||||
@@ -124,8 +124,8 @@ class EntryContentsView @JvmOverloads constructor(context: Context,
|
||||
notesContainerView = findViewById(R.id.entry_notes_container)
|
||||
notesView = findViewById(R.id.entry_notes)
|
||||
|
||||
extrasContainerView = findViewById(R.id.extra_strings_container)
|
||||
extrasView = findViewById(R.id.extra_strings)
|
||||
entryExtraFieldsContainerParent = findViewById(R.id.extra_fields_container_parent)
|
||||
entryExtraFieldsContainer = findViewById(R.id.extra_fields_container)
|
||||
|
||||
attachmentsContainerView = findViewById(R.id.entry_attachments_container)
|
||||
attachmentsListView = findViewById(R.id.entry_attachments_list)
|
||||
@@ -206,10 +206,10 @@ class EntryContentsView @JvmOverloads constructor(context: Context,
|
||||
}
|
||||
|
||||
fun atLeastOneFieldProtectedPresent(): Boolean {
|
||||
extrasView.let {
|
||||
entryExtraFieldsContainer.let {
|
||||
for (i in 0 until it.childCount) {
|
||||
val childCustomView = it.getChildAt(i)
|
||||
if (childCustomView is EntryCustomField)
|
||||
if (childCustomView is EntryExtraField)
|
||||
if (childCustomView.isProtected)
|
||||
return true
|
||||
}
|
||||
@@ -220,10 +220,10 @@ class EntryContentsView @JvmOverloads constructor(context: Context,
|
||||
fun setHiddenPasswordStyle(hiddenStyle: Boolean) {
|
||||
passwordView.applyHiddenStyle(hiddenStyle)
|
||||
// Hidden style for custom fields
|
||||
extrasView.let {
|
||||
entryExtraFieldsContainer.let {
|
||||
for (i in 0 until it.childCount) {
|
||||
val childCustomView = it.getChildAt(i)
|
||||
if (childCustomView is EntryCustomField)
|
||||
if (childCustomView is EntryExtraField)
|
||||
childCustomView.setHiddenPasswordStyle(hiddenStyle)
|
||||
}
|
||||
}
|
||||
@@ -304,30 +304,6 @@ class EntryContentsView @JvmOverloads constructor(context: Context,
|
||||
}
|
||||
}
|
||||
|
||||
fun addExtraField(title: String,
|
||||
value: ProtectedString,
|
||||
enableActionButton: Boolean,
|
||||
onActionClickListener: OnClickListener?) {
|
||||
|
||||
val entryCustomField: EntryCustomField? = EntryCustomField(context, attrs, defStyle)
|
||||
entryCustomField?.apply {
|
||||
setLabel(title)
|
||||
setValue(value.toString(), value.isProtected)
|
||||
enableActionButton(enableActionButton)
|
||||
assignActionButtonClickListener(onActionClickListener)
|
||||
applyFontVisibility(fontInVisibility)
|
||||
}
|
||||
entryCustomField?.let {
|
||||
extrasView.addView(it)
|
||||
}
|
||||
extrasContainerView.visibility = View.VISIBLE
|
||||
}
|
||||
|
||||
fun clearExtraFields() {
|
||||
extrasView.removeAllViews()
|
||||
extrasContainerView.visibility = View.GONE
|
||||
}
|
||||
|
||||
fun assignCreationDate(date: DateInstant) {
|
||||
creationDateView.text = date.getDateTimeString(resources)
|
||||
}
|
||||
@@ -357,29 +333,61 @@ class EntryContentsView @JvmOverloads constructor(context: Context,
|
||||
uuidReferenceView.text = UuidUtil.toHexString(uuid)
|
||||
}
|
||||
|
||||
/* -------------
|
||||
* Extra Fields
|
||||
* -------------
|
||||
*/
|
||||
|
||||
private fun showOrHideExtraFieldsContainer(hide: Boolean) {
|
||||
entryExtraFieldsContainerParent.visibility = if (hide) View.GONE else View.VISIBLE
|
||||
}
|
||||
|
||||
fun addExtraField(title: String,
|
||||
value: ProtectedString,
|
||||
enableActionButton: Boolean,
|
||||
onActionClickListener: OnClickListener?) {
|
||||
|
||||
val entryCustomField: EntryExtraField? = EntryExtraField(context, attrs, defStyle)
|
||||
entryCustomField?.apply {
|
||||
setLabel(title)
|
||||
setValue(value.toString(), value.isProtected)
|
||||
enableActionButton(enableActionButton)
|
||||
assignActionButtonClickListener(onActionClickListener)
|
||||
applyFontVisibility(fontInVisibility)
|
||||
}
|
||||
entryCustomField?.let {
|
||||
entryExtraFieldsContainer.addView(it)
|
||||
}
|
||||
showOrHideExtraFieldsContainer(false)
|
||||
}
|
||||
|
||||
fun clearExtraFields() {
|
||||
entryExtraFieldsContainer.removeAllViews()
|
||||
showOrHideExtraFieldsContainer(true)
|
||||
}
|
||||
|
||||
/* -------------
|
||||
* Attachments
|
||||
* -------------
|
||||
*/
|
||||
|
||||
fun showAttachments(show: Boolean) {
|
||||
private fun showAttachments(show: Boolean) {
|
||||
attachmentsContainerView.visibility = if (show) View.VISIBLE else View.GONE
|
||||
}
|
||||
|
||||
fun assignAttachments(attachments: ArrayList<EntryAttachment>) {
|
||||
fun assignAttachments(attachments: ArrayList<EntryAttachment>,
|
||||
onAttachmentClicked: (attachment: EntryAttachment)->Unit) {
|
||||
showAttachments(attachments.isNotEmpty())
|
||||
attachmentsAdapter.assignAttachments(attachments)
|
||||
attachmentsAdapter.onItemClickListener = { item ->
|
||||
onAttachmentClicked.invoke(item)
|
||||
}
|
||||
}
|
||||
|
||||
fun updateAttachmentDownloadProgress(attachmentToDownload: EntryAttachment) {
|
||||
attachmentsAdapter.updateProgress(attachmentToDownload)
|
||||
}
|
||||
|
||||
fun onAttachmentClick(action: (attachment: EntryAttachment, position: Int)->Unit) {
|
||||
attachmentsAdapter.onItemClickListener = { item, position ->
|
||||
action.invoke(item, position)
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------
|
||||
* History
|
||||
* -------------
|
||||
|
||||
@@ -60,7 +60,9 @@ class EntryEditContentsView @JvmOverloads constructor(context: Context,
|
||||
private val entryExpiresCheckBox: CompoundButton
|
||||
private val entryExpiresTextView: TextView
|
||||
private val entryNotesView: EditText
|
||||
private val entryExtraFieldsContainerParent: ViewGroup
|
||||
private val entryExtraFieldsContainer: ViewGroup
|
||||
private val attachmentsContainerView: View
|
||||
private val attachmentsListView: RecyclerView
|
||||
|
||||
private val attachmentsAdapter = EntryAttachmentsAdapter(context, true)
|
||||
@@ -92,7 +94,9 @@ class EntryEditContentsView @JvmOverloads constructor(context: Context,
|
||||
entryExpiresCheckBox = findViewById(R.id.entry_edit_expires_checkbox)
|
||||
entryExpiresTextView = findViewById(R.id.entry_edit_expires_text)
|
||||
entryNotesView = findViewById(R.id.entry_edit_notes)
|
||||
entryExtraFieldsContainer = findViewById(R.id.entry_edit_extra_fields_container)
|
||||
entryExtraFieldsContainerParent = findViewById(R.id.extra_fields_container_parent)
|
||||
entryExtraFieldsContainer = findViewById(R.id.extra_fields_container)
|
||||
attachmentsContainerView = findViewById(R.id.entry_attachments_container)
|
||||
attachmentsListView = findViewById(R.id.entry_attachments_list)
|
||||
attachmentsListView?.apply {
|
||||
layoutManager = LinearLayoutManager(context, LinearLayoutManager.VERTICAL, true)
|
||||
@@ -218,6 +222,11 @@ class EntryEditContentsView @JvmOverloads constructor(context: Context,
|
||||
entryNotesView.applyFontVisibility()
|
||||
}
|
||||
|
||||
/* -------------
|
||||
* Extra Fields
|
||||
* -------------
|
||||
*/
|
||||
|
||||
val customFields: MutableList<Field>
|
||||
get() {
|
||||
val customFieldsArray = ArrayList<Field>()
|
||||
@@ -226,7 +235,7 @@ class EntryEditContentsView @JvmOverloads constructor(context: Context,
|
||||
try {
|
||||
for (i in 0 until it.childCount) {
|
||||
val view = it.getChildAt(i) as EntryEditExtraField
|
||||
customFieldsArray.add(view.customField)
|
||||
customFieldsArray.add(view.extraField)
|
||||
}
|
||||
} catch (exception: Exception) {
|
||||
// Extra field container contains another type of view
|
||||
@@ -235,11 +244,11 @@ class EntryEditContentsView @JvmOverloads constructor(context: Context,
|
||||
return customFieldsArray
|
||||
}
|
||||
|
||||
private fun getCustomFieldByLabel(label: String): EntryEditExtraField? {
|
||||
private fun getExtraFieldByLabel(label: String): EntryEditExtraField? {
|
||||
for (i in 0..entryExtraFieldsContainer.childCount) {
|
||||
try {
|
||||
val extraFieldView = entryExtraFieldsContainer.getChildAt(i) as EntryEditExtraField?
|
||||
if (extraFieldView?.customField?.name == label) {
|
||||
if (extraFieldView?.extraField?.name == label) {
|
||||
return extraFieldView
|
||||
}
|
||||
} catch(e: Exception) {
|
||||
@@ -249,15 +258,34 @@ class EntryEditContentsView @JvmOverloads constructor(context: Context,
|
||||
return null
|
||||
}
|
||||
|
||||
private fun showOrHideExtraFieldsContainer(hide: Boolean, animate: Boolean = false) {
|
||||
entryExtraFieldsContainerParent.apply {
|
||||
if (!animate)
|
||||
visibility = if (hide) View.GONE else View.VISIBLE
|
||||
else
|
||||
if (hide) collapse(true) else expand(true)
|
||||
}
|
||||
}
|
||||
|
||||
private fun buildNewEntryEditExtraField(): EntryEditExtraField {
|
||||
return EntryEditExtraField(context).apply {
|
||||
applyFontVisibility(fontInVisibility)
|
||||
onViewDeletedListener = {
|
||||
// remove callback
|
||||
showOrHideExtraFieldsContainer(entryExtraFieldsContainer.childCount <= 1, true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove all children and add new views for each field
|
||||
*/
|
||||
fun assignExtraFields(fields: List<Field>) {
|
||||
showOrHideExtraFieldsContainer(fields.isEmpty())
|
||||
entryExtraFieldsContainer.removeAllViews()
|
||||
fields.forEach { extraField ->
|
||||
entryExtraFieldsContainer.addView(EntryEditExtraField(context).apply {
|
||||
setFontVisibility(fontInVisibility)
|
||||
customField = extraField
|
||||
entryExtraFieldsContainer.addView(buildNewEntryEditExtraField().apply {
|
||||
this.extraField = extraField
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -265,27 +293,46 @@ class EntryEditContentsView @JvmOverloads constructor(context: Context,
|
||||
/**
|
||||
* Update an extra field or create a new one if doesn't exists
|
||||
*/
|
||||
fun putExtraField(customField: Field)
|
||||
fun putExtraField(extraField: Field)
|
||||
: EntryEditExtraField {
|
||||
var extraFieldView = getCustomFieldByLabel(customField.name)
|
||||
showOrHideExtraFieldsContainer(false)
|
||||
var extraFieldView = getExtraFieldByLabel(extraField.name)
|
||||
// Create new view if not exists
|
||||
if (extraFieldView == null) {
|
||||
extraFieldView = EntryEditExtraField(context)
|
||||
extraFieldView.setFontVisibility(fontInVisibility)
|
||||
extraFieldView = buildNewEntryEditExtraField()
|
||||
// No need animation because of scroll
|
||||
entryExtraFieldsContainer.addView(extraFieldView)
|
||||
}
|
||||
extraFieldView.customField = customField
|
||||
extraFieldView.extraField = extraField
|
||||
return extraFieldView
|
||||
}
|
||||
|
||||
fun assignAttachments(attachments: java.util.ArrayList<EntryAttachment>) {
|
||||
attachmentsAdapter.assignAttachments(attachments)
|
||||
/* -------------
|
||||
* Attachments
|
||||
* -------------
|
||||
*/
|
||||
|
||||
private fun showOrHideAttachmentsContainer(hide: Boolean, animate: Boolean = false) {
|
||||
attachmentsContainerView.apply {
|
||||
if (!animate)
|
||||
visibility = if (hide) View.GONE else View.VISIBLE
|
||||
else
|
||||
if (hide) collapse(true) else expand(true)
|
||||
}
|
||||
}
|
||||
|
||||
fun onAttachmentDeleted(action: (attachment: EntryAttachment, position: Int)->Unit) {
|
||||
attachmentsAdapter.onDeleteListener = { item, position ->
|
||||
action.invoke(item, position)
|
||||
fun assignAttachments(attachments: java.util.ArrayList<EntryAttachment>,
|
||||
onAttachmentClicked: (attachment: EntryAttachment)->Unit,
|
||||
onAttachmentDeleted: ((attachment: EntryAttachment)->Unit)? = null) {
|
||||
showOrHideAttachmentsContainer(attachments.isEmpty())
|
||||
attachmentsAdapter.assignAttachments(attachments)
|
||||
attachmentsAdapter.onItemClickListener = { item ->
|
||||
onAttachmentClicked.invoke(item)
|
||||
}
|
||||
attachmentsAdapter.onDeleteListener = { item, lastOne ->
|
||||
onAttachmentDeleted?.invoke(item)
|
||||
if (lastOne)
|
||||
showOrHideAttachmentsContainer(hide = true, animate = true)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -301,11 +348,11 @@ class EntryEditContentsView @JvmOverloads constructor(context: Context,
|
||||
val customFieldLabelSet = HashSet<String>()
|
||||
for (i in 0 until it.childCount) {
|
||||
val entryEditCustomField = it.getChildAt(i) as EntryEditExtraField
|
||||
if (customFieldLabelSet.contains(entryEditCustomField.customField.name)) {
|
||||
if (customFieldLabelSet.contains(entryEditCustomField.extraField.name)) {
|
||||
entryEditCustomField.setError(R.string.error_label_exists)
|
||||
return false
|
||||
}
|
||||
customFieldLabelSet.add(entryEditCustomField.customField.name)
|
||||
customFieldLabelSet.add(entryEditCustomField.extraField.name)
|
||||
if (!entryEditCustomField.isValid()) {
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -47,7 +47,9 @@ class EntryEditExtraField @JvmOverloads constructor(context: Context,
|
||||
private var isProtected = false
|
||||
private var mValueViewInputType: Int = 0
|
||||
|
||||
var customField: Field
|
||||
var onViewDeletedListener: ((Field) -> Unit)? = null
|
||||
|
||||
var extraField: Field
|
||||
get() {
|
||||
return Field(valueLayoutView.hint.toString(), ProtectedString(isProtected, valueView.text.toString()))
|
||||
}
|
||||
@@ -75,6 +77,8 @@ class EntryEditExtraField @JvmOverloads constructor(context: Context,
|
||||
mValueViewInputType = valueView.inputType
|
||||
deleteButton.setOnClickListener {
|
||||
collapse(true) {
|
||||
onViewDeletedListener?.invoke(extraField)
|
||||
onViewDeletedListener = null
|
||||
(parent as ViewGroup?)?.apply {
|
||||
removeView(this@EntryEditExtraField)
|
||||
}
|
||||
@@ -82,6 +86,12 @@ class EntryEditExtraField @JvmOverloads constructor(context: Context,
|
||||
}
|
||||
}
|
||||
|
||||
fun applyFontVisibility(applyFontVisibility: Boolean) {
|
||||
mApplyFontVisibility = applyFontVisibility
|
||||
if (applyFontVisibility)
|
||||
valueView.applyFontVisibility()
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate or not the entry form
|
||||
*
|
||||
@@ -104,12 +114,6 @@ class EntryEditExtraField @JvmOverloads constructor(context: Context,
|
||||
}
|
||||
}
|
||||
|
||||
fun setFontVisibility(applyFontVisibility: Boolean) {
|
||||
mApplyFontVisibility = applyFontVisibility
|
||||
if (applyFontVisibility)
|
||||
valueView.applyFontVisibility()
|
||||
}
|
||||
|
||||
override fun requestFocus(direction: Int, previouslyFocusedRect: Rect?): Boolean {
|
||||
valueView.requestFocus(direction, previouslyFocusedRect)
|
||||
return true
|
||||
|
||||
@@ -29,9 +29,9 @@ import android.widget.TextView
|
||||
import androidx.core.content.ContextCompat
|
||||
import com.kunzisoft.keepass.R
|
||||
|
||||
class EntryCustomField @JvmOverloads constructor(context: Context,
|
||||
attrs: AttributeSet? = null,
|
||||
defStyle: Int = 0)
|
||||
class EntryExtraField @JvmOverloads constructor(context: Context,
|
||||
attrs: AttributeSet? = null,
|
||||
defStyle: Int = 0)
|
||||
: LinearLayout(context, attrs, defStyle) {
|
||||
|
||||
private val labelView: TextView
|
||||
@@ -116,8 +116,8 @@
|
||||
|
||||
<com.kunzisoft.keepass.view.EntryContentsView
|
||||
android:id="@+id/entry_contents"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintWidth_percent="@dimen/content_percent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/history_container"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
|
||||
@@ -50,15 +50,20 @@
|
||||
android:scrollbarStyle="insideOverlay"
|
||||
android:scrollbars="none"
|
||||
app:layout_behavior="@string/appbar_scrolling_view_behavior">
|
||||
<com.kunzisoft.keepass.view.EntryEditContentsView
|
||||
android:id="@+id/entry_edit_contents"
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="?attr/actionBarSize"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintWidth_percent="@dimen/content_percent" />
|
||||
android:layout_height="match_parent"
|
||||
android:paddingBottom="?attr/actionBarSize">
|
||||
<com.kunzisoft.keepass.view.EntryEditContentsView
|
||||
android:id="@+id/entry_edit_contents"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintWidth_percent="@dimen/content_percent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</androidx.core.widget.NestedScrollView>
|
||||
|
||||
<com.google.android.material.bottomappbar.BottomAppBar
|
||||
|
||||
@@ -79,7 +79,7 @@
|
||||
android:padding="6dp"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
android:src="@drawable/ic_close_white_24dp"
|
||||
android:src="@drawable/ic_content_delete_white_24dp"
|
||||
app:tint="?attr/colorAccent"
|
||||
android:contentDescription="@string/content_description_remove_field">
|
||||
</ImageView>
|
||||
|
||||
@@ -53,7 +53,7 @@
|
||||
android:layout_marginTop="12dp"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
android:src="@drawable/ic_close_white_24dp"
|
||||
android:src="@drawable/ic_content_delete_white_24dp"
|
||||
android:contentDescription="@string/content_description_remove_field"
|
||||
android:tint="?attr/colorAccent" />
|
||||
|
||||
|
||||
@@ -20,8 +20,8 @@
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/entry_table"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<androidx.cardview.widget.CardView
|
||||
@@ -185,9 +185,8 @@
|
||||
</LinearLayout>
|
||||
</androidx.cardview.widget.CardView>
|
||||
|
||||
<!-- Extras -->
|
||||
<androidx.cardview.widget.CardView
|
||||
android:id="@+id/extra_strings_container"
|
||||
android:id="@+id/extra_fields_container_parent"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:visibility="gone"
|
||||
@@ -197,7 +196,7 @@
|
||||
android:layout_marginRight="@dimen/card_view_margin"
|
||||
android:layout_marginBottom="@dimen/card_view_margin_bottom">
|
||||
<LinearLayout
|
||||
android:id="@+id/extra_strings"
|
||||
android:id="@+id/extra_fields_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="@dimen/card_view_padding"
|
||||
|
||||
@@ -29,17 +29,18 @@
|
||||
android:id="@+id/entry_edit_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/card_view_margin"
|
||||
android:layout_marginStart="0dp"
|
||||
android:layout_marginEnd="0dp"
|
||||
android:layout_marginLeft="0dp"
|
||||
android:layout_marginRight="0dp"
|
||||
android:layout_marginTop="@dimen/card_view_margin_bottom"
|
||||
android:layout_marginStart="@dimen/card_view_margin"
|
||||
android:layout_marginEnd="@dimen/card_view_margin"
|
||||
android:layout_marginLeft="@dimen/card_view_margin"
|
||||
android:layout_marginRight="@dimen/card_view_margin"
|
||||
android:layout_marginBottom="@dimen/card_view_margin_bottom"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
<LinearLayout
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="@dimen/default_margin">
|
||||
android:layout_margin="@dimen/card_view_padding">
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageButton
|
||||
android:id="@+id/entry_edit_icon_button"
|
||||
@@ -199,39 +200,56 @@
|
||||
</androidx.cardview.widget.CardView>
|
||||
|
||||
<androidx.cardview.widget.CardView
|
||||
android:id="@+id/entry_edit_extra_fields_container_parent"
|
||||
android:id="@+id/extra_fields_container_parent"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:visibility="gone"
|
||||
android:layout_marginTop="@dimen/card_view_margin_bottom"
|
||||
android:layout_marginStart="0dp"
|
||||
android:layout_marginEnd="0dp"
|
||||
android:layout_marginLeft="0dp"
|
||||
android:layout_marginRight="0dp"
|
||||
android:layout_marginStart="@dimen/card_view_margin"
|
||||
android:layout_marginEnd="@dimen/card_view_margin"
|
||||
android:layout_marginLeft="@dimen/card_view_margin"
|
||||
android:layout_marginRight="@dimen/card_view_margin"
|
||||
android:layout_marginBottom="@dimen/card_view_margin_bottom"
|
||||
app:layout_constraintTop_toBottomOf="@+id/entry_edit_container">
|
||||
<LinearLayout
|
||||
android:id="@+id/entry_edit_extra_fields_container"
|
||||
android:id="@+id/extra_fields_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="@dimen/default_margin"
|
||||
android:layout_margin="@dimen/card_view_padding"
|
||||
android:orientation="vertical">
|
||||
</LinearLayout>
|
||||
</androidx.cardview.widget.CardView>
|
||||
|
||||
<androidx.cardview.widget.CardView
|
||||
android:id="@+id/entry_edit_attachments_container_parent"
|
||||
android:id="@+id/entry_attachments_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/card_view_margin_bottom"
|
||||
android:layout_marginStart="0dp"
|
||||
android:layout_marginEnd="0dp"
|
||||
android:layout_marginLeft="0dp"
|
||||
android:layout_marginRight="0dp"
|
||||
app:layout_constraintTop_toBottomOf="@+id/entry_edit_extra_fields_container_parent">
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/entry_attachments_list"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_marginStart="@dimen/card_view_margin"
|
||||
android:layout_marginEnd="@dimen/card_view_margin"
|
||||
android:layout_marginLeft="@dimen/card_view_margin"
|
||||
android:layout_marginRight="@dimen/card_view_margin"
|
||||
app:layout_constraintTop_toBottomOf="@+id/extra_fields_container_parent">
|
||||
<LinearLayout
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="@dimen/default_margin" />
|
||||
android:layout_width="match_parent"
|
||||
android:layout_margin="@dimen/card_view_padding"
|
||||
android:orientation="vertical">
|
||||
|
||||
<!-- Binary files -->
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:id="@+id/entry_attachments_label"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/entry_attachments"
|
||||
style="@style/KeepassDXStyle.TextAppearance.LabelTextStyle" />
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/entry_attachments_list"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
</LinearLayout>
|
||||
</androidx.cardview.widget.CardView>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
Reference in New Issue
Block a user