app/resources/qml/Pages/QrCodeScanPage.qml

299 lines
8.1 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
2021-06-25 09:41:07 +02:00
import "../Components"
2021-06-25 09:41:07 +02:00
Page {
id: control
property string _statusText: ""
property string _statusColor: Material.primaryTextColor
property bool _freezeScanning: false
2021-06-25 09:41:07 +02:00
signal headerComponentChanged()
2021-06-20 20:11:19 +02:00
//% "Scan QR-Code"
2021-06-20 21:08:59 +02:00
title: qsTrId("#scanQrCode")
2021-06-25 09:41:07 +02:00
onFocusChanged: focus ? open() : close()
2021-06-25 09:41:07 +02:00
function open() {
_setDefaultStatusText()
control._freezeScanning = false
if(serverConn.isCameraPermissionGranted())
cameraLoader.sourceComponent = cameraComponent
else
cameraLoader.sourceComponent = noPermissionComponent
}
2021-06-25 09:41:07 +02:00
function close() {
cameraLoader.sourceComponent = null
}
2021-06-25 09:41:07 +02:00
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
}
2021-06-25 09:41:07 +02:00
function _handleTag(tag) {
if(control._freezeScanning)
return
control._freezeScanning = true
//% "Plase wait"
control._statusText = qsTrId("#pleaseWait") + "..."
if(app.openWidgetFromUrl(tag))
control.close()
else {
//% "Invalid QR-Code"
control._statusText = qsTrId("#invalidQrCode")
control._statusColor = Material.color(Material.Red)
statusTextResetTimer.start()
control._freezeScanning = false
}
}
function _requestCameraPermission() {
var permissionGranted = serverConn.requestCameraPermission()
if(permissionGranted)
cameraLoader.sourceComponent = cameraComponent
}
contentItem: Loader {
id: cameraLoader
2021-06-25 09:41:07 +02:00
anchors.fill: parent
//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
}
}
2021-06-25 09:41:07 +02:00
FancyBusyIndicator {
anchors.centerIn: parent
}
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"
2021-06-25 09:41:07 +02:00
opacity: 0.5
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
2021-06-25 09:41:07 +02:00
ColumnLayout {
//anchors.fill: parent
//anchors.margins: app.landscape() ? app.height * 0.1 : app.width * 0.1
property int columnWidth: control.width * 0.9
spacing: height * 0.02
Item {
Layout.fillHeight: true
}
Label {
id: noPermissionIcon
2021-06-25 09:41:07 +02:00
Layout.preferredWidth: parent.columnWidth
Layout.alignment: Layout.Center
font.pixelSize: app.landscape() ? parent.height * 0.25:parent.height * 0.15
font.family: fa5solid.name
2021-06-25 09:41:07 +02:00
horizontalAlignment: Text.AlignHCenter
text: "\uf3ed"
}
Label {
id: noPermissionText
2021-06-25 09:41:07 +02:00
Layout.preferredWidth: parent.columnWidth
Layout.alignment: Layout.Center
font.bold: true
2021-06-25 09:41:07 +02:00
font.pixelSize: noPermissionIcon.height * 0.2
horizontalAlignment: Text.AlignHCenter
wrapMode: Text.Wrap
2021-06-25 09:41:07 +02:00
//% "Camera access required"
text: qsTrId("#cameraPermissionDenied")
}
Label {
id: noPermissionDetailText
2021-06-25 09:41:07 +02:00
Layout.preferredWidth: parent.columnWidth
Layout.alignment: Layout.Center
font.pixelSize: noPermissionText.font.pixelSize * 0.7
horizontalAlignment: Text.AlignHCenter
wrapMode: Text.Wrap
2021-06-25 09:41:07 +02:00
//% "blueROCK needs to access your camera in order to scan QR-Codes. It will never record or store any photos or videos."
text: qsTrId("#cameraPermissionDeniedDetails")
}
2021-06-25 09:41:07 +02:00
Button {
id: grantPermissionButton
Layout.alignment: Layout.Center
//% "Allow access"
text: qsTrId("#allowAccess")
onClicked: control._requestCameraPermission()
}
Item {
Layout.fillHeight: true
}
}
}
QZXingFilter {
id: zxingFilter
decoder {
2021-06-25 09:41:07 +02:00
onTagFound: control._handleTag(tag)
enabledDecoders: QZXing.DecoderFormat_QR_CODE
}
}
Timer {
id: statusTextResetTimer
running: false
repeat: false
interval: 3000
2021-06-25 09:41:07 +02:00
onTriggered: _setDefaultStatusText()
}
}