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 //% "Scan QR-Code" 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() { //% "Place the Code in the center" _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 //% "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 } } enabledDecoders: QZXing.DecoderFormat_QR_CODE } } Timer { id: statusTextResetTimer running: false repeat: false interval: 3000 onTriggered: setDefaultStatusText() } }