You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1207 lines
59 KiB
1207 lines
59 KiB
/**************************************************************************** |
|
* |
|
* (c) 2009-2016 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org> |
|
* |
|
* QGroundControl is licensed according to the terms in the file |
|
* COPYING.md in the root of the source code directory. |
|
* |
|
****************************************************************************/ |
|
|
|
import QtQuick 2.3 |
|
import QtQuick.Controls 1.2 |
|
import QtQuick.Controls.Styles 1.4 |
|
import QtQuick.Dialogs 1.2 |
|
import QtQuick.Layouts 1.2 |
|
import QtLocation 5.3 |
|
import QtPositioning 5.3 |
|
|
|
import QGroundControl 1.0 |
|
import QGroundControl.Controls 1.0 |
|
import QGroundControl.ScreenTools 1.0 |
|
import QGroundControl.Palette 1.0 |
|
import QGroundControl.FlightMap 1.0 |
|
import QGroundControl.QGCMapEngineManager 1.0 |
|
import QGroundControl.FactSystem 1.0 |
|
import QGroundControl.FactControls 1.0 |
|
|
|
QGCView { |
|
id: offlineMapView |
|
viewPanel: panel |
|
anchors.fill: parent |
|
|
|
property var _currentSelection: null |
|
|
|
property string mapKey: "lastMapType" |
|
|
|
property Fact _mapboxFact: QGroundControl.settingsManager.appSettings.mapboxToken |
|
property Fact _esriFact: QGroundControl.settingsManager.appSettings.esriToken |
|
|
|
property string mapType: _settings.mapProvider.enumStringValue + " " + _settings.mapType.enumStringValue |
|
property bool isMapInteractive: false |
|
property var savedCenter: undefined |
|
property real savedZoom: 3 |
|
property string savedMapType: "" |
|
property bool _showPreview: true |
|
property bool _defaultSet: offlineMapView && offlineMapView._currentSelection && offlineMapView._currentSelection.defaultSet |
|
property real _margins: ScreenTools.defaultFontPixelWidth * 0.5 |
|
property real _buttonSize: ScreenTools.defaultFontPixelWidth * 12 |
|
property real _bigButtonSize: ScreenTools.defaultFontPixelWidth * 16 |
|
|
|
property bool _saveRealEstate: ScreenTools.isTinyScreen || ScreenTools.isShortScreen |
|
property real _adjustableFontPointSize: _saveRealEstate ? ScreenTools.smallFontPointSize : ScreenTools.defaultFontPointSize |
|
|
|
property var _mapAdjustedColor: _map.isSatelliteMap ? "white" : "black" |
|
property bool _tooManyTiles: QGroundControl.mapEngineManager.tileCount > _maxTilesForDownload |
|
property var _settings: QGroundControl.settingsManager.flightMapSettings |
|
|
|
readonly property real minZoomLevel: 1 |
|
readonly property real maxZoomLevel: 20 |
|
readonly property real sliderTouchArea: ScreenTools.defaultFontPixelWidth * (ScreenTools.isTinyScreen ? 5 : (ScreenTools.isMobile ? 6 : 3)) |
|
|
|
readonly property int _maxTilesForDownload: 100000 |
|
|
|
QGCPalette { id: qgcPal } |
|
|
|
Component.onCompleted: { |
|
QGroundControl.mapEngineManager.loadTileSets() |
|
updateMap() |
|
savedCenter = _map.toCoordinate(Qt.point(_map.width / 2, _map.height / 2), false /* clipToViewPort */) |
|
} |
|
|
|
Connections { |
|
target: QGroundControl.mapEngineManager |
|
onTileSetsChanged: { |
|
setName.text = QGroundControl.mapEngineManager.getUniqueName() |
|
} |
|
onErrorMessageChanged: { |
|
errorDialog.visible = true |
|
} |
|
} |
|
|
|
ExclusiveGroup { id: setGroup } |
|
|
|
function handleChanges() { |
|
if(isMapInteractive) { |
|
var xl = 0 |
|
var yl = 0 |
|
var xr = _map.width.toFixed(0) - 1 // Must be within boundaries of visible map |
|
var yr = _map.height.toFixed(0) - 1 // Must be within boundaries of visible map |
|
var c0 = _map.toCoordinate(Qt.point(xl, yl), false /* clipToViewPort */) |
|
var c1 = _map.toCoordinate(Qt.point(xr, yr), false /* clipToViewPort */) |
|
QGroundControl.mapEngineManager.updateForCurrentView(c0.longitude, c0.latitude, c1.longitude, c1.latitude, sliderMinZoom.value, sliderMaxZoom.value, mapType) |
|
} |
|
} |
|
|
|
function updateMap() { |
|
for (var i = 0; i < _map.supportedMapTypes.length; i++) { |
|
//console.log(_map.supportedMapTypes[i].name) |
|
if (mapType === _map.supportedMapTypes[i].name) { |
|
_map.activeMapType = _map.supportedMapTypes[i] |
|
//console.log("Update Map:" + " " + _map.activeMapType) |
|
handleChanges() |
|
return |
|
} |
|
} |
|
} |
|
|
|
function addNewSet() { |
|
isMapInteractive = true |
|
mapType = _settings.mapProvider.enumStringValue + " " + _settings.mapType.enumStringValue |
|
resetMapToDefaults() |
|
handleChanges() |
|
_map.visible = true |
|
_tileSetList.visible = false |
|
infoView.visible = false |
|
_exporTiles.visible = false |
|
addNewSetView.visible = true |
|
} |
|
|
|
function showList() { |
|
_exporTiles.visible = false |
|
isMapInteractive = false |
|
_map.visible = false |
|
_tileSetList.visible = true |
|
infoView.visible = false |
|
addNewSetView.visible = false |
|
QGroundControl.mapEngineManager.resetAction(); |
|
} |
|
|
|
function showExport() { |
|
isMapInteractive = false |
|
_map.visible = false |
|
_tileSetList.visible = false |
|
infoView.visible = false |
|
addNewSetView.visible = false |
|
_exporTiles.visible = true |
|
} |
|
|
|
function showInfo() { |
|
isMapInteractive = false |
|
if(_currentSelection && !offlineMapView._currentSelection.deleting) { |
|
enterInfoView() |
|
} else |
|
showList() |
|
} |
|
|
|
function toRadian(deg) { |
|
return deg * Math.PI / 180 |
|
} |
|
|
|
function toDegree(rad) { |
|
return rad * 180 / Math.PI |
|
} |
|
|
|
function midPoint(lat1, lat2, lon1, lon2) { |
|
var dLon = toRadian(lon2 - lon1); |
|
lat1 = toRadian(lat1); |
|
lat2 = toRadian(lat2); |
|
lon1 = toRadian(lon1); |
|
var Bx = Math.cos(lat2) * Math.cos(dLon); |
|
var By = Math.cos(lat2) * Math.sin(dLon); |
|
var lat3 = Math.atan2(Math.sin(lat1) + Math.sin(lat2), Math.sqrt((Math.cos(lat1) + Bx) * (Math.cos(lat1) + Bx) + By * By)); |
|
var lon3 = lon1 + Math.atan2(By, Math.cos(lat1) + Bx); |
|
return QtPositioning.coordinate(toDegree(lat3), toDegree(lon3)) |
|
} |
|
|
|
function enterInfoView() { |
|
_map.visible = true |
|
isMapInteractive = false |
|
savedCenter = _map.toCoordinate(Qt.point(_map.width / 2, _map.height / 2), false /* clipToViewPort */) |
|
savedZoom = _map.zoomLevel |
|
savedMapType = mapType |
|
if(!offlineMapView._currentSelection.defaultSet) { |
|
mapType = offlineMapView._currentSelection.mapTypeStr |
|
_map.center = midPoint(offlineMapView._currentSelection.topleftLat, offlineMapView._currentSelection.bottomRightLat, offlineMapView._currentSelection.topleftLon, offlineMapView._currentSelection.bottomRightLon) |
|
//-- Delineate Set Region |
|
var x0 = offlineMapView._currentSelection.topleftLon |
|
var x1 = offlineMapView._currentSelection.bottomRightLon |
|
var y0 = offlineMapView._currentSelection.topleftLat |
|
var y1 = offlineMapView._currentSelection.bottomRightLat |
|
mapBoundary.topLeft = QtPositioning.coordinate(y0, x0) |
|
mapBoundary.bottomRight = QtPositioning.coordinate(y1, x1) |
|
mapBoundary.visible = true |
|
// Some times, for whatever reason, the bounding box is correct (around ETH for instance), but the rectangle is drawn across the planet. |
|
// When that happens, the "_map.fitViewportToMapItems()" below makes the map to zoom to the entire earth. |
|
//console.log("Map boundary: " + mapBoundary.topLeft + " " + mapBoundary.bottomRight) |
|
_map.fitViewportToMapItems() |
|
} |
|
_tileSetList.visible = false |
|
addNewSetView.visible = false |
|
infoView.visible = true |
|
} |
|
|
|
function leaveInfoView() { |
|
mapBoundary.visible = false |
|
_map.center = savedCenter |
|
_map.zoomLevel = savedZoom |
|
mapType = savedMapType |
|
} |
|
|
|
function resetMapToDefaults() { |
|
_map.center = QGroundControl.flightMapPosition |
|
_map.zoomLevel = QGroundControl.flightMapZoom |
|
} |
|
|
|
ExclusiveGroup { |
|
id: _dropButtonsExclusiveGroup |
|
} |
|
|
|
onMapTypeChanged: { |
|
updateMap() |
|
if(isMapInteractive) { |
|
QGroundControl.mapEngineManager.saveSetting(mapKey, mapType) |
|
} |
|
} |
|
|
|
MessageDialog { |
|
id: errorDialog |
|
visible: false |
|
text: QGroundControl.mapEngineManager.errorMessage |
|
icon: StandardIcon.Critical |
|
standardButtons: StandardButton.Ok |
|
title: qsTr("Error Message") |
|
onYes: { |
|
errorDialog.visible = false |
|
} |
|
} |
|
|
|
Component { |
|
id: optionsDialogComponent |
|
|
|
QGCViewDialog { |
|
id: optionDialog |
|
|
|
function accept() { |
|
QGroundControl.mapEngineManager.maxDiskCache = parseInt(maxCacheSize.text) |
|
QGroundControl.mapEngineManager.maxMemCache = parseInt(maxCacheMemSize.text) |
|
optionDialog.hideDialog() |
|
} |
|
|
|
QGCFlickable { |
|
anchors.fill: parent |
|
contentHeight: optionsColumn.height |
|
|
|
Column { |
|
id: optionsColumn |
|
anchors.margins: ScreenTools.defaultFontPixelWidth |
|
anchors.left: parent.left |
|
anchors.right: parent.right |
|
anchors.top: parent.top |
|
spacing: ScreenTools.defaultFontPixelHeight / 2 |
|
|
|
QGCLabel { text: qsTr("Max Cache Disk Size (MB):") } |
|
|
|
QGCTextField { |
|
id: maxCacheSize |
|
maximumLength: 6 |
|
inputMethodHints: Qt.ImhDigitsOnly |
|
validator: IntValidator {bottom: 1; top: 262144;} |
|
text: QGroundControl.mapEngineManager.maxDiskCache |
|
} |
|
|
|
Item { width: 1; height: 1 } |
|
|
|
QGCLabel { text: qsTr("Max Cache Memory Size (MB):") } |
|
|
|
QGCTextField { |
|
id: maxCacheMemSize |
|
maximumLength: 4 |
|
inputMethodHints: Qt.ImhDigitsOnly |
|
validator: IntValidator {bottom: 1; top: 1024;} |
|
text: QGroundControl.mapEngineManager.maxMemCache |
|
} |
|
|
|
QGCLabel { |
|
font.pointSize: _adjustableFontPointSize |
|
text: qsTr("Memory cache changes require a restart to take effect.") |
|
} |
|
|
|
Item { width: 1; height: 1; visible: _mapboxFact ? _mapboxFact.visible : false } |
|
QGCLabel { text: qsTr("Mapbox Access Token"); visible: _mapboxFact ? _mapboxFact.visible : false } |
|
FactTextField { |
|
fact: _mapboxFact |
|
visible: _mapboxFact ? _mapboxFact.visible : false |
|
maximumLength: 256 |
|
width: ScreenTools.defaultFontPixelWidth * 30 |
|
} |
|
QGCLabel { |
|
text: qsTr("To enable Mapbox maps, enter your access token.") |
|
visible: _mapboxFact ? _mapboxFact.visible : false |
|
font.pointSize: _adjustableFontPointSize |
|
} |
|
|
|
Item { width: 1; height: 1; visible: _esriFact ? _esriFact.visible : false } |
|
QGCLabel { text: qsTr("Esri Access Token"); visible: _esriFact ? _esriFact.visible : false } |
|
FactTextField { |
|
fact: _esriFact |
|
visible: _esriFact ? _esriFact.visible : false |
|
maximumLength: 256 |
|
width: ScreenTools.defaultFontPixelWidth * 30 |
|
} |
|
QGCLabel { |
|
text: qsTr("To enable Esri maps, enter your access token.") |
|
visible: _esriFact ? _esriFact.visible : false |
|
font.pointSize: _adjustableFontPointSize |
|
} |
|
} // GridLayout |
|
} // QGCFlickable |
|
} // QGCViewDialog - optionsDialog |
|
} // Component - optionsDialogComponent |
|
|
|
Component { |
|
id: deleteConfirmationDialogComponent |
|
QGCViewMessage { |
|
id: deleteConfirmationDialog |
|
message: { |
|
if(offlineMapView._currentSelection.defaultSet) |
|
return qsTr("This will delete all tiles INCLUDING the tile sets you have created yourself.\n\nIs this really what you want?"); |
|
else |
|
return qsTr("Delete %1 and all its tiles.\n\nIs this really what you want?").arg(offlineMapView._currentSelection.name); |
|
} |
|
function accept() { |
|
QGroundControl.mapEngineManager.deleteTileSet(offlineMapView._currentSelection) |
|
deleteConfirmationDialog.hideDialog() |
|
leaveInfoView() |
|
showList() |
|
} |
|
} |
|
} |
|
|
|
QGCViewPanel { |
|
id: panel |
|
anchors.fill: parent |
|
|
|
Map { |
|
id: _map |
|
anchors.fill: parent |
|
center: QGroundControl.flightMapPosition |
|
visible: false |
|
gesture.flickDeceleration: 3000 |
|
|
|
property bool isSatelliteMap: activeMapType.name.indexOf("Satellite") > -1 || activeMapType.name.indexOf("Hybrid") > -1 |
|
|
|
plugin: Plugin { name: "QGroundControl" } |
|
|
|
MapRectangle { |
|
id: mapBoundary |
|
border.width: 2 |
|
border.color: "red" |
|
color: Qt.rgba(1,0,0,0.05) |
|
smooth: true |
|
antialiasing: true |
|
} |
|
|
|
Component.onCompleted: resetMapToDefaults() |
|
|
|
onCenterChanged: handleChanges() |
|
onZoomLevelChanged: handleChanges() |
|
onWidthChanged: handleChanges() |
|
onHeightChanged: handleChanges() |
|
|
|
// Used to make pinch zoom work |
|
MouseArea { |
|
anchors.fill: parent |
|
} |
|
|
|
MapScale { |
|
anchors.leftMargin: ScreenTools.defaultFontPixelWidth / 2 |
|
anchors.bottomMargin: anchors.leftMargin |
|
anchors.left: parent.left |
|
anchors.bottom: parent.bottom |
|
mapControl: _map |
|
} |
|
|
|
//----------------------------------------------------------------- |
|
//-- Show Set Info |
|
Rectangle { |
|
id: infoView |
|
anchors.margins: ScreenTools.defaultFontPixelHeight |
|
anchors.right: parent.right |
|
anchors.verticalCenter: parent.verticalCenter |
|
width: tileInfoColumn.width + (ScreenTools.defaultFontPixelWidth * 2) |
|
height: tileInfoColumn.height + (ScreenTools.defaultFontPixelHeight * 2) |
|
color: Qt.rgba(qgcPal.window.r, qgcPal.window.g, qgcPal.window.b, 0.85) |
|
radius: ScreenTools.defaultFontPixelWidth * 0.5 |
|
visible: false |
|
|
|
property bool _extraButton: { |
|
if(!offlineMapView._currentSelection) |
|
return false; |
|
var curSel = offlineMapView._currentSelection; |
|
return !_defaultSet && ((!curSel.complete && !curSel.downloading) || (!curSel.complete && curSel.downloading)); |
|
} |
|
|
|
property real _labelWidth: ScreenTools.defaultFontPixelWidth * 10 |
|
property real _valueWidth: ScreenTools.defaultFontPixelWidth * 14 |
|
Column { |
|
id: tileInfoColumn |
|
anchors.margins: ScreenTools.defaultFontPixelHeight * 0.5 |
|
spacing: ScreenTools.defaultFontPixelHeight * 0.5 |
|
anchors.centerIn: parent |
|
QGCLabel { |
|
anchors.left: parent.left |
|
anchors.right: parent.right |
|
wrapMode: Text.WordWrap |
|
text: offlineMapView._currentSelection ? offlineMapView._currentSelection.name : "" |
|
font.pointSize: _saveRealEstate ? ScreenTools.defaultFontPointSize : ScreenTools.mediumFontPointSize |
|
horizontalAlignment: Text.AlignHCenter |
|
visible: _defaultSet |
|
} |
|
QGCTextField { |
|
id: editSetName |
|
anchors.left: parent.left |
|
anchors.right: parent.right |
|
visible: !_defaultSet |
|
text: offlineMapView._currentSelection ? offlineMapView._currentSelection.name : "" |
|
} |
|
QGCLabel { |
|
anchors.left: parent.left |
|
anchors.right: parent.right |
|
wrapMode: Text.WordWrap |
|
text: { |
|
if(offlineMapView._currentSelection) { |
|
if(offlineMapView._currentSelection.defaultSet) |
|
return qsTr("System Wide Tile Cache"); |
|
else |
|
return "(" + offlineMapView._currentSelection.mapTypeStr + ")" |
|
} else |
|
return ""; |
|
} |
|
horizontalAlignment: Text.AlignHCenter |
|
} |
|
//-- Tile Sets |
|
Row { |
|
spacing: ScreenTools.defaultFontPixelWidth |
|
anchors.horizontalCenter: parent.horizontalCenter |
|
visible: !_defaultSet |
|
QGCLabel { text: qsTr("Zoom Levels:"); width: infoView._labelWidth; } |
|
QGCLabel { text: offlineMapView._currentSelection ? (offlineMapView._currentSelection.minZoom + " - " + offlineMapView._currentSelection.maxZoom) : ""; horizontalAlignment: Text.AlignRight; width: infoView._valueWidth; } |
|
} |
|
Row { |
|
spacing: ScreenTools.defaultFontPixelWidth |
|
anchors.horizontalCenter: parent.horizontalCenter |
|
visible: !_defaultSet |
|
QGCLabel { text: qsTr("Total:"); width: infoView._labelWidth; } |
|
QGCLabel { text: (offlineMapView._currentSelection ? offlineMapView._currentSelection.totalTileCountStr : "") + " (" + (offlineMapView._currentSelection ? offlineMapView._currentSelection.totalTilesSizeStr : "") + ")"; horizontalAlignment: Text.AlignRight; width: infoView._valueWidth; } |
|
} |
|
Row { |
|
spacing: ScreenTools.defaultFontPixelWidth |
|
anchors.horizontalCenter: parent.horizontalCenter |
|
visible: offlineMapView && offlineMapView._currentSelection && !_defaultSet && offlineMapView._currentSelection.uniqueTileCount > 0 |
|
QGCLabel { text: qsTr("Unique:"); width: infoView._labelWidth; } |
|
QGCLabel { text: (offlineMapView._currentSelection ? offlineMapView._currentSelection.uniqueTileCountStr : "") + " (" + (offlineMapView._currentSelection ? offlineMapView._currentSelection.uniqueTileSizeStr : "") + ")"; horizontalAlignment: Text.AlignRight; width: infoView._valueWidth; } |
|
} |
|
|
|
Row { |
|
spacing: ScreenTools.defaultFontPixelWidth |
|
anchors.horizontalCenter: parent.horizontalCenter |
|
visible: offlineMapView && offlineMapView._currentSelection && !_defaultSet && !offlineMapView._currentSelection.complete |
|
QGCLabel { text: qsTr("Downloaded:"); width: infoView._labelWidth; } |
|
QGCLabel { text: (offlineMapView._currentSelection ? offlineMapView._currentSelection.savedTileCountStr : "") + " (" + (offlineMapView._currentSelection ? offlineMapView._currentSelection.savedTileSizeStr : "") + ")"; horizontalAlignment: Text.AlignRight; width: infoView._valueWidth; } |
|
} |
|
Row { |
|
spacing: ScreenTools.defaultFontPixelWidth |
|
anchors.horizontalCenter: parent.horizontalCenter |
|
visible: offlineMapView && offlineMapView._currentSelection && !_defaultSet && !offlineMapView._currentSelection.complete && offlineMapView._currentSelection.errorCount > 0 |
|
QGCLabel { text: qsTr("Error Count:"); width: infoView._labelWidth; } |
|
QGCLabel { text: offlineMapView._currentSelection ? offlineMapView._currentSelection.errorCountStr : ""; horizontalAlignment: Text.AlignRight; width: infoView._valueWidth; } |
|
} |
|
//-- Default Tile Set |
|
Row { |
|
spacing: ScreenTools.defaultFontPixelWidth |
|
anchors.horizontalCenter: parent.horizontalCenter |
|
visible: _defaultSet |
|
QGCLabel { text: qsTr("Size:"); width: infoView._labelWidth; } |
|
QGCLabel { text: offlineMapView._currentSelection ? offlineMapView._currentSelection.savedTileSizeStr : ""; horizontalAlignment: Text.AlignRight; width: infoView._valueWidth; } |
|
} |
|
Row { |
|
spacing: ScreenTools.defaultFontPixelWidth |
|
anchors.horizontalCenter: parent.horizontalCenter |
|
visible: _defaultSet |
|
QGCLabel { text: qsTr("Tile Count:"); width: infoView._labelWidth; } |
|
QGCLabel { text: offlineMapView._currentSelection ? offlineMapView._currentSelection.savedTileCountStr : ""; horizontalAlignment: Text.AlignRight; width: infoView._valueWidth; } |
|
} |
|
Row { |
|
spacing: ScreenTools.defaultFontPixelWidth |
|
anchors.horizontalCenter: parent.horizontalCenter |
|
QGCButton { |
|
text: qsTr("Resume Download") |
|
visible: offlineMapView._currentSelection && offlineMapView._currentSelection && !_defaultSet && (!offlineMapView._currentSelection.complete && !offlineMapView._currentSelection.downloading) |
|
width: ScreenTools.defaultFontPixelWidth * 16 |
|
onClicked: { |
|
if(offlineMapView._currentSelection) |
|
offlineMapView._currentSelection.resumeDownloadTask() |
|
} |
|
} |
|
QGCButton { |
|
text: qsTr("Cancel Download") |
|
visible: offlineMapView._currentSelection && offlineMapView._currentSelection && !_defaultSet && (!offlineMapView._currentSelection.complete && offlineMapView._currentSelection.downloading) |
|
width: ScreenTools.defaultFontPixelWidth * 16 |
|
onClicked: { |
|
if(offlineMapView._currentSelection) |
|
offlineMapView._currentSelection.cancelDownloadTask() |
|
} |
|
} |
|
QGCButton { |
|
text: qsTr("Delete") |
|
width: ScreenTools.defaultFontPixelWidth * (infoView._extraButton ? 6 : 10) |
|
onClicked: showDialog(deleteConfirmationDialogComponent, qsTr("Confirm Delete"), qgcView.showDialogDefaultWidth, StandardButton.Yes | StandardButton.No) |
|
} |
|
QGCButton { |
|
text: qsTr("Ok") |
|
width: ScreenTools.defaultFontPixelWidth * (infoView._extraButton ? 6 : 10) |
|
visible: !_defaultSet |
|
enabled: editSetName.text !== "" |
|
onClicked: { |
|
if(editSetName.text !== _currentSelection.name) { |
|
QGroundControl.mapEngineManager.renameTileSet(_currentSelection, editSetName.text) |
|
} |
|
leaveInfoView() |
|
showList() |
|
} |
|
} |
|
QGCButton { |
|
text: _defaultSet ? qsTr("Close") : qsTr("Cancel") |
|
width: ScreenTools.defaultFontPixelWidth * (infoView._extraButton ? 6 : 10) |
|
onClicked: { |
|
leaveInfoView() |
|
showList() |
|
} |
|
} |
|
} |
|
} |
|
} // Rectangle - infoView |
|
|
|
//----------------------------------------------------------------- |
|
//-- Add new set |
|
Item { |
|
id: addNewSetView |
|
anchors.fill: parent |
|
visible: false |
|
|
|
Column { |
|
anchors.verticalCenter: parent.verticalCenter |
|
anchors.leftMargin: _margins |
|
anchors.left: parent.left |
|
spacing: _margins |
|
|
|
QGCButton { |
|
text: "Show zoom previews" |
|
visible: !_showPreview |
|
onClicked: _showPreview = !_showPreview |
|
} |
|
|
|
Map { |
|
id: minZoomPreview |
|
width: addNewSetView.width / 4 |
|
height: addNewSetView.height / 4 |
|
center: _map.center |
|
activeMapType: _map.activeMapType |
|
zoomLevel: sliderMinZoom.value |
|
gesture.enabled: false |
|
visible: _showPreview |
|
|
|
property bool isSatelliteMap: activeMapType.name.indexOf("Satellite") > -1 || activeMapType.name.indexOf("Hybrid") > -1 |
|
|
|
plugin: Plugin { name: "QGroundControl" } |
|
|
|
MapScale { |
|
anchors.leftMargin: ScreenTools.defaultFontPixelWidth / 2 |
|
anchors.bottomMargin: anchors.leftMargin |
|
anchors.left: parent.left |
|
anchors.bottom: parent.bottom |
|
mapControl: parent |
|
} |
|
|
|
Rectangle { |
|
anchors.fill: parent |
|
border.color: _mapAdjustedColor |
|
color: "transparent" |
|
|
|
QGCMapLabel { |
|
anchors.centerIn: parent |
|
map: minZoomPreview |
|
text: qsTr("Min Zoom: %1").arg(sliderMinZoom.value) |
|
} |
|
MouseArea { |
|
anchors.fill: parent |
|
onClicked: _showPreview = false |
|
} |
|
} |
|
} // Map |
|
|
|
Map { |
|
id: maxZoomPreview |
|
width: minZoomPreview.width |
|
height: minZoomPreview.height |
|
center: _map.center |
|
activeMapType: _map.activeMapType |
|
zoomLevel: sliderMaxZoom.value |
|
gesture.enabled: false |
|
visible: _showPreview |
|
|
|
property bool isSatelliteMap: activeMapType.name.indexOf("Satellite") > -1 || activeMapType.name.indexOf("Hybrid") > -1 |
|
|
|
plugin: Plugin { name: "QGroundControl" } |
|
|
|
MapScale { |
|
anchors.leftMargin: ScreenTools.defaultFontPixelWidth / 2 |
|
anchors.bottomMargin: anchors.leftMargin |
|
anchors.left: parent.left |
|
anchors.bottom: parent.bottom |
|
mapControl: parent |
|
} |
|
|
|
Rectangle { |
|
anchors.fill: parent |
|
border.color: _mapAdjustedColor |
|
color: "transparent" |
|
|
|
QGCMapLabel { |
|
anchors.centerIn: parent |
|
map: maxZoomPreview |
|
text: qsTr("Max Zoom: %1").arg(sliderMaxZoom.value) |
|
} |
|
MouseArea { |
|
anchors.fill: parent |
|
onClicked: _showPreview = false |
|
} |
|
} |
|
} // Map |
|
} |
|
} // Item - Add new set view |
|
|
|
CenterMapDropButton { |
|
topMargin: 0 |
|
anchors.margins: _margins |
|
anchors.left: map.left |
|
anchors.top: map.top |
|
map: _map |
|
showMission: false |
|
showAllItems: false |
|
visible: addNewSetView.visible |
|
} |
|
} // Map |
|
|
|
//-- Add new set dialog |
|
Rectangle { |
|
anchors.margins: ScreenTools.defaultFontPixelWidth |
|
anchors.verticalCenter: parent.verticalCenter |
|
anchors.right: parent.right |
|
visible: addNewSetView.visible |
|
width: ScreenTools.defaultFontPixelWidth * (ScreenTools.isTinyScreen ? 24 : 28) |
|
height: Math.min(parent.height - (anchors.margins * 2), addNewSetFlickable.y + addNewSetColumn.height + addNewSetLabel.anchors.margins) |
|
color: Qt.rgba(qgcPal.window.r, qgcPal.window.g, qgcPal.window.b, 0.85) |
|
radius: ScreenTools.defaultFontPixelWidth * 0.5 |
|
|
|
MouseArea { |
|
anchors.fill: parent |
|
onWheel: { wheel.accepted = true; } |
|
onPressed: { mouse.accepted = true; } |
|
onReleased: { mouse.accepted = true; } |
|
} |
|
|
|
QGCLabel { |
|
id: addNewSetLabel |
|
anchors.margins: ScreenTools.defaultFontPixelHeight / 2 |
|
anchors.top: parent.top |
|
anchors.left: parent.left |
|
anchors.right: parent.right |
|
wrapMode: Text.WordWrap |
|
text: qsTr("Add New Set") |
|
font.pointSize: _saveRealEstate ? ScreenTools.defaultFontPointSize : ScreenTools.mediumFontPointSize |
|
horizontalAlignment: Text.AlignHCenter |
|
} |
|
|
|
QGCFlickable { |
|
id: addNewSetFlickable |
|
anchors.leftMargin: ScreenTools.defaultFontPixelWidth |
|
anchors.rightMargin: anchors.leftMargin |
|
anchors.topMargin: ScreenTools.defaultFontPixelWidth / 3 |
|
anchors.bottomMargin: anchors.topMargin |
|
anchors.top: addNewSetLabel.bottom |
|
anchors.left: parent.left |
|
anchors.right: parent.right |
|
anchors.bottom: parent.bottom |
|
clip: true |
|
contentHeight: addNewSetColumn.height |
|
|
|
Column { |
|
id: addNewSetColumn |
|
anchors.left: parent.left |
|
anchors.right: parent.right |
|
spacing: ScreenTools.defaultFontPixelHeight * (ScreenTools.isTinyScreen ? 0.25 : 0.5) |
|
|
|
Column { |
|
spacing: ScreenTools.isTinyScreen ? 0 : ScreenTools.defaultFontPixelHeight * 0.25 |
|
anchors.left: parent.left |
|
anchors.right: parent.right |
|
QGCLabel { text: qsTr("Name:") } |
|
QGCTextField { |
|
id: setName |
|
anchors.left: parent.left |
|
anchors.right: parent.right |
|
} |
|
} |
|
|
|
Column { |
|
spacing: ScreenTools.isTinyScreen ? 0 : ScreenTools.defaultFontPixelHeight * 0.25 |
|
anchors.left: parent.left |
|
anchors.right: parent.right |
|
QGCLabel { |
|
text: qsTr("Map type:") |
|
visible: !_saveRealEstate |
|
} |
|
QGCComboBox { |
|
id: mapCombo |
|
anchors.left: parent.left |
|
anchors.right: parent.right |
|
model: QGroundControl.mapEngineManager.mapList |
|
onActivated: { |
|
mapType = textAt(index) |
|
if(_dropButtonsExclusiveGroup.current) |
|
_dropButtonsExclusiveGroup.current.checked = false |
|
_dropButtonsExclusiveGroup.current = null |
|
} |
|
Component.onCompleted: { |
|
var index = mapCombo.find(mapType) |
|
if (index === -1) { |
|
console.warn("Active map name not in combo", mapType) |
|
} else { |
|
mapCombo.currentIndex = index |
|
} |
|
} |
|
} |
|
} |
|
|
|
Rectangle { |
|
anchors.left: parent.left |
|
anchors.right: parent.right |
|
height: zoomColumn.height + ScreenTools.defaultFontPixelHeight * 0.5 |
|
color: qgcPal.window |
|
border.color: qgcPal.text |
|
radius: ScreenTools.defaultFontPixelWidth * 0.5 |
|
|
|
Column { |
|
id: zoomColumn |
|
spacing: ScreenTools.isTinyScreen ? 0 : ScreenTools.defaultFontPixelHeight * 0.5 |
|
anchors.margins: ScreenTools.defaultFontPixelHeight * 0.25 |
|
anchors.top: parent.top |
|
anchors.left: parent.left |
|
anchors.right: parent.right |
|
|
|
QGCLabel { |
|
text: qsTr("Min/Max Zoom Levels") |
|
font.pointSize: _adjustableFontPointSize |
|
anchors.horizontalCenter: parent.horizontalCenter |
|
} |
|
|
|
Slider { |
|
id: sliderMinZoom |
|
anchors.left: parent.left |
|
anchors.right: parent.right |
|
height: sliderTouchArea * 1.25 |
|
minimumValue: minZoomLevel |
|
maximumValue: maxZoomLevel |
|
stepSize: 1 |
|
updateValueWhileDragging: true |
|
property real _savedZoom |
|
Component.onCompleted: Math.max(sliderMinZoom.value = _map.zoomLevel - 4, 2) |
|
onValueChanged: { |
|
if(sliderMinZoom.value > sliderMaxZoom.value) { |
|
sliderMaxZoom.value = sliderMinZoom.value |
|
} |
|
handleChanges() |
|
} |
|
style: SliderStyle { |
|
groove: Rectangle { |
|
implicitWidth: sliderMinZoom.width |
|
implicitHeight: 4 |
|
color: qgcPal.colorBlue |
|
radius: 4 |
|
} |
|
handle: Rectangle { |
|
anchors.centerIn: parent |
|
color: qgcPal.button |
|
border.color: qgcPal.buttonText |
|
border.width: 1 |
|
implicitWidth: sliderTouchArea |
|
implicitHeight: sliderTouchArea |
|
radius: sliderTouchArea * 0.5 |
|
Label { |
|
text: sliderMinZoom.value |
|
anchors.centerIn: parent |
|
font.family: ScreenTools.normalFontFamily |
|
font.pointSize: ScreenTools.smallFontPointSize |
|
color: qgcPal.buttonText |
|
} |
|
} |
|
} |
|
} // Slider - min zoom |
|
|
|
Slider { |
|
id: sliderMaxZoom |
|
anchors.left: parent.left |
|
anchors.right: parent.right |
|
height: sliderTouchArea * 1.25 |
|
minimumValue: minZoomLevel |
|
maximumValue: maxZoomLevel |
|
stepSize: 1 |
|
updateValueWhileDragging: true |
|
property real _savedZoom |
|
Component.onCompleted: Math.min(sliderMaxZoom.value = _map.zoomLevel + 2, 20) |
|
onValueChanged: { |
|
if(sliderMaxZoom.value < sliderMinZoom.value) { |
|
sliderMinZoom.value = sliderMaxZoom.value |
|
} |
|
handleChanges() |
|
} |
|
style: SliderStyle { |
|
groove: Rectangle { |
|
implicitWidth: sliderMaxZoom.width |
|
implicitHeight: 4 |
|
color: qgcPal.colorBlue |
|
radius: 4 |
|
} |
|
handle: Rectangle { |
|
anchors.centerIn: parent |
|
color: qgcPal.button |
|
border.color: qgcPal.buttonText |
|
border.width: 1 |
|
implicitWidth: sliderTouchArea |
|
implicitHeight: sliderTouchArea |
|
radius: sliderTouchArea * 0.5 |
|
Label { |
|
text: sliderMaxZoom.value |
|
anchors.centerIn: parent |
|
font.family: ScreenTools.normalFontFamily |
|
font.pointSize: ScreenTools.smallFontPointSize |
|
color: qgcPal.buttonText |
|
} |
|
} |
|
} |
|
} // Slider - max zoom |
|
|
|
GridLayout { |
|
columns: 2 |
|
rowSpacing: ScreenTools.isTinyScreen ? 0 : ScreenTools.defaultFontPixelHeight * 0.5 |
|
QGCLabel { |
|
text: qsTr("Tile Count:") |
|
font.pointSize: _adjustableFontPointSize |
|
} |
|
QGCLabel { |
|
text: QGroundControl.mapEngineManager.tileCountStr |
|
font.pointSize: _adjustableFontPointSize |
|
} |
|
|
|
QGCLabel { |
|
text: qsTr("Est Size:") |
|
font.pointSize: _adjustableFontPointSize |
|
} |
|
QGCLabel { |
|
text: QGroundControl.mapEngineManager.tileSizeStr |
|
font.pointSize: _adjustableFontPointSize |
|
} |
|
} |
|
} // Column - Zoom info |
|
} // Rectangle - Zoom info |
|
|
|
QGCLabel { |
|
text: qsTr("Too many tiles") |
|
visible: _tooManyTiles |
|
color: qgcPal.warningText |
|
anchors.horizontalCenter: parent.horizontalCenter |
|
} |
|
|
|
Row { |
|
id: addButtonRow |
|
spacing: ScreenTools.defaultFontPixelWidth |
|
anchors.horizontalCenter: parent.horizontalCenter |
|
QGCButton { |
|
text: qsTr("Download") |
|
width: (addNewSetColumn.width * 0.5) - (addButtonRow.spacing * 0.5) |
|
enabled: !_tooManyTiles && setName.text.length > 0 |
|
onClicked: { |
|
if(QGroundControl.mapEngineManager.findName(setName.text)) { |
|
duplicateName.visible = true |
|
} else { |
|
QGroundControl.mapEngineManager.startDownload(setName.text, mapType); |
|
showList() |
|
} |
|
} |
|
} |
|
QGCButton { |
|
text: qsTr("Cancel") |
|
width: (addNewSetColumn.width * 0.5) - (addButtonRow.spacing * 0.5) |
|
onClicked: { |
|
showList() |
|
} |
|
} |
|
} |
|
|
|
} // Column |
|
} // QGCFlickable |
|
} // Rectangle - Add new set dialog |
|
|
|
QGCFlickable { |
|
id: _tileSetList |
|
clip: true |
|
anchors.margins: ScreenTools.defaultFontPixelWidth |
|
anchors.top: parent.top |
|
anchors.bottom: _listButtonRow.top |
|
anchors.left: parent.left |
|
anchors.right: parent.right |
|
contentHeight: _cacheList.height |
|
|
|
Column { |
|
id: _cacheList |
|
width: Math.min(_tileSetList.width, (ScreenTools.defaultFontPixelWidth * 50).toFixed(0)) |
|
spacing: ScreenTools.defaultFontPixelHeight * 0.5 |
|
anchors.horizontalCenter: parent.horizontalCenter |
|
OfflineMapButton { |
|
id: firstButton |
|
text: qsTr("Add New Set") |
|
width: _cacheList.width |
|
height: ScreenTools.defaultFontPixelHeight * 2 |
|
onClicked: { |
|
offlineMapView._currentSelection = null |
|
addNewSet() |
|
} |
|
} |
|
Repeater { |
|
model: QGroundControl.mapEngineManager.tileSets |
|
delegate: OfflineMapButton { |
|
text: object.name |
|
size: object.downloadStatus |
|
tiles: object.totalTileCount |
|
complete: object.complete |
|
width: firstButton.width |
|
height: ScreenTools.defaultFontPixelHeight * 2 |
|
onClicked: { |
|
offlineMapView._currentSelection = object |
|
showInfo() |
|
} |
|
} |
|
} |
|
} |
|
} |
|
Row { |
|
id: _listButtonRow |
|
visible: _tileSetList.visible |
|
spacing: _margins |
|
anchors.bottom: parent.bottom |
|
anchors.margins: ScreenTools.defaultFontPixelWidth |
|
anchors.horizontalCenter: parent.horizontalCenter |
|
QGCButton { |
|
text: qsTr("Import") |
|
width: _buttonSize |
|
visible: !ScreenTools.isMobile |
|
onClicked: { |
|
QGroundControl.mapEngineManager.importAction = QGCMapEngineManager.ActionNone |
|
rootLoader.sourceComponent = importDialog |
|
} |
|
} |
|
QGCButton { |
|
text: qsTr("Export") |
|
width: _buttonSize |
|
visible: !ScreenTools.isMobile |
|
enabled: QGroundControl.mapEngineManager.tileSets.count > 1 |
|
onClicked: showExport() |
|
} |
|
QGCButton { |
|
text: qsTr("Options") |
|
width: _buttonSize |
|
onClicked: showDialog(optionsDialogComponent, qsTr("Offline Maps Options"), qgcView.showDialogDefaultWidth, StandardButton.Save | StandardButton.Cancel) |
|
} |
|
} |
|
|
|
//-- Export Tile Sets |
|
QGCFlickable { |
|
id: _exporTiles |
|
clip: true |
|
visible: false |
|
anchors.margins: ScreenTools.defaultFontPixelWidth |
|
anchors.top: parent.top |
|
anchors.bottom: _exportButtonRow.top |
|
anchors.left: parent.left |
|
anchors.right: parent.right |
|
contentHeight: _exportList.height |
|
Column { |
|
id: _exportList |
|
width: Math.min(_exporTiles.width, (ScreenTools.defaultFontPixelWidth * 50).toFixed(0)) |
|
spacing: ScreenTools.defaultFontPixelHeight * 0.5 |
|
anchors.horizontalCenter: parent.horizontalCenter |
|
QGCLabel { |
|
text: qsTr("Select Tile Sets to Export") |
|
font.pointSize: ScreenTools.mediumFontPointSize |
|
} |
|
Item { width: 1; height: ScreenTools.defaultFontPixelHeight; } |
|
Repeater { |
|
model: QGroundControl.mapEngineManager.tileSets |
|
delegate: QGCCheckBox { |
|
text: object.name |
|
checked: object.selected |
|
onClicked: { |
|
object.selected = checked |
|
} |
|
} |
|
} |
|
} |
|
} |
|
Row { |
|
id: _exportButtonRow |
|
visible: _exporTiles.visible |
|
spacing: _margins |
|
anchors.bottom: parent.bottom |
|
anchors.margins: ScreenTools.defaultFontPixelWidth |
|
anchors.horizontalCenter: parent.horizontalCenter |
|
QGCButton { |
|
text: qsTr("Select All") |
|
width: _bigButtonSize |
|
onClicked: QGroundControl.mapEngineManager.selectAll() |
|
} |
|
QGCButton { |
|
text: qsTr("Select None") |
|
width: _bigButtonSize |
|
onClicked: QGroundControl.mapEngineManager.selectNone() |
|
} |
|
QGCButton { |
|
text: qsTr("Export") |
|
width: _bigButtonSize |
|
enabled: QGroundControl.mapEngineManager.selectedCount > 0 |
|
onClicked: { |
|
showList(); |
|
if(QGroundControl.mapEngineManager.exportSets()) { |
|
rootLoader.sourceComponent = exportToDiskProgress |
|
} |
|
} |
|
} |
|
QGCButton { |
|
text: qsTr("Cancel") |
|
width: _bigButtonSize |
|
onClicked: showList() |
|
} |
|
} |
|
} // QGCViewPanel |
|
|
|
Component { |
|
id: exportToDiskProgress |
|
Rectangle { |
|
width: mainWindow.width |
|
height: mainWindow.height |
|
color: "black" |
|
anchors.centerIn: parent |
|
Rectangle { |
|
width: parent.width * 0.5 |
|
height: exportCol.height * 1.25 |
|
radius: ScreenTools.defaultFontPixelWidth |
|
color: qgcPal.windowShadeDark |
|
border.color: qgcPal.text |
|
anchors.centerIn: parent |
|
Column { |
|
id: exportCol |
|
spacing: ScreenTools.defaultFontPixelHeight |
|
width: parent.width |
|
anchors.centerIn: parent |
|
QGCLabel { |
|
text: QGroundControl.mapEngineManager.importAction === QGCMapEngineManager.ActionExporting ? qsTr("Tile Set Export Progress") : qsTr("Tile Set Export Completed") |
|
font.family: ScreenTools.demiboldFontFamily |
|
font.pointSize: ScreenTools.mediumFontPointSize |
|
anchors.horizontalCenter: parent.horizontalCenter |
|
} |
|
ProgressBar { |
|
id: progressBar |
|
width: parent.width * 0.45 |
|
maximumValue: 100 |
|
value: QGroundControl.mapEngineManager.actionProgress |
|
anchors.horizontalCenter: parent.horizontalCenter |
|
} |
|
BusyIndicator { |
|
visible: QGroundControl.mapEngineManager ? QGroundControl.mapEngineManager.importAction === QGCMapEngineManager.ActionExporting : false |
|
running: QGroundControl.mapEngineManager ? QGroundControl.mapEngineManager.importAction === QGCMapEngineManager.ActionExporting : false |
|
width: exportCloseButton.height |
|
height: exportCloseButton.height |
|
anchors.horizontalCenter: parent.horizontalCenter |
|
} |
|
QGCButton { |
|
id: exportCloseButton |
|
text: qsTr("Close") |
|
width: _buttonSize |
|
visible: !QGroundControl.mapEngineManager.exporting |
|
anchors.horizontalCenter: parent.horizontalCenter |
|
onClicked: { |
|
rootLoader.sourceComponent = null |
|
} |
|
} |
|
} |
|
} |
|
} |
|
} |
|
|
|
Component { |
|
id: importDialog |
|
Rectangle { |
|
width: mainWindow.width |
|
height: mainWindow.height |
|
color: "black" |
|
anchors.centerIn: parent |
|
Rectangle { |
|
width: parent.width * 0.5 |
|
height: importCol.height * 1.5 |
|
radius: ScreenTools.defaultFontPixelWidth |
|
color: qgcPal.windowShadeDark |
|
border.color: qgcPal.text |
|
anchors.centerIn: parent |
|
Column { |
|
id: importCol |
|
spacing: ScreenTools.defaultFontPixelHeight |
|
width: parent.width |
|
anchors.centerIn: parent |
|
QGCLabel { |
|
text: { |
|
if(QGroundControl.mapEngineManager.importAction === QGCMapEngineManager.ActionNone) { |
|
return qsTr("Map Tile Set Import"); |
|
} else if(QGroundControl.mapEngineManager.importAction === QGCMapEngineManager.ActionImporting) { |
|
return qsTr("Map Tile Set Import Progress"); |
|
} else { |
|
return qsTr("Map Tile Set Import Completed"); |
|
} |
|
} |
|
font.family: ScreenTools.demiboldFontFamily |
|
font.pointSize: ScreenTools.mediumFontPointSize |
|
anchors.horizontalCenter: parent.horizontalCenter |
|
} |
|
ProgressBar { |
|
id: progressBar |
|
width: parent.width * 0.45 |
|
maximumValue: 100 |
|
visible: QGroundControl.mapEngineManager.importAction === QGCMapEngineManager.ActionImporting |
|
value: QGroundControl.mapEngineManager.actionProgress |
|
anchors.horizontalCenter: parent.horizontalCenter |
|
} |
|
BusyIndicator { |
|
visible: QGroundControl.mapEngineManager.importAction === QGCMapEngineManager.ActionImporting |
|
running: QGroundControl.mapEngineManager.importAction === QGCMapEngineManager.ActionImporting |
|
width: ScreenTools.defaultFontPixelWidth * 2 |
|
height: width |
|
anchors.horizontalCenter: parent.horizontalCenter |
|
} |
|
ExclusiveGroup { id: radioGroup } |
|
Column { |
|
spacing: ScreenTools.defaultFontPixelHeight |
|
width: ScreenTools.defaultFontPixelWidth * 24 |
|
anchors.horizontalCenter: parent.horizontalCenter |
|
QGCRadioButton { |
|
exclusiveGroup: radioGroup |
|
text: qsTr("Append to existing set") |
|
checked: !QGroundControl.mapEngineManager.importReplace |
|
onClicked: QGroundControl.mapEngineManager.importReplace = !checked |
|
visible: QGroundControl.mapEngineManager.importAction === QGCMapEngineManager.ActionNone |
|
} |
|
QGCRadioButton { |
|
exclusiveGroup: radioGroup |
|
text: qsTr("Replace existing set") |
|
checked: QGroundControl.mapEngineManager.importReplace |
|
onClicked: QGroundControl.mapEngineManager.importReplace = checked |
|
visible: QGroundControl.mapEngineManager.importAction === QGCMapEngineManager.ActionNone |
|
} |
|
} |
|
QGCButton { |
|
text: qsTr("Close") |
|
width: _bigButtonSize * 1.25 |
|
visible: QGroundControl.mapEngineManager.importAction === QGCMapEngineManager.ActionDone |
|
anchors.horizontalCenter: parent.horizontalCenter |
|
onClicked: { |
|
showList(); |
|
rootLoader.sourceComponent = null |
|
} |
|
} |
|
Row { |
|
spacing: _margins |
|
visible: QGroundControl.mapEngineManager.importAction === QGCMapEngineManager.ActionNone |
|
anchors.horizontalCenter: parent.horizontalCenter |
|
QGCButton { |
|
text: qsTr("Import") |
|
width: _bigButtonSize * 1.25 |
|
onClicked: { |
|
if(!QGroundControl.mapEngineManager.importSets()) { |
|
showList(); |
|
rootLoader.sourceComponent = null |
|
} |
|
} |
|
} |
|
QGCButton { |
|
text: qsTr("Cancel") |
|
width: _bigButtonSize * 1.25 |
|
onClicked: { |
|
showList(); |
|
rootLoader.sourceComponent = null |
|
} |
|
} |
|
} |
|
} |
|
} |
|
} |
|
} |
|
|
|
} // QGCView
|
|
|