Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .clang-format
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ BraceWrapping:
IndentBraces: false
SplitEmptyFunction: true
SplitEmptyRecord: true
AllowShortFunctionsOnASingleLine: None
AllowShortIfStatementsOnASingleLine: Never
AllowShortFunctionsOnASingleLine: InlineOnly
AllowShortIfStatementsOnASingleLine: WithoutElse
Comment on lines +33 to +34
Copy link

Copilot AI Feb 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed from 'None'/'Never' to 'InlineOnly'/'WithoutElse'. This allows single-line inline functions and simple if statements without else clauses. Ensure the team agrees with this style change as it affects code formatting across the project.

Suggested change
AllowShortFunctionsOnASingleLine: InlineOnly
AllowShortIfStatementsOnASingleLine: WithoutElse
AllowShortFunctionsOnASingleLine: None
AllowShortIfStatementsOnASingleLine: Never

Copilot uses AI. Check for mistakes.
AllowShortLoopsOnASingleLine: false
AllowShortBlocksOnASingleLine: Never
AllowShortCaseLabelsOnASingleLine: false
Expand Down
17 changes: 14 additions & 3 deletions cmake/find-modules/FindGStreamer.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -131,18 +131,29 @@ elseif(LINUX)
# Android Platform
# ----------------------------------------------------------------------------
elseif(ANDROID)
set(_gst_android_url_official "https://gstreamer.freedesktop.org/data/pkg/android/${GStreamer_FIND_VERSION}/gstreamer-1.0-android-universal-${GStreamer_FIND_VERSION}.tar.xz")
set(_gst_android_url_qgc_mirror "https://qgroundcontrol.s3.us-west-2.amazonaws.com/android-gstreamer/qgc-android-gstreamer-${GStreamer_FIND_VERSION}.tar.xz")

if(QGC_CUSTOM_GST_PACKAGE)
set(_gst_android_url "https://qgroundcontrol.s3.us-west-2.amazonaws.com/android-gstreamer/qgc-android-gstreamer-${GStreamer_FIND_VERSION}.tar.xz")
# Prefer QGC mirror, but keep upstream as fallback to reduce CI flakiness.
set(_gst_android_urls
"${_gst_android_url_qgc_mirror}"
"${_gst_android_url_official}"
)
else()
set(_gst_android_url "https://gstreamer.freedesktop.org/data/pkg/android/${GStreamer_FIND_VERSION}/gstreamer-1.0-android-universal-${GStreamer_FIND_VERSION}.tar.xz")
# Prefer upstream package, fall back to QGC mirror on transient CDN/network failures.
set(_gst_android_urls
"${_gst_android_url_official}"
"${_gst_android_url_qgc_mirror}"
)
# https://gstreamer.freedesktop.org/data/pkg/android/${GStreamer_FIND_VERSION}/gstreamer-1.0-android-universal-${GStreamer_FIND_VERSION}.tar.xz.sha256sum
# set(_gst_android_url_hash "be92cf477d140c270b480bd8ba0e26b1e01c8db042c46b9e234d87352112e485")
endif()

CPMAddPackage(
NAME gstreamer
VERSION ${GStreamer_FIND_VERSION}
URL ${_gst_android_url}
URL ${_gst_android_urls}
# URL_HASH ${_gst_android_url_hash}
)

Expand Down
52 changes: 42 additions & 10 deletions cmake/install/CreateAppImage.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,22 @@
message(STATUS "QGC: Creating AppImage...")

set(APPDIR_PATH "${CMAKE_BINARY_DIR}/AppDir")
set(APPIMAGE_PATH "${CMAKE_BINARY_DIR}/${CMAKE_PROJECT_NAME}-${CMAKE_SYSTEM_PROCESSOR}.AppImage")

string(TOLOWER "${CMAKE_SYSTEM_PROCESSOR}" _qgc_system_processor)
if(_qgc_system_processor STREQUAL "x86_64" OR _qgc_system_processor STREQUAL "amd64")
set(_qgc_appimage_arch "x86_64")
elseif(_qgc_system_processor STREQUAL "aarch64" OR _qgc_system_processor STREQUAL "arm64")
set(_qgc_appimage_arch "aarch64")
elseif(_qgc_system_processor STREQUAL "armhf" OR _qgc_system_processor STREQUAL "armv7l")
set(_qgc_appimage_arch "armhf")
elseif(_qgc_system_processor STREQUAL "i686" OR _qgc_system_processor STREQUAL "i386")
set(_qgc_appimage_arch "i686")
else()
message(FATAL_ERROR "QGC: Unsupported AppImage architecture '${CMAKE_SYSTEM_PROCESSOR}'.")
endif()

set(APPIMAGE_PATH "${CMAKE_BINARY_DIR}/${CMAKE_PROJECT_NAME}-${_qgc_appimage_arch}.AppImage")
message(STATUS "QGC: AppImage architecture resolved to '${_qgc_appimage_arch}' from '${CMAKE_SYSTEM_PROCESSOR}'")

# ============================================================================
# Helper Functions
Expand All @@ -22,10 +37,24 @@ function(download_tool VAR URL)
if(NOT EXISTS "${_dest}")
file(MAKE_DIRECTORY "${CMAKE_BINARY_DIR}/tools")
message(STATUS "QGC: Downloading ${_name} to ${_dest}")
file(DOWNLOAD "${URL}" "${_dest}" STATUS _status TLS_VERIFY ON)
list(GET _status 0 _result)
if(NOT _result EQUAL 0)
message(FATAL_ERROR "Failed to download ${URL} to ${_dest}: ${_status}")
set(_download_ok FALSE)
set(_status "")
foreach(_attempt RANGE 1 3)
file(DOWNLOAD "${URL}" "${_dest}" STATUS _status TLS_VERIFY ON)
list(GET _status 0 _result)
if(_result EQUAL 0)
set(_download_ok TRUE)
break()
endif()

# Avoid reusing a partial download on the next retry.
file(REMOVE "${_dest}")
if(_attempt LESS 3)
message(WARNING "QGC: Download attempt ${_attempt}/3 failed for ${_name}: ${_status}")
endif()
endforeach()
if(NOT _download_ok)
message(FATAL_ERROR "Failed to download ${URL} to ${_dest} after 3 attempts: ${_status}")
endif()
file(CHMOD "${_dest}" FILE_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
endif()
Expand All @@ -38,12 +67,12 @@ endfunction()

message(STATUS "QGC: Downloading AppImage build tools...")

download_tool(LINUXDEPLOY https://github.com/linuxdeploy/linuxdeploy/releases/download/1-alpha-20251107-1/linuxdeploy-${CMAKE_SYSTEM_PROCESSOR}.AppImage)
download_tool(APPIMAGETOOL https://github.com/AppImage/appimagetool/releases/download/1.9.1/appimagetool-${CMAKE_SYSTEM_PROCESSOR}.AppImage)
download_tool(LINUXDEPLOY https://github.com/linuxdeploy/linuxdeploy/releases/download/1-alpha-20251107-1/linuxdeploy-${_qgc_appimage_arch}.AppImage)
download_tool(APPIMAGETOOL https://github.com/AppImage/appimagetool/releases/download/1.9.1/appimagetool-${_qgc_appimage_arch}.AppImage)

# AppImageLint is only available for x86_64
if(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64")
download_tool(APPIMAGELINT https://github.com/TheAssassin/appimagelint/releases/download/continuous/appimagelint-${CMAKE_SYSTEM_PROCESSOR}.AppImage)
if(_qgc_appimage_arch STREQUAL "x86_64")
download_tool(APPIMAGELINT https://github.com/TheAssassin/appimagelint/releases/download/continuous/appimagelint-${_qgc_appimage_arch}.AppImage)
endif()

# ============================================================================
Expand All @@ -52,6 +81,9 @@ endif()

message(STATUS "QGC: Bundling runtime dependencies with linuxdeploy...")

# Hosted CI runners often do not support FUSE mounts for AppImage binaries.
set(ENV{APPIMAGE_EXTRACT_AND_RUN} 1)

execute_process(
COMMAND "${LINUXDEPLOY_PATH}"
--appdir "${APPDIR_PATH}"
Expand All @@ -69,7 +101,7 @@ execute_process(

message(STATUS "QGC: Building AppImage package...")

set(ENV{ARCH} ${CMAKE_SYSTEM_PROCESSOR})
set(ENV{ARCH} ${_qgc_appimage_arch})
set(ENV{VERSION} ${CMAKE_PROJECT_VERSION})

execute_process(
Expand Down
19 changes: 19 additions & 0 deletions cmake/patches/gdal-guard-export-targets.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
diff --git a/gdal.cmake b/gdal.cmake
index b5e5e4f..d8484cd 100644
--- a/gdal.cmake
+++ b/gdal.cmake
@@ -611,9 +611,11 @@ install(
FRAMEWORK DESTINATION "${FRAMEWORK_DESTINATION}")

# Generate targets file for importing directly from GDAL build tree
-export(TARGETS ${GDAL_LIB_TARGET_NAME}
- NAMESPACE GDAL::
- FILE "GDAL-targets.cmake")
+if(NOT CMAKE_SKIP_INSTALL_RULES)
+ export(TARGETS ${GDAL_LIB_TARGET_NAME}
+ NAMESPACE GDAL::
+ FILE "GDAL-targets.cmake")
+endif()

if (NOT GDAL_ENABLE_MACOSX_FRAMEWORK)
# Generate GdalConfig.cmake and GdalConfigVersion.cmake
21 changes: 21 additions & 0 deletions cmake/patches/gdal-guard-hdfs-jvm-target.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
diff --git a/cmake/modules/packages/FindHDFS.cmake b/cmake/modules/packages/FindHDFS.cmake
index 7d33c95..b18e141 100644
--- a/cmake/modules/packages/FindHDFS.cmake
+++ b/cmake/modules/packages/FindHDFS.cmake
@@ -22,10 +22,12 @@ include(FindPackageHandleStandardArgs)

find_package(JNI)
if(JNI_FOUND)
- add_library(HDFS::JVM UNKNOWN IMPORTED)
- set_target_properties(HDFS::JVM PROPERTIES
- IMPORTED_LINK_INTERFACE_LANGUAGES "C"
- IMPORTED_LOCATION "${JAVA_JVM_LIBRARY}")
+ if(NOT TARGET HDFS::JVM)
+ add_library(HDFS::JVM UNKNOWN IMPORTED)
+ set_target_properties(HDFS::JVM PROPERTIES
+ IMPORTED_LINK_INTERFACE_LANGUAGES "C"
+ IMPORTED_LOCATION "${JAVA_JVM_LIBRARY}")
+ endif()
endif()

find_path(HDFS_INCLUDE_DIR NAMES hdfs.h)
12 changes: 12 additions & 0 deletions cmake/patches/proj-guard-uninstall-target.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -522,6 +522,8 @@ if(NOT _is_multi_config_generator)
endif()

configure_file(cmake/uninstall.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/proj_uninstall.cmake @ONLY)
-add_custom_target(uninstall COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/proj_uninstall.cmake)
+if(NOT TARGET uninstall)
+ add_custom_target(uninstall COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/proj_uninstall.cmake)
+endif()

message(STATUS "EMBED_RESOURCE_FILES=${EMBED_RESOURCE_FILES}")
3 changes: 2 additions & 1 deletion deploy/docker/entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ if [[ -n "${ANDROID_SDK_ROOT:-}" ]]; then
else
echo "Building QGroundControl (${BUILD_TYPE})..."
qt-cmake -S /project/source -B /project/build -G Ninja \
-DCMAKE_BUILD_TYPE="${BUILD_TYPE}"
-DCMAKE_BUILD_TYPE="${BUILD_TYPE}" \
-DCMAKE_INSTALL_PREFIX=/project/build/AppDir/usr
cmake --build /project/build --target all --parallel
cmake --install /project/build --config "${BUILD_TYPE}"
fi
Expand Down
10 changes: 5 additions & 5 deletions src/FlightMap/MapItems/QGCMapPolygonVisuals.qml
Original file line number Diff line number Diff line change
Expand Up @@ -207,12 +207,12 @@ Item {

QGCPalette { id: qgcPal }

KMLOrSHPFileDialog {
id: kmlOrSHPLoadDialog
ShapeFileDialog {
id: shapeFileLoadDialog
title: qsTr("Select Polygon File")

onAcceptedForLoad: (file) => {
mapPolygon.loadKMLOrSHPFile(file)
mapPolygon.loadShapeFile(file)
mapFitFunctions.fitMapViewportToMissionItems()
close()
}
Expand Down Expand Up @@ -622,8 +622,8 @@ Item {

QGCButton {
_horizontalPadding: 0
text: qsTr("Load KML/SHP...")
onClicked: kmlOrSHPLoadDialog.openForLoad()
text: qsTr("Load Shape File...")
onClicked: shapeFileLoadDialog.openForLoad()
visible: !mapPolygon.traceMode
}
}
Expand Down
10 changes: 5 additions & 5 deletions src/FlightMap/MapItems/QGCMapPolylineVisuals.qml
Original file line number Diff line number Diff line change
Expand Up @@ -110,12 +110,12 @@ Item {

QGCPalette { id: qgcPal }

KMLOrSHPFileDialog {
id: kmlOrSHPLoadDialog
ShapeFileDialog {
id: shapeFileLoadDialog
title: qsTr("Select Polyline File")

onAcceptedForLoad: (file) => {
mapPolyline.loadKMLOrSHPFile(file)
mapPolyline.loadShapeFile(file)
mapFitFunctions.fitMapViewportToMissionItems()
close()
}
Expand Down Expand Up @@ -347,8 +347,8 @@ Item {

QGCButton {
_horizontalPadding: 0
text: qsTr("Load KML/SHP...")
onClicked: kmlOrSHPLoadDialog.openForLoad()
text: qsTr("Load Shape File...")
onClicked: shapeFileLoadDialog.openForLoad()
visible: !mapPolyline.traceMode
}
}
Expand Down
81 changes: 78 additions & 3 deletions src/MissionManager/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,6 @@ target_sources(${CMAKE_PROJECT_NAME}
GeoFenceController.h
GeoFenceManager.cc
GeoFenceManager.h
KMLPlanDomDocument.cc
KMLPlanDomDocument.h
LandingComplexItem.cc
LandingComplexItem.h
MissionCommandList.cc
Expand All @@ -51,6 +49,73 @@ target_sources(${CMAKE_PROJECT_NAME}
PlanManager.h
PlanMasterController.cc
PlanMasterController.h

# PlanShapes - Core
PlanShapes/GeoFormatPlanImporter.cc
PlanShapes/GeoFormatPlanImporter.h
PlanShapes/PlanDocument.cc
PlanShapes/PlanDocument.h
PlanShapes/PlanExporter.cc
PlanShapes/PlanExporter.h
PlanShapes/PlanImporter.cc
PlanShapes/PlanImporter.h

# PlanShapes - CSV format
PlanShapes/CSV/CsvPlanDocument.cc
PlanShapes/CSV/CsvPlanDocument.h
PlanShapes/CSV/CsvPlanExporter.cc
PlanShapes/CSV/CsvPlanExporter.h
PlanShapes/CSV/CsvPlanImporter.cc
PlanShapes/CSV/CsvPlanImporter.h

# PlanShapes - GeoJSON format
PlanShapes/GeoJSON/GeoJsonPlanDocument.cc
PlanShapes/GeoJSON/GeoJsonPlanDocument.h
PlanShapes/GeoJSON/GeoJsonPlanExporter.cc
PlanShapes/GeoJSON/GeoJsonPlanExporter.h
PlanShapes/GeoJSON/GeoJsonPlanImporter.cc
PlanShapes/GeoJSON/GeoJsonPlanImporter.h

# PlanShapes - GPX format
PlanShapes/GPX/GpxPlanDocument.cc
PlanShapes/GPX/GpxPlanDocument.h
PlanShapes/GPX/GpxPlanExporter.cc
PlanShapes/GPX/GpxPlanExporter.h
PlanShapes/GPX/GpxPlanImporter.cc
PlanShapes/GPX/GpxPlanImporter.h

# PlanShapes - KML format
PlanShapes/KML/KMLPlanDomDocument.cc
PlanShapes/KML/KMLPlanDomDocument.h
PlanShapes/KML/KmlPlanExporter.cc
PlanShapes/KML/KmlPlanExporter.h
PlanShapes/KML/KmlPlanImporter.cc
PlanShapes/KML/KmlPlanImporter.h
PlanShapes/KML/KmzPlanExporter.cc
PlanShapes/KML/KmzPlanExporter.h
PlanShapes/KML/KmzPlanImporter.cc
PlanShapes/KML/KmzPlanImporter.h

# PlanShapes - OpenAir format
PlanShapes/OpenAir/OpenAirPlanImporter.cc
PlanShapes/OpenAir/OpenAirPlanImporter.h

# PlanShapes - SHP format
PlanShapes/SHP/ShpPlanDocument.cc
PlanShapes/SHP/ShpPlanDocument.h
PlanShapes/SHP/ShpPlanExporter.cc
PlanShapes/SHP/ShpPlanExporter.h
PlanShapes/SHP/ShpPlanImporter.cc
PlanShapes/SHP/ShpPlanImporter.h

# PlanShapes - WKT format
PlanShapes/WKT/WktPlanDocument.cc
PlanShapes/WKT/WktPlanDocument.h
PlanShapes/WKT/WktPlanExporter.cc
PlanShapes/WKT/WktPlanExporter.h
PlanShapes/WKT/WktPlanImporter.cc
PlanShapes/WKT/WktPlanImporter.h

RallyPoint.cc
RallyPointController.cc
RallyPointController.h
Expand Down Expand Up @@ -89,7 +154,17 @@ qt_add_resources(${CMAKE_PROJECT_NAME} json_mission_manager
FILES ${JSON_FILES}
)

target_include_directories(${CMAKE_PROJECT_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
target_include_directories(${CMAKE_PROJECT_NAME} PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/PlanShapes
${CMAKE_CURRENT_SOURCE_DIR}/PlanShapes/CSV
${CMAKE_CURRENT_SOURCE_DIR}/PlanShapes/GeoJSON
${CMAKE_CURRENT_SOURCE_DIR}/PlanShapes/GPX
${CMAKE_CURRENT_SOURCE_DIR}/PlanShapes/KML
${CMAKE_CURRENT_SOURCE_DIR}/PlanShapes/OpenAir
${CMAKE_CURRENT_SOURCE_DIR}/PlanShapes/SHP
${CMAKE_CURRENT_SOURCE_DIR}/PlanShapes/WKT
)

# qt_add_qml_module(QGC
# URI QGroundControl.MissionManager
Expand Down
6 changes: 0 additions & 6 deletions src/MissionManager/ComplexMissionItem.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
#include "PlanMasterController.h"
#include "FlightPathSegment.h"
#include "MissionController.h"
#include "KMLPlanDomDocument.h"
#include "SettingsManager.h"

#include <QtCore/QCborMap>
Expand Down Expand Up @@ -101,11 +100,6 @@ QJsonObject ComplexMissionItem::_loadPresetJson(const QString& name)
return QCborValue::fromVariant(settings.value(name)).toMap().toJsonObject();
}

void ComplexMissionItem::addKMLVisuals(KMLPlanDomDocument& /* domDocument */)
{
// Default implementation has no visuals
}

void ComplexMissionItem::_appendFlightPathSegment(FlightPathSegment::SegmentType segmentType, const QGeoCoordinate& coord1, double coord1AMSLAlt, const QGeoCoordinate& coord2, double coord2AMSLAlt)
{
FlightPathSegment* segment = new FlightPathSegment(segmentType, coord1, coord1AMSLAlt, coord2, coord2AMSLAlt, true /* queryTerrainData */, this /* parent */);
Expand Down
3 changes: 0 additions & 3 deletions src/MissionManager/ComplexMissionItem.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@

class PlanMasterController;
class MissionController;
class KMLPlanDomDocument;

class ComplexMissionItem : public VisualMissionItem
{
Expand Down Expand Up @@ -80,8 +79,6 @@ class ComplexMissionItem : public VisualMissionItem
/// Empty string signals no support for presets.
virtual QString presetsSettingsGroup(void) { return QString(); }

virtual void addKMLVisuals(KMLPlanDomDocument& domDocument);

bool presetsSupported (void) { return !presetsSettingsGroup().isEmpty(); }
bool isIncomplete (void) const { return _isIncomplete; }

Expand Down
Loading
Loading