2018-05-20 01:54:08 +02:00
|
|
|
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
|
2015-04-22 19:30:09 +02:00
|
|
|
|
2018-05-20 01:54:08 +02:00
|
|
|
Kirigami.ApplicationWindow {
|
2015-04-22 19:30:09 +02:00
|
|
|
id: root
|
2018-06-14 23:19:28 +02:00
|
|
|
property alias showPasswordsOnFocus: showPasswordsOnFocusSwitch.checked
|
2018-06-14 23:46:18 +02:00
|
|
|
property var entriesComponent: undefined
|
2018-05-20 01:54:08 +02:00
|
|
|
|
|
|
|
header: Kirigami.ApplicationHeader {
|
|
|
|
}
|
|
|
|
globalDrawer: Kirigami.GlobalDrawer {
|
|
|
|
id: leftMenu
|
|
|
|
title: qsTr("Password manager")
|
|
|
|
titleIcon: "passwordmanager"
|
2018-06-14 23:19:28 +02:00
|
|
|
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
|
2018-06-14 23:46:18 +02:00
|
|
|
text: nativeInterface.fileOpen ? nativeInterface.fileName : qsTr(
|
|
|
|
"No file opened")
|
2018-06-14 23:19:28 +02:00
|
|
|
}
|
|
|
|
}
|
2018-05-20 01:54:08 +02:00
|
|
|
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: "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()
|
2015-04-22 19:30:09 +02:00
|
|
|
}
|
2018-05-20 01:54:08 +02:00
|
|
|
]
|
2018-06-14 23:19:28 +02:00
|
|
|
Controls.Switch {
|
|
|
|
id: showPasswordsOnFocusSwitch
|
|
|
|
text: qsTr("Show passwords on focus")
|
|
|
|
checked: true
|
|
|
|
}
|
|
|
|
|
2018-06-12 22:02:37 +02:00
|
|
|
Controls.Label {
|
|
|
|
wrapMode: Controls.Label.Wrap
|
|
|
|
Layout.fillWidth: true
|
2018-06-14 23:46:18 +02:00
|
|
|
text: nativeInterface.fileOpen ? nativeInterface.filePath : qsTr(
|
|
|
|
"No file opened")
|
2015-04-22 19:30:09 +02:00
|
|
|
}
|
|
|
|
}
|
2018-06-12 22:02:37 +02:00
|
|
|
contextDrawer: Kirigami.ContextDrawer {
|
|
|
|
id: contextDrawer
|
|
|
|
}
|
2018-05-20 01:54:08 +02:00
|
|
|
Component.onCompleted: {
|
2018-06-14 23:46:18 +02:00
|
|
|
// load the entries component
|
|
|
|
entriesComponent = Qt.createComponent("EntriesPage.qml")
|
|
|
|
if (entriesComponent.status !== Component.Ready) {
|
|
|
|
var errorMessage = "Unable to load EntriesPage.qml: " + entriesComponent.errorString()
|
|
|
|
showPassiveNotification(errorMessage)
|
|
|
|
console.error(errorMessage)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2018-05-20 01:54:08 +02:00
|
|
|
// load file if one has been specified via CLI argument
|
|
|
|
if (nativeInterface.filePath.length) {
|
|
|
|
nativeInterface.load()
|
2015-04-22 19:30:09 +02:00
|
|
|
}
|
|
|
|
}
|
2018-06-14 23:46:18 +02:00
|
|
|
|
|
|
|
PasswordDialog {
|
|
|
|
id: enterPasswordDialog
|
|
|
|
}
|
|
|
|
|
|
|
|
FileDialog {
|
|
|
|
id: fileDialog
|
|
|
|
title: selectExisting ? qsTr("Select an existing file") : qsTr(
|
|
|
|
"Select path for new file")
|
|
|
|
onAccepted: {
|
|
|
|
if (fileUrls.length < 1) {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
nativeInterface.filePath = fileUrls[0]
|
|
|
|
if (selectExisting) {
|
|
|
|
nativeInterface.load()
|
|
|
|
} else {
|
|
|
|
nativeInterface.create()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
onRejected: {
|
|
|
|
showPassiveNotification(qsTr("Canceled file selection"))
|
|
|
|
}
|
|
|
|
|
|
|
|
function openExisting() {
|
|
|
|
this.selectExisting = true
|
|
|
|
this.open()
|
|
|
|
}
|
|
|
|
function createNew() {
|
|
|
|
this.selectExisting = false
|
|
|
|
this.open()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function clearStack() {
|
|
|
|
pageStack.pop(root.pageStack.initialPage, Controls.StackView.Immediate)
|
|
|
|
}
|
|
|
|
|
|
|
|
function pushStackEntry(entryModel, rootIndex) {
|
|
|
|
pageStack.push(entriesComponent.createObject(root, {
|
|
|
|
main: root,
|
|
|
|
entryModel: entryModel,
|
|
|
|
rootIndex: rootIndex,
|
|
|
|
title: entryModel.data(
|
|
|
|
rootIndex)
|
|
|
|
}))
|
|
|
|
}
|
2015-04-22 19:30:09 +02:00
|
|
|
}
|