@sapui5/sap.ndc 1.96.24 → 1.96.25
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/sap/ndc/.library +1 -1
- package/src/sap/ndc/BarcodeScanner.js +251 -193
- package/src/sap/ndc/BarcodeScannerUIContainer.js +5 -2
- package/src/sap/ndc/css/sapNdcBarcodeScanner.css +0 -1
- package/src/sap/ndc/library.js +1 -1
- package/src/sap/ndc/messagebundle_en.properties +12 -0
- package/src/sap/ndc/messagebundle_sh.properties +1 -1
- package/src/sap/ndc/messagebundle_sr.properties +1 -1
package/package.json
CHANGED
package/src/sap/ndc/.library
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
<vendor>SAP SE</vendor>
|
|
6
6
|
<copyright>SAPUI5
|
|
7
7
|
* (c) Copyright 2009-2022 SAP SE. All rights reserved.</copyright>
|
|
8
|
-
<version>1.96.
|
|
8
|
+
<version>1.96.25</version>
|
|
9
9
|
|
|
10
10
|
<documentation>SAPUI5 library with controls with native device capabilities.</documentation>
|
|
11
11
|
|
|
@@ -82,9 +82,10 @@ sap.ui.define([
|
|
|
82
82
|
/* =========================================================== */
|
|
83
83
|
oStream,
|
|
84
84
|
oScanDialog,
|
|
85
|
+
oBarcodeScannerUIContainer,
|
|
86
|
+
oVideoTrack,
|
|
85
87
|
oBarcodeVideoDOM,
|
|
86
88
|
oBarcodeCanvasDOM,
|
|
87
|
-
oContext,
|
|
88
89
|
oBarcodeOverlayDOM,
|
|
89
90
|
oBarcodeHighlightDOM,
|
|
90
91
|
|
|
@@ -107,14 +108,11 @@ sap.ui.define([
|
|
|
107
108
|
},
|
|
108
109
|
deviceId: undefined,
|
|
109
110
|
preferFrontCamera: false,
|
|
110
|
-
zoom: null,
|
|
111
111
|
enableGS1Header: false
|
|
112
112
|
},
|
|
113
113
|
scanDialog: {
|
|
114
114
|
title: "", //oDialogTitle
|
|
115
115
|
onLiveUpdate: null, //Live update function
|
|
116
|
-
imgTruncX: 0,
|
|
117
|
-
imgTruncY: 0,
|
|
118
116
|
barcodeOverlaySetup: false,
|
|
119
117
|
isNoScanner: false,
|
|
120
118
|
scanningStartTime: 0,
|
|
@@ -376,7 +374,7 @@ sap.ui.define([
|
|
|
376
374
|
* @private
|
|
377
375
|
*/
|
|
378
376
|
function loadZXingCPPAPI() {
|
|
379
|
-
Log.
|
|
377
|
+
Log.debug("BarcodeScanner.loadZXingCPPAPI: load ZXingCPP API");
|
|
380
378
|
updateScannerAPI("ZXingCPP", oScannerAPIStatus.Loading);
|
|
381
379
|
sap.ui.require([
|
|
382
380
|
"sap/ndc/thirdparty/zxingcpp/zxing_reader"
|
|
@@ -515,7 +513,7 @@ sap.ui.define([
|
|
|
515
513
|
.catch(
|
|
516
514
|
function(oErr) {
|
|
517
515
|
oModel.setProperty("/devices/needCheck", false);
|
|
518
|
-
Log.error("BarcodeScanner.getDeviceCameras: Can not get device cameras.\
|
|
516
|
+
Log.error("BarcodeScanner.getDeviceCameras: Can not get device cameras.\nError Message: " + oErr);
|
|
519
517
|
});
|
|
520
518
|
}
|
|
521
519
|
|
|
@@ -534,11 +532,13 @@ sap.ui.define([
|
|
|
534
532
|
Log.debug("BarcodeScanner.findMainCamera: can not find the main camera.");
|
|
535
533
|
fnCallback();
|
|
536
534
|
} else {
|
|
537
|
-
var oCamera = aCamerasClone.
|
|
535
|
+
var oCamera = aCamerasClone[aCamerasClone.length - 1];
|
|
538
536
|
var oConstraints = deepClone(oModel.getProperty("/config/defaultConstraints"));
|
|
539
537
|
oConstraints.video.deviceId = {
|
|
540
538
|
exact: oCamera.deviceId
|
|
541
539
|
};
|
|
540
|
+
var oVideoResolution = calculateVideoResolution();
|
|
541
|
+
oConstraints.video = Object.assign(oConstraints.video, oVideoResolution);
|
|
542
542
|
window.navigator.mediaDevices
|
|
543
543
|
.getUserMedia(oConstraints)
|
|
544
544
|
.then(
|
|
@@ -553,7 +553,7 @@ sap.ui.define([
|
|
|
553
553
|
Log.debug("BarcodeScanner.findMainCamera: the main camera is " + oCamera.deviceId);
|
|
554
554
|
oStream = stream;
|
|
555
555
|
if (oStream) {
|
|
556
|
-
|
|
556
|
+
playbackVideoAndDecode();
|
|
557
557
|
} else {
|
|
558
558
|
oScanDialog.getModel().setProperty("/isNoScanner", true);
|
|
559
559
|
openBarcodeInputDialog();
|
|
@@ -561,11 +561,19 @@ sap.ui.define([
|
|
|
561
561
|
}, function() {
|
|
562
562
|
videoTrack.stop();
|
|
563
563
|
Log.debug("BarcodeScanner.findMainCamera: " + oCamera.deviceId + " is not the main camera, check the next camera");
|
|
564
|
+
aCamerasClone.pop();
|
|
564
565
|
fnCheckStream();
|
|
565
566
|
});
|
|
566
567
|
}
|
|
567
568
|
).catch(
|
|
568
|
-
function() {
|
|
569
|
+
function (error) {
|
|
570
|
+
Log.debug("BarcodeScanner.findMainCamera: getUserMedia() failed.\nError Message: " + error);
|
|
571
|
+
if (oModel.getProperty("/config/defaultConstraints/video/zoom") !== undefined) {
|
|
572
|
+
Log.debug("BarcodeScanner.findMainCamera: getUserMedia() failed maybe caused by unsupported constraint 'zoom', delete it and try again.");
|
|
573
|
+
delete oModel.getProperty("/config/defaultConstraints/video").zoom;
|
|
574
|
+
} else {
|
|
575
|
+
aCamerasClone.pop();
|
|
576
|
+
}
|
|
569
577
|
fnCheckStream();
|
|
570
578
|
}
|
|
571
579
|
);
|
|
@@ -613,7 +621,7 @@ sap.ui.define([
|
|
|
613
621
|
reject();
|
|
614
622
|
}
|
|
615
623
|
}).catch(function(oError) {
|
|
616
|
-
Log.debug("BarcodeScanner.checkFlashLight: Camera not started or not available
|
|
624
|
+
Log.debug("BarcodeScanner.checkFlashLight: Camera not started or not available.\nError Message: " + oError);
|
|
617
625
|
reject();
|
|
618
626
|
});
|
|
619
627
|
});
|
|
@@ -804,21 +812,29 @@ sap.ui.define([
|
|
|
804
812
|
);
|
|
805
813
|
|
|
806
814
|
oScanDialog.setBusy(false);
|
|
807
|
-
oScanDialog.open();
|
|
808
815
|
}
|
|
809
816
|
|
|
810
817
|
/**
|
|
811
|
-
*
|
|
818
|
+
* Open correct camera
|
|
812
819
|
* @private
|
|
813
820
|
*/
|
|
814
|
-
function
|
|
821
|
+
function openCorrectCamera() {
|
|
815
822
|
if (!oModel.getProperty("/config/preferFrontCamera")) {
|
|
816
823
|
delete oModel.getProperty("/config/defaultConstraints/video").facingMode;
|
|
817
824
|
var oDevices = oModel.getProperty("/devices");
|
|
818
|
-
|
|
825
|
+
// when:
|
|
826
|
+
// a. no camera seleted
|
|
827
|
+
// b. main camera not found (no camera label contains '0, facing back')
|
|
828
|
+
// c. not iphone devices
|
|
829
|
+
// d. not Mac, or not ipad devices with Safari browser
|
|
830
|
+
// e. needCheck flag !== false
|
|
831
|
+
// f. camera list length > 1
|
|
832
|
+
// need to find main camera
|
|
833
|
+
if (!oModel.getProperty("/config/deviceId") && !oDevices.mainCamera && !Device.os.ios && !Device.os.macintosh && oDevices.needCheck && oDevices.all.length > 1) {
|
|
834
|
+
// if back camera list length > 1, find main camera in back camera list, or find it in all camera list
|
|
819
835
|
var oCameras = oDevices.back.length > 1 ? oDevices.back : oDevices.all;
|
|
820
836
|
var sCategory = oDevices.back.length > 1 ? "back" : "all";
|
|
821
|
-
Log.debug("BarcodeScanner.
|
|
837
|
+
Log.debug("BarcodeScanner.openCorrectCamera: start to find the main camera in " + sCategory + " camera list.");
|
|
822
838
|
findMainCamera(oCameras, openCamera);
|
|
823
839
|
return;
|
|
824
840
|
}
|
|
@@ -826,7 +842,8 @@ sap.ui.define([
|
|
|
826
842
|
openCamera();
|
|
827
843
|
}
|
|
828
844
|
|
|
829
|
-
function openCamera() {
|
|
845
|
+
function openCamera(bAttachOrientationChangeListener) {
|
|
846
|
+
Log.debug("BarcodeScanner.openCamera: start to open camera");
|
|
830
847
|
if (oModel.getProperty("/config/deviceId")) {
|
|
831
848
|
// if config/deviceId is set, use it as camera deviceId directly
|
|
832
849
|
delete oModel.getProperty("/config/defaultConstraints/video").facingMode;
|
|
@@ -846,13 +863,16 @@ sap.ui.define([
|
|
|
846
863
|
oModel.setProperty("/config/defaultConstraints/video/facingMode", "environment");
|
|
847
864
|
}
|
|
848
865
|
}
|
|
866
|
+
var oConstraints = deepClone(oModel.getProperty("/config/defaultConstraints"));
|
|
867
|
+
var oVideoResolution = calculateVideoResolution();
|
|
868
|
+
oConstraints.video = Object.assign(oConstraints.video, oVideoResolution);
|
|
849
869
|
window.navigator.mediaDevices
|
|
850
|
-
.getUserMedia(
|
|
870
|
+
.getUserMedia(oConstraints)
|
|
851
871
|
.then(
|
|
852
872
|
function(stream) {
|
|
853
873
|
oStream = stream;
|
|
854
874
|
if (oStream) {
|
|
855
|
-
|
|
875
|
+
playbackVideoAndDecode(bAttachOrientationChangeListener);
|
|
856
876
|
} else {
|
|
857
877
|
oModel.setProperty("/scanDialog/isNoScanner", true);
|
|
858
878
|
openBarcodeInputDialog();
|
|
@@ -860,14 +880,21 @@ sap.ui.define([
|
|
|
860
880
|
}
|
|
861
881
|
)
|
|
862
882
|
.catch(
|
|
863
|
-
function() {
|
|
864
|
-
|
|
865
|
-
|
|
883
|
+
function (error) {
|
|
884
|
+
Log.debug("BarcodeScanner.openCamera: getUserMedia() failed.\nError Message: " + error);
|
|
885
|
+
if (oModel.getProperty("/config/defaultConstraints/video/zoom") !== undefined) {
|
|
886
|
+
Log.debug("BarcodeScanner.openCamera: getUserMedia() failed maybe caused by unsupported constraint 'zoom', delete it and try again.");
|
|
887
|
+
delete oModel.getProperty("/config/defaultConstraints/video").zoom;
|
|
888
|
+
openCamera();
|
|
889
|
+
} else {
|
|
890
|
+
oModel.setProperty("/scanDialog/isNoScanner", true);
|
|
891
|
+
openBarcodeInputDialog();
|
|
892
|
+
}
|
|
866
893
|
}
|
|
867
894
|
);
|
|
868
895
|
}
|
|
869
896
|
|
|
870
|
-
function
|
|
897
|
+
function openScanDialog() {
|
|
871
898
|
oModel.checkUpdate(true);
|
|
872
899
|
var oDialogModel;
|
|
873
900
|
|
|
@@ -910,8 +937,25 @@ sap.ui.define([
|
|
|
910
937
|
oScanDialog.setModel(oResourceModel, "i18n");
|
|
911
938
|
}
|
|
912
939
|
|
|
940
|
+
oScanDialog.addStyleClass('sapUiNoContentPadding');
|
|
941
|
+
oScanDialog.setBusy(true);
|
|
942
|
+
|
|
913
943
|
if (isScannerAPIAvailable("ZXingCPP") && isUserMediaAccessSupported()) {
|
|
914
|
-
|
|
944
|
+
oScanDialog.attachAfterOpen(function() {
|
|
945
|
+
openCorrectCamera();
|
|
946
|
+
});
|
|
947
|
+
oScanDialog.destroyContent();
|
|
948
|
+
oBarcodeHighlightDOM = undefined;
|
|
949
|
+
oBarcodeOverlayDOM = undefined;
|
|
950
|
+
oBarcodeVideoDOM = undefined;
|
|
951
|
+
oBarcodeCanvasDOM = undefined;
|
|
952
|
+
|
|
953
|
+
oBarcodeScannerUIContainer = new BarcodeScannerUIContainer();
|
|
954
|
+
oScanDialog.addContent(oBarcodeScannerUIContainer);
|
|
955
|
+
oScanDialog.setContentWidth('100%');
|
|
956
|
+
oScanDialog.setContentHeight('100%');
|
|
957
|
+
|
|
958
|
+
oModel.setProperty("/scanDialog/barcodeOverlaySetup", false);
|
|
915
959
|
} else {
|
|
916
960
|
if (oModel.getProperty("/available")) {
|
|
917
961
|
oModel.setProperty("/scanDialog/isNoScanner", false);
|
|
@@ -920,8 +964,7 @@ sap.ui.define([
|
|
|
920
964
|
}
|
|
921
965
|
openBarcodeInputDialog();
|
|
922
966
|
}
|
|
923
|
-
|
|
924
|
-
return oScanDialog;
|
|
967
|
+
oScanDialog.open();
|
|
925
968
|
}
|
|
926
969
|
|
|
927
970
|
/**
|
|
@@ -941,39 +984,39 @@ sap.ui.define([
|
|
|
941
984
|
*/
|
|
942
985
|
function scanWithCordova() {
|
|
943
986
|
var options;
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
}
|
|
957
|
-
} else {
|
|
958
|
-
getScanDialog();
|
|
987
|
+
if (oModel.getProperty("/config/preferFrontCamera")) {
|
|
988
|
+
options = {
|
|
989
|
+
preferFrontCamera: true
|
|
990
|
+
};
|
|
991
|
+
}
|
|
992
|
+
oModel.getProperty("/apis/Cordova/scannerAPI").scan(
|
|
993
|
+
function (oResult) {
|
|
994
|
+
if (oResult.cancelled === "false" || !oResult.cancelled) {
|
|
995
|
+
oResult.cancelled = false;
|
|
996
|
+
var onFnSuccess = oModel.getProperty("/callBackHandler/onFnSuccess");
|
|
997
|
+
if (typeof onFnSuccess === "function") {
|
|
998
|
+
onFnSuccess(oResult);
|
|
959
999
|
}
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
1000
|
+
} else {
|
|
1001
|
+
openScanDialog();
|
|
1002
|
+
}
|
|
1003
|
+
oModel.setProperty("/bReady", true);
|
|
1004
|
+
},
|
|
1005
|
+
function (oEvent) {
|
|
1006
|
+
Log.error("BarcodeScanner.scanWithCordova: Barcode scanning failed.");
|
|
1007
|
+
oModel.setProperty("/bReady", true);
|
|
1008
|
+
var onFnFail = oModel.getProperty("/callBackHandler/onFnFail");
|
|
1009
|
+
if (typeof onFnFail === "function") {
|
|
1010
|
+
if (typeof oEvent === "string") {
|
|
1011
|
+
var str = oEvent;
|
|
1012
|
+
oEvent = {"text": str};
|
|
1013
|
+
Log.debug("BarcodeScanner.scanWithCordova: Change the type of oEvent from string to object");
|
|
973
1014
|
}
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
1015
|
+
onFnFail(oEvent);
|
|
1016
|
+
}
|
|
1017
|
+
},
|
|
1018
|
+
options
|
|
1019
|
+
);
|
|
977
1020
|
}
|
|
978
1021
|
|
|
979
1022
|
/**
|
|
@@ -984,7 +1027,7 @@ sap.ui.define([
|
|
|
984
1027
|
if (checkScannerAPIStatus("ZXingCPP", oScannerAPIStatus.Initial)) {
|
|
985
1028
|
Log.debug("BarcodeScanner.scanWithZXingCPP: ZXingCPP instances is not loaded, start to load them.");
|
|
986
1029
|
loadZXingCPPInstance(function() {
|
|
987
|
-
|
|
1030
|
+
openScanDialog();
|
|
988
1031
|
}, function() {
|
|
989
1032
|
if (isScannerAPIAvailable("ZebraEnterpriseBrowser")) {
|
|
990
1033
|
setCurrentScannerAPI("ZebraEnterpriseBrowser");
|
|
@@ -993,71 +1036,47 @@ sap.ui.define([
|
|
|
993
1036
|
setCurrentScannerAPI("unknown");
|
|
994
1037
|
Log.warning("BarcodeScanner.scanWithZXingCPP: Zebra is unavailable too, set the current scanner API to unknown.");
|
|
995
1038
|
}
|
|
996
|
-
|
|
1039
|
+
openScanDialog();
|
|
997
1040
|
});
|
|
998
1041
|
} else {
|
|
999
|
-
|
|
1042
|
+
Log.debug("BarcodeScanner.scanWithZXingCPP: get scan dialog.");
|
|
1043
|
+
openScanDialog();
|
|
1000
1044
|
}
|
|
1001
1045
|
}
|
|
1002
1046
|
|
|
1003
1047
|
/**
|
|
1004
|
-
*
|
|
1048
|
+
* Playback the video, then decode via ZXingCPP
|
|
1005
1049
|
* @private
|
|
1006
1050
|
*/
|
|
1007
|
-
function
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
oScanDialog.
|
|
1011
|
-
|
|
1012
|
-
// some error happened during dialog creation and may not be directly related to video element
|
|
1013
|
-
oScanDialog.getEndButton().setEnabled(true);
|
|
1014
|
-
oScanDialog.setBusy(false);
|
|
1015
|
-
|
|
1016
|
-
if (!oBarcodeHighlightDOM) {
|
|
1017
|
-
oBarcodeHighlightDOM = oBarcodeScannerUIContainer.getDomRef('highlight');
|
|
1018
|
-
}
|
|
1019
|
-
if (!oBarcodeVideoDOM) {
|
|
1020
|
-
oBarcodeVideoDOM = oBarcodeScannerUIContainer ? document.createElement("video") : undefined;
|
|
1021
|
-
if (oBarcodeVideoDOM) {
|
|
1022
|
-
oBarcodeVideoDOM.setAttribute("id", "video");
|
|
1023
|
-
oBarcodeVideoDOM.setAttribute("autoplay", "autoplay");
|
|
1024
|
-
oBarcodeVideoDOM.setAttribute("webkit-playsinline", "webkit-playsinline");
|
|
1025
|
-
oBarcodeVideoDOM.setAttribute("playsinline", "playsinline");
|
|
1026
|
-
}
|
|
1027
|
-
}
|
|
1028
|
-
if (!oBarcodeCanvasDOM) {
|
|
1029
|
-
oBarcodeCanvasDOM = oBarcodeScannerUIContainer ? oBarcodeScannerUIContainer.getDomRef('canvas') : undefined;
|
|
1030
|
-
oContext = oBarcodeCanvasDOM.getContext("2d", { willReadFrequently: true });
|
|
1031
|
-
}
|
|
1032
|
-
try {
|
|
1033
|
-
oBarcodeVideoDOM.srcObject = oStream;
|
|
1034
|
-
oBarcodeVideoDOM.play().then(function() {
|
|
1035
|
-
oBarcodeCanvasDOM.width = oBarcodeVideoDOM.videoWidth;
|
|
1036
|
-
oBarcodeCanvasDOM.height = oBarcodeVideoDOM.videoHeight;
|
|
1037
|
-
decodeWithZXingCPP();
|
|
1038
|
-
});
|
|
1039
|
-
} catch (err) {
|
|
1040
|
-
Log.debug("BarcodeScanner.openBarcodeScannerDialogContains is failed. error: " + err);
|
|
1041
|
-
}
|
|
1042
|
-
});
|
|
1043
|
-
oScanDialog.destroyContent();
|
|
1044
|
-
oBarcodeHighlightDOM = undefined;
|
|
1045
|
-
oBarcodeOverlayDOM = undefined;
|
|
1046
|
-
oBarcodeVideoDOM = undefined;
|
|
1047
|
-
|
|
1048
|
-
oBarcodeCanvasDOM = undefined;
|
|
1049
|
-
oContext = undefined;
|
|
1050
|
-
|
|
1051
|
-
oBarcodeScannerUIContainer = new BarcodeScannerUIContainer();
|
|
1052
|
-
oScanDialog.addContent(oBarcodeScannerUIContainer);
|
|
1053
|
-
|
|
1054
|
-
oScanDialog.setContentWidth('100%');
|
|
1055
|
-
oScanDialog.setContentHeight('100%');
|
|
1056
|
-
oScanDialog.addStyleClass('sapUiNoContentPadding');
|
|
1057
|
-
oScanDialog.setBusy(true);
|
|
1058
|
-
oScanDialog.open();
|
|
1051
|
+
function playbackVideoAndDecode(bAttachOrientationChangeListener) {
|
|
1052
|
+
// Dev note: if video element dom reference is unavailable at this point (console exception)
|
|
1053
|
+
// some error happened during dialog creation and may not be directly related to video element
|
|
1054
|
+
oScanDialog.getEndButton().setEnabled(true);
|
|
1055
|
+
oScanDialog.setBusy(false);
|
|
1059
1056
|
|
|
1060
|
-
|
|
1057
|
+
if (!oBarcodeHighlightDOM) {
|
|
1058
|
+
oBarcodeHighlightDOM = oBarcodeScannerUIContainer.getDomRef('highlight');
|
|
1059
|
+
}
|
|
1060
|
+
if (!oBarcodeVideoDOM) {
|
|
1061
|
+
oBarcodeVideoDOM = oBarcodeScannerUIContainer ? oBarcodeScannerUIContainer.getDomRef('video') : undefined;
|
|
1062
|
+
}
|
|
1063
|
+
try {
|
|
1064
|
+
oBarcodeVideoDOM.srcObject = oStream;
|
|
1065
|
+
oBarcodeVideoDOM.play().then(function() {
|
|
1066
|
+
// show scan overlay box
|
|
1067
|
+
scanFrame();
|
|
1068
|
+
if (Device.support.orientation && bAttachOrientationChangeListener !== false) {
|
|
1069
|
+
Device.orientation.attachHandler(orientationChangeListener);
|
|
1070
|
+
}
|
|
1071
|
+
Log.debug("BarcodeScanner.playbackVideoAndDecode: video screen size " + oBarcodeVideoDOM.videoHeight + "X" + oBarcodeVideoDOM.videoWidth);
|
|
1072
|
+
oVideoTrack = typeof oStream.stop === "function" ? oStream : oStream.getTracks()[0];
|
|
1073
|
+
var settings = oVideoTrack.getSettings();
|
|
1074
|
+
Log.debug("BarcodeScanner.playbackVideoAndDecode: video screen frameRate is " + settings.frameRate + ", zoom is " + settings.zoom);
|
|
1075
|
+
decodeWithZXingCPP();
|
|
1076
|
+
});
|
|
1077
|
+
} catch (err) {
|
|
1078
|
+
Log.debug("BarcodeScanner.playbackVideoAndDecode is failed. error: " + err);
|
|
1079
|
+
}
|
|
1061
1080
|
}
|
|
1062
1081
|
|
|
1063
1082
|
/**
|
|
@@ -1065,31 +1084,43 @@ sap.ui.define([
|
|
|
1065
1084
|
* @private
|
|
1066
1085
|
*/
|
|
1067
1086
|
function decodeWithZXingCPP() {
|
|
1068
|
-
Log.
|
|
1087
|
+
Log.debug("BarcodeScanner.decodeWithZXingCPP: start to decode");
|
|
1069
1088
|
if (!oBarcodeVideoDOM || !oBarcodeVideoDOM.srcObject) {
|
|
1089
|
+
Log.debug("BarcodeScanner.decodeWithZXingCPP: video dom doesn't exist, stop decoding");
|
|
1070
1090
|
return;
|
|
1071
1091
|
}
|
|
1072
|
-
scanFrame();
|
|
1073
1092
|
|
|
1074
1093
|
try {
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1094
|
+
// use canvas to get video frame as image data
|
|
1095
|
+
if (!oBarcodeCanvasDOM) {
|
|
1096
|
+
oBarcodeCanvasDOM = oBarcodeScannerUIContainer ? document.createElement("canvas") : undefined;
|
|
1097
|
+
}
|
|
1098
|
+
if (!oBarcodeCanvasDOM) {
|
|
1099
|
+
Log.debug("BarcodeScanner.decodeWithZXingCPP: canvas dom doesn't exist, stop decoding");
|
|
1100
|
+
return;
|
|
1101
|
+
}
|
|
1102
|
+
var oContext = oBarcodeCanvasDOM.getContext("2d", { willReadFrequently: true });
|
|
1103
|
+
var imgWidth = oBarcodeVideoDOM.videoWidth;
|
|
1104
|
+
var imgHeight = oBarcodeVideoDOM.videoHeight;
|
|
1105
|
+
oBarcodeCanvasDOM.width = imgWidth;
|
|
1106
|
+
oBarcodeCanvasDOM.height = imgHeight;
|
|
1107
|
+
oContext.drawImage(oBarcodeVideoDOM, 0, 0, imgWidth, imgHeight);
|
|
1108
|
+
var imageData = oContext.getImageData(0, 0, imgWidth, imgHeight);
|
|
1080
1109
|
var oData = imageData.data;
|
|
1110
|
+
// decode image data via ZXingCPP
|
|
1081
1111
|
var buffer;
|
|
1082
1112
|
var oZXingCPPScannerAPI = oModel.getProperty("/apis/ZXingCPP/scannerAPI");
|
|
1083
1113
|
try {
|
|
1084
1114
|
buffer = oZXingCPPScannerAPI._malloc(oData.length);
|
|
1085
1115
|
oZXingCPPScannerAPI.HEAPU8.set(oData, buffer);
|
|
1086
1116
|
} catch (err) {
|
|
1087
|
-
Log.
|
|
1117
|
+
Log.error("BarcodeScanner.decodeWithZXingCPP: zxing.HEAPU8 error: " + err);
|
|
1088
1118
|
}
|
|
1089
1119
|
var results = oZXingCPPScannerAPI.readBarcodesFromPixmap(buffer, imgWidth, imgHeight, true, "", 1);
|
|
1090
1120
|
oZXingCPPScannerAPI._free(buffer);
|
|
1091
1121
|
var iSize = results.size();
|
|
1092
1122
|
if (iSize > 0 && results.get(0).format) {
|
|
1123
|
+
Log.debug("BarcodeScanner.decodeWithZXingCPP: decode successful");
|
|
1093
1124
|
var result = results.get(0);
|
|
1094
1125
|
highlightResult(result);
|
|
1095
1126
|
if (result.cancelled === "false" || !result.cancelled) {
|
|
@@ -1139,8 +1170,8 @@ sap.ui.define([
|
|
|
1139
1170
|
}
|
|
1140
1171
|
|
|
1141
1172
|
if (oBarcodeHighlightDOM) {
|
|
1142
|
-
scaleX =
|
|
1143
|
-
scaleY =
|
|
1173
|
+
scaleX = oBarcodeVideoDOM.clientWidth / oBarcodeVideoDOM.videoWidth;
|
|
1174
|
+
scaleY = oBarcodeVideoDOM.clientHeight / oBarcodeVideoDOM.videoHeight;
|
|
1144
1175
|
if (result.position) {
|
|
1145
1176
|
result.resultPoints = [
|
|
1146
1177
|
result.position.topLeft,
|
|
@@ -1173,8 +1204,8 @@ sap.ui.define([
|
|
|
1173
1204
|
oBarcodeHighlightDOM.hidden = false;
|
|
1174
1205
|
oBarcodeHighlightDOM.style.top = top * scaleY + 'px';
|
|
1175
1206
|
oBarcodeHighlightDOM.style.left = left * scaleX + 'px';
|
|
1176
|
-
oBarcodeHighlightDOM.style.width = (right - left > 0 ? (right - left
|
|
1177
|
-
oBarcodeHighlightDOM.style.height = (bottom - top > 0 ? (bottom - top
|
|
1207
|
+
oBarcodeHighlightDOM.style.width = (right - left > 0 ? (right - left) * scaleX : 5) + 'px';
|
|
1208
|
+
oBarcodeHighlightDOM.style.height = (bottom - top > 0 ? (bottom - top) * scaleY : 5) + 'px';
|
|
1178
1209
|
}
|
|
1179
1210
|
}
|
|
1180
1211
|
|
|
@@ -1190,22 +1221,81 @@ sap.ui.define([
|
|
|
1190
1221
|
oBarcodeHighlightDOM.style.height = '0';
|
|
1191
1222
|
}
|
|
1192
1223
|
|
|
1224
|
+
/**
|
|
1225
|
+
* If orientaition changed, reopen camera to maxsize video screen
|
|
1226
|
+
* @private
|
|
1227
|
+
*/
|
|
1228
|
+
function orientationChangeListener(oNewOrientation) {
|
|
1229
|
+
oScanDialog.setBusy(true);
|
|
1230
|
+
var sOrientation = oNewOrientation.landscape ? "landscape" : "portrait";
|
|
1231
|
+
Log.debug("BarcodeScanner.orientationChangeListener: device orientation changed to " + sOrientation + ", call openCamera again to resize");
|
|
1232
|
+
if (oBarcodeOverlayDOM) {
|
|
1233
|
+
// hide overlay during orientation change
|
|
1234
|
+
oBarcodeOverlayDOM.hidden = true;
|
|
1235
|
+
}
|
|
1236
|
+
// close the camera since video screen is not in full size after orientation changed
|
|
1237
|
+
closeScannerContain(false);
|
|
1238
|
+
if (Device.os.ios || Device.os.macintosh) {
|
|
1239
|
+
// on iOS devices (iphone and ipad), the dialog may be in small size and moved to top left after orientation changed, so max size and reposition it in center
|
|
1240
|
+
oScanDialog._positionDialog();
|
|
1241
|
+
}
|
|
1242
|
+
// need to wait for the orientation change finished, then reopen camera so that the video screen is in full size
|
|
1243
|
+
setTimeout(function() {
|
|
1244
|
+
openCamera(false);
|
|
1245
|
+
}, 500);
|
|
1246
|
+
}
|
|
1247
|
+
|
|
1248
|
+
/**
|
|
1249
|
+
* Calculate video height and width
|
|
1250
|
+
* @returns {object} Video height and width object
|
|
1251
|
+
* @private
|
|
1252
|
+
*/
|
|
1253
|
+
function calculateVideoResolution() {
|
|
1254
|
+
var iAvailHeight = oBarcodeScannerUIContainer.getDomRef().clientHeight,
|
|
1255
|
+
iAvailWidth = oBarcodeScannerUIContainer.getDomRef().clientWidth,
|
|
1256
|
+
iWidth = 1920,
|
|
1257
|
+
iHeight = 1440;
|
|
1258
|
+
/*
|
|
1259
|
+
if (iAvailHeight > iAvailWidth) {
|
|
1260
|
+
iHeight = 1920;
|
|
1261
|
+
iWidth = Math.trunc(1920 * iAvailWidth / iAvailHeight);
|
|
1262
|
+
} else {
|
|
1263
|
+
iWidth = 1920;
|
|
1264
|
+
iHeight = Math.trunc(1920 * iAvailHeight / iAvailWidth);
|
|
1265
|
+
}*/
|
|
1266
|
+
// in portrait mode, width means height ???, so above codes will meet Not Full Screen issue when in this mode
|
|
1267
|
+
// have to change to below, need to check document
|
|
1268
|
+
if (iAvailHeight > iAvailWidth) {
|
|
1269
|
+
iHeight = Math.trunc(1920 * iAvailWidth / iAvailHeight);
|
|
1270
|
+
} else {
|
|
1271
|
+
iHeight = Math.trunc(1920 * iAvailHeight / iAvailWidth);
|
|
1272
|
+
}
|
|
1273
|
+
return {
|
|
1274
|
+
width: { ideal: iWidth },
|
|
1275
|
+
height: { ideal: iHeight }
|
|
1276
|
+
};
|
|
1277
|
+
}
|
|
1278
|
+
|
|
1193
1279
|
function scanFrame() {
|
|
1194
|
-
|
|
1280
|
+
Log.debug("BarcodeScanner.scanFrame: start to set up overlay dom");
|
|
1281
|
+
if (!oScanDialog || !oBarcodeVideoDOM || !oBarcodeVideoDOM.videoHeight || !oBarcodeVideoDOM.videoWidth) {
|
|
1282
|
+
Log.debug("BarcodeScanner.scanFrame: scan dialog or video screen is closed, stop set up");
|
|
1195
1283
|
return;
|
|
1196
1284
|
}
|
|
1197
1285
|
var iInactiveZonePercent = 0.15;
|
|
1198
|
-
var oBarcodeScannerUIContainer = oScanDialog.getContent()[0];
|
|
1199
1286
|
|
|
1200
1287
|
if (!oBarcodeOverlayDOM && oBarcodeScannerUIContainer) {
|
|
1201
1288
|
oBarcodeOverlayDOM = oBarcodeScannerUIContainer.getDomRef('overlay');
|
|
1202
1289
|
}
|
|
1203
1290
|
|
|
1204
|
-
updateZoom();
|
|
1205
|
-
|
|
1206
1291
|
if (oBarcodeOverlayDOM) {
|
|
1207
|
-
|
|
1208
|
-
|
|
1292
|
+
// show overlay since it may be hidden during orientation change
|
|
1293
|
+
oBarcodeOverlayDOM.hidden = false;
|
|
1294
|
+
var iBarcodeVideoDOMWidth = oBarcodeVideoDOM.clientWidth,
|
|
1295
|
+
iBarcodeVideoDOMHeight = oBarcodeVideoDOM.clientHeight;
|
|
1296
|
+
var oBarcodeOverlayWidthTemp = iBarcodeVideoDOMWidth * (1 - 2 * iInactiveZonePercent);
|
|
1297
|
+
var oBarcodeOverlayHeightTemp = iBarcodeVideoDOMHeight * (1 - 2 * iInactiveZonePercent);
|
|
1298
|
+
|
|
1209
1299
|
|
|
1210
1300
|
if (oBarcodeOverlayWidthTemp <= oBarcodeOverlayHeightTemp) {
|
|
1211
1301
|
oBarcodeOverlayHeightTemp = oBarcodeOverlayWidthTemp * (1 - 2 * iInactiveZonePercent);
|
|
@@ -1219,73 +1309,23 @@ sap.ui.define([
|
|
|
1219
1309
|
|
|
1220
1310
|
oBarcodeOverlayDOM.style.width = oBarcodeOverlayWidthTemp + 'px';
|
|
1221
1311
|
oBarcodeOverlayDOM.style.height = oBarcodeOverlayHeightTemp + 'px';
|
|
1222
|
-
oBarcodeOverlayDOM.style.borderWidth = (
|
|
1223
|
-
}
|
|
1224
|
-
}
|
|
1225
|
-
}
|
|
1226
|
-
|
|
1227
|
-
function updateZoom() {
|
|
1228
|
-
if (oModel.getProperty("/config/zoom") !== "skipUpdateZoom" && oBarcodeVideoDOM) {
|
|
1229
|
-
var videoTrack = oBarcodeVideoDOM.srcObject.getVideoTracks();
|
|
1230
|
-
var oSupport = window.navigator.mediaDevices.getSupportedConstraints();
|
|
1231
|
-
var capabilities = videoTrack[0].getCapabilities();
|
|
1232
|
-
// Verify the permission about updating zoom
|
|
1233
|
-
if (oSupport.zoom && capabilities && capabilities.zoom) {
|
|
1234
|
-
Log.debug("BarcodeScanner.updateZoom: Support zoom to update");
|
|
1235
|
-
if (oModel.getProperty("/config/zoom") === 'undefined' || oModel.getProperty("/config/zoom") === null) {
|
|
1236
|
-
// reset zoom
|
|
1237
|
-
oModel.setProperty("/config/zoom", capabilities.zoom.min);
|
|
1238
|
-
}
|
|
1239
|
-
} else {
|
|
1240
|
-
Log.debug("BarcodeScanner.updateZoom: Don't support zoom or getCapabilities() failed.");
|
|
1241
|
-
oModel.setProperty("/config/zoom", "skipUpdateZoom");
|
|
1242
|
-
return;
|
|
1243
|
-
}
|
|
1244
|
-
// Update zoom
|
|
1245
|
-
try {
|
|
1246
|
-
var fRoom = oModel.getProperty("/config/zoom");
|
|
1247
|
-
videoTrack[0].applyConstraints(
|
|
1248
|
-
{
|
|
1249
|
-
advanced: [{
|
|
1250
|
-
zoom: fRoom
|
|
1251
|
-
}]
|
|
1252
|
-
}
|
|
1253
|
-
).then(
|
|
1254
|
-
function() {
|
|
1255
|
-
oModel.setProperty("/config/zoom", "skipUpdateZoom");
|
|
1256
|
-
Log.debug("BarcodeScanner.updateZoom: Zoom is updated to " + fRoom);
|
|
1257
|
-
}
|
|
1258
|
-
).catch(
|
|
1259
|
-
function(error) {
|
|
1260
|
-
if (error && error.message && error.message.match(/out of range|Failed to read the 'zoom' property/i)) {
|
|
1261
|
-
oModel.setProperty("/config/zoom", "skipUpdateZoom");
|
|
1262
|
-
MessageToast.show(
|
|
1263
|
-
oResourceModel.getResourceBundle().getText('BARCODE_DIALOG_CAMERA_UPDATE_PARAMETER_ERROR_MSG', 'zoom'),
|
|
1264
|
-
{
|
|
1265
|
-
duration: 1000
|
|
1266
|
-
}
|
|
1267
|
-
);
|
|
1268
|
-
} else {
|
|
1269
|
-
Log.error("BarcodeScanner.updateZoom: Update zoom to " + fRoom + " failed. Error Message:" + error);
|
|
1270
|
-
}
|
|
1271
|
-
}
|
|
1272
|
-
);
|
|
1273
|
-
} catch (err) {
|
|
1274
|
-
Log.error("BarcodeScanner.updateZoom: applyConstraints() failed. Error Message:" + err);
|
|
1275
|
-
oModel.setProperty("/config/zoom", "skipUpdateZoom");
|
|
1312
|
+
oBarcodeOverlayDOM.style.borderWidth = (iBarcodeVideoDOMHeight - oBarcodeOverlayHeightTemp) / 2 + 'px ' + (iBarcodeVideoDOMWidth - oBarcodeOverlayWidthTemp) / 2 + 'px';
|
|
1276
1313
|
}
|
|
1277
|
-
var settings = videoTrack[0].getSettings();
|
|
1278
|
-
Log.debug("BarcodeScanner.updateZoom: frameRate is " + settings.frameRate + ". zoom is " + settings.zoom);
|
|
1279
1314
|
}
|
|
1280
1315
|
}
|
|
1281
1316
|
|
|
1282
|
-
function closeScannerContain() {
|
|
1317
|
+
function closeScannerContain(bDetachOrientationChangeListener) {
|
|
1283
1318
|
// oStream and oBarcodeVideoDOM.srcObject point to the same video stream, set them to undefined when closing scan screen
|
|
1319
|
+
if (oVideoTrack) {
|
|
1320
|
+
oVideoTrack.stop();
|
|
1321
|
+
oVideoTrack = undefined;
|
|
1322
|
+
}
|
|
1284
1323
|
if (oStream) {
|
|
1285
|
-
var videoTrack = typeof oStream.stop === "function" ? oStream : oStream.getTracks()[0];
|
|
1286
|
-
videoTrack.stop();
|
|
1287
1324
|
oStream = undefined;
|
|
1288
1325
|
}
|
|
1326
|
+
if (Device.support.orientation && bDetachOrientationChangeListener !== false) {
|
|
1327
|
+
Device.orientation.detachHandler(orientationChangeListener);
|
|
1328
|
+
}
|
|
1289
1329
|
if (oBarcodeVideoDOM && oBarcodeVideoDOM.srcObject) {
|
|
1290
1330
|
oBarcodeVideoDOM.srcObject = undefined;
|
|
1291
1331
|
}
|
|
@@ -1420,6 +1460,7 @@ sap.ui.define([
|
|
|
1420
1460
|
Log.error("BarcodeScanner.scan: Barcode scanning is already in progress.");
|
|
1421
1461
|
return;
|
|
1422
1462
|
}
|
|
1463
|
+
Log.debug("BarcodeScanner.scan: start to scan barcode.");
|
|
1423
1464
|
|
|
1424
1465
|
oModel.setProperty("/bReady", false);
|
|
1425
1466
|
if (typeof fnSuccess === 'function') {
|
|
@@ -1459,15 +1500,32 @@ sap.ui.define([
|
|
|
1459
1500
|
}
|
|
1460
1501
|
);
|
|
1461
1502
|
}
|
|
1462
|
-
|
|
1503
|
+
// Reset zoom
|
|
1504
|
+
if (oModel.getProperty("/config/defaultConstraints/video/zoom") !== undefined) {
|
|
1505
|
+
delete oModel.getProperty("/config/defaultConstraints/video").zoom;
|
|
1506
|
+
}
|
|
1507
|
+
// apply value of zoom parameter
|
|
1508
|
+
if (typeof zoom === "number" && zoom > 0) {
|
|
1509
|
+
oModel.setProperty("/config/defaultConstraints/video/zoom", zoom);
|
|
1510
|
+
} else if (typeof zoom !== 'undefined') {
|
|
1511
|
+
MessageToast.show(
|
|
1512
|
+
oResourceModel.getResourceBundle().getText('BARCODE_DIALOG_CAMERA_UPDATE_PARAMETER_ERROR_MSG', 'zoom'),
|
|
1513
|
+
{
|
|
1514
|
+
duration: 1000
|
|
1515
|
+
}
|
|
1516
|
+
);
|
|
1517
|
+
}
|
|
1463
1518
|
oModel.setProperty("/scanDialog/keepCameraScan", keepCameraScan);
|
|
1464
1519
|
oModel.checkUpdate(true);
|
|
1465
1520
|
|
|
1466
1521
|
if (checkZebraEBScanAvailable()) {
|
|
1522
|
+
Log.debug("BarcodeScanner.scan: Zebra EB is available, use it to scan barcode.");
|
|
1467
1523
|
scanWithZebra();
|
|
1468
1524
|
} else if (isScannerAPIAvailable("Cordova")) {
|
|
1525
|
+
Log.debug("BarcodeScanner.scan: Cordova is available, use it to scan barcode.");
|
|
1469
1526
|
scanWithCordova();
|
|
1470
1527
|
} else {
|
|
1528
|
+
Log.debug("BarcodeScanner.scan: both of Zebra EB and Cordova are NOT available, use ZXingCPP to scan barcode.");
|
|
1471
1529
|
scanWithZXingCPP();
|
|
1472
1530
|
}
|
|
1473
1531
|
};
|
|
@@ -1569,7 +1627,7 @@ sap.ui.define([
|
|
|
1569
1627
|
Log.error("BarcodeScanner.scan: The scanner API '" + scannerAPI + "' is unavailable, will use current scanner API '" + oModel.getProperty("/apis/" + getCurrentScannerAPI() + "/description") + "' to scan the barcode.");
|
|
1570
1628
|
return false;
|
|
1571
1629
|
} else {
|
|
1572
|
-
Log.
|
|
1630
|
+
Log.debug("BarcodeScanner.scan: Switch to scanner API '" + scannerAPI + "' to scan the barcode.");
|
|
1573
1631
|
setCurrentScannerAPI(scannerAPI);
|
|
1574
1632
|
return true;
|
|
1575
1633
|
}
|
|
@@ -1577,7 +1635,7 @@ sap.ui.define([
|
|
|
1577
1635
|
Log.error("BarcodeScanner.scan: The scanner API '" + scannerAPI + "' is unavailable, will use current scanner API '" + oModel.getProperty("/apis/" + getCurrentScannerAPI() + "/description") + "' to scan the barcode.");
|
|
1578
1636
|
return false;
|
|
1579
1637
|
} else {
|
|
1580
|
-
Log.
|
|
1638
|
+
Log.debug("BarcodeScanner.scan: Switch to scanner API '" + scannerAPI + "' to scan the barcode.");
|
|
1581
1639
|
setCurrentScannerAPI(scannerAPI);
|
|
1582
1640
|
return true;
|
|
1583
1641
|
}
|
|
@@ -24,10 +24,13 @@ sap.ui.define([
|
|
|
24
24
|
oRm.openStart("div", oControl);
|
|
25
25
|
oRm.class("sapNdcRTCDialogVideo");
|
|
26
26
|
oRm.openEnd();
|
|
27
|
-
oRm.openStart("
|
|
27
|
+
oRm.openStart("video", oControl.getId() + "-video");
|
|
28
|
+
oRm.attr("autoplay", "autoplay");
|
|
29
|
+
oRm.attr("webkit-playsinline", "webkit-playsinline");
|
|
30
|
+
oRm.attr("playsinline", "playsinline");
|
|
28
31
|
oRm.class("sapNdcRTCDialogVideoContainer");
|
|
29
32
|
oRm.openEnd();
|
|
30
|
-
oRm.close("
|
|
33
|
+
oRm.close("video");
|
|
31
34
|
oRm.close("div");
|
|
32
35
|
|
|
33
36
|
// Overlay that is used to mark scan area
|
package/src/sap/ndc/library.js
CHANGED
|
@@ -1,20 +1,32 @@
|
|
|
1
|
+
#This is the resource bundle for the sap.ndc library
|
|
2
|
+
#
|
|
1
3
|
|
|
4
|
+
#XTIT: title of the manual barcode input
|
|
2
5
|
BARCODE_DIALOG_TITLE=Enter Barcode
|
|
3
6
|
|
|
7
|
+
#XBUT: OK button in the manual barcode input dialog
|
|
4
8
|
BARCODE_DIALOG_OK=OK
|
|
5
9
|
|
|
10
|
+
#XBUT: Cancel button in the manual barcode input dialog
|
|
6
11
|
BARCODE_DIALOG_CANCEL=Cancel
|
|
7
12
|
|
|
13
|
+
#XFLD: Placeholder of the barcode input field
|
|
8
14
|
BARCODE_DIALOG_PLACEHOLDER=Enter barcode
|
|
9
15
|
|
|
16
|
+
#YMSG: Message in the manual barcode input dialog
|
|
10
17
|
BARCODE_DIALOG_MSG=Scanner is not available
|
|
11
18
|
|
|
19
|
+
#XMSG: error message for updating parameter of Camera
|
|
12
20
|
BARCODE_DIALOG_CAMERA_UPDATE_PARAMETER_ERROR_MSG=The {0} parameter is out of range.
|
|
13
21
|
|
|
22
|
+
#XTIT: title of the scan barcode dialog
|
|
14
23
|
BARCODE_DIALOG_SCANNING_TITLE=Scan Barcode
|
|
15
24
|
|
|
25
|
+
#XTOL: Barcode Scanner Button tooltip
|
|
16
26
|
BARCODE_SCANNER_BUTTON_TOOLTIP=Bar Code Scanner Button
|
|
17
27
|
|
|
28
|
+
#XTIT: title of the scan bar busy dialog
|
|
18
29
|
BARCODE_DIALOG_BUSY_TITLE=Loading Libraries
|
|
19
30
|
|
|
31
|
+
#XTXT: text of loading zxing-cpp in the scan bar busy dialog
|
|
20
32
|
BARCODE_DIALOG_BUSY_TEXT_ZXINGCPP=Loading ZXing-cpp library...
|
|
@@ -13,7 +13,7 @@ BARCODE_DIALOG_CAMERA_UPDATE_PARAMETER_ERROR_MSG=Parametar {0} je van raspona.
|
|
|
13
13
|
|
|
14
14
|
BARCODE_DIALOG_SCANNING_TITLE=Skeniraj bar kod
|
|
15
15
|
|
|
16
|
-
BARCODE_SCANNER_BUTTON_TOOLTIP=
|
|
16
|
+
BARCODE_SCANNER_BUTTON_TOOLTIP=Dugme skenera bar koda
|
|
17
17
|
|
|
18
18
|
BARCODE_DIALOG_BUSY_TITLE=U\u010Ditavanje biblioteka
|
|
19
19
|
|
|
@@ -13,7 +13,7 @@ BARCODE_DIALOG_CAMERA_UPDATE_PARAMETER_ERROR_MSG=\u041F\u0430\u0440\u0430\u043C\
|
|
|
13
13
|
|
|
14
14
|
BARCODE_DIALOG_SCANNING_TITLE=\u0421\u043A\u0435\u043D\u0438\u0440\u0430\u0458 \u0431\u0430\u0440 \u043A\u043E\u0434
|
|
15
15
|
|
|
16
|
-
BARCODE_SCANNER_BUTTON_TOOLTIP
|
|
16
|
+
BARCODE_SCANNER_BUTTON_TOOLTIP=\u0414\u0443\u0433\u043C\u0435 \u0441\u043A\u0435\u043D\u0435\u0440\u0430 \u0431\u0430\u0440 \u043A\u043E\u0434\u0430
|
|
17
17
|
|
|
18
18
|
BARCODE_DIALOG_BUSY_TITLE=\u0423\u0447\u0438\u0442\u0430\u0432\u0430\u045A\u0435 \u0431\u0438\u0431\u043B\u0438\u043E\u0442\u0435\u043A\u0430
|
|
19
19
|
|