QGroundControl
Ground Control Station for MAVLink Drones
Loading...
Searching...
No Matches
LinkSettings.qml
Go to the documentation of this file.
1import QtQuick
2import QtQuick.Controls
3import QtQuick.Dialogs
4import QtQuick.Layouts
5
6import QGroundControl
7import QGroundControl.Controls
8import QGroundControl.FactControls
9
10SettingsPage {
11 id: _root
12 property var _linkManager: QGroundControl.linkManager
13 property var _autoConnectSettings: QGroundControl.settingsManager.autoConnectSettings
14
15 SettingsGroupLayout {
16 heading: qsTr("AutoConnect")
17 visible: _autoConnectSettings.visible
18
19 Repeater {
20 id: autoConnectRepeater
21
22 model: [
23 _autoConnectSettings.autoConnectPixhawk,
24 _autoConnectSettings.autoConnectSiKRadio,
25 _autoConnectSettings.autoConnectLibrePilot,
26 _autoConnectSettings.autoConnectUDP,
27 _autoConnectSettings.autoConnectZeroConf,
28 _autoConnectSettings.autoConnectRTKGPS,
29 ]
30
31 property var names: [ qsTr("Pixhawk"), qsTr("SiK Radio"), qsTr("LibrePilot"), qsTr("UDP"), qsTr("Zero-Conf"), qsTr("RTK") ]
32
33 FactCheckBoxSlider {
34 Layout.fillWidth: true
35 text: autoConnectRepeater.names[index]
36 fact: modelData
37 visible: modelData.visible
38 }
39 }
40 }
41
42 SettingsGroupLayout {
43 heading: qsTr("NMEA GPS")
44 visible: QGroundControl.settingsManager.autoConnectSettings.autoConnectNmeaPort.visible && QGroundControl.settingsManager.autoConnectSettings.autoConnectNmeaBaud.visible
45
46 LabelledComboBox {
47 id: nmeaPortCombo
48 label: qsTr("Device")
49
50 model: ListModel {}
51
52 onActivated: (index) => {
53 if (index !== -1) {
54 QGroundControl.settingsManager.autoConnectSettings.autoConnectNmeaPort.value = comboBox.textAt(index);
55 }
56 }
57
58 Component.onCompleted: {
59 var model = []
60
61 model.push(qsTr("Disabled"))
62 model.push(qsTr("UDP Port"))
63
64 if (QGroundControl.linkManager.serialPorts.length === 0) {
65 model.push(qsTr("Serial <none available>"))
66 } else {
67 for (var i in QGroundControl.linkManager.serialPorts) {
68 model.push(QGroundControl.linkManager.serialPorts[i])
69 }
70 }
71 nmeaPortCombo.model = model
72
73 const index = nmeaPortCombo.comboBox.find(QGroundControl.settingsManager.autoConnectSettings.autoConnectNmeaPort.valueString);
74 nmeaPortCombo.currentIndex = index;
75 }
76 }
77
78 LabelledComboBox {
79 id: nmeaBaudCombo
80 visible: (nmeaPortCombo.currentText !== "UDP Port") && (nmeaPortCombo.currentText !== "Disabled")
81 label: qsTr("Baudrate")
82 model: QGroundControl.linkManager.serialBaudRates
83
84 onActivated: (index) => {
85 if (index !== -1) {
86 QGroundControl.settingsManager.autoConnectSettings.autoConnectNmeaBaud.value = parseInt(comboBox.textAt(index));
87 }
88 }
89
90 Component.onCompleted: {
91 const index = nmeaBaudCombo.comboBox.find(QGroundControl.settingsManager.autoConnectSettings.autoConnectNmeaBaud.valueString);
92 nmeaBaudCombo.currentIndex = index;
93 }
94 }
95
96 LabelledFactTextField {
97 visible: nmeaPortCombo.currentText === "UDP Port"
98 label: qsTr("NMEA stream UDP port")
99 fact: QGroundControl.settingsManager.autoConnectSettings.nmeaUdpPort
100 }
101 }
102
103 SettingsGroupLayout {
104 heading: qsTr("Links")
105
106 Repeater {
107 model: _linkManager.linkConfigurations
108
109 RowLayout {
110 Layout.fillWidth: true
111 visible: !object.dynamic
112
113 QGCLabel {
114 Layout.fillWidth: true
115 text: object.name
116 }
117 QGCColoredImage {
118 height: ScreenTools.minTouchPixels
119 width: height
120 sourceSize.height: height
121 fillMode: Image.PreserveAspectFit
122 mipmap: true
123 smooth: true
124 color: qgcPalEdit.text
125 source: "/res/pencil.svg"
126 enabled: !object.link
127
128 QGCPalette {
129 id: qgcPalEdit
130 colorGroupEnabled: parent.enabled
131 }
132
133 QGCMouseArea {
134 fillItem: parent
135 onClicked: {
136 var editingConfig = _linkManager.startConfigurationEditing(object)
137 linkDialogFactory.open({ editingConfig: editingConfig, originalConfig: object })
138 }
139 }
140 }
141 QGCColoredImage {
142 height: ScreenTools.minTouchPixels
143 width: height
144 sourceSize.height: height
145 fillMode: Image.PreserveAspectFit
146 mipmap: true
147 smooth: true
148 color: qgcPalDelete.text
149 source: "/res/TrashDelete.svg"
150
151 QGCPalette {
152 id: qgcPalDelete
153 colorGroupEnabled: parent.enabled
154 }
155
156 QGCMouseArea {
157 fillItem: parent
158 onClicked: QGroundControl.showMessageDialog(
159 _root,
160 qsTr("Delete Link"),
161 qsTr("Are you sure you want to delete '%1'?").arg(object.name),
162 Dialog.Ok | Dialog.Cancel,
163 function () {
164 _linkManager.removeConfiguration(object)
165 })
166 }
167 }
168 QGCButton {
169 text: object.link ? qsTr("Disconnect") : qsTr("Connect")
170 onClicked: {
171 if (object.link) {
172 object.link.disconnect()
173 } else {
174 _linkManager.createConnectedLink(object)
175 }
176 }
177 }
178 }
179 }
180
181 LabelledButton {
182 label: qsTr("Add New Link")
183 buttonText: qsTr("Add")
184
185 onClicked: {
186 var editingConfig = _linkManager.createConfiguration(ScreenTools.isSerialAvailable ? LinkConfiguration.TypeSerial : LinkConfiguration.TypeUdp, "")
187 linkDialogFactory.open({ editingConfig: editingConfig, originalConfig: null })
188 }
189 }
190 }
191
192 QGCPopupDialogFactory {
193 id: linkDialogFactory
194
195 dialogComponent: linkDialogComponent
196 }
197
198 Component {
199 id: linkDialogComponent
200
201 QGCPopupDialog {
202 title: originalConfig ? qsTr("Edit Link") : qsTr("Add New Link")
203 buttons: Dialog.Save | Dialog.Cancel
204 acceptButtonEnabled: nameField.text !== ""
205
206 property var originalConfig
207 property var editingConfig
208
209 onAccepted: {
210 linkSettingsLoader.item.saveSettings()
211 editingConfig.name = nameField.text
212 if (originalConfig) {
213 _linkManager.endConfigurationEditing(originalConfig, editingConfig)
214 } else {
215 // If it was edited, it's no longer "dynamic"
216 editingConfig.dynamic = false
217 _linkManager.endCreateConfiguration(editingConfig)
218 }
219 }
220
221 onRejected: _linkManager.cancelConfigurationEditing(editingConfig)
222
223 ColumnLayout {
224 spacing: ScreenTools.defaultFontPixelHeight / 2
225
226 RowLayout {
227 Layout.fillWidth: true
228 spacing: ScreenTools.defaultFontPixelWidth
229
230 QGCLabel { text: qsTr("Name") }
231 QGCTextField {
232 id: nameField
233 Layout.fillWidth: true
234 text: editingConfig.name
235 placeholderText: qsTr("Enter name")
236 }
237 }
238
239 QGCCheckBoxSlider {
240 Layout.fillWidth: true
241 text: qsTr("Automatically Connect on Start")
242 checked: editingConfig.autoConnect
243 onCheckedChanged: editingConfig.autoConnect = checked
244 }
245
246 QGCCheckBoxSlider {
247 Layout.fillWidth: true
248 text: qsTr("High Latency")
249 checked: editingConfig.highLatency
250 onCheckedChanged: editingConfig.highLatency = checked
251 }
252
253 LabelledComboBox {
254 label: qsTr("Type")
255 enabled: originalConfig == null
256 model: _linkManager.linkTypeStrings
257 Component.onCompleted: comboBox.currentIndex = editingConfig.linkType
258
259 onActivated: (index) => {
260 if (index !== editingConfig.linkType) {
261 // Save current name
262 var name = nameField.text
263 // Create new link configuration
264 editingConfig = _linkManager.createConfiguration(index, name)
265 }
266 }
267 }
268
269 Loader {
270 id: linkSettingsLoader
271 source: editingConfig && editingConfig.settingsURL ? editingConfig.settingsURL : ""
272 asynchronous: true
273
274 property var subEditConfig: editingConfig
275 property int _firstColumnWidth: ScreenTools.defaultFontPixelWidth * 12
276 property int _secondColumnWidth: ScreenTools.defaultFontPixelWidth * 30
277 property int _rowSpacing: ScreenTools.defaultFontPixelHeight / 2
278 property int _colSpacing: ScreenTools.defaultFontPixelWidth / 2
279
280 onStatusChanged: {
281 if (status === Loader.Error) {
282 console.warn("Failed to load link settings page:", source)
283 }
284 }
285 }
286 }
287 }
288 }
289}