app/resources/qml/Components/QrCodeScanPopup.qml

270 lines
7.6 KiB
QML
Raw Normal View History

import QtQuick 2.0
import QtQuick.Controls 2.12
import QtQuick.Layouts 1.12
import QZXing 3.1
import QtMultimedia 5.12
import QtQuick.Shapes 1.12
import QtQuick.Controls.Material 2.12
Dialog {
id: control
property string _statusText: ""
property string _statusColor: Material.primaryTextColor
property bool _freezeScanning: false
parent: Overlay.overlay
x: (parent.width - width) * 0.5
y: (parent.height - height) * 0.5
height: app.height * 0.8
width: app.width * 0.8
modal: true
2021-06-20 20:11:19 +02:00
//% "Scan QR-Code"
2021-06-20 21:08:59 +02:00
title: qsTrId("#scanQrCode")
standardButtons: Dialog.Cancel
onOpened: {
setDefaultStatusText()
control._freezeScanning = false
if(serverConn.isCameraPermissionGranted())
cameraLoader.sourceComponent = cameraComponent
else
cameraLoader.sourceComponent = noPermissionComponent
}
onClosed: cameraLoader.sourceComponent = null
function setDefaultStatusText() {
2021-06-20 20:11:19 +02:00
//% "Place the Code in the center"
2021-06-20 21:08:59 +02:00
_statusText = qsTrId("#placeQrCodeInCenter")
_statusColor = Material.primaryTextColor
}
contentItem: Loader {
id: cameraLoader
asynchronous: true
sourceComponent: null
}
Component {
id: cameraComponent
Item {
anchors.fill: parent
Camera {
id: camera
captureMode: Camera.CaptureStillImage
imageProcessing.whiteBalanceMode: CameraImageProcessing.WhiteBalanceAuto
focus {
focusMode: Camera.FocusContinuous
focusPointMode: Camera.FocusPointCenter
}
}
VideoOutput {
id: videoOutput
x: 0
y: 0
width: parent.width
height: parent.height
fillMode: VideoOutput.PreserveAspectCrop
source: camera
filters: [ zxingFilter ]
focus : visible // to receive focus and capture key events when visible
autoOrientation: true
MouseArea {
anchors.fill: parent
onClicked: {
if (camera.lockStatus !== Camera.Unlocked)
camera.unlock();
camera.searchAndLock();
}
}
Rectangle {
anchors {
top: parent.top
left: parent.left
right: app.landscape() ? focusIndicatorRect.left : parent.right
bottom: app.landscape() ? parent.bottom : focusIndicatorRect.top
}
opacity: focusIndicatorRect.opacity
color: focusIndicatorRect.border.color
}
Rectangle {
id: focusIndicatorRect
anchors.centerIn: parent
width: Math.min(parent.height, parent.width)
height: width
border.width: width * 0.1
border.color: "#000000"
opacity: 0.3
color: "transparent"
}
Rectangle {
anchors {
bottom: focusIndicatorRect.bottom
bottomMargin: height * 0.5
horizontalCenter: focusIndicatorRect.horizontalCenter
}
width: (focusIndicatorRect.width - focusIndicatorRect.border.width * 2) * 0.8
height: focusIndicatorRect.border.width
radius: height * 0.3
color: Material.backgroundColor
Material.elevation: 10
Label {
anchors {
fill: parent
margins: height * 0.1
}
color: control._statusColor
font.pixelSize: height * 0.5
fontSizeMode: Text.Fit
minimumPixelSize: height * 0.2
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignHCenter
text: control._statusText
}
}
Rectangle {
anchors {
top: app.landscape() ? parent.top : focusIndicatorRect.bottom
left: app.landscape() ? focusIndicatorRect.right : parent.left
right: parent.right
bottom: parent.bottom
}
opacity: focusIndicatorRect.opacity
color: focusIndicatorRect.border.color
}
}
}
}
Component {
id: noPermissionComponent
Item {
anchors.fill: parent
Label {
id: noPermissionIcon
anchors {
top: parent.top
topMargin: parent.height * 0
horizontalCenter: parent.horizontalCenter
}
font.pixelSize: parent.height * 0.3
font.family: fa5solid.name
text: "\uf3ed"
}
Label {
id: noPermissionText
anchors {
top: noPermissionIcon.bottom
topMargin: noPermissionIcon.height * 0.15
horizontalCenter: parent.horizontalCenter
}
width: parent.width * 0.9
font.bold: true
font.pixelSize: noPermissionIcon.height * 0.15
horizontalAlignment: Text.AlignHCenter
wrapMode: Text.Wrap
//% "Camera permission denied!"
text: qsTrId("#cameraPermissionDenied")
}
Label {
id: noPermissionDetailText
anchors {
top: noPermissionText.bottom
topMargin: noPermissionText.height * 0.15
horizontalCenter: parent.horizontalCenter
}
width: parent.width * 0.9
font.pixelSize: noPermissionText.font.pixelSize * 0.7
horizontalAlignment: Text.AlignHCenter
wrapMode: Text.Wrap
//% "This app requires access to your camera in order to scan QR-Codes. It will never record or store any photos or videos."
text: qsTrId("#cameraPermissionDeniedDetails")
}
}
}
QZXingFilter {
id: zxingFilter
decoder {
onTagFound: {
if(control._freezeScanning)
return
control._freezeScanning = true
2021-06-20 20:11:19 +02:00
//% "Plase wait"
2021-06-20 21:08:59 +02:00
control._statusText = qsTrId("#pleaseWait") + "..."
if(app.openWidgetFromUrl(tag))
control.close()
else {
2021-06-20 20:11:19 +02:00
//% "Invalid QR-Code"
2021-06-20 21:08:59 +02:00
control._statusText = qsTrId("#invalidQrCode")
control._statusColor = Material.color(Material.Red)
statusTextResetTimer.start()
control._freezeScanning = false
}
}
enabledDecoders: QZXing.DecoderFormat_QR_CODE
}
}
Timer {
id: statusTextResetTimer
running: false
repeat: false
interval: 3000
onTriggered: setDefaultStatusText()
}
}