204 lines
6.8 KiB
QML
204 lines
6.8 KiB
QML
import QtQuick 2.7
|
|
import QtQuick.Controls 2.1 as Controls
|
|
import QtQuick.Layouts 1.2
|
|
import QtQuick.Dialogs 1.3
|
|
import org.kde.kirigami 2.4 as Kirigami
|
|
|
|
Kirigami.ApplicationWindow {
|
|
id: root
|
|
property alias showPasswordsOnFocus: showPasswordsOnFocusSwitch.checked
|
|
|
|
header: Kirigami.ApplicationHeader {
|
|
}
|
|
globalDrawer: Kirigami.GlobalDrawer {
|
|
id: leftMenu
|
|
title: qsTr("Password Manager")
|
|
titleIcon: "qrc://icons/hicolor/scalable/apps/passwordmanager.svg"
|
|
visible: !nativeInterface.fileOpen
|
|
topContent: ColumnLayout {
|
|
Layout.fillWidth: true
|
|
|
|
Controls.MenuSeparator {
|
|
padding: 0
|
|
topPadding: 8
|
|
bottomPadding: 0
|
|
Layout.fillWidth: true
|
|
}
|
|
Controls.Label {
|
|
padding: 8
|
|
wrapMode: Controls.Label.Wrap
|
|
fontSizeMode: Text.HorizontalFit
|
|
minimumPixelSize: 10
|
|
font.pixelSize: 20
|
|
Layout.fillWidth: true
|
|
text: nativeInterface.fileOpen ? nativeInterface.fileName : qsTr(
|
|
"No file opened")
|
|
}
|
|
}
|
|
actions: [
|
|
Kirigami.Action {
|
|
text: qsTr("Create new file")
|
|
iconName: "document-new"
|
|
onTriggered: fileDialog.createNew()
|
|
},
|
|
Kirigami.Action {
|
|
text: qsTr("Open existing file")
|
|
iconName: "document-open"
|
|
onTriggered: fileDialog.openExisting()
|
|
},
|
|
Kirigami.Action {
|
|
text: qsTr("Recently opened ...")
|
|
iconName: "document-open-recent"
|
|
children: createFileActions(nativeInterface.recentFiles)
|
|
},
|
|
Kirigami.Action {
|
|
text: "Save modifications"
|
|
enabled: nativeInterface.fileOpen
|
|
iconName: "document-save"
|
|
onTriggered: nativeInterface.save()
|
|
},
|
|
Kirigami.Action {
|
|
text: "Change password"
|
|
enabled: nativeInterface.fileOpen
|
|
iconName: "dialog-password"
|
|
onTriggered: enterPasswordDialog.askForNewPassword(
|
|
"Change password for " + nativeInterface.filePath)
|
|
},
|
|
Kirigami.Action {
|
|
text: "Close file"
|
|
enabled: nativeInterface.fileOpen
|
|
iconName: "document-close"
|
|
onTriggered: nativeInterface.close()
|
|
}
|
|
]
|
|
Controls.Switch {
|
|
text: qsTr("Use native file dialog")
|
|
checked: nativeInterface.useNativeFileDialog
|
|
visible: nativeInterface.supportsNativeFileDialog
|
|
onCheckedChanged: nativeInterface.useNativeFileDialog = checked
|
|
}
|
|
Controls.Switch {
|
|
id: showPasswordsOnFocusSwitch
|
|
text: qsTr("Show passwords on focus")
|
|
checked: true
|
|
}
|
|
|
|
Controls.Label {
|
|
wrapMode: Controls.Label.Wrap
|
|
Layout.fillWidth: true
|
|
text: nativeInterface.fileOpen ? nativeInterface.filePath : qsTr(
|
|
"No file opened")
|
|
}
|
|
}
|
|
contextDrawer: Kirigami.ContextDrawer {
|
|
id: contextDrawer
|
|
}
|
|
Component.onCompleted: nativeInterface.init()
|
|
|
|
PasswordDialog {
|
|
id: enterPasswordDialog
|
|
}
|
|
|
|
FileDialog {
|
|
id: fileDialog
|
|
title: selectExisting ? qsTr("Select an existing file") : qsTr(
|
|
"Select path for new file")
|
|
property bool selectExisting: true
|
|
|
|
onAccepted: {
|
|
if (fileUrls.length < 1) {
|
|
return
|
|
}
|
|
nativeInterface.handleFileSelectionAccepted(fileUrls[0],
|
|
this.selectExisting)
|
|
}
|
|
onRejected: nativeInterface.handleFileSelectionCanceled()
|
|
|
|
function show() {
|
|
if (nativeInterface.showNativeFileDialog(this.selectExisting)) {
|
|
return
|
|
}
|
|
// fallback to the Qt Quick file dialog if a native implementation is not available
|
|
this.open()
|
|
}
|
|
function openExisting() {
|
|
this.selectExisting = true
|
|
this.show()
|
|
}
|
|
function createNew() {
|
|
this.selectExisting = false
|
|
this.show()
|
|
}
|
|
}
|
|
|
|
Connections {
|
|
target: nativeInterface
|
|
onFileError: {
|
|
showPassiveNotification(errorMessage)
|
|
}
|
|
onPasswordRequired: {
|
|
enterPasswordDialog.askForExistingPassword(
|
|
qsTr("Password required to open %1").arg(
|
|
nativeInterface.filePath))
|
|
leftMenu.resetMenu()
|
|
}
|
|
onFileOpenChanged: {
|
|
clearStack()
|
|
if (!nativeInterface.fileOpen) {
|
|
showPassiveNotification(qsTr("%1 closed").arg(
|
|
nativeInterface.fileName))
|
|
return
|
|
}
|
|
var entryModel = nativeInterface.entryModel
|
|
var rootIndex = entryModel.index(0, 0)
|
|
pushStackEntry(entryModel, rootIndex)
|
|
showPassiveNotification(qsTr("%1 opened").arg(
|
|
nativeInterface.fileName))
|
|
}
|
|
onFileSaved: {
|
|
showPassiveNotification(qsTr("%1 saved").arg(
|
|
nativeInterface.fileName))
|
|
}
|
|
onNewNotification: {
|
|
showPassiveNotification(message)
|
|
}
|
|
}
|
|
|
|
Component {
|
|
id: fileActionComponent
|
|
Kirigami.Action {
|
|
property string filePath
|
|
text: filePath.substring(filePath.lastIndexOf('/') + 1)
|
|
onTriggered: nativeInterface.load(filePath)
|
|
}
|
|
}
|
|
|
|
Component {
|
|
id: entriesComponent
|
|
EntriesPage {
|
|
main: root
|
|
}
|
|
}
|
|
|
|
function clearStack() {
|
|
pageStack.pop(root.pageStack.initialPage, Controls.StackView.Immediate)
|
|
}
|
|
|
|
function pushStackEntry(entryModel, rootIndex) {
|
|
pageStack.push(entriesComponent.createObject(root, {
|
|
"entryModel": entryModel,
|
|
"rootIndex": rootIndex,
|
|
"title": entryModel.data(
|
|
rootIndex)
|
|
}))
|
|
}
|
|
|
|
function createFileActions(files) {
|
|
return files.map(function (filePath) {
|
|
return this.createObject(root, {
|
|
"filePath": filePath
|
|
})
|
|
}, fileActionComponent)
|
|
}
|
|
}
|