From 6744dce57e3ad030b8eaaa347a4e77b31746da67 Mon Sep 17 00:00:00 2001 From: eugenyorbitsoftcom Date: Wed, 6 Jul 2022 11:04:46 +0600 Subject: [PATCH 1/2] QRCodeReader (WIP) --- client/client.pro | 8 +- client/main.cpp | 3 + client/platforms/ios/QRCodeReader.h | 28 ++++ client/platforms/ios/QRCodeReader.mm | 109 +++++++++++++++ client/ui/qml/Pages/PageQrDecoder.qml | 193 ++++++++++++++------------ 5 files changed, 251 insertions(+), 90 deletions(-) create mode 100644 client/platforms/ios/QRCodeReader.h create mode 100644 client/platforms/ios/QRCodeReader.mm diff --git a/client/client.pro b/client/client.pro index 1cc9dbd2..b6b00330 100644 --- a/client/client.pro +++ b/client/client.pro @@ -296,15 +296,17 @@ ios { platforms/ios/bigint.h \ platforms/ios/bigintipv6addr.h \ platforms/ios/ipaddress.h \ - platforms/ios/ipaddressrange.h - + platforms/ios/ipaddressrange.h \ + platforms/ios/QRCodeReader.h + SOURCES += \ protocols/ios_vpnprotocol.mm \ platforms/ios/iosnotificationhandler.mm \ platforms/ios/json.cpp \ platforms/ios/iosglue.mm \ platforms/ios/ipaddress.cpp \ - platforms/ios/ipaddressrange.cpp + platforms/ios/ipaddressrange.cpp \ + platforms/ios/QRCodeReader.mm Q_ENABLE_BITCODE.value = NO Q_ENABLE_BITCODE.name = ENABLE_BITCODE diff --git a/client/main.cpp b/client/main.cpp index 9cdab7eb..b1419f18 100644 --- a/client/main.cpp +++ b/client/main.cpp @@ -37,6 +37,8 @@ #include "QZXing.h" +#include "platforms/ios/QRCodeReader.h" + #include "debug.h" #include "defines.h" @@ -167,6 +169,7 @@ int main(int argc, char *argv[]) declareQmlContainerEnum(); qmlRegisterType("PageType", 1, 0, "PageType"); + qmlRegisterType("QRCodeReader", 1, 0, "QRCodeReader"); QScopedPointer containerProps(new ContainerProps); qmlRegisterSingletonInstance("ContainerProps", 1, 0, "ContainerProps", containerProps.get()); diff --git a/client/platforms/ios/QRCodeReader.h b/client/platforms/ios/QRCodeReader.h new file mode 100644 index 00000000..bc8c9925 --- /dev/null +++ b/client/platforms/ios/QRCodeReader.h @@ -0,0 +1,28 @@ +#ifndef QRCODEREADER_H +#define QRCODEREADER_H + +#include +#include + +class QRCodeReader: public QObject { + Q_OBJECT + +public: + QRCodeReader(); + + QRect cameraSize(); + +public slots: + void startReading(); + void stopReading(); + void setCameraSize(QRect value); + +signals: + void codeReaded(QString code); + +private: + void* m_qrCodeReader; + QRect m_cameraSize; +}; + +#endif // QRCODEREADER_H diff --git a/client/platforms/ios/QRCodeReader.mm b/client/platforms/ios/QRCodeReader.mm new file mode 100644 index 00000000..85f71ba6 --- /dev/null +++ b/client/platforms/ios/QRCodeReader.mm @@ -0,0 +1,109 @@ +#include "QRCodeReader.h" + +#import +#import + +@interface QRCodeReaderImpl : UIViewController +@end + +@interface QRCodeReaderImpl () +@property (nonatomic) QRCodeReader* qrCodeReader; +@property (nonatomic, strong) AVCaptureSession *captureSession; +@property (nonatomic, strong) AVCaptureVideoPreviewLayer *videoPreviewPlayer; +@end + + +@implementation QRCodeReaderImpl + +- (void)viewDidLoad { + [super viewDidLoad]; + + _captureSession = nil; +} + +- (void)setQrCodeReader: (QRCodeReader*)value { + _qrCodeReader = value; +} + +- (BOOL)startReading { + NSError *error; + + AVCaptureDevice *captureDevice = [AVCaptureDevice defaultDeviceWithMediaType: AVMediaTypeVideo]; + AVCaptureDeviceInput *deviceInput = [AVCaptureDeviceInput deviceInputWithDevice: captureDevice error: &error]; + + if(!deviceInput) { + NSLog(@"Error %@", error.localizedDescription); + return NO; + } + + _captureSession = [[AVCaptureSession alloc]init]; + [_captureSession addInput:deviceInput]; + + AVCaptureMetadataOutput *capturedMetadataOutput = [[AVCaptureMetadataOutput alloc] init]; + [_captureSession addOutput:capturedMetadataOutput]; + + dispatch_queue_t dispatchQueue; + dispatchQueue = dispatch_queue_create("myQueue", NULL); + [capturedMetadataOutput setMetadataObjectsDelegate: self queue: dispatchQueue]; + [capturedMetadataOutput setMetadataObjectTypes: [NSArray arrayWithObject:AVMetadataObjectTypeQRCode]]; + + _videoPreviewPlayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession: _captureSession]; + + CGFloat tabBarHeight = 20.0; + QRect cameraRect = _qrCodeReader->cameraSize(); + CGRect cameraCGRect = CGRectMake(cameraRect.x(), + cameraRect.y() + tabBarHeight, + cameraRect.width(), + cameraRect.height()); + + [_videoPreviewPlayer setVideoGravity: AVLayerVideoGravityResizeAspect]; + [_videoPreviewPlayer setFrame: cameraCGRect]; + + CALayer* layer = [UIApplication sharedApplication].keyWindow.layer; + [layer addSublayer: _videoPreviewPlayer]; + + [_captureSession startRunning]; + + return YES; +} + +- (void)stopReading { + [_captureSession stopRunning]; + _captureSession = nil; + + [_videoPreviewPlayer removeFromSuperlayer]; +} + +- (void)captureOutput:(AVCaptureOutput *)output didOutputMetadataObjects:(NSArray<__kindof AVMetadataObject *> *)metadataObjects fromConnection:(AVCaptureConnection *)connection { + + if (metadataObjects != nil && metadataObjects.count > 0) { + AVMetadataMachineReadableCodeObject *metadataObject = [metadataObjects objectAtIndex:0]; + + if ([[metadataObject type] isEqualToString: AVMetadataObjectTypeQRCode]) { + _qrCodeReader->emit codeReaded([metadataObject stringValue].UTF8String); + } + } +} + +@end + +QRCodeReader::QRCodeReader() { + m_qrCodeReader = [[QRCodeReaderImpl alloc] init]; + [m_qrCodeReader setQrCodeReader: this]; +} + +QRect QRCodeReader::cameraSize() { + return m_cameraSize; +} + +void QRCodeReader::setCameraSize(QRect value) { + m_cameraSize = value; +} + +void QRCodeReader::startReading() { + [m_qrCodeReader startReading]; +} + +void QRCodeReader::stopReading() { + [m_qrCodeReader stopReading]; +} diff --git a/client/ui/qml/Pages/PageQrDecoder.qml b/client/ui/qml/Pages/PageQrDecoder.qml index 6506b7fa..ead2dde3 100644 --- a/client/ui/qml/Pages/PageQrDecoder.qml +++ b/client/ui/qml/Pages/PageQrDecoder.qml @@ -3,6 +3,7 @@ import QtQuick.Controls 2.12 import PageEnum 1.0 import QtMultimedia 5.5 import QZXing 3.2 +import QRCodeReader 1.0 import "./" import "../Controls" @@ -51,108 +52,126 @@ PageBase { Item { anchors.fill: parent - Camera - { - id:camera - focus { - focusMode: CameraFocus.FocusContinuous - focusPointMode: CameraFocus.FocusPointAuto + + QRCodeReader { + id: qrCodeReader + + onCodeReaded: { + QrDecoderLogic.onDetectedQrCode(code) } + + Component.onCompleted: { + qrCodeReader.setCameraSize(Qt.rect(loader.x, + loader.y, + loader.width, + loader.height)) + qrCodeReader.startReading() + } + Component.onDestruction: qrCodeReader.stopReading() } - VideoOutput - { - id: videoOutput - source: camera - anchors.top: parent.top - anchors.bottom: parent.bottom - anchors.left: parent.left - anchors.right: parent.right - autoOrientation: true - fillMode: VideoOutput.PreserveAspectFit - filters: [ zxingFilter ] +// Camera +// { +// id:camera +// focus { +// focusMode: CameraFocus.FocusContinuous +// focusPointMode: CameraFocus.FocusPointAuto +// } +// } + +// VideoOutput +// { +// id: videoOutput +// source: camera +// anchors.top: parent.top +// anchors.bottom: parent.bottom +// anchors.left: parent.left +// anchors.right: parent.right +// autoOrientation: true +// fillMode: VideoOutput.PreserveAspectFit +// filters: [ zxingFilter ] - Rectangle { - color: "black" - opacity: 0.5 - width: videoOutput.contentRect.width *0.15 - height: videoOutput.contentRect.height - x: (videoOutput.width - videoOutput.contentRect.width)/2 - anchors.verticalCenter: videoOutput.verticalCenter - } +// Rectangle { +// color: "black" +// opacity: 0.5 +// width: videoOutput.contentRect.width * 0.15 +// height: videoOutput.contentRect.height +// x: (videoOutput.width - videoOutput.contentRect.width)/2 +// anchors.verticalCenter: videoOutput.verticalCenter +// } - Rectangle { - color: "black" - opacity: 0.5 - width: videoOutput.contentRect.width *0.15 - height: videoOutput.contentRect.height - x: videoOutput.width/2 + videoOutput.contentRect.width/2 - videoOutput.contentRect.width *0.15 - anchors.verticalCenter: videoOutput.verticalCenter - } +// Rectangle { +// color: "black" +// opacity: 0.5 +// width: videoOutput.contentRect.width * 0.15 +// height: videoOutput.contentRect.height +// x: videoOutput.width/2 + videoOutput.contentRect.width/2 - videoOutput.contentRect.width * 0.15 +// anchors.verticalCenter: videoOutput.verticalCenter +// } - Rectangle { - color: "black" - opacity: 0.5 - width: videoOutput.contentRect.width *0.7 - height: videoOutput.contentRect.height *0.15 - x: (videoOutput.width - videoOutput.contentRect.width)/2 + videoOutput.contentRect.width *0.15 - y: (videoOutput.height - videoOutput.contentRect.height)/2 - } +// Rectangle { +// color: "black" +// opacity: 0.5 +// width: videoOutput.contentRect.width * 0.7 +// height: videoOutput.contentRect.height * 0.15 +// x: (videoOutput.width - videoOutput.contentRect.width)/2 + videoOutput.contentRect.width * 0.15 +// y: (videoOutput.height - videoOutput.contentRect.height)/2 +// } - Rectangle { - color: "black" - opacity: 0.5 - width: videoOutput.contentRect.width *0.7 - height: videoOutput.contentRect.height *0.15 - x: (videoOutput.width - videoOutput.contentRect.width)/2 + videoOutput.contentRect.width *0.15 - y: videoOutput.height/2 + videoOutput.contentRect.height/2 - videoOutput.contentRect.height *0.15 - } +// Rectangle { +// color: "black" +// opacity: 0.5 +// width: videoOutput.contentRect.width * 0.7 +// height: videoOutput.contentRect.height * 0.15 +// x: (videoOutput.width - videoOutput.contentRect.width)/2 + videoOutput.contentRect.width * 0.15 +// y: videoOutput.height/2 + videoOutput.contentRect.height/2 - videoOutput.contentRect.height * 0.15 +// } - LabelType { - width: parent.width - text: qsTr("Decoded QR chunks " + QrDecoderLogic.receivedChunksCount + "/" + QrDecoderLogic.totalChunksCount) - horizontalAlignment: Text.AlignLeft - visible: QrDecoderLogic.totalChunksCount > 0 - anchors.horizontalCenter: videoOutput.horizontalCenter - y: videoOutput.height/2 + videoOutput.contentRect.height/2 - } - } +// LabelType { +// width: parent.width +// text: qsTr("Decoded QR chunks " + QrDecoderLogic.receivedChunksCount + "/" + QrDecoderLogic.totalChunksCount) +// horizontalAlignment: Text.AlignLeft +// visible: QrDecoderLogic.totalChunksCount > 0 +// anchors.horizontalCenter: videoOutput.horizontalCenter +// y: videoOutput.height/2 + videoOutput.contentRect.height/2 +// } +// } - QZXingFilter - { - id: zxingFilter - orientation: videoOutput.orientation - captureRect: { - // setup bindings - videoOutput.contentRect; - videoOutput.sourceRect; - return videoOutput.mapRectToSource(videoOutput.mapNormalizedRectToItem(Qt.rect( - 0.15, 0.15, 0.7, 0.7 //0, 0, 1.0, 1.0 - ))); - } +// QZXingFilter +// { +// id: zxingFilter +// orientation: videoOutput.orientation +// captureRect: { +// // setup bindings +// videoOutput.contentRect; +// videoOutput.sourceRect; +// return videoOutput.mapRectToSource(videoOutput.mapNormalizedRectToItem(Qt.rect( +// 0.15, 0.15, 0.7, 0.7 //0, 0, 1.0, 1.0 +// ))); +// } - decoder { - enabledDecoders: QZXing.DecoderFormat_QR_CODE +// decoder { +// enabledDecoders: QZXing.DecoderFormat_QR_CODE - onTagFound: { - QrDecoderLogic.onDetectedQrCode(tag) - } +// onTagFound: { +// QrDecoderLogic.onDetectedQrCode(tag) +// } - tryHarder: true - } +// tryHarder: true +// } - property int framesDecoded: 0 - property real timePerFrameDecode: 0 +// property int framesDecoded: 0 +// property real timePerFrameDecode: 0 - onDecodingFinished: - { - timePerFrameDecode = (decodeTime + framesDecoded * timePerFrameDecode) / (framesDecoded + 1); - framesDecoded++; - if(succeeded) - console.log("frame finished: " + succeeded, decodeTime, timePerFrameDecode, framesDecoded); - } - } +// onDecodingFinished: +// { +// timePerFrameDecode = (decodeTime + framesDecoded * timePerFrameDecode) / (framesDecoded + 1); +// framesDecoded++; +// if(succeeded) +// console.log("frame finished: " + succeeded, decodeTime, timePerFrameDecode, framesDecoded); +// } +// } } From 9aabe7c72eec5511c38fda33c18b660ba991199d Mon Sep 17 00:00:00 2001 From: eugenyorbitsoftcom Date: Wed, 6 Jul 2022 14:02:56 +0600 Subject: [PATCH 2/2] QRCodeReader for iOS --- client/client.pro | 15 +- client/platforms/ios/QRCodeReader.cpp | 14 ++ client/resources.qrc | 1 + client/ui/pages.h | 2 +- client/ui/qml/Pages/PageQrDecoder.qml | 194 ++++++++++------------- client/ui/qml/Pages/PageQrDecoderIos.qml | 76 +++++++++ client/ui/qml/Pages/PageStart.qml | 6 +- 7 files changed, 194 insertions(+), 114 deletions(-) create mode 100644 client/platforms/ios/QRCodeReader.cpp create mode 100644 client/ui/qml/Pages/PageQrDecoderIos.qml diff --git a/client/client.pro b/client/client.pro index b6b00330..c972acc8 100644 --- a/client/client.pro +++ b/client/client.pro @@ -75,7 +75,8 @@ HEADERS += \ logger.h \ loghandler.h \ loglevel.h \ - constants.h + constants.h \ + platforms/ios/QRCodeReader.h SOURCES += \ configurators/cloak_configurator.cpp \ @@ -126,8 +127,8 @@ SOURCES += \ vpnconnection.cpp \ protocols/vpnprotocol.cpp \ logger.cpp \ - loghandler.cpp - + loghandler.cpp \ + platforms/ios/QRCodeReader.cpp RESOURCES += \ resources.qrc @@ -296,10 +297,12 @@ ios { platforms/ios/bigint.h \ platforms/ios/bigintipv6addr.h \ platforms/ios/ipaddress.h \ - platforms/ios/ipaddressrange.h \ - platforms/ios/QRCodeReader.h + platforms/ios/ipaddressrange.h - SOURCES += \ + SOURCES -= \ + platforms/ios/QRCodeReader.cpp + + SOURCES += \ protocols/ios_vpnprotocol.mm \ platforms/ios/iosnotificationhandler.mm \ platforms/ios/json.cpp \ diff --git a/client/platforms/ios/QRCodeReader.cpp b/client/platforms/ios/QRCodeReader.cpp new file mode 100644 index 00000000..c422a0e7 --- /dev/null +++ b/client/platforms/ios/QRCodeReader.cpp @@ -0,0 +1,14 @@ +#include "QRCodeReader.h" + +QRCodeReader::QRCodeReader() +{ + +} + +QRect QRCodeReader::cameraSize() { + return QRect(); +} + +void QRCodeReader::startReading() {} +void QRCodeReader::stopReading() {} +void QRCodeReader::setCameraSize(QRect) {}; diff --git a/client/resources.qrc b/client/resources.qrc index cb7877ff..db61db33 100644 --- a/client/resources.qrc +++ b/client/resources.qrc @@ -157,5 +157,6 @@ images/svg/control_point_black_24dp.svg images/svg/settings_suggest_black_24dp.svg ui/qml/Controls/SvgButtonType.qml + ui/qml/Pages/PageQrDecoderIos.qml diff --git a/client/ui/pages.h b/client/ui/pages.h index b111679a..d74c64a6 100644 --- a/client/ui/pages.h +++ b/client/ui/pages.h @@ -24,7 +24,7 @@ enum class Page {Start = 0, NewServer, NewServerProtocols, Vpn, Wizard, WizardLow, WizardMedium, WizardHigh, WizardVpnMode, ServerConfiguringProgress, GeneralSettings, AppSettings, NetworkSettings, ServerSettings, ServerContainers, ServersList, ShareConnection, Sites, - ProtocolSettings, ProtocolShare, QrDecoder, About}; + ProtocolSettings, ProtocolShare, QrDecoder, QrDecoderIos, About}; Q_ENUM_NS(Page) static void declareQmlPageEnum() { diff --git a/client/ui/qml/Pages/PageQrDecoder.qml b/client/ui/qml/Pages/PageQrDecoder.qml index ead2dde3..f432b742 100644 --- a/client/ui/qml/Pages/PageQrDecoder.qml +++ b/client/ui/qml/Pages/PageQrDecoder.qml @@ -3,7 +3,6 @@ import QtQuick.Controls 2.12 import PageEnum 1.0 import QtMultimedia 5.5 import QZXing 3.2 -import QRCodeReader 1.0 import "./" import "../Controls" @@ -27,7 +26,7 @@ PageBase { } Connections { - target: QrDecoderLogic + target: Qt.platform.os != "ios" ? QrDecoderLogic : nil function onStartDecode() { console.debug("Starting QR decoder") loader.sourceComponent = component @@ -53,125 +52,108 @@ PageBase { Item { anchors.fill: parent - QRCodeReader { - id: qrCodeReader - - onCodeReaded: { - QrDecoderLogic.onDetectedQrCode(code) + Camera + { + id:camera + focus { + focusMode: CameraFocus.FocusContinuous + focusPointMode: CameraFocus.FocusPointAuto } - - Component.onCompleted: { - qrCodeReader.setCameraSize(Qt.rect(loader.x, - loader.y, - loader.width, - loader.height)) - qrCodeReader.startReading() - } - Component.onDestruction: qrCodeReader.stopReading() } -// Camera -// { -// id:camera -// focus { -// focusMode: CameraFocus.FocusContinuous -// focusPointMode: CameraFocus.FocusPointAuto -// } -// } - -// VideoOutput -// { -// id: videoOutput -// source: camera -// anchors.top: parent.top -// anchors.bottom: parent.bottom -// anchors.left: parent.left -// anchors.right: parent.right -// autoOrientation: true -// fillMode: VideoOutput.PreserveAspectFit -// filters: [ zxingFilter ] + VideoOutput + { + id: videoOutput + source: camera + anchors.top: parent.top + anchors.bottom: parent.bottom + anchors.left: parent.left + anchors.right: parent.right + autoOrientation: true + fillMode: VideoOutput.PreserveAspectFit + filters: [ zxingFilter ] -// Rectangle { -// color: "black" -// opacity: 0.5 -// width: videoOutput.contentRect.width * 0.15 -// height: videoOutput.contentRect.height -// x: (videoOutput.width - videoOutput.contentRect.width)/2 -// anchors.verticalCenter: videoOutput.verticalCenter -// } + Rectangle { + color: "black" + opacity: 0.5 + width: videoOutput.contentRect.width * 0.15 + height: videoOutput.contentRect.height + x: (videoOutput.width - videoOutput.contentRect.width)/2 + anchors.verticalCenter: videoOutput.verticalCenter + } -// Rectangle { -// color: "black" -// opacity: 0.5 -// width: videoOutput.contentRect.width * 0.15 -// height: videoOutput.contentRect.height -// x: videoOutput.width/2 + videoOutput.contentRect.width/2 - videoOutput.contentRect.width * 0.15 -// anchors.verticalCenter: videoOutput.verticalCenter -// } + Rectangle { + color: "black" + opacity: 0.5 + width: videoOutput.contentRect.width * 0.15 + height: videoOutput.contentRect.height + x: videoOutput.width/2 + videoOutput.contentRect.width/2 - videoOutput.contentRect.width * 0.15 + anchors.verticalCenter: videoOutput.verticalCenter + } -// Rectangle { -// color: "black" -// opacity: 0.5 -// width: videoOutput.contentRect.width * 0.7 -// height: videoOutput.contentRect.height * 0.15 -// x: (videoOutput.width - videoOutput.contentRect.width)/2 + videoOutput.contentRect.width * 0.15 -// y: (videoOutput.height - videoOutput.contentRect.height)/2 -// } + Rectangle { + color: "black" + opacity: 0.5 + width: videoOutput.contentRect.width * 0.7 + height: videoOutput.contentRect.height * 0.15 + x: (videoOutput.width - videoOutput.contentRect.width)/2 + videoOutput.contentRect.width * 0.15 + y: (videoOutput.height - videoOutput.contentRect.height)/2 + } -// Rectangle { -// color: "black" -// opacity: 0.5 -// width: videoOutput.contentRect.width * 0.7 -// height: videoOutput.contentRect.height * 0.15 -// x: (videoOutput.width - videoOutput.contentRect.width)/2 + videoOutput.contentRect.width * 0.15 -// y: videoOutput.height/2 + videoOutput.contentRect.height/2 - videoOutput.contentRect.height * 0.15 -// } + Rectangle { + color: "black" + opacity: 0.5 + width: videoOutput.contentRect.width * 0.7 + height: videoOutput.contentRect.height * 0.15 + x: (videoOutput.width - videoOutput.contentRect.width)/2 + videoOutput.contentRect.width * 0.15 + y: videoOutput.height/2 + videoOutput.contentRect.height/2 - videoOutput.contentRect.height * 0.15 + } -// LabelType { -// width: parent.width -// text: qsTr("Decoded QR chunks " + QrDecoderLogic.receivedChunksCount + "/" + QrDecoderLogic.totalChunksCount) -// horizontalAlignment: Text.AlignLeft -// visible: QrDecoderLogic.totalChunksCount > 0 -// anchors.horizontalCenter: videoOutput.horizontalCenter -// y: videoOutput.height/2 + videoOutput.contentRect.height/2 -// } -// } + LabelType { + width: parent.width + text: qsTr("Decoded QR chunks " + QrDecoderLogic.receivedChunksCount + "/" + QrDecoderLogic.totalChunksCount) + horizontalAlignment: Text.AlignLeft + visible: QrDecoderLogic.totalChunksCount > 0 + anchors.horizontalCenter: videoOutput.horizontalCenter + y: videoOutput.height/2 + videoOutput.contentRect.height/2 + } + } -// QZXingFilter -// { -// id: zxingFilter -// orientation: videoOutput.orientation -// captureRect: { -// // setup bindings -// videoOutput.contentRect; -// videoOutput.sourceRect; -// return videoOutput.mapRectToSource(videoOutput.mapNormalizedRectToItem(Qt.rect( -// 0.15, 0.15, 0.7, 0.7 //0, 0, 1.0, 1.0 -// ))); -// } + QZXingFilter + { + id: zxingFilter + orientation: videoOutput.orientation + captureRect: { + // setup bindings + videoOutput.contentRect; + videoOutput.sourceRect; + return videoOutput.mapRectToSource(videoOutput.mapNormalizedRectToItem(Qt.rect( + 0.15, 0.15, 0.7, 0.7 //0, 0, 1.0, 1.0 + ))); + } -// decoder { -// enabledDecoders: QZXing.DecoderFormat_QR_CODE + decoder { + enabledDecoders: QZXing.DecoderFormat_QR_CODE -// onTagFound: { -// QrDecoderLogic.onDetectedQrCode(tag) -// } + onTagFound: { + QrDecoderLogic.onDetectedQrCode(tag) + } -// tryHarder: true -// } + tryHarder: true + } -// property int framesDecoded: 0 -// property real timePerFrameDecode: 0 + property int framesDecoded: 0 + property real timePerFrameDecode: 0 -// onDecodingFinished: -// { -// timePerFrameDecode = (decodeTime + framesDecoded * timePerFrameDecode) / (framesDecoded + 1); -// framesDecoded++; -// if(succeeded) -// console.log("frame finished: " + succeeded, decodeTime, timePerFrameDecode, framesDecoded); -// } -// } + onDecodingFinished: + { + timePerFrameDecode = (decodeTime + framesDecoded * timePerFrameDecode) / (framesDecoded + 1); + framesDecoded++; + if(succeeded) + console.log("frame finished: " + succeeded, decodeTime, timePerFrameDecode, framesDecoded); + } + } } diff --git a/client/ui/qml/Pages/PageQrDecoderIos.qml b/client/ui/qml/Pages/PageQrDecoderIos.qml new file mode 100644 index 00000000..7dd077dd --- /dev/null +++ b/client/ui/qml/Pages/PageQrDecoderIos.qml @@ -0,0 +1,76 @@ +import QtQuick 2.12 +import QtQuick.Controls 2.12 +import PageEnum 1.0 +import QRCodeReader 1.0 + +import "./" +import "../Controls" +import "../Config" + +PageBase { + id: root + page: PageEnum.QrDecoderIos + logic: QrDecoderLogic + + onDeactivated: { + console.debug("Stopping QR decoder") + loader.sourceComponent = undefined + } + + BackButton { + } + Caption { + id: caption + text: qsTr("Import configuration") + } + + Connections { + target: Qt.platform.os == "ios" ? QrDecoderLogic : nil + function onStartDecode() { + console.debug("Starting QR decoder") + loader.sourceComponent = component + } + function onStopDecode() { + console.debug("Stopping QR decoder") + loader.sourceComponent = undefined + } + } + + Loader { + id: loader + + anchors.top: caption.bottom + anchors.bottom: parent.bottom + anchors.left: parent.left + anchors.right: parent.right + } + + Component { + id: component + + Item { + anchors.fill: parent + + QRCodeReader { + id: qrCodeReader + + onCodeReaded: { + QrDecoderLogic.onDetectedQrCode(code) + } + + Component.onCompleted: { + qrCodeReader.setCameraSize(Qt.rect(loader.x, + loader.y, + loader.width, + loader.height)) + qrCodeReader.startReading() + } + Component.onDestruction: qrCodeReader.stopReading() + } + + } + + } + + +} diff --git a/client/ui/qml/Pages/PageStart.qml b/client/ui/qml/Pages/PageStart.qml index 26fc5e5f..3ff11a86 100644 --- a/client/ui/qml/Pages/PageStart.qml +++ b/client/ui/qml/Pages/PageStart.qml @@ -135,7 +135,11 @@ PageBase { text: qsTr("Scan QR code") visible: StartPageLogic.pushButtonConnectVisible onClicked: { - UiLogic.goToPage(PageEnum.QrDecoder) + if (Qt.platform.os == "ios") { + UiLogic.goToPage(PageEnum.QrDecoderIos) + } else { + UiLogic.goToPage(PageEnum.QrDecoder) + } } enabled: StartPageLogic.pushButtonConnectEnabled }