6import QGroundControl.Controls
7import QGroundControl.FactControls
11 pageComponent: pageComponent
19 spacing: ScreenTools.defaultFontPixelHeight * 0.75
21 readonly property string scriptRoot: "/APM/scripts/"
22 readonly property var luaNameFilters: [ qsTr("Lua Scripts (*.lua)"), qsTr("All Files (*)") ]
23 readonly property Fact scriptingEnabledFact: factController.getParameterFact(-1, "SCR_ENABLE", false)
25 readonly property var filteredEntries: {
26 let rawEntries = ftpController.directoryEntries.filter(function(entry) {
27 if (!entry || entry.length < 2) {
30 var kind = entry.charAt(0)
36 let filenameEntries = []
37 for (let i=0; i<rawEntries.length; i++) {
38 filenameEntries.push(rawEntries[i].slice(1).split("\t")[0])
40 return filenameEntries
43 function fullRemotePath(filename) {
44 return scriptRoot + filename
47 function fileNameFromPath(path) {
51 // Handle both forward slashes and backslashes
52 var normalizedPath = path.replace(/\\/g, "/")
53 var parts = normalizedPath.split("/")
54 return parts[parts.length - 1]
57 function refreshDirectoryList() {
58 ftpController.listDirectory(scriptRoot)
61 Component.onCompleted: {
62 if (scriptingEnabledFact && scriptingEnabledFact.rawValue) {
63 ftpController.listDirectory(root.scriptRoot)
68 target: scriptingEnabledFact
71 if (scriptingEnabledFact.rawValue) {
72 ftpController.listDirectory(root.scriptRoot)
82 onUploadComplete: (remotePath, error) => {
83 if (error.length > 0) {
84 statusText.text = error
86 statusText.text = qsTr("Upload succeeded: %1").arg(remotePath)
87 refreshDirectoryList()
91 onDownloadComplete: (filePath, error) => {
92 if (error.length > 0) {
93 statusText.text = error
95 statusText.text = qsTr("Download succeeded: %1").arg(filePath)
99 onDeleteComplete: (remotePath, error) => {
100 if (error.length > 0) {
101 statusText.text = error
103 statusText.text = qsTr("Delete succeeded: %1").arg(remotePath)
104 refreshDirectoryList()
109 FactPanelController {
113 QGCPalette { id: qgcPal; colorGroupEnabled: true }
116 text: qsTr("Enable Scripting")
117 fact: scriptingEnabledFact
118 enabled: scriptingEnabledFact !== null
123 Layout.fillWidth: true
124 text: ftpController.errorString
130 Layout.fillWidth: true
131 spacing: ScreenTools.defaultFontPixelHeight
132 enabled: !ftpController.busy && scriptingEnabledFact && scriptingEnabledFact.rawValue
136 iconSource: "/res/Upload.svg"
137 enabled: !ftpController.busy
139 uploadDialog.folder = QGroundControl.settingsManager.appSettings.missionSavePath
140 uploadDialog.openForLoad()
145 model: root.filteredEntries
148 width: button.checked ? deleteIcon.x + deleteIcon.width + button.rightPadding : button.width
149 height: button.height
150 radius: button.backRadius
151 border.width: button.showBorder ? 1 : 0
152 border.color: button.background.border.color
153 color: qgcPal.buttonHighlight
157 anchors.leftMargin: button.leftPadding
158 anchors.left: parent.left
159 anchors.verticalCenter: button.verticalCenter
161 height: button._iconHeight
162 fillMode: Image.PreserveAspectFit
163 source: "/res/Download.svg"
164 color: button.textColor
165 visible: button.checked
170 downloadDialog.defaultSuffix = "lua"
171 downloadDialog.title = qsTr("Download %1").arg(modelData)
172 downloadDialog.fileToDownload = modelData
173 downloadDialog.folder = QGroundControl.settingsManager.appSettings.missionSavePath
174 downloadDialog.openForLoad()
181 anchors.left: checked ? downloadIcon.right : parent.left
188 anchors.left: button.right
189 anchors.verticalCenter: button.verticalCenter
191 height: button._iconHeight
192 fillMode: Image.PreserveAspectFit
193 source: "/res/TrashCan.svg"
194 color: button.textColor
195 visible: button.checked
200 var confirm = qsTr("Are you sure you want to delete the script \"%1\"? This action cannot be undone.").arg(modelData)
201 QGroundControl.showMessageDialog(scriptingPage, qsTr("Delete Lua Script"), confirm, Dialog.Ok | Dialog.Cancel, function() {
202 var remotePath = root.fullRemotePath(modelData)
203 if (!ftpController.deleteFile(remotePath)) {
204 var deleteError = ftpController.errorString.length > 0 ? ftpController.errorString : qsTr("Delete failed")
205 QGroundControl.showMessageDialog(scriptingPage, qsTr("Lua Delete"), deleteError)
216 Layout.fillWidth: true
217 spacing: ScreenTools.defaultFontPixelHeight * 0.5
220 text: qsTr("Cancel Operation")
221 visible: ftpController.busy
222 onClicked: ftpController.cancelActiveOperation()
225 Item { Layout.fillWidth: true }
228 text: qsTr("Transferring... %1%" ).arg(Math.round(ftpController.progress * 100))
229 visible: ftpController.busy
235 title: qsTr("Select Lua script to upload")
236 nameFilters: root.luaNameFilters
238 onAcceptedForLoad: (file) => {
243 var fileName = root.fileNameFromPath(file)
244 if (fileName.length === 0) {
248 if (!fileName.toLowerCase().endsWith(".lua")) {
249 fileName = fileName + ".lua"
251 var remotePath = root.fullRemotePath(fileName)
252 if (!ftpController.uploadFile(file, remotePath)) {
253 var uploadError = ftpController.errorString.length > 0 ? ftpController.errorString : qsTr("Upload failed")
254 QGroundControl.showMessageDialog(scriptingPage, qsTr("Lua Upload"), uploadError)
262 title: qsTr("Save Lua Script")
263 nameFilters: root.luaNameFilters
266 property string fileToDownload
268 onAcceptedForLoad: (folder) => {
273 if (!ftpController.downloadFile(root.fullRemotePath(fileToDownload), folder, fileToDownload)) {
274 var downloadError = ftpController.errorString.length > 0 ? ftpController.errorString : qsTr("Download failed")
275 QGroundControl.showMessageDialog(scriptingPage, qsTr("Lua Download"), downloadError)
282 Layout.fillWidth: true
283 Layout.preferredHeight: availableHeight
285 visible: scriptingEnabledFact === null
288 anchors.centerIn: parent
289 text: qsTr("Scripting is not supported by this version of firmware.")
291 horizontalAlignment: Text.AlignHCenter
292 verticalAlignment: Text.AlignVCenter