From edf1d742f3202603c8ee6f7c554092d7c8d495b6 Mon Sep 17 00:00:00 2001 From: DoinLakeFlyer Date: Sat, 2 May 2020 13:30:17 -0700 Subject: [PATCH] Add support for Json file string translations --- UnitTest.qrc | 24 +-- localization/README.md | 64 +++++- localization/qgc-lupdate-json.py | 132 +++++++++++++ localization/to-crowdin.sh | 5 +- src/Airmap/AirMap.SettingsGroup.json | 5 + .../APM/APMFollowComponent.FactMetaData.json | 5 + .../APM/APMPowerComponent.qml | 2 +- .../PX4/AirframeComponent.qml | 4 +- src/FactSystem/FactMetaData.cc | 45 ++--- src/FactSystem/FactMetaData.h | 11 +- ...oCommon.json => APM-MavCmdInfoCommon.json} | 6 +- ...Wing.json => APM-MavCmdInfoFixedWing.json} | 6 +- ...tor.json => APM-MavCmdInfoMultiRotor.json} | 6 +- .../APM/APM-MavCmdInfoRover.json | 8 + src/FirmwarePlugin/APM/APM-MavCmdInfoSub.json | 8 + .../APM/APM-MavCmdInfoVTOL.json | 8 + src/FirmwarePlugin/APM/APMFirmwarePlugin.cc | 12 +- src/FirmwarePlugin/APM/APMResources.qrc | 12 +- src/FirmwarePlugin/APM/MavCmdInfoRover.json | 8 - src/FirmwarePlugin/APM/MavCmdInfoSub.json | 8 - src/FirmwarePlugin/APM/MavCmdInfoVTOL.json | 8 - .../PX4/MavCmdInfoFixedWing.json | 8 - src/FirmwarePlugin/PX4/MavCmdInfoRover.json | 8 - src/FirmwarePlugin/PX4/MavCmdInfoSub.json | 8 - src/FirmwarePlugin/PX4/MavCmdInfoVTOL.json | 8 - ...oCommon.json => PX4-MavCmdInfoCommon.json} | 6 +- .../PX4/PX4-MavCmdInfoFixedWing.json | 8 + ...tor.json => PX4-MavCmdInfoMultiRotor.json} | 6 +- .../PX4/PX4-MavCmdInfoRover.json | 8 + src/FirmwarePlugin/PX4/PX4-MavCmdInfoSub.json | 8 + .../PX4/PX4-MavCmdInfoVTOL.json | 8 + src/FirmwarePlugin/PX4/PX4FirmwarePlugin.cc | 12 +- src/FirmwarePlugin/PX4/PX4Resources.qrc | 12 +- src/JsonHelper.cc | 185 +++++++++++++++--- src/JsonHelper.h | 49 +++-- .../BreachReturn.FactMetaData.json | 5 + .../CameraCalc.FactMetaData.json | 5 + .../CameraSection.FactMetaData.json | 5 + .../CameraSpec.FactMetaData.json | 5 + .../CorridorScan.SettingsGroup.json | 5 + .../FWLandingPattern.FactMetaData.json | 5 + src/MissionManager/MavCmdInfoCommon.json | 4 +- src/MissionManager/MavCmdInfoFixedWing.json | 6 +- src/MissionManager/MavCmdInfoMultiRotor.json | 6 +- src/MissionManager/MavCmdInfoRover.json | 6 +- src/MissionManager/MavCmdInfoSub.json | 6 +- src/MissionManager/MavCmdInfoVTOL.json | 6 +- src/MissionManager/MissionCommandList.cc | 28 +-- src/MissionManager/MissionCommandList.h | 7 +- src/MissionManager/MissionCommandTree.cc | 12 +- src/MissionManager/MissionCommandUIInfo.cc | 2 +- src/MissionManager/MissionController.cc | 2 +- .../MissionSettings.FactMetaData.json | 5 + src/MissionManager/PlanMasterController.cc | 2 +- src/MissionManager/QGCMapCircle.Facts.json | 5 + .../RallyPoint.FactMetaData.json | 5 + .../SpeedSection.FactMetaData.json | 5 + .../StructureScan.SettingsGroup.json | 5 + src/MissionManager/Survey.SettingsGroup.json | 5 + .../TransectStyle.SettingsGroup.json | 5 + .../UnitTest/MavCmdInfoMultiRotor.json | 8 - .../UnitTest/MavCmdInfoSub.json | 8 - .../UnitTest/MavCmdInfoVTOL.json | 8 - ...foCommon.json => UT-MavCmdInfoCommon.json} | 6 +- ...dWing.json => UT-MavCmdInfoFixedWing.json} | 6 +- .../UnitTest/UT-MavCmdInfoMultiRotor.json | 8 + ...InfoRover.json => UT-MavCmdInfoRover.json} | 4 +- .../UnitTest/UT-MavCmdInfoSub.json | 8 + .../UnitTest/UT-MavCmdInfoVTOL.json | 8 + .../VTOLLandingPattern.FactMetaData.json | 5 + src/PlanView/GeoFenceEditor.qml | 2 +- src/QGCApplication.cc | 1 - src/QGCApplication.h | 2 + src/QGCToolbox.cc | 4 + .../EditPositionDialog.FactMetaData.json | 5 + .../RCToParamDialog.FactMetaData.json | 5 + .../ADSBVehicleManager.SettingsGroup.json | 5 + .../APMMavlinkStreamRate.SettingsGroup.json | 3 + src/Settings/App.SettingsGroup.json | 5 + src/Settings/AutoConnect.SettingsGroup.json | 5 + src/Settings/BrandImage.SettingsGroup.json | 5 + .../FirmwareUpgrade.SettingsGroup.json | 5 + src/Settings/FlightMap.SettingsGroup.json | 5 + src/Settings/FlyView.SettingsGroup.json | 5 + src/Settings/OfflineMaps.SettingsGroup.json | 5 + src/Settings/PlanView.SettingsGroup.json | 5 + src/Settings/RTK.SettingsGroup.json | 5 + src/Settings/Units.SettingsGroup.json | 5 + src/Settings/Video.SettingsGroup.json | 5 + src/Vehicle/BatteryFact.json | 5 + src/Vehicle/ClockFact.json | 5 + src/Vehicle/DistanceSensorFact.json | 5 + src/Vehicle/EstimatorStatusFactGroup.json | 5 + src/Vehicle/GPSFact.json | 5 + src/Vehicle/GPSRTKFact.json | 5 + src/Vehicle/SetpointFact.json | 5 + src/Vehicle/SubmarineFact.json | 5 + src/Vehicle/TemperatureFact.json | 5 + src/Vehicle/TerrainFactGroup.json | 5 + src/Vehicle/VehicleFact.json | 5 + src/Vehicle/VibrationFact.json | 5 + src/Vehicle/WindFact.json | 6 +- src/comm/QGCSerialPortInfo.cc | 12 +- src/comm/USBBoardInfo.json | 6 +- 104 files changed, 823 insertions(+), 285 deletions(-) create mode 100755 localization/qgc-lupdate-json.py rename src/FirmwarePlugin/APM/{MavCmdInfoCommon.json => APM-MavCmdInfoCommon.json} (97%) rename src/FirmwarePlugin/APM/{MavCmdInfoFixedWing.json => APM-MavCmdInfoFixedWing.json} (92%) rename src/FirmwarePlugin/APM/{MavCmdInfoMultiRotor.json => APM-MavCmdInfoMultiRotor.json} (91%) create mode 100644 src/FirmwarePlugin/APM/APM-MavCmdInfoRover.json create mode 100644 src/FirmwarePlugin/APM/APM-MavCmdInfoSub.json create mode 100644 src/FirmwarePlugin/APM/APM-MavCmdInfoVTOL.json delete mode 100644 src/FirmwarePlugin/APM/MavCmdInfoRover.json delete mode 100644 src/FirmwarePlugin/APM/MavCmdInfoSub.json delete mode 100644 src/FirmwarePlugin/APM/MavCmdInfoVTOL.json delete mode 100644 src/FirmwarePlugin/PX4/MavCmdInfoFixedWing.json delete mode 100644 src/FirmwarePlugin/PX4/MavCmdInfoRover.json delete mode 100644 src/FirmwarePlugin/PX4/MavCmdInfoSub.json delete mode 100644 src/FirmwarePlugin/PX4/MavCmdInfoVTOL.json rename src/FirmwarePlugin/PX4/{MavCmdInfoCommon.json => PX4-MavCmdInfoCommon.json} (85%) create mode 100644 src/FirmwarePlugin/PX4/PX4-MavCmdInfoFixedWing.json rename src/FirmwarePlugin/PX4/{MavCmdInfoMultiRotor.json => PX4-MavCmdInfoMultiRotor.json} (90%) create mode 100644 src/FirmwarePlugin/PX4/PX4-MavCmdInfoRover.json create mode 100644 src/FirmwarePlugin/PX4/PX4-MavCmdInfoSub.json create mode 100644 src/FirmwarePlugin/PX4/PX4-MavCmdInfoVTOL.json delete mode 100644 src/MissionManager/UnitTest/MavCmdInfoMultiRotor.json delete mode 100644 src/MissionManager/UnitTest/MavCmdInfoSub.json delete mode 100644 src/MissionManager/UnitTest/MavCmdInfoVTOL.json rename src/MissionManager/UnitTest/{MavCmdInfoCommon.json => UT-MavCmdInfoCommon.json} (98%) rename src/MissionManager/UnitTest/{MavCmdInfoFixedWing.json => UT-MavCmdInfoFixedWing.json} (93%) create mode 100644 src/MissionManager/UnitTest/UT-MavCmdInfoMultiRotor.json rename src/MissionManager/UnitTest/{MavCmdInfoRover.json => UT-MavCmdInfoRover.json} (62%) create mode 100644 src/MissionManager/UnitTest/UT-MavCmdInfoSub.json create mode 100644 src/MissionManager/UnitTest/UT-MavCmdInfoVTOL.json diff --git a/UnitTest.qrc b/UnitTest.qrc index 2bfa5bbb8..4f29c94a6 100644 --- a/UnitTest.qrc +++ b/UnitTest.qrc @@ -1,18 +1,18 @@ - src/MissionManager/UnitTest/SectionTest.plan - src/MissionManager/UnitTest/MavCmdInfoCommon.json - src/MissionManager/UnitTest/MavCmdInfoFixedWing.json - src/MissionManager/UnitTest/MavCmdInfoMultiRotor.json - src/MissionManager/UnitTest/MavCmdInfoRover.json - src/MissionManager/UnitTest/MavCmdInfoSub.json - src/MissionManager/UnitTest/MavCmdInfoVTOL.json + src/MissionManager/UnitTest/SectionTest.plan + src/MissionManager/UnitTest/UT-MavCmdInfoCommon.json + src/MissionManager/UnitTest/UT-MavCmdInfoFixedWing.json + src/MissionManager/UnitTest/UT-MavCmdInfoMultiRotor.json + src/MissionManager/UnitTest/UT-MavCmdInfoRover.json + src/MissionManager/UnitTest/UT-MavCmdInfoSub.json + src/MissionManager/UnitTest/UT-MavCmdInfoVTOL.json src/MissionManager/UnitTest/MissionPlanner.waypoints src/MissionManager/UnitTest/OldFileFormat.mission - src/MissionManager/UnitTest/PolygonAreaTest.kml - src/MissionManager/UnitTest/PolygonGood.kml - src/MissionManager/UnitTest/PolygonMissingNode.kml - src/MissionManager/UnitTest/PolygonBadXml.kml - src/MissionManager/UnitTest/PolygonBadCoordinatesNode.kml + src/MissionManager/UnitTest/PolygonAreaTest.kml + src/MissionManager/UnitTest/PolygonGood.kml + src/MissionManager/UnitTest/PolygonMissingNode.kml + src/MissionManager/UnitTest/PolygonBadXml.kml + src/MissionManager/UnitTest/PolygonBadCoordinatesNode.kml diff --git a/localization/README.md b/localization/README.md index fd5ea12da..d7d5e2c68 100644 --- a/localization/README.md +++ b/localization/README.md @@ -1,5 +1,65 @@ -To generate (or update) a source translation file, use the `to-crowdin.sh` script in this directory. You will need to update the path to Qt within it. +# QGroundControl string translations + +QGC uses the standard Qt Linguist mechanisms for string translation. QGC uses crowd sourced string translation through a [Crowdin project](https://crowdin.com/project/qgroundcontrol for translation). + + +## C++ and Qml code strings +These are coded using the standard Qt tr() for C++ and qsTr() for Qml mechanisms. + +## Translating strings within Json files +QGC uses json files internally for metadata. These files need to be translated as well. There is a [python parser](https://github.com/mavlink/qgroundcontrol/blob/master/localization/qgc-lupdate-json.py) which is used to find all the json files in the source tree and pull all the strings out for translation. This parser outputs the localization file for json strings in Qt .ts file format. + +In order for the parser to know which strings must be translated additional keys must be available at the root object level. + +> Important: Json files which have the same name are not allowed. Since the name is used as the context for the translation lookup it must be unique. The parse will throw an error if it finds duplicate file names. + +> Important: The root file name for the json file must be the same as the root filename for the Qt resource alias. This due to the fact that the root filename is used as the translation context. The json parser reads files from the file system and sees file system names. Whereas the QGC C++ code reads json files from the QT resource system and see the file alias as the full path and root name. + +### Specifying known file type +The parser supports two known file types: "MAVCmdInfo" and "FactMetaData". If your json file is one of these types you should place a `fileType` key at the root with one of these values. This will cause the parser to use these defaults for instructions: + +#### MAVCmdInfo +``` + "translateKeys": "label,enumStrings,friendlyName,description", + "arrayIDKeys": "rawName,comment" +``` +#### FactMetaData +``` + "translateKeys": "shortDescription,longDescription,enumStrings" + "arrayIDKeys": "name" +``` + +### Manually specify parser instructions +For this case dont include the `fileType` key/value pair. And include the followings keys (as needed) in the root object: + +* `translateKeys` This key is a string which is a list of all the keys which should be translated. +* `arrayIDKeys` The json localization parser provides additional information to the translator about where this string came from in the json hierarchy. If there is an array in the json, just displaying an array index as to where this came from is not that helpful. In most cases there is a key within each array element for which the value is unique. If this is the case then specify this key name(s) as the value for `arrayIDKeys`. + +### Disambiguation +This is used when you have two strings in the same file which are equal, but there meaning ar different enough that when translated they may each have their own different translation. In order to specific that you include a special prefix marker in the string which includes comments to the translator to explain the specifics of the string. + +``` + "foo": "#loc.disambiguation#This is the foo version of baz#baz" + "bar": "#loc.disambiguation#This is the bar version of baz#baz" +``` + +In the example above "baz" is the string which is the same for two different keys. The prefix `#loc.disambiguation#` indicates a disambiguation is to follow which is the string between the next set of `#`s. + +## Uploading new strings to Crowdin +To generate (or update) a source translation file, use the [to-crowdin.sh](https://github.com/mavlink/qgroundcontrol/blob/master/localization/to-crowdin.sh) script in this directory. You will need to update the path to Qt within it. This will do the following steps: + +* Delete the current qgc.ts file +* Run the qt lupdate command to generate a new qgc.ts file +* Run the python json parser which will add the json strings to the qgc.ts file + +Once this is complete you can upload the new qgc.ts file to Crowdin. + +https://github.com/mavlink/qgroundcontrol/blob/master/localization/to-crowdin.sh + +## Download translations from Crowdin + +Once translations have been done/updated, within Crowdin "Build and Download". Extract the resulting qgroundcontro.zip here and run [from-crowdin.sh](https://github.com/mavlink/qgroundcontrol/blob/master/localization/from-crowdin.sh). This will parse all the source files and generate a language translation file called qgc.ts, which should be uploaded to crowdin. -Once translations have been done/updated, within Crowdin "Build and Download". Extract the resulting qgroundcontro.zip here and run `from-crowdin.py`. + diff --git a/localization/qgc-lupdate-json.py b/localization/qgc-lupdate-json.py new file mode 100755 index 000000000..abcc8de76 --- /dev/null +++ b/localization/qgc-lupdate-json.py @@ -0,0 +1,132 @@ +#!/usr/bin/env python +import os +import json +from xml.dom.minidom import parse +import xml.dom.minidom +import codecs +import sys + +qgcFileTypeKey = "fileType" +translateKeysKey = "translateKeys" +arrayIDKeysKey = "arrayIDKeys" +disambiguationPrefix = "#loc.disambiguation#" + +def parseJsonObjectForTranslateKeys(jsonObjectHierarchy, jsonObject, translateKeys, arrayIDKeys, locStringDict): + for translateKey in translateKeys: + if (translateKey in jsonObject): + locStr = jsonObject[translateKey] + currentHierarchy = jsonObjectHierarchy + "." + translateKey + if locStr in locStringDict: + # Duplicate of an existing string + locStringDict[locStr].append(currentHierarchy) + else: + # First time we are seeing this string + locStringDict[locStr] = [ currentHierarchy ] + for key in jsonObject: + currentHierarchy = jsonObjectHierarchy + "." + key + if (type(jsonObject[key]) == type({})): + parseJsonObjectForTranslateKeys(currentHierarchy, jsonObject[key], translateKeys,arrayIDKeys, locStringDict) + elif (type(jsonObject[key]) == type([])): + parseJsonArrayForTranslateKeys(currentHierarchy, jsonObject[key], translateKeys, arrayIDKeys, locStringDict) + +def parseJsonArrayForTranslateKeys(jsonObjectHierarchy, jsonArray, translateKeys, arrayIDKeys, locStringDict): + for index in range(0, len(jsonArray)): + jsonObject = jsonArray[index] + arrayIndexStr = str(index) + for arrayIDKey in arrayIDKeys: + if arrayIDKey in jsonObject.keys(): + arrayIndexStr = jsonObject[arrayIDKey] + break + currentHierarchy = jsonObjectHierarchy + "[" + arrayIndexStr + "]" + parseJsonObjectForTranslateKeys(currentHierarchy, jsonObject, translateKeys, arrayIDKeys, locStringDict) + +def addLocKeysBasedOnQGCFileType(jsonPath, jsonDict): + # Instead of having to add the same keys over and over again in a pile of files we add them here automatically based on file type + if qgcFileTypeKey in jsonDict: + qgcFileType = jsonDict[qgcFileTypeKey] + translateKeyValue = "" + arrayIDKeysKeyValue = "" + if qgcFileType == "MavCmdInfo": + translateKeyValue = "label,enumStrings,friendlyName,description,category" + arrayIDKeysKeyValue = "rawName,comment" + elif qgcFileType == "FactMetaData": + translateKeyValue = "shortDescription,longDescription,enumStrings" + arrayIDKeysKeyValue = "name" + if translateKeysKey not in jsonDict and translateKeyValue != "": + jsonDict[translateKeysKey] = translateKeyValue + if arrayIDKeysKey not in jsonDict and arrayIDKeysKeyValue != "": + jsonDict[arrayIDKeysKey] = arrayIDKeysKeyValue + +def parseJson(jsonPath, locStringDict): + jsonFile = open(jsonPath) + jsonDict = json.load(jsonFile) + if (type(jsonDict) != type({})): + return + addLocKeysBasedOnQGCFileType(jsonPath, jsonDict) + if (not translateKeysKey in jsonDict): + return + translateKeys = jsonDict[translateKeysKey].split(",") + arrayIDKeys = jsonDict.get(arrayIDKeysKey, "").split(",") + parseJsonObjectForTranslateKeys("", jsonDict, translateKeys, arrayIDKeys, locStringDict) + +def walkDirectoryTreeForJsonFiles(dir, multiFileLocArray): + for filename in os.listdir(dir): + path = os.path.join(dir, filename) + if (os.path.isfile(path) and filename.endswith(".json")): + #print "json",path + singleFileLocStringDict = {} + parseJson(path, singleFileLocStringDict) + if len(singleFileLocStringDict.keys()): + # Check for duplicate file names + for entry in multiFileLocArray: + if entry[0] == filename: + print "Error: Duplicate filenames: %s paths: %s %s" % (filename, path, entry[1]) + sys.exit(1) + multiFileLocArray.append([filename, path, singleFileLocStringDict]) + if (os.path.isdir(path)): + walkDirectoryTreeForJsonFiles(path, multiFileLocArray) + +def appendToQGCTSFile(multiFileLocArray): + originalTSFile = codecs.open('qgc.ts', 'r', "utf-8") + newTSFile = codecs.open('qgc.ts.new', 'w', "utf-8") + line = originalTSFile.readline() + while (line != "\n"): + newTSFile.write(line); + line = originalTSFile.readline() + originalTSFile.close() + for entry in multiFileLocArray: + newTSFile.write("\n") + newTSFile.write(" %s\n" % entry[0]) + singleFileLocStringDict = entry[2] + for locStr in singleFileLocStringDict.keys(): + disambiguation = "" + if locStr.startswith(disambiguationPrefix): + workStr = locStr[len(disambiguationPrefix):] + terminatorIndex = workStr.find("#") + if terminatorIndex == -1: + print "Bad disambiguation %1 '%2'" % (entry[0], locStr) + sys.exit(1) + disambiguation = workStr[:terminatorIndex] + locStr = workStr[terminatorIndex+1:] + newTSFile.write(" \n") + if len(disambiguation): + newTSFile.write(" %s\n" % disambiguation) + extraCommentStr = "" + for jsonHierachy in singleFileLocStringDict[locStr]: + extraCommentStr += "%s, " % jsonHierachy + newTSFile.write(" %s\n" % extraCommentStr) + newTSFile.write(" \n" % entry[1]) + newTSFile.write(unicode(" %s\n") % locStr) + newTSFile.write(" \n") + newTSFile.write(" \n") + newTSFile.write("\n") + newTSFile.write("\n") + newTSFile.close() + +def main(): + multiFileLocArray = [] + walkDirectoryTreeForJsonFiles("../src", multiFileLocArray) + appendToQGCTSFile(multiFileLocArray) + +if __name__ == '__main__': + main() diff --git a/localization/to-crowdin.sh b/localization/to-crowdin.sh index 4ca1455bd..78101bb72 100755 --- a/localization/to-crowdin.sh +++ b/localization/to-crowdin.sh @@ -1,5 +1,8 @@ #!/bin/bash # This is set to find lupdate in my particular installation. You will need to set the path # where you have Qt installed. -QT_PATH=~/Applications/Qt/5.12.3/clang_64/bin +QT_PATH=~//Qt/5.12.6/gcc_64/bin +rm qgc.ts $QT_PATH/lupdate ../src -ts qgc.ts +python qgc-lupdate-json.py +mv qgc.ts.new qgc.ts diff --git a/src/Airmap/AirMap.SettingsGroup.json b/src/Airmap/AirMap.SettingsGroup.json index 2f2181e0c..c38ba29a9 100644 --- a/src/Airmap/AirMap.SettingsGroup.json +++ b/src/Airmap/AirMap.SettingsGroup.json @@ -1,3 +1,7 @@ +{ + "version": 1, + "fileType": "FactMetaData", + "QGC.MetaData.Facts": [ { "name": "usePersonalApiKey", @@ -48,3 +52,4 @@ "defaultValue": false } ] +} diff --git a/src/AutoPilotPlugins/APM/APMFollowComponent.FactMetaData.json b/src/AutoPilotPlugins/APM/APMFollowComponent.FactMetaData.json index 7d0269718..606f4320d 100644 --- a/src/AutoPilotPlugins/APM/APMFollowComponent.FactMetaData.json +++ b/src/AutoPilotPlugins/APM/APMFollowComponent.FactMetaData.json @@ -1,3 +1,7 @@ +{ + "version": 1, + "fileType": "FactMetaData", + "QGC.MetaData.Facts": [ { "name": "angle", @@ -28,3 +32,4 @@ "defaultValue": 5 } ] +} diff --git a/src/AutoPilotPlugins/APM/APMPowerComponent.qml b/src/AutoPilotPlugins/APM/APMPowerComponent.qml index 340144aa2..376348e4c 100644 --- a/src/AutoPilotPlugins/APM/APMPowerComponent.qml +++ b/src/AutoPilotPlugins/APM/APMPowerComponent.qml @@ -266,7 +266,7 @@ SetupPage { QGCLabel { text: qsTr("- The arming tone will be played (if the vehicle has a buzzer attached)") } QGCLabel { text: qsTr("- If using a flight controller with a safety button press it until it displays solid red") } QGCLabel { text: qsTr("- You will hear a musical tone then two beeps") } - QGCLabel { text: qsTr("- A few seconds later you should hear a number of beeps (one for each battery cell you’re using)") } + QGCLabel { text: qsTr("- A few seconds later you should hear a number of beeps (one for each battery cell you're using)") } QGCLabel { text: qsTr("- And finally a single long beep indicating the end points have been set and the ESC is calibrated") } QGCLabel { text: qsTr("- Disconnect the battery and power up again normally") } } diff --git a/src/AutoPilotPlugins/PX4/AirframeComponent.qml b/src/AutoPilotPlugins/PX4/AirframeComponent.qml index 719f5e3bb..a99e1a34c 100644 --- a/src/AutoPilotPlugins/PX4/AirframeComponent.qml +++ b/src/AutoPilotPlugins/PX4/AirframeComponent.qml @@ -111,7 +111,7 @@ SetupPage { QGCLabel { anchors.fill: parent wrapMode: Text.WordWrap - text: qsTr("Clicking “Apply” will save the changes you have made to your airframe configuration.

\ + text: qsTr("Clicking 'Apply' will save the changes you have made to your airframe configuration.

\ All vehicle parameters other than Radio Calibration will be reset.

\ Your vehicle will also be restarted in order to complete the process.") } @@ -130,7 +130,7 @@ Your vehicle will also be restarted in order to complete the process.") text: (controller.currentVehicleName != "" ? qsTr("You've connected a %1.").arg(controller.currentVehicleName) : qsTr("Airframe is not set.")) + - qsTr("To change this configuration, select the desired airframe below then click “Apply and Restart”.") + qsTr("To change this configuration, select the desired airframe below then click 'Apply and Restart'.") font.family: ScreenTools.demiboldFontFamily wrapMode: Text.WordWrap } diff --git a/src/FactSystem/FactMetaData.cc b/src/FactSystem/FactMetaData.cc index b4b8ce4de..4897e47a8 100644 --- a/src/FactSystem/FactMetaData.cc +++ b/src/FactSystem/FactMetaData.cc @@ -35,6 +35,7 @@ const qreal FactMetaData::UnitConsts_s::inchesToCentimeters = 2.54; static const char* kDefaultCategory = QT_TRANSLATE_NOOP("FactMetaData", "Other"); static const char* kDefaultGroup = QT_TRANSLATE_NOOP("FactMetaData", "Misc"); +const char* FactMetaData::qgcFileType = "FactMetaData"; const char* FactMetaData::_jsonMetaDataDefinesName = "QGC.MetaData.Defines"; const char* FactMetaData::_jsonMetaDataFactsName = "QGC.MetaData.Facts"; @@ -1220,45 +1221,29 @@ QMap FactMetaData::createMapFromJsonFile(const QString& { QMap metaDataMap; - QFile jsonFile(jsonFilename); - if (!jsonFile.open(QIODevice::ReadOnly | QIODevice::Text)) { - qWarning() << "Unable to open file" << jsonFilename << jsonFile.errorString(); - return metaDataMap; - } - - QByteArray bytes = jsonFile.readAll(); - jsonFile.close(); - QJsonParseError jsonParseError; - QJsonDocument doc = QJsonDocument::fromJson(bytes, &jsonParseError); - if (jsonParseError.error != QJsonParseError::NoError) { - qWarning() << "Unable to parse json document filename:error:offset" << jsonFilename << jsonParseError.errorString() << jsonParseError.offset; + QString errorString; + int version; + QJsonObject jsonObject = JsonHelper::openInternalQGCJsonFile(jsonFilename, qgcFileType, 1, 1, version, errorString); + if (!errorString.isEmpty()) { + qWarning() << "Internal Error: " << errorString; return metaDataMap; } QJsonArray factArray; QMap defineMap; - if (doc.isObject()) { - // Check for Defines/Facts format - QString errorString; - QList keyInfoList = { - { FactMetaData::_jsonMetaDataDefinesName, QJsonValue::Object, true }, - { FactMetaData::_jsonMetaDataFactsName, QJsonValue::Array, true }, - }; - if (!JsonHelper::validateKeys(doc.object(), keyInfoList, errorString)) { - qWarning() << "Json document incorrect format:" << errorString; - return metaDataMap; - } - - _loadJsonDefines(doc.object()[FactMetaData::_jsonMetaDataDefinesName].toObject(), defineMap); - factArray = doc.object()[FactMetaData::_jsonMetaDataFactsName].toArray(); - } else if (doc.isArray()) { - factArray = doc.array(); - } else { - qWarning() << "Json document is neither array nor object"; + QList keyInfoList = { + { FactMetaData::_jsonMetaDataDefinesName, QJsonValue::Object, false }, + { FactMetaData::_jsonMetaDataFactsName, QJsonValue::Array, true }, + }; + if (!JsonHelper::validateKeys(jsonObject, keyInfoList, errorString)) { + qWarning() << "Json document incorrect format:" << errorString; return metaDataMap; } + _loadJsonDefines(jsonObject[FactMetaData::_jsonMetaDataDefinesName].toObject(), defineMap); + factArray = jsonObject[FactMetaData::_jsonMetaDataFactsName].toArray(); + return createMapFromJsonArray(factArray, defineMap, metaDataParent); } diff --git a/src/FactSystem/FactMetaData.h b/src/FactSystem/FactMetaData.h index c6c1484c2..e5a27a94d 100644 --- a/src/FactSystem/FactMetaData.h +++ b/src/FactSystem/FactMetaData.h @@ -7,12 +7,7 @@ * ****************************************************************************/ - -/// @file -/// @author Don Gagne - -#ifndef FactMetaData_H -#define FactMetaData_H +#pragma once #include #include @@ -172,6 +167,8 @@ public: static ValueType_t stringToType(const QString& typeString, bool& unknownType); static size_t typeToSize(ValueType_t type); + static const char* qgcFileType; + private: QVariant _minForType(void) const; QVariant _maxForType(void) const; @@ -298,5 +295,3 @@ private: static const char* _jsonMetaDataDefinesName; static const char* _jsonMetaDataFactsName; }; - -#endif diff --git a/src/FirmwarePlugin/APM/MavCmdInfoCommon.json b/src/FirmwarePlugin/APM/APM-MavCmdInfoCommon.json similarity index 97% rename from src/FirmwarePlugin/APM/MavCmdInfoCommon.json rename to src/FirmwarePlugin/APM/APM-MavCmdInfoCommon.json index 1226035af..aee59c1ad 100644 --- a/src/FirmwarePlugin/APM/MavCmdInfoCommon.json +++ b/src/FirmwarePlugin/APM/APM-MavCmdInfoCommon.json @@ -1,7 +1,7 @@ { - "comment": "ArduPilot, Any Vehicle", - - "version": 1, + "comment": "ArduPilot, Any Vehicle", + "version": 1, + "fileType": "MavCmdInfo", "mavCmdInfo": [ { diff --git a/src/FirmwarePlugin/APM/MavCmdInfoFixedWing.json b/src/FirmwarePlugin/APM/APM-MavCmdInfoFixedWing.json similarity index 92% rename from src/FirmwarePlugin/APM/MavCmdInfoFixedWing.json rename to src/FirmwarePlugin/APM/APM-MavCmdInfoFixedWing.json index 9cca7514c..d647b6654 100644 --- a/src/FirmwarePlugin/APM/MavCmdInfoFixedWing.json +++ b/src/FirmwarePlugin/APM/APM-MavCmdInfoFixedWing.json @@ -1,7 +1,7 @@ { - "comment": "ArduPilot, Fixed Wing", - - "version": 1, + "comment": "ArduPilot, Fixed Wing", + "version": 1, + "fileType": "MavCmdInfo", "mavCmdInfo": [ { diff --git a/src/FirmwarePlugin/APM/MavCmdInfoMultiRotor.json b/src/FirmwarePlugin/APM/APM-MavCmdInfoMultiRotor.json similarity index 91% rename from src/FirmwarePlugin/APM/MavCmdInfoMultiRotor.json rename to src/FirmwarePlugin/APM/APM-MavCmdInfoMultiRotor.json index 4d47dac8d..2170b7038 100644 --- a/src/FirmwarePlugin/APM/MavCmdInfoMultiRotor.json +++ b/src/FirmwarePlugin/APM/APM-MavCmdInfoMultiRotor.json @@ -1,7 +1,7 @@ { - "comment": "ArduPilot, Multi Rotor", - - "version": 1, + "comment": "ArduPilot, Multi Rotor", + "version": 1, + "fileType": "MavCmdInfo", "mavCmdInfo": [ { diff --git a/src/FirmwarePlugin/APM/APM-MavCmdInfoRover.json b/src/FirmwarePlugin/APM/APM-MavCmdInfoRover.json new file mode 100644 index 000000000..d243f13f9 --- /dev/null +++ b/src/FirmwarePlugin/APM/APM-MavCmdInfoRover.json @@ -0,0 +1,8 @@ +{ + "comment": "ArduPilot, Rover", + "version": 1, + "fileType": "MavCmdInfo", + + "mavCmdInfo": [ + ] +} diff --git a/src/FirmwarePlugin/APM/APM-MavCmdInfoSub.json b/src/FirmwarePlugin/APM/APM-MavCmdInfoSub.json new file mode 100644 index 000000000..45c5962d0 --- /dev/null +++ b/src/FirmwarePlugin/APM/APM-MavCmdInfoSub.json @@ -0,0 +1,8 @@ +{ + "comment": "ArduPilot, Sub", + "version": 1, + "fileType": "MavCmdInfo", + + "mavCmdInfo": [ + ] +} diff --git a/src/FirmwarePlugin/APM/APM-MavCmdInfoVTOL.json b/src/FirmwarePlugin/APM/APM-MavCmdInfoVTOL.json new file mode 100644 index 000000000..e94cf27d4 --- /dev/null +++ b/src/FirmwarePlugin/APM/APM-MavCmdInfoVTOL.json @@ -0,0 +1,8 @@ +{ + "comment": "ArduPilot, VTOL", + "version": 1, + "fileType": "MavCmdInfo", + + "mavCmdInfo": [ + ] +} diff --git a/src/FirmwarePlugin/APM/APMFirmwarePlugin.cc b/src/FirmwarePlugin/APM/APMFirmwarePlugin.cc index 9a035ce55..4f0480fa7 100644 --- a/src/FirmwarePlugin/APM/APMFirmwarePlugin.cc +++ b/src/FirmwarePlugin/APM/APMFirmwarePlugin.cc @@ -753,17 +753,17 @@ QString APMFirmwarePlugin::missionCommandOverrides(MAV_TYPE vehicleType) const { switch (vehicleType) { case MAV_TYPE_GENERIC: - return QStringLiteral(":/json/APM/MavCmdInfoCommon.json"); + return QStringLiteral(":/json/APM-MavCmdInfoCommon.json"); case MAV_TYPE_FIXED_WING: - return QStringLiteral(":/json/APM/MavCmdInfoFixedWing.json"); + return QStringLiteral(":/json/APM-MavCmdInfoFixedWing.json"); case MAV_TYPE_QUADROTOR: - return QStringLiteral(":/json/APM/MavCmdInfoMultiRotor.json"); + return QStringLiteral(":/json/APM-MavCmdInfoMultiRotor.json"); case MAV_TYPE_VTOL_QUADROTOR: - return QStringLiteral(":/json/APM/MavCmdInfoVTOL.json"); + return QStringLiteral(":/json/APM-MavCmdInfoVTOL.json"); case MAV_TYPE_SUBMARINE: - return QStringLiteral(":/json/APM/MavCmdInfoSub.json"); + return QStringLiteral(":/json/APM-MavCmdInfoSub.json"); case MAV_TYPE_GROUND_ROVER: - return QStringLiteral(":/json/APM/MavCmdInfoRover.json"); + return QStringLiteral(":/json/APM-MavCmdInfoRover.json"); default: qWarning() << "APMFirmwarePlugin::missionCommandOverrides called with bad MAV_TYPE:" << vehicleType; return QString(); diff --git a/src/FirmwarePlugin/APM/APMResources.qrc b/src/FirmwarePlugin/APM/APMResources.qrc index 363bc846b..19e04df90 100644 --- a/src/FirmwarePlugin/APM/APMResources.qrc +++ b/src/FirmwarePlugin/APM/APMResources.qrc @@ -33,12 +33,12 @@ QGroundControl.ArduPilot.qmldir - MavCmdInfoCommon.json - MavCmdInfoFixedWing.json - MavCmdInfoMultiRotor.json - MavCmdInfoRover.json - MavCmdInfoSub.json - MavCmdInfoVTOL.json + APM-MavCmdInfoCommon.json + APM-MavCmdInfoFixedWing.json + APM-MavCmdInfoMultiRotor.json + APM-MavCmdInfoRover.json + APM-MavCmdInfoSub.json + APM-MavCmdInfoVTOL.json ../../AutoPilotPlugins/APM/APMFollowComponent.FactMetaData.json diff --git a/src/FirmwarePlugin/APM/MavCmdInfoRover.json b/src/FirmwarePlugin/APM/MavCmdInfoRover.json deleted file mode 100644 index 941b0b6da..000000000 --- a/src/FirmwarePlugin/APM/MavCmdInfoRover.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "comment": "ArduPilot, Rover", - - "version": 1, - - "mavCmdInfo": [ - ] -} diff --git a/src/FirmwarePlugin/APM/MavCmdInfoSub.json b/src/FirmwarePlugin/APM/MavCmdInfoSub.json deleted file mode 100644 index 0e2486979..000000000 --- a/src/FirmwarePlugin/APM/MavCmdInfoSub.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "comment": "ArduPilot, Sub", - - "version": 1, - - "mavCmdInfo": [ - ] -} diff --git a/src/FirmwarePlugin/APM/MavCmdInfoVTOL.json b/src/FirmwarePlugin/APM/MavCmdInfoVTOL.json deleted file mode 100644 index a486ae1d3..000000000 --- a/src/FirmwarePlugin/APM/MavCmdInfoVTOL.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "comment": "ArduPilot, VTOL", - - "version": 1, - - "mavCmdInfo": [ - ] -} diff --git a/src/FirmwarePlugin/PX4/MavCmdInfoFixedWing.json b/src/FirmwarePlugin/PX4/MavCmdInfoFixedWing.json deleted file mode 100644 index 12c53425e..000000000 --- a/src/FirmwarePlugin/PX4/MavCmdInfoFixedWing.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "comment": "PX4 Pro, Fixed Wing", - - "version": 1, - - "mavCmdInfo": [ - ] -} diff --git a/src/FirmwarePlugin/PX4/MavCmdInfoRover.json b/src/FirmwarePlugin/PX4/MavCmdInfoRover.json deleted file mode 100644 index 2402c0fc2..000000000 --- a/src/FirmwarePlugin/PX4/MavCmdInfoRover.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "comment": "PX4 Pro, Rover", - - "version": 1, - - "mavCmdInfo": [ - ] -} diff --git a/src/FirmwarePlugin/PX4/MavCmdInfoSub.json b/src/FirmwarePlugin/PX4/MavCmdInfoSub.json deleted file mode 100644 index e719d6e9e..000000000 --- a/src/FirmwarePlugin/PX4/MavCmdInfoSub.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "comment": "PX4 Pro, Sub", - - "version": 1, - - "mavCmdInfo": [ - ] -} diff --git a/src/FirmwarePlugin/PX4/MavCmdInfoVTOL.json b/src/FirmwarePlugin/PX4/MavCmdInfoVTOL.json deleted file mode 100644 index e2d418eca..000000000 --- a/src/FirmwarePlugin/PX4/MavCmdInfoVTOL.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "comment": "PX4 Pro, VTOL", - - "version": 1, - - "mavCmdInfo": [ - ] -} diff --git a/src/FirmwarePlugin/PX4/MavCmdInfoCommon.json b/src/FirmwarePlugin/PX4/PX4-MavCmdInfoCommon.json similarity index 85% rename from src/FirmwarePlugin/PX4/MavCmdInfoCommon.json rename to src/FirmwarePlugin/PX4/PX4-MavCmdInfoCommon.json index 865726189..3182be6fb 100644 --- a/src/FirmwarePlugin/PX4/MavCmdInfoCommon.json +++ b/src/FirmwarePlugin/PX4/PX4-MavCmdInfoCommon.json @@ -1,7 +1,7 @@ { - "comment": "PX4 Pro, Any Vehicle", - - "version": 1, + "comment": "PX4 Pro, Any Vehicle", + "version": 1, + "fileType": "MavCmdInfo", "mavCmdInfo": [ { diff --git a/src/FirmwarePlugin/PX4/PX4-MavCmdInfoFixedWing.json b/src/FirmwarePlugin/PX4/PX4-MavCmdInfoFixedWing.json new file mode 100644 index 000000000..836056d92 --- /dev/null +++ b/src/FirmwarePlugin/PX4/PX4-MavCmdInfoFixedWing.json @@ -0,0 +1,8 @@ +{ + "comment": "PX4 Pro, Fixed Wing", + "version": 1, + "fileType": "MavCmdInfo", + + "mavCmdInfo": [ + ] +} diff --git a/src/FirmwarePlugin/PX4/MavCmdInfoMultiRotor.json b/src/FirmwarePlugin/PX4/PX4-MavCmdInfoMultiRotor.json similarity index 90% rename from src/FirmwarePlugin/PX4/MavCmdInfoMultiRotor.json rename to src/FirmwarePlugin/PX4/PX4-MavCmdInfoMultiRotor.json index ae9917c29..cc37c64f9 100644 --- a/src/FirmwarePlugin/PX4/MavCmdInfoMultiRotor.json +++ b/src/FirmwarePlugin/PX4/PX4-MavCmdInfoMultiRotor.json @@ -1,7 +1,7 @@ { - "comment": "PX4 Pro, Multi Rotor", - - "version": 1, + "comment": "PX4 Pro, Multi Rotor", + "version": 1, + "fileType": "MavCmdInfo", "mavCmdInfo": [ { diff --git a/src/FirmwarePlugin/PX4/PX4-MavCmdInfoRover.json b/src/FirmwarePlugin/PX4/PX4-MavCmdInfoRover.json new file mode 100644 index 000000000..2dde98e8c --- /dev/null +++ b/src/FirmwarePlugin/PX4/PX4-MavCmdInfoRover.json @@ -0,0 +1,8 @@ +{ + "comment": "PX4 Pro, Rover", + "version": 1, + "fileType": "MavCmdInfo", + + "mavCmdInfo": [ + ] +} diff --git a/src/FirmwarePlugin/PX4/PX4-MavCmdInfoSub.json b/src/FirmwarePlugin/PX4/PX4-MavCmdInfoSub.json new file mode 100644 index 000000000..632f92c01 --- /dev/null +++ b/src/FirmwarePlugin/PX4/PX4-MavCmdInfoSub.json @@ -0,0 +1,8 @@ +{ + "comment": "PX4 Pro, Sub", + "version": 1, + "fileType": "MavCmdInfo", + + "mavCmdInfo": [ + ] +} diff --git a/src/FirmwarePlugin/PX4/PX4-MavCmdInfoVTOL.json b/src/FirmwarePlugin/PX4/PX4-MavCmdInfoVTOL.json new file mode 100644 index 000000000..e03df84d9 --- /dev/null +++ b/src/FirmwarePlugin/PX4/PX4-MavCmdInfoVTOL.json @@ -0,0 +1,8 @@ +{ + "comment": "PX4 Pro, VTOL", + "version": 1, + "fileType": "MavCmdInfo", + + "mavCmdInfo": [ + ] +} diff --git a/src/FirmwarePlugin/PX4/PX4FirmwarePlugin.cc b/src/FirmwarePlugin/PX4/PX4FirmwarePlugin.cc index cdb2baf2c..9e70bffec 100644 --- a/src/FirmwarePlugin/PX4/PX4FirmwarePlugin.cc +++ b/src/FirmwarePlugin/PX4/PX4FirmwarePlugin.cc @@ -312,17 +312,17 @@ QString PX4FirmwarePlugin::missionCommandOverrides(MAV_TYPE vehicleType) const { switch (vehicleType) { case MAV_TYPE_GENERIC: - return QStringLiteral(":/json/PX4/MavCmdInfoCommon.json"); + return QStringLiteral(":/json/PX4-MavCmdInfoCommon.json"); case MAV_TYPE_FIXED_WING: - return QStringLiteral(":/json/PX4/MavCmdInfoFixedWing.json"); + return QStringLiteral(":/json/PX4-MavCmdInfoFixedWing.json"); case MAV_TYPE_QUADROTOR: - return QStringLiteral(":/json/PX4/MavCmdInfoMultiRotor.json"); + return QStringLiteral(":/json/PX4-MavCmdInfoMultiRotor.json"); case MAV_TYPE_VTOL_QUADROTOR: - return QStringLiteral(":/json/PX4/MavCmdInfoVTOL.json"); + return QStringLiteral(":/json/PX4-MavCmdInfoVTOL.json"); case MAV_TYPE_SUBMARINE: - return QStringLiteral(":/json/PX4/MavCmdInfoSub.json"); + return QStringLiteral(":/json/PX4-MavCmdInfoSub.json"); case MAV_TYPE_GROUND_ROVER: - return QStringLiteral(":/json/PX4/MavCmdInfoRover.json"); + return QStringLiteral(":/json/PX4-MavCmdInfoRover.json"); default: qWarning() << "PX4FirmwarePlugin::missionCommandOverrides called with bad MAV_TYPE:" << vehicleType; return QString(); diff --git a/src/FirmwarePlugin/PX4/PX4Resources.qrc b/src/FirmwarePlugin/PX4/PX4Resources.qrc index 2418d5ab7..8b370c1e2 100644 --- a/src/FirmwarePlugin/PX4/PX4Resources.qrc +++ b/src/FirmwarePlugin/PX4/PX4Resources.qrc @@ -23,12 +23,12 @@ ../../QmlControls/QGroundControl/PX4/qmldir - MavCmdInfoCommon.json - MavCmdInfoFixedWing.json - MavCmdInfoMultiRotor.json - MavCmdInfoRover.json - MavCmdInfoSub.json - MavCmdInfoVTOL.json + PX4-MavCmdInfoCommon.json + PX4-MavCmdInfoFixedWing.json + PX4-MavCmdInfoMultiRotor.json + PX4-MavCmdInfoRover.json + PX4-MavCmdInfoSub.json + PX4-MavCmdInfoVTOL.json ../../AutoPilotPlugins/PX4/AirframeFactMetaData.xml diff --git a/src/JsonHelper.cc b/src/JsonHelper.cc index 61b8a747e..5c5656a6c 100644 --- a/src/JsonHelper.cc +++ b/src/JsonHelper.cc @@ -10,12 +10,17 @@ #include "JsonHelper.h" #include "QGCQGeoCoordinate.h" #include "QmlObjectListModel.h" +#include "MissionCommandList.h" +#include "FactMetaData.h" +#include "QGCApplication.h" #include #include #include #include #include +#include +#include const char* JsonHelper::_enumStringsJsonKey = "enumStrings"; const char* JsonHelper::_enumValuesJsonKey = "enumValues"; @@ -23,6 +28,8 @@ const char* JsonHelper::jsonVersionKey = "version"; const char* JsonHelper::jsonGroundStationKey = "groundStation"; const char* JsonHelper::jsonGroundStationValue = "QGroundControl"; const char* JsonHelper::jsonFileTypeKey = "fileType"; +const char* JsonHelper::_translateKeysKey = "translateKeys"; +const char* JsonHelper::_arrayIDKeysKey = "_arrayIDKeys"; bool JsonHelper::validateRequiredKeys(const QJsonObject& jsonObject, const QStringList& keys, QString& errorString) { @@ -215,22 +222,19 @@ bool JsonHelper::isJsonFile(const QByteArray& bytes, QJsonDocument& jsonDoc, QSt } } -bool JsonHelper::validateQGCJsonFile(const QJsonObject& jsonObject, - const QString& expectedFileType, - int minSupportedVersion, - int maxSupportedVersion, - int& version, - QString& errorString) +bool JsonHelper::validateInternalQGCJsonFile(const QJsonObject& jsonObject, + const QString& expectedFileType, + int minSupportedVersion, + int maxSupportedVersion, + int& version, + QString& errorString) { - // Check for required keys - QStringList requiredKeys = { jsonFileTypeKey, jsonGroundStationKey, jsonVersionKey }; - if (!validateRequiredKeys(jsonObject, requiredKeys, errorString)) { - return false; - } - - // Validate base key types - QList typeList = { QJsonValue::String, QJsonValue::String }; - if (!validateKeyTypes(jsonObject, requiredKeys, typeList, errorString)) { + // Validate required keys + QList requiredKeys = { + { jsonFileTypeKey, QJsonValue::String, true }, + { jsonVersionKey, QJsonValue::Double, true }, + }; + if (!JsonHelper::validateKeys(jsonObject, requiredKeys, errorString)) { return false; } @@ -241,18 +245,8 @@ bool JsonHelper::validateQGCJsonFile(const QJsonObject& jsonObject, return false; } - // Check version - support both old style v1 string and new style integer - - QJsonValue versionValue = jsonObject[jsonVersionKey]; - if (versionValue.type() == QJsonValue::String && versionValue.toString() == QStringLiteral("1.0")) { - version = 1; - } else { - if (versionValue.type() != QJsonValue::Double) { - errorString = QObject::tr("Incorrect type for version value, must be integer"); - return false; - } - version = versionValue.toInt(); - } + // Version check + version = jsonObject[jsonVersionKey].toInt(); if (version < minSupportedVersion) { errorString = QObject::tr("File version %1 is no longer supported").arg(version); return false; @@ -265,6 +259,143 @@ bool JsonHelper::validateQGCJsonFile(const QJsonObject& jsonObject, return true; } +bool JsonHelper::validateExternalQGCJsonFile(const QJsonObject& jsonObject, + const QString& expectedFileType, + int minSupportedVersion, + int maxSupportedVersion, + int& version, + QString& errorString) +{ + // Validate required keys + QList requiredKeys = { + { jsonGroundStationKey, QJsonValue::String, true }, + }; + if (!JsonHelper::validateKeys(jsonObject, requiredKeys, errorString)) { + return false; + } + + return validateInternalQGCJsonFile(jsonObject, expectedFileType, minSupportedVersion, maxSupportedVersion, version, errorString); +} + +QStringList JsonHelper::_addDefaultLocKeys(QJsonObject& jsonObject) +{ + QString translateKeys; + QString fileType = jsonObject[jsonFileTypeKey].toString(); + if (!fileType.isEmpty()) { + if (fileType == MissionCommandList::qgcFileType) { + if (jsonObject.contains(_translateKeysKey)) { + translateKeys = jsonObject[_translateKeysKey].toString(); + } else { + translateKeys = "label,enumStrings,friendlyName,description,category"; + jsonObject[_translateKeysKey] = translateKeys; + } + if (!jsonObject.contains(_arrayIDKeysKey)) { + jsonObject[_arrayIDKeysKey] = "rawName,comment"; + } + } else if (fileType == FactMetaData::qgcFileType) { + if (jsonObject.contains(_translateKeysKey)) { + translateKeys = jsonObject[_translateKeysKey].toString(); + } else { + translateKeys = "shortDescription,longDescription,enumStrings"; + jsonObject[_translateKeysKey] = "shortDescription,longDescription,enumStrings"; + } + if (!jsonObject.contains(_arrayIDKeysKey)) { + jsonObject[_arrayIDKeysKey] = "name"; + } + } + } + return translateKeys.split(","); +} + +QJsonObject JsonHelper::_translateObject(QJsonObject& jsonObject, const QString& translateContext, const QStringList& translateKeys) +{ + for (const QString& key: jsonObject.keys()) { + if (jsonObject[key].isString()) { + QString locString = jsonObject[key].toString(); + if (translateKeys.contains(key)) { + QString disambiguation; + QString disambiguationPrefix("#loc.disambiguation#"); + + if (locString.startsWith(disambiguationPrefix)) { + locString = locString.right(locString.length() - disambiguationPrefix.length()); + int commentEndIndex = locString.indexOf("#"); + if (commentEndIndex != -1) { + disambiguation = locString.left(commentEndIndex); + locString = locString.right(locString.length() - disambiguation.length() - 1); + } + } + + QString xlatString = qgcApp()->qgcTranslator().translate(translateContext.toUtf8().constData(), locString.toUtf8().constData(), disambiguation.toUtf8().constData()); + if (!xlatString.isNull()) { + jsonObject[key] = xlatString; + } + } + } else if (jsonObject[key].isArray()) { + QJsonArray childJsonArray = jsonObject[key].toArray(); + jsonObject[key] = _translateArray(childJsonArray, translateContext, translateKeys); + } else if (jsonObject[key].isObject()) { + QJsonObject childJsonObject = jsonObject[key].toObject(); + jsonObject[key] = _translateObject(childJsonObject, translateContext, translateKeys); + } + } + + return jsonObject; +} + +QJsonArray JsonHelper::_translateArray(QJsonArray& jsonArray, const QString& translateContext, const QStringList& translateKeys) +{ + for (int i=0; i #include #include +#include /// @file /// @author Don Gagne @@ -23,6 +23,8 @@ class QmlObjectListModel; /// Primarily used for parsing and processing Fact metadata. class JsonHelper { + Q_DECLARE_TR_FUNCTIONS(JsonHelper) + public: /// Determines is the specified data is a json file /// @return true: file is json, false: file is not json @@ -35,17 +37,38 @@ public: const QString& fileType, ///< file type for file int version); ///< version number for file - /// Validates the standard parts of a QGC json file: + /// Validates the standard parts of an external QGC json file (Plan file, ...): + /// jsonFileTypeKey - Required and checked to be equal to expectedFileType + /// jsonVersionKey - Required and checked to be below supportedMajorVersion, supportedMinorVersion + /// jsonGroundStationKey - Required and checked to be string type + /// @return false: validation failed, errorString set + static bool validateExternalQGCJsonFile(const QJsonObject& jsonObject, ///< json object to validate + const QString& expectedFileType, ///< correct file type for file + int minSupportedVersion, ///< minimum supported version + int maxSupportedVersion, ///< maximum supported major version + int &version, ///< returned file version + QString& errorString); ///< returned error string if validation fails + + /// Validates the standard parts of a internal QGC json file (FactMetaData, ...): /// jsonFileTypeKey - Required and checked to be equal to expectedFileType /// jsonVersionKey - Required and checked to be below supportedMajorVersion, supportedMinorVersion /// jsonGroundStationKey - Required and checked to be string type /// @return false: validation failed, errorString set - static bool validateQGCJsonFile(const QJsonObject& jsonObject, ///< json object to validate - const QString& expectedFileType, ///< correct file type for file - int minSupportedVersion, ///< minimum supported version - int maxSupportedVersion, ///< maximum supported major version - int &version, ///< returned file version - QString& errorString); ///< returned error string if validation fails + static bool validateInternalQGCJsonFile(const QJsonObject& jsonObject, ///< json object to validate + const QString& expectedFileType, ///< correct file type for file + int minSupportedVersion, ///< minimum supported version + int maxSupportedVersion, ///< maximum supported major version + int &version, ///< returned file version + QString& errorString); ///< returned error string if validation fails + + // Opens, validates and translates an internal QGC json file. + // @return Json root object for file. Empty QJsonObject if error. + static QJsonObject openInternalQGCJsonFile(const QString& jsonFilename, ///< Json file to open + const QString& expectedFileType, ///< correct file type for file + int minSupportedVersion, ///< minimum supported version + int maxSupportedVersion, ///< maximum supported major version + int &version, ///< returned file version + QString& errorString); ///< returned error string if validation fails /// Validates that the specified keys are in the object /// @return false: validation failed, errorString set @@ -149,9 +172,13 @@ private: QJsonValue& jsonValue, bool geoJsonFormat); static bool _parseEnumWorker(const QJsonObject& jsonObject, QMap& defineMap, QStringList& enumStrings, QStringList& enumValues, QString& errorString, QString valueName); + static QStringList _addDefaultLocKeys(QJsonObject& jsonObject); + static QJsonObject _translateRoot(QJsonObject& jsonObject, const QString& translateContext, const QStringList& translateKeys); + static QJsonObject _translateObject(QJsonObject& jsonObject, const QString& translateContext, const QStringList& translateKeys); + static QJsonArray _translateArray(QJsonArray& jsonArray, const QString& translateContext, const QStringList& translateKeys); static const char* _enumStringsJsonKey; static const char* _enumValuesJsonKey; + static const char* _translateKeysKey; + static const char* _arrayIDKeysKey; }; - -#endif diff --git a/src/MissionManager/BreachReturn.FactMetaData.json b/src/MissionManager/BreachReturn.FactMetaData.json index fa7536ee2..bc4146ee9 100644 --- a/src/MissionManager/BreachReturn.FactMetaData.json +++ b/src/MissionManager/BreachReturn.FactMetaData.json @@ -1,3 +1,7 @@ +{ + "version": 1, + "fileType": "FactMetaData", + "QGC.MetaData.Facts": [ { "name": "Latitude", @@ -19,3 +23,4 @@ "units": "m" } ] +} diff --git a/src/MissionManager/CameraCalc.FactMetaData.json b/src/MissionManager/CameraCalc.FactMetaData.json index 2addaa89c..36cf17978 100644 --- a/src/MissionManager/CameraCalc.FactMetaData.json +++ b/src/MissionManager/CameraCalc.FactMetaData.json @@ -1,3 +1,7 @@ +{ + "version": 1, + "fileType": "FactMetaData", + "QGC.MetaData.Facts": [ { "name": "CameraName", @@ -66,3 +70,4 @@ "defaultValue": 25 } ] +} diff --git a/src/MissionManager/CameraSection.FactMetaData.json b/src/MissionManager/CameraSection.FactMetaData.json index 818a18d42..16323cd30 100644 --- a/src/MissionManager/CameraSection.FactMetaData.json +++ b/src/MissionManager/CameraSection.FactMetaData.json @@ -1,3 +1,7 @@ +{ + "version": 1, + "fileType": "FactMetaData", + "QGC.MetaData.Facts": [ { "name": "CameraAction", @@ -56,3 +60,4 @@ "defaultValue": 0 } ] +} diff --git a/src/MissionManager/CameraSpec.FactMetaData.json b/src/MissionManager/CameraSpec.FactMetaData.json index f48ce287f..da1402412 100644 --- a/src/MissionManager/CameraSpec.FactMetaData.json +++ b/src/MissionManager/CameraSpec.FactMetaData.json @@ -1,3 +1,7 @@ +{ + "version": 1, + "fileType": "FactMetaData", + "QGC.MetaData.Facts": [ { "name": "Name", @@ -69,3 +73,4 @@ "defaultValue": 1.0 } ] +} diff --git a/src/MissionManager/CorridorScan.SettingsGroup.json b/src/MissionManager/CorridorScan.SettingsGroup.json index 78e0a7bb0..36a383cd8 100644 --- a/src/MissionManager/CorridorScan.SettingsGroup.json +++ b/src/MissionManager/CorridorScan.SettingsGroup.json @@ -1,3 +1,7 @@ +{ + "version": 1, + "fileType": "FactMetaData", + "QGC.MetaData.Facts": [ { "name": "Altitude", @@ -44,3 +48,4 @@ "defaultValue": 30 } ] +} diff --git a/src/MissionManager/FWLandingPattern.FactMetaData.json b/src/MissionManager/FWLandingPattern.FactMetaData.json index 61906dd2e..b34e15902 100644 --- a/src/MissionManager/FWLandingPattern.FactMetaData.json +++ b/src/MissionManager/FWLandingPattern.FactMetaData.json @@ -1,3 +1,7 @@ +{ + "version": 1, + "fileType": "FactMetaData", + "QGC.MetaData.Facts": [ { "name": "LandingDistance", @@ -72,3 +76,4 @@ "defaultValue": true } ] +} diff --git a/src/MissionManager/MavCmdInfoCommon.json b/src/MissionManager/MavCmdInfoCommon.json index 56a42f9b5..4fca3c147 100644 --- a/src/MissionManager/MavCmdInfoCommon.json +++ b/src/MissionManager/MavCmdInfoCommon.json @@ -1,7 +1,7 @@ { "comment": "Any Firmware, Any Vehicle", - - "version": 1, + "version": 1, + "fileType": "MavCmdInfo", "mavCmdInfo": [ { diff --git a/src/MissionManager/MavCmdInfoFixedWing.json b/src/MissionManager/MavCmdInfoFixedWing.json index cb37109cf..8d0c406d2 100644 --- a/src/MissionManager/MavCmdInfoFixedWing.json +++ b/src/MissionManager/MavCmdInfoFixedWing.json @@ -1,7 +1,7 @@ { - "comment": "Any Firmware, Fixed Wing", - - "version": 1, + "comment": "Any Firmware, Fixed Wing", + "version": 1, + "fileType": "MavCmdInfo", "mavCmdInfo": [ { diff --git a/src/MissionManager/MavCmdInfoMultiRotor.json b/src/MissionManager/MavCmdInfoMultiRotor.json index 90c4dec66..da324399d 100644 --- a/src/MissionManager/MavCmdInfoMultiRotor.json +++ b/src/MissionManager/MavCmdInfoMultiRotor.json @@ -1,7 +1,7 @@ { - "comment": "Any Firmware, Multi Rotor", - - "version": 1, + "comment": "Any Firmware, Multi Rotor", + "version": 1, + "fileType": "MavCmdInfo", "mavCmdInfo": [ ] diff --git a/src/MissionManager/MavCmdInfoRover.json b/src/MissionManager/MavCmdInfoRover.json index 41113dbcb..59fd1d299 100644 --- a/src/MissionManager/MavCmdInfoRover.json +++ b/src/MissionManager/MavCmdInfoRover.json @@ -1,7 +1,7 @@ { - "comment": "Any Firmware, Rover", - - "version": 1, + "comment": "Any Firmware, Rover", + "version": 1, + "fileType": "MavCmdInfo", "mavCmdInfo": [ ] diff --git a/src/MissionManager/MavCmdInfoSub.json b/src/MissionManager/MavCmdInfoSub.json index 632002069..5839d2e38 100644 --- a/src/MissionManager/MavCmdInfoSub.json +++ b/src/MissionManager/MavCmdInfoSub.json @@ -1,7 +1,7 @@ { - "comment": "Any Firmware, Sub", - - "version": 1, + "comment": "Any Firmware, Sub", + "version": 1, + "fileType": "MavCmdInfo", "mavCmdInfo": [ ] diff --git a/src/MissionManager/MavCmdInfoVTOL.json b/src/MissionManager/MavCmdInfoVTOL.json index ffe4cac74..22b59d8f4 100644 --- a/src/MissionManager/MavCmdInfoVTOL.json +++ b/src/MissionManager/MavCmdInfoVTOL.json @@ -1,7 +1,7 @@ { - "comment": "Any Firmware, VTOL", - - "version": 1, + "comment": "Any Firmware, VTOL", + "version": 1, + "fileType": "MavCmdInfo", "mavCmdInfo": [ ] diff --git a/src/MissionManager/MissionCommandList.cc b/src/MissionManager/MissionCommandList.cc index f156212a4..5ca37136c 100644 --- a/src/MissionManager/MissionCommandList.cc +++ b/src/MissionManager/MissionCommandList.cc @@ -22,6 +22,7 @@ #include #include +const char* MissionCommandList::qgcFileType = "MavCmdInfo"; const char* MissionCommandList::_versionJsonKey = "version"; const char* MissionCommandList::_mavCmdInfoJsonKey = "mavCmdInfo"; @@ -39,30 +40,15 @@ void MissionCommandList::_loadMavCmdInfoJson(const QString& jsonFilename, bool b qCDebug(MissionCommandsLog) << "Loading" << jsonFilename; - QFile jsonFile(jsonFilename); - if (!jsonFile.open(QIODevice::ReadOnly | QIODevice::Text)) { - qWarning() << "Unable to open file" << jsonFilename << jsonFile.errorString(); + QString errorString; + int version; + QJsonObject jsonObject = JsonHelper::openInternalQGCJsonFile(jsonFilename, qgcFileType, 1, 1, version, errorString); + if (!errorString.isEmpty()) { + qWarning() << "Internal Error: " << errorString; return; } - QByteArray bytes = jsonFile.readAll(); - jsonFile.close(); - QJsonParseError jsonParseError; - QJsonDocument doc = QJsonDocument::fromJson(bytes, &jsonParseError); - if (jsonParseError.error != QJsonParseError::NoError) { - qWarning() << jsonFilename << "Unable to open json document" << jsonParseError.errorString(); - return; - } - - QJsonObject json = doc.object(); - - int version = json.value(_versionJsonKey).toInt(); - if (version != 1) { - qWarning() << jsonFilename << "Invalid version" << version; - return; - } - - QJsonValue jsonValue = json.value(_mavCmdInfoJsonKey); + QJsonValue jsonValue = jsonObject.value(_mavCmdInfoJsonKey); if (!jsonValue.isArray()) { qWarning() << jsonFilename << "mavCmdInfo not array"; return; diff --git a/src/MissionManager/MissionCommandList.h b/src/MissionManager/MissionCommandList.h index 433365e25..5c62199ee 100644 --- a/src/MissionManager/MissionCommandList.h +++ b/src/MissionManager/MissionCommandList.h @@ -7,8 +7,7 @@ * ****************************************************************************/ -#ifndef MissionCommandList_H -#define MissionCommandList_H +#pragma once #include "QGCToolbox.h" #include "QGCMAVLink.h" @@ -40,6 +39,8 @@ public: const QList& commandIds(void) const { return _ids; } + static const char* qgcFileType; + private: void _loadMavCmdInfoJson(const QString& jsonFilename, bool baseCommandList); @@ -50,5 +51,3 @@ private: static const char* _versionJsonKey; static const char* _mavCmdInfoJsonKey; }; - -#endif diff --git a/src/MissionManager/MissionCommandTree.cc b/src/MissionManager/MissionCommandTree.cc index bee62b823..40f66b1f0 100644 --- a/src/MissionManager/MissionCommandTree.cc +++ b/src/MissionManager/MissionCommandTree.cc @@ -37,12 +37,12 @@ void MissionCommandTree::setToolbox(QGCToolbox* toolbox) #ifdef UNITTEST_BUILD if (_unitTest) { // Load unit testing tree - _staticCommandTree[MAV_AUTOPILOT_GENERIC][MAV_TYPE_GENERIC] = new MissionCommandList(":/unittest/MavCmdInfoCommon.json", true, this); - _staticCommandTree[MAV_AUTOPILOT_GENERIC][MAV_TYPE_FIXED_WING] = new MissionCommandList(":/unittest/MavCmdInfoFixedWing.json", false, this); - _staticCommandTree[MAV_AUTOPILOT_GENERIC][MAV_TYPE_QUADROTOR] = new MissionCommandList(":/unittest/MavCmdInfoMultiRotor.json", false, this); - _staticCommandTree[MAV_AUTOPILOT_GENERIC][MAV_TYPE_VTOL_QUADROTOR] = new MissionCommandList(":/unittest/MavCmdInfoVTOL.json", false, this); - _staticCommandTree[MAV_AUTOPILOT_GENERIC][MAV_TYPE_SUBMARINE] = new MissionCommandList(":/unittest/MavCmdInfoSub.json", false, this); - _staticCommandTree[MAV_AUTOPILOT_GENERIC][MAV_TYPE_GROUND_ROVER] = new MissionCommandList(":/unittest/MavCmdInfoRover.json", false, this); + _staticCommandTree[MAV_AUTOPILOT_GENERIC][MAV_TYPE_GENERIC] = new MissionCommandList(":/unittest/UT-MavCmdInfoCommon.json", true, this); + _staticCommandTree[MAV_AUTOPILOT_GENERIC][MAV_TYPE_FIXED_WING] = new MissionCommandList(":/unittest/UT-MavCmdInfoFixedWing.json", false, this); + _staticCommandTree[MAV_AUTOPILOT_GENERIC][MAV_TYPE_QUADROTOR] = new MissionCommandList(":/unittest/UT-MavCmdInfoMultiRotor.json", false, this); + _staticCommandTree[MAV_AUTOPILOT_GENERIC][MAV_TYPE_VTOL_QUADROTOR] = new MissionCommandList(":/unittest/UT-MavCmdInfoVTOL.json", false, this); + _staticCommandTree[MAV_AUTOPILOT_GENERIC][MAV_TYPE_SUBMARINE] = new MissionCommandList(":/unittest/UT-MavCmdInfoSub.json", false, this); + _staticCommandTree[MAV_AUTOPILOT_GENERIC][MAV_TYPE_GROUND_ROVER] = new MissionCommandList(":/unittest/UT-MavCmdInfoRover.json", false, this); } else { #endif // Load all levels of hierarchy diff --git a/src/MissionManager/MissionCommandUIInfo.cc b/src/MissionManager/MissionCommandUIInfo.cc index 68b58370e..2d822e2d8 100644 --- a/src/MissionManager/MissionCommandUIInfo.cc +++ b/src/MissionManager/MissionCommandUIInfo.cc @@ -417,7 +417,7 @@ bool MissionCommandUIInfo::loadJsonInfo(const QJsonObject& jsonObject, bool requ paramInfo->_enumValues << QVariant(value); } if (paramInfo->_enumValues.count() != paramInfo->_enumStrings.count()) { - internalError = QString("enum strings/values count mismatch: %1, %2").arg(paramInfo->_enumStrings.count()).arg(paramInfo->_enumValues.count()); + internalError = QString("enum strings/values count mismatch, label:'%1' enumStrings:'%2'").arg(paramInfo->_label).arg(paramInfo->_enumStrings.join(",")); errorString = _loadErrorString(internalError); return false; } diff --git a/src/MissionManager/MissionController.cc b/src/MissionManager/MissionController.cc index aeffa6db4..6fdd837a1 100644 --- a/src/MissionManager/MissionController.cc +++ b/src/MissionManager/MissionController.cc @@ -872,7 +872,7 @@ bool MissionController::_loadItemsFromJson(const QJsonObject& json, QmlObjectLis } int fileVersion; - JsonHelper::validateQGCJsonFile(json, + JsonHelper::validateExternalQGCJsonFile(json, _jsonFileTypeValue, // expected file type 1, // minimum supported version 2, // maximum supported version diff --git a/src/MissionManager/MissionSettings.FactMetaData.json b/src/MissionManager/MissionSettings.FactMetaData.json index 9357d636f..f80616714 100644 --- a/src/MissionManager/MissionSettings.FactMetaData.json +++ b/src/MissionManager/MissionSettings.FactMetaData.json @@ -1,3 +1,7 @@ +{ + "version": 1, + "fileType": "FactMetaData", + "QGC.MetaData.Facts": [ { "name": "PlannedHomePositionAltitude", @@ -8,3 +12,4 @@ "defaultValue": 0 } ] +} diff --git a/src/MissionManager/PlanMasterController.cc b/src/MissionManager/PlanMasterController.cc index 09b3e9c3c..1695bcbf7 100644 --- a/src/MissionManager/PlanMasterController.cc +++ b/src/MissionManager/PlanMasterController.cc @@ -362,7 +362,7 @@ void PlanMasterController::loadFromFile(const QString& filename) qgcApp()->toolbox()->corePlugin()->preLoadFromJson(this, json); int version; - if (!JsonHelper::validateQGCJsonFile(json, kPlanFileType, kPlanFileVersion, kPlanFileVersion, version, errorString)) { + if (!JsonHelper::validateExternalQGCJsonFile(json, kPlanFileType, kPlanFileVersion, kPlanFileVersion, version, errorString)) { qgcApp()->showAppMessage(errorMessage.arg(errorString)); return; } diff --git a/src/MissionManager/QGCMapCircle.Facts.json b/src/MissionManager/QGCMapCircle.Facts.json index 2f496fa1d..2183c0b73 100644 --- a/src/MissionManager/QGCMapCircle.Facts.json +++ b/src/MissionManager/QGCMapCircle.Facts.json @@ -1,3 +1,7 @@ +{ + "version": 1, + "fileType": "FactMetaData", + "QGC.MetaData.Facts": [ { "name": "Radius", @@ -8,3 +12,4 @@ "units": "m" } ] +} diff --git a/src/MissionManager/RallyPoint.FactMetaData.json b/src/MissionManager/RallyPoint.FactMetaData.json index 318f4ad85..27fef7732 100644 --- a/src/MissionManager/RallyPoint.FactMetaData.json +++ b/src/MissionManager/RallyPoint.FactMetaData.json @@ -1,3 +1,7 @@ +{ + "version": 1, + "fileType": "FactMetaData", + "QGC.MetaData.Facts": [ { "name": "Latitude", @@ -20,3 +24,4 @@ "defaultValue": 0.0 } ] +} diff --git a/src/MissionManager/SpeedSection.FactMetaData.json b/src/MissionManager/SpeedSection.FactMetaData.json index 0a6f4368d..ba4d6e738 100644 --- a/src/MissionManager/SpeedSection.FactMetaData.json +++ b/src/MissionManager/SpeedSection.FactMetaData.json @@ -1,3 +1,7 @@ +{ + "version": 1, + "fileType": "FactMetaData", + "QGC.MetaData.Facts": [ { "name": "FlightSpeed", @@ -9,3 +13,4 @@ "defaultValue": 0 } ] +} diff --git a/src/MissionManager/StructureScan.SettingsGroup.json b/src/MissionManager/StructureScan.SettingsGroup.json index 8f3d1b2b6..ff8aa42cd 100644 --- a/src/MissionManager/StructureScan.SettingsGroup.json +++ b/src/MissionManager/StructureScan.SettingsGroup.json @@ -1,3 +1,7 @@ +{ + "version": 1, + "fileType": "FactMetaData", + "QGC.MetaData.Facts": [ { "name": "GimbalPitch", @@ -48,3 +52,4 @@ "defaultValue": true } ] +} diff --git a/src/MissionManager/Survey.SettingsGroup.json b/src/MissionManager/Survey.SettingsGroup.json index 9cf5fcf58..17eb154a7 100644 --- a/src/MissionManager/Survey.SettingsGroup.json +++ b/src/MissionManager/Survey.SettingsGroup.json @@ -1,3 +1,7 @@ +{ + "version": 1, + "fileType": "FactMetaData", + "QGC.MetaData.Facts": [ { "name": "GridAngle", @@ -22,3 +26,4 @@ "defaultValue": false } ] +} diff --git a/src/MissionManager/TransectStyle.SettingsGroup.json b/src/MissionManager/TransectStyle.SettingsGroup.json index d65116894..2f24f1038 100644 --- a/src/MissionManager/TransectStyle.SettingsGroup.json +++ b/src/MissionManager/TransectStyle.SettingsGroup.json @@ -1,3 +1,7 @@ +{ + "version": 1, + "fileType": "FactMetaData", + "QGC.MetaData.Facts": [ { "name": "TurnAroundDistance", @@ -63,3 +67,4 @@ "defaultValue": 0 } ] +} diff --git a/src/MissionManager/UnitTest/MavCmdInfoMultiRotor.json b/src/MissionManager/UnitTest/MavCmdInfoMultiRotor.json deleted file mode 100644 index a8a83852d..000000000 --- a/src/MissionManager/UnitTest/MavCmdInfoMultiRotor.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "comment": "Any Firmware, Multi Rotor (unit test)", - - "version": 1, - - "mavCmdInfo": [ - ] -} diff --git a/src/MissionManager/UnitTest/MavCmdInfoSub.json b/src/MissionManager/UnitTest/MavCmdInfoSub.json deleted file mode 100644 index b372eb6f6..000000000 --- a/src/MissionManager/UnitTest/MavCmdInfoSub.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "comment": "Any Firmware, Sub (unit test)", - - "version": 1, - - "mavCmdInfo": [ - ] -} diff --git a/src/MissionManager/UnitTest/MavCmdInfoVTOL.json b/src/MissionManager/UnitTest/MavCmdInfoVTOL.json deleted file mode 100644 index e7060a893..000000000 --- a/src/MissionManager/UnitTest/MavCmdInfoVTOL.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "comment": "Any Firmware, VTOL (unit test)", - - "version": 1, - - "mavCmdInfo": [ - ] -} diff --git a/src/MissionManager/UnitTest/MavCmdInfoCommon.json b/src/MissionManager/UnitTest/UT-MavCmdInfoCommon.json similarity index 98% rename from src/MissionManager/UnitTest/MavCmdInfoCommon.json rename to src/MissionManager/UnitTest/UT-MavCmdInfoCommon.json index 76010b56c..c6dea22a4 100644 --- a/src/MissionManager/UnitTest/MavCmdInfoCommon.json +++ b/src/MissionManager/UnitTest/UT-MavCmdInfoCommon.json @@ -1,7 +1,7 @@ { - "comment": "Any Firmware, Any Vehicle (unit test)", - - "version": 1, + "comment": "Any Firmware, Any Vehicle (unit test)", + "version": 1, + "fileType": "MavCmdInfo", "mavCmdInfo": [ { diff --git a/src/MissionManager/UnitTest/MavCmdInfoFixedWing.json b/src/MissionManager/UnitTest/UT-MavCmdInfoFixedWing.json similarity index 93% rename from src/MissionManager/UnitTest/MavCmdInfoFixedWing.json rename to src/MissionManager/UnitTest/UT-MavCmdInfoFixedWing.json index f54c8c9f1..065e84acb 100644 --- a/src/MissionManager/UnitTest/MavCmdInfoFixedWing.json +++ b/src/MissionManager/UnitTest/UT-MavCmdInfoFixedWing.json @@ -1,7 +1,7 @@ { - "comment": "Any Firmware, Fixed Wing (unit test)", - - "version": 1, + "comment": "Any Firmware, Fixed Wing (unit test)", + "version": 1, + "fileType": "MavCmdInfo", "mavCmdInfo": [ { diff --git a/src/MissionManager/UnitTest/UT-MavCmdInfoMultiRotor.json b/src/MissionManager/UnitTest/UT-MavCmdInfoMultiRotor.json new file mode 100644 index 000000000..869a91143 --- /dev/null +++ b/src/MissionManager/UnitTest/UT-MavCmdInfoMultiRotor.json @@ -0,0 +1,8 @@ +{ + "comment": "Any Firmware, Multi Rotor (unit test)", + "version": 1, + "fileType": "MavCmdInfo", + + "mavCmdInfo": [ + ] +} diff --git a/src/MissionManager/UnitTest/MavCmdInfoRover.json b/src/MissionManager/UnitTest/UT-MavCmdInfoRover.json similarity index 62% rename from src/MissionManager/UnitTest/MavCmdInfoRover.json rename to src/MissionManager/UnitTest/UT-MavCmdInfoRover.json index 40d422fce..e452c794c 100644 --- a/src/MissionManager/UnitTest/MavCmdInfoRover.json +++ b/src/MissionManager/UnitTest/UT-MavCmdInfoRover.json @@ -1,7 +1,7 @@ { "comment": "Any Firmware, Rover (unit test)", - - "version": 1, + "version": 1, + "fileType": "MavCmdInfo", "mavCmdInfo": [ ] diff --git a/src/MissionManager/UnitTest/UT-MavCmdInfoSub.json b/src/MissionManager/UnitTest/UT-MavCmdInfoSub.json new file mode 100644 index 000000000..1b5a68c24 --- /dev/null +++ b/src/MissionManager/UnitTest/UT-MavCmdInfoSub.json @@ -0,0 +1,8 @@ +{ + "comment": "Any Firmware, Sub (unit test)", + "version": 1, + "fileType": "MavCmdInfo", + + "mavCmdInfo": [ + ] +} diff --git a/src/MissionManager/UnitTest/UT-MavCmdInfoVTOL.json b/src/MissionManager/UnitTest/UT-MavCmdInfoVTOL.json new file mode 100644 index 000000000..18713408e --- /dev/null +++ b/src/MissionManager/UnitTest/UT-MavCmdInfoVTOL.json @@ -0,0 +1,8 @@ +{ + "comment": "Any Firmware, VTOL (unit test)", + "version": 1, + "fileType": "MavCmdInfo", + + "mavCmdInfo": [ + ] +} diff --git a/src/MissionManager/VTOLLandingPattern.FactMetaData.json b/src/MissionManager/VTOLLandingPattern.FactMetaData.json index 2ccd0a5d8..6715a7dfb 100644 --- a/src/MissionManager/VTOLLandingPattern.FactMetaData.json +++ b/src/MissionManager/VTOLLandingPattern.FactMetaData.json @@ -1,3 +1,7 @@ +{ + "version": 1, + "fileType": "FactMetaData", + "QGC.MetaData.Facts": [ { "name": "LandingDistance", @@ -56,3 +60,4 @@ "defaultValue": true } ] +} diff --git a/src/PlanView/GeoFenceEditor.qml b/src/PlanView/GeoFenceEditor.qml index 667b6d37d..a91563882 100644 --- a/src/PlanView/GeoFenceEditor.qml +++ b/src/PlanView/GeoFenceEditor.qml @@ -62,7 +62,7 @@ QGCFlickable { wrapMode: Text.WordWrap font.pointSize: myGeoFenceController.supported ? ScreenTools.smallFontPointSize : ScreenTools.defaultFontPointSize text: myGeoFenceController.supported ? - qsTr("GeoFencing allows you to set a virtual ‘fence’ around the area you want to fly in.") : + qsTr("GeoFencing allows you to set a virtual fence around the area you want to fly in.") : qsTr("This vehicle does not support GeoFence.") } diff --git a/src/QGCApplication.cc b/src/QGCApplication.cc index 34671d22b..3c14a33ca 100644 --- a/src/QGCApplication.cc +++ b/src/QGCApplication.cc @@ -356,7 +356,6 @@ QGCApplication::QGCApplication(int &argc, char* argv[], bool unitTesting) } #endif /* __mobile__ */ - setLanguage(); _checkForNewVersion(); } diff --git a/src/QGCApplication.h b/src/QGCApplication.h index bf851fcaa..c8e054f9e 100644 --- a/src/QGCApplication.h +++ b/src/QGCApplication.h @@ -98,6 +98,8 @@ public: FactGroup* gpsRtkFactGroup(void) { return _gpsRtkFactGroup; } + QTranslator& qgcTranslator(void) { return _QGCTranslator; } + static QString cachedParameterMetaDataFile(void); static QString cachedAirframeMetaDataFile(void); diff --git a/src/QGCToolbox.cc b/src/QGCToolbox.cc index a6bbeef1a..d3583a472 100644 --- a/src/QGCToolbox.cc +++ b/src/QGCToolbox.cc @@ -98,6 +98,10 @@ void QGCToolbox::setChildToolboxes(void) { // SettingsManager must be first so settings are available to any subsequent tools _settingsManager->setToolbox(this); + + // We now know the language setting to setup the translators. This makes the translators available to the subsequence tools. + qgcApp()->setLanguage(); + _corePlugin->setToolbox(this); _audioOutput->setToolbox(this); _factSystem->setToolbox(this); diff --git a/src/QmlControls/EditPositionDialog.FactMetaData.json b/src/QmlControls/EditPositionDialog.FactMetaData.json index c136759e6..76a19a2c7 100644 --- a/src/QmlControls/EditPositionDialog.FactMetaData.json +++ b/src/QmlControls/EditPositionDialog.FactMetaData.json @@ -1,3 +1,7 @@ +{ + "version": 1, + "fileType": "FactMetaData", + "QGC.MetaData.Facts": [ { "name": "Latitude", @@ -47,3 +51,4 @@ "type": "string" } ] +} diff --git a/src/QmlControls/RCToParamDialog.FactMetaData.json b/src/QmlControls/RCToParamDialog.FactMetaData.json index 63d3af9a6..e13cf5fde 100644 --- a/src/QmlControls/RCToParamDialog.FactMetaData.json +++ b/src/QmlControls/RCToParamDialog.FactMetaData.json @@ -1,3 +1,7 @@ +{ + "version": 1, + "fileType": "FactMetaData", + "QGC.MetaData.Facts": [ { "name": "Scale", @@ -29,3 +33,4 @@ "decimalPlaces": 7 } ] +} diff --git a/src/Settings/ADSBVehicleManager.SettingsGroup.json b/src/Settings/ADSBVehicleManager.SettingsGroup.json index 62500d7b4..82ff9fb46 100644 --- a/src/Settings/ADSBVehicleManager.SettingsGroup.json +++ b/src/Settings/ADSBVehicleManager.SettingsGroup.json @@ -1,3 +1,7 @@ +{ + "version": 1, + "fileType": "FactMetaData", + "QGC.MetaData.Facts": [ { "name": "adsbServerConnectEnabled", @@ -22,3 +26,4 @@ "qgcRebootRequired": true } ] +} diff --git a/src/Settings/APMMavlinkStreamRate.SettingsGroup.json b/src/Settings/APMMavlinkStreamRate.SettingsGroup.json index 954b079dc..53c875ed2 100644 --- a/src/Settings/APMMavlinkStreamRate.SettingsGroup.json +++ b/src/Settings/APMMavlinkStreamRate.SettingsGroup.json @@ -1,4 +1,7 @@ { + "version": 1, + "fileType": "FactMetaData", + "translateKeys": "StreamRateEnumStrings", "QGC.MetaData.Defines": { "StreamRateEnumStrings": "Controlled By Vehicle,0 hz,1 hz,2 hz,3 hz,4 hz,5 hz,6 hz,7 hz,8 hz,9 hz,10 hz,50 hz,100 hz", "StreamRateEnumValues": "-1,0,1,2,3,4,5,6,7,8,9,10,50,100" diff --git a/src/Settings/App.SettingsGroup.json b/src/Settings/App.SettingsGroup.json index f1312c92b..3f212dd79 100644 --- a/src/Settings/App.SettingsGroup.json +++ b/src/Settings/App.SettingsGroup.json @@ -1,3 +1,7 @@ +{ + "version": 1, + "fileType": "FactMetaData", + "QGC.MetaData.Facts": [ { "name": "offlineEditingFirmwareType", @@ -285,3 +289,4 @@ "defaultValue": true } ] +} diff --git a/src/Settings/AutoConnect.SettingsGroup.json b/src/Settings/AutoConnect.SettingsGroup.json index abbec2da6..2603c3339 100644 --- a/src/Settings/AutoConnect.SettingsGroup.json +++ b/src/Settings/AutoConnect.SettingsGroup.json @@ -1,3 +1,7 @@ +{ + "version": 1, + "fileType": "FactMetaData", + "QGC.MetaData.Facts": [ { "name": "autoConnectUDP", @@ -80,3 +84,4 @@ "defaultValue": 14401 } ] +} diff --git a/src/Settings/BrandImage.SettingsGroup.json b/src/Settings/BrandImage.SettingsGroup.json index df61322da..2b7c861d8 100644 --- a/src/Settings/BrandImage.SettingsGroup.json +++ b/src/Settings/BrandImage.SettingsGroup.json @@ -1,3 +1,7 @@ +{ + "version": 1, + "fileType": "FactMetaData", + "QGC.MetaData.Facts": [ { "name": "userBrandImageIndoor", @@ -14,3 +18,4 @@ "defaultValue": "" } ] +} diff --git a/src/Settings/FirmwareUpgrade.SettingsGroup.json b/src/Settings/FirmwareUpgrade.SettingsGroup.json index 97711ac12..8deb4d6fe 100644 --- a/src/Settings/FirmwareUpgrade.SettingsGroup.json +++ b/src/Settings/FirmwareUpgrade.SettingsGroup.json @@ -1,3 +1,7 @@ +{ + "version": 1, + "fileType": "FactMetaData", + "QGC.MetaData.Facts": [ { "name": "defaultFirmwareType", @@ -20,3 +24,4 @@ "defaultValue": 0 } ] +} diff --git a/src/Settings/FlightMap.SettingsGroup.json b/src/Settings/FlightMap.SettingsGroup.json index 14135cddd..89c089be9 100644 --- a/src/Settings/FlightMap.SettingsGroup.json +++ b/src/Settings/FlightMap.SettingsGroup.json @@ -1,3 +1,7 @@ +{ + "version": 1, + "fileType": "FactMetaData", + "QGC.MetaData.Facts": [ { "name": "mapProvider", @@ -12,3 +16,4 @@ "defaultValue": "Hybrid" } ] +} diff --git a/src/Settings/FlyView.SettingsGroup.json b/src/Settings/FlyView.SettingsGroup.json index 118f6cadc..4773b5658 100644 --- a/src/Settings/FlyView.SettingsGroup.json +++ b/src/Settings/FlyView.SettingsGroup.json @@ -1,3 +1,7 @@ +{ + "version": 1, + "fileType": "FactMetaData", + "QGC.MetaData.Facts": [ { "name": "guidedMinimumAltitude", @@ -52,3 +56,4 @@ "min": 1 } ] +} diff --git a/src/Settings/OfflineMaps.SettingsGroup.json b/src/Settings/OfflineMaps.SettingsGroup.json index 48b7bad5f..8a3a12459 100644 --- a/src/Settings/OfflineMaps.SettingsGroup.json +++ b/src/Settings/OfflineMaps.SettingsGroup.json @@ -1,3 +1,7 @@ +{ + "version": 1, + "fileType": "FactMetaData", + "QGC.MetaData.Facts": [ { "name": "minZoomLevelDownload", @@ -22,3 +26,4 @@ "defaultValue": 100000 } ] +} diff --git a/src/Settings/PlanView.SettingsGroup.json b/src/Settings/PlanView.SettingsGroup.json index dcb198bc9..402efd259 100644 --- a/src/Settings/PlanView.SettingsGroup.json +++ b/src/Settings/PlanView.SettingsGroup.json @@ -1,3 +1,7 @@ +{ + "version": 1, + "fileType": "FactMetaData", + "QGC.MetaData.Facts": [ { "name": "displayPresetsTabFirst", @@ -30,3 +34,4 @@ "defaultValue": false } ] +} diff --git a/src/Settings/RTK.SettingsGroup.json b/src/Settings/RTK.SettingsGroup.json index 72b797d3e..928b80742 100644 --- a/src/Settings/RTK.SettingsGroup.json +++ b/src/Settings/RTK.SettingsGroup.json @@ -1,3 +1,7 @@ +{ + "version": 1, + "fileType": "FactMetaData", + "QGC.MetaData.Facts": [ { "name": "surveyInAccuracyLimit", @@ -72,3 +76,4 @@ "qgcRebootRequired": true } ] +} diff --git a/src/Settings/Units.SettingsGroup.json b/src/Settings/Units.SettingsGroup.json index 0d4f101c7..9bdf73105 100644 --- a/src/Settings/Units.SettingsGroup.json +++ b/src/Settings/Units.SettingsGroup.json @@ -1,2 +1,7 @@ +{ + "version": 1, + "fileType": "FactMetaData", + "QGC.MetaData.Facts": [ ] +} diff --git a/src/Settings/Video.SettingsGroup.json b/src/Settings/Video.SettingsGroup.json index c9cd28a04..06dcc9b19 100644 --- a/src/Settings/Video.SettingsGroup.json +++ b/src/Settings/Video.SettingsGroup.json @@ -1,3 +1,7 @@ +{ + "version": 1, + "fileType": "FactMetaData", + "QGC.MetaData.Facts": [ { "name": "videoSource", @@ -126,3 +130,4 @@ "defaultValue": false } ] +} diff --git a/src/Vehicle/BatteryFact.json b/src/Vehicle/BatteryFact.json index 9521501cf..cfca6c44a 100644 --- a/src/Vehicle/BatteryFact.json +++ b/src/Vehicle/BatteryFact.json @@ -1,3 +1,7 @@ +{ + "version": 1, + "fileType": "FactMetaData", + "QGC.MetaData.Facts": [ { "name": "voltage", @@ -57,3 +61,4 @@ "decimalPlaces": 0 } ] +} diff --git a/src/Vehicle/ClockFact.json b/src/Vehicle/ClockFact.json index dc233f9ca..592a63634 100644 --- a/src/Vehicle/ClockFact.json +++ b/src/Vehicle/ClockFact.json @@ -1,3 +1,7 @@ +{ + "version": 1, + "fileType": "FactMetaData", + "QGC.MetaData.Facts": [ { "name": "currentTime", @@ -10,3 +14,4 @@ "type": "string" } ] +} diff --git a/src/Vehicle/DistanceSensorFact.json b/src/Vehicle/DistanceSensorFact.json index 97f2837e4..3ef83db0f 100644 --- a/src/Vehicle/DistanceSensorFact.json +++ b/src/Vehicle/DistanceSensorFact.json @@ -1,3 +1,7 @@ +{ + "version": 1, + "fileType": "FactMetaData", + "QGC.MetaData.Facts": [ { "name": "rotationNone", @@ -70,3 +74,4 @@ "units": "m" } ] +} diff --git a/src/Vehicle/EstimatorStatusFactGroup.json b/src/Vehicle/EstimatorStatusFactGroup.json index 6a1d3cea0..99b10f969 100644 --- a/src/Vehicle/EstimatorStatusFactGroup.json +++ b/src/Vehicle/EstimatorStatusFactGroup.json @@ -1,3 +1,7 @@ +{ + "version": 1, + "fileType": "FactMetaData", + "QGC.MetaData.Facts": [ { "name": "goodAttitudeEsimate", @@ -128,3 +132,4 @@ "default": null } ] +} diff --git a/src/Vehicle/GPSFact.json b/src/Vehicle/GPSFact.json index 3f7fe6843..f8f44aeda 100644 --- a/src/Vehicle/GPSFact.json +++ b/src/Vehicle/GPSFact.json @@ -1,3 +1,7 @@ +{ + "version": 1, + "fileType": "FactMetaData", + "QGC.MetaData.Facts": [ { "name": "lat", @@ -49,3 +53,4 @@ "type": "uint32" } ] +} diff --git a/src/Vehicle/GPSRTKFact.json b/src/Vehicle/GPSRTKFact.json index 638bebf21..ad3abbe8f 100644 --- a/src/Vehicle/GPSRTKFact.json +++ b/src/Vehicle/GPSRTKFact.json @@ -1,3 +1,7 @@ +{ + "version": 1, + "fileType": "FactMetaData", + "QGC.MetaData.Facts": [ { "name": "connected", @@ -61,3 +65,4 @@ "default": 0 } ] +} diff --git a/src/Vehicle/SetpointFact.json b/src/Vehicle/SetpointFact.json index 58fea5833..ec39e1c63 100644 --- a/src/Vehicle/SetpointFact.json +++ b/src/Vehicle/SetpointFact.json @@ -1,3 +1,7 @@ +{ + "version": 1, + "fileType": "FactMetaData", + "QGC.MetaData.Facts": [ { "name": "roll", @@ -42,3 +46,4 @@ "units": "deg/s" } ] +} diff --git a/src/Vehicle/SubmarineFact.json b/src/Vehicle/SubmarineFact.json index 527a14f2a..2c5961dc9 100644 --- a/src/Vehicle/SubmarineFact.json +++ b/src/Vehicle/SubmarineFact.json @@ -1,3 +1,7 @@ +{ + "version": 1, + "fileType": "FactMetaData", + "QGC.MetaData.Facts": [ { "name": "camera tilt", @@ -43,3 +47,4 @@ "units": "meters" } ] +} diff --git a/src/Vehicle/TemperatureFact.json b/src/Vehicle/TemperatureFact.json index 01cfb25e7..4eec68bbd 100644 --- a/src/Vehicle/TemperatureFact.json +++ b/src/Vehicle/TemperatureFact.json @@ -1,3 +1,7 @@ +{ + "version": 1, + "fileType": "FactMetaData", + "QGC.MetaData.Facts": [ { "name": "temperature1", @@ -21,3 +25,4 @@ "units": "C" } ] +} diff --git a/src/Vehicle/TerrainFactGroup.json b/src/Vehicle/TerrainFactGroup.json index d29047346..4c131c43a 100644 --- a/src/Vehicle/TerrainFactGroup.json +++ b/src/Vehicle/TerrainFactGroup.json @@ -1,3 +1,7 @@ +{ + "version": 1, + "fileType": "FactMetaData", + "QGC.MetaData.Facts": [ { "name": "blocksPending", @@ -14,3 +18,4 @@ "default": 0 } ] +} diff --git a/src/Vehicle/VehicleFact.json b/src/Vehicle/VehicleFact.json index 41aaf28ea..52bc3b9af 100644 --- a/src/Vehicle/VehicleFact.json +++ b/src/Vehicle/VehicleFact.json @@ -1,3 +1,7 @@ +{ + "version": 1, + "fileType": "FactMetaData", + "QGC.MetaData.Facts": [ { "name": "roll", @@ -134,3 +138,4 @@ "units": "%" } ] +} diff --git a/src/Vehicle/VibrationFact.json b/src/Vehicle/VibrationFact.json index e56b5ea5c..b05e306d8 100644 --- a/src/Vehicle/VibrationFact.json +++ b/src/Vehicle/VibrationFact.json @@ -1,3 +1,7 @@ +{ + "version": 1, + "fileType": "FactMetaData", + "QGC.MetaData.Facts": [ { "name": "xAxis", @@ -33,3 +37,4 @@ "type": "uint32" } ] +} diff --git a/src/Vehicle/WindFact.json b/src/Vehicle/WindFact.json index ce2029406..0a84368af 100644 --- a/src/Vehicle/WindFact.json +++ b/src/Vehicle/WindFact.json @@ -1,3 +1,7 @@ +{ + "version": 1, + "fileType": "FactMetaData", + "QGC.MetaData.Facts": [ { "name": "direction", @@ -21,4 +25,4 @@ "units": "m/s" } ] - +} diff --git a/src/comm/QGCSerialPortInfo.cc b/src/comm/QGCSerialPortInfo.cc index 488f641c3..4cf191454 100644 --- a/src/comm/QGCSerialPortInfo.cc +++ b/src/comm/QGCSerialPortInfo.cc @@ -80,12 +80,12 @@ void QGCSerialPortInfo::_loadJsonData(void) int fileVersion; QString errorString; - if (!JsonHelper::validateQGCJsonFile(json, - _jsonFileTypeValue, // expected file type - 1, // minimum supported version - 1, // maximum supported version - fileVersion, - errorString)) { + if (!JsonHelper::validateInternalQGCJsonFile(json, + _jsonFileTypeValue, // expected file type + 1, // minimum supported version + 1, // maximum supported version + fileVersion, + errorString)) { qWarning() << errorString; return; } diff --git a/src/comm/USBBoardInfo.json b/src/comm/USBBoardInfo.json index 46c29a3ad..fc085fbcb 100644 --- a/src/comm/USBBoardInfo.json +++ b/src/comm/USBBoardInfo.json @@ -1,9 +1,7 @@ { "comment": "AutoConnect usb board info", - - "version": 1, - "fileType": "USBBoardInfo", - "groundStation": "QGroundControl", + "version": 1, + "fileType": "USBBoardInfo", "boardInfo": [ { "vendorID": 9900, "productID": 16, "boardClass": "Pixhawk", "name": "PX4 FMU V1" }, -- 2.22.0