mirror of
https://github.com/Kunzisoft/KeePassDX.git
synced 2025-12-04 15:49:33 +01:00
Possibility to remove attachment
This commit is contained in:
@@ -350,7 +350,6 @@ class EntryActivity : LockingActivity() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
entryContentsView?.refreshAttachments()
|
|
||||||
|
|
||||||
// Assign dates
|
// Assign dates
|
||||||
entryContentsView?.assignCreationDate(entry.creationTime)
|
entryContentsView?.assignCreationDate(entry.creationTime)
|
||||||
|
|||||||
@@ -300,6 +300,10 @@ class EntryEditActivity : LockingActivity(),
|
|||||||
for ((key, value) in newEntry.customFields) {
|
for ((key, value) in newEntry.customFields) {
|
||||||
putCustomField(Field(key, value))
|
putCustomField(Field(key, value))
|
||||||
}
|
}
|
||||||
|
assignAttachments(newEntry.getAttachments())
|
||||||
|
onAttachmentDeleted { attachment, _ ->
|
||||||
|
newEntry.removeAttachment(attachment)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -33,11 +33,13 @@ import com.kunzisoft.keepass.database.element.database.CompressionAlgorithm
|
|||||||
import com.kunzisoft.keepass.model.AttachmentState
|
import com.kunzisoft.keepass.model.AttachmentState
|
||||||
import com.kunzisoft.keepass.model.EntryAttachment
|
import com.kunzisoft.keepass.model.EntryAttachment
|
||||||
|
|
||||||
class EntryAttachmentsAdapter(val context: Context) : RecyclerView.Adapter<EntryAttachmentsAdapter.EntryBinariesViewHolder>() {
|
class EntryAttachmentsAdapter(val context: Context, private val editable: Boolean)
|
||||||
|
: RecyclerView.Adapter<EntryAttachmentsAdapter.EntryBinariesViewHolder>() {
|
||||||
|
|
||||||
private val inflater: LayoutInflater = LayoutInflater.from(context)
|
private val inflater: LayoutInflater = LayoutInflater.from(context)
|
||||||
var entryAttachmentsList: MutableList<EntryAttachment> = ArrayList()
|
var entryAttachmentsList: MutableList<EntryAttachment> = ArrayList()
|
||||||
var onItemClickListener: ((item: EntryAttachment, position: Int)->Unit)? = null
|
var onItemClickListener: ((item: EntryAttachment, position: Int)->Unit)? = null
|
||||||
|
var onDeleteListener: ((item: EntryAttachment, position: Int)->Unit)? = null
|
||||||
|
|
||||||
private val mDatabase = Database.getInstance()
|
private val mDatabase = Database.getInstance()
|
||||||
|
|
||||||
@@ -61,16 +63,28 @@ class EntryAttachmentsAdapter(val context: Context) : RecyclerView.Adapter<Entry
|
|||||||
visibility = View.GONE
|
visibility = View.GONE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
holder.binaryFileProgress.apply {
|
if (editable) {
|
||||||
visibility = when (entryAttachment.downloadState) {
|
holder.binaryFileProgressContainer.visibility = View.GONE
|
||||||
AttachmentState.NULL, AttachmentState.COMPLETE, AttachmentState.ERROR -> View.GONE
|
holder.binaryFileDeleteButton.apply {
|
||||||
AttachmentState.START, AttachmentState.IN_PROGRESS -> View.VISIBLE
|
visibility = View.VISIBLE
|
||||||
|
setOnClickListener {
|
||||||
|
onDeleteListener?.invoke(entryAttachment, position)
|
||||||
|
deleteAttachment(entryAttachment)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
holder.binaryFileProgressContainer.visibility = View.VISIBLE
|
||||||
|
holder.binaryFileDeleteButton.visibility = View.GONE
|
||||||
|
holder.binaryFileProgress.apply {
|
||||||
|
visibility = when (entryAttachment.downloadState) {
|
||||||
|
AttachmentState.NULL, AttachmentState.COMPLETE, AttachmentState.ERROR -> View.GONE
|
||||||
|
AttachmentState.START, AttachmentState.IN_PROGRESS -> View.VISIBLE
|
||||||
|
}
|
||||||
|
progress = entryAttachment.downloadProgression
|
||||||
|
}
|
||||||
|
holder.itemView.setOnClickListener {
|
||||||
|
onItemClickListener?.invoke(entryAttachment, position)
|
||||||
}
|
}
|
||||||
progress = entryAttachment.downloadProgression
|
|
||||||
}
|
|
||||||
|
|
||||||
holder.itemView.setOnClickListener {
|
|
||||||
onItemClickListener?.invoke(entryAttachment, position)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -78,6 +92,23 @@ class EntryAttachmentsAdapter(val context: Context) : RecyclerView.Adapter<Entry
|
|||||||
return entryAttachmentsList.size
|
return entryAttachmentsList.size
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun assignAttachments(attachments: List<EntryAttachment>) {
|
||||||
|
entryAttachmentsList.apply {
|
||||||
|
clear()
|
||||||
|
addAll(attachments)
|
||||||
|
}
|
||||||
|
notifyDataSetChanged()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun deleteAttachment(attachment: EntryAttachment) {
|
||||||
|
val position = entryAttachmentsList.indexOf(attachment)
|
||||||
|
if (position >= 0) {
|
||||||
|
entryAttachmentsList.removeAt(position)
|
||||||
|
notifyItemRemoved(position)
|
||||||
|
}
|
||||||
|
// TODO Animation
|
||||||
|
}
|
||||||
|
|
||||||
fun updateProgress(entryAttachment: EntryAttachment) {
|
fun updateProgress(entryAttachment: EntryAttachment) {
|
||||||
val indexEntryAttachment = entryAttachmentsList.indexOfLast { current -> current.name == entryAttachment.name }
|
val indexEntryAttachment = entryAttachmentsList.indexOfLast { current -> current.name == entryAttachment.name }
|
||||||
if (indexEntryAttachment != -1) {
|
if (indexEntryAttachment != -1) {
|
||||||
@@ -95,6 +126,8 @@ class EntryAttachmentsAdapter(val context: Context) : RecyclerView.Adapter<Entry
|
|||||||
var binaryFileTitle: TextView = itemView.findViewById(R.id.item_attachment_title)
|
var binaryFileTitle: TextView = itemView.findViewById(R.id.item_attachment_title)
|
||||||
var binaryFileSize: TextView = itemView.findViewById(R.id.item_attachment_size)
|
var binaryFileSize: TextView = itemView.findViewById(R.id.item_attachment_size)
|
||||||
var binaryFileCompression: TextView = itemView.findViewById(R.id.item_attachment_compression)
|
var binaryFileCompression: TextView = itemView.findViewById(R.id.item_attachment_compression)
|
||||||
|
var binaryFileProgressContainer: View = itemView.findViewById(R.id.item_attachment_progress_container)
|
||||||
var binaryFileProgress: ProgressBar = itemView.findViewById(R.id.item_attachment_progress)
|
var binaryFileProgress: ProgressBar = itemView.findViewById(R.id.item_attachment_progress)
|
||||||
|
var binaryFileDeleteButton: View = itemView.findViewById(R.id.item_attachment_delete_button)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -329,22 +329,31 @@ class Entry : Node, EntryVersionedInterface<Group> {
|
|||||||
fun getAttachments(): ArrayList<EntryAttachment> {
|
fun getAttachments(): ArrayList<EntryAttachment> {
|
||||||
val attachments = ArrayList<EntryAttachment>()
|
val attachments = ArrayList<EntryAttachment>()
|
||||||
|
|
||||||
val binaryDescriptionKDB = entryKDB?.binaryDescription ?: ""
|
entryKDB?.binaryData?.let { binaryKDB ->
|
||||||
val binaryKDB = entryKDB?.binaryData
|
attachments.add(EntryAttachment(entryKDB?.binaryDescription ?: "", binaryKDB))
|
||||||
if (binaryKDB != null) {
|
|
||||||
attachments.add(EntryAttachment(binaryDescriptionKDB, binaryKDB))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val actionEach = object : (Map.Entry<String, BinaryAttachment>)->Unit {
|
entryKDBX?.binaries?.let { binariesKDBX ->
|
||||||
override fun invoke(mapEntry: Map.Entry<String, BinaryAttachment>) {
|
for ((key, value) in binariesKDBX) {
|
||||||
attachments.add(EntryAttachment(mapEntry.key, mapEntry.value))
|
attachments.add(EntryAttachment(key, value))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
entryKDBX?.binaries?.forEach(actionEach)
|
|
||||||
|
|
||||||
return attachments
|
return attachments
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun removeAttachment(attachment: EntryAttachment) {
|
||||||
|
entryKDB?.apply {
|
||||||
|
if (binaryDescription == attachment.name
|
||||||
|
&& binaryData == attachment.binaryAttachment) {
|
||||||
|
binaryDescription = ""
|
||||||
|
binaryData = null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
entryKDBX?.removeProtectedBinary(attachment.name)
|
||||||
|
}
|
||||||
|
|
||||||
fun getHistory(): ArrayList<Entry> {
|
fun getHistory(): ArrayList<Entry> {
|
||||||
val history = ArrayList<Entry>()
|
val history = ArrayList<Entry>()
|
||||||
val entryKDBXHistory = entryKDBX?.history ?: ArrayList()
|
val entryKDBXHistory = entryKDBX?.history ?: ArrayList()
|
||||||
|
|||||||
@@ -288,6 +288,10 @@ class EntryKDBX : EntryVersioned<UUID, UUID, GroupKDBX, EntryKDBX>, NodeKDBXInte
|
|||||||
binaries[key] = value
|
binaries[key] = value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun removeProtectedBinary(name: String) {
|
||||||
|
binaries.remove(name)
|
||||||
|
}
|
||||||
|
|
||||||
fun sizeOfHistory(): Int {
|
fun sizeOfHistory(): Int {
|
||||||
return history.size
|
return history.size
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,6 +47,22 @@ data class EntryAttachment(var name: String,
|
|||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun equals(other: Any?): Boolean {
|
||||||
|
if (this === other) return true
|
||||||
|
if (other !is EntryAttachment) return false
|
||||||
|
|
||||||
|
if (name != other.name) return false
|
||||||
|
if (binaryAttachment != other.binaryAttachment) return false
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun hashCode(): Int {
|
||||||
|
var result = name.hashCode()
|
||||||
|
result = 31 * result + binaryAttachment.hashCode()
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
companion object CREATOR : Parcelable.Creator<EntryAttachment> {
|
companion object CREATOR : Parcelable.Creator<EntryAttachment> {
|
||||||
override fun createFromParcel(parcel: Parcel): EntryAttachment {
|
override fun createFromParcel(parcel: Parcel): EntryAttachment {
|
||||||
return EntryAttachment(parcel)
|
return EntryAttachment(parcel)
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ class EntryContentsView @JvmOverloads constructor(context: Context,
|
|||||||
|
|
||||||
private val attachmentsContainerView: View
|
private val attachmentsContainerView: View
|
||||||
private val attachmentsListView: RecyclerView
|
private val attachmentsListView: RecyclerView
|
||||||
private val attachmentsAdapter = EntryAttachmentsAdapter(context)
|
private val attachmentsAdapter = EntryAttachmentsAdapter(context, false)
|
||||||
|
|
||||||
private val historyContainerView: View
|
private val historyContainerView: View
|
||||||
private val historyListView: RecyclerView
|
private val historyListView: RecyclerView
|
||||||
@@ -366,13 +366,8 @@ class EntryContentsView @JvmOverloads constructor(context: Context,
|
|||||||
attachmentsContainerView.visibility = if (show) View.VISIBLE else View.GONE
|
attachmentsContainerView.visibility = if (show) View.VISIBLE else View.GONE
|
||||||
}
|
}
|
||||||
|
|
||||||
fun refreshAttachments() {
|
|
||||||
attachmentsAdapter.notifyDataSetChanged()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun assignAttachments(attachments: ArrayList<EntryAttachment>) {
|
fun assignAttachments(attachments: ArrayList<EntryAttachment>) {
|
||||||
attachmentsAdapter.clear()
|
attachmentsAdapter.assignAttachments(attachments)
|
||||||
attachmentsAdapter.entryAttachmentsList.addAll(attachments)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun updateAttachmentDownloadProgress(attachmentToDownload: EntryAttachment) {
|
fun updateAttachmentDownloadProgress(attachmentToDownload: EntryAttachment) {
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ class EntryCustomField @JvmOverloads constructor(context: Context,
|
|||||||
init {
|
init {
|
||||||
|
|
||||||
val inflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater?
|
val inflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater?
|
||||||
inflater?.inflate(R.layout.item_entry_new_field, this)
|
inflater?.inflate(R.layout.item_entry_extra_field, this)
|
||||||
|
|
||||||
labelView = findViewById(R.id.title)
|
labelView = findViewById(R.id.title)
|
||||||
valueView = findViewById(R.id.value)
|
valueView = findViewById(R.id.value)
|
||||||
|
|||||||
@@ -22,18 +22,22 @@ package com.kunzisoft.keepass.view
|
|||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.graphics.Color
|
import android.graphics.Color
|
||||||
import android.util.AttributeSet
|
import android.util.AttributeSet
|
||||||
import android.util.Log
|
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.widget.*
|
import android.widget.*
|
||||||
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import androidx.recyclerview.widget.SimpleItemAnimator
|
||||||
import com.google.android.material.textfield.TextInputLayout
|
import com.google.android.material.textfield.TextInputLayout
|
||||||
import com.kunzisoft.keepass.R
|
import com.kunzisoft.keepass.R
|
||||||
|
import com.kunzisoft.keepass.adapters.EntryAttachmentsAdapter
|
||||||
import com.kunzisoft.keepass.database.element.DateInstant
|
import com.kunzisoft.keepass.database.element.DateInstant
|
||||||
import com.kunzisoft.keepass.database.element.icon.IconImage
|
import com.kunzisoft.keepass.database.element.icon.IconImage
|
||||||
import com.kunzisoft.keepass.icons.IconDrawableFactory
|
import com.kunzisoft.keepass.icons.IconDrawableFactory
|
||||||
import com.kunzisoft.keepass.icons.assignDatabaseIcon
|
import com.kunzisoft.keepass.icons.assignDatabaseIcon
|
||||||
import com.kunzisoft.keepass.icons.assignDefaultDatabaseIcon
|
import com.kunzisoft.keepass.icons.assignDefaultDatabaseIcon
|
||||||
|
import com.kunzisoft.keepass.model.EntryAttachment
|
||||||
import com.kunzisoft.keepass.model.Field
|
import com.kunzisoft.keepass.model.Field
|
||||||
import org.joda.time.Duration
|
import org.joda.time.Duration
|
||||||
import org.joda.time.Instant
|
import org.joda.time.Instant
|
||||||
@@ -57,6 +61,9 @@ class EntryEditContentsView @JvmOverloads constructor(context: Context,
|
|||||||
private val entryExpiresTextView: TextView
|
private val entryExpiresTextView: TextView
|
||||||
private val entryNotesView: EditText
|
private val entryNotesView: EditText
|
||||||
private val entryExtraFieldsContainer: ViewGroup
|
private val entryExtraFieldsContainer: ViewGroup
|
||||||
|
private val attachmentsListView: RecyclerView
|
||||||
|
|
||||||
|
private val attachmentsAdapter = EntryAttachmentsAdapter(context, true)
|
||||||
|
|
||||||
private var iconColor: Int = 0
|
private var iconColor: Int = 0
|
||||||
private var expiresInstant: DateInstant = DateInstant(Instant.now().plus(Duration.standardDays(30)).toDate())
|
private var expiresInstant: DateInstant = DateInstant(Instant.now().plus(Duration.standardDays(30)).toDate())
|
||||||
@@ -86,6 +93,12 @@ class EntryEditContentsView @JvmOverloads constructor(context: Context,
|
|||||||
entryExpiresTextView = findViewById(R.id.entry_edit_expires_text)
|
entryExpiresTextView = findViewById(R.id.entry_edit_expires_text)
|
||||||
entryNotesView = findViewById(R.id.entry_edit_notes)
|
entryNotesView = findViewById(R.id.entry_edit_notes)
|
||||||
entryExtraFieldsContainer = findViewById(R.id.entry_edit_extra_fields_container)
|
entryExtraFieldsContainer = findViewById(R.id.entry_edit_extra_fields_container)
|
||||||
|
attachmentsListView = findViewById(R.id.entry_attachments_list)
|
||||||
|
attachmentsListView?.apply {
|
||||||
|
layoutManager = LinearLayoutManager(context, LinearLayoutManager.VERTICAL, true)
|
||||||
|
adapter = attachmentsAdapter
|
||||||
|
(itemAnimator as SimpleItemAnimator).supportsChangeAnimations = false
|
||||||
|
}
|
||||||
|
|
||||||
entryExpiresCheckBox.setOnCheckedChangeListener { _, _ ->
|
entryExpiresCheckBox.setOnCheckedChangeListener { _, _ ->
|
||||||
assignExpiresDateText()
|
assignExpiresDateText()
|
||||||
@@ -255,6 +268,16 @@ class EntryEditContentsView @JvmOverloads constructor(context: Context,
|
|||||||
return extraFieldView
|
return extraFieldView
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun assignAttachments(attachments: java.util.ArrayList<EntryAttachment>) {
|
||||||
|
attachmentsAdapter.assignAttachments(attachments)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun onAttachmentDeleted(action: (attachment: EntryAttachment, position: Int)->Unit) {
|
||||||
|
attachmentsAdapter.onDeleteListener = { item, position ->
|
||||||
|
action.invoke(item, position)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validate or not the entry form
|
* Validate or not the entry form
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ class EntryEditExtraField @JvmOverloads constructor(context: Context,
|
|||||||
|
|
||||||
init {
|
init {
|
||||||
val inflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater?
|
val inflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater?
|
||||||
inflater?.inflate(R.layout.view_entry_edit_extra_field, this)
|
inflater?.inflate(R.layout.item_entry_edit_extra_field, this)
|
||||||
|
|
||||||
valueLayoutView = findViewById(R.id.entry_extra_field_value_container)
|
valueLayoutView = findViewById(R.id.entry_extra_field_value_container)
|
||||||
valueView = findViewById(R.id.entry_extra_field_value)
|
valueView = findViewById(R.id.entry_extra_field_value)
|
||||||
|
|||||||
@@ -44,7 +44,7 @@
|
|||||||
android:gravity="end"
|
android:gravity="end"
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintEnd_toStartOf="@+id/item_attachment_icon" >
|
app:layout_constraintEnd_toStartOf="@+id/item_attachment_action_container" >
|
||||||
<androidx.appcompat.widget.AppCompatTextView
|
<androidx.appcompat.widget.AppCompatTextView
|
||||||
android:id="@+id/item_attachment_size"
|
android:id="@+id/item_attachment_size"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
@@ -65,24 +65,48 @@
|
|||||||
android:paddingEnd="8dp"
|
android:paddingEnd="8dp"
|
||||||
tools:text="GZip" />
|
tools:text="GZip" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
<androidx.appcompat.widget.AppCompatImageView
|
<FrameLayout
|
||||||
android:id="@+id/item_attachment_icon"
|
android:id="@+id/item_attachment_action_container"
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
android:layout_width="36dp"
|
android:layout_width="36dp"
|
||||||
android:layout_height="36dp"
|
android:layout_height="36dp">
|
||||||
android:padding="6dp"
|
<ImageView
|
||||||
android:src="@drawable/ic_file_download_white_24dp"
|
android:id="@+id/item_attachment_delete_button"
|
||||||
android:tint="?attr/colorAccent" />
|
android:layout_width="match_parent"
|
||||||
<ProgressBar
|
android:layout_height="match_parent"
|
||||||
android:id="@+id/item_attachment_progress"
|
android:padding="6dp"
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
android:src="@drawable/ic_close_white_24dp"
|
||||||
style="@style/KeepassDXStyle.ProgressBar.Circle"
|
app:tint="?attr/colorAccent"
|
||||||
android:layout_width="36dp"
|
android:contentDescription="@string/content_description_remove_field">
|
||||||
android:layout_height="36dp"
|
</ImageView>
|
||||||
android:max="100"
|
<FrameLayout
|
||||||
android:progress="60" />
|
android:id="@+id/item_attachment_progress_container"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
<androidx.appcompat.widget.AppCompatImageView
|
||||||
|
android:id="@+id/item_attachment_icon"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:padding="6dp"
|
||||||
|
android:src="@drawable/ic_file_download_white_24dp"
|
||||||
|
android:tint="?attr/colorAccent" />
|
||||||
|
<ProgressBar
|
||||||
|
android:id="@+id/item_attachment_progress"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
style="@style/KeepassDXStyle.ProgressBar.Circle"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:max="100"
|
||||||
|
android:progress="60" />
|
||||||
|
</FrameLayout>
|
||||||
|
</FrameLayout>
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
@@ -33,11 +33,7 @@
|
|||||||
app:layout_constraintTop_toTopOf="parent"
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintEnd_toStartOf="@+id/entry_extra_field_delete"
|
app:layout_constraintEnd_toStartOf="@+id/entry_extra_field_delete">
|
||||||
android:paddingLeft="@dimen/default_margin"
|
|
||||||
android:paddingStart="@dimen/default_margin"
|
|
||||||
android:paddingRight="0dp"
|
|
||||||
android:paddingEnd="0dp">
|
|
||||||
|
|
||||||
<com.google.android.material.textfield.TextInputEditText
|
<com.google.android.material.textfield.TextInputEditText
|
||||||
android:id="@+id/entry_extra_field_value"
|
android:id="@+id/entry_extra_field_value"
|
||||||
@@ -51,9 +47,10 @@
|
|||||||
|
|
||||||
<androidx.appcompat.widget.AppCompatImageView
|
<androidx.appcompat.widget.AppCompatImageView
|
||||||
android:id="@+id/entry_extra_field_delete"
|
android:id="@+id/entry_extra_field_delete"
|
||||||
android:layout_width="48dp"
|
android:layout_width="36dp"
|
||||||
android:layout_height="48dp"
|
android:layout_height="36dp"
|
||||||
android:padding="12dp"
|
android:padding="6dp"
|
||||||
|
android:layout_marginTop="12dp"
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
android:src="@drawable/ic_close_white_24dp"
|
android:src="@drawable/ic_close_white_24dp"
|
||||||
@@ -212,10 +212,26 @@
|
|||||||
android:id="@+id/entry_edit_extra_fields_container"
|
android:id="@+id/entry_edit_extra_fields_container"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="@dimen/default_margin"
|
android:layout_margin="@dimen/default_margin"
|
||||||
android:layout_marginBottom="@dimen/default_margin"
|
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
</androidx.cardview.widget.CardView>
|
</androidx.cardview.widget.CardView>
|
||||||
|
|
||||||
|
<androidx.cardview.widget.CardView
|
||||||
|
android:id="@+id/entry_edit_attachments_container_parent"
|
||||||
|
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_height="wrap_content"
|
||||||
|
android:layout_margin="@dimen/default_margin" />
|
||||||
|
</androidx.cardview.widget.CardView>
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
Reference in New Issue
Block a user