Warning, /utilities/qrca/src/contents/ui/QrCodeScannerPage.qml is written in an unsupported language. File is not indexed.

0001 /*
0002  *  SPDX-FileCopyrightText: 2020 Nicolas Fella <nicolas.fella@gmx.de>
0003  *  SPDX-FileCopyrightText: 2016-2019 Kaidan developers and contributors (see the LICENSE file of Kaidan for a full list of copyright authors)
0004  *
0005  *  SPDX-License-Identifier: GPL-3.0-or-later
0006  */
0007 
0008 import QtCore
0009 import QtQuick 2.0
0010 import QtQuick.Controls 2.3 as Controls
0011 import QtMultimedia
0012 import org.kde.kirigami as Kirigami
0013 import QtQuick.Layouts 1.3
0014 import org.kde.prison.scanner 1.0 as Prison
0015 
0016 import org.kde.qrca 1.0
0017 
0018 Kirigami.Page {
0019     leftPadding: 0
0020     rightPadding: 0
0021     topPadding: 0
0022     bottomPadding: 0
0023 
0024     title: qsTr("Scan QR code")
0025     actions: [
0026         Kirigami.Action {
0027             icon.name: checked ? "flashlight-off" : "flashlight-on"
0028             text: i18n("Light")
0029             checkable: true
0030             checked: camera.torchMode == Camera.TorchOn
0031             visible: camera.isTorchModeSupported
0032             onTriggered: camera.torchMode = (camera.torchMode == Camera.TorchOn ? Camera.TorchOff : Camera.TorchOn)
0033         },
0034         Kirigami.Action {
0035             text: i18n("Select Camera")
0036             visible: devices.videoInputs.length > 1
0037             icon.name: "camera-video-symbolic"
0038             onTriggered: cameraSelectorSheet.open()
0039         }
0040     ]
0041 
0042     CameraPermission {
0043         id: permission
0044         onStatusChanged: {
0045             if (status == Qt.PermissionStatus.Granted) {
0046                 camera.start();
0047             }
0048         }
0049     }
0050 
0051     MediaDevices {
0052         id: devices
0053     }
0054 
0055     function asLink(text) {
0056         return "<a href='" + text + "'>" + text + "</a>"
0057     }
0058 
0059     Kirigami.OverlaySheet {
0060         id: resultSheet
0061 
0062         property var tag
0063 
0064         header: Kirigami.Heading {
0065             text: {
0066                 switch (resultSheet.tag.contentType) {
0067                     case QrCodeContent.Text:
0068                         return i18n("Text found")
0069                     case QrCodeContent.Url:
0070                         return i18n("URL found")
0071                     case QrCodeContent.VCard:
0072                         return i18n("Contact found")
0073                     case QrCodeContent.OtpToken:
0074                         return i18n("OTP URI found")
0075                     case QrCodeContent.Binary:
0076                         return i18n("Binary data found")
0077                     case QrCodeContent.HealthCertificate:
0078                         return i18n("Health certificate found")
0079                     case QrCodeContent.TransportTicket:
0080                         return i18n("Transport ticket found")
0081                     case QrCodeContent.ISBN:
0082                         return i18n("ISBN found")
0083                     case QrCodeContent.EAN:
0084                         return i18n("International Article Number found")
0085                     case QrCodeContent.WifiSetting:
0086                         return i18n("Wi-Fi settings found")
0087                 }
0088             }
0089         }
0090 
0091         Item {
0092             implicitWidth: Kirigami.Units.gridUnit * 20
0093             height: childrenRect.height
0094 
0095             Controls.Label {
0096                 text: {
0097                     switch(resultSheet.tag.contentType) {
0098                         case QrCodeContent.VCard:
0099                             return Qrca.getVCardName(resultSheet.tag.text);
0100                         case QrCodeContent.WifiSetting:
0101                             return Qrca.wifiName(resultSheet.tag.text);
0102                         default:
0103                             return resultSheet.tag.isPlainText ? resultSheet.tag.text : i18n("<binary data>");
0104                     }
0105                 }
0106                 anchors.left: parent.left
0107                 anchors.right: parent.right
0108                 wrapMode: Text.Wrap
0109             }
0110         }
0111 
0112         footer: RowLayout {
0113             Controls.Button {
0114                 text: {
0115                     switch (resultSheet.tag.contentType) {
0116                     case QrCodeContent.Url:
0117                         return i18n("Open")
0118                     case QrCodeContent.VCard:
0119                         return i18n("Save contact")
0120                     case QrCodeContent.OtpToken:
0121                         return i18n("Open OTP client")
0122                     case QrCodeContent.EAN:
0123                         return i18n("Open Food Facts")
0124                     case QrCodeContent.ISBN:
0125                         return i18n("Wikipedia Book Sources")
0126                     case QrCodeContent.TransportTicket:
0127                         return i18n("Open KDE Itinerary")
0128                     case QrCodeContent.HealthCertificate:
0129                         return i18n("Open in Vakzination")
0130                     case QrCodeContent.WifiSetting:
0131                         return i18n("Connect")
0132                     }
0133                 }
0134                 onClicked: {
0135                     switch (resultSheet.tag.contentType) {
0136                     case QrCodeContent.Url:
0137                        Qt.openUrlExternally(resultSheet.tag.text)
0138                        break
0139                     case QrCodeContent.VCard:
0140                          Qrca.saveVCard(resultSheet.tag.text)
0141                         break
0142                     case QrCodeContent.OtpToken:
0143                         Qt.openUrlExternally(resultSheet.tag.text)
0144                         break
0145                     case QrCodeContent.EAN:
0146                         Qt.openUrlExternally("https://world.openfoodfacts.org/product/" + resultSheet.tag.text)
0147                         break;
0148                     case QrCodeContent.ISBN:
0149                         Qt.openUrlExternally("https://en.wikipedia.org/wiki/Special:BookSources?isbn=" + resultSheet.tag.text)
0150                         break;
0151                     case QrCodeContent.TransportTicket:
0152                         Qrca.openInApplication(resultSheet.tag, "org.kde.itinerary");
0153                         break;
0154                     case QrCodeContent.HealthCertificate:
0155                         Qrca.openInApplication(resultSheet.tag, "org.kde.vakzination");
0156                     case QrCodeContent.WifiSetting:
0157                         Qrca.connectToWifi(resultSheet.tag.text);
0158                     }
0159                     resultSheet.close()
0160                 }
0161                 visible: {
0162                     switch (resultSheet.tag.contentType) {
0163                     case QrCodeContent.Binary:
0164                     case QrCodeContent.Text:
0165                         return false;
0166                     case QrCodeContent.TransportTicket:
0167                         return Qrca.hasApplication("org.kde.itinerary");
0168                     case QrCodeContent.HealthCertificate:
0169                         return Qrca.hasApplication("org.kde.vakzination");
0170                     case QrCodeContent.WifiSetting:
0171                         return Qrca.canConnectToWifi();
0172                     }
0173                     return true;
0174                 }
0175                 icon.name: {
0176                     switch (resultSheet.tag.contentType) {
0177                     case QrCodeContent.VCard:
0178                         return "document-save";
0179                     case QrCodeContent.OtpToken:
0180                         return "document-encrypt";
0181                     case QrCodeContent.TransportTicket:
0182                         return Qrca.applicationIconName("org.kde.itinerary");
0183                     case QrCodeContent.HealthCertificate:
0184                         return Qrca.applicationIconName("org.kde.vakzination");
0185                     case QrCodeContent.WifiSetting:
0186                         return "network-wireless";
0187                     }
0188                     return "internet-services"
0189                 }
0190 
0191                 Layout.fillWidth: true
0192             }
0193             Controls.Button {
0194                 text: i18n("Copy to clipboard")
0195                 icon.name: "edit-copy-symbolic"
0196                 onClicked: {
0197                     Qrca.copyToClipboard(resultSheet.tag)
0198                     resultSheet.close()
0199                 }
0200                 Layout.fillWidth: true
0201             }
0202         }
0203     }
0204 
0205     Kirigami.OverlaySheet {
0206         id: cameraSelectorSheet
0207 
0208         header: Kirigami.Heading {
0209             text: i18n("Select Camera")
0210         }
0211 
0212         ListView {
0213             model: devices.videoInputs
0214             implicitWidth: Kirigami.Units.gridUnit * 20
0215 
0216             delegate: Controls.ItemDelegate {
0217                 text: modelData.description
0218                 width: ListView.view.width
0219                 onClicked: {
0220                     camera.cameraDevice = modelData;
0221                     camera.start();
0222                     cameraSelectorSheet.close();
0223                 }
0224             }
0225         }
0226     }
0227 
0228     VideoOutput {
0229         id: viewfinder
0230         anchors.fill: parent
0231         fillMode: VideoOutput.PreserveAspectCrop
0232     }
0233 
0234     Prison.VideoScanner {
0235         id: scannerFilter
0236 
0237         onResultContentChanged: result => {
0238             if (!result.hasContent) {
0239                 return
0240             }
0241 
0242             resultSheet.tag = Qrca.resultContent(result)
0243             if (!resultSheet.sheetOpen) {
0244                 resultSheet.open()
0245             }
0246         }
0247         videoSink: viewfinder.videoSink
0248     }
0249 
0250     CaptureSession {
0251         id: captureSession
0252         camera: Camera {
0253             id: camera
0254             active: true
0255         }
0256         videoOutput: viewfinder
0257     }
0258 
0259     Kirigami.PlaceholderMessage {
0260         text: camera.errorString
0261         visible: camera.error != Camera.NoError
0262         anchors.fill: parent
0263     }
0264 
0265     Component.onCompleted: {
0266         if (permission.status == Qt.PermissionStatus.Undetermined)
0267             permission.request()
0268     }
0269 }