passwordmanager/qml/EntriesPage.qml

182 lines
6.4 KiB
QML

import QtQuick 2.15
import QtQuick.Layouts 1.2
import QtQml.Models 2.2
import QtQuick.Controls 2.4 as Controls
import org.kde.kirigami 2.5 as Kirigami
Kirigami.ScrollablePage {
id: page
property var main: undefined
property alias entryModel: delegateModel.model
property alias rootIndex: delegateModel.rootIndex
Layout.fillWidth: true
title: {
var currentEntryName = entryModel.data(rootIndex)
return currentEntryName ? currentEntryName : ""
}
actions:[
Kirigami.Action {
icon.name: "list-add"
text: qsTr("Add account")
visible: !nativeInterface.hasEntryFilter
enabled: !nativeInterface.hasEntryFilter
onTriggered: insertEntry("Account")
shortcut: "Ctrl+A"
},
Kirigami.Action {
icon.name: "edit-paste"
text: qsTr("Paste account")
visible: !nativeInterface.hasEntryFilter
enabled: nativeInterface.canPaste && !nativeInterface.hasEntryFilter
onTriggered: {
var pastedEntries = nativeInterface.pasteEntries(rootIndex)
if (pastedEntries.length < 1) {
showPassiveNotification(
qsTr("Unable to paste the entries here"))
return
}
showPassiveNotification(qsTr("Pasted %1").arg(
pastedEntries.join(", ")))
}
shortcut: StandardKey.Paste
},
Kirigami.Action {
icon.name: "folder-add"
text: qsTr("Add category")
visible: !nativeInterface.hasEntryFilter
enabled: !nativeInterface.hasEntryFilter
onTriggered: insertEntry("Node")
shortcut: "Ctrl+Shift+A"
}
]
// dialog to confirm deletion of an entry
BasicDialog {
id: confirmDeletionDialog
property string entryDesc: "?"
property int entryIndex: -1
standardButtons: Controls.Dialog.Ok | Controls.Dialog.Cancel
title: qsTr("Delete %1?").arg(entryDesc)
onAccepted: entryModel.removeRows(this.entryIndex, 1, rootIndex)
contentItem: ColumnLayout {
Controls.Label {
text: " "
}
}
function confirmDeletion(entryName, entryIndex) {
var isNode = entryModel.isNode(entryModel.index(entryIndex, 0,
rootIndex))
var entryType = isNode ? qsTr("category ") : qsTr("account ")
this.entryIndex = entryIndex
this.entryDesc = entryType + entryName
// skip dialog if undo is supported
if (nativeInterface.undoStack) {
entryModel.removeRows(entryIndex, 1, rootIndex)
showPassiveNotification(qsTr("Deleted %1").arg(entryDesc))
return
}
this.open()
}
}
// dialog to rename an entry
BasicDialog {
id: renameDialog
property string entryDesc: "?"
property int entryIndex: -1
property alias newEntryName: entryNameTextField.text
property bool entryNew: false
standardButtons: newEntryName.length
> 0 ? Controls.Dialog.Ok | Controls.Dialog.Cancel : Controls.Dialog.Cancel
title: entryNew ? qsTr("Name for new %1").arg(entryDesc) : qsTr(
"Rename %1").arg(entryDesc)
onAccepted: {
entryModel.setData(entryModel.index(this.entryIndex, 0, rootIndex),
newEntryName)
}
onRejected: {
if (this.entryNew) {
entryModel.removeRows(this.entryIndex, 1, rootIndex)
}
}
contentItem: ColumnLayout {
Controls.TextField {
id: entryNameTextField
Layout.preferredWidth: renameDialog.availableWidth
placeholderText: qsTr("enter new name here")
Keys.onPressed: (event) => renameDialog.acceptOnReturn(event)
}
}
function renameEntry(entryName, entryIndex) {
var isNode = entryModel.isNode(entryModel.index(entryIndex, 0,
rootIndex))
var entryType = isNode ? qsTr("category ") : qsTr("account ")
this.entryIndex = entryIndex
this.entryNew = entryName === null
if (this.entryNew) {
this.entryDesc = entryType
this.newEntryName = ""
} else {
this.entryDesc = entryType + entryName
this.newEntryName = entryName
}
entryNameTextField.forceActiveFocus()
this.open()
}
}
// list view to display one hierarchy level of entry model
ListView {
id: entriesListView
anchors.fill: parent
moveDisplaced: Transition {
YAnimator {
duration: Kirigami.Units.longDuration
easing.type: Easing.InOutQuad
}
}
reuseItems: true
model: DelegateModel {
id: delegateModel
delegate: EntryDelegate {
width: entriesListView.width
view: entriesListView
onMoveRequested:
(oldIndex, newIndex) => {
entryModel.moveRows(rootIndex, oldIndex, 1, rootIndex, oldIndex < newIndex ? newIndex + 1 : newIndex)
}
}
function isNode(rowNumber) {
return entryModel.isNode(entryModel.index(rowNumber, 0,
rootIndex))
}
function handleEntryClicked(rowNumber, entryName) {
var modelIndex = entryModel.index(rowNumber, 0, rootIndex)
if (entryModel.isNode(modelIndex)) {
root.pushStackEntry(entryModel, modelIndex)
} else {
nativeInterface.currentAccountIndex = modelIndex
root.pushAccountEdit()
}
}
}
}
function insertEntry(entryType) {
var newIndex = entryModel.rowCount(rootIndex)
entryModel["setInsertTypeTo" + entryType]()
entryModel.insertRows(newIndex, 1, rootIndex)
renameDialog.renameEntry(null, newIndex)
}
}