Compare commits

..
Author SHA1 Message Date
berrux-dev d130c55be5 Fix Qt6 resource compilation so LogView icons are embedded at runtime
- QT5_ADD_RESOURCES was a no-op stub under Qt6, silently dropping .qrc
  files: LogView's :/image/* icons were never compiled into the binary.
  Map the stub onto qt6_add_resources() (outfiles-variable form, which
  appends the generated qrc_*.cpp to the source list). LogView is the
  only caller of the stub.
- nglwidgets' Qt6 branch only processed rme_light_style.qrc;
  nglresources.qrc (which provides :icons/16x16/* toolbar/window icons)
  was left as a raw file in the source list and never compiled
  (CMAKE_AUTORCC is off). Process both qrcs.
- LogView never loads libnglwidgets.so at runtime (--as-needed drops it:
  the code uses no nglwidgets symbols), so its :icons/16x16 resources
  were never registered for the app. Embed the 20 icons LogView actually
  uses directly into LogViewResources.qrc with explicit aliases (rcc
  rejects XML comments in .qrc and, without an alias, registers the full
  relative path as the resource name).
2026-11-03 13:31:02 +01:00
berrux-dev 0e2100f383 reset Jenkins file 2026-10-15 20:43:46 +02:00
berrux-dev 26f702b7a4 reset jenkins file 2026-10-15 20:40:29 +02:00
berrux-dev 37bd700564 Fixed make error 2026-10-15 12:21:52 +02:00
berrux-dev 684e05109d Add lcov code coverage to the release pipeline and Jenkins
- new_docker_build.sh: new --run-coverage mode (mutually exclusive with
  --run-jenkins-builder). Instruments the release-scope build with
  -O0 -g --coverage -fPIC -DNDEBUG (RELEASE flag override keeps -DNDEBUG
  and -fPIC so behavior and PIC match the green baseline), runs ctest,
  then collects the lcov report: capture --external -> extract on the
  four release dirs -> remove test sources -> summary -> genhtml, all
  with --ignore-errors mismatch,inconsistent,unused (GCC 15 + lcov 2.4).
  Report lands in --coverage-output-dir (default ./coverage-out):
  html/index.html, coverage.info, coverage_summary.txt.
- Dockerfile image gains lcov via APT_PACKAGES (genhtml ships in the
  same package).
- Jenkinsfile: RunCoverage parameter (default on) + per-OS Coverage
  stage running the driver on the agent and archiving
  coverage/<project>/<os>/**.
- release-16-10-2026.sh: same coverage step, gated by DRYRUN_COVERAGE
  (default ON, mirrors the Jenkins default).
- README: Step 6 (code coverage) and options/env reference entries.
- .gitignore: coverage-out/
2026-10-15 09:00:33 +02:00
berrux-dev 676ae05335 Rewrite the build README without excluded-module sections
Scope is now described only as what the release build contains
(TetraIF, Z/src, Lts/Common, TrainingAreaBase). All steps (image,
compile, tests, DEB packaging, Jenkins) kept and refreshed; the
license note is reduced to 'no license file is required'.
2026-10-14 20:40:05 +02:00
berrux-dev a17b431669 Trim stub header comments and redundant explanations
- Drop the 'Stub file ... BUILD_RTI=OFF / Auto-generated' headers from the
  tab_* and pdm_* stub files (RTI is gone on this branch; the names say it)
- Drop stub comments from MockCoordTrans.h and the coordTransTests placeholders
- Drop the DDS exclusion list comment from Lts/Common/CMakeLists.txt
- Shorten the staging and packages-out comments in new_docker_build.sh
2026-10-14 20:30:09 +02:00
berrux-dev 493893d2e6 Reduce make_rpm_ubuntu26.py line count (925 to 526) without changing behavior
- Merge build_single_deb and build_single_deb_nobuild into one build_deb()
- Add build_nobuild_package() factory for the 4 no-build packages
- Extract run(), prune_dirs() and write_deb_file() helpers
- Drop the unreachable release_scope copy branch (all call sites used the
  full-tree copy; the --release_scope CLI flag is kept)
- Trim pipeline_files to the 8 files that actually exist and are packaged
- Remove unused imports (configparser, getpass, re, datetime, Path, stat),
  unused vars (test_patterns, script_extensions) and a duplicated write block
2026-10-14 20:25:51 +02:00
berrux-dev 8976b5aedb Remove dead CMake configuration from the release validation scope
- Top-level CMakeLists.txt: drop RTI/Connext DDS config and placeholder targets,
  MIGRATE_MODULE guarded-subdir machinery (now unconditional add_subdirectory),
  BUILD_QAV, BUILD_PLUGINS_*, KDReports stub, ArcGIS option and FindRTI placeholder loop
- Lts/CMakeLists.txt: release scope now unconditional (Common + Proxies/TrainingAreaBase),
  codegen/DDS/test/docs blocks removed
- Lts/Common: drop DDS/RTI-gated plugin and utils test blocks
- Lts/Proxies/TrainingAreaBase: remove RTI codegen, svcTabClient/svcTabServer, RTI plugins,
  sTAB; keep stub-only svcTabCommon + tabTelegrams + tabPluginInterface
- TetraIF/PrtCnv: remove out-of-scope TetraTestServer/LastTest subdirs
- Z/src/nglcompression: remove nglcomp_test (pre-existing Qt6 failure, no longer registered)
- Delete 16 unused cmake/ helper modules and the tests/ scaffolding dir
- new_docker_build.sh: drop BUILD_ARCGIS and nglcomp_test from the release build
- README: update ctest baseline to 7/7 and remove license/exception mentions
2026-10-14 18:39:18 +02:00
berrux-dev 6e7b09cf6f Remove include/ entries and LogView files unused by the release-scope build
Audited the release-scope compilation (TetraIF, Z/src, Lts/Common +
TrainingAreaBase, BUILD_RTI=OFF) for every file under include/:

Removed (zero references from release-scope sources or CMake):
- service-stub header dirs (AlarmManagement, AreaEffectSimulation,
  AssetManagement, AudioVideoManagement, Core, ExerciseEventManagement,
  ExerciseManagement, GuezNasat, InfrastructureManagement, Lts,
  LtsProjectionWorkstation, LtsScriptTimeline, LtsSession,
  MarkerManagement, NotificationManagement, OperatorManagement,
  ParticipantManagement, ProjectDataManagement, ReportManagement,
  Services, SituationReplay, TopicEditorBase, Viewer)
- include/grantlee (codegen modules excluded from the release build)
- include/nglapplication (all headers duplicate Z/src/nglapplication)
- include/poppler (Qt5 header; the build includes poppler/qt6 from the
  system package)
- include/rti (142 Connext DDS headers; only consumers are behind
  BUILD_RTI, which is OFF for this branch)
- TetraIF/LogView zsksxd_tetraForLogView{,_guez}.cpp and
  zsksxd_tetraForLogView_guez.x (the build compiles the .x; the guez
  variant is referenced nowhere; LogView loads the .x from the app dir)

Kept (actively included): include/GeographicLib, include/LtsUtilsGuiDds,
include/NGLLogger.

Also drop the now-dangling include_directories for the removed dirs in
the top-level CMakeLists (include/Viewer/SituationMap) and
Lts/CMakeLists.txt (six stub dirs) - otherwise GCC warns
-Wmissing-include-dirs for every compile.

Verified with a full pipeline rebuild (scope-rebuild15): 0 warnings,
ctest baseline unchanged, all 5 DEBs produced.
2026-10-14 16:51:32 +02:00
berrux-dev 11501ff7bb Drop the rti_license.dat requirement from the release scope build
The release validation scope (TetraIF, Z/src, Lts/Common +
TrainingAreaBase) never consumes an RTI license: no CMake file or
build step reads RTI_LICENSE_FILE, and the only RTI Connext DDS
consumers are all behind BUILD_RTI (OFF for this branch, stubs
compiled instead). The license was pure plumbing:

- new_docker_build.sh: remove the require_file validation, the
  bind mount and the in-container RTI_LICENSE_FILE export
- jenkins-ci-rme: remove the RTI_LICENSE_FILE export and the
  Jenkinsfile workspace-layout comment
- README: document that no license file is needed

Verified with a full pipeline rebuild (scope-rebuild12) run while
rti_license.dat was absent: 0 warnings, ctest baseline unchanged,
all 5 DEBs produced, none of them containing the license.
2026-10-14 16:28:03 +02:00
berrux-dev 59f0c025e5 Add a step-by-step build and test README for the release scope
Document the full flow: prebuilt Docker image build, release-scope
compilation (mandatory CMake flags), running the unit tests (ctest
baseline plus direct execution of the test binaries), DEB package
production with the in-tree rpmbuild script, the Jenkins/CI entry
points, the options reference and troubleshooting notes.
2026-10-14 16:28:03 +02:00
berrux-dev cebc456bc1 Add unit tests for the TetraIF modules in a unit-test folder
New TetraIF/unit-test/ directory with one QtTest executable per
TetraIF release-scope module, wired into ctest and the DEB pipeline:

- coprtcnv_unit_test: central and radio telegram header fields,
  payload access, length checks, fragmentation/reassembly roundtrip,
  telegram-id string helpers
- logview_unit_test: IntegerCalculator arithmetic, operator priority,
  parentheses, error codes and variables (compiles the LogView class
  source directly; the class otherwise lives in the LogView
  executable)
- prtcnv_unit_test: PrtCnvMember state and fragmented-telegram
  handling (compiles the class source directly because PrtCnvLib is
  built with hidden visibility)

TetraIF/CMakeLists.txt adds the unit-test subdirectory and
new_docker_build.sh builds and ctest-runs the three new targets.
2026-10-14 16:28:03 +02:00
berrux-dev 2d1b12b5d8 Copy jenkins-ci-rme into the source tree and adapt it to this project
- Jenkinsfile: guez-only release pipeline; the prebuilt build image is
  built from the in-tree Dockerfile (via new_docker_build.sh
  --build-prebuilt-image) instead of a pre-pulled harbor image; the
  builder runs inside the container with the workspace mounted at
  /workspace; the post-publish cleanup stage was dropped so the DEBs
  stay under ${WORKSPACE}/rpms/... (the documented output location)
- jenkins_builder_ubuntu26.sh: uses the in-tree rpmbuild/
  make_rpm_ubuntu26.py instead of the outer-repo copy; same-file guard
  on the packages-out copy (host output dir == make_rpm output dir)
- jenkins_publisher_ubuntu26.sh: uploads rpms/${PROJECT}/${OS_VERSION}/
  directly - make_rpm_ubuntu26.py writes the DEBs there without a TDS
  subfolder
- release-16-10-2026.sh: local driver adapted to the current
  new_docker_build.sh interface (drops the no-longer-existing
  --use-prebuilt-image option, builds the image on demand, outputs to
  ${WORKSPACE}/rpms/${PROJECT}/${OS_VERSION}/)
- make_rpm_ubuntu26.py: stage the new jenkins-ci-rme/ files (Jenkinsfile,
  builder, publisher) into the build-pipeline DEB (release-16-10-2026.sh
  was already listed)

Not copied (superseded): openSUSE builder/publisher, the old Dockerfile
recipes (replaced by the in-tree Dockerfile), Bitbucket notification
(jenkins_notifier.sh is not part of this project)
2026-10-14 16:28:03 +02:00
berrux-dev bf3fecf5c0 Use the Jenkins-style DEB output path and fix the copy to the packages-out mount
- Document --package-output-dir "${WORKSPACE}/rpms/${PROJECT}/${OS_VERSION}/"
  (Jenkins convention) in the usage examples
- The in-container copy step now copies to the real mount point
  /workspace/packages-out instead of ${PACKAGE_OUTPUT_DIR}, which is a host
  path that does not exist inside the container (the copy was a silent
  no-op; packages reached the host directly via make_rpm's
  --output_dir /workspace/rpms/... on the workspace mount)
- Skip the copy when the host output directory is the same directory as
  make_rpm's output dir (stat device:inode guard) - which is exactly the
  case for the Jenkins-style path above, where make_rpm already writes the
  packages in place
2026-10-14 16:28:03 +02:00
torsten 5c012ba228 Adds minimal format changing clang-format file 2026-10-14 13:28:55 +00:00
torsten 5644914fe3 Formats minimally release source files based on former clang-format 2026-10-14 13:28:01 +00:00
torsten b662e4daf9 Reinserts original comments 2026-10-14 12:56:16 +00:00
699 changed files with 12352 additions and 68936 deletions

No files matched your search

@@ -0,0 +1,54 @@
---
BasedOnStyle: LLVM
AccessModifierOffset: -2
AlignTrailingComments: true
AlignAfterOpenBracket: true
AllowAllParametersOfDeclarationOnNextLine: false
AllowShortFunctionsOnASingleLine: Inline
AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: false
AllowShortBlocksOnASingleLine: false
BinPackArguments: false
BinPackParameters: false
BreakBeforeBinaryOperators: false
BreakBeforeBraces: Allman
BreakConstructorInitializers: BeforeComma
BreakInheritanceList: BeforeComma
ColumnLimit: 170
ConstructorInitializerAllOnOneLineOrOnePerLine: false
IncludeCategories:
- Regex: '^".*"$'
Priority: 1
- Regex: '^<.*>$'
Priority: 2
IndentCaseLabels: true
IndentWidth: 2
InsertNewlineAtEOF: true
Language: Cpp
MaxEmptyLinesToKeep: 2
NamespaceIndentation: All
PenaltyBreakBeforeFirstCallParameter: 1000
PenaltyReturnTypeOnItsOwnLine: 1000
PointerAlignment: Right
PointerBindsToType: false
SortIncludes: false
SpaceBeforeParens: ControlStatements
SpacesInAngles: false
SpacesInParentheses: false
Standard: c++20
UseTab: Never
TabWidth: 2
AlignConsecutiveAssignments: false
AlignConsecutiveDeclarations: false
CompactNamespaces: false
DerivePointerAlignment: false
ReflowComments: false
SortUsingDeclarations: false
SpaceAfterCStyleCast: false
SpaceAfterTemplateKeyword: true
SpaceBeforeAssignmentOperators: true
SpaceBeforeInheritanceColon: true
SpaceBeforeRangeBasedForLoopColon: true
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 1
FixNamespaceComments: false
@@ -14,3 +14,4 @@ build/
build2/ build2/
.envrc .envrc
build4 build4
coverage-out/
+3 -349
View File
@@ -40,26 +40,9 @@ MESSAGE(STATUS "LTS Version: ${LTS_VERSION_MAJOR}.${LTS_VERSION_MINOR}.${LTS_VER
# Enable CTest integration for unit tests # Enable CTest integration for unit tests
include(CTest) include(CTest)
# Release scope: subdirectories are added unconditionally (no per-module migration builds)
function(NGL_ADD_SUBDIR_GUARDED subdir) function(NGL_ADD_SUBDIR_GUARDED subdir)
if(MIGRATE_MODULE STREQUAL "")
add_subdirectory(${subdir}) add_subdirectory(${subdir})
else()
# normalize to forward slashes
string(REPLACE "\\" "/" _mig "${MIGRATE_MODULE}")
string(REPLACE "\\" "/" _sub "${subdir}")
# also compare basenames so MIGRATE_MODULE=Lts/DDS matches subdir 'DDS' when called from Lts
get_filename_component(_mig_base "${_mig}" NAME)
get_filename_component(_sub_base "${_sub}" NAME)
# If MIGRATE_MODULE either starts with the subdir, equals it, contains it as a path component,
# or the basename matches, include the subdir. This makes nested paths like
# 'Lts/Proxies/TrainingAreaBase' include both 'Lts' and its child 'Proxies'.
if(_mig MATCHES "^${_sub}(/|$)" OR _sub MATCHES "^${_mig}(/|$)" OR _mig MATCHES ".*/${_sub}(/|$)" OR _sub MATCHES ".*/${_mig}(/|$)" OR _mig_base STREQUAL _sub OR _sub_base STREQUAL _mig)
message(STATUS "Including subdir ${subdir} because MIGRATE_MODULE=${MIGRATE_MODULE}")
add_subdirectory(${subdir})
else()
message(STATUS "Skipping subdir ${subdir} because MIGRATE_MODULE=${MIGRATE_MODULE}")
endif()
endif()
endfunction() endfunction()
SET(LTS_VERSION_DATE "01.01.2018" CACHE STRING "The date when this software was compiled") SET(LTS_VERSION_DATE "01.01.2018" CACHE STRING "The date when this software was compiled")
@@ -95,51 +78,6 @@ if(EXISTS "${CMAKE_SOURCE_DIR}/Lts/Viewer/SituationMap/Symbology")
include_directories(${CMAKE_SOURCE_DIR}/Lts/Viewer/LtsDataView) include_directories(${CMAKE_SOURCE_DIR}/Lts/Viewer/LtsDataView)
endif() endif()
include_directories(${CMAKE_SOURCE_DIR}/Lts/Proxies/TrainingAreaBase) include_directories(${CMAKE_SOURCE_DIR}/Lts/Proxies/TrainingAreaBase)
# Release scope: exclude Services, DDS, and Plugins include paths
IF(NOT RELEASE_BUILD)
include_directories(${CMAKE_BINARY_DIR}/Lts/Services/ProjectDataManagement)
include_directories(${CMAKE_SOURCE_DIR}/Lts/Services)
include_directories(${CMAKE_SOURCE_DIR}/include/ProjectDataManagement)
include_directories(${CMAKE_BINARY_DIR}/Lts/Services/InfrastructureManagement)
include_directories(${CMAKE_SOURCE_DIR}/include/InfrastructureManagement)
include_directories(${CMAKE_BINARY_DIR}/Lts/Plugins/InfrastructureManagement/Shared)
include_directories(${CMAKE_BINARY_DIR}/Lts/Services/AssetManagement)
include_directories(${CMAKE_SOURCE_DIR}/include/AssetManagement)
include_directories(${CMAKE_BINARY_DIR}/Lts/Services/AudioVideoManagement)
include_directories(${CMAKE_SOURCE_DIR}/include/AudioVideoManagement)
include_directories(${CMAKE_BINARY_DIR}/Lts/Services/ExerciseEventManagement)
include_directories(${CMAKE_SOURCE_DIR}/include/ExerciseEventManagement)
include_directories(${CMAKE_BINARY_DIR}/Lts/Services/ExerciseManagement)
include_directories(${CMAKE_SOURCE_DIR}/include/ExerciseManagement)
include_directories(${CMAKE_BINARY_DIR}/Lts/Services/FileManagement)
include_directories(${CMAKE_BINARY_DIR}/Lts/Services/NotificationManagement)
include_directories(${CMAKE_SOURCE_DIR}/include/NotificationManagement)
include_directories(${CMAKE_BINARY_DIR}/Lts/Services/ParticipantManagement)
include_directories(${CMAKE_SOURCE_DIR}/include/ParticipantManagement)
include_directories(${CMAKE_BINARY_DIR}/Lts/Services/ReportManagement)
include_directories(${CMAKE_SOURCE_DIR}/include/ReportManagement)
include_directories(${CMAKE_BINARY_DIR}/Lts/Services/SituationReplay)
include_directories(${CMAKE_SOURCE_DIR}/include/SituationReplay)
# Evaluations' generated evl_db_structs.h includes <evl_enums.hpp> by bare name, and that
# header is consumed from OcBaseDownload as well, so its build dir must be visible tree-wide
# like the services above. There is no include/Evaluations stub tree, so only the build dir
# is added (same shape as FileManagement above, which has no stub tree either).
include_directories(${CMAKE_BINARY_DIR}/Lts/Services/Evaluations)
include_directories(${CMAKE_SOURCE_DIR}/Lts/Proxies/GuezNasat)
include_directories(${CMAKE_SOURCE_DIR}/Lts/DDS)
include_directories(${CMAKE_SOURCE_DIR}/Lts/DDS/QosProfile)
# Generated DDS headers (BUILD_RTI=ON)
include_directories(${CMAKE_BINARY_DIR}/Lts)
# <Core/core.hpp> consumers (LtsCoordinate, AES/CES, HLA proxies) resolve the
# rtiddsgen-generated core.hpp from the DDS build dir (the qt5 include order);
# the OFF-era stub copies in include/Core/ have been removed.
include_directories(${CMAKE_BINARY_DIR}/Lts/DDS)
include_directories(${CMAKE_BINARY_DIR}/Lts/DDS/DDSConnector)
include_directories(${CMAKE_BINARY_DIR}/Lts/Services/Messaging)
include_directories(${CMAKE_SOURCE_DIR}/include/OperatorManagement)
include_directories(${CMAKE_BINARY_DIR}/Lts/Services/OperatorManagement)
include_directories(${CMAKE_SOURCE_DIR}/Lts/Plugins)
ENDIF()
# Release scope: include path for ProjectDataManagement stub headers # Release scope: include path for ProjectDataManagement stub headers
IF(RELEASE_BUILD) IF(RELEASE_BUILD)
include_directories(${CMAKE_SOURCE_DIR}/Lts/Services/ProjectDataManagement/stubs) include_directories(${CMAKE_SOURCE_DIR}/Lts/Services/ProjectDataManagement/stubs)
@@ -154,7 +92,6 @@ include_directories(${CMAKE_BINARY_DIR}/Lts/Common/LtsUtils/LtsUtilsCore)
# only that generated header, so appending it cannot shadow an existing include. # only that generated header, so appending it cannot shadow an existing include.
include_directories(${CMAKE_BINARY_DIR}/Lts/Common/LtsUtils/LtsUtilsSettings) include_directories(${CMAKE_BINARY_DIR}/Lts/Common/LtsUtils/LtsUtilsSettings)
include_directories(${CMAKE_SOURCE_DIR}/Z/src/NGLLogger) include_directories(${CMAKE_SOURCE_DIR}/Z/src/NGLLogger)
include_directories(${CMAKE_SOURCE_DIR}/include/Viewer/SituationMap)
SET(CMAKE_CXX_STANDARD 17) SET(CMAKE_CXX_STANDARD 17)
SET(CMAKE_CXX_STANDARD_REQUIRED ON) SET(CMAKE_CXX_STANDARD_REQUIRED ON)
SET(CMAKE_VISIBILITY_INLINES_HIDDEN ON) SET(CMAKE_VISIBILITY_INLINES_HIDDEN ON)
@@ -171,78 +108,15 @@ IF(CMAKE_VERSION VERSION_GREATER 3.15.9)
ENDIF() ENDIF()
ENDIF() ENDIF()
# Qt6 Migration: Options to disable modules with missing dependencies (WebEngine, XmlPatterns, ArcGIS)
# These can be enabled once the required system dependencies are available in the build environment
OPTION(BUILD_PLUGINS_PLANEDITOR "Build PlanEditor plugin (requires Qt6 WebEngine + ArcGIS SDK)" OFF)
OPTION(BUILD_PLUGINS_ONLINEHELP "Build OnlineHelp plugin (requires Qt6 WebEngine)" OFF)
OPTION(BUILD_PLUGINS_SERVICEMONITOR "Build ServiceMonitor plugin (requires Qt6 WebEngine)" OFF)
OPTION(BUILD_PLUGINS_PARTICIPANT_ORG_CHART "Build ParticipantOrgChart (requires Qt6 WebEngine)" OFF)
OPTION(BUILD_PLUGINS_MSDL "Build MSDL module (requires Qt6 XmlPatterns)" OFF)
OPTION(BUILD_PLUGINS_SAAB "Build Saab module (requires Qt6 XmlPatterns)" OFF)
OPTION(BUILD_RTI "Build RTI Connext DDS dependent modules" OFF)
OPTION(BUILD_VIEWER_ONLY "Build only Viewer module (no RTI required)" OFF)
# Add Lts/ include path globally for QosProfile and other Lts headers # Add Lts/ include path globally for QosProfile and other Lts headers
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/Lts) INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/Lts)
IF(BUILD_RTI)
# Define BUILD_RTI as preprocessor macro for all targets
ADD_COMPILE_DEFINITIONS(BUILD_RTI)
ENDIF()
OPTION(BUILD_ARCGIS "Build ArcGIS SDK dependent modules" ON)
OPTION(BUILD_FILTERMANAGEMENT "Build FilterManagement plugins (temporarily disabled for migration)" OFF)
OPTION(BUILD_CODIFICATION "Build CodificationManagement plugins (requires KDReports)" OFF)
OPTION(BUILD_GRANTLEE "Build CodeGen SQL files using KTextTemplate parser (KF6::TextTemplate)" ON)
# If BUILD_GRANTLEE is OFF but ngl_codegen is needed (for IDL codegen),
# provide it as an imported executable target from pre-built location
# Skip this for RELEASE_BUILD since CodeGen is excluded and ngl_codegen is not needed
IF(NOT BUILD_GRANTLEE AND NOT RELEASE_BUILD)
# ngl_codegen is copied to build/bin/ by run_final_migration.sh
# Create an imported target so MacroCodeGenIdl.cmake can find it
IF(NOT TARGET ngl_codegen)
ADD_EXECUTABLE(ngl_codegen IMPORTED GLOBAL)
SET_TARGET_PROPERTIES(ngl_codegen PROPERTIES
IMPORTED_LOCATION "${CMAKE_BINARY_DIR}/bin/ngl_codegen"
)
MESSAGE(STATUS "Using pre-built ngl_codegen from ${CMAKE_BINARY_DIR}/bin/ngl_codegen")
ENDIF()
ENDIF()
OPTION(BUILD_LTSWEBSOCKET "Build LtsWebSocket module (requires NGLLogger)" ON) OPTION(BUILD_LTSWEBSOCKET "Build LtsWebSocket module (requires NGLLogger)" ON)
IF(WIN32)
SET(EXTERNAL_LIBRARY_DIR "C:/Development/Projekte/SituationMap/ExtFw" CACHE STRING "Library dir with all external dependencies")
LIST(APPEND CMAKE_PREFIX_PATH "${EXTERNAL_LIBRARY_DIR}")
LIST(APPEND CMAKE_PROGRAM_PATH "${EXTERNAL_LIBRARY_DIR}/bin;${EXTERNAL_LIBRARY_DIR}/dev-utils/bin")
ELSE()
# Linux: ArcGIS SDK Pfad konfigurieren (nur wenn BUILD_ARCGIS=ON)
IF(BUILD_ARCGIS)
# Use environment variable ARCGIS_ROOT if set, otherwise default to /workspace/external/... (Docker) or host path
IF(DEFINED ENV{ARCGIS_ROOT})
SET(ARCGIS_SDK_DIR "$ENV{ARCGIS_ROOT}" CACHE STRING "ArcGIS Runtime SDK for Qt directory")
ELSEIF(EXISTS "/workspace/external/ArcGIS/MapsSDK_Qt_300.0.0/ArcGIS_Maps_SDK_Qt_300.0.0/qt300.0.0/sdk")
SET(ARCGIS_SDK_DIR "/workspace/external/ArcGIS/MapsSDK_Qt_300.0.0/ArcGIS_Maps_SDK_Qt_300.0.0/qt300.0.0/sdk" CACHE STRING "ArcGIS Runtime SDK for Qt directory")
ELSE()
SET(ARCGIS_SDK_DIR "/repo/external/ArcGIS/MapsSDK_Qt_300.0.0/ArcGIS_Maps_SDK_Qt_300.0.0/qt300.0.0/sdk" CACHE STRING "ArcGIS Runtime SDK for Qt directory")
ENDIF()
IF(EXISTS "${ARCGIS_SDK_DIR}")
LIST(APPEND CMAKE_PREFIX_PATH "${ARCGIS_SDK_DIR}")
MESSAGE(STATUS "ArcGIS SDK found at: ${ARCGIS_SDK_DIR}")
ELSE()
MESSAGE(WARNING "ArcGIS SDK not found at: ${ARCGIS_SDK_DIR}")
ENDIF()
ENDIF()
ENDIF()
# Set CMAKE_MODULE_PATH early so FIND_PACKAGE can find our custom Find modules # Set CMAKE_MODULE_PATH early so FIND_PACKAGE can find our custom Find modules
SET(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake") SET(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
INCLUDE(FindLibraryWithDebug) INCLUDE(FindLibraryWithDebug)
# Find ArcGIS SDK globally if BUILD_ARCGIS is enabled
# This creates ArcGIS::ArcGIS target for all modules to use
IF(BUILD_ARCGIS)
FIND_PACKAGE(ArcGIS REQUIRED)
ENDIF()
ENABLE_TESTING() ENABLE_TESTING()
INCLUDE(CTest) INCLUDE(CTest)
CONFIGURE_FILE(CTestCustom.ctest ${CMAKE_BINARY_DIR}/CTestCustom.ctest COPYONLY) CONFIGURE_FILE(CTestCustom.ctest ${CMAKE_BINARY_DIR}/CTestCustom.ctest COPYONLY)
@@ -521,17 +395,6 @@ if(NOT TARGET Qt6::WebEngineWidgets)
message(STATUS "Created stub target for Qt6::WebEngineWidgets (library not available)") message(STATUS "Created stub target for Qt6::WebEngineWidgets (library not available)")
endif() endif()
# Stub KDReports::KDReports target if not available (needed by LtsReportDisplay)
# UNKNOWN (not INTERFACE) so FindKDReports.cmake can upgrade it with a real
# IMPORTED_LOCATION; an INTERFACE imported target ignores IMPORTED_LOCATION.
if(NOT TARGET KDReports::KDReports)
add_library(KDReports::KDReports UNKNOWN IMPORTED)
set_target_properties(KDReports::KDReports PROPERTIES
INTERFACE_COMPILE_DEFINITIONS "NO_KDREPORTS"
)
message(STATUS "Created stub target for KDReports::KDReports (library not available)")
endif()
# Stub Qt6::Core5Compat target if not available (needed by textEditorTest) # Stub Qt6::Core5Compat target if not available (needed by textEditorTest)
if(NOT TARGET Qt6::Core5Compat) if(NOT TARGET Qt6::Core5Compat)
add_library(Qt6::Core5Compat INTERFACE IMPORTED) add_library(Qt6::Core5Compat INTERFACE IMPORTED)
@@ -623,140 +486,6 @@ endif()
MESSAGE(STATUS "Qt version is ${Qt6Core_VERSION}, GUI available: ${QT6_GUI_AVAILABLE}") MESSAGE(STATUS "Qt version is ${Qt6Core_VERSION}, GUI available: ${QT6_GUI_AVAILABLE}")
# #
# RTI Connext DDS - manuelle Konfiguration da keine CMake Config Files vorhanden
#
IF(BUILD_RTI)
# Support environment variable override, otherwise use relative path from repo root
IF(DEFINED ENV{DDS_PATH})
SET(RTI_INSTALL_DIR "$ENV{DDS_PATH}" CACHE PATH "RTI Connext DDS installation directory")
ELSE()
# In Docker container: /workspace/external/rti_connext_dds-7.7.0
# On host: ${CMAKE_SOURCE_DIR}/../../../external/rti_connext_dds-7.7.0
IF(EXISTS "/workspace/external/rti_connext_dds-7.7.0")
SET(RTI_INSTALL_DIR "/workspace/external/rti_connext_dds-7.7.0" CACHE PATH "RTI Connext DDS installation directory")
ELSEIF(EXISTS "${CMAKE_SOURCE_DIR}/../../../external/rti_connext_dds-7.7.0")
SET(RTI_INSTALL_DIR "${CMAKE_SOURCE_DIR}/../../../external/rti_connext_dds-7.7.0" CACHE PATH "RTI Connext DDS installation directory")
ELSE()
SET(RTI_INSTALL_DIR "/opt/RTI" CACHE PATH "RTI Connext DDS installation directory")
ENDIF()
ENDIF()
# Also set RTI_DIR for FindRTI.cmake compatibility (used by subdirectories)
SET(RTI_DIR "${RTI_INSTALL_DIR}" CACHE PATH "RTI base path" FORCE)
IF(EXISTS "${RTI_INSTALL_DIR}")
SET(RTI_LIB_DIR "${RTI_INSTALL_DIR}/lib/x64Linux4gcc8.5.0")
SET(RTI_INCLUDE_DIR "${RTI_INSTALL_DIR}/include/ndds/hpp")
# RTI hat vier Include-Pfade:
# - include/ für ndds/... und andere Top-Level Headers (z.B. ndds/ndds_config_common.h)
# - include/ndds/ für osapi/... Headers (z.B. osapi/osapi_platform.h)
# - include/ndds/hpp für C++ Headers (dds/..., rti/...)
# - include/rti für rti/... Headers
SET(RTI_INCLUDE_DIRS
"${RTI_INSTALL_DIR}/include"
"${RTI_INSTALL_DIR}/include/ndds"
"${RTI_INSTALL_DIR}/include/ndds/hpp"
"${RTI_INSTALL_DIR}/include/rti"
)
# RTI Include-Pfade global hinzufügen (auch für Tests die keine RTI Libraries linken)
INCLUDE_DIRECTORIES(${RTI_INCLUDE_DIRS})
# RTI Include-Pfade auch an MOC weitergeben (für Q_OBJECT Header mit RTI Types)
SET(CMAKE_AUTOMOC_INCLUDE_DIRECTORIES ${CMAKE_AUTOMOC_INCLUDE_DIRECTORIES} ${RTI_INCLUDE_DIRS})
# The generated <svc>_topic_type_plugin.h / <svc>_record_replay_plugin.h
# headers use Q_INTERFACES(DDSGeneric::TopicTypePlugin), so moc must see
# the Q_DECLARE_INTERFACE in Lts/DDS/... (resolved through the Lts include
# root). Without this path every <svc>TopicTypePlugin fails with
# "Undefined interface" even though the compiler sees the header.
SET(CMAKE_AUTOMOC_INCLUDE_DIRECTORIES ${CMAKE_AUTOMOC_INCLUDE_DIRECTORIES} ${CMAKE_SOURCE_DIR}/Lts)
# The ElevationMapManager stub header (include/Viewer/SituationMap/ElevationMap/)
# lives apart from its source (src/...), so moc needs its directory explicitly.
# NOTE: this must be set at root scope - subdir-scope appends do not reach
# the AutogenInfo MOC_INCLUDES.
SET(CMAKE_AUTOMOC_INCLUDE_DIRECTORIES ${CMAKE_AUTOMOC_INCLUDE_DIRECTORIES} ${CMAKE_SOURCE_DIR}/include/Viewer/SituationMap/ElevationMap)
# The migrated Projects declare Q_INTERFACES(ProjectPlugin::Plugin) and include
# <PluginInterfaces/project_plugin_interface.h>. That include dir
# (Lts/Common/PluginInterfaces/..) is only a target-level PUBLIC include of
# ProjectPluginInterface and is NOT part of the global include_directories that
# reach the AutogenInfo MOC_INCLUDES, so moc fails with "Undefined interface".
# Add the Lts/Common root explicitly (mirrors the Lts append above) so moc can
# resolve the interface. Must be set at root scope - subdir appends do not
# reach the AutogenInfo MOC_INCLUDES.
SET(CMAKE_AUTOMOC_INCLUDE_DIRECTORIES ${CMAKE_AUTOMOC_INCLUDE_DIRECTORIES} ${CMAKE_SOURCE_DIR}/Lts/Common)
# IMPORTED Targets für RTI Libraries erstellen
# Debug und Release Varianten korrekt konfigurieren
FOREACH(lib nddsc nddscore nddscpp nddscpp2 nddsctesthelpers)
ADD_LIBRARY(RTI::${lib} SHARED IMPORTED)
# Debug Library
IF(EXISTS "${RTI_LIB_DIR}/lib${lib}d.so")
SET_TARGET_PROPERTIES(RTI::${lib} PROPERTIES
IMPORTED_LOCATION_DEBUG "${RTI_LIB_DIR}/lib${lib}d.so"
)
ENDIF()
# Release Library
IF(EXISTS "${RTI_LIB_DIR}/lib${lib}.so")
SET_TARGET_PROPERTIES(RTI::${lib} PROPERTIES
IMPORTED_LOCATION_RELEASE "${RTI_LIB_DIR}/lib${lib}.so"
IMPORTED_LOCATION_RELWITHDEBINFO "${RTI_LIB_DIR}/lib${lib}.so"
IMPORTED_LOCATION_MINSIZEREL "${RTI_LIB_DIR}/lib${lib}.so"
)
ENDIF()
# Include Verzeichnisse für alle Varianten
# RTI_UNIX required for basic types (RTI_INT32, RTI_UINT32, etc.)
# RTI_POSIX_THREADS required for pthread support
SET_TARGET_PROPERTIES(RTI::${lib} PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${RTI_INCLUDE_DIRS}"
INTERFACE_COMPILE_DEFINITIONS "RTI_LINUX;RTI_UNIX;RTI_POSIX_THREADS"
)
ENDFOREACH()
MESSAGE(STATUS "RTI Connext DDS found at: ${RTI_INSTALL_DIR}")
MESSAGE(STATUS "RTI Libraries: ${RTI_LIB_DIR}")
MESSAGE(STATUS "RTI Platform: RTI_LINUX")
ELSE()
MESSAGE(WARNING "RTI Connext DDS not found at: ${RTI_INSTALL_DIR}, BUILD_RTI will fail")
ENDIF()
ENDIF(BUILD_RTI)
# Alias Targets für RTI Libraries (für Abwärtskompatibilität)
# Ermöglicht Verwendung von "ddscore" statt "RTI::nddscore" in CMakeLists.txt Files
# HINWEIS: ddscore, ddsftc, ddsfts, ddsconnector werden von Lts/DDS Modulen als echte Targets erstellt
# Daher hier KEINE ALIAS für diese Targets erstellen um Kollisionen zu vermeiden
IF(BUILD_RTI)
# BUILD_RTI=ON: Targets werden von Lts/DDS/Core/CMakeLists.txt erstellt - hier keine Stubs!
# Alias-Typen werden später erstellt, wenn RTI:: Targets verfügbar sind
IF(TARGET RTI::nddsc)
ADD_LIBRARY(ddsc ALIAS RTI::nddsc)
# ddscore wird von Lts/DDS/Core/CMakeLists.txt als echtes Target erstellt - kein Alias hier!
ADD_LIBRARY(ddscpp2 ALIAS RTI::nddscpp2)
# Optionale Targets nur als ALIAS erstellen wenn verfügbar (RTI 7.x hat nicht alle Legacy-Bibliotheken)
IF(TARGET RTI::nddscpp)
ADD_LIBRARY(ddscpp ALIAS RTI::nddscpp)
ENDIF()
IF(TARGET RTI::nddsctesthelpers)
ADD_LIBRARY(nddsctesthelpers ALIAS RTI::nddsctesthelpers)
ENDIF()
ENDIF()
# HINWEIS: ddsftc, ddsfts, ddsconnector werden von Lts/DDS/FTC Modulen als INTERFACE Targets erstellt
# Hier KEINE ALIAS erstellen um Target-Kollisionen zu vermeiden
ELSE()
# BUILD_RTI=OFF: Leere Interface-Libraries als Platzhalter
ADD_LIBRARY(ddsc INTERFACE)
ADD_LIBRARY(ddscore INTERFACE)
ADD_LIBRARY(ddscpp INTERFACE)
ADD_LIBRARY(ddscpp2 INTERFACE)
ADD_LIBRARY(nddsctesthelpers INTERFACE)
# HINWEIS: ddsftc, ddsfts, ddsconnector werden von Lts/DDS/FTC Modulen als INTERFACE Targets erstellt
# Hier KEINE Platzhalter erstellen um Target-Kollisionen zu vermeiden
ENDIF(BUILD_RTI)
ADD_DEFINITIONS(-DQT_USE_QSTRINGBUILDER) ADD_DEFINITIONS(-DQT_USE_QSTRINGBUILDER)
ADD_DEFINITIONS(-DQT_NO_CAST_TO_ASCII) ADD_DEFINITIONS(-DQT_NO_CAST_TO_ASCII)
ADD_DEFINITIONS(-DQT_NO_CAST_FROM_ASCII) ADD_DEFINITIONS(-DQT_NO_CAST_FROM_ASCII)
@@ -774,25 +503,12 @@ ENDIF()
# Ein paar NGL-spezifische Macros # Ein paar NGL-spezifische Macros
# #
INCLUDE(NGLMacros) INCLUDE(NGLMacros)
# Skip MacroCodeGenIdl for release builds as CodeGen module is excluded
IF(NOT RELEASE_BUILD)
INCLUDE(MacroCodeGenIdl)
ENDIF()
# #
# Projektspezifische Einstellungen? # Projektspezifische Einstellungen?
# #
NGL_INSTALL(SV AAR WS FILES lts-cc.conf DESTINATION . RENAME lts-cc.conf.distrib) NGL_INSTALL(SV AAR WS FILES lts-cc.conf DESTINATION . RENAME lts-cc.conf.distrib)
OPTION(ETS_MODE "Build for ETS (No B-Contamination etc)" OFF)
IF(ETS_MODE)
ADD_DEFINITIONS(-DETS_MODE)
ENDIF()
OPTION(TABLET_MODE "Build for TABLET " OFF)
IF(TABLET_MODE)
ADD_DEFINITIONS(-DTABLET_MODE)
ENDIF()
OPTION(GUEZ_MODE "Build for GUEZ " ON) OPTION(GUEZ_MODE "Build for GUEZ " ON)
IF(GUEZ_MODE) IF(GUEZ_MODE)
ADD_DEFINITIONS(-DGUEZ_MODE) ADD_DEFINITIONS(-DGUEZ_MODE)
@@ -948,74 +664,12 @@ ELSE()
ENDIF() ENDIF()
# # Release scope: always build only TetraIF, Z/src, and Lts/Common
# DDS benoetigt zwingend RTI # (TrainingAreaBase is included via Lts/Proxies when Lts is processed)
#
FIND_PACKAGE(RTI QUIET)
if(NOT RTI_FOUND)
message(WARNING "RTI not found; creating placeholder RTI::* imported targets to allow configure without RTI installation")
set(_rti_libs nddscore nddsc nddscpp2 rtiroutingservice)
foreach(_lib ${_rti_libs})
if(NOT TARGET RTI::${_lib})
add_library(RTI::${_lib} UNKNOWN IMPORTED)
set_property(TARGET RTI::${_lib} PROPERTY INTERFACE_INCLUDE_DIRECTORIES "")
endif()
endforeach()
endif()
# Respect MIGRATE_MODULE: when set to a relative path (e.g. "Lts/Common"), only add
# the top-level subdirectories required to configure/build that module. This allows
# per-module migration builds via -DMIGRATE_MODULE=<path>.
if(NOT DEFINED MIGRATE_MODULE)
set(MIGRATE_MODULE "" CACHE STRING "If set, only add subdirectories covering this module (path relative to repo root)")
endif()
# RELEASE_BUILD: when ON, only build the first release modules (TetraIF, Z, Lts/Common)
# This excludes Lts/Services, Lts/DDS, Lts/Tools, Lts/Application, Lts/Proxies, Lts/Plugins, Lts/Viewer, Lts/Projects
if(NOT DEFINED RELEASE_BUILD)
set(RELEASE_BUILD OFF CACHE BOOL "Build only the first release modules (TetraIF, Z, Lts/Common)")
endif()
# For release builds, disable ArcGIS (not in release scope, requires Qt6Location which is not available)
if(RELEASE_BUILD)
set(BUILD_ARCGIS OFF CACHE BOOL "Build ArcGIS SDK dependent modules" FORCE)
endif()
# Add only guarded subdirectories
if(RELEASE_BUILD)
message(STATUS "RELEASE_BUILD=ON: Building only TetraIF, Z/src, and Lts/Common")
NGL_ADD_SUBDIR_GUARDED(TetraIF) NGL_ADD_SUBDIR_GUARDED(TetraIF)
NGL_ADD_SUBDIR_GUARDED(Z/src) NGL_ADD_SUBDIR_GUARDED(Z/src)
NGL_ADD_SUBDIR_GUARDED(Lts) NGL_ADD_SUBDIR_GUARDED(Lts)
else()
NGL_ADD_SUBDIR_GUARDED(TetraIF)
NGL_ADD_SUBDIR_GUARDED(Z/src)
# Services are included before plugins via Lts/CMakeLists.txt (LTS_SUBDIRS order)
NGL_ADD_SUBDIR_GUARDED(Lts)
endif()
# Add migration tests - skip when MIGRATE_MODULE targets specific Lts modules (tests need full codebase)
# MUST be after Lts configuration so tests can access Lts targets (LtsTimelineClassic, codegen_base, etc.)
if(NOT DEFINED MIGRATE_MODULE OR MIGRATE_MODULE STREQUAL "" OR MIGRATE_MODULE STREQUAL "tests")
ADD_SUBDIRECTORY(tests)
else()
message(STATUS "MIGRATE_MODULE=${MIGRATE_MODULE} - skipping tests (need full codebase)")
endif()
# TrainingAreaBase is included via Lts/Proxies when Lts is processed
# Special-case: when migrating TetraIF, also include ProjectDataManagement so generated headers
# and internal logger target are available in the same build tree for TetraIF dependents.
if(DEFINED MIGRATE_MODULE AND MIGRATE_MODULE STREQUAL "TetraIF")
message(STATUS "Including helper modules for TetraIF migration: Lts/Plugins/ProjectDataManagement")
# Services already included above when BUILD_RTI=ON
add_subdirectory(Lts/Plugins/ProjectDataManagement)
endif()
# at last, to make sure we get all targets in NGL_TS_TARGETS property # at last, to make sure we get all targets in NGL_TS_TARGETS property
NGL_ADD_SUBDIR_GUARDED(translations) NGL_ADD_SUBDIR_GUARDED(translations)
#----------------------------------------------------------------------------------------------------- #-----------------------------------------------------------------------------------------------------
OPTION(BUILD_QAV "Build script for local QAV analysis" OFF)
IF (BUILD_QAV)
ADD_SUBDIRECTORY(qav)
ENDIF()
@@ -15,11 +15,9 @@ else()
message(WARNING "Doxygen config ${CMAKE_SOURCE_DIR}/doxygen/DoxyfileLts.in not found; skipping ADD_DOXYGEN_TARGET(Lts)") message(WARNING "Doxygen config ${CMAKE_SOURCE_DIR}/doxygen/DoxyfileLts.in not found; skipping ADD_DOXYGEN_TARGET(Lts)")
endif() endif()
# Add only existing subdirectories to allow partial checkouts / incremental migration # Release scope: only build Lts/Common and Lts/Proxies/TrainingAreaBase (tabTelegrams library)
if(RELEASE_BUILD)
# For first release: only build Lts/Common and Lts/Proxies/TrainingAreaBase (tabTelegrams library)
# Excludes: Tools, Application, DDS, Services, most of Proxies, Plugins, Viewer, Projects # Excludes: Tools, Application, DDS, Services, most of Proxies, Plugins, Viewer, Projects
message(STATUS "RELEASE_BUILD=ON: Building Lts/Common and Lts/Proxies/TrainingAreaBase") message(STATUS "Building Lts/Common and Lts/Proxies/TrainingAreaBase")
if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/Common") if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/Common")
NGL_ADD_SUBDIR_GUARDED(Common) NGL_ADD_SUBDIR_GUARDED(Common)
else() else()
@@ -31,48 +29,7 @@ if(RELEASE_BUILD)
else() else()
message(STATUS "Skipping missing Lts subdirectory: Proxies/TrainingAreaBase") message(STATUS "Skipping missing Lts subdirectory: Proxies/TrainingAreaBase")
endif() endif()
else()
set(LTS_SUBDIRS Tools Application DDS Common Services Proxies Plugins Viewer Projects)
foreach(dir IN LISTS LTS_SUBDIRS)
if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${dir}")
# Use guarded add so top-level MIGRATE_MODULE can restrict which Lts subdirs are included
NGL_ADD_SUBDIR_GUARDED(${dir})
else()
message(STATUS "Skipping missing Lts subdirectory: ${dir}")
endif()
endforeach() # Export headers included by bare name from module sources (release scope)
endif()
IF (BUILD_TESTING)
if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/Tests")
ADD_SUBDIRECTORY(Tests)
else()
message(STATUS "Skipping missing Tests directory under Lts (BUILD_TESTING is ON)")
endif()
ENDIF()
OPTION(BUILD_DOCS "Build documentation as html files from Lts/Documentation" OFF)
IF (BUILD_DOCS)
ADD_SUBDIRECTORY(Documentation)
ENDIF()
# Ensure codegen macros are available before calling CODEGEN_* helpers
# Skip for release builds as CodeGen module is excluded and not needed
IF(NOT RELEASE_BUILD)
INCLUDE(MacroCodeGenIdl)
ENDIF()
# Add stub headers for non-RTI/non-FilterManagement builds
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../include/AudioVideoManagement/)
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../include/NGLLogger/) INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../include/NGLLogger/)
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../include/LtsSession/)
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../include/TopicEditorBase/)
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../include/OperatorManagement/)
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../include/LtsScriptTimeline/)
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../include/LtsUtilsGuiDds/) INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../include/LtsUtilsGuiDds/)
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../include/Services/PresentationManagement/)
IF(NOT RELEASE_BUILD)
CODEGEN_WRITE_SERVICEFILE_INFO()
ENDIF()
@@ -4,13 +4,6 @@
# $Author$ # $Author$
# #
# RELEASE_BUILD: exclude modules with DDS/RTI dependencies not needed for TetraIF/Z
# DDS-dependent modules: CodeGen, LtsAppManager, LtsBotan, LtsCoordinate, LtsElevation,
# LtsLogin, LtsMultiMonitor, LtsPluginManager, LtsPrinting, LtsProjectionWorkstation,
# LtsScriptTimeline, LtsSession, LtsTimelineClassic, LtsVirtualKeyboard, LtsWidgets,
# PluginInterfaces (TopicReplayInterface, RecordReplayPlugin), TopicEditorBase
if(RELEASE_BUILD)
# Core modules needed for TetraIF and Z # Core modules needed for TetraIF and Z
ADD_SUBDIRECTORY(CommonUnitTestsPlaceholder) ADD_SUBDIRECTORY(CommonUnitTestsPlaceholder)
ADD_SUBDIRECTORY(httq) ADD_SUBDIRECTORY(httq)
@@ -30,33 +23,3 @@ if(RELEASE_BUILD)
# LtsMultiMonitor, LtsPluginManager, LtsPrinting, LtsProjectionWorkstation, # LtsMultiMonitor, LtsPluginManager, LtsPrinting, LtsProjectionWorkstation,
# LtsScriptTimeline, LtsSession, LtsTimelineClassic, LtsVirtualKeyboard, LtsWidgets, # LtsScriptTimeline, LtsSession, LtsTimelineClassic, LtsVirtualKeyboard, LtsWidgets,
# TopicEditorBase # TopicEditorBase
else()
ADD_SUBDIRECTORY(CodeGen)
ADD_SUBDIRECTORY(CommonUnitTestsPlaceholder)
ADD_SUBDIRECTORY(httq)
ADD_SUBDIRECTORY(LtsAppDescriptor)
ADD_SUBDIRECTORY(LtsAppManager)
ADD_SUBDIRECTORY(LtsCommandLineParser)
ADD_SUBDIRECTORY(LtsCoordinate)
ADD_SUBDIRECTORY(LtsCoordTrans)
ADD_SUBDIRECTORY(LtsElevation)
ADD_SUBDIRECTORY(LtsLicence)
ADD_SUBDIRECTORY(LtsLogin)
ADD_SUBDIRECTORY(LtsMultiMonitor)
ADD_SUBDIRECTORY(LtsNotification)
ADD_SUBDIRECTORY(LtsPluginManager)
ADD_SUBDIRECTORY(LtsPrinting)
ADD_SUBDIRECTORY(LtsProjectionWorkstation)
ADD_SUBDIRECTORY(LtsRestClient)
ADD_SUBDIRECTORY(LtsScriptTimeline)
ADD_SUBDIRECTORY(LtsSerialPortQuerry)
ADD_SUBDIRECTORY(LtsSession)
ADD_SUBDIRECTORY(LtsTimeline)
ADD_SUBDIRECTORY(LtsUtils)
ADD_SUBDIRECTORY(LtsVirtualKeyboard)
ADD_SUBDIRECTORY(LtsWebSocket)
ADD_SUBDIRECTORY(LtsWidgets)
ADD_SUBDIRECTORY(PluginInterfaces)
ADD_SUBDIRECTORY(ProjectConfig)
ADD_SUBDIRECTORY(TopicEditorBase)
endif()
@@ -1,11 +1,13 @@
// Stub GTest smoke test for coordTrans
#include <gtest/gtest.h> #include <gtest/gtest.h>
TEST(CoordTransSmokeTest, StubTest) { TEST(CoordTransSmokeTest, StubTest)
{
EXPECT_TRUE(true); EXPECT_TRUE(true);
} }
int main(int argc, char **argv) { int main(int argc, char **argv)
{
::testing::InitGoogleTest(&argc, argv); ::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS(); return RUN_ALL_TESTS();
} }
@@ -1,4 +1,4 @@
// Stub QtTest smoke test for coordTrans
#include <QTest> #include <QTest>
class CoordTransSmokeTest : public QObject class CoordTransSmokeTest : public QObject
@@ -6,9 +6,7 @@ class CoordTransSmokeTest : public QObject
Q_OBJECT Q_OBJECT
private slots: private slots:
void stubTest() { void stubTest() { QVERIFY(true); }
QVERIFY(true);
}
}; };
QTEST_APPLESS_MAIN(CoordTransSmokeTest) QTEST_APPLESS_MAIN(CoordTransSmokeTest)
@@ -1,5 +1,3 @@
// MockCoordTrans.h - Stub mock for CoordTrans functionality
// This is a placeholder to allow builds without full CoordTrans implementation
#ifndef MOCK_COORD_TRANS_H #ifndef MOCK_COORD_TRANS_H
#define MOCK_COORD_TRANS_H #define MOCK_COORD_TRANS_H
@@ -8,9 +6,11 @@
#include <QtCore/QPointF> #include <QtCore/QPointF>
// Minimal stub to satisfy linker requirements // Minimal stub to satisfy linker requirements
namespace LtsCoordTrans { namespace LtsCoordTrans
{
// Placeholder types // Placeholder types
struct UtmCoordinate { struct UtmCoordinate
{
static UtmCoordinate fromMgrs(const QString &) { return UtmCoordinate(); } static UtmCoordinate fromMgrs(const QString &) { return UtmCoordinate(); }
QPointF geographic() const { return QPointF(); } QPointF geographic() const { return QPointF(); }
}; };
@@ -35,8 +35,6 @@ NGL_TARGET_LINK_LIBRARIES(LtsAppDescriptor
NGL_INSTALL_TARGET(LtsAppDescriptor) NGL_INSTALL_TARGET(LtsAppDescriptor)
# LtsAppDescriptorChecker # LtsAppDescriptorChecker
SET(LtsAppDescriptorChecker_SRCS SET(LtsAppDescriptorChecker_SRCS
checker/main.cpp checker/main.cpp
@@ -51,27 +49,6 @@ NGL_TARGET_LINK_LIBRARIES(LtsAppDescriptorChecker
Qt6::Core Qt6::Core
) )
# LtsAppDescriptorEditor => Hat niemand benutzt, wird keiner benutzen, also wird der bis auf Weiteres auch nicht an die neue Syntax angepasst.
#SET(LtsAppDescriptorEditor_SRCS
# lts_app_descriptor_editor.cpp
# lts_app_descriptor_editor.h
#)
#NGL_WRAP_UI(LtsAppDescriptorEditor_SRCS
# lts_app_descriptor_editor.ui
#)
#NGL_ADD_LIBRARY2(WS NO_TRANSLATION LtsAppDescriptorEditor SHARED ${LtsAppDescriptorEditor_SRCS})
#NGL_TARGET_INCLUDE_DIRECTORIES(LtsAppDescriptorEditor
# PUBLIC
# ${CMAKE_CURRENT_SOURCE_DIR}/../
#)
if(QT6_GUI_AVAILABLE) if(QT6_GUI_AVAILABLE)
#NGL_TARGET_LINK_LIBRARIES(LtsAppDescriptorEditor #NGL_TARGET_LINK_LIBRARIES(LtsAppDescriptorEditor
# PUBLIC # PUBLIC
@@ -28,8 +28,7 @@ int main(int argc, char* argv[])
if (!f.open(QFile::ReadOnly)) if (!f.open(QFile::ReadOnly))
{ {
printf("LtsAppDescriptorChecker: cannot open apps.json at %s: %s\n", appsJsonFilePath.toStdString().c_str(), printf("LtsAppDescriptorChecker: cannot open apps.json at %s: %s\n", appsJsonFilePath.toStdString().c_str(), f.errorString().toStdString().c_str());
f.errorString().toStdString().c_str());
return -2; return -2;
} }
@@ -38,12 +37,12 @@ int main(int argc, char* argv[])
QStringList lastErrors; QStringList lastErrors;
QStringList dummy1; QStringList dummy1;
QString dummy2; QString dummy2;
LtsAppDescriptor::AppDescriptionVector adv = LtsAppDescriptor::AppDescriptionVector adv = LtsAppDescriptor::LtsAppDescriptor::getAppDescriptionVector(f.readAll(), lastErrors, dummy1, dummy2);
LtsAppDescriptor::LtsAppDescriptor::getAppDescriptionVector(f.readAll(), lastErrors, dummy1, dummy2);
if (!lastErrors.isEmpty()) if (!lastErrors.isEmpty())
{ {
printf("LtsAppDescriptorChecker: apps.json at %s invalid:\n%s\n", appsJsonFilePath.toStdString().c_str(), printf("LtsAppDescriptorChecker: apps.json at %s invalid:\n%s\n",
appsJsonFilePath.toStdString().c_str(),
lastErrors.join(QStringLiteral("\r\n\r\n")).toStdString().c_str()); lastErrors.join(QStringLiteral("\r\n\r\n")).toStdString().c_str());
return 1; return 1;
} }
@@ -107,8 +106,7 @@ int main(int argc, char* argv[])
{ {
if (!guiPluginIIDs.contains(pi.iid)) if (!guiPluginIIDs.contains(pi.iid))
{ {
printf("LtsAppDescriptorChecker: apps.json at '%s' uses unknown IID '%s'\n", printf("LtsAppDescriptorChecker: apps.json at '%s' uses unknown IID '%s'\n", appsJsonFilePath.toStdString().c_str(), pi.iid.toStdString().c_str());
appsJsonFilePath.toStdString().c_str(), pi.iid.toStdString().c_str());
ok = false; ok = false;
} }
} }
@@ -34,9 +34,13 @@ static void addOptionToPlugin(QVector<PluginInfo>& pluginInfos, const PluginInfo
pluginInfos.append(pi); pluginInfos.append(pi);
} }
static bool addOptionsToPlugin(AppDescription& appDesc, const QString& optionIdentifier, static bool addOptionsToPlugin(AppDescription &appDesc,
const QStringList& ignoredPlugins, const QJsonObject& optionsObject, const QString &optionIdentifier,
const PluginInfo::Flag flag, QStringList& lastErrors, bool atLeastOnePluginNeeded) const QStringList &ignoredPlugins,
const QJsonObject &optionsObject,
const PluginInfo::Flag flag,
QStringList &lastErrors,
bool atLeastOnePluginNeeded)
{ {
bool hasPlugins = false; bool hasPlugins = false;
auto optionsObjectIt = optionsObject.constFind(optionIdentifier); auto optionsObjectIt = optionsObject.constFind(optionIdentifier);
@@ -57,8 +61,7 @@ static bool addOptionsToPlugin(AppDescription& appDesc, const QString& optionIde
if (atLeastOnePluginNeeded && !hasPlugins) if (atLeastOnePluginNeeded && !hasPlugins)
{ {
lastErrors.append(QCoreApplication::tr("No plugins specified for '%1' option for app '%2'") lastErrors.append(QCoreApplication::tr("No plugins specified for '%1' option for app '%2'").arg(optionIdentifier, appDesc.appName));
.arg(optionIdentifier, appDesc.appName));
return false; return false;
} }
@@ -96,7 +99,8 @@ App LtsAppDescriptor::appFromInteger(int i)
return App::Login; return App::Login;
} }
AppDescriptionVector LtsAppDescriptor::getAppDescriptionVector(const QByteArray& jsonDocument, QStringList& lastErrors, AppDescriptionVector LtsAppDescriptor::getAppDescriptionVector(const QByteArray &jsonDocument,
QStringList &lastErrors,
const QStringList &ignoredPlugins, const QStringList &ignoredPlugins,
QString &loginPluginIid) QString &loginPluginIid)
{ {
@@ -129,10 +133,7 @@ AppDescriptionVector LtsAppDescriptor::getAppDescriptionVector(const QByteArray&
} }
} }
lastErrors.append(QCoreApplication::tr("JSON: %1<br>Row: %2, Column: %3") lastErrors.append(QCoreApplication::tr("JSON: %1<br>Row: %2, Column: %3").arg(parseError.errorString()).arg(row + 1).arg(column + 1));
.arg(parseError.errorString())
.arg(row + 1)
.arg(column + 1));
return appDescriptions; return appDescriptions;
} }
@@ -166,9 +167,7 @@ AppDescriptionVector LtsAppDescriptor::getAppDescriptionVector(const QByteArray&
{ {
if (valueActive.type() != QJsonValue::Type::Bool) if (valueActive.type() != QJsonValue::Type::Bool)
{ {
lastErrors.append(QCoreApplication::tr("App '%1': value App.Active is not a bool (%2)") lastErrors.append(QCoreApplication::tr("App '%1': value App.Active is not a bool (%2)").arg(appDesc.appName).arg((int)valueActive.type()));
.arg(appDesc.appName)
.arg((int)valueActive.type()));
return appDescriptions; return appDescriptions;
} }
} }
@@ -177,9 +176,7 @@ AppDescriptionVector LtsAppDescriptor::getAppDescriptionVector(const QByteArray&
const QJsonValue valueVisible = appObject.value(QStringLiteral("Visible")); const QJsonValue valueVisible = appObject.value(QStringLiteral("Visible"));
if (!valueVisible.isUndefined() && valueVisible.type() != QJsonValue::Type::Bool) if (!valueVisible.isUndefined() && valueVisible.type() != QJsonValue::Type::Bool)
{ {
lastErrors.append(QCoreApplication::tr("App '%1': value App.Visible is not a bool (%2)") lastErrors.append(QCoreApplication::tr("App '%1': value App.Visible is not a bool (%2)").arg(appDesc.appName).arg((int)valueVisible.type()));
.arg(appDesc.appName)
.arg((int)valueVisible.type()));
return appDescriptions; return appDescriptions;
} }
appDesc.visible = valueVisible.toBool(true); appDesc.visible = valueVisible.toBool(true);
@@ -190,12 +187,9 @@ AppDescriptionVector LtsAppDescriptor::getAppDescriptionVector(const QByteArray&
const QJsonObject optionsObject(appObject.value(QStringLiteral("Options")).toObject()); const QJsonObject optionsObject(appObject.value(QStringLiteral("Options")).toObject());
addOptionsToPlugin(appDesc, QStringLiteral("Payloads"), ignoredPlugins, optionsObject, addOptionsToPlugin(appDesc, QStringLiteral("Payloads"), ignoredPlugins, optionsObject, PluginInfo::Flag::PAYLOAD, lastErrors, false);
PluginInfo::Flag::PAYLOAD, lastErrors, false); addOptionsToPlugin(appDesc, QStringLiteral("Actions"), ignoredPlugins, optionsObject, PluginInfo::Flag::ACTIONS, lastErrors, true);
addOptionsToPlugin(appDesc, QStringLiteral("Actions"), ignoredPlugins, optionsObject, PluginInfo::Flag::ACTIONS, addOptionsToPlugin(appDesc, QStringLiteral("Main"), ignoredPlugins, optionsObject, PluginInfo::Flag::MAIN, lastErrors, false);
lastErrors, true);
addOptionsToPlugin(appDesc, QStringLiteral("Main"), ignoredPlugins, optionsObject, PluginInfo::Flag::MAIN,
lastErrors, false);
appDescriptions.append(appDesc); appDescriptions.append(appDesc);
} }
@@ -97,8 +97,10 @@ typedef QVector<AppDescription> AppDescriptionVector;
namespace LtsAppDescriptor // TODO: make qobject class singleton - for tr namespace LtsAppDescriptor // TODO: make qobject class singleton - for tr
{ {
LTSAPPDESCRIPTOR_EXPORT App appFromInteger(int i); LTSAPPDESCRIPTOR_EXPORT App appFromInteger(int i);
LTSAPPDESCRIPTOR_EXPORT AppDescriptionVector getAppDescriptionVector(const QByteArray &jsonDocument, QStringList &lastErrors, LTSAPPDESCRIPTOR_EXPORT AppDescriptionVector getAppDescriptionVector(const QByteArray &jsonDocument,
const QStringList &ignoredPlugins, QString &loginPluginIid); QStringList &lastErrors,
const QStringList &ignoredPlugins,
QString &loginPluginIid);
} }
} // namespace LtsAppDescriptor } // namespace LtsAppDescriptor
@@ -13,7 +13,9 @@
#include <QtWidgets/QLineEdit> #include <QtWidgets/QLineEdit>
#include <QtWidgets/QPushButton> #include <QtWidgets/QPushButton>
LtsAppDescriptorEditor::LtsAppDescriptorEditor(QWidget* parent) : QWidget(parent), m_ui(new Ui_LtsAppDescriptionEditor) LtsAppDescriptorEditor::LtsAppDescriptorEditor(QWidget *parent)
: QWidget(parent)
, m_ui(new Ui_LtsAppDescriptionEditor)
{ {
m_ui->setupUi(this); m_ui->setupUi(this);
m_vector = LtsAppDescriptor::AppDescriptionVector(); m_vector = LtsAppDescriptor::AppDescriptionVector();
@@ -53,9 +55,8 @@ LtsAppDescriptorEditor::~LtsAppDescriptorEditor()
void LtsAppDescriptorEditor::getAppDescriptionVector() void LtsAppDescriptorEditor::getAppDescriptionVector()
{ {
m_fileName = QFileDialog::getOpenFileName( m_fileName =
this, tr("Open JSON"), QLatin1Literal("/shd/CTC/TOOLS/TDS/TDS-source/Lts/Projects/Legatus/resources/"), QFileDialog::getOpenFileName(this, tr("Open JSON"), QLatin1Literal("/shd/CTC/TOOLS/TDS/TDS-source/Lts/Projects/Legatus/resources/"), tr("JSON File (*.json)"));
tr("JSON File (*.json)"));
if (m_fileName.isEmpty()) if (m_fileName.isEmpty())
return; return;
@@ -111,8 +112,7 @@ void LtsAppDescriptorEditor::onAppsClicked(const QModelIndex& index)
if (optionalFlag) if (optionalFlag)
strFlags.append(QLatin1String("optional ")); strFlags.append(QLatin1String("optional "));
pluginList << QString(type + QLatin1String(": ") + reqPlugin.iid + QLatin1String(" [ ") + strFlags + pluginList << QString(type + QLatin1String(": ") + reqPlugin.iid + QLatin1String(" [ ") + strFlags + QLatin1String("]"));
QLatin1String("]"));
} }
} }
updatePluginModel(pluginList); updatePluginModel(pluginList);
@@ -189,8 +189,7 @@ void LtsAppDescriptorEditor::pluginTypeChanged()
} }
else else
{ {
QMessageBox msgBox(QMessageBox::Information, tr("Error"), QMessageBox msgBox(QMessageBox::Information, tr("Error"), tr("Plugin Type must either be \"gui\" or \"data\"."));
tr("Plugin Type must either be \"gui\" or \"data\"."));
msgBox.exec(); msgBox.exec();
m_ui->lePluginType->setText(QString()); m_ui->lePluginType->setText(QString());
} }
@@ -215,8 +214,7 @@ void LtsAppDescriptorEditor::onAppAddClicked()
if (appList.contains(m_ui->leAppName->text(), Qt::CaseInsensitive)) if (appList.contains(m_ui->leAppName->text(), Qt::CaseInsensitive))
{ {
QMessageBox msgBox(QMessageBox::Critical, tr("Error"), QMessageBox msgBox(QMessageBox::Critical, tr("Error"), tr("There already exists an app named \"%1\".").arg(m_ui->leAppName->text()));
tr("There already exists an app named \"%1\".").arg(m_ui->leAppName->text()));
msgBox.exec(); msgBox.exec();
return; return;
} }
@@ -254,8 +252,7 @@ void LtsAppDescriptorEditor::onPluginAddClicked()
if (pluginList.contains(m_ui->lePluginName->text(), Qt::CaseInsensitive)) if (pluginList.contains(m_ui->lePluginName->text(), Qt::CaseInsensitive))
{ {
QMessageBox msgBox(QMessageBox::Critical, tr("Error"), QMessageBox msgBox(QMessageBox::Critical, tr("Error"), tr("There already exists an plugin named \"%1\".").arg(m_ui->lePluginName->text()));
tr("There already exists an plugin named \"%1\".").arg(m_ui->lePluginName->text()));
msgBox.exec(); msgBox.exec();
return; return;
} }
@@ -293,8 +290,10 @@ void LtsAppDescriptorEditor::onAppDeleteClicked()
QMessageBox msgBox(tr("Warning"), QMessageBox msgBox(tr("Warning"),
tr("The App \n\"%1\" \nwill be removed. Continue?").arg(m_appIndex.data().toString()), tr("The App \n\"%1\" \nwill be removed. Continue?").arg(m_appIndex.data().toString()),
QMessageBox::Warning, QMessageBox::Yes | QMessageBox::Default, QMessageBox::Warning,
QMessageBox::No | QMessageBox::Escape, QMessageBox::NoButton); QMessageBox::Yes | QMessageBox::Default,
QMessageBox::No | QMessageBox::Escape,
QMessageBox::NoButton);
if (msgBox.exec() == QMessageBox::No) if (msgBox.exec() == QMessageBox::No)
return; return;
@@ -313,8 +312,10 @@ void LtsAppDescriptorEditor::onPluginDeletedClicked()
QMessageBox msgBox(tr("Warning"), QMessageBox msgBox(tr("Warning"),
tr("The Plugin \n\"%1\" \nwill be removed. Continue?").arg(m_pluginIndex.data().toString()), tr("The Plugin \n\"%1\" \nwill be removed. Continue?").arg(m_pluginIndex.data().toString()),
QMessageBox::Warning, QMessageBox::Yes | QMessageBox::Default, QMessageBox::Warning,
QMessageBox::No | QMessageBox::Escape, QMessageBox::NoButton); QMessageBox::Yes | QMessageBox::Default,
QMessageBox::No | QMessageBox::Escape,
QMessageBox::NoButton);
if (msgBox.exec() == QMessageBox::No) if (msgBox.exec() == QMessageBox::No)
return; return;
@@ -354,27 +355,20 @@ void LtsAppDescriptorEditor::onUpdateClicked()
m_vector[m_appIndex.row()].requiredPlugins[m_pluginIndex.row()].iid = m_ui->lePluginName->text(); m_vector[m_appIndex.row()].requiredPlugins[m_pluginIndex.row()].iid = m_ui->lePluginName->text();
if (m_ui->lePluginType->text() == QLatin1String("gui")) if (m_ui->lePluginType->text() == QLatin1String("gui"))
m_vector[m_appIndex.row()].requiredPlugins[m_pluginIndex.row()].type = m_vector[m_appIndex.row()].requiredPlugins[m_pluginIndex.row()].type = LtsAppDescriptor::PluginInfo::PluginType::GUI;
LtsAppDescriptor::PluginInfo::PluginType::GUI;
else if (m_ui->lePluginType->text() == QLatin1String("data")) else if (m_ui->lePluginType->text() == QLatin1String("data"))
m_vector[m_appIndex.row()].requiredPlugins[m_pluginIndex.row()].type = m_vector[m_appIndex.row()].requiredPlugins[m_pluginIndex.row()].type = LtsAppDescriptor::PluginInfo::PluginType::DATA;
LtsAppDescriptor::PluginInfo::PluginType::DATA;
else else
m_vector[m_appIndex.row()].requiredPlugins[m_pluginIndex.row()].type = m_vector[m_appIndex.row()].requiredPlugins[m_pluginIndex.row()].type = LtsAppDescriptor::PluginInfo::PluginType::UNKNOWN;
LtsAppDescriptor::PluginInfo::PluginType::UNKNOWN;
m_vector[m_appIndex.row()].requiredPlugins[m_pluginIndex.row()].flags = m_vector[m_appIndex.row()].requiredPlugins[m_pluginIndex.row()].flags = QFlags<LtsAppDescriptor::PluginInfo::Flag>();
QFlags<LtsAppDescriptor::PluginInfo::Flag>();
if (m_ui->chbActions->isChecked()) if (m_ui->chbActions->isChecked())
m_vector[m_appIndex.row()].requiredPlugins[m_pluginIndex.row()].flags |= m_vector[m_appIndex.row()].requiredPlugins[m_pluginIndex.row()].flags |= LtsAppDescriptor::PluginInfo::Flag::ACTIONS;
LtsAppDescriptor::PluginInfo::Flag::ACTIONS;
if (m_ui->chbMain->isChecked()) if (m_ui->chbMain->isChecked())
m_vector[m_appIndex.row()].requiredPlugins[m_pluginIndex.row()].flags |= m_vector[m_appIndex.row()].requiredPlugins[m_pluginIndex.row()].flags |= LtsAppDescriptor::PluginInfo::Flag::MAIN;
LtsAppDescriptor::PluginInfo::Flag::MAIN;
if (m_ui->chbPayload->isChecked()) if (m_ui->chbPayload->isChecked())
m_vector[m_appIndex.row()].requiredPlugins[m_pluginIndex.row()].flags |= m_vector[m_appIndex.row()].requiredPlugins[m_pluginIndex.row()].flags |= LtsAppDescriptor::PluginInfo::Flag::PAYLOAD;
LtsAppDescriptor::PluginInfo::Flag::PAYLOAD;
onAppsClicked(m_appIndex); onAppsClicked(m_appIndex);
onNewpluginClicked(); onNewpluginClicked();
@@ -454,9 +448,12 @@ void LtsAppDescriptorEditor::checkSave()
{ {
if (m_changed) if (m_changed)
{ {
QMessageBox msgBox(tr("Warning"), tr("The Data has been modified.\nDo you want to save your changes?"), QMessageBox msgBox(tr("Warning"),
QMessageBox::Warning, QMessageBox::Yes | QMessageBox::Default, tr("The Data has been modified.\nDo you want to save your changes?"),
QMessageBox::No | QMessageBox::Escape, QMessageBox::NoButton); QMessageBox::Warning,
QMessageBox::Yes | QMessageBox::Default,
QMessageBox::No | QMessageBox::Escape,
QMessageBox::NoButton);
if (msgBox.exec() == QMessageBox::Yes) if (msgBox.exec() == QMessageBox::Yes)
onSaveAsClicked(); onSaveAsClicked();
@@ -465,9 +462,8 @@ void LtsAppDescriptorEditor::checkSave()
void LtsAppDescriptorEditor::onSaveAsClicked() void LtsAppDescriptorEditor::onSaveAsClicked()
{ {
QString fileName = QFileDialog::getSaveFileName( QString fileName =
this, tr("Save JSON"), QLatin1Literal("/shd/CTC/TOOLS/TDS/TDS-source/Lts/Projects/Legatus/resources/"), QFileDialog::getSaveFileName(this, tr("Save JSON"), QLatin1Literal("/shd/CTC/TOOLS/TDS/TDS-source/Lts/Projects/Legatus/resources/"), tr("JSON File (*.json)"));
tr("JSON File (*.json)"));
if (fileName.isEmpty()) if (fileName.isEmpty())
return; return;
@@ -13,7 +13,8 @@ namespace LtsCommandLineParser
static constexpr int s_maxDomainId = 232; static constexpr int s_maxDomainId = 232;
LtsCommandLineParser::LtsCommandLineParser(ProvideCommandLineParameterOptions opts) LtsCommandLineParser::LtsCommandLineParser(ProvideCommandLineParameterOptions opts)
: QCommandLineParser(), m_enabledOptions(opts) : QCommandLineParser()
, m_enabledOptions(opts)
{ {
if (NGL::isAppInBuildBasePath() || m_enabledOptions.testFlag(CreateDomainIdFromIp)) if (NGL::isAppInBuildBasePath() || m_enabledOptions.testFlag(CreateDomainIdFromIp))
{ {
@@ -45,18 +46,12 @@ LtsCommandLineParser::LtsCommandLineParser(ProvideCommandLineParameterOptions op
if (m_enabledOptions.testFlag(CustomConfigFile)) if (m_enabledOptions.testFlag(CustomConfigFile))
{ {
const QString cf(NGL::findProjectConfigFile()); const QString cf(NGL::findProjectConfigFile());
addOption({{QStringLiteral("i"), QStringLiteral("ini")}, addOption({{QStringLiteral("i"), QStringLiteral("ini")}, QStringLiteral("Default: ") + cf, QStringLiteral("filename"), cf});
QStringLiteral("Default: ") + cf,
QStringLiteral("filename"),
cf});
} }
if (m_enabledOptions.testFlag(TcpConnectionUrl)) if (m_enabledOptions.testFlag(TcpConnectionUrl))
{ {
const QString defaultTcpUrl(QStringLiteral("EXCTDS01:7400")); const QString defaultTcpUrl(QStringLiteral("EXCTDS01:7400"));
addOption({{QStringLiteral("t"), QStringLiteral("tcpurl")}, addOption({{QStringLiteral("t"), QStringLiteral("tcpurl")}, QStringLiteral("Default: ") + defaultTcpUrl, QStringLiteral("hostname:port"), defaultTcpUrl});
QStringLiteral("Default: ") + defaultTcpUrl,
QStringLiteral("hostname:port"),
defaultTcpUrl});
} }
addHelpOption(); addHelpOption();
@@ -13,7 +13,8 @@ namespace LtsCommandLineParser
class LTSCOMMANDLINEPARSER_EXPORT LtsCommandLineParser : public QCommandLineParser class LTSCOMMANDLINEPARSER_EXPORT LtsCommandLineParser : public QCommandLineParser
{ {
public: public:
enum ProvideCommandLineParameterOptions { enum ProvideCommandLineParameterOptions
{
None = 0x0000, None = 0x0000,
CreateDomainIdFromIp = 0x0001, CreateDomainIdFromIp = 0x0001,
DomainId = 0x0002, DomainId = 0x0002,
@@ -23,21 +24,15 @@ class LTSCOMMANDLINEPARSER_EXPORT LtsCommandLineParser : public QCommandLinePars
NoVersion = 0x0020 NoVersion = 0x0020
}; };
explicit LtsCommandLineParser(ProvideCommandLineParameterOptions opts = ProvideCommandLineParameterOptions( explicit LtsCommandLineParser(ProvideCommandLineParameterOptions opts = ProvideCommandLineParameterOptions(CreateDomainIdFromIp | DomainId | ExerciseId |
CreateDomainIdFromIp | DomainId | ExerciseId | CustomConfigFile)); CustomConfigFile));
virtual ~LtsCommandLineParser() = default; virtual ~LtsCommandLineParser() = default;
int domainId() const; int domainId() const;
void setDomainId(int id); void setDomainId(int id);
int exerciseId() const int exerciseId() const { return m_exerciseId; }
{
return m_exerciseId;
}
QString iniFile() const QString iniFile() const { return m_iniFile; }
{
return m_iniFile;
}
bool iniFileSet() const; bool iniFileSet() const;
bool useTcpConnection() const; bool useTcpConnection() const;
@@ -48,10 +43,7 @@ class LTSCOMMANDLINEPARSER_EXPORT LtsCommandLineParser : public QCommandLinePars
bool domainIdProvided() const; bool domainIdProvided() const;
bool exerciseIdProvided() const; bool exerciseIdProvided() const;
void setUnitModuleTestMode(bool onOff) void setUnitModuleTestMode(bool onOff) { m_unitModuleTestMode = onOff; }
{
m_unitModuleTestMode = onOff;
}
protected: protected:
QString m_additionalHelpStr; QString m_additionalHelpStr;
@@ -58,7 +58,17 @@ int main(int argc, char** argv)
part3 = mgrs.substr(5, prec); part3 = mgrs.substr(5, prec);
part4 = mgrs.substr(5 + prec, prec); part4 = mgrs.substr(5 + prec, prec);
} }
fprintf(stdout, "%13.10f, %13.10f = %s %s %s %s (UTM: %d %.2f, %.2f %c)\n", lon, lat, part1.c_str(), part2.c_str(), fprintf(stdout,
part3.c_str(), part4.c_str(), zone, x, y, northp ? 'N' : 'S'); "%13.10f, %13.10f = %s %s %s %s (UTM: %d %.2f, %.2f %c)\n",
lon,
lat,
part1.c_str(),
part2.c_str(),
part3.c_str(),
part4.c_str(),
zone,
x,
y,
northp ? 'N' : 'S');
return 0; return 0;
} }
@@ -72,8 +72,7 @@ QString UtmCoordinate::mgrs(int prec, bool withSpaces) const
ret = QString::fromLatin1(ptr, 3) + QLatin1Char(' ') + QString::fromLatin1(ptr + 3, 2); ret = QString::fromLatin1(ptr, 3) + QLatin1Char(' ') + QString::fromLatin1(ptr + 3, 2);
if (prec > 0) if (prec > 0)
{ {
ret += QLatin1Char(' ') + QString::fromLatin1(ptr + 5, prec) + QLatin1Char(' ') + ret += QLatin1Char(' ') + QString::fromLatin1(ptr + 5, prec) + QLatin1Char(' ') + QString::fromLatin1(ptr + 5 + prec, prec);
QString::fromLatin1(ptr + 5 + prec, prec);
} }
} }
else else
@@ -96,8 +95,7 @@ QPointF UtmCoordinate::geographic(double offsetX, double offsetY) const
} }
catch (const std::exception &e) catch (const std::exception &e)
{ {
fprintf(stderr, "Error while calculating geographic from utm %d, %9.6f, %9.6f: %s\n", zone, x + offsetX, fprintf(stderr, "Error while calculating geographic from utm %d, %9.6f, %9.6f: %s\n", zone, x + offsetX, y + offsetY, e.what());
y + offsetY, e.what());
ret = QPointF(); ret = QPointF();
} }
return ret * deg2rad(); return ret * deg2rad();
@@ -217,8 +215,7 @@ QRectF addMarginToArea(const QRectF& rect_LatLon_radiant, const QSize& marginMet
return res; return res;
} }
QVector<UtmCoordinate> getMgrsSquares(const QRectF& rect, bool setAsDefaultSquares, bool setAsPreferedSquare, QVector<UtmCoordinate> getMgrsSquares(const QRectF &rect, bool setAsDefaultSquares, bool setAsPreferedSquare, bool setAsSquareWithMargin)
bool setAsSquareWithMargin)
{ {
QVector<UtmCoordinate> ret = getMgrsSquaresInternal(rect); QVector<UtmCoordinate> ret = getMgrsSquaresInternal(rect);
@@ -393,25 +390,18 @@ double squareDistance(const QPointF& p1, const QPointF& p2)
std::ostream &operator<<(std::ostream &stream, const UtmCoordinate &coord) std::ostream &operator<<(std::ostream &stream, const UtmCoordinate &coord)
{ {
stream << "UtmCoordinate(" << std::setprecision(8) << coord.x << "#" << std::setprecision(8) << coord.y stream << "UtmCoordinate(" << std::setprecision(8) << coord.x << "#" << std::setprecision(8) << coord.y << " zone=" << coord.zone << ")";
<< " zone=" << coord.zone << ")";
return stream; return stream;
} }
void dumpConversionCounter() void dumpConversionCounter()
{ {
fprintf(stderr, "LtsCoordTrans: s_conversion_counter_MGRS_Forward : - mgrs : %ld\n", fprintf(stderr, "LtsCoordTrans: s_conversion_counter_MGRS_Forward : - mgrs : %ld\n", s_conversion_counter_MGRS_Forward);
s_conversion_counter_MGRS_Forward); fprintf(stderr, "LtsCoordTrans: s_conversion_counter_MGRS_Reverse - fromMgrs : %ld\n", s_conversion_counter_MGRS_Reverse);
fprintf(stderr, "LtsCoordTrans: s_conversion_counter_MGRS_Reverse - fromMgrs : %ld\n", fprintf(stderr, "LtsCoordTrans: s_conversion_counter_WGS84_Forward - lonLatAltToGeocentric : %ld\n", s_conversion_counter_WGS84_Forward);
s_conversion_counter_MGRS_Reverse); fprintf(stderr, "LtsCoordTrans: s_conversion_counter_WGS84_Reverse - geocentric2LonLatAlt : %ld\n", s_conversion_counter_WGS84_Reverse);
fprintf(stderr, "LtsCoordTrans: s_conversion_counter_WGS84_Forward - lonLatAltToGeocentric : %ld\n", fprintf(stderr, "LtsCoordTrans: s_conversion_counter_UTMUPS_Forward - fromGeographic : %ld\n", s_conversion_counter_UTMUPS_Forward);
s_conversion_counter_WGS84_Forward); fprintf(stderr, "LtsCoordTrans: s_conversion_counter_UTMUPS_Reverse - geographic : %ld\n", s_conversion_counter_UTMUPS_Reverse);
fprintf(stderr, "LtsCoordTrans: s_conversion_counter_WGS84_Reverse - geocentric2LonLatAlt : %ld\n",
s_conversion_counter_WGS84_Reverse);
fprintf(stderr, "LtsCoordTrans: s_conversion_counter_UTMUPS_Forward - fromGeographic : %ld\n",
s_conversion_counter_UTMUPS_Forward);
fprintf(stderr, "LtsCoordTrans: s_conversion_counter_UTMUPS_Reverse - geographic : %ld\n",
s_conversion_counter_UTMUPS_Reverse);
} }
long getConversionCounter_MGRS_Forward() long getConversionCounter_MGRS_Forward()
@@ -38,13 +38,16 @@ struct LTSCOORDTRANS_EXPORT UtmCoordinate
UtmCoordinate() = default; UtmCoordinate() = default;
UtmCoordinate(int zone_, double x_, double y_, bool northp_ = true) : zone(zone_), northp(northp_), x(x_), y(y_) {} UtmCoordinate(int zone_, double x_, double y_, bool northp_ = true)
: zone(zone_)
bool isValid() const , northp(northp_)
, x(x_)
, y(y_)
{ {
return zone > 0 && zone <= 60;
} }
bool isValid() const { return zone > 0 && zone <= 60; }
QString mgrs(int prec = 5, bool withSpaces = true) const; QString mgrs(int prec = 5, bool withSpaces = true) const;
QPointF toPoint() const; QPointF toPoint() const;
@@ -68,9 +71,7 @@ LTSCOORDTRANS_EXPORT QPointF geographicFromMgrs(const QString& mgrs);
LTSCOORDTRANS_EXPORT QRectF addMarginToArea(const QRectF &rect_LatLon_radiant, const QSize &marginMeter); LTSCOORDTRANS_EXPORT QRectF addMarginToArea(const QRectF &rect_LatLon_radiant, const QSize &marginMeter);
LTSCOORDTRANS_EXPORT QVector<UtmCoordinate> getMgrsSquares(const QRectF& rect, bool setAsDefaultSquares, LTSCOORDTRANS_EXPORT QVector<UtmCoordinate> getMgrsSquares(const QRectF &rect, bool setAsDefaultSquares, bool setAsPreferedSquare, bool setAsSquareWithMargin = false);
bool setAsPreferedSquare,
bool setAsSquareWithMargin = false);
QVector<UtmCoordinate> getMgrsSquaresInternal(const QRectF &rect); QVector<UtmCoordinate> getMgrsSquaresInternal(const QRectF &rect);
@@ -84,11 +85,9 @@ LTSCOORDTRANS_EXPORT QVector<UtmCoordinate> defaultMgrsSquares();
LTSCOORDTRANS_EXPORT UtmCoordinate preferedMgrsSquare(); LTSCOORDTRANS_EXPORT UtmCoordinate preferedMgrsSquare();
LTSCOORDTRANS_EXPORT bool lonLatAltToGeocentric(double lon, double lat, double altitude, double& xOut, double& yOut, LTSCOORDTRANS_EXPORT bool lonLatAltToGeocentric(double lon, double lat, double altitude, double &xOut, double &yOut, double &zOut);
double& zOut);
LTSCOORDTRANS_EXPORT bool geocentric2LonLatAlt(double x, double y, double z, double& lon, double& lat, LTSCOORDTRANS_EXPORT bool geocentric2LonLatAlt(double x, double y, double z, double &lon, double &lat, double &altitude);
double& altitude);
inline double squareDistance(const UtmCoordinate &p1, const UtmCoordinate &p2) inline double squareDistance(const UtmCoordinate &p1, const UtmCoordinate &p2)
{ {
@@ -153,12 +152,10 @@ class LTSCOORDTRANS_EXPORT UtmCoordinate3D : public LtsCoordTrans::UtmCoordinate
using BaseClass = LtsCoordTrans::UtmCoordinate; using BaseClass = LtsCoordTrans::UtmCoordinate;
public: public:
UtmCoordinate3D() UtmCoordinate3D() { reset(); }
{
reset();
}
explicit UtmCoordinate3D(const LtsCoordTrans::UtmCoordinate& utm2d, double _zValue = std::nan("")) : BaseClass() explicit UtmCoordinate3D(const LtsCoordTrans::UtmCoordinate &utm2d, double _zValue = std::nan(""))
: BaseClass()
{ {
zone = utm2d.zone; zone = utm2d.zone;
northp = utm2d.northp; northp = utm2d.northp;
@@ -177,10 +174,7 @@ class LTSCOORDTRANS_EXPORT UtmCoordinate3D : public LtsCoordTrans::UtmCoordinate
zValue = std::nan(""); zValue = std::nan("");
} }
double z() const double z() const { return zValue; }
{
return zValue;
}
protected: protected:
double zValue{std::nan("")}; double zValue{std::nan("")};
@@ -77,8 +77,7 @@ void coordtrans_test::testRelativeMetricalOffet()
QFETCH(QPoint, offset); QFETCH(QPoint, offset);
QFETCH(QString, correctMgrs); QFETCH(QString, correctMgrs);
const LtsCoordTrans::UtmCoordinate& utmRef = const LtsCoordTrans::UtmCoordinate &utmRef = LtsCoordTrans::UtmCoordinate::fromMgrs(QStringLiteral("32U PD 99990 99990"));
LtsCoordTrans::UtmCoordinate::fromMgrs(QStringLiteral("32U PD 99990 99990"));
qDebug() << "utmRef = " << utmRef.mgrs(); qDebug() << "utmRef = " << utmRef.mgrs();
{ {
@@ -103,8 +102,7 @@ QRectF createArea(const QString& base, int xCenter, int yCenter, int width, int
{ {
QRectF areaRect = QRectF(xCenter - width / 2, yCenter - height / 2, width, height); QRectF areaRect = QRectF(xCenter - width / 2, yCenter - height / 2, width, height);
LtsCoordTrans::UtmCoordinate utmBase( LtsCoordTrans::UtmCoordinate utmBase(LtsCoordTrans::UtmCoordinate::fromGeographic(LtsCoordTrans::geographicFromMgrs(base)));
LtsCoordTrans::UtmCoordinate::fromGeographic(LtsCoordTrans::geographicFromMgrs(base)));
const QPointF topLeft(utmBase.geographic(areaRect.left(), areaRect.top())); const QPointF topLeft(utmBase.geographic(areaRect.left(), areaRect.top()));
const QPointF bottomRight(utmBase.geographic(areaRect.right(), areaRect.bottom())); const QPointF bottomRight(utmBase.geographic(areaRect.right(), areaRect.bottom()));
@@ -120,13 +118,10 @@ void coordtrans_test::testAddMarginToArea()
QRectF area = createArea(QStringLiteral("32U PD 0000000000"), 50000, 10000, 30000, 30000); QRectF area = createArea(QStringLiteral("32U PD 0000000000"), 50000, 10000, 30000, 30000);
QRectF area1Increased = LtsCoordTrans::addMarginToArea(area, QSize(5000, 20000)); QRectF area1Increased = LtsCoordTrans::addMarginToArea(area, QSize(5000, 20000));
qDebug() << "topLeft : " << qSetRealNumberPrecision(15) << area.topLeft() qDebug() << "topLeft : " << qSetRealNumberPrecision(15) << area.topLeft() << " - degree:" << area.topLeft() * LtsCoordTrans::rad2deg();
<< " - degree:" << area.topLeft() * LtsCoordTrans::rad2deg(); qDebug() << "topLeftInc : " << qSetRealNumberPrecision(15) << area1Increased.topLeft() << " - degree:" << area1Increased.topLeft() * LtsCoordTrans::rad2deg();
qDebug() << "topLeftInc : " << qSetRealNumberPrecision(15) << area1Increased.topLeft()
<< " - degree:" << area1Increased.topLeft() * LtsCoordTrans::rad2deg();
qDebug() << "bottomRight : " << qSetRealNumberPrecision(15) << area.bottomRight() qDebug() << "bottomRight : " << qSetRealNumberPrecision(15) << area.bottomRight() << " - degree:" << area.bottomRight() * LtsCoordTrans::rad2deg();
<< " - degree:" << area.bottomRight() * LtsCoordTrans::rad2deg();
qDebug() << "bottomRightInc : " << qSetRealNumberPrecision(15) << area1Increased.bottomRight() qDebug() << "bottomRightInc : " << qSetRealNumberPrecision(15) << area1Increased.bottomRight()
<< " - degree:" << area1Increased.bottomRight() * LtsCoordTrans::rad2deg(); << " - degree:" << area1Increased.bottomRight() * LtsCoordTrans::rad2deg();
@@ -142,13 +137,10 @@ void coordtrans_test::testAddMarginToArea()
QRectF area = createArea(QStringLiteral("32U LA 0000000000"), 100, 100, 5000, 5000); QRectF area = createArea(QStringLiteral("32U LA 0000000000"), 100, 100, 5000, 5000);
QRectF area1Increased = LtsCoordTrans::addMarginToArea(area, QSize(50000, 20000)); QRectF area1Increased = LtsCoordTrans::addMarginToArea(area, QSize(50000, 20000));
qDebug() << "topLeft : " << qSetRealNumberPrecision(15) << area.topLeft() qDebug() << "topLeft : " << qSetRealNumberPrecision(15) << area.topLeft() << " - degree:" << area.topLeft() * LtsCoordTrans::rad2deg();
<< " - degree:" << area.topLeft() * LtsCoordTrans::rad2deg(); qDebug() << "topLeftInc : " << qSetRealNumberPrecision(15) << area1Increased.topLeft() << " - degree:" << area1Increased.topLeft() * LtsCoordTrans::rad2deg();
qDebug() << "topLeftInc : " << qSetRealNumberPrecision(15) << area1Increased.topLeft()
<< " - degree:" << area1Increased.topLeft() * LtsCoordTrans::rad2deg();
qDebug() << "bottomRight : " << qSetRealNumberPrecision(15) << area.bottomRight() qDebug() << "bottomRight : " << qSetRealNumberPrecision(15) << area.bottomRight() << " - degree:" << area.bottomRight() * LtsCoordTrans::rad2deg();
<< " - degree:" << area.bottomRight() * LtsCoordTrans::rad2deg();
qDebug() << "bottomRightInc : " << qSetRealNumberPrecision(15) << area1Increased.bottomRight() qDebug() << "bottomRightInc : " << qSetRealNumberPrecision(15) << area1Increased.bottomRight()
<< " - degree:" << area1Increased.bottomRight() * LtsCoordTrans::rad2deg(); << " - degree:" << area1Increased.bottomRight() * LtsCoordTrans::rad2deg();
@@ -167,8 +159,7 @@ void coordtrans_test::testIncreaseRect()
QString mgrs = LtsCoordTrans::mgrsFromGeographic(lonlat.x(), lonlat.y(), 9); QString mgrs = LtsCoordTrans::mgrsFromGeographic(lonlat.x(), lonlat.y(), 9);
QCOMPARE(mgrs, QStringLiteral("32U MD 745000000 840000000")); QCOMPARE(mgrs, QStringLiteral("32U MD 745000000 840000000"));
const LtsCoordTrans::UtmCoordinate centerPoint = const LtsCoordTrans::UtmCoordinate centerPoint = LtsCoordTrans::UtmCoordinate::fromGeographic(lonlat.x(), lonlat.y());
LtsCoordTrans::UtmCoordinate::fromGeographic(lonlat.x(), lonlat.y());
LtsCoordTrans::UtmCoordinate topLeftUtm; LtsCoordTrans::UtmCoordinate topLeftUtm;
LtsCoordTrans::UtmCoordinate topLeftUtm2; LtsCoordTrans::UtmCoordinate topLeftUtm2;
@@ -178,11 +169,9 @@ void coordtrans_test::testIncreaseRect()
QPointF bottomRightGeo = centerPoint.geographic(3000, -4000); QPointF bottomRightGeo = centerPoint.geographic(3000, -4000);
topLeftUtm = LtsCoordTrans::UtmCoordinate::fromGeographic(topLeftGeo); topLeftUtm = LtsCoordTrans::UtmCoordinate::fromGeographic(topLeftGeo);
const LtsCoordTrans::UtmCoordinate bottomRightUtm = const LtsCoordTrans::UtmCoordinate bottomRightUtm = LtsCoordTrans::UtmCoordinate::fromGeographic(bottomRightGeo);
LtsCoordTrans::UtmCoordinate::fromGeographic(bottomRightGeo);
qDebug() << "topLeftUtm: " << topLeftUtm.x << " - " << qSetRealNumberPrecision(15) << topLeftUtm.y; qDebug() << "topLeftUtm: " << topLeftUtm.x << " - " << qSetRealNumberPrecision(15) << topLeftUtm.y;
qDebug() << "bottomRightUtm: " << bottomRightUtm.x << " - " << qSetRealNumberPrecision(15) qDebug() << "bottomRightUtm: " << bottomRightUtm.x << " - " << qSetRealNumberPrecision(15) << bottomRightUtm.y;
<< bottomRightUtm.y;
} }
{ {
@@ -194,8 +183,7 @@ void coordtrans_test::testIncreaseRect()
bottomRightUtm2.y = centerPoint.y - 4000; bottomRightUtm2.y = centerPoint.y - 4000;
qDebug() << "topLeftUtm2: " << topLeftUtm2.x << " - " << qSetRealNumberPrecision(15) << topLeftUtm2.y; qDebug() << "topLeftUtm2: " << topLeftUtm2.x << " - " << qSetRealNumberPrecision(15) << topLeftUtm2.y;
qDebug() << "bottomRightUtm2: " << bottomRightUtm2.x << " - " << qSetRealNumberPrecision(15) qDebug() << "bottomRightUtm2: " << bottomRightUtm2.x << " - " << qSetRealNumberPrecision(15) << bottomRightUtm2.y;
<< bottomRightUtm2.y;
} }
QVERIFY2(qFuzzyCompare(topLeftUtm.x, topLeftUtm2.x), "testIncreaseRect x failed"); QVERIFY2(qFuzzyCompare(topLeftUtm.x, topLeftUtm2.x), "testIncreaseRect x failed");
@@ -213,8 +201,7 @@ void coordtrans_test::testIncreaseRect2()
QRectF myRectIncreased; QRectF myRectIncreased;
{ {
const LtsCoordTrans::UtmCoordinate centerPoint = const LtsCoordTrans::UtmCoordinate centerPoint = LtsCoordTrans::UtmCoordinate::fromGeographic(lonlat.x(), lonlat.y());
LtsCoordTrans::UtmCoordinate::fromGeographic(lonlat.x(), lonlat.y());
QPointF topLeftGeo = centerPoint.geographic(-3000, 2000); QPointF topLeftGeo = centerPoint.geographic(-3000, 2000);
QPointF bottomRightGeo = centerPoint.geographic(3000, -2000); QPointF bottomRightGeo = centerPoint.geographic(3000, -2000);
@@ -239,10 +226,8 @@ void coordtrans_test::testIncreaseRect2()
qDebug() << "myRectIncreased height: " << myRectIncreased.height(); qDebug() << "myRectIncreased height: " << myRectIncreased.height();
} }
QVERIFY2((int)(myRectIncreased.center().x() * 10000) == (int)(myRect.center().x() * 10000), QVERIFY2((int)(myRectIncreased.center().x() * 10000) == (int)(myRect.center().x() * 10000), "testIncreaseRect2 centerX failed");
"testIncreaseRect2 centerX failed"); QVERIFY2((int)(myRectIncreased.center().y() * 10000) == (int)(myRect.center().y() * 10000), "testIncreaseRect2 centerY failed");
QVERIFY2((int)(myRectIncreased.center().y() * 10000) == (int)(myRect.center().y() * 10000),
"testIncreaseRect2 centerY failed");
QVERIFY2(myRectIncreased.width() > myRect.width(), "testIncreaseRect2 width failed"); QVERIFY2(myRectIncreased.width() > myRect.width(), "testIncreaseRect2 width failed");
QVERIFY2(myRectIncreased.height() > myRect.height(), "testIncreaseRect2 height failed"); QVERIFY2(myRectIncreased.height() > myRect.height(), "testIncreaseRect2 height failed");
@@ -260,50 +245,84 @@ void coordtrans_test::testGeographicFromMgrs()
void coordtrans_test::testMgrsSquares() void coordtrans_test::testMgrsSquares()
{ {
checkArea(QStringLiteral("32U PD 0000000000"), 50000, 10000, 30000, 30000, checkArea(QStringLiteral("32U PD 0000000000"), 50000, 10000, 30000, 30000, {QStringLiteral("32U PC"), QStringLiteral("32U PD")});
{QStringLiteral("32U PC"), QStringLiteral("32U PD")}); checkArea(QStringLiteral("32U MD 0000000000"), 50000, 10000, 30000, 30000, {QStringLiteral("32U MC"), QStringLiteral("32U MD")});
checkArea(QStringLiteral("32U MD 0000000000"), 50000, 10000, 30000, 30000, checkArea(QStringLiteral("32U MD 0000000000"),
{QStringLiteral("32U MC"), QStringLiteral("32U MD")}); 89999,
checkArea(QStringLiteral("32U MD 0000000000"), 89999, 89999, 21000, 21000, 89999,
21000,
21000,
{QStringLiteral("32U MD"), QStringLiteral("32U ME"), QStringLiteral("32U ND"), QStringLiteral("32U NE")}); {QStringLiteral("32U MD"), QStringLiteral("32U ME"), QStringLiteral("32U ND"), QStringLiteral("32U NE")});
checkArea(QStringLiteral("39Q XG 0000000000"), 40000, 35000, 60000, 70000, checkArea(QStringLiteral("39Q XG 0000000000"), 40000, 35000, 60000, 70000, {QStringLiteral("39Q XG"), QStringLiteral("39R XG")});
{QStringLiteral("39Q XG"), QStringLiteral("39R XG")});
checkArea(QStringLiteral("40R CP 0000000000"), 94000, 9000, 7000, 16000, {QStringLiteral("40R CP")}); checkArea(QStringLiteral("40R CP 0000000000"), 94000, 9000, 7000, 16000, {QStringLiteral("40R CP")});
checkArea(QStringLiteral("40R DN 0000000000"), 500, 95500, 12000, 7000, checkArea(QStringLiteral("40R DN 0000000000"), 500, 95500, 12000, 7000, {QStringLiteral("40R CN"), QStringLiteral("40R DN")});
{QStringLiteral("40R CN"), QStringLiteral("40R DN")}); checkArea(QStringLiteral("40R DN 0000000000"),
checkArea(QStringLiteral("40R DN 0000000000"), 500, 96760, 30000, 30000, 500,
96760,
30000,
30000,
{QStringLiteral("40R CN"), QStringLiteral("40R CP"), QStringLiteral("40R DN"), QStringLiteral("40R DP")}); {QStringLiteral("40R CN"), QStringLiteral("40R CP"), QStringLiteral("40R DN"), QStringLiteral("40R DP")});
checkArea(QStringLiteral("40R BM 0000000000"), 59000, 59500, 46000, 40000, checkArea(QStringLiteral("40R BM 0000000000"), 59000, 59500, 46000, 40000, {QStringLiteral("40Q BM"), QStringLiteral("40R BM")});
{QStringLiteral("40Q BM"), QStringLiteral("40R BM")});
checkArea(QStringLiteral("32U LA 0000000000"), 10000, 10000, 5000, 5000, checkArea(QStringLiteral("32U LA 0000000000"),
10000,
10000,
5000,
5000,
{ {
QStringLiteral("32U LA"), QStringLiteral("32U LA"),
}); });
checkArea(QStringLiteral("32U LA 0000000000"), 100, 100, 60000, 60000, checkArea(QStringLiteral("32U LA 0000000000"),
{QStringLiteral("31U GQ"), QStringLiteral("31U GR"), QStringLiteral("32U KA"), QStringLiteral("32U KV"), 100,
QStringLiteral("32U LA"), QStringLiteral("32U LV")}); 100,
60000,
60000,
{QStringLiteral("31U GQ"), QStringLiteral("31U GR"), QStringLiteral("32U KA"), QStringLiteral("32U KV"), QStringLiteral("32U LA"), QStringLiteral("32U LV")});
checkArea(QStringLiteral("32U LA 0000000000"), 100, 100, 150000, 150000, checkArea(QStringLiteral("32U LA 0000000000"),
{QStringLiteral("31U FQ"), QStringLiteral("31U FR"), QStringLiteral("31U GQ"), QStringLiteral("31U GR"), 100,
QStringLiteral("32U KA"), QStringLiteral("32U KV"), QStringLiteral("32U LA"), QStringLiteral("32U LV")}); 100,
150000,
150000,
{QStringLiteral("31U FQ"),
QStringLiteral("31U FR"),
QStringLiteral("31U GQ"),
QStringLiteral("31U GR"),
QStringLiteral("32U KA"),
QStringLiteral("32U KV"),
QStringLiteral("32U LA"),
QStringLiteral("32U LV")});
checkArea(QStringLiteral("32U LA 0000000000"), 100, 100, 200000, 200000, checkArea(QStringLiteral("32U LA 0000000000"),
{QStringLiteral("31U FP"), QStringLiteral("31U FQ"), QStringLiteral("31U FR"), QStringLiteral("31U GP"), 100,
QStringLiteral("31U GQ"), QStringLiteral("31U GR"), QStringLiteral("31U GS"), QStringLiteral("32U KA"), 100,
QStringLiteral("32U KB"), QStringLiteral("32U KV"), QStringLiteral("32U LA"), QStringLiteral("32U LB"), 200000,
QStringLiteral("32U LV"), QStringLiteral("32U MA"), QStringLiteral("32U MB"), QStringLiteral("32U MV")}); 200000,
{QStringLiteral("31U FP"),
QStringLiteral("31U FQ"),
QStringLiteral("31U FR"),
QStringLiteral("31U GP"),
QStringLiteral("31U GQ"),
QStringLiteral("31U GR"),
QStringLiteral("31U GS"),
QStringLiteral("32U KA"),
QStringLiteral("32U KB"),
QStringLiteral("32U KV"),
QStringLiteral("32U LA"),
QStringLiteral("32U LB"),
QStringLiteral("32U LV"),
QStringLiteral("32U MA"),
QStringLiteral("32U MB"),
QStringLiteral("32U MV")});
} }
QVector<LtsCoordTrans::UtmCoordinate> checkAreaGetMgrsSquares(const QString& base, int xCenter, int yCenter, int width, QVector<LtsCoordTrans::UtmCoordinate> checkAreaGetMgrsSquares(const QString &base, int xCenter, int yCenter, int width, int height)
int height)
{ {
QRectF areaRect = QRectF(xCenter - width / 2, yCenter - height / 2, width, height); QRectF areaRect = QRectF(xCenter - width / 2, yCenter - height / 2, width, height);
LtsCoordTrans::UtmCoordinate utmBase( LtsCoordTrans::UtmCoordinate utmBase(LtsCoordTrans::UtmCoordinate::fromGeographic(LtsCoordTrans::geographicFromMgrs(base)));
LtsCoordTrans::UtmCoordinate::fromGeographic(LtsCoordTrans::geographicFromMgrs(base)));
const QPointF topLeft(utmBase.geographic(areaRect.left(), areaRect.top())); const QPointF topLeft(utmBase.geographic(areaRect.left(), areaRect.top()));
const QPointF bottomRight(utmBase.geographic(areaRect.right(), areaRect.bottom())); const QPointF bottomRight(utmBase.geographic(areaRect.right(), areaRect.bottom()));
@@ -323,20 +342,17 @@ void coordtrans_test::testMgrsSquaresWithSurrounding()
int initialSize = 5000; int initialSize = 5000;
QVector<LtsCoordTrans::UtmCoordinate> squares1 = QVector<LtsCoordTrans::UtmCoordinate> squares1 = checkAreaGetMgrsSquares(QStringLiteral("32U NC 0000000000"), 50000, 50000, initialSize, initialSize);
checkAreaGetMgrsSquares(QStringLiteral("32U NC 0000000000"), 50000, 50000, initialSize, initialSize);
QVERIFY2(squares1.size() == 1, "checkAreaGetMgrsSquares failed"); QVERIFY2(squares1.size() == 1, "checkAreaGetMgrsSquares failed");
int biggerSize = initialSize + (1 * 110000); int biggerSize = initialSize + (1 * 110000);
QVector<LtsCoordTrans::UtmCoordinate> squares9 = QVector<LtsCoordTrans::UtmCoordinate> squares9 = checkAreaGetMgrsSquares(QStringLiteral("32U NC 0000000000"), 50000, 50000, biggerSize, biggerSize);
checkAreaGetMgrsSquares(QStringLiteral("32U NC 0000000000"), 50000, 50000, biggerSize, biggerSize);
QVERIFY2(squares9.size() == 9, "checkAreaGetMgrsSquares biggerSize failed"); QVERIFY2(squares9.size() == 9, "checkAreaGetMgrsSquares biggerSize failed");
int muchBiggerSize = initialSize + (3 * 110000); int muchBiggerSize = initialSize + (3 * 110000);
QVector<LtsCoordTrans::UtmCoordinate> square33 = QVector<LtsCoordTrans::UtmCoordinate> square33 = checkAreaGetMgrsSquares(QStringLiteral("32U NC 0000000000"), 50000, 50000, muchBiggerSize, muchBiggerSize);
checkAreaGetMgrsSquares(QStringLiteral("32U NC 0000000000"), 50000, 50000, muchBiggerSize, muchBiggerSize);
QVERIFY2(square33.size() == 33, "checkAreaGetMgrsSquares muchBiggerSize failed"); QVERIFY2(square33.size() == 33, "checkAreaGetMgrsSquares muchBiggerSize failed");
@@ -376,13 +392,11 @@ void coordtrans_test::testMgrsSquaresWithSurrounding()
} }
} }
void coordtrans_test::checkArea(const QString& base, int xCenter, int yCenter, int width, int height, void coordtrans_test::checkArea(const QString &base, int xCenter, int yCenter, int width, int height, const QStringList &coords)
const QStringList& coords)
{ {
qDebug() << "checkArea : base: " << base; qDebug() << "checkArea : base: " << base;
QRectF areaRect = QRectF(xCenter - width / 2, yCenter - height / 2, width, height); QRectF areaRect = QRectF(xCenter - width / 2, yCenter - height / 2, width, height);
LtsCoordTrans::UtmCoordinate utmBase( LtsCoordTrans::UtmCoordinate utmBase(LtsCoordTrans::UtmCoordinate::fromGeographic(LtsCoordTrans::geographicFromMgrs(base)));
LtsCoordTrans::UtmCoordinate::fromGeographic(LtsCoordTrans::geographicFromMgrs(base)));
const QPointF topLeft(utmBase.geographic(areaRect.left(), areaRect.top())); const QPointF topLeft(utmBase.geographic(areaRect.left(), areaRect.top()));
const QPointF bottomRight(utmBase.geographic(areaRect.right(), areaRect.bottom())); const QPointF bottomRight(utmBase.geographic(areaRect.right(), areaRect.bottom()));
qDebug() << "TopLeft: " << topLeft * LtsCoordTrans::rad2deg(); qDebug() << "TopLeft: " << topLeft * LtsCoordTrans::rad2deg();
@@ -10,7 +10,9 @@
namespace LtsCoordWidget namespace LtsCoordWidget
{ {
LtsCoordWidget::LtsCoordWidget(DisplayType dt, QWidget* parent) : QWidget(parent), m_displayType(dt) LtsCoordWidget::LtsCoordWidget(DisplayType dt, QWidget *parent)
: QWidget(parent)
, m_displayType(dt)
{ {
setFocusPolicy(Qt::StrongFocus); setFocusPolicy(Qt::StrongFocus);
rebuildUi(); rebuildUi();
@@ -149,12 +151,9 @@ void LtsCoordWidget::rebuildUi()
m_inputWidgetHandler->setSquaresEditable(m_bMgrsSquareEditable); m_inputWidgetHandler->setSquaresEditable(m_bMgrsSquareEditable);
m_inputWidgetHandler->resetButton()->setVisible(m_bWithResetButton); m_inputWidgetHandler->resetButton()->setVisible(m_bWithResetButton);
connect(m_inputWidgetHandler->resetButton(), &QToolButton::clicked, this, connect(m_inputWidgetHandler->resetButton(), &QToolButton::clicked, this, &LtsCoordWidget::onResetToDefaultCoordinate);
&LtsCoordWidget::onResetToDefaultCoordinate); connect(m_inputWidgetHandler, &LtsCoordInputWidgetHandler::coordinateChanged, this, &LtsCoordWidget::coordinateChanged);
connect(m_inputWidgetHandler, &LtsCoordInputWidgetHandler::coordinateChanged, this, connect(m_inputWidgetHandler, &LtsCoordInputWidgetHandler::invalidCoordinate, this, &LtsCoordWidget::invalidCoordinate);
&LtsCoordWidget::coordinateChanged);
connect(m_inputWidgetHandler, &LtsCoordInputWidgetHandler::invalidCoordinate, this,
&LtsCoordWidget::invalidCoordinate);
if (!m_defaultCoordinate.isNull()) if (!m_defaultCoordinate.isNull())
m_inputWidgetHandler->setCoordinate(m_defaultCoordinate); m_inputWidgetHandler->setCoordinate(m_defaultCoordinate);
} }
@@ -16,14 +16,24 @@ class LTSCOORDWIDGET_EXPORT LtsCoordWidget : public QWidget
{ {
Q_OBJECT Q_OBJECT
public: public:
enum class DisplayType { MGRS5, MGRS7, UTM, WGS84, MGRS = DisplayType::MGRS5 }; enum class DisplayType
{
MGRS5,
MGRS7,
UTM,
WGS84,
MGRS = DisplayType::MGRS5
};
Q_ENUM(DisplayType) Q_ENUM(DisplayType)
Q_PROPERTY(DisplayType displayType READ displayType WRITE setDisplayType) Q_PROPERTY(DisplayType displayType READ displayType WRITE setDisplayType)
Q_PROPERTY(bool withResetButton READ withResetButton WRITE setWithResetButton) Q_PROPERTY(bool withResetButton READ withResetButton WRITE setWithResetButton)
Q_PROPERTY(bool showToolTip READ showToolTip WRITE setShowToolTip) Q_PROPERTY(bool showToolTip READ showToolTip WRITE setShowToolTip)
Q_PROPERTY(bool mgrsSquareEditable READ mgrsSquareEditable WRITE setMgrsSquareEditable) Q_PROPERTY(bool mgrsSquareEditable READ mgrsSquareEditable WRITE setMgrsSquareEditable)
explicit LtsCoordWidget(QWidget* parent = nullptr) : LtsCoordWidget(LtsCoordWidget::DisplayType::MGRS, parent) {} explicit LtsCoordWidget(QWidget *parent = nullptr)
: LtsCoordWidget(LtsCoordWidget::DisplayType::MGRS, parent)
{
}
explicit LtsCoordWidget(DisplayType dt, QWidget *parent = nullptr); explicit LtsCoordWidget(DisplayType dt, QWidget *parent = nullptr);
@@ -19,7 +19,9 @@ void LtsCoordInputWidgetHandler::onCoordinateDataChanged()
} }
MgrsEdit::MgrsEdit(int precision, QWidget *widget) MgrsEdit::MgrsEdit(int precision, QWidget *widget)
: LtsCoordInputWidgetHandler(widget), m_precision(precision), m_ui(new Ui::Mgrs) : LtsCoordInputWidgetHandler(widget)
, m_precision(precision)
, m_ui(new Ui::Mgrs)
{ {
m_ui->setupUi(widget); m_ui->setupUi(widget);
@@ -32,8 +34,7 @@ MgrsEdit::MgrsEdit(int precision, QWidget* widget)
m_ui->leNorth->setValidator(new QIntValidator(0, upperLimit, m_ui->leNorth)); m_ui->leNorth->setValidator(new QIntValidator(0, upperLimit, m_ui->leNorth));
setDefaultMgrsSquares(); setDefaultMgrsSquares();
connect(m_ui->cbxZone, QOverload<int>::of(&QComboBox::currentIndexChanged), this, connect(m_ui->cbxZone, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &MgrsEdit::onCoordinateDataChanged);
&MgrsEdit::onCoordinateDataChanged);
connect(m_ui->leEast, &QLineEdit::editingFinished, this, &MgrsEdit::onCoordinateDataChanged); connect(m_ui->leEast, &QLineEdit::editingFinished, this, &MgrsEdit::onCoordinateDataChanged);
connect(m_ui->leNorth, &QLineEdit::editingFinished, this, &MgrsEdit::onCoordinateDataChanged); connect(m_ui->leNorth, &QLineEdit::editingFinished, this, &MgrsEdit::onCoordinateDataChanged);
} }
@@ -206,7 +207,9 @@ void MgrsEdit::setMgrsSquares(const QVector<LtsCoordTrans::UtmCoordinate>& geoCo
m_ui->cbxZone->addItems(sl); m_ui->cbxZone->addItems(sl);
} }
Wgs84Edit::Wgs84Edit(QWidget* widget) : LtsCoordInputWidgetHandler(widget), m_ui(new Ui::Wgs84) Wgs84Edit::Wgs84Edit(QWidget *widget)
: LtsCoordInputWidgetHandler(widget)
, m_ui(new Ui::Wgs84)
{ {
m_ui->setupUi(widget); m_ui->setupUi(widget);
@@ -17,7 +17,10 @@ class LtsCoordInputWidgetHandler : public QObject
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit LtsCoordInputWidgetHandler(QObject* parent) : QObject(parent) {} explicit LtsCoordInputWidgetHandler(QObject *parent)
: QObject(parent)
{
}
virtual bool isValid() = 0; virtual bool isValid() = 0;
virtual void setCoordinate(const QPointF &geoCoord) = 0; virtual void setCoordinate(const QPointF &geoCoord) = 0;
@@ -77,20 +80,11 @@ class Wgs84Edit final : public LtsCoordInputWidgetHandler
void cleanup() override; void cleanup() override;
void clear() override; void clear() override;
void setSquaresEditable(bool bEditable) override void setSquaresEditable(bool bEditable) override { Q_UNUSED(bEditable); }
{
Q_UNUSED(bEditable);
}
void setWithSurroundingSquare(bool bEnabled) override void setWithSurroundingSquare(bool bEnabled) override { Q_UNUSED(bEnabled); }
{
Q_UNUSED(bEnabled);
}
void setMgrsSquares(const QVector<LtsCoordTrans::UtmCoordinate>& geoCoords) override void setMgrsSquares(const QVector<LtsCoordTrans::UtmCoordinate> &geoCoords) override { Q_UNUSED(geoCoords); }
{
Q_UNUSED(geoCoords);
}
private: private:
Ui::Wgs84 *m_ui; Ui::Wgs84 *m_ui;
@@ -12,10 +12,8 @@
static void updateLabel(const QPointF &coord, QLabel *lbl, int prec) static void updateLabel(const QPointF &coord, QLabel *lbl, int prec)
{ {
QString mgrs = LtsCoordTrans::mgrsFromGeographic(coord.x(), coord.y(), prec); QString mgrs = LtsCoordTrans::mgrsFromGeographic(coord.x(), coord.y(), prec);
QString str = QStringLiteral("mgrs: %1, lon: %2, lat: %3") QString str =
.arg(mgrs) QStringLiteral("mgrs: %1, lon: %2, lat: %3").arg(mgrs).arg(coord.x() * LtsCoordTrans::rad2deg(), 0, 'f', 10).arg(coord.y() * LtsCoordTrans::rad2deg(), 0, 'f', 10);
.arg(coord.x() * LtsCoordTrans::rad2deg(), 0, 'f', 10)
.arg(coord.y() * LtsCoordTrans::rad2deg(), 0, 'f', 10);
lbl->setText(str); lbl->setText(str);
} }
@@ -33,50 +31,46 @@ int main(int argc, char** argv)
const QPointF defCoord(QPointF(53.0, 8.0) * LtsCoordTrans::deg2rad()); const QPointF defCoord(QPointF(53.0, 8.0) * LtsCoordTrans::deg2rad());
LtsCoordWidget::LtsCoordWidget* wMgrs5( LtsCoordWidget::LtsCoordWidget *wMgrs5(new LtsCoordWidget::LtsCoordWidget(LtsCoordWidget::LtsCoordWidget::DisplayType::MGRS, dialog));
new LtsCoordWidget::LtsCoordWidget(LtsCoordWidget::LtsCoordWidget::DisplayType::MGRS, dialog));
wMgrs5->setWithResetButton(true); wMgrs5->setWithResetButton(true);
wMgrs5->setCoordinate(defCoord, true); wMgrs5->setCoordinate(defCoord, true);
lay->addWidget(wMgrs5); lay->addWidget(wMgrs5);
QLabel *lbl5(new QLabel(dialog)); QLabel *lbl5(new QLabel(dialog));
lay->addWidget(lbl5); lay->addWidget(lbl5);
QObject::connect(wMgrs5, &LtsCoordWidget::LtsCoordWidget::coordinateChanged, lbl5, QObject::connect(wMgrs5, &LtsCoordWidget::LtsCoordWidget::coordinateChanged, lbl5, [lbl5](const QPointF &coord) { updateLabel(coord, lbl5, 5); });
[lbl5](const QPointF& coord) { updateLabel(coord, lbl5, 5); });
LtsCoordWidget::LtsCoordWidget* wMgrs7( LtsCoordWidget::LtsCoordWidget *wMgrs7(new LtsCoordWidget::LtsCoordWidget(LtsCoordWidget::LtsCoordWidget::DisplayType::MGRS7, dialog));
new LtsCoordWidget::LtsCoordWidget(LtsCoordWidget::LtsCoordWidget::DisplayType::MGRS7, dialog));
wMgrs7->setWithResetButton(true); wMgrs7->setWithResetButton(true);
wMgrs7->setCoordinate(defCoord, true); wMgrs7->setCoordinate(defCoord, true);
lay->addWidget(wMgrs7); lay->addWidget(wMgrs7);
QLabel *lbl7(new QLabel(dialog)); QLabel *lbl7(new QLabel(dialog));
lay->addWidget(lbl7); lay->addWidget(lbl7);
QObject::connect(wMgrs7, &LtsCoordWidget::LtsCoordWidget::coordinateChanged, wMgrs7, QObject::connect(wMgrs7, &LtsCoordWidget::LtsCoordWidget::coordinateChanged, wMgrs7, [lbl7](const QPointF &coord) { updateLabel(coord, lbl7, 7); });
[lbl7](const QPointF& coord) { updateLabel(coord, lbl7, 7); });
LtsCoordWidget::LtsCoordWidget* w84( LtsCoordWidget::LtsCoordWidget *w84(new LtsCoordWidget::LtsCoordWidget(LtsCoordWidget::LtsCoordWidget::DisplayType::WGS84, dialog));
new LtsCoordWidget::LtsCoordWidget(LtsCoordWidget::LtsCoordWidget::DisplayType::WGS84, dialog));
w84->setWithResetButton(true); w84->setWithResetButton(true);
w84->setCoordinate(defCoord, true); w84->setCoordinate(defCoord, true);
lay->addWidget(w84); lay->addWidget(w84);
QLabel *lbl84(new QLabel(dialog)); QLabel *lbl84(new QLabel(dialog));
lay->addWidget(lbl84); lay->addWidget(lbl84);
QObject::connect(w84, &LtsCoordWidget::LtsCoordWidget::coordinateChanged, w84, QObject::connect(w84, &LtsCoordWidget::LtsCoordWidget::coordinateChanged, w84, [lbl84](const QPointF &coord) { updateLabel(coord, lbl84, 11); });
[lbl84](const QPointF& coord) { updateLabel(coord, lbl84, 11); });
QHBoxLayout *hLay = new QHBoxLayout; QHBoxLayout *hLay = new QHBoxLayout;
lay->addLayout(hLay); lay->addLayout(hLay);
LtsCoordWidget::LtsCoordWidget* wChange( LtsCoordWidget::LtsCoordWidget *wChange(new LtsCoordWidget::LtsCoordWidget(LtsCoordWidget::LtsCoordWidget::DisplayType::WGS84, dialog));
new LtsCoordWidget::LtsCoordWidget(LtsCoordWidget::LtsCoordWidget::DisplayType::WGS84, dialog));
wChange->setWithResetButton(true); wChange->setWithResetButton(true);
wChange->setCoordinate(defCoord, true); wChange->setCoordinate(defCoord, true);
hLay->addWidget(wChange); hLay->addWidget(wChange);
QPushButton *pbReset(new QPushButton(QStringLiteral("With Reset"), dialog)); QPushButton *pbReset(new QPushButton(QStringLiteral("With Reset"), dialog));
hLay->addWidget(pbReset); hLay->addWidget(pbReset);
QObject::connect(pbReset, &QPushButton::clicked, wChange, QObject::connect(pbReset, &QPushButton::clicked, wChange, [wChange]() { wChange->setWithResetButton(!wChange->withResetButton()); });
[wChange]() { wChange->setWithResetButton(!wChange->withResetButton()); });
QPushButton *pbNext(new QPushButton(QStringLiteral("Next Type"), dialog)); QPushButton *pbNext(new QPushButton(QStringLiteral("Next Type"), dialog));
hLay->addWidget(pbNext); hLay->addWidget(pbNext);
QObject::connect(pbNext, &QPushButton::clicked, wChange, [wChange]() { QObject::connect(pbNext,
&QPushButton::clicked,
wChange,
[wChange]()
{
LtsCoordWidget::LtsCoordWidget::DisplayType dt = wChange->displayType(); LtsCoordWidget::LtsCoordWidget::DisplayType dt = wChange->displayType();
switch (dt) switch (dt)
{ {
@@ -38,7 +38,15 @@ int main(int argc, char** argv)
part2 = mgrs.substr(3, 2); part2 = mgrs.substr(3, 2);
part3 = mgrs.substr(5, prec); part3 = mgrs.substr(5, prec);
part4 = mgrs.substr(5 + prec, prec); part4 = mgrs.substr(5 + prec, prec);
fprintf(stdout, "%s %s %s %s = %13.10f, %13.10f ( %13.10f, %13.10f )\n", part1.c_str(), part2.c_str(), fprintf(stdout,
part3.c_str(), part4.c_str(), lonDeg, latDeg, lonDeg / 180. * M_PI, latDeg / 180. * M_PI); "%s %s %s %s = %13.10f, %13.10f ( %13.10f, %13.10f )\n",
part1.c_str(),
part2.c_str(),
part3.c_str(),
part4.c_str(),
lonDeg,
latDeg,
lonDeg / 180. * M_PI,
latDeg / 180. * M_PI);
return 0; return 0;
} }
@@ -13,8 +13,8 @@ namespace LtsLicence
struct AesCryptPrivate struct AesCryptPrivate
{ {
AesCryptPrivate() AesCryptPrivate()
: passPhrase(QLatin1String("LTS " LTS_VERSION_MAJOR "." LTS_VERSION_MINOR)), : passPhrase(QLatin1String("LTS " LTS_VERSION_MAJOR "." LTS_VERSION_MINOR))
logger(NGL::NGLLoggerBootstrap::getNGLRootLogger().getNGLLogger("LtsLicenceLib.AesCrypt")) , logger(NGL::NGLLoggerBootstrap::getNGLRootLogger().getNGLLogger("LtsLicenceLib.AesCrypt"))
{ {
#if OPENSSL_VERSION_NUMBER < 0x1010000fL #if OPENSSL_VERSION_NUMBER < 0x1010000fL
ERR_load_crypto_strings(); ERR_load_crypto_strings();
@@ -12,9 +12,7 @@ namespace LtsLicence
LTSLICENCE_EXPORT void setPassPhrase(const QString &passPhrase); LTSLICENCE_EXPORT void setPassPhrase(const QString &passPhrase);
LTSLICENCE_EXPORT QString passPhrase(); LTSLICENCE_EXPORT QString passPhrase();
LTSLICENCE_EXPORT QByteArray decryptData(const QByteArray& dataToDecrypt, const QString& pw = passPhrase(), LTSLICENCE_EXPORT QByteArray decryptData(const QByteArray &dataToDecrypt, const QString &pw = passPhrase(), bool *bOk = nullptr);
bool* bOk = nullptr);
LTSLICENCE_EXPORT QByteArray encryptData(const QByteArray& dataToEncrypt, const QString& pw = passPhrase(), LTSLICENCE_EXPORT QByteArray encryptData(const QByteArray &dataToEncrypt, const QString &pw = passPhrase(), bool *bOk = nullptr);
bool* bOk = nullptr);
} // namespace LtsLicence } // namespace LtsLicence
@@ -51,8 +51,7 @@ QByteArray writeUnencryptedLicences(const QVector<Licence>& licences)
{ {
QDomDocument xmlDoc; QDomDocument xmlDoc;
QDomProcessingInstruction instr = xmlDoc.createProcessingInstruction( QDomProcessingInstruction instr = xmlDoc.createProcessingInstruction(QLatin1String("xml"), QLatin1String("version='1.0' encoding='UTF-8' standalone='yes'"));
QLatin1String("xml"), QLatin1String("version='1.0' encoding='UTF-8' standalone='yes'"));
xmlDoc.appendChild(instr); xmlDoc.appendChild(instr);
QDomElement root = xmlDoc.createElement(QLatin1String("licences")); QDomElement root = xmlDoc.createElement(QLatin1String("licences"));
@@ -126,10 +125,9 @@ bool extractLicence(const QDomElement& licenceElement, QVector<Licence>& licence
licence.expiration = qdt; licence.expiration = qdt;
INFO_LOG(getLogger()) << "Read licence for:'" << licence.name << "'" INFO_LOG(getLogger()) << "Read licence for:'" << licence.name << "'"
<< " IgnoreMaxCount: " << licence.ignoreMaxCount << " IgnoreMaxCount: " << licence.ignoreMaxCount << " IgnoreExpiration: " << licence.ignoreExpiration << " MaxCount: " << licence.maxCount
<< " IgnoreExpiration: " << licence.ignoreExpiration << " MaxCount: " << licence.maxCount << " Expiration: " << licence.expiration.date().toString() << " " << licence.expiration.time().toString()
<< " Expiration: " << licence.expiration.date().toString() << " " << " RefCount: " << licence.licenceRefCount;
<< licence.expiration.time().toString() << " RefCount: " << licence.licenceRefCount;
licenceVec.append(licence); licenceVec.append(licence);
return true; return true;
@@ -9,7 +9,9 @@
namespace LtsNotification namespace LtsNotification
{ {
LtsNotification::LtsNotification(LtsNotificationController* ctl) : QObject(), m_controller(ctl) LtsNotification::LtsNotification(LtsNotificationController *ctl)
: QObject()
, m_controller(ctl)
{ {
connect(ctl, &LtsNotificationController::destroyed, this, &LtsNotification::slotCtlDestroyed); connect(ctl, &LtsNotificationController::destroyed, this, &LtsNotification::slotCtlDestroyed);
} }
@@ -14,7 +14,9 @@ namespace LtsNotification
{ {
LtsNotificationController::LtsNotificationController(const QString &identifier) LtsNotificationController::LtsNotificationController(const QString &identifier)
: QObject(), m_count(0), m_identifier(QStringLiteral("LtsNotification%1").arg(identifier)) : QObject()
, m_count(0)
, m_identifier(QStringLiteral("LtsNotification%1").arg(identifier))
{ {
} }
@@ -48,9 +50,8 @@ void LtsNotificationController::setBackground(const int r, const int g, const in
if (r == -1 && g == -1 && b == -1) if (r == -1 && g == -1 && b == -1)
stylesheet = QStringLiteral(""); stylesheet = QStringLiteral("");
else else
stylesheet = QStringLiteral("QToolButton {background-color: rgb(") + QString::number(r) + stylesheet = QStringLiteral("QToolButton {background-color: rgb(") + QString::number(r) + QStringLiteral(",") + QString::number(g) + QStringLiteral(",") +
QStringLiteral(",") + QString::number(g) + QStringLiteral(",") + QString::number(b) + QString::number(b) + QStringLiteral(");}");
QStringLiteral(");}");
tb->setStyleSheet(stylesheet); tb->setStyleSheet(stylesheet);
} }
@@ -133,7 +134,11 @@ QToolButton* LtsNotificationController::createWidget()
b->setMaximumSize(SIZE, SIZE); b->setMaximumSize(SIZE, SIZE);
connect(b, &QToolButton::destroyed, this, &LtsNotificationController::slotNotiWidgetDestroyed); connect(b, &QToolButton::destroyed, this, &LtsNotificationController::slotNotiWidgetDestroyed);
connect(b, &QToolButton::clicked, this, [this]() { connect(b,
&QToolButton::clicked,
this,
[this]()
{
if (m_action) if (m_action)
m_action(); m_action();
}); });
@@ -37,15 +37,9 @@ class LTSNOTIFICATION_EXPORT LtsNotificationController : public QObject
void setCount(const int count); void setCount(const int count);
void setBackground(const int r, const int g, const int b); void setBackground(const int r, const int g, const int b);
const QString& identifier() const const QString &identifier() const { return m_identifier; }
{
return m_identifier;
}
const QString& tooltip() const const QString &tooltip() const { return m_toolTip; }
{
return m_toolTip;
}
void setEnabled(bool enable); void setEnabled(bool enable);
@@ -41,7 +41,10 @@ void LtsRestClient::ping(PingSuccessCallback onSuccess, ErrorCallback onError, i
timeoutTimer->setSingleShot(true); timeoutTimer->setSingleShot(true);
// 2. Connect the timeout signal to abort the request // 2. Connect the timeout signal to abort the request
connect(timeoutTimer, &QTimer::timeout, this, [reply]() connect(timeoutTimer,
&QTimer::timeout,
this,
[reply]()
{ {
if (reply && reply->isRunning()) if (reply && reply->isRunning())
reply->abort(); // Triggers finished() with OperationCanceledError reply->abort(); // Triggers finished() with OperationCanceledError
@@ -15,9 +15,12 @@ class LTSSERIALPORTQUERRY_EXPORT LtsSerialPortQuerry : public QObject
public: public:
explicit LtsSerialPortQuerry(QObject *parent = nullptr); explicit LtsSerialPortQuerry(QObject *parent = nullptr);
void setSerialPortSettings(const QSerialPort::BaudRate& baudRate, const QSerialPort::OpenModeFlag& openModeFlag, void setSerialPortSettings(const QSerialPort::BaudRate &baudRate,
const QSerialPort::DataBits& dataBits, const QSerialPort::FlowControl& flowControll, const QSerialPort::OpenModeFlag &openModeFlag,
const QSerialPort::Parity& parity, const QSerialPort::StopBits& stopBits); const QSerialPort::DataBits &dataBits,
const QSerialPort::FlowControl &flowControll,
const QSerialPort::Parity &parity,
const QSerialPort::StopBits &stopBits);
void continueQuerry(); void continueQuerry();
void restartQuerry(); void restartQuerry();
QSerialPort *currentSerialPort(); QSerialPort *currentSerialPort();
@@ -6,10 +6,16 @@ namespace LtsSerialPortQuerry
{ {
LtsSerialPortQuerry::LtsSerialPortQuerry(QObject *parent) LtsSerialPortQuerry::LtsSerialPortQuerry(QObject *parent)
: QObject(parent), m_logger(getLogger("LtsSerialPortQuerry")), m_currentQuerry(0), : QObject(parent)
m_baudRate(QSerialPort::Baud115200), m_openModeFlag(QSerialPort::ReadWrite), m_dataBits(QSerialPort::Data8), , m_logger(getLogger("LtsSerialPortQuerry"))
m_flowControll(QSerialPort::NoFlowControl), m_parity(QSerialPort::NoParity), m_stopBits(QSerialPort::OneStop), , m_currentQuerry(0)
m_currentSerialPort(nullptr) , m_baudRate(QSerialPort::Baud115200)
, m_openModeFlag(QSerialPort::ReadWrite)
, m_dataBits(QSerialPort::Data8)
, m_flowControll(QSerialPort::NoFlowControl)
, m_parity(QSerialPort::NoParity)
, m_stopBits(QSerialPort::OneStop)
, m_currentSerialPort(nullptr)
{ {
} }
@@ -66,8 +72,7 @@ void LtsSerialPortQuerry::querrySerialPort(const QSerialPortInfo& info)
m_currentSerialPort->setStopBits(m_stopBits); m_currentSerialPort->setStopBits(m_stopBits);
m_currentSerialPort->setFlowControl(m_flowControll); m_currentSerialPort->setFlowControl(m_flowControll);
DEBUG_LOG(m_logger) << "Try opening Comport:" << m_currentSerialPort->portName() DEBUG_LOG(m_logger) << "Try opening Comport:" << m_currentSerialPort->portName() << " index is: " << m_currentQuerry;
<< " index is: " << m_currentQuerry;
if (!m_currentSerialPort->open(QSerialPort::ReadWrite)) if (!m_currentSerialPort->open(QSerialPort::ReadWrite))
{ {
@@ -78,8 +83,7 @@ void LtsSerialPortQuerry::querrySerialPort(const QSerialPortInfo& info)
} }
else else
{ {
connect(m_currentSerialPort, &QSerialPort::errorOccurred, this, &LtsSerialPortQuerry::onSerialPortError, connect(m_currentSerialPort, &QSerialPort::errorOccurred, this, &LtsSerialPortQuerry::onSerialPortError, Qt::UniqueConnection);
Qt::UniqueConnection);
DEBUG_LOG(m_logger) << "Oppened comport" << m_currentSerialPort->portName(); DEBUG_LOG(m_logger) << "Oppened comport" << m_currentSerialPort->portName();
emit connectionEstablished(); emit connectionEstablished();
} }
@@ -105,13 +109,13 @@ void LtsSerialPortQuerry::onSerialPortError(QSerialPort::SerialPortError serialP
return; return;
DEBUG_LOG(m_logger) << "Spontaneous error " << serialPortError << " doesn't have to be an error ..."; DEBUG_LOG(m_logger) << "Spontaneous error " << serialPortError << " doesn't have to be an error ...";
const QString errStr(QStringLiteral("QSerialPort::SerialPortError ") + QString::number(serialPortError) + const QString errStr(QStringLiteral("QSerialPort::SerialPortError ") + QString::number(serialPortError) + QStringLiteral(" from serial port ") +
QStringLiteral(" from serial port ") + m_currentSerialPort->portName() + m_currentSerialPort->portName() + QStringLiteral(" error: ") + m_currentSerialPort->errorString());
QStringLiteral(" error: ") + m_currentSerialPort->errorString());
switch (serialPortError) switch (serialPortError)
{ {
case QSerialPort::SerialPortError::NoError: { case QSerialPort::SerialPortError::NoError:
{
break; break;
} }
@@ -119,17 +123,20 @@ void LtsSerialPortQuerry::onSerialPortError(QSerialPort::SerialPortError serialP
case QSerialPort::SerialPortError::PermissionError: case QSerialPort::SerialPortError::PermissionError:
case QSerialPort::SerialPortError::OpenError: case QSerialPort::SerialPortError::OpenError:
case QSerialPort::SerialPortError::NotOpenError: case QSerialPort::SerialPortError::NotOpenError:
case QSerialPort::SerialPortError::UnknownError: { case QSerialPort::SerialPortError::UnknownError:
{
ERROR_LOG(m_logger) << "Closing port and try to reopen it. " << m_currentSerialPort->portName(); ERROR_LOG(m_logger) << "Closing port and try to reopen it. " << m_currentSerialPort->portName();
continueQuerry(); continueQuerry();
Q_FALLTHROUGH(); Q_FALLTHROUGH();
} }
case QSerialPort::SerialPortError::UnsupportedOperationError: { case QSerialPort::SerialPortError::UnsupportedOperationError:
{
ERROR_LOG(m_logger) << errStr; ERROR_LOG(m_logger) << errStr;
break; break;
} }
default: { default:
{
ERROR_LOG(m_logger) << "Got an Error> " << errStr << "restarting"; ERROR_LOG(m_logger) << "Got an Error> " << errStr << "restarting";
continueQuerry(); continueQuerry();
@@ -15,9 +15,12 @@ class LTSSERIALPORTQUERRY_EXPORT LtsSerialPortQuerry : public QObject
public: public:
explicit LtsSerialPortQuerry(QObject *parent = nullptr); explicit LtsSerialPortQuerry(QObject *parent = nullptr);
void setSerialPortSettings(const QSerialPort::BaudRate& baudRate, const QSerialPort::OpenModeFlag& openModeFlag, void setSerialPortSettings(const QSerialPort::BaudRate &baudRate,
const QSerialPort::DataBits& dataBits, const QSerialPort::FlowControl& flowControll, const QSerialPort::OpenModeFlag &openModeFlag,
const QSerialPort::Parity& parity, const QSerialPort::StopBits& stopBits); const QSerialPort::DataBits &dataBits,
const QSerialPort::FlowControl &flowControll,
const QSerialPort::Parity &parity,
const QSerialPort::StopBits &stopBits);
void restartQuerry(); void restartQuerry();
QSerialPort *currentSerialPort(); QSerialPort *currentSerialPort();
@@ -8,7 +8,4 @@
ADD_SUBDIRECTORY(LtsUtilsCore) ADD_SUBDIRECTORY(LtsUtilsCore)
IF(NOT RELEASE_BUILD)
ADD_SUBDIRECTORY(LtsUtilsGui)
ENDIF()
ADD_SUBDIRECTORY(LtsUtilsSettings) ADD_SUBDIRECTORY(LtsUtilsSettings)
@@ -48,22 +48,3 @@ NGL_TARGET_LINK_LIBRARIES(LtsUtilsCore
Qt6::Core Qt6::Core
LtsUtilsCoreHeaderOnly LtsUtilsCoreHeaderOnly
) )
#
# --- Tests --------------------------------------------------------------
#
IF(BUILD_RTI AND (BUILD_WS OR BUILD_SV) AND BUILD_TESTING)
ADD_EXECUTABLE(utils_test
UnitTests/utils_test.cpp
UnitTests/utils_test.h
promise_examples.h
promise_examples.cpp
)
TARGET_LINK_LIBRARIES(utils_test
LtsUtilsCore
Qt6::Core
Qt6::Test
ddscore
)
ADD_TEST(NAME utils_test COMMAND $<TARGET_FILE:utils_test>)
ENDIF()
@@ -43,11 +43,9 @@ template <> char* toString(const QVector<int>& vec)
return qstrdup(sl.join(QLatin1Char(',')).toLatin1().constData()); return qstrdup(sl.join(QLatin1Char(',')).toLatin1().constData());
} }
#if QT_VERSION < QT_VERSION_CHECK(5, 10, 0) #if QT_VERSION < QT_VERSION_CHECK(5, 10, 0)
template <typename T1, typename T2> template <typename T1, typename T2> inline bool qCompare(const T1 &t1, const T2 &t2, const char *actual, const char *expected, const char *file, int line)
inline bool qCompare(const T1& t1, const T2& t2, const char* actual, const char* expected, const char* file, int line)
{ {
return compare_helper(t1 == t2, "Compared values are not the same", toString(t1), toString(t2), actual, expected, return compare_helper(t1 == t2, "Compared values are not the same", toString(t1), toString(t2), actual, expected, file, line);
file, line);
} }
#endif #endif
} // namespace QTest } // namespace QTest
@@ -65,7 +63,9 @@ void LtsUtilsTest::test_promise()
results.append(1); results.append(1);
LtsUtils::Promise p([&results](LtsUtils::ResultFunction resolve, LtsUtils::ResultFunction) { LtsUtils::Promise p(
[&results](LtsUtils::ResultFunction resolve, LtsUtils::ResultFunction)
{
results.append(4); results.append(4);
qDebug() << "LtsUtils Promise: Promise executed! Resolving now"; qDebug() << "LtsUtils Promise: Promise executed! Resolving now";
@@ -75,13 +75,17 @@ void LtsUtilsTest::test_promise()
results.append(2); results.append(2);
bool resolved = false; bool resolved = false;
p.resolved([&resolved, &results](const QVariant& value) { p.resolved(
[&resolved, &results](const QVariant &value)
{
results.append(5); results.append(5);
qDebug() << "LtsUtils Promise: Promise was resolved with value" << value; qDebug() << "LtsUtils Promise: Promise was resolved with value" << value;
resolved = true; resolved = true;
}); });
p.rejected([](const QVariant& val) { p.rejected(
[](const QVariant &val)
{
qCritical() << "rejected with val" << val; qCritical() << "rejected with val" << val;
QFAIL("Promise unexpectedly rejected"); QFAIL("Promise unexpectedly rejected");
}); });
@@ -260,8 +264,7 @@ void LtsUtilsTest::test_fromIntArray2D()
{ {
qDebug("LtsUtils: test_fromIntArray2D"); qDebug("LtsUtils: test_fromIntArray2D");
QString str = LtsUtils::IntArray2D({{0, 2}, {1, 3}, {2, 999999999}, {3, -2147483647}, {4, 2147483647}, {5, 123456}}) QString str = LtsUtils::IntArray2D({{0, 2}, {1, 3}, {2, 999999999}, {3, -2147483647}, {4, 2147483647}, {5, 123456}}).toPgString();
.toPgString();
qDebug() << "LtsUtils: Result " << str; qDebug() << "LtsUtils: Result " << str;
QCOMPARE(str, QLatin1String("{{0,2},{1,3},{2,999999999},{3,-2147483647},{4,2147483647},{5,123456}}")); QCOMPARE(str, QLatin1String("{{0,2},{1,3},{2,999999999},{3,-2147483647},{4,2147483647},{5,123456}}"));
@@ -295,9 +298,7 @@ void LtsUtilsTest::test_fromBigintArray2D()
{ {
qDebug("LtsUtils: test_fromBigintArray2D"); qDebug("LtsUtils: test_fromBigintArray2D");
QString str = QString str = LtsUtils::BigintArray2D({{0, -123456789}, {1, -2147483647}, {2, 999999999999}, {3, 123456789}, {4, 2147483647}}).toPgString();
LtsUtils::BigintArray2D({{0, -123456789}, {1, -2147483647}, {2, 999999999999}, {3, 123456789}, {4, 2147483647}})
.toPgString();
qDebug() << "LtsUtils: Result " << str; qDebug() << "LtsUtils: Result " << str;
QCOMPARE(str, QLatin1String("{{0,-123456789},{1,-2147483647},{2,999999999999},{3,123456789},{4,2147483647}}")); QCOMPARE(str, QLatin1String("{{0,-123456789},{1,-2147483647},{2,999999999999},{3,123456789},{4,2147483647}}"));
@@ -336,14 +337,10 @@ void LtsUtilsTest::test_bitArray()
qDebug("LtsUtils: test_bitArray"); qDebug("LtsUtils: test_bitArray");
{ {
QVERIFY2(LtsUtils::BitArray::convert<std::vector<uint8_t>>(QBitArray(8)).size() == 1, QVERIFY2(LtsUtils::BitArray::convert<std::vector<uint8_t>>(QBitArray(8)).size() == 1, " wrong size of underlying data");
" wrong size of underlying data"); QVERIFY2(LtsUtils::BitArray::convert<std::vector<uint8_t>>(QBitArray(9)).size() == 2, " wrong size of underlying data");
QVERIFY2(LtsUtils::BitArray::convert<std::vector<uint8_t>>(QBitArray(9)).size() == 2, QVERIFY2(LtsUtils::BitArray::convert<std::vector<uint8_t>>(QBitArray(16)).size() == 2, " wrong size of underlying data");
" wrong size of underlying data"); QVERIFY2(LtsUtils::BitArray::convert<std::vector<uint8_t>>(QBitArray(17)).size() == 3, " wrong size of underlying data");
QVERIFY2(LtsUtils::BitArray::convert<std::vector<uint8_t>>(QBitArray(16)).size() == 2,
" wrong size of underlying data");
QVERIFY2(LtsUtils::BitArray::convert<std::vector<uint8_t>>(QBitArray(17)).size() == 3,
" wrong size of underlying data");
} }
{ {
@@ -513,10 +510,7 @@ class Spy : public QObject
public slots: public slots:
void slot1() void slot1() { ++m_slot1Count; }
{
++m_slot1Count;
}
public: public:
int m_slot1Count{0}; int m_slot1Count{0};
@@ -526,8 +520,7 @@ void LtsUtilsTest::test_connection()
{ {
Emitter emitter; Emitter emitter;
Spy spy; Spy spy;
std::unique_ptr<LtsUtils::IConnection> conn( std::unique_ptr<LtsUtils::IConnection> conn(LtsUtils::createConnection(&emitter, &Emitter::signal1, &spy, &Spy::slot1));
LtsUtils::createConnection(&emitter, &Emitter::signal1, &spy, &Spy::slot1));
emit emitter.signal1(); emit emitter.signal1();
QCOMPARE(spy.m_slot1Count, 0); QCOMPARE(spy.m_slot1Count, 0);
@@ -544,8 +537,7 @@ void LtsUtilsTest::test_queuedConnection()
{ {
Emitter emitter; Emitter emitter;
Spy spy; Spy spy;
std::unique_ptr<LtsUtils::IConnection> conn( std::unique_ptr<LtsUtils::IConnection> conn(LtsUtils::createConnection(&emitter, &Emitter::signal2, &spy, &Spy::slot1));
LtsUtils::createConnection(&emitter, &Emitter::signal2, &spy, &Spy::slot1));
emit emitter.signal2(42); emit emitter.signal2(42);
QCOMPARE(spy.m_slot1Count, 0); QCOMPARE(spy.m_slot1Count, 0);
@@ -560,10 +552,8 @@ void LtsUtilsTest::test_signalSignalConnection()
{ {
Emitter emitter; Emitter emitter;
Spy spy; Spy spy;
std::unique_ptr<LtsUtils::IConnection> signalSignalConn( std::unique_ptr<LtsUtils::IConnection> signalSignalConn(LtsUtils::createConnection(&emitter, &Emitter::signal2, &emitter, &Emitter::signal1));
LtsUtils::createConnection(&emitter, &Emitter::signal2, &emitter, &Emitter::signal1)); std::unique_ptr<LtsUtils::IConnection> signalSlotConn(LtsUtils::createConnection(&emitter, &Emitter::signal1, &spy, &Spy::slot1));
std::unique_ptr<LtsUtils::IConnection> signalSlotConn(
LtsUtils::createConnection(&emitter, &Emitter::signal1, &spy, &Spy::slot1));
signalSignalConn->connect(); signalSignalConn->connect();
signalSlotConn->connect(); signalSlotConn->connect();
@@ -963,10 +953,8 @@ void LtsUtilsTest::test_byteStreamFromSfmMessage()
const quint8 payloadArray[] = {0x11, 0x02, 0x03, 0x04, 0x50}; const quint8 payloadArray[] = {0x11, 0x02, 0x03, 0x04, 0x50};
msg.setPayload(QByteArray(reinterpret_cast<const char *>(payloadArray), sizeof(payloadArray))); msg.setPayload(QByteArray(reinterpret_cast<const char *>(payloadArray), sizeof(payloadArray)));
const quint8 expectedResultArray[] = {0x02, 0x80, 0x00, 0x10, 0x05, 0x80, 0x91, 0x80, const quint8 expectedResultArray[] = {0x02, 0x80, 0x00, 0x10, 0x05, 0x80, 0x91, 0x80, 0x82, 0x80, 0x83, 0x04, 0x50, 0x00, 0x03};
0x82, 0x80, 0x83, 0x04, 0x50, 0x00, 0x03}; QByteArray expectedResult = QByteArray(reinterpret_cast<const char *>(expectedResultArray), sizeof(expectedResultArray));
QByteArray expectedResult =
QByteArray(reinterpret_cast<const char*>(expectedResultArray), sizeof(expectedResultArray));
QByteArray byteMessage = byteStreamFromSfmMessage(msg); QByteArray byteMessage = byteStreamFromSfmMessage(msg);
@@ -990,8 +978,7 @@ void LtsUtilsTest::test_byteStreamToSfmMessage()
const quint8 payloadArray[] = {0x11, 0x02, 0x03, 0x04, 0x50, 0x00}; const quint8 payloadArray[] = {0x11, 0x02, 0x03, 0x04, 0x50, 0x00};
msgComplete.setPayload(QByteArray(reinterpret_cast<const char *>(payloadArray), sizeof(payloadArray))); msgComplete.setPayload(QByteArray(reinterpret_cast<const char *>(payloadArray), sizeof(payloadArray)));
const quint8 dataArray[] = {0x02, 0x80, 0x00, 0x10, 0x06, 0x80, 0x91, 0x80, const quint8 dataArray[] = {0x02, 0x80, 0x00, 0x10, 0x06, 0x80, 0x91, 0x80, 0x82, 0x80, 0x83, 0x04, 0x50, 0x00, 0xFF, 0x03};
0x82, 0x80, 0x83, 0x04, 0x50, 0x00, 0xFF, 0x03};
QByteArray dataComplete = QByteArray(reinterpret_cast<const char *>(dataArray), sizeof(dataArray)); QByteArray dataComplete = QByteArray(reinterpret_cast<const char *>(dataArray), sizeof(dataArray));
SfmMessage result; SfmMessage result;
@@ -7,9 +7,7 @@
namespace LtsUtils namespace LtsUtils
{ {
template <typename Func> template <typename Func> void addConnect(QEventLoop &x, bool &success, const typename QtPrivate::FunctionPointer<Func>::Object *sender, Func signal, bool isSuccess)
void addConnect(QEventLoop& x, bool& success, const typename QtPrivate::FunctionPointer<Func>::Object* sender,
Func signal, bool isSuccess)
{ {
if (isSuccess) if (isSuccess)
{ {
@@ -20,8 +18,7 @@ void addConnect(QEventLoop& x, bool& success, const typename QtPrivate::Function
} }
template <typename Func, typename... Connect> template <typename Func, typename... Connect>
void addConnect(QEventLoop& x, bool& success, const typename QtPrivate::FunctionPointer<Func>::Object* sender, void addConnect(QEventLoop &x, bool &success, const typename QtPrivate::FunctionPointer<Func>::Object *sender, Func signal, bool isSuccess, Connect... connects)
Func signal, bool isSuccess, Connect... connects)
{ {
addConnect(x, success, sender, signal, isSuccess); addConnect(x, success, sender, signal, isSuccess);
addConnect(x, success, connects...); addConnect(x, success, connects...);
@@ -52,7 +49,11 @@ template <typename... Connect> void awaitTimeout(const int timeoutMs, Connect...
{ {
t->setInterval(timeoutMs); t->setInterval(timeoutMs);
t->setSingleShot(true); t->setSingleShot(true);
QObject::connect(t.get(), &QTimer::timeout, t.get(), [&timeout]() { QObject::connect(t.get(),
&QTimer::timeout,
t.get(),
[&timeout]()
{
fprintf(stderr, "awaitTimeout: timed out!\n"); fprintf(stderr, "awaitTimeout: timed out!\n");
timeout = true; timeout = true;
}); });
@@ -69,8 +70,10 @@ template <typename... Connect> void awaitTimeout(const int timeoutMs, Connect...
} }
template <typename Func1, typename Func2> template <typename Func1, typename Func2>
void awaitWithCancelationSignal(const typename QtPrivate::FunctionPointer<Func1>::Object* sender1, Func1 signal1, void awaitWithCancelationSignal(const typename QtPrivate::FunctionPointer<Func1>::Object *sender1,
const typename QtPrivate::FunctionPointer<Func2>::Object* sender2, Func2 signal2, Func1 signal1,
const typename QtPrivate::FunctionPointer<Func2>::Object *sender2,
Func2 signal2,
const int timeoutMs = 0) noexcept(false) const int timeoutMs = 0) noexcept(false)
{ {
if (timeoutMs > 0) if (timeoutMs > 0)
@@ -52,7 +52,10 @@ template <class Signal, class Slot> class Connection : public IConnection
public: public:
Connection(Emitter *emitter, Signal signal, Target *target, Slot slot) Connection(Emitter *emitter, Signal signal, Target *target, Slot slot)
: m_emitter(emitter), m_signal(signal), m_target(target), m_slot(slot) : m_emitter(emitter)
, m_signal(signal)
, m_target(target)
, m_slot(slot)
{ {
Q_ASSERT(emitter); Q_ASSERT(emitter);
Q_ASSERT(signal); Q_ASSERT(signal);
@@ -93,8 +96,10 @@ template <class Signal, class Slot> class Connection : public IConnection
}; };
template <class Signal, class Slot> template <class Signal, class Slot>
Connection<Signal, Slot>* createConnection(typename detail::ExtractClass<Signal>::type* emitter, Signal signal, Connection<Signal, Slot> *createConnection(typename detail::ExtractClass<Signal>::type *emitter,
typename detail::ExtractClass<Slot>::type* target, Slot slot) Signal signal,
typename detail::ExtractClass<Slot>::type *target,
Slot slot)
{ {
return new Connection<Signal, Slot>(emitter, signal, target, slot); return new Connection<Signal, Slot>(emitter, signal, target, slot);
} }
@@ -4,7 +4,12 @@
#include <ostream> #include <ostream>
enum class DataModification { eAdded, eModified, eRemoved }; enum class DataModification
{
eAdded,
eModified,
eRemoved
};
inline std::ostream &operator<<(std::ostream &str, DataModification mod) inline std::ostream &operator<<(std::ostream &str, DataModification mod)
{ {
@@ -25,8 +25,7 @@ class JsonParseError : public std::runtime_error
{ {
public: public:
JsonParseError(const QJsonParseError &err) JsonParseError(const QJsonParseError &err)
: std::runtime_error("json parse error: " + err.errorString().toStdString() + " - at offset " + : std::runtime_error("json parse error: " + err.errorString().toStdString() + " - at offset " + std::to_string(err.offset))
std::to_string(err.offset))
{ {
} }
}; };
@@ -62,50 +61,37 @@ class JsonObject
JsonObject() = default; JsonObject() = default;
explicit JsonObject(const QJsonObject& json) : m_json(json), m_jsonIsSet(true) {} explicit JsonObject(const QJsonObject &json)
: m_json(json)
, m_jsonIsSet(true)
{
}
explicit JsonObject(QJsonObject&& json) : m_json(std::move(json)), m_jsonIsSet(true) {} explicit JsonObject(QJsonObject &&json)
: m_json(std::move(json))
, m_jsonIsSet(true)
{
}
static inline JsonObject fromJson(const char *json, int len = -1); static inline JsonObject fromJson(const char *json, int len = -1);
static inline JsonObject fromJson(const QByteArray& json) static inline JsonObject fromJson(const QByteArray &json) { return fromJson(json.data(), json.size()); }
{
return fromJson(json.data(), json.size());
}
static inline JsonObject fromJson(const std::string& json) static inline JsonObject fromJson(const std::string &json) { return fromJson(json.c_str(), json.size()); }
{
return fromJson(json.c_str(), json.size());
}
static inline JsonObject fromJsonSafe(const char *json, int len = -1) noexcept(false); static inline JsonObject fromJsonSafe(const char *json, int len = -1) noexcept(false);
static inline JsonObject fromJsonSafe(const QByteArray& json) noexcept(false) static inline JsonObject fromJsonSafe(const QByteArray &json) noexcept(false) { return fromJsonSafe(json.data(), json.size()); }
{
return fromJsonSafe(json.data(), json.size());
}
static inline JsonObject fromJsonSafe(const std::string& json) noexcept(false) static inline JsonObject fromJsonSafe(const std::string &json) noexcept(false) { return fromJsonSafe(json.c_str(), json.size()); }
{
return fromJsonSafe(json.c_str(), json.size());
}
template <class T> [[nodiscard]] bool contains(const Key &key) const; template <class T> [[nodiscard]] bool contains(const Key &key) const;
[[nodiscard]] bool isNull(const Key& key) const [[nodiscard]] bool isNull(const Key &key) const { return contains<void>(key); }
{
return contains<void>(key);
}
[[nodiscard]] bool isEmpty() const [[nodiscard]] bool isEmpty() const { return m_json.isEmpty(); }
{
return m_json.isEmpty();
}
[[nodiscard]] bool isValid() const [[nodiscard]] bool isValid() const { return m_jsonIsSet; }
{
return m_jsonIsSet;
}
template <class T> T value(const Key &key) const noexcept(false); template <class T> T value(const Key &key) const noexcept(false);
@@ -117,49 +103,40 @@ class JsonObject
template <class T> std::map<std::string, T> toStdMap() const; template <class T> std::map<std::string, T> toStdMap() const;
bool operator==(const JsonObject& other) const bool operator==(const JsonObject &other) const { return m_json == other.m_json; }
{
return m_json == other.m_json;
}
bool operator!=(const JsonObject& other) const bool operator!=(const JsonObject &other) const { return !(*this == other); }
{
return !(*this == other);
}
class Key class Key
{ {
public: public:
Key(QString s) : m_s(std::move(s)) {} Key(QString s)
: m_s(std::move(s))
Key(const std::string& s) : m_s(QString::fromStdString(s)) {}
Key(const char* s) : m_s(QString::fromUtf8(s)) {}
operator const QString&() const
{ {
return m_s;
} }
Key(const std::string &s)
: m_s(QString::fromStdString(s))
{
}
Key(const char *s)
: m_s(QString::fromUtf8(s))
{
}
operator const QString &() const { return m_s; }
private: private:
const QString m_s; const QString m_s;
}; };
operator const QJsonObject&() const operator const QJsonObject &() const { return m_json; }
{
return m_json;
}
[[nodiscard]] const QJsonObject& object() const [[nodiscard]] const QJsonObject &object() const { return m_json; }
{
return m_json;
}
private: private:
[[nodiscard]] bool containsAny(const QString& key) const [[nodiscard]] bool containsAny(const QString &key) const { return m_json.contains(key); }
{
return m_json.contains(key);
}
QJsonObject m_json; QJsonObject m_json;
bool m_jsonIsSet = false; bool m_jsonIsSet = false;
@@ -200,55 +177,39 @@ class JsonArray
public: public:
JsonArray() = default; JsonArray() = default;
explicit JsonArray(const QJsonArray& json) : m_json(json), m_jsonIsSet(true) {} explicit JsonArray(const QJsonArray &json)
: m_json(json)
, m_jsonIsSet(true)
{
}
explicit JsonArray(QJsonArray&& json) : m_json(std::move(json)), m_jsonIsSet(true) {} explicit JsonArray(QJsonArray &&json)
: m_json(std::move(json))
, m_jsonIsSet(true)
{
}
static inline JsonArray fromJson(const char *json, int len = -1); static inline JsonArray fromJson(const char *json, int len = -1);
static inline JsonArray fromJson(const QByteArray& json) static inline JsonArray fromJson(const QByteArray &json) { return fromJson(json.data(), json.size()); }
{
return fromJson(json.data(), json.size());
}
static inline JsonArray fromJson(const std::string& json) static inline JsonArray fromJson(const std::string &json) { return fromJson(json.c_str(), json.size()); }
{
return fromJson(json.c_str(), json.size());
}
static inline JsonArray fromJsonSafe(const char *json, int len = -1) noexcept(false); static inline JsonArray fromJsonSafe(const char *json, int len = -1) noexcept(false);
static inline JsonArray fromJsonSafe(const QByteArray& json) noexcept(false) static inline JsonArray fromJsonSafe(const QByteArray &json) noexcept(false) { return fromJson(json.data(), json.size()); }
{
return fromJson(json.data(), json.size());
}
static inline JsonArray fromJsonSafe(const std::string& json) noexcept(false) static inline JsonArray fromJsonSafe(const std::string &json) noexcept(false) { return fromJson(json.c_str(), json.size()); }
{
return fromJson(json.c_str(), json.size());
}
[[nodiscard]] int size() const [[nodiscard]] int size() const { return m_json.size(); }
{
return m_json.size();
}
[[nodiscard]] bool isEmpty() const [[nodiscard]] bool isEmpty() const { return m_json.isEmpty(); }
{
return m_json.isEmpty();
}
[[nodiscard]] bool isValid() const [[nodiscard]] bool isValid() const { return m_jsonIsSet; }
{
return m_jsonIsSet;
}
template <class T> [[nodiscard]] bool contains(int index) const noexcept(false); template <class T> [[nodiscard]] bool contains(int index) const noexcept(false);
[[nodiscard]] bool isNull(int index) const noexcept(false) [[nodiscard]] bool isNull(int index) const noexcept(false) { return contains<void>(index); }
{
return contains<void>(index);
}
template <class T> T at(int index) const noexcept(false); template <class T> T at(int index) const noexcept(false);
@@ -258,20 +219,11 @@ class JsonArray
template <class T> std::vector<T> toStdVector() const; template <class T> std::vector<T> toStdVector() const;
bool operator==(const JsonArray& other) const bool operator==(const JsonArray &other) const { return m_json == other.m_json; }
{
return m_json == other.m_json;
}
bool operator!=(const JsonArray& other) const bool operator!=(const JsonArray &other) const { return !(*this == other); }
{
return !(*this == other);
}
const QJsonArray& operator()() const const QJsonArray &operator()() const { return m_json; }
{
return m_json;
}
private: private:
QJsonArray m_json; QJsonArray m_json;
@@ -312,41 +264,23 @@ template <class T> struct JsonValue;
template <class Int> struct JsonLimits template <class Int> struct JsonLimits
{ {
static constexpr Int lowest() static constexpr Int lowest() { return std::numeric_limits<Int>::lowest(); }
{
return std::numeric_limits<Int>::lowest();
}
static constexpr Int max() static constexpr Int max() { return std::numeric_limits<Int>::max(); }
{
return std::numeric_limits<Int>::max();
}
}; };
template <> struct JsonLimits<int64_t> template <> struct JsonLimits<int64_t>
{ {
static constexpr int64_t lowest() static constexpr int64_t lowest() { return -(static_cast<int64_t>(1) << 53) + 1; }
{
return -(static_cast<int64_t>(1) << 53) + 1;
}
static constexpr int64_t max() static constexpr int64_t max() { return (static_cast<int64_t>(1) << 53) - 1; }
{
return (static_cast<int64_t>(1) << 53) - 1;
}
}; };
template <> struct JsonLimits<uint64_t> template <> struct JsonLimits<uint64_t>
{ {
static constexpr uint64_t lowest() static constexpr uint64_t lowest() { return 0; }
{
return 0;
}
static constexpr uint64_t max() static constexpr uint64_t max() { return JsonLimits<int64_t>::max(); }
{
return JsonLimits<int64_t>::max();
}
}; };
template <class Int> struct JsonIntValue template <class Int> struct JsonIntValue
@@ -400,10 +334,7 @@ template <> struct JsonValue<uint64_t> : JsonIntValue<uint64_t>
template <> struct JsonValue<double> template <> struct JsonValue<double>
{ {
static bool matchesType(const QJsonValue& value) static bool matchesType(const QJsonValue &value) { return value.isDouble(); }
{
return value.isDouble();
}
static double value(const QJsonValue &value) noexcept(false) static double value(const QJsonValue &value) noexcept(false)
{ {
@@ -415,10 +346,7 @@ template <> struct JsonValue<double>
template <> struct JsonValue<bool> template <> struct JsonValue<bool>
{ {
static bool matchesType(const QJsonValue& value) static bool matchesType(const QJsonValue &value) { return value.isBool(); }
{
return value.isBool();
}
static bool value(const QJsonValue &value) noexcept(false) static bool value(const QJsonValue &value) noexcept(false)
{ {
@@ -430,10 +358,7 @@ template <> struct JsonValue<bool>
template <> struct JsonValue<QString> template <> struct JsonValue<QString>
{ {
static bool matchesType(const QJsonValue& value) static bool matchesType(const QJsonValue &value) { return value.isString(); }
{
return value.isString();
}
static QString value(const QJsonValue &value) noexcept(false) static QString value(const QJsonValue &value) noexcept(false)
{ {
@@ -445,23 +370,14 @@ template <> struct JsonValue<QString>
template <> struct JsonValue<std::string> template <> struct JsonValue<std::string>
{ {
static bool matchesType(const QJsonValue& value) static bool matchesType(const QJsonValue &value) { return value.isString(); }
{
return value.isString();
}
static std::string value(const QJsonValue& value) static std::string value(const QJsonValue &value) { return JsonValue<QString>::value(value).toStdString(); }
{
return JsonValue<QString>::value(value).toStdString();
}
}; };
template <> struct JsonValue<QJsonObject> template <> struct JsonValue<QJsonObject>
{ {
static bool matchesType(const QJsonValue& value) static bool matchesType(const QJsonValue &value) { return value.isObject(); }
{
return value.isObject();
}
static QJsonObject value(const QJsonValue &value) noexcept(false) static QJsonObject value(const QJsonValue &value) noexcept(false)
{ {
@@ -473,31 +389,19 @@ template <> struct JsonValue<QJsonObject>
template <> struct JsonValue<JsonObject> template <> struct JsonValue<JsonObject>
{ {
static bool matchesType(const QJsonValue& value) static bool matchesType(const QJsonValue &value) { return value.isObject(); }
{
return value.isObject();
}
static JsonObject value(const QJsonValue& value) static JsonObject value(const QJsonValue &value) { return JsonObject(JsonValue<QJsonObject>::value(value)); }
{
return JsonObject(JsonValue<QJsonObject>::value(value));
}
}; };
template <> struct JsonValue<void> template <> struct JsonValue<void>
{ {
static bool matchesType(const QJsonValue& value) static bool matchesType(const QJsonValue &value) { return value.isNull(); }
{
return value.isNull();
}
}; };
template <> struct JsonValue<QJsonArray> template <> struct JsonValue<QJsonArray>
{ {
static bool matchesType(const QJsonValue& value) static bool matchesType(const QJsonValue &value) { return value.isArray(); }
{
return value.isArray();
}
static QJsonArray value(const QJsonValue &value) noexcept(false) static QJsonArray value(const QJsonValue &value) noexcept(false)
{ {
@@ -509,15 +413,9 @@ template <> struct JsonValue<QJsonArray>
template <> struct JsonValue<JsonArray> template <> struct JsonValue<JsonArray>
{ {
static bool matchesType(const QJsonValue& value) static bool matchesType(const QJsonValue &value) { return value.isArray(); }
{
return value.isArray();
}
static JsonArray value(const QJsonValue& value) static JsonArray value(const QJsonValue &value) { return JsonArray(JsonValue<QJsonArray>::value(value)); }
{
return JsonArray(JsonValue<QJsonArray>::value(value));
}
}; };
template <class T> struct JsonValue<QVector<T>> template <class T> struct JsonValue<QVector<T>>
@@ -540,10 +438,7 @@ template <class T> struct JsonValue<QVector<T>>
template <class T> struct JsonValue<std::vector<T>> template <class T> struct JsonValue<std::vector<T>>
{ {
static bool matchesType(const QJsonValue& value) static bool matchesType(const QJsonValue &value) { return JsonValue<QVector<T>>::matchesType(value); }
{
return JsonValue<QVector<T>>::matchesType(value);
}
static std::vector<T> value(const QJsonValue &value) static std::vector<T> value(const QJsonValue &value)
{ {
@@ -572,10 +467,7 @@ template <class T> struct JsonValue<QMap<QString, T>>
template <class T> struct JsonValue<std::map<std::string, T>> template <class T> struct JsonValue<std::map<std::string, T>>
{ {
static bool matchesType(const QJsonValue& value) static bool matchesType(const QJsonValue &value) { return JsonValue<QMap<QString, T>>::matchesType(value); }
{
return JsonValue<QMap<QString, T>>::matchesType(value);
}
static std::map<std::string, T> value(const QJsonValue &value) static std::map<std::string, T> value(const QJsonValue &value)
{ {
@@ -601,8 +493,7 @@ template <class T> T JsonObject::value(const Key& key) const noexcept(false)
} }
catch (const JsonTypeError &typeError) catch (const JsonTypeError &typeError)
{ {
throw JsonTypeError(std::string(typeError.what()) + throw JsonTypeError(std::string(typeError.what()) + " - key: " + static_cast<const QString &>(key).toStdString());
" - key: " + static_cast<const QString&>(key).toStdString());
} }
} }
@@ -6,10 +6,10 @@
namespace LtsUtils namespace LtsUtils
{ {
LtsTranslatableIdentifier::LtsTranslatableIdentifier(const QString& identifier, const QObject* context, LtsTranslatableIdentifier::LtsTranslatableIdentifier(const QString &identifier, const QObject *context, const char *translatableText)
const char* translatableText) : m_identifier(identifier)
: m_identifier(identifier), m_translationContext(context->metaObject()->className()), , m_translationContext(context->metaObject()->className())
m_translatableText(translatableText) , m_translatableText(translatableText)
{ {
} }
@@ -10,21 +10,19 @@ namespace LtsUtils
class LTSUTILSCORE_EXPORT LtsTranslatableIdentifier class LTSUTILSCORE_EXPORT LtsTranslatableIdentifier
{ {
public: public:
LtsTranslatableIdentifier() : m_translationContext(nullptr), m_translatableText("") {} LtsTranslatableIdentifier()
: m_translationContext(nullptr)
, m_translatableText("")
{
}
LtsTranslatableIdentifier(const QString &identifier, const QObject *context, const char *translatableText); LtsTranslatableIdentifier(const QString &identifier, const QObject *context, const char *translatableText);
const QString& identifier() const const QString &identifier() const { return m_identifier; }
{
return m_identifier;
}
const QString translatedText(const char *disambiguation = nullptr, int n = -1) const; const QString translatedText(const char *disambiguation = nullptr, int n = -1) const;
const QString _context() const const QString _context() const { return QString::fromUtf8(m_translationContext); }
{
return QString::fromUtf8(m_translationContext);
}
private: private:
QString m_identifier; QString m_identifier;
@@ -33,9 +33,7 @@ template <> LTSUTILSCORE_EXPORT QString BigintArray::toPgString() const
return convertToPgString(m_data); return convertToPgString(m_data);
} }
template <typename T> template <typename T> static inline T convertFromPgString(const QString &str, const std::function<typename T::Type(QStringView val, bool *bOk)> &convertFunc)
static inline T convertFromPgString(const QString& str,
const std::function<typename T::Type(QStringView val, bool* bOk)>& convertFunc)
{ {
typename T::ContainerType result; typename T::ContainerType result;
@@ -71,8 +69,7 @@ template <> LTSUTILSCORE_EXPORT IntArray IntArray::fromPgString(const QString& s
template <> LTSUTILSCORE_EXPORT BigintArray BigintArray::fromPgString(const QString &str) template <> LTSUTILSCORE_EXPORT BigintArray BigintArray::fromPgString(const QString &str)
{ {
return convertFromPgString<BigintArray>(str, return convertFromPgString<BigintArray>(str, [](QStringView val, bool *bOk) { return val.toString().toLongLong(bOk); });
[](QStringView val, bool* bOk) { return val.toString().toLongLong(bOk); });
} }
template <typename T> static inline QString convertToPgString(const std::map<T, T> &data) template <typename T> static inline QString convertToPgString(const std::map<T, T> &data)
@@ -82,8 +79,7 @@ template <typename T> static inline QString convertToPgString(const std::map<T,
QString ret(QLatin1Char('{')); QString ret(QLatin1Char('{'));
for (const auto &it : data) for (const auto &it : data)
{ {
ret += QLatin1Char('{') + QString::number(it.first) + QLatin1Char(',') + QString::number(it.second) + ret += QLatin1Char('{') + QString::number(it.first) + QLatin1Char(',') + QString::number(it.second) + QLatin1String("},");
QLatin1String("},");
} }
ret.chop(1); ret.chop(1);
ret += QLatin1Char('}'); ret += QLatin1Char('}');
@@ -100,9 +96,7 @@ template <> LTSUTILSCORE_EXPORT QString BigintArray2D::toPgString() const
return convertToPgString<BigintArray2D::Type>(m_data); return convertToPgString<BigintArray2D::Type>(m_data);
} }
template <typename T> template <typename T> static inline T convertFromPgString2D(const QString &str, const std::function<typename T::Type(QStringView val)> &convertFunc)
static inline T convertFromPgString2D(const QString& str,
const std::function<typename T::Type(QStringView val)>& convertFunc)
{ {
typename T::ContainerType ret; typename T::ContainerType ret;
int idxStart = str.indexOf(QLatin1Char('{')); int idxStart = str.indexOf(QLatin1Char('{'));
@@ -17,13 +17,13 @@ template <typename T, typename C> class PgArray
PgArray() = default; PgArray() = default;
Q_DECL_CONSTEXPR explicit PgArray(const C& data) : m_data(data) {} Q_DECL_CONSTEXPR explicit PgArray(const C &data)
: m_data(data)
Q_DECL_CONSTEXPR C operator()() const
{ {
return m_data;
} }
Q_DECL_CONSTEXPR C operator()() const { return m_data; }
[[nodiscard]] QString toPgString() const; [[nodiscard]] QString toPgString() const;
static PgArray fromPgString(const QString &str); static PgArray fromPgString(const QString &str);
@@ -8,7 +8,11 @@ namespace LtsUtils
{ {
Promise::Promise(const std::function<void(ResultFunction resolve, ResultFunction reject)> &function, QObject *parent) Promise::Promise(const std::function<void(ResultFunction resolve, ResultFunction reject)> &function, QObject *parent)
: QObject(parent), m_functionAlreadySet(false), m_timeout(new QTimer(this)), m_resultSet(false), m_timeoutSet(false) : QObject(parent)
, m_functionAlreadySet(false)
, m_timeout(new QTimer(this))
, m_resultSet(false)
, m_timeoutSet(false)
{ {
m_timeout->setSingleShot(true); m_timeout->setSingleShot(true);
connect(m_timeout, &QTimer::timeout, this, &Promise::slotTimeout); connect(m_timeout, &QTimer::timeout, this, &Promise::slotTimeout);
@@ -25,9 +29,7 @@ void Promise::setFunction(const std::function<void(ResultFunction resolve, Resul
if (m_timeoutSet) if (m_timeoutSet)
m_timeout->start(); m_timeout->start();
QTimer::singleShot(0, this, [this, function]() { QTimer::singleShot(0, this, [this, function]() { function([this](const QVariant &value) { resolve(value); }, [this](const QVariant &value) { reject(value); }); });
function([this](const QVariant& value) { resolve(value); }, [this](const QVariant& value) { reject(value); });
});
} }
void Promise::setTimeout(int interval) void Promise::setTimeout(int interval)
@@ -18,8 +18,7 @@ class LTSUTILSCORE_EXPORT Promise : public QObject
Q_OBJECT Q_OBJECT
public: public:
Promise(const std::function<void(ResultFunction resolve, ResultFunction reject)>& function, Promise(const std::function<void(ResultFunction resolve, ResultFunction reject)> &function, QObject *parent = nullptr);
QObject* parent = nullptr);
void setFunction(const std::function<void(ResultFunction resolve, ResultFunction reject)> &function); void setFunction(const std::function<void(ResultFunction resolve, ResultFunction reject)> &function);
@@ -19,13 +19,20 @@ void PromiseExample1_Class::doSomethingAsync2()
QTimer::singleShot(450, this, [this]() { emit signalDone2(true, 1234); }); QTimer::singleShot(450, this, [this]() { emit signalDone2(true, 1234); });
} }
PromiseExample1::PromiseExample1(QObject* parent) : QObject(parent), m_success(false) PromiseExample1::PromiseExample1(QObject *parent)
: QObject(parent)
, m_success(false)
{ {
auto func = [this](ResultFunction resolve, ResultFunction reject) { auto func = [this](ResultFunction resolve, ResultFunction reject)
{
PromiseExample1_Class *c = new PromiseExample1_Class(this); PromiseExample1_Class *c = new PromiseExample1_Class(this);
connect(c, &PromiseExample1_Class::signalDone1, this, [this, c, resolve, reject](bool didThisWork) { connect(c,
&PromiseExample1_Class::signalDone1,
this,
[this, c, resolve, reject](bool didThisWork)
{
if (!didThisWork) if (!didThisWork)
{ {
@@ -35,8 +42,11 @@ PromiseExample1::PromiseExample1(QObject* parent) : QObject(parent), m_success(f
else else
{ {
connect(c, &PromiseExample1_Class::signalDone2, this, connect(c,
[resolve, reject](bool didThisWork, int someNumberThatReturns) { &PromiseExample1_Class::signalDone2,
this,
[resolve, reject](bool didThisWork, int someNumberThatReturns)
{
if (didThisWork) if (didThisWork)
resolve(someNumberThatReturns); resolve(someNumberThatReturns);
else else
@@ -51,14 +61,19 @@ PromiseExample1::PromiseExample1(QObject* parent) : QObject(parent), m_success(f
}; };
Promise *p = new Promise(func, this); Promise *p = new Promise(func, this);
p->resolved([this](const QVariant& value) { p->resolved(
[this](const QVariant &value)
{
qDebug() << "example1 promise succeeded! 'someNumberThatReturns' was" << value; qDebug() << "example1 promise succeeded! 'someNumberThatReturns' was" << value;
m_success = true; m_success = true;
}).rejected([](const QVariant& value) { qDebug() << "example1 promise failed.." << value; }); })
.rejected([](const QVariant &value) { qDebug() << "example1 promise failed.." << value; });
} }
PromiseExample2::PromiseExample2(QObject* parent) : QObject(parent), m_success(false) PromiseExample2::PromiseExample2(QObject *parent)
: QObject(parent)
, m_success(false)
{ {
Promise* p = new Promise( Promise* p = new Promise(
@@ -71,14 +86,19 @@ PromiseExample2::PromiseExample2(QObject* parent) : QObject(parent), m_success(f
p->resolved([](const QVariant &) { QFAIL("This test case's promise should never resolve"); }); p->resolved([](const QVariant &) { QFAIL("This test case's promise should never resolve"); });
p->rejected([this](const QVariant& val) { p->rejected(
[this](const QVariant &val)
{
QVERIFY2(val == QStringLiteral("timeout"), "Promise didn't reject with string \"timeout\""); QVERIFY2(val == QStringLiteral("timeout"), "Promise didn't reject with string \"timeout\"");
qDebug() << "Promise rejected as expected"; qDebug() << "Promise rejected as expected";
m_success = true; m_success = true;
}); });
} }
PromiseExample3::PromiseExample3(QObject* parent) : QObject(parent), m_success(true), m_alreadyRejected(false) PromiseExample3::PromiseExample3(QObject *parent)
: QObject(parent)
, m_success(true)
, m_alreadyRejected(false)
{ {
Promise *p = new Promise([](ResultFunction, ResultFunction reject) { reject(QString()); }, this); Promise *p = new Promise([](ResultFunction, ResultFunction reject) { reject(QString()); }, this);
@@ -87,7 +107,9 @@ PromiseExample3::PromiseExample3(QObject* parent) : QObject(parent), m_success(t
p->resolved([](const QVariant &) { QFAIL("This test case's promise should never resolve"); }); p->resolved([](const QVariant &) { QFAIL("This test case's promise should never resolve"); });
p->rejected([this](const QVariant& val) { p->rejected(
[this](const QVariant &val)
{
qDebug() << "rejected with val" << val; qDebug() << "rejected with val" << val;
QVERIFY2(val == QString(), "Promise didn't reject with an expected empty string."); QVERIFY2(val == QString(), "Promise didn't reject with an expected empty string.");
QVERIFY2(!m_alreadyRejected, "Promise rejected more than once"); QVERIFY2(!m_alreadyRejected, "Promise rejected more than once");
@@ -25,10 +25,7 @@ class PromiseExample1 : public QObject
public: public:
explicit PromiseExample1(QObject *parent = nullptr); explicit PromiseExample1(QObject *parent = nullptr);
[[nodiscard]] bool isSuccess() const [[nodiscard]] bool isSuccess() const { return m_success; }
{
return m_success;
}
private: private:
bool m_success; bool m_success;
@@ -40,10 +37,7 @@ class PromiseExample2 : public QObject
public: public:
explicit PromiseExample2(QObject *parent = nullptr); explicit PromiseExample2(QObject *parent = nullptr);
[[nodiscard]] bool isSuccess() const [[nodiscard]] bool isSuccess() const { return m_success; }
{
return m_success;
}
private: private:
bool m_success; bool m_success;
@@ -55,10 +49,7 @@ class PromiseExample3 : public QObject
public: public:
explicit PromiseExample3(QObject *parent = nullptr); explicit PromiseExample3(QObject *parent = nullptr);
[[nodiscard]] bool isSuccess() const [[nodiscard]] bool isSuccess() const { return m_success; }
{
return m_success;
}
private: private:
bool m_success; bool m_success;
@@ -23,7 +23,8 @@ template <typename T> void inline set8Byte(const T in, QByteArray& out)
template <> void inline set8Byte(const double in, QByteArray &out) template <> void inline set8Byte(const double in, QByteArray &out)
{ {
union hack { union hack
{
double d; double d;
int64_t i; int64_t i;
} h; } h;
@@ -64,7 +65,8 @@ template <> bool inline get8Byte(const QByteArray& baData, size_t& pos, double&
{ {
out = 0.; out = 0.;
union hack { union hack
{
double d; double d;
int64_t i; int64_t i;
} h; } h;
@@ -6,7 +6,9 @@ namespace LtsUtils
{ {
QPlane3D::QPlane3D(const QPoint3D &pos, const QPoint3D &vec1, const QPoint3D &vec2) QPlane3D::QPlane3D(const QPoint3D &pos, const QPoint3D &vec1, const QPoint3D &vec2)
: m_pos(pos), m_vec1(vec1), m_vec2(vec2) : m_pos(pos)
, m_vec1(vec1)
, m_vec2(vec2)
{ {
m_normal = QPoint3D::crossProduct(m_vec1, m_vec2); m_normal = QPoint3D::crossProduct(m_vec1, m_vec2);
m_planeC = QPoint3D::dotProduct(m_pos, m_normal); m_planeC = QPoint3D::dotProduct(m_pos, m_normal);
@@ -44,7 +46,8 @@ double QPlane3D::distanceTo(const QPoint3D& point) const
} }
QPolygon3D::QPolygon3D(const QVector<QPoint3D> &vertices) QPolygon3D::QPolygon3D(const QVector<QPoint3D> &vertices)
: QPlane3D(vertices[0], vertices[1], vertices[2]), m_vertices(vertices) : QPlane3D(vertices[0], vertices[1], vertices[2])
, m_vertices(vertices)
{ {
} }
@@ -23,30 +23,15 @@ class LTSUTILSCORE_EXPORT QPlane3D
bool inPlane(const QPoint3D &point) const; bool inPlane(const QPoint3D &point) const;
double distanceTo(const QPoint3D &point) const; double distanceTo(const QPoint3D &point) const;
const QPoint3D& pos() const const QPoint3D &pos() const { return m_pos; }
{
return m_pos;
}
const QPoint3D& vec1() const const QPoint3D &vec1() const { return m_vec1; }
{
return m_vec1;
}
const QPoint3D& vec2() const const QPoint3D &vec2() const { return m_vec2; }
{
return m_vec2;
}
const QPoint3D& normal() const const QPoint3D &normal() const { return m_normal; }
{
return m_normal;
}
double planeC() const double planeC() const { return m_planeC; }
{
return m_planeC;
}
protected: protected:
QPoint3D m_pos; QPoint3D m_pos;
@@ -62,10 +47,7 @@ class LTSUTILSCORE_EXPORT QPolygon3D : public QPlane3D
public: public:
QPolygon3D(const QVector<QPoint3D> &vertices); QPolygon3D(const QVector<QPoint3D> &vertices);
bool contains(const QPoint3D& point) const bool contains(const QPoint3D &point) const { return m_vertices.contains(point); }
{
return m_vertices.contains(point);
}
bool containsPoint(const QPoint3D &point) const; bool containsPoint(const QPoint3D &point) const;
@@ -16,12 +16,21 @@ namespace LtsUtils
class QPoint3D class QPoint3D
{ {
public: public:
enum class Axis { X, Y, Z }; enum class Axis
{
X,
Y,
Z
};
constexpr QPoint3D() = default; constexpr QPoint3D() = default;
constexpr QPoint3D(double xpos, double ypos, double zpos); constexpr QPoint3D(double xpos, double ypos, double zpos);
template <typename T> explicit QPoint3D(const T& data) : xp(data.offsetX()), yp(data.offsetY()), zp(data.offsetZ()) template <typename T>
explicit QPoint3D(const T &data)
: xp(data.offsetX())
, yp(data.offsetY())
, zp(data.offsetZ())
{ {
} }
@@ -40,20 +49,11 @@ class QPoint3D
constexpr inline QPointF toPointF() const; constexpr inline QPointF toPointF() const;
static QPoint3D fromQPointF(const QPointF& p) static QPoint3D fromQPointF(const QPointF &p) { return QPoint3D(p.x(), p.y(), .0); }
{
return QPoint3D(p.x(), p.y(), .0);
}
inline double lengthSquared() const inline double lengthSquared() const { return (xp * xp) + (yp * yp) + (zp * zp); }
{
return (xp * xp) + (yp * yp) + (zp * zp);
}
inline double length() const inline double length() const { return std::sqrt(lengthSquared()); }
{
return std::sqrt(lengthSquared());
}
inline void normalize() inline void normalize()
{ {
@@ -85,21 +85,24 @@ class QPoint3D
const double cos = std::cos(phi); const double cos = std::cos(phi);
switch (axis) switch (axis)
{ {
case Axis::X: { case Axis::X:
{
const double _yp = (cos * yp) - (sin * zp); const double _yp = (cos * yp) - (sin * zp);
const double _zp = (sin * yp) + (cos * zp); const double _zp = (sin * yp) + (cos * zp);
yp = _yp; yp = _yp;
zp = _zp; zp = _zp;
break; break;
} }
case Axis::Y: { case Axis::Y:
{
const double _xp = (cos * xp) + (sin * zp); const double _xp = (cos * xp) + (sin * zp);
const double _zp = (-sin * xp) + (cos * zp); const double _zp = (-sin * xp) + (cos * zp);
xp = _xp; xp = _xp;
zp = _zp; zp = _zp;
break; break;
} }
case Axis::Z: { case Axis::Z:
{
const double _xp = (cos * xp) - (sin * yp); const double _xp = (cos * xp) - (sin * yp);
const double _yp = (sin * xp) + (cos * yp); const double _yp = (sin * xp) + (cos * yp);
xp = _xp; xp = _xp;
@@ -123,47 +126,26 @@ class QPoint3D
QPoint3D p = point + dotProduct(*this - point, direction) * direction; QPoint3D p = point + dotProduct(*this - point, direction) * direction;
return (*this - p).length(); return (*this - p).length();
} }
inline double distanceToPlane(const QPoint3D& plane, const QPoint3D& normal) const inline double distanceToPlane(const QPoint3D &plane, const QPoint3D &normal) const { return dotProduct(*this - plane, normal); }
{
return dotProduct(*this - plane, normal);
}
inline double distanceToPlane(const QPoint3D &plane1, const QPoint3D &plane2, const QPoint3D &plane3) const inline double distanceToPlane(const QPoint3D &plane1, const QPoint3D &plane2, const QPoint3D &plane3) const
{ {
QPoint3D n = normal(plane2 - plane1, plane3 - plane1); QPoint3D n = normal(plane2 - plane1, plane3 - plane1);
return dotProduct(*this - plane1, n); return dotProduct(*this - plane1, n);
} }
inline double distanceToPoint(const QPoint3D& point) const inline double distanceToPoint(const QPoint3D &point) const { return (*this - point).length(); }
{
return (*this - point).length();
}
friend constexpr inline bool operator==(const QPoint3D &p1, const QPoint3D &p2); friend constexpr inline bool operator==(const QPoint3D &p1, const QPoint3D &p2);
friend constexpr inline bool operator!=(const QPoint3D &p1, const QPoint3D &p2); friend constexpr inline bool operator!=(const QPoint3D &p1, const QPoint3D &p2);
friend constexpr inline QPoint3D operator+(const QPoint3D& p1, const QPoint3D& p2) friend constexpr inline QPoint3D operator+(const QPoint3D &p1, const QPoint3D &p2) { return QPoint3D(p1.xp + p2.xp, p1.yp + p2.yp, p1.zp + p2.zp); }
{
return QPoint3D(p1.xp + p2.xp, p1.yp + p2.yp, p1.zp + p2.zp);
}
friend constexpr inline QPoint3D operator-(const QPoint3D& p1, const QPoint3D& p2) friend constexpr inline QPoint3D operator-(const QPoint3D &p1, const QPoint3D &p2) { return QPoint3D(p1.xp - p2.xp, p1.yp - p2.yp, p1.zp - p2.zp); }
{
return QPoint3D(p1.xp - p2.xp, p1.yp - p2.yp, p1.zp - p2.zp);
}
friend constexpr inline QPoint3D operator*(const QPoint3D& p1, double factor) friend constexpr inline QPoint3D operator*(const QPoint3D &p1, double factor) { return QPoint3D(p1.xp * factor, p1.yp * factor, p1.zp * factor); }
{
return QPoint3D(p1.xp * factor, p1.yp * factor, p1.zp * factor);
}
friend constexpr inline QPoint3D operator*(double factor, const QPoint3D& p1) friend constexpr inline QPoint3D operator*(double factor, const QPoint3D &p1) { return QPoint3D(p1.xp * factor, p1.yp * factor, p1.zp * factor); }
{
return QPoint3D(p1.xp * factor, p1.yp * factor, p1.zp * factor);
}
friend constexpr inline QPoint3D operator/(const QPoint3D& p1, double factor) friend constexpr inline QPoint3D operator/(const QPoint3D &p1, double factor) { return QPoint3D(p1.xp / factor, p1.yp / factor, p1.zp / factor); }
{
return QPoint3D(p1.xp / factor, p1.yp / factor, p1.zp / factor);
}
constexpr inline QPoint3D &operator+=(const QPoint3D &o) constexpr inline QPoint3D &operator+=(const QPoint3D &o)
{ {
@@ -197,25 +179,16 @@ class QPoint3D
return *this; return *this;
} }
constexpr static inline double dotProduct(const QPoint3D& v1, const QPoint3D& v2) constexpr static inline double dotProduct(const QPoint3D &v1, const QPoint3D &v2) { return v1.xp * v2.xp + v1.yp * v2.yp + v1.zp * v2.zp; }
{
return v1.xp * v2.xp + v1.yp * v2.yp + v1.zp * v2.zp;
}
constexpr static inline QPoint3D crossProduct(const QPoint3D &v1, const QPoint3D &v2) constexpr static inline QPoint3D crossProduct(const QPoint3D &v1, const QPoint3D &v2)
{ {
return QPoint3D(v1.yp * v2.zp - v1.zp * v2.yp, v1.zp * v2.xp - v1.xp * v2.zp, v1.xp * v2.yp - v1.yp * v2.xp); return QPoint3D(v1.yp * v2.zp - v1.zp * v2.yp, v1.zp * v2.xp - v1.xp * v2.zp, v1.xp * v2.yp - v1.yp * v2.xp);
} }
static inline QPoint3D normal(const QPoint3D& v1, const QPoint3D& v2) static inline QPoint3D normal(const QPoint3D &v1, const QPoint3D &v2) { return crossProduct(v1, v2).normalized(); }
{
return crossProduct(v1, v2).normalized();
}
static inline QPoint3D normal(const QPoint3D& v1, const QPoint3D& v2, const QPoint3D& v3) static inline QPoint3D normal(const QPoint3D &v1, const QPoint3D &v2, const QPoint3D &v3) { return crossProduct((v2 - v1), (v3 - v1)).normalized(); }
{
return crossProduct((v2 - v1), (v3 - v1)).normalized();
}
friend inline bool qFuzzyCompare(const QPoint3D &v1, const QPoint3D &v2) friend inline bool qFuzzyCompare(const QPoint3D &v1, const QPoint3D &v2)
{ {
@@ -231,7 +204,12 @@ class QPoint3D
// QDataStream& operator<<(QDataStream& s, const QPoint3D& p); // QDataStream& operator<<(QDataStream& s, const QPoint3D& p);
// QDataStream& operator>>(QDataStream& s, QPoint3D& p); // QDataStream& operator>>(QDataStream& s, QPoint3D& p);
constexpr inline QPoint3D::QPoint3D(double xpos, double ypos, double zpos) : xp(xpos), yp(ypos), zp(zpos) {} constexpr inline QPoint3D::QPoint3D(double xpos, double ypos, double zpos)
: xp(xpos)
, yp(ypos)
, zp(zpos)
{
}
inline bool QPoint3D::isNull() const inline bool QPoint3D::isNull() const
{ {
@@ -7,7 +7,8 @@
namespace LtsUtils namespace LtsUtils
{ {
ScopedConnection::ScopedConnection(IConnection* connection, Qt::ConnectionType connType) : m_conn(connection) ScopedConnection::ScopedConnection(IConnection *connection, Qt::ConnectionType connType)
: m_conn(connection)
{ {
Q_ASSERT(connection); Q_ASSERT(connection);
m_conn->connect(connType); m_conn->connect(connType);
@@ -12,40 +12,19 @@ namespace LtsUtils
class LTSUTILSCORE_EXPORT SfmMessage class LTSUTILSCORE_EXPORT SfmMessage
{ {
public: public:
unsigned int id() const unsigned int id() const { return m_id; }
{
return m_id;
}
void setId(unsigned int id) void setId(unsigned int id) { m_id = id; }
{
m_id = id;
}
bool rtr() const bool rtr() const { return m_rtr; }
{
return m_rtr;
}
void setRtr(bool rtr) void setRtr(bool rtr) { m_rtr = rtr; }
{
m_rtr = rtr;
}
QByteArray payload() const QByteArray payload() const { return m_payload; }
{
return m_payload;
}
void setPayload(const QByteArray& payload) void setPayload(const QByteArray &payload) { m_payload = payload; }
{
m_payload = payload;
}
bool operator==(const SfmMessage& msg) const bool operator==(const SfmMessage &msg) const { return (m_id == msg.id() && m_rtr == msg.rtr() && m_payload == msg.payload()); }
{
return (m_id == msg.id() && m_rtr == msg.rtr() && m_payload == msg.payload());
}
protected: protected:
unsigned int m_id = 0; unsigned int m_id = 0;
@@ -12,8 +12,7 @@ int ConnectingDialog::s_waitForHistoricalDataWaitTime = 10000;
void ConnectingDialog::reset() void ConnectingDialog::reset()
{ {
m_ui->label->setText(QStringLiteral("<font color='orange'>%1</font>") m_ui->label->setText(QStringLiteral("<font color='orange'>%1</font>").arg(tr("Connecting to %1 on %2 ...").arg(m_serviceName, m_exerciseName)));
.arg(tr("Connecting to %1 on %2 ...").arg(m_serviceName, m_exerciseName)));
} }
void ConnectingDialog::setup() void ConnectingDialog::setup()
@@ -22,7 +21,11 @@ void ConnectingDialog::setup()
m_ui->setupUi(this); m_ui->setupUi(this);
reset(); reset();
setMinimumSize(sizeHint()); setMinimumSize(sizeHint());
connect(m_ui->pbRetry, &QPushButton::clicked, this, [this]() { connect(m_ui->pbRetry,
&QPushButton::clicked,
this,
[this]()
{
m_ui->pbRetry->setEnabled(false); m_ui->pbRetry->setEnabled(false);
m_ui->pbIgnore->setEnabled(false); m_ui->pbIgnore->setEnabled(false);
@@ -30,7 +33,11 @@ void ConnectingDialog::setup()
emit signalStopLoop(); emit signalStopLoop();
}); });
connect(m_ui->pbIgnore, &QPushButton::clicked, this, [this]() { connect(m_ui->pbIgnore,
&QPushButton::clicked,
this,
[this]()
{
m_ui->pbIgnore->setEnabled(false); m_ui->pbIgnore->setEnabled(false);
m_ui->pbRetry->setEnabled(false); m_ui->pbRetry->setEnabled(false);
m_ui->pbIgnore->setText(tr("continuing..")); m_ui->pbIgnore->setText(tr("continuing.."));
@@ -47,8 +54,7 @@ ConnectingDialog::~ConnectingDialog()
void ConnectingDialog::failed() void ConnectingDialog::failed()
{ {
m_ui->label->setText(QStringLiteral("<font color='red'>%1</font>") m_ui->label->setText(QStringLiteral("<font color='red'>%1</font>").arg(tr("Could not connect to %1 on %2 !").arg(m_serviceName, m_exerciseName)));
.arg(tr("Could not connect to %1 on %2 !").arg(m_serviceName, m_exerciseName)));
m_ui->pbRetry->setEnabled(true); m_ui->pbRetry->setEnabled(true);
m_ui->pbIgnore->setEnabled(true); m_ui->pbIgnore->setEnabled(true);
@@ -25,10 +25,15 @@ class LTSUTILSGUICONNECTDIALOG_EXPORT ConnectingDialog : public LtsWidgets::LtsF
static int s_waitForHistoricalDataWaitTime; static int s_waitForHistoricalDataWaitTime;
template <typename DtcType, typename WaitForHistoricalDataFunction> template <typename DtcType, typename WaitForHistoricalDataFunction>
explicit ConnectingDialog(DtcType dtc, WaitForHistoricalDataFunction waitForHistoricalDataFunction, explicit ConnectingDialog(DtcType dtc,
const QString& serviceName, const QString& exerciseName, QWidget* parent = nullptr) WaitForHistoricalDataFunction waitForHistoricalDataFunction,
: LtsWidgets::LtsFramelessDialog(parent, LtsWidgets::Behaviour::Modal), m_serviceName(serviceName), const QString &serviceName,
m_exerciseName(exerciseName), m_ui(nullptr) const QString &exerciseName,
QWidget *parent = nullptr)
: LtsWidgets::LtsFramelessDialog(parent, LtsWidgets::Behaviour::Modal)
, m_serviceName(serviceName)
, m_exerciseName(exerciseName)
, m_ui(nullptr)
{ {
setWindowTitle(tr("Connecting ..")); setWindowTitle(tr("Connecting .."));
setup(); setup();
@@ -12,16 +12,23 @@
namespace LtsUtils namespace LtsUtils
{ {
ConnectingDialogNT::ConnectingDialogNT(const std::function<bool(int)>& checkFn, const QString& serviceName, ConnectingDialogNT::ConnectingDialogNT(const std::function<bool(int)> &checkFn, const QString &serviceName, const QString &exerciseName, QWidget *parent)
const QString& exerciseName, QWidget* parent) : LtsWidgets::LtsFramelessDialog(parent, LtsWidgets::Behaviour::Modal)
: LtsWidgets::LtsFramelessDialog(parent, LtsWidgets::Behaviour::Modal), m_serviceName(serviceName), , m_serviceName(serviceName)
m_exerciseName(exerciseName), m_checkFn(checkFn), m_go(false), m_autoRetryTimer(new QTimer(this)), , m_exerciseName(exerciseName)
m_ui(new Ui::ConnectingDialog) , m_checkFn(checkFn)
, m_go(false)
, m_autoRetryTimer(new QTimer(this))
, m_ui(new Ui::ConnectingDialog)
{ {
m_ui->setupUi(this); m_ui->setupUi(this);
m_autoRetryTimer->setInterval(1000); m_autoRetryTimer->setInterval(1000);
connect(m_autoRetryTimer, &QTimer::timeout, this, [this]() { connect(m_autoRetryTimer,
&QTimer::timeout,
this,
[this]()
{
if (m_autoRetryTick < 1) if (m_autoRetryTick < 1)
{ {
slotRetry(); slotRetry();
@@ -36,7 +43,11 @@ ConnectingDialogNT::ConnectingDialogNT(const std::function<bool(int)>& checkFn,
setMinimumSize(sizeHint()); setMinimumSize(sizeHint());
connect(m_ui->pbRetry, &QPushButton::clicked, this, &ConnectingDialogNT::slotRetry); connect(m_ui->pbRetry, &QPushButton::clicked, this, &ConnectingDialogNT::slotRetry);
connect(m_ui->pbIgnore, &QPushButton::clicked, this, [this]() { connect(m_ui->pbIgnore,
&QPushButton::clicked,
this,
[this]()
{
m_ui->pbIgnore->setEnabled(false); m_ui->pbIgnore->setEnabled(false);
m_ui->pbRetry->setEnabled(false); m_ui->pbRetry->setEnabled(false);
m_ui->pbIgnore->setText(tr("continuing..")); m_ui->pbIgnore->setText(tr("continuing.."));
@@ -103,8 +114,7 @@ void ConnectingDialogNT::slotGo()
void ConnectingDialogNT::reset() void ConnectingDialogNT::reset()
{ {
m_ui->label->setText(QStringLiteral("<font color='orange'>%1</font>") m_ui->label->setText(QStringLiteral("<font color='orange'>%1</font>").arg(tr("Connecting to %1 on %2 ...").arg(m_serviceName, m_exerciseName)));
.arg(tr("Connecting to %1 on %2 ...").arg(m_serviceName, m_exerciseName)));
} }
ConnectingDialogNT::~ConnectingDialogNT() ConnectingDialogNT::~ConnectingDialogNT()
@@ -114,8 +124,7 @@ ConnectingDialogNT::~ConnectingDialogNT()
void ConnectingDialogNT::failed() void ConnectingDialogNT::failed()
{ {
m_ui->label->setText(QStringLiteral("<font color='red'>%1</font>") m_ui->label->setText(QStringLiteral("<font color='red'>%1</font>").arg(tr("Could not connect to %1 on %2 !").arg(m_serviceName, m_exerciseName)));
.arg(tr("Could not connect to %1 on %2 !").arg(m_serviceName, m_exerciseName)));
m_ui->pbRetry->setEnabled(true); m_ui->pbRetry->setEnabled(true);
m_ui->pbIgnore->setEnabled(true); m_ui->pbIgnore->setEnabled(true);
@@ -22,8 +22,7 @@ class LTSUTILSGUICONNECTDIALOG_EXPORT ConnectingDialogNT : public LtsWidgets::Lt
Q_OBJECT Q_OBJECT
public: public:
explicit ConnectingDialogNT(const std::function<bool(int)>& checkFn, const QString& serviceName, explicit ConnectingDialogNT(const std::function<bool(int)> &checkFn, const QString &serviceName, const QString &exerciseName, QWidget *parent);
const QString& exerciseName, QWidget* parent);
~ConnectingDialogNT(); ~ConnectingDialogNT();
void failed(); void failed();
@@ -45,9 +45,6 @@ if(QT6_GUI_AVAILABLE)
Qt6::Svg Qt6::Svg
) )
endif() endif()
IF(BUILD_RTI)
TARGET_LINK_LIBRARIES(LtsUtilsGuiDds PUBLIC ddscore)
ENDIF(BUILD_RTI)
NGL_TARGET_COMPILE_DEFINITIONS(LtsUtilsGuiDds NGL_TARGET_COMPILE_DEFINITIONS(LtsUtilsGuiDds
PUBLIC PUBLIC
REQUEST_HELPER_WITH_GUI REQUEST_HELPER_WITH_GUI
@@ -66,6 +63,3 @@ NGL_TARGET_LINK_LIBRARIES(LtsUtilsDds
PUBLIC PUBLIC
Qt6::Core Qt6::Core
) )
IF(BUILD_RTI)
TARGET_LINK_LIBRARIES(LtsUtilsDds PUBLIC ddscore)
ENDIF(BUILD_RTI)
@@ -20,11 +20,18 @@ namespace LtsUtils
{ {
bool RequestHelper::s_debug = false; bool RequestHelper::s_debug = false;
RequestHelper::RequestHelper(QObject* parent, bool quiet, RequestHelper::RequestHelper(QObject *parent,
bool quiet,
const std::function<void(void)>& success, const std::function<void(void)>& failure) const std::function<void(void)> &success,
: QObject(parent), m_failed(false), m_repliedId(-1), m_quiet(quiet), m_blockingCall(true), m_successFn(success), const std::function<void(void)> &failure)
m_failureFn(failure) : QObject(parent)
, m_failed(false)
, m_repliedId(-1)
, m_quiet(quiet)
, m_blockingCall(true)
, m_successFn(success)
, m_failureFn(failure)
{ {
connect(this, &RequestHelper::signalSuccess, this, m_successFn, Qt::QueuedConnection); connect(this, &RequestHelper::signalSuccess, this, m_successFn, Qt::QueuedConnection);
connect(this, &RequestHelper::signalFailed, this, m_failureFn, Qt::QueuedConnection); connect(this, &RequestHelper::signalFailed, this, m_failureFn, Qt::QueuedConnection);
@@ -45,8 +52,7 @@ RequestHelper::RequestHelper(QObject* parent, bool quiet,
} }
} }
void RequestHelper::addRequest(const std::function<int64_t()>& requestFunction, void RequestHelper::addRequest(const std::function<int64_t()> &requestFunction, const std::function<void(const Core::FunctionReply &baseReply)> &baseReplyHandler)
const std::function<void(const Core::FunctionReply& baseReply)>& baseReplyHandler)
{ {
m_requestFunctions.append(RequestFunctionContainer(requestFunction, baseReplyHandler)); m_requestFunctions.append(RequestFunctionContainer(requestFunction, baseReplyHandler));
} }
@@ -75,13 +81,11 @@ bool RequestHelper::_requestReply(const Core::FunctionReplyObject& fro, const Co
{ {
if (m_blockingCall) if (m_blockingCall)
{ {
LtsWidgets::LtsMessageDialog::showMessage(qobject_cast<QWidget*>(parent()), m_errorString, LtsWidgets::LtsMessageDialog::showMessage(qobject_cast<QWidget *>(parent()), m_errorString, tr("Request failed"));
tr("Request failed"));
} }
else else
{ {
new LtsWidgets::LtsMessageDialogNew(qobject_cast<QWidget*>(parent()), m_errorString, new LtsWidgets::LtsMessageDialogNew(qobject_cast<QWidget *>(parent()), m_errorString, tr("Request failed"));
tr("Request failed"));
} }
} }
} }
@@ -94,8 +98,7 @@ bool RequestHelper::_requestReply(const Core::FunctionReplyObject& fro, const Co
if (baseReply) if (baseReply)
m_singleRequestCustomFunctionReply(*baseReply); m_singleRequestCustomFunctionReply(*baseReply);
else else
m_singleRequestCustomFunctionReply( m_singleRequestCustomFunctionReply(Core::FunctionReply(fro.id(), fro.str(), fro.args(), fro.additionalInfo()));
Core::FunctionReply(fro.id(), fro.str(), fro.args(), fro.additionalInfo()));
} }
if (fro.error()) if (fro.error())
@@ -108,8 +111,7 @@ bool RequestHelper::_requestReply(const Core::FunctionReplyObject& fro, const Co
return true; return true;
} }
bool RequestHelper::startSingleRequest( bool RequestHelper::startSingleRequest(const std::function<int64_t()> &requestFunction,
const std::function<int64_t()>& requestFunction,
const std::function<void(const Core::FunctionReply &baseReply)> &baseReplyHandler) const std::function<void(const Core::FunctionReply &baseReply)> &baseReplyHandler)
{ {
addRequest(requestFunction, baseReplyHandler); addRequest(requestFunction, baseReplyHandler);
@@ -171,7 +173,9 @@ void RequestHelper::slotNextRequest()
else else
{ {
connect(new LtsWidgets::LtsMessageDialogNew(qobject_cast<QWidget *>(parent()), tr("Request failed")), connect(new LtsWidgets::LtsMessageDialogNew(qobject_cast<QWidget *>(parent()), tr("Request failed")),
&LtsWidgets::LtsMessageDialogNew::destroyed, this, [this]() { failure(); }); &LtsWidgets::LtsMessageDialogNew::destroyed,
this,
[this]() { failure(); });
return; return;
} }
@@ -181,8 +185,7 @@ void RequestHelper::slotNextRequest()
} }
} }
void RequestHelper::startSingleBackgroundRequest( void RequestHelper::startSingleBackgroundRequest(const std::function<int64_t()> &requestFunction,
const std::function<int64_t()>& requestFunction,
const std::function<void(const Core::FunctionReply &)> &baseReplyHandler) const std::function<void(const Core::FunctionReply &)> &baseReplyHandler)
{ {
m_blockingCall = false; m_blockingCall = false;
@@ -27,14 +27,12 @@
namespace LtsUtils namespace LtsUtils
{ {
template<typename T> template <typename T> dds::core::optional<T> toOptional(T inVal)
dds::core::optional<T> toOptional(T inVal)
{ {
return inVal != T() ? dds::core::optional<T>(inVal) : dds::core::optional<T>(); return inVal != T() ? dds::core::optional<T>(inVal) : dds::core::optional<T>();
} }
template<typename T> template <typename T> dds::core::optional<T> optional()
dds::core::optional<T> optional()
{ {
return dds::core::optional<T>(); return dds::core::optional<T>();
} }
@@ -47,7 +45,9 @@ class LTSUTILSGUIDDS_INTERNAL_EXPORT RequestHelper : public QObject // TODO: DOC
public: public:
static bool s_debug; static bool s_debug;
explicit RequestHelper(QObject *parent = nullptr, bool quiet = false, explicit RequestHelper(
QObject *parent = nullptr,
bool quiet = false,
// for non-blocking // for non-blocking
const std::function<void(void)> &success = []() {}, const std::function<void(void)> &success = []() {},
const std::function<void(void)> &failure = []() {}); const std::function<void(void)> &failure = []() {});
@@ -55,13 +55,13 @@ public:
bool quiet() const { return m_quiet; } bool quiet() const { return m_quiet; }
void setQuiet(bool quiet) { m_quiet = quiet; } void setQuiet(bool quiet) { m_quiet = quiet; }
void addRequest(const std::function<int64_t()> &requestFunction, void addRequest(const std::function<int64_t()> &requestFunction, const std::function<void(const Core::FunctionReply &baseReply)> &baseReplyHandler = nullptr);
const std::function<void(const Core::FunctionReply &baseReply)> &baseReplyHandler = nullptr);
bool startRequests(); // blocks! bool startRequests(); // blocks!
// do not throw a message if this method fails, as this method does this already // blocks! // do not throw a message if this method fails, as this method does this already // blocks!
bool startSingleRequest(const std::function<int64_t(void)> &requestFunction, bool startSingleRequest(const std::function<int64_t(void)> &requestFunction,
const std::function<void(const Core::FunctionReply &baseReply)> &baseReplyHandler = nullptr // for replies that return a custom FunctionReply, which has to be handled >>after successful execution<< const std::function<void(const Core::FunctionReply &baseReply)> &baseReplyHandler =
nullptr // for replies that return a custom FunctionReply, which has to be handled >>after successful execution<<
); );
// non-blocking ! // non-blocking !
@@ -134,7 +134,6 @@ signals:
private slots: private slots:
void slotNextRequest(); void slotNextRequest();
}; };
} // namespace LtsUtils } // namespace LtsUtils
@@ -31,8 +31,7 @@ bool StyleManager::loadStyle(const QString& stylePluginName, bool highDpi)
if (sp == nullptr) if (sp == nullptr)
{ {
qWarning() << "StyleManager::loadStyle: could not unload style plugin - wrong type (" qWarning() << "StyleManager::loadStyle: could not unload style plugin - wrong type (" << pluginInstance->metaObject()->className() << ") - new style not loaded";
<< pluginInstance->metaObject()->className() << ") - new style not loaded";
return false; return false;
} }
@@ -46,8 +45,8 @@ bool StyleManager::loadStyle(const QString& stylePluginName, bool highDpi)
QPluginLoader *stylePluginLoader = nullptr; QPluginLoader *stylePluginLoader = nullptr;
int pluginsLoaded = 0; int pluginsLoaded = 0;
std::function<bool(const LtsPluginManager::PluginInstance& pi)> loadPluginFn = std::function<bool(const LtsPluginManager::PluginInstance &pi)> loadPluginFn = [&stylePluginLoader, &pluginsLoaded](const LtsPluginManager::PluginInstance &pi)
[&stylePluginLoader, &pluginsLoaded](const LtsPluginManager::PluginInstance& pi) { {
stylePluginLoader = pi.pluginLoader; stylePluginLoader = pi.pluginLoader;
pluginsLoaded++; pluginsLoaded++;
return true; return true;
@@ -61,15 +60,13 @@ bool StyleManager::loadStyle(const QString& stylePluginName, bool highDpi)
if (pluginsLoaded == 0) if (pluginsLoaded == 0)
{ {
qWarning() << "StyleManager::loadStyle: Could not find Style Plugin" << stylePluginName qWarning() << "StyleManager::loadStyle: Could not find Style Plugin" << stylePluginName << "- using default Qt style";
<< "- using default Qt style";
return false; return false;
} }
if (pluginsLoaded > 1) if (pluginsLoaded > 1)
{ {
qWarning() << "StyleManager::loadStyle: Style Plugin" << stylePluginName qWarning() << "StyleManager::loadStyle: Style Plugin" << stylePluginName << " is ambiguous - using default Qt style";
<< " is ambiguous - using default Qt style";
return false; return false;
} }
@@ -83,8 +80,8 @@ bool StyleManager::loadStyle(const QString& stylePluginName, bool highDpi)
if (sp == nullptr) if (sp == nullptr)
{ {
qWarning() << "StyleManager::loadStyle: could not load style plugin - wrong type (" qWarning() << "StyleManager::loadStyle: could not load style plugin - wrong type (" << stylePluginLoader->instance()->metaObject()->className()
<< stylePluginLoader->instance()->metaObject()->className() << ") - new style not loaded"; << ") - new style not loaded";
return false; return false;
} }
@@ -21,10 +21,7 @@ class LTSUTILSGUISTYLEMANAGER_EXPORT StyleManager : public QObject
bool loadStyle(const QString &stylePluginName, bool highDpi = false); bool loadStyle(const QString &stylePluginName, bool highDpi = false);
const QString& currentStyleName() const const QString &currentStyleName() const { return m_stylePluginName; }
{
return m_stylePluginName;
}
private: private:
friend struct StyleManagerHandler; friend struct StyleManagerHandler;
@@ -16,7 +16,8 @@
namespace LtsUtils namespace LtsUtils
{ {
enum class SettingType { enum class SettingType
{
String = 1, String = 1,
StringList = 2, StringList = 2,
Json = 3, Json = 3,
@@ -133,7 +134,8 @@ bool ProjectSettings::initFromFile(const QString& filename)
case SettingType::Json: case SettingType::Json:
val = QJsonDocument(jVal.toObject()).toJson(); val = QJsonDocument(jVal.toObject()).toJson();
break; break;
case SettingType::StringList: { case SettingType::StringList:
{
const QJsonArray arr(jVal.toArray()); const QJsonArray arr(jVal.toArray());
QStringList sl; QStringList sl;
sl.reserve(arr.size()); sl.reserve(arr.size());
@@ -161,8 +163,7 @@ bool ProjectSettings::initFromFile(const QString& filename)
bool ProjectSettings::isFunctionEnabled(const QString &group, const QString &function) bool ProjectSettings::isFunctionEnabled(const QString &group, const QString &function)
{ {
const QStringList functionNames = const QStringList functionNames = getInstance()->value(QStringLiteral("Functionalities"), QStringLiteral("IdentifierList")).toStringList();
getInstance()->value(QStringLiteral("Functionalities"), QStringLiteral("IdentifierList")).toStringList();
return functionNames.contains(group + QLatin1Char(':') + function); return functionNames.contains(group + QLatin1Char(':') + function);
} }
@@ -11,7 +11,9 @@ namespace LtsWebSocket
{ {
ClientConnection::ClientConnection(QWebSocket *socket, QObject *parent) ClientConnection::ClientConnection(QWebSocket *socket, QObject *parent)
: QThread(parent), m_logger(getLogger("LtsWebSocket.ClientConnection")), m_socket(socket ? socket : new QWebSocket) : QThread(parent)
, m_logger(getLogger("LtsWebSocket.ClientConnection"))
, m_socket(socket ? socket : new QWebSocket)
{ {
} }
@@ -32,8 +34,7 @@ bool ClientConnection::init()
} }
DEBUG_LOG(m_logger) << "Started new thread" << this; DEBUG_LOG(m_logger) << "Started new thread" << this;
connect(m_socket, &QWebSocket::textMessageReceived, this, &ClientConnection::onNewTextMessageFromSocket, connect(m_socket, &QWebSocket::textMessageReceived, this, &ClientConnection::onNewTextMessageFromSocket, Qt::DirectConnection);
Qt::DirectConnection);
connect(m_socket, &QWebSocket::connected, this, &ClientConnection::sendMessagesFromQueue); connect(m_socket, &QWebSocket::connected, this, &ClientConnection::sendMessagesFromQueue);
connect(m_socket, &QWebSocket::disconnected, this, &ClientConnection::onSocketDisconnect); connect(m_socket, &QWebSocket::disconnected, this, &ClientConnection::onSocketDisconnect);
@@ -79,8 +80,7 @@ void ClientConnection::sendMessagesFromQueue()
void ClientConnection::onSocketDisconnect() void ClientConnection::onSocketDisconnect()
{ {
DEBUG_LOG(m_logger) << "Client disconnected ip: " << m_socket->peerAddress().toString() << ":" DEBUG_LOG(m_logger) << "Client disconnected ip: " << m_socket->peerAddress().toString() << ":" << m_socket->peerPort();
<< m_socket->peerPort();
exit(0); exit(0);
emit disconnected(this); emit disconnected(this);
} }
@@ -12,7 +12,10 @@
#ifdef QT6_WEBSOCKETS_AVAILABLE #ifdef QT6_WEBSOCKETS_AVAILABLE
class QWebSocket; class QWebSocket;
#else #else
namespace LtsWebSocket { class QWebSocketStub; } namespace LtsWebSocket
{
class QWebSocketStub;
}
using QWebSocket = LtsWebSocket::QWebSocketStub; using QWebSocket = LtsWebSocket::QWebSocketStub;
namespace LtsWebSocket namespace LtsWebSocket
{ {
@@ -32,7 +35,9 @@ class QWebSocketStub
namespace LtsWebSocket namespace LtsWebSocket
{ {
class LTSWEBSOCKETSERVER_EXPORT ClientConnection : public QThread, public ReplyHandler class LTSWEBSOCKETSERVER_EXPORT ClientConnection
: public QThread
, public ReplyHandler
{ {
Q_OBJECT Q_OBJECT
public: public:
@@ -45,10 +50,7 @@ class LTSWEBSOCKETSERVER_EXPORT ClientConnection : public QThread, public ReplyH
void addReply(ReplyMessage *message) override; void addReply(ReplyMessage *message) override;
QWebSocket* webSocket() QWebSocket *webSocket() { return m_socket; }
{
return m_socket;
}
#else #else
bool init() { return false; } bool init() { return false; }
void addReply(ReplyMessage * /*message*/) override {} void addReply(ReplyMessage * /*message*/) override {}
@@ -10,7 +10,8 @@ namespace LtsWebSocket
{ {
InvalidMessage::InvalidMessage(ReplyHandler *client, const QString &uuid, const QString &errorText) InvalidMessage::InvalidMessage(ReplyHandler *client, const QString &uuid, const QString &errorText)
: AbstractClientMessage(client, QString(), 1, uuid), m_errorText(errorText) : AbstractClientMessage(client, QString(), 1, uuid)
, m_errorText(errorText)
{ {
} }
@@ -14,9 +14,12 @@ namespace LtsWebSocket
class LTSWEBSOCKETCOMMON_EXPORT AbstractClientMessage class LTSWEBSOCKETCOMMON_EXPORT AbstractClientMessage
{ {
public: public:
AbstractClientMessage(ReplyHandler* client, const QString& type, const int typeId, const QString& uuid, AbstractClientMessage(ReplyHandler *client, const QString &type, const int typeId, const QString &uuid, const QJsonValue &data = QJsonValue())
const QJsonValue& data = QJsonValue()) : m_type(type)
: m_type(type), m_typeId(typeId), m_uuid(uuid), m_data(data), m_client(client) , m_typeId(typeId)
, m_uuid(uuid)
, m_data(data)
, m_client(client)
{ {
} }
@@ -26,10 +29,7 @@ class LTSWEBSOCKETCOMMON_EXPORT AbstractClientMessage
virtual bool hasValidData() const = 0; virtual bool hasValidData() const = 0;
void reply(ReplyMessage* reply) void reply(ReplyMessage *reply) { m_client->addReply(reply); }
{
m_client->addReply(reply);
}
protected: protected:
const QString m_type; const QString m_type;
@@ -41,8 +41,7 @@ AbstractClientMessage* AbstractClientMessageFactory::checkAttributes(ReplyHandle
return new LtsWebSocket::InvalidMessage(client, m_uuid, QStringLiteral("Message has no type")); return new LtsWebSocket::InvalidMessage(client, m_uuid, QStringLiteral("Message has no type"));
} }
AbstractClientMessage* AbstractClientMessageFactory::checkResult(ReplyHandler* client, const QString& message, AbstractClientMessage *AbstractClientMessageFactory::checkResult(ReplyHandler *client, const QString &message, AbstractClientMessage *result) const
AbstractClientMessage* result) const
{ {
if (result == nullptr) if (result == nullptr)
{ {
@@ -20,7 +20,10 @@ namespace LtsWebSocket
class LTSWEBSOCKETCOMMON_EXPORT AbstractClientMessageFactory class LTSWEBSOCKETCOMMON_EXPORT AbstractClientMessageFactory
{ {
public: public:
explicit AbstractClientMessageFactory(NGL::INGLLogger& logger) : m_logger(logger) {} explicit AbstractClientMessageFactory(NGL::INGLLogger &logger)
: m_logger(logger)
{
}
virtual ~AbstractClientMessageFactory() {} virtual ~AbstractClientMessageFactory() {}
@@ -30,8 +33,7 @@ class LTSWEBSOCKETCOMMON_EXPORT AbstractClientMessageFactory
protected: protected:
AbstractClientMessage *checkAttributes(ReplyHandler *client, const QString &message) const; AbstractClientMessage *checkAttributes(ReplyHandler *client, const QString &message) const;
AbstractClientMessage* checkResult(ReplyHandler* client, const QString& message, AbstractClientMessage *checkResult(ReplyHandler *client, const QString &message, AbstractClientMessage *result) const;
AbstractClientMessage* result) const;
protected: protected:
NGL::INGLLogger &m_logger; NGL::INGLLogger &m_logger;
@@ -44,22 +46,17 @@ class LTSWEBSOCKETCOMMON_EXPORT AbstractClientMessageFactory
class PongMessage final : public ReplyMessage class PongMessage final : public ReplyMessage
{ {
public: public:
static QString strPong() static QString strPong() { return QStringLiteral("pong"); }
static int idPong() { return 2; }
explicit PongMessage(const QString &payload)
: ReplyMessage(strPong(), idPong(), QString())
, m_payload(payload)
{ {
return QStringLiteral("pong");
} }
static int idPong() QString toJsonString() const override { return m_payload.isEmpty() ? strPong() : QStringLiteral("%1 %2").arg(strPong(), m_payload); }
{
return 2;
}
explicit PongMessage(const QString& payload) : ReplyMessage(strPong(), idPong(), QString()), m_payload(payload) {}
QString toJsonString() const override
{
return m_payload.isEmpty() ? strPong() : QStringLiteral("%1 %2").arg(strPong(), m_payload);
}
private: private:
QString m_payload; QString m_payload;
@@ -13,7 +13,9 @@
using namespace LtsWebSocket; using namespace LtsWebSocket;
ConnectionHandler::ConnectionHandler(QObject *parent) ConnectionHandler::ConnectionHandler(QObject *parent)
: QObject(parent), m_logger(getLogger("LtsWebSocket.ConnectionHandler")), m_server(nullptr) : QObject(parent)
, m_logger(getLogger("LtsWebSocket.ConnectionHandler"))
, m_server(nullptr)
{ {
} }
@@ -70,8 +72,7 @@ void ConnectionHandler::onNewConnection()
QWebSocket *socket = m_server->nextPendingConnection(); QWebSocket *socket = m_server->nextPendingConnection();
ClientConnection *newConnection = new ClientConnection(socket, this); ClientConnection *newConnection = new ClientConnection(socket, this);
connect(newConnection, &ClientConnection::destroyed, this, connect(newConnection, &ClientConnection::destroyed, this, [this](QObject *o) { m_connections.remove(static_cast<ClientConnection *>(o)); });
[this](QObject* o) { m_connections.remove(static_cast<ClientConnection*>(o)); });
if (!newConnection->init()) if (!newConnection->init())
{ {
@@ -88,8 +89,7 @@ void ConnectionHandler::onNewConnection()
m_connections.insert(newConnection); m_connections.insert(newConnection);
emit clientConnected(newConnection); emit clientConnected(newConnection);
INFO_LOG(m_logger) << "New client connected ip: " << socket->localAddress().toString() << ":" INFO_LOG(m_logger) << "New client connected ip: " << socket->localAddress().toString() << ":" << socket->localPort();
<< socket->localPort();
} }
} }
#endif #endif
@@ -11,9 +11,18 @@
#include <QtWebSockets/QWebSocketServer> #include <QtWebSockets/QWebSocketServer>
#include <QtWebSockets/qwebsocketprotocol.h> #include <QtWebSockets/qwebsocketprotocol.h>
#else #else
namespace LtsWebSocket { class QWebSocketServerStub; } namespace LtsWebSocket
{
class QWebSocketServerStub;
}
using QWebSocketServer = LtsWebSocket::QWebSocketServerStub; using QWebSocketServer = LtsWebSocket::QWebSocketServerStub;
namespace QWebSocketProtocol { enum class CloseCode { NormalClosure = 1000 }; } namespace QWebSocketProtocol
{
enum class CloseCode
{
NormalClosure = 1000
};
}
#endif #endif
namespace LtsWebSocket namespace LtsWebSocket
@@ -34,10 +43,7 @@ class ConnectionHandler : public QObject
void sendToAllClients(ReplyMessage *message); void sendToAllClients(ReplyMessage *message);
unsigned short webSocketPort() unsigned short webSocketPort() { return m_server->serverPort(); }
{
return m_server->serverPort();
}
#else #else
bool init(const QString & /*serviceName*/, unsigned short /*port*/) { return false; } bool init(const QString & /*serviceName*/, unsigned short /*port*/) { return false; }
void sendToAllClients(ReplyMessage * /*message*/) {} void sendToAllClients(ReplyMessage * /*message*/) {}
@@ -13,7 +13,8 @@ template <typename T> class DataManagerBaseDl
{ {
protected: protected:
explicit DataManagerBaseDl(const std::shared_ptr<T> &dbInterface, NGL::INGLLogger &logger) explicit DataManagerBaseDl(const std::shared_ptr<T> &dbInterface, NGL::INGLLogger &logger)
: m_logger(logger), m_dbInterface(dbInterface) : m_logger(logger)
, m_dbInterface(dbInterface)
{ {
} }
@@ -14,8 +14,7 @@ class WebSocketHelper : public QObject
{ {
Q_OBJECT Q_OBJECT
public: public:
WebSocketHelper(AbstractClientMessageFactory* messageFactory, LtsWebSocketClient* webSocketClient, WebSocketHelper(AbstractClientMessageFactory *messageFactory, LtsWebSocketClient *webSocketClient, NGL::INGLLogger &logger);
NGL::INGLLogger& logger);
~WebSocketHelper(); ~WebSocketHelper();
public Q_SLOTS: public Q_SLOTS:
@@ -40,10 +39,12 @@ class WebSocketHelper : public QObject
NGL::INGLLogger &m_logger; NGL::INGLLogger &m_logger;
}; };
WebSocketHelper::WebSocketHelper(AbstractClientMessageFactory* messageFactory, LtsWebSocketClient* webSocketClient, WebSocketHelper::WebSocketHelper(AbstractClientMessageFactory *messageFactory, LtsWebSocketClient *webSocketClient, NGL::INGLLogger &logger)
NGL::INGLLogger& logger) : QObject()
: QObject(), m_messageFactory(messageFactory), m_webSocketClient(webSocketClient), , m_messageFactory(messageFactory)
m_socket(new QWebSocket(QString(), QWebSocketProtocol::VersionLatest, this)), m_logger(logger) , m_webSocketClient(webSocketClient)
, m_socket(new QWebSocket(QString(), QWebSocketProtocol::VersionLatest, this))
, m_logger(logger)
{ {
connect(m_socket, &QWebSocket::textMessageReceived, this, &WebSocketHelper::parseMessage); connect(m_socket, &QWebSocket::textMessageReceived, this, &WebSocketHelper::parseMessage);
connect(m_socket, &QWebSocket::textFrameReceived, this, &WebSocketHelper::dataReceived); connect(m_socket, &QWebSocket::textFrameReceived, this, &WebSocketHelper::dataReceived);
@@ -96,8 +97,7 @@ void WebSocketHelper::doSendTextMessage(const QString& msg)
void WebSocketHelper::onConnected() void WebSocketHelper::onConnected()
{ {
INFO_LOG(m_logger) << "Connected to server url: " << m_socket->requestUrl().toDisplayString() INFO_LOG(m_logger) << "Connected to server url: " << m_socket->requestUrl().toDisplayString() << " using local port: " << m_socket->localPort();
<< " using local port: " << m_socket->localPort();
emit connected(); emit connected();
} }
@@ -128,19 +128,18 @@ void WebSocketHelper::parseMessage(const QString& message)
clientMessage = m_messageFactory->createMessage(m_webSocketClient, message); clientMessage = m_messageFactory->createMessage(m_webSocketClient, message);
else else
{ {
WARNING_LOG(m_logger) << "Could not parse incoming message: '" << message WARNING_LOG(m_logger) << "Could not parse incoming message: '" << message << "', error: " << result.errorString();
<< "', error: " << result.errorString(); clientMessage = new InvalidMessage(m_webSocketClient, QString(), QStringLiteral("Got message which is not JSON conform (%1)").arg(result.errorString()));
clientMessage =
new InvalidMessage(m_webSocketClient, QString(),
QStringLiteral("Got message which is not JSON conform (%1)").arg(result.errorString()));
} }
if (clientMessage) if (clientMessage)
emit messageParsed(clientMessage); emit messageParsed(clientMessage);
} }
LtsWebSocketClient::LtsWebSocketClient(AbstractClientMessageFactory *messageFactory, QObject *parent) LtsWebSocketClient::LtsWebSocketClient(AbstractClientMessageFactory *messageFactory, QObject *parent)
: QObject(parent), m_logger(getLogger("LtsWebSocketClient")), m_messageFactory(messageFactory), : QObject(parent)
m_webSocketHelperThread(new QThread(this)) , m_logger(getLogger("LtsWebSocketClient"))
, m_messageFactory(messageFactory)
, m_webSocketHelperThread(new QThread(this))
{ {
m_webSocketHelper = new WebSocketHelper(m_messageFactory, this, m_logger); m_webSocketHelper = new WebSocketHelper(m_messageFactory, this, m_logger);
m_webSocketHelper->moveToThread(m_webSocketHelperThread); m_webSocketHelper->moveToThread(m_webSocketHelperThread);
@@ -15,7 +15,9 @@ namespace LtsWebSocket
{ {
class WebSocketHelper; class WebSocketHelper;
class LTSWEBSOCKETCLIENT_EXPORT LtsWebSocketClient : public QObject, public ReplyHandler class LTSWEBSOCKETCLIENT_EXPORT LtsWebSocketClient
: public QObject
, public ReplyHandler
{ {
Q_OBJECT Q_OBJECT
public: public:
@@ -12,8 +12,11 @@ namespace LtsWebSocket
{ {
LtsWebSocketServer::LtsWebSocketServer(AbstractClientMessageFactory *messageFactory, QObject *parent) LtsWebSocketServer::LtsWebSocketServer(AbstractClientMessageFactory *messageFactory, QObject *parent)
: QObject(parent), m_queueTimer(new QTimer(this)), m_messageFactory(messageFactory), m_connectionHandler(nullptr), : QObject(parent)
m_logger(getLogger("LtsWebSocket.Server")) , m_queueTimer(new QTimer(this))
, m_messageFactory(messageFactory)
, m_connectionHandler(nullptr)
, m_logger(getLogger("LtsWebSocket.Server"))
{ {
connect(m_queueTimer, &QTimer::timeout, this, &LtsWebSocketServer::onQueueTimerTimeout); connect(m_queueTimer, &QTimer::timeout, this, &LtsWebSocketServer::onQueueTimerTimeout);
@@ -29,16 +32,13 @@ bool LtsWebSocketServer::init(const QString& serviceName, const unsigned short p
if (!m_connectionHandler->init(serviceName, port)) if (!m_connectionHandler->init(serviceName, port))
{ {
ERROR_LOG(m_logger) << "Could not init m_connectionHandler with servicename: " << serviceName ERROR_LOG(m_logger) << "Could not init m_connectionHandler with servicename: " << serviceName
<< ((port == 0) ? QStringLiteral(" random port") << ((port == 0) ? QStringLiteral(" random port") : QStringLiteral(" port: ") + QString::number(port));
: QStringLiteral(" port: ") + QString::number(port));
m_connectionHandler.reset(); m_connectionHandler.reset();
return false; return false;
} }
connect(m_connectionHandler.get(), &ConnectionHandler::newTextMessageFromClient, this, connect(m_connectionHandler.get(), &ConnectionHandler::newTextMessageFromClient, this, &LtsWebSocketServer::onNewTextMessage);
&LtsWebSocketServer::onNewTextMessage); connect(m_connectionHandler.get(), &ConnectionHandler::clientDisconnected, this, &LtsWebSocketServer::clientDisconnected);
connect(m_connectionHandler.get(), &ConnectionHandler::clientDisconnected, this,
&LtsWebSocketServer::clientDisconnected);
connect(m_connectionHandler.get(), &ConnectionHandler::clientConnected, this, &LtsWebSocketServer::clientConnected); connect(m_connectionHandler.get(), &ConnectionHandler::clientConnected, this, &LtsWebSocketServer::clientConnected);
m_queueTimer->start(m_messageDelay); m_queueTimer->start(m_messageDelay);
@@ -105,11 +105,9 @@ void LtsWebSocketServer::onQueueTimerTimeout()
clientMessage = m_messageFactory->createMessage(credentials.client, credentials.message); clientMessage = m_messageFactory->createMessage(credentials.client, credentials.message);
else else
{ {
WARNING_LOG(m_logger) << "Could not parse incoming message: '" << credentials.message WARNING_LOG(m_logger) << "Could not parse incoming message: '" << credentials.message << "', error: " << result.errorString();
<< "', error: " << result.errorString();
clientMessage = clientMessage = new InvalidMessage(credentials.client, QString(), QStringLiteral("Got message which is not JSON conform"));
new InvalidMessage(credentials.client, QString(), QStringLiteral("Got message which is not JSON conform"));
} }
if (clientMessage) if (clientMessage)
@@ -127,7 +125,9 @@ namespace LtsWebSocket
{ {
LtsWebSocketServer::LtsWebSocketServer(AbstractClientMessageFactory * /*messageFactory*/, QObject *parent) LtsWebSocketServer::LtsWebSocketServer(AbstractClientMessageFactory * /*messageFactory*/, QObject *parent)
: QObject(parent), m_queueTimer(new QTimer(this)), m_logger(getLogger("LtsWebSocket.Server")) : QObject(parent)
, m_queueTimer(new QTimer(this))
, m_logger(getLogger("LtsWebSocket.Server"))
{ {
} }
@@ -52,7 +52,11 @@ class LTSWEBSOCKETSERVER_EXPORT LtsWebSocketServer : public QObject
ReplyHandler *client{nullptr}; ReplyHandler *client{nullptr};
QString message; QString message;
MessageCredentials(ReplyHandler* client, const QString& message) : client(client), message(message) {} MessageCredentials(ReplyHandler *client, const QString &message)
: client(client)
, message(message)
{
}
}; };
QQueue<MessageCredentials> m_messageQueue; QQueue<MessageCredentials> m_messageQueue;
@@ -26,9 +26,9 @@ ReplyMessage::ReplyMessage(const QString& type, const int typeId, const QString&
ErrorMessage::ErrorMessage(const ErrorMessage::ErrorData &data) ErrorMessage::ErrorMessage(const ErrorMessage::ErrorData &data)
: ReplyMessage(JsonKeys::ERROR_(), -1, QUuid::createUuid().toString()) : ReplyMessage(JsonKeys::ERROR_(), -1, QUuid::createUuid().toString())
{ {
m_jsonRepresentation.insert(JsonKeys::DATA(), QJsonObject({{JsonKeys::UUID_(), data.uuid}, m_jsonRepresentation.insert(JsonKeys::DATA(),
{JsonKeys::ERROR_CLASS(), data.errorClass}, QJsonObject(
{JsonKeys::ERROR_MESSAGE(), data.errorMessage}})); {{JsonKeys::UUID_(), data.uuid}, {JsonKeys::ERROR_CLASS(), data.errorClass}, {JsonKeys::ERROR_MESSAGE(), data.errorMessage}}));
} }
} // namespace LtsWebSocket } // namespace LtsWebSocket
@@ -18,10 +18,7 @@ class LTSWEBSOCKETCOMMON_EXPORT ReplyMessage
virtual QString toJsonString() const; virtual QString toJsonString() const;
QJsonObject json() const QJsonObject json() const { return m_jsonRepresentation; }
{
return m_jsonRepresentation;
}
protected: protected:
ReplyMessage() = default; ReplyMessage() = default;
@@ -14,16 +14,6 @@ ADD_LIBRARY(DataPluginInterface SHARED
TARGET_INCLUDE_DIRECTORIES(DataPluginInterface PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/..) TARGET_INCLUDE_DIRECTORIES(DataPluginInterface PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/..)
TARGET_LINK_LIBRARIES(DataPluginInterface PUBLIC Qt6::Core) TARGET_LINK_LIBRARIES(DataPluginInterface PUBLIC Qt6::Core)
# GuiPluginInterface
IF(NOT RELEASE_BUILD)
ADD_LIBRARY(GuiPluginInterface SHARED
${CMAKE_CURRENT_SOURCE_DIR}/gui_plugin_interface.h
${CMAKE_CURRENT_SOURCE_DIR}/gui_plugin_interface.cpp
)
TARGET_INCLUDE_DIRECTORIES(GuiPluginInterface PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/..)
TARGET_LINK_LIBRARIES(GuiPluginInterface PUBLIC Qt6::Core LtsWidgets ProjectConfig LtsAppDescriptor LtsUtilsCore)
ENDIF()
# projectPluginInterface # projectPluginInterface
ADD_LIBRARY(ProjectPluginInterface SHARED ADD_LIBRARY(ProjectPluginInterface SHARED
${CMAKE_CURRENT_SOURCE_DIR}/project_plugin_interface.h ${CMAKE_CURRENT_SOURCE_DIR}/project_plugin_interface.h
@@ -39,24 +29,3 @@ ADD_LIBRARY(StylePluginInterface SHARED
) )
TARGET_INCLUDE_DIRECTORIES(StylePluginInterface PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/..) TARGET_INCLUDE_DIRECTORIES(StylePluginInterface PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/..)
TARGET_LINK_LIBRARIES(StylePluginInterface PUBLIC Qt6::Core) TARGET_LINK_LIBRARIES(StylePluginInterface PUBLIC Qt6::Core)
# record_replay_plugin (requires RTI DDS)
if(BUILD_RTI)
ADD_LIBRARY(RecordReplayPlugin SHARED
${CMAKE_CURRENT_SOURCE_DIR}/record_replay_plugin.h
${CMAKE_CURRENT_SOURCE_DIR}/record_replay_plugin.cpp
)
TARGET_INCLUDE_DIRECTORIES(RecordReplayPlugin PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/..)
TARGET_LINK_LIBRARIES(RecordReplayPlugin PUBLIC Qt6::Core)
# Topic Replay Interface (requires RTI DDS and TopicEditorBase)
ADD_LIBRARY(TopicReplayInterface SHARED
${CMAKE_CURRENT_SOURCE_DIR}/topic_replay_interface.h
${CMAKE_CURRENT_SOURCE_DIR}/topic_replay_interface.cpp
)
TARGET_INCLUDE_DIRECTORIES(TopicReplayInterface PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/..
${CMAKE_BINARY_DIR}/Lts/Common/TopicEditorBase # topiceditorbase_export.h
)
TARGET_LINK_LIBRARIES(TopicReplayInterface PUBLIC Qt6::Core TopicEditorBase)
endif()
@@ -47,58 +47,34 @@ class Interface
{ {
public: public:
Interface(LtsSession::LtsSession *session, NGL::INGLLogger &logger) Interface(LtsSession::LtsSession *session, NGL::INGLLogger &logger)
: m_hasInit(true), m_session(session), m_appId(LtsAppDescriptor::App::Login), m_logger(logger) : m_hasInit(true)
, m_session(session)
, m_appId(LtsAppDescriptor::App::Login)
, m_logger(logger)
{ {
} }
virtual ~Interface() = default; virtual ~Interface() = default;
void setFlags(const QFlags<LtsAppDescriptor::PluginInfo::Flag>& flags) void setFlags(const QFlags<LtsAppDescriptor::PluginInfo::Flag> &flags) { m_flags = flags; }
{
m_flags = flags;
}
const QFlags<LtsAppDescriptor::PluginInfo::Flag>& getFlags() const const QFlags<LtsAppDescriptor::PluginInfo::Flag> &getFlags() const { return m_flags; }
{
return m_flags;
}
void setOptions(const QStringList& options) void setOptions(const QStringList &options) { m_options = options; }
{
m_options = options;
}
const QStringList& getOptions() const const QStringList &getOptions() const { return m_options; }
{
return m_options;
}
void setAppId(LtsAppDescriptor::App appId) void setAppId(LtsAppDescriptor::App appId) { m_appId = appId; }
{
m_appId = appId;
}
LtsAppDescriptor::App appId() const LtsAppDescriptor::App appId() const { return m_appId; }
{
return m_appId;
}
virtual QVector<LtsWidgets::PluginData> getActions() virtual QVector<LtsWidgets::PluginData> getActions() { return QVector<LtsWidgets::PluginData>(); }
{
return QVector<LtsWidgets::PluginData>();
}
virtual bool fetchInterfaces() virtual bool fetchInterfaces() { return true; }
{
return true;
}
virtual void clearInterfaces() {} virtual void clearInterfaces() {}
virtual QString menuGroup() const virtual QString menuGroup() const { return {}; }
{
return {};
}
virtual LtsUtils::LtsTranslatableIdentifier menuGroupIdentifier() const virtual LtsUtils::LtsTranslatableIdentifier menuGroupIdentifier() const
{ {
@@ -112,20 +88,11 @@ class Interface
return true; return true;
} }
virtual void init() virtual void init() { m_hasInit = false; }
{
m_hasInit = false;
}
virtual void executePayload(LtsWidgets::LtsBackgroundWidget* mainBackground) virtual void executePayload(LtsWidgets::LtsBackgroundWidget *mainBackground) { (void)mainBackground; }
{
(void)mainBackground;
}
virtual int executionPriority() const virtual int executionPriority() const { return -1; }
{
return -1;
}
bool m_hasInit; bool m_hasInit;
mutable bool m_hasMenuGroupIdentifier = true; mutable bool m_hasMenuGroupIdentifier = true;
@@ -28,8 +28,7 @@ class RecordReplayPlugin
virtual bool initDtc(const std::shared_ptr<DDSConnector::DdsConnector> &ddsConnector, int exerciseId) = 0; virtual bool initDtc(const std::shared_ptr<DDSConnector::DdsConnector> &ddsConnector, int exerciseId) = 0;
virtual bool initDts(const std::shared_ptr<DDSConnector::DdsConnector>& ddsConnector, int exerciseId, virtual bool initDts(const std::shared_ptr<DDSConnector::DdsConnector> &ddsConnector, int exerciseId, bool bCanHandleSchemas, NSqlQuery &query) = 0;
bool bCanHandleSchemas, NSqlQuery& query) = 0;
virtual bool initCopy(int exerciseId, bool bCanHandleSchemasRead, bool bCanHandleSchemasWrite) = 0; virtual bool initCopy(int exerciseId, bool bCanHandleSchemasRead, bool bCanHandleSchemasWrite) = 0;
@@ -60,13 +59,15 @@ class RecordReplayPlugin
RecSnapshot() = default; RecSnapshot() = default;
RecSnapshot(qint64 timeStamp_, const std::map<int64_t, int64_t> &recIdArray_) RecSnapshot(qint64 timeStamp_, const std::map<int64_t, int64_t> &recIdArray_)
: timeStamp(timeStamp_), recIdArray(recIdArray_) : timeStamp(timeStamp_)
, recIdArray(recIdArray_)
{ {
} }
}; };
virtual std::map<QString, std::vector<RecSnapshot>> virtual std::map<QString, std::vector<RecSnapshot>> getSnapshotTimes(NSqlQuery &query,
getSnapshotTimes(NSqlQuery& query, qint64 toTime, qint64 interval, qint64 toTime,
qint64 interval,
const QHash<QString, qint64> &minRecordedSampleTimes) = 0; const QHash<QString, qint64> &minRecordedSampleTimes) = 0;
virtual QVector<QString> getRecordTopicNames() const = 0; virtual QVector<QString> getRecordTopicNames() const = 0;
@@ -20,10 +20,7 @@ class Interface
{ {
public: public:
static QJsonObject timeRange(qint64 start, qint64 end) static QJsonObject timeRange(qint64 start, qint64 end) { return {{QStringLiteral("start"), start}, {QStringLiteral("end"), end}}; }
{
return {{QStringLiteral("start"), start}, {QStringLiteral("end"), end}};
}
struct SituationReplayTime struct SituationReplayTime
{ {
@@ -63,10 +60,7 @@ class Interface
Interface() = default; Interface() = default;
virtual ~Interface() = default; virtual ~Interface() = default;
virtual QWidget* createWidget() virtual QWidget *createWidget() { return nullptr; }
{
return nullptr;
}
virtual bool playbackInit(const QJsonObject &attributes) virtual bool playbackInit(const QJsonObject &attributes)
{ {
@@ -80,26 +74,18 @@ class Interface
return true; return true;
} }
virtual bool playbackPause() virtual bool playbackPause() { return true; }
{
return true;
}
virtual bool playbackStop() virtual bool playbackStop() { return true; }
{
return true;
}
virtual void setExportPlaybackTimes(qint64 startTimeSec, qint64 durationSec, virtual void setExportPlaybackTimes(qint64 startTimeSec, qint64 durationSec, const QVector<SituationReplayTime> &sitReplayTimes)
const QVector<SituationReplayTime>& sitReplayTimes)
{ {
Q_UNUSED(startTimeSec); Q_UNUSED(startTimeSec);
Q_UNUSED(durationSec); Q_UNUSED(durationSec);
Q_UNUSED(sitReplayTimes); Q_UNUSED(sitReplayTimes);
} }
virtual bool exportTopic(const QJsonObject& attributes, const QString& strFolderPath, virtual bool exportTopic(const QJsonObject &attributes, const QString &strFolderPath, TopicEditorBase::ExportNotifier *pExportNotifier) = 0;
TopicEditorBase::ExportNotifier* pExportNotifier) = 0;
virtual QVector<TopicEditorBase::TopicData> additionalTrackEntries(const QJsonObject &attributes) const virtual QVector<TopicEditorBase::TopicData> additionalTrackEntries(const QJsonObject &attributes) const
{ {
@@ -107,17 +93,13 @@ class Interface
return {}; return {};
} }
virtual QVector<TopicEditorBase::TopicData> additionalTrackEntries(const QJsonObject& attributes, virtual QVector<TopicEditorBase::TopicData> additionalTrackEntries(const QJsonObject &attributes, bool &keepOriginalTopic) const
bool& keepOriginalTopic) const
{ {
keepOriginalTopic = true; keepOriginalTopic = true;
return additionalTrackEntries(attributes); return additionalTrackEntries(attributes);
} }
virtual void setBasePath(const QString& basePath) virtual void setBasePath(const QString &basePath) { Q_UNUSED(basePath); }
{
Q_UNUSED(basePath);
}
}; };
class Factory class Factory
@@ -10,7 +10,8 @@
namespace IDL namespace IDL
{ {
enum class PartitionType { enum class PartitionType
{
Any, Any,
Global, Global,
Exercise, Exercise,
@@ -10,7 +10,10 @@
namespace httq namespace httq
{ {
AbstractServer::AbstractServer(QObject *parent) AbstractServer::AbstractServer(QObject *parent)
: QObject(parent), mSvr(new QTcpServer(this)), mLoggerFactory(nullptr), mLogger(nullptr) : QObject(parent)
, mSvr(new QTcpServer(this))
, mLoggerFactory(nullptr)
, mLogger(nullptr)
{ {
} }
@@ -42,7 +45,11 @@ void AbstractServer::slotNewConnection()
HttpRequest *req = new HttpRequest(cli, this); HttpRequest *req = new HttpRequest(cli, this);
connect(req, &HttpRequest::signalUpgrade, this, [this, req](QTcpSocket* sock) { connect(req,
&HttpRequest::signalUpgrade,
this,
[this, req](QTcpSocket *sock)
{
mLogger->debug(QStringLiteral("signalUpgrade")); mLogger->debug(QStringLiteral("signalUpgrade"));
#ifdef QT6_WEBSOCKETS_AVAILABLE #ifdef QT6_WEBSOCKETS_AVAILABLE
@@ -66,7 +73,11 @@ void AbstractServer::slotNewConnection()
emit sock->readyRead(); emit sock->readyRead();
}); });
connect(req, &HttpRequest::signalReady, this, [this, req]() { connect(req,
&HttpRequest::signalReady,
this,
[this, req]()
{
mLogger->debug(QStringLiteral("signalReady")); mLogger->debug(QStringLiteral("signalReady"));
newHttpConnection(req); newHttpConnection(req);
}); });
@@ -1,14 +1,6 @@
# Modified CMakeLists.txt from github.com/wille-io/httq # Modified CMakeLists.txt from github.com/wille-io/httq
# Make ${Qt6_WebSockets} optional # Make ${Qt6_WebSockets} optional
# Link the real WebSockets module whenever the websocket code path is
# compiled: QT6_WEBSOCKETS_AVAILABLE (root CMakeLists) and the manual
# Qt6::WebSockets import are set when the real module was found. The old
# QT6_GUI_AVAILABLE condition never held in this environment (Qt6
# discovery takes the minimal path) and the Qt6_WebSockets variable was
# never defined, so AbstractServer.cpp compiled the websocket code
# without the module on the link line (undefined reference to
# QWebSocketServer::handleConnection).
if(QT6_WEBSOCKETS_REAL_FOUND OR Qt6WebSockets_FOUND) if(QT6_WEBSOCKETS_REAL_FOUND OR Qt6WebSockets_FOUND)
set(Qt6_WebSockets Qt6::WebSockets) set(Qt6_WebSockets Qt6::WebSockets)
else() else()
@@ -13,10 +13,20 @@
namespace httq namespace httq
{ {
DataStream::DataStream(QIODevice* from, QIODevice* to, const QByteArray& bodyPartial, qint64 fileLength, DataStream::DataStream(QIODevice *from,
size_t bufferSize, LoggerFactory* loggerFactory, QObject* parent) QIODevice *to,
: QObject(parent), mBodyPartial(bodyPartial), mFrom(from), mTo(to), mBufferSize(bufferSize), const QByteArray &bodyPartial,
mFileLength(fileLength), mLogger(loggerFactory->createLogger(this)) qint64 fileLength,
size_t bufferSize,
LoggerFactory *loggerFactory,
QObject *parent)
: QObject(parent)
, mBodyPartial(bodyPartial)
, mFrom(from)
, mTo(to)
, mBufferSize(bufferSize)
, mFileLength(fileLength)
, mLogger(loggerFactory->createLogger(this))
{ {
#ifdef SAVE_PARTIAL_BODY #ifdef SAVE_PARTIAL_BODY
@@ -32,7 +42,10 @@ DataStream::DataStream(QIODevice* from, QIODevice* to, const QByteArray& bodyPar
if (mFileLength == 0) if (mFileLength == 0)
{ {
mLogger->warning(QStringLiteral("file size = 0 - done")); mLogger->warning(QStringLiteral("file size = 0 - done"));
QTimer::singleShot(1, this, [this]() { QTimer::singleShot(1,
this,
[this]()
{
emit signalDone(); emit signalDone();
deleteLater(); deleteLater();
}); });
@@ -45,19 +58,26 @@ DataStream::DataStream(QIODevice* from, QIODevice* to, const QByteArray& bodyPar
mFromSupportsSignals = (qobject_cast<QFileDevice *>(mFrom) == nullptr); mFromSupportsSignals = (qobject_cast<QFileDevice *>(mFrom) == nullptr);
mToSupportsSignals = (qobject_cast<QFileDevice *>(mTo) == nullptr); mToSupportsSignals = (qobject_cast<QFileDevice *>(mTo) == nullptr);
mLogger->debug( mLogger->debug(QStringLiteral("signal support - from: %1 - to: %2").arg(mFromSupportsSignals).arg(mToSupportsSignals));
QStringLiteral("signal support - from: %1 - to: %2").arg(mFromSupportsSignals).arg(mToSupportsSignals));
auto sock = qobject_cast<QTcpSocket *>(mFrom); auto sock = qobject_cast<QTcpSocket *>(mFrom);
qWarning() << "######################### SOCK" << sock; qWarning() << "######################### SOCK" << sock;
connect(sock, &QTcpSocket::readyRead, this, [this]() { connect(sock,
&QTcpSocket::readyRead,
this,
[this]()
{
mLogger->debug(QStringLiteral(">> DataStream readyRead")); mLogger->debug(QStringLiteral(">> DataStream readyRead"));
QTimer::singleShot(1, this, [this]() { readNext(); }); QTimer::singleShot(1, this, [this]() { readNext(); });
}); });
if (mToSupportsSignals) if (mToSupportsSignals)
connect(mTo, &QIODevice::bytesWritten, this, [this]() { connect(mTo,
&QIODevice::bytesWritten,
this,
[this]()
{
mLogger->debug(QStringLiteral(">> DataStream write")); mLogger->debug(QStringLiteral(">> DataStream write"));
mReadyWrite = true; mReadyWrite = true;
@@ -147,8 +167,7 @@ void DataStream::writeNext()
if (!mTo->isOpen() || !mTo->isWritable()) if (!mTo->isOpen() || !mTo->isWritable())
{ {
mLogger->debug( mLogger->debug(QStringLiteral("write: file error: open? %1 - writable? %2").arg(mTo->isOpen()).arg(mTo->isWritable()));
QStringLiteral("write: file error: open? %1 - writable? %2").arg(mTo->isOpen()).arg(mTo->isWritable()));
deleteLater(); deleteLater();
return; return;
} }
@@ -166,10 +185,7 @@ void DataStream::writeNext()
const qint64 size = mTo->write(mBuffer); const qint64 size = mTo->write(mBuffer);
mLogger->debug(QStringLiteral("write: wrote to buffer %1 bytes").arg(size)); mLogger->debug(QStringLiteral("write: wrote to buffer %1 bytes").arg(size));
mLogger->debug(QStringLiteral("write: %1 / %2 bytes done (%3 bytes left until DataStream done)") mLogger->debug(QStringLiteral("write: %1 / %2 bytes done (%3 bytes left until DataStream done)").arg(alreadyRead).arg(mFileLength).arg(mFileLength - alreadyRead));
.arg(alreadyRead)
.arg(mFileLength)
.arg(mFileLength - alreadyRead));
if (size < mBuffer.size()) if (size < mBuffer.size())
{ {
@@ -14,7 +14,9 @@
namespace httq namespace httq
{ {
HttpRequest::HttpRequest(QTcpSocket *cli, AbstractServer *parent) HttpRequest::HttpRequest(QTcpSocket *cli, AbstractServer *parent)
: QObject(parent), mCli(cli), mLogger(parent->getLoggerFactory()->createLogger(this)) : QObject(parent)
, mCli(cli)
, mLogger(parent->getLoggerFactory()->createLogger(this))
{ {
mLogger->debug(QStringLiteral("HttpRequest c_tor")); mLogger->debug(QStringLiteral("HttpRequest c_tor"));
@@ -83,8 +85,7 @@ int HttpRequest::on_url(http_parser* parser, const char* at, size_t length)
if (parserUrl.field_set & (1 << UF_PORT)) if (parserUrl.field_set & (1 << UF_PORT))
{ {
bool k = false; bool k = false;
QString portString( QString portString(QString::fromUtf8(at + parserUrl.field_data[UF_PORT].off, parserUrl.field_data[UF_PORT].len));
QString::fromUtf8(at + parserUrl.field_data[UF_PORT].off, parserUrl.field_data[UF_PORT].len));
qint16 port = portString.toShort(&k); qint16 port = portString.toShort(&k);
if (!k) if (!k)
@@ -109,8 +110,7 @@ int HttpRequest::on_url(http_parser* parser, const char* at, size_t length)
} }
if (isUrlFieldSet(UF_USERINFO)) if (isUrlFieldSet(UF_USERINFO))
url.setUserInfo( url.setUserInfo(QString::fromUtf8(at + parserUrl.field_data[UF_USERINFO].off, parserUrl.field_data[UF_USERINFO].len));
QString::fromUtf8(at + parserUrl.field_data[UF_USERINFO].off, parserUrl.field_data[UF_USERINFO].len));
#undef isUrlFieldSet #undef isUrlFieldSet
dataLogger(parser)->debug(QStringLiteral("final url = %1").arg(url.toString())); dataLogger(parser)->debug(QStringLiteral("final url = %1").arg(url.toString()));
@@ -192,8 +192,7 @@ qint64 HttpRequest::availableBytes() const
return (mContentLength - alreadyRead); return (mContentLength - alreadyRead);
} }
DataStream* HttpRequest::createDataStreamToClient(int status, const QString& contentType, QIODevice* from, DataStream *HttpRequest::createDataStreamToClient(int status, const QString &contentType, QIODevice *from, qint64 fileSize, qint64 bufferSize)
qint64 fileSize, qint64 bufferSize)
{ {
mLogger->debug(QStringLiteral("createDataStreamToClient")); mLogger->debug(QStringLiteral("createDataStreamToClient"));
@@ -227,10 +226,7 @@ void HttpRequest::write(int status, const QJsonValue& jsonValue)
void HttpRequest::write(int status, const QByteArray &data, const QString &contentType) void HttpRequest::write(int status, const QByteArray &data, const QString &contentType)
{ {
mLogger->debug(QStringLiteral("write to client: status = %1, data (size) = %2, contentType = %3") mLogger->debug(QStringLiteral("write to client: status = %1, data (size) = %2, contentType = %3").arg(status).arg(data.size()).arg(contentType));
.arg(status)
.arg(data.size())
.arg(contentType));
writeStatusHeader(status); writeStatusHeader(status);
addHeader(QStringLiteral("Content-Type"), contentType); addHeader(QStringLiteral("Content-Type"), contentType);
@@ -293,8 +289,7 @@ void HttpRequest::slotReadyRead()
if (size < static_cast<size_t>(dataSize)) if (size < static_cast<size_t>(dataSize))
{ {
mLogger->error(QStringLiteral("http parser error: %1") mLogger->error(QStringLiteral("http parser error: %1").arg(QString::fromUtf8(http_errno_name(HTTP_PARSER_ERRNO(&mParser)))));
.arg(QString::fromUtf8(http_errno_name(HTTP_PARSER_ERRNO(&mParser)))));
mCli->commitTransaction(); mCli->commitTransaction();
deleteLater(); deleteLater();
return; return;
@@ -343,8 +338,7 @@ void HttpRequest::slotReadyRead()
alreadyRead = mData.mBodyPartial.size(); alreadyRead = mData.mBodyPartial.size();
mLogger->debug( mLogger->debug(QStringLiteral("slotReadyRead: already read %1 / %2 bytes").arg(alreadyRead).arg(contentLength()));
QStringLiteral("slotReadyRead: already read %1 / %2 bytes").arg(alreadyRead).arg(contentLength()));
mCli->commitTransaction(); mCli->commitTransaction();
emit signalReady(); emit signalReady();
@@ -10,7 +10,9 @@ Logger* LoggerFactory::createLogger(QObject* parent)
return new Logger(this, parent); return new Logger(this, parent);
} }
Logger::Logger(LoggerFactory* loggerFactory, QObject* parent) : QObject(parent), mLoggerFactory(loggerFactory) Logger::Logger(LoggerFactory *loggerFactory, QObject *parent)
: QObject(parent)
, mLoggerFactory(loggerFactory)
{ {
if (parent == nullptr) if (parent == nullptr)
{ {
@@ -31,7 +31,8 @@ typedef unsigned __int64 uint64_t;
#endif #endif
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C"
{
#endif #endif
/* Forward declarations */ /* Forward declarations */
@@ -105,7 +106,8 @@ typedef int (*http_cb)(http_parser*);
XX(510, NOT_EXTENDED, Not Extended) \ XX(510, NOT_EXTENDED, Not Extended) \
XX(511, NETWORK_AUTHENTICATION_REQUIRED, Network Authentication Required) XX(511, NETWORK_AUTHENTICATION_REQUIRED, Network Authentication Required)
enum http_status { enum http_status
{
#define XX(num, name, string) HTTP_STATUS_##name = num, #define XX(num, name, string) HTTP_STATUS_##name = num,
HTTP_STATUS_MAP(XX) HTTP_STATUS_MAP(XX)
@@ -156,16 +158,23 @@ enum http_status {
\ \
XX(33, SOURCE, SOURCE) XX(33, SOURCE, SOURCE)
enum http_method { enum http_method
{
#define XX(num, name, string) HTTP_##name = num, #define XX(num, name, string) HTTP_##name = num,
HTTP_METHOD_MAP(XX) HTTP_METHOD_MAP(XX)
#undef XX #undef XX
}; };
enum http_parser_type { HTTP_REQUEST, HTTP_RESPONSE, HTTP_BOTH }; enum http_parser_type
{
HTTP_REQUEST,
HTTP_RESPONSE,
HTTP_BOTH
};
enum flags { enum flags
{
F_CHUNKED = 1 << 0, F_CHUNKED = 1 << 0,
F_CONNECTION_KEEP_ALIVE = 1 << 1, F_CONNECTION_KEEP_ALIVE = 1 << 1,
F_CONNECTION_CLOSE = 1 << 2, F_CONNECTION_CLOSE = 1 << 2,
@@ -218,7 +227,10 @@ enum flags {
#define HTTP_ERRNO_GEN(n, s) HPE_##n, #define HTTP_ERRNO_GEN(n, s) HPE_##n,
enum http_errno { HTTP_ERRNO_MAP(HTTP_ERRNO_GEN) }; enum http_errno
{
HTTP_ERRNO_MAP(HTTP_ERRNO_GEN)
};
#undef HTTP_ERRNO_GEN #undef HTTP_ERRNO_GEN
@@ -264,7 +276,8 @@ struct http_parser_settings
http_cb on_chunk_complete; http_cb on_chunk_complete;
}; };
enum http_parser_url_fields { enum http_parser_url_fields
{
UF_SCHEMA = 0, UF_SCHEMA = 0,
UF_HOST = 1, UF_HOST = 1,
UF_PORT = 2, UF_PORT = 2,
@@ -25,10 +25,7 @@ class HTTQ_EXPORT AbstractServer : public QObject
virtual bool newHttpConnection(HttpRequest *request) = 0; virtual bool newHttpConnection(HttpRequest *request) = 0;
#ifdef QT6_WEBSOCKETS_AVAILABLE #ifdef QT6_WEBSOCKETS_AVAILABLE
virtual QWebSocketServer* webSocketServer() const virtual QWebSocketServer *webSocketServer() const { return nullptr; }
{
return nullptr;
}
#endif #endif
virtual LoggerFactory *createLoggerFactory(); virtual LoggerFactory *createLoggerFactory();
@@ -17,8 +17,13 @@ class HTTQ_EXPORT DataStream : public QObject
Q_OBJECT Q_OBJECT
private: private:
explicit DataStream(QIODevice* from, QIODevice* to, const QByteArray& bodyPartial, qint64 fileLength, explicit DataStream(QIODevice *from,
size_t bufferSize, LoggerFactory* loggerFactory, QObject* parent = nullptr); QIODevice *to,
const QByteArray &bodyPartial,
qint64 fileLength,
size_t bufferSize,
LoggerFactory *loggerFactory,
QObject *parent = nullptr);
public: public:
~DataStream(); ~DataStream();
@@ -44,40 +44,19 @@ class HTTQ_EXPORT HttpRequest : public QObject
qint64 availableBytes() const; qint64 availableBytes() const;
http_method method() const http_method method() const { return (enum http_method)mParser.method; }
{
return (enum http_method)mParser.method;
}
QString methodString() const QString methodString() const { return QString::fromUtf8(http_method_str(method())); }
{
return QString::fromUtf8(http_method_str(method()));
}
const QUrl& url() const const QUrl &url() const { return mData.mUrl; }
{
return mData.mUrl;
}
const QUrlQuery& query() const const QUrlQuery &query() const { return mData.mQuery; }
{
return mData.mQuery;
}
qint64 contentLength() const qint64 contentLength() const { return mContentLength; }
{
return mContentLength;
}
const QMap<QString, QString>& requestHeaders() const const QMap<QString, QString> &requestHeaders() const { return mData.mHeaders; }
{
return mData.mHeaders;
}
Logger* logger() Logger *logger() { return mLogger; }
{
return mLogger;
}
QString toString() const; QString toString() const;
@@ -85,8 +64,7 @@ class HTTQ_EXPORT HttpRequest : public QObject
void write(int status, const QByteArray &data, const QString &contentType); void write(int status, const QByteArray &data, const QString &contentType);
void write(int status, const QJsonValue &jsonValue); void write(int status, const QJsonValue &jsonValue);
DataStream *createDataStreamFromClient(QIODevice *to, qint64 fileSize, qint64 bufferSize = 1024 * 1024); DataStream *createDataStreamFromClient(QIODevice *to, qint64 fileSize, qint64 bufferSize = 1024 * 1024);
DataStream* createDataStreamToClient(int status, const QString& contentType, QIODevice* from, qint64 fileSize, DataStream *createDataStreamToClient(int status, const QString &contentType, QIODevice *from, qint64 fileSize, qint64 bufferSize = 1024 * 1024);
qint64 bufferSize = 1024 * 1024);
friend class DataStream; friend class DataStream;
@@ -107,15 +85,9 @@ class HTTQ_EXPORT HttpRequest : public QObject
static int on_chunk_header(http_parser *parser); static int on_chunk_header(http_parser *parser);
static int on_chunk_complete(http_parser *parser); static int on_chunk_complete(http_parser *parser);
static HttpRequestData* data(http_parser* parser) static HttpRequestData *data(http_parser *parser) { return static_cast<HttpRequestData *>(parser->data); }
{
return static_cast<HttpRequestData*>(parser->data);
}
static Logger* dataLogger(http_parser* parser) static Logger *dataLogger(http_parser *parser) { return static_cast<HttpRequestData *>(parser->data)->mHttpRquest->logger(); }
{
return static_cast<HttpRequestData*>(parser->data)->mHttpRquest->logger();
}
QTcpSocket *mCli; QTcpSocket *mCli;
http_parser mParser; http_parser mParser;
@@ -15,7 +15,10 @@ class HTTQ_EXPORT LoggerFactory : public QObject
Q_OBJECT Q_OBJECT
public: public:
LoggerFactory(QObject* parent) : QObject(parent) {} LoggerFactory(QObject *parent)
: QObject(parent)
{
}
virtual Logger *createLogger(QObject *parent); virtual Logger *createLogger(QObject *parent);
}; };
@@ -16,9 +16,6 @@ else()
endif() endif()
INCLUDE(MacroRTIDDSGen)
INCLUDE(MacroCodeGenIdl)
ADD_SUBDIRECTORY(Plugins) ADD_SUBDIRECTORY(Plugins)
SET(xml_FILE tab_service.xml) SET(xml_FILE tab_service.xml)
@@ -36,6 +33,9 @@ SET(SRCS_telegrams
training_area_telegrams.h training_area_telegrams.h
) )
NGL_ADD_LIBRARY(AAR SV WS HLA tabTelegrams STATIC ${SRCS_telegrams}) NGL_ADD_LIBRARY(AAR SV WS HLA tabTelegrams STATIC ${SRCS_telegrams})
# tabTelegrams is a STATIC lib linked into shared/MODULE targets
SET_TARGET_PROPERTIES(tabTelegrams PROPERTIES POSITION_INDEPENDENT_CODE ON)
NGL_TARGET_INCLUDE_DIRECTORIES(tabTelegrams NGL_TARGET_INCLUDE_DIRECTORIES(tabTelegrams
PUBLIC PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/.. ${CMAKE_CURRENT_SOURCE_DIR}/..
@@ -70,34 +70,17 @@ SET(SRCS_common
tab_export.h tab_export.h
) )
IF(BUILD_RTI) # Stub files (no RTI code generation in the release scope)
# Generate tab_enums.idl / tab.idl
CODEGEN_IDL_SVC(SRCS_common ${xml_FILE})
# Generate tab_db_impl.cpp/.h, tab_db.h
CODEGEN_DATABASE(SRCS_common ${xml_FILE})
# Generate *.cpp/*.hpp from idl (only with BUILD_RTI)
RTIDDSGEN(SRCS_common tab_enums.idl)
# tab.idl includes pdm.idl, so add explicit dependency on pdm.idl generation
RTIDDSGEN(SRCS_common tab.idl DEPENDS ${CMAKE_BINARY_DIR}/Lts/Services/ProjectDataManagement/pdm.idl)
# Generate tab_dt[s,c]_types.h, tab_ft[s,c]_types.h
CODEGEN_TOPIC_TYPEDEFS(SRCS_common ${xml_FILE})
# generate tab_[d|f]tc.h
CODEGEN_CLIENT_TOPICS_IFC(SRCS_common ${xml_FILE})
ELSE()
# Stub files for BUILD_RTI=OFF - NO code generation
LIST(APPEND SRCS_common LIST(APPEND SRCS_common
stubs/tab_enums_stub.hpp stubs/tab_enums_stub.hpp
stubs/tab_stub.hpp stubs/tab_stub.hpp
stubs/tab_db_stub.hpp stubs/tab_db_stub.hpp
stubs/tab_topic_type_plugin_stub.cpp stubs/tab_topic_type_plugin_stub.cpp
) )
ENDIF()
# Create target only if component flags allow # Create target only if component flags allow
NGL_ADD_LIBRARY2(AAR SV WS HLA svcTabCommon SHARED ${SRCS_common}) NGL_ADD_LIBRARY2(AAR SV WS HLA svcTabCommon SHARED ${SRCS_common})
# Generate export header ALWAYS (needed for logger.h even if target not built)
# Use custom command to create minimal export header if target wasn't created
IF(NOT TARGET svcTabCommon) IF(NOT TARGET svcTabCommon)
# Create a dummy static library just for export header generation # Create a dummy static library just for export header generation
ADD_LIBRARY(svcTabCommon STATIC ${SRCS_common}) ADD_LIBRARY(svcTabCommon STATIC ${SRCS_common})
@@ -121,220 +104,8 @@ NGL_TARGET_LINK_LIBRARIES(svcTabCommon
$<IF:$<TARGET_EXISTS:svcPdmCommon>,svcPdmCommon,> $<IF:$<TARGET_EXISTS:svcPdmCommon>,svcPdmCommon,>
LtsUtilsCoreHeaderOnly LtsUtilsCoreHeaderOnly
) )
IF(BUILD_RTI)
NGL_TARGET_LINK_LIBRARIES(svcTabCommon
PRIVATE
RTI::nddscpp2
PUBLIC
ddscore
)
ENDIF(BUILD_RTI)
NGL_INSTALL_TARGET(svcTabCommon) NGL_INSTALL_TARGET(svcTabCommon)
#
# --- Library svcTabClient --------------------------------------------------------------------------------
#
# Skip for release builds - DDS-dependent service library
IF(NOT RELEASE_BUILD)
SET(SRCS_client
tab_export.h
)
IF(BUILD_RTI)
# generate tab_[d|f]tc_impl.[cpp|h]
CODEGEN_CLIENT_TOPICS_IMPL(SRCS_client ${xml_FILE})
ENDIF()
NGL_ADD_LIBRARY2(AAR SV WS HLA svcTabClient SHARED ${SRCS_client})
# NGL_ADD_LIBRARY2 (unlike NGL_ADD_LIBRARY) does not define the
# MAKE_<SYMBOL>_LIB compile guard, but the generated tab_[d|f]tc_impl.h
# headers require MAKE_SVCTABCLIENT_LIB — same situation as
# svcCoreClient/ddscore, which define their guards explicitly.
TARGET_COMPILE_DEFINITIONS(svcTabClient PRIVATE MAKE_SVCTABCLIENT_LIB)
NGL_TARGET_INCLUDE_DIRECTORIES(svcTabClient
PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/../
${CMAKE_CURRENT_BINARY_DIR}/../
)
IF(BUILD_RTI)
NGL_TARGET_LINK_LIBRARIES(svcTabClient
PRIVATE
RTI::nddscpp2
ddsconnector
PUBLIC
svcTabCommon
ddsftc
)
ENDIF(BUILD_RTI)
NGL_INSTALL_TARGET(svcTabClient)
ENDIF() # NOT RELEASE_BUILD
#
# --- Library svcTabServer --------------------------------------------------------------------------------
#
# Skip for release builds - DDS-dependent service library
IF(NOT RELEASE_BUILD)
SET(SRCS_server
tx_mixin.cpp
tx_mixin.h
)
IF(BUILD_RTI)
# generate tab_[d|f]ts.h, tab_[d|f]ts_impl.[cpp|h]
CODEGEN_SERVER_TOPICS(SRCS_server ${xml_FILE})
ENDIF()
NGL_ADD_LIBRARY2(AAR HLA SV svcTabServer SHARED ${SRCS_server}) # NGL_ADD_LIBRARY2 won't work here - no time for investigations
# Generated tab_[d|f]ts_impl.h require MAKE_SVCTABSERVER_LIB (see svcTabClient above).
TARGET_COMPILE_DEFINITIONS(svcTabServer PRIVATE MAKE_SVCTABSERVER_LIB)
if(BUILD_SV OR BUILD_HLA)
GENERATE_EXPORT_HEADER(svcTabServer) # FIXME: quick workaround
endif()
NGL_TARGET_INCLUDE_DIRECTORIES(svcTabServer
PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/../
${CMAKE_CURRENT_BINARY_DIR}/../
)
NGL_TARGET_LINK_LIBRARIES(svcTabServer
PUBLIC
svcTabCommon
ngldb
${_QT_CORE_TARGET}
$<IF:$<AND:$<BOOL:${QT6_GUI_AVAILABLE}>,$<TARGET_EXISTS:Qt6::Gui>>,Qt6::Gui,>
${_QT_NETWORK_TARGET}
)
IF(BUILD_RTI)
NGL_TARGET_LINK_LIBRARIES(svcTabServer
PRIVATE
RTI::nddscpp2
ddsconnector
ddsfts
)
ENDIF(BUILD_RTI)
NGL_INSTALL_TARGET(svcTabServer)
ENDIF() # NOT RELEASE_BUILD
#
# --- Topic Type Plugin --------------------------------------------------------------
#
IF(BUILD_RTI)
CREATE_TOPIC_TYPE_PLUGIN(${xml_FILE})
ENDIF()
#
# --- RecordReplayPlugin --------------------------------------------------------------
#
IF(BUILD_RTI)
CREATE_RECORD_REPLAY_PLUGIN_SHARED(${xml_FILE})
IF (TARGET tabRecordReplayPlugin)
TARGET_SOURCES(tabRecordReplayPlugin
PRIVATE
tab_record_replay_plugin_custom.cpp
tab_record_replay_plugin_custom.h
)
ENDIF()
ENDIF()
#
# --- Executable svcTrainingAreaBase (sTAB) -------------------------------------------------
#
# Skip for release builds - DDS-dependent executable
IF(NOT RELEASE_BUILD)
SET(SRCS_exe
dds_handler.cpp
dds_handler.h
exm_handler.cpp
exm_handler.h
ism_handler.cpp
ism_handler.h
main.cpp
main_handler.cpp
main_handler.h
pdm_handler.cpp
pdm_handler.h
ppm_handler.cpp
ppm_handler.h
position_handler.cpp
position_handler.h
recv_from_dds_aes.cpp
recv_from_dds_aes.h
recv_from_dds_fts.cpp
recv_from_dds_fts.h
recv_from_tab.h
send_to_dds.cpp
send_to_dds.h
send_to_tab.h
settings.cpp
settings.h
tab_export.h
tab_plugin_interface.h
WebSocketInterface/data_manager.cpp
WebSocketInterface/data_manager.h
WebSocketInterface/json_keys.h
WebSocketInterface/websocket_interface_handler.cpp
WebSocketInterface/websocket_interface_handler.h
WebSocketInterface/Messages/client_message.cpp
WebSocketInterface/Messages/client_message.h
WebSocketInterface/Messages/reply_message.cpp
WebSocketInterface/Messages/reply_message.h
# tx_mixin.cpp
# tx_mixin.h
log4cxx_tab.props
${xml_FILE}
)
IF(BUILD_RTI)
# Generate tab.sql, tab.xml
CODEGEN_SQL(SRCS_exe ${xml_FILE})
ENDIF()
NGL_ADD_SVC_ICON(SRCS_exe)
NGL_ADD_EXECUTABLE(AAR SV svcTrainingAreaBase ${SRCS_exe})
NGL_TARGET_LINK_LIBRARIES(svcTrainingAreaBase
Qt6::Core
Qt6::Network
LtsCoordTrans
LtsWebSocketServer
LtsCommandLineParser
LtsPluginLoader
LtsUtilsCoreHeaderOnly
LtsUtilsCore
svcTabCommon
svcTabServer
# main_handler.cpp includes the generated <TrainingAreaBase/tab_record_replay_plugin.h>
# and directly instantiates TrainingAreaBase::RecordReplayPluginCustom (whose methods
# live in the plugin .so). Linking the plugin target (rather than relying on a full
# `make all` having generated the header first) makes this a proper build dependency:
# the plugin's codegen runs before the exe compiles (so the generated header exists),
# the plugin's PUBLIC build-tree include dir is inherited (so the include resolves),
# and the plugin .so is linked (so the RecordReplayPluginCustom symbols resolve).
$<IF:$<TARGET_EXISTS:tabRecordReplayPlugin>,tabRecordReplayPlugin,>
svcNomClient
svcAesClient
svcOpmClient
svcCoreClient
svcAsmClient
svcExmClient
$<IF:$<TARGET_EXISTS:svcIsmClient>,svcIsmClient,>
svcPdmClient
svcPpmClient
$<IF:$<TARGET_EXISTS:ddsconnector>,ddsconnector,>
nglsettings
ProjectConfig
NGLLogger
nglcoreapplication
ngltools
tabTelegrams
)
NGL_INSTALL_TARGET(svcTrainingAreaBase)
NGL_INSTALL(AAR SV FILES log4cxx_tab.props DESTINATION bin)
NGL_ADD_TARGET_LINK(svcTrainingAreaBase sTAB)
ENDIF() # NOT RELEASE_BUILD
# clientPluginInterface # clientPluginInterface
ADD_LIBRARY(tabPluginInterface INTERFACE) ADD_LIBRARY(tabPluginInterface INTERFACE)
TARGET_SOURCES(tabPluginInterface INTERFACE TARGET_SOURCES(tabPluginInterface INTERFACE
@@ -4,43 +4,5 @@
# $Author$ # $Author$
# #
IF (NOT BUILD_RPM AND NOT RELEASE_BUILD) # Release scope: only the TetraJson plugin is in the tree (GUEZ project, no RTI)
ADD_SUBDIRECTORY(DebugJsonDir)
ENDIF()
#ADD_SUBDIRECTORY(Spu)
IF (BUILD_WLS AND NOT RELEASE_BUILD)
ADD_SUBDIRECTORY(WlsTetra)
ELSE()
ADD_SUBDIRECTORY(TetraJson) ADD_SUBDIRECTORY(TetraJson)
ENDIF()
IF ("${_pname}" STREQUAL "commaster")
ADD_SUBDIRECTORY(Nmea)
ENDIF()
IF (BUILD_SV AND DEFINED _pname)
IF ("${_pname}" STREQUAL "guez")
IF(NOT RELEASE_BUILD)
ADD_SUBDIRECTORY(HlaJson)
ENDIF()
ENDIF()
ENDIF()
IF (BUILD_SVC_HLA)
IF ("${_pname}" STREQUAL "ahtc")
ADD_SUBDIRECTORY(ApacheHlaJson)
ENDIF()
ENDIF()
# AdlerJson depends on svcPdmClient (ProjectDataManagement) which is not in release scope
IF(NOT RELEASE_BUILD)
ADD_SUBDIRECTORY(AdlerJson)
ENDIF()
OPTION(BUILD_UAS_PROXY "Build the UAS TAB Plugin (default: OFF) [needs BUILD_SV = ON and UNIX-like OS]" OFF) # TODO: use 'pname = guez' if done
if (BUILD_SV AND BUILD_UAS_PROXY AND NOT WIN32 AND NOT RELEASE_BUILD)
add_subdirectory(UAS)
endif()
@@ -11,10 +11,12 @@
namespace TetraRadio namespace TetraRadio
{ {
ConvertFromJson::ConvertFromJson(const std::shared_ptr<TrainingAreaBase::RecvFromTab> &rxHandler, ConvertFromJson::ConvertFromJson(const std::shared_ptr<TrainingAreaBase::RecvFromTab> &rxHandler, const char *loggerName)
const char *loggerName) : m_rxHandler(rxHandler) : m_rxHandler(rxHandler)
, m_bWarnedOnce(false) , m_bWarnedOnce(false)
, m_logger(N_LogView::getLogger(loggerName)) {} , m_logger(N_LogView::getLogger(loggerName))
{
}
bool ConvertFromJson::handleTelegram(const QByteArray &baJson, int &recvCounter) bool ConvertFromJson::handleTelegram(const QByteArray &baJson, int &recvCounter)
{ {
@@ -162,8 +164,7 @@ bool ConvertFromJson::handleTelegram(const QByteArray &baJson, int &recvCounter)
break; break;
default: default:
WARNING_LOG(m_logger) << "Handler for telegram Id " << typeId.toInt() WARNING_LOG(m_logger) << "Handler for telegram Id " << typeId.toInt() << " not yet implemented (" << baJson << ")";
<< " not yet implemented (" << baJson << ")";
return false; return false;
} }
} }
@@ -175,8 +176,7 @@ bool ConvertFromJson::handleTelegram(const QByteArray &baJson, int &recvCounter)
return true; return true;
} }
template<typename T> template <typename T> void ConvertFromJson::rxData(const T &data)
void ConvertFromJson::rxData(const T &data)
{ {
if (!m_rxHandler) if (!m_rxHandler)
{ {
@@ -19,14 +19,14 @@ protected:
bool handleTelegram(const QByteArray &baJson, int &recvCounter); bool handleTelegram(const QByteArray &baJson, int &recvCounter);
virtual void handleAcknowledge(qint64 timeStamp, int counter) = 0; virtual void handleAcknowledge(qint64 timeStamp, int counter) = 0;
virtual void handleTetraConnectionChanged(bool bConnected) = 0; virtual void handleTetraConnectionChanged(bool bConnected) = 0;
private:
template<typename T>
void rxData(const T &data);
private: private:
template <typename T> void rxData(const T &data);
private:
static TrainingAreaBase::TetraIcd::BiteError convertBiteError(const QJsonObject &obj); static TrainingAreaBase::TetraIcd::BiteError convertBiteError(const QJsonObject &obj);
std::shared_ptr<TrainingAreaBase::RecvFromTab> m_rxHandler; std::shared_ptr<TrainingAreaBase::RecvFromTab> m_rxHandler;
protected: protected:
NGL::INGLLogger &m_logger; NGL::INGLLogger &m_logger;
bool m_bWarnedOnce; bool m_bWarnedOnce;
Loaded 100 of 699 files, more files were not shown because too many files have changed in this diff. Show more